diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index ec77aa2e3a9..237c3ecf623 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -2,32 +2,37 @@
/obj/effect/glowshroom
name = "glowshroom"
+ desc = "Mycena Bregprox, a species of mushroom that glows in the dark."
anchored = 1
opacity = 0
density = 0
icon = 'icons/obj/lighting.dmi'
- icon_state = "glowshroomf"
+ icon_state = "glowshroom" //replaced in New
layer = 2.1
var/endurance = 30
var/potency = 30
var/delay = 1200
var/floor = 0
var/yield = 3
- var/spreadChance = 40
+ var/generation = 1
var/spreadIntoAdjacentChance = 60
- var/evolveChance = 2
- var/lastTick = 0
- var/spreaded = 1
+
+obj/effect/glowshroom/glowcap
+ name = "glowcap"
+ icon_state = "glowcap"
/obj/effect/glowshroom/single
- spreadChance = 0
+ yield = 0
+
+/obj/effect/glowshroom/examine(mob/user)
+ . = ..()
+ to_chat(user, "This is a [generation]\th generation [name]!")
/obj/effect/glowshroom/New()
-
..()
-
+ set_light(round(potency/10))
dir = CalcDir()
-
+ var/base_icon_state = initial(icon_state)
if(!floor)
switch(dir) //offset to make it be on the wall rather than on the floor
if(NORTH)
@@ -38,70 +43,52 @@
pixel_x = 32
if(WEST)
pixel_x = -32
- icon_state = "glowshroom[rand(1,3)]"
+ icon_state = "[base_icon_state][rand(1,3)]"
else //if on the floor, glowshroom on-floor sprite
- icon_state = "glowshroomf"
+ icon_state = "[base_icon_state]f"
- processing_objects += src
+ addtimer(src, "Spread", delay)
+/obj/effect/glowshroom/proc/Spread()
+ for(var/i = 1 to yield)
+ if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
+ var/list/possibleLocs = list()
+ var/spreadsIntoAdjacent = FALSE
- set_light(round(potency/10))
- lastTick = world.timeofday
+ if(prob(spreadIntoAdjacentChance))
+ spreadsIntoAdjacent = TRUE
+ for(var/turf/simulated/floor/earth in view(3,src))
+ if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth))
+ possibleLocs += earth
+ CHECK_TICK
-/obj/effect/glowshroom/Destroy()
- processing_objects -= src
- return ..()
+ if(!possibleLocs.len)
+ break
-/obj/effect/glowshroom/process()
- if(!spreaded)
- return
+ var/turf/newLoc = pick(possibleLocs)
- if(((world.timeofday - lastTick) > delay) || ((world.timeofday - lastTick) < 0))
- lastTick = world.timeofday
- spreaded = 0
+ var/shroomCount = 0 //hacky
+ var/placeCount = 1
+ for(var/obj/effect/glowshroom/shroom in newLoc)
+ shroomCount++
+ for(var/wallDir in cardinal)
+ var/turf/isWall = get_step(newLoc,wallDir)
+ if(isWall.density)
+ placeCount++
+ if(shroomCount >= placeCount)
+ continue
- for(var/i=1,i<=yield,i++)
- if(prob(spreadChance))
- var/list/possibleLocs = list()
- var/spreadsIntoAdjacent = 0
+ var/obj/effect/glowshroom/child = new type(newLoc)//The baby mushrooms have different stats :3
+ child.potency = max(potency + rand(-3,6), 0)
+ child.yield = max(yield + rand(-1,2), 0)
+ child.delay = max(delay + rand(-30,60), 0)
+ child.endurance = max(endurance + rand(-3,6), 1)
+ child.generation = generation + 1
- if(prob(spreadIntoAdjacentChance))
- spreadsIntoAdjacent = 1
-
- for(var/turf/simulated/floor/plating/airless/asteroid/earth in view(3,src))
- if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth))
- possibleLocs += earth
-
- if(!possibleLocs.len)
- break
-
- var/turf/newLoc = pick(possibleLocs)
-
- var/shroomCount = 0 //hacky
- var/placeCount = 1
- for(var/obj/effect/glowshroom/shroom in newLoc)
- shroomCount++
- for(var/wallDir in cardinal)
- var/turf/isWall = get_step(newLoc,wallDir)
- if(isWall.density)
- placeCount++
- if(shroomCount >= placeCount)
- continue
-
- var/obj/effect/glowshroom/child = new /obj/effect/glowshroom(newLoc)
- child.potency = potency
- child.yield = yield
- child.delay = delay
- child.endurance = endurance
-
- spreaded++
-
- if(prob(evolveChance)) //very low chance to evolve on its own
- potency += rand(4,6)
+ CHECK_TICK
/obj/effect/glowshroom/proc/CalcDir(turf/location = loc)
- //set background = 1
var/direction = 16
for(var/wallDir in cardinal)
@@ -133,28 +120,22 @@
floor = 1
return 1
-/obj/effect/glowshroom/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
+/obj/effect/glowshroom/attackby(obj/item/I, mob/user)
..()
-
- endurance -= W.force
-
- CheckEndurance()
+ if(I.damtype != STAMINA)
+ endurance -= I.force
+ CheckEndurance()
/obj/effect/glowshroom/ex_act(severity)
switch(severity)
- if(1.0)
+ if(1)
qdel(src)
- return
- if(2.0)
+ if(2)
if(prob(50))
qdel(src)
- return
- if(3.0)
+ if(3)
if(prob(5))
qdel(src)
- return
- else
- return
/obj/effect/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index fa67573307c..ba5ced7723c 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -4,6 +4,7 @@
luminosity = 1
var/intact = 1
+ var/turf/baseturf = /turf/space
var/slowdown = 0 //negative for faster, positive for slower
//Properties for open tiles (/floor)
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index cf00e4f78b9..13929b95c4c 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -1,11 +1,564 @@
-/var/global/spacevines_spawned = 0
-
-/datum/event/spacevine
- announceWhen = 10
+//Types of usual mutations
+#define POSITIVE 1
+#define NEGATIVE 2
+#define MINOR_NEGATIVE 3
/datum/event/spacevine/start()
- spacevine_infestation()
- spacevines_spawned = 1
+ var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
-/datum/event/spacevine/announce()
- command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
+ var/obj/effect/spacevine/SV = new()
+
+ for(var/area/hallway/A in world)
+ for(var/turf/F in A)
+ if(F.Enter(SV))
+ turfs += F
+
+ qdel(SV)
+
+ if(turfs.len) //Pick a turf to spawn at if we can
+ var/turf/T = pick(turfs)
+ new/obj/effect/spacevine_controller(T) //spawn a controller at turf
+
+
+/datum/spacevine_mutation
+ var/name = ""
+ var/severity = 1
+ var/hue
+ var/quality
+
+/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/effect/spacevine/holder)
+ holder.mutations |= src
+ holder.color = hue
+
+/datum/spacevine_mutation/proc/process_mutation(obj/effect/spacevine/holder)
+ return
+
+/datum/spacevine_mutation/proc/process_temperature(obj/effect/spacevine/holder, temp, volume)
+ return
+
+/datum/spacevine_mutation/proc/on_birth(obj/effect/spacevine/holder)
+ return
+
+/datum/spacevine_mutation/proc/on_grow(obj/effect/spacevine/holder)
+ return
+
+/datum/spacevine_mutation/proc/on_death(obj/effect/spacevine/holder)
+ return
+
+/datum/spacevine_mutation/proc/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
+ . = expected_damage
+
+/datum/spacevine_mutation/proc/on_cross(obj/effect/spacevine/holder, mob/crosser)
+ return
+
+/datum/spacevine_mutation/proc/on_chem(obj/effect/spacevine/holder, datum/reagent/R)
+ return
+
+/datum/spacevine_mutation/proc/on_eat(obj/effect/spacevine/holder, mob/living/eater)
+ return
+
+/datum/spacevine_mutation/proc/on_spread(obj/effect/spacevine/holder, turf/target)
+ return
+
+/datum/spacevine_mutation/proc/on_buckle(obj/effect/spacevine/holder, mob/living/buckled)
+ return
+
+/datum/spacevine_mutation/proc/on_explosion(severity)
+ return
+
+
+/datum/spacevine_mutation/space_covering
+ name = "space protective"
+ hue = "#aa77aa"
+ quality = POSITIVE
+
+/turf/simulated/floor/vines
+ color = "#aa77aa"
+ icon_state = "vinefloor"
+ broken_states = list()
+
+
+//All of this shit is useless for vines
+
+/turf/simulated/floor/vines/attackby()
+ return
+
+/turf/simulated/floor/vines/burn_tile()
+ return
+
+/turf/simulated/floor/vines/break_tile()
+ return
+
+/turf/simulated/floor/vines/make_plating()
+ return
+
+/turf/simulated/floor/vines/break_tile_to_plating()
+ return
+
+/turf/simulated/floor/vines/ex_act(severity)
+ if(severity < 3)
+ ChangeTurf(baseturf)
+
+/turf/simulated/floor/vines/narsie_act()
+ if(prob(20))
+ ChangeTurf(baseturf) //nar sie eats this shit
+
+/turf/simulated/floor/vines/singularity_pull(S, current_size)
+ if(current_size >= STAGE_FIVE)
+ if(prob(50))
+ ChangeTurf(baseturf)
+
+/turf/simulated/floor/vines/ChangeTurf(turf/open/floor/T)
+ for(var/obj/effect/spacevine/SV in src)
+ qdel(SV)
+ return ..()
+
+/datum/spacevine_mutation/space_covering
+ var/static/list/coverable_turfs
+
+/datum/spacevine_mutation/space_covering/New()
+ . = ..()
+ if(!coverable_turfs)
+ coverable_turfs = typecacheof(list(
+ /turf/space
+ ))
+ coverable_turfs -= typecacheof(list(
+ /turf/space/transit
+ ))
+
+/datum/spacevine_mutation/space_covering/on_grow(obj/effect/spacevine/holder)
+ process_mutation(holder)
+
+/datum/spacevine_mutation/space_covering/process_mutation(obj/effect/spacevine/holder)
+ var/turf/T = get_turf(holder)
+ if(is_type_in_typecache(T, coverable_turfs))
+ var/currtype = T.type
+ T.ChangeTurf(/turf/simulated/floor/vines)
+ T.baseturf = currtype
+
+/datum/spacevine_mutation/space_covering/on_death(obj/effect/spacevine/holder)
+ var/turf/T = get_turf(holder)
+ if(istype(T, /turf/simulated/floor/vines))
+ T.ChangeTurf(T.baseturf)
+
+/datum/spacevine_mutation/bluespace
+ name = "bluespace"
+ hue = "#3333ff"
+ quality = MINOR_NEGATIVE
+
+/datum/spacevine_mutation/bluespace/on_spread(obj/effect/spacevine/holder, turf/target)
+ if(holder.energy > 1 && !locate(/obj/effect/spacevine) in target)
+ holder.master.spawn_spacevine_piece(target, holder)
+
+/datum/spacevine_mutation/light
+ name = "light"
+ hue = "#ffff00"
+ quality = POSITIVE
+ severity = 4
+
+/datum/spacevine_mutation/light/on_grow(obj/effect/spacevine/holder)
+ if(holder.energy)
+ holder.set_light(severity)
+
+/datum/spacevine_mutation/toxicity
+ name = "toxic"
+ hue = "#ff00ff"
+ severity = 10
+ quality = NEGATIVE
+
+/datum/spacevine_mutation/toxicity/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
+ if(issilicon(crosser))
+ return
+ if(prob(severity) && istype(crosser) && !isvineimmune(crosser))
+ crosser << "You accidently touch the vine and feel a strange sensation."
+ crosser.adjustToxLoss(5)
+
+/datum/spacevine_mutation/toxicity/on_eat(obj/effect/spacevine/holder, mob/living/eater)
+ if(!isvineimmune(eater))
+ eater.adjustToxLoss(5)
+
+/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!!
+ name = "explosive"
+ hue = "#ff0000"
+ quality = NEGATIVE
+ severity = 2
+
+/datum/spacevine_mutation/explosive/on_explosion(explosion_severity)
+ if(explosion_severity < 3)
+ qdel(src)
+ else
+ . = 1
+ spawn(5)
+ qdel(src)
+
+/datum/spacevine_mutation/explosive/on_death(obj/effect/spacevine/holder, mob/hitter, obj/item/I)
+ explosion(holder.loc, 0, 0, severity, 0, 0)
+
+/datum/spacevine_mutation/fire_proof
+ name = "fire proof"
+ hue = "#ff8888"
+ quality = MINOR_NEGATIVE
+
+/datum/spacevine_mutation/fire_proof/process_temperature(obj/effect/spacevine/holder, temp, volume)
+ return 1
+
+/datum/spacevine_mutation/fire_proof/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage)
+ if(I && I.damtype == "fire")
+ . = 0
+ else
+ . = expected_damage
+
+/datum/spacevine_mutation/vine_eating
+ name = "vine eating"
+ hue = "#ff7700"
+ quality = MINOR_NEGATIVE
+
+/datum/spacevine_mutation/vine_eating/on_spread(obj/effect/spacevine/holder, turf/target)
+ var/obj/effect/spacevine/prey = locate() in target
+ if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin
+ qdel(prey)
+
+/datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently
+ name = "aggressive spreading"
+ hue = "#333333"
+ severity = 3
+ quality = NEGATIVE
+
+/datum/spacevine_mutation/aggressive_spread/on_spread(obj/effect/spacevine/holder, turf/target)
+ target.ex_act(severity, src) // vine immunity handled at /mob/ex_act
+
+/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/effect/spacevine/holder, mob/living/buckled)
+ buckled.ex_act(severity, src)
+
+/datum/spacevine_mutation/transparency
+ name = "transparent"
+ hue = ""
+ quality = POSITIVE
+
+/datum/spacevine_mutation/transparency/on_grow(obj/effect/spacevine/holder)
+ holder.set_opacity(0)
+ holder.alpha = 125
+
+/datum/spacevine_mutation/thorns
+ name = "thorny"
+ hue = "#666666"
+ severity = 10
+ quality = NEGATIVE
+
+/datum/spacevine_mutation/thorns/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
+ if(prob(severity) && istype(crosser) && !isvineimmune(holder))
+ var/mob/living/M = crosser
+ M.adjustBruteLoss(5)
+ M << "You cut yourself on the thorny vines."
+
+/datum/spacevine_mutation/thorns/on_hit(obj/effect/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
+ if(prob(severity) && istype(hitter) && !isvineimmune(holder))
+ var/mob/living/M = hitter
+ M.adjustBruteLoss(5)
+ M << "You cut yourself on the thorny vines."
+ . = expected_damage
+
+/datum/spacevine_mutation/woodening
+ name = "hardened"
+ hue = "#997700"
+ quality = NEGATIVE
+
+/datum/spacevine_mutation/woodening/on_grow(obj/effect/spacevine/holder)
+ if(holder.energy)
+ holder.density = 1
+ holder.maxhealth = 100
+ holder.health = holder.maxhealth
+
+/datum/spacevine_mutation/woodening/on_hit(obj/effect/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
+ if(is_sharp(I))
+ . = expected_damage * 0.5
+ else
+ . = expected_damage
+
+/datum/spacevine_mutation/flowering
+ name = "flowering"
+ hue = "#0A480D"
+ quality = NEGATIVE
+ severity = 10
+
+/datum/spacevine_mutation/flowering/on_grow(obj/effect/spacevine/holder)
+ if(holder.energy == 2 && prob(severity) && !locate(/obj/structure/alien/resin/flower_bud_enemy) in range(5,holder))
+ var/obj/structure/alien/resin/flower_bud_enemy/FBE = new /obj/structure/alien/resin/flower_bud_enemy(get_turf(holder))
+ FBE.layer = holder.layer+0.1
+
+/datum/spacevine_mutation/flowering/on_cross(obj/effect/spacevine/holder, mob/living/crosser)
+ if(prob(25))
+ holder.entangle(crosser)
+
+
+// SPACE VINES (Note that this code is very similar to Biomass code)
+/obj/effect/spacevine
+ name = "space vines"
+ desc = "An extremely expansionistic species of vine."
+ icon = 'icons/effects/spacevines.dmi'
+ icon_state = "Light1"
+ anchored = 1
+ density = 0
+ layer = MOB_LAYER + 0.8
+ mouse_opacity = 2 //Clicking anywhere on the turf is good enough
+ pass_flags = PASSTABLE | PASSGRILLE
+ var/health = 50
+ var/maxhealth = 50
+ var/energy = 0
+ var/obj/effect/spacevine_controller/master = null
+ var/list/mutations = list()
+
+/obj/effect/spacevine/New()
+ ..()
+ color = "#ffffff"
+
+/obj/effect/spacevine/examine(mob/user)
+ ..()
+ var/text = "This one is a"
+ if(mutations.len)
+ for(var/A in mutations)
+ var/datum/spacevine_mutation/SM = A
+ text += " [SM.name]"
+ else
+ text += " normal"
+ text += " vine."
+ user << text
+
+/obj/effect/spacevine/Destroy()
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_death(src)
+ if(master)
+ master.vines -= src
+ master.growth_queue -= src
+ if(!master.vines.len)
+ var/obj/item/seeds/kudzu/KZ = new(loc)
+ KZ.mutations |= mutations
+ KZ.potency = min(100, master.mutativeness * 10)
+ KZ.production = (master.spread_cap / initial(master.spread_cap)) * 5
+ mutations = list()
+ set_opacity(0)
+ if(has_buckled_mobs())
+ unbuckle_all_mobs(force=1)
+ return ..()
+
+/obj/effect/spacevine/proc/on_chem_effect(datum/reagent/R)
+ var/override = 0
+ for(var/datum/spacevine_mutation/SM in mutations)
+ override += SM.on_chem(src, R)
+ if(!override && istype(R, /datum/reagent/atrazine))
+ if(prob(50))
+ qdel(src)
+
+/obj/effect/spacevine/proc/eat(mob/eater)
+ var/override = 0
+ for(var/datum/spacevine_mutation/SM in mutations)
+ override += SM.on_eat(src, eater)
+ if(!override)
+ if(prob(10))
+ eater.say("Nom")
+ qdel(src)
+
+/obj/effect/spacevine/attackby(obj/item/weapon/W, mob/user, params)
+ if (!W || !user || !W.type)
+ return
+ user.changeNext_move(CLICK_CD_MELEE)
+ var/force = W.force
+
+ if(istype(W, /obj/item/weapon/scythe))
+ force = force * 4
+ for(var/obj/effect/spacevine/B in orange(1,src))
+ B.health = health - force
+ if(B.health < 1)
+ qdel(B)
+
+ health = health - force
+
+ if(health < 1)
+ qdel(src)
+
+ return
+
+ if(is_sharp(W))
+ force = force * 4
+
+ if(W && W.damtype == "fire")
+ force = force * 4
+
+ for(var/datum/spacevine_mutation/SM in mutations)
+ force = SM.on_hit(src, user, W, force) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
+
+ health = health - force
+ if(health < 1)
+ qdel(src)
+
+ ..()
+
+/obj/effect/spacevine/Crossed(mob/crosser)
+ if(isliving(crosser))
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_cross(src, crosser)
+
+/obj/effect/spacevine/attack_hand(mob/user)
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_hit(src, user)
+ user_unbuckle_mob(user, user)
+
+/obj/effect/spacevine/attack_alien(mob/living/user)
+ eat(user)
+
+/obj/effect/spacevine_controller
+ invisibility = 101
+ var/list/obj/effect/spacevine/vines = list()
+ var/list/growth_queue = list()
+ var/spread_multiplier = 5
+ var/spread_cap = 30
+ var/list/mutations_list = list()
+ var/mutativeness = 1
+
+/obj/effect/spacevine_controller/New(loc, list/muts, potency, production)
+ color = "#ffffff"
+ spawn_spacevine_piece(loc, , muts)
+ processing_objects.Add(src)
+ init_subtypes(/datum/spacevine_mutation/, mutations_list)
+ if(potency != null)
+ mutativeness = potency / 10
+ if(production != null)
+ spread_cap *= production / 5
+ spread_multiplier /= production / 5
+ ..()
+
+
+/obj/effect/spacevine_controller/ex_act() //only killing all vines will end this suffering
+ return
+
+/obj/effect/spacevine_controller/singularity_act()
+ return
+
+/obj/effect/spacevine_controller/singularity_pull()
+ return
+
+/obj/effect/spacevine_controller/Destroy()
+ processing_objects.Remove(src)
+ return ..()
+
+/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/effect/spacevine/parent, list/muts)
+ var/obj/effect/spacevine/SV = new(location)
+ growth_queue += SV
+ vines += SV
+ SV.master = src
+ if(muts && muts.len)
+ for(var/datum/spacevine_mutation/M in muts)
+ M.add_mutation_to_vinepiece(SV)
+ return
+ if(parent)
+ SV.mutations |= parent.mutations
+ SV.color = parent.color
+ if(prob(mutativeness))
+ var/datum/spacevine_mutation/randmut = pick(mutations_list - SV.mutations)
+ randmut.add_mutation_to_vinepiece(SV)
+
+ for(var/datum/spacevine_mutation/SM in SV.mutations)
+ SM.on_birth(SV)
+
+/obj/effect/spacevine_controller/process()
+ if(!vines)
+ qdel(src) //space vines exterminated. Remove the controller
+ return
+ if(!growth_queue)
+ qdel(src) //Sanity check
+ return
+
+ var/length = 0
+
+ length = min( spread_cap , max( 1 , vines.len / spread_multiplier ) )
+ var/i = 0
+ var/list/obj/effect/spacevine/queue_end = list()
+
+ for(var/obj/effect/spacevine/SV in growth_queue)
+ if(qdeleted(SV))
+ continue
+ i++
+ queue_end += SV
+ growth_queue -= SV
+ for(var/datum/spacevine_mutation/SM in SV.mutations)
+ SM.process_mutation(SV)
+ if(SV.energy < 2) //If tile isn't fully grown
+ if(prob(20))
+ SV.grow()
+ else //If tile is fully grown
+ SV.entangle_mob()
+
+ //if(prob(25))
+ SV.spread()
+ if(i >= length)
+ break
+
+ growth_queue = growth_queue + queue_end
+
+/obj/effect/spacevine/proc/grow()
+ if(!energy)
+ icon_state = pick("Med1", "Med2", "Med3")
+ energy = 1
+ set_opacity(1)
+ layer = 5
+ else
+ icon_state = pick("Hvy1", "Hvy2", "Hvy3")
+ energy = 2
+
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_grow(src)
+
+/obj/effect/spacevine/proc/entangle_mob()
+ if(!has_buckled_mobs() && prob(25))
+ for(var/mob/living/V in loc)
+ entangle(V)
+ if(has_buckled_mobs())
+ break //only capture one mob at a time
+
+
+/obj/effect/spacevine/proc/entangle(mob/living/V)
+ if(!V || isvineimmune(V))
+ return
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_buckle(src, V)
+ if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured
+ V << "The vines [pick("wind", "tangle", "tighten")] around you!"
+ buckle_mob(V, 1)
+
+/obj/effect/spacevine/proc/spread()
+ var/direction = pick(cardinal)
+ var/turf/stepturf = get_step(src,direction)
+ for(var/datum/spacevine_mutation/SM in mutations)
+ SM.on_spread(src, stepturf)
+ stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen
+ if(!locate(/obj/effect/spacevine, stepturf))
+ if(stepturf.Enter(src))
+ if(master)
+ master.spawn_spacevine_piece(stepturf, src)
+
+/obj/effect/spacevine/ex_act(severity)
+ var/i
+ for(var/datum/spacevine_mutation/SM in mutations)
+ i += SM.on_explosion(severity)
+ if(!i && prob(100/severity))
+ qdel(src)
+
+/obj/effect/spacevine/temperature_expose(null, temp, volume)
+ var/override = 0
+ for(var/datum/spacevine_mutation/SM in mutations)
+ override += SM.process_temperature(src, temp, volume)
+ if(!override)
+ qdel(src)
+
+/obj/effect/spacevine/CanPass(atom/movable/mover, turf/target, height=0)
+ if(isvineimmune(mover))
+ . = TRUE
+ else
+ . = ..()
+
+/proc/isvineimmune(atom/A)
+ . = FALSE
+ if(isliving(A))
+ var/mob/living/M = A
+ if(("vines" in M.faction) || ("plants" in M.faction))
+ . = TRUE
\ No newline at end of file
diff --git a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm
index 03ceb5c0034..56159c8b7d6 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm
@@ -4,27 +4,29 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = 2.9
- density = 0
+ density = 1
anchored = 0
use_power = 1
idle_power_usage = 5
active_power_usage = 100
+ pass_flags = PASSTABLE
var/obj/item/weapon/reagent_containers/beaker = null
- var/global/list/allowed_items = list(
+ var/global/list/allowed_items = list (
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = "tomatojuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/carrot = "carrotjuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/berries = "berryjuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/grapes = "grapejuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green = "grapejuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/banana = "banana",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/potato = "potato",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon = "lemonjuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = "orangejuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime = "limejuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon = "watermelonjuice",
/obj/item/weapon/reagent_containers/food/snacks/watermelonslice = "watermelonjuice",
- /obj/item/weapon/reagent_containers/food/snacks/grown = "water",
- )
-
- var/global/list/allowed_tags = list (
- "tomato" = "tomatojuice",
- "carrot" = "carrotjuice",
- "berries" = "berryjuice",
- "banana" = "banana",
- "potato" = "potato",
- "lemon" = "lemonjuice",
- "orange" = "orangejuice",
- "lime" = "limejuice",
- "poisonberries" = "poisonberryjuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison = "poisonberryjuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin = "pumpkinjuice",
+ /obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = "blumpkinjuice",
)
/obj/machinery/juicer/New()
@@ -135,23 +137,18 @@
beaker = null
update_icon()
-/obj/machinery/juicer/proc/get_juice_id(var/obj/item/weapon/reagent_containers/food/snacks/O)
- if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/watermelonslice))
- return "watermelonjuice"
- else if(istype(O, /obj.item/weapon/reagent_containers/food/snacks/grown))
- var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O
- for(var/i in allowed_tags)
- if(G.seed.kitchen_tag == allowed_tags[i])
- return allowed_tags[i]
- return "water"
+/obj/machinery/juicer/proc/get_juice_id(obj/item/weapon/reagent_containers/food/snacks/grown/O)
+ for (var/i in allowed_items)
+ if (istype(O, i))
+ return allowed_items[i]
-/obj/machinery/juicer/proc/get_juice_amount(var/obj/item/weapon/reagent_containers/food/snacks/grown/O)
- if(!istype(O))
+/obj/machinery/juicer/proc/get_juice_amount(obj/item/weapon/reagent_containers/food/snacks/grown/O)
+ if(!istype(O) || !O.seed)
return 5
- else if(O.potency == -1)
+ else if (O.seed.potency == -1)
return 5
else
- return round(5*sqrt(O.potency))
+ return round(5*sqrt(O.seed.potency))
/obj/machinery/juicer/proc/juice()
power_change() //it is a portable machine
@@ -167,19 +164,21 @@
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
-/obj/structure/closet/crate/juice
- New()
- ..()
- new/obj/machinery/juicer(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
- new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
\ No newline at end of file
+/obj/structure/closet/crate/juice/New()
+ ..()
+ new/obj/machinery/juicer(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/grapes(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/grapes(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
+ new/obj/item/weapon/reagent_containers/food/snacks/grown/grapes(src)
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index eba41c66891..e30d72a26bb 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -37,9 +37,9 @@
return ..()
/obj/machinery/biogenerator/ex_act(severity)
- ..()
if(beaker)
beaker.ex_act(severity)
+ ..()
/obj/machinery/biogenerator/RefreshParts()
var/E = 0
diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm
index 121b5480bc1..835b2574731 100644
--- a/code/modules/hydroponics/grown/corn.dm
+++ b/code/modules/hydroponics/grown/corn.dm
@@ -36,7 +36,7 @@
throw_range = 7
/obj/item/weapon/grown/corncob/attackby(obj/item/weapon/grown/W, mob/user, params)
- if(W.is_sharp())
+ if(is_sharp(W))
to_chat(user, "You use [W] to fashion a pipe out of the corn cob!")
new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc)
user.unEquip(src)
diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm
index 53751068f5f..0d0d786a077 100644
--- a/code/modules/hydroponics/grown/misc.dm
+++ b/code/modules/hydroponics/grown/misc.dm
@@ -125,11 +125,9 @@
log_game("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x],[user.y],[user.z]).")
prime()
-/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/deconstruct(disassembled = TRUE)
- if(!disassembled)
- prime()
- if(!qdeleted(src))
- qdel(src)
+/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/burn()
+ prime()
+ ..()
/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/ex_act(severity)
qdel(src) //Ensuring that it's deleted by its own explosion. Also prevents mass chain reaction with piles of cherry bombs
diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm
index 538764a41e7..016a6071aa0 100644
--- a/code/modules/hydroponics/grown/mushrooms.dm
+++ b/code/modules/hydroponics/grown/mushrooms.dm
@@ -163,7 +163,7 @@
origin_tech = "biotech=4;programming=5"
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user)
- if(isspaceturf(user.loc))
+ if(istype(user.loc, /turf/space))
return
var/mob/living/simple_animal/hostile/mushroom/M = new /mob/living/simple_animal/hostile/mushroom(user.loc)
M.maxHealth += round(seed.endurance / 4)
@@ -229,16 +229,15 @@
desc = "Mycena Bregprox: This species of mushroom glows in the dark."
icon_state = "glowshroom"
filling_color = "#00FA9A"
- var/effect_path = /obj/structure/glowshroom
+ var/effect_path = /obj/effect/glowshroom
origin_tech = "biotech=4;plasmatech=6"
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user)
- if(isspaceturf(user.loc))
+ if(istype(user.loc, /turf/space))
return
- var/obj/structure/glowshroom/planted = new effect_path(user.loc)
+ var/obj/effect/glowshroom/planted = new effect_path(user.loc)
planted.delay = planted.delay - seed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
- planted.obj_integrity = seed.endurance
- planted.max_integrity = seed.endurance
+ planted.endurance = seed.endurance
planted.yield = seed.yield
planted.potency = seed.potency
to_chat(user, "You plant [src].")
@@ -266,5 +265,5 @@
desc = "Mycena Ruthenia: This species of mushroom glows in the dark, but aren't bioluminescent. They're warm to the touch..."
icon_state = "glowcap"
filling_color = "#00FA9A"
- effect_path = /obj/structure/glowshroom/glowcap
+ effect_path = /obj/effect/glowshroom/glowcap
origin_tech = "biotech=4;powerstorage=6;plasmatech=4"
diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm
index a52d2e9bf62..2b144679698 100644
--- a/code/modules/hydroponics/grown/potato.dm
+++ b/code/modules/hydroponics/grown/potato.dm
@@ -36,7 +36,7 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W, mob/user, params)
- if(W.is_sharp())
+ if(is_sharp(W))
to_chat(user, "You cut the potato into wedges with [W].")
var/obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges/Wedges = new /obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges
if(!remove_item_from_storage(user))
diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm
index 1354edbcaa1..ed8e64742ce 100644
--- a/code/modules/hydroponics/grown/pumpkin.dm
+++ b/code/modules/hydroponics/grown/pumpkin.dm
@@ -25,7 +25,7 @@
bitesize_mod = 2
/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if(W.is_sharp())
+ if(is_sharp(W))
user.show_message("You carve a face into [src]!", 1)
new /obj/item/clothing/head/hardhat/pumpkinhead(user.loc)
qdel(src)
diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm
index f631d61b628..82f81c0b3a6 100644
--- a/code/modules/hydroponics/grown/root.dm
+++ b/code/modules/hydroponics/grown/root.dm
@@ -23,7 +23,7 @@
bitesize_mod = 2
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params)
- if(I.is_sharp())
+ if(is_sharp(I))
to_chat(user, "You sharpen the carrot into a shiv with [I].")
var/obj/item/weapon/kitchen/knife/carrotshiv/Shiv = new /obj/item/weapon/kitchen/knife/carrotshiv
if(!remove_item_from_storage(user))
diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm
index e04bdba2a9c..64764442e4a 100644
--- a/code/modules/hydroponics/grown/tomato.dm
+++ b/code/modules/hydroponics/grown/tomato.dm
@@ -124,7 +124,7 @@
..()
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer/attack_self(mob/user)
- if(awakening || isspaceturf(user.loc))
+ if(awakening || istype(user.loc, /turf/space))
return
to_chat(user, "You begin to awaken the Killer Tomato...")
awakening = 1
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index cccb0cf575a..b6716ce7ad3 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -68,9 +68,6 @@
if(exchange_parts(user, I))
return
- if(default_pry_open(I))
- return
-
if(default_unfasten_wrench(user, I))
return
@@ -830,8 +827,8 @@
else if(anchored)
user.visible_message("[user] begins to unwrench [src].", \
"You begin to unwrench [src]...")
- playsound(loc, O.usesound, 50, 1)
- if (do_after(user, 20*O.toolspeed, target = src))
+ playsound(loc, 'sound/items/Ratchet.ogg', 50, 1)
+ if (do_after(user, 20, target = src))
if(!anchored)
return
anchored = 0
@@ -840,7 +837,7 @@
else if(istype(O, /obj/item/weapon/wirecutters) && unwrenchable)
using_irrigation = !using_irrigation
- playsound(src, O.usesound, 50, 1)
+ playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
user.visible_message("[user] [using_irrigation ? "" : "dis"]connects [src]'s irrigation hoses.", \
"You [using_irrigation ? "" : "dis"]connect [src]'s irrigation hoses.")
for(var/obj/machinery/hydroponics/h in range(1,src))
diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm
index 1e5bb4fb002..21f10f63505 100644
--- a/code/modules/hydroponics/seed_extractor.dm
+++ b/code/modules/hydroponics/seed_extractor.dm
@@ -70,9 +70,6 @@
if(exchange_parts(user, O))
return
- if(default_pry_open(O))
- return
-
if(default_unfasten_wrench(user, O))
return
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 04506c819c8..534ec607e6e 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -34,7 +34,7 @@
for(var/direction in shuffle(list(1,2,4,8,5,6,9,10)))
var/step = get_step(src, direction)
if(step)
- if(locate(/obj/effect/plant) in step)
+ if(locate(/obj/effect/spacevine) in step)
Move(step, get_dir(src, step))
/mob/living/simple_animal/hostile/retaliate/goat/handle_automated_action()
@@ -47,11 +47,9 @@
LoseTarget()
src.visible_message("\blue [src] calms down.")
- if(locate(/obj/effect/plant) in loc)
- var/obj/effect/plant/SV = locate(/obj/effect/plant) in loc
- qdel(SV)
- if(prob(10))
- say("Nom")
+ var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc
+ if(SV)
+ SV.eat(src)
/mob/living/simple_animal/hostile/retaliate/goat/Life()
. = ..()
@@ -66,11 +64,9 @@
/mob/living/simple_animal/hostile/retaliate/goat/Move()
..()
if(!stat)
- if(locate(/obj/effect/plant) in loc)
- var/obj/effect/plant/SV = locate(/obj/effect/plant) in loc
- qdel(SV)
- if(prob(10))
- say("Nom")
+ var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc
+ if(SV)
+ SV.eat(src)
/mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass))
diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm
index 8c927eaefbd..538ce8450c7 100644
--- a/code/modules/mob/living/simple_animal/hostile/bees.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bees.dm
@@ -5,9 +5,9 @@
#define BEE_TRAY_RECENT_VISIT 200 //How long in deciseconds until a tray can be visited by a bee again
#define BEE_DEFAULT_COLOUR "#e5e500" //the colour we make the stripes of the bee if our reagent has no colour (or we have no reagent)
-#define BEE_POLLINATE_YIELD_CHANCE 10
+#define BEE_POLLINATE_YIELD_CHANCE 33
#define BEE_POLLINATE_PEST_CHANCE 33
-#define BEE_POLLINATE_POTENTCY_CHANCE 50
+#define BEE_POLLINATE_POTENCY_CHANCE 50
/mob/living/simple_animal/hostile/poison/bees
name = "bee"
@@ -15,6 +15,7 @@
icon_state = ""
icon_living = ""
icon = 'icons/mob/bees.dmi'
+ gender = FEMALE
speak_emote = list("buzzes")
emote_hear = list("buzzes")
turns_per_move = 0
@@ -142,7 +143,7 @@
if(beehome.bees)
beehome.bees.Remove(src)
beehome = null
- ..()
+ return ..()
/mob/living/simple_animal/hostile/poison/bees/worker/death(gibbed)
if(beehome)
@@ -158,10 +159,10 @@
to_chat(user, "This bee is homeless!")
/mob/living/simple_animal/hostile/poison/bees/worker/Found(atom/A)
- if(istype(A, /obj/machinery/portable_atmospherics/hydroponics))
- var/obj/machinery/portable_atmospherics/hydroponics/Hydro = A
- if(Hydro.seed && !Hydro.dead && !Hydro.recent_bee_visit && !Hydro.closed_system)
- wanted_objects |= /obj/machinery/portable_atmospherics/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered
+ if(istype(A, /obj/machinery/hydroponics))
+ var/obj/machinery/hydroponics/Hydro = A
+ if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit)
+ wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted
return 1
..()
@@ -175,24 +176,24 @@
/mob/living/simple_animal/hostile/poison/bees/worker/AttackingTarget()
//Pollinate
- if(istype(target, /obj/machinery/portable_atmospherics/hydroponics))
- var/obj/machinery/portable_atmospherics/hydroponics/Hydro = target
+ if(istype(target, /obj/machinery/hydroponics))
+ var/obj/machinery/hydroponics/Hydro = target
pollinate(Hydro)
else if(target == beehome)
var/obj/structure/beebox/BB = target
forceMove(BB)
target = null
- wanted_objects.Remove(/obj/structure/beebox) //so we don't attack beeboxes when not going home
+ wanted_objects -= /obj/structure/beebox //so we don't attack beeboxes when not going home
else
..()
-/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/portable_atmospherics/hydroponics/Hydro)
- if(!istype(Hydro) || !Hydro.seed || Hydro.dead || Hydro.recent_bee_visit || Hydro.closed_system)
+/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/hydroponics/Hydro)
+ if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit)
target = null
return
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
- wanted_objects.Remove(/obj/machinery/portable_atmospherics/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
+ wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted
Hydro.recent_bee_visit = TRUE
spawn(BEE_TRAY_RECENT_VISIT)
if(Hydro)
@@ -200,23 +201,14 @@
var/growth = health //Health also means how many bees are in the swarm, roughly.
//better healthier plants!
- Hydro.health += round(growth*0.5)
+ Hydro.adjustHealth(growth*0.5)
if(prob(BEE_POLLINATE_PEST_CHANCE))
- Hydro.pestlevel = max(0, --Hydro.pestlevel)
- if(prob(BEE_POLLINATE_YIELD_CHANCE)) //Yield mod is HELLA powerful, but quite rare
- if(!isnull(plant_controller.seeds[Hydro.seed.name]))
- Hydro.seed = Hydro.seed.diverge()
- else
- Hydro.seed.update_name_prefixes()
- var/seed_yield = Hydro.seed.get_trait(TRAIT_YIELD)
- Hydro.seed.set_trait(TRAIT_YIELD, seed_yield + 1, 10, 0)
- if(prob(BEE_POLLINATE_POTENTCY_CHANCE))
- if(!isnull(plant_controller.seeds[Hydro.seed.name]))
- Hydro.seed = Hydro.seed.diverge()
- else
- Hydro.seed.update_name_prefixes()
- var/seed_potency = Hydro.seed.get_trait(TRAIT_POTENCY)
- Hydro.seed.set_trait(TRAIT_POTENCY, seed_potency + 1, 200, 0)
+ Hydro.adjustPests(-10)
+ if(prob(BEE_POLLINATE_YIELD_CHANCE))
+ Hydro.myseed.adjust_yield(1)
+ Hydro.yieldmod = 2
+ if(prob(BEE_POLLINATE_POTENCY_CHANCE))
+ Hydro.myseed.adjust_potency(1)
if(beehome)
beehome.bee_resources = min(beehome.bee_resources + growth, 100)
@@ -234,7 +226,7 @@
idle = max(0, --idle)
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
if(!FindTarget())
- wanted_objects.Add(/obj/structure/beebox) //so we don't attack beeboxes when not going home
+ wanted_objects += /obj/structure/beebox //so we don't attack beeboxes when not going home
target = beehome
if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home
for(var/obj/structure/beebox/BB in view(vision_range, src))
@@ -304,6 +296,7 @@
/obj/item/queen_bee/Destroy()
qdel(queen)
+ queen = null
return ..()
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 38cfdf4b0ae..828e8967e5d 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -3,62 +3,84 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = 2.9
- density = 1
anchored = 1
use_power = 1
idle_power_usage = 5
active_power_usage = 100
- var/inuse = 0
+ pass_flags = PASSTABLE
+ var/operating = 0
var/obj/item/weapon/reagent_containers/beaker = null
var/limit = 10
//IMPORTANT NOTE! A negative number is a multiplier, a positive number is a flat amount to add. 0 means equal to the amount of the original reagent
var/list/blend_items = list (
- //Sheets
- /obj/item/stack/sheet/mineral/plasma = list("plasma_dust" = 20),
- /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
- /obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
- /obj/item/stack/sheet/mineral/tranquillite = list("nothing" = 20),
- /obj/item/stack/sheet/mineral/silver = list("silver" = 20),
- /obj/item/stack/sheet/mineral/gold = list("gold" = 20),
- /obj/item/weapon/grown/novaflower = list("capsaicin" = 0),
+ //Sheets
+ /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20),
+ /obj/item/stack/sheet/metal = list("iron" = 20),
+ /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20),
+ /obj/item/stack/sheet/wood = list("carbon" = 20),
+ /obj/item/stack/sheet/glass = list("silicon" = 20),
+ /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20),
+ /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
+ /obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
+ /obj/item/stack/sheet/mineral/tranquillite = list("nothing" = 20),
+ /obj/item/stack/sheet/mineral/silver = list("silver" = 20),
+ /obj/item/stack/sheet/mineral/gold = list("gold" = 20),
+ /obj/item/weapon/grown/nettle/basic = list("sacid" = 0),
+ /obj/item/weapon/grown/nettle/death = list("facid" = 0, "sacid" = 0),
+ /obj/item/weapon/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0),
- //archaeology!
- ///obj/item/weapon/rocksliver = list("ground_rock" = 50),
+ //Blender Stuff
+ /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
+
+ //Grinder stuff, but only if dry
+ /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
- //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
- /obj/item/weapon/reagent_containers/food = list(),
- /obj/item/weapon/reagent_containers/honeycomb = list()
- )
-
- var/list/blend_tags = list (
- "nettle" = list("sacid" = 0),
- "deathnettle" = list("facid" = 0),
- "soybeans" = list("soymilk" = 0),
- "tomato" = list("ketchup" = 0),
- "wheat" = list("flour" = -5),
- "rice" = list("rice" = -5),
- "cherries" = list("cherryjelly" = 0),
+ //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
+ /obj/item/slime_extract = list(),
+ /obj/item/weapon/reagent_containers/food = list(),
+ /obj/item/weapon/reagent_containers/honeycomb = list()
)
var/list/juice_items = list (
- /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0),
+
+ //Juicer Stuff
+ /obj/item/weapon/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/banana = list("banana" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/potato = list("potato" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0),
)
- var/list/juice_tags = list (
- "tomato" = list("tomatojuice" = 0),
- "carrot" = list("carrotjuice" = 0),
- "berries" = list("berryjuice" = 0),
- "banana" = list("banana" = 0),
- "potato" = list("potato" = 0),
- "lemon" = list("lemonjuice" = 0),
- "orange" = list("orangejuice" = 0),
- "lime" = list("limejuice" = 0),
- "poisonberries" = list("poisonberryjuice" = 0),
- "grapes" = list("grapejuice" = 0),
- "corn" = list("cornoil" = 0),
+ var/list/dried_items = list(
+ //Grinder stuff, but only if dry,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)
)
var/list/holdingitems = list()
@@ -68,348 +90,352 @@
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
return
+/obj/machinery/reagentgrinder/Destroy()
+ if(beaker)
+ qdel(beaker)
+ beaker = null
+ return ..()
+
+/obj/machinery/reagentgrinder/ex_act(severity)
+ if(beaker)
+ beaker.ex_act(severity)
+ ..()
+
/obj/machinery/reagentgrinder/update_icon()
- icon_state = "juicer"+num2text(!isnull(beaker))
- return
+ if(beaker)
+ icon_state = "juicer1"
+ else
+ icon_state = "juicer0"
-/obj/machinery/reagentgrinder/attackby(obj/item/O, mob/user, params)
-
- if(istype(O,/obj/item/weapon/reagent_containers/glass) || \
- istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \
- istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker))
-
- if(beaker)
- return 1
- else
- if(!user.drop_item())
- to_chat(user, "[O] is stuck to you!")
+/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params)
+ if(default_unfasten_wrench(user, I))
return
- beaker = O
- O.forceMove(src)
- update_icon()
- updateUsrDialog()
- return 0
- if(holdingitems && holdingitems.len >= limit)
- to_chat(usr, "The machine cannot hold anymore items.")
- return 1
+ if (istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER) )
+ if (!beaker)
+ if(!user.drop_item())
+ return 1
+ beaker = I
+ beaker.loc = src
+ update_icon()
+ src.updateUsrDialog()
+ else
+ user << "There's already a container inside."
+ return 1 //no afterattack
- //Fill machine with a plantbag!
- if(istype(O, /obj/item/weapon/storage/bag/plants))
- var/obj/item/weapon/storage/bag/plants/PB = O
- for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in PB.contents)
- PB.remove_from_storage(G, src)
- holdingitems += G
- if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill
- to_chat(user, "You must dry that first!"
+ return 1
- if(!PB.contents.len)
- to_chat(user, "You empty [PB] into the All-In-One grinder.")
+ if(holdingitems && holdingitems.len >= limit)
+ usr << "The machine cannot hold anymore items."
+ return 1
- updateUsrDialog()
- return 0
+ //Fill machine with a bag!
+ if(istype(I, /obj/item/weapon/storage/bag))
+ var/obj/item/weapon/storage/bag/B = I
+ for (var/obj/item/weapon/reagent_containers/food/snacks/grown/G in B.contents)
+ B.remove_from_storage(G, src)
+ holdingitems += G
+ if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill
+ user << "You fill the All-In-One grinder to the brim."
+ break
+ if(!I.contents.len)
+ user << "You empty the plant bag into the All-In-One grinder."
- if(!is_type_in_list(O, blend_items) && !is_type_in_list(O, juice_items))
- to_chat(user, "Cannot refine into a reagent.")
- return 1
+ src.updateUsrDialog()
+ return 1
- user.unEquip(O)
- O.forceMove(src)
- holdingitems += O
- updateUsrDialog()
- return 0
+ if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items))
+ if(user.a_intent == I_HARM)
+ return ..()
+ else
+ user << "Cannot refine into a reagent!"
+ return 1
+
+ if(user.drop_item())
+ I.loc = src
+ holdingitems += I
+ src.updateUsrDialog()
+ return 0
/obj/machinery/reagentgrinder/attack_ai(mob/user)
- return 0
+ return 0
/obj/machinery/reagentgrinder/attack_hand(mob/user)
- user.set_machine(src)
- interact(user)
+ user.set_machine(src)
+ interact(user)
/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu
- var/is_chamber_empty = 0
- var/is_beaker_ready = 0
- var/processing_chamber = ""
- var/beaker_contents = ""
- var/dat = ""
+ var/is_chamber_empty = 0
+ var/is_beaker_ready = 0
+ var/processing_chamber = ""
+ var/beaker_contents = ""
+ var/dat = ""
- if(!inuse)
- for(var/obj/item/O in holdingitems)
- processing_chamber += "\A [O.name]
"
+ if(!operating)
+ for (var/obj/item/O in holdingitems)
+ processing_chamber += "\A [O.name]
"
- if(!processing_chamber)
- is_chamber_empty = 1
- processing_chamber = "Nothing."
- if(!beaker)
- beaker_contents = "No beaker attached.
"
+ if (!processing_chamber)
+ is_chamber_empty = 1
+ processing_chamber = "Nothing."
+ if (!beaker)
+ beaker_contents = "No beaker attached.
"
+ else
+ is_beaker_ready = 1
+ beaker_contents = "The beaker contains:
"
+ var/anything = 0
+ for(var/datum/reagent/R in beaker.reagents.reagent_list)
+ anything = 1
+ beaker_contents += "[R.volume] - [R.name]
"
+ if(!anything)
+ beaker_contents += "Nothing
"
+
+
+ dat = {"
+ Processing chamber contains:
+ [processing_chamber]
+ [beaker_contents]