Modular computers now use list of components (#20557)

* Bringing computers to the light side

Bringing computers to the light side

* Lighter and lighter

Lighter and lighter

* Missed some lists

Missed some lists

* Text to defines

Text to defines

* Last commit

Last commit

* How did this even get here

How did this even get here

* Removing bad stuff

Removing bad stuff

* Fixes verb adding and idle check

Fixes verb adding and idle check
This commit is contained in:
Razharas
2016-09-18 01:40:21 +03:00
committed by phil235
parent 6b3e788ee9
commit 186d852bc5
30 changed files with 269 additions and 217 deletions

View File

@@ -22,4 +22,13 @@
#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually.
#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
#define BIOGENERATOR 32 //Uses biomass
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
#define MC_CPU "CPU"
#define MC_HDD "HDD"
#define MC_SDD "SDD"
#define MC_CARD "CARD"
#define MC_NET "NET"
#define MC_PRINT "PRINT"
#define MC_CELL "CELL"
#define MC_CHARGE "CHARGE"

View File

@@ -132,8 +132,9 @@
if(istype(charging, /obj/item/device/modular_computer))
var/obj/item/device/modular_computer/C = charging
if(C.battery_module)
var/obj/item/weapon/computer_hardware/battery/B = C.battery_module
var/obj/item/weapon/computer_hardware/battery/battery_module = C.all_components[MC_CELL]
if(battery_module)
var/obj/item/weapon/computer_hardware/battery/B = battery_module
if(B.battery)
if(B.battery.charge < B.battery.maxcharge)
B.battery.give(B.battery.chargerate * recharge_coeff)

View File

@@ -36,22 +36,12 @@
var/max_damage = 100 // Damage level at which the computer breaks apart.
// Important hardware (must be installed for computer to work)
var/obj/item/weapon/computer_hardware/processor_unit/processor_unit // CPU. Without it the computer won't run. Better CPUs can run more programs at once.
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive // Hard Drive component of this computer. Stores programs and files.
var/obj/item/weapon/computer_hardware/battery/battery_module // Power cell connector. Power cell can be recharged.
// OR
var/obj/item/weapon/computer_hardware/recharger/recharger // Recharger. Can be used to recharge power cell or power the PC without it.
// Optional hardware (improves functionality, but is not critical for computer to work)
var/obj/item/weapon/computer_hardware/network_card/network_card // Network Card component of this computer. Allows connection to NTNet.
var/obj/item/weapon/computer_hardware/card_slot/card_slot // ID Card slot component of this computer.
var/obj/item/weapon/computer_hardware/printer/printer // Printer component of this computer, for your everyday paperwork needs.
var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive // Portable data storage
var/list/all_components = list()
var/list/all_components // List of "connection ports" in this computer and the components with which they are plugged
var/list/idle_threads = list() // Idle programs on background. They still receive process calls but can't be interacted with.
var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with.
var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks.
@@ -63,30 +53,48 @@
physical = src
..()
all_components = list()
idle_threads = list()
/obj/item/device/modular_computer/Destroy()
kill_program(forced = TRUE)
STOP_PROCESSING(SSobj, src)
for(var/H in all_components)
var/obj/item/weapon/computer_hardware/CH = H
var/obj/item/weapon/computer_hardware/CH = all_components[H]
if(CH.holder == src)
CH.holder = null
qdel(CH)
return ..()
/obj/item/device/modular_computer/proc/add_verb(var/path)
switch(path)
if(MC_CARD)
verbs += /obj/item/device/modular_computer/proc/eject_id
if(MC_SDD)
verbs += /obj/item/device/modular_computer/proc/eject_disk
/obj/item/device/modular_computer/proc/remove_verb(path)
switch(path)
if(MC_CARD)
verbs -= /obj/item/device/modular_computer/proc/eject_id
if(MC_SDD)
verbs -= /obj/item/device/modular_computer/proc/eject_disk
// Eject ID card from computer, if it has ID slot with card inside.
/obj/item/device/modular_computer/verb/eject_id()
/obj/item/device/modular_computer/proc/eject_id()
set name = "Eject ID"
set category = "Object"
set src in view(1)
if(issilicon(usr))
return
if (usr.canUseTopic(src))
proc_eject_id(usr)
var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
if(usr.canUseTopic(src))
card_slot.try_eject(, usr)
// Eject ID card from computer, if it has ID slot with card inside.
/obj/item/device/modular_computer/verb/eject_disk()
/obj/item/device/modular_computer/proc/eject_disk()
set name = "Eject Data Disk"
set category = "Object"
set src in view(1)
@@ -94,30 +102,10 @@
if(issilicon(usr))
return
if (usr.canUseTopic(src))
proc_eject_disk(usr)
/obj/item/device/modular_computer/proc/proc_eject_id(mob/user, slot)
if(!user)
user = usr
if(!card_slot)
user << "<span class='warning'>\The [src] does not have an ID card slot!</span>"
return
card_slot.try_eject(slot, user)
/obj/item/device/modular_computer/proc/proc_eject_disk(mob/user)
if(!user)
user = usr
if(!portable_drive)
user << "<span class='warning'>There is no data disk in \the [src]!</span>"
return
var/obj/item/I = portable_drive
if(uninstall_component(portable_drive, user))
I.verb_pickup()
if(usr.canUseTopic(src))
var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
if(uninstall_component(portable_drive, usr))
portable_drive.verb_pickup()
/obj/item/device/modular_computer/AltClick(mob/user)
..()
@@ -125,19 +113,24 @@
return
if(user.canUseTopic(src))
var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive = all_components[MC_SDD]
if(portable_drive)
proc_eject_disk(user)
if(uninstall_component(portable_drive, user))
portable_drive.verb_pickup()
else if(card_slot)
proc_eject_id(user)
card_slot.try_eject(, user)
// Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs.
/obj/item/device/modular_computer/GetAccess()
var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
if(card_slot)
return card_slot.GetAccess()
return ..()
/obj/item/device/modular_computer/GetID()
var/obj/item/weapon/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
if(card_slot)
return card_slot.GetID()
return ..()
@@ -208,10 +201,11 @@
return
// If we have a recharger, enable it automatically. Lets computer without a battery work.
var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger)
recharger.enabled = 1
if(processor_unit && use_power()) // use_power() checks if the PC is powered
if(all_components[MC_CPU] && use_power()) // use_power() checks if the PC is powered
if(issynth)
user << "<span class='notice'>You send an activation signal to \the [src], turning it on.</span>"
else
@@ -265,6 +259,9 @@
/obj/item/device/modular_computer/proc/get_header_data()
var/list/data = list()
var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(battery_module && battery_module.battery)
switch(battery_module.battery.percent())
if(80 to 200) // 100 should be maximal but just in case..
@@ -328,6 +325,7 @@
// Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on)
/obj/item/device/modular_computer/proc/get_ntnet_status(specific_action = 0)
var/obj/item/weapon/computer_hardware/network_card/network_card = all_components[MC_NET]
if(network_card)
return network_card.get_signal(specific_action)
else
@@ -336,6 +334,7 @@
/obj/item/device/modular_computer/proc/add_log(text)
if(!get_ntnet_status())
return FALSE
var/obj/item/weapon/computer_hardware/network_card/network_card = all_components[MC_NET]
return ntnet_global.add_log(text, network_card)
/obj/item/device/modular_computer/proc/shutdown_computer(loud = 1)
@@ -352,7 +351,7 @@
/obj/item/device/modular_computer/attackby(obj/item/weapon/W as obj, mob/user as mob)
// Insert items into the components
for(var/h in all_components)
var/obj/item/weapon/computer_hardware/H = h
var/obj/item/weapon/computer_hardware/H = all_components[h]
if(H.try_insert(W, user))
return

