mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-15 01:54:52 +01:00
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
279 lines
12 KiB
Plaintext
279 lines
12 KiB
Plaintext
///Tail parent, it doesn't do very much.
|
|
/obj/item/organ/tail
|
|
name = "tail"
|
|
desc = "A severed tail. What did you cut this off of?"
|
|
icon_state = "severedtail"
|
|
|
|
zone = BODY_ZONE_PRECISE_GROIN
|
|
slot = ORGAN_SLOT_EXTERNAL_TAIL
|
|
|
|
//dna_block = /datum/dna_block/feature/accessory/tail // BUBBER EDIT REMOVAL - Customization - We have our own system to handle DNA.
|
|
restyle_flags = EXTERNAL_RESTYLE_FLESH
|
|
|
|
// defaults to cat, but the parent type shouldn't be created regardless
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/cat
|
|
|
|
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
|
|
|
|
///Does this tail have a wagging sprite, and is it currently wagging?
|
|
var/wag_flags = NONE
|
|
///The original owner of this tail
|
|
var/original_owner //Yay, snowflake code!
|
|
///The overlay for tail spines, if any
|
|
var/datum/bodypart_overlay/mutant/tail_spines/tail_spines_overlay
|
|
|
|
/obj/item/organ/tail/on_mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
|
. = ..()
|
|
receiver.clear_mood_event("tail_lost")
|
|
receiver.clear_mood_event("tail_balance_lost")
|
|
|
|
if(!special) // if some admin wants to give someone tail moodles for tail shenanigans, they can spawn it and do it by hand
|
|
original_owner ||= WEAKREF(receiver)
|
|
|
|
// If it's your tail, an infinite debuff is replaced with a timed one
|
|
// If it's not your tail but of same species, I guess it works, but we are more sad
|
|
// If it's not your tail AND of different species, we are horrified
|
|
if(IS_WEAKREF_OF(receiver, original_owner))
|
|
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_right)
|
|
else if(type in receiver.dna.species.mutant_organs)
|
|
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_species)
|
|
else
|
|
receiver.add_mood_event("tail_regained", /datum/mood_event/tail_regained_wrong)
|
|
|
|
/obj/item/organ/tail/on_bodypart_insert(obj/item/bodypart/bodypart)
|
|
var/obj/item/organ/spines/our_spines = bodypart.owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_SPINES)
|
|
if(our_spines)
|
|
try_insert_tail_spines(bodypart)
|
|
return ..()
|
|
|
|
/obj/item/organ/tail/on_bodypart_remove(obj/item/bodypart/bodypart)
|
|
remove_tail_spines(bodypart)
|
|
return ..()
|
|
|
|
/// If the owner has spines and an appropriate overlay exists, add a tail spines overlay.
|
|
/obj/item/organ/tail/proc/try_insert_tail_spines(obj/item/bodypart/bodypart)
|
|
// Don't insert another overlay if there already is one.
|
|
if(tail_spines_overlay)
|
|
return
|
|
// If this tail doesn't have a valid set of tail spines, don't insert them
|
|
var/datum/sprite_accessory/tails/tail_sprite_datum = bodypart_overlay.sprite_datum
|
|
if(!istype(tail_sprite_datum))
|
|
return
|
|
var/tail_spine_key = tail_sprite_datum.spine_key
|
|
if(!tail_spine_key)
|
|
return
|
|
|
|
tail_spines_overlay = new
|
|
tail_spines_overlay.tail_spine_key = tail_spine_key
|
|
// SKYRAT EDIT ADDITION START
|
|
if(!bodypart.owner.dna.mutant_bodyparts[FEATURE_SPINES])
|
|
bodypart.owner.dna.mutant_bodyparts[FEATURE_SPINES] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600"))
|
|
bodypart.owner.dna.update_uf_block(/datum/dna_block/feature/mutant/spines)
|
|
// SKYRAT EDIT ADDITION END
|
|
var/feature_name = bodypart.owner.dna.mutant_bodyparts[FEATURE_SPINES][MUTANT_INDEX_NAME] // BUBBER EDIT CHANGE - ORIGINAL: var/feature_name = bodypart.owner.dna.features[FEATURE_SPINES] //tail spines don't live in DNA, but share feature names with regular spines
|
|
tail_spines_overlay.set_appearance_from_dna(bodypart.owner.dna, feature_name, feature_key = FEATURE_SPINES) // BUBBER EDIT CHANGE - ORIGINAL: tail_spines_overlay.set_appearance_from_name(feature_name)
|
|
bodypart.add_bodypart_overlay(tail_spines_overlay)
|
|
|
|
/// If we have a tail spines overlay, delete it
|
|
/obj/item/organ/tail/proc/remove_tail_spines(obj/item/bodypart/bodypart)
|
|
if(!tail_spines_overlay)
|
|
return
|
|
bodypart.remove_bodypart_overlay(tail_spines_overlay)
|
|
QDEL_NULL(tail_spines_overlay)
|
|
|
|
/obj/item/organ/tail/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
|
. = ..()
|
|
|
|
if(wag_flags & WAG_WAGGING)
|
|
stop_wag(organ_owner)
|
|
|
|
organ_owner.clear_mood_event("tail_regained")
|
|
|
|
if(type in organ_owner.dna?.species.mutant_organs)
|
|
organ_owner.add_mood_event("tail_lost", /datum/mood_event/tail_lost)
|
|
organ_owner.add_mood_event("tail_balance_lost", /datum/mood_event/tail_balance_lost)
|
|
|
|
///We need some special behaviour for accessories, wrapped here so we can easily add more interactions later
|
|
///Accepts an optional timeout after which we remove the tail wagging
|
|
///Returns false if the wag worked, true otherwise
|
|
/obj/item/organ/tail/proc/start_wag(mob/living/carbon/organ_owner, stop_after = INFINITY)
|
|
if(wag_flags & WAG_WAGGING || !(wag_flags & WAG_ABLE)) // we are already wagging
|
|
return FALSE
|
|
if(organ_owner.stat == DEAD || organ_owner != owner) // no wagging when owner is dead or tail has been disembodied
|
|
return FALSE
|
|
|
|
if(stop_after != INFINITY)
|
|
addtimer(CALLBACK(src, PROC_REF(stop_wag), organ_owner), stop_after, TIMER_STOPPABLE|TIMER_DELETE_ME)
|
|
|
|
var/datum/bodypart_overlay/mutant/tail/accessory = bodypart_overlay
|
|
wag_flags |= WAG_WAGGING
|
|
accessory.wagging = TRUE
|
|
if(tail_spines_overlay) //if there are spines, they should wag with the tail
|
|
tail_spines_overlay.wagging = TRUE
|
|
organ_owner.update_body_parts()
|
|
RegisterSignal(organ_owner, COMSIG_LIVING_DEATH, PROC_REF(owner_died))
|
|
return TRUE
|
|
|
|
/obj/item/organ/tail/proc/owner_died(mob/living/carbon/organ_owner) // Resisting the urge to replace owner with daddy
|
|
SIGNAL_HANDLER
|
|
stop_wag(organ_owner)
|
|
|
|
///We need some special behaviour for accessories, wrapped here so we can easily add more interactions later
|
|
///Returns false if the wag stopping worked, true otherwise
|
|
/obj/item/organ/tail/proc/stop_wag(mob/living/carbon/organ_owner)
|
|
if(!(wag_flags & WAG_ABLE))
|
|
return FALSE
|
|
|
|
var/succeeded = FALSE
|
|
if(wag_flags & WAG_WAGGING)
|
|
wag_flags &= ~WAG_WAGGING
|
|
succeeded = TRUE
|
|
|
|
var/datum/bodypart_overlay/mutant/tail/tail_overlay = bodypart_overlay
|
|
tail_overlay.wagging = FALSE
|
|
if(tail_spines_overlay) //if there are spines, they should stop wagging with the tail
|
|
tail_spines_overlay.wagging = FALSE
|
|
if(isnull(organ_owner))
|
|
return succeeded
|
|
|
|
organ_owner.update_body_parts()
|
|
UnregisterSignal(organ_owner, COMSIG_LIVING_DEATH)
|
|
return succeeded
|
|
|
|
/obj/item/organ/tail/proc/get_butt_sprite()
|
|
return null
|
|
|
|
///Tail parent type, with wagging functionality
|
|
/datum/bodypart_overlay/mutant/tail
|
|
layers = EXTERNAL_FRONT|EXTERNAL_BEHIND
|
|
dyable = TRUE
|
|
feature_key = FEATURE_TAIL_GENERIC
|
|
var/wagging = FALSE
|
|
|
|
/datum/bodypart_overlay/mutant/tail/get_base_icon_state()
|
|
return "[wagging ? "wagging_" : ""][sprite_datum.icon_state]" //add the wagging tag if we be wagging
|
|
|
|
/datum/bodypart_overlay/mutant/tail/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE)
|
|
return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEJUMPSUIT)
|
|
|
|
/obj/item/organ/tail/cat
|
|
name = "tail"
|
|
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/cat
|
|
restyle_flags = EXTERNAL_RESTYLE_FLESH
|
|
|
|
wag_flags = WAG_ABLE
|
|
|
|
/datum/bodypart_overlay/mutant/tail/get_global_feature_list()
|
|
return SSaccessories.sprite_accessories[FEATURE_TAIL_GENERIC] // BUBBER EDIT CHANGE - Customization - ORIGINAL: return SSaccessories.tails_list_human
|
|
|
|
/obj/item/organ/tail/cat/get_butt_sprite()
|
|
return icon('icons/mob/butts.dmi', BUTT_SPRITE_CAT)
|
|
|
|
///Cat tail bodypart overlay
|
|
/datum/bodypart_overlay/mutant/tail/cat
|
|
feature_key = FEATURE_TAIL_GENERIC // BUBBER EDIT CHANGE - Customization - ORIGINAL: feature_key = FEATURE_TAIL_CAT
|
|
// color_source = ORGAN_COLOR_HAIR // SKYRAT EDIT REMOVAL
|
|
|
|
/obj/item/organ/tail/monkey
|
|
name = "monkey tail"
|
|
icon_state = "severedmonkeytail"
|
|
dna_block = null
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey
|
|
|
|
///Monkey tail bodypart overlay
|
|
/datum/bodypart_overlay/mutant/tail/monkey
|
|
color_source = NONE
|
|
feature_key = FEATURE_TAIL_MONKEY
|
|
|
|
/obj/item/organ/tail/xeno
|
|
name = "alien tail"
|
|
desc = "A long and flexible tail slightly resembling a spine, used by its original owner as both weapon and balance aid."
|
|
icon_state = "severedxenotail"
|
|
dna_block = null
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/xeno
|
|
organ_traits = list(TRAIT_TACKLING_TAILED_POUNCE, TRAIT_FREERUNNING)
|
|
|
|
/obj/item/organ/tail/xeno_queen
|
|
name = "alien queen's tail"
|
|
desc = "An enormous serrated tail, used to deadly effect by its original owner but perhaps too heavy for a human spine."
|
|
icon = 'icons/mob/human/species/alien/tail_xenomorph_queen.dmi'
|
|
icon_state = "severedqueentail"
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
slowdown = 2
|
|
item_flags = SLOWS_WHILE_IN_HAND
|
|
dna_block = null
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/xeno/queen
|
|
/// Our tail whip action
|
|
var/datum/action/cooldown/spell/aoe/repulse/xeno/tail_whip
|
|
|
|
/obj/item/organ/tail/xeno_queen/Initialize(mapload)
|
|
. = ..()
|
|
tail_whip = new(src)
|
|
|
|
/obj/item/organ/tail/xeno_queen/on_mob_insert(mob/living/carbon/receiver, special, movement_flags)
|
|
. = ..()
|
|
tail_whip.Grant(receiver)
|
|
receiver.add_movespeed_modifier(/datum/movespeed_modifier/tail_dragger)
|
|
|
|
/obj/item/organ/tail/xeno_queen/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
|
. = ..()
|
|
tail_whip.Remove(organ_owner)
|
|
organ_owner.remove_movespeed_modifier(/datum/movespeed_modifier/tail_dragger)
|
|
|
|
///Alien tail bodypart overlay
|
|
/datum/bodypart_overlay/mutant/tail/xeno
|
|
color_source = NONE
|
|
feature_key = FEATURE_TAIL_XENO
|
|
draw_on_husks = HUSK_OVERLAY_GRAYSCALE
|
|
imprint_on_next_insertion = FALSE
|
|
/// We don't want to bother writing this in DNA, just use this appearance
|
|
var/default_appearance = "Xeno"
|
|
|
|
/datum/bodypart_overlay/mutant/tail/xeno/New()
|
|
. = ..()
|
|
set_appearance_from_name(default_appearance)
|
|
|
|
/datum/bodypart_overlay/mutant/tail/xeno/randomize_appearance()
|
|
set_appearance_from_name(default_appearance)
|
|
|
|
/datum/bodypart_overlay/mutant/tail/xeno/queen
|
|
default_appearance = "Xeno Queen"
|
|
|
|
/obj/item/organ/tail/lizard
|
|
name = "lizard tail"
|
|
desc = "A severed lizard tail. Somewhere, no doubt, a lizard hater is very pleased with themselves."
|
|
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/lizard
|
|
|
|
wag_flags = WAG_ABLE
|
|
//dna_block = /datum/dna_block/feature/accessory/tail_lizard // BUBBER EDIT REMOVAL - Customization - We have our own system to handle DNA.
|
|
|
|
///Lizard tail bodypart overlay datum
|
|
/datum/bodypart_overlay/mutant/tail/lizard
|
|
feature_key = FEATURE_TAIL_GENERIC // BUBBER EDIT CHANGE - Customization - ORIGINAL: feature_key = FEATURE_TAIL_LIZARD
|
|
draw_on_husks = HUSK_OVERLAY_GRAYSCALE
|
|
|
|
/obj/item/organ/tail/lizard/fake
|
|
name = "fabricated lizard tail"
|
|
desc = "A fabricated severed lizard tail. This one's made of synthflesh. Probably not usable for lizard wine."
|
|
|
|
///Bodypart overlay for tail spines. Handled by the tail - has no actual organ associated.
|
|
/datum/bodypart_overlay/mutant/tail_spines
|
|
layers = EXTERNAL_ADJACENT|EXTERNAL_BEHIND
|
|
feature_key = FEATURE_TAILSPINES
|
|
draw_on_husks = HUSK_OVERLAY_GRAYSCALE
|
|
///Spines wag when the tail does
|
|
var/wagging = FALSE
|
|
/// Key for tail spine states, depends on the shape of the tail. Defined in the tail sprite datum.
|
|
var/tail_spine_key = NONE
|
|
|
|
/datum/bodypart_overlay/mutant/tail_spines/get_base_icon_state()
|
|
return (!isnull(tail_spine_key) ? "[tail_spine_key]_" : "") + (wagging ? "wagging_" : "") + sprite_datum.icon_state // Select the wagging state if appropriate
|
|
|
|
/datum/bodypart_overlay/mutant/tail_spines/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE)
|
|
return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEJUMPSUIT)
|
|
|
|
/datum/bodypart_overlay/mutant/tail_spines/set_dye_color(new_color, obj/item/organ/organ)
|
|
dye_color = new_color //no update_body_parts() call, tail/set_dye_color will do it.
|