frontend
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
/datum/computer_file
|
||||
var/filename = "NewFile" // Placeholder. No spacebars
|
||||
var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
|
||||
var/size = 1 // File size in GQ. Integers only!
|
||||
var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file.
|
||||
var/unsendable = FALSE // Whether the file may be sent to someone via NTNet transfer or other means.
|
||||
var/undeletable = FALSE // Whether the file may be deleted. Setting to TRUE prevents deletion/renaming/etc.
|
||||
var/uid // UID of this file
|
||||
var/filename = "NewFile" // Placeholder. No spacebars
|
||||
var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
|
||||
var/size = 1 // File size in GQ. Integers only!
|
||||
var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file.
|
||||
var/unsendable = FALSE // Whether the file may be sent to someone via NTNet transfer or other means.
|
||||
var/undeletable = FALSE // Whether the file may be deleted. Setting to TRUE prevents deletion/renaming/etc.
|
||||
var/uid // UID of this file
|
||||
var/static/file_uid = 0
|
||||
|
||||
/datum/computer_file/New()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// /data/ files store data in string format.
|
||||
// They don't contain other logic for now.
|
||||
/datum/computer_file/data
|
||||
var/stored_data = "" // Stored data in string format.
|
||||
var/stored_data = "" // Stored data in string format.
|
||||
filetype = "DAT"
|
||||
var/block_size = 250
|
||||
var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited.
|
||||
var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited.
|
||||
|
||||
/datum/computer_file/data/clone()
|
||||
var/datum/computer_file/data/temp = ..()
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
var/filedesc = "Unknown Program"
|
||||
/// Short description of this program's function.
|
||||
var/extended_desc = "N/A"
|
||||
/// Category in the NTDownloader.
|
||||
var/category = PROGRAM_CATEGORY_MISC
|
||||
/// Program-specific screen icon state
|
||||
var/program_icon_state = null
|
||||
/// Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes.
|
||||
@@ -25,10 +27,10 @@
|
||||
var/ntnet_status = 1
|
||||
/// Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL
|
||||
var/usage_flags = PROGRAM_ALL
|
||||
/// Whether the program can be downloaded from NTNet. Set to 0 to disable.
|
||||
var/available_on_ntnet = 1
|
||||
/// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
|
||||
var/available_on_syndinet = 0
|
||||
/// Whether the program can be downloaded from NTNet. Set to FALSE to disable.
|
||||
var/available_on_ntnet = TRUE
|
||||
/// Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to TRUE to enable.
|
||||
var/available_on_syndinet = FALSE
|
||||
/// Name of the tgui interface
|
||||
var/tgui_id
|
||||
/// Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /icons/program_icons. Be careful not to use too large images!
|
||||
@@ -64,7 +66,7 @@
|
||||
// Relays icon update to the computer.
|
||||
/datum/computer_file/program/proc/update_computer_icon()
|
||||
if(computer)
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
|
||||
// Attempts to create a log in global ntnet datum. Returns 1 on success, 0 on fail.
|
||||
/datum/computer_file/program/proc/generate_network_log(text)
|
||||
@@ -72,10 +74,25 @@
|
||||
return computer.add_log(text)
|
||||
return 0
|
||||
|
||||
/**
|
||||
*Runs when the device is used to attack an atom in non-combat mode.
|
||||
*
|
||||
*Simulates using the device to read or scan something. Tap is called by the computer during pre_attack
|
||||
*and sends us all of the related info. If we return TRUE, the computer will stop the attack process
|
||||
*there. What we do with the info is up to us, but we should only return TRUE if we actually perform
|
||||
*an action of some sort.
|
||||
*Arguments:
|
||||
*A is the atom being tapped
|
||||
*user is the person making the attack action
|
||||
*params is anything the pre_attack() proc had in the same-named variable.
|
||||
*/
|
||||
/datum/computer_file/program/proc/tap(atom/A, mob/living/user, params)
|
||||
return FALSE
|
||||
|
||||
/datum/computer_file/program/proc/is_supported_by_hardware(hardware_flag = 0, loud = 0, mob/user = null)
|
||||
if(!(hardware_flag & usage_flags))
|
||||
if(loud && computer && user)
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes a \"Hardware Error - Incompatible software\" warning.</span>")
|
||||
to_chat(user, span_danger("\The [computer] flashes a \"Hardware Error - Incompatible software\" warning."))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -109,7 +126,7 @@
|
||||
if(!access_to_check) // No required_access, allow it.
|
||||
return TRUE
|
||||
|
||||
if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones.
|
||||
if(!transfer && computer && (computer.obj_flags & EMAGGED)) //emags can bypass the execution locks but not the download ones.
|
||||
return TRUE
|
||||
|
||||
if(IsAdminGhost(user))
|
||||
@@ -127,14 +144,14 @@
|
||||
|
||||
if(!D)
|
||||
if(loud)
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
|
||||
to_chat(user, span_danger("\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning."))
|
||||
return FALSE
|
||||
access = D.GetAccess()
|
||||
|
||||
if(access_to_check in access)
|
||||
return TRUE
|
||||
if(loud)
|
||||
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
|
||||
to_chat(user, span_danger("\The [computer] flashes an \"Access Denied\" warning."))
|
||||
return FALSE
|
||||
|
||||
// This attempts to retrieve header data for UIs. If implementing completely new device of different type than existing ones
|
||||
@@ -219,7 +236,7 @@
|
||||
program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs
|
||||
|
||||
computer.active_program = null
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
ui.close()
|
||||
|
||||
if(user && istype(user))
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
/datum/computer_file/program/proc/event_networkfailure(background)
|
||||
kill_program(forced = TRUE)
|
||||
if(background)
|
||||
computer.visible_message("<span class='danger'>\The [computer]'s screen displays a \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
|
||||
computer.visible_message(span_danger("\The [computer]'s screen displays a \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error"))
|
||||
else
|
||||
computer.visible_message("<span class='danger'>\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.</span>")
|
||||
computer.visible_message(span_danger("\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error."))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/aidiag
|
||||
filename = "aidiag"
|
||||
filedesc = "NT FRK"
|
||||
category = PROGRAM_CATEGORY_ROBO
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "Firmware Restoration Kit, capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot."
|
||||
size = 12
|
||||
@@ -55,7 +56,7 @@
|
||||
|
||||
/datum/computer_file/program/aidiag/process_tick()
|
||||
. = ..()
|
||||
if(!restoring) //Put the check here so we don't check for an ai all the time
|
||||
if(!restoring) //Put the check here so we don't check for an ai all the time
|
||||
return
|
||||
var/obj/item/aicard/cardhold = get_ai(2)
|
||||
|
||||
@@ -64,7 +65,7 @@
|
||||
|
||||
var/mob/living/silicon/ai/A = get_ai()
|
||||
if(!A || !cardhold)
|
||||
restoring = FALSE // If the AI was removed, stop the restoration sequence.
|
||||
restoring = FALSE // If the AI was removed, stop the restoration sequence.
|
||||
if(ai_slot)
|
||||
ai_slot.locked = FALSE
|
||||
return
|
||||
@@ -84,7 +85,7 @@
|
||||
|
||||
if(A.health >= 0 && A.stat == DEAD)
|
||||
A.revive(full_heal = FALSE, admin_revive = FALSE)
|
||||
cardhold.update_icon()
|
||||
cardhold.update_appearance()
|
||||
|
||||
// Finished restoring
|
||||
if(A.health >= 100)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/contract_uplink
|
||||
filename = "contractor uplink"
|
||||
filedesc = "Syndicate Contractor Uplink"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "assign"
|
||||
extended_desc = "A standard, Syndicate issued system for handling important contracts while on the field."
|
||||
size = 10
|
||||
@@ -91,9 +92,9 @@
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.put_in_hands(crystals))
|
||||
to_chat(H, "<span class='notice'>Your payment materializes into your hands!</span>")
|
||||
to_chat(H, span_notice("Your payment materializes into your hands!"))
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Your payment materializes onto the floor.</span>")
|
||||
to_chat(user, span_notice("Your payment materializes onto the floor."))
|
||||
|
||||
hard_drive.traitor_data.contractor_hub.contract_TC_payed_out += hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem
|
||||
hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem = 0
|
||||
@@ -164,6 +165,11 @@
|
||||
))
|
||||
|
||||
for (var/datum/syndicate_contract/contract in traitor_data.contractor_hub.assigned_contracts)
|
||||
if(!contract.contract)
|
||||
stack_trace("Syndiate contract with null contract objective found in [traitor_data.owner]'s contractor hub!")
|
||||
contract.status = CONTRACT_STATUS_ABORTED
|
||||
continue
|
||||
|
||||
data["contracts"] += list(list(
|
||||
"target" = contract.contract.target,
|
||||
"target_rank" = contract.target_rank,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/ntnet_dos
|
||||
filename = "ntn_dos"
|
||||
filedesc = "DoS Traffic Generator"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "hostile"
|
||||
extended_desc = "This advanced script can perform denial of service attacks against NTNet quantum relays. The system administrator will probably notice this. Multiple devices can run this program together against same relay for increased effect"
|
||||
size = 20
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/revelation
|
||||
filename = "revelation"
|
||||
filedesc = "Revelation"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "hostile"
|
||||
extended_desc = "This virus can destroy hard drive of system it is executed on. It may be obfuscated to look like another non-malicious program. Once armed, it will destroy the system upon next execution."
|
||||
size = 13
|
||||
@@ -20,13 +21,13 @@
|
||||
if(computer)
|
||||
if(istype(computer, /obj/item/modular_computer/tablet/integrated)) //If this is a borg's integrated tablet
|
||||
var/obj/item/modular_computer/tablet/integrated/modularInterface = computer
|
||||
to_chat(modularInterface.borgo,"<span class='userdanger'>SYSTEM PURGE DETECTED/</span>")
|
||||
to_chat(modularInterface.borgo,span_userdanger("SYSTEM PURGE DETECTED/"))
|
||||
addtimer(CALLBACK(modularInterface.borgo, /mob/living/silicon/robot/.proc/death), 2 SECONDS, TIMER_UNIQUE)
|
||||
return
|
||||
|
||||
computer.visible_message("<span class='notice'>\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.</span>")
|
||||
computer.visible_message(span_notice("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard."))
|
||||
computer.enabled = FALSE
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
|
||||
var/obj/item/computer_hardware/battery/battery_module = computer.all_components[MC_CELL]
|
||||
var/obj/item/computer_hardware/recharger/recharger = computer.all_components[MC_CHARGE]
|
||||
@@ -34,13 +35,13 @@
|
||||
computer.take_damage(25, BRUTE, 0, 0)
|
||||
if(battery_module && prob(25))
|
||||
qdel(battery_module)
|
||||
computer.visible_message("<span class='notice'>\The [computer]'s battery explodes in rain of sparks.</span>")
|
||||
computer.visible_message(span_notice("\The [computer]'s battery explodes in rain of sparks."))
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
|
||||
spark_system.start()
|
||||
|
||||
if(recharger && prob(50))
|
||||
qdel(recharger)
|
||||
computer.visible_message("<span class='notice'>\The [computer]'s recharger explodes in rain of sparks.</span>")
|
||||
computer.visible_message(span_notice("\The [computer]'s recharger explodes in rain of sparks."))
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
|
||||
spark_system.start()
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
game_active = FALSE
|
||||
program_icon_state = "arcade_off"
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
ticket_count += 1
|
||||
// user?.mind?.adjust_experience(/datum/skill/gaming, 50)
|
||||
sleep(10)
|
||||
@@ -42,7 +42,7 @@
|
||||
game_active = FALSE
|
||||
program_icon_state = "arcade_off"
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
// user?.mind?.adjust_experience(/datum/skill/gaming, 10)
|
||||
sleep(10)
|
||||
|
||||
@@ -150,20 +150,20 @@
|
||||
return TRUE
|
||||
if("Dispense_Tickets")
|
||||
if(!printer)
|
||||
to_chat(usr, "<span class='notice'>Hardware error: A printer is required to redeem tickets.</span>")
|
||||
to_chat(usr, span_notice("Hardware error: A printer is required to redeem tickets."))
|
||||
return
|
||||
if(printer.stored_paper <= 0)
|
||||
to_chat(usr, "<span class='notice'>Hardware error: Printer is out of paper.</span>")
|
||||
to_chat(usr, span_notice("Hardware error: Printer is out of paper."))
|
||||
return
|
||||
else
|
||||
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
|
||||
computer.visible_message(span_notice("\The [computer] prints out paper."))
|
||||
if(ticket_count >= 1)
|
||||
new /obj/item/stack/arcadeticket((get_turf(computer)), 1)
|
||||
to_chat(usr, "<span class='notice'>[src] dispenses a ticket!</span>")
|
||||
to_chat(usr, span_notice("[computer] dispenses a ticket!"))
|
||||
ticket_count -= 1
|
||||
printer.stored_paper -= 1
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You don't have any stored tickets!</span>")
|
||||
to_chat(usr, span_notice("You don't have any stored tickets!"))
|
||||
return TRUE
|
||||
if("Start_Game")
|
||||
game_active = TRUE
|
||||
@@ -175,4 +175,4 @@
|
||||
boss_id = rand(1,6)
|
||||
pause_state = FALSE
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/atmosscan
|
||||
filename = "atmosscan"
|
||||
filedesc = "AtmoZphere"
|
||||
category = PROGRAM_CATEGORY_ENGI
|
||||
program_icon_state = "air"
|
||||
extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device."
|
||||
size = 4
|
||||
@@ -12,7 +13,7 @@
|
||||
if (!.)
|
||||
return
|
||||
if(!computer?.get_modular_computer_part(MC_SENSORS)) //Giving a clue to users why the program is spitting out zeros.
|
||||
to_chat(user, "<span class='warning'>\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\".</span>")
|
||||
to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\sensorpackage\\startup.bin -- file not found\"."))
|
||||
|
||||
|
||||
/datum/computer_file/program/atmosscan/ui_data(mob/user)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/borg_monitor
|
||||
filename = "siliconnect"
|
||||
filedesc = "SiliConnect"
|
||||
category = PROGRAM_CATEGORY_ROBO
|
||||
ui_header = "borg_mon.gif"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program allows for remote monitoring of station cyborgs."
|
||||
@@ -9,6 +10,70 @@
|
||||
size = 5
|
||||
tgui_id = "NtosCyborgRemoteMonitor"
|
||||
program_icon = "project-diagram"
|
||||
var/emagged = FALSE ///Bool of if this app has already been emagged
|
||||
var/list/loglist = list() ///A list to copy a borg's IC log list into
|
||||
var/mob/living/silicon/robot/DL_source ///reference of a borg if we're downloading a log, or null if not.
|
||||
var/DL_progress = -1 ///Progress of current download, 0 to 100, -1 for no current download
|
||||
|
||||
/datum/computer_file/program/borg_monitor/Destroy()
|
||||
loglist = null
|
||||
DL_source = null
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/borg_monitor/kill_program(forced = FALSE)
|
||||
loglist = null //Not everything is saved if you close an app
|
||||
DL_source = null
|
||||
DL_progress = 0
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/borg_monitor/run_emag()
|
||||
if(emagged)
|
||||
return FALSE
|
||||
emagged = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/borg_monitor/tap(atom/A, mob/living/user, params)
|
||||
var/mob/living/silicon/robot/borgo = A
|
||||
if(!istype(borgo) || !borgo.modularInterface)
|
||||
return FALSE
|
||||
DL_source = borgo
|
||||
DL_progress = 0
|
||||
|
||||
var/username = "unknown user"
|
||||
var/obj/item/card/id/stored_card = computer.GetID()
|
||||
if(istype(stored_card) && stored_card.registered_name)
|
||||
username = "user [stored_card.registered_name]"
|
||||
to_chat(borgo, span_userdanger("Request received from [username] for the system log file. Upload in progress."))//Damning evidence may be contained, so warn the borg
|
||||
borgo.logevent("File request by [username]: /var/logs/syslog")
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/borg_monitor/process_tick()
|
||||
if(!DL_source)
|
||||
DL_progress = -1
|
||||
return
|
||||
|
||||
var/turf/here = get_turf(computer)
|
||||
var/turf/there = get_turf(DL_source)
|
||||
if(!here.Adjacent(there))//If someone walked away, cancel the download
|
||||
to_chat(DL_source, span_danger("Log upload failed: general connection error."))//Let the borg know the upload stopped
|
||||
DL_source = null
|
||||
DL_progress = -1
|
||||
return
|
||||
|
||||
if(DL_progress == 100)
|
||||
if(!DL_source || !DL_source.modularInterface) //sanity check, in case the borg or their modular tablet poofs somehow
|
||||
loglist = list("System log of unit [DL_source.name]")
|
||||
loglist += "Error -- Download corrupted."
|
||||
else
|
||||
loglist = DL_source.modularInterface.borglog.Copy()
|
||||
loglist.Insert(1,"System log of unit [DL_source.name]")
|
||||
DL_progress = -1
|
||||
DL_source = null
|
||||
for(var/datum/tgui/window in SStgui.open_uis_by_src[REF(src)])
|
||||
window.send_full_update()
|
||||
return
|
||||
|
||||
DL_progress += 25
|
||||
|
||||
/datum/computer_file/program/borg_monitor/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
@@ -32,15 +97,22 @@
|
||||
|
||||
var/list/cyborg_data = list(
|
||||
name = R.name,
|
||||
integ = round((R.health + 100) / 2), //mob heath is -100 to 100, we want to scale that to 0 - 100
|
||||
locked_down = R.locked_down,
|
||||
status = R.stat,
|
||||
shell_discon = shell,
|
||||
charge = R.cell ? round(R.cell.percent()) : null,
|
||||
module = R.module ? "[R.module.name] Module" : "No Module Detected",
|
||||
module = R.module ? "[R.module.name] Model" : "No Model Detected",
|
||||
upgrades = upgrade,
|
||||
ref = REF(R)
|
||||
)
|
||||
data["cyborgs"] += list(cyborg_data)
|
||||
data["DL_progress"] = DL_progress
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/borg_monitor/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["borglog"] = loglist
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/borg_monitor/ui_act(action, params)
|
||||
@@ -57,16 +129,16 @@
|
||||
if(!ID)
|
||||
return
|
||||
if(R.stat == DEAD) //Dead borgs will listen to you no longer
|
||||
to_chat(usr, "<span class='warn'>Error -- Could not open a connection to unit:[R]</span>")
|
||||
to_chat(usr, span_warning("Error -- Could not open a connection to unit:[R]"))
|
||||
var/message = stripped_input(usr, message = "Enter message to be sent to remote cyborg.", title = "Send Message")
|
||||
if(!message)
|
||||
return
|
||||
to_chat(R, "<br><br><span class='notice'>Message from [ID] -- \"[message]\"</span><br>")
|
||||
to_chat(R, "<br><br>[span_notice("Message from [ID] -- \"[message]\"")]<br>")
|
||||
to_chat(usr, "Message sent to [R]: [message]")
|
||||
R.logevent("Message from [ID] -- \"[message]\"")
|
||||
SEND_SOUND(R, 'sound/machines/twobeep_high.ogg')
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "<br><br><span class='notice'>Message from [ID] to [R] -- \"[message]\"</span><br>")
|
||||
to_chat(R.connected_ai, "<br><br>[span_notice("Message from [ID] to [R] -- \"[message]\"")]<br>")
|
||||
SEND_SOUND(R.connected_ai, 'sound/machines/twobeep_high.ogg')
|
||||
usr.log_talk(message, LOG_PDA, tag="Cyborg Monitor Program: ID name \"[ID]\" to [R]")
|
||||
|
||||
@@ -82,12 +154,15 @@
|
||||
/datum/computer_file/program/borg_monitor/proc/checkID()
|
||||
var/obj/item/card/id/ID = computer.GetID()
|
||||
if(!ID)
|
||||
if(emagged)
|
||||
return "STDERR:UNDF"
|
||||
return FALSE
|
||||
return ID.registered_name
|
||||
|
||||
/datum/computer_file/program/borg_monitor/syndicate
|
||||
filename = "roboverlord"
|
||||
filedesc = "Roboverlord"
|
||||
category = PROGRAM_CATEGORY_ROBO
|
||||
ui_header = "borg_mon.gif"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program allows for remote monitoring of mission-assigned cyborgs."
|
||||
@@ -97,6 +172,9 @@
|
||||
transfer_access = null
|
||||
tgui_id = "NtosCyborgRemoteMonitorSyndicate"
|
||||
|
||||
/datum/computer_file/program/borg_monitor/syndicate/run_emag()
|
||||
return FALSE
|
||||
|
||||
/datum/computer_file/program/borg_monitor/syndicate/evaluate_borg(mob/living/silicon/robot/R)
|
||||
if((get_turf(computer)).z != (get_turf(R)).z)
|
||||
return FALSE
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/bounty_board
|
||||
filename = "bountyboard"
|
||||
filedesc = "Bounty Board Request Network"
|
||||
category = PROGRAM_CATEGORY_SUPL
|
||||
program_icon_state = "bountyboard"
|
||||
extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.."
|
||||
requires_ntnet = TRUE
|
||||
|
||||
@@ -1,41 +1,50 @@
|
||||
/datum/computer_file/program/budgetorders
|
||||
filename = "orderapp"
|
||||
filedesc = "NT IRN"
|
||||
// category = PROGRAM_CATEGORY_SUPL
|
||||
category = PROGRAM_CATEGORY_SUPL
|
||||
program_icon_state = "request"
|
||||
extended_desc = "Nanotrasen Internal Requisition Network interface for supply purchasing using a department budget account."
|
||||
requires_ntnet = TRUE
|
||||
transfer_access = ACCESS_HEADS
|
||||
usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET
|
||||
size = 20
|
||||
tgui_id = "NtosCargo"
|
||||
///Are you actually placing orders with it?
|
||||
var/requestonly = TRUE
|
||||
///Can the tablet see or buy illegal stuff?
|
||||
var/contraband_view = FALSE
|
||||
var/contraband = FALSE
|
||||
///Is it being bought from a personal account, or is it being done via a budget/cargo?
|
||||
var/self_paid = FALSE
|
||||
///Can this console approve purchase requests?
|
||||
var/can_approve_requests = FALSE
|
||||
///What do we say when the shuttle moves with living beings on it.
|
||||
var/safety_warning = "For safety reasons, the automated supply shuttle \
|
||||
cannot transport live organisms, human remains, classified nuclear weaponry, \
|
||||
homing beacons or machinery housing any form of artificial intelligence."
|
||||
var/safety_warning = "For safety and ethical reasons, the automated supply shuttle \
|
||||
cannot transport live organisms, human remains, classified nuclear weaponry, mail, \
|
||||
homing beacons, unstable eigenstates or machinery housing any form of artificial intelligence."
|
||||
///If you're being raided by pirates, what do you tell the crew?
|
||||
var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible."
|
||||
///The name of the shuttle template being used as the cargo shuttle. 'supply' is default and contains critical code. Don't change this unless you know what you're doing.
|
||||
var/cargo_shuttle = "supply"
|
||||
///The docking port called when returning to the station.
|
||||
var/docking_home = "supply_home"
|
||||
///The docking port called when leaving the station.
|
||||
var/docking_away = "supply_away"
|
||||
///If this console can loan the cargo shuttle. Set to false to disable.
|
||||
var/stationcargo = TRUE
|
||||
///The account this console processes and displays. Independent from the account the shuttle processes.
|
||||
var/cargo_account = ACCOUNT_CAR
|
||||
|
||||
/datum/computer_file/program/budgetorders/proc/get_export_categories()
|
||||
. = EXPORT_CARGO
|
||||
|
||||
/datum/computer_file/program/budgetorders/run_emag()
|
||||
if(!contraband_view)
|
||||
contraband_view = TRUE
|
||||
if(!contraband)
|
||||
contraband = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/budgetorders/proc/is_visible_pack(mob/user, paccess_to_check, list/access, contraband)
|
||||
if(issilicon(user)) //Borgs can't buy things.
|
||||
return FALSE
|
||||
if((computer.obj_flags & EMAGGED) || contraband_view)
|
||||
if(computer.obj_flags & EMAGGED)
|
||||
return TRUE
|
||||
else if(contraband) //Hide contrband when non-emagged.
|
||||
return FALSE
|
||||
@@ -64,11 +73,11 @@
|
||||
. = ..()
|
||||
var/list/data = get_header_data()
|
||||
data["location"] = SSshuttle.supply.getStatusText()
|
||||
var/datum/bank_account/buyer = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
var/datum/bank_account/buyer = SSeconomy.get_dep_account(cargo_account)
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
|
||||
var/obj/item/card/id/id_card = card_slot?.GetID()
|
||||
if(id_card?.registered_account)
|
||||
if(ACCESS_HEADS in id_card.access)
|
||||
if((ACCESS_HEADS in id_card.access) || (ACCESS_QM in id_card.access))
|
||||
requestonly = FALSE
|
||||
buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
|
||||
can_approve_requests = TRUE
|
||||
@@ -85,14 +94,14 @@
|
||||
data["supplies"] = list()
|
||||
for(var/pack in SSshuttle.supply_packs)
|
||||
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
|
||||
if(!is_visible_pack(usr, P.access , null, P.contraband))
|
||||
if(!is_visible_pack(usr, P.access , null, P.contraband) || P.hidden)
|
||||
continue
|
||||
if(!data["supplies"][P.group])
|
||||
data["supplies"][P.group] = list(
|
||||
"name" = P.group,
|
||||
"packs" = list()
|
||||
)
|
||||
if(((P.hidden || P.contraband) && !contraband_view) || (P.special && !P.special_enabled) || P.DropPodOnly)
|
||||
if((P.hidden && (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly))
|
||||
continue
|
||||
data["supplies"][P.group]["packs"] += list(list(
|
||||
"name" = P.name,
|
||||
@@ -105,7 +114,7 @@
|
||||
|
||||
//Data regarding the User's capability to buy things.
|
||||
data["has_id"] = id_card
|
||||
data["away"] = SSshuttle.supply.getDockedId() == "supply_away"
|
||||
data["away"] = SSshuttle.supply.getDockedId() == docking_away
|
||||
data["self_paid"] = self_paid
|
||||
data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
|
||||
data["loan"] = !!SSshuttle.shuttle_loan
|
||||
@@ -153,15 +162,15 @@
|
||||
if(SSshuttle.supplyBlocked)
|
||||
computer.say(blockade_warning)
|
||||
return
|
||||
if(SSshuttle.supply.getDockedId() == "supply_home")
|
||||
if(SSshuttle.supply.getDockedId() == docking_home)
|
||||
SSshuttle.supply.export_categories = get_export_categories()
|
||||
SSshuttle.moveShuttle("supply", "supply_away", TRUE)
|
||||
SSshuttle.moveShuttle(cargo_shuttle, docking_away, TRUE)
|
||||
computer.say("The supply shuttle is departing.")
|
||||
computer.investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO)
|
||||
else
|
||||
computer.investigate_log("[key_name(usr)] called the supply shuttle.", INVESTIGATE_CARGO)
|
||||
computer.say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.")
|
||||
SSshuttle.moveShuttle("supply", "supply_home", TRUE)
|
||||
SSshuttle.moveShuttle(cargo_shuttle, docking_home, TRUE)
|
||||
. = TRUE
|
||||
if("loan")
|
||||
if(!SSshuttle.shuttle_loan)
|
||||
@@ -171,7 +180,9 @@
|
||||
return
|
||||
else if(SSshuttle.supply.mode != SHUTTLE_IDLE)
|
||||
return
|
||||
else if(SSshuttle.supply.getDockedId() != "supply_away")
|
||||
else if(SSshuttle.supply.getDockedId() != docking_away)
|
||||
return
|
||||
else if(stationcargo != TRUE)
|
||||
return
|
||||
else
|
||||
SSshuttle.shuttle_loan.loan_shuttle()
|
||||
@@ -184,7 +195,7 @@
|
||||
var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
|
||||
if(!istype(pack))
|
||||
return
|
||||
if(((pack.hidden || pack.contraband) && !contraband_view) || pack.DropPodOnly)
|
||||
if((pack.hidden && (pack.contraband && !contraband) || pack.DropPodOnly))
|
||||
return
|
||||
|
||||
var/name = "*None Provided*"
|
||||
@@ -273,7 +284,7 @@
|
||||
self_paid = !self_paid
|
||||
. = TRUE
|
||||
if(.)
|
||||
post_signal("supply")
|
||||
post_signal(cargo_shuttle)
|
||||
|
||||
/datum/computer_file/program/budgetorders/proc/post_signal(command)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
/datum/computer_file/program/card_mod
|
||||
filename = "plexagonidwriter"
|
||||
filedesc = "Plexagon Access Management"
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
program_icon_state = "id"
|
||||
extended_desc = "Program for programming employee ID cards to access parts of the station."
|
||||
transfer_access = ACCESS_HEADS
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/shipping
|
||||
filename = "shipping"
|
||||
filedesc = "GrandArk Exporter"
|
||||
category = PROGRAM_CATEGORY_SUPL
|
||||
program_icon_state = "shipping"
|
||||
extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping."
|
||||
size = 6
|
||||
@@ -8,8 +9,12 @@
|
||||
program_icon = "tags"
|
||||
///Account used for creating barcodes.
|
||||
var/datum/bank_account/payments_acc
|
||||
///The amount which the tagger will receive for the sale.
|
||||
var/percent_cut = 20
|
||||
///The person who tagged this will receive the sale value multiplied by this number.
|
||||
var/cut_multiplier = 0.5
|
||||
///Maximum value for cut_multiplier.
|
||||
var/cut_max = 0.5
|
||||
///Minimum value for cut_multiplier.
|
||||
var/cut_min = 0.01
|
||||
|
||||
/datum/computer_file/program/shipping/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
@@ -22,7 +27,7 @@
|
||||
data["paperamt"] = printer ? "[printer.stored_paper] / [printer.max_paper]" : null
|
||||
data["card_owner"] = card_slot?.stored_card ? id_card.registered_name : "No Card Inserted."
|
||||
data["current_user"] = payments_acc ? payments_acc.account_holder : null
|
||||
data["barcode_split"] = percent_cut
|
||||
data["barcode_split"] = cut_multiplier * 100
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/shipping/ui_act(action, list/params)
|
||||
@@ -54,20 +59,20 @@
|
||||
if("resetid")
|
||||
payments_acc = null
|
||||
if("setsplit")
|
||||
var/potential_cut = tgui_input_num(usr, "How much would you like to payout to the registered card?","Percentage Profit")
|
||||
percent_cut = potential_cut ? clamp(round(potential_cut, 1), 1, 50) : 20
|
||||
var/potential_cut = input("How much would you like to pay out to the registered card?","Percentage Profit ([round(cut_min*100)]% - [round(cut_max*100)]%)") as num|null
|
||||
cut_multiplier = potential_cut ? clamp(round(potential_cut/100, cut_min), cut_min, cut_max) : initial(cut_multiplier)
|
||||
if("print")
|
||||
if(!printer)
|
||||
to_chat(usr, "<span class='notice'>Hardware error: A printer is required to print barcodes.</span>")
|
||||
to_chat(usr, span_notice("Hardware error: A printer is required to print barcodes."))
|
||||
return
|
||||
if(printer.stored_paper <= 0)
|
||||
to_chat(usr, "<span class='notice'>Hardware error: Printer is out of paper.</span>")
|
||||
to_chat(usr, span_notice("Hardware error: Printer is out of paper."))
|
||||
return
|
||||
if(!payments_acc)
|
||||
to_chat(usr, "<span class='notice'>Software error: Please set a current user first.</span>")
|
||||
to_chat(usr, span_notice("Software error: Please set a current user first."))
|
||||
return
|
||||
var/obj/item/barcode/barcode = new /obj/item/barcode(get_turf(ui_host()))
|
||||
barcode.payments_acc = payments_acc
|
||||
barcode.percent_cut = percent_cut
|
||||
barcode.cut_multiplier = cut_multiplier
|
||||
printer.stored_paper--
|
||||
to_chat(usr, "<span class='notice'>The computer prints out a barcode.</span>")
|
||||
to_chat(usr, span_notice("The computer prints out a barcode."))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/crew_manifest
|
||||
filename = "plexagoncrew"
|
||||
filedesc = "Plexagon Crew List"
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
program_icon_state = "id"
|
||||
extended_desc = "Program for viewing and printing the current crew manifest"
|
||||
transfer_access = ACCESS_HEADS
|
||||
@@ -11,7 +12,7 @@
|
||||
|
||||
/datum/computer_file/program/crew_manifest/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["manifest"] = GLOB.data_core.get_manifest_tg()
|
||||
data["manifest"] = GLOB.data_core.get_manifest()
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/crew_manifest/ui_data(mob/user)
|
||||
@@ -44,7 +45,7 @@
|
||||
[GLOB.data_core ? GLOB.data_core.get_manifest() : ""]
|
||||
"}
|
||||
if(!printer.print_text(contents,text("crew manifest ([])", STATION_TIME_TIMESTAMP("hh:mm:ss", world.time))))
|
||||
to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
|
||||
to_chat(usr, span_notice("Hardware error: Printer was unable to print the file. It may be out of paper."))
|
||||
return
|
||||
else
|
||||
computer.visible_message("<span class='notice'>\The [computer] prints out a paper.</span>")
|
||||
computer.visible_message(span_notice("\The [computer] prints out a paper."))
|
||||
|
||||
@@ -38,14 +38,27 @@
|
||||
return
|
||||
RHDD.remove_file(file)
|
||||
return TRUE
|
||||
if("PRG_rename")
|
||||
if("PRG_renamefile")
|
||||
if(!HDD)
|
||||
return
|
||||
var/datum/computer_file/file = HDD.find_file_by_name(params["name"])
|
||||
if(!file)
|
||||
return
|
||||
var/newname = params["new_name"]
|
||||
if(!newname)
|
||||
var/newname = reject_bad_name(params["new_name"])
|
||||
if(!newname || newname != params["new_name"])
|
||||
playsound(computer, 'sound/machines/terminal_error.ogg', 25, FALSE)
|
||||
return
|
||||
file.filename = newname
|
||||
return TRUE
|
||||
if("PRG_usbrenamefile")
|
||||
if(!RHDD)
|
||||
return
|
||||
var/datum/computer_file/file = RHDD.find_file_by_name(params["name"])
|
||||
if(!file)
|
||||
return
|
||||
var/newname = reject_bad_name(params["new_name"])
|
||||
if(!newname || newname != params["new_name"])
|
||||
playsound(computer, 'sound/machines/terminal_error.ogg', 25, FALSE)
|
||||
return
|
||||
file.filename = newname
|
||||
return TRUE
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/// The time since the last job opening was created
|
||||
// GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
|
||||
/datum/computer_file/program/job_management
|
||||
filename = "plexagoncore"
|
||||
filedesc = "Plexagon HR Core"
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
program_icon_state = "id"
|
||||
extended_desc = "Program for viewing and changing job slot avalibility."
|
||||
transfer_access = ACCESS_HEADS
|
||||
@@ -35,21 +39,25 @@
|
||||
change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay)
|
||||
|
||||
/datum/computer_file/program/job_management/proc/can_open_job(datum/job/job)
|
||||
if(!(job?.title in blacklisted))
|
||||
if((job.total_positions <= length(GLOB.player_list) * (max_relative_positions / 100)))
|
||||
var/delta = (world.time / 10) - GLOB.time_last_changed_position
|
||||
if((change_position_cooldown < delta) || (opened_positions[job.title] < 0))
|
||||
return TRUE
|
||||
if(job?.title in blacklisted)
|
||||
return FALSE
|
||||
if((job.total_positions <= length(GLOB.player_list) * (max_relative_positions / 100)))
|
||||
var/delta = (world.time / 10) - GLOB.time_last_changed_position
|
||||
if((change_position_cooldown < delta) || (opened_positions[job.title] < 0))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/computer_file/program/job_management/proc/can_close_job(datum/job/job)
|
||||
if(!(job?.title in blacklisted))
|
||||
if(job.total_positions > job.current_positions)
|
||||
var/delta = (world.time / 10) - GLOB.time_last_changed_position
|
||||
if((change_position_cooldown < delta) || (opened_positions[job.title] > 0))
|
||||
return TRUE
|
||||
if(job?.title in blacklisted)
|
||||
return FALSE
|
||||
if(job.total_positions > job.current_positions)
|
||||
var/delta = (world.time / 10) - GLOB.time_last_changed_position
|
||||
if((change_position_cooldown < delta) || (opened_positions[job.title] > 0))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/computer_file/program/job_management/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -68,9 +76,10 @@
|
||||
if(!j || !can_open_job(j))
|
||||
return
|
||||
if(opened_positions[edit_job_target] >= 0)
|
||||
GLOB.time_last_changed_position = world.time / 10 // global cd
|
||||
GLOB.time_last_changed_position = world.time / 10
|
||||
j.total_positions++
|
||||
opened_positions[edit_job_target]++
|
||||
log_game("[key_name(usr)] opened a [j.title] job position, for a total of [j.total_positions] open job slots.")
|
||||
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
|
||||
return TRUE
|
||||
if("PRG_close_job")
|
||||
@@ -83,21 +92,23 @@
|
||||
GLOB.time_last_changed_position = world.time / 10
|
||||
j.total_positions--
|
||||
opened_positions[edit_job_target]--
|
||||
log_game("[key_name(usr)] closed a [j.title] job position, leaving [j.total_positions] open job slots.")
|
||||
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
|
||||
return TRUE
|
||||
if("PRG_priority")
|
||||
if(length(SSjob.prioritized_jobs) >= 5)
|
||||
return
|
||||
var/priority_target = params["target"]
|
||||
var/datum/job/j = SSjob.GetJob(priority_target)
|
||||
if(!j)
|
||||
if(!j || (job?.title in blacklisted))
|
||||
return
|
||||
if(j.total_positions <= j.current_positions)
|
||||
return
|
||||
if(j in SSjob.prioritized_jobs)
|
||||
SSjob.prioritized_jobs -= j
|
||||
else
|
||||
SSjob.prioritized_jobs += j
|
||||
if(length(SSjob.prioritized_jobs) < 5)
|
||||
SSjob.prioritized_jobs += j
|
||||
else
|
||||
computer.say("Error: CentCom employment protocols restrict prioritising more than 5 jobs.")
|
||||
playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
var/emagged = FALSE
|
||||
var/list/main_repo
|
||||
var/list/antag_repo
|
||||
var/list/show_categories = list(
|
||||
PROGRAM_CATEGORY_CREW,
|
||||
PROGRAM_CATEGORY_ENGI,
|
||||
PROGRAM_CATEGORY_ROBO,
|
||||
PROGRAM_CATEGORY_SUPL,
|
||||
PROGRAM_CATEGORY_MISC,
|
||||
)
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/run_program()
|
||||
. = ..()
|
||||
@@ -146,39 +153,29 @@
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = my_computer.all_components[MC_HDD]
|
||||
data["disk_size"] = hard_drive.max_capacity
|
||||
data["disk_used"] = hard_drive.used_capacity
|
||||
var/list/all_entries[0]
|
||||
for(var/A in main_repo)
|
||||
var/datum/computer_file/program/P = A
|
||||
// Only those programs our user can run will show in the list
|
||||
if(hard_drive.find_file_by_name(P.filename))
|
||||
continue
|
||||
all_entries.Add(list(list(
|
||||
data["emagged"] = emagged
|
||||
|
||||
var/list/repo = antag_repo | main_repo
|
||||
var/list/program_categories = list()
|
||||
|
||||
for(var/I in repo)
|
||||
var/datum/computer_file/program/P = I
|
||||
if(!(P.category in program_categories))
|
||||
program_categories.Add(P.category)
|
||||
data["programs"] += list(list(
|
||||
"icon" = P.program_icon,
|
||||
"filename" = P.filename,
|
||||
"filedesc" = P.filedesc,
|
||||
"fileinfo" = P.extended_desc,
|
||||
"compatibility" = check_compatibility(P),
|
||||
"category" = P.category,
|
||||
"installed" = !!hard_drive.find_file_by_name(P.filename),
|
||||
"compatible" = check_compatibility(P),
|
||||
"size" = P.size,
|
||||
"access" = P.can_run(user,transfer = 1, access = access)
|
||||
)))
|
||||
data["hackedavailable"] = FALSE
|
||||
if(emagged) // If we are running on emagged computer we have access to some "bonus" software
|
||||
var/list/hacked_programs[0]
|
||||
for(var/S in antag_repo)
|
||||
var/datum/computer_file/program/P = S
|
||||
if(hard_drive.find_file_by_name(P.filename))
|
||||
continue
|
||||
data["hackedavailable"] = TRUE
|
||||
hacked_programs.Add(list(list(
|
||||
"filename" = P.filename,
|
||||
"filedesc" = P.filedesc,
|
||||
"fileinfo" = P.extended_desc,
|
||||
"compatibility" = check_compatibility(P),
|
||||
"size" = P.size,
|
||||
"access" = TRUE,
|
||||
)))
|
||||
data["hacked_programs"] = hacked_programs
|
||||
"access" = emagged && P.available_on_syndinet ? TRUE : P.can_run(user,transfer = 1, access = access),
|
||||
"verifiedsource" = P.available_on_ntnet,
|
||||
))
|
||||
|
||||
data["downloadable_programs"] = all_entries
|
||||
data["categories"] = show_categories & program_categories
|
||||
|
||||
return data
|
||||
|
||||
@@ -186,8 +183,8 @@
|
||||
var/hardflag = computer.hardware_flag
|
||||
|
||||
if(P?.is_supported_by_hardware(hardflag,0))
|
||||
return "Compatible"
|
||||
return "Incompatible!"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/kill_program(forced)
|
||||
abort_file_download()
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/datum/computer_file/program/ntnetmonitor
|
||||
filename = "wirecarp"
|
||||
filedesc = "WireCarp"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "comm_monitor"
|
||||
extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes"
|
||||
size = 12
|
||||
requires_ntnet = TRUE
|
||||
required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM.
|
||||
required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM.
|
||||
available_on_ntnet = TRUE
|
||||
tgui_id = "NtosNetMonitor"
|
||||
program_icon = "network-wired"
|
||||
|
||||
@@ -1,25 +1,36 @@
|
||||
|
||||
/datum/computer_file/program/chatclient
|
||||
filename = "ntnrc_client"
|
||||
filedesc = "Chat Client"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "command"
|
||||
extended_desc = "This program allows communication over NTNRC network"
|
||||
size = 8
|
||||
requires_ntnet = 1
|
||||
requires_ntnet = TRUE
|
||||
requires_ntnet_feature = NTNET_COMMUNICATION
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
available_on_ntnet = 1
|
||||
available_on_ntnet = TRUE
|
||||
tgui_id = "NtosNetChat"
|
||||
program_icon = "comment-alt"
|
||||
var/last_message // Used to generate the toolbar icon
|
||||
alert_able = TRUE
|
||||
var/last_message // Used to generate the toolbar icon
|
||||
var/username
|
||||
var/active_channel
|
||||
var/list/channel_history = list()
|
||||
var/operator_mode = FALSE // Channel operator mode
|
||||
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
|
||||
var/operator_mode = FALSE // Channel operator mode
|
||||
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
|
||||
//A list of all the converstations we're a part of
|
||||
var/list/datum/ntnet_conversation/conversations = list()
|
||||
|
||||
/datum/computer_file/program/chatclient/New()
|
||||
username = "DefaultUser[rand(100, 999)]"
|
||||
|
||||
/datum/computer_file/program/chatclient/Destroy()
|
||||
for(var/datum/ntnet_conversation/discussion as anything in conversations)
|
||||
discussion.purge_client(src)
|
||||
conversations.Cut()
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/chatclient/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -36,7 +47,7 @@
|
||||
var/message = reject_bad_text(params["message"])
|
||||
if(!message)
|
||||
return
|
||||
if(channel.password && !(src in channel.clients))
|
||||
if(channel.password && (!(src in channel.active_clients) && !(src in channel.offline_clients)))
|
||||
if(channel.password == message)
|
||||
channel.add_client(src)
|
||||
return TRUE
|
||||
@@ -56,7 +67,7 @@
|
||||
|
||||
active_channel = new_target
|
||||
channel = SSnetworks.station_network.get_chat_channel_by_id(new_target)
|
||||
if(!(src in channel.clients) && !channel.password)
|
||||
if((!(src in channel.active_clients) && !(src in channel.offline_clients)) && !channel.password)
|
||||
channel.add_client(src)
|
||||
return TRUE
|
||||
if("PRG_leavechannel")
|
||||
@@ -89,12 +100,12 @@
|
||||
return TRUE
|
||||
if("PRG_changename")
|
||||
var/newname = sanitize(params["new_name"])
|
||||
if(!newname)
|
||||
newname = replacetext(newname, " ", "_")
|
||||
if(!newname || newname == username)
|
||||
return
|
||||
for(var/C in SSnetworks.station_network.chat_channels)
|
||||
var/datum/ntnet_conversation/chan = C
|
||||
if(src in chan.clients)
|
||||
chan.add_status_message("[username] is now known as [newname].")
|
||||
for(var/datum/ntnet_conversation/anychannel as anything in SSnetworks.station_network.chat_channels)
|
||||
if(src in anychannel.active_clients)
|
||||
anychannel.add_status_message("[username] is now known as [newname].")
|
||||
username = newname
|
||||
return TRUE
|
||||
if("PRG_savelog")
|
||||
@@ -117,9 +128,9 @@
|
||||
// This program shouldn't even be runnable without computer.
|
||||
CRASH("Var computer is null!")
|
||||
if(!hard_drive)
|
||||
computer.visible_message("<span class='warning'>\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.</span>")
|
||||
else // In 99.9% cases this will mean our HDD is full
|
||||
computer.visible_message("<span class='warning'>\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.</span>")
|
||||
computer.visible_message(span_warning("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning."))
|
||||
else // In 99.9% cases this will mean our HDD is full
|
||||
computer.visible_message(span_warning("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning."))
|
||||
return TRUE
|
||||
if("PRG_renamechannel")
|
||||
if(!authed)
|
||||
@@ -145,6 +156,18 @@
|
||||
|
||||
channel.password = new_password
|
||||
return TRUE
|
||||
if("PRG_mute_user")
|
||||
if(!authed)
|
||||
return
|
||||
var/datum/computer_file/program/chatclient/muted = locate(params["ref"]) in channel.active_clients + channel.offline_clients
|
||||
channel.mute_user(src, muted)
|
||||
return TRUE
|
||||
if("PRG_ping_user")
|
||||
if(!authed)
|
||||
return
|
||||
var/datum/computer_file/program/chatclient/pinged = locate(params["ref"]) in channel.active_clients + channel.offline_clients
|
||||
channel.ping_user(src, pinged)
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/chatclient/process_tick()
|
||||
. = ..()
|
||||
@@ -162,10 +185,19 @@
|
||||
else
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
|
||||
/datum/computer_file/program/chatclient/run_program(mob/living/user)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
for(var/datum/ntnet_conversation/channel as anything in SSnetworks.station_network.chat_channels)
|
||||
if(src in channel.offline_clients)
|
||||
channel.offline_clients.Remove(src)
|
||||
channel.active_clients.Add(src)
|
||||
|
||||
/datum/computer_file/program/chatclient/kill_program(forced = FALSE)
|
||||
for(var/C in SSnetworks.station_network.chat_channels)
|
||||
var/datum/ntnet_conversation/channel = C
|
||||
channel.remove_client(src)
|
||||
for(var/datum/ntnet_conversation/channel as anything in SSnetworks.station_network.chat_channels)
|
||||
channel.go_offline(src)
|
||||
active_channel = null
|
||||
..()
|
||||
|
||||
/datum/computer_file/program/chatclient/ui_static_data(mob/user)
|
||||
@@ -192,6 +224,7 @@
|
||||
data["all_channels"] = all_channels
|
||||
|
||||
data["active_channel"] = active_channel
|
||||
data["selfref"] = REF(src) //used to verify who is you, as usernames can be copied.
|
||||
data["username"] = username
|
||||
data["adminmode"] = netadmin_mode
|
||||
var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel)
|
||||
@@ -203,21 +236,25 @@
|
||||
if(netadmin_mode)
|
||||
authed = TRUE
|
||||
var/list/clients = list()
|
||||
for(var/C in channel.clients)
|
||||
if(C == src)
|
||||
for(var/datum/computer_file/program/chatclient/channel_client as anything in channel.active_clients + channel.offline_clients)
|
||||
if(channel_client == src)
|
||||
authed = TRUE
|
||||
var/datum/computer_file/program/chatclient/cl = C
|
||||
clients.Add(list(list(
|
||||
"name" = cl.username
|
||||
"name" = channel_client.username,
|
||||
"status" = channel_client.program_state,
|
||||
"muted" = (channel_client in channel.muted_clients),
|
||||
"operator" = channel.operator == channel_client,
|
||||
"ref" = REF(channel_client)
|
||||
)))
|
||||
data["authed"] = authed
|
||||
//no fishing for ui data allowed
|
||||
if(authed)
|
||||
data["strong"] = channel.strong
|
||||
data["clients"] = clients
|
||||
var/list/messages = list()
|
||||
for(var/M in channel.messages)
|
||||
for(var/message in channel.messages)
|
||||
messages.Add(list(list(
|
||||
"msg" = M
|
||||
"msg" = message
|
||||
)))
|
||||
data["messages"] = messages
|
||||
data["is_operator"] = (channel.operator == src) || netadmin_mode
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
///how much paper it takes from the printer to create a canvas.
|
||||
#define CANVAS_PAPER_COST 10
|
||||
|
||||
/**
|
||||
* ## portrait printer!
|
||||
*
|
||||
* Program that lets the curator browse all of the portraits in the database
|
||||
* They are free to print them out as they please.
|
||||
*/
|
||||
/datum/computer_file/program/portrait_printer
|
||||
filename = "PortraitPrinter"
|
||||
filedesc = "Marlowe Treeby's Art Galaxy"
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
program_icon_state = "dummy"
|
||||
extended_desc = "This program connects to a Spinward Sector community art site for viewing and printing art."
|
||||
transfer_access = ACCESS_LIBRARY
|
||||
usage_flags = PROGRAM_CONSOLE
|
||||
requires_ntnet = TRUE
|
||||
size = 9
|
||||
tgui_id = "NtosPortraitPrinter"
|
||||
program_icon = "paint-brush"
|
||||
|
||||
/datum/computer_file/program/portrait_printer/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["library"] = SSpersistence.paintings["library"] ? SSpersistence.paintings["library"] : 0
|
||||
data["library_secure"] = SSpersistence.paintings["library_secure"] ? SSpersistence.paintings["library_secure"] : 0
|
||||
data["library_private"] = SSpersistence.paintings["library_private"] ? SSpersistence.paintings["library_private"] : 0 //i'm gonna regret this, won't i?
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/portrait_printer/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/portraits/library),
|
||||
get_asset_datum(/datum/asset/simple/portraits/library_secure),
|
||||
get_asset_datum(/datum/asset/simple/portraits/library_private)
|
||||
)
|
||||
|
||||
/datum/computer_file/program/portrait_printer/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
//printer check!
|
||||
var/obj/item/computer_hardware/printer/printer
|
||||
if(computer)
|
||||
printer = computer.all_components[MC_PRINT]
|
||||
if(!printer)
|
||||
to_chat(usr, span_notice("Hardware error: A printer is required to print a canvas."))
|
||||
return
|
||||
if(printer.stored_paper < CANVAS_PAPER_COST)
|
||||
to_chat(usr, span_notice("Printing error: Your printer needs at least [CANVAS_PAPER_COST] paper to print a canvas."))
|
||||
return
|
||||
printer.stored_paper -= CANVAS_PAPER_COST
|
||||
|
||||
//canvas printing!
|
||||
var/list/tab2key = list(TAB_LIBRARY = "library", TAB_SECURE = "library_secure", TAB_PRIVATE = "library_private")
|
||||
var/folder = tab2key[params["tab"]]
|
||||
var/list/current_list = SSpersistence.paintings[folder]
|
||||
var/list/chosen_portrait = current_list[params["selected"]]
|
||||
var/author = chosen_portrait["author"]
|
||||
var/title = chosen_portrait["title"]
|
||||
var/png = "data/paintings/[folder]/[chosen_portrait["md5"]].png"
|
||||
var/icon/art_icon = new(png)
|
||||
var/obj/item/canvas/printed_canvas
|
||||
var/art_width = art_icon.Width()
|
||||
var/art_height = art_icon.Height()
|
||||
for(var/canvas_type in typesof(/obj/item/canvas))
|
||||
printed_canvas = canvas_type
|
||||
if(initial(printed_canvas.width) == art_width && initial(printed_canvas.height) == art_height)
|
||||
printed_canvas = new canvas_type(get_turf(computer.physical))
|
||||
break
|
||||
printed_canvas.fill_grid_from_icon(art_icon)
|
||||
printed_canvas.generated_icon = art_icon
|
||||
printed_canvas.icon_generated = TRUE
|
||||
printed_canvas.finalized = TRUE
|
||||
printed_canvas.painting_name = title
|
||||
printed_canvas.author_ckey = author
|
||||
printed_canvas.name = "painting - [title]"
|
||||
///this is a copy of something that is already in the database- it should not be able to be saved.
|
||||
printed_canvas.no_save = TRUE
|
||||
printed_canvas.update_icon()
|
||||
to_chat(usr, span_notice("You have printed [title] onto a new canvas."))
|
||||
playsound(computer.physical, 'sound/items/poster_being_created.ogg', 100, TRUE)
|
||||
@@ -3,6 +3,7 @@
|
||||
/datum/computer_file/program/power_monitor
|
||||
filename = "ampcheck"
|
||||
filedesc = "AmpCheck"
|
||||
category = PROGRAM_CATEGORY_ENGI
|
||||
program_icon_state = "power_monitor"
|
||||
extended_desc = "This program connects to sensors around the station to provide information about electrical systems"
|
||||
ui_header = "power_norm.gif"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/radar //generic parent that handles most of the process
|
||||
filename = "genericfinder"
|
||||
filedesc = "debug_finder"
|
||||
category = PROGRAM_CATEGORY_CREW
|
||||
ui_header = "borg_mon.gif" //DEBUG -- new icon before PR
|
||||
program_icon_state = "radarntos"
|
||||
requires_ntnet = TRUE
|
||||
@@ -15,7 +16,7 @@
|
||||
var/atom/selected
|
||||
///Used to store when the next scan is available. Updated by the scan() proc.
|
||||
var/next_scan = 0
|
||||
///Used to keep track of the last value program_icon_state was set to, to prevent constant unnecessary update_icon() calls
|
||||
///Used to keep track of the last value program_icon_state was set to, to prevent constant unnecessary update_appearance() calls
|
||||
var/last_icon_state = ""
|
||||
///Used by the tgui interface, themed NT or Syndicate.
|
||||
var/arrowstyle = "ntosradarpointer.png"
|
||||
@@ -174,7 +175,7 @@
|
||||
if(!trackable(signal))
|
||||
program_icon_state = "[initial(program_icon_state)]lost"
|
||||
if(last_icon_state != program_icon_state)
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
last_icon_state = program_icon_state
|
||||
return
|
||||
|
||||
@@ -192,7 +193,7 @@
|
||||
program_icon_state = "[initial(program_icon_state)]far"
|
||||
|
||||
if(last_icon_state != program_icon_state)
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
last_icon_state = program_icon_state
|
||||
computer.setDir(get_dir(here_turf, target_turf))
|
||||
|
||||
@@ -241,13 +242,12 @@
|
||||
/datum/computer_file/program/radar/lifeline/trackable(mob/living/carbon/human/humanoid)
|
||||
if(!humanoid || !istype(humanoid))
|
||||
return FALSE
|
||||
if(..() && istype(humanoid.w_uniform, /obj/item/clothing/under))
|
||||
|
||||
var/obj/item/clothing/under/uniform = humanoid.w_uniform
|
||||
if(!uniform.has_sensor || (uniform.sensor_mode < SENSOR_COORDS)) // Suit sensors must be on maximum.
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
if(..())
|
||||
if (istype(humanoid.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/uniform = humanoid.w_uniform
|
||||
if(uniform.has_sensor && uniform.sensor_mode >= SENSOR_COORDS) // Suit sensors must be on maximum
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
////////////////////////
|
||||
//Nuke Disk Finder App//
|
||||
@@ -257,6 +257,7 @@
|
||||
/datum/computer_file/program/radar/fission360
|
||||
filename = "fission360"
|
||||
filedesc = "Fission360"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "radarsyndicate"
|
||||
extended_desc = "This program allows for tracking of nuclear authorization disks and warheads."
|
||||
requires_ntnet = FALSE
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/datum/computer_file/program/robocontrol
|
||||
filename = "botkeeper"
|
||||
filedesc = "BotKeeper"
|
||||
category = PROGRAM_CATEGORY_ROBO
|
||||
program_icon_state = "robot"
|
||||
extended_desc = "A remote controller used for giving basic commands to non-sentient robots."
|
||||
transfer_access = null
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/robotact
|
||||
filename = "robotact"
|
||||
filedesc = "RoboTact"
|
||||
category = PROGRAM_CATEGORY_ROBO
|
||||
extended_desc = "A built-in app for cyborg self-management and diagnostics."
|
||||
ui_header = "robotact.gif" //DEBUG -- new icon before PR
|
||||
program_icon_state = "command"
|
||||
@@ -22,7 +23,7 @@
|
||||
|
||||
/datum/computer_file/program/robotact/run_program(mob/living/user)
|
||||
if(!istype(computer, /obj/item/modular_computer/tablet/integrated))
|
||||
to_chat(user, "<span class='warning'>A warning flashes across \the [computer]: Device Incompatible.</span>")
|
||||
to_chat(user, span_warning("A warning flashes across \the [computer]: Device Incompatible."))
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -39,7 +40,7 @@
|
||||
var/mob/living/silicon/robot/borgo = tablet.borgo
|
||||
|
||||
data["name"] = borgo.name
|
||||
data["designation"] = borgo.designation //Borgo module type
|
||||
data["designation"] = borgo.designation //Borgo model type
|
||||
data["masterAI"] = borgo.connected_ai //Master AI
|
||||
|
||||
var/charge = 0
|
||||
@@ -62,7 +63,7 @@
|
||||
data["cover"] = "[borgo.locked? "LOCKED":"UNLOCKED"]"
|
||||
//Ability to move. FAULT if lockdown wire is cut, DISABLED if borg locked, ENABLED otherwise
|
||||
data["locomotion"] = "[borgo.wires.is_cut(WIRE_LOCKDOWN)?"FAULT":"[borgo.locked_down?"DISABLED":"ENABLED"]"]"
|
||||
//Module wire. FAULT if cut, NOMINAL otherwise
|
||||
//Model wire. FAULT if cut, NOMINAL otherwise
|
||||
data["wireModule"] = "[borgo.wires.is_cut(WIRE_RESET_MODULE)?"FAULT":"NOMINAL"]"
|
||||
//DEBUG -- Camera(net) wire. FAULT if cut (or no cameranet camera), DISABLED if pulse-disabled, NOMINAL otherwise
|
||||
data["wireCamera"] = "[!borgo.builtInCamera || borgo.wires.is_cut(WIRE_CAMERA)?"FAULT":"[borgo.builtInCamera.can_use()?"NOMINAL":"DISABLED"]"]"
|
||||
@@ -110,7 +111,7 @@
|
||||
if("alertPower")
|
||||
if(borgo.stat == CONSCIOUS)
|
||||
if(!borgo.cell || !borgo.cell.charge)
|
||||
borgo.visible_message("<span class='notice'>The power warning light on <span class='name'>[borgo]</span> flashes urgently.</span>", \
|
||||
borgo.visible_message(span_notice("The power warning light on [span_name("[borgo]")] flashes urgently."), \
|
||||
"You announce you are operating in low power mode.")
|
||||
playsound(borgo, 'sound/machines/buzz-two.ogg', 50, FALSE)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/datum/computer_file/program/secureye
|
||||
filename = "secureye"
|
||||
filedesc = "SecurEye"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
ui_header = "borg_mon.gif"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program allows access to standard security camera networks."
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/datum/computer_file/program/signaler
|
||||
filename = "signaler"
|
||||
filedesc = "SignalCommander"
|
||||
category = PROGRAM_CATEGORY_MISC
|
||||
program_icon_state = "signal"
|
||||
extended_desc = "A small built-in frequency app that sends out signaller signals with the appropriate hardware."
|
||||
size = 2
|
||||
tgui_id = "NtosSignaler"
|
||||
program_icon = "satellite-dish"
|
||||
usage_flags = PROGRAM_TABLET | PROGRAM_LAPTOP
|
||||
///What is the saved signal frequency?
|
||||
var/signal_frequency = FREQ_SIGNALER
|
||||
/// What is the saved signal code?
|
||||
var/signal_code = DEFAULT_SIGNALER_CODE
|
||||
/// Radio connection datum used by signalers.
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/datum/computer_file/program/signaler/run_program(mob/living/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
if(!computer?.get_modular_computer_part(MC_SIGNALER)) //Giving a clue to users why the program is spitting out zeros.
|
||||
to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\signal_hardware\\startup.bin -- file not found\"."))
|
||||
|
||||
|
||||
/datum/computer_file/program/signaler/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(sensor?.check_functionality())
|
||||
data["frequency"] = signal_frequency
|
||||
data["code"] = signal_code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
data["maxFrequency"] = MAX_FREE_FREQ
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/signaler/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(!(sensor?.check_functionality()))
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE)
|
||||
return
|
||||
switch(action)
|
||||
if("signal")
|
||||
INVOKE_ASYNC(src, .proc/signal)
|
||||
. = TRUE
|
||||
if("freq")
|
||||
signal_frequency = unformat_frequency(params["freq"])
|
||||
signal_frequency = sanitize_frequency(signal_frequency, TRUE)
|
||||
set_frequency(signal_frequency)
|
||||
. = TRUE
|
||||
if("code")
|
||||
signal_code = text2num(params["code"])
|
||||
signal_code = round(signal_code)
|
||||
. = TRUE
|
||||
if("reset")
|
||||
if(params["reset"] == "freq")
|
||||
signal_frequency = initial(signal_frequency)
|
||||
else
|
||||
signal_code = initial(signal_code)
|
||||
. = TRUE
|
||||
|
||||
/datum/computer_file/program/signaler/proc/signal()
|
||||
if(!radio_connection)
|
||||
return
|
||||
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
var/logging_data
|
||||
if(usr)
|
||||
logging_data = "[time] <B>:</B> [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) <B>:</B> [format_frequency(signal_frequency)]/[signal_code]"
|
||||
GLOB.lastsignalers.Add(logging_data)
|
||||
|
||||
var/datum/signal/signal = new(list("code" = signal_code), logging_data = logging_data)
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
/datum/computer_file/program/signaler/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, signal_frequency)
|
||||
signal_frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, signal_frequency, RADIO_SIGNALER)
|
||||
return
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/computer_file/program/supermatter_monitor
|
||||
filename = "ntcims"
|
||||
filedesc = "NT CIMS"
|
||||
category = PROGRAM_CATEGORY_ENGI
|
||||
ui_header = "smmon_0.gif"
|
||||
program_icon_state = "smmon_0"
|
||||
extended_desc = "Crystal Integrity Monitoring System, connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines."
|
||||
@@ -12,7 +13,7 @@
|
||||
alert_able = TRUE
|
||||
var/last_status = SUPERMATTER_INACTIVE
|
||||
var/list/supermatters
|
||||
var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal.
|
||||
var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal.
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/Destroy()
|
||||
clear_signals()
|
||||
@@ -27,7 +28,7 @@
|
||||
ui_header = "smmon_[last_status].gif"
|
||||
program_icon_state = "smmon_[last_status]"
|
||||
if(istype(computer))
|
||||
computer.update_icon()
|
||||
computer.update_appearance()
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user)
|
||||
. = ..(user)
|
||||
@@ -36,11 +37,15 @@
|
||||
refresh()
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE)
|
||||
for(var/supermatter in supermatters)
|
||||
clear_supermatter(supermatter)
|
||||
supermatters = null
|
||||
..()
|
||||
|
||||
// Refreshes list of active supermatter crystals
|
||||
/datum/computer_file/program/supermatter_monitor/proc/refresh()
|
||||
for(var/supermatter in supermatters)
|
||||
clear_supermatter(supermatter)
|
||||
supermatters = list()
|
||||
var/turf/T = get_turf(ui_host())
|
||||
if(!T)
|
||||
@@ -50,9 +55,7 @@
|
||||
if (!isturf(S.loc) || !(is_station_level(S.z) || is_mining_level(S.z) || S.z == T.z))
|
||||
continue
|
||||
supermatters.Add(S)
|
||||
|
||||
if(!(active in supermatters))
|
||||
active = null
|
||||
RegisterSignal(S, COMSIG_PARENT_QDELETING, .proc/react_to_del)
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/proc/get_status()
|
||||
. = SUPERMATTER_INACTIVE
|
||||
@@ -67,9 +70,9 @@
|
||||
* the signal and exit.
|
||||
*/
|
||||
/datum/computer_file/program/supermatter_monitor/proc/set_signals()
|
||||
// if(active)
|
||||
// RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM, .proc/send_alert, override = TRUE)
|
||||
// RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM, .proc/send_start_alert, override = TRUE)
|
||||
if(active)
|
||||
RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM, .proc/send_alert, override = TRUE)
|
||||
RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM, .proc/send_start_alert, override = TRUE)
|
||||
|
||||
/**
|
||||
* Removes the signal listener for Supermatter delaminations from the selected supermatter.
|
||||
@@ -77,9 +80,9 @@
|
||||
* Pretty much does what it says.
|
||||
*/
|
||||
/datum/computer_file/program/supermatter_monitor/proc/clear_signals()
|
||||
// if(active)
|
||||
// UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM)
|
||||
// UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM)
|
||||
if(active)
|
||||
UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM)
|
||||
UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM)
|
||||
|
||||
/**
|
||||
* Sends an SM delam alert to the computer.
|
||||
@@ -90,6 +93,7 @@
|
||||
* the supermatter probably don't need constant beeping to distract them.
|
||||
*/
|
||||
/datum/computer_file/program/supermatter_monitor/proc/send_alert()
|
||||
SIGNAL_HANDLER
|
||||
if(!computer.get_ntnet_status())
|
||||
return
|
||||
if(computer.active_program != src)
|
||||
@@ -106,12 +110,13 @@
|
||||
* minimized or closed to avoid double-notifications.
|
||||
*/
|
||||
/datum/computer_file/program/supermatter_monitor/proc/send_start_alert()
|
||||
SIGNAL_HANDLER
|
||||
if(!computer.get_ntnet_status())
|
||||
return
|
||||
if(computer.active_program == src)
|
||||
computer.alert_call(src, "Crystal delamination in progress!")
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/ui_data()
|
||||
/datum/computer_file/program/supermatter_monitor/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
if(istype(active))
|
||||
@@ -125,30 +130,9 @@
|
||||
active = null
|
||||
return
|
||||
|
||||
data["active"] = TRUE
|
||||
data["SM_integrity"] = active.get_integrity()
|
||||
data["SM_power"] = active.power
|
||||
data["SM_ambienttemp"] = air.return_temperature()
|
||||
data["SM_ambientpressure"] = air.return_pressure()
|
||||
//data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01)
|
||||
var/list/gasdata = list()
|
||||
data += active.ui_data()
|
||||
data["singlecrystal"] = FALSE
|
||||
|
||||
|
||||
if(air.total_moles())
|
||||
for(var/gasid in air.get_gases())
|
||||
var/amount = air.get_moles(gasid)
|
||||
if(amount)
|
||||
gasdata.Add(list(list(
|
||||
"name"= GLOB.gas_data.names[gasid],
|
||||
"amount" = round(100*amount/air.total_moles(),0.01))))
|
||||
|
||||
else
|
||||
for(var/gasid in air.get_gases())
|
||||
gasdata.Add(list(list(
|
||||
"name"= GLOB.gas_data.names[gasid],
|
||||
"amount" = 0)))
|
||||
|
||||
data["gases"] = gasdata
|
||||
else
|
||||
var/list/SMS = list()
|
||||
for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
|
||||
@@ -185,3 +169,13 @@
|
||||
active = S
|
||||
set_signals()
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/proc/react_to_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
clear_supermatter(source)
|
||||
|
||||
/datum/computer_file/program/supermatter_monitor/proc/clear_supermatter(matter)
|
||||
supermatters -= matter
|
||||
if(matter == active)
|
||||
active = null
|
||||
UnregisterSignal(matter, COMSIG_PARENT_QDELETING)
|
||||
|
||||
Reference in New Issue
Block a user