View File

@@ -6,32 +6,8 @@
user << "<span class='warning'>This component is too large for \the [src]!</span>"
return FALSE
if(istype(H, /obj/item/weapon/computer_hardware/hard_drive/portable) && portable_drive)
user << "<span class='warning'>This computer's FDD is already occupied by \the [portable_drive].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit) && processor_unit)
user << "<span class='warning'>This computer's CPU slot is already occupied by \the [processor_unit].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/hard_drive) && hard_drive)
user << "<span class='warning'>This computer's data port is already occupied by \the [hard_drive].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/battery) && battery_module)
user << "<span class='warning'>This computer's power converter slot is already occupied by \the [battery_module].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/recharger) && recharger)
user << "<span class='warning'>This computer's recharger slot is already occupied by \the [recharger].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/card_slot) && card_slot)
user << "<span class='warning'>This computer's card reader slot is already occupied by \the [card_slot].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/network_card) && network_card)
user << "<span class='warning'>This computer's network card is already occupied by \the [network_card].</span>"
return FALSE
else if(istype(H, /obj/item/weapon/computer_hardware/printer) && printer)
user << "<span class='warning'>This computer's printer slot is already occupied by \the [printer].</span>"
if(all_components[H.device_type])
user << "<span class='warning'>This computer's hardware slot is already occupied by \the [all_components[H.device_type]].</span>"
return FALSE
return TRUE
@@ -44,32 +20,12 @@
if(user && !user.unEquip(H))
return FALSE
if(istype(H, /obj/item/weapon/computer_hardware/hard_drive/portable))
portable_drive = H
else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit))
processor_unit = H
else if(istype(H, /obj/item/weapon/computer_hardware/hard_drive))
hard_drive = H
else if(istype(H, /obj/item/weapon/computer_hardware/battery))
battery_module = H
else if(istype(H, /obj/item/weapon/computer_hardware/recharger))
recharger = H
else if(istype(H, /obj/item/weapon/computer_hardware/card_slot))
card_slot = H
else if(istype(H, /obj/item/weapon/computer_hardware/network_card))
network_card = H
else if(istype(H, /obj/item/weapon/computer_hardware/printer))
printer = H
all_components[H.device_type] = H
user << "<span class='notice'>You install \the [H] into \the [src].</span>"
H.forceMove(src)
H.holder = src
all_components |= H
H.on_install(src, user)
return TRUE
// Uninstalls component.
@@ -77,41 +33,22 @@
if(H.holder != src) // Not our component at all.
return FALSE
if(processor_unit == H)
processor_unit = null
if(hard_drive == H)
hard_drive = null
if(battery_module == H)
battery_module = null
if(recharger == H)
recharger = null
if(card_slot == H)
card_slot = null
if(network_card == H)
network_card = null
if(printer == H)
printer = null
if(portable_drive == H)
portable_drive = null
all_components.Remove(H.device_type)
user << "<span class='notice'>You remove \the [H] from \the [src].</span>"
H.forceMove(get_turf(src))
H.holder = null
all_components -= H
H.on_remove(src, user)
if(enabled && (!processor_unit || !hard_drive || !use_power()))
if(enabled && !use_power())
shutdown_computer()
update_icon()
return TRUE
// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null
/obj/item/device/modular_computer/proc/find_hardware_by_name(name)
for(var/i in all_components)
var/obj/O = i
var/obj/O = all_components[i]
if(O.name == name)
return O
return null

