From 2016156d6f9efb53943b85528c64121bdefda977 Mon Sep 17 00:00:00 2001 From: Jacquerel Date: Mon, 19 Aug 2024 01:01:41 +0100 Subject: [PATCH] Shift certain flying mob positions upon death (#85942) ## About The Pull Request Chasing more side effects of offsetting mobs and giving them shadows. ![dreamseeker_dd0UwOHLV6](https://github.com/user-attachments/assets/1f619084-77f4-41d8-9d0c-eacd63bbf58c) Some mobs are "flying" while they are alive, but not while they are dead. Some mobs (like Watchers) offset their death sprites in the dmi to make it look like they have dropped to the ground, others do not bother. For the ones which don't, we want to shift them down ourselves so it doesn't look like the corpse is levitating. I'm willing to accept better suggestions for how to implement this but this seemed like the most obvious. ## Why It's Good For The Game No more levitating corpses ## Changelog :cl: fix: Carp, bat, parrot, and dragon corpses no longer float in the air. /:cl: --- code/datums/components/drop_shadow.dm | 33 ++++++++++++++++--- code/modules/mob/living/basic/basic.dm | 19 +++++++++++ .../living/basic/lavaland/watcher/watcher.dm | 1 + .../mob/living/basic/pets/parrot/_parrot.dm | 1 + .../mob/living/basic/space_fauna/carp/carp.dm | 1 + .../space_fauna/space_dragon/space_dragon.dm | 1 + .../mob/living/basic/vermin/space_bat.dm | 3 ++ 7 files changed, 54 insertions(+), 5 deletions(-) diff --git a/code/datums/components/drop_shadow.dm b/code/datums/components/drop_shadow.dm index f57140549bb..961f2760c94 100644 --- a/code/datums/components/drop_shadow.dm +++ b/code/datums/components/drop_shadow.dm @@ -7,14 +7,17 @@ var/shadow_offset /// Any temporary extra offsets we are tracking var/additional_offset = 0 + /// Additional offset to apply while mob is dead + var/death_offset /// Timer to make sure var/unhide_shadow_timer -/datum/component/drop_shadow/Initialize(icon = 'icons/mob/mob_shadows.dmi', icon_state = SHADOW_MEDIUM, shadow_offset_x = 0, shadow_offset_y = 0) +/datum/component/drop_shadow/Initialize(icon = 'icons/mob/mob_shadows.dmi', icon_state = SHADOW_MEDIUM, shadow_offset_x = 0, shadow_offset_y = 0, death_offset = 0) . = ..() if (!ismovable(parent)) // Only being used for mobs at the moment but it seems reasonably likely that we'll want to put it on some effect some time return COMPONENT_INCOMPATIBLE + src.death_offset = death_offset shadow_offset = shadow_offset_y var/atom/movable/movable_parent = parent @@ -28,7 +31,7 @@ shadow.pixel_x = shadow_offset_x - movable_parent.pixel_x update_shadow_position() -/datum/component/drop_shadow/InheritComponent(icon = 'icons/mob/mob_shadows.dmi', icon_state = SHADOW_MEDIUM, shadow_offset_x = 0, shadow_offset_y = 0) +/datum/component/drop_shadow/InheritComponent(icon = 'icons/mob/mob_shadows.dmi', icon_state = SHADOW_MEDIUM, shadow_offset_x = 0, shadow_offset_y = 0, death_offset = 0) var/changed_appearance = FALSE if (shadow.pixel_x != shadow_offset_x) @@ -43,8 +46,21 @@ shadow.icon_state = icon_state changed_appearance = TRUE + var/changed_offset = FALSE + + if (death_offset != src.death_offset) + if (src.death_offset == 0) + RegisterSignal(parent, COMSIG_MOB_STATCHANGE, PROC_REF(update_shadow_position)) + else if (death_offset == 0) + UnregisterSignal(parent, COMSIG_MOB_STATCHANGE, PROC_REF(update_shadow_position)) + src.death_offset = death_offset + changed_offset = TRUE + if (shadow_offset_y != shadow_offset) shadow_offset = shadow_offset_y + changed_offset = TRUE + + if (changed_offset) update_shadow_position() // Calling this will also update the overlays so we can return here and safely apply any of the above changes too return @@ -62,6 +78,8 @@ RegisterSignal(parent, COMSIG_LIVING_POST_UPDATE_TRANSFORM, PROC_REF(on_transform_updated)) RegisterSignal(parent, COMSIG_MOB_BUCKLED, PROC_REF(hide_shadow)) RegisterSignal(parent, COMSIG_MOB_UNBUCKLED, PROC_REF(show_shadow)) + if (death_offset != 0) + RegisterSignal(parent, COMSIG_MOB_STATCHANGE, PROC_REF(update_shadow_position)) if (!HAS_TRAIT(parent, TRAIT_SHADOWLESS)) var/atom/atom_parent = parent @@ -76,6 +94,7 @@ COMSIG_ATOM_STOPPED_ORBITING, COMSIG_LIVING_POST_UPDATE_TRANSFORM, COMSIG_MOB_BUCKLED, + COMSIG_MOB_STATCHANGE, COMSIG_MOB_UNBUCKLED, SIGNAL_ADDTRAIT(TRAIT_SHADOWLESS), SIGNAL_REMOVETRAIT(TRAIT_SHADOWLESS), @@ -83,14 +102,18 @@ /// Repositions the shadow to try and stay under our mob should be at under current conditions /datum/component/drop_shadow/proc/update_shadow_position() - var/lying_offset = 0 + SIGNAL_HANDLER + + var/living_offset = 0 if (isliving(parent)) var/mob/living/living_parent = parent if (living_parent.rotate_on_lying && living_parent.body_position != STANDING_UP) - lying_offset = living_parent.body_position_pixel_y_offset + living_offset -= living_parent.body_position_pixel_y_offset + if (death_offset != 0 && living_parent.stat == DEAD) + living_offset += death_offset shadow.transform = matrix() * living_parent.current_size - shadow.pixel_z = -DEPTH_OFFSET - additional_offset - lying_offset + shadow_offset + shadow.pixel_z = -DEPTH_OFFSET - additional_offset + living_offset + shadow_offset if (!HAS_TRAIT(parent, TRAIT_SHADOWLESS)) var/atom/atom_parent = parent diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index 582af27c316..7e5b9ca0b86 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -97,6 +97,8 @@ var/unsuitable_cold_damage = 1 ///This damage is taken when the body temp is too hot. Set both this and unsuitable_cold_damage to 0 to avoid adding the body_temp_sensitive element. var/unsuitable_heat_damage = 1 + ///Amount to increment our vertical position by when dead + var/death_offset_y = 0 /mob/living/basic/Initialize(mapload) . = ..() @@ -123,6 +125,18 @@ apply_temperature_requirements(mapload) apply_target_randomisation() +/mob/living/basic/create_shadow() + if (shadow_type == SHADOW_NONE) + qdel(GetComponent(/datum/component/drop_shadow)) + return + + AddComponent(/datum/component/drop_shadow, \ + icon_state = shadow_type, \ + shadow_offset_x = shadow_offset_x, \ + shadow_offset_y = shadow_offset_y, \ + death_offset = -death_offset_y, \ + ) + /mob/living/basic/proc/on_ssair_init(datum/source) SIGNAL_HANDLER UnregisterSignal(SSair, COMSIG_SUBSYSTEM_POST_INITIALIZE) @@ -189,6 +203,7 @@ if(!(basic_mob_flags & REMAIN_DENSE_WHILE_DEAD)) ADD_TRAIT(src, TRAIT_UNDENSE, BASIC_MOB_DEATH_TRAIT) SEND_SIGNAL(src, COMSIG_BASICMOB_LOOK_DEAD) + pixel_z = base_pixel_z + death_offset_y /mob/living/basic/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) . = ..() @@ -204,6 +219,8 @@ if(!(basic_mob_flags & REMAIN_DENSE_WHILE_DEAD)) REMOVE_TRAIT(src, TRAIT_UNDENSE, BASIC_MOB_DEATH_TRAIT) SEND_SIGNAL(src, COMSIG_BASICMOB_LOOK_ALIVE) + if (death_offset_y != 0) + pixel_z = base_pixel_z /mob/living/basic/update_sight() lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue) @@ -247,6 +264,8 @@ if(NAMEOF(src, speed)) datum_flags |= DF_VAR_EDITED set_varspeed(vval) + if(NAMEOF(src, death_offset_y)) + create_shadow() /mob/living/basic/proc/set_varspeed(var_value) speed = var_value diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher.dm index d5790cfd06f..49cd37fd7ea 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher.dm @@ -23,6 +23,7 @@ /obj/item/stack/sheet/sinew = 2, ) shadow_type = SHADOW_LARGE + /// How often can we shoot? var/ranged_cooldown = 3 SECONDS /// What kind of beams we got? diff --git a/code/modules/mob/living/basic/pets/parrot/_parrot.dm b/code/modules/mob/living/basic/pets/parrot/_parrot.dm index c23481d85a7..09bf4ead787 100644 --- a/code/modules/mob/living/basic/pets/parrot/_parrot.dm +++ b/code/modules/mob/living/basic/pets/parrot/_parrot.dm @@ -36,6 +36,7 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( friendly_verb_simple = "groom" mob_size = MOB_SIZE_SMALL gold_core_spawnable = FRIENDLY_SPAWN + death_offset_y = -9 ai_controller = /datum/ai_controller/basic_controller/parrot diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm index 816bb7cd838..bf1abd371aa 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -43,6 +43,7 @@ habitable_atmos = null minimum_survivable_temperature = 0 maximum_survivable_temperature = 1500 + death_offset_y = -10 /// Cytology cells you can swab from this creature var/cell_line = CELL_LINE_TABLE_CARP diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index f94f7aeff47..a8dcf3dc237 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -51,6 +51,7 @@ lighting_cutoff_green = 15 lighting_cutoff_blue = 34 shadow_type = SHADOW_LARGE + death_offset_y = -4 /// The colour of the space dragon var/chosen_colour diff --git a/code/modules/mob/living/basic/vermin/space_bat.dm b/code/modules/mob/living/basic/vermin/space_bat.dm index 53f367f4487..a0f5f1759dd 100644 --- a/code/modules/mob/living/basic/vermin/space_bat.dm +++ b/code/modules/mob/living/basic/vermin/space_bat.dm @@ -31,6 +31,9 @@ obj_damage = 0 unsuitable_atmos_damage = 0 + shadow_type = SHADOW_SMALL + death_offset_y = -3 + ai_controller = /datum/ai_controller/basic_controller/space_bat /mob/living/basic/bat/Initialize(mapload)