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 00000000000..f6439b53756 Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/icons/mob/forge_clothing.dmi differ diff --git a/modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi b/modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi new file mode 100644 index 00000000000..d8e368d5f5b Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_l.dmi differ 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 00000000000..03178f2df89 Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/icons/mob/forge_weapon_r.dmi differ diff --git a/modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi b/modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi new file mode 100644 index 00000000000..ae3cc0a5c3c Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/icons/obj/forge_clothing.dmi differ 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 00000000000..3971a07957d Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/icons/obj/forge_items.dmi differ 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 00000000000..c1abe928c2f Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/icons/obj/forge_structures.dmi differ 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 00000000000..8ade5b6485d Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/sound/forge.ogg differ 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 00000000000..36f312b210f Binary files /dev/null and b/modular_skyrat/modules/reagent_forging/sound/hot_hiss.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 373c82c11cb..07e6b443468 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4374,6 +4374,13 @@ #include "modular_skyrat\modules\QOL\code\_under.dm" #include "modular_skyrat\modules\radiosound\code\game\objects\items\devices\radio\headset.dm" #include "modular_skyrat\modules\random_mining\code\mining_maps.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\anvil.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\forge.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\forge_clothing.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\forge_items.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\forge_recipes.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\forge_weapons.dm" +#include "modular_skyrat\modules\reagent_forging\code\modules\reagent_forging\water_basin.dm" #include "modular_skyrat\modules\roboclothes\code\clothing\robotics_clothing.dm" #include "modular_skyrat\modules\roboclothes\code\vending\wardrobes.dm" #include "modular_skyrat\modules\rod-stopper\code\immovable_skyrat.dm"