View File

@@ -3,10 +3,14 @@
if(check_power_override())
return TRUE
var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger && recharger.check_functionality())
if(recharger.use_power(amount))
return TRUE
var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
if(battery_module && battery_module.battery && battery_module.battery.charge)
var/obj/item/weapon/stock_parts/cell/cell = battery_module.battery
if(cell.use(amount * CELLRATE))
@@ -17,6 +21,7 @@
return FALSE
/obj/item/device/modular_computer/proc/give_power(amount)
var/obj/item/weapon/computer_hardware/battery/battery_module = all_components[MC_CELL]
if(battery_module && battery_module.battery)
return battery_module.battery.give(amount)
return 0
@@ -34,6 +39,7 @@
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
/obj/item/device/modular_computer/proc/handle_power()
var/obj/item/weapon/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger)
recharger.process()

View File

@@ -24,6 +24,7 @@
// We are still here, that means there is no program loaded. Load the BIOS/ROM/OS/whatever you want to call it.
// This screen simply lists available programs and user may select them.
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len)
physical.visible_message("<span class='danger'>\The [src] beeps three times, it's screen displaying \"DISK ERROR\" warning.</span>")
return // No HDD, No HDD files list or no stored files. Something is very broken.
@@ -41,6 +42,7 @@
/obj/item/device/modular_computer/ui_data(mob/user)
var/list/data = get_header_data()
data["programs"] = list()
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
for(var/datum/computer_file/program/P in hard_drive.stored_files)
var/running = 0
if(P in idle_threads)
@@ -55,6 +57,7 @@
/obj/item/device/modular_computer/ui_act(action, params)
if(..())
return
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
switch(action)
if("PC_exit")
kill_program()
@@ -64,7 +67,7 @@
return 1
if("PC_minimize")
var/mob/user = usr
if(!active_program || !processor_unit)
if(!active_program || !all_components[MC_CPU])
return
idle_threads.Add(active_program)
@@ -112,7 +115,9 @@
update_icon()
return
if(idle_threads.len >= processor_unit.max_idle_programs+1)
var/obj/item/weapon/computer_hardware/processor_unit/PU = all_components[MC_CPU]
if(idle_threads.len > PU.max_idle_programs)
user << "<span class='danger'>\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error.</span>"
return

View File

@@ -23,6 +23,8 @@
CRASH("Inapropriate type passed to obj/item/device/modular_computer/processor/New()! Aborting.")
return
// Obtain reference to machinery computer
all_components = list()
idle_threads = list()
machinery_computer = comp
machinery_computer.cpu = src
hardware_flag = machinery_computer.hardware_flag
@@ -53,3 +55,17 @@
..()
machinery_computer.update_icon()
return
/obj/item/device/modular_computer/processor/add_verb(path)
switch(path)
if(MC_CARD)
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_id
if(MC_SDD)
machinery_computer.verbs += /obj/machinery/modular_computer/proc/eject_disk
/obj/item/device/modular_computer/processor/remove_verb(path)
switch(path)
if(MC_CARD)
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_id
if(MC_SDD)
machinery_computer.verbs -= /obj/machinery/modular_computer/proc/eject_disk

View File

@@ -1,4 +1,4 @@
/obj/item/device/modular_computer/tablet
/obj/item/device/modular_computer/tablet //Its called tablet for theme of 90ies but actually its a "big smartphone" sized
name = "tablet computer"
icon = 'icons/obj/modular_tablet.dmi'
icon_state = "tablet"
@@ -9,3 +9,4 @@
max_hardware_size = 1
w_class = 2
steel_sheet_cost = 1
slot_flags = SLOT_ID | SLOT_BELT

View File

@@ -30,8 +30,9 @@
desc = "A stationary computer. This one comes preloaded with engineering programs."
/obj/machinery/modular_computer/console/preset/engineering/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/power_monitor())
cpu.hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/power_monitor())
hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
// ===== RESEARCH CONSOLE =====
/obj/machinery/modular_computer/console/preset/research
@@ -39,9 +40,10 @@
desc = "A stationary computer. This one comes preloaded with research programs."
/obj/machinery/modular_computer/console/preset/research/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer())
cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
hard_drive.store_file(new/datum/computer_file/program/nttransfer())
hard_drive.store_file(new/datum/computer_file/program/chatclient())
// ===== COMMAND CONSOLE =====
@@ -52,8 +54,9 @@
_has_printer = 1
/obj/machinery/modular_computer/console/preset/command/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod())
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/chatclient())
hard_drive.store_file(new/datum/computer_file/program/card_mod())
// ===== CIVILIAN CONSOLE =====
/obj/machinery/modular_computer/console/preset/civilian
@@ -61,6 +64,6 @@
desc = "A stationary computer. This one comes preloaded with generic programs."
/obj/machinery/modular_computer/console/preset/civilian/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer())
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
hard_drive.store_file(new/datum/computer_file/program/chatclient())
hard_drive.store_file(new/datum/computer_file/program/nttransfer())

