diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 5c931924397..57f8c5d1eeb 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -398,6 +398,7 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define ARCADE_FILE "arcade.json" #define BOOMER_FILE "boomer.json" #define LOCATIONS_FILE "locations.json" +#define WANTED_FILE "wanted_message.json" //Fullscreen overlay resolution in tiles. #define FULLSCREEN_OVERLAY_RESOLUTION_X 15 diff --git a/code/__HELPERS/_string_lists.dm b/code/__HELPERS/_string_lists.dm index f2f57bb15db..32c2dc213ec 100644 --- a/code/__HELPERS/_string_lists.dm +++ b/code/__HELPERS/_string_lists.dm @@ -1,4 +1,5 @@ #define pick_list(FILE, KEY) (pick(strings(FILE, KEY))) +#define pick_list_weighted(FILE, KEY) (pickweight(strings(FILE, KEY))) #define pick_list_replacements(FILE, KEY) (strings_replacement(FILE, KEY)) #define json_load(FILE) (json_decode(file2text(FILE))) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 4789d04bc0d..2235ddc1364 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -355,11 +355,8 @@ var result = "" var total_spent_rep = 0 - var/completed_contracts = 0 + var/completed_contracts = contractor_hub.contracts_completed var/tc_total = contractor_hub.contract_TC_payed_out + contractor_hub.contract_TC_to_redeem - for (var/datum/syndicate_contract/contract in contractor_hub.assigned_contracts) - if (contract.status == CONTRACT_STATUS_COMPLETE) - completed_contracts++ var/contractor_item_icons = "" // Icons of purchases var/contractor_support_unit = "" // Set if they had a support unit - and shows appended to their contracts completed diff --git a/code/modules/antagonists/traitor/equipment/contractor.dm b/code/modules/antagonists/traitor/equipment/contractor.dm index e82c7f30edd..2c3dff433e5 100644 --- a/code/modules/antagonists/traitor/equipment/contractor.dm +++ b/code/modules/antagonists/traitor/equipment/contractor.dm @@ -35,6 +35,7 @@ var/list/assigned_targets = list() // used as a blacklist to make sure we're not assigning targets already assigned + var/contracts_completed = 0 var/contract_TC_payed_out = 0 // Keeping track for roundend reporting var/contract_TC_to_redeem = 0 // Used internally and roundend reporting - what TC we have available to cashout. @@ -56,8 +57,12 @@ CONTRACT_PAYOUT_SMALL ) + //What the fuck + if(length(to_generate) > length(GLOB.data_core.locked)) + to_generate.Cut(1, length(GLOB.data_core.locked)) + // We don't want the sum of all the payouts to be under this amount - var/lowest_TC_threshold = 30 + var/lowest_TC_threshold = 30 var/total = 0 var/lowest_paying_sum = 0 @@ -75,7 +80,7 @@ for (var/i = 1; i <= to_generate.len; i++) var/datum/syndicate_contract/contract_to_add = new(owner, assigned_targets, to_generate[i]) var/contract_payout_total = contract_to_add.contract.payout + contract_to_add.contract.payout_bonus - + assigned_targets.Add(contract_to_add.contract.target) if (!lowest_paying_contract || (contract_payout_total < lowest_paying_sum)) @@ -96,14 +101,14 @@ var/name // Name of item var/desc // description of item var/item // item path, no item path means the purchase needs it's own handle_purchase() - var/item_icon = "fa-broadcast-tower" // fontawesome icon to use inside the hub - https://fontawesome.com/icons/ + var/item_icon = "broadcast-tower" // fontawesome icon to use inside the hub - https://fontawesome.com/icons/ var/limited = -1 // Any number above 0 for how many times it can be bought in a round for a single traitor. -1 is unlimited. var/cost // Cost of the item in contract rep. /datum/contractor_item/contract_reroll name = "Contract Reroll" desc = "Request a reroll of your current contract list. Will generate a new target, payment, and dropoff for the contracts you currently have available." - item_icon = "fa-dice" + item_icon = "dice" limited = 2 cost = 0 @@ -118,7 +123,7 @@ if (contract_check.contract.target) new_target_list.Add(contract_check.contract.target) continue - + /// Reroll contracts without duplicates for(var/datum/syndicate_contract/rerolling_contract in hub.assigned_contracts) if (rerolling_contract.status != CONTRACT_STATUS_ACTIVE && rerolling_contract.status != CONTRACT_STATUS_INACTIVE) @@ -134,7 +139,7 @@ name = "Contractor Pinpointer" desc = "A pinpointer that finds targets even without active suit sensors. Due to taking advantage of an exploit within the system, it can't pinpoint to the same accuracy as the traditional models. Becomes permanently locked to the user that first activates it." item = /obj/item/pinpointer/crew/contractor - item_icon = "fa-search-location" + item_icon = "search-location" limited = 2 cost = 1 @@ -142,14 +147,14 @@ name = "Fulton Extraction Kit" desc = "For getting your target across the station to those difficult dropoffs. Place the beacon somewhere secure, and link the pack. Activating the pack on your target in space will send them over to the beacon - make sure they're not just going to run away though!" item = /obj/item/storage/box/contractor/fulton_extraction - item_icon = "fa-parachute-box" + item_icon = "parachute-box" limited = 1 cost = 1 /datum/contractor_item/contractor_partner name = "Reinforcements" desc = "Upon purchase we'll contact available units in the area. Should there be an agent free, we'll send them down to assist you immediately. If no units are free, we give a full refund." - item_icon = "fa-user-friends" + item_icon = "user-friends" limited = 1 cost = 2 var/datum/mind/partner_mind = null @@ -175,7 +180,7 @@ /datum/outfit/contractor_partner name = "Contractor Support Unit" - + uniform = /obj/item/clothing/under/chameleon suit = /obj/item/clothing/suit/chameleon back = /obj/item/storage/backpack @@ -186,7 +191,7 @@ id = /obj/item/card/id/syndicate r_hand = /obj/item/storage/toolbox/syndicate - backpack_contents = list(/obj/item/storage/box/survival, /obj/item/implanter/uplink, /obj/item/clothing/mask/chameleon, + backpack_contents = list(/obj/item/storage/box/survival, /obj/item/implanter/uplink, /obj/item/clothing/mask/chameleon, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/lighter) /datum/outfit/contractor_partner/post_equip(mob/living/carbon/human/H, visualsOnly) @@ -229,7 +234,7 @@ /datum/contractor_item/blackout name = "Blackout" desc = "Request Syndicate Command to distrupt the station's powernet. Disables power across the station for a short duration." - item_icon = "fa-bolt" + item_icon = "bolt" limited = 2 cost = 3 @@ -242,10 +247,10 @@ // Subtract cost, and spawn if it's an item. /datum/contractor_item/proc/handle_purchase(var/datum/contractor_hub/hub, mob/living/user) - + if (hub.contract_rep >= cost) hub.contract_rep -= cost - else + else return FALSE if (limited >= 1) @@ -259,7 +264,7 @@ if (item && ispath(item)) var/atom/item_to_create = new item(get_turf(user)) - + if(user.put_in_hands(item_to_create)) to_chat(user, "Your purchase materializes into your hands!") else diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm index 3e2ed4b7a84..269e284d112 100644 --- a/code/modules/antagonists/traitor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/syndicate_contract.dm @@ -4,7 +4,8 @@ var/datum/objective/contract/contract = new() var/target_rank var/ransom = 0 - var/payout_type = null + var/payout_type + var/wanted_message var/list/victim_belongings = list() @@ -16,11 +17,11 @@ /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) if (record) target_rank = record.fields["rank"] - else + else target_rank = "Unknown" if (payout_type == CONTRACT_PAYOUT_LARGE) @@ -35,6 +36,12 @@ ransom = 100 * rand(18, 45) + var/base = pick_list(WANTED_FILE, "basemessage") + var/verb_string = pick_list(WANTED_FILE, "verb") + var/noun = pick_list_weighted(WANTED_FILE, "noun") + var/location = pick_list_weighted(WANTED_FILE, "location") + wanted_message = "[base] [verb_string] [noun] [location]." + /datum/syndicate_contract/proc/handle_extraction(var/mob/living/user) if (contract.target && contract.dropoff_check(user, contract.target.current)) @@ -50,7 +57,7 @@ // Launch the pod to collect our victim. /datum/syndicate_contract/proc/launch_extraction_pod(turf/empty_pod_turf) var/obj/structure/closet/supplypod/extractionpod/empty_pod = new() - + RegisterSignal(empty_pod, COMSIG_ATOM_ENTERED, .proc/enter_check) empty_pod.stay_after_drop = TRUE @@ -65,23 +72,24 @@ if (isliving(sent_mob)) var/mob/living/M = sent_mob var/datum/antagonist/traitor/traitor_data = contract.owner.has_antag_datum(/datum/antagonist/traitor) - + if (M == contract.target.current) traitor_data.contractor_hub.contract_TC_to_redeem += contract.payout + traitor_data.contractor_hub.contracts_completed += 1 if (M.stat != DEAD) traitor_data.contractor_hub.contract_TC_to_redeem += contract.payout_bonus status = CONTRACT_STATUS_COMPLETE - if (traitor_data.contractor_hub.current_contract == src) + if (traitor_data.contractor_hub.current_contract == src) traitor_data.contractor_hub.current_contract = null - + traitor_data.contractor_hub.contract_rep += 2 else status = CONTRACT_STATUS_ABORTED // Sending a target that wasn't even yours is as good as just aborting it - - if (traitor_data.contractor_hub.current_contract == src) + + if (traitor_data.contractor_hub.current_contract == src) traitor_data.contractor_hub.current_contract = null if (iscarbon(M)) @@ -92,11 +100,11 @@ continue //So all they're left with are shoes and uniform. if(W == H.shoes) continue - + M.transferItemToLoc(W) victim_belongings.Add(W) - + var/obj/structure/closet/supplypod/extractionpod/pod = source // Handle the pod returning @@ -104,14 +112,14 @@ if (ishuman(M)) var/mob/living/carbon/human/target = M - + // After we remove items, at least give them what they need to live. target.dna.species.give_important_for_life(target) // After pod is sent we start the victim narrative/heal. handleVictimExperience(M) - // This is slightly delayed because of the sleep calls above to handle the narrative. + // This is slightly delayed because of the sleep calls above to handle the narrative. // We don't want to tell the station instantly. var/points_to_check var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) @@ -119,7 +127,7 @@ points_to_check = D.account_balance if(points_to_check >= ransom) D.adjust_money(-ransom) - else + else D.adjust_money(-points_to_check) priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. \ @@ -187,7 +195,7 @@ if (possible_drop_loc.len > 0) var/pod_rand_loc = rand(1, possible_drop_loc.len) - + var/obj/structure/closet/supplypod/return_pod = new() return_pod.bluespace = TRUE return_pod.explosionSize = list(0,0,0,0) @@ -207,7 +215,7 @@ for(var/obj/item/W in victim_belongings) W.forceMove(return_pod) - + M.forceMove(return_pod) M.flash_act() 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 ddc029814ab..81b88ff5c6d 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 @@ -10,18 +10,19 @@ undeletable = 1 tgui_id = "synd_contract" ui_style = "syndicate" - ui_x = 600 + 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] @@ -33,9 +34,9 @@ // Set as the active contract 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) @@ -45,7 +46,7 @@ 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, 0) + user.playsound_local(user, 'sound/effects/contractstartup.ogg', 100, FALSE) traitor_data.contractor_hub = new traitor_data.contractor_hub.create_hub_items() @@ -57,22 +58,24 @@ program_icon_state = "contracts" assigned = TRUE - return 1 + else + 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 user.playsound_local(user, 'sound/machines/uplinkerror.ogg', 50) 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 + 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 + return TRUE if("PRG_contract_abort") var/contract_id = hard_drive.traitor_data.contractor_hub.current_contract.id @@ -81,10 +84,10 @@ 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), + 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 @@ -95,18 +98,19 @@ 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"] @@ -122,9 +126,11 @@ 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 - data = get_header_data() + data += get_header_data() if (traitor_data.contractor_hub.current_contract) data["ongoing_contract"] = TRUE @@ -132,13 +138,20 @@ 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 @@ -159,15 +172,16 @@ "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 if (traitor_data.contractor_hub.current_contract) var/turf/curr = get_turf(user) - var/turf/dropoff_turf + var/turf/dropoff_turf data["current_location"] = "[get_area_name(curr, TRUE)]" - + for (var/turf/content in traitor_data.contractor_hub.current_contract.contract.dropoff.contents) if (isturf(content)) dropoff_turf = content @@ -182,16 +196,8 @@ 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() diff --git a/strings/wanted_message.json b/strings/wanted_message.json new file mode 100644 index 00000000000..73027797695 --- /dev/null +++ b/strings/wanted_message.json @@ -0,0 +1,74 @@ +{ + "basemessage": [ + "Fugitive from the law due to", + "Needs to be interrogated for information about", + "Wanted by The Syndicate for", + "Ransomable to Nanotrasen for", + "Has exploitable information about" + ], + "verb": [ + "murdering", + "killing", + "accidentally destroying", + "destroying", + "knowing information about", + "stealing", + "slipping", + "sabotaging", + "robusting", + "collaborating with", + "being close friends with", + "cloning", + "befriending", + "bombing", + "kidnapping", + "pretending to be", + "seducing", + "ignoring", + "assassinating" + ], + "noun": { + "secret plans": 50, + "the hand teleporter": 50, + "an NT centcomm uniform": 50, + "a supermatter shard": 50, + "internal Syndicate documents": 50, + "experimental Nanotrasen technology": 50, + "bluespace crystals": 50, + "a cult": 50, + "shapeshifting creatures": 50, + "a toolbox": 10, + "a bar of soap": 10, + "lizardmen": 10, + "two million credits": 10, + "a gondola": 10, + "one billion credits": 5, + "research on floor clowns": 5, + "Officer Beepsky": 5, + "clown tears": 5, + "John F Kennedy 2": 5, + "Nanotrasen's swimsuit calendar": 5, + "a suspicious bus": 5, + "administrators": 5, + "a solid gold gondola": 5, + "the anime archive": 5, + "YALPER": 1, + "absolutely nothing": 1, + "Cuban Pete": 1, + "your mother": 1, + "WGW": 1 + }, + "location": { + "on Space Station 13": 50, + "somewhere in deep space": 50, + "on a remote syndicate base": 50, + "in a secure NT facility": 50, + "while on an escape shuttle": 10, + "while infilrating centcomm headquarters": 10, + "deep in the necropolis": 10, + "during a drunken bar fight": 5, + "while stuck in a bathroom": 5, + "in a back alley on Mars": 5, + "on Virgo Orbital": 1 + } +} diff --git a/tgui-next/packages/tgui/components/Box.js b/tgui-next/packages/tgui/components/Box.js index 93b8e6f2fa9..fdeb2d910f3 100644 --- a/tgui-next/packages/tgui/components/Box.js +++ b/tgui-next/packages/tgui/components/Box.js @@ -68,6 +68,7 @@ const styleMapperByPropName = { lineHeight: mapUnitPropTo('line-height'), opacity: mapRawPropTo('opacity'), textAlign: mapRawPropTo('text-align'), + verticalAlign: mapRawPropTo('vertical-align'), // Boolean props inline: mapBooleanPropTo('display', 'inline-block'), bold: mapBooleanPropTo('font-weight', 'bold'), diff --git a/tgui-next/packages/tgui/interfaces/SyndContractor.js b/tgui-next/packages/tgui/interfaces/SyndContractor.js new file mode 100644 index 00000000000..23f152a8319 --- /dev/null +++ b/tgui-next/packages/tgui/interfaces/SyndContractor.js @@ -0,0 +1,382 @@ +import { Box, Button, Section, Dimmer, Table, Icon, NoticeBox, Tabs, Grid, LabeledList } from "../components"; +import { useBackend } from "../backend"; +import { Fragment, Component } from "inferno"; + +export class FakeTerminal extends Component { + constructor(props) { + super(props); + this.timer = null; + this.state = { + currentIndex: 0, + currentDisplay: [], + }; + } + + tick() { + const { props, state } = this; + if (state.currentIndex <= props.allMessages.length) { + this.setState(prevState => { + return ({ + currentIndex: prevState.currentIndex + 1, + }); + }); + const { currentDisplay } = state; + currentDisplay.push(props.allMessages[state.currentIndex]); + } else { + clearTimeout(this.timer); + setTimeout(props.onFinished, props.finishedTimeout); + } + } + + componentDidMount() { + const { + linesPerSecond = 2.5, + } = this.props; + this.timer = setInterval(() => this.tick(), 1000 / linesPerSecond); + } + + componentWillUnmount() { + clearTimeout(this.timer); + } + + render() { + return ( + + {this.state.currentDisplay.map(value => ( + + {value} +
+
+ ))} +
+ ); + } +} + +export const SyndContractor = props => { + const { data, act } = useBackend(props); + + const terminalMessages = [ + "Recording biometric data...", + "Analyzing embedded syndicate info...", + "STATUS CONFIRMED", + "Contacting syndicate database...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Awaiting response...", + "Response received, ack 4851234...", + "CONFIRM ACC " + (Math.round(Math.random() * 20000)), + "Setting up private accounts...", + "CONTRACTOR ACCOUNT CREATED", + "Searching for available contracts...", + "Searching for available contracts...", + "Searching for available contracts...", + "Searching for available contracts...", + "CONTRACTS FOUND", + "WELCOME, AGENT", + ]; + + const infoEntries = [ + "SyndTract v2.0", + "", + "We've identified potentional high-value targets that are", + "currently assigned to your mission area. They are believed", + "to hold valuable information which could be of immediate", + "importance to our organisation.", + "", + "Listed below are all of the contracts available to you. You", + "are to bring the specified target to the designated", + "drop-off, and contact us via this uplink. We will send", + "a specialised extraction unit to put the body into.", + "", + "We want targets alive - but we will sometimes pay slight", + "amounts if they're not, you just won't recieve the shown", + "bonus. You can redeem your payment through this uplink in", + "the form of raw telecrystals, which can be put into your", + "regular Syndicate uplink to purchase whatever you may need.", + "We provide you with these crystals the moment you send the", + "target up to us, which can be collected at anytime through", + "this system.", + "", + "Targets extracted will be ransomed back to the station once", + "their use to us is fulfilled, with us providing you a small", + "percentage cut. You may want to be mindful of them", + "identifying you when they come back. We provide you with", + "a standard contractor loadout, which will help cover your", + "identity.", + ]; + + const errorPane = !!data.error && ( + + + + + + + + + + {data.error} + +
+
+
+ ); + + if (!data.logged_in) { + return ( +
+ +
+ ); + } + + if (data.logged_in && data.first_load) { + return ( + + act('PRG_set_first_load_finished')} /> + + ); + } + + if (data.info_screen) { + return ( + + + + +