• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

My work-around fix for "Orb of Slow"

Status
Not open for further replies.
Hello,

You may know the following abilities:
- Orb of Slow
- Orb of Lightning
- Attack black arrow bonus
- Melee Lightning Damage Bonus

They are similar, and allow you to make normal attacks have a chance of casting any ability with a target. However they have a known weird issue in which, you didn't ordered the owner of the ability to do something, and even if you have put the chance to do the ability to 100%, it will never fire.

So I have been working on a "work-around" fix for this matter. After hours and hours of experimenting and programming, I got a detailed analysis and a custom fix that works !! It is MUI and I tested it OK with all the cases I thought of (patrol, hold position, attack, smart, move, guard-position consistence...) :)

Detailed analysis:
First impressions
The ability only casts when players manually gave one of the following orders:
- Order targeting an object (unit): smart (right-click), attack
- Order targeting a point (any point, but order must not be over): attack ground, attack-move, patrol

Test cases (logging last order issued & current order)
OK - Unit is on patrol, and engages a target: lastevent=patrol, currentorder=_
OK - Unit is still doing an attack position order: lastevent=attack, currentorder=attack
OK - Unit is attacking an unit because of an attack or smart order: lastevent=attack/smart, currentorder=attacks/mart (both are identical)
KO - Unit is holding position: lastevent=holdposition, currentorder=_
KO - Unit aquires a new target, and was stopped before: lastevent=stop, current=_
KO - Unit aquires a new target, and last order was irrelevant (learn skill, use skill, etc...): lastevent=****, current=_
KO - Unit finished an attack position, smart or move order; then aquires a target: lastevent=attack/smart/move, currentorder=_
KO - Unit finished an attack or smart order (the unit died or became invisible/invincible), and aquires a new one: lastevent=smart/attack, currentorder = _

How to use:
When you create a unit with the bugged ability, or when a unit learns the bugged ability, just call RegisterUnitForOosFix(<unit>). My code handles the rest (target aquisition, improper orders handle, unit death...).

Triggers:
OosFix RegisterUnit (JASS API function)
JASS:
function RegisterUnitForOosFix takes unit u returns nothing
    // Unit issued order events
    if ( IsTriggerEnabled( gg_trg_OosFix_UnitIssuedOrder ) == false ) then
        call EnableTrigger( gg_trg_OosFix_UnitIssuedOrder )
    endif
    call TriggerRegisterUnitEvent( gg_trg_OosFix_UnitIssuedOrder, u, EVENT_UNIT_ISSUED_TARGET_ORDER )
    call TriggerRegisterUnitEvent( gg_trg_OosFix_UnitIssuedOrder, u, EVENT_UNIT_ISSUED_POINT_ORDER )
    call TriggerRegisterUnitEvent( gg_trg_OosFix_UnitIssuedOrder, u, EVENT_UNIT_ISSUED_ORDER )
 
    // Unit acquires target event
    if ( IsTriggerEnabled( gg_trg_OosFix_UnitTargetAcquisition ) == false ) then
        call EnableTrigger( gg_trg_OosFix_UnitTargetAcquisition )
    endif
    call TriggerRegisterUnitEvent( gg_trg_OosFix_UnitTargetAcquisition, u, EVENT_UNIT_ACQUIRED_TARGET )
endfunction

