Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Movement update v2 #20548

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions aurorastation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
#include "code\__DEFINES\modular_guns.dm"
#include "code\__DEFINES\move_force.dm"
#include "code\__DEFINES\movement.dm"
#include "code\__DEFINES\movement_info.dm"
#include "code\__DEFINES\movespeed_modification.dm"
#include "code\__DEFINES\multiz.dm"
#include "code\__DEFINES\obj.dm"
Expand Down
7 changes: 6 additions & 1 deletion code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ GLOBAL_LIST_INIT(mimic_defines, list("ZM_MIMIC_BELOW",
"ZM_NO_OCCLUDE",
"ZM_MIMIC_BASETURF"))

//EMP protection
///EMP will protect itself.
#define EMP_PROTECT_SELF (1<<0)
///EMP will protect the contents from also being EMPed.
#define EMP_PROTECT_CONTENTS (1<<1)
///EMP will protect the wires.
#define EMP_PROTECT_WIRES (1<<2)

///Protects against all EMP types.
#define EMP_PROTECT_ALL (EMP_PROTECT_SELF | EMP_PROTECT_CONTENTS | EMP_PROTECT_WIRES)

// Flags bitmask

/// If a dense atom (potentially) only blocks movements from a given direction, i.e. window panes
Expand Down
6 changes: 6 additions & 0 deletions code/__DEFINES/movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
#define MOVEMENT_BUCKET_TIME 1
#define MOVEMENT_BUCKET_LIST 2

//Diagonal movement is split into two cardinal moves
/// The first step of the diagnonal movement
#define FIRST_DIAG_STEP 1
/// The second step of the diagnonal movement
#define SECOND_DIAG_STEP 2

///Return values for moveloop Move()
#define MOVELOOP_FAILURE 0
#define MOVELOOP_SUCCESS 1
Expand Down
21 changes: 21 additions & 0 deletions code/__DEFINES/movement_info.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#define ACTIVE_MOVEMENT_OLDLOC 1
#define ACTIVE_MOVEMENT_DIRECTION 2
#define ACTIVE_MOVEMENT_FORCED 3
#define ACTIVE_MOVEMENT_OLDLOCS 4

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

/// Finish any active movements
#define RESOLVE_ACTIVE_MOVEMENT \
if(active_movement) { \
var/__move_args = active_movement; \
active_movement = null; \
Moved(arglist(__move_args)); \
}
2 changes: 1 addition & 1 deletion code/_onclick/hud/skybox.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
if(skybox)
skybox.screen_loc = "CENTER:[-224 - T.x],CENTER:[-224 - T.y]"

/mob/Move()
/mob/Move(atom/newloc, direct, glide_size_override, update_dir)
var/old_z = GET_Z(src)
. = ..()
if(. && client)
Expand Down
2 changes: 1 addition & 1 deletion code/datums/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This sets up a listening relationship such that when the target object emits a signal
* the source datum this proc is called upon, will receive a callback to the given proctype
* Use PROC_REF(procname), TYPE_PROC_REF(type,procname) or GLOBAL_PROC_REF(procname) macros to validate the passed in proc at compile time.
* PROC_REF for procs defined on current type or it's ancestors, TYPE_PROC_REF for procs defined on unrelated type and GLOBAL_PROC_REF for global procs.
* PROC_REF for procs defined on current type or its ancestors, TYPE_PROC_REF for procs defined on unrelated type and GLOBAL_PROC_REF for global procs.
* Return values from procs registered must be a bitfield
*
* Arguments:
Expand Down
3 changes: 1 addition & 2 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,10 @@
*/
/atom/proc/emp_act(var/severity)
SHOULD_CALL_PARENT(TRUE)
SHOULD_NOT_SLEEP(TRUE)

var/protection = SEND_SIGNAL(src, COMSIG_ATOM_PRE_EMP_ACT, severity)

RETURN_TYPE(protection)

SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity, protection)
return protection // Pass the protection value collected here upwards

Expand Down
183 changes: 174 additions & 9 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
appearance_flags = DEFAULT_APPEARANCE_FLAGS | TILE_BOUND

var/last_move = null
var/anchored = 0
/// A list containing arguments for Moved().
VAR_PRIVATE/tmp/list/active_movement
var/anchored = FALSE
var/movable_flags

///Used to scale icons up or down horizonally in update_transform().
Expand Down Expand Up @@ -42,6 +44,9 @@
///Delay in deciseconds between inertia based movement
var/inertia_move_delay = 5

