diff --git a/code/__DEFINES/dcs/signals/signals_turf.dm b/code/__DEFINES/dcs/signals/signals_turf.dm index 04a2648773a..f89f30d1eb4 100644 --- a/code/__DEFINES/dcs/signals/signals_turf.dm +++ b/code/__DEFINES/dcs/signals/signals_turf.dm @@ -35,3 +35,8 @@ #define FOOTSTEP_OVERRIDEN (1<<0) ///from base of datum/thrownthing/finalize(): (turf/turf, atom/movable/thrownthing) when something is thrown and lands on us #define COMSIG_TURF_MOVABLE_THROW_LANDED "turf_movable_throw_landed" + +///From element/elevation/reset_elevation(): (list/values) +#define COMSIG_TURF_RESET_ELEVATION "turf_reset_elevation" + #define ELEVATION_CURRENT_PIXEL_SHIFT 1 + #define ELEVATION_MAX_PIXEL_SHIFT 2 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 7cd031824f7..4aa6f4a74a4 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -846,6 +846,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NO_MIRROR_REFLECTION "no_mirror_reflection" /// If this movable is currently treading in a turf with the immerse element. #define TRAIT_IMMERSED "immersed" +/// From [/datum/element/elevation_core] for purpose of checking if the turf has the trait from an instance of the element +#define TRAIT_ELEVATED_TURF "elevated_turf" /** * With this, the immerse overlay will give the atom its own submersion visual overlay * instead of one that's also shared with other movables, thus making editing its appearance possible. diff --git a/code/__DEFINES/traits/macros.dm b/code/__DEFINES/traits/macros.dm index bbb5bf0d641..731f9fec260 100644 --- a/code/__DEFINES/traits/macros.dm +++ b/code/__DEFINES/traits/macros.dm @@ -1,6 +1,11 @@ -// This file contains all of the "dynamic" trait sources that can be used in a number of versatile and everchanging ways. +// This file contains all of the "dynamic" traits and trait sources that can be used +// in a number of versatile and everchanging ways. // If it uses psuedo-variables like the examples below, it's a macro-trait. + +/// From [/datum/element/elevation] for purpose of registering/removing signals and detaching the elevation_core when the trait is absent. +#define TRAIT_TURF_HAS_ELEVATED_OBJ(z) "turf_has_elevated_obj_[z]" + /// The item is magically cursed #define CURSED_ITEM_TRAIT(item_type) "cursed_item_[item_type]" /// A trait given by a specific status effect (not sure why we need both but whatever!) diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 7a4ec9a8b89..79facdd304c 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -557,6 +557,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPINNING_WEB_TURF" = TRAIT_SPINNING_WEB_TURF, "TRAIT_TURF_IGNORE_SLIPPERY" = TRAIT_TURF_IGNORE_SLIPPERY, "TRAIT_TURF_IGNORE_SLOWDOWN" = TRAIT_TURF_IGNORE_SLOWDOWN, + "TRAIT_ELEVATED_TURF" = TRAIT_ELEVATED_TURF, ), // SKYRAT EDIT ADDITION START - SKYRAT TRAITS /obj/item/toy/plush/skyrat = list( diff --git a/code/datums/elements/elevation.dm b/code/datums/elements/elevation.dm new file mode 100644 index 00000000000..a2c6511c034 --- /dev/null +++ b/code/datums/elements/elevation.dm @@ -0,0 +1,169 @@ +/** + * Manages the elevation of the turf the source is on (can be the turf itself) + * The atom with the highest pixel_shift gets to set the elevation of the turf to that value. + */ +/datum/element/elevation + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH_ON_HOST_DESTROY + argument_hash_start_idx = 2 + ///The amount of pixel_z applied to the mob standing on the turf + var/pixel_shift + +/datum/element/elevation/Attach(datum/target, pixel_shift) + . = ..() + if(!isatom(target) || isarea(target)) + return ELEMENT_INCOMPATIBLE + + src.pixel_shift = pixel_shift + + if(ismovable(target)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + + var/turf/turf = get_turf(target) + if(turf) + if(!HAS_TRAIT(turf, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift))) + RegisterSignal(turf, COMSIG_TURF_RESET_ELEVATION, PROC_REF(check_elevation)) + RegisterSignal(turf, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf)) + reset_elevation(turf) + ADD_TRAIT(turf, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), ref(target)) + +/datum/element/elevation/Detach(atom/movable/source) + unregister_turf(source, source.loc) + return ..() + +/datum/element/elevation/proc/reset_elevation(turf/target) + var/list/current_values[2] + SEND_SIGNAL(target, COMSIG_TURF_RESET_ELEVATION, current_values) + var/current_pixel_shift = current_values[ELEVATION_CURRENT_PIXEL_SHIFT] + var/new_pixel_shift = current_values[ELEVATION_MAX_PIXEL_SHIFT] + if(new_pixel_shift == current_pixel_shift) + return + if(current_pixel_shift) + target.RemoveElement(/datum/element/elevation_core, current_pixel_shift) + if(new_pixel_shift) + target.AddElement(/datum/element/elevation_core, new_pixel_shift) + +/datum/element/elevation/proc/check_elevation(turf/source, list/current_values) + SIGNAL_HANDLER + current_values[ELEVATION_MAX_PIXEL_SHIFT] = max(current_values[ELEVATION_MAX_PIXEL_SHIFT], pixel_shift) + +/datum/element/elevation/proc/on_moved(atom/movable/source, atom/oldloc) + SIGNAL_HANDLER + unregister_turf(source, oldloc) + if(isturf(source.loc)) + if(!HAS_TRAIT(source.loc, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift))) + RegisterSignal(source.loc, COMSIG_TURF_RESET_ELEVATION, PROC_REF(check_elevation)) + RegisterSignal(source.loc, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf)) + reset_elevation(source.loc) + ADD_TRAIT(source.loc, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), ref(source)) + +/datum/element/elevation/proc/unregister_turf(atom/movable/source, atom/location) + if(!isturf(location)) + return + REMOVE_TRAIT(location, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), ref(source)) + if(!HAS_TRAIT(location, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift))) + UnregisterSignal(location, list(COMSIG_TURF_RESET_ELEVATION, COMSIG_TURF_CHANGE)) + reset_elevation(location) + +///Changing or destroying the turf detaches the element, also we need to reapply the traits since they don't get passed down. +/datum/element/elevation/proc/pre_change_turf(turf/changed, path, list/new_baseturfs, flags, list/post_change_callbacks) + SIGNAL_HANDLER + var/list/trait_sources = GET_TRAIT_SOURCES(changed, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift)) + trait_sources = trait_sources.Copy() + post_change_callbacks += CALLBACK(src, PROC_REF(post_change_turf), trait_sources) + +/datum/element/elevation/proc/post_change_turf(list/trait_sources, turf/changed) + ADD_TRAIT(changed, TRAIT_TURF_HAS_ELEVATED_OBJ(pixel_shift), trait_sources) + reset_elevation(changed) + +#define ELEVATE_TIME 0.2 SECONDS + +/** + * The core element attached to the turf itself. Do not use this directly! + * + * Causes mobs walking over a turf with this element to be pixel shifted vertically by the pixel_shift amount. + * Because of the way it's structured, it should only be added through the elevation element (without the core suffix). + * + * To explain: in the case of multiple objects with (different instances of) the element being stacked on one turf somehow, + * we only want that with the highest pixel shift value to apply it to the turf, so that the mobs standing on top of it all + * doesn't look like it's floating off the pile. + */ +/datum/element/elevation_core + element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH_ON_HOST_DESTROY + argument_hash_start_idx = 2 + ///The amount of pixel_z applied to the mob standing on the turf. + var/pixel_shift + +/datum/element/elevation_core/Attach(datum/target, pixel_shift) + . = ..() + if(!isturf(target)) + return ELEMENT_INCOMPATIBLE + if(!pixel_shift) + CRASH("attempted attaching /datum/element/elevation_core with a pixel_shift value of [isnull(pixel_shift) ? "null" : 0]") + + RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) + RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, PROC_REF(on_initialized_on)) + RegisterSignal(target, COMSIG_ATOM_EXITED, PROC_REF(on_exited)) + RegisterSignal(target, COMSIG_TURF_RESET_ELEVATION, PROC_REF(on_reset_elevation)) + + src.pixel_shift = pixel_shift + + ADD_TRAIT(target, TRAIT_ELEVATED_TURF, REF(src)) + + for(var/mob/living/living in target) + RegisterSignal(living, COMSIG_LIVING_SET_BUCKLED, PROC_REF(on_set_buckled)) + elevate_mob(living) + +/datum/element/elevation_core/Detach(datum/source) + /** + * Since the element can be removed outside of Destroy(), + * and even then, signals are passed down to the new turf, + * it's necessary to clear them here. + */ + UnregisterSignal(source, list( + COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON, + COMSIG_ATOM_ENTERED, + COMSIG_ATOM_EXITED, + COMSIG_TURF_RESET_ELEVATION, + )) + REMOVE_TRAIT(source, TRAIT_ELEVATED_TURF, REF(src)) + for(var/mob/living/living in source) + elevate_mob(living, -pixel_shift) + UnregisterSignal(living, COMSIG_LIVING_SET_BUCKLED) + return ..() + +/datum/element/elevation_core/proc/on_entered(turf/source, atom/movable/entered, atom/old_loc) + SIGNAL_HANDLER + if((isnull(old_loc) || !HAS_TRAIT_FROM(old_loc, TRAIT_ELEVATED_TURF, REF(src))) && isliving(entered)) + var/elevate_time = isturf(old_loc) && source.Adjacent(old_loc) ? ELEVATE_TIME : 0 + elevate_mob(entered, elevate_time = elevate_time) + +/datum/element/elevation_core/proc/on_initialized_on(turf/source, atom/movable/spawned) + SIGNAL_HANDLER + if(isliving(spawned)) + elevate_mob(spawned) + +/datum/element/elevation_core/proc/on_exited(turf/source, atom/movable/gone) + SIGNAL_HANDLER + if((isnull(gone.loc) || !HAS_TRAIT_FROM(gone.loc, TRAIT_ELEVATED_TURF, REF(src))) && isliving(gone)) + var/elevate_time = isturf(gone.loc) && source.Adjacent(gone.loc) ? ELEVATE_TIME : 0 + elevate_mob(gone, -pixel_shift, elevate_time) + UnregisterSignal(gone, COMSIG_LIVING_SET_BUCKLED) + +/datum/element/elevation_core/proc/elevate_mob(mob/living/target, z_shift = pixel_shift, elevate_time = ELEVATE_TIME) + animate(target, pixel_z = z_shift, time = elevate_time, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + if(target.buckled && isvehicle(target.buckled)) + animate(target.buckled, pixel_z = z_shift, time = elevate_time, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + +///Vehicles or other things the mob is buckled too also are shifted. +/datum/element/elevation_core/proc/on_set_buckled(mob/living/source, atom/movable/new_buckled) + SIGNAL_HANDLER + if(source.buckled && isvehicle(source.buckled)) + animate(source.buckled, pixel_z = -pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + if(new_buckled && isvehicle(new_buckled)) + animate(source.buckled, pixel_z = pixel_shift, time = ELEVATE_TIME, flags = ANIMATION_RELATIVE|ANIMATION_PARALLEL) + +/datum/element/elevation_core/proc/on_reset_elevation(turf/source, list/current_values) + SIGNAL_HANDLER + current_values[ELEVATION_CURRENT_PIXEL_SHIFT] = pixel_shift + +#undef ELEVATE_TIME diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 1bc70dc500f..78f28d8b81c 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -76,7 +76,7 @@ if(blocked || !istype(victim) || HAS_TRAIT(victim, TRAIT_PIERCEIMMUNE)) return FALSE - + if(victim.status_flags & GODMODE) return FALSE diff --git a/code/datums/elements/waddling.dm b/code/datums/elements/waddling.dm index 825b0c4e4cb..c51a1759768 100644 --- a/code/datums/elements/waddling.dm +++ b/code/datums/elements/waddling.dm @@ -21,7 +21,8 @@ waddling_animation(moved) /datum/element/waddling/proc/waddling_animation(atom/movable/target) - animate(target, pixel_z = 4, time = 0) - var/prev_trans = matrix(target.transform) - animate(pixel_z = 0, transform = turn(target.transform, pick(-12, 0, 12)), time=2) - animate(pixel_z = 0, transform = prev_trans, time = 0) + var/prev_pixel_z = target.pixel_z + animate(target, pixel_z = target.pixel_z + 4, time = 0) + var/prev_transform = target.transform + animate(pixel_z = prev_pixel_z, transform = turn(target.transform, pick(-12, 0, 12)), time=2) + animate(transform = prev_transform, time = 0) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 6f08275d95e..9d27e2a4cc9 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -129,7 +129,7 @@ /obj/structure/barricade/sandbags/Initialize(mapload) . = ..() AddElement(/datum/element/climbable) - AddElement(/datum/element/liquids_height, 20) //SKYRAT EDIT ADDITION + AddElement(/datum/element/elevation, pixel_shift = 12) /obj/structure/barricade/security name = "security barrier" diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index b3020c8d749..140ff025196 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -18,9 +18,22 @@ var/mattress_state = "stasis_on" var/obj/effect/overlay/vis/mattress_on +/obj/machinery/stasis/Initialize(mapload) + . = ..() + AddElement(/datum/element/elevation, pixel_shift = 6) + /obj/machinery/stasis/Destroy() . = ..() +///Just like beds, the elevation looks good while standing, but not when buckled to the bed. +/obj/machinery/stasis/post_buckle_mob(mob/living/buckled) + . = ..() + buckled.pixel_y -= 6 + +/obj/machinery/stasis/post_unbuckle_mob(mob/living/buckled) + . = ..() + buckled.pixel_y += 6 + /obj/machinery/stasis/examine(mob/user) . = ..() . += span_notice("Alt-click to [stasis_enabled ? "turn off" : "turn on"] the machine.") diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index 87d8ffb1710..09ce802c547 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -13,6 +13,7 @@ canSmoothWith = SMOOTH_GROUP_ALIEN_NEST build_stack_type = null flags_1 = NODECONSTRUCT_1 + elevation = 0 var/static/mutable_appearance/nest_overlay = mutable_appearance('icons/mob/nonhuman-player/alien.dmi', "nestoverlay", LYING_MOB_LAYER) /obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user) diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index 4b82aeb5e8e..b1d38c61a24 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -22,10 +22,14 @@ var/build_stack_type = /obj/item/stack/sheet/iron /// How many mats to drop when deconstructed var/build_stack_amount = 2 + /// Mobs standing on it are nudged up by this amount. Also used to align the person back when buckled to it after init. + var/elevation = 8 /obj/structure/bed/Initialize(mapload) . = ..() AddElement(/datum/element/soft_landing) + if(elevation) + AddElement(/datum/element/elevation, pixel_shift = elevation) register_context() /obj/structure/bed/examine(mob/user) @@ -63,6 +67,16 @@ deconstruct(disassembled = TRUE) return TRUE +/obj/structure/bed/post_buckle_mob(mob/living/buckled) + . = ..() + buckled.base_pixel_y -= elevation + buckled.pixel_y -= elevation + +/obj/structure/bed/post_unbuckle_mob(mob/living/buckled) + . = ..() + buckled.base_pixel_y += elevation + buckled.pixel_y += elevation + /// Medical beds /obj/structure/bed/medical name = "medical bed" @@ -74,6 +88,7 @@ resistance_flags = NONE build_stack_type = /obj/item/stack/sheet/mineral/titanium build_stack_amount = 1 + elevation = 0 /// The item it spawns when it's folded up. var/foldable_type @@ -117,11 +132,13 @@ balloon_alert(user, "brakes [anchored ? "applied" : "released"]") update_appearance() -/obj/structure/bed/medical/post_buckle_mob(mob/living/patient) +/obj/structure/bed/medical/post_buckle_mob(mob/living/buckled) + . = ..() set_density(TRUE) update_appearance() -/obj/structure/bed/medical/post_unbuckle_mob(mob/living/patient) +/obj/structure/bed/medical/post_unbuckle_mob(mob/living/buckled) + . = ..() set_density(FALSE) update_appearance() @@ -135,7 +152,6 @@ patient.pixel_y = patient.base_pixel_y else buckled_mobs[1].pixel_y = buckled_mobs[1].base_pixel_y - else icon_state = "[base_icon_state]_down" @@ -257,6 +273,7 @@ anchored = FALSE build_stack_type = /obj/item/stack/sheet/mineral/wood build_stack_amount = 10 + elevation = 0 var/owned = FALSE /obj/structure/bed/dogbed/ian @@ -306,6 +323,7 @@ name = "dirty mattress" desc = "An old grubby mattress. You try to not think about what could be the cause of those stains." icon_state = "dirty_mattress" + elevation = 7 /obj/structure/bed/maint/Initialize(mapload) . = ..() @@ -322,11 +340,15 @@ var/mob/living/goldilocks /obj/structure/bed/double/post_buckle_mob(mob/living/target) + . = ..() if(buckled_mobs.len > 1 && !goldilocks) // Push the second buckled mob a bit higher from the normal lying position - target.pixel_y = target.base_pixel_y + 6 + target.base_pixel_y += 12 + target.pixel_y += 12 goldilocks = target /obj/structure/bed/double/post_unbuckle_mob(mob/living/target) - target.pixel_y = target.base_pixel_y + target.body_position_pixel_y_offset + . = ..() if(target == goldilocks) + target.base_pixel_y -= 12 + target.pixel_y -= 12 goldilocks = null diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 34f09ad25e7..aa45cce3a16 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -18,7 +18,13 @@ drag_slowdown = 0 door_anim_time = 0 // no animation pass_flags_self = PASSSTRUCTURE | LETPASSTHROW - var/crate_climb_time = 20 + /// Mobs standing on it are nudged up by this amount. + var/elevation = 14 + /// The same, but when the crate is open + var/elevation_open = 14 + /// The time spent to climb this crate. + var/crate_climb_time = 2 SECONDS + /// The reference of the manifest paper attached to the cargo crate. var/obj/item/paper/fluff/jobs/cargo/manifest/manifest /// Where the Icons for lids are located. var/lid_icon = 'icons/obj/storage/crates.dmi' @@ -31,6 +37,8 @@ /obj/structure/closet/crate/Initialize(mapload) AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) //add element in closed state before parent init opens it(if it does) + if(elevation) + AddElement(/datum/element/elevation, pixel_shift = elevation) . = ..() var/static/list/crate_paint_jobs @@ -102,6 +110,11 @@ . = ..() RemoveElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) AddElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0) + if(elevation != elevation_open) + if(elevation) + RemoveElement(/datum/element/elevation, pixel_shift = elevation) + if(elevation_open) + AddElement(/datum/element/elevation, pixel_shift = elevation_open) if(!QDELETED(manifest)) playsound(src, 'sound/items/poster_ripped.ogg', 75, TRUE) manifest.forceMove(get_turf(src)) @@ -112,6 +125,11 @@ . = ..() RemoveElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0) AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) + if(elevation != elevation_open) + if(elevation_open) + RemoveElement(/datum/element/elevation, pixel_shift = elevation_open) + if(elevation) + AddElement(/datum/element/elevation, pixel_shift = elevation) /obj/structure/closet/crate/proc/tear_manifest(mob/user) to_chat(user, span_notice("You tear the manifest off of [src].")) @@ -142,6 +160,7 @@ close_sound_volume = 50 can_install_electronics = FALSE paint_jobs = null + elevation_open = 0 /obj/structure/closet/crate/maint @@ -177,6 +196,8 @@ desc = "A large cart for hauling around large amounts of laundry." icon_state = "laundry" base_icon_state = "laundry" + elevation = 14 + elevation_open = 14 /obj/structure/closet/crate/trashcart/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm index f97a86aba23..6b865b84586 100644 --- a/code/game/objects/structures/crates_lockers/crates/bins.dm +++ b/code/game/objects/structures/crates_lockers/crates/bins.dm @@ -10,6 +10,8 @@ delivery_icon = null can_install_electronics = FALSE paint_jobs = null + elevation = 17 + elevation_open = 17 /obj/structure/closet/crate/bin/LateInitialize() . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm index a89d82ea0ea..5e1873d166a 100644 --- a/code/game/objects/structures/crates_lockers/crates/critter.dm +++ b/code/game/objects/structures/crates_lockers/crates/critter.dm @@ -15,6 +15,8 @@ close_sound_volume = 50 contents_pressure_protection = 0.8 can_install_electronics = FALSE + elevation = 21 + elevation_open = 0 var/obj/item/tank/internals/emergency_oxygen/tank diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index 0f3b9c19773..073d4a936d8 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -14,6 +14,7 @@ open_sound_volume = 25 close_sound_volume = 50 can_install_electronics = FALSE + elevation = 22 // Stops people from "diving into" a crate you can't open normally divable = FALSE diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 78357a5dd4a..e482be10f2b 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -29,8 +29,6 @@ smoothing_flags = SMOOTH_BITMASK smoothing_groups = SMOOTH_GROUP_TABLES canSmoothWith = SMOOTH_GROUP_TABLES - ///TRUE if the table can be climbed on and have living mobs placed on it normally, FALSE otherwise - var/climbable = TRUE var/frame = /obj/structure/table_frame var/framestack = /obj/item/stack/rods var/glass_shard_type = /obj/item/shard @@ -46,8 +44,7 @@ buildstack = _buildstack AddElement(/datum/element/footstep_override, priority = STEP_SOUND_TABLE_PRIORITY) - if (climbable) - AddElement(/datum/element/climbable) + make_climbable() var/static/list/loc_connections = list( COMSIG_CARBON_DISARM_COLLIDE = PROC_REF(table_carbon), @@ -58,6 +55,11 @@ AddElement(/datum/element/give_turf_traits, give_turf_traits) register_context() +///Adds the element used to make the object climbable, and also the one that shift the mob buckled to it up. +/obj/structure/table/proc/make_climbable() + AddElement(/datum/element/climbable) + AddElement(/datum/element/elevation, pixel_shift = 12) + /obj/structure/table/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) . = ..() @@ -730,9 +732,8 @@ smoothing_flags = NONE smoothing_groups = null canSmoothWith = null - can_buckle = 1 + can_buckle = TRUE buckle_lying = 90 - climbable = FALSE custom_materials = list(/datum/material/silver =SHEET_MATERIAL_AMOUNT) var/mob/living/carbon/patient = null var/obj/machinery/computer/operating/computer = null @@ -756,11 +757,26 @@ UnregisterSignal(loc, COMSIG_ATOM_EXITED) return ..() +/obj/structure/table/optable/make_climbable() + AddElement(/datum/element/elevation, pixel_shift = 12) + /obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob) pushed_mob.forceMove(loc) pushed_mob.set_resting(TRUE, TRUE) visible_message(span_notice("[user] lays [pushed_mob] on [src].")) +///Align the mob with the table when buckled. +/obj/structure/bed/post_buckle_mob(mob/living/buckled) + . = ..() + buckled.base_pixel_y -= 6 + buckled.pixel_y -= 6 + +///Disalign the mob with the table when unbuckled. +/obj/structure/bed/post_unbuckle_mob(mob/living/buckled) + . = ..() + buckled.base_pixel_y += 6 + buckled.pixel_y += 6 + /// Any mob that enters our tile will be marked as a potential patient. They will be turned into a patient if they lie down. /obj/structure/table/optable/proc/mark_patient(datum/source, mob/living/carbon/potential_patient) SIGNAL_HANDLER @@ -768,7 +784,6 @@ return RegisterSignal(potential_patient, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(recheck_patient)) recheck_patient(potential_patient) // In case the mob is already lying down before they entered. - potential_patient.pixel_y = potential_patient.base_pixel_y /// Unmark the potential patient. /obj/structure/table/optable/proc/unmark_patient(datum/source, mob/living/carbon/potential_patient) @@ -778,7 +793,6 @@ if(potential_patient == patient) recheck_patient(patient) // Can just set patient to null, but doing the recheck lets us find a replacement patient. UnregisterSignal(potential_patient, COMSIG_LIVING_SET_BODY_POSITION) - potential_patient.pixel_y = potential_patient.base_pixel_y + potential_patient.body_position_pixel_y_offset /// Someone on our tile just lied down, got up, moved in, or moved out. /// potential_patient is the mob that had one of those four things change. diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index d7b463122ff..e0852b0fd39 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -20,6 +20,7 @@ init_tube_dirs() update_appearance() AddElement(/datum/element/climbable) + AddElement(/datum/element/elevation, pixel_shift = 12) /obj/structure/transit_tube/Destroy() for(var/obj/structure/transit_tube_pod/P in loc) diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index aa201292f72..4c08fdc47ba 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -151,6 +151,8 @@ can_weld_shut = FALSE cutting_tool = null paint_jobs = null + elevation = 4 //It's a small mound. + elevation_open = 0 /// will this grave give you nightmares when opened var/lead_tomb = FALSE diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index c8c8cf966ba..0b42fd23212 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -128,15 +128,15 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) holder_obj.add_overlay(balloon) playsound(holder_obj.loc, 'sound/items/fultext_deploy.ogg', vol = 50, vary = TRUE, extrarange = -3) - animate(holder_obj, pixel_z = 10, time = 2 SECONDS) - animate(pixel_z = 15, time = 1 SECONDS) - animate(pixel_z = 10, time = 1 SECONDS) - animate(pixel_z = 15, time = 1 SECONDS) - animate(pixel_z = 10, time = 1 SECONDS) + animate(holder_obj, pixel_z = 10, time = 2 SECONDS, flags = ANIMATION_RELATIVE) + animate(pixel_z = 5, time = 1 SECONDS, flags = ANIMATION_RELATIVE) + animate(pixel_z = -5, time = 1 SECONDS, flags = ANIMATION_RELATIVE) + animate(pixel_z = 5, time = 1 SECONDS, flags = ANIMATION_RELATIVE) + animate(pixel_z = -5, time = 1 SECONDS, flags = ANIMATION_RELATIVE) sleep(6 SECONDS) playsound(holder_obj.loc, 'sound/items/fultext_launch.ogg', vol = 50, vary = TRUE, extrarange = -3) - animate(holder_obj, pixel_z = 1000, time = 3 SECONDS) + animate(holder_obj, pixel_z = 1000, time = 3 SECONDS, flags = ANIMATION_RELATIVE) if(ishuman(thing)) var/mob/living/carbon/human/creature = thing @@ -157,9 +157,9 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) holder_obj.forceMove(pick(flooring_near_beacon)) - animate(holder_obj, pixel_z = 10, time = 5 SECONDS) - animate(pixel_z = 15, time = 1 SECONDS) - animate(pixel_z = 10, time = 1 SECONDS) + animate(holder_obj, pixel_z = -990, time = 5 SECONDS, flags = ANIMATION_RELATIVE) + animate(pixel_z = 5, time = 1 SECONDS, flags = ANIMATION_RELATIVE) + animate(pixel_z = -5, time = 1 SECONDS, flags = ANIMATION_RELATIVE) sleep(7 SECONDS) balloon3 = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_retract") @@ -172,7 +172,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) holder_obj.cut_overlay(balloon3) thing.set_anchored(FALSE) // An item has to be unanchored to be extracted in the first place. thing.set_density(initial(thing.density)) - animate(holder_obj, pixel_z = 0, time = 0.5 SECONDS) + animate(holder_obj, pixel_z = -10, time = 0.5 SECONDS, flags = ANIMATION_RELATIVE) sleep(0.5 SECONDS) thing.forceMove(holder_obj.loc) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index 26f3690fef1..4e31088309a 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -206,8 +206,9 @@ Difficulty: Hard COOLDOWN_START(src, scream_cooldown, scream_cooldown_time) SLEEP_CHECK_DEATH(5, src) playsound(loc, 'sound/magic/demon_dies.ogg', 600, FALSE, 10) - animate(src, pixel_z = rand(5, 15), time = 1, loop = 20) - animate(pixel_z = 0, time = 1) + var/pixel_shift = rand(5, 15) + animate(src, pixel_z = pixel_shift, time = 1, loop = 20, flags = ANIMATION_RELATIVE) + animate(pixel_z = -pixel_shift, time = 1, flags = ANIMATION_RELATIVE) for(var/mob/living/dizzy_target in get_hearers_in_view(7, src) - src) dizzy_target.set_dizzy_if_lower(12 SECONDS) to_chat(dizzy_target, span_danger("The wendigo screams loudly!")) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 0f122c104eb..de9ae632861 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -91,6 +91,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) . = ..() toner_cartridge = new(src) setup_components() + AddElement(/datum/element/elevation, pixel_shift = 8) //enough to look like your bums are on the machine. /// Simply adds the necessary components for this to function. /obj/machinery/photocopier/proc/setup_components() diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index 83c19bf9350..1985046a434 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -90,9 +90,9 @@ if(can_shoot()) ADD_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src)) playsound(src, 'sound/vehicles/rocketlaunch.ogg', 80, TRUE, 5) - animate(user, pixel_z = 300, time = 30, easing = LINEAR_EASING) + animate(user, pixel_z = 300, time = 30, flags = ANIMATION_RELATIVE, easing = LINEAR_EASING) sleep(7 SECONDS) - animate(user, pixel_z = 0, time = 5, easing = LINEAR_EASING) + animate(user, pixel_z = -300, time = 5, flags = ANIMATION_RELATIVE, easing = LINEAR_EASING) sleep(0.5 SECONDS) REMOVE_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src)) process_fire(user, user, TRUE) diff --git a/code/modules/religion/religion_structures.dm b/code/modules/religion/religion_structures.dm index ae61004b46e..1b30d021268 100644 --- a/code/modules/religion/religion_structures.dm +++ b/code/modules/religion/religion_structures.dm @@ -18,6 +18,7 @@ reflect_sect_in_icons() GLOB.chaplain_altars += src AddElement(/datum/element/climbable) + AddElement(/datum/element/elevation, pixel_shift = 12) /obj/structure/altar_of_gods/Destroy() GLOB.chaplain_altars -= src diff --git a/modular_skyrat/master_files/code/game/machinery/deployable.dm b/modular_skyrat/master_files/code/game/machinery/deployable.dm new file mode 100644 index 00000000000..f44f5d51796 --- /dev/null +++ b/modular_skyrat/master_files/code/game/machinery/deployable.dm @@ -0,0 +1,3 @@ +/obj/structure/barricade/sandbags/Initialize(mapload) + . = ..() + AddElement(/datum/element/liquids_height, 20) diff --git a/tgstation.dme b/tgstation.dme index b49261481dd..9fff3b91389 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1463,6 +1463,7 @@ #include "code\datums\elements\earhealing.dm" #include "code\datums\elements\easily_fragmented.dm" #include "code\datums\elements\effect_trail.dm" +#include "code\datums\elements\elevation.dm" #include "code\datums\elements\embed.dm" #include "code\datums\elements\empprotection.dm" #include "code\datums\elements\envenomable_casing.dm" @@ -6141,6 +6142,7 @@ #include "modular_skyrat\master_files\code\game\gamemodes\objective.dm" #include "modular_skyrat\master_files\code\game\gamemodes\dynamic\dynamic_rulesets_midround.dm" #include "modular_skyrat\master_files\code\game\gamemodes\dynamic\dynamic_rulesets_roundstart.dm" +#include "modular_skyrat\master_files\code\game\machinery\deployable.dm" #include "modular_skyrat\master_files\code\game\machinery\hologram.dm" #include "modular_skyrat\master_files\code\game\machinery\limbgrower.dm" #include "modular_skyrat\master_files\code\game\machinery\suit_storage.dm"