diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index fc5f07bee1c..599f9151c40 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -315,6 +315,25 @@ mood_change = -3 timeout = 90 SECONDS +/datum/mood_event/tail_lost + description = "My tail!! Why?!\n" + mood_change = -8 + timeout = 10 MINUTES + +/datum/mood_event/tail_balance_lost + description = "I feel off-balance without my tail.\n" + mood_change = -2 + +/datum/mood_event/tail_regained_right + description = "My tail is back, but that was traumatic...\n" + mood_change = -2 + timeout = 5 MINUTES + +/datum/mood_event/tail_regained_wrong + description = "Is this some kind of sick joke?! This is NOT the right tail.\n" + mood_change = -12 // -8 for tail still missing + -4 bonus for being frakenstein's monster + timeout = 5 MINUTES + /datum/mood_event/burnt_wings description = "MY PRECIOUS WINGS!!\n" mood_change = -10 diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index b19dd2d0cf4..85c73b9fd79 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -458,6 +458,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) C.dna.species.mutant_bodyparts -= "wings" C.dna.features["wings"] = "None" C.update_body() + clear_tail_moodlets(C) C.remove_movespeed_modifier(/datum/movespeed_modifier/species) @@ -2026,6 +2027,63 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/is_wagging_tail(mob/living/carbon/human/H) return FALSE +/* + * This proc is called when a mob loses their tail. + * + * tail_owner - the owner of the tail (who holds our species datum) + * lost_tail - the tail that was removed + * on_species_init - whether or not this was called when the species was initialized, or if it was called due to an ingame means (like surgery) + */ +/datum/species/proc/on_tail_lost(mob/living/carbon/human/tail_owner, obj/item/organ/tail/lost_tail, on_species_init = FALSE) + SEND_SIGNAL(tail_owner, COMSIG_CLEAR_MOOD_EVENT, "right_tail_regained") + SEND_SIGNAL(tail_owner, COMSIG_CLEAR_MOOD_EVENT, "wrong_tail_regained") + stop_wagging_tail(tail_owner) + + // If it's initializing the species, don't add moodlets + if(on_species_init) + return + // If we don't have a set tail, don't bother adding moodlets + if(!mutant_organs.len) + return + + SEND_SIGNAL(tail_owner, COMSIG_ADD_MOOD_EVENT, "tail_lost", /datum/mood_event/tail_lost) + SEND_SIGNAL(tail_owner, COMSIG_ADD_MOOD_EVENT, "tail_balance_lost", /datum/mood_event/tail_balance_lost) + +/* + * This proc is called when a mob gains a tail. + * + * tail_owner - the owner of the tail (who holds our species datum) + * lost_tail - the tail that was added + * on_species_init - whether or not this was called when the species was initialized, or if it was called due to an ingame means (like surgery) + */ +/datum/species/proc/on_tail_regain(mob/living/carbon/human/tail_owner, obj/item/organ/tail/found_tail, on_species_init = FALSE) + SEND_SIGNAL(tail_owner, COMSIG_CLEAR_MOOD_EVENT, "tail_lost") + SEND_SIGNAL(tail_owner, COMSIG_CLEAR_MOOD_EVENT, "tail_balance_lost") + + // If it's initializing the species, don't add moodlets + if(on_species_init) + return + // If we don't have a set tail, don't add moodlets + if(!mutant_organs.len) + return + + if(found_tail.type in mutant_organs) + SEND_SIGNAL(tail_owner, COMSIG_ADD_MOOD_EVENT, "right_tail_regained", /datum/mood_event/tail_regained_right) + else + SEND_SIGNAL(tail_owner, COMSIG_ADD_MOOD_EVENT, "wrong_tail_regained", /datum/mood_event/tail_regained_wrong) + +/* + * Clears all tail related moodlets when they lose their species. + * + * former_tail_owner - the mob that was once a species with a tail and now is a different species + */ +/datum/species/proc/clear_tail_moodlets(mob/living/carbon/human/former_tail_owner) + SEND_SIGNAL(former_tail_owner, COMSIG_CLEAR_MOOD_EVENT, "tail_lost") + SEND_SIGNAL(former_tail_owner, COMSIG_CLEAR_MOOD_EVENT, "tail_balance_lost") + SEND_SIGNAL(former_tail_owner, COMSIG_CLEAR_MOOD_EVENT, "right_tail_regained") + SEND_SIGNAL(former_tail_owner, COMSIG_CLEAR_MOOD_EVENT, "wrong_tail_regained") + stop_wagging_tail(former_tail_owner) + /datum/species/proc/start_wagging_tail(mob/living/carbon/human/H) /datum/species/proc/stop_wagging_tail(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index db26556e36d..68aabf120ee 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -58,7 +58,7 @@ mutantears = /obj/item/organ/ears if(H.dna.features["tail_human"] == "Cat") var/obj/item/organ/tail/cat/tail = new - tail.Insert(H, drop_if_replaced = FALSE) + tail.Insert(H, special = TRUE, drop_if_replaced = FALSE) else mutant_organs = list() return ..() diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 11df1d36932..a64f53d2e09 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -40,7 +40,13 @@ foodtypes = RAW | MEAT | GROSS,\ volume = reagent_vol,\ after_eat = CALLBACK(src, .proc/OnEatFrom)) - +/* + * Insert the organ into the select mob. + * + * M - the mob who will get our organ + * special - "quick swapping" an organ out - when TRUE, the mob will be unaffected by not having that organ for the moment + * drop_if_replaced - if there's an organ in the slot already, whether we drop it afterwards + */ /obj/item/organ/proc/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE) if(!iscarbon(M) || owner == M) return @@ -64,7 +70,12 @@ A.Grant(M) STOP_PROCESSING(SSobj, src) -//Special is for instant replacement like autosurgeons +/* + * Remove the organ from the select mob. + * + * M - the mob who owns our organ, that we're removing the organ from. + * special - "quick swapping" an organ out - when TRUE, the mob will be unaffected by not having that organ for the moment + */ /obj/item/organ/proc/Remove(mob/living/carbon/M, special = FALSE) owner = null if(M) diff --git a/code/modules/surgery/organs/tails.dm b/code/modules/surgery/organs/tails.dm index d8cf00be4bd..2ca70316d7a 100644 --- a/code/modules/surgery/organs/tails.dm +++ b/code/modules/surgery/organs/tails.dm @@ -8,17 +8,20 @@ slot = ORGAN_SLOT_TAIL var/tail_type = "None" -/obj/item/organ/tail/Remove(mob/living/carbon/human/H, special = 0) - ..() - if(H && H.dna && H.dna.species) - H.dna.species.stop_wagging_tail(H) +/obj/item/organ/tail/Insert(mob/living/carbon/human/tail_owner, special = FALSE, drop_if_replaced = TRUE) + . = ..() + tail_owner?.dna?.species?.on_tail_regain(tail_owner, src, special) + +/obj/item/organ/tail/Remove(mob/living/carbon/human/tail_owner, special = FALSE) + . = ..() + tail_owner?.dna?.species?.on_tail_lost(tail_owner, src, special) /obj/item/organ/tail/cat name = "cat tail" desc = "A severed cat tail. Who's wagging now?" tail_type = "Cat" -/obj/item/organ/tail/cat/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE) +/obj/item/organ/tail/cat/Insert(mob/living/carbon/human/H, special = FALSE, drop_if_replaced = TRUE) ..() if(istype(H)) var/default_part = H.dna.species.mutant_bodyparts["tail_human"] @@ -26,7 +29,7 @@ H.dna.features["tail_human"] = H.dna.species.mutant_bodyparts["tail_human"] = tail_type H.update_body() -/obj/item/organ/tail/cat/Remove(mob/living/carbon/human/H, special = 0) +/obj/item/organ/tail/cat/Remove(mob/living/carbon/human/H, special = FALSE) ..() if(istype(H)) H.dna.features["tail_human"] = "None" @@ -45,7 +48,7 @@ . = ..() color = "#"+ random_color() -/obj/item/organ/tail/lizard/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE) +/obj/item/organ/tail/lizard/Insert(mob/living/carbon/human/H, special = FALSE, drop_if_replaced = TRUE) ..() if(istype(H)) // Checks here are necessary so it wouldn't overwrite the tail of a lizard it spawned in @@ -58,7 +61,7 @@ H.dna.features["spines"] = H.dna.species.mutant_bodyparts["spines"] = spines H.update_body() -/obj/item/organ/tail/lizard/Remove(mob/living/carbon/human/H, special = 0) +/obj/item/organ/tail/lizard/Remove(mob/living/carbon/human/H, special = FALSE) ..() if(istype(H)) H.dna.species.mutant_bodyparts -= "tail_lizard" @@ -84,7 +87,7 @@ tail_type = "Monkey" icon_state = "severedmonkeytail" -/obj/item/organ/tail/monkey/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE) +/obj/item/organ/tail/monkey/Insert(mob/living/carbon/human/H, special = FALSE, drop_if_replaced = TRUE) ..() if(istype(H)) if(!("tail_monkey" in H.dna.species.mutant_bodyparts)) @@ -92,7 +95,7 @@ H.dna.features["tail_monkey"] = tail_type H.update_body() -/obj/item/organ/tail/monkey/Remove(mob/living/carbon/human/H, special = 0) +/obj/item/organ/tail/monkey/Remove(mob/living/carbon/human/H, special = FALSE) ..() if(istype(H)) H.dna.features["tail_monkey"] = "None"