Skip to content

Commit

Permalink
woe, refactor upon yee
Browse files Browse the repository at this point in the history
  • Loading branch information
XeonMations committed Aug 22, 2024
1 parent 8b04e0d commit 53b7588
Show file tree
Hide file tree
Showing 52 changed files with 295 additions and 126 deletions.
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@
#include "code\datums\elements\light_blocking.dm"
#include "code\datums\elements\mechanical_repair.dm"
#include "code\datums\elements\mirage_border.dm"
#include "code\datums\elements\movetype_handler.dm"
#include "code\datums\elements\obj_regen.dm"
#include "code\datums\elements\openspace_item_click_handler.dm"
#include "code\datums\elements\pet_bonus.dm"
Expand Down
9 changes: 9 additions & 0 deletions code/__DEFINES/dcs/signals/signals_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,12 @@
#define COMSIG_STORAGE_ENTERED "storage_entered"
///from base of atom/movable/on_exit_storage(): (datum/component/storage/concrete/master_storage)
#define COMSIG_STORAGE_EXITED "storage_exited"

// /datum/element/movetype_handler signals
/// Called when the floating anim has to be temporarily stopped and restarted later: (timer)
#define COMSIG_PAUSE_FLOATING_ANIM "pause_floating_anim"
/// From base of datum/element/movetype_handler/on_movement_type_trait_gain: (flag)
#define COMSIG_MOVETYPE_FLAG_ENABLED "movetype_flag_enabled"
/// From base of datum/element/movetype_handler/on_movement_type_trait_loss: (flag)
#define COMSIG_MOVETYPE_FLAG_DISABLED "movetype_flag_disabled"

15 changes: 15 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,18 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai

/// Trait for psyphoza, flag for examine logic
#define TRAIT_PSYCHIC_SENSE "psychic_sense"

///Movement type traits for movables. See elements/movetype_handler.dm
#define TRAIT_MOVE_GROUND "move_ground"
#define TRAIT_MOVE_FLYING "move_flying"
#define TRAIT_MOVE_VENTCRAWLING "move_ventcrawling"
#define TRAIT_MOVE_FLOATING "move_floating"
#define TRAIT_MOVE_PHASING "move_phasing"
/// Disables the floating animation. See above.
#define TRAIT_NO_FLOATING_ANIM "no-floating-animation"

#define VENTCRAWLING_TRAIT "ventcrawling"
#define SPECIES_FLIGHT_TRAIT "species-flight"
#define NO_GRAVITY_TRAIT "no-gravity"
#define LIFECANDLE_TRAIT "lifecandle"
#define LEAPER_BUBBLE_TRAIT "leaper-bubble"
29 changes: 29 additions & 0 deletions code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_DOOR_PRYER" = TRAIT_DOOR_PRYER,
"TRAIT_FISH_SAFE_STORAGE" = TRAIT_FISH_SAFE_STORAGE,
"TRAIT_FISH_CASE_COMPATIBILE" = TRAIT_FISH_CASE_COMPATIBILE
),
/atom/movable = list(
"TRAIT_MOVE_GROUND" = TRAIT_MOVE_GROUND,
"TRAIT_MOVE_FLYING" = TRAIT_MOVE_FLYING,
"TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING,
"TRAIT_MOVE_FLOATING" = TRAIT_MOVE_FLOATING,
"TRAIT_MOVE_PHASING" = TRAIT_MOVE_PHASING
)
))

Expand All @@ -151,3 +158,25 @@ GLOBAL_LIST(trait_name_map)
for(var/tname in GLOB.traits_by_type[key])
var/val = GLOB.traits_by_type[key][tname]
.[val] = tname


GLOBAL_LIST_INIT(movement_type_trait_to_flag, list(
TRAIT_MOVE_GROUND = GROUND,
TRAIT_MOVE_FLYING = FLYING,
TRAIT_MOVE_VENTCRAWLING = VENTCRAWLING,
TRAIT_MOVE_FLOATING = FLOATING,
TRAIT_MOVE_PHASING = PHASING
))

GLOBAL_LIST_INIT(movement_type_addtrait_signals, set_movement_type_addtrait_signals())
GLOBAL_LIST_INIT(movement_type_removetrait_signals, set_movement_type_removetrait_signals())

/proc/set_movement_type_addtrait_signals(signal_prefix)
. = list()
for(var/trait in GLOB.movement_type_trait_to_flag)
. += SIGNAL_ADDTRAIT(trait)

/proc/set_movement_type_removetrait_signals(signal_prefix)
. = list()
for(var/trait in GLOB.movement_type_trait_to_flag)
. += SIGNAL_REMOVETRAIT(trait)
2 changes: 1 addition & 1 deletion code/datums/components/caltrop.dm
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover))
return