View File

@@ -74,7 +74,7 @@ var/list/global_modular_computers = list()
add_overlay("broken")
// Eject ID card from computer, if it has ID slot with card inside.
/obj/machinery/modular_computer/verb/eject_id()
/obj/machinery/modular_computer/proc/eject_id()
set name = "Eject ID"
set category = "Object"
set src in view(1)
@@ -83,7 +83,7 @@ var/list/global_modular_computers = list()
cpu.eject_id()
// Eject ID card from computer, if it has ID slot with card inside.
/obj/machinery/modular_computer/verb/eject_disk()
/obj/machinery/modular_computer/proc/eject_disk()
set name = "Eject Data Disk"
set category = "Object"
set src in view(1)
@@ -109,8 +109,9 @@ var/list/global_modular_computers = list()
// Used in following function to reduce copypaste
/obj/machinery/modular_computer/proc/power_failure(malfunction = 0)
var/obj/item/weapon/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL]
if(cpu && cpu.enabled) // Shut down the computer
visible_message("<span class='danger'>\The [src]'s screen flickers [cpu.battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.</span>")
visible_message("<span class='danger'>\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.</span>")
if(cpu)
cpu.shutdown_computer(0)
stat |= NOPOWER
@@ -119,7 +120,7 @@ var/list/global_modular_computers = list()
// 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()
if(cpu && cpu.use_power()) // If "CPU" still has a power source, PC wouldn't go offline.
if(cpu && cpu.use_power()) // If MC_CPU still has a power source, PC wouldn't go offline.
stat &= ~NOPOWER
update_icon()
return

View File

@@ -22,29 +22,35 @@
/obj/machinery/modular_computer/console/buildable/New()
..()
// User-built consoles start as empty frames.
qdel(cpu.recharger)
qdel(cpu.network_card)
qdel(cpu.hard_drive)
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/hard_drive/network_card = cpu.all_components[MC_NET]
var/obj/item/weapon/computer_hardware/hard_drive/recharger = cpu.all_components[MC_CHARGE]
qdel(recharger)
qdel(network_card)
qdel(hard_drive)
/obj/machinery/modular_computer/console/New()
..()
if(cpu.battery_module)
qdel(cpu.battery_module)
var/obj/item/weapon/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL]
if(battery_module)
qdel(battery_module)
cpu.install_component(new /obj/item/weapon/computer_hardware/network_card/wired)
var/obj/item/weapon/computer_hardware/network_card/wired/network_card = new()
cpu.install_component(network_card)
cpu.install_component(new /obj/item/weapon/computer_hardware/recharger/APC)
cpu.install_component(new /obj/item/weapon/computer_hardware/hard_drive/super) // Consoles generally have better HDDs due to lower space limitations
var/area/A = get_area(src)
// Attempts to set this console's tag according to our area. Since some areas have stuff like "XX - YY" in their names we try to remove that too.
if(A && console_department)
cpu.network_card.identification_string = replacetext(replacetext(replacetext("[A.name] [console_department] Console", " ", "_"), "-", ""), "__", "_") // Replace spaces with "_"
network_card.identification_string = replacetext(replacetext(replacetext("[A.name] [console_department] Console", " ", "_"), "-", ""), "__", "_") // Replace spaces with "_"
else if(A)
cpu.network_card.identification_string = replacetext(replacetext(replacetext("[A.name] Console", " ", "_"), "-", ""), "__", "_")
network_card.identification_string = replacetext(replacetext(replacetext("[A.name] Console", " ", "_"), "-", ""), "__", "_")
else if(console_department)
cpu.network_card.identification_string = replacetext(replacetext(replacetext("[console_department] Console", " ", "_"), "-", ""), "__", "_")
network_card.identification_string = replacetext(replacetext(replacetext("[console_department] Console", " ", "_"), "-", ""), "__", "_")
else
cpu.network_card.identification_string = "Unknown Console"
network_card.identification_string = "Unknown Console"
if(cpu)
cpu.screen_on = 1
update_icon()

View File

