mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
## About The Pull Request Over half of the line changes are merely from splitting the fish_types.dm into several files since it was over 1k lines already. One of the small issues with fishing right now is RNG. You want to get some specific fish, and you go through all the micromanaging with hooks, reels and baits only for the random number god to say "nope", and that's only going to get worse the more fish are in the game. However, I've a solution: (unconsumable/reusable) fishing lures, each of which attracts different fish based on different conditions. The only caveat is that they require to be spun at set intervals (usually 1 to 3 seconds, depending on the lure, with a second-long window). Worry not, there're visual cues in the form of a green/red light hovering the fishing float, so you won't get screwed up by the server slowing down or whatever. The whole box of lures (12 so far) can be from cargo for the fair price of 450 credits. I've also added 5 new fish: monkfish, plaice, pike, another punnier variant of the pike, perch and squid. The latter is quite special because of the ink production trait, which lets players use it to blind others at a close range and when butchered, it yields an ink sac, which can be processed into a can of squid ink (one less item exclusive to the produce console), or thrown at people in a sort-of-similar fashion of banana cream pies (except it's ink). <details> <summary>Images</summary> Fishing lures (forgot to take my cursor off the veggie one before the screenshot):  The five new fish:  </details> <details> <summary>A table of fish catchable wth each lure (excluding holodeck)</summary>  </details> A few more things in the CL, baitfish are a thing now. ## Why It's Good For The Game There should be ways to contrast some of the RNG fishing has. After all, it's only going to get more random the more fish are in the game. Furthermore, I find it disappointing that a lot of food stuff is exclusive to the ingredients console and there're no other ways to get it. ## Changelog 🆑 add: Added fishing lures to the game. They don't get used up like baits and let you catch specific kinds of fish, though they need to be spun every few seconds. The whole set can be ordered from cargo for 450 credits. balance: The magnet hook now removes dud chances. add: Added five new fish types: perch, two types of pike, monkfish, plaice and squid. Squids have a fairly special ink production trait, which lets you use them (unless dead) to ink people face at close range, and can be butchered for an ink sac, which can either be processed into canned squid ink, or thrown at someone. fix: Refactored throwing a little. Some items (specifically components/elements) won't be triggered when caught. no more plates shattering despite being caught for example. add: Goldfish, lavaloops, needlefish and armorfish can now be used as baits. /🆑
955 lines
35 KiB
Plaintext
955 lines
35 KiB
Plaintext
/// Plant gene datums - things that build and modify a plant or seed.
|
|
/datum/plant_gene
|
|
/// The name of the gene.
|
|
var/name
|
|
/// The font awesome icon name representing the gene in the seed extractor UI
|
|
var/icon = "dna"
|
|
/// Flags that determine if a gene can be modified.
|
|
var/mutability_flags
|
|
|
|
/*
|
|
* Returns the formatted name of the plant gene.
|
|
*
|
|
* Overridden by the various subtypes of plant genes to format their respective names.
|
|
*/
|
|
/datum/plant_gene/proc/get_name()
|
|
return name
|
|
|
|
/*
|
|
* Check if the seed can accept this plant gene.
|
|
*
|
|
* our_seed - the seed we're adding the gene to
|
|
*
|
|
* Returns TRUE if the seed can take the gene, and FALSE otherwise.
|
|
*/
|
|
/datum/plant_gene/proc/can_add(obj/item/seeds/our_seed)
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
return TRUE
|
|
|
|
/// Copies over vars and information about our current gene to a new gene and returns the new instance of gene.
|
|
/datum/plant_gene/proc/Copy()
|
|
var/datum/plant_gene/new_gene = new type
|
|
new_gene.mutability_flags = mutability_flags
|
|
return new_gene
|
|
|
|
/*
|
|
* on_new_seed is called when seed genes are initialized on the /obj/seed.
|
|
*
|
|
* new_seed - the seed being created
|
|
*/
|
|
/datum/plant_gene/proc/on_new_seed(obj/item/seeds/new_seed)
|
|
return // Not implemented
|
|
|
|
/*
|
|
* on_removed is called when the gene is removed from a seed.
|
|
* Also called when a seed is qdel'd (and all the genes are removed and deleted).
|
|
*
|
|
* old_seed - our seed, before being removed
|
|
*/
|
|
/datum/plant_gene/proc/on_removed(obj/item/seeds/old_seed)
|
|
return // Not implemented
|
|
|
|
/// Reagent genes store a reagent ID and reagent ratio.
|
|
/datum/plant_gene/reagent
|
|
name = "UNKNOWN"
|
|
mutability_flags = PLANT_GENE_REMOVABLE
|
|
/// The typepath of the actual reagent that this gene is tied to.
|
|
var/reagent_id = /datum/reagent/consumable/nutriment
|
|
/// The amount of reagent generated by the plant. The equation is [1 + ((max_volume*(potency/100)) * rate)]
|
|
var/rate = 0.04
|
|
|
|
/datum/plant_gene/reagent/get_name()
|
|
var/formatted_name
|
|
if(!(mutability_flags & PLANT_GENE_REMOVABLE))
|
|
formatted_name += "Fragile "
|
|
formatted_name += "[name] production [rate*100]%"
|
|
return formatted_name
|
|
|
|
/*
|
|
* Set our reagent's ID and name to the passed reagent.
|
|
*
|
|
* new_reagent_id - typepath of the reagent we're setting this gene to
|
|
*/
|
|
/datum/plant_gene/reagent/proc/set_reagent(new_reagent_id)
|
|
reagent_id = new_reagent_id
|
|
|
|
var/datum/reagent/found_reagent = GLOB.chemical_reagents_list[new_reagent_id]
|
|
if(found_reagent?.type == reagent_id)
|
|
name = found_reagent.name
|
|
|
|
/datum/plant_gene/reagent/New(new_reagent_id, new_reagent_rate = 0.04)
|
|
. = ..()
|
|
if(new_reagent_id)
|
|
set_reagent(new_reagent_id)
|
|
rate = new_reagent_rate
|
|
|
|
/datum/plant_gene/reagent/Copy()
|
|
. = ..()
|
|
var/datum/plant_gene/reagent/new_reagent_gene = .
|
|
new_reagent_gene.name = name
|
|
new_reagent_gene.reagent_id = reagent_id
|
|
new_reagent_gene.rate = rate
|
|
return
|
|
|
|
/datum/plant_gene/reagent/can_add(obj/item/seeds/our_seed)
|
|
. = ..()
|
|
if(!.)
|
|
return FALSE
|
|
for(var/datum/plant_gene/reagent/seed_reagent in our_seed.genes)
|
|
if(seed_reagent.reagent_id == reagent_id && seed_reagent.rate <= rate)
|
|
return FALSE // We can upgrade reagent genes if our rate is greater than the one already in the plant.
|
|
return TRUE
|
|
|
|
/**
|
|
* Intends to compare a reagent gene with a set of seeds, and if the seeds contain the same gene, with more production rate, upgrades the rate to the highest of the two.
|
|
*
|
|
* Called when plants are crossbreeding, this looks for two matching reagent_ids, where the rates are greater, in order to upgrade.
|
|
*/
|
|
/datum/plant_gene/reagent/proc/try_upgrade_gene(obj/item/seeds/seed)
|
|
for(var/datum/plant_gene/reagent/reagent in seed.genes)
|
|
if(reagent.reagent_id != reagent_id || reagent.rate <= rate)
|
|
continue
|
|
rate = reagent.rate
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/// Traits that affect the grown product.
|
|
/datum/plant_gene/trait
|
|
/// The rate at which this trait affects something. This can be anything really - why? I dunno.
|
|
var/rate = 0.05
|
|
/// Bonus lines displayed on examine.
|
|
var/description = ""
|
|
/// Flag - Traits that share an ID cannot be placed on the same plant.
|
|
var/trait_ids
|
|
/// Flag - Modifications made to the final product.
|
|
var/trait_flags
|
|
/// A blacklist of seeds that a trait cannot be attached to.
|
|
var/list/obj/item/seeds/seed_blacklist
|
|
|
|
/datum/plant_gene/trait/Copy()
|
|
. = ..()
|
|
var/datum/plant_gene/trait/new_trait_gene = .
|
|
new_trait_gene.rate = rate
|
|
return
|
|
|
|
/datum/plant_gene/trait/get_name() // Used for manipulator display and gene disk name.
|
|
var/formatted_name
|
|
if(!(mutability_flags & PLANT_GENE_REMOVABLE))
|
|
if(!(mutability_flags & PLANT_GENE_GRAFTABLE))
|
|
formatted_name += "Immutable "
|
|
else
|
|
formatted_name += "Essential "
|
|
formatted_name += name
|
|
return formatted_name
|
|
|
|
/*
|
|
* Checks if we can add the trait to the seed in question.
|
|
*
|
|
* source_seed - the seed genes we're adding the trait too
|
|
*/
|
|
/datum/plant_gene/trait/can_add(obj/item/seeds/source_seed)
|
|
. = ..()
|
|
if(!.)
|
|
return FALSE
|
|
|
|
if(is_type_in_list(source_seed, seed_blacklist))
|
|
return FALSE
|
|
|
|
for(var/datum/plant_gene/trait/trait in source_seed.genes)
|
|
if(trait_ids & trait.trait_ids)
|
|
return FALSE
|
|
if(type == trait.type)
|
|
return FALSE
|
|
|
|
return TRUE
|
|
|
|
/*
|
|
* on_new_plant is called for every plant trait on an /obj/item/grown or /obj/item/food/grown when initialized.
|
|
*
|
|
* our_plant - the source plant being created
|
|
* newloc - the loc of the plant
|
|
*/
|
|
/datum/plant_gene/trait/proc/on_new_plant(obj/item/our_plant, newloc)
|
|
// Plants should always have seeds, but if a plant gene is somehow being instantiated on a plant with no seed, stop initializing genes
|
|
// (Plants hold their genes on their seeds, so we can't really add them to something that doesn't exist)
|
|
if(isnull(our_plant.get_plant_seed()))
|
|
stack_trace("[our_plant] ([our_plant.type]) has a nulled seed value while trying to initialize [src]!")
|
|
return FALSE
|
|
|
|
// Add on any bonus lines on examine
|
|
if(description)
|
|
RegisterSignal(our_plant, COMSIG_ATOM_EXAMINE, PROC_REF(examine))
|
|
return TRUE
|
|
|
|
/// Add on any unique examine text to the plant's examine text.
|
|
/datum/plant_gene/trait/proc/examine(obj/item/our_plant, mob/examiner, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
|
|
examine_list += span_info("[description]")
|
|
|
|
/// Allows the plant to be squashed when thrown or slipped on, leaving a colored mess and trash type item behind.
|
|
/datum/plant_gene/trait/squash
|
|
name = "Liquid Contents"
|
|
icon = "droplet"
|
|
description = "It may burst open from the internal pressure on impact."
|
|
trait_ids = THROW_IMPACT_ID | REAGENT_TRANSFER_ID | ATTACK_SELF_ID
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
// Register a signal that our plant can be squashed on add.
|
|
/datum/plant_gene/trait/squash/on_new_plant(obj/item/food/grown/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SLIP, PROC_REF(squash_plant))
|
|
RegisterSignal(our_plant, COMSIG_MOVABLE_IMPACT, PROC_REF(squash_plant_if_not_caught))
|
|
RegisterSignal(our_plant, COMSIG_ITEM_ATTACK_SELF, PROC_REF(squash_plant))
|
|
|
|
/*
|
|
* Signal proc to squash the plant this trait belongs to, causing a smudge, exposing the target to reagents, and deleting it,
|
|
*
|
|
* Arguments
|
|
* our_plant - the plant this trait belongs to.
|
|
* target - the atom being hit by this squashed plant.
|
|
*/
|
|
/datum/plant_gene/trait/squash/proc/squash_plant(obj/item/food/grown/our_plant, atom/target)
|
|
SIGNAL_HANDLER
|
|
|
|
var/turf/our_turf = get_turf(target)
|
|
our_plant.forceMove(our_turf)
|
|
if(istype(our_plant))
|
|
if(ispath(our_plant.splat_type, /obj/effect/decal/cleanable/food/plant_smudge))
|
|
var/obj/plant_smudge = new our_plant.splat_type(our_turf)
|
|
plant_smudge.name = "[our_plant.name] smudge"
|
|
if(our_plant.filling_color)
|
|
plant_smudge.color = our_plant.filling_color
|
|
else if(our_plant.splat_type)
|
|
new our_plant.splat_type(our_turf)
|
|
else
|
|
var/obj/effect/decal/cleanable/food/plant_smudge/misc_smudge = new(our_turf)
|
|
misc_smudge.name = "[our_plant.name] smudge"
|
|
misc_smudge.color = "#82b900"
|
|
|
|
our_plant.visible_message(span_warning("[our_plant] is squashed."),span_hear("You hear a smack."))
|
|
SEND_SIGNAL(our_plant, COMSIG_PLANT_ON_SQUASH, target)
|
|
|
|
our_plant.reagents?.expose(our_turf)
|
|
for(var/things in our_turf)
|
|
our_plant.reagents?.expose(things)
|
|
|
|
qdel(our_plant)
|
|
|
|
/datum/plant_gene/trait/squash/proc/squash_plant_if_not_caught(datum/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught)
|
|
if(!caught)
|
|
squash_plant(source, hit_atom)
|
|
|
|
/*
|
|
* Makes plant slippery, unless it has a grown-type trash. Then the trash gets slippery.
|
|
* Applies other trait effects (teleporting, etc) to the target by signal.
|
|
*/
|
|
/datum/plant_gene/trait/slip
|
|
name = "Slippery Skin"
|
|
description = "Watch your step around this."
|
|
icon = "person-falling"
|
|
rate = 1.6
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/slip/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/food/grown/grown_plant = our_plant
|
|
if(istype(grown_plant) && ispath(grown_plant.trash_type, /obj/item/grown))
|
|
return
|
|
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
var/stun_len = our_seed.potency * rate
|
|
|
|
if(!istype(our_plant, /obj/item/grown/bananapeel) && (!our_plant.reagents || !our_plant.reagents.has_reagent(/datum/reagent/lube)))
|
|
stun_len /= 3
|
|
|
|
our_plant.AddComponent(/datum/component/slippery, min(stun_len, 140), NONE, CALLBACK(src, PROC_REF(handle_slip), our_plant))
|
|
|
|
/// On slip, sends a signal that our plant was slipped on out.
|
|
/datum/plant_gene/trait/slip/proc/handle_slip(obj/item/food/grown/our_plant, mob/slipped_target)
|
|
SEND_SIGNAL(our_plant, COMSIG_PLANT_ON_SLIP, slipped_target)
|
|
|
|
/*
|
|
* Cell recharging trait. Charges all mob's power cells to (potency*rate)% mark when eaten.
|
|
* Generates sparks on squash.
|
|
* Small (potency * rate) chance to shock squish or slip target for (potency * rate) damage.
|
|
* Also affects plant batteries see capatative cell production datum
|
|
*/
|
|
/datum/plant_gene/trait/cell_charge
|
|
name = "Electrical Activity"
|
|
description = "It can electrocute on interaction or recharge batteries when eaten."
|
|
icon = "bolt"
|
|
rate = 0.2
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/cell_charge/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
if(our_seed.get_gene(/datum/plant_gene/trait/squash))
|
|
// If we have the squash gene, let that handle slipping
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SQUASH, PROC_REF(zap_target))
|
|
else
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SLIP, PROC_REF(zap_target))
|
|
|
|
RegisterSignal(our_plant, COMSIG_FOOD_EATEN, PROC_REF(recharge_cells))
|
|
|
|
/*
|
|
* Zaps the target with a stunning shock.
|
|
*
|
|
* our_plant - our source plant, shocking the target
|
|
* target - the atom being zapped by our plant
|
|
*/
|
|
/datum/plant_gene/trait/cell_charge/proc/zap_target(obj/item/our_plant, atom/target)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!iscarbon(target))
|
|
return
|
|
|
|
our_plant.investigate_log("zapped [key_name(target)] at [AREACOORD(target)]. Last touched by: [our_plant.fingerprintslast].", INVESTIGATE_BOTANY)
|
|
var/mob/living/carbon/target_carbon = target
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
var/power = our_seed.potency * rate
|
|
if(prob(power))
|
|
target_carbon.electrocute_act(round(power), our_plant, 1, SHOCK_NOGLOVES)
|
|
|
|
/*
|
|
* Recharges every cell the person is holding for a bit based on plant potency.
|
|
*
|
|
* our_plant - our source plant, that we consumed to charge the cells
|
|
* eater - the mob that bit the plant
|
|
* feeder - the mob that feed the eater the plant
|
|
*/
|
|
/datum/plant_gene/trait/cell_charge/proc/recharge_cells(obj/item/our_plant, mob/living/eater, mob/feeder)
|
|
SIGNAL_HANDLER
|
|
|
|
to_chat(eater, span_notice("You feel energized as you bite into [our_plant]."))
|
|
var/batteries_recharged = FALSE
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
for(var/obj/item/stock_parts/power_store/found_cell in eater.get_all_contents())
|
|
var/newcharge = min(our_seed.potency * 0.01 * found_cell.maxcharge, found_cell.maxcharge)
|
|
if(found_cell.charge < newcharge)
|
|
found_cell.charge = newcharge
|
|
if(isobj(found_cell.loc))
|
|
var/obj/cell_location = found_cell.loc
|
|
cell_location.update_appearance() //update power meters and such
|
|
found_cell.update_appearance()
|
|
batteries_recharged = TRUE
|
|
if(batteries_recharged)
|
|
to_chat(eater, span_notice("Your batteries are recharged!"))
|
|
|
|
/*
|
|
* Makes the plant glow. Makes the plant in tray glow, too.
|
|
* Adds (1.4 + potency * rate) light range and (potency * (rate + 0.01)) light_power to products.
|
|
*/
|
|
/datum/plant_gene/trait/glow
|
|
name = "Bioluminescence"
|
|
icon = "lightbulb"
|
|
rate = 0.03
|
|
description = "It emits a soft glow."
|
|
trait_ids = GLOW_ID
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
/// The color of our bioluminescence.
|
|
var/glow_color = COLOR_BIOLUMINESCENCE_STANDARD
|
|
|
|
/datum/plant_gene/trait/glow/proc/glow_range(obj/item/seeds/seed)
|
|
return 1.4 + seed.potency * rate
|
|
|
|
/datum/plant_gene/trait/glow/proc/glow_power(obj/item/seeds/seed)
|
|
return max(seed.potency * (rate + 0.01), 0.1)
|
|
|
|
/datum/plant_gene/trait/glow/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
our_plant.light_system = OVERLAY_LIGHT
|
|
our_plant.AddComponent(/datum/component/overlay_lighting, glow_range(our_seed), glow_power(our_seed), glow_color)
|
|
|
|
/*
|
|
* Makes plant emit darkness. (Purple-ish shadows)
|
|
* Adds - (potency * (rate * 0.2)) light power to products.
|
|
*/
|
|
/datum/plant_gene/trait/glow/shadow
|
|
name = "Shadow Emission"
|
|
icon = "lightbulb-o"
|
|
rate = 0.04
|
|
glow_color = COLOR_BIOLUMINESCENCE_SHADOW
|
|
|
|
/datum/plant_gene/trait/glow/shadow/glow_power(obj/item/seeds/seed)
|
|
return -max(seed.potency*(rate*0.2), 0.2)
|
|
|
|
/// Colored versions of bioluminescence.
|
|
|
|
/// White
|
|
/datum/plant_gene/trait/glow/white
|
|
name = "White Bioluminescence"
|
|
glow_color = COLOR_WHITE
|
|
|
|
/// Red
|
|
/datum/plant_gene/trait/glow/red
|
|
name = "Red Bioluminescence"
|
|
glow_color = COLOR_RED_LIGHT
|
|
|
|
/// Yellow (not the disgusting glowshroom yellow hopefully)
|
|
/datum/plant_gene/trait/glow/yellow
|
|
name = "Yellow Bioluminescence"
|
|
glow_color = COLOR_BIOLUMINESCENCE_YELLOW
|
|
|
|
/// Green (oh no, now i'm radioactive)
|
|
/datum/plant_gene/trait/glow/green
|
|
name = "Green Bioluminescence"
|
|
glow_color = COLOR_BIOLUMINESCENCE_GREEN
|
|
|
|
/// Blue (the best one)
|
|
/datum/plant_gene/trait/glow/blue
|
|
name = "Blue Bioluminescence"
|
|
glow_color = COLOR_BIOLUMINESCENCE_BLUE
|
|
|
|
/// Purple (did you know that notepad++ doesnt think bioluminescence is a word) (was the person who wrote this using notepad++ for dm?)
|
|
/datum/plant_gene/trait/glow/purple
|
|
name = "Purple Bioluminescence"
|
|
glow_color = COLOR_BIOLUMINESCENCE_PURPLE
|
|
|
|
// Pink (gay tide station pride)
|
|
/datum/plant_gene/trait/glow/pink
|
|
name = "Pink Bioluminescence"
|
|
glow_color = COLOR_BIOLUMINESCENCE_PINK
|
|
|
|
/*
|
|
* Makes plant teleport people when squashed or slipped on.
|
|
* Teleport radius is roughly potency / 10.
|
|
*/
|
|
/datum/plant_gene/trait/teleport
|
|
name = "Bluespace Activity"
|
|
description = "It causes people to teleport on interaction."
|
|
icon = "right-left"
|
|
rate = 0.1
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/teleport/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
if(our_seed.get_gene(/datum/plant_gene/trait/squash))
|
|
// If we have the squash gene, let that handle slipping
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SQUASH, PROC_REF(squash_teleport))
|
|
else
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SLIP, PROC_REF(slip_teleport))
|
|
|
|
/*
|
|
* When squashed, makes the target teleport.
|
|
*
|
|
* our_plant - our plant, being squashed, and teleporting the target
|
|
* target - the atom targeted by the squash
|
|
*/
|
|
/datum/plant_gene/trait/teleport/proc/squash_teleport(obj/item/our_plant, atom/target)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!isliving(target))
|
|
return
|
|
|
|
our_plant.investigate_log("squash-teleported [key_name(target)] at [AREACOORD(target)]. Last touched by: [our_plant.fingerprintslast].", INVESTIGATE_BOTANY)
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
var/teleport_radius = max(round(our_seed.potency / 10), 1)
|
|
var/turf/T = get_turf(target)
|
|
new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect...
|
|
do_teleport(target, T, teleport_radius, channel = TELEPORT_CHANNEL_BLUESPACE)
|
|
|
|
/*
|
|
* When slipped on, makes the target teleport and either teleport the source again or delete it.
|
|
*
|
|
* our_plant - our plant being slipped on
|
|
* target - the carbon targeted that was slipped and was teleported
|
|
*/
|
|
/datum/plant_gene/trait/teleport/proc/slip_teleport(obj/item/our_plant, mob/living/carbon/target)
|
|
SIGNAL_HANDLER
|
|
|
|
our_plant.investigate_log("slip-teleported [key_name(target)] at [AREACOORD(target)]. Last touched by: [our_plant.fingerprintslast].", INVESTIGATE_BOTANY)
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
var/teleport_radius = max(round(our_seed.potency / 10), 1)
|
|
var/turf/T = get_turf(target)
|
|
to_chat(target, span_warning("You slip through spacetime!"))
|
|
do_teleport(target, T, teleport_radius, channel = TELEPORT_CHANNEL_BLUESPACE)
|
|
if(prob(50))
|
|
do_teleport(our_plant, T, teleport_radius, channel = TELEPORT_CHANNEL_BLUESPACE)
|
|
else
|
|
new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect...
|
|
qdel(our_plant)
|
|
|
|
/**
|
|
* A plant trait that causes the plant's capacity to double.
|
|
*
|
|
* When harvested, the plant's individual capacity is set to double its default.
|
|
* However, the plant's maximum yield is also halved, only up to 5.
|
|
*/
|
|
/datum/plant_gene/trait/maxchem
|
|
name = "Densified Chemicals"
|
|
description = "The reagent volume is doubled, halving the plant yield instead."
|
|
icon = "flask-vial"
|
|
rate = 2
|
|
trait_flags = TRAIT_HALVES_YIELD
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/maxchem/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/food/grown/grown_plant = our_plant
|
|
if(istype(grown_plant, /obj/item/food/grown))
|
|
//Grown foods use the edible component so we need to change their max_volume var
|
|
grown_plant.max_volume *= rate
|
|
else
|
|
//Grown inedibles however just use a reagents holder, so.
|
|
our_plant.reagents?.maximum_volume *= rate
|
|
|
|
/// Allows a plant to be harvested multiple times.
|
|
/datum/plant_gene/trait/repeated_harvest
|
|
name = "Perennial Growth"
|
|
description = "It may be harvested multiple times from the same plant."
|
|
icon = "cubes-stacked"
|
|
/// Don't allow replica pods to be multi harvested, please.
|
|
seed_blacklist = list(
|
|
/obj/item/seeds/replicapod,
|
|
/obj/item/seeds/seedling/evil,
|
|
)
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/*
|
|
* Allows a plant to be turned into a battery when cabling is applied.
|
|
* 100 potency plants are made into 2 mj batteries.
|
|
* Plants with electrical activity has their capacities massively increased (up to 40 mj at 100 potency)
|
|
*/
|
|
/datum/plant_gene/trait/battery
|
|
name = "Capacitive Cell Production"
|
|
description = "It can work like a power cell when wired properly."
|
|
icon = "car-battery"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
/// The number of cables needed to make a battery.
|
|
var/cables_needed_per_battery = 5
|
|
|
|
/datum/plant_gene/trait/battery/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
our_plant.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1
|
|
RegisterSignal(our_plant, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item))
|
|
RegisterSignal(our_plant, COMSIG_ATOM_ATTACKBY, PROC_REF(make_battery))
|
|
|
|
/*
|
|
* Signal proc for [COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM] to add context to plant batteries.
|
|
*/
|
|
/datum/plant_gene/trait/battery/proc/on_requesting_context_from_item(
|
|
obj/item/source,
|
|
list/context,
|
|
obj/item/held_item,
|
|
mob/living/user,
|
|
)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!istype(held_item, /obj/item/stack/cable_coil))
|
|
return NONE
|
|
|
|
var/obj/item/stack/cable_coil/cabling = held_item
|
|
if(cabling.amount < cables_needed_per_battery)
|
|
return NONE
|
|
|
|
context[SCREENTIP_CONTEXT_LMB] = "Make [source.name] battery"
|
|
return CONTEXTUAL_SCREENTIP_SET
|
|
|
|
/*
|
|
* When a plant with this gene is hit (attackby) with cables, we turn it into a battery.
|
|
*
|
|
* our_plant - our plant being hit
|
|
* hit_item - the item we're hitting the plant with
|
|
* user - the person hitting the plant with an item
|
|
*/
|
|
/datum/plant_gene/trait/battery/proc/make_battery(obj/item/our_plant, obj/item/hit_item, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!istype(hit_item, /obj/item/stack/cable_coil))
|
|
return
|
|
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
var/obj/item/stack/cable_coil/cabling = hit_item
|
|
if(!cabling.use(cables_needed_per_battery))
|
|
to_chat(user, span_warning("You need five lengths of cable to make a [our_plant] battery!"))
|
|
return
|
|
|
|
to_chat(user, span_notice("You add some cable to [our_plant] and slide it inside the battery encasing."))
|
|
var/obj/item/stock_parts/power_store/cell/potato/pocell = new /obj/item/stock_parts/power_store/cell/potato(user.loc)
|
|
pocell.icon = our_plant.icon // Just in case the plant icons get spread out in different files eventually, this trait won't cause error sprites (also yay downstreams)
|
|
pocell.icon_state = our_plant.icon_state
|
|
pocell.maxcharge = our_seed.potency * 0.02 * STANDARD_CELL_CHARGE
|
|
|
|
// The secret of potato supercells!
|
|
var/datum/plant_gene/trait/cell_charge/electrical_gene = our_seed.get_gene(/datum/plant_gene/trait/cell_charge)
|
|
if(electrical_gene) // Cell charge max is now 40MJ or otherwise known as 400KJ (Same as bluespace power cells)
|
|
pocell.maxcharge *= (electrical_gene.rate * 100)
|
|
|
|
pocell.charge = pocell.maxcharge
|
|
pocell.name = "[our_plant.name] battery"
|
|
pocell.desc = "A rechargeable plant-based power cell. This one has a rating of [display_energy(pocell.maxcharge)], and you should not swallow it."
|
|
|
|
if(our_plant.reagents.has_reagent(/datum/reagent/toxin/plasma, 2))
|
|
pocell.rigged = TRUE
|
|
|
|
qdel(our_plant)
|
|
|
|
/*
|
|
* Injects a number of chemicals from the plant when you throw it at someone or they slip on it.
|
|
* At 0 potency it can inject 1 unit of its chemicals, while at 100 potency it can inject 20 units.
|
|
*/
|
|
/datum/plant_gene/trait/stinging
|
|
name = "Hypodermic Prickles"
|
|
description = "It stings, passing some reagents in the process."
|
|
icon = "syringe"
|
|
trait_ids = REAGENT_TRANSFER_ID
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/stinging/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SLIP, PROC_REF(prickles_inject))
|
|
RegisterSignal(our_plant, COMSIG_MOVABLE_IMPACT, PROC_REF(prickles_inject))
|
|
|
|
/*
|
|
* Injects a target with a number of reagents from our plant.
|
|
*
|
|
* our_plant - our plant that's injecting someone
|
|
* target - the atom being hit on thrown or slipping on our plant
|
|
*/
|
|
/datum/plant_gene/trait/stinging/proc/prickles_inject(obj/item/our_plant, atom/target)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!isliving(target) || !our_plant.reagents?.total_volume)
|
|
return
|
|
|
|
var/mob/living/living_target = target
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
if(living_target.reagents && living_target.can_inject())
|
|
var/injecting_amount = max(1, our_seed.potency * 0.2) // Minimum of 1, max of 20
|
|
our_plant.reagents.trans_to(living_target, injecting_amount, methods = INJECT)
|
|
to_chat(target, span_danger("You are pricked by [our_plant]!"))
|
|
log_combat(our_plant, living_target, "pricked and attempted to inject reagents from [our_plant] to [living_target]. Last touched by: [our_plant.fingerprintslast].")
|
|
our_plant.investigate_log("pricked and injected [key_name(living_target)] and injected [injecting_amount] reagents at [AREACOORD(living_target)]. Last touched by: [our_plant.fingerprintslast].", INVESTIGATE_BOTANY)
|
|
|
|
/// Explodes into reagent-filled smoke when squashed.
|
|
/datum/plant_gene/trait/smoke
|
|
name = "Gaseous Decomposition"
|
|
description = "It can be smashed to turn its Liquid Contents into smoke."
|
|
icon = "cloud"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/smoke/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SQUASH, PROC_REF(make_smoke))
|
|
|
|
/*
|
|
* Makes a cloud of reagent smoke.
|
|
*
|
|
* our_plant - our plant being squashed and smoked
|
|
* target - the atom the plant was squashed on
|
|
*/
|
|
/datum/plant_gene/trait/smoke/proc/make_smoke(obj/item/our_plant, atom/target)
|
|
SIGNAL_HANDLER
|
|
|
|
our_plant.investigate_log("made smoke at [AREACOORD(target)]. Last touched by: [our_plant.fingerprintslast].", INVESTIGATE_BOTANY)
|
|
var/datum/effect_system/fluid_spread/smoke/chem/smoke = new ()
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
var/splat_location = get_turf(target)
|
|
var/range = sqrt(our_seed.potency * 0.1)
|
|
smoke.attach(splat_location)
|
|
smoke.set_up(round(range), holder = our_plant, location = splat_location, carry = our_plant.reagents, silent = FALSE)
|
|
smoke.start(log = TRUE)
|
|
our_plant.reagents.clear_reagents()
|
|
|
|
/// Makes the plant and its seeds fireproof. From lavaland plants.
|
|
/datum/plant_gene/trait/fire_resistance
|
|
name = "Fire Resistance"
|
|
description = "Makes the seeds, plant and produce fireproof."
|
|
icon = "fire"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/fire_resistance/on_new_seed(obj/item/seeds/new_seed)
|
|
if(!(new_seed.resistance_flags & FIRE_PROOF))
|
|
new_seed.resistance_flags |= FIRE_PROOF
|
|
|
|
/datum/plant_gene/trait/fire_resistance/on_removed(obj/item/seeds/old_seed)
|
|
if(old_seed.resistance_flags & FIRE_PROOF)
|
|
old_seed.resistance_flags &= ~FIRE_PROOF
|
|
|
|
/datum/plant_gene/trait/fire_resistance/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
if(!(our_plant.resistance_flags & FIRE_PROOF))
|
|
our_plant.resistance_flags |= FIRE_PROOF
|
|
|
|
/// Invasive spreading lets the plant jump to other trays, and the spreading plant won't replace plants of the same type.
|
|
/datum/plant_gene/trait/invasive
|
|
name = "Invasive Spreading"
|
|
description = "It attempts to spread around if not contained."
|
|
icon = "virus"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/invasive/on_new_seed(obj/item/seeds/new_seed)
|
|
RegisterSignal(new_seed, COMSIG_SEED_ON_GROW, PROC_REF(try_spread))
|
|
|
|
/datum/plant_gene/trait/invasive/on_removed(obj/item/seeds/old_seed)
|
|
UnregisterSignal(old_seed, COMSIG_SEED_ON_GROW)
|
|
|
|
/*
|
|
* Attempt to find an adjacent tray we can spread to.
|
|
*
|
|
* our_seed - our plant's seed, what spreads to other trays
|
|
* our_tray - the hydroponics tray we're currently in
|
|
*/
|
|
/datum/plant_gene/trait/invasive/proc/try_spread(obj/item/seeds/our_seed, obj/machinery/hydroponics/our_tray)
|
|
SIGNAL_HANDLER
|
|
|
|
if(prob(100 - (5 * (11 - our_seed.production))))
|
|
return
|
|
|
|
for(var/step_dir in GLOB.alldirs)
|
|
var/obj/machinery/hydroponics/spread_tray = locate() in get_step(our_tray, step_dir)
|
|
if(spread_tray && prob(15))
|
|
if(!our_tray.Adjacent(spread_tray))
|
|
continue //Don't spread through things we can't go through.
|
|
|
|
spread_seed(spread_tray, our_tray)
|
|
|
|
/*
|
|
* Actually spread the plant to the tray we found in try_spread.
|
|
*
|
|
* target_tray - the tray we're spreading to
|
|
* origin_tray - the tray we're currently in
|
|
*/
|
|
/datum/plant_gene/trait/invasive/proc/spread_seed(obj/machinery/hydroponics/target_tray, obj/machinery/hydroponics/origin_tray)
|
|
if(target_tray.myseed) // Check if there's another seed in the next tray.
|
|
if(target_tray.myseed.type == origin_tray.myseed.type && target_tray.plant_status != HYDROTRAY_PLANT_DEAD)
|
|
return FALSE // It should not destroy its own kind.
|
|
target_tray.visible_message(span_warning("The [target_tray.myseed.plantname] is overtaken by [origin_tray.myseed.plantname]!"))
|
|
QDEL_NULL(target_tray.myseed)
|
|
target_tray.set_seed(origin_tray.myseed.Copy())
|
|
target_tray.age = 0
|
|
target_tray.set_plant_health(target_tray.myseed.endurance)
|
|
target_tray.lastcycle = world.time
|
|
target_tray.set_weedlevel(0, update_icon = FALSE) // Reset
|
|
target_tray.set_pestlevel(0) // Reset
|
|
target_tray.visible_message(span_warning("The [origin_tray.myseed.plantname] spreads!"))
|
|
if(target_tray.myseed)
|
|
target_tray.name = "[initial(target_tray.name)] ([target_tray.myseed.plantname])"
|
|
else
|
|
target_tray.name = initial(target_tray.name)
|
|
|
|
return TRUE
|
|
|
|
/**
|
|
* A plant trait that causes the plant's food reagents to ferment instead.
|
|
*
|
|
* In practice, it replaces the plant's nutriment and vitamins with half as much of its fermented reagent.
|
|
* This exception is executed in seeds.dm under 'prepare_result'.
|
|
*
|
|
* Incompatible with auto-juicing composition.
|
|
*/
|
|
/datum/plant_gene/trait/brewing
|
|
name = "Auto-Distilling Composition"
|
|
description = "Its nutriments undergo fermentation."
|
|
icon = "wine-glass"
|
|
trait_ids = CONTENTS_CHANGE_ID
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/**
|
|
* Similar to auto-distilling, but instead of brewing the plant's contents it juices it.
|
|
*
|
|
* Incompatible with auto-distilling composition.
|
|
*/
|
|
/datum/plant_gene/trait/juicing
|
|
name = "Auto-Juicing Composition"
|
|
description = "Its nutriments turn into juice."
|
|
icon = "glass-water"
|
|
trait_ids = CONTENTS_CHANGE_ID
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/**
|
|
* Plays a laughter sound when someone slips on it.
|
|
* Like the sitcom component but for plants.
|
|
* Just like slippery skin, if we have a trash type this only functions on that. (Banana peels)
|
|
*/
|
|
/datum/plant_gene/trait/plant_laughter
|
|
name = "Hallucinatory Feedback"
|
|
description = "Makes sounds when people slip on it."
|
|
icon = "face-laugh-squint"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
/// Sounds that play when this trait triggers
|
|
var/list/sounds = list('sound/items/SitcomLaugh1.ogg', 'sound/items/SitcomLaugh2.ogg', 'sound/items/SitcomLaugh3.ogg')
|
|
|
|
/datum/plant_gene/trait/plant_laughter/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/food/grown/grown_plant = our_plant
|
|
if(istype(grown_plant) && ispath(grown_plant.trash_type, /obj/item/grown))
|
|
return
|
|
|
|
RegisterSignal(our_plant, COMSIG_PLANT_ON_SLIP, PROC_REF(laughter))
|
|
|
|
/*
|
|
* Play a sound effect from our plant.
|
|
*
|
|
* our_plant - the source plant that was slipped on
|
|
* target - the atom that slipped on the plant
|
|
*/
|
|
/datum/plant_gene/trait/plant_laughter/proc/laughter(obj/item/our_plant, atom/target)
|
|
SIGNAL_HANDLER
|
|
|
|
our_plant.audible_message(span_notice("[our_plant] lets out burst of laughter."))
|
|
playsound(our_plant, pick(sounds), 100, FALSE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
|
|
/**
|
|
* A plant trait that causes the plant to gain aesthetic googly eyes.
|
|
*
|
|
* Has no functional purpose outside of causing japes, adds eyes over the plant's sprite, which are adjusted for size by potency.
|
|
*/
|
|
/datum/plant_gene/trait/eyes
|
|
name = "Oculary Mimicry"
|
|
description = "It will watch after you."
|
|
icon = "eye"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
/// Our googly eyes appearance.
|
|
var/mutable_appearance/googly
|
|
|
|
/datum/plant_gene/trait/eyes/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
googly = mutable_appearance('icons/obj/service/hydroponics/harvest.dmi', "eyes")
|
|
googly.appearance_flags = RESET_COLOR
|
|
our_plant.add_overlay(googly)
|
|
|
|
/// Makes the plant embed on thrown impact.
|
|
/datum/plant_gene/trait/sticky
|
|
name = "Prickly Adhesion"
|
|
description = "It sticks to people when thrown, also passing reagents if stingy."
|
|
icon = "bandage"
|
|
trait_ids = THROW_IMPACT_ID
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/sticky/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
|
|
our_plant.throwforce = (our_seed.potency/20)
|
|
if (!our_plant.get_embed())
|
|
return
|
|
|
|
if(our_seed.get_gene(/datum/plant_gene/trait/stinging))
|
|
our_plant.set_embed(our_plant.get_embed().generate_with_values(ignore_throwspeed_threshold = TRUE))
|
|
return
|
|
|
|
our_plant.set_embed(our_plant.get_embed().generate_with_values(ignore_throwspeed_threshold = TRUE, pain_mult = 0, jostle_pain_mult = 0))
|
|
|
|
/**
|
|
* This trait automatically heats up the plant's chemical contents when harvested.
|
|
* This requires nutriment to fuel. 1u nutriment = 25 K.
|
|
*/
|
|
/datum/plant_gene/trait/chem_heating
|
|
name = "Exothermic Activity"
|
|
description = "It consumes nutriments to heat up other reagents, halving the yield."
|
|
icon = "temperatyre-arrow-up"
|
|
trait_ids = TEMP_CHANGE_ID
|
|
trait_flags = TRAIT_HALVES_YIELD
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/**
|
|
* This trait is the opposite of above - it cools down the plant's chemical contents on harvest.
|
|
* This requires nutriment to fuel. 1u nutriment = -5 K.
|
|
*/
|
|
/datum/plant_gene/trait/chem_cooling
|
|
name = "Endothermic Activity"
|
|
description = "It consumes nutriments to cool down other reagents, halving the yield."
|
|
icon = "temperature-arrow-down"
|
|
trait_ids = TEMP_CHANGE_ID
|
|
trait_flags = TRAIT_HALVES_YIELD
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/// Prevents species mutation, while still allowing wild mutation harvest and Floral Somatoray species mutation. Trait acts as a tag for hydroponics.dm to recognise.
|
|
/datum/plant_gene/trait/never_mutate
|
|
name = "Prosophobic Inclination"
|
|
description = "The plant does not mutate normally, but may give a mutated produce."
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/// Prevents stat mutation caused by instability. Trait acts as a tag for hydroponics.dm to recognise.
|
|
/datum/plant_gene/trait/stable_stats
|
|
name = "Symbiotic Resilience"
|
|
description = "High instability does not affect the plant stats."
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/// Traits for flowers, makes plants not decompose.
|
|
/datum/plant_gene/trait/preserved
|
|
name = "Natural Insecticide"
|
|
description = "It does not attract ants or decompose."
|
|
icon = "bug-slash"
|
|
mutability_flags = PLANT_GENE_REMOVABLE | PLANT_GENE_MUTATABLE | PLANT_GENE_GRAFTABLE
|
|
|
|
/datum/plant_gene/trait/preserved/on_new_plant(obj/item/our_plant, newloc)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
|
|
var/obj/item/food/grown/grown_plant = our_plant
|
|
if(istype(grown_plant))
|
|
grown_plant.preserved_food = TRUE
|
|
|
|
/datum/plant_gene/trait/carnivory
|
|
name = "Obligate Carnivory"
|
|
description = "Pests have positive effect on the plant health."
|
|
icon = "spider"
|
|
|
|
/// Plant type traits. Incompatible with one another.
|
|
/datum/plant_gene/trait/plant_type
|
|
name = "you shouldn't see this"
|
|
trait_ids = PLANT_TYPE_ID
|
|
mutability_flags = PLANT_GENE_GRAFTABLE
|
|
|
|
/// Weeds don't get annoyed by weeds in their tray.
|
|
/datum/plant_gene/trait/plant_type/weed_hardy
|
|
name = "Weed Adaptation"
|
|
description = "It is a weed that needs no nutrients and doesn't suffer from other weeds."
|
|
icon = "seedling"
|
|
|
|
/// Mushrooms need less light and have a minimum yield.
|
|
/datum/plant_gene/trait/plant_type/fungal_metabolism
|
|
name = "Fungal Vitality"
|
|
description = "It is a mushroom that needs no water, less light and can't be overtaken by weeds."
|
|
icon = "droplet-slash"
|
|
|
|
/// Currently unused and does nothing. Appears in strange seeds.
|
|
/datum/plant_gene/trait/plant_type/alien_properties
|
|
name ="?????"
|
|
icon = "reddit-alien"
|