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)