Skip to content

Commit

Permalink
tweak(astar): port tg version of AStar
Browse files Browse the repository at this point in the history
  • Loading branch information
Doster-d committed Mar 13, 2024
1 parent e3b97d6 commit 4299182
Show file tree
Hide file tree
Showing 31 changed files with 1,518 additions and 53 deletions.
6 changes: 6 additions & 0 deletions baystation12.dme
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include "code\__defines\modifiers.dm"
#include "code\__defines\movement.dm"
#include "code\__defines\organs.dm"
#include "code\__defines\path.dm"
#include "code\__defines\preferences.dm"
#include "code\__defines\proc_presets.dm"
#include "code\__defines\process_scheduler.dm"
Expand Down Expand Up @@ -148,6 +149,7 @@
#include "code\_helpers\game.dm"
#include "code\_helpers\global_access.dm"
#include "code\_helpers\global_lists.dm"
#include "code\_helpers\heap.dm"
#include "code\_helpers\icons.dm"
#include "code\_helpers\input.dm"
#include "code\_helpers\json.dm"
Expand Down Expand Up @@ -178,6 +180,9 @@
#include "code\_helpers\vector.dm"
#include "code\_helpers\warnings.dm"
#include "code\_helpers\weakref.dm"
#include "code\_helpers\paths\jps.dm"
#include "code\_helpers\paths\path.dm"
#include "code\_helpers\paths\sssp.dm"
#include "code\_helpers\sorts\__main.dm"
#include "code\_helpers\sorts\TimSort.dm"
#include "code\_onclick\adjacent.dm"
Expand Down Expand Up @@ -249,6 +254,7 @@
#include "code\controllers\subsystems\misc_late.dm"
#include "code\controllers\subsystems\open_space.dm"
#include "code\controllers\subsystems\overlays.dm"
#include "code\controllers\subsystems\pathfinder.dm"
#include "code\controllers\subsystems\plants.dm"
#include "code\controllers\subsystems\points_of_interest.dm"
#include "code\controllers\subsystems\radiation.dm"
Expand Down
26 changes: 21 additions & 5 deletions code/__defines/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,24 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define ITEM_FLAG_PREMODIFIED 0x0400 // Gloves that are clipped by default
#define ITEM_FLAG_IS_BELT 0x0800 // Items that can be worn on the belt slot, even with no undersuit equipped

// Flags for pass_flags.
#define PASS_FLAG_TABLE 0x1
#define PASS_FLAG_GLASS 0x2
#define PASS_FLAG_GRILLE 0x4
#define PASS_FLAG_MOB 0x8
/*
These defines are used specifically with the atom/pass_flags bitmask
the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example)
*/
//flags for pass_flags
#define PASS_FLAG_TABLE (1<<0)
#define PASS_FLAG_GLASS (1<<1)
#define PASS_FLAG_GRILLE (1<<2)
#define PASS_FLAG_BLOB (1<<3)
#define PASS_FLAG_MOB (1<<4)
#define PASS_FLAG_CLOSED_TURF (1<<5)
/// Let thrown things past us. **ONLY MEANINGFUL ON pass_flags_self!**
#define LETPASSTHROW (1<<6)
#define PASS_FLAG_MACHINE (1<<7)
#define PASS_FLAG_STRUCTURE (1<<8)
#define PASS_FLAG_FLAPS (1<<9)
#define PASS_FLAG_DOORS (1<<10)
#define PASS_FLAG_VEHICLE (1<<11)
#define PASS_FLAG_ITEM (1<<12)
/// Do not intercept click attempts during Adjacent() checks. See [turf/proc/ClickCross]. **ONLY MEANINGFUL ON pass_flags_self!**
#define LETPASSCLICKS (1<<13)
3 changes: 3 additions & 0 deletions code/__defines/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,6 @@

// Shortcut for image_repository.overlay_image(...)
#define OVERLAY(args...) image_repository.overlay_image(args)

/// Until a condition is true, sleep
#define UNTIL(X) while(!(X)) stoplag()
25 changes: 25 additions & 0 deletions code/__defines/path.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Define set that decides how an atom will be scanned for astar things
/// If set, we make the assumption that CanAStarPass() will NEVER return FALSE unless density is true
#define CANASTARPASS_DENSITY 0
/// If this is set, we bypass density checks and always call the proc
#define CANASTARPASS_ALWAYS_PROC 1

