diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index ba3ed604e00..a4503e427d8 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -406,6 +406,128 @@ range_light = 4 range_flame = 2 +/obj/item/weapon/bombcore/chemical + name = "chemical payload" + desc = "An explosive payload designed to spread chemicals, dangerous or otherwise, across a large area. It is able to hold up to four chemical containers, and must be loaded before use." + origin_tech = "combat=4;materials=3" + icon_state = "chemcore" + var/list/beakers = list() + var/max_beakers = 1 + var/spread_range = 5 + var/temp_boost = 50 + var/time_release = 0 + +/obj/item/weapon/bombcore/chemical/detonate() + + if(time_release > 0) + var/total_volume = 0 + for(var/obj/item/weapon/reagent_containers/RC in beakers) + total_volume += RC.reagents.total_volume + + if(total_volume < time_release) // If it's empty, the detonation is complete. + if(loc && istype(loc, /obj/machinery/syndicatebomb)) + qdel(loc) + qdel(src) + return + + var/fraction = time_release/total_volume + var/datum/reagents/reactants = new(time_release) + reactants.my_atom = src + for(var/obj/item/weapon/reagent_containers/RC in beakers) + RC.reagents.trans_to(reactants, RC.reagents.total_volume*fraction, 1, 1, 1) + chem_splash(get_turf(src), spread_range, list(reactants), temp_boost) + + // Detonate it again in one second, until it's out of juice. + addtimer(src, "detonate", 10) + + // If it's not a time release bomb, do normal explosion + + var/list/reactants = list() + + for(var/obj/item/weapon/reagent_containers/glass/G in beakers) + reactants += G.reagents + + for(var/obj/item/slime_extract/S in beakers) + if(S.Uses) + for(var/obj/item/weapon/reagent_containers/glass/G in beakers) + G.reagents.trans_to(S, G.reagents.total_volume) + + if(S && S.reagents && S.reagents.total_volume) + reactants += S.reagents + + if(!chem_splash(get_turf(src), spread_range, reactants, temp_boost)) + playsound(loc, 'sound/items/Screwdriver2.ogg', 50, 1) + return // The Explosion didn't do anything. No need to log, or disappear. + + if(adminlog) + message_admins(adminlog) + log_game(adminlog) + + playsound(loc, 'sound/effects/bamf.ogg', 75, 1, 5) + + if(loc && istype(loc, /obj/machinery/syndicatebomb)) + qdel(loc) + qdel(src) + +/obj/item/weapon/bombcore/chemical/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/crowbar) && beakers.len > 0) + playsound(loc, I.usesound, 50, 1) + for (var/obj/item/B in beakers) + B.loc = get_turf(src) + beakers -= B + return + else if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker) || istype(I, /obj/item/weapon/reagent_containers/glass/bottle)) + if(beakers.len < max_beakers) + if(!user.drop_item()) + return + beakers += I + to_chat(user, "You load [src] with [I].") + I.loc = src + else + to_chat(user, "The [I] wont fit! The [src] can only hold up to [max_beakers] containers.") + return + ..() + +/obj/item/weapon/bombcore/chemical/CheckParts(list/parts_list) + ..() + // Using different grenade casings, causes the payload to have different properties. + var/obj/item/weapon/stock_parts/matter_bin/MB = locate(/obj/item/weapon/stock_parts/matter_bin) in src + if(MB) + max_beakers += MB.rating // max beakers = 2-5. + qdel(MB) + for(var/obj/item/weapon/grenade/chem_grenade/G in src) + + if(istype(G, /obj/item/weapon/grenade/chem_grenade/large)) + var/obj/item/weapon/grenade/chem_grenade/large/LG = G + max_beakers += 1 // Adding two large grenades only allows for a maximum of 7 beakers. + spread_range += 2 // Extra range, reduced density. + temp_boost += 50 // maximum of +150K blast using only large beakers. Not enough to self ignite. + for(var/obj/item/slime_extract/S in LG.beakers) // And slime cores. + if(beakers.len < max_beakers) + beakers += S + S.loc = src + else + S.loc = get_turf(src) + + if(istype(G, /obj/item/weapon/grenade/chem_grenade/cryo)) + spread_range -= 1 // Reduced range, but increased density. + temp_boost -= 100 // minimum of -150K blast. + + if(istype(G, /obj/item/weapon/grenade/chem_grenade/pyro)) + temp_boost += 150 // maximum of +350K blast, which is enough to self ignite. Which means a self igniting bomb can't take advantage of other grenade casing properties. Sorry? + + if(istype(G, /obj/item/weapon/grenade/chem_grenade/adv_release)) + time_release += 50 // A typical bomb, using basic beakers, will explode over 2-4 seconds. Using two will make the reaction last for less time, but it will be more dangerous overall. + + for(var/obj/item/weapon/reagent_containers/glass/B in G) + if(beakers.len < max_beakers) + beakers += B + B.loc = src + else + B.loc = get_turf(src) + + qdel(G) + ///Syndicate Detonator (aka the big red button)/// /obj/item/device/syndicatedetonator diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index f21914a7c32..9ba1950d2a0 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -19,6 +19,9 @@ var/obj/item/device/assembly_holder/nadeassembly = null var/label = 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/weapon/grenade/chem_grenade/New() create_reagents(1000) @@ -99,6 +102,7 @@ log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])") bombers += "[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])" to_chat(user, "You prime the [name]! [det_time / 10] second\s!") + playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) active = 1 update_icon() if(iscarbon(user)) @@ -264,13 +268,18 @@ if(stage != READY) return - var/has_reagents = 0 + var/list/datum/reagents/reactants = list() for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - if(G.reagents.total_volume) - has_reagents = 1 + reactants += G.reagents - if(!has_reagents) - playsound(loc, usesound, 50, 1) + 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.forceMove(get_turf(src)) + beakers = list() + stage = EMPTY + update_icon() return if(nadeassembly) @@ -281,31 +290,9 @@ message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) ([admin_jump_link(M)]) and last touched by [key_name_admin(last)](?) ([admin_jump_link(last)]) ([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])") - playsound(loc, 'sound/effects/bamf.ogg', 50, 1) - update_mob() - invisibility = INVISIBILITY_MAXIMUM //kaboom - qdel(nadeassembly) // do this now to stop infrared beams - var/end_temp = 0 - for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - G.reagents.trans_to(src, G.reagents.total_volume) - end_temp += G.reagents.chem_temp - reagents.chem_temp = end_temp - if(reagents.total_volume) //The possible reactions didnt use up all reagents. - var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() - steam.set_up(10, 0, get_turf(src)) - steam.attach(src) - steam.start() - - for(var/atom/A in view(affected_area, loc)) - if(A == src) - continue - reagents.reaction(A, 1, 10) - - - spawn(15) //Making sure all reagents can work - qdel(src) //correctly before deleting the grenade. + qdel(src) /obj/item/weapon/grenade/chem_grenade/proc/CreateDefaultTrigger(var/typekey) if(ispath(typekey,/obj/item/device/assembly)) @@ -327,64 +314,37 @@ //Large chem grenades accept slime cores and use the appropriately. /obj/item/weapon/grenade/chem_grenade/large name = "large grenade casing" - desc = "For oversized grenades; fits additional contents and affects a greater area." + desc = "A custom made large grenade. It affects a larger area." icon_state = "large_grenade" bomb_state = "largebomb" allowed_containers = list(/obj/item/weapon/reagent_containers/glass,/obj/item/weapon/reagent_containers/food/condiment, /obj/item/weapon/reagent_containers/food/drinks) origin_tech = "combat=3;engineering=3" - affected_area = 4 - + 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/weapon/grenade/chem_grenade/large/prime() if(stage != READY) return - var/has_reagents = 0 - var/obj/item/slime_extract/valid_core = null + for(var/obj/item/slime_extract/S in beakers) + if(S.Uses) + for(var/obj/item/weapon/reagent_containers/glass/G in beakers) + G.reagents.trans_to(S, G.reagents.total_volume) - for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - if(!istype(G)) continue - if(G.reagents.total_volume) has_reagents = 1 - for(var/obj/item/slime_extract/E in beakers) - if(!istype(E)) continue - if(E.Uses) valid_core = E - if(E.reagents.total_volume) has_reagents = 1 + //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(!has_reagents) - playsound(loc, prime_sound, 50, 1) - return - - playsound(loc, 'sound/effects/bamf.ogg', 50, 1) - - update_mob() - - if(valid_core) - for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - G.reagents.trans_to(valid_core, G.reagents.total_volume) - - //If there is still a core (sometimes it's used up) - //and there are reagents left, behave normally - - if(valid_core && valid_core.reagents && valid_core.reagents.total_volume) - valid_core.reagents.trans_to(src,valid_core.reagents.total_volume) - else - for(var/obj/item/weapon/reagent_containers/glass/G in beakers) - G.reagents.trans_to(src, G.reagents.total_volume) - - if(reagents.total_volume) //The possible reactions didnt use up all reagents. - var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() - steam.set_up(10, 0, get_turf(src)) - steam.attach(src) - steam.start() - - for(var/atom/A in view(affected_area, loc)) - if( A == src ) continue - reagents.reaction(A, 1, 10) - - invisibility = INVISIBILITY_MAXIMUM //Why am i doing this? - spawn(50) //To make sure all reagents can work - qdel(src) //correctly before deleting the grenade. + if(S) + if(S.reagents && S.reagents.total_volume) + for(var/obj/item/weapon/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 @@ -399,6 +359,71 @@ else return ..() +/obj/item/weapon/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/weapon/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/weapon/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/weapon/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/weapon/grenade/chem_grenade/adv_release/prime() + if(stage != READY) + return + + var/total_volume = 0 + for(var/obj/item/weapon/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/weapon/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(src, "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])") /obj/item/weapon/grenade/chem_grenade/metalfoam payload_name = "metal foam" diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 6f266c121e1..3fbcf39ed08 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -324,6 +324,30 @@ /obj/item/stack/rods = 1) category = CAT_MISC +/datum/crafting_recipe/chemical_payload + name = "Chemical Payload (C4)" + result = /obj/item/weapon/bombcore/chemical + reqs = list( + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/grenade/plastic/c4 = 1, + /obj/item/weapon/grenade/chem_grenade = 2 + ) + parts = list(/obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/grenade/chem_grenade = 2) + time = 30 + category = CAT_WEAPON + +/datum/crafting_recipe/chemical_payload2 + name = "Chemical Payload (gibtonite)" + result = /obj/item/weapon/bombcore/chemical + reqs = list( + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/twohanded/required/gibtonite = 1, + /obj/item/weapon/grenade/chem_grenade = 2 + ) + parts = list(/obj/item/weapon/stock_parts/matter_bin = 1, /obj/item/weapon/grenade/chem_grenade = 2) + time = 50 + category = CAT_WEAPON + /datum/crafting_recipe/bonfire name = "Bonfire" time = 60 diff --git a/code/modules/reagents/chem_splash.dm b/code/modules/reagents/chem_splash.dm new file mode 100644 index 00000000000..7c16bf1ab9a --- /dev/null +++ b/code/modules/reagents/chem_splash.dm @@ -0,0 +1,78 @@ +// Replaces chemgrenade stuff, allowing reagent explosions to be called from anywhere. +// It should be called using a location, the range, and a list of reagents involved. + +// Threatscale is a multiplier for the 'threat' of the grenade. If you're increasing the affected range drastically, you might want to improve this. +// Extra heat affects the temperature of the mixture, and may cause it to react in different ways. + + +/proc/chem_splash(turf/epicenter, affected_range = 3, list/datum/reagents/reactants = list(), extra_heat = 0, threatscale = 1, adminlog = 1) + if(!isturf(epicenter) || !reactants.len || threatscale <= 0) + return + var/has_reagents + var/total_reagents + for(var/datum/reagents/R in reactants) + if(R.total_volume) + has_reagents = 1 + total_reagents += R.total_volume + + if(!has_reagents) + return + + var/datum/reagents/splash_holder = new/datum/reagents(total_reagents*threatscale) + splash_holder.my_atom = epicenter // For some reason this is setting my_atom to null, and causing runtime errors. + var/total_temp = 0 + + for(var/datum/reagents/R in reactants) + R.trans_to(splash_holder, R.total_volume, threatscale, 1, 1) + total_temp += R.chem_temp + splash_holder.chem_temp = (total_temp/reactants.len) + extra_heat // Average temperature of reagents + extra heat. + splash_holder.handle_reactions() // React them now. + + if(splash_holder.total_volume && affected_range >= 0) //The possible reactions didnt use up all reagents, so we spread it around. + var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() + steam.set_up(10, 0, epicenter) + steam.attach(epicenter) + steam.start() + + var/list/viewable = view(affected_range, epicenter) + + var/list/accessible = list(epicenter) + for(var/i=1; i<=affected_range; i++) + var/list/turflist = list() + for(var/turf/T in (orange(i, epicenter) - orange(i-1, epicenter))) + turflist |= T + for(var/turf/T in turflist) + if( !(get_dir(T,epicenter) in cardinal) && (abs(T.x - epicenter.x) == abs(T.y - epicenter.y) )) + turflist.Remove(T) + turflist.Add(T) // we move the purely diagonal turfs to the end of the list. + for(var/turf/T in turflist) + if(accessible[T]) + continue + for(var/thing in T.GetAtmosAdjacentTurfs(alldir = TRUE)) + var/turf/NT = thing + if(!(NT in accessible)) + continue + if(!(get_dir(T,NT) in cardinal)) + continue + accessible[T] = 1 + break + var/list/reactable = accessible + for(var/turf/T in accessible) + for(var/atom/A in T.GetAllContents()) + if(!(A in viewable)) + continue + reactable |= A + if(extra_heat >= 300) + T.hotspot_expose(extra_heat*2, 5) + if(!reactable.len) //Nothing to react with. Probably means we're in nullspace. + return + for(var/thing in reactable) + var/atom/A = thing + var/distance = max(1,get_dist(A, epicenter)) + var/fraction = 0.5/(2 ** distance) //50/25/12/6... for a 200u splash, 25/12/6/3... for a 100u, 12/6/3/1 for a 50u + splash_holder.reaction(A, TOUCH, fraction) + + qdel(splash_holder) + return 1 + + diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index c65c628353b..662843e337a 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -108,7 +108,7 @@ var/const/INGEST = 2 return the_id -/datum/reagents/proc/trans_to(target, amount=1, multiplier=1, preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. +/datum/reagents/proc/trans_to(target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. if(!target) return if(total_volume <= 0) @@ -143,13 +143,14 @@ var/const/INGEST = 2 if(preserve_data) trans_data = copy_data(current_reagent) - R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, chem_temp) + R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, chem_temp, no_react = 1) remove_reagent(current_reagent.id, current_reagent_transfer) update_total() R.update_total() - R.handle_reactions() - handle_reactions() + if(!no_react) + R.handle_reactions() + handle_reactions() return amount /datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1, safety = 0) @@ -537,7 +538,7 @@ var/const/INGEST = 2 var/amt = list_reagents[r_id] add_reagent(r_id, amt, data) -/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300) +/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0) if(!isnum(amount)) return 1 update_total() @@ -554,7 +555,8 @@ var/const/INGEST = 2 update_total() my_atom.on_reagent_change() R.on_merge(data) - handle_reactions() + if(!no_react) + handle_reactions() return 0 var/datum/reagent/D = chemical_reagents_list[reagent] @@ -570,7 +572,8 @@ var/const/INGEST = 2 update_total() my_atom.on_reagent_change() - handle_reactions() + if(!no_react) + handle_reactions() return 0 else warning("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index f60efa3b784..63db086cef8 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -40,7 +40,8 @@ /obj/machinery/biogenerator, /obj/machinery/hydroponics, /obj/machinery/constructable_frame, - /obj/machinery/icemachine) + /obj/machinery/icemachine, + /obj/item/weapon/bombcore/chemical) /obj/item/weapon/reagent_containers/glass/New() ..() diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index d406dcaf0ef..eb43698d451 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -29,6 +29,7 @@ /obj/structure/reagent_dispensers/proc/boom() visible_message("[src] ruptures!") + chem_splash(loc, 5, list(reagents)) qdel(src) /obj/structure/reagent_dispensers/ex_act(severity) @@ -53,15 +54,6 @@ desc = "A water tank." icon_state = "water" -/obj/structure/reagent_dispensers/watertank/boom() - playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6) - new /obj/effect/effect/water(loc) - for(var/turf/simulated/T in view(5, loc)) - T.MakeSlippery() - for(var/mob/living/L in T) - L.adjust_fire_stacks(-20) - ..() - /obj/structure/reagent_dispensers/watertank/high name = "high-capacity water tank" desc = "A highly-pressurized water tank made to hold gargantuan amounts of water.." diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 9391af77424..09b17748dfd 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -80,6 +80,36 @@ build_path = /obj/item/weapon/grenade/chem_grenade/large category = list("Weapons") +/datum/design/pyro_grenade + name = "Pyro Grenade" + desc = "An advanced grenade that is able to self ignite its mixture." + id = "pyro_Grenade" + req_tech = list("combat" = 4, "engineering" = 4) + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_PLASMA = 500) + build_path = /obj/item/weapon/grenade/chem_grenade/pyro + category = list("Weapons") + +/datum/design/cryo_grenade + name = "Cryo Grenade" + desc = "An advanced grenade that rapidly cools its contents upon detonation." + id = "cryo_Grenade" + req_tech = list("combat" = 3, "materials" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 500) + build_path = /obj/item/weapon/grenade/chem_grenade/cryo + category = list("Weapons") + +/datum/design/adv_grenade + name = "Advanced Release Grenade" + desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter." + id = "adv_Grenade" + req_tech = list("combat" = 3, "engineering" = 4) + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 500) + build_path = /obj/item/weapon/grenade/chem_grenade/adv_release + category = list("Weapons") + /datum/design/tele_shield name = "Telescopic Riot Shield" desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi index ad8268ad59d..f33135baec6 100644 Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ diff --git a/paradise.dme b/paradise.dme index 0775e9b2577..0f7332878f4 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1948,6 +1948,7 @@ #include "code\modules\projectiles\projectile\magic.dm" #include "code\modules\projectiles\projectile\reusable.dm" #include "code\modules\projectiles\projectile\special.dm" +#include "code\modules\reagents\chem_splash.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" #include "code\modules\reagents\chemistry\colors.dm"