• 🏆 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] Why is unit not stopping?

Status
Not open for further replies.
I'm trying to order a unit to stop:

JASS:
    private function TankerOrderCndAcn takes nothing returns boolean
        local integer targetId = GetUnitTypeId(GetOrderTargetUnit())
        local string orderStr = OrderId2String(GetIssuedOrderId())
        local string targetStr = null
        local unit tanker = null
    
        if orderStr == "returnresources" and targetId != 'h000' then
            set targetStr = "Refinery"
        elseif orderStr == "harvest" and targetId != 'h001' then
            set targetStr = "Platform"
        endif
    
        if targetStr != null then
            set tanker = GetOrderedUnit()
            call DisplayTextToPlayer(GetOwningPlayer(tanker), 1, 1, "|cffffcc00Must target an Oil "+targetStr+".|r")
            call IssueImmediateOrder(tanker, "stop")
            call BJDebugMsg(GetUnitName(tanker)) // Correctly shows unit's name
            set tanker = null
        endif
    
        return false
    endfunction

// .....

        call TriggerRegisterPlayerUnitEvent(trgTankerOrder, plr, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function TankerFltr)

        call TriggerAddCondition(trgTankerOrder, function TankerOrderCndAcn)

But it's not happening. Any idea why?
The abilities with "returnresources"/"harvest" are custom Channel abilities, TankerFltr just filters by unit type.
 
Try pausing the unit first before issuing the stop command. Unpause the unit afterwards.

The solution above is notable for overriding the current order of the unit, and may affect Shift-Queue orders.

Ah, so if the unit is paused first, it will not remove queued orders? :D
Edit: just tested, queued orders still removed so I must've misunderstood. Unit is stopping now though!
Is there a way to cancel the order without removing queued orders?

The order for stun might be a better alternative to stop. Prevent an Unit Order
Why is it better? The thread doesn't make that clear to me.
 
Last edited:
I believe it's something like:

stoporder is instant
moveorder is not instant

  1. Unit gets move order, but does not instantly finish, comes in queue
  2. Unit gets stop order, gets processed right away and overrides move order, and is finished right after, no queue
    => stop order has finished, and now move order still comes from queue
with pause:
  1. Unit gets move order, not instantly finishes, comes in queue
  2. Pause & Unpause unit -> clears the order queue
  3. Order stop, overrides move ordered move
Is there a way to cancel the order without removing queued orders?
Waiting a short amount of time might maybe work, that the stop really gets ordered after the move order has really finished. (maybe timer with "0" is not long enough..)
 
Well, anything the player orders with shift-rightclick.
So I want to cancel the order from the code above, without removing queued orders added by shift-rightclicking.

Simply doing this:
JASS:
        call UnitRemoveAbility(tanker, abilId)
        call TriggerSleepAction(0)
        call UnitAddAbility(tanker, abilId)

Will cancel the order corresponding to that ability, while retaining shift-queued orders.

The (mostly) complete example:
JASS:
    private function TankerOrderCnd takes nothing returns boolean
        local string orderStr = OrderId2String(GetIssuedOrderId())
        local integer targetId = GetUnitTypeId(GetOrderTargetUnit())
        return (orderStr == "returnresources" and targetId != 'h000' and targetId != 'h002') or (orderStr == "harvest" and targetId != 'h001')
    endfunction
 
    private function TankerOrderAcn takes nothing returns nothing
        local string str = OrderId2String(GetIssuedOrderId())
        local unit tanker = GetOrderedUnit()
        local integer id
     
        if str == "returnresources" then
            set id = 'A001'
            set str = "a Shipyard or an Oil Refinery"
        elseif str == "harvest" then
            set id = 'A000'
            set str = "an Oil Platform"
        endif
     
        if not GetSoundIsPlaying(SND_ERR) then
            call StartSound(SND_ERR)
        endif
        call DisplayTimedTextToPlayer(GetOwningPlayer(tanker), 0.512, 0, 10, "|cffffcc00Must target "+str+".|r")
        call UnitRemoveAbility(tanker, id)
        call TriggerSleepAction(0)
        call UnitAddAbility(tanker, id)
     
        set tanker = null
    endfunction

// ... initializer:


        call TriggerRegisterPlayerUnitEvent(trgTankerOrder, plr, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function TankerFltr)
        call TriggerAddCondition(trgTankerOrder, function TankerOrderCnd)
        call TriggerAddAction(trgTankerOrder, function TankerOrderAcn)

The downside is that you can see the ability disappear for a moment. It will probably also work if you disable the ability instead, and then you won't see it disappear.
 
Ah ok, yes. Thanks for explanation.
I don't know all prequities anymore, but I applied same method some time in some abilities in a map, example Trigger Viewer | HIVE. I remove ability onOrder, and add the ability again after 0 duration timer, and iirc it works without noticing the ability being removed. But yes if disable ability works it's probably better.
 
Status
Not open for further replies.
Top