From 87b34972301f7d3949617d2e5b316668f97ebca2 Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:29:58 -0700 Subject: [PATCH] [MIRROR] selective belly import (#11530) Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> --- code/controllers/subsystems/garbage.dm | 6 ++ code/modules/mob/new_player/lobby_browser.dm | 9 +++ code/modules/tgui_input/alert.dm | 2 +- code/modules/tgui_input/checkboxes.dm | 13 +++-- code/modules/tgui_input/list.dm | 3 +- code/modules/vore/eating/belly_import.dm | 57 ++++++++++++------- maps/virgo_minitest/virgo_minitest_defines.dm | 4 -- .../tgui/interfaces/CheckboxInput.tsx | 17 ++---- .../interfaces/LobbyMenu/LobbyButtons.tsx | 13 +++++ .../tgui/interfaces/LobbyMenu/types.ts | 2 + 10 files changed, 85 insertions(+), 41 deletions(-) diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm index 0923ede9bb..d00060e43c 100644 --- a/code/controllers/subsystems/garbage.dm +++ b/code/controllers/subsystems/garbage.dm @@ -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 diff --git a/code/modules/mob/new_player/lobby_browser.dm b/code/modules/mob/new_player/lobby_browser.dm index 003443c8d2..ef992fae4d 100644 --- a/code/modules/mob/new_player/lobby_browser.dm +++ b/code/modules/mob/new_player/lobby_browser.dm @@ -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.")) diff --git a/code/modules/tgui_input/alert.dm b/code/modules/tgui_input/alert.dm index 80ef7bd98d..abc9d86fa2 100644 --- a/code/modules/tgui_input/alert.dm +++ b/code/modules/tgui_input/alert.dm @@ -88,7 +88,7 @@ /datum/tgui_alert/Destroy(force, ...) SStgui.close_uis(src) state = null - QDEL_NULL(buttons) + buttons?.Cut() . = ..() /** diff --git a/code/modules/tgui_input/checkboxes.dm b/code/modules/tgui_input/checkboxes.dm index 1732f474e1..45f8a7f529 100644 --- a/code/modules/tgui_input/checkboxes.dm +++ b/code/modules/tgui_input/checkboxes.dm @@ -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 diff --git a/code/modules/tgui_input/list.dm b/code/modules/tgui_input/list.dm index 00531a09a5..8422d1be2b 100644 --- a/code/modules/tgui_input/list.dm +++ b/code/modules/tgui_input/list.dm @@ -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 ..() /** diff --git a/code/modules/vore/eating/belly_import.dm b/code/modules/vore/eating/belly_import.dm index 1cdaa9c2bd..01de4ae1f9 100644 --- a/code/modules/vore/eating/belly_import.dm +++ b/code/modules/vore/eating/belly_import.dm @@ -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) diff --git a/maps/virgo_minitest/virgo_minitest_defines.dm b/maps/virgo_minitest/virgo_minitest_defines.dm index 00b384c969..ef445be928 100644 --- a/maps/virgo_minitest/virgo_minitest_defines.dm +++ b/maps/virgo_minitest/virgo_minitest_defines.dm @@ -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" diff --git a/tgui/packages/tgui/interfaces/CheckboxInput.tsx b/tgui/packages/tgui/interfaces/CheckboxInput.tsx index 3c6d27d1d8..1b02ff12ae 100644 --- a/tgui/packages/tgui/interfaces/CheckboxInput.tsx +++ b/tgui/packages/tgui/interfaces/CheckboxInput.tsx @@ -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([]); - const [searchQuery, setSearchQuery] = useState(''); + const [searchQuery, setSearchQuery] = useState(''); const search = createSearch(searchQuery, (item: string) => item); const toDisplay = items.filter(search); @@ -55,7 +54,7 @@ export const CheckboxInput = (props) => { {!!timeout && } - + {decodeHtmlEntities(message)}{' '} @@ -63,7 +62,7 @@ export const CheckboxInput = (props) => { {max_checked < 50 && ` (Max: ${max_checked})`} - +
{toDisplay.map((item, index) => ( @@ -86,21 +85,17 @@ export const CheckboxInput = (props) => {
- + - setSearchQuery(value)} - /> + - +
diff --git a/tgui/packages/tgui/interfaces/LobbyMenu/LobbyButtons.tsx b/tgui/packages/tgui/interfaces/LobbyMenu/LobbyButtons.tsx index e52ebd7a6e..eb4aade4e4 100644 --- a/tgui/packages/tgui/interfaces/LobbyMenu/LobbyButtons.tsx +++ b/tgui/packages/tgui/interfaces/LobbyMenu/LobbyButtons.tsx @@ -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 )} + {!!can_start_now && ( + act('start_immediately')} + color={immediate_start ? 'green' : 'red'} + icon="play" + > + Start Now + + )}
); diff --git a/tgui/packages/tgui/interfaces/LobbyMenu/types.ts b/tgui/packages/tgui/interfaces/LobbyMenu/types.ts index a69b959c0b..d277212a7b 100644 --- a/tgui/packages/tgui/interfaces/LobbyMenu/types.ts +++ b/tgui/packages/tgui/interfaces/LobbyMenu/types.ts @@ -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 = {