if((H.movement_type & FLYING) || (H.body_position == LYING_DOWN)|| H.buckled)
if((H.movement_type & (FLYING|FLOATING)) || (H.body_position == LYING_DOWN)|| H.buckled)
return

var/damage = rand(min_damage, max_damage)
Expand Down
4 changes: 1 addition & 3 deletions code/datums/components/chasm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
return FALSE
if(!isliving(AM) && !isobj(AM))
return FALSE
if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || (AM.movement_type & FLOATING))
if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || (AM.movement_type & (FLOATING|FLYING)))
return FALSE
//Flies right over the chasm
if(ismob(AM))
Expand All @@ -78,8 +78,6 @@
var/mob/buckled_to = M.buckled
if((!ismob(M.buckled) || (buckled_to.buckled != M)) && !droppable(M.buckled))
return FALSE
if(M.is_flying())
return FALSE
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
if(istype(H.belt, /obj/item/wormhole_jaunter))
Expand Down
107 changes: 107 additions & 0 deletions code/datums/elements/movetype_handler.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* An element that enables and disables movetype bitflags as movetype traits are added and removed.
* It also handles the +2/-2 pixel y anim loop typical of mobs possessing the FLYING or FLOATING movetypes.
* This element is necessary for the TRAIT_MOVE_ traits to work correctly. So make sure to include it when
* manipulating those traits on non-living movables.
*/
/datum/element/movetype_handler
element_flags = ELEMENT_DETACH

var/list/attached_atoms = list()
var/list/paused_floating_anim_atoms = list()

/datum/element/movetype_handler/Attach(datum/target)
. = ..()
if(!ismovable(target))
return ELEMENT_INCOMPATIBLE
if(attached_atoms[target]) //Already attached.
return

var/atom/movable/movable_target = target
RegisterSignals(movable_target, GLOB.movement_type_addtrait_signals, .proc/on_movement_type_trait_gain)
RegisterSignals(movable_target, GLOB.movement_type_removetrait_signals, .proc/on_movement_type_trait_loss)
RegisterSignal(movable_target, SIGNAL_ADDTRAIT(TRAIT_NO_FLOATING_ANIM), .proc/on_no_floating_anim_trait_gain)
RegisterSignal(movable_target, SIGNAL_REMOVETRAIT(TRAIT_NO_FLOATING_ANIM), .proc/on_no_floating_anim_trait_loss)
RegisterSignal(movable_target, COMSIG_PAUSE_FLOATING_ANIM, .proc/pause_floating_anim)
attached_atoms[movable_target] = TRUE

if(movable_target.movement_type & (FLOATING|FLYING) && !HAS_TRAIT(movable_target, TRAIT_NO_FLOATING_ANIM))
float(movable_target)

/datum/element/movetype_handler/Detach(datum/source)
UnregisterSignal(source, GLOB.movement_type_addtrait_signals)
UnregisterSignal(source, GLOB.movement_type_removetrait_signals)
UnregisterSignal(source, SIGNAL_ADDTRAIT(TRAIT_NO_FLOATING_ANIM))
UnregisterSignal(source, SIGNAL_REMOVETRAIT(TRAIT_NO_FLOATING_ANIM))
UnregisterSignal(source, COMSIG_PAUSE_FLOATING_ANIM)
attached_atoms -= source
paused_floating_anim_atoms -= source
stop_floating(source)
return ..()

/// Called when a movement type trait is added to the movable. Enables the relative bitflag.
/datum/element/movetype_handler/proc/on_movement_type_trait_gain(atom/movable/source, trait)
SIGNAL_HANDLER
var/flag = GLOB.movement_type_trait_to_flag[trait]
if(source.movement_type & flag)
return
if(!(source.movement_type & (FLOATING|FLYING)) && (trait == TRAIT_MOVE_FLYING || trait == TRAIT_MOVE_FLOATING) && !paused_floating_anim_atoms[source] && !HAS_TRAIT(source, TRAIT_NO_FLOATING_ANIM))
float(source)
source.movement_type |= flag
SEND_SIGNAL(source, COMSIG_MOVETYPE_FLAG_ENABLED, flag)

/// Called when a movement type trait is removed from the movable. Disables the relative bitflag if it wasn't there in the compile-time bitfield.
/datum/element/movetype_handler/proc/on_movement_type_trait_loss(atom/movable/source, trait)
SIGNAL_HANDLER
var/flag = GLOB.movement_type_trait_to_flag[trait]
if(initial(source.movement_type) & flag)
return
source.movement_type &= ~flag
if((trait == TRAIT_MOVE_FLYING || trait == TRAIT_MOVE_FLOATING) && !(source.movement_type & (FLOATING|FLYING)))
stop_floating(source)
SEND_SIGNAL(source, COMSIG_MOVETYPE_FLAG_DISABLED, flag)

