Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5b2f557
clean up crap
CheffieGithub Mar 2, 2026
3fc9eed
stop
CheffieGithub Mar 2, 2026
32153c6
move
CheffieGithub Mar 2, 2026
d8d0dbc
stuff
CheffieGithub Mar 2, 2026
d99d95f
controller
CheffieGithub Mar 2, 2026
b135ba7
outta the damn way
CheffieGithub Mar 3, 2026
0542f6f
astar works for no multiz
CheffieGithub Mar 3, 2026
794a692
bleg
CheffieGithub Mar 3, 2026
ef94273
fix
CheffieGithub Mar 3, 2026
2a92f43
holy stick
CheffieGithub Mar 3, 2026
ea16f09
Merge branch 'main' of https://github.com/Monkestation/Vanderlin into…
CheffieGithub Mar 3, 2026
2300f25
happy fun time
CheffieGithub Mar 3, 2026
62a4fa1
TODO STAIRS
CheffieGithub Mar 4, 2026
de86994
blelelele
CheffieGithub Mar 4, 2026
a4cde48
Merge branch 'main' of https://github.com/Monkestation/Vanderlin into…
CheffieGithub Apr 14, 2026
337db95
Merge branch 'main' of https://github.com/Monkestation/Vanderlin into…
CheffieGithub Aug 23, 2026
0ce1411
awesome sort
CheffieGithub Aug 23, 2026
284b4a2
datum
CheffieGithub Aug 23, 2026
287f820
a
CheffieGithub Aug 24, 2026
15e1c13
stairs
CheffieGithub Aug 24, 2026
e161d11
make multiz default
CheffieGithub Aug 24, 2026
415a787
a
CheffieGithub Aug 24, 2026
a3e4c8b
this works
CheffieGithub Aug 24, 2026
9d08ace
waves use closest approach, everything that was hybrid uses new hybrid
CheffieGithub Aug 24, 2026
2eda6ce
adaptive responds to Z changes
CheffieGithub Aug 24, 2026
a36e85b
wtf
CheffieGithub Aug 24, 2026
d126ae5
it can't be tick lag
CheffieGithub Aug 24, 2026
9212802
undef
CheffieGithub Aug 24, 2026
bb330ca
f
CheffieGithub Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,584 changes: 1,658 additions & 1,926 deletions _maps/map_files/debug/roguetest.dmm

Large diffs are not rendered by default.

17 changes: 13 additions & 4 deletions code/__DEFINES/ai/_ai.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#define GET_AI_BEHAVIOR(behavior_type) SSai_behaviors.ai_behaviors[behavior_type]
#define HAS_AI_CONTROLLER_TYPE(thing, type) istype(thing?.ai_controller, type)
#define AI_STATUS_ON "ai_on"
#define AI_STATUS_OFF "ai_off"
#define AI_STATUS_IDLE "ai_idle"

//AI controller flags
//If you add a new status, be sure to add it to the ai_controllers subsystem's ai_controllers_by_status list.
///The AI is currently active.
#define AI_STATUS_ON "ai_on"
///The AI is currently offline for any reason.
#define AI_STATUS_OFF "ai_off"
///The AI is currently in idle mode.
#define AI_STATUS_IDLE "ai_idle"

//Flags returned by get_able_to_run()
///pauses AI processing
Expand All @@ -15,10 +21,11 @@
#define SHOULD_STAND(source) (source.resting)
#define IS_DEAD_OR_INCAP(source) (source.incapacitated(IGNORE_GRAB) || source.stat)


// How far should we, by default, be looking for interesting things to de-idle?
#define AI_DEFAULT_INTERESTING_DIST 10

/// Generic max path length
#define AI_MAX_PATH_LENGTH 30
///Max pathing attempts before auto-fail
#define MAX_PATHING_ATTEMPTS 30
///Flags for ai_behavior new()
Expand Down Expand Up @@ -355,6 +362,8 @@
#define ALCHEMY_STATE_RETURN_BOTTLE "return_bottle"
#define ALCHEMY_STATE_RETURN_WATER_CONTAINER "return_container"
#define ALCHEMY_STATE_RETURN_ESSENCE_VIAL "return_vial"
///Path we should use next time we use the movement datum
#define BB_PATH_TO_USE "BB_path_to_use"

