| 03-09-2007, 10:51 PM | #1 |
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. 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 |
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 |
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 | |
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:
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 |
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 | |
Quote:
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 |
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 |
Well, so far so good. This trigger works in most cases, but I will sometimes run into a problem. 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 |
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. |
