• 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.

Is Point Reachable 1.3

This bundle is marked as high quality. It exceeds standards and is highly desirable.
What does it do?
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

How does it works?
It's based around the instant ability Call to Arms. When a peasant issues Call to Arms, it will try to find a path to the closest Town Hall and if a path can't be found the peasant won't retain the order, in contrast to the regular pathfinding where the peasant attempts to reach its destination, even if a path doesn't exist.

The system in detail
1) The distance between IPR_Point[1] and IPR_Point[2] is calculated to avoid false negatives, if less than 16 the point is considered reachable
2) The abilities Call to Arms (Transmitter), Call To Arms (Reciever) and Move are enabled
3) The unit Transmitter (1) is moved to IPR_Point[1] and Reciever (2) to IPR_Point[2]
4) Transmitter (1) issues Call To Arms
5) If Transmitter (1) has the order militia, the point is reachable
6) If Transmitter (1) doesnt have the order militia, the system repeats once from step 3) but swaps the points. This increases the range to find a path
7) The abilities Call to Arms (Transmitter), Call To Arms (Reciever) and Move are disabled. Disabling Move resets Transmitter (1)'s pathfinding
  • 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

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 category Is Point Reachable 1.3 [GUI]

How to use?
1) Set IPR_Point[1]
2) Set IPR_Point[2]
3) Make sure both points have terrain walkability
4) Run Is Point Reachable System
5) IPR_IsPointReachable is True if reachable
  • 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
JASS
Now contains a fully JASS library version.
JASS:
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
1.3:
Decreased cast range of Call To Arms to 0
Reworked false positive detection to a distance check
Improved range to find a path by checking from both points
Added requirment to check both points for terrain pathability to avoid false positives
Remade units Transmitter (1) and Reciever (2) with new ids
Changed ability ids of Call to Arms (Transmitter) and Call To Arms (Reciever)
Added a JASS library version
Updated demo triggers
Terrain changes to the map
Previews
Contents

Is Point Reachable 1.3 (Map)

Reviews
Antares
A creative and novel way of solving an old problem. I tried around a bit, but couldn't solve any of the limitations you mention. Also couldn't find a way to make the dummy face the movement direction instantly. You could get the direction with a...
Level 24
Joined
Feb 27, 2019
Messages
833
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.
Thanks for the heartwarming fart comment.
What is the 32-collision-size-limit based on? Is that hard-coded into the Call to Arms ability?

Would it also be possible to detect the direction the dummy is trying to move to get to the target point?
Ive tried to increase the less than 32 collision size limit but havnt been able to so Id say its hardcoded.

Not possible to detect the direction the dummy is trying to move as far as I know.
 
A creative and novel way of solving an old problem.

I tried around a bit, but couldn't solve any of the limitations you mention. Also couldn't find a way to make the dummy face the movement direction instantly. You could get the direction with a delay, but one wouldn't need your system to do that.

The system is easy-to-use and its limitations are clearly documented.

High Quality

Mind if I do a Lua translation?
 
Level 24
Joined
Feb 27, 2019
Messages
833
A creative and novel way of solving an old problem.

I tried around a bit, but couldn't solve any of the limitations you mention. Also couldn't find a way to make the dummy face the movement direction instantly. You could get the direction with a delay, but one wouldn't need your system to do that.

The system is easy-to-use and its limitations are clearly documented.

High Quality

Mind if I do a Lua translation?
Wow, didnt excpect that rating, though it has taken me a quite some time and effort to get the system working great.

Long story short: You are free to make a Lua translation but I have thought a lot about the system and am planning on uploading kind of a big change so you may wanna hold off until then, but its up to you.
 
Top