// Keys used by one and only one behavior
// Used to hold state without making bigass lists
Expand Down
12 changes: 7 additions & 5 deletions code/__DEFINES/dcs/signals/signals_moveloop.dm
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
///from [/datum/move_loop/start_loop] ():
///from [/datum/move_loop/loop_started] ():
#define COMSIG_MOVELOOP_START "moveloop_start"
///from [/datum/move_loop/stop_loop] ():
///from [/datum/move_loop/loop_stopped] ():
#define COMSIG_MOVELOOP_STOP "moveloop_stop"
///from [/datum/move_loop/process] ():
#define COMSIG_MOVELOOP_PREPROCESS_CHECK "moveloop_preprocess_check"
#define MOVELOOP_SKIP_STEP (1<<0)
///from [/datum/move_loop/process] (succeeded, visual_delay):
///from [/datum/move_loop/process] (result, visual_delay): //Result is an enum value. Enums defined in __DEFINES/movement.dm
#define COMSIG_MOVELOOP_POSTPROCESS "moveloop_postprocess"
//from [/datum/move_loop/has_target/jps/recalculate_path] ():
#define COMSIG_MOVELOOP_JPS_REPATH "moveloop_jps_repath"
//from [/datum/move_loop/has_target/recalculate_path] ():
#define COMSIG_MOVELOOP_REPATH "moveloop_repath"
///from [/datum/move_loop/has_target/on_finish_pathing]
#define COMSIG_MOVELOOP_FINISHED_PATHING "moveloop_finished_pathing"
22 changes: 17 additions & 5 deletions code/__DEFINES/movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
///Added to the move packet `processing_move_loop_flags` so we know when a loop is behind movement even in absence of other flags
#define MOVED_BY_MOVEMENT_LOOP (1<<6)

//Index defines for movement bucket data packets
#define MOVEMENT_BUCKET_TIME 1
#define MOVEMENT_BUCKET_LIST 2

// Movement loop status flags
/// Has the loop been paused, soon to be resumed?
#define MOVELOOP_STATUS_PAUSED (1<<0)
/// Is the loop running? (Is true even when paused)
#define MOVELOOP_STATUS_RUNNING (1<<1)
/// Is the loop queued in a subsystem?
#define MOVELOOP_STATUS_QUEUED (1<<2)

///Return values for moveloop Move()
#define MOVELOOP_FAILURE 0
#define MOVELOOP_SUCCESS 1
#define MOVELOOP_NOT_READY 2

#define DEFAULT_MOB_SNEAK_TIME 5 SECONDS

/**
Expand Down Expand Up @@ -113,8 +130,3 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
#define ZMOVE_FALL_FLAGS (ZMOVE_FALL_CHECKS|ZMOVE_ALLOW_BUCKLED)
/// Used when swimming
#define ZMOVE_SWIM_FLAGS (ZMOVE_WATER_CHECKS|ZMOVE_INCAPACITATED_CHECKS|ZMOVE_CHECK_PULLS|ZMOVE_ALLOW_BUCKLED)

///Return values for moveloop Move()
#define MOVELOOP_FAILURE 0
#define MOVELOOP_SUCCESS 1
#define MOVELOOP_NOT_READY 2
24 changes: 24 additions & 0 deletions code/__DEFINES/path.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

// 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

/// Don't remove diagonals
#define DIAGONAL_DO_NOTHING NONE
/// Removal all diagaonals
#define DIAGONAL_REMOVE_ALL 1
/// Remove diagonals on edges
#define DIAGONAL_REMOVE_CLUNKY 2

/**
* 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.
* Note that this can only be used inside the [datum/pathfind][pathfind datum] since it uses variables from said datum.
* If you really want to optimize things, optimize this, cuz this gets called a lot.
*/
#define CAN_STEP(cur_turf, next, pass_info, avoid) \
(next && !next.density && (next != avoid) && !cur_turf.LinkBlockedWithAccess(next, pass_info))
/// Check if we are close enough to be considered done
/// Only relevant for a point on the same Z level
#define ASTAR_CLOSE_ENOUGH_TO_END(end, checking_turf) (end == checking_turf || (mintargetdist && (get_dist(checking_turf, end) <= mintargetdist)))
1 change: 1 addition & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
#define FIRE_PRIORITY_NPC 20
#define FIRE_PRIORITY_NPC_MOVEMENT 21
#define FIRE_PRIORITY_NPC_ACTIONS 22
#define FIRE_PRIORITY_PATHFINDING 23
#define FIRE_PRIORITY_PROCESS 25
#define FIRE_PRIORITY_THROWING 25
#define FIRE_PRIORITY_SPACEDRIFT 30
Expand Down
10 changes: 6 additions & 4 deletions code/__DEFINES/traits/definitions.dm
Original file line number Diff line number Diff line change
Expand Up @@ -619,12 +619,14 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// This item can't be pickpocketed
#define TRAIT_HARD_TO_STEAL "hard_to_steal"

