• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Overwrite issued order by scripted order... doesn't work anymore?

Status
Not open for further replies.
Level 20
Joined
Jul 10, 2009
Messages
477
Hi guys,

I was used to overwrite user given orders by scripted orders like this:

  • Overwrite Point Order By Stop
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
    • Actions
      • Unit - Order (Triggering unit) to Stop.
The trigger above should prevent units from accepting point orders like "move", but since patch 1.32.X, it doesn't work anymore (pretty sure, it did before).

  • Display Orders On Screen
    • Events
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order with no target
    • Conditions
    • Actions
      • Game - Display to (All players) for 30.00 seconds the text: (String((Issued order)))
Displaying all orders on screen clearly shows that both the move and the stop order are issued.
Just, the stop order is either ignored or comes before the move order, unlike in previous wc3 versions.

Do you guys have any insight on why this doesn't work anymore? I sadly can't run tests on older versions anymore, cause my 1.28 editor recently stopped functioning :(

Best regards and stay healthy
Eikonium
 
Level 20
Joined
Jul 10, 2009
Messages
477
I'm afraid, that doesn't solve the problem. My units still can move as they please.

  • Overwrite Point Order By Stop v2
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
    • Actions
      • Unit - Pause (Triggering unit)
      • Unit - Unpause (Triggering unit)
      • Unit - Order (Triggering unit) to Stop.
As far as I remember, pausing lets a unit remember its orders and continue them after unpausing? Doesn't that contradict the statement that pausing clears order queues?

Displaying the orders on screen kind of shows the pausing behaviour, I guess.
While the trigger in the original post produced "stop[linebreak]smart" on screen, the current one (v2) does "stop[linebreak](null)[linebreak]stop[linebreak]smart". So the stop order is reissued after unpausing the unit, but still the event triggering order smart/move comes afterwards.

It looks to me like the order queue processing sequence has changed recently from normal to reverse.
Can anybody confirm?
 
Level 20
Joined
Jul 10, 2009
Messages
477
Try to disable the trigger at first, and enabling it after the "stop" again. But keep the pause/unpause.
That works. For some reason, "pausing" fires the "Issue Point Order"-Event (which you prevent by deactivating the trigger).
  • Overwrite Point Order By Stop v3
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
    • Actions
      • Trigger - Turn off (This trigger)
      • Unit - Pause (Triggering unit)
      • Unit - Unpause (Triggering unit)
      • Unit - Order (Triggering unit) to Stop.
      • Trigger - Turn on (This trigger)
Still, this solution is giving me a bug: Trying to move my sample Footman leads to the following orders on screen:
Undefend.png

You notice that there is an undefend in between that should never have been issued. I didn't even have the research for defend ready, so the ability was locked on the Footman (and the undefend was still ordered).
I do fear now that this trigger might interfere with other unit's abilities at unpredictable times.

So I have to ask: Is there any other method of clearing the order queue or solving the issue in the original post?

Remove pauses and put a wait 0s before the stop order.
Thanks for your suggestion, but that doesn't solve the problem. The 0-Wait is enough to let the unit move a little bit.
 
Level 14
Joined
Feb 7, 2020
Messages
386
Didn't know this kind of thing didn't work anymore.

Mimicking your code, the only thing that stopped properly was Patrol.

I got it to work with the attached map though it's a bit janky. I'm also not certain it has 100% recursive protection if some action-skip bug occurs. Could be fool-proof fixed by allowing a certain number of calls per sec or something with an incremented integer. The game crashes on an infinite order trigger loop being called (found out the hard way :)).

  • Clear Queue
    • Events
      • Unit - A unit owned by Player 1 (Red) Is issued an order targeting a point
      • Unit - A unit owned by Player 1 (Red) Is issued an order targeting an object
    • Conditions
      • toggle Equal to False
    • Actions
      • Game - Display to (All players) the text: (Movement Was: + (String((Issued order))))
      • Set VariableSet loc = (Position of (Triggering unit))
      • Set VariableSet toggle = True
      • Unit - Order (Triggering unit) to Right-Click loc
      • Set VariableSet toggle = False
      • Custom script: call RemoveLocation(udg_loc)
 

Attachments

  • stop_move_fix.w3m
    13.1 KB · Views: 29
Last edited:
@Eikonium
The (null) order is the "pause" order, it has no string name, just an id (851973). So it seems like a invalid order name.

And it's the "pause" order that fires the "undefend" order. It's a common case specifically for the "undefend" order that units will automatically order in some cases. In past some people found out that killing or removing a unit will also always fire the "undefend" order for example, also unrelated to the research of defend ability. Just all units always will do this.

This behaviour that units automatically order "undefend" in such situations is by the way also the hack to get the custom deindex or "A unit is removed from game" event, because people abused it to give every unit a custom "defend" ability, and just wait the units to order "undefend". This, in combination with some checks can provide the event when a unit is removed from game.
 
Last edited:

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,870
This seems to work.
  • Stop
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
    • Actions
      • Custom script: call SetUnitPropWindow( GetTriggerUnit(), 0)
      • Wait 0.00 seconds
      • Unit - Order (Triggering unit) to Stop.
Still, I'm not sure if you want to reset the prop window after.
 
Level 20
Joined
Jul 10, 2009
Messages
477
I have solved the problem now, thanks a lot for all of your input!

I should have mentioned more clearly that the stop thing in my original post was just an example to grasp the underlying problem. My actual goal was to be able to overwrite any user issued order by any scripted order.
Your posts helped me understanding that immediate orders can be used after pausing and unpausing the triggering unit, while other order types (like move) work out of the box.
The pausing and unpausing prior to immediate orders however is delaying the immediate order by just the tiny bit that lets the Disable/Enable trigger wrap not making the trigger recursion safe anymore.
In other words, this trigger will crash Wc3 in a bit of time, because the actions will trigger the event again after a tiny delay.
  • Wc3 Crash - Overwrite Point Order By Stop
    • Events
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order with no target
      • Unit - A unit Is issued an order targeting an object
    • Conditions
    • Actions
      • Trigger - Turn off (This trigger)
      • Unit - Pause (Triggering unit)
      • Unit - Unpause (Triggering unit)
      • Unit - Order (Triggering unit) to Stop.
      • Trigger - Turn on (This trigger)
The crash can neither be prevented by disabling/enabling the trigger (like shown above) nor by setting a global variable (like in Planetary's example).

But the crash can be prevented by memorizing the last order that triggered the event (for every unit separately) and checking for if both the order and order target are the same as last time (and if yes, skip remaining trigger actions). You also have to exclude the pause order from firing the event obviously. That's what I am doing now and I'm fine with that solution :)

I got it to work with the attached map though it's a bit janky.
Nice idea to replace stop by a trivial move order! Sorry for not letting you know that I wanted to make it work for any desired scripted order, not just stop.

@Eikonium
The (null) order is the "pause" order, it has no string name, just an id (851973). So it seems like a invalid order name.

And it's the "pause" order that fires the "undefend" order. It's a common case specifically for the "undefend" order that units will automatically order in some cases. In past some people found out that killing or removing a unit will also always fire the "undefend" order for example, also unrelated to the research of defend ability. Just all units always will do this.

This behaviour that units automatically order "undefend" in such situations is by the way also the hack to get the custom deindex or "A unit is removed from game" event, because people abused it to give every unit a custom "defend" ability, and just wait the units to order "undefend". This, in combination with some checks can provide the event when a unit is removed from game.
Thanks for the insight! Good to know!

This seems to work.
  • Stop
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
    • Actions
      • Custom script: call SetUnitPropWindow( GetTriggerUnit(), 0)
      • Wait 0.00 seconds
      • Unit - Order (Triggering unit) to Stop.
Still, I'm not sure if you want to reset the prop window after.
Thanks for your suggestion. It gave me the useful knowledge that SetUnitPropWindow disables movement speed (didn't know before) and will definitely use that in my map! :)
However, I don't want to use a solution with 0-waits for the original problem. This would actually introduce a small delay, where the unit doesn't do anything, right?
 
Status
Not open for further replies.
Top