Merge remote-tracking branch 'upstream/release'

This commit is contained in:
Hawk_v3
2019-05-04 21:03:48 +01:00
491 changed files with 60588 additions and 353777 deletions

View File

@@ -38,6 +38,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define NOSLIP (1<<2) // Prevents from slipping on wet floors, in space, etc. #define NOSLIP (1<<2) // Prevents from slipping on wet floors, in space, etc.
#define BLOCK_GAS_SMOKE_EFFECT (1<<3) // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) #define BLOCK_GAS_SMOKE_EFFECT (1<<3) // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL)
#define FLEXIBLEMATERIAL (1<<4) // At the moment, masks with this flag will not prevent eating even if they are covering your face. #define FLEXIBLEMATERIAL (1<<4) // At the moment, masks with this flag will not prevent eating even if they are covering your face.
#define ALLOW_SURVIVALFOOD (1<<5) // Allows special survival food items to be eaten through it
// Flags for pass_flags. - Used in /atom/var/pass_flags // Flags for pass_flags. - Used in /atom/var/pass_flags
#define PASSTABLE (1<<0) #define PASSTABLE (1<<0)

View File

@@ -56,6 +56,9 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define NETWORK_TELECOM "Tcomms" #define NETWORK_TELECOM "Tcomms"
#define NETWORK_THUNDER "Thunderdome" #define NETWORK_THUNDER "Thunderdome"
#define NETWORK_COMMUNICATORS "Communicators" #define NETWORK_COMMUNICATORS "Communicators"
#define NETWORK_ALARM_ATMOS "Atmosphere Alarms"
#define NETWORK_ALARM_POWER "Power Alarms"
#define NETWORK_ALARM_FIRE "Fire Alarms"
// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. // Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them.
var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret", NETWORK_COMMUNICATORS) var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret", NETWORK_COMMUNICATORS)
@@ -69,14 +72,6 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret
#define STAGE_FIVE 9 #define STAGE_FIVE 9
#define STAGE_SUPER 11 #define STAGE_SUPER 11
// computer3 error codes, move lower in the file when it passes dev -Sayu
#define PROG_CRASH 0x1 // Generic crash.
#define MISSING_PERIPHERAL 0x2 // Missing hardware.
#define BUSTED_ASS_COMPUTER 0x4 // Self-perpetuating error. BAC will continue to crash forever.
#define MISSING_PROGRAM 0x8 // Some files try to automatically launch a program. This is that failing.
#define FILE_DRM 0x10 // Some files want to not be copied/moved. This is them complaining that you tried.
#define NETWORK_FAILURE 0x20
// NanoUI flags // NanoUI flags
#define STATUS_INTERACTIVE 2 // GREEN Visability #define STATUS_INTERACTIVE 2 // GREEN Visability
#define STATUS_UPDATE 1 // ORANGE Visability #define STATUS_UPDATE 1 // ORANGE Visability
@@ -106,6 +101,16 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret
#define ATMOS_DEFAULT_VOLUME_MIXER 200 // L. #define ATMOS_DEFAULT_VOLUME_MIXER 200 // L.
#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L. #define ATMOS_DEFAULT_VOLUME_PIPE 70 // L.
// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse!
#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case.
#define SUPERMATTER_INACTIVE 0 // No or minimal energy
#define SUPERMATTER_NORMAL 1 // Normal operation
#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE
#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged
#define SUPERMATTER_DANGER 4 // Integrity < 50%
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
//wIP - PORT ALL OF THESE TO SUBSYSTEMS AND GET RID OF THE WHOLE LIST PROCESS THING //wIP - PORT ALL OF THESE TO SUBSYSTEMS AND GET RID OF THE WHOLE LIST PROCESS THING
// Fancy-pants START/STOP_PROCESSING() macros that lets us custom define what the list is. // Fancy-pants START/STOP_PROCESSING() macros that lets us custom define what the list is.
#define START_PROCESSING_IN_LIST(DATUM, LIST) \ #define START_PROCESSING_IN_LIST(DATUM, LIST) \

View File

@@ -113,6 +113,7 @@
#define MAX_RECORD_LENGTH 24576 #define MAX_RECORD_LENGTH 24576
#define MAX_LNAME_LEN 64 #define MAX_LNAME_LEN 64
#define MAX_NAME_LEN 52 #define MAX_NAME_LEN 52
#define MAX_TEXTFILE_LENGTH 128000 // 512GQ file
// Event defines. // Event defines.
#define EVENT_LEVEL_MUNDANE 1 #define EVENT_LEVEL_MUNDANE 1
@@ -191,6 +192,33 @@
#define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2) #define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2)
#define BOMBCAP_LIGHT_RADIUS max_explosion_range #define BOMBCAP_LIGHT_RADIUS max_explosion_range
#define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5) #define BOMBCAP_FLASH_RADIUS (max_explosion_range*1.5)
// NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc)
#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet
#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices
#define NTNET_COMMUNICATION 3 // Communication (messaging)
#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc.
// NTNet transfer speeds, used when downloading/uploading a file/program.
#define NTNETSPEED_LOWSIGNAL 0.25 // GQ/s transfer speed when the device is wirelessly connected and on Low signal
#define NTNETSPEED_HIGHSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on High signal
#define NTNETSPEED_ETHERNET 1.0 // GQ/s transfer speed when the device is using wired connection
#define NTNETSPEED_DOS_AMPLIFICATION 5 // Multiplier for Denial of Service program. Resulting load on NTNet relay is this multiplied by NTNETSPEED of the device
// Program bitflags
#define PROGRAM_ALL 15
#define PROGRAM_CONSOLE 1
#define PROGRAM_LAPTOP 2
#define PROGRAM_TABLET 4
#define PROGRAM_TELESCREEN 8
#define PROGRAM_STATE_KILLED 0
#define PROGRAM_STATE_BACKGROUND 1
#define PROGRAM_STATE_ACTIVE 2
// Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it.
#define MAX_NTNET_LOGS 500
#define MIN_NTNET_LOGS 10
// Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile. // Special return values from bullet_act(). Positive return values are already used to indicate the blocked level of the projectile.
#define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act() #define PROJECTILE_CONTINUE -1 //if the projectile should continue flying after calling bullet_act()

View File

@@ -756,3 +756,5 @@ proc/dd_sortedTextList(list/incoming)
. = list() . = list()
for(var/i in L) for(var/i in L)
. |= i . |= i
#define listequal(A, B) (A.len == B.len && !length(A^B))

View File

@@ -0,0 +1,43 @@
/proc/get_turf_pixel(atom/movable/AM)
if(!istype(AM))
return
//Find AM's matrix so we can use it's X/Y pixel shifts
var/matrix/M = matrix(AM.transform)
var/pixel_x_offset = AM.pixel_x + M.get_x_shift()
var/pixel_y_offset = AM.pixel_y + M.get_y_shift()
//Irregular objects
if(AM.bound_height != world.icon_size || AM.bound_width != world.icon_size)
var/icon/AMicon = icon(AM.icon, AM.icon_state)
pixel_x_offset += ((AMicon.Width()/world.icon_size)-1)*(world.icon_size*0.5)
pixel_y_offset += ((AMicon.Height()/world.icon_size)-1)*(world.icon_size*0.5)
qdel(AMicon)
//DY and DX
var/rough_x = round(round(pixel_x_offset,world.icon_size)/world.icon_size)
var/rough_y = round(round(pixel_y_offset,world.icon_size)/world.icon_size)
//Find coordinates
var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom
var/final_x = T.x + rough_x
var/final_y = T.y + rough_y
if(final_x || final_y)
return locate(final_x, final_y, T.z)
// Walks up the loc tree until it finds a holder of the given holder_type
/proc/get_holder_of_type(atom/A, holder_type)
if(!istype(A)) return
for(A, A && !istype(A, holder_type), A=A.loc);
return A
/atom/movable/proc/throw_at_random(var/include_own_turf, var/maxrange, var/speed)
var/list/turfs = trange(maxrange, src)
if(!maxrange)
maxrange = 1
if(!include_own_turf)
turfs -= get_turf(src)
src.throw_at(pick(turfs), maxrange, speed, src)

View File

@@ -331,6 +331,55 @@ proc/TextPreview(var/string,var/len=40)
/proc/strip_improper(var/text) /proc/strip_improper(var/text)
return replacetext(replacetext(text, "\proper", ""), "\improper", "") return replacetext(replacetext(text, "\proper", ""), "\improper", "")
/proc/pencode2html(t)
t = replacetext(t, "\n", "<BR>")
t = replacetext(t, "\[center\]", "<center>")
t = replacetext(t, "\[/center\]", "</center>")
t = replacetext(t, "\[br\]", "<BR>")
t = replacetext(t, "\[b\]", "<B>")
t = replacetext(t, "\[/b\]", "</B>")
t = replacetext(t, "\[i\]", "<I>")
t = replacetext(t, "\[/i\]", "</I>")
t = replacetext(t, "\[u\]", "<U>")
t = replacetext(t, "\[/u\]", "</U>")
t = replacetext(t, "\[time\]", "[stationtime2text()]")
t = replacetext(t, "\[date\]", "[stationdate2text()]")
t = replacetext(t, "\[large\]", "<font size=\"4\">")
t = replacetext(t, "\[/large\]", "</font>")
t = replacetext(t, "\[field\]", "<span class=\"paper_field\"></span>")
t = replacetext(t, "\[h1\]", "<H1>")
t = replacetext(t, "\[/h1\]", "</H1>")
t = replacetext(t, "\[h2\]", "<H2>")
t = replacetext(t, "\[/h2\]", "</H2>")
t = replacetext(t, "\[h3\]", "<H3>")
t = replacetext(t, "\[/h3\]", "</H3>")
t = replacetext(t, "\[*\]", "<li>")
t = replacetext(t, "\[hr\]", "<HR>")
t = replacetext(t, "\[small\]", "<font size = \"1\">")
t = replacetext(t, "\[/small\]", "</font>")
t = replacetext(t, "\[list\]", "<ul>")
t = replacetext(t, "\[/list\]", "</ul>")
t = replacetext(t, "\[table\]", "<table border=1 cellspacing=0 cellpadding=3 style='border: 1px solid black;'>")
t = replacetext(t, "\[/table\]", "</td></tr></table>")
t = replacetext(t, "\[grid\]", "<table>")
t = replacetext(t, "\[/grid\]", "</td></tr></table>")
t = replacetext(t, "\[row\]", "</td><tr>")
t = replacetext(t, "\[cell\]", "<td>")
t = replacetext(t, "\[logo\]", "<img src = ntlogo.png>")
t = replacetext(t, "\[redlogo\]", "<img src = redntlogo.png>")
t = replacetext(t, "\[sglogo\]", "<img src = sglogo.png>")
t = replacetext(t, "\[editorbr\]", "")
return t
// Random password generator
/proc/GenerateKey()
//Feel free to move to Helpers.
var/newKey
newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le")
newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai")
newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
return newKey
//Used for applying byonds text macros to strings that are loaded at runtime //Used for applying byonds text macros to strings that are loaded at runtime
/proc/apply_text_macros(string) /proc/apply_text_macros(string)
var/next_backslash = findtext(string, "\\") var/next_backslash = findtext(string, "\\")

View File

@@ -11,6 +11,7 @@
#define log_world(message) world.log << message #define log_world(message) world.log << message
#define to_file(file_entry, source_var) file_entry << source_var #define to_file(file_entry, source_var) file_entry << source_var
#define from_file(file_entry, target_var) file_entry >> target_var #define from_file(file_entry, target_var) file_entry >> target_var
#define show_browser(target, browser_content, browser_name) target << browse(browser_content, browser_name)
// From TG, might be useful to have. // From TG, might be useful to have.
// Didn't port SEND_TEXT() since to_chat() appears to serve the same purpose. // Didn't port SEND_TEXT() since to_chat() appears to serve the same purpose.
@@ -20,4 +21,8 @@
#define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE) #define CanInteract(user, state) (CanUseTopic(user, state) == STATUS_INTERACTIVE)
#define qdel_null(x) if(x) { qdel(x) ; x = null }
#define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id)
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") } #define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }

View File

@@ -108,6 +108,22 @@
screen_loc = "WEST,SOUTH to EAST,NORTH" screen_loc = "WEST,SOUTH to EAST,NORTH"
icon_state = "druggy" icon_state = "druggy"
/obj/screen/fullscreen/noise
icon = 'icons/effects/static.dmi'
icon_state = "1 light"
screen_loc = ui_entire_screen
layer = FULLSCREEN_LAYER
/obj/screen/fullscreen/scanline
icon = 'icons/effects/static.dmi'
icon_state = "scanlines"
screen_loc = ui_entire_screen
alpha = 50
layer = FULLSCREEN_LAYER
/obj/screen/fullscreen/fishbed
icon_state = "fishbed"
#undef FULLSCREEN_LAYER #undef FULLSCREEN_LAYER
#undef BLIND_LAYER #undef BLIND_LAYER
#undef DAMAGE_LAYER #undef DAMAGE_LAYER

View File

@@ -5,9 +5,11 @@
/datum/configuration /datum/configuration
var/list/engine_map // Comma separated list of engines to choose from. Blank means fully random. var/list/engine_map // Comma separated list of engines to choose from. Blank means fully random.
var/time_off = FALSE var/time_off = FALSE
var/pto_job_change = FALSE
var/limit_interns = -1 //Unlimited by default var/limit_interns = -1 //Unlimited by default
var/limit_visitors = -1 //Unlimited by default var/limit_visitors = -1 //Unlimited by default
var/pto_cap = 100 //Hours var/pto_cap = 100 //Hours
var/require_flavor = FALSE
/hook/startup/proc/read_vs_config() /hook/startup/proc/read_vs_config()
var/list/Lines = file2list("config/config.txt") var/list/Lines = file2list("config/config.txt")
@@ -52,5 +54,8 @@
config.pto_cap = text2num(value) config.pto_cap = text2num(value)
if ("time_off") if ("time_off")
config.time_off = TRUE config.time_off = TRUE
if ("pto_job_change")
config.pto_job_change = TRUE
if ("require_flavor")
config.require_flavor = TRUE
return 1 return 1

View File

@@ -35,7 +35,12 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
if (!shuttle.location) //leaving from the station if (!shuttle.location) //leaving from the station
//launch the pods! //launch the pods!
for (var/datum/shuttle/ferry/escape_pod/pod in escape_pods) for (var/EP in escape_pods)
var/datum/shuttle/ferry/escape_pod/pod
if(istype(escape_pods[EP], /datum/shuttle/ferry/escape_pod))
pod = escape_pods[EP]
else
continue
if (!pod.arming_controller || pod.arming_controller.armed) if (!pod.arming_controller || pod.arming_controller.armed)
pod.launch(src) pod.launch(src)
@@ -57,7 +62,12 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
//arm the escape pods //arm the escape pods
if (evac) if (evac)
for (var/datum/shuttle/ferry/escape_pod/pod in escape_pods) for (var/EP in escape_pods)
var/datum/shuttle/ferry/escape_pod/pod
if(istype(escape_pods[EP], /datum/shuttle/ferry/escape_pod))
pod = escape_pods[EP]
else
continue
if (pod.arming_controller) if (pod.arming_controller)
pod.arming_controller.arm() pod.arming_controller.arm()

View File

@@ -12,6 +12,8 @@ SUBSYSTEM_DEF(nanoui)
var/list/nano_asset_dirs = list(\ var/list/nano_asset_dirs = list(\
"nano/css/",\ "nano/css/",\
"nano/images/",\ "nano/images/",\
"nano/images/status_icons/",\
"nano/images/modular_computers/",
"nano/js/",\ "nano/js/",\
"nano/templates/"\ "nano/templates/"\
) )

View File

@@ -9,6 +9,10 @@ SUBSYSTEM_DEF(processing)
var/stat_tag = "P" //Used for logging var/stat_tag = "P" //Used for logging
var/list/processing = list() var/list/processing = list()
var/list/currentrun = list() var/list/currentrun = list()
var/process_proc = /datum/proc/process
var/debug_last_thing
var/debug_original_process_proc // initial() does not work with procs
/datum/controller/subsystem/processing/stat_entry() /datum/controller/subsystem/processing/stat_entry()
..("[stat_tag]:[processing.len]") ..("[stat_tag]:[processing.len]")
@@ -30,6 +34,32 @@ SUBSYSTEM_DEF(processing)
if (MC_TICK_CHECK) if (MC_TICK_CHECK)
return return
/datum/controller/subsystem/processing/proc/toggle_debug()
if(!check_rights(R_DEBUG))
return
if(debug_original_process_proc)
process_proc = debug_original_process_proc
debug_original_process_proc = null
else
debug_original_process_proc = process_proc
process_proc = /datum/proc/DebugSubsystemProcess
to_chat(usr, "[name] - Debug mode [debug_original_process_proc ? "en" : "dis"]abled")
/datum/proc/DebugSubsystemProcess(var/wait, var/times_fired, var/datum/controller/subsystem/processing/subsystem)
subsystem.debug_last_thing = src
var/start_tick = world.time
var/start_tick_usage = world.tick_usage
. = call(src, subsystem.debug_original_process_proc)(wait, times_fired)
var/tick_time = world.time - start_tick
var/tick_use_limit = world.tick_usage - start_tick_usage - 100 // Current tick use - starting tick use - 100% (a full tick excess)
if(tick_time > 0)
crash_with("[log_info_line(subsystem.debug_last_thing)] slept during processing. Spent [tick_time] tick\s.")
if(tick_use_limit > 0)
crash_with("[log_info_line(subsystem.debug_last_thing)] took longer than a tick to process. Exceeded with [tick_use_limit]%")
/datum/proc/process() /datum/proc/process()
set waitfor = 0 set waitfor = 0
return PROCESS_KILL return PROCESS_KILL

View File

@@ -19,6 +19,7 @@
var/list/med = new() var/list/med = new()
var/list/sci = new() var/list/sci = new()
var/list/car = new() var/list/car = new()
var/list/pla = new() //VOREStation Edit
var/list/civ = new() var/list/civ = new()
var/list/bot = new() var/list/bot = new()
var/list/misc = new() var/list/misc = new()
@@ -72,6 +73,11 @@
if(real_rank in cargo_positions) if(real_rank in cargo_positions)
car[name] = rank car[name] = rank
department = 1 department = 1
//VOREStation Edit Begin
if(real_rank in planet_positions)
pla[name] = rank
department = 1
//VOREStation Edit End
if(real_rank in civilian_positions) if(real_rank in civilian_positions)
civ[name] = rank civ[name] = rank
department = 1 department = 1
@@ -118,6 +124,13 @@
for(name in car) for(name in car)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[car[name]]</td><td>[isactive[name]]</td></tr>" dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[car[name]]</td><td>[isactive[name]]</td></tr>"
even = !even even = !even
//VOREStation Edit Begin
if(pla.len > 0)
dat += "<tr><th colspan=3>Exploration</th></tr>"
for(name in pla)
dat += "<tr[even ? " class='alt'" : ""]><td>[name]</td><td>[pla[name]]</td><td>[isactive[name]]</td></tr>"
even = !even
//VOREStation Edit End
if(civ.len > 0) if(civ.len > 0)
dat += "<tr><th colspan=3>Civilian</th></tr>" dat += "<tr><th colspan=3>Civilian</th></tr>"
for(name in civ) for(name in civ)

View File

@@ -1,3 +1,11 @@
//wrapper
/proc/do_noeffect_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, local=TRUE)
new /datum/teleport/instant/science/noeffect(arglist(args))
return
/datum/teleport/instant/science/noeffect/setEffects(datum/effect/effect/system/aeffectin,datum/effect/effect/system/aeffectout)
return 1
/datum/teleport/proc/try_televore() /datum/teleport/proc/try_televore()
//Destination is in a belly //Destination is in a belly
if(isbelly(destination.loc)) if(isbelly(destination.loc))

View File

@@ -6,11 +6,6 @@
name = OUTFIT_JOB_NAME("Visitor") name = OUTFIT_JOB_NAME("Visitor")
id_pda_assignment = "Visitor" id_pda_assignment = "Visitor"
uniform = /obj/item/clothing/under/assistantformal uniform = /obj/item/clothing/under/assistantformal
/decl/hierarchy/outfit/job/assistant/resident
name = OUTFIT_JOB_NAME("Resident")
id_pda_assignment = "Resident"
uniform = /obj/item/clothing/under/color/white
//VOREStation Add - Interns //VOREStation Add - Interns
/decl/hierarchy/outfit/job/assistant/intern /decl/hierarchy/outfit/job/assistant/intern
name = OUTFIT_JOB_NAME("Intern") name = OUTFIT_JOB_NAME("Intern")

View File

@@ -0,0 +1,18 @@
/decl/hierarchy/outfit/job/assistant/worker
id_type = /obj/item/weapon/card/id/civilian
/decl/hierarchy/outfit/job/assistant/cargo
id_type = /obj/item/weapon/card/id/cargo
/decl/hierarchy/outfit/job/assistant/engineer
id_type = /obj/item/weapon/card/id/engineering
flags = OUTFIT_EXTENDED_SURVIVAL
/decl/hierarchy/outfit/job/assistant/medic
id_type = /obj/item/weapon/card/id/medical
/decl/hierarchy/outfit/job/assistant/scientist
id_type = /obj/item/weapon/card/id/science
/decl/hierarchy/outfit/job/assistant/officer
id_type = /obj/item/weapon/card/id/security

View File

@@ -36,7 +36,7 @@
l_ear = /obj/item/device/radio/headset/headset_com l_ear = /obj/item/device/radio/headset/headset_com
shoes = /obj/item/clothing/shoes/brown shoes = /obj/item/clothing/shoes/brown
id_type = /obj/item/weapon/card/id/silver/secretary id_type = /obj/item/weapon/card/id/silver/secretary
pda_type = /obj/item/device/pda/heads/hop pda_type = /obj/item/device/pda/heads
r_hand = /obj/item/weapon/clipboard r_hand = /obj/item/weapon/clipboard
/decl/hierarchy/outfit/job/secretary/pre_equip(mob/living/carbon/human/H) /decl/hierarchy/outfit/job/secretary/pre_equip(mob/living/carbon/human/H)

View File

@@ -0,0 +1,70 @@
var/repository/unique/uniqueness_repository = new()
/repository/unique
var/list/generators
/repository/unique/New()
..()
generators = list()
/repository/unique/proc/Generate()
var/generator_type = args[1]
var/datum/uniqueness_generator/generator = generators[generator_type]
if(!generator)
generator = new generator_type()
generators[generator_type] = generator
var/list/generator_args = args.Copy() // Cannot cut args directly, BYOND complains about it being readonly.
generator_args -= generator_type
return generator.Generate(arglist(generator_args))
/datum/uniqueness_generator/proc/Generate()
return
/datum/uniqueness_generator/id_sequential
var/list/ids_by_key
/datum/uniqueness_generator/id_sequential/New()
..()
ids_by_key = list()
/datum/uniqueness_generator/id_sequential/Generate(var/key, var/default_id = 100)
var/id = ids_by_key[key]
if(id)
id++
else
id = default_id
ids_by_key[key] = id
. = id
/datum/uniqueness_generator/id_random
var/list/ids_by_key
/datum/uniqueness_generator/id_random/New()
..()
ids_by_key = list()
/datum/uniqueness_generator/id_random/Generate(var/key, var/min, var/max)
var/list/ids = ids_by_key[key]
if(!ids)
ids = list()
ids_by_key[key] = ids
if(ids.len >= (max - min) + 1)
error("Random ID limit reached for key [key].")
ids.Cut()
if(ids.len >= 0.6 * ((max-min) + 1)) // if more than 60% of possible ids used
. = list()
for(var/i = min to max)
if(i in ids)
continue
. += i
var/id = pick(.)
ids += id
return id
else
do
. = rand(min, max)
while(. in ids)
ids += .

View File

@@ -33,8 +33,3 @@
name = "Voice Changer" name = "Voice Changer"
item_cost = 15 item_cost = 15
path = /obj/item/clothing/mask/gas/voice path = /obj/item/clothing/mask/gas/voice
/datum/uplink_item/item/stealth_items/camera_floppy
name = "Camera Network Access - Floppy"
item_cost = 15
path = /obj/item/weapon/disk/file/cameras/syndicate

View File

@@ -57,9 +57,6 @@ var/const/CAMERA_WIRE_NOTHING2 = 32
var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range)) var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range))
C.setViewRange(new_range) C.setViewRange(new_range)
if(CAMERA_WIRE_POWER)
C.kick_viewers() // Kicks anyone watching the camera
if(CAMERA_WIRE_LIGHT) if(CAMERA_WIRE_LIGHT)
C.light_disabled = !C.light_disabled C.light_disabled = !C.light_disabled

View File

@@ -39,7 +39,6 @@ var/const/BORG_WIRE_CAMERA = 16
if (BORG_WIRE_CAMERA) if (BORG_WIRE_CAMERA)
if(!isnull(R.camera) && !R.scrambledcodes) if(!isnull(R.camera) && !R.scrambledcodes)
R.camera.status = mended R.camera.status = mended
R.camera.kick_viewers() // Will kick anyone who is watching the Cyborg's camera.
if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh
if (R.lawupdate) if (R.lawupdate)
@@ -59,7 +58,6 @@ var/const/BORG_WIRE_CAMERA = 16
if (BORG_WIRE_CAMERA) if (BORG_WIRE_CAMERA)
if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes)
R.camera.kick_viewers() // Kick anyone watching the Cyborg's camera
R.visible_message("[R]'s camera lense focuses loudly.") R.visible_message("[R]'s camera lense focuses loudly.")
R << "Your camera lense focuses loudly." R << "Your camera lense focuses loudly."

View File

@@ -157,7 +157,7 @@ var/global/list/PDA_Manifest = list()
list("cat" = "Medical", "elems" = med), list("cat" = "Medical", "elems" = med),
list("cat" = "Science", "elems" = sci), list("cat" = "Science", "elems" = sci),
list("cat" = "Cargo", "elems" = car), list("cat" = "Cargo", "elems" = car),
// list("cat" = "Planetside", "elems" = pla), // VOREStation Edit - Don't show empty dpt in PDA list("cat" = "Exploration", "elems" = pla), // VOREStation Edit
list("cat" = "Civilian", "elems" = civ), list("cat" = "Civilian", "elems" = civ),
list("cat" = "Silicon", "elems" = bot), list("cat" = "Silicon", "elems" = bot),
list("cat" = "Miscellaneous", "elems" = misc) list("cat" = "Miscellaneous", "elems" = misc)

View File

@@ -295,3 +295,7 @@
/area/engineering/engine_gas /area/engineering/engine_gas
name = "\improper Engine Gas Storage" name = "\improper Engine Gas Storage"
icon_state = "engine_waste" icon_state = "engine_waste"
/area/chapel/observation
name = "\improper Chapel Observation"
icon_state = "chapel"

View File

@@ -46,14 +46,8 @@
intercepttext += "<B>* A cure is to be researched immediately, but NanoTrasen intellectual property must be respected. To prevent knowledge of [virus_name] from falling into unauthorized hands, all medical staff that work with the pathogen must be enhanced with a NanoTrasen loyality implant.</B><BR>" intercepttext += "<B>* A cure is to be researched immediately, but NanoTrasen intellectual property must be respected. To prevent knowledge of [virus_name] from falling into unauthorized hands, all medical staff that work with the pathogen must be enhanced with a NanoTrasen loyality implant.</B><BR>"
for (var/obj/machinery/computer/communications/comm in world) //New message handling won't hurt if someone enables epidemic
if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) post_comm_message("Cent. Com. CONFIDENTIAL REPORT", intercepttext)
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
intercept.name = "paper"
intercept.info = intercepttext
comm.messagetitle.Add("CentCom CONFIDENTIAL REPORT")
comm.messagetext.Add(intercepttext)
world << sound('sound/AI/commandreport.ogg') world << sound('sound/AI/commandreport.ogg')
@@ -68,14 +62,7 @@
intercepttext += "<FONT size = 2;color='red'><B>PATHOGEN [virus_name] IS STILL PRESENT ON [station_name()]. IN COMPLIANCE WITH NANOTRASEN LAWS FOR INTERSTELLAR SAFETY, EMERGENCY SAFETY MEASURES HAVE BEEN AUTHORIZED. ALL INFECTED CREW MEMBERS ON [station_name()] ARE TO BE NEUTRALIZED AND DISPOSED OF IN A MANNER THAT WILL DESTROY ALL TRACES OF THE PATHOGEN. FAILURE TO COMPLY WILL RESULT IN IMMEDIATE DESTRUCTION OF [station_name].</B></FONT><BR>" intercepttext += "<FONT size = 2;color='red'><B>PATHOGEN [virus_name] IS STILL PRESENT ON [station_name()]. IN COMPLIANCE WITH NANOTRASEN LAWS FOR INTERSTELLAR SAFETY, EMERGENCY SAFETY MEASURES HAVE BEEN AUTHORIZED. ALL INFECTED CREW MEMBERS ON [station_name()] ARE TO BE NEUTRALIZED AND DISPOSED OF IN A MANNER THAT WILL DESTROY ALL TRACES OF THE PATHOGEN. FAILURE TO COMPLY WILL RESULT IN IMMEDIATE DESTRUCTION OF [station_name].</B></FONT><BR>"
intercepttext += "<B>CRUISER WILL ARRIVE IN [round(cruiser_seconds()/60)] MINUTES</B><BR>" intercepttext += "<B>CRUISER WILL ARRIVE IN [round(cruiser_seconds()/60)] MINUTES</B><BR>"
for (var/obj/machinery/computer/communications/comm in world) post_comm_message("Cent. Com. CONFIDENTIAL REPORT", intercepttext)
if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
intercept.name = "paper"
intercept.info = intercepttext
comm.messagetitle.Add("CentCom CONFIDENTIAL REPORT")
comm.messagetext.Add(intercepttext)
world << sound('sound/AI/commandreport.ogg') world << sound('sound/AI/commandreport.ogg')

View File

@@ -146,10 +146,10 @@ var/global/list/additional_antag_types = list()
playerC++ playerC++
if(master_mode=="secret") if(master_mode=="secret")
if(playerC < config.player_requirements_secret) if(playerC < config.player_requirements_secret[config_tag])
return 0 return 0
else else
if(playerC < config.player_requirements) if(playerC < config.player_requirements[config_tag])
return 0 return 0
if(!(antag_templates && antag_templates.len)) if(!(antag_templates && antag_templates.len))

View File

@@ -101,7 +101,7 @@ var/global/datum/controller/gameticker/ticker
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly. job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
if(!src.mode.can_start()) if(!src.mode.can_start())
world << "<B>Unable to start [mode.name].</B> Not enough players readied, [mode.required_players] players needed. Reverting to pregame lobby." world << "<B>Unable to start [mode.name].</B> Not enough players readied, [config.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby."
current_state = GAME_STATE_PREGAME current_state = GAME_STATE_PREGAME
Master.SetRunLevel(RUNLEVEL_LOBBY) Master.SetRunLevel(RUNLEVEL_LOBBY)
mode.fail_setup() mode.fail_setup()

View File

@@ -178,6 +178,10 @@
/proc/get_centcom_access_desc(A) /proc/get_centcom_access_desc(A)
return get_access_desc(A) return get_access_desc(A)
/proc/get_access_by_id(id)
var/list/AS = get_all_access_datums_by_id()
return AS[id]
/proc/get_all_jobs() /proc/get_all_jobs()
var/list/all_jobs = list() var/list/all_jobs = list()
var/list/all_datums = typesof(/datum/job) var/list/all_datums = typesof(/datum/job)

View File

@@ -256,7 +256,12 @@
desc = "Quartermaster" desc = "Quartermaster"
region = ACCESS_REGION_SUPPLY region = ACCESS_REGION_SUPPLY
// /var/const/free_access_id = 43 /var/const/access_network = 42
/datum/access/network
id = access_network
desc = "Station Network"
region = ACCESS_REGION_RESEARCH
// /var/const/free_access_id = 43 // /var/const/free_access_id = 43
// /var/const/free_access_id = 44 // /var/const/free_access_id = 44

View File

@@ -45,6 +45,7 @@
if(config) if(config)
total_positions = config.limit_visitors total_positions = config.limit_visitors
spawn_positions = config.limit_visitors spawn_positions = config.limit_visitors
/datum/job/assistant/get_access() /datum/job/assistant/get_access()
if(config.assistant_maint) if(config.assistant_maint)
return list(access_maint_tunnels) return list(access_maint_tunnels)

View File

@@ -8,6 +8,9 @@
//Every hour playing this role gains this much time off. (Can be negative for off duty jobs!) //Every hour playing this role gains this much time off. (Can be negative for off duty jobs!)
var/timeoff_factor = 3 var/timeoff_factor = 3
//Disallow joining as this job midround from off-duty position via going on-duty
var/disallow_jobhop = FALSE
// Check client-specific availability rules. // Check client-specific availability rules.
/datum/job/proc/player_has_enough_pto(client/C) /datum/job/proc/player_has_enough_pto(client/C)
return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, department) > 0) return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, department) > 0)

View File

@@ -3,7 +3,7 @@
// //
/datum/job/offduty_civilian /datum/job/offduty_civilian
title = "Off-Duty Worker" title = "Off-duty Worker"
latejoin_only = TRUE latejoin_only = TRUE
timeoff_factor = -1 timeoff_factor = -1
total_positions = -1 total_positions = -1
@@ -13,7 +13,7 @@
selection_color = "#9b633e" selection_color = "#9b633e"
access = list(access_maint_tunnels) access = list(access_maint_tunnels)
minimal_access = list(access_maint_tunnels) minimal_access = list(access_maint_tunnels)
outfit_type = /decl/hierarchy/outfit/job/assistant outfit_type = /decl/hierarchy/outfit/job/assistant/worker
/datum/job/offduty_cargo /datum/job/offduty_cargo
title = "Off-duty Cargo" title = "Off-duty Cargo"
@@ -26,7 +26,7 @@
selection_color = "#9b633e" selection_color = "#9b633e"
access = list(access_maint_tunnels) access = list(access_maint_tunnels)
minimal_access = list(access_maint_tunnels) minimal_access = list(access_maint_tunnels)
outfit_type = /decl/hierarchy/outfit/job/assistant outfit_type = /decl/hierarchy/outfit/job/assistant/cargo
/datum/job/offduty_engineering /datum/job/offduty_engineering
title = "Off-duty Engineer" title = "Off-duty Engineer"
@@ -39,7 +39,7 @@
selection_color = "#5B4D20" selection_color = "#5B4D20"
access = list(access_maint_tunnels, access_external_airlocks, access_construction) access = list(access_maint_tunnels, access_external_airlocks, access_construction)
minimal_access = list(access_maint_tunnels, access_external_airlocks) minimal_access = list(access_maint_tunnels, access_external_airlocks)
outfit_type = /decl/hierarchy/outfit/job/assistant outfit_type = /decl/hierarchy/outfit/job/assistant/engineer
/datum/job/offduty_medical /datum/job/offduty_medical
title = "Off-duty Medic" title = "Off-duty Medic"
@@ -52,7 +52,7 @@
selection_color = "#013D3B" selection_color = "#013D3B"
access = list(access_maint_tunnels, access_external_airlocks) access = list(access_maint_tunnels, access_external_airlocks)
minimal_access = list(access_maint_tunnels, access_external_airlocks) minimal_access = list(access_maint_tunnels, access_external_airlocks)
outfit_type = /decl/hierarchy/outfit/job/assistant outfit_type = /decl/hierarchy/outfit/job/assistant/medic
/datum/job/offduty_science /datum/job/offduty_science
title = "Off-duty Scientist" title = "Off-duty Scientist"
@@ -65,7 +65,7 @@
selection_color = "#633D63" selection_color = "#633D63"
access = list(access_maint_tunnels) access = list(access_maint_tunnels)
minimal_access = list(access_maint_tunnels) minimal_access = list(access_maint_tunnels)
outfit_type = /decl/hierarchy/outfit/job/assistant outfit_type = /decl/hierarchy/outfit/job/assistant/scientist
/datum/job/offduty_security /datum/job/offduty_security
title = "Off-duty Officer" title = "Off-duty Officer"
@@ -78,4 +78,4 @@
selection_color = "#601C1C" selection_color = "#601C1C"
access = list(access_maint_tunnels) access = list(access_maint_tunnels)
minimal_access = list(access_maint_tunnels) minimal_access = list(access_maint_tunnels)
outfit_type = /decl/hierarchy/outfit/job/assistant outfit_type = /decl/hierarchy/outfit/job/assistant/officer

View File

@@ -15,11 +15,11 @@
access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter, access_sec_doors, access_tox_storage, access_teleporter, access_sec_doors,
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva) //VOREStation Edit access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network) //VOREStation Edit
minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter, access_sec_doors, access_tox_storage, access_teleporter, access_sec_doors,
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva) //VOREStation Edit access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network) //VOREStation Edit
alt_titles = list("Research Supervisor") alt_titles = list("Research Supervisor")
minimum_character_age = 25 minimum_character_age = 25

View File

@@ -1,8 +1,30 @@
//Contains all modified jobs for easy access and editing. //Contains all modified jobs for easy access and editing.
/datum/job/captain
disallow_jobhop = TRUE
/datum/job/hop /datum/job/hop
disallow_jobhop = TRUE
alt_titles = list("Deputy Director", "Crew Resources Officer") alt_titles = list("Deputy Director", "Crew Resources Officer")
/datum/job/hos
disallow_jobhop = TRUE
/datum/job/chief_engineer
disallow_jobhop = TRUE
/datum/job/cmo
disallow_jobhop = TRUE
/datum/job/rd
disallow_jobhop = TRUE
/datum/job/secretary
disallow_jobhop = TRUE
/datum/job/lawyer
disallow_jobhop = TRUE
/datum/job/doctor /datum/job/doctor
total_positions = 5 total_positions = 5
spawn_positions = 5 spawn_positions = 5
@@ -50,6 +72,6 @@
/datum/job/atmos /datum/job/atmos
total_positions = 3 total_positions = 3
spawn_positions = 3 spawn_positions = 3
/datum/job/scientist /datum/job/scientist
alt_titles = list("Xenoarcheologist", "Anomalist", "Phoron Researcher", "Circuit Designer") alt_titles = list("Xenoarcheologist", "Anomalist", "Phoron Researcher", "Circuit Designer")

View File

@@ -508,6 +508,29 @@ var/global/datum/controller/occupations/job_master
if(job.req_admin_notify) if(job.req_admin_notify)
H << "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>" H << "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>"
// EMAIL GENERATION
// Email addresses will be created under this domain name. Mostly for the looks.
var/domain = "freemail.nt"
var/sanitized_name = sanitize(replacetext(replacetext(lowertext(H.real_name), " ", "."), "'", ""))
var/complete_login = "[sanitized_name]@[domain]"
// It is VERY unlikely that we'll have two players, in the same round, with the same name and branch, but still, this is here.
// If such conflict is encountered, a random number will be appended to the email address. If this fails too, no email account will be created.
if(ntnet_global.does_email_exist(complete_login))
complete_login = "[sanitized_name][random_id(/datum/computer_file/data/email_account/, 100, 999)]@[domain]"
// If even fallback login generation failed, just don't give them an email. The chance of this happening is astronomically low.
if(ntnet_global.does_email_exist(complete_login))
to_chat(H, "You were not assigned an email address.")
H.mind.store_memory("You were not assigned an email address.")
else
var/datum/computer_file/data/email_account/EA = new/datum/computer_file/data/email_account()
EA.password = GenerateKey()
EA.login = complete_login
to_chat(H, "Your email account address is <b>[EA.login]</b> and the password is <b>[EA.password]</b>. This information has also been placed into your notes.")
H.mind.store_memory("Your email account address is [EA.login] and the password is [EA.password].")
// END EMAIL GENERATION
//Gives glasses to the vision impaired //Gives glasses to the vision impaired
if(H.disabilities & NEARSIGHTED) if(H.disabilities & NEARSIGHTED)
var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses) var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses)

View File

@@ -75,18 +75,15 @@ var/list/medical_positions = list(
"Geneticist", "Geneticist",
"Psychiatrist", "Psychiatrist",
"Chemist", "Chemist",
"Field Medic", // VOREStation Edit - Moved SAR from planetary -> medical
"Paramedic" "Paramedic"
) )
var/list/science_positions = list( var/list/science_positions = list(
"Research Director", "Research Director",
"Pathfinder", // VOREStation Edit - Added Pathfinder
"Scientist", "Scientist",
"Geneticist", //Part of both medical and science "Geneticist", //Part of both medical and science
"Roboticist", "Roboticist",
"Explorer", // VOREStation Edit - Moved Explorer from planetary -> science
"Xenobiologist" "Xenobiologist"
) )
@@ -106,7 +103,6 @@ var/list/civilian_positions = list(
"Librarian", "Librarian",
"Lawyer", "Lawyer",
"Chaplain", "Chaplain",
"Pilot", // VOREStation Edit - Moved Pilot from planetary -> civ
USELESS_JOB, //VOREStation Edit - Visitor not Assistant USELESS_JOB, //VOREStation Edit - Visitor not Assistant
"Intern" //VOREStation Edit - Intern "Intern" //VOREStation Edit - Intern
) )
@@ -121,9 +117,10 @@ var/list/security_positions = list(
var/list/planet_positions = list( var/list/planet_positions = list(
// "Explorer", // VOREStation Edit - Moved Explorer from planetary -> science "Pathfinder", // VOREStation Edit - Added Pathfinder
// "Pilot", // VOREStation Edit - Moved Pilot from planetary -> civ "Explorer",
// "Search and Rescue" // VOREStation Edit - Moved SAR from planetary -> medical "Pilot",
"Field Medic" // VOREStation Edit - Field Medic
) )

View File

@@ -40,6 +40,24 @@
var/list/camera_computers_using_this = list() var/list/camera_computers_using_this = list()
/obj/machinery/camera/apply_visual(mob/living/carbon/human/M)
if(!M.client)
return
M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed)
M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline)
M.overlay_fullscreen("whitenoise",/obj/screen/fullscreen/noise)
M.machine_visual = src
return 1
/obj/machinery/camera/remove_visual(mob/living/carbon/human/M)
if(!M.client)
return
M.clear_fullscreen("fishbed",0)
M.clear_fullscreen("scanlines")
M.clear_fullscreen("whitenoise")
M.machine_visual = null
return 1
/obj/machinery/camera/New() /obj/machinery/camera/New()
wires = new(src) wires = new(src)
assembly = new(src) assembly = new(src)
@@ -93,7 +111,6 @@
stat |= EMPED stat |= EMPED
set_light(0) set_light(0)
triggerCameraAlarm() triggerCameraAlarm()
kick_viewers()
update_icon() update_icon()
update_coverage() update_coverage()
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
@@ -246,26 +263,25 @@
user = null user = null
if(choice != 1) if(choice != 1)
//legacy support, if choice is != 1 then just kick viewers without changing status return
kick_viewers()
else set_status(!src.status)
set_status(!src.status) if (!(src.status))
if (!(src.status)) if(user)
if(user) visible_message("<span class='notice'> [user] has deactivated [src]!</span>")
visible_message("<span class='notice'> [user] has deactivated [src]!</span>")
else
visible_message("<span class='notice'> [src] clicks and shuts down. </span>")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = "[initial(icon_state)]1"
add_hiddenprint(user)
else else
if(user) visible_message("<span class='notice'> [src] clicks and shuts down. </span>")
visible_message("<span class='notice'> [user] has reactivated [src]!</span>") playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
else icon_state = "[initial(icon_state)]1"
visible_message("<span class='notice'> [src] clicks and reactivates itself. </span>") add_hiddenprint(user)
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) else
icon_state = initial(icon_state) if(user)
add_hiddenprint(user) visible_message("<span class='notice'> [user] has reactivated [src]!</span>")
else
visible_message("<span class='notice'> [src] clicks and reactivates itself. </span>")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = initial(icon_state)
add_hiddenprint(user)
/obj/machinery/camera/proc/take_damage(var/force, var/message) /obj/machinery/camera/proc/take_damage(var/force, var/message)
//prob(25) gives an average of 3-4 hits //prob(25) gives an average of 3-4 hits
@@ -277,7 +293,6 @@
stat |= BROKEN stat |= BROKEN
wires.RandomCutAll() wires.RandomCutAll()
kick_viewers()
triggerCameraAlarm() triggerCameraAlarm()
update_icon() update_icon()
update_coverage() update_coverage()
@@ -292,26 +307,12 @@
if (status != newstatus) if (status != newstatus)
status = newstatus status = newstatus
update_coverage() update_coverage()
// now disconnect anyone using the camera
//Apparently, this will disconnect anyone even if the camera was re-activated.
//I guess that doesn't matter since they couldn't use it anyway?
kick_viewers()
/obj/machinery/camera/check_eye(mob/user) /obj/machinery/camera/check_eye(mob/user)
if(!can_use()) return -1 if(!can_use()) return -1
if(isXRay()) return SEE_TURFS|SEE_MOBS|SEE_OBJS if(isXRay()) return SEE_TURFS|SEE_MOBS|SEE_OBJS
return 0 return 0
//This might be redundant, because of check_eye()
/obj/machinery/camera/proc/kick_viewers()
for(var/mob/O in player_list)
if (istype(O.machine, /obj/machinery/computer/security))
var/obj/machinery/computer/security/S = O.machine
if (S.current_camera == src)
O.unset_machine()
O.reset_view(null)
O << "The screen bursts into static."
/obj/machinery/camera/update_icon() /obj/machinery/camera/update_icon()
if (!status || (stat & BROKEN)) if (!status || (stat & BROKEN))
icon_state = "[initial(icon_state)]1" icon_state = "[initial(icon_state)]1"

View File

@@ -26,9 +26,9 @@ var/global/list/engineering_networks = list(
NETWORK_ENGINE, NETWORK_ENGINE,
NETWORK_ENGINEERING, NETWORK_ENGINEERING,
NETWORK_ENGINEERING_OUTPOST, NETWORK_ENGINEERING_OUTPOST,
"Atmosphere Alarms", NETWORK_ALARM_ATMOS,
"Fire Alarms", NETWORK_ALARM_FIRE,
"Power Alarms") NETWORK_ALARM_POWER)
/obj/machinery/camera/network/crescent /obj/machinery/camera/network/crescent
network = list(NETWORK_CRESCENT) network = list(NETWORK_CRESCENT)

View File

@@ -108,7 +108,7 @@
list("cat" = "Science", "jobs" = format_jobs(science_positions)), list("cat" = "Science", "jobs" = format_jobs(science_positions)),
list("cat" = "Security", "jobs" = format_jobs(security_positions)), list("cat" = "Security", "jobs" = format_jobs(security_positions)),
list("cat" = "Cargo", "jobs" = format_jobs(cargo_positions)), list("cat" = "Cargo", "jobs" = format_jobs(cargo_positions)),
list("cat" = "Planetside", "jobs" = format_jobs(planet_positions)), list("cat" = "Exploration", "jobs" = format_jobs(planet_positions)), //VOREStation Edit
list("cat" = "Civilian", "jobs" = format_jobs(civilian_positions)), list("cat" = "Civilian", "jobs" = format_jobs(civilian_positions)),
list("cat" = "CentCom", "jobs" = format_jobs(get_all_centcom_jobs())) list("cat" = "CentCom", "jobs" = format_jobs(get_all_centcom_jobs()))
) )

View File

@@ -531,6 +531,13 @@
message_admins("[key_name_admin(user)] has recalled the shuttle.", 1) message_admins("[key_name_admin(user)] has recalled the shuttle.", 1)
return return
/proc/is_relay_online()
for(var/obj/machinery/telecomms/relay/M in world)
if(M.stat == 0)
return 1
return 0
/obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2) /obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2)
var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435)

View File

@@ -18,6 +18,12 @@
clicksound = null clicksound = null
var/obj/item/weapon/card/id/card // Inserted Id card var/obj/item/weapon/card/id/card // Inserted Id card
var/obj/item/device/radio/intercom/announce // Integreated announcer
/obj/machinery/computer/timeclock/New()
announce = new /obj/item/device/radio/intercom(src)
..()
/obj/machinery/computer/timeclock/Destroy() /obj/machinery/computer/timeclock/Destroy()
if(card) if(card)
@@ -84,9 +90,10 @@
"head_position" = job.head_position, "head_position" = job.head_position,
"timeoff_factor" = job.timeoff_factor "timeoff_factor" = job.timeoff_factor
) )
// TODO - Once job changing is implemented, we will want to list jobs to change into. if(config.time_off && config.pto_job_change)
// if(job && job.timeoff_factor < 0) // Currently are Off Duty, so gotta lookup what on-duty jobs are open data["allow_change_job"] = TRUE
// data["job_choices"] = getOpenOnDutyJobs(user, job.department) if(job && job.timeoff_factor < 0) // Currently are Off Duty, so gotta lookup what on-duty jobs are open
data["job_choices"] = getOpenOnDutyJobs(user, job.department)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui) if (!ui)
@@ -101,7 +108,7 @@
src.add_fingerprint(usr) src.add_fingerprint(usr)
if (href_list["id"]) if (href_list["id"])
if (card) if(card)
usr.put_in_hands(card) usr.put_in_hands(card)
card = null card = null
else else
@@ -110,8 +117,103 @@
I.forceMove(src) I.forceMove(src)
card = I card = I
update_icon() update_icon()
return 1
if(href_list["switch-to-onduty"])
if(card)
if(checkCardCooldown())
makeOnDuty(href_list["switch-to-onduty"])
usr.put_in_hands(card)
card = null
update_icon()
return 1
if(href_list["switch-to-offduty"])
if(card)
if(checkCardCooldown())
makeOffDuty()
usr.put_in_hands(card)
card = null
update_icon()
return 1
return 1 // Return 1 to update UI return 1 // Return 1 to update UI
/obj/machinery/computer/timeclock/proc/getOpenOnDutyJobs(var/mob/user, var/department)
var/list/available_jobs = list()
for(var/datum/job/job in job_master.occupations)
if(job && job.is_position_available() && !job.whitelist_only && !jobban_isbanned(user,job.title) && job.player_old_enough(user.client))
if(job.department == department && !job.disallow_jobhop && job.timeoff_factor > 0)
available_jobs += job.title
if(job.alt_titles)
for(var/alt_job in job.alt_titles)
available_jobs += alt_job
return available_jobs
/obj/machinery/computer/timeclock/proc/makeOnDuty(var/newjob)
var/datum/job/foundjob = null
for(var/datum/job/job in job_master.occupations)
if(newjob == job.title)
foundjob = job
break
if(newjob in job.alt_titles)
foundjob = job
break
if(!newjob in getOpenOnDutyJobs(usr, job_master.GetJob(card.rank).department))
return
if(foundjob && card)
card.access = foundjob.get_access()
card.rank = foundjob.title
card.assignment = newjob
card.name = text("[card.registered_name]'s ID Card ([card.assignment])")
data_core.manifest_modify(card.registered_name, card.assignment)
card.last_job_switch = world.time
callHook("reassign_employee", list(card))
foundjob.current_positions++
announce.autosay("[card.registered_name] has moved On-Duty as [card.assignment].", "Employee Oversight")
return
/obj/machinery/computer/timeclock/proc/makeOffDuty()
var/datum/job/foundjob = null
for(var/datum/job/job in job_master.occupations)
if(card.rank == job.title)
foundjob = job
break
if(!foundjob)
return
var/real_dept = foundjob.department
if(real_dept && real_dept == "Command")
real_dept = "Civilian"
var/datum/job/ptojob = null
for(var/datum/job/job in job_master.occupations)
if(job.department == real_dept && job.timeoff_factor < 0)
ptojob = job
break
if(ptojob && card)
var/oldtitle = card.assignment
card.access = ptojob.get_access()
card.rank = ptojob.title
card.assignment = ptojob.title
card.name = text("[card.registered_name]'s ID Card ([card.assignment])")
data_core.manifest_modify(card.registered_name, card.assignment)
card.last_job_switch = world.time
callHook("reassign_employee", list(card))
foundjob.current_positions--
announce.autosay("[card.registered_name], [oldtitle], has moved Off-Duty.", "Employee Oversight")
return
/obj/machinery/computer/timeclock/proc/checkCardCooldown()
if(!card)
return FALSE
if((world.time - card.last_job_switch) < 15 MINUTES)
to_chat(usr, "You need to wait at least 15 minutes after last duty switch.")
return FALSE
return TRUE
/obj/item/weapon/card/id
var/last_job_switch
/obj/item/weapon/card/id/New()
.=..()
last_job_switch = world.time
// //
// Frame type for construction // Frame type for construction
// //
@@ -144,4 +246,4 @@
/obj/machinery/computer/timeclock/premade/west /obj/machinery/computer/timeclock/premade/west
dir = 4 dir = 4
pixel_x = -26 pixel_x = -26

View File

@@ -1,233 +0,0 @@
/*
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 = "<table border='0' align='left'>"
var/i = 0
for(var/datum/file/F in filelist)
if(!F.hidden_file)
i++
if(i==1)
dat += "<tr>"
if(i>= 6)
i = 0
dat += "</tr>"
continue
dat += {"
<td>
<center><a href='?src=\ref[src];[fileop]=\ref[F]'>
<img src=\ref[F.image]><br>
<span>[F.name]</span>
</a></center>
</td>"}
dat += "</tr></table>"
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 = "<table border='0' align='left'>"
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 += "<tr>"
if(i>= 6)
i = 0
dat += "</tr>"
continue
dat += {"
<td>
<a href='?src=\ref[src];[peripheralop]=\ref[C]'>
\icon[C]<br>
<span>[C.name]</span>
</a>
</td>"}
dat += "</tr></table>"
return dat
/datum/file/program/ntos/proc/window(var/title,var/buttonbar,var/content)
return {"
<div class='filewin'>
<div class='titlebar'>[title] <a href='?src=\ref[src];winclose'><img src=\ref['icons/ntos/tb_close.png']></a></div>
<div class='buttonbar'>[buttonbar]</div>
<div class='contentpane'>[content]</div>
</div>"}
/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 = {"
<html>
<head>
<title>Operating System</title>
<style>
div.filewin {
position:absolute;
left:80px;
top:114px;
width:480px;
height:360px;
border:2px inset black;
background-color:#F0F0F0;
overflow:auto
}
div.titlebar {
position:fixed;
left:80px;
top:60px;
width:480px;
height:18px;
padding:1px;
padding-left:8px;
border:none;
background-color:#2020a0;
color:#FFFFFF;
z-index:5
}
.titlebar a {
position:absolute;
right:4px;
display: block;
width:16px;
height:100%;
background-color:#000000;
color:#808080;
}
div.buttonbar {
position:fixed;
left:80px;
top:78px;
width:480px;
height:36px;
padding:2px;
background-color:#f0d0d0;
}
div.contentpane {
padding:4px;
width:100%;
height:100%
}
table a {
display: block;
height: 100%;
width: 100%;
text-decoration: none;
color: black;
text-align:center;
}
table span {
background-color: #E0E0E0;
font-family: verdana;
font-size: 12px;
}
td {
width: 64;
height: 64;
overflow: hidden;
valign: "top";
}
a img {
border: none;
}
</style>
</head>
<body><div style='width:640px;height:480px; border:2px solid black;padding:8px;background-position:center;background-image:url(\ref['nano/images/uiBackground.png'])'>"}
dat += generate_status_bar()
var/list/files = list_files()
if(current)
dat +=window(current.name,buttonbar(),filegrid(files))
else
dat += desktop()
dat += "</div></body></html>"
usr << browse(dat, "window=\ref[computer];size=670x510")
onclose(usr, "\ref[computer]")
// STATUS BAR
// Small 16x16 icons representing status of components, etc.
// Currently only used by battery icon
// TODO: Add more icons!
/datum/file/program/ntos/proc/generate_status_bar()
var/dat = ""
// Battery level icon
switch(computer.check_battery_status())
if(-1)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_none.gif']>"
if(0 to 5)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_5.gif']>"
if(6 to 20)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_20.gif']>"
if(21 to 40)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_40.gif']>"
if(41 to 60)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_60.gif']>"
if(61 to 80)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_80.gif']>"
if(81 to 100)
dat += "<img src=\ref['icons/ntos/battery_icons/batt_100.gif']>"
dat += "<br>"
return dat
/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"]) in src.computer
if(!istype(C))
return
if(istype(C,/obj/item/part/computer/storage))
current = C
interact()
return
// else ???
if(istype(C,/obj/item/part/computer/cardslot))
computer.cardslot.remove(usr)
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

View File

@@ -1,176 +0,0 @@
/*
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().
*/
/obj/machinery/computer3/proc/interactable(var/mob/user)
if( !src || !user || stat || user.stat || user.lying || user.blinded )
return 0
if(!program)
return 0
if(!isturf(loc) || !isturf(user.loc)) // todo handheld maybe
return 0
if(user.restrained())
to_chat(user, "<span class='warning'>You need a free hand!</span>")
return 0
if(issilicon(user) &&!program.ai_allowed )
to_chat(user, "<span class='warning'>You are forbidden from accessing this program.</span>")
return 0
if(!ishuman(user) && program.human_controls)
to_chat(user, "<span class='warning'>Your body can't work the controls!</span>")
return 0
if(!in_range(src,user) && (!program.human_controls || !istype(user.get_active_hand(),/obj/item/tk_grab)))
// telekinesis check
to_chat(user, "<span class='warning'>It's too complicated to work at a distance!</span>")
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.
*/
/obj/machinery/computer3/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
*/
/obj/machinery/computer3/check_eye(var/mob/user as mob)
if(!interactable(user) || user.machine != src)
if(user.machine == src)
user.unset_machine()
return -1
var/datum/file/program/security/S = program
if( !istype(S) || !S.current || !S.current.status || !camnet )
if( user.machine == src )
user.unset_machine()
return -1
user.reset_view(S.current, 0)
return 0
/*
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?)
*/
/obj/machinery/computer3/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
*/
/obj/machinery/computer3/proc/Crash(var/errorcode = PROG_CRASH)
if(!src)
return null
switch(errorcode)
if(PROG_CRASH)
if(usr)
usr << "<span class='warning'>The program crashed!</span>"
usr << browse(null,"\ref[src]")
Reset()
if(MISSING_PERIPHERAL)
Reset()
if(usr)
usr << browse("<h2>ERROR: Missing or disabled component</h2><b>A hardware failure has occured. Please insert or replace the missing or damaged component and restart the computer.</b>","window=\ref[src]")
if(BUSTED_ASS_COMPUTER)
Reset()
os.error = BUSTED_ASS_COMPUTER
if(usr)
usr << browse("<h2>ERROR: Missing or disabled component</h2><b>A hardware failure has occured. Please insert or replace the missing or damaged component and restart the computer.</b>","window=\ref[src]")
if(MISSING_PROGRAM)
Reset()
if(usr)
usr << browse("<h2>ERROR: No associated program</h2><b>This file requires a specific program to open, which cannot be located. Please install the related program and try again.</b>","window=\ref[src]")
if(FILE_DRM)
Reset()
if(usr)
usr << browse("<h2>ERROR: File operation prohibited</h2><b>Copy protection exception: missing authorization token.</b>","window=\ref[src]")
if(NETWORK_FAILURE)
Reset()
if(usr)
usr << browse("<h2>ERROR: Networking exception: Unable to connect to remote host.</h2>","window=\ref[src]")
else
if(usr)
usr << "<span class='warning'>The program crashed!</span>"
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
/obj/machinery/computer3/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) && istype(cardslot, /obj/item/part/computer/cardslot/dual))
var/obj/item/part/computer/cardslot/dual/D = cardslot
if(D.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(istype(cardslot, /obj/item/part/computer/cardslot/dual))
var/obj/item/part/computer/cardslot/dual/D = cardslot
if(D.addfile(F))
return 1
if(hdd && hdd.addfile(F))
return 1
return 0

View File

@@ -1,303 +0,0 @@
// Computer3 circuitboard specifically
/obj/item/part/computer/circuitboard
density = 0
anchored = 0
w_class = ITEMSIZE_SMALL
name = "Circuit board"
icon = 'icons/obj/module.dmi'
icon_state = "id_mod"
item_state = "electronic"
origin_tech = list(TECH_DATA = 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/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(P.is_wrench())
playsound(src.loc, P.usesound, 50, 1)
if(do_after(user, 20 * P.toolspeed))
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
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))
to_chat(user, "The welding tool must be on to complete this task.")
return
playsound(src.loc, WT.usesound, 50, 1)
if(do_after(user, 20 * WT.toolspeed))
if(!src || !WT.isOn()) return
to_chat(user, "<span class='notice'>You deconstruct the frame.</span>")
new /obj/item/stack/material/steel( src.loc, 5 )
qdel(src)
if(1)
if(P.is_wrench())
playsound(src.loc, P.usesound, 50, 1)
if(do_after(user, 20 * P.toolspeed))
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
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)
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
src.icon_state = "1"
src.circuit = P
user.drop_item()
P.loc = src
else
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
if(P.is_screwdriver() && circuit)
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
src.state = 2
src.icon_state = "2"
if(P.is_crowbar() && circuit)
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
src.state = 1
src.icon_state = "0"
circuit.loc = src.loc
src.circuit = null
if(2)
if(P.is_screwdriver() && circuit)
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
src.state = 1
src.icon_state = "1"
if(P.is_crowbar())
if(battery)
playsound(src.loc, P.usesound, 50, 1)
if(do_after(10 * P.toolspeed))
battery.loc = loc
to_chat(user, "<span class='notice'>You remove [battery].</span>")
battery = null
else
to_chat(user, "<span class='warning'>There's no battery to remove!</span>")
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
to_chat(user, "<span class='notice'>You insert [battery].</span>")
else
to_chat(user, "<span class='warning'>There's already \an [battery] in [src]!</span>")
if(istype(P, /obj/item/stack/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) qdel(P)
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
src.state = 3
src.icon_state = "3"
if(3)
if(P.is_wirecutter())
if(components.len)
to_chat(user, "There are parts in the way!")
return
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the cables.</span>")
src.state = 2
src.icon_state = "2"
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( src.loc )
A.amount = 5
if(P.is_crowbar())
remove_peripheral()
if(istype(P, /obj/item/stack/material) && P.get_material_name() == "glass")
var/obj/item/stack/S = P
if(S.amount >= 2)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20))
if(S)
S.use(2)
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
src.state = 4
src.icon_state = "4"
if(4)
if(P.is_crowbar())
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
src.state = 3
src.icon_state = "3"
new /obj/item/stack/material/glass( src.loc, 2 )
if(P.is_screwdriver())
playsound(src.loc, P.usesound, 50, 1)
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
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
qdel(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)
to_chat(usr, "<span class='warning'>There are no components in [src] to take out!</span>")
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
to_chat(usr, "<span class='notice'>You remove [I]</span>")
return 1
return 0
/obj/structure/computer3frame/proc/insert_peripheral(var/obj/item/I)
if(components.len >= max_components)
to_chat(usr, "There isn't room in [src] for another component!")
return 0
switch(I.type)
if(/obj/item/part/computer/storage/hdd)
if(hdd)
to_chat(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)
to_chat(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)
to_chat(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)
to_chat(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)
to_chat(usr, "There is already \an [net] in [src]!")

View File

@@ -1,230 +0,0 @@
/*
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 = ITEMSIZE_SMALL
var/emagged = 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()
/obj/item/part/computer/proc/allow_attackby(var/obj/item/I, var/mob/user)
for(var/typepath in attackby_types)
if(istype(I, typepath))
return 1
return 0
/obj/item/part/computer/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 = "intelliCore 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
/obj/item/part/computer/ai_holder/attackby(obj/I as obj,mob/user as mob)
if(computer && !computer.stat)
if(istype(I, /obj/item/device/aicard))
var/obj/item/device/aicard/card = I
var/mob/living/silicon/ai/comp_ai = locate() in src
var/mob/living/silicon/ai/card_ai = locate() in card
if(istype(comp_ai))
if(busy)
to_chat(user, "<span class='danger'>ERROR:</span> Reconstruction in progress.")
return
if(card.grab_ai(comp_ai, user))
occupant = null
else if(istype(card_ai))
load_ai(card_ai,card,user)
if(computer.program)
computer.program.update_icon()
computer.update_icon()
..()
return
/obj/item/part/computer/ai_holder/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user)
if(!istype(transfer))
return
// Transfer over the AI.
to_chat(transfer, "You have been transferred into a mobile terminal. Sadly, there is no remote access from here.")
to_chat(user, "<span class='notice'>Transfer successful:</span> [transfer.name] placed within mobile terminal.")
transfer.loc = src
transfer.cancel_camera()
transfer.control_disabled = 1
occupant = transfer
if(card)
card.clear()
/*
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
attackby_types = list(/obj/item/weapon/card)
/obj/item/part/computer/cardslot/attackby(var/obj/item/I as obj, var/mob/user)
if(istype(I,/obj/item/weapon/card) && computer)
if(istype(I,/obj/item/weapon/card/emag) && !reader) // emag reader slot
user.visible_message("[computer]'s screen flickers for a moment.","You insert \the [I]. After a moment, the card ejects itself, and [computer] beeps.","[computer] beeps.")
computer.emagged = 1
return
insert(I, user)
return
..(I,user)
// cardslot.insert(card, slot)
// card: The card obj you want to insert (usually your ID)
// user: The mob inserting the card
/obj/item/part/computer/cardslot/proc/insert(var/obj/item/weapon/card/card, var/mob/user)
if(equip_to_reader(card, user))
to_chat(user, "You insert the card into reader slot")
return 1
to_chat(user, "There is already something in the reader slot.")
return 0
// Usage of insert() preferred, as it also tells result to the user.
/obj/item/part/computer/cardslot/proc/equip_to_reader(var/obj/item/weapon/card/card, var/mob/living/L)
if(!reader)
L.drop_item()
card.loc = src
reader = card
return 1
return 0
// cardslot.remove(slot)
// user: The mob removing the card
/obj/item/part/computer/cardslot/proc/remove(var/mob/user)
if(remove_reader(user))
to_chat(user, "You remove the card from reader slot")
return 1
to_chat(user, "There is nothing in the reader slot")
return 0
/obj/item/part/computer/cardslot/proc/remove_reader(var/mob/living/L)
if(reader)
if(ishuman(L) && !L.get_active_hand())
L.put_in_hands(reader)
else
reader.loc = get_turf(computer)
reader = null
return 1
return 0
// Authorizes the user based on the computer's requirements
/obj/item/part/computer/cardslot/proc/authenticate()
return computer.check_access(reader)
/obj/item/part/computer/cardslot/dual
name = "magnetic card reader"
desc = "Contains slots for inserting magnetic swipe cards for reading and writing."
var/obj/item/weapon/card/writer = null
// Ater: Single- and dual-slot card readers have separate functions.
// According to OOP principles, they should be separate classes and use inheritance, polymorphism.
/obj/item/part/computer/cardslot/dual/proc/equip_to_writer(var/obj/item/weapon/card/card, var/mob/living/L)
if(!writer)
L.drop_item()
card.loc = src
writer = card
return 1
return 0
/obj/item/part/computer/cardslot/dual/proc/remove_from_writer(var/mob/living/L)
if(writer)
if(ishuman(L) && !L.get_active_hand())
L.put_in_hands(writer)
else
writer.loc = get_turf(computer)
writer = null
return 1
return 0
// cardslot.insert(card, slot)
// card: The card obj you want to insert (usually your ID)
// user: The mob inserting the card
// slot: Which slot to insert into (1->Reader, 2->Writer, 3->Auto) Default 3
/obj/item/part/computer/cardslot/dual/insert(var/obj/item/weapon/card/card, var/mob/user, var/slot = 3)
if(slot != 2)
if(..(card, user))
return 1
if(slot != 1)
if(equip_to_writer(card, user))
to_chat(user, "You insert the card into writer slot")
return 1
else
to_chat(user, "There is already something in the writer slot.")
return 0
// cardslot/dual.insert(card, slot)
// user: The mob removing the card
// slot: Which slot to remove from (1->Reader, 2->Writer, 3->Both, 4->Reader and if empty, Writer) Default 3
/obj/item/part/computer/cardslot/dual/remove(var/mob/user, var/slot = 3)
if(slot != 2)
if(..(user) && slot != 3) // ..() probes reader
return 1 // slot is either 1 or 4, where we only probe reader if there's anything in it
if(slot != 1) // If slot is 1, then we only probe reader
if(remove_from_writer(user)) // Probe writer
to_chat(user, "You remove the card from the writer slot")
return 1
to_chat(user, "There is nothing in the writer slot.")
return 0
/obj/item/part/computer/cardslot/dual/proc/addfile(var/datum/file/F)
if(!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

View File

@@ -1,459 +0,0 @@
/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/circuitb
// 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
// 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
/obj/machinery/computer3/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(!circuitb || !istype(circuitb))
circuitb = new(src)
if(circuitb.OS)
os = circuitb.OS
circuitb.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
circuitb.OS = P
circuitb.OS.computer = src
os = circuitb.OS
circuitb.name = "Circuitboard ([P])"
if(hdd) // Spawn files
for(var/typekey in spawn_files)
hdd.addfile(new typekey,1)
update_icon()
/obj/machinery/computer3/verb/ResetComputer()
set name = "Reset Computer"
set category = "Object"
set src in view(1)
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
to_chat(usr, "<span class='warning'>You can't do that.</span>")
return
if(!Adjacent(usr))
to_chat(usr, "You can't reach it.")
return
Reset()
/obj/machinery/computer3/proc/update_spawn_files()
for(var/typekey in spawn_files)
hdd.addfile(new typekey,1)
/obj/machinery/computer3/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)
continue
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
/obj/machinery/computer3/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
/obj/machinery/computer3/emp_act(severity)
if(prob(20/severity)) set_broken()
..()
/obj/machinery/computer3/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
return
if(2.0)
if (prob(25))
qdel(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
/*
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
*/
/obj/machinery/computer3/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
/obj/machinery/computer3/use_power(var/amount, var/chan = -1)
if(chan == -1)
chan = power_channel
var/area/A = get_area(loc)
if(istype(A) && A.powered(chan))
A.use_power(amount, chan)
else if(battery && battery.charge > 0)
battery.use(amount)
/obj/machinery/computer3/power_change()
if( !powered(power_channel) && (!battery || battery.charge <= 0) )
stat |= NOPOWER
else
stat &= ~NOPOWER
/obj/machinery/computer3/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
/obj/machinery/computer3/proc/set_broken()
icon_state = "computer_b"
stat |= BROKEN
if(program)
program.error = BUSTED_ASS_COMPUTER
if(os)
os.error = BUSTED_ASS_COMPUTER
/obj/machinery/computer3/attackby(obj/item/I as obj, mob/user as mob)
if(I.is_screwdriver() && allow_disassemble)
disassemble(user)
return
/*
+++++++++++
|IMPORTANT| If you add a peripheral, put it in this list
+++++++++++ --------------------------------------------
*/
var/list/p_list = list()
for(var/obj/item/part/computer/C in src)
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
..()
/obj/machinery/computer3/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
to_chat(user, "\The [src] won't boot!")
/obj/machinery/computer3/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
to_chat(user, "\The [src] won't boot!")
/obj/machinery/computer3/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
/obj/machinery/computer3/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)"
//Returns percentage of battery charge remaining. Returns -1 if no battery is installed.
/obj/machinery/computer3/proc/check_battery_status()
if (battery)
var/obj/item/weapon/cell/B = battery
return round(B.charge / (B.maxcharge / 100))
else
return -1
/obj/machinery/computer3/wall_comp
name = "terminal"
icon = 'icons/obj/computer3.dmi'
icon_state = "wallframe"
density = 0
pixel_y = -3
show_keyboard = 0

View File

@@ -1,34 +0,0 @@
/*
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, ???)
*/

View File