// **** turf traits
///Turf slowdown will be ignored when this trait is added to a turf.
#define TRAIT_TURF_IGNORE_SLOWDOWN "turf_ignore_slowdown"
// ************* turf traits
/// Turf trait for when a turf is transparent
#define TRAIT_Z_TRANSPARENT "turf_z_transparent"
/// Turf is one that ai mobs will generally avoid pathing through
/// Doesn't need to be applied to any turfs that override can_cross_safely
#define TRAIT_AI_AVOID_TURF "warning_turf"
#define TRAIT_AI_AVOID_TURF "ai_avoid_turf"
///Turf slowdown will be ignored when this trait is added to a turf.
#define TRAIT_TURF_IGNORE_SLOWDOWN "turf_ignore_slowdown"

// ************* Debug traits
/// This object has sound debugging tools attached to it
Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/turfs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@
/// Turf is currently queued in GLOB.SUNLIGHT_QUEUE_CORNER and should not be re-queued to avoid duplicates
#define TURF_SUNLIGHT_QUEUED (1<<5)

/// 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

//water_height defines
#define WATER_HEIGHT_ANKLE 1
#define WATER_HEIGHT_SHALLOW 2
Expand Down
71 changes: 16 additions & 55 deletions code/__HELPERS/AStar.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,33 +41,9 @@ Actual Adjacent procs :
node[TOTAL_COST_F] = new_g + new_h * (1 + PF_TIEBREAKER); \
node[NODE_TURN] = new_nt

#define ASTAR_CLOSE_ENOUGH_TO_END(end, checking_turf, mintargetdist) \
(checking_turf == end || (mintargetdist && (get_dist_3d(checking_turf, end) <= mintargetdist)))

#define SORT_TOTAL_COST_F(list) (list[TOTAL_COST_F])

#define PF_TIEBREAKER 0.005
#define MASK_ODD 85
#define MASK_EVEN 170

/proc/PathWeightCompare(list/a, list/b)
return a[TOTAL_COST_F] - b[TOTAL_COST_F]

/proc/HeapPathWeightCompare(list/a, list/b)
return b[TOTAL_COST_F] - a[TOTAL_COST_F]

/proc/get_path_to(atom/movable/requester, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id = null, turf/exclude = null, simulated_only = TRUE, check_z_levels = TRUE)
var/l = SSpathfinder.mobs.getfree(requester)
while (!l)
stoplag(3)
if(QDELETED(requester)) // check if we've stopped existing, since we slept
return list() // no path, we got deleted
l = SSpathfinder.mobs.getfree(requester)
var/list/path = AStar(requester, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent, id, exclude, simulated_only, check_z_levels)
SSpathfinder.mobs.found(l)
if (!path)
path = list()
return path

/proc/AStar(atom/movable/requester, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id = null, turf/exclude = null, simulated_only = TRUE, check_z_levels = TRUE)
var/turf/end = get_turf(_end)
Expand Down Expand Up @@ -184,18 +160,18 @@ Actual Adjacent procs :
* Useful for wave defense etc, where a point might be behind unbroken obstacles -
* mobs should still path as close as possible instead of giving up entirely.
*/
/proc/get_path_to_closest_approach(atom/movable/requester, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id = null, turf/exclude = null, simulated_only = TRUE, check_z_levels = TRUE)
var/l = SSpathfinder.mobs.getfree(requester)
while (!l)
stoplag(3)
if(QDELETED(requester))
return list()
l = SSpathfinder.mobs.getfree(requester)
var/list/path = AStarClosestApproach(requester, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent, id, exclude, simulated_only, check_z_levels)
SSpathfinder.mobs.found(l)
if (!path)
path = list()
return path
// /proc/get_path_to_closest_approach(atom/movable/requester, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id = null, turf/exclude = null, simulated_only = TRUE, check_z_levels = TRUE)
// var/l = SSpathfinder.mobs.getfree(requester)
// while (!l)
// stoplag(3)
// if(QDELETED(requester))
// return list()
// l = SSpathfinder.mobs.getfree(requester)
// var/list/path = AStarClosestApproach(requester, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent, id, exclude, simulated_only, check_z_levels)
// SSpathfinder.mobs.found(l)
// if (!path)
// path = list()
// return path