@@ -87,6 +87,11 @@
return 1
if(ishuman(user))
var/obj/item/weapon/card/id/D
var/obj/item/weapon/computer_hardware/card_slot/card_slot
if(computer && card_slot)
card_slot = computer.all_components[MC_CARD]
D = card_slot.GetID()
var/mob/living/carbon/human/h = user
var/obj/item/weapon/card/id/I = h.get_idcard()
var/obj/item/weapon/card/id/C = h.get_active_held_item()
@@ -95,7 +100,7 @@
if(!(C && istype(C)))
C = null
if(!I && !C)
if(!I && !C && !D)
if(loud)
user << "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>"
return 0
@@ -106,6 +111,9 @@
else if(C)
if(access_to_check in C.GetAccess())
return 1
else if(D)
if(access_to_check in D.GetAccess())
return 1
if(loud)
user << "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>"
return 0
@@ -162,7 +170,7 @@
return 1
if("PC_minimize")
var/mob/user = usr
if(!computer.active_program || !computer.processor_unit)
if(!computer.active_program || !computer.all_components[MC_CPU])
return
computer.idle_threads.Add(computer.active_program)

View File

@@ -69,7 +69,8 @@
executed = 1
target.dos_sources.Add(src)
if(ntnet_global.intrusion_detection_enabled)
ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [computer.network_card.get_network_tag()]")
var/obj/item/weapon/computer_hardware/network_card/network_card = computer.all_components[MC_NET]
ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [network_card.get_network_tag()]")
ntnet_global.intrusion_detection_alarm = 1
return 1

View File

@@ -19,16 +19,19 @@
computer.visible_message("<span class='notice'>\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.</span>")
computer.enabled = 0
computer.update_icon()
qdel(computer.hard_drive)
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/battery/battery_module = computer.all_components[MC_CELL]
var/obj/item/weapon/computer_hardware/recharger/recharger = computer.all_components[MC_CHARGE]
qdel(hard_drive)
computer.take_damage(25, 10, 1, 1)
if(computer.battery_module && prob(25))
qdel(computer.battery_module)
if(battery_module && prob(25))
qdel(battery_module)
computer.visible_message("<span class='notice'>\The [computer]'s battery explodes in rain of sparks.</span>")
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
spark_system.start()
if(computer.recharger && prob(50))
qdel(computer.recharger)
if(recharger && prob(50))
qdel(recharger)
computer.visible_message("<span class='notice'>\The [computer]'s recharger explodes in rain of sparks.</span>")
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
spark_system.start()

View File

