This commit is contained in:
LetterN
2021-10-28 17:34:52 +08:00
parent 49940c373e
commit f7b898a2a9
346 changed files with 13714 additions and 8493 deletions

View File

@@ -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)

View File

@@ -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,

View File

@@ -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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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."))

View File

@@ -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."))

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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."

View File

@@ -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

View File

@@ -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)