/// Called when the TRAIT_NO_FLOATING_ANIM trait is added to the movable. Stops it from bobbing up and down.
/datum/element/movetype_handler/proc/on_no_floating_anim_trait_gain(atom/movable/source, trait)
SIGNAL_HANDLER
stop_floating(source)

/// Called when the TRAIT_NO_FLOATING_ANIM trait is removed from the mob. Restarts the bobbing animation.
/datum/element/movetype_handler/proc/on_no_floating_anim_trait_loss(atom/movable/source, trait)
SIGNAL_HANDLER
if(source.movement_type & (FLOATING|FLYING) && !paused_floating_anim_atoms[source])
float(source)

///Pauses the floating animation for the duration of the timer... plus [tickrate - (world.time + timer) % tickrate] to be precise.
/datum/element/movetype_handler/proc/pause_floating_anim(atom/movable/source, timer)
SIGNAL_HANDLER
if(paused_floating_anim_atoms[source] < world.time + timer)
stop_floating(source)
if(!length(paused_floating_anim_atoms))
START_PROCESSING(SSdcs, src) //1 second tickrate.
paused_floating_anim_atoms[source] = world.time + timer

/datum/element/movetype_handler/process()
for(var/_paused in paused_floating_anim_atoms)
var/atom/movable/paused = _paused
if(!paused)
paused_floating_anim_atoms -= paused
else if(paused_floating_anim_atoms[paused] < world.time)
if(paused.movement_type & (FLOATING|FLYING) && !HAS_TRAIT(paused, TRAIT_NO_FLOATING_ANIM))
float(paused)
paused_floating_anim_atoms -= paused
if(!length(paused_floating_anim_atoms))
STOP_PROCESSING(SSdcs, src)

///Floats the movable up and down. Not a comsig proc.
/datum/element/movetype_handler/proc/float(atom/movable/target)
animate(target, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)

/// Stops the above. Also not a comsig proc.
/datum/element/movetype_handler/proc/stop_floating(atom/movable/target)
var/final_pixel_y = target.base_pixel_y
if(isliving(target)) //Living mobs also have a 'body_position_pixel_y_offset' variable that has to be taken into account here.
var/mob/living/living_target = target
final_pixel_y += living_target.body_position_pixel_y_offset
animate(target, pixel_y = final_pixel_y, time = 1 SECONDS)
30 changes: 8 additions & 22 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@
var/datum/movement_packet/move_packet
var/list/acted_explosions //for explosion dodging
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
///In case you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. Should only be changed through setMovetype()
/**
* In case you have multiple types, you automatically use the most useful one.
* IE: Skating on ice, flippers on water, flying over chasm/space, etc.
* I reccomend you use the movetype_handler system and not modify this directly, especially for living mobs.
*/
var/movement_type = GROUND

var/atom/movable/pulling
var/grab_state = 0
var/throwforce = 0
Expand Down Expand Up @@ -665,14 +670,6 @@

Moved(oldloc, NONE, TRUE)

///Proc to modify the movement_type and hook behavior associated with it changing.
/atom/movable/proc/setMovetype(newval)
if(movement_type == newval)
return
. = movement_type
movement_type = newval


//Called whenever an object moves and by mobs when they attempt to move themselves through space
//And when an object or action applies a force on src, see newtonian_move() below
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
Expand Down Expand Up @@ -908,8 +905,8 @@

var/matrix/initial_transform = matrix(transform)
var/matrix/rotated_transform = transform.Turn(rand(13,17) * turn_dir)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN)
animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform=rotated_transform, time = 1, easing=BACK_EASING|EASE_IN, flags = ANIMATION_PARALLEL)
animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform=initial_transform, time = 2, easing=SINE_EASING, flags = ANIMATION_PARALLEL)

/atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item)
var/image/I
Expand Down Expand Up @@ -1008,17 +1005,6 @@
acted_explosions += ex_id
return TRUE

