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

refactor: Movement cross/uncross implementation. #26762

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d08dac8
refactor: Movement cross/uncross implementation.
warriorstar-orion Sep 5, 2024
1abac61
wrong var name
warriorstar-orion Sep 12, 2024
fa793a7
fix unit tests dropping PDAs into nowhere
warriorstar-orion Sep 12, 2024
283dca6
Merge remote-tracking branch 'origin/master' into refactor/core-move
warriorstar-orion Sep 14, 2024
3c5b761
Add documentation.
warriorstar-orion Sep 14, 2024
cefddd1
remove unused constants
warriorstar-orion Sep 14, 2024
9c2ea39
say which procs are off limits
warriorstar-orion Sep 14, 2024
d8a5fe4
fix simpleanimal z change runtime
warriorstar-orion Sep 14, 2024
d7aaa64
Merge remote-tracking branch 'origin/master' into refactor/core-move
warriorstar-orion Sep 18, 2024
d4b4cf4
helps not to leave merge conflicts
warriorstar-orion Sep 18, 2024
0160c86
kill me
warriorstar-orion Sep 18, 2024
1edfe72
Merge remote-tracking branch 'origin/master' into refactor/core-move
warriorstar-orion Sep 19, 2024
a1c3576
fix typecast
warriorstar-orion Sep 19, 2024
2f78b6b
Merge branch 'master' into refactor/core-move
warriorstar-orion Sep 27, 2024
3679054
Merge remote-tracking branch 'origin/master' into refactor/core-move
warriorstar-orion Sep 27, 2024
4c7de17
fix projectile/table collision
warriorstar-orion Sep 27, 2024
f02b326
treadmills don't cause MC to crash anymore
warriorstar-orion Sep 28, 2024
9ec2b16
connect_loc is appropriate here
warriorstar-orion Sep 28, 2024
6f268fb
fix windoors and teleporters
warriorstar-orion Oct 1, 2024
39962c3
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 1, 2024
04f7ff9
fix bonfires and clarify docs
warriorstar-orion Oct 1, 2024
7086a0d
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 2, 2024
ff4df1f
fix proximity sensors
warriorstar-orion Oct 2, 2024
1d715d3
lint
warriorstar-orion Oct 2, 2024
0feb081
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 2, 2024
bd03ee7
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 3, 2024
be83a82
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 10, 2024
fcfc5ea
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 13, 2024
ca9630a
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 15, 2024
52473ed
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 20, 2024
9814f98
fix: polarized access helper false positives
warriorstar-orion Oct 20, 2024
6b1e0f4
Revert "fix: polarized access helper false positives"
warriorstar-orion Oct 20, 2024
8c3f065
Merge remote-tracking branch 'upstream/master' into refactor/core-move
warriorstar-orion Oct 21, 2024
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
4 changes: 3 additions & 1 deletion code/__DEFINES/dcs/atom_signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

// /atom

//from SSatoms InitAtom - Only if the atom was not deleted or failed initialization and has a loc
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON "atom_init_success_on"
///from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMSIG_PARENT_ATTACKBY "atom_attackby"
///Return this in response if you don't want afterattack to be called
Expand Down Expand Up @@ -40,7 +42,7 @@
#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/entered, /atom)
#define COMSIG_ATOM_ENTERED "atom_entered"
///from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
#define COMSIG_ATOM_EXIT "atom_exit"
Expand Down
15 changes: 8 additions & 7 deletions code/__DEFINES/dcs/movable_signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@
* All signals send the source datum of the signal as the first argument
*/

///from base of atom/movable/Moved(): (/atom)
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move"
#define COMPONENT_MOVABLE_BLOCK_PRE_MOVE (1<<0)
///from base of atom/movable/Moved(): (/atom, dir)
#define COMSIG_MOVABLE_MOVED "movable_moved"
///from base of atom/movable/Cross(): (/atom/movable)
#define COMSIG_MOVABLE_CROSS "movable_cross"
///from base of atom/movable/Crossed(): (/atom/movable)
#define COMSIG_MOVABLE_CROSSED "movable_crossed"
///when we cross over something (calling Crossed() on that atom)
#define COMSIG_CROSSED_MOVABLE "crossed_movable"
#define COMPONENT_BLOCK_CROSS (1<<0)
///from base of atom/movable/Move(): (/atom/movable)
#define COMSIG_MOVABLE_CROSS_OVER "movable_cross_over"
///from base of atom/movable/Uncross(): (/atom/movable)
#define COMSIG_MOVABLE_UNCROSS "movable_uncross"
#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)
#define COMSIG_MOVABLE_BUMP "movable_bump"
#define COMPONENT_INTERCEPT_BUMPED (1<<0)
///from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
#define COMSIG_MOVABLE_IMPACT "movable_impact"
#define COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH (1<<0) //if true, flip if the impact will push what it hits
Expand All @@ -41,7 +42,7 @@
#define COMSIG_MOVABLE_THROW_LANDED "movable_throw_landed"
///from base of atom/movable/shove_impact(): (mob/living/target, mob/living/attacker)
#define COMSIG_MOVABLE_SHOVE_IMPACT "movable_shove_impact"
///from base of atom/movable/onTransitZ(): (old_z, new_z)
///from base of atom/movable/on_changed_z_level(): (turf/old_turf, turf/new_turf)
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit"