/**
* A helper macro to see if it's possible to step from the first turf into the second one, minding things like door access and directional windows.
* If you really want to optimize things, optimize this, cuz this gets called a lot.
* We do early next.density check despite it being already checked in LinkBlockedWithAccess for short-circuit performance
*/
#define CAN_STEP(cur_turf, next, simulated_only, pass_info, avoid) (next && !next.density && !(simulated_only && SSpathfinder.space_type_cache[next.type]) && !cur_turf.LinkBlockedWithAccess(next, pass_info) && (next != avoid))

#define DIAGONAL_DO_NOTHING NONE
#define DIAGONAL_REMOVE_ALL 1
#define DIAGONAL_REMOVE_CLUNKY 2

// Set of delays for path_map reuse
// The longer you go, the higher the risk of invalid paths
#define MAP_REUSE_INSTANT (0)
#define MAP_REUSE_SNAPPY (0.5 SECONDS)
#define MAP_REUSE_FAST (2 SECONDS)
#define MAP_REUSE_SLOW (20 SECONDS)
// Longest delay, so any maps older then this will be discarded from the subsystem cache
#define MAP_REUSE_SLOWEST (60 SECONDS)
1 change: 1 addition & 0 deletions code/__defines/subsystem-priority.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define SS_PRIORITY_SHUTTLE 20 // Shuttle movement.
#define SS_PRIORITY_CIRCUIT_COMP 20 // Processing circuit component do_work.
#define SS_PRIORITY_EXPLOSION 666 // Processing explosion stuff, abnormal number for abnormal stuff
#define SS_PRIORITY_PATHFINDING 23
#define SS_PRIORITY_VIRUSES 20 // Processing viruses life.
#define SS_PRIORITY_OPEN_SPACE 20 // Open turf updates.
#define SS_PRIORITY_AIRFLOW 15 // Object movement from ZAS airflow.
Expand Down
1 change: 1 addition & 0 deletions code/__defines/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#define SS_INIT_BAY_LEGACY -12
#define SS_INIT_STORYTELLER -15
#define SS_INIT_TICKER -20
#define SS_INIT_ORDER_PATH -50
#define SS_INIT_EXPLOSIONS -69
#define SS_INIT_ANNOUNCERS -90
#define SS_INIT_VOTE -95
Expand Down
16 changes: 16 additions & 0 deletions code/__defines/turfs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,19 @@
#define TURF_HAS_CORNERS 128
#define TURF_IS_FRAGILE 256
#define TURF_ACID_IMMUNE 512

#define ALL (~0) //For convenience.
#define NONE 0

/// Turf will be passable if density is 0
#define TURF_PATHING_PASS_DENSITY 0
/// Turf will be passable depending on [CanAStarPass] return value
#define TURF_PATHING_PASS_PROC 1
/// Turf is never passable
#define TURF_PATHING_PASS_NO 2

/// Returns a list of turfs similar to CORNER_BLOCK but with offsets
#define CORNER_BLOCK_OFFSET(corner, width, height, offset_x, offset_y) ((block(locate(corner.x + offset_x, corner.y + offset_y, corner.z), locate(min(corner.x + (width - 1) + offset_x, world.maxx), min(corner.y + (height - 1) + offset_y, world.maxy), corner.z))))

/// Returns a list of around us
#define TURF_NEIGHBORS(turf) (CORNER_BLOCK_OFFSET(turf, 3, 3, -1, -1) - turf)
13 changes: 9 additions & 4 deletions code/_helpers/game.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a
///Returns a list of turf in a square
#define RANGE_TURFS(RADIUS, CENTER) \
block( \
locate(max(CENTER.x - (RADIUS), 1), max(CENTER.y - (RADIUS), 1), CENTER.z), \
locate(min(CENTER.x + (RADIUS), world.maxx), min(CENTER.y + (RADIUS), world.maxy), CENTER.z) \
)
RECT_TURFS(RADIUS, RADIUS, CENTER)

