Skip to content

Commit

Permalink
ports some tg botany code to fix novaflowers (shiptest-ss13#3063)
Browse files Browse the repository at this point in the history
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->
novaflowers werent applying firestacks so i ported a ton of botany code.
novaflowers and nettles now use genes for there pickup and attack stuff
clothing traits that only botany gloves use rn

tgstation/tgstation#59107
tgstation/tgstation#56233
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
better code c:
<!-- Please add a short description of why you think these changes would
benefit the game. If you can't justify it in words, it might not be
worth adding. -->

:cl: FalloutFalcon, MrMelbert, Coiax
code: ported alot tg botany code along with gene desc and icons to be
used more soon
refactor: moves most plant effects into genetics stuff
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Co-authored-by: Sun-Soaked <[email protected]>
  • Loading branch information
2 people authored and MysticalFaceLesS committed Sep 11, 2024
1 parent 8f515c3 commit b5ec977
Show file tree
Hide file tree
Showing 24 changed files with 1,216 additions and 333 deletions.
21 changes: 21 additions & 0 deletions code/__DEFINES/botany.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,24 @@

//Floral Somoray
#define REVOLUTION_CHARGE 10000 // Default flora cell

/// -- Trait IDs. Plants that match IDs cannot be added to the same plant. --
/// Plants that glow.
#define GLOW_ID (1<<0)
/// Plant types.
#define PLANT_TYPE_ID (1<<1)
/// Plants that affect the reagent's temperature.
#define TEMP_CHANGE_ID (1<<2)
/// Plants that affect the reagent contents.
#define CONTENTS_CHANGE_ID (1<<3)
/// Plants that do something special when they impact.
#define THROW_IMPACT_ID (1<<4)
/// Plants that transfer reagents on impact.
#define REAGENT_TRANSFER_ID (1<<5)
/// Plants that have a unique effect on attack_self.
#define ATTACK_SELF_ID (1<<6)

#define HYDROTRAY_NO_PLANT "missing"
#define HYDROTRAY_PLANT_DEAD "dead"
#define HYDROTRAY_PLANT_GROWING "growing"
#define HYDROTRAY_PLANT_HARVESTABLE "harvestable"
39 changes: 39 additions & 0 deletions code/__DEFINES/clothing.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
//stages of shoe tying-ness
/// Shoes are untied
#define SHOES_UNTIED 0
/// Shoes are tied normally
#define SHOES_TIED 1
/// Shoes have been tied in knots
#define SHOES_KNOTTED 2
//suit sensors: sensor_mode defines
/// Suit sensor is turned off
#define SENSOR_OFF 0
/// Suit sensor displays the mob as alive or dead
#define SENSOR_LIVING 1
/// Suit sensor displays the mob damage values
#define SENSOR_VITALS 2
/// Suit sensor displays the mob damage values and exact location
#define SENSOR_COORDS 3
//suit sensors: has_sensor defines
/// Suit sensor has been EMP'd and cannot display any information (can be fixed)
#define BROKEN_SENSORS -1
/// Suit sensor is not present and cannot display any information
#define NO_SENSORS 0
/// Suit sensor is present and can display information
#define HAS_SENSORS 1
/// Suit sensor is present and is forced to display information (used on prisoner jumpsuits)
#define LOCKED_SENSORS 2
*/

/// Wrapper for adding clothing based traits
#define ADD_CLOTHING_TRAIT(mob, trait) ADD_TRAIT(mob, trait, "[CLOTHING_TRAIT]_[REF(src)]")
/// Wrapper for removing clothing based traits
#define REMOVE_CLOTHING_TRAIT(mob, trait) REMOVE_TRAIT(mob, trait, "[CLOTHING_TRAIT]_[REF(src)]")

/*
/// How much integrity does a shirt lose every time we bite it?
#define MOTH_EATING_CLOTHING_DAMAGE 15
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//Plants / Plant Traits

///called when a plant with slippery skin is slipped on (mob/victim)
#define COMSIG_PLANT_ON_SLIP "plant_on_slip"
///called when a plant with liquid contents is squashed on (atom/target)
#define COMSIG_PLANT_ON_SQUASH "plant_on_squash"
///called when a plant backfires via the backfire element (mob/victim)
#define COMSIG_PLANT_ON_BACKFIRE "plant_on_backfire"
///called when a seed grows in a tray (obj/machinery/hydroponics)
#define COMSIG_SEED_ON_GROW "plant_on_grow"
///called when a seed is planted in a tray (obj/machinery/hydroponics)
#define COMSIG_SEED_ON_PLANTED "plant_on_plant"

//Hydro tray
///from base of /obj/machinery/hydroponics/set_seed() : (obj/item/new_seed)
#define COMSIG_HYDROTRAY_SET_SEED "hydrotray_set_seed"
///from base of /obj/machinery/hydroponics/set_self_sustaining() : (new_value)
#define COMSIG_HYDROTRAY_SET_SELFSUSTAINING "hydrotray_set_selfsustaining"
///from base of /obj/machinery/hydroponics/set_weedlevel() : (new_value)
#define COMSIG_HYDROTRAY_SET_WEEDLEVEL "hydrotray_set_weedlevel"
///from base of /obj/machinery/hydroponics/set_pestlevel() : (new_value)
#define COMSIG_HYDROTRAY_SET_PESTLEVEL "hydrotray_set_pestlevel"
///from base of /obj/machinery/hydroponics/set_waterlevel() : (new_value)
#define COMSIG_HYDROTRAY_SET_WATERLEVEL "hydrotray_set_waterlevel"
///from base of /obj/machinery/hydroponics/set_plant_health() : (new_value)
#define COMSIG_HYDROTRAY_SET_PLANT_HEALTH "hydrotray_set_plant_health"
///from base of /obj/machinery/hydroponics/set_toxic() : (new_value)
#define COMSIG_HYDROTRAY_SET_TOXIC "hydrotray_set_toxic"
///from base of /obj/machinery/hydroponics/set_plant_status() : (new_value)
#define COMSIG_HYDROTRAY_SET_PLANT_STATUS "hydrotray_set_plant_status"
///from base of /obj/machinery/hydroponics/update_tray() : (mob/user, product_count)
#define COMSIG_HYDROTRAY_ON_HARVEST "hydrotray_on_harvest"
///from base of /obj/machinery/hydroponics/plantdies()
#define COMSIG_HYDROTRAY_PLANT_DEATH "hydrotray_plant_death"
11 changes: 9 additions & 2 deletions code/__DEFINES/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,16 @@
#define MACHINE_ELECTRIFIED_PERMANENT -1
#define MACHINE_DEFAULT_ELECTRIFY_TIME 30

//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified.
/// -- Flags for genes --
/// Plant genes that can be removed via gene shears.
#define PLANT_GENE_REMOVABLE (1<<0)
#define PLANT_GENE_EXTRACTABLE (1<<1)
/// Plant genes that can be mutated randomly in strange seeds / due to high instability.
#define PLANT_GENE_MUTATABLE (1<<1)
#define PLANT_GENE_EXTRACTABLE (1<<2)

/// -- Flags for traits. --
/// Caps the plant's yield at 5 instead of 10.
#define TRAIT_HALVES_YIELD (1<<0)

//used to determine what rotation mode the ore redemption machine is in
#define ORM_BOTH 0
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_SCOOPABLE "scoopable"
//your smooches actually deal damage to their target
#define TRAIT_KISS_OF_DEATH "kiss_of_death"
/// We can handle 'dangerous' plants in botany safely
#define TRAIT_PLANT_SAFE "plant_safe"
/// This mob overrides certian SSlag_switch measures with this special trait
#define TRAIT_BYPASS_MEASURES "bypass_lagswitch_measures"
//non-mob traits
Expand Down
4 changes: 2 additions & 2 deletions code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
// [CELADON-ADD] - CELADON_ACHIEVEMENTS
"TRAIT_ELITE_CHALLENGER" = TRAIT_ELITE_CHALLENGER, // CELADON EDIT // Given to elite tumor fighters
// [/CELADON-ADD]
"TRAIT_KISS_OF_DEATH" = TRAIT_KISS_OF_DEATH

"TRAIT_KISS_OF_DEATH" = TRAIT_KISS_OF_DEATH,
"TRAIT_PLANT_SAFE" = TRAIT_PLANT_SAFE,
),
/obj/item/bodypart = list(
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS
Expand Down
125 changes: 125 additions & 0 deletions code/datums/elements/plant_backfire.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/// -- Plant backfire element --
/// Certain high-danger plants, like death-nettles, will backfire and harm the holder if they're not properly protected.
/// If a user is protected with something like leather gloves, they can handle them normally.
/// If they're not protected properly, we invoke a callback on the user, harming or inconveniencing them.
/datum/element/plant_backfire
element_flags = ELEMENT_BESPOKE
id_arg_index = 2
/// Whether we stop the current action if backfire is triggered (EX: returning CANCEL_ATTACK_CHAIN)
var/cancel_action = FALSE
/// Any extra traits we want to check in addition to TRAIT_PLANT_SAFE. Mobs with a trait in this list will be considered safe. List of traits.
var/extra_traits
/// Any plant genes we want to check that are required for our plant to be dangerous. Plants without a gene in this list will be considered safe. List of typepaths.
var/extra_genes

/datum/element/plant_backfire/Attach(datum/target, cancel_action = FALSE, extra_traits, extra_genes)
. = ..()
if(!isitem(target))
return ELEMENT_INCOMPATIBLE

src.cancel_action = cancel_action
src.extra_traits = extra_traits
src.extra_genes = extra_genes

RegisterSignal(target, COMSIG_ITEM_PRE_ATTACK, PROC_REF(attack_safety_check))
RegisterSignal(target, COMSIG_ITEM_PICKUP, PROC_REF(pickup_safety_check))
RegisterSignal(target, COMSIG_MOVABLE_PRE_THROW, PROC_REF(throw_safety_check))

/datum/element/plant_backfire/Detach(datum/target)
. = ..()
UnregisterSignal(target, list(COMSIG_ITEM_PRE_ATTACK, COMSIG_ITEM_PICKUP, COMSIG_MOVABLE_PRE_THROW))

/**
* Checks before we attack if we're okay to continue.
*
* source - our plant
* user - the mob wielding our [source]
*/
/datum/element/plant_backfire/proc/attack_safety_check(obj/item/source, atom/target, mob/user)
SIGNAL_HANDLER

// Covers stuff like tk, since we aren't actually touching the plant.
if(!user.is_holding(source))
return
if(!backfire(source, user))
return

return //cancel_action ? COMPONENT_CANCEL_ATTACK_CHAIN : NONE

/**
* Checks before we pick up the plant if we're okay to continue.
*
* source - our plant
* user - the mob picking our [source]
*/
/datum/element/plant_backfire/proc/pickup_safety_check(obj/item/source, mob/user)
SIGNAL_HANDLER

backfire(source, user)

/**
* Checks before we throw the plant if we're okay to continue.
*
* source - our plant
* thrower - the mob throwing our [source]
*/
/datum/element/plant_backfire/proc/throw_safety_check(obj/item/source, list/arguments)
SIGNAL_HANDLER

var/mob/living/thrower = arguments[4] // the 4th arg = the mob throwing our item
if(!istype(thrower) || !thrower.is_holding(source))
return
if(!backfire(source, thrower))
return

return //cancel_action ? COMPONENT_CANCEL_ATTACK_CHAIN : NONE

/**
* The actual backfire occurs here.
* Checks if the user is able to safely handle the plant.
* If not, sends the backfire signal (meaning backfire will occur and be handled by one or multiple genes).
*
* Returns FALSE if the user was safe and no backfire occured.
* Returns TRUE if the user was not safe and a backfire actually happened.
*/
/datum/element/plant_backfire/proc/backfire(obj/item/plant, mob/user)
if(plant_safety_check(plant, user))
return FALSE

SEND_SIGNAL(plant, COMSIG_PLANT_ON_BACKFIRE, user)
return TRUE

/**
* Actually checks if our user is safely handling our plant.
*
* Checks for TRAIT_PLANT_SAFE, and returns TRUE if we have it.
* Then, any extra traits we need to check (Like TRAIT_PIERCEIMMUNE for nettles) and returns TRUE if we have one of them.
* Then, any extra genes we need to check (Like liquid contents for bluespace tomatos) and returns TRUE if we don't have the gene.
*
* source - our plant
* user - the carbon handling our [source]
*
* returns FALSE if none of the checks are successful.
*/
/datum/element/plant_backfire/proc/plant_safety_check(obj/item/plant, mob/living/carbon/user)
if(!istype(user))
return TRUE

if(HAS_TRAIT(user, TRAIT_PLANT_SAFE))
return TRUE

for(var/checked_trait in extra_traits)
if(HAS_TRAIT(user, checked_trait))
return TRUE

var/obj/item/seeds/our_seed = plant.get_plant_seed()
if(our_seed)
for(var/checked_gene in extra_genes)
if(!our_seed.get_gene(checked_gene))
return TRUE

for(var/obj/item/clothing/worn_item in user.get_equipped_items())
if((worn_item.body_parts_covered & HANDS) && (worn_item.clothing_flags & THICKMATERIAL))
return TRUE

return FALSE
42 changes: 42 additions & 0 deletions code/modules/clothing/clothing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
/// If this can be eaten by a moth
var/moth_edible = TRUE

// Not used yet
/// Trait modification, lazylist of traits to add/take away, on equipment/drop in the correct slot
var/list/clothing_traits

/obj/item/clothing/Initialize()
if((clothing_flags & VOICEBOX_TOGGLABLE))
actions_types += /datum/action/item_action/toggle_voice_box
Expand Down Expand Up @@ -111,6 +115,8 @@
..()
if(!istype(user))
return
for(var/trait in clothing_traits)
REMOVE_CLOTHING_TRAIT(user, trait)
if(LAZYLEN(user_vars_remembered))
for(var/variable in user_vars_remembered)
if(variable in user.vars)
Expand All @@ -123,12 +129,48 @@
if (!istype(user))
return
if(slot_flags & slot) //Was equipped to a valid slot for this item?
for(var/trait in clothing_traits)
ADD_CLOTHING_TRAIT(user, trait)
if (LAZYLEN(user_vars_to_edit))
for(var/variable in user_vars_to_edit)
if(variable in user.vars)
LAZYSET(user_vars_remembered, variable, user.vars[variable])
user.vv_edit_var(variable, user_vars_to_edit[variable])

/**
* Inserts a trait (or multiple traits) into the clothing traits list
*
* If worn, then we will also give the wearer the trait as if equipped
*
* This is so you can add clothing traits without worrying about needing to equip or unequip them to gain effects
*/
/obj/item/clothing/proc/attach_clothing_traits(trait_or_traits)
if(!islist(trait_or_traits))
trait_or_traits = list(trait_or_traits)

LAZYOR(clothing_traits, trait_or_traits)
var/mob/wearer = loc
if(istype(wearer) && (wearer.get_slot_by_item(src) & slot_flags))
for(var/new_trait in trait_or_traits)
ADD_CLOTHING_TRAIT(wearer, new_trait)

/**
* Removes a trait (or multiple traits) from the clothing traits list
*
* If worn, then we will also remove the trait from the wearer as if unequipped
*
* This is so you can add clothing traits without worrying about needing to equip or unequip them to gain effects
*/
/obj/item/clothing/proc/detach_clothing_traits(trait_or_traits)
if(!islist(trait_or_traits))
trait_or_traits = list(trait_or_traits)

LAZYREMOVE(clothing_traits, trait_or_traits)
var/mob/wearer = loc
if(istype(wearer))
for(var/new_trait in trait_or_traits)
REMOVE_CLOTHING_TRAIT(wearer, new_trait)

/obj/item/clothing/examine(mob/user)
. = ..()
switch (max_heat_protection_temperature)
Expand Down
3 changes: 2 additions & 1 deletion code/modules/clothing/gloves/miscellaneous.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = NONE
clothing_traits = list(TRAIT_PLANT_SAFE)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 30)

