diff --git a/code/modules/awaymissions/mission_code/ruins/freegolems.dm b/code/modules/awaymissions/mission_code/ruins/freegolems.dm index d7d23ad1f7a..d13370f1054 100644 --- a/code/modules/awaymissions/mission_code/ruins/freegolems.dm +++ b/code/modules/awaymissions/mission_code/ruins/freegolems.dm @@ -35,7 +35,7 @@ */ /obj/machinery/mineral/ore_redemption/golem req_access = list(ACCESS_FREE_GOLEMS) - req_access_claim = ACCESS_FREE_GOLEMS + req_access_claim = list(ACCESS_FREE_GOLEMS) /obj/machinery/mineral/ore_redemption/golem/Initialize(mapload) . = ..() diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index c2e66526341..c94a37d3295 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -10,13 +10,16 @@ icon_state = "ore_redemption" density = TRUE anchored = TRUE - req_access = list(ACCESS_MINERAL_STOREROOM) speed_process = TRUE - // Settings + req_access = list(ACCESS_MINERAL_STOREROOM) /// 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 + var/list/req_access_claim = list(ACCESS_MINING_STATION, ACCESS_EXPEDITION) + /// If FALSE, the ORM will ignore all access requirements. + var/scan_id = TRUE + /// If TRUE, the ORM will throw stuff at people. + var/throw_inventory = FALSE + /// % chance per process that the ORM will throw stuff at people when `throw_inventory` is TRUE. Remember that this machine speed processes, so this rolls 5 times per second. + var/throw_chance = 1 /// 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( @@ -29,7 +32,7 @@ "Bar" = list(MAT_URANIUM, MAT_PLASMA), "Virology" = list(MAT_PLASMA, MAT_URANIUM, MAT_GOLD) ) - // Variables + var/datum/wires/ore_redemption/wires /// The number of unclaimed points. var/points = 0 /// Sheet multiplier applied when smelting ore. Updated by [/obj/machinery/proc/RefreshParts]. @@ -46,13 +49,14 @@ var/obj/item/disk/design_disk/inserted_disk var/datum/component/material_container/mat_container var/invalid_material - + COOLDOWN_DECLARE(temp_shock) /obj/machinery/mineral/ore_redemption/Initialize(mapload) . = ..() mat_container = 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_PLATINUM, MAT_IRIDIUM, MAT_PALLADIUM), INFINITY, FALSE, /obj/item/stack, null, CALLBACK(src, PROC_REF(on_material_insert))) ore_buffer = list() files = new /datum/research/smelter(src) + wires = new(src) initialize_parts() RefreshParts() @@ -81,8 +85,9 @@ */ /obj/machinery/mineral/ore_redemption/labor name = "labor camp ore redemption machine" + desc = "A public-access ORM for convicts to deposit ore in exchange for the mining points they need to earn their freedom." req_access = list() - anyone_claim = TRUE + req_access_claim = list() /obj/machinery/mineral/ore_redemption/labor/initialize_parts() component_parts = list() @@ -95,6 +100,8 @@ /obj/machinery/mineral/ore_redemption/Destroy() // Move any stuff inside us out + SStgui.close_uis(wires) + QDEL_NULL(wires) var/turf/T = get_turf(src) inserted_disk?.forceMove(T) var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) @@ -161,8 +168,10 @@ SStgui.update_uis(src) send_console_message() message_sent = TRUE + if(throw_inventory && prob(throw_chance)) + throw_item() -// Interactions +// MARK: Interactions /obj/machinery/mineral/ore_redemption/item_interaction(mob/living/user, obj/item/used, list/modifiers) if(istype(used, /obj/item/storage/part_replacer)) return ..() @@ -173,17 +182,25 @@ if(istype(used, /obj/item/card/id)) var/obj/item/card/id/ID = used if(!points) - to_chat(usr, SPAN_WARNING("There are no points to claim.")); + to_chat(user, SPAN_WARNING("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(usr, SPAN_NOTICE("[points] Mining Points claimed. You have earned a total of [ID.total_mining_points] Mining Points this Shift!")) - points = 0 - SStgui.update_uis(src) - else - to_chat(usr, SPAN_WARNING("Required access not found.")) - add_fingerprint(usr) + + if(scan_id) + var/accepted + for(var/req in req_access_claim) + if(req in ID.access) + accepted = TRUE + break + if(!accepted) + to_chat(user, SPAN_WARNING("Required access not found!")) + return ITEM_INTERACT_COMPLETE + + ID.mining_points += points + ID.total_mining_points += points + to_chat(user, SPAN_NOTICE("[points] Mining Points claimed. You have earned a total of [ID.total_mining_points] Mining Points this Shift!")) + points = 0 + SStgui.update_uis(src) + add_fingerprint(user) return ITEM_INTERACT_COMPLETE if(istype(used, /obj/item/disk/design_disk)) @@ -210,12 +227,22 @@ if(default_deconstruction_crowbar(user, I)) return TRUE +/obj/machinery/mineral/ore_redemption/wirecutter_act(mob/user, obj/item/I) + if(!panel_open) + return + . = TRUE + if(!I.tool_start_check(src, user, 0)) + return + wires.Interact(user) + /obj/machinery/mineral/ore_redemption/multitool_act(mob/user, obj/item/I) if(!panel_open) return . = TRUE if(!has_power()) return + if(is_electrified() && shock(user, 100)) + return if(!I.tool_start_check(src, user, 0)) return input_dir = turn(input_dir, -90) @@ -223,11 +250,17 @@ to_chat(user, SPAN_NOTICE("You change [src]'s I/O settings, setting the input to [dir2text(input_dir)] and the output to [dir2text(output_dir)].")) /obj/machinery/mineral/ore_redemption/screwdriver_act(mob/user, obj/item/I) + if(is_electrified() && shock(user, 100)) + return TRUE + if(default_deconstruction_screwdriver(user, "ore_redemption-open", "ore_redemption", I)) SStgui.update_uis(src) return TRUE /obj/machinery/mineral/ore_redemption/wrench_act(mob/user, obj/item/I) + if(is_electrified() && shock(user, 100)) + return TRUE + if(default_unfasten_wrench(user, I, time = 6 SECONDS)) return TRUE @@ -237,13 +270,69 @@ /obj/machinery/mineral/ore_redemption/attack_hand(mob/user) if(..()) return + + if(is_electrified() && shock(user, 100)) + return + ui_interact(user) /obj/machinery/mineral/ore_redemption/ex_act(severity) do_sparks(5, TRUE, src) ..() -// UI +/obj/machinery/mineral/ore_redemption/emag_act(mob/user) + if(emagged) + return FALSE + + to_chat(user, SPAN_NOTICE("You short out the ID scanner on [src], allowing anyone to access it.")) + scan_id = FALSE + emagged = TRUE + +/obj/machinery/mineral/ore_redemption/proc/throw_item() + var/mob/living/target = locate() in view(7, src) + if(!target) + return FALSE + + var/datum/component/material_container/storage = GetComponent(/datum/component/material_container) + for(var/product in storage.materials) + var/datum/material/M = storage.materials[product] + var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT + if(!mineral_amount) + continue + + storage.retrieve_sheets(1, M.id, loc) + break + + var/obj/throw_item = locate(/obj/item/stack/sheet) in get_turf(src) + if(!throw_item) + return + + throw_item.throw_at(target, 16, 3) + visible_message(SPAN_DANGER("[src] launches [throw_item] at [target]!")) + +/obj/machinery/mineral/ore_redemption/proc/is_powered() + if(stat & (NOPOWER|BROKEN)) + return FALSE + + return TRUE + +/obj/machinery/mineral/ore_redemption/proc/temp_electrify(undo = FALSE) + if(undo) + COOLDOWN_RESET(src, temp_shock) + return + + COOLDOWN_START(src, temp_shock, 30 SECONDS) + +/obj/machinery/mineral/ore_redemption/proc/is_electrified() + if(!is_powered()) + return FALSE + + if(wires.is_cut(WIRE_ELECTRIFY) || !COOLDOWN_FINISHED(src, temp_shock)) + return TRUE + + return FALSE + +// MARK: UI /obj/machinery/mineral/ore_redemption/ui_data(mob/user) var/list/data = list() var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) @@ -359,6 +448,7 @@ get_asset_datum(/datum/asset/spritesheet/alloys) ) +// MARK: SMELTING /** * Smelts the given stack of ore. * @@ -499,3 +589,60 @@ /obj/machinery/mineral/ore_redemption/proc/on_material_insert(inserted_type, last_inserted_id, inserted) give_points(inserted_type, inserted) SStgui.update_uis(src) + +// MARK: Wires +/datum/wires/ore_redemption + holder_type = /obj/machinery/mineral/ore_redemption + wire_count = 3 + proper_name = "Ore Redemption Machine" + +/datum/wires/ore_redemption/New(atom/_holder) + wires = list(WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_THROW_ITEM) + return ..() + +/datum/wires/ore_redemption/interactable(mob/user) + var/obj/machinery/mineral/ore_redemption/orm = holder + if(!issilicon(user) && orm.is_electrified() && orm.shock(user, 100)) + return FALSE + if(orm.panel_open) + return TRUE + return FALSE + +/datum/wires/ore_redemption/on_pulse(wire) + var/obj/machinery/mineral/ore_redemption/orm = holder + switch(wire) + if(WIRE_IDSCAN) + if(orm.emagged) + return + orm.scan_id = !orm.scan_id + + if(WIRE_ELECTRIFY) + orm.temp_electrify() + + if(WIRE_THROW_ITEM) + orm.throw_inventory = !orm.throw_inventory + +/datum/wires/ore_redemption/on_cut(wire, mend) + var/obj/machinery/mineral/ore_redemption/orm = holder + switch(wire) + if(WIRE_IDSCAN) + if(orm.emagged) + return + orm.scan_id = !orm.scan_id + + if(WIRE_ELECTRIFY) + if(mend) + orm.temp_electrify(TRUE) + + if(WIRE_THROW_ITEM) + orm.throw_inventory = TRUE + +/datum/wires/ore_redemption/get_status() + . = ..() + var/obj/machinery/mineral/ore_redemption/orm = holder + . += "The orange light is [(orm.is_electrified()) ? "off" : "on"]." + . += "The red light is [(orm.throw_inventory && orm.is_powered()) ? "off" : "blinking"]." + . += "The ID scanner light is [(orm.scan_id && !orm.emagged && orm.is_powered()) ? "off" : "on"]." + +/obj/machinery/mineral/ore_redemption/get_internal_wires() + return wires