/// Called just before something gets untilted
Expand Down
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_pass_meteor, typecacheof(list(
#define ispassmeteorturf(A) (is_type_in_typecache(A, GLOB.turfs_pass_meteor))

#define is_screen_atom(A) istype(A, /atom/movable/screen)

#define is_multi_tile_object(atom) (atom.bound_width > world.icon_size || atom.bound_height > world.icon_size)
warriorstar-orion marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 16 additions & 0 deletions code/__DEFINES/movement_info.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/// 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)); \
}
10 changes: 10 additions & 0 deletions code/__HELPERS/atom_helpers.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
///Returns a list of all locations (except the area) the movable is within.
/proc/get_nested_locs(atom/movable/atom_on_location, include_turf = FALSE)
. = list()
var/atom/location = atom_on_location.loc
var/turf/our_turf = get_turf(atom_on_location)
while(location && location != our_turf)
. += location
location = location.loc
if(our_turf && include_turf) //At this point, only the turf is left, provided it exists.
. += our_turf
4 changes: 4 additions & 0 deletions code/controllers/subsystem/non_firing/SSatoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ SUBSYSTEM_DEF(atoms)
qdeleted = TRUE
else if(!A.initialized)
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
else
var/atom/location = A.loc
if(location)
SEND_SIGNAL(location, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, A, arguments[1])

return qdeleted || QDELING(A)

Expand Down
22 changes: 15 additions & 7 deletions code/datums/beam.dm
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@
anchored = TRUE
var/datum/beam/owner

/obj/effect/ebeam/Initialize(mapload)
. = ..()
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered),
)
AddElement(/datum/element/connect_loc, loc_connections)

/obj/effect/ebeam/proc/on_atom_entered(datum/source, atom/movable/entered)
return

/obj/effect/ebeam/ex_act(severity)
return

Expand All @@ -131,9 +141,8 @@
/obj/effect/ebeam/singularity_act()
return

/obj/effect/ebeam/deadly/Crossed(atom/A, oldloc)
..()
A.ex_act(EXPLODE_DEVASTATE)
/obj/effect/ebeam/deadly/on_atom_entered(datum/source, atom/movable/entered)
entered.ex_act(EXPLODE_DEVASTATE)

/obj/effect/ebeam/vetus/Destroy()
for(var/mob/living/M in get_turf(src))
Expand All @@ -147,11 +156,10 @@
/obj/effect/ebeam/disintegration
layer = ON_EDGED_TURF_LAYER

/obj/effect/ebeam/disintegration/Crossed(atom/A, oldloc)
..()
if(!isliving(A))
/obj/effect/ebeam/disintegration/on_atom_entered(datum/source, atom/movable/entered)
if(!isliving(entered))
return
var/mob/living/L = A
var/mob/living/L = entered
var/damage = 50
if(L.stat == DEAD)
visible_message("<span class='danger'>[L] is disintegrated by the beam!</span>")
Expand Down
21 changes: 16 additions & 5 deletions code/datums/components/caltrop.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
///Shoebypassing, walking interaction, silence
var/flags

///given to connect_loc to listen for something moving over target
var/static/list/crossed_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
)

var/cooldown = 0

/datum/component/caltrop/Initialize(_min_damage = 0, _max_damage = 0, _probability = 100, _weaken_duration = 6 SECONDS, _flags = NONE)
Expand All @@ -23,21 +28,23 @@
src.weaken_duration = _weaken_duration
src.flags = _flags

/datum/component/caltrop/RegisterWithParent()
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, PROC_REF(Crossed))
if(ismovable(parent))
AddComponent(/datum/component/connect_loc_behalf, parent, crossed_connections)
else
RegisterSignal(get_turf(parent), COMSIG_ATOM_ENTERED, PROC_REF(on_entered))

/datum/component/caltrop/proc/Crossed(datum/source, atom/movable/AM)
/datum/component/caltrop/proc/on_entered(atom/source, atom/movable/entered, turf/old_loc)
var/atom/A = parent
if(!has_gravity(A))
return

if(!prob(probability))
return

if(!ishuman(AM))
if(!ishuman(entered))
return

var/mob/living/carbon/human/H = AM
var/mob/living/carbon/human/H = entered

if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE))
return
Expand Down Expand Up @@ -82,3 +89,7 @@

cooldown = world.time
H.Weaken(weaken_duration)

