I have a trigger:
And the Delayed Order function does:
But it doesn't work, and the unit keeps "blinking" to watter terrain and into forests...
How do I PROPERLY check if terrain is walkable?
EDIT: Actually, seems like the order given wasn't "blink" and that's why the trigger wasn't kicking in... Now it prevents me from blinking on the ground... I can only blink in water... The logic is stunning me..
EDIT 2: Actually, now I think I can make something, which will work..
When I remove the "not" from the condition - I can move around on the ground, but can't enter water (which is good, although weird, because of the syntax Blizzard has chosen). Now I can make a custom function to create a unit on the desired coordinates, and then compare the unit's coordinates to the original ones, if they aren't the same (or at least close) - it will return false xP
EDIT 3: Okay... I kind a managed to get it working.. Here are the triggers if you are having issues with similar problem
I did the condition in this "tree shape" to make it as light as possible, and not to do unnecessary checks, unless the other conditions are fulfilled.
JASS:
function FlightRequiresWalkable takes nothing returns boolean
if GetIssuedOrderId() == OrderId("blink") and not IsTerrainPathable(GetOrderPointX(), GetOrderPointY(), PATHING_TYPE_WALKABILITY) then
call IssueDelayedOrder(GetTriggerUnit(), "stop", "immediate", null, 0, 0)
endif
return false
endfunction
//during initialization:
call TriggerRegisterAnyUnitEventBJ( pr, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerAddCondition( pr, Condition( function FlightRequiresWalkable ) )
JASS:
function IssueDelayedOrder takes unit u, string order, string ordType, unit target, real x, real y returns nothing
local timer t
local integer id
if ordType == "immediate" then
set t = GetFreeTimer()
set id = GetHandleId(t)
call SaveUnitHandle(udg_Table, id, 'unit', u)
call SaveStr(udg_Table, id, 'ordr', order)
call TimerStart(t, 0.00, false, function DelayedImmediateOrder)
set t = null
elseif ordType == "target" then
set t = GetFreeTimer()
set id = GetHandleId(t)
call SaveUnitHandle(udg_Table, id, 'unit', u)
call SaveStr(udg_Table, id, 'ordr', order)
call SaveUnitHandle(udg_Table, id, 'targ', target)
call TimerStart(t, 0.00, false, function DelayedTargetOrder)
set t = null
elseif ordType == "point" then
set t = GetFreeTimer()
set id = GetHandleId(t)
call SaveUnitHandle(udg_Table, id, 'unit', u)
call SaveStr(udg_Table, id, 'ordr', order)
call SaveReal(udg_Table, id, 'tarx', x)
call SaveReal(udg_Table, id, 'tary', y)
call TimerStart(t, 0.00, false, function DelayedPointOrder)
set t = null
endif
endfunction
How do I PROPERLY check if terrain is walkable?
EDIT: Actually, seems like the order given wasn't "blink" and that's why the trigger wasn't kicking in... Now it prevents me from blinking on the ground... I can only blink in water... The logic is stunning me..
EDIT 2: Actually, now I think I can make something, which will work..
When I remove the "not" from the condition - I can move around on the ground, but can't enter water (which is good, although weird, because of the syntax Blizzard has chosen). Now I can make a custom function to create a unit on the desired coordinates, and then compare the unit's coordinates to the original ones, if they aren't the same (or at least close) - it will return false xP
EDIT 3: Okay... I kind a managed to get it working.. Here are the triggers if you are having issues with similar problem
JASS:
function IsPointWalkable takes real x, real y, real tollerance returns boolean
local unit d = CreateUnit(Player(15), 'hfoo', x, y, 0)
local real dist = (GetUnitX(d) - x)*(GetUnitX(d) - x) + (GetUnitY(d) - y)*(GetUnitY(d) - y)
call RemoveUnit(d)
set d = null
return dist < tollerance*tollerance
endfunction
JASS:
function FlightRequiresWalkable takes nothing returns boolean
local real x
local real y
local integer id
if GetIssuedOrderId() == OrderId("divineshield") then
set id = GetUnitTypeId(GetTriggerUnit())
if id == 'E00U' or id == 'E00V' or id == 'E00W' then
set x = GetOrderPointX()
set y = GetOrderPointY()
if IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) or not IsVisibleToPlayer(x, y, GetTriggerPlayer()) then
call IssueDelayedOrder(GetTriggerUnit(), "stop", "immediate", null, 0, 0)
call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "Can't fly to that position!")
elseif not IsPointWalkable(x, y, 100) then
call IssueDelayedOrder(GetTriggerUnit(), "stop", "immediate", null, 0, 0)
call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "Can't fly to that position!")
endif
endif
endif
return false
endfunction
Last edited: