You can transplant xenomorph tails onto people (#89618)

This PR allows you to extract tail organs from xenomorphs and surgically
attach xenomorph tails to people.
(Despite being a carbon the xenomorph sprite is not built out of
component overlays so this technically does not remove the tail from its
corpse sorry).

Having a xenomorph tail makes you better at tackling, changes your
tackle verb to "pounce" like if you are a felinid, and also gives you
the parkour benefits of the Freerunning quirk.

![image](https://github.com/user-attachments/assets/6eb0f825-4f23-4a22-aa4d-03cc1cbd676a)
You can also surgically attach a xenomorph _queen_'s tail to someone.
This arguably is a bad idea because it makes you slower (it's much too
heavy) but it does give you access to the queen's tail spin attack
(after which you will fall over if you aren't inhumanly strong). Also
more importantly, it is comically large.

Look I'm racking my brain but this one really mostly comes down to "it's
funny to do this".
But let's pretend that it also increases the depth and complexity of the
sandbox and promotes interesting interactions between crewmembers or
something like that.

Ideally sometimes in the future we will either decide that xenomorphs
are not carbons (is it purely because they have organs?) or decide that
they _are_ carbons and build them accordingly. In the latter case this
will have been a useful addition.

🆑
add: You can transplant xenomorph tails onto people.
/🆑
This commit is contained in:
Jacquerel
2025-03-12 16:53:40 -04:00
committed by Roxy
parent d5e597926c
commit e366ace9ec
20 changed files with 126 additions and 8 deletions
+3
View File
@@ -1232,6 +1232,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Makes a character be better/worse at defending against tackling depending on their tail's status
#define TRAIT_TACKLING_TAILED_DEFENDER "tackling_tailed_defender"
/// Makes a character better at tackling if they have a tail
#define TRAIT_TACKLING_TAILED_POUNCE "tackling_tailed_pounce"
/// Is runechat for this atom/movable currently disabled, regardless of prefs or anything?
#define TRAIT_RUNECHAT_HIDDEN "runechat_hidden"
+1
View File
@@ -539,6 +539,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_SURGICALLY_ANALYZED" = TRAIT_SURGICALLY_ANALYZED,
"TRAIT_TACKLING_FRAIL_ATTACKER" = TRAIT_TACKLING_FRAIL_ATTACKER,
"TRAIT_TACKLING_TAILED_DEFENDER" = TRAIT_TACKLING_TAILED_DEFENDER,
"TRAIT_TACKLING_TAILED_POUNCE" = TRAIT_TACKLING_TAILED_POUNCE,
"TRAIT_TACKLING_WINGED_ATTACKER" = TRAIT_TACKLING_WINGED_ATTACKER,
"TRAIT_TACTICALLY_CAMOUFLAGED" = TRAIT_TACTICALLY_CAMOUFLAGED,
"TRAIT_TAGGER" = TRAIT_TAGGER,
+3
View File
@@ -291,6 +291,9 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_SUPERMATTER_SOOTHER" = TRAIT_SUPERMATTER_SOOTHER,
"TRAIT_SURGEON" = TRAIT_SURGEON,
"TRAIT_SURGICALLY_ANALYZED" = TRAIT_SURGICALLY_ANALYZED,
"TRAIT_TACKLING_FRAIL_ATTACKER" = TRAIT_TACKLING_FRAIL_ATTACKER,
"TRAIT_TACKLING_TAILED_DEFENDER" = TRAIT_TACKLING_TAILED_DEFENDER,
"TRAIT_TACKLING_TAILED_POUNCE" = TRAIT_TACKLING_TAILED_POUNCE,
"TRAIT_TAGGER" = TRAIT_TAGGER,
"TRAIT_TENTACLE_IMMUNE" = TRAIT_TENTACLE_IMMUNE,
"TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE,
@@ -53,6 +53,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
var/list/tails_list_felinid
var/list/tails_list_lizard
var/list/tails_list_monkey
var/list/tails_list_xeno
var/list/tails_list_fish
var/list/ears_list
var/list/wings_list
@@ -129,6 +130,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard)[DEFAULT_SPRITE_LIST]
*/
tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST]
tails_list_xeno = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/xeno)[DEFAULT_SPRITE_LIST]
//tails fo fish organ infusions, not for prefs.
tails_list_fish = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/fish)[DEFAULT_SPRITE_LIST]
/*
@@ -26,6 +26,9 @@
/datum/bodypart_overlay/mutant/proc/on_mob_insert(obj/item/organ/parent, mob/living/carbon/receiver)
SIGNAL_HANDLER
if (isalien(receiver))
return // Xenomorphs have no dna or other features required to support this, maybe one day
if(!should_visual_organ_apply_to(parent.type, receiver))
stack_trace("adding a [parent.type] to a [receiver.type] when it shouldn't be!")
+5 -1
View File
@@ -106,7 +106,7 @@
RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(checkObstacle))
playsound(user, 'sound/items/weapons/thudswoosh.ogg', 40, TRUE, -1)
var/leap_word = isfeline(user) ? "pounce" : "leap" //If cat, "pounce" instead of "leap". // SKYRAT EDIT - FELINE TRAITS. Was: isfelinid(user)
var/leap_word = isfeline(user) || HAS_TRAIT(user, TRAIT_TACKLING_TAILED_POUNCE) ? "pounce" : "leap" //If cat, "pounce" instead of "leap". // SKYRAT EDIT - FELINE TRAITS. Was: isfelinid(user)
if(can_see(user, clicked_atom, 7))
user.visible_message(span_warning("[user] [leap_word]s at [clicked_atom]!"), span_danger("You [leap_word] at [clicked_atom]!"))
else
@@ -434,6 +434,10 @@
if(HAS_TRAIT(sacker, TRAIT_NOGUNS)) //Those dedicated to martial combat are particularly skilled tacklers
attack_mod += 2
if(HAS_TRAIT(sacker, TRAIT_TACKLING_TAILED_POUNCE))
var/obj/item/organ/tail/lizard/sacker_tail = sacker.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
attack_mod += sacker_tail ? 2 : -2
if(HAS_TRAIT(sacker, TRAIT_TACKLING_WINGED_ATTACKER))
var/obj/item/organ/wings/moth/sacker_moth_wing = sacker.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS)
if(!sacker_moth_wing || sacker_moth_wing.burnt)
+15
View File
@@ -1825,6 +1825,21 @@
icon_state = "default"
color_src = FALSE
/datum/sprite_accessory/tails/xeno
icon_state = "default"
color_src = FALSE
center = TRUE
/datum/sprite_accessory/tails/xeno/default
name = "Xeno"
icon = 'icons/mob/human/species/alien/tail_xenomorph.dmi'
dimension_x = 40
/datum/sprite_accessory/tails/xeno/queen
name = "Xeno Queen"
icon = 'icons/mob/human/species/alien/tail_xenomorph_queen.dmi'
dimension_x = 64
/datum/sprite_accessory/pod_hair
icon = 'icons/mob/human/species/podperson_hair.dmi'
em_block = TRUE
@@ -16,6 +16,7 @@
ORGAN_SLOT_XENO_PLASMAVESSEL = /obj/item/organ/alien/plasmavessel/large,
ORGAN_SLOT_XENO_RESINSPINNER = /obj/item/organ/alien/resinspinner,
ORGAN_SLOT_XENO_ACIDGLAND = /obj/item/organ/alien/acid,
ORGAN_SLOT_EXTERNAL_TAIL = /obj/item/organ/tail/xeno,
)
/mob/living/carbon/alien/adult/drone/Initialize(mapload)
@@ -15,6 +15,7 @@
ORGAN_SLOT_EARS = /obj/item/organ/ears,
ORGAN_SLOT_STOMACH = /obj/item/organ/stomach/alien,
ORGAN_SLOT_XENO_PLASMAVESSEL = /obj/item/organ/alien/plasmavessel/small,
ORGAN_SLOT_EXTERNAL_TAIL = /obj/item/organ/tail/xeno,
)
var/atom/movable/screen/leap_icon = null
@@ -18,6 +18,7 @@
ORGAN_SLOT_XENO_RESINSPINNER = /obj/item/organ/alien/resinspinner,
ORGAN_SLOT_XENO_ACIDGLAND = /obj/item/organ/alien/acid,
ORGAN_SLOT_XENO_NEUROTOXINGLAND = /obj/item/organ/alien/neurotoxin,
ORGAN_SLOT_EXTERNAL_TAIL = /obj/item/organ/tail/xeno,
)
/mob/living/carbon/alien/adult/royal/praetorian/Initialize(mapload)
@@ -17,6 +17,7 @@
ORGAN_SLOT_XENO_PLASMAVESSEL = /obj/item/organ/alien/plasmavessel,
ORGAN_SLOT_XENO_ACIDGLAND = /obj/item/organ/alien/acid,
ORGAN_SLOT_XENO_NEUROTOXINGLAND = /obj/item/organ/alien/neurotoxin,
ORGAN_SLOT_EXTERNAL_TAIL = /obj/item/organ/tail/xeno,
)
/mob/living/carbon/alien/adult/sentinel/Initialize(mapload)
@@ -20,6 +20,8 @@
REMOVE_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
// that'd be a too cheeky shield bashing strat
ADD_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, INNATE_TRAIT)
// Lets you spin without falling over
ADD_TRAIT(src, TRAIT_STRENGTH, INNATE_TRAIT)
AddComponent(/datum/component/seethrough_mob)
/mob/living/carbon/alien/adult/royal/on_lying_down(new_lying_angle)
@@ -56,12 +58,12 @@
ORGAN_SLOT_XENO_ACIDGLAND = /obj/item/organ/alien/acid,
ORGAN_SLOT_XENO_NEUROTOXINGLAND = /obj/item/organ/alien/neurotoxin,
ORGAN_SLOT_XENO_EGGSAC = /obj/item/organ/alien/eggsac,
ORGAN_SLOT_EXTERNAL_TAIL = /obj/item/organ/tail/xeno_queen,
)
/mob/living/carbon/alien/adult/royal/queen/Initialize(mapload)
var/static/list/innate_actions = list(
/datum/action/cooldown/alien/promote,
/datum/action/cooldown/spell/aoe/repulse/xeno,
)
grant_actions_by_list(innate_actions)
+3
View File
@@ -180,3 +180,6 @@
/datum/movespeed_modifier/fish_on_water
blacklisted_movetypes = MOVETYPES_NOT_TOUCHING_GROUND
multiplicative_slowdown = - /turf/open/water::slowdown
/datum/movespeed_modifier/tail_dragger
multiplicative_slowdown = 4
@@ -107,6 +107,22 @@
if(iscarbon(cast_on))
var/mob/living/carbon/carbon_caster = cast_on
playsound(get_turf(carbon_caster), 'sound/mobs/non-humanoids/hiss/hiss5.ogg', 80, TRUE, TRUE)
carbon_caster.spin(6, 1)
carbon_caster.spin(0.6 SECONDS, 1)
if(isliving(cast_on) && !is_strongman(cast_on))
addtimer(CALLBACK(src, PROC_REF(after_spin)), 0.6 SECONDS, TIMER_DELETE_ME)
return ..()
/// Returns true if you're strong enough
/datum/action/cooldown/spell/aoe/repulse/xeno/proc/is_strongman(mob/living/owner)
if (HAS_TRAIT(owner, TRAIT_STRENGTH))
return TRUE
var/strength_level = owner.mind?.get_skill_level(/datum/skill/athletics)
return strength_level >= SKILL_LEVEL_MASTER
/// You're not strong enough :(
/datum/action/cooldown/spell/aoe/repulse/xeno/proc/after_spin()
if(QDELETED(owner) || is_strongman(owner))
return
var/mob/living/living_owner = owner
living_owner.Knockdown(5 SECONDS)
+8 -1
View File
@@ -91,7 +91,7 @@
/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/saw,
/datum/surgery_step/manipulate_organs/internal,
/datum/surgery_step/manipulate_organs/any,
/datum/surgery_step/close,
)
@@ -317,6 +317,13 @@
/datum/surgery_step/manipulate_organs/proc/can_use_organ(obj/item/organ/organ)
return FALSE
/datum/surgery_step/manipulate_organs/any
time = 6.4 SECONDS
name = "manipulate organs (hemostat/organ)"
/datum/surgery_step/manipulate_organs/any/can_use_organ(obj/item/organ/organ)
return TRUE
///Surgery step for internal organs, like hearts and brains
/datum/surgery_step/manipulate_organs/internal
time = 6.4 SECONDS
+59 -4
View File
@@ -88,7 +88,7 @@
organ_owner.clear_mood_event("tail_regained")
if(type in organ_owner.dna.species.mutant_organs)
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)
@@ -187,10 +187,9 @@
/obj/item/organ/tail/monkey
name = "monkey tail"
preference = "feature_monkey_tail"
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey
icon_state = "severedmonkeytail"
dna_block = null
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/monkey
///Monkey tail bodypart overlay
/datum/bodypart_overlay/mutant/tail/monkey
@@ -200,6 +199,62 @@
/datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list()
return SSaccessories.tails_list_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 = "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/get_global_feature_list()
return SSaccessories.tails_list_xeno
/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."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 61 KiB