| 10-04-2007, 02:15 PM | #1 |
I am trying to make a small structure which will handle registering units and triggers for the Unit-takes-damage event. The idea is that whenever there are no damage event units left, the damage trigger is destroyed, recreated, and the 'actions' are added again. The problem is that it works great... until the trigger is recreated. I've checked, and the code to re-add the actions IS being run. They just aren't being called when damage happens. What am I doing wrong? JASS://this is called at startup with functions that want "takes damage" calls function registerForDamage takes code c returns nothing if (numDamageCode > MAX_DAMAGE_CALLBACKS) then call showMessage("Critical Map Error: too many callbacks for unit takes damage") return endif set numDamageCode = numDamageCode + 1 set damageCode[numDamageCode] = Code2I(c) call TriggerAddAction(trigDamage, c) endfunction //Called for new runners function addDamageEventUnit takes unit u returns nothing if (u != null and IsUnitInGroup(u, damageUnits) == false) then call GroupAddUnit(damageUnits, u) call TriggerRegisterUnitEvent(trigDamage, u, EVENT_UNIT_DAMAGED) endif endfunction //Called when runners die function catchDeath takes nothing returns nothing local integer i local unit u = GetTriggerUnit() if (IsUnitInGroup(u, damageUnits)) then call GroupRemoveUnit(damageUnits, u) if (CountUnitsInGroup(damageUnits) == 0) then //guaranteed to happen when rounds end //recreate the damage trigger call DestroyTrigger(trigDamage) set trigDamage = CreateTrigger() set i = 1 loop exitwhen i > numDamageCode call TriggerAddAction(trigDamage, I2Code(damageCode[i])) //<== doesn't work, action never called set i = i + 1 endloop endif endif endfunction |
| 10-04-2007, 03:50 PM | #2 |
You cannot add more than one unit to the same UNIT_DAMAGE trigger. |
| 10-04-2007, 05:37 PM | #3 | |
It must be something with I2Code/Code2I. Why not just store the actions in a code array in the first place, instead of converting it back and forth? Quote:
What.....? |
| 10-04-2007, 05:49 PM | #4 | |
Quote:
I doubt the actions are failing to get added, first check the trigger is actually getting called... For example you can have a debug trigger that shows GetTriggerEvalCount(trigDamage) ... |
| 10-04-2007, 05:51 PM | #5 |
Exactly like i said, let me repeat it. You can NOT add more than one unit to the same UNIT_DAMAGE trigger. |
| 10-04-2007, 06:24 PM | #6 | |
Quote:
|
| 10-04-2007, 06:30 PM | #7 |
prove me wrong. |
| 10-04-2007, 07:35 PM | #8 |
If you mean adding more than one UNIT_DAMAGE event to the same trigger for different units, then yes you can. People have been doing it for ages. So how about we put the onus on you. Triggers can have multiple events and people have used systems with multiple UNIT_DAMAGE events on the same trigger (hundreds of them, in fact). Upload a test map which proves you are right. |
| 10-04-2007, 09:03 PM | #9 |
My bad, had a bug in test map and made some wrong conclusions based on it. |
| 10-04-2007, 10:30 PM | #10 |
GetTriggerEvalCount(trigDamage) is returning the correct amounts, as if the trigger were being destroyed and firing appropriately. Furthermore, "TriggerAddAction" isn't returning null, so that should mean the action was added correctly. At this point I am COMPLETELY confused. ![]() |
| 10-04-2007, 10:55 PM | #11 |
I think I have the problem worked out. If I add a "real" TriggerAddAction call, which is given a code argument of the form "function name", it works. To me, that suggests something is going wrong storing the handle to the code. I would bet that WC3 tracks code handles much more closely than other types, and cleans it up without me realizing it. That makes my stored integers become incorrect, and the actions would then just get dropped when called. In any case, I have a workaround: I separated my trigger into events and actions. I only need to destroy the events trigger, so there is no need to store the actions. This is arguably simpler than what I was originally doing. JASS://called by trigDamageEvents, forwards to trigDamageActions function catchDamage takes nothing returns nothing call ConditionalTriggerExecute(trigDamageActions) endfunction //Called when runners die function catchDeath takes nothing returns nothing local integer i local unit u = GetTriggerUnit() if (IsUnitInGroup(u, damageUnits)) then call GroupRemoveUnit(damageUnits, u) if (CountUnitsInGroup(damageUnits) == 0) then //guaranteed to happen when rounds end //recreate the damage trigger call DestroyTrigger(trigDamageEvents) set trigDamageEvents = CreateTrigger() call TriggerAddAction(trigDamageEvents, function catchDamage) //call middle-man endif endif endfunction //this is called at startup with functions that want "takes damage" calls function registerForDamage takes code c returns nothing call TriggerAddAction(trigDamageActions, c) endfunction //Called for new runners function addDamageEventUnit takes unit u returns nothing if (u != null and IsUnitInGroup(u, damageUnits) == false) then call GroupAddUnit(damageUnits, u) call TriggerRegisterUnitEvent(trigDamageEvents, u, EVENT_UNIT_DAMAGED) endif endfunction |
| 10-04-2007, 11:02 PM | #12 | |
Quote:
you know, this doesn't really make sense, when you consider that code is a constant type... My bet would be JASS:function I2Code takes integer i returns code return i return null endfunction function I2Code_Fix takes integer i returns code local code c=I2Code(i) return c endfunction I've seen reals requiring this bridge thing for the return bugger to work correctly, else they really misbehave, so there's a chance the same happens with code. |
| 10-04-2007, 11:05 PM | #13 | |
Quote:
That makes more sense, since "function X" always seems to return the same thing. In any case, the two-trigger work-around works, and it cuts the amount of code down, too. ![]() |