///0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
var/moving_diagonally = 0

///Holds information about any movement loops currently running/waiting to run on the movable. Lazy, will be null if nothing's going on
var/datum/movement_packet/move_packet

Expand Down Expand Up @@ -71,6 +76,9 @@
///Internal holder for emissive blocker object, DO NOT USE DIRECTLY. Use blocks_emissive
var/mutable_appearance/em_block

/// Whether this atom should have its dir automatically changed when it moves. Setting this to FALSE allows for things such as directional windows to retain dir on moving without snowflake code all of the place.
var/set_dir_on_move = TRUE

/atom/movable/Initialize(mapload, ...)
. = ..()
update_emissive_blocker()
Expand Down Expand Up @@ -148,7 +156,7 @@
if(old_area)
old_area.Exited(src, NONE)

Moved(oldloc, NONE, TRUE, null)
RESOLVE_ACTIVE_MOVEMENT

// Make sure you know what you're doing if you call this
// You probably want CanPass()
Expand All @@ -162,7 +170,7 @@
///default byond proc that is deprecated for us in lieu of signals. do not call
/atom/movable/Crossed(atom/movable/crossed_atom, oldloc)
SHOULD_NOT_OVERRIDE(TRUE)
// CRASH("atom/movable/Crossed() was called!") //pending rework of /atom/movable/Move() this is suppressed
CRASH("atom/movable/Crossed() was called!")

/**
* `Uncross()` is a default BYOND proc that is called when something is *going*
Expand All @@ -187,7 +195,7 @@
/atom/movable/Uncross()
. = TRUE
SHOULD_NOT_OVERRIDE(TRUE)
// CRASH("Uncross() should not be being called, please read the doc-comment for it for why.") //pending rework of /atom/movable/Move() this is suppressed
CRASH("Uncross() should not be being called, please read the doc-comment for it for why.")

/**
* default byond proc that is normally called on everything inside the previous turf
Expand All @@ -197,7 +205,7 @@
*/
/atom/movable/Uncrossed(atom/movable/uncrossed_atom)
SHOULD_NOT_OVERRIDE(TRUE)
// CRASH("/atom/movable/Uncrossed() was called") //pending rework of /atom/movable/Move() this is suppressed
CRASH("/atom/movable/Uncrossed() was called")

/**
* Pretend this is `Bump()`
Expand Down Expand Up @@ -486,14 +494,20 @@

// Core movement hooks & procs.
/atom/movable/proc/forceMove(atom/destination)
. = FALSE
RESOLVE_ACTIVE_MOVEMENT

if(!destination)
return FALSE
if(loc)
loc.Exited(src, destination)
var/old_loc = loc
var/oldloc = loc

SET_ACTIVE_MOVEMENT(oldloc, NONE, TRUE, null)

loc = destination
loc.Entered(src, old_loc)
Moved(old_loc, get_dir(old_loc, destination), TRUE)
loc.Entered(src, oldloc)
Moved(oldloc, get_dir(oldloc, destination), TRUE)

//Zmimic
if(bound_overlay)
Expand All @@ -515,6 +529,8 @@
L = thing
L.source_atom.update_light()

RESOLVE_ACTIVE_MOVEMENT

return TRUE

/**
Expand Down Expand Up @@ -857,14 +873,163 @@
* most of the time you want forceMove()
*/
/atom/movable/proc/abstract_move(atom/new_loc)
// RESOLVE_ACTIVE_MOVEMENT // This should NEVER happen, but, just in case...
RESOLVE_ACTIVE_MOVEMENT // This should NEVER happen, but, just in case...
var/atom/old_loc = loc
var/direction = get_dir(old_loc, new_loc)
loc = new_loc

//is Moved(old_loc, direction, TRUE, momentum_change = FALSE) in tg
Moved(old_loc, direction, TRUE)

////////////////////////////////////////
// Here's where we rewrite how byond handles movement except slightly different
// To be removed on step_ conversion
// All this work to prevent a second bump
/atom/movable/Move(atom/newloc, direction, glide_size_override = 0, update_dir = TRUE) //Last 2 parameters are not used but they're caught
CAN_BE_REDEFINED(TRUE)
. = FALSE
if(!newloc || newloc == loc)
return

// A mid-movement... movement... occurred, resolve that first.
RESOLVE_ACTIVE_MOVEMENT

if(!direction)
direction = get_dir(src, newloc)

