diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index d52fd60b7eb..4c85144d1e5 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -133,3 +133,13 @@
layer = 2
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
+
+/obj/effect/decal/cleanable/fruit_smudge
+ name = "smudge"
+ desc = "Some kind of fruit smear."
+ density = 0
+ anchored = 1
+ layer = 2
+ icon = 'icons/effects/blood.dmi'
+ icon_state = "mfloor1"
+ random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
\ No newline at end of file
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index f090d8665dc..2d2003bb856 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -993,6 +993,20 @@ var/global/floorIsLava = 0
else
return "Error: Invalid sabotage target: [target]"
*/
+
+/datum/admins/proc/spawn_fruit()
+ set category = "Debug"
+ set desc = "(seed index) Spawn the product of a seed."
+ set name = "Spawn Fruit"
+
+ if(!check_rights(R_SPAWN)) return
+
+ var/seedtype = input("Select a seed type", "Spawn Fruit") as null|anything in seed_types
+ if(!seedtype || !seed_types[seedtype])
+ return
+ var/datum/seed/S = seed_types[seedtype]
+ S.harvest(usr,0,0,1)
+
/datum/admins/proc/spawn_atom(var/object as text)
set category = "Debug"
set desc = "(atom path) Spawn an atom"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index d20105a67e6..8db6658139a 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -106,6 +106,7 @@ var/list/admin_verbs_fun = list(
/client/proc/editappear
)
var/list/admin_verbs_spawn = list(
+ /datum/admins/proc/spawn_fruit,
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
/client/proc/respawn_character
)
diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm
index 87617d95cef..94ef9b3bdf3 100644
--- a/code/modules/food/recipes_microwave.dm
+++ b/code/modules/food/recipes_microwave.dm
@@ -607,7 +607,7 @@ I said no!
/datum/recipe/nettlesoup
reagents = list("water" = 10)
items = list(
- /obj/item/weapon/grown/nettle,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/nettle,
/obj/item/weapon/reagent_containers/food/snacks/grown/potato,
/obj/item/weapon/reagent_containers/food/snacks/egg,
)
diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm
index d82807f738a..88bcfa6cfd8 100644
--- a/code/modules/hydroponics/grown_inedible.dm
+++ b/code/modules/hydroponics/grown_inedible.dm
@@ -8,7 +8,7 @@
var/plantname
var/potency = 1
-/obj/item/weapon/grown/New()
+/obj/item/weapon/grown/New(newloc,planttype)
..()
@@ -17,21 +17,20 @@
R.my_atom = src
//Handle some post-spawn var stuff.
- spawn(1)
- // Fill the object up with the appropriate reagents.
- if(!isnull(plantname))
- var/datum/seed/S = seed_types[plantname]
- if(!S || !S.chems)
- return
+ if(planttype)
+ plantname = planttype
+ var/datum/seed/S = seed_types[plantname]
+ if(!S || !S.chems)
+ return
- potency = S.potency
+ potency = S.potency
- for(var/rid in S.chems)
- var/list/reagent_data = S.chems[rid]
- var/rtotal = reagent_data[1]
- if(reagent_data.len > 1 && potency > 0)
- rtotal += round(potency/reagent_data[2])
- reagents.add_reagent(rid,max(1,rtotal))
+ for(var/rid in S.chems)
+ var/list/reagent_data = S.chems[rid]
+ var/rtotal = reagent_data[1]
+ if(reagent_data.len > 1 && potency > 0)
+ rtotal += round(potency/reagent_data[2])
+ reagents.add_reagent(rid,max(1,rtotal))
/obj/item/weapon/grown/log
name = "towercap"
@@ -63,111 +62,6 @@
del(src)
return
-/obj/item/weapon/grown/sunflower // FLOWER POWER!
- plantname = "sunflowers"
- name = "sunflower"
- desc = "It's beautiful! A certain person might beat you to death if you trample these."
- icon = 'icons/obj/harvest.dmi'
- icon_state = "sunflower"
- damtype = "fire"
- force = 0
- flags = TABLEPASS
- throwforce = 1
- w_class = 1.0
- throw_speed = 1
- throw_range = 3
-
-/obj/item/weapon/grown/sunflower/attack(mob/M as mob, mob/user as mob)
- M << " [user] smacks you with a sunflower!FLOWER POWER"
- user << " Your sunflower's FLOWER POWER strikes [M]"
-
-/obj/item/weapon/grown/nettle // -- Skie
- plantname = "nettle"
- desc = "It's probably not wise to touch it with bare hands..."
- icon = 'icons/obj/weapons.dmi'
- name = "nettle"
- icon_state = "nettle"
- damtype = "fire"
- force = 15
- flags = TABLEPASS
- throwforce = 1
- w_class = 2.0
- throw_speed = 1
- throw_range = 3
- origin_tech = "combat=1"
- attack_verb = list("stung")
- hitsound = ""
-
- var/potency_divisior = 5
-
-/obj/item/weapon/grown/nettle/New()
- ..()
- spawn(5)
- force = round((5+potency/potency_divisior), 1)
-
-/obj/item/weapon/grown/nettle/pickup(mob/living/carbon/human/user as mob)
- if(istype(user) && !user.gloves)
- user << "\red The nettle burns your bare hand!"
- if(istype(user, /mob/living/carbon/human))
- var/organ = ((user.hand ? "l_":"r_") + "arm")
- var/datum/organ/external/affecting = user.get_organ(organ)
- if(affecting.take_damage(0,force))
- user.UpdateDamageIcon()
- else
- user.take_organ_damage(0,force)
- return 1
- return 0
-
-/obj/item/weapon/grown/nettle/proc/lose_leaves(var/mob/user)
- if(force > 0)
- playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
- force -= rand(1,(force/3)+1) // When you whack someone with it, leaves fall off
-
- sleep(1)
-
- if(force <= 0)
- if(user)
- user << "All the leaves have fallen off \the [src] from violent whacking."
- user.drop_from_inventory(src)
- del(src)
-
-/obj/item/weapon/grown/nettle/death // -- Skie
- plantname = "deathnettle"
- desc = "The \red glowing \black nettle incites \redrage\black in you just from looking at it!"
- name = "deathnettle"
- icon_state = "deathnettle"
- origin_tech = "combat=3"
- potency_divisior = 2.5
-
-/obj/item/weapon/grown/nettle/death/pickup(mob/living/carbon/human/user as mob)
-
- if(..() && prob(50))
- user.Paralyse(5)
- user << "\red You are stunned by the deathnettle when you try picking it up!"
-
-/obj/item/weapon/grown/nettle/attack(mob/living/carbon/M as mob, mob/user as mob)
-
- if(!..()) return
-
- lose_leaves(user)
-
-/obj/item/weapon/grown/nettle/death/attack(mob/living/carbon/M as mob, mob/user as mob)
-
- if(!..()) return
-
- if(istype(M, /mob/living))
- M << "\red You are stunned by the powerful acid of the deathnettle!"
-
- M.attack_log += text("\[[time_stamp()]\] Had the [src.name] used on them by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] on [M.name] ([M.ckey]) (JMP)")
-
- M.eye_blurry += force/7
- if(prob(20))
- M.Paralyse(force/6)
- M.Weaken(force/15)
- M.drop_item()
-
/obj/item/weapon/corncob
name = "corn cob"
desc = "A reminder of meals gone by."
@@ -185,4 +79,4 @@
user << "You use [W] to fashion a pipe out of the corn cob!"
new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc)
del(src)
- return
+ return
\ No newline at end of file
diff --git a/code/modules/hydroponics/hydro_tools.dm b/code/modules/hydroponics/hydro_tools.dm
index 328e1a020ec..6de670f417e 100644
--- a/code/modules/hydroponics/hydro_tools.dm
+++ b/code/modules/hydroponics/hydro_tools.dm
@@ -136,7 +136,7 @@
switch(grown_seed.spread)
if(1)
- dat += "
It is capable of growing beyond the confines of a tray."
+ dat += "
It is able to be planted outside of a tray."
if(2)
dat += "
It is a robust and vigorous vine that will spread rapidly."
@@ -156,6 +156,21 @@
if(grown_seed.flowers)
dat += "
It has [grown_seed.flower_colour ? "flowers" : "flowers"]."
+ if(grown_seed.produces_power)
+ user << "
The fruit will function as a battery if prepared appropriately."
+
+ if(grown_seed.stings)
+ user << "
The fruit is covered in stinging spines."
+
+ if(grown_seed.juicy)
+ user << "
The fruit is excessively juicy."
+
+ if(grown_seed.explosive)
+ user << "
The fruit is internally unstable."
+
+ if(grown_seed.teleporting)
+ user << "
The fruit is temporal/spatially unstable."
+
if(dat)
user << browse(dat,"window=plant_analyzer")
diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/hydro_tray.dm
index eafff17b073..b082a609bc1 100644
--- a/code/modules/hydroponics/hydro_tray.dm
+++ b/code/modules/hydroponics/hydro_tray.dm
@@ -642,12 +642,7 @@
user << "You plant the [S.seed.seed_name] [S.seed.seed_noun]."
- if(S.seed.spread == 1)
- msg_admin_attack("[key_name(user)] has planted a creeper packet.")
- var/obj/effect/plant_controller/creeper/PC = new(get_turf(src))
- if(PC)
- PC.seed = S.seed
- else if(S.seed.spread == 2)
+ if(S.seed.spread == 2)
msg_admin_attack("[key_name(user)] has planted a spreading vine packet.")
var/obj/effect/plant_controller/PC = new(get_turf(src))
if(PC)
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index 33e6f47c574..0ff3935fdae 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -99,7 +99,7 @@ proc/populate_seed_list()
var/spread = 0 // 0 limits plant to tray, 1 = creepers, 2 = vines.
var/carnivorous = 0 // 0 = none, 1 = eat pests in tray, 2 = eat living things (when a vine).
var/parasite = 0 // 0 = no, 1 = gain health from weed level.
- var/immutable = 0 // If set, plant will never mutate. If -1, plant is highly mutable.
+ var/immutable = 0 // If set, plant will never mutate. If -1, plant is highly mutable.
var/alter_temp // If set, the plant will periodically alter local temp by this amount.
// Cosmetics.
@@ -113,6 +113,200 @@ proc/populate_seed_list()
var/flower_icon = "vine_fruit" // Which overlay to use.
var/flower_colour // Which colour to use.
+ // Special traits.
+ var/produces_power // Can be used to make a battery.
+ var/juicy // When thrown, causes a splatter decal.
+ var/stings // Can cause damage/inject reagents when thrown or handled.
+ var/explosive // When thrown, acts as a grenade.
+ var/teleporting // Uses the bluespace tomato effect.
+ var/splat_type = /obj/effect/decal/cleanable/fruit_smudge
+
+// Does brute damage to a target.
+/datum/seed/proc/do_thorns(var/mob/living/carbon/human/target, var/obj/item/fruit, var/target_limb)
+
+ if(!istype(target) || !carnivorous)
+ return
+
+ if(!target_limb) target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin")
+ var/datum/organ/external/affecting = target.get_organ(target_limb)
+ var/damage = 0
+
+ if(carnivorous == 2)
+ if(affecting)
+ target << "\The [fruit]'s thorns pierce your [affecting.display_name] greedily!"
+ else
+ target << "\The [fruit]'s thorns pierce your flesh greedily!"
+ damage = potency/2
+ else
+ if(affecting)
+ target << "\The [fruit]'s thorns dig deeply into your [affecting.display_name]!"
+ else
+ target << "\The [fruit]'s thorns dig deeply into your flesh!"
+ damage = potency/5
+
+ if(affecting)
+ affecting.take_damage(damage, 0)
+ affecting.add_autopsy_data("Thorns",damage)
+ else
+ target.adjustBruteLoss(damage)
+ target.UpdateDamageIcon()
+ target.updatehealth()
+
+// Adds reagents to a target.
+/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit)
+ if(!stings)
+ return
+ if(chems && chems.len)
+ target << "You are stung by \the [fruit]!"
+ for(var/rid in chems)
+ var/injecting = min(5,max(1,potency/5))
+ target.reagents.add_reagent(rid,injecting)
+
+//Splatter a turf.
+/datum/seed/proc/splatter(var/turf/T,var/obj/item/thrown)
+ if(splat_type)
+ var/obj/effect/decal/cleanable/fruit_smudge/splat = new splat_type(T)
+ splat.name = "[thrown.name] [pick("smear","smudge","splatter")]"
+ if(biolum)
+ if(biolum_colour)
+ splat.l_color = biolum_colour
+ splat.SetLuminosity(biolum)
+ if(istype(splat))
+ if(product_colour)
+ splat.color = product_colour
+
+ if(chems)
+ for(var/mob/living/M in T.contents)
+ if(!M.reagents)
+ continue
+ for(var/chem in chems)
+ var/injecting = min(5,max(1,potency/3))
+ M.reagents.add_reagent(chem,injecting)
+
+//Applies an effect to a target atom.
+/datum/seed/proc/thrown_at(var/obj/item/thrown,var/atom/target)
+
+ var/splatted
+ var/turf/origin_turf = get_turf(target)
+
+ if(explosive)
+
+ var/flood_dist = min(10,max(1,potency/10))
+ var/list/open_turfs = list()
+ var/list/closed_turfs = list()
+ var/list/valid_turfs = list()
+ open_turfs |= origin_turf
+
+ // Flood fill to get affected turfs.
+ while(open_turfs.len)
+ var/turf/T = pick(open_turfs)
+ open_turfs -= T
+ closed_turfs |= T
+ valid_turfs |= T
+
+ for(var/dir in alldirs)
+ var/turf/neighbor = get_step(T,dir)
+ if(!neighbor || (neighbor in closed_turfs) || (neighbor in open_turfs))
+ continue
+ if(neighbor.density || get_dist(neighbor,origin_turf) > flood_dist || istype(neighbor,/turf/space))
+ closed_turfs |= neighbor
+ continue
+ // Check for windows.
+ var/no_los
+ for(var/turf/target_turf in getline(origin_turf,neighbor))
+ if(target_turf.density)
+ no_los = 1
+ break
+
+ if(!no_los)
+ var/los_dir = get_dir(neighbor,origin_turf)
+ var/list/blocked = list()
+ for(var/obj/machinery/door/D in neighbor.contents)
+ if(istype(D,/obj/machinery/door/window))
+ blocked |= D.dir
+ else
+ if(D.density)
+ no_los = 1
+ break
+ for(var/obj/structure/window/W in neighbor.contents)
+ if(W.is_fulltile())
+ no_los = 1
+ break
+ blocked |= W.dir
+ if(!no_los)
+ switch(los_dir)
+ if(NORTHEAST)
+ if((NORTH in blocked) && (EAST in blocked))
+ no_los = 1
+ if(SOUTHEAST)
+ if((SOUTH in blocked) && (EAST in blocked))
+ no_los = 1
+ if(NORTHWEST)
+ if((NORTH in blocked) && (WEST in blocked))
+ no_los = 1
+ if(SOUTHWEST)
+ if((SOUTH in blocked) && (WEST in blocked))
+ no_los = 1
+ else
+ if(los_dir in blocked)
+ no_los = 1
+ if(no_los)
+ closed_turfs |= neighbor
+ continue
+ open_turfs |= neighbor
+
+ for(var/turf/T in valid_turfs)
+ for(var/mob/living/M in T.contents)
+ apply_special_effect(M)
+ splatter(T,thrown)
+ origin_turf.visible_message("The [thrown.name] violently explodes against [target]!")
+ del(thrown)
+ return
+
+ if(istype(target,/mob/living))
+ splatted = apply_special_effect(target,thrown)
+ else if(istype(target,/turf))
+ splatted = 1
+ for(var/mob/living/M in target.contents)
+ apply_special_effect(M)
+
+ if(juicy && splatted)
+ splatter(origin_turf,thrown)
+ origin_turf.visible_message("The [thrown.name] splatters against [target]!")
+ del(thrown)
+
+/datum/seed/proc/apply_special_effect(var/mob/living/target,var/obj/item/thrown)
+
+ var/impact = 1
+ do_sting(target,thrown)
+ do_thorns(target,thrown)
+
+ // Bluespace tomato code copied over from grown.dm.
+ if(teleporting)
+
+ //Plant potency determines radius of teleport.
+ var/outer_teleport_radius = potency/5
+ var/inner_teleport_radius = potency/15
+
+ var/list/turfs = list()
+ if(inner_teleport_radius > 0)
+ for(var/turf/T in orange(target,outer_teleport_radius))
+ if(get_dist(target,T) >= inner_teleport_radius)
+ turfs |= T
+
+ if(turfs.len)
+ // Moves the mob, causes sparks.
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(3, 1, get_turf(target))
+ s.start()
+ var/turf/picked = get_turf(pick(turfs)) // Just in case...
+ new/obj/effect/decal/cleanable/molten_item(get_turf(target)) // Leave a pile of goo behind for dramatic effect...
+ target.loc = picked // And teleport them to the chosen location.
+
+ impact = 1
+
+ return impact
+
//Creates a random seed. MAKE SURE THE LINE HAS DIVERGED BEFORE THIS IS CALLED.
/datum/seed/proc/randomize()
@@ -192,6 +386,20 @@ proc/populate_seed_list()
if(prob(20))
harvest_repeat = 1
+ if(prob(15))
+ juicy = 1
+
+ if(prob(5))
+ stings = 1
+
+ if(prob(5))
+ produces_power = 1
+
+ if(prob(1))
+ explosive = 1
+ else if(prob(1))
+ teleporting = 1
+
if(prob(5))
consume_gasses = list()
var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide")
@@ -560,7 +768,7 @@ proc/populate_seed_list()
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)
+/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount)
if(!user)
return
@@ -569,8 +777,8 @@ proc/populate_seed_list()
if(!isnull(products) && products.len && yield > 0)
got_product = 1
- if(!got_product && !harvest_sample)
- user << "\red You fail to harvest anything useful."
+ if(!force_amount && !got_product && !harvest_sample)
+ user << "You fail to harvest anything useful."
else
user << "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name]."
@@ -587,18 +795,28 @@ proc/populate_seed_list()
return
var/total_yield = 0
- if(yield > -1)
- if(isnull(yield_mod) || yield_mod < 1)
- yield_mod = 0
- total_yield = yield
- else
- total_yield = yield + rand(yield_mod)
- total_yield = max(1,total_yield)
+ if(!isnull(force_amount))
+ total_yield = force_amount
+ else
+ if(yield > -1)
+ if(isnull(yield_mod) || yield_mod < 1)
+ yield_mod = 0
+ total_yield = yield
+ else
+ total_yield = yield + rand(yield_mod)
+ total_yield = max(1,total_yield)
currently_querying = list()
for(var/i = 0;i\The [src] pierces your flesh greedily!"
-
- var/damage = rand(round(seed.potency/2),seed.potency)
- if(!istype(H))
- H.adjustBruteLoss(damage)
- return
-
- var/datum/organ/external/affecting = H.get_organ(pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin"))
-
- if(affecting)
- affecting.take_damage(damage, 0)
- if(affecting.parent)
- affecting.parent.add_autopsy_data("[plant_damage_noun]", damage)
- else
- H.adjustBruteLoss(damage)
-
- H.UpdateDamageIcon()
- H.updatehealth()
-
- // Inject some chems.
- if(seed.chems && seed.chems.len && istype(H))
- H << "You feel something seeping into your skin!"
- for(var/rid in seed.chems)
- var/injecting = min(5,max(1,seed.potency/5))
- H.reagents.add_reagent(rid,injecting)
+ seed.do_thorns(buckled_mob,src)
+ seed.do_sting(buckled_mob,src)
/obj/effect/plantsegment/proc/update()
if(!seed) return
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index a2ea7c6f0c0..84905a4efb5 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -831,8 +831,8 @@
/obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
/obj/item/stack/sheet/mineral/silver = list("silver" = 20),
/obj/item/stack/sheet/mineral/gold = list("gold" = 20),
- /obj/item/weapon/grown/nettle/death = list("pacid" = 0),
- /obj/item/weapon/grown/nettle = list("sacid" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/nettle/death = list("pacid" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/nettle = list("sacid" = 0),
//Blender Stuff
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index 827c400898f..72bb60b4c62 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -28,8 +28,8 @@
return
/obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone)
- if (can_operate(M)) //Checks if mob is lying down on table for surgery
- if (do_surgery(M,user,src))
+ if(can_operate(M)) //Checks if mob is lying down on table for surgery
+ if(do_surgery(M,user,src))
return
// this prevented pills, food, and other things from being picked up by bags.
diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm
index 7aaad7a6785..1a964e66500 100644
--- a/code/modules/reagents/reagent_containers/food/snacks.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks.dm
@@ -32,9 +32,10 @@
return
/obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone)
- if(!reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it.
- user << "\red None of [src] left, oh no!"
- M.drop_from_inventory(src) //so icons update :[
+
+ if(!reagents.total_volume)
+ user << "None of [src] left!"
+ user.drop_from_inventory(src)
del(src)
return 0
@@ -106,9 +107,6 @@
return 0
-/obj/item/weapon/reagent_containers/food/snacks/afterattack(obj/target, mob/user, proximity)
- return ..()
-
/obj/item/weapon/reagent_containers/food/snacks/examine(mob/user)
if(!..(user, 1))
return
diff --git a/code/modules/reagents/reagent_containers/food/snacks/grown.dm b/code/modules/reagents/reagent_containers/food/snacks/grown.dm
index d570f13861e..c49f38c4348 100644
--- a/code/modules/reagents/reagent_containers/food/snacks/grown.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks/grown.dm
@@ -1,46 +1,190 @@
+//Grown foods.
+/obj/item/weapon/reagent_containers/food/snacks/grown
-
-// ***********************************************************
-// Foods that are produced from hydroponics ~~~~~~~~~~
-// Data from the seeds carry over to these grown foods
-// ***********************************************************
-
-//Grown foods
-//Subclass so we can pass on values
-/obj/item/weapon/reagent_containers/food/snacks/grown/
- var/plantname
- var/potency = -1
+ name = "fruit"
+ desc = "It's a fruit."
icon = 'icons/obj/harvest.dmi'
- New(newloc,newpotency)
- if (!isnull(newpotency))
- potency = newpotency
- ..()
- src.pixel_x = rand(-5.0, 5)
- src.pixel_y = rand(-5.0, 5)
-/obj/item/weapon/reagent_containers/food/snacks/grown/New()
+ var/plantname
+ var/datum/seed/seed
+ var/potency = -1
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/New(newloc,planttype)
+
..()
- //Handle some post-spawn var stuff.
- spawn(1)
- // Fill the object up with the appropriate reagents.
- if(!isnull(plantname))
- var/datum/seed/S = seed_types[plantname]
- if(!S || !S.chems)
+ src.pixel_x = rand(-5.0, 5)
+ src.pixel_y = rand(-5.0, 5)
+
+ // Fill the object up with the appropriate reagents.
+ if(planttype)
+ plantname = planttype
+ seed = seed_types[plantname]
+ if(!seed || !seed.chems)
+ return
+
+ potency = seed.potency
+
+ for(var/rid in seed.chems)
+ var/list/reagent_data = seed.chems[rid]
+ var/rtotal = reagent_data[1]
+ if(reagent_data.len > 1 && potency > 0)
+ rtotal += round(potency/reagent_data[2])
+ reagents.add_reagent(rid,max(1,rtotal))
+
+ if(reagents.total_volume > 0)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(var/mob/living/M)
+ if(seed && seed.juicy)
+ if(istype(M))
+
+ if(M.buckled)
return
- potency = S.potency
+ if(istype(M,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ if(H.shoes && H.shoes.flags & NOSLIP)
+ return
- for(var/rid in S.chems)
- var/list/reagent_data = S.chems[rid]
- var/rtotal = reagent_data[1]
- if(reagent_data.len > 1 && potency > 0)
- rtotal += round(potency/reagent_data[2])
- reagents.add_reagent(rid,max(1,rtotal))
+ M.stop_pulling()
+ M << "\blue You slipped on the [name]!"
+ playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
+ M.Stun(8)
+ M.Weaken(5)
- if(reagents.total_volume > 0)
- bitesize = 1+round(reagents.total_volume / 2, 1)
+/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom)
+ ..()
+ if(seed) seed.thrown_at(src,hit_atom)
+/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ ..()
+ if(seed && seed.produces_power && istype(W, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/C = W
+ if(C.use(5))
+ //TODO: generalize this.
+ user << "You add some cable to the [src.name] and slide it inside the battery casing."
+ var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(get_turf(user))
+ if(src.loc == user && !(user.l_hand && user.r_hand) && istype(user,/mob/living/carbon/human))
+ user.put_in_hands(pocell)
+ pocell.maxcharge = src.potency * 10
+ pocell.charge = pocell.maxcharge
+ del(src)
+ return
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/attack(var/mob/living/carbon/M, var/mob/user, var/def_zone)
+ if(user == M)
+ return ..()
+
+ if(user.a_intent == "hurt")
+
+ // This is being copypasted here because reagent_containers (WHY DOES FOOD DESCEND FROM THAT) overrides it completely.
+ // TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z
+ if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0
+
+ user.lastattacked = M
+ M.lastattacker = user
+ user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])"
+ M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])"
+ msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" )
+
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ var/hit = H.attacked_by(src, user, def_zone)
+ if(hit && hitsound)
+ playsound(loc, hitsound, 50, 1, -1)
+ return hit
+ else
+ if(attack_verb.len)
+ user.visible_message("[M] has been [pick(attack_verb)] with [src] by [user]!")
+ else
+ user.visible_message("[M] has been attacked with [src] by [user]!")
+
+ if (hitsound)
+ playsound(loc, hitsound, 50, 1, -1)
+ switch(damtype)
+ if("brute")
+ M.take_organ_damage(force)
+ if(prob(33))
+ var/turf/simulated/location = get_turf(M)
+ if(istype(location)) location.add_blood_floor(M)
+ if("fire")
+ if (!(COLD_RESISTANCE in M.mutations))
+ M.take_organ_damage(0, force)
+ M.updatehealth()
+
+ if(seed && seed.stings)
+ if(!reagents || reagents.total_volume <= 0)
+ return
+ reagents.remove_any(rand(1,3))
+ seed.thrown_at(src,M)
+ sleep(-1)
+ if(!src)
+ return
+ if(prob(35))
+ if(user)
+ user << "\The [src] has fallen to bits."
+ user.drop_from_inventory(src)
+ del(src)
+
+ add_fingerprint(user)
+ return 1
+
+ else
+ ..()
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/attack_self(mob/user as mob)
+
+ if(!seed)
+ return
+
+ if(istype(user.loc,/turf/space))
+ return
+
+ if(user.a_intent == "hurt")
+ user.visible_message("\The [user] squashes \the [src]!")
+ seed.thrown_at(src,user)
+ sleep(-1)
+ if(src) del(src)
+ return
+
+ if(seed.spread == 0)
+ return
+
+ // TODO: Generalize.
+ var/obj/effect/glowshroom/planted = new /obj/effect/glowshroom(user.loc)
+ planted.delay = 50
+ planted.endurance = 100
+ planted.potency = potency
+
+ user << "You plant the [src.name]."
+ del(src)
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user)
+ ..()
+ if(!seed)
+ return
+ if(seed.biolum)
+ user.SetLuminosity(user.luminosity + seed.biolum)
+ SetLuminosity(0)
+ if(seed.stings)
+ var/mob/living/carbon/human/H = user
+ if(istype(H) && H.gloves)
+ return
+ if(!reagents || reagents.total_volume <= 0)
+ return
+ reagents.remove_any(rand(1,3))
+ seed.do_thorns(H,src)
+ seed.do_sting(H,src,pick("r_hand","l_hand"))
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user)
+ if(!..() || !seed)
+ return
+ if(seed.biolum)
+ user.SetLuminosity(user.luminosity - seed.biolum)
+ SetLuminosity(seed.biolum)
+
+// Food object defines follow.
/obj/item/weapon/reagent_containers/food/snacks/grown/corn
name = "ear of corn"
desc = "Needs some butter!"
@@ -82,18 +226,6 @@
filling_color = "#E6E8DA"
plantname = "potato"
-/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/C = W
- if(C.use(5))
- user << "You add some cable to the potato and slide it inside the battery encasing."
- var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(user.loc)
- pocell.maxcharge = src.potency * 10
- pocell.charge = pocell.maxcharge
- del(src)
- return
-
/obj/item/weapon/reagent_containers/food/snacks/grown/grapes
name = "bunch of grapes"
desc = "Nutritious!"
@@ -139,62 +271,13 @@
filling_color = "#C4C4C4"
plantname = "plastic"
-/obj/item/weapon/reagent_containers/food/snacks/grown/shand
- name = "S'rendarr's Hand leaf"
- desc = "A leaf sample from a lowland thicket shrub. Smells strongly like wax."
- icon_state = "shand"
- filling_color = "#70C470"
- plantname = "shand"
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/mtear
- name = "sprig of Messa's Tear"
- desc = "A mountain climate herb with a soft, cold blue flower, known to contain an abundance of healing chemicals."
- icon_state = "mtear"
- filling_color = "#70C470"
- plantname = "mtear"
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/mtear/attack_self(mob/user as mob)
- if(istype(user.loc,/turf/space))
- return
- var/obj/item/stack/medical/ointment/tajaran/poultice = new /obj/item/stack/medical/ointment/tajaran(user.loc)
-
- poultice.heal_burn = potency
- del(src)
-
- user << "You mash the petals into a poultice."
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/shand/attack_self(mob/user as mob)
- if(istype(user.loc,/turf/space))
- return
- var/obj/item/stack/medical/bruise_pack/tajaran/poultice = new /obj/item/stack/medical/bruise_pack/tajaran(user.loc)
-
- poultice.heal_brute = potency
- del(src)
-
- user << "You mash the leaves into a poultice."
-
/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries
name = "bunch of glow-berries"
desc = "Nutritious!"
- var/light_on = 1
- var/brightness_on = 2 //luminosity when on
filling_color = "#D3FF9E"
icon_state = "glowberrypile"
plantname = "glowberries"
-/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/Del()
- if(istype(loc,/mob))
- loc.SetLuminosity(round(loc.luminosity - potency/5,1))
- ..()
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/pickup(mob/user)
- src.SetLuminosity(0)
- user.SetLuminosity(round(user.luminosity + (potency/5),1))
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/dropped(mob/user)
- user.SetLuminosity(round(user.luminosity - (potency/5),1))
- src.SetLuminosity(round(potency/5,1))
-
/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod
name = "cocoa pod"
desc = "Can be ground into cocoa powder."
@@ -279,22 +362,6 @@
slices_num = 5
plantname = "watermelon"
-/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin
- name = "pumpkin"
- desc = "It's large and scary."
- icon_state = "pumpkin"
- potency = 10
- filling_color = "#FAB728"
- plantname = "pumpkin"
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob)
- ..()
- if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/twohanded/fireaxe) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/melee/energy))
- user.show_message("You carve a face into [src]!", 1)
- new /obj/item/clothing/head/pumpkinhead (user.loc)
- del(src)
- return
-
/obj/item/weapon/reagent_containers/food/snacks/grown/lime
name = "lime"
desc = "It's so sour, your face will twist."
@@ -313,7 +380,7 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/orange
name = "orange"
- desc = "It's a tangy fruit."
+ desc = "It's an tangy fruit."
icon_state = "orange"
potency = 20
filling_color = "#FAAD28"
@@ -367,30 +434,6 @@
potency = 10
plantname = "tomato"
-/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/throw_impact(atom/hit_atom)
- ..()
- new/obj/effect/decal/cleanable/tomato_smudge(src.loc)
- src.visible_message("The [src.name] has been squashed.","You hear a smack.")
- del(src)
- return
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/killertomato
- name = "killer-tomato"
- desc = "I say to-mah-to, you say tom-mae-to... OH GOD IT'S EATING MY LEGS!!"
- icon_state = "killertomato"
- potency = 10
- filling_color = "#FF0000"
- potency = 30
- plantname = "killertomato"
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/killertomato/attack_self(mob/user as mob)
- if(istype(user.loc,/turf/space))
- return
- new /mob/living/simple_animal/tomato(user.loc)
- del(src)
-
- user << "You plant the killer-tomato."
-
/obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato
name = "blood-tomato"
desc = "So bloody...so...very...bloody....AHHHH!!!!"
@@ -399,16 +442,6 @@
filling_color = "#FF0000"
plantname = "bloodtomato"
-/obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato/throw_impact(atom/hit_atom)
- ..()
- new/obj/effect/decal/cleanable/blood/splatter(src.loc)
- src.visible_message("The [src.name] has been squashed.","You hear a smack.")
- src.reagents.reaction(get_turf(hit_atom))
- for(var/atom/A in get_turf(hit_atom))
- src.reagents.reaction(A)
- del(src)
- return
-
/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato
name = "blue-tomato"
desc = "I say blue-mah-to, you say blue-mae-to."
@@ -417,21 +450,6 @@
filling_color = "#586CFC"
plantname = "bluetomato"
-/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/throw_impact(atom/hit_atom)
- ..()
- new/obj/effect/decal/cleanable/blood/oil(src.loc)
- src.visible_message("The [src.name] has been squashed.","You hear a smack.")
- src.reagents.reaction(get_turf(hit_atom))
- for(var/atom/A in get_turf(hit_atom))
- src.reagents.reaction(A)
- del(src)
- return
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/Crossed(AM as mob|obj)
- if (istype(AM, /mob/living))
- var/mob/living/M = AM
- M.slip("the [src]!")
-
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat
name = "wheat"
desc = "Sigh... wheat... a-grain?"
@@ -518,14 +536,6 @@
potency = 30
plantname = "walkingmushroom"
-/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user as mob)
- if(istype(user.loc,/turf/space))
- return
- new /mob/living/simple_animal/mushroom(user.loc)
- del(src)
-
- user << "You plant the walking mushroom."
-
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle
name = "chanterelle cluster"
desc = "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!"
@@ -541,37 +551,6 @@
potency = 30
plantname = "glowshroom"
-/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user as mob)
- if(istype(user.loc,/turf/space))
- return
- var/obj/effect/glowshroom/planted = new /obj/effect/glowshroom(user.loc)
-
- planted.delay = 50
- planted.endurance = 100
- planted.potency = potency
- del(src)
-
- user << "You plant the glowshroom."
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/Del()
- if(istype(loc,/mob))
- loc.SetLuminosity(round(loc.luminosity - potency/10,1))
- ..()
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/pickup(mob/user)
- SetLuminosity(0)
- user.SetLuminosity(round(user.luminosity + (potency/10),1))
-
-/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/dropped(mob/user)
- user.SetLuminosity(round(user.luminosity - (potency/10),1))
- SetLuminosity(round(potency/10,1))
-
-
-// *************************************
-// Complex Grown Object Defines -
-// Putting these at the bottom so they don't clutter the list up. -Cheridan
-// *************************************
-
/obj/item/weapon/reagent_containers/food/snacks/grown/bluespacetomato
name = "blue-space tomato"
desc = "So lubricated, you might slip through space-time."
@@ -581,52 +560,85 @@
filling_color = "#91F8FF"
plantname = "bluespacetomato"
-/obj/item/weapon/reagent_containers/food/snacks/grown/bluespacetomato/throw_impact(atom/hit_atom)
+// Super special snowflake grown items below.
+/obj/item/weapon/reagent_containers/food/snacks/grown/shand
+ name = "S'rendarr's Hand leaf"
+ desc = "A leaf sample from a lowland thicket shrub. Smells strongly like wax."
+ icon_state = "shand"
+ filling_color = "#70C470"
+ plantname = "shand"
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/mtear
+ name = "sprig of Messa's Tear"
+ desc = "A mountain climate herb with a soft, cold blue flower, known to contain an abundance of healing chemicals."
+ icon_state = "mtear"
+ filling_color = "#70C470"
+ plantname = "mtear"
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/mtear/attack_self(mob/user as mob)
+ if(istype(user.loc,/turf/space))
+ return
+ var/obj/item/stack/medical/ointment/tajaran/poultice = new /obj/item/stack/medical/ointment/tajaran(user.loc)
+
+ poultice.heal_burn = potency
+ del(src)
+
+ user << "You mash the petals into a poultice."
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/shand/attack_self(mob/user as mob)
+ if(istype(user.loc,/turf/space))
+ return
+ var/obj/item/stack/medical/bruise_pack/tajaran/poultice = new /obj/item/stack/medical/bruise_pack/tajaran(user.loc)
+
+ poultice.heal_brute = potency
+ del(src)
+
+ user << "You mash the leaves into a poultice."
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin
+ name = "pumpkin"
+ desc = "It's large and scary."
+ icon_state = "pumpkin"
+ potency = 10
+ filling_color = "#FAB728"
+ plantname = "pumpkin"
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
- var/mob/M = usr
- var/outer_teleport_radius = potency/10 //Plant potency determines radius of teleport.
- var/inner_teleport_radius = potency/15
- var/list/turfs = new/list()
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- if(inner_teleport_radius < 1) //Wasn't potent enough, it just splats.
- new/obj/effect/decal/cleanable/blood/oil(src.loc)
- src.visible_message("The [src.name] has been squashed.","You hear a smack.")
+ if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/twohanded/fireaxe) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/melee/energy))
+ user.show_message("You carve a face into [src]!", 1)
+ new /obj/item/clothing/head/pumpkinhead (user.loc)
del(src)
return
- for(var/turf/T in orange(M,outer_teleport_radius))
- if(T in orange(M,inner_teleport_radius)) continue
- if(istype(T,/turf/space)) continue
- if(T.density) continue
- if(T.x>world.maxx-outer_teleport_radius || T.xworld.maxy-outer_teleport_radius || T.yThe [src.name] has been squashed, causing a distortion in space-time.","You hear a splat and a crackle.")
- del(src)
- return
\ No newline at end of file
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/sunflower // FLOWER POWER!
+ plantname = "sunflowers"
+ name = "sunflower"
+ desc = "A beautiful yellow flower."
+ icon_state = "sunflower"
+ damtype = "fire"
+ force = 0
+ throw_speed = 1
+ throw_range = 3
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/nettle
+ plantname = "nettle"
+ desc = "It's probably not wise to touch it with bare hands..."
+ icon = 'icons/obj/weapons.dmi'
+ name = "nettle"
+ icon_state = "nettle"
+ damtype = "fire"
+ force = 15
+ w_class = 2.0
+ throw_speed = 1
+ throw_range = 3
+ origin_tech = "combat=1"
+ attack_verb = list("stung")
+ hitsound = ""
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/nettle/death
+ plantname = "deathnettle"
+ desc = "A cruel and toxic-looking plant."
+ name = "deathnettle"
+ icon_state = "deathnettle"
+ origin_tech = "combat=3"
\ No newline at end of file