#define RECT_TURFS(H_RADIUS, V_RADIUS, CENTER) \
block( \
locate(max((CENTER).x-(H_RADIUS),1), max((CENTER).y-(V_RADIUS),1), (CENTER).z), \
locate(min((CENTER).x+(H_RADIUS),world.maxx), min((CENTER).y+(V_RADIUS),world.maxy), (CENTER).z) \
)

/proc/dopage(src, target)
var/href_list
Expand Down
80 changes: 80 additions & 0 deletions code/_helpers/heap.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//////////////////////
//datum/heap object
//////////////////////

/datum/heap
var/list/L
var/cmp

/datum/heap/New(compare)
L = new()
cmp = compare

/datum/heap/Destroy(force)
for(var/i in L) // because this is before the list helpers are loaded
qdel(i)
L = null
return ..()

/datum/heap/proc/is_empty()
return !length(L)

//insert and place at its position a new node in the heap
/datum/heap/proc/insert(A)

L.Add(A)
swim(length(L))

//removes and returns the first element of the heap
//(i.e the max or the min dependant on the comparison function)
/datum/heap/proc/pop()
if(!length(L))
return 0
. = L[1]

L[1] = L[length(L)]
L.Cut(length(L))
if(length(L))
sink(1)

//Get a node up to its right position in the heap
/datum/heap/proc/swim(index)
var/parent = round(index * 0.5)

while(parent > 0 && (call(cmp)(L[index],L[parent]) > 0))
L.Swap(index,parent)
index = parent
parent = round(index * 0.5)

//Get a node down to its right position in the heap
/datum/heap/proc/sink(index)
var/g_child = get_greater_child(index)

while(g_child > 0 && (call(cmp)(L[index],L[g_child]) < 0))
L.Swap(index,g_child)
index = g_child
g_child = get_greater_child(index)

//Returns the greater (relative to the comparison proc) of a node children
//or 0 if there's no child
/datum/heap/proc/get_greater_child(index)
if(index * 2 > length(L))
return 0

if(index * 2 + 1 > length(L))
return index * 2

if(call(cmp)(L[index * 2],L[index * 2 + 1]) < 0)
return index * 2 + 1
else
return index * 2

//Replaces a given node so it verify the heap condition
/datum/heap/proc/resort(A)
var/index = L.Find(A)

swim(index)
sink(index)

/datum/heap/proc/List()
. = L.Copy()
35 changes: 35 additions & 0 deletions code/_helpers/lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,34 @@
/// Passed into BINARY_INSERT to compare values
#define COMPARE_VALUE __BIN_LIST[__BIN_LIST[__BIN_MID]]

// Generic listoflist safe add and removal macros:
///If value is a list, wrap it in a list so it can be used with list add/remove operations
#define LIST_VALUE_WRAP_LISTS(value) (islist(value) ? list(value) : value)
///Add an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun
#define UNTYPED_LIST_ADD(list, item) (list += LIST_VALUE_WRAP_LISTS(item))
///Remove an untyped item to a list, taking care to handle list items by wrapping them in a list to remove the footgun
#define UNTYPED_LIST_REMOVE(list, item) (list -= LIST_VALUE_WRAP_LISTS(item))

///Copies a list, and all lists inside it recusively
///Does not copy any other reference type
/proc/deep_copy_list(list/inserted_list)
if(!islist(inserted_list))
return inserted_list
. = inserted_list.Copy()
for(var/i in 1 to inserted_list.len)
var/key = .[i]
if(isnum(key))
// numbers cannot ever be associative keys
continue
var/value = .[key]
if(islist(value))
value = deep_copy_list(value)
.[key] = value
if(islist(key))
key = deep_copy_list(key)
.[i] = key
.[key] = value

//Returns a list in plain english as a string
/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "")
switch(input.len)
Expand Down Expand Up @@ -188,6 +216,13 @@
result = first ^ second
return result

/// Turns an associative list into a flat list of keys
/proc/assoc_to_keys(list/input)
var/list/keys = list()
for(var/key in input)
UNTYPED_LIST_ADD(keys, key)
return keys

/proc/assoc_merge_add(value_a, value_b)
return value_a + value_b

Expand Down
Loading

0 comments on commit 4299182

Please sign in to comment.