@@ -1,245 +0,0 @@
/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
/datum/file/program/holodeck/interact()
if(!interactable())
return
var/dat = "<h3>Current Loaded Programs</h3>"
dat += "<A href='?src=\ref[src];emptycourt'>((Empty Court))</A><BR>"
dat += "<A href='?src=\ref[src];boxingcourt'>((Boxing Court))</A><BR>"
dat += "<A href='?src=\ref[src];basketball'>((Basketball Court))</A><BR>"
dat += "<A href='?src=\ref[src];thunderdomecourt'>((Thunderdome Court))</A><BR>"
dat += "<A href='?src=\ref[src];beach'>((Beach))</A><BR>"
// dat += "<A href='?src=\ref[src];turnoff'>((Shutdown System))</A><BR>"
dat += "<span class='notice'>Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.</span><BR>"
if(emagged)
dat += "<A href='?src=\ref[src];burntest'>(<font color=red>Begin Atmospheric Burn Simulation</font>)</A><BR>"
dat += "Ensure the holodeck is empty before testing.<BR>"
dat += "<BR>"
dat += "<A href='?src=\ref[src];wildlifecarp'>(<font color=red>Begin Wildlife Simulation</font>)</A><BR>"
dat += "Ensure the holodeck is empty before testing.<BR>"
dat += "<BR>"
if(issilicon(usr))
dat += "<A href='?src=\ref[src];AIoverride'>(<font color=green>Re-Enable Safety Protocols?</font>)</A><BR>"
dat += "Safety Protocols are <font class='bad'>DISABLED</font><BR>"
else
if(issilicon(usr))
dat += "<A href='?src=\ref[src];AIoverride'>(<font color=red>Override Safety Protocols?</font>)</A><BR>"
dat += "<BR>"
dat += "Safety Protocols are <font class='good'>ENABLED</font><BR>"
popup.set_content(dat)
popup.open()
return
/datum/file/program/holodeck/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
/datum/file/program/holodeck/Reset()
emergencyShutdown()
/datum/file/program/holodeck/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)
/datum/file/program/holodeck/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.remove_from_mob(obj)
if(!silent)
var/obj/oldobj = obj
obj.visible_message("The [oldobj.name] fades away!")
qdel(obj)
/datum/file/program/holodeck/proc/checkInteg(var/area/A)
for(var/turf/T in A)
if(istype(T, /turf/space))
return 0
return 1
/datum/file/program/holodeck/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
/datum/file/program/holodeck/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("<span class='warning'>ERROR. Recalibrating projetion apparatus.</span>")
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)
qdel(B)
for(var/mob/living/simple_mob/animal/space/carp/C in linkedholodeck)
qdel(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_mob/animal/space/carp(L.loc)
/datum/file/program/holodeck/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

View File

@@ -1,47 +0,0 @@
/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 += "<B>Patient information:</B><BR>"
if(src.table && (src.table.check_victim()))
src.patient = src.table.victim
dat += {"<B>Patient Status:</B> [patient.stat ? "Non-Responsive" : "Stable"]<BR>
<B>Blood Type:</B> [patient.b_type]<BR>
<BR>
<B>Health:</B> [round(patient.health)]<BR>
<B>Brute Damage:</B> [round(patient.getBruteLoss())]<BR>
<B>Toxins Damage:</B> [round(patient.getToxLoss())]<BR>
<B>Fire Damage:</B> [round(patient.getFireLoss())]<BR>
<B>Suffocation Damage:</B> [round(patient.getOxyLoss())]<BR>
"}
else
src.patient = null
dat += "<B>No patient detected</B>"
else
dat += "<B>Operating table not found.</B>"
popup.set_content(dat)
popup.open()
/datum/file/program/op_monitor/Topic()
if(!interactable())
return
..()

View File

@@ -1,183 +0,0 @@
/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/weapon/gun/projectile/revolver/capgun = 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
)
/obj/item/part/computer/toybox/allow_attackby(var/obj/item/I, var/mob/user)
return 0
/obj/item/part/computer/toybox/proc/dispense()
if(computer && !computer.stat)
var/prizeselect = pickweight(prizes)
new prizeselect(computer.loc)
if(istype(prizeselect, /obj/item/weapon/gun/projectile/revolver/capgun)) //Ammo comes with the gun
new /obj/item/projectile/bullet/pistol/cap(src.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 the Company'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 = "<center><h4>[enemy_name]</h4></center>"
dat += "<br><center><h3>[temp]</h3></center>"
dat += "<br><center>Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]</center>"
dat += "<center><b>"
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 += "</b></center>"
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

View File

@@ -1,100 +0,0 @@
/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
/datum/file/program/atmos_alert/execute(var/datum/file/program/source)
..(source)
if(!computer.radio)
computer.Crash(MISSING_PERIPHERAL)
computer.radio.set_frequency(1437,RADIO_ATMOSIA)
// This will be called as long as the program is running on the parent computer
// and the computer has the radio peripheral
/datum/file/program/atmos_alert/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_air_alarms -= zone
priority_air_alarms -= zone
if(severity=="severe")
priority_air_alarms += zone
else if (severity=="minor")
minor_air_alarms += zone
update_icon()
return
/datum/file/program/atmos_alert/interact()
if(!interactable())
return
if(!computer.radio)
computer.Crash(MISSING_PERIPHERAL)
popup.set_content(return_text())
popup.open()
/datum/file/program/atmos_alert/update_icon()
..()
if(priority_air_alarms.len > 0)
overlay.icon_state = "alert:2"
else if(minor_air_alarms.len > 0)
overlay.icon_state = "alert:1"
else
overlay.icon_state = "alert:0"
if(computer)
computer.update_icon()
/datum/file/program/atmos_alert/proc/return_text()
var/priority_text = "<h2>Priority Alerts:</h2>"
var/minor_text = "<h2>Minor Alerts:</h2>"
if(priority_air_alarms.len)
for(var/zone in priority_air_alarms)
priority_text += "<FONT color='red'><B>[format_text(zone)]</B></FONT> [topic_link(src,"priority_clear=[ckey(zone)]","X")]<BR>"
else
priority_text += "No priority alerts detected.<BR>"
if(minor_air_alarms.len)
for(var/zone in minor_air_alarms)
minor_text += "<B>[format_text(zone)]</B> [topic_link(src,"minor_clear=[ckey(zone)]","X")]<BR>"
else
minor_text += "No minor alerts detected.<BR>"
return "[priority_text]<BR><HR>[minor_text]<BR>[topic_link(src,"close","Close")]"
/datum/file/program/atmos_alert/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_air_alarms)
if(ckey(zone) == removing_zone)
to_chat(usr, "<span class='notice'>Priority Alert for area [zone] cleared.</span>")
priority_air_alarms -= zone
if("minor_clear" in href_list)
var/removing_zone = href_list["minor_clear"]
for(var/zone in minor_air_alarms)
if(ckey(zone) == removing_zone)
to_chat(usr, "<span class='notice'>Minor Alert for area [zone] cleared.</span>")
minor_air_alarms -= zone
computer.updateUsrDialog()

View File

@@ -1,352 +0,0 @@
/*
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
/obj/machinery/computer3/security/wooden_tv/New()
..(built=0)
os = program
circuitb.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/networks = list("ALL") // A little workaround as it is not possible to place station_networks here
var/screen = "cameras"
/datum/file/camnet_key/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/New()
for(var/N in networks)
if(N == "ALL")
networks = using_map.station_networks
break
return ..()
/datum/file/camnet_key/mining
name = "Mining Camera Network Key"
title = "mining station"
desc = "Connects to mining security cameras."
networks = list(NETWORK_MINE)
screen = "miningcameras"
/datum/file/camnet_key/research
name = "Research Camera Network Key"
title = "research"
networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/bombrange
name = "R&D Bomb Range Camera Network Key"
title = "bomb range"
desc = "Monitors the bomb range."
networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/xeno
name = "R&D Misc. Research Camera Network Key"
title = "special research"
networks = list(NETWORK_RESEARCH)
/datum/file/camnet_key/singulo
name = "Singularity Camera Network Key"
title = "singularity"
networks = list(NETWORK_ENGINE)
/datum/file/camnet_key/entertainment
name = "Entertainment Channel Encryption Key"
title = "entertainment"
desc = "Damn, I hope they have /tg/thechannel on here."
networks = list(NETWORK_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(NETWORK_ERT)
/datum/file/camnet_key/prison
name = "Prison Camera Network Key"
title = "prison"
desc = "Monitors the prison."
networks = list(NETWORK_SECURITY)
/datum/file/camnet_key/syndicate
name = "Camera Network Key"
title = "%!#BUFFER OVERFLOW"
desc = "Connects to security cameras."
networks = list("ALL")
hidden_file = 1
/*
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)
/obj/item/part/computer/networking/cameras/get_machines(var/datum/file/camnet_key/key)
if (!computer || computer.z > 6)
return null
cameranet.process_sort()
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)
return L
/obj/item/part/computer/networking/cameras/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 = "Connects to the station 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
/datum/file/program/security/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)
/datum/file/program/security/Reset()
..()
reset_current()
for(var/mob/living/L in viewers(1))
if(!istype(L,/mob/living/silicon/ai) && L.machine == src)
L.reset_view(null)
/datum/file/program/security/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 \]")]<hr>"
for(var/obj/machinery/camera/C in temp_list)
if(C.can_use())
camera_list += "[C.c_tag] - [topic_link(src,"show=\ref[C]","Show")]<br>"
else
camera_list += "[C.c_tag] - <b>DEACTIVATED</b><br>"
//camera_list += "<br>" + topic_link(src,"close","Close")
popup.set_content(camera_list)
popup.open()
/datum/file/program/security/update_icon()
if(key)
overlay.icon_state = key.screen
name = key.title + " Camera Monitor"
else
overlay.icon_state = "camera-static"
name = initial(name)
/datum/file/program/security/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"])
if(istype(C) && C.can_use())
set_current(C)
usr.reset_view(C)
interact()
return
if("keyselect" in href_list)
reset_current()
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)
select_key(key)
if(key)
interact()
else
to_chat(usr, "The screen turns to static.")
return
/datum/file/program/security/proc/select_key(var/selected_key)
key = selected_key
camera_list = null
update_icon()
computer.update_icon()
/datum/file/program/security/proc/set_current(var/obj/machinery/camera/C)
if(current == C)
return
if(current)
reset_current()
src.current = C
if(current)
var/mob/living/L = current.loc
if(istype(L))
L.tracking_initiated()
/datum/file/program/security/proc/reset_current()
if(current)
var/mob/living/L = current.loc
if(istype(L))
L.tracking_cancelled()
current = null
// Atlantis: Required for camnetkeys to work.
/datum/file/program/security/hidden
hidden_file = 1
/*
Camera monitoring program
Works much as the parent program, except:
* It requires a camera to be found using the proximity network card.
* It begins with all cam-access.
*/
/datum/file/program/security/syndicate
name = "camer# moni!%r"
desc = "Cons the Nanotrash Camera Network"
var/special_key = new/datum/file/camnet_key/syndicate
var/camera_conn = null
/datum/file/program/security/syndicate/interact()
if(!interactable())
return
if(!computer.net)
computer.Crash(MISSING_PERIPHERAL)
return
camera_conn = computer.net.connect_to(/obj/machinery/camera,camera_conn)
if(!camera_conn)
computer.Crash(NETWORK_FAILURE)
return
// On interact, override camera key selection
select_key(special_key)
..()

View File

@@ -1,422 +0,0 @@
/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
var/datum/announcement/priority/crew_announcement = new
/datum/file/program/communications/New()
..()
crew_announcement.newscast = 1
/datum/file/program/communications/Reset()
..()
authenticated = 0
state = STATE_DEFAULT
aistate = STATE_DEFAULT
/datum/file/program/communications/Topic(var/href, var/list/href_list)
if(!interactable() || !computer.radio || ..(href,href_list) )
return
if (computer.z > 1)
to_chat(usr, "<span class='danger'>Unable to establish a connection:</span> 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
crew_announcement.announcer = GetNameAndAssignmentFromId(I)
if(istype(I,/obj/item/weapon/card/emag))
authenticated = 2
computer.emagged = 1
if("logout" in href_list)
authenticated = 0
crew_announcement.announcer = ""
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_YELLOW)
feedback_inc("alert_comms_yellow",1)
if(SEC_LEVEL_VIOLET)
feedback_inc("alert_comms_violet",1)
if(SEC_LEVEL_ORANGE)
feedback_inc("alert_comms_orange",1)
if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1)
tmp_alertlevel = 0
else
to_chat(usr, "You are not authorized to do this.")
tmp_alertlevel = 0
state = STATE_DEFAULT
else
to_chat(usr, "You need to swipe your ID.")
if("announce" in href_list)
if(authenticated==2)
if(message_cooldown)
usr << "Please allow at least one minute to pass between announcements"
return
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement")
if(!input || !interactable())
return
crew_announcement.Announce(input)
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(sanitize(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40)
computer.updateDialog()
if("setmsg2" in href_list)
stat_msg2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40)
computer.updateDialog()
// OMG CENTCOM LETTERHEAD
if("MessageCentCom" in href_list)
if(!computer.radio.subspace)
return
if(authenticated==2)
if(centcomm_message_cooldown)
to_chat(usr, "Arrays recycling. Please stand by.")
return
var/input = sanitize(input("Please choose a message to transmit to [using_map.boss_short] 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
CentCom_announce(input, usr)
to_chat(usr, "Message transmitted.")
log_game("[key_name(usr)] has made a [using_map.boss_short] 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)
to_chat(usr, "Arrays recycling. Please stand by.")
return
var/input = sanitize(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)
to_chat(usr, "Message transmitted.")
log_game("[key_name(usr)] has made an illegal announcement: [input]")
centcomm_message_cooldown = 1
spawn(600)//10 minute cooldown
centcomm_message_cooldown = 0
if("RestoreBackup" in href_list)
to_chat(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()
/datum/file/program/communications/proc/main_menu()
var/dat = ""
if (computer.radio.subspace)
if(emergency_shuttle.online() && emergency_shuttle.location())
var/timeleft = emergency_shuttle.estimate_arrival_time()
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]<BR>"
refresh = 1
else
refresh = 0
if (authenticated)
dat += "<BR>\[ <A HREF='?src=\ref[src];logout'>Log Out</A> \]"
if (authenticated==2)
dat += "<BR>\[ <A HREF='?src=\ref[src];announce'>Make An Announcement</A> \]"
if(computer.emagged == 0)
dat += "<BR>\[ <A HREF='?src=\ref[src];MessageCentCom'>Send an emergency message to [using_map.boss_short]</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];MessageSyndicate'>Send an emergency message to \[UNKNOWN\]</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];RestoreBackup'>Restore Backup Routing Data</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];changeseclevel'>Change alert level</A> \]"
if(emergency_shuttle.location())
if (emergency_shuttle.online())
dat += "<BR>\[ <A HREF='?src=\ref[src];cancelshuttle'>Cancel Shuttle Call</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];callshuttle'>Call Emergency Shuttle</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];status'>Set Status Display</A> \]"
else
dat += "<BR>\[ <A HREF='?src=\ref[src];login'>Log In</A> \]"
dat += "<BR>\[ <A HREF='?src=\ref[src];messagelist'>Message List</A> \]"
return dat
/datum/file/program/communications/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")] \]"
/datum/file/program/communications/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 += "<BR><A HREF='?src=\ref[src];viewmessage;message-num=[i]'>[messagetitle[i]]</A>"
if(STATE_VIEWMESSAGE)
if (currmsg)
dat += "<B>[messagetitle[currmsg]]</B><BR><BR>[messagetext[currmsg]]"
if (authenticated)
dat += "<BR><BR>\[ <A HREF='?src=\ref[src];delmessage'>Delete \]"
else
state = STATE_MESSAGELIST
interact()
return
if(STATE_DELMESSAGE)
if (currmsg)
dat += "Are you sure you want to delete this message? \[ <A HREF='?src=\ref[src];delmessage2'>OK</A> | <A HREF='?src=\ref[src];viewmessage'>Cancel</A> \]"
else
state = STATE_MESSAGELIST
interact()
return
if(STATE_STATUSDISPLAY)
dat += "\[ <A HREF='?src=\ref[src];main'>Back</A> \]<BR>"
dat += "Set Status Displays<BR>"
dat += "\[ <A HREF='?src=\ref[src];setstat;statdisp=blank'>Clear</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];setstat;statdisp=time'>Station Time</A> \]"
dat += "\[ <A HREF='?src=\ref[src];setstat;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];setstat;statdisp=message'>Message</A> \]"
dat += "<ul><li> Line 1: <A HREF='?src=\ref[src];setmsg1'>[ stat_msg1 ? stat_msg1 : "(none)"]</A>"
dat += "<li> Line 2: <A HREF='?src=\ref[src];setmsg2'>[ stat_msg2 ? stat_msg2 : "(none)"]</A></ul><br>"
dat += "\[ Alert: <A HREF='?src=\ref[src];setstat;statdisp=alert;alert=default'>None</A> |"
dat += " <A HREF='?src=\ref[src];setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
dat += " <A HREF='?src=\ref[src];setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
dat += " <A HREF='?src=\ref[src];setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
if(STATE_ALERT_LEVEL)
dat += "Current alert level: [get_security_level()]<BR>"
if(security_level == SEC_LEVEL_DELTA)
dat += "<font color='red'><b>The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate.</b></font>"
else
dat += "<A HREF='?src=\ref[src];securitylevel;newalertlevel=[SEC_LEVEL_BLUE]'>Blue</A><BR>"
dat += "<A HREF='?src=\ref[src];securitylevel;newalertlevel=[SEC_LEVEL_ORANGE]'>Orange</A><BR>"
dat += "<A HREF='?src=\ref[src];securitylevel;newalertlevel=[SEC_LEVEL_VIOLET]'>Violet</A><BR>"
dat += "<A HREF='?src=\ref[src];securitylevel;newalertlevel=[SEC_LEVEL_YELLOW]'>Yellow</A><BR>"
dat += "<A HREF='?src=\ref[src];securitylevel;newalertlevel=[SEC_LEVEL_GREEN]'>Green</A>"
if(STATE_CONFIRM_LEVEL)
dat += "Current alert level: [get_security_level()]<BR>"
dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]<BR>"
dat += "<A HREF='?src=\ref[src];swipeidseclevel'>Swipe ID</A> to confirm change.<BR>"
popup.set_content(dat)
popup.open()
/datum/file/program/communications/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)

View File

@@ -1,76 +0,0 @@
/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( )
/datum/file/program/crew/interact(mob/user)
if(!interactable())
return
scan()
var/t = "<TT><B>Crew Monitoring</B><HR>"
t += "<BR><A href='?src=\ref[src];update=1'>Refresh</A> "
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
t += "<table><tr><td width='40%'>Name</td><td width='20%'>Vitals</td><td width='40%'>Position</td></tr>"
var/list/logs = list()
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)
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 ? "<font color=red>Deceased</font>" : "Living"]"
var/damage_report = "(<font color='blue'>[dam1]</font>/<font color='green'>[dam2]</font>/<font color='orange'>[dam3]</font>/<font color='red'>[dam4]</font>)"
log += "<tr><td width='40%'>[H.get_authentification_name()] ([H.get_assignment()])</td>"
switch(C.sensor_mode)
if(1)
log += "<td width='15%'>[life_status]</td><td width='40%'>Not Available</td></tr>"
if(2)
log += "<td width='20%'>[life_status] [damage_report]</td><td width='40%'>Not Available</td></tr>"
if(3)
var/area/player_area = get_area(H)
log += "<td width='20%'>[life_status] [damage_report]</td><td width='40%'>[sanitize(player_area.name)] ([pos.x], [pos.y])</td></tr>"
logs += log
logs = sortList(logs)
for(var/log in logs)
t += log
t += "</table>"
t += "</TT>"
popup.set_content(t)
popup.open()
/datum/file/program/crew/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
/datum/file/program/crew/Topic(href, list/href_list)
if(!interactable() || !computer.cardslot || ..(href,href_list))
return
if( href_list["close"] )
usr << browse(null, "window=crewcomp")
usr.unset_machine()
return
if(href_list["update"])
interact()
//src.updateUsrDialog()
return

View File

@@ -1,3 +0,0 @@
/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)

View File

@@ -1,84 +0,0 @@
/obj/machinery/computer3/aiupload
name = "AI Upload"
desc = "Used to upload laws to the AI."
icon_state = "frame-rnd"
circuit = /obj/item/weapon/circuitboard/aiupload
var/mob/living/silicon/ai/current = null
var/opened = 0
/obj/machinery/computer3/aiupload/verb/AccessInternals()
set category = "Object"
set name = "Access Computer's Internals"
set src in oview(1)
if(!Adjacent(usr) || usr.restrained() || usr.lying || usr.stat || istype(usr, /mob/living/silicon) || !istype(usr, /mob/living))
return
opened = !opened
if(opened)
to_chat(usr, "<span class='notice'>The access panel is now open.</span>")
else
to_chat(usr, "<span class='notice'>The access panel is now closed.</span>")
return
/obj/machinery/computer3/aiupload/attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob)
if (user.z > 6)
to_chat(user, "<span class='danger'>Unable to establish a connection:</span> You're too far away from the station!")
return
if(istype(module, /obj/item/weapon/aiModule))
module.install(src, user)
else
return ..()
/obj/machinery/computer3/aiupload/attack_hand(var/mob/user as mob)
if(src.stat & NOPOWER)
to_chat(user, "The upload computer has no power!")
return
if(src.stat & BROKEN)
to_chat(user, "The upload computer is broken!")
return
src.current = select_active_ai(user)
if (!src.current)
to_chat(user, "No active AIs detected.")
else
to_chat(user, "[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/weapon/circuitboard/borgupload
var/mob/living/silicon/robot/current = null
/obj/machinery/computer3/borgupload/attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob)
if(istype(module, /obj/item/weapon/aiModule))
module.install(src, user)
else
return ..()
/obj/machinery/computer3/borgupload/attack_hand(var/mob/user as mob)
if(src.stat & NOPOWER)
to_chat(user, "The upload computer has no power!")
return
if(src.stat & BROKEN)
to_chat(user, "The upload computer is broken!")
return
src.current = freeborg()
if (!src.current)
to_chat(user, "No free cyborgs detected.")
else
to_chat(user, "[src.current.name] selected for law changes.")
return

View File

@@ -1,512 +0,0 @@
/*
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)
/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."
active_state = "medcomp"
req_one_access = list(access_medical, access_forensics_lockers)
var/obj/item/weapon/card/id/scan = null
var/obj/item/weapon/card/id/scan2 = 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
/datum/file/program/med_data/proc/authenticate()
if(isAI(usr) || access_medical in scan.access)
return 1
return 0
/datum/file/program/med_data/interact()
if(!computer.cardslot)
computer.Crash(MISSING_PERIPHERAL)
return
usr.set_machine(src)
scan = computer.cardslot.reader
if(!interactable())
return
if(computer.z > 6)
to_chat(usr, "<span class='danger'>Unable to establish a connection:</span> You're too far away from the station!")
return
var/dat
if (temp)
dat = text("<TT>[src.temp]</TT><BR><BR><A href='?src=\ref[src];temp=1'>Clear Screen</A>")
else
dat = text("Confirm Identity (R): <A href='?src=\ref[];cardr=1'>[]</A><HR>", src, (scan ? text("[]", scan.name) : "----------"))
if (istype(computer.cardslot, /obj/item/part/computer/cardslot/dual))
dat += text("Check Identity (W): <A href='?src=\ref[];cardw=1'>[]</A><BR>", src, (scan2 ? text("[]", scan2.name) : "----------"))
if(scan2 && !scan)
dat += text("<div class='notice'>Insert card into reader slot to log in.</div><br>")
if (src.authenticated)
switch(src.screen)
if(1.0)
dat += {"
<A href='?src=\ref[src];search=1'>Search Records</A>
<BR><A href='?src=\ref[src];screen=2'>List Records</A>
<BR>
<BR><A href='?src=\ref[src];screen=5'>Virus Database</A>
<BR><A href='?src=\ref[src];screen=6'>Medbot Tracking</A>
<BR>
<BR><A href='?src=\ref[src];screen=3'>Record Maintenance</A>
<BR><A href='?src=\ref[src];logout=1'>{Log Out}</A><BR>
"}
if(2.0)
dat += "<B>Record List</B>:<HR>"
if(!isnull(data_core.general))
for(var/datum/data/record/R in sortRecord(data_core.general))
dat += text("<A href='?src=\ref[];d_rec=\ref[]'>[]: []<BR>", src, R, R.fields["id"], R.fields["name"])
//Foreach goto(132)
dat += text("<HR><A href='?src=\ref[];screen=1'>Back</A>", src)
if(3.0)
dat += text("<B>Records Maintenance</B><HR>\n<A href='?src=\ref[];back=1'>Backup To Disk</A><BR>\n<A href='?src=\ref[];u_load=1'>Upload From disk</A><BR>\n<A href='?src=\ref[];del_all=1'>Delete All Records</A><BR>\n<BR>\n<A href='?src=\ref[];screen=1'>Back</A>", src, src, src, src)
if(4.0)
dat += "<CENTER><B>Medical Record</B></CENTER><BR>"
if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
var/icon/front = active1.fields["photo_front"]
var/icon/side = active1.fields["photo_side"]
usr << browse_rsc(front, "front.png")
usr << browse_rsc(side, "side.png")
dat += "<table><tr><td>Name: [active1.fields["name"]] \
ID: [active1.fields["id"]]<BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];field=age'>[active1.fields["age"]]</A><BR>\n \
Fingerprint: <A href='?src=\ref[src];field=fingerprint'>[active1.fields["fingerprint"]]</A><BR>\n \
Physical Status: <A href='?src=\ref[src];field=p_stat'>[active1.fields["p_stat"]]</A><BR>\n \
Mental Status: <A href='?src=\ref[src];field=m_stat'>[active1.fields["m_stat"]]</A><BR></td><td align = center valign = top> \
Photo:<br><img src=front.png height=64 width=64 border=5><img src=side.png height=64 width=64 border=5></td></tr></table>"
else
dat += "<B>General Record Lost!</B><BR>"
if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
dat += text("<BR>\n<CENTER><B>Medical Data</B></CENTER><BR>\nBlood Type: <A href='?src=\ref[];field=b_type'>[]</A><BR>\nDNA: <A href='?src=\ref[];field=b_dna'>[]</A><BR>\n<BR>\nMinor Disabilities: <A href='?src=\ref[];field=mi_dis'>[]</A><BR>\nDetails: <A href='?src=\ref[];field=mi_dis_d'>[]</A><BR>\n<BR>\nMajor Disabilities: <A href='?src=\ref[];field=ma_dis'>[]</A><BR>\nDetails: <A href='?src=\ref[];field=ma_dis_d'>[]</A><BR>\n<BR>\nAllergies: <A href='?src=\ref[];field=alg'>[]</A><BR>\nDetails: <A href='?src=\ref[];field=alg_d'>[]</A><BR>\n<BR>\nCurrent Diseases: <A href='?src=\ref[];field=cdi'>[]</A> (per disease info placed in log/comment section)<BR>\nDetails: <A href='?src=\ref[];field=cdi_d'>[]</A><BR>\n<BR>\nImportant Notes:<BR>\n\t<A href='?src=\ref[];field=notes'>[]</A><BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", 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("[]<BR><A href='?src=\ref[];del_c=[]'>Delete Entry</A><BR><BR>", src.active2.fields[text("com_[]", counter)], src, counter)
counter++
dat += text("<A href='?src=\ref[];add_c=1'>Add Entry</A><BR><BR>", src)
dat += text("<A href='?src=\ref[];del_r=1'>Delete Record (Medical Only)</A><BR><BR>", src)
else
dat += "<B>Medical Record Lost!</B><BR>"
dat += text("<A href='?src=\ref[src];new=1'>New Record</A><BR><BR>")
dat += text("\n<A href='?src=\ref[];print_p=1'>Print Record</A><BR>\n<A href='?src=\ref[];screen=2'>Back</A><BR>", src, src)
if(5.0)
dat += "<CENTER><B>Virus Database</B></CENTER>"
for (var/ID in virusDB)
var/datum/data/record/v = virusDB[ID]
dat += "<br><a href='?src=\ref[src];vir=\ref[v]'>[v.fields["name"]]</a>"
dat += "<br><a href='?src=\ref[src];screen=1'>Back</a>"
if(6.0)
dat += "<center><b>Medical Robot Monitor</b></center>"
dat += "<a href='?src=\ref[src];screen=1'>Back</a>"
dat += "<br><b>Medical Robots:</b>"
var/bdat = null
for(var/mob/living/bot/medbot/M in mob_list)
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] - <b>\[[bl.x],[bl.y]\]</b> - [M.on ? "Online" : "Offline"]<br>"
if((!isnull(M.reagent_glass)) && M.use_beaker)
bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]<br>"
else
bdat += "Using Internal Synthesizer.<br>"
if(!bdat)
dat += "<br><center>None detected</center>"
else
dat += "<br>[bdat]"
else
dat += text("<A href='?src=\ref[];login=1'>{Log In}</A>", src)
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()
return
/datum/file/program/med_data/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
if(href_list["temp"])
src.temp = null
if(href_list["cardr"])
if(scan)
if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
computer.cardslot.remove(usr, 1)
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, usr)
scan = I
if(href_list["cardw"])
if(scan2)
if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
computer.cardslot.remove(usr, 2)
else
scan2.loc = get_turf(src)
scan2 = null
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id))
computer.cardslot.insert(I, usr, 2)
scan2 = I
else if(href_list["logout"])
src.authenticated = null
src.screen = null
src.active1 = null
src.active2 = null
else if(href_list["login"])
if(isAI(usr))
src.active1 = null
src.active2 = null
src.authenticated = usr.name
src.rank = "AI"
src.screen = 1
else if(isrobot(usr))
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 = "<center>GNAv2 based virus lifeform V-[v.fields["id"]]</center>"
src.temp += "<br><b>Name:</b> <A href='?src=\ref[src];field=vir_name;edit_vir=\ref[v]'>[v.fields["name"]]</A>"
src.temp += "<br><b>Antigen:</b> [v.fields["antigen"]]"
src.temp += "<br><b>Spread:</b> [v.fields["spread type"]] "
src.temp += "<br><b>Details:</b><br> <A href='?src=\ref[src];field=vir_desc;edit_vir=\ref[v]'>[v.fields["description"]]</A>"
if(href_list["del_all"])
src.temp = text("Are you sure you wish to delete all records?<br>\n\t<A href='?src=\ref[];temp=1;del_all2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
if(href_list["del_all2"])
for(var/datum/data/record/R in data_core.medical)
//R = null
qdel(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 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || 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() && !issilicon(usr)) || src.active1 != a1)
return
src.active1.fields["age"] = t1
if("mi_dis")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["mi_dis"] = t1
if("mi_dis_d")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["mi_dis_d"] = t1
if("ma_dis")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["ma_dis"] = t1
if("ma_dis_d")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["ma_dis_d"] = t1
if("alg")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["alg"] = t1
if("alg_d")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["alg_d"] = t1
if("cdi")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["cdi"] = t1
if("cdi_d")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["cdi_d"] = t1
if("notes")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["notes"] = t1
if("p_stat")
if (istype(src.active1, /datum/data/record))
src.temp = text("<B>Physical Condition:</B><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=deceased'>*Deceased*</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=ssd'>*SSD*</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=active'>Active</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=unfit'>Physically Unfit</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=disabled'>Disabled</A><BR>", src, src, src, src, src)
if("m_stat")
if (istype(src.active1, /datum/data/record))
src.temp = text("<B>Mental Condition:</B><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=insane'>*Insane*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=unstable'>*Unstable*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=watch'>*Watch*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=stable'>Stable</A><BR>", src, src, src, src)
if("b_type")
if (istype(src.active2, /datum/data/record))
src.temp = text("<B>Blood Type:</B><BR>\n\t<A href='?src=\ref[];temp=1;b_type=an'>A-</A> <A href='?src=\ref[];temp=1;b_type=ap'>A+</A><BR>\n\t<A href='?src=\ref[];temp=1;b_type=bn'>B-</A> <A href='?src=\ref[];temp=1;b_type=bp'>B+</A><BR>\n\t<A href='?src=\ref[];temp=1;b_type=abn'>AB-</A> <A href='?src=\ref[];temp=1;b_type=abp'>AB+</A><BR>\n\t<A href='?src=\ref[];temp=1;b_type=on'>O-</A> <A href='?src=\ref[];temp=1;b_type=op'>O+</A><BR>", src, src, src, src, src, src, src, src)
if("b_dna")
if(istype(src.active2, /datum/data/record))
var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active2 != a2)
return
src.active2.fields["b_dna"] = t1
if("vir_name")
var/datum/data/record/v = locate(href_list["edit_vir"])
if(v)
var/t1 = sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text)
if (!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || 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 = sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || src.active1 != a1)
return
v.fields["description"] = t1
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(PDA_Manifest.len)
PDA_Manifest.Cut()
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)?<br>\n\t<A href='?src=\ref[];temp=1;del_r2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
if(href_list["del_r2"])
if(src.active2)
//src.active2 = null
qdel(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 = sanitize(input("Add Comment:", "Med. records", null, null) as message)
if(!t1 || !src.authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || 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")] [stationtime2text()], [game_year]<BR>[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"])] = "<B>Deleted</B>"
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() && !issilicon(usr)))
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
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
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 = "<CENTER><B>Medical Record</B></CENTER><BR>"
if(record1)
P.info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", 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 += "<B>General Record Lost!</B><BR>"
P.name = "Medical Record"
if(record2)
P.info += text("<BR>\n<CENTER><B>Medical Data</B></CENTER><BR>\nBlood Type: []<BR>\nDNA: []<BR>\n<BR>\nMinor Disabilities: []<BR>\nDetails: []<BR>\n<BR>\nMajor Disabilities: []<BR>\nDetails: []<BR>\n<BR>\nAllergies: []<BR>\nDetails: []<BR>\n<BR>\nCurrent Diseases: [] (per disease info placed in log/comment section)<BR>\nDetails: []<BR>\n<BR>\nImportant Notes:<BR>\n\t[]<BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", 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("[]<BR>", record2.fields[text("com_[]", counter)])
counter++
else
P.info += "<B>Medical Record Lost!</B><BR>"
P.info += "</TT>"
src.printing = null
interact()
return

View File

@@ -1,48 +0,0 @@
/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"
/datum/file/program/powermon/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"]<BR>"
/datum/file/program/powermon/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 += "<A href='?src=\ref[src]'>Refresh</A><br /><br />"
if(!L || !L.len)
t += "No connection"
else
var/datum/powernet/powernet = computer.net.connect_to(/datum/powernet,null)
if(powernet)
t += "<PRE>Total power: [powernet.avail] W<BR>Total load: [num2text(powernet.viewload,10)] W<BR>"
else
t += "<PRE><i>Power statistics unavailable</i><BR>"
t += "<FONT SIZE=-1>"
if(L.len > 0)
t += "Area Eqp./Lgt./Env. Load Cell<HR>"
for(var/obj/machinery/power/apc/A in L)
t += src.format(A)
t += "</FONT></PRE>"
popup.set_content(t)
popup.open()
/datum/file/program/powermon/Topic(var/href, var/list/href_list)
if(!interactable() || ..(href,href_list))
return
interact()

View File

@@ -1,106 +0,0 @@
//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 Console"
active_state = "explosive"
req_access = list(access_armory)
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
/datum/file/program/prisoner/interact()
if(!interactable())
return
var/dat
dat += "<B>Prisoner Implant Manager System</B><BR>"
if(screen == 0)
dat += "<HR><A href='?src=\ref[src];lock=1'>Unlock Console</A>"
else if(screen == 1)
dat += "<HR>Chemical Implants<BR>"
var/turf/Tr = null
for(var/obj/item/weapon/implant/chem/C in all_chem_implants)
Tr = get_turf(C)
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 += "<A href='?src=\ref[src];inject1=\ref[C]'>(<font color=red>(1)</font>)</A>"
dat += "<A href='?src=\ref[src];inject5=\ref[C]'>(<font color=red>(5)</font>)</A>"
dat += "<A href='?src=\ref[src];inject10=\ref[C]'>(<font color=red>(10)</font>)</A><BR>"
dat += "********************************<BR>"
dat += "<HR>Tracking Implants<BR>"
for(var/obj/item/weapon/implant/tracking/T in all_tracking_implants)
Tr = get_turf(T)
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
if(M.z in using_map.station_levels && !istype(M.loc, /turf/space))
var/turf/mob_loc = get_turf(M)
loc_display = mob_loc.loc
if(T.malfunction)
loc_display = pick(teleportlocs)
dat += "ID: [T.id] | Location: [loc_display]<BR>"
dat += "<A href='?src=\ref[src];warn=\ref[T]'>(<font color=red><i>Send Message</i></font>)</A> |<BR>"
dat += "********************************<BR>"
dat += "<HR><A href='?src=\ref[src];lock=1'>Lock Console</A>"
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
/datum/file/program/prisoner/process()
if(!..())
interact()
return
/datum/file/program/prisoner/Topic(href, href_list)
if(!interactable() || ..(href,href_list))
return
if(href_list["inject1"])
var/obj/item/weapon/implant/I = locate(href_list["inject1"])
if(istype(I))
I.activate(1)
else if(href_list["inject5"])
var/obj/item/weapon/implant/I = locate(href_list["inject5"])
if(istype(I))
I.activate(5)
else if(href_list["inject10"])
var/obj/item/weapon/implant/I = locate(href_list["inject10"])
if(istype(I))
I.activate(10)
else if(href_list["lock"])
screen = !screen
else if(href_list["warn"])
var/warning = sanitize(input(usr,"Message:","Enter your message here!",""))
if(!warning) return
var/obj/item/weapon/implant/I = locate(href_list["warn"])
if(istype(I) && I.imp_in)
var/mob/living/carbon/R = I.imp_in
log_game("PrisonComputer3 message: [key_name(usr)]->[key_name(R)] : [warning]")
to_chat(R, "<span class='notice'>You hear a voice in your head saying: '[warning]'</span>")
interact()
return

View File

@@ -1,210 +0,0 @@
/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)
/datum/file/program/borg_control/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
/datum/file/program/borg_control/interact()
if(!interactable() || computer.z > 6)
return
var/dat
if (src.temp)
dat = "<TT>[src.temp]</TT><BR><BR><A href='?src=\ref[src];temp=1'>Clear Screen</A>"
else
if(screen == 0)
//dat += "<h3>Cyborg Control Console</h3><BR>"
dat += "<A href='?src=\ref[src];screen=1'>1. Cyborg Status</A><BR>"
dat += "<A href='?src=\ref[src];screen=2'>2. Emergency Full Destruct</A><BR>"
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 += "<A href='?src=\ref[src];magbot=\ref[R]'>(<i>Hack</i>)</A> "
dat += "<A href='?src=\ref[src];stopbot=\ref[R]'>(<i>[R.canmove ? "Lockdown" : "Release"]</i>)</A> "
dat += "<A href='?src=\ref[src];killbot=\ref[R]'>(<i>Destroy</i>)</A>"
dat += "<BR>"
dat += "<A href='?src=\ref[src];screen=0'>(Return to Main Menu)</A><BR>"
if(screen == 2)
if(!src.status)
dat += {"<BR><B>Emergency Robot Self-Destruct</B><HR>\nStatus: Off<BR>
\n<BR>
\nCountdown: [src.timeleft]/60 <A href='?src=\ref[src];reset=1'>\[Reset\]</A><BR>
\n<BR>
\n<A href='?src=\ref[src];killall'>Start Sequence</A><BR>
\n<BR>
\n<A href='?src=\ref[usr];close'>Close</A>"}
else
dat = {"<B>Emergency Robot Self-Destruct</B><HR>\nStatus: Activated<BR>
\n<BR>
\nCountdown: [src.timeleft]/60 \[Reset\]<BR>
\n<BR>\n<A href='?src=\ref[src];stop=1'>Stop Sequence</A><BR>
\n<BR>
\n<A href='?src=\ref[usr];mach_close=computer'>Close</A>"}
dat += "<A href='?src=\ref[src];screen=0'>(Return to Main Menu)</A><BR>"
popup.set_content(dat)
popup.open()
return
/datum/file/program/borg_control/Topic(var/href, var/list/href_list)
if(!interactable() || ..(href,href_list))
return
if("killall" in href_list)
src.temp = {"Destroy Robots?<BR>
<BR><B><A href='?src=\ref[src];do_killall'>\[Swipe ID to initiate destruction sequence\]</A></B><BR>
<A href='?src=\ref[src];temp=1'>Cancel</A>"}
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("<span class='notice'>[key_name_admin(usr)] has initiated the global cyborg killswitch!</span>")
log_game("[key_name(usr)] has initiated the global cyborg killswitch!")
src.status = 1
src.start_sequence()
src.temp = null
else
to_chat(usr, "<span class='warning'>Access Denied.</span>")
if("stop" in href_list)
src.temp = {"
Stop Robot Destruction Sequence?<BR>
<BR><A href='?src=\ref[src];stop2=1'>Yes</A><BR>
<A href='?src=\ref[src];temp=1'>No</A>"}
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)
to_chat(R, "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered.")
R.ResetSecurityCodes()
else
message_admins("<span class='notice'>[key_name_admin(usr)] detonated [key_name(R.name)]!</span>")
log_game("<span class='notice'>[key_name_admin(usr)] detonated [key_name(R.name)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg kill-switch activated: [R.name]</span><br>")
R.self_destruct()
else
to_chat(usr, "<span class='warning'>Access Denied.</span>")
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("<span class='notice'>[key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!</span>")
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R.name)]!")
R.canmove = !R.canmove
if(R.lockcharge)
R.lockcharge = !R.lockcharge
to_chat(R, "Your lockdown has been lifted!")
else
R.lockcharge = !R.lockcharge
to_chat(R, "You have been locked down!")
else
to_chat(usr, "<span class='warning'>Access Denied.</span>")
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("<span class='notice'>[key_name_admin(usr)] emagged [R.name] using robotic console!</span>") // why is this commented out?
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

View File

@@ -1,613 +0,0 @@
//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
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/obj/item/weapon/card/id/scan2 = 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
/datum/file/program/secure_data/proc/authenticate()
if(access_security in scan.access || access_forensics_lockers in scan.access )
return 1
if(isAI(usr))
return 1
return 0
/datum/file/program/secure_data/interact()
if(!computer.cardslot)
computer.Crash(MISSING_PERIPHERAL)
return
usr.set_machine(src)
scan = computer.cardslot.reader
if(istype(computer.cardslot, /obj/item/part/computer/cardslot/dual))
var/obj/item/part/computer/cardslot/dual/D = computer.cardslot
scan2 = D.writer
if(!interactable())
return
if(computer.z > 6)
to_chat(usr, "<span class='danger'>Unable to establish a connection:</span> You're too far away from the station!")
return
var/dat
if(temp)
dat = text("<TT>[]</TT><BR><BR><A href='?src=\ref[];choice=Clear Screen'>Clear Screen</A>", temp, src)
else
dat = text("Confirm Identity (R): <A href='?src=\ref[];choice=Confirm Identity R'>[]</A><HR>", src, (scan ? text("[]", scan.name) : "----------"))
if(istype(computer.cardslot, /obj/item/part/computer/cardslot/dual))
dat += text("Confirm Identity (W): <A href='?src=\ref[];choice=Confirm Identity W'>[]</A><BR>", src, (scan2 ? text("[]", scan2.name) : "----------"))
if(scan2 && !scan)
dat += text("<div class='notice'>Insert card into reader slot to log in.</div><br>")
if(authenticated)
switch(screen)
if(1.0)
dat += "<p style='text-align:center;'>"
dat += text("<A href='?src=\ref[];choice=Search Records'>Search Records</A><BR>", src)
dat += text("<A href='?src=\ref[];choice=New Record (General)'>New Record</A><BR>", src)
dat += {"
</p>
<table style="text-align:center;" cellspacing="0" width="100%">
<tr>
<th>Records:</th>
</tr>
</table>
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th><A href='?src=\ref[src];choice=Sorting;sort=name'>Name</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=id'>ID</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=rank'>Rank</A></th>
<th><A href='?src=\ref[src];choice=Sorting;sort=fingerprint'>Fingerprints</A></th>
<th>Criminal Status</th>
</tr>"}
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:#00FF00;'"
if("")
background = "'background-color:#00FF7F;'"
crimstat = "No Record."
dat += text("<tr style=[]><td><A href='?src=\ref[];choice=Browse Record;d_rec=\ref[]'>[]</a></td>", background, src, R, R.fields["name"])
dat += text("<td>[]</td>", R.fields["id"])
dat += text("<td>[]</td>", R.fields["rank"])
dat += text("<td>[]</td>", R.fields["fingerprint"])
dat += text("<td>[]</td></tr>", crimstat)
dat += "</table><hr width='75%' />"
dat += text("<A href='?src=\ref[];choice=Record Maintenance'>Record Maintenance</A><br><br>", src)
dat += text("<A href='?src=\ref[];choice=Log Out'>{Log Out}</A>",src)
if(2.0)
dat += "<B>Records Maintenance</B><HR>"
dat += "<BR><A href='?src=\ref[src];choice=Delete All Records'>Delete All Records</A><BR><BR><A href='?src=\ref[src];choice=Return'>Back</A>"
if(3.0)
dat += "<CENTER><B>Security Record</B></CENTER><BR>"
if(istype(active1, /datum/data/record) && data_core.general.Find(active1))
var/icon/front = active1.fields["photo_front"]
var/icon/side = active1.fields["photo_side"]
usr << browse_rsc(front, "front.png")
usr << browse_rsc(side, "side.png")
dat += text("<table><tr><td> \
Name: <A href='?src=\ref[src];choice=Edit Field;field=name'>[active1.fields["name"]]</A><BR> \
ID: <A href='?src=\ref[src];choice=Edit Field;field=id'>[active1.fields["id"]]</A><BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];choice=Edit Field;field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];choice=Edit Field;field=age'>[active1.fields["age"]]</A><BR>\n \
Rank: <A href='?src=\ref[src];choice=Edit Field;field=rank'>[active1.fields["rank"]]</A><BR>\n \
Fingerprint: <A href='?src=\ref[src];choice=Edit Field;field=fingerprint'>[active1.fields["fingerprint"]]</A><BR>\n \
Physical Status: [active1.fields["p_stat"]]<BR>\n \
Mental Status: [active1.fields["m_stat"]]<BR></td> \
<td align = center valign = top>Photo:<br><img src=front.png height=80 width=80 border=4> \
<img src=side.png height=80 width=80 border=4></td></tr></table>")
else
dat += "<B>General Record Lost!</B><BR>"
if(istype(active2, /datum/data/record) && data_core.security.Find(active2))
dat += text("<BR>\n<CENTER><B>Security Data</B></CENTER><BR>\nCriminal Status: <A href='?src=\ref[];choice=Edit Field;field=criminal'>[]</A><BR>\n<BR>\nMinor Crimes: <A href='?src=\ref[];choice=Edit Field;field=mi_crim'>[]</A><BR>\nDetails: <A href='?src=\ref[];choice=Edit Field;field=mi_crim_d'>[]</A><BR>\n<BR>\nMajor Crimes: <A href='?src=\ref[];choice=Edit Field;field=ma_crim'>[]</A><BR>\nDetails: <A href='?src=\ref[];choice=Edit Field;field=ma_crim_d'>[]</A><BR>\n<BR>\nImportant Notes:<BR>\n\t<A href='?src=\ref[];choice=Edit Field;field=notes'>[]</A><BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", 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("[]<BR><A href='?src=\ref[];choice=Delete Entry;del_c=[]'>Delete Entry</A><BR><BR>", active2.fields[text("com_[]", counter)], src, counter)
counter++
dat += text("<A href='?src=\ref[];choice=Add Entry'>Add Entry</A><BR><BR>", src)
dat += text("<A href='?src=\ref[];choice=Delete Record (Security)'>Delete Record (Security Only)</A><BR><BR>", src)
else
dat += "<B>Security Record Lost!</B><BR>"
dat += text("<A href='?src=\ref[];choice=New Record (Security)'>New Security Record</A><BR><BR>", src)
dat += text("\n<A href='?src=\ref[];choice=Delete Record (ALL)'>Delete Record (ALL)</A><BR><BR>\n<A href='?src=\ref[];choice=Print Record'>Print Record</A><BR>\n<A href='?src=\ref[];choice=Return'>Back</A><BR>", src, src, src)
if(4.0)
if(!Perp.len)
dat += text("ERROR. String could not be located.<br><br><A href='?src=\ref[];choice=Return'>Back</A>", src)
else
dat += {"
<table style="text-align:center;" cellspacing="0" width="100%">
<tr> "}
dat += text("<th>Search Results for '[]':</th>", tempname)
dat += {"
</tr>
</table>
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr>
<th>Name</th>
<th>ID</th>
<th>Rank</th>
<th>Fingerprints</th>
<th>Criminal Status</th>
</tr> "}
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("<tr style=[]><td><A href='?src=\ref[];choice=Browse Record;d_rec=\ref[]'>[]</a></td>", background, src, R, R.fields["name"])
dat += text("<td>[]</td>", R.fields["id"])
dat += text("<td>[]</td>", R.fields["rank"])
dat += text("<td>[]</td>", R.fields["fingerprint"])
dat += text("<td>[]</td></tr>", crimstat)
dat += "</table><hr width='75%' />"
dat += text("<br><A href='?src=\ref[];choice=Return'>Return to index.</A>", src)
else
else
dat += text("<A href='?src=\ref[];choice=Log In'>{Log In}</A>", src)
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()
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.*/
/datum/file/program/secure_data/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 R")
if(scan)
if(ishuman(usr) && !usr.get_active_hand())
computer.cardslot.remove(usr, 1)
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))
usr << "Attempting to insert"
computer.cardslot.insert(I, usr) // No slot, will autofill
scan = I
if("Confirm Identity W")
if(scan2)
if(ishuman(usr) && !usr.get_active_hand())
computer.cardslot.remove(usr, 2)
else
scan2.loc = get_turf(src)
scan2 = null
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id))
computer.cardslot.insert(I, usr, 2) // Specifically writer slot
scan2 = I
if("Log Out")
authenticated = null
screen = null
active1 = null
active2 = null
if("Log In")
if(isAI(usr))
src.active1 = null
src.active2 = null
src.authenticated = usr.name
src.rank = "AI"
src.screen = 1
else if(isrobot(usr))
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
if(!t1 || usr.stat || !authenticated || usr.restrained() || !interactable())
return
Perp = new/list()
t1 = lowertext(t1)
var/list/components = splittext(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 = "<CENTER><B>Security Record</B></CENTER><BR>"
if(record1)
P.info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", 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 += "<B>General Record Lost!</B><BR>"
P.name = "Security Record"
if(record2)
P.info += text("<BR>\n<CENTER><B>Security Data</B></CENTER><BR>\nCriminal Status: []<BR>\n<BR>\nMinor Crimes: []<BR>\nDetails: []<BR>\n<BR>\nMajor Crimes: []<BR>\nDetails: []<BR>\n<BR>\nImportant Notes:<BR>\n\t[]<BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", 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("[]<BR>", record2.fields[text("com_[]", counter)])
counter++
else
P.info += "<B>Security Record Lost!</B><BR>"
P.info += "</TT>"
printing = null
computer.updateUsrDialog()
//RECORD DELETE
if("Delete All Records")
temp = ""
temp += "Are you sure you wish to delete all Security records?<br>"
temp += "<a href='?src=\ref[src];choice=Purge All Records'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
if("Purge All Records")
for(var/datum/data/record/R in data_core.security)
qdel(R)
temp = "All Security records deleted."
if("Add Entry")
if(!istype(active2, /datum/data/record))
return
var/a2 = active2
var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || 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")] [stationtime2text()], [game_year]<BR>[t1]")
if("Delete Record (ALL)")
if(active1)
temp = "<h5>Are you sure you wish to delete the record (ALL)?</h5>"
temp += "<a href='?src=\ref[src];choice=Delete Record (ALL) Execute'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
if("Delete Record (Security)")
if(active2)
temp = "<h5>Are you sure you wish to delete the record (Security Portion Only)?</h5>"
temp += "<a href='?src=\ref[src];choice=Delete Record (Security) Execute'>Yes</a><br>"
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
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"])] = "<B>Deleted</B>"
//RECORD CREATE
if("New Record (Security)")
if(istype(active1, /datum/data/record) && !istype(active2, /datum/data/record))
active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
screen = 3
if("New Record (General)")
active1 = data_core.CreateGeneralRecord()
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 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
if(!t1 || !length(trim(t1)) || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1)
return
active1.fields["name"] = t1
if("id")
if(istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active1 != a1)
return
active1.fields["id"] = t1
if("fingerprint")
if(istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || 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() && !issilicon(usr)) || active1 != a1)
return
active1.fields["age"] = t1
if("mi_crim")
if(istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2)
return
active2.fields["mi_crim"] = t1
if("mi_crim_d")
if(istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message)
if (!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2)
return
active2.fields["mi_crim_d"] = t1
if("ma_crim")
if(istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2)
return
active2.fields["ma_crim"] = t1
if("ma_crim_d")
if(istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2)
return
active2.fields["ma_crim_d"] = t1
if("notes")
if(istype(active2, /datum/data/record))
var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || active2 != a2)
return
active2.fields["notes"] = t1
if("criminal")
if (istype(active2, /datum/data/record))
temp = "<h5>Criminal Status:</h5>"
temp += "<ul>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=none'>None</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=arrest'>*Arrest*</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=incarcerated'>Incarcerated</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=parolled'>Parolled</a></li>"
temp += "<li><a href='?src=\ref[src];choice=Change Criminal Status;criminal2=released'>Released</a></li>"
temp += "</ul>"
if("rank")
var/list/L = list( "Head of Personnel", "Colony Director", "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 = "<h5>Rank:</h5>"
temp += "<ul>"
for(var/rank in joblist)
temp += "<li><a href='?src=\ref[src];choice=Change Rank;rank=[rank]'>[rank]</a></li>"
temp += "</ul>"
else
alert(usr, "You do not have the required rank to do this!")
if("species")
if (istype(active1, /datum/data/record))
var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)
if(!t1 || !authenticated || usr.stat || usr.restrained() || (!interactable() && !issilicon(usr)) || 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)
BITSET(H.hud_updateflag, 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)
qdel(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"])
qdel(R)
else
qdel(active1)
if(active2)
qdel(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(PDA_Manifest.len)
PDA_Manifest.Cut()
if(6)
R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
continue
else if(prob(1))
qdel(R)
continue
..(severity)
/obj/machinery/computer3/secure_data/detective_computer
icon = 'icons/obj/computer.dmi'
icon_state = "messyfiles"

View File

@@ -1,34 +0,0 @@
/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'
/datum/file/program/welcome/interact()
usr.set_machine(src)
if(!interactable())
return
var/dat = ""
dat += "<center><span style='font-size:24pt'><b>Welcome to NTOS</b></span></center>"
dat += "<center><span style='font-size:8pt'>Thank you for choosing NTOS, your gateway to the future of mobile computing technology, sponsored by [using_map.company_name] (R)</span></center><br>"
dat += "<span style='font-size:12pt'><b>Getting started with NTOS:</b></span><br>"
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 [using_map.company_name] 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 [using_map.boss_name]."
popup.set_content(dat)
popup.set_title_image(usr.browse_rsc_icon(computer.icon, computer.icon_state))
popup.open()
return
/datum/file/program/welcome/Topic(href, href_list)
if(!interactable() || ..(href,href_list))
return
interact()
return

View File

@@ -1,166 +0,0 @@
// 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/hidden_file = 0 // Prevents file from showing up on NTOS program list.
var/drm = 0 // Copy protection, called by copy() and move()
var/readonly = 0 // Edit protection, called by edit(), which is just a failcheck proc
/datum/file/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
//
/datum/file/proc/copy(var/obj/item/part/computer/storage/dest)
if(!computer) 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
//
/datum/file/proc/move(var/obj/item/part/computer/storage/dest)
if(!computer) 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.
//
/datum/file/proc/edit()
if(!computer)
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
/datum/file/data/New()
if(content)
if(file_increment > 1)
volume = round(file_increment * length(content))
..()
// Set the content to a specific amount, increase filesize appropriately.
/datum/file/data/proc/set_content(var/text)
content = text
if(file_increment > 1)
volume = round(file_increment * length(text))
/datum/file/data/copy(var/obj/O)
var/datum/file/data/D = ..(O)
if(D)
D.content = content
D.readonly = readonly
/*
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"
/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

View File

@@ -1,183 +0,0 @@
/*
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"
pixel_x = 2
pixel_y = -3
w_class = ITEMSIZE_NORMAL
var/obj/machinery/computer3/laptop/stored_computer = null
/obj/item/device/laptop/get_cell()
return stored_computer.battery
/obj/item/device/laptop/verb/open_computer()
set name = "Open Laptop"
set category = "Object"
set src in view(1)
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
to_chat(usr, "<span class='warning'>You can't do that.</span>")
return
if(!Adjacent(usr))
to_chat(usr, "You can't reach it.")
return
if(!istype(loc,/turf))
to_chat(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
to_chat(usr, "\The [src] crumbles to pieces.")
spawn(5)
qdel(src)
return
stored_computer.loc = loc
stored_computer.stat &= ~MAINT
stored_computer.update_icon()
loc = stored_computer
to_chat(usr, "You open \the [src].")
/obj/item/device/laptop/AltClick()
if(Adjacent(usr))
open_computer()
//Quickfix until Snapshot works out how he wants to redo power. ~Z
/obj/item/device/laptop/verb/eject_id()
set category = "Object"
set name = "Eject ID Card"
set src in oview(1)
if(stored_computer)
stored_computer.eject_id()
/obj/machinery/computer3/laptop/verb/eject_id()
set category = "Object"
set name = "Eject ID Card"
set src in oview(1)
var/obj/item/part/computer/cardslot/C = locate() in src.contents
if(!C)
to_chat(usr, "There is no card port on the laptop.")
return
C.remove(usr)
return
/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
active_power_usage = 200 // Stationary consoles we use on station have 300, laptops are probably slightly more power efficient
idle_power_usage = 100
var/obj/item/device/laptop/portable = null
/obj/machinery/computer3/laptop/New(var/L, var/built = 0)
if(!built && !battery)
battery = new /obj/item/weapon/cell(src)
battery.maxcharge = 500
battery.charge = 500
..(L,built)
/obj/machinery/computer3/laptop/verb/close_computer()
set name = "Close Laptop"
set category = "Object"
set src in view(1)
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
to_chat(usr, "<span class='warning'>You can't do that.</span>")
return
if(!Adjacent(usr))
to_chat(usr, "<span class='warning'>You can't reach it.</span>")
return
close_laptop(usr)
/obj/machinery/computer3/laptop/proc/close_laptop(mob/user = null)
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)
if(user)
to_chat(user, "\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
if(user)
to_chat(user, "You close \the [src].")
/obj/machinery/computer3/laptop/auto_use_power()
if(stat&MAINT)
return
if(use_power && istype(battery) && battery.charge > 0)
if(use_power == 1)
battery.use(idle_power_usage*CELLRATE) //idle and active_power_usage are in WATTS. battery.use() expects CHARGE.
else
battery.use(active_power_usage*CELLRATE)
return 1
return 0
/obj/machinery/computer3/laptop/use_power(var/amount, var/chan = -1)
if(battery && battery.charge > 0)
battery.use(amount*CELLRATE)
/obj/machinery/computer3/laptop/power_change()
if( !battery || battery.charge <= 0 )
stat |= NOPOWER
else
stat &= ~NOPOWER
/obj/machinery/computer3/laptop/Destroy()
if(istype(loc,/obj/item/device/laptop))
var/obj/O = loc
spawn(5)
if(O)
qdel(O)
..()
/obj/machinery/computer3/laptop/AltClick()
if(Adjacent(usr))
close_computer()

View File

@@ -1,374 +0,0 @@
/obj/machinery/lapvend
name = "Laptop Vendor"
desc = "A generic vending machine."
icon = 'icons/obj/vending.dmi'
icon_state = "robotics"
anchored = 1
density = 1
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/attackby(obj/item/weapon/W as obj, mob/user as mob)
var/obj/item/weapon/card/id/I = W.GetID()
if(default_unfasten_wrench(user, W, 20))
return
if(vendmode == 1 && I)
scan_id(I, W)
vendmode = 0
SSnanoui.update_uis(src)
if(vendmode == 2 && I)
if(reimburse_id(I, W))
vendmode = 0
SSnanoui.update_uis(src)
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 = 2
to_chat(user, "<span class='notice'>You slot your [L.name] into \The [src.name]</span>")
SSnanoui.update_uis(src)
else
..()
/obj/machinery/lapvend/attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
ui_interact(user)
/**
* Display the NanoUI window for the vending machine.
*
* See NanoUI documentation for details.
*/
/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/list/data = list()
data["mode"] = vendmode
data["cardreader"] = cardreader
data["floppy"] = floppy
data["radionet"] = radionet
data["camera"] = camera
data["network"] = network
data["power"] = power
data["total"] = total()
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "laptop_vendor.tmpl", src.name, 480, 425)
ui.set_initial_data(data)
ui.open()
//ui.set_auto_update(5)
/obj/machinery/lapvend/Topic(href, href_list)
if(stat & (BROKEN|NOPOWER))
return
if(usr.stat || usr.restrained())
return
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 ("cardreader_rem")
cardreader = 0
if ("floppy_rem")
floppy = 0
if ("radio_rem")
radionet = 0
if ("camnet_rem")
camera = 0
if ("network_rem")
network = 0
if ("power_rem")
power = 0
if("vend")
vendmode = 1
if("cancel")
if(relap)
relap.loc = src.loc
relap = null
vendmode = 0
src.add_fingerprint(usr)
SSnanoui.update_uis(src)
/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)
newlap.battery.maxcharge = 1000
newlap.battery.charge = 1000
if (power == 2)
newlap.battery.maxcharge = 1750
newlap.battery.charge = 1750
newlap.spawn_parts()
/obj/machinery/lapvend/proc/scan_id(var/obj/item/weapon/card/id/C, var/obj/item/I)
visible_message("<span class='info'>\The [usr] swipes \the [I] through \the [src].</span>")
var/datum/money_account/CH = get_account(C.associated_account_number)
if(!CH)
to_chat(usr, "\icon[src]<span class='warning'>No valid account number is associated with this card.</span>")
return
if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
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)
transfer_and_vend(D, C)
else
to_chat(usr, "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.</span>")
else
to_chat(usr, "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.</span>")
else
transfer_and_vend(CH, C)
// Transfers money and vends the laptop.
/obj/machinery/lapvend/proc/transfer_and_vend(var/datum/money_account/D, var/obj/item/weapon/card/C)
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 = stationtime2text()
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 = stationtime2text()
vendor_account.transaction_log.Add(T)
newlap = new /obj/machinery/computer3/laptop/vended(src.loc)
choose_progs(C)
vend()
newlap.close_laptop()
newlap = null
cardreader = 0
floppy = 0
radionet = 0
camera = 0
network = 0
power = 0
else
to_chat(usr, "\icon[src]<span class='warning'>You don't have that much money!</span>")
/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) || (access_forensics_lockers in C.access)) //Gives detective the medical records program, but not the crew monitoring one.
newlap.spawn_files += (/datum/file/program/med_data)
if (access_medical in C.access)
newlap.spawn_files += (/datum/file/program/crew)
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)
//Atlantis: Each laptop gets "invisible" program/security - REQUIRED for camnetkeys to work.
newlap.spawn_files += (/datum/file/program/security/hidden)
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_id(var/obj/item/weapon/card/id/C, var/obj/item/I)
visible_message("<span class='info'>\The [usr] swipes \the [I] through \the [src].</span>")
var/datum/money_account/CH = get_account(C.associated_account_number)
if(!CH)
to_chat(usr, "\icon[src]<span class='warning'>No valid account number is associated with this card.</span>")
return 0
if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2)
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)
transfer_and_reimburse(D)
return 1
else
to_chat(usr, "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.</span>")
return 0
else
to_chat(usr, "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call [using_map.boss_short] Support.</span>")
return 0
else
transfer_and_reimburse(CH)
return 1
/obj/machinery/lapvend/proc/transfer_and_reimburse(var/datum/money_account/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 = stationtime2text()
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 = stationtime2text()
vendor_account.transaction_log.Add(T)
qdel(relap)
vendmode = 0
cardreader = 0
floppy = 0
radionet = 0
camera = 0
network = 0
power = 0

View File

@@ -1,243 +0,0 @@
/obj/item/part/computer/networking
name = "Computer networking component"
/obj/item/part/computer/networking/allow_attackby(var/obj/item/I, var/mob/user)
return 0
/*
This is the public-facing proc used by NETUP.
It does additional checking before and after calling get_machines()
*/
/obj/item/part/computer/networking/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.
*/
/obj/item/part/computer/networking/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.
*/
/obj/item/part/computer/networking/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 = PUB_FREQ
var/rad_filter = null
var/range = null
var/subspace = 0
/obj/item/part/computer/networking/radio/init()
..()
spawn(5)
radio_connection = radio_controller.add_object(src, src.frequency, src.rad_filter)
/obj/item/part/computer/networking/radio/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, rad_filter)
else
frequency = new_frequency
spawn(rand(5,10))
set_frequency(new_frequency)
/obj/item/part/computer/networking/radio/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)
/obj/item/part/computer/networking/radio/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,rad_filter,range)
/obj/item/part/computer/networking/radio/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
/obj/item/part/computer/networking/radio/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"
/obj/item/part/computer/networking/area/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/obj/O in A.contents)
if(istype(O,typekey))
machines |= O
return machines
/obj/item/part/computer/networking/area/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"
/obj/item/part/computer/networking/prox/get_machines(var/typekey)
var/turf/T = get_turf(loc)
if(!istype(T))
return list()
if(typekey == null)
typekey = /obj/machinery
var/list/nearby_machines = list()
for(var/obj/O in T)
if(istype(O,typekey))
nearby_machines += O
for(var/d in cardinal)
var/turf/T2 = get_step(T,d)
for(var/obj/O in T2)
if(istype(O,typekey))
nearby_machines += O
return nearby_machines
/obj/item/part/computer/networking/prox/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."
/obj/item/part/computer/networking/cable/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
/obj/item/part/computer/networking/cable/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

View File

@@ -1,404 +0,0 @@
/*
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","<BR>")
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()
qdel(popup)
return
/*
The computer object will transfer process() calls to the program.
*/
/datum/file/program/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","<img src=\ref['icons/ntos/tb_close.png']>"))
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 "<span class='linkOff'>[text]</span>"
/*
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 += "<h3>[computer.hdd]</h3>"
for(var/datum/file/F in computer.hdd.files)
if(istype(F,typekey))
dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "<br>"
if(computer.hdd.files.len == 0)
dat += "<i>No files</i><br>"
dat += "<br>"
if(computer.floppy)
if(!computer.floppy.inserted)
dat += "<h3>[computer.floppy] - <span class='linkOff'>Eject</span></h3><br><br>"
else
dat += "<h3>[computer.floppy] - [topic_link(src,"eject_disk","Eject")]</h3>"
for(var/datum/file/F in computer.floppy.inserted.files)
dat += topic_link(src,"[linkop]=\ref[F]",F.name) + "<br>"
if(computer.floppy.inserted.files.len == 0)
dat += "<i>No files</i><br>"
dat += "<br>"
if(computer.cardslot && istype(computer.cardslot.reader,/obj/item/weapon/card/data))
dat += "<h3>[computer.cardslot.reader] - [topic_link(src,"eject_card=reader","Eject")]</h3>"
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) + "<br>"
if(D.files.len == 0)
dat += "<i>No files</i><br>"
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(istype(computer.cardslot, /obj/item/part/computer/cardslot/dual) && href_list["eject_card"] == "writer")
computer.cardslot.remove(usr)
else
computer.cardslot.remove(usr)
return 1
//
// usage: runfile=\ref[file]
// executes the file
//
if("runfile" in href_list)
var/datum/file/F = locate(href_list["runfile"])
if(istype(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/powermon
name = "Power Grid"
image = 'icons/ntos/power.png'
active_state = "power"
volume = 7200
/datum/file/program/prisoner
name = "Prisoner Control"
image = 'icons/ntos/prison.png'
drm = 1
active_state = "power"
volume = 5000
/datum/file/program/borg_control
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

View File

@@ -1,51 +0,0 @@
/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/cameras/syndicate
name = "Camera Viewer"
desc = "A program install disk. A crude skull has been drawn on it and there is a list of items:\nFloppy Drive\nCamera Card\nNetwork Card: Adjacent\nPosition laptop nearby camera, enjoy."
icon = 'icons/obj/stock_parts.dmi'
icon_state = "datadisk_arcade"
spawn_files = list(/datum/file/program/security/syndicate)
/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)
*/

View File

@@ -1,32 +0,0 @@
/*
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)
/obj/machinery/computer3/server/rack/update_icon()
//overlays.Cut()
return
/obj/machinery/computer3/server/rack/attack_hand() // Racks have no screen, only AI can use them
return

View File

@@ -1,181 +0,0 @@
/*
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
/obj/item/part/computer/storage/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
/obj/item/part/computer/storage/proc/addfile(var/datum/file/F,var/forced = 0)
if(!F || (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
/obj/item/part/computer/storage/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
/obj/item/part/computer/storage/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
/obj/item/part/computer/storage/removable/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
/obj/item/part/computer/storage/removable/attackby(obj/O as obj, mob/user as mob)
if(inserted && istype(O,/obj/item/weapon/pen))
to_chat(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)
to_chat(usr, "There's already a disk in [src]!")
return
to_chat(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
..()
/obj/item/part/computer/storage/removable/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
/obj/item/weapon/disk/file/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

View File

@@ -446,3 +446,9 @@ Class Procs:
M.deconstruct(src) M.deconstruct(src)
qdel(src) qdel(src)
return 1 return 1
/datum/proc/apply_visual(mob/M)
return
/datum/proc/remove_visual(mob/M)
return

View File

@@ -8,7 +8,7 @@ obj/machinery/recharger
idle_power_usage = 4 idle_power_usage = 4
active_power_usage = 40000 //40 kW active_power_usage = 40000 //40 kW
var/obj/item/charging = null var/obj/item/charging = null
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/device/laptop, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/ammo_casing/nsfw_batt) //VOREStation Add - NSFW Batteries var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/ammo_casing/nsfw_batt) //VOREStation Add - NSFW Batteries
var/icon_state_charged = "recharger2" var/icon_state_charged = "recharger2"
var/icon_state_charging = "recharger1" var/icon_state_charging = "recharger1"
var/icon_state_idle = "recharger0" //also when unpowered var/icon_state_idle = "recharger0" //also when unpowered
@@ -44,7 +44,12 @@ obj/machinery/recharger
if(E.self_recharge) if(E.self_recharge)
to_chat(user, "<span class='notice'>Your gun has no recharge port.</span>") to_chat(user, "<span class='notice'>Your gun has no recharge port.</span>")
return return
if(!G.get_cell() && !istype(G, /obj/item/ammo_casing/nsfw_batt)) //VOREStation Edit: NSFW charging if(istype(G, /obj/item/modular_computer))
var/obj/item/modular_computer/C = G
if(!C.battery_module)
to_chat(user, "This device does not have a battery installed.")
return
else if(!G.get_cell() && !istype(G, /obj/item/ammo_casing/nsfw_batt)) //VOREStation Edit: NSFW charging
to_chat(user, "This device does not have a battery installed.") to_chat(user, "This device does not have a battery installed.")
return return
@@ -86,6 +91,27 @@ obj/machinery/recharger
update_use_power(1) update_use_power(1)
icon_state = icon_state_idle icon_state = icon_state_idle
else else
if(istype(charging, /obj/item/modular_computer))
var/obj/item/modular_computer/C = charging
if(!C.battery_module.battery.fully_charged())
icon_state = icon_state_charging
C.battery_module.battery.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
return
else if(istype(charging, /obj/item/weapon/computer_hardware/battery_module))
var/obj/item/weapon/computer_hardware/battery_module/BM = charging
if(!BM.battery.fully_charged())
icon_state = icon_state_charging
BM.battery.give(active_power_usage*CELLRATE)
update_use_power(2)
else
icon_state = icon_state_charged
update_use_power(1)
return
var/obj/item/weapon/cell/C = charging.get_cell() var/obj/item/weapon/cell/C = charging.get_cell()
if(istype(C)) if(istype(C))
if(!C.fully_charged()) if(!C.fully_charged())
@@ -139,4 +165,4 @@ obj/machinery/recharger
icon_state_charging = "wrecharger1" icon_state_charging = "wrecharger1"
icon_state_idle = "wrecharger0" icon_state_idle = "wrecharger0"
portable = 0 portable = 0
circuit = /obj/item/weapon/circuitboard/recharger/wrecharger circuit = /obj/item/weapon/circuitboard/recharger/wrecharger

View File

@@ -371,17 +371,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/broadcasting = 1 var/broadcasting = 1
var/receiving = 1 var/receiving = 1
// VOREStation Edit - Make sure constructed relays keep relaying for their current Z when moved by shuttles. /obj/machinery/telecomms/relay/forceMove(var/newloc)
/obj/machinery/telecomms/relay/proc/update_z() . = ..(newloc)
if (initial(listening_level) == 0) listening_level = z
var/turf/T = get_turf(src)
listening_level = T.z
/area/shuttle_arrived()
. = ..()
for(var/obj/machinery/telecomms/relay/R in contents)
R.update_z()
// VOREStation Edit End
/obj/machinery/telecomms/relay/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) /obj/machinery/telecomms/relay/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)

View File

@@ -797,17 +797,17 @@
/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 8, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 8,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 8,
/obj/item/weapon/reagent_containers/pill/diet = 8, /obj/item/weapon/reagent_containers/pill/diet = 8,
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, //VOREStation Removal,
/obj/item/weapon/towel/random = 8) /obj/item/weapon/towel/random = 8)
prices = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 3, prices = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 3,
/obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 3, /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 3,
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 40, //VOREStation Edit, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 40, //VOREStation Edit,
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 5, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 5,
/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 5,
/obj/item/weapon/reagent_containers/pill/diet = 25, /obj/item/weapon/reagent_containers/pill/diet = 25,
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, ///obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5, //VOREStation Removal,
/obj/item/weapon/towel/random = 40) /obj/item/weapon/towel/random = 40)
contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4) contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4)

View File

@@ -4,6 +4,7 @@ var/list/command_cartridges = list(
/obj/item/weapon/cartridge/hos, /obj/item/weapon/cartridge/hos,
/obj/item/weapon/cartridge/ce, /obj/item/weapon/cartridge/ce,
/obj/item/weapon/cartridge/rd, /obj/item/weapon/cartridge/rd,
/obj/item/weapon/cartridge/cmo,
/obj/item/weapon/cartridge/head, /obj/item/weapon/cartridge/head,
/obj/item/weapon/cartridge/lawyer // Internal Affaris, /obj/item/weapon/cartridge/lawyer // Internal Affaris,
) )
@@ -149,7 +150,7 @@ var/list/civilian_cartridges = list(
*/ */
/obj/item/weapon/cartridge/service /obj/item/weapon/cartridge/service
name = "\improper Serv-U Pro" name = "\improper Serv-U Pro cartridge"
desc = "A data cartridge designed to serve YOU!" desc = "A data cartridge designed to serve YOU!"
/obj/item/weapon/cartridge/signal /obj/item/weapon/cartridge/signal
@@ -175,12 +176,12 @@ var/list/civilian_cartridges = list(
access_quartermaster = 1 access_quartermaster = 1
/obj/item/weapon/cartridge/miner /obj/item/weapon/cartridge/miner
name = "\improper Drill-Jockey 4.5" name = "\improper Drill-Jockey 4.5 cartridge"
desc = "It's covered in some sort of sand." desc = "It's covered in some sort of sand."
icon_state = "cart-q" icon_state = "cart-q"
/obj/item/weapon/cartridge/head /obj/item/weapon/cartridge/head
name = "\improper Easy-Record DELUXE" name = "\improper Easy-Record DELUXE cartridge"
icon_state = "cart-h" icon_state = "cart-h"
access_status_display = 1 access_status_display = 1
@@ -193,7 +194,7 @@ var/list/civilian_cartridges = list(
access_security = 1 access_security = 1
/obj/item/weapon/cartridge/hos /obj/item/weapon/cartridge/hos
name = "\improper R.O.B.U.S.T. DELUXE" name = "\improper R.O.B.U.S.T. DELUXE cartridge"
icon_state = "cart-hos" icon_state = "cart-hos"
access_status_display = 1 access_status_display = 1
access_security = 1 access_security = 1
@@ -203,21 +204,21 @@ var/list/civilian_cartridges = list(
. = ..() . = ..()
/obj/item/weapon/cartridge/ce /obj/item/weapon/cartridge/ce
name = "\improper Power-On DELUXE" name = "\improper Power-On DELUXE cartridge"
icon_state = "cart-ce" icon_state = "cart-ce"
access_status_display = 1 access_status_display = 1
access_engine = 1 access_engine = 1
access_atmos = 1 access_atmos = 1
/obj/item/weapon/cartridge/cmo /obj/item/weapon/cartridge/cmo
name = "\improper Med-U DELUXE" name = "\improper Med-U DELUXE cartridge"
icon_state = "cart-cmo" icon_state = "cart-cmo"
access_status_display = 1 access_status_display = 1
access_reagent_scanner = 1 access_reagent_scanner = 1
access_medical = 1 access_medical = 1
/obj/item/weapon/cartridge/rd /obj/item/weapon/cartridge/rd
name = "\improper Signal Ace DELUXE" name = "\improper Signal Ace DELUXE cartridge"
icon_state = "cart-rd" icon_state = "cart-rd"
access_status_display = 1 access_status_display = 1
access_reagent_scanner = 1 access_reagent_scanner = 1

View File

@@ -77,6 +77,8 @@
"Temperature" = planet.weather_holder.temperature - T0C, "Temperature" = planet.weather_holder.temperature - T0C,
"High" = planet.weather_holder.current_weather.temp_high - T0C, "High" = planet.weather_holder.current_weather.temp_high - T0C,
"Low" = planet.weather_holder.current_weather.temp_low - T0C, "Low" = planet.weather_holder.current_weather.temp_low - T0C,
"WindDir" = planet.weather_holder.wind_dir ? dir2text(planet.weather_holder.wind_dir) : "None",
"WindSpeed" = planet.weather_holder.wind_speed ? "[planet.weather_holder.wind_speed > 2 ? "Severe" : "Normal"]" : "None",
"Forecast" = english_list(planet.weather_holder.forecast, and_text = "&#8594;", comma_text = "&#8594;", final_comma_text = "&#8594;") // Unicode RIGHTWARDS ARROW. "Forecast" = english_list(planet.weather_holder.forecast, and_text = "&#8594;", comma_text = "&#8594;", final_comma_text = "&#8594;") // Unicode RIGHTWARDS ARROW.
) )
weather[++weather.len] = W weather[++weather.len] = W

View File

@@ -0,0 +1,110 @@
/obj/item/device/holowarrant
name = "warrant projector"
desc = "The practical paperwork replacement for the officer on the go."
icon_state = "holowarrant"
item_state = "flashtool"
throwforce = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
var/datum/data/record/warrant/active
//look at it
/obj/item/device/holowarrant/examine(mob/user)
. = ..()
if(active)
to_chat(user, "It's a holographic warrant for '[active.fields["namewarrant"]]'.")
if(in_range(user, src) || istype(user, /mob/observer/dead))
show_content(user)
else
to_chat(user, "<span class='notice'>You have to go closer if you want to read it.</span>")
//hit yourself with it
/obj/item/device/holowarrant/attack_self(mob/living/user as mob)
active = null
var/list/warrants = list()
if(!isnull(data_core.general))
for(var/datum/data/record/warrant/W in data_core.warrants)
warrants += W.fields["namewarrant"]
if(warrants.len == 0)
to_chat(user,"<span class='notice'>There are no warrants available</span>")
return
var/temp
temp = input(user, "Which warrant would you like to load?") as null|anything in warrants
for(var/datum/data/record/warrant/W in data_core.warrants)
if(W.fields["namewarrant"] == temp)
active = W
update_icon()
/obj/item/device/holowarrant/attackby(obj/item/weapon/W, mob/user)
if(active)
var/obj/item/weapon/card/id/I = W.GetIdCard()
if(I)
var/choice = alert(user, "Would you like to authorize this warrant?","Warrant authorization","Yes","No")
if(choice == "Yes")
active.fields["auth"] = "[I.registered_name] - [I.assignment ? I.assignment : "(Unknown)"]"
user.visible_message("<span class='notice'>You swipe \the [I] through the [src].</span>", \
"<span class='notice'>[user] swipes \the [I] through the [src].</span>")
return 1
..()
//hit other people with it
/obj/item/device/holowarrant/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
user.visible_message("<span class='notice'>You show the warrant to [M].</span>", \
"<span class='notice'>[user] holds up a warrant projector and shows the contents to [M].</span>")
M.examinate(src)
/obj/item/device/holowarrant/update_icon()
if(active)
icon_state = "holowarrant_filled"
else
icon_state = "holowarrant"
/obj/item/device/holowarrant/proc/show_content(mob/user, forceshow)
if(!active)
return
if(active.fields["arrestsearch"] == "arrest")
var/output = {"
<HTML><HEAD><TITLE>[active.fields["namewarrant"]]</TITLE></HEAD>
<BODY bgcolor='#FFFFFF'><center><large><b>Sol Central Government Colonial Marshal Bureau</b></large></br>
in the jurisdiction of the</br>
[using_map.boss_name] in [using_map.station_name]</br>
</br>
<b>ARREST WARRANT</b></center></br>
</br>
This document serves as authorization and notice for the arrest of _<u>[active.fields["namewarrant"]]</u>____ for the crime(s) of:</br>[active.fields["charges"]]</br>
</br>
Vessel or habitat: _<u>[using_map.station_name]</u>____</br>
</br>_<u>[active.fields["auth"]]</u>____</br>
<small>Person authorizing arrest</small></br>
</BODY></HTML>
"}
show_browser(user, output, "window=Warrant for the arrest of [active.fields["namewarrant"]]")
if(active.fields["arrestsearch"] == "search")
var/output= {"
<HTML><HEAD><TITLE>Search Warrant: [active.fields["namewarrant"]]</TITLE></HEAD>
<BODY bgcolor='#FFFFFF'><center>in the jurisdiction of the</br>
[using_map.boss_name] in [using_map.station_name]</br>
</br>
<b>SEARCH WARRANT</b></center></br>
</br>
<small><i>The Security Officer(s) bearing this Warrant are hereby authorized by the Issuer </br>
to conduct a one time lawful search of the Suspect's person/belongings/premises and/or Department </br>
for any items and materials that could be connected to the suspected criminal act described below, </br>
pending an investigation in progress. The Security Officer(s) are obligated to remove any and all</br>
such items from the Suspects posession and/or Department and file it as evidence. The Suspect/Department </br>
staff is expected to offer full co-operation. In the event of the Suspect/Department staff attempting </br>
to resist/impede this search or flee, they must be taken into custody immediately! </br>
All confiscated items must be filed and taken to Evidence!</small></i></br>
</br>
<b>Suspect's/location name: </b>[active.fields["namewarrant"]]</br>
</br>
<b>For the following reasons: </b> [active.fields["charges"]]</br>
</br>
<b>Warrant issued by: </b> [active.fields ["auth"]]</br>
</br>
Vessel or habitat: _<u>[using_map.station_name]</u>____</br>
</BODY></HTML>
"}
show_browser(user, output, "window=Search warrant for [active.fields["namewarrant"]]")

View File

@@ -422,7 +422,7 @@ var/global/list/default_medbay_channels = list(
subspace_transmission = FALSE subspace_transmission = FALSE
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote), return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name, src, message, displayname, jobname, real_name, M.voice_name,
signal.transmission_method, signal.data["compression"], list(position.z), connection.frequency,verb,speaking) signal.transmission_method, signal.data["compression"], GetConnectedZlevels(position.z), connection.frequency,verb,speaking)
/* ###### Intercoms and station-bounced radios ###### */ /* ###### Intercoms and station-bounced radios ###### */
@@ -491,7 +491,7 @@ var/global/list/default_medbay_channels = list(
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote), return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name, src, message, displayname, jobname, real_name, M.voice_name,
filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking) filter_type, signal.data["compression"], GetConnectedZlevels(position.z), connection.frequency,verb,speaking)
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null) /obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)

View File

@@ -21,6 +21,7 @@
/obj/item/device/subspaceradio /obj/item/device/subspaceradio
name = "subspace radio" name = "subspace radio"
desc = "A powerful new radio recently gifted to Nanotrasen from KHI, this communications device has the ability to send and recieve transmissions from anywhere." desc = "A powerful new radio recently gifted to Nanotrasen from KHI, this communications device has the ability to send and recieve transmissions from anywhere."
catalogue_data = list(/datum/category_item/catalogue/information/organization/khi)
icon = 'icons/vore/custom_items_vr.dmi' icon = 'icons/vore/custom_items_vr.dmi'
icon_override = 'icons/mob/back_vr.dmi' icon_override = 'icons/mob/back_vr.dmi'
icon_state = "radiopack" icon_state = "radiopack"

View File

@@ -74,7 +74,6 @@ var/datum/uplink_random_selection/all_uplink_selection = new/datum/uplink_random
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit) items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector) items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice) items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/camera_floppy, 10, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/heavy_vest) items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/heavy_vest)
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/combat) items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/combat)

View File

@@ -85,4 +85,12 @@ obj/item/weapon/circuitboard/rdserver/attackby(obj/item/I as obj, mob/user as mo
/obj/item/weapon/stock_parts/matter_bin = 2, /obj/item/weapon/stock_parts/matter_bin = 2,
/obj/item/weapon/stock_parts/manipulator = 1, /obj/item/weapon/stock_parts/manipulator = 1,
/obj/item/weapon/stock_parts/micro_laser = 1, /obj/item/weapon/stock_parts/micro_laser = 1,
/obj/item/weapon/stock_parts/console_screen = 1) /obj/item/weapon/stock_parts/console_screen = 1)
obj/item/weapon/circuitboard/ntnet_relay
name = "Circuit board (NTNet Quantum Relay)"
build_path = "/obj/machinery/ntnet_relay"
board_type = "machine"
origin_tech = list(TECH_DATA = 4)
req_components = list(
"/obj/item/stack/cable_coil" = 15)

View File

@@ -36,3 +36,16 @@
name = "box of command keys" name = "box of command keys"
desc = "A box full of service keys, for the HoP to give out as necessary." desc = "A box full of service keys, for the HoP to give out as necessary."
starts_with = list(/obj/item/device/encryptionkey/headset_service = 7) starts_with = list(/obj/item/device/encryptionkey/headset_service = 7)
/obj/item/weapon/storage/box/survival/space
name = "boxed emergency suit and helmet"
icon_state = "survivaleng"
starts_with = list(
/obj/item/clothing/suit/space/emergency,
/obj/item/clothing/head/helmet/space/emergency,
/obj/item/clothing/mask/breath,
/obj/item/weapon/tank/emergency/oxygen/double
)
/obj/item/weapon/storage/secure/briefcase/trashmoney
starts_with = list(/obj/item/weapon/spacecash/c200 = 10)

View File

@@ -1,4 +1,64 @@
/obj/item/weapon/storage/pill_bottle/adminordrazine
name = "bottle of Adminordrazine pills"
desc = "It's magic. We don't have to explain it."
starts_with = list(/obj/item/weapon/reagent_containers/pill/adminordrazine = 21)
/obj/item/weapon/storage/pill_bottle/nutriment /obj/item/weapon/storage/pill_bottle/nutriment
name = "bottle of Nutriment pills" name = "bottle of Food pills"
desc = "Contains pills used to feed people." desc = "Contains pills used to feed people."
starts_with = list(/obj/item/weapon/reagent_containers/pill/nutriment = 7) starts_with = list(/obj/item/weapon/reagent_containers/pill/nutriment = 7, /obj/item/weapon/reagent_containers/pill/protein = 7)
/obj/item/weapon/storage/pill_bottle/rezadone
name = "bottle of Rezadone pills"
desc = "A powder with almost magical properties, this substance can effectively treat genetic damage in humanoids, though excessive consumption has side effects."
starts_with = list(/obj/item/weapon/reagent_containers/pill/rezadone = 7)
/obj/item/weapon/storage/pill_bottle/peridaxon
name = "bottle of Peridaxon pills"
desc = "Used to encourage recovery of internal organs and nervous systems. Medicate cautiously."
starts_with = list(/obj/item/weapon/reagent_containers/pill/peridaxon = 7)
/obj/item/weapon/storage/pill_bottle/carthatoline
name = "bottle of Carthatoline pills"
desc = "Carthatoline is strong evacuant used to treat severe poisoning."
starts_with = list(/obj/item/weapon/reagent_containers/pill/carthatoline = 7)
/obj/item/weapon/storage/pill_bottle/alkysine
name = "bottle of Alkysine pills"
desc = "Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue."
starts_with = list(/obj/item/weapon/reagent_containers/pill/alkysine = 7)
/obj/item/weapon/storage/pill_bottle/imidazoline
name = "bottle of Imidazoline pills"
desc = "Heals eye damage."
starts_with = list(/obj/item/weapon/reagent_containers/pill/imidazoline = 7)
/obj/item/weapon/storage/pill_bottle/osteodaxon
name = "bottle of Osteodaxon pills"
desc = "An experimental drug used to heal bone fractures."
starts_with = list(/obj/item/weapon/reagent_containers/pill/osteodaxon = 7)
/obj/item/weapon/storage/pill_bottle/myelamine
name = "bottle of Myelamine pills"
desc = "Used to rapidly clot internal hemorrhages by increasing the effectiveness of platelets."
starts_with = list(/obj/item/weapon/reagent_containers/pill/myelamine = 7)
/obj/item/weapon/storage/pill_bottle/hyronalin
name = "bottle of Hyronalin pills"
desc = "Hyronalin is a medicinal drug used to counter the effect of radiation poisoning."
starts_with = list(/obj/item/weapon/reagent_containers/pill/hyronalin = 7)
/obj/item/weapon/storage/pill_bottle/arithrazine
name = "bottle of Arithrazine pills"
desc = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning."
starts_with = list(/obj/item/weapon/reagent_containers/pill/arithrazine = 7)
/obj/item/weapon/storage/pill_bottle/corophizine
name = "bottle of Corophizine pills"
desc = "A wide-spectrum antibiotic drug. Powerful and uncomfortable in equal doses."
starts_with = list(/obj/item/weapon/reagent_containers/pill/corophizine = 7)
/obj/item/weapon/storage/pill_bottle/healing_nanites
name = "bottle of Healing nanites capsules"
desc = "Miniature medical robots that swiftly restore bodily damage."
starts_with = list(/obj/item/weapon/reagent_containers/pill/healing_nanites = 7)

View File

@@ -0,0 +1,10 @@
/obj/item/weapon/storage/toolbox/lunchbox/survival
name = "survival lunchbox"
icon = 'icons/obj/storage_vr.dmi'
icon_state = "lunchbox_survival"
item_state_slots = list(slot_r_hand_str = "toolbox_syndi", slot_l_hand_str = "toolbox_syndi")
desc = "A little lunchbox. This one seems to be much sturdier than normal, made of a durable steel!"
max_storage_space = ITEMSIZE_COST_SMALL * 6
/obj/item/weapon/storage/toolbox/lunchbox/survival/zaddat
starts_with = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 6)

View File

@@ -515,6 +515,7 @@
name = "\improper NanoTrasen" name = "\improper NanoTrasen"
desc = "An old metal sign which reads 'NanoTrasen'." desc = "An old metal sign which reads 'NanoTrasen'."
icon_state = "NT" icon_state = "NT"
catalogue_data = list(/datum/category_item/catalogue/information/organization/nanotrasen)
// Eris standards compliant hazards // Eris standards compliant hazards
/obj/structure/sign/signnew /obj/structure/sign/signnew

View File

@@ -20,6 +20,7 @@
var/global/list/unique_gamma = list( var/global/list/unique_gamma = list(
/obj/item/device/perfect_tele, /obj/item/device/perfect_tele,
/obj/item/weapon/bluespace_harpoon, /obj/item/weapon/bluespace_harpoon,
/obj/item/clothing/glasses/thermal/syndi,
/obj/item/weapon/gun/energy/netgun, /obj/item/weapon/gun/energy/netgun,
/obj/item/weapon/gun/projectile/pirate, /obj/item/weapon/gun/projectile/pirate,
/obj/item/clothing/accessory/permit/gun, /obj/item/clothing/accessory/permit/gun,
@@ -222,13 +223,13 @@
prob(4);/obj/item/weapon/storage/pill_bottle/happy, prob(4);/obj/item/weapon/storage/pill_bottle/happy,
prob(4);/obj/item/weapon/storage/pill_bottle/zoom, prob(4);/obj/item/weapon/storage/pill_bottle/zoom,
prob(4);/obj/item/weapon/gun/energy/sizegun, prob(4);/obj/item/weapon/gun/energy/sizegun,
prob(3);/obj/item/weapon/implanter/sizecontrol,
prob(3);/obj/item/weapon/material/butterfly, prob(3);/obj/item/weapon/material/butterfly,
prob(3);/obj/item/weapon/material/butterfly/switchblade, prob(3);/obj/item/weapon/material/butterfly/switchblade,
prob(3);/obj/item/clothing/gloves/knuckledusters, prob(3);/obj/item/clothing/gloves/knuckledusters,
prob(3);/obj/item/weapon/reagent_containers/syringe/drugs, prob(3);/obj/item/weapon/reagent_containers/syringe/drugs,
prob(2);/obj/item/weapon/implanter/sizecontrol,
prob(2);/obj/item/weapon/handcuffs/fuzzy, prob(2);/obj/item/weapon/handcuffs/fuzzy,
// prob(2);/obj/item/weapon/legcuffs, prob(2);/obj/item/weapon/handcuffs/legcuffs/fuzzy,
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy, prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
prob(2);/obj/item/weapon/grenade/anti_photon, prob(2);/obj/item/weapon/grenade/anti_photon,
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc, prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
@@ -240,6 +241,8 @@
prob(1);/obj/item/weapon/cell/hyper/empty, prob(1);/obj/item/weapon/cell/hyper/empty,
prob(1);/obj/item/weapon/disk/nifsoft/compliance, prob(1);/obj/item/weapon/disk/nifsoft/compliance,
prob(1);/obj/item/weapon/material/knife/tacknife, prob(1);/obj/item/weapon/material/knife/tacknife,
prob(1);/obj/item/weapon/storage/box/survival/space,
prob(1);/obj/item/weapon/storage/secure/briefcase/trashmoney,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid) prob(1);/obj/item/weapon/reagent_containers/syringe/steroid)
var/obj/item/I = new path() var/obj/item/I = new path()

View File

@@ -159,6 +159,7 @@ var/world_topic_spam_protect_time = world.timeofday
"med" = medical_positions, "med" = medical_positions,
"sci" = science_positions, "sci" = science_positions,
"car" = cargo_positions, "car" = cargo_positions,
"pla" = planet_positions, //VOREStation Edit,
"civ" = civilian_positions, "civ" = civilian_positions,
"bot" = nonhuman_positions "bot" = nonhuman_positions
) )

View File

@@ -173,7 +173,7 @@ var/max_explosion_range = 14
// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it. // Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it.
var/global/obj/item/device/radio/intercom/omni/global_announcer = new /obj/item/device/radio/intercom/omni(null) var/global/obj/item/device/radio/intercom/omni/global_announcer = new /obj/item/device/radio/intercom/omni(null)
var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Exploration", "Civilian") //VOREStation Edit
//Icons for in-game HUD glasses. Why don't we just share these a little bit? //Icons for in-game HUD glasses. Why don't we just share these a little bit?
var/static/icon/ingame_hud = icon('icons/mob/hud.dmi') var/static/icon/ingame_hud = icon('icons/mob/hud.dmi')

View File

@@ -516,7 +516,28 @@
jobs += "</tr><tr align='center'>" jobs += "</tr><tr align='center'>"
counter = 0 counter = 0
jobs += "</tr></table>" jobs += "</tr></table>"
//VOREStation Edit Start
//Exploration (Purple)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='e79fff'><th colspan='[length(planet_positions)]'><a href='?src=\ref[src];jobban3=explorationdept;jobban4=\ref[M]'>Exploration Positions</a></th></tr><tr align='center'>"
for(var/jobPos in planet_positions)
if(!jobPos) continue
var/datum/job/job = job_master.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//VOREstation Edit End
//Civilian (Grey) //Civilian (Grey)
counter = 0 counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>" jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
@@ -670,6 +691,14 @@
var/datum/job/temp = job_master.GetJob(jobPos) var/datum/job/temp = job_master.GetJob(jobPos)
if(!temp) continue if(!temp) continue
joblist += temp.title joblist += temp.title
//VOREStation Edit Start
if("explorationdept")
for(var/jobPos in planet_positions)
if(!jobPos) continue
var/datum/job/temp = job_master.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
//VOREStation Edit End
if("civiliandept") if("civiliandept")
for(var/jobPos in civilian_positions) for(var/jobPos in civilian_positions)
if(!jobPos) continue if(!jobPos) continue

View File

@@ -575,15 +575,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
return return
if(!customname) if(!customname)
customname = "[using_map.company_name] Update" customname = "[using_map.company_name] Update"
for (var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) ) //New message handling
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc ) post_comm_message(customname, replacetext(input, "\n", "<br/>"))
P.name = "'[command_name()] Update.'"
P.info = replacetext(input, "\n", "<br/>")
P.update_space(P.info)
P.update_icon()
C.messagetitle.Add("[command_name()] Update")
C.messagetext.Add(P.info)
switch(alert("Should this be announced to the general population?",,"Yes","No")) switch(alert("Should this be announced to the general population?",,"Yes","No"))
if("Yes") if("Yes")

View File

@@ -1,275 +1,291 @@
// Specialized AI for slime simplemobs. // Specialized AI for slime simplemobs.
// Unlike the parent AI code, this will probably break a lot of things if you put it on something that isn't /mob/living/simple_mob/slime/xenobio // Unlike the parent AI code, this will probably break a lot of things if you put it on something that isn't /mob/living/simple_mob/slime/xenobio
/datum/ai_holder/simple_mob/xenobio_slime /datum/ai_holder/simple_mob/xenobio_slime
hostile = TRUE hostile = TRUE
cooperative = TRUE cooperative = TRUE
firing_lanes = TRUE firing_lanes = TRUE
mauling = TRUE // They need it to get the most out of monkeys. mauling = TRUE // They need it to get the most out of monkeys.
var/rabid = FALSE // Will attack regardless of discipline. var/rabid = FALSE // Will attack regardless of discipline.
var/discipline = 0 // Beating slimes makes them less likely to lash out. In theory. var/discipline = 0 // Beating slimes makes them less likely to lash out. In theory.
var/resentment = 0 // 'Unjustified' beatings make this go up, and makes it more likely for abused slimes to go rabid. var/resentment = 0 // 'Unjustified' beatings make this go up, and makes it more likely for abused slimes to go rabid.
var/obedience = 0 // Conversely, 'justified' beatings make this go up, and makes discipline decay slower, potentially making it not decay at all. var/obedience = 0 // Conversely, 'justified' beatings make this go up, and makes discipline decay slower, potentially making it not decay at all.
var/always_stun = FALSE // If true, the slime will elect to attempt to permastun the target. var/always_stun = FALSE // If true, the slime will elect to attempt to permastun the target.
var/last_discipline_decay = null // Last world.time discipline was reduced from decay. var/last_discipline_decay = null // Last world.time discipline was reduced from decay.
var/discipline_decay_time = 5 SECONDS // Earliest that one discipline can decay. var/discipline_decay_time = 5 SECONDS // Earliest that one discipline can decay.
/datum/ai_holder/simple_mob/xenobio_slime/sapphire var/list/grudges = list() // List of Prometheans who are jerks.
always_stun = TRUE // They know that stuns are godly.
intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death. /datum/ai_holder/simple_mob/xenobio_slime/Destroy()
grudges.Cut()
/datum/ai_holder/simple_mob/xenobio_slime/light_pink ..()
discipline = 10
obedience = 10 /datum/ai_holder/simple_mob/xenobio_slime/sapphire
always_stun = TRUE // They know that stuns are godly.
/datum/ai_holder/simple_mob/xenobio_slime/passive/New() // For Kendrick. intelligence_level = AI_SMART // Also knows not to walk while confused if it risks death.
..()
pacify() /datum/ai_holder/simple_mob/xenobio_slime/light_pink
discipline = 10
/datum/ai_holder/simple_mob/xenobio_slime/New() obedience = 10
..()
ASSERT(istype(holder, /mob/living/simple_mob/slime/xenobio)) /datum/ai_holder/simple_mob/xenobio_slime/passive/New() // For Kendrick.
..()
// Checks if disciplining the slime would be 'justified' right now. pacify()
/datum/ai_holder/simple_mob/xenobio_slime/proc/is_justified_to_discipline()
ai_log("xenobio_slime/is_justified_to_discipline() : Entered.", AI_LOG_TRACE) /datum/ai_holder/simple_mob/xenobio_slime/New()
if(!can_act()) ..()
ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be unjustified because we cannot act. Exiting.", AI_LOG_DEBUG) ASSERT(istype(holder, /mob/living/simple_mob/slime/xenobio))
return FALSE // The slime considers it abuse if they get stunned while already stunned.
if(rabid) // Checks if disciplining the slime would be 'justified' right now.
ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be justified because we're rabid. Exiting.", AI_LOG_TRACE) /datum/ai_holder/simple_mob/xenobio_slime/proc/is_justified_to_discipline()
return TRUE ai_log("xenobio_slime/is_justified_to_discipline() : Entered.", AI_LOG_TRACE)
if(target && can_attack(target)) if(!can_act())
if(ishuman(target)) ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be unjustified because we cannot act. Exiting.", AI_LOG_DEBUG)
var/mob/living/carbon/human/H = target return FALSE // The slime considers it abuse if they get stunned while already stunned.
if(istype(H.species, /datum/species/monkey)) if(rabid)
ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be unjustified because we're targeting a monkey. Exiting.", AI_LOG_DEBUG) ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be justified because we're rabid. Exiting.", AI_LOG_TRACE)
return FALSE // Attacking monkeys is okay. return TRUE
ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be justified because we are targeting a non-monkey. Exiting.", AI_LOG_TRACE) if(target && can_attack(target))
return TRUE // Otherwise attacking other things is bad. if(ishuman(target))
ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be unjustified because we are not targeting anything. Exiting.", AI_LOG_DEBUG) var/mob/living/carbon/human/H = target
return FALSE // Not attacking anything. if(istype(H.species, /datum/species/monkey))
ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be unjustified because we're targeting a monkey. Exiting.", AI_LOG_DEBUG)
/datum/ai_holder/simple_mob/xenobio_slime/proc/can_command(mob/living/commander) return FALSE // Attacking monkeys is okay.
if(rabid) ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be justified because we are targeting a non-monkey. Exiting.", AI_LOG_TRACE)
return FALSE return TRUE // Otherwise attacking other things is bad.
if(!hostile) ai_log("xenobio_slime/is_justified_to_discipline() : Judged to be unjustified because we are not targeting anything. Exiting.", AI_LOG_DEBUG)
return SLIME_COMMAND_OBEY return FALSE // Not attacking anything.
// if(commander in friends)
// return SLIME_COMMAND_FRIEND /datum/ai_holder/simple_mob/xenobio_slime/proc/can_command(mob/living/commander)
if(holder.IIsAlly(commander)) if(rabid)
return SLIME_COMMAND_FACTION return FALSE
if(discipline > resentment && obedience >= 5) if(!hostile)
return SLIME_COMMAND_OBEY return SLIME_COMMAND_OBEY
return FALSE // if(commander in friends)
// return SLIME_COMMAND_FRIEND
/datum/ai_holder/simple_mob/xenobio_slime/proc/adjust_discipline(amount, silent) if(holder.IIsAlly(commander))
var/mob/living/simple_mob/slime/xenobio/my_slime = holder return SLIME_COMMAND_FACTION
if(amount > 0) if(discipline > resentment && obedience >= 5)
if(rabid) return SLIME_COMMAND_OBEY
return return FALSE
var/justified = my_slime.is_justified_to_discipline() // This will also consider the AI-side of that proc.
lost_target() // Stop attacking. /datum/ai_holder/simple_mob/xenobio_slime/proc/adjust_discipline(amount, silent)
var/mob/living/simple_mob/slime/xenobio/my_slime = holder
if(justified) if(amount > 0)
obedience++ if(rabid)
if(!silent) return
holder.say(pick("Fine...", "Okay...", "Sorry...", "I yield...", "Mercy...")) var/justified = my_slime.is_justified_to_discipline() // This will also consider the AI-side of that proc.
else lost_target() // Stop attacking.
if(prob(resentment * 20))
enrage() if(justified)
holder.say(pick("Evil...", "Kill...", "Tyrant...")) obedience++
else if(!silent)
if(!silent) holder.say(pick("Fine...", "Okay...", "Sorry...", "I yield...", "Mercy..."))
holder.say(pick("Why...?", "I don't understand...?", "Cruel...", "Stop...", "Nooo...")) else
resentment++ // Done after check so first time will never enrage. if(prob(resentment * 20))
enrage()
discipline = between(0, discipline + amount, 10) holder.say(pick("Evil...", "Kill...", "Tyrant..."))
my_slime.update_mood() else
if(!silent)
// This slime always enrages if disciplined. holder.say(pick("Why...?", "I don't understand...?", "Cruel...", "Stop...", "Nooo..."))
/datum/ai_holder/simple_mob/xenobio_slime/red/adjust_discipline(amount, silent) resentment++ // Done after check so first time will never enrage.
if(amount > 0 && !rabid)
holder.say("Grrr...") discipline = between(0, discipline + amount, 10)
holder.add_modifier(/datum/modifier/berserk, 30 SECONDS) my_slime.update_mood()
enrage()
// This slime always enrages if disciplined.
/datum/ai_holder/simple_mob/xenobio_slime/handle_special_strategical() /datum/ai_holder/simple_mob/xenobio_slime/red/adjust_discipline(amount, silent)
discipline_decay() if(amount > 0 && !rabid)
holder.say("Grrr...")
// Handles decay of discipline. holder.add_modifier(/datum/modifier/berserk, 30 SECONDS)
/datum/ai_holder/simple_mob/xenobio_slime/proc/discipline_decay() enrage()
if(discipline > 0 && last_discipline_decay + discipline_decay_time < world.time)
if(!prob(75 + (obedience * 5))) /datum/ai_holder/simple_mob/xenobio_slime/handle_special_strategical()
adjust_discipline(-1) discipline_decay()
last_discipline_decay = world.time
// Handles decay of discipline.
/datum/ai_holder/simple_mob/xenobio_slime/handle_special_tactic() /datum/ai_holder/simple_mob/xenobio_slime/proc/discipline_decay()
evolve_and_reproduce() if(discipline > 0 && last_discipline_decay + discipline_decay_time < world.time)
if(!prob(75 + (obedience * 5)))
// Hit the correct verbs to keep the slime species going. adjust_discipline(-1)
/datum/ai_holder/simple_mob/xenobio_slime/proc/evolve_and_reproduce() last_discipline_decay = world.time
var/mob/living/simple_mob/slime/xenobio/my_slime = holder
if(my_slime.amount_grown >= 10) /datum/ai_holder/simple_mob/xenobio_slime/handle_special_tactic()
// Press the correct verb when we can. evolve_and_reproduce()
if(my_slime.is_adult)
my_slime.reproduce() // Splits into four new baby slimes. // Hit the correct verbs to keep the slime species going.
else /datum/ai_holder/simple_mob/xenobio_slime/proc/evolve_and_reproduce()
my_slime.evolve() // Turns our holder into an adult slime. var/mob/living/simple_mob/slime/xenobio/my_slime = holder
if(my_slime.amount_grown >= 10)
// Press the correct verb when we can.
// Called when pushed too far (or a red slime core was used). if(my_slime.is_adult)
/datum/ai_holder/simple_mob/xenobio_slime/proc/enrage() my_slime.reproduce() // Splits into four new baby slimes.
var/mob/living/simple_mob/slime/xenobio/my_slime = holder else
if(my_slime.harmless) my_slime.evolve() // Turns our holder into an adult slime.
return
rabid = TRUE
my_slime.update_mood() // Called when pushed too far (or a red slime core was used).
my_slime.visible_message(span("danger", "\The [src] enrages!")) /datum/ai_holder/simple_mob/xenobio_slime/proc/enrage()
var/mob/living/simple_mob/slime/xenobio/my_slime = holder
// Called when using a pacification agent (or it's Kendrick being initalized). if(my_slime.harmless)
/datum/ai_holder/simple_mob/xenobio_slime/proc/pacify() return
lost_target() // So it stops trying to kill them. rabid = TRUE
rabid = FALSE my_slime.update_mood()
hostile = FALSE my_slime.visible_message(span("danger", "\The [src] enrages!"))
retaliate = FALSE
cooperative = FALSE // Called when using a pacification agent (or it's Kendrick being initalized).
/datum/ai_holder/simple_mob/xenobio_slime/proc/pacify()
// The holder's attack changes based on intent. This lets the AI choose what effect is desired. lost_target() // So it stops trying to kill them.
/datum/ai_holder/simple_mob/xenobio_slime/pre_melee_attack(atom/A) rabid = FALSE
if(istype(A, /mob/living)) hostile = FALSE
var/mob/living/L = A retaliate = FALSE
var/mob/living/simple_mob/slime/xenobio/my_slime = holder cooperative = FALSE
if( (!L.lying && prob(30 + (my_slime.power_charge * 7) ) || (!L.lying && always_stun) )) // The holder's attack changes based on intent. This lets the AI choose what effect is desired.
my_slime.a_intent = I_DISARM // Stun them first. /datum/ai_holder/simple_mob/xenobio_slime/pre_melee_attack(atom/A)
else if(my_slime.can_consume(L) && L.lying) if(istype(A, /mob/living))
my_slime.a_intent = I_GRAB // Then eat them. var/mob/living/L = A
else var/mob/living/simple_mob/slime/xenobio/my_slime = holder
my_slime.a_intent = I_HURT // Otherwise robust them.
if( (!L.lying && prob(30 + (my_slime.power_charge * 7) ) || (!L.lying && always_stun) ))
/datum/ai_holder/simple_mob/xenobio_slime/closest_distance(atom/movable/AM) my_slime.a_intent = I_DISARM // Stun them first.
if(istype(AM, /mob/living)) else if(my_slime.can_consume(L) && L.lying)
var/mob/living/L = AM my_slime.a_intent = I_GRAB // Then eat them.
if(ishuman(L)) else
var/mob/living/carbon/human/H = L my_slime.a_intent = I_HURT // Otherwise robust them.
if(istype(H.species, /datum/species/monkey))
return 1 // Otherwise ranged slimes will eat a lot less often. /datum/ai_holder/simple_mob/xenobio_slime/closest_distance(atom/movable/AM)
if(L.stat >= UNCONSCIOUS) if(istype(AM, /mob/living))
return 1 // Melee (eat) the target if dead/dying, don't shoot it. var/mob/living/L = AM
return ..() if(ishuman(L))
var/mob/living/carbon/human/H = L
/datum/ai_holder/simple_mob/xenobio_slime/can_attack(atom/movable/AM) if(istype(H.species, /datum/species/monkey))
. = ..() return 1 // Otherwise ranged slimes will eat a lot less often.
if(.) // Do some additional checks because we have Special Code(tm). if(L.stat >= UNCONSCIOUS)
if(ishuman(AM)) return 1 // Melee (eat) the target if dead/dying, don't shoot it.
var/mob/living/carbon/human/H = AM return ..()
if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
return TRUE // Monkeys are always food (sorry Pun Pun). /datum/ai_holder/simple_mob/xenobio_slime/can_attack(atom/movable/AM)
else if(H.species && H.species.name == SPECIES_PROMETHEAN) . = ..()
return FALSE // Prometheans are always our friends. if(.) // Do some additional checks because we have Special Code(tm).
if(discipline && !rabid) if(ishuman(AM))
return FALSE // We're a good slime. var/mob/living/carbon/human/H = AM
if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too.
// Commands, reactions, etc return TRUE // Monkeys are always food (sorry Pun Pun).
/datum/ai_holder/simple_mob/xenobio_slime/on_hear_say(mob/living/speaker, message) else if(H.species && H.species.name == SPECIES_PROMETHEAN) // Prometheans are always our friends.
ai_log("xenobio_slime/on_hear_say([speaker], [message]) : Entered.", AI_LOG_DEBUG) if(H in grudges) // Unless they're an ass.
var/mob/living/simple_mob/slime/xenobio/my_slime = holder return TRUE
return FALSE
if((findtext(message, num2text(my_slime.number)) || findtext(message, my_slime.name) || findtext(message, "slimes"))) // Talking to us. if(discipline && !rabid)
return FALSE // We're a good slime.
// First, make sure it's actually a player saying something and not an AI, or else we risk infinite loops.
if(!speaker.client) /datum/ai_holder/simple_mob/xenobio_slime/react_to_attack(atom/movable/attacker)
return . = ..(attacker)
// Are all slimes being referred to? if(ishuman(attacker))
// var/mass_order = FALSE var/mob/living/carbon/human/H = attacker
// if(findtext(message, "slimes")) if(H.species && H.species.name == SPECIES_PROMETHEAN) // They're a jerk.
// mass_order = TRUE grudges |= H
// Say hello back. // Commands, reactions, etc
if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings")) /datum/ai_holder/simple_mob/xenobio_slime/on_hear_say(mob/living/speaker, message)
delayed_say(pick("Hello...", "Hi..."), speaker) ai_log("xenobio_slime/on_hear_say([speaker], [message]) : Entered.", AI_LOG_DEBUG)
var/mob/living/simple_mob/slime/xenobio/my_slime = holder
// Follow request.
if(findtext(message, "follow") || findtext(message, "come with me")) if((findtext(message, num2text(my_slime.number)) || findtext(message, my_slime.name) || findtext(message, "slimes"))) // Talking to us.
if(!can_command(speaker))
delayed_say(pick("No...", "I won't follow..."), speaker) // First, make sure it's actually a player saying something and not an AI, or else we risk infinite loops.
return if(!speaker.client)
return
delayed_say("Yes... I follow \the [speaker]...", speaker)
set_follow(speaker) // Are all slimes being referred to?
// var/mass_order = FALSE
// Squish request. // if(findtext(message, "slimes"))
if(findtext(message , "squish")) // mass_order = TRUE
if(!can_command(speaker))
delayed_say("No...", speaker) // Say hello back.
return if(findtext(message, "hello") || findtext(message, "hi") || findtext(message, "greetings"))
delayed_say(pick("Hello...", "Hi..."), speaker)
spawn(rand(1 SECOND, 2 SECONDS))
if(!src || !holder || !can_act()) // We might've died/got deleted/etc in the meantime. // Follow request.
return if(findtext(message, "follow") || findtext(message, "come with me"))
my_slime.squish() if(!can_command(speaker))
delayed_say(pick("No...", "I won't follow..."), speaker)
return
// Stop request.
if(findtext(message, "stop") || findtext(message, "halt") || findtext(message, "cease")) delayed_say("Yes... I follow \the [speaker]...", speaker)
if(my_slime.victim) // We're being asked to stop eatting someone. set_follow(speaker)
if(!can_command(speaker) || !is_justified_to_discipline())
delayed_say("No...", speaker) // Squish request.
return if(findtext(message , "squish"))
else if(!can_command(speaker))
delayed_say("Fine...", speaker) delayed_say("No...", speaker)
adjust_discipline(1, TRUE) return
my_slime.stop_consumption()
spawn(rand(1 SECOND, 2 SECONDS))
if(target) // We're being asked to stop chasing someone. if(!src || !holder || !can_act()) // We might've died/got deleted/etc in the meantime.
if(!can_command(speaker) || !is_justified_to_discipline()) return
delayed_say("No...", speaker) my_slime.squish()
return
else
delayed_say("Fine...", speaker) // Stop request.
adjust_discipline(1, TRUE) // This must come before losing the target or it will be unjustified. if(findtext(message, "stop") || findtext(message, "halt") || findtext(message, "cease"))
lost_target() if(my_slime.victim) // We're being asked to stop eatting someone.
if(!can_command(speaker) || !is_justified_to_discipline())
delayed_say("No...", speaker)
if(leader) // We're being asked to stop following someone. return
if(can_command(speaker) == SLIME_COMMAND_FRIEND || leader == speaker) else
delayed_say("Yes... I'll stop...", speaker) delayed_say("Fine...", speaker)
lose_follow() adjust_discipline(1, TRUE)
else my_slime.stop_consumption()
delayed_say("No... I'll keep following \the [leader]...", speaker)
if(target) // We're being asked to stop chasing someone.
/* // Commented out since its mostly useless now due to slimes refusing to attack if it would make them naughty. if(!can_command(speaker) || !is_justified_to_discipline())
// Murder request delayed_say("No...", speaker)
if(findtext(message, "harm") || findtext(message, "attack") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume") || findtext(message, "absorb")) return
if(can_command(speaker) < SLIME_COMMAND_FACTION) else
delayed_say("No...", speaker) delayed_say("Fine...", speaker)
return adjust_discipline(1, TRUE) // This must come before losing the target or it will be unjustified.
lost_target()
for(var/mob/living/L in view(7, my_slime) - list(my_slime, speaker))
if(L == src)
continue // Don't target ourselves. if(leader) // We're being asked to stop following someone.
var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example. if(can_command(speaker) == SLIME_COMMAND_FRIEND || leader == speaker)
for(var/line in valid_names) // Check each part of someone's name. delayed_say("Yes... I'll stop...", speaker)
if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to. lose_follow()
if(!(mass_order && line == "slime")) //don't think random other slimes are target else
if(can_attack(L)) delayed_say("No... I'll keep following \the [leader]...", speaker)
delayed_say("Okay... I attack \the [L]...", speaker)
give_target(L) /* // Commented out since its mostly useless now due to slimes refusing to attack if it would make them naughty.
return // Murder request
else if(findtext(message, "harm") || findtext(message, "attack") || findtext(message, "kill") || findtext(message, "murder") || findtext(message, "eat") || findtext(message, "consume") || findtext(message, "absorb"))
delayed_say("No... I won't attack \the [L].", speaker) if(can_command(speaker) < SLIME_COMMAND_FACTION)
return delayed_say("No...", speaker)
return
// If we're here, it couldn't find anyone with that name.
delayed_say("No... I don't know who to attack...", speaker) for(var/mob/living/L in view(7, my_slime) - list(my_slime, speaker))
*/ if(L == src)
ai_log("xenobio_slime/on_hear_say() : Exited.", AI_LOG_DEBUG) continue // Don't target ourselves.
var/list/valid_names = splittext(L.name, " ") // Should output list("John", "Doe") as an example.
/datum/ai_holder/simple_mob/xenobio_slime/can_violently_breakthrough() for(var/line in valid_names) // Check each part of someone's name.
if(discipline && !rabid) // Good slimes don't shatter the windows because their buddy in an adjacent cell decided to piss off Slimesky. if(findtext(message, lowertext(line))) // If part of someone's name is in the command, the slime targets them if allowed to.
return FALSE if(!(mass_order && line == "slime")) //don't think random other slimes are target
return ..() if(can_attack(L))
delayed_say("Okay... I attack \the [L]...", speaker)
give_target(L)
return
else
delayed_say("No... I won't attack \the [L].", speaker)
return
// If we're here, it couldn't find anyone with that name.
delayed_say("No... I don't know who to attack...", speaker)
*/
ai_log("xenobio_slime/on_hear_say() : Exited.", AI_LOG_DEBUG)
/datum/ai_holder/simple_mob/xenobio_slime/can_violently_breakthrough()
if(discipline && !rabid) // Good slimes don't shatter the windows because their buddy in an adjacent cell decided to piss off Slimesky.
return FALSE
return ..()

View File

@@ -56,12 +56,8 @@
/datum/ai_holder/proc/pick_target(list/targets) /datum/ai_holder/proc/pick_target(list/targets)
if(target != null) // If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets. if(target != null) // If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets.
targets = target_filter_distance(targets) targets = target_filter_distance(targets)
// for(var/possible_target in targets) else
// var/atom/A = possible_target targets = target_filter_closest(targets)
// var/target_dist = get_dist(holder, target)
// var/possible_target_distance = get_dist(holder, A)
// if(target_dist < possible_target_distance)
// targets -= A
if(!targets.len) // We found nothing. if(!targets.len) // We found nothing.
return return
@@ -95,6 +91,23 @@
targets -= A targets -= A
return targets return targets
/datum/ai_holder/proc/target_filter_closest(list/targets)
var/lowest_distance = -1
var/list/sorted_targets = list()
for(var/possible_target in targets)
var/atom/A = possible_target
var/current_distance = get_dist(holder, A)
if(lowest_distance == -1)
lowest_distance = current_distance
sorted_targets += A
else if(current_distance < lowest_distance)
targets.Cut()
lowest_distance = current_distance
sorted_targets += A
else if(current_distance == lowest_distance)
sorted_targets += A
return sorted_targets
/datum/ai_holder/proc/can_attack(atom/movable/the_target) /datum/ai_holder/proc/can_attack(atom/movable/the_target)
if(!can_see_target(the_target)) if(!can_see_target(the_target))
return FALSE return FALSE

View File

@@ -50,6 +50,11 @@
/datum/alarm_handler/proc/major_alarms() /datum/alarm_handler/proc/major_alarms()
return visible_alarms() return visible_alarms()
/datum/alarm_handler/proc/has_major_alarms()
if(alarms && alarms.len)
return 1
return 0
/datum/alarm_handler/proc/minor_alarms() /datum/alarm_handler/proc/minor_alarms()
return visible_alarms() return visible_alarms()

View File

@@ -0,0 +1,76 @@
//TODO: VIRGO_LORE_WRITING_WIP - this whole file
/datum/category_item/catalogue/fauna/akula
name = "Sapients - Akula"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/sergal
name = "Sapients - Sergal"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/nevrean
name = "Sapients - Nevrean"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/rapala
name = "Sapients - Rapala"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/xenochimera
name = "Sapients - Xenochimera"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/vulpkanin
name = "Sapients - Vulpkanin"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/alraune
name = "Sapients - Alraune"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/vasilissan
name = "Sapients - Vasilissan"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/xenohybrid
name = "Sapients - Xenomorph Hybrid"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/zorren
name = "Sapients - Zorren"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/highzorren
name = "Sapients - Highlander Zorren"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/flatzorren
name = "Sapients - Flatlander Zorren"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/fauna/custom_species
name = "Sapients - Other"
desc = "Remote frontiers require people of all sorts of life...\
Sometimes species one would never see anywhere close to core worlds can be met here."
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/technology/resleeving
name = "Resleeving"
desc = ""
value = CATALOGUER_REWARD_TRIVIAL
/datum/category_item/catalogue/information/organization/khi
name = "Government - Kitsuhana Heavy Industries"
datum_to_copy = /datum/lore/organization/gov/kitsuhana

View File

@@ -0,0 +1,12 @@
#ifndef T_BOARD
#error T_BOARD macro is not defined but we need it!
#endif
/obj/item/weapon/circuitboard/exploration_equipment_vendor
name = T_BOARD("Exploration Equipment Vendor")
board_type = new /datum/frame/frame_types/machine
build_path = /obj/machinery/equipment_vendor/exploration
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/matter_bin = 3)

View File

@@ -0,0 +1,164 @@
/**********************Exploration Equipment Vendor**************************/
/obj/machinery/equipment_vendor/exploration
name = "exploration equipment vendor"
desc = "An equipment vendor for explorers, points collected with cataloguers can be spent here."
icon = 'icons/obj/machines/mining_machines_vr.dmi'
icon_state = "exploration"
density = TRUE
anchored = TRUE
circuit = /obj/item/weapon/circuitboard/exploration_equipment_vendor
var/icon_deny = "exploration-deny"
var/icon_vend = "exploration-vend"
var/obj/item/device/cataloguer/inserted_cataloguer
var/list/prize_list = list(
new /datum/data/exploration_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1),
new /datum/data/exploration_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10),
new /datum/data/exploration_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30),
new /datum/data/exploration_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10),
new /datum/data/exploration_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10),
new /datum/data/exploration_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15),
new /datum/data/exploration_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20),
new /datum/data/exploration_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90),
new /datum/data/exploration_equipment("Plush Toy", /obj/random/plushie, 30),
new /datum/data/exploration_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50),
new /datum/data/exploration_equipment("Point Transfer Card", /obj/item/weapon/card/exploration_point_card, 50),
new /datum/data/exploration_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 50),
new /datum/data/exploration_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120),
new /datum/data/exploration_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100),
new /datum/data/exploration_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250),
new /datum/data/exploration_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310)
)
/datum/data/exploration_equipment
var/equipment_name = "generic"
var/equipment_path = null
var/cost = 0
/datum/data/exploration_equipment/New(name, path, cost)
src.equipment_name = name
src.equipment_path = path
src.cost = cost
/obj/machinery/equipment_vendor/exploration/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()
if(inserted_cataloguer && !powered())
visible_message("<span class='notice'>The cataloguer slot indicator light flickers on \the [src] as it spits out the device before powering down.</span>")
inserted_cataloguer.forceMove(get_turf(src))
/obj/machinery/equipment_vendor/exploration/update_icon()
if(panel_open)
icon_state = "[initial(icon_state)]-open"
else if(powered())
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]-off"
/obj/machinery/equipment_vendor/exploration/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/equipment_vendor/exploration/attack_ghost(mob/user)
interact(user)
/obj/machinery/equipment_vendor/exploration/interact(mob/user)
user.set_machine(src)
var/dat
dat +="<div class='statusDisplay'>"
if(istype(inserted_cataloguer))
dat += "You have [inserted_cataloguer.points_stored] exploration points collected. <A href='?src=\ref[src];choice=eject'>Eject Cataloguer.</A><br>"
else
dat += "No Cataloguer inserted. <A href='?src=\ref[src];choice=insert'>Insert Cataloguer.</A><br>"
dat += "</div>"
dat += "<br><b>Equipment point cost list:</b><BR><table border='0' width='100%'>"
for(var/datum/data/exploration_equipment/prize in prize_list)
dat += "<tr><td>[prize.equipment_name]</td><td>[prize.cost]</td><td><A href='?src=\ref[src];purchase=\ref[prize]'>Purchase</A></td></tr>"
dat += "</table>"
var/datum/browser/popup = new(user, "miningvendor", "Exploration Equipment Vendor", 400, 600)
popup.set_content(dat)
popup.open()
/obj/machinery/equipment_vendor/exploration/Topic(href, href_list)
if(..())
return 1
if(href_list["choice"])
if(istype(inserted_cataloguer))
if(href_list["choice"] == "eject")
to_chat(usr, "<span class='notice'>You eject the ID from [src]'s card slot.</span>")
usr.put_in_hands(inserted_cataloguer)
inserted_cataloguer = null
else if(href_list["choice"] == "insert")
var/obj/item/device/cataloguer/C = usr.get_active_hand()
if(istype(C) && !inserted_cataloguer && usr.unEquip(C))
C.forceMove(src)
inserted_cataloguer = C
interact(usr)
to_chat(usr, "<span class='notice'>You insert the ID into [src]'s card slot.</span>")
else
to_chat(usr, "<span class='warning'>No valid ID.</span>")
flick(icon_deny, src)
if(href_list["purchase"])
if(istype(inserted_cataloguer))
var/datum/data/exploration_equipment/prize = locate(href_list["purchase"])
if (!prize || !(prize in prize_list))
to_chat(usr, "<span class='warning'>Error: Invalid choice!</span>")
flick(icon_deny, src)
return
if(prize.cost > inserted_cataloguer.points_stored)
to_chat(usr, "<span class='warning'>Error: Insufficent points for [prize.equipment_name]!</span>")
flick(icon_deny, src)
else
inserted_cataloguer.points_stored -= prize.cost
to_chat(usr, "<span class='notice'>[src] clanks to life briefly before vending [prize.equipment_name]!</span>")
flick(icon_vend, src)
new prize.equipment_path(drop_location())
else
to_chat(usr, "<span class='warning'>Error: Please insert a valid ID!</span>")
flick(icon_deny, src)
updateUsrDialog()
/obj/machinery/equipment_vendor/exploration/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, I))
updateUsrDialog()
return
if(default_part_replacement(user, I))
return
if(default_deconstruction_crowbar(user, I))
return
if(istype(I,/obj/item/device/cataloguer))
if(!powered())
return
else if(!inserted_cataloguer && user.unEquip(I))
I.forceMove(src)
inserted_cataloguer = I
interact(user)
return
..()
/obj/machinery/equipment_vendor/exploration/dismantle()
if(inserted_cataloguer)
inserted_cataloguer.forceMove(loc) //Prevents deconstructing the ORM from deleting whatever ID was inside it.
. = ..()
/obj/machinery/equipment_vendor/exploration/proc/new_prize(var/name, var/path, var/cost) // Generic proc for adding new entries. Good for abusing for FUN and PROFIT.
if(!cost)
cost = 100
if(!path)
path = /obj/item/stack/marker_beacon
if(!name)
name = "Generic Entry"
prize_list += new /datum/data/exploration_equipment(name, path, cost)
/obj/machinery/equipment_vendor/exploration/ex_act(severity, target)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if(prob(50 / severity) && severity < 3)
qdel(src)

View File

@@ -0,0 +1,23 @@
/obj/item/weapon/card/exploration_point_card
name = "exploration point card"
desc = "A small card preloaded with exploration points. Swipe your Cataloguer over it to transfer the points, then discard."
icon_state = "data"
var/points = 50
/obj/item/weapon/card/exploration_point_card/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/device/cataloguer))
if(points)
var/obj/item/device/cataloguer/C = I
C.points_stored += points
to_chat(user, "<span class='info'>You transfer [points] points to [C].</span>")
points = 0
else
to_chat(user, "<span class='info'>There's no points left on [src].</span>")
..()
/obj/item/weapon/card/exploration_point_card/examine(mob/user)
..(user)
to_chat(user, "There's [points] points on the card.")
/obj/item/weapon/card/exploration_point_card/can_catalogue(mob/user)
return FALSE

View File

@@ -59,7 +59,7 @@
switch(href_list["flavor_text"]) switch(href_list["flavor_text"])
if("open") if("open")
if("general") if("general")
var/msg = sanitize(input(usr,"Give a general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(pref.flavor_texts[href_list["flavor_text"]])) as message, extra = 0) var/msg = sanitize(input(usr,"Give a general description of your character. This will be shown regardless of clothings.","Flavor Text",html_decode(pref.flavor_texts[href_list["flavor_text"]])) as message, extra = 0) //VOREStation Edit: separating out OOC notes
if(CanUseTopic(user)) if(CanUseTopic(user))
pref.flavor_texts[href_list["flavor_text"]] = msg pref.flavor_texts[href_list["flavor_text"]] = msg
else else

View File

@@ -140,3 +140,300 @@
else else
. = valid_reagents[metadata] . = valid_reagents[metadata]
I.reagents.add_reagent(., I.reagents.get_free_space()) I.reagents.add_reagent(., I.reagents.get_free_space())
/datum/gear_tweak/tablet
var/list/ValidProcessors = list(/obj/item/weapon/computer_hardware/processor_unit/small)
var/list/ValidBatteries = list(/obj/item/weapon/computer_hardware/battery_module/nano, /obj/item/weapon/computer_hardware/battery_module/micro, /obj/item/weapon/computer_hardware/battery_module)
var/list/ValidHardDrives = list(/obj/item/weapon/computer_hardware/hard_drive/micro, /obj/item/weapon/computer_hardware/hard_drive/small, /obj/item/weapon/computer_hardware/hard_drive)
var/list/ValidNetworkCards = list(/obj/item/weapon/computer_hardware/network_card, /obj/item/weapon/computer_hardware/network_card/advanced)
var/list/ValidNanoPrinters = list(null, /obj/item/weapon/computer_hardware/nano_printer)
var/list/ValidCardSlots = list(null, /obj/item/weapon/computer_hardware/card_slot)
var/list/ValidTeslaLinks = list(null, /obj/item/weapon/computer_hardware/tesla_link)
/datum/gear_tweak/tablet/get_contents(var/list/metadata)
var/list/names = list()
var/obj/O = ValidProcessors[metadata[1]]
if(O)
names += initial(O.name)
O = ValidBatteries[metadata[2]]
if(O)
names += initial(O.name)
O = ValidHardDrives[metadata[3]]
if(O)
names += initial(O.name)
O = ValidNetworkCards[metadata[4]]
if(O)
names += initial(O.name)
O = ValidNanoPrinters[metadata[5]]
if(O)
names += initial(O.name)
O = ValidCardSlots[metadata[6]]
if(O)
names += initial(O.name)
O = ValidTeslaLinks[metadata[7]]
if(O)
names += initial(O.name)
return "[english_list(names, and_text = ", ")]"
/datum/gear_tweak/tablet/get_metadata(var/user, var/metadata)
. = list()
var/list/names = list()
var/counter = 1
for(var/i in ValidProcessors)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
var/entry = input(user, "Choose a processor.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidBatteries)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a battery.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidHardDrives)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a hard drive.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidNetworkCards)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a network card.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidNanoPrinters)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a nanoprinter.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidCardSlots)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a card slot.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidTeslaLinks)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a tesla link.", "Character Preference") in names
. += names[entry]
/datum/gear_tweak/tablet/get_default()
return list(1, 1, 1, 1, 1, 1, 1)
/datum/gear_tweak/tablet/tweak_item(var/obj/item/modular_computer/tablet/I, var/list/metadata)
if(ValidProcessors[metadata[1]])
var/t = ValidProcessors[metadata[1]]
I.processor_unit = new t(I)
if(ValidBatteries[metadata[2]])
var/t = ValidBatteries[metadata[2]]
I.battery_module = new t(I)
I.battery_module.charge_to_full()
if(ValidHardDrives[metadata[3]])
var/t = ValidHardDrives[metadata[3]]
I.hard_drive = new t(I)
if(ValidNetworkCards[metadata[4]])
var/t = ValidNetworkCards[metadata[4]]
I.network_card = new t(I)
if(ValidNanoPrinters[metadata[5]])
var/t = ValidNanoPrinters[metadata[5]]
I.nano_printer = new t(I)
if(ValidCardSlots[metadata[6]])
var/t = ValidCardSlots[metadata[6]]
I.card_slot = new t(I)
if(ValidTeslaLinks[metadata[7]])
var/t = ValidTeslaLinks[metadata[7]]
I.tesla_link = new t(I)
/datum/gear_tweak/laptop
var/list/ValidProcessors = list(/obj/item/weapon/computer_hardware/processor_unit/small, /obj/item/weapon/computer_hardware/processor_unit)
var/list/ValidBatteries = list(/obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/computer_hardware/battery_module/advanced, /obj/item/weapon/computer_hardware/battery_module/super)
var/list/ValidHardDrives = list(/obj/item/weapon/computer_hardware/hard_drive, /obj/item/weapon/computer_hardware/hard_drive/advanced, /obj/item/weapon/computer_hardware/hard_drive/super)
var/list/ValidNetworkCards = list(/obj/item/weapon/computer_hardware/network_card, /obj/item/weapon/computer_hardware/network_card/advanced)
var/list/ValidNanoPrinters = list(null, /obj/item/weapon/computer_hardware/nano_printer)
var/list/ValidCardSlots = list(null, /obj/item/weapon/computer_hardware/card_slot)
var/list/ValidTeslaLinks = list(null, /obj/item/weapon/computer_hardware/tesla_link)
/datum/gear_tweak/laptop/get_contents(var/list/metadata)
var/list/names = list()
var/obj/O = ValidProcessors[metadata[1]]
if(O)
names += initial(O.name)
O = ValidBatteries[metadata[2]]
if(O)
names += initial(O.name)
O = ValidHardDrives[metadata[3]]
if(O)
names += initial(O.name)
O = ValidNetworkCards[metadata[4]]
if(O)
names += initial(O.name)
O = ValidNanoPrinters[metadata[5]]
if(O)
names += initial(O.name)
O = ValidCardSlots[metadata[6]]
if(O)
names += initial(O.name)
O = ValidTeslaLinks[metadata[7]]
if(O)
names += initial(O.name)
return "[english_list(names, and_text = ", ")]"
/datum/gear_tweak/laptop/get_metadata(var/user, var/metadata)
. = list()
var/list/names = list()
var/counter = 1
for(var/i in ValidProcessors)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
var/entry = input(user, "Choose a processor.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidBatteries)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a battery.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidHardDrives)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a hard drive.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidNetworkCards)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a network card.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidNanoPrinters)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a nanoprinter.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidCardSlots)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a card slot.", "Character Preference") in names
. += names[entry]
names = list()
counter = 1
for(var/i in ValidTeslaLinks)
if(i)
var/obj/O = i
names[initial(O.name)] = counter++
else
names["None"] = counter++
entry = input(user, "Choose a tesla link.", "Character Preference") in names
. += names[entry]
/datum/gear_tweak/laptop/get_default()
return list(1, 1, 1, 1, 1, 1, 1)
/datum/gear_tweak/laptop/tweak_item(var/obj/item/modular_computer/laptop/preset/I, var/list/metadata)
if(ValidProcessors[metadata[1]])
var/t = ValidProcessors[metadata[1]]
I.processor_unit = new t(I)
if(ValidBatteries[metadata[2]])
var/t = ValidBatteries[metadata[2]]
I.battery_module = new t(I)
I.battery_module.charge_to_full()
if(ValidHardDrives[metadata[3]])
var/t = ValidHardDrives[metadata[3]]
I.hard_drive = new t(I)
if(ValidNetworkCards[metadata[4]])
var/t = ValidNetworkCards[metadata[4]]
I.network_card = new t(I)
if(ValidNanoPrinters[metadata[5]])
var/t = ValidNanoPrinters[metadata[5]]
I.nano_printer = new t(I)
if(ValidCardSlots[metadata[6]])
var/t = ValidCardSlots[metadata[6]]
I.card_slot = new t(I)
if(ValidTeslaLinks[metadata[7]])
var/t = ValidTeslaLinks[metadata[7]]
I.tesla_link = new t(I)

View File

@@ -36,11 +36,11 @@
/datum/gear/accessory/brown_vest /datum/gear/accessory/brown_vest
display_name = "webbing, brown" display_name = "webbing, brown"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder") allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner")
/datum/gear/accessory/black_vest /datum/gear/accessory/black_vest
display_name = "webbing, black" display_name = "webbing, black"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder") allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner")
/datum/gear/accessory/white_vest /datum/gear/accessory/white_vest
display_name = "webbing, white (Medical)" display_name = "webbing, white (Medical)"
@@ -48,16 +48,19 @@
/datum/gear/accessory/brown_drop_pouches /datum/gear/accessory/brown_drop_pouches
display_name = "drop pouches, brown" display_name = "drop pouches, brown"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder") allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner")
/datum/gear/accessory/black_drop_pouches /datum/gear/accessory/black_drop_pouches
display_name = "drop pouches, black" display_name = "drop pouches, black"
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder") allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic","Pathfinder","Shaft Miner")
/datum/gear/accessory/white_drop_pouches /datum/gear/accessory/white_drop_pouches
display_name = "drop pouches, white (Medical)" display_name = "drop pouches, white (Medical)"
allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic") allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor","Chemist","Field Medic")
/datum/gear/accessory/webbing
cost = 1
/datum/gear/accessory/stethoscope /datum/gear/accessory/stethoscope
allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Psychiatrist","Paramedic", "Field Medic") allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Psychiatrist","Paramedic", "Field Medic")
@@ -78,4 +81,4 @@
/datum/gear/accessory/flops/New() /datum/gear/accessory/flops/New()
..() ..()
gear_tweaks = list(gear_tweak_free_color_choice) gear_tweaks = list(gear_tweak_free_color_choice)

Some files were not shown because too many files have changed in this diff Show More