diff --git a/code/datums/components/crafting/recipes/recipes_clothing.dm b/code/datums/components/crafting/recipes/recipes_clothing.dm index 717e99e8b2..df0a2a091a 100644 --- a/code/datums/components/crafting/recipes/recipes_clothing.dm +++ b/code/datums/components/crafting/recipes/recipes_clothing.dm @@ -273,6 +273,16 @@ time = 30 category = CAT_CLOTHING +/datum/crafting_recipe/twinsheath + name = "Twin Sword Sheath" + result = /obj/item/storage/belt/sabre/twin + reqs = list(/obj/item/stack/sheet/mineral/wood = 3, + /obj/item/stack/sheet/leather = 8) + tools = list(TOOL_WIRECUTTER) + time = 70 + category = CAT_CLOTHING + + /datum/crafting_recipe/durathread_reinforcement_kit name = "Durathread Reinforcement Kit" result = /obj/item/armorkit diff --git a/code/datums/components/crafting/recipes/recipes_misc.dm b/code/datums/components/crafting/recipes/recipes_misc.dm index f113be728d..14987bac44 100644 --- a/code/datums/components/crafting/recipes/recipes_misc.dm +++ b/code/datums/components/crafting/recipes/recipes_misc.dm @@ -120,6 +120,53 @@ category = CAT_MISC always_availible = FALSE // Disabled til learned +/datum/crafting_recipe/furnace + name = "Sandstone Furnace" + result = /obj/structure/furnace + time = 300 + reqs = list(/obj/item/stack/sheet/mineral/sandstone = 15, + /obj/item/stack/sheet/metal = 4, + /obj/item/stack/rods = 2) + tools = list(TOOL_CROWBAR) + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC + +/datum/crafting_recipe/tableanvil + name = "Table Anvil" + result = /obj/structure/anvil/obtainable/table + time = 300 + reqs = list(/obj/item/stack/sheet/metal = 4, + /obj/item/stack/rods = 2) + tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC + +/datum/crafting_recipe/sandvil + name = "Sandstone Anvil" + result = /obj/structure/anvil/obtainable/sandstone + time = 300 + reqs = list(/obj/item/stack/sheet/mineral/sandstone = 24) + tools = list(TOOL_CROWBAR) + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC + +/datum/crafting_recipe/basaltblock + name = "Sintered Basalt Block" + result = /obj/item/basaltblock + time = 200 + reqs = list(/obj/item/stack/ore/glass/basalt = 50) + tools = list(TOOL_WELDER) + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC + +/datum/crafting_recipe/basaltanvil + name = "Basalt Anvil" + result = /obj/structure/anvil/obtainable/basalt + time = 200 + reqs = list(/obj/item/basaltblock = 5) + tools = list(TOOL_CROWBAR) + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC /////////////////// //Tools & Storage// /////////////////// @@ -175,6 +222,17 @@ subcategory = CAT_TOOL category = CAT_MISC +/datum/crafting_recipe/toolboxhammer + name = "Toolbox Hammer" + result = /obj/item/melee/smith/hammer/toolbox + tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER) + reqs = list(/obj/item/storage/toolbox = 1, + /obj/item/stack/sheet/metal = 4, + /obj/item/stack/rods = 2) + time = 40 + subcategory = CAT_TOOL + category = CAT_MISC + /datum/crafting_recipe/papersack name = "Paper Sack" result = /obj/item/storage/box/papersack @@ -358,6 +416,25 @@ //Unsorted// //////////// + + +/datum/crafting_recipe/stick + name = "Stick" + time = 30 + reqs = list(/obj/item/stack/sheet/mineral/wood = 1) + result = /obj/item/stick + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC + + +/datum/crafting_recipe/swordhilt + name = "Sword Hilt" + time = 30 + reqs = list(/obj/item/stack/sheet/mineral/wood = 2) + result = /obj/item/swordhandle + subcategory = CAT_MISCELLANEOUS + category = CAT_MISC + /datum/crafting_recipe/blackcarpet name = "Black Carpet" reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 1469965b57..30a04d7382 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -35,23 +35,24 @@ Unless you know what you're doing, only use the first three numbers. They're in value_per_unit = 0.025 beauty_modifier = 0.075 -///Slight force increase +///Slight force decrease. It's gold, it's soft as fuck. /datum/material/gold name = "gold" desc = "Gold" color = list(340/255, 240/255, 50/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //gold is shiny, but not as bright as bananium - strength_modifier = 1.2 + strength_modifier = 0.8 categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/gold value_per_unit = 0.0625 beauty_modifier = 0.15 armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1) -///Has no special properties +///Small force increase, for diamond swords /datum/material/diamond name = "diamond" desc = "Highly pressurized carbon" color = list(48/255, 272/255, 301/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) + strength_modifier = 1.1 alpha = 132 categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/diamond @@ -106,6 +107,7 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bluespace crystal" desc = "Crystals with bluespace properties" color = list(119/255, 217/255, 396/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) + integrity_modifier = 0.2 //these things shatter when thrown. alpha = 200 categories = list(MAT_CATEGORY_ORE = TRUE) beauty_modifier = 0.5 @@ -139,7 +141,7 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "titanium" desc = "Titanium" color = "#b3c0c7" - strength_modifier = 1.3 + strength_modifier = 1.1 categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/titanium value_per_unit = 0.0625 @@ -203,7 +205,7 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "adamantine" desc = "A powerful material made out of magic, I mean science!" color = "#6d7e8e" - strength_modifier = 1.5 + strength_modifier = 1.3 categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/adamantine value_per_unit = 0.25 @@ -276,6 +278,7 @@ Unless you know what you're doing, only use the first three numbers. They're in desc = "Mir'ntrath barhah Nar'sie." color = "#3C3434" categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) + strength_modifier = 1.2 sheet_type = /obj/item/stack/sheet/runed_metal value_per_unit = 0.75 armor_modifiers = list("melee" = 1.2, "bullet" = 1.2, "laser" = 1, "energy" = 1, "bomb" = 1.2, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) @@ -286,6 +289,7 @@ Unless you know what you're doing, only use the first three numbers. They're in name = "bronze" desc = "Clock Cult? Never heard of it." color = "#92661A" + strength_modifier = 1.1 categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/bronze value_per_unit = 0.025 diff --git a/code/datums/skills/_skill_holder.dm b/code/datums/skills/_skill_holder.dm index 73748417c3..83c95c6439 100644 --- a/code/datums/skills/_skill_holder.dm +++ b/code/datums/skills/_skill_holder.dm @@ -110,7 +110,7 @@ /** * Automatic skill increase, multiplied by skill affinity if existing. - * Only works if skill is numerical. + * Only works if skill is numerical or levelled.. */ /datum/mind/proc/auto_gain_experience(skill, value, maximum, silent = FALSE) if(!ispath(skill, /datum/skill)) diff --git a/code/datums/skills/blacksmithing.dm b/code/datums/skills/blacksmithing.dm new file mode 100644 index 0000000000..0bddae5562 --- /dev/null +++ b/code/datums/skills/blacksmithing.dm @@ -0,0 +1,6 @@ +/datum/skill/level/dorfy/blacksmithing + name = "Blacksmithing" + desc = "Making metal into fancy shapes using heat and force. Higher levels increase both your working speed at an anvil as well as the quality of your works." + name_color = COLOR_FLOORTILE_GRAY + skill_traits = list(SKILL_SANITY, SKILL_INTELLIGENCE, SKILL_USE_TOOL, SKILL_TRAINING_TOOL) + ui_category = SKILL_UI_CAT_MISC diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 7692278ba3..426958b99a 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -117,6 +117,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \ +// new/datum/stack_recipe("diamond brick", /obj/item/ingot/diamond, 6, time = 100), \ not yet )) /obj/item/stack/sheet/mineral/diamond/get_main_recipes() @@ -145,6 +146,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \ new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("uranium ingot", /obj/item/ingot/uranium, 6, time = 100), \ )) /obj/item/stack/sheet/mineral/uranium/get_main_recipes() @@ -177,6 +179,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \ new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \ +// new/datum/stack_recipe("plasma ingot", /obj/item/ingot/plasma, 6, time = 100), \ no )) /obj/item/stack/sheet/mineral/plasma/get_main_recipes() @@ -221,6 +224,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \ new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("gold ingot", /obj/item/ingot/gold, 6, time = 100), \ )) /obj/item/stack/sheet/mineral/gold/get_main_recipes() @@ -252,6 +256,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("silver ingot", /obj/item/ingot/silver, 6, time = 100), \ )) /obj/item/stack/sheet/mineral/silver/get_main_recipes() @@ -278,6 +283,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ GLOBAL_LIST_INIT(bananium_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("hilarious ingot", /obj/item/ingot/bananium, 6, time = 100), \ )) /obj/item/stack/sheet/mineral/bananium/get_main_recipes() @@ -306,6 +312,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \ GLOBAL_LIST_INIT(titanium_recipes, list ( \ new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \ + new/datum/stack_recipe("titanic ingot", /obj/item/ingot/titanium, 6, time = 100), \ )) /obj/item/stack/sheet/mineral/titanium/get_main_recipes() @@ -353,6 +360,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ */ GLOBAL_LIST_INIT(adamantine_recipes, list( new /datum/stack_recipe("incomplete servant golem shell", /obj/item/golem_shell/servant, req_amount=1, res_amount=1), + new/datum/stack_recipe("adamant ingot", /obj/item/ingot/adamantine, 6, time = 100), \ )) /obj/item/stack/sheet/mineral/adamantine diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 645051b7c2..9ed930b8c7 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -121,6 +121,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \ new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("iron ingot", /obj/item/ingot/iron, 6, time = 100), \ )) /obj/item/stack/sheet/metal @@ -556,6 +557,9 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("anvil", /obj/structure/anvil/obtainable/narsie, 4, time = 40, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("runic ingot", /obj/item/ingot/cult, 2, time = 100), \ + new/datum/stack_recipe("rune smith's hammer", /obj/item/melee/smith/hammer/narsie, 6), \ )) /obj/item/stack/sheet/runed_metal @@ -618,6 +622,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brass anvil", /obj/structure/anvil/obtainable/ratvar, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("brass furnace", /obj/structure/furnace/infinite/ratvar, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ null, \ new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("sender - mech sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ @@ -629,6 +635,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \ null, \ new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \ + new/datum/stack_recipe("brass smith's hammer", /obj/item/melee/smith/hammer/ratvar, 6), \ + new/datum/stack_recipe("brass ingot", /obj/item/ingot/bronze/ratvar, 6, time = 100), \ )) /obj/item/stack/tile/brass @@ -684,7 +692,10 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \ new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \ - new /datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \ + new/datum/stack_recipe("bronze anvil",/obj/structure/anvil/obtainable/bronze, 20, time = 110, one_per_turf = TRUE, on_floor = TRUE), \ + null, + new/datum/stack_recipe("bronze ingot", /obj/item/ingot/bronze, 6, time = 100), \ + new/datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \ )) /obj/item/stack/sheet/bronze diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 0001494fdd..590df34cde 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -815,3 +815,18 @@ attack_verb = list("bashed", "slashes", "prods", "pokes") fitting_swords = list(/obj/item/melee/rapier) starting_sword = /obj/item/melee/rapier + +/obj/item/storage/belt/sabre/twin + name = "twin sheath" + desc = "Two sheaths. One is capable of holding a katana (or bokken) and the other a wakizashi. You could put two wakizashis in if you really wanted to. Now you can really roleplay as a samurai." + icon_state = "twinsheath" + item_state = "quiver" //this'll do. + w_class = WEIGHT_CLASS_BULKY + fitting_swords = list(/obj/item/melee/smith/wakizashi, /obj/item/melee/smith/twohand/katana, /obj/item/melee/bokken) + starting_sword = null + +/obj/item/storage/belt/sabre/twin/ComponentInitialize() + . = ..() + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + STR.max_items = 2 + STR.max_w_class = WEIGHT_CLASS_BULKY + WEIGHT_CLASS_NORMAL //katana and waki. diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm index 5803941f36..a388621c92 100644 --- a/code/modules/antagonists/cult/cult_structures.dm +++ b/code/modules/antagonists/cult/cult_structures.dm @@ -174,7 +174,14 @@ new reward(get_turf(src)) to_chat(user, "You work the forge as dark knowledge guides your hands, creating the [choice]!") - +/obj/structure/destructible/cult/forge/attackby(obj/item/I, mob/user) + if(!iscultist(user)) + to_chat(user, "The heat radiating from [src] pushes you back.") + return + if(istype(I, /obj/item/ingot)) + var/obj/item/ingot/notsword = I + to_chat(user, "You heat the [notsword] in the [src].") + notsword.workability = "shapeable" /obj/structure/destructible/cult/pylon name = "pylon" diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm index c6728831eb..394b86bb81 100644 --- a/code/modules/cargo/packs/misc.dm +++ b/code/modules/cargo/packs/misc.dm @@ -13,6 +13,13 @@ //////////////////// Paperwork and Writing Supplies ////////////////////////// ////////////////////////////////////////////////////////////////////////////// + +/datum/supply_pack/misc/anvil + name = "Anvil Crate" + desc = "An anvil in a crate, we had to dig this out of the old warehouse. It's got wheels on it so you can move it." + cost = 7500 + contains = list(/obj/structure/anvil/obtainable/basic) + /datum/supply_pack/misc/artsupply name = "Art Supplies" desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!" diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index 9ccb7c0efc..b2cd840468 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -12,13 +12,14 @@ slot_flags = ITEM_SLOT_BELT var/cooldown = 35 var/current_cooldown = 0 + var/range = 7 /obj/item/mining_scanner/attack_self(mob/user) if(!user.client) return if(current_cooldown <= world.time) current_cooldown = world.time + cooldown - mineral_scan_pulse(get_turf(user)) + mineral_scan_pulse(get_turf(user), range) //Debug item to identify all ore spread quickly /obj/item/mining_scanner/admin diff --git a/code/modules/smithing/anvil.dm b/code/modules/smithing/anvil.dm new file mode 100644 index 0000000000..88711aec37 --- /dev/null +++ b/code/modules/smithing/anvil.dm @@ -0,0 +1,315 @@ +#define WORKPIECE_PRESENT 1 +#define WORKPIECE_INPROGRESS 2 +#define WORKPIECE_FINISHED 3 +#define WORKPIECE_SLAG 5 + +#define RECIPE_SMALLPICK "dbp" //draw bend punch +#define RECIPE_LARGEPICK "ddbp" //draw draw bend punch +#define RECIPE_SHOVEL "dfup" //draw fold upset punch +#define RECIPE_HAMMER "sfp" //shrink fold punch + + +#define RECIPE_SMALLKNIFE "sdd" //shrink draw draw +#define RECIPE_SHORTSWORD "dff" //draw fold fold +#define RECIPE_WAKI "dfsf" //draw fold shrink fold +#define RECIPE_SCIMITAR "dfb" //draw fold bend +#define RECIPE_SABRE "ddsf" //draw draw shrink fold +#define RECIPE_RAPIER "sdfd" //shrink draw fold draw +#define RECIPE_BROADSWORD "dfuf" //draw fold upset fold +#define RECIPE_ZWEIHANDER "udfsf" //upset draw fold shrink fold +#define RECIPE_KATANA "fffff" //fold fold fold fold fold + + +#define RECIPE_SCYTHE "bdf" //bend draw fold +#define RECIPE_COGHEAD "bsf" //bend shrink fold. + + +#define RECIPE_JAVELIN "dbf" //draw bend fold +#define RECIPE_HALBERD "duffp" //draw upset fold fold punch +#define RECIPE_GLAIVE "usfp" //upset shrink fold punch +#define RECIPE_PIKE "ddbf" //draw draw bend fold + +/obj/structure/anvil + name = "anvil" + desc = "Base class of anvil. This shouldn't exist, but is useable." + icon = 'icons/obj/smith.dmi' + icon_state = "anvil" + density = TRUE + anchored = TRUE + var/workpiece_state = FALSE + var/datum/material/workpiece_material + var/anvilquality = 0 + var/currentquality = 0 //lolman? what the fuck do these vars do? + var/currentsteps = 0 //even i don't know + var/outrightfailchance = 1 //todo: document this shit + var/stepsdone = "" + var/rng = FALSE + var/debug = FALSE //vv this if you want an artifact + var/artifactrolled = FALSE + var/itemqualitymax = 20 + var/list/smithrecipes = list(RECIPE_HAMMER = /obj/item/smithing/hammerhead, + RECIPE_SCYTHE = /obj/item/smithing/scytheblade, + RECIPE_SHOVEL = /obj/item/smithing/shovelhead, + RECIPE_COGHEAD = /obj/item/smithing/cogheadclubhead, + RECIPE_JAVELIN = /obj/item/smithing/javelinhead, + RECIPE_LARGEPICK = /obj/item/smithing/pickaxehead, + RECIPE_SMALLPICK = /obj/item/smithing/prospectingpickhead, + RECIPE_SHORTSWORD = /obj/item/smithing/shortswordblade, + RECIPE_SCIMITAR = /obj/item/smithing/scimitarblade, + RECIPE_WAKI = /obj/item/smithing/wakiblade, + RECIPE_RAPIER = /obj/item/smithing/rapierblade, + RECIPE_SABRE = /obj/item/smithing/sabreblade, + RECIPE_SMALLKNIFE = /obj/item/smithing/knifeblade, + RECIPE_BROADSWORD = /obj/item/smithing/broadblade, + RECIPE_ZWEIHANDER = /obj/item/smithing/zweiblade, + RECIPE_KATANA = /obj/item/smithing/katanablade, + RECIPE_HALBERD = /obj/item/smithing/halberdhead, + RECIPE_GLAIVE = /obj/item/smithing/glaivehead, + RECIPE_PIKE = /obj/item/smithing/pikehead) + +/obj/structure/anvil/Initialize() + ..() + currentquality = anvilquality + +/obj/structure/anvil/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/ingot)) + var/obj/item/ingot/notsword = I + if(workpiece_state) + to_chat(user, "There's already a workpiece! Finish it or take it off.") + return FALSE + if(notsword.workability == "shapeable") + workpiece_state = WORKPIECE_PRESENT + workpiece_material = notsword.custom_materials + to_chat(user, "You place the [notsword] on the [src].") + currentquality = anvilquality + var/skillmod = 0 + if(user.mind.skill_holder) + skillmod = user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/2 + currentquality += skillmod + qdel(notsword) + else + to_chat(user, "The ingot isn't workable yet!") + return FALSE + return + else if(istype(I, /obj/item/melee/smith/hammer)) + var/obj/item/melee/smith/hammer/hammertime = I + if(workpiece_state == WORKPIECE_PRESENT || workpiece_state == WORKPIECE_INPROGRESS) + do_shaping(user, hammertime.qualitymod) + return + else + to_chat(user, "You can't work an empty anvil!") + return FALSE + return ..() + +/obj/structure/anvil/wrench_act(mob/living/user, obj/item/I) + ..() + default_unfasten_wrench(user, I, 5) + return TRUE + + +/obj/structure/anvil/proc/do_shaping(mob/user, var/qualitychange) + currentquality += qualitychange + var/list/shapingsteps = list("weak hit", "strong hit", "heavy hit", "fold", "draw", "shrink", "bend", "punch", "upset") //weak/strong/heavy hit affect strength. All the other steps shape. + workpiece_state = WORKPIECE_INPROGRESS + var/stepdone = input(user, "How would you like to work the metal?") in shapingsteps + var/steptime = 50 + if(user.mind.skill_holder) + var/skillmod = user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/10 + 1 + steptime = 50 / skillmod + playsound(src, 'sound/effects/clang2.ogg',40, 2) + if(!do_after(user, steptime, target = src)) + return FALSE + switch(stepdone) + if("weak hit") + currentsteps += 1 + outrightfailchance += 5 + currentquality += 1 + if("strong hit") + currentsteps += 2 + outrightfailchance += 9.5 + currentquality += 2 + if("heavy hit") + currentsteps += 3 + outrightfailchance += 12.5 + currentquality += 3 + if("fold") + stepsdone += "f" + currentsteps += 1 + currentquality -= 1 + if("draw") + stepsdone += "d" + currentsteps += 1 + currentquality -= 1 + if("shrink") + stepsdone += "s" + currentsteps += 1 + currentquality -= 1 + if("bend") + stepsdone += "b" + currentsteps += 1 + currentquality -= 1 + if("punch") + stepsdone += "p" + currentsteps += 1 + currentquality -= 1 + if("upset") + stepsdone += "u" + currentsteps += 1 + currentquality -= 1 + user.visible_message("[user] works the metal on the anvil with their hammer with a loud clang!", \ + "You [stepdone] the metal with a loud clang!") + playsound(src, 'sound/effects/clang2.ogg',40, 2) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/effects/clang2.ogg', 40, 2), 15) + if(length(stepsdone) >= 3) + tryfinish(user) + +/obj/structure/anvil/proc/tryfinish(mob/user) + var/artifactchance = 0 + if(!artifactrolled) + artifactchance = (1+(user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/4))/2500 + artifactrolled = TRUE + var/artifact = max(prob(artifactchance), debug) + var/finalfailchance = outrightfailchance + if(user.mind.skill_holder) + var/skillmod = user.mind.get_skill_level(/datum/skill/level/dorfy/blacksmithing)/10 + 1 + finalfailchance = max(0, finalfailchance / skillmod) //lv 2 gives 20% less to fail, 3 30%, etc + if((currentsteps > 10 || (rng && prob(finalfailchance))) && !artifact) + to_chat(user, "") + var/turf/T = get_turf(user) + workpiece_state = FALSE + new /obj/item/stack/ore/slag(T) + currentquality = anvilquality + stepsdone = "" + currentsteps = 0 + outrightfailchance = 1 + artifactrolled = FALSE + if(user.mind.skill_holder) + user.mind.auto_gain_experience(/datum/skill/level/dorfy/blacksmithing, 25, 400, silent = FALSE) + for(var/i in smithrecipes) + if(i == stepsdone) + var/turf/T = get_turf(user) + var/obj/item/smithing/create = smithrecipes[stepsdone] + var/obj/item/smithing/finisheditem = new create(T) + to_chat(user, "You finish your [finisheditem]!") + if(artifact) + to_chat(user, "It is an artifact, a creation whose legacy shall live on forevermore.") //todo: SSblackbox + currentquality = max(currentquality, 2) + finisheditem.quality = currentquality * 3//this is insane i know it's 1/2500 for most of the time and 0.8% at best + finisheditem.artifact = TRUE + else + finisheditem.quality = min(currentquality, itemqualitymax) + switch(finisheditem.quality) + if(-1000 to -8) + finisheditem.desc = "It looks to be the most awfully made object you've ever seen." + if(-8) + finisheditem.desc = "It looks to be the second most awfully made object you've ever seen." + if(-8 to 0) + finisheditem.desc = "It looks to be barely passable as... whatever it's trying to pass for." + if(0) + finisheditem.desc = "It looks to be totally average." + if(0 to INFINITY) + finisheditem.desc = "It looks to be better than average." + workpiece_state = FALSE + finisheditem.set_custom_materials(workpiece_material) + currentquality = anvilquality + stepsdone = "" + currentsteps = 0 + outrightfailchance = 1 + artifactrolled = FALSE + if(user.mind.skill_holder) + user.mind.auto_gain_experience(/datum/skill/level/dorfy/blacksmithing, 50, 10000000, silent = FALSE) + break + +/obj/structure/anvil/debugsuper + name = "super ultra epic anvil of debugging." + desc = "WOW. A DEBUG ITEM STRUCTURE. EPIC." + icon_state = "anvil" + anvilquality = 10 + itemqualitymax = 9001 + outrightfailchance = 0 + +/obj/structure/anvil/obtainable + name = "anvil" + desc = "Base class of anvil. This shouldn't exist, but is useable." + anvilquality = 0 + outrightfailchance = 5 + rng = TRUE + +/obj/structure/anvil/obtainable/table + name = "table anvil" + desc = "A slightly reinforced table. Good luck." + icon_state = "tablevil" + anvilquality = -2 + itemqualitymax = 0 + + +/obj/structure/anvil/obtainable/table/do_shaping(mob/user, var/qualitychange) + if(prob(5)) + to_chat(user, "The [src] breaks under the strain!") + take_damage(max_integrity) + return FALSE + else + ..() + +/obj/structure/anvil/obtainable/bronze + name = "slab of bronze" + desc = "A big block of bronze. Useable as an anvil." + custom_materials = list(/datum/material/bronze=8000) + icon_state = "ratvaranvil" + anvilquality = -0.5 + itemqualitymax = 2 + +/obj/structure/anvil/obtainable/sandstone + name = "sandstone brick anvil" + desc = "A big block of sandstone. Useable as an anvil." + custom_materials = list(/datum/material/sandstone=8000) + icon_state = "sandvil" + anvilquality = -1 + itemqualitymax = 2 + +/obj/structure/anvil/obtainable/basalt + name = "basalt brick anvil" + desc = "A big block of basalt. Useable as an anvil, better than sandstone. Igneous!" + icon_state = "sandvilnoir" + anvilquality = -0.5 + itemqualitymax = 4 + +/obj/structure/anvil/obtainable/basic + name = "anvil" + desc = "An anvil. It's got wheels bolted to the bottom." + anvilquality = 0 + itemqualitymax = 6 + +/obj/structure/anvil/obtainable/ratvar + name = "brass anvil" + desc = "A big block of what appears to be brass. Useable as an anvil, if whatever's holding the brass together lets you." + custom_materials = list(/datum/material/bronze=8000) + icon_state = "ratvaranvil" + anvilquality = 1 + itemqualitymax = 8 + +/obj/structure/anvil/obtainable/ratvar/attackby(obj/item/I, mob/user) + if(is_servant_of_ratvar(user)) + return ..() + else + to_chat(user, "KNPXWN, QNJCQNW!") //rot13 then rot22 if anyone wants to decode + +/obj/structure/anvil/obtainable/narsie + name = "runic anvil" + desc = "An anvil made of a strange, runic metal." + custom_materials = list(/datum/material/runedmetal=8000) + icon = 'icons/obj/smith.dmi' + icon_state = "evil" + anvilquality = 1 + itemqualitymax = 8 + +/obj/structure/anvil/obtainable/narsie/attackby(obj/item/I, mob/user) + if(iscultist(user)) + return ..() + else + to_chat(user, "That is not yours to use!") + +#undef WORKPIECE_PRESENT +#undef WORKPIECE_INPROGRESS +#undef WORKPIECE_FINISHED +#undef WORKPIECE_SLAG diff --git a/code/modules/smithing/finished_items.dm b/code/modules/smithing/finished_items.dm new file mode 100644 index 0000000000..5db6b09452 --- /dev/null +++ b/code/modules/smithing/finished_items.dm @@ -0,0 +1,329 @@ + +/obj/item/melee/smith + name = "base class obj/item/melee/smith" //tin. handles overlay and quality and shit. + desc = "cringe" + icon = 'icons/obj/smith.dmi' + icon_state = "claymore" + item_state = "claymore" + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON //yeah ok + slot_flags = ITEM_SLOT_BELT + w_class = WEIGHT_CLASS_NORMAL + force = 6 + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + var/quality + var/overlay_state = "stick" + var/mutable_appearance/overlay + var/wielded_mult = 1 + var/wield_force = 15 + +/obj/item/melee/smith/Initialize() + ..() + if(desc == "cringe") + desc = "A handmade [name]." + overlay = mutable_appearance(icon, overlay_state) + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + if(force < 0) + force = 0 + + +/obj/item/melee/smith/twohand + item_flags = NEEDS_PERMIT //it's a bigass sword/spear. beepsky is going to give you shit for it. + sharpness = SHARP_EDGED + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + force = 10 + wielded_mult = 1.75 + w_class = WEIGHT_CLASS_BULKY + +/obj/item/melee/smith/twohand/ComponentInitialize() + . = ..() + AddComponent(/datum/component/butchering, 100, 70) //decent in a pinch, but pretty bad. + AddElement(/datum/element/sword_point) + + + +/////////////////////////// +// Mining // +/////////////////////////// +/obj/item/mining_scanner/prospector + name = "prospector's pickaxe" + desc = "A pickaxe that can sound rocks to find mineral deposits and stop gibtonite detonations." + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + icon = 'icons/obj/smith.dmi' + icon_state = "minipick" //todo:sprite + sharpness = SHARP_POINTY//it doesnt have a blade it has a point + +/obj/item/mining_scanner/prospector/Initialize() + ..() + var/mutable_appearance/overlay + desc = "A handmade [name]." + overlay = mutable_appearance(icon, "minihandle") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + if(force < 0) + force = 0 + +/obj/item/pickaxe/smithed + name = "pickaxe" + desc = "A pickaxe." + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + icon = 'icons/obj/smith.dmi' + icon_state = "pickaxe" + sharpness = SHARP_POINTY + +/obj/item/pickaxe/smithed/Initialize() + ..() + desc = "A handmade [name]." + var/mutable_appearance/overlay + overlay = mutable_appearance(icon, "stick") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + if(force < 0) + force = 0 + +/obj/item/pickaxe/smithed/attack_self(mob/user) + to_chat(user, "Tool does not have a configureable dig range.") + +/obj/item/shovel/smithed + name = "shovel" + desc = "A shovel." + icon = 'icons/obj/smith.dmi' + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + icon_state = "shovel" + sharpness = SHARP_EDGED //it cuts through the earth + +/obj/item/shovel/smithed/Initialize() + ..() + desc = "A handmade [name]." + var/mutable_appearance/overlay + overlay = mutable_appearance(icon, "shovelhandle") + overlay.appearance_flags = RESET_COLOR + add_overlay(overlay) + if(force < 0) + force = 0 + + +/////////////////////////// +// Spears // +/////////////////////////// + + +/obj/item/melee/smith/twohand/halberd + name = "halberd" + icon_state = "halberd" + w_class = WEIGHT_CLASS_HUGE + overlay_state = "spearhandle" + slot_flags = ITEM_SLOT_BACK + wielded_mult = 2.5 + +/obj/item/melee/smith/twohand/halberd/ComponentInitialize() + . = ..() + AddComponent(/datum/component/jousting) + +/obj/item/melee/smith/twohand/javelin + name = "javelin" + icon_state = "javelin" + overlay_state = "longhandle" + wielded_mult = 1.5 + slot_flags = ITEM_SLOT_BACK + sharpness = SHARP_POINTY + + +/obj/item/melee/smith/twohand/javelin/ComponentInitialize() + . = ..() + AddComponent(/datum/component/jousting) + +/obj/item/melee/smith/twohand/glaive + name = "glaive" + icon_state = "glaive" + overlay_state = "longhandle" + slot_flags = ITEM_SLOT_BACK + wielded_mult = 2 + +/obj/item/melee/smith/twohand/glaive/ComponentInitialize() + . = ..() + AddComponent(/datum/component/jousting) + + +/obj/item/melee/smith/twohand/pike + name = "pike" + icon_state = "pike" + w_class = WEIGHT_CLASS_HUGE + overlay_state = "longhandle" + reach = 2 //yeah ok + slot_flags = ITEM_SLOT_BACK + sharpness = SHARP_POINTY + +////////////////////////// +// Other Melee // +/////////////////////////// + + +/obj/item/melee/smith/hammer//blacksmithing, not warhammer. + name = "hammer" + icon_state = "hammer" + overlay_state = "hammerhandle" + var/qualitymod = 0 + +/obj/item/scythe/smithed //we need to inherit scythecode, but that's about it. + material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + + +/obj/item/melee/smith/cogheadclub + name = "coghead club" + icon_state = "coghead" + item_flags = NEEDS_PERMIT + overlay_state = "stick" + +/obj/item/melee/smith/shortsword + name = "gladius" + force = 9 + item_flags = NEEDS_PERMIT + sharpness = SHARP_EDGED + icon_state = "gladius" + overlay_state = "gladiushilt" + +/obj/item/melee/smith/shortsword/scimitar + name = "scimitar" + sharpness = SHARP_EDGED + icon_state = "scimitar" + overlay_state = "scimitarhilt" + +/obj/item/melee/smith/wakizashi + name = "wakizashi" + sharpness = SHARP_EDGED + force = 7 + item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY + obj_flags = UNIQUE_RENAME + icon_state = "waki" + overlay_state = "wakihilt" + block_parry_data = /datum/block_parry_data/waki + +/datum/block_parry_data/waki //like longbokken but worse reflect + parry_stamina_cost = 6 + parry_time_windup = 0 + parry_time_active = 15 //decent window + parry_time_spindown = 0 + parry_time_perfect = 2 + parry_time_perfect_leeway = 0.75 + parry_imperfect_falloff_percent = 7.5 + parry_efficiency_to_counterattack = 100 + parry_efficiency_considered_successful = 80 + parry_efficiency_perfect = 120 + parry_failed_stagger_duration = 3 SECONDS + parry_data = list(PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 1.9) + +/obj/item/melee/smith/twohand/broadsword + name = "broadsword" + icon_state = "broadsword" + overlay_state = "broadhilt" + wielded_mult = 1.8 + +/obj/item/melee/smith/twohand/zweihander + name = "zweihander" + icon_state = "zwei" + overlay_state = "zweihilt" + total_mass = TOTAL_MASS_MEDIEVAL_WEAPON * 2 + force = 4 + wielded_mult = 3 //affected more by quality. a -1 is 25% less damage, a +1 is 25% more. These bonuses are tripled when wielded. + +/obj/item/melee/smith/twohand/katana + name = "katana" + icon_state = "katana" + overlay_state = "katanahilt" + force = 7 + wielded_mult = 2 + item_flags = ITEM_CAN_PARRY | NEEDS_PERMIT //want to name your katana "DEMON BLADE" or some shit? go ahead, idiot. + obj_flags = UNIQUE_RENAME + block_parry_data = /datum/block_parry_data/captain_saber //todo + +/obj/item/melee/smith/sabre + name = "sabre" + icon_state = "sabre" + sharpness = SHARP_EDGED + overlay_state = "sabrehilt" + armour_penetration = 15 + force = 9 + hitsound = 'sound/weapons/rapierhit.ogg' + item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY + block_parry_data = /datum/block_parry_data/captain_saber //yeah this is fine i guess + +/obj/item/melee/smith/sabre/rapier + name = "rapier" + icon_state = "rapier" + sharpness = SHARP_EDGED + overlay_state = "rapierhilt" + force = 6 //less force, stronger parry + sharpness = SHARP_POINTY + armour_penetration = 30 + block_parry_data = /datum/block_parry_data/smithrapier + +/datum/block_parry_data/smithrapier //parry into riposte. i am pretty sure this is going to be nearly fucking impossible to land. + parry_stamina_cost = 12 //dont miss + parry_time_active = 4 + parry_time_perfect = 2 + parry_time_perfect_leeway = 2 + parry_failed_stagger_duration = 3 SECONDS + parry_failed_clickcd_duration = 3 SECONDS + parry_time_windup = 0 + parry_time_spindown = 0 + parry_imperfect_falloff_percent = 0 + parry_efficiency_to_counterattack = 100 + parry_efficiency_considered_successful = 120 + parry_efficiency_perfect = 120 + parry_data = list(PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN = 4) + +//unique hammers +/obj/item/melee/smith/hammer/toolbox + name = "toolbox hammer" + desc = "A metal filled toolbox on a stick. Useable as a really shitty hammer." + w_class = WEIGHT_CLASS_BULKY + icon_state = "toolbox" + overlay_state = "hammerhandle" + qualitymod = -2 + +/obj/item/melee/smith/hammer/narsie + name = "runemetal hammer" + custom_materials = list(/datum/material/runedmetal = 12000) + desc = "A metal hammer inscribed with geometeric runes." + qualitymod = 1 + +/obj/item/melee/smith/hammer/narsie/attack(mob/living/target, mob/living/carbon/human/user) + if(!iscultist(user)) + user.DefaultCombatKnockdown(100) + user.dropItemToGround(src, TRUE) + user.visible_message("A powerful force shoves [user] away from [target]!", \ + "\"You shouldn't be touching tools that aren't yours.\"") + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.apply_damage(rand(force/2, force), BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + else + user.adjustBruteLoss(rand(force/2,force)) + return + ..() + +/obj/item/melee/smith/hammer/ratvar + name = "brass hammer" + custom_materials = list(/datum/material/bronze = 12000) + desc = "A brass hammer inscribed with... writing? You can't read it." + qualitymod = 1 + +/obj/item/melee/smith/hammer/ratvar/attack(mob/living/target, mob/living/carbon/human/user) + if(!is_servant_of_ratvar(user)) + user.DefaultCombatKnockdown(100) + user.dropItemToGround(src, TRUE) + user.visible_message("A powerful force shoves [user] away from [target]!", "\"You shouldn't be touching tools that aren't yours.\"") + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.apply_damage(rand(force/2, force), BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + else + user.adjustBruteLoss(rand(force/2,force)) + return + ..() + +/obj/item/melee/smith/hammer/debug + name = "debugging hammer" + desc = "A DEBUGGING HAMMER!! EPIC!!." + qualitymod = 10 diff --git a/code/modules/smithing/furnace.dm b/code/modules/smithing/furnace.dm new file mode 100644 index 0000000000..ee1d6a1b93 --- /dev/null +++ b/code/modules/smithing/furnace.dm @@ -0,0 +1,75 @@ +/obj/structure/furnace + name = "furnace" + desc = "A furnace." + icon = 'icons/obj/smith.dmi' + icon_state = "furnace0" + density = TRUE + anchored = TRUE + var/debug = FALSE //debugging only + var/working = TRUE + var/fueluse = 1 + + +/obj/structure/furnace/Initialize() + ..() + create_reagents(250, TRANSPARENT) + START_PROCESSING(SSobj, src) + +/obj/structure/furnace/Destroy() + ..() + STOP_PROCESSING(SSobj, src) + +/obj/structure/furnace/process() + if(debug) + reagents.add_reagent(/datum/reagent/fuel, 1) + return TRUE + if(reagents.remove_reagent(/datum/reagent/fuel, fueluse)) + working = TRUE + if(icon_state == "furnace0") + icon_state = "furnace1" + else + working = FALSE + icon_state = "furnace0" + +/obj/structure/furnace/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/ingot)) + var/obj/item/ingot/notsword = I + if(working) + to_chat(user, "You heat the [notsword] in the [src].") + notsword.workability = "shapeable" + else + to_chat(user, "The furnace isn't working!.") + else + ..() + +/obj/structure/furnace/wrench_act(mob/living/user, obj/item/I) + ..() + default_unfasten_wrench(user, I, 5) + return TRUE + +/obj/structure/furnace/attackby(obj/item/W, mob/user, params) + if(W.reagents) + W.reagents.trans_to(src, 250) + else + return ..() + +/obj/structure/furnace/plunger_act(obj/item/plunger/P, mob/living/user, reinforced) + to_chat(user, "You start furiously plunging [name].") + if(do_after(user, 30, target = src)) + to_chat(user, "You finish plunging the [name].") + reagents.reaction(get_turf(src), TOUCH) //splash on the floor + reagents.clear_reagents() + +/obj/structure/furnace/infinite + name = "fuelless furnace" + debug = TRUE + icon_state = "ratfurnace" + + +/obj/structure/furnace/infinite/ratvar + name = "brass furnace" + desc = "A brass furnace. Powered by... something, but seems otherwise safe." //todo:sprites they're safe for noncultists because you're just putting ingots in them. also there';s a reason to steal them ig + +/obj/structure/furnace/infinite/narsie + name = "rune furnace" + desc = "A runed furnace. Powered by... something, but seems otherwise safe." diff --git a/code/modules/smithing/smithed_items.dm b/code/modules/smithing/smithed_items.dm new file mode 100644 index 0000000000..df30a01f8c --- /dev/null +++ b/code/modules/smithing/smithed_items.dm @@ -0,0 +1,420 @@ +/obj/item/basaltblock + name = "basalt block" + desc = "A block of basalt." + icon = 'icons/obj/smith.dmi' + icon_state = "sandvilnoir" + + +/obj/item/smithing + name = "base class /obj/item/smithing" + icon = 'icons/obj/smith.dmi' + icon_state = "unfinished" + material_flags = MATERIAL_COLOR | MATERIAL_ADD_PREFIX + var/quality = 0 //quality. Changed by the smithing process. + var/obj/item/finishingitem = /obj/item/stick //What this item needs to be hit by to create finalitem + var/obj/item/finalitem + var/artifact = FALSE + +/obj/item/ingot + name = "ingot" + icon = 'icons/obj/smith.dmi' + icon_state = "ingot" + material_flags = MATERIAL_COLOR | MATERIAL_ADD_PREFIX + var/workability = 0 + + +/obj/item/ingot/on_attack_hand(mob/user) + var/mob/living/carbon/human/H + if(workability != "shapeable") + return ..() + var/prot = 0 + if(ishuman(user)) + H = user + if(H.gloves) + var/obj/item/clothing/gloves/G = H.gloves + if(G.max_heat_protection_temperature) + prot = (G.max_heat_protection_temperature > 360) + else + prot = 1 + if(prot > 0 || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) + to_chat(user, "You pick up the [src].") + return ..() + else + to_chat(user, "You try to move the [src], but you burn your hand on it!") + if(H) + var/obj/item/bodypart/affecting = H.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage + H.update_damage_overlays() + +/obj/item/ingot/iron + custom_materials = list(/datum/material/iron=12000) + +/obj/item/ingot/diamond + custom_materials = list(/datum/material/diamond=12000) //yeah ok + +/obj/item/ingot/uranium + custom_materials = list(/datum/material/uranium=12000) + +/obj/item/ingot/plasma + custom_materials = list(/datum/material/plasma=12000)//yeah ok + +/obj/item/ingot/gold + custom_materials = list(/datum/material/gold=12000) + +/obj/item/ingot/silver + custom_materials = list(/datum/material/silver=12000) + +/obj/item/ingot/bananium + custom_materials = list(/datum/material/bananium=12000) + +/obj/item/ingot/titanium + custom_materials = list(/datum/material/titanium=12000) + +/obj/item/ingot/adamantine + custom_materials = list(/datum/material/adamantine=12000) + +/obj/item/ingot/cult + custom_materials = list(/datum/material/runedmetal=12000) + +/obj/item/ingot/bronze + custom_materials = list(/datum/material/bronze=12000) + +/obj/item/ingot/bronze/ratvar + material_flags = MATERIAL_COLOR + name = "brass ingnot" + desc = "On closer inspection, what appears to be wholly-unsuitable-for-smithing brass is actually more structurally stable bronze. Ratvar must have transformed the brass into bronze. Somehow." + + +/obj/item/smithing/attackby(obj/item/I, mob/user) + if(istype(I, finishingitem)) + qdel(I) + startfinish() + else + return ..() + +/obj/item/smithing/proc/startfinish() + dofinish() + +/obj/item/smithing/proc/dofinish() + var/qualname + switch(quality) + if(-1000 to -5) + qualname = "awful" + if(-1000 to -2) + qualname = "shoddy" + if(-1000 to -1) + qualname = "poor" + if(-1 to 1) + qualname = "normal" + if(10 to INFINITY) + qualname = "legendary" + if(7.5 to 10) + qualname = "masterwork" + if(5.5 to 7.5) + qualname = "excellent" + if(3.5 to 5.5) + qualname = "good" + if(0 to 3.5) + qualname = "above-average" + var/datum/material/mat = custom_materials[1] + finalitem.set_custom_materials(custom_materials) + mat = mat.name + if(artifact) + dwarfyartifact(finalitem, mat) + else + finalitem.name = "[qualname] [mat] [initial(finalitem.name)]" + finalitem.desc = "A [qualname] [initial(finalitem.name)]. Its quality is [quality]." + finalitem.forceMove(get_turf(src)) + qdel(src) + + +/obj/item/smithing/proc/dwarfyartifact(var/obj/item/finalitem, var/mat) + var/finaldesc = "A [initial(finalitem.name)] made of [mat], all craftsmanship is of the highest quality. It " + switch(pick(1,2,3,4,5)) + if(1) + finaldesc += "is encrusted with [pick("","synthetic ","multi-faceted ","magical ","sparkling ") + pick("rubies","emeralds","jade","opals","lapiz lazuli")]." + if(2) + finaldesc += "is laced with studs of [pick("gold","silver","aluminium","titanium")]." + if(3) + finaldesc += "is encircled with bands of [pick("durasteel","metallic hydrogen","ferritic-alloy","plasteel","duranium")]." + if(4) + finaldesc += "menaces with spikes of [pick("ytterbium","uranium","white pearl","black steel")]." + if(5) + finaldesc += "is encrusted with [pick("","synthetic ","multi-faceted ","magical ","sparkling ") + pick("rubies","emeralds","jade","opals","lapis lazuli")],laced with studs of [pick("gold","silver","aluminium","titanium")], encircled with bands of [pick("durasteel","metallic hydrogen","ferritic-alloy","plasteel","duranium")] and menaces with spikes of [pick("ytterbium","uranium","white pearl","black steel")]." + finalitem.desc = finaldesc + finalitem.name = pick("Delersibnir", "Nekolangrir", "Zanoreshik","Öntakrítin", "Nogzatan", "Vunomam", "Nazushagsaldôbar", "Sergeb", "Zafaldastot", "Vudnis", "Dostust", "Shotom", "Mugshith", "Angzak", "Oltud", "Deleratîs", "Nökornomal") //one of these is literally BLOOD POOL CREATE.iirc its Nazushagsaldôbar. + +/obj/item/smithing/hammerhead + name = "smithed hammer head" + finalitem = /obj/item/melee/smith/hammer + icon_state = "hammer" + +/obj/item/smithing/hammerhead/startfinish() + var/obj/item/melee/smith/hammer/finalforreal = new /obj/item/melee/smith/hammer(src) + finalforreal.force += quality/2 + finalforreal.qualitymod = quality/4 + finalitem = finalforreal + ..() + + + +/obj/item/smithing/scytheblade + name = "smithed scythe head" + finalitem = /obj/item/scythe/smithed + icon_state = "scythe" + +/obj/item/smithing/scytheblade/startfinish() + finalitem = new /obj/item/scythe/smithed(src) + finalitem.force += quality + ..() + +/obj/item/smithing/shovelhead + name = "smithed shovel head" + finalitem = /obj/item/shovel/smithed + icon_state = "shovel" + +/obj/item/smithing/shovelhead/startfinish() + finalitem = new /obj/item/shovel/smithed(src) + finalitem.force += quality/2 + if(quality > 0) + finalitem.toolspeed = max(0.05,(1-(quality/10))) + else + finalitem.toolspeed *= max(1, (quality * -1)) + ..() + +/obj/item/smithing/cogheadclubhead + name = "smithed coghead club head" + finalitem = /obj/item/melee/smith/cogheadclub + icon_state = "coghead" + +/obj/item/smithing/cogheadclubhead/startfinish() + finalitem = new /obj/item/melee/smith/cogheadclub(src) + finalitem.force += quality + ..() + +/obj/item/smithing/javelinhead + name = "smithed javelin head" + finalitem = /obj/item/melee/smith/twohand/javelin + icon_state = "javelin" + +/obj/item/smithing/javelinhead/startfinish() + var/obj/item/melee/smith/twohand/javelin/finalforreal = new /obj/item/melee/smith/twohand/javelin(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalforreal.throwforce = finalforreal.force*2 + finalitem = finalforreal + ..() + +/obj/item/smithing/pikehead + name = "smithed pike head" + finalitem = /obj/item/melee/smith/twohand/pike + icon_state = "pike" + +/obj/item/smithing/pikehead/startfinish() + var/obj/item/melee/smith/twohand/pike/finalforreal = new /obj/item/melee/smith/twohand/pike(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalforreal.throwforce = finalforreal.force/10 //its a pike not a javelin + finalitem = finalforreal + ..() + +/obj/item/smithing/pickaxehead + name = "smithed pickaxe head" + finalitem = /obj/item/pickaxe/smithed + icon_state = "pickaxe" + +/obj/item/smithing/pickaxehead/startfinish() + var/obj/item/pickaxe/smithed/finalforreal = new /obj/item/pickaxe/smithed(src) + finalforreal.force += quality/2 + if(quality > 0) + finalforreal.toolspeed = max(0.05,(1-(quality/10))) + else + finalforreal.toolspeed *= max(1, (quality * -1)) + switch(quality) + if(10 to INFINITY) + finalforreal.digrange = 4 + if(5 to 9) + finalforreal.digrange = 3 + if(3,4) + finalforreal.digrange = 2 + else + finalforreal.digrange = 1 + finalitem = finalforreal + ..() + + +/obj/item/smithing/prospectingpickhead + name = "smithed prospector's pickaxe head" + finalitem = /obj/item/mining_scanner/prospector + icon_state = "minipick" + +/obj/item/smithing/prospectingpickhead/startfinish() + var/obj/item/mining_scanner/prospector/finalforreal = new /obj/item/mining_scanner/prospector(src) + finalforreal.range = 2 + quality + if(quality) + finalforreal.cooldown = 100/quality + finalitem = finalforreal + ..() + + +/obj/item/smithing/shortswordblade + name = "smithed gladius blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/shortsword + icon_state = "gladius" + +/obj/item/smithing/shortswordblade/startfinish() + finalitem = new /obj/item/melee/smith/shortsword(src) + finalitem.force += quality + ..() + +/obj/item/smithing/scimitarblade + name = "smithed scimitar blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/shortsword/scimitar + icon_state = "scimitar" + +/obj/item/smithing/scimitarblade/startfinish() + finalitem = new /obj/item/melee/smith/shortsword/scimitar(src) + finalitem.force += quality + ..() + +/obj/item/smithing/wakiblade + name = "smithed wakizashi blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/wakizashi + icon_state = "waki" + +/obj/item/smithing/wakiblade/startfinish() + finalitem = new /obj/item/melee/smith/wakizashi(src) + finalitem.force += quality + ..() + +/obj/item/smithing/sabreblade + name = "smithed sabre blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/sabre + icon_state = "sabre" + +/obj/item/smithing/sabreblade/startfinish() + finalitem = new /obj/item/melee/smith/sabre(src) + finalitem.force += quality + ..() + +/obj/item/smithing/rapierblade + name = "smithed rapier blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/sabre/rapier + icon_state = "rapier" + +/obj/item/smithing/rapierblade/startfinish() + finalitem = new /obj/item/melee/smith/sabre/rapier(src) + finalitem.force += quality + ..() + +/obj/item/smithing/knifeblade + name = "smithed knife blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/kitchen/knife + icon_state = "dagger" + +/obj/item/smithing/knifeblade/startfinish() + finalitem = new /obj/item/kitchen/knife(src) + finalitem.force = 4 + quality/2 + finalitem.icon = 'icons/obj/smith.dmi' + finalitem.icon_state = "dagger" + finalitem.name = "dagger" + finalitem.desc = "A dagger." + var/mutable_appearance/overlay = mutable_appearance('icons/obj/smith.dmi', "daggerhilt") + overlay.appearance_flags = RESET_COLOR + finalitem.add_overlay(overlay) + if(finalitem.force < 0) + finalitem.force = 0 + finalitem.material_flags = MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + ..() + +/obj/item/smithing/broadblade + name = "smithed broadsword blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/twohand/broadsword + icon_state = "broadsword" + +/obj/item/smithing/broadblade/startfinish() + var/obj/item/melee/smith/twohand/broadsword/finalforreal = new /obj/item/melee/smith/twohand/broadsword(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalitem = finalforreal + ..() + +/obj/item/smithing/zweiblade + name = "smithed zweihander blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/twohand/zweihander + icon_state = "zwei" + +/obj/item/smithing/zweiblade/startfinish() + var/obj/item/melee/smith/twohand/zweihander/finalforreal = new /obj/item/melee/smith/twohand/zweihander(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalitem = finalforreal + ..() + +/obj/item/smithing/halberdhead + name = "smithed halberd head" + finalitem = /obj/item/melee/smith/twohand/halberd + icon_state = "halberd" + +/obj/item/smithing/halberdhead/startfinish() + var/obj/item/melee/smith/twohand/halberd/finalforreal = new /obj/item/melee/smith/twohand/halberd(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.throwforce = finalforreal.force/3 + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalitem = finalforreal + ..() + +/obj/item/smithing/glaivehead + name = "smithed glaive head" + finalitem = /obj/item/melee/smith/twohand/glaive + icon_state = "glaive" + +/obj/item/smithing/glaive/startfinish() + var/obj/item/melee/smith/twohand/glaive/finalforreal = new /obj/item/melee/smith/twohand/glaive(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.throwforce = finalforreal.force + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalitem = finalforreal + ..() + +/obj/item/smithing/katanablade + name = "smithed katana blade" + finishingitem = /obj/item/swordhandle + finalitem = /obj/item/melee/smith/twohand/katana + icon_state = "katana" + + +/obj/item/smithing/katanablade/startfinish() + var/obj/item/melee/smith/twohand/katana/finalforreal = new /obj/item/melee/smith/twohand/katana(src) + finalforreal.force += quality + finalforreal.wield_force = finalforreal.force*finalforreal.wielded_mult + finalforreal.AddComponent(/datum/component/two_handed, force_unwielded=finalforreal.force, force_wielded=finalforreal.wield_force, icon_wielded="[icon_state]") + finalitem = finalforreal + ..() + +/obj/item/stick + name = "wooden rod" + desc = "It's a rod, suitable for use of a handle of a tool. Also could serve as a weapon, in a pinch." + icon = 'icons/obj/smith.dmi' + icon_state = "stick" + force = 7 + +/obj/item/swordhandle + name = "sword handle" + desc = "It's a crudlely shaped wooden sword hilt." + icon = 'icons/obj/smith.dmi' + icon_state = "shorthilt" diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index c106bd12fc..1a98872463 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/smith.dmi b/icons/obj/smith.dmi new file mode 100644 index 0000000000..a40b9a2b19 Binary files /dev/null and b/icons/obj/smith.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 7bd4824eef..2b31b68243 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -648,6 +648,7 @@ #include "code\datums\skills\_skill.dm" #include "code\datums\skills\_skill_holder.dm" #include "code\datums\skills\_skill_modifier.dm" +#include "code\datums\skills\blacksmithing.dm" #include "code\datums\skills\engineering.dm" #include "code\datums\skills\medical.dm" #include "code\datums\skills\modifiers\job.dm" @@ -3308,6 +3309,10 @@ #include "code\modules\shuttle\shuttle_creation\shuttle_creator_eye.dm" #include "code\modules\shuttle\shuttle_creation\shuttle_creator_overlay.dm" #include "code\modules\shuttle\shuttle_creation\shuttle_upgrades.dm" +#include "code\modules\smithing\anvil.dm" +#include "code\modules\smithing\finished_items.dm" +#include "code\modules\smithing\furnace.dm" +#include "code\modules\smithing\smithed_items.dm" #include "code\modules\spells\spell.dm" #include "code\modules\spells\spell_types\aimed.dm" #include "code\modules\spells\spell_types\area_teleport.dm"