diff --git a/icons/obj/items/billet.dmi b/icons/obj/items/billet.dmi new file mode 100644 index 00000000000..1b841d667a0 Binary files /dev/null and b/icons/obj/items/billet.dmi differ diff --git a/icons/obj/items/tongs.dmi b/icons/obj/items/tongs.dmi new file mode 100644 index 00000000000..72764d913b3 Binary files /dev/null and b/icons/obj/items/tongs.dmi differ diff --git a/icons/obj/structures/anvil.dmi b/icons/obj/structures/anvil.dmi new file mode 100644 index 00000000000..403390e3251 Binary files /dev/null and b/icons/obj/structures/anvil.dmi differ diff --git a/icons/obj/structures/anvil_crude.dmi b/icons/obj/structures/anvil_crude.dmi new file mode 100644 index 00000000000..1f43be3ed0f Binary files /dev/null and b/icons/obj/structures/anvil_crude.dmi differ diff --git a/icons/obj/structures/anvil_crude_alt.dmi b/icons/obj/structures/anvil_crude_alt.dmi new file mode 100644 index 00000000000..d3876c4f37f Binary files /dev/null and b/icons/obj/structures/anvil_crude_alt.dmi differ diff --git a/icons/obj/structures/anvil_improvised.dmi b/icons/obj/structures/anvil_improvised.dmi new file mode 100644 index 00000000000..a80b2d7a06b Binary files /dev/null and b/icons/obj/structures/anvil_improvised.dmi differ diff --git a/icons/obj/structures/forging/forge.dmi b/icons/obj/structures/forging/forge.dmi new file mode 100644 index 00000000000..452def1aa58 Binary files /dev/null and b/icons/obj/structures/forging/forge.dmi differ diff --git a/maps/modpack_testing/modpack_testing.dm b/maps/modpack_testing/modpack_testing.dm index 33b776920fb..6042deec053 100644 --- a/maps/modpack_testing/modpack_testing.dm +++ b/maps/modpack_testing/modpack_testing.dm @@ -24,6 +24,7 @@ #include "../../mods/content/shackles/_shackles.dme" #include "../../mods/content/supermatter/_supermatter.dme" #include "../../mods/content/xenobiology/_xenobiology.dme" + #include "../../mods/content/blacksmithy/_blacksmithy.dme" #include "../../mods/content/item_sharpening/_item_sharpening.dme" #include "../../mods/gamemodes/cult/_cult.dme" diff --git a/maps/shaded_hills/shaded_hills-inn.dmm b/maps/shaded_hills/shaded_hills-inn.dmm index 7dc097ab79b..0213b0de86c 100644 --- a/maps/shaded_hills/shaded_hills-inn.dmm +++ b/maps/shaded_hills/shaded_hills-inn.dmm @@ -148,6 +148,10 @@ /obj/structure/cask_rack/large/mapped, /turf/floor/path/herringbone/basalt, /area/shaded_hills/inn/kitchen) +"fM" = ( +/obj/structure/working/bellows, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "fR" = ( /turf/floor/wood/rough/walnut, /area/shaded_hills/storehouse) @@ -214,6 +218,10 @@ }, /turf/floor/wood/rough/walnut, /area/shaded_hills/farmhouse) +"gJ" = ( +/mob/living/simple_animal/passive/horse/small, +/turf/floor/straw, +/area/shaded_hills/stable) "gL" = ( /obj/structure/reagent_dispensers/barrel/ebony/oil, /turf/floor/path/herringbone/basalt, @@ -232,6 +240,10 @@ "gU" = ( /turf/wall/brick/basalt, /area/shaded_hills/inn/kitchen) +"gW" = ( +/obj/structure/closet/crate/chest/ebony, +/turf/floor/wood/rough/walnut, +/area/shaded_hills/stable) "hb" = ( /obj/structure/wall_sconce/lantern{ dir = 4; @@ -446,6 +458,10 @@ /obj/item/shears, /turf/floor/wood/rough/walnut, /area/shaded_hills/farmhouse) +"mD" = ( +/obj/structure/bed/chair/rustic, +/turf/floor/wood/rough/walnut, +/area/shaded_hills/stable) "mG" = ( /obj/structure/railing/mapped/wooden/walnut{ dir = 4 @@ -677,6 +693,10 @@ /obj/abstract/landmark/organize/horizontal, /turf/floor/path/herringbone/basalt, /area/shaded_hills/inn/kitchen) +"tH" = ( +/obj/structure/reagent_dispensers/barrel/ebony/wine, +/turf/floor/wood/rough/walnut, +/area/shaded_hills/stable) "tS" = ( /obj/structure/railing/mapped/wooden/walnut{ dir = 8 @@ -771,6 +791,21 @@ /obj/structure/closet/crate/chest/ebony, /turf/floor/path/basalt, /area/shaded_hills/general_store) +"wp" = ( +/obj/structure/wall_sconce/lantern{ + dir = 4 + }, +/obj/structure/bed/chair/rustic{ + dir = 1 + }, +/turf/floor/wood/rough/walnut, +/area/shaded_hills/stable) +"xa" = ( +/obj/item/stack/material/bar/mapped/iron/thirty, +/obj/structure/table/wood/reinforced/ebony, +/obj/item/tongs, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "xh" = ( /obj/structure/table/wood/ebony, /obj/item/chems/condiment/large/salt, @@ -785,6 +820,10 @@ "xH" = ( /turf/wall/brick/basalt, /area/shaded_hills/slaughterhouse) +"xI" = ( +/obj/structure/fire_source/forge, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "xJ" = ( /obj/structure/table/desk/dresser/ebony, /turf/floor/carpet/rustic, @@ -893,6 +932,9 @@ /obj/structure/wall_sconce/lantern, /turf/floor/wood/rough/walnut, /area/shaded_hills/shrine/kitchen) +"At" = ( +/turf/wall/log/walnut/shutter/open, +/area/shaded_hills/stable) "Aw" = ( /obj/structure/railing/mapped/wooden/walnut{ dir = 4 @@ -922,6 +964,10 @@ /obj/item/bag/sack, /turf/floor/wood/rough/walnut, /area/shaded_hills/farmhouse) +"AS" = ( +/mob/living/simple_animal/passive/horse, +/turf/floor/straw, +/area/shaded_hills/stable) "AW" = ( /obj/structure/railing/mapped/wooden/walnut, /obj/structure/flora/bush/brflowers, @@ -1186,6 +1232,10 @@ /obj/item/chems/glass/handmade/jar, /turf/floor/path/herringbone/basalt, /area/shaded_hills/shrine/kitchen) +"HM" = ( +/obj/structure/reagent_dispensers/barrel/ebony/water, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "HP" = ( /obj/structure/table/end/alt, /obj/item/flame/candle/handmade{ @@ -1283,6 +1333,12 @@ /obj/structure/wall_sconce/lantern, /turf/floor/path/herringbone/basalt, /area/shaded_hills/shrine) +"JS" = ( +/obj/structure/bed/chair/rustic{ + dir = 1 + }, +/turf/floor/wood/rough/walnut, +/area/shaded_hills/stable) "JU" = ( /obj/structure/railing/mapped/wooden/walnut, /turf/floor/wood/rough/walnut, @@ -1326,6 +1382,13 @@ }, /turf/floor/path/herringbone/basalt, /area/shaded_hills/inn) +"LA" = ( +/obj/structure/closet/crate/chest/ebony, +/obj/item/stack/material/brick/mapped/graphite/forty, +/obj/item/rock/flint/striker, +/obj/item/bladed/knife/iron, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "LH" = ( /obj/structure/table/wood/ebony, /obj/item/chems/glass/bucket/wood, @@ -1419,6 +1482,10 @@ "Pa" = ( /turf/floor/path/running_bond/basalt, /area/shaded_hills/outside/downlands/poi) +"Pb" = ( +/obj/structure/closet/cabinet/wooden/ebony, +/turf/floor/wood/rough/walnut, +/area/shaded_hills/stable) "Pd" = ( /turf/floor/carpet/rustic, /area/shaded_hills/farmhouse) @@ -1450,6 +1517,10 @@ /obj/structure/reagent_dispensers/barrel/ebony/oil, /turf/floor/wood/rough/walnut, /area/shaded_hills/storehouse) +"Qa" = ( +/obj/structure/reagent_dispensers/barrel/ebony/oil, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "Qb" = ( /turf/floor/carpet, /area/shaded_hills/inn) @@ -1502,6 +1573,11 @@ /obj/abstract/landmark/start/shaded_hills/innkeeper, /turf/floor/wood/walnut, /area/shaded_hills/inn) +"Rk" = ( +/obj/structure/anvil, +/obj/item/tool/hammer/forge/iron, +/turf/floor/path/basalt, +/area/shaded_hills/stable) "Rl" = ( /turf/floor/mud, /area/shaded_hills/outside/downlands) @@ -1818,6 +1894,10 @@ /obj/machinery/portable_atmospherics/hydroponics/soil, /turf/floor/mud, /area/shaded_hills/outside/shrine) +"ZC" = ( +/obj/structure/table/wood/ebony, +/turf/floor/wood/walnut, +/area/shaded_hills/stable) "ZD" = ( /obj/abstract/landmark/start/shaded_hills/bartender, /turf/floor/path/herringbone/basalt, @@ -13138,7 +13218,7 @@ nn nn nn nn -nn +At nn nn nn @@ -13287,19 +13367,19 @@ TR nn jA HP -js +Pb nn -js -js -js +mD +ZC +JS js nn +LA Ak Ak Ak Ak -Ak -Ak +HM nn TR TR @@ -13448,10 +13528,10 @@ js kE Ak Ak +fM Ak Ak -Ak -Ak +Qa nn aU TR @@ -13590,20 +13670,20 @@ TR TR nn bu -jf +wp js nn js jf -js -js +tH +gW nn Ak Ak +xI Ak Ak -Ak -Ak +xa HE KG EV @@ -13752,7 +13832,7 @@ nn nn Ak Ak -Ak +Rk Ak Ak Ak @@ -14198,19 +14278,19 @@ HI TR nn Wk -PA +Wk Wk nn Wk -PA +Wk Wk nn Wk -PA +Wk Wk nn Wk -PA +Wk Wk nn aU @@ -14350,7 +14430,7 @@ HI TR nn PA -PA +AS PA nn PA @@ -14358,7 +14438,7 @@ PA PA nn PA -PA +gJ PA nn PA diff --git a/maps/shaded_hills/shaded_hills-woods.dmm b/maps/shaded_hills/shaded_hills-woods.dmm index 06a9695d634..854c4bb10df 100644 --- a/maps/shaded_hills/shaded_hills-woods.dmm +++ b/maps/shaded_hills/shaded_hills-woods.dmm @@ -8,7 +8,7 @@ /turf/floor/path/running_bond/basalt, /area/shaded_hills/outside/woods) "cN" = ( -/obj/item/bladed/knife, +/obj/item/bladed/knife/iron, /turf/floor/wood/rough/walnut, /area/shaded_hills/forester_hut) "dp" = ( diff --git a/maps/shaded_hills/shaded_hills.dm b/maps/shaded_hills/shaded_hills.dm index ae5cb32e946..0d7f2b5f770 100644 --- a/maps/shaded_hills/shaded_hills.dm +++ b/maps/shaded_hills/shaded_hills.dm @@ -7,6 +7,7 @@ #include "../../mods/species/drakes/_drakes.dme" // include before _fantasy.dme so overrides work #include "../../mods/content/item_sharpening/_item_sharpening.dme" #include "../../mods/content/fantasy/_fantasy.dme" + #include "../../mods/content/blacksmithy/_blacksmithy.dme" #include "areas/_areas.dm" #include "areas/downlands.dm" diff --git a/mods/content/blacksmithy/_blacksmithy.dm b/mods/content/blacksmithy/_blacksmithy.dm new file mode 100644 index 00000000000..978dbebe0d6 --- /dev/null +++ b/mods/content/blacksmithy/_blacksmithy.dm @@ -0,0 +1,3 @@ +/decl/modpack/blacksmithy + name = "Blacksmithy" + diff --git a/mods/content/blacksmithy/_blacksmithy.dme b/mods/content/blacksmithy/_blacksmithy.dme new file mode 100644 index 00000000000..3421d65d10f --- /dev/null +++ b/mods/content/blacksmithy/_blacksmithy.dme @@ -0,0 +1,19 @@ +#ifndef MODPACK_BLACKSMITHY +#define MODPACK_BLACKSMITHY +// BEGIN_INCLUDE +#include "_blacksmithy.dm" +#include "anvil.dm" +#include "billet.dm" +#include "boulder.dm" +#include "forge_fire.dm" +#include "forging_step.dm" +#include "forging_step_armor.dm" +#include "forging_step_billets.dm" +#include "forging_step_blades.dm" +#include "forging_step_components.dm" +#include "forging_step_ornate.dm" +#include "forging_step_tools.dm" +#include "forging_types.dm" +#include "tongs.dm" +// END_INCLUDE +#endif diff --git a/mods/content/blacksmithy/anvil.dm b/mods/content/blacksmithy/anvil.dm new file mode 100644 index 00000000000..367e706c8ed --- /dev/null +++ b/mods/content/blacksmithy/anvil.dm @@ -0,0 +1,134 @@ +// Cut up from https://freesound.org/people/MrAuralization/sounds/274846/ (Avil, MrAuralization) (CC-BY-4) +/datum/composite_sound/anvil_strike + mid_sounds = list( + 'sound/effects/anvil1.ogg', + 'sound/effects/anvil2.ogg', + 'sound/effects/anvil3.ogg', + 'sound/effects/anvil4.ogg', + 'sound/effects/anvil5.ogg', + ) + mid_length = 1.5 SECONDS + var/mob/user + +/datum/composite_sound/anvil_strike/Destroy() + user = null + return ..() + +// This is a bit evil, but it should be cleaner than trying to run a second timing loop for the hammer strikes. +/datum/composite_sound/anvil_strike/play(soundfile) + . = ..() + for(var/obj/structure/anvil/anvil in output_atoms) + if(user) + user.do_attack_animation(anvil, user.get_active_held_item()) + anvil.shake_animation() + for(var/obj/item/thing in anvil.loc?.get_contained_external_atoms()) + thing.shake_animation() + spark_at(get_turf(anvil), amount = 1, spark_type = /datum/effect/effect/system/spark_spread/silent) + +/obj/structure/anvil + name = "anvil" + desc = "A heavy block of material used as support for hammering things into shape." + icon = 'icons/obj/structures/anvil.dmi' + icon_state = ICON_STATE_WORLD + anchored = TRUE + density = TRUE + opacity = FALSE + atom_flags = ATOM_FLAG_CLIMBABLE + w_class = ITEM_SIZE_STRUCTURE //_LARGE + material = /decl/material/solid/metal/iron + max_health = 1000 + structure_flags = STRUCTURE_FLAG_SURFACE + material_alteration = MAT_FLAG_ALTERATION_ALL + hitsound = 'sound/effects/anvil1.ogg' + var/datum/composite_sound/anvil_strike/clang + +/obj/structure/anvil/Initialize() + . = ..() + clang = new(list(src), FALSE) + +/obj/structure/anvil/Destroy() + QDEL_NULL(clang) + return ..() + +/obj/structure/anvil/proc/start_working(mob/user) + if(clang) + clang.user = user + if(!clang.started) + clang.start() + +/obj/structure/anvil/proc/stop_working() + if(clang) + clang.user = null + if(clang.started) + clang.stop() + +/obj/structure/anvil/on_update_icon() + . = ..() + icon_state = initial(icon_state) + switch(get_health_percent()) + if(0 to 0.35) + icon_state = "[icon_state]-damage-heavy" + if(0.35 to 0.65) + icon_state = "[icon_state]-damage-light" + +/obj/structure/anvil/attackby(obj/item/used_item, mob/user, click_params) + + // Put the bar from tongs onto the anvil. + if(istype(used_item, /obj/item/tongs)) + var/obj/item/tongs/tongs = used_item + if(tongs.holding_bar) + used_item = tongs.holding_bar + tongs.holding_bar.dropInto(loc) + // Flow through into procs below. + + // Put the bar onto the anvil (need to do this to avoid repairs in ..()) + if(istype(used_item, /obj/item/stack/material/bar)) + var/obj/item/stack/material/bar/bar = used_item + if(used_item.material != material || current_health >= get_max_health()) + if(bar.get_amount() > 1) + bar = bar.split(1) + if(bar.loc == user) + if(!user.try_unequip(bar, get_turf(src))) + return TRUE + else + bar.dropInto(get_turf(src)) + qdel(bar) + used_item = new /obj/item/billet(loc, used_item.material?.type) + // Flow through to billet placement below. + + // Place things onto the anvil. + if(!user.check_intent(I_FLAG_HARM) && (istype(used_item, /obj/item/tool/hammer/forge) || istype(used_item, /obj/item/tongs) || istype(used_item, /obj/item/billet))) + if(used_item.loc == user) + if(!user.try_unequip(used_item, get_turf(src))) + return TRUE + else + used_item.dropInto(get_turf(src)) + auto_align(used_item, click_params) + return TRUE + + . = ..() + +// Chipped out of a boulder with a pick. +/obj/structure/anvil/boulder + name_prefix = "crude" + icon = 'icons/obj/structures/anvil_crude.dmi' + desc = "A crude anvil chipped out of a chunk of stone. It probably won't last very long." + material = /decl/material/solid/stone/granite + max_health = 500 + +/obj/structure/anvil/boulder/Initialize(ml, _mat, _reinf_mat) + . = ..() + if(prob(50)) + set_icon('icons/obj/structures/anvil_crude_alt.dmi') + +// Improvised with spaceman materials. +/obj/structure/anvil/improvised + name_prefix = "improvised" + icon = 'icons/obj/structures/anvil_improvised.dmi' + desc = "A anvil roughly improvised out of scrap metal. It probably won't last very long." + material = /decl/material/solid/metal/steel + max_health = 500 + +/decl/stack_recipe/steel/furniture + result_type = /obj/structure/anvil/improvised + difficulty = MAT_VALUE_HARD_DIY diff --git a/mods/content/blacksmithy/billet.dm b/mods/content/blacksmithy/billet.dm new file mode 100644 index 00000000000..95cfbb6bcb1 --- /dev/null +++ b/mods/content/blacksmithy/billet.dm @@ -0,0 +1,208 @@ +// Turning billets back into bars. +/obj/item/stack/material/bar/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/billet) && used_item.material == material && !reinf_material) + var/obj/item/billet/billet = used_item + if(billet.current_forging_step && billet.current_forging_step.type != /decl/forging_step/billet) + to_chat(user, SPAN_WARNING("\The [used_item] will need to be melted down and recast before you can reuse it as a bar.")) + return TRUE + if(!user.try_unequip(used_item, loc)) + return TRUE + if(get_amount() >= get_max_amount()) + return TRUE + add(1) + qdel(used_item) + return TRUE + . = ..() + +/obj/item/proc/hot_enough_to_forge(melting_point_percent = 0.25) + if(!istype(material) || isnull(material.melting_point) || !material.forgable) + return FALSE + // Defaults to >25% of the way to melting to be considered 'forgable' + return temperature >= ((material.melting_point - T20C) * melting_point_percent) + T20C + +/obj/item/billet + name = "billet" + desc = "An unworked or partially-worked length of metal used to forge items and tools." + icon = 'icons/obj/items/billet.dmi' + icon_state = ICON_STATE_WORLD + material = /decl/material/solid/metal/iron + material_alteration = MAT_FLAG_ALTERATION_ALL + var/decl/forging_step/current_forging_step = /decl/forging_step/billet + +/obj/item/billet/Initialize(ml, material_key) + if(ispath(current_forging_step)) + set_forging_step(current_forging_step, force = TRUE) + . = ..() + +/obj/item/billet/proc/set_forging_step(decl/forging_step/new_step, force) + if(ispath(new_step)) + new_step = GET_DECL(new_step) + if(!istype(new_step) || (!force && current_forging_step == new_step)) + return FALSE + current_forging_step = new_step + . = current_forging_step.apply_to(src) + if(!QDELETED(src)) + update_name() + update_icon() + update_heat_glow(anim_time = 0) // reset heat color to avoid weird visual jitter + +/obj/item/billet/attackby(obj/item/used_item, mob/user) + + // Merging billets back into bars. + if(istype(used_item, /obj/item/billet) && material == used_item.material) + if(current_forging_step && current_forging_step.type != /decl/forging_step/billet) + to_chat(user, SPAN_WARNING("\The [src] will need to be melted down and recast before you can reuse it as a bar.")) + return TRUE + var/obj/item/billet/billet = used_item + if(billet.current_forging_step && billet.current_forging_step.type != /decl/forging_step/billet) + to_chat(user, SPAN_WARNING("\The [billet] will need to be melted down and recast before you can reuse it as a bar.")) + return TRUE + if(user.try_unequip(used_item, loc)) + var/obj/item/stack/material/bar/bars = new(loc, 2, material.type) + bars.dropInto(loc) + qdel(used_item) + qdel(src) + return TRUE + + // Picking up in tongs. + if(istype(used_item, /obj/item/tongs)) + var/obj/item/tongs/tongs = used_item + if(tongs.holding_bar) + return ..() + var/mob/holder = loc + if(istype(holder)) + if(!holder.try_unequip(src, tongs)) + return TRUE + else if(loc?.storage) + if(!loc.storage.remove_from_storage(user, src, tongs)) + return TRUE + else + forceMove(tongs) + if(loc == tongs) + tongs.holding_bar = src + tongs.update_icon() + return TRUE + + if(!istype(used_item, /obj/item/tool/hammer/forge) || user.check_intent(I_FLAG_HARM)) + return ..() + + // Check for surface. + var/obj/structure/anvil/anvil = locate() in loc + if(!istype(anvil)) + to_chat(user, SPAN_WARNING("\The [src] can only be worked on an anvil.")) + return TRUE + + // Check for heat. + if(!hot_enough_to_forge()) + to_chat(user, SPAN_WARNING("\The [src] is too cold to be worked on the anvil.")) + return TRUE + + // Sanity check. + if(!length(current_forging_step?.steps)) // how tho + to_chat(user, SPAN_WARNING("You cannot see any further way to refine \the [src].")) + return TRUE + + // Handle the actual forging process. + var/last_step = current_forging_step + var/decl/forging_step/next_step = show_radial_menu(user, src, current_forging_step.get_radial_choices(), radius = 42, use_labels = RADIAL_LABELS_CENTERED, require_near = TRUE, check_locs = list(src)) + + if(!standard_forging_checks(user, used_item, last_step, next_step, anvil)) + return TRUE + + if(user.get_stamina() < 10) + to_chat(user, SPAN_WARNING("You are too exhausted to swing \the [used_item].")) + return TRUE + + user.adjust_stamina(-10) + anvil.start_working(user) + + // Skill checks! + if(!user.do_skilled(3 SECONDS, next_step.work_skill, anvil)) + anvil?.stop_working() + return TRUE + + if(!istype(next_step) || (next_step.skill_fail_prob && user.skill_fail_prob(next_step.work_skill, next_step.skill_fail_prob, next_step.skill_level, next_step.skill_factor))) + to_chat(user, SPAN_WARNING("You fumble the work and fail to reshape \the [src].")) + anvil?.stop_working() + return TRUE + + // Since we have a sleep() above, we recheck our basic conditions. + if(!standard_forging_checks(user, used_item, last_step, next_step, anvil)) + anvil?.stop_working() + return TRUE + + if(user.get_stamina() < 10) + to_chat(user, SPAN_WARNING("You are too exhausted to keep swinging \the [used_item].")) + anvil?.stop_working() + return TRUE + + user.adjust_stamina(-10) + + // Update the billet (which may produce an item!) + var/obj/item/forged_thing = set_forging_step(next_step) + if(istype(forged_thing)) + user.visible_message(SPAN_NOTICE("\The [user] has [next_step.work_verb] the billet into \a [forged_thing].")) + // Forging gradually degrades anvils. + if(!QDELETED(anvil)) + anvil.stop_working() + anvil.take_damage(rand(10, 20), BRUTE, silent = TRUE) // We are already going CLANG CLANG CLANG, don't need a THUNK + return TRUE + +/obj/item/billet/examine(mob/user, distance, infix, suffix) + . = ..() + for(var/decl/forging_step/next_step in current_forging_step?.steps) + if(user.skill_check(next_step.work_skill, next_step.skill_level)) + to_chat(user, SPAN_INFO("It can be [next_step.work_verb] into \a [next_step.get_product_name(material)] on an anvil.")) + +/obj/item/billet/proc/standard_forging_checks(mob/user, obj/item/used_item, decl/forging_step/last_step, decl/forging_step/next_step, obj/structure/anvil/anvil) + // We cancelled or changed state, abort. + if(!next_step || current_forging_step != last_step || !(next_step in current_forging_step.steps)) + return FALSE + // Something has been destroyed since we started forging. + if(QDELETED(src) || QDELETED(used_item) || QDELETED(anvil) || QDELETED(user)) + return FALSE + // Something else has changed, very unfortunate. + if(loc != anvil.loc || !CanPhysicallyInteract(user) || user.get_active_held_item() != used_item) + return FALSE + return hot_enough_to_forge() + +/obj/item/billet/on_update_icon() + . = ..() + if(!istype(current_forging_step)) + return + if(current_forging_step.billet_icon) + set_icon(current_forging_step.billet_icon) + else + set_icon(initial(icon)) + icon_state = get_world_inventory_state() + if(current_forging_step.billet_icon_state) + icon_state = "[icon_state]-[current_forging_step.billet_icon_state]" + +/obj/item/billet/get_world_inventory_state() + if(!current_forging_step?.billet_icon_state) + return ..() + if(!check_state_in_icon("[ICON_STATE_INV]-[current_forging_step.billet_icon_state]", icon)) + return ICON_STATE_WORLD + return ..() + +/obj/item/billet/update_name() + if(!istype(current_forging_step)) + base_name = initial(base_name) + name_prefix = initial(name_prefix) + desc = initial(desc) + return ..() + base_name = current_forging_step.billet_name + name_prefix = current_forging_step.billet_name_prefix + . = ..() + desc = current_forging_step.billet_desc + if(istype(material)) + desc = "[desc] This one is made of [material.solid_name]." + +/obj/item/billet/ProcessAtomTemperature() + . = ..() + update_heat_glow() + +// Arbitrary value to give people enough time to forge the bloody thing. +/obj/item/billet/get_thermal_mass_coefficient(delta) + // Only delay cooling if we're over our forging point. + return delta < 0 && hot_enough_to_forge() ? 0.01 : ..() diff --git a/mods/content/blacksmithy/boulder.dm b/mods/content/blacksmithy/boulder.dm new file mode 100644 index 00000000000..6da6419a7ef --- /dev/null +++ b/mods/content/blacksmithy/boulder.dm @@ -0,0 +1,24 @@ + +/obj/structure/boulder/get_alt_interactions(mob/user) + . = ..() + LAZYADD(., /decl/interaction_handler/chip_anvil) + +/decl/interaction_handler/chip_anvil + name = "Chip Into Anvil" + expected_target_type = /obj/structure/boulder + var/work_skill = SKILL_CONSTRUCTION + +/decl/interaction_handler/chip_anvil/is_possible(atom/target, mob/user, obj/item/prop) + . = ..() && istype(prop) && IS_PICK(prop) && prop.material?.hardness >= target.get_material()?.hardness && user.skill_check(work_skill, SKILL_BASIC) + +/decl/interaction_handler/chip_anvil/invoked(atom/target, mob/user, obj/item/prop) + user.visible_message(SPAN_NOTICE("\The [user] begins chipping \the [target] into a rough anvil using \the [prop].")) + if(!user.do_skilled(10 SECONDS, work_skill, target)) + return FALSE + if(QDELETED(user) || QDELETED(target) || QDELETED(prop) || user.get_active_held_item() != prop || !CanPhysicallyInteractWith(user, target)) + return FALSE + if(!is_possible(target, user, prop)) + return FALSE + user.visible_message(SPAN_NOTICE("\The [user] chips \the [target] into a rough anvil using \the [prop].")) + new /obj/structure/anvil/boulder(get_turf(target), target.get_material()?.type) + return TRUE diff --git a/mods/content/blacksmithy/forge_fire.dm b/mods/content/blacksmithy/forge_fire.dm new file mode 100644 index 00000000000..a6b8b365ccc --- /dev/null +++ b/mods/content/blacksmithy/forge_fire.dm @@ -0,0 +1,82 @@ +/datum/storage/forge + can_hold = list( + /obj/item/stack/material/bar, + /obj/item/billet + ) + max_storage_space = ITEM_SIZE_NORMAL * 10 // Fairly spacious + max_w_class = ITEM_SIZE_LARGE + +/datum/storage/forge/consolidate_stacks() + return // We want to keep them as single bars. + +/obj/structure/fire_source/forge + name = "forge fire" + desc = "A sturdy hearth used to heat metal bars for forging on an anvil." + density = TRUE + icon = 'icons/obj/structures/forging/forge.dmi' + icon_state = "forge" + storage = /datum/storage/forge + +/obj/structure/fire_source/forge/proc/get_forgable_contents() + . = list() + for(var/obj/item/thing in get_stored_inventory()) + if(thing.material?.forgable && (istype(thing, /obj/item/billet) || istype(thing, /obj/item/stack/material/bar))) + . += thing + +/obj/structure/fire_source/forge/attackby(obj/item/used_item, mob/user) + + // Raw materials. + if(istype(used_item, /obj/item/stack/material/bar)) + var/obj/item/stack/material/bar/bar = used_item + if(used_item.material != material || current_health >= get_max_health()) + if(bar.get_amount() > 1) + bar = bar.split(1) + if(bar.loc == user) + if(!user.try_unequip(bar, get_turf(src))) + return TRUE + else + bar.dropInto(get_turf(src)) + qdel(bar) + used_item = new /obj/item/billet(loc, used_item.material?.type) + // Flows through to below. + + // Partially worked billets. + if(istype(used_item, /obj/item/billet)) + if(used_item.loc == user) + user.try_unequip(used_item, loc) + else + used_item.dropInto(loc) + if(storage.can_be_inserted(used_item, user)) + storage.handle_item_insertion(user, used_item) + update_icon() + return TRUE + + // Tongs holding bars or partially worked billets. + if(istype(used_item, /obj/item/tongs) && !user.check_intent(I_FLAG_HARM)) + + // Put whatever's in the tongs into storage. + var/obj/item/tongs/tongs = used_item + if(tongs.holding_bar) + return attackby(tongs.holding_bar, user) + + // Check if we have any bars. + var/list/bars = get_forgable_contents() + if(!length(bars)) + to_chat(user, SPAN_WARNING("There are no bars in \the [src] to retrieve.")) + return TRUE + + // Get the hottest bar. + var/obj/item/hottest_bar + for(var/obj/item/bar in bars) + if(!hottest_bar || bar.temperature > hottest_bar) + hottest_bar = bar + + // Extract a single bar from the forge with the tongs. + if(storage.remove_from_storage(user, hottest_bar, tongs)) + tongs.holding_bar = hottest_bar + if(tongs.holding_bar) + user.visible_message(SPAN_NOTICE("\The [user] pulls \the [tongs.holding_bar] from \the [src] with \the [tongs].")) + tongs.update_icon() + return TRUE + + return ..() diff --git a/mods/content/blacksmithy/forging_step.dm b/mods/content/blacksmithy/forging_step.dm new file mode 100644 index 00000000000..e443555b3f3 --- /dev/null +++ b/mods/content/blacksmithy/forging_step.dm @@ -0,0 +1,100 @@ +/decl/forging_step + abstract_type = /decl/forging_step + /// Base name, generated from billet_name and billet_name_prefix. + var/name + /// Name to use for the actual billet item. + var/billet_name = "billet" + /// Name prefix to use for the billet at this stage. + var/billet_name_prefix + /// Description to use for the billet at this stage. + var/billet_desc + /// Icon state modifier to use for the billet at this stage. + var/billet_icon_state + /// Icon to use for the billet (for modpacks/downstreams) + var/billet_icon = 'icons/obj/items/billet.dmi' + /// List of available /decl/forging_step instances. + var/list/steps + /// Probability of failing this step if we're below skill_level. + var/skill_fail_prob = 30 + /// Impact of skill against probability of failure. + var/skill_factor = 1 + /// Skill level where failing this step becomes impossible. + var/skill_level = SKILL_ADEPT + /// What skill this step requires. + var/work_skill = SKILL_CONSTRUCTION + /// Descriptive string for this action. + var/work_verb = "forged" + +/decl/forging_step/Initialize() + + // Resolve our types now to get it out of the way. + for(var/step in steps) + steps -= step + steps += GET_DECL(step) + + if(billet_name_prefix) + name = jointext(list(billet_name_prefix, billet_name), " ") + else + name = billet_name + + . = ..() + +/decl/forging_step/validate() + . = ..() + if(!istext(name)) + . += "null or invalid name" + if(!istext(billet_desc)) + . += "null or invalid billet_desc" + if(!length(steps) && !istype(src, /decl/forging_step/product)) + . += "null or empty steps list" + if(billet_icon_state) + if(billet_icon) + if(!check_state_in_icon("[ICON_STATE_WORLD]-[billet_icon_state]", billet_icon)) + . += "missing billet icon state '[ICON_STATE_WORLD]-[billet_icon_state]' from icon '[billet_icon]'" + else + . += "missing billet_icon" + +/decl/forging_step/proc/get_product_name(decl/material/billet_material) + . = billet_name + if(billet_material) + . = "[billet_material.adjective_name] [.]" + if(billet_name_prefix) + . = "[billet_name_prefix] [.]" + +/decl/forging_step/proc/get_radial_choices() + for(var/decl/forging_step/step in steps) + var/image/radial_button = new + radial_button.name = capitalize(step.name) + LAZYSET(., step, radial_button) + +/decl/forging_step/proc/apply_to(obj/item/billet/billet) + return billet + +// There are effectively finished products. +/decl/forging_step/product + // Dummy strings to avoid validate() fails; shouldn't be used anywhere. + name = "finished product" + billet_desc = "A finished product." + abstract_type = /decl/forging_step/product + var/product_type = /obj/item/stick + +/decl/forging_step/product/get_product_name(decl/material/billet_material) + return atom_info_repository.get_name_for(product_type, billet_material?.type) + +/decl/forging_step/product/apply_to(obj/item/billet/billet) + var/obj/item/thing = new product_type(null, billet.material?.type) + thing.dropInto(billet.loc) + thing.pixel_x = billet.pixel_x + thing.pixel_y = billet.pixel_y + thing.pixel_w = billet.pixel_w + thing.pixel_z = billet.pixel_z + thing.temperature = billet.temperature + thing.update_heat_glow(anim_time = 0) + + if(billet.paint_color) + thing.paint_color = billet.paint_color + thing.update_icon() + qdel(billet) + thing.base_name = name + thing.update_name() + return thing diff --git a/mods/content/blacksmithy/forging_step_armor.dm b/mods/content/blacksmithy/forging_step_armor.dm new file mode 100644 index 00000000000..f0633652912 --- /dev/null +++ b/mods/content/blacksmithy/forging_step_armor.dm @@ -0,0 +1,37 @@ +/decl/forging_step/armour_plates + billet_desc = "A set of worked metal plates, a few steps and fittings away from forming some kind of armour." + billet_name = "armour plates" + billet_icon_state = "armour" + steps = list( + /decl/forging_step/product/breastplate, + /decl/forging_step/product/cuirass, + /decl/forging_step/product/banded + ) + +/decl/forging_step/armour_segments + billet_desc = "A set of small worked metal plates, a few steps and fittings away from forming a helmet, or arm or leg armour." + billet_name = "armour segments" + billet_icon_state = "helmet" + steps = list( + /decl/forging_step/product/helmet, + /decl/forging_step/product/sabatons, + /decl/forging_step/product/vambraces + ) + +/decl/forging_step/product/breastplate + product_type = /obj/item/clothing/suit/armor/forged/breastplate + +/decl/forging_step/product/cuirass + product_type = /obj/item/clothing/suit/armor/forged/cuirass + +/decl/forging_step/product/banded + product_type = /obj/item/clothing/suit/armor/forged/banded + +/decl/forging_step/product/helmet + product_type = /obj/item/clothing/head/helmet/plumed + +/decl/forging_step/product/sabatons + product_type = /obj/item/clothing/shoes/sabatons + +/decl/forging_step/product/vambraces + product_type = /obj/item/clothing/gloves/vambrace diff --git a/mods/content/blacksmithy/forging_step_billets.dm b/mods/content/blacksmithy/forging_step_billets.dm new file mode 100644 index 00000000000..f1c23273b93 --- /dev/null +++ b/mods/content/blacksmithy/forging_step_billets.dm @@ -0,0 +1,47 @@ +/decl/forging_step/billet + billet_desc = "An unworked length of metal used to forge items and tools." + steps = list( + /decl/forging_step/thin_billet, + /decl/forging_step/curved_billet, + /decl/forging_step/flat_bar, + /decl/forging_step/punched_billet + ) + +/decl/forging_step/thin_billet + billet_name_prefix = "thin" + billet_icon_state = "thin" + billet_desc = "A thin, elongated length of metal used to forge items and tools." + steps = list( + /decl/forging_step/blade_blank, + /decl/forging_step/ornate_blank + ) + +/decl/forging_step/curved_billet + billet_name_prefix = "curved" + billet_icon_state = "curved" + billet_desc = "A curved length of metal used to forge items and tools." + steps = list( + /decl/forging_step/product/hook, + /decl/forging_step/product/chain, + /decl/forging_step/product/horseshoe + ) + +/decl/forging_step/flat_bar + billet_name = "bar" + billet_name_prefix = "flat" + billet_icon_state = "flat" + billet_desc = "A flattened bar of metal used to forge armour components and plates." + steps = list( + /decl/forging_step/armour_plates, + /decl/forging_step/armour_segments, + /decl/forging_step/product/shield_fasteners + ) + +/decl/forging_step/punched_billet + billet_name_prefix = "punched" + billet_icon_state = "punched" + billet_desc = "A punched bar of metal used to forge items and tools" + steps = list( + /decl/forging_step/tool_head_blank, + /decl/forging_step/product/tongs + ) diff --git a/mods/content/blacksmithy/forging_step_blades.dm b/mods/content/blacksmithy/forging_step_blades.dm new file mode 100644 index 00000000000..253a1dd7332 --- /dev/null +++ b/mods/content/blacksmithy/forging_step_blades.dm @@ -0,0 +1,59 @@ +/decl/forging_step/blade_blank + billet_name = "blade blank" + billet_icon_state = "blade" + billet_desc = "A roughly shaped, dull blade. It will need further refinement before it can be finished." + steps = list( + /decl/forging_step/long_blade_blank, + /decl/forging_step/short_sword_blank + ) + +/decl/forging_step/long_blade_blank + billet_name = "blade blank" + billet_name_prefix = "long" + billet_desc = "A long, dull and unrefined blade, only a step from being a finished product." + + steps = list( + /decl/forging_step/product/longsword_blade, + /decl/forging_step/product/broadsword_blade, + /decl/forging_step/product/rapier_blade + ) + +/decl/forging_step/short_sword_blank + billet_name = "blade blank" + billet_name_prefix = "short" + billet_desc = "A short, dull and unrefined blade, only a step from being a finished product." + steps = list( + /decl/forging_step/product/poignard_blade, + /decl/forging_step/product/knife_blade, + /decl/forging_step/product/shortsword_blade, + /decl/forging_step/product/spear_head + ) + +// TODO: make these blades, add weapon crafting. +/decl/forging_step/product/longsword_blade + billet_name = "longsword" + product_type = /obj/item/bladed/longsword/forged + +/decl/forging_step/product/broadsword_blade + billet_name = "broadsword" + product_type = /obj/item/bladed/broadsword/forged + +/decl/forging_step/product/rapier_blade + billet_name = "rapier" + product_type = /obj/item/bladed/rapier/forged + +/decl/forging_step/product/poignard_blade + billet_name = "poignard" + product_type = /obj/item/bladed/poignard/forged + +/decl/forging_step/product/knife_blade + billet_name = "knife" + product_type = /obj/item/bladed/knife/forged + +/decl/forging_step/product/shortsword_blade + billet_name = "shortsword" + product_type = /obj/item/bladed/shortsword/forged + +/decl/forging_step/product/spear_head + billet_name = "spear" + product_type = /obj/item/bladed/polearm/spear/forged diff --git a/mods/content/blacksmithy/forging_step_components.dm b/mods/content/blacksmithy/forging_step_components.dm new file mode 100644 index 00000000000..6e508d3aa52 --- /dev/null +++ b/mods/content/blacksmithy/forging_step_components.dm @@ -0,0 +1,15 @@ +/decl/forging_step/product/hook + billet_name = "hook" + product_type = /obj/item/hook + +/decl/forging_step/product/chain + billet_name = "chain" + product_type = /obj/item/chain + +/decl/forging_step/product/horseshoe + billet_name = "horseshoe" + product_type = /obj/item/horseshoe + +/decl/forging_step/product/shield_fasteners + billet_name = "shield fasteners" + product_type = /obj/item/shield_fasteners diff --git a/mods/content/blacksmithy/forging_step_ornate.dm b/mods/content/blacksmithy/forging_step_ornate.dm new file mode 100644 index 00000000000..515d9d57d21 --- /dev/null +++ b/mods/content/blacksmithy/forging_step_ornate.dm @@ -0,0 +1,22 @@ +/decl/forging_step/ornate_blank + billet_name = "blank" + billet_name_prefix = "ornate" + billet_icon_state = "ornate" + billet_desc = "An ornate piece of worked metal. It still needs some last touches to be made into something useful." + steps = list( + /decl/forging_step/product/candelabra, + /decl/forging_step/product/decanter, + /decl/forging_step/product/goblet + ) + +/decl/forging_step/product/candelabra + billet_name = "candelabra" + product_type = /obj/item/candelabra + +/decl/forging_step/product/goblet + billet_name = "goblet" + product_type = /obj/item/chems/glass/handmade/fancy/goblet + +/decl/forging_step/product/decanter + billet_name = "decanter" + product_type =/obj/item/chems/glass/handmade/fancy/decanter \ No newline at end of file diff --git a/mods/content/blacksmithy/forging_step_tools.dm b/mods/content/blacksmithy/forging_step_tools.dm new file mode 100644 index 00000000000..d7cfb50501b --- /dev/null +++ b/mods/content/blacksmithy/forging_step_tools.dm @@ -0,0 +1,56 @@ +/decl/forging_step/tool_head_blank + billet_desc = "A heavy piece of shaped metal, almost suitable for use as the head of a tool. It still needs some last touches to be made into something useful." + billet_name = "tool head blank" + billet_icon_state = "tool_head" + steps = list( + /decl/forging_step/product/hoe_head, + /decl/forging_step/product/shovel_head, + /decl/forging_step/hammer_head_blank, + /decl/forging_step/product/chisel_head + ) + +/decl/forging_step/hammer_head_blank + billet_name = "hammer head blank" + billet_desc = "A worked slab of material in the rough shape of a hammer head, only a step from being a finished product." + steps = list( + /decl/forging_step/product/pickaxe_head, + /decl/forging_step/product/sledge_head, + /decl/forging_step/product/hammer_head, + /decl/forging_step/product/forging_hammer_head + ) + +/decl/forging_step/product/tongs + billet_name = "tongs" + product_type = /obj/item/tongs + +/decl/forging_step/product/chisel_head + billet_name = "chisel head" + product_type = /obj/item/tool_component/head/chisel + +/decl/forging_step/product/hammer_head + billet_name = "hammer head" + product_type = /obj/item/tool_component/head/hammer + +/decl/forging_step/product/shovel_head + billet_name = "shovel head" + product_type = /obj/item/tool_component/head/shovel + +/decl/forging_step/product/hoe_head + billet_name = "hoe head" + product_type = /obj/item/tool_component/head/hoe + +/decl/forging_step/product/handaxe_head + billet_name = "handaxe head" + product_type = /obj/item/tool_component/head/handaxe + +/decl/forging_step/product/pickaxe_head + billet_name = "pickaxe head" + product_type = /obj/item/tool_component/head/pickaxe + +/decl/forging_step/product/sledge_head + billet_name = "sledge head" + product_type = /obj/item/tool_component/head/sledgehammer + +/decl/forging_step/product/forging_hammer_head + billet_name = "forging hammer head" + product_type = /obj/item/tool_component/head/forging_hammer diff --git a/mods/content/blacksmithy/forging_types.dm b/mods/content/blacksmithy/forging_types.dm new file mode 100644 index 00000000000..f766d39982d --- /dev/null +++ b/mods/content/blacksmithy/forging_types.dm @@ -0,0 +1,41 @@ +/obj/item/bladed/longsword/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null + +/obj/item/bladed/broadsword/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null + +/obj/item/bladed/rapier/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null + +/obj/item/bladed/poignard/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null + +/obj/item/bladed/knife/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null + +/obj/item/bladed/shortsword/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null + +/obj/item/bladed/polearm/spear/forged + material = /decl/material/solid/metal/iron + hilt_material = null + guard_material = null + pommel_material = null diff --git a/mods/content/blacksmithy/tongs.dm b/mods/content/blacksmithy/tongs.dm new file mode 100644 index 00000000000..a3cc37728b6 --- /dev/null +++ b/mods/content/blacksmithy/tongs.dm @@ -0,0 +1,32 @@ +/obj/item/tongs + name = "tongs" + desc = "Long-handled grippers well suited to fishing white-hot iron out of a forge fire." + icon = 'icons/obj/items/tongs.dmi' + icon_state = ICON_STATE_WORLD + material = /decl/material/solid/metal/iron + obj_flags = OBJ_FLAG_INSULATED_HANDLE + material_alteration = MAT_FLAG_ALTERATION_ALL + var/obj/item/holding_bar + +/obj/item/tongs/on_update_icon() + . = ..() + if(holding_bar) + // Note, not get_color(); heat color is temporarily applied over the top of base color. + add_overlay(overlay_image(icon, "[icon_state]-bar", holding_bar.color, RESET_COLOR)) + +/obj/item/tongs/adjust_mob_overlay(mob/living/user_mob, bodytype, image/overlay, slot, bodypart, use_fallback_if_icon_missing) + if(overlay && holding_bar) + var/check_state = "[overlay.icon_state]-bar" + if(check_state_in_icon(check_state, overlay.icon)) + overlay.overlays += overlay_image(overlay.icon, check_state, holding_bar.get_color(), RESET_COLOR) + . = ..() + +/obj/item/tongs/Exited(atom/movable/AM, atom/new_loc) + . = ..() + if(AM == holding_bar) + holding_bar = null + update_icon() + +/obj/item/tongs/Destroy() + QDEL_NULL(holding_bar) + . = ..() diff --git a/mods/content/fantasy/submaps/woods/bear_den/bear_den.dmm b/mods/content/fantasy/submaps/woods/bear_den/bear_den.dmm index 021df578e9b..0a5b96087a4 100644 --- a/mods/content/fantasy/submaps/woods/bear_den/bear_den.dmm +++ b/mods/content/fantasy/submaps/woods/bear_den/bear_den.dmm @@ -22,7 +22,7 @@ /turf/floor/dirt, /area/fantasy/outside/point_of_interest/bear_den) "w" = ( -/obj/item/bladed/knife, +/obj/item/bladed/knife/iron, /obj/item/cash/imperial/crown, /obj/item/cash/imperial/crown, /obj/item/cash/imperial/quin, diff --git a/mods/content/fantasy/submaps/woods/chemistry_shack/chemistry_shack.dmm b/mods/content/fantasy/submaps/woods/chemistry_shack/chemistry_shack.dmm index 6ed42c83589..a35016e505f 100644 --- a/mods/content/fantasy/submaps/woods/chemistry_shack/chemistry_shack.dmm +++ b/mods/content/fantasy/submaps/woods/chemistry_shack/chemistry_shack.dmm @@ -108,7 +108,7 @@ "L" = ( /obj/abstract/exterior_marker/inside, /obj/structure/table/wood/ebony, -/obj/item/bladed/knife, +/obj/item/bladed/knife/iron, /obj/item/food/grown/potato, /obj/item/food/grown/potato, /obj/item/food/grown/carrot, diff --git a/mods/content/fantasy/submaps/woods/hunter_camp/hunter_camp.dmm b/mods/content/fantasy/submaps/woods/hunter_camp/hunter_camp.dmm index b269d8d4cdd..c54ef3bfe8c 100644 --- a/mods/content/fantasy/submaps/woods/hunter_camp/hunter_camp.dmm +++ b/mods/content/fantasy/submaps/woods/hunter_camp/hunter_camp.dmm @@ -85,7 +85,7 @@ /turf/floor/barren, /area/fantasy/outside/point_of_interest/hunter_camp) "Z" = ( -/obj/item/bladed/knife, +/obj/item/bladed/knife/iron, /turf/floor/barren, /area/fantasy/outside/point_of_interest/hunter_camp) diff --git a/mods/content/fantasy/submaps/woods/old_cabin/old_cabin.dmm b/mods/content/fantasy/submaps/woods/old_cabin/old_cabin.dmm index 18e12175274..9156eb4514d 100644 --- a/mods/content/fantasy/submaps/woods/old_cabin/old_cabin.dmm +++ b/mods/content/fantasy/submaps/woods/old_cabin/old_cabin.dmm @@ -67,7 +67,7 @@ /area/fantasy/outside/point_of_interest/old_cabin) "H" = ( /obj/structure/table/wood/ebony, -/obj/item/bladed/knife, +/obj/item/bladed/knife/iron, /obj/item/food/grown/potato, /obj/item/food/grown/potato, /obj/item/food/grown/carrot, diff --git a/mods/content/fantasy/submaps/woods/suspicious_cabin/suspicious_cabin.dmm b/mods/content/fantasy/submaps/woods/suspicious_cabin/suspicious_cabin.dmm index 1629e04adaf..c79f214b00d 100644 --- a/mods/content/fantasy/submaps/woods/suspicious_cabin/suspicious_cabin.dmm +++ b/mods/content/fantasy/submaps/woods/suspicious_cabin/suspicious_cabin.dmm @@ -43,7 +43,7 @@ /area/template_noop) "t" = ( /obj/structure/table/wood/ebony, -/obj/item/bladed/knife, +/obj/item/bladed/knife/iron, /turf/floor/path/basalt, /area/template_noop) "v" = ( diff --git a/mods/~compatibility/patches/fantasy.dm b/mods/~compatibility/patches/fantasy.dm index 4b4d6f7feab..b0abba63bcd 100644 --- a/mods/~compatibility/patches/fantasy.dm +++ b/mods/~compatibility/patches/fantasy.dm @@ -7,3 +7,7 @@ #ifdef MODPACK_ITEM_SHARPENING #include "fantasy/whetstone_fantasy.dm" #endif + +#ifdef MODPACK_BLACKSMITHY +#include "fantasy/forging_fantasy.dm" +#endif \ No newline at end of file diff --git a/mods/~compatibility/patches/fantasy/forging_fantasy.dm b/mods/~compatibility/patches/fantasy/forging_fantasy.dm new file mode 100644 index 00000000000..6de02a927d2 --- /dev/null +++ b/mods/~compatibility/patches/fantasy/forging_fantasy.dm @@ -0,0 +1,2 @@ +/decl/forging_step + work_skill = SKILL_METALWORK diff --git a/sound/effects/anvil1.ogg b/sound/effects/anvil1.ogg new file mode 100644 index 00000000000..2c29e242750 Binary files /dev/null and b/sound/effects/anvil1.ogg differ diff --git a/sound/effects/anvil2.ogg b/sound/effects/anvil2.ogg new file mode 100644 index 00000000000..dc7f43ceaa0 Binary files /dev/null and b/sound/effects/anvil2.ogg differ diff --git a/sound/effects/anvil3.ogg b/sound/effects/anvil3.ogg new file mode 100644 index 00000000000..ad3747c0f32 Binary files /dev/null and b/sound/effects/anvil3.ogg differ diff --git a/sound/effects/anvil4.ogg b/sound/effects/anvil4.ogg new file mode 100644 index 00000000000..88da5eb8bb6 Binary files /dev/null and b/sound/effects/anvil4.ogg differ diff --git a/sound/effects/anvil5.ogg b/sound/effects/anvil5.ogg new file mode 100644 index 00000000000..80533e38aeb Binary files /dev/null and b/sound/effects/anvil5.ogg differ