Skip to content

Commit

Permalink
Movement Looping System
Browse files Browse the repository at this point in the history
  • Loading branch information
Gottfrei committed Jun 14, 2024
1 parent 3d68d12 commit 7307423
Show file tree
Hide file tree
Showing 231 changed files with 5,174 additions and 2,576 deletions.
10 changes: 5 additions & 5 deletions _maps/map_files/generic/CentComm.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,7 @@
/turf/simulated/wall/indestructible/fakeglass,
/area/centcom/specops)
"aQh" = (
/obj/structure/chair/wheelchair/bike{
/obj/vehicle/motorcycle{
dir = 8
},
/obj/structure/sign/poster/contraband/random{
Expand Down Expand Up @@ -6811,7 +6811,7 @@
},
/area/centcom/zone3)
"dxs" = (
/obj/structure/chair/wheelchair/bike{
/obj/vehicle/motorcycle{
dir = 1
},
/turf/simulated/floor/plasteel{
Expand Down Expand Up @@ -44128,7 +44128,7 @@
/area/centcom/supply)
"vwk" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/chair/wheelchair/bike{
/obj/vehicle/motorcycle{
dir = 1
},
/turf/simulated/floor/plasteel{
Expand Down Expand Up @@ -44637,7 +44637,7 @@
/turf/simulated/floor/plasteel,
/area/shuttle/escape)
"vLc" = (
/obj/structure/chair/wheelchair/bike{
/obj/vehicle/motorcycle{
dir = 8
},
/obj/effect/decal/cleanable/dirt,
Expand Down Expand Up @@ -46609,7 +46609,7 @@
/turf/simulated/floor/mech_bay_recharge_floor,
/area/centcom/specops)
"wGg" = (
/obj/structure/chair/wheelchair/bike{
/obj/vehicle/motorcycle{
dir = 8
},
/turf/simulated/floor/wood{
Expand Down
9 changes: 9 additions & 0 deletions code/__DEFINES/MC.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@
}\
/datum/controller/subsystem/timer/##X/fire() {..() /*just so it shows up on the profiler*/} \
/datum/controller/subsystem/timer/##X

#define MOVEMENT_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/movement/##X);\
/datum/controller/subsystem/movement/##X/New(){\
NEW_SS_GLOBAL(SS##X);\
PreInit();\
}\
/datum/controller/subsystem/movement/##X/fire() {..() /*just so it shows up on the profiler*/} \
/datum/controller/subsystem/movement/##X

3 changes: 3 additions & 0 deletions code/__DEFINES/_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
//skips preceding invalid characters
#define hex2num(X) text2num(X, 16)

/// Until a condition is true, sleep
#define UNTIL(X) while(!(X)) stoplag()

1 change: 1 addition & 0 deletions code/__DEFINES/alerts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define ALERT_LEGCUFFED "legcuffed"
#define ALERT_EMBEDDED "embedded"
#define ALERT_NUTRITION "nutrition"
#define ALERT_DIRECTION_LOCK "direction_lock"

/** Silicon related */
#define ALERT_LOCKED "locked"
Expand Down
14 changes: 10 additions & 4 deletions code/__DEFINES/cooldowns.dm
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,26 @@

#define TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time))

#define TIMER_COOLDOWN_CHECK(cd_source, cd_index) LAZYACCESS(cd_source.cooldowns, cd_index)
/// Checks if a timer based cooldown is NOT finished.
#define TIMER_COOLDOWN_RUNNING(cd_source, cd_index) LAZYACCESS(cd_source.cooldowns, cd_index)

/// Checks if a timer based cooldown is finished.
#define TIMER_COOLDOWN_FINISHED(cd_source, cd_index) (!TIMER_COOLDOWN_RUNNING(cd_source, cd_index))

#define TIMER_COOLDOWN_END(cd_source, cd_index) LAZYREMOVE(cd_source.cooldowns, cd_index)

/*
* Stoppable timer cooldowns.
* Use indexes the same as the regular tiemr cooldowns.
* They make use of the TIMER_COOLDOWN_CHECK() and TIMER_COOLDOWN_END() macros the same, just not the TIMER_COOLDOWN_START() one.
* They make use of the TIMER_COOLDOWN_RUNNING() and TIMER_COOLDOWN_END() macros the same, just not the TIMER_COOLDOWN_START() one.
* A bit more expensive than the regular timers, but can be reset before they end and the time left can be checked.
*/

#define S_TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time, TIMER_STOPPABLE))

#define S_TIMER_COOLDOWN_RESET(cd_source, cd_index) reset_cooldown(cd_source, cd_index)

#define S_TIMER_COOLDOWN_TIMELEFT(cd_source, cd_index) (timeleft(TIMER_COOLDOWN_CHECK(cd_source, cd_index)))
#define S_TIMER_COOLDOWN_TIMELEFT(cd_source, cd_index) (timeleft(TIMER_COOLDOWN_RUNNING(cd_source, cd_index)))


/*
Expand All @@ -100,8 +104,10 @@
#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time))

//Returns true if the cooldown has run its course, false otherwise
#define COOLDOWN_FINISHED(cd_source, cd_index) (cd_source.cd_index < world.time)
#define COOLDOWN_FINISHED(cd_source, cd_index) (cd_source.cd_index <= world.time)

#define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0

#define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0)

#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time))
62 changes: 55 additions & 7 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@
#define COMSIG_ATOM_ATTACK "atom_attack"
///called when the atom sucessfully has it's density var changed, from base atom/set_density(): (value)
#define COMSIG_ATOM_SET_DENSITY "atom_set_density"
///from base of atom/experience_pressure_difference(): (pressure_difference, direction, pressure_resistance_prob_delta)
#define COMSIG_ATOM_PRE_PRESSURE_PUSH "atom_pre_pressure_push"
///prevents pressure movement
#define COMSIG_ATOM_BLOCKS_PRESSURE (1<<0)
///signal sent out by an atom when it checks if it can be pulled, for additional checks
#define COMSIG_ATOM_CAN_BE_PULLED "movable_can_be_pulled"
#define COMSIG_ATOM_CANT_PULL (1 << 0)
///signal sent out by an atom when it is no longer being pulled by something else : (atom/puller)
#define COMSIG_ATOM_NO_LONGER_PULLED "movable_no_longer_pulled"
///signal sent out by an atom when it is no longer pulling something : (atom/pulling)
#define COMSIG_ATOM_NO_LONGER_PULLING "movable_no_longer_pulling"

///from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMSIG_PARENT_ATTACKBY "atom_attackby"
Expand Down Expand Up @@ -103,8 +114,10 @@
#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays"
///from base of [/atom/update_icon]: (signalOut, did_anything)
#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon"
///from base of atom/Entered(): (atom/movable/entering, /atom)
///from base of atom/Entered(): (atom/movable/arrived, atom/oldloc)
#define COMSIG_ATOM_ENTERED "atom_entered"
/// Sent from the atom that just Entered src. From base of atom/Entered(): (/atom/destination, atom/oldloc)
#define COMSIG_ATOM_ENTERING "atom_entering"
///from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
#define COMSIG_ATOM_EXIT "atom_exit"
#define COMPONENT_ATOM_BLOCK_EXIT (1<<0)
Expand Down Expand Up @@ -137,8 +150,13 @@
///from obj/machinery/bsa/full/proc/fire(): ()
#define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass"
#define COMSIG_ATOM_BLOCKS_BSA_BEAM (1<<0)
///from base of atom/setDir(): (old_dir, new_dir)
/// From base of atom/setDir(): (old_dir, new_dir). Called before the direction changes
#define COMSIG_ATOM_PRE_DIR_CHANGE "atom_pre_face_atom"
#define COMPONENT_ATOM_BLOCK_DIR_CHANGE (1<<0)
///from base of atom/setDir(): (old_dir, new_dir). Called before the direction changes.
#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change"
///from base of atom/setDir(): (old_dir, new_dir). Called after the direction changes.
#define COMSIG_ATOM_POST_DIR_CHANGE "atom_dir_change"
///from base of atom/handle_atom_del(): (atom/deleted)
#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del"
///from base of atom/has_gravity(): (turf/location, list/forced_gravities)
Expand Down Expand Up @@ -220,10 +238,7 @@
#define ZIMPACT_NO_MESSAGE (1<<1)
/// Do not do the spin animation when landing
#define ZIMPACT_NO_SPIN (1<<2)
///from base of atom/movable/experience_pressure_difference(): (pressure_difference, direction, pressure_resistance_prob_delta)
#define COMSIG_ATOM_PRE_PRESSURE_PUSH "atom_pre_pressure_push"
///prevents pressure movement
#define COMSIG_ATOM_BLOCKS_PRESSURE (1<<0)

/////////////////

///from base of area/Entered(): (/area)
Expand Down Expand Up @@ -288,7 +303,7 @@
#define COMPONENT_MOVABLE_BLOCK_UNCROSS (1<<0)
///from base of atom/movable/Uncrossed(): (/atom/movable)
#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed"
///from base of atom/movable/Bump(): (/atom)
///from base of atom/movable/Bump(): (/atom/bumped_atom)
#define COMSIG_MOVABLE_BUMP "movable_bump"
///from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
#define COMSIG_MOVABLE_IMPACT "movable_impact"
Expand Down Expand Up @@ -327,6 +342,22 @@
#define COMSIG_MOVABLE_DISPOSING "movable_disposing"
///called when the movable is removed from a disposal holder object: /obj/structure/disposalpipe/proc/expel(): (obj/structure/disposalholder/H, turf/T, direction)
#define COMSIG_MOVABLE_EXIT_DISPOSALS "movable_exit_disposals"
///From base of /datum/move_loop/process() after attempting to move a movable: (datum/move_loop/loop, old_dir)
#define COMSIG_MOVABLE_MOVED_FROM_LOOP "movable_moved_from_loop"
///called when the movable's glide size is updated: (new_glide_size)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size"
/// from base of atom/movable/Process_Spacemove(): (movement_dir, continuous_move)
#define COMSIG_MOVABLE_SPACEMOVE "spacemove"
#define COMSIG_MOVABLE_STOP_SPACEMOVE (1<<0)
///from base of atom/movable/newtonian_move(): (inertia_direction, start_delay)
#define COMSIG_MOVABLE_NEWTONIAN_MOVE "movable_newtonian_move"
#define COMPONENT_MOVABLE_NEWTONIAN_BLOCK (1<<0)
///from datum/component/drift/apply_initial_visuals(): ()
#define COMSIG_MOVABLE_DRIFT_VISUAL_ATTEMPT "movable_drift_visual_attempt"
#define DRIFT_VISUAL_FAILED (1<<0)
///from datum/component/drift/allow_final_movement(): ()
#define COMSIG_MOVABLE_DRIFT_BLOCK_INPUT "movable_drift_block_input"
#define DRIFT_ALLOW_INPUT (1<<0)

// /datum/mind signals

Expand Down Expand Up @@ -551,6 +582,8 @@
#define MOVE_ARG_NEW_LOC 1
/// The arugment of move_args which dictates our movement direction
#define MOVE_ARG_DIRECTION 2
/// From base of /client/Move(): (direction, old_dir)
#define COMSIG_MOB_CLIENT_MOVED "mob_client_moved"

/// From base of /client/Move(): (list/move_args)
#define COMSIG_MOB_CLIENT_PRE_LIVING_MOVE "mob_client_pre_living_move"
Expand Down Expand Up @@ -1060,6 +1093,21 @@
/// Sent from /proc/do_after once a do_after action completes, whether via the bar filling or via interruption.
#define COMSIG_DO_AFTER_ENDED "mob_do_after_ended"


// HUD:
/// Sent from /datum/hud/proc/eye_z_changed() : (old_offset, new_offset)
#define COMSIG_HUD_OFFSET_CHANGED "hud_offset_changed"


///from [/datum/move_loop/start_loop] ():
#define COMSIG_MOVELOOP_START "moveloop_start"
///from [/datum/move_loop/stop_loop] ():
#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):
#define COMSIG_MOVELOOP_POSTPROCESS "moveloop_postprocess"
//from [/datum/move_loop/has_target/jps/recalculate_path] ():
#define COMSIG_MOVELOOP_JPS_REPATH "moveloop_jps_repath"

8 changes: 8 additions & 0 deletions code/__DEFINES/dcs/signals_object.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Jetpack things

//called in /obj/item/tank/jetpack/proc/turn_on() : ()
#define COMSIG_JETPACK_ACTIVATED "jetpack_activated"
#define JETPACK_ACTIVATION_FAILED (1<<0)
//called in /obj/item/tank/jetpack/proc/turn_off() : ()
#define COMSIG_JETPACK_DEACTIVATED "jetpack_deactivated"

2 changes: 2 additions & 0 deletions code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,5 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(


#define is_ventcrawler(A) (HAS_TRAIT(A, TRAIT_VENTCRAWLER_NUDE) || HAS_TRAIT(A, TRAIT_VENTCRAWLER_ALWAYS) || HAS_TRAIT(A, TRAIT_VENTCRAWLER_ITEM_BASED) || HAS_TRAIT(A, TRAIT_VENTCRAWLER_ALIEN))

#define is_multi_tile_object(atom) (atom.bound_width > world.icon_size || atom.bound_height > world.icon_size)
1 change: 0 additions & 1 deletion code/__DEFINES/math.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#define PI 3.1415
#define INFINITY 1e31 //closer than enough
#define SQRT_2 1.4142135623730950488016887242097

#define SHORT_REAL_LIMIT 16777216

Expand Down
19 changes: 18 additions & 1 deletion code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,24 @@

#define is_admin(user) (check_rights(R_ADMIN, 0, (user)) != 0)

#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return;
#define SLEEP_CHECK_DEATH(A, X) \
sleep(X); \
if(QDELETED(A)) return; \
if(ismob(A)) { \
var/mob/sleep_check_death_mob = A; \
if(sleep_check_death_mob.stat == DEAD) return; \
}

/// Until a condition is true, sleep. If target is qdeleted or dead, return.
#define UNTIL_DEATH_CHECK(target, expression) \
while(!(expression)) { \
stoplag(); \
if(QDELETED(target)) return; \
if(ismob(target)) { \
var/mob/sleep_check_death_mob = target; \
if(sleep_check_death_mob.stat == DEAD) return; \
}; \
};

// Locations
#define is_ventcrawling(A) (istype(A.loc, /obj/machinery/atmospherics))
Expand Down
90 changes: 90 additions & 0 deletions code/__DEFINES/movement.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,71 @@
/// The minimum for glide_size to be clamped to.
#define MIN_GLIDE_SIZE 1
/// The maximum for glide_size to be clamped to.
/// This shouldn't be higher than the icon size, and generally you shouldn't be changing this, but it's here just in case.
#define MAX_GLIDE_SIZE 32

/// Compensating for time dilation
GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)

///Broken down, here's what this does:
/// divides the world icon_size (32) by delay divided by ticklag to get the number of pixels something should be moving each tick.
/// The division result is given a min value of 1 to prevent obscenely slow glide sizes from being set
/// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave.
/// The whole result is then clamped to within the range above.
/// Not very readable but it works
#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))

///Similar to DELAY_TO_GLIDE_SIZE, except without the clamping, and it supports piping in an unrelated scalar
#define MOVEMENT_ADJUSTED_GLIDE_SIZE(delay, movement_disparity) (world.icon_size / ((delay) / world.tick_lag) * movement_disparity * GLOB.glide_size_multiplier)

/// Above this multiplicative slowdown / move_to_delay simplemobs will stop gliding, looks silly otherwise.
/// This number is arbitary and a subject to change.
#define END_GLIDE_SPEED 16

//Movement loop priority. Only one loop can run at a time, this dictates that
// Higher numbers beat lower numbers
///Standard, go lower then this if you want to override, higher otherwise
#define MOVEMENT_DEFAULT_PRIORITY 10
///Very few things should override this
#define MOVEMENT_SPACE_PRIORITY 100
///Higher then the heavens
#define MOVEMENT_ABOVE_SPACE_PRIORITY (MOVEMENT_SPACE_PRIORITY + 1)

//Movement loop flags
///Should the loop act immediately following its addition?
#define MOVEMENT_LOOP_START_FAST (1<<0)
///Do we not use the priority system?
#define MOVEMENT_LOOP_IGNORE_PRIORITY (1<<1)
///Should we override the loop's glide?
#define MOVEMENT_LOOP_IGNORE_GLIDE (1<<2)
///Should we not update our movables dir on move?
#define MOVEMENT_LOOP_NO_DIR_UPDATE (1<<3)
///Is the loop moving the movable outside its control, like it's an external force? e.g. footsteps won't play if enabled.
#define MOVEMENT_LOOP_OUTSIDE_CONTROL (1<<4)

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

/**
* Returns a bitfield containing flags both present in `flags` arg and the `processing_move_loop_flags` move_packet variable.
* Has no use outside of procs called within the movement proc chain.
*/
#define CHECK_MOVE_LOOP_FLAGS(movable, flags) (movable.move_packet ? (movable.move_packet.processing_move_loop_flags & (flags)) : NONE)

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

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


/**
* currently_z_moving defines. Higher numbers mean higher priority.
Expand Down Expand Up @@ -50,3 +118,25 @@
#define ZMOVE_STAIRS_FLAGS (ZMOVE_CHECK_PULLEDBY|ZMOVE_ALLOW_BUCKLED|ZMOVE_INCLUDE_PULLED)
/// Used for falling down open space.
#define ZMOVE_FALL_FLAGS (ZMOVE_FALL_CHECKS|ZMOVE_ALLOW_BUCKLED)


#define ACTIVE_MOVEMENT_OLDLOC 1
#define ACTIVE_MOVEMENT_DIRECTION 2
#define ACTIVE_MOVEMENT_FORCED 3

/// The arguments of this macro correspond directly to the argument order of /atom/movable/proc/Moved
#define SET_ACTIVE_MOVEMENT(_old_loc, _direction, _forced) \
active_movement = list( \
_old_loc, \
_direction, \
_forced, \
)

/// Finish any active movements
#define RESOLVE_ACTIVE_MOVEMENT \
if(active_movement) { \
var/__move_args = active_movement; \
active_movement = null; \
Moved(arglist(__move_args)); \
}

3 changes: 3 additions & 0 deletions code/__DEFINES/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Give us unsafe_unwrenching protection
#define TRAIT_GUSTPROTECTION "gustprotection"

/// Unlinks gliding from movement speed, meaning that there will be a delay between movements rather than a single move movement between tiles
#define TRAIT_NO_GLIDE "no_glide"

/// Apply this to make a mob not dense, and remove it when you want it to no longer make them undense, other sorces of undesity will still apply. Always define a unique source when adding a new instance of this!
#define TRAIT_UNDENSE "undense"

Expand Down
Loading

0 comments on commit 7307423

Please sign in to comment.