TGUI; actually fixes station announcer

This commit is contained in:
Putnam3145
2022-08-07 17:17:58 -07:00
parent 0897aac2c8
commit e1c822cbd8
9 changed files with 279 additions and 9 deletions

View File

@@ -30,4 +30,4 @@
/datum/game_mode/extended/announced/send_intercept(report = 0)
if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart
return ..()
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport")
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", SSstation.announcer.get_rand_report_sound())

View File

@@ -278,7 +278,7 @@
/datum/game_mode/proc/send_intercept()
if(flipseclevel && !(config_tag == "extended"))//CIT CHANGE - lets the security level be flipped roundstart
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport")
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", SSstation.announcer.get_rand_report_sound())
return
var/intercepttext = "<b><i>Central Command Status Summary</i></b><hr>"
intercepttext += "<b>Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \

View File

@@ -244,7 +244,7 @@
nuke_request(reason, usr)
to_chat(usr, span_notice("Request sent."))
usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY)
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", "commandreport")
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", SSstation.announcer.get_rand_report_sound())
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("restoreBackupRoutingData")

View File

@@ -560,7 +560,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/announce_command_report = TRUE
switch(confirm)
if("Yes")
priority_announce(input, null, "commandreport")
priority_announce(input, null, SSstation.announcer.get_rand_report_sound())
announce_command_report = FALSE
if("Cancel")
return

View File

@@ -352,7 +352,7 @@
if(is_station_level(W.z) && !istype(get_area(W), /area/command) && !istype(get_area(W), /area/commons) && !istype(get_area(W), /area/service) && !istype(get_area(W), /area/command/heads_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(holder)] activated Egalitarian Station mode")
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, "commandreport")
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, SSstation.announcer.get_rand_report_sound())
if("ancap")
if(!is_funmin)
return
@@ -360,9 +360,9 @@
SSeconomy.full_ancap = !SSeconomy.full_ancap
message_admins("[key_name_admin(holder)] toggled Anarcho-capitalist mode")
if(SSeconomy.full_ancap)
priority_announce("The NAP is now in full effect.", null, "commandreport")
priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound())
else
priority_announce("The NAP has been revoked.", null, "commandreport")
priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound())
if("blackout")
if(!is_funmin)
return

View File

@@ -37,7 +37,7 @@
// if(PIRATES_DUTCHMAN)
// ship_name = "Flying Dutchman"
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", "commandreport")
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
payoff = max(payoff_min, FLOOR(D.account_balance * 0.80, 1000))

View File

@@ -12,7 +12,7 @@
var/report_message = "Complete this goal."
/datum/station_goal/proc/send_report()
priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", "commandreport")
priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", SSstation.announcer.get_rand_report_sound())
print_command_report(get_report(),"Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", announce=FALSE)
on_report()

View File

@@ -0,0 +1,19 @@
/**
* Throws an error such that a non-exhaustive check will error at compile time
* when using TypeScript, rather than at runtime.
*
* For example:
* enum Color { Red, Green, Blue }
* switch (color) {
* case Color.Red:
* return "red";
* case Color.Green:
* return "green";
* default:
* // This will error at compile time that we forgot blue.
* exhaustiveCheck(color);
* }
*/
export const exhaustiveCheck = (input: never) => {
throw new Error(`Unhandled case: ${input}`);
};

View File

