mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-18 19:39:42 +01:00
Initial (buggy) implementation
- Implements modular computers, starting with single program (power monitoring console) - Implements most hardware. Some is still TBD, but the important stuff is in place - Implements file-based system. Currently two file types exist, programs, which have NanoUI/Topic() interaction with user and data files, which may be used to store string of data.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Program-based computers (similar to computer3 project, which this system replaces. It may, in future, be extended to other devices)
|
||||
|
||||
|
||||
1. Basic information
|
||||
Program based computers will allow you to do multiple things from single computer. Each computer will have programs, with more being downloadable from NTNet (stationwide wireless network)
|
||||
if user has apropriate ID card access. It will be possible to hack the computer by using an emag on it - the emag will have to be completely new and will be consumed on use, but it will
|
||||
lift ALL locks on ALL installed programs, and allow download of programs even if your ID doesn't have access to them. Computers will have hard drives that can store files.
|
||||
Files can be programs (datum/computer_file/program/ subtype) or data files (datum/computer_file/data/ subtypes). Program for sending files will be available that will allow transfer via NTNet.
|
||||
NTNet coverage will be limited to station's Z level, but better network card (=more expensive and higher power use) will allow usage everywhere. Hard drives will have limited capacity for files
|
||||
which will be related to how good hard drive you buy when purchasing the laptop. For storing more files USB-style drives will be buildable with Protolathe in research.
|
||||
|
||||
2. Laptops
|
||||
Laptops are vendable via vending machine similar to how original laptops worked. This vending machine will allow hardware selection (hardware will be described below). Laptops will be
|
||||
quite expensive, basic cost being 1499$ + cost of any extra hardware. When purchased they will contain only basic software (text editor, game, etc.) but more will be downloadable via NTNet.
|
||||
|
||||
3. Laptop Hardware
|
||||
Laptops will come with basic hardware installed, with upgrades being selectable when purchasing the laptop.
|
||||
Hard Drive: Basic (20 GQ, free), Advanced (35 GQ, +199$), Super (60 GQ, +499$) One file (program or data file) equals 1GQ of capacity, regardless of file contents.
|
||||
Network Card: Basic (NTNet on station Z levels, free), Advanced (NTNet on all Z levels, +399$)
|
||||
Battery: Basic (about 10 minutes of charge, free), Advanced (about 20 minutes of charge, +199$), Super (about 30 minutes of charge, +399$)
|
||||
Extras (those won't be installed by default)
|
||||
ID Card Slot (required for HoP-style programs to work. Access for security record-style programs is read from ID of user [RFID?] without requiring this) - 99$
|
||||
APC Wireless Relay (allows the computer to run from APC, including slow recharge) - 499$
|
||||
Disk Drive (allows usage of data disks that store 10GQ of data, comes with FREE disk already inside!) - 199$
|
||||
Nano Printer (allows the computer to store few pieces of paper and print text files on them [NOTE: Paper not included!]) - 199$ // HoP's best friend!
|
||||
|
||||
4. NTNet
|
||||
NTNet is stationwide network that allows users to download programs needed for their work. It will be possible to send any files to other active computers using relevant program (NTN Transfer).
|
||||
NTNet is under jurisdiction of both Engineering and Research. Engineering is responsible for any repairs if necessary and research is responsible for monitoring. It is similar to PDA messaging.
|
||||
Operation requires functional "NTNet Relay" which is by default placed on tcommsat. If the relay is damaged NTNet will be offline until it is replaced. Multiple relays bring extra redundancy,
|
||||
if one is destroyed the second will take over. If all relays are gone it stops working, simple as that. NTNet may be altered via administration console available to Research Director. It is
|
||||
possible to enable/disable Software Downloading, P2P file transfers and Communication (IC version of IRC, PDA messages for more than two people)
|
||||
|
||||
5. Software
|
||||
Software would almost exclusively use NanoUI modules. Few exceptions are text editor (uses similar screen as TCS IDE used for editing and classic HTML for previewing as Nano looks differently)
|
||||
and similar programs which for some reason require HTML UI. Most software will be highly dependent on NTNet to work as laptops are not physically connected to the station's network.
|
||||
What i plan to add:
|
||||
|
||||
Note: XXXXDB programs will use ingame_manuals to display basic help for players, similar to how books, etc. do
|
||||
|
||||
Basic - Software in this bundle is automagically preinstalled in every new computer
|
||||
NTN Transfer - Allows P2P transfer of files to other computers that run this.
|
||||
Configurator - Allows configuration of computer's hardware, basically status screen.
|
||||
File Browser - Allows you to browse all files stored on the computer. Allows renaming/deleting of files.
|
||||
TXT Editor - Allows you editing data files in text editor mode.
|
||||
NanoPrint - Allows you to operate NanoPrinter hardware to print text files.
|
||||
NTNRC Chat - NTNet Relay Chat client. Allows PDA-messaging style messaging for more than two users. Person which created the conversation is Host and has administrative privilegies (kicking, etc.)
|
||||
NTNet News - Allows reading news from newscaster network.
|
||||
|
||||
Engineering - Requires "Engineering" access on ID card (ie. CE, Atmostech, Engineer)
|
||||
Alarm Monitor - Allows monitoring alarms, same as the stationbound one.
|
||||
Power Monitor - Power monitoring computer, connects to sensors in same way as regular one does.
|
||||
Atmospheric Control - Allows access to the Atmospherics Monitor Console that operates air alarms. Requires extra access: "Atmospherics"
|
||||
RCON Remote Control Console - Allows access to the RCON Remote Control Console. Requires extra access: "Power Equipment"
|
||||
EngiDB - Allows accessing NTNet information repository for information about engineering-related things.
|
||||
|
||||
Medical - Requires "Medbay" access on ID card (ie. CMO, Doctor,..)
|
||||
Medical Records Uplink - Allows editing/reading of medical records. Printing requires NanoPrinter hardware.
|
||||
MediDB - Allows accessing NTNet information repository for information about medical procedures
|
||||
ChemDB - Requires extra access: "Chemistry" - Downloads basic information about recipes from NTNet
|
||||
|
||||
Research - Requires "Research and Development" access on ID card (ie. RD, Roboticist, etc.)
|
||||
Research Server Monitor - Allows monitoring of research levels on RnD servers. (read only)
|
||||
Robotics Monitor Console - Allows monitoring of robots and exosuits. Lockdown/Self-Destruct options are unavailable [balance reasons for malf/traitor AIs]. Requires extra access: "Robotics"
|
||||
NTNRC Administration Console - Allows administrative access to NTNRC. This includes bypassing any channel passwords and enabling "invisible" mode for spying on conversations. Requires extra access: "Research Director"
|
||||
NTNet Administration Console - Allows remote configuration of NTNet Relay - CAUTION: If NTNet is turned off it won't be possible to turn it on again from the computer, as operation requires NTNet to work! Requires extra access: "Research Director"
|
||||
|
||||
Security - Requires "Security" access on ID card (ie. HOS, Security officer, Detective)
|
||||
Security Records Uplink - Allows editing/reading of security records. Printing requires Nanoprinter hardware.
|
||||
LawDB - Allows accessing NTNet information repository for security information (corporate regulations)
|
||||
Camera Uplink - Allows viewing cameras around the station.
|
||||
|
||||
Command - Requires "Bridge" access on ID card (all heads)
|
||||
Alertcon Access - Allows changing of alert levels. Red requires activation from two computers with two IDs similar to how those wall mounted devices do.
|
||||
Employment Records Access - Allows reading of employment records. Printing requires NanoPrinter hardware.
|
||||
Communication Console - Allows sending emergency messages to Central.
|
||||
Emergency Shuttle Control Console - Allows calling/recalling the emergency shuttle.
|
||||
Shuttle Control Console - Allows control of various shuttles around the station (mining, research, engineering)
|
||||
|
||||
6. Security
|
||||
Laptops will be password-lockable. If password is set a MD5 hash of it is stored and password is required every time you turn on the laptop.
|
||||
Passwords may be decrypted by using special Decrypter (protolathable, RDs office starts with one) device that will slowly decrypt the password.
|
||||
Decryption time would be length_of_password * 30 seconds, with maximum being 9 minutes (due to battery life limitations, which is 10+ min).
|
||||
If decrypted the password is cleared, so you can keep using your favorite password without people ever actually revealing it (for meta prevention reasons mostly).
|
||||
Emagged laptops will have option to enable "Safe Encryption". If safely encrypted laptop is decrypted it loses it's emag status and 50% of files is deleted (randomly selected).
|
||||
*/
|
||||
@@ -0,0 +1,375 @@
|
||||
// Portable item-based laptop
|
||||
|
||||
/obj/item/laptop
|
||||
name = "laptop computer"
|
||||
desc = "A portable computer. It is closed."
|
||||
icon = 'icons/obj/computer3.dmi' // Let's recycle the icons from computer3, they are decent.
|
||||
icon_state = "laptop-closed"
|
||||
item_state = "laptop-inhand"
|
||||
w_class = 3
|
||||
var/obj/machinery/modular_computer/laptop/stored_computer = null
|
||||
|
||||
/obj/item/laptop/verb/open_computer()
|
||||
set name = "Open Laptop"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
|
||||
usr << "<span class='warning'>You can't do that.</span>"
|
||||
return
|
||||
|
||||
if(!Adjacent(usr))
|
||||
usr << "You can't reach it."
|
||||
return
|
||||
|
||||
if(!istype(loc,/turf))
|
||||
usr << "[src] is too bulky! You'll have to set it down."
|
||||
return
|
||||
|
||||
if(!stored_computer)
|
||||
if(contents.len)
|
||||
for(var/obj/O in contents)
|
||||
O.loc = loc
|
||||
usr << "\The [src] crumbles to pieces."
|
||||
spawn(5)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
stored_computer.loc = loc
|
||||
stored_computer.stat &= ~MAINT
|
||||
stored_computer.update_icon()
|
||||
stored_computer.open = 1
|
||||
loc = stored_computer
|
||||
usr << "You open \the [src]."
|
||||
|
||||
|
||||
/obj/item/laptop/AltClick()
|
||||
if(Adjacent(usr))
|
||||
open_computer()
|
||||
|
||||
|
||||
// Laptop itself
|
||||
|
||||
// Defaults in here are for laptops, and are overriden for stationbound consoles.
|
||||
/obj/machinery/modular_computer/
|
||||
name = "laptop computer"
|
||||
desc = "A portable computer."
|
||||
var/open = 1 // Whether the laptop is open.
|
||||
var/enabled = 1 // Whether the laptop is turned on.
|
||||
var/datum/computer_file/program/active_program = null // A currently active program running on the computer.
|
||||
var/obj/item/laptop/portable = null // Portable version of this computer, dropped on alt-click to allow transport. Used by laptops.
|
||||
use_power = 0
|
||||
|
||||
icon = 'icons/obj/computer3.dmi'
|
||||
icon_state = "laptop-open"
|
||||
var/icon_state_unpowered = "laptop-open" // Icon state when the computer is turned off
|
||||
var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen.
|
||||
|
||||
// Important hardware (must be installed for computer to work)
|
||||
var/datum/computer_hardware/network_card/network_card // Network Card component of this computer. Allows connection to NTNet
|
||||
var/datum/computer_hardware/hard_drive/hard_drive // Hard Drive component of this computer. Stores programs and files.
|
||||
var/obj/item/weapon/cell/battery = null // Battery component of this computer. Powers the computer. Áll computers can have batteries.
|
||||
// Optional hardware (improves functionality, but is not critical for computer to work)
|
||||
var/datum/computer_hardware/tesla_link/tesla_link // Tesla Link component of this computer. Allows remote charging from nearest APC.
|
||||
var/datum/computer_hardware/card_slot/card_slot // ID Card slot component of this computer. Mostly for HoP modification console that needs ID slot for modification.
|
||||
|
||||
/obj/machinery/modular_computer/laptop/update_icon()
|
||||
icon_state = icon_state_unpowered
|
||||
|
||||
overlays.Cut()
|
||||
if(!enabled)
|
||||
return
|
||||
if(active_program)
|
||||
overlays.Add(active_program.laptop_icon_state ? active_program.laptop_icon_state : icon_state_menu)
|
||||
else
|
||||
overlays.Add(icon_state_menu)
|
||||
|
||||
// Close the computer. collapsing it into movable item that can't be used.
|
||||
/obj/machinery/modular_computer/laptop/verb/close_computer()
|
||||
set name = "Close Laptop"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
|
||||
usr << "<span class='warning'>You can't do that.</span>"
|
||||
return
|
||||
|
||||
if(!Adjacent(usr))
|
||||
usr << "<span class='warning'>You can't reach it.</span>"
|
||||
return
|
||||
|
||||
close_laptop(usr)
|
||||
|
||||
/obj/machinery/modular_computer/laptop/proc/close_laptop(mob/user = null)
|
||||
if(istype(loc,/obj/item/laptop))
|
||||
return
|
||||
if(!istype(loc,/turf))
|
||||
return
|
||||
|
||||
if(!portable)
|
||||
portable=new
|
||||
portable.stored_computer = src
|
||||
|
||||
portable.loc = loc
|
||||
loc = portable
|
||||
stat |= MAINT
|
||||
if(user)
|
||||
user << "You close \the [src]."
|
||||
open = 0
|
||||
|
||||
/obj/machinery/modular_computer/laptop/AltClick()
|
||||
if(Adjacent(usr))
|
||||
close_laptop()
|
||||
|
||||
// Eject ID card from computer, if it has ID slot with card inside.
|
||||
/obj/machinery/modular_computer/verb/eject_id()
|
||||
set name = "Eject ID"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
|
||||
usr << "<span class='warning'>You can't do that.</span>"
|
||||
return
|
||||
|
||||
if(!Adjacent(usr))
|
||||
usr << "<span class='warning'>You can't reach it.</span>"
|
||||
return
|
||||
|
||||
proc_eject_id(usr)
|
||||
|
||||
/obj/machinery/modular_computer/proc/proc_eject_id(mob/user)
|
||||
if(!user)
|
||||
user = usr
|
||||
|
||||
if(!card_slot)
|
||||
user << "\The [src] does not have an ID card slot"
|
||||
return
|
||||
|
||||
if(!card_slot.stored_card)
|
||||
user << "There is no card in \the [src]"
|
||||
return
|
||||
|
||||
card_slot.stored_card.loc = src.loc
|
||||
card_slot.stored_card = null
|
||||
user << "You remove the card from \the [src]"
|
||||
|
||||
|
||||
// TODO: Convert hardware creation specific stuff to vending machine that handles laptops.
|
||||
/obj/machinery/modular_computer/New()
|
||||
network_card = new(src)
|
||||
hard_drive = new(src)
|
||||
tesla_link = new(src)
|
||||
battery = new(src)
|
||||
battery.maxcharge = 500
|
||||
battery.charge = 500
|
||||
|
||||
hard_drive.stored_files.Add(new/datum/computer_file/program/power_monitor(src))
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
// Operates NanoUI
|
||||
/obj/machinery/modular_computer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!open || !enabled)
|
||||
if(ui)
|
||||
ui.close()
|
||||
return 0
|
||||
if(stat & (BROKEN | NOPOWER | MAINT))
|
||||
if(ui)
|
||||
ui.close()
|
||||
return 0
|
||||
|
||||
// If we have an active program switch to it now.
|
||||
if(active_program)
|
||||
if(ui) // This is the main laptop screen. Since we are switching to program's UI close it for now.
|
||||
ui.close()
|
||||
active_program.ui_interact(user)
|
||||
return
|
||||
|
||||
// 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.
|
||||
if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len)
|
||||
visible_message("\The [src] beeps three times, it's screen displaying \"DISK ERROR\" warning.")
|
||||
return // No HDD, No HDD files list or no stored files. Something is very broken.
|
||||
|
||||
var/list/data = get_header_data()
|
||||
|
||||
var/list/programs = list()
|
||||
for(var/datum/computer_file/program/P in hard_drive.stored_files)
|
||||
var/list/program = list()
|
||||
program["name"] = P.filename
|
||||
program["desc"] = P.filedesc
|
||||
program["icon_link"] = P.fileicon
|
||||
programs.Add(list(program))
|
||||
|
||||
data["programs"] = programs
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "laptop_mainscreen.tmpl", "NTOS Main Menu", 400, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
// On-click handling. Turns on the computer if it's off and opens the GUI.
|
||||
/obj/machinery/modular_computer/attack_hand(mob/user)
|
||||
if(enabled)
|
||||
ui_interact(user)
|
||||
else if((battery && battery.charge > 0) || (!battery && powered())) // Battery-run and charged or non-battery but powered by APC.
|
||||
user << "You press the power button and start up \the [src]"
|
||||
enabled = 1
|
||||
update_icon()
|
||||
|
||||
// Process currently calls handle_power(), may be expanded in future if more things are added.
|
||||
/obj/machinery/modular_computer/process()
|
||||
if(!enabled) // The computer is turned off
|
||||
use_power = 0
|
||||
return 0
|
||||
|
||||
handle_power() // Handles all laptop power interaction
|
||||
|
||||
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
|
||||
/obj/machinery/modular_computer/proc/get_header_data()
|
||||
var/list/data = list()
|
||||
|
||||
if(battery)
|
||||
switch(battery.percent())
|
||||
if(80 to 200) // 100 should be maximal but just in case..
|
||||
data["PC_batteryicon"] = "batt_100.gif"
|
||||
if(60 to 80)
|
||||
data["PC_batteryicon"] = "batt_80.gif"
|
||||
if(40 to 60)
|
||||
data["PC_batteryicon"] = "batt_60.gif"
|
||||
if(20 to 40)
|
||||
data["PC_batteryicon"] = "batt_40.gif"
|
||||
if(5 to 20)
|
||||
data["PC_batteryicon"] = "batt_20.gif"
|
||||
else
|
||||
data["PC_batteryicon"] = "batt_5.gif"
|
||||
data["PC_batterypercent"] = "[round(battery.percent())] %"
|
||||
else // Computer without battery shouldn't work at all, but in case we implement computers without batteries in future that run solely on APC network, it's here.
|
||||
data["PC_batteryicon"] = "batt_5.gif"
|
||||
data["PC_batterypercent"] = "N/C"
|
||||
|
||||
switch(get_ntnet_status())
|
||||
if(0)
|
||||
data["PC_ntneticon"] = "sig_none.gif"
|
||||
if(1)
|
||||
data["PC_ntneticon"] = "sig_low.gif"
|
||||
if(2)
|
||||
data["PC_ntneticon"] = "sig_high.gif"
|
||||
|
||||
if(tesla_link && tesla_link.enabled && powered())
|
||||
data["PC_apclinkicon"] = "charging.gif"
|
||||
|
||||
data["PC_stationtime"] = worldtime2text()
|
||||
data["PC_hasheader"] = 1
|
||||
return data
|
||||
|
||||
|
||||
// Relays kill program request to currently active program. Use this to quit current program.
|
||||
/obj/machinery/modular_computer/proc/kill_program(var/forced = 0)
|
||||
if(active_program)
|
||||
active_program.kill_program(forced)
|
||||
active_program = null
|
||||
var/mob/user = usr
|
||||
if(user && istype(user))
|
||||
ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
|
||||
update_icon()
|
||||
|
||||
// Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on)
|
||||
/obj/machinery/modular_computer/proc/get_ntnet_status()
|
||||
if(network_card)
|
||||
return network_card.get_signal()
|
||||
else
|
||||
return 0
|
||||
|
||||
// Handles user's GUI input
|
||||
/obj/machinery/modular_computer/Topic(href, href_list)
|
||||
if( href_list["PC_exit"] )
|
||||
kill_program()
|
||||
return
|
||||
if( href_list["PC_shutdown"] )
|
||||
kill_program(1)
|
||||
visible_message("\The [src] shuts down.")
|
||||
enabled = 0
|
||||
return
|
||||
if( href_list["PC_runprogram"] )
|
||||
var/prog = href_list["PC_runprogram"]
|
||||
var/datum/computer_file/program/P = null
|
||||
var/mob/user = usr
|
||||
if(hard_drive)
|
||||
P = hard_drive.find_file_by_name(prog)
|
||||
|
||||
if(!P || !istype(P)) // Program not found or it's not executable program.
|
||||
return
|
||||
|
||||
if(P.run_program(user))
|
||||
active_program = P
|
||||
update_icon()
|
||||
return
|
||||
|
||||
// Used in following function to reduce copypaste
|
||||
/obj/machinery/modular_computer/proc/power_failure()
|
||||
if(enabled) // Shut down the computer)
|
||||
visible_message("\The [src]'s screen flickers \"BATTERY CRITICAL\" warning as it shuts down unexpectedly.")
|
||||
kill_program(1)
|
||||
enabled = 0
|
||||
update_icon()
|
||||
stat |= NOPOWER
|
||||
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged, NOPOWER flag, etc.
|
||||
/obj/machinery/modular_computer/proc/handle_power()
|
||||
if(battery && battery.charge <= 0) // Battery-run but battery is depleted.
|
||||
power_failure()
|
||||
return 0
|
||||
else if(!battery && (!powered() || !tesla_link || !tesla_link.enabled)) // Not battery run, but lacking APC connection.
|
||||
power_failure()
|
||||
return 0
|
||||
else if(stat & NOPOWER)
|
||||
stat &= ~NOPOWER
|
||||
|
||||
var/power_usage = open ? 300 : 25 // 300W when it's open and only 25W when closed (sleep mode)? Screen probably uses a lot.
|
||||
if(network_card && network_card.enabled)
|
||||
power_usage += network_card.power_usage
|
||||
|
||||
if(hard_drive && hard_drive.enabled)
|
||||
power_usage += hard_drive.power_usage
|
||||
|
||||
// Wireless APC connection exists.
|
||||
if(tesla_link && tesla_link.enabled)
|
||||
idle_power_usage = power_usage
|
||||
active_power_usage = idle_power_usage + 100 // APCLink only charges at 100W rate, but covers any power usage.
|
||||
use_power = 1
|
||||
// Battery is not fully charged. Begin slowly recharging.
|
||||
if(battery && battery.charge < battery.maxcharge)
|
||||
use_power = 2
|
||||
|
||||
if(battery && powered() && (use_power == 2)) // Battery charging itself
|
||||
battery.give(100 * CELLRATE)
|
||||
else if(battery && !powered()) // Unpowered, but battery covers the usage.
|
||||
battery.use(idle_power_usage * CELLRATE)
|
||||
|
||||
else // No wireless connection run only on battery.
|
||||
use_power = 0
|
||||
if (battery)
|
||||
battery.use(power_usage * CELLRATE)
|
||||
|
||||
// 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()
|
||||
return
|
||||
|
||||
/obj/machinery/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/card/id)) // ID Card, try to insert it.
|
||||
var/obj/item/weapon/card/id/I = W
|
||||
if(!card_slot)
|
||||
user << "You try to insert \the [I] into \the [src], but it does not have an ID card slot installed."
|
||||
return
|
||||
|
||||
if(card_slot.stored_card)
|
||||
user << "You try to insert \the [I] into \the [src], but it's ID card slot is occupied."
|
||||
return
|
||||
|
||||
card_slot.stored_card = I
|
||||
I.loc = src
|
||||
user << "You insert \the [I] into \the [src]."
|
||||
return
|
||||
|
||||
..()
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 682 B |
@@ -0,0 +1,18 @@
|
||||
/datum/computer_file/
|
||||
var/filename = "NewFile" // Placeholder. No spacebars
|
||||
var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
|
||||
var/size = 1 // File size in GQ (default 1, do not change unless you really have to). Non-1 values are currently unused but they should be supported.
|
||||
var/datum/computer_hardware/hard_drive/holder // Holder that contains this file.
|
||||
var/icon_path = null // !!32x32!! icon of this program
|
||||
|
||||
|
||||
/datum/computer_file/Destroy()
|
||||
if(!holder)
|
||||
return ..()
|
||||
|
||||
holder.stored_files -= src
|
||||
// holder.holder is the computer that has drive installed. If we are Destroy()ing program that's currently running kill it.
|
||||
if(holder.holder && holder.holder.active_program == src)
|
||||
holder.holder.kill_program(1)
|
||||
holder = null
|
||||
..()
|
||||
@@ -0,0 +1,5 @@
|
||||
// /data/ files store data in string format.
|
||||
// They don't contain other logic for now.
|
||||
/datum/computer_file/data
|
||||
var/stored_data = "" // Stored data in string format.
|
||||
filetype = "DAT"
|
||||
@@ -0,0 +1,83 @@
|
||||
// /program/ files are executable programs that do things.
|
||||
/datum/computer_file/program
|
||||
filetype = "PRG"
|
||||
filename = "UnknownProgram" // File name.
|
||||
var/required_access = null // List of required accesses to *run* the program.
|
||||
var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
|
||||
var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program.
|
||||
var/running = 1 // Set to 1 when the program is run and back to 0 when it's stopped.
|
||||
var/atom/movable/computer = null // Device that runs this program.
|
||||
var/filedesc = "Unknown Program" // User-friendly name of this program.
|
||||
var/fileicon = "unknwn" // Name of relevant icon that is displayed with the program
|
||||
var/laptop_icon_state = null // Program-specific icon state (stored in /icons/obj/computer3.dmi)
|
||||
|
||||
/datum/computer_file/program/New(var/atom/movable/comp = null)
|
||||
..()
|
||||
if(comp)
|
||||
computer = comp
|
||||
|
||||
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
|
||||
// User has to wear their ID or have it inhand for ID Scan to work.
|
||||
/datum/computer_file/program/proc/can_run(var/mob/living/user)
|
||||
if(!required_access) // No required_access, allow it.
|
||||
return 1
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/weapon/card/id/I = H.wear_id
|
||||
if(!H) // No equipped ID, let's try checking active hand too
|
||||
I = H.get_active_hand()
|
||||
if(!H || !istype(I)) // Still no ID.
|
||||
return 0
|
||||
|
||||
if(required_access in I.access)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// This attempts to retrieve header data for NanoUIs. If implementing completely new device of different type than existing ones
|
||||
// always include the device here in this proc. This proc basically relays the request to whatever is running the program.
|
||||
/datum/computer_file/program/proc/get_header_data()
|
||||
if(istype(computer, /obj/machinery/modular_computer))
|
||||
var/obj/machinery/modular_computer/L = computer
|
||||
return L.get_header_data()
|
||||
|
||||
// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
|
||||
// When implementing new program based device, use this to run the program.
|
||||
/datum/computer_file/program/proc/run_program(var/mob/living/user)
|
||||
if(can_run(user))
|
||||
if(nanomodule_path)
|
||||
NM = new nanomodule_path(computer) // Computer is passed here as it's (probably!) physical object. Some UI's perform get_turf() and passing program datum wouldn't go well with this.
|
||||
NM.program = src // Set the program reference to separate variable, instead.
|
||||
running = 1
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
|
||||
/datum/computer_file/program/proc/kill_program(var/forced = 0)
|
||||
running = 0
|
||||
qdel(NM)
|
||||
NM = null
|
||||
return 1
|
||||
|
||||
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
|
||||
// It returns 0 if it can't run or if NanoModule was used instead. I suggest using NanoModules where applicable.
|
||||
/datum/computer_file/program/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!running) // Our program was closed. Close the ui if it exists.
|
||||
if(ui)
|
||||
ui.close()
|
||||
return 0
|
||||
if(NM)
|
||||
NM.ui_interact(user, ui_key, ui, force_open)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
|
||||
// Topic calls are automagically forwarded from NanoModule this program contains.
|
||||
// Calls beginning with "PRG_" are reserved for programs handling.
|
||||
// Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program)
|
||||
// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
|
||||
/datum/computer_file/program/Topic(href, href_list)
|
||||
|
||||
if(computer)
|
||||
computer.Topic(href, href_list)
|
||||
..()
|
||||
@@ -0,0 +1,5 @@
|
||||
/datum/computer_file/program/power_monitor
|
||||
filename = "powermonitor"
|
||||
filedesc = "Power Monitoring"
|
||||
nanomodule_path = /datum/nano_module/power_monitor/
|
||||
laptop_icon_state = "power_monitor"
|
||||
@@ -0,0 +1,7 @@
|
||||
/datum/computer_hardware/card_slot
|
||||
name = "RFID Card Slot"
|
||||
desc = "Slot that allows this computer to write data on RFID cards. Necessary for some programs to run properly."
|
||||
power_usage = 10 //W
|
||||
critical = 0
|
||||
|
||||
var/obj/item/weapon/card/id/stored_card = null
|
||||
@@ -0,0 +1,36 @@
|
||||
/datum/computer_hardware/hard_drive/
|
||||
name = "Hard Drive"
|
||||
desc = "A small power efficient solid state drive, with 25GQ of storage capacity for use in basic computers where power efficiency is desired."
|
||||
power_usage = 25 // SSD or something with low power usage
|
||||
var/max_capacity = 25
|
||||
var/list/stored_files = list() // List of stored files on this drive.
|
||||
|
||||
/datum/computer_hardware/hard_drive/advanced
|
||||
desc = "A small hybrid hard drive with 35GQ of storage capacity for use in higher grade computers where balance between power efficiency and capacity is desired."
|
||||
max_capacity = 35
|
||||
power_usage = 50 // Hybrid, medium capacity and medium power storage
|
||||
|
||||
/datum/computer_hardware/hard_drive/super
|
||||
desc = "A small hard drive with 60GQ of storage capacity for use in cluster storage solutions where capacity is more important than power efficiency."
|
||||
max_capacity = 60
|
||||
power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link.
|
||||
|
||||
// Checks whether file can be stored on the hard drive.
|
||||
/datum/computer_hardware/hard_drive/proc/can_store_file(var/size = 1)
|
||||
if(stored_files.len + size > max_capacity)
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
// Tries to find the file by filename. Returns null on failure
|
||||
/datum/computer_hardware/hard_drive/proc/find_file_by_name(var/filename)
|
||||
if(!filename)
|
||||
return null
|
||||
|
||||
if(!stored_files)
|
||||
return null
|
||||
|
||||
for(var/datum/computer_file/F in stored_files)
|
||||
if(F.filename == filename)
|
||||
return F
|
||||
return null
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/computer_hardware/
|
||||
var/name = "Hardware"
|
||||
var/desc = "Unknown Hardware"
|
||||
var/obj/machinery/modular_computer/holder = null
|
||||
var/power_usage = 0 // If the hardware uses extra power, change this.
|
||||
var/enabled = 1 // If the hardware is turned off set this to 0.
|
||||
var/critical = 1 // Prevent disabling for important component, like the HDD.
|
||||
|
||||
/datum/computer_hardware/New(var/obj/machinery/modular_computer/L)
|
||||
holder = L
|
||||
..()
|
||||
@@ -0,0 +1,44 @@
|
||||
/datum/computer_hardware/network_card/
|
||||
name = "NTNet Network Card"
|
||||
desc = "A basic network card for usage with standard NTNet frequencies."
|
||||
power_usage = 50
|
||||
critical = 0
|
||||
var/long_range = 0
|
||||
var/ethernet = 0 // Hard-wired, therefore always on, ignores NTNet wireless checks.
|
||||
|
||||
/datum/computer_hardware/network_card/advanced
|
||||
desc = "An advanced network card for usage with standard NTNet frequencies. It's transmitter is strong enough to connect even off-station."
|
||||
long_range = 1
|
||||
power_usage = 100 // Better range but higher power usage.
|
||||
|
||||
/datum/computer_hardware/network_card/wired
|
||||
desc = "An advanced network card for usage with NTNet. This one uses wired connection."
|
||||
ethernet = 1
|
||||
power_usage = 100 // Better range but higher power usage.
|
||||
|
||||
/datum/computer_hardware/network_card/Destroy()
|
||||
if(holder && (holder.network_card == src))
|
||||
holder.network_card = null
|
||||
holder = null
|
||||
..()
|
||||
|
||||
// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection
|
||||
/datum/computer_hardware/network_card/proc/get_signal()
|
||||
if(!holder) // Hardware is not installed in anything. No signal. How did this even get called?
|
||||
return 0
|
||||
|
||||
if(!enabled)
|
||||
return 0
|
||||
|
||||
if(ethernet) // Computer is connected via wired connection.
|
||||
return 3
|
||||
|
||||
// TODO: Add checks for NTNet Relays here!
|
||||
|
||||
if(holder.z in config.station_levels) // Computer is on station, High signal
|
||||
return 2
|
||||
|
||||
if(long_range) // Computer is not on station, but it has upgraded network card. Low signal.
|
||||
return 1
|
||||
|
||||
return 0 // Computer is not on station and does not have upgraded network card. No signal.
|
||||
@@ -0,0 +1,5 @@
|
||||
/datum/computer_hardware/tesla_link
|
||||
name = "Tesla Link"
|
||||
desc = "An advanced tesla link that wirelessly recharges connected device from nearby area power controller."
|
||||
critical = 0
|
||||
enabled = 0 // Starts turned off
|
||||
Reference in New Issue
Block a user