HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Big function small problem :(

02-27-2008, 08:36 PM#1
Tastingo
Hey basicly I'm making AI for a game, if your wondering what the function is for, and I'm having a problem with GroupEnumUnitsInRect.I will highlight the lines that I'm having problems with. Also if anyone is interested at looking at the rest, which you don't have to, the rest is pretty much getting the closest unit within the region.

Collapse JASS:
function allycheck takes unit u returns boolean
if( IsUnitPaused(GetFilterUnit()) == true) then
    if(GetUnitTypeId(GetFilterUnit()) == GetUnitTypeId(u)) then
        return true
    else
        return false
    endif
else
    return false
endif
endfunction

function enemycheck takes unit u returns boolean
if( IsUnitPaused(GetFilterUnit()) == false) then
    if(GetUnitTypeId(GetFilterUnit()) != GetUnitTypeId(u)) then
        return true
    else
        return false
    endif
else
    return false
endif
endfunction

function checkdistance takes real pickedallydistance, real pickedenemydistance, integer a returns boolean
if(udg_BLNThawing[a] == false) then
    if( pickedallydistance < pickedenemydistance) then
        return true
    else
        return false
    endif
else
    return false
endif
endfunction

function checkdistance2 takes real pickedallydistance, real pickedenemydistance, integer a returns boolean
if(udg_BLNThawing[a] == false) then
    if( pickedallydistance > pickedenemydistance) then
        return true
    else
        return false
    endif
else
    return false
endif
endfunction

function AttackingAI takes nothing returns nothing
//Locals
//Checks for closest
local boolean array smallest
//Creates temporary groups
local group allunits = CreateGroup()
local group ai = CreateGroup()
local group allyrect = CreateGroup()
local group enemyrect = CreateGroup()
//The Ai unit
local unit u
//targets
local unit allytarget
local unit enemytarget
//Unit compared for distance
local unit comparing
local unit array units
//Closest enemy and ally
local unit closestally
local unit closestenemy
//Counters
local integer a = 0
local integer b = 0
local integer c = 0
//Number of each
local integer ally = 0
local integer enemy = 0
//Unit positions
local real x
local real x2
local real y
local real y2
//Comparing distance of each unit
local real array allydistance
local real array enemydistance
//Closest enemy and ally distance
local real pickedallydistance
local real pickedenemydistance
//Initilization of arrays
set allydistance[0] = 0.
set allydistance[1] = 0.
set allydistance[2] = 0.
set allydistance[3] = 0.
set allydistance[4] = 0.
set allydistance[5] = 0.
set enemydistance[0] = 0.
set enemydistance[1] = 0.
set enemydistance[2] = 0.
set enemydistance[3] = 0.
set enemydistance[4] = 0.
set enemydistance[5] = 0.
set units[0] = null
set units[1] = null
set units[2] = null
set units[3] = null
set units[4] = null
set units[5] = null

    loop
    exitwhen a>11
        if(GetPlayerController(Player(a)) == MAP_CONTROL_COMPUTER) then
                    //Reset groups
            call GroupClear(allunits)
            call GroupClear(ai)
            call GroupClear(allyrect)
            call GroupClear(enemyrect)
                    //Add groups
            call GroupEnumUnitsInRect(allunits, udg_Region[a], null)
            call GroupEnumUnitsOfPlayer(ai, Player(a), null)
            set u = FirstOfGroup(ai)
            call GroupEnumUnitsInRect(allyrect, udg_Region[a], Condition(function allycheck(u)))
            call GroupEnumUnitsInRect(enemyrect, udg_Region[a], Condition(function enemycheck(u)))
            set bj_groupCountUnits = 0
            call ForGroup(allyrect, function CountUnitsInGroupEnum)
            set ally = bj_groupCountUnits
            set bj_groupCountUnits = 0
            call ForGroup(enemyrect, function CountUnitsInGroupEnum)
            set enemy = bj_groupCountUnits
                    //Coordinates and loops
            set a = 0
            set b = 0
            set c = 0
            set x = GetUnitX(u)
            set y = GetUnitY(u)
                    //Ally distances
            loop
            exitwhen b > ally
                set comparing = FirstOfGroup(allyrect)
                call GroupRemoveUnit(allyrect, comparing)
                set units[b] = comparing
                set x2 = GetUnitX(comparing)
                set y2 = GetUnitY(comparing)
                set x2 = x - x2
                set y2 = y - y2
                set allydistance[b] = (x2 * x2) + (y2 * y2)
                set b = b + 1
            endloop
                    //Closet ally distance
            set b = 0
            loop
            exitwhen b > ally
                loop
                exitwhen c > ally
                    if( allydistance[b] > allydistance[c]) then
                        set smallest[b] = false
                    else
                        set smallest[b] = true
                    endif
                    set c = c + 1
                endloop
                if( smallest[b] == true ) then
                    set closestally = units[b]
                endif
                set b = b + 1
            endloop
                    //Enemy distances
            set b = 0
            loop
            exitwhen b > enemy
                set comparing = FirstOfGroup(enemyrect)
                call GroupRemoveUnit(enemyrect, comparing)
                set units[b] = comparing
                set x2 = GetUnitX(comparing)
                set y2 = GetUnitY(comparing)
                set x2 = x - x2
                set y2 = y - y2
                set enemydistance[b] = (x2 * x2) + (y2 * y2)
                set b = b + 1
                    //Closet enemy distance
            set b = 0
            set c = 0
            loop
            exitwhen b > enemy
                loop
                exitwhen c > enemy
                    if( enemydistance[b] > enemydistance[c]) then
                        set smallest[b] = false
                    else
                        set smallest[b] = true
                    endif
                    set c = c + 1
                endloop
                if( smallest[b] == true ) then
                    set closestenemy = units[b]
                endif
                set b = b + 1
            endloop
            endloop
                //Who to attack
            if(checkdistance(pickedallydistance, pickedenemydistance, a)) then
                set udg_BLNThawing[a] = true
                call IssueTargetOrder( u, "attack", closestally )
            elseif(checkdistance2(pickedallydistance, pickedenemydistance, a)) then
            
            endif
        endif
        set a = a + 1
    endloop
    
//Delete Groups
call DestroyGroup(allunits)
call DestroyGroup(ai)
call DestroyGroup(allyrect)
call DestroyGroup(enemyrect)
endfunction

//===========================================================================
function InitTrig_Attack_or_Freeze takes nothing returns nothing
    set gg_trg_Attack_or_Freeze = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Attack_or_Freeze, 0.01 )
    call TriggerAddAction( gg_trg_Attack_or_Freeze, function AttackingAI )