@@ -88,7 +88,8 @@
/datum/computer_file/program/card_mod/proc/format_jobs(list/jobs)
var/obj/item/weapon/card/id/id_card = computer.card_slot.stored_card
var/obj/item/weapon/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
var/obj/item/weapon/card/id/id_card = card_slot.stored_card
var/list/formatted = list()
for(var/job in jobs)
formatted.Add(list(list(
@@ -102,11 +103,19 @@
if(..())
return 1
var/obj/item/weapon/computer_hardware/card_slot/card_slot
var/obj/item/weapon/computer_hardware/printer/printer
if(computer)
card_slot = computer.all_components[MC_CARD]
printer = computer.all_components[MC_PRINT]
if(!card_slot)
return
var/obj/item/weapon/card/id/user_id_card = null
var/mob/user = usr
var/obj/item/weapon/card/id/id_card = computer.card_slot.stored_card
var/obj/item/weapon/card/id/auth_card = computer.card_slot.stored_card2
var/obj/item/weapon/card/id/id_card = card_slot.stored_card
var/obj/item/weapon/card/id/auth_card = card_slot.stored_card2
if(auth_card)
user_id_card = auth_card
@@ -129,7 +138,7 @@
else
show_assignments = 1
if("PRG_print")
if(computer && computer.printer) //This option should never be called if there is no printer
if(computer && printer) //This option should never be called if there is no printer
if(mod_mode)
if(authorized())
var/contents = {"<h4>Access Report</h4>
@@ -145,7 +154,7 @@
if(A in known_access_rights)
contents += " [get_access_desc(A)]"
if(!computer.printer.print_text(contents,"access report"))
if(!printer.print_text(contents,"access report"))
usr << "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>"
return
else
@@ -155,26 +164,26 @@
<br>
[data_core ? data_core.get_manifest(0) : ""]
"}
if(!computer.printer.print_text(contents,text("crew manifest ([])", worldtime2text())))
if(!printer.print_text(contents,text("crew manifest ([])", worldtime2text())))
usr << "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>"
return
else
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
if("PRG_eject")
if(computer && computer.card_slot)
if(computer && card_slot)
var/select = params["target"]
switch(select)
if("id")
if(id_card)
data_core.manifest_modify(id_card.registered_name, id_card.assignment)
computer.proc_eject_id(user, 1)
card_slot.try_eject(, user)
else
var/obj/item/I = usr.get_active_held_item()
if (istype(I, /obj/item/weapon/card/id))
if(!usr.drop_item())
return
I.forceMove(computer)
computer.card_slot.stored_card = I
card_slot.stored_card = I
if("auth")
if(auth_card)
if(id_card)
@@ -183,14 +192,14 @@
region_access = null
authenticated = 0
minor = 0
computer.proc_eject_id(user, 2)
card_slot.try_eject(, user)
else
var/obj/item/I = usr.get_active_held_item()
if (istype(I, /obj/item/weapon/card/id))
if(!usr.drop_item())
return
I.forceMove(computer)
computer.card_slot.stored_card2 = I
card_slot.stored_card2 = I
if("PRG_terminate")
if(computer && ((id_card.assignment in head_subordinates) || id_card.assignment == "Assistant"))
id_card.assignment = "Unassigned"
@@ -292,13 +301,21 @@
var/list/data = get_header_data()
var/obj/item/weapon/computer_hardware/card_slot/card_slot
var/obj/item/weapon/computer_hardware/printer/printer
if(computer)
card_slot = computer.all_components[MC_CARD]
printer = computer.all_components[MC_PRINT]
data["mmode"] = mod_mode
var/authed = 0
if(computer && computer.card_slot)
var/obj/item/weapon/card/id/auth_card = computer.card_slot.stored_card2
data["auth_name"] = auth_card ? strip_html_simple(auth_card.name) : "-----"
authed = authorized()
if(computer)
if(card_slot)
var/obj/item/weapon/card/id/auth_card = card_slot.stored_card2
data["auth_name"] = auth_card ? strip_html_simple(auth_card.name) : "-----"
authed = authorized()
if(mod_mode == 2)
@@ -336,9 +353,9 @@
data["manifest"] = crew
data["assignments"] = show_assignments
if(computer)
data["have_id_slot"] = !!computer.card_slot
data["have_printer"] = !!computer.printer
if(!computer.card_slot && mod_mode == 1)
data["have_id_slot"] = !!card_slot
data["have_printer"] = !!printer
if(!card_slot && mod_mode == 1)
mod_mode = 0 //We can't modify IDs when there is no card reader
else
data["have_id_slot"] = 0
@@ -350,10 +367,9 @@
data["authenticated"] = authed
if(mod_mode == 1)
if(computer && computer.card_slot)
var/obj/item/weapon/card/id/id_card = computer.card_slot.stored_card
if(mod_mode == 1 && computer)
if(card_slot)
var/obj/item/weapon/card/id/id_card = card_slot.stored_card
data["has_id"] = !!id_card
data["id_rank"] = id_card && id_card.assignment ? html_encode(id_card.assignment) : "Unassigned"
@@ -370,8 +386,8 @@
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs())
if(computer.card_slot.stored_card)
var/obj/item/weapon/card/id/id_card = computer.card_slot.stored_card
if(card_slot.stored_card)
var/obj/item/weapon/card/id/id_card = card_slot.stored_card
if(is_centcom)
var/list/all_centcom_access = list()
for(var/access in get_all_centcom_access())
@@ -431,9 +447,10 @@
/datum/computer_file/program/card_mod/proc/authorized()
if(!authenticated)
if(computer && computer.card_slot)
var/obj/item/weapon/card/id/auth_card = computer.card_slot.stored_card2
if(!authenticated && computer)
var/obj/item/weapon/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
if(card_slot)
var/obj/item/weapon/card/id/auth_card = card_slot.stored_card2
if(auth_card)
region_access = list()
if(transfer_access in auth_card.GetAccess())

View File

@@ -29,6 +29,8 @@
/datum/computer_file/program/computerconfig/ui_data(mob/user)
movable = computer
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = movable.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/battery/battery_module = movable.all_components[MC_CELL]
if(!istype(movable))
movable = null
@@ -38,20 +40,20 @@
var/list/data = get_header_data()
data["disk_size"] = movable.hard_drive.max_capacity
data["disk_used"] = movable.hard_drive.used_capacity
data["disk_size"] = hard_drive.max_capacity
data["disk_used"] = hard_drive.used_capacity
data["power_usage"] = movable.last_power_usage
data["battery_exists"] = movable.battery_module ? 1 : 0
if(movable.battery_module && movable.battery_module.battery)
data["battery_rating"] = movable.battery_module.battery.maxcharge
data["battery_percent"] = round(movable.battery_module.battery.percent())
data["battery_exists"] = battery_module ? 1 : 0
if(battery_module && battery_module.battery)
data["battery_rating"] = battery_module.battery.maxcharge
data["battery_percent"] = round(battery_module.battery.percent())
if(movable.battery_module && movable.battery_module.battery)
data["battery"] = list("max" = movable.battery_module.battery.maxcharge, "charge" = round(movable.battery_module.battery.charge))
if(battery_module && battery_module.battery)
data["battery"] = list("max" = battery_module.battery.maxcharge, "charge" = round(battery_module.battery.charge))
var/list/all_entries[0]
for(var/I in movable.all_components)
var/obj/item/weapon/computer_hardware/H = I
var/obj/item/weapon/computer_hardware/H = movable.all_components[I]
all_entries.Add(list(list(
"name" = H.name,
"desc" = H.desc,

View File

@@ -14,8 +14,9 @@
if(..())
return 1
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.portable_drive
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/hard_drive/RHDD = computer.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/printer/printer = computer.all_components[MC_PRINT]
switch(action)
if("PRG_openfile")
@@ -106,10 +107,10 @@
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
if(!computer.printer)
if(!printer)
error = "Missing Hardware: Your computer does not have required hardware to complete this operation."
return 1
if(!computer.printer.print_text(parse_tags(F.stored_data)))
if(!printer.print_text(parse_tags(F.stored_data)))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return 1
if("PRG_copytousb")
@@ -185,17 +186,16 @@
/datum/computer_file/program/filemanager/ui_data(mob/user)
var/list/data = get_header_data()
var/obj/item/weapon/computer_hardware/hard_drive/HDD
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD
var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD]
var/obj/item/weapon/computer_hardware/hard_drive/portable/RHDD = computer.all_components[MC_SDD]
if(error)
data["error"] = error
if(open_file)
var/datum/computer_file/data/file
if(!computer || !computer.hard_drive)
if(!computer || !HDD)
data["error"] = "I/O ERROR: Unable to access hard drive."
else
HDD = computer.hard_drive
file = HDD.find_file_by_name(open_file)
if(!istype(file))
data["error"] = "I/O ERROR: Unable to open file."
@@ -203,11 +203,9 @@
data["filedata"] = parse_tags(file.stored_data)
data["filename"] = "[file.filename].[file.filetype]"
else
if(!computer || !computer.hard_drive)
if(!computer || !HDD)
data["error"] = "I/O ERROR: Unable to access hard drive."
else
HDD = computer.hard_drive
RHDD = computer.portable_drive
var/list/files[0]
for(var/datum/computer_file/F in HDD.stored_files)
files.Add(list(list(

View File

@@ -30,7 +30,9 @@
if(PRG.available_on_syndinet && !computer.emagged)
return 0
if(!computer || !computer.hard_drive || !computer.hard_drive.can_store_file(PRG))
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
if(!computer || !hard_drive || !hard_drive.can_store_file(PRG))
return 0
ui_header = "downloader_running.gif"
@@ -59,7 +61,8 @@
if(!downloaded_file)
return
generate_network_log("Completed download of file [hacked_download ? "**ENCRYPTED**" : "[downloaded_file.filename].[downloaded_file.filetype]"].")
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(downloaded_file))
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
if(!computer || !hard_drive || !hard_drive.store_file(downloaded_file))
// The download failed
downloaderror = "I/O ERROR - Unable to save file. Check whether you have enough free space on your hard drive and whether your hard drive is properly connected. If the issue persists contact your system administrator for assistance."
downloaded_file = null
@@ -129,8 +132,9 @@
data["downloadspeed"] = download_netspeed
data["downloadcompletion"] = round(download_completion, 0.1)
else // No download running, pick file.
data["disk_size"] = my_computer.hard_drive.max_capacity
data["disk_used"] = my_computer.hard_drive.used_capacity
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = my_computer.all_components[MC_HDD]
data["disk_size"] = hard_drive.max_capacity
data["disk_used"] = hard_drive.used_capacity
var/list/all_entries[0]
for(var/A in ntnet_global.available_station_software)
var/datum/computer_file/program/P = A

View File

@@ -119,12 +119,13 @@
logfile.stored_data += "[logstring]\[BR\]"
logfile.stored_data += "\[b\]Logfile dump completed.\[/b\]"
logfile.calculate_size()
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(logfile))
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
if(!computer || !hard_drive || !hard_drive.store_file(logfile))
if(!computer)
// This program shouldn't even be runnable without computer.
CRASH("Var computer is null!")
return 1
if(!computer.hard_drive)
if(!hard_drive)
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")
else // In 99.9% cases this will mean our HDD is full
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")

View File

@@ -66,7 +66,8 @@ var/global/nttransfer_uid = 0
// Finishes download and attempts to store the file on HDD
/datum/computer_file/program/nttransfer/proc/finish_download()
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(downloaded_file))
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
if(!computer || !hard_drive || !hard_drive.store_file(downloaded_file))
error = "I/O Error: Unable to save file. Check your hard drive and try again."
finalize_download()
@@ -136,7 +137,8 @@ var/global/nttransfer_uid = 0
server_password = pass
return 1
if("PRG_uploadfile")
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
for(var/datum/computer_file/F in hard_drive.stored_files)
if("[F.uid]" == params["id"])
if(F.unsendable)
error = "I/O Error: File locked."
@@ -174,7 +176,8 @@ var/global/nttransfer_uid = 0
data["upload_filename"] = "[provided_file.filename].[provided_file.filetype]"
else if (upload_menu)
var/list/all_files[0]
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
var/obj/item/weapon/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
for(var/datum/computer_file/F in hard_drive.stored_files)
all_files.Add(list(list(
"uid" = F.uid,
"filename" = "[F.filename].[F.filetype]",

View File

@@ -11,6 +11,10 @@
malfunction_probability = 1
origin_tech = "programming=3;engineering=2"
var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description.
device_type = MC_CPU
/obj/item/weapon/computer_hardware/processor_unit/on_remove(obj/item/device/modular_computer/MC, mob/user)
MC.shutdown_computer()
/obj/item/weapon/computer_hardware/processor_unit/small
name = "microprocessor"

View File

@@ -18,6 +18,7 @@
var/damage_malfunction = 20 // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things
var/damage_failure = 50 // "Failure" threshold. When damage exceeds this value the hardware piece will not work at all.
var/malfunction_probability = 10// Chance of malfunction when the component is damaged
var/device_type
/obj/item/weapon/computer_hardware/New(var/obj/L)
..()

View File

@@ -6,6 +6,7 @@
malfunction_probability = 1
origin_tech = "powerstorage=1;engineering=1"
var/obj/item/weapon/stock_parts/cell/battery = null
device_type = MC_CELL
/obj/item/weapon/computer_hardware/battery/New(loc, battery_type = null)
if(battery_type)

View File

@@ -5,6 +5,7 @@
icon_state = "card_mini"
w_class = 1
origin_tech = "programming=2"
device_type = MC_CARD
var/obj/item/weapon/card/id/stored_card = null
var/obj/item/weapon/card/id/stored_card2 = null
@@ -29,6 +30,12 @@
return stored_card2
return ..()
/obj/item/weapon/computer_hardware/card_slot/on_install(obj/item/device/modular_computer/M, mob/living/user = null)
M.add_verb(device_type)
/obj/item/weapon/computer_hardware/card_slot/on_remove(obj/item/device/modular_computer/M, mob/living/user = null)
M.remove_verb(device_type)
/obj/item/weapon/computer_hardware/card_slot/try_insert(obj/item/I, mob/living/user = null)
if(!holder)
return FALSE

View File

@@ -6,10 +6,14 @@
critical = 1
w_class = 1
origin_tech = "programming=1;engineering=1"
device_type = MC_HDD
var/max_capacity = 128
var/used_capacity = 0
var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY!
/obj/item/weapon/computer_hardware/hard_drive/on_remove(obj/item/device/modular_computer/MC, mob/user)
MC.shutdown_computer()
/obj/item/weapon/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
store_file(new/datum/computer_file/program/ntnetdownload(src)) // NTNet Downloader Utility, allows users to download more software from NTNet repository

View File

@@ -11,6 +11,7 @@ var/global/ntnet_card_uid = 1
var/long_range = 0
var/ethernet = 0 // Hard-wired, therefore always on, ignores NTNet wireless checks.
malfunction_probability = 1
device_type = MC_NET
/obj/item/weapon/computer_hardware/network_card/diagnostics(var/mob/user)
..()

View File

@@ -7,6 +7,14 @@
critical = 0
max_capacity = 16
origin_tech = "programming=1"
device_type = MC_SDD
/obj/item/weapon/computer_hardware/hard_drive/portable/on_install(obj/item/device/modular_computer/M, mob/living/user = null)
M.add_verb(device_type)
/obj/item/weapon/computer_hardware/hard_drive/portable/on_remove(obj/item/device/modular_computer/M, mob/living/user = null)
..()
M.remove_verb(device_type)
/obj/item/weapon/computer_hardware/hard_drive/portable/install_default_programs()
return // Empty by default

View File

@@ -5,6 +5,7 @@
origin_tech = "programming=2;engineering=2"
icon_state = "printer"
w_class = 3
device_type = MC_PRINT
var/stored_paper = 20
var/max_paper = 30

View File

@@ -2,6 +2,7 @@
critical = 1
enabled = 1
var/charge_rate = 100
device_type = MC_CHARGE
/obj/item/weapon/computer_hardware/recharger/proc/use_power(amount, charging=0)
if(charging)
@@ -10,10 +11,11 @@
/obj/item/weapon/computer_hardware/recharger/process()
..()
if(!holder || !holder.battery_module || !holder.battery_module.battery)
var/obj/item/weapon/computer_hardware/battery/battery_module = holder.all_components[MC_CELL]
if(!holder || !battery_module || !battery_module.battery)
return
var/obj/item/weapon/stock_parts/cell/cell = holder.battery_module.battery
var/obj/item/weapon/stock_parts/cell/cell = battery_module.battery
if(cell.charge >= cell.maxcharge)
return

View File

@@ -54,6 +54,7 @@
fabricated_laptop = new /obj/item/device/modular_computer/laptop/buildable(src)
fabricated_laptop.install_component(new /obj/item/weapon/computer_hardware/battery)
total_price = 99
var/obj/item/weapon/computer_hardware/battery/battery_module = fabricated_laptop.all_components[MC_CELL]
switch(dev_cpu)
if(1)
if(fabricate)
@@ -65,14 +66,14 @@
switch(dev_battery)
if(1) // Basic(750C)
if(fabricate)
fabricated_laptop.battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer)
battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer)
if(2) // Upgraded(1100C)
if(fabricate)
fabricated_laptop.battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/advanced)
battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/advanced)
total_price += 199
if(3) // Advanced(1500C)
if(fabricate)
fabricated_laptop.battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/super)
battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/super)
total_price += 499
switch(dev_disk)
if(1) // Basic(128GQ)
@@ -115,17 +116,18 @@
fabricated_tablet.install_component(new /obj/item/weapon/computer_hardware/battery)
fabricated_tablet.install_component(new /obj/item/weapon/computer_hardware/processor_unit/small)
total_price = 199
var/obj/item/weapon/computer_hardware/battery/battery_module = fabricated_tablet.all_components[MC_CELL]
switch(dev_battery)
if(1) // Basic(300C)
if(fabricate)
fabricated_tablet.battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/nano)
battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/nano)
if(2) // Upgraded(500C)
if(fabricate)
fabricated_tablet.battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/micro)
battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer/micro)
total_price += 199
if(3) // Advanced(750C)
if(fabricate)
fabricated_tablet.battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer)
battery_module.try_insert(new /obj/item/weapon/stock_parts/cell/computer)
total_price += 499
switch(dev_disk)
if(1) // Basic(32GQ)