Fixes some stupid behavior in computer hardware code. (#61350)

This commit is contained in:
LemonInTheDark
2021-09-13 18:30:28 -07:00
committed by GitHub
parent 2635258d0a
commit a3dfa16a98
9 changed files with 76 additions and 74 deletions
@@ -52,7 +52,6 @@
var/comp_light_luminosity = 3 //The brightness of that light
var/comp_light_color //The color of that light
/obj/item/modular_computer/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
@@ -67,13 +66,10 @@
/obj/item/modular_computer/Destroy()
kill_program(forced = TRUE)
STOP_PROCESSING(SSobj, src)
for(var/H in all_components)
var/obj/item/computer_hardware/CH = all_components[H]
if(CH.holder == src)
CH.on_remove(src)
CH.holder = null
all_components.Remove(CH.device_type)
qdel(CH)
for(var/port in all_components)
var/obj/item/computer_hardware/component = all_components[port]
qdel(component)
all_components.Cut() //Die demon die
//Some components will actually try and interact with this, so let's do it later
QDEL_NULL(soundloop)
physical = null
@@ -1,67 +1,71 @@
/obj/item/modular_computer/proc/can_install_component(obj/item/computer_hardware/H, mob/living/user = null)
if(!H.can_install(src, user))
/obj/item/modular_computer/proc/can_install_component(obj/item/computer_hardware/try_install, mob/living/user = null)
if(!try_install.can_install(src, user))
return FALSE
if(H.w_class > max_hardware_size)
if(try_install.w_class > max_hardware_size)
to_chat(user, span_warning("This component is too large for \the [src]!"))
return FALSE
if(H.expansion_hw)
if(try_install.expansion_hw)
if(LAZYLEN(expansion_bays) >= max_bays)
to_chat(user, span_warning("All of the computer's expansion bays are filled."))
return FALSE
if(LAZYACCESS(expansion_bays, H.device_type))
to_chat(user, span_warning("The computer immediately ejects /the [H] and flashes an error: \"Hardware Address Conflict\"."))
if(LAZYACCESS(expansion_bays, try_install.device_type))
to_chat(user, span_warning("The computer immediately ejects /the [try_install] and flashes an error: \"Hardware Address Conflict\"."))
return FALSE
if(all_components[H.device_type])
to_chat(user, span_warning("This computer's hardware slot is already occupied by \the [all_components[H.device_type]]."))
if(all_components[try_install.device_type])
to_chat(user, span_warning("This computer's hardware slot is already occupied by \the [all_components[try_install.device_type]]."))
return FALSE
return TRUE
// Installs component.
/obj/item/modular_computer/proc/install_component(obj/item/computer_hardware/H, mob/living/user = null)
if(!can_install_component(H, user))
/// Installs component.
/obj/item/modular_computer/proc/install_component(obj/item/computer_hardware/install, mob/living/user = null)
if(!can_install_component(install, user))
return FALSE
if(user && !user.transferItemToLoc(H, src))
if(user && !user.transferItemToLoc(install, src))
return FALSE
if(H.expansion_hw)
LAZYSET(expansion_bays, H.device_type, H)
all_components[H.device_type] = H
if(install.expansion_hw)
LAZYSET(expansion_bays, install.device_type, install)
all_components[install.device_type] = install
to_chat(user, span_notice("You install \the [H] into \the [src]."))
H.holder = src
H.forceMove(src)
H.on_install(src, user)
to_chat(user, span_notice("You install \the [install] into \the [src]."))
install.holder = src
install.forceMove(src)
install.on_install(src, user)
// Uninstalls component.
/obj/item/modular_computer/proc/uninstall_component(obj/item/computer_hardware/H, mob/living/user = null)
if(H.holder != src) // Not our component at all.
/// Uninstalls component.
/obj/item/modular_computer/proc/uninstall_component(obj/item/computer_hardware/yeet, mob/living/user = null)
if(yeet.holder != src) // Not our component at all.
return FALSE
if(H.expansion_hw)
LAZYREMOVE(expansion_bays, H.device_type)
all_components.Remove(H.device_type)
to_chat(user, span_notice("You remove \the [yeet] from \the [src]."))
to_chat(user, span_notice("You remove \the [H] from \the [src]."))
H.forceMove(get_turf(src))
H.holder = null
H.on_remove(src, user)
yeet.forceMove(get_turf(src))
forget_component(yeet)
yeet.on_remove(src, user)
if(enabled && !use_power())
shutdown_computer()
update_appearance()
return TRUE
/// This isn't the "uninstall fully" proc, it just makes the computer lose all its references to the component
/obj/item/modular_computer/proc/forget_component(obj/item/computer_hardware/wipe_memory)
if(wipe_memory.holder != src)
return FALSE
if(wipe_memory.expansion_hw)
LAZYREMOVE(expansion_bays, wipe_memory.device_type)
all_components.Remove(wipe_memory.device_type)
wipe_memory.holder = null
// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null
/// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null
/obj/item/modular_computer/proc/find_hardware_by_name(name)
for(var/i in all_components)
var/obj/O = all_components[i]
if(O.name == name)
return O
var/obj/component = all_components[i]
if(component.name == name)
return component
return null
@@ -12,8 +12,8 @@
var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description.
device_type = MC_CPU
/obj/item/computer_hardware/processor_unit/on_remove(obj/item/modular_computer/MC, mob/user)
MC.shutdown_computer()
/obj/item/computer_hardware/processor_unit/on_remove(obj/item/modular_computer/remove_from, mob/user)
remove_from.shutdown_computer()
/obj/item/computer_hardware/processor_unit/small
name = "microprocessor"
@@ -9,29 +9,29 @@
var/obj/item/modular_computer/holder = null
// Computer that holds this hardware, if any.
// If the hardware uses extra power, change this.
/// If the hardware uses extra power, change this.
var/power_usage = 0
// If the hardware is turned off set this to 0.
/// If the hardware is turned off set this to 0.
var/enabled = TRUE
// Prevent disabling for important component, like the CPU.
/// Prevent disabling for important component, like the CPU.
var/critical = FALSE
// Prevents direct installation of removable media.
/// Prevents direct installation of removable media.
var/can_install = TRUE
// Hardware that fits into expansion bays.
/// Hardware that fits into expansion bays.
var/expansion_hw = FALSE
// Whether the hardware is removable or not.
/// Whether the hardware is removable or not.
var/removable = TRUE
// Current damage level
/// Current damage level
var/damage = 0
// Maximal damage level.
// Maximal damage level.
var/max_damage = 100
// "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things
/// "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things
var/damage_malfunction = 20
// "Failure" threshold. When damage exceeds this value the hardware piece will not work at all.
/// "Failure" threshold. When damage exceeds this value the hardware piece will not work at all.
var/damage_failure = 50
// Chance of malfunction when the component is damaged
/// Chance of malfunction when the component is damaged
var/malfunction_probability = 10
// What define is used to qualify this piece of hardware? Important for upgraded versions of the same hardware.
/// What define is used to qualify this piece of hardware? Important for upgraded versions of the same hardware.
var/device_type
/obj/item/computer_hardware/New(obj/L)
@@ -41,7 +41,7 @@
/obj/item/computer_hardware/Destroy()
if(holder)
holder.uninstall_component(src)
holder.forget_component(src)
return ..()
@@ -69,11 +69,11 @@
to_chat(user, "******************************")
return TRUE
// Called on multitool click, prints diagnostic information to the user.
/// Called on multitool click, prints diagnostic information to the user.
/obj/item/computer_hardware/proc/diagnostics(mob/user)
to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]")
// Handles damage checks
/// Handles damage checks
/obj/item/computer_hardware/proc/check_functionality()
if(!enabled) // Disabled.
return FALSE
@@ -96,20 +96,20 @@
else if(damage)
. += span_notice("It seems to be slightly damaged.")
// Component-side compatibility check.
/obj/item/computer_hardware/proc/can_install(obj/item/modular_computer/M, mob/living/user = null)
/// Component-side compatibility check.
/obj/item/computer_hardware/proc/can_install(obj/item/modular_computer/install_into, mob/living/user = null)
return can_install
// Called when component is installed into PC.
/obj/item/computer_hardware/proc/on_install(obj/item/modular_computer/M, mob/living/user = null)
/// Called when component is installed into PC.
/obj/item/computer_hardware/proc/on_install(obj/item/modular_computer/install_into, mob/living/user = null)
return
// Called when component is removed from PC.
/obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/M, mob/living/user)
if(M.physical || !QDELETED(M))
/// Called when component is removed from PC.
/obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/remove_from, mob/living/user)
if(remove_from.physical && !QDELETED(remove_from) && !QDELETED(src))
try_eject(forced = TRUE)
// Called when someone tries to insert something in it - paper in printer, card in card reader, etc.
/// Called when someone tries to insert something in it - paper in printer, card in card reader, etc.
/obj/item/computer_hardware/proc/try_insert(obj/item/I, mob/living/user = null)
return FALSE
@@ -16,7 +16,8 @@
battery = new battery_type(src)
/obj/item/computer_hardware/battery/Destroy()
battery = null
if(battery)
QDEL_NULL(battery)
return ..()
///What happens when the battery is removed (or deleted) from the module, through try_eject() or not.
@@ -28,7 +28,8 @@
return ..()
/obj/item/computer_hardware/card_slot/Destroy()
try_eject(forced = TRUE)
if(stored_card) //If you didn't expect this behavior for some dumb reason, do something different instead of directly destroying the slot
QDEL_NULL(stored_card)
return ..()
/obj/item/computer_hardware/card_slot/GetAccess()
@@ -10,8 +10,8 @@
var/used_capacity = 0
var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY!
/obj/item/computer_hardware/hard_drive/on_remove(obj/item/modular_computer/MC, mob/user)
MC.shutdown_computer()
/obj/item/computer_hardware/hard_drive/on_remove(obj/item/modular_computer/remove_from, mob/user)
remove_from.shutdown_computer()
/obj/item/computer_hardware/hard_drive/proc/install_default_programs()
store_file(new/datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar
@@ -8,7 +8,7 @@
max_capacity = 16
device_type = MC_SDD
/obj/item/computer_hardware/hard_drive/portable/on_remove(obj/item/modular_computer/MC, mob/user)
/obj/item/computer_hardware/hard_drive/portable/on_remove(obj/item/modular_computer/remove_from, mob/user)
return //this is a floppy disk, let's not shut the computer down when it gets pulled out.
/obj/item/computer_hardware/hard_drive/portable/install_default_programs()
@@ -52,8 +52,8 @@
icon_state = "charger_wire"
w_class = WEIGHT_CLASS_NORMAL
/obj/item/computer_hardware/recharger/wired/can_install(obj/item/modular_computer/M, mob/living/user = null)
if(ismachinery(M.physical) && M.physical.anchored)
/obj/item/computer_hardware/recharger/wired/can_install(obj/item/modular_computer/install_into, mob/living/user = null)
if(ismachinery(install_into.physical) && install_into.physical.anchored)
return ..()
to_chat(user, span_warning("\The [src] is incompatible with portable computers!"))
return FALSE