mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 03:55:11 +01:00
276 lines
11 KiB
Plaintext
276 lines
11 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)
|
|
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
|
|
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
|
|
|
|
/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
|
|
///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)
|
|
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.
|