diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index ddcf80ae5d..1077dbf2b3 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -42,6 +42,7 @@ var/synchronizer_coeff = -1 //makes the mutation hurt the user less var/power_coeff = -1 //boosts mutation strength var/energy_coeff = -1 //lowers mutation cooldown + var/list/valid_chrom_list = list() //List of strings of valid chromosomes this mutation can accept. /datum/mutation/human/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut) . = ..() @@ -166,6 +167,7 @@ energy_coeff = HM.energy_coeff mutadone_proof = HM.mutadone_proof can_chromosome = HM.can_chromosome + valid_chrom_list = HM.valid_chrom_list /datum/mutation/human/proc/remove_chromosome() stabilizer_coeff = initial(stabilizer_coeff) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 0de9a25f12..69476b5950 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -825,6 +825,9 @@ /atom/proc/GenerateTag() return +/atom/proc/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE) + return + // Generic logging helper /atom/proc/log_message(message, message_type, color=null, log_globally=TRUE) if(!log_globally) diff --git a/code/game/objects/items/stacks/tickets.dm b/code/game/objects/items/stacks/tickets.dm new file mode 100644 index 0000000000..22cb895277 --- /dev/null +++ b/code/game/objects/items/stacks/tickets.dm @@ -0,0 +1,31 @@ +/obj/item/stack/arcadeticket + name = "arcade tickets" + desc = "Wow! With enough of these, you could buy a bike! ...Pssh, yeah right." + singular_name = "arcade ticket" + icon_state = "arcade-ticket" + item_state = "tickets" + w_class = WEIGHT_CLASS_TINY + max_amount = 30 + +/obj/item/stack/arcadeticket/Initialize(mapload, new_amount, merge = TRUE) + . = ..() + update_icon() + +/obj/item/stack/arcadeticket/update_icon() + var/amount = get_amount() + if((amount >= 12) && (amount > 0)) + icon_state = "arcade-ticket_4" + else if((amount >= 6) && (amount > 0)) + icon_state = "arcade-ticket_3" + else if((amount >= 2) && (amount > 0)) + icon_state = "arcade-ticket_2" + else + icon_state = "arcade-ticket" + +/obj/item/stack/arcadeticket/proc/pay_tickets() + amount -= 2 + if (amount == 0) + qdel(src) + +/obj/item/stack/arcadeticket/thirty + amount = 30 diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm index daa9127591..57a300be78 100644 --- a/code/modules/antagonists/traitor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/syndicate_contract.dm @@ -14,12 +14,14 @@ /datum/syndicate_contract/proc/generate(blacklist) contract.find_target(null, blacklist) - var/datum/data/record/record = find_record("name", contract.target.name, GLOB.data_core.general) + var/datum/data/record/record + if(contract.target) + record = find_record("name", contract.target.name, GLOB.data_core.general) if(record) target_rank = record.fields["rank"] else target_rank = "Unknown" - if (payout_type == CONTRACT_PAYOUT_LARGE) + if(payout_type == CONTRACT_PAYOUT_LARGE) contract.payout_bonus = rand(9,13) else if(payout_type == CONTRACT_PAYOUT_MEDIUM) contract.payout_bonus = rand(6,8) diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 181b2b31f3..9684a0d2d2 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -147,7 +147,8 @@ "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js', "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js', "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css', - "browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css', + "browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css', + "browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css' ) /datum/asset/simple/fontawesome @@ -200,35 +201,27 @@ "boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif', "boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif', "boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif', - ) - -/datum/asset/spritesheet/simple/achievements - name ="achievements" - assets = list( - "default" = 'icons/UI_Icons/Achievements/default.png', - "basemisc" = 'icons/UI_Icons/Achievements/basemisc.png', - "baseboss" = 'icons/UI_Icons/Achievements/baseboss.png', - "baseskill" = 'icons/UI_Icons/Achievements/baseskill.png', - "bbgum" = 'icons/UI_Icons/Achievements/Boss/bbgum.png', - "colossus" = 'icons/UI_Icons/Achievements/Boss/colossus.png', - "hierophant" = 'icons/UI_Icons/Achievements/Boss/hierophant.png', - "legion" = 'icons/UI_Icons/Achievements/Boss/legion.png', - "miner" = 'icons/UI_Icons/Achievements/Boss/miner.png', - "swarmer" = 'icons/UI_Icons/Achievements/Boss/swarmer.png', - "tendril" = 'icons/UI_Icons/Achievements/Boss/tendril.png', - "featofstrength" = 'icons/UI_Icons/Achievements/Misc/featofstrength.png', - "helbital" = 'icons/UI_Icons/Achievements/Misc/helbital.png', - "jackpot" = 'icons/UI_Icons/Achievements/Misc/jackpot.png', - "meteors" = 'icons/UI_Icons/Achievements/Misc/meteors.png', - "timewaste" = 'icons/UI_Icons/Achievements/Misc/timewaste.png', - "upgrade" = 'icons/UI_Icons/Achievements/Misc/upgrade.png', - "clownking" = 'icons/UI_Icons/Achievements/Misc/clownking.png', - "clownthanks" = 'icons/UI_Icons/Achievements/Misc/clownthanks.png', - "rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png', - "snail" = 'icons/UI_Icons/Achievements/Misc/snail.png', - "mining" = 'icons/UI_Icons/Achievements/Skills/mining.png', ) +/datum/asset/spritesheet/simple/minesweeper + name = "minesweeper" + assets = list( + "1" = 'icons/misc/minesweeper_tiles/one.png', + "2" = 'icons/misc/minesweeper_tiles/two.png', + "3" = 'icons/misc/minesweeper_tiles/three.png', + "4" = 'icons/misc/minesweeper_tiles/four.png', + "5" = 'icons/misc/minesweeper_tiles/five.png', + "6" = 'icons/misc/minesweeper_tiles/six.png', + "7" = 'icons/misc/minesweeper_tiles/seven.png', + "8" = 'icons/misc/minesweeper_tiles/eight.png', + "empty" = 'icons/misc/minesweeper_tiles/empty.png', + "flag" = 'icons/misc/minesweeper_tiles/flag.png', + "hidden" = 'icons/misc/minesweeper_tiles/hidden.png', + "mine" = 'icons/misc/minesweeper_tiles/mine.png', + "minehit" = 'icons/misc/minesweeper_tiles/minehit.png' + ) + + /datum/asset/spritesheet/simple/pills name ="pills" assets = list( diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index f83442b137..066f1fb98b 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -85,3 +85,4 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/chatclient()) hard_drive.store_file(new/datum/computer_file/program/nttransfer()) + hard_drive.store_file(new/datum/computer_file/program/arcade()) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index b54bc9f2be..f28b2e36a4 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -1,26 +1,43 @@ // /program/ files are executable programs that do things. /datum/computer_file/program filetype = "PRG" - filename = "UnknownProgram" // File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET! - var/required_access = null // List of required accesses to *run* the program. - var/transfer_access = null // List of required access to download or file host the program - var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running. - var/obj/item/modular_computer/computer // Device that runs this program. - var/filedesc = "Unknown Program" // User-friendly name of this program. - var/extended_desc = "N/A" // Short description of this program's function. - var/program_icon_state = null // Program-specific screen icon state - var/requires_ntnet = 0 // Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes. - var/requires_ntnet_feature = 0 // Optional, if above is set to 1 checks for specific function of NTNet (currently NTNET_SOFTWAREDOWNLOAD, NTNET_PEERTOPEER, NTNET_SYSTEMCONTROL and NTNET_COMMUNICATION) - var/ntnet_status = 1 // NTNet status, updated every tick by computer running this program. Don't use this for checks if NTNet works, computers do that. Use this for calculations, etc. - var/usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL - var/network_destination = null // Optional string that describes what NTNet server/system this program connects to. Used in default logging. - var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable. - var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable. - var/tgui_id // ID of TGUI interface - var/ui_style // ID of custom TGUI style (optional) - var/ui_x = 575 // Default size of TGUI window, in pixels + /// File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET! + filename = "UnknownProgram" + /// List of required accesses to *run* the program. + var/required_access = null + /// List of required access to download or file host the program + var/transfer_access = null + /// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running. + var/program_state = PROGRAM_STATE_KILLED + /// Device that runs this program. + var/obj/item/modular_computer/computer + /// User-friendly name of this program. + var/filedesc = "Unknown Program" + /// Short description of this program's function. + var/extended_desc = "N/A" + /// 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. + var/requires_ntnet = FALSE + /// Optional, if above is set to 1 checks for specific function of NTNet (currently NTNET_SOFTWAREDOWNLOAD, NTNET_PEERTOPEER, NTNET_SYSTEMCONTROL and NTNET_COMMUNICATION) + var/requires_ntnet_feature = 0 + /// NTNet status, updated every tick by computer running this program. Don't use this for checks if NTNet works, computers do that. Use this for calculations, etc. + var/ntnet_status = 1 + /// Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL + var/usage_flags = PROGRAM_ALL + /// Optional string that describes what NTNet server/system this program connects to. Used in default logging. + var/network_destination = null + /// 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 + /// ID of TGUI interface + var/tgui_id + /// Default size of TGUI window, in pixels + var/ui_x = 575 var/ui_y = 700 - var/ui_header = null // 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! + /// 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! + var/ui_header = null /datum/computer_file/program/New(obj/item/modular_computer/comp = null) ..() @@ -50,23 +67,23 @@ /datum/computer_file/program/proc/generate_network_log(text) if(computer) return computer.add_log(text) - return 0 + 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, "\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.") - return 0 - return 1 + return FALSE + return TRUE /datum/computer_file/program/proc/get_signal(specific_action = 0) if(computer) return computer.get_ntnet_status(specific_action) - return 0 + return FALSE // Called by Process() on device that runs us, once every tick. /datum/computer_file/program/proc/process_tick() - return 1 + return TRUE // Check if the user can run program. Only humans can operate computer. Automatically called in run_program() // User has to wear their ID for ID Scan to work. @@ -87,7 +104,7 @@ if(IsAdminGhost(user)) return TRUE - if(computer && computer.hasSiliconAccessInArea(user)) + if(issilicon(user)) return TRUE if(ishuman(user)) @@ -98,6 +115,7 @@ D = card_slot.GetID() var/mob/living/carbon/human/h = user var/obj/item/card/id/I = h.get_idcard(TRUE) + if(!I && !D) if(loud) to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") @@ -123,7 +141,7 @@ // This is performed on program startup. May be overridden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure. // When implementing new program based device, use this to run the program. /datum/computer_file/program/proc/run_program(mob/living/user) - if(can_run(user, 1)) + if(can_run(user, TRUE)) if(requires_ntnet && network_destination) generate_network_log("Connection opened to [network_destination].") program_state = PROGRAM_STATE_ACTIVE @@ -145,10 +163,6 @@ assets.send(user) ui = new(user, src, ui_key, tgui_id, filedesc, ui_x, ui_y, state = state) - - if(ui_style) - ui.set_style(ui_style) - ui.set_autoupdate(state = 1) ui.open() // CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC: @@ -156,7 +170,7 @@ // Calls beginning with "PRG_" are reserved for programs handling. // Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program) // ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE. -/datum/computer_file/program/ui_act(action,params,datum/tgui/ui) +/datum/computer_file/program/ui_act(action,list/params,datum/tgui/ui) if(..()) return TRUE if(computer) diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm index 8b9f98ca73..4e9cd85577 100644 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -4,14 +4,14 @@ program_icon_state = "generic" extended_desc = "This program is capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." size = 12 - requires_ntnet = 0 - usage_flags = PROGRAM_CONSOLE + requires_ntnet = FALSE + usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP transfer_access = ACCESS_HEADS available_on_ntnet = TRUE tgui_id = "NtosAiRestorer" ui_x = 370 ui_y = 400 - + /// Variable dictating if we are in the process of restoring the AI in the inserted intellicard var/restoring = FALSE /datum/computer_file/program/aidiag/proc/get_ai(cardcheck) @@ -30,11 +30,11 @@ if(ai_slot.stored_card.AI) return ai_slot.stored_card.AI - return null + return /datum/computer_file/program/aidiag/ui_act(action, params) if(..()) - return TRUE + return var/mob/living/silicon/ai/A = get_ai() if(!A) @@ -44,6 +44,7 @@ if("PRG_beginReconstruction") if(A && A.health < 100) restoring = TRUE + A.notify_ghost_cloning("Your core files are being restored!", source = computer) return TRUE if("PRG_eject") if(computer.all_components[MC_AI]) @@ -53,7 +54,7 @@ return TRUE /datum/computer_file/program/aidiag/process_tick() - ..() + . = ..() 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) @@ -73,13 +74,13 @@ restoring = FALSE return ai_slot.locked =TRUE - A.adjustOxyLoss(-1, 0) - A.adjustFireLoss(-1, 0) - A.adjustToxLoss(-1, 0) - A.adjustBruteLoss(-1, 0) + A.adjustOxyLoss(-5, 0) + A.adjustFireLoss(-5, 0) + A.adjustToxLoss(-5, 0) + A.adjustBruteLoss(-5, 0) A.updatehealth() if(A.health >= 0 && A.stat == DEAD) - A.revive() + A.revive(full_heal = FALSE, admin_revive = FALSE) // Finished restoring if(A.health >= 100) ai_slot.locked = FALSE @@ -90,14 +91,14 @@ /datum/computer_file/program/aidiag/ui_data(mob/user) var/list/data = get_header_data() - var/mob/living/silicon/ai/AI - // A shortcut for getting the AI stored inside the computer. The program already does necessary checks. - AI = get_ai() + var/mob/living/silicon/ai/AI = get_ai() var/obj/item/aicard/aicard = get_ai(2) + data["ejectable"] = TRUE + data["AI_present"] = FALSE + data["error"] = null if(!aicard) - data["nocard"] = TRUE data["error"] = "Please insert an intelliCard." else if(!AI) @@ -107,15 +108,15 @@ if(cardhold.flush) data["error"] = "Flush in progress" else + data["AI_present"] = TRUE data["name"] = AI.name data["restoring"] = restoring - data["laws"] = AI.laws.get_law_list(include_zeroth = 1) data["health"] = (AI.health + 100) / 2 data["isDead"] = AI.stat == DEAD - data["ai_laws"] = AI.laws.get_law_list(include_zeroth = 1) + data["laws"] = AI.laws.get_law_list(include_zeroth = 1) return data /datum/computer_file/program/aidiag/kill_program(forced) restoring = FALSE - return ..(forced) + return ..() diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index ebfd3c0ad8..34daeff6ca 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -72,15 +72,23 @@ /datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 + var/arealevelalarm = FALSE // set to TRUE for alarms that set/clear whole areas + if (class=="Fire") + arealevelalarm = TRUE for (var/I in L) if (I == A.name) - var/list/alarm = L[I] - var/list/srcs = alarm[3] - if (origin in srcs) - srcs -= origin - if (srcs.len == 0) + if (!arealevelalarm) // the traditional behaviour + var/list/alarm = L[I] + var/list/srcs = alarm[3] + if (origin in srcs) + srcs -= origin + if (srcs.len == 0) + cleared = 1 + L -= I + else + L -= I // wipe the instances entirely cleared = 1 - L -= I + update_alarm_display() return !cleared diff --git a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm index 326f885ee7..cf842f086f 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm @@ -12,15 +12,16 @@ ui_x = 500 ui_y = 600 var/error = "" - var/page = CONTRACT_UPLINK_PAGE_CONTRACTS + var/info_screen = TRUE var/assigned = FALSE + var/first_load = TRUE /datum/computer_file/program/contract_uplink/run_program(var/mob/living/user) . = ..(user) /datum/computer_file/program/contract_uplink/ui_act(action, params) if(..()) - return 1 + return TRUE var/mob/living/user = usr var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = computer.all_components[MC_HDD] switch(action) @@ -30,27 +31,32 @@ hard_drive.traitor_data.contractor_hub.assigned_contracts[contract_id].status = CONTRACT_STATUS_ACTIVE hard_drive.traitor_data.contractor_hub.current_contract = hard_drive.traitor_data.contractor_hub.assigned_contracts[contract_id] program_icon_state = "single_contract" - return 1 + return TRUE if("PRG_login") var/datum/antagonist/traitor/traitor_data = user.mind.has_antag_datum(/datum/antagonist/traitor) - if(traitor_data) // Bake their data right into the hard drive, or we don't allow non-antags gaining access to unused contract system. We also create their contracts at this point. - if(!traitor_data.contractor_hub) // Only play greet sound, and handle contractor hub when assigning for the first time. + + // Bake their data right into the hard drive, or we don't allow non-antags gaining access to an unused + // contract system. + // We also create their contracts at this point. + if(traitor_data) + // Only play greet sound, and handle contractor hub when assigning for the first time. + if(!traitor_data.contractor_hub) + user.playsound_local(user, 'sound/effects/contractstartup.ogg', 100, FALSE) traitor_data.contractor_hub = new traitor_data.contractor_hub.create_hub_items() - user.playsound_local(user, 'sound/effects/contractstartup.ogg', 100, 0) - // Stops any topic exploits such as logging in multiple times on a single system. + // Stops any topic exploits such as logging in multiple times on a single system. if(!assigned) traitor_data.contractor_hub.create_contracts(traitor_data.owner) hard_drive.traitor_data = traitor_data program_icon_state = "contracts" assigned = TRUE else - error = "Incorrect login details." - return 1 + error = "UNAUTHORIZED USER" + return TRUE if("PRG_call_extraction") if(hard_drive.traitor_data.contractor_hub.current_contract.status != CONTRACT_STATUS_EXTRACTING) if(hard_drive.traitor_data.contractor_hub.current_contract.handle_extraction(user)) - user.playsound_local(user, 'sound/effects/confirmdropoff.ogg', 100, 1) + user.playsound_local(user, 'sound/effects/confirmdropoff.ogg', 100, TRUE) hard_drive.traitor_data.contractor_hub.current_contract.status = CONTRACT_STATUS_EXTRACTING program_icon_state = "extracted" else @@ -58,17 +64,18 @@ error = "Either both you or your target aren't at the dropoff location, or the pod hasn't got a valid place to land. Clear space, or make sure you're both inside." else user.playsound_local(user, 'sound/machines/uplinkerror.ogg', 50) - error = "Already extracting... Place the target into the pod. If the pod was destroyed, you will need to cancel this contract." - return 1 + error = "Already extracting... Place the target into the pod. If the pod was destroyed, this contract is no longer possible." + return TRUE if("PRG_contract_abort") var/contract_id = hard_drive.traitor_data.contractor_hub.current_contract.id hard_drive.traitor_data.contractor_hub.current_contract = null hard_drive.traitor_data.contractor_hub.assigned_contracts[contract_id].status = CONTRACT_STATUS_ABORTED program_icon_state = "contracts" - return 1 + return TRUE if("PRG_redeem_TC") if(hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem) - var/obj/item/stack/telecrystal/crystals = new /obj/item/stack/telecrystal(get_turf(user), hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem) + var/obj/item/stack/telecrystal/crystals = new /obj/item/stack/telecrystal(get_turf(user), + hard_drive.traitor_data.contractor_hub.contract_TC_to_redeem) if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.put_in_hands(crystals)) @@ -77,22 +84,23 @@ to_chat(user, "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 - return 1 + return TRUE else user.playsound_local(user, 'sound/machines/uplinkerror.ogg', 50) - return 1 + return TRUE if("PRG_clear_error") error = "" - if("PRG_contractor_hub") - page = CONTRACT_UPLINK_PAGE_HUB - program_icon_state = "store" - if("PRG_hub_back") - page = CONTRACT_UPLINK_PAGE_CONTRACTS - program_icon_state = "contracts" + return TRUE + if("PRG_set_first_load_finished") + first_load = FALSE + return TRUE + if("PRG_toggle_info") + info_screen = !info_screen + return TRUE if("buy_hub") if(hard_drive.traitor_data.owner.current == user) var/item = params["item"] - for (var/datum/contractor_item/hub_item in hard_drive.traitor_data.contractor_hub.hub_items) + for(var/datum/contractor_item/hub_item in hard_drive.traitor_data.contractor_hub.hub_items) if (hub_item.name == item) hub_item.handle_purchase(hard_drive.traitor_data.contractor_hub, user) else @@ -103,21 +111,28 @@ var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = computer.all_components[MC_HDD] var/screen_to_be = null + data["first_load"] = first_load if(hard_drive && hard_drive.traitor_data != null) var/datum/antagonist/traitor/traitor_data = hard_drive.traitor_data - error = "" - data = get_header_data() + data += get_header_data() if(traitor_data.contractor_hub.current_contract) data["ongoing_contract"] = TRUE screen_to_be = "single_contract" if(traitor_data.contractor_hub.current_contract.status == CONTRACT_STATUS_EXTRACTING) data["extraction_enroute"] = TRUE screen_to_be = "extracted" + else + data["extraction_enroute"] = FALSE + else + data["ongoing_contract"] = FALSE + data["extraction_enroute"] = FALSE data["logged_in"] = TRUE data["station_name"] = GLOB.station_name data["redeemable_tc"] = traitor_data.contractor_hub.contract_TC_to_redeem + data["earned_tc"] = traitor_data.contractor_hub.contract_TC_payed_out + data["contracts_completed"] = traitor_data.contractor_hub.contracts_completed data["contract_rep"] = traitor_data.contractor_hub.contract_rep - data["page"] = page + data["info_screen"] = info_screen data["error"] = error for(var/datum/contractor_item/hub_item in traitor_data.contractor_hub.hub_items) data["contractor_hub_items"] += list(list( @@ -135,7 +150,8 @@ "payout_bonus" = contract.contract.payout_bonus, "dropoff" = contract.contract.dropoff, "id" = contract.id, - "status" = contract.status + "status" = contract.status, + "message" = contract.wanted_message )) var/direction @@ -154,14 +170,8 @@ else direction = "???" data["dropoff_direction"] = direction - if (page == CONTRACT_UPLINK_PAGE_HUB) - screen_to_be = "store" - if (!screen_to_be) - screen_to_be = "contracts" else data["logged_in"] = FALSE - if (!screen_to_be) - screen_to_be = "assign" program_icon_state = screen_to_be update_computer_icon() return data diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm index a2bc2df49b..9dedc3810f 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -36,61 +36,52 @@ if(target) target.dos_sources.Remove(src) target = null - executed = 0 + executed = FALSE ..() /datum/computer_file/program/ntnet_dos/ui_act(action, params) if(..()) - return 1 + return switch(action) if("PRG_target_relay") for(var/obj/machinery/ntnet_relay/R in SSnetworks.station_network.relays) if("[R.uid]" == params["targid"]) target = R - return 1 + break + return TRUE if("PRG_reset") if(target) target.dos_sources.Remove(src) target = null - executed = 0 + executed = FALSE error = "" - return 1 + return TRUE if("PRG_execute") if(target) - executed = 1 + executed = TRUE target.dos_sources.Add(src) if(SSnetworks.station_network.intrusion_detection_enabled) var/obj/item/computer_hardware/network_card/network_card = computer.all_components[MC_NET] SSnetworks.station_network.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [network_card.get_network_tag()]") - SSnetworks.station_network.intrusion_detection_alarm = 1 - return 1 + SSnetworks.station_network.intrusion_detection_alarm = TRUE + return TRUE /datum/computer_file/program/ntnet_dos/ui_data(mob/user) if(!SSnetworks.station_network) return - var/list/data = list() + var/list/data = get_header_data() - data = get_header_data() - - if(error) - data["error"] = error - else if(target && executed) - data["target"] = 1 + data["error"] = error + if(target && executed) + data["target"] = TRUE data["speed"] = dos_speed - // This is mostly visual, generate some strings of 1s and 0s - // Probability of 1 is equal of completion percentage of DoS attack on this relay. - // Combined with UI updates this adds quite nice effect to the UI - var/percentage = target.dos_overload * 100 / target.dos_capacity - data["dos_strings"] = list() - for(var/j, j<10, j++) - var/string = "" - for(var/i, i<20, i++) - string = "[string][prob(percentage)]" - data["dos_strings"] += list(list("nums" = string)) + data["overload"] = target.dos_overload + data["capacity"] = target.dos_capacity else + data["target"] = FALSE data["relays"] = list() for(var/obj/machinery/ntnet_relay/R in SSnetworks.station_network.relays) data["relays"] += list(list("id" = R.uid)) diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm index 5b8f6a0ae3..a312815008 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -21,7 +21,7 @@ /datum/computer_file/program/revelation/proc/activate() if(computer) computer.visible_message("\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.") - computer.enabled = 0 + computer.enabled = FALSE computer.update_icon() 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] @@ -43,18 +43,20 @@ /datum/computer_file/program/revelation/ui_act(action, params) if(..()) - return 1 + return switch(action) if("PRG_arm") armed = !armed + return TRUE if("PRG_activate") activate() + return TRUE if("PRG_obfuscate") - var/mob/living/user = usr - var/newname = sanitize(input(user, "Enter new program name: ")) + var/newname = params["new_name"] if(!newname) return filedesc = newname + return TRUE /datum/computer_file/program/revelation/clone() diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 6309a1a89f..eb7b60b070 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -1,3 +1,11 @@ +#define CARDCON_DEPARTMENT_SERVICE "Service" +#define CARDCON_DEPARTMENT_SECURITY "Security" +#define CARDCON_DEPARTMENT_MEDICAL "Medical" +#define CARDCON_DEPARTMENT_SUPPLY "Supply" +#define CARDCON_DEPARTMENT_SCIENCE "Science" +#define CARDCON_DEPARTMENT_ENGINEERING "Engineering" +#define CARDCON_DEPARTMENT_COMMAND "Command" + /datum/computer_file/program/card_mod filename = "cardmod" filedesc = "ID Card Modification" @@ -85,11 +93,11 @@ update_static_data(user) return TRUE - return formatted + return FALSE /datum/computer_file/program/card_mod/ui_act(action, params) if(..()) - return 1 + return TRUE var/obj/item/computer_hardware/card_slot/card_slot var/obj/item/computer_hardware/printer/printer @@ -99,192 +107,220 @@ if(!card_slot) return - var/obj/item/card/id/user_id_card = null var/mob/user = usr + var/obj/item/card/id/user_id_card = user.get_idcard(FALSE) var/obj/item/card/id/id_card = card_slot.stored_card - var/obj/item/card/id/auth_card = card_slot.stored_card2 - - if(auth_card) - user_id_card = auth_card - else - if(ishuman(user)) - var/mob/living/carbon/human/h = user - user_id_card = h.get_idcard(TRUE) switch(action) - if("PRG_switchm") - if(params["target"] == "mod") - mod_mode = 1 - else if (params["target"] == "manifest") - mod_mode = 0 - else if (params["target"] == "manage") - mod_mode = 2 - if("PRG_togglea") - if(show_assignments) - show_assignments = 0 - else - show_assignments = 1 + if("PRG_authenticate") + if(!computer || !user_id_card) + playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) + return + if(authenticate(user, user_id_card)) + playsound(computer, 'sound/machines/terminal_on.ogg', 50, FALSE) + return TRUE + if("PRG_logout") + authenticated = FALSE + playsound(computer, 'sound/machines/terminal_off.ogg', 50, FALSE) + return TRUE if("PRG_print") - if(computer && printer) //This option should never be called if there is no printer - if(mod_mode) - if(authorized()) - var/contents = {"

