mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 01:49:19 +00:00
TGUI; actually fixes station announcer
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
19
tgui/packages/common/exhaustive.ts
Normal file
19
tgui/packages/common/exhaustive.ts
Normal 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}`);
|
||||
};
|
||||
251
tgui/packages/tgui/interfaces/StationTraitsPanel.tsx
Normal file
251
tgui/packages/tgui/interfaces/StationTraitsPanel.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user