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