diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 6b3be49653..427bc95253 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1067,9 +1067,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
icon_state = "engivend"
icon_deny = "engivend-deny"
req_access_txt = "11" //Engineering Equipment access
- products = list(/obj/item/clothing/glasses/meson/engine = 2, /obj/item/device/multitool = 4, /obj/item/electronics/airlock = 10, /obj/item/electronics/apc = 10, /obj/item/electronics/airalarm = 10, /obj/item/stock_parts/cell/high = 10, /obj/item/construction/rcd/loaded = 3, /obj/item/device/geiger_counter = 5)
+ products = list(/obj/item/clothing/glasses/meson/engine = 2, /obj/item/device/multitool = 4, /obj/item/electronics/airlock = 10, /obj/item/electronics/apc = 10, /obj/item/electronics/airalarm = 10, /obj/item/stock_parts/cell/high = 10, /obj/item/construction/rcd/loaded = 3, /obj/item/device/geiger_counter = 5, /obj/item/grenade/chem_grenade/smart_metal_foam = 10)
contraband = list(/obj/item/stock_parts/cell/potato = 3)
- premium = list(/obj/item/storage/belt/utility = 3)
+ premium = list(/obj/item/storage/belt/utility = 3, /obj/item/storage/box/smart_metal_foam = 1)
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
resistance_flags = FIRE_PROOF
diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm
index 07da20f615..b352596e2f 100644
--- a/code/game/objects/items/grenades/chem_grenade.dm
+++ b/code/game/objects/items/grenades/chem_grenade.dm
@@ -1,549 +1,567 @@
-#define EMPTY 1
-#define WIRED 2
-#define READY 3
-
-/obj/item/grenade/chem_grenade
- name = "chemical grenade"
- desc = "A custom made grenade."
- icon_state = "chemg"
- item_state = "flashbang"
- w_class = WEIGHT_CLASS_SMALL
- force = 2
- var/stage = EMPTY
- var/list/beakers = list()
- var/list/allowed_containers = list(/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle)
- var/affected_area = 3
- var/obj/item/device/assembly_holder/nadeassembly = null
- var/assemblyattacher
- var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off.
- var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
- var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions.
-
-/obj/item/grenade/chem_grenade/Initialize()
- . = ..()
- create_reagents(1000)
- stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY.
-
-/obj/item/grenade/chem_grenade/examine(mob/user)
- display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state
- ..()
-
-
-/obj/item/grenade/chem_grenade/attack_self(mob/user)
- if(stage == READY && !active)
- if(nadeassembly)
- nadeassembly.attack_self(user)
- else if(clown_check(user))
- var/turf/bombturf = get_turf(src)
- var/area/A = get_area(bombturf)
- message_admins("[ADMIN_LOOKUPFLW(usr)] has primed a [name] for detonation at [A.name][ADMIN_JMP(bombturf)].")
- log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
- to_chat(user, "You prime the [name]! [det_time / 10] second\s!")
- playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
- active = 1
- icon_state = initial(icon_state) + "_active"
- if(iscarbon(user))
- var/mob/living/carbon/C = user
- C.throw_mode_on()
-
- addtimer(CALLBACK(src, .proc/prime), det_time)
-
-
-/obj/item/grenade/chem_grenade/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/screwdriver))
- if(stage == WIRED)
- if(beakers.len)
- stage_change(READY)
- to_chat(user, "You lock the [initial(name)] assembly.")
- playsound(loc, I.usesound, 25, -3)
- else
- to_chat(user, "You need to add at least one beaker before locking the [initial(name)] assembly!")
- else if(stage == READY && !nadeassembly)
- det_time = det_time == 50 ? 30 : 50 //toggle between 30 and 50
- to_chat(user, "You modify the time delay. It's set for [det_time / 10] second\s.")
- else if(stage == EMPTY)
- to_chat(user, "You need to add an activation mechanism!")
-
- else if(stage == WIRED && is_type_in_list(I, allowed_containers))
- . = 1 //no afterattack
- if(beakers.len == 2)
- to_chat(user, "[src] can not hold more containers!")
- return
- else
- if(I.reagents.total_volume)
- if(!user.transferItemToLoc(I, src))
- return
- to_chat(user, "You add [I] to the [initial(name)] assembly.")
- beakers += I
- else
- to_chat(user, "[I] is empty!")
-
- else if(stage == EMPTY && istype(I, /obj/item/device/assembly_holder))
- . = 1 // no afterattack
- var/obj/item/device/assembly_holder/A = I
- if(isigniter(A.a_left) == isigniter(A.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
- return
- if(!user.transferItemToLoc(I, src))
- return
-
- nadeassembly = A
- A.master = src
- assemblyattacher = user.ckey
-
- stage_change(WIRED)
- to_chat(user, "You add [A] to the [initial(name)] assembly.")
-
- else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil))
- var/obj/item/stack/cable_coil/C = I
- if (C.use(1))
- det_time = 50 // In case the cable_coil was removed and readded.
- stage_change(WIRED)
- to_chat(user, "You rig the [initial(name)] assembly.")
- else
- to_chat(user, "You need one length of coil to wire the assembly!")
- return
-
- else if(stage == READY && istype(I, /obj/item/wirecutters) && !active)
- stage_change(WIRED)
- to_chat(user, "You unlock the [initial(name)] assembly.")
-
- else if(stage == WIRED && istype(I, /obj/item/wrench))
- if(beakers.len)
- for(var/obj/O in beakers)
- O.loc = get_turf(src)
- beakers = list()
- to_chat(user, "You open the [initial(name)] assembly and remove the payload.")
- return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
- if(nadeassembly)
- nadeassembly.loc = get_turf(src)
- nadeassembly.master = null
- nadeassembly = null
- else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used.
- new /obj/item/stack/cable_coil(get_turf(src),1)
- stage_change(EMPTY)
- to_chat(user, "You remove the activation mechanism from the [initial(name)] assembly.")
- else
- return ..()
-
-/obj/item/grenade/chem_grenade/proc/stage_change(N)
- if(N)
- stage = N
- if(stage == EMPTY)
- name = "[initial(name)] casing"
- desc = "A do it yourself [initial(name)]!"
- icon_state = initial(icon_state)
- else if(stage == WIRED)
- name = "unsecured [initial(name)]"
- desc = "An unsecured [initial(name)] assembly."
- icon_state = "[initial(icon_state)]_ass"
- else if(stage == READY)
- name = initial(name)
- desc = initial(desc)
- icon_state = "[initial(icon_state)]_locked"
-
-
-//assembly stuff
-/obj/item/grenade/chem_grenade/receive_signal()
- prime()
-
-
-/obj/item/grenade/chem_grenade/Crossed(atom/movable/AM)
- if(nadeassembly)
- nadeassembly.Crossed(AM)
-
-/obj/item/grenade/chem_grenade/on_found(mob/finder)
- if(nadeassembly)
- nadeassembly.on_found(finder)
-
-/obj/item/grenade/chem_grenade/prime()
- if(stage != READY)
- return
-
- var/list/datum/reagents/reactants = list()
- for(var/obj/item/reagent_containers/glass/G in beakers)
- reactants += G.reagents
-
- if(!chem_splash(get_turf(src), affected_area, reactants, ignition_temp, threatscale) && !no_splash)
- playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1)
- if(beakers.len)
- for(var/obj/O in beakers)
- O.loc = get_turf(src)
- beakers = list()
- stage_change(EMPTY)
- return
-
- if(nadeassembly)
- var/mob/M = get_mob_by_ckey(assemblyattacher)
- var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
- var/turf/T = get_turf(src)
- var/area/A = get_area(T)
- message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [ADMIN_JMP(T)].")
- log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [COORD(T)]")
-
- var/turf/DT = get_turf(src)
- var/area/DA = get_area(DT)
- log_game("A grenade detonated at [DA.name] [COORD(DT)]")
-
- update_mob()
-
- qdel(src)
-
-//Large chem grenades accept slime cores and use the appropriately.
-/obj/item/grenade/chem_grenade/large
- name = "large grenade"
- desc = "A custom made large grenade. It affects a larger area."
- icon_state = "large_grenade"
- allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment,
- /obj/item/reagent_containers/food/drinks)
- origin_tech = "combat=3;engineering=3"
- affected_area = 5
- ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
- threatscale = 1.1 // 10% more effective.
-
-/obj/item/grenade/chem_grenade/large/prime()
- if(stage != READY)
- return
-
- for(var/obj/item/slime_extract/S in beakers)
- if(S.Uses)
- for(var/obj/item/reagent_containers/glass/G in beakers)
- G.reagents.trans_to(S, G.reagents.total_volume)
-
- //If there is still a core (sometimes it's used up)
- //and there are reagents left, behave normally,
- //otherwise drop it on the ground for timed reactions like gold.
-
- if(S)
- if(S.reagents && S.reagents.total_volume)
- for(var/obj/item/reagent_containers/glass/G in beakers)
- S.reagents.trans_to(G, S.reagents.total_volume)
- else
- S.forceMove(get_turf(src))
- no_splash = TRUE
- ..()
-
- //I tried to just put it in the allowed_containers list but
- //if you do that it must have reagents. If you're going to
- //make a special case you might as well do it explicitly. -Sayu
-/obj/item/grenade/chem_grenade/large/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/slime_extract) && stage == WIRED)
- if(!user.transferItemToLoc(I, src))
- return
- to_chat(user, "You add [I] to the [initial(name)] assembly.")
- beakers += I
- else
- return ..()
-
-/obj/item/grenade/chem_grenade/cryo // Intended for rare cryogenic mixes. Cools the area moderately upon detonation.
- name = "cryo grenade"
- desc = "A custom made cryogenic grenade. It rapidly cools its contents upon detonation."
- icon_state = "cryog"
- affected_area = 2
- ignition_temp = -100
-
-/obj/item/grenade/chem_grenade/pyro // Intended for pyrotechnical mixes. Produces a small fire upon detonation, igniting potentially flammable mixtures.
- name = "pyro grenade"
- desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation."
- icon_state = "pyrog"
- origin_tech = "combat=4;engineering=4"
- affected_area = 3
- ignition_temp = 500 // This is enough to expose a hotspot.
-
-/obj/item/grenade/chem_grenade/adv_release // Intended for weaker, but longer lasting effects. Could have some interesting uses.
- name = "advanced release grenade"
- desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool."
- icon_state = "timeg"
- origin_tech = "combat=3;engineering=4"
- var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool.
-
-/obj/item/grenade/chem_grenade/adv_release/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/device/multitool))
- switch(unit_spread)
- if(0 to 24)
- unit_spread += 5
- if(25 to 99)
- unit_spread += 25
- else
- unit_spread = 5
- to_chat(user, " You set the time release to [unit_spread] units per detonation.")
- return
- ..()
-
-/obj/item/grenade/chem_grenade/adv_release/prime()
- if(stage != READY)
- return
-
- var/total_volume = 0
- for(var/obj/item/reagent_containers/RC in beakers)
- total_volume += RC.reagents.total_volume
- if(!total_volume)
- qdel(src)
- qdel(nadeassembly)
- return
- var/fraction = unit_spread/total_volume
- var/datum/reagents/reactants = new(unit_spread)
- reactants.my_atom = src
- for(var/obj/item/reagent_containers/RC in beakers)
- RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, threatscale, 1, 1)
- chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale)
-
- if(nadeassembly)
- var/mob/M = get_mob_by_ckey(assemblyattacher)
- var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
- var/turf/T = get_turf(src)
- var/area/A = get_area(T)
- message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
- log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
- else
- addtimer(CALLBACK(src, .proc/prime), det_time)
- var/turf/DT = get_turf(src)
- var/area/DA = get_area(DT)
- log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])")
-
-
-
-
-
-//////////////////////////////
-////// PREMADE GRENADES //////
-//////////////////////////////
-
-/obj/item/grenade/chem_grenade/metalfoam
- name = "metal foam grenade"
- desc = "Used for emergency sealing of air breaches."
- stage = READY
-
-/obj/item/grenade/chem_grenade/metalfoam/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
-
- B1.reagents.add_reagent("aluminium", 30)
- B2.reagents.add_reagent("foaming_agent", 10)
- B2.reagents.add_reagent("facid", 10)
-
- beakers += B1
- beakers += B2
-
-
-/obj/item/grenade/chem_grenade/incendiary
- name = "incendiary grenade"
- desc = "Used for clearing rooms of living things."
- stage = READY
-
-/obj/item/grenade/chem_grenade/incendiary/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
-
- B1.reagents.add_reagent("phosphorus", 25)
- B2.reagents.add_reagent("stable_plasma", 25)
- B2.reagents.add_reagent("sacid", 25)
-
- beakers += B1
- beakers += B2
-
-
-/obj/item/grenade/chem_grenade/antiweed
- name = "weedkiller grenade"
- desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents."
- stage = READY
-
-/obj/item/grenade/chem_grenade/antiweed/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
-
- B1.reagents.add_reagent("plantbgone", 25)
- B1.reagents.add_reagent("potassium", 25)
- B2.reagents.add_reagent("phosphorus", 25)
- B2.reagents.add_reagent("sugar", 25)
-
- beakers += B1
- beakers += B2
-
-
-/obj/item/grenade/chem_grenade/cleaner
- name = "cleaner grenade"
- desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
- stage = READY
-
-/obj/item/grenade/chem_grenade/cleaner/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
-
- B1.reagents.add_reagent("fluorosurfactant", 40)
- B2.reagents.add_reagent("water", 40)
- B2.reagents.add_reagent("cleaner", 10)
-
- beakers += B1
- beakers += B2
-
-
-/obj/item/grenade/chem_grenade/ez_clean
- name = "cleaner grenade"
- desc = "Waffle Co.-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
- stage = READY
-
-/obj/item/grenade/chem_grenade/ez_clean/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
-
- B1.reagents.add_reagent("fluorosurfactant", 40)
- B2.reagents.add_reagent("water", 40)
- B2.reagents.add_reagent("ez_clean", 60) //ensures a t h i c c distribution
-
- beakers += B1
- beakers += B2
-
-
-
-/obj/item/grenade/chem_grenade/teargas
- name = "teargas grenade"
- desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents."
- stage = READY
-
-/obj/item/grenade/chem_grenade/teargas/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
-
- B1.reagents.add_reagent("condensedcapsaicin", 60)
- B1.reagents.add_reagent("potassium", 40)
- B2.reagents.add_reagent("phosphorus", 40)
- B2.reagents.add_reagent("sugar", 40)
-
- beakers += B1
- beakers += B2
-
-
-/obj/item/grenade/chem_grenade/facid
- name = "acid grenade"
- desc = "Used for melting armoured opponents."
- stage = READY
-
-/obj/item/grenade/chem_grenade/facid/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
-
- B1.reagents.add_reagent("facid", 290)
- B1.reagents.add_reagent("potassium", 10)
- B2.reagents.add_reagent("phosphorus", 10)
- B2.reagents.add_reagent("sugar", 10)
- B2.reagents.add_reagent("facid", 280)
-
- beakers += B1
- beakers += B2
-
-
-/obj/item/grenade/chem_grenade/colorful
- name = "colorful grenade"
- desc = "Used for wide scale painting projects."
- stage = READY
-
-/obj/item/grenade/chem_grenade/colorful/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
-
- B1.reagents.add_reagent("colorful_reagent", 25)
- B1.reagents.add_reagent("potassium", 25)
- B2.reagents.add_reagent("phosphorus", 25)
- B2.reagents.add_reagent("sugar", 25)
-
- beakers += B1
- beakers += B2
-
-/obj/item/grenade/chem_grenade/glitter
- name = "generic glitter grenade"
- desc = "You shouldn't see this description."
- stage = READY
- var/glitter_type = "glitter"
-
-/obj/item/grenade/chem_grenade/glitter/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
-
- B1.reagents.add_reagent(glitter_type, 25)
- B1.reagents.add_reagent("potassium", 25)
- B2.reagents.add_reagent("phosphorus", 25)
- B2.reagents.add_reagent("sugar", 25)
-
- beakers += B1
- beakers += B2
-
-/obj/item/grenade/chem_grenade/glitter/pink
- name = "pink glitter bomb"
- desc = "For that HOT glittery look."
- glitter_type = "pink_glitter"
-
-/obj/item/grenade/chem_grenade/glitter/blue
- name = "blue glitter bomb"
- desc = "For that COOL glittery look."
- glitter_type = "blue_glitter"
-
-/obj/item/grenade/chem_grenade/glitter/white
- name = "white glitter bomb"
- desc = "For that somnolent glittery look."
- glitter_type = "white_glitter"
-
-/obj/item/grenade/chem_grenade/clf3
- name = "clf3 grenade"
- desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas."
- stage = READY
-
-/obj/item/grenade/chem_grenade/clf3/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
-
- B1.reagents.add_reagent("fluorosurfactant", 250)
- B1.reagents.add_reagent("clf3", 50)
- B2.reagents.add_reagent("water", 250)
- B2.reagents.add_reagent("clf3", 50)
-
- beakers += B1
- beakers += B2
-
-/obj/item/grenade/chem_grenade/bioterrorfoam
- name = "Bio terror foam grenade"
- desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin"
- stage = READY
-
-/obj/item/grenade/chem_grenade/bioterrorfoam/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
-
- B1.reagents.add_reagent("cryptobiolin", 75)
- B1.reagents.add_reagent("water", 50)
- B1.reagents.add_reagent("mutetoxin", 50)
- B1.reagents.add_reagent("spore", 75)
- B1.reagents.add_reagent("itching_powder", 50)
- B2.reagents.add_reagent("fluorosurfactant", 150)
- B2.reagents.add_reagent("mutagen", 150)
- beakers += B1
- beakers += B2
-
-/obj/item/grenade/chem_grenade/tuberculosis
- name = "Fungal tuberculosis grenade"
- desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE."
- stage = READY
-
-/obj/item/grenade/chem_grenade/tuberculosis/Initialize()
- . = ..()
- var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
- var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
-
- B1.reagents.add_reagent("potassium", 50)
- B1.reagents.add_reagent("phosphorus", 50)
- B1.reagents.add_reagent("fungalspores", 200)
- B2.reagents.add_reagent("blood", 250)
- B2.reagents.add_reagent("sugar", 50)
-
- beakers += B1
- beakers += B2
+#define EMPTY 1
+#define WIRED 2
+#define READY 3
+
+/obj/item/grenade/chem_grenade
+ name = "chemical grenade"
+ desc = "A custom made grenade."
+ icon_state = "chemg"
+ item_state = "flashbang"
+ w_class = WEIGHT_CLASS_SMALL
+ force = 2
+ var/stage = EMPTY
+ var/list/beakers = list()
+ var/list/allowed_containers = list(/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle)
+ var/affected_area = 3
+ var/obj/item/device/assembly_holder/nadeassembly = null
+ var/assemblyattacher
+ var/ignition_temp = 10 // The amount of heat added to the reagents when this grenade goes off.
+ var/threatscale = 1 // Used by advanced grenades to make them slightly more worthy.
+ var/no_splash = FALSE //If the grenade deletes even if it has no reagents to splash with. Used for slime core reactions.
+
+/obj/item/grenade/chem_grenade/Initialize()
+ . = ..()
+ create_reagents(1000)
+ stage_change() // If no argument is set, it will change the stage to the current stage, useful for stock grenades that start READY.
+
+/obj/item/grenade/chem_grenade/examine(mob/user)
+ display_timer = (stage == READY && !nadeassembly) //show/hide the timer based on assembly state
+ ..()
+
+
+/obj/item/grenade/chem_grenade/attack_self(mob/user)
+ if(stage == READY && !active)
+ if(nadeassembly)
+ nadeassembly.attack_self(user)
+ else if(clown_check(user))
+ var/turf/bombturf = get_turf(src)
+ var/area/A = get_area(bombturf)
+ message_admins("[ADMIN_LOOKUPFLW(usr)] has primed a [name] for detonation at [A.name][ADMIN_JMP(bombturf)].")
+ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
+ to_chat(user, "You prime the [name]! [det_time / 10] second\s!")
+ playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
+ active = 1
+ icon_state = initial(icon_state) + "_active"
+ if(iscarbon(user))
+ var/mob/living/carbon/C = user
+ C.throw_mode_on()
+
+ addtimer(CALLBACK(src, .proc/prime), det_time)
+
+
+/obj/item/grenade/chem_grenade/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/screwdriver))
+ if(stage == WIRED)
+ if(beakers.len)
+ stage_change(READY)
+ to_chat(user, "You lock the [initial(name)] assembly.")
+ playsound(loc, I.usesound, 25, -3)
+ else
+ to_chat(user, "You need to add at least one beaker before locking the [initial(name)] assembly!")
+ else if(stage == READY && !nadeassembly)
+ det_time = det_time == 50 ? 30 : 50 //toggle between 30 and 50
+ to_chat(user, "You modify the time delay. It's set for [det_time / 10] second\s.")
+ else if(stage == EMPTY)
+ to_chat(user, "You need to add an activation mechanism!")
+
+ else if(stage == WIRED && is_type_in_list(I, allowed_containers))
+ . = 1 //no afterattack
+ if(beakers.len == 2)
+ to_chat(user, "[src] can not hold more containers!")
+ return
+ else
+ if(I.reagents.total_volume)
+ if(!user.transferItemToLoc(I, src))
+ return
+ to_chat(user, "You add [I] to the [initial(name)] assembly.")
+ beakers += I
+ else
+ to_chat(user, "[I] is empty!")
+
+ else if(stage == EMPTY && istype(I, /obj/item/device/assembly_holder))
+ . = 1 // no afterattack
+ var/obj/item/device/assembly_holder/A = I
+ if(isigniter(A.a_left) == isigniter(A.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
+ return
+ if(!user.transferItemToLoc(I, src))
+ return
+
+ nadeassembly = A
+ A.master = src
+ assemblyattacher = user.ckey
+
+ stage_change(WIRED)
+ to_chat(user, "You add [A] to the [initial(name)] assembly.")
+
+ else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/C = I
+ if (C.use(1))
+ det_time = 50 // In case the cable_coil was removed and readded.
+ stage_change(WIRED)
+ to_chat(user, "You rig the [initial(name)] assembly.")
+ else
+ to_chat(user, "You need one length of coil to wire the assembly!")
+ return
+
+ else if(stage == READY && istype(I, /obj/item/wirecutters) && !active)
+ stage_change(WIRED)
+ to_chat(user, "You unlock the [initial(name)] assembly.")
+
+ else if(stage == WIRED && istype(I, /obj/item/wrench))
+ if(beakers.len)
+ for(var/obj/O in beakers)
+ O.loc = get_turf(src)
+ beakers = list()
+ to_chat(user, "You open the [initial(name)] assembly and remove the payload.")
+ return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism.
+ if(nadeassembly)
+ nadeassembly.loc = get_turf(src)
+ nadeassembly.master = null
+ nadeassembly = null
+ else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used.
+ new /obj/item/stack/cable_coil(get_turf(src),1)
+ stage_change(EMPTY)
+ to_chat(user, "You remove the activation mechanism from the [initial(name)] assembly.")
+ else
+ return ..()
+
+/obj/item/grenade/chem_grenade/proc/stage_change(N)
+ if(N)
+ stage = N
+ if(stage == EMPTY)
+ name = "[initial(name)] casing"
+ desc = "A do it yourself [initial(name)]!"
+ icon_state = initial(icon_state)
+ else if(stage == WIRED)
+ name = "unsecured [initial(name)]"
+ desc = "An unsecured [initial(name)] assembly."
+ icon_state = "[initial(icon_state)]_ass"
+ else if(stage == READY)
+ name = initial(name)
+ desc = initial(desc)
+ icon_state = "[initial(icon_state)]_locked"
+
+
+//assembly stuff
+/obj/item/grenade/chem_grenade/receive_signal()
+ prime()
+
+
+/obj/item/grenade/chem_grenade/Crossed(atom/movable/AM)
+ if(nadeassembly)
+ nadeassembly.Crossed(AM)
+
+/obj/item/grenade/chem_grenade/on_found(mob/finder)
+ if(nadeassembly)
+ nadeassembly.on_found(finder)
+
+/obj/item/grenade/chem_grenade/prime()
+ if(stage != READY)
+ return
+
+ var/list/datum/reagents/reactants = list()
+ for(var/obj/item/reagent_containers/glass/G in beakers)
+ reactants += G.reagents
+
+ if(!chem_splash(get_turf(src), affected_area, reactants, ignition_temp, threatscale) && !no_splash)
+ playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1)
+ if(beakers.len)
+ for(var/obj/O in beakers)
+ O.loc = get_turf(src)
+ beakers = list()
+ stage_change(EMPTY)
+ return
+
+ if(nadeassembly)
+ var/mob/M = get_mob_by_ckey(assemblyattacher)
+ var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
+ var/turf/T = get_turf(src)
+ var/area/A = get_area(T)
+ message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [ADMIN_JMP(T)].")
+ log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [COORD(T)]")
+
+ var/turf/DT = get_turf(src)
+ var/area/DA = get_area(DT)
+ log_game("A grenade detonated at [DA.name] [COORD(DT)]")
+
+ update_mob()
+
+ qdel(src)
+
+//Large chem grenades accept slime cores and use the appropriately.
+/obj/item/grenade/chem_grenade/large
+ name = "large grenade"
+ desc = "A custom made large grenade. It affects a larger area."
+ icon_state = "large_grenade"
+ allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment,
+ /obj/item/reagent_containers/food/drinks)
+ origin_tech = "combat=3;engineering=3"
+ affected_area = 5
+ ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
+ threatscale = 1.1 // 10% more effective.
+
+/obj/item/grenade/chem_grenade/large/prime()
+ if(stage != READY)
+ return
+
+ for(var/obj/item/slime_extract/S in beakers)
+ if(S.Uses)
+ for(var/obj/item/reagent_containers/glass/G in beakers)
+ G.reagents.trans_to(S, G.reagents.total_volume)
+
+ //If there is still a core (sometimes it's used up)
+ //and there are reagents left, behave normally,
+ //otherwise drop it on the ground for timed reactions like gold.
+
+ if(S)
+ if(S.reagents && S.reagents.total_volume)
+ for(var/obj/item/reagent_containers/glass/G in beakers)
+ S.reagents.trans_to(G, S.reagents.total_volume)
+ else
+ S.forceMove(get_turf(src))
+ no_splash = TRUE
+ ..()
+
+ //I tried to just put it in the allowed_containers list but
+ //if you do that it must have reagents. If you're going to
+ //make a special case you might as well do it explicitly. -Sayu
+/obj/item/grenade/chem_grenade/large/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/slime_extract) && stage == WIRED)
+ if(!user.transferItemToLoc(I, src))
+ return
+ to_chat(user, "You add [I] to the [initial(name)] assembly.")
+ beakers += I
+ else
+ return ..()
+
+/obj/item/grenade/chem_grenade/cryo // Intended for rare cryogenic mixes. Cools the area moderately upon detonation.
+ name = "cryo grenade"
+ desc = "A custom made cryogenic grenade. It rapidly cools its contents upon detonation."
+ icon_state = "cryog"
+ affected_area = 2
+ ignition_temp = -100
+
+/obj/item/grenade/chem_grenade/pyro // Intended for pyrotechnical mixes. Produces a small fire upon detonation, igniting potentially flammable mixtures.
+ name = "pyro grenade"
+ desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation."
+ icon_state = "pyrog"
+ origin_tech = "combat=4;engineering=4"
+ affected_area = 3
+ ignition_temp = 500 // This is enough to expose a hotspot.
+
+/obj/item/grenade/chem_grenade/adv_release // Intended for weaker, but longer lasting effects. Could have some interesting uses.
+ name = "advanced release grenade"
+ desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool."
+ icon_state = "timeg"
+ origin_tech = "combat=3;engineering=4"
+ var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool.
+
+/obj/item/grenade/chem_grenade/adv_release/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/device/multitool))
+ switch(unit_spread)
+ if(0 to 24)
+ unit_spread += 5
+ if(25 to 99)
+ unit_spread += 25
+ else
+ unit_spread = 5
+ to_chat(user, " You set the time release to [unit_spread] units per detonation.")
+ return
+ ..()
+
+/obj/item/grenade/chem_grenade/adv_release/prime()
+ if(stage != READY)
+ return
+
+ var/total_volume = 0
+ for(var/obj/item/reagent_containers/RC in beakers)
+ total_volume += RC.reagents.total_volume
+ if(!total_volume)
+ qdel(src)
+ qdel(nadeassembly)
+ return
+ var/fraction = unit_spread/total_volume
+ var/datum/reagents/reactants = new(unit_spread)
+ reactants.my_atom = src
+ for(var/obj/item/reagent_containers/RC in beakers)
+ RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, threatscale, 1, 1)
+ chem_splash(get_turf(src), affected_area, list(reactants), ignition_temp, threatscale)
+
+ if(nadeassembly)
+ var/mob/M = get_mob_by_ckey(assemblyattacher)
+ var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
+ var/turf/T = get_turf(src)
+ var/area/A = get_area(T)
+ message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
+ log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
+ else
+ addtimer(CALLBACK(src, .proc/prime), det_time)
+ var/turf/DT = get_turf(src)
+ var/area/DA = get_area(DT)
+ log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])")
+
+
+
+
+
+//////////////////////////////
+////// PREMADE GRENADES //////
+//////////////////////////////
+
+/obj/item/grenade/chem_grenade/metalfoam
+ name = "metal foam grenade"
+ desc = "Used for emergency sealing of air breaches."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/metalfoam/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent("aluminium", 30)
+ B2.reagents.add_reagent("foaming_agent", 10)
+ B2.reagents.add_reagent("facid", 10)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/smart_metal_foam
+ name = "smart metal foam grenade"
+ desc = "Used for sealing and reconstruction of air breaches."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/smart_metal_foam/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent("aluminium", 75)
+ B2.reagents.add_reagent("smart_foaming_agent", 25)
+ B2.reagents.add_reagent("facid", 25)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/incendiary
+ name = "incendiary grenade"
+ desc = "Used for clearing rooms of living things."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/incendiary/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent("phosphorus", 25)
+ B2.reagents.add_reagent("stable_plasma", 25)
+ B2.reagents.add_reagent("sacid", 25)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/antiweed
+ name = "weedkiller grenade"
+ desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/antiweed/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent("plantbgone", 25)
+ B1.reagents.add_reagent("potassium", 25)
+ B2.reagents.add_reagent("phosphorus", 25)
+ B2.reagents.add_reagent("sugar", 25)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/cleaner
+ name = "cleaner grenade"
+ desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/cleaner/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent("fluorosurfactant", 40)
+ B2.reagents.add_reagent("water", 40)
+ B2.reagents.add_reagent("cleaner", 10)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/ez_clean
+ name = "cleaner grenade"
+ desc = "Waffle Co.-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/ez_clean/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
+
+ B1.reagents.add_reagent("fluorosurfactant", 40)
+ B2.reagents.add_reagent("water", 40)
+ B2.reagents.add_reagent("ez_clean", 60) //ensures a t h i c c distribution
+
+ beakers += B1
+ beakers += B2
+
+
+
+/obj/item/grenade/chem_grenade/teargas
+ name = "teargas grenade"
+ desc = "Used for nonlethal riot control. Contents under pressure. Do not directly inhale contents."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/teargas/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src)
+
+ B1.reagents.add_reagent("condensedcapsaicin", 60)
+ B1.reagents.add_reagent("potassium", 40)
+ B2.reagents.add_reagent("phosphorus", 40)
+ B2.reagents.add_reagent("sugar", 40)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/facid
+ name = "acid grenade"
+ desc = "Used for melting armoured opponents."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/facid/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
+
+ B1.reagents.add_reagent("facid", 290)
+ B1.reagents.add_reagent("potassium", 10)
+ B2.reagents.add_reagent("phosphorus", 10)
+ B2.reagents.add_reagent("sugar", 10)
+ B2.reagents.add_reagent("facid", 280)
+
+ beakers += B1
+ beakers += B2
+
+
+/obj/item/grenade/chem_grenade/colorful
+ name = "colorful grenade"
+ desc = "Used for wide scale painting projects."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/colorful/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent("colorful_reagent", 25)
+ B1.reagents.add_reagent("potassium", 25)
+ B2.reagents.add_reagent("phosphorus", 25)
+ B2.reagents.add_reagent("sugar", 25)
+
+ beakers += B1
+ beakers += B2
+
+/obj/item/grenade/chem_grenade/glitter
+ name = "generic glitter grenade"
+ desc = "You shouldn't see this description."
+ stage = READY
+ var/glitter_type = "glitter"
+
+/obj/item/grenade/chem_grenade/glitter/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/B2 = new(src)
+
+ B1.reagents.add_reagent(glitter_type, 25)
+ B1.reagents.add_reagent("potassium", 25)
+ B2.reagents.add_reagent("phosphorus", 25)
+ B2.reagents.add_reagent("sugar", 25)
+
+ beakers += B1
+ beakers += B2
+
+/obj/item/grenade/chem_grenade/glitter/pink
+ name = "pink glitter bomb"
+ desc = "For that HOT glittery look."
+ glitter_type = "pink_glitter"
+
+/obj/item/grenade/chem_grenade/glitter/blue
+ name = "blue glitter bomb"
+ desc = "For that COOL glittery look."
+ glitter_type = "blue_glitter"
+
+/obj/item/grenade/chem_grenade/glitter/white
+ name = "white glitter bomb"
+ desc = "For that somnolent glittery look."
+ glitter_type = "white_glitter"
+
+/obj/item/grenade/chem_grenade/clf3
+ name = "clf3 grenade"
+ desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/clf3/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
+
+ B1.reagents.add_reagent("fluorosurfactant", 250)
+ B1.reagents.add_reagent("clf3", 50)
+ B2.reagents.add_reagent("water", 250)
+ B2.reagents.add_reagent("clf3", 50)
+
+ beakers += B1
+ beakers += B2
+
+/obj/item/grenade/chem_grenade/bioterrorfoam
+ name = "Bio terror foam grenade"
+ desc = "Tiger Cooperative chemical foam grenade. Causes temporary irration, blindness, confusion, mutism, and mutations to carbon based life forms. Contains additional spore toxin"
+ stage = READY
+
+/obj/item/grenade/chem_grenade/bioterrorfoam/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
+
+ B1.reagents.add_reagent("cryptobiolin", 75)
+ B1.reagents.add_reagent("water", 50)
+ B1.reagents.add_reagent("mutetoxin", 50)
+ B1.reagents.add_reagent("spore", 75)
+ B1.reagents.add_reagent("itching_powder", 50)
+ B2.reagents.add_reagent("fluorosurfactant", 150)
+ B2.reagents.add_reagent("mutagen", 150)
+ beakers += B1
+ beakers += B2
+
+/obj/item/grenade/chem_grenade/tuberculosis
+ name = "Fungal tuberculosis grenade"
+ desc = "WARNING: GRENADE WILL RELEASE DEADLY SPORES CONTAINING ACTIVE AGENTS. SEAL SUIT AND AIRFLOW BEFORE USE."
+ stage = READY
+
+/obj/item/grenade/chem_grenade/tuberculosis/Initialize()
+ . = ..()
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B1 = new(src)
+ var/obj/item/reagent_containers/glass/beaker/bluespace/B2 = new(src)
+
+ B1.reagents.add_reagent("potassium", 50)
+ B1.reagents.add_reagent("phosphorus", 50)
+ B1.reagents.add_reagent("fungalspores", 200)
+ B2.reagents.add_reagent("blood", 250)
+ B2.reagents.add_reagent("sugar", 50)
+
+ beakers += B1
+ beakers += B2
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index 7b8b6c385c..cc60c9ba9c 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -583,6 +583,15 @@
for(var/i in 1 to 7)
new /obj/item/grenade/chem_grenade/metalfoam(src)
+/obj/item/storage/box/smart_metal_foam
+ name = "box of smart metal foam grenades"
+ desc = "Used to rapidly seal hull breaches. This variety conforms to the walls of its area."
+ illustration = "flashbang"
+
+/obj/item/storage/box/smart_metal_foam/PopulateContents()
+ for(var/i in 1 to 7)
+ new/obj/item/grenade/chem_grenade/smart_metal_foam(src)
+
/obj/item/storage/box/hug
name = "box of hugs"
desc = "A special box for sensitive people."
@@ -726,12 +735,13 @@
/obj/item/storage/box/ingredients/Initialize()
..()
- if(item_state)
- name = "[name] ([item_state])"
- desc = "A box containing supplementary ingredients for the aspiring chef. This box's theme is '[item_state]'."
+ if(icon_state)
+ name = "[name] ([icon_state])"
+ desc = "A box containing supplementary ingredients for the aspiring chef. This box's theme is '[icon_state]'."
+ item_state = "syringe_kit"
/obj/item/storage/box/ingredients/wildcard
- item_state = "wildcard"
+ icon_state = "wildcard"
/obj/item/storage/box/ingredients/wildcard/PopulateContents()
for(var/i in 1 to 7)
@@ -752,7 +762,7 @@
new randomFood(src)
/obj/item/storage/box/ingredients/fiesta
- item_state = "fiesta"
+ icon_state = "fiesta"
/obj/item/storage/box/ingredients/fiesta/PopulateContents()
new /obj/item/reagent_containers/food/snacks/tortilla(src)
@@ -762,7 +772,7 @@
new /obj/item/reagent_containers/food/snacks/grown/chili(src)
/obj/item/storage/box/ingredients/italian
- item_state = "italian"
+ icon_state = "italian"
/obj/item/storage/box/ingredients/italian/PopulateContents()
for(var/i in 1 to 3)
@@ -771,7 +781,7 @@
new /obj/item/reagent_containers/food/drinks/bottle/wine(src)
/obj/item/storage/box/ingredients/vegetarian
- item_state = "vegetarian"
+ icon_state = "vegetarian"
/obj/item/storage/box/ingredients/vegetarian/PopulateContents()
for(var/i in 1 to 2)
@@ -783,7 +793,7 @@
new /obj/item/reagent_containers/food/snacks/grown/tomato(src)
/obj/item/storage/box/ingredients/american
- item_state = "american"
+ icon_state = "american"
/obj/item/storage/box/ingredients/american/PopulateContents()
for(var/i in 1 to 2)
@@ -793,7 +803,7 @@
new /obj/item/reagent_containers/food/snacks/faggot(src)
/obj/item/storage/box/ingredients/fruity
- item_state = "fruity"
+ icon_state = "fruity"
/obj/item/storage/box/ingredients/fruity/PopulateContents()
for(var/i in 1 to 2)
@@ -804,7 +814,7 @@
new /obj/item/reagent_containers/food/snacks/grown/watermelon(src)
/obj/item/storage/box/ingredients/sweets
- item_state = "sweets"
+ icon_state = "sweets"
/obj/item/storage/box/ingredients/sweets/PopulateContents()
for(var/i in 1 to 2)
@@ -815,7 +825,7 @@
new /obj/item/reagent_containers/food/snacks/grown/apple(src)
/obj/item/storage/box/ingredients/delights
- item_state = "delights"
+ icon_state = "delights"
/obj/item/storage/box/ingredients/delights/PopulateContents()
for(var/i in 1 to 2)
@@ -826,7 +836,7 @@
new /obj/item/reagent_containers/food/snacks/grown/berries(src)
/obj/item/storage/box/ingredients/grains
- item_state = "grains"
+ icon_state = "grains"
/obj/item/storage/box/ingredients/grains/PopulateContents()
for(var/i in 1 to 3)
@@ -837,7 +847,7 @@
new /obj/item/seeds/poppy(src)
/obj/item/storage/box/ingredients/carnivore
- item_state = "carnivore"
+ icon_state = "carnivore"
/obj/item/storage/box/ingredients/carnivore/PopulateContents()
new /obj/item/reagent_containers/food/snacks/meat/slab/bear(src)
@@ -849,7 +859,7 @@
new /obj/item/reagent_containers/food/snacks/faggot(src)
/obj/item/storage/box/ingredients/exotic
- item_state = "exotic"
+ icon_state = "exotic"
/obj/item/storage/box/ingredients/exotic/PopulateContents()
for(var/i in 1 to 2)
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 1fae8ed2c0..c13def9897 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -24,7 +24,7 @@
..()
//This is so damaged or burnt tiles or platings don't get remembered as the default tile
var/static/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","damaged4",
- "damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2",
+ "damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2", "foam_plating",
"platingdmg3","plating","light_on","light_on_flicker1","light_on_flicker2",
"light_on_clicker3","light_on_clicker4","light_on_clicker5","light_broken",
"light_on_broken","light_off","wall_thermite","grass", "sand",
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 3247b273ae..ffc24882fd 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -62,6 +62,13 @@
data["viruses"] = preserve
return 1
+/datum/reagent/blood/proc/get_diseases()
+ . = list()
+ if(data && data["viruses"])
+ for(var/thing in data["viruses"])
+ var/datum/disease/D = thing
+ . += D
+
/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
if(!istype(T))
return
@@ -1079,6 +1086,14 @@
color = "#664B63" // rgb: 102, 75, 99
taste_description = "metal"
+/datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls.
+ name = "Smart foaming agent"
+ id = "smart_foaming_agent"
+ description = "A agent that yields metallic foam which conforms to area boundaries when mixed with light metal and a strong acid."
+ reagent_state = SOLID
+ color = "#664B63" // rgb: 102, 75, 99
+ taste_description = "metal"
+
/datum/reagent/ammonia
name = "Ammonia"
id = "ammonia"
@@ -1558,6 +1573,18 @@
ZI.Insert(H)
..()
+/datum/reagent/magillitis
+ name = "Magillitis"
+ id = "magillitis"
+ description = "An experimental serum which causes rapid muscular growth in basic primates. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas."
+ reagent_state = LIQUID
+ color = "#00f041"
+
+/datum/reagent/magillitis/on_mob_life(mob/living/carbon/M)
+ ..()
+ if(ismonkey(M) && current_cycle >= 10)
+ return M.gorillize()
+
/datum/reagent/growthserum
name = "Growth Serum"
id = "growthserum"
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index 173bcbcacc..222f88ba8b 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -466,6 +466,20 @@
s.start()
holder.clear_reagents()
+/datum/chemical_reaction/smart_foam
+ name = "Smart Metal Foam"
+ id = "smart_metal_foam"
+ required_reagents = list("aluminium" = 3, "smart_foaming_agent" = 1, "facid" = 1)
+ mob_react = TRUE
+
+/datum/chemical_reaction/smart_foam/on_reaction(datum/reagents/holder, created_volume)
+ var/turf/location = get_turf(holder.my_atom)
+ location.visible_message("The solution spews out metallic foam!")
+ var/datum/effect_system/foam_spread/metal/smart/s = new()
+ s.set_up(created_volume * 5, location, holder, TRUE)
+ s.start()
+ holder.clear_reagents()
+
/datum/chemical_reaction/ironfoam
name = "Iron Foam"
id = "ironlfoam"
@@ -487,6 +501,13 @@
results = list("foaming_agent" = 1)
required_reagents = list("lithium" = 1, "hydrogen" = 1)
+/datum/chemical_reaction/smart_foaming_agent
+ name = "Smart foaming Agent"
+ id = "smart_foaming_agent"
+ results = list("smart_foaming_agent" = 3)
+ required_reagents = list("foaming_agent" = 3, "acetone" = 1, "iron" = 1)
+ mix_message = "The solution mixes into a frothy metal foam and conforms to the walls of its container."
+
/////////////////////////////// Cleaning and hydroponics /////////////////////////////////////////////////
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index ee1d186509..a0521414f1 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