From ffa39629edc0021a14aa5de285332b88ab222bd4 Mon Sep 17 00:00:00 2001 From: jjpark-kb <55967837+jjpark-kb@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:36:12 -0400 Subject: [PATCH] [semi-modular] reagent forging (#6614) * start of reagent forging * reagent forging * add the three items to ashwalker den --- .../lavaland_surface_ash_walker1.dmm | 3 + code/game/objects/items/stacks/rods.dm | 10 + .../items/stacks/sheets/sheet_types.dm | 6 +- .../code/modules/reagent_forging/anvil.dm | 48 +++ .../code/modules/reagent_forging/forge.dm | 337 ++++++++++++++++++ .../modules/reagent_forging/forge_clothing.dm | 65 ++++ .../modules/reagent_forging/forge_items.dm | 84 +++++ .../modules/reagent_forging/forge_recipes.dm | 44 +++ .../modules/reagent_forging/forge_weapons.dm | 46 +++ .../modules/reagent_forging/water_basin.dm | 30 ++ .../icons/mob/forge_clothing.dmi | Bin 0 -> 1108 bytes .../icons/mob/forge_weapon_l.dmi | Bin 0 -> 473 bytes .../icons/mob/forge_weapon_r.dmi | Bin 0 -> 476 bytes .../icons/obj/forge_clothing.dmi | Bin 0 -> 765 bytes .../reagent_forging/icons/obj/forge_items.dmi | Bin 0 -> 1866 bytes .../icons/obj/forge_structures.dmi | Bin 0 -> 1118 bytes .../modules/reagent_forging/readme.md | 28 ++ .../modules/reagent_forging/sound/forge.ogg | Bin 0 -> 16811 bytes .../reagent_forging/sound/hot_hiss.ogg | Bin 0 -> 15870 bytes tgstation.dme | 7 + 20 files changed, 707 insertions(+), 1 deletion(-) create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/anvil.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_clothing.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_items.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_recipes.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_weapons.dm create mode 100644 modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/water_basin.dm create mode 100644 modular_skyrat/modules/reagent_forging/icons/mob/forge_clothing.dmi create mode 100644 modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi create mode 100644 modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi create mode 100644 modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi create mode 100644 modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi create mode 100644 modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi create mode 100644 modular_skyrat/modules/reagent_forging/readme.md create mode 100644 modular_skyrat/modules/reagent_forging/sound/forge.ogg create mode 100644 modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index 5d42d955483..076b23cab38 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -359,6 +359,9 @@ /obj/structure/stone_tile{ dir = 4 }, +/obj/item/forging/billow, +/obj/item/forging/hammer, +/obj/item/forging/tongs, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/ash_walkers) "bc" = ( diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 697682c5e03..4791e8b3bb1 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -74,6 +74,16 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ R.use(2) if (!R && replace) user.put_in_hands(new_item) + // SKYRAT EDIT ADDITION BEGIN: Reagent Forging + if(istype(W, /obj/item/forging/tongs)) + var/obj/searchObj = locate(/obj) in W.contents + if(searchObj) + to_chat(user, span_warning("The tongs are already holding something, make room.")) + return + forceMove(W) + W.icon_state = "tong_full" + return + // SKYRAT EDIT ADDITION END else return ..() diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index a8adb798032..0fbb37a023e 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -124,7 +124,10 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("voting box", /obj/structure/votebox, 15, time = 50), \ new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \ new/datum/stack_recipe("hygienebot assembly", /obj/item/bot_assembly/hygienebot, 2, time = 5 SECONDS), \ - new/datum/stack_recipe("shower frame", /obj/structure/showerframe, 2, time= 2 SECONDS) + new/datum/stack_recipe("shower frame", /obj/structure/showerframe, 2, time= 2 SECONDS), \ + null, \ + new/datum/stack_recipe("anvil", /obj/structure/reagent_anvil, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("forge", /obj/structure/reagent_forge, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE) )) /obj/item/stack/sheet/iron//SKYRAT EDIT - ICON OVERRIDEN BY AESTHETICS - SEE MODULE @@ -245,6 +248,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new/datum/stack_recipe("wooden crate", /obj/structure/closet/crate/wooden, 6, time = 50, one_per_turf = TRUE, on_floor = TRUE),\ new/datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),\ new/datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("water basin", /obj/structure/reagent_water_basin, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE), /* SKYRAT EDIT ADDITION*/\ new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar, 3), \ new/datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 100), \ null, \ diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/anvil.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/anvil.dm new file mode 100644 index 00000000000..4430d708bfc --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/anvil.dm @@ -0,0 +1,48 @@ +/obj/structure/reagent_anvil + name = "anvil" + desc = "An object with the intent to hammer metal against. One of the most important parts for forging an item." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi' + icon_state = "anvil_empty" + + anchored = TRUE + density = TRUE + +/obj/structure/reagent_anvil/attackby(obj/item/I, mob/living/user, params) + var/obj/item/forging/incomplete/searchIncompleteSrc = locate(/obj/item/forging/incomplete) in contents + if(istype(I, /obj/item/forging/hammer) && searchIncompleteSrc) + playsound(src, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', 50, TRUE) + if(searchIncompleteSrc.heat_world_compare <= world.time) + to_chat(user, span_warning("You mess up, the metal was too cool!")) + searchIncompleteSrc.times_hit -= 3 + return + if(searchIncompleteSrc.world_compare <= world.time) + searchIncompleteSrc.world_compare = world.time + searchIncompleteSrc.average_wait + searchIncompleteSrc.times_hit++ + to_chat(user, span_notice("You strike the metal-- good hit.")) + if(searchIncompleteSrc.times_hit >= searchIncompleteSrc.average_hits) + to_chat(user, span_notice("The metal is sounding ready.")) + return + searchIncompleteSrc.times_hit -= 3 + to_chat(user, span_warning("You strike the metal-- bad hit.")) + if(searchIncompleteSrc.times_hit <= -(searchIncompleteSrc.average_hits)) + to_chat(user, span_warning("The hits were too inconsistent-- the metal breaks!")) + icon_state = "anvil_empty" + qdel(searchIncompleteSrc) + return + if(istype(I, /obj/item/forging/tongs)) + var/obj/item/forging/incomplete/searchIncompleteItem = locate(/obj/item/forging/incomplete) in I.contents + if(searchIncompleteSrc && !searchIncompleteItem) + searchIncompleteSrc.forceMove(I) + icon_state = "anvil_empty" + I.icon_state = "tong_full" + return + if(!searchIncompleteSrc && searchIncompleteItem) + searchIncompleteItem.forceMove(src) + icon_state = "anvil_full" + I.icon_state = "tong_empty" + return + if(I.tool_behaviour == TOOL_WRENCH) + new /obj/item/stack/sheet/iron/ten(get_turf(src)) + qdel(src) + return + return ..() diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge.dm new file mode 100644 index 00000000000..596b3356440 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge.dm @@ -0,0 +1,337 @@ +/obj/structure/reagent_forge + name = "forge" + desc = "A structure built out of bricks, with the intended purpose of heating up metal." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi' + icon_state = "forge_empty" + + anchored = TRUE + density = TRUE + + ///the temperature of the forge + //temperature reached by wood is not enough, requires billows. As long as fuel is in, temperature can be raised. + var/forge_temperature = 0 + //what temperature the forge is trying to reach + var/target_temperature = 0 + ///the chance that the forges temperature will not lower; max of 100 sinew_lower_chance. + //normal forges are 0; to increase value, use watcher sinew to increase by 10, to a max of 100. + var/sinew_lower_chance = 0 + ///the fuel amount (in seconds) that the forge has (wood) + var/forge_fuel_weak = 0 + ///the fuel amount (in seconds) that the forge has (stronger than wood) + var/forge_fuel_strong = 0 + ///whether the forge is capable of allowing reagent forging of the forged item. + //normal forges are false; to turn into true, use 3 (active) legion cores. + var/reagent_forging = FALSE + //counting how many cores used to turn forge into a reagent forging forge. + var/current_core = 0 + //the variable for the process checking to the world time + var/world_check = 0 + //the variable that stops spamming + var/in_use = FALSE + +/obj/structure/reagent_forge/Initialize() + . = ..() + START_PROCESSING(SSobj, src) + +/obj/structure/reagent_forge/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/structure/reagent_forge/proc/check_fuel() + if(forge_fuel_strong) //use strong fuel first + forge_fuel_strong -= 5 + target_temperature = 100 + return + if(forge_fuel_weak) //then weak fuel second + forge_fuel_weak -=5 + target_temperature = 50 + return + target_temperature = 0 //if no fuel, slowly go back down to zero + +/obj/structure/reagent_forge/proc/check_temp() + if(forge_temperature > target_temperature) //above temp needs to lower slowly + if(sinew_lower_chance && prob(sinew_lower_chance))//chance to not lower the temp, up to 100 from 10 sinew + return + forge_temperature -= 5 + return + else if(forge_temperature < target_temperature && (forge_fuel_weak || forge_fuel_strong)) //below temp with fuel needs to rise + forge_temperature += 5 + + if(forge_temperature > 0) + icon_state = "forge_full" + light_range = 3 + else if(forge_temperature <= 0) + icon_state = "forge_empty" + light_range = 0 + +/obj/structure/reagent_forge/process() + if(world_check >= world.time) //to make it not too intensive, every 5 seconds + return + world_check += 5 SECONDS + check_fuel() + check_temp() + +/obj/structure/reagent_forge/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/stack/sheet/mineral/wood)) //used for weak fuel + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + if(forge_fuel_weak >= 300) //cannot insert too much + to_chat(user, span_warning("You only need one to two pieces of wood at a time! You have [forge_fuel_weak] seconds remaining!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to throw the fuel into the forge...")) + if(!do_after(user, 3 SECONDS, target = src)) //need 3 seconds to fuel the forge + to_chat(user, span_warning("You abandon fueling the forge.")) + in_use = FALSE + return + var/obj/item/stack/sheet/stackSheet = I + if(!stackSheet.use(1)) //you need to be able to use the item, so no glue. + to_chat(user, span_warning("You abandon fueling the forge.")) + in_use = FALSE + return + forge_fuel_weak += 300 //5 minutes + in_use = FALSE + to_chat(user, span_notice("You successfully fuel the forge.")) + return + + if(istype(I, /obj/item/stack/sheet/mineral/coal)) //used for strong fuel + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + if(forge_fuel_strong >= 300) //cannot insert too much + to_chat(user, span_warning("You only need one to two pieces of coal at a time! You have [forge_fuel_strong] seconds remaining!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to throw the fuel into the forge...")) + if(!do_after(user, 3 SECONDS, target = src)) //need 3 seconds to fuel the forge + to_chat(user, span_warning("You abandon fueling the forge.")) + in_use = FALSE + return + var/obj/item/stack/sheet/stackSheet = I + if(!stackSheet.use(1)) //need to be able to use the item, so no glue + to_chat(user, span_warning("You abandon fueling the forge.")) + in_use = FALSE + return + forge_fuel_strong += 300 //5 minutes + in_use = FALSE + to_chat(user, span_notice("You successfully fuel the forge.")) + return + + if(istype(I, /obj/item/forging/billow)) + if(in_use) //no spamming the billows + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + if(!forge_fuel_strong && !forge_fuel_weak) //if there isnt any fuel, no billow use + to_chat(user, span_warning("You cannot use the billow without some sort of fuel in the forge!")) + in_use = FALSE + return + if(forge_temperature >= 100) //we don't want the "temp" to overflow or something somehow + to_chat(user, span_warning("You do not need to use a billow at this moment, the forge is already hot enough!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to pump the billow into the forge...")) + if(!do_after(user, 3 SECONDS, target = src)) //3 seconds to increase the temperature + to_chat(user, span_warning("You abandon billowing the forge.")) + in_use = FALSE + return + forge_temperature += 10 + in_use = FALSE + to_chat(user, span_notice("You successfully increase the temperature inside the forge.")) + return + + if(istype(I, /obj/item/stack/sheet/sinew)) + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + if(sinew_lower_chance >= 100) //max is 100 + to_chat(user, span_warning("You cannot insert any more sinew!")) + in_use = FALSE + return + to_chat(user, span_warning("You start lining the forge with sinew...")) + if(!do_after(user, 3 SECONDS, target = src)) //wait 3 seconds to upgrade + to_chat(user, span_warning("You abandon lining the forge with sinew.")) + in_use = FALSE + return + var/obj/item/stack/sheet/stackSheet = I + if(!stackSheet.use(1)) //need to be able to use the item, so no glue + to_chat(user, span_warning("You abandon lining the forge with sinew.")) + in_use = FALSE + return + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + sinew_lower_chance += 10 + in_use = FALSE + to_chat(user, span_notice("You successfully line the forge with sinew.")) + return + + if(istype(I, /obj/item/organ/regenerative_core)) + if(reagent_forging) //if its already able to reagent forge, why continue wasting? + to_chat(user, span_warning("This forge is already upgraded.")) + return + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + var/obj/item/organ/regenerative_core/usedCore = I + if(usedCore.inert) //no inert cores allowed + to_chat(user, span_warning("You cannot use an inert regenerative core.")) + in_use = FALSE + return + to_chat(user, span_warning("You start to sacrifice the regenerative core to the forge...")) + if(!do_after(user, 3 SECONDS, target = src)) //wait 3 seconds to upgrade + to_chat(user, span_warning("You abandon sacrificing the regenerative core to the forge.")) + in_use = FALSE + return + to_chat(user, span_notice("You successfully sacrifice the regenerative core to the forge.")) + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + qdel(I) + current_core++ + in_use = FALSE + if(current_core >= 3) //use three regenerative cores to get reagent forging capabilities on the forge + reagent_forging = TRUE + to_chat(user, span_notice("You feel the forge has upgraded.")) + color = "#ff5151" + name = "reagent forge" + desc = "A structure built out of metal, with the intended purpose of heating up metal. It has the ability to imbue!" + return + + if(istype(I, /obj/item/forging/tongs)) + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + if(forge_temperature <= 50) + to_chat(user, span_warning("The temperature is not hot enough to start heating the metal.")) + in_use = FALSE + return + var/obj/item/forging/incomplete/searchIncomplete = locate(/obj/item/forging/incomplete) in I.contents + if(searchIncomplete) + to_chat(user, span_warning("You start to heat up the metal...")) + if(!do_after(user, 3 SECONDS, target = src)) //wait 3 seconds to upgrade + to_chat(user, span_warning("You abandon heating up the metal, breaking the metal.")) + in_use = FALSE + return + searchIncomplete.heat_world_compare = world.time + 1 MINUTES + in_use = FALSE + to_chat(user, span_notice("You successfully heat up the metal.")) + return + var/obj/item/stack/rods/searchRods = locate(/obj/item/stack/rods) in I.contents + if(searchRods) + var/user_choice = input(user, "What would you like to work on?", "Forge Selection") as null|anything in list("Chain", "Sword", "Staff") + if(!user_choice) + to_chat(user, span_warning("You decide against continuing to forge.")) + in_use = FALSE + return + if(!searchRods.use(1)) + to_chat(user, span_warning("You cannot use the rods!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to heat up the metal...")) + if(!do_after(user, 3 SECONDS, target = src)) //wait 3 seconds to upgrade + to_chat(user, span_warning("You abandon heating up the metal, breaking the metal.")) + in_use = FALSE + return + var/obj/item/forging/incomplete/incompleteItem + switch(user_choice) + if("Chain") + incompleteItem = new /obj/item/forging/incomplete/chain(get_turf(src)) + if("Sword") + incompleteItem = new /obj/item/forging/incomplete/sword(get_turf(src)) + if("Staff") + incompleteItem = new /obj/item/forging/incomplete/staff(get_turf(src)) + incompleteItem.heat_world_compare = world.time + 1 MINUTES + in_use = FALSE + to_chat(user, span_notice("You successfully heat up the metal, ready to forge a [user_choice].")) + return + + if(I.tool_behaviour == TOOL_WRENCH) + new /obj/item/stack/sheet/iron/ten(get_turf(src)) + qdel(src) + + if(istype(I, /obj/item/forging/reagent_weapon) && reagent_forging) + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + var/obj/item/forging/reagent_weapon/reagentWeapon = I + if(reagentWeapon.imbued_reagent.len > 0) + to_chat(user, span_warning("This weapon has already been imbued!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to imbue the weapon...")) + if(!do_after(user, 10 SECONDS, target = src)) //wait 10 seconds to upgrade + to_chat(user, span_warning("You abandon imbueing the weapon.")) + in_use = FALSE + return + for(var/datum/reagent/weaponReagent in reagentWeapon.reagents.reagent_list) + if(weaponReagent.volume < 200) + continue + reagentWeapon.imbued_reagent += weaponReagent.type + reagentWeapon.name = "[weaponReagent.name] [reagentWeapon.name]" + reagentWeapon.color = mix_color_from_reagents(reagentWeapon.reagents.reagent_list) + to_chat(user, span_notice("You finish imbueing the weapon...")) + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + in_use = FALSE + return + + if(istype(I, /obj/item/clothing/suit/armor/reagent_clothing) && reagent_forging) + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + var/obj/item/clothing/suit/armor/reagent_clothing/reagentClothing = I + if(reagentClothing.imbued_reagent.len > 0) + to_chat(user, span_warning("This clothing has already been imbued!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to imbue the clothing...")) + if(!do_after(user, 10 SECONDS, target = src)) //wait 10 seconds to upgrade + to_chat(user, span_warning("You abandon imbueing the clothing.")) + in_use = FALSE + return + for(var/datum/reagent/clothingReagent in reagentClothing.reagents.reagent_list) + if(clothingReagent.volume < 200) + continue + reagentClothing.imbued_reagent += clothingReagent.type + reagentClothing.name = "[clothingReagent.name] [reagentClothing.name]" + reagentClothing.color = mix_color_from_reagents(reagentClothing.reagents.reagent_list) + to_chat(user, span_notice("You finish imbueing the clothing...")) + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + in_use = FALSE + return + + if(istype(I, /obj/item/clothing/gloves/reagent_clothing) && reagent_forging) + if(in_use) //only insert one at a time + to_chat(user, span_warning("You cannot do multiple things at the same time!")) + return + in_use = TRUE + var/obj/item/clothing/gloves/reagent_clothing/reagentClothing = I + if(reagentClothing.imbued_reagent.len > 0) + to_chat(user, span_warning("This clothing has already been imbued!")) + in_use = FALSE + return + to_chat(user, span_warning("You start to imbue the clothing...")) + if(!do_after(user, 10 SECONDS, target = src)) //wait 10 seconds to upgrade + to_chat(user, span_warning("You abandon imbueing the clothing.")) + in_use = FALSE + return + for(var/datum/reagent/clothingReagent in reagentClothing.reagents.reagent_list) + if(clothingReagent.volume < 200) + continue + reagentClothing.imbued_reagent += clothingReagent.type + reagentClothing.name = "[clothingReagent.name] [reagentClothing.name]" + reagentClothing.color = mix_color_from_reagents(reagentClothing.reagents.reagent_list) + to_chat(user, span_notice("You finish imbueing the clothing...")) + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + in_use = FALSE + return + + return ..() + +/obj/structure/reagent_forge/reagent_allow + current_core = 3 + reagent_forging = TRUE diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_clothing.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_clothing.dm new file mode 100644 index 00000000000..c123daa747f --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_clothing.dm @@ -0,0 +1,65 @@ +//armor +/obj/item/clothing/suit/armor/reagent_clothing + name = "chain armor" + desc = "A piece of armor made out of chains, ready to be imbued with a chemical." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "chain_armor" + worn_icon = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_clothing.dmi' + resistance_flags = FIRE_PROOF + var/list/imbued_reagent = list() + var/world_pausing = 0 + mutant_variants = NONE + +/obj/item/clothing/suit/armor/reagent_clothing/Initialize() + . = ..() + create_reagents(500, INJECTABLE | REFILLABLE) + START_PROCESSING(SSobj, src) + +/obj/item/clothing/suit/armor/reagent_clothing/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/item/clothing/suit/armor/reagent_clothing/process() + if(world_pausing >= world.time) + return + world_pausing = world.time + 2 SECONDS + if(!imbued_reagent.len || !ishuman(loc)) + return + var/mob/living/carbon/human/humanMob = loc + if(!humanMob.wear_suit != src) + return + for(var/reagentList in imbued_reagent) + humanMob.reagents.add_reagent(reagentList, 0.5) + +//gloves +/obj/item/clothing/gloves/reagent_clothing + name = "chain gloves" + desc = "A set of gloves made out of chains, ready to be imbued with a chemical." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi' + icon_state = "chain_glove" + worn_icon = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_clothing.dmi' + resistance_flags = FIRE_PROOF + var/list/imbued_reagent = list() + var/world_pausing = 0 + mutant_variants = NONE + +/obj/item/clothing/gloves/reagent_clothing/Initialize() + . = ..() + create_reagents(500, INJECTABLE | REFILLABLE) + START_PROCESSING(SSobj, src) + +/obj/item/clothing/gloves/reagent_clothing/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/item/clothing/gloves/reagent_clothing/process() + if(world_pausing >= world.time) + return + world_pausing = world.time + 2 SECONDS + if(!imbued_reagent.len || !ishuman(loc)) + return + var/mob/living/carbon/human/humanMob = loc + if(humanMob.gloves != src) + return + for(var/reagentList in imbued_reagent) + humanMob.reagents.add_reagent(reagentList, 0.5) diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_items.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_items.dm new file mode 100644 index 00000000000..7506db66ea1 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_items.dm @@ -0,0 +1,84 @@ +/obj/item/forging + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + +/obj/item/forging/tongs + name = "forging tongs" + desc = "A set of tongs specifically crafted for use in forging. A wise man once said 'I lift things up and put them down.'" + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + icon_state = "tong_empty" + +/obj/item/forging/tongs/attack_self(mob/user, modifiers) + . = ..() + var/obj/searchObj = locate(/obj) in contents + if(searchObj) + searchObj.forceMove(get_turf(src)) + icon_state = "tong_empty" + return + +/obj/item/forging/hammer + name = "forging hammer" + desc = "A hammer specifically crafted for use in forging. Used to slowly shape metal; careful, you could break something with it!" + icon_state = "hammer" + +/obj/item/forging/billow + name = "forging billow" + desc = "A billow specifically crafted for use in forging. Used to stoke the flames and keep the forge lit." + icon_state = "billow" + +//incomplete pre-complete items +/obj/item/forging/incomplete + name = "parent dev item" + desc = "An incomplete forge item, continue to work hard to be rewarded for your efforts." + //the compare of when it gets too cold to hammer + var/heat_world_compare = 0 + //the compare so you cant just keep hitting + var/world_compare = 0 + var/average_hits = 30 + var/times_hit = 0 + var/average_wait = 1 SECONDS + + var/spawn_item + +/obj/item/forging/incomplete/attackby(obj/item/I, mob/living/user, params) + . = ..() + if(istype(I, /obj/item/forging/tongs)) + var/obj/searchObj = locate(/obj) in I.contents + if(searchObj) + to_chat(user, span_warning("The tongs are already holding something, make room.")) + return + forceMove(I) + I.icon_state = "tong_full" + return + +/obj/item/forging/incomplete/chain + name = "incomplete chain" + icon_state = "hot_chain" + average_hits = 10 + average_wait = 0.5 SECONDS + spawn_item = /obj/item/forging/complete/chain + +/obj/item/forging/incomplete/sword + name = "incomplete sword blade" + icon_state = "hot_blade" + spawn_item = /obj/item/forging/complete/sword + +/obj/item/forging/incomplete/staff + name = "incomplete staff head" + icon_state = "hot_staffhead" + spawn_item = /obj/item/forging/complete/staff + +//"complete" pre-complete items +/obj/item/forging/complete/chain + name = "chain" + desc = "A singular chain, best used in combination with multiple chains." + icon_state = "chain" + +/obj/item/forging/complete/sword + name = "sword blade" + desc = "A sword blade, ready to get some wood for completion." + icon_state = "blade" + +/obj/item/forging/complete/staff + name = "staff head" + desc = "A staff head, ready to get some wood for completion." + icon_state = "staffhead" diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_recipes.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_recipes.dm new file mode 100644 index 00000000000..b5bf1197374 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_recipes.dm @@ -0,0 +1,44 @@ +/datum/crafting_recipe/chain_armor + name = "Chain Armor" + result = /obj/item/clothing/suit/armor/reagent_clothing + reqs = list(/obj/item/forging/complete/chain = 6) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/chain_glove + name = "Chain Gloves" + result = /obj/item/clothing/gloves/reagent_clothing + reqs = list(/obj/item/forging/complete/chain = 3) + time = 40 + category = CAT_CLOTHING + +/datum/crafting_recipe/reagent_sword + name = "Reagent Sword" + result = /obj/item/forging/reagent_weapon/sword + reqs = list(/obj/item/forging/complete/sword = 1, + /obj/item/stack/sheet/mineral/wood = 2) + time = 40 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + +/datum/crafting_recipe/reagent_staff + name = "Reagent Staff" + result = /obj/item/forging/reagent_weapon/staff + reqs = list(/obj/item/forging/complete/staff = 1, + /obj/item/stack/sheet/mineral/wood = 2) + time = 40 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + +//cargo supply pack for items +/datum/supply_pack/service/forging_items + name = "Forging Starter Item Pack" + desc = "Featuring: Forging. This pack is full of three items necessary to start your forging career: tongs, hammer, and billow." + cost = CARGO_CRATE_VALUE * 4 + contains = list(/obj/item/forging/tongs, /obj/item/forging/hammer, /obj/item/forging/billow) + crate_name = "forging start items" + crate_type = /obj/structure/closet/crate/forging_items + +/obj/structure/closet/crate/forging_items + name = "forging starter items" + desc = "A crate filled with the items necessary to start forging (billow, hammer, and tongs)." diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_weapons.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_weapons.dm new file mode 100644 index 00000000000..10e2d1caead --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/forge_weapons.dm @@ -0,0 +1,46 @@ +/obj/item/forging/reagent_weapon + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi' + var/list/imbued_reagent = list() + +/obj/item/forging/reagent_weapon/Initialize() + . = ..() + create_reagents(500, INJECTABLE | REFILLABLE) + +/obj/item/forging/reagent_weapon/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(!proximity_flag) + return + if(isliving(target) && imbued_reagent) + var/mob/living/livingMob = target + for(var/reagentList in imbued_reagent) + livingMob.reagents.add_reagent(reagentList, 3) + +/obj/item/forging/reagent_weapon/sword + name = "reagent sword" + desc = "A sword that can be imbued with a reagent." + force = 20 + icon_state = "sword" + inhand_icon_state = "sword" + lefthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi' + righthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi' + hitsound = 'sound/weapons/bladeslice.ogg' + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + resistance_flags = FIRE_PROOF + attack_verb_continuous = list("attacks", "slashes", "stabs", "slices", "tears", "lacerates", "rips", "dices", "cuts") + attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut") + sharpness = SHARP_EDGED + +/obj/item/forging/reagent_weapon/staff + name = "reagent staff" + desc = "A staff that can be imbued with a reagent." + force = 0 + icon_state = "staff" + inhand_icon_state = "staff" + lefthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi' + righthand_file = 'modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi' + throwforce = 0 + w_class = WEIGHT_CLASS_NORMAL + resistance_flags = FIRE_PROOF + attack_verb_continuous = list("bonks", "bashes", "whacks", "pokes", "prods") + attack_verb_simple = list("bonk", "bash", "whack", "poke", "prod") diff --git a/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/water_basin.dm b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/water_basin.dm new file mode 100644 index 00000000000..61c5c853405 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/code/modules/reagent_forging/water_basin.dm @@ -0,0 +1,30 @@ +/obj/structure/reagent_water_basin + name = "water basin" + desc = "A basin full of water, ready to quench the hot metal." + icon = 'modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi' + icon_state = "water_basin" + anchored = TRUE + density = TRUE + +/obj/structure/reagent_water_basin/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/forging/tongs)) + var/obj/item/forging/incomplete/searchIncomplete = locate(/obj/item/forging/incomplete) in I.contents + if(searchIncomplete?.times_hit < searchIncomplete.average_hits) + to_chat(user, span_warning("You cool down the metal-- it wasn't ready yet.")) + searchIncomplete.heat_world_compare = 0 + playsound(src, 'modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg', 50, TRUE) + return + if(searchIncomplete?.times_hit >= searchIncomplete.average_hits) + to_chat(user, span_notice("You cool down the metal-- it is ready.")) + playsound(src, 'modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg', 50, TRUE) + var/obj/item/forging/complete/spawnItem = searchIncomplete.spawn_item + new spawnItem(get_turf(src)) + qdel(searchIncomplete) + I.icon_state = "tong_empty" + return + if(I.tool_behaviour == TOOL_WRENCH) + for(var/i in 1 to 5) + new /obj/item/stack/sheet/mineral/wood(get_turf(src)) + qdel(src) + return + return ..() diff --git a/modular_skyrat/modules/reagent_forging/icons/mob/forge_clothing.dmi b/modular_skyrat/modules/reagent_forging/icons/mob/forge_clothing.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f6439b537562df9ba51c58de67be5c78acfd8647 GIT binary patch literal 1108 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGo4OJl#B`&GO$wiq3C7Jno3=9=> zN>6R%I%FWg_Q3MHi2Yl=sNMIJG$$>rW##;q!?9O2pd$wCg zyPom({3}uWesQOo!8+NUD!Z0cEw~cF+VgDYqP+f$>}_p#)`T5+adNNDx}XC){@i;y zxBO>$G|%LAdFEP1e_PFsdpC$3W?*3M_jGX#shIP2?%mQy1|lu(w$a@g3am>Q%^xr= zPzz?@-O(uGz`SDSo5N8u4<&M9J>}S+RV)7KD>)u6^vU#QZEdaNhaZRY4(wKDK5>G< z$f%)*M*)fX+5G9z+WYm)4aM&)>dsZ)XLPu1vfIeFdd>fyS-(tg=-%ym@%!Ix%W|H^ zKHm=c&-cnrn*_cvmN3ZOyLPGnw&B+up~V*kM9S}3mY1Bn+w^Yl`#HrO^W%$_EZbo6 zW9t|9w+xo7rq$)fgmZIBZo|!m_{ZAInBDgCmDlZ7&g;_vTH=hsC!i>G0L5 z{*}*_+y{`IFVwYDv?Z~gwy?2q3T#hEufElL(;&boW2KtS!l z58G*Oxt{+eufP5(u>D~5{56)ldFK8&aC3|P&BAT}cy2n+f7*Rxb7BH-#;?bUx%=<*h4&sokn|NH_2!wbFX+_$#z9$d*4U4Mv$!Qj2UD!=3N&yu;f9~JFfkU1;% z#UFtwuQq&Ter&6#eUh!^+_qfn%Kc_Je>;>W@3&+=Bxt@bUV2-d%fyrMk_qjT8Shos z)YRNj+w<}7tqornmz6B;wG{3?-_dFHVu_8Uq=OsVgo%tPDGb<|GoKV6YP?kX>AhDN z+Y!@G5C3Ew-SlDlkraoRtu{7C^!k2nRgpH}suPdhc0`B&&(?_N4f3p>*<$H?g~FKM ztvWPondQ{%OVxo|%&Q~>{9kCU)_(n4;@7p%3%Wm?d;ct{;A|7Umih8IU-1>q?Mb=1 zwW}Gk*H!s3@NHhd>v=;_WMrtlHFM8<|ARt4-WN1}E!(x=V~`1tGcYa!etDIiW-Z^U zC$#3{JQ?P&|1%rHkHkotn`&zQcsaxTal`Gn3vY#FC;GiB+w!f!=%lGbwZlve<`XGr z85hg16<{l=WssaJtOiV`K#}zao{k$ zN=*O%*-iX6+80cEdS6we()Pfr2;Lh}?c2*7bdJT$V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5skl79C`E~jGbOXA7^I1dGp#5wHx z03E<2@~n+%GXMYp?@2^KR9J=WmQ4y29IMgHEenfEBG#6md=FU10*49##2yS*5RDBhh>c7n zJyMVWQqb)mC|X!L#dryP{%zYgfU&}hLv!cP(TeUg9?qnT6gg-Q_-v(hd< P00000NkvXXu0mjfBVxZI literal 0 HcmV?d00001 diff --git a/modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi b/modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi new file mode 100644 index 0000000000000000000000000000000000000000..03178f2df8940e19a974990e57b6ea5c683c99f1 GIT binary patch literal 476 zcmV<20VDp2P)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a*U0*I5Sc+ z(=$pSoZ^zil2jm5skl79C`E~jGbOXA7^I1dGp#5wHx z03E<2@~n+%GXMYp@<~KNR9J=Wl}!$UFc3x&664a!1*j*0-~qbRYnXTdkHEr%D~W`b zPG-ImQ4;4{K>uDJkTA_M&0^WZgK2)oE$U1navclo=?<*lUdHzB3;?&z>pao~F9l%e#1&tT`}G58R+lG(cM}c! Sh%&qY0000V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWN;^NFm z%}mcIfpCgT5=&AQY!#G}GZHiN;?r~T%TkrNI8!oF1D+;)2DS9*0`!vhqa z1bPh*z{mC>$)U&g5ahuGY;fWson~h|8jKLyjgTF`IOp)6@!C6q-gpYoJAvMK3eY=& z-uU+dy!B3?2F&c^F%ccM_~h{L6~N4%h~5DVVpFnVJj8yfPYHJufSJ8q_lz0Hd=Sx> z*qm=XA8eHfO#+lihD3pj`d8(63sUmT{Bet4ifRE$B;`Ic57yd|nWy<%gow&I{bj!p z9fMlG%>oD!A!&@6k&MY7kH=}=S_?^_Rfr{0xnr>6wc&Zm3ka&XRlhPC&w#XXDUlcbAQDOE*Y{5puR zxYvt(5RtOiS`Pq5T$<3Bp8ePY7>Vd0y&^9A$U+*W#Fcdw$DrzrFWB$3eP%r%Lmq47 zWv!3~Af!bEFf)j#i9B$5oed;*AwLr!IH%;HwH}CQ)LH|;BtjY}>iUv+NrYx>seszp zS5JW)`H=hp0HO-GS{Eun#xoHDk?KDwN$lnd*d%}?4IoQCzMlpP>t^L0#T$v}u!Vex zy;}uLO)#^m7ZSPqxw$=XLnEx}0Yw2G1vRh5g$k%@whu1=&@KWRo-}_#0O0zI&k|aW v=ARK@FFgDwvAyvWpmzej@f4tU0=@AIKI3NhX^HeM00000NkvXXu0mjfn%q~$ literal 0 HcmV?d00001 diff --git a/modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi b/modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3971a07957d908db74623a67402f72a5a67ad3e6 GIT binary patch literal 1866 zcmV-Q2etT#P)V=-0C=2@&AkePFcgO2Ik}31?xlZgmZB5~y#+ZoCngY0Nlq)h`wmVWO0s<) zJn+_VYwz6vP2b5k#pJ>Y3a*Ev6r0m*LBZuLg(Wvz-cMp=0tFR^bslMX@~4tQyO==1 zNeUBjp?&{S^YT6`C+B_GvdrSLP|UNye` zWB#cc+M$7_@8lOLNt|n;n$a+MdYdSDi12D#(=41#hjK||Sf6WKs@bIwkJEN1; zR)2X1Opk}Hs};nlwyFtq7$7g@&vV{a9$yrnQzkx#n*hi*!Sr~Th(C>5ssULOc(E5S znM|bWkkQGs$EN~OTtR(wv{1Vuu-WCC_H+z0UL z`JxiEgJ`GT3h{v&HGnYqyXcts0B}C9 zmJ~1V%IgAM^?)kz0Z9X-27eB8OMC#hUMwq{05E^-K&AMAgaNvo_S4icfe9n179Xf+ z0H4I?$eIAqYXTkO0~HM5oA@6G8_``cfiCfZ5(D@qK06vFd%H^|CQxMro#F!p2JlUM zU~?##n}8ePda=Zd3;F-o^t=My;sZGb@KJn@Xo7S$cyY1XO_VJV8<;?=_&~-&kk8_8 zwL@4CI-l?0da>O4yJ(C&_I5YldG@5}h()$At4+(|q^=BF9<=dw71_I#qk{={}OGU==V(&F3N@>~`l=%@i)5I>CLBrU#c=^yA|4d9yiE{ZPFsSH5k z%hMSHkofiJgaJtW`n28vBz`lbioh@oH=mzO-aYt0WL5y*#23eZk}>{u?vWsMLP!{f zJG0qrxn+b+i&hOXWC9n&2Y~0ZSz>C-FB*St2w4+I8=&w5hD_j!_@*fv|2ig+s{yjo zzQ}m|SnB`Pz*q5s?6fa3t}*_tD+0wMYCegti&m}#lJM$iT?Qc3B5#1Ad8n*LAR1Ft z2b9$aS;!fH7hhR{4DSZ|2)_|#me59a0|6jpae}-%vy%AQDY`YT_Jtr$$l}baTuFR0 zgvcO1 zC|P`BrZ1HBUwZ}!f*^_GIEmxz14z1K^VhdGH?Y+Pm;0~P06`EW;=>$maeH%vi#KnK z#})hk&)c`g<8zAougw5y@v|OVY623!xc^!V;DY!;5G3i&n`%dv_+Jf&M#rFP|CJYk zu8D6tzH8!_^k4GiFd z_`qgA*GKWE$HT_vuXS3uE8^S274a|cfZP9o?|!QPC>rT?0AIy__iB;=z(-$ykFJOh z)R+RqBTBxA4*-u3#ytS|_m3X{bVGcgW)0Bq_j^8x&-v?j1_1c*_0Is>FFrsggj9wP z{x83-Oz`RaH!JZ~iVu(hDv=)i&%XV!^;O;7?*IS*07*qoM6N<$ Eg6}hQp#T5? literal 0 HcmV?d00001 diff --git a/modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi b/modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi new file mode 100644 index 0000000000000000000000000000000000000000..c1abe928c2f11eb4ec584f1fe30c187f9b225c6c GIT binary patch literal 1118 zcmV-k1flzhP)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo` zEh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KBS97q?%CnXkV<|%P; zreqcs14RwFIMa#}b5lWVW1whiPGTjHX`};$T%1Lz<(YXYU}bP)67$M3bK+BT3rZ@n z8-t-Xtu!ZxpwhJbqV!ZEjfJSiZLA5xBZfL)$fc~{>gNIuHUMBZTW@D=c%lFR0~<+1 zK~!jg?U?D7s~`}BgQDojpzr^*mqnJw#;rM%AD24GBw9*;w8W(5^J!{oYBFM|>iO3I z9U@lGzXs@g-lsBK4Eo6d?tShX?RM_p0RRLX0oaEQWiY>V{;dvBW_Z;>r(sMqpbY>s zj3eX?$_WpC5B&j@Mi^L+&G3E!)+Zf|1F=vaCD40o&5-r+0DCIW7r}rCy9DoM=sVa0 z4$k2s5W9}$=`&<@hkYb#nIBeRV955f*mW>NUt#wTGvvYNJUygL;1MtYWQGXY`P zAio9)0p5YvGi3fVoZU^(TM<&9JVO@hr^oOo0JIr0-Y1TK!;yR8G))FTzkvEDs^KT) zJO4T8QUvU))T@Rc0YZI40Qyo?4L@j}BH1*5p#$?A$>s#$?>YeV`Fk~h6yYo7o0^)M ziu%#|D!{TVKVODe?lPdis_Xb3;grDyt8pk7p!rMa!y&&1dK>Esb0GLJJqHFuF=XeP zQ%7_9h?OAtFux}ZfIy56-p*n~3Xpu5+!u5~=u<}_r5gchGTjIHeTT?hDa{ba#Z2`x z2DfP#f@P>>km)BZK=d;N#29Sm0r8-_?p`^4A9efn# z%d+oO%I|IfDRTe;eWhmo(1XvNQkXxN{T-l?-|aO#G$36?c0&)Z$JT?J=QBS5l+tUw zkD09c{-9F7iF<*8n)p?>F;30U+deh35AwzXE}{ kmG8G5Ky8J5-}GGn0G_8{mTGvpI{*Lx07*qoM6N<$f_=6S!vFvP literal 0 HcmV?d00001 diff --git a/modular_skyrat/modules/reagent_forging/readme.md b/modular_skyrat/modules/reagent_forging/readme.md new file mode 100644 index 00000000000..1833dd50082 --- /dev/null +++ b/modular_skyrat/modules/reagent_forging/readme.md @@ -0,0 +1,28 @@ +## Title: Reagent Forging + +MODULE ID: REAGENT_FORGING + +### Description: + +Reagent forging is a form of forging where users are able to create various items that have the ability to become imbued with reagents. Items that have been imbued have the ability to permanently inject +imbued reagents into the targets. + +### TG Proc Changes: + +- N/A + +### Defines: + +- N/A + +### Master file additions + +- N/A + +### Included files that are not contained in this module: + +- N/A + +### Credits: + +Jake Park diff --git a/modular_skyrat/modules/reagent_forging/sound/forge.ogg b/modular_skyrat/modules/reagent_forging/sound/forge.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8ade5b6485d0c0bb6d3353b3c9c23eee9159bdf2 GIT binary patch literal 16811 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 a@bXLnAS9Eq)O;KR2KISbP5|ig!T$pA%>g(7 literal 0 HcmV?d00001 diff --git a/modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg b/modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg new file mode 100644 index 0000000000000000000000000000000000000000..36f312b210f0c999a34bccc7570362d12fe239b0 GIT binary patch literal 15870 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