- Joined
- Oct 10, 2009
- Messages
- 439
20 years later some fresh faced hobbiest discovers a filthy, unwashed hack to calculate if a unit can path in a single frame. Impressive work master duck farter, may you keep huffing those farts.
Is Point Reachable System

Events

Conditions

Actions


-------- This system takes advantage of some of Wc3's own pathfinding from the ability Call to Arms --------


-------- to detect if a point is reachable which has two limitations: --------


-------- 1. Can only detect reachability for ground units with less than 32 collision size --------


-------- 2. Has limited "range" to find a path --------


-------- NOTE: Requires both points to have terrain walkability --------


Custom script: local integer i = 1


Custom script: local real array x


Custom script: local real array y


Custom script: set x[1] = GetLocationX(udg_IPR_Point[2])


Custom script: set y[1] = GetLocationY(udg_IPR_Point[2])


Custom script: set x[2] = GetLocationX(udg_IPR_Point[1])


Custom script: set y[2] = GetLocationY(udg_IPR_Point[1])


-------- Stops false negatives with ~ equal XY --------


Custom script: if SquareRoot((x[2]-x[1])[I](x[2]-x[1]) + (y[2]-y[1])[/I](y[2]-y[1])) < 16 then


Custom script: set udg_IPR_IsPointReachable = true


Custom script: else


-------- Enables abilities --------


Custom script: call BlzUnitDisableAbility(udg_IPR_Unit[1], udg_IPR_CallToArms[1], false, false)


Custom script: call BlzUnitDisableAbility(udg_IPR_Unit[2], udg_IPR_CallToArms[2], false, false)


Custom script: call BlzUnitDisableAbility(udg_IPR_Unit[1], 'Amov', false, false)


-------- Checks reachability from both points using Call to Arms --------


Custom script: loop


Custom script: call SetUnitX(udg_IPR_Unit[1], x[i])


Custom script: call SetUnitY(udg_IPR_Unit[1], y[i])


Custom script: call SetUnitX(udg_IPR_Unit[2], x[2/i])


Custom script: call SetUnitY(udg_IPR_Unit[2], y[2/i])


Custom script: call IssueImmediateOrderById(udg_IPR_Unit[1], 852072)


Custom script: if GetUnitCurrentOrder(udg_IPR_Unit[1]) == 852072 then


Custom script: set udg_IPR_IsPointReachable = true


Custom script: exitwhen true


Custom script: else


Custom script: set udg_IPR_IsPointReachable = false


Custom script: endif


Custom script: set i = i + 1


Custom script: exitwhen i > 2


Custom script: endloop


-------- Disables abilities --------


Custom script: call BlzUnitDisableAbility(udg_IPR_Unit[1], udg_IPR_CallToArms[1], true, false)


Custom script: call BlzUnitDisableAbility(udg_IPR_Unit[2], udg_IPR_CallToArms[2], true, false)


-------- Disabling 'Amov' stops Transmitter (1) --------


Custom script: call BlzUnitDisableAbility(udg_IPR_Unit[1], 'Amov', true, false)


Custom script: endif
Demo 3

Events


Unit - A unit Is issued an order targeting a point

Conditions


(Issued order) Equal to (Order(blink))


(Unit-type of (Triggering unit)) Equal to Warden

Actions


-------- How to use: --------


-------- 1) Set IPR_Point[1] --------


Set VariableSet IPR_Point[1] = (Position of (Triggering unit))


-------- 2) Set IPR_Point[2] --------


Set VariableSet IPR_Point[2] = (Target point of issued order)


-------- 3) Make sure both points have terrain walkability --------


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




(Terrain pathing at IPR_Point[1] of type Walkability is off) Equal to False




(Terrain pathing at IPR_Point[2] of type Walkability is off) Equal to False



Then - Actions




-------- 4) Run Is Point Reachable System --------




Trigger - Run Is Point Reachable System <gen> (ignoring conditions)




-------- Debug --------




If (All Conditions are True) then do (Then Actions) else do (Else Actions)





If - Conditions






IPR_IsPointReachable Equal to True





Then - Actions






Game - Display to (All players) for 2.00 seconds the text: |cff00ff00√|r





Else - Actions






Game - Display to (All players) for 2.00 seconds the text: |cffff0000X|r




