diff --git a/tgui/packages/tgui/interfaces/VorePanelExport/VorePanelExportBellyString.tsx b/tgui/packages/tgui/interfaces/VorePanelExport/VorePanelExportBellyString.tsx index b683d34060a..2a2a87b1ca4 100644 --- a/tgui/packages/tgui/interfaces/VorePanelExport/VorePanelExportBellyString.tsx +++ b/tgui/packages/tgui/interfaces/VorePanelExport/VorePanelExportBellyString.tsx @@ -4,7 +4,14 @@ import { STRUGGLE_OUTSIDE_ABSORBED_MESSAGE, STRUGGLE_OUTSIDE_MESSAGE, } from './constants'; -import type { Belly } from './types'; +import { + formatListEmotes, + formatListItems, + formatListMessages, + getYesNo, +} from './functions'; +import type { Belly, EmoteEntry, SettingItem } from './types'; + import { GetAddons, GetAutotransferFlags, @@ -228,7 +235,24 @@ export const generateBellyString = (belly: Belly, index: number) => { let result = ''; result += `

`; result += `

'; result += `
`; @@ -236,10 +260,17 @@ export const generateBellyString = (belly: Belly, index: number) => { result += `Addons:
${GetAddons(addons)}

`; result += '== Descriptions ==
'; - result += `Vore Verb:
${vore_verb}

`; - result += `Release Verb:
${release_verb}

`; - result += `Description:
"${desc}"

`; - result += `Absorbed Description:
"${absorbed_desc}"

`; + + const infoFields = [ + { label: 'Vore Verb', value: vore_verb }, + { label: 'Release Verb', value: release_verb }, + { label: 'Description', value: `"${desc}"` }, + { label: 'Absorbed Description', value: `"${absorbed_desc}"` }, + ]; + + infoFields.forEach(({ label, value }) => { + result += `${label}:
${value}

`; + }); result += '
'; @@ -252,387 +283,206 @@ export const generateBellyString = (belly: Belly, index: number) => { result += '
'; // Start Div messagesTabpanel result += '
'; result += '
'; - result += `Escape Attempt Messages (Owner)`; - result += `Escape Attempt Messages (Prey)`; - result += `Escape Message (Owner)`; - result += `Escape Message (Prey)`; - result += `Escape Message (Outside)`; - result += `Escape Item Messages (Owner)`; - result += `Escape Item Messages (Prey)`; - result += `Escape Item Messages (Outside)`; - result += `Escape Fail Messages (Owner)`; - result += `Escape Fail Messages (Prey)`; - result += `Escape Attempt Absorbed Messages (Owner)`; - result += `Escape Attempt Absorbed Messages (Prey)`; - result += `Escape Absorbed Messages (Owner)`; - result += `Escape Absorbed Messages (Prey)`; - result += `Escape Absorbed Messages (Outside)`; - result += `Escape Fail Absorbed Messages (Owner)`; - result += `Escape Fail Absorbed Messages (Prey)`; - result += `Primary Transfer Messages (Owner)`; - result += `Primary Transfer Messages (Prey)`; - result += `Secondary Transfer Messages (Owner)`; - result += `Secondary Transfer Messages (Prey)`; - result += `Digest Chance Messages (Owner)`; - result += `Digest Chance Messages (Prey)`; - result += `Absorb Chance Messages (Owner)`; - result += `Absorb Chance Messages (Prey)`; - result += `Struggle Messages (Outside) (${ - displayed_message_flags & STRUGGLE_OUTSIDE_MESSAGE - ? 'On' - : 'Off' - })`; - result += `Struggle Messages (Inside)`; - result += `Absorbed Struggle Messages (Outside) (${ - displayed_message_flags & STRUGGLE_OUTSIDE_ABSORBED_MESSAGE - ? 'On' - : 'Off' - })`; - result += `Absorbed Struggle Messages (Inside)`; - result += `Digest Messages (Owner)`; - result += `Digest Messages (Prey)`; - result += `Absorb Messages (Owner)`; - result += `Absorb Messages (Prey)`; - result += `Unabsorb Messages (Owner)`; - result += `Unabsorb Messages (Prey)`; - result += `Examine Messages`; - result += `Examine Messages (Absorbed)`; - result += `Trash Eater Ingest Messages`; - result += `Item Expel Messages`; + + const tabLinks: { + id: string; + label: string; + active?: boolean; + enabled?: boolean; + }[] = [ + { + id: 'escapeAttemptMessagesOwner', + label: 'Escape Attempt Messages (Owner)', + active: true, + }, + { + id: 'escapeAttemptMessagesPrey', + label: 'Escape Attempt Messages (Prey)', + }, + { id: 'escapeMessagesOwner', label: 'Escape Message (Owner)' }, + { id: 'escapeMessagesPrey', label: 'Escape Message (Prey)' }, + { id: 'escapeMessagesOutside', label: 'Escape Message (Outside)' }, + { id: 'escapeItemMessagesOwner', label: 'Escape Item Messages (Owner)' }, + { id: 'escapeItemMessagesPrey', label: 'Escape Item Messages (Prey)' }, + { + id: 'escapeItemMessagesOutside', + label: 'Escape Item Messages (Outside)', + }, + { id: 'escapeFailMessagesOwner', label: 'Escape Fail Messages (Owner)' }, + { id: 'escapeFailMessagesPrey', label: 'Escape Fail Messages (Prey)' }, + { + id: 'escapeAttemptAbsorbedMessagesOwner', + label: 'Escape Attempt Absorbed Messages (Owner)', + }, + { + id: 'escapeAttemptAbsorbedMessagesPrey', + label: 'Escape Attempt Absorbed Messages (Prey)', + }, + { + id: 'escapeAbsorbedMessagesOwner', + label: 'Escape Absorbed Messages (Owner)', + }, + { + id: 'escapeAbsorbedMessagesPrey', + label: 'Escape Absorbed Messages (Prey)', + }, + { + id: 'escapeAbsorbedMessagesOutside', + label: 'Escape Absorbed Messages (Outside)', + }, + { + id: 'escapeFailAbsorbedMessagesOwner', + label: 'Escape Fail Absorbed Messages (Owner)', + }, + { + id: 'escapeFailAbsorbedMessagesPrey', + label: 'Escape Fail Absorbed Messages (Prey)', + }, + { + id: 'primaryTransferMessagesOwner', + label: 'Primary Transfer Messages (Owner)', + }, + { + id: 'primaryTransferMessagesPrey', + label: 'Primary Transfer Messages (Prey)', + }, + { + id: 'secondaryTransferMessagesOwner', + label: 'Secondary Transfer Messages (Owner)', + }, + { + id: 'secondaryTransferMessagesPrey', + label: 'Secondary Transfer Messages (Prey)', + }, + { + id: 'digestChanceMessagesOwner', + label: 'Digest Chance Messages (Owner)', + }, + { id: 'digestChanceMessagesPrey', label: 'Digest Chance Messages (Prey)' }, + { + id: 'absorbChanceMessagesOwner', + label: 'Absorb Chance Messages (Owner)', + }, + { id: 'absorbChanceMessagesPrey', label: 'Absorb Chance Messages (Prey)' }, + { + id: 'struggleMessagesOutside', + label: 'Struggle Messages (Outside)', + enabled: (displayed_message_flags & STRUGGLE_OUTSIDE_MESSAGE) > 0, + }, + { id: 'struggleMessagesInside', label: 'Struggle Messages (Inside)' }, + { + id: 'absorbedStruggleOutside', + label: 'Absorbed Struggle Messages (Outside)', + enabled: + (displayed_message_flags & STRUGGLE_OUTSIDE_ABSORBED_MESSAGE) > 0, + }, + { + id: 'absorbedStruggleInside', + label: 'Absorbed Struggle Messages (Inside)', + }, + { id: 'digestMessagesOwner', label: 'Digest Messages (Owner)' }, + { id: 'digestMessagesPrey', label: 'Digest Messages (Prey)' }, + { id: 'absorbMessagesOwner', label: 'Absorb Messages (Owner)' }, + { id: 'absorbMessagesPrey', label: 'Absorb Messages (Prey)' }, + { id: 'unabsorbMessagesOwner', label: 'Unabsorb Messages (Owner)' }, + { id: 'unabsorbMessagesPrey', label: 'Unabsorb Messages (Prey)' }, + { id: 'examineMessages', label: 'Examine Messages' }, + { id: 'examineMessagesAbsorbed', label: 'Examine Messages (Absorbed)' }, + { id: 'trash_eater_in', label: 'Trash Eater Ingest Messages' }, + { id: 'trash_eater_out', label: 'Item Expel Messages' }, + ]; + + tabLinks.forEach(({ id, label, enabled }, i) => { + const isActive = i === 0 ? ' active' : ''; + const status = enabled === undefined ? '' : getYesNo(enabled); + + result += `${label}${status}`; + }); + result += '
'; result += '
'; result += '
'; - result += `
`; - escape_attempt_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; + const messageTypes: [string, string[] | null][] = [ + ['escapeAttemptMessagesOwner', escape_attempt_messages_owner], + ['escapeAttemptMessagesPrey', escape_attempt_messages_prey], + ['escapeMessagesOwner', escape_messages_owner], + ['escapeMessagesPrey', escape_messages_prey], + ['escapeMessagesOutside', escape_messages_outside], + ['escapeItemMessagesOwner', escape_item_messages_owner], + ['escapeItemMessagesPrey', escape_item_messages_prey], + ['escapeItemMessagesOutside', escape_item_messages_outside], + ['escapeFailMessagesOwner', escape_fail_messages_owner], + ['escapeFailMessagesPrey', escape_fail_messages_prey], + [ + 'escapeAttemptAbsorbedMessagesOwner', + escape_attempt_absorbed_messages_owner, + ], + [ + 'escapeAttemptAbsorbedMessagesPrey', + escape_attempt_absorbed_messages_prey, + ], + ['escapeAbsorbedMessagesOwner', escape_absorbed_messages_owner], + ['escapeAbsorbedMessagesPrey', escape_absorbed_messages_prey], + ['escapeAbsorbedMessagesOutside', escape_absorbed_messages_outside], + ['escapeFailAbsorbedMessagesOwner', escape_fail_absorbed_messages_owner], + ['escapeFailAbsorbedMessagesPrey', escape_fail_absorbed_messages_prey], + ['primaryTransferMessagesOwner', primary_transfer_messages_owner], + ['primaryTransferMessagesPrey', primary_transfer_messages_prey], + ['secondaryTransferMessagesOwner', secondary_transfer_messages_owner], + ['secondaryTransferMessagesPrey', secondary_transfer_messages_prey], + ['primaryAutoTransferMessagesOwner', primary_autotransfer_messages_owner], + ['primaryAutoTransferMessagesPrey', primary_autotransfer_messages_prey], + [ + 'secondaryAutoTransferMessagesOwner', + secondary_autotransfer_messages_owner, + ], + ['secondaryAutoTransferMessagesPrey', secondary_autotransfer_messages_prey], + ['digestChanceMessagesOwner', digest_chance_messages_owner], + ['digestChanceMessagesPrey', digest_chance_messages_prey], + ['absorbChanceMessagesOwner', absorb_chance_messages_owner], + ['absorbChanceMessagesPrey', absorb_chance_messages_prey], + ['struggleMessagesOutside', struggle_messages_outside], + ['struggleMessagesInside', struggle_messages_inside], + ['absorbedStruggleOutside', absorbed_struggle_messages_outside], + ['absorbedStruggleInside', absorbed_struggle_messages_inside], + ['digestMessagesOwner', digest_messages_owner], + ['digestMessagesPrey', digest_messages_prey], + ['absorbMessagesOwner', absorb_messages_owner], + ['absorbMessagesPrey', absorb_messages_prey], + ['unabsorbMessagesOwner', unabsorb_messages_owner], + ['unabsorbMessagesPrey', unabsorb_messages_prey], + ['examineMessages', examine_messages], + ['examineMessagesAbsorbed', examine_messages_absorbed], + ['trash_eater_in', trash_eater_in], + ['trash_eater_out', trash_eater_out], + ]; - result += `
`; - escape_attempt_messages_prey?.forEach((msg) => { - result += `${msg}
`; + messageTypes.forEach(([messageKey, messageData], i) => { + result += formatListMessages(`${messageKey}${index}`, messageData, i === 0); }); - result += '
'; - - result += `
`; - escape_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_messages_outside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_item_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_item_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_item_messages_outside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_fail_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_fail_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_attempt_absorbed_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_attempt_absorbed_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_absorbed_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_absorbed_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_absorbed_messages_outside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_fail_absorbed_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - escape_fail_absorbed_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - primary_transfer_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - primary_transfer_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - secondary_transfer_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - secondary_transfer_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - primary_autotransfer_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - primary_autotransfer_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - secondary_autotransfer_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - secondary_autotransfer_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - digest_chance_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - digest_chance_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - absorb_chance_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - absorb_chance_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - struggle_messages_outside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - struggle_messages_inside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - absorbed_struggle_messages_outside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - absorbed_struggle_messages_inside?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - digest_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - digest_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - absorb_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - absorb_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - unabsorb_messages_owner?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - unabsorb_messages_prey?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - examine_messages?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - examine_messages_absorbed?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - trash_eater_in?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - - result += `
`; - trash_eater_out?.forEach((msg) => { - result += `${msg}
`; - }); - result += '
'; - result += '
'; result += '
'; result += '
'; // End Div messagesTabpanel result += '
= Idle Messages =

'; - result += '

Idle Messages (Hold):

'; - emotes_hold?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; + const emoteSections: EmoteEntry[] = [ + { label: 'Idle Messages (Hold)', messages: emotes_hold }, + { label: 'Idle Messages (Hold Absorbed)', messages: emotes_holdabsorbed }, + { label: 'Idle Messages (Digest)', messages: emotes_digest }, + { label: 'Idle Messages (Absorb)', messages: emotes_absorb }, + { label: 'Idle Messages (Unabsorb)', messages: emotes_unabsorb }, + { label: 'Idle Messages (Drain)', messages: emotes_drain }, + { label: 'Idle Messages (Heal)', messages: emotes_heal }, + { label: 'Idle Messages (Size Steal)', messages: emotes_steal }, + { label: 'Idle Messages (Shrink)', messages: emotes_shrink }, + { label: 'Idle Messages (Grow)', messages: emotes_grow }, + { label: 'Idle Messages (Encase In Egg)', messages: emotes_egg }, + ]; - result += '
Idle Messages (Hold Absorbed):

'; - emotes_holdabsorbed?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Digest):

'; - emotes_digest?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Absorb):

'; - emotes_absorb?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Unabsorb):

'; - emotes_unabsorb?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Drain):

'; - emotes_drain?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Heal):

'; - emotes_heal?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Size Steal):

'; - emotes_steal?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Shrink):

'; - emotes_shrink?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Grow):

'; - emotes_grow?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; - - result += '
Idle Messages (Encase In Egg):

'; - emotes_egg?.forEach((msg) => { - result += `${msg}
`; - }); - result += '


'; + result += formatListEmotes(emoteSections); result += '


'; @@ -651,57 +501,96 @@ export const generateBellyString = (belly: Belly, index: number) => { result += `
`; result += '
'; result += '
    '; - result += `
  • Can Taste: ${ - can_taste - ? 'Yes' - : 'No' - }
  • `; - result += `
  • Feedable: ${ - is_feedable - ? 'Yes' - : 'No' - }
  • `; - result += `
  • Contaminates: ${ - contaminates - ? 'Yes' - : 'No' - }
  • `; - result += `
  • Contamination Flavor: ${contamination_flavor}
  • `; - result += `
  • Contamination Color: ${contamination_color}
  • `; - result += `
  • Nutritional Gain: ${nutrition_percent}%
  • `; - result += `
  • Required Examine Size: ${bulge_size * 100}%
  • `; - result += `
  • Display Absorbed Examines: ${ - display_absorbed_examine - ? 'True' - : 'False' - }
  • `; - result += `
  • Save Digest Mode: ${ - save_digest_mode - ? 'True' - : 'False' - }
  • `; - result += `
  • Idle Emotes: ${ - emote_active - ? 'Active' - : 'Inactive' - }
  • `; - result += `
  • Idle Emote Delay: ${emote_time} seconds
  • `; - result += `
  • Shrink/Grow Size: ${shrink_grow_size * 100}%
  • `; - result += `
  • Vore Spawn Blacklist: ${ - vorespawn_blacklist - ? 'Yes' - : 'No' - }
  • `; - result += `
  • Vore Spawn Whitelist: ${vorespawn_whitelist.length ? vorespawn_whitelist.join(', ') : 'Anyone!'}
  • `; - result += `
  • Vore Spawn Absorbed: ${ - vorespawn_absorbed === 0 - ? 'No' - : vorespawn_absorbed === 1 - ? 'Yes' - : 'Prey Choice' - }
  • `; - result += `
  • Egg Type: ${egg_type}
  • `; - result += `
  • Selective Mode Preference: ${selective_preference}
  • `; + + const settingItem: SettingItem[] = [ + { + label: 'Can Taste', + value: can_taste, + formatter: (val: boolean): string => getYesNo(val), + }, + { + label: 'Feedable', + value: is_feedable, + formatter: (val: boolean): string => getYesNo(val), + }, + { + label: 'Contaminates', + value: contaminates, + formatter: (val: boolean): string => getYesNo(val), + }, + { label: 'Contamination Flavor', value: contamination_flavor }, + { label: 'Contamination Color', value: contamination_color }, + { + label: 'Nutritional Gain', + value: nutrition_percent, + formatter: (val: number): string => `${val}%`, + }, + { + label: 'Required Examine Size', + value: bulge_size, + formatter: (val: number): string => `${val * 100}%`, + }, + { + label: 'Display Absorbed Examines', + value: display_absorbed_examine, + formatter: (val: boolean): string => + val + ? 'True' + : 'False', + }, + { + label: 'Save Digest Mode', + value: save_digest_mode, + formatter: (val: boolean): string => + val + ? 'True' + : 'False', + }, + { + label: 'Idle Emotes', + value: emote_active, + formatter: (val: boolean): string => + val + ? 'Active' + : 'Inactive', + }, + { + label: 'Idle Emote Delay', + value: emote_time, + formatter: (val: number): string => `${val} seconds`, + }, + { + label: 'Shrink/Grow Size', + value: shrink_grow_size, + formatter: (val: number): string => `${val * 100}%`, + }, + { + label: 'Vore Spawn Blacklist', + value: vorespawn_blacklist, + formatter: (val: boolean): string => getYesNo(val), + }, + { + label: 'Vore Spawn Whitelist', + value: vorespawn_whitelist, + formatter: (val: string[]): string => + val.length ? val.join(', ') : 'Anyone!', + }, + { + label: 'Vore Spawn Absorbed', + value: vorespawn_absorbed, + formatter: (val: number): string => + val === 0 + ? 'No' + : val === 1 + ? 'Yes' + : 'Prey Choice', + }, + { label: 'Egg Type', value: egg_type }, + { label: 'Selective Mode Preference', value: selective_preference }, + ]; + + result += formatListItems(settingItem); + result += '
'; result += '
'; @@ -717,21 +606,17 @@ export const generateBellyString = (belly: Belly, index: number) => { result += `
`; result += '
'; result += '
    '; - result += `
  • Fleshy Belly: ${ - is_wet ? 'Yes' : 'No' - }
  • `; - result += `
  • Internal Loop: ${ - wet_loop - ? 'Yes' - : 'No' - }
  • `; - result += `
  • Use Fancy Sounds: ${ - fancy_vore - ? 'Yes' - : 'No' - }
  • `; - result += `
  • Vore Sound: ${vore_sound}
  • `; - result += `
  • Release Sound: ${release_sound}
  • `; + + const soundItems = [ + { label: 'Fleshy Belly', value: is_wet, formatter: getYesNo }, + { label: 'Internal Loop', value: wet_loop, formatter: getYesNo }, + { label: 'Use Fancy Sounds', value: fancy_vore, formatter: getYesNo }, + { label: 'Vore Sound', value: vore_sound }, + { label: 'Release Sound', value: release_sound }, + ]; + + result += formatListItems(soundItems); + result += '
'; result += '
'; @@ -748,27 +633,48 @@ export const generateBellyString = (belly: Belly, index: number) => { result += '
'; result += 'Vore Sprites'; result += ''; result += 'Belly Fullscreens Preview and Coloring'; result += ''; result += 'Vore FX'; result += '
'; @@ -856,11 +837,17 @@ export const generateBellyString = (belly: Belly, index: number) => { ? 'On' : 'Off' }`; - result += `
  • Liquid Type: ${reagent_chosen}
  • `; - result += `
  • Liquid Name: ${reagent_name}
  • `; - result += `
  • Transfer Verb: ${reagent_transfer_verb}
  • `; - result += `
  • Generation Time: ${gen_time_display}
  • `; - result += `
  • Liquid Capacity: ${custom_max_volume}
  • `; + + const liquidItems = [ + { label: 'Liquid Type', value: reagent_chosen }, + { label: 'Liquid Name', value: reagent_name }, + { label: 'Transfer Verb', value: reagent_transfer_verb }, + { label: 'Generation Time', value: gen_time_display }, + { label: 'Liquid Capacity', value: custom_max_volume }, + ]; + + result += formatListItems(liquidItems); + result += `
  • Slosh Sounds: ${ vorefootsteps_sounds ? 'On' @@ -890,65 +877,44 @@ export const generateBellyString = (belly: Belly, index: number) => { result += '
    '; result += '
    '; - result += `Examine Message (0 to 20%) (${ - liquid_fullness1_messages - ? 'On' - : 'Off' - })`; - result += `Examine Message (20 to 40%) (${ - liquid_fullness2_messages - ? 'On' - : 'Off' - })`; - result += `Examine Message (40 to 60%) (${ - liquid_fullness3_messages - ? 'On' - : 'Off' - })`; - result += `Examine Message (60 to 80%) (${ - liquid_fullness4_messages - ? 'On' - : 'Off' - })`; - result += `Examine Message (80 to 100%) (${ - liquid_fullness5_messages - ? 'On' - : 'Off' - })`; + + const fullnessItems = [ + ['examineMessage0_20', liquid_fullness1_messages, '0 to 20%'], + ['examineMessage20_40', liquid_fullness2_messages, '20 to 40%'], + ['examineMessage40_60', liquid_fullness3_messages, '40 to 60%'], + ['examineMessage60_80', liquid_fullness4_messages, '60 to 80%'], + ['examineMessage80_100', liquid_fullness5_messages, '80 to 100%'], + ]; + + fullnessItems.forEach(([idPrefix, messages, label], i) => { + const activeClass = i === 0 ? 'active' : ''; + const isOn = messages + ? 'On' + : 'Off'; + result += `Examine Message (${label}) (${isOn})`; + }); + result += '
    '; result += '
    '; result += '
    '; - result += `
    `; - fullness1_messages?.forEach((msg) => { - result += `${msg}
    `; - }); - result += '
    '; + const fullnessMessages: [string, string[]][] = [ + ['examineMessage0_20', fullness1_messages], + ['examineMessage20_40', fullness2_messages], + ['examineMessage40_60', fullness3_messages], + ['examineMessage60_80', fullness4_messages], + ['examineMessage80_100', fullness5_messages], + ]; - result += `
    `; - fullness2_messages?.forEach((msg) => { - result += `${msg}
    `; + fullnessMessages.forEach(([idPrefix, messages], i) => { + const classes = i === 0 ? 'tab-pane fade show active' : 'tab-pane fade'; + result += `
    `; + messages?.forEach((msg) => { + result += `${msg}
    `; + }); + result += '
    '; }); - result += '
    '; - - result += `
    `; - fullness3_messages?.forEach((msg) => { - result += `${msg}
    `; - }); - result += '
    '; - - result += `
    `; - fullness4_messages?.forEach((msg) => { - result += `${msg}
    `; - }); - result += '
    '; - - result += `
    `; - fullness5_messages?.forEach((msg) => { - result += `${msg}
    `; - }); - result += '
    '; result += '
    '; result += '
    '; diff --git a/tgui/packages/tgui/interfaces/VorePanelExport/functions.ts b/tgui/packages/tgui/interfaces/VorePanelExport/functions.ts new file mode 100644 index 00000000000..cce871db50d --- /dev/null +++ b/tgui/packages/tgui/interfaces/VorePanelExport/functions.ts @@ -0,0 +1,51 @@ +import type { BooleanLike } from 'tgui-core/react'; +import type { EmoteEntry } from './types'; + +export function formatListItems( + items: { + label: string; + value: string | string[] | BooleanLike; + formatter?: (val: boolean) => string; + suffix?: string; + }[], +): string { + let result = ''; + items.forEach(({ label, value, formatter, suffix = '' }) => { + const displayValue = formatter ? formatter(!!value) : value; + result += `
  • ${label}: ${displayValue}${suffix}
  • `; + }); + return result; +} + +export function formatListMessages( + id: string, + messages: string[] | null, + isActive = false, +): string { + const activeClass = isActive ? 'show active' : ''; + let result = `
    `; + messages?.forEach((msg) => { + result += `${msg}
    `; + }); + result += '
    '; + return result; +} + +export function formatListEmotes(sections: EmoteEntry[]): string { + let result = ''; + sections.forEach(({ label, messages }) => { + if (!messages?.length) return; + result += `
    ${label}:

    `; + messages.forEach((msg) => { + result += `${msg}
    `; + }); + result += '


    '; + }); + return result; +} + +export function getYesNo(val: boolean): string { + return val + ? 'Yes' + : 'No'; +} diff --git a/tgui/packages/tgui/interfaces/VorePanelExport/types.ts b/tgui/packages/tgui/interfaces/VorePanelExport/types.ts index e0a64c7d70b..8370ff9c765 100644 --- a/tgui/packages/tgui/interfaces/VorePanelExport/types.ts +++ b/tgui/packages/tgui/interfaces/VorePanelExport/types.ts @@ -238,3 +238,13 @@ export type Soulcatcher = { linked_belly: string; setting_flags: number; }; + +type Formatter = (val: T) => string; + +export type SettingItem = { + label: string; + value: T; + formatter?: Formatter; +}; + +export type EmoteEntry = { label: string; messages?: string[] };