HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Unit Group Array

03-09-2007, 10:51 PM#1
Fluxx
Hello folks,

Building on my previous coding and the help I got from Pyrogasm and Rising Dusk, I have built up another jass spell. Running into a little trouble and want to see if I am on the right track to fixing it.

Collapse JASS:
function Trig_Twist_Allegiance_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006' 
endfunction

function Twist_Enemy_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Twist_Caster))
endfunction

function Trig_Twist_Allegiance_Actions takes nothing returns nothing
local group g = CreateGroup()
local integer i = 0
local boolexpr p = Condition(function Twist_Enemy_Filter)
local unit u  
local player a = GetTriggerPlayer()
local group array o
local location loc = GetSpellTargetLoc()

call GroupEnumUnitsInRangeOfLoc(g, loc, 350.00, p)

    loop 
       set u = FirstOfGroup(g) 
       exitwhen u == null
       set i = GetPlayerId(GetOwningPlayer(u))
       call GroupAddUnit(o[i],u)
       call BJDebugMsg(I2S(i))
       call SetUnitOwner(u,a,true)
       call GroupRemoveUnit(g,u)
     endloop
     
     call TriggerSleepAction( 2 )
     set i = 0
     
     
     loop 
       exitwhen i > 4
       loop
        set u = FirstOfGroup(o[i])
        set a = Player(i)
        exitwhen u == null
        call SetUnitOwner(u,a,true)
        call GroupRemoveUnit(o[i],u)
       endloop
       set i = i+1
       call BJDebugMsg(I2S(i))
     endloop
     endfunction

        

The intent of the code is to convert all enemy units in a specific radius to the owner of the triggering player. After a certain amount of time these units will revert back to their original controllers.

I am convinced that the error lies in the second loop (perhaps how I nested them) because the debug messages display the proper player indexes and the [i] value is being looped. There is no leak cleanup noted, but is present in the actual code.

Thanks!

-Fluxx
03-09-2007, 11:14 PM#2
FatalError
First of all, what are the reals 'x' and 'y' for? They don't seem to be used...

Second, I don't know what I missed but I don't see the point of having the group array or the nested loop. Is there a reason why you didn't just stick to using the 'g' variable in the bottom loops?
03-09-2007, 11:27 PM#3
grim001
The group array won't even do anything because it's not actually storing any groups... you perform a GroupAddUnit on a group that doesn't exist with this line...

"call GroupAddUnit(o[i],u)"
03-09-2007, 11:30 PM#4
Fluxx
They were a missed part of the older code. They have been edited out.

I am using the group array to store the units for each specific player in order to swap controllers back at the end of the trigger.

Quote:
Originally Posted by grim001
The group array won't even do anything because it's not actually storing any groups... you perform a GroupAddUnit on a group that doesn't exist with this line...

"call GroupAddUnit(o[i],u)"

So if I wished to store those units I will need to initalize that group? I was under the impression that arrays cannot be initalized. Is there a better way to appraoch this problem?

Or do I need to simply add a line that will create the o[i] group?
03-09-2007, 11:31 PM#5
Toink
Yeah, you add the o[i] to the unit declared as u == FirstOfGroup()

Add it to g not u

And you also remove the group g from the unit u

You did not reread your script

EDIT: Couldn't you just order a dummy/caster to charm every unit?
03-09-2007, 11:51 PM#6
Fluxx
Quote:
Originally Posted by Toink
Yeah, you add the o[i] to the unit declared as u == FirstOfGroup()

Add it to g not u

And you also remove the group g from the unit u

You did not reread your script

EDIT: Couldn't you just order a dummy/caster to charm every unit?


I will try that.

I will probably end up doing charming for simplicity, but I am trying to expand my jass coding ability.

From a coding concept consideration is this the correct way to approach such a problem?
03-10-2007, 02:56 AM#7
grim001
You can't initialize arrays all at once, you'd have to do something like...
set o[0] = CreateGroup()
set o[1] = CreateGroup()
...
call DestroyGroup(o[0])
call DestroyGroup(o[1])
..


This is an example where gamecache actually would work well and not affect performance... just attach an integer to each unit that represents which player it came from so that you can restore ownership properly. If you don't know gamecache now would be a perfect time to learn about it, but I really suggest not lingering on it, there are better alternatives nowdays so gamecache is rarely the optimal solution.
03-10-2007, 09:39 PM#8
Fluxx
Well, so far so good.

This trigger works in most cases, but I will sometimes run into a problem.

Collapse JASS:
function Trig_Twist_Allegiance_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006' 
endfunction

function Twist_Enemy_Filter takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Twist_Caster))
endfunction




function Trig_Twist_Allegiance_Actions takes nothing returns nothing
local group g = CreateGroup()
local group array o
local boolexpr p = Condition(function Twist_Enemy_Filter)
local unit u
local integer i = 0
local player a = GetTriggerPlayer()
local location loc = GetSpellTargetLoc()
local timer t

call GroupEnumUnitsInRangeOfLoc(g, loc, 200.00, p)

set o[0] = CreateGroup()
set o[1] = CreateGroup()
set o[2] = CreateGroup()
set o[3] = CreateGroup()
set o[4] = CreateGroup()
 
    loop 
       set u = FirstOfGroup(g) 
       exitwhen u == null
       call GroupAddUnit(o[GetPlayerId(GetOwningPlayer(u))],u)
       call SetUnitOwner(u,a,true)
       call GroupRemoveUnit(g,u)
       endloop

   call TriggerSleepAction(5)

   loop
    exitwhen i > 4
      loop
       set u = FirstOfGroup(o[i]) 
       exitwhen u == null
       call SetUnitOwner(u,Player(i),true)
       call GroupRemoveUnit(o[i],u)    
      endloop 
     set i = i+1
   endloop        
     endfunction
        

This will swap unit control back and forth consistantly. However, on occasion the change of control will not swap back. Is there a surer way of achiving the effect intended?
03-11-2007, 12:33 AM#9
grim001
TriggerSleepAction is not exact and not always reliable... if other things are happening in the map it might just forget to execute the code after the sleep...

You should use a timer callback to make it 100% reliable, but then you have the issue of having to pass the variables via some method. You'd wind up needing to use global arrays, gamecache, or structs.