/proc/AStarClosestApproach(atom/movable/requester, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id = null, turf/exclude = null, simulated_only = TRUE, check_z_levels = TRUE)
var/turf/end = get_turf(_end)
Expand Down Expand Up @@ -351,10 +327,12 @@ Actual Adjacent procs :

// Add a helper function to compute 3D Manhattan distance
/turf/proc/Distance3D(turf/T)
if(!T)
if(!istype(T))
return 0

if(z == T.z)
return abs(x - T.x) + abs(y - T.y)

if(is_in_zweb(z, T.z))
return abs(x - T.x) + abs(y - T.y) + abs(z - T.z) * 5

Expand Down Expand Up @@ -404,23 +382,6 @@ Actual Adjacent procs :

return abs(cx - T.x) + abs(cy - T.y) + abs(cz - T.z) * 5 + hops * 5

/turf/proc/LinkBlockedWithAccess(turf/T, requester, ID)
var/adir = get_dir(src, T)
var/rdir = ((adir & MASK_ODD)<<1)|((adir & MASK_EVEN)>>1)
for(var/obj/O in T)
if(!O.CanAStarPass(ID, rdir, requester))
return TRUE
for(var/obj/O in src)
if(!O.CanAStarPass(ID, adir, requester))
return TRUE
for(var/mob/living/M in T)
if(!M.CanPass(requester, src))
return TRUE
for(var/obj/structure/M in T)
if(!M.CanPass(requester, src))
return TRUE
return FALSE

#undef ATURF
#undef TOTAL_COST_F
#undef DIST_FROM_START_G
Expand All @@ -430,4 +391,4 @@ Actual Adjacent procs :
#undef BLOCKED_FROM
#undef ASTAR_NODE
#undef ASTAR_UPDATE_NODE
#undef ASTAR_CLOSE_ENOUGH_TO_END
//#undef ASTAR_CLOSE_ENOUGH_TO_END
36 changes: 32 additions & 4 deletions code/__HELPERS/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,33 @@ if (length(L) < I) { \
};\
} while(FALSE)

/// The above but the tree is sorted in reverse.
#define BINARY_INSERT_REVERSE(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \
do {\
var/list/__BIN_LIST = LIST;\
var/__BIN_CTTL = length(__BIN_LIST);\
if(!__BIN_CTTL) {\
__BIN_LIST += INPUT;\
} else {\
var/__BIN_LEFT = 1;\
var/__BIN_RIGHT = __BIN_CTTL;\
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
var ##TYPECONT/__BIN_ITEM;\
while(__BIN_LEFT < __BIN_RIGHT) {\
__BIN_ITEM = COMPTYPE;\
if(__BIN_ITEM.##COMPARISON >= COMPARE.##COMPARISON) {\
__BIN_LEFT = __BIN_MID + 1;\
} else {\
__BIN_RIGHT = __BIN_MID;\
};\
__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
};\
__BIN_ITEM = COMPTYPE;\
__BIN_MID = __BIN_ITEM.##COMPARISON < COMPARE.##COMPARISON ? __BIN_MID : __BIN_MID + 1;\
__BIN_LIST.Insert(__BIN_MID, INPUT);\
};\
} while(FALSE)

//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 = "" )
var/total = length(input)
Expand Down Expand Up @@ -790,11 +817,12 @@ if (length(L) < I) { \
else
L1[key] = other_value

/proc/assoc_list_strip_value(list/input)
var/list/ret = list()
/// 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)
ret += key
return ret
keys += key
return keys

/proc/compare_list(list/l,list/d)
if(!islist(l) || !islist(d))
Expand Down
Loading
Loading