OosFix UnitIssuedOrder (GUI)
  • OosFix UnitIssuedOrder
    • Events
    • Conditions
    • Actions
      • Set TempBoolean = True
      • -------- Patrol order is ignored if distance is too short, because no action was taken by the unit --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (String((Issued order))) Equal to patrol
        • Then - Actions
          • Set TempPoint = (Position of (Ordered unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between TempPoint and (Target point of issued order)) Less than 100.00
            • Then - Actions
              • Set TempBoolean = False
            • Else - Actions
              • Do nothing
          • Custom script: call RemoveLocation(udg_TempPoint)
        • Else - Actions
          • Do nothing
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TempBoolean Equal to True
        • Then - Actions
          • Hashtable - Save (String((Issued order))) as (Key UnitIssuedOrder) of (Key (Ordered unit)) in GameCache
        • Else - Actions
          • Do nothing

OosFix UnitTargetAcquisition (GUI)
  • OosFix UnitTargetAcquisition
    • Events
    • Conditions
    • Actions
      • -------- Retrieve unit issued order --------
      • Set TempString1 = <Empty String>
      • Set TempString1 = (Load (Key UnitIssuedOrder) of (Key (Triggering unit)) from GameCache)
      • -------- Case A: unit was forced back to holdposition, but re-acquires a target --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TempString1 Equal to holdpositionforced
        • Then - Actions
          • Trigger - Turn off OosFix UnitIssuedOrder <gen>
          • -------- Attack-move in place: preserves guard position. --------
          • Set TempPoint = (Position of (Triggering unit))
          • Unit - Order (Triggering unit) to Attack-Move To TempPoint
          • Custom script: call RemoveLocation(udg_TempPoint)
          • Trigger - Turn on OosFix UnitIssuedOrder <gen>
          • Unit Group - Add (Triggering unit) to BugFixHoldPositionResumeGroup
          • Trigger - Turn on OosFix HoldPositionResume <gen>
          • Hashtable - Save holdposition as (Key UnitIssuedOrder) of (Key (Triggering unit)) in GameCache
        • Else - Actions
          • Do nothing
      • -------- Case B: hold position order is under execution --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TempString1 Equal to holdposition
        • Then - Actions
          • -------- Wait for the end of this acquisition, then reload variable to ensure MUI --------
          • Wait 0.01 seconds
          • Set TempString1 = <Empty String>
          • Set TempString1 = (Load (Key UnitIssuedOrder) of (Key (Triggering unit)) from GameCache)
          • Trigger - Turn off OosFix UnitIssuedOrder <gen>
          • -------- Force back to hold position. Cancels previous acquisition. --------
          • Unit - Order (Triggering unit) to Hold Position
          • Trigger - Turn on OosFix UnitIssuedOrder <gen>
          • Hashtable - Save holdpositionforced as (Key UnitIssuedOrder) of (Key (Triggering unit)) in GameCache
        • Else - Actions
          • Do nothing
      • -------- Case C: no order under execution for the moment --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TempString1 Not equal to patrol
          • TempString1 Not equal to holdposition
          • TempString1 Not equal to holdpositionforced
          • (String((Current order of (Triggering unit)))) Equal to <Empty String>
        • Then - Actions
          • Trigger - Turn off OosFix UnitIssuedOrder <gen>
          • -------- Attack-move in place: preserves guard position. Do not change acquisition. --------
          • Set TempPoint = (Position of (Triggering unit))
          • Unit - Order (Triggering unit) to Attack-Move To TempPoint
          • Custom script: call RemoveLocation(udg_TempPoint)
          • Trigger - Turn on OosFix UnitIssuedOrder <gen>
        • Else - Actions
      • -------- Case DEFAULT: no change, preserves orders under-execution. --------
      • -------- Else: string(UnitIssuedOrder) == "patrol" or (string(UnitIssuedOrder) != "holdposition" string(current order) != <string vide>) --------

OosFix HoldPositionResume (GUI)
  • OosFix HoldPositionResume
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in BugFixHoldPositionResumeGroup and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is dead) Equal to True
            • Then - Actions
              • Unit Group - Remove (Picked unit) from BugFixHoldPositionResumeGroup
            • Else - Actions
              • Set TempString1 = <Empty String>
              • Set TempString1 = (Load (Key UnitCurrentOrder) of (Key (Picked unit)) from GameCache)
              • Set TempString2 = <Empty String>
              • Set TempString2 = (Load (Key UnitIssuedOrder) of (Key (Picked unit)) from GameCache)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TempString1 Equal to (String((Current order of (Picked unit))))
                • Then - Actions
                  • Do nothing
                • Else - Actions
                  • Hashtable - Save (String((Current order of (Picked unit)))) as (Key UnitCurrentOrder) of (Key (Picked unit)) in GameCache
                  • -------- Case A: last issued order is hold position (normal or forced), and changes from something to idle --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • TempString1 Not equal to holdposition
                      • Or - Any (Conditions) are true
                        • Conditions
                          • TempString2 Equal to holdposition
                          • TempString2 Equal to holdpositionforced
                      • (String((Current order of (Picked unit)))) Equal to <Empty String>
                    • Then - Actions
                      • Trigger - Turn off OosFix UnitIssuedOrder <gen>
                      • -------- Force back to hold position. --------
                      • Unit - Order (Picked unit) to Hold Position
                      • Trigger - Turn on OosFix UnitIssuedOrder <gen>
                      • Unit Group - Remove (Picked unit) from BugFixHoldPositionResumeGroup
                    • Else - Actions
                      • Do nothing
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (BugFixHoldPositionResumeGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
          • Do nothing
 
Last edited:
Status
Not open for further replies.
Top