- 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.
library IsPointReachable//by Duckfarter
/* Configuration:
¯¯¯¯¯¯¯¯¯¯¯¯¯¯ */
globals
private constant integer TRANSMITTER = 'nipt'
private constant integer RECIEVER = 'nipr'
private constant integer C1 = 'Aipt'
private constant integer C2 = 'Aipr'
endglobals
/*
IsPointReachable 1.3
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
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 (Reciever) ID: Aipr
2. Copy units Transmitter (1) ID: nipt, and Reciever (2) ID: nipr
3. Copy trigger IsPointReachable
Link:
¯¯¯¯¯
https://www.hiveworkshop.com/threads/is-point-reachable-1-3.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 GetRecieverUnit 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), RECIEVER, 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