diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index 3071a07d5bb..5371384e781 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -327,69 +327,81 @@
var/id = null
var/sheet_type = null
var/coin_type = null
+ var/ore_type = null
/datum/material/metal
name = "Metal"
id = MAT_METAL
sheet_type = /obj/item/stack/sheet/metal
coin_type = /obj/item/coin/iron
+ ore_type = /obj/item/stack/ore/iron
/datum/material/glass
name = "Glass"
id = MAT_GLASS
sheet_type = /obj/item/stack/sheet/glass
+ ore_type = /obj/item/stack/ore/glass
/datum/material/silver
name = "Silver"
id = MAT_SILVER
sheet_type = /obj/item/stack/sheet/mineral/silver
coin_type = /obj/item/coin/silver
+ ore_type = /obj/item/stack/ore/silver
/datum/material/gold
name = "Gold"
id = MAT_GOLD
sheet_type = /obj/item/stack/sheet/mineral/gold
coin_type = /obj/item/coin/gold
+ ore_type = /obj/item/stack/ore/gold
/datum/material/diamond
name = "Diamond"
id = MAT_DIAMOND
sheet_type = /obj/item/stack/sheet/mineral/diamond
coin_type = /obj/item/coin/diamond
+ ore_type = /obj/item/stack/ore/diamond
/datum/material/uranium
name = "Uranium"
id = MAT_URANIUM
sheet_type = /obj/item/stack/sheet/mineral/uranium
coin_type = /obj/item/coin/uranium
+ ore_type = /obj/item/stack/ore/uranium
/datum/material/plasma
name = "Solid Plasma"
id = MAT_PLASMA
sheet_type = /obj/item/stack/sheet/mineral/plasma
coin_type = /obj/item/coin/plasma
+ ore_type = /obj/item/stack/ore/plasma
/datum/material/bluespace
name = "Bluespace Mesh"
id = MAT_BLUESPACE
sheet_type = /obj/item/stack/sheet/bluespace_crystal
+ ore_type = /obj/item/stack/ore/bluespace_crystal
/datum/material/bananium
name = "Bananium"
id = MAT_BANANIUM
sheet_type = /obj/item/stack/sheet/mineral/bananium
coin_type = /obj/item/coin/clown
+ ore_type = /obj/item/stack/ore/bananium
/datum/material/tranquillite
name = "Tranquillite"
id = MAT_TRANQUILLITE
sheet_type = /obj/item/stack/sheet/mineral/tranquillite
coin_type = /obj/item/coin/mime
+ ore_type = /obj/item/stack/ore/tranquillite
/datum/material/titanium
name = "Titanium"
id = MAT_TITANIUM
sheet_type = /obj/item/stack/sheet/mineral/titanium
+ ore_type = /obj/item/stack/ore/titanium
/datum/material/biomass
name = "Biomass"
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index ee10925c59a..84433a96fa6 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -1,6 +1,13 @@
-/**********************Ore Redemption Unit**************************/
-//Turns all the various mining machines into a single unit to speed up mining and establish a point system
+#define BASE_POINT_MULT 0.65
+#define BASE_SHEET_MULT 0.65
+#define POINT_MULT_ADD_PER_RATING 0.35
+#define SHEET_MULT_ADD_PER_RATING 0.35
+/**
+ * # Ore Redemption Machine
+ *
+ * Turns all the various mining machines into a single unit to speed up tmining and establish a point system.
+ */
/obj/machinery/mineral/ore_redemption
name = "ore redemption machine"
desc = "A machine that accepts ore and instantly transforms it into workable material sheets. Points for ore are generated based on type and can be redeemed at a mining equipment vendor."
@@ -13,24 +20,49 @@
req_access = list(ACCESS_MINERAL_STOREROOM)
speed_process = TRUE
layer = BELOW_OBJ_LAYER
- var/req_access_reclaim = ACCESS_MINING_STATION
- var/obj/item/card/id/inserted_id
+ // Settings
+ /// The access number required to claim points from the machine.
+ var/req_access_claim = ACCESS_MINING_STATION
+ /// If TRUE, [/obj/machinery/mineral/ore_redemption/var/req_access_claim] is ignored and any ID may be used to claim points.
+ var/anyone_claim = FALSE
+ /// List of supply console department names that can receive a notification about ore dumps.
+ /// A list may be provided as entry value to only notify when specific ore is dumped.
+ var/list/supply_consoles = list(
+ "Science",
+ "Robotics",
+ "Research Director's Desk",
+ "Mechanic",
+ "Engineering" = list(MAT_METAL, MAT_GLASS, MAT_PLASMA),
+ "Chief Engineer's Desk" = list(MAT_METAL, MAT_GLASS, MAT_PLASMA),
+ "Atmospherics" = list(MAT_METAL, MAT_GLASS, MAT_PLASMA),
+ "Bar" = list(MAT_URANIUM, MAT_PLASMA),
+ "Virology" = list(MAT_PLASMA, MAT_URANIUM, MAT_GOLD)
+ )
+ // Variables
+ /// The currently inserted ID.
+ var/obj/item/card/id/inserted_id = null
+ /// The number of unclaimed points.
var/points = 0
- var/ore_pickup_rate = 15
+ /// Sheet multiplier applied when smelting ore. Updated by [/obj/machinery/proc/RefreshParts].
var/sheet_per_ore = 1
+ /// Point multiplier applied when smelting ore. Updated by [/obj/machinery/proc/RefreshParts].
var/point_upgrade = 1
- var/list/ore_values = list("sand" = 1, "iron" = 1, "plasma" = 15, "silver" = 16, "gold" = 18, "titanium" = 30, "uranium" = 30, "diamond" = 50, "bluespace crystal" = 50, "bananium" = 60, "tranquillite" = 60)
- var/message_sent = FALSE
- var/list/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
+ /// List of ore yet to process.
+ var/list/obj/item/stack/ore/ore_buffer = null
+ /// Locally known R&D designs.
var/datum/research/files
+ /// The currently inserted design disk.
var/obj/item/disk/design_disk/inserted_disk
- var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"), "Virology" = list("plasma", "uranium", "gold"))
- var/anyuse = FALSE
/obj/machinery/mineral/ore_redemption/New()
..()
- 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), INFINITY, FALSE, /obj/item/stack)
+ ore_buffer = list()
+ // Components
+ 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), INFINITY, FALSE, /obj/item/stack, null, CALLBACK(src, .proc/on_material_insert))
files = new /datum/research/smelter(src)
+ // Stock parts
component_parts = list()
component_parts += new /obj/item/circuitboard/ore_redemption(null)
component_parts += new /obj/item/stock_parts/matter_bin(null)
@@ -51,14 +83,14 @@
component_parts += new /obj/item/stack/sheet/glass(null)
RefreshParts()
+/**
+ * # Ore Redemption Machine (Golem)
+ *
+ * Golem variant of the ORM.
+ */
/obj/machinery/mineral/ore_redemption/golem
req_access = list(ACCESS_FREE_GOLEMS)
- req_access_reclaim = ACCESS_FREE_GOLEMS
-
-/obj/machinery/mineral/ore_redemption/labor
- name = "labor camp ore redemption machine"
- req_access = list()
- anyuse = TRUE
+ req_access_claim = ACCESS_FREE_GOLEMS
/obj/machinery/mineral/ore_redemption/golem/New()
..()
@@ -71,6 +103,16 @@
component_parts += new /obj/item/stack/sheet/glass(null)
RefreshParts()
+/**
+ * # Ore Redemption Machine (Labor Camp)
+ *
+ * Labor camp variant of the ORM. Points can be claimed by anyone.
+ */
+/obj/machinery/mineral/ore_redemption/labor
+ name = "labor camp ore redemption machine"
+ req_access = list()
+ anyone_claim = TRUE
+
/obj/machinery/mineral/ore_redemption/labor/New()
..()
component_parts = list()
@@ -83,151 +125,94 @@
RefreshParts()
/obj/machinery/mineral/ore_redemption/Destroy()
- QDEL_NULL(files)
+ // Move any stuff inside us out
+ var/turf/T = get_turf(src)
+ inserted_id?.forceMove(T)
+ inserted_disk?.forceMove(T)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
+ // Clean up
+ QDEL_NULL(files)
return ..()
/obj/machinery/mineral/ore_redemption/RefreshParts()
- var/ore_pickup_rate_temp = 15
- var/point_upgrade_temp = 1
- var/sheet_per_ore_temp = 1
- for(var/obj/item/stock_parts/matter_bin/B in component_parts)
- sheet_per_ore_temp = 0.65 + (0.35 * B.rating)
- for(var/obj/item/stock_parts/manipulator/M in component_parts)
- ore_pickup_rate_temp = 15 * M.rating
- for(var/obj/item/stock_parts/micro_laser/L in component_parts)
- point_upgrade_temp = 0.65 + (0.35 * L.rating)
- ore_pickup_rate = ore_pickup_rate_temp
- point_upgrade = point_upgrade_temp
- sheet_per_ore = sheet_per_ore_temp
+ var/P = 1
+ var/S = 1
+ for(var/sp in component_parts)
+ var/obj/item/stock_parts/SP = sp
+ if(!istype(SP))
+ continue
+ switch(SP.type)
+ if(/obj/item/stock_parts/micro_laser)
+ P = BASE_POINT_MULT + (POINT_MULT_ADD_PER_RATING * SP.rating)
+ if(/obj/item/stock_parts/matter_bin)
+ S = BASE_SHEET_MULT + (SHEET_MULT_ADD_PER_RATING * SP.rating)
+ // Manipulators do nothing
+ // Update our values
+ point_upgrade = P
+ sheet_per_ore = S
+ SStgui.update_uis(src)
-/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/O)
-
- ore_buffer -= O
-
- if(O && O.refined_type)
- points += O.points * point_upgrade * O.amount
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- var/material_amount = materials.get_item_material_amount(O)
-
- if(!material_amount)
- qdel(O) //no materials, incinerate it
-
- else if(!materials.has_space(material_amount * sheet_per_ore * O.amount)) //if there is no space, eject it
- unload_mineral(O)
+/obj/machinery/mineral/ore_redemption/power_change()
+ ..()
+ update_icon()
+ if(inserted_id && !powered())
+ visible_message("The ID slot indicator light flickers on [src] as it spits out a card before powering down.")
+ inserted_id.forceMove(get_turf(src))
+ inserted_id = null
+/obj/machinery/mineral/ore_redemption/update_icon()
+ if(powered())
+ icon_state = initial(icon_state)
else
- materials.insert_item(O, sheet_per_ore) //insert it
- qdel(O)
-
-/obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D)
- if(D.make_reagents.len)
- return FALSE
-
- var/build_amount = 0
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- for(var/mat_id in D.materials)
- var/M = D.materials[mat_id]
- var/datum/material/redemption_mat = materials.materials[mat_id]
-
- if(!M || !redemption_mat)
- return FALSE
-
- var/smeltable_sheets = round(redemption_mat.amount / M)
-
- if(!smeltable_sheets)
- return FALSE
-
- if(!build_amount)
- build_amount = smeltable_sheets
-
- build_amount = min(build_amount, smeltable_sheets)
-
- return build_amount
-
-/obj/machinery/mineral/ore_redemption/proc/process_ores(list/ores_to_process)
- var/current_amount = 0
- for(var/ore in ores_to_process)
- if(current_amount >= ore_pickup_rate)
- break
- smelt_ore(ore)
-
-/obj/machinery/mineral/ore_redemption/proc/send_console_message()
- if(!is_station_level(z))
- return
- message_sent = TRUE
- var/area/A = get_area(src)
- var/msg = "Now available in [A]:"
-
- var/has_minerals = FALSE
- var/mineral_name = null
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- for(var/mat_id in materials.materials)
- var/datum/material/M = materials.materials[mat_id]
- var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT
- mineral_name = capitalize(M.name)
- if(mineral_amount)
- has_minerals = TRUE
- msg += "[mineral_name]: [mineral_amount] sheets"
-
- if(!has_minerals)
- return
-
- for(var/obj/machinery/requests_console/D in GLOB.allRequestConsoles)
- if(D.department in src.supply_consoles)
- if(supply_consoles[D.department] == null || (mineral_name in supply_consoles[D.department]))
- D.createMessage("Ore Redemption Machine", "New Minerals Available!", msg, 1)
+ icon_state = "[initial(icon_state)]-off"
/obj/machinery/mineral/ore_redemption/process()
if(panel_open || !powered())
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/O in input)
if(QDELETED(O))
continue
ore_buffer |= O
O.forceMove(src)
CHECK_TICK
-
- if(LAZYLEN(ore_buffer))
+ // Process it
+ if(length(ore_buffer))
message_sent = FALSE
process_ores(ore_buffer)
else if(!message_sent)
+ SStgui.update_uis(src)
send_console_message()
+ message_sent = TRUE
+// Interactions
/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params)
if(exchange_parts(user, W))
return
-
if(!powered())
- return
+ return ..()
+
if(istype(W, /obj/item/card/id))
- var/obj/item/card/id/I = user.get_active_hand()
- if(istype(I) && !istype(inserted_id))
- if(!user.drop_item())
- return
- I.forceMove(src)
- inserted_id = I
- interact(user)
+ try_insert_id(user)
+ return
+ else if(istype(W, /obj/item/disk/design_disk))
+ if(!user.drop_item())
+ return
+ W.forceMove(src)
+ inserted_disk = W
+ SStgui.update_uis(src)
+ interact(user)
+ user.visible_message("[user] inserts [W] into [src].", \
+ "You insert [W] into [src].")
return
-
- if(istype(W, /obj/item/disk/design_disk))
- if(user.drop_item())
- W.forceMove(src)
- inserted_disk = W
- interact(user)
- return TRUE
-
return ..()
-
/obj/machinery/mineral/ore_redemption/crowbar_act(mob/user, obj/item/I)
if(default_deconstruction_crowbar(user, I))
return TRUE
@@ -246,174 +231,273 @@
/obj/machinery/mineral/ore_redemption/screwdriver_act(mob/user, obj/item/I)
if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", I))
- updateUsrDialog()
+ SStgui.update_uis(src)
return TRUE
/obj/machinery/mineral/ore_redemption/wrench_act(mob/user, obj/item/I)
if(default_unfasten_wrench(user, I))
return TRUE
+/obj/machinery/mineral/ore_redemption/attack_ghost(mob/user)
+ ui_interact(user)
+
/obj/machinery/mineral/ore_redemption/attack_hand(mob/user)
if(..())
return
- interact(user)
-
-/obj/machinery/mineral/ore_redemption/interact(mob/user)
- var/dat = "This machine only accepts ore. Gibtonite and Slag are not accepted.
"
- dat += "Current unclaimed points: [points]
"
-
- if(inserted_id)
- dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
"
- dat += "Claim points.
"
- else
- dat += "No ID inserted. Insert ID.
"
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- for(var/mat_id in materials.materials)
- var/datum/material/M = materials.materials[mat_id]
- if(M.amount)
- var/sheet_amount = M.amount / MINERAL_MATERIAL_AMOUNT
- dat += "[capitalize(M.name)]: [sheet_amount] "
- if(sheet_amount >= 1)
- dat += "Release
"
- else
- dat += "Release
"
-
- dat += "
Alloys:
"
-
- for(var/v in files.known_designs)
- var/datum/design/D = files.known_designs[v]
- if(can_smelt_alloy(D))
- dat += "[D.name]: Smelt
"
- else
- dat += "[D.name]: Smelt
"
-
- dat += "
| [capitalize(ore)] | [value * point_upgrade] |