HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

[IssuePointOrderById] - Frozen orders?

05-20-2010, 09:18 PM#1
watterly
Hi,

I am ordering a unit to cast a spell by using IssuePointOrderById or IssueTargetOrderById and sometimes, not all the time, the spell isn't cast and the unit is "frozen", the spell is green-white contoured but isn't cast... Using IssuePointOrderById returns true; the unit is really ordered but is not doing it... Here is a screenshot



I've tried puting the Animation Backswing and the other one to 0; it's not that... It's really random. Do anyone has ever seen that?

Thanks!
05-20-2010, 11:03 PM#2
Troll-Brain
It could be event related.
Also why this square on the floor, do you use a structure for your unit ?
05-21-2010, 12:10 AM#3
Ammorth
Quote:
Originally Posted by Troll-Brain
Also why this square on the floor, do you use a structure for your unit ?

Looks like it is for a TD.
05-21-2010, 12:28 PM#4
DioD
nice 2mb screenshoot.

there is no way to debug code by screenshoot.
05-21-2010, 02:29 PM#5
watterly
Hi,

It is for a TD.

I'm already on another forum trying to find why it's not working; it seems it might not be related to the code since I've made a test map and the bug is there.

Spell Frozen Bug

Uses the 4 Water Elementals and order-attack them a moving gnoll... You'll see sometimes, the elemental doesn't cast the spell and stops literally. (mostly when auto-attacking).
05-21-2010, 03:26 PM#6
Troll-Brain
I did few tests, and my guess seems correct, i can't reproduce the bug if i use a Timer(0) to order attacker to cast the spell on target when the attack event fire.

EDIT : Irrelevant note, but since you use string orders and not ids, you could just use the function IssuePointOrder, it's even shorter to type, and you won't need to use the function OrderId anymore.
05-21-2010, 06:10 PM#7
WaterKnight
Positive, when the event EVENT_UNIT_ATTACKED or EVENT_PLAYER_UNIT_ATTACKED fires, the unit is in fulfilling its order and on a quite critical point, a marginal one. So overlapping the order with a new one is not very secure.

The same happens with the similar EVENT_UNIT_TARGET_IN_RANGE.

I could not reconstruct the problem yet when pausing/unpausing the unit before reordering, although this also seems risky:

Code:
public function Attack takes nothing returns nothing
 local unit lanceur = GetAttacker()
 local unit cible = GetTriggerUnit()
 local integer lvl = GetUnitAbilityLevel(lanceur,spellid1) 
 call PauseUnit(lanceur, true)
 call PauseUnit(lanceur, false)
 if GetUnitState(lanceur,UNIT_STATE_MANA)>=manacost1+manacostperlvl1*lvl then
    if IssueTargetOrderById(lanceur,OrderId("carrionswarm"),cible)==true then
        //call ReOrderDelayed(lanceur,1)
    endif    
 endif
 set lanceur = null
 set cible = null
endfunction

Else you might add a timer like Troll-Brain suggested or going with another event. For example, you could give the unit an instant attack and capture an EVENT_UNIT_DAMAGED for its targets. To cast active spells on attack you might also use an orb ability that channels the desired spell through itself.

Afaik orb effects only react when the unit is actively using the "attack" order and not if the target was automatically chosen to attack by AI, so you might have to reorder the attack.
05-21-2010, 11:19 PM#8
watterly
Puting 0 timer seems to be fixing the problem.

Take in note that not all spells requires that 0 timer to be working; in fact only 3 of them on maybee 150 requires this 0 timer to work correctly.

One of my spell required a 0 timer that runned 3 times to work correctly; I had to order to unit 3 times in a row to ensure that the spell is really cast.

Thanks everyone for your help.
05-22-2010, 10:19 AM#9
Troll-Brain
Quote:
One of my spell required a 0 timer that runned 3 times to work correctly; I had to order to unit 3 times in a row to ensure that the spell is really cast.

You mean you order it 3 times in the timer callback ?

Also instead of a timer(0), you could try to .execute/evaluate a function (which order the unit to cast the ability) sometimes opening a new thread works.
It's worth a try, because if it works that's definitely more elegant, cleaner,smother.

I don't really remember a such case where it works but i think it had to do with training events, and queue training remove/add.
05-22-2010, 05:19 PM#10
Bribe
He could also use
Collapse JASS:
call ExecuteFunc("FuncName")
, however that is slower than both. But I like having different options, and
Collapse JASS:
ExecuteFunc
does not create a whole trigger just to run that one little deal.
05-24-2010, 05:01 PM#11
Troll-Brain
Quote:
Originally Posted by Bribe
He could also use
Collapse JASS:
call ExecuteFunc("FuncName")
, however that is slower than both. But I like having different options, and
Collapse JASS:
ExecuteFunc
does not create a whole trigger just to run that one little deal.
Yes he could, but to be honest i don't really care about this trigger creation, neither the speed issue. (Execute/evaluate a trigger is supposed to be faster than ExecuteFunc, but i have never tested it just read this sentence)

I care much more about how errors are handled.

typo or wrong name

- ExecuteFunc

Make wc3 crash, and it could be hard to find where the code is wrong.
Also this make the optimisation of the map script harder.

- .execute/evaluate


The error is showed during the compilation, or eventually nothing run (null (0) function interface), so easily noticeable.
Also because of function interface it makes the code far more easier to edit the code later.
05-24-2010, 05:41 PM#12
Tot
Quote:
Originally Posted by Troll-Brain
I care much more about how errors are handled.

typo or wrong name

- ExecuteFunc

Make wc3 crash, and it could be hard to find where the code is wrong.
Also this make the optimisation of the map script harder.

not really; simply use ExecuteFunc(myFunctionWithSomeStupidName.name)
hail JH
05-24-2010, 06:03 PM#13
Troll-Brain
Oh well, fair enough.

I've forgotten an other thing about function interface though.
You can have arguments and a returns something, when you can't with ExecuteFunc.
Ofc in the background it uses a workaround with global variables, but you don't have to do it yourself.

vJass was always be done to make code easier, not run code smoother.

But in this example you don't need arguments, neither returns something, so i'm agree that ExecuteFunc is a valid way here.
Even if strings are poorly managed in wc3 though.
05-24-2010, 07:05 PM#14
Tot
yea, I use it mainly for funtions-that-need-to-be-run-once-but-require-their-own-thred-to-go-round-the-po-limit-execution, where function interfaces/triggers would be simple memory-waste