diff --git a/code/modules/vore/eating/panel_databackend/vorepanel_vore_data.dm b/code/modules/vore/eating/panel_databackend/vorepanel_vore_data.dm index e05875b8465..611de1bd7cd 100644 --- a/code/modules/vore/eating/panel_databackend/vorepanel_vore_data.dm +++ b/code/modules/vore/eating/panel_databackend/vorepanel_vore_data.dm @@ -63,6 +63,11 @@ for(var/atom/movable/O in inside_belly) if(O == owner) continue + var/our_type + if(isliving(O)) + our_type = "Living" + else if(isitem(O)) + our_type = "Item" var/list/info = list( "name" = "[O]", @@ -70,6 +75,7 @@ "stat" = 0, "ref" = "\ref[O]", "outside" = FALSE, + "our_type" = our_type ) if(show_pictures) //disables icon mode if(inside_belly.contents.len <= max_icon_content) @@ -292,6 +298,22 @@ var/list/selected_contents var/total_content_count = 0 for(var/O in selected) + + // Please don't pass the options as a list... let TGUI handle that + var/our_type + if(ishuman(O)) + our_type = "Human" + + else if(isobserver(O) || istype(O,/obj/item/mmi)) + our_type = "Obeserver" + + else if(isliving(O)) + var/mob/living/datarget = O + if(datarget.client) + our_type = "LivingC" + else + our_type = "Living" + total_content_count++ if(active_vore_tab == CONTENTS_TAB) var/list/info = list( @@ -300,6 +322,7 @@ "stat" = 0, "ref" = "\ref[O]", "outside" = TRUE, + "our_type" = our_type ) if(show_pictures) //disables icon mode if(selected.contents.len <= max_icon_content) diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index c5526e30f1a..f5548a4b91b 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -867,10 +867,16 @@ // Only allow indirect belly viewers to examine if(user in OB) if(isliving(target)) - intent = tgui_alert(user, "What do you want to do to them?","Query",list("Examine","Help Out","Devour")) + if(params["option"] in list("Examine","Help Out","Devour")) + intent = params["option"] + else + intent = tgui_alert(user, "What do you want to do to them?","Query",list("Examine","Help Out","Devour")) - else if(istype(target, /obj/item)) - intent = tgui_alert(user, "What do you want to do to that?","Query",list("Examine","Use Hand")) + else if(isitem(target)) + if(params["option"] in list("Examine","Use Hand")) + intent = params["option"] + else + intent = tgui_alert(user, "What do you want to do to that?","Query",list("Examine","Use Hand")) //End of indirect vorefx changes switch(intent) @@ -989,7 +995,10 @@ if(datarget.client) available_options += "Process" available_options += "Health" - intent = tgui_input_list(user, "What would you like to do with [target]?", "Vore Pick", available_options) + if((params["option"] in available_options)) + intent = params["option"] + else + intent = tgui_input_list(user, "What would you like to do with [target]?", "Vore Pick", available_options) switch(intent) if("Examine") var/list/results = target.examine(host) @@ -1023,7 +1032,9 @@ if(host.stat) to_chat(user,span_warning("You can't do that in your state!")) return TRUE - var/obj/belly/choice = tgui_input_list(user, "Move [target] where?","Select Belly", host.vore_organs) + var/obj/belly/choice = locate(params["targetBelly"]) + if(!(choice in host.vore_organs)) + choice = tgui_input_list(user, "Move [target] where?","Select Belly", host.vore_organs) if(!choice || !(target in host.vore_selected)) return TRUE to_chat(target,span_vwarning("You're squished from [host]'s [lowertext(host.vore_selected.name)] to their [lowertext(choice.name)]!")) @@ -1082,6 +1093,7 @@ return FALSE if(!H.allow_spontaneous_tf) + to_chat(user,span_warning("Your target can't be transformed!")) return FALSE var/datum/tgui_module/appearance_changer/vore/V = new(host, H) diff --git a/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreSelectedBelly.tsx b/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreSelectedBelly.tsx index 6e8795fa88a..9592767c68c 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreSelectedBelly.tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreSelectedBelly.tsx @@ -132,7 +132,7 @@ export const VoreSelectedBelly = (props: { -
+
{tabs[activeVoreTab] || 'Error'}
diff --git a/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreUserPreferences.tsx b/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreUserPreferences.tsx index 81a40df27fc..679df1b4954 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreUserPreferences.tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/VorePanelMainTabs/VoreUserPreferences.tsx @@ -1,5 +1,4 @@ import { Section } from 'tgui-core/components'; -import type { BooleanLike } from 'tgui-core/react'; import { digestModeToColor } from '../constants'; import type { localPrefs, prefData } from '../types'; @@ -10,12 +9,8 @@ import { VoreUserPreferencesSoulcatcher } from '../VoreUserPreferencesTabs/VoreU import { VoreUserPreferencesSpawn } from '../VoreUserPreferencesTabs/VoreUserPreferencesSpawn'; import { VoreUserPreferencesSpontaneous } from '../VoreUserPreferencesTabs/VoreUserPreferencesSpontaneous'; -export const VoreUserPreferences = (props: { - prefs: prefData; - show_pictures: BooleanLike; - icon_overflow: BooleanLike; -}) => { - const { prefs, show_pictures, icon_overflow } = props; +export const VoreUserPreferences = (props: { prefs: prefData }) => { + const { prefs } = props; const { digestable, absorbable, @@ -715,11 +710,7 @@ export const VoreUserPreferences = (props: { return (
- + { const { act } = useBackend(); + const [selectedAtom, setSelectedAtom] = useState(null); + const [contentSearchText, setContentSearchText] = useState(''); const { contents = [], @@ -34,6 +42,15 @@ export const VoreContentsPanel = (props: { icon_overflow, } = props; + useEffect(() => { + if ( + selectedAtom && + !contents?.some((item) => item.ref === selectedAtom.ref) + ) { + setSelectedAtom(null); + } + }, [contents]); + function bellyValueToName(value: string) { const bellyName = bellyDropdownNames ?.map((entry) => { @@ -49,111 +66,270 @@ export const VoreContentsPanel = (props: { return ''; } + const contentSearch = createSearch( + contentSearchText, + (content: contentData) => content.name, + ); + const displayedContents = contents?.filter(contentSearch); + return ( - <> - {!!outside && ( +
- - - act('pick_from_outside', { pickall: true, intent: 'eject_all' }) - } - > - Eject All - + + - - - act('pick_from_outside', { - pickall: true, - intent: 'move_all', - val: targetBelly, - }) + + - {!!bellyDropdownNames && !!onTargetBely && ( - - onTargetBely(value)} - options={bellyDropdownNames!} - selected={bellyValueToName(targetBelly)} - /> - + + } + > + + {!!outside && ( + + + + + act('pick_from_outside', { + pickall: true, + intent: 'eject_all', + }) + } + > + Eject All + + + + + act('pick_from_outside', { + pickall: true, + intent: 'move_all', + val: targetBelly, + }) + } + > + Move All + + + {!!bellyDropdownNames && !!onTargetBely && ( + <> + Destination: + + onTargetBely(value)} + options={bellyDropdownNames!} + selected={bellyValueToName(targetBelly)} + /> + + + )} + + + )} + + {selectedAtom ? ( + + {ourTypeToOptions( + selectedAtom.our_type, + !!selectedAtom.outside, + bellyValueToName(targetBelly), + ).map((option) => ( + + {option.needsConfirm ? ( + + act( + selectedAtom.outside + ? 'pick_from_outside' + : 'pick_from_inside', + { + option: option.name, + pick: selectedAtom.ref, + targetBelly: targetBelly, + belly: belly, + }, + ) + } + > + {option.name} + + ) : ( + + )} + + ))} + + + + + + ) : ( + Select something to interact with it. )} - - )} - {(show_pictures && !icon_overflow && ( - - {contents?.map((thing) => ( - - - {thing.name} - - ))} - - )) || ( - - {contents?.map((thing) => ( - - - - ))} - - )} - + + + +
+ {(show_pictures && !icon_overflow && ( + + {displayedContents?.map((thing) => ( + + + {thing.ref === selectedAtom?.ref && + (!!stats[thing.stat] || !!thing.absorbed) && ( + <> + + + {' '} + + + )} + {thing.name} + + ))} + + )) || ( + + {displayedContents?.map((thing) => ( + + + + ))} + + )} +
+
+ +
); }; diff --git a/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical.tsx b/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical.tsx index 95ba10e562f..bb4e4ef97d9 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical.tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical.tsx @@ -1,41 +1,15 @@ -import { useBackend } from 'tgui/backend'; -import { Button, Section, Stack } from 'tgui-core/components'; -import type { BooleanLike } from 'tgui-core/react'; +import { Section, Stack } from 'tgui-core/components'; import type { localPrefs } from '../types'; import { VoreUserPreferenceItem } from '../VorePanelElements/VoreUserPreferenceItem'; export const VoreUserPreferencesMechanical = (props: { - show_pictures: BooleanLike; - icon_overflow: BooleanLike; preferences: localPrefs; }) => { - const { act } = useBackend(); - const { show_pictures, icon_overflow, preferences } = props; + const { preferences } = props; return ( -
act('show_pictures')} - > - Contents Preference: {show_pictures ? 'Show Pictures' : 'Show List'} - - } - > +
= cost; } @@ -82,3 +84,113 @@ export async function paste_from_clipboard( } return ourText; } + +export function ourTypeToOptions( + type: string, + outside: boolean, + belly?: string, +): ActionButtonData[] { + const commonOption = { + name: 'Examine', + tooltip: 'Examine your current target.', + }; + + if (outside) { + const baseOptions = [ + { + name: 'Eject', + color: 'yellow', + needsConfirm: true, + tooltip: 'Eject your current target at your location.', + }, + { + name: 'Launch', + color: 'yellow', + needsConfirm: true, + tooltip: 'Eject your current target with some force in front of you.', + }, + { + name: 'Move', + color: 'yellow', + needsConfirm: true, + disabled: !belly, + tooltip: + 'Move your current target towards your selected destination belly.', + }, + { + name: 'Transfer', + color: 'yellow', + needsConfirm: true, + tooltip: 'Transfer your current target to a nearby person.', + }, + ]; + const interaction_options: ActionButtonData[] = []; + if (type === 'Human') { + interaction_options.push({ + name: 'Transform', + color: 'purple', + needsConfirm: true, + tooltip: 'Transform your current target into something else.', + }); + interaction_options.push({ + name: 'Health Check', + tooltip: 'Check the health of your current target.', + }); + } + if (type === 'Observer') { + interaction_options.push({ + name: 'Reform', + color: 'green', + needsConfirm: true, + tooltip: 'Reform your current target.', + }); + } + if (type === 'LivingC') { + interaction_options.push({ + name: 'Process', + color: 'red', + needsConfirm: true, + tooltip: 'Process your current target instantly.', + }); + interaction_options.push({ + name: 'Health', + tooltip: 'Display the health of the current target.', + }); + } else if (type === 'Living') { + interaction_options.push({ + name: 'Health', + tooltip: 'Display the health of the current target.', + }); + } + return [commonOption, ...baseOptions, ...interaction_options]; + } + if (type === 'Living') { + return [ + commonOption, + { + name: 'Help Out', + color: 'green', + needsConfirm: true, + tooltip: 'Help your current target to escape.', + }, + { + name: 'Devour', + color: 'red', + needsConfirm: true, + tooltip: 'Devour your current target.', + }, + ]; + } + if (type === 'Item') { + return [ + commonOption, + { + name: 'Use Hand', + color: 'yellow', + needsConfirm: true, + tooltip: 'Pick up your current target.', + }, + ]; + } + return []; +} diff --git a/tgui/packages/tgui/interfaces/VorePanel/index.tsx b/tgui/packages/tgui/interfaces/VorePanel/index.tsx index ba17de5bc59..c282d7a441e 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/index.tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/index.tsx @@ -80,13 +80,7 @@ export const VorePanel = () => { persist_edit_mode={persist_edit_mode} /> ); - tabs[3] = prefs && ( - - ); + tabs[3] = prefs && ; return ( diff --git a/tgui/packages/tgui/interfaces/VorePanel/types.ts b/tgui/packages/tgui/interfaces/VorePanel/types.ts index 1d968ab827c..b22f0c4d58e 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/types.ts +++ b/tgui/packages/tgui/interfaces/VorePanel/types.ts @@ -204,6 +204,7 @@ export type contentData = { ref: string; outside: BooleanLike; icon: string; + our_type: string; }; export type bellyLiquidData = { @@ -467,3 +468,11 @@ export type preferenceData = { fluid?: boolean; back_color?: { enabled: string; disabled: string }; }; + +export type ActionButtonData = { + name: string; + tooltip: string; + disabled?: boolean; + color?: string; + needsConfirm?: boolean; +};