//TODO: Better floating
/atom/movable/proc/float(on)
if(throwing)
return
if(on && !(movement_type & FLOATING))
animate(src, pixel_y = 2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
animate(pixel_y = -2, time = 10, loop = -1, flags = ANIMATION_RELATIVE)
setMovetype(movement_type | FLOATING)
else if (!on && (movement_type & FLOATING))
animate(src, pixel_y = base_pixel_y, time = 10)
setMovetype(movement_type & ~FLOATING)
/* Language procs
* Unless you are doing something very specific, these are the ones you want to use.
*/
Expand Down
19 changes: 19 additions & 0 deletions code/game/objects/buckling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@
if (!check_loc && M.loc != loc)
M.forceMove(loc)

if(anchored)
ADD_TRAIT(M, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT)
if(!length(buckled_mobs))
RegisterSignal(src, COMSIG_MOVABLE_SET_ANCHORED, .proc/on_set_anchored)
M.set_buckled(src)
M.setDir(dir)
buckled_mobs |= M
Expand Down Expand Up @@ -153,10 +157,25 @@
buckled_mob.clear_alert("buckled")
//buckled_mob.set_glide_size(DELAY_TO_GLIDE_SIZE(buckled_mob.total_multiplicative_slowdown()))
buckled_mobs -= buckled_mob
if(anchored)
REMOVE_TRAIT(buckled_mob, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT)
if(!length(buckled_mobs))
UnregisterSignal(src, COMSIG_MOVABLE_SET_ANCHORED, .proc/on_set_anchored)
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)

post_unbuckle_mob(.)

/atom/movable/proc/on_set_anchored(atom/movable/source, anchorvalue)
SIGNAL_HANDLER
for(var/_buckled_mob in buckled_mobs)
if(!_buckled_mob)
continue
var/mob/living/buckled_mob = _buckled_mob
if(anchored)
ADD_TRAIT(buckled_mob, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT)
else
REMOVE_TRAIT(buckled_mob, TRAIT_NO_FLOATING_ANIM, BUCKLED_TRAIT)


/atom/movable/proc/unbuckle_all_mobs(force=FALSE)
if(!has_buckled_mobs())
Expand Down
9 changes: 8 additions & 1 deletion code/game/objects/structures/life_candle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
var/respawn_time = 50
var/respawn_sound = 'sound/magic/staff_animation.ogg'

/obj/structure/life_candle/ComponentInitialize()
. = ..()
AddElement(/datum/element/movetype_handler)

/obj/structure/life_candle/attack_hand(mob/user)
. = ..()
if(.)
Expand All @@ -33,12 +37,15 @@
if(user.mind in linked_minds)
user.visible_message("<span class='notice'>[user] reaches out and pinches the flame of [src].</span>", "<span class='warning'>You sever the connection between yourself and [src].</span>")
linked_minds -= user.mind
if(!linked_minds.len)
REMOVE_TRAIT(src, TRAIT_MOVE_FLOATING, LIFECANDLE_TRAIT)
else
user.visible_message("<span class='notice'>[user] touches [src]. It seems to respond to [user.p_their()] presence!</span>", "<span class='warning'>You create a connection between you and [src].</span>")
linked_minds |= user.mind
if(!linked_minds.len)
ADD_TRAIT(src, TRAIT_MOVE_FLOATING, LIFECANDLE_TRAIT)

update_icon()
float(linked_minds.len)
if(linked_minds.len)
START_PROCESSING(SSobj, src)
set_light(lit_luminosity)
Expand Down
2 changes: 2 additions & 0 deletions code/modules/admin/verbs/randomverbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/source = "adminabuse"
switch(add_or_remove)
if("Add") //Not doing source choosing here intentionally to make this bit faster to use, you can always vv it.
if(GLOB.movement_type_trait_to_flag[chosen_trait]) //include the required element.
D.AddElement(/datum/element/movetype_handler)
ADD_TRAIT(D,chosen_trait,source)
if("Remove")
var/specific = input("All or specific source ?", "Trait Remove/Add") as null|anything in list("All","Specific")
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/blob/blob_mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
attack_verb_continuous = "hits"
attack_verb_simple = "hit"
attack_sound = 'sound/weapons/genhit1.ogg'
movement_type = FLYING
is_flying_animal = TRUE
del_on_death = TRUE
deathmessage = "explodes into a cloud of gas!"
gold_core_spawnable = HOSTILE_SPAWN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(clockwork_marauders)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = INFINITY
movement_type = FLYING
is_flying_animal = TRUE
move_resist = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_LARGE
pass_flags = PASSTABLE
Expand Down
2 changes: 1 addition & 1 deletion code/modules/antagonists/clock_cult/mobs/eminence.dm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
status_flags = 0
wander = FALSE
density = FALSE
movement_type = FLYING
is_flying_animal = TRUE
move_resist = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_TINY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
var/target_stabbed = FALSE
density = TRUE
for(var/mob/living/M in get_turf(src))
if(M.incorporeal_move || M.is_flying())
if(M.incorporeal_move || M.movement_type & (FLOATING|FLYING))
continue
if(buckle_mob(M, TRUE))
target_stabbed = TRUE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
if(istype(M))
if(is_servant_of_ratvar(M))
return
if(M.incorporeal_move || M.is_flying())
if(M.incorporeal_move || M.movement_type & (FLOATING|FLYING))
return
else
return
Expand Down
Loading

0 comments on commit 53b7588

Please sign in to comment.