[General] GetUnitCurrentOrder not detecting automated orders

So I've noticed that if you right-click on a target and your unit begins to attack, the order that is caught it smart, rather than attack. Similarly, if the target was acquired automatically, the order id returned is 0, meaning there wasn't even an order event that fired. It's only after specifically telling the unit to attack by pressing the attack icon and clicking on a target that the order will return 851983, the order id for attack.

There are similar issues with moving with right-click, which causes the order returned to be smart instead of move.

Does anyone have any idea how to circumvent that?
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,328
Whenever a unit is ordered smart, order it to do the specific order. I think you need to delay it with a 0 second timer, but I am not sure.
For example:
a unit is ordered targeting an object
- order == smart
- target unit is enemy
- target unit can be attacked by triggering unit

order triggering unit to attack target unit

or

a unit is ordered targeting a point
- order == smart

order triggering unit to move to point

It's a lot of work, because there are so many situations, where smart can be used.
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,328
The actions automatically performed are moving and attacking?
Both of them can be detected, so if your unit has no current order and it starts moving or attacking, you can order it to attack move to it's current position.
Auto acquiring targets while patroling is more difficult though, but at least the order is not 0, but patrol then.
 
From my tests, attacking upon auto-acquisition returns 0 on the attacker. I assume the same is true from a unit that moves to get in attack range after acquiring a target: the current order will still return 0. It may show what orders are being enacted on the command card, but the triggers say something else. Did a simple test with this:
JASS:
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    call BJDebugMsg(I2S(GetUnitCurrentOrder(GetAttacker())))
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_001, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction
 

Jampion

Code Reviewer
Level 15
Joined
Mar 25, 2016
Messages
1,328
That's not what I meant.

You use:

a unit is attacked
- attacking unit's order == 0

order attacking unit to attack move at position of attacking unit

and

a unit starts moving (this event does not exist, but there is a "unit is moving" system)
- moving unit's order == 0

order attacking unit to attack move at position of attacking unit

If a unit moves/attacks and has no order, movement/attacking is caused by auto acquiring a target. Then you change the order to a generic attack move command. I think attack move is better than directly ordering to attack the attacked unit, because a targeted attack would cause the unit to follow the target unit forever, which is bad for auto acquiring.
 

Kyrbi0

Arena Moderator
Level 42
Joined
Jul 29, 2008
Messages
9,412
I'm not sure if this is precisely what you are looking for, but I was messing around a while back, and discovered a GUI function called something like "unit acquires target" (or was it "unit enters acquisition range"?).

It basically works perfectly; the instant an enemy got within the (OE-specified) acquisition range of the trigger-specified unit, the action would fire off.

This only seemed to work on attacks, but hey.
 
Alright, I messed around with the idea proposed by Jampion and I have the following:
JASS:
    private function TurretActions takes nothing returns nothing
        local unit guest = LoadUnitHandle(TurretStorage, GetHandleId(GetTriggeringTrigger()), 0)
        local integer idGuest = GetUnitUserData(guest)
        set Cooldown[idGuest] = CooldownReset[idGuest]
        if GetUnitCurrentOrder(guest) != ORDER_ATTACK then
            //call IssueTargetOrderById(guest, ORDER_ATTACK, GetTriggerUnit())
            call IssuePointOrderById(guest, ORDER_ATTACK, GetUnitX(guest), GetUnitY(guest))
        endif
        set TurretPhase[idGuest] = true
        set guest = null
    endfunction
This action fires on two different events:
call TriggerRegisterUnitEvent(TurretTrigger[idGuest], guest, EVENT_UNIT_ACQUIRED_TARGET)
call TriggerRegisterUnitEvent(TurretTrigger[idGuest], guest, EVENT_UNIT_TARGET_IN_RANGE)

EVENT_UNIT_TARGET_IN_RANGE seems to fire every time a target is about to be attacked, which is good as it refreshes the internal cooldown the system I'm working on uses. Unfortunately, it doesn't seem to work all the time, and I have NO idea why. It's potentially unrelated the current issue, but if anyone has any insight on the difference b/w EVENT_UNIT_TARGET_IN_RANGE and EVENT_UNIT_ACQUIRED_TARGET, I'd love to hear 'em.
 

MyPad

Spell Reviewer
Level 26
Joined
May 9, 2014
Messages
1,773
^^ My guess as to their difference:

EVENT_UNIT_ACQUIRED_TARGET fires when a unit comes into the acquisition range of a unit.
EVENT_UNIT_TARGET_IN_RANGE fires when a unit comes into the attack range of a unit.

Suppose:
Unit:
Acquisition Range: 750
Attack Range: 500

Acquired Target: enemy within 750 units.
Target in range: enemy within 500 units, and can be attacked.

But those are my 50 cents.
 
Level 7
Joined
Feb 9, 2021
Messages
301
The thing is that EVENT_UNIT_TARGET_IN_RANGE seems to proc repeatedly (which is good for my purposes), but is restricted to facing angle. Additionally, I think it fires when a unit casts spells on a target as well? I'll need to test this when I get a moment.
Sorry for bringing up an old thread, but did you test it? I want to make a system, which turns off auto aggression
 
Top