/obj/item/clothing/gloves/combat
Expand Down Expand Up @@ -125,7 +126,7 @@
name = "explorer envirogloves"
icon_state = "explorerplasma"

/obj/item/clothing/gloves/color/botanic_leather/plasmaman
/obj/item/clothing/gloves/botanic_leather/plasmaman
name = "botany envirogloves"
desc = "Covers up those scandalous boney hands."
icon_state = "botanyplasma"
Expand Down
2 changes: 1 addition & 1 deletion code/modules/clothing/outfits/plasmaman.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

head = /obj/item/clothing/head/helmet/space/plasmaman/botany
uniform = /obj/item/clothing/under/plasmaman/botany
gloves = /obj/item/clothing/gloves/color/botanic_leather/plasmaman
gloves = /obj/item/clothing/gloves/botanic_leather/plasmaman

/datum/outfit/plasmaman/curator
name = "Curator Plasmaman"
Expand Down
1 change: 0 additions & 1 deletion code/modules/hydroponics/gene_modder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@
seed.genes += disk.gene.Copy()
if(istype(disk.gene, /datum/plant_gene/reagent))
seed.reagents_from_genes()
disk.gene.apply_vars(seed)
repaint_seed()


Expand Down
Loading

0 comments on commit b5ec977

Please sign in to comment.