[MIRROR] selective belly import (#11530)

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-08-29 15:29:58 -07:00
committed by GitHub
parent 8a4c185fb4
commit 87b3497230
10 changed files with 85 additions and 41 deletions

View File

@@ -350,6 +350,12 @@ SUBSYSTEM_DEF(garbage)
/// Datums passed to this will be given a chance to clean up references to allow the GC to collect them.
/proc/qdel(datum/to_delete, force = FALSE)
if(!istype(to_delete))
if(isnull(to_delete))
return
else if(islist(to_delete))
stack_trace("Lists should not be directly passed to qdel! You likely want either list.Cut(), QDEL_LIST(list), QDEL_LIST_ASSOC(list), or QDEL_LIST_ASSOC_VAL(list)")
else if(to_delete != world)
stack_trace("Tried to qdel possibly invalid value: [to_delete]")
del(to_delete)
return

View File

@@ -52,6 +52,8 @@
data["show_station_news"] = GLOB.news_data.station_newspaper
data["new_station_news"] = client.prefs.lastlorenews != GLOB.news_data.newsindex
data["new_changelog"] = read_preference(/datum/preference/text/lastchangelog) == GLOB.changelog_hash
data["can_start_now"] = client.is_localhost() && check_rights_for(client, R_SERVER)
data["immediate_start"] = SSticker.start_immediately || (!isnull(SSticker.timeLeft) && SSticker.timeLeft < 0)
return data
@@ -165,3 +167,10 @@
playsound_local(ui.user, get_sfx("keyboard"), vol = 20)
return TRUE
if("start_immediately")
if(!ui.user.client.is_localhost() || !check_rights_for(ui.user.client, R_SERVER))
return FALSE
SSticker.start_immediately = TRUE
if(SSticker.current_state == GAME_STATE_STARTUP)
to_chat(usr, span_admin("The server is still setting up, but the round will be started as soon as possible."))

View File

@@ -88,7 +88,7 @@
/datum/tgui_alert/Destroy(force, ...)
SStgui.close_uis(src)
state = null
QDEL_NULL(buttons)
buttons?.Cut()
. = ..()
/**

View File

@@ -26,7 +26,8 @@
return null
if(!user.read_preference(/datum/preference/toggle/tgui_input_mode))
return input(user, message, title) as null|anything in items
var/our_input = input(user, message, title) as null|anything in items
return our_input ? list(our_input) : null
var/datum/tgui_checkbox_input/input = new(user, message, title, items, min_checked, max_checked, timeout, ui_state)
input.tgui_interact(user)
input.wait()
@@ -73,7 +74,7 @@
/datum/tgui_checkbox_input/Destroy(force)
SStgui.close_uis(src)
state = null
QDEL_NULL(items)
items?.Cut()
return ..()
@@ -115,7 +116,7 @@
return data
/datum/tgui_checkbox_input/tgui_act(action, list/params)
/datum/tgui_checkbox_input/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
. = ..()
if (.)
return
@@ -124,7 +125,11 @@
if("submit")
var/list/selections = params["entry"]
if(length(selections) >= min_checked && length(selections) <= max_checked)
set_choices(selections)
var/list/valid_selections = list()
for(var/raw_entry in selections)
if(raw_entry in items)
valid_selections += raw_entry
set_choices(valid_selections)
closed = TRUE
SStgui.close_uis(src)
return TRUE

View File

@@ -97,7 +97,8 @@
/datum/tgui_list_input/Destroy(force)
SStgui.close_uis(src)
state = null
QDEL_NULL(items)
items?.Cut()
items_map?.Cut()
return ..()
/**

View File

@@ -1,14 +1,14 @@
#define IMPORT_ALL_BELLIES "Import all bellies from VRDB"
#define IMPORT_ONE_BELLY "Import one belly from VRDB"
#define IMPORT_ONE_BELLY "Import some bellies from VRDB"
#define IMPORT_SOULCATCHER "Import Soulcatcher from VRDB"
/datum/vore_look/proc/import_belly(mob/host)
var/panel_choice = tgui_input_list(host, "Belly Import", "Pick an option", list(IMPORT_ALL_BELLIES, IMPORT_ONE_BELLY, IMPORT_SOULCATCHER))
if(!panel_choice) return
var/pickOne = FALSE
var/pickSome = FALSE
if(panel_choice == IMPORT_ONE_BELLY)
pickOne = TRUE
pickSome = TRUE
var/input_file = input(host,"Please choose a valid VRDB file to import from.","Belly Import") as file
var/input_data
try
@@ -41,16 +41,22 @@
var/list/updated = list()
for(var/list/raw_list in input_data)
if(length(valid_names) >= BELLIES_MAX) break
if(!islist(raw_list)) continue
if(!istext(raw_list["name"])) continue
if(length(raw_list["name"]) > BELLIES_NAME_MAX || length(raw_list["name"]) < BELLIES_NAME_MIN) continue
if(raw_list["name"] in valid_names) continue
if(length(valid_names) >= BELLIES_MAX)
break
if(!islist(raw_list))
continue
if(!istext(raw_list["name"]))
continue
if(length(raw_list["name"]) > BELLIES_NAME_MAX || length(raw_list["name"]) < BELLIES_NAME_MIN)
continue
if(raw_list["name"] in valid_names)
continue
for(var/obj/belly/B in host.vore_organs)
if(lowertext(B.name) == lowertext(raw_list["name"]))
updated += raw_list["name"]
break
if(!pickOne && length(host.vore_organs)+length(valid_names)-length(updated) >= BELLIES_MAX) continue
if(!pickSome && length(host.vore_organs)+length(valid_names)-length(updated) >= BELLIES_MAX)
continue
valid_names += raw_list["name"]
valid_lists += list(raw_list)
@@ -58,18 +64,29 @@
tgui_alert_async(host, "The supplied VRDB file does not contain any valid bellies.", "Error!")
return FALSE
if(pickOne)
var/picked = tgui_input_list(host, "Belly Import", "Which belly?", valid_names)
if(!picked) return
if(pickSome)
var/list/picked = tgui_input_checkboxes(host, "Belly Import", "Which bellies?", valid_names)
if(!LAZYLEN(picked))
return
var/list/trimmed_names = list()
var/list/trimmed_lists = list()
var/list/trimmed_update = list()
for(var/B in valid_lists)
if(lowertext(picked) == lowertext(B["name"]))
valid_names = list(picked)
valid_lists = list(B)
break
if(picked in updated)
updated = list(picked)
else
updated = list()
var/belly_to_check = B["name"]
if(belly_to_check in picked)
if(belly_to_check in updated)
trimmed_update += belly_to_check
if(length(host.vore_organs)+length(trimmed_names)-length(trimmed_update) >= BELLIES_MAX)
break
trimmed_names += belly_to_check
trimmed_lists += list(B)
valid_names = trimmed_names
valid_lists = trimmed_lists
updated = trimmed_update
if(length(valid_names) == 0)
return FALSE
var/list/alert_msg = list()
if(length(valid_names)-length(updated) > 0)

View File

@@ -61,10 +61,6 @@
allowed_spawns = list("Arrivals Shuttle","Gateway","Cryogenic Storage","Cyborg Storage")
/datum/map/virgo_minitest/New()
..()
SSticker.start_immediately = TRUE
/datum/map_z_level/minitest/station
z = Z_LEVEL_MAIN_VIRGO_TESTING
name = "Station Level"

View File

@@ -12,7 +12,6 @@ import {
Tooltip,
} from 'tgui-core/components';
import { createSearch, decodeHtmlEntities } from 'tgui-core/string';
import { InputButtons } from './common/InputButtons';
import { Loader } from './common/Loader';
@@ -39,7 +38,7 @@ export const CheckboxInput = (props) => {
const [selections, setSelections] = useState<string[]>([]);
const [searchQuery, setSearchQuery] = useState<string>('');
const [searchQuery, setSearchQuery] = useState('');
const search = createSearch(searchQuery, (item: string) => item);
const toDisplay = items.filter(search);
@@ -55,7 +54,7 @@ export const CheckboxInput = (props) => {
<Window title={title} width={425} height={300}>
{!!timeout && <Loader value={timeout} />}
<Window.Content>
<Stack fill vertical>
<Stack fill vertical g={0}>
<Stack.Item>
<NoticeBox info textAlign="center">
{decodeHtmlEntities(message)}{' '}
@@ -63,7 +62,7 @@ export const CheckboxInput = (props) => {
{max_checked < 50 && ` (Max: ${max_checked})`}
</NoticeBox>
</Stack.Item>
<Stack.Item grow mt={0}>
<Stack.Item grow>
<Section fill scrollable>
<Table>
{toDisplay.map((item, index) => (
@@ -86,21 +85,17 @@ export const CheckboxInput = (props) => {
</Table>
</Section>
</Stack.Item>
<Stack m={1} mb={0}>
<Stack m={1}>
<Stack.Item>
<Tooltip content="Search" position="bottom">
<Icon name="search" mt={0.5} />
</Tooltip>
</Stack.Item>
<Stack.Item grow>
<Input
fluid
value={searchQuery}
onChange={(value: string) => setSearchQuery(value)}
/>
<Input fluid value={searchQuery} onChange={setSearchQuery} />
</Stack.Item>
</Stack>
<Stack.Item mt={0.7}>
<Stack.Item>
<Section>
<InputButtons input={selections} />
</Section>

View File

@@ -24,6 +24,8 @@ export const LobbyButtons = (props: {
show_station_news,
new_station_news,
new_changelog,
can_start_now,
immediate_start,
} = data;
return (
@@ -131,6 +133,17 @@ export const LobbyButtons = (props: {
Join Game
</LobbyButton>
)}
{!!can_start_now && (
<LobbyButton
index={7}
disabled={!!immediate_start}
onClick={() => act('start_immediately')}
color={immediate_start ? 'green' : 'red'}
icon="play"
>
Start Now
</LobbyButton>
)}
</Stack>
</Section>
);

View File

@@ -15,6 +15,8 @@ export type LobbyData = {
show_station_news: BooleanLike;
new_station_news: BooleanLike;
new_changelog: BooleanLike;
can_start_now: BooleanLike;
immediate_start: BooleanLike;
};
export type LobbyContextType = {