From 40e45287265a3a693c7111c6debd198ee6252e0b Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sat, 21 Jun 2014 00:30:29 -0700 Subject: [PATCH 01/25] initial testing stuff for better laptops. --- baystation12.dme | 4 +++- icons/obj/computer.dmi | Bin 73753 -> 73903 bytes 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/baystation12.dme b/baystation12.dme index 3b378a6e61..ba4fd0ac65 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -478,6 +478,8 @@ #include "code\game\objects\items\devices\uplinks.dm" #include "code\game\objects\items\devices\violin.dm" #include "code\game\objects\items\devices\whistle.dm" +#include "code\game\objects\items\devices\laptops\laptop.dm" +#include "code\game\objects\items\devices\laptops\medical.dm" #include "code\game\objects\items\devices\PDA\cart.dm" #include "code\game\objects\items\devices\PDA\chatroom.dm" #include "code\game\objects\items\devices\PDA\PDA.dm" @@ -1354,5 +1356,5 @@ #include "code\ZAS\Zone.dm" #include "interface\interface.dm" #include "interface\skin.dmf" -#include "maps\tgstation2.dmm" +#include "maps\test2.dmm" // END_INCLUDE diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi index de9a335a701ac3937e8657985694fdd6161a6db1..44903c2e2ec55f33a1d00d58897f2a6e4e8445e7 100644 GIT binary patch delta 7019 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 C*(r+v delta 6843 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 Nxo4 Date: Sun, 22 Jun 2014 02:08:42 -0700 Subject: [PATCH 02/25] Initial commit of Computer 3 from Paradise, along with a bunch of fixes. --- code/WorkInProgress/computer3/NTOS.dm | 199 +++ code/WorkInProgress/computer3/bios.dm | 182 +++ .../computer3/buildandrepair.dm | 302 ++++ code/WorkInProgress/computer3/component.dm | 194 +++ code/WorkInProgress/computer3/computer.dm | 446 ++++++ .../computer3/computer3_notes.dm | 34 + .../computer3/computers/HolodeckControl.dm | 254 ++++ .../computer3/computers/Operating.dm | 47 + .../computer3/computers/aifixer.dm | 117 ++ .../computer3/computers/arcade.dm | 180 +++ .../computer3/computers/atmos_alert.dm | 110 ++ .../computer3/computers/camera.dm | 277 ++++ .../computer3/computers/card.dm | 289 ++++ .../computer3/computers/cloning.dm | 363 +++++ .../computer3/computers/communications.dm | 384 +++++ .../computer3/computers/crew.dm | 71 + .../computer3/computers/customs.dm | 3 + .../WorkInProgress/computer3/computers/law.dm | 84 ++ .../computer3/computers/medical.dm | 503 +++++++ .../computer3/computers/message.dm | 441 ++++++ .../WorkInProgress/computer3/computers/pod.dm | 218 +++ .../computer3/computers/power.dm | 47 + .../computer3/computers/prisoner.dm | 109 ++ .../computer3/computers/prisonshuttle.dm | 242 ++++ .../computer3/computers/robot.dm | 211 +++ .../computer3/computers/scanconsole.dm | 1274 +++++++++++++++++ .../computer3/computers/security.dm | 606 ++++++++ .../computer3/computers/shuttle.dm | 75 + .../computer3/computers/specops_shuttle.dm | 246 ++++ .../computer3/computers/station_alert.dm | 114 ++ .../computer3/computers/syndicate_shuttle.dm | 103 ++ .../computers/syndicate_specops_shuttle.dm | 259 ++++ code/WorkInProgress/computer3/file.dm | 166 +++ code/WorkInProgress/computer3/laptop.dm | 137 ++ code/WorkInProgress/computer3/networking.dm | 236 +++ code/WorkInProgress/computer3/program.dm | 404 ++++++ .../WorkInProgress/computer3/program_disks.dm | 44 + code/WorkInProgress/computer3/server.dm | 32 + code/WorkInProgress/computer3/storage.dm | 184 +++ .../WorkInProgress/computer3/test_machines.dm | 86 ++ .../computer3/upload/lawfile.dm | 29 + .../computer3/upload/programs.dm | 13 + code/__HELPERS/unsorted.dm | 5 + code/datums/browser.dm | 7 + code/setup.dm | 9 + icons/NTOS/airestore.png | Bin 0 -> 3096 bytes icons/NTOS/aiupload.png | Bin 0 -> 3093 bytes icons/NTOS/alerts.png | Bin 0 -> 3041 bytes icons/NTOS/borgcontrol.png | Bin 0 -> 3154 bytes icons/NTOS/borgupload.png | Bin 0 -> 3040 bytes icons/NTOS/camera.png | Bin 0 -> 3298 bytes icons/NTOS/cardcomp.png | Bin 0 -> 3174 bytes icons/NTOS/cloning.png | Bin 0 -> 3050 bytes icons/NTOS/comms.png | Bin 0 -> 3157 bytes icons/NTOS/copyfile.png | Bin 0 -> 3030 bytes icons/NTOS/deletefile.png | Bin 0 -> 3008 bytes icons/NTOS/drive.png | Bin 0 -> 259 bytes icons/NTOS/exocontrol.png | Bin 0 -> 3355 bytes icons/NTOS/file.png | Bin 0 -> 2984 bytes icons/NTOS/folder.png | Bin 0 -> 259 bytes icons/NTOS/foldermeta.png | Bin 0 -> 350 bytes icons/NTOS/genetics.png | Bin 0 -> 3194 bytes icons/NTOS/medical.png | Bin 0 -> 3030 bytes icons/NTOS/monitoring.png | Bin 0 -> 3011 bytes icons/NTOS/movefile.png | Bin 0 -> 2985 bytes icons/NTOS/ntos.png | Bin 0 -> 67090 bytes icons/NTOS/operating.png | Bin 0 -> 2990 bytes icons/NTOS/pda.png | Bin 0 -> 2953 bytes icons/NTOS/power.png | Bin 0 -> 3055 bytes icons/NTOS/prison.png | Bin 0 -> 3117 bytes icons/NTOS/program.png | Bin 0 -> 2963 bytes icons/NTOS/records.png | Bin 0 -> 3069 bytes icons/NTOS/research.png | Bin 0 -> 3120 bytes icons/NTOS/server.png | Bin 0 -> 3195 bytes icons/NTOS/tb_close.png | Bin 0 -> 453 bytes icons/NTOS/tcomms.png | Bin 0 -> 3289 bytes icons/obj/computer3.dmi | Bin 0 -> 37470 bytes 77 files changed, 9336 insertions(+) create mode 100644 code/WorkInProgress/computer3/NTOS.dm create mode 100644 code/WorkInProgress/computer3/bios.dm create mode 100644 code/WorkInProgress/computer3/buildandrepair.dm create mode 100644 code/WorkInProgress/computer3/component.dm create mode 100644 code/WorkInProgress/computer3/computer.dm create mode 100644 code/WorkInProgress/computer3/computer3_notes.dm create mode 100644 code/WorkInProgress/computer3/computers/HolodeckControl.dm create mode 100644 code/WorkInProgress/computer3/computers/Operating.dm create mode 100644 code/WorkInProgress/computer3/computers/aifixer.dm create mode 100644 code/WorkInProgress/computer3/computers/arcade.dm create mode 100644 code/WorkInProgress/computer3/computers/atmos_alert.dm create mode 100644 code/WorkInProgress/computer3/computers/camera.dm create mode 100644 code/WorkInProgress/computer3/computers/card.dm create mode 100644 code/WorkInProgress/computer3/computers/cloning.dm create mode 100644 code/WorkInProgress/computer3/computers/communications.dm create mode 100644 code/WorkInProgress/computer3/computers/crew.dm create mode 100644 code/WorkInProgress/computer3/computers/customs.dm create mode 100644 code/WorkInProgress/computer3/computers/law.dm create mode 100644 code/WorkInProgress/computer3/computers/medical.dm create mode 100644 code/WorkInProgress/computer3/computers/message.dm create mode 100644 code/WorkInProgress/computer3/computers/pod.dm create mode 100644 code/WorkInProgress/computer3/computers/power.dm create mode 100644 code/WorkInProgress/computer3/computers/prisoner.dm create mode 100644 code/WorkInProgress/computer3/computers/prisonshuttle.dm create mode 100644 code/WorkInProgress/computer3/computers/robot.dm create mode 100644 code/WorkInProgress/computer3/computers/scanconsole.dm create mode 100644 code/WorkInProgress/computer3/computers/security.dm create mode 100644 code/WorkInProgress/computer3/computers/shuttle.dm create mode 100644 code/WorkInProgress/computer3/computers/specops_shuttle.dm create mode 100644 code/WorkInProgress/computer3/computers/station_alert.dm create mode 100644 code/WorkInProgress/computer3/computers/syndicate_shuttle.dm create mode 100644 code/WorkInProgress/computer3/computers/syndicate_specops_shuttle.dm create mode 100644 code/WorkInProgress/computer3/file.dm create mode 100644 code/WorkInProgress/computer3/laptop.dm create mode 100644 code/WorkInProgress/computer3/networking.dm create mode 100644 code/WorkInProgress/computer3/program.dm create mode 100644 code/WorkInProgress/computer3/program_disks.dm create mode 100644 code/WorkInProgress/computer3/server.dm create mode 100644 code/WorkInProgress/computer3/storage.dm create mode 100644 code/WorkInProgress/computer3/test_machines.dm create mode 100644 code/WorkInProgress/computer3/upload/lawfile.dm create mode 100644 code/WorkInProgress/computer3/upload/programs.dm create mode 100644 icons/NTOS/airestore.png create mode 100644 icons/NTOS/aiupload.png create mode 100644 icons/NTOS/alerts.png create mode 100644 icons/NTOS/borgcontrol.png create mode 100644 icons/NTOS/borgupload.png create mode 100644 icons/NTOS/camera.png create mode 100644 icons/NTOS/cardcomp.png create mode 100644 icons/NTOS/cloning.png create mode 100644 icons/NTOS/comms.png create mode 100644 icons/NTOS/copyfile.png create mode 100644 icons/NTOS/deletefile.png create mode 100644 icons/NTOS/drive.png create mode 100644 icons/NTOS/exocontrol.png create mode 100644 icons/NTOS/file.png create mode 100644 icons/NTOS/folder.png create mode 100644 icons/NTOS/foldermeta.png create mode 100644 icons/NTOS/genetics.png create mode 100644 icons/NTOS/medical.png create mode 100644 icons/NTOS/monitoring.png create mode 100644 icons/NTOS/movefile.png create mode 100644 icons/NTOS/ntos.png create mode 100644 icons/NTOS/operating.png create mode 100644 icons/NTOS/pda.png create mode 100644 icons/NTOS/power.png create mode 100644 icons/NTOS/prison.png create mode 100644 icons/NTOS/program.png create mode 100644 icons/NTOS/records.png create mode 100644 icons/NTOS/research.png create mode 100644 icons/NTOS/server.png create mode 100644 icons/NTOS/tb_close.png create mode 100644 icons/NTOS/tcomms.png create mode 100644 icons/obj/computer3.dmi diff --git a/code/WorkInProgress/computer3/NTOS.dm b/code/WorkInProgress/computer3/NTOS.dm new file mode 100644 index 0000000000..54fad87ce0 --- /dev/null +++ b/code/WorkInProgress/computer3/NTOS.dm @@ -0,0 +1,199 @@ +/* + The Big Bad NT Operating System +*/ + +/datum/file/program/NTOS + name = "Nanotrasen Operating System" + extension = "prog" + active_state = "ntos" + var/obj/item/part/computer/storage/current // the drive being viewed, null for desktop/computer + var/fileop = "runfile" + +/* + Generate a basic list of files in the selected scope +*/ + +/datum/file/program/NTOS/proc/list_files() + if(!computer || !current) return null + return current.files + + +/datum/file/program/NTOS/proc/filegrid(var/list/filelist) + var/dat = "" + var/i = 0 + for(var/datum/file/F in filelist) + i++ + if(i==1) + dat += "" + if(i>= 7) + i = 0 + dat += "" + continue + dat += {" + "} + + dat += "
+ +
+ [F.name] +
+
" + return dat + +// +// I am separating this from filegrid so that I don't have to +// make metadata peripheral files +// +/datum/file/program/NTOS/proc/desktop(var/peripheralop = "viewperipheral") + var/dat = "" + var/i = 0 + var/list/peripherals = list(computer.hdd,computer.floppy,computer.cardslot) + for(var/obj/item/part/computer/C in peripherals) + if(!istype(C)) continue + i++ + if(i==1) + dat += "" + if(i>= 8) + i = 0 + dat += "" + continue + dat += {" + "} + + dat += "
+ + \icon[C]
+ [C.name] +
+
" + return dat + + +/datum/file/program/NTOS/proc/window(var/title,var/buttonbar,var/content) + return {" +
+
[title]
+
[buttonbar]
+
[content]
+
"} + +/datum/file/program/NTOS/proc/buttonbar(var/type = 0) + switch(type) + if(0) // FILE OPERATIONS + return {""} + +/datum/file/program/NTOS/interact() + if(!interactable()) + return + var/dat = {" + + + Nanotrasen Operating System + + + +
"} + + var/list/files = list_files() + if(current) + dat +=window(current.name,buttonbar(),filegrid(files)) + else + dat += desktop() + + dat += "
" + + usr << browse(dat, "window=\ref[computer];size=670x510") + onclose(usr, "\ref[computer]") + +/datum/file/program/NTOS/Topic(href, list/href_list) + if(!interactable() || ..(href,href_list)) + return + + if("viewperipheral" in href_list) // open drive, show status of peripheral + var/obj/item/part/computer/C = locate(href_list["viewperipheral"]) + if(istype(C,/obj/item/part/computer/storage)) + current = C + interact() + return + // else ??? + interact() + return + + // distinct from close, this is the file dialog window + if("winclose" in href_list) + current = null + interact() + return + +#undef MAX_ROWS +#undef MAX_COLUMNS diff --git a/code/WorkInProgress/computer3/bios.dm b/code/WorkInProgress/computer3/bios.dm new file mode 100644 index 0000000000..17ed0c4789 --- /dev/null +++ b/code/WorkInProgress/computer3/bios.dm @@ -0,0 +1,182 @@ +/* + Okay so my last effort to have a central BIOS function was interesting + but completely unmaintainable, I have scrapped it. + + The parts that were actually useful will be put here in functions instead. + If we want a central bios function we can add one that just indexes them. + That should at least allow sensible debugging. +*/ + +/obj/machinery/computer3 + + /* + interactable(user): performs all standard sanity checks + Call in topic() and interact(). + */ + proc/interactable(var/mob/user) + if( !src || !user || stat || user.stat || user.lying || user.blinded ) + return 0 + if(!program) + return 0 + + if(!istype(loc,/turf) || !istype(user.loc,/turf)) // todo handheld maybe + return 0 + + if(istype(user,/mob/living/silicon)) + if(!program.ai_allowed) + user << "\blue You are forbidden from accessing this program." + return 0 + else + if(program.human_controls) + if(!ishuman(user)) + user << "\red Your body can't work the controls!" + return 0 + if(user.restrained()) + user << "\red You need a free hand!" + return 0 + + if(!in_range(src,user)) + // telekinesis check + if(ishuman(user) && istype(user.get_active_hand(),/obj/item/tk_grab)) + if(program.human_controls) + user << "\red It's too complicated to work at a distance!" + return 0 + add_fingerprint(user) + user.set_machine(src) + return 1 + return 0 + + add_fingerprint(user) + user.set_machine(src) + return 1 + + /* + Deduplicates an item list and gives you range and direction. + This is used for networking so you can determine which of several + identically named objects you're referring to. + */ + proc/format_atomlist(var/list/atoms) + var/list/output = list() + for(var/atom/A in atoms) + var/title = "[A] (Range [get_dist(A,src)] meters, [dir2text(get_dir(src,A))])" + output[title] = A + return output + + /* + This is used by the camera monitoring program to see if you're still in range + */ + check_eye(var/mob/user as mob) + if(!interactable(user) || user.machine != src) + if(user.machine == src) + user.unset_machine() + return null + + var/datum/file/program/security/S = program + if( !istype(S) || !S.current || !S.current.status || !camnet ) + if( user.machine == src ) + user.unset_machine() + return null + + user.reset_view(S.current) + return 1 + + /* + List all files, including removable disks and data cards + (I don't know why but I don't want to rip data cards out. + It just seems... interesting?) + */ + proc/list_files(var/typekey = null) + var/list/files = list() + if(hdd) + files += hdd.files + if(floppy && floppy.inserted) + files += floppy.inserted.files + if(cardslot && istype(cardslot.reader,/obj/item/weapon/card/data)) + files += cardslot.reader:files + if(!ispath(typekey)) + return files + + var/i = 1 + while(i<=files.len) + if(istype(files[i],typekey)) + i++ + continue + files.Cut(i,i+1) + return files + + /* + Crash the computer with an error. + Todo: redo + */ + proc/Crash(var/errorcode = PROG_CRASH) + if(!src) + return null + + switch(errorcode) + if(PROG_CRASH) + if(usr) + usr << "\red The program crashed!" + usr << browse(null,"\ref[src]") + Reset() + + if(MISSING_PERIPHERAL) + Reset() + if(usr) + usr << browse("

ERROR: Missing or disabled component

A hardware failure has occured. Please insert or replace the missing or damaged component and restart the computer.","window=\ref[src]") + + if(BUSTED_ASS_COMPUTER) + Reset() + os.error = BUSTED_ASS_COMPUTER + if(usr) + usr << browse("

ERROR: Missing or disabled component

A hardware failure has occured. Please insert or replace the missing or damaged component and restart the computer.","window=\ref[src]") + + if(MISSING_PROGRAM) + Reset() + if(usr) + usr << browse("

ERROR: No associated program

This file requires a specific program to open, which cannot be located. Please install the related program and try again.","window=\ref[src]") + + if(FILE_DRM) + Reset() + if(usr) + usr << browse("

ERROR: File operation prohibited

Copy protection exception: missing authorization token.","window=\ref[src]") + + if(NETWORK_FAILURE) + Reset() + if(usr) + usr << browse("

ERROR: Networking exception: Unable to connect to remote host.","window=\ref[src]") + + + else + if(usr) + usr << "\red The program crashed!" + usr << browse(null,"\ref[src]") + testing("computer/Crash() - unknown error code [errorcode]") + Reset() + return null + + #define ANY_DRIVE 0 + #define PREFER_FLOPPY 1 + #define PREFER_CARD 2 + #define PREFER_HDD 4 + + + // required_location: only put on preferred devices + proc/writefile(var/datum/file/F, var/where = ANY_DRIVE, var/required_location = 0) + if(where != ANY_DRIVE) + if((where&PREFER_FLOPPY) && floppy && floppy.addfile(F)) + return 1 + if((where&PREFER_CARD) && cardslot && cardslot.addfile(F)) + return 1 + if((where&PREFER_HDD) && hdd && hdd.addfile(F)) + return 1 + + if(required_location) + return 0 + + if(floppy && floppy.addfile(F)) + return 1 + if(cardslot && cardslot.addfile(F)) + return 1 + if(hdd && hdd.addfile(F)) + return 1 + return 0 diff --git a/code/WorkInProgress/computer3/buildandrepair.dm b/code/WorkInProgress/computer3/buildandrepair.dm new file mode 100644 index 0000000000..2cb9139f2e --- /dev/null +++ b/code/WorkInProgress/computer3/buildandrepair.dm @@ -0,0 +1,302 @@ +// Computer3 circuitboard specifically +/obj/item/part/computer/circuitboard + density = 0 + anchored = 0 + w_class = 2.0 + name = "Circuit board" + icon = 'icons/obj/module.dmi' + icon_state = "id_mod" + item_state = "electronic" + origin_tech = "programming=2" + var/id = null + var/frequency = null + var/build_path = null + var/board_type = "computer" + var/list/req_components = null + var/powernet = null + var/list/records = null + var/frame_desc = null + + var/datum/file/program/OS = new/datum/file/program/NTOS + +/obj/machinery/computer3/proc/disassemble(mob/user as mob) // todo + return + + +/obj/structure/computer3frame + density = 1 + anchored = 0 + name = "computer frame" + icon = 'icons/obj/stock_parts.dmi' + icon_state = "0" + var/state = 0 + + var/obj/item/part/computer/circuitboard/circuit = null + var/completed = /obj/machinery/computer + + // Computer3 components - a carbon copy of the list from + // computer.dm; however, we will need to check to make sure + // we don't install more components than the computer frame + // can handle. This will be different for certain formfactors. + + var/max_components = 4 + var/list/components = list() + + // Storage + var/obj/item/part/computer/storage/hdd/hdd = null + var/obj/item/part/computer/storage/removable/floppy = null + // Networking + var/obj/item/part/computer/networking/radio/radio = null // not handled the same as other networks + var/obj/item/part/computer/networking/cameras/camnet = null // just plain special + var/obj/item/part/computer/networking/net = null // Proximity, area, or cable network + var/obj/item/part/computer/networking/subspace/centcom = null // only for offstation communications + + // Card reader - note the HoP reader is a subtype + var/obj/item/part/computer/cardslot/cardslot = null + + // Misc & special purpose + var/obj/item/part/computer/ai_holder/cradle = null + var/obj/item/part/computer/toybox/toybox = null + + // Battery must be installed BEFORE wiring the computer. + // if installing it in an existing computer, you will have to + // get back to this state first. + var/obj/item/weapon/cell/battery = null + +/obj/structure/computer3frame/server + name = "server frame" + completed = /obj/machinery/computer3/server + max_components = 6 +/obj/structure/computer3frame/wallcomp + name = "wall-computer frame" + completed = /obj/machinery/computer3/wall_comp + max_components = 3 +/obj/structure/computer3frame/laptop + name = "laptop frame" + completed = /obj/machinery/computer3/laptop + max_components = 3 + +/obj/structure/computer3frame/attackby(obj/item/P as obj, mob/user as mob) + switch(state) + if(0) + if(istype(P, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + if(do_after(user, 20)) + user << "\blue You wrench the frame into place." + src.anchored = 1 + src.state = 1 + if(istype(P, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = P + if(!WT.remove_fuel(0, user)) + user << "The welding tool must be on to complete this task." + return + playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) + if(do_after(user, 20)) + if(!src || !WT.isOn()) return + user << "\blue You deconstruct the frame." + new /obj/item/stack/sheet/metal( src.loc, 5 ) + del(src) + if(1) + if(istype(P, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + if(do_after(user, 20)) + user << "\blue You unfasten the frame." + src.anchored = 0 + src.state = 0 + if(istype(P, /obj/item/weapon/circuitboard) && !circuit) + var/obj/item/weapon/circuitboard/B = P + if(B.board_type == "computer") + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + user << "\blue You place the circuit board inside the frame." + src.icon_state = "1" + src.circuit = P + user.drop_item() + P.loc = src + else + user << "\red This frame does not accept circuit boards of this type!" + if(istype(P, /obj/item/weapon/screwdriver) && circuit) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + user << "\blue You screw the circuit board into place." + src.state = 2 + src.icon_state = "2" + if(istype(P, /obj/item/weapon/crowbar) && circuit) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "\blue You remove the circuit board." + src.state = 1 + src.icon_state = "0" + circuit.loc = src.loc + src.circuit = null + if(2) + if(istype(P, /obj/item/weapon/screwdriver) && circuit) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + user << "\blue You unfasten the circuit board." + src.state = 1 + src.icon_state = "1" + + if(istype(P, /obj/item/weapon/crowbar)) + if(battery) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + if(do_after(10)) + battery.loc = loc + user << "\blue You remove [battery]." + battery = null + else + user << "\red There's no battery to remove!" + + if(istype(P, /obj/item/weapon/cell)) + if(!battery) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(5)) + battery = P + P.loc = src + user << "\blue You insert [battery]." + else + user << "\red There's already \an [battery] in [src]!" + + + if(istype(P, /obj/item/weapon/cable_coil)) + if(P:amount >= 5) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(user, 20)) + if(P) + P:amount -= 5 + if(!P:amount) del(P) + user << "\blue You add cables to the frame." + src.state = 3 + src.icon_state = "3" + if(3) + if(istype(P, /obj/item/weapon/wirecutters)) + if(components.len) + user << "There are parts in the way!" + return + playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1) + user << "\blue You remove the cables." + src.state = 2 + src.icon_state = "2" + var/obj/item/weapon/cable_coil/A = new /obj/item/weapon/cable_coil( src.loc ) + A.amount = 5 + + if(istype(P, /obj/item/weapon/crowbar)) // complicated check + remove_peripheral() + + if(istype(P, /obj/item/stack/sheet/glass)) + if(P:amount >= 2) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(user, 20)) + if(P) + P:use(2) + user << "\blue You put in the glass panel." + src.state = 4 + src.icon_state = "4" + if(4) + if(istype(P, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "\blue You remove the glass panel." + src.state = 3 + src.icon_state = "3" + new /obj/item/stack/sheet/glass( src.loc, 2 ) + if(istype(P, /obj/item/weapon/screwdriver)) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + user << "\blue You connect the monitor." + var/obj/machinery/computer3/B = new src.circuit.build_path ( src.loc, built=1 ) + /*if(circuit.powernet) B:powernet = circuit.powernet + if(circuit.id) B:id = circuit.id + //if(circuit.records) B:records = circuit.records + if(circuit.frequency) B:frequency = circuit.frequency + if(istype(circuit,/obj/item/weapon/circuitboard/supplycomp)) + var/obj/machinery/computer/supplycomp/SC = B + var/obj/item/weapon/circuitboard/supplycomp/C = circuit + SC.can_order_contraband = C.contraband_enabled*/ + B.circuit = circuit + circuit.loc = B + if(circuit.OS) + circuit.OS.computer = B + B.RefreshParts() // todo + del(src) + +/* + This will remove peripherals if you specify one, but the main function is to + allow the user to remove a part specifically. +*/ +/obj/structure/computer3frame/proc/remove_peripheral(var/obj/item/I = null) + if(!components || !components.len) + usr << "\red There are no components in [src] to take out!" + return 0 + if(!I) + I = input(usr, "Remove which component?","Remove component", null) as null|obj in components + + if(I) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + if(do_after(usr,25)) + if(I==hdd) + components -= hdd + hdd.loc = loc + hdd = null + else if(I==floppy) + components -= floppy + floppy.loc = loc + floppy = null + else if(I==radio) + components -= radio + radio.loc = loc + radio = null + else if(I==camnet) + components -= camnet + camnet.loc = loc + camnet = null + else if(I==net) + components -= net + net.loc = loc + net = null + else if(I==cradle) + components -= cradle + cradle.loc = loc + cradle = null + else if(I==toybox) + components -= toybox + toybox.loc = loc + toybox = null + else + warning("Erronous component in computerframe/remove_peripheral: [I]") + I.loc = loc + usr << "\blue You remove [I]" + return 1 + return 0 +/obj/structure/computer3frame/proc/insert_peripheral(var/obj/item/I) + if(components.len >= max_components) + usr << "There isn't room in [src] for another component!" + return 0 + switch(I.type) + if(/obj/item/part/computer/storage/hdd) + if(hdd) + usr << "There is already \an [hdd] in [src]!" + return 0 + hdd = I + components += hdd + hdd.loc = src + if(/obj/item/part/computer/storage/removable) + if(floppy) + usr << "There is already \an [floppy] in [src]!" + return 0 + floppy = I + components += floppy + floppy.loc = src + if(/obj/item/part/computer/networking/radio) + if(radio) + usr << "There is already \an [radio] in [src]!" + return 0 + radio = I + components += radio + radio.loc = src + if(/obj/item/part/computer/networking/cameras) + if(camnet) + usr << "There is already \an [camnet] in [src]!" + return 0 + camnet = I + components += camnet + camnet.loc = src + if(/obj/item/part/computer/networking) + if(net) + usr << "There is already \an [net] in [src]!" + + diff --git a/code/WorkInProgress/computer3/component.dm b/code/WorkInProgress/computer3/component.dm new file mode 100644 index 0000000000..a6965ab9e5 --- /dev/null +++ b/code/WorkInProgress/computer3/component.dm @@ -0,0 +1,194 @@ + +/* + Objects used to construct computers, and objects that can be inserted into them, etc. + + TODO: + * Synthesizer part (toybox, injectors, etc) +*/ + + + +/obj/item/part/computer + name = "computer part" + desc = "Holy jesus you donnit now" + gender = PLURAL + icon = 'icons/obj/stock_parts.dmi' + icon_state = "hdd1" + w_class = 2.0 + + var/emagged = 0 + crit_fail = 0 + + // the computer that this device is attached to + var/obj/machinery/computer3/computer + + // If the computer is attacked by an item it will reference this to decide which peripheral(s) are affected. + var/list/attackby_types = list() + proc/allow_attackby(var/obj/item/I as obj,var/mob/user as mob) + + for(var/typekey in attackby_types) + if(istype(I,typekey)) + return 1 + return 0 + + proc/init(var/obj/machinery/computer/target) + computer = target + // continue to handle all other type-specific procedures + +/* + Below are all the miscellaneous components + For storage drives, see storage.dm + For networking parts, see +*/ + +/obj/item/part/computer/ai_holder + name = "intelliCard computer module" + desc = "Contains a specialized nacelle for dealing with highly sensitive equipment without interference." + + attackby_types = list(/obj/item/device/aicard) + + var/mob/living/silicon/ai/occupant = null + var/busy = 0 + + // Ninja gloves check + attack_hand(mob/user as mob) + if(ishuman(user) && istype(user:gloves, /obj/item/clothing/gloves/space_ninja) && user:gloves:candrain && !user:gloves:draining) + if(user:wear_suit:s_control) + user:wear_suit.transfer_ai("AIFIXER","NINJASUIT",src,user) + else + user << "\red ERROR: \black Remote access channel disabled." + return + ..() + + attackby(obj/I as obj,mob/user as mob) + if(computer && !computer.stat) + if(istype(I, /obj/item/device/aicard)) + I:transfer_ai("AIFIXER","AICARD",src,user) + if(computer.program) + computer.program.update_icon() + computer.update_icon() + computer.occupant = occupant + ..() + return + +/* + ID computer cardslot - reading and writing slots +*/ + +/obj/item/part/computer/cardslot + name = "magnetic card slot" + desc = "Contains a slot for reading magnetic swipe cards." + + var/obj/item/weapon/card/reader = null + var/obj/item/weapon/card/writer = null // so that you don't need to typecast dual cardslots, but pretend it's not here + // alternately pretend they did it to save money on manufacturing somehow + var/dualslot = 0 // faster than typechecking + attackby_types = list(/obj/item/weapon/card) + + attackby(var/obj/item/I as obj, var/mob/user as mob) + if(istype(I,/obj/item/weapon/card)) + insert(I) + return + ..(I,user) + + proc/insert(var/obj/item/weapon/card/card) + if(!computer) + return 0 + if(reader != null) + usr << "There is already something in the slot!" + return 0 + if(istype(card,/obj/item/weapon/card/emag)) // emag reader slot + usr << "You insert \the [card], and the computer grinds, sparks, and beeps. After a moment, the card ejects itself." + computer.emagged = 1 + return 1 + var/mob/living/L = usr + L.drop_item() + card.loc = src + reader = card + + proc/remove() + reader.loc = loc + var/mob/living/carbon/human/user = usr + if(istype(user) && !user.get_active_hand()) + user.put_in_hands(reader) + reader = null + + // Authorizes the user based on the computer's requirements + proc/authenticate() + return computer.check_access(reader) + + proc/addfile(var/datum/file/F) + if(!dualslot || !istype(writer,/obj/item/weapon/card/data)) + return 0 + var/obj/item/weapon/card/data/D = writer + if(D.files.len > 3) + return 0 + D.files += F + return 1 + +/obj/item/part/computer/cardslot/dual + name = "magnetic card reader" + desc = "Contains slots for inserting magnetic swipe cards for reading and writing." + dualslot = 1 + + insert(var/obj/item/weapon/card/card,var/slot = 0) + if(!computer) + return 0 + + if(istype(card,/obj/item/weapon/card/emag) && !reader) // emag reader slot + usr.visible_message("[computer]'s screen flickers for a moment.","You insert \the [card]. After a moment, the card ejects itself, and [computer] beeps.","[computer] beeps.") + computer.emagged = 1 + return 1 + + if(slot == 1) // 1: writer + if(writer != null) + usr << "There's already a card in that slot!" + return 0 + var/mob/living/L = usr + L.drop_item() + card.loc = src + writer = card + return 1 + else if(slot == 2) // 2: reader + if(reader != null) + usr << "There's already a card in that slot!" + return 0 + var/mob/living/L = usr + L.drop_item() + card.loc = src + reader = card + return 1 + else // 0: auto + if(reader && writer) + usr << "Both slots are full!" + return 0 + var/mob/living/L = usr + L.drop_item() + card.loc = src + if(reader) + writer = card + computer.updateUsrDialog() + return 1 + if(istype(card,/obj/item/weapon/card/id) && !(access_change_ids in card:access) && !writer) // not authorized + writer = card + computer.updateUsrDialog() + return 1 + if(!reader) + reader = card + computer.updateUsrDialog() + return 1 + return 0 + + remove(var/obj/item/weapon/card/card) + if(card != reader && card != writer) + return + + if(card == reader) reader = null + if(card == writer) writer = null + card.loc = loc + + var/mob/living/carbon/human/user = usr + if(ishuman(user) && !user.get_active_hand()) + user.put_in_hands(card) + + diff --git a/code/WorkInProgress/computer3/computer.dm b/code/WorkInProgress/computer3/computer.dm new file mode 100644 index 0000000000..48869571d1 --- /dev/null +++ b/code/WorkInProgress/computer3/computer.dm @@ -0,0 +1,446 @@ +/obj/machinery/computer3 + name = "computer" + icon = 'icons/obj/computer3.dmi' + icon_state = "frame" + density = 1 + anchored = 1.0 + + idle_power_usage = 20 + active_power_usage = 50 + + var/allow_disassemble = 1 + var/legacy_icon = 0 // if 1, use old style icons + var/show_keyboard = 1 + + // These is all you should need to change when creating a new computer. + // If there is no default program, the OS will run instead. + // If there is no hard drive, but there is a default program, the OS rom on + // the circuitboard will be overridden. + + // For these, typepaths are used, NOT objects + + var/default_prog = null // the program running when spawned + var/list/spawn_files = list() // files added when spawned + var/list/spawn_parts = list(/obj/item/part/computer/storage/hdd/big) // peripherals to spawn + + // Computer3 components - put an object in them in New() when not built + // I used to have a more pliable /list, but the ambiguities + // there in how many of what you had was killing me, especially + // when you had to search the list to find what you had. + + // Mostly decorative, holds the OS rom + var/obj/item/part/computer/circuitboard/circuit + + // Storage + var/obj/item/part/computer/storage/hdd/hdd = null + var/obj/item/part/computer/storage/removable/floppy = null + // Networking + var/obj/item/part/computer/networking/radio/radio = null // not handled the same as other networks + var/obj/item/part/computer/networking/cameras/camnet = null // just plain special + var/obj/item/part/computer/networking/net = null // Proximity, area, or cable network + + // Card reader - note the HoP reader is a subtype + var/obj/item/part/computer/cardslot/cardslot = null + + // Misc & special purpose + var/obj/item/part/computer/ai_holder/cradle = null + var/obj/item/part/computer/toybox/toybox = null + var/mob/living/silicon/ai/occupant = null + + + // Legacy variables + // camera networking - overview (???) + var/mapping = 0 + var/last_pic = 1.0 + + // Purely graphical effect + var/icon/kb = null + + // These are necessary in order to consolidate all computer types into one + var/datum/wires/wires = null + var/powernet = null + + // Used internally + var/datum/file/program/program = null // the active program (null if defaulting to os) + var/datum/file/program/os = null // the base code of the machine (os or hardcoded program) + + // If you want the computer to have a UPS, add a battery during construction. This is useful for things like + // the comms computer, solar trackers, etc, that should function when all else is off. + // Laptops will require batteries and have no mains power. + + var/obj/item/weapon/cell/battery = null // uninterruptible power supply aka battery + + + verb/ResetComputer() + set name = "Reset Computer" + set category = "Object" + set src in view(1) + Reset() + + New(var/L, var/built = 0) + ..() + spawn(2) + power_change() + + if(show_keyboard) + var/kb_state = "kb[rand(1,15)]" + kb = image('icons/obj/computer3.dmi',icon_state=kb_state) + overlays += kb + + if(!built) + if(!circuit || !istype(circuit)) + circuit = new(src) + if(circuit.OS) + os = circuit.OS + circuit.OS.computer = src + else + os = null + + // separated into its own function because blech + spawn_parts() + + if(default_prog) // Add the default software if applicable + var/datum/file/program/P = new default_prog + if(hdd) + hdd.addfile(P,1) + program = P + if(!os) + os = P + else if(floppy) + floppy.inserted = new(floppy) + floppy.files = floppy.inserted.files + floppy.addfile(P) + program = P + else + circuit.OS = P + circuit.OS.computer = src + os = circuit.OS + circuit.name = "Circuitboard ([P])" + + + if(hdd) // Spawn files + for(var/typekey in spawn_files) + hdd.addfile(new typekey,1) + + if(program) + program.execute(os) + update_icon() + + + + proc/spawn_parts() + for(var/typekey in spawn_parts) + + if(ispath(typekey,/obj/item/part/computer/storage/removable)) + if(floppy) continue + floppy = new typekey(src) + floppy.init(src) + continue + if(ispath(typekey,/obj/item/part/computer/storage/hdd)) + if(hdd) continue + hdd = new typekey(src) + hdd.init(src) + continue + + if(ispath(typekey,/obj/item/part/computer/networking/cameras)) + if(camnet) continue + camnet = new typekey(src) + camnet.init(src) + continue + if(ispath(typekey,/obj/item/part/computer/networking/radio)) + if(radio) continue + radio = new typekey(src) + radio.init(src) + continue + if(ispath(typekey,/obj/item/part/computer/networking)) + if(net) continue + net = new typekey(src) + net.init(src) + continue + + if(ispath(typekey,/obj/item/part/computer/cardslot)) + if(cardslot) continue + cardslot = new typekey(src) + cardslot.init(src) + continue + if(ispath(typekey,/obj/item/part/computer/ai_holder)) + if(cradle) continue + cradle = new typekey(src) + cradle.init(src) + if(ispath(typekey,/obj/item/part/computer/toybox)) + if(toybox) continue + toybox = new typekey(src) + toybox.init(src) + continue + + if(ispath(typekey,/obj/item/weapon/cell)) + if(battery) continue + battery = new typekey(src) + continue + + proc/Reset(var/error = 0) + for(var/mob/living/M in range(1)) + M << browse(null,"window=\ref[src]") + if(program) + program.Reset() + program = null + req_access = os.req_access + update_icon() + + // todo does this do enough + + + meteorhit(var/obj/O as obj) + for(var/x in verbs) + verbs -= x + set_broken() + return + + + emp_act(severity) + if(prob(20/severity)) set_broken() + ..() + + + ex_act(severity) + switch(severity) + if(1.0) + del(src) + return + if(2.0) + if (prob(25)) + del(src) + return + if (prob(50)) + for(var/x in verbs) + verbs -= x + set_broken() + if(3.0) + if (prob(25)) + for(var/x in verbs) + verbs -= x + set_broken() + else + return + + + blob_act() + if (prob(75)) + set_broken() + density = 0 + + /* + Computers have the capability to use a battery backup. + Note that auto_use_power's return value is strictly whether + or not it is successfully powered. + + This allows laptops, and also allows you to create computers that + remain active when: + + * the APC is destroy'd, emag'd, malf'd, emp'd, ninja'd etc + * the computer was built in an unpowered zone + * the station power is out, cables are cut, etc + + By default, most computers will NOT spawn with a battery backup, and + SHOULD not. Players can take apart a computer to insert the battery + if they want to ensure, for example, the AI upload remains when the + power is cut off. + + Make sure to use use_power() a bunch in peripherals code + */ + auto_use_power() + if(!powered(power_channel)) + if(battery && battery.charge > 0) + if(use_power == 1) + battery.use(idle_power_usage) + else + battery.use(active_power_usage) + return 1 + return 0 + if(src.use_power == 1) + use_power(idle_power_usage,power_channel) + else if(src.use_power >= 2) + use_power(active_power_usage,power_channel) + return 1 + + use_power(var/amount, var/chan = -1) + if(chan == -1) + chan = power_channel + + var/area/A = get_area(loc) + if(istype(A) && A.master && A.master.powered(chan)) + A.master.use_power(amount, chan) + else if(battery && battery.charge > 0) + battery.use(amount) + + power_change() + if( !powered(power_channel) && (!battery || battery.charge <= 0) ) + stat |= NOPOWER + else + stat &= ~NOPOWER + + process() + auto_use_power() + power_change() + update_icon() + if(stat & (NOPOWER|BROKEN)) + return + + if(program) + program.process() + return + + if(os) + program = os + os.process() + return + + + proc/set_broken() + icon_state = "computer_b" + stat |= BROKEN + crit_fail = 1 + if(program) + program.error = BUSTED_ASS_COMPUTER + if(os) + os.error = BUSTED_ASS_COMPUTER + + attackby(I as obj, mob/user as mob) + if(istype(I, /obj/item/weapon/screwdriver) && allow_disassemble) + disassemble(user) + return + + /* + +++++++++++ + |IMPORTANT| If you add a peripheral, put it in this list + +++++++++++ -------------------------------------------- + */ + var/list/peripherals = list(hdd,floppy,radio,net,cardslot,cradle) //camnet, toybox removed + + var/list/p_list = list() + for(var/obj/item/part/computer/C in peripherals) + if(!isnull(C) && C.allow_attackby(I,user)) + p_list += C + if(p_list.len) + var/obj/item/part/computer/P = null + if(p_list.len == 1) + P = p_list[1] + else + P = input(user,"Which component?") as null|anything in p_list + + if(P) + P.attackby(I,user) + return + ..() + + attack_hand(var/mob/user as mob) + if(stat) + Reset() + return + + // I don't want to deal with computers that you can't walk up to and use + // there is still cardauth anyway + //if(!allowed(user)) + // return + + if(program) + if(program.computer != src) // floppy disk may have been removed, etc + Reset() + attack_hand(user) + return + if(program.error) + Crash(program.error) + return + user.set_machine(src) + program.attack_hand(user) // will normally translate to program/interact() + return + + if(os) + program = os + user.set_machine(src) + os.attack_hand(user) + return + + user << "\The [src] won't boot!" + + attack_ai(var/mob/user as mob) // copypasta because server racks lose attack_hand() + if(stat) + Reset() + return + + if(program) + if(program.computer != src) // floppy disk may have been removed, etc + Reset() + attack_ai(user) + return + if(program.error) + Crash(program.error) + return + user.set_machine(src) + program.attack_hand(user) // will normally translate to program/interact() + return + + if(os) + program = os + user.set_machine(src) + os.attack_hand(user) + return + + user << "\The [src] won't boot!" + + interact() + if(stat) + Reset() + return + if(!allowed(usr) || !usr in view(1)) + usr.unset_machine() + return + + if(program) + program.interact() + return + + if(os) + program = os + os.interact() + return + + update_icon() + if(legacy_icon) + icon_state = initial(icon_state) + // Broken + if(stat & BROKEN) + icon_state += "b" + + // Powered + else if(stat & NOPOWER) + icon_state = initial(icon_state) + icon_state += "0" + return + if(stat) + overlays.Cut() + return + if(program) + overlays = list(program.overlay) + if(show_keyboard) + overlays += kb + name = "[program.name] [initial(name)]" + else if(os) + overlays = list(os.overlay) + if(show_keyboard) + overlays += kb + name = initial(name) + else + var/global/image/generic = image('icons/obj/computer3.dmi',icon_state="osod") // orange screen of death + overlays = list(generic) + if(show_keyboard) + overlays += kb + name = initial(name) + " (orange screen of death)" + +/obj/machinery/computer3/wall_comp + name = "terminal" + icon = 'icons/obj/computer3.dmi' + icon_state = "wallframe" + density = 0 + pixel_y = -3 + show_keyboard = 0 \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computer3_notes.dm b/code/WorkInProgress/computer3/computer3_notes.dm new file mode 100644 index 0000000000..f0d0bd5028 --- /dev/null +++ b/code/WorkInProgress/computer3/computer3_notes.dm @@ -0,0 +1,34 @@ +/* + 1. Do NOT confuse Computer.Crash(errorcode) with byond CRASH(message) + 2 Do NOT talk about fight club. + 3 If this if your first night here, you have to crash the computer. + 4 Where am I? + 5 Someone help me, please... + 6. Be sure to use computer.use_power() appropriately. Laptops should run out of battery occasionally. + 7 Everyone fights, no-one quits. If you don't do your job, I'll crash you myself. + 6 Don't allow more than 42 angels to dance on the head of a pin. + 5. Once a computer has spawned, they are just like the rest, except when they aren't. + 4 Get me four glasses of apple juice. + 3. Components are only added or removed when disassembled and rebuilt. However, they may be EMP'd. + 2 Only you can prevent friendly fire. + 1 Do not talk about fight club. + 2. If a component subtype needs to be handled separately (removable drives, radio networks), declare it separately. + 3 Television rules the nation + 4. interactable() does all the sanity checks, adds fingerprints, sets machines, initializes popup, and makes a damn fine pot of coffee. + 5 Love conquers all. + 6 If at all possible, do a barrel roll. + 7. Don't forget to use the network verify function to make sure you still have access to remote machines. + + + + + TODO: + * "Nothing left to call the shuttle" check + * Communications terminal printing - move it to a printer of some sort? Make a printer peripheral--but then which ones print the comms? + * Remove the partially transparent border on program screens, as it clashes with some frames + * Chop the corners on program screens now that screen sizes are standard + * NTOS: + * Needs a text editor/viewer + * Needs file copy and file move - I think I know how I'm gonna do it + * Needs a peripheral view (eject disks and cards, network actions, ???) +*/ \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/HolodeckControl.dm b/code/WorkInProgress/computer3/computers/HolodeckControl.dm new file mode 100644 index 0000000000..e650185f85 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/HolodeckControl.dm @@ -0,0 +1,254 @@ +/obj/machinery/computer3/HolodeckControl + default_prog = /datum/file/program/holodeck + + +// Todo: I personally would like to add a second holodeck in the theater for making appropriate playgrounds. +// perhaps a holodeck association keyfile? +// One more thing while I'm here +// C3 allows multiple computers to run this program, but it was designed on the assumption that only one would, ever +// I am not going to add or remove anything right now, I'm just porting it + + +/datum/file/program/holodeck + name = "Holodeck Control Console" + desc = "Used to control a nearby holodeck." + active_state = "holocontrol" + var/area/linkedholodeck = null + var/area/target = null + var/active = 0 + var/list/holographic_items = list() + var/damaged = 0 + var/last_change = 0 + var/emagged = 0 + + + interact() + if(!interactable()) + return + var/dat = "

Current Loaded Programs

" + dat += "((Empty Court))
" + dat += "((Boxing Court))
" + dat += "((Basketball Court))
" + dat += "((Thunderdome Court))
" + dat += "((Beach))
" +// dat += "((Shutdown System))
" + + dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
" + + if(emagged) + dat += "(Begin Atmospheric Burn Simulation)
" + dat += "Ensure the holodeck is empty before testing.
" + dat += "
" + dat += "(Begin Wildlife Simulation)
" + dat += "Ensure the holodeck is empty before testing.
" + dat += "
" + if(issilicon(usr)) + dat += "(Re-Enable Safety Protocols?)
" + dat += "Safety Protocols are DISABLED
" + else + if(issilicon(usr)) + dat += "(Override Safety Protocols?)
" + dat += "
" + dat += "Safety Protocols are ENABLED
" + + popup.set_content(dat) + popup.open() + return + + + Topic(var/href, var/list/href_list) + if(!interactable() || ..(href,href_list)) + return + + if("emptycourt" in href_list) + target = locate(/area/holodeck/source_emptycourt) + if(target) + loadProgram(target) + + else if("boxingcourt" in href_list) + target = locate(/area/holodeck/source_boxingcourt) + if(target) + loadProgram(target) + + else if("basketball" in href_list) + target = locate(/area/holodeck/source_basketball) + if(target) + loadProgram(target) + + else if("thunderdomecourt" in href_list) + target = locate(/area/holodeck/source_thunderdomecourt) + if(target) + loadProgram(target) + + else if("beach" in href_list) + target = locate(/area/holodeck/source_beach) + if(target) + loadProgram(target) + + else if("turnoff" in href_list) + target = locate(/area/holodeck/source_plating) + if(target) + loadProgram(target) + + else if("burntest" in href_list) + if(!emagged) return + target = locate(/area/holodeck/source_burntest) + if(target) + loadProgram(target) + + else if("wildlifecarp" in href_list) + if(!emagged) return + target = locate(/area/holodeck/source_wildlife) + if(target) + loadProgram(target) + + else if("AIoverride" in href_list) + if(!issilicon(usr)) return + emagged = !emagged + if(emagged) + message_admins("[key_name_admin(usr)] overrode the holodeck's safeties") + log_game("[key_name(usr)] overrided the holodeck's safeties") + else + message_admins("[key_name_admin(usr)] restored the holodeck's safeties") + log_game("[key_name(usr)] restored the holodeck's safeties") + + interact() + return + + Reset() + emergencyShutdown() + + process() + if(active) + if(!checkInteg(linkedholodeck)) + damaged = 1 + target = locate(/area/holodeck/source_plating) + if(target) + loadProgram(target) + active = 0 + for(var/mob/M in range(10,src)) + M.show_message("The holodeck overloads!") + + + for(var/turf/T in linkedholodeck) + if(prob(30)) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, T) + s.start() + T.ex_act(3) + T.hotspot_expose(1000,500,1) + + + for(var/item in holographic_items) + if(!(get_turf(item) in linkedholodeck)) + derez(item, 0) + + + + proc/derez(var/obj/obj , var/silent = 1) + holographic_items.Remove(obj) + + if(obj == null) + return + + if(isobj(obj)) + var/mob/M = obj.loc + if(ismob(M)) + M.u_equip(obj) + M.update_icons() //so their overlays update + + if(!silent) + var/obj/oldobj = obj + obj.visible_message("The [oldobj.name] fades away!") + del(obj) + + proc/checkInteg(var/area/A) + for(var/turf/T in A) + if(istype(T, /turf/space)) + return 0 + + return 1 + + proc/togglePower(var/toggleOn = 0) + + if(toggleOn) + var/area/targetsource = locate(/area/holodeck/source_emptycourt) + holographic_items = targetsource.copy_contents_to(linkedholodeck) + + spawn(30) + for(var/obj/effect/landmark/L in linkedholodeck) + if(L.name=="Atmospheric Test Start") + spawn(20) + var/turf/T = get_turf(L) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, T) + s.start() + if(T) + T.temperature = 5000 + T.hotspot_expose(50000,50000,1) + + active = 1 + else + for(var/item in holographic_items) + derez(item) + var/area/targetsource = locate(/area/holodeck/source_plating) + targetsource.copy_contents_to(linkedholodeck , 1) + active = 0 + + + proc/loadProgram(var/area/A) + + if(world.time < (last_change + 25)) + if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve + return + for(var/mob/M in range(3,src)) + M.show_message("\b ERROR. Recalibrating projetion apparatus.") + last_change = world.time + return + + last_change = world.time + active = 1 + + for(var/item in holographic_items) + derez(item) + + for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck) + del(B) + + for(var/mob/living/simple_animal/hostile/carp/C in linkedholodeck) + del(C) + + holographic_items = A.copy_contents_to(linkedholodeck , 1) + + if(emagged) + for(var/obj/item/weapon/holo/esword/H in linkedholodeck) + H.damtype = BRUTE + + spawn(30) + for(var/obj/effect/landmark/L in linkedholodeck) + if(L.name=="Atmospheric Test Start") + spawn(20) + var/turf/T = get_turf(L) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, T) + s.start() + if(T) + T.temperature = 5000 + T.hotspot_expose(50000,50000,1) + if(L.name=="Holocarp Spawn") + new /mob/living/simple_animal/hostile/carp(L.loc) + + + proc/emergencyShutdown() + //Get rid of any items + for(var/item in holographic_items) + derez(item) + //Turn it back to the regular non-holographic room + target = locate(/area/holodeck/source_plating) + if(target) + loadProgram(target) + + var/area/targetsource = locate(/area/holodeck/source_plating) + targetsource.copy_contents_to(linkedholodeck , 1) + active = 0 + diff --git a/code/WorkInProgress/computer3/computers/Operating.dm b/code/WorkInProgress/computer3/computers/Operating.dm new file mode 100644 index 0000000000..0f989780d7 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/Operating.dm @@ -0,0 +1,47 @@ +/obj/machinery/computer3/operating + default_prog = /datum/file/program/op_monitor + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/prox) + icon_state = "frame-med" + +/datum/file/program/op_monitor + name = "operating table monitor" + desc = "Monitors patient status during surgery." + active_state = "operating" + var/mob/living/carbon/human/patient = null + var/obj/machinery/optable/table = null + + +/datum/file/program/op_monitor/interact() + if(!interactable()) + return + if(!computer.net) + computer.Crash(MISSING_PERIPHERAL) + return + table = computer.net.connect_to(/obj/machinery/optable,table) + + var/dat = "" + if(table) + dat += "Patient information:
" + if(src.table && (src.table.check_victim())) + src.patient = src.table.victim + dat += {"Patient Status: [patient.stat ? "Non-Responsive" : "Stable"]
+ Blood Type: [patient.b_type]
+
+ Health: [round(patient.health)]
+ Brute Damage: [round(patient.getBruteLoss())]
+ Toxins Damage: [round(patient.getToxLoss())]
+ Fire Damage: [round(patient.getFireLoss())]
+ Suffocation Damage: [round(patient.getOxyLoss())]
+ "} + else + src.patient = null + dat += "No patient detected" + else + dat += "Operating table not found." + + popup.set_content(dat) + popup.open() +/datum/file/program/op_monitor/Topic() + if(!interactable()) + return + ..() \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/aifixer.dm b/code/WorkInProgress/computer3/computers/aifixer.dm new file mode 100644 index 0000000000..45790c50a7 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/aifixer.dm @@ -0,0 +1,117 @@ +/obj/machinery/computer3/aifixer + default_prog = /datum/file/program/aifixer + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/ai_holder) + icon_state = "frame-rnd" + + +/datum/file/program/aifixer + name = "AI system integrity restorer" + desc = "Repairs and revives artificial intelligence cores." + image = 'icons/NTOS/airestore.png' + active_state = "ai-fixer-empty" + req_access = list(access_captain, access_robotics, access_heads) + + update_icon() + if(!computer || !computer.cradle) + overlay.icon_state = "ai-fixer-404" + return // what + + if(!computer.cradle.occupant) + overlay.icon_state = "ai-fixer-empty" + else + if (computer.cradle.occupant.health >= 0 && computer.cradle.occupant.stat != 2) + overlay.icon_state = "ai-fixer-full" + else + overlay.icon_state = "ai-fixer-404" + computer.update_icon() + + interact() + if(!interactable()) + return + + if(!computer.cradle) + computer.Crash(MISSING_PERIPHERAL) + return + + popup.set_content(aifixer_menu()) + popup.open() + return + + proc/aifixer_menu() + var/dat = "" + if (computer.cradle.occupant) + var/laws + dat += "

Stored AI: [computer.cradle.occupant.name]

" + dat += "System integrity: [(computer.cradle.occupant.health+100)/2]%
" + + if (computer.cradle.occupant.laws.zeroth) + laws += "0: [computer.cradle.occupant.laws.zeroth]
" + + var/number = 1 + for (var/index = 1, index <= computer.cradle.occupant.laws.inherent.len, index++) + var/law = computer.cradle.occupant.laws.inherent[index] + if (length(law) > 0) + laws += "[number]: [law]
" + number++ + + for (var/index = 1, index <= computer.cradle.occupant.laws.supplied.len, index++) + var/law = computer.cradle.occupant.laws.supplied[index] + if (length(law) > 0) + laws += "[number]: [law]
" + number++ + + dat += "Laws:
[laws]
" + + if (computer.cradle.occupant.stat == 2) + dat += "AI non-functional" + else + dat += "AI functional" + if (!computer.cradle.busy) + dat += "

[topic_link(src,"fix","Begin Reconstruction")]" + else + dat += "

Reconstruction in process, please wait.
" + dat += "
[topic_link(src,"close","Close")]" + return dat + + Topic(var/href, var/list/href_list) + if(!interactable() || !computer.cradle || ..(href,href_list)) + return + + if ("fix" in href_list) + var/mob/living/silicon/ai/occupant = computer.cradle.occupant + if(!occupant) return + + computer.cradle.busy = 1 + computer.overlays += image('icons/obj/computer.dmi', "ai-fixer-on") + + var/i = 0 + while (occupant.health < 100) + if(!computer || (computer.stat&~MAINT)) // takes some time, keep checking + break + + occupant.adjustOxyLoss(-1) + occupant.adjustFireLoss(-1) + occupant.adjustToxLoss(-1) + occupant.adjustBruteLoss(-1) + occupant.updatehealth() + if (occupant.health >= 0 && computer.cradle.occupant.stat == 2) + occupant.stat = 0 + occupant.lying = 0 + dead_mob_list -= occupant + living_mob_list += occupant + update_icon() + + i++ + if(i == 5) + computer.use_power(50) // repairing an AI is nontrivial. laptop battery may not be enough. + computer.power_change() // if the power runs out, set stat + i = 0 + + computer.updateUsrDialog() + + sleep(10) + computer.cradle.busy = 0 + computer.overlays -= image('icons/obj/computer.dmi', "ai-fixer-on") + + computer.updateUsrDialog() + return diff --git a/code/WorkInProgress/computer3/computers/arcade.dm b/code/WorkInProgress/computer3/computers/arcade.dm new file mode 100644 index 0000000000..746551079b --- /dev/null +++ b/code/WorkInProgress/computer3/computers/arcade.dm @@ -0,0 +1,180 @@ +/obj/machinery/computer3/arcade + default_prog = /datum/file/program/arcade + spawn_parts = list(/obj/item/part/computer/toybox) //NO HDD - the game is loaded on the circuitboard's OS slot + +/obj/item/part/computer/toybox + var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, + /obj/item/toy/blink = 2, + /obj/item/clothing/under/syndicate/tacticool = 2, + /obj/item/toy/sword = 2, + /obj/item/toy/gun = 2, + /obj/item/toy/crossbow = 2, + /obj/item/clothing/suit/syndicatefake = 2, + /obj/item/weapon/storage/fancy/crayons = 2, + /obj/item/toy/spinningtoy = 2, + /obj/item/toy/prize/ripley = 1, + /obj/item/toy/prize/fireripley = 1, + /obj/item/toy/prize/deathripley = 1, + /obj/item/toy/prize/gygax = 1, + /obj/item/toy/prize/durand = 1, + /obj/item/toy/prize/honk = 1, + /obj/item/toy/prize/marauder = 1, + /obj/item/toy/prize/seraph = 1, + /obj/item/toy/prize/mauler = 1, + /obj/item/toy/prize/odysseus = 1, + /obj/item/toy/prize/phazon = 1 + ) + proc/dispense() + if(computer && !computer.stat) + var/prizeselect = pickweight(prizes) + new prizeselect(computer.loc) + if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun + new /obj/item/toy/ammo/gun(computer.loc) + else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit + new /obj/item/clothing/head/syndicatefake(computer.loc) + feedback_inc("arcade_win_normal") + computer.use_power(500) + + +/datum/file/program/arcade + desc = "The best arcade game ever produced by Nanotrasen's short-lived entertainment divison." + //headcanon: they also ported E.T. for the atari 2600, superman 64, and basically every other movie tie-in game ever + + active_state = "generic" + + var/turtle = 0 + var/enemy_name = "Space Villian" + var/temp = "Winners Don't Use Spacedrugs" //Temporary message, for attack messages, etc + var/player_hp = 30 //Player health/attack points + var/player_mp = 10 + var/enemy_hp = 45 //Enemy health/attack points + var/enemy_mp = 20 + var/gameover = 0 + var/blocked = 0 //Player cannot attack/heal while set + +/datum/file/program/arcade/New() + ..() + var/name_action + var/name_part1 + var/name_part2 + + name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "ERP ") + + name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") + name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn") + + enemy_name = replacetext(name_part1, "the ", "") + name_part2 + name = (name_action + name_part1 + name_part2) + + +/datum/file/program/arcade/interact() + if(!interactable()) + return + var/dat// = topic_link(src,"close","Close") + dat = "

[enemy_name]

" + + dat += "

[temp]

" + dat += "
Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]
" + + if (gameover) + dat += "
[topic_link(src,"newgame","New Game")]" + else + dat += "
[topic_link(src,"attack","Attack")] | [topic_link(src,"heal","Heal")] | [topic_link(src,"charge","Recharge Power")]" + + dat += "
" + + popup.set_content(dat) + popup.open() + +/datum/file/program/arcade/Topic(href, list/href_list) + if(!interactable() || ..(href,href_list)) + return + if (!blocked && !gameover) + if ("attack" in href_list) + blocked = 1 + var/attackamt = rand(2,6) + temp = "You attack for [attackamt] damage!" + computer.updateUsrDialog() + if(turtle > 0) + turtle-- + + sleep(10) + enemy_hp -= attackamt + arcade_action() + + else if ("heal" in href_list) + blocked = 1 + var/pointamt = rand(1,3) + var/healamt = rand(6,8) + temp = "You use [pointamt] magic to heal for [healamt] damage!" + computer.updateUsrDialog() + turtle++ + + sleep(10) + player_mp -= pointamt + player_hp += healamt + blocked = 1 + computer.updateUsrDialog() + arcade_action() + + else if ("charge" in href_list) + blocked = 1 + var/chargeamt = rand(4,7) + temp = "You regain [chargeamt] points" + player_mp += chargeamt + if(turtle > 0) + turtle-- + + computer.updateUsrDialog() + sleep(10) + arcade_action() + + if ("newgame" in href_list) //Reset everything + temp = "New Round" + player_hp = 30 + player_mp = 10 + enemy_hp = 45 + enemy_mp = 20 + gameover = 0 + turtle = 0 + computer.updateUsrDialog() + + +/datum/file/program/arcade/proc/arcade_action() + if ((enemy_mp <= 0) || (enemy_hp <= 0)) + if(!gameover) + gameover = 1 + temp = "[enemy_name] has fallen! Rejoice!" + if(computer.toybox) + computer.toybox.dispense() + + else if ((enemy_mp <= 5) && (prob(70))) + var/stealamt = rand(2,3) + temp = "[enemy_name] steals [stealamt] of your power!" + player_mp -= stealamt + + if (player_mp <= 0) + gameover = 1 + sleep(10) + temp = "You have been drained! GAME OVER" + feedback_inc("arcade_loss_mana_normal") + + else if ((enemy_hp <= 10) && (enemy_mp > 4)) + temp = "[enemy_name] heals for 4 health!" + enemy_hp += 4 + enemy_mp -= 4 + + else + var/attackamt = rand(3,6) + temp = "[enemy_name] attacks for [attackamt] damage!" + player_hp -= attackamt + + if ((player_mp <= 0) || (player_hp <= 0)) + gameover = 1 + temp = "You have been crushed! GAME OVER" + feedback_inc("arcade_loss_hp_normal") + + if(interactable()) + computer.updateUsrDialog() + blocked = 0 + return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/atmos_alert.dm b/code/WorkInProgress/computer3/computers/atmos_alert.dm new file mode 100644 index 0000000000..6596b76d7c --- /dev/null +++ b/code/WorkInProgress/computer3/computers/atmos_alert.dm @@ -0,0 +1,110 @@ +/obj/machinery/computer3/atmos_alert + default_prog = /datum/file/program/atmos_alert + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) + icon_state = "frame-eng" + +/datum/file/program/atmos_alert + name = "atmospheric alert monitor" + desc = "Recieves alerts over the radio." + active_state = "alert:2" + refresh = 1 + var/list/priority_alarms = list() + var/list/minor_alarms = list() + + + execute(var/datum/file/program/source) + ..(source) + + if(!computer.radio) + computer.Crash(MISSING_PERIPHERAL) + + computer.radio.set_frequency(1437,RADIO_ATMOSIA) + + + Reset() + ..() + // Never save your work + priority_alarms.Cut() + minor_alarms.Cut() + + + // This will be called as long as the program is running on the parent computer + // and the computer has the radio peripheral + receive_signal(datum/signal/signal) + if(!signal || signal.encryption) return + + var/zone = signal.data["zone"] + var/severity = signal.data["alert"] + if(!zone || !severity) return + + minor_alarms -= zone + priority_alarms -= zone + if(severity=="severe") + priority_alarms += zone + else if (severity=="minor") + minor_alarms += zone + update_icon() + return + + + interact() + if(!interactable()) + return + if(!computer.radio) + computer.Crash(MISSING_PERIPHERAL) + + popup.set_content(return_text()) + popup.open() + + + update_icon() + ..() + if(priority_alarms.len > 0) + overlay.icon_state = "alert:2" + else if(minor_alarms.len > 0) + overlay.icon_state = "alert:1" + else + overlay.icon_state = "alert:0" + + if(computer) + computer.update_icon() + + + proc/return_text() + var/priority_text = "

Priority Alerts:

" + var/minor_text = "

Minor Alerts:

" + + if(priority_alarms.len) + for(var/zone in priority_alarms) + priority_text += "[format_text(zone)] [topic_link(src,"priority_clear=[ckey(zone)]","X")]
" + else + priority_text += "No priority alerts detected.
" + + if(minor_alarms.len) + for(var/zone in minor_alarms) + minor_text += "[format_text(zone)] [topic_link(src,"minor_clear=[ckey(zone)]","X")]
" + else + minor_text += "No minor alerts detected.
" + + return "[priority_text]

[minor_text]
[topic_link(src,"close","Close")]" + + + Topic(var/href, var/list/href_list) + if(!interactable() || ..(href,href_list)) + return + + if("priority_clear" in href_list) + var/removing_zone = href_list["priority_clear"] + for(var/zone in priority_alarms) + if(ckey(zone) == removing_zone) + usr << "\green Priority Alert for area [zone] cleared." + priority_alarms -= zone + + if("minor_clear" in href_list) + var/removing_zone = href_list["minor_clear"] + for(var/zone in minor_alarms) + if(ckey(zone) == removing_zone) + usr << "\green Minor Alert for area [zone] cleared." + minor_alarms -= zone + + computer.updateUsrDialog() diff --git a/code/WorkInProgress/computer3/computers/camera.dm b/code/WorkInProgress/computer3/computers/camera.dm new file mode 100644 index 0000000000..17e639166d --- /dev/null +++ b/code/WorkInProgress/computer3/computers/camera.dm @@ -0,0 +1,277 @@ +/* + Camera monitoring computers + + NOTE: If we actually split the station camera network into regions that will help with sorting through the + tediously large list of cameras. The new camnet_key architecture lets you switch between keys easily, + so you don't lose the capability of seeing everything, you just switch to a subnet. +*/ + +/obj/machinery/computer3/security + default_prog = /datum/file/program/security + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/cameras) + spawn_files = list(/datum/file/camnet_key) + icon_state = "frame-sec" + + +/obj/machinery/computer3/security/wooden_tv + name = "security cameras" + desc = "An old TV hooked into the stations camera network." + icon = 'icons/obj/computer.dmi' + icon_state = "security_det" + + legacy_icon = 1 + allow_disassemble = 0 + + // No operating system + New() + ..(built=0) + os = program + circuit.OS = os + + +/obj/machinery/computer3/security/mining + name = "Outpost Cameras" + desc = "Used to access the various cameras on the outpost." + spawn_files = list(/datum/file/camnet_key/mining) + +/* + Camera monitoring computers, wall-mounted +*/ +/obj/machinery/computer3/wall_comp/telescreen + default_prog = /datum/file/program/security + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/cameras) + spawn_files = list(/datum/file/camnet_key) + +/obj/machinery/computer3/wall_comp/telescreen/entertainment + desc = "Damn, they better have /tg/thechannel on these things." + spawn_files = list(/datum/file/camnet_key/entertainment) + + +/* + File containing an encrypted camera network key. + + (Where by encrypted I don't actually mean encrypted at all) +*/ +/datum/file/camnet_key + name = "Security Camera Network Main Key" + var/title = "Station" + var/desc = "Connects to station security cameras." + var/list/networks = list("SS13") + var/screen = "cameras" + + execute(var/datum/file/source) + if(istype(source,/datum/file/program/security)) + var/datum/file/program/security/prog = source + prog.key = src + prog.camera_list = null + return + if(istype(source,/datum/file/program/NTOS)) + for(var/obj/item/part/computer/storage/S in list(computer.hdd,computer.floppy)) + for(var/datum/file/F in S.files) + if(istype(F,/datum/file/program/security)) + var/datum/file/program/security/Sec = F + Sec.key = src + Sec.camera_list = null + Sec.execute(source) + return + computer.Crash(MISSING_PROGRAM) + +/datum/file/camnet_key/mining + name = "Mining Camera Network Key" + title = "mining station" + desc = "Connects to mining security cameras." + networks = list("MINE") + screen = "miningcameras" + +/datum/file/camnet_key/research + name = "Research Camera Network Key" + title = "research" + networks = list("RD") + +/datum/file/camnet_key/bombrange + name = "R&D Bomb Range Camera Network Key" + title = "bomb range" + desc = "Monitors the bomb range." + networks = list("Toxins") + +/datum/file/camnet_key/xeno + name = "R&D Misc. Research Camera Network Key" + title = "special research" + networks = list("Misc") + +/datum/file/camnet_key/singulo + name = "Singularity Camera Network Key" + title = "singularity" + networks = list("Singularity") + +/datum/file/camnet_key/entertainment + name = "Entertainment Channel Encryption Key" + title = "entertainment" + desc = "Damn, I hope they have /tg/thechannel on here." + networks = list("thunder") + screen = "entertainment" + +/datum/file/camnet_key/creed + name = "Special Ops Camera Encryption Key" + title = "special ops" + desc = "Connects to special ops secure camera feeds." + networks = list("CREED") + +/datum/file/camnet_key/prison + name = "Prison Camera Network Key" + title = "prison" + desc = "Monitors the prison." + networks = list("Prison") + + + +/* + Computer part needed to connect to cameras +*/ + +/obj/item/part/computer/networking/cameras + name = "camera network access module" + desc = "Connects a computer to the camera network." + + // I have no idea what the following does + var/mapping = 0//For the overview file, interesting bit of code. + + //proc/camera_list(var/datum/file/camnet_key/key) + get_machines(var/datum/file/camnet_key/key) + if (!computer || computer.z > 6) + return null + + var/list/L = list() + for(var/obj/machinery/camera/C in cameranet.cameras) + var/list/temp = C.network & key.networks + if(temp.len) + L.Add(C) + + //camera_sort(L) + + return L + verify_machine(var/obj/machinery/camera/C,var/datum/file/camnet_key/key = null) + if(!istype(C) || !C.can_use()) + return 0 + + if(key) + var/list/temp = C.network & key.networks + if(!temp.len) + return 0 + return 1 + +/* + Camera monitoring program + + The following things should break you out of the camera view: + * The computer resetting, being damaged, losing power, etc + * The program quitting + * Closing the window + * Going out of range of the computer + * Becoming incapacitated + * The camera breaking, emping, disconnecting, etc +*/ + +/datum/file/program/security + name = "camera monitor" + desc = "Connets to the Nanotrasen Camera Network" + image = 'icons/NTOS/camera.png' + active_state = "camera-static" + + var/datum/file/camnet_key/key = null + var/last_pic = 1.0 + var/last_camera_refresh = 0 + var/camera_list = null + + var/obj/machinery/camera/current = null + + execute(var/datum/file/program/caller) + ..(caller) + if(computer && !key) + var/list/fkeys = computer.list_files(/datum/file/camnet_key) + if(fkeys && fkeys.len) + key = fkeys[1] + update_icon() + computer.update_icon() + for(var/mob/living/L in viewers(1)) + if(!istype(L,/mob/living/silicon/ai) && L.machine == src) + L.reset_view(null) + + + Reset() + ..() + current = null + for(var/mob/living/L in viewers(1)) + if(!istype(L,/mob/living/silicon/ai) && L.machine == src) + L.reset_view(null) + + interact() + if(!interactable()) + return + + if(!computer.camnet) + computer.Crash(MISSING_PERIPHERAL) + return + + if(!key) + var/list/fkeys = computer.list_files(/datum/file/camnet_key) + if(fkeys && fkeys.len) + key = fkeys[1] + update_icon() + computer.update_icon() + if(!key) + return + + if(computer.camnet.verify_machine(current)) + usr.reset_view(current) + + if(world.time - last_camera_refresh > 50 || !camera_list) + last_camera_refresh = world.time + + var/list/temp_list = computer.camnet.get_machines(key) + + camera_list = "Network Key: [key.title] [topic_link(src,"keyselect","\[ Select key \]")]
" + for(var/obj/machinery/camera/C in temp_list) + if(C.status) + camera_list += "[C.c_tag] - [topic_link(src,"show=\ref[C]","Show")]
" + else + camera_list += "[C.c_tag] - DEACTIVATED
" + //camera_list += "
" + topic_link(src,"close","Close") + + popup.set_content(camera_list) + popup.open() + + + update_icon() + if(key) + overlay.icon_state = key.screen + name = key.title + " Camera Monitor" + else + overlay.icon_state = "camera-static" + name = initial(name) + + + + Topic(var/href,var/list/href_list) + if(!interactable() || !computer.camnet || ..(href,href_list)) + return + + if("show" in href_list) + var/obj/machinery/camera/C = locate(href_list["show"]) + current = C + usr.reset_view(C) + interact() + return + + if("keyselect" in href_list) + current = null + usr.reset_view(null) + key = input(usr,"Select a camera network key:", "Key Select", null) as null|anything in computer.list_files(/datum/file/camnet_key) + camera_list = null + update_icon() + computer.update_icon() + if(key) + interact() + else + usr << "The screen turns to static." + return diff --git a/code/WorkInProgress/computer3/computers/card.dm b/code/WorkInProgress/computer3/computers/card.dm new file mode 100644 index 0000000000..00e51778a3 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/card.dm @@ -0,0 +1,289 @@ +/obj/machinery/computer3/card + default_prog = /datum/file/program/card_comp + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot/dual) +/obj/machinery/computer3/card/hop + default_prog = /datum/file/program/card_comp + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot/dual) + spawn_files = list(/datum/file/program/arcade, /datum/file/program/security, /datum/file/camnet_key/mining, /datum/file/camnet_key/entertainment,/datum/file/camnet_key/prison) + + +/obj/machinery/computer3/card/centcom + default_prog = /datum/file/program/card_comp/centcom + +/datum/file/program/card_comp + name = "identification card console" + desc = "Used to modify magnetic strip ID cards." + image = 'icons/NTOS/cardcomp.png' + active_state = "id" + + var/obj/item/weapon/card/id/reader = null + var/obj/item/weapon/card/id/writer = null + + var/mode = 0 + var/auth = 0 + var/printing = 0 + + proc/list_jobs() + return get_all_jobs() + "Custom" + + // creates the block with the script in it + // cache the result since it's almost constant but not quite + // the list of jobs won't change after all... + proc/scriptblock() + var/global/dat = null + if(!dat) + var/jobs_all = "" + for(var/job in list_jobs()) + jobs_all += topic_link(src,"assign=[job]",replacetext(job," "," ")) + " "//make sure there isn't a line break in the middle of a job + dat = {""} + return dat + + // creates the list of access rights on the card + proc/accessblock() + var/accesses = "
Access
" + accesses += "" + accesses += "" + for(var/i = 1; i <= 7; i++) + accesses += "" + accesses += "" + for(var/i = 1; i <= 7; i++) + accesses += "" + accesses += "
[get_region_accesses_name(i)]:
" + for(var/A in get_region_accesses(i)) + if(A in writer.access) + accesses += topic_link(src,"access=[A]","[replacetext(get_access_desc(A), " ", " ")]") + " " + else + accesses += topic_link(src,"access=[A]",replacetext(get_access_desc(A), " ", " ")) + " " + accesses += "
" + accesses += "
" + return accesses + + proc/card_modify_menu() + //assume peripherals and cards, do checks for them in interact + + // Header + var/dat = "

" + dat += topic_link(src,"remove=writer","Remove [writer.name]") + " || " + dat += topic_link(src,"remove=reader","Remove [reader.name]") + "
" + dat += topic_link(src,"mode=1","Access Crew Manifest") + " || " + dat += topic_link(src,"logout","Log Out") + "
" + dat += "
" + scriptblock() + + // form for renaming the ID + dat += "
" + dat += "" + dat += "registered_name: " + dat += "" + dat += "
" + + // form for changing assignment, taken care of by scriptblock() mostly + var/assign_temp = writer.assignment + if(!assign_temp || assign_temp == "") assign_temp = "Unassigned" + dat += "Assignment: [assign_temp] change" + + // list of access rights + dat += accessblock() + + return dat + + proc/login_menu() + //assume peripherals and cards, do checks for them in interact + var/dat = "
Please insert the cards into the slots
" + + if(istype(writer)) + dat += "Target: [topic_link(src,"remove=writer",writer.name)]
" + else + dat += "Target: [topic_link(src,"insert=writer","--------")]
" + + if(istype(reader)) + dat += "Confirm Identity: [topic_link(src,"remove=reader",reader.name)]
" + else + dat += "Confirm Identity: [topic_link(src,"insert=reader","--------")]
" + dat += "[topic_link(src,"auth","{Log in}")]

" + dat += topic_link(src,"mode=1","Access Crew Manifest") + return dat + + proc/show_manifest() + // assume linked_db since called by interact() + var/crew = "" + var/list/L = list() + for (var/datum/data/record/t in data_core.general) + var/R = t.fields["name"] + " - " + t.fields["rank"] + L += R + for(var/R in sortList(L)) + crew += "[R]
" + return "Crew Manifest:
Please use security record computer to modify entries.

[crew][topic_link(src,"print","Print")]

[topic_link(src,"mode=0","Access ID modification console.")]
" + + // These are here partly in order to be overwritten by the centcom card computer code + proc/authenticate() + if(access_change_ids in reader.access) + return 1 + if(istype(usr,/mob/living/silicon/ai)) + return 1 + return 0 + + proc/set_default_access(var/jobname) + var/datum/job/jobdatum + for(var/jobtype in typesof(/datum/job)) + var/datum/job/J = new jobtype + if(ckey(J.title) == ckey(jobname)) + jobdatum = J + break + if(jobdatum) + writer.access = jobdatum.get_access() // ( istype(src,/obj/machinery/computer/card/centcom) ? get_centcom_access(t1) + + + interact() + if(!interactable()) return + + if(!computer.cardslot || !computer.cardslot.dualslot) + computer.Crash(MISSING_PERIPHERAL) + return + + reader = computer.cardslot.reader + writer = computer.cardslot.writer + + var/dat + + switch(mode) + if(0) + if( !istype(writer) || !istype(reader) ) + auth = 0 + if( !auth ) + dat = login_menu() + else + dat = card_modify_menu() + if(1) + dat = show_manifest() + + + popup = new(usr, "ID Computer", name, 940, 520) + popup.set_content(dat) + popup.open() + return + + + Topic(href, list/href_list) + if(!interactable() || !computer.cardslot || ..(href,href_list)) + return + // todo distance/disability checks + + if("mode" in href_list) + mode = text2num(href_list["mode"]) + if(mode != 0 && mode != 1) + mode = 0 + + auth = 0 // always log out if switching modes just in case + + if("remove" in href_list) + var/which = href_list["remove"] + if(which == "writer") + computer.cardslot.remove(computer.cardslot.writer) + else + computer.cardslot.remove(computer.cardslot.reader) + auth = 0 + + if("insert" in href_list) + var/obj/item/weapon/card/card = usr.get_active_hand() + if(!istype(card)) return + + var/which = href_list["insert"] + if(which == "writer") + computer.cardslot.insert(card,1) + else + computer.cardslot.insert(card,2) + + if("print" in href_list) + if (printing) + return + + printing = 1 + sleep(50) + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( computer.loc ) + P.info = "Crew Manifest:
" + var/list/L = list() + for (var/datum/data/record/t in data_core.general) + var/R = t.fields["name"] + " - " + t.fields["rank"] + L += R + for(var/R in sortList(L)) + P.info += "[R]
" + P.name = "paper- 'Crew Manifest'" + printing = 0 + + if("auth" in href_list) + auth = 0 + if(istype(reader) && istype(writer) && authenticate()) + auth = 1 + + if("logout" in href_list) + auth = 0 + + // Actual ID changing + + if("access" in href_list) + if(auth) + var/access_type = text2num(href_list["access"]) + writer.access ^= list(access_type) //logical xor: remove if present, add if not + + if("assign" in href_list) + if(auth) + var/t1 = href_list["assign"] + if(t1 == "Custom") + var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,MAX_MESSAGE_LEN) + if(temp_t) + t1 = temp_t + set_default_access(t1) + + writer.assignment = t1 + writer.name = text("[writer.registered_name]'s ID Card ([writer.assignment])") + + if("reg" in href_list) + if(auth) + writer.registered_name = href_list["reg"] + writer.name = text("[writer.registered_name]'s ID Card ([writer.assignment])") + + computer.updateUsrDialog() + return + + + + + + +/datum/file/program/card_comp/centcom + name = "CentCom identification console" + drm = 1 + + list_jobs() + return get_all_centcom_jobs() + "Custom" + + accessblock() + var/accesses = "
Central Command:
" + for(var/A in get_all_centcom_access()) + if(A in writer.access) + accesses += topic_link(src,"access=[A]","[replacetext(get_centcom_access_desc(A), " ", " ")]") + " " + else + accesses += topic_link(src,"access=[A]",replacetext(get_centcom_access_desc(A), " ", " ")) + " " + return accesses + + authenticate() + if(access_cent_captain in reader.access) + return 1 + return 0 \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/cloning.dm b/code/WorkInProgress/computer3/computers/cloning.dm new file mode 100644 index 0000000000..49ed2a04b8 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/cloning.dm @@ -0,0 +1,363 @@ +/obj/machinery/computer3/cloning + default_prog = /datum/file/program/cloning + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/storage/removable,/obj/item/part/computer/networking/prox) + +/datum/file/program/cloning + name = "cloning console" + desc = "Connects to cloning machinery through the local network." + active_state = "dna_old" + + req_access = list(access_heads) //Only used for record deletion right now. + + var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. + var/obj/machinery/clonepod/pod1 = null //Linked cloning pod. + + var/temp = "Inactive" + var/scantemp_ckey + var/scantemp = "Ready to Scan" + var/menu = 1 //Which menu screen to display + var/list/records = list() + var/datum/data/record/active_record = null + var/loading = 0 // Nice loading text + var/has_disk = 0 + + proc/updatemodules() + if(!computer.net) return + + if(scanner && pod1) + if(!computer.net.verify_machine(scanner)) + scanner = null + if(!computer.net.verify_machine(pod1)) + pod1 = null + + if(!scanner || !pod1) + var/list/nearby = computer.net.get_machines() + scanner = locate(/obj/machinery/dna_scannernew) in nearby + pod1 = locate(/obj/machinery/clonepod) in nearby + + if (pod1) + pod1.connected = src // Some variable the pod needs + + proc/ScanningMenu() + if (isnull(scanner)) + return "ERROR: No Scanner detected!
" + + var/dat = "

Scanner Functions

" + dat += "
" + + if (!scanner.occupant) + dat += "Scanner Unoccupied" + else if(loading) + dat += "[scanner.occupant] => Scanning..." + else + if (scanner.occupant.ckey != scantemp_ckey) + scantemp = "Ready to Scan" + scantemp_ckey = scanner.occupant.ckey + dat += "[scanner.occupant] => [scantemp]" + + dat += "
" + + if (scanner.occupant) + dat += topic_link(src,"scan","Start Scan") + "
" + if(scanner.locked) + dat += topic_link(src,"lock","Unlock Scanner") + else + dat += topic_link(src,"lock","Lock Scanner") + else + dat += fake_link("Start Scan") + + // Footer + dat += "

Database Functions

" + if (records.len > 0) + dat += topic_link(src,"menu=2","View Records ([records.len])") + "
" + else + dat += fake_link("View Records (0)") + + if (has_disk) + dat += topic_link(src,"eject_disk","Eject Disk") + "
" + return dat + + proc/RecordsList() + var/dat = "

Current records

" + dat += topic_link(src,"menu=1","<< Back") + "

" + for(var/datum/data/record/R in records) + dat += "

[R.fields["name"]]

Scan ID [R.fields["id"]] " + topic_link(src,"view_rec=\ref[R]","View Record") + return dat + + proc/ShowRecord() + var/dat = "

Selected Record

" + dat += topic_link(src,"menu=2","<< Back") + "

" + + if (!active_record) + dat += "Record not found." + else + dat += "

[active_record.fields["name"]]

" + dat += "Scan ID [active_record.fields["id"]] [topic_link(src,"clone","Clone")]
" + + var/obj/item/weapon/implant/health/H = locate(active_record.fields["imp"]) + + if ((H) && (istype(H))) + dat += "Health Implant Data:
[H.sensehealth()]

" + else + dat += "Unable to locate Health Implant.

" + + dat += "Unique Identifier:
[active_record.fields["UI"]]
" + dat += "Structural Enzymes:
[active_record.fields["SE"]]
" + + if (has_disk) + dat += "
" + dat += "

Inserted Disk

" + dat += "Contents: " + if (computer.floppy.inserted.files.len == 0) + dat += "Empty" + else + for(var/datum/file/data/genome/G in computer.floppy.inserted.files) + dat += topic_link(src,"loadfile=\ref[G]","[G.name]") + "
" + + dat += "

Save to Disk:
" + dat += topic_link(src,"save_disk=ue","Unique Identifier + Unique Enzymes") + "
" + dat += topic_link(src,"save_disk=ui","Unique Identifier") + "
" + dat += topic_link(src,"save_disk=se","Structural Enzymes") + "
" + dat += "
" + + dat += "[topic_link(src,"del_rec","Delete Record")]" + return dat + proc/ConfirmDelete() + var/dat = "[temp]
" + dat += "

Confirm Record Deletion

" + + dat += "[topic_link(src,"del_rec","Scan card to confirm")]
" + dat += "[topic_link(src,"menu=3","Cancel")]" + return dat + + interact() + if(!interactable()) + return + + updatemodules() + + var/dat = "" + dat += topic_link(src,"refresh","Refresh") + dat += "

Cloning Pod Status

" + dat += "
[temp] 
" + + has_disk = (computer.floppy && computer.floppy.inserted) + if(!active_record && menu > 2) + menu = 2 + + switch(menu) + if(1) + dat += ScanningMenu() + + if(2) + dat += RecordsList() + + if(3) + dat += ShowRecord() + + if(4) + dat = ConfirmDelete() // not (+=), this is how it used to be, just putting it in a function + + if(!popup) + popup = new(usr, "\ref[computer]", "Cloning System Control") + popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) + + popup.set_content(dat) + popup.open() + return + + Topic(var/href, var/list/href_list) + if(loading || !interactable()) + return + + if (href_list["menu"]) + menu = text2num(href_list["menu"]) + else if (("scan" in href_list) && !isnull(scanner)) + scantemp = "" + + loading = 1 + computer.updateUsrDialog() + + spawn(20) + scan_mob(scanner.occupant) + + loading = 0 + computer.updateUsrDialog() + + + //No locking an open scanner. + else if (("lock" in href_list) && !isnull(scanner)) + if ((!scanner.locked) && (scanner.occupant)) + scanner.locked = 1 + else + scanner.locked = 0 + + else if ("view_rec" in href_list) + active_record = locate(href_list["view_rec"]) + if(istype(active_record,/datum/data/record)) + if ( !active_record.fields["ckey"] || active_record.fields["ckey"] == "" ) + del(active_record) + temp = "Record Corrupt" + else + menu = 3 + else + active_record = null + temp = "Record missing." + + else if ("del_rec" in href_list) + if ((!active_record) || (menu < 3)) + return + if (menu == 3) //If we are viewing a record, confirm deletion + temp = "Delete record?" + menu = 4 + + else if (menu == 4) + var/obj/item/weapon/card/id/C = usr.get_active_hand() + if (istype(C)||istype(C, /obj/item/device/pda)) + if(check_access(C)) + temp = "[active_record.fields["name"]] => Record deleted." + records.Remove(active_record) + del(active_record) + menu = 2 + else + temp = "Access Denied." + + else if ("eject_disk" in href_list) + if(computer.floppy) + computer.floppy.eject_disk() + + else if("loadfile" in href_list) + + var/datum/file/data/genome/G = locate(href_list["loadfile"]) in computer.floppy.files + if(!istype(G)) + temp = "Load error." + computer.updateUsrDialog() + return + switch(G.type) + if(/datum/file/data/genome/UI) + active_record.fields["UI"] = G.content + if(/datum/file/data/genome/UE) + active_record.fields["name"] = G.real_name + if(/datum/file/data/genome/SE) + active_record.fields["SE"] = G.content + if(/datum/file/data/genome/cloning) + active_record = G:record + else if("savefile" in href_list) + if (!active_record || !computer || !computer.floppy) + temp = "Save error." + computer.updateUsrDialog() + return + var/rval = 0 + switch(href_list["save_disk"]) + if("ui") + var/datum/file/data/genome/UI/ui = new + ui.content = active_record.fields["UI"] + ui.real_name = active_record.fields["name"] + rval = computer.floppy.addfile(ui) + if("ue") + var/datum/file/data/genome/UI/UE/ui = new + ui.content = active_record.fields["UI"] + ui.real_name = active_record.fields["name"] + rval = computer.floppy.addfile(ui) + if("se") + var/datum/file/data/genome/SE/se = new + se.content = active_record.fields["SE"] + se.real_name = active_record.fields["name"] + rval = computer.floppy.addfile(se) + if("clone") + var/datum/file/data/genome/cloning/c = new + c.record = active_record + c.real_name = active_record.fields["name"] + rval = computer.floppy.addfile(c) + if(!rval) + temp = "Disk write error." + + else if ("refresh" in href_list) + computer.updateUsrDialog() + + else if ("clone" in href_list) + //Look for that player! They better be dead! + if(active_record) + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!pod1) + temp = "No Clonepod detected." + else if(pod1.occupant) + temp = "Clonepod is currently occupied." + else if(pod1.mess) + temp = "Clonepod malfunction." + else if(!config.revival_cloning) + temp = "Unable to initiate cloning cycle." + else if(pod1.growclone(active_record.fields["ckey"], active_record.fields["name"], active_record.fields["UI"], active_record.fields["SE"], active_record.fields["mind"], active_record.fields["mrace"])) + temp = "[active_record.fields["name"]] => Cloning cycle in progress..." + records.Remove(active_record) + del(active_record) + menu = 1 + else + temp = "[active_record.fields["name"]] => Initialisation failure." + + else + temp = "Data corruption." + + computer.add_fingerprint(usr) + computer.updateUsrDialog() + return + + proc/scan_mob(mob/living/carbon/human/subject as mob) + if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna)) + scantemp = "Unable to locate valid genetic data." + return + if (!getbrain(subject)) + scantemp = "No signs of intelligence detected." + return + if (subject.suiciding == 1) + scantemp = "Subject's brain is not responding to scanning stimuli." + return + if ((!subject.ckey) || (!subject.client)) + scantemp = "Mental interface failure." + return + if (NOCLONE in subject.mutations) + scantemp = "Mental interface failure." + return + if (!isnull(find_record(subject.ckey))) + scantemp = "Subject already in database." + return + + subject.dna.check_integrity() + + var/datum/data/record/R = new /datum/data/record( ) + if(subject.dna) + R.fields["mrace"] = subject.dna.mutantrace + R.fields["UI"] = subject.dna.uni_identity + R.fields["SE"] = subject.dna.struc_enzymes + else + R.fields["mrace"] = null + R.fields["UI"] = null + R.fields["SE"] = null + R.fields["ckey"] = subject.ckey + R.fields["name"] = subject.real_name + R.fields["id"] = copytext(md5(subject.real_name), 2, 6) + + + + //Add an implant if needed + var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) + if (isnull(imp)) + imp = new /obj/item/weapon/implant/health(subject) + imp.implanted = subject + R.fields["imp"] = "\ref[imp]" + //Update it if needed + else + R.fields["imp"] = "\ref[imp]" + + if (!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning. + R.fields["mind"] = "\ref[subject.mind]" + + records += R + scantemp = "Subject successfully scanned." + +//Find a specific record by key. + proc/find_record(var/find_key) + for(var/datum/data/record/R in records) + if (R.fields["ckey"] == find_key) + return R + return null diff --git a/code/WorkInProgress/computer3/computers/communications.dm b/code/WorkInProgress/computer3/computers/communications.dm new file mode 100644 index 0000000000..23b2540ade --- /dev/null +++ b/code/WorkInProgress/computer3/computers/communications.dm @@ -0,0 +1,384 @@ +/obj/machinery/computer3/communications + default_prog = /datum/file/program/communications + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace) + +/obj/machinery/computer3/communications/captain + default_prog = /datum/file/program/communications + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/cardslot/dual) + spawn_files = list(/datum/file/program/card_comp, /datum/file/program/security, /datum/file/program/crew, /datum/file/program/arcade, + /datum/file/camnet_key, /datum/file/camnet_key/entertainment, /datum/file/camnet_key/singulo) + + +/datum/file/program/communications + var/const/STATE_DEFAULT = 1 + var/const/STATE_CALLSHUTTLE = 2 + var/const/STATE_CANCELSHUTTLE = 3 + var/const/STATE_MESSAGELIST = 4 + var/const/STATE_VIEWMESSAGE = 5 + var/const/STATE_DELMESSAGE = 6 + var/const/STATE_STATUSDISPLAY = 7 + var/const/STATE_ALERT_LEVEL = 8 + var/const/STATE_CONFIRM_LEVEL = 9 + + +/datum/file/program/communications + name = "Centcom communications relay" + desc = "Used to connect to Centcom." + active_state = "comm" + req_access = list(access_heads) + + var/prints_intercept = 1 + var/authenticated = 0 + var/list/messagetitle = list() + var/list/messagetext = list() + var/currmsg = 0 + var/aicurrmsg = 0 + var/state = STATE_DEFAULT + var/aistate = STATE_DEFAULT + var/message_cooldown = 0 + var/centcomm_message_cooldown = 0 + var/tmp_alertlevel = 0 + + var/status_display_freq = "1435" + var/stat_msg1 + var/stat_msg2 + + Reset() + ..() + authenticated = 0 + state = STATE_DEFAULT + aistate = STATE_DEFAULT + + + Topic(var/href, var/list/href_list) + if(!interactable() || !computer.radio || ..(href,href_list) ) + return + if (computer.z > 1) + usr << "\red Unable to establish a connection: \black You're too far away from the station!" + return + + if("main" in href_list) + state = STATE_DEFAULT + if("login" in href_list) + var/mob/M = usr + var/obj/item/I = M.get_active_hand() + if(I) + I = I.GetID() + if(istype(I,/obj/item/weapon/card/id) && check_access(I)) + authenticated = 1 + if(access_captain in I.GetAccess()) + authenticated = 2 + if(istype(I,/obj/item/weapon/card/emag)) + authenticated = 2 + computer.emagged = 1 + if("logout" in href_list) + authenticated = 0 + + if("swipeidseclevel" in href_list) + var/mob/M = usr + var/obj/item/I = M.get_active_hand() + I = I.GetID() + + if (istype(I,/obj/item/weapon/card/id)) + if(access_captain in I.GetAccess()) + var/old_level = security_level + if(!tmp_alertlevel) tmp_alertlevel = SEC_LEVEL_GREEN + if(tmp_alertlevel < SEC_LEVEL_GREEN) tmp_alertlevel = SEC_LEVEL_GREEN + if(tmp_alertlevel > SEC_LEVEL_BLUE) tmp_alertlevel = SEC_LEVEL_BLUE //Cannot engage delta with this + set_security_level(tmp_alertlevel) + if(security_level != old_level) + //Only notify the admins if an actual change happened + log_game("[key_name(usr)] has changed the security level to [get_security_level()].") + message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].") + switch(security_level) + if(SEC_LEVEL_GREEN) + feedback_inc("alert_comms_green",1) + if(SEC_LEVEL_BLUE) + feedback_inc("alert_comms_blue",1) + tmp_alertlevel = 0 + else: + usr << "You are not authorized to do this." + tmp_alertlevel = 0 + state = STATE_DEFAULT + else + usr << "You need to swipe your ID." + if("announce" in href_list) + if(authenticated==2) + if(message_cooldown) return + var/input = stripped_input(usr, "Please choose a message to announce to the station crew.", "What?") + if(!input || !interactable()) + return + captain_announce(input)//This should really tell who is, IE HoP, CE, HoS, RD, Captain + log_say("[key_name(usr)] has made a captain announcement: [input]") + message_admins("[key_name_admin(usr)] has made a captain announcement.", 1) + message_cooldown = 1 + spawn(600)//One minute cooldown + message_cooldown = 0 + + if("callshuttle" in href_list) + state = STATE_DEFAULT + if(authenticated) + state = STATE_CALLSHUTTLE + if("callshuttle2" in href_list) + if(!computer.radio.subspace) + return + if(authenticated) + call_shuttle_proc(usr) + if(emergency_shuttle.online) + post_status("shuttle") + state = STATE_DEFAULT + if("cancelshuttle" in href_list) + state = STATE_DEFAULT + if(authenticated) + state = STATE_CANCELSHUTTLE + if("messagelist" in href_list) + currmsg = 0 + state = STATE_MESSAGELIST + if("viewmessage" in href_list) + state = STATE_VIEWMESSAGE + if (!currmsg) + if(href_list["message-num"]) + currmsg = text2num(href_list["message-num"]) + else + state = STATE_MESSAGELIST + if("delmessage" in href_list) + state = (currmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST + if("delmessage2" in href_list) + if(authenticated) + if(currmsg) + var/title = messagetitle[currmsg] + var/text = messagetext[currmsg] + messagetitle.Remove(title) + messagetext.Remove(text) + if(currmsg == aicurrmsg) + aicurrmsg = 0 + currmsg = 0 + state = STATE_MESSAGELIST + else + state = STATE_VIEWMESSAGE + if("status" in href_list) + state = STATE_STATUSDISPLAY + + // Status display stuff + if("setstat" in href_list) + switch(href_list["statdisp"]) + if("message") + post_status("message", stat_msg1, stat_msg2) + if("alert") + post_status("alert", href_list["alert"]) + else + post_status(href_list["statdisp"]) + + if("setmsg1" in href_list) + stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40) + computer.updateDialog() + if("setmsg2" in href_list) + stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40) + computer.updateDialog() + + // OMG CENTCOMM LETTERHEAD + if("MessageCentcomm" in href_list) + if(!computer.radio.subspace) + return + if(authenticated==2) + if(centcomm_message_cooldown) + usr << "Arrays recycling. Please stand by." + return + var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") + if(!input || !interactable()) + return + Centcomm_announce(input, usr) + usr << "Message transmitted." + log_say("[key_name(usr)] has made a Centcomm announcement: [input]") + centcomm_message_cooldown = 1 + spawn(600)//10 minute cooldown + centcomm_message_cooldown = 0 + + + // OMG SYNDICATE ...LETTERHEAD + if("MessageSyndicate" in href_list) + if((authenticated==2) && (computer.emagged)) + if(centcomm_message_cooldown) + usr << "Arrays recycling. Please stand by." + return + var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") + if(!input || !interactable()) + return + Syndicate_announce(input, usr) + usr << "Message transmitted." + log_say("[key_name(usr)] has made a Syndicate announcement: [input]") + centcomm_message_cooldown = 1 + spawn(600)//10 minute cooldown + centcomm_message_cooldown = 0 + + if("RestoreBackup" in href_list) + usr << "Backup routing data restored!" + computer.emagged = 0 + computer.updateDialog() + + + + // AI interface + if("ai-main" in href_list) + aicurrmsg = 0 + aistate = STATE_DEFAULT + if("ai-callshuttle" in href_list) + aistate = STATE_CALLSHUTTLE + if("ai-callshuttle2" in href_list) + if(!computer.radio.subspace) + return + call_shuttle_proc(usr) + aistate = STATE_DEFAULT + if("ai-messagelist" in href_list) + aicurrmsg = 0 + aistate = STATE_MESSAGELIST + if("ai-viewmessage" in href_list) + aistate = STATE_VIEWMESSAGE + if (!aicurrmsg) + if(href_list["message-num"]) + aicurrmsg = text2num(href_list["message-num"]) + else + aistate = STATE_MESSAGELIST + if("ai-delmessage" in href_list) + aistate = (aicurrmsg) ? STATE_DELMESSAGE : STATE_MESSAGELIST + if("ai-delmessage2" in href_list) + if(aicurrmsg) + var/title = messagetitle[aicurrmsg] + var/text = messagetext[aicurrmsg] + messagetitle.Remove(title) + messagetext.Remove(text) + if(currmsg == aicurrmsg) + currmsg = 0 + aicurrmsg = 0 + aistate = STATE_MESSAGELIST + if("ai-status" in href_list) + aistate = STATE_STATUSDISPLAY + + if("securitylevel" in href_list) + tmp_alertlevel = text2num( href_list["newalertlevel"] ) + if(!tmp_alertlevel) tmp_alertlevel = 0 + state = STATE_CONFIRM_LEVEL + + if("changeseclevel" in href_list) + state = STATE_ALERT_LEVEL + + computer.updateUsrDialog() + + + + proc/main_menu() + var/dat = "" + if (computer.radio.subspace) + if(emergency_shuttle.online && emergency_shuttle.location==0) + var/timeleft = emergency_shuttle.timeleft() + dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]
" + refresh = 1 + else + refresh = 0 + if (authenticated) + dat += "
\[ Log Out \]" + if (authenticated==2) + dat += "
\[ Make An Announcement \]" + if(computer.emagged == 0) + dat += "
\[ Send an emergency message to Centcomm \]" + else + dat += "
\[ Send an emergency message to \[UNKNOWN\] \]" + dat += "
\[ Restore Backup Routing Data \]" + + dat += "
\[ Change alert level \]" + if(emergency_shuttle.location==0) + if (emergency_shuttle.online) + dat += "
\[ Cancel Shuttle Call \]" + else + dat += "
\[ Call Emergency Shuttle \]" + + dat += "
\[ Set Status Display \]" + else + dat += "
\[ Log In \]" + dat += "
\[ Message List \]" + return dat + + proc/confirm_menu(var/prompt,var/yes_option) + return "Are you sure you want to [prompt]? \[ [topic_link(src,yes_option,"OK")] | [topic_link(src,"main","Cancel")] \]" + + interact() + if(!interactable()) + return + if(!computer.radio) + computer.Crash(MISSING_PERIPHERAL) + return + + var/dat = "" + switch(state) + if(STATE_DEFAULT) + dat = main_menu() + if(STATE_CALLSHUTTLE) + dat = confirm_menu("call the shuttle","callshuttle2") + if(STATE_CANCELSHUTTLE) + dat = confirm_menu("cancel the shuttle","cancelshuttle2") + if(STATE_MESSAGELIST) + dat += "Messages:" + for(var/i = 1; i<=messagetitle.len; i++) + dat += "
[messagetitle[i]]" + if(STATE_VIEWMESSAGE) + if (currmsg) + dat += "[messagetitle[currmsg]]

[messagetext[currmsg]]" + if (authenticated) + dat += "

\[ Delete \]" + else + state = STATE_MESSAGELIST + interact() + return + if(STATE_DELMESSAGE) + if (currmsg) + dat += "Are you sure you want to delete this message? \[ OK | Cancel \]" + else + state = STATE_MESSAGELIST + interact() + return + if(STATE_STATUSDISPLAY) + dat += "\[ Back \]
" + dat += "Set Status Displays
" + dat += "\[ Clear \]
" + dat += "\[ Shuttle ETA \]
" + dat += "\[ Message \]" + dat += "
" + dat += "\[ Alert: None |" + dat += " Red Alert |" + dat += " Lockdown |" + dat += " Biohazard \]

" + if(STATE_ALERT_LEVEL) + dat += "Current alert level: [get_security_level()]
" + if(security_level == SEC_LEVEL_DELTA) + dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." + else + dat += "Blue
" + dat += "Green" + if(STATE_CONFIRM_LEVEL) + dat += "Current alert level: [get_security_level()]
" + dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
" + dat += "Swipe ID to confirm change.
" + + popup.set_content(dat) + popup.open() + + + proc/post_status(var/command, var/data1, var/data2) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) + + if(!frequency) return + + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + if("alert") + status_signal.data["picture_state"] = data1 + + frequency.post_signal(src, status_signal) diff --git a/code/WorkInProgress/computer3/computers/crew.dm b/code/WorkInProgress/computer3/computers/crew.dm new file mode 100644 index 0000000000..d9ecace0c3 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/crew.dm @@ -0,0 +1,71 @@ +/obj/machinery/computer3/crew + default_prog = /datum/file/program/crew + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) + icon_state = "frame-med" + +/datum/file/program/crew + name = "Crew Monitoring Console" + desc = "Used to monitor active health sensors built into most of the crew's uniforms." + active_state = "crew" + var/list/tracked = list( ) + + interact(mob/user) + if(!interactable()) + return + + scan() + var/t = "" + t += "
Refresh " + t += "Close
" + t += "" + var/list/logs = list() + for(var/obj/item/clothing/under/C in tracked) + var/log = "" + var/turf/pos = get_turf(C) + if((C) && (C.has_sensor) && (pos) && (pos.z == computer.z) && C.sensor_mode) + if(istype(C.loc, /mob/living/carbon/human)) + + var/mob/living/carbon/human/H = C.loc + + var/dam1 = round(H.getOxyLoss(),1) + var/dam2 = round(H.getToxLoss(),1) + var/dam3 = round(H.getFireLoss(),1) + var/dam4 = round(H.getBruteLoss(),1) + + var/life_status = "[H.stat > 1 ? "Deceased" : "Living"]" + var/damage_report = "([dam1]/[dam2]/[dam3]/[dam4])" + + if(H.wear_id) + log += "" + else + log += "" + + switch(C.sensor_mode) + if(1) + log += "" + if(2) + log += "" + if(3) + var/area/player_area = get_area(H) + log += "" + logs += log + logs = sortList(logs) + for(var/log in logs) + t += log + t += "

Name

Vitals

Position

[H.wear_id.name]
Unknown[life_status]Not Available
[life_status] [damage_report]Not Available
[life_status] [damage_report][format_text(player_area.name)] ([pos.x], [pos.y])
" + + popup.set_content(t) + popup.open() + + + proc/scan() + for(var/obj/item/clothing/under/C in world) + if((C.has_sensor) && (istype(C.loc, /mob/living/carbon/human))) + tracked |= C + return 1 + + Topic(href, list/href_list) + if(!interactable() || !computer.cardslot || ..(href,href_list)) + return + computer.updateUsrDialog() + return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/customs.dm b/code/WorkInProgress/computer3/computers/customs.dm new file mode 100644 index 0000000000..bca73055b8 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/customs.dm @@ -0,0 +1,3 @@ +/obj/machinery/computer3/customs + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras) + spawn_files = list(/datum/file/program/arcade,/datum/file/program/security,/datum/file/camnet_key/entertainment,/datum/file/program/crew) \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/law.dm b/code/WorkInProgress/computer3/computers/law.dm new file mode 100644 index 0000000000..8f7a639ae2 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/law.dm @@ -0,0 +1,84 @@ + + +/obj/machinery/computer3/aiupload + name = "AI Upload" + desc = "Used to upload laws to the AI." + icon_state = "frame-rnd" + circuit = "/obj/item/part/board/circuit/aiupload" + var/mob/living/silicon/ai/current = null + var/opened = 0 + + + verb/AccessInternals() + set category = "Object" + set name = "Access Computer's Internals" + set src in oview(1) + if(get_dist(src, usr) > 1 || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon)) + return + + opened = !opened + if(opened) + usr << "\blue The access panel is now open." + else + usr << "\blue The access panel is now closed." + return + + + attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) + if (user.z > 6) + user << "\red Unable to establish a connection: \black You're too far away from the station!" + return + if(istype(module, /obj/item/weapon/aiModule)) + module.install(src) + else + return ..() + + + attack_hand(var/mob/user as mob) + if(src.stat & NOPOWER) + usr << "The upload computer has no power!" + return + if(src.stat & BROKEN) + usr << "The upload computer is broken!" + return + + src.current = select_active_ai(user) + + if (!src.current) + usr << "No active AIs detected." + else + usr << "[src.current.name] selected for law changes." + return + + + +/obj/machinery/computer3/borgupload + name = "Cyborg Upload" + desc = "Used to upload laws to Cyborgs." + icon_state = "frame-rnd" + circuit = "/obj/item/part/board/circuit/borgupload" + var/mob/living/silicon/robot/current = null + + + attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob) + if(istype(module, /obj/item/weapon/aiModule)) + module.install(src) + else + return ..() + + + attack_hand(var/mob/user as mob) + if(src.stat & NOPOWER) + usr << "The upload computer has no power!" + return + if(src.stat & BROKEN) + usr << "The upload computer is broken!" + return + + src.current = freeborg() + + if (!src.current) + usr << "No free cyborgs detected." + else + usr << "[src.current.name] selected for law changes." + return diff --git a/code/WorkInProgress/computer3/computers/medical.dm b/code/WorkInProgress/computer3/computers/medical.dm new file mode 100644 index 0000000000..13302f75b0 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/medical.dm @@ -0,0 +1,503 @@ +/* + I hate to make this a todo, but I cannot possibly complete all of computer3 + if I have to rearchitecture datacores and everything else that uses them right now. + + In the future the datacore should probably be a server, perhaps on station, perhaps on centcom, + with data records as files probably. It's not difficult unless you're trying to do a million + impossible things before breakfast. +*/ + +/obj/machinery/computer3/med_data + default_prog = /datum/file/program/med_data + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) + +/datum/file/program/med_data + name = "Medical Records" + desc = "This can be used to check medical records." + active_state = "medcomp" + req_one_access = list(access_medical, access_forensics_lockers) + + var/obj/item/weapon/card/id/scan = null + var/authenticated = null + var/rank = null + var/screen = null + var/datum/data/record/active1 = null + var/datum/data/record/active2 = null + var/a_id = null + var/temp = null + var/printing = null + + + proc/authenticate() + if(access_medical in scan.access) + return 1 + if(istype(usr,/mob/living/silicon/ai)) + return 1 + return 0 + + interact() + usr.set_machine(src) + scan = computer.cardslot.reader + if(!interactable()) + return + if (computer.z > 6) + usr << "\red Unable to establish a connection: \black You're too far away from the station!" + return + var/dat + if (src.temp) + dat = text("[src.temp]

Clear Screen") + else + dat = text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) + if (src.authenticated) + switch(src.screen) + if(1.0) + dat += {" +Search Records +
List Records +
+
Virus Database +
Medbot Tracking +
+
Record Maintenance +
{Log Out}
+"} + if(2.0) + dat += "Record List:
" + if(!isnull(data_core.general)) + for(var/datum/data/record/R in sortRecord(data_core.general)) + dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"]) + //Foreach goto(132) + dat += text("
Back", src) + if(3.0) + dat += text("Records Maintenance
\nBackup To Disk
\nUpload From disk
\nDelete All Records
\n
\nBack", src, src, src, src) + if(4.0) + var/icon/front = new(active1.fields["photo"], dir = SOUTH) + var/icon/side = new(active1.fields["photo"], dir = WEST) + usr << browse_rsc(front, "front.png") + usr << browse_rsc(side, "side.png") + dat += "
Medical Record

" + if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) + dat += "
Name: [active1.fields["name"]] \ + ID: [active1.fields["id"]]
\n \ + Sex: [active1.fields["sex"]]
\n \ + Age: [active1.fields["age"]]
\n \ + Fingerprint: [active1.fields["fingerprint"]]
\n \ + Physical Status: [active1.fields["p_stat"]]
\n \ + Mental Status: [active1.fields["m_stat"]]
\ + Photo:
" + else + dat += "General Record Lost!
" + if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) + dat += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, decode(src.active2.fields["notes"])) + var/counter = 1 + while(src.active2.fields[text("com_[]", counter)]) + dat += text("[]
Delete Entry

", src.active2.fields[text("com_[]", counter)], src, counter) + counter++ + dat += text("Add Entry

", src) + dat += text("Delete Record (Medical Only)

", src) + else + dat += "Medical Record Lost!
" + dat += text("New Record

") + dat += text("\nPrint Record
\nBack
", src, src) + if(5.0) + dat += "
Virus Database
" + /* Advanced diseases is weak! Feeble! Glory to virus2! + for(var/Dt in typesof(/datum/disease/)) + var/datum/disease/Dis = new Dt(0) + if(istype(Dis, /datum/disease/advance)) + continue // TODO (tm): Add advance diseases to the virus database which no one uses. + if(!Dis.desc) + continue + dat += "
[Dis.name]" + */ + for (var/ID in virusDB) + var/datum/data/record/v = virusDB[ID] + dat += "
[v.fields["name"]]" + + dat += "
Back" + if(6.0) + dat += "
Medical Robot Monitor
" + dat += "Back" + dat += "
Medical Robots:" + var/bdat = null + for(var/obj/machinery/bot/medbot/M in world) + + if(M.z != computer.z) continue //only find medibots on the same z-level as the computer + var/turf/bl = get_turf(M) + if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up + bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
" + if((!isnull(M.reagent_glass)) && M.use_beaker) + bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
" + else + bdat += "Using Internal Synthesizer.
" + if(!bdat) + dat += "
None detected
" + else + dat += "
[bdat]" + + else + else + dat += text("{Log In}", src) + var/datum/browser/popup = new(usr, "med_comp", "Medical Records", 600, 400) + popup.set_content(dat) + popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) + popup.open() + return + + Topic(href, href_list) + if(!interactable() || !computer.cardslot || ..(href,href_list)) + return + + if (!( data_core.general.Find(src.active1) )) + src.active1 = null + + if (!( data_core.medical.Find(src.active2) )) + src.active2 = null + + usr.set_machine(src) + + if (href_list["temp"]) + src.temp = null + + if (href_list["scan"]) + if (scan) + if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) + computer.cardslot.remove(scan) + else + scan.loc = get_turf(src) + scan = null + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/card/id)) + computer.cardslot.insert(I) + scan = I + + else if (href_list["logout"]) + src.authenticated = null + src.screen = null + src.active1 = null + src.active2 = null + + else if (href_list["login"]) + + if (istype(usr, /mob/living/silicon/ai)) + src.active1 = null + src.active2 = null + src.authenticated = usr.name + src.rank = "AI" + src.screen = 1 + + else if (istype(usr, /mob/living/silicon/robot)) + src.active1 = null + src.active2 = null + src.authenticated = usr.name + var/mob/living/silicon/robot/R = usr + src.rank = "[R.modtype] [R.braintype]" + src.screen = 1 + + else if (istype(src.scan, /obj/item/weapon/card/id)) + src.active1 = null + src.active2 = null + + if (src.check_access(src.scan)) + src.authenticated = src.scan.registered_name + src.rank = src.scan.assignment + src.screen = 1 + + if (src.authenticated) + + if(href_list["screen"]) + src.screen = text2num(href_list["screen"]) + if(src.screen < 1) + src.screen = 1 + + src.active1 = null + src.active2 = null + + if(href_list["vir"]) + var/datum/data/record/v = locate(href_list["vir"]) + src.temp = "
GNAv2 based virus lifeform V-[v.fields["id"]]
" + src.temp += "
Name: [v.fields["name"]]" + src.temp += "
Antigen: [v.fields["antigen"]]" + src.temp += "
Spread: [v.fields["spread type"]] " + src.temp += "
Details:
[v.fields["description"]]" + + if (href_list["del_all"]) + src.temp = text("Are you sure you wish to delete all records?
\n\tYes
\n\tNo
", src, src) + + if (href_list["del_all2"]) + for(var/datum/data/record/R in data_core.medical) + //R = null + del(R) + //Foreach goto(494) + src.temp = "All records deleted." + + if (href_list["field"]) + var/a1 = src.active1 + var/a2 = src.active2 + switch(href_list["field"]) + if("fingerprint") + if (istype(src.active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) + return + src.active1.fields["fingerprint"] = t1 + if("sex") + if (istype(src.active1, /datum/data/record)) + if (src.active1.fields["sex"] == "Male") + src.active1.fields["sex"] = "Female" + else + src.active1.fields["sex"] = "Male" + if("age") + if (istype(src.active1, /datum/data/record)) + var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) + return + src.active1.fields["age"] = t1 + if("mi_dis") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["mi_dis"] = t1 + if("mi_dis_d") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["mi_dis_d"] = t1 + if("ma_dis") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["ma_dis"] = t1 + if("ma_dis_d") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["ma_dis_d"] = t1 + if("alg") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["alg"] = t1 + if("alg_d") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["alg_d"] = t1 + if("cdi") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["cdi"] = t1 + if("cdi_d") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["cdi_d"] = t1 + if("notes") + if (istype(src.active2, /datum/data/record)) + var/t1 = copytext(html_encode(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + src.active2.fields["notes"] = t1 + if("p_stat") + if (istype(src.active1, /datum/data/record)) + src.temp = text("Physical Condition:
\n\t*Deceased*
\n\t*SSD*
\n\tActive
\n\tPhysically Unfit
\n\tDisabled
", src, src, src, src, src) + if("m_stat") + if (istype(src.active1, /datum/data/record)) + src.temp = text("Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
", src, src, src, src) + if("b_type") + if (istype(src.active2, /datum/data/record)) + src.temp = text("Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
", src, src, src, src, src, src, src, src) + if("b_dna") + if (istype(src.active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input DNA hash:", "Med. records", src.active1.fields["dna"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) + return + src.active1.fields["dna"] = t1 + if("vir_name") + var/datum/data/record/v = locate(href_list["edit_vir"]) + if (v) + var/t1 = copytext(sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) + return + v.fields["name"] = t1 + if("vir_desc") + var/datum/data/record/v = locate(href_list["edit_vir"]) + if (v) + var/t1 = copytext(sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) + return + v.fields["description"] = t1 + else + + if (href_list["p_stat"]) + if (src.active1) + switch(href_list["p_stat"]) + if("deceased") + src.active1.fields["p_stat"] = "*Deceased*" + if("ssd") + src.active1.fields["p_stat"] = "*SSD*" + if("active") + src.active1.fields["p_stat"] = "Active" + if("unfit") + src.active1.fields["p_stat"] = "Physically Unfit" + if("disabled") + src.active1.fields["p_stat"] = "Disabled" + + if (href_list["m_stat"]) + if (src.active1) + switch(href_list["m_stat"]) + if("insane") + src.active1.fields["m_stat"] = "*Insane*" + if("unstable") + src.active1.fields["m_stat"] = "*Unstable*" + if("watch") + src.active1.fields["m_stat"] = "*Watch*" + if("stable") + src.active1.fields["m_stat"] = "Stable" + + + if (href_list["b_type"]) + if (src.active2) + switch(href_list["b_type"]) + if("an") + src.active2.fields["b_type"] = "A-" + if("bn") + src.active2.fields["b_type"] = "B-" + if("abn") + src.active2.fields["b_type"] = "AB-" + if("on") + src.active2.fields["b_type"] = "O-" + if("ap") + src.active2.fields["b_type"] = "A+" + if("bp") + src.active2.fields["b_type"] = "B+" + if("abp") + src.active2.fields["b_type"] = "AB+" + if("op") + src.active2.fields["b_type"] = "O+" + + + if (href_list["del_r"]) + if (src.active2) + src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
", src, src) + + if (href_list["del_r2"]) + if (src.active2) + //src.active2 = null + del(src.active2) + + if (href_list["d_rec"]) + var/datum/data/record/R = locate(href_list["d_rec"]) + var/datum/data/record/M = locate(href_list["d_rec"]) + if (!( data_core.general.Find(R) )) + src.temp = "Record Not Found!" + return + for(var/datum/data/record/E in data_core.medical) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + M = E + else + //Foreach continue //goto(2540) + src.active1 = R + src.active2 = M + src.screen = 4 + + if (href_list["new"]) + if ((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) ))) + var/datum/data/record/R = new /datum/data/record( ) + R.fields["name"] = src.active1.fields["name"] + R.fields["id"] = src.active1.fields["id"] + R.name = text("Medical Record #[]", R.fields["id"]) + R.fields["b_type"] = "Unknown" + R.fields["b_dna"] = "Unknown" + R.fields["mi_dis"] = "None" + R.fields["mi_dis_d"] = "No minor disabilities have been declared." + R.fields["ma_dis"] = "None" + R.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + R.fields["alg"] = "None" + R.fields["alg_d"] = "No allergies have been detected in this patient." + R.fields["cdi"] = "None" + R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + R.fields["notes"] = "No notes." + data_core.medical += R + src.active2 = R + src.screen = 4 + + if (href_list["add_c"]) + if (!( istype(src.active2, /datum/data/record) )) + return + var/a2 = src.active2 + var/t1 = copytext(sanitize(input("Add Comment:", "Med. records", null, null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) + return + var/counter = 1 + while(src.active2.fields[text("com_[]", counter)]) + counter++ + src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]
[t1]") + + if (href_list["del_c"]) + if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])])) + src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" + + if (href_list["search"]) + var/t1 = input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text + if ((!( t1 ) || usr.stat || !( src.authenticated ) || usr.restrained() || ((!interactable()) && (!istype(usr, /mob/living/silicon))))) + return + src.active1 = null + src.active2 = null + t1 = lowertext(t1) + for(var/datum/data/record/R in data_core.medical) + if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) + src.active2 = R + else + //Foreach continue //goto(3229) + if (!( src.active2 )) + src.temp = text("Could not locate record [].", t1) + else + for(var/datum/data/record/E in data_core.general) + if ((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"])) + src.active1 = E + else + //Foreach continue //goto(3334) + src.screen = 4 + + if (href_list["print_p"]) + if (!( src.printing )) + src.printing = 1 + var/datum/data/record/record1 = null + var/datum/data/record/record2 = null + if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) + record1 = active1 + if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) + record2 = active2 + sleep(50) + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( computer.loc ) + P.info = "
Medical Record

" + if (record1) + P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) + P.name = text("Medical Record ([])", record1.fields["name"]) + else + P.info += "General Record Lost!
" + P.name = "Medical Record" + if (record2) + P.info += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", record2.fields["b_type"], record2.fields["b_dna"], record2.fields["mi_dis"], record2.fields["mi_dis_d"], record2.fields["ma_dis"], record2.fields["ma_dis_d"], record2.fields["alg"], record2.fields["alg_d"], record2.fields["cdi"], record2.fields["cdi_d"], decode(record2.fields["notes"])) + var/counter = 1 + while(record2.fields[text("com_[]", counter)]) + P.info += text("[]
", record2.fields[text("com_[]", counter)]) + counter++ + else + P.info += "Medical Record Lost!
" + P.info += "" + src.printing = null + + interact() + return diff --git a/code/WorkInProgress/computer3/computers/message.dm b/code/WorkInProgress/computer3/computers/message.dm new file mode 100644 index 0000000000..d03f4a4753 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/message.dm @@ -0,0 +1,441 @@ +/obj/machinery/computer3/message_monitor + default_prog = /datum/file/program/message_mon + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/prox) + +/datum/file/program/message_mon + name = "Message Monitor Console" + desc = "Used to Monitor the crew's messages, that are sent via PDA. Can also be used to view Request Console messages." + active_state = "comm_logs" + var/hack_icon = "comm_logsc" + var/normal_icon = "comm_logs" + + //Server linked to. + var/obj/machinery/message_server/linkedServer = null + //Sparks effect - For emag + //var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread + + //Messages - Saves me time if I want to change something. + var/noserver = "ALERT: No server detected." + var/incorrectkey = "ALERT: Incorrect decryption key!" + var/defaultmsg = "Welcome. Please select an option." + var/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!" + + //Computer properties + var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message + var/hacking = 0 // Is it being hacked into by the AI/Cyborg + var/emag = 0 // When it is emagged. + var/message = "System bootup complete. Please select an option." // The message that shows on the main menu. + var/auth = 0 // Are they authenticated? + var/optioncount = 7 + + // Custom Message Properties + var/customsender = "System Administrator" + var/obj/item/device/pda/customrecepient = null + var/customjob = "Admin" + var/custommessage = "This is a test, please ignore." + + + update_icon() + if(emag || hacking) + overlay.icon_state = hack_icon + else + overlay.icon_state = normal_icon + computer.update_icon() + + interact() + if(!interactable()) + return + + //If the computer is being hacked or is emagged, display the reboot message. + if(hacking || emag) + message = rebootmsg + + var/dat = "
/
" + + if(auth) + dat += "

\[Authenticated\] /" + dat += " Server Power: [src.linkedServer && src.linkedServer.active ? "\[On\]":"\[Off\]"]

" + else + dat += "

\[Unauthenticated\] /" + dat += " Server Power: [src.linkedServer && src.linkedServer.active ? "\[On\]":"\[Off\]"]

" + + if(hacking || emag) + screen = 2 + else + if(!auth) + screen = 0 + if( !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)) ) + message = noserver + screen = 0 + + switch(screen) + //Main menu + if(0) + // = TAB + var/i = 0 + dat += "
[++i]. Link To A Server
" + if(auth) + if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) + dat += "
ERROR: Server not found!
" + else + dat += "
[++i]. View Message Logs
" + dat += "
[++i]. View Request Console Logs
" + dat += "
[++i]. Clear Message Logs
" + dat += "
[++i]. Clear Request Console Logs
" + dat += "
[++i]. Set Custom Key
" + dat += "
[++i]. Send Admin Message
" + else + for(var/n = ++i; n <= optioncount; n++) + dat += "
[n]. ---------------
" + if((istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot)) && (usr.mind.special_role && usr.mind.original == usr)) + //Malf/Traitor AIs can bruteforce into the system to gain the Key. + dat += "
*&@#. Bruteforce Key
" + else + dat += "
" + + //Bottom message + if(!auth) + dat += "

Please authenticate with the server in order to show additional options." + else + dat += "

Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties." + + //Message Logs + if(1) + var/index = 0 + //var/recipient = "Unspecified" //name of the person + //var/sender = "Unspecified" //name of the sender + //var/message = "Blank" //transferred message + dat += "
Back - Refresh

" + dat += "" + for(var/datum/data_pda_msg/pda in src.linkedServer.pda_msgs) + index++ + if(index > 3000) + break + // Del - Sender - Recepient - Message + // X - Al Green - Your Mom - WHAT UP!? + dat += "" + dat += "
XSenderRecipientMessage
X
[pda.sender][pda.recipient][pda.message]
" + //Hacking screen. + if(2) + if(istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot)) + dat += "Brute-forcing for server key.
It will take 20 seconds for every character that the password has." + dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time." + else + //It's the same message as the one above but in binary. Because robots understand binary and humans don't... well I thought it was clever. + dat += {"01000010011100100111010101110100011001010010110
+ 10110011001101111011100100110001101101001011011100110011
+ 10010000001100110011011110111001000100000011100110110010
+ 10111001001110110011001010111001000100000011010110110010
+ 10111100100101110001000000100100101110100001000000111011
+ 10110100101101100011011000010000001110100011000010110101
+ 10110010100100000001100100011000000100000011100110110010
+ 10110001101101111011011100110010001110011001000000110011
+ 00110111101110010001000000110010101110110011001010111001
+ 00111100100100000011000110110100001100001011100100110000
+ 10110001101110100011001010111001000100000011101000110100
+ 00110000101110100001000000111010001101000011001010010000
+ 00111000001100001011100110111001101110111011011110111001
+ 00110010000100000011010000110000101110011001011100010000
+ 00100100101101110001000000111010001101000011001010010000
+ 00110110101100101011000010110111001110100011010010110110
+ 10110010100101100001000000111010001101000011010010111001
+ 10010000001100011011011110110111001110011011011110110110
+ 00110010100100000011000110110000101101110001000000111001
+ 00110010101110110011001010110000101101100001000000111100
+ 10110111101110101011100100010000001110100011100100111010
+ 10110010100100000011010010110111001110100011001010110111
+ 00111010001101001011011110110111001110011001000000110100
+ 10110011000100000011110010110111101110101001000000110110
+ 00110010101110100001000000111001101101111011011010110010
+ 10110111101101110011001010010000001100001011000110110001
+ 10110010101110011011100110010000001101001011101000010111
+ 00010000001001101011000010110101101100101001000000111001
+ 10111010101110010011001010010000001101110011011110010000
+ 00110100001110101011011010110000101101110011100110010000
+ 00110010101101110011101000110010101110010001000000111010
+ 00110100001100101001000000111001001101111011011110110110
+ 10010000001100100011101010111001001101001011011100110011
+ 10010000001110100011010000110000101110100001000000111010
+ 001101001011011010110010100101110"} + + //Fake messages + if(3) + dat += "
Back - Reset

" + + dat += {" + + + + "} + //Sender - Sender's Job - Recepient - Message + //Al Green- Your Dad - Your Mom - WHAT UP!? + + dat += {" + + + "} + dat += "
SenderSender's JobRecipientMessage
[customsender][customjob][customrecepient ? customrecepient.owner : "NONE"][custommessage]

Send" + + //Request Console Logs + if(4) + + var/index = 0 + /* data_rc_msg + X - 5% + var/rec_dpt = "Unspecified" //name of the person - 15% + var/send_dpt = "Unspecified" //name of the sender- 15% + var/message = "Blank" //transferred message - 300px + var/stamp = "Unstamped" - 15% + var/id_auth = "Unauthenticated" - 15% + var/priority = "Normal" - 10% + */ + dat += "
Back - Refresh

" + dat += {" + "} + for(var/datum/data_rc_msg/rc in src.linkedServer.rc_msgs) + index++ + if(index > 3000) + break + // Del - Sender - Recepient - Message + // X - Al Green - Your Mom - WHAT UP!? + dat += {" + "} + dat += "
XSending Dep.Receiving Dep.MessageStampID Auth.Priority.
X
[rc.send_dpt][rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]
" + + message = defaultmsg + + popup.set_content(dat) + popup.open() + return + + + proc/BruteForce(mob/usr as mob) + if(isnull(linkedServer)) + usr << "Could not complete brute-force: Linked Server Disconnected!" + else + var/currentKey = src.linkedServer.decryptkey + usr << "Brute-force completed! The key is '[currentKey]'." + src.hacking = 0 + src.active_state = normal_icon + src.screen = 0 // Return the screen back to normal + + proc/UnmagConsole() + src.active_state = normal_icon + src.emag = 0 + + proc/ResetMessage() + customsender = "System Administrator" + customrecepient = null + custommessage = "This is a test, please ignore." + customjob = "Admin" + + Topic(var/href, var/list/href_list) + if(!interactable() || ..(href,href_list)) + return + + if ("auth" in href_list) + if(auth) + auth = 0 + screen = 0 + else + var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) + if(dkey && dkey != "") + if(src.linkedServer.decryptkey == dkey) + auth = 1 + else + message = incorrectkey + + //Turn the server on/off. + if ("active" in href_list) + if(auth) linkedServer.active = !linkedServer.active + //Find a server + if ("find" in href_list) + if(message_servers && message_servers.len > 1) + src.linkedServer = input(usr,"Please select a server.", "Select a server.", null) as null|anything in message_servers + message = "NOTICE: Server selected." + else if(message_servers && message_servers.len > 0) + linkedServer = message_servers[1] + message = "NOTICE: Only Single Server Detected - Server selected." + else + message = noserver + + //View the logs - KEY REQUIRED + if ("view" in href_list) + if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else + if(auth) + src.screen = 1 + + //Clears the logs - KEY REQUIRED + if ("clear" in href_list) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else + if(auth) + src.linkedServer.pda_msgs = list() + message = "NOTICE: Logs cleared." + //Clears the request console logs - KEY REQUIRED + if ("clearr" in href_list) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else + if(auth) + src.linkedServer.rc_msgs = list() + message = "NOTICE: Logs cleared." + //Change the password - KEY REQUIRED + if ("pass" in href_list) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else + if(auth) + var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) + if(dkey && dkey != "") + if(src.linkedServer.decryptkey == dkey) + var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):")) + if(length(newkey) <= 3) + message = "NOTICE: Decryption key too short!" + else if(length(newkey) > 16) + message = "NOTICE: Decryption key too long!" + else if(newkey && newkey != "") + src.linkedServer.decryptkey = newkey + message = "NOTICE: Decryption key set." + else + message = incorrectkey + + //Hack the Console to get the password + if ("hack" in href_list) + if((istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot)) && (usr.mind.special_role && usr.mind.original == usr)) + src.hacking = 1 + src.screen = 2 + src.active_state = hack_icon + //Time it takes to bruteforce is dependant on the password length. + spawn(100*length(src.linkedServer.decryptkey)) + if(src && src.linkedServer && usr) + BruteForce(usr) + //Delete the log. + if ("delete" in href_list) + //Are they on the view logs screen? + if(screen == 1) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else //if(istype(href_list["delete"], /datum/data_pda_msg)) + src.linkedServer.pda_msgs -= locate(href_list["delete"]) + message = "NOTICE: Log Deleted!" + //Delete the request console log. + if ("deleter" in href_list) + //Are they on the view logs screen? + if(screen == 4) + if(!linkedServer || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else //if(istype(href_list["delete"], /datum/data_pda_msg)) + src.linkedServer.rc_msgs -= locate(href_list["deleter"]) + message = "NOTICE: Log Deleted!" + //Create a custom message + if ("msg" in href_list) + if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else + if(auth) + src.screen = 3 + //Fake messaging selection - KEY REQUIRED + if ("select" in href_list) + if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + screen = 0 + else + switch(href_list["select"]) + + //Reset + if("Reset") + ResetMessage() + + //Select Your Name + if("Sender") + customsender = input(usr, "Please enter the sender's name.") as text|null + + //Select Receiver + if("Recepient") + //Get out list of viable PDAs + var/list/obj/item/device/pda/sendPDAs = list() + for(var/obj/item/device/pda/P in PDAs) + if(!P.owner || P.toff || P.hidden) continue + sendPDAs += P + if(PDAs && PDAs.len > 0) + customrecepient = input(usr, "Select a PDA from the list.") as null|anything in sortAtom(sendPDAs) + else + customrecepient = null + + + //Enter custom job + if("RecJob") + customjob = input(usr, "Please enter the sender's job.") as text|null + + //Enter message + if("Message") + custommessage = input(usr, "Please enter your message.") as text|null + custommessage = copytext(sanitize(custommessage), 1, MAX_MESSAGE_LEN) + + //Send message + if("Send") + + if(isnull(customsender) || customsender == "") + customsender = "UNKNOWN" + + if(isnull(customrecepient)) + message = "NOTICE: No recepient selected!" + return src.attack_hand(usr) + + if(isnull(custommessage) || custommessage == "") + message = "NOTICE: No message entered!" + return src.attack_hand(usr) + + var/obj/item/device/pda/PDARec = null + for (var/obj/item/device/pda/P in PDAs) + if (!P.owner || P.toff || P.hidden) continue + if(P.owner == customsender) + PDARec = P + //Sender isn't faking as someone who exists + if(isnull(PDARec)) + src.linkedServer.send_pda_message("[customrecepient.owner]", "[customsender]","[custommessage]") + customrecepient.tnote += "← From
[customsender] ([customjob]):
[custommessage]
" + if (!customrecepient.silent) + playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1) + for (var/mob/O in hearers(3, customrecepient.loc)) + O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*")) + if( customrecepient.loc && ishuman(customrecepient.loc) ) + var/mob/living/carbon/human/H = customrecepient.loc + H << "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)" + log_pda("[usr] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]") + customrecepient.overlays.Cut() + customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r") + //Sender is faking as someone who exists + else + src.linkedServer.send_pda_message("[customrecepient.owner]", "[PDARec.owner]","[custommessage]") + customrecepient.tnote += "← From [PDARec.owner] ([customjob]):
[custommessage]
" + if (!customrecepient.silent) + playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1) + for (var/mob/O in hearers(3, customrecepient.loc)) + O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*")) + if( customrecepient.loc && ishuman(customrecepient.loc) ) + var/mob/living/carbon/human/H = customrecepient.loc + H << "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)" + log_pda("[usr] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]") + customrecepient.overlays.Cut() + customrecepient.overlays += image('icons/obj/pda.dmi', "pda-r") + //Finally.. + ResetMessage() + + //Request Console Logs - KEY REQUIRED + if("viewr" in href_list) + if(src.linkedServer == null || (src.linkedServer.stat & (NOPOWER|BROKEN))) + message = noserver + else + if(auth) + src.screen = 4 + + //usr << href_list["select"] + + if ("back" in href_list) + src.screen = 0 + interact() \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/pod.dm b/code/WorkInProgress/computer3/computers/pod.dm new file mode 100644 index 0000000000..47f45b1c91 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/pod.dm @@ -0,0 +1,218 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 + +/obj/machinery/computer3/pod + name = "Pod Launch Control" + desc = "A controll for launching pods. Some people prefer firing Mechas." + icon_state = "computer_generic" + var/id = 1.0 + var/obj/machinery/mass_driver/connected = null + var/timing = 0.0 + var/time = 30.0 + var/title = "Mass Driver Controls" + + +/obj/machinery/computer3/pod/New() + ..() + spawn( 5 ) + for(var/obj/machinery/mass_driver/M in world) + if(M.id == id) + connected = M + else + return + return + + +/obj/machinery/computer3/pod/proc/alarm() + if(stat & (NOPOWER|BROKEN)) + return + + if(!( connected )) + viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!" + return + + for(var/obj/machinery/door/poddoor/M in world) + if(M.id == id) + M.open() + return + sleep(20) + + for(var/obj/machinery/mass_driver/M in world) + if(M.id == id) + M.power = connected.power + M.drive() + + sleep(50) + for(var/obj/machinery/door/poddoor/M in world) + if(M.id == id) + M.close() + return + return + + +/obj/machinery/computer3/pod/attackby(I as obj, user as mob) + if(istype(I, /obj/item/tool/screwdriver)) + playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) + if(do_after(user, 20)) + if(stat & BROKEN) + user << "\blue The broken glass falls out." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) + new /obj/item/trash/shard( loc ) + + //generate appropriate circuitboard. Accounts for /pod/old computer types + var/obj/item/part/board/circuit/pod/M = null + if(istype(src, /obj/machinery/computer/pod/old)) + M = new /obj/item/part/board/circuit/olddoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/syndicate)) + M = new /obj/item/part/board/circuit/syndicatedoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/swf)) + M = new /obj/item/part/board/circuit/swfdoor( A ) + else //it's not an old computer. Generate standard pod circuitboard. + M = new /obj/item/part/board/circuit/pod( A ) + + for (var/obj/C in src) + C.loc = loc + M.id = id + A.circuit = M + A.state = 3 + A.icon_state = "3" + A.anchored = 1 + del(src) + else + user << "\blue You disconnect the monitor." + var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) + + //generate appropriate circuitboard. Accounts for /pod/old computer types + var/obj/item/part/board/circuit/pod/M = null + if(istype(src, /obj/machinery/computer/pod/old)) + M = new /obj/item/part/board/circuit/olddoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/syndicate)) + M = new /obj/item/part/board/circuit/syndicatedoor( A ) + if(istype(src, /obj/machinery/computer/pod/old/swf)) + M = new /obj/item/part/board/circuit/swfdoor( A ) + else //it's not an old computer. Generate standard pod circuitboard. + M = new /obj/item/part/board/circuit/pod( A ) + + for (var/obj/C in src) + C.loc = loc + M.id = id + A.circuit = M + A.state = 4 + A.icon_state = "4" + A.anchored = 1 + del(src) + else + attack_hand(user) + return + + +/obj/machinery/computer3/pod/attack_ai(var/mob/user as mob) + return attack_hand(user) + + +/obj/machinery/computer3/pod/attack_paw(var/mob/user as mob) + return attack_hand(user) + + +/obj/machinery/computer3/pod/attack_hand(var/mob/user as mob) + if(..()) + return + + var/dat = "" + user.set_machine(src) + if(connected) + var/d2 + if(timing) //door controls do not need timers. + d2 = "Stop Time Launch" + else + d2 = "Initiate Time Launch" + var/second = time % 60 + var/minute = (time - second) / 60 + dat += "
\nTimer System: [d2]\nTime Left: [minute ? "[minute]:" : null][second] - - + +" + var/temp = "" + var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 ) + for(var/t in L) + if(t == connected.power) + temp += "[t] " + else + temp += "[t] " + dat += "
\nPower Level: [temp]
\nFiring Sequence
\nTest Fire Driver
\nToggle Outer Door
" + else + dat += "
\nToggle Outer Door
" + dat += "

Close" + add_fingerprint(usr) + //user << browse(dat, "window=computer;size=400x500") + //onclose(user, "computer") + var/datum/browser/popup = new(user, "computer", title, 400, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + + +/obj/machinery/computer3/pod/process() + if(!..()) + return + if(timing) + if(time > 0) + time = round(time) - 1 + else + alarm() + time = 0 + timing = 0 + updateDialog() + return + + +/obj/machinery/computer3/pod/Topic(href, href_list) + if(..()) + return + if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + if(href_list["power"]) + var/t = text2num(href_list["power"]) + t = min(max(0.25, t), 16) + if(connected) + connected.power = t + if(href_list["alarm"]) + alarm() + if(href_list["time"]) + timing = text2num(href_list["time"]) + if(href_list["tp"]) + var/tp = text2num(href_list["tp"]) + time += tp + time = min(max(round(time), 0), 120) + if(href_list["door"]) + for(var/obj/machinery/door/poddoor/M in world) + if(M.id == id) + if(M.density) + M.open() + else + M.close() + updateUsrDialog() + return + + + +/obj/machinery/computer3/pod/old + icon_state = "old" + name = "DoorMex Control Console" + title = "Door Controls" + + + +/obj/machinery/computer3/pod/old/syndicate + name = "ProComp Executive IIc" + desc = "The Syndicate operate on a tight budget. Operates external airlocks." + title = "External Airlock Controls" + req_access = list(access_syndicate) + +/obj/machinery/computer3/pod/old/syndicate/attack_hand(var/mob/user as mob) + if(!allowed(user)) + user << "\red Access Denied" + return + else + ..() + +/obj/machinery/computer3/pod/old/swf + name = "Magix System IV" + desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorceror's Edition" diff --git a/code/WorkInProgress/computer3/computers/power.dm b/code/WorkInProgress/computer3/computers/power.dm new file mode 100644 index 0000000000..4bd838a207 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/power.dm @@ -0,0 +1,47 @@ +/obj/machinery/computer3/powermonitor + default_prog = /datum/file/program/powermon + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/cable) + icon_state = "frame-eng" + +/datum/file/program/powermon + name = "power monitoring console" + desc = "It monitors APC status." + active_state = "power" + + proc/format(var/obj/machinery/power/apc/A) + var/static/list/S = list(" Off","AOff"," On", " AOn") + var/static/list/chg = list("N","C","F") + return "[copytext(add_tspace("\The [A.area]", 30), 1, 30)] [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]
" + + interact() + if(!interactable()) + return + if(!computer.net) + computer.Crash(MISSING_PERIPHERAL) + return + var/list/L = computer.net.get_machines(/obj/machinery/power/apc) + var/t = "" + t += "Refresh

" + if(!L || !L.len) + t += "\red No connection" + else + var/datum/powernet/powernet = computer.net.connect_to(/datum/powernet,null) + if(powernet) + t += "
Total power: [powernet.avail] W
Total load: [num2text(powernet.viewload,10)] W
" + else + t += "
Power statistics unavailable
" + t += "" + + if(L.len > 0) + t += "Area Eqp./Lgt./Env. Load Cell
" + for(var/obj/machinery/power/apc/A in L) + t += src.format(A) + t += "
" + + popup.set_content(t) + popup.open() + + Topic(var/href, var/list/href_list) + if(!interactable() || ..(href,href_list)) + return + interact() diff --git a/code/WorkInProgress/computer3/computers/prisoner.dm b/code/WorkInProgress/computer3/computers/prisoner.dm new file mode 100644 index 0000000000..d88a8bffdf --- /dev/null +++ b/code/WorkInProgress/computer3/computers/prisoner.dm @@ -0,0 +1,109 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 + +/obj/machinery/computer3/prisoner + name = "Prisoner Management Comsole" + icon = 'icons/obj/computer.dmi' + icon_state = "explosive" + req_access = list(access_armory) + circuit = "/obj/item/part/board/circuit/prisoner" + var/id = 0.0 + var/temp = null + var/status = 0 + var/timeleft = 60 + var/stop = 0.0 + var/screen = 0 // 0 - No Access Denied, 1 - Access allowed + + + attack_ai(var/mob/user as mob) + return src.attack_hand(user) + + + attack_paw(var/mob/user as mob) + return + + + attack_hand(var/mob/user as mob) + if(..()) + return + user.set_machine(src) + var/dat + dat += "Prisoner Implant Manager System
" + if(screen == 0) + dat += "
Unlock Console" + else if(screen == 1) + dat += "
Chemical Implants
" + var/turf/Tr = null + for(var/obj/item/weapon/implant/chem/C in world) + Tr = get_turf(C) + if((Tr) && (Tr.z != src.z)) continue//Out of range + if(!C.implanted) continue + dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: " + dat += "((1))" + dat += "((5))" + dat += "((10))
" + dat += "********************************
" + dat += "
Tracking Implants
" + for(var/obj/item/weapon/implant/tracking/T in world) + Tr = get_turf(T) + if((Tr) && (Tr.z != src.z)) continue//Out of range + if(!T.implanted) continue + var/loc_display = "Unknown" + var/mob/living/carbon/M = T.imp_in + if(M.z == 1 && !istype(M.loc, /turf/space)) + var/turf/mob_loc = get_turf_loc(M) + loc_display = mob_loc.loc + if(T.malfunction) + loc_display = pick(teleportlocs) + dat += "ID: [T.id] | Location: [loc_display]
" + dat += "(Message Holder) |
" + dat += "********************************
" + dat += "
Lock Console" + + user << browse(dat, "window=computer;size=400x500") + onclose(user, "computer") + return + + + process() + if(!..()) + src.updateDialog() + return + + + Topic(href, href_list) + if(..()) + return + if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + + if(href_list["inject1"]) + var/obj/item/weapon/implant/I = locate(href_list["inject1"]) + if(I) I.activate(1) + + else if(href_list["inject5"]) + var/obj/item/weapon/implant/I = locate(href_list["inject5"]) + if(I) I.activate(5) + + else if(href_list["inject10"]) + var/obj/item/weapon/implant/I = locate(href_list["inject10"]) + if(I) I.activate(10) + + else if(href_list["lock"]) + if(src.allowed(usr)) + screen = !screen + else + usr << "Unauthorized Access." + + else if(href_list["warn"]) + var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN) + if(!warning) return + var/obj/item/weapon/implant/I = locate(href_list["warn"]) + if((I)&&(I.imp_in)) + var/mob/living/carbon/R = I.imp_in + R << "\green You hear a voice in your head saying: '[warning]'" + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + + diff --git a/code/WorkInProgress/computer3/computers/prisonshuttle.dm b/code/WorkInProgress/computer3/computers/prisonshuttle.dm new file mode 100644 index 0000000000..f6f246e578 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/prisonshuttle.dm @@ -0,0 +1,242 @@ +//Config stuff +#define PRISON_MOVETIME 150 //Time to station is milliseconds. +#define PRISON_STATION_AREATYPE "/area/shuttle/prison/station" //Type of the prison shuttle area for station +#define PRISON_DOCK_AREATYPE "/area/shuttle/prison/prison" //Type of the prison shuttle area for dock + +var/prison_shuttle_moving_to_station = 0 +var/prison_shuttle_moving_to_prison = 0 +var/prison_shuttle_at_station = 0 +var/prison_shuttle_can_send = 1 +var/prison_shuttle_time = 0 +var/prison_shuttle_timeleft = 0 + +/obj/machinery/computer3/prison_shuttle + name = "Prison Shuttle Console" + icon = 'icons/obj/computer.dmi' + icon_state = "shuttle" + req_access = list(access_security) + circuit = "/obj/item/part/board/circuit/prison_shuttle" + var/temp = null + var/hacked = 0 + var/allowedtocall = 0 + var/prison_break = 0 + + + attackby(I as obj, user as mob) + return src.attack_hand(user) + + + attack_ai(var/mob/user as mob) + return src.attack_hand(user) + + + attack_paw(var/mob/user as mob) + return src.attack_hand(user) + + + attackby(I as obj, user as mob) + if(istype(I, /obj/item/tool/screwdriver)) + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + if(do_after(user, 20)) + var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) + var/obj/item/part/board/circuit/prison_shuttle/M = new /obj/item/part/board/circuit/prison_shuttle( A ) + for (var/obj/C in src) + C.loc = src.loc + A.circuit = M + A.anchored = 1 + + if (src.stat & BROKEN) + user << "\blue The broken glass falls out." + new /obj/item/trash/shard( src.loc ) + A.state = 3 + A.icon_state = "3" + else + user << "\blue You disconnect the monitor." + A.state = 4 + A.icon_state = "4" + + del(src) + else if(istype(I,/obj/item/card/emag) && (!hacked)) + hacked = 1 + user << "\blue You disable the lock." + else + return src.attack_hand(user) + + + attack_hand(var/mob/user as mob) + if(!src.allowed(user) && (!hacked)) + user << "\red Access Denied." + return + if(prison_break) + user << "\red Unable to locate shuttle." + return + if(..()) + return + user.set_machine(src) + post_signal("prison") + var/dat + if (src.temp) + dat = src.temp + else + dat += {"Location: [prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison ? "Moving to station ([prison_shuttle_timeleft] Secs.)":prison_shuttle_at_station ? "Station":"Dock"]
+ [prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison ? "\n*Shuttle already called*
\n
":prison_shuttle_at_station ? "\nSend to Dock
\n
":"\nSend to Station
\n
"] + \nClose"} + + //user << browse(dat, "window=computer;size=575x450") + //onclose(user, "computer") + var/datum/browser/popup = new(user, "computer", name, 575, 450) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + + + Topic(href, href_list) + if(..()) + return + + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + + if (href_list["sendtodock"]) + if (!prison_can_move()) + usr << "\red The prison shuttle is unable to leave." + return + if(!prison_shuttle_at_station|| prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison) return + post_signal("prison") + usr << "\blue The prison shuttle has been called and will arrive in [(PRISON_MOVETIME/10)] seconds." + src.temp += "Shuttle sent.

OK" + src.updateUsrDialog() + prison_shuttle_moving_to_prison = 1 + prison_shuttle_time = world.timeofday + PRISON_MOVETIME + spawn(0) + prison_process() + + else if (href_list["sendtostation"]) + if (!prison_can_move()) + usr << "\red The prison shuttle is unable to leave." + return + if(prison_shuttle_at_station || prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison) return + post_signal("prison") + usr << "\blue The prison shuttle has been called and will arrive in [(PRISON_MOVETIME/10)] seconds." + src.temp += "Shuttle sent.

OK" + src.updateUsrDialog() + prison_shuttle_moving_to_station = 1 + prison_shuttle_time = world.timeofday + PRISON_MOVETIME + spawn(0) + prison_process() + + else if (href_list["mainmenu"]) + src.temp = null + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + + + proc/prison_can_move() + if(prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison) return 0 + else return 1 + +/* + proc/prison_break() + switch(prison_break) + if (0) + if(!prison_shuttle_at_station || prison_shuttle_moving_to_prison) return + + prison_shuttle_moving_to_prison = 1 + prison_shuttle_at_station = prison_shuttle_at_station + + if (!prison_shuttle_moving_to_prison || !prison_shuttle_moving_to_station) + prison_shuttle_time = world.timeofday + PRISON_MOVETIME + spawn(0) + prison_process() + prison_break = 1 + if(1) + prison_break = 0 +*/ + + proc/post_signal(var/command) + var/datum/radio_frequency/frequency = radio_controller.return_frequency(1311) + if(!frequency) return + var/datum/signal/status_signal = new + status_signal.source = src + status_signal.transmission_method = 1 + status_signal.data["command"] = command + frequency.post_signal(src, status_signal) + return + + + proc/prison_process() + while(prison_shuttle_time - world.timeofday > 0) + var/ticksleft = prison_shuttle_time - world.timeofday + + if(ticksleft > 1e5) + prison_shuttle_time = world.timeofday + 10 // midnight rollover + + prison_shuttle_timeleft = (ticksleft / 10) + sleep(5) + prison_shuttle_moving_to_station = 0 + prison_shuttle_moving_to_prison = 0 + + switch(prison_shuttle_at_station) + + if(0) + prison_shuttle_at_station = 1 + if (prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison) return + + if (!prison_can_move()) + usr << "\red The prison shuttle is unable to leave." + return + + var/area/start_location = locate(/area/shuttle/prison/prison) + var/area/end_location = locate(/area/shuttle/prison/station) + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in end_location) + dstturfs += T + if(T.y < throwy) + throwy = T.y + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + if(istype(T, /turf/simulated)) + del(T) + start_location.move_contents_to(end_location) + + if(1) + prison_shuttle_at_station = 0 + if (prison_shuttle_moving_to_station || prison_shuttle_moving_to_prison) return + + if (!prison_can_move()) + usr << "\red The prison shuttle is unable to leave." + return + + var/area/start_location = locate(/area/shuttle/prison/station) + var/area/end_location = locate(/area/shuttle/prison/prison) + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in end_location) + dstturfs += T + if(T.y < throwy) + throwy = T.y + + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + if(istype(T, /turf/simulated)) + del(T) + start_location.move_contents_to(end_location) + return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/robot.dm b/code/WorkInProgress/computer3/computers/robot.dm new file mode 100644 index 0000000000..e3eca9ace2 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/robot.dm @@ -0,0 +1,211 @@ +/obj/machinery/computer3/robotics + default_prog = /datum/file/program/borg_control + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) + icon_state = "frame-rnd" + +/datum/file/program/borg_control + name = "Cyborg Control" + desc = "Used to remotely lockdown or detonate linked Cyborgs." + active_state = "robot" + var/id = 0.0 + var/temp = null + var/status = 0 + var/timeleft = 60 + var/stop = 0.0 + var/screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text + req_access = list(access_robotics) + + proc/start_sequence() + do + if(src.stop) + src.stop = 0 + return + src.timeleft-- + sleep(10) + while(src.timeleft) + + for(var/mob/living/silicon/robot/R in mob_list) + if(!R.scrambledcodes) + R.self_destruct() + return + + + interact() + if(!interactable() || computer.z > 6) + return + var/dat + if (src.temp) + dat = "[src.temp]

Clear Screen" + else + if(screen == 0) + //dat += "

Cyborg Control Console


" + dat += "1. Cyborg Status
" + dat += "2. Emergency Full Destruct
" + if(screen == 1) + for(var/mob/living/silicon/robot/R in mob_list) + if(istype(usr, /mob/living/silicon/ai)) + if (R.connected_ai != usr) + continue + if(istype(usr, /mob/living/silicon/robot)) + if (R != usr) + continue + if(R.scrambledcodes) + continue + + dat += "[R.name] |" + if(R.stat) + dat += " Not Responding |" + else if (!R.canmove) + dat += " Locked Down |" + else + dat += " Operating Normally |" + if (!R.canmove) + else if(R.cell) + dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |" + else + dat += " No Cell Installed |" + if(R.module) + dat += " Module Installed ([R.module.name]) |" + else + dat += " No Module Installed |" + if(R.connected_ai) + dat += " Slaved to [R.connected_ai.name] |" + else + dat += " Independent from AI |" + if (istype(usr, /mob/living/silicon)) + if(issilicon(usr) && is_special_character(usr) && !R.emagged) + dat += "(Hack) " + dat += "([R.canmove ? "Lockdown" : "Release"]) " + dat += "(Destroy)" + dat += "
" + dat += "(Return to Main Menu)
" + if(screen == 2) + if(!src.status) + dat += {"
Emergency Robot Self-Destruct
\nStatus: Off
+ \n
+ \nCountdown: [src.timeleft]/60 \[Reset\]
+ \n
+ \nStart Sequence
+ \n
+ \nClose"} + else + dat = {"Emergency Robot Self-Destruct
\nStatus: Activated
+ \n
+ \nCountdown: [src.timeleft]/60 \[Reset\]
+ \n
\nStop Sequence
+ \n
+ \nClose"} + dat += "(Return to Main Menu)
" + + popup.set_content(dat) + popup.open() + return + + Topic(var/href, var/list/href_list) + if(!interactable() || ..(href,href_list)) + return + + if ("killall" in href_list) + src.temp = {"Destroy Robots?
+
\[Swipe ID to initiate destruction sequence\]
+ Cancel"} + + if ("do_killall" in href_list) + var/obj/item/weapon/card/id/I = usr.get_active_hand() + if (istype(I, /obj/item/device/pda)) + var/obj/item/device/pda/pda = I + I = pda.id + if (istype(I)) + if(src.check_access(I)) + if (!status) + message_admins("\blue [key_name_admin(usr)] has initiated the global cyborg killswitch!") + log_game("\blue [key_name(usr)] has initiated the global cyborg killswitch!") + src.status = 1 + src.start_sequence() + src.temp = null + + else + usr << "\red Access Denied." + + if ("stop" in href_list) + src.temp = {" + Stop Robot Destruction Sequence?
+
Yes
+ No"} + + if ("stop2" in href_list) + src.stop = 1 + src.temp = null + src.status = 0 + + if ("reset" in href_list) + src.timeleft = 60 + + if ("temp" in href_list) + src.temp = null + if ("screen" in href_list) + switch(href_list["screen"]) + if("0") + screen = 0 + if("1") + screen = 1 + if("2") + screen = 2 + if ("killbot" in href_list) + if(computer.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["killbot"]) + if(R) + var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm") + if(R && istype(R)) + if(R.mind && R.mind.special_role && R.emagged) + R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered." + R.ResetSecurityCodes() + + else + message_admins("\blue [key_name_admin(usr)] detonated [R.name]!") + log_game("\blue [key_name_admin(usr)] detonated [R.name]!") + R.self_destruct() + else + usr << "\red Access Denied." + + if ("stopbot" in href_list) + if(computer.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) + if(R && istype(R)) // Extra sancheck because of input var references + var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm") + if(R && istype(R)) + message_admins("\blue [key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") + log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") + R.canmove = !R.canmove + if (R.lockcharge) + // R.cell.charge = R.lockcharge + R.lockcharge = !R.lockcharge + R << "Your lockdown has been lifted!" + else + R.lockcharge = !R.lockcharge + // R.cell.charge = 0 + R << "You have been locked down!" + + else + usr << "\red Access Denied." + + if ("magbot" in href_list) + if(computer.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["magbot"]) + if(R) + var/choice = input("Are you certain you wish to hack [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm") + if(R && istype(R)) +// message_admins("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!") + log_game("[key_name(usr)] emagged [R.name] using robotic console!") + R.emagged = 1 + if(R.mind.special_role) + R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes + + interact() + return + + + diff --git a/code/WorkInProgress/computer3/computers/scanconsole.dm b/code/WorkInProgress/computer3/computers/scanconsole.dm new file mode 100644 index 0000000000..3092f51fb8 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/scanconsole.dm @@ -0,0 +1,1274 @@ +/obj/machinery/computer3/scan_consolenew + default_prog = /datum/file/program/dnascanner + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/storage/removable,/obj/item/part/computer/networking/prox) + + +#define MAX_UIBLOCK 13 +#define MAX_SEBLOCK 14 + +/datum/file/program/dnascanner + name = "DNA Scanner and Manipulator" + desc = "The DNA ScaM is sure to change your life forever." + active_state = "dna" + var/obj/machinery/dna_scannernew/scanner = null + + var/ui_block = 1 + var/se_block = 1 + var/subblock = 1 + + var/uitarget = 1 + var/uitargethex = "1" + + var/radduration = 2 + var/radstrength = 1 + + var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete + + var/mode = 0 + // These keep track of the patient status + var/present = 0 + var/viable = 0 + + var/bufferlabel = "" + var/datum/dna/buffer = null + var/obj/item/part/computer/target_drive = null + + Reset() + ..() + mode = 0 + scanner = null + ui_block = 1 + se_block = 1 + subblock = 1 + buffer = null + bufferlabel = "" + + + Topic(var/href, var/list/href_list) + if(!interactable() || !computer.net || ..(href,href_list)) + return + + scanner = computer.net.connect_to(/obj/machinery/dna_scannernew, scanner) // if exists, will be verified + if(!scanner) + computer.Crash(NETWORK_FAILURE) + return + + // todo check everything goddamnit + present = scanner.occupant && scanner.occupant.dna + viable = present && !(NOCLONE in scanner.occupant.mutations) + + // current screen/function + if("mode" in href_list) + mode = text2num(href_list["mode"]) + // locks scanner door + if("lock" in href_list) + scanner.locked = !scanner.locked + + // inject good-juice + if("rejuv" in href_list) + rejuv() + + // expose to radiation, controlled otherwise + if("pulse" in href_list) + pulse(href_list["pulse"]) // ui, se, or nothing/null + + if("duration" in href_list) + var/modifier = text2num(href_list["duration"]) + radduration += modifier + if("strength" in href_list) + var/modifier = text2num(href_list["strength"]) + radstrength += modifier + + if("uiblock" in href_list) + ui_block = text2num(href_list["uiblock"]) + if("seblock" in href_list) + se_block = text2num(href_list["seblock"]) + if("subblock" in href_list) + subblock = text2num(href_list["subblock"]) + if("uitarget" in href_list) + uitarget = text2num(href_list["uitarget"]) + uitargethex = num2hex(uitarget) + + // save dna to buffer - buffer=se,ui,ue,all,clear + if("buffer" in href_list) + if(!viable) + return + var/which = href_list["buffer"] + if(!which || which == "clear") + buffer = null + else + if(!buffer) + buffer = new + if( which == "all" ) + buffer.unique_enzymes = scanner.occupant.dna.unique_enzymes + buffer.struc_enzymes = scanner.occupant.dna.struc_enzymes + buffer.uni_identity = scanner.occupant.dna.uni_identity + buffer.real_name = scanner.occupant.dna.real_name + buffer.mutantrace = scanner.occupant.dna.mutantrace + if( which == "se" ) + buffer.struc_enzymes = scanner.occupant.dna.struc_enzymes + buffer.mutantrace = scanner.occupant.dna.mutantrace + if( which == "ui" ) + buffer.uni_identity = scanner.occupant.dna.uni_identity + if( which == "ue" ) + buffer.uni_identity = scanner.occupant.dna.uni_identity + buffer.unique_enzymes = scanner.occupant.dna.unique_enzymes + buffer.real_name = scanner.occupant.dna.real_name + + // save buffer to file - + if("save" in href_list) + if(!viable || !buffer) + return + var/datum/file/data/genome/G = null + var/obj/item/part/computer/dest = device + if(target_drive) + dest = target_drive + + switch(href_list["save"]) + if("se") + if(buffer.struc_enzymes) + G = new /datum/file/data/genome/SE() + G.content = buffer.struc_enzymes + G:mutantrace = buffer.mutantrace // : not . due to inheritance + G.real_name = buffer.real_name + if("ui") + if(buffer.uni_identity) + G = new /datum/file/data/genome/UI() + G.content = buffer.uni_identity + G.real_name = buffer.real_name + if("ue") + if(buffer.uni_identity) + G = new /datum/file/data/genome/UI/UE() + G.content = buffer.uni_identity + G.real_name = buffer.real_name + if(G && dest) + var/label = input(usr, "Enter a filename:", "Save file", buffer.real_name) as text + G.name = G.name + "([label])" + dest:addfile(G) + + // load buffer from file + if("load" in href_list) + var/datum/file/data/genome/G = locate(href_list["load"]) + if(G) + if(!buffer) + buffer = new + switch(G.type) + if(/datum/file/data/genome/SE) + buffer.struc_enzymes = G.content + buffer.mutantrace = G:mutantrace + if(/datum/file/data/genome/UI/UE) + buffer.uni_identity = G.content + buffer.real_name = G.real_name + buffer.unique_enzymes = md5(buffer.real_name) + if(/datum/file/data/genome/UI) + buffer.uni_identity = G.content + if(/datum/file/data/genome/cloning) + var/datum/dna/record = G:record + buffer.unique_enzymes = record.unique_enzymes + buffer.struc_enzymes = record.struc_enzymes + buffer.uni_identity = record.uni_identity + buffer.real_name = record.real_name + buffer.mutantrace = record.mutantrace + + + // inject genetics into occupant + if("inject" in href_list) + if(!buffer || !viable) + return + + var/which = href_list["inject"] + var/datum/dna/target = scanner.occupant.dna + switch(which) + if("all",null) + if(buffer.struc_enzymes) + target.struc_enzymes = buffer.struc_enzymes + if(buffer.uni_identity) + target.uni_identity = buffer.uni_identity + if(buffer.real_name) + target.real_name = buffer.real_name + target.unique_enzymes = md5(target.real_name) + updateappearance(scanner.occupant,target.uni_identity) + domutcheck(scanner.occupant, scanner, 1) + + if(ishuman(scanner.occupant)) + target.mutantrace = buffer.mutantrace + scanner.occupant:update_mutantrace() + if("se") + if(buffer.struc_enzymes) + target.struc_enzymes = buffer.struc_enzymes + domutcheck(scanner.occupant, scanner, 1) + if(ishuman(scanner.occupant)) + target.mutantrace = buffer.mutantrace + scanner.occupant:update_mutantrace() + if("ui") + if(buffer.uni_identity) + target.uni_identity = buffer.uni_identity + updateappearance(scanner.occupant,target.uni_identity) + if("ue") + if(buffer.uni_identity) + target.uni_identity = buffer.uni_identity + if(buffer.real_name) + target.real_name = buffer.real_name + target.unique_enzymes = md5(target.real_name) + updateappearance(scanner.occupant,target.uni_identity) + + // generate dna injector + if("generate" in href_list) + if(!buffer || !injectorready) + return + buffer.check_integrity() + var/which = href_list["generate"] + var/obj/item/weapon/dnainjector/inj + switch(which) + if("se") + inj = new(computer.loc) + inj.dnatype = "se" + inj.dna = buffer.struc_enzymes + inj.mutantrace = buffer.mutantrace + inj.name = "Structural Enzymes" + if("ui") + inj = new(computer.loc) + inj.dnatype = "ui" + inj.dna = buffer.uni_identity + inj.ue = null + inj.name = "Unique Identifiers" + if("ue") + inj = new(computer.loc) + inj.dnatype = "ui" + inj.dna = buffer.uni_identity + inj.ue = buffer.real_name + inj.name = "Unique Enzymes + Unique Identifiers" + if(inj) + injectorready = 0 + spawn(300) + injectorready = 1 + var/label = input(usr, "Enter a label", "Label [inj.name] Injector", buffer.real_name) as null|text + if(label && inj) // it's possible it was deleted before we get here, input suspends execution + inj.name += " ([label])" + + interact() + return // putting this in there to visually mark the end of topic() while I do other things + + proc/menu() + if(!present && (mode==1 || mode==2)) // require viable occupant + mode = 0 + switch(mode) + if(0) // MAIN MENU + return main_menu() + + if(1) + return ui_menu() + if(2) + return se_menu() + + if(3) + return emitter_menu() + + if(4) + return buffer_menu() + + // unified header with health data + // option to show UI,UE,SE as plaintext + proc/status_display(var/dna_summary = 0) + var/mob/living/occupant = scanner.occupant + var/status_html + if(viable) + status_html = "
Health:
[occupant.health]%
" + status_html += "
Radiation Level:
[occupant.radiation]%
" + if(ishuman(occupant)) + var/rejuvenators = round(occupant.reagents.get_reagent_amount("inaprovaline") / REJUVENATORS_MAX * 100) + status_html += "
Rejuvenators:
[occupant.reagents.get_reagent_amount("inaprovaline")] units
" + + if (dna_summary) + status_html += "
Unique Enzymes :
[uppertext(occupant.dna.unique_enzymes)]
" + status_html += "
Unique Identifier:
[occupant.dna.uni_identity]
" + status_html += "
Structural Enzymes:
[occupant.dna.struc_enzymes]
" + + var/occupant_status = "Scanner Unoccupied" + if(present) + if(!viable) + occupant_status = "Invalid DNA structure" + else + switch(occupant.stat) // obvious, see what their status is + if(0) + occupant_status = "Conscious" + if(1) + occupant_status = "Unconscious" + else + occupant_status = "DEAD" + + occupant_status = "[occupant.name] => [occupant_status]
" + var/dat = "

Scanner Status

[topic_link(src,"","Scan")]
[occupant_status][status_html]
" + if(present) + dat += topic_link(src,"lock",scanner.locked?"Unlock Scanner":"Lock Scanner") + " " + topic_link(src,"rejuv","Inject Rejuvenators") + else + dat += "[scanner.locked?"Unlock Scanner":"Lock Scanner"] Inject Rejuvenators" + return dat + + proc/main_menu() + var/dat = status_display(dna_summary = 1) + dat += "

Main Menu

" + if(present) + dat += topic_link(src,"mode=1","Modify Unique Identifier") + "
" + topic_link(src,"mode=2","Modify Structural Enzymes") + "

" + else + dat += "Modify Unique Identifier
Modify Structural Enzymes

" + dat += topic_link(src,"mode=3","Radiation Emitter Settings") + "

" + topic_link(src,"mode=4","Transfer Buffer") + return dat + + + proc/block_plus_minus(var/topicstr, var/blockval,var/min,var/max) + var/left = blockval - 1 + var/right = blockval + 1 + if(left < min) + left = max + if(right > max) + right = min + return topic_link(src,"[topicstr]=[left]","<-") + " [blockval] " + topic_link(src,"[topicstr]=[right]","->") + + + proc/getblockstring(var/ui = 0) + var/mainblock = "seblock" + var/block = se_block + var/input = scanner.occupant.dna.struc_enzymes + if(ui) + mainblock = "uiblock" + block = ui_block + input = scanner.occupant.dna.uni_identity + + var/string = "
" + var/subpos = 1 // keeps track of the current sub block + var/blockpos = 1 + + for(var/i = 1, i <= length(input), i++) // loop through each letter + + if(blockpos == block && subpos == subblock) // if the current block/subblock is selected, mark it + string += fake_link(copytext(input,i,i+1)) + else + string += topic_link(src,"[mainblock]=[blockpos];subblock=[subpos]",copytext(input,i,i+1)) + + subpos++ + if(subpos > 3) // add a line break for every block + string += "
" + subpos = 1 + blockpos++ + + string += "
" + return string + + proc/ui_menu() + if(!viable) + return "No viable occupant detected." + var/dat = topic_link(src,"mode=0","<< Main Menu") + "
" + dat += "

Modify Unique Identifier

" + dat += "
Unique Identifier:
[getblockstring(ui=1)]

" + + dat += "Selected Block: " + block_plus_minus("uiblock",ui_block,1,MAX_UIBLOCK) + "

" + dat += "Selected Sub-Block: " + block_plus_minus("subblock",subblock,1,3) + "

" + dat += "Selected Target: " + block_plus_minus("uitarget",uitarget,0,15) + "

" + dat += "Modify Block
" + dat += topic_link(src,"pulse=ui","Irradiate") + "
" + return dat + + proc/se_menu() + if(!viable) + return "No viable occupant detected." + var/dat = topic_link(src,"mode=0","<< Main Menu") + "
" + dat += "

Modify Structural Enzymes

" + dat += "
Structural Enzymes: [getblockstring(ui=0)]

" + dat += "Selected Block: " + block_plus_minus("seblock",se_block,1,MAX_SEBLOCK) + "

" + dat += "Selected Sub-Block: " + block_plus_minus("subblock",subblock,1,3) + "

" + dat += "Modify Block
" + dat += topic_link(src,"pulse=se","Irradiate") + "
" + return dat + + proc/emitter_menu() + var/dat = topic_link(src,"mode=0","<< Main Menu") + "
" + dat += "

Radiation Emitter Settings

" + if (viable) + dat += topic_link(src,"pulse","Pulse Radiation") + else + dat += fake_link("Pulse Radiation") + dat += "

" + dat += "Radiation Duration: " + block_plus_minus("duration",radduration,1,20) + "
" + dat += "Radiation Intensity: " + block_plus_minus("strength",radstrength,1,10) + "

" + return dat + + proc/buffer_menu() + + interact() + if(!interactable()) + return + popup.add_stylesheet("scannernew", 'html/browser/scannernew.css') + + if(!computer.net) + computer.Crash(MISSING_PERIPHERAL) + return + + scanner = computer.net.connect_to(/obj/machinery/dna_scannernew, scanner) // if exists, will be verified + if(!scanner) + computer.Crash(NETWORK_FAILURE) + return + + // todo check everything goddamnit + + present = scanner.occupant && scanner.occupant.dna + viable = present && !(NOCLONE in scanner.occupant.mutations) + + popup.set_content(menu()) + popup.open() + + proc/pulse(var/target as null|anything in list("ui","se")) + + //Makes sure someone is in there (And valid) before trying anything + //More than anything, this just acts as a sanity check in case the option DOES appear for whatever reason + + if(target != "ui" && target != "se") + target = null + + // transforms into the fail condition instead of having it in yet another nested if block + else if( prob(20 - (radduration / 2))) + target += "-f" + + if(!viable) + popup.set_content("No viable occupant detected.") + popup.open() + else + popup.set_content("Working ... Please wait ([radduration]) Seconds)") + popup.open() + + var/lock_state = scanner.locked + scanner.locked = 1//lock it + sleep(10*radduration) + + switch(target) + if("ui") + var/ui = scanner.occupant.dna.uni_identity + var/block = getblock(ui,ui_block,3) + var/result = "" + for(var/sb = 1; sb <=3; sb++) + var/temp = copytext(block,sb,sb+1) + if(sb == subblock) + temp = miniscramble("[uitargethex]",radstrength,radduration) + result += temp + scanner.occupant.dna.uni_identity = setblock(ui, ui_block, result,3) + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + scanner.occupant.radiation += (radstrength+radduration) + if("ui-f") + if (prob(20+radstrength)) + randmutb(scanner.occupant) + domutcheck(scanner.occupant,scanner) + else + randmuti(scanner.occupant) + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + scanner.occupant.radiation += ((radstrength*2)+radduration) + + if("se") + var/se = scanner.occupant.dna.struc_enzymes + var/targetblock = se_block + + if (!(se_block in list(2,8,10,12)) && prob (20)) // shifts the target slightly + if (se_block <= 5) + targetblock++ + else + targetblock-- + var/block = getblock(scanner.occupant.dna.struc_enzymes,targetblock,3) + + var/result = "" + for(var/sb = 1; sb <=3; sb++) + var/temp = copytext(block,sb,sb+1) + if(sb == subblock) + temp = miniscramble(temp,radstrength,radduration) + result += temp + + scanner.occupant.dna.struc_enzymes = setblock(se, se_block, result,3) + domutcheck(scanner.occupant,scanner) + scanner.occupant.radiation += (radstrength+radduration) + if("se-f") + if (prob(80-radduration)) + randmutb(scanner.occupant) + domutcheck(scanner.occupant,scanner) + else + randmuti(scanner.occupant) + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + scanner.occupant.radiation += ((radstrength*2)+radduration) + + if(null) + if (prob(95)) + if(prob(75)) + randmutb(scanner.occupant) + else + randmuti(scanner.occupant) + else + if(prob(95)) + randmutg(scanner.occupant) + else + randmuti(scanner.occupant) + scanner.occupant.radiation += ((radstrength*3)+radduration*3) + + + scanner.locked = lock_state + interact() + + proc/rejuv() + if(!viable) + popup.set_content("No viable occupant detected.") + popup.open() + var/mob/living/carbon/human/H = scanner.occupant + if(istype(H)) + var/inap = H.reagents.get_reagent_amount("inaprovaline") // oh my *god* this section was ugly before I shortened it + + if (inap < (REJUVENATORS_MAX - REJUVENATORS_INJECT)) + H.reagents.add_reagent("inaprovaline", REJUVENATORS_INJECT) + else + H.reagents.add_reagent("inaprovaline", max(REJUVENATORS_MAX - inap,0)) + +/* +/obj/machinery/computer/scan_consolenew/Topic(href, href_list) + + temp_html = null + var/temp_header_html = null + var/temp_footer_html = null + + scanner_status_html = null // Scanner status is reset each update + var/mob/living/occupant = scanner.occupant + var/viable_occupant = (occupant && occupant.dna && !(NOCLONE in occupant.mutations)) + var/mob/living/carbon/human/human_occupant = scanner.occupant + + if (href_list["screen"]) // Passing a screen is only a request, we set current_screen here but it can be overridden below if necessary + current_screen = href_list["screen"] + + if (!viable_occupant) // If there is no viable occupant only allow certain screens + var/allowed_no_occupant_screens = list("mainmenu", "radsetmenu", "buffermenu") //These are the screens which will be allowed if there's no occupant + if (!(current_screen in allowed_no_occupant_screens)) + href_list = new /list(0) // clear list of options + current_screen = "mainmenu" + + + if (!current_screen) // If no screen is set default to mainmenu + current_screen = "mainmenu" + + + if (!scanner) //Is the scanner not connected? + scanner_status_html = "ERROR: No DNA Scanner connected." + current_screen = null // blank does not exist in the switch below, so no screen will be outputted + updateUsrDialog() + return + + usr.set_machine(src) + if (href_list["locked"]) + if (scanner.occupant) + scanner.locked = !( scanner.locked ) + //////////////////////////////////////////////////////// + if (href_list["genpulse"]) + if(!viable_occupant)//Makes sure someone is in there (And valid) before trying anything + temp_html = text("No viable occupant detected.")//More than anything, this just acts as a sanity check in case the option DOES appear for whatever reason + //usr << browse(temp_html, "window=scannernew;size=550x650") + //onclose(usr, "scannernew") + popup.set_content(temp_html) + popup.open() + else + + temp_html = text("Working ... Please wait ([] Seconds)", radduration) + popup.set_content(temp_html) + popup.open() + var/lock_state = scanner.locked + scanner.locked = 1//lock it + sleep(10*radduration) + if (!scanner.occupant) + temp_html = null + return null + if (prob(95)) + if(prob(75)) + randmutb(scanner.occupant) + else + randmuti(scanner.occupant) + else + if(prob(95)) + randmutg(scanner.occupant) + else + randmuti(scanner.occupant) + scanner.occupant.radiation += ((radstrength*3)+radduration*3) + scanner.locked = lock_state + temp_html = null + dopage(src,"screen=radsetmenu") + if (href_list["radleplus"]) + if(!viable_occupant) + temp_html = text("No viable occupant detected.") + popup.set_content(temp_html) + popup.open() + if (radduration < 20) + radduration++ + radduration++ + dopage(src,"screen=radsetmenu") + if (href_list["radleminus"]) + if(!viable_occupant) + temp_html = text("No viable occupant detected.") + popup.set_content(temp_html) + popup.open() + if (radduration > 2) + radduration-- + radduration-- + dopage(src,"screen=radsetmenu") + if (href_list["radinplus"]) + if (radstrength < 10) + radstrength++ + dopage(src,"screen=radsetmenu") + if (href_list["radinminus"]) + if (radstrength > 1) + radstrength-- + dopage(src,"screen=radsetmenu") + //////////////////////////////////////////////////////// + if (href_list["unimenuplus"]) + if (ui_block < 13) + ui_block++ + else + ui_block = 1 + dopage(src,"screen=unimenu") + if (href_list["unimenuminus"]) + if (ui_block > 1) + ui_block-- + else + ui_block = 13 + dopage(src,"screen=unimenu") + if (href_list["unimenusubplus"]) + if (subblock < 3) + subblock++ + else + subblock = 1 + dopage(src,"screen=unimenu") + if (href_list["unimenusubminus"]) + if (subblock > 1) + subblock-- + else + subblock = 3 + dopage(src,"screen=unimenu") + if (href_list["unimenutargetplus"]) + if (unitarget < 15) + unitarget++ + unitargethex = unitarget + switch(unitarget) + if(10) + unitargethex = "A" + if(11) + unitargethex = "B" + if(12) + unitargethex = "C" + if(13) + unitargethex = "D" + if(14) + unitargethex = "E" + if(15) + unitargethex = "F" + else + unitarget = 0 + unitargethex = 0 + dopage(src,"screen=unimenu") + if (href_list["unimenutargetminus"]) + if (unitarget > 0) + unitarget-- + unitargethex = unitarget + switch(unitarget) + if(10) + unitargethex = "A" + if(11) + unitargethex = "B" + if(12) + unitargethex = "C" + if(13) + unitargethex = "D" + if(14) + unitargethex = "E" + else + unitarget = 15 + unitargethex = "F" + dopage(src,"screen=unimenu") + if (href_list["uimenuset"] && href_list["uimenusubset"]) // This chunk of code updates selected block / sub-block based on click + var/menuset = text2num(href_list["uimenuset"]) + var/menusubset = text2num(href_list["uimenusubset"]) + if ((menuset <= 13) && (menuset >= 1)) + ui_block = menuset + if ((menusubset <= 3) && (menusubset >= 1)) + subblock = menusubset + dopage(src, "unimenu") + if (href_list["unipulse"]) + if(scanner.occupant) + var/block + var/newblock + var/tstructure2 + block = getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),subblock,1) + + temp_html = text("Working ... Please wait ([] Seconds)", radduration) + popup.set_content(temp_html) + popup.open() + var/lock_state = scanner.locked + scanner.locked = 1//lock it + sleep(10*radduration) + if (!scanner.occupant) + temp_html = null + return null + /// + if (prob((80 + (radduration / 2)))) + block = miniscrambletarget(num2text(unitarget), radstrength, radduration) + newblock = null + if (subblock == 1) newblock = block + getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),2,1) + getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),3,1) + if (subblock == 2) newblock = getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),1,1) + block + getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),3,1) + if (subblock == 3) newblock = getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),1,1) + getblock(getblock(scanner.occupant.dna.uni_identity,ui_block,3),2,1) + block + tstructure2 = setblock(scanner.occupant.dna.uni_identity, ui_block, newblock,3) + scanner.occupant.dna.uni_identity = tstructure2 + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + scanner.occupant.radiation += (radstrength+radduration) + else + if (prob(20+radstrength)) + randmutb(scanner.occupant) + domutcheck(scanner.occupant,scanner) + else + randmuti(scanner.occupant) + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + scanner.occupant.radiation += ((radstrength*2)+radduration) + scanner.locked = lock_state + dopage(src,"screen=unimenu") + + //////////////////////////////////////////////////////// + if (href_list["rejuv"]) + if(!viable_occupant) + temp_html = text("No viable occupant detected.") + popup.set_content(temp_html) + popup.open() + else + if(human_occupant) + if (human_occupant.reagents.get_reagent_amount("inaprovaline") < REJUVENATORS_MAX) + if (human_occupant.reagents.get_reagent_amount("inaprovaline") < (REJUVENATORS_MAX - REJUVENATORS_INJECT)) + human_occupant.reagents.add_reagent("inaprovaline", REJUVENATORS_INJECT) + else + human_occupant.reagents.add_reagent("inaprovaline", round(REJUVENATORS_MAX - human_occupant.reagents.get_reagent_amount("inaprovaline"))) + //usr << text("Occupant now has [] units of rejuvenation in his/her bloodstream.", human_occupant.reagents.get_reagent_amount("inaprovaline")) + + //////////////////////////////////////////////////////// + if (href_list["strucmenuplus"]) + if (se_block < 14) + se_block++ + else + se_block = 1 + dopage(src,"screen=strucmenu") + if (href_list["strucmenuminus"]) + if (se_block > 1) + se_block-- + else + se_block = 14 + dopage(src,"screen=strucmenu") + if (href_list["strucmenusubplus"]) + if (subblock < 3) + subblock++ + else + subblock = 1 + dopage(src,"screen=strucmenu") + if (href_list["strucmenusubminus"]) + if (subblock > 1) + subblock-- + else + subblock = 3 + dopage(src,"screen=strucmenu") + if (href_list["semenuset"] && href_list["semenusubset"]) // This chunk of code updates selected block / sub-block based on click (se stands for strutural enzymes) + var/menuset = text2num(href_list["semenuset"]) + var/menusubset = text2num(href_list["semenusubset"]) + if ((menuset <= 14) && (menuset >= 1)) + se_block = menuset + if ((menusubset <= 3) && (menusubset >= 1)) + subblock = menusubset + dopage(src, "strucmenu") + if (href_list["strucpulse"]) + var/block + var/newblock + var/tstructure2 + var/oldblock + var/lock_state = scanner.locked + scanner.locked = 1//lock it + if (viable_occupant) + block = getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),subblock,1) + + temp_html = text("Working ... Please wait ([] Seconds)", radduration) + popup.set_content(temp_html) + popup.open() + sleep(10*radduration) + else + temp_html = null + return null + /// + if(viable_occupant) + if (prob((80 + (radduration / 2)))) + if ((se_block != 2 || se_block != 12 || se_block != 8 || se_block || 10) && prob (20)) + oldblock = se_block + block = miniscramble(block, radstrength, radduration) + newblock = null + if (se_block > 1 && se_block < 5) + se_block++ + else if (se_block > 5 && se_block < 14) + se_block-- + if (subblock == 1) newblock = block + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),2,1) + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),3,1) + if (subblock == 2) newblock = getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),1,1) + block + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),3,1) + if (subblock == 3) newblock = getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),1,1) + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),2,1) + block + tstructure2 = setblock(scanner.occupant.dna.struc_enzymes, se_block, newblock,3) + scanner.occupant.dna.struc_enzymes = tstructure2 + domutcheck(scanner.occupant,scanner) + scanner.occupant.radiation += (radstrength+radduration) + se_block = oldblock + else + // + block = miniscramble(block, radstrength, radduration) + newblock = null + if (subblock == 1) newblock = block + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),2,1) + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),3,1) + if (subblock == 2) newblock = getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),1,1) + block + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),3,1) + if (subblock == 3) newblock = getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),1,1) + getblock(getblock(scanner.occupant.dna.struc_enzymes,se_block,3),2,1) + block + tstructure2 = setblock(scanner.occupant.dna.struc_enzymes, se_block, newblock,3) + scanner.occupant.dna.struc_enzymes = tstructure2 + domutcheck(scanner.occupant,scanner) + scanner.occupant.radiation += (radstrength+radduration) + else + if (prob(80-radduration)) + randmutb(scanner.occupant) + domutcheck(scanner.occupant,scanner) + else + randmuti(scanner.occupant) + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + scanner.occupant.radiation += ((radstrength*2)+radduration) + scanner.locked = lock_state + /// + dopage(src,"screen=strucmenu") + + //////////////////////////////////////////////////////// + if (href_list["b1addui"]) + if(scanner.occupant && scanner.occupant.dna) + buffer1iue = 0 + buffer1 = scanner.occupant.dna.uni_identity + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer1owner = scanner.occupant.name + else + buffer1owner = scanner.occupant.real_name + buffer1label = "Unique Identifier" + buffer1type = "ui" + dopage(src,"screen=buffermenu") + if (href_list["b1adduiue"]) + if(scanner.occupant && scanner.occupant.dna) + buffer1 = scanner.occupant.dna.uni_identity + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer1owner = scanner.occupant.name + else + buffer1owner = scanner.occupant.real_name + buffer1label = "Unique Identifier & Unique Enzymes" + buffer1type = "ui" + buffer1iue = 1 + dopage(src,"screen=buffermenu") + if (href_list["b2adduiue"]) + if(scanner.occupant && scanner.occupant.dna) + buffer2 = scanner.occupant.dna.uni_identity + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer2owner = scanner.occupant.name + else + buffer2owner = scanner.occupant.real_name + buffer2label = "Unique Identifier & Unique Enzymes" + buffer2type = "ui" + buffer2iue = 1 + dopage(src,"screen=buffermenu") + if (href_list["b3adduiue"]) + if(scanner.occupant && scanner.occupant.dna) + buffer3 = scanner.occupant.dna.uni_identity + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer3owner = scanner.occupant.name + else + buffer3owner = scanner.occupant.real_name + buffer3label = "Unique Identifier & Unique Enzymes" + buffer3type = "ui" + buffer3iue = 1 + dopage(src,"screen=buffermenu") + if (href_list["b2addui"]) + if(scanner.occupant && scanner.occupant.dna) + buffer2iue = 0 + buffer2 = scanner.occupant.dna.uni_identity + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer2owner = scanner.occupant.name + else + buffer2owner = scanner.occupant.real_name + buffer2label = "Unique Identifier" + buffer2type = "ui" + dopage(src,"screen=buffermenu") + if (href_list["b3addui"]) + if(scanner.occupant && scanner.occupant.dna) + buffer3iue = 0 + buffer3 = scanner.occupant.dna.uni_identity + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer3owner = scanner.occupant.name + else + buffer3owner = scanner.occupant.real_name + buffer3label = "Unique Identifier" + buffer3type = "ui" + dopage(src,"screen=buffermenu") + if (href_list["b1addse"]) + if(scanner.occupant && scanner.occupant.dna) + buffer1iue = 0 + buffer1 = scanner.occupant.dna.struc_enzymes + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer1owner = scanner.occupant.name + else + buffer1owner = scanner.occupant.real_name + buffer1label = "Structural Enzymes" + buffer1type = "se" + dopage(src,"screen=buffermenu") + if (href_list["b2addse"]) + if(scanner.occupant && scanner.occupant.dna) + buffer2iue = 0 + buffer2 = scanner.occupant.dna.struc_enzymes + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer2owner = scanner.occupant.name + else + buffer2owner = scanner.occupant.real_name + buffer2label = "Structural Enzymes" + buffer2type = "se" + dopage(src,"screen=buffermenu") + if (href_list["b3addse"]) + if(scanner.occupant && scanner.occupant.dna) + buffer3iue = 0 + buffer3 = scanner.occupant.dna.struc_enzymes + if (!istype(scanner.occupant,/mob/living/carbon/human)) + buffer3owner = scanner.occupant.name + else + buffer3owner = scanner.occupant.real_name + buffer3label = "Structural Enzymes" + buffer3type = "se" + dopage(src,"screen=buffermenu") + if (href_list["b1clear"]) + buffer1 = null + buffer1owner = null + buffer1label = null + buffer1iue = null + dopage(src,"screen=buffermenu") + if (href_list["b2clear"]) + buffer2 = null + buffer2owner = null + buffer2label = null + buffer2iue = null + dopage(src,"screen=buffermenu") + if (href_list["b3clear"]) + buffer3 = null + buffer3owner = null + buffer3label = null + buffer3iue = null + dopage(src,"screen=buffermenu") + if (href_list["b1label"]) + buffer1label = sanitize(input("New Label:","Edit Label","Infos here")) + dopage(src,"screen=buffermenu") + if (href_list["b2label"]) + buffer2label = sanitize(input("New Label:","Edit Label","Infos here")) + dopage(src,"screen=buffermenu") + if (href_list["b3label"]) + buffer3label = sanitize(input("New Label:","Edit Label","Infos here")) + dopage(src,"screen=buffermenu") + if (href_list["b1transfer"]) + if (!scanner.occupant || (NOCLONE in scanner.occupant.mutations) || !scanner.occupant.dna) + return + if (buffer1type == "ui") + if (buffer1iue) + scanner.occupant.real_name = buffer1owner + scanner.occupant.name = buffer1owner + scanner.occupant.dna.uni_identity = buffer1 + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + else if (buffer1type == "se") + scanner.occupant.dna.struc_enzymes = buffer1 + domutcheck(scanner.occupant,scanner) + temp_html = "Transfered." + scanner.occupant.radiation += rand(20,50) + + if (href_list["b2transfer"]) + if (!scanner.occupant || (NOCLONE in scanner.occupant.mutations) || !scanner.occupant.dna) + return + if (buffer2type == "ui") + if (buffer2iue) + scanner.occupant.real_name = buffer2owner + scanner.occupant.name = buffer2owner + scanner.occupant.dna.uni_identity = buffer2 + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + else if (buffer2type == "se") + scanner.occupant.dna.struc_enzymes = buffer2 + domutcheck(scanner.occupant,scanner) + temp_html = "Transfered." + scanner.occupant.radiation += rand(20,50) + + if (href_list["b3transfer"]) + if (!scanner.occupant || (NOCLONE in scanner.occupant.mutations) || !scanner.occupant.dna) + return + if (buffer3type == "ui") + if (buffer3iue) + scanner.occupant.real_name = buffer3owner + scanner.occupant.name = buffer3owner + scanner.occupant.dna.uni_identity = buffer3 + updateappearance(scanner.occupant,scanner.occupant.dna.uni_identity) + else if (buffer3type == "se") + scanner.occupant.dna.struc_enzymes = buffer3 + domutcheck(scanner.occupant,scanner) + temp_html = "Transfered." + scanner.occupant.radiation += rand(20,50) + + if (href_list["b1injector"]) + if (injectorready) + var/obj/item/tool/medical/dnainjector/I = new /obj/item/tool/medical/dnainjector + I.dna = buffer1 + I.dnatype = buffer1type + I.loc = loc + I.name += " ([buffer1label])" + if (buffer1iue) I.ue = buffer1owner //lazy haw haw + temp_html = "Injector created." + + injectorready = 0 + spawn(300) + injectorready = 1 + else + temp_html = "Replicator not ready yet." + + if (href_list["b2injector"]) + if (injectorready) + var/obj/item/tool/medical/dnainjector/I = new /obj/item/tool/medical/dnainjector + I.dna = buffer2 + I.dnatype = buffer2type + I.loc = loc + I.name += " ([buffer2label])" + if (buffer2iue) I.ue = buffer2owner //lazy haw haw + temp_html = "Injector created." + + injectorready = 0 + spawn(300) + injectorready = 1 + else + temp_html = "Replicator not ready yet." + + if (href_list["b3injector"]) + if (injectorready) + var/obj/item/tool/medical/dnainjector/I = new /obj/item/tool/medical/dnainjector + I.dna = buffer3 + I.dnatype = buffer3type + I.loc = loc + I.name += " ([buffer3label])" + if (buffer3iue) I.ue = buffer3owner //lazy haw haw + temp_html = "Injector created." + + injectorready = 0 + spawn(300) + injectorready = 1 + else + temp_html = "Replicator not ready yet." + + //////////////////////////////////////////////////////// + if (href_list["load_disk"]) + var/buffernum = text2num(href_list["load_disk"]) + if ((buffernum > 3) || (buffernum < 1)) + return + if ((isnull(diskette)) || (!diskette.data) || (diskette.data == "")) + return + switch(buffernum) + if(1) + buffer1 = diskette.data + buffer1type = diskette.data_type + buffer1iue = diskette.ue + buffer1owner = diskette.owner + if(2) + buffer2 = diskette.data + buffer2type = diskette.data_type + buffer2iue = diskette.ue + buffer2owner = diskette.owner + if(3) + buffer3 = diskette.data + buffer3type = diskette.data_type + buffer3iue = diskette.ue + buffer3owner = diskette.owner + temp_html = "Data loaded." + + if (href_list["save_disk"]) + var/buffernum = text2num(href_list["save_disk"]) + if ((buffernum > 3) || (buffernum < 1)) + return + if ((isnull(diskette)) || (diskette.read_only)) + return + switch(buffernum) + if(1) + diskette.data = buffer1 + diskette.data_type = buffer1type + diskette.ue = buffer1iue + diskette.owner = buffer1owner + diskette.name = "data disk - '[buffer1owner]'" + if(2) + diskette.data = buffer2 + diskette.data_type = buffer2type + diskette.ue = buffer2iue + diskette.owner = buffer2owner + diskette.name = "data disk - '[buffer2owner]'" + if(3) + diskette.data = buffer3 + diskette.data_type = buffer3type + diskette.ue = buffer3iue + diskette.owner = buffer3owner + diskette.name = "data disk - '[buffer3owner]'" + temp_html = "Data saved." + if (href_list["eject_disk"]) + if (!diskette) + return + diskette.loc = get_turf(src) + diskette = null + //////////////////////////////////////////////////////// + + temp_html = temp_header_html + switch(current_screen) + if ("mainmenu") + temp_html += "

Main Menu

" + if (viable_occupant) //is there REALLY someone in there who can be modified? + temp_html += text("Modify Unique Identifier
", src) + temp_html += text("Modify Structural Enzymes

", src) + else + temp_html += "Modify Unique Identifier
" + temp_html += "Modify Structural Enzymes

" + temp_html += text("Radiation Emitter Settings

", src) + temp_html += text("Transfer Buffer

", src) + + if ("unimenu") + if(!viable_occupant) + temp_html = text("No viable occupant detected.") + popup.set_content(temp_html) + popup.open() + else + temp_html = "<< Main Menu
" + temp_html += "

Modify Unique Identifier

" + temp_html += "
Unique Identifier:
[getblockstring(scanner.occupant.dna.uni_identity,ui_block,subblock,3, src,1)]

" + temp_html += "Selected Block: <- [ui_block] ->

" + temp_html += "Selected Sub-Block: <- [subblock] ->

" + temp_html += "Selected Target: <- [unitargethex] ->

" + temp_html += "Modify Block
" + temp_html += "Irradiate
" + + if ("strucmenu") + if(!viable_occupant) + temp_html = text("No viable occupant detected.") + popup.set_content(temp_html) + popup.open() + else + temp_html = "<< Main Menu
" + temp_html += "

Modify Structural Enzymes

" + temp_html += "
Structural Enzymes: [getblockstring(scanner.occupant.dna.struc_enzymes,se_block,subblock,3,src,0)]

" + temp_html += "Selected Block: <- [se_block] ->

" + temp_html += "Selected Sub-Block: <- [subblock] ->

" + temp_html += "Modify Block
" + temp_html += "Irradiate
" + + if ("radsetmenu") + temp_html = "<< Main Menu
" + temp_html += "

Radiation Emitter Settings

" + if (viable_occupant) + temp_html += text("Pulse Radiation", src) + else + temp_html += "Pulse Radiation" + temp_html += "

Radiation Duration: - [radduration] +
" + temp_html += "Radiation Intensity: - [radstrength] +

" + + if ("buffermenu") + temp_html = "<< Main Menu
" + temp_html += "

Transfer Buffer

" + temp_html += "

Buffer 1:

" + if (!(buffer1)) + temp_html += "Buffer Empty
" + else + temp_html += text("Data: []
", buffer1) + temp_html += text("By: []
", buffer1owner) + temp_html += text("Label: []
", buffer1label) + if (viable_occupant) temp_html += text("Save : UI - UI+UE - SE
", src, src, src) + if (buffer1) temp_html += text("Transfer to: Occupant - Injector
", src, src) + //if (buffer1) temp_html += text("Isolate Block
", src) + if (buffer1) temp_html += "Disk: Save To | Load From
" + if (buffer1) temp_html += text("Edit Label
", src) + if (buffer1) temp_html += text("Clear Buffer

", src) + if (!buffer1) temp_html += "
" + temp_html += "

Buffer 2:

" + if (!(buffer2)) + temp_html += "Buffer Empty
" + else + temp_html += text("Data: []
", buffer2) + temp_html += text("By: []
", buffer2owner) + temp_html += text("Label: []
", buffer2label) + if (viable_occupant) temp_html += text("Save : UI - UI+UE - SE
", src, src, src) + if (buffer2) temp_html += text("Transfer to: Occupant - Injector
", src, src) + //if (buffer2) temp_html += text("Isolate Block
", src) + if (buffer2) temp_html += "Disk: Save To | Load From
" + if (buffer2) temp_html += text("Edit Label
", src) + if (buffer2) temp_html += text("Clear Buffer

", src) + if (!buffer2) temp_html += "
" + temp_html += "

Buffer 3:

" + if (!(buffer3)) + temp_html += "Buffer Empty
" + else + temp_html += text("Data: []
", buffer3) + temp_html += text("By: []
", buffer3owner) + temp_html += text("Label: []
", buffer3label) + if (viable_occupant) temp_html += text("Save : UI - UI+UE - SE
", src, src, src) + if (buffer3) temp_html += text("Transfer to: Occupant - Injector
", src, src) + //if (buffer3) temp_html += text("Isolate Block
", src) + if (buffer3) temp_html += "Disk: Save To | Load From
" + if (buffer3) temp_html += text("Edit Label
", src) + if (buffer3) temp_html += text("Clear Buffer

", src) + if (!buffer3) temp_html += "
" + temp_html += temp_footer_html + + if(viable_occupant && !scanner_status_html && occupant) //is there REALLY someone in there? + scanner_status_html = "
Health:
[occupant.health]%
" + scanner_status_html += "
Radiation Level:
[occupant.radiation]%
" + if(human_occupant) + var/rejuvenators = round(human_occupant.reagents.get_reagent_amount("inaprovaline") / REJUVENATORS_MAX * 100) + scanner_status_html += "
Rejuvenators:
[human_occupant.reagents.get_reagent_amount("inaprovaline")] units
" + + if (current_screen == "mainmenu") + scanner_status_html += "
Unique Enzymes :
[uppertext(occupant.dna.unique_enzymes)]
" + scanner_status_html += "
Unique Identifier:
[occupant.dna.uni_identity]
" + scanner_status_html += "
Structural Enzymes:
[occupant.dna.struc_enzymes]
" + + var/dat = "

Scanner Status

" + + var/occupant_status = "Scanner Unoccupied" + if(occupant && occupant.dna) //is there REALLY someone in there? + if (!istype(occupant,/mob/living/carbon/human)) + sleep(1) + if(NOCLONE in occupant.mutations) + occupant_status = "Invalid DNA structure" + else + switch(occupant.stat) // obvious, see what their status is + if(0) + occupant_status = "Conscious" + if(1) + occupant_status = "Unconscious" + else + occupant_status = "DEAD" + + occupant_status = "[occupant.name] => [occupant_status]
" + + dat += "
[occupant_status][scanner_status_html]
" + + var/scanner_access_text = "Lock Scanner" + if (scanner.locked) + scanner_access_text = "Unlock Scanner" + + dat += "Scan " + + if (occupant && occupant.dna) + dat += "[scanner_access_text] " + if (human_occupant) + dat += "Inject Rejuvenators
" + else + dat += "Inject Rejuvenators
" + else + dat += "[scanner_access_text] " + dat += "Inject Rejuvenators
" + + if (!isnull(diskette)) + dat += text("Eject Disk
", src) + + dat += "
" + + if (temp_html) + dat += temp_html + + popup.set_content(dat) + popup.open() +*/ \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/security.dm b/code/WorkInProgress/computer3/computers/security.dm new file mode 100644 index 0000000000..8c6152e1c1 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/security.dm @@ -0,0 +1,606 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 +/obj/machinery/computer3/secure_data + default_prog = /datum/file/program/secure_data + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) + icon_state = "frame-sec" + +/obj/machinery/computer3/laptop/secure_data + default_prog = /datum/file/program/secure_data + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) + icon_state = "laptop" + + +/datum/file/program/secure_data//TODO:SANITY + name = "Security Records" + desc = "Used to view and edit personnel's security records" + active_state = "security" + image = 'icons/NTOS/records.png' + + req_one_access = list(access_security, access_forensics_lockers) + + var/obj/item/weapon/card/id/scan = null + var/authenticated = null + var/rank = null + var/screen = null + var/datum/data/record/active1 = null + var/datum/data/record/active2 = null + var/a_id = null + var/temp = null + var/printing = null + var/can_change_id = 0 + var/list/Perp + var/tempname = null + //Sorting Variables + var/sortBy = "name" + var/order = 1 // -1 = Descending - 1 = Ascending + + + + proc/authenticate() + if(access_security in scan.access || access_forensics_lockers in scan.access ) + return 1 + if(istype(usr,/mob/living/silicon/ai)) + return 1 + return 0 + + interact() + usr.set_machine(src) + scan = computer.cardslot.reader + if(!interactable()) + return + if (computer.z > 6) + usr << "\red Unable to establish a connection: \black You're too far away from the station!" + return + var/dat + + if (temp) + dat = text("[]

Clear Screen", temp, src) + else + dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------")) + if (authenticated) + switch(screen) + if(1.0) + dat += {" +

"} + dat += text("Search Records
", src) + dat += text("New Record
", src) + dat += {" +

+ + + + +
Records:
+ + + + + + + + "} + if(!isnull(data_core.general)) + for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order)) + var/crimstat = "" + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) + crimstat = E.fields["criminal"] + var/background + switch(crimstat) + if("*Arrest*") + background = "'background-color:#DC143C;'" + if("Incarcerated") + background = "'background-color:#CD853F;'" + if("Parolled") + background = "'background-color:#CD853F;'" + if("Released") + background = "'background-color:#3BB9FF;'" + if("None") + background = "'background-color:#00FF7F;'" + if("") + background = "'background-color:#00FF00;'" + crimstat = "No Record." + dat += text("", background, src, R, R.fields["name"]) + dat += text("", R.fields["id"]) + dat += text("", R.fields["rank"]) + dat += text("", R.fields["fingerprint"]) + dat += text("", crimstat) + dat += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" + dat += text("Record Maintenance

", src) + dat += text("{Log Out}",src) + if(2.0) + dat += "Records Maintenance
" + dat += "
Delete All Records

Back" + if(3.0) + dat += "
Security Record

" + if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) + var/icon/front = new(active1.fields["photo"], dir = SOUTH) + var/icon/side = new(active1.fields["photo"], dir = WEST) + usr << browse_rsc(front, "front.png") + usr << browse_rsc(side, "side.png") + dat += text(" \ +
\ + Name: [active1.fields["name"]]
\ + ID: [active1.fields["id"]]
\n \ + Sex: [active1.fields["sex"]]
\n \ + Age: [active1.fields["age"]]
\n \ + Rank: [active1.fields["rank"]]
\n \ + Fingerprint: [active1.fields["fingerprint"]]
\n \ + Physical Status: [active1.fields["p_stat"]]
\n \ + Mental Status: [active1.fields["m_stat"]]
Photo:
\ +
") + else + dat += "General Record Lost!
" + if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) + dat += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", src, active2.fields["criminal"], src, active2.fields["mi_crim"], src, active2.fields["mi_crim_d"], src, active2.fields["ma_crim"], src, active2.fields["ma_crim_d"], src, decode(active2.fields["notes"])) + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + dat += text("[]
Delete Entry

", active2.fields[text("com_[]", counter)], src, counter) + counter++ + dat += text("Add Entry

", src) + dat += text("Delete Record (Security Only)

", src) + else + dat += "Security Record Lost!
" + dat += text("New Security Record

", src) + dat += text("\nDelete Record (ALL)

\nPrint Record
\nBack
", src, src, src) + if(4.0) + if(!Perp.len) + dat += text("ERROR. String could not be located.

Back", src) + else + dat += {" + + "} + dat += text("", tempname) + dat += {" + +
Search Results for '[]':
+ + + + + + + + "} + for(var/i=1, i<=Perp.len, i += 2) + var/crimstat = "" + var/datum/data/record/R = Perp[i] + if(istype(Perp[i+1],/datum/data/record/)) + var/datum/data/record/E = Perp[i+1] + crimstat = E.fields["criminal"] + var/background + switch(crimstat) + if("*Arrest*") + background = "'background-color:#DC143C;'" + if("Incarcerated") + background = "'background-color:#CD853F;'" + if("Parolled") + background = "'background-color:#CD853F;'" + if("Released") + background = "'background-color:#3BB9FF;'" + if("None") + background = "'background-color:#00FF7F;'" + if("") + background = "'background-color:#FFFFFF;'" + crimstat = "No Record." + dat += text("", background, src, R, R.fields["name"]) + dat += text("", R.fields["id"]) + dat += text("", R.fields["rank"]) + dat += text("", R.fields["fingerprint"]) + dat += text("", crimstat) + dat += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" + dat += text("
Return to index.", src) + else + else + dat += text("{Log In}", src) + var/datum/browser/popup = new(usr, "secure_rec", "Security Records", 600, 400) + popup.set_content(dat) + popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) + popup.open() + return + +/*Revised /N +I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. +What a mess.*/ + Topic(href, href_list) + if(!interactable() || !computer.cardslot || ..(href,href_list)) + return + if (!( data_core.general.Find(active1) )) + active1 = null + if (!( data_core.security.Find(active2) )) + active2 = null + switch(href_list["choice"]) +// SORTING! + if("Sorting") + // Reverse the order if clicked twice + if(sortBy == href_list["sort"]) + if(order == 1) + order = -1 + else + order = 1 + else + // New sorting order! + sortBy = href_list["sort"] + order = initial(order) +//BASIC FUNCTIONS + if("Clear Screen") + temp = null + + if ("Return") + screen = 1 + active1 = null + active2 = null + + if("Confirm Identity") + if (scan) + if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand()) + computer.cardslot.remove(scan) + else + scan.loc = get_turf(src) + scan = null + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/card/id)) + computer.cardslot.insert(I) + scan = I + + if("Log Out") + authenticated = null + screen = null + active1 = null + active2 = null + + if("Log In") + if (istype(usr, /mob/living/silicon/ai)) + src.active1 = null + src.active2 = null + src.authenticated = usr.name + src.rank = "AI" + src.screen = 1 + else if (istype(usr, /mob/living/silicon/robot)) + src.active1 = null + src.active2 = null + src.authenticated = usr.name + var/mob/living/silicon/robot/R = usr + src.rank = "[R.modtype] [R.braintype]" + src.screen = 1 + else if (istype(scan, /obj/item/weapon/card/id)) + active1 = null + active2 = null + if(authenticate()) + authenticated = scan.registered_name + rank = scan.assignment + screen = 1 +//RECORD FUNCTIONS + if("Search Records") + var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text + world << "input [t1]" + if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !interactable())) + return + Perp = new/list() + t1 = lowertext(t1) + var/list/components = text2list(t1, " ") + if(components.len > 5) + return //Lets not let them search too greedily. + for(var/datum/data/record/R in data_core.general) + var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"] + for(var/i = 1, i<=components.len, i++) + if(findtext(temptext,components[i])) + var/prelist = new/list(2) + prelist[1] = R + Perp += prelist + for(var/i = 1, i<=Perp.len, i+=2) + for(var/datum/data/record/E in data_core.security) + var/datum/data/record/R = Perp[i] + if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) + Perp[i+1] = E + tempname = t1 + screen = 4 + + if("Record Maintenance") + screen = 2 + active1 = null + active2 = null + + if ("Browse Record") + var/datum/data/record/R = locate(href_list["d_rec"]) + var/S = locate(href_list["d_rec"]) + if (!( data_core.general.Find(R) )) + temp = "Record Not Found!" + else + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + S = E + active1 = R + active2 = S + screen = 3 + +/* if ("Search Fingerprints") + var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text + if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!interactable()) && (!istype(usr, /mob/living/silicon)))) + return + active1 = null + active2 = null + t1 = lowertext(t1) + for(var/datum/data/record/R in data_core.general) + if (lowertext(R.fields["fingerprint"]) == t1) + active1 = R + if (!( active1 )) + temp = text("Could not locate record [].", t1) + else + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"])) + active2 = E + screen = 3 */ + + if ("Print Record") + if (!( printing )) + printing = 1 + var/datum/data/record/record1 = null + var/datum/data/record/record2 = null + if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) + record1 = active1 + if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) + record2 = active2 + sleep(50) + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( computer.loc ) + P.info = "
Security Record

" + if (record1) + P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) + P.name = text("Security Record ([])", record1.fields["name"]) + else + P.info += "General Record Lost!
" + P.name = "Security Record" + if (record2) + P.info += text("
\n
Security Data

\nCriminal Status: []
\n
\nMinor Crimes: []
\nDetails: []
\n
\nMajor Crimes: []
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", record2.fields["criminal"], record2.fields["mi_crim"], record2.fields["mi_crim_d"], record2.fields["ma_crim"], record2.fields["ma_crim_d"], decode(record2.fields["notes"])) + var/counter = 1 + while(record2.fields[text("com_[]", counter)]) + P.info += text("[]
", record2.fields[text("com_[]", counter)]) + counter++ + else + P.info += "Security Record Lost!
" + P.info += "" + printing = null + computer.updateUsrDialog() +//RECORD DELETE + if ("Delete All Records") + temp = "" + temp += "Are you sure you wish to delete all Security records?
" + temp += "Yes
" + temp += "No" + + if ("Purge All Records") + for(var/datum/data/record/R in data_core.security) + del(R) + temp = "All Security records deleted." + + if ("Add Entry") + if (!( istype(active2, /datum/data/record) )) + return + var/a2 = active2 + var/t1 = copytext(sanitize(input("Add Comment:", "Secure. records", null, null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + return + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + counter++ + active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]
[t1]") + + if ("Delete Record (ALL)") + if (active1) + temp = "
Are you sure you wish to delete the record (ALL)?
" + temp += "Yes
" + temp += "No" + + if ("Delete Record (Security)") + if (active2) + temp = "
Are you sure you wish to delete the record (Security Portion Only)?
" + temp += "Yes
" + temp += "No" + + if ("Delete Entry") + if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) + active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" +//RECORD CREATE + if ("New Record (Security)") + if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) + var/datum/data/record/R = new /datum/data/record() + R.fields["name"] = active1.fields["name"] + R.fields["id"] = active1.fields["id"] + R.name = text("Security Record #[]", R.fields["id"]) + R.fields["criminal"] = "None" + R.fields["mi_crim"] = "None" + R.fields["mi_crim_d"] = "No minor crime convictions." + R.fields["ma_crim"] = "None" + R.fields["ma_crim_d"] = "No major crime convictions." + R.fields["notes"] = "No notes." + data_core.security += R + active2 = R + screen = 3 + + if ("New Record (General)") + var/datum/data/record/G = new /datum/data/record() + G.fields["name"] = "New Record" + G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) + G.fields["rank"] = "Unassigned" + G.fields["real_rank"] = "Unassigned" + G.fields["sex"] = "Male" + G.fields["age"] = "Unknown" + G.fields["fingerprint"] = "Unknown" + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + G.fields["species"] = "Human" + data_core.general += G + active1 = G + active2 = null + +//FIELD FUNCTIONS + if ("Edit Field") + var/a1 = active1 + var/a2 = active2 + switch(href_list["field"]) + if("name") + if (istype(active1, /datum/data/record)) + var/t1 = input("Please input name:", "Secure. records", active1.fields["name"], null) as text + if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon)))) || active1 != a1) + return + active1.fields["name"] = t1 + if("id") + if (istype(active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["id"] = t1 + if("fingerprint") + if (istype(active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["fingerprint"] = t1 + if("sex") + if (istype(active1, /datum/data/record)) + if (active1.fields["sex"] == "Male") + active1.fields["sex"] = "Female" + else + active1.fields["sex"] = "Male" + if("age") + if (istype(active1, /datum/data/record)) + var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["age"] = t1 + if("mi_crim") + if (istype(active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + return + active2.fields["mi_crim"] = t1 + if("mi_crim_d") + if (istype(active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + return + active2.fields["mi_crim_d"] = t1 + if("ma_crim") + if (istype(active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + return + active2.fields["ma_crim"] = t1 + if("ma_crim_d") + if (istype(active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + return + active2.fields["ma_crim_d"] = t1 + if("notes") + if (istype(active2, /datum/data/record)) + var/t1 = copytext(html_encode(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) + return + active2.fields["notes"] = t1 + if("criminal") + if (istype(active2, /datum/data/record)) + temp = "
Criminal Status:
" + temp += "" + if("rank") + var/list/L = list( "Head of Personnel", "Captain", "AI" ) + //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N + if ((istype(active1, /datum/data/record) && L.Find(rank))) + temp = "
Rank:
" + temp += "
    " + for(var/rank in joblist) + temp += "
  • [rank]
  • " + temp += "
" + else + alert(usr, "You do not have the required rank to do this!") + if("species") + if (istype(active1, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message),1,MAX_MESSAGE_LEN) + if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) + return + active1.fields["species"] = t1 + +//TEMPORARY MENU FUNCTIONS + else//To properly clear as per clear screen. + temp=null + switch(href_list["choice"]) + if ("Change Rank") + if (active1) + active1.fields["rank"] = href_list["rank"] + if(href_list["rank"] in joblist) + active1.fields["real_rank"] = href_list["real_rank"] + + if ("Change Criminal Status") + if (active2) + for(var/mob/living/carbon/human/H in player_list) + H.hud_updateflag |= 1 << WANTED_HUD + switch(href_list["criminal2"]) + if("none") + active2.fields["criminal"] = "None" + if("arrest") + active2.fields["criminal"] = "*Arrest*" + if("incarcerated") + active2.fields["criminal"] = "Incarcerated" + if("parolled") + active2.fields["criminal"] = "Parolled" + if("released") + active2.fields["criminal"] = "Released" + + if ("Delete Record (Security) Execute") + if (active2) + del(active2) + + if ("Delete Record (ALL) Execute") + if (active1) + for(var/datum/data/record/R in data_core.medical) + if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) + del(R) + else + del(active1) + if (active2) + del(active2) + else + temp = "This function does not appear to be working at the moment. Our apologies." + + //computer.updateUsrDialog() + interact() + return + +/obj/machinery/computer3/secure_data/emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + ..(severity) + return + + for(var/datum/data/record/R in data_core.security) + if(prob(10/severity)) + switch(rand(1,6)) + if(1) + R.fields["name"] = "[pick(pick(first_names_male), pick(first_names_female))] [pick(last_names)]" + if(2) + R.fields["sex"] = pick("Male", "Female") + if(3) + R.fields["age"] = rand(5, 85) + if(4) + R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Parolled", "Released") + if(5) + R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit") + if(6) + R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") + continue + + else if(prob(1)) + del(R) + continue + + ..(severity) + +/obj/machinery/computer3/secure_data/detective_computer + icon = 'icons/obj/computer.dmi' + icon_state = "messyfiles" diff --git a/code/WorkInProgress/computer3/computers/shuttle.dm b/code/WorkInProgress/computer3/computers/shuttle.dm new file mode 100644 index 0000000000..5d5fab6528 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/shuttle.dm @@ -0,0 +1,75 @@ +/* + This may not migrate to C3. It's basically a machine in the guise of a computer; + there is nothing interactive about it. +*/ + +/obj/machinery/computer3/shuttle + name = "Shuttle" + desc = "For shuttle control." + icon_state = "shuttle" + var/auth_need = 3.0 + var/list/authorized = list( ) + + + attackby(var/obj/item/card/W as obj, var/mob/user as mob) + if(stat & (BROKEN|NOPOWER)) return + if ((!( istype(W, /obj/item/card) ) || !( ticker ) || emergency_shuttle.location != 1 || !( user ))) return + if (istype(W, /obj/item/card/id)||istype(W, /obj/item/device/pda)) + if (istype(W, /obj/item/device/pda)) + var/obj/item/device/pda/pda = W + W = pda.id + if (!W:access) //no access + user << "The access level of [W:registered_name]\'s card is not high enough. " + return + + var/list/cardaccess = W:access + if(!istype(cardaccess, /list) || !cardaccess.len) //no access + user << "The access level of [W:registered_name]\'s card is not high enough. " + return + + if(!(access_heads in W:access)) //doesn't have this access + user << "The access level of [W:registered_name]\'s card is not high enough. " + return 0 + + var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort") + if(emergency_shuttle.location != 1 && user.get_active_hand() != W) + return 0 + switch(choice) + if("Authorize") + src.authorized -= W:registered_name + src.authorized += W:registered_name + if (src.auth_need - src.authorized.len > 0) + message_admins("[key_name_admin(user)] has authorized early shuttle launch") + log_game("[user.ckey] has authorized early shuttle launch") + world << text("\blue Alert: [] authorizations needed until shuttle is launched early", src.auth_need - src.authorized.len) + else + message_admins("[key_name_admin(user)] has launched the shuttle") + log_game("[user.ckey] has launched the shuttle early") + world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" + emergency_shuttle.online = 1 + emergency_shuttle.settimeleft(10) + //src.authorized = null + del(src.authorized) + src.authorized = list( ) + + if("Repeal") + src.authorized -= W:registered_name + world << text("\blue Alert: [] authorizations needed until shuttle is launched early", src.auth_need - src.authorized.len) + + if("Abort") + world << "\blue All authorizations to shorting time for shuttle launch have been revoked!" + src.authorized.len = 0 + src.authorized = list( ) + + else if (istype(W, /obj/item/card/emag) && !emagged) + var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") + + if(!emagged && emergency_shuttle.location == 1 && user.get_active_hand() == W) + switch(choice) + if("Launch") + world << "\blue Alert: Shuttle launch time shortened to 10 seconds!" + emergency_shuttle.settimeleft( 10 ) + emagged = 1 + if("Cancel") + return + return diff --git a/code/WorkInProgress/computer3/computers/specops_shuttle.dm b/code/WorkInProgress/computer3/computers/specops_shuttle.dm new file mode 100644 index 0000000000..81c94614cf --- /dev/null +++ b/code/WorkInProgress/computer3/computers/specops_shuttle.dm @@ -0,0 +1,246 @@ +//Config stuff +#define SPECOPS_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves. +#define SPECOPS_STATION_AREATYPE "/area/shuttle/specops/station" //Type of the spec ops shuttle area for station +#define SPECOPS_DOCK_AREATYPE "/area/shuttle/specops/centcom" //Type of the spec ops shuttle area for dock + +var/specops_shuttle_moving_to_station = 0 +var/specops_shuttle_moving_to_centcom = 0 +var/specops_shuttle_at_station = 0 +var/specops_shuttle_can_send = 1 +var/specops_shuttle_time = 0 +var/specops_shuttle_timeleft = 0 + +/obj/machinery/computer3/specops_shuttle + name = "Spec. Ops. Shuttle Console" + icon = 'icons/obj/computer.dmi' + icon_state = "shuttle" + req_access = list(access_cent_specops) + var/temp = null + var/hacked = 0 + var/allowedtocall = 0 + +/proc/specops_process() + var/area/centcom/control/cent_com = locate()//To find announcer. This area should exist for this proc to work. + var/area/centcom/specops/special_ops = locate()//Where is the specops area located? + var/mob/living/silicon/decoy/announcer = locate() in cent_com//We need a fake AI to announce some stuff below. Otherwise it will be wonky. + + var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values. + var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown. + if(announcer) + announcer.say(message) + message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD" + announcer.say(message) + + while(specops_shuttle_time - world.timeofday > 0) + var/ticksleft = specops_shuttle_time - world.timeofday + + if(ticksleft > 1e5) + specops_shuttle_time = world.timeofday + 10 // midnight rollover + specops_shuttle_timeleft = (ticksleft / 10) + + //All this does is announce the time before launch. + if(announcer) + var/rounded_time_left = round(specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions. + if(rounded_time_left in message_tracker)//If that time is in the list for message announce. + message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN" + if(rounded_time_left==0) + message = "ALERT: TAKEOFF" + announcer.say(message) + message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle. + //Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that. + + sleep(5) + + specops_shuttle_moving_to_station = 0 + specops_shuttle_moving_to_centcom = 0 + + specops_shuttle_at_station = 1 + if (specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return + + if (!specops_can_move()) + usr << "\red The Special Operations shuttle is unable to leave." + return + + //Begin Marauder launchpad. + spawn(0)//So it parallel processes it. + for(var/obj/machinery/door/poddoor/M in special_ops) + switch(M.id) + if("ASSAULT0") + spawn(10)//1 second delay between each. + M.open() + if("ASSAULT1") + spawn(20) + M.open() + if("ASSAULT2") + spawn(30) + M.open() + if("ASSAULT3") + spawn(40) + M.open() + + sleep(10) + + var/spawn_marauder[] = new() + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "Marauder Entry") + spawn_marauder.Add(L) + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "Marauder Exit") + var/obj/effect/portal/P = new(L.loc) + P.invisibility = 101//So it is not seen by anyone. + P.failchance = 0//So it has no fail chance when teleporting. + P.target = pick(spawn_marauder)//Where the marauder will arrive. + spawn_marauder.Remove(P.target) + + sleep(10) + + for(var/obj/machinery/mass_driver/M in special_ops) + switch(M.id) + if("ASSAULT0") + spawn(10) + M.drive() + if("ASSAULT1") + spawn(20) + M.drive() + if("ASSAULT2") + spawn(30) + M.drive() + if("ASSAULT3") + spawn(40) + M.drive() + + sleep(50)//Doors remain open for 5 seconds. + + for(var/obj/machinery/door/poddoor/M in special_ops) + switch(M.id)//Doors close at the same time. + if("ASSAULT0") + spawn(0) + M.close() + if("ASSAULT1") + spawn(0) + M.close() + if("ASSAULT2") + spawn(0) + M.close() + if("ASSAULT3") + spawn(0) + M.close() + special_ops.readyreset()//Reset firealarm after the team launched. + //End Marauder launchpad. + + var/area/start_location = locate(/area/shuttle/specops/centcom) + var/area/end_location = locate(/area/shuttle/specops/station) + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in end_location) + dstturfs += T + if(T.y < throwy) + throwy = T.y + + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + if(istype(T, /turf/simulated)) + del(T) + + start_location.move_contents_to(end_location) + + for(var/turf/T in get_area_turfs(end_location) ) + var/mob/M = locate(/mob) in T + M << "\red You have arrived to [station_name]. Commence operation!" + +/proc/specops_can_move() + if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return 0 + else return 1 + +/obj/machinery/computer3/specops_shuttle/attackby(I as obj, user as mob) + return attack_hand(user) + +/obj/machinery/computer3/specops_shuttle/attack_ai(var/mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/specops_shuttle/attack_paw(var/mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/specops_shuttle/attackby(I as obj, user as mob) + if(istype(I,/obj/item/card/emag)) + user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." + else + return attack_hand(user) + +/obj/machinery/computer3/specops_shuttle/attack_hand(var/mob/user as mob) + if(!allowed(user)) + user << "\red Access Denied." + return + + if (sent_strike_team == 0) + usr << "\red The strike team has not yet deployed." + return + + if(..()) + return + + user.set_machine(src) + var/dat + if (temp) + dat = temp + else + dat += {" + Location: [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "Departing for [station_name] in ([specops_shuttle_timeleft] seconds.)":specops_shuttle_at_station ? "Station":"Dock"]
+ [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*
\n
":specops_shuttle_at_station ? "\nShuttle Offline
\n
":"\nDepart to [station_name]
\n
"] + \nClose"} + + //user << browse(dat, "window=computer;size=575x450") + //onclose(user, "computer") + var/datum/browser/popup = new(user, "computer", "Special Operations Shuttle", 575, 450) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer3/specops_shuttle/Topic(href, href_list) + if(..()) + return + + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + + if (href_list["sendtodock"]) + if(!specops_shuttle_at_station|| specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return + + usr << "\blue Central Command will not allow the Special Operations shuttle to return." + return + + else if (href_list["sendtostation"]) + if(specops_shuttle_at_station || specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return + + if (!specops_can_move()) + usr << "\red The Special Operations shuttle is unable to leave." + return + + usr << "\blue The Special Operations shuttle will arrive on [station_name] in [(SPECOPS_MOVETIME/10)] seconds." + + temp += "Shuttle departing.

OK" + updateUsrDialog() + + var/area/centcom/specops/special_ops = locate() + if(special_ops) + special_ops.readyalert()//Trigger alarm for the spec ops area. + specops_shuttle_moving_to_station = 1 + + specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME + spawn(0) + specops_process() + + else if (href_list["mainmenu"]) + temp = null + + add_fingerprint(usr) + updateUsrDialog() + return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/station_alert.dm b/code/WorkInProgress/computer3/computers/station_alert.dm new file mode 100644 index 0000000000..2ee767a39a --- /dev/null +++ b/code/WorkInProgress/computer3/computers/station_alert.dm @@ -0,0 +1,114 @@ + +/obj/machinery/computer3/station_alert + name = "Station Alert Console" + desc = "Used to access the station's automated alert system." + icon_state = "alert:0" + circuit = "/obj/item/part/board/circuit/stationalert" + var/alarms = list("Fire"=list(), "Atmosphere"=list(), "Power"=list()) + + + attack_ai(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) + return + interact(user) + return + + + attack_hand(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) + return + interact(user) + return + + + interact(mob/user) + usr.set_machine(src) + var/dat = "" + for (var/cat in src.alarms) + dat += text("

[]

", cat) + var/list/L = src.alarms[cat] + if (L.len) + for (var/alarm in L) + var/list/alm = L[alarm] + var/area/A = alm[1] + var/list/sources = alm[3] + dat += "" + dat += "• " + dat += "[format_text(A.name)]" + if (sources.len > 1) + dat += text(" - [] sources", sources.len) + dat += "
\n" + else + dat += "-- All Systems Nominal
\n" + dat += "
\n" + //user << browse(dat, "window=alerts") + //onclose(user, "alerts") + var/datum/browser/popup = new(user, "alerts", "Current Station Alerts") + popup.add_head_content("") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + + + Topic(href, href_list) + if(..()) + return + return + + + proc/triggerAlarm(var/class, area/A, var/O, var/alarmsource) + if(stat & (BROKEN)) + return + var/list/L = src.alarms[class] + for (var/I in L) + if (I == A.name) + var/list/alarm = L[I] + var/list/sources = alarm[3] + if (!(alarmsource in sources)) + sources += alarmsource + return 1 + var/obj/machinery/camera/C = null + var/list/CL = null + if (O && istype(O, /list)) + CL = O + if (CL.len == 1) + C = CL[1] + else if (O && istype(O, /obj/machinery/camera)) + C = O + L[A.name] = list(A, (C) ? C : O, list(alarmsource)) + return 1 + + + proc/cancelAlarm(var/class, area/A as area, obj/origin) + if(stat & (BROKEN)) + return + var/list/L = src.alarms[class] + var/cleared = 0 + for (var/I in L) + if (I == A.name) + var/list/alarm = L[I] + var/list/srcs = alarm[3] + if (origin in srcs) + srcs -= origin + if (srcs.len == 0) + cleared = 1 + L -= I + return !cleared + + + process() + if(stat & (BROKEN|NOPOWER)) + icon_state = "atmos0" + return + var/active_alarms = 0 + for (var/cat in src.alarms) + var/list/L = src.alarms[cat] + if(L.len) active_alarms = 1 + if(active_alarms) + icon_state = "alert:2" + else + icon_state = "alert:0" + ..() + return diff --git a/code/WorkInProgress/computer3/computers/syndicate_shuttle.dm b/code/WorkInProgress/computer3/computers/syndicate_shuttle.dm new file mode 100644 index 0000000000..ccd711788b --- /dev/null +++ b/code/WorkInProgress/computer3/computers/syndicate_shuttle.dm @@ -0,0 +1,103 @@ +#define SYNDICATE_SHUTTLE_MOVE_TIME 240 +#define SYNDICATE_SHUTTLE_COOLDOWN 200 + +/obj/machinery/computer3/syndicate_station + name = "syndicate shuttle terminal" + icon = 'icons/obj/computer.dmi' + icon_state = "syndishuttle" + req_access = list(access_syndicate) + var/area/curr_location + var/moving = 0 + var/lastMove = 0 + + +/obj/machinery/computer3/syndicate_station/New() + curr_location= locate(/area/syndicate_station/start) + + +/obj/machinery/computer3/syndicate_station/proc/syndicate_move_to(area/destination as area) + if(moving) return + if(lastMove + SYNDICATE_SHUTTLE_COOLDOWN > world.time) return + var/area/dest_location = locate(destination) + if(curr_location == dest_location) return + + moving = 1 + lastMove = world.time + + if(curr_location.z != dest_location.z) + var/area/transit_location = locate(/area/syndicate_station/transit) + curr_location.move_contents_to(transit_location) + curr_location = transit_location + sleep(SYNDICATE_SHUTTLE_MOVE_TIME) + + curr_location.move_contents_to(dest_location) + curr_location = dest_location + moving = 0 + return 1 + + +/obj/machinery/computer3/syndicate_station/attackby(obj/item/I as obj, mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/syndicate_station/attack_ai(mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/syndicate_station/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/syndicate_station/attack_hand(mob/user as mob) + if(!allowed(user)) + user << "\red Access Denied" + return + + user.set_machine(src) + + var/dat = {"Location: [curr_location]
+ Ready to move[max(lastMove + SYNDICATE_SHUTTLE_COOLDOWN - world.time, 0) ? " in [max(round((lastMove + SYNDICATE_SHUTTLE_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]
+ Syndicate Space
+ North West of SS13 | + North of SS13 | + North East of SS13
+ South West of SS13 | + South of SS13 | + South East of SS13
+ North East of the Mining Asteroid
+ Close"} + + user << browse(dat, "window=computer;size=575x450") + onclose(user, "computer") + return + + +/obj/machinery/computer3/syndicate_station/Topic(href, href_list) + if(!isliving(usr)) return + var/mob/living/user = usr + + if(in_range(src, user) || istype(user, /mob/living/silicon)) + user.set_machine(src) + + if(href_list["syndicate"]) + syndicate_move_to(/area/syndicate_station/start) + else if(href_list["station_nw"]) + syndicate_move_to(/area/syndicate_station/northwest) + else if(href_list["station_n"]) + syndicate_move_to(/area/syndicate_station/north) + else if(href_list["station_ne"]) + syndicate_move_to(/area/syndicate_station/northeast) + else if(href_list["station_sw"]) + syndicate_move_to(/area/syndicate_station/southwest) + else if(href_list["station_s"]) + syndicate_move_to(/area/syndicate_station/south) + else if(href_list["station_se"]) + syndicate_move_to(/area/syndicate_station/southeast) +// else if(href_list["commssat"]) +// syndicate_move_to(/area/syndicate_station/commssat) + else if(href_list["mining"]) + syndicate_move_to(/area/syndicate_station/mining) + + add_fingerprint(usr) + updateUsrDialog() + return + +/obj/machinery/computer3/syndicate_station/bullet_act(var/obj/item/projectile/Proj) + visible_message("[Proj] ricochets off [src]!") //let's not let them fuck themselves in the rear \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/syndicate_specops_shuttle.dm b/code/WorkInProgress/computer3/computers/syndicate_specops_shuttle.dm new file mode 100644 index 0000000000..61dc0ba975 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/syndicate_specops_shuttle.dm @@ -0,0 +1,259 @@ +//Config stuff +#define SYNDICATE_ELITE_MOVETIME 600 //Time to station is deciseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves. +#define SYNDICATE_ELITE_STATION_AREATYPE "/area/shuttle/syndicate_elite/station" //Type of the spec ops shuttle area for station +#define SYNDICATE_ELITE_DOCK_AREATYPE "/area/shuttle/syndicate_elite/mothership" //Type of the spec ops shuttle area for dock + +var/syndicate_elite_shuttle_moving_to_station = 0 +var/syndicate_elite_shuttle_moving_to_mothership = 0 +var/syndicate_elite_shuttle_at_station = 0 +var/syndicate_elite_shuttle_can_send = 1 +var/syndicate_elite_shuttle_time = 0 +var/syndicate_elite_shuttle_timeleft = 0 + +/obj/machinery/computer3/syndicate_elite_shuttle + name = "Elite Syndicate Squad Shuttle Console" + icon = 'icons/obj/computer.dmi' + icon_state = "syndishuttle" + req_access = list(access_cent_specops) + var/temp = null + var/hacked = 0 + var/allowedtocall = 0 + +/proc/syndicate_elite_process() + var/area/syndicate_mothership/control/syndicate_ship = locate()//To find announcer. This area should exist for this proc to work. + var/area/syndicate_mothership/elite_squad/elite_squad = locate()//Where is the specops area located? + var/mob/living/silicon/decoy/announcer = locate() in syndicate_ship//We need a fake AI to announce some stuff below. Otherwise it will be wonky. + + var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values. + var/message = "THE SYNDICATE ELITE SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown. + if(announcer) + announcer.say(message) + // message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD" + // announcer.say(message) + + while(syndicate_elite_shuttle_time - world.timeofday > 0) + var/ticksleft = syndicate_elite_shuttle_time - world.timeofday + + if(ticksleft > 1e5) + syndicate_elite_shuttle_time = world.timeofday // midnight rollover + syndicate_elite_shuttle_timeleft = (ticksleft / 10) + + //All this does is announce the time before launch. + if(announcer) + var/rounded_time_left = round(syndicate_elite_shuttle_timeleft)//Round time so that it will report only once, not in fractions. + if(rounded_time_left in message_tracker)//If that time is in the list for message announce. + message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN" + if(rounded_time_left==0) + message = "ALERT: TAKEOFF" + announcer.say(message) + message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle. + //Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that. + + sleep(5) + + syndicate_elite_shuttle_moving_to_station = 0 + syndicate_elite_shuttle_moving_to_mothership = 0 + + syndicate_elite_shuttle_at_station = 1 + if (syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return + + if (!syndicate_elite_can_move()) + usr << "\red The Syndicate Elite shuttle is unable to leave." + return + + sleep(600) +/* + //Begin Marauder launchpad. + spawn(0)//So it parallel processes it. + for(var/obj/machinery/door/poddoor/M in elite_squad) + switch(M.id) + if("ASSAULT0") + spawn(10)//1 second delay between each. + M.open() + if("ASSAULT1") + spawn(20) + M.open() + if("ASSAULT2") + spawn(30) + M.open() + if("ASSAULT3") + spawn(40) + M.open() + + sleep(10) + + var/spawn_marauder[] = new() + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "Marauder Entry") + spawn_marauder.Add(L) + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "Marauder Exit") + var/obj/effect/portal/P = new(L.loc) + P.invisibility = 101//So it is not seen by anyone. + P.failchance = 0//So it has no fail chance when teleporting. + P.target = pick(spawn_marauder)//Where the marauder will arrive. + spawn_marauder.Remove(P.target) + + sleep(10) + + for(var/obj/machinery/mass_driver/M in elite_squad) + switch(M.id) + if("ASSAULT0") + spawn(10) + M.drive() + if("ASSAULT1") + spawn(20) + M.drive() + if("ASSAULT2") + spawn(30) + M.drive() + if("ASSAULT3") + spawn(40) + M.drive() + + sleep(50)//Doors remain open for 5 seconds. + + for(var/obj/machinery/door/poddoor/M in elite_squad) + switch(M.id)//Doors close at the same time. + if("ASSAULT0") + spawn(0) + M.close() + if("ASSAULT1") + spawn(0) + M.close() + if("ASSAULT2") + spawn(0) + M.close() + if("ASSAULT3") + spawn(0) + M.close() + */ + elite_squad.readyreset()//Reset firealarm after the team launched. + //End Marauder launchpad. +/* + var/obj/explosionmarker = locate("Syndicate Breach Area") + if(explosionmarker) + var/turf/simulated/T = explosionmarker.loc + if(T) + explosion(T,4,6,8,10,0) + + sleep(40) +// proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1) + +*/ + var/area/start_location = locate(/area/shuttle/syndicate_elite/mothership) + var/area/end_location = locate(/area/shuttle/syndicate_elite/station) + + var/list/dstturfs = list() + var/throwy = world.maxy + + for(var/turf/T in end_location) + dstturfs = T + if(T.y < throwy) + throwy = T.y + + // hey you, get out of the way! + for(var/turf/T in dstturfs) + // find the turf to move things to + var/turf/D = locate(T.x, throwy - 1, 1) + //var/turf/E = get_step(D, SOUTH) + for(var/atom/movable/AM as mob|obj in T) + AM.Move(D) + if(istype(T, /turf/simulated)) + del(T) + + start_location.move_contents_to(end_location) + + for(var/turf/T in get_area_turfs(end_location) ) + var/mob/M = locate(/mob) in T + M << "\red You have arrived to [station_name]. Commence operation!" + +/proc/syndicate_elite_can_move() + if(syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return 0 + else return 1 + +/obj/machinery/computer3/syndicate_elite_shuttle/attackby(I as obj, user as mob) + return attack_hand(user) + +/obj/machinery/computer3/syndicate_elite_shuttle/attack_ai(var/mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/syndicate_elite_shuttle/attack_paw(var/mob/user as mob) + return attack_hand(user) + +/obj/machinery/computer3/syndicate_elite_shuttle/attackby(I as obj, user as mob) + if(istype(I,/obj/item/card/emag)) + user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." + else + return attack_hand(user) + +/obj/machinery/computer3/syndicate_elite_shuttle/attack_hand(var/mob/user as mob) + if(!allowed(user)) + user << "\red Access Denied." + return + +// if (sent_syndicate_strike_team == 0) +// usr << "\red The strike team has not yet deployed." +// return + + if(..()) + return + + user.set_machine(src) + var/dat + if (temp) + dat = temp + else + dat = {"Location: [syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership ? "Departing for [station_name] in ([syndicate_elite_shuttle_timeleft] seconds.)":syndicate_elite_shuttle_at_station ? "Station":"Dock"]
+ [syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership ? "\n*The Syndicate Elite shuttle is already leaving.*
\n
":syndicate_elite_shuttle_at_station ? "\nShuttle Offline
\n
":"\nDepart to [station_name]
\n
"] + \nClose"} + + //user << browse(dat, "window=computer;size=575x450") + //onclose(user, "computer") + var/datum/browser/popup = new(user, "computer", "Special Operations Shuttle", 575, 450) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer3/syndicate_elite_shuttle/Topic(href, href_list) + if(..()) + return + + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + + if (href_list["sendtodock"]) + if(!syndicate_elite_shuttle_at_station|| syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return + + usr << "\blue The Syndicate will not allow the Elite Squad shuttle to return." + return + + else if (href_list["sendtostation"]) + if(syndicate_elite_shuttle_at_station || syndicate_elite_shuttle_moving_to_station || syndicate_elite_shuttle_moving_to_mothership) return + + if (!specops_can_move()) + usr << "\red The Syndicate Elite shuttle is unable to leave." + return + + usr << "\blue The Syndicate Elite shuttle will arrive on [station_name] in [(SYNDICATE_ELITE_MOVETIME/10)] seconds." + + temp = "Shuttle departing.

OK" + updateUsrDialog() + + var/area/syndicate_mothership/elite_squad/elite_squad = locate() + if(elite_squad) + elite_squad.readyalert()//Trigger alarm for the spec ops area. + syndicate_elite_shuttle_moving_to_station = 1 + + syndicate_elite_shuttle_time = world.timeofday + SYNDICATE_ELITE_MOVETIME + spawn(0) + syndicate_elite_process() + + + else if (href_list["mainmenu"]) + temp = null + + add_fingerprint(usr) + updateUsrDialog() + return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/file.dm b/code/WorkInProgress/computer3/file.dm new file mode 100644 index 0000000000..cd959a7ea0 --- /dev/null +++ b/code/WorkInProgress/computer3/file.dm @@ -0,0 +1,166 @@ +// I am deciding that for sayustation's purposes directories are right out, +// we can't even get backpacks to work right with recursion, and that +// actually fucking matters. Metadata too, that can be added if ever needed. + +/* + Files are datums that can be stored in digital storage devices +*/ + +/datum/file + var/name = "File" + var/extension = "dat" + var/volume = 10 // in KB + var/image = 'icons/NTOS/file.png' // determines the icon to use, found in icons/NTOS + var/obj/machinery/computer3/computer // the parent computer, if fixed + var/obj/item/part/computer/storage/device // the device that is containing this file + + var/drm = 0 // Copy protection, called by copy() and move() + var/readonly = 0 // Edit protection, called by edit(), which is just a failcheck proc + + proc/execute(var/datum/file/source) + return + + // + // Copy file to device. + // If you overwrite this function, use the return value to make sure it succeeded + // + proc/copy(var/obj/item/part/computer/storage/dest) + if(!computer || computer.crit_fail) return null + if(drm) + if(!computer.emagged) + return null + var/datum/file/F = new type() + if(!dest.addfile(F)) + return null // todo: arf here even though the player can't do a damn thing due to concurrency + return F + + // + // Move file to device + // Returns null on failure even though the existing file doesn't go away + // + proc/move(var/obj/item/part/computer/storage/dest) + if(!computer || computer.crit_fail) return null + if(drm) + if(!computer.emagged) + return null + var/obj/item/part/computer/storage/current = device + if(!dest.addfile(src)) + return null + current.removefile(src) + return src + + // + // Determines if the file is editable. This does not use the DRM flag, + // but instead the readonly flag. + // + + proc/edit() + if(!computer || computer.crit_fail) + return 0 + if(readonly && !computer.emagged) + return 0 // + return 1 + +/* + Centcom root authorization certificate + + Non-destructive, officially sanctioned. + Has the same effect on computers as an emag. +*/ +/datum/file/centcom_auth + name = "Centcom Root Access Token" + extension = "auth" + volume = 100 + copy() + return null + +/* + A file that contains information +*/ + +/datum/file/data + + var/content = "content goes here" + var/file_increment = 1 + var/binary = 0 // determines if the file can't be opened by editor + + // Set the content to a specific amount, increase filesize appropriately. + proc/set_content(var/text) + content = text + if(file_increment > 1) + volume = round(file_increment * length(text)) + + copy(var/obj/O) + var/datum/file/data/D = ..(O) + if(D) + D.content = content + D.readonly = readonly + + New() + if(content) + if(file_increment > 1) + volume = round(file_increment * length(content)) + +/* + A generic file that contains text +*/ + +/datum/file/data/text + name = "Text File" + extension = "txt" + image = 'icons/NTOS/file.png' + content = "" + file_increment = 0.002 // 0.002 kilobytes per character (1024 characters per KB) + +/datum/file/data/text/ClownProphecy + name = "Clown Prophecy" + content = "HONKhHONKeHONKlHONKpHONKHONmKHONKeHONKHONKpHONKlHONKeHONKaHONKsHONKe" + + +/* + A file that contains research +*/ + +/datum/file/data/research + name = "Untitled Research" + binary = 1 + content = "Untitled Tier X Research" + var/datum/tech/stored // the actual tech contents + volume = 1440 + +/* + A file that contains genetic information +*/ + +/datum/file/data/genome + name = "Genetic Buffer" + binary = 1 + var/real_name = "Poop" + + +/datum/file/data/genome/SE + name = "Structural Enzymes" + var/mutantrace = null + +/datum/file/data/genome/UE + name = "Unique Enzymes" + +/* +the way genome computers now work, a subtype is the wrong way to do this; +it will no longer be picked up. You can change this later if you need to. +for now put it on a disk + +/datum/file/data/genome/UE/GodEmperorOfMankind + name = "G.E.M.K." + content = "066000033000000000AF00330660FF4DB002690" + label = "God Emperor of Mankind" +*/ +/datum/file/data/genome/UI + name = "Unique Identifier" + +/datum/file/data/genome/UI/UE + name = "Unique Identifier + Unique Enzymes" + +/datum/file/data/genome/cloning + name = "Cloning Data" + var/datum/data/record/record diff --git a/code/WorkInProgress/computer3/laptop.dm b/code/WorkInProgress/computer3/laptop.dm new file mode 100644 index 0000000000..c681ff50a7 --- /dev/null +++ b/code/WorkInProgress/computer3/laptop.dm @@ -0,0 +1,137 @@ +/* + Computer3 portable computer. + + Battery powered only; it does not use the APC network at all. + + When picked up, becomes an inert item. This item can be put in a recharger, + or set down and re-opened into the original machine. While closed, the computer + has the MAINT stat flag. If you want to ignore this, you will have to bitmask it out. + + The unused(?) alt+click will toggle laptops open and closed. If we find a better + answer for this in the future, by all means use it. I just don't want it limited + to the verb, which is SIGNIFICANTLY less accessible than shutting a laptop. + Ctrl-click would work for closing the machine, since it's anchored, but not for + opening it back up again. And obviously, I don't want to override shift-click. + There's no double-click because that's used in regular click events. Alt-click is the + only obvious one left. +*/ + + +/obj/item/device/laptop + name = "Laptop Computer" + desc = "A clamshell portable computer. It is closed." + icon = 'icons/obj/computer3.dmi' + icon_state = "laptop-closed" + item_state = "laptop-inhand" + pixel_x = 2 + pixel_y = -3 + w_class = 4 + + var/obj/machinery/computer3/laptop/stored_computer = null + + verb/open_computer() + set name = "open laptop" + set category = "Object" + set src in view(1) + + 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) + del src + return + + + stored_computer.loc = loc + stored_computer.stat &= ~MAINT + stored_computer.update_icon() + loc = null + usr << "You open \the [src]." + + spawn(5) + del src + + AltClick() + open_computer() + +/obj/machinery/computer3/laptop + name = "Laptop Computer" + desc = "A clamshell portable computer. It is open." + + icon_state = "laptop" + density = 0 + pixel_x = 2 + pixel_y = -3 + show_keyboard = 0 + + var/obj/item/device/laptop/portable = null + + New(var/L, var/built = 0) + if(!built && !battery) + battery = new /obj/item/weapon/cell(src) + ..(L,built) + + verb/close_computer() + set name = "close laptop" + set category = "Object" + set src in view(1) + + if(istype(loc,/obj/item/device/laptop)) + testing("Close closed computer") + return + if(!istype(loc,/turf)) + testing("Odd computer location: [loc] - close laptop") + return + + if(stat&BROKEN) + usr << "\The [src] is broken! You can't quite get it closed." + return + + if(!portable) + portable=new + portable.stored_computer = src + + portable.loc = loc + loc = portable + stat |= MAINT + usr << "You close \the [src]." + + auto_use_power() + if(stat&MAINT) + return + if(use_power && istype(battery) && battery.charge > 0) + if(use_power == 1) + battery.use(idle_power_usage) + else + battery.use(active_power_usage) + return 1 + return 0 + + use_power(var/amount, var/chan = -1) + if(battery && battery.charge > 0) + battery.use(amount) + + power_change() + if( !battery || battery.charge <= 0 ) + stat |= NOPOWER + else + stat &= ~NOPOWER + + Del() + if(istype(loc,/obj/item/device/laptop)) + var/obj/O = loc + spawn(5) + if(O) + del O + ..() + + + AltClick() + close_computer() + diff --git a/code/WorkInProgress/computer3/networking.dm b/code/WorkInProgress/computer3/networking.dm new file mode 100644 index 0000000000..12341e2b6f --- /dev/null +++ b/code/WorkInProgress/computer3/networking.dm @@ -0,0 +1,236 @@ +/obj/item/part/computer/networking + name = "Computer networking component" + + /* + This is the public-facing proc used by NETUP. + It does additional checking before and after calling get_machines() + + */ + proc/connect_to(var/typekey,var/atom/previous) + if(!computer || computer.stat) + return null + + if(istype(previous,typekey) && verify_machine(previous)) + return previous + + var/result = get_machines(typekey) + + if(!result) + return null + + if(islist(result)) + var/list/R = result + if(R.len == 0) + return null + else if(R.len == 1) + return R[1] + else + var/list/atomlist = computer.format_atomlist(R) + result = input("Select:","Multiple destination machines located",atomlist[1]) as null|anything in atomlist + return atomlist[result] + + if(isobj(result)) + return result + + return null // ? + + /* + This one is used to determine the candidate machines. + It may return an object, a list of objects, or null. + + Overwite this on any networking component. + */ + proc/get_machines(var/typekey) + return list() + + /* + This is used to verify that an existing machine is within the network. + Calling NETUP() with an object argument will run this check, and if + the object is still accessible, it will be used. Otherwise, another + search will be run. + + Overwrite this on any networking component. + */ + proc/verify_machine(var/obj/previous) + return 0 + +/* + Provides radio/signaler functionality, and also + network-connects to anything on the same z-level + which is tuned to the same frequency. +*/ +/obj/item/part/computer/networking/radio + name = "Wireless networking component" + desc = "Radio module for computers" + + var/datum/radio_frequency/radio_connection = null + var/frequency = 1459 + var/filter = null + var/range = null + var/subspace = 0 + + init() + ..() + spawn(5) + radio_connection = radio_controller.add_object(src, src.frequency, src.filter) + + proc/set_frequency(new_frequency) + if(radio_controller) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, filter) + else + frequency = new_frequency + spawn(rand(5,10)) + set_frequency(new_frequency) + + receive_signal(var/datum/signal/signal) + if(!signal || !computer || (computer.stat&~MAINT)) // closed laptops use maint, allow it + return + if(computer.program) + computer.program.receive_signal(signal) + + proc/post_signal(var/datum/signal/signal) + if(!computer || (computer.stat&~MAINT) || !computer.program) return + if(!radio_connection) return + + radio_connection.post_signal(src,signal,filter,range) + + get_machines(var/typekey) + if(!radio_connection || !radio_connection.frequency) + return list() + var/list/result = list() + var/turf/T = get_turf(loc) + var/z_level = T.z + for(var/obj/O in radio_connection.devices) + if(istype(O,typekey)) + T = get_turf(O) + if(istype(O) && (subspace || (O.z == z_level))) // radio does not work across z-levels + result |= O + return result + + verify_machine(var/obj/previous) + if(!previous) return 0 + if(subspace) + return ( radio_connection && (previous in radio_connection.devices) ) + else + var/turf/T = get_turf(loc) + var/turf/O = get_turf(previous) + if(!T || !O) + return 0 + return ( radio_connection && (previous in radio_connection.devices) && (T.z == O.z)) + +/* + Subspace networking: Communicates off-station. Allows centcom communications. +*/ +/obj/item/part/computer/networking/radio/subspace + name = "subspace networking terminal" + desc = "Communicates long distances and through spatial anomalies." + subspace = 1 + +/* + APC (/area) networking +*/ + +/obj/item/part/computer/networking/area + name = "short-wave networking terminal" + desc = "Connects to nearby computers through the area power network" + + get_machines(var/typekey) + var/area/A = get_area(loc) + if(!istype(A) || A == /area) + return list() + if(typekey == null) + typekey = /obj/machinery + var/list/machines = list() + for(var/area/area in A.related) + for(var/obj/O in area.contents) + if(istype(O,typekey)) + machines |= O + return machines + verify_machine(var/obj/previous) + if(!previous) return 0 + var/area/A = get_area(src) + if( A && A == get_area(previous) ) + return 1 + return 0 + +/* + Proximity networking: Connects to machines or computers adjacent to this device +*/ +/obj/item/part/computer/networking/prox + name = "proximity networking terminal" + desc = "Connects a computer to adjacent machines" + + get_machines(var/typekey) + var/turf/T = get_turf(loc) + if(!istype(T)) + return list() + if(typekey == null) + typekey = /obj/machinery + var/list/machines = list() + for(var/d in cardinal) + var/turf/T2 = get_step(T,d) + for(var/obj/O in T2) + if(istype(O,typekey)) + machines += O + return machines + + verify_machine(var/obj/previous) + if(!previous) + return 0 + if(get_dist(get_turf(previous),get_turf(loc)) == 1) + return 1 + return 0 +/* + Cable networking: Not currently used +*/ + +/obj/item/part/computer/networking/cable + name = "cable networking terminal" + desc = "Connects to other machines on the same cable network." + + get_machines(var/typekey) +// if(istype(computer,/obj/machinery/computer/laptop)) // laptops move, this could get breaky +// return list() + var/turf/T = get_turf(loc) + var/datum/powernet/P = null + for(var/obj/structure/cable/C in T) + if(C.d1 == 0) + P = C.powernet + break + if(!P) + return list() + if(!typekey) + typekey = /obj/machinery + else if(typekey == /datum/powernet) + return list(P) + var/list/candidates = list() + for(var/atom/A in P.nodes) + if(istype(A,typekey)) + candidates += A + else if(istype(A,/obj/machinery/power/terminal)) + var/obj/machinery/power/terminal/PT = A + if(istype(PT.master,typekey)) + candidates += PT.master + return candidates + + verify_machine(var/obj/previous) + if(!previous) + return 0 + var/turf/T = get_turf(loc) + var/datum/powernet/P = null + for(var/obj/structure/cable/C in T) + if(C.d1 == 0) + P = C.powernet + break + if(istype(previous,/datum/powernet)) + if(previous == P) + return 1 + return 0 + T = get_turf(previous.loc) + for(var/obj/structure/cable/C in T) + if(C.d1 == 0 && (C.powernet == P)) + return 1 + return 0 + diff --git a/code/WorkInProgress/computer3/program.dm b/code/WorkInProgress/computer3/program.dm new file mode 100644 index 0000000000..42794f4c2e --- /dev/null +++ b/code/WorkInProgress/computer3/program.dm @@ -0,0 +1,404 @@ + +/* +Programs are a file that can be executed +*/ + +/datum/file/program + name = "Untitled" + extension = "prog" + image = 'icons/NTOS/program.png' + var/desc = "An unidentifiable program." + + var/image/overlay = null // Icon to be put on top of the computer frame. + + var/active_state = "generic" // the icon_state that the computer goes to when the program is active + + drm = 0 // prevents a program from being copied + var/refresh = 0 // if true, computer does screen updates during process(). + var/error = 0 // set by background programs so an error pops up when used + + var/human_controls = 0 // if true, non-human animals cannot interact with this program (monkeys, xenos, etc) + var/ai_allowed = 1 // if true, silicon mobs (AI/cyborg) are allowed to use this program. + + var/datum/browser/popup = null + + // ID access: Note that computer3 does not normally check your ID. + // By default this is only really used for inserted cards. + var/list/req_access = list() // requires all of these UNLESS below succeeds + var/list/req_one_access = list() // requires one of these + + +/datum/file/program/New() + ..() + if(!active_state) + active_state = "generic" + overlay = image('icons/obj/computer3.dmi',icon_state = active_state) + + +/datum/file/program/proc/decode(text) + //adds line breaks + text = replacetext(text, "\n","
") + return text + + + +/datum/file/program/execute(var/datum/file/source) + if(computer && !computer.stat) + computer.program = src + computer.req_access = req_access + computer.req_one_access = req_one_access + update_icon() + computer.update_icon() + if(usr) + usr << browse(null, "window=\ref[computer]") + computer.attack_hand(usr) + + ..() + +/* + Standard Topic() for links +*/ + +/datum/file/program/Topic(href, href_list) + return + +/* + The computer object will transfer all empty-hand calls to the program (this includes AIs, Cyborgs, and Monkies) +*/ +/datum/file/program/proc/interact() + return + +/* + Standard receive_signal() +*/ + +/datum/file/program/proc/receive_signal(var/datum/signal/signal) + return +/* + The computer object will transfer all attackby() calls to the program + If the item is a valid interactable object, return 1. Else, return 0. + This helps identify what to use to actually hit the computer with, and + what can be used to interact with it. + + Screwdrivers will, by default, never call program/attackby(). That's used + for deconstruction instead. +*/ + + +/datum/file/program/proc/attackby(O as obj, user as mob) + return + +/* + Try not to overwrite this proc, I'd prefer we stayed + with interact() as the main proc +*/ +/datum/file/program/proc/attack_hand(mob/user as mob) + usr = user + interact() + +/* + Called when the computer is rebooted or the program exits/restarts. + Be sure not to save any work. Do NOT start the program again. + If it is the os, the computer will run it again automatically. + + Also, we are deleting the browser window on the chance that this is happening + when the computer is damaged or disassembled, causing us to lose our computer. + The popup window's title is a reference to the computer, making it unique, so + it could introduce bugs in that case. +*/ +/datum/file/program/proc/Reset() + error = 0 + update_icon() + if(popup) + popup.close() + del popup + return + +/* + The computer object will transfer process() calls to the program. +*/ +/datum/file/program/proc/process() + if(refresh && computer && !computer.stat) + computer.updateDialog() + update_icon() + +/datum/file/program/proc/update_icon() + return + +/datum/file/program/proc/check_access(obj/item/I) + if( (!istype(req_access) || !req_access.len) && (!istype(req_one_access) || !req_one_access.len) ) //no requirements + return 1 + + if(!I) + return 0 + + var/list/iAccess = I.GetAccess() + if(!iAccess || !iAccess.len) + return 0 + + var/list/temp = req_one_access & iAccess + if(temp.len) // a required access in item access list + return 1 + temp = req_access - iAccess + if(temp.len) // a required access not in item access list + return 0 + return 1 + + +/* + Because this does sanity checks I have added the code to make a popup here. + It also does sanity checks there that should prevent some edge case madness. +*/ +/datum/file/program/proc/interactable(var/mob/user = usr) + if(computer && computer.interactable(user)) + if(!popup) + popup = new(user, "\ref[computer]", name, nref=src) + popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) + popup.set_title_buttons(topic_link(src,"quit","")) + if(popup.user != user) + popup.user = user + popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) + popup.set_title(name) + return 1 + return 0 + + +/datum/file/program/proc/fake_link(var/text) + return "[text]" + +/* + Meant for text (not icons) - + lists all installed drives and their files + + I am NOT adding a computer sanity check here, + because why the flying fuck would you get to this + proc before having run it at least once? + If you cause runtimes with this function + may the shame of all ages come upon you. +*/ +/datum/file/program/proc/list_all_files_by_drive(var/typekey,var/linkop = "runfile") + var/dat = "" + if(!typekey) typekey = /datum/file + if(computer.hdd) + dat += "

[computer.hdd]

" + for(var/datum/file/F in computer.hdd.files) + if(istype(F,typekey)) + dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "
" + if(computer.hdd.files.len == 0) + dat += "No files
" + dat += "
" + + if(computer.floppy) + if(!computer.floppy.inserted) + dat += "

[computer.floppy] - Eject



" + else + dat += "

[computer.floppy] - [topic_link(src,"eject_disk","Eject")]

" + for(var/datum/file/F in computer.floppy.inserted.files) + dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "
" + if(computer.floppy.inserted.files.len == 0) + dat += "No files
" + dat += "
" + + if(computer.cardslot && istype(computer.cardslot.reader,/obj/item/weapon/card/data)) + dat += "

[computer.cardslot.reader] - [topic_link(src,"eject_card=reader","Eject")]

" + var/obj/item/weapon/card/data/D = computer.cardslot.reader + for(var/datum/file/F in D.files) + dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "
" + if(D.files.len == 0) + dat += "No files
" + return dat + +// You don't NEED to use this version of topic() for this, you can do it yourself if you prefer +// If you do, do the interactable() check first, please, I don't want to repeat it here. It's not hard. +/datum/file/program/Topic(var/href,var/list/href_list) + if(!computer) + return 0 + + // + // usage: eject_disk + // only functions if there is a removable drive + // + if("eject_disk" in href_list) + if(computer.floppy) + computer.floppy.eject_disk() + return 1 + // + // usage: eject_card | eject_card=reader | eject_card=writer + // only functions if there is a cardslot + // + if("eject_card" in href_list) + if(computer.cardslot) + if(computer.cardslot.dualslot && href_list["eject_card"] == "writer") + computer.cardslot.remove(computer.cardslot.writer) + else + computer.cardslot.remove(computer.cardslot.reader) + return 1 + // + // usage: runfile=\ref[file] + // executes the file + // + if("runfile" in href_list) + var/datum/file/F = locate(href_list["runfile"]) + if(F && F.computer == computer) + F.execute(src) + return 1 + + if("close" in href_list) + usr.unset_machine() + popup.close() + return 1 + // + // usage: quit + // unloads the program, returning control to the OS + // + if("quit" in href_list) + computer.program = null + usr << browse(null,"window=\ref[computer]") // NTOS will need to resize the window + computer.update_icon() + computer.updateDialog() + return 1 + return 0 + + +/datum/file/program/RD + name = "R&D Manager" + image = 'icons/NTOS/research.png' + desc = "A software suit for generic research and development machinery interaction. Comes pre-packaged with extensive cryptographic databanks for secure connections with external devices." + active_state = "rdcomp" + volume = 11000 + +/datum/file/program/RDserv + name = "R&D Server" + image = 'icons/NTOS/server.png' + active_state = "rdcomp" + volume = 9000 + +/datum/file/program/SuitSensors + name = "Crew Monitoring" + image = 'icons/NTOS/monitoring.png' + active_state = "crew" + volume = 3400 + +/datum/file/program/Genetics + name = "Genetics Suite" + image = 'icons/NTOS/genetics.png' + desc = "A sophisticated software suite containing read-only genetics hardware specifications and a highly compressed genome databank." + active_state = "dna" + volume = 8000 + +/datum/file/program/Cloning + name = "Cloning Platform" + image = 'icons/NTOS/cloning.png' + desc = "A software platform for accessing external cloning apparatus." + active_state = "dna" + volume = 7000 + +/datum/file/program/TCOMmonitor + name = "TComm Monitor" + image = 'icons/NTOS/tcomms.png' + active_state = "comm_monitor" + volume = 5500 + +/datum/file/program/TCOMlogs + name = "TComm Log View" + image = 'icons/NTOS/tcomms.png' + active_state = "comm_logs" + volume = 5230 + +/datum/file/program/TCOMtraffic + name = "TComm Traffic" + image = 'icons/NTOS/tcomms.png' + active_state = "generic" + volume = 8080 + +/datum/file/program/securitycam + name = "Sec-Cam Viewport" + image = 'icons/NTOS/camera.png' + drm = 1 + active_state = "cameras" + volume = 2190 + +/datum/file/program/securityrecords + name = "Security Records" + image = 'icons/NTOS/records.png' + drm = 1 + active_state = "security" + volume = 2520 + +/datum/file/program/medicalrecords + name = "Medical Records" + image = 'icons/NTOS/medical.png' + drm = 1 + active_state = "medcomp" + volume = 5000 + +/datum/file/program/SMSmonitor + name = "Messaging Monitor" + image = 'icons/NTOS/pda.png' + active_state = "comm_monitor" + volume = 3070 + +/datum/file/program/OperationMonitor + name = "OR Monitor" + image = 'icons/NTOS/operating.png' + active_state = "operating" + volume = 4750 + +/datum/file/program/PodLaunch + name = "Pod Launch" + active_state = "computer_generic" + volume = 520 + +/datum/file/program/PowerMonitor + name = "Power Grid" + image = 'icons/NTOS/power.png' + active_state = "power" + volume = 7200 + +/datum/file/program/PrisonerManagement + name = "Prisoner Control" + image = 'icons/NTOS/prison.png' + drm = 1 + active_state = "power" + volume = 5000 + +/datum/file/program/Roboticscontrol + name = "Cyborg Maint" + image = 'icons/NTOS/borgcontrol.png' + active_state = "robot" + volume = 9050 + +/datum/file/program/AIupload + name = "AI Upload" + image = 'icons/NTOS/aiupload.png' + active_state = "command" + volume = 5000 + +/datum/file/program/Cyborgupload + name = "Cyborg Upload" + image = 'icons/NTOS/borgupload.png' + active_state = "command" + volume = 5000 + +/datum/file/program/Exosuit + name = "Exosuit Monitor" + image = 'icons/NTOS/exocontrol.png' + active_state = "mecha" + volume = 7000 + +/datum/file/program/EmergencyShuttle + name = "Shuttle Console" + active_state = "shuttle" + volume = 10000 + +/datum/file/program/Stationalert + name = "Alert Monitor" + image = 'icons/NTOS/alerts.png' + active_state = "computer_generic" + volume = 10150 + + + + + + diff --git a/code/WorkInProgress/computer3/program_disks.dm b/code/WorkInProgress/computer3/program_disks.dm new file mode 100644 index 0000000000..201fff3939 --- /dev/null +++ b/code/WorkInProgress/computer3/program_disks.dm @@ -0,0 +1,44 @@ + + +/obj/item/weapon/disk/file/arcade + name = "Arcade game grab pack" + desc = "A program install disk." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/arcade,/datum/file/program/arcade,/datum/file/program/arcade,/datum/file/program/arcade) + +/*/obj/item/weapon/disk/file/aifixer + name = "AI System Integrity Restorer" + desc = "A program install disk." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/aifixer)*/ + +/obj/item/weapon/disk/file/atmos_alert + name = "Atmospheric Alert Notifier" + desc = "A program install disk." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/atmos_alert) + +/obj/item/weapon/disk/file/cameras + name = "Camera Viewer" + desc = "A program install disk." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/security) + +/obj/item/weapon/disk/file/card + name = "ID Card Modifier" + desc = "A program install disk." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/card_comp) +/* +/obj/item/weapon/disk/file/genetics + name = "Genetics & Cloning" + desc = "A program install disk." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/cloning,/datum/file/program/dnascanner) +*/ diff --git a/code/WorkInProgress/computer3/server.dm b/code/WorkInProgress/computer3/server.dm new file mode 100644 index 0000000000..9e32918fea --- /dev/null +++ b/code/WorkInProgress/computer3/server.dm @@ -0,0 +1,32 @@ +/* + Todo: + I can probably get away with a global list on servers that contains database sort of stuff + (replacing the datacore probably) + with the justification that they loadbalance and duplicate data across each other. As long as + one server-type computer exists, the station will still have access to datacore-type info. + + I can doubtless use this for station alerts as well, which is good, because I was sort of + wondering how the hell I was going to port that. + + Also todo: Server computers should maybe generate heat the way the R&D server does? + At least the rack computer probably should. +*/ + +/obj/machinery/computer3/server + name = "server" + icon = 'icons/obj/computer3.dmi' + icon_state = "serverframe" + show_keyboard = 0 + +/obj/machinery/computer3/server/rack + name = "server rack" + icon_state = "rackframe" + + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio/subspace) + + update_icon() + //overlays.Cut() + return + + attack_hand() // Racks have no screen, only AI can use them + return diff --git a/code/WorkInProgress/computer3/storage.dm b/code/WorkInProgress/computer3/storage.dm new file mode 100644 index 0000000000..acf9a76288 --- /dev/null +++ b/code/WorkInProgress/computer3/storage.dm @@ -0,0 +1,184 @@ +/* + Computer devices that can store programs, files, etc. +*/ + +/obj/item/part/computer/storage + name = "Storage Device" + desc = "A device used for storing and retrieving digital information." + + // storage capacity, kb + var/volume = 0 + var/max_volume = 64 // should be enough for anyone + + var/driveletter = null // drive letter according to the computer + + var/list/files = list() // a list of files in the memory (ALL files) + var/removeable = 0 // determinse if the storage device is a removable hard drive (ie floppy) + + + var/writeprotect = 0 // determines if the drive forbids writing. + // note that write-protect is hardware and does not respect emagging. + + var/list/spawnfiles = list()// For mappers, special drives, and data disks + + New() + ..() + if(islist(spawnfiles)) + if(removeable && spawnfiles.len) + var/obj/item/part/computer/storage/removable/R = src + R.inserted = new(src) + if(writeprotect) + R.inserted.writeprotect = 1 + for(var/typekey in spawnfiles) + addfile(new typekey(),1) + + // Add a file to the hard drive, returns 0 if failed + // forced is used when spawning files on a write-protect drive + proc/addfile(var/datum/file/F,var/forced = 0) + if(!F || crit_fail || (F in files)) + return 1 + if(writeprotect && !forced) + return 0 + if(volume + F.volume > max_volume) + if(!forced) + return 0 + max_volume = volume + F.volume + + files.Add(F) + volume += F.volume + F.computer = computer + F.device = src + return 1 + proc/removefile(var/datum/file/F,var/forced = 0) + if(!F || !(F in files)) + return 1 + if(writeprotect && !forced) + return 0 + + files -= F + volume -= F.volume + if(F.device == src) + F.device = null + F.computer = null + return 1 + + init(var/obj/machinery/computer/target) + computer = target + for(var/datum/file/F in files) + F.computer = computer + +/* + Standard hard drives for computers. Used in computer construction +*/ + +/obj/item/part/computer/storage/hdd + name = "Hard Drive" + max_volume = 25000 + icon_state = "hdd1" + + +/obj/item/part/computer/storage/hdd/big + name = "Big Hard Drive" + max_volume = 50000 + icon_state = "hdd2" + +/obj/item/part/computer/storage/hdd/gigantic + name = "Gigantic Hard Drive" + max_volume = 75000 + icon_state = "hdd3" + +/* + Removeable hard drives for portable storage +*/ + +/obj/item/part/computer/storage/removable + name = "Disk Drive" + max_volume = 3000 + removeable = 1 + + attackby_types = list(/obj/item/weapon/disk/file, /obj/item/weapon/pen) + var/obj/item/weapon/disk/file/inserted = null + + proc/eject_disk(var/forced = 0) + if(!forced) + return + files = list() + inserted.loc = computer.loc + if(usr) + if(!usr.get_active_hand()) + usr.put_in_active_hand(inserted) + else if(forced && !usr.get_inactive_hand()) + usr.put_in_inactive_hand(inserted) + for(var/datum/file/F in inserted.files) + F.computer = null + inserted = null + + + attackby(obj/O as obj, mob/user as mob) + if(inserted && istype(O,/obj/item/weapon/pen)) + usr << "You use [O] to carefully pry [inserted] out of [src]." + eject_disk(forced = 1) + return + + if(istype(O,/obj/item/weapon/disk/file)) + if(inserted) + usr << "There's already a disk in [src]!" + return + + usr << "You insert [O] into [src]." + usr.drop_item() + O.loc = src + inserted = O + writeprotect = inserted.writeprotect + + files = inserted.files + for(var/datum/file/F in inserted.files) + F.computer = computer + + return + + ..() + + addfile(var/datum/file/F) + if(!F || !inserted) + return 0 + + if(F in inserted.files) + return 1 + + if(inserted.volume + F.volume > inserted.max_volume) + return 0 + + inserted.files.Add(F) + F.computer = computer + F.device = inserted + return 1 + +/* + Removable hard drive presents... + removeable disk! +*/ + +/obj/item/weapon/disk/file + //parent_type = /obj/item/part/computer/storage // todon't: do this + name = "Data Disk" + desc = "A device that can be inserted and removed into computers easily as a form of portable data storage. This one stores 1 Megabyte" + var/list/files + var/list/spawn_files = list() + var/writeprotect = 0 + var/volume = 0 + var/max_volume = 1028 + + + New() + ..() + icon_state = "datadisk[rand(0,6)]" + src.pixel_x = rand(-5, 5) + src.pixel_y = rand(-5, 5) + files = list() + if(istype(spawn_files)) + for(var/typekey in spawn_files) + var/datum/file/F = new typekey() + F.device = src + files += F + volume += F.volume diff --git a/code/WorkInProgress/computer3/test_machines.dm b/code/WorkInProgress/computer3/test_machines.dm new file mode 100644 index 0000000000..998937e634 --- /dev/null +++ b/code/WorkInProgress/computer3/test_machines.dm @@ -0,0 +1,86 @@ + +/obj/machinery/computer3/testing + spawn_files = list(/datum/file/program/aifixer,/datum/file/program/arcade,/datum/file/program/atmos_alert, + /datum/file/program/security,/datum/file/program/card_comp, + /datum/file/program/borg_control,/datum/file/program/holodeck, /datum/file/program/communications, + /datum/file/program/crew,/datum/file/program/op_monitor, /datum/file/program/powermon, + + /datum/file/camnet_key,/datum/file/camnet_key/mining,/datum/file/camnet_key/entertainment,/datum/file/camnet_key/research, + /datum/file/camnet_key/bombrange,/datum/file/camnet_key/xeno,/datum/file/camnet_key/singulo,/datum/file/camnet_key/prison) + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/storage/removable,/obj/item/part/computer/ai_holder, + /obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras, + /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) + New(var/L,var/built=0) + if(!built && !battery) + battery = new /obj/item/weapon/cell(src) + ..(L,built) + +/obj/machinery/computer3/laptop/testing + spawn_files = list(/datum/file/program/aifixer,/datum/file/program/arcade,/datum/file/program/atmos_alert, + /datum/file/program/security,/datum/file/program/card_comp, + /datum/file/program/borg_control,/datum/file/program/holodeck, /datum/file/program/communications, + /datum/file/program/crew,/datum/file/program/op_monitor, /datum/file/program/powermon, + + /datum/file/camnet_key,/datum/file/camnet_key/mining,/datum/file/camnet_key/entertainment,/datum/file/camnet_key/research, + /datum/file/camnet_key/bombrange,/datum/file/camnet_key/xeno,/datum/file/camnet_key/singulo,/datum/file/camnet_key/prison) + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/storage/removable,/obj/item/part/computer/ai_holder, + /obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras, + /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) + New(var/L,var/built=0) + if(!built && !battery) + battery = new /obj/item/weapon/cell/super(src) + ..(L,built) + +/obj/machinery/computer3/wall_comp/testing + spawn_files = list(/datum/file/program/aifixer,/datum/file/program/arcade,/datum/file/program/atmos_alert, + /datum/file/program/security,/datum/file/program/card_comp, + /datum/file/program/borg_control,/datum/file/program/holodeck, /datum/file/program/communications, + /datum/file/program/crew,/datum/file/program/op_monitor, /datum/file/program/powermon, + + /datum/file/camnet_key,/datum/file/camnet_key/mining,/datum/file/camnet_key/entertainment,/datum/file/camnet_key/research, + /datum/file/camnet_key/bombrange,/datum/file/camnet_key/xeno,/datum/file/camnet_key/singulo,/datum/file/camnet_key/prison) + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/storage/removable,/obj/item/part/computer/ai_holder, + /obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras, + /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) + New(var/L,var/built=0) + if(!built && !battery) + battery = new /obj/item/weapon/cell(src) + ..(L,built) + +/obj/machinery/computer3/server/testing + spawn_files = list(/datum/file/program/aifixer,/datum/file/program/arcade,/datum/file/program/atmos_alert, + /datum/file/program/security,/datum/file/program/card_comp, + /datum/file/program/borg_control,/datum/file/program/holodeck, /datum/file/program/communications, + /datum/file/program/crew,/datum/file/program/op_monitor, /datum/file/program/powermon, + + /datum/file/camnet_key,/datum/file/camnet_key/mining,/datum/file/camnet_key/entertainment,/datum/file/camnet_key/research, + /datum/file/camnet_key/bombrange,/datum/file/camnet_key/xeno,/datum/file/camnet_key/singulo,/datum/file/camnet_key/prison) + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/storage/removable,/obj/item/part/computer/ai_holder, + /obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras, + /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) + New(var/L,var/built=0) + if(!built && !battery) + battery = new /obj/item/weapon/cell(src) + ..(L,built) + +/obj/machinery/computer3/server/rack/testing + spawn_files = list(/datum/file/program/aifixer,/datum/file/program/arcade,/datum/file/program/atmos_alert, + /datum/file/program/security,/datum/file/program/card_comp, + /datum/file/program/borg_control,/datum/file/program/holodeck, /datum/file/program/communications, + /datum/file/program/crew,/datum/file/program/op_monitor, /datum/file/program/powermon, + + /datum/file/camnet_key,/datum/file/camnet_key/mining,/datum/file/camnet_key/entertainment,/datum/file/camnet_key/research, + /datum/file/camnet_key/bombrange,/datum/file/camnet_key/xeno,/datum/file/camnet_key/singulo,/datum/file/camnet_key/prison) + spawn_parts = list(/obj/item/part/computer/storage/hdd/big,/obj/item/part/computer/storage/removable,/obj/item/part/computer/ai_holder, + /obj/item/part/computer/networking/radio/subspace,/obj/item/part/computer/networking/cameras, + /obj/item/part/computer/cardslot/dual,/obj/item/part/computer/networking/area) + New(var/L,var/built=0) + if(!built && !battery) + battery = new /obj/item/weapon/cell(src) + ..(L,built) + +/obj/item/weapon/storage/box/testing_disks + New() + ..() + for(var/typekey in typesof(/obj/item/weapon/disk/file) - /obj/item/weapon/disk/file) + new typekey(src) \ No newline at end of file diff --git a/code/WorkInProgress/computer3/upload/lawfile.dm b/code/WorkInProgress/computer3/upload/lawfile.dm new file mode 100644 index 0000000000..e3b21f537e --- /dev/null +++ b/code/WorkInProgress/computer3/upload/lawfile.dm @@ -0,0 +1,29 @@ +/* + Computer3 law changes: + + * Laws are a file type + * Connecting to the AI requires a network connection + * Connecting to a borg requires a radio or network. + +*/ + +/datum/file/ai_law + var/list/hacklaws = null + var/zerolaw = null + var/list/corelaws = null + var/list/auxlaws = null + + var/configurable = 0 + + // override this when you need to be able to alter the parameters of the lawset + proc/configure() + return + + execute(var/datum/file/program/source) + if(istype(usr,/mob/living/silicon)) + return + if(istype(source,/datum/file/program/NTOS)) + if(configurable) + configure() + return + if(istype(source,/datum/file/program/upload/ai)) \ No newline at end of file diff --git a/code/WorkInProgress/computer3/upload/programs.dm b/code/WorkInProgress/computer3/upload/programs.dm new file mode 100644 index 0000000000..bcf45159b6 --- /dev/null +++ b/code/WorkInProgress/computer3/upload/programs.dm @@ -0,0 +1,13 @@ +/* + Note that as with existing ai upload, this is not an interactive program. + That means that the work is done in execute() rather than interact() +*/ + +/datum/file/program/upload/ai + execute(var/datum/file/program/source) + if(!interactable() || istype(usr,/mob/living/silicon)) + return 0 + if(!computer.net) + usr << "An indecipherable set of code flicks across the screen. Nothing else happens." + return + var/list/results = computer.net.get_machines \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index c6c1c38a4f..8b65de1f37 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1386,3 +1386,8 @@ var/list/WALLITEMS = list( /proc/format_text(text) return replacetext(replacetext(text,"\proper ",""),"\improper ","") + +/proc/topic_link(var/datum/D, var/arglist, var/content) + if(istype(arglist,/list)) + arglist = list2params(arglist) + return "[content]" \ No newline at end of file diff --git a/code/datums/browser.dm b/code/datums/browser.dm index cee5acdd53..31124c6faf 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -13,6 +13,7 @@ var/body_elements var/head_content = "" var/content = "" + var/title_buttons = "" /datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) @@ -29,9 +30,15 @@ ref = nref add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs +/datum/browser/proc/set_title(ntitle) + title = format_text(ntitle) + /datum/browser/proc/add_head_content(nhead_content) head_content = nhead_content +/datum/browser/proc/set_title_buttons(ntitle_buttons) + title_buttons = ntitle_buttons + /datum/browser/proc/set_window_options(nwindow_options) window_options = nwindow_options diff --git a/code/setup.dm b/code/setup.dm index 86d1aaff87..4971241ea8 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -758,3 +758,12 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse #define COLOR_YELLOW "#FFFF00" #define COLOR_ORANGE "#FF9900" #define COLOR_WHITE "#FFFFFF" + + +//computer3 error codes, move lower in the file when it passes dev -Sayu + #define PROG_CRASH 1 // Generic crash + #define MISSING_PERIPHERAL 2 // Missing hardware + #define BUSTED_ASS_COMPUTER 4 // Self-perpetuating error. BAC will continue to crash forever. + #define MISSING_PROGRAM 8 // Some files try to automatically launch a program. This is that failing. + #define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried. + #define NETWORK_FAILURE 32 \ No newline at end of file diff --git a/icons/NTOS/airestore.png b/icons/NTOS/airestore.png new file mode 100644 index 0000000000000000000000000000000000000000..d8e5207bfbf25919fcb8f77221a3ef9f93964ec2 GIT binary patch literal 3096 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/cardcomp.png b/icons/NTOS/cardcomp.png new file mode 100644 index 0000000000000000000000000000000000000000..e7df0ab20711aa98becf6e4d68babb77d6fb5434 GIT binary patch literal 3174 zcmV-s44LzZP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0004zNkl~=wFufGh-?NxL`b>-kR5`gmd!tLIq4Tkx&**9>nJnQcs});@COB8&;sc~l19P!NgMzwjZs82EPQ!!J{MkR8Umo_ zn4I*B1i*ULX0O{(DVNH0(@-jn5k1HJ;<05}*x%dLaKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0003MNklde&4+MdNf-xm&z`T(7eB5#GBT^Dt zt^ti#Cotw5BvZw~yK81Va{5sGRSHNdb9(?d@}*R~Rs)J|pL=(-n%PS=x?Tv?gP!CmTr#6Nq=)v6-VMXP%sLHp}e$ z?G-$Lf-@@#I1&JCH|z=+6%2SNzXM;i;ywafL4KuTR?yNu0YsRkpkdZL`E%dKsdEG( s-=#TFJ4cRU*ni7Afli literal 0 HcmV?d00001 diff --git a/icons/NTOS/comms.png b/icons/NTOS/comms.png new file mode 100644 index 0000000000000000000000000000000000000000..e089889d93027a49946cea67bb6ccadee40fb0f5 GIT binary patch literal 3157 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/copyfile.png b/icons/NTOS/copyfile.png new file mode 100644 index 0000000000000000000000000000000000000000..50c10b375787fc407b5da24a4347bd74ab500008 GIT binary patch literal 3030 zcmV;{3n}!8P)|D^_ww@lRz|vCuzLs)$;-`! zo*{AqUjza0dRV*yaMRE;fKCVhpQKsoe1Yhg01=zBIT!& zC1$=TK@rP|Ibo3vKKm@PqnO#LJhq6%Ij6Hz*<$V$@wQAMN5qJ)hzm2hoGcOF60t^# zFqJFfH{#e-4l@G)6iI9sa9D{VHW4w29}?su;^hF~NC{tY+*d5%WDCTXa!E_i;d2ub z1#}&jF5T4HnnCyEWTkKf0>c0%E1Ah>(_PY1)0w;+02c53Su*0<(nUqKG_|(0G&D0Z z{i;y^b@OjZ+}lNZ8Th$p5Uu}MTtq^NHl z*T1?CO*}7&0ztZsv2j*bmJyf3G7=Z`5B*PvzoDiKdLpOAxi2$L0#SX*@cY_n(^h55xYX z#km%V()bZjV~l{*bt*u9?FT3d5g^g~#a;iSZ@&02Abxq_DwB(I|L-^bXThc7C4-yr zInE_0gw7K3GZ**7&k~>k0Z0NWkO#^@9q0fwx1%qjZ=)yBuQ3=5 z4Wo^*!gyjLF-e%Um=erBOdIALW)L%unZshS@>qSW9o8Sq#0s#5*edK%>{;v(b^`kb zN5rY%%y90wC>#%$kE_5P!JWYk;U;klcqzOl-UjcFXXA75rT9jCH~u<)0>40zCTJ7v z2qAyk54cquI@7b&LHdZ`+zlTss6bJ7%PQ)z$cROu4wBhpu-r)01)S~6}jY?%U? zgEALn#wiFzo#H}aQ8rT=DHkadR18&{>P1bW7E`~Y4p3)hWn`DhhRJ5j*2tcg9i<^O zEt(fCg;q*CP8+7ZTcWhYX$fb^_9d-LhL+6BEtPYWVlfK zTBusSTASKKb%HuWJzl+By+?gkLq)?+BTu761jmyXF)a;mc z^>(B7bo*HQ1NNg1st!zt28YLv>W*y3CdWx9U8f|cqfXDAO`Q48?auQqHZJR2&bcD4 z9Ip>EY~kKEPV6Wm+eXFV)D)_R=tM0@&p?(!V*Qu1PXHG9o^TY0bZ?)4%0 z1p8F`JoeS|<@=<@RE7GY07EYX@lwd>4oW|Yi!o+Su@M`;WuSK8LKk71XR(_ zRKHM1xJ5XYX`fk>`6eqY>qNG6HZQwBM=xi4&Sb88?zd}EYguc1@>KIS<&CX#T35dw zS|7K*XM_5Nf(;WJJvJWRMA($P>8E^?{IdL4o5MGE7bq2MEEwP7v8AO@qL5!WvekBL z-8R%V?zVyL=G&{be=K4bT`e{#t|)$A!YaA?jp;X)-+bB;zhj`(vULAW%ue3U;av{9 z4wp%n<(7@__S@Z2PA@Mif3+uO&y|X06?J#o zSi8M;ejj_^(0<4Lt#wLu#dYrva1Y$6_o(k^&}yhSh&h;f@JVA>W8b%oZ=0JGnu?n~ z9O4}sJsfnnx7n(>`H13?(iXTy*fM=I`sj`CT)*pTHEgYKqqP+u1IL8No_-(u{qS+0 z<2@%BCt82d{Gqm;(q7a7b>wu+b|!X?c13m#p7cK1({0<`{-e>4hfb-UsyQuty7Ua; zOu?B?XLHZaol8GAb3Wnxcu!2v{R_`T4=x`(GvqLI{-*2AOSimkUAw*F_TX^n z@STz9kDQ$NC=!KfXWC z8h`dn#xL(D3Z9UkR7|Q&Hcy#Notk!^zVUSB(}`#4&lYA1f0h2V_PNgUAAWQEt$#LR zcH#y9#i!p(Udq2b^lI6wp1FXzN3T;~FU%Lck$-deE#qz9yYP3D3t8{6?<+s(e(3(_ z^YOu_)K8!O1p}D#{JO;G(*OVf24YJ`L;(K){{a7>y{D4^000SaNLh0L01m_e01m_f zl`9S#00007bV*G`2i*f26e=I%JfaH#00ACJL_t(o!|j)`4uUWchVM+@ghUy50|pl3 z=;F>(nK-$)yEqaS2j9R!O?;N$3DRPFc!FWDw{WE#eEfe~3Im`iV@4B41c(3;U~&LM zM8wSEY6O6#{vq|INgmgW_kwwr6EmX^;@kQb;C6pfRiE3A)v{>YkL#ru;@f%#K+KHO z@!-AjdQ-Mhb$?2y|s+7FYI&|2XDtd@my?B?krabU)<;!S~W zk)5ZD87>$+2Uh#&6U9Yi{$J~}nOS&D+EC9fh?*~R#Kyy6+=J;n60sbD~ Y1!s)k9T)A@l>h($07*qoM6N<$f|W|D^_ww@lRz|vCuzLs)$;-`! zo*{AqUjza0dRV*yaMRE;fKCVhpQKsoe1Yhg01=zBIT!& zC1$=TK@rP|Ibo3vKKm@PqnO#LJhq6%Ij6Hz*<$V$@wQAMN5qJ)hzm2hoGcOF60t^# zFqJFfH{#e-4l@G)6iI9sa9D{VHW4w29}?su;^hF~NC{tY+*d5%WDCTXa!E_i;d2ub z1#}&jF5T4HnnCyEWTkKf0>c0%E1Ah>(_PY1)0w;+02c53Su*0<(nUqKG_|(0G&D0Z z{i;y^b@OjZ+}lNZ8Th$p5Uu}MTtq^NHl z*T1?CO*}7&0ztZsv2j*bmJyf3G7=Z`5B*PvzoDiKdLpOAxi2$L0#SX*@cY_n(^h55xYX z#km%V()bZjV~l{*bt*u9?FT3d5g^g~#a;iSZ@&02Abxq_DwB(I|L-^bXThc7C4-yr zInE_0gw7K3GZ**7&k~>k0Z0NWkO#^@9q0fwx1%qjZ=)yBuQ3=5 z4Wo^*!gyjLF-e%Um=erBOdIALW)L%unZshS@>qSW9o8Sq#0s#5*edK%>{;v(b^`kb zN5rY%%y90wC>#%$kE_5P!JWYk;U;klcqzOl-UjcFXXA75rT9jCH~u<)0>40zCTJ7v z2qAyk54cquI@7b&LHdZ`+zlTss6bJ7%PQ)z$cROu4wBhpu-r)01)S~6}jY?%U? zgEALn#wiFzo#H}aQ8rT=DHkadR18&{>P1bW7E`~Y4p3)hWn`DhhRJ5j*2tcg9i<^O zEt(fCg;q*CP8+7ZTcWhYX$fb^_9d-LhL+6BEtPYWVlfK zTBusSTASKKb%HuWJzl+By+?gkLq)?+BTu761jmyXF)a;mc z^>(B7bo*HQ1NNg1st!zt28YLv>W*y3CdWx9U8f|cqfXDAO`Q48?auQqHZJR2&bcD4 z9Ip>EY~kKEPV6Wm+eXFV)D)_R=tM0@&p?(!V*Qu1PXHG9o^TY0bZ?)4%0 z1p8F`JoeS|<@=<@RE7GY07EYX@lwd>4oW|Yi!o+Su@M`;WuSK8LKk71XR(_ zRKHM1xJ5XYX`fk>`6eqY>qNG6HZQwBM=xi4&Sb88?zd}EYguc1@>KIS<&CX#T35dw zS|7K*XM_5Nf(;WJJvJWRMA($P>8E^?{IdL4o5MGE7bq2MEEwP7v8AO@qL5!WvekBL z-8R%V?zVyL=G&{be=K4bT`e{#t|)$A!YaA?jp;X)-+bB;zhj`(vULAW%ue3U;av{9 z4wp%n<(7@__S@Z2PA@Mif3+uO&y|X06?J#o zSi8M;ejj_^(0<4Lt#wLu#dYrva1Y$6_o(k^&}yhSh&h;f@JVA>W8b%oZ=0JGnu?n~ z9O4}sJsfnnx7n(>`H13?(iXTy*fM=I`sj`CT)*pTHEgYKqqP+u1IL8No_-(u{qS+0 z<2@%BCt82d{Gqm;(q7a7b>wu+b|!X?c13m#p7cK1({0<`{-e>4hfb-UsyQuty7Ua; zOu?B?XLHZaol8GAb3Wnxcu!2v{R_`T4=x`(GvqLI{-*2AOSimkUAw*F_TX^n z@STz9kDQ$NC=!KfXWC z8h`dn#xL(D3Z9UkR7|Q&Hcy#Notk!^zVUSB(}`#4&lYA1f0h2V_PNgUAAWQEt$#LR zcH#y9#i!p(Udq2b^lI6wp1FXzN3T;~FU%Lck$-deE#qz9yYP3D3t8{6?<+s(e(3(_ z^YOu_)K8!O1p}D#{JO;G(*OVf24YJ`L;(K){{a7>y{D4^000SaNLh0L01m_e01m_f zl`9S#00007bV*G`2i*f26eh*@DjWLk{=oTi1ppLz1|nkJ$QX4(u~?s;Ch@l}AZ820u}~Ac2LM0X zH*$!oB}nx)BqBZ?52NG4z=I#{m6MdC8@6KCX%ctV!@$$}-~U=bc0##L*8L*0GXTCF1mH)DA$Q% zCm@HhB*-tA!Qt7BG$1FXDkP%BCAB!YD6^m>Ge3`kp<+&OSV2+g_b^4^2yh7rH$&*Ju z+FoaTTQ^JJKRT^vIsrY0vS@Ef$XIZ5QKzGmGZ8MHbq zmciKRAj63j|M^+!8++D-I&2U-cEdYea7XnCMh0d#r~4(Aho=DzVDNPHb6Mw<&;$TA CT3yEg literal 0 HcmV?d00001 diff --git a/icons/NTOS/exocontrol.png b/icons/NTOS/exocontrol.png new file mode 100644 index 0000000000000000000000000000000000000000..101f32e44db9031f6b1e7e875660eab5c524dff5 GIT binary patch literal 3355 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/file.png b/icons/NTOS/file.png new file mode 100644 index 0000000000000000000000000000000000000000..05556e01f807b5a6adc82e1b8fdb6f6113940a46 GIT binary patch literal 2984 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 Y0NR3N*e@5|c>n+a07*qoM6N<$f@!swDF6Tf literal 0 HcmV?d00001 diff --git a/icons/NTOS/monitoring.png b/icons/NTOS/monitoring.png new file mode 100644 index 0000000000000000000000000000000000000000..a94910e48a0f72672ba355067f436ecd3e73a1bb GIT binary patch literal 3011 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 FV1hPtm+}Ar literal 0 HcmV?d00001 diff --git a/icons/NTOS/movefile.png b/icons/NTOS/movefile.png new file mode 100644 index 0000000000000000000000000000000000000000..5b31c6c2a8811bc725b45f17cfc33db07aa357c2 GIT binary patch literal 2985 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/ntos.png b/icons/NTOS/ntos.png new file mode 100644 index 0000000000000000000000000000000000000000..8b9d735cc99d9f2053fd024bc4b7a04ca73ae97e GIT binary patch literal 67090 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/pda.png b/icons/NTOS/pda.png new file mode 100644 index 0000000000000000000000000000000000000000..c6b0bb00fb3d4b956b9a6b8992c6e01670706925 GIT binary patch literal 2953 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/power.png b/icons/NTOS/power.png new file mode 100644 index 0000000000000000000000000000000000000000..b2e4cc837f15e6262696d5c0272f359fb0aed75f GIT binary patch literal 3055 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/prison.png b/icons/NTOS/prison.png new file mode 100644 index 0000000000000000000000000000000000000000..a846fe00411518853313b1f3bef444b76d8bb57d GIT binary patch literal 3117 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 JPDHLkV1m49a6141 literal 0 HcmV?d00001 diff --git a/icons/NTOS/records.png b/icons/NTOS/records.png new file mode 100644 index 0000000000000000000000000000000000000000..eaaf68e50d1a5b40661ca43194a52bd1f18536c6 GIT binary patch literal 3069 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 LNkvXXu0mjfkIS_l literal 0 HcmV?d00001 diff --git a/icons/NTOS/research.png b/icons/NTOS/research.png new file mode 100644 index 0000000000000000000000000000000000000000..5ebd63aafccaa9616dee30a13ea4c65ebb3e440f GIT binary patch literal 3120 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 KMNUMnLSTX`{Kpgk literal 0 HcmV?d00001 diff --git a/icons/NTOS/server.png b/icons/NTOS/server.png new file mode 100644 index 0000000000000000000000000000000000000000..6d96b1141398bfed50fb6e890b5725c20d58ec2a GIT binary patch literal 3195 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 literal 0 HcmV?d00001 diff --git a/icons/NTOS/tb_close.png b/icons/NTOS/tb_close.png new file mode 100644 index 0000000000000000000000000000000000000000..b99a6d81542fd3d4def1b7093c8550bfa1c7502f GIT binary patch literal 453 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 XNA`leI!U!S00000NkvXXu0mjfq$U*( literal 0 HcmV?d00001 diff --git a/icons/obj/computer3.dmi b/icons/obj/computer3.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4942da6a6b50d0b0b744a9177053426b7433ab4e GIT binary patch literal 37470 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 L@v!uP<-7k2m?O^n literal 0 HcmV?d00001 From 4067dffb819befa67c437be42658328c486d6f4a Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sun, 22 Jun 2014 02:09:22 -0700 Subject: [PATCH 03/25] Can't forget to commit the DME. --- baystation12.dme | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index ba4fd0ac65..45911ead56 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -478,8 +478,6 @@ #include "code\game\objects\items\devices\uplinks.dm" #include "code\game\objects\items\devices\violin.dm" #include "code\game\objects\items\devices\whistle.dm" -#include "code\game\objects\items\devices\laptops\laptop.dm" -#include "code\game\objects\items\devices\laptops\medical.dm" #include "code\game\objects\items\devices\PDA\cart.dm" #include "code\game\objects\items\devices\PDA\chatroom.dm" #include "code\game\objects\items\devices\PDA\PDA.dm" @@ -1333,6 +1331,29 @@ #include "code\WorkInProgress\Chinsky\ashtray.dm" #include "code\WorkInProgress\Chinsky\guestpass.dm" #include "code\WorkInProgress\Cib\MedicalSideEffects.dm" +#include "code\WorkInProgress\computer3\bios.dm" +#include "code\WorkInProgress\computer3\buildandrepair.dm" +#include "code\WorkInProgress\computer3\component.dm" +#include "code\WorkInProgress\computer3\computer.dm" +#include "code\WorkInProgress\computer3\computer3_notes.dm" +#include "code\WorkInProgress\computer3\file.dm" +#include "code\WorkInProgress\computer3\laptop.dm" +#include "code\WorkInProgress\computer3\networking.dm" +#include "code\WorkInProgress\computer3\NTOS.dm" +#include "code\WorkInProgress\computer3\program.dm" +#include "code\WorkInProgress\computer3\program_disks.dm" +#include "code\WorkInProgress\computer3\server.dm" +#include "code\WorkInProgress\computer3\storage.dm" +#include "code\WorkInProgress\computer3\computers\arcade.dm" +#include "code\WorkInProgress\computer3\computers\atmos_alert.dm" +#include "code\WorkInProgress\computer3\computers\camera.dm" +#include "code\WorkInProgress\computer3\computers\card.dm" +#include "code\WorkInProgress\computer3\computers\communications.dm" +#include "code\WorkInProgress\computer3\computers\crew.dm" +#include "code\WorkInProgress\computer3\computers\HolodeckControl.dm" +#include "code\WorkInProgress\computer3\computers\law.dm" +#include "code\WorkInProgress\computer3\computers\medical.dm" +#include "code\WorkInProgress\computer3\computers\security.dm" #include "code\WorkInProgress\kilakk\fax.dm" #include "code\WorkInProgress\Mini\atmos_control.dm" #include "code\WorkInProgress\Ported\policetape.dm" From 7a5a3d47aeff6ee378e4487ebbd9883e72224d88 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sun, 22 Jun 2014 03:31:06 -0700 Subject: [PATCH 04/25] Fixed up security, medical, card, and crew. Made Computer 3 actually do what it's supposed to do. --- .../computer3/computers/card.dm | 3 ++- .../computer3/computers/crew.dm | 3 ++- .../computer3/computers/medical.dm | 10 ++++------ .../computer3/computers/security.dm | 3 ++- code/WorkInProgress/computer3/program.dm | 1 + code/datums/browser.dm | 7 +++---- html/browser/common.css | 20 +++++++++++++++++++ 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/code/WorkInProgress/computer3/computers/card.dm b/code/WorkInProgress/computer3/computers/card.dm index 00e51778a3..7b62612398 100644 --- a/code/WorkInProgress/computer3/computers/card.dm +++ b/code/WorkInProgress/computer3/computers/card.dm @@ -174,7 +174,8 @@ dat = show_manifest() - popup = new(usr, "ID Computer", name, 940, 520) + popup.width = 940 + popup.height = 520 popup.set_content(dat) popup.open() return diff --git a/code/WorkInProgress/computer3/computers/crew.dm b/code/WorkInProgress/computer3/computers/crew.dm index d9ecace0c3..22a8b3425f 100644 --- a/code/WorkInProgress/computer3/computers/crew.dm +++ b/code/WorkInProgress/computer3/computers/crew.dm @@ -67,5 +67,6 @@ Topic(href, list/href_list) if(!interactable() || !computer.cardslot || ..(href,href_list)) return - computer.updateUsrDialog() + if("update" in href_list) + interact() return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/medical.dm b/code/WorkInProgress/computer3/computers/medical.dm index 13302f75b0..e370182744 100644 --- a/code/WorkInProgress/computer3/computers/medical.dm +++ b/code/WorkInProgress/computer3/computers/medical.dm @@ -44,7 +44,8 @@ usr << "\red Unable to establish a connection: \black You're too far away from the station!" return var/dat - if (src.temp) + + if (temp) dat = text("[src.temp]

Clear Screen") else dat = text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) @@ -138,7 +139,8 @@ else else dat += text("{Log In}", src) - var/datum/browser/popup = new(usr, "med_comp", "Medical Records", 600, 400) + popup.width = 600 + popup.height = 400 popup.set_content(dat) popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) popup.open() @@ -147,15 +149,11 @@ Topic(href, href_list) if(!interactable() || !computer.cardslot || ..(href,href_list)) return - if (!( data_core.general.Find(src.active1) )) src.active1 = null - if (!( data_core.medical.Find(src.active2) )) src.active2 = null - usr.set_machine(src) - if (href_list["temp"]) src.temp = null diff --git a/code/WorkInProgress/computer3/computers/security.dm b/code/WorkInProgress/computer3/computers/security.dm index 8c6152e1c1..17903477fb 100644 --- a/code/WorkInProgress/computer3/computers/security.dm +++ b/code/WorkInProgress/computer3/computers/security.dm @@ -193,7 +193,8 @@ else else dat += text("{Log In}", src) - var/datum/browser/popup = new(usr, "secure_rec", "Security Records", 600, 400) + popup.width = 600 + popup.height = 400 popup.set_content(dat) popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) popup.open() diff --git a/code/WorkInProgress/computer3/program.dm b/code/WorkInProgress/computer3/program.dm index 42794f4c2e..e16afe4939 100644 --- a/code/WorkInProgress/computer3/program.dm +++ b/code/WorkInProgress/computer3/program.dm @@ -155,6 +155,7 @@ Programs are a file that can be executed popup = new(user, "\ref[computer]", name, nref=src) popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) popup.set_title_buttons(topic_link(src,"quit","")) + // popup.set_title_buttons("") if(popup.user != user) popup.user = user popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 31124c6faf..09281bf1f7 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -82,7 +82,7 @@
- [title ? "
[title]
" : ""] + [title ? "
[title]
[title_buttons]
" : ""]
"} @@ -144,7 +144,7 @@ // Otherwise, the user mob's machine var will be reset directly. // /proc/onclose(mob/user, windowid, var/atom/ref=null) - if(!user.client) return + if(!user || !user.client) return var/param = "null" if(ref) param = "\ref[ref]" @@ -166,11 +166,10 @@ //world << "windowclose: [atomref]" if(atomref!="null") // if passed a real atomref var/hsrc = locate(atomref) // find the reffed atom - var/href = "close=1" if(hsrc) //world << "[src] Topic [href] [hsrc]" usr = src.mob - src.Topic(href, params2list(href), hsrc) // this will direct to the atom's + src.Topic("close=1", list("close"="1"), hsrc) // this will direct to the atom's return // Topic() proc via client.Topic() // no atomref specified (or not found) diff --git a/html/browser/common.css b/html/browser/common.css index 9e8b8b0b43..1de45bd953 100644 --- a/html/browser/common.css +++ b/html/browser/common.css @@ -126,6 +126,7 @@ h4 width: 100%; height: 100%; + padding-top:32px; } .uiTitle @@ -138,6 +139,25 @@ h4 font-size: 16px; } +.uiTitleWrapper + { + position:fixed; + top:0px; + left:0px; + right:0px; + z-index: 10 + } + + .uiTitleButtons + { + position:fixed; + top:0px; + right:0px; + height:32px; + z-index:11; + } + + .uiTitle.icon { padding: 6px 8px 6px 42px; From 41362280f3a5ec9ca38f40f52271c7f7a2537579 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sun, 22 Jun 2014 03:46:36 -0700 Subject: [PATCH 05/25] lowercase ntos by request of mloc + updates to background. --- code/WorkInProgress/computer3/NTOS.dm | 22 ++++----- .../computer3/buildandrepair.dm | 2 +- .../computer3/computer3_notes.dm | 2 +- .../computer3/computers/aifixer.dm | 2 +- .../computer3/computers/camera.dm | 4 +- .../computer3/computers/card.dm | 2 +- .../computer3/computers/crew.dm | 24 ++++++---- .../computer3/computers/security.dm | 2 +- code/WorkInProgress/computer3/file.dm | 4 +- code/WorkInProgress/computer3/program.dm | 47 +++++++++---------- .../computer3/upload/lawfile.dm | 2 +- 11 files changed, 59 insertions(+), 54 deletions(-) diff --git a/code/WorkInProgress/computer3/NTOS.dm b/code/WorkInProgress/computer3/NTOS.dm index 54fad87ce0..ee68971083 100644 --- a/code/WorkInProgress/computer3/NTOS.dm +++ b/code/WorkInProgress/computer3/NTOS.dm @@ -2,10 +2,10 @@ The Big Bad NT Operating System */ -/datum/file/program/NTOS +/datum/file/program/ntos name = "Nanotrasen Operating System" extension = "prog" - active_state = "ntos" + active_state = "NTOS" var/obj/item/part/computer/storage/current // the drive being viewed, null for desktop/computer var/fileop = "runfile" @@ -13,12 +13,12 @@ Generate a basic list of files in the selected scope */ -/datum/file/program/NTOS/proc/list_files() +/datum/file/program/ntos/proc/list_files() if(!computer || !current) return null return current.files -/datum/file/program/NTOS/proc/filegrid(var/list/filelist) +/datum/file/program/ntos/proc/filegrid(var/list/filelist) var/dat = "" var/i = 0 for(var/datum/file/F in filelist) @@ -44,7 +44,7 @@ // I am separating this from filegrid so that I don't have to // make metadata peripheral files // -/datum/file/program/NTOS/proc/desktop(var/peripheralop = "viewperipheral") +/datum/file/program/ntos/proc/desktop(var/peripheralop = "viewperipheral") var/dat = "
" var/i = 0 var/list/peripherals = list(computer.hdd,computer.floppy,computer.cardslot) @@ -69,20 +69,20 @@ return dat -/datum/file/program/NTOS/proc/window(var/title,var/buttonbar,var/content) +/datum/file/program/ntos/proc/window(var/title,var/buttonbar,var/content) return {"
-
[title]
+
[title]
[buttonbar]
[content]
"} -/datum/file/program/NTOS/proc/buttonbar(var/type = 0) +/datum/file/program/ntos/proc/buttonbar(var/type = 0) switch(type) if(0) // FILE OPERATIONS return {""} -/datum/file/program/NTOS/interact() +/datum/file/program/ntos/interact() if(!interactable()) return var/dat = {" @@ -162,7 +162,7 @@ -
"} +
"} var/list/files = list_files() if(current) @@ -175,7 +175,7 @@ usr << browse(dat, "window=\ref[computer];size=670x510") onclose(usr, "\ref[computer]") -/datum/file/program/NTOS/Topic(href, list/href_list) +/datum/file/program/ntos/Topic(href, list/href_list) if(!interactable() || ..(href,href_list)) return diff --git a/code/WorkInProgress/computer3/buildandrepair.dm b/code/WorkInProgress/computer3/buildandrepair.dm index 2cb9139f2e..0b1f2d8fd0 100644 --- a/code/WorkInProgress/computer3/buildandrepair.dm +++ b/code/WorkInProgress/computer3/buildandrepair.dm @@ -17,7 +17,7 @@ var/list/records = null var/frame_desc = null - var/datum/file/program/OS = new/datum/file/program/NTOS + var/datum/file/program/OS = new/datum/file/program/ntos /obj/machinery/computer3/proc/disassemble(mob/user as mob) // todo return diff --git a/code/WorkInProgress/computer3/computer3_notes.dm b/code/WorkInProgress/computer3/computer3_notes.dm index f0d0bd5028..c27410e637 100644 --- a/code/WorkInProgress/computer3/computer3_notes.dm +++ b/code/WorkInProgress/computer3/computer3_notes.dm @@ -27,7 +27,7 @@ * Communications terminal printing - move it to a printer of some sort? Make a printer peripheral--but then which ones print the comms? * Remove the partially transparent border on program screens, as it clashes with some frames * Chop the corners on program screens now that screen sizes are standard - * NTOS: + * ntos: * Needs a text editor/viewer * Needs file copy and file move - I think I know how I'm gonna do it * Needs a peripheral view (eject disks and cards, network actions, ???) diff --git a/code/WorkInProgress/computer3/computers/aifixer.dm b/code/WorkInProgress/computer3/computers/aifixer.dm index 45790c50a7..a52e40a0d5 100644 --- a/code/WorkInProgress/computer3/computers/aifixer.dm +++ b/code/WorkInProgress/computer3/computers/aifixer.dm @@ -7,7 +7,7 @@ /datum/file/program/aifixer name = "AI system integrity restorer" desc = "Repairs and revives artificial intelligence cores." - image = 'icons/NTOS/airestore.png' + image = 'icons/ntos/airestore.png' active_state = "ai-fixer-empty" req_access = list(access_captain, access_robotics, access_heads) diff --git a/code/WorkInProgress/computer3/computers/camera.dm b/code/WorkInProgress/computer3/computers/camera.dm index 17e639166d..4da54340c1 100644 --- a/code/WorkInProgress/computer3/computers/camera.dm +++ b/code/WorkInProgress/computer3/computers/camera.dm @@ -65,7 +65,7 @@ prog.key = src prog.camera_list = null return - if(istype(source,/datum/file/program/NTOS)) + if(istype(source,/datum/file/program/ntos)) for(var/obj/item/part/computer/storage/S in list(computer.hdd,computer.floppy)) for(var/datum/file/F in S.files) if(istype(F,/datum/file/program/security)) @@ -175,7 +175,7 @@ /datum/file/program/security name = "camera monitor" desc = "Connets to the Nanotrasen Camera Network" - image = 'icons/NTOS/camera.png' + image = 'icons/ntos/camera.png' active_state = "camera-static" var/datum/file/camnet_key/key = null diff --git a/code/WorkInProgress/computer3/computers/card.dm b/code/WorkInProgress/computer3/computers/card.dm index 7b62612398..660e25a67c 100644 --- a/code/WorkInProgress/computer3/computers/card.dm +++ b/code/WorkInProgress/computer3/computers/card.dm @@ -13,7 +13,7 @@ /datum/file/program/card_comp name = "identification card console" desc = "Used to modify magnetic strip ID cards." - image = 'icons/NTOS/cardcomp.png' + image = 'icons/ntos/cardcomp.png' active_state = "id" var/obj/item/weapon/card/id/reader = null diff --git a/code/WorkInProgress/computer3/computers/crew.dm b/code/WorkInProgress/computer3/computers/crew.dm index 22a8b3425f..2d89b336f8 100644 --- a/code/WorkInProgress/computer3/computers/crew.dm +++ b/code/WorkInProgress/computer3/computers/crew.dm @@ -14,12 +14,12 @@ return scan() - var/t = "" + var/t = "Crew Monitoring
" t += "
Refresh " t += "Close
" - t += "
" + t += "

Name

Vitals

Position

" var/list/logs = list() - for(var/obj/item/clothing/under/C in tracked) + for(var/obj/item/clothing/under/C in src.tracked) var/log = "" var/turf/pos = get_turf(C) if((C) && (C.has_sensor) && (pos) && (pos.z == computer.z) && C.sensor_mode) @@ -32,7 +32,7 @@ var/dam3 = round(H.getFireLoss(),1) var/dam4 = round(H.getBruteLoss(),1) - var/life_status = "[H.stat > 1 ? "Deceased" : "Living"]" + var/life_status = "[H.stat > 1 ? "Deceased" : "Living"]" var/damage_report = "([dam1]/[dam2]/[dam3]/[dam4])" if(H.wear_id) @@ -42,17 +42,18 @@ switch(C.sensor_mode) if(1) - log += "" + log += "" if(2) - log += "" + log += "" if(3) var/area/player_area = get_area(H) - log += "" + log += "" logs += log logs = sortList(logs) for(var/log in logs) t += log t += "
NameVitalsPosition
[life_status]Not Available
[life_status]Not Available
[life_status] [damage_report]Not Available
[life_status] [damage_report]Not Available
[life_status] [damage_report][format_text(player_area.name)] ([pos.x], [pos.y])
[life_status] [damage_report][player_area.name] ([pos.x], [pos.y])
" + t += "
" popup.set_content(t) popup.open() @@ -67,6 +68,11 @@ Topic(href, list/href_list) if(!interactable() || !computer.cardslot || ..(href,href_list)) return - if("update" in href_list) + if( href_list["close"] ) + usr << browse(null, "window=crewcomp") + usr.unset_machine() + return + if(href_list["update"]) interact() - return \ No newline at end of file + //src.updateUsrDialog() + return \ No newline at end of file diff --git a/code/WorkInProgress/computer3/computers/security.dm b/code/WorkInProgress/computer3/computers/security.dm index 17903477fb..77161bb247 100644 --- a/code/WorkInProgress/computer3/computers/security.dm +++ b/code/WorkInProgress/computer3/computers/security.dm @@ -14,7 +14,7 @@ name = "Security Records" desc = "Used to view and edit personnel's security records" active_state = "security" - image = 'icons/NTOS/records.png' + image = 'icons/ntos/records.png' req_one_access = list(access_security, access_forensics_lockers) diff --git a/code/WorkInProgress/computer3/file.dm b/code/WorkInProgress/computer3/file.dm index cd959a7ea0..3693579067 100644 --- a/code/WorkInProgress/computer3/file.dm +++ b/code/WorkInProgress/computer3/file.dm @@ -10,7 +10,7 @@ var/name = "File" var/extension = "dat" var/volume = 10 // in KB - var/image = 'icons/NTOS/file.png' // determines the icon to use, found in icons/NTOS + var/image = 'icons/ntos/file.png' // determines the icon to use, found in icons/ntos var/obj/machinery/computer3/computer // the parent computer, if fixed var/obj/item/part/computer/storage/device // the device that is containing this file @@ -108,7 +108,7 @@ /datum/file/data/text name = "Text File" extension = "txt" - image = 'icons/NTOS/file.png' + image = 'icons/ntos/file.png' content = "" file_increment = 0.002 // 0.002 kilobytes per character (1024 characters per KB) diff --git a/code/WorkInProgress/computer3/program.dm b/code/WorkInProgress/computer3/program.dm index e16afe4939..985ed74d35 100644 --- a/code/WorkInProgress/computer3/program.dm +++ b/code/WorkInProgress/computer3/program.dm @@ -6,7 +6,7 @@ Programs are a file that can be executed /datum/file/program name = "Untitled" extension = "prog" - image = 'icons/NTOS/program.png' + image = 'icons/ntos/program.png' var/desc = "An unidentifiable program." var/image/overlay = null // Icon to be put on top of the computer frame. @@ -154,8 +154,7 @@ Programs are a file that can be executed if(!popup) popup = new(user, "\ref[computer]", name, nref=src) popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) - popup.set_title_buttons(topic_link(src,"quit","")) - // popup.set_title_buttons("") + popup.set_title_buttons(topic_link(src,"quit","")) if(popup.user != user) popup.user = user popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state)) @@ -254,7 +253,7 @@ Programs are a file that can be executed // if("quit" in href_list) computer.program = null - usr << browse(null,"window=\ref[computer]") // NTOS will need to resize the window + usr << browse(null,"window=\ref[computer]") // ntos will need to resize the window computer.update_icon() computer.updateDialog() return 1 @@ -263,85 +262,85 @@ Programs are a file that can be executed /datum/file/program/RD name = "R&D Manager" - image = 'icons/NTOS/research.png' + image = 'icons/ntos/research.png' desc = "A software suit for generic research and development machinery interaction. Comes pre-packaged with extensive cryptographic databanks for secure connections with external devices." active_state = "rdcomp" volume = 11000 /datum/file/program/RDserv name = "R&D Server" - image = 'icons/NTOS/server.png' + image = 'icons/ntos/server.png' active_state = "rdcomp" volume = 9000 /datum/file/program/SuitSensors name = "Crew Monitoring" - image = 'icons/NTOS/monitoring.png' + image = 'icons/ntos/monitoring.png' active_state = "crew" volume = 3400 /datum/file/program/Genetics name = "Genetics Suite" - image = 'icons/NTOS/genetics.png' + image = 'icons/nots/genetics.png' desc = "A sophisticated software suite containing read-only genetics hardware specifications and a highly compressed genome databank." active_state = "dna" volume = 8000 /datum/file/program/Cloning name = "Cloning Platform" - image = 'icons/NTOS/cloning.png' + image = 'icons/ntos/cloning.png' desc = "A software platform for accessing external cloning apparatus." active_state = "dna" volume = 7000 /datum/file/program/TCOMmonitor name = "TComm Monitor" - image = 'icons/NTOS/tcomms.png' + image = 'icons/ntos/tcomms.png' active_state = "comm_monitor" volume = 5500 /datum/file/program/TCOMlogs name = "TComm Log View" - image = 'icons/NTOS/tcomms.png' + image = 'icons/ntos/tcomms.png' active_state = "comm_logs" volume = 5230 /datum/file/program/TCOMtraffic name = "TComm Traffic" - image = 'icons/NTOS/tcomms.png' + image = 'icons/ntos/tcomms.png' active_state = "generic" volume = 8080 /datum/file/program/securitycam name = "Sec-Cam Viewport" - image = 'icons/NTOS/camera.png' + image = 'icons/ntos/camera.png' drm = 1 active_state = "cameras" volume = 2190 /datum/file/program/securityrecords name = "Security Records" - image = 'icons/NTOS/records.png' + image = 'icons/ntos/records.png' drm = 1 active_state = "security" volume = 2520 /datum/file/program/medicalrecords name = "Medical Records" - image = 'icons/NTOS/medical.png' + image = 'icons/ntos/medical.png' drm = 1 active_state = "medcomp" volume = 5000 /datum/file/program/SMSmonitor name = "Messaging Monitor" - image = 'icons/NTOS/pda.png' + image = 'icons/ntos/pda.png' active_state = "comm_monitor" volume = 3070 /datum/file/program/OperationMonitor name = "OR Monitor" - image = 'icons/NTOS/operating.png' + image = 'icons/ntos/operating.png' active_state = "operating" volume = 4750 @@ -352,38 +351,38 @@ Programs are a file that can be executed /datum/file/program/PowerMonitor name = "Power Grid" - image = 'icons/NTOS/power.png' + image = 'icons/ntos/power.png' active_state = "power" volume = 7200 /datum/file/program/PrisonerManagement name = "Prisoner Control" - image = 'icons/NTOS/prison.png' + image = 'icons/ntos/prison.png' drm = 1 active_state = "power" volume = 5000 /datum/file/program/Roboticscontrol name = "Cyborg Maint" - image = 'icons/NTOS/borgcontrol.png' + image = 'icons/ntos/borgcontrol.png' active_state = "robot" volume = 9050 /datum/file/program/AIupload name = "AI Upload" - image = 'icons/NTOS/aiupload.png' + image = 'icons/ntos/aiupload.png' active_state = "command" volume = 5000 /datum/file/program/Cyborgupload name = "Cyborg Upload" - image = 'icons/NTOS/borgupload.png' + image = 'icons/ntos/borgupload.png' active_state = "command" volume = 5000 /datum/file/program/Exosuit name = "Exosuit Monitor" - image = 'icons/NTOS/exocontrol.png' + image = 'icons/ntos/exocontrol.png' active_state = "mecha" volume = 7000 @@ -394,7 +393,7 @@ Programs are a file that can be executed /datum/file/program/Stationalert name = "Alert Monitor" - image = 'icons/NTOS/alerts.png' + image = 'icons/ntos/alerts.png' active_state = "computer_generic" volume = 10150 diff --git a/code/WorkInProgress/computer3/upload/lawfile.dm b/code/WorkInProgress/computer3/upload/lawfile.dm index e3b21f537e..7fcbac0066 100644 --- a/code/WorkInProgress/computer3/upload/lawfile.dm +++ b/code/WorkInProgress/computer3/upload/lawfile.dm @@ -22,7 +22,7 @@ execute(var/datum/file/program/source) if(istype(usr,/mob/living/silicon)) return - if(istype(source,/datum/file/program/NTOS)) + if(istype(source,/datum/file/program/ntos)) if(configurable) configure() return From aa27bdc64c6d78368f66dc480b2b6f698332e346 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sun, 22 Jun 2014 17:19:40 -0700 Subject: [PATCH 06/25] laptop vending part 1. and more cleanup. --- baystation12.dme | 7 + code/WorkInProgress/computer3/NTOS.dm | 2 +- code/WorkInProgress/computer3/computer.dm | 3 + .../computer3/computers/card.dm | 99 ++++++-- .../computer3/computers/medical.dm | 5 + .../computer3/computers/message.dm | 29 ++- .../WorkInProgress/computer3/computers/pod.dm | 218 ------------------ .../computer3/computers/power.dm | 5 +- .../computer3/computers/prisoner.dm | 85 +++---- .../computer3/computers/robot.dm | 6 +- .../computer3/computers/security.dm | 2 +- .../computer3/computers/station_alert.dm | 53 ++--- code/WorkInProgress/computer3/laptop.dm | 2 +- code/WorkInProgress/computer3/program.dm | 2 +- icons/obj/computer3.dmi | Bin 37470 -> 37465 bytes 15 files changed, 178 insertions(+), 340 deletions(-) delete mode 100644 code/WorkInProgress/computer3/computers/pod.dm diff --git a/baystation12.dme b/baystation12.dme index 45911ead56..ddbd5a3e5b 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1338,6 +1338,7 @@ #include "code\WorkInProgress\computer3\computer3_notes.dm" #include "code\WorkInProgress\computer3\file.dm" #include "code\WorkInProgress\computer3\laptop.dm" +#include "code\WorkInProgress\computer3\lapvend.dm" #include "code\WorkInProgress\computer3\networking.dm" #include "code\WorkInProgress\computer3\NTOS.dm" #include "code\WorkInProgress\computer3\program.dm" @@ -1350,10 +1351,16 @@ #include "code\WorkInProgress\computer3\computers\card.dm" #include "code\WorkInProgress\computer3\computers\communications.dm" #include "code\WorkInProgress\computer3\computers\crew.dm" +#include "code\WorkInProgress\computer3\computers\customs.dm" #include "code\WorkInProgress\computer3\computers\HolodeckControl.dm" #include "code\WorkInProgress\computer3\computers\law.dm" #include "code\WorkInProgress\computer3\computers\medical.dm" +#include "code\WorkInProgress\computer3\computers\Operating.dm" +#include "code\WorkInProgress\computer3\computers\power.dm" +#include "code\WorkInProgress\computer3\computers\prisoner.dm" +#include "code\WorkInProgress\computer3\computers\robot.dm" #include "code\WorkInProgress\computer3\computers\security.dm" +#include "code\WorkInProgress\computer3\computers\welcome.dm" #include "code\WorkInProgress\kilakk\fax.dm" #include "code\WorkInProgress\Mini\atmos_control.dm" #include "code\WorkInProgress\Ported\policetape.dm" diff --git a/code/WorkInProgress/computer3/NTOS.dm b/code/WorkInProgress/computer3/NTOS.dm index ee68971083..8b779d9077 100644 --- a/code/WorkInProgress/computer3/NTOS.dm +++ b/code/WorkInProgress/computer3/NTOS.dm @@ -5,7 +5,7 @@ /datum/file/program/ntos name = "Nanotrasen Operating System" extension = "prog" - active_state = "NTOS" + active_state = "ntos" var/obj/item/part/computer/storage/current // the drive being viewed, null for desktop/computer var/fileop = "runfile" diff --git a/code/WorkInProgress/computer3/computer.dm b/code/WorkInProgress/computer3/computer.dm index 48869571d1..95824e555e 100644 --- a/code/WorkInProgress/computer3/computer.dm +++ b/code/WorkInProgress/computer3/computer.dm @@ -127,6 +127,9 @@ update_icon() + proc/update_spawn_files() + for(var/typekey in spawn_files) + hdd.addfile(new typekey,1) proc/spawn_parts() for(var/typekey in spawn_parts) diff --git a/code/WorkInProgress/computer3/computers/card.dm b/code/WorkInProgress/computer3/computers/card.dm index 660e25a67c..6080b59643 100644 --- a/code/WorkInProgress/computer3/computers/card.dm +++ b/code/WorkInProgress/computer3/computers/card.dm @@ -31,28 +31,85 @@ // the list of jobs won't change after all... proc/scriptblock() var/global/dat = null - if(!dat) - var/jobs_all = "" - for(var/job in list_jobs()) - jobs_all += topic_link(src,"assign=[job]",replacetext(job," "," ")) + " "//make sure there isn't a line break in the middle of a job + var/counter = 0 + var jobs_all = "" + jobs_all += "" + + jobs_all += ""//Captain in special because he is head of heads ~Intercross21 + jobs_all += "" + jobs_all += "" + + counter = 0 + jobs_all += ""//Red + for(var/job in security_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Orange + for(var/job in engineering_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Green + for(var/job in medical_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Purple + for(var/job in science_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + + counter = 0 + jobs_all += ""//Grey + for(var/job in civilian_positions) + counter++ + if(counter >= 6) + jobs_all += "" + counter = 0 + jobs_all += "" + dat = {""} + function markRed(){ + var nameField = document.getElementById('namefield'); + nameField.style.backgroundColor = "#FFDDDD"; + } + function markGreen(){ + var nameField = document.getElementById('namefield'); + nameField.style.backgroundColor = "#DDFFDD"; + } + function markAccountGreen(){ + var nameField = document.getElementById('accountfield'); + nameField.style.backgroundColor = "#DDFFDD"; + } + function markAccountRed(){ + var nameField = document.getElementById('accountfield'); + nameField.style.backgroundColor = "#FFDDDD"; + } + function showAll(){ + var allJobsSlot = document.getElementById('alljobsslot'); + allJobsSlot.innerHTML = "hide
"+ "[jobs_all]"; + } + function hideAll(){ + var allJobsSlot = document.getElementById('alljobsslot'); + allJobsSlot.innerHTML = "[(writer.assignment) ? writer.assignment : "Unassgied"]"; + } + "} return dat // creates the list of access rights on the card diff --git a/code/WorkInProgress/computer3/computers/medical.dm b/code/WorkInProgress/computer3/computers/medical.dm index e370182744..8e6b7cb7fc 100644 --- a/code/WorkInProgress/computer3/computers/medical.dm +++ b/code/WorkInProgress/computer3/computers/medical.dm @@ -11,6 +11,11 @@ default_prog = /datum/file/program/med_data spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) + +/obj/machinery/computer3/laptop/medical + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/cardslot,/obj/item/part/computer/networking/radio) + spawn_files = list(/datum/file/program/arcade,/datum/file/program/crew,/datum/file/program/med_data) + /datum/file/program/med_data name = "Medical Records" desc = "This can be used to check medical records." diff --git a/code/WorkInProgress/computer3/computers/message.dm b/code/WorkInProgress/computer3/computers/message.dm index d03f4a4753..3bbb580f5e 100644 --- a/code/WorkInProgress/computer3/computers/message.dm +++ b/code/WorkInProgress/computer3/computers/message.dm @@ -2,6 +2,9 @@ default_prog = /datum/file/program/message_mon spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/prox) + +//BROKEN AS HELL, DON'T USE UNTIL FIXED + /datum/file/program/message_mon name = "Message Monitor Console" desc = "Used to Monitor the crew's messages, that are sent via PDA. Can also be used to view Request Console messages." @@ -35,6 +38,13 @@ var/custommessage = "This is a test, please ignore." + procinitialize() + if(!linkedServer) + if(message_servers && message_servers.len > 0) + linkedServer = message_servers[1] + return + + update_icon() if(emag || hacking) overlay.icon_state = hack_icon @@ -45,12 +55,12 @@ interact() if(!interactable()) return - //If the computer is being hacked or is emagged, display the reboot message. if(hacking || emag) message = rebootmsg - - var/dat = "
/
" + var/dat = "Message Monitor Console" + dat += "

Message Monitor Console


" + dat += "

" if(auth) dat += "

\[Authenticated\] /" @@ -61,12 +71,9 @@ if(hacking || emag) screen = 2 - else - if(!auth) - screen = 0 - if( !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN)) ) - message = noserver - screen = 0 + else if(!auth || !linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) + if(!linkedServer || (linkedServer.stat & (NOPOWER|BROKEN))) message = noserver + screen = 0 switch(screen) //Main menu @@ -202,9 +209,11 @@

"} dat += "
Command
SpecialCaptainCustom
Security
[replacetext(job, " ", " ")]
Engineering
[replacetext(job, " ", " ")]
Medical
[replacetext(job, " ", " ")]
Science
[replacetext(job, " ", " ")]
Civilian
[replacetext(job, " ", " ")][rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]
" - message = defaultmsg + popup.width = 700 + popup.height = 700 popup.set_content(dat) + popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) popup.open() return diff --git a/code/WorkInProgress/computer3/computers/pod.dm b/code/WorkInProgress/computer3/computers/pod.dm deleted file mode 100644 index 47f45b1c91..0000000000 --- a/code/WorkInProgress/computer3/computers/pod.dm +++ /dev/null @@ -1,218 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - -/obj/machinery/computer3/pod - name = "Pod Launch Control" - desc = "A controll for launching pods. Some people prefer firing Mechas." - icon_state = "computer_generic" - var/id = 1.0 - var/obj/machinery/mass_driver/connected = null - var/timing = 0.0 - var/time = 30.0 - var/title = "Mass Driver Controls" - - -/obj/machinery/computer3/pod/New() - ..() - spawn( 5 ) - for(var/obj/machinery/mass_driver/M in world) - if(M.id == id) - connected = M - else - return - return - - -/obj/machinery/computer3/pod/proc/alarm() - if(stat & (NOPOWER|BROKEN)) - return - - if(!( connected )) - viewers(null, null) << "Cannot locate mass driver connector. Cancelling firing sequence!" - return - - for(var/obj/machinery/door/poddoor/M in world) - if(M.id == id) - M.open() - return - sleep(20) - - for(var/obj/machinery/mass_driver/M in world) - if(M.id == id) - M.power = connected.power - M.drive() - - sleep(50) - for(var/obj/machinery/door/poddoor/M in world) - if(M.id == id) - M.close() - return - return - - -/obj/machinery/computer3/pod/attackby(I as obj, user as mob) - if(istype(I, /obj/item/tool/screwdriver)) - playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) - if(do_after(user, 20)) - if(stat & BROKEN) - user << "\blue The broken glass falls out." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) - new /obj/item/trash/shard( loc ) - - //generate appropriate circuitboard. Accounts for /pod/old computer types - var/obj/item/part/board/circuit/pod/M = null - if(istype(src, /obj/machinery/computer/pod/old)) - M = new /obj/item/part/board/circuit/olddoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/syndicate)) - M = new /obj/item/part/board/circuit/syndicatedoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/swf)) - M = new /obj/item/part/board/circuit/swfdoor( A ) - else //it's not an old computer. Generate standard pod circuitboard. - M = new /obj/item/part/board/circuit/pod( A ) - - for (var/obj/C in src) - C.loc = loc - M.id = id - A.circuit = M - A.state = 3 - A.icon_state = "3" - A.anchored = 1 - del(src) - else - user << "\blue You disconnect the monitor." - var/obj/structure/computerframe/A = new /obj/structure/computerframe( loc ) - - //generate appropriate circuitboard. Accounts for /pod/old computer types - var/obj/item/part/board/circuit/pod/M = null - if(istype(src, /obj/machinery/computer/pod/old)) - M = new /obj/item/part/board/circuit/olddoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/syndicate)) - M = new /obj/item/part/board/circuit/syndicatedoor( A ) - if(istype(src, /obj/machinery/computer/pod/old/swf)) - M = new /obj/item/part/board/circuit/swfdoor( A ) - else //it's not an old computer. Generate standard pod circuitboard. - M = new /obj/item/part/board/circuit/pod( A ) - - for (var/obj/C in src) - C.loc = loc - M.id = id - A.circuit = M - A.state = 4 - A.icon_state = "4" - A.anchored = 1 - del(src) - else - attack_hand(user) - return - - -/obj/machinery/computer3/pod/attack_ai(var/mob/user as mob) - return attack_hand(user) - - -/obj/machinery/computer3/pod/attack_paw(var/mob/user as mob) - return attack_hand(user) - - -/obj/machinery/computer3/pod/attack_hand(var/mob/user as mob) - if(..()) - return - - var/dat = "" - user.set_machine(src) - if(connected) - var/d2 - if(timing) //door controls do not need timers. - d2 = "Stop Time Launch" - else - d2 = "Initiate Time Launch" - var/second = time % 60 - var/minute = (time - second) / 60 - dat += "
\nTimer System: [d2]\nTime Left: [minute ? "[minute]:" : null][second] - - + +" - var/temp = "" - var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 ) - for(var/t in L) - if(t == connected.power) - temp += "[t] " - else - temp += "[t] " - dat += "
\nPower Level: [temp]
\nFiring Sequence
\nTest Fire Driver
\nToggle Outer Door
" - else - dat += "
\nToggle Outer Door
" - dat += "

Close" - add_fingerprint(usr) - //user << browse(dat, "window=computer;size=400x500") - //onclose(user, "computer") - var/datum/browser/popup = new(user, "computer", title, 400, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - - -/obj/machinery/computer3/pod/process() - if(!..()) - return - if(timing) - if(time > 0) - time = round(time) - 1 - else - alarm() - time = 0 - timing = 0 - updateDialog() - return - - -/obj/machinery/computer3/pod/Topic(href, href_list) - if(..()) - return - if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - if(href_list["power"]) - var/t = text2num(href_list["power"]) - t = min(max(0.25, t), 16) - if(connected) - connected.power = t - if(href_list["alarm"]) - alarm() - if(href_list["time"]) - timing = text2num(href_list["time"]) - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 120) - if(href_list["door"]) - for(var/obj/machinery/door/poddoor/M in world) - if(M.id == id) - if(M.density) - M.open() - else - M.close() - updateUsrDialog() - return - - - -/obj/machinery/computer3/pod/old - icon_state = "old" - name = "DoorMex Control Console" - title = "Door Controls" - - - -/obj/machinery/computer3/pod/old/syndicate - name = "ProComp Executive IIc" - desc = "The Syndicate operate on a tight budget. Operates external airlocks." - title = "External Airlock Controls" - req_access = list(access_syndicate) - -/obj/machinery/computer3/pod/old/syndicate/attack_hand(var/mob/user as mob) - if(!allowed(user)) - user << "\red Access Denied" - return - else - ..() - -/obj/machinery/computer3/pod/old/swf - name = "Magix System IV" - desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorceror's Edition" diff --git a/code/WorkInProgress/computer3/computers/power.dm b/code/WorkInProgress/computer3/computers/power.dm index 4bd838a207..6e27da0568 100644 --- a/code/WorkInProgress/computer3/computers/power.dm +++ b/code/WorkInProgress/computer3/computers/power.dm @@ -11,7 +11,8 @@ proc/format(var/obj/machinery/power/apc/A) var/static/list/S = list(" Off","AOff"," On", " AOn") var/static/list/chg = list("N","C","F") - return "[copytext(add_tspace("\The [A.area]", 30), 1, 30)] [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]
" + return "[copytext(add_tspace("\The [A.area]", 30), 1, 30)] [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] \ + [add_lspace(A.lastused_total, 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]
" interact() if(!interactable()) @@ -23,7 +24,7 @@ var/t = "" t += "Refresh

" if(!L || !L.len) - t += "\red No connection" + t += "No connection" else var/datum/powernet/powernet = computer.net.connect_to(/datum/powernet,null) if(powernet) diff --git a/code/WorkInProgress/computer3/computers/prisoner.dm b/code/WorkInProgress/computer3/computers/prisoner.dm index d88a8bffdf..529a210e43 100644 --- a/code/WorkInProgress/computer3/computers/prisoner.dm +++ b/code/WorkInProgress/computer3/computers/prisoner.dm @@ -1,11 +1,14 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - /obj/machinery/computer3/prisoner + default_prog = /datum/file/program/prisoner + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) + icon_state = "frame-sec" + +/datum/file/program/prisoner name = "Prisoner Management Comsole" - icon = 'icons/obj/computer.dmi' - icon_state = "explosive" + active_state = "explosive" req_access = list(access_armory) - circuit = "/obj/item/part/board/circuit/prisoner" + var/id = 0.0 var/temp = null var/status = 0 @@ -14,18 +17,9 @@ var/screen = 0 // 0 - No Access Denied, 1 - Access allowed - attack_ai(var/mob/user as mob) - return src.attack_hand(user) - - - attack_paw(var/mob/user as mob) - return - - - attack_hand(var/mob/user as mob) - if(..()) + interact() + if(!interactable()) return - user.set_machine(src) var/dat dat += "Prisoner Implant Manager System
" if(screen == 0) @@ -35,7 +29,7 @@ var/turf/Tr = null for(var/obj/item/weapon/implant/chem/C in world) Tr = get_turf(C) - if((Tr) && (Tr.z != src.z)) continue//Out of range + if((Tr) && (Tr.z != computer.z)) continue//Out of range if(!C.implanted) continue dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: " dat += "((1))" @@ -45,7 +39,7 @@ dat += "
Tracking Implants
" for(var/obj/item/weapon/implant/tracking/T in world) Tr = get_turf(T) - if((Tr) && (Tr.z != src.z)) continue//Out of range + if((Tr) && (Tr.z != computer.z)) continue//Out of range if(!T.implanted) continue var/loc_display = "Unknown" var/mob/living/carbon/M = T.imp_in @@ -55,55 +49,52 @@ if(T.malfunction) loc_display = pick(teleportlocs) dat += "ID: [T.id] | Location: [loc_display]
" - dat += "(Message Holder) |
" + dat += "(Send Message
) |
" dat += "********************************
" dat += "
Lock Console" - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") + popup.width = 400 + popup.height = 500 + popup.set_content(dat) + popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) + popup.open() return process() if(!..()) - src.updateDialog() + interact() return Topic(href, href_list) - if(..()) + if(!interactable() || ..(href,href_list)) return - if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - if(href_list["inject1"]) - var/obj/item/weapon/implant/I = locate(href_list["inject1"]) - if(I) I.activate(1) + if(href_list["inject1"]) + var/obj/item/weapon/implant/I = locate(href_list["inject1"]) + if(I) I.activate(1) - else if(href_list["inject5"]) - var/obj/item/weapon/implant/I = locate(href_list["inject5"]) - if(I) I.activate(5) + else if(href_list["inject5"]) + var/obj/item/weapon/implant/I = locate(href_list["inject5"]) + if(I) I.activate(5) - else if(href_list["inject10"]) - var/obj/item/weapon/implant/I = locate(href_list["inject10"]) - if(I) I.activate(10) + else if(href_list["inject10"]) + var/obj/item/weapon/implant/I = locate(href_list["inject10"]) + if(I) I.activate(10) - else if(href_list["lock"]) - if(src.allowed(usr)) - screen = !screen - else - usr << "Unauthorized Access." + else if(href_list["lock"]) + screen = !screen - else if(href_list["warn"]) - var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN) - if(!warning) return - var/obj/item/weapon/implant/I = locate(href_list["warn"]) - if((I)&&(I.imp_in)) - var/mob/living/carbon/R = I.imp_in - R << "\green You hear a voice in your head saying: '[warning]'" + else if(href_list["warn"]) + var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN) + if(!warning) return + var/obj/item/weapon/implant/I = locate(href_list["warn"]) + if((I)&&(I.imp_in)) + var/mob/living/carbon/R = I.imp_in + R << "\green You hear a voice in your head saying: '[warning]'" - src.add_fingerprint(usr) - src.updateUsrDialog() + interact() return diff --git a/code/WorkInProgress/computer3/computers/robot.dm b/code/WorkInProgress/computer3/computers/robot.dm index e3eca9ace2..98eea82f9c 100644 --- a/code/WorkInProgress/computer3/computers/robot.dm +++ b/code/WorkInProgress/computer3/computers/robot.dm @@ -74,9 +74,9 @@ dat += " Independent from AI |" if (istype(usr, /mob/living/silicon)) if(issilicon(usr) && is_special_character(usr) && !R.emagged) - dat += "(Hack) " - dat += "([R.canmove ? "Lockdown" : "Release"]) " - dat += "(Destroy)" + dat += "(Hack) " + dat += "([R.canmove ? "Lockdown" : "Release"]) " + dat += "(Destroy)" dat += "
" dat += "(Return to Main Menu)
" if(screen == 2) diff --git a/code/WorkInProgress/computer3/computers/security.dm b/code/WorkInProgress/computer3/computers/security.dm index 77161bb247..7d94f892bb 100644 --- a/code/WorkInProgress/computer3/computers/security.dm +++ b/code/WorkInProgress/computer3/computers/security.dm @@ -10,7 +10,7 @@ icon_state = "laptop" -/datum/file/program/secure_data//TODO:SANITY +/datum/file/program/secure_data name = "Security Records" desc = "Used to view and edit personnel's security records" active_state = "security" diff --git a/code/WorkInProgress/computer3/computers/station_alert.dm b/code/WorkInProgress/computer3/computers/station_alert.dm index 2ee767a39a..850bfc83c5 100644 --- a/code/WorkInProgress/computer3/computers/station_alert.dm +++ b/code/WorkInProgress/computer3/computers/station_alert.dm @@ -1,33 +1,23 @@ - /obj/machinery/computer3/station_alert + default_prog = /datum/file/program/station_alert + spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/networking/radio) + icon_state = "frame-eng" + + +/datum/file/program/station_alert name = "Station Alert Console" desc = "Used to access the station's automated alert system." - icon_state = "alert:0" - circuit = "/obj/item/part/board/circuit/stationalert" + active_state = "alert:0" var/alarms = list("Fire"=list(), "Atmosphere"=list(), "Power"=list()) - - attack_ai(mob/user) - add_fingerprint(user) - if(stat & (BROKEN|NOPOWER)) - return - interact(user) - return - - - attack_hand(mob/user) - add_fingerprint(user) - if(stat & (BROKEN|NOPOWER)) - return - interact(user) - return - - interact(mob/user) usr.set_machine(src) - var/dat = "" + if(!interactable()) + return + var/dat = "Current Station Alerts\n" + dat += "Close

" for (var/cat in src.alarms) - dat += text("

[]

", cat) + dat += text("[]
\n", cat) var/list/L = src.alarms[cat] if (L.len) for (var/alarm in L) @@ -36,7 +26,7 @@ var/list/sources = alm[3] dat += "" dat += "• " - dat += "[format_text(A.name)]" + dat += "[A.name]" if (sources.len > 1) dat += text(" - [] sources", sources.len) dat += "
\n" @@ -45,11 +35,10 @@ dat += "
\n" //user << browse(dat, "window=alerts") //onclose(user, "alerts") - var/datum/browser/popup = new(user, "alerts", "Current Station Alerts") - popup.add_head_content("") popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) popup.open() + return Topic(href, href_list) @@ -59,8 +48,6 @@ proc/triggerAlarm(var/class, area/A, var/O, var/alarmsource) - if(stat & (BROKEN)) - return var/list/L = src.alarms[class] for (var/I in L) if (I == A.name) @@ -82,8 +69,6 @@ proc/cancelAlarm(var/class, area/A as area, obj/origin) - if(stat & (BROKEN)) - return var/list/L = src.alarms[class] var/cleared = 0 for (var/I in L) @@ -98,17 +83,15 @@ return !cleared + process() - if(stat & (BROKEN|NOPOWER)) - icon_state = "atmos0" - return var/active_alarms = 0 for (var/cat in src.alarms) var/list/L = src.alarms[cat] if(L.len) active_alarms = 1 if(active_alarms) - icon_state = "alert:2" + active_state = "alert:2" else - icon_state = "alert:0" + active_state = "alert:0" ..() return diff --git a/code/WorkInProgress/computer3/laptop.dm b/code/WorkInProgress/computer3/laptop.dm index c681ff50a7..4b3368b946 100644 --- a/code/WorkInProgress/computer3/laptop.dm +++ b/code/WorkInProgress/computer3/laptop.dm @@ -25,7 +25,7 @@ item_state = "laptop-inhand" pixel_x = 2 pixel_y = -3 - w_class = 4 + w_class = 3 var/obj/machinery/computer3/laptop/stored_computer = null diff --git a/code/WorkInProgress/computer3/program.dm b/code/WorkInProgress/computer3/program.dm index 985ed74d35..67e1d7b3d3 100644 --- a/code/WorkInProgress/computer3/program.dm +++ b/code/WorkInProgress/computer3/program.dm @@ -281,7 +281,7 @@ Programs are a file that can be executed /datum/file/program/Genetics name = "Genetics Suite" - image = 'icons/nots/genetics.png' + image = 'icons/ntos/genetics.png' desc = "A sophisticated software suite containing read-only genetics hardware specifications and a highly compressed genome databank." active_state = "dna" volume = 8000 diff --git a/icons/obj/computer3.dmi b/icons/obj/computer3.dmi index 4942da6a6b50d0b0b744a9177053426b7433ab4e..1fb6ce267ef9d6da564cef9948c25f8ad2ed886b 100644 GIT binary patch delta 33737 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�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 Date: Sun, 22 Jun 2014 23:42:47 -0700 Subject: [PATCH 07/25] fixes for potential runtimes. --- code/WorkInProgress/computer3/NTOS.dm | 8 ++++---- code/WorkInProgress/computer3/computers/medical.dm | 3 +++ code/WorkInProgress/computer3/computers/prisoner.dm | 2 +- code/WorkInProgress/computer3/computers/security.dm | 4 ++++ code/WorkInProgress/computer3/program.dm | 6 +++--- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/code/WorkInProgress/computer3/NTOS.dm b/code/WorkInProgress/computer3/NTOS.dm index 8b779d9077..b7c2defc4a 100644 --- a/code/WorkInProgress/computer3/NTOS.dm +++ b/code/WorkInProgress/computer3/NTOS.dm @@ -25,16 +25,16 @@ i++ if(i==1) dat += "" - if(i>= 7) + if(i>= 6) i = 0 dat += "" continue dat += {" - +

[F.name] -
+
"} dat += "" @@ -53,7 +53,7 @@ i++ if(i==1) dat += "" - if(i>= 8) + if(i>= 6) i = 0 dat += "" continue diff --git a/code/WorkInProgress/computer3/computers/medical.dm b/code/WorkInProgress/computer3/computers/medical.dm index 8e6b7cb7fc..ee55a857b2 100644 --- a/code/WorkInProgress/computer3/computers/medical.dm +++ b/code/WorkInProgress/computer3/computers/medical.dm @@ -41,6 +41,9 @@ return 0 interact() + if(!computer.cardslot) + computer.Crash(MISSING_PERIPHERAL) + return usr.set_machine(src) scan = computer.cardslot.reader if(!interactable()) diff --git a/code/WorkInProgress/computer3/computers/prisoner.dm b/code/WorkInProgress/computer3/computers/prisoner.dm index 529a210e43..51beec5c03 100644 --- a/code/WorkInProgress/computer3/computers/prisoner.dm +++ b/code/WorkInProgress/computer3/computers/prisoner.dm @@ -5,7 +5,7 @@ icon_state = "frame-sec" /datum/file/program/prisoner - name = "Prisoner Management Comsole" + name = "Prisoner Management Console" active_state = "explosive" req_access = list(access_armory) diff --git a/code/WorkInProgress/computer3/computers/security.dm b/code/WorkInProgress/computer3/computers/security.dm index 7d94f892bb..a9abf0a5f4 100644 --- a/code/WorkInProgress/computer3/computers/security.dm +++ b/code/WorkInProgress/computer3/computers/security.dm @@ -44,10 +44,14 @@ return 0 interact() + if(!computer.cardslot) + computer.Crash(MISSING_PERIPHERAL) + return usr.set_machine(src) scan = computer.cardslot.reader if(!interactable()) return + return if (computer.z > 6) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return diff --git a/code/WorkInProgress/computer3/program.dm b/code/WorkInProgress/computer3/program.dm index 67e1d7b3d3..4c977489f5 100644 --- a/code/WorkInProgress/computer3/program.dm +++ b/code/WorkInProgress/computer3/program.dm @@ -349,20 +349,20 @@ Programs are a file that can be executed active_state = "computer_generic" volume = 520 -/datum/file/program/PowerMonitor +/datum/file/program/powermon name = "Power Grid" image = 'icons/ntos/power.png' active_state = "power" volume = 7200 -/datum/file/program/PrisonerManagement +/datum/file/program/prisoner name = "Prisoner Control" image = 'icons/ntos/prison.png' drm = 1 active_state = "power" volume = 5000 -/datum/file/program/Roboticscontrol +/datum/file/program/borg_control name = "Cyborg Maint" image = 'icons/ntos/borgcontrol.png' active_state = "robot" From e96b682cf4757e36f7674a6466dc4aa445a0daad Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sun, 22 Jun 2014 23:45:38 -0700 Subject: [PATCH 08/25] laptop vendor! --- code/WorkInProgress/computer3/lapvend.dm | 398 +++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 code/WorkInProgress/computer3/lapvend.dm diff --git a/code/WorkInProgress/computer3/lapvend.dm b/code/WorkInProgress/computer3/lapvend.dm new file mode 100644 index 0000000000..d36af863d1 --- /dev/null +++ b/code/WorkInProgress/computer3/lapvend.dm @@ -0,0 +1,398 @@ +/obj/machinery/lapvend + name = "Laptop Vendor" + desc = "A generic vending machine." + icon = 'icons/obj/vending.dmi' + icon_state = "robotics" + layer = 2.9 + anchored = 1 + density = 1 + var/datum/browser/popup = null + var/obj/machinery/computer3/laptop/vended/newlap = null + var/obj/item/device/laptop/relap = null + var/vendmode = 0 + + + var/cardreader = 0 + var/floppy = 0 + var/radionet = 0 + var/camera = 0 + var/network = 0 + var/power = 0 + + +/obj/machinery/lapvend/New() + ..() + spawn(4) + power_change() + return + return + + +/obj/machinery/lapvend/blob_act() + if (prob(50)) + spawn(0) + del(src) + return + + return + + +/obj/machinery/lapvend/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(vendmode == 1) + if(istype(W, /obj/item/weapon/card)) + var/obj/item/weapon/card/I = W + scan_card(I) + vendmode = 0 + if(vendmode == 3) + if(istype(W,/obj/item/weapon/card)) + var/obj/item/weapon/card/I = W + reimburse(I) + vendmode = 0 + if(vendmode == 0) + if(istype(W, /obj/item/device/laptop)) + var/obj/item/device/laptop/L = W + relap = L + calc_reimburse(L) + usr.drop_item() + L.loc = src + vendmode = 3 + usr << "You slot your [L.name] into \The [src.name]" + else + ..() + + +/obj/machinery/lapvend/attack_hand(mob/user as mob) + user.set_machine(src) + var/vendorname = (src.name) //import the machine's name + var/dat = "
[vendorname]


" //display the name, and added a horizontal rule + if(vendmode == 0) + dat += "
Please choose your laptop customization options

" + dat += "
Your comptuer will automatically be loaded with any programs you can use after the transaction is complete." + dat += "
Some programs will require additional components to be installed!


" + dat += "
HDD (Required) : Added

" + dat += "
Card Reader : Single (50) | Dual (125)
" + dat += "
Floppy Drive: Add (50)
" + dat += "
Radio Network card Add (50)
" + dat += "
Camera Card Add (100)
" + dat += "
Network card Area (75) Adjacent (50)Powernet (25)
" + dat += "
Power source upgrade
Extended (175) Unreal (250)" + + if(vendmode == 0 || vendmode == 1) + dat += "

Cart

" + dat += "Total: [total()]
" + if(cardreader == 1) + dat += "Card Reader: (single) (50)
" + else if (cardreader == 2) + dat += "Card Reader: (double) (125)
" + else + dat += "Card Reader: None
" + if(floppy == 0) + dat += "Floppy Drive: None
" + else + dat += "Floppy Drive: Added (50)
" + if(radionet == 1) + dat += "Radio Card: Added (50)
" + else + dat += "Radio Card: None
" + if(camera == 1) + dat += "Camera Card: Added (100)
" + else + dat += "Camera Card: None
" + if(network == 1) + dat += "Network card: Area (75)
" + else if(network == 2) + dat += "Network card: Adjacent (50)
" + else if(network == 3) + dat += "Network card: Powernet (25)
" + else + dat += "Network card: None" + if (power == 0) + dat += "Power source: Regular" + else if (power == 1) + dat += "Power source: Extended (175)
" + else + dat += "Power source: Unreal (250)
" + + if(vendmode == 0) + dat += "
Vend Laptop" + + if(vendmode == 1) + dat += "Please swipe your card and enter your PIN to complete the transaction" + + if(vendmode == 3) + dat += "Please swipe your card and enter your PIN to be finish returning your computer
" + dat += "Cancel" + + + + + popup = new(user, "lapvend", name, 450, 500) + popup.set_content(dat) + popup.open() + return + + +/obj/machinery/lapvend/Topic(href, href_list) + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) + usr.set_machine(src) + switch(href_list["choice"]) + if("single_add") + cardreader = 1 + if ("dual_add") + cardreader = 2 + if ("floppy_add") + floppy = 1 + if ("radio_add") + radionet = 1 + if ("camnet_add") + camera = 1 + if ("area_add") + network = 1 + if ("prox_add") + network = 2 + if ("cable_add") + network = 3 + if ("high_add") + power = 1 + if ("super_add") + power = 2 + + if ("single_rem" || "dual_rem") + cardreader = 0 + if ("floppy_rem") + floppy = 0 + if ("radio_rem") + radionet = 0 + if ("camnet_rem") + camera = 0 + if ("area_rem" || "prox_rem" || "cable_rem") + network = 0 + if ("high_rem" || "super_rem") + power = 0 + + if("vend") + vendmode = 1 + + if("cancel") + relap.loc = src.loc + relap = null + vendmode = 0 + + src.updateUsrDialog() + return + + +/obj/machinery/lapvend/proc/vend() + if(cardreader > 0) + if(cardreader == 1) + newlap.spawn_parts += (/obj/item/part/computer/cardslot) + else + newlap.spawn_parts += (/obj/item/part/computer/cardslot/dual) + if(floppy == 1) + newlap.spawn_parts += (/obj/item/part/computer/storage/removable) + if(radionet == 1) + newlap.spawn_parts += (/obj/item/part/computer/networking/radio) + if(camera == 1) + newlap.spawn_parts += (/obj/item/part/computer/networking/cameras) + if (network == 1) + newlap.spawn_parts += (/obj/item/part/computer/networking/area) + if (network == 2) + newlap.spawn_parts += (/obj/item/part/computer/networking/prox) + if (network == 3) + newlap.spawn_parts += (/obj/item/part/computer/networking/cable) + if (power == 1) + del(newlap.battery) + newlap.battery = new /obj/item/weapon/cell/high(newlap) + if (power == 2) + del(newlap.battery) + newlap.battery = new /obj/item/weapon/cell/super(newlap) + + newlap.spawn_parts() + +/obj/machinery/lapvend/proc/scan_card(var/obj/item/weapon/card/I) + if (istype(I, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = I + visible_message("[usr] swipes a card through [src].") + if(vendor_account) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) + if(D) + var/transaction_amount = total() + if(transaction_amount <= D.money) + + //transfer the money + D.money -= transaction_amount + vendor_account.money += transaction_amount + + //Transaction logs + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Purchase of Laptop" + if(transaction_amount > 0) + T.amount = "([transaction_amount])" + else + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + D.transaction_log.Add(T) + // + T = new() + T.target_name = D.owner_name + T.purpose = "Purchase of Laptop" + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) + + newlap = new /obj/machinery/computer3/laptop/vended(src.loc) + + choose_progs(C) + vend() + popup.close() + newlap.close_computer() + newlap = null + cardreader = 0 + floppy = 0 + radionet = 0 + camera = 0 + network = 0 + power = 0 + else + usr << "\icon[src]You don't have that much money!" + else + usr << "\icon[src]Unable to access account. Check security settings and try again." + else + usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + +/obj/machinery/lapvend/proc/total() + var/total = 0 + + if(cardreader == 1) + total += 50 + if(cardreader == 2) + total += 125 + if(floppy == 1) + total += 50 + if(radionet == 1) + total += 50 + if(camera == 1) + total += 100 + if(network == 1) + total += 75 + if(network == 2) + total += 50 + if(network == 3) + total += 25 + if(power == 1) + total += 175 + if(power == 2) + total += 250 + + return total + +/obj/machinery/lapvend/proc/choose_progs(var/obj/item/weapon/card/id/C) + if(access_security in C.access) + newlap.spawn_files += (/datum/file/program/secure_data) + newlap.spawn_files += (/datum/file/camnet_key) + newlap.spawn_files += (/datum/file/program/security) + if(access_armory in C.access) + newlap.spawn_files += (/datum/file/program/prisoner) + if(access_atmospherics in C.access) + newlap.spawn_files += (/datum/file/program/atmos_alert) + if(access_change_ids in C.access) + newlap.spawn_files += (/datum/file/program/card_comp) + if(access_heads in C.access) + newlap.spawn_files += (/datum/file/program/communications) + if(access_medical in C.access) + newlap.spawn_files += (/datum/file/program/crew) + newlap.spawn_files += (/datum/file/program/med_data) + if(access_engine in C.access) + newlap.spawn_files += (/datum/file/program/powermon) + if(access_research in C.access) + newlap.spawn_files += (/datum/file/camnet_key/research) + newlap.spawn_files += (/datum/file/camnet_key/bombrange) + newlap.spawn_files += (/datum/file/camnet_key/xeno) + if(access_rd in C.access) + newlap.spawn_files += (/datum/file/program/borg_control) + if(access_cent_specops in C.access) + newlap.spawn_files += (/datum/file/camnet_key/creed) + newlap.spawn_files += (/datum/file/program/arcade) + newlap.spawn_files += (/datum/file/camnet_key/entertainment) + newlap.update_spawn_files() + +/obj/machinery/lapvend/proc/calc_reimburse(var/obj/item/device/laptop/L) + if(istype(L.stored_computer.cardslot,/obj/item/part/computer/cardslot)) + cardreader = 1 + if(istype(L.stored_computer.cardslot,/obj/item/part/computer/cardslot/dual)) + cardreader = 2 + if(istype(L.stored_computer.floppy,/obj/item/part/computer/storage/removable)) + floppy = 1 + if(istype(L.stored_computer.radio,/obj/item/part/computer/networking/radio)) + radionet = 1 + if(istype(L.stored_computer.camnet,/obj/item/part/computer/networking/cameras)) + camera = 1 + if(istype(L.stored_computer.net,/obj/item/part/computer/networking/area)) + network = 1 + if(istype(L.stored_computer.net,/obj/item/part/computer/networking/prox)) + network = 2 + if(istype(L.stored_computer.net,/obj/item/part/computer/networking/cable)) + network = 3 + if(istype(L.stored_computer.battery, /obj/item/weapon/cell/high)) + power = 1 + if(istype(L.stored_computer.battery, /obj/item/weapon/cell/super)) + power = 2 + + + +/obj/machinery/lapvend/proc/reimburse(var/obj/item/weapon/card/I) + if (istype(I, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = I + visible_message("[usr] swipes a card through [src].") + if(vendor_account) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) + if(D) + var/transaction_amount = total() + + //transfer the money + D.money += transaction_amount + vendor_account.money -= transaction_amount + + //Transaction logs + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Return purchase of Laptop" + if(transaction_amount > 0) + T.amount = "([transaction_amount])" + else + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + D.transaction_log.Add(T) + // + T = new() + T.target_name = D.owner_name + T.purpose = "Return purchase of Laptop" + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) + + del(relap) + + vendmode = 0 + cardreader = 0 + floppy = 0 + radionet = 0 + camera = 0 + network = 0 + power = 0 + + else + usr << "\icon[src]Unable to access account. Check security settings and try again." + else + usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." \ No newline at end of file From dc6b2ef3bf4156687a5e6077b6ee7c39432dcd65 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Sun, 22 Jun 2014 23:55:26 -0700 Subject: [PATCH 09/25] allows laptops to be recharged in rechargers. --- code/game/machinery/recharger.dm | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 094d3af123..a5d9a6ce1d 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -8,12 +8,12 @@ obj/machinery/recharger use_power = 1 idle_power_usage = 4 active_power_usage = 250 - var/obj/item/weapon/charging = null + var/obj/item/charging = null obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob) if(istype(user,/mob/living/silicon)) return - if(istype(G, /obj/item/weapon/gun/energy) || istype(G, /obj/item/weapon/melee/baton)) + if(istype(G, /obj/item/weapon/gun/energy) || istype(G, /obj/item/weapon/melee/baton) || istype(G,/obj/item/device/laptop)) if(charging) return @@ -31,6 +31,11 @@ obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob) return if (istype(G, /obj/item/weapon/gun/energy/staff)) return + if(istype(G, /obj/item/device/laptop)) + var/obj/item/device/laptop/L = G + if(!L.stored_computer.battery) + user << "There's no battery in it!" + return user.drop_item() G.loc = src charging = G @@ -79,6 +84,16 @@ obj/machinery/recharger/process() use_power(150) else icon_state = "recharger2" + return + if(istype(charging, /obj/item/device/laptop)) + var/obj/item/device/laptop/L = charging + if(L.stored_computer.battery.charge < L.stored_computer.battery.maxcharge) + L.stored_computer.battery.give(100) + icon_state = "recharger1" + use_power(250) + else + icon_state = "recharger2" + return obj/machinery/recharger/emp_act(severity) if(stat & (NOPOWER|BROKEN) || !anchored) From 80580de834b4d4478f4922de4bdf0781b00cefde Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Mon, 23 Jun 2014 00:07:55 -0700 Subject: [PATCH 10/25] added laptops and extra chargers to the map. --- maps/tgstation2.dmm | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/maps/tgstation2.dmm b/maps/tgstation2.dmm index 9330039a8b..92986dd969 100644 --- a/maps/tgstation2.dmm +++ b/maps/tgstation2.dmm @@ -791,7 +791,7 @@ "apk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Brig Evidence Storage"; dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "apl" = (/obj/structure/rack,/obj/item/weapon/storage/box/seccarts{pixel_x = 3; pixel_y = 2},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs{pixel_x = -2; pixel_y = -2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) "apm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/item/weapon/folder/red,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/security/main) -"apn" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/item/weapon/storage/fancy/donut_box,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) +"apn" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/recharger{pixel_y = 0},/obj/item/weapon/storage/fancy/donut_box,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) "apo" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/security/hos) "app" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/security/hos) "apq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/stool,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) @@ -1604,7 +1604,7 @@ "aER" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aES" = (/obj/structure/table,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/storage/primary) "aET" = (/obj/effect/landmark/start{name = "Assistant"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor,/area/storage/primary) -"aEU" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/security/vacantoffice) +"aEU" = (/obj/machinery/lapvend,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/exit) "aEV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plating,/area/security/vacantoffice) "aEW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/plating,/area/security/vacantoffice) "aEX" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/security/vacantoffice) @@ -2227,7 +2227,7 @@ "aQQ" = (/obj/machinery/door/morgue{dir = 2; name = "Confession Booth"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aQR" = (/obj/machinery/light/small,/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1480; name = "Confessional Intercom"; pixel_x = 25},/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aQS" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aQT" = (/obj/machinery/computer/arcade,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/exit) +"aQT" = (/obj/structure/table/woodentable,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor/wood,/area/library) "aQU" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit) "aQV" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/hallway/secondary/exit) "aQW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/exit) @@ -4025,7 +4025,7 @@ "bzu" = (/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/hallway/primary/central) "bzv" = (/obj/structure/filingcabinet/chestdrawer,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/crew_quarters/heads) "bzw" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel RC"; pixel_y = -30},/obj/machinery/camera{c_tag = "Head of Personnel's Office"; dir = 1},/turf/simulated/floor,/area/crew_quarters/heads) -"bzx" = (/obj/structure/table,/obj/item/device/eftpos{eftpos_name = "HoP EFTPOS scanner"},/turf/simulated/floor,/area/crew_quarters/heads) +"bzx" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor,/area/storage/primary) "bzy" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/wood,/area/medical/psych) "bzz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/wall/r_wall,/area/turret_protected/ai_server_room) "bzA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/crew_quarters/sleep/engi) @@ -6162,7 +6162,7 @@ "coz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "coA" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "coB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"coC" = (/obj/structure/table/reinforced,/turf/simulated/floor,/area/hallway/primary/aft) +"coC" = (/obj/structure/table/woodentable,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor/plating,/area/security/vacantoffice) "coD" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/item/weapon/folder/yellow,/turf/simulated/floor,/area/hallway/primary/aft) "coE" = (/obj/structure/table/reinforced,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/hallway/primary/aft) "coF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) @@ -6338,6 +6338,7 @@ "crT" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter,/obj/machinery/firealarm{pixel_y = 24},/turf/simulated/floor,/area/atmos) "crU" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/atmos) "crV" = (/obj/structure/stool/bed/chair/comfy/brown,/obj/effect/landmark/start{name = "Psychiatrist"},/turf/simulated/floor{icon_state = "bcarpet06"},/area/medical/psych) +"crW" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor/plating,/area/security/vacantoffice) "crX" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/decal/cleanable/blood/oil{amount = 0},/turf/simulated/floor/plating,/area/maintenance/asmaint) "crY" = (/obj/machinery/computer/atmos_alert,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor,/area/engine/engineering_monitoring) "crZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) @@ -8236,6 +8237,7 @@ "dcu" = (/obj/machinery/camera{c_tag = "Central Compartment South"; dir = 1; network = list("Tcomsat")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light,/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) "dcv" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 120; icon_state = "in"; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) "dcw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/wall/r_wall,/area/tcommsat/chamber) +"dcx" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor/plating,/area/security/vacantoffice) "dcy" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/space,/area/turret_protected/tcomsat) "dcz" = (/obj/structure/window/reinforced,/obj/structure/lattice,/obj/machinery/light{dir = 1},/turf/space,/area/turret_protected/tcomsat) "dcA" = (/turf/simulated/wall/r_wall,/area/turret_protected/tcomfoyer) @@ -10666,10 +10668,12 @@ "dXh" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/asmaint) "dXi" = (/obj/structure/table,/obj/item/weapon/storage/box/cups,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "dXj" = (/obj/structure/reagent_dispensers/water_cooler,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"dXk" = (/obj/machinery/lapvend,/turf/simulated/floor,/area/storage/primary) "dXl" = (/turf/unsimulated/wall{icon_state = "phoron14"},/area/alien) "dXm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/virology) "dXn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virologyq_airlock_exterior"; locked = 1; name = "Virology Quarantine Airlock"; req_access_txt = "39"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virologyq_airlock_control"; name = "Virology Quarantine Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "39"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "dXo" = (/turf/unsimulated/wall{icon_state = "phoron10"},/area/alien) +"dXp" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/medbreak) "dXq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "dXr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "dXs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) @@ -10733,6 +10737,8 @@ "dYy" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/closet/l3closet/virology,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/clothing/mask/gas,/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/medical/virology) "dYz" = (/obj/machinery/portable_atmospherics/canister,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power) "dYA" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor,/area/quartermaster/office) +"dYB" = (/obj/structure/table,/obj/item/device/eftpos{eftpos_name = "HoP EFTPOS scanner"},/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor,/area/crew_quarters/heads) +"dYC" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor,/area/hallway/primary/aft) "dYF" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "dYG" = (/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; sortType = "Atmospherics"; name = "Atmospherics"},/turf/simulated/floor,/area/atmos) "dYH" = (/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_access_txt = null; req_one_access_txt = "5;12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/incinerator) @@ -10974,23 +10980,23 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafazQasSazRavtazSazTazUazVazWazSavtazXazYasSazZaAaatKaAbaAcaAcaAcaAcaAcaAcavzbezaAeazbaAfaAgaAhazbbghapaapaapaapaapaapaapaapaaAjaygaafaAkaAkaAkaAkaAkaAkaAkaafaygaykaylaAlaAmaAnaAoaAlaylaQnaApaxraxraxraxraAqaAraypaAsaAraAtaxraxraxraxrayzapEaAualNaQvaNFaHybdEaHqaHravdaAvazBazBazBazBazBazBaAwaAxaAyazBasPasPasPasPbgobgrasPasPbdKasRasRasRasRasRbdKasPaaaaaaaaaaaeaaaaaaaaaaaaaafaAAaABbdTaADaAAaafaaaaaaaafaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxRayVaAEaAFaAFaAFaAFaAGayVaxRaAHasSaAIaAJaAKaAKaAKaAKaAKaAKaAKaAKawibfxbfzazbbckaANaAOazbaAPaAQaAPaAPaAPaAPaAPaAPaAPaAPaARaaaaAkaASaATaAUbbTaAWaAkaaaaygaykaylaAlaAXbewaAZaAlaylaQnapxaxraBaaBbazlaBcaBdazoazpaBdaBeazsaBfaBfaxrayzapEayAalNbdZaIkaIhbdEbejbelavdaAvazBaBiaAxaBjaBjazBaAwaBkaAyazBaBlaBmaBnaBobhDaULaBqaafbfBbfdbfdbfdbfdbfdbfgaafaaaaaaaaaaaaaaaaaaaaaaaaaafaAAaBuaBvaBwaAAaafaaaaaaaBqaBqaBqaBqaBqbhqbhCaBqaBqaBqaBqaBqaBqaBqbgHaBFaBFaBFaBGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaBHaBIaBJaBIaBIaDRaDSaBIaBIaBJaBMaBNasSayWaBOaQlaQjaSQaBSaBTaBUaBVaAKawiaPOatKazbazbaBXaBYaARaBZaCaaCbaCcaCdaCeaCfaCgaXEaCiaARaafaAkaQmaCkaClaCmaCnaAkaafaygaykaylaCoaCpaCqaCpaCraylaQnaCsaxrayoaypaCtaCuaAraCvaAsaAraCwaCxaypaCyaxrayzapEayAalNaQvaIAaIDaQxaIvaHraCAaCBazBaCCaAxaAxaAxazCaCDaCEaCFazBaCGaCHaCIaCJaYFaULaBqaaaaafaaaaafaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaAAaZbaCMaCNaAAaBqaCOaCPaBqaQSaQDaQDaQDaQDaQDaQDaQFaRdaRdaRdaRdaRfaRdaRdaRdaRhaDaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBHaBMaBIaDbaDcaDcaDdaDeaDfaDgaDhaDcaDcaDiaDjayUayWaZuaAKaRqaDmaDnaDoaDnaDpaDqaDraDsaqYaZnaDuaDvaAcaDwaDxaDyaDzaDzaDzaDAaDzaDzaDBaCaaARaaaaAkaRAaRTaRVaCmaSaaAkaaaaygaykaylaRuaDHaDIaDJaRyaylaQnaDLaxraxraxraxraDMaAraypaDNaBdaDOaTuaypaDQaVHaVzaVAaVpaVwaKJaVGaShaShaShaSEaScaVdaTiaTnbabaSPaSPaSPaUgaSPaTFaTTaTUaTVaUkaUGaVQaULaBqaBqaBqaBqaBqaBqaBqaBqaBqaCOaCPaBqaBqaBqaCOaEjaEkaBqaBqaAAaAAaElaEmaAAaEnaVqaVoaVoaVsaEsaEsaEsaEsaEsaWyaVraEuaEuaEuaEuaUNaEuaEyaEyaVnaEyaEyaEyaEyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBHaBMaBIaDbaDcaDcaDdaDeaDfaDgaDhaDcaDcaDiaDjayUayWaZuaAKaRqaDmaDnaDoaDnaDpaDqaDraDsaqYaZnaDuaDvaAcaDwaDxaDyaDzaDzaDzaDAaDzaDzaDBdXkaARaaaaAkaRAaRTaRVaCmaSaaAkaaaaygaykaylaRuaDHaDIaDJaRyaylaQnaDLaxraxraxraxraDMaAraypaDNaBdaDOaTuaypaDQaVHaVzaVAaVpaVwaKJaVGaShaShaShaSEaScaVdaTiaTnbabaSPaSPaSPaUgaSPaTFaTTaTUaTVaUkaUGaVQaULaBqaBqaBqaBqaBqaBqaBqaBqaBqaCOaCPaBqaBqaBqaCOaEjaEkaBqaBqaAAaAAaElaEmaAAaEnaVqaVoaVoaVsaEsaEsaEsaEsaEsaWyaVraEuaEuaEuaEuaUNaEuaEyaEyaVnaEyaEyaEyaEyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaEBaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSayWaEHaAKaVuaEJaEKaELaEMaENaAKaEOaVtaAcaEQaAcaERaqYaAPaESaDBaDzaDzaDzaDzaDzaDzaETaWjaWgaVJaVIaWMaWNaWKaWLaWJaAkaafaygaWIaWpaWuaWxaWqaWsaWkaWpaZdaZcaxraFmaypazlaFnaBdazoaFoaAraCwaVvaypaFqaVHaWTaFsaFtaXcbdZagjagjagjagjaVEaVFaWSaVxaVybazaVxaXfaVxaXeaVxaXgaXhaFGaFHaFIaBoaXjaXmaXXaXVaXVaXCaYcaXYaXYaXYaXYaXYbaCaXYaXYaYwaYgaYeaXnaYHaYGaYxaWOaWPaWQaWQaWQaWRaEsaEsaGeaEsaGfaGgaGhaEsaEuaWUaEuaGjaXlaXkaGmaGnaGoaIbasHaGraGsaGtaGuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXoaDcaDcaBJaDcaEEaDcaEEaGxaEEaDcaEEaDcaEFaEGazSayWaGyaAKaYQaYRaYKaYPaYKaQlaQlaYJaYNaYOaYLaYMaYLaYLbakbajaGKaGLaGLaGLaGMaGLaGLaGNaGOaARaaaaZXaAkaGQaZOaGQaAkaAkaaaaygavOaylbaiaZIaZiaZqaZDaZEaZhbglaxraHbaypaCxaCuaAraypaAsaAraCwaZgaypaHdawGaYhaHfaHgaUnaYfalNalNalNalNalNaHjaYbazBaHlaAxazBaHmazBaHnazBaHobcvbcwbcNbczbdNbcXaYUbdlbdmbbvbdAbbwbbvbbvbbxbbzbbybbAbbybbFbbybbybbibcubcbbawbawbbEbaSbawbaxbawbaWaYIaHOaHPaHQaHRaHSaHTaEsaHUbaXaEuaHWaHXaYiaHZaGnaIaaIbasHaIcaEyaEyaEyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaIdaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSaIeawzawyawxawuawuawuawzawCawDawzawAaImaInawBauKauKaAPaGOaIpaCaaIqaGOaGOaIraIsaItaIuaARaaaawaaaaavMavNavMaaaaafaaaaygavOaylaIyaIzavZaIBaICaylavLapaaxraIEaypazlaIFaIGazoaIHaIIaIJaIKaILaIMawGaBsaIOaIPaIQaBKaISaaaaaaaUnaIUaIVaBLazBaIXaAxaAxaAxaCEaAxaAxaAxauOaBoaKyaBoaBoavJaBoaJcaBoaJdavHavGaJgaJhaJiaJjaJkavFaJjavEaJjaJjaJjaJjavDaJjaJjavCaJjaJjaJjaJjasIayRayvaAzaAiaBraBpazHbMsazIavpavlavmavnazFayNayPazDazEasHaIbaJDaJEaJFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaJIaBIaDbaDcaDcaDcaJJaDcaDcaJKaDcaDcaDiaJLaJMayWaxTaJNaJOaJOaJOaJOaJOaJOaJOaJPasDatKatKavkatKatKaAPaJSaJTaJUaJVaJVaJVaJVaJWaJXaJYaARaJZavaaKbaKcavbaKeaKbaKbaKfaygavcaylaylaylayKayJayLawGayBavKaxraxraxraxraKlaKmaCxaCxaKnayHawGawGaxraxraIOaIOaIOaIOaKpaKqaKraKsaUnaKtaIVaKuazBazBazBazBazBazBazBazBazBauOaKwaKvaKxaIZauMavIaKBaKCaJdauyauWauXaKGaKHaJjaKIauVaKKawtaKKaKMaKNaKOauQaKQaKRauxaKTauUaKVaJjauwauvaKYaJraKZaJtaJuaysaEsaLbauuaLdavfauoaveaunaEuaEyaLhasHaIbaLiaLjaLkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaIdaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSaIeawzawyawxawuawuawuawzawCawDawzawAaImaInawBauKauKaAPaGOaIpaCaaIqbzxaGOaIraIsaItaIuaARaaaawaaaaavMavNavMaaaaafaaaaygavOaylaIyaIzavZaIBaICaylavLapaaxraIEaypazlaIFaIGazoaIHaIIaIJaIKaILaIMawGaBsaIOaIPaIQaBKaISaaaaaaaUnaIUaIVaBLazBaIXaAxaAxaAxaCEaAxaAxaAxauOaBoaKyaBoaBoavJaBoaJcaBoaJdavHavGaJgaJhaJiaJjaJkavFaJjavEaJjaJjaJjaJjavDaJjaJjavCaJjaJjaJjaJjasIayRayvaAzaAiaBraBpazHbMsazIavpavlavmavnazFayNayPazDazEasHaIbaJDaJEaJFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaJIaBIaDbaDcaDcaDcaJJaDcaDcaJKaDcaDcaDiaJLaJMayWaxTaJNaJOaJOaJOaJOaJOaJOaJOaJPasDatKatKavkatKatKaAPaJSaJTaJUaJVaJVaJVaJVaJWaJXaJYaARaJZavaaKbaKcavbaKeaKbaKbaKfaygavcaylaylaylayKayJayLawGayBavKaxraxraxraxraKlaKmaCxaCxaKnayHawGawGaxraxraIOaIOaIOaIOaKpaKqaKraKsaUnaKtaIVaKuazBazBazBazBazBazBazBazBazBauOaKwaKvaKxaIZauMavIaKBaKCaJdauyauWauXaKGaKHaJjaKIauVaKKawtaKKaKMaKNaKOauQaKQaKRauxaKTauUaKVaJjauwauvaKYaJraQTaJtaJuaysaEsaLbauuaLdavfauoaveaunaEuaEyaLhasHaIbaLiaLjaLkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaBIaBJaBIaBIaDRaDSaBIaBIaBJaJIaLmasSaLnaxTawXaLoaLoaLpaLoaLqatHaLraLsasDaLtaLuaACaLwazwaLyaLzaLAaLzaLzaLzaLzaLzaLzaLzaLBaLCazNaAdaLFaLFayTaLHaLFaLFaLFaLIazKaLKaLLaLFazJaLNaLOaLPaDKaIOaLRaLSaIOaIPaLTaLTaLTaLTaLTaLTaLUaLVaLWaLXaLYaLZaMaaMbaMcaIOaIOaIOaDGaMeaMfaMeaMgaMhaMiaMjaIOaMkaIOaBoaMlaxMaOOaMoaMnaMpaxKaMraMsaMtaJdaxLaMvaMwaMwaMxaJjaMyaxJaMAaxBaMAaMAaMCaMDaxDaMDaMFayOayCayQaMDaJjasIarZaHPaHPaCXaDFaHPaHPaEsaMOaMPaEuaytaMRaHZavTaEuaMSaymayeaIbaEyaEyaEyaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawXayVaMVaAFaAFaAFaAFaMWayVawXaAHasSaAIaMXaMYaMZavSaNbaNbaNcatHaNdaLsaxAaNfaLuaxzaNhaNiaNjaNkaNlaLzaLzaLzaLzaLzaLzaLzaxhaxiaxuaLzaLzaLzaxpayuaLzaLzaLzaLzaxvaLzaLzaLzaxtaNmaLuaLPaIOaIOaIOaIOaIOaIOaIOaIOaIOaIOaIOaIOaNsaNtaNuaNvaNwaNxaNyaNzaNAaIOaIOaIOaLPaIOaIOaIOaIOaIOaIOaIOaIOaNBaCzaCjaCWaCQaMpaNEaMpaMpawEaNGaMsaNHaJdawFawJawSaNLaNMaJjaNNawTaNPawHaNRaNSaJjaNTawIaNTaJjaJjaJjavCaJjaJjasIarZaNVaHPaHPaNWaHPaNXaEsaEuaEuaEuaEuaEuaEuavQaEuaIbaIbasHaIbaNZaOaaEyaaaaafaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafazQasSaMYavtazSaObaOcaOdaOeazSavtaOfaOgasSayWaxTaMYaOhaOiaNbaNbaNcatHaOjaLsasDaNfaLuasXaLAaLzaLzaLzaChaEzaBPaLzausardaOmaOraALatmarMaOmaOvaOwaOxathatlatkatjatiatcatbatbasYatdaNmaLuaLPaIOaOHaIOaOIaOIaOIaOIaOIaOIaOIaOIaOJaOKaOIaOIaOIaOIaOLaOIaOIaOIaOIaOIaOMaONaOIaOIaOIaOIaOIaOIaOIaIOaIOaIOaBoaAYasOaOQaOQaOQaORasQaNGaMsaBQaJdaJdaJdaJdaJdaOUaJjaOVasKasLasNaNPaNPaJjaOZasMaPbaPcaPbaPbasJaPeaJjasIarZaPfaPfaPgaPhaPiaPiaPjaEsaPkaPlaPmaEyaskaVbasbaIbaIbasHaIbaEyaPsaEyaPtaPtaPtaPuaPvaPwaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafatHaxRayVaJMayWaxTaxTayXaJMayVaJMaPxawYaPyaxTaxRaPzaPzaLpaPzaLqatHaPAaLsasDaPBaPBasCatzaPBaPEaPEaPEaPEaPEaPFaPGaPEaPEaPEaPEaPEasEaPIaPJaPIaPKasGaPMaLzaLAaPNasFaPPaPQaLAaLzaPRaPRaUnaIOaIOaIPaPTaKraKraPUaPUaPUaPUaPVawGawRaxqaPZaQaaQaaQbaQcaQaaQdaQeaQfawGaQgaPUaPUaPUaPUaKraKraQhaINaIOaIOaBoaQiashaQkaQkaQkaQkasyassasiaQoavXarFdZFaQsaQtaQuaJdaJdaszaQwasBaQyaQzaJjaQAasAaQCaQCaQCaQCascaQEaJjasaarZaQGaHPaPgaPhaHPaHPaQHaEsaQIaQJaQKaEyaQLarpaPraSoaPoasgaIbaQQaQRaEyasfaQTaPtaQUaQVaQWaafaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafatHaxRayVaJMayWaxTaxTayXaJMayVaJMaPxawYaPyaxTaxRaPzaPzaLpaPzaLqatHaPAaLsasDaPBaPBasCatzaPBaPEaPEaPEaPEaPEaPFaPGaPEaPEaPEaPEaPEasEaPIaPJaPIaPKasGaPMaLzaLAaPNasFaPPaPQaLAaLzaPRaPRaUnaIOaIOaIPaPTaKraKraPUaPUaPUaPUaPVawGawRaxqaPZaQaaQaaQbaQcaQaaQdaQeaQfawGaQgaPUaPUaPUaPUaKraKraQhaINaIOaIOaBoaQiashaQkaQkaQkaQkasyassasiaQoavXarFdZFaQsaQtaQuaJdaJdaszaQwasBaQyaQzaJjaQAasAaQCaQCaQCaQCascaQEaJjasaarZaQGaHPaPgaPhaHPaHPaQHaEsaQIaQJaQKaEyaQLarpaPraSoaPoasgaIbaQQaQRaEyasfaEUaPtaQUaQVaQWaafaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawXaQXaxTaQYaPyaxTaxTaQZaQYaxTaQXaPyaxTaxTaxTaRaaRbaRbaRbaRbaRbaRbaRbaRcatUaPBaReaufaFvautaumaRjaRkaRlaRmaRnaRoaRpaukaRraRsaRtaujaRvaRwaxIaPKatwaPMaPMaRzaPMaugaPSaPSaRBaRCaPSaPSaPSaRDaIOaIPaREaaaaaaaaaaaaaaaaaaaaaaPWaRFaRGaRHaRIaRJaRKaRJaRLaRMaRNaROaPWaaaaaaaaaaaaaaaaaaaaaaRPaINaIOauZaRRaRSatDaQoaQoaQoaQoaQoaRUatGaQoaQoaQoaQraMpaRWaRXaRYaRZatxaSbatyaSdaSeaJdaPbatCaSgaSgaSgaSgatTaSiaJjasIarZaSjaSjaPgaPhaSkaSkaSlaEsaEsaSmaEsaEyaLhatZaulaulaulatNaTJaEyaEyaEyaSpaSqaSraSsaStaSuaafaafaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaxRaSvaSwaSvaSvaSvaSvaSvaSvaSwaSvaSvaSxaxTaxTaSyaxTaxTaSzaxTaSAaSBaSCaSDatuaPBaReattbeRaPEaSHaRnaRnaRnaRnaRnaRoaSIaRnaRnaRnaRtasEaSJaSKauRaPKatwaPMaSMaSNaupatvaPSasnaSRaSSaSTaSUaSVaIOaIOaIPaREaaaaaaaaaaaaaPWaPWaPWaPWaSWaSXaSYaSZaTaaTbaTcaTdaTeaTfaTgaPWaPWaPWaPWaaaaaaaaaaaaaRPaINaIOaIOaThaQoatnaTjaTkaQoaTlaTmaCIatqaToaTkaQoaQraMpaTpaRXaTqaTratraTtatsaTvaRXaTwaTxaTyaSgaTzaTAaSgaTBaPbaJjasIarZaQGaHPaPgaPhaHPaHPaHPaTCaTDaHPaTEaEyarDastaSoaSoaSoasgaIbaIbaEyaTKaSsaSsaSsaSsaStaTLaTMaTMaTNaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasSasSaTOaTPaTPaTPaTPaTPaTPaTPazYasSatHaTQaTRaTSaTSaTSaFuaTSaTSaTSaBgaTSaBgaPBaReattbeRaPEaTXaRnaRnaTYaTZaUaaUbaTYaRnaRnaRnaUcasEaUdaUeaUfaPKaFkaPMaUhaUiaUjaFpaPSaUlaSUaSUaSSaSUaUmaIOaIOaIPaKqaPVaUnaUoaPWaPWaUpaUqaUraUsaUtaUtaUuaUvaUtaUuaUvaUtaUwaUxaUyaUzaUAaPWaPWaUoaUnaUBaUCaINaIOaIOaBoaUDatnaToaTkaQoaUEaUFaQoaFjaUHaTkaQoaQraMpaUIaRXaUJaFzaFyaUMaFxaUOaRXaUPaUQaURaSgaUSaUTaSgaUUaUVaJjasIarZaUWaUWaPgaPhaUXaHPaHPaUYaHPaUZaVaaEyaIbaTGaTHaSoaTGaFwaQqaVfaEyaVgaSsaSsaSsaSsaSsaVhaViaVjaVkaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaafaVmazTaxVaxTaExaEwaEvaEtaEraEXaEWaEVaEUaEPaEIaEAaOqaEqaPEaVBaRnaRnaTYaUaaVCaVDaTYaRnaRnaRnaRtasEaPKaPKaEfaPKaEgaEhaEhaEhaEhaEoaEiaEpaSSaSSaSSaHcaUmaIOaIOaIPaLTaLTaVKaVLaVMaPWaVNaTbaUtaVOaUtaUtaUtaUtaVPaUtaUtaUtaVRaVSaVSaVTaVUaPWaVVaVLaVWaVXaLTaINaIOaIOaThaQoatDaQoaQoaQoaVYaVZaQoaFjaWaaTkaQoaQraMpaWbaRXaWcaWdaWeaWfaFiaUOaWhaJdaPbaURaWiaSgaSgaSgaUUaPbaJjaFharZaEsaEsaFgaPhaWlaWmaHPaWnaWoaKZaFfaFaaymaFdaFeaFcaFdaFbaymaEZaFaaEYaWzaSsaSsaSsaWAaWBaWCaTMaWDaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaWEaWFaWGayWaWHaGlaGzaGqaGBaGAaGDaGCaGEaGqaGGaGFaGIaYCaFXaPEaWVaRnaWWaWXaYdaYAaYBaWYaWYaWYaXaaXbaFYaXdaGcaGbaGaaFZaReaReaXiaPBaGdaPSaIoaIlaHFaHEaHBaHpaIRaIOaIOaIOaIOaXpaXqaXraXsaXtaXuaUtaXvaXwaXxaXyaXzaXAaXBaIWaXDaKUaXFaXtaXGaXHaXIaXJaXKaXLaXMaXNaXOaIOaXPaBoaRSatnaXQaTkaQoaXRaXSaQoaFjaToaTkaQoaQraXTaRWaRXaWcaRXaXUaRXaGJaUOaXWaJdaQAaURaSgaSgaSgaSgaUUaQEaJjaYDaGRaXZaYaaQOaQPaPgaPgaPgaPgaPgaPgaFVaEyaIbaTGaTHaSoaTGaTHaIbasHaEyaSnaSsaSsaSsaSsaYkaYlaYmaafaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaafaVmazTaxVaxTaExaEwaEvaEtaEraEXaEWaEVcrWaEPaEIaEAaOqaEqaPEaVBaRnaRnaTYaUaaVCaVDaTYaRnaRnaRnaRtasEaPKaPKaEfaPKaEgaEhaEhaEhaEhaEoaEiaEpaSSaSSaSSaHcaUmaIOaIOaIPaLTaLTaVKaVLaVMaPWaVNaTbaUtaVOaUtaUtaUtaUtaVPaUtaUtaUtaVRaVSaVSaVTaVUaPWaVVaVLaVWaVXaLTaINaIOaIOaThaQoatDaQoaQoaQoaVYaVZaQoaFjaWaaTkaQoaQraMpaWbaRXaWcaWdaWeaWfaFiaUOaWhaJdaPbaURaWiaSgaSgaSgaUUaPbaJjaFharZaEsaEsaFgaPhaWlaWmaHPaWnaWoaKZaFfaFaaymaFdaFeaFcaFdaFbaymaEZaFaaEYaWzaSsaSsaSsaWAaWBaWCaTMaWDaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaWEaWFaWGayWaWHaGlaGzdcxaGBaGAaGDaGCaGEaGqaGGaGFaGIaYCaFXaPEaWVaRnaWWaWXaYdaYAaYBaWYaWYaWYaXaaXbaFYaXdaGcaGbaGaaFZaReaReaXiaPBaGdaPSaIoaIlaHFaHEaHBaHpaIRaIOaIOaIOaIOaXpaXqaXraXsaXtaXuaUtaXvaXwaXxaXyaXzaXAaXBaIWaXDaKUaXFaXtaXGaXHaXIaXJaXKaXLaXMaXNaXOaIOaXPaBoaRSatnaXQaTkaQoaXRaXSaQoaFjaToaTkaQoaQraXTaRWaRXaWcaRXaXUaRXaGJaUOaXWaJdaQAaURaSgaSgaSgaSgaUUaQEaJjaYDaGRaXZaYaaQOaQPaPgaPgaPgaPgaPgaPgaFVaEyaIbaTGaTHaSoaTGaTHaIbasHaEyaSnaSsaSsaSsaSsaYkaYlaYmaafaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaYnavtaYnaxTaYoaBgaYpaYqaYraYraYraYraYsaYtaTSaYuaYvaOlaCSaYyaYyaYyaYzaYyaOsaRnaTWaUKaWZaWZaPDaSGaFOaFPaFEaFDaFJaFFaFAaIgaFCaFBaFLaFKaFMaYSaYSaYSaYTaUnaHhaIOaYVaYWaYXaYYaYZaZaaPWaHkaHiaZeaZfaPWaPWaPWaPWaPWaPWaPWaPWaPWaHeaXwaZkaZlaPWaZaaYZaZmaGTaYWaZoaIOaIOaThaQoaZpaQoaQoaQoaFHaQoaQoaFUaQoaZraZraZraZraZsaZtaKAaRXaRXaRXaZvaZwaZxaJdaZyaZzaSgaZAaZAaZBaZzaZCaJjaFWaBDaZFaZGaPgaPgaPgaPgaZHaPgaPgaPgaFVawKaIbaPoaPraSoaPoaPraIbasHawKaYjaSsaSsaZJaSsaSsaZKaYmaafaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaZLaZMaWGayWaZNaBWaZPaZQaZRaZSaZTaYraZUaZVaTSaZWbaEaOlaCSaZYaZZbaaaCLaYybacbadbaeaPEbafbagbahaOnaPEaCRaBtbalbalbalbalaHubalbalbanbaobaobaobapbaobaqaUnbasbatbauawGawGawGbaAaFTbaAbayaFQbaybaAbaBbaBbaBbaBbaBbaBbaBbaBbaBaCVbaDbbubaDaPWaPWaPWawGawGawGaZoaIOaIOaUnbaFbaGaBlbaHaQobaIaQobaJbaKbaLaZrbaMaFRbaOaJdaJdaJdbaPbaQbaQbaQaJdaJdaJdbaRaSgaSgaLeaFNbaUbaVaGwaJjaBEaBDbaYaEsbaZbbabbbaWmbbcbbabbdaWmbbeaEybbfaQMaQNbbgaQMaQNaIbbbhaEyaDkbbjbbkaSsaSsbblbbmaYmaafaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaafaxRbbnaPybboaBgbbpbbpbbqaAMbbsbbqbbtbbpaTSaQpaOTaGHaByaBzaBzaBAaBBaBzbbBbadbbCaPEbafbagbbDaGPaPEaBxbfabalbbGbbHbbHazqbbIbalbbJbbKbbLbbMbarbarbaraUnaIOaIOaYVawGbbPbbQbbRbbSaBRaFraFlbbWbaAbaBbbXbbYbbZbcaaBhbccbcdbaBaCVbcebcfbcgbchbcibcjaAVbdsawGbcmbcnbcnaUnbcqbcqaBoaBobcoaThbcobcpaBoaBoaRRaBoaBoaBobcqbcrbcrbcrbcrbcrbcrbcsbcrbcqazGbctbctaCKaZFaZFaZFaZFbcqaBEaBDbaYaEsaEsaEsaEsaEsarZaEsaEsaEsaEsaEyaBCbcAawKavUawKbcybcAaEyaEybcBaSsbcCaSsaSsaWAbcDbcEaTMaWDaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaafaxRbbnaPybboaBgbbpbbpcoCaAMbbsbbqbbtbbpaTSaQpaOTaGHaByaBzaBzaBAaBBaBzbbBbadbbCaPEbafbagbbDaGPaPEaBxbfabalbbGbbHbbHazqbbIbalbbJbbKbbLbbMbarbarbaraUnaIOaIOaYVawGbbPbbQbbRbbSaBRaFraFlbbWbaAbaBbbXbbYbbZbcaaBhbccbcdbaBaCVbcebcfbcgbchbcibcjaAVbdsawGbcmbcnbcnaUnbcqbcqaBoaBobcoaThbcobcpaBoaBoaRRaBoaBoaBobcqbcrbcrbcrbcrbcrbcrbcsbcrbcqazGbctbctaCKaZFaZFaZFaZFbcqaBEaBDbaYaEsaEsaEsaEsaEsarZaEsaEsaEsaEsaEyaBCbcAawKavUawKbcybcAaEyaEybcBaSsbcCaSsaSsaWAbcDbcEaTMaWDaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazQasSbcFaAFaWGatHatHatHatHatHatHbcGbboaBgaTSaTSaTSaTSaTSaTSaTSaTSaTSbcHaReaOlaCSaZYbcIbcJbcKaYybcLbcMaDEaPEbafbagbcOaOpaPEaBxbfabalbbHbcQbcQbbHbcQbalbbJbcRbcSbcSbcTbcUbcVbarbcWaIOaYVaGpbcYbgCbdabdbbdbbdaaGibddbaAbaBbdebdfbdgbdhbdibdjbdkaGYaHabdnbdobclbdpbdqbdrbclaLgawGaZobdtaIOaNsbdubdvaZFaZFaZFaZFaZFaZFaZFbdwaZFaZFaZFaZFbdxaZFaZFaZFaZFaZFaZFaZFaZFbdyaZFaZFaZFaZFaZFaZFaZFaZFbdzaDPaDTaCYaDUaCYaDVaCYaDXaDWaDYaCYaDZaCYaEaaEbaCYaCYaCYaCYaCYaCYaEcaEdaEebdObcCaSsaSsaSsaVkbdPaVjaVkaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaaaaafbdRazTaxVbdSaCTbdUbdUbdUbdUbdUbdUbdVbdWaPBaXiaReaOlaCSaYyaYybdXbdYaYyaPEaPEaCUaPEbafbeabcOaOoaPEbfbaFSbalbecbedbbHbcQbeebalbbJbefbcSbcSbcSbegbehbarbeiaIOaYVaGkbekbgCbembenbeobepaGibeqbaAbaBberbesbetbetbetbeubevbaBaCVbexbclbclbdpbeybdrbclaLfawGbeAaIOaIOaNsbdubdvaZFaZFaZFaZFaZFaZFaZFbeBaZFaZFaZFaZFaZFaZFbeCaCYaCYaCYaCYaCYaCYaCZaCYaCYaCYaCYaCYaCYaCYaDlaDDaDCaDtaZFaZFaZFaZFaZFaBDaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbeIbdzbeJaSsaSsbcCaSsaSsbeKbeLaTMaTMaTNaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaWEaWFbeMayWbeNbUVbePbePbeQbePbePbePbeRaPBaPBaPBaPBaOlaCSaZYbeSbeTbeUaYybeVbeWbUWaPEaPEaPEaPEbUmaPEbUybfabalbUqbbHbcQbUibUkbalbbJbarbfcbcSbcSbPhbfebarbULaIOaYVbTrbfhbgCbembfibfjbepaGibfkbaAbflbfmbfnbetbfobetbdfbfpbfqaCVbfrbfsbftbfubfubfvbclbfwawGcuRcuSaXNcvvcxRdPwdPxdTPdPxdPxdPxdPxdTQbTtdTSctbctbctaaZFaZFaZFaZFbfDaZFbfybfOaZFctcctectdbfIbWUbfIbfIbfKdTUdTVdTWaZFaZFaZFaZFaZFbfObfPbfDaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbdzbfQbfRbfSbfTbfUbfVbbmbfWaafaaaaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11006,14 +11012,14 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaeaaaaaaaaabowbowbowbowbowbowbowbusbutbusbuublpblpblpbrybrybrybryboAblpbuvbuwbalbuxbcSbndboCbuybuzbtcbOxbuBbqfbuCbuDbuEbpcbuFbtgbuGbuHbuIbuJbOmbMfboMbOpbOobNBbOnbuRbrSbuRbOvbOwbuTbuTbNqbuUbuVbuWbuXbuYbuZbMkawGbvcaIOaIOawGbLSbMnbMrbMBbMSbMTbMUbnebMLbMPbMQbMRbNabMZbNcbNbbApbHvbMYbMWbNlbNkbNGbNobNfbNebNibNhbMjbMlbMhbMibiSbvybvzbMgbvBbvBbkBbvCbvDbvEbkBbNVbkCbvGbvHbvIbvJbOebvLbvMbOfbvObvPbvQbsIbkJbvRbvSbvTbvUbvVbvVbvVbvVbvWbvXbpObMebvYbMebpObvZaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbwabrvbwbbwcblpblpblpblpblpblpblpboAblpbuvbwdbalbwebegbndbncbqfbwgbqfbNFbcSbrFbRdbffaIObpcbuFbtgboMbwibwjbwkbwlbMdboMbwpbwnbHhbzzbNgbNjbNmbNnbwubGIbwwbNqbGCbwybwzbwAbwBbwBbnTbINbambdDaIRbgUbLQbLRbLNbLPbeZbixbLYbLZbLDbLXbLVbLWbFNbLDbLAbLzbDcbDcbDcbDcbDcbHfbIIbHfbAqbLJbLGbAqbAqbAqbAqbLybiSbiSbxbbxbbxbbxbbkBbkBbkBbkBbkBbMMbxebxfbxgbxhbxibMobMpbMpbMqbxmbojbxnbxobxpbvRbojbvTbxqbojbxrbojbxsbkIbupbuqburbxtbkIaaaaaaaafaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbusbutbusbxubxvblpblpbxwbSRbSSbSRbSXbSRbSYbTabSTbSUbSVbzmbFnbSWbTcbTdbSVbxFbxGbRgbffaIObxHbxIbxJboMbxKbxLbxMbxNbSdbRzbXwbSfbRUbRJbSubSvbSsbStbSkbSrbSebShbybbycbycbydbyebyfbQEbtvcbPbDNbONbgUbixcbQcciccjcarcawcaWcbabPucbccbecbOcdabPucdkbWubRSceEceJceFbDccckccFccEbAqbSCbTsbRebRvbAybAqbwNbRybRBbRwbRxbRpbRpbRibRmbRpbRtbRrbRsbREbRDbRpbRCbQubSPbyPbyQbSLbySbySbySbySbySbyTbyUbyVbupburbkIbojbvVbyWbyXbyYbyZbzabzbaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbzcbzdbzcbzebzfbzgbzgbzgbzgbzgbzhbPLblpbuvbzjbalbzkbOXbsZbwfbzoboEbRZbzqbzrbarbarbzsaIObztbzubtgboMbzvbzwbzxbwjbQTboMbRGbRAbRHbOpbQwbzEbQDbuTbQvbzIbzJbNqbzKbzLbzMbzNbyebyfbQEbtvbpcbDNbNwbOHbOLbOMbOJbOKbEpbXtbXrbXsbLDbLDbLDbXubWzbLDbWybWubXqbXpbXobOSbDcbNvbVRbVQbWtbRcbQUbQKbRjbQabYcbrBbYObZMbZNbZObvMbvMbArbvMbAsbvMbOfbQqbQqbQqbQsbQrbQtbAvbAwbAxbRTbAzbAAbABbACbySbADbAEbAFaafaafbkIbAGbvVbyXbyXbvWbAHbAIbAJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbzcbzdbzcbzebzfbzgbzgbzgbzgbzgbzhbPLblpbuvbzjbalbzkbOXbsZbwfbzoboEbRZbzqbzrbarbarbzsaIObztbzubtgboMbzvbzwdYBbwjbQTboMbRGbRAbRHbOpbQwbzEbQDbuTbQvbzIbzJbNqbzKbzLbzMbzNbyebyfbQEbtvbpcbDNbNwbOHbOLbOMbOJbOKbEpbXtbXrbXsbLDbLDbLDbXubWzbLDbWybWubXqbXpbXobOSbDcbNvbVRbVQbWtbRcbQUbQKbRjbQabYcbrBbYObZMbZNbZObvMbvMbArbvMbAsbvMbOfbQqbQqbQqbQsbQrbQtbAvbAwbAxbRTbAzbAAbABbACbySbADbAEbAFaafaafbkIbAGbvVbyXbyXbvWbAHbAIbAJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbAKbALbAMbalbalbANbrvbrvbrvbAObalbalbAPbAQbARbalbASbASbASbRKbASbAUbRLbAWbAXbAYbAUbffaIObAZbBaaUnboMawGawGawGawGbQlboMbOpbQObOpbQmbQnbQobQnbuTbuTbuTbuTbNqawGawGawGawGawGbtvbPobtvbpcbVabuDbVbbUSbQkbUUbUZbUdbUfbUgbrAbTFbTGbUbbUcbVKbVJbVMbVLbVxbVwbVIbVCbQcbVpbVvbVtbVmbPTbQbbQabOQbPEbAqbSKbSJbzCbzCbzCbzCbzCbQjbzCbzCbELbQhbQiblTblTbBUbKjbOqbBWbAwbBXbQZbBZbCabCbbCcbySbADbAEbCdaaaaaabkIbCebCfbkIbvWbkIbkIbvWbkIaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabCgaafaaaaaaaaaaaabASbChbNpbQRbCkbAUbQQbCmbCnbCobAUbffaIObQMbQLbQNbQLbPzbPebPIbPFbPNbPJbQfbQPaXNbCzbCAbCBbCCbCDbCEaIOaMibDbaMjaNsbCubCGbCHaCzbPdaIObpcbDNbSHbymbymbSBbSBbSBbymbymbSmbSxbRXbSibScbSgbRYbRXbRWbRVbRSbRRbRQbRPbDcbRObRNbRMbRIbOtbOrbAybAgbNrbAqbRkbCTbzCbPbbPcbFUbOWbOZbPabOObELbOPbOTbIZblTblTbQdbOqbBWbDubDvbPXbDxbDybDzbDAbySbADbDBbyVbyVbyVbyVbyVbkIbkIaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabASbDCbDDbDmbDFbDGbDnbDIbDlbDKbAUbffbDLbDiaIOaIOaIObDbaNsbCubCGbDNaIOaIObDdaIOaIObDPbDQbDRaIOaIOaIOaIObDbaIOaNsbCubCGbDSaXNbDYaXNbFrbENbDZbymbEbbBxbBxbBxbEebEdbEgbEfbEibEhbzGbEjbCUbCYbCZbDabDcbDebDfbDgbDcbDhbDkbDwbDEbAgbCQbCRbAgbAgbAqbksbCTbzCbEqbEobEybEtbEsbErbEMbELbEBbEzbEmbEmblTbDqbEnbECbEDbEEbEFbDzbDtbEHbEIbySbADbAEbyVbEJbEKbFsbyVaafaafaafaafaafaafaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbEPbEQbEQbFgbtybtybjBbjBbjBbjBbEOaafaafaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowaaaaaaaaaaaaaaaaaaaaaaaabERbESbBTbESbEUaaaaaaaaabASbASbEVbEWbDmbEWbEXbEYbEZbFdbFbbAUbFcbffbEwbFebuDbFfbFybFAbFhbFibuEaIObFjbEuaZjbEvbFaaIObDSaXNaXNaXNaXNbDWbjvbFobFpbFqbFrbFCbFJbFHbuDbuEaIObymbFmbBxbFlbETbBxbEdbFubFtbFzbFxbFwbFvbFEbFFbFBbFDbFKbFQbFGbDcbDcbHfbHfbHfbAqbEGbExbEAbElbEkbAqbksbCTbzCbFRbFPbFUbFTbFWbFVbFXbELbFYbEzbEmbEmblTbFIbFZbFLbFMbyHbFObGabFSbGebGfbySbGbbxZbxZbxZbxZbVNbAFaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbGjbmNbGhbmNbtybjBbjBbjSbmLbjSbjBbjBaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGpbGqbGrbGqbGpbGsbGtbGubASbGvbEWbGwbBbbGybGzbGAbGAbBcbuSbAUbGDbGDbBibGDaUnaUnaUnaUnaUnaUnaUnbGFbGFbGFbGFaUnbBgbBfbBeaUnbGHbGHbGHbBhbAfaUnaUnaUnaUnbAVbAubGKaIUaKtbzYbymbzXbBxbBxbBxbAebAcbApbAobzGbzZbAbbAabvxbzGbzObzPbyzbyAbyCbvwbzTbzUbEcbAgbAgbAgbAtbAybATbAgbAqbksbhQbhQbhQbhQbhQbhQbhQbhQbhQbhQbBRbBQbBqbBqblTbBnbBdbHqbjfbjfbjfbjfbBObBPbBNbjfbjfbjfbjfbjfbAEbADbHxaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagbxXbmNbmNbtnbjBbjBbjSbjSbBSbjSbjSbjBbjBaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBTbHBbHCbHBbBTbHDbHEbHFbASbHGbHHbEWbHIbHJbAUbHKbHLbBrbHNbAUbHObHObBBbGDaaaaaaaaaaaabGFbBvbHRbvAbHTbHUbHVbCtbBVbHXbBYbCtbHZbCjbCpbClbBGbBDbBKbBJbBMbCvbCwbzlbBobGKbGKbymbBmbBlbBlbBkbymbBCbBybBwbBubBtbBsbBpbCsbCybCqbCrbBHbBIbBEbBFbCNbCObFkbCIbBLbCFbBjbAgbAgbCJbAqbksbhQbCxbCxbCxbCPbCMbCxbCxbCxbhQbCLbCKbDpbDpblTbwxbCVbBWbCXbDjbDMbDObDTbDUbDrbDsbDHbDJbDXbjfbyVbDVbyVbngbngbngbngbngaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabxYbjBbxXbjBbjBbjSbjSbjSbjSbjSbjSbjSbjBbjBaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGpbHBbHBbHBbJdbJebEWbEWbJfbJgbEWbEWbJhbJibAUbAUbAUbJRbAUbAUbJvbJlbJDbJnaaabJCbJpbJBbJrbJsbHVbJtbJubJPbJKbJbbJybJxbJwbJbbCSbJobJEbJFbJGbJHbJIbGHbGHbJJbJcbDobJQbJNbJUbJSbJZbJWbJWbJWbIDbICbJabIFbzGbJjbJMbJLbIxbzGbIybIzbEcbIAbIBbIBbIubIvbEcbAqbIwbAqbAqbAqbAqbAqbAqbksbhQbKFbKvbCxbCxbCxbCxbCxbKubhQbKtbEzbKpbKpblTbKjbKsbKrbKqbKgbKgbKgbKgbKhbIYbIYbKibKobJYbjfbKfbKdbJTbJObJXbJVbJAbJzaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbtybjBbptbpubpubjSbjSbjSbjSbjSbjSbjSbjSbjBbjBaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGpbHBbHBbHBbJdbJebEWbEWbJfbJgbEWbEWbJhbJibAUbAUbAUbJRbAUbAUbJvbJlbJDbJnaaabJCbJpbJBbJrbJsbHVbJtbJubJPbJKbJbbJybJxbJwbJbbCSbJobJEbJFbJGbJHbJIbGHbGHbJJbJcbDobJQbJNbJUbJSbJZbJWbJWbJWbIDbICbJabIFbzGbJjbJMbJLbIxbzGbIybIzbEcbIAdXpbIBbIubIvbEcbAqbIwbAqbAqbAqbAqbAqbAqbksbhQbKFbKvbCxbCxbCxbCxbCxbKubhQbKtbEzbKpbKpblTbKjbKsbKrbKqbKgbKgbKgbKgbKhbIYbIYbKibKobJYbjfbKfbKdbJTbJObJXbJVbJAbJzaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbtybjBbptbpubpubjSbjSbjSbjSbjSbjSbjSbjSbjBbjBaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBTbHCbHCbHCbBTbKKbKLbKMbKNbKObEWbKPbLsbltbLibKVbKVbKZbKWbKVbKDbjwbKQbKYaaabGLbLabLbbLcbLdbHVbLebLfbLgbLhbCtbKHbKGbKRbCtbLlbLmbLnbLobLpbLqbLrbKUboNbKSbKIbGKbPybPybKnbymbFmbBxbFlbETbBxbHcbKcbFtbKmbKlbKkbKebKBbKCbGXbGYbLxbIAbIBbIBbIubKxbEcbKwbKzbKAbmobKybKbbKabkybksbhQbCxbLEbCxbCxbCxbCxbCxbCxbhQbLCbEzbHPbHPblTbLObojbBWbMabIYbIYbLFbLHbLIbLKbIYbLLbLMbLBbLwbLvbLubLtbLjbKXbKTbJAbKJaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabjBbjBbkQbjSbjSbjSbjSbjSbjSbjSbjSbjSbjSbjSbjBbjBaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaabGpbMwbMxbMybGpbMzbGtbGubASbASbMAbMAbMAbASbASbGDbJkbJkbGibJkbJkbJkblPbKYaaabGLbMDbMEbMFbMGbMHbMIbMJbMGbMGbMKbGBbGlbGkbGHbGHbGHbGHbGHbGHbMObGHbGHbyKbGGbGmbGKbPycpqasZbymbEbbBxbBxbBxbHdbHcbApbFtbHabGZbHbbBtbGVbGWbGXbGYbGRbGSbGTbGUbGNbGObEcbGPbGcbGdbmobGgbHgbHebkybksbhQbhQbIpbCxbCxbCxbCxbhQbhQbhQbIobHYbHPbHPblTbHQbojbBWbCXbHAbHybHzbHtbHubHrbHsbHnbHpbGEbGxbGMbGJbGQbngbHlbHkbGobGnaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbjBbjSbjSbjSbjSbjSbjSbjXbjSbHmbjSbjSbjSbjSbjSbjBbjBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNObESbNPbESbNQaaaaafaaaaaabASbNRbNSbNTbASaaabGDccpcbybzibJkbJkbJkblPbKYaaabGLbNWbNXbNYbNZbHVbOabObbOcbOdbGFbIabIqbIcbIbbIdbIdbIdbIdbIdbIdbItbIdbIebIebIEbGKbGKbGKbGKbymbymbHwbHMbHwbymbymbHvbHobHjbHibzGbBubCUbInbIlbImbEcbIkbEcbEcbEcbEcbEcbIjbIfbBAbmobHSbIsbCibkybksbhQbIMbIVbIUbIRbIQbITbISbIMblUbIPbIObIZblTblTbJmbojbOVbngbngbjfbjfbjfbjfbIWbjfbIXbIYbIHbjfbIhbCWbyVbngbIKbIJbIGbngaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabjBbulbulbulbulbulbulbILbjSbuPbulbHmbjSbjSbjSbjSbjBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -11028,7 +11034,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaafaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbSFbSGcnjcngcnhcnQbSFcrKcrFcrwcrvcrEcrCcrrcrrcrucnEcnEcnDcnFbAkbYpbjqbjxcnCbwMcnzctfcnBcnwcnxcnybfNbtVcnpcnqdTTbfNbkjbqZdZLdZOdZOdZMdZNbqZdYtdZPdZQbiDdZTdZRdZSdZHbiDdZGbtBcrVbwUbxPbtKbxQbiKdZKdZJbiKcrXbPwbiddZUbssdZVdZWbidbfMdWwdXGbGKaaaaafaaaaaaaafaaaaaaaaaaaaccBcrZcslcskccBaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYUbYUcoebYWbYUaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcrLbEQbEQbFgbtybtybjBbjBbjBbjBbEOaafaafaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaaaaafaafaafbTebTebTebTebTebTebTebTebTebTebTebTebTeaaaaaacmobSGbSGbSGbSGcmAbSFcqicqgcqfcqecqdcpVcqccpVcpUcpTcpScpQcpOcpLcqjcqwcmCcqMbgXbgXbgXbgXbgXbgXbgXbfNbfNcmBbfNbfNbfNbkjbqZbqZdZrdZsdZtdZubqZcqxcqDcqTbiDbkdbiDbiDbiDbiDbwUdZydZzbwUcqXcqWcqXbiKbXLdZBbiKbPybPybiddZDbssbidbidbidbfMcpWcmNbGKaaaaafaaaaaaaafaaaaaeaaaaaacrfcbWcrpcoBcrfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYUcqQcmGbZVbYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaaaaaaaaaaaabTecnScqacnSbTecnOcpYcnObTecnMcpZcnMbTeaaaaaacphbSGcpXbSGbSGcpRbSFcFVcFUcQKcFXcRqcRpcFMcFKcFRbqVbqVcFTbqVbqKcFIcFJbjxcpCcpDcpucpucpEcpucpucoMcpvcpwcpxcpyeaqcoMbkjbEaeaxbMXbMXeaveaweaDeaEdLbdPueazeaAeayeaeeaeeaudXBbwUbwUbwUdhOcZLdyNbiKbiKbiKbiKbPybPybidbssbsseareasbidbfMbGKbGKbGKaaaaafaaaaaaaafaaaaaaaaaaaacWzcWQcRYcRScWzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYUcaycqbcaAbYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaaaaaaaaaaaabTecnScnRcnSbTecnOcnPcnObTecnMcnNcnMbTeaaaaaacphbSGbSGbSGcpicoIcoHcsOcsNcvgcuVcsWcsPcsMcsEcsmcoycoEcoDcoCbAkbYpcpdcpbcpccpgcpfcpecpfcoOcoWcoMcoNcoZcpacoXdZZcoMbkjbEaeabbMXbOsbMXeaaeageahcCNeajeaceadeaeeafeaeeandXBciZboNcDacEycExcFHcFGboNboNboNboNcEzbidbidbidbidbidbidbfMbGKaafaafaafcbfaafaafaafaafaafaafaafccQbudcCKcylccQaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYUcbjcpjcblbYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaaaaaaaaaaaabTecnScnRcnSbTecnOcnPcnObTecnMcnNcnMbTeaaaaaacphbSGbSGbSGcpicoIcoHcsOcsNcvgcuVcsWcsPcsMcsEcsmcoycoEcoDdYCbAkbYpcpdcpbcpccpgcpfcpecpfcoOcoWcoMcoNcoZcpacoXdZZcoMbkjbEaeabbMXbOsbMXeaaeageahcCNeajeaceadeaeeafeaeeandXBciZboNcDacEycExcFHcFGboNboNboNboNcEzbidbidbidbidbidbidbfMbGKaafaafaafcbfaafaafaafaafaafaafaafccQbudcCKcylccQaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYUcbjcpjcblbYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaaaaaaaaaaaabTecrgcnicrebTecrccnfcrbbTecracnccqZbTeaaaaafcphcrdbSGbSGcqqbWbbSFdPYdPVcvgcvgdPTcvgcvgcvgcvgcrzbYpcrxcrybAkbYpdRPcrlbyOcrhcricrkcricrocrqcrscrtcrmcrncoMcoMcoMbkjbEaeboebrebsebpebqebiebjdQhebhebmebnebkeblebcebbebadQabJNebfdQedQddPZbCTbyDbXPbXQbGKbvKboNboNboNboNboNboNciNbGKaaaaaaaaaaafaaaaaaaafaaaaaaaaaaaabuddQidQSdQRbudaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaacbZccacrNcccccdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalQaaaaaaaafaafbTecqocdMcqpbTecdWcdMcdXbTecdLcdMcdNbTeaaaaafcqrbSGbSGbSIcqqcqybSFdPAdPvcqvcqucqtcqscqAcqAcqAcqBcqAcmpcqzbAkbAkbjqcqIcqJcpDcqCcqCcqHcqPdaWcoMcqOcYGcqNcqKcqLcoMbkjbEaeaLeaMeaNeaOeaPbEaeaFdPDeaHdXBeaIeaJeaKeaSeaRdXBbfMbPydXFeaUeaTeaQdXFaaaaaaaaabGKbGKbGKbXObXPbXPbXQbGKbGKbGKaaaaaaaaabudbudbudbudbudbudbudbudbuddPHdPSdPPbudaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaafccScqYccSaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachdaafaafaafaaaaafcsLaafcsLaafcdmaafcdlaafcdmaafcdlaafaafaaabSFcsKbUXcsIdbicszbQGcsBcsAbQGcsCcsDcmJcmJdTDcmJchBcsGcsFchBcsHcstcsucsvcswcaOcaOcaOcaOcsxcsycaOcjXcjXcjXcjXcjXcjXbkjbEaebRebPebQebNebObEaeaFdTLebMdXBebKebIebJebHebGdXBbfMbPydXFebFebEcnsdXFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaabudcnbcmXcmYdTJdTKcdydTHcfcdTIdTFdTEdTGcrHaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaafcebceccebaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa From 9096e61ad1754f02464de07f672317a2c7d55c0f Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Mon, 23 Jun 2014 00:19:50 -0700 Subject: [PATCH 11/25] DME fix --- baystation12.dme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baystation12.dme b/baystation12.dme index ddbd5a3e5b..2068f9ff37 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1384,5 +1384,5 @@ #include "code\ZAS\Zone.dm" #include "interface\interface.dm" #include "interface\skin.dmf" -#include "maps\test2.dmm" +#include "maps\tgstation2.dmm" // END_INCLUDE From d8ef1647a733f2e1fed1deaef6741e81a08cb1a3 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Mon, 23 Jun 2014 01:54:03 -0700 Subject: [PATCH 12/25] Forgot to commit welcome.dm --- .../computer3/computers/welcome.dm | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 code/WorkInProgress/computer3/computers/welcome.dm diff --git a/code/WorkInProgress/computer3/computers/welcome.dm b/code/WorkInProgress/computer3/computers/welcome.dm new file mode 100644 index 0000000000..11695ce532 --- /dev/null +++ b/code/WorkInProgress/computer3/computers/welcome.dm @@ -0,0 +1,34 @@ +/obj/machinery/computer3/laptop/vended + default_prog = /datum/file/program/welcome + + +/datum/file/program/welcome + name = "Welcome Screen" + desc = "First time boot splash screen" + active_state = "osod" + image = 'icons/ntos/program.png' + + + interact() + usr.set_machine(src) + if(!interactable()) + return + var/dat = "" + dat += "
Welcome to NTOS
" + dat += "
Thank you for choosing NTOS, your gateway to the future of mobile computing technology, sponsored by Nanotrasen (R)

" + dat += "Getting started with NTOS:
" + dat += "To leave a current program, click the X button in the top right corner of the window. This will return you to the NTOS desktop. \ + From the desktop, you can open the hard drive, usually located in the top left corner to access all the programs installed on your computer. \ + When you rented your laptop, you were supplied with programs that your Nanotrasen Issued ID has given you access to use. \ + In the event of a serious error, the right click menu will give you the ability to reset your computer. To open and close your laptop, alt-click your device.\ + If you have any questions or technical issues, please contact your local computer technical experts at your local Central Command." + popup.set_content(dat) + popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state)) + popup.open() + return + + Topic(href, href_list) + if(!interactable() || ..(href,href_list)) + return + interact() + return \ No newline at end of file From db6a403c2f69130e328cadc32b631f74f6fae053 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Mon, 23 Jun 2014 02:09:17 -0700 Subject: [PATCH 13/25] uses get_turf instead of get_turf_loc now --- code/WorkInProgress/computer3/computers/prisoner.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/WorkInProgress/computer3/computers/prisoner.dm b/code/WorkInProgress/computer3/computers/prisoner.dm index 51beec5c03..3ec29a5480 100644 --- a/code/WorkInProgress/computer3/computers/prisoner.dm +++ b/code/WorkInProgress/computer3/computers/prisoner.dm @@ -44,7 +44,7 @@ var/loc_display = "Unknown" var/mob/living/carbon/M = T.imp_in if(M.z == 1 && !istype(M.loc, /turf/space)) - var/turf/mob_loc = get_turf_loc(M) + var/turf/mob_loc = get_turf(M) loc_display = mob_loc.loc if(T.malfunction) loc_display = pick(teleportlocs) From c007b013d0a63d858f85861add83ec433023b612 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Mon, 23 Jun 2014 14:43:43 -0700 Subject: [PATCH 14/25] Clicking the magnetic card slot option on the desktop will eject all cards. No more eating cards! --- code/WorkInProgress/computer3/NTOS.dm | 8 ++++++++ code/WorkInProgress/computer3/component.dm | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/code/WorkInProgress/computer3/NTOS.dm b/code/WorkInProgress/computer3/NTOS.dm index b7c2defc4a..0b921ad43b 100644 --- a/code/WorkInProgress/computer3/NTOS.dm +++ b/code/WorkInProgress/computer3/NTOS.dm @@ -186,6 +186,14 @@ interact() return // else ??? + if(istype(C,/obj/item/part/computer/cardslot)) + if(computer.cardslot.reader != null) + computer.cardslot.remove() + if(istype(C,/obj/item/part/computer/cardslot/dual)) + if(computer.cardslot.writer != null) + computer.cardslot.remove(computer.cardslot.writer) + if(computer.cardslot.reader != null) + computer.cardslot.remove(computer.cardslot.reader) interact() return diff --git a/code/WorkInProgress/computer3/component.dm b/code/WorkInProgress/computer3/component.dm index a6965ab9e5..8dc2ec835b 100644 --- a/code/WorkInProgress/computer3/component.dm +++ b/code/WorkInProgress/computer3/component.dm @@ -111,6 +111,8 @@ var/mob/living/carbon/human/user = usr if(istype(user) && !user.get_active_hand()) user.put_in_hands(reader) + else + reader.loc = computer.loc reader = null // Authorizes the user based on the computer's requirements @@ -190,5 +192,7 @@ var/mob/living/carbon/human/user = usr if(ishuman(user) && !user.get_active_hand()) user.put_in_hands(card) + else + card.loc = computer.loc From 0ac199f92d06b68418462935a000418849e60393 Mon Sep 17 00:00:00 2001 From: DJSnapshot Date: Mon, 23 Jun 2014 15:15:53 -0700 Subject: [PATCH 15/25] shuttle controller fix --- .../computer3/computers/communications.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/WorkInProgress/computer3/computers/communications.dm b/code/WorkInProgress/computer3/computers/communications.dm index 23b2540ade..20c29aaec4 100644 --- a/code/WorkInProgress/computer3/computers/communications.dm +++ b/code/WorkInProgress/computer3/computers/communications.dm @@ -124,7 +124,7 @@ return if(authenticated) call_shuttle_proc(usr) - if(emergency_shuttle.online) + if(emergency_shuttle.online()) post_status("shuttle") state = STATE_DEFAULT if("cancelshuttle" in href_list) @@ -269,8 +269,8 @@ proc/main_menu() var/dat = "" if (computer.radio.subspace) - if(emergency_shuttle.online && emergency_shuttle.location==0) - var/timeleft = emergency_shuttle.timeleft() + if(emergency_shuttle.online() && emergency_shuttle.location()) + var/timeleft = emergency_shuttle.estimate_arrival_time() dat += "Emergency shuttle\n
\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]
" refresh = 1 else @@ -286,8 +286,8 @@ dat += "
\[ Restore Backup Routing Data \]" dat += "
\[ Change alert level \]" - if(emergency_shuttle.location==0) - if (emergency_shuttle.online) + if(emergency_shuttle.location()) + if (emergency_shuttle.online()) dat += "
\[ Cancel Shuttle Call \]" else dat += "
\[ Call Emergency Shuttle \]" From 14bf0f064c6ac218ca3379e821473fb547981d5c Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Tue, 24 Jun 2014 10:59:08 +0930 Subject: [PATCH 16/25] Removed ability for drones to talk on Binary. --- code/modules/mob/living/silicon/robot/drone/drone.dm | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 485ff99e3b..a20ebf2e21 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -104,15 +104,8 @@ if(copytext(message,1,2) == "*") return emote(copytext(message,2)) else if(length(message) >= 2) - if(copytext(message, 1 ,3) == ":b" || copytext(message, 1 ,3) == ":B") - if(!is_component_functioning("comms")) - src << "\red Your binary communications component isn't functional." - return - - robot_talk(trim(copytext(message,3))) - - else if(copytext(message, 1 ,3) == ":d" || copytext(message, 1 ,3) == ":D") + if(copytext(message, 1 ,3) == ":d" || copytext(message, 1 ,3) == ":D") if(!is_component_functioning("radio")) src << "\red Your radio transmitter isn't functional." From ef277f1e6b5209e5f22a30d5e75bb4df93b2092f Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Tue, 24 Jun 2014 10:59:57 +0930 Subject: [PATCH 17/25] Added extra bit of info to drone spawn. --- code/modules/mob/living/silicon/robot/drone/drone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index a20ebf2e21..26af79a56e 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -323,7 +323,7 @@ src << "
You are a maintenance drone, a tiny-brained robotic repair machine." src << "You have no individual will, no personality, and no drives or urges other than your laws." src << "Use :b to talk to your fellow synthetics, :d to talk to other drones, and say to speak silently to your nearby fellows." - src << "Remember, you are lawed against interference with the crew." + src << "Remember, you are lawed against interference with the crew. Also remember, you DO NOT take orders from the AI." src << "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets." src << "If a crewmember has noticed you, you are probably breaking your third law." From e27cdb3620527e2b3b699ac257145d93dbab32b1 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Tue, 24 Jun 2014 11:11:55 +0930 Subject: [PATCH 18/25] Fixes #5323 --- code/modules/mob/living/silicon/robot/drone/drone.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 26af79a56e..08758ae8ce 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -60,7 +60,6 @@ //Some tidying-up. flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'" - updatename() updateicon() //Redefining some robot procs... From 4cc0d6b6ee866f4716edd9d035e3ec5a23473007 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Tue, 24 Jun 2014 11:35:08 +0930 Subject: [PATCH 19/25] Fixes #5339 --- code/modules/paperwork/paper_bundle.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index da9a3e150e..0143b595ad 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -61,7 +61,10 @@ usr << browse("", "window=[name]") //Closes the dialog P = src[page] P.attackby(W, user) + + update_icon() + attack_self(usr) //Update the browsed page. add_fingerprint(usr) return From 24730cfd9facb586226f563fd6ef2479efe6e72d Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Tue, 24 Jun 2014 14:11:08 +0930 Subject: [PATCH 20/25] Drones now have plasma cutters instead of emags. --- code/modules/mob/living/silicon/robot/robot_modules.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 5e73996377..5ebaf5df7c 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -306,8 +306,8 @@ src.modules += new /obj/item/weapon/matter_decompiler(src) src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src) - src.emag = new /obj/item/weapon/card/emag(src) - src.emag.name = "Cryptographic Sequencer" + src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src) + src.emag.name = "Plasma Cutter" for(var/T in stacktypes) var/obj/item/stack/sheet/W = new T(src) From 481f3caec50f5237a209693ca76e33542f0ac5fd Mon Sep 17 00:00:00 2001 From: Chinsky Date: Tue, 24 Jun 2014 13:46:15 +0400 Subject: [PATCH 21/25] Moved scooping into a separate helper. --- code/modules/mob/holder.dm | 16 ++++++++++++++++ code/modules/mob/living/carbon/monkey/diona.dm | 10 ++-------- .../mob/living/silicon/robot/drone/drone.dm | 3 +-- .../silicon/robot/drone/drone_abilities.dm | 9 +-------- .../mob/living/simple_animal/friendly/cat.dm | 11 +++-------- 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index f7d495f6ed..d65679d947 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -34,6 +34,22 @@ for(var/mob/living/M in contents) M.show_message(message,m_type) +//Mob procs and vars for scooping up +/mob/living/var/holder_type + +/mob/living/proc/get_scooped(var/mob/living/carbon/grabber) + if(!holder_type) + return + var/obj/item/weapon/holder/H = new holder_type(loc) + src.loc = H + H.name = loc.name + H.attack_hand(grabber) + + grabber << "You scoop up [src]." + src << "[grabber] scoops you up." + grabber.status_flags |= PASSEMOTES + return + //Mob specific holders. /obj/item/weapon/holder/diona diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm index 8e6f10df4b..2469ded956 100644 --- a/code/modules/mob/living/carbon/monkey/diona.dm +++ b/code/modules/mob/living/carbon/monkey/diona.dm @@ -12,6 +12,7 @@ var/ready_evolve = 0 universal_understand = 0 // Dionaea do not need to speak to people universal_speak = 0 // before becoming an adult. Use *chirp. + holder_type = /obj/item/weapon/holder/diona /mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob) @@ -24,14 +25,7 @@ src.verbs -= /mob/living/carbon/monkey/diona/proc/merge src.loc = M else - var/obj/item/weapon/holder/diona/D = new(loc) - src.loc = D - D.name = loc.name - D.attack_hand(M) - M << "You scoop up [src]." - src << "[M] scoops you up." - M.status_flags |= PASSEMOTES - return + get_scooped(M) ..() diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 485ff99e3b..5e49feced3 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -25,8 +25,7 @@ //Used for self-mailing. var/mail_destination = "" - //Used for pulling. - + holder_type = /obj/item/weapon/holder/drone /mob/living/silicon/robot/drone/New() ..() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm index 6ed1259890..2c45af24d1 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm @@ -47,12 +47,5 @@ /mob/living/silicon/robot/drone/attack_hand(mob/living/carbon/human/M as mob) if(M.a_intent == "help") - var/obj/item/weapon/holder/drone/D = new(loc) - src.loc = D - D.attack_hand(M) - M << "You scoop up [src]." - src << "[M] scoops you up." - M.status_flags |= PASSEMOTES - return - + get_scooped(M) ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index a8a9122ef8..1fc3b8fe42 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -21,6 +21,7 @@ min_oxy = 16 //Require atleast 16kPA oxygen minbodytemp = 223 //Below -50 Degrees Celcius maxbodytemp = 323 //Above 50 Degrees Celcius + holder_type = /obj/item/weapon/holder/cat /mob/living/simple_animal/cat/Life() //MICE! @@ -63,18 +64,12 @@ /mob/living/simple_animal/cat/MouseDrop(atom/over_object) - var/mob/living/carbon/human/H = over_object + var/mob/living/carbon/H = over_object if(!istype(H)) return ..() //This REALLY needs to be moved to a general mob proc somewhere. if(H.a_intent == "help") - var/obj/item/weapon/holder/cat/C = new(loc) - src.loc = C - C.name = loc.name - C.attack_hand(H) - H << "You scoop up [src]." - src << "[H] scoops you up." - H.status_flags |= PASSEMOTES + get_scooped(H) return else return ..() From 3ab7e510d5cd3251df147ebc6998666ef3708c91 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 25 Jun 2014 14:34:28 +0930 Subject: [PATCH 22/25] Removed reference to :b in drone spawn text. --- code/modules/mob/living/silicon/robot/drone/drone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 08758ae8ce..55270907ac 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -321,7 +321,7 @@ full_law_reset() src << "
You are a maintenance drone, a tiny-brained robotic repair machine." src << "You have no individual will, no personality, and no drives or urges other than your laws." - src << "Use :b to talk to your fellow synthetics, :d to talk to other drones, and say to speak silently to your nearby fellows." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." src << "Remember, you are lawed against interference with the crew. Also remember, you DO NOT take orders from the AI." src << "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets." src << "If a crewmember has noticed you, you are probably breaking your third law." From 89a450c4f433bf05e2ae65d112aecd17059d1db7 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 25 Jun 2014 16:25:15 +0930 Subject: [PATCH 23/25] Mining tweaks, removal of debug/cruft, balancing of values. --- code/modules/mining/drilling/distribution.dm | 63 +++++++------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/code/modules/mining/drilling/distribution.dm b/code/modules/mining/drilling/distribution.dm index 1fbedca59a..e0aec22db8 100644 --- a/code/modules/mining/drilling/distribution.dm +++ b/code/modules/mining/drilling/distribution.dm @@ -18,10 +18,10 @@ #define MAX_DEEP_COUNT 300 #define ITERATE_BEFORE_FAIL 200 -#define RESOURCE_HIGH_MAX 8 -#define RESOURCE_HIGH_MIN 5 -#define RESOURCE_MID_MAX 4 -#define RESOURCE_MID_MIN 2 +#define RESOURCE_HIGH_MAX 3 +#define RESOURCE_HIGH_MIN 0 +#define RESOURCE_MID_MAX 2 +#define RESOURCE_MID_MIN 1 #define RESOURCE_LOW_MAX 1 #define RESOURCE_LOW_MIN 0 @@ -52,10 +52,6 @@ Deep minerals: var/random_variance_chance = 25 var/random_element = 0.5 -//Called by the drilling rigs each process(). -/datum/ore_distribution/proc/get_ore(var/x,var/y) - return "Nope." - /datum/ore_distribution/proc/map_is_sane() if(!map) return 0 @@ -79,12 +75,13 @@ Deep minerals: //Halfassed diamond-square algorithm with some fuckery since it's a single dimension array. /datum/ore_distribution/proc/populate_distribution_map() - //Seed beginning values. + //Announce it! + world << "Generating resource distribution map." + //Seed beginning values. var/x = 1 var/y = 1 var/size = real_size-1 - map[MAP_TOP_LEFT] = (range/3)+rand(range/5) map[MAP_TOP_RIGHT] = (range/3)+rand(range/5) map[MAP_BOTTOM_LEFT] = (range/3)+rand(range/5) @@ -131,11 +128,16 @@ Deep minerals: /datum/ore_distribution/proc/apply_to_asteroid() - var/origin_x = 13 - var/origin_y = 32 - var/limit_x = 217 - var/limit_y = 223 - var/asteroid_z = 5 + // THESE VALUES DETERMINE THE AREA THAT THE DISTRIBUTION MAP IS APPLIED TO. + // IF YOU DO NOT RUN OFFICIAL BAYCODE ASTEROID MAP YOU NEED TO CHANGE THEM. + // ORIGIN IS THE BOTTOM LEFT CORNER OF THE SQUARE CONTAINING ALL ASTEROID + // TILES YOU WISH TO APPLY THE DISTRIBUTION MAP TO. + + var/origin_x = 13 //We start here... + var/origin_y = 32 //...and here... + var/limit_x = 217 //...and iterate until here... + var/limit_y = 223 //...and here... + var/asteroid_z = 5 //...on this Z-level. var/tx = origin_x var/ty = origin_y @@ -155,18 +157,9 @@ Deep minerals: target_turf = locate(tx+j, ty+i, asteroid_z) - if(target_turf.has_resources) + if(target_turf && target_turf.has_resources) - var/printcolor - if(map[MAP_CELL] > (range*0.60)) - printcolor = "#FF0000" - else if(map[MAP_CELL] > (range*0.40)) - printcolor = "#00FF00" - else - printcolor = "#0000FF" - target_turf.color = "#[printcolor]" target_turf.resources = list() - target_turf.resources["silicates"] = rand(RESOURCE_HIGH_MIN,RESOURCE_HIGH_MAX) target_turf.resources["carbonaceous rock"] = rand(RESOURCE_HIGH_MIN,RESOURCE_HIGH_MAX) @@ -202,24 +195,8 @@ Deep minerals: tx = origin_x ty += chunk_size -/datum/ore_distribution/proc/print_map() - world << "---" - var/string = "" - for(var/y = 1, y <= real_size, y++) - for(var/x = 1, x <= real_size, x++) - - var/printcolor - if(map[MAP_CELL] > (range*0.60)) - printcolor = "#FF0000" - else if(map[MAP_CELL] > (range*0.40)) - printcolor = "#00FF00" - else - printcolor = "#0000FF" - string += "#" - - world << string - string = "" - world << "---" + world << "" + return #undef MAP_CELL #undef MAP_CENTRE From 9638349fe2197ba1f377021eb10f577db0ae5e16 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 25 Jun 2014 16:48:20 +0930 Subject: [PATCH 24/25] Update distribution.dm --- code/modules/mining/drilling/distribution.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mining/drilling/distribution.dm b/code/modules/mining/drilling/distribution.dm index e0aec22db8..2ca9a3f685 100644 --- a/code/modules/mining/drilling/distribution.dm +++ b/code/modules/mining/drilling/distribution.dm @@ -195,7 +195,7 @@ Deep minerals: tx = origin_x ty += chunk_size - world << "" + world << "Resource map generation complete." return #undef MAP_CELL @@ -222,4 +222,4 @@ Deep minerals: #undef RESOURCE_MID_MAX #undef RESOURCE_MID_MIN #undef RESOURCE_LOW_MAX -#undef RESOURCE_LOW_MIN \ No newline at end of file +#undef RESOURCE_LOW_MIN From 30bf9302d686a6a4d8cce44af345af4db77597f4 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 25 Jun 2014 19:57:15 +0930 Subject: [PATCH 25/25] Update cat.dm --- code/modules/mob/living/simple_animal/friendly/cat.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 1fc3b8fe42..225290d91b 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -67,7 +67,6 @@ var/mob/living/carbon/H = over_object if(!istype(H)) return ..() - //This REALLY needs to be moved to a general mob proc somewhere. if(H.a_intent == "help") get_scooped(H) return