From 195aa07b3ac45847f8a4acba76d1334a36afe9a8 Mon Sep 17 00:00:00 2001 From: SatinIsle <98125273+SatinIsle@users.noreply.github.com> Date: Sat, 26 Jul 2025 14:41:12 +0100 Subject: [PATCH] Unexpected Alraune Love (#18077) Spruced up some flavourful abilities for alraune. Added a new "Poison Fruit" ability to Alraune. It applies any poison that can be used by the injecting venom ability to fruit grown from the Alraune. There is a notice attached to the selection that states this is intended for scenes and to not leave the poisoned fruit out for people who do not OOC consent, as well as admin logging when this fruit is produced. Added a new thorns ability for alraune that will cause anyone touching them, or simple mobs attacking them, to take a small amount of brute damage. This starts off and can be toggled off and on at will. Added variables to seed harvesting so that code can force them to spawn with specific reagents inside. Allowed alraune to change the type of fruit they spawn more than once. --- code/__defines/species_traits.dm | 1 + code/modules/hydroponics/seed.dm | 5 +- code/modules/mob/living/carbon/carbon.dm | 10 ++++ .../living/carbon/human/human_attackhand.dm | 8 +++ .../carbon/human/species/station/alraune.dm | 56 ++++++++++++++++++- code/modules/mob/living/living_defense.dm | 15 +++++ code/modules/mob/living/living_powers.dm | 12 ++++ 7 files changed, 103 insertions(+), 4 deletions(-) diff --git a/code/__defines/species_traits.dm b/code/__defines/species_traits.dm index 8b44872b4e7..2e83746f02a 100644 --- a/code/__defines/species_traits.dm +++ b/code/__defines/species_traits.dm @@ -4,3 +4,4 @@ #define SPECIES_TRAIT_PATTING_DEFENCE 1 #define SPECIES_TRAIT_PERSONAL_BUBBLE 2 +#define SPECIES_TRAIT_THORNS 4 diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index f3e9aa66d53..ca6165beafa 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -767,7 +767,7 @@ return (P ? P : 0) //Place the plant products at the feet of the user. -/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount) +/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount,var/reagent_mod,var/reagent_mod_amount) if(!user) return @@ -824,6 +824,9 @@ var/obj/item/reagent_containers/food/food = product food.filling_color = get_trait(TRAIT_PRODUCT_COLOUR) + if(reagent_mod && reagent_mod_amount) + product.reagents.add_reagent(reagent_mod,reagent_mod_amount) + if(mysterious) product.name += "?" product.desc += " On second thought, something about this one looks strange." diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 22fe0c7a240..33b4bc7e38a 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -53,7 +53,17 @@ ..() /mob/living/carbon/attack_hand(mob/M as mob) + if(touch_reaction_flags & SPECIES_TRAIT_THORNS) + if(src != M) + if(istype(M,/mob/living)) + var/mob/living/L = M + L.apply_damage(3, BRUTE) + L.visible_message( \ + span_warning("[L] is hurt by sharp body parts when touching [src]!"), \ + span_warning("[src] is covered in sharp bits and it hurt when you touched them!"), ) + if(!istype(M, /mob/living/carbon)) return + if (ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/temp = H.organs_by_name[BP_R_HAND] diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 35fbac84712..f9bd220d864 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -417,6 +417,14 @@ return /mob/living/carbon/human/attack_generic(var/mob/user, var/damage, var/attack_message, var/armor_type = "melee", var/armor_pen = 0, var/a_sharp = 0, var/a_edge = 0) + if(istype(user,/mob/living)) + var/mob/living/L = user + if(touch_reaction_flags & SPECIES_TRAIT_THORNS) + if((src != L)) + L.apply_damage(3, BRUTE) + L.visible_message( \ + span_warning("[L] is hurt by sharp body parts when touching [src]!"), \ + span_warning("[src] is covered in sharp bits and it hurt when you touched them!"), ) if(!damage) return diff --git a/code/modules/mob/living/carbon/human/species/station/alraune.dm b/code/modules/mob/living/carbon/human/species/station/alraune.dm index 3c344f76579..9ddebfedc44 100644 --- a/code/modules/mob/living/carbon/human/species/station/alraune.dm +++ b/code/modules/mob/living/carbon/human/species/station/alraune.dm @@ -48,7 +48,8 @@ appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR inherent_verbs = list(/mob/living/carbon/human/proc/alraune_fruit_select, //Give them the voremodes related to wrapping people in vines and sapping their fluids - /mob/living/carbon/human/proc/tie_hair) + /mob/living/carbon/human/proc/tie_hair, + /mob/living/proc/toggle_thorns) color_mult = 1 icobase = 'icons/mob/human_races/r_human_vr.dmi' @@ -351,6 +352,21 @@ var/fruit_type = PLANT_APPLE var/mob/living/organ_owner = null var/gen_cost = 0.5 + var/poison_reagent + + var/list/poison_options = list( + REAGENT_ID_MICROCILLIN, + REAGENT_ID_MACROCILLIN, + REAGENT_ID_NORMALCILLIN, + REAGENT_ID_NUMBENZYME, + REAGENT_ID_ANDROROVIR, + REAGENT_ID_GYNOROVIR, + REAGENT_ID_ANDROGYNOROVIR, + REAGENT_ID_STOXIN, + REAGENT_ID_RAINBOWTOXIN, + REAGENT_ID_PARALYSISTOXIN, + REAGENT_ID_PAINENZYME + ) /obj/item/organ/internal/fruitgland/Initialize(mapload, internal) . = ..() @@ -394,7 +410,8 @@ if(selection) fruit_gland.fruit_type = selection add_verb(src, /mob/living/carbon/human/proc/alraune_fruit_pick) - remove_verb(src, /mob/living/carbon/human/proc/alraune_fruit_select) + add_verb(src, /mob/living/carbon/human/proc/alraune_fruit_reagent) +// remove_verb(src, /mob/living/carbon/human/proc/alraune_fruit_select) //We are allowing them to switch fruits now. fruit_gland.organ_owner = src fruit_gland.emote_descriptor = list("fruit right off of [fruit_gland.organ_owner]!", "a fruit from [fruit_gland.organ_owner]!") @@ -426,7 +443,12 @@ return var/datum/seed/S = SSplants.seeds["[fruit_gland.fruit_type]"] - S.harvest(usr,0,0,1) + + if(fruit_gland.poison_reagent) + S.harvest(usr,0,0,1,fruit_gland.poison_reagent,10) + log_admin("[src] played by [src.ckey] has produced a fruit containing [fruit_gland.poison_reagent]. It was picked by [usr].") + else + S.harvest(usr,0,0,1) var/index = rand(0,2) @@ -442,6 +464,34 @@ fruit_gland.reagents.remove_any(fruit_gland.transfer_amount) +/mob/living/carbon/human/proc/alraune_fruit_reagent() + set name = "Poison Fruit" + set desc = "Select a reagent to be placed in your fruit." + set category = "Abilities.Alraune" + + if(!isliving(usr) || !usr.checkClickCooldown()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/organ/internal/fruitgland/fruit_gland + for(var/I in contents) + if(istype(I, /obj/item/organ/internal/fruitgland)) + fruit_gland = I + break + + if(fruit_gland) + var/poison_choice = tgui_input_list(src, "Choose which reagent to poison your fruit with! Be aware, this option is intended for use in scenes and ERP. This is not for use as pranks or to change the gender of unsuspecting crew, and you must be aware of the preferences of the people who eat it. Do not just leave it out unattended.", "Select reagent", fruit_gland.poison_options) + if(!poison_choice) + to_chat(src, span_notice("You have chosen no poison to add, any previously chosen poisons have been cleared and no poison will be added to produced fruits.")) + fruit_gland.poison_reagent = null + return + else + fruit_gland.poison_reagent = poison_choice + to_chat(src, span_notice("Fruit that you produce will now contain [poison_choice]. Be aware of out of character consent.")) + return + //End of fruit gland code. /datum/species/alraune/get_race_key() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 9192157009a..db7c4d6974a 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -98,6 +98,12 @@ if(istype(L) && L.a_intent != I_HELP) if(ai_holder) // Using disarm, grab, or harm intent is considered a hostile action to the mob's AI. ai_holder.react_to_attack(L) + if(touch_reaction_flags & SPECIES_TRAIT_THORNS) + if(src != L) + L.apply_damage(3, BRUTE) + L.visible_message( \ + span_warning("[L] is hurt by sharp body parts when touching [src]!"), \ + span_warning("[src] is covered in sharp bits and it hurt when you touched them!"), ) /mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone) @@ -393,6 +399,15 @@ // End BS12 momentum-transfer code. /mob/living/attack_generic(var/mob/user, var/damage, var/attack_message) + if(istype(user,/mob/living)) + var/mob/living/L = user + if(touch_reaction_flags & SPECIES_TRAIT_THORNS) + if((src != L)) + L.apply_damage(3, BRUTE) + L.visible_message( \ + span_warning("[L] is hurt by sharp body parts when touching [src]!"), \ + span_warning("[src] is covered in sharp bits and it hurt when you touched them!"), ) + if(!damage) return diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm index 41a90a55ce1..bf5d66746c1 100644 --- a/code/modules/mob/living/living_powers.dm +++ b/code/modules/mob/living/living_powers.dm @@ -55,6 +55,18 @@ touch_reaction_flags |= SPECIES_TRAIT_PERSONAL_BUBBLE to_chat(src,span_notice("You will now dodge all attempts at hugging, patting, booping, licking, smelling and hand shaking.")) +/mob/living/proc/toggle_thorns() + set name = "Toggle Thorns" + set desc = "Toggles defensive thorns across your body." + set category = "Abilities.General" + + if(touch_reaction_flags & SPECIES_TRAIT_THORNS) + touch_reaction_flags &= ~(SPECIES_TRAIT_THORNS) + to_chat(src,span_notice("You will no longer be covered in defensive thorns.")) + else + touch_reaction_flags |= SPECIES_TRAIT_THORNS + to_chat(src,span_notice("You will now be covered in defensive thorns that may hurt those who touch you.")) + /mob/living/proc/toggle_sparkles() set name = "Toggle Sparkles" set desc = "Toggle fancy glowing sparkles!"