mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-25 08:51:41 +00:00
Fixes the reagent grinder machines not properly grinding tomato into ketchup and rice into rice Updates botany code to use qdel over del to help alleviate potential lag from del calls Removes the PanDEMIC 2200 board from Tech Storage and the Circuit Imprinter, as the computer it builds has been commented out for a long time. Also deletes the commented out code (over 250 lines of commented out code deleted)
863 lines
27 KiB
Plaintext
863 lines
27 KiB
Plaintext
/obj/machinery/portable_atmospherics/hydroponics
|
|
name = "hydroponics tray"
|
|
icon = 'icons/obj/hydroponics_machines.dmi'
|
|
icon_state = "hydrotray3"
|
|
density = 1
|
|
anchored = 1
|
|
flags = OPENCONTAINER
|
|
volume = 100
|
|
|
|
var/mechanical = 1 // Set to 0 to stop it from drawing the alert lights.
|
|
var/base_name = "tray"
|
|
|
|
// Plant maintenance vars.
|
|
var/waterlevel = 100 // Water level (max 100)
|
|
var/maxwater = 100
|
|
var/nutrilevel = 10 // Nutrient level (max 10)
|
|
var/maxnutri = 10
|
|
var/pestlevel = 0 // Pests (max 10)
|
|
var/weedlevel = 0 // Weeds (max 10)
|
|
|
|
// Tray state vars.
|
|
var/dead = 0 // Is it dead?
|
|
var/harvest = 0 // Is it ready to harvest?
|
|
var/age = 0 // Current plant age
|
|
var/sampled = 0 // Have we taken a sample?
|
|
|
|
// Harvest/mutation mods.
|
|
var/yield_mod = 0 // Modifier to yield
|
|
var/mutation_mod = 0 // Modifier to mutation chance
|
|
var/toxins = 0 // Toxicity in the tray?
|
|
var/tray_light = 1 // Supplied lighting.
|
|
|
|
// Mechanical concerns.
|
|
var/health = 0 // Plant health.
|
|
var/lastproduce = 0 // Last time tray was harvested
|
|
var/lastcycle = 0 // Cycle timing/tracking var.
|
|
var/cycledelay = 150 // Delay per cycle.
|
|
var/closed_system // If set, the tray will attempt to take atmos from a pipe.
|
|
var/force_update // Set this to bypass the cycle time check.
|
|
var/obj/temp_chem_holder // Something to hold reagents during process_reagents()
|
|
var/labelled
|
|
|
|
// Seed details/line data.
|
|
var/datum/seed/seed = null // The currently planted seed
|
|
|
|
// Construction
|
|
var/unwrenchable = 1
|
|
|
|
// Reagent information for process(), consider moving this to a controller along
|
|
// with cycle information under 'mechanical concerns' at some point.
|
|
var/global/list/toxic_reagents = list(
|
|
"charcoal" = -2,
|
|
"toxin" = 2,
|
|
"fluorine" = 2.5,
|
|
"chlorine" = 1.5,
|
|
"sacid" = 1.5,
|
|
"facid" = 3,
|
|
"atrazine" = 3,
|
|
"cryoxadone" = -3,
|
|
"radium" = 2
|
|
)
|
|
var/global/list/nutrient_reagents = list(
|
|
"milk" = 0.1,
|
|
"beer" = 0.25,
|
|
"phosphorus" = 0.1,
|
|
"sugar" = 0.1,
|
|
"sodawater" = 0.1,
|
|
"ammonia" = 1,
|
|
"diethylamine" = 2,
|
|
"nutriment" = 1,
|
|
"adminordrazine" = 1,
|
|
"eznutrient" = 1,
|
|
"robustharvest" = 1,
|
|
"left4zed" = 1,
|
|
"fishwater" = 0.75,
|
|
)
|
|
var/global/list/weedkiller_reagents = list(
|
|
"fluorine" = -4,
|
|
"chlorine" = -3,
|
|
"phosphorus" = -2,
|
|
"sugar" = 2,
|
|
"sacid" = -2,
|
|
"facid" = -4,
|
|
"atrazine" = -8,
|
|
"adminordrazine" = -5
|
|
)
|
|
var/global/list/pestkiller_reagents = list(
|
|
"sugar" = 2,
|
|
"diethylamine" = -2,
|
|
"adminordrazine" = -5
|
|
)
|
|
var/global/list/water_reagents = list(
|
|
"water" = 1,
|
|
"adminordrazine" = 1,
|
|
"milk" = 0.9,
|
|
"beer" = 0.7,
|
|
"fluorine" = -0.5,
|
|
"chlorine" = -0.5,
|
|
"phosphorus" = -0.5,
|
|
"water" = 1,
|
|
"sodawater" = 1,
|
|
"fishwater" = 1,
|
|
)
|
|
|
|
// Beneficial reagents also have values for modifying yield_mod and mut_mod (in that order).
|
|
var/global/list/beneficial_reagents = list(
|
|
// "reagent" = list(health, yield_Mod, mut_mod),
|
|
"beer" = list( -0.05, 0, 0 ),
|
|
"fluorine" = list( -2, 0, 0 ),
|
|
"chlorine" = list( -1, 0, 0 ),
|
|
"phosphorus" = list( -0.75, 0, 0 ),
|
|
"sodawater" = list( 0.1, 0, 0 ),
|
|
"sacid" = list( -1, 0, 0 ),
|
|
"facid" = list( -2, 0, 0 ),
|
|
"atrazine" = list( -2, 0, 0.2),
|
|
"cryoxadone" = list( 3, 0, 0 ),
|
|
"ammonia" = list( 0.5, 0, 0 ),
|
|
"diethylamine" = list( 1, 0, 0 ),
|
|
"nutriment" = list( 0.25, 0.15, 0 ),
|
|
"radium" = list( -1.5, 0, 0.2),
|
|
"adminordrazine" = list( 1, 1, 1 ),
|
|
"robustharvest" = list( 0, 0.2, 0 ),
|
|
"left4zed" = list( 0, 0, 0.2)
|
|
)
|
|
|
|
//--FalseIncarnate
|
|
// Mutagen list specifies reagent_min_value and reagent_step
|
|
// Reagent_min_value (value 1) is the minimum number of units needed to begin mutations
|
|
// Reagent_step (value 2) is the number of units between each mutation threshold
|
|
var/global/list/mutagenic_reagents = list(
|
|
"radium" = list(10,10),
|
|
"mutagen" = list(1,5)
|
|
)
|
|
//--FalseIncarnate
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/AltClick()
|
|
if(mechanical && !usr.stat && !usr.lying && Adjacent(usr))
|
|
close_lid(usr)
|
|
return
|
|
return ..()
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/attack_generic(var/mob/user)
|
|
if(istype(user,/mob/living/carbon/primitive/diona))
|
|
var/mob/living/carbon/primitive/diona/nymph = user
|
|
|
|
if(nymph.stat == DEAD || nymph.paralysis || nymph.weakened || nymph.stunned || nymph.restrained())
|
|
return
|
|
|
|
if(weedlevel > 0)
|
|
nymph.reagents.add_reagent("nutriment", weedlevel)
|
|
weedlevel = 0
|
|
nymph.visible_message("<font color='blue'><b>[nymph]</b> begins rooting through [src], ripping out weeds and eating them noisily.</font>","<font color='blue'>You begin rooting through [src], ripping out weeds and eating them noisily.</font>")
|
|
else if(nymph.nutrition > 100 && nutrilevel < 10)
|
|
nymph.nutrition -= ((10-nutrilevel)*5)
|
|
nutrilevel = 10
|
|
nymph.visible_message("<font color='blue'><b>[nymph]</b> secretes a trickle of green liquid, refilling [src].</font>","<font color='blue'>You secrete a trickle of green liquid, refilling [src].</font>")
|
|
else
|
|
nymph.visible_message("<font color='blue'><b>[nymph]</b> rolls around in [src] for a bit.</font>","<font color='blue'>You roll around in [src] for a bit.</font>")
|
|
return
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/New()
|
|
..()
|
|
|
|
component_parts = list()
|
|
component_parts += new /obj/item/weapon/circuitboard/hydroponics(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
|
|
RefreshParts()
|
|
|
|
temp_chem_holder = new()
|
|
temp_chem_holder.create_reagents(10)
|
|
|
|
create_reagents(200)
|
|
connect()
|
|
update_icon()
|
|
if(closed_system)
|
|
flags &= ~OPENCONTAINER
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/upgraded/New()
|
|
..()
|
|
component_parts = list()
|
|
component_parts += new /obj/item/weapon/circuitboard/hydroponics(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src)
|
|
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
|
|
RefreshParts()
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/RefreshParts()
|
|
var/tmp_capacity = 0
|
|
for (var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
|
tmp_capacity += M.rating
|
|
maxwater = tmp_capacity * 50 // Up to 300
|
|
maxnutri = tmp_capacity * 5 // Up to 30
|
|
//waterlevel = maxwater
|
|
//nutrilevel = 3
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj)
|
|
|
|
//Don't act on seeds like dionaea that shouldn't change.
|
|
if(seed && seed.get_trait(TRAIT_IMMUTABLE) > 0)
|
|
return
|
|
|
|
//--FalseIncarnate
|
|
//Override for somatoray projectiles, updated to work with new mutation rework
|
|
if(istype(Proj ,/obj/item/projectile/energy/floramut))
|
|
mutate("F1")
|
|
return
|
|
else if(istype(Proj ,/obj/item/projectile/energy/florayield))
|
|
mutate("F2")
|
|
return
|
|
//--FalseIncarnate
|
|
|
|
..()
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
|
if(air_group || (height==0)) return 1
|
|
|
|
if(istype(mover) && mover.checkpass(PASSTABLE))
|
|
return 1
|
|
else
|
|
return 0
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/check_health()
|
|
if(seed && !dead && health <= 0)
|
|
die()
|
|
check_level_sanity()
|
|
update_icon()
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/die()
|
|
dead = 1
|
|
harvest = 0
|
|
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
|
|
pestlevel = 0
|
|
|
|
//Process reagents being input into the tray.
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/process_reagents()
|
|
|
|
if(!reagents) return
|
|
|
|
if(reagents.total_volume <= 0)
|
|
return
|
|
|
|
/* I have plans for this at a later date, so it's just being commented out for now --FalseIncarnate
|
|
|
|
reagents.trans_to(temp_chem_holder, min(reagents.total_volume,rand(1,3)))
|
|
|
|
for(var/datum/reagent/R in temp_chem_holder.reagents.reagent_list)
|
|
|
|
var/reagent_total = temp_chem_holder.reagents.get_reagent_amount(R.id)
|
|
*/
|
|
|
|
for(var/datum/reagent/R in reagents.reagent_list)
|
|
|
|
var/reagent_total = reagents.get_reagent_amount(R.id)
|
|
|
|
if(seed && !dead)
|
|
//Handle some general level adjustments.
|
|
if(toxic_reagents[R.id])
|
|
toxins += toxic_reagents[R.id] * reagent_total
|
|
if(weedkiller_reagents[R.id])
|
|
weedlevel -= weedkiller_reagents[R.id] * reagent_total
|
|
if(pestkiller_reagents[R.id])
|
|
pestlevel += pestkiller_reagents[R.id] * reagent_total
|
|
|
|
// Beneficial reagents have a few impacts along with health buffs.
|
|
if(beneficial_reagents[R.id])
|
|
health += beneficial_reagents[R.id][1] * reagent_total
|
|
yield_mod = min(100, yield_mod + (beneficial_reagents[R.id][2] * reagent_total))
|
|
mutation_mod += beneficial_reagents[R.id][3] * reagent_total
|
|
|
|
// Mutagen is distinct from the previous types and mostly has a chance of proccing a mutation.
|
|
|
|
//--FalseIncarnate
|
|
// Mutation rework, will now use "thresholds" for proccing types of mutations and their respective chances.
|
|
// This should make it easier to avoid species shifts when trying to only affect stats like potency.
|
|
// Additionally, the chance of mutations will vary depending on the amount of mutagenic reagents added.
|
|
if(mutagenic_reagents[R.id])
|
|
var/reagent_min_value = mutagenic_reagents[R.id][1] //10 for radium, 1 for unstable mutagen
|
|
var/reagent_step = mutagenic_reagents[R.id][2] //10 for radium, 5 for unstable mutagen
|
|
|
|
if(reagent_total >= reagent_min_value + (3 * reagent_step)) //31+ for radium, 16+ for unstable mutagen
|
|
mutate(4)
|
|
else if(reagent_total >= reagent_min_value + (2 * reagent_step)) //21-30 for radium, 11-15 for unstable mutagen
|
|
mutate(3)
|
|
else if(reagent_total >= reagent_min_value + reagent_step) //11-20 for radium, 6-10 for unstable mutagen
|
|
mutate(2)
|
|
else if(reagent_total >= reagent_min_value) //1-10 for radium, 1-5 for unstable mutagen
|
|
mutate(1)
|
|
|
|
//--FalseIncarnate
|
|
|
|
// Handle nutrient refilling.
|
|
if(nutrient_reagents[R.id])
|
|
nutrilevel += nutrient_reagents[R.id] * reagent_total
|
|
|
|
// Handle water and water refilling.
|
|
var/water_added = 0
|
|
if(water_reagents[R.id])
|
|
var/water_input = water_reagents[R.id] * reagent_total
|
|
water_added += water_input
|
|
waterlevel += water_input
|
|
|
|
// Water dilutes toxin level.
|
|
if(water_added > 0)
|
|
toxins -= round(water_added/4)
|
|
|
|
// temp_chem_holder.reagents.clear_reagents()
|
|
reagents.clear_reagents()
|
|
check_health()
|
|
|
|
//Harvests the product of a plant.
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/harvest(var/mob/user)
|
|
|
|
//Harvest the product of the plant,
|
|
if(!seed || !harvest)
|
|
return
|
|
|
|
if(closed_system)
|
|
if(user) user << "You can't harvest from the plant while the lid is shut."
|
|
return
|
|
|
|
if(user)
|
|
seed.harvest(user,yield_mod)
|
|
else
|
|
seed.harvest(get_turf(src),yield_mod)
|
|
|
|
// Reset values.
|
|
harvest = 0
|
|
lastproduce = age
|
|
|
|
if(!seed.get_trait(TRAIT_HARVEST_REPEAT))
|
|
yield_mod = 0
|
|
seed = null
|
|
dead = 0
|
|
age = 0
|
|
sampled = 0
|
|
mutation_mod = 0
|
|
|
|
check_health()
|
|
return
|
|
|
|
//Clears out a dead plant.
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/remove_dead(var/mob/user)
|
|
if(!user || !dead) return
|
|
|
|
if(closed_system)
|
|
user << "You can't remove the dead plant while the lid is shut."
|
|
return
|
|
|
|
seed = null
|
|
dead = 0
|
|
|
|
sampled = 0
|
|
age = 0
|
|
yield_mod = 0
|
|
mutation_mod = 0
|
|
|
|
user << "You remove the dead plant."
|
|
check_health()
|
|
return
|
|
|
|
// If a weed growth is sufficient, this proc is called.
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/weed_invasion()
|
|
|
|
//Remove the seed if something is already planted.
|
|
if(seed) seed = null
|
|
seed = plant_controller.seeds[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))]
|
|
if(!seed) return //Weed does not exist, someone fucked up.
|
|
|
|
dead = 0
|
|
age = 0
|
|
health = seed.get_trait(TRAIT_ENDURANCE)
|
|
lastcycle = world.time
|
|
harvest = 0
|
|
weedlevel = 0
|
|
pestlevel = 0
|
|
sampled = 0
|
|
update_icon()
|
|
visible_message("<span class='notice'>[src] has been overtaken by [seed.display_name].</span>")
|
|
|
|
return
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate(var/severity)
|
|
|
|
// No seed, no mutations.
|
|
if(!seed)
|
|
return
|
|
|
|
/*
|
|
--FalseIncarnate
|
|
New mutation system, now uses "Mutation Tiers" to adjust the chances of mutations
|
|
Tier 1 has a low chance of causing a stat mutation
|
|
Tier 2 has a higher chance of causing a stat mutation
|
|
Tier 3 has a low chance of causing a species shift (if possible), and will ALWAYS cause a stat mutation if it does not shift species
|
|
Tier 4 has a higher chance of causing a species shift (if possible), and will ALWAYS cause a stat mutation if it does not shift species
|
|
Tier 4 also has a low chance to cause a SECOND stat mutation when it does not shift species
|
|
All mutation chances are increased by the mutation_mod value. Mutation_mod is not transferred into seeds/harvests, and is reset when the plant dies
|
|
*/
|
|
|
|
switch(severity)
|
|
//Reagent Tiers
|
|
if(1) //Tier 1
|
|
if(prob(20+mutation_mod)) //Low chance of stat mutation
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
if(2) //Tier 2
|
|
if(prob(60+mutation_mod)) //Higher chance of stat mutation
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
if(3) //Tier 3
|
|
if(prob(20+mutation_mod)) //Low chance of species shift mutation
|
|
if(seed.mutants. && seed.mutants.len) //Check if current seed/plant has mutant species
|
|
mutate_species()
|
|
else //No mutant species, mutate stats instead
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
else //Failed to shift, mutate stats instead
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
if(4) //Tier 4
|
|
if(prob(60+mutation_mod)) //Higher chance of species shift mutation
|
|
if(seed.mutants. && seed.mutants.len) //Check if current seed/plant has mutant species
|
|
mutate_species()
|
|
else //No mutant species, mutate stats instead
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
if(prob(20+mutation_mod)) //Low chance for second stat mutation
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
else //Failed to shift, mutate stats instead
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
if(prob(20+mutation_mod)) //Low chance for second stat mutation
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
//Floral Somatoray Tiers
|
|
if("F1") //Random Stat Tier
|
|
if(prob(80+mutation_mod)) //EVEN Higher chance of stat mutation
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(1,get_turf(src))
|
|
return
|
|
if("F2") //Yield Tier
|
|
if(prob(40+mutation_mod)) //Medium chance of Yield stat mutation
|
|
if(!isnull(plant_controller.seeds[seed.name]))
|
|
seed = seed.diverge()
|
|
if(seed.get_trait(TRAIT_IMMUTABLE) <= 0 && seed.get_trait(TRAIT_YIELD) != -1) //Check if the plant can be mutated and has a yield to mutate
|
|
seed.set_trait(TRAIT_YIELD, (seed.get_trait(TRAIT_YIELD) + rand(-2, 2))) //Randomly adjust yield
|
|
if(seed.get_trait(TRAIT_YIELD) < 0) //If yield would drop below 0 after adjustment, set to 0 to allow further attempts
|
|
seed.set_trait(TRAIT_YIELD, 0)
|
|
return
|
|
|
|
/* code references
|
|
// We need to make sure we're not modifying one of the global seed datums.
|
|
// If it's not in the global list, then no products of the line have been
|
|
// harvested yet and it's safe to assume it's restricted to this tray.
|
|
if(!isnull(seed_types[seed.name]))
|
|
seed = seed.diverge()
|
|
seed.mutate(severity,get_turf(src))
|
|
*/
|
|
|
|
//--FalseIncarnate
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/verb/remove_label()
|
|
|
|
set name = "Remove Label"
|
|
set category = "Object"
|
|
set src in view(1)
|
|
|
|
if(labelled)
|
|
usr << "You remove the label."
|
|
labelled = null
|
|
update_icon()
|
|
else
|
|
usr << "There is no label to remove."
|
|
return
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/verb/setlight()
|
|
set name = "Set Light"
|
|
set category = "Object"
|
|
set src in view(1)
|
|
|
|
var/new_light = input("Specify a light level.") as null|anything in list(0,1,2,3,4,5,6,7,8,9,10)
|
|
if(new_light)
|
|
tray_light = new_light
|
|
usr << "You set the tray to a light level of [tray_light] lumens."
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/check_level_sanity()
|
|
//Make sure various values are sane.
|
|
if(seed)
|
|
health = max(0,min(seed.get_trait(TRAIT_ENDURANCE),health))
|
|
else
|
|
health = 0
|
|
dead = 0
|
|
|
|
nutrilevel = max(0,min(nutrilevel,10))
|
|
waterlevel = max(0,min(waterlevel,100))
|
|
pestlevel = max(0,min(pestlevel,10))
|
|
weedlevel = max(0,min(weedlevel,10))
|
|
toxins = max(0,min(toxins,10))
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate_species()
|
|
|
|
var/previous_plant = seed.display_name
|
|
var/newseed = seed.get_mutant_variant()
|
|
if(newseed in plant_controller.seeds)
|
|
seed = plant_controller.seeds[newseed]
|
|
else
|
|
return
|
|
|
|
dead = 0
|
|
//mutate(1)
|
|
age = 0
|
|
health = seed.get_trait(TRAIT_ENDURANCE)
|
|
lastcycle = world.time
|
|
harvest = 0
|
|
weedlevel = 0
|
|
|
|
update_icon()
|
|
visible_message("\red The \blue [previous_plant] \red has suddenly mutated into \blue [seed.display_name]!")
|
|
|
|
return
|
|
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
|
if(exchange_parts(user, O))
|
|
return
|
|
|
|
if(istype(O, /obj/item/weapon/crowbar))
|
|
if(anchored==2)
|
|
user << "Unscrew the hoses first!"
|
|
return
|
|
default_deconstruction_crowbar(O, 1)
|
|
|
|
//--FalseIncarnate
|
|
//Check if held item is an open container
|
|
if (O.is_open_container())
|
|
//Check if container is of the "glass" subtype (includes buckets, beakers, vials)
|
|
if(istype(O, /obj/item/weapon/reagent_containers/glass))
|
|
var/obj/item/weapon/reagent_containers/glass/C = O
|
|
//Check if container is empty
|
|
if(!C.reagents.total_volume)
|
|
user << "\red [C] is empty."
|
|
return
|
|
//Container not empty, transfer contents to tray
|
|
var/trans = C.reagents.trans_to(src, C.amount_per_transfer_from_this)
|
|
user << "\blue You transfer [trans] units of the solution to [src]."
|
|
|
|
check_level_sanity()
|
|
process_reagents()
|
|
update_icon()
|
|
|
|
//Check if container is one of the plantsprays (defined in tray_reagents.dm)
|
|
else if(istype(O, /obj/item/weapon/plantspray))
|
|
var/obj/item/weapon/plantspray/P = O
|
|
user.drop_item(O)
|
|
toxins += P.toxicity
|
|
pestlevel -= P.pest_kill_str
|
|
weedlevel -= P.weed_kill_str
|
|
user << "You spray [src] with [O]."
|
|
playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6)
|
|
qdel(O)
|
|
|
|
check_level_sanity()
|
|
update_icon()
|
|
|
|
//Check if spray is weedkiller (defined in tray_reagents.dm, un-obtainable currently)
|
|
else if(istype(O, /obj/item/weedkiller))
|
|
var/obj/item/weedkiller/W = O
|
|
user.drop_item(O)
|
|
toxins += W.toxicity
|
|
weedlevel -= W.weed_kill_str
|
|
user << "You spray [src] with [O]."
|
|
playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6)
|
|
qdel(O)
|
|
|
|
check_level_sanity()
|
|
update_icon()
|
|
|
|
//Check if container is any spray container
|
|
else if (istype(O, /obj/item/weapon/reagent_containers/spray))
|
|
var/obj/item/weapon/reagent_containers/spray/S = O
|
|
//Check if there is a plant in the tray
|
|
if(seed)
|
|
if(!S.reagents.total_volume)
|
|
user << "\red [S] is empty."
|
|
return
|
|
//Container not empty, transfer contents to tray
|
|
S.reagents.trans_to(src, S.amount_per_transfer_from_this)
|
|
visible_message("\red <B>\The [src] has been sprayed with \the [O][(user ? " by [user]." : ".")]")
|
|
playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6)
|
|
check_level_sanity()
|
|
update_icon()
|
|
else
|
|
user << "There's nothing in [src] to spray!"
|
|
|
|
else if(istype(O, /obj/item/weapon/screwdriver) && unwrenchable) //THIS NEED TO BE DONE DIFFERENTLY, SOMEONE REFACTOR THE TRAY CODE ALREADY
|
|
if(anchored)
|
|
if(anchored == 2)
|
|
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
|
anchored = 1
|
|
user << "You unscrew the [src]'s hoses."
|
|
panel_open = 0
|
|
|
|
else if(anchored == 1)
|
|
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
|
anchored = 2
|
|
user << "You screw in the [src]'s hoses."
|
|
panel_open = 1
|
|
|
|
for(var/obj/machinery/portable_atmospherics/hydroponics/h in range(1,src))
|
|
spawn()
|
|
h.update_icon()
|
|
|
|
if(istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/weapon/scalpel))
|
|
|
|
if(!seed)
|
|
user << "There is nothing to take a sample from in \the [src]."
|
|
return
|
|
|
|
if(sampled)
|
|
user << "You have already sampled from this plant."
|
|
return
|
|
|
|
if(dead)
|
|
user << "The plant is dead."
|
|
return
|
|
|
|
// Create a sample.
|
|
seed.harvest(user,yield_mod,1)
|
|
health -= (rand(3,5)*10)
|
|
|
|
if(prob(30))
|
|
sampled = 1
|
|
|
|
// Bookkeeping.
|
|
check_health()
|
|
force_update = 1
|
|
process()
|
|
|
|
return
|
|
|
|
else if(istype(O, /obj/item/weapon/reagent_containers/syringe))
|
|
|
|
var/obj/item/weapon/reagent_containers/syringe/S = O
|
|
|
|
if (S.mode == 1)
|
|
if(seed)
|
|
return ..()
|
|
else
|
|
user << "There's no plant to inject."
|
|
return 1
|
|
else
|
|
if(seed)
|
|
//Leaving this in in case we want to extract from plants later.
|
|
user << "You can't get any extract out of this plant."
|
|
else
|
|
user << "There's nothing to draw something from."
|
|
return 1
|
|
|
|
else if (istype(O, /obj/item/seeds))
|
|
|
|
if(!seed)
|
|
|
|
var/obj/item/seeds/S = O
|
|
user.drop_item(O)
|
|
|
|
if(!S.seed)
|
|
user << "The packet seems to be empty. You throw it away."
|
|
qdel(O)
|
|
return
|
|
|
|
user << "You plant the [S.seed.seed_name] [S.seed.seed_noun]."
|
|
seed = S.seed //Grab the seed datum.
|
|
dead = 0
|
|
age = 1
|
|
//Snowflakey, maybe move this to the seed datum
|
|
health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE))
|
|
lastcycle = world.time
|
|
|
|
qdel(O)
|
|
|
|
check_health()
|
|
|
|
else
|
|
user << "<span class='danger'>\The [src] already has seeds in it!</span>"
|
|
|
|
else if (istype(O, /obj/item/weapon/minihoe)) // The minihoe
|
|
|
|
if(weedlevel > 0)
|
|
user.visible_message("<span class='danger'>[user] starts uprooting the weeds.</span>", "<span class='danger'>You remove the weeds from the [src].</span>")
|
|
weedlevel = 0
|
|
update_icon()
|
|
else
|
|
user << "<span class='danger'>This plot is completely devoid of weeds. It doesn't need uprooting.</span>"
|
|
|
|
else if (istype(O, /obj/item/weapon/storage/bag/plants))
|
|
|
|
attack_hand(user)
|
|
|
|
var/obj/item/weapon/storage/bag/plants/S = O
|
|
for (var/obj/item/weapon/reagent_containers/food/snacks/grown/G in locate(user.x,user.y,user.z))
|
|
if(!S.can_be_inserted(G))
|
|
return
|
|
S.handle_item_insertion(G, 1)
|
|
|
|
else if(mechanical && istype(O, /obj/item/weapon/wrench))
|
|
|
|
//If there's a connector here, the portable_atmospherics setup can handle it.
|
|
if(locate(/obj/machinery/atmospherics/portables_connector/) in loc)
|
|
return ..()
|
|
|
|
playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
|
|
anchored = !anchored
|
|
user << "You [anchored ? "wrench" : "unwrench"] \the [src]."
|
|
|
|
else if(istype(O, /obj/item/apiary))
|
|
|
|
if(seed)
|
|
user << "<span class='danger'>[src] is already occupied!</span>"
|
|
else
|
|
user.drop_item()
|
|
qdel(O)
|
|
|
|
var/obj/machinery/apiary/A = new(src.loc)
|
|
A.icon = src.icon
|
|
A.icon_state = src.icon_state
|
|
A.hydrotray_type = src.type
|
|
qdel(src)
|
|
else if ((istype(O, /obj/item/weapon/tank) && !( src.destroyed )))
|
|
if (src.holding)
|
|
user << "\blue There is alreadu a tank loaded into the [src]."
|
|
return
|
|
var/obj/item/weapon/tank/T = O
|
|
user.drop_item()
|
|
T.loc = src
|
|
src.holding = T
|
|
update_icon()
|
|
return
|
|
else if(O && O.force && seed)
|
|
user.visible_message("<span class='danger'>\The [seed.display_name] has been attacked by [user] with \the [O]!</span>")
|
|
if(!dead)
|
|
health -= O.force
|
|
check_health()
|
|
return
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/attack_tk(mob/user as mob)
|
|
if(dead)
|
|
remove_dead(user)
|
|
else if(harvest)
|
|
harvest(user)
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/attack_hand(mob/user as mob)
|
|
|
|
if(istype(usr,/mob/living/silicon))
|
|
return
|
|
|
|
if(harvest)
|
|
harvest(user)
|
|
else if(dead)
|
|
remove_dead(user)
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/examine()
|
|
|
|
..()
|
|
|
|
if(!seed)
|
|
usr << "[src] is empty."
|
|
return
|
|
|
|
usr << "<span class='notice'>[seed.display_name]</span> are growing here.</span>"
|
|
|
|
if(!Adjacent(usr))
|
|
return
|
|
|
|
usr << "Water: [round(waterlevel,0.1)]/100"
|
|
usr << "Nutrient: [round(nutrilevel,0.1)]/10"
|
|
|
|
if(weedlevel >= 5)
|
|
usr << "\The [src] is <span class='danger'>infested with weeds</span>!"
|
|
if(pestlevel >= 5)
|
|
usr << "\The [src] is <span class='danger'>infested with tiny worms</span>!"
|
|
|
|
if(dead)
|
|
usr << "<span class='danger'>The plant is dead.</span>"
|
|
else if(health <= (seed.get_trait(TRAIT_ENDURANCE)/ 2))
|
|
usr << "The plant looks <span class='danger'>unhealthy</span>."
|
|
|
|
if(mechanical)
|
|
var/turf/T = loc
|
|
var/datum/gas_mixture/environment
|
|
|
|
if(closed_system && (connected_port || holding))
|
|
environment = air_contents
|
|
|
|
if(!environment)
|
|
if(istype(T))
|
|
environment = T.return_air()
|
|
|
|
if(!environment) //We're in a crate or nullspace, bail out.
|
|
return
|
|
|
|
var/light_string
|
|
if(closed_system && mechanical)
|
|
light_string = "that the internal lights are set to [tray_light] lumens"
|
|
else
|
|
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
|
|
var/light_available
|
|
if(L)
|
|
light_available = L.get_clamped_lum()*10
|
|
else
|
|
light_available = 5
|
|
light_string = "a light level of [light_available] lumens"
|
|
|
|
usr << "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K."
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb()
|
|
set name = "Toggle Tray Lid"
|
|
set category = "Object"
|
|
set src in view(1)
|
|
close_lid(usr)
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/close_lid(var/mob/living/user)
|
|
if(!user || user.stat || user.restrained())
|
|
return
|
|
|
|
closed_system = !closed_system
|
|
user << "You [closed_system ? "close" : "open"] the tray's lid."
|
|
update_icon()
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/verb/eject_tank_verb()
|
|
set name = "Eject Internal Tank"
|
|
set category = "Object"
|
|
set src in view(1)
|
|
eject_tank(usr)
|
|
|
|
/obj/machinery/portable_atmospherics/hydroponics/proc/eject_tank(var/mob/living/user)
|
|
if(!user || user.stat || user.restrained())
|
|
return
|
|
|
|
if(!holding)
|
|
usr << "\red There is no tank loaded into [src] to eject."
|
|
|
|
if(istype(holding, /obj/item/weapon/tank))
|
|
usr << "\blue You eject [holding.name] from [src]."
|
|
holding.loc = loc
|
|
holding = null
|