- Joined
- Feb 27, 2019
- Messages
- 401
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:
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)
OosFix UnitIssuedOrder (GUI)
OosFix UnitTargetAcquisition (GUI)
OosFix HoldPositionResume (GUI)
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 = _
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: