mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 04:26:03 +01:00
[MIRROR] Integrated circuits for modular computers (#26196)
Integrated circuits for modular computers (#80530) This PR integrates circuits for modular computers and a good bits of their programs. The peculiarity here is that modular computers have no fixed amount of unremovable components (except the base one with just a couple ports for now), instead, they're added and removed along with programs. With a few exceptions (such as the messenger and signaler), for these program circuits to work, their associated program has to be either open or in the background. For a reason or another, not all programs have a circuit associated to them, still, however the programs with a circuit are still a handful. They are: - Nanotrasen Pay System - Notepad - SiliConnect - WireCarp - MODsuit Control - Spectre Meter - Direct Messenger* - LifeConnect - Custodial Locator - Fission360 - Camera - Status Display - SignalCommander *By the by, sending messages has a cooldown, so it shouldn't be as spammy. If it turns out to not be enough, I can make it so messages from circuit will be ignored by other messenger circuits. The PR is no longer WIP. I believe modular computers could make for some interesting setups with circuits, since they're fairly flexible and stocked with features unlike many other appliances, therefore also a speck more abusable, though limits, cooldowns, logging and sanitization have been implemented to keep it in check. 🆑 add: Modular Computers now support integrated circuits. What can be done with them depends on the programs installed and whether they're running (open or background). add: Modular Consoles (the machinery) now have a small backup cell they draw power from if the power goes out. /🆑 Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -110,6 +110,15 @@
|
||||
///The max amount of paper that can be held at once.
|
||||
var/max_paper = 30
|
||||
|
||||
/// The capacity of the circuit shell component of this item
|
||||
var/shell_capacity = SHELL_CAPACITY_MEDIUM
|
||||
|
||||
/**
|
||||
* Reference to the circuit shell component, because we're special and do special things with it,
|
||||
* such as creating and deleting unremovable circuit comps based on the programs installed.
|
||||
*/
|
||||
var/datum/component/shell/shell
|
||||
|
||||
/datum/armor/item_modular_computer
|
||||
bullet = 20
|
||||
laser = 20
|
||||
@@ -120,6 +129,7 @@
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(!physical)
|
||||
physical = src
|
||||
add_shell_component(shell_capacity)
|
||||
set_light_color(comp_light_color)
|
||||
set_light_range(comp_light_luminosity)
|
||||
if(looping_sound)
|
||||
@@ -137,6 +147,26 @@
|
||||
register_context()
|
||||
update_appearance()
|
||||
|
||||
///Initialize the shell for this item, or the physical machinery it belongs to.
|
||||
/obj/item/modular_computer/proc/add_shell_component(capacity = SHELL_CAPACITY_MEDIUM, shell_flags = NONE)
|
||||
shell = physical.AddComponent(/datum/component/shell, list(new /obj/item/circuit_component/modpc), capacity, shell_flags)
|
||||
RegisterSignal(shell, COMSIG_SHELL_CIRCUIT_ATTACHED, PROC_REF(on_circuit_attached))
|
||||
RegisterSignal(shell, COMSIG_SHELL_CIRCUIT_REMOVED, PROC_REF(on_circuit_removed))
|
||||
|
||||
/obj/item/modular_computer/proc/on_circuit_attached(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
RegisterSignal(shell.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE, PROC_REF(use_power_for_circuits))
|
||||
|
||||
///Try to draw power from our internal cell first, before switching to that of the circuit.
|
||||
/obj/item/modular_computer/proc/use_power_for_circuits(datum/source, power_usage_per_input)
|
||||
SIGNAL_HANDLER
|
||||
if(use_power(power_usage_per_input, check_programs = FALSE))
|
||||
return COMPONENT_OVERRIDE_POWER_USAGE
|
||||
|
||||
/obj/item/modular_computer/proc/on_circuit_removed(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(shell.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE)
|
||||
|
||||
/obj/item/modular_computer/proc/install_default_programs()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
for(var/programs in default_programs + starting_programs)
|
||||
@@ -158,6 +188,7 @@
|
||||
if(computer_id_slot)
|
||||
QDEL_NULL(computer_id_slot)
|
||||
|
||||
shell = null
|
||||
physical = null
|
||||
return ..()
|
||||
|
||||
@@ -438,29 +469,32 @@
|
||||
/obj/item/modular_computer/proc/turn_on(mob/user, open_ui = TRUE)
|
||||
var/issynth = issilicon(user) // Robots and AIs get different activation messages.
|
||||
if(atom_integrity <= integrity_failure * max_integrity)
|
||||
if(issynth)
|
||||
to_chat(user, span_warning("You send an activation signal to \the [src], but it responds with an error code. It must be damaged."))
|
||||
else
|
||||
to_chat(user, span_warning("You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again."))
|
||||
if(user)
|
||||
if(issynth)
|
||||
to_chat(user, span_warning("You send an activation signal to \the [src], but it responds with an error code. It must be damaged."))
|
||||
else
|
||||
to_chat(user, span_warning("You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again."))
|
||||
return FALSE
|
||||
|
||||
if(use_power()) // checks if the PC is powered
|
||||
if(issynth)
|
||||
to_chat(user, span_notice("You send an activation signal to \the [src], turning it on."))
|
||||
else
|
||||
to_chat(user, span_notice("You press the power button and start up \the [src]."))
|
||||
if(looping_sound)
|
||||
soundloop.start()
|
||||
enabled = TRUE
|
||||
update_appearance()
|
||||
if(open_ui)
|
||||
update_tablet_open_uis(user)
|
||||
if(user)
|
||||
if(issynth)
|
||||
to_chat(user, span_notice("You send an activation signal to \the [src], turning it on."))
|
||||
else
|
||||
to_chat(user, span_notice("You press the power button and start up \the [src]."))
|
||||
if(open_ui)
|
||||
update_tablet_open_uis(user)
|
||||
return TRUE
|
||||
else // Unpowered
|
||||
if(issynth)
|
||||
to_chat(user, span_warning("You send an activation signal to \the [src] but it does not respond."))
|
||||
else
|
||||
to_chat(user, span_warning("You press the power button but \the [src] does not respond."))
|
||||
if(user)
|
||||
if(issynth)
|
||||
to_chat(user, span_warning("You send an activation signal to \the [src] but it does not respond."))
|
||||
else
|
||||
to_chat(user, span_warning("You press the power button but \the [src] does not respond."))
|
||||
return FALSE
|
||||
|
||||
// Process currently calls handle_power(), may be expanded in future if more things are added.
|
||||
@@ -572,18 +606,22 @@
|
||||
if(program.computer != src)
|
||||
CRASH("tried to open program that does not belong to this computer")
|
||||
|
||||
if(!program || !istype(program)) // Program not found or it's not executable program.
|
||||
if(isnull(program) || !istype(program)) // Program not found or it's not executable program.
|
||||
if(user)
|
||||
to_chat(user, span_danger("\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning."))
|
||||
return FALSE
|
||||
|
||||
if(active_program == program)
|
||||
return FALSE
|
||||
|
||||
// The program is already running. Resume it.
|
||||
if(program in idle_threads)
|
||||
active_program?.background_program()
|
||||
active_program = program
|
||||
program.alert_pending = FALSE
|
||||
idle_threads.Remove(program)
|
||||
if(open_ui)
|
||||
update_tablet_open_uis(user)
|
||||
INVOKE_ASYNC(src, PROC_REF(update_tablet_open_uis), user)
|
||||
update_appearance(UPDATE_ICON)
|
||||
return TRUE
|
||||
|
||||
@@ -603,10 +641,12 @@
|
||||
if(!program.on_start(user))
|
||||
return FALSE
|
||||
|
||||
active_program?.background_program()
|
||||
|
||||
active_program = program
|
||||
program.alert_pending = FALSE
|
||||
if(open_ui)
|
||||
update_tablet_open_uis(user)
|
||||
INVOKE_ASYNC(src, PROC_REF(update_tablet_open_uis), user)
|
||||
update_appearance(UPDATE_ICON)
|
||||
return TRUE
|
||||
|
||||
@@ -682,10 +722,11 @@
|
||||
* It is separated from ui_act() to be overwritten as needed.
|
||||
*/
|
||||
/obj/item/modular_computer/proc/toggle_flashlight(mob/user)
|
||||
if(!has_light || !internal_cell || !internal_cell.charge)
|
||||
if(!has_light || !internal_cell?.charge)
|
||||
return FALSE
|
||||
if(!COOLDOWN_FINISHED(src, disabled_time))
|
||||
balloon_alert(user, "disrupted!")
|
||||
if(user)
|
||||
balloon_alert(user, "disrupted!")
|
||||
return FALSE
|
||||
set_light_on(!light_on)
|
||||
update_appearance()
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
///A simple circuit component compatible with stationary consoles, laptops and PDAs, independent from programs.
|
||||
/obj/item/circuit_component/modpc
|
||||
display_name = "Modular Computer"
|
||||
desc = "Circuit for basic functions of a modular computer."
|
||||
var/obj/item/modular_computer/computer
|
||||
///Turns the PC on/off
|
||||
var/datum/port/input/on_off
|
||||
///When set, will print a piece of paper with the value as text.
|
||||
var/datum/port/input/print
|
||||
|
||||
///Toggles lights on and off. Also RGB.
|
||||
var/datum/port/input/lights
|
||||
var/datum/port/input/red
|
||||
var/datum/port/input/green
|
||||
var/datum/port/input/blue
|
||||
|
||||
/obj/item/circuit_component/modpc/register_shell(atom/movable/shell)
|
||||
. = ..()
|
||||
if(istype(shell, /obj/item/modular_computer))
|
||||
computer = shell
|
||||
else if(istype(shell, /obj/machinery/modular_computer))
|
||||
var/obj/machinery/modular_computer/console = shell
|
||||
computer = console.cpu
|
||||
|
||||
/**
|
||||
* Some mod pc have lights while some don't, but populate_ports()
|
||||
* is called before we get to know which object this has attahed to,
|
||||
* I hope you're cool with me doing it here.
|
||||
*/
|
||||
if(computer?.has_light)
|
||||
lights = add_input_port("Toggle Lights", PORT_TYPE_SIGNAL)
|
||||
red = add_input_port("Red", PORT_TYPE_NUMBER)
|
||||
green = add_input_port("Green", PORT_TYPE_NUMBER)
|
||||
blue = add_input_port("Blue", PORT_TYPE_NUMBER)
|
||||
|
||||
/obj/item/circuit_component/modpc/unregister_shell(atom/movable/shell)
|
||||
computer = null
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/modpc/populate_ports()
|
||||
on_off = add_input_port("Turn On/Off", PORT_TYPE_SIGNAL)
|
||||
print = add_input_port("Print Text", PORT_TYPE_STRING)
|
||||
|
||||
/obj/item/circuit_component/modpc/pre_input_received(datum/port/input/port)
|
||||
if(isnull(computer))
|
||||
return
|
||||
if(COMPONENT_TRIGGERED_BY(print, port))
|
||||
print.set_value(html_encode(trim(print.value, MAX_PAPER_LENGTH)))
|
||||
else if(COMPONENT_TRIGGERED_BY(red, port))
|
||||
red.set_value(clamp(red.value, 0, 255))
|
||||
else if(COMPONENT_TRIGGERED_BY(blue, port))
|
||||
blue.set_value(clamp(blue.value, 0, 255))
|
||||
else if(COMPONENT_TRIGGERED_BY(green, port))
|
||||
green.set_value(clamp(green.value, 0, 255))
|
||||
|
||||
/obj/item/circuit_component/modpc/input_received(datum/port/input/port)
|
||||
if(isnull(computer))
|
||||
return
|
||||
if(COMPONENT_TRIGGERED_BY(on_off, port))
|
||||
if(computer.enabled)
|
||||
INVOKE_ASYNC(computer, TYPE_PROC_REF(/obj/item/modular_computer, shutdown_computer))
|
||||
else
|
||||
INVOKE_ASYNC(computer, TYPE_PROC_REF(/obj/item/modular_computer, turn_on))
|
||||
return
|
||||
|
||||
if(!computer.enabled)
|
||||
return
|
||||
|
||||
if(COMPONENT_TRIGGERED_BY(print, port))
|
||||
computer.print_text(print.value)
|
||||
|
||||
if(lights)
|
||||
if(COMPONENT_TRIGGERED_BY(lights, port))
|
||||
computer.toggle_flashlight()
|
||||
if(COMPONENT_TRIGGERED_BY(red, port) || COMPONENT_TRIGGERED_BY(green, port) || COMPONENT_TRIGGERED_BY(blue, port))
|
||||
computer.set_flashlight_color(rgb(red.value || 0, green.value || 0, blue.value || 0))
|
||||
@@ -3,23 +3,24 @@
|
||||
|
||||
///Draws power from its rightful source (area if its a computer, the cell otherwise)
|
||||
///Takes into account special cases, like silicon PDAs through override, and nopower apps.
|
||||
/obj/item/modular_computer/proc/use_power(amount = 0)
|
||||
if(check_power_override())
|
||||
/obj/item/modular_computer/proc/use_power(amount = 0, check_programs = TRUE)
|
||||
if(check_power_override(amount))
|
||||
return TRUE
|
||||
|
||||
if(!internal_cell)
|
||||
return FALSE
|
||||
if(!internal_cell.charge && (isnull(active_program) || !(active_program.program_flags & PROGRAM_RUNS_WITHOUT_POWER)))
|
||||
close_all_programs()
|
||||
for(var/datum/computer_file/program/programs as anything in stored_files)
|
||||
if((programs.program_flags & PROGRAM_RUNS_WITHOUT_POWER) && open_program(program = programs))
|
||||
return TRUE
|
||||
if(internal_cell.use(amount JOULES))
|
||||
return TRUE
|
||||
if(!check_programs)
|
||||
return FALSE
|
||||
|
||||
if(!internal_cell.use(amount JOULES))
|
||||
internal_cell.use(min(amount JOULES, internal_cell.charge)) //drain it anyways.
|
||||
return FALSE
|
||||
return TRUE
|
||||
internal_cell.use(min(amount JOULES, internal_cell.charge)) //drain it anyways.
|
||||
if(active_program?.program_flags & PROGRAM_RUNS_WITHOUT_POWER)
|
||||
return TRUE
|
||||
INVOKE_ASYNC(src, PROC_REF(close_all_programs))
|
||||
for(var/datum/computer_file/program/programs as anything in stored_files)
|
||||
if((programs.program_flags & PROGRAM_RUNS_WITHOUT_POWER) && open_program(program = programs))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/modular_computer/proc/give_power(amount)
|
||||
if(internal_cell)
|
||||
@@ -60,8 +61,8 @@
|
||||
|
||||
///Returns TRUE if the PC should not be using any power, FALSE otherwise.
|
||||
///Checks to see if the current app allows to be ran without power, if so we'll run with it.
|
||||
/obj/item/modular_computer/proc/check_power_override()
|
||||
return (!internal_cell?.charge && (active_program?.program_flags & PROGRAM_RUNS_WITHOUT_POWER))
|
||||
/obj/item/modular_computer/proc/check_power_override(amount)
|
||||
return !amount && !internal_cell?.charge && (active_program?.program_flags & PROGRAM_RUNS_WITHOUT_POWER)
|
||||
|
||||
//Integrated (Silicon) tablets don't drain power, because the tablet is required to state laws, so it being disabled WILL cause problems.
|
||||
/obj/item/modular_computer/pda/silicon/check_power_override()
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
if("PC_minimize")
|
||||
if(!active_program || (!isnull(internal_cell) && !internal_cell.charge))
|
||||
return
|
||||
active_program.background_program()
|
||||
active_program.background_program(usr)
|
||||
return TRUE
|
||||
|
||||
if("PC_killprogram")
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
comp_light_luminosity = 2.3 //this is what old PDAs were set to
|
||||
looping_sound = FALSE
|
||||
|
||||
shell_capacity = SHELL_CAPACITY_SMALL
|
||||
|
||||
///The item currently inserted into the PDA, starts with a pen.
|
||||
var/obj/item/inserted_item = /obj/item/pen
|
||||
|
||||
@@ -337,6 +339,10 @@
|
||||
silicon_owner = null
|
||||
return ..()
|
||||
|
||||
///Silicons don't have the tools (or hands) to make circuits setups with their own PDAs.
|
||||
/obj/item/modular_computer/pda/silicon/add_shell_component(capacity)
|
||||
return
|
||||
|
||||
/obj/item/modular_computer/pda/silicon/turn_on(mob/user, open_ui = FALSE)
|
||||
if(silicon_owner?.stat != DEAD)
|
||||
return ..()
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
icon_state = null
|
||||
icon_state_unpowered = null
|
||||
icon_state_menu = null
|
||||
hardware_flag = 0
|
||||
hardware_flag = NONE
|
||||
internal_cell = /obj/item/stock_parts/cell/crap
|
||||
|
||||
///The modular computer MACHINE that hosts us.
|
||||
var/obj/machinery/modular_computer/machinery_computer
|
||||
@@ -25,7 +26,6 @@
|
||||
physical = loc
|
||||
machinery_computer = loc
|
||||
machinery_computer.cpu = src
|
||||
internal_cell = machinery_computer.internal_cell
|
||||
hardware_flag = machinery_computer.hardware_flag
|
||||
steel_sheet_cost = machinery_computer.steel_sheet_cost
|
||||
max_idle_programs = machinery_computer.max_idle_programs
|
||||
@@ -44,12 +44,12 @@
|
||||
machinery_computer = null
|
||||
return ..()
|
||||
|
||||
/obj/item/modular_computer/processor/use_power(amount = 0)
|
||||
/obj/item/modular_computer/processor/use_power(amount = 0, check_programs = TRUE)
|
||||
var/obj/machinery/machine_holder = physical
|
||||
if(machine_holder.powered())
|
||||
machine_holder.use_power(amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/modular_computer/processor/relay_qdel()
|
||||
qdel(machinery_computer)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define CPU_INTERACTABLE(user) (cpu && !HAS_TRAIT_FROM(src, TRAIT_MODPC_INTERACTING_WITH_FRAME, REF(user)))
|
||||
|
||||
// Modular Computer - A machinery that is mostly just a host to the Modular Computer item.
|
||||
/obj/machinery/modular_computer
|
||||
name = "modular computer"
|
||||
@@ -9,8 +11,6 @@
|
||||
max_integrity = 300
|
||||
integrity_failure = 0.5
|
||||
|
||||
///The power cell, null by default as we use the APC we're in
|
||||
var/internal_cell = null
|
||||
///A flag that describes this device type
|
||||
var/hardware_flag = PROGRAM_CONSOLE
|
||||
/// Amount of programs that can be ran at once
|
||||
@@ -41,23 +41,42 @@
|
||||
. = ..()
|
||||
cpu = new(src)
|
||||
cpu.screen_on = TRUE
|
||||
cpu.add_shell_component(SHELL_CAPACITY_LARGE, SHELL_FLAG_USB_PORT)
|
||||
update_appearance()
|
||||
register_context()
|
||||
|
||||
/obj/machinery/modular_computer/Destroy()
|
||||
QDEL_NULL(cpu)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/modular_computer/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
if(isnull(held_item))
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Toggle processor interaction"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/modular_computer/attack_hand_secondary(mob/user, list/modifiers)
|
||||
. = ..()
|
||||
if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN)
|
||||
return
|
||||
if(HAS_TRAIT_FROM(src, TRAIT_MODPC_INTERACTING_WITH_FRAME, REF(user)))
|
||||
REMOVE_TRAIT(src, TRAIT_MODPC_INTERACTING_WITH_FRAME, REF(user))
|
||||
balloon_alert(user, "now interacting with computer")
|
||||
else
|
||||
ADD_TRAIT(src, TRAIT_MODPC_INTERACTING_WITH_FRAME, REF(user))
|
||||
balloon_alert(user, "now interacting with frame")
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
/obj/machinery/modular_computer/examine(mob/user)
|
||||
if(cpu)
|
||||
return cpu.examine(user)
|
||||
return ..()
|
||||
. = cpu?.examine(user) || ..()
|
||||
. += span_info("You can toggle interaction between computer and its machinery frame with [EXAMINE_HINT("Right-Click")] while empty-handed.")
|
||||
. += span_info("Currently interacting with [EXAMINE_HINT(HAS_TRAIT_FROM(src, TRAIT_MODPC_INTERACTING_WITH_FRAME, REF(user)) ? "frame" : "computer")].")
|
||||
|
||||
/obj/machinery/modular_computer/attack_ghost(mob/dead/observer/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(cpu)
|
||||
cpu.attack_ghost(user)
|
||||
cpu?.attack_ghost(user)
|
||||
|
||||
/obj/machinery/modular_computer/emag_act(mob/user, obj/item/card/emag/emag_card)
|
||||
if(!cpu)
|
||||
@@ -98,17 +117,14 @@
|
||||
|
||||
/obj/machinery/modular_computer/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!can_interact(user))
|
||||
if(CPU_INTERACTABLE(user) || !can_interact(user))
|
||||
return
|
||||
if(cpu)
|
||||
cpu.AltClick(user)
|
||||
cpu.AltClick(user)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
// On-click handling. Turns on the computer if it's off and opens the GUI.
|
||||
/obj/machinery/modular_computer/interact(mob/user)
|
||||
if(cpu)
|
||||
return cpu.interact(user)
|
||||
return ..()
|
||||
return CPU_INTERACTABLE(user) ? cpu.interact(user) : ..()
|
||||
|
||||
// Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us.
|
||||
/obj/machinery/modular_computer/power_change()
|
||||
@@ -118,30 +134,33 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
///Try to recharge our internal cell if it isn't fully charged.
|
||||
/obj/machinery/modular_computer/process(seconds_per_tick)
|
||||
var/obj/item/stock_parts/cell/cell = get_cell()
|
||||
if(isnull(cell) || cell.percent() >= 100)
|
||||
return
|
||||
var/power_to_draw = idle_power_usage * seconds_per_tick * 0.5
|
||||
if(!use_power_from_net(power_to_draw))
|
||||
return
|
||||
cell.give(power_to_draw)
|
||||
|
||||
/obj/machinery/modular_computer/get_cell()
|
||||
return cpu?.internal_cell
|
||||
|
||||
/obj/machinery/modular_computer/screwdriver_act(mob/user, obj/item/tool)
|
||||
if(cpu)
|
||||
return cpu.screwdriver_act(user, tool)
|
||||
return ..()
|
||||
return CPU_INTERACTABLE(user) ? cpu.screwdriver_act(user, tool) : ..()
|
||||
|
||||
/obj/machinery/modular_computer/wrench_act_secondary(mob/user, obj/item/tool)
|
||||
if(cpu)
|
||||
return cpu.wrench_act_secondary(user, tool)
|
||||
return ..()
|
||||
return CPU_INTERACTABLE(user) ? cpu.wrench_act_secondary(user, tool) : ..()
|
||||
|
||||
/obj/machinery/modular_computer/welder_act(mob/user, obj/item/tool)
|
||||
if(cpu)
|
||||
return cpu.welder_act(user, tool)
|
||||
return ..()
|
||||
return CPU_INTERACTABLE(user) ? cpu.welder_act(user, tool) : ..()
|
||||
|
||||
/obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/living/user)
|
||||
if (cpu && !user.combat_mode && !(obj_flags & NO_DECONSTRUCTION))
|
||||
return cpu.attackby(W, user)
|
||||
return ..()
|
||||
/obj/machinery/modular_computer/attackby(obj/item/weapon, mob/living/user)
|
||||
return (CPU_INTERACTABLE(user) && !user.combat_mode) ? cpu.attackby(weapon, user) : ..()
|
||||
|
||||
/obj/machinery/modular_computer/attacked_by(obj/item/attacking_item, mob/living/user)
|
||||
if (cpu)
|
||||
return cpu.attacked_by(attacking_item, user)
|
||||
return ..()
|
||||
return CPU_INTERACTABLE(user) ? cpu.attacked_by(attacking_item, user) : ..()
|
||||
|
||||
// Stronger explosions cause serious damage to internal components
|
||||
// Minor explosions are mostly mitigitated by casing.
|
||||
@@ -170,6 +189,6 @@
|
||||
// "Burn" damage is equally strong against internal components and exterior casing
|
||||
// "Brute" damage mostly damages the casing.
|
||||
/obj/machinery/modular_computer/bullet_act(obj/projectile/Proj)
|
||||
if(cpu)
|
||||
return cpu.bullet_act(Proj)
|
||||
return ..()
|
||||
return cpu?.bullet_act(Proj) || ..()
|
||||
|
||||
#undef CPU_INTERACTABLE
|
||||
|
||||
Reference in New Issue
Block a user