Component Traits. (#17665)

* Drippy component

* Converts disabilities to components.

* Makes weaver a component

* living

* Update vorestation.dme

* Update weaver.dm

* yeah tis

* no spawn

* yes

* signals hell yeah

* Teaching

* yeaaah

* makes gargoyle follow the law

* whoops

* return properly

* wah

* Update station.dm
This commit is contained in:
Cameron Lennox
2025-05-15 00:59:47 -07:00
committed by GitHub
parent adbc9063fb
commit 5d95b50db9
27 changed files with 646 additions and 342 deletions
@@ -31,7 +31,6 @@
var/list/teleporters = list() //Used for lleill abilities
var/rest_dir = 0 //To lay down in a specific direction
var/gutdeathpressure = 0 //For GIBBING trait
var/list/datum/genetics/side_effect/genetic_side_effects = list() //For any genetic side effects we currently have.
/mob/living/carbon/human/Initialize(mapload, var/new_species = null)
+2 -64
View File
@@ -61,7 +61,6 @@
handle_organs()
stabilize_body_temperature() //Body temperature adjusts itself (self-regulation)
weightgain()
process_weaver_silk()
handle_shock()
handle_pain()
@@ -183,69 +182,8 @@
if(stat != CONSCIOUS) //Let's not worry about tourettes if you're not conscious.
return
if (disabilities & EPILEPSY)
if ((prob(1) && prob(1) && paralysis < 1))
to_chat(src, span_red("You have a seizure!"))
for(var/mob/O in viewers(src, null))
if(O == src)
continue
O.show_message(span_danger("[src] starts having a seizure!"), 1)
Paralyse(10)
make_jittery(1000)
if (disabilities & COUGHING)
if ((prob(5) && paralysis <= 1))
drop_item()
emote("cough")
if(dna)
if(disabilities & DETERIORATE && prob(2) && prob(3)) // stacked percents for rarity
// random strange symptoms from organ/limb
automatic_custom_emote(VISIBLE_MESSAGE, "flinches slightly.", check_stat = TRUE)
switch(rand(1,4))
if(1)
adjustToxLoss(rand(2,8))
if(2)
adjustCloneLoss(rand(1,2))
if(3)
add_chemical_effect(CE_PAINKILLER, rand(8,28))
else
adjustOxyLoss(rand(13,26))
// external organs need to fall off if damaged enough
var/obj/item/organ/O = pick(organs)
if(O && !(O.organ_tag == BP_GROIN || O.organ_tag == BP_TORSO) && istype(O,/obj/item/organ/external))
var/obj/item/organ/external/E = O
if(O.damage >= O.min_broken_damage && O.robotic <= ORGAN_ASSISTED && prob(70))
add_chemical_effect(CE_PAINKILLER, 120) // what limb? Extreme nerve damage. Can't feel a thing + shock
E.droplimb(TRUE, DROPLIMB_ACID)
if(disabilities & GIBBING)
gutdeathpressure += 0.01
if(gutdeathpressure > 0 && prob(gutdeathpressure))
emote(pick("whimper","belch","belch","belch","choke","shiver"))
Weaken(gutdeathpressure / 3)
if((gutdeathpressure/3) >= 1 && prob(gutdeathpressure/3))
gutdeathpressure = 0 // to stop retriggering
spawn(1)
emote(pick("whimper","shiver"))
spawn(3)
emote(pick("whimper","belch","shiver"))
spawn(4)
emote(pick("whimper","shiver"))
spawn(6)
emote(pick("belch"))
gib()
if (disabilities & TOURETTES)
if ((prob(1) && prob(2) && paralysis <= 1))
Stun(10)
make_jittery(100)
switch(rand(1, 3))
if(1)
emote("twitch")
if(2 to 3)
say("[prob(50) ? ";" : ""][pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")]")
if (disabilities & NERVOUS)
if (prob(5) && prob(7))
stuttering = max(15, stuttering)
if(jitteriness < 50)
make_jittery(65)
if(isbelly(loc)) //Let's not have you seizing, coughing, or falling apart if you're in a belly.
return
var/rn = rand(0, 200)
if(getBrainLoss() >= 5)
@@ -6,14 +6,6 @@
else if (nutrition <= MAX_NUTRITION_TO_LOSE && stat != 2 && weight > MIN_MOB_WEIGHT && weight_loss)
weight -= species.metabolism*(0.01*weight_loss) // starvation weight loss
/mob/living/carbon/human/proc/process_weaver_silk()
if(!species || !(species.is_weaver))
return
if(species.silk_reserve < species.silk_max_reserve && species.silk_production == TRUE && nutrition > 100)
species.silk_reserve = min(species.silk_reserve + 2, species.silk_max_reserve)
adjust_nutrition(-0.4)
//Our call for the NIF to do whatever
/mob/living/carbon/human/proc/handle_nif()
if(!nif) return
@@ -244,7 +244,6 @@
var/gluttonous // Can eat some mobs. 1 for mice, 2 for monkeys, 3 for people.
var/soft_landing = FALSE // Can fall down and land safely on small falls.
var/drippy = FALSE // If we drip or not. Primarily for goo beings.
var/photosynthesizing = FALSE // If we get nutrition from light or not.
var/shrinks = FALSE // If we shrink when we have no nutrition. Not added but here for downstream's sake.
var/grows = FALSE // Same as above but if we grow when >1000 nutrition.
@@ -348,12 +347,6 @@
var/bloodsucker = FALSE // Allows safely getting nutrition from blood.
var/bloodsucker_controlmode = "always loud" //Allows selecting between bloodsucker control modes. Always Loud corresponds to original implementation.
var/is_weaver = FALSE
var/silk_production = FALSE
var/silk_reserve = 100
var/silk_max_reserve = 500
var/silk_color = "#FFFFFF"
var/list/traits = list()
//Vars that need to be copied when producing a copy of species.
var/list/copy_vars = list("base_species", "icobase", "deform", "tail", "tail_animation", "icobase_tail", "color_mult", "primitive_form", "appearance_flags", "flesh_color", "base_color", "blood_mask", "damage_mask", "damage_overlays", "move_trail", "has_floating_eyes")
@@ -1547,13 +1547,10 @@
tail = "tail" //Spider tail.
icobase_tail = 1
species_component = /datum/component/weaver
inherent_verbs = list(
/mob/living/carbon/human/proc/check_silk_amount,
/mob/living/carbon/human/proc/toggle_silk_production,
/mob/living/carbon/human/proc/weave_structure,
/mob/living/carbon/human/proc/weave_item,
/mob/living/carbon/human/proc/set_silk_color,
/mob/living/carbon/human/proc/tie_hair)
/mob/living/carbon/human/proc/tie_hair)
min_age = 18
max_age = 80
@@ -1585,10 +1582,6 @@
base_color = "#333333" //Blackish-gray
blood_color = "#0952EF" //Spiders have blue blood.
is_weaver = TRUE
silk_reserve = 500
silk_max_reserve = 1000
climb_mult = 0.75
/datum/species/spider/handle_environment_special(var/mob/living/carbon/human/H)
@@ -615,151 +615,6 @@
pass_flags ^= PASSTABLE //I dunno what this fancy ^= is but Aronai gave it to me.
to_chat(src, "You [pass_flags&PASSTABLE ? "will" : "will NOT"] move over tables/railings/trays!")
/mob/living/carbon/human/proc/check_silk_amount()
set name = "Check Silk Amount"
set category = "Abilities.Weaver"
if(species.is_weaver)
to_chat(src, "Your silk reserves are at [species.silk_reserve]/[species.silk_max_reserve].")
else
to_chat(src, span_warning("You are not a weaver! How are you doing this? Tell a developer!"))
/mob/living/carbon/human/proc/toggle_silk_production()
set name = "Toggle Silk Production"
set category = "Abilities.Weaver"
if(species.is_weaver)
species.silk_production = !(species.silk_production)
to_chat(src, "You are [species.silk_production ? "now" : "no longer"] producing silk.")
else
to_chat(src, span_warning("You are not a weaver! How are you doing this? Tell a developer!"))
/mob/living/carbon/human/proc/weave_structure()
set name = "Weave Structure"
set category = "Abilities.Weaver"
if(!(species.is_weaver))
to_chat(src, span_warning("You are not a weaver! How are you doing this? Tell a developer!"))
return
var/choice
var/datum/weaver_recipe/structure/desired_result
var/finalized = "No"
while(finalized == "No" && src.client)
choice = tgui_input_list(src,"What would you like to weave?", "Weave Choice", GLOB.weavable_structures)
desired_result = GLOB.weavable_structures[choice]
if(!desired_result || !istype(desired_result))
return
if(choice)
finalized = tgui_alert(src, "Are you sure you want to weave [desired_result.title]? It will cost you [desired_result.cost] silk.","Confirmation",list("Yes","No"))
if(!desired_result || !istype(desired_result))
return
if(desired_result.cost > species.silk_reserve)
to_chat(src, span_warning("You don't have enough silk to weave that!"))
return
if(stat)
to_chat(src, span_warning("You can't do that in your current state!"))
return
if(locate(desired_result.result_type) in src.loc)
to_chat(src, span_warning("You can't create another weaversilk [desired_result.title] here!"))
return
if(!isturf(src.loc))
to_chat(src, span_warning("You can't weave here!"))
return
if(do_after(src, desired_result.time, exclusive = TASK_USER_EXCLUSIVE))
if(desired_result.cost > species.silk_reserve)
to_chat(src, span_warning("You don't have enough silk to weave that!"))
return
if(locate(desired_result.result_type) in src.loc)
to_chat(src, span_warning("You can't create another weaversilk [desired_result.title] here!"))
return
if(!isturf(src.loc))
to_chat(src, span_warning("You can't weave here!"))
return
species.silk_reserve = max(species.silk_reserve - desired_result.cost, 0)
//new desired_result.result_type(src.loc)
var/atom/O = new desired_result.result_type(src.loc)
O.color = species.silk_color
/mob/living/carbon/human/proc/weave_item()
set name = "Weave Item"
set category = "Abilities.Weaver"
if(!(species.is_weaver))
return
var/choice
var/datum/weaver_recipe/item/desired_result
var/finalized = "No"
while(finalized == "No" && src.client)
choice = tgui_input_list(src,"What would you like to weave?", "Weave Choice", GLOB.weavable_items)
desired_result = GLOB.weavable_items[choice]
if(!desired_result || !istype(desired_result))
return
if(choice)
finalized = tgui_alert(src, "Are you sure you want to weave [desired_result.title]? It will cost you [desired_result.cost] silk.","Confirmation",list("Yes","No"))
if(!desired_result || !istype(desired_result))
return
if(!(species.is_weaver))
to_chat(src, span_warning("You are not a weaver! How are you doing this? Tell a developer!"))
return
if(desired_result.cost > species.silk_reserve)
to_chat(src, span_warning("You don't have enough silk to weave that!"))
return
if(stat)
to_chat(src, span_warning("You can't do that in your current state!"))
return
if(!isturf(src.loc))
to_chat(src, span_warning("You can't weave here!"))
return
if(do_after(src, desired_result.time, exclusive = TASK_USER_EXCLUSIVE))
if(desired_result.cost > species.silk_reserve)
to_chat(src, span_warning("You don't have enough silk to weave that!"))
return
if(!isturf(src.loc))
to_chat(src, span_warning("You can't weave here!"))
return
species.silk_reserve = max(species.silk_reserve - desired_result.cost, 0)
//new desired_result.result_type(src.loc)
var/atom/O = new desired_result.result_type(src.loc)
O.color = species.silk_color
/mob/living/carbon/human/proc/set_silk_color()
set name = "Set Silk Color"
set category = "Abilities.Weaver"
if(!(species.is_weaver))
to_chat(src, span_warning("You are not a weaver! How are you doing this? Tell a developer!"))
return
var/new_silk_color = tgui_color_picker(src, "Pick a color for your woven products:","Silk Color", species.silk_color)
if(new_silk_color)
species.silk_color = new_silk_color
/mob/living/carbon/human/proc/toggle_eye_glow()
set name = "Toggle Eye Glowing"
set category = "Abilities.General"
@@ -768,8 +623,6 @@
update_eyes()
to_chat(src, "Your eyes [species.has_glowing_eyes ? "are now" : "are no longer"] glowing.")
/mob/living/carbon/human/proc/enter_cocoon()
set name = "Spin Cocoon"
set category = "Abilities.Weaver"
@@ -24,9 +24,10 @@
is_genetrait = TRUE
hidden = FALSE
disability=EPILEPSY
activation_message="You get a headache."
primitive_expression_messages=list("shudders and twitches.")
added_component_path = /datum/component/epilepsy_disability
/datum/trait/negative/disability_cough
name = "Coughing Fits"
@@ -37,8 +38,8 @@
is_genetrait = TRUE
hidden = FALSE
disability=COUGHING
activation_message="You start coughing."
added_component_path = /datum/component/coughing_disability
/datum/trait/negative/disability_clumsy
name = "Clumsy"
@@ -49,7 +50,6 @@
is_genetrait = TRUE
hidden = FALSE
mutation=CLUMSY
activation_message="You feel lightheaded."
primitive_expression_messages=list("trips.")
@@ -62,9 +62,9 @@
is_genetrait = FALSE //VOREStation Note: TRAITGENETICS - Disabled on VS
hidden = TRUE //VOREStation Note: TRAITGENETICS - Disabled on VS
disability=TOURETTES
activation_message="You twitch."
primitive_expression_messages=list("twitches and chitters.")
added_component_path = /datum/component/tourettes_disability
/* Replaced by /datum/trait/negative/blindness
/datum/trait/negative/disability_blind
@@ -165,9 +165,10 @@
is_genetrait = FALSE //VOREStation Note: TRAITGENETICS - Disabled on VS
hidden = TRUE //VOREStation Note: TRAITGENETICS - Disabled on VS
disability=DETERIORATE
activation_message="You feel sore..."
primitive_expression_messages=list("shudders.","gasps.","chokes.")
added_component_path = /datum/component/rotting_disability
/datum/trait/negative/disability_gibbing
name = "Gibbingtons"
@@ -178,9 +179,10 @@
is_genetrait = TRUE
hidden = TRUE
disability=GIBBING
activation_message="You feel bloated..."
primitive_expression_messages=list("shudders.","gasps.","chokes.")
added_component_path = /datum/component/gibbing_disability
/datum/trait/negative/disability_damagedspine
name = "Lumbar Impairment"
@@ -1441,10 +1441,11 @@
"tint" = list(TRAIT_PREF_TYPE_COLOR, "Statue color", TRAIT_NO_VAREDIT_TARGET, "#FFFFFF"),
"adjective" = list(TRAIT_PREF_TYPE_STRING, "Adjective", TRAIT_NO_VAREDIT_TARGET, "hardens")/*,
"pickupable" = list(TRAIT_PREF_TYPE_BOOLEAN, "Can be picked up", TRAIT_NO_VAREDIT_TARGET, FALSE)*/)
added_component_path = /datum/component/gargoyle
/datum/trait/neutral/gargoyle/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs)
..()
var/datum/component/gargoyle/G = H.LoadComponent(/datum/component/gargoyle)
var/datum/component/gargoyle/G = H.GetComponent(added_component_path)
if (trait_prefs)
G.tint = trait_prefs["tint"]
G.material = lowertext(trait_prefs["material"])
@@ -1479,7 +1480,6 @@
name = "Drippy"
desc = "You cannot hold your form together, or produce a constant film of sludge that drips off of your body. Hope the station has a janitor."
cost = 0
var_changes = list("drippy" = 1)
// Traitgenes Made into a genetrait
is_genetrait = TRUE
@@ -1487,6 +1487,7 @@
activation_message="You feel softer..."
primitive_expression_messages=list("drips.")
added_component_path = /datum/component/drippy
/datum/trait/neutral/mudking
name = "Mudking"
@@ -23,6 +23,6 @@
is_genetrait = TRUE
hidden = FALSE
disability=NERVOUS
activation_message="You feel nervous."
primitive_expression_messages=list("nervously chitters.")
added_component_path = /datum/component/nervousness_disability
@@ -190,19 +190,20 @@
name = "Weaver"
desc = "You can produce silk and create various articles of clothing and objects."
cost = 2
var_changes = list("is_weaver" = 1)
allowed_species = list(SPECIES_HANNER, SPECIES_CUSTOM) //So it only shows up for custom species and hanner
custom_only = FALSE
has_preferences = list("silk_production" = list(TRAIT_PREF_TYPE_BOOLEAN, "Silk production on spawn", TRAIT_VAREDIT_TARGET_SPECIES), \
"silk_color" = list(TRAIT_PREF_TYPE_COLOR, "Silk color", TRAIT_VAREDIT_TARGET_SPECIES))
has_preferences = list("silk_production" = list(TRAIT_PREF_TYPE_BOOLEAN, "Silk production on spawn", TRAIT_NO_VAREDIT_TARGET), \
"silk_color" = list(TRAIT_PREF_TYPE_COLOR, "Silk color", TRAIT_NO_VAREDIT_TARGET))
added_component_path = /datum/component/weaver
/datum/trait/positive/weaver/apply(var/datum/species/S,var/mob/living/carbon/human/H)
/datum/trait/positive/weaver/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs)
..()
add_verb(H, /mob/living/carbon/human/proc/check_silk_amount)
add_verb(H, /mob/living/carbon/human/proc/toggle_silk_production)
add_verb(H, /mob/living/carbon/human/proc/weave_structure)
add_verb(H, /mob/living/carbon/human/proc/weave_item)
add_verb(H, /mob/living/carbon/human/proc/set_silk_color)
var/datum/component/weaver/W = H.GetComponent(added_component_path)
if(S.get_bodytype() == SPECIES_VASILISSAN)
W.silk_reserve = 500
W.silk_max_reserve = 1000
W.silk_production = trait_prefs["silk_production"]
W.silk_color = lowertext(trait_prefs["silk_color"])
/datum/trait/positive/aquatic
name = "Aquatic"
@@ -16,6 +16,7 @@
var/varchange_type = TRAIT_VARCHANGE_ALWAYS_OVERRIDE //Mostly used for non-custom species.
var/has_preferences //if set, should be a list of the preferences for this trait in the format: list("identifier/name of var to edit" = list(typeofpref, "text to display in prefs", TRAIT_NO_VAREDIT_TARGET/TRAIT_VAREDIT_TARGET_SPECIES/etc, (optional: default value)), etc) typeofpref should follow the defines in _traits.dm (eg. TRAIT_PREF_TYPE_BOOLEAN)
var/special_env = FALSE
var/added_component_path //What component this trait applies, if any.
@@ -73,6 +74,8 @@
add_verb(H, /mob/living/carbon/human/proc/trait_tutorial)
if(special_env)
S.env_traits += src
if(added_component_path)
H.AddComponent(added_component_path)
return
// Traitgenes Disabling traits, genes can be turned off after all!
@@ -102,6 +105,10 @@
H.sdisabilities &= ~sdisability // bitflag
if(special_env)
S.env_traits -= src
if(added_component_path)
var/datum/component/C = H.GetComponent(added_component_path)
if(C)
qdel(C)
return
/datum/trait/proc/send_message(var/mob/living/carbon/human/H, var/enabled)
@@ -57,10 +57,9 @@
icon_state = pick(possible_icon_states)
/obj/effect/weaversilk/wall/CanPass(atom/movable/mover, turf/target)
if(ishuman(mover))
var/mob/living/carbon/human/H = mover
if(H.species.is_weaver)
return TRUE
var/datum/component/weaver/comp = mover.GetComponent(/datum/component/weaver)
if(comp)
return
..()
/obj/structure/bed/double/weaversilk_nest
@@ -94,10 +93,9 @@
/obj/effect/weaversilk/trap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
if(H.species.is_weaver)
return
var/datum/component/weaver/comp = AM.GetComponent(/datum/component/weaver)
if(comp)
return
if(isliving(AM) && trap_active)
var/mob/living/L = AM
if(L.m_intent == I_RUN)
+3 -2
View File
@@ -2,6 +2,8 @@
set invisibility = INVISIBILITY_NONE
set background = BACKGROUND_ENABLED
SEND_SIGNAL(src, COMSIG_LIVING_LIFE)
..()
if (transforming)
@@ -84,8 +86,6 @@
handle_tf_holder()
handle_dripping()
handle_vr_derez()
/mob/living/proc/handle_breathing()
@@ -203,6 +203,7 @@
return confused
/mob/living/proc/handle_disabilities()
SEND_SIGNAL(src, COMSIG_HANDLE_DISABILITIES)
//Eyes
if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
SetBlinded(1)
-44
View File
@@ -1456,50 +1456,6 @@
if(toggled_sleeping)
Sleeping(1)
/mob/living/proc/handle_dripping()
if(prob(95))
return
if(!isturf(src.loc))
return
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.species && H.species.drippy)
// drip body color if human
var/obj/effect/decal/cleanable/blood/B
var/decal_type = /obj/effect/decal/cleanable/blood/splatter
var/turf/T = get_turf(src.loc)
// Are we dripping or splattering?
var/list/drips = list()
// Only a certain number of drips (or one large splatter) can be on a given turf.
for(var/obj/effect/decal/cleanable/blood/drip/drop in T)
drips |= drop.drips
qdel(drop)
if(drips.len < 6)
decal_type = /obj/effect/decal/cleanable/blood/drip
// Find a blood decal or create a new one.
B = locate(decal_type) in T
if(!B)
B = new decal_type(T)
var/obj/effect/decal/cleanable/blood/drip/drop = B
if(istype(drop) && drips && drips.len)
drop.add_overlay(drips)
drop.drips |= drips
// Update appearance.
drop.basecolor = rgb(H.r_skin,H.g_skin,H.b_skin)
drop.update_icon()
drop.name = "drips of something"
drop.desc = "It's thick and gooey. Perhaps it's the chef's cooking?"
drop.dryname = "dried something"
drop.drydesc = "It's dry and crusty. The janitor isn't doing their job."
drop.fluorescent = 0
drop.invisibility = INVISIBILITY_NONE
//else
// come up with drips for other mobs someday
/mob/living/proc/set_metainfo_favs(var/mob/user, var/reopen = TRUE)
if(user != src)
return