diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 0dbc154ec0b..5f8fc1b3422 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -109,3 +109,9 @@ #define RC_SUPPLY (1<<1) /// [/obj/machinery/requests_console] can relay anonymous information. #define RC_INFO (1<<2) + +/// ORM / Smart hopper point defines +#define BASE_POINT_MULT 0.90 +#define BASE_SHEET_MULT 0.90 +#define POINT_MULT_ADD_PER_RATING 0.10 +#define SHEET_MULT_ADD_PER_RATING 0.10 diff --git a/code/__DEFINES/smith_defines.dm b/code/__DEFINES/smith_defines.dm new file mode 100644 index 00000000000..459faaeae12 --- /dev/null +++ b/code/__DEFINES/smith_defines.dm @@ -0,0 +1,6 @@ +#define PART_PRIMARY 1 +#define PART_SECONDARY 2 +#define PART_TRIM 3 + +#define OPERATION_SPEED_MULT_PER_RATING 0.075 +#define EFFICIENCY_MULT_ADD_PER_RATING 0.05 diff --git a/code/game/machinery/smith_machines.dm b/code/game/machinery/smith_machines.dm deleted file mode 100644 index 0ccf8e51565..00000000000 --- a/code/game/machinery/smith_machines.dm +++ /dev/null @@ -1,1136 +0,0 @@ -#define BASE_POINT_MULT 0.60 -#define BASE_SHEET_MULT 0.60 -#define POINT_MULT_ADD_PER_RATING 0.10 -#define SHEET_MULT_ADD_PER_RATING 0.20 -#define OPERATION_SPEED_MULT_PER_RATING 0.075 -#define EFFICIENCY_MULT_ADD_PER_RATING 0.05 - -/obj/machinery/mineral/smart_hopper - name = "smart hopper" - desc = "An electronic deposit bin that accepts raw ores and delivers them to an adjacent magma crucible." - icon = 'icons/obj/machines/smithing_machines.dmi' - icon_state = "hopper" - anchored = TRUE - density = TRUE - resistance_flags = FIRE_PROOF - /// Linked magma crucible - var/obj/machinery/magma_crucible/linked_crucible - /// Access to claim points - var/req_access_claim = ACCESS_MINING_STATION - /// The number of unclaimed points. - var/points = 0 - /// Point multiplier - var/point_upgrade = 1 - /// List of ore yet to process. - var/list/obj/item/stack/ore/ore_buffer = list() - /// Whether the message to relevant supply consoles was sent already or not for an ore dump. If FALSE, another will be sent. - var/message_sent = TRUE - /// If TRUE, [/obj/machinery/mineral/smart_hopper/var/req_access_claim] is ignored and any ID may be used to claim points. - var/anyone_claim = FALSE - /// What consoles get alerted when this is filled - var/list/supply_consoles = list( - "Smith's Office", - "Quartermaster's Desk" - ) - -/obj/machinery/mineral/smart_hopper/Initialize(mapload) - . = ..() - // Stock parts - component_parts = list() - component_parts += new /obj/item/circuitboard/smart_hopper(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stack/sheet/glass(null) - RefreshParts() - // Try to link to magma crucible on initialize. Link to the first crucible it can find. - for(var/obj/machinery/magma_crucible/crucible in view(2, src)) - linked_crucible = crucible - linked_crucible.linked_machines |= src - return - -/obj/machinery/mineral/smart_hopper/update_overlays() - . = ..() - overlays.Cut() - if(panel_open) - . += "hopper_wires" - -/obj/machinery/mineral/smart_hopper/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - . = ..() - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/mineral/smart_hopper/RefreshParts() - var/point_mult = BASE_POINT_MULT - for(var/obj/item/stock_parts/component in component_parts) - point_mult += POINT_MULT_ADD_PER_RATING * component.rating - // Update our values - point_upgrade = point_mult - SStgui.update_uis(src) - -/obj/machinery/mineral/smart_hopper/process() - if(panel_open || !has_power()) - return - // Check if the input turf has a [/obj/structure/ore_box] to draw ore from. Otherwise suck ore from the turf - var/atom/input = get_step(src, input_dir) - var/obj/structure/ore_box/OB = locate() in input - if(OB) - input = OB - // Suck the ore in - for(var/obj/item/stack/ore/ore in input) - if(QDELETED(ore)) - continue - ore_buffer |= ore - ore.forceMove(src) - CHECK_TICK - // Process it - if(length(ore_buffer)) - message_sent = FALSE - process_ores(ore_buffer) - else if(!message_sent) - send_console_message() - message_sent = TRUE - -// Interactions -/obj/machinery/mineral/smart_hopper/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(istype(used, /obj/item/storage/part_replacer)) - return ..() - - if(!has_power()) - return ..() - - if(istype(used, /obj/item/card/id)) - var/obj/item/card/id/ID = used - if(!points) - to_chat(user, "There are no points to claim."); - return ITEM_INTERACT_COMPLETE - if(anyone_claim || (req_access_claim in ID.access)) - ID.mining_points += points - ID.total_mining_points += points - to_chat(user, "[points] Mining Points claimed. You have earned a total of [ID.total_mining_points] Mining Points this Shift!") - points = 0 - else - to_chat(user, "Required access not found.") - add_fingerprint(user) - return ITEM_INTERACT_COMPLETE - return ..() - -/obj/machinery/mineral/smart_hopper/multitool_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(!I.multitool_check_buffer(user)) - return - if(panel_open) - var/obj/item/multitool/multi = I - if(!istype(multi.buffer, /obj/machinery/magma_crucible)) - to_chat(user, "You cannot link [src] to [multi.buffer]!") - return - linked_crucible = multi.buffer - linked_crucible.linked_machines |= src - to_chat(user, "You link [src] to [multi.buffer].") - -/obj/machinery/mineral/smart_hopper/crowbar_act(mob/user, obj/item/I) - if(default_deconstruction_crowbar(user, I)) - return TRUE - -/obj/machinery/mineral/smart_hopper/screwdriver_act(mob/user, obj/item/I) - if(!I.use_tool(src, user, 0, volume = 0)) - return - . = TRUE - default_deconstruction_screwdriver(user, icon_state, icon_state, I) - -/obj/machinery/mineral/smart_hopper/wrench_act(mob/living/user, obj/item/I) - if(!panel_open) - return - . = TRUE - if(!has_power()) - return - if(!I.tool_start_check(src, user, 0)) - return - input_dir = turn(input_dir, -90) - to_chat(user, "You change [src]'s input, moving the input to [dir2text(input_dir)].") - -/obj/machinery/mineral/smart_hopper/Destroy() - if(linked_crucible) - linked_crucible.linked_machines -= src - linked_crucible = null - if(ore_buffer) - for(var/obj/item/ores in ore_buffer) - ores.forceMove(src.loc) - return ..() - -/obj/machinery/mineral/smart_hopper/proc/process_ores(list/obj/item/stack/ore/ore_list) - if(!linked_crucible) - return - for(var/ore in ore_list) - transfer_ore(ore) - -/obj/machinery/mineral/smart_hopper/proc/transfer_ore(obj/item/stack/ore/O) - if(!linked_crucible) - return - // Award points if the ore is actually transferable to the magma crucible - give_points(O.type, O.amount) - animate_transfer(O.amount) - // Insert materials - var/datum/component/material_container/materials = linked_crucible.GetComponent(/datum/component/material_container) - var/amount_compatible = materials.get_item_material_amount(O) - if(amount_compatible) - // Prevents duping - if(O.refined_type) - materials.insert_item(O, linked_crucible.sheet_per_ore) - else - materials.insert_item(O, 1) - // Delete the stack - ore_buffer -= O - qdel(O) - -/obj/machinery/mineral/smart_hopper/proc/send_console_message() - if(!is_station_level(z)) - return - - var/list/msg = list("Now available in [get_area_name(src, TRUE) || "Unknown"]:") - var/mats_in_stock = list() - var/datum/component/material_container/materials = linked_crucible.GetComponent(/datum/component/material_container) - for(var/MAT in materials.materials) - var/datum/material/M = materials.materials[MAT] - var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT - if(mineral_amount) - mats_in_stock += M.id - msg.Add("[capitalize(M.name)]: [mineral_amount] sheets") - - // No point sending a message if we're dry - if(!length(mats_in_stock)) - return - - // Notify - for(var/obj/machinery/requests_console/console as anything in GLOB.allRequestConsoles) - if(!(console.department in supply_consoles)) - continue - if(!supply_consoles[console.department] || length(supply_consoles[console.department] - mats_in_stock)) - console.createMessage("Smart Hopper", "New Minerals Available!", msg, RQ_LOWPRIORITY) - -/obj/machinery/mineral/smart_hopper/proc/give_points(obj/item/stack/ore/ore_path, ore_amount) - if(initial(ore_path.refined_type)) - points += initial(ore_path.points) * point_upgrade * ore_amount - -/obj/machinery/mineral/smart_hopper/proc/animate_transfer(ore_amount) - icon_state = "hopper_on" - var/time_to_animate = max(ore_amount * 2, 1 SECONDS) - addtimer(VARSET_CALLBACK(src, icon_state, "hopper"), time_to_animate) - linked_crucible.animate_transfer(time_to_animate) - -/obj/machinery/magma_crucible - name = "magma crucible" - desc = "A massive machine that smelts down raw ore into a fine slurry, then sorts it into respective tanks for storage and use." - icon = 'icons/obj/machines/magma_crucible.dmi' - icon_state = "crucible" - max_integrity = 300 - pixel_x = -32 // 3x3 - pixel_y = -32 - bound_width = 96 - bound_x = -32 - bound_height = 96 - bound_y = -32 - anchored = TRUE - density = TRUE - resistance_flags = FIRE_PROOF - /// Sheet multiplier applied when smelting ore. - var/sheet_per_ore = 1 - /// State for adding ore - var/adding_ore - /// State for if ore is being taken from it - var/pouring - /// List of linked machines - var/list/linked_machines = list() - -/obj/machinery/magma_crucible/Initialize(mapload) - . = ..() - AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE, MAT_PALLADIUM, MAT_IRIDIUM, MAT_PLATINUM, MAT_BRASS), INFINITY, FALSE, list(/obj/item/stack, /obj/item/smithed_item), null, null) - // Stock parts - component_parts = list() - component_parts += new /obj/item/circuitboard/magma_crucible(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/assembly/igniter(null) - RefreshParts() - -/obj/machinery/magma_crucible/screwdriver_act(mob/user, obj/item/I) - if(!I.use_tool(src, user, 0, volume = 0)) - return - . = TRUE - default_deconstruction_screwdriver(user, icon_state, icon_state, I) - -/obj/machinery/magma_crucible/crowbar_act(mob/user, obj/item/I) - if(default_deconstruction_crowbar(user, I)) - return TRUE - -/obj/machinery/magma_crucible/RefreshParts() - var/sheet_mult = BASE_SHEET_MULT - for(var/obj/item/stock_parts/micro_laser/component in component_parts) - sheet_mult += SHEET_MULT_ADD_PER_RATING * component.rating - // Update our values - sheet_per_ore = sheet_mult - -/obj/machinery/magma_crucible/update_overlays() - . = ..() - overlays.Cut() - if(adding_ore) - . += "crucible_input" - if(panel_open) - . += "crucible_wires" - if(pouring) - . += "crucible_output" - -/obj/machinery/magma_crucible/update_icon_state() - . = ..() - if(!has_power()) - icon_state = "[initial(icon_state)]_off" - else - icon_state = initial(icon_state) - -/obj/machinery/magma_crucible/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - . = ..() - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/magma_crucible/Destroy() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.retrieve_all() - for(var/obj/machinery/machine in linked_machines) - if(istype(machine, /obj/machinery/mineral/smart_hopper)) - var/obj/machinery/mineral/smart_hopper/hopper = machine - hopper.linked_crucible = null - if(istype(machine, /obj/machinery/smithing/casting_basin)) - var/obj/machinery/smithing/casting_basin/basin = machine - basin.linked_crucible = null - linked_machines.Cut() - return ..() - -/obj/machinery/magma_crucible/power_change() - if(!..()) - return - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/magma_crucible/proc/animate_transfer(time_to_animate) - adding_ore = TRUE - update_icon(UPDATE_OVERLAYS) - addtimer(CALLBACK(src, PROC_REF(stop_animating)), time_to_animate) - -/obj/machinery/magma_crucible/proc/stop_animating() - adding_ore = FALSE - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/magma_crucible/proc/animate_pour(time_to_animate) - pouring = TRUE - update_icon(UPDATE_OVERLAYS) - addtimer(CALLBACK(src, PROC_REF(stop_pouring)), time_to_animate) - -/obj/machinery/magma_crucible/proc/stop_pouring() - pouring = FALSE - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/magma_crucible/multitool_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(panel_open) - if(!I.multitool_check_buffer(user)) - return - var/obj/item/multitool/multi = I - multi.set_multitool_buffer(user, src) - to_chat(user, "You save [src]'s linking data to the buffer.") - return - - var/list/msgs = list() - msgs += "Scanning contents of [src]:" - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - for(var/MAT in materials.materials) - var/datum/material/M = materials.materials[MAT] - if(!M) - continue - msgs += "[M.name]: [floor(M.amount / MINERAL_MATERIAL_AMOUNT)] sheets." - to_chat(user, chat_box_regular(msgs.Join("
"))) - -/obj/machinery/smithing - name = "smithing machine" - desc = "A large unknown smithing machine. If you see this, there's a problem and you should notify the development team." - icon = 'icons/obj/machines/large_smithing_machines.dmi' - icon_state = "power_hammer" - max_integrity = 200 - pixel_x = 0 // 2x2 - pixel_y = -32 - bound_height = 64 - bound_width = 64 - bound_y = -32 - anchored = TRUE - density = TRUE - resistance_flags = FIRE_PROOF - /// How many loops per operation - var/operation_time = 10 - /// Is this active - var/operating = FALSE - /// Cooldown on harming - var/special_attack_cooldown = 10 SECONDS - /// Are we on harm cooldown - var/special_attack_on_cooldown = FALSE - /// Store the worked component - var/obj/item/smithed_item/component/working_component - /// The noise the machine makes when operating - var/operation_sound - /// Will the machine auto-repeat? - var/repeating = FALSE - -/obj/machinery/smithing/examine(mob/user) - . = ..() - if(working_component) - . += "You can activate the machine with your hand, or remove the component by alt-clicking." - -/obj/machinery/smithing/power_change() - if(!..()) - return - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/smithing/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(istype(used, /obj/item/grab)) - var/obj/item/grab/G = used - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "Putting [G.affecting] in [src] might hurt them!") - return ITEM_INTERACT_COMPLETE - special_attack_grab(G, user) - return ITEM_INTERACT_COMPLETE - - if(operating) - to_chat(user, "[src] is still operating!") - return FINISH_ATTACK - - if(istype(used, /obj/item/smithed_item/component)) - if(working_component) - to_chat(user, "There is already a component in the machine!") - return ITEM_INTERACT_COMPLETE - - if(used.flags & NODROP || !user.drop_item() || !used.forceMove(src)) - to_chat(user, "[used] is stuck to your hand!") - return ITEM_INTERACT_COMPLETE - - working_component = used - return ITEM_INTERACT_COMPLETE - return ..() - -/obj/machinery/smithing/proc/operate(loops, mob/living/user) - operating = TRUE - update_icon(ALL) - for(var/i in 1 to loops) - if(stat & (NOPOWER|BROKEN)) - return FALSE - use_power(500) - if(operation_sound) - playsound(src, operation_sound, 50, TRUE) - sleep(1 SECONDS) - playsound(src, 'sound/machines/recycler.ogg', 50, FALSE) - operating = FALSE - update_icon(ALL) - -/obj/machinery/smithing/proc/special_attack_grab(obj/item/grab/G, mob/user) - if(special_attack_on_cooldown) - return FALSE - if(!istype(G)) - return FALSE - if(!iscarbon(G.affecting)) - to_chat(user, "You can't shove that in there!") - return FALSE - if(G.state < GRAB_NECK) - to_chat(user, "You need a better grip to do that!") - return FALSE - var/result = special_attack(user, G.affecting) - user.changeNext_move(CLICK_CD_MELEE) - special_attack_on_cooldown = TRUE - addtimer(VARSET_CALLBACK(src, special_attack_on_cooldown, FALSE), special_attack_cooldown) - if(result && !QDELETED(G)) - qdel(G) - - return TRUE - -/obj/machinery/smithing/proc/special_attack(mob/user, mob/living/target) - return - -/obj/machinery/smithing/AltClick(mob/living/user) - . = ..() - if(!Adjacent(user)) - return - if(!working_component) - to_chat(user, "There isn't anything in [src].") - return - if(operating) - to_chat(user, "[src] is currently operating!") - return - if(working_component.burn_check(user)) - working_component.burn_user(user) - working_component.forceMove(user.loc) - working_component = null - return - user.put_in_hands(working_component) - working_component = null - -/obj/machinery/smithing/screwdriver_act(mob/user, obj/item/I) - if(!I.use_tool(src, user, 0, volume = 0)) - return - . = TRUE - if(operating) - to_chat(user, "[src] is busy. Please wait for completion of previous operation.") - return - default_deconstruction_screwdriver(user, icon_state, icon_state, I) - -/obj/machinery/smithing/crowbar_act(mob/user, obj/item/I) - if(default_deconstruction_crowbar(user, I)) - return TRUE - -/obj/machinery/smithing/casting_basin - name = "casting basin" - desc = "A table with a large basin for pouring molten metal. It has a slot for a mold." - icon = 'icons/obj/machines/smithing_machines.dmi' - icon_state = "casting_open" - max_integrity = 100 - pixel_x = 0 // 1x1 - pixel_y = 0 - bound_height = 32 - bound_width = 32 - bound_y = 0 - /// Linked magma crucible - var/obj/machinery/magma_crucible/linked_crucible - /// Operational Efficiency - var/efficiency = 1 - /// Inserted cast - var/obj/item/smithing_cast/cast - /// Finished product - var/obj/item/smithed_item/component/produced_item - -/obj/machinery/smithing/casting_basin/Initialize(mapload) - . = ..() - // Stock parts - component_parts = list() - component_parts += new /obj/item/circuitboard/casting_basin(null) - component_parts += new /obj/item/stock_parts/matter_bin(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stack/sheet/glass(null) - RefreshParts() - // Try to link to magma crucible on initialize. Link to the first crucible it can find. - for(var/obj/machinery/magma_crucible/crucible in view(2, src)) - linked_crucible = crucible - linked_crucible.linked_machines |= src - return - -/obj/machinery/smithing/casting_basin/examine(mob/user) - . = ..() - if(cast) - . += "You can activate the machine with your hand, or remove the cast by alt-clicking." - . += "There is a [cast] in the cast slot." - . += "Currently set to produce: [cast.selected_product.name]" - if(istype(cast, /obj/item/smithing_cast/component) && !produced_item) - var/obj/item/temp_product = new cast.selected_product(src) // This is necessary due to selected_product being a type - var/obj/item/smithing_cast/component/comp_cast = cast - var/datum/smith_quality/quality = new comp_cast.quality - . += "Required Resources:" - var/MAT - // Get the materials the item needs and display - for(MAT in temp_product.materials) - . += " - [MAT]: [ROUND_UP(((temp_product.materials[MAT] * quality.material_mult) * efficiency) / MINERAL_MATERIAL_AMOUNT)] sheets." - // Get rid of the temp product - qdel(temp_product) - - if(produced_item) - . += "There is a [produced_item] in the machine. You can pick it up with your hand." - -/obj/machinery/smithing/casting_basin/RefreshParts() - var/operation_mult = 0 - var/efficiency_mult = 0 - for(var/obj/item/stock_parts/component in component_parts) - operation_mult += 2 * OPERATION_SPEED_MULT_PER_RATING * component.rating - efficiency_mult += EFFICIENCY_MULT_ADD_PER_RATING * component.rating - // Update our values - operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) - efficiency = initial(efficiency) * (1.1 - efficiency_mult) - -/obj/machinery/smithing/casting_basin/update_overlays() - . = ..() - overlays.Cut() - if(produced_item) - . += "casting_closed" - if(cast && !produced_item) - if(istype(cast, /obj/item/smithing_cast/sheet)) - . += "cast_sheet" - else if(istype(cast, /obj/item/smithing_cast/component/insert_frame)) - . += "cast_armorframe" - else if(istype(cast, /obj/item/smithing_cast/component/insert_lining)) - . += "cast_mesh" - else if(istype(cast, /obj/item/smithing_cast/component/bit_mount)) - . += "cast_bitmount" - else if(istype(cast, /obj/item/smithing_cast/component/bit_head)) - . += "cast_bithead" - else if(istype(cast, /obj/item/smithing_cast/component/lens_focus)) - . += "cast_focus" - else if(istype(cast, /obj/item/smithing_cast/component/lens_frame)) - . += "cast_lens" - else if(istype(cast, /obj/item/smithing_cast/component/trim)) - . += "cast_trim" - . += "casting_lip" - if(panel_open) - . += "casting_wires" - if(operating) - . += "casting_pour" - -/obj/machinery/smithing/casting_basin/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - . = ..() - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/smithing/casting_basin/multitool_act(mob/living/user, obj/item/I) - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(!I.multitool_check_buffer(user)) - return - if(panel_open) - var/obj/item/multitool/multi = I - if(!istype(multi.buffer, /obj/machinery/magma_crucible)) - to_chat(user, "You cannot link [src] to [multi.buffer]!") - return - linked_crucible = multi.buffer - linked_crucible.linked_machines |= src - to_chat(user, "You link [src] to [multi.buffer].") - -/obj/machinery/smithing/casting_basin/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(!istype(used, /obj/item/smithing_cast)) - to_chat(user, "[used] does not fit in [src]'s cast slot.") - return - - if(cast) - to_chat(user, "[src] already has a cast inserted.") - return - - if(used.flags & NODROP || !user.transfer_item_to(used, src)) - to_chat(user, "[used] is stuck to your hand!") - return ITEM_INTERACT_COMPLETE - cast = used - update_icon(UPDATE_OVERLAYS) - return ITEM_INTERACT_COMPLETE - -/obj/machinery/smithing/casting_basin/AltClick(mob/living/user) - if(!Adjacent(user)) - return - if(!cast) - to_chat(user, "There is no cast to remove.") - return - if(operating) - to_chat(user, "[src] is currently operating!") - return - user.put_in_hands(cast) - cast = null - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/smithing/casting_basin/attack_hand(mob/user) - if(produced_item) - if(produced_item.burn_check(user)) - produced_item.burn_user(user) - produced_item.forceMove(user.loc) - produced_item = null - return FINISH_ATTACK - user.put_in_hands(produced_item) - produced_item = null - update_icon(UPDATE_OVERLAYS) - return FINISH_ATTACK - if(!cast) - to_chat(user, "There is no cast inserted!") - return FINISH_ATTACK - if(!linked_crucible) - to_chat(user, "There is no linked magma crucible!") - return FINISH_ATTACK - if(operating) - to_chat(user, "[src] is currently operating!") - return FINISH_ATTACK - - var/datum/component/material_container/materials = linked_crucible.GetComponent(/datum/component/material_container) - var/obj/item/temp_product = new cast.selected_product // Product is stored as a type, I need a temporary item for handling material calcs - var/amount = cast.amount_to_make - var/MAT - - if(!istype(temp_product)) - to_chat(user, "The product is not an item! This is a problem you should make an issue report about!") - log_debug("Attempted to make [temp_product] at a casting basin, product is not an item.") - return FINISH_ATTACK - - if(istype(cast, /obj/item/smithing_cast/component)) - var/obj/item/smithing_cast/component/comp_cast = cast - var/datum/smith_quality/quality = new comp_cast.quality - var/list/used_mats = list() - - // Check if there is enough materials to craft the item - for(MAT in temp_product.materials) - used_mats[MAT] = (temp_product.materials[MAT] * quality.material_mult) * efficiency - - if(!materials.has_materials(used_mats, 1)) - to_chat(user, "Not enough materials in the crucible to smelt [temp_product.name]!") - qdel(temp_product) - return FINISH_ATTACK - - to_chat(user, "You begin to pour the liquid minerals into the [src]...") - // Use the materials and create the item. - materials.use_amount(used_mats) - linked_crucible.animate_pour(operation_time SECONDS) - operate(operation_time, user) - produced_item = new cast.selected_product(src) - produced_item.quality = quality - produced_item.set_worktime() - produced_item.update_appearance(UPDATE_NAME) - produced_item.update_icon(UPDATE_ICON_STATE) - update_icon(UPDATE_OVERLAYS) - // Clean up temps - qdel(temp_product) - return FINISH_ATTACK - - if(istype(cast, /obj/item/smithing_cast/sheet)) - // Get max amount of sheets (0-50) - var/datum/material/M - var/stored - - // Check if there is enough materials to craft the item - for(MAT in temp_product.materials) - M = materials.materials[MAT] - if(!stored) - stored = M.amount / MINERAL_MATERIAL_AMOUNT - else - stored = min(M.amount / MINERAL_MATERIAL_AMOUNT, stored) - if(istype(cast, /obj/item/smithing_cast/sheet)) - amount = min(amount, stored, MAX_STACK_SIZE) - if(!amount) - to_chat(user, "Not enough materials in the crucible to smelt a sheet of [temp_product.name]!") - qdel(temp_product) - return FINISH_ATTACK - - to_chat(user, "You begin to pour the liquid minerals into the [src]...") - playsound(src, 'sound/machines/recycler.ogg', 50, TRUE) - // Use the materials and create the item. - materials.use_amount(temp_product.materials, amount) - linked_crucible.animate_pour(operation_time SECONDS) - operate(operation_time, user) - var/obj/item/stack/new_stack = new cast.selected_product(src.loc) - new_stack.amount = amount - new_stack.update_icon(UPDATE_ICON_STATE) - - // Clean up temps - qdel(temp_product) - return FINISH_ATTACK - -/obj/machinery/smithing/casting_basin/Destroy() - if(linked_crucible) - linked_crucible.linked_machines -= src - linked_crucible = null - return ..() - -/obj/machinery/smithing/power_hammer - name = "power hammer" - desc = "A heavy-duty pneumatic hammer designed to shape and mold molten metal." - icon = 'icons/obj/machines/large_smithing_machines.dmi' - icon_state = "power_hammer" - operation_sound = 'sound/magic/fellowship_armory.ogg' - -/obj/machinery/smithing/power_hammer/Initialize(mapload) - . = ..() - // Stock parts - component_parts = list() - component_parts += new /obj/item/circuitboard/power_hammer(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stack/sheet/plasteel(null) - RefreshParts() - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/smithing/power_hammer/update_overlays() - . = ..() - overlays.Cut() - if(operating) - . += "hammer_hit" - else - . += "hammer_idle" - if(panel_open) - . += "hammer_wires" - if(has_power()) - . += "hammer_fan_on" - -/obj/machinery/smithing/power_hammer/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - . = ..() - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/smithing/power_hammer/RefreshParts() - var/operation_mult = 0 - for(var/obj/item/stock_parts/component in component_parts) - operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating - // Update our values - operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) - -/obj/machinery/smithing/power_hammer/operate(loops, mob/living/user) - if(!working_component.hot) - to_chat(user, "[working_component] is too cold to properly shape.") - return - if(working_component.hammer_time <= 0) - to_chat(user, "[working_component] is already fully shaped.") - return - ..() - working_component.powerhammer() - do_sparks(5, TRUE, src) - // If the hammer is set to repeat mode, let it repeat operations automatically. - if(repeating && working_component.hot && working_component.hammer_time) - operate(loops, user) - // When an item is done, beep. - if(!working_component.hammer_time) - playsound(src, 'sound/machines/boop.ogg', 50, TRUE) - -/obj/machinery/smithing/power_hammer/multitool_act(mob/living/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - if(!repeating) - repeating = TRUE - to_chat(user, "You set [src] to auto-repeat.") - else - repeating = FALSE - to_chat(user, "You set [src] to not auto-repeat.") - -/obj/machinery/smithing/power_hammer/attack_hand(mob/user) - . = ..() - if(operating) - to_chat(user, "[src] is currently operating!") - return - operate(operation_time, user) - update_icon(UPDATE_ICON_STATE) - return FINISH_ATTACK - -/obj/machinery/smithing/power_hammer/special_attack(mob/user, mob/living/target) - var/obj/item/organ/external/head/head = target.get_organ(BODY_ZONE_HEAD) - if(!istype(head)) - to_chat(user, "This person doesn't have a head!") - return FALSE - target.visible_message("[user] hammers [target]'s head with [src]!", \ - "[user] hammers your head with [src]! Did somebody get the license plate on that car?") - var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, attack_flag = MELEE, armour_penetration_percentage = 50) - target.apply_damage(40, BRUTE, BODY_ZONE_HEAD, armor) - target.Weaken(4 SECONDS) - target.emote("scream") - playsound(src, operation_sound, 50, TRUE) - add_attack_logs(user, target, "Hammered with [src]") - return TRUE - -/obj/machinery/smithing/lava_furnace - name = "lava furnace" - desc = "A furnace that uses the innate heat of lavaland to reheat metal that has not been fully reshaped." - icon = 'icons/obj/machines/large_smithing_machines.dmi' - icon_state = "furnace_off" - operation_sound = 'sound/surgery/cautery1.ogg' - -/obj/machinery/smithing/lava_furnace/Initialize(mapload) - . = ..() - // Stock parts - component_parts = list() - component_parts += new /obj/item/circuitboard/lava_furnace(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/assembly/igniter(null) - RefreshParts() - -/obj/machinery/smithing/lava_furnace/RefreshParts() - var/operation_mult = 0 - for(var/obj/item/stock_parts/component in component_parts) - operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating - // Update our values - operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) - -/obj/machinery/smithing/lava_furnace/update_overlays() - . = ..() - overlays.Cut() - if(panel_open) - . += "furnace_wires" - -/obj/machinery/smithing/lava_furnace/update_icon_state() - . = ..() - if(operating) - icon_state = "furnace" - else - icon_state = "furnace_off" - -/obj/machinery/smithing/lava_furnace/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - . = ..() - update_icon(UPDATE_OVERLAYS) - -/obj/machinery/smithing/lava_furnace/operate(loops, mob/living/user) - if(working_component.hot) - to_chat(user, "[working_component] is already well heated.") - return - if(working_component.hammer_time <= 0) - to_chat(user, "[working_component] is already fully shaped.") - return - ..() - working_component.heat_up() - -/obj/machinery/smithing/lava_furnace/attack_hand(mob/user) - . = ..() - if(operating) - to_chat(user, "[src] is currently operating!") - return - if(!working_component) - to_chat(user, "There is nothing in [src]!") - return - - operate(operation_time, user) - return FINISH_ATTACK - -/obj/machinery/smithing/lava_furnace/special_attack(mob/user, mob/living/target) - var/obj/item/organ/external/head/head = target.get_organ(BODY_ZONE_HEAD) - if(!istype(head)) - to_chat(user, "This person doesn't have a head!") - return FALSE - target.visible_message("[user] pushes [target]'s head into [src]!", \ - "[user] pushes your head into [src]! The heat is agonizing!") - var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, attack_flag = MELEE, armour_penetration_percentage = 50) - target.apply_damage(40, BURN, BODY_ZONE_HEAD, armor) - target.adjust_fire_stacks(5) - target.IgniteMob() - target.emote("scream") - playsound(src, operation_sound, 50, TRUE) - add_attack_logs(user, target, "Burned with [src]") - return TRUE - -#define PART_PRIMARY 1 -#define PART_SECONDARY 2 -#define PART_TRIM 3 - -/obj/machinery/smithing/kinetic_assembler - name = "kinetic assembler" - desc = "A smart assembler that takes components and combines them at the strike of a hammer." - icon = 'icons/obj/machines/smithing_machines.dmi' - icon_state = "assembler" - max_integrity = 100 - pixel_x = 0 // 1x1 - pixel_y = 0 - bound_height = 32 - bound_width = 32 - bound_y = 0 - operation_sound = 'sound/items/welder.ogg' - /// Primary component - var/obj/item/smithed_item/component/primary - /// Secondary component - var/obj/item/smithed_item/component/secondary - /// Trim component - var/obj/item/smithed_item/component/trim - /// Finished product - var/obj/item/smithed_item/finished_product - -/obj/machinery/smithing/kinetic_assembler/Initialize(mapload) - . = ..() - // Stock parts - component_parts = list() - component_parts += new /obj/item/circuitboard/kinetic_assembler(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/manipulator(null) - component_parts += new /obj/item/stock_parts/micro_laser(null) - component_parts += new /obj/item/stack/sheet/glass(null) - RefreshParts() - -/obj/machinery/smithing/kinetic_assembler/examine(mob/user) - . = ..() - if(primary || secondary || trim) - . += "You can activate the machine with your hand, or remove a component by alt-clicking." - if(primary) - . += "There is a [primary] in the primary slot." - if(secondary) - . += "There is a [secondary] in the primary slot." - if(trim) - . += "There is a [trim] in the primary slot." - if(finished_product) - . += "There is a nearly-complete [finished_product] on the assembler. To complete the product, strike it with your hammer!" - -/obj/machinery/smithing/kinetic_assembler/RefreshParts() - var/operation_mult = 0 - for(var/obj/item/stock_parts/component in component_parts) - operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating - // Update our values - operation_time = operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) - -/obj/machinery/smithing/kinetic_assembler/update_icon_state() - . = ..() - if(panel_open) - icon_state = "assembler_wires" - -/obj/machinery/smithing/kinetic_assembler/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) - . = ..() - update_icon(UPDATE_ICON_STATE) - -/obj/machinery/smithing/kinetic_assembler/update_overlays() - . = ..() - overlays.Cut() - if(panel_open) - icon_state = "assembler_wires" - -/obj/machinery/smithing/kinetic_assembler/AltClick(mob/living/user) - if(!Adjacent(user)) - return - if(!primary && !secondary && !trim) - to_chat(user, "There is no component to remove.") - return - var/list/components = list("Primary", "Secondary", "Trim") - var/removed = tgui_input_list(user, "Select a component to remove", src, components) - if(!removed) - return - switch(removed) - if("Primary") - to_chat(user, "You remove [primary] from the primary component slot of [src].") - if(primary.burn_check(user)) - primary.burn_user(user) - primary.forceMove(user.loc) - primary = null - return - user.put_in_hands(primary) - primary = null - return - if("Secondary") - to_chat(user, "You remove [secondary] from the secondary component slot of [src].") - if(secondary.burn_check(user)) - secondary.burn_user(user) - secondary.forceMove(user.loc) - secondary = null - return - user.put_in_hands(secondary) - secondary = null - return - if("Trim") - to_chat(user, "You remove [trim] from the trim component slot of [src].") - if(trim.burn_check(user)) - trim.burn_user(user) - trim.forceMove(user.loc) - trim = null - return - user.put_in_hands(trim) - trim = null - return - -/obj/machinery/smithing/kinetic_assembler/item_interaction(mob/living/user, obj/item/used, list/modifiers) - if(operating) - to_chat(user, "[src] is still operating!") - return ITEM_INTERACT_COMPLETE - - if(istype(used, /obj/item/hammer)) - return ITEM_INTERACT_COMPLETE - - if(!istype(used, /obj/item/smithed_item/component)) - to_chat(user, "You feel like there's no reason to process [used].") - return ITEM_INTERACT_COMPLETE - - if(finished_product) - to_chat(user, "There is an almost finished [finished_product] in [src]!") - return ITEM_INTERACT_COMPLETE - - var/obj/item/smithed_item/component/comp = used - if(comp.hammer_time) - to_chat(user, "[used] is not complete yet!") - return ITEM_INTERACT_COMPLETE - - if(comp.part_type == PART_PRIMARY) - if(primary) - to_chat(user, "You remove [primary] from the primary component slot of [src].") - primary.forceMove(src.loc) - primary = null - if(comp.flags & NODROP || !user.transfer_item_to(used, src)) - to_chat(user, "[comp] is stuck to your hand!") - return ITEM_INTERACT_COMPLETE - to_chat(user, "You insert [comp] into the primary component slot of [src].") - primary = comp - return ITEM_INTERACT_COMPLETE - - if(comp.part_type == PART_SECONDARY) - if(secondary) - to_chat(user, "You remove [secondary] from the secondary component slot of [src].") - secondary.forceMove(src.loc) - secondary = null - if(comp.flags & NODROP || !user.transfer_item_to(used, src)) - to_chat(user, "[comp] is stuck to your hand!") - return ITEM_INTERACT_COMPLETE - to_chat(user, "You insert [comp] into the secondary component slot of [src].") - secondary = comp - return ITEM_INTERACT_COMPLETE - - if(comp.part_type == PART_TRIM) - if(trim) - to_chat(user, "You remove [trim] from the trim component slot of [src].") - trim.forceMove(src.loc) - trim = null - if(comp.flags & NODROP || !user.transfer_item_to(used, src)) - to_chat(user, "[comp] is stuck to your hand!") - return ITEM_INTERACT_COMPLETE - to_chat(user, "You insert [comp] into the trim component slot of [src].") - trim = comp - return ITEM_INTERACT_COMPLETE - -/obj/machinery/smithing/kinetic_assembler/attack_hand(mob/user) - if(!primary) - to_chat(user, "[src] lacks a primary component!") - return FINISH_ATTACK - - if(!secondary) - to_chat(user, "[src] lacks a secondary component!") - return FINISH_ATTACK - - if(!trim) - to_chat(user, "[src] lacks a trim component!") - return FINISH_ATTACK - - if(primary.finished_product != secondary.finished_product) - to_chat(user, "[primary] does not match [secondary]!") - return FINISH_ATTACK - - operate(operation_time, user) - return FINISH_ATTACK - -/obj/machinery/smithing/kinetic_assembler/operate(loops, mob/living/user) - ..() - finished_product = new primary.finished_product(src) - var/quality_list = list(primary.quality, secondary.quality, trim.quality) - var/datum/smith_quality/lowest = quality_list[1] - for(var/datum/smith_quality/quality in quality_list) - if(quality.stat_mult < lowest.stat_mult) - lowest = quality - finished_product.quality = lowest - finished_product.material = trim.material - finished_product.set_stats() - finished_product.update_appearance(UPDATE_NAME) - qdel(primary) - qdel(secondary) - qdel(trim) - primary = null - secondary = null - trim = null - -/obj/machinery/smithing/kinetic_assembler/hammer_act(mob/user, obj/item/i) - if(operating) - to_chat(user, "[src] is still operating!") - return - if(!finished_product) - to_chat(user, "There is no finished product ready!") - return - playsound(src, 'sound/magic/fellowship_armory.ogg', 50, TRUE) - finished_product.forceMove(src.loc) - finished_product = null - -#undef PART_PRIMARY -#undef PART_SECONDARY -#undef PART_TRIM -#undef BASE_POINT_MULT -#undef BASE_SHEET_MULT -#undef POINT_MULT_ADD_PER_RATING -#undef SHEET_MULT_ADD_PER_RATING -#undef OPERATION_SPEED_MULT_PER_RATING -#undef EFFICIENCY_MULT_ADD_PER_RATING diff --git a/code/modules/crafting/smithed_items.dm b/code/modules/crafting/smithed_items.dm deleted file mode 100644 index 1b8f16234a0..00000000000 --- a/code/modules/crafting/smithed_items.dm +++ /dev/null @@ -1,1209 +0,0 @@ -/obj/item/smithing_cast - name = "smithing cast" - icon = 'icons/obj/smithing.dmi' - icon_state = "debug" - desc = "Debug smithing cast. If you see this, notify the development team." - w_class = WEIGHT_CLASS_SMALL - /// The selected final product of the item - var/obj/item/selected_product - /// Possible products of the item - var/list/possible_products = list() - /// How many products are we smelting at any given operation? - var/amount_to_make = 1 - - new_attack_chain = TRUE - -/obj/item/smithing_cast/Initialize(mapload) - . = ..() - populate_products() - -/obj/item/smithing_cast/examine(mob/user) - . = ..() - . += "It is currently configured to make [amount_to_make == 1 ? "a" : "[amount_to_make]"] [selected_product.name][amount_to_make == 1 ? "" : "s"]." - . += "You can select the desired product by using [src] in your hand." - -/obj/item/smithing_cast/activate_self(mob/user) - . = ..() - if(!possible_products) - return - var/list/product_names = list() - var/product - for(product in possible_products) - var/obj/item/possible_product = product - product_names[possible_product.name] = possible_product - var/new_product = tgui_input_list(user, "Select a product", src, product_names) - if(!new_product) - selected_product = possible_products[1] - else - selected_product = product_names[new_product] - -/obj/item/smithing_cast/update_desc() - return ..() - -/obj/item/smithing_cast/proc/populate_products() - return - -/obj/item/smithing_cast/sheet - name = "sheet cast" - icon_state = "sheet_cast" - desc = "A cast for forging molten minerals into workable sheets." - -/obj/item/smithing_cast/sheet/examine(mob/user) - . = ..() - . += "You can change the amount of sheets smelted by alt-clicking [src]." - -/obj/item/smithing_cast/sheet/populate_products() - possible_products = list(/obj/item/stack/sheet/metal, - /obj/item/stack/sheet/glass, - /obj/item/stack/sheet/mineral/silver, - /obj/item/stack/sheet/mineral/gold, - /obj/item/stack/sheet/mineral/plasma, - /obj/item/stack/sheet/mineral/uranium, - /obj/item/stack/sheet/mineral/diamond, - /obj/item/stack/ore/bluespace_crystal/refined, - /obj/item/stack/sheet/mineral/titanium, - /obj/item/stack/sheet/plasmaglass, - /obj/item/stack/sheet/titaniumglass, - /obj/item/stack/sheet/plasteel, - /obj/item/stack/sheet/mineral/plastitanium, - /obj/item/stack/sheet/plastitaniumglass, - /obj/item/stack/sheet/mineral/bananium, - /obj/item/stack/sheet/mineral/tranquillite, - /obj/item/stack/sheet/mineral/platinum, - /obj/item/stack/sheet/mineral/palladium, - /obj/item/stack/sheet/mineral/iridium, - /obj/item/stack/tile/brass - ) - if(length(possible_products)) - selected_product = possible_products[1] - -/obj/item/smithing_cast/sheet/AltClick(mob/user) - . = ..() - if(!Adjacent(user)) - return - amount_to_make = tgui_input_number(user, "Select an amount (1-50)", src, 1, 50, 1) - -/obj/item/smithing_cast/component - name = "component cast" - desc = "Debug component cast. If you see this, notify the development team." - /// The selected quality of the item - var/datum/smith_quality/quality = /datum/smith_quality - /// The type of product - var/product_type - -/obj/item/smithing_cast/component/examine(mob/user) - . = ..() - . += "The current selected quality is [quality.name]." - . += "You can change the quality of the product by alt-clicking [src]." - -/obj/item/smithing_cast/component/AltClick(mob/user) - . = ..() - if(!Adjacent(user)) - return - var/list/quality_name_list = list() - var/list/quality_type_list = typesof(/datum/smith_quality) - var/quality_type - for(quality_type in quality_type_list) - var/datum/smith_quality/new_quality = quality_type - quality_name_list[new_quality.name] = new_quality - var/selected_quality = tgui_input_list(user, "Select a quality", src, quality_name_list) - if(!selected_quality) - quality = quality_type_list[1] - else - quality = quality_name_list[selected_quality] - -/obj/item/smithing_cast/component/populate_products() - possible_products = (typesof(product_type) - list(product_type)) - if(length(possible_products)) - selected_product = possible_products[1] - -/obj/item/smithing_cast/component/insert_frame - name = "insert frame cast" - icon_state = "insert_frame_cast" - desc = "A cast for creating insert frames." - product_type = /obj/item/smithed_item/component/insert_frame - -/obj/item/smithing_cast/component/insert_lining - name = "insert lining cast" - icon_state = "insert_lining_cast" - desc = "A cast for creating insert linings." - product_type = /obj/item/smithed_item/component/insert_lining - -/obj/item/smithing_cast/component/bit_mount - name = "bit mount cast" - icon_state = "bit_mount_cast" - desc = "A cast for creating bit mounts." - product_type = /obj/item/smithed_item/component/bit_mount - -/obj/item/smithing_cast/component/bit_head - name = "bit head cast" - icon_state = "bit_head_cast" - desc = "A cast for creating bit heads." - product_type = /obj/item/smithed_item/component/bit_head - -/obj/item/smithing_cast/component/lens_frame - name = "lens frame cast" - icon_state = "lens_frame_cast" - desc = "A cast for creating lens frames." - product_type = /obj/item/smithed_item/component/lens_frame - -/obj/item/smithing_cast/component/lens_focus - name = "lens focus cast" - icon_state = "lens_focus_cast" - desc = "A cast for creating lens foci." - product_type = /obj/item/smithed_item/component/lens_focus - -/obj/item/smithing_cast/component/trim - name = "trim cast" - icon_state = "trim_cast" - desc = "A cast for creating trims." - product_type = /obj/item/smithed_item/component/trim - -/obj/item/smithed_item - name = "Debug smithed item" - icon = 'icons/obj/smithing.dmi' - icon_state = "debug" - desc = "Debug smithed item. If you see this, notify the development team." - w_class = WEIGHT_CLASS_SMALL - /// The quality of the item - var/datum/smith_quality/quality - /// The material of the item - var/datum/smith_material/material - - new_attack_chain = TRUE - -/obj/item/smithed_item/Initialize(mapload) - . = ..() - set_name() - -/obj/item/smithed_item/update_name() - . = ..() - set_name() - -/obj/item/smithed_item/proc/on_attached(mob/user, obj/item/target) - return - -/obj/item/smithed_item/proc/on_detached(mob/user) - return - -/obj/item/smithed_item/proc/set_stats() - return - -/obj/item/smithed_item/proc/set_name() - if(!quality) - return - if(!material) - name = "[quality.name] " + name - return - name = "[quality.name] [material.name] [initial(name)]" - -// Inserts - -/obj/item/smithed_item/insert - name = "debug insert" - icon_state = "insert" - desc = "Debug insert. If you see this, notify the development team." - /// Brute armor - var/brute_armor = 0 - /// Burn armor - var/burn_armor = 0 - /// Laser armor - var/laser_armor = 0 - /// Explosive armor - var/explosive_armor = 0 - /// Movement speed - var/movement_speed_mod = 0 - /// Heat insulation - var/heat_insulation = 0 - /// Electrical insulation - var/siemens_coeff = 0.0 - /// Radiation armor - var/radiation_armor = 0 - /// The suit the insert is attached to - var/obj/item/clothing/suit/attached_suit - -/obj/item/smithed_item/insert/set_stats() - brute_armor = initial(brute_armor) * quality.stat_mult * material.brute_armor_mult - burn_armor = initial(burn_armor) * quality.stat_mult * material.burn_armor_mult - laser_armor = initial(laser_armor) * quality.stat_mult * material.laser_armor_mult - explosive_armor = initial(explosive_armor) * quality.stat_mult * material.explosive_armor_mult - movement_speed_mod = initial(movement_speed_mod) * quality.stat_mult * material.movement_speed_mod - heat_insulation = initial(heat_insulation) * quality.stat_mult * material.heat_insulation_mult - siemens_coeff = initial(siemens_coeff) * quality.stat_mult * material.siemens_coeff_mult - radiation_armor = initial(radiation_armor) * quality.stat_mult * material.radiation_armor_mult - armor = new /datum/armor(brute_armor, brute_armor, laser_armor, laser_armor, explosive_armor, radiation_armor, burn_armor, 0, 0) - -/obj/item/smithed_item/insert/on_attached(obj/item/clothing/suit/target) - if(!istype(target)) - return - attached_suit = target - attached_suit.armor = attached_suit.armor.attachArmor(armor) - attached_suit.insert_slowdown -= movement_speed_mod - attached_suit.slowdown = initial(attached_suit.slowdown) + attached_suit.insert_slowdown - if(attached_suit.mobility_meshed) - attached_suit.slowdown = 0 - attached_suit.siemens_coefficient -= siemens_coeff - attached_suit.min_cold_protection_temperature -= heat_insulation - attached_suit.max_heat_protection_temperature += heat_insulation - -/obj/item/smithed_item/insert/on_detached(mob/user) - attached_suit.armor = attached_suit.armor.detachArmor(armor) - attached_suit.insert_slowdown += movement_speed_mod - attached_suit.slowdown = initial(attached_suit.slowdown) + attached_suit.insert_slowdown - if(attached_suit.mobility_meshed) - attached_suit.slowdown = 0 - attached_suit.siemens_coefficient += siemens_coeff - attached_suit.min_cold_protection_temperature += heat_insulation - attached_suit.max_heat_protection_temperature -= heat_insulation - attached_suit.inserts -= src - attached_suit = null - -/obj/item/smithed_item/insert/ballistic - name = "ballistic plate" - desc = "A reinforced plate designed to stop small-caliber bullets and kinetic impacts." - brute_armor = 10 - explosive_armor = 10 - heat_insulation = -10 - -/obj/item/smithed_item/insert/thermal - name = "thermal plate" - desc = "A fragile plate designed to reduce heat exposure." - brute_armor = -10 - burn_armor = 10 - heat_insulation = 10 - -/obj/item/smithed_item/insert/fireproofing - name = "fireproofing plate" - desc = "A heavy plate of asbestos designed to fireproof a user. A firefighter's godsend." - burn_armor = 10 - movement_speed_mod = -0.2 - heat_insulation = 20 - -/obj/item/smithed_item/insert/reflective - name = "reflective plate" - desc = "A shiny plate that assists in laser deflection." - burn_armor = -10 - laser_armor = 10 - siemens_coeff = -0.2 - -/obj/item/smithed_item/insert/rad_hazard - name = "radiation hazard plate" - desc = "A dense plate that can reduce a wearer's radiation exposure." - heat_insulation = -10 - radiation_armor = 20 - -/obj/item/smithed_item/insert/rubberized - name = "rubberized plate" - desc = "A flexible plate that is resistant to electrical shocks." - brute_armor = -10 - siemens_coeff = 0.2 - -/obj/item/smithed_item/insert/advanced - name = "advanced armor mesh" - desc = "An alloy mesh that can protect the wearer from most sources of damage." - brute_armor = 10 - burn_armor = 10 - laser_armor = 10 - explosive_armor = 10 - radiation_armor = 10 - movement_speed_mod = -0.2 - -/obj/item/smithed_item/insert/engineering - name = "engineering mesh" - desc = "An alloy mesh designed to assist in most work around electrical engines." - brute_armor = -10 - burn_armor = 10 - radiation_armor = 10 - heat_insulation = 10 - explosive_armor = 10 - siemens_coeff = 0.4 - movement_speed_mod = -0.2 - -/obj/item/smithed_item/insert/heavy - name = "heavy duty plate" - desc = "An advanced plate often used in SWAT gear. Heavy, yet durable." - brute_armor = 20 - burn_armor = 10 - laser_armor = 10 - explosive_armor = 10 - heat_insulation = 10 - siemens_coeff = -0.4 - movement_speed_mod = -0.4 - -/obj/item/smithed_item/insert/mobility - name = "mobility mesh" - desc = "An advanced alloy mesh that is both lightweight and invigorating to the wearer." - brute_armor = -5 - burn_armor = -5 - laser_armor = -5 - heat_insulation = 10 - /// Attached suit slowdown when the mobility mesh was applied - var/initial_slowdown = 0 - -/obj/item/smithed_item/insert/mobility/on_attached(obj/item/clothing/suit/target) - . = ..() - attached_suit.mobility_meshed = TRUE - attached_suit.slowdown = 0 - -/obj/item/smithed_item/insert/mobility/on_detached(mob/user) - attached_suit.mobility_meshed = FALSE - . = ..() - - -/obj/item/smithed_item/insert/admin - name = "adminium mesh" - desc = "A special mesh plate reserved exclusively for high-ranking central command personnel." - brute_armor = 50 - burn_armor = 50 - laser_armor = 50 - radiation_armor = 50 - heat_insulation = 50 - movement_speed_mod = 1 - siemens_coeff = 1 - quality = /datum/smith_quality/masterwork - material = /datum/smith_material/platinum - -// Tool Bits - -/obj/item/smithed_item/tool_bit - name = "Debug tool bit" - icon_state = "bit" - desc = "Debug tool bit. If you see this, notify the development team." - /// Base Speed modifier - var/base_speed_mod = 0 - /// Base Efficiency modifier - var/base_efficiency_mod = 0 - /// Speed modifier - var/speed_mod = 1.0 - /// Efficiency modifier - var/efficiency_mod = 1.0 - /// Failure rate - var/failure_rate = 0 - /// Size modifier - var/size_mod = 0 - /// Durability - var/durability = 90 - /// Max durability - var/max_durability = 90 - /// The tool the bit is attached to - var/obj/item/attached_tool - -/obj/item/smithed_item/tool_bit/interact_with_atom(atom/target, mob/living/user, list/modifiers) - . = ..() - if(istype(target, /obj/item)) - SEND_SIGNAL(target, COMSIG_BIT_ATTACH, src, user) - return ITEM_INTERACT_COMPLETE - -/obj/item/smithed_item/tool_bit/set_stats() - durability = initial(durability) * material.durability_mult - max_durability = durability - size_mod = initial(size_mod) + material.size_mod - speed_mod = 1 + (base_speed_mod * quality.stat_mult * material.tool_speed_mult) - failure_rate = initial(failure_rate) * quality.stat_mult * material.tool_failure_mult - efficiency_mod = 1 + (base_efficiency_mod * quality.stat_mult * material.power_draw_mult) - -/obj/item/smithed_item/tool_bit/on_attached(obj/item/target) - if(!istype(target)) - return - attached_tool = target - attached_tool.w_class += size_mod - attached_tool.toolspeed = attached_tool.toolspeed * speed_mod - attached_tool.bit_failure_rate += failure_rate - attached_tool.bit_efficiency_mod = attached_tool.bit_efficiency_mod * efficiency_mod - -/obj/item/smithed_item/tool_bit/on_detached() - attached_tool.toolspeed = attached_tool.toolspeed / speed_mod - attached_tool.w_class -= size_mod - attached_tool.bit_failure_rate -= failure_rate - attached_tool.bit_efficiency_mod = attached_tool.bit_efficiency_mod / efficiency_mod - attached_tool.attached_bits -= src - attached_tool = null - -/obj/item/smithed_item/tool_bit/examine(mob/user) - . = ..() - var/healthpercent = (durability/max_durability) * 100 - switch(healthpercent) - if(80 to 100) - . += "It looks pristine." - if(60 to 79) - . += "It looks slightly used." - if(40 to 59) - . += "It's seen better days." - if(20 to 39) - . += "It's been heavily used." - if(0 to 19) - . += "It's falling apart!" - -/obj/item/smithed_item/tool_bit/proc/damage_bit() - durability-- - if(istype(attached_tool, /obj/item/rcd)) - durability-- - if(durability == 0) - break_bit() - -/obj/item/smithed_item/tool_bit/proc/break_bit() - on_detached() - qdel(src) - -/obj/item/smithed_item/tool_bit/speed - name = "speed bit" - desc = "A tool bit optimized for speed, at the cost of efficiency." - base_speed_mod = -0.2 - failure_rate = 5 - base_efficiency_mod = 0.1 - -/obj/item/smithed_item/tool_bit/efficiency - name = "efficient bit" - desc = "A tool bit optimized for efficiency, at the cost of speed." - base_speed_mod = 0.2 - base_efficiency_mod = -0.25 - -/obj/item/smithed_item/tool_bit/balanced - name = "balanced bit" - desc = "A tool bit that's fairly balanced in all aspects." - base_speed_mod = -0.1 - failure_rate = 2 - base_efficiency_mod = -0.1 - -/obj/item/smithed_item/tool_bit/heavy - name = "heavy duty bit" - desc = "A large, advanced tool bit that maximises speed." - base_speed_mod = -0.4 - failure_rate = 10 - base_efficiency_mod = 0.25 - size_mod = 1 - durability = 120 - -/obj/item/smithed_item/tool_bit/economical - name = "economical bit" - desc = "An advanced tool bit that maximises efficiency." - base_speed_mod = 0.4 - base_efficiency_mod = -0.45 - durability = 60 - -/obj/item/smithed_item/tool_bit/advanced - name = "advanced bit" - desc = "An advanced tool bit that's fairly balanced in all aspects." - base_speed_mod = -0.25 - failure_rate = 2 - base_efficiency_mod = -0.3 - -/obj/item/smithed_item/tool_bit/admin - name = "adminium bit" - desc = "A hyper-advanced bit restricted to central command officials." - speed_mod = -1 - efficiency_mod = 1 - durability = 300 - quality = /datum/smith_quality/masterwork - material = /datum/smith_material/platinum - -// lenses - -/obj/item/smithed_item/lens - name = "Debug lens" - icon_state = "lens" - desc = "Debug lens. If you see this, notify the development team." - /// Base laser speed multiplier - var/base_laser_speed_mult = 0 - /// Base power draw multiplier - var/base_power_mult = 0 - /// Base damage multiplier - var/base_damage_mult = 0 - /// Base fire rate multiplier - var/base_fire_rate_mult = 0 - /// Laser speed multiplier after construction - var/laser_speed_mult = 1 - /// Power draw multiplier after construction - var/power_mult = 1 - /// Damage multiplier after construction - var/damage_mult = 1 - /// Fire rate multiplier after construction - var/fire_rate_mult = 1 - /// lens durability - var/durability = 40 - /// Max durability - var/max_durability = 40 - /// The weapon the lens is attached to - var/obj/item/gun/energy/attached_gun - -/obj/item/smithed_item/lens/set_stats() - durability = initial(durability) * material.durability_mult - max_durability = durability - power_mult = 1 + (base_power_mult * quality.stat_mult * material.power_draw_mult) - damage_mult = 1 + (base_damage_mult * quality.stat_mult * material.projectile_damage_multiplier) - laser_speed_mult = 1 + (base_laser_speed_mult * quality.stat_mult * material.projectile_speed_mult) - fire_rate_mult = 1 + (base_fire_rate_mult * quality.stat_mult * material.fire_rate_multiplier) - -/obj/item/smithed_item/lens/on_attached(obj/item/gun/energy/target) - if(!istype(target)) - return - attached_gun = target - attached_gun.fire_delay = attached_gun.fire_delay / fire_rate_mult - for(var/obj/item/ammo_casing/energy/casing in attached_gun.ammo_type) - casing.e_cost = casing.e_cost * power_mult - casing.lens_damage_multiplier = casing.lens_damage_multiplier * damage_mult - casing.lens_speed_multiplier = casing.lens_speed_multiplier / laser_speed_mult - -/obj/item/smithed_item/lens/on_detached() - attached_gun.fire_delay = attached_gun.fire_delay * fire_rate_mult - for(var/obj/item/ammo_casing/energy/casing in attached_gun.ammo_type) - casing.e_cost = casing.e_cost / power_mult - casing.lens_damage_multiplier = casing.lens_damage_multiplier / damage_mult - casing.lens_speed_multiplier = casing.lens_speed_multiplier * laser_speed_mult - attached_gun.current_lens = null - attached_gun = null - -/obj/item/smithed_item/lens/examine(mob/user) - . = ..() - var/healthpercent = (durability/max_durability) * 100 - switch(healthpercent) - if(80 to 100) - . += "It looks pristine." - if(60 to 79) - . += "It looks slightly used." - if(40 to 59) - . += "It's seen better days." - if(20 to 39) - . += "It's been heavily used." - if(0 to 19) - . += "It's falling apart!" - -/obj/item/smithed_item/lens/proc/damage_lens() - durability-- - if(durability <= 0) - break_lens() - -/obj/item/smithed_item/lens/proc/break_lens() - on_detached() - qdel(src) - -/obj/item/smithed_item/lens/accelerator - name = "accelerator lens" - desc = "A lens that accelerates energy beams to a higher velocity, using some of its own energy to propel it." - base_laser_speed_mult = 0.1 - base_damage_mult = -0.1 - -/obj/item/smithed_item/lens/speed - name = "speed lens" - desc = "A lens that cools the capacitors more efficiently, allowing for greater fire rate." - base_fire_rate_mult = 0.15 - base_damage_mult = -0.1 - durability = 30 - -/obj/item/smithed_item/lens/amplifier - name = "amplifier lens" - desc = "A lens that increases the frequency of emitted beams, increasing their potency." - base_power_mult = 0.2 - base_damage_mult = 0.1 - -/obj/item/smithed_item/lens/efficiency - name = "efficiency lens" - desc = "A lens that optimizes the number of shots an energy weapon can take before running dry." - base_power_mult = -0.2 - base_damage_mult = -0.1 - durability = 80 - -/obj/item/smithed_item/lens/rapid - name = "rapid lens" - desc = "An advanced lens that bypasses the heat capacitor entirely, allowing for unprecedented fire rates of low-power emissions." - base_fire_rate_mult = 0.5 - base_laser_speed_mult = -0.1 - base_damage_mult = -0.2 - durability = 60 - -/obj/item/smithed_item/lens/densifier - name = "densifier lens" - desc = "An advanced lens that keeps energy emissions in the barrel as long as possible, maximising impact at the cost of everything else." - base_fire_rate_mult = -0.4 - base_laser_speed_mult = -0.4 - base_damage_mult = 0.4 - durability = 30 - -/obj/item/smithed_item/lens/velocity - name = "velocity lens" - desc = "An advanced lens that forces energy emissions from the barrel as fast as possible, accelerating them to ludicrous speed." - base_laser_speed_mult = 0.5 - base_damage_mult = -0.2 - durability = 30 - -/obj/item/smithed_item/lens/admin - name = "adminium lens" - desc = "A hyper-advanced lens restricted to high-ranking central command officials." - laser_speed_mult = 5 - damage_mult = 5 - fire_rate_mult = 5 - power_mult = -0.5 - durability = 3000 - quality = /datum/smith_quality/masterwork - material = /datum/smith_material/platinum - -// Random Spawners -/obj/item/smithed_item/random - name = "random smithed item" - desc = "If you see me please contact development because I should not exist." - /// Weighted list of possible item qualities - var/list/smithed_item_qualities = list( - /datum/smith_quality = 9, - /datum/smith_quality/improved = 1 - ) - /// Weighted list of possible item materials - var/list/smithed_item_materials = list( - /datum/smith_material/metal = 40, - /datum/smith_material/silver = 10, - /datum/smith_material/gold = 5, - /datum/smith_material/plasma = 10, - /datum/smith_material/titanium = 5, - /datum/smith_material/uranium = 3, - /datum/smith_material/brass = 15 - ) - /// List of possible item types - var/list/smithed_type_list = list( - /obj/item/smithed_item/insert/ballistic, - /obj/item/smithed_item/insert/thermal, - /obj/item/smithed_item/insert/fireproofing, - /obj/item/smithed_item/insert/reflective, - /obj/item/smithed_item/insert/rad_hazard, - /obj/item/smithed_item/insert/rubberized, - /obj/item/smithed_item/tool_bit/speed, - /obj/item/smithed_item/tool_bit/balanced, - /obj/item/smithed_item/tool_bit/efficiency, - /obj/item/smithed_item/lens/accelerator, - /obj/item/smithed_item/lens/speed, - /obj/item/smithed_item/lens/amplifier, - /obj/item/smithed_item/lens/efficiency - ) - -/obj/item/smithed_item/random/Initialize(mapload) - . = ..() - var/picked_type = pick(smithed_type_list) - var/obj/item/smithed_item/new_item = new picked_type(src.loc) - new_item.quality = pickweight(smithed_item_qualities) - new_item.material = pickweight(smithed_item_materials) - new_item.set_stats() - new_item.update_appearance(UPDATE_NAME) - qdel(src) - -/obj/item/smithed_item/random/insert - name = "random smithed insert" - smithed_type_list = list( - /obj/item/smithed_item/insert/ballistic, - /obj/item/smithed_item/insert/thermal, - /obj/item/smithed_item/insert/fireproofing, - /obj/item/smithed_item/insert/reflective, - /obj/item/smithed_item/insert/rad_hazard, - /obj/item/smithed_item/insert/rubberized - ) - -/obj/item/smithed_item/random/bit - name = "random smithed tool bit" - smithed_type_list = list( - /obj/item/smithed_item/tool_bit/speed, - /obj/item/smithed_item/tool_bit/balanced, - /obj/item/smithed_item/tool_bit/efficiency - ) - -/obj/item/smithed_item/random/lens - name = "random smithed lens" - smithed_type_list = list( - /obj/item/smithed_item/lens/accelerator, - /obj/item/smithed_item/lens/speed, - /obj/item/smithed_item/lens/amplifier, - /obj/item/smithed_item/lens/efficiency - ) - -// Components - -#define PART_PRIMARY 1 -#define PART_SECONDARY 2 -#define PART_TRIM 3 - -/obj/item/smithed_item/component - name = "Debug smithed component" - icon = 'icons/obj/smithing.dmi' - icon_state = "debug" - desc = "Debug smithed component part. If you see this, notify the development team." - /// What type of part is it - var/part_type - /// What is this a part of - var/finished_product - /// Is this component currently hot - var/hot = TRUE - /// How many times the component needs to be shaped to be considered ready - var/hammer_time = 3 - -/obj/item/smithed_item/component/update_icon_state() - . = ..() - if(hot) - icon_state = "[initial(icon_state)]_hot" - else - icon_state = "[initial(icon_state)]" - -/obj/item/smithed_item/component/proc/powerhammer() - hammer_time-- - if(prob(50) || hammer_time <= 0) - hot = FALSE - update_icon(UPDATE_ICON_STATE) - -/obj/item/smithed_item/component/proc/heat_up() - hot = TRUE - update_icon(UPDATE_ICON_STATE) - -/obj/item/smithed_item/component/examine(mob/user) - . = ..() - if(hammer_time) - . += "It is incomplete. It looks like it needs [hammer_time] more cycles in the power hammer." - else - . += "It is complete." - if(hot) - . +="It is glowing hot!" - -/obj/item/smithed_item/component/attack_hand(mob/user) - if(!hot) - return ..() - if(burn_check(user)) - burn_user(user) - return - return ..() - -/obj/item/smithed_item/component/proc/set_worktime() - if(!quality) - return - hammer_time = ROUND_UP(initial(hammer_time) * quality.work_mult) - -/obj/item/smithed_item/component/proc/burn_check(mob/user) - if(!hot) - return FALSE - var/burn_me = TRUE - var/mob/living/carbon/human/H = user - if(!istype(H)) - return TRUE - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - if(G.max_heat_protection_temperature) - burn_me = !(G.max_heat_protection_temperature > 360) - - if(!burn_me || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) - return FALSE - return TRUE - -/obj/item/smithed_item/component/proc/burn_user(mob/user) - var/mob/living/carbon/human/H = user - if(!istype(H)) - return - to_chat(user, "You burn your hand as you try to pick up [src]!") - var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand") - if(affecting.receive_damage(0, 10)) // 10 burn damage - H.UpdateDamageIcon() - H.updatehealth() - -/obj/item/smithed_item/component/insert_frame - name = "Debug insert frame" - icon_state = "insert_frame" - desc = "Debug smithed component part of an insert. If you see this, notify the development team." - part_type = PART_PRIMARY - -/obj/item/smithed_item/component/insert_frame/ballistic - name = "ballistic insert frame" - desc = "This is the primary component of a ballistic plate." - materials = list(MAT_METAL = 10000) - finished_product = /obj/item/smithed_item/insert/ballistic - -/obj/item/smithed_item/component/insert_frame/thermal - name = "thermal insert frame" - desc = "This is the primary component of a thermal plate." - materials = list(MAT_GOLD = 6000) - finished_product = /obj/item/smithed_item/insert/thermal - -/obj/item/smithed_item/component/insert_frame/fireproofing - name = "fireproofing insert frame" - desc = "This is the primary component of a fireproofing plate." - materials = list(MAT_SILVER = 10000) - finished_product = /obj/item/smithed_item/insert/fireproofing - -/obj/item/smithed_item/component/insert_frame/reflective - name = "reflective insert frame" - desc = "This is the primary component of a reflective plate." - materials = list(MAT_SILVER = 10000) - finished_product = /obj/item/smithed_item/insert/reflective - -/obj/item/smithed_item/component/insert_frame/rad_hazard - name = "radiation hazard insert frame" - desc = "This is the primary component of a radiation hazard plate." - materials = list(MAT_GOLD = 6000) - finished_product = /obj/item/smithed_item/insert/rad_hazard - -/obj/item/smithed_item/component/insert_frame/rubberized - name = "rubberized insert frame" - desc = "This is the primary component of a rubberized plate." - materials = list(MAT_PLASMA = 10000) - finished_product = /obj/item/smithed_item/insert/rubberized - -/obj/item/smithed_item/component/insert_frame/advanced - name = "advanced insert frame" - desc = "This is the primary component of a advanced armor mesh." - materials = list(MAT_METAL = 10000, MAT_PLASMA = 10000) - finished_product = /obj/item/smithed_item/insert/advanced - -/obj/item/smithed_item/component/insert_frame/engineering - name = "engineering insert frame" - desc = "This is the primary component of a advanced engineering mesh." - materials = list(MAT_GOLD = 10000, MAT_SILVER = 10000) - finished_product = /obj/item/smithed_item/insert/engineering - -/obj/item/smithed_item/component/insert_frame/heavy - name = "heavy duty insert frame" - desc = "This is the primary component of a advanced heavy duty plate." - materials = list(MAT_TITANIUM = 20000, MAT_PLASMA = 20000) - finished_product = /obj/item/smithed_item/insert/heavy - -/obj/item/smithed_item/component/insert_frame/mobility - name = "mobility mesh insert frame" - desc = "This is the primary component of a advanced mobility mesh." - materials = list(MAT_BLUESPACE = 4000) - finished_product = /obj/item/smithed_item/insert/mobility - -/obj/item/smithed_item/component/insert_lining - name = "Debug insert lining" - icon_state = "insert_lining" - desc = "Debug smithed component part of an insert. If you see this, notify the development team." - part_type = PART_SECONDARY - -/obj/item/smithed_item/component/insert_lining/ballistic - name = "ballistic insert lining" - desc = "This is the secondary component of a ballistic plate." - materials = list(MAT_METAL = 10000) - finished_product = /obj/item/smithed_item/insert/ballistic - -/obj/item/smithed_item/component/insert_lining/thermal - name = "thermal insert lining" - desc = "This is the secondary component of a thermal plate." - materials = list(MAT_METAL = 10000) - finished_product = /obj/item/smithed_item/insert/thermal - -/obj/item/smithed_item/component/insert_lining/fireproofing - name = "fireproofing insert lining" - desc = "This is the secondary component of a fireproofing plate." - materials = list(MAT_METAL = 10000, MAT_PLASMA = 10000) - finished_product = /obj/item/smithed_item/insert/fireproofing - -/obj/item/smithed_item/component/insert_lining/reflective - name = "reflective insert lining" - desc = "This is the secondary component of a reflective plate." - materials = list(MAT_GOLD = 6000) - finished_product = /obj/item/smithed_item/insert/reflective - -/obj/item/smithed_item/component/insert_lining/rad_hazard - name = "radiation hazard insert lining" - desc = "This is the secondary component of a radiation hazard plate." - materials = list(MAT_TITANIUM = 10000) - finished_product = /obj/item/smithed_item/insert/rad_hazard - -/obj/item/smithed_item/component/insert_lining/rubberized - name = "rubberized insert lining" - desc = "This is the secondary component of a rubberized plate." - materials = list(MAT_PLASMA = 10000) - finished_product = /obj/item/smithed_item/insert/rubberized - -/obj/item/smithed_item/component/insert_lining/advanced - name = "advanced insert lining" - desc = "This is the secondary component of a advanced armor mesh." - materials = list(MAT_TITANIUM = 10000, MAT_DIAMOND = 2000) - finished_product = /obj/item/smithed_item/insert/advanced - -/obj/item/smithed_item/component/insert_lining/engineering - name = "engineering insert lining" - desc = "This is the secondary component of a advanced engineering mesh." - materials = list(MAT_TITANIUM = 10000, MAT_IRIDIUM = 2000) - finished_product = /obj/item/smithed_item/insert/engineering - -/obj/item/smithed_item/component/insert_lining/heavy - name = "heavy duty insert lining" - desc = "This is the secondary component of a advanced heavy duty plate." - materials = list(MAT_TITANIUM = 10000, MAT_PLATINUM = 2000) - finished_product = /obj/item/smithed_item/insert/heavy - -/obj/item/smithed_item/component/insert_lining/mobility - name = "mobility mesh insert lining" - desc = "This is the secondary component of a advanced mobility mesh." - materials = list(MAT_PALLADIUM = 2000) - finished_product = /obj/item/smithed_item/insert/mobility - -/obj/item/smithed_item/component/bit_mount - name = "Debug bit mount" - icon_state = "bit_mount" - desc = "Debug smithed component part of a tool bit. If you see this, notify the development team." - part_type = PART_PRIMARY - -/obj/item/smithed_item/component/bit_mount/speed - name = "speed bit mount" - desc = "This is the primary component of a speed bit" - materials = list(MAT_TITANIUM = 4000) - finished_product = /obj/item/smithed_item/tool_bit/speed - -/obj/item/smithed_item/component/bit_mount/efficiency - name = "efficiency bit mount" - desc = "This is the primary component of an efficiency bit" - materials = list(MAT_SILVER = 4000) - finished_product = /obj/item/smithed_item/tool_bit/efficiency - -/obj/item/smithed_item/component/bit_mount/balanced - name = "balanced bit mount" - desc = "This is the primary component of an balanced bit." - materials = list(MAT_TITANIUM = 4000) - finished_product = /obj/item/smithed_item/tool_bit/balanced - -/obj/item/smithed_item/component/bit_mount/heavy - name = "heavy duty bit mount" - desc = "This is the primary component of a heavy duty bit." - materials = list(MAT_TITANIUM = 8000, MAT_PLASMA = 8000) - finished_product = /obj/item/smithed_item/tool_bit/heavy - -/obj/item/smithed_item/component/bit_mount/economical - name = "economical bit mount" - desc = "This is the primary component of an economical bit." - materials = list(MAT_TITANIUM = 4000, MAT_PLASMA = 4000) - finished_product = /obj/item/smithed_item/tool_bit/economical - -/obj/item/smithed_item/component/bit_mount/advanced - name = "advanced bit mount" - desc = "This is the primary component of an advanced bit." - materials = list(MAT_TITANIUM = 4000, MAT_PLASMA = 4000) - finished_product = /obj/item/smithed_item/tool_bit/advanced - -/obj/item/smithed_item/component/bit_head - name = "Debug bit head" - icon_state = "bit_head" - desc = "Debug smithed component part of a tool bit. If you see this, notify the development team." - part_type = PART_SECONDARY - -/obj/item/smithed_item/component/bit_head/speed - name = "speed bit head" - desc = "This is the secondary component of a speed bit." - materials = list(MAT_METAL = 4000) - finished_product = /obj/item/smithed_item/tool_bit/speed - -/obj/item/smithed_item/component/bit_head/efficiency - name = "efficiency bit head" - desc = "This is the secondary component of an efficiency bit." - materials = list(MAT_METAL = 4000) - finished_product = /obj/item/smithed_item/tool_bit/efficiency - -/obj/item/smithed_item/component/bit_head/balanced - name = "balanced bit head" - desc = "This is the secondary component of a balanced bit." - materials = list(MAT_BRASS = 4000) - finished_product = /obj/item/smithed_item/tool_bit/balanced - -/obj/item/smithed_item/component/bit_head/heavy - name = "heavy duty bit head" - desc = "This is the secondary component of a heavy duty bit." - materials = list(MAT_METAL = 8000, MAT_PLASMA = 8000) - finished_product = /obj/item/smithed_item/tool_bit/heavy - -/obj/item/smithed_item/component/bit_head/economical - name = "economical bit head" - desc = "This is the secondary component of an economical bit." - materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000) - finished_product = /obj/item/smithed_item/tool_bit/economical - -/obj/item/smithed_item/component/bit_head/advanced - name = "advanced bit head" - desc = "This is the secondary component of an advanced bit." - materials = list(MAT_METAL = 4000, MAT_PLATINUM = 4000) - finished_product = /obj/item/smithed_item/tool_bit/advanced - -/obj/item/smithed_item/component/lens_frame - name = "Debug lens frame" - icon_state = "lens_frame" - desc = "Debug smithed component part of a laser lens. If you see this, notify the development team." - part_type = PART_PRIMARY - -/obj/item/smithed_item/component/lens_frame/accelerator - name = "accelerator lens frame" - desc = "This is the primary component of an accelerator lens." - materials = list(MAT_TITANIUM = 4000) - finished_product = /obj/item/smithed_item/lens/accelerator - -/obj/item/smithed_item/component/lens_frame/speed - name = "speed lens frame" - desc = "This is the primary component of a speed lens." - materials = list(MAT_METAL = 4000) - finished_product = /obj/item/smithed_item/lens/speed - -/obj/item/smithed_item/component/lens_frame/amplifier - name = "amplifier lens frame" - desc = "This is the primary component of an amplifier lens." - materials = list(MAT_GOLD = 4000) - finished_product = /obj/item/smithed_item/lens/amplifier - -/obj/item/smithed_item/component/lens_frame/efficiency - name = "efficiency lens frame" - desc = "This is the primary component of an efficiency lens." - materials = list(MAT_SILVER = 4000) - finished_product = /obj/item/smithed_item/lens/efficiency - -/obj/item/smithed_item/component/lens_frame/rapid - name = "rapid lens frame" - desc = "This is the primary component of an advanced rapid lens." - materials = list(MAT_PALLADIUM = 2000) - finished_product = /obj/item/smithed_item/lens/rapid - -/obj/item/smithed_item/component/lens_frame/densifier - name = "densifier lens frame" - desc = "This is the primary component of an advanced densifier lens." - materials = list(MAT_PLATINUM = 2000) - finished_product = /obj/item/smithed_item/lens/densifier - -/obj/item/smithed_item/component/lens_frame/velocity - name = "velocity lens frame" - desc = "This is the primary component of an advanced velocity lens." - materials = list(MAT_BRASS = 30000) - finished_product = /obj/item/smithed_item/lens/velocity - -/obj/item/smithed_item/component/lens_focus - name = "Debug lens focus" - icon_state = "lens_focus" - desc = "Debug smithed component part of a laser lens. If you see this, notify the development team." - part_type = PART_SECONDARY - -/obj/item/smithed_item/component/lens_focus/accelerator - name = "accelerator lens focus" - desc = "This is the secondary component of an accelerator lens." - materials = list(MAT_METAL = 4000, MAT_GLASS = 10000) - finished_product = /obj/item/smithed_item/lens/accelerator - -/obj/item/smithed_item/component/lens_focus/speed - name = "speed lens focus" - desc = "This is the secondary component of a speed lens." - materials = list(MAT_PLASMA = 4000, MAT_GLASS = 10000) - finished_product = /obj/item/smithed_item/lens/speed - -/obj/item/smithed_item/component/lens_focus/amplifier - name = "amplifier lens focus" - desc = "This is the secondary component of an amplifier lens." - materials = list(MAT_TITANIUM = 4000, MAT_GLASS = 10000) - finished_product = /obj/item/smithed_item/lens/amplifier - -/obj/item/smithed_item/component/lens_focus/efficiency - name = "efficiency lens focus" - desc = "This is the secondary component of an efficiency lens." - materials = list(MAT_METAL = 4000, MAT_GLASS = 10000) - finished_product = /obj/item/smithed_item/lens/efficiency - -/obj/item/smithed_item/component/lens_focus/rapid - name = "rapid lens focus" - desc = "This is the secondary component of an advanced rapid lens." - materials = list(MAT_PLASMA = 10000, MAT_GLASS = 10000, MAT_DIAMOND = 2000) - finished_product = /obj/item/smithed_item/lens/rapid - -/obj/item/smithed_item/component/lens_focus/densifier - name = "densifier lens focus" - desc = "This is the secondary component of an advanced densifier lens." - materials = list(MAT_PLASMA = 10000, MAT_GLASS = 10000, MAT_DIAMOND = 2000) - finished_product = /obj/item/smithed_item/lens/densifier - -/obj/item/smithed_item/component/lens_focus/velocity - name = "velocity lens focus" - desc = "This is the secondary component of an advanced velocity lens." - materials = list(MAT_PLASMA = 10000, MAT_GLASS = 10000, MAT_DIAMOND = 2000) - finished_product = /obj/item/smithed_item/lens/velocity - -/obj/item/smithed_item/component/trim - name = "Debug trim" - icon_state = "trim" - desc = "Debug smithed component part of any smithed item. If you see this, notify the development team." - part_type = PART_TRIM - -/obj/item/smithed_item/component/trim/set_name() - if(!quality) - return - name = "[quality.name] " + name - return - -/obj/item/smithed_item/component/trim/metal - name = "metal trim" - desc = "Smithed component of any smithing item. Made of metal." - materials = list(MAT_METAL = 10000) - material = /datum/smith_material/metal - -/obj/item/smithed_item/component/trim/silver - name = "silver trim" - desc = "Smithed component of any smithing item. Made of silver." - materials = list(MAT_SILVER = 10000) - material = /datum/smith_material/silver - -/obj/item/smithed_item/component/trim/gold - name = "gold trim" - desc = "Smithed component of any smithing item. Made of gold." - materials = list(MAT_GOLD = 10000) - material = /datum/smith_material/gold - -/obj/item/smithed_item/component/trim/plasma - name = "plasma trim" - desc = "Smithed component of any smithing item. Made of solid plasma." - materials = list(MAT_PLASMA = 10000) - material = /datum/smith_material/plasma - -/obj/item/smithed_item/component/trim/titanium - name = "titanium trim" - desc = "Smithed component of any smithing item. Made of titanium." - materials = list(MAT_TITANIUM = 10000) - material = /datum/smith_material/titanium - -/obj/item/smithed_item/component/trim/uranium - name = "uranium trim" - desc = "Smithed component of any smithing item. Made of uranium." - materials = list(MAT_URANIUM = 10000) - material = /datum/smith_material/uranium - -/obj/item/smithed_item/component/trim/diamond - name = "diamond trim" - desc = "Smithed component of any smithing item. Made of diamond." - materials = list(MAT_DIAMOND = 10000) - material = /datum/smith_material/diamond - -/obj/item/smithed_item/component/trim/bluespace - name = "bluespace trim" - desc = "Smithed component of any smithing item. Made of bluespace crystals." - materials = list(MAT_BLUESPACE = 10000) - material = /datum/smith_material/bluespace - -/obj/item/smithed_item/component/trim/plasteel - name = "plasteel trim" - desc = "Smithed component of any smithing item. Made of plasteel." - materials = list(MAT_METAL = 10000, MAT_PLASMA = 10000) - material = /datum/smith_material/plasteel - -/obj/item/smithed_item/component/trim/plastitanium - name = "plastitanium trim" - desc = "Smithed component of any smithing item. Made of plastitanium." - materials = list(MAT_TITANIUM = 10000, MAT_PLASMA = 10000) - material = /datum/smith_material/plastitanium - -/obj/item/smithed_item/component/trim/iridium - name = "iridium trim" - desc = "Smithed component of any smithing item. Made of iridium." - materials = list(MAT_IRIDIUM = 10000) - material = /datum/smith_material/iridium - -/obj/item/smithed_item/component/trim/palladium - name = "palladium trim" - desc = "Smithed component of any smithing item. Made of palladium." - materials = list(MAT_PALLADIUM = 10000) - material = /datum/smith_material/palladium - -/obj/item/smithed_item/component/trim/platinum - name = "platinum trim" - desc = "Smithed component of any smithing item. Made of platinum." - materials = list(MAT_PLATINUM = 10000) - material = /datum/smith_material/platinum - -/obj/item/smithed_item/component/trim/brass - name = "brass trim" - desc = "Smithed component of any smithing item. Made of brass." - materials = list(MAT_BRASS = 10000) - material = /datum/smith_material/brass - -#undef PART_PRIMARY -#undef PART_SECONDARY -#undef PART_TRIM diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index d49a0f97c40..fda2e7768ae 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -1,8 +1,3 @@ -#define BASE_POINT_MULT 0.90 -#define BASE_SHEET_MULT 0.90 -#define POINT_MULT_ADD_PER_RATING 0.10 -#define SHEET_MULT_ADD_PER_RATING 0.10 - /** * # Ore Redemption Machine * @@ -516,8 +511,3 @@ /obj/machinery/mineral/ore_redemption/proc/on_material_insert(inserted_type, last_inserted_id, inserted) give_points(inserted_type, inserted) SStgui.update_uis(src) - -#undef BASE_POINT_MULT -#undef BASE_SHEET_MULT -#undef POINT_MULT_ADD_PER_RATING -#undef SHEET_MULT_ADD_PER_RATING diff --git a/code/modules/smithing/components/inserts_components.dm b/code/modules/smithing/components/inserts_components.dm new file mode 100644 index 00000000000..663afb46346 --- /dev/null +++ b/code/modules/smithing/components/inserts_components.dm @@ -0,0 +1,131 @@ +/obj/item/smithed_item/component/insert_frame + name = "Debug insert frame" + icon_state = "insert_frame" + desc = "Debug smithed component part of an insert. If you see this, notify the development team." + part_type = PART_PRIMARY + +/obj/item/smithed_item/component/insert_frame/ballistic + name = "ballistic insert frame" + desc = "This is the primary component of a ballistic plate." + materials = list(MAT_METAL = 10000) + finished_product = /obj/item/smithed_item/insert/ballistic + +/obj/item/smithed_item/component/insert_frame/thermal + name = "thermal insert frame" + desc = "This is the primary component of a thermal plate." + materials = list(MAT_GOLD = 6000) + finished_product = /obj/item/smithed_item/insert/thermal + +/obj/item/smithed_item/component/insert_frame/fireproofing + name = "fireproofing insert frame" + desc = "This is the primary component of a fireproofing plate." + materials = list(MAT_SILVER = 10000) + finished_product = /obj/item/smithed_item/insert/fireproofing + +/obj/item/smithed_item/component/insert_frame/reflective + name = "reflective insert frame" + desc = "This is the primary component of a reflective plate." + materials = list(MAT_SILVER = 10000) + finished_product = /obj/item/smithed_item/insert/reflective + +/obj/item/smithed_item/component/insert_frame/rad_hazard + name = "radiation hazard insert frame" + desc = "This is the primary component of a radiation hazard plate." + materials = list(MAT_GOLD = 6000) + finished_product = /obj/item/smithed_item/insert/rad_hazard + +/obj/item/smithed_item/component/insert_frame/rubberized + name = "rubberized insert frame" + desc = "This is the primary component of a rubberized plate." + materials = list(MAT_PLASMA = 10000) + finished_product = /obj/item/smithed_item/insert/rubberized + +/obj/item/smithed_item/component/insert_frame/advanced + name = "advanced insert frame" + desc = "This is the primary component of a advanced armor mesh." + materials = list(MAT_METAL = 10000, MAT_PLASMA = 10000) + finished_product = /obj/item/smithed_item/insert/advanced + +/obj/item/smithed_item/component/insert_frame/engineering + name = "engineering insert frame" + desc = "This is the primary component of a advanced engineering mesh." + materials = list(MAT_GOLD = 10000, MAT_SILVER = 10000) + finished_product = /obj/item/smithed_item/insert/engineering + +/obj/item/smithed_item/component/insert_frame/heavy + name = "heavy duty insert frame" + desc = "This is the primary component of a advanced heavy duty plate." + materials = list(MAT_TITANIUM = 20000, MAT_PLASMA = 20000) + finished_product = /obj/item/smithed_item/insert/heavy + +/obj/item/smithed_item/component/insert_frame/mobility + name = "mobility mesh insert frame" + desc = "This is the primary component of a advanced mobility mesh." + materials = list(MAT_BLUESPACE = 4000) + finished_product = /obj/item/smithed_item/insert/mobility + +/obj/item/smithed_item/component/insert_lining + name = "Debug insert lining" + icon_state = "insert_lining" + desc = "Debug smithed component part of an insert. If you see this, notify the development team." + part_type = PART_SECONDARY + +/obj/item/smithed_item/component/insert_lining/ballistic + name = "ballistic insert lining" + desc = "This is the secondary component of a ballistic plate." + materials = list(MAT_METAL = 10000) + finished_product = /obj/item/smithed_item/insert/ballistic + +/obj/item/smithed_item/component/insert_lining/thermal + name = "thermal insert lining" + desc = "This is the secondary component of a thermal plate." + materials = list(MAT_METAL = 10000) + finished_product = /obj/item/smithed_item/insert/thermal + +/obj/item/smithed_item/component/insert_lining/fireproofing + name = "fireproofing insert lining" + desc = "This is the secondary component of a fireproofing plate." + materials = list(MAT_METAL = 10000, MAT_PLASMA = 10000) + finished_product = /obj/item/smithed_item/insert/fireproofing + +/obj/item/smithed_item/component/insert_lining/reflective + name = "reflective insert lining" + desc = "This is the secondary component of a reflective plate." + materials = list(MAT_GOLD = 6000) + finished_product = /obj/item/smithed_item/insert/reflective + +/obj/item/smithed_item/component/insert_lining/rad_hazard + name = "radiation hazard insert lining" + desc = "This is the secondary component of a radiation hazard plate." + materials = list(MAT_TITANIUM = 10000) + finished_product = /obj/item/smithed_item/insert/rad_hazard + +/obj/item/smithed_item/component/insert_lining/rubberized + name = "rubberized insert lining" + desc = "This is the secondary component of a rubberized plate." + materials = list(MAT_PLASMA = 10000) + finished_product = /obj/item/smithed_item/insert/rubberized + +/obj/item/smithed_item/component/insert_lining/advanced + name = "advanced insert lining" + desc = "This is the secondary component of a advanced armor mesh." + materials = list(MAT_TITANIUM = 10000, MAT_DIAMOND = 2000) + finished_product = /obj/item/smithed_item/insert/advanced + +/obj/item/smithed_item/component/insert_lining/engineering + name = "engineering insert lining" + desc = "This is the secondary component of a advanced engineering mesh." + materials = list(MAT_TITANIUM = 10000, MAT_IRIDIUM = 2000) + finished_product = /obj/item/smithed_item/insert/engineering + +/obj/item/smithed_item/component/insert_lining/heavy + name = "heavy duty insert lining" + desc = "This is the secondary component of a advanced heavy duty plate." + materials = list(MAT_TITANIUM = 10000, MAT_PLATINUM = 2000) + finished_product = /obj/item/smithed_item/insert/heavy + +/obj/item/smithed_item/component/insert_lining/mobility + name = "mobility mesh insert lining" + desc = "This is the secondary component of a advanced mobility mesh." + materials = list(MAT_PALLADIUM = 2000) + finished_product = /obj/item/smithed_item/insert/mobility diff --git a/code/modules/smithing/components/lens_components.dm b/code/modules/smithing/components/lens_components.dm new file mode 100644 index 00000000000..9ccadfc8ee2 --- /dev/null +++ b/code/modules/smithing/components/lens_components.dm @@ -0,0 +1,95 @@ +/obj/item/smithed_item/component/lens_frame + name = "Debug lens frame" + icon_state = "lens_frame" + desc = "Debug smithed component part of a laser lens. If you see this, notify the development team." + part_type = PART_PRIMARY + +/obj/item/smithed_item/component/lens_frame/accelerator + name = "accelerator lens frame" + desc = "This is the primary component of an accelerator lens." + materials = list(MAT_TITANIUM = 4000) + finished_product = /obj/item/smithed_item/lens/accelerator + +/obj/item/smithed_item/component/lens_frame/speed + name = "speed lens frame" + desc = "This is the primary component of a speed lens." + materials = list(MAT_METAL = 4000) + finished_product = /obj/item/smithed_item/lens/speed + +/obj/item/smithed_item/component/lens_frame/amplifier + name = "amplifier lens frame" + desc = "This is the primary component of an amplifier lens." + materials = list(MAT_GOLD = 4000) + finished_product = /obj/item/smithed_item/lens/amplifier + +/obj/item/smithed_item/component/lens_frame/efficiency + name = "efficiency lens frame" + desc = "This is the primary component of an efficiency lens." + materials = list(MAT_SILVER = 4000) + finished_product = /obj/item/smithed_item/lens/efficiency + +/obj/item/smithed_item/component/lens_frame/rapid + name = "rapid lens frame" + desc = "This is the primary component of an advanced rapid lens." + materials = list(MAT_PALLADIUM = 2000) + finished_product = /obj/item/smithed_item/lens/rapid + +/obj/item/smithed_item/component/lens_frame/densifier + name = "densifier lens frame" + desc = "This is the primary component of an advanced densifier lens." + materials = list(MAT_PLATINUM = 2000) + finished_product = /obj/item/smithed_item/lens/densifier + +/obj/item/smithed_item/component/lens_frame/velocity + name = "velocity lens frame" + desc = "This is the primary component of an advanced velocity lens." + materials = list(MAT_BRASS = 30000) + finished_product = /obj/item/smithed_item/lens/velocity + +/obj/item/smithed_item/component/lens_focus + name = "Debug lens focus" + icon_state = "lens_focus" + desc = "Debug smithed component part of a laser lens. If you see this, notify the development team." + part_type = PART_SECONDARY + +/obj/item/smithed_item/component/lens_focus/accelerator + name = "accelerator lens focus" + desc = "This is the secondary component of an accelerator lens." + materials = list(MAT_METAL = 4000, MAT_GLASS = 10000) + finished_product = /obj/item/smithed_item/lens/accelerator + +/obj/item/smithed_item/component/lens_focus/speed + name = "speed lens focus" + desc = "This is the secondary component of a speed lens." + materials = list(MAT_PLASMA = 4000, MAT_GLASS = 10000) + finished_product = /obj/item/smithed_item/lens/speed + +/obj/item/smithed_item/component/lens_focus/amplifier + name = "amplifier lens focus" + desc = "This is the secondary component of an amplifier lens." + materials = list(MAT_TITANIUM = 4000, MAT_GLASS = 10000) + finished_product = /obj/item/smithed_item/lens/amplifier + +/obj/item/smithed_item/component/lens_focus/efficiency + name = "efficiency lens focus" + desc = "This is the secondary component of an efficiency lens." + materials = list(MAT_METAL = 4000, MAT_GLASS = 10000) + finished_product = /obj/item/smithed_item/lens/efficiency + +/obj/item/smithed_item/component/lens_focus/rapid + name = "rapid lens focus" + desc = "This is the secondary component of an advanced rapid lens." + materials = list(MAT_PLASMA = 10000, MAT_GLASS = 10000, MAT_DIAMOND = 2000) + finished_product = /obj/item/smithed_item/lens/rapid + +/obj/item/smithed_item/component/lens_focus/densifier + name = "densifier lens focus" + desc = "This is the secondary component of an advanced densifier lens." + materials = list(MAT_PLASMA = 10000, MAT_GLASS = 10000, MAT_DIAMOND = 2000) + finished_product = /obj/item/smithed_item/lens/densifier + +/obj/item/smithed_item/component/lens_focus/velocity + name = "velocity lens focus" + desc = "This is the secondary component of an advanced velocity lens." + materials = list(MAT_PLASMA = 10000, MAT_GLASS = 10000, MAT_DIAMOND = 2000) + finished_product = /obj/item/smithed_item/lens/velocity diff --git a/code/modules/smithing/components/tool_bits_components.dm b/code/modules/smithing/components/tool_bits_components.dm new file mode 100644 index 00000000000..ee10334104c --- /dev/null +++ b/code/modules/smithing/components/tool_bits_components.dm @@ -0,0 +1,83 @@ +/obj/item/smithed_item/component/bit_mount + name = "Debug bit mount" + icon_state = "bit_mount" + desc = "Debug smithed component part of a tool bit. If you see this, notify the development team." + part_type = PART_PRIMARY + +/obj/item/smithed_item/component/bit_mount/speed + name = "speed bit mount" + desc = "This is the primary component of a speed bit" + materials = list(MAT_TITANIUM = 4000) + finished_product = /obj/item/smithed_item/tool_bit/speed + +/obj/item/smithed_item/component/bit_mount/efficiency + name = "efficiency bit mount" + desc = "This is the primary component of an efficiency bit" + materials = list(MAT_SILVER = 4000) + finished_product = /obj/item/smithed_item/tool_bit/efficiency + +/obj/item/smithed_item/component/bit_mount/balanced + name = "balanced bit mount" + desc = "This is the primary component of an balanced bit." + materials = list(MAT_TITANIUM = 4000) + finished_product = /obj/item/smithed_item/tool_bit/balanced + +/obj/item/smithed_item/component/bit_mount/heavy + name = "heavy duty bit mount" + desc = "This is the primary component of a heavy duty bit." + materials = list(MAT_TITANIUM = 8000, MAT_PLASMA = 8000) + finished_product = /obj/item/smithed_item/tool_bit/heavy + +/obj/item/smithed_item/component/bit_mount/economical + name = "economical bit mount" + desc = "This is the primary component of an economical bit." + materials = list(MAT_TITANIUM = 4000, MAT_PLASMA = 4000) + finished_product = /obj/item/smithed_item/tool_bit/economical + +/obj/item/smithed_item/component/bit_mount/advanced + name = "advanced bit mount" + desc = "This is the primary component of an advanced bit." + materials = list(MAT_TITANIUM = 4000, MAT_PLASMA = 4000) + finished_product = /obj/item/smithed_item/tool_bit/advanced + +/obj/item/smithed_item/component/bit_head + name = "Debug bit head" + icon_state = "bit_head" + desc = "Debug smithed component part of a tool bit. If you see this, notify the development team." + part_type = PART_SECONDARY + +/obj/item/smithed_item/component/bit_head/speed + name = "speed bit head" + desc = "This is the secondary component of a speed bit." + materials = list(MAT_METAL = 4000) + finished_product = /obj/item/smithed_item/tool_bit/speed + +/obj/item/smithed_item/component/bit_head/efficiency + name = "efficiency bit head" + desc = "This is the secondary component of an efficiency bit." + materials = list(MAT_METAL = 4000) + finished_product = /obj/item/smithed_item/tool_bit/efficiency + +/obj/item/smithed_item/component/bit_head/balanced + name = "balanced bit head" + desc = "This is the secondary component of a balanced bit." + materials = list(MAT_BRASS = 4000) + finished_product = /obj/item/smithed_item/tool_bit/balanced + +/obj/item/smithed_item/component/bit_head/heavy + name = "heavy duty bit head" + desc = "This is the secondary component of a heavy duty bit." + materials = list(MAT_METAL = 8000, MAT_PLASMA = 8000) + finished_product = /obj/item/smithed_item/tool_bit/heavy + +/obj/item/smithed_item/component/bit_head/economical + name = "economical bit head" + desc = "This is the secondary component of an economical bit." + materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000) + finished_product = /obj/item/smithed_item/tool_bit/economical + +/obj/item/smithed_item/component/bit_head/advanced + name = "advanced bit head" + desc = "This is the secondary component of an advanced bit." + materials = list(MAT_METAL = 4000, MAT_PLATINUM = 4000) + finished_product = /obj/item/smithed_item/tool_bit/advanced diff --git a/code/modules/smithing/components/trim.dm b/code/modules/smithing/components/trim.dm new file mode 100644 index 00000000000..8530769acf4 --- /dev/null +++ b/code/modules/smithing/components/trim.dm @@ -0,0 +1,95 @@ +/obj/item/smithed_item/component/trim + name = "Debug trim" + icon_state = "trim" + desc = "Debug smithed component part of any smithed item. If you see this, notify the development team." + part_type = PART_TRIM + +/obj/item/smithed_item/component/trim/set_name() + if(!quality) + return + name = "[quality.name] " + name + return + +/obj/item/smithed_item/component/trim/metal + name = "metal trim" + desc = "Smithed component of any smithing item. Made of metal." + materials = list(MAT_METAL = 10000) + material = /datum/smith_material/metal + +/obj/item/smithed_item/component/trim/silver + name = "silver trim" + desc = "Smithed component of any smithing item. Made of silver." + materials = list(MAT_SILVER = 10000) + material = /datum/smith_material/silver + +/obj/item/smithed_item/component/trim/gold + name = "gold trim" + desc = "Smithed component of any smithing item. Made of gold." + materials = list(MAT_GOLD = 10000) + material = /datum/smith_material/gold + +/obj/item/smithed_item/component/trim/plasma + name = "plasma trim" + desc = "Smithed component of any smithing item. Made of solid plasma." + materials = list(MAT_PLASMA = 10000) + material = /datum/smith_material/plasma + +/obj/item/smithed_item/component/trim/titanium + name = "titanium trim" + desc = "Smithed component of any smithing item. Made of titanium." + materials = list(MAT_TITANIUM = 10000) + material = /datum/smith_material/titanium + +/obj/item/smithed_item/component/trim/uranium + name = "uranium trim" + desc = "Smithed component of any smithing item. Made of uranium." + materials = list(MAT_URANIUM = 10000) + material = /datum/smith_material/uranium + +/obj/item/smithed_item/component/trim/diamond + name = "diamond trim" + desc = "Smithed component of any smithing item. Made of diamond." + materials = list(MAT_DIAMOND = 10000) + material = /datum/smith_material/diamond + +/obj/item/smithed_item/component/trim/bluespace + name = "bluespace trim" + desc = "Smithed component of any smithing item. Made of bluespace crystals." + materials = list(MAT_BLUESPACE = 10000) + material = /datum/smith_material/bluespace + +/obj/item/smithed_item/component/trim/plasteel + name = "plasteel trim" + desc = "Smithed component of any smithing item. Made of plasteel." + materials = list(MAT_METAL = 10000, MAT_PLASMA = 10000) + material = /datum/smith_material/plasteel + +/obj/item/smithed_item/component/trim/plastitanium + name = "plastitanium trim" + desc = "Smithed component of any smithing item. Made of plastitanium." + materials = list(MAT_TITANIUM = 10000, MAT_PLASMA = 10000) + material = /datum/smith_material/plastitanium + +/obj/item/smithed_item/component/trim/iridium + name = "iridium trim" + desc = "Smithed component of any smithing item. Made of iridium." + materials = list(MAT_IRIDIUM = 10000) + material = /datum/smith_material/iridium + +/obj/item/smithed_item/component/trim/palladium + name = "palladium trim" + desc = "Smithed component of any smithing item. Made of palladium." + materials = list(MAT_PALLADIUM = 10000) + material = /datum/smith_material/palladium + +/obj/item/smithed_item/component/trim/platinum + name = "platinum trim" + desc = "Smithed component of any smithing item. Made of platinum." + materials = list(MAT_PLATINUM = 10000) + material = /datum/smith_material/platinum + +/obj/item/smithed_item/component/trim/brass + name = "brass trim" + desc = "Smithed component of any smithing item. Made of brass." + materials = list(MAT_BRASS = 10000) + material = /datum/smith_material/brass diff --git a/code/modules/smithing/machinery/casting_basin.dm b/code/modules/smithing/machinery/casting_basin.dm new file mode 100644 index 00000000000..5cdda3a5de3 --- /dev/null +++ b/code/modules/smithing/machinery/casting_basin.dm @@ -0,0 +1,239 @@ +/obj/machinery/smithing/casting_basin + name = "casting basin" + desc = "A table with a large basin for pouring molten metal. It has a slot for a mold." + icon = 'icons/obj/machines/smithing_machines.dmi' + icon_state = "casting_open" + max_integrity = 100 + pixel_x = 0 // 1x1 + pixel_y = 0 + bound_height = 32 + bound_width = 32 + bound_y = 0 + /// Linked magma crucible + var/obj/machinery/magma_crucible/linked_crucible + /// Operational Efficiency + var/efficiency = 1 + /// Inserted cast + var/obj/item/smithing_cast/cast + /// Finished product + var/obj/item/smithed_item/component/produced_item + +/obj/machinery/smithing/casting_basin/Initialize(mapload) + . = ..() + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/casting_basin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stack/sheet/glass(null) + RefreshParts() + // Try to link to magma crucible on initialize. Link to the first crucible it can find. + for(var/obj/machinery/magma_crucible/crucible in view(2, src)) + linked_crucible = crucible + linked_crucible.linked_machines |= src + return + +/obj/machinery/smithing/casting_basin/examine(mob/user) + . = ..() + if(cast) + . += "You can activate the machine with your hand, or remove the cast by alt-clicking." + . += "There is a [cast] in the cast slot." + . += "Currently set to produce: [cast.selected_product.name]" + if(istype(cast, /obj/item/smithing_cast/component) && !produced_item) + var/obj/item/temp_product = new cast.selected_product(src) // This is necessary due to selected_product being a type + var/obj/item/smithing_cast/component/comp_cast = cast + var/datum/smith_quality/quality = new comp_cast.quality + . += "Required Resources:" + var/MAT + // Get the materials the item needs and display + for(MAT in temp_product.materials) + . += " - [MAT]: [ROUND_UP(((temp_product.materials[MAT] * quality.material_mult) * efficiency) / MINERAL_MATERIAL_AMOUNT)] sheets." + // Get rid of the temp product + qdel(temp_product) + + if(produced_item) + . += "There is a [produced_item] in the machine. You can pick it up with your hand." + +/obj/machinery/smithing/casting_basin/RefreshParts() + var/operation_mult = 0 + var/efficiency_mult = 0 + for(var/obj/item/stock_parts/component in component_parts) + operation_mult += 2 * OPERATION_SPEED_MULT_PER_RATING * component.rating + efficiency_mult += EFFICIENCY_MULT_ADD_PER_RATING * component.rating + // Update our values + operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) + efficiency = initial(efficiency) * (1.1 - efficiency_mult) + +/obj/machinery/smithing/casting_basin/update_overlays() + . = ..() + overlays.Cut() + if(produced_item) + . += "casting_closed" + if(cast && !produced_item) + if(istype(cast, /obj/item/smithing_cast/sheet)) + . += "cast_sheet" + else if(istype(cast, /obj/item/smithing_cast/component/insert_frame)) + . += "cast_armorframe" + else if(istype(cast, /obj/item/smithing_cast/component/insert_lining)) + . += "cast_mesh" + else if(istype(cast, /obj/item/smithing_cast/component/bit_mount)) + . += "cast_bitmount" + else if(istype(cast, /obj/item/smithing_cast/component/bit_head)) + . += "cast_bithead" + else if(istype(cast, /obj/item/smithing_cast/component/lens_focus)) + . += "cast_focus" + else if(istype(cast, /obj/item/smithing_cast/component/lens_frame)) + . += "cast_lens" + else if(istype(cast, /obj/item/smithing_cast/component/trim)) + . += "cast_trim" + . += "casting_lip" + if(panel_open) + . += "casting_wires" + if(operating) + . += "casting_pour" + +/obj/machinery/smithing/casting_basin/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/smithing/casting_basin/multitool_act(mob/living/user, obj/item/I) + if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + return + if(!I.multitool_check_buffer(user)) + return + if(panel_open) + var/obj/item/multitool/multi = I + if(!istype(multi.buffer, /obj/machinery/magma_crucible)) + to_chat(user, "You cannot link [src] to [multi.buffer]!") + return + linked_crucible = multi.buffer + linked_crucible.linked_machines |= src + to_chat(user, "You link [src] to [multi.buffer].") + +/obj/machinery/smithing/casting_basin/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(!istype(used, /obj/item/smithing_cast)) + to_chat(user, "[used] does not fit in [src]'s cast slot.") + return + + if(cast) + to_chat(user, "[src] already has a cast inserted.") + return + + if(used.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[used] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + cast = used + update_icon(UPDATE_OVERLAYS) + return ITEM_INTERACT_COMPLETE + +/obj/machinery/smithing/casting_basin/AltClick(mob/living/user) + if(!Adjacent(user)) + return + if(!cast) + to_chat(user, "There is no cast to remove.") + return + if(operating) + to_chat(user, "[src] is currently operating!") + return + user.put_in_hands(cast) + cast = null + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/smithing/casting_basin/attack_hand(mob/user) + if(produced_item) + if(produced_item.burn_check(user)) + produced_item.burn_user(user) + produced_item.forceMove(user.loc) + produced_item = null + return FINISH_ATTACK + user.put_in_hands(produced_item) + produced_item = null + update_icon(UPDATE_OVERLAYS) + return FINISH_ATTACK + if(!cast) + to_chat(user, "There is no cast inserted!") + return FINISH_ATTACK + if(!linked_crucible) + to_chat(user, "There is no linked magma crucible!") + return FINISH_ATTACK + if(operating) + to_chat(user, "[src] is currently operating!") + return FINISH_ATTACK + + var/datum/component/material_container/materials = linked_crucible.GetComponent(/datum/component/material_container) + var/obj/item/temp_product = new cast.selected_product // Product is stored as a type, I need a temporary item for handling material calcs + var/amount = cast.amount_to_make + var/MAT + + if(!istype(temp_product)) + to_chat(user, "The product is not an item! This is a problem you should make an issue report about!") + log_debug("Attempted to make [temp_product] at a casting basin, product is not an item.") + return FINISH_ATTACK + + if(istype(cast, /obj/item/smithing_cast/component)) + var/obj/item/smithing_cast/component/comp_cast = cast + var/datum/smith_quality/quality = new comp_cast.quality + var/list/used_mats = list() + + // Check if there is enough materials to craft the item + for(MAT in temp_product.materials) + used_mats[MAT] = (temp_product.materials[MAT] * quality.material_mult) * efficiency + + if(!materials.has_materials(used_mats, 1)) + to_chat(user, "Not enough materials in the crucible to smelt [temp_product.name]!") + qdel(temp_product) + return FINISH_ATTACK + + to_chat(user, "You begin to pour the liquid minerals into the [src]...") + // Use the materials and create the item. + materials.use_amount(used_mats) + linked_crucible.animate_pour(operation_time SECONDS) + operate(operation_time, user) + produced_item = new cast.selected_product(src) + produced_item.quality = quality + produced_item.set_worktime() + produced_item.update_appearance(UPDATE_NAME) + produced_item.update_icon(UPDATE_ICON_STATE) + update_icon(UPDATE_OVERLAYS) + // Clean up temps + qdel(temp_product) + return FINISH_ATTACK + + if(istype(cast, /obj/item/smithing_cast/sheet)) + // Get max amount of sheets (0-50) + var/datum/material/M + var/stored + + // Check if there is enough materials to craft the item + for(MAT in temp_product.materials) + M = materials.materials[MAT] + if(!stored) + stored = M.amount / MINERAL_MATERIAL_AMOUNT + else + stored = min(M.amount / MINERAL_MATERIAL_AMOUNT, stored) + if(istype(cast, /obj/item/smithing_cast/sheet)) + amount = min(amount, stored, MAX_STACK_SIZE) + if(!amount) + to_chat(user, "Not enough materials in the crucible to smelt a sheet of [temp_product.name]!") + qdel(temp_product) + return FINISH_ATTACK + + to_chat(user, "You begin to pour the liquid minerals into the [src]...") + playsound(src, 'sound/machines/recycler.ogg', 50, TRUE) + // Use the materials and create the item. + materials.use_amount(temp_product.materials, amount) + linked_crucible.animate_pour(operation_time SECONDS) + operate(operation_time, user) + var/obj/item/stack/new_stack = new cast.selected_product(src.loc) + new_stack.amount = amount + new_stack.update_icon(UPDATE_ICON_STATE) + + // Clean up temps + qdel(temp_product) + return FINISH_ATTACK + +/obj/machinery/smithing/casting_basin/Destroy() + if(linked_crucible) + linked_crucible.linked_machines -= src + linked_crucible = null + return ..() diff --git a/code/modules/smithing/machinery/kinetic_assembler.dm b/code/modules/smithing/machinery/kinetic_assembler.dm new file mode 100644 index 00000000000..273b326ece6 --- /dev/null +++ b/code/modules/smithing/machinery/kinetic_assembler.dm @@ -0,0 +1,216 @@ +/obj/machinery/smithing/kinetic_assembler + name = "kinetic assembler" + desc = "A smart assembler that takes components and combines them at the strike of a hammer." + icon = 'icons/obj/machines/smithing_machines.dmi' + icon_state = "assembler" + max_integrity = 100 + pixel_x = 0 // 1x1 + pixel_y = 0 + bound_height = 32 + bound_width = 32 + bound_y = 0 + operation_sound = 'sound/items/welder.ogg' + /// Primary component + var/obj/item/smithed_item/component/primary + /// Secondary component + var/obj/item/smithed_item/component/secondary + /// Trim component + var/obj/item/smithed_item/component/trim + /// Finished product + var/obj/item/smithed_item/finished_product + +/obj/machinery/smithing/kinetic_assembler/Initialize(mapload) + . = ..() + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/kinetic_assembler(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/stack/sheet/glass(null) + RefreshParts() + +/obj/machinery/smithing/kinetic_assembler/examine(mob/user) + . = ..() + if(primary || secondary || trim) + . += "You can activate the machine with your hand, or remove a component by alt-clicking." + if(primary) + . += "There is a [primary] in the primary slot." + if(secondary) + . += "There is a [secondary] in the primary slot." + if(trim) + . += "There is a [trim] in the primary slot." + if(finished_product) + . += "There is a nearly-complete [finished_product] on the assembler. To complete the product, strike it with your hammer!" + +/obj/machinery/smithing/kinetic_assembler/RefreshParts() + var/operation_mult = 0 + for(var/obj/item/stock_parts/component in component_parts) + operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating + // Update our values + operation_time = operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) + +/obj/machinery/smithing/kinetic_assembler/update_icon_state() + . = ..() + if(panel_open) + icon_state = "assembler_wires" + +/obj/machinery/smithing/kinetic_assembler/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_ICON_STATE) + +/obj/machinery/smithing/kinetic_assembler/update_overlays() + . = ..() + overlays.Cut() + if(panel_open) + icon_state = "assembler_wires" + +/obj/machinery/smithing/kinetic_assembler/AltClick(mob/living/user) + if(!Adjacent(user)) + return + if(!primary && !secondary && !trim) + to_chat(user, "There is no component to remove.") + return + var/list/components = list("Primary", "Secondary", "Trim") + var/removed = tgui_input_list(user, "Select a component to remove", src, components) + if(!removed) + return + switch(removed) + if("Primary") + to_chat(user, "You remove [primary] from the primary component slot of [src].") + if(primary.burn_check(user)) + primary.burn_user(user) + primary.forceMove(user.loc) + primary = null + return + user.put_in_hands(primary) + primary = null + return + if("Secondary") + to_chat(user, "You remove [secondary] from the secondary component slot of [src].") + if(secondary.burn_check(user)) + secondary.burn_user(user) + secondary.forceMove(user.loc) + secondary = null + return + user.put_in_hands(secondary) + secondary = null + return + if("Trim") + to_chat(user, "You remove [trim] from the trim component slot of [src].") + if(trim.burn_check(user)) + trim.burn_user(user) + trim.forceMove(user.loc) + trim = null + return + user.put_in_hands(trim) + trim = null + return + +/obj/machinery/smithing/kinetic_assembler/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(operating) + to_chat(user, "[src] is still operating!") + return ITEM_INTERACT_COMPLETE + + if(istype(used, /obj/item/hammer)) + return ITEM_INTERACT_COMPLETE + + if(!istype(used, /obj/item/smithed_item/component)) + to_chat(user, "You feel like there's no reason to process [used].") + return ITEM_INTERACT_COMPLETE + + if(finished_product) + to_chat(user, "There is an almost finished [finished_product] in [src]!") + return ITEM_INTERACT_COMPLETE + + var/obj/item/smithed_item/component/comp = used + if(comp.hammer_time) + to_chat(user, "[used] is not complete yet!") + return ITEM_INTERACT_COMPLETE + + if(comp.part_type == PART_PRIMARY) + if(primary) + to_chat(user, "You remove [primary] from the primary component slot of [src].") + primary.forceMove(src.loc) + primary = null + if(comp.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[comp] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + to_chat(user, "You insert [comp] into the primary component slot of [src].") + primary = comp + return ITEM_INTERACT_COMPLETE + + if(comp.part_type == PART_SECONDARY) + if(secondary) + to_chat(user, "You remove [secondary] from the secondary component slot of [src].") + secondary.forceMove(src.loc) + secondary = null + if(comp.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[comp] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + to_chat(user, "You insert [comp] into the secondary component slot of [src].") + secondary = comp + return ITEM_INTERACT_COMPLETE + + if(comp.part_type == PART_TRIM) + if(trim) + to_chat(user, "You remove [trim] from the trim component slot of [src].") + trim.forceMove(src.loc) + trim = null + if(comp.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[comp] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + to_chat(user, "You insert [comp] into the trim component slot of [src].") + trim = comp + return ITEM_INTERACT_COMPLETE + +/obj/machinery/smithing/kinetic_assembler/attack_hand(mob/user) + if(!primary) + to_chat(user, "[src] lacks a primary component!") + return FINISH_ATTACK + + if(!secondary) + to_chat(user, "[src] lacks a secondary component!") + return FINISH_ATTACK + + if(!trim) + to_chat(user, "[src] lacks a trim component!") + return FINISH_ATTACK + + if(primary.finished_product != secondary.finished_product) + to_chat(user, "[primary] does not match [secondary]!") + return FINISH_ATTACK + + operate(operation_time, user) + return FINISH_ATTACK + +/obj/machinery/smithing/kinetic_assembler/operate(loops, mob/living/user) + ..() + finished_product = new primary.finished_product(src) + var/quality_list = list(primary.quality, secondary.quality, trim.quality) + var/datum/smith_quality/lowest = quality_list[1] + for(var/datum/smith_quality/quality in quality_list) + if(quality.stat_mult < lowest.stat_mult) + lowest = quality + finished_product.quality = lowest + finished_product.material = trim.material + finished_product.set_stats() + finished_product.update_appearance(UPDATE_NAME) + qdel(primary) + qdel(secondary) + qdel(trim) + primary = null + secondary = null + trim = null + +/obj/machinery/smithing/kinetic_assembler/hammer_act(mob/user, obj/item/i) + if(operating) + to_chat(user, "[src] is still operating!") + return + if(!finished_product) + to_chat(user, "There is no finished product ready!") + return + playsound(src, 'sound/magic/fellowship_armory.ogg', 50, TRUE) + finished_product.forceMove(src.loc) + finished_product = null diff --git a/code/modules/smithing/machinery/lava_furnace.dm b/code/modules/smithing/machinery/lava_furnace.dm new file mode 100644 index 00000000000..8ae84454e25 --- /dev/null +++ b/code/modules/smithing/machinery/lava_furnace.dm @@ -0,0 +1,80 @@ +/obj/machinery/smithing/lava_furnace + name = "lava furnace" + desc = "A furnace that uses the innate heat of lavaland to reheat metal that has not been fully reshaped." + icon = 'icons/obj/machines/large_smithing_machines.dmi' + icon_state = "furnace_off" + operation_sound = 'sound/surgery/cautery1.ogg' + +/obj/machinery/smithing/lava_furnace/Initialize(mapload) + . = ..() + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/lava_furnace(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/assembly/igniter(null) + RefreshParts() + +/obj/machinery/smithing/lava_furnace/RefreshParts() + var/operation_mult = 0 + for(var/obj/item/stock_parts/component in component_parts) + operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating + // Update our values + operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) + +/obj/machinery/smithing/lava_furnace/update_overlays() + . = ..() + overlays.Cut() + if(panel_open) + . += "furnace_wires" + +/obj/machinery/smithing/lava_furnace/update_icon_state() + . = ..() + if(operating) + icon_state = "furnace" + else + icon_state = "furnace_off" + +/obj/machinery/smithing/lava_furnace/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/smithing/lava_furnace/operate(loops, mob/living/user) + if(working_component.hot) + to_chat(user, "[working_component] is already well heated.") + return + if(working_component.hammer_time <= 0) + to_chat(user, "[working_component] is already fully shaped.") + return + ..() + working_component.heat_up() + +/obj/machinery/smithing/lava_furnace/attack_hand(mob/user) + . = ..() + if(operating) + to_chat(user, "[src] is currently operating!") + return + if(!working_component) + to_chat(user, "There is nothing in [src]!") + return + + operate(operation_time, user) + return FINISH_ATTACK + +/obj/machinery/smithing/lava_furnace/special_attack(mob/user, mob/living/target) + var/obj/item/organ/external/head/head = target.get_organ(BODY_ZONE_HEAD) + if(!istype(head)) + to_chat(user, "This person doesn't have a head!") + return FALSE + target.visible_message("[user] pushes [target]'s head into [src]!", \ + "[user] pushes your head into [src]! The heat is agonizing!") + var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, attack_flag = MELEE, armour_penetration_percentage = 50) + target.apply_damage(40, BURN, BODY_ZONE_HEAD, armor) + target.adjust_fire_stacks(5) + target.IgniteMob() + target.emote("scream") + playsound(src, operation_sound, 50, TRUE) + add_attack_logs(user, target, "Burned with [src]") + return TRUE diff --git a/code/modules/smithing/machinery/magma_crucible.dm b/code/modules/smithing/machinery/magma_crucible.dm new file mode 100644 index 00000000000..60693b1860f --- /dev/null +++ b/code/modules/smithing/machinery/magma_crucible.dm @@ -0,0 +1,134 @@ +/obj/machinery/magma_crucible + name = "magma crucible" + desc = "A massive machine that smelts down raw ore into a fine slurry, then sorts it into respective tanks for storage and use." + icon = 'icons/obj/machines/magma_crucible.dmi' + icon_state = "crucible" + max_integrity = 300 + pixel_x = -32 // 3x3 + pixel_y = -32 + bound_width = 96 + bound_x = -32 + bound_height = 96 + bound_y = -32 + anchored = TRUE + density = TRUE + resistance_flags = FIRE_PROOF + /// Sheet multiplier applied when smelting ore. + var/sheet_per_ore = 1 + /// State for adding ore + var/adding_ore + /// State for if ore is being taken from it + var/pouring + /// List of linked machines + var/list/linked_machines = list() + +/obj/machinery/magma_crucible/Initialize(mapload) + . = ..() + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE, MAT_PALLADIUM, MAT_IRIDIUM, MAT_PLATINUM, MAT_BRASS), INFINITY, FALSE, list(/obj/item/stack, /obj/item/smithed_item), null, null) + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/magma_crucible(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/stock_parts/micro_laser(null) + component_parts += new /obj/item/assembly/igniter(null) + RefreshParts() + +/obj/machinery/magma_crucible/screwdriver_act(mob/user, obj/item/I) + if(!I.use_tool(src, user, 0, volume = 0)) + return + . = TRUE + default_deconstruction_screwdriver(user, icon_state, icon_state, I) + +/obj/machinery/magma_crucible/crowbar_act(mob/user, obj/item/I) + if(default_deconstruction_crowbar(user, I)) + return TRUE + +/obj/machinery/magma_crucible/RefreshParts() + var/sheet_mult = BASE_SHEET_MULT + for(var/obj/item/stock_parts/micro_laser/component in component_parts) + sheet_mult += SHEET_MULT_ADD_PER_RATING * component.rating + // Update our values + sheet_per_ore = sheet_mult + +/obj/machinery/magma_crucible/update_overlays() + . = ..() + overlays.Cut() + if(adding_ore) + . += "crucible_input" + if(panel_open) + . += "crucible_wires" + if(pouring) + . += "crucible_output" + +/obj/machinery/magma_crucible/update_icon_state() + . = ..() + if(!has_power()) + icon_state = "[initial(icon_state)]_off" + else + icon_state = initial(icon_state) + +/obj/machinery/magma_crucible/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/magma_crucible/Destroy() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + materials.retrieve_all() + for(var/obj/machinery/machine in linked_machines) + if(istype(machine, /obj/machinery/mineral/smart_hopper)) + var/obj/machinery/mineral/smart_hopper/hopper = machine + hopper.linked_crucible = null + if(istype(machine, /obj/machinery/smithing/casting_basin)) + var/obj/machinery/smithing/casting_basin/basin = machine + basin.linked_crucible = null + linked_machines.Cut() + return ..() + +/obj/machinery/magma_crucible/power_change() + if(!..()) + return + update_icon(UPDATE_ICON_STATE) + +/obj/machinery/magma_crucible/proc/animate_transfer(time_to_animate) + adding_ore = TRUE + update_icon(UPDATE_OVERLAYS) + addtimer(CALLBACK(src, PROC_REF(stop_animating)), time_to_animate) + +/obj/machinery/magma_crucible/proc/stop_animating() + adding_ore = FALSE + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/magma_crucible/proc/animate_pour(time_to_animate) + pouring = TRUE + update_icon(UPDATE_OVERLAYS) + addtimer(CALLBACK(src, PROC_REF(stop_pouring)), time_to_animate) + +/obj/machinery/magma_crucible/proc/stop_pouring() + pouring = FALSE + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/magma_crucible/multitool_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + return + if(panel_open) + if(!I.multitool_check_buffer(user)) + return + var/obj/item/multitool/multi = I + multi.set_multitool_buffer(user, src) + to_chat(user, "You save [src]'s linking data to the buffer.") + return + + var/list/msgs = list() + msgs += "Scanning contents of [src]:" + + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + for(var/MAT in materials.materials) + var/datum/material/M = materials.materials[MAT] + if(!M) + continue + msgs += "[M.name]: [floor(M.amount / MINERAL_MATERIAL_AMOUNT)] sheets." + to_chat(user, chat_box_regular(msgs.Join("
"))) diff --git a/code/modules/smithing/machinery/power_hammer.dm b/code/modules/smithing/machinery/power_hammer.dm new file mode 100644 index 00000000000..425f09e23ac --- /dev/null +++ b/code/modules/smithing/machinery/power_hammer.dm @@ -0,0 +1,94 @@ +/obj/machinery/smithing/power_hammer + name = "power hammer" + desc = "A heavy-duty pneumatic hammer designed to shape and mold molten metal." + icon = 'icons/obj/machines/large_smithing_machines.dmi' + icon_state = "power_hammer" + operation_sound = 'sound/magic/fellowship_armory.ogg' + +/obj/machinery/smithing/power_hammer/Initialize(mapload) + . = ..() + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/power_hammer(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stack/sheet/plasteel(null) + RefreshParts() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/smithing/power_hammer/update_overlays() + . = ..() + overlays.Cut() + if(operating) + . += "hammer_hit" + else + . += "hammer_idle" + if(panel_open) + . += "hammer_wires" + if(has_power()) + . += "hammer_fan_on" + +/obj/machinery/smithing/power_hammer/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/smithing/power_hammer/RefreshParts() + var/operation_mult = 0 + for(var/obj/item/stock_parts/component in component_parts) + operation_mult += OPERATION_SPEED_MULT_PER_RATING * component.rating + // Update our values + operation_time = max(ROUND_UP(initial(operation_time) * (1.3 - operation_mult)), 2) + +/obj/machinery/smithing/power_hammer/operate(loops, mob/living/user) + if(!working_component.hot) + to_chat(user, "[working_component] is too cold to properly shape.") + return + if(working_component.hammer_time <= 0) + to_chat(user, "[working_component] is already fully shaped.") + return + ..() + working_component.powerhammer() + do_sparks(5, TRUE, src) + // If the hammer is set to repeat mode, let it repeat operations automatically. + if(repeating && working_component.hot && working_component.hammer_time) + operate(loops, user) + // When an item is done, beep. + if(!working_component.hammer_time) + playsound(src, 'sound/machines/boop.ogg', 50, TRUE) + +/obj/machinery/smithing/power_hammer/multitool_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + return + if(!repeating) + repeating = TRUE + to_chat(user, "You set [src] to auto-repeat.") + else + repeating = FALSE + to_chat(user, "You set [src] to not auto-repeat.") + +/obj/machinery/smithing/power_hammer/attack_hand(mob/user) + . = ..() + if(operating) + to_chat(user, "[src] is currently operating!") + return + operate(operation_time, user) + update_icon(UPDATE_ICON_STATE) + return FINISH_ATTACK + +/obj/machinery/smithing/power_hammer/special_attack(mob/user, mob/living/target) + var/obj/item/organ/external/head/head = target.get_organ(BODY_ZONE_HEAD) + if(!istype(head)) + to_chat(user, "This person doesn't have a head!") + return FALSE + target.visible_message("[user] hammers [target]'s head with [src]!", \ + "[user] hammers your head with [src]! Did somebody get the license plate on that car?") + var/armor = target.run_armor_check(def_zone = BODY_ZONE_HEAD, attack_flag = MELEE, armour_penetration_percentage = 50) + target.apply_damage(40, BRUTE, BODY_ZONE_HEAD, armor) + target.Weaken(4 SECONDS) + target.emote("scream") + playsound(src, operation_sound, 50, TRUE) + add_attack_logs(user, target, "Hammered with [src]") + return TRUE diff --git a/code/modules/smithing/machinery/smart_hopper.dm b/code/modules/smithing/machinery/smart_hopper.dm new file mode 100644 index 00000000000..152d7e2be09 --- /dev/null +++ b/code/modules/smithing/machinery/smart_hopper.dm @@ -0,0 +1,214 @@ +/obj/machinery/mineral/smart_hopper + name = "smart hopper" + desc = "An electronic deposit bin that accepts raw ores and delivers them to an adjacent magma crucible." + icon = 'icons/obj/machines/smithing_machines.dmi' + icon_state = "hopper" + anchored = TRUE + density = TRUE + resistance_flags = FIRE_PROOF + /// Linked magma crucible + var/obj/machinery/magma_crucible/linked_crucible + /// Access to claim points + var/req_access_claim = ACCESS_MINING_STATION + /// The number of unclaimed points. + var/points = 0 + /// Point multiplier + var/point_upgrade = 1 + /// List of ore yet to process. + var/list/obj/item/stack/ore/ore_buffer = list() + /// Whether the message to relevant supply consoles was sent already or not for an ore dump. If FALSE, another will be sent. + var/message_sent = TRUE + /// If TRUE, [/obj/machinery/mineral/smart_hopper/var/req_access_claim] is ignored and any ID may be used to claim points. + var/anyone_claim = FALSE + /// What consoles get alerted when this is filled + var/list/supply_consoles = list( + "Smith's Office", + "Quartermaster's Desk" + ) + +/obj/machinery/mineral/smart_hopper/Initialize(mapload) + . = ..() + // Stock parts + component_parts = list() + component_parts += new /obj/item/circuitboard/smart_hopper(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/matter_bin(null) + component_parts += new /obj/item/stock_parts/manipulator(null) + component_parts += new /obj/item/stack/sheet/glass(null) + RefreshParts() + // Try to link to magma crucible on initialize. Link to the first crucible it can find. + for(var/obj/machinery/magma_crucible/crucible in view(2, src)) + linked_crucible = crucible + linked_crucible.linked_machines |= src + return + +/obj/machinery/mineral/smart_hopper/update_overlays() + . = ..() + overlays.Cut() + if(panel_open) + . += "hopper_wires" + +/obj/machinery/mineral/smart_hopper/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/I) + . = ..() + update_icon(UPDATE_OVERLAYS) + +/obj/machinery/mineral/smart_hopper/RefreshParts() + var/point_mult = BASE_POINT_MULT + for(var/obj/item/stock_parts/component in component_parts) + point_mult += POINT_MULT_ADD_PER_RATING * component.rating + // Update our values + point_upgrade = point_mult + SStgui.update_uis(src) + +/obj/machinery/mineral/smart_hopper/process() + if(panel_open || !has_power()) + return + // Check if the input turf has a [/obj/structure/ore_box] to draw ore from. Otherwise suck ore from the turf + var/atom/input = get_step(src, input_dir) + var/obj/structure/ore_box/OB = locate() in input + if(OB) + input = OB + // Suck the ore in + for(var/obj/item/stack/ore/ore in input) + if(QDELETED(ore)) + continue + ore_buffer |= ore + ore.forceMove(src) + CHECK_TICK + // Process it + if(length(ore_buffer)) + message_sent = FALSE + process_ores(ore_buffer) + else if(!message_sent) + send_console_message() + message_sent = TRUE + +// Interactions +/obj/machinery/mineral/smart_hopper/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/storage/part_replacer)) + return ..() + + if(!has_power()) + return ..() + + if(istype(used, /obj/item/card/id)) + var/obj/item/card/id/ID = used + if(!points) + to_chat(user, "There are no points to claim."); + return ITEM_INTERACT_COMPLETE + if(anyone_claim || (req_access_claim in ID.access)) + ID.mining_points += points + ID.total_mining_points += points + to_chat(user, "[points] Mining Points claimed. You have earned a total of [ID.total_mining_points] Mining Points this Shift!") + points = 0 + else + to_chat(user, "Required access not found.") + add_fingerprint(user) + return ITEM_INTERACT_COMPLETE + return ..() + +/obj/machinery/mineral/smart_hopper/multitool_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + return + if(!I.multitool_check_buffer(user)) + return + if(panel_open) + var/obj/item/multitool/multi = I + if(!istype(multi.buffer, /obj/machinery/magma_crucible)) + to_chat(user, "You cannot link [src] to [multi.buffer]!") + return + linked_crucible = multi.buffer + linked_crucible.linked_machines |= src + to_chat(user, "You link [src] to [multi.buffer].") + +/obj/machinery/mineral/smart_hopper/crowbar_act(mob/user, obj/item/I) + if(default_deconstruction_crowbar(user, I)) + return TRUE + +/obj/machinery/mineral/smart_hopper/screwdriver_act(mob/user, obj/item/I) + if(!I.use_tool(src, user, 0, volume = 0)) + return + . = TRUE + default_deconstruction_screwdriver(user, icon_state, icon_state, I) + +/obj/machinery/mineral/smart_hopper/wrench_act(mob/living/user, obj/item/I) + if(!panel_open) + return + . = TRUE + if(!has_power()) + return + if(!I.tool_start_check(src, user, 0)) + return + input_dir = turn(input_dir, -90) + to_chat(user, "You change [src]'s input, moving the input to [dir2text(input_dir)].") + +/obj/machinery/mineral/smart_hopper/Destroy() + if(linked_crucible) + linked_crucible.linked_machines -= src + linked_crucible = null + if(ore_buffer) + for(var/obj/item/ores in ore_buffer) + ores.forceMove(src.loc) + return ..() + +/obj/machinery/mineral/smart_hopper/proc/process_ores(list/obj/item/stack/ore/ore_list) + if(!linked_crucible) + return + for(var/ore in ore_list) + transfer_ore(ore) + +/obj/machinery/mineral/smart_hopper/proc/transfer_ore(obj/item/stack/ore/O) + if(!linked_crucible) + return + // Award points if the ore is actually transferable to the magma crucible + give_points(O.type, O.amount) + animate_transfer(O.amount) + // Insert materials + var/datum/component/material_container/materials = linked_crucible.GetComponent(/datum/component/material_container) + var/amount_compatible = materials.get_item_material_amount(O) + if(amount_compatible) + // Prevents duping + if(O.refined_type) + materials.insert_item(O, linked_crucible.sheet_per_ore) + else + materials.insert_item(O, 1) + // Delete the stack + ore_buffer -= O + qdel(O) + +/obj/machinery/mineral/smart_hopper/proc/send_console_message() + if(!is_station_level(z)) + return + + var/list/msg = list("Now available in [get_area_name(src, TRUE) || "Unknown"]:") + var/mats_in_stock = list() + var/datum/component/material_container/materials = linked_crucible.GetComponent(/datum/component/material_container) + for(var/MAT in materials.materials) + var/datum/material/M = materials.materials[MAT] + var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT + if(mineral_amount) + mats_in_stock += M.id + msg.Add("[capitalize(M.name)]: [mineral_amount] sheets") + + // No point sending a message if we're dry + if(!length(mats_in_stock)) + return + + // Notify + for(var/obj/machinery/requests_console/console as anything in GLOB.allRequestConsoles) + if(!(console.department in supply_consoles)) + continue + if(!supply_consoles[console.department] || length(supply_consoles[console.department] - mats_in_stock)) + console.createMessage("Smart Hopper", "New Minerals Available!", msg, RQ_LOWPRIORITY) + +/obj/machinery/mineral/smart_hopper/proc/give_points(obj/item/stack/ore/ore_path, ore_amount) + if(initial(ore_path.refined_type)) + points += initial(ore_path.points) * point_upgrade * ore_amount + +/obj/machinery/mineral/smart_hopper/proc/animate_transfer(ore_amount) + icon_state = "hopper_on" + var/time_to_animate = max(ore_amount * 2, 1 SECONDS) + addtimer(VARSET_CALLBACK(src, icon_state, "hopper"), time_to_animate) + linked_crucible.animate_transfer(time_to_animate) diff --git a/code/modules/smithing/smith_component.dm b/code/modules/smithing/smith_component.dm new file mode 100644 index 00000000000..ed2639b90be --- /dev/null +++ b/code/modules/smithing/smith_component.dm @@ -0,0 +1,78 @@ +/obj/item/smithed_item/component + name = "Debug smithed component" + icon = 'icons/obj/smithing.dmi' + icon_state = "debug" + desc = "Debug smithed component part. If you see this, notify the development team." + /// What type of part is it + var/part_type + /// What is this a part of + var/finished_product + /// Is this component currently hot + var/hot = TRUE + /// How many times the component needs to be shaped to be considered ready + var/hammer_time = 3 + +/obj/item/smithed_item/component/update_icon_state() + . = ..() + if(hot) + icon_state = "[initial(icon_state)]_hot" + else + icon_state = "[initial(icon_state)]" + +/obj/item/smithed_item/component/proc/powerhammer() + hammer_time-- + if(prob(50) || hammer_time <= 0) + hot = FALSE + update_icon(UPDATE_ICON_STATE) + +/obj/item/smithed_item/component/proc/heat_up() + hot = TRUE + update_icon(UPDATE_ICON_STATE) + +/obj/item/smithed_item/component/examine(mob/user) + . = ..() + if(hammer_time) + . += "It is incomplete. It looks like it needs [hammer_time] more cycles in the power hammer." + else + . += "It is complete." + if(hot) + . +="It is glowing hot!" + +/obj/item/smithed_item/component/attack_hand(mob/user) + if(!hot) + return ..() + if(burn_check(user)) + burn_user(user) + return + return ..() + +/obj/item/smithed_item/component/proc/set_worktime() + if(!quality) + return + hammer_time = ROUND_UP(initial(hammer_time) * quality.work_mult) + +/obj/item/smithed_item/component/proc/burn_check(mob/user) + if(!hot) + return FALSE + var/burn_me = TRUE + var/mob/living/carbon/human/H = user + if(!istype(H)) + return TRUE + if(H.gloves) + var/obj/item/clothing/gloves/G = H.gloves + if(G.max_heat_protection_temperature) + burn_me = !(G.max_heat_protection_temperature > 360) + + if(!burn_me || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) + return FALSE + return TRUE + +/obj/item/smithed_item/component/proc/burn_user(mob/user) + var/mob/living/carbon/human/H = user + if(!istype(H)) + return + to_chat(user, "You burn your hand as you try to pick up [src]!") + var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand") + if(affecting.receive_damage(0, 10)) // 10 burn damage + H.UpdateDamageIcon() + H.updatehealth() diff --git a/code/datums/smith_datums.dm b/code/modules/smithing/smith_datums.dm similarity index 100% rename from code/datums/smith_datums.dm rename to code/modules/smithing/smith_datums.dm diff --git a/code/modules/smithing/smith_item.dm b/code/modules/smithing/smith_item.dm new file mode 100644 index 00000000000..25b166d4be7 --- /dev/null +++ b/code/modules/smithing/smith_item.dm @@ -0,0 +1,111 @@ +/obj/item/smithed_item + name = "Debug smithed item" + icon = 'icons/obj/smithing.dmi' + icon_state = "debug" + desc = "Debug smithed item. If you see this, notify the development team." + w_class = WEIGHT_CLASS_SMALL + /// The quality of the item + var/datum/smith_quality/quality + /// The material of the item + var/datum/smith_material/material + + new_attack_chain = TRUE + +/obj/item/smithed_item/Initialize(mapload) + . = ..() + set_name() + +/obj/item/smithed_item/update_name() + . = ..() + set_name() + +/obj/item/smithed_item/proc/on_attached(mob/user, obj/item/target) + return + +/obj/item/smithed_item/proc/on_detached(mob/user) + return + +/obj/item/smithed_item/proc/set_stats() + return + +/obj/item/smithed_item/proc/set_name() + if(!quality) + return + if(!material) + name = "[quality.name] " + name + return + name = "[quality.name] [material.name] [initial(name)]" + +// Random Spawners +/obj/item/smithed_item/random + name = "random smithed item" + desc = "If you see me please contact development because I should not exist." + /// Weighted list of possible item qualities + var/list/smithed_item_qualities = list( + /datum/smith_quality = 9, + /datum/smith_quality/improved = 1 + ) + /// Weighted list of possible item materials + var/list/smithed_item_materials = list( + /datum/smith_material/metal = 40, + /datum/smith_material/silver = 10, + /datum/smith_material/gold = 5, + /datum/smith_material/plasma = 10, + /datum/smith_material/titanium = 5, + /datum/smith_material/uranium = 3, + /datum/smith_material/brass = 15 + ) + /// List of possible item types + var/list/smithed_type_list = list( + /obj/item/smithed_item/insert/ballistic, + /obj/item/smithed_item/insert/thermal, + /obj/item/smithed_item/insert/fireproofing, + /obj/item/smithed_item/insert/reflective, + /obj/item/smithed_item/insert/rad_hazard, + /obj/item/smithed_item/insert/rubberized, + /obj/item/smithed_item/tool_bit/speed, + /obj/item/smithed_item/tool_bit/balanced, + /obj/item/smithed_item/tool_bit/efficiency, + /obj/item/smithed_item/lens/accelerator, + /obj/item/smithed_item/lens/speed, + /obj/item/smithed_item/lens/amplifier, + /obj/item/smithed_item/lens/efficiency + ) + +/obj/item/smithed_item/random/Initialize(mapload) + . = ..() + var/picked_type = pick(smithed_type_list) + var/obj/item/smithed_item/new_item = new picked_type(src.loc) + new_item.quality = pickweight(smithed_item_qualities) + new_item.material = pickweight(smithed_item_materials) + new_item.set_stats() + new_item.update_appearance(UPDATE_NAME) + qdel(src) + +/obj/item/smithed_item/random/insert + name = "random smithed insert" + smithed_type_list = list( + /obj/item/smithed_item/insert/ballistic, + /obj/item/smithed_item/insert/thermal, + /obj/item/smithed_item/insert/fireproofing, + /obj/item/smithed_item/insert/reflective, + /obj/item/smithed_item/insert/rad_hazard, + /obj/item/smithed_item/insert/rubberized + ) + +/obj/item/smithed_item/random/bit + name = "random smithed tool bit" + smithed_type_list = list( + /obj/item/smithed_item/tool_bit/speed, + /obj/item/smithed_item/tool_bit/balanced, + /obj/item/smithed_item/tool_bit/efficiency + ) + +/obj/item/smithed_item/random/lens + name = "random smithed lens" + smithed_type_list = list( + /obj/item/smithed_item/lens/accelerator, + /obj/item/smithed_item/lens/speed, + /obj/item/smithed_item/lens/amplifier, + /obj/item/smithed_item/lens/efficiency + ) diff --git a/code/modules/smithing/smith_machinery.dm b/code/modules/smithing/smith_machinery.dm new file mode 100644 index 00000000000..452d92d59f2 --- /dev/null +++ b/code/modules/smithing/smith_machinery.dm @@ -0,0 +1,132 @@ +/obj/machinery/smithing + name = "smithing machine" + desc = "A large unknown smithing machine. If you see this, there's a problem and you should notify the development team." + icon = 'icons/obj/machines/large_smithing_machines.dmi' + icon_state = "power_hammer" + max_integrity = 200 + pixel_x = 0 // 2x2 + pixel_y = -32 + bound_height = 64 + bound_width = 64 + bound_y = -32 + anchored = TRUE + density = TRUE + resistance_flags = FIRE_PROOF + /// How many loops per operation + var/operation_time = 10 + /// Is this active + var/operating = FALSE + /// Cooldown on harming + var/special_attack_cooldown = 10 SECONDS + /// Are we on harm cooldown + var/special_attack_on_cooldown = FALSE + /// Store the worked component + var/obj/item/smithed_item/component/working_component + /// The noise the machine makes when operating + var/operation_sound + /// Will the machine auto-repeat? + var/repeating = FALSE + +/obj/machinery/smithing/examine(mob/user) + . = ..() + if(working_component) + . += "You can activate the machine with your hand, or remove the component by alt-clicking." + +/obj/machinery/smithing/power_change() + if(!..()) + return + update_icon(UPDATE_ICON_STATE) + +/obj/machinery/smithing/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/grab)) + var/obj/item/grab/G = used + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "Putting [G.affecting] in [src] might hurt them!") + return ITEM_INTERACT_COMPLETE + special_attack_grab(G, user) + return ITEM_INTERACT_COMPLETE + + if(operating) + to_chat(user, "[src] is still operating!") + return FINISH_ATTACK + + if(istype(used, /obj/item/smithed_item/component)) + if(working_component) + to_chat(user, "There is already a component in the machine!") + return ITEM_INTERACT_COMPLETE + + if(used.flags & NODROP || !user.drop_item() || !used.forceMove(src)) + to_chat(user, "[used] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + + working_component = used + return ITEM_INTERACT_COMPLETE + return ..() + +/obj/machinery/smithing/proc/operate(loops, mob/living/user) + operating = TRUE + update_icon(ALL) + for(var/i in 1 to loops) + if(stat & (NOPOWER|BROKEN)) + return FALSE + use_power(500) + if(operation_sound) + playsound(src, operation_sound, 50, TRUE) + sleep(1 SECONDS) + playsound(src, 'sound/machines/recycler.ogg', 50, FALSE) + operating = FALSE + update_icon(ALL) + +/obj/machinery/smithing/proc/special_attack_grab(obj/item/grab/G, mob/user) + if(special_attack_on_cooldown) + return FALSE + if(!istype(G)) + return FALSE + if(!iscarbon(G.affecting)) + to_chat(user, "You can't shove that in there!") + return FALSE + if(G.state < GRAB_NECK) + to_chat(user, "You need a better grip to do that!") + return FALSE + var/result = special_attack(user, G.affecting) + user.changeNext_move(CLICK_CD_MELEE) + special_attack_on_cooldown = TRUE + addtimer(VARSET_CALLBACK(src, special_attack_on_cooldown, FALSE), special_attack_cooldown) + if(result && !QDELETED(G)) + qdel(G) + + return TRUE + +/obj/machinery/smithing/proc/special_attack(mob/user, mob/living/target) + return + +/obj/machinery/smithing/AltClick(mob/living/user) + . = ..() + if(!Adjacent(user)) + return + if(!working_component) + to_chat(user, "There isn't anything in [src].") + return + if(operating) + to_chat(user, "[src] is currently operating!") + return + if(working_component.burn_check(user)) + working_component.burn_user(user) + working_component.forceMove(user.loc) + working_component = null + return + user.put_in_hands(working_component) + working_component = null + +/obj/machinery/smithing/screwdriver_act(mob/user, obj/item/I) + if(!I.use_tool(src, user, 0, volume = 0)) + return + . = TRUE + if(operating) + to_chat(user, "[src] is busy. Please wait for completion of previous operation.") + return + default_deconstruction_screwdriver(user, icon_state, icon_state, I) + +/obj/machinery/smithing/crowbar_act(mob/user, obj/item/I) + if(default_deconstruction_crowbar(user, I)) + return TRUE diff --git a/code/modules/smithing/smithed_items/inserts.dm b/code/modules/smithing/smithed_items/inserts.dm new file mode 100644 index 00000000000..2d77e0dd5d4 --- /dev/null +++ b/code/modules/smithing/smithed_items/inserts.dm @@ -0,0 +1,163 @@ +/obj/item/smithed_item/insert + name = "debug insert" + icon_state = "insert" + desc = "Debug insert. If you see this, notify the development team." + /// Brute armor + var/brute_armor = 0 + /// Burn armor + var/burn_armor = 0 + /// Laser armor + var/laser_armor = 0 + /// Explosive armor + var/explosive_armor = 0 + /// Movement speed + var/movement_speed_mod = 0 + /// Heat insulation + var/heat_insulation = 0 + /// Electrical insulation + var/siemens_coeff = 0.0 + /// Radiation armor + var/radiation_armor = 0 + /// The suit the insert is attached to + var/obj/item/clothing/suit/attached_suit + +/obj/item/smithed_item/insert/set_stats() + brute_armor = initial(brute_armor) * quality.stat_mult * material.brute_armor_mult + burn_armor = initial(burn_armor) * quality.stat_mult * material.burn_armor_mult + laser_armor = initial(laser_armor) * quality.stat_mult * material.laser_armor_mult + explosive_armor = initial(explosive_armor) * quality.stat_mult * material.explosive_armor_mult + movement_speed_mod = initial(movement_speed_mod) * quality.stat_mult * material.movement_speed_mod + heat_insulation = initial(heat_insulation) * quality.stat_mult * material.heat_insulation_mult + siemens_coeff = initial(siemens_coeff) * quality.stat_mult * material.siemens_coeff_mult + radiation_armor = initial(radiation_armor) * quality.stat_mult * material.radiation_armor_mult + armor = new /datum/armor(brute_armor, brute_armor, laser_armor, laser_armor, explosive_armor, radiation_armor, burn_armor, 0, 0) + +/obj/item/smithed_item/insert/on_attached(obj/item/clothing/suit/target) + if(!istype(target)) + return + attached_suit = target + attached_suit.armor = attached_suit.armor.attachArmor(armor) + attached_suit.insert_slowdown -= movement_speed_mod + attached_suit.slowdown = initial(attached_suit.slowdown) + attached_suit.insert_slowdown + if(attached_suit.mobility_meshed) + attached_suit.slowdown = 0 + attached_suit.siemens_coefficient -= siemens_coeff + attached_suit.min_cold_protection_temperature -= heat_insulation + attached_suit.max_heat_protection_temperature += heat_insulation + +/obj/item/smithed_item/insert/on_detached(mob/user) + attached_suit.armor = attached_suit.armor.detachArmor(armor) + attached_suit.insert_slowdown += movement_speed_mod + attached_suit.slowdown = initial(attached_suit.slowdown) + attached_suit.insert_slowdown + if(attached_suit.mobility_meshed) + attached_suit.slowdown = 0 + attached_suit.siemens_coefficient += siemens_coeff + attached_suit.min_cold_protection_temperature += heat_insulation + attached_suit.max_heat_protection_temperature -= heat_insulation + attached_suit.inserts -= src + attached_suit = null + +/obj/item/smithed_item/insert/ballistic + name = "ballistic plate" + desc = "A reinforced plate designed to stop small-caliber bullets and kinetic impacts." + brute_armor = 10 + explosive_armor = 10 + heat_insulation = -10 + +/obj/item/smithed_item/insert/thermal + name = "thermal plate" + desc = "A fragile plate designed to reduce heat exposure." + brute_armor = -10 + burn_armor = 10 + heat_insulation = 10 + +/obj/item/smithed_item/insert/fireproofing + name = "fireproofing plate" + desc = "A heavy plate of asbestos designed to fireproof a user. A firefighter's godsend." + burn_armor = 10 + movement_speed_mod = -0.2 + heat_insulation = 20 + +/obj/item/smithed_item/insert/reflective + name = "reflective plate" + desc = "A shiny plate that assists in laser deflection." + burn_armor = -10 + laser_armor = 10 + siemens_coeff = -0.2 + +/obj/item/smithed_item/insert/rad_hazard + name = "radiation hazard plate" + desc = "A dense plate that can reduce a wearer's radiation exposure." + heat_insulation = -10 + radiation_armor = 20 + +/obj/item/smithed_item/insert/rubberized + name = "rubberized plate" + desc = "A flexible plate that is resistant to electrical shocks." + brute_armor = -10 + siemens_coeff = 0.2 + +/obj/item/smithed_item/insert/advanced + name = "advanced armor mesh" + desc = "An alloy mesh that can protect the wearer from most sources of damage." + brute_armor = 10 + burn_armor = 10 + laser_armor = 10 + explosive_armor = 10 + radiation_armor = 10 + movement_speed_mod = -0.2 + +/obj/item/smithed_item/insert/engineering + name = "engineering mesh" + desc = "An alloy mesh designed to assist in most work around electrical engines." + brute_armor = -10 + burn_armor = 10 + radiation_armor = 10 + heat_insulation = 10 + explosive_armor = 10 + siemens_coeff = 0.4 + movement_speed_mod = -0.2 + +/obj/item/smithed_item/insert/heavy + name = "heavy duty plate" + desc = "An advanced plate often used in SWAT gear. Heavy, yet durable." + brute_armor = 20 + burn_armor = 10 + laser_armor = 10 + explosive_armor = 10 + heat_insulation = 10 + siemens_coeff = -0.4 + movement_speed_mod = -0.4 + +/obj/item/smithed_item/insert/mobility + name = "mobility mesh" + desc = "An advanced alloy mesh that is both lightweight and invigorating to the wearer." + brute_armor = -5 + burn_armor = -5 + laser_armor = -5 + heat_insulation = 10 + /// Attached suit slowdown when the mobility mesh was applied + var/initial_slowdown = 0 + +/obj/item/smithed_item/insert/mobility/on_attached(obj/item/clothing/suit/target) + . = ..() + attached_suit.mobility_meshed = TRUE + attached_suit.slowdown = 0 + +/obj/item/smithed_item/insert/mobility/on_detached(mob/user) + attached_suit.mobility_meshed = FALSE + . = ..() + + +/obj/item/smithed_item/insert/admin + name = "adminium mesh" + desc = "A special mesh plate reserved exclusively for high-ranking central command personnel." + brute_armor = 50 + burn_armor = 50 + laser_armor = 50 + radiation_armor = 50 + heat_insulation = 50 + movement_speed_mod = 1 + siemens_coeff = 1 + quality = /datum/smith_quality/masterwork + material = /datum/smith_material/platinum diff --git a/code/modules/smithing/smithed_items/lens.dm b/code/modules/smithing/smithed_items/lens.dm new file mode 100644 index 00000000000..19f065fc11c --- /dev/null +++ b/code/modules/smithing/smithed_items/lens.dm @@ -0,0 +1,137 @@ +/obj/item/smithed_item/lens + name = "Debug lens" + icon_state = "lens" + desc = "Debug lens. If you see this, notify the development team." + /// Base laser speed multiplier + var/base_laser_speed_mult = 0 + /// Base power draw multiplier + var/base_power_mult = 0 + /// Base damage multiplier + var/base_damage_mult = 0 + /// Base fire rate multiplier + var/base_fire_rate_mult = 0 + /// Laser speed multiplier after construction + var/laser_speed_mult = 1 + /// Power draw multiplier after construction + var/power_mult = 1 + /// Damage multiplier after construction + var/damage_mult = 1 + /// Fire rate multiplier after construction + var/fire_rate_mult = 1 + /// lens durability + var/durability = 40 + /// Max durability + var/max_durability = 40 + /// The weapon the lens is attached to + var/obj/item/gun/energy/attached_gun + +/obj/item/smithed_item/lens/set_stats() + durability = initial(durability) * material.durability_mult + max_durability = durability + power_mult = 1 + (base_power_mult * quality.stat_mult * material.power_draw_mult) + damage_mult = 1 + (base_damage_mult * quality.stat_mult * material.projectile_damage_multiplier) + laser_speed_mult = 1 + (base_laser_speed_mult * quality.stat_mult * material.projectile_speed_mult) + fire_rate_mult = 1 + (base_fire_rate_mult * quality.stat_mult * material.fire_rate_multiplier) + +/obj/item/smithed_item/lens/on_attached(obj/item/gun/energy/target) + if(!istype(target)) + return + attached_gun = target + attached_gun.fire_delay = attached_gun.fire_delay / fire_rate_mult + for(var/obj/item/ammo_casing/energy/casing in attached_gun.ammo_type) + casing.e_cost = casing.e_cost * power_mult + casing.lens_damage_multiplier = casing.lens_damage_multiplier * damage_mult + casing.lens_speed_multiplier = casing.lens_speed_multiplier / laser_speed_mult + +/obj/item/smithed_item/lens/on_detached() + attached_gun.fire_delay = attached_gun.fire_delay * fire_rate_mult + for(var/obj/item/ammo_casing/energy/casing in attached_gun.ammo_type) + casing.e_cost = casing.e_cost / power_mult + casing.lens_damage_multiplier = casing.lens_damage_multiplier / damage_mult + casing.lens_speed_multiplier = casing.lens_speed_multiplier * laser_speed_mult + attached_gun.current_lens = null + attached_gun = null + +/obj/item/smithed_item/lens/examine(mob/user) + . = ..() + var/healthpercent = (durability/max_durability) * 100 + switch(healthpercent) + if(80 to 100) + . += "It looks pristine." + if(60 to 79) + . += "It looks slightly used." + if(40 to 59) + . += "It's seen better days." + if(20 to 39) + . += "It's been heavily used." + if(0 to 19) + . += "It's falling apart!" + +/obj/item/smithed_item/lens/proc/damage_lens() + durability-- + if(durability <= 0) + break_lens() + +/obj/item/smithed_item/lens/proc/break_lens() + on_detached() + qdel(src) + +/obj/item/smithed_item/lens/accelerator + name = "accelerator lens" + desc = "A lens that accelerates energy beams to a higher velocity, using some of its own energy to propel it." + base_laser_speed_mult = 0.1 + base_damage_mult = -0.1 + +/obj/item/smithed_item/lens/speed + name = "speed lens" + desc = "A lens that cools the capacitors more efficiently, allowing for greater fire rate." + base_fire_rate_mult = 0.15 + base_damage_mult = -0.1 + durability = 30 + +/obj/item/smithed_item/lens/amplifier + name = "amplifier lens" + desc = "A lens that increases the frequency of emitted beams, increasing their potency." + base_power_mult = 0.2 + base_damage_mult = 0.1 + +/obj/item/smithed_item/lens/efficiency + name = "efficiency lens" + desc = "A lens that optimizes the number of shots an energy weapon can take before running dry." + base_power_mult = -0.2 + base_damage_mult = -0.1 + durability = 80 + +/obj/item/smithed_item/lens/rapid + name = "rapid lens" + desc = "An advanced lens that bypasses the heat capacitor entirely, allowing for unprecedented fire rates of low-power emissions." + base_fire_rate_mult = 0.5 + base_laser_speed_mult = -0.1 + base_damage_mult = -0.2 + durability = 60 + +/obj/item/smithed_item/lens/densifier + name = "densifier lens" + desc = "An advanced lens that keeps energy emissions in the barrel as long as possible, maximising impact at the cost of everything else." + base_fire_rate_mult = -0.4 + base_laser_speed_mult = -0.4 + base_damage_mult = 0.4 + durability = 30 + +/obj/item/smithed_item/lens/velocity + name = "velocity lens" + desc = "An advanced lens that forces energy emissions from the barrel as fast as possible, accelerating them to ludicrous speed." + base_laser_speed_mult = 0.5 + base_damage_mult = -0.2 + durability = 30 + +/obj/item/smithed_item/lens/admin + name = "adminium lens" + desc = "A hyper-advanced lens restricted to high-ranking central command officials." + laser_speed_mult = 5 + damage_mult = 5 + fire_rate_mult = 5 + power_mult = -0.5 + durability = 3000 + quality = /datum/smith_quality/masterwork + material = /datum/smith_material/platinum diff --git a/code/modules/smithing/smithed_items/tool_bits.dm b/code/modules/smithing/smithed_items/tool_bits.dm new file mode 100644 index 00000000000..9ccf5def051 --- /dev/null +++ b/code/modules/smithing/smithed_items/tool_bits.dm @@ -0,0 +1,131 @@ +/obj/item/smithed_item/tool_bit + name = "Debug tool bit" + icon_state = "bit" + desc = "Debug tool bit. If you see this, notify the development team." + /// Base Speed modifier + var/base_speed_mod = 0 + /// Base Efficiency modifier + var/base_efficiency_mod = 0 + /// Speed modifier + var/speed_mod = 1.0 + /// Efficiency modifier + var/efficiency_mod = 1.0 + /// Failure rate + var/failure_rate = 0 + /// Size modifier + var/size_mod = 0 + /// Durability + var/durability = 90 + /// Max durability + var/max_durability = 90 + /// The tool the bit is attached to + var/obj/item/attached_tool + +/obj/item/smithed_item/tool_bit/interact_with_atom(atom/target, mob/living/user, list/modifiers) + . = ..() + if(istype(target, /obj/item)) + SEND_SIGNAL(target, COMSIG_BIT_ATTACH, src, user) + return ITEM_INTERACT_COMPLETE + +/obj/item/smithed_item/tool_bit/set_stats() + durability = initial(durability) * material.durability_mult + max_durability = durability + size_mod = initial(size_mod) + material.size_mod + speed_mod = 1 + (base_speed_mod * quality.stat_mult * material.tool_speed_mult) + failure_rate = initial(failure_rate) * quality.stat_mult * material.tool_failure_mult + efficiency_mod = 1 + (base_efficiency_mod * quality.stat_mult * material.power_draw_mult) + +/obj/item/smithed_item/tool_bit/on_attached(obj/item/target) + if(!istype(target)) + return + attached_tool = target + attached_tool.w_class += size_mod + attached_tool.toolspeed = attached_tool.toolspeed * speed_mod + attached_tool.bit_failure_rate += failure_rate + attached_tool.bit_efficiency_mod = attached_tool.bit_efficiency_mod * efficiency_mod + +/obj/item/smithed_item/tool_bit/on_detached() + attached_tool.toolspeed = attached_tool.toolspeed / speed_mod + attached_tool.w_class -= size_mod + attached_tool.bit_failure_rate -= failure_rate + attached_tool.bit_efficiency_mod = attached_tool.bit_efficiency_mod / efficiency_mod + attached_tool.attached_bits -= src + attached_tool = null + +/obj/item/smithed_item/tool_bit/examine(mob/user) + . = ..() + var/healthpercent = (durability/max_durability) * 100 + switch(healthpercent) + if(80 to 100) + . += "It looks pristine." + if(60 to 79) + . += "It looks slightly used." + if(40 to 59) + . += "It's seen better days." + if(20 to 39) + . += "It's been heavily used." + if(0 to 19) + . += "It's falling apart!" + +/obj/item/smithed_item/tool_bit/proc/damage_bit() + durability-- + if(istype(attached_tool, /obj/item/rcd)) + durability-- + if(durability == 0) + break_bit() + +/obj/item/smithed_item/tool_bit/proc/break_bit() + on_detached() + qdel(src) + +/obj/item/smithed_item/tool_bit/speed + name = "speed bit" + desc = "A tool bit optimized for speed, at the cost of efficiency." + base_speed_mod = -0.2 + failure_rate = 5 + base_efficiency_mod = 0.1 + +/obj/item/smithed_item/tool_bit/efficiency + name = "efficient bit" + desc = "A tool bit optimized for efficiency, at the cost of speed." + base_speed_mod = 0.2 + base_efficiency_mod = -0.25 + +/obj/item/smithed_item/tool_bit/balanced + name = "balanced bit" + desc = "A tool bit that's fairly balanced in all aspects." + base_speed_mod = -0.1 + failure_rate = 2 + base_efficiency_mod = -0.1 + +/obj/item/smithed_item/tool_bit/heavy + name = "heavy duty bit" + desc = "A large, advanced tool bit that maximises speed." + base_speed_mod = -0.4 + failure_rate = 10 + base_efficiency_mod = 0.25 + size_mod = 1 + durability = 120 + +/obj/item/smithed_item/tool_bit/economical + name = "economical bit" + desc = "An advanced tool bit that maximises efficiency." + base_speed_mod = 0.4 + base_efficiency_mod = -0.45 + durability = 60 + +/obj/item/smithed_item/tool_bit/advanced + name = "advanced bit" + desc = "An advanced tool bit that's fairly balanced in all aspects." + base_speed_mod = -0.25 + failure_rate = 2 + base_efficiency_mod = -0.3 + +/obj/item/smithed_item/tool_bit/admin + name = "adminium bit" + desc = "A hyper-advanced bit restricted to central command officials." + speed_mod = -1 + efficiency_mod = 1 + durability = 300 + quality = /datum/smith_quality/masterwork + material = /datum/smith_material/platinum diff --git a/code/modules/smithing/smithing_cast.dm b/code/modules/smithing/smithing_cast.dm new file mode 100644 index 00000000000..9a2140be5a0 --- /dev/null +++ b/code/modules/smithing/smithing_cast.dm @@ -0,0 +1,160 @@ +/obj/item/smithing_cast + name = "smithing cast" + icon = 'icons/obj/smithing.dmi' + icon_state = "debug" + desc = "Debug smithing cast. If you see this, notify the development team." + w_class = WEIGHT_CLASS_SMALL + /// The selected final product of the item + var/obj/item/selected_product + /// Possible products of the item + var/list/possible_products = list() + /// How many products are we smelting at any given operation? + var/amount_to_make = 1 + + new_attack_chain = TRUE + +/obj/item/smithing_cast/Initialize(mapload) + . = ..() + populate_products() + +/obj/item/smithing_cast/examine(mob/user) + . = ..() + . += "It is currently configured to make [amount_to_make == 1 ? "a" : "[amount_to_make]"] [selected_product.name][amount_to_make == 1 ? "" : "s"]." + . += "You can select the desired product by using [src] in your hand." + +/obj/item/smithing_cast/activate_self(mob/user) + . = ..() + if(!possible_products) + return + var/list/product_names = list() + var/product + for(product in possible_products) + var/obj/item/possible_product = product + product_names[possible_product.name] = possible_product + var/new_product = tgui_input_list(user, "Select a product", src, product_names) + if(!new_product) + selected_product = possible_products[1] + else + selected_product = product_names[new_product] + +/obj/item/smithing_cast/update_desc() + return ..() + +/obj/item/smithing_cast/proc/populate_products() + return + +/obj/item/smithing_cast/sheet + name = "sheet cast" + icon_state = "sheet_cast" + desc = "A cast for forging molten minerals into workable sheets." + +/obj/item/smithing_cast/sheet/examine(mob/user) + . = ..() + . += "You can change the amount of sheets smelted by alt-clicking [src]." + +/obj/item/smithing_cast/sheet/populate_products() + possible_products = list(/obj/item/stack/sheet/metal, + /obj/item/stack/sheet/glass, + /obj/item/stack/sheet/mineral/silver, + /obj/item/stack/sheet/mineral/gold, + /obj/item/stack/sheet/mineral/plasma, + /obj/item/stack/sheet/mineral/uranium, + /obj/item/stack/sheet/mineral/diamond, + /obj/item/stack/ore/bluespace_crystal/refined, + /obj/item/stack/sheet/mineral/titanium, + /obj/item/stack/sheet/plasmaglass, + /obj/item/stack/sheet/titaniumglass, + /obj/item/stack/sheet/plasteel, + /obj/item/stack/sheet/mineral/plastitanium, + /obj/item/stack/sheet/plastitaniumglass, + /obj/item/stack/sheet/mineral/bananium, + /obj/item/stack/sheet/mineral/tranquillite, + /obj/item/stack/sheet/mineral/platinum, + /obj/item/stack/sheet/mineral/palladium, + /obj/item/stack/sheet/mineral/iridium, + /obj/item/stack/tile/brass + ) + if(length(possible_products)) + selected_product = possible_products[1] + +/obj/item/smithing_cast/sheet/AltClick(mob/user) + . = ..() + if(!Adjacent(user)) + return + amount_to_make = tgui_input_number(user, "Select an amount (1-50)", src, 1, 50, 1) + +/obj/item/smithing_cast/component + name = "component cast" + desc = "Debug component cast. If you see this, notify the development team." + /// The selected quality of the item + var/datum/smith_quality/quality = /datum/smith_quality + /// The type of product + var/product_type + +/obj/item/smithing_cast/component/examine(mob/user) + . = ..() + . += "The current selected quality is [quality.name]." + . += "You can change the quality of the product by alt-clicking [src]." + +/obj/item/smithing_cast/component/AltClick(mob/user) + . = ..() + if(!Adjacent(user)) + return + var/list/quality_name_list = list() + var/list/quality_type_list = typesof(/datum/smith_quality) + var/quality_type + for(quality_type in quality_type_list) + var/datum/smith_quality/new_quality = quality_type + quality_name_list[new_quality.name] = new_quality + var/selected_quality = tgui_input_list(user, "Select a quality", src, quality_name_list) + if(!selected_quality) + quality = quality_type_list[1] + else + quality = quality_name_list[selected_quality] + +/obj/item/smithing_cast/component/populate_products() + possible_products = (typesof(product_type) - list(product_type)) + if(length(possible_products)) + selected_product = possible_products[1] + +/obj/item/smithing_cast/component/insert_frame + name = "insert frame cast" + icon_state = "insert_frame_cast" + desc = "A cast for creating insert frames." + product_type = /obj/item/smithed_item/component/insert_frame + +/obj/item/smithing_cast/component/insert_lining + name = "insert lining cast" + icon_state = "insert_lining_cast" + desc = "A cast for creating insert linings." + product_type = /obj/item/smithed_item/component/insert_lining + +/obj/item/smithing_cast/component/bit_mount + name = "bit mount cast" + icon_state = "bit_mount_cast" + desc = "A cast for creating bit mounts." + product_type = /obj/item/smithed_item/component/bit_mount + +/obj/item/smithing_cast/component/bit_head + name = "bit head cast" + icon_state = "bit_head_cast" + desc = "A cast for creating bit heads." + product_type = /obj/item/smithed_item/component/bit_head + +/obj/item/smithing_cast/component/lens_frame + name = "lens frame cast" + icon_state = "lens_frame_cast" + desc = "A cast for creating lens frames." + product_type = /obj/item/smithed_item/component/lens_frame + +/obj/item/smithing_cast/component/lens_focus + name = "lens focus cast" + icon_state = "lens_focus_cast" + desc = "A cast for creating lens foci." + product_type = /obj/item/smithed_item/component/lens_focus + +/obj/item/smithing_cast/component/trim + name = "trim cast" + icon_state = "trim_cast" + desc = "A cast for creating trims." + product_type = /obj/item/smithed_item/component/trim diff --git a/paradise.dme b/paradise.dme index 28f9fffe16c..077ab4e163d 100644 --- a/paradise.dme +++ b/paradise.dme @@ -121,6 +121,7 @@ #include "code\__DEFINES\shuttle_defines.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\silicon_defines.dm" +#include "code\__DEFINES\smith_defines.dm" #include "code\__DEFINES\sound_defines.dm" #include "code\__DEFINES\speech_channels.dm" #include "code\__DEFINES\spell_defines.dm" @@ -434,7 +435,6 @@ #include "code\datums\revision.dm" #include "code\datums\ruins.dm" #include "code\datums\shuttles.dm" -#include "code\datums\smith_datums.dm" #include "code\datums\spawners_menu.dm" #include "code\datums\station_state.dm" #include "code\datums\tgs_event_handler.dm" @@ -923,7 +923,6 @@ #include "code\game\machinery\shieldgen.dm" #include "code\game\machinery\Sleeper.dm" #include "code\game\machinery\slotmachine.dm" -#include "code\game\machinery\smith_machines.dm" #include "code\game\machinery\snow_machine.dm" #include "code\game\machinery\spaceheater.dm" #include "code\game\machinery\status_display.dm" @@ -1921,7 +1920,6 @@ #include "code\modules\crafting\craft.dm" #include "code\modules\crafting\guncrafting.dm" #include "code\modules\crafting\recipes.dm" -#include "code\modules\crafting\smithed_items.dm" #include "code\modules\crafting\tailoring.dm" #include "code\modules\customitems\item_defines.dm" #include "code\modules\detective_work\detective_work.dm" @@ -2928,6 +2926,24 @@ #include "code\modules\shuttle\shuttle_rotate.dm" #include "code\modules\shuttle\supply.dm" #include "code\modules\shuttle\syndicate_shuttles.dm" +#include "code\modules\smithing\smith_component.dm" +#include "code\modules\smithing\smith_datums.dm" +#include "code\modules\smithing\smith_item.dm" +#include "code\modules\smithing\smith_machinery.dm" +#include "code\modules\smithing\smithing_cast.dm" +#include "code\modules\smithing\components\inserts_components.dm" +#include "code\modules\smithing\components\lens_components.dm" +#include "code\modules\smithing\components\tool_bits_components.dm" +#include "code\modules\smithing\components\trim.dm" +#include "code\modules\smithing\machinery\casting_basin.dm" +#include "code\modules\smithing\machinery\kinetic_assembler.dm" +#include "code\modules\smithing\machinery\lava_furnace.dm" +#include "code\modules\smithing\machinery\magma_crucible.dm" +#include "code\modules\smithing\machinery\power_hammer.dm" +#include "code\modules\smithing\machinery\smart_hopper.dm" +#include "code\modules\smithing\smithed_items\inserts.dm" +#include "code\modules\smithing\smithed_items\lens.dm" +#include "code\modules\smithing\smithed_items\tool_bits.dm" #include "code\modules\space_management\level_check.dm" #include "code\modules\space_management\level_traits.dm" #include "code\modules\space_management\space_chunk.dm"