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