Access Report

- Prepared By: [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]
- For: [id_card.registered_name ? id_card.registered_name : "Unregistered"]
-
- Assignment: [id_card.assignment]
- Access:
- "} + if(!computer || !printer) + return + if(!authenticated) + return + var/contents = {"

Access Report

+ Prepared By: [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]
+ For: [id_card.registered_name ? id_card.registered_name : "Unregistered"]
+
+ Assignment: [id_card.assignment]
+ Access:
+ "} - var/known_access_rights = get_all_accesses() - for(var/A in id_card.access) - if(A in known_access_rights) - contents += " [get_access_desc(A)]" + var/known_access_rights = get_all_accesses() + for(var/A in id_card.access) + if(A in known_access_rights) + contents += " [get_access_desc(A)]" - if(!printer.print_text(contents,"access report")) - to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") - return - else - computer.visible_message("\The [computer] prints out paper.") - else - var/contents = {"

Crew Manifest

-
- [GLOB.data_core ? GLOB.data_core.get_manifest(0) : ""] - "} - if(!printer.print_text(contents,text("crew manifest ([])", STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)))) - to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") - return - else - computer.visible_message("\The [computer] prints out paper.") - if("PRG_eject") - if(computer && card_slot) - var/select = params["target"] - switch(select) - if("id") - if(id_card) - GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment) - card_slot.try_eject(1, user) - else - var/obj/item/I = usr.get_active_held_item() - if (istype(I, /obj/item/card/id)) - if(!usr.transferItemToLoc(I, computer)) - return - card_slot.stored_card = I - if("auth") - if(auth_card) - if(id_card) - GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment) - head_subordinates = null - region_access = null - authenticated = 0 - minor = 0 - card_slot.try_eject(2, user) - else - var/obj/item/I = usr.get_active_held_item() - if (istype(I, /obj/item/card/id)) - if(!usr.transferItemToLoc(I, computer)) - return - card_slot.stored_card2 = I - if("PRG_terminate") - if(computer && ((id_card.assignment in head_subordinates) || id_card.assignment == "Assistant")) - id_card.assignment = "Unassigned" - remove_nt_access(id_card) - - if("PRG_edit") - if(computer && authorized()) - if(params["name"]) - var/temp_name = reject_bad_name(input("Enter name.", "Name", id_card.registered_name)) - if(temp_name) - id_card.registered_name = temp_name - else - computer.visible_message("[computer] buzzes rudely.") - //else if(params["account"]) - // var/account_num = text2num(input("Enter account number.", "Account", id_card.associated_account_number)) - // id_card.associated_account_number = account_num - if("PRG_assign") - if(computer && authorized() && id_card) - var/t1 = params["assign_target"] - if(t1 == "Custom") - var/temp_t = reject_bad_text(input("Enter a custom job assignment.","Assignment", id_card.assignment), 45) - //let custom jobs function as an impromptu alt title, mainly for sechuds - if(temp_t) - id_card.assignment = temp_t - else - var/list/access = list() - if(is_centcom) - access = get_centcom_access(t1) - else - var/datum/job/jobdatum - for(var/jobtype in typesof(/datum/job)) - var/datum/job/J = new jobtype - if(ckey(J.title) == ckey(t1)) - jobdatum = J - break - if(!jobdatum) - to_chat(usr, "No log exists for this job: [t1]") - return - - access = jobdatum.get_access() - - remove_nt_access(id_card) - apply_access(id_card, access) - id_card.assignment = t1 - - if("PRG_access") - if(params["allowed"] && computer && authorized()) - var/access_type = text2num(params["access_target"]) - var/access_allowed = text2num(params["allowed"]) - if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses())) - id_card.access -= access_type - if(!access_allowed) - id_card.access += access_type - if("PRG_open_job") - var/edit_job_target = params["target"] - var/datum/job/j = SSjob.GetJob(edit_job_target) - if(!j) - return 0 - if(can_open_job(j) != 1) - return 0 - if(opened_positions[edit_job_target] >= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions++ - opened_positions[edit_job_target]++ - if("PRG_close_job") - var/edit_job_target = params["target"] - var/datum/job/j = SSjob.GetJob(edit_job_target) - if(!j) - return 0 - if(can_close_job(j) != 1) - return 0 - //Allow instant closing without cooldown if a position has been opened before - if(opened_positions[edit_job_target] <= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions-- - opened_positions[edit_job_target]-- - if("PRG_regsel") - if(!reg_ids) - reg_ids = list() - var/regsel = text2num(params["region"]) - if(regsel in reg_ids) - reg_ids -= regsel + if(!printer.print_text(contents,"access report")) + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") + return else - reg_ids += regsel + playsound(computer, 'sound/machines/terminal_on.ogg', 50, FALSE) + computer.visible_message("\The [computer] prints out a paper.") + return TRUE + if("PRG_eject") + if(!computer || !card_slot) + return + if(id_card) + GLOB.data_core.manifest_modify(id_card.registered_name, id_card.assignment) + card_slot.try_eject(TRUE, user) + else + var/obj/item/I = user.get_active_held_item() + if(istype(I, /obj/item/card/id)) + if(!user.transferItemToLoc(I, computer)) + return + card_slot.stored_card = I + playsound(computer, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + return TRUE + if("PRG_terminate") + if(!computer || !authenticated) + return + if(minor) + if(!(id_card.assignment in head_subordinates) && id_card.assignment != "Assistant") + return - if(id_card) - id_card.name = text("[id_card.registered_name]'s ID Card ([id_card.assignment])") + id_card.access -= get_all_centcom_access() + get_all_accesses() + id_card.assignment = "Unassigned" + id_card.update_label() + playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) + return TRUE + if("PRG_edit") + if(!computer || !authenticated || !id_card) + return + var/new_name = params["name"] + if(!new_name) + return + id_card.registered_name = new_name + id_card.update_label() + playsound(computer, "terminal_type", 50, FALSE) + return TRUE + if("PRG_assign") + if(!computer || !authenticated || !id_card) + return + var/target = params["assign_target"] + if(!target) + return - return 1 + if(target == "Custom") + var/custom_name = params["custom_name"] + if(custom_name) + id_card.assignment = custom_name + id_card.update_label() + else + if(minor && !(target in head_subordinates)) + return + var/list/new_access = list() + if(is_centcom) + new_access = get_centcom_access(target) + else + var/datum/job/job + for(var/jobtype in subtypesof(/datum/job)) + var/datum/job/J = new jobtype + if(J.title == target) + job = J + break + if(!job) + to_chat(user, "No class exists for this job: [target]") + return + new_access = job.get_access() + id_card.access -= get_all_centcom_access() + get_all_accesses() + id_card.access |= new_access + id_card.assignment = target + id_card.update_label() + playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + return TRUE + if("PRG_access") + if(!computer || !authenticated) + return + var/access_type = text2num(params["access_target"]) + if(access_type in (is_centcom ? get_all_centcom_access() : get_all_accesses())) + if(access_type in id_card.access) + id_card.access -= access_type + else + id_card.access |= access_type + playsound(computer, "terminal_type", 50, FALSE) + return TRUE + if("PRG_grantall") + if(!computer || !authenticated || minor) + return + id_card.access |= (is_centcom ? get_all_centcom_access() : get_all_accesses()) + playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + return TRUE + if("PRG_denyall") + if(!computer || !authenticated || minor) + return + id_card.access.Cut() + playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) + return TRUE + if("PRG_grantregion") + if(!computer || !authenticated) + return + var/region = text2num(params["region"]) + if(isnull(region)) + return + id_card.access |= get_region_accesses(region) + playsound(computer, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + return TRUE + if("PRG_denyregion") + if(!computer || !authenticated) + return + var/region = text2num(params["region"]) + if(isnull(region)) + return + id_card.access -= get_region_accesses(region) + playsound(computer, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) + return TRUE -/datum/computer_file/program/card_mod/proc/remove_nt_access(obj/item/card/id/id_card) - id_card.access -= get_all_accesses() - id_card.access -= get_all_centcom_access() -/datum/computer_file/program/card_mod/proc/apply_access(obj/item/card/id/id_card, list/accesses) - id_card.access |= accesses + +/datum/computer_file/program/card_mod/ui_static_data(mob/user) + var/list/data = list() + data["station_name"] = station_name() + data["centcom_access"] = is_centcom + data["minor"] = target_dept || minor ? TRUE : FALSE + + var/list/departments = target_dept + if(is_centcom) + departments = list("CentCom" = get_all_centcom_jobs()) + else if(isnull(departments)) + departments = list( + CARDCON_DEPARTMENT_COMMAND = list("Captain"),//lol + CARDCON_DEPARTMENT_ENGINEERING = GLOB.engineering_positions, + CARDCON_DEPARTMENT_MEDICAL = GLOB.medical_positions, + CARDCON_DEPARTMENT_SCIENCE = GLOB.science_positions, + CARDCON_DEPARTMENT_SECURITY = GLOB.security_positions, + CARDCON_DEPARTMENT_SUPPLY = GLOB.supply_positions, + CARDCON_DEPARTMENT_SERVICE = GLOB.service_positions + ) + data["jobs"] = list() + for(var/department in departments) + var/list/job_list = departments[department] + var/list/department_jobs = list() + for(var/job in job_list) + if(minor && !(job in head_subordinates)) + continue + department_jobs += list(list( + "display_name" = replacetext(job, " ", " "), + "job" = job + )) + if(length(department_jobs)) + data["jobs"][department] = department_jobs + + var/list/regions = list() + for(var/i in 1 to 7) + if((minor || target_dept) && !(i in region_access)) + continue + + var/list/accesses = list() + for(var/access in get_region_accesses(i)) + if (get_access_desc(access)) + accesses += list(list( + "desc" = replacetext(get_access_desc(access), " ", " "), + "ref" = access, + )) + + regions += list(list( + "name" = get_region_accesses_name(i), + "regid" = i, + "accesses" = accesses + )) + + data["regions"] = regions + + return data /datum/computer_file/program/card_mod/ui_data(mob/user) - var/list/data = get_header_data() var/obj/item/computer_hardware/card_slot/card_slot @@ -294,181 +330,34 @@ card_slot = computer.all_components[MC_CARD] printer = computer.all_components[MC_PRINT] - data["mmode"] = mod_mode - - var/authed = 0 - if(computer) - if(card_slot) - var/obj/item/card/id/auth_card = card_slot.stored_card2 - data["auth_name"] = auth_card ? strip_html_simple(auth_card.name) : "-----" - authed = authorized() - - - if(mod_mode == 2) - data["slots"] = list() - var/list/pos = list() - for(var/datum/job/job in SSjob.occupations) - if(job.title in blacklisted) - continue - - var/list/status_open = build_manage(job,1) - var/list/status_close = build_manage(job,0) - - pos.Add(list(list( - "title" = job.title, - "current" = job.current_positions, - "total" = job.total_positions, - "status_open" = (authed && !minor) ? status_open["enable"]: 0, - "status_close" = (authed && !minor) ? status_close["enable"] : 0, - "desc_open" = status_open["desc"], - "desc_close" = status_close["desc"]))) - data["slots"] = pos - - data["src"] = "[REF(src)]" data["station_name"] = station_name() - - if(!mod_mode) - data["manifest"] = list() - var/list/crew = list() - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - crew.Add(list(list( - "name" = t.fields["name"], - "rank" = t.fields["rank"]))) - - data["manifest"] = crew - data["assignments"] = show_assignments if(computer) data["have_id_slot"] = !!card_slot data["have_printer"] = !!printer - if(!card_slot && mod_mode == 1) - mod_mode = 0 //We can't modify IDs when there is no card reader else - data["have_id_slot"] = 0 - data["have_printer"] = 0 + data["have_id_slot"] = FALSE + data["have_printer"] = FALSE - data["centcom_access"] = is_centcom - - - data["authenticated"] = authed - - - if(mod_mode == 1 && computer) - if(card_slot) - var/obj/item/card/id/id_card = card_slot.stored_card - - data["has_id"] = !!id_card - data["id_rank"] = id_card && id_card.assignment ? html_encode(id_card.assignment) : "Unassigned" - data["id_owner"] = id_card && id_card.registered_name ? html_encode(id_card.registered_name) : "-----" - data["id_name"] = id_card ? strip_html_simple(id_card.name) : "-----" - - if(show_assignments) - data["engineering_jobs"] = format_jobs(GLOB.engineering_positions) - data["medical_jobs"] = format_jobs(GLOB.medical_positions) - data["science_jobs"] = format_jobs(GLOB.science_positions) - data["security_jobs"] = format_jobs(GLOB.security_positions) - data["cargo_jobs"] = format_jobs(GLOB.supply_positions) - data["civilian_jobs"] = format_jobs(GLOB.civilian_positions) - data["centcom_jobs"] = format_jobs(get_all_centcom_jobs()) - - - if(card_slot.stored_card) - var/obj/item/card/id/id_card = card_slot.stored_card - if(is_centcom) - var/list/all_centcom_access = list() - for(var/access in get_all_centcom_access()) - all_centcom_access.Add(list(list( - "desc" = replacetext(get_centcom_access_desc(access), " ", " "), - "ref" = access, - "allowed" = (access in id_card.access) ? 1 : 0))) - data["all_centcom_access"] = all_centcom_access - else - var/list/regions = list() - for(var/i = 1; i <= 7; i++) - if((minor || target_dept) && !(i in region_access)) - continue - - var/list/accesses = list() - if(i in reg_ids) - for(var/access in get_region_accesses(i)) - if (get_access_desc(access)) - accesses.Add(list(list( - "desc" = replacetext(get_access_desc(access), " ", " "), - "ref" = access, - "allowed" = (access in id_card.access) ? 1 : 0))) - - regions.Add(list(list( - "name" = get_region_accesses_name(i), - "regid" = i, - "selected" = (i in reg_ids) ? 1 : null, - "accesses" = accesses))) - data["regions"] = regions - - data["minor"] = target_dept || minor ? 1 : 0 + data["authenticated"] = authenticated + if(computer) + var/obj/item/card/id/id_card = card_slot.stored_card + data["has_id"] = !!id_card + data["id_name"] = id_card ? id_card.name : "-----" + if(id_card) + data["id_rank"] = id_card.assignment ? id_card.assignment : "Unassigned" + data["id_owner"] = id_card.registered_name ? id_card.registered_name : "-----" + data["access_on_card"] = id_card.access return data -/datum/computer_file/program/card_mod/proc/build_manage(datum/job,open = FALSE) - var/out = "Denied" - var/can_change= 0 - if(open) - can_change = can_open_job(job) - else - can_change = can_close_job(job) - var/enable = 0 - if(can_change == 1) - out = "[open ? "Open Position" : "Close Position"]" - enable = 1 - else if(can_change == -2) - var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) - var/mins = round(time_to_wait / 60) - var/seconds = time_to_wait - (60*mins) - out = "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" - else - out = "Denied" - return list("enable" = enable, "desc" = out) - - -/datum/computer_file/program/card_mod/proc/authorized() - if(!authenticated && computer) - var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD] - if(card_slot) - var/obj/item/card/id/auth_card = card_slot.stored_card2 - if(auth_card) - region_access = list() - if(ACCESS_CHANGE_IDS in auth_card.GetAccess()) - minor = 0 - authenticated = 1 - return 1 - else - if((ACCESS_HOP in auth_card.access) && ((target_dept==1) || !target_dept)) - region_access |= 1 - region_access |= 6 - get_subordinates("Head of Personnel") - if((ACCESS_HOS in auth_card.access) && ((target_dept==2) || !target_dept)) - region_access |= 2 - get_subordinates("Head of Security") - if((ACCESS_CMO in auth_card.access) && ((target_dept==3) || !target_dept)) - region_access |= 3 - get_subordinates("Chief Medical Officer") - if((ACCESS_RD in auth_card.access) && ((target_dept==4) || !target_dept)) - region_access |= 4 - get_subordinates("Research Director") - if((ACCESS_CE in auth_card.access) && ((target_dept==5) || !target_dept)) - region_access |= 5 - get_subordinates("Chief Engineer") - if(region_access.len) - minor = 1 - authenticated = 1 - return 1 - else - return authenticated - -/datum/computer_file/program/card_mod/proc/get_subordinates(rank) - head_subordinates = list() - for(var/datum/job/job in SSjob.occupations) - if(rank in job.department_head) - head_subordinates += job.title +#undef CARDCON_DEPARTMENT_SERVICE +#undef CARDCON_DEPARTMENT_SECURITY +#undef CARDCON_DEPARTMENT_MEDICAL +#undef CARDCON_DEPARTMENT_SCIENCE +#undef CARDCON_DEPARTMENT_SUPPLY +#undef CARDCON_DEPARTMENT_ENGINEERING +#undef CARDCON_DEPARTMENT_COMMAND diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index fd3b81be25..aba826fce8 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -14,176 +14,57 @@ /datum/computer_file/program/filemanager/ui_act(action, params) if(..()) - return 1 + return var/obj/item/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/RHDD = computer.all_components[MC_SDD] - var/obj/item/computer_hardware/printer/printer = computer.all_components[MC_PRINT] switch(action) - if("PRG_openfile") - . = 1 - open_file = params["name"] - if("PRG_newtextfile") - . = 1 - var/newname = stripped_input(usr, "Enter file name or leave blank to cancel:", "File rename", max_length=50) - if(!newname) - return 1 - if(!HDD) - return 1 - var/datum/computer_file/data/F = new/datum/computer_file/data() - F.filename = newname - F.filetype = "TXT" - HDD.store_file(F) if("PRG_deletefile") - . = 1 if(!HDD) - return 1 + return var/datum/computer_file/file = HDD.find_file_by_name(params["name"]) if(!file || file.undeletable) - return 1 + return HDD.remove_file(file) + return TRUE if("PRG_usbdeletefile") - . = 1 if(!RHDD) - return 1 + return var/datum/computer_file/file = RHDD.find_file_by_name(params["name"]) if(!file || file.undeletable) - return 1 - RHDD.remove_file(file) - if("PRG_closefile") - . = 1 - open_file = null - error = null - if("PRG_clone") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/F = HDD.find_file_by_name(params["name"]) - if(!F || !istype(F)) - return 1 - var/datum/computer_file/C = F.clone(1) - HDD.store_file(C) - if("PRG_rename") - . = 1 - if(!HDD) - return 1 - var/datum/computer_file/file = HDD.find_file_by_name(params["name"]) - if(!file || !istype(file)) - return 1 - var/newname = stripped_input(usr, "Enter new file name:", "File rename", file.filename, max_length=50) - if(file && newname) - file.filename = newname - if("PRG_edit") - . = 1 - if(!open_file) - return 1 - if(!HDD) - return 1 - var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) - if(!F || !istype(F)) - return 1 - if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No")) - return 1 - // 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently. - var/newtext = stripped_multiline_input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", html_decode(F.stored_data), 16384, TRUE) - if(!newtext) return - if(F) - var/datum/computer_file/data/backup = F.clone() - HDD.remove_file(F) - F.stored_data = newtext - F.calculate_size() - // We can't store the updated file, it's probably too large. Print an error and restore backed up version. - // This is mostly intended to prevent people from losing texts they spent lot of time working on due to running out of space. - // They will be able to copy-paste the text from error screen and store it in notepad or something. - if(!HDD.store_file(F)) - error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:

[F.stored_data]

" - HDD.store_file(backup) - if("PRG_printfile") - . = 1 - if(!open_file) - return 1 + RHDD.remove_file(file) + return TRUE + if("PRG_rename") if(!HDD) - return 1 - var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) - if(!F || !istype(F)) - return 1 - if(!printer) - error = "Missing Hardware: Your computer does not have required hardware to complete this operation." - return 1 - if(!printer.print_text("" + prepare_printjob(F.stored_data) + "", open_file)) - error = "Hardware error: Printer was unable to print the file. It may be out of paper." - return 1 + return + var/datum/computer_file/file = HDD.find_file_by_name(params["name"]) + if(!file) + return + var/newname = params["new_name"] + if(!newname) + return + file.filename = newname + return TRUE if("PRG_copytousb") - . = 1 if(!HDD || !RHDD) - return 1 + return var/datum/computer_file/F = HDD.find_file_by_name(params["name"]) - if(!F || !istype(F)) - return 1 - var/datum/computer_file/C = F.clone(0) + if(!F) + return + var/datum/computer_file/C = F.clone(FALSE) RHDD.store_file(C) + return TRUE if("PRG_copyfromusb") - . = 1 if(!HDD || !RHDD) - return 1 + return var/datum/computer_file/F = RHDD.find_file_by_name(params["name"]) if(!F || !istype(F)) - return 1 - var/datum/computer_file/C = F.clone(0) + return + var/datum/computer_file/C = F.clone(FALSE) HDD.store_file(C) - -/datum/computer_file/program/filemanager/proc/parse_tags(t) - t = replacetext(t, "\[center\]", "
") - t = replacetext(t, "\[/center\]", "
") - t = replacetext(t, "\[br\]", "
") - t = replacetext(t, "\n", "
") - t = replacetext(t, "\[b\]", "") - t = replacetext(t, "\[/b\]", "") - t = replacetext(t, "\[i\]", "") - t = replacetext(t, "\[/i\]", "") - t = replacetext(t, "\[u\]", "") - t = replacetext(t, "\[/u\]", "") - t = replacetext(t, "\[time\]", "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]") - t = replacetext(t, "\[date\]", "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]") - t = replacetext(t, "\[large\]", "") - t = replacetext(t, "\[/large\]", "") - t = replacetext(t, "\[h1\]", "

