Paste #2670: PathfindChooseTarget

Date: 2014/03/20 08:55:53 UTC-07:00
Type: Denizen Script

View Raw Paste Download This Paste
Copy Link


'PathfindChooseTarget':
# -----------------------------------------------------------------------------#
#
# OVERVIEW
#
# Chooses a target to walk to. Will always be in the general direction of the
# Destination. Will incrementally expand the search radius if unable to find a
# pathMaterial (UpTo 5 retries. Maybe that should be configurable?)
#
# ____________________________________
#
# DETAILED METHOD
#
# Examines the player XZ coordinates and the Destination XZ coordinates
# individually.
#
# If the distance between the X points is less then or equal to the
# pathSearchRadius it will use the destinationX point and add a little lateral
# wiggle.
#
# If the destinationDistanceX is more then the pathSearchRadius it will compare
# the npcX and destinationX values and return an X value that is closer to
# destinationX by a value of between minPathFindRadius and maxPathFindRadius.
#
# It then does the same for the Z coordinate.
#
# Now you have an XZ coordinate that is between minPathFindRadius and
# maxPathFindRadius closer to your destination. A target is built using this
# data along with the destinationY value and the current world. From this target
# we search for surface blocks within pathSearchRadius that matches pathMaterial
# and return a random coordinate from this list defined as pathTarget.
#
# If all went well then the script that injected this will have a coordinate to
# walk to. If not, we go through some retries and expand our search radii.
#
# ____________________________________
#
# Sets <npc.flag[Pathfind.Status]> when lost.
# Clears <npc.flag[Pathfind.DestinationName]> when lost.
# Use on npc flag change event as needed.
#
# -----------------------------------------------------------------------------#

  type: task
  debug: false
  script:
    - define wiggle <def[pathSearchRadius].mul[1.25]>
    - if <def[destinationDistanceX].is[OR_LESS].than[%pathSearchRadius%]> {
      - define targetX <def[destinationX].add[<util.random.int[-<def[wiggle]>].to[<def[wiggle]>]>]>
      }
      else {
      - define targetX '<tern[<def[npcX].is[MORE].than[%destinationX%]>]:<def[npcX].sub[<util.random.int[%minPathFindRadius%].to[%maxPathFindRadius%]>]> || <def[npcX].add[<util.random.int[%minPathFindRadius%].to[%maxPathFindRadius%]>]>>'
      }
    - if <def[destinationDistanceZ].is[OR_LESS].than[%pathSearchRadius%]> {
      - define targetZ <def[destinationZ].add[<util.random.int[-<def[wiggle]>].to[<def[wiggle]>]>]>
      }
      else {
      - define targetZ '<tern[<def[npcZ].is[MORE].than[%destinationZ%]>]:<def[npcZ].sub[<util.random.int[%minPathFindRadius%].to[%maxPathFindRadius%]>]> || <def[npcZ].add[<util.random.int[%minPathFindRadius%].to[%maxPathFindRadius%]>]>>'
      }
    - define target '<def[targetX]>,<def[destination].y>,<def[targetZ]>,<def[world]>'
    - define pathTarget '<def[target].as_location.find.surface_blocks[<def[pathMaterial]>].within[<def[pathSearchRadius]>].random>'

    - if <def[pathTarget].is[==].to[null]> {
      - define counter '<def[counter] || 0>' 
      - if <def[counter].is[LESS].than[5]> {
        - if <def[minPathFindRadius].is[OR_LESS].than[<npc.flag[Pathfind.maxPathFindRadius].mul[2]>]> {
          - define minPathFindRadius '<def[minPathFindRadius].add[10]>'
          - chat "I<&sq>m just a bit lost... I<&sq>ll expand my search. <def[minPathFindRadius]> should be enough."
          - define counter <math:%counter%+1>
          - inject s@PathfindChooseTarget
          }
          else if <def[pathSearchRadius].is[OR_LESS].than[<npc.flag[Pathfind.pathSearchRadius].mul[2]>]> {
          - define pathSearchRadius '<def[pathSearchRadius].add[10]>'
          - chat "I<&sq>m really stuck. I<&sq>ll search a wider area for sidewalks. <def[pathSearchRadius]> block radius should be enough." no_target
          - define counter <math:%counter%+1>
          - inject s@PathfindChooseTarget
          }
        }
        else {
        - flag npc Pathfind.DestinationName:!
        - flag npc Pathfind.Status:Lost
        - announce "<npc.name><&co> I seem to be lost."
        - queue clear
        }
      }