@@ -0,0 +1,251 @@
import { filterMap } from 'common/collections';
import { exhaustiveCheck } from 'common/exhaustive';
import { BooleanLike } from 'common/react';
import { useBackend, useLocalState } from '../backend';
import { Box, Button, Divider, Dropdown, Stack, Tabs } from '../components';
import { Window } from '../layouts';
type CurrentStationTrait = {
can_revert: BooleanLike;
name: string;
ref: string;
};
type ValidStationTrait = {
name: string;
path: string;
};
type StationTraitsData = {
current_traits: CurrentStationTrait[];
future_station_traits?: ValidStationTrait[];
too_late_to_revert: BooleanLike;
valid_station_traits: ValidStationTrait[];
};
enum Tab {
SetupFutureStationTraits,
ViewStationTraits,
}
const FutureStationTraitsPage = (props, context) => {
const { act, data } = useBackend<StationTraitsData>(context);
const { future_station_traits } = data;
const [selectedTrait, setSelectedTrait] = useLocalState<string | null>(
context,
'selectedFutureTrait',
null
);
const traitsByName = Object.fromEntries(
data.valid_station_traits.map((trait) => {
return [trait.name, trait.path];
})
);
const traitNames = Object.keys(traitsByName);
traitNames.sort();
return (
<Box>
<Stack fill>
<Stack.Item grow>
<Dropdown
displayText={!selectedTrait && 'Select trait to add...'}
onSelected={setSelectedTrait}
options={traitNames}
selected={selectedTrait}
width="100%"
/>
</Stack.Item>
<Stack.Item>
<Button
color="green"
icon="plus"
onClick={() => {
if (!selectedTrait) {
return;
}
const selectedPath = traitsByName[selectedTrait];
let newStationTraits = [selectedPath];
if (future_station_traits) {
const selectedTraitPaths = future_station_traits.map(
(trait) => trait.path
);
if (selectedTraitPaths.indexOf(selectedPath) !== -1) {
return;
}
newStationTraits = newStationTraits.concat(
...selectedTraitPaths
);
}
act('setup_future_traits', {
station_traits: newStationTraits,
});
}}>
Add
</Button>
</Stack.Item>
</Stack>
<Divider />
{Array.isArray(future_station_traits) ? (
future_station_traits.length > 0 ? (
<Stack vertical fill>
{future_station_traits.map((trait) => (
<Stack.Item key={trait.path}>
<Stack fill>
<Stack.Item grow>{trait.name}</Stack.Item>
<Stack.Item>
<Button
color="red"
icon="times"
onClick={() => {
act('setup_future_traits', {
station_traits: filterMap(
future_station_traits,
(otherTrait) => {
if (otherTrait.path === trait.path) {
return undefined;
} else {
return otherTrait.path;
}
}
),
});
}}>
Delete
</Button>
</Stack.Item>
</Stack>
</Stack.Item>
))}
</Stack>
) : (
<>
<Box>No station traits will run next round.</Box>
<Box>
<Button
color="red"
icon="times"
tooltip="The next round will roll station traits randomly, just like normal"
onClick={() => act('clear_future_traits')}>
Run Station Traits Normally
</Button>
</Box>
</>
)
) : (
<>
<Box>No future station traits are planned.</Box>
<Box>
<Button
color="red"
icon="times"
onClick={() =>
act('setup_future_traits', {
station_traits: [],
})}>
Prevent station traits from running next round
</Button>
</Box>
</>
)}
</Box>
);
};
const ViewStationTraitsPage = (props, context) => {
const { act, data } = useBackend<StationTraitsData>(context);
return data.current_traits.length > 0 ? (
<Stack vertical fill>
{data.current_traits.map((stationTrait) => (
<Stack.Item key={stationTrait.ref}>
<Stack fill>
<Stack.Item grow>{stationTrait.name}</Stack.Item>
<Stack.Item>
<Button.Confirm
content="Revert"
color="red"
disabled={data.too_late_to_revert || !stationTrait.can_revert}
tooltip={
(!stationTrait.can_revert
&& 'This trait is not revertable.')
|| (data.too_late_to_revert
&& "It's too late to revert station traits, the round has already started.")
}
icon="times"
onClick={() =>
act('revert', {
ref: stationTrait.ref,
})}
/>
</Stack.Item>
</Stack>
</Stack.Item>
))}
</Stack>
) : (
<Box>There are no active station traits.</Box>
);
};
export const StationTraitsPanel = (props, context) => {
const [currentTab, setCurrentTab] = useLocalState(
context,
'station_traits_tab',
Tab.ViewStationTraits
);
let currentPage;
switch (currentTab) {
case Tab.SetupFutureStationTraits:
currentPage = <FutureStationTraitsPage />;
break;
case Tab.ViewStationTraits:
currentPage = <ViewStationTraitsPage />;
break;
default:
exhaustiveCheck(currentTab);
}
return (
<Window title="Modify Station Traits" height={500} width={500}>
<Window.Content scrollable>
<Tabs>
<Tabs.Tab
icon="eye"
selected={currentTab === Tab.ViewStationTraits}
onClick={() => setCurrentTab(Tab.ViewStationTraits)}>
View
</Tabs.Tab>
<Tabs.Tab
icon="edit"
selected={currentTab === Tab.SetupFutureStationTraits}
onClick={() => setCurrentTab(Tab.SetupFutureStationTraits)}>
Edit
</Tabs.Tab>
</Tabs>
<Divider />
{currentPage}
</Window.Content>
</Window>
);
};