") - t = replacetext(t, "\[/h1\]", "

") - t = replacetext(t, "\[h2\]", "

") - t = replacetext(t, "\[/h2\]", "

") - t = replacetext(t, "\[h3\]", "

") - t = replacetext(t, "\[/h3\]", "

") - t = replacetext(t, "\[*\]", "
  • ") - t = replacetext(t, "\[hr\]", "
    ") - t = replacetext(t, "\[small\]", "") - t = replacetext(t, "\[/small\]", "") - t = replacetext(t, "\[list\]", "") - t = replacetext(t, "\[table\]", "") - t = replacetext(t, "\[/table\]", "
    ") - t = replacetext(t, "\[grid\]", "") - t = replacetext(t, "\[/grid\]", "
    ") - t = replacetext(t, "\[row\]", "") - t = replacetext(t, "\[tr\]", "") - t = replacetext(t, "\[td\]", "") - t = replacetext(t, "\[cell\]", "") - t = replacetext(t, "\[tab\]", "    ") - - t = parsemarkdown_basic(t) - - return t - -/datum/computer_file/program/filemanager/proc/prepare_printjob(t) // Additional stuff to parse if we want to print it and make a happy Head of Personnel. Forms FTW. - t = replacetext(t, "\[field\]", "") - t = replacetext(t, "\[sign\]", "") - - t = parse_tags(t) - - t = replacetext(t, regex("(?:%s(?:ign)|%f(?:ield))(?=\\s|$)", "ig"), "") - - return t + return TRUE /datum/computer_file/program/filemanager/ui_data(mob/user) var/list/data = get_header_data() @@ -192,41 +73,28 @@ var/obj/item/computer_hardware/hard_drive/portable/RHDD = computer.all_components[MC_SDD] if(error) data["error"] = error - if(open_file) - var/datum/computer_file/data/file - - if(!computer || !HDD) - data["error"] = "I/O ERROR: Unable to access hard drive." - else - file = HDD.find_file_by_name(open_file) - if(!istype(file)) - data["error"] = "I/O ERROR: Unable to open file." - else - data["filedata"] = parse_tags(file.stored_data) - data["filename"] = "[file.filename].[file.filetype]" + if(!computer || !HDD) + data["error"] = "I/O ERROR: Unable to access hard drive." else - if(!computer || !HDD) - data["error"] = "I/O ERROR: Unable to access hard drive." - else - var/list/files[0] - for(var/datum/computer_file/F in HDD.stored_files) - files.Add(list(list( + var/list/files = list() + for(var/datum/computer_file/F in HDD.stored_files) + files += list(list( + "name" = F.filename, + "type" = F.filetype, + "size" = F.size, + "undeletable" = F.undeletable + )) + data["files"] = files + if(RHDD) + data["usbconnected"] = TRUE + var/list/usbfiles = list() + for(var/datum/computer_file/F in RHDD.stored_files) + usbfiles += list(list( "name" = F.filename, "type" = F.filetype, "size" = F.size, "undeletable" = F.undeletable - ))) - data["files"] = files - if(RHDD) - data["usbconnected"] = 1 - var/list/usbfiles[0] - for(var/datum/computer_file/F in RHDD.stored_files) - usbfiles.Add(list(list( - "name" = F.filename, - "type" = F.filetype, - "size" = F.size, - "undeletable" = F.undeletable - ))) - data["usbfiles"] = usbfiles + )) + data["usbfiles"] = usbfiles return data diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index 80c014bd03..352f13f305 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -115,49 +115,50 @@ var/list/data = get_header_data() - // This IF cuts on data transferred to client, so i guess it's worth it. - if(downloaderror) // Download errored. Wait until user resets the program. - data["error"] = downloaderror - else if(downloaded_file) // Download running. Wait please.. + data["downloading"] = !!downloaded_file + data["error"] = downloaderror || FALSE + + // Download running. Wait please.. + if(downloaded_file) data["downloadname"] = downloaded_file.filename data["downloaddesc"] = downloaded_file.filedesc data["downloadsize"] = downloaded_file.size data["downloadspeed"] = download_netspeed data["downloadcompletion"] = round(download_completion, 0.1) - else // No download running, pick file. - 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 SSnetworks.station_network.available_station_software) - var/datum/computer_file/program/P = A - // Only those programs our user can run will show in the list - if(!P.can_run(user,transfer = 1) || hard_drive.find_file_by_name(P.filename)) - continue - all_entries.Add(list(list( + + 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 SSnetworks.station_network.available_station_software) + var/datum/computer_file/program/P = A + // Only those programs our user can run will show in the list + if(!P.can_run(user,transfer = 1) || hard_drive.find_file_by_name(P.filename)) + continue + all_entries.Add(list(list( "filename" = P.filename, "filedesc" = P.filedesc, "fileinfo" = P.extended_desc, "compatibility" = check_compatibility(P), - "size" = P.size - ))) - data["hackedavailable"] = 0 - if(computer.obj_flags & EMAGGED) // If we are running on emagged computer we have access to some "bonus" software - var/list/hacked_programs[0] - for(var/S in SSnetworks.station_network.available_antag_software) - var/datum/computer_file/program/P = S - if(hard_drive.find_file_by_name(P.filename)) - continue - data["hackedavailable"] = 1 - hacked_programs.Add(list(list( + "size" = P.size, + ))) + data["hackedavailable"] = FALSE + if(computer.obj_flags & EMAGGED) // If we are running on emagged computer we have access to some "bonus" software + var/list/hacked_programs[0] + for(var/S in SSnetworks.station_network.available_antag_software) + 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, - "size" = P.size - ))) - data["hacked_programs"] = hacked_programs + "size" = P.size, + ))) + data["hacked_programs"] = hacked_programs - data["downloadable_programs"] = all_entries + data["downloadable_programs"] = all_entries return data diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index 656c7614ab..7d6d89f32c 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -4,58 +4,48 @@ 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 = 1 + requires_ntnet = TRUE required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM. available_on_ntnet = TRUE tgui_id = "NtosNetMonitor" /datum/computer_file/program/ntnetmonitor/ui_act(action, params) if(..()) - return 1 + return switch(action) if("resetIDS") - . = 1 if(SSnetworks.station_network) SSnetworks.station_network.resetIDS() - return 1 + return TRUE if("toggleIDS") - . = 1 if(SSnetworks.station_network) SSnetworks.station_network.toggleIDS() - return 1 + return TRUE if("toggleWireless") - . = 1 if(!SSnetworks.station_network) - return 1 + return // NTNet is disabled. Enabling can be done without user prompt if(SSnetworks.station_network.setting_disabled) - SSnetworks.station_network.setting_disabled = 0 - return 1 + SSnetworks.station_network.setting_disabled = FALSE + return TRUE - // NTNet is enabled and user is about to shut it down. Let's ask them if they really want to do it, as wirelessly connected computers won't connect without NTNet being enabled (which may prevent people from turning it back on) - var/mob/user = usr - if(!user) - return 1 - var/response = alert(user, "Really disable NTNet wireless? If your computer is connected wirelessly you won't be able to turn it back on! This will affect all connected wireless devices.", "NTNet shutdown", "Yes", "No") - if(response == "Yes") - SSnetworks.station_network.setting_disabled = 1 - return 1 + SSnetworks.station_network.setting_disabled = TRUE + return TRUE if("purgelogs") - . = 1 if(SSnetworks.station_network) SSnetworks.station_network.purge_logs() + return TRUE if("updatemaxlogs") - . = 1 - var/mob/user = usr - var/logcount = text2num(input(user,"Enter amount of logs to keep in memory ([MIN_NTNET_LOGS]-[MAX_NTNET_LOGS]):")) + var/logcount = params["new_number"] if(SSnetworks.station_network) SSnetworks.station_network.update_max_log_count(logcount) + return TRUE if("toggle_function") - . = 1 if(!SSnetworks.station_network) - return 1 + return SSnetworks.station_network.toggle_function(text2num(params["id"])) + return TRUE /datum/computer_file/program/ntnetmonitor/ui_data(mob/user) if(!SSnetworks.station_network) @@ -73,6 +63,8 @@ data["config_systemcontrol"] = SSnetworks.station_network.setting_systemcontrol data["ntnetlogs"] = list() + data["minlogs"] = MIN_NTNET_LOGS + data["maxlogs"] = MAX_NTNET_LOGS for(var/i in SSnetworks.station_network.logs) data["ntnetlogs"] += list(list("entry" = i)) diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index 0c30319c2a..d78ed9239e 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -81,13 +81,13 @@ if(air.total_moles()) for(var/gasid in air.gases) gasdata.Add(list(list( - "name"= GLOB.meta_gas_names[gasid], - "amount" = round(100*air.gases[gasid]/air.total_moles(),0.01)))) + "name"= air.gases[gasid][GAS_META][META_GAS_NAME], + "amount" = round(100*air.gases[gasid][MOLES]/air.total_moles(),0.01)))) else for(var/gasid in air.gases) gasdata.Add(list(list( - "name"= GLOB.meta_gas_names[gasid], + "name"= air.gases[gasid][GAS_META][META_GAS_NAME], "amount" = 0))) data["gases"] = gasdata diff --git a/code/modules/ruins/spaceruin_code/TheDerelict.dm b/code/modules/ruins/spaceruin_code/TheDerelict.dm index 2e2765b1a9..e69e8ed3e7 100644 --- a/code/modules/ruins/spaceruin_code/TheDerelict.dm +++ b/code/modules/ruins/spaceruin_code/TheDerelict.dm @@ -167,6 +167,7 @@ // So drones can teach borgs and AI dronespeak. For best effect, combine with mother drone lawset. + /obj/item/dronespeak_manual name = "dronespeak manual" desc = "The book's cover reads: \"Understanding Dronespeak - An exercise in futility.\"" @@ -180,7 +181,7 @@ to_chat(user, "You start skimming through [src], but you already know dronespeak.") else to_chat(user, "You start skimming through [src], and suddenly the drone chittering makes sense.") - user.grant_language(/datum/language/drone, TRUE, TRUE, LANGUAGE_MIND) + user.grant_language(/datum/language/drone, TRUE, TRUE) return if(user.has_language(/datum/language/drone)) @@ -201,7 +202,7 @@ M.visible_message("[user] beats [M] over the head with [src]!", "[user] beats you over the head with [src]!", "You hear smacking.") else M.visible_message("[user] teaches [M] by beating [M.p_them()] over the head with [src]!", "As [user] hits you with [src], chitters resonate in your mind.", "You hear smacking.") - M.grant_language(/datum/language/drone, TRUE, TRUE, LANGUAGE_MIND) + M.grant_language(/datum/language/drone, TRUE, TRUE) return /obj/structure/fluff/oldturret diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index fed256e98c..301ab24f98 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -105,10 +105,10 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) message_admins("[ADMIN_LOOKUPFLW(triggerer)] triggered and [ADMIN_LOOKUPFLW(confirmer)] confirmed event [event]") var/area/A1 = get_area(triggerer) - deadchat_broadcast(" triggered [event] at [A1.name].", "[triggerer]", triggerer, message_type=DEADCHAT_ANNOUNCEMENT) + deadchat_broadcast(" triggered [event] at [A1.name].", "[triggerer]", triggerer) var/area/A2 = get_area(confirmer) - deadchat_broadcast(" confirmed [event] at [A2.name].", "[confirmer]", confirmer, message_type=DEADCHAT_ANNOUNCEMENT) + deadchat_broadcast(" confirmed [event] at [A2.name].", "[confirmer]", confirmer) switch(event) if(KEYCARD_RED_ALERT) set_security_level(SEC_LEVEL_RED) diff --git a/code/modules/shuttle/manipulator.dm b/code/modules/shuttle/manipulator.dm index 3ba2198b35..a44bb179f0 100644 --- a/code/modules/shuttle/manipulator.dm +++ b/code/modules/shuttle/manipulator.dm @@ -5,369 +5,3 @@ Two roads diverged in a wood, and I,\n\ I took the one less traveled by,\n\ And that has made all the difference." - - icon = 'icons/obj/machines/shuttle_manipulator.dmi' - icon_state = "holograph_on" - - density = TRUE - - // UI state variables - var/datum/map_template/shuttle/selected - - var/obj/docking_port/mobile/existing_shuttle - - var/obj/docking_port/mobile/preview_shuttle - var/datum/map_template/shuttle/preview_template - -/obj/machinery/shuttle_manipulator/Initialize() - . = ..() - update_icon() - SSshuttle.manipulator = src - -/obj/machinery/shuttle_manipulator/Destroy(force) - if(!force) - . = QDEL_HINT_LETMELIVE - else - SSshuttle.manipulator = null - . = ..() - -/obj/machinery/shuttle_manipulator/update_overlays() - . = ..() - var/mutable_appearance/hologram_projection = mutable_appearance(icon, "hologram_on") - hologram_projection.pixel_y = 22 - var/mutable_appearance/hologram_ship = mutable_appearance(icon, "hologram_whiteship") - hologram_ship.pixel_y = 27 - . += hologram_projection - . += hologram_ship - -/obj/machinery/shuttle_manipulator/can_interact(mob/user) - // Only admins can use this, but they can use it from anywhere - return user.client && check_rights_for(user.client, R_ADMIN) - -/obj/machinery/shuttle_manipulator/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "shuttle_manipulator", name, 800, 600, master_ui, state) - ui.open() - -/proc/shuttlemode2str(mode) - switch(mode) - if(SHUTTLE_IDLE) - . = "idle" - if(SHUTTLE_IGNITING) - . = "engines charging" - if(SHUTTLE_RECALL) - . = "recalled" - if(SHUTTLE_CALL) - . = "called" - if(SHUTTLE_DOCKED) - . = "docked" - if(SHUTTLE_STRANDED) - . = "stranded" - if(SHUTTLE_ESCAPE) - . = "escape" - if(SHUTTLE_ENDGAME) - . = "endgame" - if(!.) - CRASH("shuttlemode2str(): invalid mode [mode]") - - -/obj/machinery/shuttle_manipulator/ui_data(mob/user) - var/list/data = list() - data["tabs"] = list("Status", "Templates", "Modification") - - // Templates panel - data["templates"] = list() - var/list/templates = data["templates"] - data["templates_tabs"] = list() - data["selected"] = list() - - for(var/shuttle_id in SSmapping.shuttle_templates) - var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id] - - if(!templates[S.port_id]) - data["templates_tabs"] += S.port_id - templates[S.port_id] = list( - "port_id" = S.port_id, - "templates" = list()) - - var/list/L = list() - L["name"] = S.name - L["shuttle_id"] = S.shuttle_id - L["port_id"] = S.port_id - L["description"] = S.description - L["admin_notes"] = S.admin_notes - - if(selected == S) - data["selected"] = L - - templates[S.port_id]["templates"] += list(L) - - data["templates_tabs"] = sortList(data["templates_tabs"]) - - data["existing_shuttle"] = null - - // Status panel - data["shuttles"] = list() - for(var/i in SSshuttle.mobile) - var/obj/docking_port/mobile/M = i - var/timeleft = M.timeLeft(1) - var/list/L = list() - L["name"] = M.name - L["id"] = M.id - L["timer"] = M.timer - L["timeleft"] = M.getTimerStr() - if (timeleft > 1 HOURS) - L["timeleft"] = "Infinity" - L["can_fast_travel"] = M.timer && timeleft >= 50 - L["can_fly"] = TRUE - if(istype(M, /obj/docking_port/mobile/emergency)) - L["can_fly"] = FALSE - else if(!M.destination) - L["can_fast_travel"] = FALSE - if (M.mode != SHUTTLE_IDLE) - L["mode"] = capitalize(shuttlemode2str(M.mode)) - L["status"] = M.getDbgStatusText() - if(M == existing_shuttle) - data["existing_shuttle"] = L - - data["shuttles"] += list(L) - - return data - -/obj/machinery/shuttle_manipulator/ui_act(action, params) - if(..()) - return - - var/mob/user = usr - - // Preload some common parameters - var/shuttle_id = params["shuttle_id"] - var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id] - - switch(action) - if("select_template") - if(S) - existing_shuttle = SSshuttle.getShuttle(S.port_id) - selected = S - . = TRUE - if("jump_to") - if(params["type"] == "mobile") - for(var/i in SSshuttle.mobile) - var/obj/docking_port/mobile/M = i - if(M.id == params["id"]) - user.forceMove(get_turf(M)) - . = TRUE - break - - if("fly") - for(var/i in SSshuttle.mobile) - var/obj/docking_port/mobile/M = i - if(M.id == params["id"]) - . = TRUE - M.admin_fly_shuttle(user) - break - - if("fast_travel") - for(var/i in SSshuttle.mobile) - var/obj/docking_port/mobile/M = i - if(M.id == params["id"] && M.timer && M.timeLeft(1) >= 50) - M.setTimer(50) - . = TRUE - message_admins("[key_name_admin(usr)] fast travelled [M]") - log_admin("[key_name(usr)] fast travelled [M]") - SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[M.name]") - break - - if("preview") - if(S) - . = TRUE - unload_preview() - load_template(S) - if(preview_shuttle) - preview_template = S - user.forceMove(get_turf(preview_shuttle)) - if("load") - if(existing_shuttle == SSshuttle.backup_shuttle) - // TODO make the load button disabled - WARNING("The shuttle that the selected shuttle will replace \ - is the backup shuttle. Backup shuttle is required to be \ - intact for round sanity.") - else if(S) - . = TRUE - // If successful, returns the mobile docking port - var/obj/docking_port/mobile/mdp = action_load(S) - if(mdp) - user.forceMove(get_turf(mdp)) - message_admins("[key_name_admin(usr)] loaded [mdp] with the shuttle manipulator.") - log_admin("[key_name(usr)] loaded [mdp] with the shuttle manipulator.") - SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]") - - update_icon() - -/obj/machinery/shuttle_manipulator/proc/action_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port) - // Check for an existing preview - if(preview_shuttle && (loading_template != preview_template)) - preview_shuttle.jumpToNullSpace() - preview_shuttle = null - preview_template = null - - if(!preview_shuttle) - if(load_template(loading_template)) - preview_shuttle.linkup(loading_template, destination_port) - preview_template = loading_template - - // get the existing shuttle information, if any - var/timer = 0 - var/mode = SHUTTLE_IDLE - var/obj/docking_port/stationary/D - - if(istype(destination_port)) - D = destination_port - else if(existing_shuttle) - timer = existing_shuttle.timer - mode = existing_shuttle.mode - D = existing_shuttle.get_docked() - - if(!D) - CRASH("No dock found for preview shuttle ([preview_template.name]), aborting.") - - var/result = preview_shuttle.canDock(D) - // truthy value means that it cannot dock for some reason - // but we can ignore the someone else docked error because we'll - // be moving into their place shortly - if((result != SHUTTLE_CAN_DOCK) && (result != SHUTTLE_SOMEONE_ELSE_DOCKED)) - WARNING("Template shuttle [preview_shuttle] cannot dock at [D] ([result]).") - return - - if(existing_shuttle) - existing_shuttle.jumpToNullSpace() - - var/list/force_memory = preview_shuttle.movement_force - preview_shuttle.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0) - preview_shuttle.initiate_docking(D) - preview_shuttle.movement_force = force_memory - - . = preview_shuttle - - // Shuttle state involves a mode and a timer based on world.time, so - // plugging the existing shuttles old values in works fine. - preview_shuttle.timer = timer - preview_shuttle.mode = mode - - preview_shuttle.register() - - // TODO indicate to the user that success happened, rather than just - // blanking the modification tab - preview_shuttle = null - preview_template = null - existing_shuttle = null - selected = null - -/obj/machinery/shuttle_manipulator/proc/load_template(datum/map_template/shuttle/S) - . = FALSE - // load shuttle template, centred at shuttle import landmark, - var/turf/landmark_turf = get_turf(locate(/obj/effect/landmark/shuttle_import) in GLOB.landmarks_list) - S.load(landmark_turf, centered = TRUE, register = FALSE) - - var/affected = S.get_affected_turfs(landmark_turf, centered=TRUE) - - var/found = 0 - // Search the turfs for docking ports - // - We need to find the mobile docking port because that is the heart of - // the shuttle. - // - We need to check that no additional ports have slipped in from the - // template, because that causes unintended behaviour. - for(var/T in affected) - for(var/obj/docking_port/P in T) - if(istype(P, /obj/docking_port/mobile)) - found++ - if(found > 1) - qdel(P, force=TRUE) - log_world("Map warning: Shuttle Template [S.mappath] has multiple mobile docking ports.") - else - preview_shuttle = P - if(istype(P, /obj/docking_port/stationary)) - log_world("Map warning: Shuttle Template [S.mappath] has a stationary docking port.") - if(!found) - var/msg = "load_template(): Shuttle Template [S.mappath] has no mobile docking port. Aborting import." - for(var/T in affected) - var/turf/T0 = T - T0.empty() - - message_admins(msg) - WARNING(msg) - return - //Everything fine - S.on_bought() - return TRUE - -/obj/machinery/shuttle_manipulator/proc/unload_preview() - if(preview_shuttle) - preview_shuttle.jumpToNullSpace() - preview_shuttle = null - -/obj/docking_port/mobile/proc/admin_fly_shuttle(mob/user) - var/list/options = list() - - for(var/port in SSshuttle.stationary) - if (istype(port, /obj/docking_port/stationary/transit)) - continue // please don't do this - var/obj/docking_port/stationary/S = port - if (canDock(S) == SHUTTLE_CAN_DOCK) - options[S.name || S.id] = S - - options += "--------" - options += "Infinite Transit" - options += "Delete Shuttle" - options += "Into The Sunset (delete & greentext 'escape')" - - var/selection = input(user, "Select where to fly [name || id]:", "Fly Shuttle") as null|anything in options - if(!selection) - return - - switch(selection) - if("Infinite Transit") - destination = null - mode = SHUTTLE_IGNITING - setTimer(ignitionTime) - - if("Delete Shuttle") - if(alert(user, "Really delete [name || id]?", "Delete Shuttle", "Cancel", "Really!") != "Really!") - return - jumpToNullSpace() - - if("Into The Sunset (delete & greentext 'escape')") - if(alert(user, "Really delete [name || id] and greentext escape objectives?", "Delete Shuttle", "Cancel", "Really!") != "Really!") - return - intoTheSunset() - - else - if(options[selection]) - request(options[selection]) - -/obj/docking_port/mobile/emergency/admin_fly_shuttle(mob/user) - return // use the existing verbs for this - -/obj/docking_port/mobile/arrivals/admin_fly_shuttle(mob/user) - switch(alert(user, "Would you like to fly the arrivals shuttle once or change its destination?", "Fly Shuttle", "Fly", "Retarget", "Cancel")) - if("Cancel") - return - if("Fly") - return ..() - - var/list/options = list() - - for(var/port in SSshuttle.stationary) - if (istype(port, /obj/docking_port/stationary/transit)) - continue // please don't do this - var/obj/docking_port/stationary/S = port - if (canDock(S) == SHUTTLE_CAN_DOCK) - options[S.name || S.id] = S - - var/selection = input(user, "Select the new arrivals destination:", "Fly Shuttle") as null|anything in options - if(!selection) - return - target_dock = options[selection] - if(!QDELETED(target_dock)) - destination = target_dock diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 2c466564ff..5de6b8ca06 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -194,10 +194,10 @@ roundstart_template = SSmapping.shuttle_templates[sid] if(!roundstart_template) - CRASH("Invalid path ([roundstart_template]) passed to docking port.") + CRASH("Invalid path ([sid]/[roundstart_template]) passed to docking port.") if(roundstart_template) - SSshuttle.manipulator.action_load(roundstart_template, src) + SSshuttle.action_load(roundstart_template, src) //returns first-found touching shuttleport /obj/docking_port/stationary/get_docked() diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm index 5ddbd81b25..e626b98815 100644 --- a/code/modules/tgui/states.dm +++ b/code/modules/tgui/states.dm @@ -111,7 +111,7 @@ return UI_DISABLED return UI_CLOSE // Otherwise, we got nothing. -/mob/living/carbon/human/shared_living_ui_distance(atom/movable/src_object) +/mob/living/carbon/human/shared_living_ui_distance(atom/movable/src_object, viewcheck = TRUE) if(dna.check_mutation(TK) && tkMaxRangeCheck(src, src_object)) return UI_INTERACTIVE return ..() diff --git a/icons/UI_Icons/Arcade/boss1.gif b/icons/UI_Icons/Arcade/boss1.gif new file mode 100644 index 0000000000..4730ac0021 Binary files /dev/null and b/icons/UI_Icons/Arcade/boss1.gif differ diff --git a/icons/UI_Icons/Arcade/boss2.gif b/icons/UI_Icons/Arcade/boss2.gif new file mode 100644 index 0000000000..d95fd84f0e Binary files /dev/null and b/icons/UI_Icons/Arcade/boss2.gif differ diff --git a/icons/UI_Icons/Arcade/boss3.gif b/icons/UI_Icons/Arcade/boss3.gif new file mode 100644 index 0000000000..e97056998a Binary files /dev/null and b/icons/UI_Icons/Arcade/boss3.gif differ diff --git a/icons/UI_Icons/Arcade/boss4.gif b/icons/UI_Icons/Arcade/boss4.gif new file mode 100644 index 0000000000..6695b6cfbf Binary files /dev/null and b/icons/UI_Icons/Arcade/boss4.gif differ diff --git a/icons/UI_Icons/Arcade/boss5.gif b/icons/UI_Icons/Arcade/boss5.gif new file mode 100644 index 0000000000..a827fb8c4e Binary files /dev/null and b/icons/UI_Icons/Arcade/boss5.gif differ diff --git a/icons/UI_Icons/Arcade/boss6.gif b/icons/UI_Icons/Arcade/boss6.gif new file mode 100644 index 0000000000..7a926cf89d Binary files /dev/null and b/icons/UI_Icons/Arcade/boss6.gif differ diff --git a/tgstation.dme b/tgstation.dme index 9fbcad85c8..be80aeb64a 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1050,6 +1050,7 @@ #include "code\game\objects\items\stacks\rods.dm" #include "code\game\objects\items\stacks\stack.dm" #include "code\game\objects\items\stacks\telecrystal.dm" +#include "code\game\objects\items\stacks\tickets.dm" #include "code\game\objects\items\stacks\wrap.dm" #include "code\game\objects\items\stacks\sheets\glass.dm" #include "code\game\objects\items\stacks\sheets\leather.dm"