diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 4fb5a00adc1..1bd3a191f76 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -251,3 +251,4 @@ GLOBAL_LIST_INIT(announcer_keys, list( #define SFX_PLASTIC_BOTTLE_LIQUID_SLOSH "plastic_bottle_liquid_slosh" #define SFX_DEFAULT_LIQUID_SLOSH "default_liquid_slosh" #define SFX_PLATE_ARMOR_RUSTLE "plate_armor_rustle" +#define SFX_PIG_OINK "pig_oink" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 8746e198d08..ae2dec14d16 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -139,7 +139,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NOFIRE "nonflammable" #define TRAIT_NOFIRE_SPREAD "no_fire_spreading" /// Prevents plasmamen from self-igniting if only their helmet is missing -#define TRAIT_NOSELFIGNITION_HEAD_ONLY "no_selfignition_head_only" +#define TRAIT_HEAD_ATMOS_SEALED "no_selfignition_head_only" #define TRAIT_NOGUNS "no_guns" ///Can toss a guns like a badass, causing additional damage/effect to their enemies #define TRAIT_TOSS_GUN_HARD "toss_gun_hard" @@ -288,6 +288,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Applied into wounds when they're scanned with the wound analyzer, halves time to treat them manually. #define TRAIT_WOUND_SCANNED "wound_scanned" +/// Owner will ignore any fire protection when calculating fire damage +#define TRAIT_IGNORE_FIRE_PROTECTION "ignore_fire_protection" + #define TRAIT_NODEATH "nodeath" #define TRAIT_NOHARDCRIT "nohardcrit" #define TRAIT_NOSOFTCRIT "nosoftcrit" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 3aa4b4f1926..8c2b86e2cbc 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -371,7 +371,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NOHUNGER" = TRAIT_NOHUNGER, "TRAIT_NOLIMBDISABLE" = TRAIT_NOLIMBDISABLE, "TRAIT_NOMOBSWAP" = TRAIT_NOMOBSWAP, - "TRAIT_NOSELFIGNITION_HEAD_ONLY" = TRAIT_NOSELFIGNITION_HEAD_ONLY, + "TRAIT_HEAD_ATMOS_SEALED" = TRAIT_HEAD_ATMOS_SEALED, "TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT, "TRAIT_NO_AUGMENTS" = TRAIT_NO_AUGMENTS, "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, @@ -567,6 +567,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPEECH_BOOSTER" = TRAIT_SPEECH_BOOSTER, "TRAIT_MINING_PARRYING" = TRAIT_MINING_PARRYING, "TRAIT_ILLUSORY_EFFECT" = TRAIT_ILLUSORY_EFFECT, + "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION, ), /obj/item = list( "TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 691db719f54..fd33957efe9 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -325,6 +325,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_XRAY_HEARING" = TRAIT_XRAY_HEARING, "TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION, "TRAIT_MINING_PARRYING" = TRAIT_MINING_PARRYING, + "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION, ), /obj/item = list( "TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING, diff --git a/code/datums/actions/mobs/lava_swoop.dm b/code/datums/actions/mobs/lava_swoop.dm index 2b07734b4a8..428c9756656 100644 --- a/code/datums/actions/mobs/lava_swoop.dm +++ b/code/datums/actions/mobs/lava_swoop.dm @@ -144,11 +144,17 @@ for(var/turf/T in walled) drakewalls += new /obj/effect/temp_visual/drakewall(T) // no people with lava immunity can just run away from the attack for free var/list/indestructible_turfs = list() - for(var/turf/T in RANGE_TURFS(2, center)) - if(isindestructiblefloor(T)) + + for(var/turf/turf_target as anything in RANGE_TURFS(2, center)) + if(isindestructiblefloor(turf_target)) + continue + if(isindestructiblewall(turf_target)) + indestructible_turfs += turf_target continue - if(isindestructiblewall(T)) - indestructible_turfs += T + if(ismineralturf(turf_target)) + var/turf/closed/mineral/mineral_turf = turf_target + mineral_turf.gets_drilled(owner) + SLEEP_CHECK_DEATH(1 SECONDS, owner) // give them a bit of time to realize what attack is actually happening var/list/turfs = RANGE_TURFS(2, center) diff --git a/code/datums/components/self_ignition.dm b/code/datums/components/self_ignition.dm new file mode 100644 index 00000000000..6736a746355 --- /dev/null +++ b/code/datums/components/self_ignition.dm @@ -0,0 +1,57 @@ +/// Component used by plasmeme limbs. Ignites the owner and prevents fire armor from working if they're exposed to oxygen +/datum/component/self_ignition + /// How many fire stacks do we apply per second? + /// Default value is 0.25 / 6 (default amount of limbs) + var/fire_stacks_per_second = 0.0416 + /// How many fire stacks are removed when we're exposed to hypernoblium + /// Default value is 10 / 6 (default amount of limbs) + var/fire_stacks_loss = 1.66 + +/datum/component/self_ignition/Initialize(fire_stacks_per_second = 0.0416, fire_stacks_loss = 1.66) + . = ..() + if(!isbodypart(parent)) + return COMPONENT_INCOMPATIBLE + src.fire_stacks_per_second = fire_stacks_per_second + src.fire_stacks_loss = fire_stacks_loss + +/datum/component/self_ignition/RegisterWithParent() + RegisterSignal(parent, COMSIG_BODYPART_ATTACHED, PROC_REF(on_attached)) + RegisterSignal(parent, COMSIG_BODYPART_REMOVED, PROC_REF(on_detached)) + +/datum/component/self_ignition/proc/on_attached(datum/source, mob/living/carbon/human/new_owner) + SIGNAL_HANDLER + RegisterSignal(new_owner, COMSIG_LIVING_LIFE, PROC_REF(on_life)) + +/datum/component/self_ignition/proc/on_detached(datum/source, mob/living/carbon/human/old_owner) + SIGNAL_HANDLER + UnregisterSignal(old_owner, COMSIG_LIVING_LIFE) + REMOVE_TRAIT(old_owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent)) + +/datum/component/self_ignition/proc/on_life(mob/living/carbon/human/owner, seconds_per_tick, times_fired) + SIGNAL_HANDLER + + if (owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + if (!owner.on_fire) + REMOVE_TRAIT(owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent)) + return + + var/datum/gas_mixture/environment = owner.loc.return_air() + if (!environment?.total_moles()) + return + + if(environment.gases[/datum/gas/hypernoblium] && environment.gases[/datum/gas/hypernoblium][MOLES] >= 5) + if(owner.on_fire && owner.fire_stacks > 0) + owner.adjust_fire_stacks(-fire_stacks_loss * seconds_per_tick) + return + + if (HAS_TRAIT(owner, TRAIT_NOFIRE)) + return + + ADD_TRAIT(owner, TRAIT_IGNORE_FIRE_PROTECTION, REF(parent)) + + if(!environment.gases[/datum/gas/oxygen] || environment.gases[/datum/gas/oxygen][MOLES] < 1) //Same threshhold that extinguishes fire + return + + owner.adjust_fire_stacks(fire_stacks_per_second * seconds_per_tick) + if(owner.ignite_mob()) + owner.visible_message(span_danger("[owner]'s body reacts with the atmosphere and bursts into flames!"), span_userdanger("Your body reacts with the atmosphere and bursts into flame!")) diff --git a/code/datums/elements/pet_bonus.dm b/code/datums/elements/pet_bonus.dm index a802c363f44..d809b9ef4bd 100644 --- a/code/datums/elements/pet_bonus.dm +++ b/code/datums/elements/pet_bonus.dm @@ -10,17 +10,14 @@ ///string key of the emote to do when pet. var/emote_name - ///optional cute message to send when you pet your pet! - var/emote_message ///actual moodlet given, defaults to the pet animal one var/moodlet -/datum/element/pet_bonus/Attach(datum/target, emote_message, moodlet = /datum/mood_event/pet_animal) +/datum/element/pet_bonus/Attach(datum/target, emote_name, moodlet = /datum/mood_event/pet_animal) . = ..() if(!isliving(target)) return ELEMENT_INCOMPATIBLE - src.emote_message = emote_message src.emote_name = emote_name src.moodlet = moodlet RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand)) @@ -37,8 +34,6 @@ new /obj/effect/temp_visual/heart(pet.loc) SEND_SIGNAL(pet, COMSIG_ANIMAL_PET, petter, modifiers) - if(emote_message && prob(33)) - pet.manual_emote(emote_message) - if(emote_name) + if(emote_name && prob(33)) INVOKE_ASYNC(pet, TYPE_PROC_REF(/mob, emote), emote_name) petter.add_mood_event("petting_bonus", moodlet, pet) diff --git a/code/game/machinery/nebula_shielding.dm b/code/game/machinery/nebula_shielding.dm index 10306177ebf..6473c1b1bfc 100644 --- a/code/game/machinery/nebula_shielding.dm +++ b/code/game/machinery/nebula_shielding.dm @@ -140,7 +140,7 @@ /obj/item/paper/fluff/radiation_nebula name = "radioactive nebula shielding" default_raw_text = {"EXTREME IMPORTANCE!!!!
- Set up these radioactive nebula shielding units before the gravity generators native shielding is overwhelmed!
+ Set up these radioactive nebula shielding units before the gravity generator's native shielding is overwhelmed!
Shielding units passively generate tritium, so make sure to properly ventilate/isolate the area before setting up a shielding unit! More circuit boards can be ordered through cargo. Consider setting up auxillary shielding units in-case of destruction, power loss or sabotage. "} @@ -149,6 +149,6 @@ /obj/item/paper/fluff/radiation_nebula_virologist name = "radioactive resonance" default_raw_text = {"EXTREME IMPORTANCE!!!!
- During routine bloodscreening on employees working in the nebula, we found no traces of the sympton called 'Radioactive Resonance'.
- Something inside the nebula is interfering with it, be wary of a more shallow viral genepool. + During routine blood screening on employees working within the nebula, we have found no traces of the symptom called 'Radioactive Resonance'.
+ Something inside the nebula is interfering with it; be wary of a more shallow viral genepool. "} diff --git a/code/game/sound.dm b/code/game/sound.dm index ab00fc4d6e0..f77a2aebf35 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -541,7 +541,7 @@ 'sound/mobs/humanoids/human/snore/snore_male1.ogg' = 20, 'sound/mobs/humanoids/human/snore/snore_male2.ogg' = 20, 'sound/mobs/humanoids/human/snore/snore_male3.ogg' = 20, - 'sound/mobs/humanoids/human/snore/snore_male3.ogg' = 20, + 'sound/mobs/humanoids/human/snore/snore_male4.ogg' = 20, 'sound/mobs/humanoids/human/snore/snore_male5.ogg' = 20, 'sound/mobs/humanoids/human/snore/snore_mimimi2.ogg' = 1, )) @@ -580,4 +580,9 @@ 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle4.ogg' = 23, 'sound/items/handling/armor_rustle/plate_armor/plate_armor_rustle5.ogg' = 23, )) + if(SFX_PIG_OINK) + soundin = pick( + 'sound/mobs/non-humanoids/pig/pig1.ogg', + 'sound/mobs/non-humanoids/pig/pig2.ogg', + ) return soundin diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 88767b84b66..3de75657d33 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -9,11 +9,10 @@ icon_state = "plasmaman_suit" inhand_icon_state = "plasmaman_suit" fishing_modifier = 0 - var/next_extinguish = 0 + COOLDOWN_DECLARE(extinguish_timer) var/extinguish_cooldown = 100 var/extinguishes_left = 10 - /datum/armor/eva_plasmaman bio = 100 fire = 100 @@ -23,21 +22,52 @@ . = ..() . += span_notice("There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charge\s left in this suit.") +/obj/item/clothing/suit/space/eva/plasmaman/equipped(mob/living/user, slot) + . = ..() + if (slot & ITEM_SLOT_OCLOTHING) + RegisterSignals(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)), PROC_REF(check_fire_state)) + check_fire_state() + +/obj/item/clothing/suit/space/eva/plasmaman/dropped(mob/living/user) + . = ..() + UnregisterSignal(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED))) + +/obj/item/clothing/suit/space/eva/plasmaman/proc/check_fire_state(datum/source) + SIGNAL_HANDLER + + if (!ishuman(loc)) + return + + // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown + // This is why we're ignoring source and instead checking by loc + var/mob/living/carbon/human/owner = loc + if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + return -/obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) + if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer)) return - if(H.fire_stacks > 0) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message(span_warning("[H]'s suit automatically extinguishes [H.p_them()]!"),span_warning("Your suit automatically extinguishes you.")) - H.extinguish_mob() - new /obj/effect/particle_effect/water(get_turf(H)) + extinguishes_left -= 1 + COOLDOWN_START(src, extinguish_timer, extinguish_cooldown) + // Check if our (possibly other) wearer is on fire once the cooldown ends + addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown) + owner.visible_message(span_warning("[owner]'s suit automatically extinguishes [owner.p_them()]!"), span_warning("Your suit automatically extinguishes you.")) + owner.extinguish_mob() + new /obj/effect/particle_effect/water(get_turf(owner)) + +/obj/item/clothing/suit/space/eva/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if (!istype(tool, /obj/item/extinguisher_refill)) + return + if (extinguishes_left == 5) + to_chat(user, span_notice("The inbuilt extinguisher is full.")) + return ITEM_INTERACT_BLOCKING + + extinguishes_left = 5 + to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge.")) + check_fire_state() + qdel(tool) + return ITEM_INTERACT_SUCCESS //I just want the light feature of helmets /obj/item/clothing/head/helmet/space/plasmaman diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm index ee70fbb3d6a..1d2166653ae 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm @@ -11,7 +11,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS can_adjust = FALSE strip_delay = 80 - var/next_extinguish = 0 + COOLDOWN_DECLARE(extinguish_timer) var/extinguish_cooldown = 100 var/extinguishes_left = 5 @@ -22,31 +22,54 @@ /obj/item/clothing/under/plasmaman/examine(mob/user) . = ..() - . += span_notice("There are [extinguishes_left] extinguisher charges left in this suit.") + . += span_notice("There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charges left in this suit.") -/obj/item/clothing/under/plasmaman/proc/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) +/obj/item/clothing/under/plasmaman/equipped(mob/living/user, slot) + . = ..() + if (slot & ITEM_SLOT_ICLOTHING) + RegisterSignals(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED)), PROC_REF(check_fire_state)) + check_fire_state() + +/obj/item/clothing/under/plasmaman/dropped(mob/living/user) + . = ..() + UnregisterSignal(user, list(COMSIG_MOB_EQUIPPED_ITEM, COMSIG_LIVING_IGNITED, SIGNAL_ADDTRAIT(TRAIT_HEAD_ATMOS_SEALED))) + +/obj/item/clothing/under/plasmaman/proc/check_fire_state(datum/source) + SIGNAL_HANDLER + + if (!ishuman(loc)) + return + + // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown + // This is why we're ignoring source and instead checking by loc + var/mob/living/carbon/human/owner = loc + if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + return + + if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer)) return - if(H.on_fire) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message(span_warning("[H]'s suit automatically extinguishes [H.p_them()]!"),span_warning("Your suit automatically extinguishes you.")) - H.extinguish_mob() - new /obj/effect/particle_effect/water(get_turf(H)) - -/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) - ..() - if (istype(E, /obj/item/extinguisher_refill)) - if (extinguishes_left == 5) - to_chat(user, span_notice("The inbuilt extinguisher is full.")) - else - extinguishes_left = 5 - to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge.")) - qdel(E) + extinguishes_left -= 1 + COOLDOWN_START(src, extinguish_timer, extinguish_cooldown) + // Check if our (possibly other) wearer is on fire once the cooldown ends + addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown) + owner.visible_message(span_warning("[owner]'s suit automatically extinguishes [owner.p_them()]!"), span_warning("Your suit automatically extinguishes you.")) + owner.extinguish_mob() + new /obj/effect/particle_effect/water(get_turf(owner)) + +/obj/item/clothing/under/plasmaman/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if (!istype(tool, /obj/item/extinguisher_refill)) + return + + if (extinguishes_left == 5) + to_chat(user, span_notice("The inbuilt extinguisher is full.")) + return ITEM_INTERACT_BLOCKING + + extinguishes_left = 5 + to_chat(user, span_notice("You refill the suit's built-in extinguisher, using up the cartridge.")) + check_fire_state() + qdel(tool) + return ITEM_INTERACT_SUCCESS /obj/item/extinguisher_refill name = "envirosuit extinguisher cartridge" @@ -54,7 +77,6 @@ icon_state = "plasmarefill" icon = 'icons/obj/canisters.dmi' - /obj/item/clothing/under/plasmaman/cargo name = "cargo plasma envirosuit" desc = "A joint envirosuit used by plasmamen quartermasters and cargo techs alike, due to the logistical problems of differenciating the two with the length of their pant legs." @@ -134,20 +156,27 @@ sensor_mode = SENSOR_COORDS random_sensor = FALSE -/obj/item/clothing/under/plasmaman/clown/Extinguish(mob/living/carbon/human/H) - if(!istype(H)) +/obj/item/clothing/under/plasmaman/clown/check_fire_state(datum/source, datum/status_effect/fire_handler/status_effect) + if (!ishuman(loc)) + return + + // This is weird but basically we're calling this proc once the cooldown ends in case our wearer gets set on fire again during said cooldown + // This is why we're ignoring source and instead checking by loc + var/mob/living/carbon/human/owner = loc + if (!owner.on_fire || !owner.is_atmos_sealed(additional_flags = PLASMAMAN_PREVENT_IGNITION, check_hands = TRUE, ignore_chest_pressureprot = TRUE)) + return + + if (!extinguishes_left || !COOLDOWN_FINISHED(src, extinguish_timer)) return - if(H.on_fire) - if(extinguishes_left) - if(next_extinguish > world.time) - return - next_extinguish = world.time + extinguish_cooldown - extinguishes_left-- - H.visible_message(span_warning("[H]'s suit spews space lube everywhere!"),span_warning("Your suit spews space lube everywhere!")) - H.extinguish_mob() - var/datum/effect_system/fluid_spread/foam/foam = new - var/datum/reagents/foamreagent = new /datum/reagents(15) - foamreagent.add_reagent(/datum/reagent/lube, 15) - foam.set_up(4, holder = src, location = H.loc, carry = foamreagent) - foam.start() //Truly terrifying. + extinguishes_left -= 1 + COOLDOWN_START(src, extinguish_timer, extinguish_cooldown) + // Check if our (possibly other) wearer is on fire once the cooldown ends + addtimer(CALLBACK(src, PROC_REF(check_fire_state)), extinguish_cooldown) + owner.visible_message(span_warning("[owner]'s suit spews space lube everywhere!"), span_warning("Your suit spews space lube everywhere!")) + owner.extinguish_mob() + var/datum/effect_system/fluid_spread/foam/foam = new + var/datum/reagents/foamreagent = new /datum/reagents(15) + foamreagent.add_reagent(/datum/reagent/lube, 15) + foam.set_up(4, holder = src, location = get_turf(owner), carry = foamreagent) + foam.start() //Truly terrifying. diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chick.dm b/code/modules/mob/living/basic/farm_animals/chicken/chick.dm index 9e4af384aee..7ddf86b0cfb 100644 --- a/code/modules/mob/living/basic/farm_animals/chicken/chick.dm +++ b/code/modules/mob/living/basic/farm_animals/chicken/chick.dm @@ -33,6 +33,18 @@ /// What we grow into. var/grow_as = /mob/living/basic/chicken +/datum/emote/chick + mob_type_allowed_typecache = /mob/living/basic/chick + mob_type_blacklist_typecache = list() + +/datum/emote/chick/chirp + key = "chirp" + key_third_person = "chirps" + message = "chirps!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/chicken/chick_peep.ogg' + /mob/living/basic/chick/Initialize(mapload) . = ..() pixel_x = base_pixel_x + rand(-6, 6) @@ -40,7 +52,7 @@ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "chirps!") + AddElement(/datum/element/pet_bonus, "chirp") AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) diff --git a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm index 9508f8fae3b..4f83608b9d6 100644 --- a/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm +++ b/code/modules/mob/living/basic/farm_animals/chicken/chicken.dm @@ -38,12 +38,24 @@ GLOBAL_VAR_INIT(chicken_count, 0) ///boolean deciding whether eggs laid by this chicken can hatch into chicks var/fertile = TRUE +/datum/emote/chicken + mob_type_allowed_typecache = /mob/living/basic/chicken + mob_type_blacklist_typecache = list() + +/datum/emote/chicken/cluck + key = "cluck" + key_third_person = "clucks" + message = "clucks happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/chicken/bagawk.ogg' + /mob/living/basic/chicken/Initialize(mapload) . = ..() GLOB.chicken_count++ ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "clucks happily!") + AddElement(/datum/element/pet_bonus, "cluck") AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/swabable, CELL_LINE_TABLE_CHICKEN, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) AddElement(/datum/element/animal_variety, "chicken", pick("brown", "black", "white"), modify_pixels = TRUE) diff --git a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm index fadac576ea5..5c771e72bad 100644 --- a/code/modules/mob/living/basic/farm_animals/cow/_cow.dm +++ b/code/modules/mob/living/basic/farm_animals/cow/_cow.dm @@ -36,13 +36,25 @@ /// What kind of juice do we produce? var/milked_reagent = /datum/reagent/consumable/milk +/datum/emote/cow + mob_type_allowed_typecache = /mob/living/basic/cow + mob_type_blacklist_typecache = list() + +/datum/emote/cow/moo + key = "moo" + key_third_person = "moos" + message = "moos happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/cow/cow.ogg' + /mob/living/basic/cow/Initialize(mapload) AddComponent(/datum/component/tippable, \ tip_time = 0.5 SECONDS, \ untip_time = 0.5 SECONDS, \ self_right_time = rand(25 SECONDS, 50 SECONDS), \ post_tipped_callback = CALLBACK(src, PROC_REF(after_cow_tipped))) - AddElement(/datum/element/pet_bonus, "moos happily!") + AddElement(/datum/element/pet_bonus, "moo") AddElement(/datum/element/swabable, CELL_LINE_TABLE_COW, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) setup_udder() setup_eating() diff --git a/code/modules/mob/living/basic/farm_animals/pig.dm b/code/modules/mob/living/basic/farm_animals/pig.dm index d0fbb5a8247..c3cfc57ac05 100644 --- a/code/modules/mob/living/basic/farm_animals/pig.dm +++ b/code/modules/mob/living/basic/farm_animals/pig.dm @@ -28,9 +28,20 @@ blood_volume = BLOOD_VOLUME_NORMAL ai_controller = /datum/ai_controller/basic_controller/pig +/datum/emote/pig + mob_type_allowed_typecache = /mob/living/basic/pig + mob_type_blacklist_typecache = list() + +/datum/emote/pig/oink + key = "oink" + key_third_person = "oinks" + message = "oinks!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = SFX_PIG_OINK /mob/living/basic/pig/Initialize(mapload) . = ..() - AddElement(/datum/element/pet_bonus, "oinks!") + AddElement(/datum/element/pet_bonus, "oink") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) make_tameable() diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm index 29672e032c8..a39fd328f11 100644 --- a/code/modules/mob/living/basic/farm_animals/pony.dm +++ b/code/modules/mob/living/basic/farm_animals/pony.dm @@ -33,11 +33,23 @@ /// Greyscale color config; 1st color is body, 2nd is mane var/list/ponycolors = list("#cc8c5d", "#cc8c5d") +/datum/emote/pony + mob_type_allowed_typecache = /mob/living/basic/pony + mob_type_blacklist_typecache = list() + +/datum/emote/pony/whicker + key = "whicker" + key_third_person = "whickers" + message = "whickers." + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/pony/snort.ogg' + /mob/living/basic/pony/Initialize(mapload) . = ..() apply_colour() - AddElement(/datum/element/pet_bonus, "whickers.") + AddElement(/datum/element/pet_bonus, "whicker") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling) diff --git a/code/modules/mob/living/basic/farm_animals/rabbit.dm b/code/modules/mob/living/basic/farm_animals/rabbit.dm index dec48ea8be4..c667ac311cd 100644 --- a/code/modules/mob/living/basic/farm_animals/rabbit.dm +++ b/code/modules/mob/living/basic/farm_animals/rabbit.dm @@ -39,10 +39,20 @@ /// passed to animal_varity as the prefix icon. var/icon_prefix = "rabbit" +/datum/emote/rabbit + mob_type_allowed_typecache = /mob/living/basic/rabbit + mob_type_blacklist_typecache = list() + +/datum/emote/rabbit + key = "hop" + key_third_person = "hops" + message = "hops around happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/rabbit/Initialize(mapload) . = ..() AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "hops around happily!") + AddElement(/datum/element/pet_bonus, "hop") AddElement(/datum/element/animal_variety, icon_prefix, pick("brown", "black", "white"), TRUE) if(prob(20)) // bunny name = "bunny" diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index b4de3d2321f..625dc4af907 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -157,6 +157,17 @@ /// Were we tamed? If yes, tame the mob we become when we grow up too. var/was_tamed = FALSE +/datum/emote/lobstrosity_juvenile + mob_type_allowed_typecache = /mob/living/basic/mining/lobstrosity/juvenile + mob_type_blacklist_typecache = list() + +/datum/emote/lobstrosity_juvenile/chitter + key = "chitter" + key_third_person = "chitters" + message = "chitters pleasantly!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + sound = 'sound/mobs/non-humanoids/insect/chitter.ogg' + /mob/living/basic/mining/lobstrosity/juvenile/Initialize(mapload) . = ..() var/growth_step = 1000/(7 MINUTES) //It should take 7-ish minutes if you keep the happiness above 40% and at most 12 @@ -203,7 +214,7 @@ . = ..() was_tamed = TRUE // They are more pettable I guess - AddElement(/datum/element/pet_bonus, "chitters pleasantly!") + AddElement(/datum/element/pet_bonus, "chitter") REMOVE_TRAIT(src, TRAIT_MOB_HIDE_HAPPINESS, INNATE_TRAIT) /mob/living/basic/mining/lobstrosity/juvenile/proc/ready_to_grow() diff --git a/code/modules/mob/living/basic/pets/cat/cat.dm b/code/modules/mob/living/basic/pets/cat/cat.dm index fe652495965..68821731ee4 100644 --- a/code/modules/mob/living/basic/pets/cat/cat.dm +++ b/code/modules/mob/living/basic/pets/cat/cat.dm @@ -86,7 +86,7 @@ AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state) AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state, collar_resting_icon_state = TRUE) AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, null, /datum/mood_event/pet_animal, "purr") + AddElement(/datum/element/pet_bonus, "purr", /datum/mood_event/pet_animal) AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) add_cell_sample() add_verb(src, /mob/living/proc/toggle_resting) diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm index 35996d4d77c..b5259d275b5 100644 --- a/code/modules/mob/living/basic/pets/dog/_dog.dm +++ b/code/modules/mob/living/basic/pets/dog/_dog.dm @@ -50,12 +50,22 @@ ///icon state of our cult icon var/cult_icon_state +/datum/emote/dog + mob_type_allowed_typecache = /mob/living/basic/pet/dog + mob_type_blacklist_typecache = list() + +/datum/emote/dog/woof + key = "woof" + key_third_person = "woof" + message = "woofs happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/pet/dog/Initialize(mapload) . = ..() AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state) AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state) ADD_TRAIT(src, TRAIT_WOUND_LICKER, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "woofs happily!") + AddElement(/datum/element/pet_bonus, "woof") AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/unfriend_attacker, untamed_reaction = "%SOURCE% fixes %TARGET% with a look of betrayal.") AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/meat/slab/human/mutant/skeleton, /obj/item/stack/sheet/bone), tame_chance = 30, bonus_tame_chance = 15, unique = FALSE) diff --git a/code/modules/mob/living/basic/pets/fox.dm b/code/modules/mob/living/basic/pets/fox.dm index c19e89e1fe8..737f7b21391 100644 --- a/code/modules/mob/living/basic/pets/fox.dm +++ b/code/modules/mob/living/basic/pets/fox.dm @@ -37,13 +37,22 @@ /datum/pet_command/perform_trick_sequence, ) +/datum/emote/fox + mob_type_allowed_typecache = /mob/living/basic/pet/fox + mob_type_blacklist_typecache = list() + +/datum/emote/fox/yap + key = "yap" + key_third_person = "yaps" + message = "yaps happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE /mob/living/basic/pet/fox/Initialize(mapload) . = ..() AddComponent(/datum/component/obeys_commands, pet_commands) AddElement(/datum/element/cultist_pet) AddElement(/datum/element/wears_collar) - AddElement(/datum/element/pet_bonus, "pants and yaps happily!") + AddElement(/datum/element/pet_bonus, "yap") AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) AddElement(/datum/element/tiny_mob_hunter, MOB_SIZE_SMALL) AddElement(/datum/element/ai_retaliate) diff --git a/code/modules/mob/living/basic/pets/gondolas/gondola.dm b/code/modules/mob/living/basic/pets/gondolas/gondola.dm index 9e17d1e08a5..e607a13bf1e 100644 --- a/code/modules/mob/living/basic/pets/gondolas/gondola.dm +++ b/code/modules/mob/living/basic/pets/gondolas/gondola.dm @@ -39,7 +39,7 @@ /mob/living/basic/pet/gondola/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_MUTE, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "smiles!") + AddElement(/datum/element/pet_bonus, "smile") if(LAZYLEN(loot)) loot = string_list(loot) AddElement(/datum/element/death_drops, loot) diff --git a/code/modules/mob/living/basic/pets/penguin.dm b/code/modules/mob/living/basic/pets/penguin.dm index a597bd70cbb..c1afe10187c 100644 --- a/code/modules/mob/living/basic/pets/penguin.dm +++ b/code/modules/mob/living/basic/pets/penguin.dm @@ -17,6 +17,15 @@ ///the egg it carries var/obj/carried_egg +/datum/emote/penguin + mob_type_allowed_typecache = /mob/living/basic/pet/penguin + mob_type_blacklist_typecache = list() + +/datum/emote/penguin/honk + key = "honk" + key_third_person = "honks" + message = "honks happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE /mob/living/basic/pet/penguin/Initialize(mapload) . = ..() @@ -24,7 +33,7 @@ AddElement(/datum/element/wears_collar) AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) - AddElement(/datum/element/pet_bonus, "honks happily!") + AddElement(/datum/element/pet_bonus, "honk") AddElementTrait(TRAIT_WADDLING, INNATE_TRAIT, /datum/element/waddling) if(!can_lay_eggs) return diff --git a/code/modules/mob/living/basic/pets/sloth.dm b/code/modules/mob/living/basic/pets/sloth.dm index 9cd7711aa06..b1f5c61001a 100644 --- a/code/modules/mob/living/basic/pets/sloth.dm +++ b/code/modules/mob/living/basic/pets/sloth.dm @@ -37,9 +37,19 @@ GLOBAL_DATUM(cargo_sloth, /mob/living/basic/sloth) ai_controller = /datum/ai_controller/basic_controller/sloth +/datum/emote/sloth + mob_type_allowed_typecache = /mob/living/basic/sloth + mob_type_blacklist_typecache = list() + +/datum/emote/sloth/smile_slow + key = "ssmile" + key_third_person = "slowlysmiles" + message = "slowly smiles!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/sloth/Initialize(mapload) . = ..() - AddElement(/datum/element/pet_bonus, "slowly smiles!") + AddElement(/datum/element/pet_bonus, "ssmile") AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) AddElement(/datum/element/ai_retaliate) AddComponent(/datum/component/tree_climber) diff --git a/code/modules/mob/living/basic/space_fauna/ant.dm b/code/modules/mob/living/basic/space_fauna/ant.dm index 7fbbe03e631..3ae46b7f539 100644 --- a/code/modules/mob/living/basic/space_fauna/ant.dm +++ b/code/modules/mob/living/basic/space_fauna/ant.dm @@ -36,10 +36,20 @@ ai_controller = /datum/ai_controller/basic_controller/ant +/datum/emote/ant + mob_type_allowed_typecache = /mob/living/basic/ant + mob_type_blacklist_typecache = list() + +/datum/emote/ant/clack + key = "clack" + key_third_person = "clacks" + message = "clacks happily!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/ant/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "clacks happily!") + AddElement(/datum/element/pet_bonus, "clack") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) 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 f1c12cc3ce9..a315e253ece 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -81,6 +81,16 @@ /obj/structure/window, )) +/datum/emote/carp + mob_type_allowed_typecache = /mob/living/basic/carp + mob_type_blacklist_typecache = list() + +/datum/emote/carp/bloop + key = "bloop" + key_third_person = "bloops" + message = "bloops!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/carp/Initialize(mapload, mob/tamer) ADD_TRAIT(src, TRAIT_FREE_HYPERSPACE_MOVEMENT, INNATE_TRAIT) //Need to set before init cause if we init in hyperspace we get dragged before the trait can be added . = ..() @@ -186,7 +196,7 @@ /mob/living/basic/carp/pet/Initialize(mapload) . = ..() AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "bloops happily!") + AddElement(/datum/element/pet_bonus, "bloop") /** * Lia - Sometimes the pet of the Head of Security. @@ -291,7 +301,7 @@ /mob/living/basic/carp/passive/Initialize(mapload) . = ..() AddComponent(/datum/component/ai_retaliate_advanced, CALLBACK(src, PROC_REF(on_attacked))) - AddElement(/datum/element/pet_bonus, "bloops happily!") + AddElement(/datum/element/pet_bonus, "bloop") ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT) /// If someone slaps one of the school, scatter diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm index f293f1dcbaa..1e78bd924a8 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm @@ -608,6 +608,6 @@ /mob/living/basic/spider/giant/sgt_araneus/Initialize(mapload) . = ..() - AddElement(/datum/element/pet_bonus, "chitters proudly!") + AddElement(/datum/element/pet_bonus, "chitter") AddElement(/datum/element/ai_retaliate) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm index 9f94d839a76..195b8149833 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm @@ -49,6 +49,18 @@ /// If true then you shouldn't be told that you're a spider antagonist as soon as you are placed into this mob var/apply_spider_antag = TRUE +/datum/emote/spider + mob_type_allowed_typecache = /mob/living/basic/spider + mob_type_blacklist_typecache = list() + +/datum/emote/spider/chitter + key = "chitter" + key_third_person = "chitters" + message = "chitters." + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/insect/chitter.ogg' + /mob/living/basic/spider/Initialize(mapload) . = ..() add_traits(list(TRAIT_WEB_SURFER, TRAIT_FENCE_CLIMBER), INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/vermin/lizard.dm b/code/modules/mob/living/basic/vermin/lizard.dm index da68087d70f..c1c21850ee6 100644 --- a/code/modules/mob/living/basic/vermin/lizard.dm +++ b/code/modules/mob/living/basic/vermin/lizard.dm @@ -46,10 +46,19 @@ /mob/living/basic/cockroach, )) +/datum/emote/lizard + mob_type_allowed_typecache = /mob/living/basic/lizard + mob_type_blacklist_typecache = list() + +/datum/emote/lizard/whicker + key = "tongue" + message = "sticks its tongue out contentedly!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/lizard/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "sticks its tongue out contentedly!") + AddElement(/datum/element/pet_bonus, "tongue") AddElement(/datum/element/basic_eating, heal_amt = 5, food_types = edibles) ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(edibles)) diff --git a/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm b/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm index 4e5d4fbf7f0..6d4d201f59e 100644 --- a/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm +++ b/code/modules/mob/living/basic/vermin/mothroach/mothroach.dm @@ -46,6 +46,16 @@ // NOVA EDIT ADDITION END ) +/datum/emote/mothroach + mob_type_allowed_typecache = /mob/living/basic/mothroach + mob_type_blacklist_typecache = list() + +/datum/emote/mothroach/squeaks + key = "squeaks" + key_third_person = "squeaks" + message = "squeaks!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + /mob/living/basic/mothroach/Initialize(mapload) . = ..() var/static/list/food_types = list(/obj/item/clothing) @@ -53,7 +63,7 @@ AddComponent(/datum/component/obeys_commands, pet_commands) ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(food_types)) AddElement(/datum/element/ai_retaliate) - AddElement(/datum/element/pet_bonus, "squeaks happily!") + AddElement(/datum/element/pet_bonus, "squeak") add_verb(src, /mob/living/proc/toggle_resting) ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index aba7c00d4c7..a0c1faf971d 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -44,6 +44,18 @@ /datum/pet_command/perform_trick_sequence, ) +/datum/emote/mouse + mob_type_allowed_typecache = /mob/living/basic/mouse + mob_type_blacklist_typecache = list() + +/datum/emote/mouse/squeak + key = "squeak" + key_third_person = "squeaks" + message = "squeak!" + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + vary = TRUE + sound = 'sound/mobs/non-humanoids/mouse/mousesqueek.ogg' + /mob/living/basic/mouse/Initialize(mapload, tame = FALSE, new_body_color) . = ..() if(contributes_to_ratcap) @@ -278,7 +290,7 @@ . = ..() // Tom fears no cable. ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT) - AddElement(/datum/element/pet_bonus, "squeaks happily!") + AddElement(/datum/element/pet_bonus, "squeak") /mob/living/basic/mouse/brown/tom/create_a_new_rat() new /mob/living/basic/mouse/brown(loc, /* tame = */ tame) // dominant gene diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 6a7f17fda8e..14b371c2bd3 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -1557,14 +1557,6 @@ GLOBAL_LIST_EMPTY(features_by_species) H.adjustBruteLoss(pressure_damage, required_bodytype = BODYTYPE_ORGANIC) H.throw_alert(ALERT_PRESSURE, /atom/movable/screen/alert/lowpressure, 2) - -////////// -// FIRE // -////////// - -/datum/species/proc/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE) - return no_protection - //////////// // Stun // //////////// diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 31925573d77..260cc5af20f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1140,6 +1140,26 @@ add_traits(list(TRAIT_NO_DNA_SCRAMBLE, TRAIT_BADDNA, TRAIT_BORN_MONKEY), SPECIES_TRAIT) +/mob/living/carbon/human/proc/is_atmos_sealed(additional_flags = null, check_hands = FALSE, ignore_chest_pressureprot = FALSE) + var/chest_covered = FALSE + var/head_covered = FALSE + var/hands_covered = FALSE + for (var/obj/item/clothing/equipped in get_equipped_items()) + // We don't really have space-proof gloves, so even if we're checking them we ignore the flags + if ((equipped.body_parts_covered & HANDS) && num_hands >= default_num_hands) + hands_covered = TRUE + if (!isnull(additional_flags) && !(equipped.clothing_flags & additional_flags)) + continue + if ((ignore_chest_pressureprot || (equipped.clothing_flags & STOPSPRESSUREDAMAGE)) && (equipped.body_parts_covered & CHEST)) + chest_covered = TRUE + if ((equipped.clothing_flags & STOPSPRESSUREDAMAGE) && (equipped.body_parts_covered & HEAD)) + head_covered = TRUE + if (!chest_covered) + return FALSE + if (!hands_covered && check_hands) + return FALSE + return head_covered || HAS_TRAIT(src, TRAIT_HEAD_ATMOS_SEALED) + /mob/living/carbon/human/species/abductor race = /datum/species/abductor diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index eeb3f9ea9b3..3c433842000 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -816,6 +816,6 @@ SEND_SIGNAL(src, COMSIG_HUMAN_BURNING) burn_clothing(seconds_per_tick, fire_handler.stacks) var/no_protection = FALSE - if(dna && dna.species) - no_protection = dna.species.handle_fire(src, seconds_per_tick, no_protection) + if (HAS_TRAIT(src, TRAIT_IGNORE_FIRE_PROTECTION)) + no_protection = TRUE fire_handler.harm_human(seconds_per_tick, no_protection) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 48a63300ee5..dcfbc70ca6d 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -69,62 +69,6 @@ /// If the bones themselves are burning clothes won't help you much var/internal_fire = FALSE -/datum/species/plasmaman/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) - . = ..() - var/atmos_sealed = TRUE - if(HAS_TRAIT(H, TRAIT_NOFIRE)) - atmos_sealed = FALSE - else if(!isclothing(H.wear_suit) || !(H.wear_suit.clothing_flags & STOPSPRESSUREDAMAGE)) - atmos_sealed = FALSE - else if(!HAS_TRAIT(H, TRAIT_NOSELFIGNITION_HEAD_ONLY) && (!isclothing(H.head) || !(H.head.clothing_flags & STOPSPRESSUREDAMAGE))) - atmos_sealed = FALSE - - var/flammable_limb = FALSE - for(var/obj/item/bodypart/found_bodypart as anything in H.bodyparts)//If any plasma based limb is found the plasmaman will attempt to autoignite - if(IS_ORGANIC_LIMB(found_bodypart) && found_bodypart.limb_id == SPECIES_PLASMAMAN) //Allows for "donated" limbs and augmented limbs to prevent autoignition - flammable_limb = TRUE - break - - if(!flammable_limb && !H.on_fire) //Allows their suit to attempt to autoextinguish if augged and on fire - return - - var/can_burn = FALSE - if(!isclothing(H.w_uniform) || !(H.w_uniform.clothing_flags & PLASMAMAN_PREVENT_IGNITION)) - can_burn = TRUE - else if(!isclothing(H.gloves) || H.num_hands < H.default_num_hands) //If you dont have the other glove then the suit isnt really sealed is it? - can_burn = TRUE - else if(!HAS_TRAIT(H, TRAIT_NOSELFIGNITION_HEAD_ONLY) && (!isclothing(H.head) || !(H.head.clothing_flags & PLASMAMAN_PREVENT_IGNITION))) - can_burn = TRUE - - if(!atmos_sealed && can_burn) - var/datum/gas_mixture/environment = H.loc.return_air() - if(environment?.total_moles()) - if(environment.gases[/datum/gas/hypernoblium] && (environment.gases[/datum/gas/hypernoblium][MOLES]) >= 5) - if(H.on_fire && H.fire_stacks > 0) - H.adjust_fire_stacks(-10 * seconds_per_tick) - else if(!HAS_TRAIT(H, TRAIT_NOFIRE)) - if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire - H.adjust_fire_stacks(0.25 * seconds_per_tick) - if(!H.on_fire && H.fire_stacks > 0) - H.visible_message(span_danger("[H]'s body reacts with the atmosphere and bursts into flames!"),span_userdanger("Your body reacts with the atmosphere and bursts into flame!")) - H.ignite_mob() - internal_fire = TRUE - - else if(H.fire_stacks) - var/obj/item/clothing/under/plasmaman/P = H.w_uniform - if(istype(P)) - P.Extinguish(H) - internal_fire = FALSE - else - internal_fire = FALSE - - H.update_appearance(UPDATE_OVERLAYS) - -/datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, seconds_per_tick, no_protection = FALSE) - if(internal_fire) - no_protection = TRUE - . = ..() - /datum/species/plasmaman/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only = FALSE) if(job?.plasmaman_outfit) equipping.equipOutfit(job.plasmaman_outfit, visuals_only) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 3faf44fe2f0..485b66941d4 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -675,10 +675,10 @@ return ..() /obj/item/mod/module/plasma_stabilizer/on_equip() - ADD_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT) + ADD_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT) /obj/item/mod/module/plasma_stabilizer/on_unequip() - REMOVE_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT) + REMOVE_TRAIT(mod.wearer, TRAIT_HEAD_ATMOS_SEALED, MOD_TRAIT) //Finally, https://pipe.miroware.io/5b52ba1d94357d5d623f74aa/mspfa/Nuke%20Ops/Panels/0648.gif can be real: diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 72bf5337dba..18e8de72101 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -560,7 +560,7 @@ color_override = "orange", ) INVOKE_ASYNC(SSticker, TYPE_PROC_REF(/datum/controller/subsystem/ticker, poll_hearts)) - INVOKE_ASYNC(SSvote, TYPE_PROC_REF(/datum/controller/subsystem/vote, initiate_vote), /datum/vote/map_vote, vote_initiator_name = "Map Rotation") + INVOKE_ASYNC(SSvote, TYPE_PROC_REF(/datum/controller/subsystem/vote, initiate_vote), /datum/vote/map_vote, vote_initiator_name = "Map Rotation", forced = TRUE) if(!is_reserved_level(z)) CRASH("Emergency shuttle did not move to transit z-level!") diff --git a/code/modules/spells/spell_types/pointed/tie_shoes.dm b/code/modules/spells/spell_types/pointed/tie_shoes.dm index b8efafaf3ba..42c47779aea 100644 --- a/code/modules/spells/spell_types/pointed/tie_shoes.dm +++ b/code/modules/spells/spell_types/pointed/tie_shoes.dm @@ -46,7 +46,7 @@ return isliving(cast_on) // We need to override this, as trying to change next_use_time in cast() will just result in it being overridden. -/datum/action/cooldown/spell/touch/before_cast(atom/cast_on) +/datum/action/cooldown/spell/pointed/untie_shoes/before_cast(atom/cast_on) return ..() | SPELL_NO_IMMEDIATE_COOLDOWN /datum/action/cooldown/spell/pointed/untie_shoes/cast(mob/living/carbon/cast_on) diff --git a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm index b0acf914079..0125601bda5 100644 --- a/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/plasmaman_bodyparts.dm @@ -12,6 +12,10 @@ head_flags = HEAD_EYESPRITES bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/head/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/chest/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_chest" @@ -29,6 +33,10 @@ /obj/item/bodypart/chest/plasmaman/get_butt_sprite() return icon('icons/mob/butts.dmi', BUTT_SPRITE_PLASMA) +/obj/item/bodypart/chest/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/arm/left/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_l_arm" @@ -41,6 +49,10 @@ burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/arm/left/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/arm/right/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_r_arm" @@ -53,6 +65,10 @@ burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/arm/right/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/leg/left/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_l_leg" @@ -65,6 +81,10 @@ burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE +/obj/item/bodypart/leg/left/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) + /obj/item/bodypart/leg/right/plasmaman icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi' icon_state = "plasmaman_r_leg" @@ -76,3 +96,7 @@ brute_modifier = 1.5 //Plasmemes are weak burn_modifier = 1.5 //Plasmemes are weak bodypart_flags = BODYPART_UNHUSKABLE + +/obj/item/bodypart/leg/right/plasmaman/Initialize(mapload) + . = ..() + AddComponent(/datum/component/self_ignition) diff --git a/html/changelogs/AutoChangeLog-pr-87086.yml b/html/changelogs/AutoChangeLog-pr-87086.yml new file mode 100644 index 00000000000..6197c676d67 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87086.yml @@ -0,0 +1,5 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Plasmaman space suit internal extinguisher works and can be refilled now" + - refactor: "Refactored plasmamen self-ignition to be limb-side instead of being handled by their species" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87126.yml b/html/changelogs/AutoChangeLog-pr-87126.yml new file mode 100644 index 00000000000..d8282e1ebb2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87126.yml @@ -0,0 +1,6 @@ +author: "grungussuss" +delete-after: True +changes: + - rscadd: "a lot of basic mobs and pets got new emotes" + - refactor: "emotes triggered by petting pets work differently now, please report any oddities with these behaviors." + - sound: "new emotes for basic mobs got sounds" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87158.yml b/html/changelogs/AutoChangeLog-pr-87158.yml new file mode 100644 index 00000000000..7d1810b7fd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87158.yml @@ -0,0 +1,4 @@ +author: "YakumoChen" +delete-after: True +changes: + - spellcheck: "Proofreads some faxes sent during radioactive nebulae" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87160.yml b/html/changelogs/AutoChangeLog-pr-87160.yml new file mode 100644 index 00000000000..f580e640640 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87160.yml @@ -0,0 +1,4 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - bugfix: "fixes ashdrake arena attack not clearing out lavaland walls" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87168.yml b/html/changelogs/AutoChangeLog-pr-87168.yml new file mode 100644 index 00000000000..cf39b3a5484 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87168.yml @@ -0,0 +1,4 @@ +author: "grungussuss" +delete-after: True +changes: + - bugfix: "snore emote works properly now" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-87183.yml b/html/changelogs/AutoChangeLog-pr-87183.yml new file mode 100644 index 00000000000..53ac31882e6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-87183.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "Untie shoes should have its cooldown increased correctly when casting it from a long distance" \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index fe0a7bfc9f3..6e853160451 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1321,6 +1321,7 @@ #include "code\datums\components\security_vision.dm" #include "code\datums\components\seethrough.dm" #include "code\datums\components\seethrough_mob.dm" +#include "code\datums\components\self_ignition.dm" #include "code\datums\components\shell.dm" #include "code\datums\components\shielded.dm" #include "code\datums\components\shovel_hands.dm"