-------- ---- --------



Else - Actions




Set VariableSet IPR_IsPointReachable = False




-------- Debug --------




Game - Display to (All players) for 2.00 seconds the text: |cff8080ffX|r




-------- ---- --------


Custom script: call RemoveLocation(udg_IPR_Point[1])


Custom script: call RemoveLocation(udg_IPR_Point[2])


-------- 5) IPR_IsPointReachable is True if reachable --------


If (All Conditions are True) then do (Then Actions) else do (Else Actions)



If - Conditions




IPR_IsPointReachable Equal to False



Then - Actions




Unit - For Unit (Triggering unit), start cooldown of ability Blink " over "0.01 seconds.



Else - Actions
library IsPointReachable//by Duckfarter
/* Configuration:
¯¯¯¯¯¯¯¯¯¯¯¯¯¯ */
globals
private constant integer TRANSMITTER = 'nipt'
private constant integer RECEIVER = 'nipr'
private constant integer C1 = 'Aipt'
private constant integer C2 = 'Aipr'
endglobals
/*
IsPointReachable 1.4
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Description:
¯¯¯¯¯¯¯¯¯¯¯¯
This library takes advantage of some of Wc3's own pathfinding from the ability Call to Arms
to detect if xy co-ordinates are reachable which has two limitations:
1. Can only detect reachability for ground units with less than 32 collision size
2. Has limited "range" to find a path
NOTE: Requires both xy co-ordinates to have terrain walkability
API:
¯¯¯¯
| function IsPointReachable takes real x1, real y1, real x2, real y2 returns boolean
How to import:
¯¯¯¯¯¯¯¯¯¯¯¯¯¯
1. Copy abilities Call to Arms (Transmitter) ID: Aipt, and Call To Arms (Receiver) ID: Aipr
2. Copy units Transmitter (1) ID: nipt, and Receiver (2) ID: nipr
3. Copy trigger IsPointReachable
Link:
¯¯¯¯¯
https://www.hiveworkshop.com/threads/is-point-reachable-1-4.353693/
*/
globals
private unit uT
private unit uR
private integer i
private real array xF
private real array yF
endglobals
function IsPointReachable takes real x1, real y1, real x2, real y2 returns boolean
//Stops false negatives with ~ equal XY
if SquareRoot((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) < 16 then
return true
endif
//Enables abilities
call BlzUnitDisableAbility(uT, C1, false, false)
call BlzUnitDisableAbility(uR, C2, false, false)
call BlzUnitDisableAbility(uT, 'Amov', false, false)
//Checks reachability from both points using Call to Arms
set xF[1] = x2
set yF[1] = y2
set xF[2] = x1
set yF[2] = y1
set i = 1
loop
call SetUnitX(uT, xF[i])
call SetUnitY(uT, yF[i])
call SetUnitX(uR, xF[2/i])
call SetUnitY(uR, yF[2/i])
call IssueImmediateOrderById(uT, 852072)
if GetUnitCurrentOrder(uT) == 852072 then
call BlzUnitDisableAbility(uT, C1, true, false)
call BlzUnitDisableAbility(uR, C2, true, false)
//Disabling 'Amov' stops uT
call BlzUnitDisableAbility(uT, 'Amov', true, false)
return true
endif
set i = i + 1
exitwhen i > 2
endloop
//Disables abilities
call BlzUnitDisableAbility(uT, C1, true, false)
call BlzUnitDisableAbility(uR, C2, true, false)
call BlzUnitDisableAbility(uT, 'Amov', true, false)
return false
endfunction
//Used for LIBRARY_GetShortestPathUnit
function GetTransmitterUnit takes nothing returns unit
return uT
endfunction
function GetReceiverUnit takes nothing returns unit
return uR
endfunction
private module Init
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
private struct InitStruct extends array
private static method init takes nothing returns nothing
set uT = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TRANSMITTER, 0, 0, 0)
set uR = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), RECEIVER, 0, 0, 0)
call BlzUnitDisableAbility(uT, C1, true, false)
call BlzUnitDisableAbility(uR, C2, true, false)
call BlzUnitDisableAbility(uT, 'Amov', true, false)
call ShowUnit(uT, false)
call ShowUnit(uR, false)
endmethod
implement Init
endstruct
endlibrary