mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
The Bomb (#47929)
I spent a ridiculous amount of time on this. Arm order now works like: input disk input nuke code, press E input time, press E press ARM to activate press ARM again to deactivate (with disk) press C to clear code input while ready but not armed
This commit is contained in:
committed by
Aleksej Komarov
parent
e2a3b9dbd9
commit
b4ded1ad00
@@ -94,6 +94,13 @@
|
||||
#define NUKESTATE_CORE_EXPOSED 1
|
||||
#define NUKESTATE_CORE_REMOVED 0
|
||||
|
||||
#define NUKEUI_AWAIT_DISK 0
|
||||
#define NUKEUI_AWAIT_CODE 1
|
||||
#define NUKEUI_AWAIT_TIMER 2
|
||||
#define NUKEUI_AWAIT_ARM 3
|
||||
#define NUKEUI_TIMING 4
|
||||
#define NUKEUI_EXPLODED 5
|
||||
|
||||
#define NUKE_OFF_LOCKED 0
|
||||
#define NUKE_OFF_UNLOCKED 1
|
||||
#define NUKE_ON_TIMING 2
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
ui_style = "nanotrasen"
|
||||
ui_x = 500
|
||||
ui_y = 600
|
||||
ui_x = 350
|
||||
ui_y = 442
|
||||
|
||||
var/timer_set = 90
|
||||
var/default_timer_set = 90
|
||||
var/minimum_timer_set = 90
|
||||
var/maximum_timer_set = 3600
|
||||
|
||||
var/numeric_input = ""
|
||||
var/ui_mode = NUKEUI_AWAIT_DISK
|
||||
|
||||
var/timing = FALSE
|
||||
var/exploding = FALSE
|
||||
var/exploded = FALSE
|
||||
@@ -100,6 +101,8 @@
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
return
|
||||
auth = I
|
||||
update_ui_mode()
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
add_fingerprint(user)
|
||||
return
|
||||
|
||||
@@ -235,6 +238,29 @@
|
||||
var/volume = (get_time_left() <= 20 ? 30 : 5)
|
||||
playsound(loc, 'sound/items/timer.ogg', volume, FALSE)
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/update_ui_mode()
|
||||
if(exploded)
|
||||
ui_mode = NUKEUI_EXPLODED
|
||||
return
|
||||
|
||||
if(!auth)
|
||||
ui_mode = NUKEUI_AWAIT_DISK
|
||||
return
|
||||
|
||||
if(timing)
|
||||
ui_mode = NUKEUI_TIMING
|
||||
return
|
||||
|
||||
if(!safety)
|
||||
ui_mode = NUKEUI_AWAIT_ARM
|
||||
return
|
||||
|
||||
if(!yes_code)
|
||||
ui_mode = NUKEUI_AWAIT_CODE
|
||||
return
|
||||
|
||||
ui_mode = NUKEUI_AWAIT_TIMER
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state=GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
@@ -245,104 +271,127 @@
|
||||
/obj/machinery/nuclearbomb/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["disk_present"] = auth
|
||||
data["code_approved"] = yes_code
|
||||
var/first_status
|
||||
if(auth)
|
||||
if(yes_code)
|
||||
first_status = timing ? "Func/Set" : "Functional"
|
||||
else
|
||||
first_status = "Auth S2."
|
||||
|
||||
var/hidden_code = (ui_mode == NUKEUI_AWAIT_CODE && numeric_input != "ERROR")
|
||||
|
||||
var/current_code = ""
|
||||
if(hidden_code)
|
||||
while(length(current_code) < length(numeric_input))
|
||||
current_code = "[current_code]*"
|
||||
else
|
||||
if(timing)
|
||||
first_status = "Set"
|
||||
else
|
||||
first_status = "Auth S1."
|
||||
var/second_status = exploded ? "Warhead triggered, thanks for flying Nanotrasen" : (safety ? "Safe" : "Engaged")
|
||||
current_code = numeric_input
|
||||
while(length(current_code) < 5)
|
||||
current_code = "[current_code]-"
|
||||
|
||||
var/first_status
|
||||
var/second_status
|
||||
switch(ui_mode)
|
||||
if(NUKEUI_AWAIT_DISK)
|
||||
first_status = "DEVICE LOCKED"
|
||||
if(timing)
|
||||
second_status = "TIME: [get_time_left()]"
|
||||
else
|
||||
second_status = "AWAIT DISK"
|
||||
if(NUKEUI_AWAIT_CODE)
|
||||
first_status = "INPUT CODE"
|
||||
second_status = "CODE: [current_code]"
|
||||
if(NUKEUI_AWAIT_TIMER)
|
||||
first_status = "INPUT TIME"
|
||||
second_status = "TIME: [current_code]"
|
||||
if(NUKEUI_AWAIT_ARM)
|
||||
first_status = "DEVICE READY"
|
||||
second_status = "TIME: [get_time_left()]"
|
||||
if(NUKEUI_TIMING)
|
||||
first_status = "DEVICE ARMED"
|
||||
second_status = "TIME: [get_time_left()]"
|
||||
if(NUKEUI_EXPLODED)
|
||||
first_status = "DEVICE DEPLOYED"
|
||||
second_status = "THANK YOU"
|
||||
|
||||
data["status1"] = first_status
|
||||
data["status2"] = second_status
|
||||
data["anchored"] = anchored
|
||||
data["safety"] = safety
|
||||
data["timing"] = timing
|
||||
data["time_left"] = get_time_left()
|
||||
|
||||
data["timer_set"] = timer_set
|
||||
data["timer_is_not_default"] = timer_set != default_timer_set
|
||||
data["timer_is_not_min"] = timer_set != minimum_timer_set
|
||||
data["timer_is_not_max"] = timer_set != maximum_timer_set
|
||||
|
||||
var/message = "AUTH"
|
||||
if(auth)
|
||||
message = "[numeric_input]"
|
||||
if(yes_code)
|
||||
message = "*****"
|
||||
data["message"] = message
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
playsound(src, "terminal_type", 20, FALSE)
|
||||
switch(action)
|
||||
if("eject_disk")
|
||||
if(auth && auth.loc == src)
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
auth.forceMove(get_turf(src))
|
||||
auth = null
|
||||
. = TRUE
|
||||
if("insert_disk")
|
||||
if(!auth)
|
||||
else
|
||||
var/obj/item/I = usr.is_holding_item_of_type(/obj/item/disk/nuclear)
|
||||
if(I && disk_check(I) && usr.transferItemToLoc(I, src))
|
||||
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
auth = I
|
||||
. = TRUE
|
||||
update_ui_mode()
|
||||
if("keypad")
|
||||
if(auth)
|
||||
var/digit = params["digit"]
|
||||
switch(digit)
|
||||
if("R")
|
||||
if("C")
|
||||
if(auth && ui_mode == NUKEUI_AWAIT_ARM)
|
||||
set_safety()
|
||||
yes_code = FALSE
|
||||
playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE)
|
||||
update_ui_mode()
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
numeric_input = ""
|
||||
yes_code = FALSE
|
||||
. = TRUE
|
||||
if("E")
|
||||
if(numeric_input == r_code)
|
||||
numeric_input = ""
|
||||
yes_code = TRUE
|
||||
. = TRUE
|
||||
else
|
||||
numeric_input = "ERROR"
|
||||
switch(ui_mode)
|
||||
if(NUKEUI_AWAIT_CODE)
|
||||
if(numeric_input == r_code)
|
||||
numeric_input = ""
|
||||
yes_code = TRUE
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
. = TRUE
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
numeric_input = "ERROR"
|
||||
if(NUKEUI_AWAIT_TIMER)
|
||||
var/number_value = text2num(numeric_input)
|
||||
if(number_value)
|
||||
timer_set = CLAMP(number_value, minimum_timer_set, maximum_timer_set)
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
set_safety()
|
||||
. = TRUE
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
update_ui_mode()
|
||||
if("0","1","2","3","4","5","6","7","8","9")
|
||||
if(numeric_input != "ERROR")
|
||||
numeric_input += digit
|
||||
if(length(numeric_input) > 5)
|
||||
numeric_input = "ERROR"
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
. = TRUE
|
||||
if("timer")
|
||||
if(auth && yes_code)
|
||||
var/change = params["change"]
|
||||
if(change == "reset")
|
||||
timer_set = default_timer_set
|
||||
else if(change == "decrease")
|
||||
timer_set = max(minimum_timer_set, timer_set - 10)
|
||||
else if(change == "increase")
|
||||
timer_set = min(maximum_timer_set, timer_set + 10)
|
||||
else if(change == "input")
|
||||
var/user_input = input(usr, "Set time to detonation.", name) as null|num
|
||||
if(!user_input)
|
||||
return
|
||||
var/N = text2num(user_input)
|
||||
if(!N)
|
||||
return
|
||||
timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set)
|
||||
. = TRUE
|
||||
if("safety")
|
||||
if(auth && yes_code && !exploded)
|
||||
set_safety()
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
if("arm")
|
||||
if(auth && yes_code && !safety && !exploded)
|
||||
playsound(src, 'sound/machines/nuke/confirm_beep.ogg', 50, FALSE)
|
||||
set_active()
|
||||
update_ui_mode()
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
if("anchor")
|
||||
if(auth && yes_code)
|
||||
playsound(src, 'sound/machines/nuke/general_beep.ogg', 50, FALSE)
|
||||
set_anchor()
|
||||
if("toggle_timer")
|
||||
if(auth && yes_code && !safety && !exploded)
|
||||
set_active()
|
||||
|
||||
else
|
||||
playsound(src, 'sound/machines/nuke/angry_beep.ogg', 50, FALSE)
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/set_anchor()
|
||||
if(isinspace() && !anchored)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,147 @@
|
||||
import { act } from '../byond';
|
||||
import { Box, Button, Grid, Flex, Icon } from '../components';
|
||||
import { classes } from 'common/react';
|
||||
|
||||
// This ui is so many manual overrides and !important tags
|
||||
// and hand made width sets that changing pretty much anything
|
||||
// is going to require a lot of tweaking it get it looking correct again
|
||||
// I'm sorry, but it looks bangin
|
||||
const NukeKeypad = props => {
|
||||
const { state } = props;
|
||||
const { config, data } = state;
|
||||
const { ref } = config;
|
||||
const keypadKeys = [
|
||||
["1", "4", "7", "C"],
|
||||
["2", "5", "8", "0"],
|
||||
["3", "6", "9", "E"],
|
||||
];
|
||||
return (
|
||||
<Box
|
||||
width="185px"
|
||||
>
|
||||
<Grid width="1px">
|
||||
{keypadKeys.map(keyColumn => (
|
||||
<Grid.Column key={keyColumn[0]}>
|
||||
{keyColumn.map(key => (
|
||||
<Button
|
||||
fluid
|
||||
bold
|
||||
key={key}
|
||||
mb={1}
|
||||
content={key}
|
||||
textAlign="center"
|
||||
fontSize="40px"
|
||||
lineHeight="50px"
|
||||
width="55px"
|
||||
className={classes([
|
||||
"NuclearBomb__Button",
|
||||
"NuclearBomb__Button--keypad",
|
||||
"NuclearBomb__Button--" + key,
|
||||
])}
|
||||
onClick={() => act(ref, "keypad", {digit: key})}
|
||||
/>
|
||||
))}
|
||||
</Grid.Column>
|
||||
))}
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const NuclearStatusPanel = props => {
|
||||
const { state } = props;
|
||||
const { config, data } = state;
|
||||
const { ref } = config;
|
||||
};
|
||||
|
||||
export const NuclearBomb = props => {
|
||||
const { state } = props;
|
||||
const { config, data } = state;
|
||||
const { ref } = config;
|
||||
const {
|
||||
anchored,
|
||||
disk_present,
|
||||
status1,
|
||||
status2,
|
||||
} = data;
|
||||
return (
|
||||
<Box
|
||||
m={1}
|
||||
>
|
||||
<Box
|
||||
mb={1}
|
||||
className="NuclearBomb__displayBox"
|
||||
>
|
||||
{status1}
|
||||
</Box>
|
||||
<Flex mb={1.5}>
|
||||
<Flex.Item grow={1}>
|
||||
<Box
|
||||
className="NuclearBomb__displayBox"
|
||||
>
|
||||
{status2}
|
||||
</Box>
|
||||
</Flex.Item>
|
||||
<Flex.Item>
|
||||
<Button
|
||||
icon="eject"
|
||||
fontSize="24px"
|
||||
lineHeight="23px"
|
||||
textAlign="center"
|
||||
width="43px"
|
||||
ml={1}
|
||||
mr="3px"
|
||||
mt="3px"
|
||||
className="NuclearBomb__Button NuclearBomb__Button--keypad"
|
||||
onClick={() => act(ref, "eject_disk")}
|
||||
/>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<Flex ml="3px">
|
||||
<Flex.Item>
|
||||
<NukeKeypad state={state} />
|
||||
</Flex.Item>
|
||||
<Flex.Item ml={1} width="129px">
|
||||
<Box>
|
||||
<Button
|
||||
fluid
|
||||
bold
|
||||
content="ARM"
|
||||
textAlign="center"
|
||||
fontSize="28px"
|
||||
lineHeight="32px"
|
||||
mb={1}
|
||||
className="NuclearBomb__Button NuclearBomb__Button--C"
|
||||
onClick={() => act(ref, "arm")}
|
||||
/>
|
||||
<Button
|
||||
fluid
|
||||
bold
|
||||
content="ANCHOR"
|
||||
textAlign="center"
|
||||
fontSize="28px"
|
||||
lineHeight="32px"
|
||||
className="NuclearBomb__Button NuclearBomb__Button--E"
|
||||
onClick={() => act(ref, "anchor")}
|
||||
/>
|
||||
<Box
|
||||
width="100%"
|
||||
textAlign="center"
|
||||
color="#9C9987"
|
||||
fontSize="80px"
|
||||
>
|
||||
<Icon
|
||||
name="radiation"
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
width="100%"
|
||||
height="80px"
|
||||
className="NuclearBomb__NTIcon"
|
||||
/>
|
||||
</Box>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -44,6 +44,7 @@ import { NtosMain } from './interfaces/NtosMain';
|
||||
import { NtosNetDownloader } from './interfaces/NtosNetDownloader';
|
||||
import { NtosSupermatterMonitor } from './interfaces/NtosSupermatterMonitor';
|
||||
import { NtosWrapper } from './interfaces/NtosWrapper';
|
||||
import { NuclearBomb } from './interfaces/NuclearBomb';
|
||||
import { OperatingComputer } from './interfaces/OperatingComputer';
|
||||
import { OreRedemptionMachine } from './interfaces/OreRedemptionMachine';
|
||||
import { PersonalCrafting } from './interfaces/PersonalCrafting';
|
||||
@@ -264,6 +265,11 @@ const ROUTES = {
|
||||
scrollable: true,
|
||||
theme: 'ntos',
|
||||
},
|
||||
nuclear_bomb: {
|
||||
component: () => NuclearBomb,
|
||||
scrollable: false,
|
||||
theme: 'retro',
|
||||
},
|
||||
ore_redemption_machine: {
|
||||
component: () => OreRedemptionMachine,
|
||||
scrollable: true,
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
@use '../base.scss';
|
||||
@use '../colors.scss';
|
||||
@use '../functions.scss' as *;
|
||||
|
||||
$color-danger: colors.bg(colors.$red) !default;
|
||||
$color-caution: colors.bg(colors.$yellow) !default;
|
||||
|
||||
$background-beige: #E8E4C9;
|
||||
|
||||
.NuclearBomb__displayBox {
|
||||
background-color: #002003;
|
||||
border: 4px inset $background-beige;
|
||||
color: #03e017;
|
||||
font-size: 24px;
|
||||
font-family: monospace;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.NuclearBomb__Button--keypad {
|
||||
background-color: $background-beige;
|
||||
border-color: $background-beige;
|
||||
&:hover {
|
||||
background-color: lighten($background-beige, 15%) !important;
|
||||
border-color: lighten($background-beige, 15%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.NuclearBomb__Button--1 {
|
||||
background-color: #D3CFB7 !important;
|
||||
border-color:#D3CFB7 !important;
|
||||
color: #A9A692 !important;
|
||||
}
|
||||
|
||||
.NuclearBomb__Button--E {
|
||||
background-color: $color-caution !important;
|
||||
border-color: $color-caution !important;
|
||||
&:hover {
|
||||
background-color: lighten($color-caution, 15%) !important;
|
||||
border-color: lighten($color-caution, 15%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.NuclearBomb__Button--C {
|
||||
background-color: $color-danger !important;
|
||||
border-color: $color-danger !important;
|
||||
&:hover {
|
||||
background-color: lighten($color-danger, 15%) !important;
|
||||
border-color: lighten($color-danger, 15%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.NuclearBomb__NTIcon {
|
||||
background-image: url('../assets/bg-nanotrasen.svg');
|
||||
background-size: 70%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
@include meta.load-css('./components/NoticeBox.scss');
|
||||
@include meta.load-css('./components/NtosHeader.scss');
|
||||
@include meta.load-css('./components/NtosWrapper.scss');
|
||||
@include meta.load-css('./components/NuclearBomb.scss');
|
||||
@include meta.load-css('./components/NumberInput.scss');
|
||||
@include meta.load-css('./components/ProgressBar.scss');
|
||||
@include meta.load-css('./components/Section.scss');
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
@use 'sass:color';
|
||||
@use 'sass:meta';
|
||||
|
||||
@use '../colors.scss' with (
|
||||
$primary: #000000,
|
||||
$fg-map-keys: (),
|
||||
$bg-map-keys: (),
|
||||
);
|
||||
@use '../base.scss' with (
|
||||
$color-bg: #E8E4C9,
|
||||
$color-bg-grad-spread: 0%,
|
||||
$border-radius: 0px,
|
||||
);
|
||||
|
||||
// A fat warning to anyone who wants to use this: this only half works.
|
||||
// It was made almost purely for the nuke ui, and requires a good amount of manual hacks to get it working as intended.
|
||||
.theme-retro {
|
||||
// Atomic classes
|
||||
@include meta.load-css('../atomic/color.scss');
|
||||
|
||||
// Components
|
||||
@include meta.load-css('../components/Button.scss', $with: (
|
||||
'color-default': #E8E4C9,
|
||||
'color-disabled': #363636,
|
||||
'color-selected': #9d0808,
|
||||
'color-caution': #be6209,
|
||||
'color-danger': #9a9d00,
|
||||
));
|
||||
@include meta.load-css('../components/Layout.scss');
|
||||
@include meta.load-css('../components/ProgressBar.scss', $with: (
|
||||
'color-background': rgba(0, 0, 0, 0.5),
|
||||
));
|
||||
@include meta.load-css('../components/Section.scss');
|
||||
@include meta.load-css('../components/TitleBar.scss', $with: (
|
||||
'color-background': #585337,
|
||||
));
|
||||
|
||||
.Button {
|
||||
font-family: monospace;
|
||||
color: #161613;
|
||||
border-width: 8px;
|
||||
border-style: outset;
|
||||
border-color: #E8E4C9;
|
||||
outline: 3px solid #161613;
|
||||
}
|
||||
|
||||
.Layout__content {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ module.exports = (env = {}, argv) => {
|
||||
path.resolve(__dirname, './styles/main.scss'),
|
||||
path.resolve(__dirname, './styles/themes/ntos.scss'),
|
||||
path.resolve(__dirname, './styles/themes/syndicate.scss'),
|
||||
path.resolve(__dirname, './styles/themes/retro.scss'),
|
||||
path.resolve(__dirname, './index.js'),
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user