From 2b6fec1c29e9afa10bb896e513bb1a95d13b4f95 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Tue, 2 Jan 2024 18:32:54 +0530 Subject: [PATCH] Turbine code cleanup (#80637) ## About The Pull Request 1. Removed unused vars `our_turf_thermal_conductivity`. It did nothing 2. Removed redundant vars such as - `mapped` : It can be replaced with `maploaded` var inside `Initialize()` proc as it simply checks if the turbine was created during round start or not. This does mean that admin spawned turbine parts won't come pre installed with parts but that's not a big deal since they can spawn the parts anyway - `has_gas_mix` : All turbine parts set's this var to `TRUE` so might as well make that the default case - `gas_theoretical_volume` : This can be passed as an param inside `Initialize()` directly rather than storing it in a var which gets used only once 3. Autodoc for procs, fixed return values of some tool acts & `attackby`(we want to return TRUE to end the attack chain early). Removes balloon alert when opening/closing panel. The visual overlay makes that obvious 4. The turbine now shuts itself off when the room has no power/the turbine is sufficiently damaged. The turbine uses a small amount of power for operation (for that green light, internal electronics & stuff) cause it makes sense 5. Fixes runtime when opening turbine computer and one of the turbine parts is disconnected 6. Adds Screen tips & fixes examines (they weren't using the `span_notice()` proc) and adds even more examines ## Changelog :cl: fix: turbine now shuts itself off when the room apc loses power or if it gets damaged. Also uses a small amount of power for operation of internal electronics, the green light & other stuff fix: No more runtime in turbine computer when parts are not fully connected qol: adds screentips & examines for turbine code: removed unused vars, auto doc procs and cleans up some code in turbine /:cl: --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> --- .../machines/machine_circuitboards.dm | 6 +- code/modules/power/power.dm | 2 + code/modules/power/turbine/turbine.dm | 225 ++++++++++-------- .../modules/power/turbine/turbine_computer.dm | 6 +- 4 files changed, 132 insertions(+), 107 deletions(-) diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 899be7b1813..0cceb59b3cd 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -283,7 +283,7 @@ /obj/item/circuitboard/machine/turbine_compressor name = "Turbine - Inlet Compressor" greyscale_colors = CIRCUIT_COLOR_ENGINEERING - build_path = /obj/machinery/power/turbine/inlet_compressor/constructed + build_path = /obj/machinery/power/turbine/inlet_compressor req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stack/sheet/iron = 5) @@ -291,7 +291,7 @@ /obj/item/circuitboard/machine/turbine_rotor name = "Turbine - Core Rotor" greyscale_colors = CIRCUIT_COLOR_ENGINEERING - build_path = /obj/machinery/power/turbine/core_rotor/constructed + build_path = /obj/machinery/power/turbine/core_rotor req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stack/sheet/iron = 5) @@ -299,7 +299,7 @@ /obj/item/circuitboard/machine/turbine_stator name = "Turbine - Turbine Outlet" greyscale_colors = CIRCUIT_COLOR_ENGINEERING - build_path = /obj/machinery/power/turbine/turbine_outlet/constructed + build_path = /obj/machinery/power/turbine/turbine_outlet req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stack/sheet/iron = 5) diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 0fe5b32838b..798bf2a2d75 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -60,6 +60,8 @@ return can_change_cable_layer /obj/machinery/power/multitool_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(!can_change_cable_layer || !cable_layer_change_checks(user, tool)) return diff --git a/code/modules/power/turbine/turbine.dm b/code/modules/power/turbine/turbine.dm index 06466318025..fa1a885044a 100644 --- a/code/modules/power/turbine/turbine.dm +++ b/code/modules/power/turbine/turbine.dm @@ -7,25 +7,17 @@ can_atmos_pass = ATMOS_PASS_DENSITY processing_flags = NONE - ///Theoretical volume of gas that's moving through the turbine, it expands the further it goes - var/gas_theoretical_volume = 0 - ///Stores the turf thermal conductivity to restore it later - var/our_turf_thermal_conductivity ///Checks if the machine is processing or not var/active = FALSE ///The parts can be registered on the main one only when their panel is closed var/can_connect = TRUE - ///Reference to our turbine part var/obj/item/turbine_parts/installed_part ///Path of the turbine part we can install var/obj/item/turbine_parts/part_path - - var/has_gasmix = FALSE + ///The gas mixture this turbine part is storing var/datum/gas_mixture/machine_gasmix - var/mapped = TRUE - ///Our overlay when active var/active_overlay = "" ///Our overlay when off @@ -35,20 +27,22 @@ ///Should we use emissive appearance? var/emissive = FALSE -/obj/machinery/power/turbine/Initialize(mapload) +/obj/machinery/power/turbine/Initialize(mapload, gas_theoretical_volume) . = ..() - if(has_gasmix) - machine_gasmix = new - machine_gasmix.volume = gas_theoretical_volume + machine_gasmix = new + machine_gasmix.volume = gas_theoretical_volume - if(part_path && mapped) + if(mapload) installed_part = new part_path(src) air_update_turf(TRUE) update_appearance() + register_context() + + /obj/machinery/power/turbine/LateInitialize() . = ..() activate_parts() @@ -60,13 +54,22 @@ QDEL_NULL(installed_part) if(machine_gasmix) - machine_gasmix = null + QDEL_NULL(machine_gasmix) deactivate_parts() return ..() /** * Handles all the calculations needed for the gases, work done, temperature increase/decrease + * + * Arguments + * * datum/gas_mixture/input_mix - the gas from the environment or from another part of the turbine + * * datum/gas_mixture/output_mix - the gas that got pumped into this part from the input mix. + * ideally should be same as input mix but varying texmperatur & pressures can cause varying results + * * work_amount_to_remove - the amount of work to subtract from the actual work done to pump in the input mixture. + * For e.g. if gas was transfered from the inlet compressor to the rotor we want to subtract the work done + * by the inlet from the rotor to get the true work done + * * intake_size - the percentage of gas to be fed into an turbine part, controlled by turbine computer for inlet compressor only */ /obj/machinery/power/turbine/proc/transfer_gases(datum/gas_mixture/input_mix, datum/gas_mixture/output_mix, work_amount_to_remove, intake_size = 1) //pump gases. if no gases were transferred then no work was done @@ -91,15 +94,49 @@ /obj/machinery/power/turbine/block_superconductivity() return TRUE +/obj/machinery/power/turbine/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(isnull(held_item)) + return NONE + + if(panel_open && istype(held_item, part_path)) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "[installed_part ? "Replace" : "Install"] part" + return CONTEXTUAL_SCREENTIP_SET + + if(held_item.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "[panel_open ? "Close" : "Open"] panel" + return CONTEXTUAL_SCREENTIP_SET + + if(held_item.tool_behaviour == TOOL_WRENCH && panel_open) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Rotate" + return CONTEXTUAL_SCREENTIP_SET + + if(held_item.tool_behaviour == TOOL_CROWBAR) + if(installed_part) + context[SCREENTIP_CONTEXT_CTRL_RMB] = "Remove part" + if(panel_open) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Deconstruct" + return CONTEXTUAL_SCREENTIP_SET + + if(held_item.tool_behaviour == TOOL_MULTITOOL) + if(panel_open) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Change cable layer" + else + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Link parts" + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/power/turbine/examine(mob/user) . = ..() if(installed_part) - . += "Currently at tier [installed_part.current_tier]." + . += span_notice("Currently at tier [installed_part.current_tier].") if(installed_part.current_tier + 1 < installed_part.max_tier) - . += "Can be upgraded by using a tier [installed_part.current_tier + 1] part." - . += "The [installed_part.name] can be removed by right-click with a crowbar tool." + . += span_notice("Can be upgraded by using a tier [installed_part.current_tier + 1] part.") + . += span_notice("The [installed_part.name] can be [EXAMINE_HINT("pried")] out.") else - . += "Is missing a [initial(part_path.name)]." + . += span_warning("Is missing a [initial(part_path.name)].") + . += span_notice("Its maintainence panel can be [EXAMINE_HINT("screwed")] [panel_open ? "closed" : "open"].") + if(panel_open) + . += span_notice("It can rotated with a [EXAMINE_HINT("wrench")]") + . += span_notice("The full machine can be [EXAMINE_HINT("pried")] apart") /obj/machinery/power/turbine/update_overlays() . = ..() @@ -114,12 +151,13 @@ . += off_overlay /obj/machinery/power/turbine/screwdriver_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING if(active) balloon_alert(user, "turn it off!") - return ITEM_INTERACT_SUCCESS + return if(!anchored) balloon_alert(user, "anchor first!") - return ITEM_INTERACT_SUCCESS + return tool.play_tool_sound(src, 50) toggle_panel_open() @@ -127,44 +165,54 @@ deactivate_parts(user) else activate_parts(user) - balloon_alert(user, "you [panel_open ? "open" : "close"] the maintenance hatch of [src]") update_appearance() return ITEM_INTERACT_SUCCESS /obj/machinery/power/turbine/wrench_act(mob/living/user, obj/item/tool) - return default_change_direction_wrench(user, tool) + . = ITEM_INTERACT_BLOCKING + if(default_change_direction_wrench(user, tool)) + return ITEM_INTERACT_SUCCESS /obj/machinery/power/turbine/crowbar_act(mob/living/user, obj/item/tool) - return default_deconstruction_crowbar(tool) + . = ITEM_INTERACT_BLOCKING + if(default_deconstruction_crowbar(tool)) + return ITEM_INTERACT_SUCCESS /obj/machinery/power/turbine/on_deconstruction() - if(installed_part) - installed_part.forceMove(loc) + installed_part?.forceMove(loc) return ..() /obj/machinery/power/turbine/crowbar_act_secondary(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING if(!panel_open) balloon_alert(user, "panel is closed!") - return ITEM_INTERACT_SUCCESS + return if(!installed_part) balloon_alert(user, "no rotor installed!") - return ITEM_INTERACT_SUCCESS + return if(active) balloon_alert(user, "[src] is on!") - return ITEM_INTERACT_SUCCESS - user.put_in_hands(installed_part) + return + user.put_in_hands(installed_part) return ITEM_INTERACT_SUCCESS /** * Allow easy enabling of each machine for connection to the main controller + * + * Arguments + * * mob/user - the player who activated the parts + * * check_only - if TRUE it will not activate the machine but will only check if it can be activated */ /obj/machinery/power/turbine/proc/activate_parts(mob/user, check_only = FALSE) can_connect = TRUE /** * Allow easy disabling of each machine from the main controller + * + * Arguments + * * mob/user - the player who deactivated the parts */ /obj/machinery/power/turbine/proc/deactivate_parts(mob/user) can_connect = FALSE @@ -196,7 +244,7 @@ //install the part if(!do_after(user, 2 SECONDS, src)) - return + return TRUE if(installed_part) user.put_in_hands(installed_part) balloon_alert(user, "replaced part with the one in hand") @@ -204,29 +252,19 @@ balloon_alert(user, "installed new part") user.transferItemToLoc(object, src) installed_part = object + return TRUE -/** - * Gets the efficiency of the installed part, returns 0 if no part is installed - */ +/// Gets the efficiency of the installed part, returns 0 if no part is installed /obj/machinery/power/turbine/proc/get_efficiency() - if(installed_part) - return installed_part.part_efficiency - return 0 + return installed_part?.part_efficiency || 0 /obj/machinery/power/turbine/inlet_compressor name = "inlet compressor" desc = "The input side of a turbine generator, contains the compressor." icon = 'icons/obj/machines/engine/turbine.dmi' icon_state = "inlet_compressor" - circuit = /obj/item/circuitboard/machine/turbine_compressor - - gas_theoretical_volume = 1000 - part_path = /obj/item/turbine_parts/compressor - - has_gasmix = TRUE - active_overlay = "inlet_animation" off_overlay = "inlet_off" open_overlay = "inlet_open" @@ -239,9 +277,13 @@ var/compressor_work /// Pressure of gases absorbed var/compressor_pressure - ///Ratio of the amount of gas going in the turbine + ///Ratio of gases going in the turbine var/intake_regulator = 0.5 +/obj/machinery/power/turbine/inlet_compressor/Initialize(mapload) + //Volume of gas mixture is 1000 + return ..(mapload, gas_theoretical_volume = 1000) + /obj/machinery/power/turbine/inlet_compressor/deactivate_parts(mob/user) . = ..() if(!QDELETED(rotor)) @@ -266,29 +308,19 @@ //the compressor compresses down the gases from 2500 L to 1000 L //the temperature and pressure rises up, you can regulate this to increase/decrease the amount of gas moved in. compressor_work = transfer_gases(input_turf_mixture, machine_gasmix, work_amount_to_remove = 0, intake_size = intake_regulator) - input_turf.update_visuals() input_turf.air_update_turf(TRUE) + input_turf.update_visuals() compressor_pressure = PRESSURE_MAX(machine_gasmix.return_pressure()) return input_turf_mixture.temperature -/obj/machinery/power/turbine/inlet_compressor/constructed - mapped = FALSE - /obj/machinery/power/turbine/turbine_outlet name = "turbine outlet" desc = "The output side of a turbine generator, contains the turbine and the stator." icon = 'icons/obj/machines/engine/turbine.dmi' icon_state = "turbine_outlet" - circuit = /obj/item/circuitboard/machine/turbine_stator - - gas_theoretical_volume = 6000 - part_path = /obj/item/turbine_parts/stator - - has_gasmix = TRUE - active_overlay = "outlet_animation" off_overlay = "outlet_off" open_overlay = "outlet_open" @@ -298,6 +330,10 @@ /// The turf to puch the gases out into var/turf/open/output_turf +/obj/machinery/power/turbine/turbine_outlet/Initialize(mapload) + //Volume of gas mixture is 6000 + return ..(mapload, gas_theoretical_volume = 6000) + /obj/machinery/power/turbine/turbine_outlet/deactivate_parts(mob/user) . = ..() if(!QDELETED(rotor)) @@ -316,77 +352,56 @@ //eject gases and update turf is any was ejected var/datum/gas_mixture/ejected_gases = machine_gasmix.pump_gas_to(output_turf.air, machine_gasmix.return_pressure()) if(ejected_gases) - output_turf.update_visuals() output_turf.air_update_turf(TRUE) + output_turf.update_visuals() //return ejected gases return ejected_gases -/obj/machinery/power/turbine/turbine_outlet/constructed - mapped = FALSE - /obj/machinery/power/turbine/core_rotor name = "core rotor" desc = "The middle part of a turbine generator, contains the rotor and the main computer." icon = 'icons/obj/machines/engine/turbine.dmi' icon_state = "core_rotor" - can_change_cable_layer = TRUE - - circuit = /obj/item/circuitboard/machine/turbine_rotor - - gas_theoretical_volume = 3000 - - part_path = /obj/item/turbine_parts/rotor - - has_gasmix = TRUE - active_overlay = "core_light" open_overlay = "core_open" - + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION emissive = TRUE + can_change_cable_layer = TRUE + circuit = /obj/item/circuitboard/machine/turbine_rotor + part_path = /obj/item/turbine_parts/rotor ///ID to easily connect the main part of the turbine to the computer var/mapping_id - ///Reference to the compressor var/obj/machinery/power/turbine/inlet_compressor/compressor ///Reference to the turbine var/obj/machinery/power/turbine/turbine_outlet/turbine - ///Rotation per minute the machine is doing var/rpm ///Amount of power the machine is producing var/produced_energy - ///Check to see if all parts are connected to the core var/all_parts_connected = FALSE - ///Max rmp that the installed parts can handle, limits the rpms var/max_allowed_rpm = 0 ///Max temperature that the installed parts can handle, unlimited and causes damage to the machine var/max_allowed_temperature = 0 - ///Amount of damage the machine has received var/damage = 0 ///Used to calculate the max damage received per tick and if the alarm should be called var/damage_archived = 0 - ///Our internal radio var/obj/item/radio/radio - ///The key our internal radio uses - var/radio_key = /obj/item/encryptionkey/headset_eng - ///The engineering channel - var/engineering_channel = "Engineering" COOLDOWN_DECLARE(turbine_damage_alert) -/obj/machinery/power/turbine/core_rotor/constructed - mapped = FALSE - /obj/machinery/power/turbine/core_rotor/Initialize(mapload) - . = ..() + //Volume of gas mixture is 3000 + . = ..(mapload, gas_theoretical_volume = 3000) + radio = new(src) - radio.keyslot = new radio_key + radio.keyslot = new /obj/item/encryptionkey/headset_eng radio.set_listening(FALSE) radio.recalculateChannels() @@ -396,6 +411,18 @@ QDEL_NULL(radio) return ..() +/obj/machinery/power/turbine/core_rotor/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(. == NONE) + return + + if(held_item.tool_behaviour == TOOL_MULTITOOL) + if(panel_open) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Change cable layer" + else + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Link/Log parts" + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/power/turbine/core_rotor/examine(mob/user) . = ..() if(!panel_open) @@ -524,9 +551,7 @@ deactivate_parts() return ..() -/** - * Toggle power on and off, not safe - */ +/// Toggle power on and off, not safe /obj/machinery/power/turbine/core_rotor/proc/toggle_power() if(active) power_off() @@ -546,9 +571,7 @@ call_parts_update_appearance() SSair.start_processing_machine(src) -/** - * Calls all parts update appearance proc. - */ +/// Calls all parts update appearance proc. /obj/machinery/power/turbine/core_rotor/proc/call_parts_update_appearance() update_appearance() if(!QDELETED(compressor)) @@ -571,9 +594,7 @@ call_parts_update_appearance() SSair.stop_processing_machine(src) -/** - * Returns true if all parts have their panel closed - */ +/// Returns true if all parts have their panel closed /obj/machinery/power/turbine/core_rotor/proc/all_parts_ready() if(QDELETED(compressor)) return FALSE @@ -581,19 +602,20 @@ return FALSE return !panel_open && !compressor.panel_open && !turbine.panel_open -/** - * Getter for turbine integrity, return the amount in % - */ +/// Getter for turbine integrity, return the amount in % /obj/machinery/power/turbine/core_rotor/proc/get_turbine_integrity() var/integrity = damage / 500 integrity = max(round(100 - integrity * 100, 0.01), 0) return integrity /obj/machinery/power/turbine/core_rotor/process_atmos() - if(!active || !activate_parts(check_only = TRUE)) + if(!active || !activate_parts(check_only = TRUE) || (machine_stat & BROKEN) || !powered(ignore_use_power = TRUE)) power_off() return PROCESS_KILL + //use power to operate internal electronics & stuff + update_mode_power_usage(ACTIVE_POWER_USE, active_power_usage) + //===============COMPRESSOR WORKING========// //Transfer gases from turf to compressor var/temperature = compressor.compress_gases() @@ -624,7 +646,8 @@ if(rpm < 550000) explosion(src, 2, 5, 7) return PROCESS_KILL - radio.talk_into(src, "Warning, turbine at [get_area_name(src)] taking damage, current integrity at [integrity]%!", engineering_channel) + + radio.talk_into(src, "Warning, turbine at [get_area_name(src)] taking damage, current integrity at [integrity]%!", RADIO_CHANNEL_ENGINEERING) playsound(src, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff_distance = 10) //================ROTOR WORKING============// @@ -646,7 +669,7 @@ //calculate final acheived rpm rpm = ((work_done * compressor.get_efficiency()) ** turbine.get_efficiency()) * get_efficiency() / TURBINE_RPM_CONVERSION rpm = FLOOR(min(rpm, max_allowed_rpm), 1) - //add energy into the grid + //add energy into the grid, also use part of it for turbine operation produced_energy = rpm * TURBINE_ENERGY_RECTIFICATION_MULTIPLIER * TURBINE_RPM_CONVERSION add_avail(produced_energy) diff --git a/code/modules/power/turbine/turbine_computer.dm b/code/modules/power/turbine/turbine_computer.dm index 8e8ba8deb4c..9e0f5bdaa46 100644 --- a/code/modules/power/turbine/turbine_computer.dm +++ b/code/modules/power/turbine/turbine_computer.dm @@ -54,20 +54,20 @@ var/list/data = list() var/obj/machinery/power/turbine/core_rotor/main_control = turbine_core?.resolve() - - data["connected"] = main_control ? TRUE : FALSE + data["connected"] = !!QDELETED(main_control) if(!main_control) return + data["active"] = main_control.active data["rpm"] = main_control.rpm ? main_control.rpm : 0 data["power"] = main_control.produced_energy ? main_control.produced_energy : 0 - data["temp"] = main_control.compressor.input_turf?.air.temperature data["integrity"] = main_control.get_turbine_integrity() data["parts_linked"] = main_control.all_parts_connected data["parts_ready"] = main_control.all_parts_ready() data["max_rpm"] = main_control.max_allowed_rpm data["max_temperature"] = main_control.max_allowed_temperature + data["temp"] = main_control.compressor?.input_turf?.air.temperature || 0 data["regulator"] = QDELETED(main_control.compressor) ? 0 : main_control.compressor.intake_regulator return data