// TEMPORARY OFF because i remember this giving some issues on something i don't quite remember
if(set_dir_on_move && dir != direction && update_dir)
set_dir(direction)

//There should be some multitile code above, it was cut as we don't do multitile movement (yet)
if(!loc.Exit(src, direction))
return

//There should be some multitile code above, it was cut as we don't do multitile movement (yet)
if(!newloc.Enter(src))
return
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, newloc) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
return

var/atom/oldloc = loc
var/area/oldarea = get_area(oldloc)
var/area/newarea = get_area(newloc)

SET_ACTIVE_MOVEMENT(oldloc, direction, FALSE, list()) //This is different from TG because we don't have multitile movement (yet)
loc = newloc

. = TRUE

oldloc.Exited(src, direction)
if(oldarea != newarea)
oldarea.Exited(src, direction)

newloc.Entered(src, oldloc) //This is different from TG because we don't have multitile movement (yet)
if(oldarea != newarea)
newarea.Entered(src, oldarea)

// Lighting.
if(light_sources)
var/datum/light_source/L
var/thing
for(thing in light_sources)
L = thing
L.source_atom.update_light()

// Openturf.
if(bound_overlay)
// The overlay will handle cleaning itself up on non-openspace turfs.
bound_overlay.forceMove(get_step(src, UP))
if(bound_overlay.dir != dir)
bound_overlay.set_dir(dir)

if(opacity)
updateVisibility(src)

//Mimics
if(bound_overlay)
bound_overlay.forceMove(get_step(src, UP))
if(bound_overlay.dir != dir)
bound_overlay.set_dir(dir)

src.move_speed = world.time - src.l_move_time
src.l_move_time = world.time
if ((oldloc != src.loc && oldloc && oldloc.z == src.z))
src.last_move = get_dir(oldloc, src.loc)

RESOLVE_ACTIVE_MOVEMENT

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

/atom/movable/Move(atom/newloc, direct, glide_size_override = 0, update_dir = TRUE)
CAN_BE_REDEFINED(TRUE)
// var/atom/movable/pullee = pulling
// var/turf/current_turf = loc

if(!loc || !newloc)
return FALSE

if(loc != newloc)
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
else //Diagonal move, split it into cardinal moves
moving_diagonally = FIRST_DIAG_STEP
var/first_step_dir
// The `&& moving_diagonally` checks are so that a forceMove taking
// place due to a Crossed, Bumped, etc. call will interrupt
// the second half of the diagonal movement, or the second attempt
// at a first half if step() fails because we hit something.
if (direct & NORTH)
if (direct & EAST)
if (step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & WEST)
if (step(src, NORTH) && moving_diagonally)
first_step_dir = NORTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & SOUTH)
if (direct & EAST)
if (step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (moving_diagonally && step(src, EAST))
first_step_dir = EAST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
else if (direct & WEST)
if (step(src, SOUTH) && moving_diagonally)
first_step_dir = SOUTH
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (moving_diagonally && step(src, WEST))
first_step_dir = WEST
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
if(moving_diagonally == SECOND_DIAG_STEP)
if(!. && set_dir_on_move && update_dir)
set_dir(first_step_dir)
else if(!inertia_moving)
newtonian_move(dir2angle(direct))

moving_diagonally = 0
return

last_move = direct
if(set_dir_on_move && dir != direct && update_dir)
set_dir(direct)

/**
* Adds the red drop-shadow filter when pointed to by a mob.
* Override if the atom doesn't play nice with filters.
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/cult/structures/pylon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@


/obj/structure/cult/pylon/Move()
..()
. = ..()
last_target_loc = null

/obj/structure/cult/pylon/proc/start_process()
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/CableLayer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
cable.amount = max_cable

/obj/machinery/cablelayer/Move(new_turf,M_Dir)
..()
. = ..()
if(on)
layCable(new_turf,M_Dir)

Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/floorlayer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
T = new /obj/item/stack/tile/floor/full_stack(src)

/obj/machinery/floorlayer/Move(new_turf,M_Dir)
..()
. = ..()

if(on)
if(mode["dismantle"])
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/howitzer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ ABSTRACT_TYPE(/obj/machinery/howitzer)
else
break

new /obj/effect/effect/smoke(smoke_position, 2 SECONDS)
new /obj/effect/smoke(smoke_position, 2 SECONDS)

for(var/mob/living/carbon/human/H in range(3, src))
if(H.client)
Expand Down
Loading
Loading