endfunction
02-27-2008, 09:33 PM#2
Deaod
what problems are you experiencing? without that information we cant help you.

besides, you have to null every local variable which is of a type that extends a handle. (units, group, rect, ...)
02-27-2008, 10:08 PM#3
Captain Griffen
1) Learn to indent.
2) Learn JASS (and I don't mean GUI converted, which is crap).
3) Learn JASS, as in what conditions are.

Condition() takes a code variable. A code variable is simply a function. It cannot have any parameters.
02-27-2008, 10:12 PM#4
Tastingo
yo thats really harsh griffen... that wasn't needed at all. I am learning JASS and that isn't GUI converted. The only thing that is converted is the event... I was getting errors with the GroupEnumUnitsInRect so I thought maybe use Condition since I tried to fix it. I've just started recently so seriouslly chill out. I did indent, I indent differently then you though; its a style and obviouslly I didn't learn to indent the same way you did.

Oh when I'm initializing a handle it has to be set to null? The problem with the highlighted area is with the condition. It said it convert boolean to boolexpr or vice versa(cant remember). So I put in the Condition() thought maybe that would work since I tried figuring it out myself.
02-28-2008, 03:59 PM#5
Captain Griffen
[quote=Tastingo]yo thats really harsh griffen... that wasn't needed at all.[/jass]

