Contractor Uplink tgui-next overhaul (#48453)

* tgui next contractor interface

work

cleanup

more work

getting close now

final

build

more stuff for wanted messages

rebuild

spelling

* fixes

* rebuild

* fix

* disable button when contract not active or extraction enroute, disable limited when depleted
This commit is contained in:
Rob Bailey
2020-01-03 11:29:38 +01:00
committed by skoglol
parent de6f45492c
commit cbad6e4de5
11 changed files with 552 additions and 70 deletions
+1
View File
@@ -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
+1
View File
@@ -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)))
@@ -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
@@ -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, "<span class='notice'>Your purchase materializes into your hands!</span>")
else
@@ -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()
@@ -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()
+74
View File
@@ -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
}
}
@@ -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'),
@@ -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 (
<Box m={1}>
{this.state.currentDisplay.map(value => (
<Fragment key={value}>
{value}
<br />
</Fragment>
))}
</Box>
);
}
}
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 && (
<Dimmer>
<Box
backgroundColor="red"
minHeight="150px"
mt={30}
ml={15}
mr={15}>
<Table m={1}>
<Table.Row>
<Table.Cell collapsing fontSize="100px">
<Icon
name="exclamation-triangle"
mt={4}
ml={2} />
</Table.Cell>
<Table.Cell
verticalAlign="top"
textAlign="center">
<Box
m={1}
textAlign="left"
width="100%"
minHeight="110px">
{data.error}
</Box>
<Button
content="Dismiss"
onClick={() => act('PRG_clear_error')} />
</Table.Cell>
</Table.Row>
</Table>
</Box>
</Dimmer>
);
if (!data.logged_in) {
return (
<Section minHeight="525px">
<Box
width="100%"
textAlign="center">
<Button
content="REGISTER USER"
color="transparent"
onClick={() => act('PRG_login')} />
</Box>
{!!data.error && (
<NoticeBox>
{data.error}
</NoticeBox>
)}
</Section>
);
}
if (data.logged_in && data.first_load) {
return (
<Box
backgroundColor="rgba(0, 0, 0, 0.8)"
minHeight="525px">
<FakeTerminal
allMessages={terminalMessages}
finishedTimeout={3000}
onFinished={() => act('PRG_set_first_load_finished')} />
</Box>
);
}
if (data.info_screen) {
return (
<Fragment>
<Box
backgroundColor="rgba(0, 0, 0, 0.8)"
minHeight="500px">
<FakeTerminal
allMessages={infoEntries}
linesPerSecond={10} />
</Box>
<Button
fluid
content="CONTINUE"
color="transparent"
textAlign="center"
onClick={() => act('PRG_toggle_info')} />
</Fragment>
);
}
return (
<Fragment>
{errorPane}
<SyndPane state={props.state} />
</Fragment>
);
};
export const StatusPane = props => {
const { act, data } = useBackend(props);
return (
<Section
title={(
<Fragment>
Contractor Status
<Button
content="View Information Again"
color="transparent"
mb={0}
ml={1}
onClick={() => act('PRG_toggle_info')} />
</Fragment>
)}
buttons={(
<Box bold mr={1}>
{data.contract_rep} Rep
</Box>
)}>
<Grid>
<Grid.Column size={0.85}>
<LabeledList>
<LabeledList.Item
label="TC Availible"
buttons={(
<Button
content="Claim"
disabled={data.redeemable_tc <= 0}
onClick={() => act('PRG_redeem_TC')} />
)}>
{data.redeemable_tc}
</LabeledList.Item>
<LabeledList.Item label="TC Earned">
{data.earned_tc}
</LabeledList.Item>
</LabeledList>
</Grid.Column>
<Grid.Column>
<LabeledList>
<LabeledList.Item label="Contracts Completed">
{data.contracts_completed}
</LabeledList.Item>
<LabeledList.Item label="Current Status">
ACTIVE
</LabeledList.Item>
</LabeledList>
</Grid.Column>
</Grid>
</Section>
);
};
export const SyndPane = props => {
const { act, data } = useBackend(props);
const contractor_hub_items = data.contractor_hub_items || [];
const contracts = data.contracts || [];
return (
<Fragment>
<StatusPane state={props.state} />
<Tabs>
<Tabs.Tab label="Contracts">
<Section
title="Availible Contracts"
buttons={(
<Button
content="Call Extraction"
disabled={!data.ongoing_contract || data.extraction_enroute}
onClick={() => act('PRG_call_extraction')} />
)}>
{contracts.map(contract => {
const active = (contract.status > 1);
if (contract.status >= 5) {
return;
}
return (
<Section
key={contract.target}
title={`${contract.target} (${contract.target_rank})`}
level={active ? 1 : 2}
buttons={(
<Fragment>
<Box
inline
bold
mr={1}>
{contract.payout} (+{contract.payout_bonus}) TC
</Box>
<Button
content={active ? "Abort" : "Accept"}
disabled={contract.extraction_enroute}
color={active && "bad"}
onClick={() => act(
'PRG_contract' + (active ? '_abort' : '-accept'),
{
contract_id: contract.id,
})} />
</Fragment>
)}>
<Grid>
<Grid.Column>
{contract.message}
</Grid.Column>
<Grid.Column size={0.5}>
<Box
bold
mb={1}>
Dropoff Location:
</Box>
<Box>
{contract.dropoff}
</Box>
</Grid.Column>
</Grid>
</Section>
);
})}
</Section>
</Tabs.Tab>
<Tabs.Tab label="Uplink">
<Section>
{contractor_hub_items.map(item => {
const repInfo = item.cost ? (item.cost + ' Rep') : 'FREE';
const limited = (item.limited !== -1);
return (
<Section
key={item.name}
title={item.name + ' - ' + repInfo}
level={2}
buttons={(
<Fragment>
{limited && (
<Box
inline
bold
mr={1}>
{item.limited} remaining
</Box>
)}
<Button
content="Purchase"
disabled={data.redeemable_tc < item.cost
|| (limited && item.limited <= 0)}
onClick={() => act('buy_hub', {
item: item.name,
cost: item.cost,
})} />
</Fragment>
)}>
<Table>
<Table.Row>
<Table.Cell>
<Icon
fontSize="60px"
name={item.item_icon} />
</Table.Cell>
<Table.Cell
verticalAlign="top">
{item.desc}
</Table.Cell>
</Table.Row>
</Table>
</Section>
);
})}
</Section>
</Tabs.Tab>
</Tabs>
</Fragment>
);
};
File diff suppressed because one or more lines are too long
+7
View File
@@ -97,6 +97,7 @@ import { Uplink } from './interfaces/Uplink';
import { VaultController } from './interfaces/VaultController';
import { Vending } from './interfaces/Vending';
import { Wires } from './interfaces/Wires';
import { SyndContractor } from './interfaces/SyndContractor';
const ROUTES = {
achievements: {
@@ -490,6 +491,12 @@ const ROUTES = {
component: () => SuitStorageUnit,
scrollable: false,
},
synd_contract: {
component: () => SyndContractor,
wrapper: () => NtosWrapper,
scrollable: true,
theme: 'syndicate',
},
tanks: {
component: () => Tank,
scrollable: false,