/datum/component/caltrop/UnregisterFromParent()
if(ismovable(parent))
qdel(GetComponent(/datum/component/connect_loc_behalf))
68 changes: 68 additions & 0 deletions code/datums/components/connect_containers.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/// This component behaves similar to connect_loc_behalf, but it's nested and hooks a signal onto all MOVABLES containing this atom.
/datum/component/connect_containers
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS

/// An assoc list of signal -> procpath to register to the loc this object is on.
var/list/connections
/**
* The atom the component is tracking. The component will delete itself if the tracked is deleted.
* Signals will also be updated whenever it moves.
*/
var/atom/movable/tracked

/datum/component/connect_containers/Initialize(atom/movable/tracked, list/connections)
. = ..()
if(!ismovable(tracked))
return COMPONENT_INCOMPATIBLE

src.connections = connections
set_tracked(tracked)

/datum/component/connect_containers/Destroy()
set_tracked(null)
return ..()

/datum/component/connect_containers/InheritComponent(datum/component/component, original, atom/movable/tracked, list/connections)
// Not equivalent. Checks if they are not the same list via shallow comparison.
if(!compare_list(src.connections, connections))
stack_trace("connect_containers component attached to [parent] tried to inherit another connect_containers component with different connections")
return
if(src.tracked != tracked)
set_tracked(tracked)

/datum/component/connect_containers/proc/set_tracked(atom/movable/new_tracked)
if(tracked)
UnregisterSignal(tracked, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING))
unregister_signals(tracked.loc)
tracked = new_tracked
if(!tracked)
return
RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel))
update_signals(tracked)

/datum/component/connect_containers/proc/handle_tracked_qdel()
SIGNAL_HANDLER
qdel(src)

/datum/component/connect_containers/proc/update_signals(atom/movable/listener)
if(!ismovable(listener.loc))
return

for(var/atom/movable/container as anything in get_nested_locs(listener))
RegisterSignal(container, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
for(var/signal in connections)
parent.RegisterSignal(container, signal, connections[signal])

/datum/component/connect_containers/proc/unregister_signals(atom/movable/location)
if(!ismovable(location))
return

for(var/atom/movable/target as anything in (get_nested_locs(location) + location))
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
parent.UnregisterSignal(target, connections)

/datum/component/connect_containers/proc/on_moved(atom/movable/listener, atom/old_loc)
SIGNAL_HANDLER
unregister_signals(old_loc)
update_signals(listener)
69 changes: 69 additions & 0 deletions code/datums/components/connect_loc_behalf.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/// This component behaves similar to connect_loc, hooking into a signal on a tracked object's turf
/// It has the ability to react to that signal on behalf of a separate listener however
/// This has great use, primarily for components, but it carries with it some overhead
/// So we do it separately as it needs to hold state which is very likely to lead to bugs if it remains as an element.
/datum/component/connect_loc_behalf
dupe_mode = COMPONENT_DUPE_UNIQUE

/// An assoc list of signal -> procpath to register to the loc this object is on.
var/list/connections

var/atom/movable/tracked

var/atom/tracked_loc

/datum/component/connect_loc_behalf/Initialize(atom/movable/tracked, list/connections)
. = ..()
if(!istype(tracked))
return COMPONENT_INCOMPATIBLE
src.connections = connections
src.tracked = tracked

/datum/component/connect_loc_behalf/RegisterWithParent()
RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel))
update_signals()

/datum/component/connect_loc_behalf/UnregisterFromParent()
unregister_signals()
UnregisterSignal(tracked, list(
COMSIG_MOVABLE_MOVED,
COMSIG_PARENT_QDELETING,
))

tracked = null

/datum/component/connect_loc_behalf/proc/handle_tracked_qdel()
SIGNAL_HANDLER
qdel(src)

/datum/component/connect_loc_behalf/proc/update_signals()
unregister_signals()
//You may ask yourself, isn't this just silencing an error?
//The answer is yes, but there's no good cheap way to fix it
//What happens is the tracked object or hell the listener gets say, deleted, which makes targets[old_loc] return a null
//The null results in a bad index, because of course it does
//It's not a solvable problem though, since both actions, the destroy and the move, are sourced from the same signal send
//And sending a signal should be agnostic of the order of listeners
//So we need to either pick the order agnositic, or destroy safe
//And I picked destroy safe. Let's hope this is the right path!
if(isnull(tracked.loc))
return

tracked_loc = tracked.loc

for(var/signal in connections)
parent.RegisterSignal(tracked_loc, signal, connections[signal])

/datum/component/connect_loc_behalf/proc/unregister_signals()
if(isnull(tracked_loc))
return

parent.UnregisterSignal(tracked_loc, connections)

tracked_loc = null

/datum/component/connect_loc_behalf/proc/on_moved(sigtype, atom/movable/tracked, atom/old_loc)
SIGNAL_HANDLER
update_signals()

Loading