Do you want nice, or do you want to learn? That's the question.

Quote:
I am learning JASS and that isn't GUI converted.

Then redo the conditions in a sane way, unlike the completely crap way that WE does it. Look at some JASS done by proper JASSers.

Quote:
The only thing that is converted is the event...

That's fine, personally I tend to use converted events. WE does them okay, and the BJ problem isn't really one since it isn't done on run time, but at map start up.

Quote:
I was getting errors with the GroupEnumUnitsInRect so I thought maybe use Condition since I tried to fix it.

Well, as I said, Condition takes a code variable. A code variable cannot take a parameter.

Quote:
I've just started recently so seriouslly chill out. I did indent, I indent differently then you though; its a style and obviouslly I didn't learn to indent the same way you did.

A different way to me AND the rest of the world. Seriously. All the main programming languages indent in the same way. Badly indented code is hard to read; something you'll no doubt fine unless you fix it to something sensible.

Quote:
Oh when I'm initializing a handle it has to be set to null?

Nope. At the end. JASS is messed up. Any handle variable left pointing to an object when the thread ends will result in the handle's reference count not being decremented - meaning that the handle index will never be recycled. Which is a leak.

So null any handle variables at the end of the function (note that this doesn't apply to permament handles, such as variables pointing to a hero in a normal AoS, etc.).

Quote:
The problem with the highlighted area is with the condition. It said it convert boolean to boolexpr or vice versa(cant remember). So I put in the Condition() thought maybe that would work since I tried figuring it out myself.

Oh, Condition(function allycheck) is correct (not it doesn't take a parameter - use google to find out what a parameter is if you don't know).

Change it to this:

Collapse JASS:
function allycheck takes nothing returns boolean
    return (IsUnitPaused(GetFilterUnit()) and GetUnitTypeId(GetFilterUnit()) == GetUnitTypeId(udg_TempUnit))
endfunction

function enemycheck takes unit u returns boolean
    return (IsUnitPaused(GetFilterUnit()) and (GetUnitTypeId(GetFilterUnit()) != GetUnitTypeId(udg_TempUnit))
endfunction

        set udg_TempUnit = u
            call GroupEnumUnitsInRect(allyrect, udg_Region[a], Condition(function allycheck))
            call GroupEnumUnitsInRect(enemyrect, udg_Region[a], Condition(function enemycheck))
02-28-2008, 07:06 PM#6
Tastingo
Well thank you for helping me out, I would rather learn than someone just being nice. But would rather have you give some type of example, next time when your pointing something out thats wrong. I'm not really sure what's wrong with my indenting that makes it hard to read though. I indent the If's and loops.

Collapse JASS:
return (IsUnitPaused(GetFilterUnit()) and (GetUnitTypeId(GetFilterUnit()) != GetUnitTypeId(udg_TempUnit))

Also is that checking to see if the unit is not paused because not really sure how that works. I know its checking if the unit type is not equal.
02-28-2008, 09:06 PM#7
Captain Griffen
Quote:
Originally Posted by Tastingo
Well thank you for helping me out, I would rather learn than someone just being nice. But would rather have you give some type of example, next time when your pointing something out thats wrong. I'm not really sure what's wrong with my indenting that makes it hard to read though. I indent the If's and loops.

You didn't indent the exitwhen, for example, despite that being inside the loop.

Quote:
Collapse JASS:
return (IsUnitPaused(GetFilterUnit()) and (GetUnitTypeId(GetFilterUnit()) != GetUnitTypeId(udg_TempUnit))

Also is that checking to see if the unit is not paused because not really sure how that works. I know its checking if the unit type is not equal.

It is checking if the unit is both paused and NOT the unit type. Which is actually wrong, sorry, it should be:

Collapse JASS:
return (not(IsUnitPaused(GetFilterUnit())) and (GetUnitTypeId(GetFilterUnit()) != GetUnitTypeId(udg_TempUnit))