mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-21 20:14:31 +01:00
vorepanel reloaded (#17723)
* vorepanel rework part 1 * finish first tab * those should be fine * . * floating for the addons * . * tooltip prep and style * while on it * prep data compile for tab 2 rework * message tab * undef * . * some more components * unify the mesage procs * option tab preps * tooltip prep * small fixes * sorting * some more preps * . * move that * move that * finish options tab * sound preps * sound preps * finish sound tab * visual tab prep * . * visual tab prep2 * visual * move that * interaction tab prep * interactions * interaction tab * more basic contents only for now * defaulted * . * . * clean up * liquid tab * wordng * make it the same * soulcatcher tab * prefs * crash save * typing * docs * . * sanitize corrupted save data * use the right type
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
// Vore belly options
|
||||
// Descriptions
|
||||
#define BELLY_DESCRIPTION_MESSAGE "b_desc"
|
||||
#define BELLY_DESCRIPTION_MESSAGE_ABSROED "b_absorbed_desc"
|
||||
|
||||
// Vore belly options
|
||||
#define STRUGGLE_OUTSIDE "smo"
|
||||
#define STRUGGLE_INSIDE "smi"
|
||||
|
||||
@@ -27,8 +30,8 @@
|
||||
#define ABSORBED_ESCAPE_PREY "aescp"
|
||||
#define ABSORBED_ESCAPE_OUTSIDE "aescout"
|
||||
|
||||
#define FULL_ABSORBED_ESCAPE_OWNER "aescfo"
|
||||
#define FULL_ABSORBED_ESCAPE_PREY "aescfp"
|
||||
#define ABSORBED_ESCAPE_FAIL_OWNER "aescfo"
|
||||
#define ABSORBED_ESCAPE_FAIL_PREY "aescfp"
|
||||
|
||||
#define PRIMARY_TRANSFER_OWNER "trnspo"
|
||||
#define PRIMARY_TRANSFER_PREY "trnspp"
|
||||
@@ -75,12 +78,37 @@
|
||||
#define BELLY_TRASH_EATER_IN "te_in"
|
||||
#define BELLY_TRASH_EATER_OUT "te_out"
|
||||
|
||||
#define BELLY_LIQUID_MESSAGE1 "full1"
|
||||
#define BELLY_LIQUID_MESSAGE2 "full2"
|
||||
#define BELLY_LIQUID_MESSAGE3 "full3"
|
||||
#define BELLY_LIQUID_MESSAGE4 "full4"
|
||||
#define BELLY_LIQUID_MESSAGE5 "full5"
|
||||
|
||||
#define VB_MESSAGE_SANITY(type) ASSERT(type == STRUGGLE_OUTSIDE || type == STRUGGLE_INSIDE || type == ABSORBED_STRUGGLE_OUSIDE || type == ABSORBED_STRUGGLE_INSIDE || type == ESCAPE_ATTEMPT_OWNER || type == ESCAPE_ATTEMPT_PREY ||\
|
||||
type == ESCAPE_PREY || type == ESCAPE_OWNER || type == ESCAPE_OUTSIDE || type == ESCAPE_ITEM_PREY || type == ESCAPE_ITEM_OWNER || type == ESCAPE_ITEM_OUTSIDE || type == ESCAPE_FAIL_PREY ||\
|
||||
type == ESCAPE_FAIL_OWNER || type == ABSORBED_ESCAPE_ATTEMPT_OWNER || type == ABSORBED_ESCAPE_ATTEMPT_PREY || type == ABSORBED_ESCAPE_PREY || type == ABSORBED_ESCAPE_OWNER ||\
|
||||
type == ABSORBED_ESCAPE_OUTSIDE || type == FULL_ABSORBED_ESCAPE_PREY || type == FULL_ABSORBED_ESCAPE_OWNER || type == PRIMARY_TRANSFER_PREY || type == PRIMARY_TRANSFER_OWNER ||\
|
||||
type == ABSORBED_ESCAPE_OUTSIDE || type == ABSORBED_ESCAPE_FAIL_PREY || type == ABSORBED_ESCAPE_FAIL_OWNER || type == PRIMARY_TRANSFER_PREY || type == PRIMARY_TRANSFER_OWNER ||\
|
||||
type == SECONDARY_TRANSFER_PREY || type == SECONDARY_TRANSFER_OWNER || type == PRIMARY_AUTO_TRANSFER_PREY || type == PRIMARY_AUTO_TRANSFER_OWNER || type == SECONDARY_AUTO_TRANSFER_PREY ||\
|
||||
type == SECONDARY_AUTO_TRANSFER_OWNER || type == DIGEST_CHANCE_PREY || type == DIGEST_CHANCE_OWNER || type == ABSORB_CHANCE_PREY || type == ABSORB_CHANCE_OWNER || type == DIGEST_OWNER ||\
|
||||
type == DIGEST_PREY || type == ABSORB_OWNER || type == ABSORB_PREY || type == UNABSORBS_OWNER || type == UNABSORBS_PREY || type == EXAMINES || type == EXAMINES_ABSORBED ||\
|
||||
type == BELLY_MODE_DIGEST || type == BELLY_MODE_HOLD || type == BELLY_MODE_HOLD_ABSORB || type == BELLY_MODE_ABSORB || type == BELLY_MODE_HEAL || type == BELLY_MODE_DRAIN ||\
|
||||
type == BELLY_MODE_STEAL || type == BELLY_MODE_EGG || type == BELLY_MODE_SHRINK || type == BELLY_MODE_GROW || type == BELLY_MODE_UNABSORB || type == BELLY_TRASH_EATER_IN || type==BELLY_TRASH_EATER_OUT)
|
||||
type == BELLY_MODE_STEAL || type == BELLY_MODE_EGG || type == BELLY_MODE_SHRINK || type == BELLY_MODE_GROW || type == BELLY_MODE_UNABSORB || type == BELLY_TRASH_EATER_IN || type==BELLY_TRASH_EATER_OUT ||\
|
||||
type == BELLY_LIQUID_MESSAGE1 || type == BELLY_LIQUID_MESSAGE2 || type == BELLY_LIQUID_MESSAGE3 || type == BELLY_LIQUID_MESSAGE4 || type == BELLY_LIQUID_MESSAGE5)
|
||||
|
||||
// Soulcatcher Message Options
|
||||
#define SC_INTERIOR_MESSAGE "sc_int"
|
||||
#define SC_CAPTURE_MEESAGE "sc_cap"
|
||||
#define SC_TRANSIT_MESSAGE "sc_transit"
|
||||
#define SC_RELEASE_MESSAGE "sc_rel"
|
||||
#define SC_TRANSFERE_MESSAGE "sc_transfer"
|
||||
#define SC_DELETE_MESSAGE "sc_del"
|
||||
|
||||
// General Message Options
|
||||
#define TASTE_FLAVOR "setflavor"
|
||||
#define SMELL_FLAVOR "setsmell"
|
||||
|
||||
// General Examine Messages
|
||||
#define GENERAL_EXAMINE_NUTRI "en"
|
||||
#define GENERAL_EXAMINE_WEIGHT "ew"
|
||||
|
||||
#define VPPREF_MESSAGE_SANITY(type) ASSERT(type == GENERAL_EXAMINE_NUTRI || type == GENERAL_EXAMINE_WEIGHT)
|
||||
|
||||
+22
-1
@@ -9,7 +9,28 @@
|
||||
#define BELLIES_MAX 40
|
||||
#define BELLIES_NAME_MIN 2
|
||||
#define BELLIES_NAME_MAX 40
|
||||
#define BELLIES_DESC_MAX 4096
|
||||
#define BELLIES_DESC_MAX 8192
|
||||
#define BELLIES_EXAMINE_MAX 2048
|
||||
#define BELLIES_IDLE_MAX 2048
|
||||
#define BELLIES_MESSAGE_MAX 1024
|
||||
#define BELLIES_MESSAGE_COMBINED 1024 * 10 + 18
|
||||
#define FLAVOR_MAX 400
|
||||
|
||||
#define VORE_SC_MAX 2048
|
||||
#define VORE_SC_DESC_MAX 8192
|
||||
|
||||
#define VORE_VERSION 2 //This is a Define so you don't have to worry about magic numbers.
|
||||
|
||||
#define VPANEL_DESCRIPTION_TAB 0
|
||||
#define VPANEL_EXAMINE_TAB 1
|
||||
#define VPANEL_TRASH_EATER_TAB 2
|
||||
#define VPANEL_STRUGGLE_TAB 3
|
||||
#define VPANEL_ESCAPE_TAB 4
|
||||
#define VPANEL_ESCAPE_ABSORBED_TAB 5
|
||||
#define VPANEL_TRANSFER_TAB 6
|
||||
#define VPANEL_INTERACTION_TAB 7
|
||||
#define VPANEL_BELLYMODE_TAB 8
|
||||
#define VPANEL_IDLE_TAB 9
|
||||
#define VPANEL_LIQUIDS_TAB 10
|
||||
|
||||
#define VORE_RESIZE_COST 125
|
||||
|
||||
@@ -156,274 +156,274 @@
|
||||
new_belly.release_verb = new_release_verb
|
||||
|
||||
if(islist(belly_data["digest_messages_prey"]))
|
||||
var/new_digest_messages_prey = sanitize(jointext(belly_data["digest_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_digest_messages_prey = sanitize(jointext(belly_data["digest_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_digest_messages_prey)
|
||||
new_belly.set_messages(new_digest_messages_prey,DIGEST_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_digest_messages_prey,DIGEST_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["digest_messages_owner"]))
|
||||
var/new_digest_messages_owner = sanitize(jointext(belly_data["digest_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_digest_messages_owner = sanitize(jointext(belly_data["digest_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_digest_messages_owner)
|
||||
new_belly.set_messages(new_digest_messages_owner,DIGEST_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_digest_messages_owner,DIGEST_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["absorb_messages_prey"]))
|
||||
var/new_absorb_messages_prey = sanitize(jointext(belly_data["absorb_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_absorb_messages_prey = sanitize(jointext(belly_data["absorb_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_absorb_messages_prey)
|
||||
new_belly.set_messages(new_absorb_messages_prey,ABSORB_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_absorb_messages_prey,ABSORB_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["absorb_messages_owner"]))
|
||||
var/new_absorb_messages_owner = sanitize(jointext(belly_data["absorb_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_absorb_messages_owner = sanitize(jointext(belly_data["absorb_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_absorb_messages_owner)
|
||||
new_belly.set_messages(new_absorb_messages_owner,ABSORB_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_absorb_messages_owner,ABSORB_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["unabsorb_messages_prey"]))
|
||||
var/new_unabsorb_messages_prey = sanitize(jointext(belly_data["unabsorb_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_unabsorb_messages_prey = sanitize(jointext(belly_data["unabsorb_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_unabsorb_messages_prey)
|
||||
new_belly.set_messages(new_unabsorb_messages_prey,UNABSORBS_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_unabsorb_messages_prey,UNABSORBS_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["unabsorb_messages_owner"]))
|
||||
var/new_unabsorb_messages_owner = sanitize(jointext(belly_data["unabsorb_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_unabsorb_messages_owner = sanitize(jointext(belly_data["unabsorb_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_unabsorb_messages_owner)
|
||||
new_belly.set_messages(new_unabsorb_messages_owner,UNABSORBS_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_unabsorb_messages_owner,UNABSORBS_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["struggle_messages_outside"]))
|
||||
var/new_struggle_messages_outside = sanitize(jointext(belly_data["struggle_messages_outside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_struggle_messages_outside = sanitize(jointext(belly_data["struggle_messages_outside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_struggle_messages_outside)
|
||||
new_belly.set_messages(new_struggle_messages_outside,STRUGGLE_OUTSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_struggle_messages_outside,STRUGGLE_OUTSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["struggle_messages_inside"]))
|
||||
var/new_struggle_messages_inside = sanitize(jointext(belly_data["struggle_messages_inside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_struggle_messages_inside = sanitize(jointext(belly_data["struggle_messages_inside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_struggle_messages_inside)
|
||||
new_belly.set_messages(new_struggle_messages_inside,STRUGGLE_INSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_struggle_messages_inside,STRUGGLE_INSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["absorbed_struggle_messages_outside"]))
|
||||
var/new_absorbed_struggle_messages_outside = sanitize(jointext(belly_data["absorbed_struggle_messages_outside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_absorbed_struggle_messages_outside = sanitize(jointext(belly_data["absorbed_struggle_messages_outside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_absorbed_struggle_messages_outside)
|
||||
new_belly.set_messages(new_absorbed_struggle_messages_outside,ABSORBED_STRUGGLE_OUSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_absorbed_struggle_messages_outside,ABSORBED_STRUGGLE_OUSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["absorbed_struggle_messages_inside"]))
|
||||
var/new_absorbed_struggle_messages_inside = sanitize(jointext(belly_data["absorbed_struggle_messages_inside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_absorbed_struggle_messages_inside = sanitize(jointext(belly_data["absorbed_struggle_messages_inside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_absorbed_struggle_messages_inside)
|
||||
new_belly.set_messages(new_absorbed_struggle_messages_inside,ABSORBED_STRUGGLE_INSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_absorbed_struggle_messages_inside,ABSORBED_STRUGGLE_INSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_attempt_messages_prey"]))
|
||||
var/new_escape_attempt_messages_prey = sanitize(jointext(belly_data["escape_attempt_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_attempt_messages_prey = sanitize(jointext(belly_data["escape_attempt_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_attempt_messages_prey)
|
||||
new_belly.set_messages(new_escape_attempt_messages_prey,ESCAPE_ATTEMPT_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_attempt_messages_prey,ESCAPE_ATTEMPT_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_attempt_messages_owner"]))
|
||||
var/new_escape_attempt_messages_owner = sanitize(jointext(belly_data["escape_attempt_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_attempt_messages_owner = sanitize(jointext(belly_data["escape_attempt_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_attempt_messages_owner)
|
||||
new_belly.set_messages(new_escape_attempt_messages_owner,ESCAPE_ATTEMPT_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_attempt_messages_owner,ESCAPE_ATTEMPT_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_messages_prey"]))
|
||||
var/new_escape_messages_prey = sanitize(jointext(belly_data["escape_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_messages_prey = sanitize(jointext(belly_data["escape_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_messages_prey)
|
||||
new_belly.set_messages(new_escape_messages_prey,ESCAPE_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_messages_prey,ESCAPE_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_messages_owner"]))
|
||||
var/new_escape_messages_owner = sanitize(jointext(belly_data["escape_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_messages_owner = sanitize(jointext(belly_data["escape_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_messages_owner)
|
||||
new_belly.set_messages(new_escape_messages_owner,ESCAPE_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_messages_owner,ESCAPE_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_messages_outside"]))
|
||||
var/new_escape_messages_outside = sanitize(jointext(belly_data["escape_messages_outside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_messages_outside = sanitize(jointext(belly_data["escape_messages_outside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_messages_outside)
|
||||
new_belly.set_messages(new_escape_messages_outside,ESCAPE_OUTSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_messages_outside,ESCAPE_OUTSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_item_messages_prey"]))
|
||||
var/new_escape_item_messages_prey = sanitize(jointext(belly_data["escape_item_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_item_messages_prey = sanitize(jointext(belly_data["escape_item_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_item_messages_prey)
|
||||
new_belly.set_messages(new_escape_item_messages_prey,ESCAPE_ITEM_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_item_messages_prey,ESCAPE_ITEM_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_item_messages_owner"]))
|
||||
var/new_escape_item_messages_owner = sanitize(jointext(belly_data["escape_item_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_item_messages_owner = sanitize(jointext(belly_data["escape_item_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_item_messages_owner)
|
||||
new_belly.set_messages(new_escape_item_messages_owner,ESCAPE_ITEM_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_item_messages_owner,ESCAPE_ITEM_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_item_messages_outside"]))
|
||||
var/new_escape_item_messages_outside = sanitize(jointext(belly_data["escape_item_messages_outside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_item_messages_outside = sanitize(jointext(belly_data["escape_item_messages_outside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_item_messages_outside)
|
||||
new_belly.set_messages(new_escape_item_messages_outside,ESCAPE_ITEM_OUTSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_item_messages_outside,ESCAPE_ITEM_OUTSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_fail_messages_prey"]))
|
||||
var/new_escape_fail_messages_prey = sanitize(jointext(belly_data["escape_fail_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_fail_messages_prey = sanitize(jointext(belly_data["escape_fail_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_fail_messages_prey)
|
||||
new_belly.set_messages(new_escape_fail_messages_prey,ESCAPE_FAIL_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_fail_messages_prey,ESCAPE_FAIL_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_fail_messages_owner"]))
|
||||
var/new_escape_fail_messages_owner = sanitize(jointext(belly_data["escape_fail_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_fail_messages_owner = sanitize(jointext(belly_data["escape_fail_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_fail_messages_owner)
|
||||
new_belly.set_messages(new_escape_fail_messages_owner,ESCAPE_FAIL_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_fail_messages_owner,ESCAPE_FAIL_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_attempt_absorbed_messages_prey"]))
|
||||
var/new_escape_attempt_absorbed_messages_prey = sanitize(jointext(belly_data["escape_attempt_absorbed_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_attempt_absorbed_messages_prey = sanitize(jointext(belly_data["escape_attempt_absorbed_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_attempt_absorbed_messages_prey)
|
||||
new_belly.set_messages(new_escape_attempt_absorbed_messages_prey,ABSORBED_ESCAPE_ATTEMPT_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_attempt_absorbed_messages_prey,ABSORBED_ESCAPE_ATTEMPT_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_attempt_absorbed_messages_owner"]))
|
||||
var/new_escape_attempt_absorbed_messages_owner = sanitize(jointext(belly_data["escape_attempt_absorbed_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_attempt_absorbed_messages_owner = sanitize(jointext(belly_data["escape_attempt_absorbed_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_attempt_absorbed_messages_owner)
|
||||
new_belly.set_messages(new_escape_attempt_absorbed_messages_owner,ABSORBED_ESCAPE_ATTEMPT_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_attempt_absorbed_messages_owner,ABSORBED_ESCAPE_ATTEMPT_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_absorbed_messages_prey"]))
|
||||
var/new_escape_absorbed_messages_prey = sanitize(jointext(belly_data["escape_absorbed_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_absorbed_messages_prey = sanitize(jointext(belly_data["escape_absorbed_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_absorbed_messages_prey)
|
||||
new_belly.set_messages(new_escape_absorbed_messages_prey,ABSORBED_ESCAPE_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_absorbed_messages_prey,ABSORBED_ESCAPE_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_absorbed_messages_owner"]))
|
||||
var/new_escape_absorbed_messages_owner = sanitize(jointext(belly_data["escape_absorbed_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_absorbed_messages_owner = sanitize(jointext(belly_data["escape_absorbed_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_absorbed_messages_owner)
|
||||
new_belly.set_messages(new_escape_absorbed_messages_owner,ABSORBED_ESCAPE_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_absorbed_messages_owner,ABSORBED_ESCAPE_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_absorbed_messages_outside"]))
|
||||
var/new_escape_absorbed_messages_outside = sanitize(jointext(belly_data["escape_absorbed_messages_outside"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_absorbed_messages_outside = sanitize(jointext(belly_data["escape_absorbed_messages_outside"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_absorbed_messages_outside)
|
||||
new_belly.set_messages(new_escape_absorbed_messages_outside,ABSORBED_ESCAPE_OUTSIDE, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_absorbed_messages_outside,ABSORBED_ESCAPE_OUTSIDE, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_fail_absorbed_messages_prey"]))
|
||||
var/new_escape_fail_absorbed_messages_prey = sanitize(jointext(belly_data["escape_fail_absorbed_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_fail_absorbed_messages_prey = sanitize(jointext(belly_data["escape_fail_absorbed_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_fail_absorbed_messages_prey)
|
||||
new_belly.set_messages(new_escape_fail_absorbed_messages_prey,FULL_ABSORBED_ESCAPE_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_fail_absorbed_messages_prey,ABSORBED_ESCAPE_FAIL_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["escape_fail_absorbed_messages_owner"]))
|
||||
var/new_escape_fail_absorbed_messages_owner = sanitize(jointext(belly_data["escape_fail_absorbed_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_escape_fail_absorbed_messages_owner = sanitize(jointext(belly_data["escape_fail_absorbed_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_escape_fail_absorbed_messages_owner)
|
||||
new_belly.set_messages(new_escape_fail_absorbed_messages_owner,FULL_ABSORBED_ESCAPE_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_escape_fail_absorbed_messages_owner,ABSORBED_ESCAPE_FAIL_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["primary_transfer_messages_prey"]))
|
||||
var/new_primary_transfer_messages_prey = sanitize(jointext(belly_data["primary_transfer_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_primary_transfer_messages_prey = sanitize(jointext(belly_data["primary_transfer_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_primary_transfer_messages_prey)
|
||||
new_belly.set_messages(new_primary_transfer_messages_prey,PRIMARY_TRANSFER_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_primary_transfer_messages_prey,PRIMARY_TRANSFER_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["primary_transfer_messages_owner"]))
|
||||
var/new_primary_transfer_messages_owner = sanitize(jointext(belly_data["primary_transfer_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_primary_transfer_messages_owner = sanitize(jointext(belly_data["primary_transfer_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_primary_transfer_messages_owner)
|
||||
new_belly.set_messages(new_primary_transfer_messages_owner,PRIMARY_TRANSFER_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_primary_transfer_messages_owner,PRIMARY_TRANSFER_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["secondary_transfer_messages_prey"]))
|
||||
var/new_secondary_transfer_messages_prey = sanitize(jointext(belly_data["secondary_transfer_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_secondary_transfer_messages_prey = sanitize(jointext(belly_data["secondary_transfer_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_secondary_transfer_messages_prey)
|
||||
new_belly.set_messages(new_secondary_transfer_messages_prey,SECONDARY_TRANSFER_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_secondary_transfer_messages_prey,SECONDARY_TRANSFER_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["secondary_transfer_messages_owner"]))
|
||||
var/new_secondary_transfer_messages_owner = sanitize(jointext(belly_data["secondary_transfer_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_secondary_transfer_messages_owner = sanitize(jointext(belly_data["secondary_transfer_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_secondary_transfer_messages_owner)
|
||||
new_belly.set_messages(new_secondary_transfer_messages_owner,SECONDARY_TRANSFER_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_secondary_transfer_messages_owner,SECONDARY_TRANSFER_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["primary_autotransfer_messages_prey"]))
|
||||
var/new_primary_autotransfer_messages_prey = sanitize(jointext(belly_data["primary_autotransfer_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_primary_autotransfer_messages_prey = sanitize(jointext(belly_data["primary_autotransfer_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_primary_autotransfer_messages_prey)
|
||||
new_belly.set_messages(new_primary_autotransfer_messages_prey,PRIMARY_AUTO_TRANSFER_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_primary_autotransfer_messages_prey,PRIMARY_AUTO_TRANSFER_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["primary_autotransfer_messages_owner"]))
|
||||
var/new_primary_autotransfer_messages_owner = sanitize(jointext(belly_data["primary_autotransfer_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_primary_autotransfer_messages_owner = sanitize(jointext(belly_data["primary_autotransfer_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_primary_autotransfer_messages_owner)
|
||||
new_belly.set_messages(new_primary_autotransfer_messages_owner,PRIMARY_AUTO_TRANSFER_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_primary_autotransfer_messages_owner,PRIMARY_AUTO_TRANSFER_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["secondary_autotransfer_messages_prey"]))
|
||||
var/new_secondary_autotransfer_messages_prey = sanitize(jointext(belly_data["secondary_autotransfer_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_secondary_autotransfer_messages_prey = sanitize(jointext(belly_data["secondary_autotransfer_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_secondary_autotransfer_messages_prey)
|
||||
new_belly.set_messages(new_secondary_autotransfer_messages_prey,SECONDARY_AUTO_TRANSFER_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_secondary_autotransfer_messages_prey,SECONDARY_AUTO_TRANSFER_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["secondary_autotransfer_messages_owner"]))
|
||||
var/new_secondary_autotransfer_messages_owner = sanitize(jointext(belly_data["secondary_autotransfer_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_secondary_autotransfer_messages_owner = sanitize(jointext(belly_data["secondary_autotransfer_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_secondary_autotransfer_messages_owner)
|
||||
new_belly.set_messages(new_secondary_autotransfer_messages_owner,SECONDARY_AUTO_TRANSFER_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_secondary_autotransfer_messages_owner,SECONDARY_AUTO_TRANSFER_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["digest_chance_messages_prey"]))
|
||||
var/new_digest_chance_messages_prey = sanitize(jointext(belly_data["digest_chance_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_digest_chance_messages_prey = sanitize(jointext(belly_data["digest_chance_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_digest_chance_messages_prey)
|
||||
new_belly.set_messages(new_digest_chance_messages_prey,DIGEST_CHANCE_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_digest_chance_messages_prey,DIGEST_CHANCE_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["digest_chance_messages_owner"]))
|
||||
var/new_digest_chance_messages_owner = sanitize(jointext(belly_data["digest_chance_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_digest_chance_messages_owner = sanitize(jointext(belly_data["digest_chance_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_digest_chance_messages_owner)
|
||||
new_belly.set_messages(new_digest_chance_messages_owner,DIGEST_CHANCE_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_digest_chance_messages_owner,DIGEST_CHANCE_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["absorb_chance_messages_prey"]))
|
||||
var/new_absorb_chance_messages_prey = sanitize(jointext(belly_data["absorb_chance_messages_prey"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_absorb_chance_messages_prey = sanitize(jointext(belly_data["absorb_chance_messages_prey"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_absorb_chance_messages_prey)
|
||||
new_belly.set_messages(new_absorb_chance_messages_prey,ABSORB_CHANCE_PREY, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_absorb_chance_messages_prey,ABSORB_CHANCE_PREY, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["absorb_chance_messages_owner"]))
|
||||
var/new_absorb_chance_messages_owner = sanitize(jointext(belly_data["absorb_chance_messages_owner"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_absorb_chance_messages_owner = sanitize(jointext(belly_data["absorb_chance_messages_owner"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_absorb_chance_messages_owner)
|
||||
new_belly.set_messages(new_absorb_chance_messages_owner,ABSORB_CHANCE_OWNER, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_absorb_chance_messages_owner,ABSORB_CHANCE_OWNER, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["examine_messages"]))
|
||||
var/new_examine_messages = sanitize(jointext(belly_data["examine_messages"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_examine_messages = sanitize(jointext(belly_data["examine_messages"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_examine_messages)
|
||||
new_belly.set_messages(new_examine_messages,EXAMINES, limit = MAX_MESSAGE_LEN / 2)
|
||||
new_belly.set_messages(new_examine_messages,EXAMINES, limit = BELLIES_EXAMINE_MAX)
|
||||
|
||||
if(islist(belly_data["examine_messages_absorbed"]))
|
||||
var/new_examine_messages_absorbed = sanitize(jointext(belly_data["examine_messages_absorbed"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_examine_messages_absorbed = sanitize(jointext(belly_data["examine_messages_absorbed"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_examine_messages_absorbed)
|
||||
new_belly.set_messages(new_examine_messages_absorbed,EXAMINES_ABSORBED, limit = MAX_MESSAGE_LEN / 2)
|
||||
new_belly.set_messages(new_examine_messages_absorbed,EXAMINES_ABSORBED, limit = BELLIES_EXAMINE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_digest"]))
|
||||
var/new_emotes_digest = sanitize(jointext(belly_data["emotes_digest"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_digest = sanitize(jointext(belly_data["emotes_digest"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_digest)
|
||||
new_belly.set_messages(new_emotes_digest,BELLY_MODE_DIGEST, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_digest,BELLY_MODE_DIGEST, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["trash_eater_in"]))
|
||||
var/new_trash_eater_in = sanitize(jointext(belly_data["trash_eater_in"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_trash_eater_in = sanitize(jointext(belly_data["trash_eater_in"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_trash_eater_in)
|
||||
new_belly.set_messages(new_trash_eater_in ,BELLY_TRASH_EATER_IN, limit = MAX_MESSAGE_LEN / 2)
|
||||
new_belly.set_messages(new_trash_eater_in ,BELLY_TRASH_EATER_IN, limit = BELLIES_EXAMINE_MAX)
|
||||
|
||||
if(islist(belly_data["trash_eater_out"]))
|
||||
var/new_trash_eater_out = sanitize(jointext(belly_data["trash_eater_out"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_trash_eater_out = sanitize(jointext(belly_data["trash_eater_out"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_trash_eater_out)
|
||||
new_belly.set_messages(new_trash_eater_out,BELLY_TRASH_EATER_OUT, limit = MAX_MESSAGE_LEN / 2)
|
||||
new_belly.set_messages(new_trash_eater_out,BELLY_TRASH_EATER_OUT, limit = BELLIES_EXAMINE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_hold"]))
|
||||
var/new_emotes_hold = sanitize(jointext(belly_data["emotes_hold"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_hold = sanitize(jointext(belly_data["emotes_hold"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_hold)
|
||||
new_belly.set_messages(new_emotes_hold,BELLY_MODE_HOLD, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_hold,BELLY_MODE_HOLD, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_holdabsorbed"]))
|
||||
var/new_emotes_holdabsorbed = sanitize(jointext(belly_data["emotes_holdabsorbed"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_holdabsorbed = sanitize(jointext(belly_data["emotes_holdabsorbed"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_holdabsorbed)
|
||||
new_belly.set_messages(new_emotes_holdabsorbed,BELLY_MODE_HOLD_ABSORB, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_holdabsorbed,BELLY_MODE_HOLD_ABSORB, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_absorb"]))
|
||||
var/new_emotes_absorb = sanitize(jointext(belly_data["emotes_absorb"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_absorb = sanitize(jointext(belly_data["emotes_absorb"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_absorb)
|
||||
new_belly.set_messages(new_emotes_absorb,BELLY_MODE_ABSORB, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_absorb,BELLY_MODE_ABSORB, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_heal"]))
|
||||
var/new_emotes_heal = sanitize(jointext(belly_data["emotes_heal"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_heal = sanitize(jointext(belly_data["emotes_heal"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_heal)
|
||||
new_belly.set_messages(new_emotes_heal,BELLY_MODE_HEAL, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_heal,BELLY_MODE_HEAL, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_drain"]))
|
||||
var/new_emotes_drain = sanitize(jointext(belly_data["emotes_drain"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_drain = sanitize(jointext(belly_data["emotes_drain"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_drain)
|
||||
new_belly.set_messages(new_emotes_drain,BELLY_MODE_DRAIN, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_drain,BELLY_MODE_DRAIN, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_steal"]))
|
||||
var/new_emotes_steal = sanitize(jointext(belly_data["emotes_steal"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_steal = sanitize(jointext(belly_data["emotes_steal"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_steal)
|
||||
new_belly.set_messages(new_emotes_steal,BELLY_MODE_STEAL, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_steal,BELLY_MODE_STEAL, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_egg"]))
|
||||
var/new_emotes_egg = sanitize(jointext(belly_data["emotes_egg"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_egg = sanitize(jointext(belly_data["emotes_egg"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_egg)
|
||||
new_belly.set_messages(new_emotes_egg,BELLY_MODE_EGG, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_egg,BELLY_MODE_EGG, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_shrink"]))
|
||||
var/new_emotes_shrink = sanitize(jointext(belly_data["emotes_shrink"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_shrink = sanitize(jointext(belly_data["emotes_shrink"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_shrink)
|
||||
new_belly.set_messages(new_emotes_shrink,BELLY_MODE_SHRINK, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_shrink,BELLY_MODE_SHRINK, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_grow"]))
|
||||
var/new_emotes_grow = sanitize(jointext(belly_data["emotes_grow"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_grow = sanitize(jointext(belly_data["emotes_grow"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_grow)
|
||||
new_belly.set_messages(new_emotes_grow,BELLY_MODE_GROW, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_grow,BELLY_MODE_GROW, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
if(islist(belly_data["emotes_unabsorb"]))
|
||||
var/new_emotes_unabsorb = sanitize(jointext(belly_data["emotes_unabsorb"],"\n\n"),MAX_MESSAGE_LEN * 1.5,0,0,0)
|
||||
var/new_emotes_unabsorb = sanitize(jointext(belly_data["emotes_unabsorb"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_emotes_unabsorb)
|
||||
new_belly.set_messages(new_emotes_unabsorb,BELLY_MODE_UNABSORB, limit = MAX_MESSAGE_LEN / 4)
|
||||
new_belly.set_messages(new_emotes_unabsorb,BELLY_MODE_UNABSORB, limit = BELLIES_IDLE_MAX)
|
||||
|
||||
// Options
|
||||
if(isnum(belly_data["can_taste"]))
|
||||
@@ -1154,29 +1154,29 @@
|
||||
new_belly.liquid_fullness5_messages = TRUE
|
||||
|
||||
if(islist(belly_data["fullness1_messages"]))
|
||||
var/new_fullness1_messages = sanitize(jointext(belly_data["fullness1_messages"],"\n\n"),MAX_MESSAGE_LEN,0,0,0)
|
||||
var/new_fullness1_messages = sanitize(jointext(belly_data["fullness1_messages"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_fullness1_messages)
|
||||
new_belly.set_reagent_messages(new_fullness1_messages,"full1")
|
||||
new_belly.set_messages(new_fullness1_messages,BELLY_LIQUID_MESSAGE1, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["fullness2_messages"]))
|
||||
var/new_fullness2_messages = sanitize(jointext(belly_data["fullness2_messages"],"\n\n"),MAX_MESSAGE_LEN,0,0,0)
|
||||
var/new_fullness2_messages = sanitize(jointext(belly_data["fullness2_messages"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_fullness2_messages)
|
||||
new_belly.set_reagent_messages(new_fullness2_messages,"full2")
|
||||
new_belly.set_messages(new_fullness2_messages,BELLY_LIQUID_MESSAGE2, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["fullness3_messages"]))
|
||||
var/new_fullness3_messages = sanitize(jointext(belly_data["fullness3_messages"],"\n\n"),MAX_MESSAGE_LEN,0,0,0)
|
||||
var/new_fullness3_messages = sanitize(jointext(belly_data["fullness3_messages"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_fullness3_messages)
|
||||
new_belly.set_reagent_messages(new_fullness3_messages,"full3")
|
||||
new_belly.set_messages(new_fullness3_messages,BELLY_LIQUID_MESSAGE3, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["fullness4_messages"]))
|
||||
var/new_fullness4_messages = sanitize(jointext(belly_data["fullness4_messages"],"\n\n"),MAX_MESSAGE_LEN,0,0,0)
|
||||
var/new_fullness4_messages = sanitize(jointext(belly_data["fullness4_messages"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_fullness4_messages)
|
||||
new_belly.set_reagent_messages(new_fullness4_messages,"full4")
|
||||
new_belly.set_messages(new_fullness4_messages,BELLY_LIQUID_MESSAGE4, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
if(islist(belly_data["fullness5_messages"]))
|
||||
var/new_fullness5_messages = sanitize(jointext(belly_data["fullness5_messages"],"\n\n"),MAX_MESSAGE_LEN,0,0,0)
|
||||
var/new_fullness5_messages = sanitize(jointext(belly_data["fullness5_messages"],"\n\n"),BELLIES_MESSAGE_COMBINED,0,0,0)
|
||||
if(new_fullness5_messages)
|
||||
new_belly.set_reagent_messages(new_fullness5_messages,"full5")
|
||||
new_belly.set_messages(new_fullness5_messages,BELLY_LIQUID_MESSAGE5, limit = BELLIES_MESSAGE_MAX)
|
||||
|
||||
// After import updates
|
||||
new_belly.items_preserved.Cut()
|
||||
|
||||
@@ -326,9 +326,9 @@ GLOBAL_LIST_INIT(vore_words_snake, list("snake","serpent","reptilian","noodle","
|
||||
raw_messages = escape_absorbed_messages_prey
|
||||
if(ABSORBED_ESCAPE_OUTSIDE)
|
||||
raw_messages = escape_absorbed_messages_outside
|
||||
if(FULL_ABSORBED_ESCAPE_OWNER)
|
||||
if(ABSORBED_ESCAPE_FAIL_OWNER)
|
||||
raw_messages = escape_fail_absorbed_messages_owner
|
||||
if(FULL_ABSORBED_ESCAPE_PREY)
|
||||
if(ABSORBED_ESCAPE_FAIL_PREY)
|
||||
raw_messages = escape_fail_absorbed_messages_prey
|
||||
if(PRIMARY_TRANSFER_OWNER)
|
||||
raw_messages = primary_transfer_messages_owner
|
||||
@@ -396,6 +396,16 @@ GLOBAL_LIST_INIT(vore_words_snake, list("snake","serpent","reptilian","noodle","
|
||||
raw_messages = trash_eater_in
|
||||
if(BELLY_TRASH_EATER_OUT)
|
||||
raw_messages = trash_eater_out
|
||||
if(BELLY_LIQUID_MESSAGE1)
|
||||
raw_messages = fullness1_messages
|
||||
if(BELLY_LIQUID_MESSAGE2)
|
||||
raw_messages = fullness2_messages
|
||||
if(BELLY_LIQUID_MESSAGE3)
|
||||
raw_messages = fullness3_messages
|
||||
if(BELLY_LIQUID_MESSAGE4)
|
||||
raw_messages = fullness4_messages
|
||||
if(BELLY_LIQUID_MESSAGE5)
|
||||
raw_messages = fullness5_messages
|
||||
|
||||
var/messages = null
|
||||
if(raw_messages)
|
||||
@@ -413,11 +423,15 @@ GLOBAL_LIST_INIT(vore_words_snake, list("snake","serpent","reptilian","noodle","
|
||||
|
||||
var/list/raw_list
|
||||
|
||||
if(findtext(raw_text, delim))
|
||||
raw_list = splittext(html_encode(raw_text), delim)
|
||||
if(islist(raw_text))
|
||||
raw_list = raw_text
|
||||
else if(findtext(raw_text, delim))
|
||||
raw_list = splittext(raw_text, delim)
|
||||
else
|
||||
raw_list = list(raw_text)
|
||||
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
raw_list[i] = html_encode(raw_list[i])
|
||||
if(!length(raw_list[i]))
|
||||
raw_list.Cut(i, i + 1)
|
||||
i--
|
||||
@@ -480,9 +494,9 @@ GLOBAL_LIST_INIT(vore_words_snake, list("snake","serpent","reptilian","noodle","
|
||||
escape_absorbed_messages_prey = raw_list
|
||||
if(ABSORBED_ESCAPE_OUTSIDE)
|
||||
escape_absorbed_messages_outside = raw_list
|
||||
if(FULL_ABSORBED_ESCAPE_OWNER)
|
||||
if(ABSORBED_ESCAPE_FAIL_OWNER)
|
||||
escape_fail_absorbed_messages_owner = raw_list
|
||||
if(FULL_ABSORBED_ESCAPE_PREY)
|
||||
if(ABSORBED_ESCAPE_FAIL_PREY)
|
||||
escape_fail_absorbed_messages_prey = raw_list
|
||||
if(PRIMARY_TRANSFER_OWNER)
|
||||
primary_transfer_messages_owner = raw_list
|
||||
@@ -550,3 +564,13 @@ GLOBAL_LIST_INIT(vore_words_snake, list("snake","serpent","reptilian","noodle","
|
||||
trash_eater_in = raw_list
|
||||
if(BELLY_TRASH_EATER_OUT)
|
||||
trash_eater_out = raw_list
|
||||
if(BELLY_LIQUID_MESSAGE1)
|
||||
fullness1_messages = raw_list
|
||||
if(BELLY_LIQUID_MESSAGE2)
|
||||
fullness2_messages = raw_list
|
||||
if(BELLY_LIQUID_MESSAGE3)
|
||||
fullness3_messages = raw_list
|
||||
if(BELLY_LIQUID_MESSAGE4)
|
||||
fullness4_messages = raw_list
|
||||
if(BELLY_LIQUID_MESSAGE5)
|
||||
fullness5_messages = raw_list
|
||||
|
||||
@@ -263,65 +263,6 @@
|
||||
|
||||
return(span_red("[formatted_message]<BR>"))
|
||||
|
||||
|
||||
// The next function gets the messages set on the belly, in human-readable format.
|
||||
// This is useful in customization boxes and such. The delimiter right now is \n\n so
|
||||
// in message boxes, this looks nice and is easily delimited.
|
||||
/obj/belly/proc/get_reagent_messages(var/type, var/delim = "\n\n")
|
||||
ASSERT(type == "full1" || type == "full2" || type == "full3" || type == "full4" || type == "full5")
|
||||
var/list/raw_messages
|
||||
|
||||
switch(type)
|
||||
if("full1")
|
||||
raw_messages = fullness1_messages
|
||||
if("full2")
|
||||
raw_messages = fullness2_messages
|
||||
if("full3")
|
||||
raw_messages = fullness3_messages
|
||||
if("full4")
|
||||
raw_messages = fullness4_messages
|
||||
if("full5")
|
||||
raw_messages = fullness5_messages
|
||||
|
||||
var/messages = raw_messages.Join(delim)
|
||||
return messages
|
||||
|
||||
// The next function sets the messages on the belly, from human-readable var
|
||||
// replacement strings and linebreaks as delimiters (two \n\n by default).
|
||||
// They also sanitize the messages.
|
||||
/obj/belly/proc/set_reagent_messages(var/raw_text, var/type, var/delim = "\n\n")
|
||||
ASSERT(type == "full1" || type == "full2" || type == "full3" || type == "full4" || type == "full5")
|
||||
|
||||
var/list/raw_list = splittext(html_encode(raw_text),delim)
|
||||
if(raw_list.len > 10)
|
||||
raw_list.Cut(11)
|
||||
log_debug("[owner] tried to set [lowertext(name)] with 11+ messages")
|
||||
|
||||
for(var/i = 1, i <= raw_list.len, i++)
|
||||
if(length(raw_list[i]) > 160 || length(raw_list[i]) < 10) //160 is fudged value due to htmlencoding increasing the size
|
||||
raw_list.Cut(i,i)
|
||||
log_debug("[owner] tried to set [lowertext(name)] with >121 or <10 char message")
|
||||
else
|
||||
raw_list[i] = readd_quotes(raw_list[i])
|
||||
//Also fix % sign for var replacement
|
||||
raw_list[i] = replacetext(raw_list[i],"%","%")
|
||||
|
||||
ASSERT(raw_list.len <= 10) //Sanity
|
||||
|
||||
switch(type)
|
||||
if("full1")
|
||||
fullness1_messages = raw_list
|
||||
if("full2")
|
||||
fullness2_messages = raw_list
|
||||
if("full3")
|
||||
fullness3_messages = raw_list
|
||||
if("full4")
|
||||
fullness4_messages = raw_list
|
||||
if("full5")
|
||||
fullness5_messages = raw_list
|
||||
|
||||
return
|
||||
|
||||
/////////////////////////// Process Cycle Lite /////////////////////////// CHOMP PCL
|
||||
/obj/belly/proc/quick_cycle() //For manual belly cycling without straining the bellies subsystem.
|
||||
HandleBellyReagents() //reagent belly stuff.
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
S.use(1)
|
||||
digest_stage = w_class
|
||||
else
|
||||
if(istype(src, /obj/item/reagent_containers/food))
|
||||
if(istype(B) && istype(src, /obj/item/reagent_containers/food))
|
||||
if(ishuman(B.owner) && reagents)
|
||||
var/mob/living/carbon/human/H = B.owner
|
||||
reagents.trans_to_holder(H.ingested, (reagents.total_volume), B.nutrition_percent / 100, 0)
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
var/allow_spontaneous_tf = FALSE // Obviously.
|
||||
var/show_vore_fx = TRUE // Show belly fullscreens
|
||||
var/selective_preference = DM_DEFAULT // Preference for selective bellymode
|
||||
var/text_warnings = TRUE // Allows us to dismiss the text limit warning messages after viewing it once per round
|
||||
var/eating_privacy_global = FALSE // Makes eating attempt/success messages only reach for subtle range if true, overwritten by belly-specific var
|
||||
var/allow_mimicry = TRUE // Allows mimicking their character
|
||||
var/allow_mind_transfer = FALSE //Allows ones mind to be taken over or swapped
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/datum/vore_look/proc/get_preference_data(mob/owner)
|
||||
return list(
|
||||
"digestable" = owner.digestable,
|
||||
"devourable" = owner.devourable,
|
||||
"resizable" = owner.resizable,
|
||||
"feeding" = owner.feeding,
|
||||
"absorbable" = owner.absorbable,
|
||||
"digest_leave_remains" = owner.digest_leave_remains,
|
||||
"allowmobvore" = owner.allowmobvore,
|
||||
"permit_healbelly" = owner.permit_healbelly,
|
||||
"show_vore_fx" = owner.show_vore_fx,
|
||||
"can_be_drop_prey" = owner.can_be_drop_prey,
|
||||
"can_be_drop_pred" = owner.can_be_drop_pred,
|
||||
"latejoin_vore" = owner.latejoin_vore,
|
||||
"latejoin_prey" = owner.latejoin_prey,
|
||||
"no_spawnpred_warning" = owner.no_latejoin_vore_warning,
|
||||
"no_spawnprey_warning" = owner.no_latejoin_prey_warning,
|
||||
"no_spawnpred_warning_time" = owner.no_latejoin_vore_warning_time,
|
||||
"no_spawnprey_warning_time" = owner.no_latejoin_prey_warning_time,
|
||||
"no_spawnpred_warning_save" = owner.no_latejoin_vore_warning_persists,
|
||||
"no_spawnprey_warning_save" = owner.no_latejoin_prey_warning_persists,
|
||||
"allow_spontaneous_tf" = owner.allow_spontaneous_tf,
|
||||
"step_mechanics_active" = owner.step_mechanics_pref,
|
||||
"pickup_mechanics_active" = owner.pickup_pref,
|
||||
"strip_mechanics_active" = owner.strip_pref,
|
||||
"noisy" = owner.noisy,
|
||||
//liquid belly prefs
|
||||
"liq_rec" = owner.receive_reagents,
|
||||
"liq_giv" = owner.give_reagents,
|
||||
"liq_apply" = owner.apply_reagents,
|
||||
"autotransferable" = owner.autotransferable,
|
||||
"noisy_full" = owner.noisy_full, //Belching while full
|
||||
"selective_active" = owner.selective_preference, //Reveal active selective mode in prefs
|
||||
|
||||
"allow_mind_transfer" = owner.allow_mind_transfer,
|
||||
"drop_vore" = owner.drop_vore,
|
||||
"slip_vore" = owner.slip_vore,
|
||||
"stumble_vore" = owner.stumble_vore,
|
||||
"throw_vore" = owner.throw_vore,
|
||||
"phase_vore" = owner.phase_vore,
|
||||
"food_vore" = owner.food_vore,
|
||||
"consume_liquid_belly" = owner.consume_liquid_belly,
|
||||
"digest_pain" = owner.digest_pain,
|
||||
"eating_privacy_global" = owner.eating_privacy_global,
|
||||
"allow_mimicry" = owner.allow_mimicry,
|
||||
//Soulcatcher
|
||||
"soulcatcher_allow_capture" = owner.soulcatcher_pref_flags & SOULCATCHER_ALLOW_CAPTURE,
|
||||
"soulcatcher_allow_transfer" = owner.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TRANSFER,
|
||||
"soulcatcher_allow_takeover" = owner.soulcatcher_pref_flags & SOULCATCHER_ALLOW_TAKEOVER,
|
||||
"soulcatcher_allow_deletion" = (global_flag_check(owner.soulcatcher_pref_flags, SOULCATCHER_ALLOW_DELETION) + global_flag_check(owner.soulcatcher_pref_flags, SOULCATCHER_ALLOW_DELETION_INSTANT))
|
||||
)
|
||||
|
||||
#define SET_TASTE "Set Taste"
|
||||
#define SET_SMELL "Set Smell"
|
||||
#define SET_NUTRITION_EX "Set Nutrition Examine"
|
||||
#define SET_WEIGHT_EX "Set Weight Examine"
|
||||
|
||||
/datum/vore_look/proc/get_general_data(mob/owner)
|
||||
return list(
|
||||
"active_belly" = owner.vore_selected?.name,
|
||||
"belly_rub_target" = owner.belly_rub_target,
|
||||
// start, vore sprites
|
||||
"aestethic_messages" = compile_aesthetic_messages(owner),
|
||||
"vore_sprite_color" = owner.vore_sprite_color,
|
||||
"vore_sprite_multiply" = owner.vore_sprite_multiply,
|
||||
"vore_icon_options" = owner.vore_icon_bellies
|
||||
)
|
||||
|
||||
/datum/vore_look/proc/compile_aesthetic_messages(mob/owner)
|
||||
if(!aset_message_subtab)
|
||||
aset_message_subtab = SET_TASTE
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list(SET_TASTE, SET_SMELL, SET_NUTRITION_EX, SET_WEIGHT_EX),
|
||||
"aest_subtab" = aset_message_subtab
|
||||
)
|
||||
if(aset_message_subtab == SET_TASTE)
|
||||
tab_data["max_length"] = FLAVOR_MAX
|
||||
tab_data["active_message"] = owner.vore_taste
|
||||
tab_data["set_action"] = TASTE_FLAVOR
|
||||
tab_data["tooltip"] = "What your character tastes like. This text will be printed to the pred after 'X tastes of...' so just put something like 'strawberries and cream'"
|
||||
if(aset_message_subtab == SET_SMELL)
|
||||
tab_data["max_length"] = FLAVOR_MAX
|
||||
tab_data["active_message"] = owner.vore_smell
|
||||
tab_data["set_action"] = SMELL_FLAVOR
|
||||
tab_data["tooltip"] = "What your character smells like. This text will be printed to the pred after 'X smells of...' so just put something like 'strawberries and cream'"
|
||||
if(aset_message_subtab == SET_NUTRITION_EX)
|
||||
tab_data["max_length"] = BELLIES_EXAMINE_MAX
|
||||
tab_data["active_message"] = owner.nutrition_messages
|
||||
tab_data["set_action"] = "set_attribute"
|
||||
tab_data["sub_action"] = GENERAL_EXAMINE_NUTRI
|
||||
tab_data["tooltip"] = "Change the nutrition display messages on examine."
|
||||
tab_data["button_label"] = "Display Nutrition Examine"
|
||||
tab_data["button_action"] = "toggle_nutrition_ex"
|
||||
tab_data["button_data"] = owner.nutrition_message_visible
|
||||
tab_data["button_tooltip"] = "the nutition messages on examine." // those will automatically be preceeded by Enables / Disables!
|
||||
if(aset_message_subtab == SET_WEIGHT_EX)
|
||||
tab_data["max_length"] = BELLIES_EXAMINE_MAX
|
||||
tab_data["active_message"] = owner.weight_messages
|
||||
tab_data["set_action"] = "set_attribute"
|
||||
tab_data["sub_action"] = GENERAL_EXAMINE_WEIGHT
|
||||
tab_data["tooltip"] = "Change the weight display messages on examine."
|
||||
tab_data["button_label"] = "Display Weight Examine"
|
||||
tab_data["button_action"] = "toggle_weight_ex"
|
||||
tab_data["button_data"] = owner.weight_message_visible
|
||||
tab_data["button_tooltip"] = "the weight messages on examine." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
|
||||
#undef SET_TASTE
|
||||
#undef SET_SMELL
|
||||
#undef SET_NUTRITION_EX
|
||||
#undef SET_WEIGHT_EX
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
// liquid belly procs
|
||||
/datum/vore_look/proc/liq_set_attr(mob/user, params)
|
||||
if(!host.vore_selected)
|
||||
tgui_alert(user, "No belly selected to modify.")
|
||||
return FALSE
|
||||
|
||||
var/attr = params["attribute"]
|
||||
switch(attr)
|
||||
if("b_show_liq")
|
||||
if(!host.vore_selected.show_liquids)
|
||||
host.vore_selected.show_liquids = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] now has liquid options."))
|
||||
else
|
||||
host.vore_selected.show_liquids = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] no longer has liquid options."))
|
||||
. = TRUE
|
||||
if("b_liq_reagent_gen")
|
||||
if(!host.vore_selected.reagentbellymode) //liquid container adjustments and interactions.
|
||||
host.vore_selected.reagentbellymode = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] now has interactions which can produce liquids."))
|
||||
else //Doesnt produce liquids
|
||||
host.vore_selected.reagentbellymode = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] wont produce liquids, liquids already in your [lowertext(host.vore_selected.name)] must be emptied out or removed with purge."))
|
||||
. = TRUE
|
||||
if("b_liq_reagent_type")
|
||||
var/new_reagent = params["val"]
|
||||
if(!(new_reagent in host.vore_selected.reagent_choices))
|
||||
return FALSE
|
||||
|
||||
host.vore_selected.reagent_chosen = new_reagent
|
||||
host.vore_selected.ReagentSwitch() // For changing variables when a new reagent is chosen
|
||||
. = TRUE
|
||||
if("b_liq_reagent_name")
|
||||
var/new_name = params["val"]
|
||||
|
||||
if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN)
|
||||
tgui_alert(user, "Entered name length invalid (must be longer than [BELLIES_NAME_MIN], no longer than [BELLIES_NAME_MAX]).","Error")
|
||||
return FALSE
|
||||
|
||||
host.vore_selected.reagent_name = new_name
|
||||
. = TRUE
|
||||
if("b_liq_reagent_transfer_verb")
|
||||
var/new_verb = params["val"]
|
||||
|
||||
if(length(new_verb) > BELLIES_NAME_MAX || length(new_verb) < BELLIES_NAME_MIN)
|
||||
tgui_alert(user, "Entered verb length invalid (must be longer than [BELLIES_NAME_MIN], no longer than [BELLIES_NAME_MAX]).","Error")
|
||||
return FALSE
|
||||
|
||||
host.vore_selected.reagent_transfer_verb = new_verb
|
||||
. = TRUE
|
||||
if("b_liq_reagent_nutri_rate")
|
||||
host.vore_selected.gen_time_display = params["val"]
|
||||
switch(host.vore_selected.gen_time_display)
|
||||
if("10 minutes")
|
||||
host.vore_selected.gen_time = 0
|
||||
if("30 minutes")
|
||||
host.vore_selected.gen_time = 2
|
||||
if("1 hour")
|
||||
host.vore_selected.gen_time = 5
|
||||
if("3 hours")
|
||||
host.vore_selected.gen_time = 17
|
||||
if("6 hours")
|
||||
host.vore_selected.gen_time = 35
|
||||
if("12 hours")
|
||||
host.vore_selected.gen_time = 71
|
||||
if("24 hours")
|
||||
host.vore_selected.gen_time = 143
|
||||
. = TRUE
|
||||
if("b_liq_reagent_capacity")
|
||||
var/new_custom_vol = text2num(params["val"])
|
||||
if(!isnum(new_custom_vol))
|
||||
return FALSE
|
||||
host.vore_selected.custom_max_volume = CLAMP(new_custom_vol, 10, 300)
|
||||
. = TRUE
|
||||
if("b_liq_sloshing")
|
||||
if(!host.vore_selected.vorefootsteps_sounds)
|
||||
host.vore_selected.vorefootsteps_sounds = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] can now make sounds when you walk around depending on how full you are."))
|
||||
else
|
||||
host.vore_selected.vorefootsteps_sounds = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] wont make any liquid sounds no matter how full it is."))
|
||||
. = TRUE
|
||||
if("b_liq_reagent_addons")
|
||||
var/reagent_toggle_addon = params["val"]
|
||||
if(!reagent_toggle_addon)
|
||||
return FALSE
|
||||
host.vore_selected.reagent_mode_flags ^= host.vore_selected.reagent_mode_flag_list[reagent_toggle_addon]
|
||||
. = TRUE
|
||||
if("b_liquid_overlay")
|
||||
if(!host.vore_selected.liquid_overlay)
|
||||
host.vore_selected.liquid_overlay = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] now has liquid overlay enabled."))
|
||||
else
|
||||
host.vore_selected.liquid_overlay = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] no longer has liquid overlay enabled."))
|
||||
. = TRUE
|
||||
if("b_max_liquid_level")
|
||||
var/new_max_liquid_level = params["val"]
|
||||
if(!isnum(new_max_liquid_level))
|
||||
return FALSE
|
||||
host.vore_selected.max_liquid_level = CLAMP(new_max_liquid_level, 0, 100)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_custom_reagentcolor")
|
||||
var/newcolor = tgui_color_picker(user, "Choose custom color for liquid overlay. Cancel for normal reagent color.", "", host.vore_selected.custom_reagentcolor)
|
||||
if(newcolor)
|
||||
host.vore_selected.custom_reagentcolor = newcolor
|
||||
else
|
||||
host.vore_selected.custom_reagentcolor = null
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_custom_reagentalpha")
|
||||
var/newalpha = text2num(params["val"])
|
||||
if(!isnum(newalpha))
|
||||
return FALSE
|
||||
if(newalpha)
|
||||
host.vore_selected.custom_reagentalpha = CLAMP(newalpha, 0, 255)
|
||||
else
|
||||
host.vore_selected.custom_reagentalpha = null
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_reagent_touches")
|
||||
if(!host.vore_selected.reagent_touches)
|
||||
host.vore_selected.reagent_touches = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] will now apply reagents to creatures when digesting."))
|
||||
else
|
||||
host.vore_selected.reagent_touches = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] will no longer apply reagents to creatures when digesting."))
|
||||
. = TRUE
|
||||
if("b_mush_overlay")
|
||||
if(!host.vore_selected.mush_overlay)
|
||||
host.vore_selected.mush_overlay = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] now has fullness overlay enabled."))
|
||||
else
|
||||
host.vore_selected.mush_overlay = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] no longer has fullness overlay enabled."))
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_mush_color")
|
||||
var/newcolor = tgui_color_picker(user, "Choose custom color for mush overlay.", "", host.vore_selected.mush_color)
|
||||
if(newcolor)
|
||||
host.vore_selected.mush_color = newcolor
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_mush_alpha")
|
||||
var/newalpha = text2num(params["val"])
|
||||
if(!isnum(newalpha))
|
||||
return FALSE
|
||||
host.vore_selected.mush_alpha = CLAMP(newalpha, 0, 255)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_max_mush")
|
||||
var/new_max_mush = text2num(params["val"])
|
||||
if(!isnum(new_max_mush))
|
||||
return FALSE
|
||||
host.vore_selected.max_mush = CLAMP(new_max_mush, 0, 6000)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_min_mush")
|
||||
var/new_min_mush = text2num(params["val"])
|
||||
if(!isnum(new_min_mush))
|
||||
return FALSE
|
||||
host.vore_selected.min_mush = CLAMP(new_min_mush, 0, 100)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_item_mush_val")
|
||||
var/new_item_mush_val = text2num(params["val"])
|
||||
if(!isnum(new_item_mush_val))
|
||||
return FALSE
|
||||
host.vore_selected.item_mush_val = CLAMP(new_item_mush_val, 0, 1000)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_metabolism_overlay")
|
||||
if(!host.vore_selected.metabolism_overlay)
|
||||
host.vore_selected.metabolism_overlay = 1
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] now has ingested metabolism overlay enabled."))
|
||||
else
|
||||
host.vore_selected.metabolism_overlay = 0
|
||||
to_chat(user,span_warning("Your [lowertext(host.vore_selected.name)] no longer has ingested metabolism overlay enabled."))
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_metabolism_mush_ratio")
|
||||
var/new_metabolism_mush_ratio = text2num(params["val"])
|
||||
if(!isnum(new_metabolism_mush_ratio))
|
||||
return FALSE
|
||||
host.vore_selected.metabolism_mush_ratio = CLAMP(new_metabolism_mush_ratio, 0, 500)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_max_ingested")
|
||||
var/new_max_ingested = text2num(params["val"])
|
||||
if(!isnum(new_max_ingested))
|
||||
return FALSE
|
||||
host.vore_selected.max_ingested = CLAMP(new_max_ingested, 0, 6000)
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_custom_ingested_color")
|
||||
var/newcolor = tgui_color_picker(user, "Choose custom color for ingested metabolism overlay. Cancel for reagent-based dynamic blend.", "", host.vore_selected.custom_ingested_color)
|
||||
if(newcolor)
|
||||
host.vore_selected.custom_ingested_color = newcolor
|
||||
else
|
||||
host.vore_selected.custom_ingested_color = null
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_custom_ingested_alpha")
|
||||
var/newalpha = text2num(params["val"])
|
||||
if(!isnum(newalpha))
|
||||
return FALSE
|
||||
host.vore_selected.custom_ingested_alpha = newalpha
|
||||
host.vore_selected.update_internal_overlay()
|
||||
. = TRUE
|
||||
if("b_liq_purge")
|
||||
host.vore_selected.reagents.clear_reagents()
|
||||
. = TRUE
|
||||
if(.)
|
||||
unsaved_changes = TRUE
|
||||
@@ -0,0 +1,99 @@
|
||||
#define INTERIOR_DESIGN "Interior Design"
|
||||
#define CAPTURE_MESSAGE "Capture Message"
|
||||
#define TRANSIT_MESSAGE "Transit Message"
|
||||
#define TRANSFER_MESSAGE "Transfer Message"
|
||||
#define RELEASE_MESSAGE "Release Message"
|
||||
#define DELETE_MESSAGE "Delete Message"
|
||||
|
||||
|
||||
/datum/vore_look/proc/get_soulcatcher_data(mob/owner)
|
||||
if(!owner.soulgem)
|
||||
return null
|
||||
|
||||
var/list/stored_souls = list()
|
||||
for(var/soul in owner.soulgem.brainmobs)
|
||||
var/list/info = list("displayText" = "[soul]", "value" = "\ref[soul]")
|
||||
stored_souls.Add(list(info))
|
||||
var/list/soulcatcher_data = list(
|
||||
"active" = owner.soulgem.flag_check(SOULGEM_ACTIVE),
|
||||
"name" = owner.soulgem.name,
|
||||
"caught_souls" = stored_souls,
|
||||
"selected_soul" = owner.soulgem.selected_soul,
|
||||
"selected_sfx" = owner.soulgem.linked_belly,
|
||||
"sc_message_data" = compile_soulcatcher_message_data(owner.soulgem),
|
||||
"taken_over" = owner.soulgem.is_taken_over(),
|
||||
"catch_self" = owner.soulgem.flag_check(NIF_SC_CATCHING_ME),
|
||||
"catch_prey" = owner.soulgem.flag_check(NIF_SC_CATCHING_OTHERS),
|
||||
"catch_drain" = owner.soulgem.flag_check(SOULGEM_CATCHING_DRAIN),
|
||||
"catch_ghost" = owner.soulgem.flag_check(SOULGEM_CATCHING_GHOSTS),
|
||||
"ext_hearing" = owner.soulgem.flag_check(NIF_SC_ALLOW_EARS),
|
||||
"ext_vision" = owner.soulgem.flag_check(NIF_SC_ALLOW_EYES),
|
||||
"mind_backups" = owner.soulgem.flag_check(NIF_SC_BACKUPS),
|
||||
"sr_projecting" = owner.soulgem.flag_check(NIF_SC_PROJECTING),
|
||||
"show_vore_sfx" = owner.soulgem.flag_check(SOULGEM_SHOW_VORE_SFX),
|
||||
"see_sr_projecting" = owner.soulgem.flag_check(SOULGEM_SEE_SR_SOULS),
|
||||
)
|
||||
return soulcatcher_data
|
||||
|
||||
/datum/vore_look/proc/compile_soulcatcher_message_data(obj/soulgem/gem)
|
||||
if(!sc_message_subtab)
|
||||
sc_message_subtab = INTERIOR_DESIGN
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list(INTERIOR_DESIGN, CAPTURE_MESSAGE, TRANSIT_MESSAGE, TRANSFER_MESSAGE, RELEASE_MESSAGE, DELETE_MESSAGE),
|
||||
"sc_subtab" = sc_message_subtab
|
||||
)
|
||||
if(sc_message_subtab == INTERIOR_DESIGN)
|
||||
tab_data["max_length"] = VORE_SC_DESC_MAX
|
||||
tab_data["active_message"] = gem.inside_flavor
|
||||
tab_data["set_action"] = SC_INTERIOR_MESSAGE
|
||||
tab_data["tooltip"] = "Displayed to prey after being 'caught' by the soulcatcher. This will be displayed after an intro set in the capture message. If you already have prey and change the interior, this will be displayed after the transit message."
|
||||
if(sc_message_subtab == CAPTURE_MESSAGE)
|
||||
tab_data["max_length"] = VORE_SC_MAX
|
||||
tab_data["active_message"] = gem.capture_message
|
||||
tab_data["set_action"] = SC_CAPTURE_MEESAGE
|
||||
tab_data["tooltip"] = "Change what the prey sees while being 'caught'. This will be printed before the iterior design to the prey."
|
||||
if(sc_message_subtab == TRANSIT_MESSAGE)
|
||||
tab_data["max_length"] = VORE_SC_MAX
|
||||
tab_data["active_message"] = gem.transit_message
|
||||
tab_data["set_action"] = SC_TRANSIT_MESSAGE
|
||||
tab_data["tooltip"] = "Change what the prey sees when you change the interior with them already captured."
|
||||
if(sc_message_subtab == TRANSFER_MESSAGE)
|
||||
tab_data["max_length"] = VORE_SC_MAX
|
||||
tab_data["active_message"] = gem.transfer_message
|
||||
tab_data["set_action"] = SC_TRANSFERE_MESSAGE
|
||||
tab_data["tooltip"] = "Change what the prey sees when they are transfered."
|
||||
if(sc_message_subtab == RELEASE_MESSAGE)
|
||||
tab_data["max_length"] = VORE_SC_MAX
|
||||
tab_data["active_message"] = gem.release_message
|
||||
tab_data["set_action"] = SC_RELEASE_MESSAGE
|
||||
tab_data["tooltip"] = "Change what the prey sees when they are released."
|
||||
if(sc_message_subtab == DELETE_MESSAGE)
|
||||
tab_data["max_length"] = VORE_SC_MAX
|
||||
tab_data["active_message"] = gem.delete_message
|
||||
tab_data["set_action"] = SC_DELETE_MESSAGE
|
||||
tab_data["tooltip"] = "Change what the prey sees when they are deleted."
|
||||
return tab_data
|
||||
|
||||
/datum/vore_look/proc/get_ability_data(mob/owner)
|
||||
var/list/abilities = list()
|
||||
|
||||
var/nutri_value = 0
|
||||
if(isliving(owner))
|
||||
var/mob/living/H = owner
|
||||
nutri_value = H.nutrition
|
||||
|
||||
abilities["nutrition"] = nutri_value
|
||||
abilities["size_change"] = list (
|
||||
"current_size" = owner.size_multiplier,
|
||||
"minimum_size" = owner.has_large_resize_bounds() ? RESIZE_MINIMUM_DORMS : RESIZE_MINIMUM,
|
||||
"maximum_size" = owner.has_large_resize_bounds() ? RESIZE_MAXIMUM_DORMS : RESIZE_MAXIMUM,
|
||||
"resize_cost" = VORE_RESIZE_COST
|
||||
)
|
||||
return abilities
|
||||
|
||||
#undef INTERIOR_DESIGN
|
||||
#undef CAPTURE_MESSAGE
|
||||
#undef TRANSIT_MESSAGE
|
||||
#undef TRANSFER_MESSAGE
|
||||
#undef RELEASE_MESSAGE
|
||||
#undef DELETE_MESSAGE
|
||||
@@ -0,0 +1,328 @@
|
||||
#define CONTROL_TAB 0
|
||||
#define DESCRIPTIONS_TAB 1
|
||||
#define OPTIONS_TAB 2
|
||||
#define SOUNDS_TAB 3
|
||||
#define VISUALS_TAB 4
|
||||
#define INTERACTIONS_TAB 5
|
||||
#define CONTENTS_TAB 6
|
||||
#define LIQUID_OPTIONS_TAB 7
|
||||
|
||||
/datum/vore_look/proc/get_vorebellies(mob/owner, full_data = TRUE)
|
||||
var/list/our_bellies = list()
|
||||
for(var/obj/belly/B as anything in owner.vore_organs)
|
||||
var/list/belly_data = list()
|
||||
belly_data += list(
|
||||
"name" = B.name,
|
||||
"ref" = "\ref[B]"
|
||||
)
|
||||
if(full_data)
|
||||
belly_data += list(
|
||||
"selected" = (B == owner.vore_selected),
|
||||
"digest_mode" = B.digest_mode,
|
||||
"contents" = LAZYLEN(B.contents),
|
||||
"prevent_saving" = B.prevent_saving
|
||||
)
|
||||
UNTYPED_LIST_ADD(our_bellies, belly_data)
|
||||
return our_bellies
|
||||
|
||||
/datum/vore_look/proc/get_inside_data(mob/owner)
|
||||
var/atom/hostloc = owner.loc
|
||||
//Allow VorePanel to show pred belly details even while indirectly inside
|
||||
if(isliving(owner))
|
||||
var/mob/living/H = owner
|
||||
hostloc = H.surrounding_belly()
|
||||
//End of indirect vorefx additions
|
||||
var/list/inside = list()
|
||||
if(isbelly(hostloc))
|
||||
var/obj/belly/inside_belly = hostloc
|
||||
var/mob/living/pred = inside_belly.owner
|
||||
|
||||
var/inside_desc = "No description."
|
||||
if(owner.absorbed && inside_belly.absorbed_desc)
|
||||
inside_desc = inside_belly.absorbed_desc
|
||||
else if(inside_belly.desc)
|
||||
inside_desc = inside_belly.desc
|
||||
|
||||
if(inside_desc != "No description.")
|
||||
inside_desc = inside_belly.belly_format_string(inside_desc, owner, use_first_only = TRUE)
|
||||
|
||||
inside = list(
|
||||
"absorbed" = owner.absorbed,
|
||||
"belly_name" = inside_belly.name,
|
||||
"belly_mode" = inside_belly.digest_mode,
|
||||
"desc" = inside_desc,
|
||||
"pred" = pred,
|
||||
"ref" = "\ref[inside_belly]",
|
||||
"liq_lvl" = inside_belly.reagents.total_volume,
|
||||
"liq_reagent_type" = inside_belly.reagent_chosen,
|
||||
"liuq_name" = inside_belly.reagent_name,
|
||||
)
|
||||
|
||||
var/list/inside_contents = list()
|
||||
for(var/atom/movable/O in inside_belly)
|
||||
if(O == owner)
|
||||
continue
|
||||
|
||||
var/list/info = list(
|
||||
"name" = "[O]",
|
||||
"absorbed" = FALSE,
|
||||
"stat" = 0,
|
||||
"ref" = "\ref[O]",
|
||||
"outside" = FALSE,
|
||||
)
|
||||
if(show_pictures) //disables icon mode
|
||||
if(inside_belly.contents.len <= max_icon_content)
|
||||
icon_overflow = FALSE
|
||||
info["icon"] = cached_nom_icon(O)
|
||||
else
|
||||
icon_overflow = TRUE
|
||||
if(isliving(O))
|
||||
var/mob/living/M = O
|
||||
info["stat"] = M.stat
|
||||
if(M.absorbed)
|
||||
info["absorbed"] = TRUE
|
||||
UNTYPED_LIST_ADD(inside_contents, info)
|
||||
inside["contents"] = inside_contents
|
||||
return inside
|
||||
|
||||
/datum/vore_look/proc/get_host_mobtype(mob/owner)
|
||||
var/list/host_mobtype = list("is_cyborg" = FALSE, "is_vore_simple_mob" = FALSE)
|
||||
if(isrobot(owner))
|
||||
host_mobtype["is_cyborg"] = TRUE
|
||||
else if(istype(owner, /mob/living/simple_mob/vore)) //So far, this does nothing. But, creating this for future belly work
|
||||
host_mobtype["is_vore_simple_mob"] = TRUE
|
||||
return host_mobtype
|
||||
|
||||
/datum/vore_look/proc/get_selected_data(mob/owner)
|
||||
var/list/selected_list = null
|
||||
if(owner.vore_selected)
|
||||
var/obj/belly/selected = owner.vore_selected
|
||||
selected_list = list("belly_name" = selected.name)
|
||||
if(active_vore_tab == CONTROL_TAB)
|
||||
var/list/addons = list()
|
||||
for(var/flag_name in selected.mode_flag_list)
|
||||
UNTYPED_LIST_ADD(addons, list("label" = flag_name, "selection" = selected.mode_flags & selected.mode_flag_list[flag_name]))
|
||||
var/list/belly_mode_data = list(
|
||||
"mode" = selected.digest_mode,
|
||||
"item_mode" = selected.item_digest_mode,
|
||||
"addons" = addons,
|
||||
"name_length" = BELLIES_NAME_MAX,
|
||||
"name_min" = BELLIES_NAME_MIN,
|
||||
"mode_options" = host.vore_selected.digest_modes,
|
||||
"item_mode_options" = host.vore_selected.item_digest_modes,
|
||||
|
||||
)
|
||||
selected_list["belly_mode_data"] = belly_mode_data
|
||||
|
||||
if(active_vore_tab == DESCRIPTIONS_TAB)
|
||||
// Compile our displayed options
|
||||
var/list/displayed_options = list(
|
||||
VPANEL_DESCRIPTION_TAB,
|
||||
VPANEL_EXAMINE_TAB,
|
||||
VPANEL_TRASH_EATER_TAB
|
||||
)
|
||||
if(selected.message_mode || selected.escapable)
|
||||
displayed_options += VPANEL_STRUGGLE_TAB
|
||||
displayed_options += VPANEL_ESCAPE_TAB
|
||||
displayed_options += VPANEL_ESCAPE_ABSORBED_TAB
|
||||
if(selected.message_mode || (selected.escapable && (selected.transferlocation || selected.transferlocation_secondary)) || selected.autotransfer_enabled && (selected.autotransferlocation || selected.autotransferlocation_secondary))
|
||||
displayed_options += VPANEL_TRANSFER_TAB
|
||||
if(selected.message_mode || selected.escapable && (selected.digestchance || selected.absorbchance))
|
||||
displayed_options += VPANEL_INTERACTION_TAB
|
||||
if(selected.message_mode || selected.digest_mode == DM_DIGEST || selected.digest_mode == DM_SELECT || selected.digest_mode == DM_ABSORB || selected.digest_mode == DM_UNABSORB)
|
||||
displayed_options += VPANEL_BELLYMODE_TAB
|
||||
if(selected.message_mode || selected.emote_active)
|
||||
displayed_options += VPANEL_IDLE_TAB
|
||||
if(selected.message_mode || selected.show_fullness_messages)
|
||||
displayed_options += VPANEL_LIQUIDS_TAB
|
||||
|
||||
var/list/belly_description_data = list(
|
||||
"displayed_message_types" = compile_message_data(selected),
|
||||
"verb" = selected.vore_verb,
|
||||
"release_verb" = selected.release_verb,
|
||||
"message_mode" = selected.message_mode,
|
||||
"displayed_options" = displayed_options,
|
||||
"message_option" = message_option,
|
||||
"message_subtab" = message_subtab,
|
||||
"selected_message" = selected_message,
|
||||
"show_liq_fullness" = selected.show_fullness_messages,
|
||||
"emote_time" = selected.emote_time,
|
||||
"emote_active" = selected.emote_active,
|
||||
"entrance_logs" = selected.entrance_logs,
|
||||
"item_digest_logs" = selected.item_digest_logs,
|
||||
"name_min" = BELLIES_NAME_MIN,
|
||||
"name_length" = BELLIES_NAME_MAX,
|
||||
)
|
||||
selected_list["belly_description_data"] = belly_description_data
|
||||
|
||||
if(active_vore_tab == OPTIONS_TAB)
|
||||
var/list/silicon_control = list(
|
||||
"silicon_belly_overlay_preference" = selected.silicon_belly_overlay_preference,
|
||||
"belly_sprite_option_shown" = LAZYLEN(owner.vore_icon_bellies) >= 1 ? TRUE : FALSE,
|
||||
"belly_sprite_to_affect" = selected.belly_sprite_to_affect
|
||||
)
|
||||
var/list/belly_option_data = list(
|
||||
"can_taste" = selected.can_taste,
|
||||
"is_feedable" = selected.is_feedable,
|
||||
"nutrition_percent" = selected.nutrition_percent,
|
||||
"digest_brute" = selected.digest_brute,
|
||||
"digest_burn" = selected.digest_burn,
|
||||
"digest_oxy" = selected.digest_oxy,
|
||||
"digest_tox" = selected.digest_tox,
|
||||
"digest_clone" = selected.digest_clone,
|
||||
"digest_max" = selected.digest_max,
|
||||
"digest_free" = selected.get_unused_digestion_damage(),
|
||||
"bulge_size" = selected.bulge_size,
|
||||
"shrink_grow_size" = selected.shrink_grow_size,
|
||||
"contaminates" = selected.contaminates,
|
||||
"egg_type" = selected.egg_type,
|
||||
"egg_types" = GLOB.global_vore_egg_types,
|
||||
"egg_name" = selected.egg_name,
|
||||
"egg_size" = selected.egg_size,
|
||||
"recycling" = selected.recycling,
|
||||
"storing_nutrition" = selected.storing_nutrition,
|
||||
"selective_preference" = selected.selective_preference,
|
||||
"save_digest_mode" = selected.save_digest_mode,
|
||||
"eating_privacy_local" = selected.eating_privacy_local,
|
||||
"vorespawn_blacklist" = selected.vorespawn_blacklist,
|
||||
"vorespawn_whitelist" = selected.vorespawn_whitelist,
|
||||
"vorespawn_absorbed" = (global_flag_check(selected.vorespawn_absorbed, VS_FLAG_ABSORB_YES) + global_flag_check(selected.vorespawn_absorbed, VS_FLAG_ABSORB_PREY)),
|
||||
"private_struggle" = selected.private_struggle,
|
||||
"drainmode" = selected.drainmode,
|
||||
"drainmode_options" = selected.drainmodes,
|
||||
"mob_belly_controls" = silicon_control
|
||||
)
|
||||
if(selected.contaminates)
|
||||
belly_option_data += list(
|
||||
"contaminate_flavor" = selected.contamination_flavor,
|
||||
"contaminate_options" = GLOB.contamination_flavors,
|
||||
"contaminate_color" = selected.contamination_color,
|
||||
"contaminate_colors" = GLOB.contamination_colors
|
||||
)
|
||||
|
||||
selected_list["belly_option_data"] = belly_option_data
|
||||
|
||||
if(active_vore_tab == SOUNDS_TAB)
|
||||
var/list/belly_sound_data = list(
|
||||
"is_wet" = selected.is_wet,
|
||||
"wet_loop" = selected.wet_loop,
|
||||
"fancy" = selected.fancy_vore,
|
||||
"sound" = selected.vore_sound,
|
||||
"release_sound" = selected.release_sound,
|
||||
"sound_volume" = selected.sound_volume,
|
||||
"noise_freq" = selected.noise_freq,
|
||||
"min_voice_freq" = MIN_VOICE_FREQ,
|
||||
"max_voice_freq" = MAX_VOICE_FREQ,
|
||||
"vore_sound_list" = (selected.fancy_vore ? GLOB.fancy_vore_sounds : GLOB.classic_vore_sounds),
|
||||
"release_sound_list" = (selected.fancy_vore ? GLOB.fancy_release_sounds : GLOB.classic_release_sounds)
|
||||
)
|
||||
selected_list["belly_sound_data"] = belly_sound_data
|
||||
|
||||
if(active_vore_tab == VISUALS_TAB)
|
||||
var/list/belly_fullscreens
|
||||
if(selected.colorization_enabled)
|
||||
belly_fullscreens = icon_states('icons/mob/screen_full_vore_list.dmi') //Makes any icons inside of here selectable.
|
||||
else
|
||||
belly_fullscreens = icon_states('icons/mob/screen_full_vore.dmi') //Non colorable
|
||||
|
||||
var/list/vs_flags = list()
|
||||
for(var/flag_name in selected.vore_sprite_flag_list)
|
||||
UNTYPED_LIST_ADD(vs_flags, list("label" = flag_name, "selection" = selected.vore_sprite_flags & selected.vore_sprite_flag_list[flag_name]))
|
||||
|
||||
var/datum/category_group/underwear/UWC = global_underwear.categories_by_name[host.vore_selected.undergarment_chosen]
|
||||
var/list/undergarments
|
||||
if(UWC)
|
||||
undergarments = UWC.items
|
||||
|
||||
var/list/belly_visual_data = list(
|
||||
"belly_fullscreen" = selected.belly_fullscreen,
|
||||
"colorization_enabled" = selected.colorization_enabled,
|
||||
"belly_fullscreen_color" = selected.belly_fullscreen_color,
|
||||
"belly_fullscreen_color2" = selected.belly_fullscreen_color2,
|
||||
"belly_fullscreen_color3" = selected.belly_fullscreen_color3,
|
||||
"belly_fullscreen_color4" = selected.belly_fullscreen_color4,
|
||||
"belly_fullscreen_alpha" = selected.belly_fullscreen_alpha,
|
||||
"possible_fullscreens" = belly_fullscreens,
|
||||
"disable_hud" = selected.disable_hud,
|
||||
"vore_sprite_flags" = vs_flags,
|
||||
"affects_voresprite" = selected.affects_vore_sprites,
|
||||
"absorbed_voresprite" = selected.count_absorbed_prey_for_sprite,
|
||||
"absorbed_multiplier" = selected.absorbed_multiplier,
|
||||
"liquid_voresprite" = selected.count_liquid_for_sprite,
|
||||
"liquid_multiplier" = selected.liquid_multiplier,
|
||||
"item_voresprite" = selected.count_items_for_sprite,
|
||||
"item_multiplier" = selected.item_multiplier,
|
||||
"health_voresprite" = selected.health_impacts_size,
|
||||
"resist_animation" = selected.resist_triggers_animation,
|
||||
"voresprite_size_factor" = selected.size_factor_for_sprite,
|
||||
"belly_sprite_to_affect" = selected.belly_sprite_to_affect,
|
||||
"belly_sprite_options" = host.vore_icon_bellies,
|
||||
"undergarment_chosen" = selected.undergarment_chosen,
|
||||
"undergarment_if_none" = selected.undergarment_if_none || "None",
|
||||
"undergarment_options" = global_underwear.categories,
|
||||
"undergarment_options_if_none" = undergarments,
|
||||
"undergarment_color" = selected.undergarment_color,
|
||||
"tail_option_shown" = ishuman(owner),
|
||||
"tail_to_change_to" = selected.tail_to_change_to,
|
||||
"tail_sprite_options" = global.tail_styles_list
|
||||
)
|
||||
selected_list["belly_visual_data"] = belly_visual_data
|
||||
|
||||
if(active_vore_tab == INTERACTIONS_TAB)
|
||||
var/list/belly_interaction_data = list(
|
||||
"escapable" = selected.escapable,
|
||||
"interacts" = compile_interact_data(selected),
|
||||
"autotransfer_enabled" = selected.autotransfer_enabled,
|
||||
"autotransfer" = compile_autotransfer_data(selected)
|
||||
)
|
||||
selected_list["belly_interaction_data"] = belly_interaction_data
|
||||
|
||||
|
||||
var/list/selected_contents
|
||||
var/total_content_count = 0
|
||||
for(var/O in selected)
|
||||
total_content_count++
|
||||
if(active_vore_tab == CONTENTS_TAB)
|
||||
var/list/info = list(
|
||||
"name" = "[O]",
|
||||
"absorbed" = FALSE,
|
||||
"stat" = 0,
|
||||
"ref" = "\ref[O]",
|
||||
"outside" = TRUE,
|
||||
)
|
||||
if(show_pictures) //disables icon mode
|
||||
if(selected.contents.len <= max_icon_content)
|
||||
icon_overflow = FALSE
|
||||
info["icon"] = cached_nom_icon(O)
|
||||
else
|
||||
icon_overflow = TRUE
|
||||
|
||||
if(isliving(O))
|
||||
var/mob/living/M = O
|
||||
info["stat"] = M.stat
|
||||
if(M.absorbed)
|
||||
info["absorbed"] = TRUE
|
||||
LAZYADD(selected_contents, list(info))
|
||||
if(active_vore_tab == CONTENTS_TAB)
|
||||
selected_list["contents"] = selected_contents
|
||||
|
||||
selected_list["content_length"] = total_content_count
|
||||
|
||||
if(active_vore_tab == LIQUID_OPTIONS_TAB)
|
||||
// liquid belly options
|
||||
var/list/belly_liquid_data = list(
|
||||
"show_liq" = selected.show_liquids,
|
||||
"liq_interacts" = compile_liquid_interact_data(selected)
|
||||
)
|
||||
selected_list["belly_liquid_data"] = belly_liquid_data
|
||||
|
||||
return selected_list
|
||||
|
||||
#undef CONTROL_TAB
|
||||
#undef DESCRIPTIONS_TAB
|
||||
#undef OPTIONS_TAB
|
||||
#undef SOUNDS_TAB
|
||||
#undef VISUALS_TAB
|
||||
#undef INTERACTIONS_TAB
|
||||
#undef CONTENTS_TAB
|
||||
#undef LIQUID_OPTIONS_TAB
|
||||
@@ -0,0 +1,759 @@
|
||||
#define DEFAULT_MESSAGE "Default"
|
||||
#define ABSORBED_MESSAGE "Absorbed"
|
||||
#define WITH_PREY "With Prey"
|
||||
#define WITH_ABSORBED_PREY "With Absorbed Prey"
|
||||
#define TRASH_EAT "Eat"
|
||||
#define TRASH_EXPEL "Expel"
|
||||
#define OUTSIDE_MESSAGE "Outside"
|
||||
#define INSIDE_MESSAGE "Inside"
|
||||
#define TO_YOU "To You"
|
||||
#define TO_PREY "To Prey"
|
||||
#define ATTEMPT_MESSAGE "Attempt"
|
||||
#define SUCCESS_MESSAGE "Success"
|
||||
#define ITEM_MESSAGE "Item"
|
||||
#define FAIL_MESSAGE "Fail"
|
||||
#define PRIMARY_MESSAGE "Primary"
|
||||
#define SECONARY_MESSAGE "Secondary"
|
||||
#define PRIMARY_AUTO_MESSAGE "Primary (Auto)"
|
||||
#define SECONARY_AUTO_MESSAGE "Secondary (Auto)"
|
||||
#define DIGEST_MESSAGE "Digest"
|
||||
#define HOLD_MESSAGE "Hold"
|
||||
#define HOLDABSORBED_MESSAGE "Hold (Absorbed)"
|
||||
#define ABSORB_MESSAGE "Absorb"
|
||||
#define HEAL_MESSAGE "Heal"
|
||||
#define DRAIN_MESSAGE "Drain"
|
||||
#define STEAL_MESSAGE "Steal"
|
||||
#define EGG_MESSAGE "Egg"
|
||||
#define SHRINK_MESSAGE "Shrink"
|
||||
#define GROW_MESSAGE "Grow"
|
||||
#define UNABSORB_MESSAGE "Unabsorb"
|
||||
#define LIQUID0 "Liquid 0-20%"
|
||||
#define LIQUID20 "Liquid 20-40%"
|
||||
#define LIQUID40 "Liquid 40-60%"
|
||||
#define LIQUID60 "Liquid 60-80%"
|
||||
#define LIQUID80 "Liquid 80-100%"
|
||||
|
||||
/datum/vore_look/proc/compile_message_data(obj/belly/selected)
|
||||
if(message_option == VPANEL_DESCRIPTION_TAB)
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list(DEFAULT_MESSAGE, ABSORBED_MESSAGE)
|
||||
)
|
||||
if(!selected_message)
|
||||
selected_message = DEFAULT_MESSAGE
|
||||
if(selected_message == DEFAULT_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_DESC_MAX
|
||||
tab_data["active_message"] = selected.desc
|
||||
tab_data["set_action"] = BELLY_DESCRIPTION_MESSAGE
|
||||
tab_data["tooltip"] = "Displayed to prey upon consumption."
|
||||
return tab_data
|
||||
if(selected_message == ABSORBED_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_DESC_MAX
|
||||
tab_data["active_message"] = selected.absorbed_desc
|
||||
tab_data["set_action"] = BELLY_DESCRIPTION_MESSAGE_ABSROED
|
||||
tab_data["tooltip"] = "Displayed to prey after absorption."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_EXAMINE_TAB)
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list(WITH_PREY, WITH_ABSORBED_PREY)
|
||||
)
|
||||
if(!selected_message)
|
||||
selected_message = WITH_PREY
|
||||
if(selected_message == WITH_PREY)
|
||||
tab_data["max_length"] = BELLIES_EXAMINE_MAX
|
||||
tab_data["active_message"] = selected.examine_messages
|
||||
tab_data["set_action"] = EXAMINES
|
||||
tab_data["tooltip"] = "Displayed to nearby players during examination when the vorgan is full."
|
||||
return tab_data
|
||||
if(selected_message == WITH_ABSORBED_PREY)
|
||||
tab_data["max_length"] = BELLIES_EXAMINE_MAX
|
||||
tab_data["active_message"] = selected.examine_messages_absorbed
|
||||
tab_data["set_action"] = EXAMINES_ABSORBED
|
||||
tab_data["tooltip"] = "Displayed to nearby players during examination when the vorgan contains absorbed prey."
|
||||
tab_data["button_label"] = "Display Absorbed Examine"
|
||||
tab_data["button_action"] = "b_display_absorbed_examine"
|
||||
tab_data["button_data"] = selected.display_absorbed_examine
|
||||
tab_data["button_tooltip"] = "the absorbed description on examine." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_TRASH_EATER_TAB)
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list(TRASH_EAT, TRASH_EXPEL)
|
||||
)
|
||||
if(!selected_message)
|
||||
selected_message = TRASH_EAT
|
||||
if(selected_message == TRASH_EAT)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.trash_eater_in
|
||||
tab_data["set_action"] = BELLY_TRASH_EATER_IN
|
||||
tab_data["tooltip"] = "Displayed to nearby players when you ingest trash items."
|
||||
return tab_data
|
||||
if(selected_message == TRASH_EXPEL)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.trash_eater_out
|
||||
tab_data["set_action"] = BELLY_TRASH_EATER_OUT
|
||||
tab_data["tooltip"] = "Displayed to nearby players when you expel trash items."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_STRUGGLE_TAB)
|
||||
var/list/tab_data = list(
|
||||
"subtypes" = list(DEFAULT_MESSAGE, ABSORBED_MESSAGE)
|
||||
)
|
||||
if(!message_subtab)
|
||||
message_subtab = DEFAULT_MESSAGE
|
||||
if(message_subtab == DEFAULT_MESSAGE)
|
||||
tab_data["possible_messages"] = list(OUTSIDE_MESSAGE, INSIDE_MESSAGE)
|
||||
if(!selected_message)
|
||||
selected_message = OUTSIDE_MESSAGE
|
||||
if(selected_message == OUTSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.struggle_messages_outside
|
||||
tab_data["set_action"] = STRUGGLE_OUTSIDE
|
||||
tab_data["tooltip"] = "Displayed to nearby players when your prey resists."
|
||||
return tab_data
|
||||
if(selected_message == INSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.struggle_messages_inside
|
||||
tab_data["set_action"] = STRUGGLE_INSIDE
|
||||
tab_data["tooltip"] = "Displayed to your prey when they resists."
|
||||
return tab_data
|
||||
if(message_subtab == ABSORBED_MESSAGE)
|
||||
tab_data["possible_messages"] = list(OUTSIDE_MESSAGE, INSIDE_MESSAGE)
|
||||
if(!selected_message)
|
||||
selected_message = OUTSIDE_MESSAGE
|
||||
if(selected_message == OUTSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.absorbed_struggle_messages_outside
|
||||
tab_data["set_action"] = ABSORBED_STRUGGLE_OUSIDE
|
||||
tab_data["tooltip"] = "Displayed to nearby players when your absorb prey resists."
|
||||
return tab_data
|
||||
if(selected_message == INSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.absorbed_struggle_messages_inside
|
||||
tab_data["set_action"] = ABSORBED_STRUGGLE_INSIDE
|
||||
tab_data["tooltip"] = "Displayed to your prey when absorbed prey resists."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_ESCAPE_TAB)
|
||||
var/list/tab_data = list(
|
||||
"subtypes" = list(ITEM_MESSAGE, ATTEMPT_MESSAGE, FAIL_MESSAGE)
|
||||
)
|
||||
if(selected.message_mode || selected.escapechance)
|
||||
tab_data["subtypes"] += SUCCESS_MESSAGE
|
||||
if(!message_subtab)
|
||||
message_subtab = ATTEMPT_MESSAGE
|
||||
if(message_subtab == ATTEMPT_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_attempt_messages_prey
|
||||
tab_data["set_action"] = ESCAPE_ATTEMPT_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they trigger an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_attempt_messages_owner
|
||||
tab_data["set_action"] = ESCAPE_ATTEMPT_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey triggers an escape attempt."
|
||||
return tab_data
|
||||
if(message_subtab == SUCCESS_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU, OUTSIDE_MESSAGE)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_messages_prey
|
||||
tab_data["set_action"] = ESCAPE_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they succeed an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_messages_owner
|
||||
tab_data["set_action"] = ESCAPE_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey succeeds an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == OUTSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_messages_outside
|
||||
tab_data["set_action"] = ESCAPE_OUTSIDE
|
||||
tab_data["tooltip"] = "Displayed to nearby players when your prey succeeds an escape attempt."
|
||||
return tab_data
|
||||
if(message_subtab == ITEM_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU, OUTSIDE_MESSAGE)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_item_messages_prey
|
||||
tab_data["set_action"] = ESCAPE_ITEM_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they manage to push an item out of your belly."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_item_messages_owner
|
||||
tab_data["set_action"] = ESCAPE_ITEM_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey manages to push an item out of your belly."
|
||||
return tab_data
|
||||
if(selected_message == OUTSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_item_messages_outside
|
||||
tab_data["set_action"] = ESCAPE_ITEM_OUTSIDE
|
||||
tab_data["tooltip"] = "Displayed to nearby players when your prey manages to push an item out of your belly."
|
||||
return tab_data
|
||||
if(message_subtab == FAIL_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_fail_messages_prey
|
||||
tab_data["set_action"] = ESCAPE_FAIL_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they fail an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_fail_messages_owner
|
||||
tab_data["set_action"] = ESCAPE_FAIL_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey fails an escape attempt."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_ESCAPE_ABSORBED_TAB)
|
||||
var/list/tab_data = list(
|
||||
"subtypes" = list(ATTEMPT_MESSAGE, FAIL_MESSAGE)
|
||||
)
|
||||
if(selected.message_mode || selected.escapechance_absorbed)
|
||||
tab_data["subtypes"] += SUCCESS_MESSAGE
|
||||
if(!message_subtab)
|
||||
message_subtab = ATTEMPT_MESSAGE
|
||||
if(message_subtab == ATTEMPT_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_attempt_absorbed_messages_prey
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_ATTEMPT_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they trigger an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_attempt_absorbed_messages_owner
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_ATTEMPT_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey triggers an escape attempt."
|
||||
return tab_data
|
||||
if(message_subtab == SUCCESS_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU, OUTSIDE_MESSAGE)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_absorbed_messages_prey
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_PREY
|
||||
tab_data["tooltip"] = "Displayed to your absorbed prey when they succeed an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_absorbed_messages_owner
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your absorbed prey succeeds an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == OUTSIDE_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_absorbed_messages_outside
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_OUTSIDE
|
||||
tab_data["tooltip"] = "Displayed to nearby players when your absorbed prey succeeds an escape attempt."
|
||||
return tab_data
|
||||
if(message_subtab == FAIL_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_fail_absorbed_messages_prey
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_FAIL_PREY
|
||||
tab_data["tooltip"] = "Displayed to your absorbed prey when they fail an escape attempt."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.escape_fail_absorbed_messages_owner
|
||||
tab_data["set_action"] = ABSORBED_ESCAPE_FAIL_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your absorbed prey fails an escape attempt."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_TRANSFER_TAB)
|
||||
var/list/tab_data = list(
|
||||
"subtypes" = list()
|
||||
)
|
||||
if(selected.message_mode || selected.transferlocation)
|
||||
tab_data["subtypes"] += PRIMARY_MESSAGE
|
||||
if(selected.message_mode || selected.transferlocation_secondary)
|
||||
tab_data["subtypes"] += SECONARY_MESSAGE
|
||||
if(selected.message_mode || selected.autotransferlocation)
|
||||
tab_data["subtypes"] += PRIMARY_AUTO_MESSAGE
|
||||
if(selected.message_mode || selected.autotransferlocation_secondary)
|
||||
tab_data["subtypes"] += SECONARY_AUTO_MESSAGE
|
||||
if(!message_subtab)
|
||||
message_subtab = PRIMARY_MESSAGE
|
||||
if(message_subtab == PRIMARY_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.primary_transfer_messages_prey
|
||||
tab_data["set_action"] = PRIMARY_TRANSFER_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get transfered to the primary transfer location."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.primary_transfer_messages_owner
|
||||
tab_data["set_action"] = PRIMARY_TRANSFER_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets transfered to the primary transfer location."
|
||||
return tab_data
|
||||
if(message_subtab == SECONARY_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.secondary_transfer_messages_prey
|
||||
tab_data["set_action"] = SECONDARY_TRANSFER_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get transfered to the secondary transfer location."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.secondary_transfer_messages_owner
|
||||
tab_data["set_action"] = SECONDARY_TRANSFER_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets transfered to the secondary transfer location."
|
||||
return tab_data
|
||||
if(message_subtab == PRIMARY_AUTO_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.primary_autotransfer_messages_prey
|
||||
tab_data["set_action"] = PRIMARY_AUTO_TRANSFER_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get transfered to the primary auto transfer location."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.primary_autotransfer_messages_owner
|
||||
tab_data["set_action"] = PRIMARY_AUTO_TRANSFER_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets transfered to the primary auto transfer location."
|
||||
return tab_data
|
||||
if(message_subtab == SECONARY_AUTO_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.secondary_autotransfer_messages_prey
|
||||
tab_data["set_action"] = SECONDARY_AUTO_TRANSFER_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get transfered to the secondary auto transfer location."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.secondary_autotransfer_messages_owner
|
||||
tab_data["set_action"] = SECONDARY_AUTO_TRANSFER_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets transfered to the secondary auto transfer location."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_INTERACTION_TAB)
|
||||
var/list/tab_data = list(
|
||||
"subtypes" = list()
|
||||
)
|
||||
if(selected.message_mode || selected.digestchance)
|
||||
tab_data["subtypes"] += DIGEST_MESSAGE
|
||||
if(selected.message_mode || selected.absorbchance)
|
||||
tab_data["subtypes"] += ABSORB_MESSAGE
|
||||
if(!message_subtab)
|
||||
message_subtab = DIGEST_MESSAGE
|
||||
if(message_subtab == DIGEST_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.digest_chance_messages_prey
|
||||
tab_data["set_action"] = DIGEST_CHANCE_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when their struggles trigger digest mode."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.digest_chance_messages_owner
|
||||
tab_data["set_action"] = DIGEST_CHANCE_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey's struggles trigger digest mode."
|
||||
return tab_data
|
||||
if(message_subtab == ABSORB_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.absorb_chance_messages_prey
|
||||
tab_data["set_action"] = ABSORB_CHANCE_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when their struggles trigger absorb mode."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.absorb_chance_messages_owner
|
||||
tab_data["set_action"] = ABSORB_CHANCE_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey's struggles trigger absorb mode."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_BELLYMODE_TAB)
|
||||
var/list/tab_data = list(
|
||||
"subtypes" = list()
|
||||
)
|
||||
if(selected.message_mode || selected.digest_mode == DM_DIGEST || DM_SELECT)
|
||||
tab_data["subtypes"] += DIGEST_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_ABSORB || DM_SELECT)
|
||||
tab_data["subtypes"] += ABSORB_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_UNABSORB)
|
||||
tab_data["subtypes"] += UNABSORB_MESSAGE
|
||||
if(!message_subtab)
|
||||
message_subtab = DIGEST_MESSAGE
|
||||
if(message_subtab == DIGEST_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.digest_messages_prey
|
||||
tab_data["set_action"] = DIGEST_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get digested."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.digest_messages_owner
|
||||
tab_data["set_action"] = DIGEST_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets digested."
|
||||
return tab_data
|
||||
if(message_subtab == ABSORBED_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.absorb_messages_prey
|
||||
tab_data["set_action"] = ABSORB_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get absorbed."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.absorb_messages_owner
|
||||
tab_data["set_action"] = ABSORB_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets absorbed."
|
||||
if(message_subtab == UNABSORB_MESSAGE)
|
||||
tab_data["possible_messages"] = list(TO_PREY, TO_YOU)
|
||||
if(!selected_message)
|
||||
selected_message = TO_PREY
|
||||
if(selected_message == TO_PREY)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.unabsorb_messages_prey
|
||||
tab_data["set_action"] = UNABSORBS_PREY
|
||||
tab_data["tooltip"] = "Displayed to your prey when they get unabsorbed."
|
||||
return tab_data
|
||||
if(selected_message == TO_YOU)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = selected.unabsorb_messages_owner
|
||||
tab_data["set_action"] = UNABSORBS_OWNER
|
||||
tab_data["tooltip"] = "Displayed to you when your prey gets unabsorbed."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_IDLE_TAB)
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list()
|
||||
)
|
||||
if(selected.message_mode || selected.digest_mode == DM_DIGEST || selected.digest_mode == DM_SELECT)
|
||||
tab_data["possible_messages"] += DIGEST_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_HOLD || selected.digest_mode == DM_SELECT)
|
||||
tab_data["possible_messages"] += HOLD_MESSAGE
|
||||
tab_data["possible_messages"] += HOLDABSORBED_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_ABSORB || selected.digest_mode == DM_SELECT)
|
||||
tab_data["possible_messages"] += ABSORB_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_HEAL)
|
||||
tab_data["possible_messages"] += HEAL_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_DRAIN || selected.digest_mode == DM_SELECT)
|
||||
tab_data["possible_messages"] += DRAIN_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_SIZE_STEAL)
|
||||
tab_data["possible_messages"] += STEAL_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_EGG)
|
||||
tab_data["possible_messages"] += EGG_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_SHRINK)
|
||||
tab_data["possible_messages"] += SHRINK_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_GROW)
|
||||
tab_data["possible_messages"] += GROW_MESSAGE
|
||||
if(selected.message_mode || selected.digest_mode == DM_UNABSORB)
|
||||
tab_data["possible_messages"] += UNABSORB_MESSAGE
|
||||
if(!selected_message)
|
||||
selected_message = DIGEST_MESSAGE
|
||||
if(selected_message == DIGEST_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_DIGEST])
|
||||
tab_data["set_action"] = BELLY_MODE_DIGEST
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting digested."
|
||||
return tab_data
|
||||
if(selected_message == HOLD_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_HOLD])
|
||||
tab_data["set_action"] = BELLY_MODE_HOLD
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is being held."
|
||||
return tab_data
|
||||
if(selected_message == HOLDABSORBED_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_HOLD_ABSORBED])
|
||||
tab_data["set_action"] = BELLY_MODE_HOLD_ABSORB
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your absorbed prey is being held."
|
||||
return tab_data
|
||||
if(selected_message == ABSORB_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_ABSORB])
|
||||
tab_data["set_action"] = BELLY_MODE_ABSORB
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting absorbed."
|
||||
return tab_data
|
||||
if(selected_message == HEAL_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_HEAL])
|
||||
tab_data["set_action"] = BELLY_MODE_HEAL
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting healed."
|
||||
return tab_data
|
||||
if(selected_message == DRAIN_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_DRAIN])
|
||||
tab_data["set_action"] = BELLY_MODE_DRAIN
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting drained."
|
||||
return tab_data
|
||||
if(selected_message == STEAL_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_SIZE_STEAL])
|
||||
tab_data["set_action"] = BELLY_MODE_STEAL
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey's size is stolen."
|
||||
return tab_data
|
||||
if(selected_message == EGG_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_EGG])
|
||||
tab_data["set_action"] = BELLY_MODE_EGG
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting getting encased in an egg."
|
||||
return tab_data
|
||||
if(selected_message == SHRINK_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_SHRINK])
|
||||
tab_data["set_action"] = BELLY_MODE_SHRINK
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting shrunk."
|
||||
return tab_data
|
||||
if(selected_message == GROW_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_GROW])
|
||||
tab_data["set_action"] = BELLY_MODE_GROW
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting grown."
|
||||
return tab_data
|
||||
if(selected_message == UNABSORB_MESSAGE)
|
||||
tab_data["max_length"] = BELLIES_IDLE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.emote_lists[DM_UNABSORB])
|
||||
tab_data["set_action"] = BELLY_MODE_UNABSORB
|
||||
tab_data["tooltip"] = "Cyclic idle messages while your prey is getting unabsorbed."
|
||||
return tab_data
|
||||
|
||||
if(message_option == VPANEL_LIQUIDS_TAB)
|
||||
var/list/tab_data = list(
|
||||
"possible_messages" = list(LIQUID0, LIQUID20, LIQUID40, LIQUID60, LIQUID80)
|
||||
)
|
||||
if(!selected_message)
|
||||
selected_message = LIQUID0
|
||||
if(selected_message == LIQUID0)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.fullness1_messages)
|
||||
tab_data["set_action"] = BELLY_LIQUID_MESSAGE1
|
||||
tab_data["tooltip"] = "Displayed on examine when the belly contains 0 to 20% of liquids."
|
||||
tab_data["button_label"] = "Display Fullness 0-20%"
|
||||
tab_data["button_action"] = "b_liq_msg_toggle1"
|
||||
tab_data["button_data"] = selected.liquid_fullness1_messages
|
||||
tab_data["button_tooltip"] = "the 0-20% examine description." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
if(selected_message == LIQUID20)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.fullness2_messages)
|
||||
tab_data["set_action"] = BELLY_LIQUID_MESSAGE2
|
||||
tab_data["tooltip"] = "Displayed on examine when the belly contains 20 to 40% of liquids."
|
||||
tab_data["button_label"] = "Display Fullness 20-40%"
|
||||
tab_data["button_action"] = "b_liq_msg_toggle2"
|
||||
tab_data["button_data"] = selected.liquid_fullness2_messages
|
||||
tab_data["button_tooltip"] = "the 20-40% examine description." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
if(selected_message == LIQUID40)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.fullness3_messages)
|
||||
tab_data["set_action"] = BELLY_LIQUID_MESSAGE3
|
||||
tab_data["tooltip"] = "Displayed on examine when the belly contains 40 to 60% of liquids."
|
||||
tab_data["button_label"] = "Display Fullness 40-60%"
|
||||
tab_data["button_action"] = "b_liq_msg_toggle3"
|
||||
tab_data["button_data"] = selected.liquid_fullness3_messages
|
||||
tab_data["button_tooltip"] = "the 40-60% examine description." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
if(selected_message == LIQUID60)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.fullness4_messages)
|
||||
tab_data["set_action"] = BELLY_LIQUID_MESSAGE4
|
||||
tab_data["tooltip"] = "Displayed on examine when the belly contains 60 to 80% of liquids."
|
||||
tab_data["button_label"] = "Display Fullness 60-80%"
|
||||
tab_data["button_action"] = "b_liq_msg_toggle4"
|
||||
tab_data["button_data"] = selected.liquid_fullness4_messages
|
||||
tab_data["button_tooltip"] = "the 60-80% examine description." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
if(selected_message == LIQUID80)
|
||||
tab_data["max_length"] = BELLIES_MESSAGE_MAX
|
||||
tab_data["active_message"] = SANITIZE_LIST(selected.fullness5_messages)
|
||||
tab_data["set_action"] = BELLY_LIQUID_MESSAGE5
|
||||
tab_data["tooltip"] = "Displayed on examine when the belly contains 80 to 100% of liquids."
|
||||
tab_data["button_label"] = "Display Fullness 80-100%"
|
||||
tab_data["button_action"] = "b_liq_msg_toggle5"
|
||||
tab_data["button_data"] = selected.liquid_fullness5_messages
|
||||
tab_data["button_tooltip"] = "the 80-100% examine description." // those will automatically be preceeded by Enables / Disables!
|
||||
return tab_data
|
||||
|
||||
|
||||
/datum/vore_look/proc/compile_interact_data(obj/belly/selected)
|
||||
var/list/interact_data = list()
|
||||
if(selected.escapable)
|
||||
interact_data += list(
|
||||
"escapechance" = selected.escapechance,
|
||||
"escapechance_absorbed" = selected.escapechance_absorbed,
|
||||
"escapetime" = selected.escapetime,
|
||||
"transferchance" = selected.transferchance,
|
||||
"transferlocation" = selected.transferlocation,
|
||||
"transferchance_secondary" = selected.transferchance_secondary,
|
||||
"transferlocation_secondary" = selected.transferlocation_secondary,
|
||||
"absorbchance" = selected.absorbchance,
|
||||
"digestchance" = selected.digestchance,
|
||||
"belchchance" = selected.belchchance
|
||||
)
|
||||
|
||||
return interact_data
|
||||
|
||||
/datum/vore_look/proc/compile_autotransfer_data(obj/belly/selected)
|
||||
var/list/autotransfer_data = list()
|
||||
if(selected.autotransfer_enabled)
|
||||
//auto-transfer flags
|
||||
var/list/at_whitelist = list()
|
||||
var/list/at_secondary_whitelist = list()
|
||||
var/list/at_blacklist = list()
|
||||
var/list/at_secondary_blacklist = list()
|
||||
for(var/flag_name in selected.autotransfer_flags_list)
|
||||
UNTYPED_LIST_ADD(at_whitelist, list("label" = flag_name, "selection" = selected.autotransfer_whitelist & selected.autotransfer_flags_list[flag_name]))
|
||||
UNTYPED_LIST_ADD(at_blacklist, list("label" = flag_name, "selection" = selected.autotransfer_blacklist & selected.autotransfer_flags_list[flag_name]))
|
||||
UNTYPED_LIST_ADD(at_secondary_whitelist, list("label" = flag_name, "selection" = selected.autotransfer_secondary_whitelist & selected.autotransfer_flags_list[flag_name]))
|
||||
UNTYPED_LIST_ADD(at_secondary_blacklist, list("label" = flag_name, "selection" = selected.autotransfer_secondary_blacklist & selected.autotransfer_flags_list[flag_name]))
|
||||
var/list/at_whitelist_items = list()
|
||||
var/list/at_blacklist_items = list()
|
||||
var/list/at_secondary_whitelist_items = list()
|
||||
var/list/at_secondary_blacklist_items = list()
|
||||
for(var/flag_name in selected.autotransfer_flags_list_items)
|
||||
UNTYPED_LIST_ADD(at_whitelist_items, list("label" = flag_name, "selection" = selected.autotransfer_whitelist_items & selected.autotransfer_flags_list_items[flag_name]))
|
||||
UNTYPED_LIST_ADD(at_blacklist_items, list("label" = flag_name, "selection" = selected.autotransfer_blacklist_items & selected.autotransfer_flags_list_items[flag_name]))
|
||||
UNTYPED_LIST_ADD(at_secondary_whitelist_items, list("label" = flag_name, "selection" = selected.autotransfer_secondary_whitelist_items & selected.autotransfer_flags_list_items[flag_name]))
|
||||
UNTYPED_LIST_ADD(at_secondary_blacklist_items, list("label" = flag_name, "selection" = selected.autotransfer_secondary_blacklist_items & selected.autotransfer_flags_list_items[flag_name]))
|
||||
|
||||
var/list/primary_transfer = list(
|
||||
"autotransferchance" = selected.autotransferchance,
|
||||
"autotransferlocation" = selected.autotransferlocation,
|
||||
"autotransferextralocation" = selected.autotransferextralocation,
|
||||
"autotransfer_whitelist" = at_whitelist,
|
||||
"autotransfer_blacklist" = at_blacklist,
|
||||
"autotransfer_whitelist_items" = at_whitelist_items,
|
||||
"autotransfer_blacklist_items" = at_blacklist_items
|
||||
)
|
||||
var/list/secondary_transfer = list(
|
||||
"autotransferchance" = selected.autotransferchance_secondary,
|
||||
"autotransferlocation" = selected.autotransferlocation_secondary,
|
||||
"autotransferextralocation" = selected.autotransferextralocation_secondary,
|
||||
"autotransfer_whitelist" = at_secondary_whitelist,
|
||||
"autotransfer_blacklist" = at_secondary_blacklist,
|
||||
"autotransfer_whitelist_items" = at_secondary_whitelist_items,
|
||||
"autotransfer_blacklist_items" = at_secondary_blacklist_items
|
||||
)
|
||||
|
||||
autotransfer_data += list(
|
||||
"autotransferwait" = selected.autotransferwait,
|
||||
"autotransfer_min_amount" = selected.autotransfer_min_amount,
|
||||
"autotransfer_max_amount" = selected.autotransfer_max_amount,
|
||||
"primary_transfer" = primary_transfer,
|
||||
"secondary_transfer" = secondary_transfer
|
||||
)
|
||||
return autotransfer_data
|
||||
|
||||
/datum/vore_look/proc/compile_liquid_interact_data(obj/belly/selected)
|
||||
var/list/liq_interacts = list()
|
||||
if(selected.show_liquids)
|
||||
var/list/liquid_addon_list = list()
|
||||
for(var/flag_name in selected.reagent_mode_flag_list)
|
||||
UNTYPED_LIST_ADD(liquid_addon_list, list("label" = flag_name, "selection" = selected.reagent_mode_flags & selected.reagent_mode_flag_list[flag_name]))
|
||||
|
||||
liq_interacts += list(
|
||||
"liq_reagent_gen" = selected.reagentbellymode,
|
||||
"liq_reagent_type" = selected.reagent_chosen,
|
||||
"liq_reagent_types" = selected.reagent_choices,
|
||||
"liq_reagent_name" = selected.reagent_name,
|
||||
"liq_custom_name_max" = BELLIES_NAME_MAX,
|
||||
"liq_custom_name_min" = BELLIES_NAME_MIN,
|
||||
"liq_reagent_transfer_verb" = selected.reagent_transfer_verb,
|
||||
"liq_reagent_nutri_rate" = selected.gen_time,
|
||||
"liq_reagent_capacity" = selected.custom_max_volume,
|
||||
"liq_sloshing" = selected.vorefootsteps_sounds,
|
||||
"liq_reagent_addons" = liquid_addon_list,
|
||||
"custom_reagentcolor" = (selected.custom_reagentcolor ? selected.custom_reagentcolor : selected.reagentcolor),
|
||||
"custom_reagentalpha" = selected.custom_reagentalpha,
|
||||
"liquid_overlay" = selected.liquid_overlay,
|
||||
"max_liquid_level" = selected.max_liquid_level,
|
||||
"reagent_touches" = selected.reagent_touches,
|
||||
"mush_overlay" = selected.mush_overlay,
|
||||
"mush_color" = selected.mush_color,
|
||||
"mush_alpha" = selected.mush_alpha,
|
||||
"max_mush" = selected.max_mush,
|
||||
"min_mush" = selected.min_mush,
|
||||
"item_mush_val" = selected.item_mush_val,
|
||||
"metabolism_overlay" = selected.metabolism_overlay,
|
||||
"metabolism_mush_ratio" = selected.metabolism_mush_ratio,
|
||||
"max_ingested" = selected.max_ingested,
|
||||
"custom_ingested_color" = (selected.custom_ingested_color ? selected.custom_ingested_color : "#3f6088"),
|
||||
"custom_ingested_alpha" = selected.custom_ingested_alpha
|
||||
)
|
||||
return liq_interacts
|
||||
|
||||
#undef DEFAULT_MESSAGE
|
||||
#undef ABSORBED_MESSAGE
|
||||
#undef WITH_PREY
|
||||
#undef WITH_ABSORBED_PREY
|
||||
#undef TRASH_EAT
|
||||
#undef TRASH_EXPEL
|
||||
#undef OUTSIDE_MESSAGE
|
||||
#undef INSIDE_MESSAGE
|
||||
#undef TO_YOU
|
||||
#undef TO_PREY
|
||||
#undef ATTEMPT_MESSAGE
|
||||
#undef SUCCESS_MESSAGE
|
||||
#undef ITEM_MESSAGE
|
||||
#undef FAIL_MESSAGE
|
||||
#undef PRIMARY_MESSAGE
|
||||
#undef SECONARY_MESSAGE
|
||||
#undef PRIMARY_AUTO_MESSAGE
|
||||
#undef SECONARY_AUTO_MESSAGE
|
||||
#undef DIGEST_MESSAGE
|
||||
#undef HOLD_MESSAGE
|
||||
#undef HOLDABSORBED_MESSAGE
|
||||
#undef ABSORB_MESSAGE
|
||||
#undef HEAL_MESSAGE
|
||||
#undef DRAIN_MESSAGE
|
||||
#undef STEAL_MESSAGE
|
||||
#undef EGG_MESSAGE
|
||||
#undef SHRINK_MESSAGE
|
||||
#undef GROW_MESSAGE
|
||||
#undef UNABSORB_MESSAGE
|
||||
#undef LIQUID0
|
||||
#undef LIQUID20
|
||||
#undef LIQUID40
|
||||
#undef LIQUID60
|
||||
#undef LIQUID80
|
||||
@@ -198,7 +198,7 @@
|
||||
|
||||
// Allows to adjust the interior of the soulcatcher
|
||||
/obj/soulgem/proc/adjust_interior(var/new_flavor)
|
||||
new_flavor = sanitize(new_flavor, MAX_MESSAGE_LEN * 2)
|
||||
new_flavor = sanitize(new_flavor, VORE_SC_DESC_MAX, FALSE, TRUE, FALSE)
|
||||
inside_flavor = new_flavor
|
||||
notify_holder("Updating environment...")
|
||||
for(var/mob/living/carbon/brain/caught_soul/vore/CS as anything in brainmobs)
|
||||
@@ -225,26 +225,27 @@
|
||||
|
||||
// Sets the custom messages depending on the input
|
||||
/obj/soulgem/proc/set_custom_message(var/message, var/target)
|
||||
message = sanitize(message, MAX_MESSAGE_LEN / 4)
|
||||
message = sanitize(message, VORE_SC_MAX, FALSE, TRUE, FALSE)
|
||||
switch(target)
|
||||
if("capture")
|
||||
if(SC_CAPTURE_MEESAGE)
|
||||
capture_message = message
|
||||
if("transit")
|
||||
if(SC_TRANSIT_MESSAGE)
|
||||
transit_message = message
|
||||
if("release")
|
||||
if(SC_RELEASE_MESSAGE)
|
||||
release_message = message
|
||||
if("transfer")
|
||||
if(SC_TRANSFERE_MESSAGE)
|
||||
transfer_message = message
|
||||
if("delete")
|
||||
if(SC_DELETE_MESSAGE)
|
||||
delete_message = message
|
||||
|
||||
// Allows to rename the soulgem
|
||||
/obj/soulgem/proc/rename(var/new_name)
|
||||
if(length(new_name) < 3 || length(new_name) > 60)
|
||||
to_chat(owner, span_warning("Your soulcatcher's name needs to be between 3 and 60 characters long!"))
|
||||
return
|
||||
new_name = sanitize(new_name, 60)
|
||||
return FALSE
|
||||
new_name = sanitize(new_name, 60, FALSE, TRUE, FALSE)
|
||||
name = new_name
|
||||
return TRUE
|
||||
|
||||
// Toggles the given flag
|
||||
/obj/soulgem/proc/toggle_setting(var/flag)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -154,7 +154,6 @@
|
||||
new_mob.ooc_notes_dislikes = ooc_notes_dislikes
|
||||
new_mob.appendage_color = appendage_color
|
||||
new_mob.appendage_alt_setting = appendage_alt_setting
|
||||
new_mob.text_warnings = text_warnings
|
||||
|
||||
VORE_PREF_TRANSFER(new_mob, src)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^3.2.0"
|
||||
"tgui-core": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.0",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^3.2.0",
|
||||
"tgui-core": "^4.0.1",
|
||||
"tgui-dev-server": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui": "workspace:*",
|
||||
"tgui-core": "^3.2.0"
|
||||
"tgui-core": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.0",
|
||||
|
||||
@@ -102,7 +102,7 @@ export function AlertModal(props) {
|
||||
<Window.Content onKeyDown={keyDownHandler}>
|
||||
<Section fill>
|
||||
<Stack fill vertical>
|
||||
<Stack.Item m={1}>
|
||||
<Stack.Item m={1} grow>
|
||||
<Box color="label" overflow="hidden">
|
||||
{message}
|
||||
</Box>
|
||||
|
||||
@@ -52,7 +52,7 @@ export const AlgaeFarm = (props) => {
|
||||
<Stack fill vertical>
|
||||
{errorText && (
|
||||
<Stack.Item>
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
<Box inline verticalAlign="middle">
|
||||
{errorText}
|
||||
</Box>
|
||||
|
||||
@@ -50,7 +50,7 @@ export const BotanyEditor = (props) => {
|
||||
Eject Loaded Disk
|
||||
</Button>
|
||||
</Box>
|
||||
)) || <NoticeBox warning>No disk loaded.</NoticeBox>}
|
||||
)) || <NoticeBox>No disk loaded.</NoticeBox>}
|
||||
</Section>
|
||||
<Section title="Loaded Material">
|
||||
{(loaded && (
|
||||
@@ -65,7 +65,7 @@ export const BotanyEditor = (props) => {
|
||||
Eject Target
|
||||
</Button>
|
||||
</Box>
|
||||
)) || <NoticeBox warning>No target seed packet loaded.</NoticeBox>}
|
||||
)) || <NoticeBox>No target seed packet loaded.</NoticeBox>}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
|
||||
@@ -77,24 +77,16 @@ export const BotanyIsolator = (props) => {
|
||||
Clear Genetic Buffer
|
||||
</Button>
|
||||
</Box>
|
||||
)) || (
|
||||
<NoticeBox mt={1} warning>
|
||||
No disk inserted.
|
||||
</NoticeBox>
|
||||
)}
|
||||
)) || <NoticeBox mt={1}>No disk inserted.</NoticeBox>}
|
||||
</Box>
|
||||
)) || (
|
||||
<Box>
|
||||
<NoticeBox warning>No Data Buffered.</NoticeBox>
|
||||
<NoticeBox>No Data Buffered.</NoticeBox>
|
||||
{(disk && (
|
||||
<Button icon="eject" onClick={() => act('eject_disk')}>
|
||||
Eject Loaded Disk
|
||||
</Button>
|
||||
)) || (
|
||||
<NoticeBox mt={1} warning>
|
||||
No disk inserted.
|
||||
</NoticeBox>
|
||||
)}
|
||||
)) || <NoticeBox mt={1}>No disk inserted.</NoticeBox>}
|
||||
</Box>
|
||||
)}
|
||||
</Section>
|
||||
@@ -113,7 +105,7 @@ export const BotanyIsolator = (props) => {
|
||||
Eject Packet
|
||||
</Button>
|
||||
</Box>
|
||||
)) || <NoticeBox warning>No packet loaded.</NoticeBox>}
|
||||
)) || <NoticeBox>No packet loaded.</NoticeBox>}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
|
||||
@@ -125,7 +125,7 @@ const Evacuation = (props: { evac: Evac }) => {
|
||||
return null;
|
||||
case Evac.CrewTransfer:
|
||||
return (
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
The vessel is currently undergoing crew transfer procedures.
|
||||
</NoticeBox>
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@ export const ModifyRobotNoModule = (props: { target: Target }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
Target has no active module. Limited options available.
|
||||
</NoticeBox>
|
||||
<Divider />
|
||||
|
||||
@@ -4,7 +4,7 @@ export const NoSpriteWarning = (props: { name: string }) => {
|
||||
const { name } = props;
|
||||
|
||||
return (
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
Warning, {name} has not yet chosen a sprite. Functionality might be
|
||||
limited.
|
||||
</NoticeBox>
|
||||
|
||||
@@ -127,7 +127,7 @@ export const PathogenicIsolator = (props) => {
|
||||
<ComplexModal maxHeight="100%" maxWidth="95%" />
|
||||
<Window.Content scrollable>
|
||||
{(isolating && (
|
||||
<NoticeBox warning>The Isolator is currently isolating...</NoticeBox>
|
||||
<NoticeBox>The Isolator is currently isolating...</NoticeBox>
|
||||
)) ||
|
||||
''}
|
||||
<Tabs>
|
||||
|
||||
@@ -46,7 +46,7 @@ export function WikiDonationBanner(props: {
|
||||
|
||||
if (progress < 0.66) {
|
||||
return (
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
<WikiDonationContent
|
||||
donated={donated}
|
||||
goal={goal}
|
||||
|
||||
@@ -167,7 +167,7 @@ export const PublicLibraryWiki = (props) => {
|
||||
<Stack vertical fill>
|
||||
{!!errorText && (
|
||||
<Stack.Item>
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
<Box textAlign="center">{errorText}</Box>
|
||||
</NoticeBox>
|
||||
</Stack.Item>
|
||||
|
||||
@@ -62,7 +62,7 @@ export const TelecommsLogBrowser = (props) => {
|
||||
</NoticeBox>
|
||||
)) ||
|
||||
(temp && temp.color !== 'bad' && (
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
<Box inline verticalAlign="middle">
|
||||
{temp.text}
|
||||
</Box>
|
||||
|
||||
@@ -50,7 +50,7 @@ export const TelecommsMachineBrowser = (props) => {
|
||||
</NoticeBox>
|
||||
)) ||
|
||||
(temp && temp.color !== 'bad' && (
|
||||
<NoticeBox warning>
|
||||
<NoticeBox>
|
||||
<Box inline verticalAlign="middle">
|
||||
{temp.text}
|
||||
</Box>
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export const FeatureColorInput = (props: {
|
||||
action_name: string;
|
||||
value_of: BooleanLike | string;
|
||||
back_color: string;
|
||||
name_of: string;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { action_name, value_of, back_color, name_of } = props;
|
||||
return (
|
||||
<>
|
||||
<Stack.Item shrink>
|
||||
<Box
|
||||
backgroundColor={
|
||||
back_color.startsWith('#') ? back_color : `#${back_color}`
|
||||
}
|
||||
style={{
|
||||
border: '2px solid white',
|
||||
}}
|
||||
width="20px"
|
||||
height="20px"
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Button
|
||||
fluid
|
||||
icon="eye-dropper"
|
||||
onClick={() => {
|
||||
act('set_attribute', { attribute: action_name, val: value_of });
|
||||
}}
|
||||
>
|
||||
Change {name_of}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export const LiquidColorInput = (props: {
|
||||
action_name: string;
|
||||
value_of: BooleanLike | string;
|
||||
back_color: string;
|
||||
name_of: string;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { action_name, value_of, back_color, name_of } = props;
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
act('liq_set_attribute', { liq_attribute: action_name, val: value_of });
|
||||
}}
|
||||
>
|
||||
<Stack align="center" fill>
|
||||
<Stack.Item>
|
||||
<Box
|
||||
style={{
|
||||
background: back_color.startsWith('#')
|
||||
? back_color
|
||||
: `#${back_color}`,
|
||||
border: '2px solid white',
|
||||
boxSizing: 'content-box',
|
||||
height: '11px',
|
||||
width: '11px',
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>Change {name_of}</Stack.Item>
|
||||
</Stack>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { LabeledList, Section, Slider, Stack } from 'tgui-core/components';
|
||||
import { toFixed } from 'tgui-core/math';
|
||||
|
||||
import type { abilities } from './types';
|
||||
|
||||
export const VoreAbilities = (props: { abilities: abilities }) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { abilities } = props;
|
||||
|
||||
const { nutrition, current_size, minimum_size, maximum_size, resize_cost } =
|
||||
abilities;
|
||||
|
||||
function is_enabled(nutri: number, cost: number): boolean {
|
||||
return nutri >= cost;
|
||||
}
|
||||
|
||||
return (
|
||||
<Section title="Abilities" buttons={'Nutrition: ' + toFixed(nutrition, 1)}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Resize">
|
||||
<Stack align="baseline">
|
||||
<Stack.Item>
|
||||
<Slider
|
||||
disabled={!is_enabled(nutrition, resize_cost)}
|
||||
width="250px"
|
||||
ranges={
|
||||
is_enabled(nutrition, resize_cost)
|
||||
? {
|
||||
bad: [1, 25],
|
||||
average: [25, 50],
|
||||
green: [50, 150],
|
||||
yellow: [150, 200],
|
||||
red: [200, 600],
|
||||
}
|
||||
: { black: [0, 600] }
|
||||
}
|
||||
format={(value: number) => toFixed(value, 2) + '%'}
|
||||
value={current_size * 100}
|
||||
minValue={minimum_size * 100}
|
||||
maxValue={maximum_size * 100}
|
||||
onChange={(e, value: number) =>
|
||||
act('adjust_own_size', {
|
||||
new_mob_size: value / 100,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item color="label"> Cost: </Stack.Item>
|
||||
<Stack.Item>{resize_cost}</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -1,101 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, Image, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { stats } from './constants';
|
||||
import type { contentData } from './types';
|
||||
|
||||
export const VoreContentsPanel = (props: {
|
||||
contents: contentData[];
|
||||
belly?: string;
|
||||
outside?: BooleanLike;
|
||||
show_pictures: BooleanLike;
|
||||
icon_overflow: BooleanLike;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
contents,
|
||||
belly,
|
||||
outside = false,
|
||||
show_pictures,
|
||||
icon_overflow,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{outside ? (
|
||||
<Button
|
||||
textAlign="center"
|
||||
fluid
|
||||
mb={1}
|
||||
onClick={() => act('pick_from_outside', { pickall: true })}
|
||||
>
|
||||
All
|
||||
</Button>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{(show_pictures && !icon_overflow && (
|
||||
<Stack wrap="wrap" justify="center" align="center">
|
||||
{contents.map((thing) => (
|
||||
<Stack.Item key={thing.name} basis="32%">
|
||||
<Button
|
||||
width="64px"
|
||||
color={thing.absorbed ? 'purple' : stats[thing.stat]}
|
||||
style={{
|
||||
verticalAlign: 'middle',
|
||||
marginRight: '5px',
|
||||
borderRadius: '20px',
|
||||
}}
|
||||
onClick={() =>
|
||||
act(
|
||||
thing.outside ? 'pick_from_outside' : 'pick_from_inside',
|
||||
{
|
||||
pick: thing.ref,
|
||||
belly: belly,
|
||||
},
|
||||
)
|
||||
}
|
||||
>
|
||||
<Image
|
||||
src={'data:image/jpeg;base64, ' + thing.icon}
|
||||
width="64px"
|
||||
height="64px"
|
||||
style={{
|
||||
marginLeft: '-5px',
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
{thing.name}
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
)) || (
|
||||
<LabeledList>
|
||||
{contents.map((thing, i) => (
|
||||
<LabeledList.Item key={i} label={thing.name}>
|
||||
<Button
|
||||
fluid
|
||||
mt={-1}
|
||||
mb={-1}
|
||||
color={thing.absorbed ? 'purple' : stats[thing.stat]}
|
||||
onClick={() =>
|
||||
act(
|
||||
thing.outside ? 'pick_from_outside' : 'pick_from_inside',
|
||||
{
|
||||
pick: thing.ref,
|
||||
belly: belly,
|
||||
},
|
||||
)
|
||||
}
|
||||
>
|
||||
Interact
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Box, Button } from 'tgui-core/components';
|
||||
|
||||
export const VorePanelColorBox = (props: {
|
||||
back_color: string;
|
||||
pixelSize?: number;
|
||||
alpha?: number;
|
||||
}) => {
|
||||
const { back_color, pixelSize = 20, alpha = 255 } = props;
|
||||
|
||||
const parentSize = pixelSize + 'px';
|
||||
const childSize = pixelSize - 4 + 'px';
|
||||
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
border: '2px solid white',
|
||||
}}
|
||||
width={parentSize}
|
||||
height={parentSize}
|
||||
>
|
||||
<Box
|
||||
backgroundColor={
|
||||
back_color.startsWith('#') ? back_color : `#${back_color}`
|
||||
}
|
||||
style={{
|
||||
opacity: alpha / 255,
|
||||
}}
|
||||
width={childSize}
|
||||
height={childSize}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const VorePanelEditToggle = (props: {
|
||||
editMode: boolean;
|
||||
toggleEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const { editMode, toggleEditMode } = props;
|
||||
|
||||
return (
|
||||
<Button
|
||||
icon="pencil"
|
||||
color={editMode ? 'green' : undefined}
|
||||
tooltip={(editMode ? 'Dis' : 'En') + 'able edit mode'}
|
||||
onClick={() => toggleEditMode(!editMode)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, Floating, Stack, Tooltip } from 'tgui-core/components';
|
||||
|
||||
import type { checkBoxEntry } from '../types';
|
||||
|
||||
export const VorePanelEditCheckboxes = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our option entry checboxes with labels and actiondata */
|
||||
options: checkBoxEntry[];
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** Our tooltips associated to the checkbox actions as Record mapping our options to a tooltip */
|
||||
tooltipList?: Record<string, string>;
|
||||
/** Our displayed tooltip behind the input element */
|
||||
tooltip?: string;
|
||||
/** The position of the tooltip if static */
|
||||
tooltipPosition?: ComponentProps<typeof Floating>['placement'];
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
editMode,
|
||||
options,
|
||||
action,
|
||||
subAction = '',
|
||||
tooltipList,
|
||||
tooltip,
|
||||
tooltipPosition,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Stack align="center">
|
||||
{editMode && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Floating
|
||||
placement="bottom-end"
|
||||
contentClasses="VorePanel__fLoating"
|
||||
content={
|
||||
<Stack vertical fill>
|
||||
{options.map((value) => (
|
||||
<Stack.Item key={value.label}>
|
||||
<Button.Checkbox
|
||||
tooltip={tooltipList && tooltipList[value.label]}
|
||||
checked={value.selection}
|
||||
onClick={() =>
|
||||
act(action, {
|
||||
attribute: subAction,
|
||||
val: value.ref ? value.ref : value.label,
|
||||
})
|
||||
}
|
||||
>
|
||||
{value.label}
|
||||
</Button.Checkbox>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<Box className="VorePanel__floatingButton">+/-</Box>
|
||||
</Floating>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Tooltip content={tooltip} position={tooltipPosition}>
|
||||
<Box className="VorePanel__floatingButton">?</Box>
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
<Stack.Item grow>
|
||||
<Box>
|
||||
{(options.length &&
|
||||
options
|
||||
.filter((option) => option.selection)
|
||||
.map((value) => value.label)
|
||||
.join(', ')) ||
|
||||
'None'}
|
||||
</Box>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, type Floating, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { VorePanelColorBox } from './VorePanelCommonElements';
|
||||
import { VorePanelEditNumber } from './VorePanelEditNumber';
|
||||
|
||||
export const VorePanelEditColor = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** Our color value sent to byond */
|
||||
value_of: BooleanLike | string;
|
||||
/** The displayed color of the color box */
|
||||
back_color: string;
|
||||
/** A number representing the alpha value for alpha inouts */
|
||||
alpha?: number;
|
||||
/** Optional label to show before the color box */
|
||||
name_of?: string;
|
||||
/** Our displayed tooltip behind the input element */
|
||||
tooltip?: string;
|
||||
/** The position of the tooltip if static */
|
||||
tooltipPosition?: ComponentProps<typeof Floating>['placement'];
|
||||
/** Removes the spacing behind the color box */
|
||||
removePlaceholder?: boolean;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const {
|
||||
editMode,
|
||||
action,
|
||||
subAction = '',
|
||||
value_of,
|
||||
back_color,
|
||||
alpha,
|
||||
name_of,
|
||||
tooltip,
|
||||
tooltipPosition,
|
||||
removePlaceholder,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!!name_of && (
|
||||
<Stack.Item>
|
||||
<Box color="label">{name_of}</Box>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item shrink>
|
||||
<VorePanelColorBox back_color={back_color} alpha={alpha} />
|
||||
</Stack.Item>
|
||||
{editMode && (
|
||||
<Stack.Item basis={alpha !== undefined ? '65px' : undefined}>
|
||||
{alpha !== undefined ? (
|
||||
<VorePanelEditNumber
|
||||
action={action}
|
||||
subAction={subAction}
|
||||
editMode={editMode}
|
||||
value={alpha}
|
||||
minValue={0}
|
||||
maxValue={255}
|
||||
tooltip={tooltip}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
fluid
|
||||
icon="eye-dropper"
|
||||
onClick={() => {
|
||||
act(action, { attribute: subAction, val: value_of });
|
||||
}}
|
||||
tooltip={tooltip}
|
||||
tooltipPosition={tooltipPosition}
|
||||
/>
|
||||
)}
|
||||
</Stack.Item>
|
||||
)}
|
||||
{!removePlaceholder && <Stack.Item grow />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
Dropdown,
|
||||
type Floating,
|
||||
Stack,
|
||||
Tooltip,
|
||||
} from 'tgui-core/components';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
|
||||
import type { DropdownEntry } from '../types';
|
||||
|
||||
export const VorePanelEditDropdown = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** Our dropdown inouts and actions */
|
||||
options: (string | DropdownEntry)[];
|
||||
/** The currently shown selection */
|
||||
entry: string;
|
||||
/** Color of the dropdown and text */
|
||||
color?: string;
|
||||
/** Icon of the dropdown */
|
||||
icon?: string;
|
||||
/** Our displayed tooltip behind the input element */
|
||||
tooltip?: string;
|
||||
/** The position of the tooltip if static */
|
||||
tooltipPosition?: ComponentProps<typeof Floating>['placement'];
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
entry,
|
||||
editMode,
|
||||
options,
|
||||
action,
|
||||
subAction = '',
|
||||
color,
|
||||
icon,
|
||||
tooltip,
|
||||
tooltipPosition,
|
||||
} = props;
|
||||
|
||||
return editMode ? (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Dropdown
|
||||
color={color}
|
||||
onSelected={(value) =>
|
||||
act(action, { attribute: subAction, val: value })
|
||||
}
|
||||
options={options}
|
||||
selected={entry}
|
||||
icon={icon}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{tooltip && (
|
||||
<Stack.Item>
|
||||
<Tooltip content={tooltip} position={tooltipPosition}>
|
||||
<Box className="VorePanel__floatingButton">?</Box>
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
) : (
|
||||
<Box textColor={color}>{capitalize(entry)}</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
type Floating,
|
||||
NumberInput,
|
||||
Stack,
|
||||
Tooltip,
|
||||
} from 'tgui-core/components';
|
||||
import { round, toFixed } from 'tgui-core/math';
|
||||
|
||||
export const VorePanelEditNumber = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** The current displayed number */
|
||||
value: number;
|
||||
/** The minimum number allowed */
|
||||
minValue: number;
|
||||
/** The maximum number allowed */
|
||||
maxValue: number;
|
||||
/** The steps of the input */
|
||||
step?: number;
|
||||
/** The pixels required for each step */
|
||||
stepPixel?: number;
|
||||
/** The unit shown behind the number */
|
||||
unit?: string;
|
||||
/** The color of the displayed text */
|
||||
color?: string;
|
||||
/** Our displayed tooltip behind the input element */
|
||||
tooltip?: string;
|
||||
/** The position of the tooltip if static */
|
||||
tooltipPosition?: ComponentProps<typeof Floating>['placement'];
|
||||
/** The amount of fractional digits shown */
|
||||
digits?: number;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
action,
|
||||
subAction = '',
|
||||
value,
|
||||
maxValue,
|
||||
minValue,
|
||||
step = 1,
|
||||
stepPixel = 1,
|
||||
editMode,
|
||||
unit,
|
||||
color,
|
||||
tooltip,
|
||||
tooltipPosition,
|
||||
digits = 0,
|
||||
} = props;
|
||||
|
||||
return editMode ? (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<NumberInput
|
||||
onChange={(value) =>
|
||||
act(action, {
|
||||
attribute: subAction,
|
||||
val: round(value, digits),
|
||||
})
|
||||
}
|
||||
stepPixelSize={stepPixel}
|
||||
value={value}
|
||||
maxValue={maxValue}
|
||||
minValue={minValue}
|
||||
step={step}
|
||||
unit={unit}
|
||||
format={(val) => toFixed(val, digits)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{tooltip && (
|
||||
<Stack.Item>
|
||||
<Tooltip content={tooltip} position={tooltipPosition}>
|
||||
<Box className="VorePanel__floatingButton">?</Box>
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
) : (
|
||||
<Box textColor={color}>
|
||||
{value}
|
||||
{!!unit && ' ' + unit}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, type Floating } from 'tgui-core/components';
|
||||
|
||||
export const VorePanelEditSwitch = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** Is the button currently active / selected */
|
||||
active?: boolean;
|
||||
/** Displayed text content */
|
||||
content?: string;
|
||||
/** Our displayed tooltip on button hover */
|
||||
tooltip?: string;
|
||||
/** The position of the tooltip if static */
|
||||
tooltipPosition?: ComponentProps<typeof Floating>['placement'];
|
||||
/** Color of the button and displayed text */
|
||||
color?: string;
|
||||
/** Hides the button icon */
|
||||
hideIcon?: boolean;
|
||||
/** Allows to pass custom icon options */
|
||||
customIcon?: string;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
action,
|
||||
subAction = '',
|
||||
active,
|
||||
editMode,
|
||||
content,
|
||||
tooltip,
|
||||
tooltipPosition,
|
||||
color,
|
||||
hideIcon,
|
||||
customIcon,
|
||||
} = props;
|
||||
|
||||
const currentIcon = customIcon
|
||||
? customIcon
|
||||
: active
|
||||
? 'toggle-on'
|
||||
: 'toggle-off';
|
||||
|
||||
return editMode ? (
|
||||
<Button
|
||||
tooltip={tooltip}
|
||||
tooltipPosition={tooltipPosition}
|
||||
onClick={() =>
|
||||
act(action, {
|
||||
attribute: subAction || '',
|
||||
})
|
||||
}
|
||||
icon={!hideIcon && currentIcon}
|
||||
selected={active}
|
||||
color={color}
|
||||
>
|
||||
{content ? content : active ? 'Enabled' : 'Disabled'}
|
||||
</Button>
|
||||
) : (
|
||||
<Box textColor={color ? color : active ? 'green' : 'red'}>
|
||||
{content ? content : active ? 'Enabled' : 'Disabled'}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { ComponentProps } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
type Floating,
|
||||
Input,
|
||||
Stack,
|
||||
Tooltip,
|
||||
} from 'tgui-core/components';
|
||||
|
||||
export const VorePanelEditText = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** The maximum length of each message */
|
||||
limit: number;
|
||||
/** Minimum required text to trigger an change action to byond */
|
||||
min?: number;
|
||||
/** The current displayed message */
|
||||
entry: string;
|
||||
/** The color of the displayed text */
|
||||
color?: string;
|
||||
/** Our displayed tooltip displayed the text */
|
||||
tooltip?: string;
|
||||
/** The position of the tooltip if static */
|
||||
tooltipPosition?: ComponentProps<typeof Floating>['placement'];
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
entry,
|
||||
min,
|
||||
editMode,
|
||||
limit,
|
||||
action,
|
||||
subAction = '',
|
||||
color,
|
||||
tooltip,
|
||||
tooltipPosition,
|
||||
} = props;
|
||||
|
||||
function doAct(value: string) {
|
||||
if (entry === value) return;
|
||||
if (min && value.length < min) return;
|
||||
act(action, { attribute: subAction, val: value });
|
||||
}
|
||||
|
||||
return editMode ? (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Input
|
||||
fluid
|
||||
maxLength={limit}
|
||||
value={entry}
|
||||
onBlur={(value) => doAct(value)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{tooltip && (
|
||||
<Stack.Item>
|
||||
<Tooltip content={tooltip} position={tooltipPosition}>
|
||||
<Box className="VorePanel__floatingButton">?</Box>
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
) : (
|
||||
<Box textColor={color}>{entry}</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,247 @@
|
||||
import { type ReactNode, useEffect, useRef, useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
Divider,
|
||||
Floating,
|
||||
Icon,
|
||||
Stack,
|
||||
TextArea,
|
||||
} from 'tgui-core/components';
|
||||
|
||||
import { SYNTAX_COLOR, SYNTAX_REGEX } from '../constants';
|
||||
import { calcLineHeight } from '../functions';
|
||||
|
||||
const DescriptionSyntaxHighlighting = (props: { desc: string }) => {
|
||||
const { desc } = props;
|
||||
const [htmlDesc, setHtmlDesc] = useState<ReactNode[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!desc || desc.length === 0) {
|
||||
setHtmlDesc([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const elements: ReactNode[] = [];
|
||||
|
||||
const regexCopy = new RegExp(SYNTAX_REGEX);
|
||||
|
||||
let lastIndex = 0;
|
||||
let result;
|
||||
while ((result = regexCopy.exec(desc)) !== null) {
|
||||
elements.push(<>{desc.substring(lastIndex, result.index)}</>);
|
||||
elements.push(
|
||||
<Box inline color={SYNTAX_COLOR[result[0]] || 'purple'}>
|
||||
{result[0]}
|
||||
</Box>,
|
||||
);
|
||||
lastIndex = result.index + result[0].length;
|
||||
}
|
||||
|
||||
elements.push(<>{desc.substring(lastIndex)}</>);
|
||||
|
||||
setHtmlDesc(elements);
|
||||
}, [desc]);
|
||||
|
||||
return <Box preserveWhitespace>{htmlDesc}</Box>;
|
||||
};
|
||||
|
||||
const CountedTextElement = (props: {
|
||||
limit: number;
|
||||
entry: string;
|
||||
action: Function;
|
||||
index?: number;
|
||||
}) => {
|
||||
const { entry, limit, action, index } = props;
|
||||
|
||||
const ref = useRef<HTMLTextAreaElement | null>(null);
|
||||
|
||||
const currentCount = ref.current?.value.length || 0;
|
||||
return (
|
||||
<>
|
||||
<Stack.Item grow>
|
||||
<TextArea
|
||||
height="100%"
|
||||
minHeight={calcLineHeight(limit, 16)}
|
||||
fluid
|
||||
ref={ref}
|
||||
maxLength={limit}
|
||||
value={entry}
|
||||
onBlur={(value) => {
|
||||
if (value !== entry) {
|
||||
action(value, index);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item grow />
|
||||
<Stack.Item>
|
||||
<Box color="label">{currentCount + ' / ' + limit}</Box>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow />
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const AreaMapper = (props: {
|
||||
limit: number;
|
||||
entry: string[];
|
||||
action: Function;
|
||||
exactLength: boolean;
|
||||
maxEntries: number;
|
||||
}) => {
|
||||
const { entry, limit, action, exactLength, maxEntries } = props;
|
||||
|
||||
const filledArray = [
|
||||
...entry,
|
||||
...new Array(maxEntries - entry.length).fill(''),
|
||||
];
|
||||
|
||||
function performAction(value: string, index: number) {
|
||||
const newEntry = [...filledArray];
|
||||
newEntry[index] = value;
|
||||
if (exactLength) {
|
||||
action(newEntry);
|
||||
return;
|
||||
}
|
||||
const filtered = newEntry.filter(Boolean);
|
||||
action(filtered);
|
||||
}
|
||||
|
||||
return filledArray.map((singleEntry, index) => (
|
||||
<CountedTextElement
|
||||
key={index}
|
||||
limit={limit}
|
||||
entry={singleEntry}
|
||||
action={performAction}
|
||||
index={index}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
export const VorePanelEditTextArea = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** Our secondary backend action if we used a list as input on text area blur */
|
||||
listAction?: string;
|
||||
/** Our displayed tooltip displayed above all texts */
|
||||
tooltip?: string;
|
||||
/** The maximum length of each message */
|
||||
limit: number;
|
||||
/** The current displayed message or message array */
|
||||
entry: string | string[];
|
||||
/** Do we force the input to always send the maxEntries as list length to byond */
|
||||
exactLength?: boolean;
|
||||
/** The amount of possible list entries. By default 10 */
|
||||
maxEntries?: number;
|
||||
/** Should we disbale the copy paste legacy field for text to list inputs */
|
||||
disableLegacyInput?: boolean;
|
||||
/** Disable our special highlighting used on belly messages */
|
||||
noHighlight?: boolean;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
entry,
|
||||
editMode,
|
||||
tooltip,
|
||||
limit,
|
||||
action,
|
||||
exactLength = false,
|
||||
listAction,
|
||||
subAction = '',
|
||||
maxEntries = 10,
|
||||
disableLegacyInput = false,
|
||||
noHighlight,
|
||||
} = props;
|
||||
|
||||
function doAct(value: string | string[]) {
|
||||
if (Array.isArray(value)) {
|
||||
act(action, { attribute: listAction, msgtype: subAction, val: value });
|
||||
return;
|
||||
}
|
||||
act(action, { attribute: subAction, val: value });
|
||||
}
|
||||
|
||||
function applyPaste(value: string) {
|
||||
Array.isArray(entry) ? doAct(value.split('\n\n')) : doAct(value);
|
||||
}
|
||||
|
||||
return editMode ? (
|
||||
<Stack fill vertical>
|
||||
{!!tooltip && (
|
||||
<Stack.Item>
|
||||
<Box color="label">{tooltip}</Box>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{!disableLegacyInput && Array.isArray(entry) && (
|
||||
<Stack.Item>
|
||||
<Floating
|
||||
placement="bottom-start"
|
||||
contentClasses="VorePanel__pasteArea"
|
||||
content={
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
<Box color="label">
|
||||
Copy paste the fields as legacy block text. Use enter to
|
||||
apply. Shift + Enter for new lines.
|
||||
</Box>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<TextArea
|
||||
height="100%"
|
||||
fluid
|
||||
value={Array.isArray(entry) ? entry.join('\n\n') : entry}
|
||||
onEnter={(value) => applyPaste(value)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<Box className="VorePanel__floatingButton">
|
||||
<Icon name="paste" />
|
||||
</Box>
|
||||
</Floating>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item>
|
||||
{Array.isArray(entry) ? (
|
||||
<AreaMapper
|
||||
limit={limit}
|
||||
entry={entry}
|
||||
exactLength={exactLength}
|
||||
action={doAct}
|
||||
maxEntries={maxEntries}
|
||||
/>
|
||||
) : (
|
||||
<CountedTextElement limit={limit} entry={entry} action={doAct} />
|
||||
)}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
) : Array.isArray(entry) ? (
|
||||
<Stack vertical g={1}>
|
||||
{entry.map((singleEntry, index) => (
|
||||
<Stack.Item key={index}>
|
||||
<Divider />
|
||||
{noHighlight ? (
|
||||
<Box preserveWhitespace>{singleEntry}</Box>
|
||||
) : (
|
||||
<DescriptionSyntaxHighlighting desc={singleEntry} />
|
||||
)}
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
) : !noHighlight ? (
|
||||
<Box preserveWhitespace>{entry}</Box>
|
||||
) : (
|
||||
<DescriptionSyntaxHighlighting desc={entry} />
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { LabeledList, Stack, Tabs } from 'tgui-core/components';
|
||||
|
||||
import { VorePanelEditSwitch } from './VorePanelEditSwitch';
|
||||
import { VorePanelEditTextArea } from './VorePanelTextArea';
|
||||
|
||||
export const VorePanelEditTextTabs = (props: {
|
||||
/** Switch between Element editing and display */
|
||||
editMode: boolean;
|
||||
/** The tab options to switch through */
|
||||
messsageOptions: string[];
|
||||
/** The current active tab */
|
||||
activeTab: string;
|
||||
/** The backend action to perform on tab selection */
|
||||
tabAction: string;
|
||||
/** Our displayed tooltip displayed above all texts */
|
||||
tooltip: string;
|
||||
/** The maximum length of each message */
|
||||
maxLength: number;
|
||||
/** The current displayed message or message array */
|
||||
activeMessage: string | string[] | null;
|
||||
/** Do we force the input to always send the maxEntries as list length to byond */
|
||||
exactLength?: boolean;
|
||||
/** Our backend action on text area blur */
|
||||
action: string;
|
||||
/** Our secondary backend action on text area blur */
|
||||
subAction?: string;
|
||||
/** Our secondary backend action if we used a list as input on text area blur */
|
||||
listAction?: string;
|
||||
/** The amount of possible list entries. By default 10 */
|
||||
maxEntries?: number;
|
||||
/** Should we disbale the copy paste legacy field for text to list inputs */
|
||||
disableLegacyInput?: boolean;
|
||||
/** The action of a possibly supplied button shown above all inputs */
|
||||
button_action?: string;
|
||||
/** The action of a possibly supplied button shown above all inputs */
|
||||
button_label?: string;
|
||||
/** The data of the button to show its possible selected state */
|
||||
button_data?: boolean;
|
||||
/** The tooltip to display on button hover */
|
||||
button_tooltip?: string;
|
||||
/** The icon of each tab as record, mapping the messageOptions to icons */
|
||||
tabsToIcons?: Record<string, string>;
|
||||
/** Disable our special highlighting used on belly messages */
|
||||
noHighlight?: boolean;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
editMode,
|
||||
messsageOptions,
|
||||
activeTab,
|
||||
tabAction,
|
||||
tooltip,
|
||||
maxLength,
|
||||
activeMessage,
|
||||
action,
|
||||
exactLength,
|
||||
subAction,
|
||||
listAction,
|
||||
maxEntries = 10,
|
||||
disableLegacyInput,
|
||||
button_action,
|
||||
button_label,
|
||||
button_data,
|
||||
button_tooltip,
|
||||
tabsToIcons,
|
||||
noHighlight,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Tabs>
|
||||
{messsageOptions.map((value) => (
|
||||
<Tabs.Tab
|
||||
key={value}
|
||||
selected={value === activeTab}
|
||||
onClick={() => {
|
||||
if (value !== activeTab) {
|
||||
act(tabAction, { tab: value });
|
||||
}
|
||||
}}
|
||||
icon={tabsToIcons && tabsToIcons[value]}
|
||||
>
|
||||
{value}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
{!!button_action && (
|
||||
<Stack.Item>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label={button_label}>
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction={button_action}
|
||||
editMode={editMode}
|
||||
active={!!button_data}
|
||||
tooltip={
|
||||
(button_data ? 'Dis' : 'En') + 'ables ' + button_tooltip
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item grow>
|
||||
<VorePanelEditTextArea
|
||||
noHighlight={noHighlight}
|
||||
editMode={editMode}
|
||||
tooltip={tooltip}
|
||||
limit={maxLength}
|
||||
entry={activeMessage || ''}
|
||||
action={action}
|
||||
exactLength={exactLength}
|
||||
subAction={subAction}
|
||||
listAction={listAction}
|
||||
maxEntries={maxEntries}
|
||||
disableLegacyInput={disableLegacyInput}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button } from 'tgui-core/components';
|
||||
|
||||
import type { preferenceData } from './types';
|
||||
import type { preferenceData } from '../types';
|
||||
|
||||
export const VoreUserPreferenceItem = (props: {
|
||||
spec: preferenceData;
|
||||
@@ -0,0 +1,66 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { LabeledList, Section, Slider, Stack } from 'tgui-core/components';
|
||||
import { toFixed } from 'tgui-core/math';
|
||||
|
||||
import { abilitiy_usable } from '../functions';
|
||||
import type { abilities, abilitySizeChange } from '../types';
|
||||
|
||||
export const VoreAbilities = (props: { abilities: abilities }) => {
|
||||
const { abilities } = props;
|
||||
|
||||
const { nutrition, size_change } = abilities;
|
||||
|
||||
return (
|
||||
<Section title="Abilities" buttons={'Nutrition: ' + toFixed(nutrition, 1)}>
|
||||
<LabeledList>
|
||||
<SizeChange nutrition={nutrition} sizeChange={size_change} />
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const SizeChange = (props: {
|
||||
nutrition: number;
|
||||
sizeChange: abilitySizeChange;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { nutrition, sizeChange } = props;
|
||||
|
||||
const { resize_cost, current_size, minimum_size, maximum_size } = sizeChange;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Resize">
|
||||
<Stack align="baseline">
|
||||
<Stack.Item>
|
||||
<Slider
|
||||
disabled={!abilitiy_usable(nutrition, resize_cost)}
|
||||
width="250px"
|
||||
ranges={
|
||||
abilitiy_usable(nutrition, resize_cost)
|
||||
? {
|
||||
bad: [1, 25],
|
||||
average: [25, 50],
|
||||
green: [50, 150],
|
||||
yellow: [150, 200],
|
||||
red: [200, 600],
|
||||
}
|
||||
: { black: [0, 600] }
|
||||
}
|
||||
format={(value: number) => toFixed(value, 2) + '%'}
|
||||
value={Math.round(current_size * 10000) / 100}
|
||||
minValue={minimum_size * 100}
|
||||
maxValue={maximum_size * 100}
|
||||
onChange={(e, value: number) =>
|
||||
act('adjust_own_size', {
|
||||
new_mob_size: value / 100,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item color="label"> Cost: </Stack.Item>
|
||||
<Stack.Item>{resize_cost}</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
+66
-7
@@ -1,41 +1,77 @@
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Button,
|
||||
Divider,
|
||||
Icon,
|
||||
Input,
|
||||
Section,
|
||||
Stack,
|
||||
Tabs,
|
||||
Tooltip,
|
||||
} from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
import { createSearch } from 'tgui-core/string';
|
||||
|
||||
import { digestModeToColor } from './constants';
|
||||
import type { bellyData, hostMob, selectedData } from './types';
|
||||
import { digestModeToColor } from '../constants';
|
||||
import type { bellyData, hostMob, selectedData } from '../types';
|
||||
import { VorePanelEditToggle } from '../VorePanelElements/VorePanelCommonElements';
|
||||
import { VoreSelectedBelly } from './VoreSelectedBelly';
|
||||
|
||||
export const VoreBellySelectionAndCustomization = (props: {
|
||||
activeVoreTab?: number;
|
||||
our_bellies: bellyData[];
|
||||
selected: selectedData | null;
|
||||
show_pictures: BooleanLike;
|
||||
host_mobtype: hostMob;
|
||||
icon_overflow: BooleanLike;
|
||||
vore_words: Record<string, string[]>;
|
||||
toggleEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
editMode: boolean;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
activeVoreTab = 0,
|
||||
our_bellies,
|
||||
selected,
|
||||
show_pictures,
|
||||
host_mobtype,
|
||||
icon_overflow,
|
||||
vore_words,
|
||||
toggleEditMode,
|
||||
editMode,
|
||||
} = props;
|
||||
|
||||
const [showSearch, setShowSearch] = useState(false);
|
||||
const [searchedBellies, setSearchedBellies] = useState('');
|
||||
|
||||
const bellySearch = createSearch(
|
||||
searchedBellies,
|
||||
(belly: bellyData) => belly.name,
|
||||
);
|
||||
|
||||
const belliesToDisplay = our_bellies.filter(bellySearch);
|
||||
|
||||
const bellyDropdownNames = our_bellies.map((belly) => {
|
||||
return { displayText: belly.name, value: belly.ref };
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack fill>
|
||||
<Stack.Item shrink basis="20%">
|
||||
<Section title="My Bellies" scrollable fill>
|
||||
<Section
|
||||
title="My Bellies"
|
||||
scrollable
|
||||
fill
|
||||
buttons={
|
||||
<Button
|
||||
icon="magnifying-glass"
|
||||
selected={showSearch}
|
||||
onClick={() => setShowSearch(!showSearch)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Tabs vertical>
|
||||
<Tabs.Tab onClick={() => act('newbelly')}>
|
||||
New
|
||||
@@ -50,18 +86,28 @@ export const VoreBellySelectionAndCustomization = (props: {
|
||||
<Icon name="file-import" ml={0.5} />
|
||||
</Tabs.Tab>
|
||||
<Divider />
|
||||
{our_bellies.map((belly) => (
|
||||
{showSearch && (
|
||||
<>
|
||||
<Input
|
||||
fluid
|
||||
placeholder="Search for bellies..."
|
||||
onChange={(value) => setSearchedBellies(value)}
|
||||
/>
|
||||
<Divider />
|
||||
</>
|
||||
)}
|
||||
{belliesToDisplay.map((belly) => (
|
||||
<Tabs.Tab
|
||||
key={belly.name}
|
||||
selected={!!belly.selected}
|
||||
textColor={digestModeToColor[belly.digest_mode]}
|
||||
textColor={digestModeToColor[belly.digest_mode!]}
|
||||
onClick={() => act('bellypick', { bellypick: belly.ref })}
|
||||
backgroundColor={belly.prevent_saving ? '#180000' : undefined}
|
||||
>
|
||||
<Stack
|
||||
fill
|
||||
textColor={
|
||||
(belly.selected && digestModeToColor[belly.digest_mode]) ||
|
||||
(belly.selected && digestModeToColor[belly.digest_mode!]) ||
|
||||
null
|
||||
}
|
||||
>
|
||||
@@ -87,13 +133,26 @@ export const VoreBellySelectionAndCustomization = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
{selected && (
|
||||
<Section title={selected.belly_name} fill scrollable>
|
||||
<Section
|
||||
title={selected.belly_name}
|
||||
buttons={
|
||||
<VorePanelEditToggle
|
||||
editMode={editMode}
|
||||
toggleEditMode={toggleEditMode}
|
||||
/>
|
||||
}
|
||||
fill
|
||||
scrollable
|
||||
>
|
||||
<VoreSelectedBelly
|
||||
bellyDropdownNames={bellyDropdownNames}
|
||||
activeVoreTab={activeVoreTab}
|
||||
vore_words={vore_words}
|
||||
belly={selected}
|
||||
show_pictures={show_pictures}
|
||||
host_mobtype={host_mobtype}
|
||||
icon_overflow={icon_overflow}
|
||||
editMode={editMode}
|
||||
/>
|
||||
</Section>
|
||||
)}
|
||||
+10
-11
@@ -1,10 +1,10 @@
|
||||
import { Box, Collapsible, Section } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { digestModeToPreyMode, reagentToColor } from './constants';
|
||||
import { digestModeToColor } from './constants';
|
||||
import type { insideData } from './types';
|
||||
import { VoreContentsPanel } from './VoreContentsPanel';
|
||||
import { digestModeToPreyMode, reagentToColor } from '../constants';
|
||||
import { digestModeToColor } from '../constants';
|
||||
import type { insideData } from '../types';
|
||||
import { VoreContentsPanel } from '../VoreSelectedBellyTabs/VoreContentsPanel';
|
||||
|
||||
export const VoreInsidePanel = (props: {
|
||||
inside: insideData;
|
||||
@@ -43,7 +43,7 @@ export const VoreInsidePanel = (props: {
|
||||
<Box color="red" inline>
|
||||
{belly_name}
|
||||
</Box>
|
||||
{liq_lvl! > 0 ? (
|
||||
{!!liq_lvl && liq_lvl > 0 && (
|
||||
<>
|
||||
,
|
||||
<Box color="yellow" inline>
|
||||
@@ -54,8 +54,6 @@ export const VoreInsidePanel = (props: {
|
||||
{liuq_name}
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
|
||||
<Box color="yellow" inline>
|
||||
@@ -67,17 +65,18 @@ export const VoreInsidePanel = (props: {
|
||||
</Box>
|
||||
|
||||
<Box color="label">{desc}</Box>
|
||||
{(contents!.length && (
|
||||
{contents && contents.length ? (
|
||||
<Collapsible title="Belly Contents">
|
||||
<VoreContentsPanel
|
||||
contents={contents!}
|
||||
contents={contents}
|
||||
belly={ref}
|
||||
show_pictures={show_pictures}
|
||||
icon_overflow={icon_overflow}
|
||||
/>
|
||||
</Collapsible>
|
||||
)) ||
|
||||
'There is nothing else around you.'}
|
||||
) : (
|
||||
'There is nothing else around you.'
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,135 @@
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Stack, Tabs } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { tabToNames } from '../constants';
|
||||
import type { DropdownEntry, hostMob, selectedData } from '../types';
|
||||
import { VoreContentsPanel } from '../VoreSelectedBellyTabs/VoreContentsPanel';
|
||||
import { VoreSelectedBellyControls } from '../VoreSelectedBellyTabs/VoreSelectedBellyControls';
|
||||
import { VoreSelectedBellyDescriptions } from '../VoreSelectedBellyTabs/VoreSelectedBellyDescriptions';
|
||||
import { VoreSelectedBellyInteractions } from '../VoreSelectedBellyTabs/VoreSelectedBellyInteractions';
|
||||
import { VoreSelectedBellyLiquidOptions } from '../VoreSelectedBellyTabs/VoreSelectedBellyLiquidOptions';
|
||||
import { VoreSelectedBellyOptions } from '../VoreSelectedBellyTabs/VoreSelectedBellyOptions';
|
||||
import { VoreSelectedBellySounds } from '../VoreSelectedBellyTabs/VoreSelectedBellySounds';
|
||||
import { VoreSelectedBellyVisuals } from '../VoreSelectedBellyTabs/VoreSelectedBellyVisuals';
|
||||
/**
|
||||
* Subtemplate of VoreBellySelectionAndCustomization
|
||||
*/
|
||||
export const VoreSelectedBelly = (props: {
|
||||
bellyDropdownNames: DropdownEntry[];
|
||||
activeVoreTab: number;
|
||||
belly: selectedData;
|
||||
show_pictures: BooleanLike;
|
||||
host_mobtype: hostMob;
|
||||
icon_overflow: BooleanLike;
|
||||
vore_words: Record<string, string[]>;
|
||||
editMode: boolean;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const {
|
||||
bellyDropdownNames,
|
||||
activeVoreTab,
|
||||
belly,
|
||||
show_pictures,
|
||||
host_mobtype,
|
||||
icon_overflow,
|
||||
vore_words,
|
||||
editMode,
|
||||
} = props;
|
||||
const {
|
||||
belly_name,
|
||||
belly_mode_data,
|
||||
belly_description_data,
|
||||
belly_option_data,
|
||||
belly_sound_data,
|
||||
belly_visual_data,
|
||||
belly_interaction_data,
|
||||
belly_liquid_data,
|
||||
contents,
|
||||
content_length,
|
||||
} = belly;
|
||||
|
||||
const [targetBelly, setTargetBelly] = useState('');
|
||||
|
||||
const tabs: (React.JSX.Element | undefined)[] = [];
|
||||
|
||||
tabs[0] = belly_mode_data && (
|
||||
<VoreSelectedBellyControls
|
||||
editMode={editMode}
|
||||
bellyDropdownNames={bellyDropdownNames}
|
||||
belly_name={belly_name}
|
||||
bellyModeData={belly_mode_data}
|
||||
/>
|
||||
);
|
||||
tabs[1] = belly_description_data && (
|
||||
<VoreSelectedBellyDescriptions
|
||||
editMode={editMode}
|
||||
bellyDescriptionData={belly_description_data}
|
||||
vore_words={vore_words}
|
||||
/>
|
||||
);
|
||||
tabs[2] = belly_option_data && (
|
||||
<VoreSelectedBellyOptions
|
||||
editMode={editMode}
|
||||
bellyOptionData={belly_option_data}
|
||||
host_mobtype={host_mobtype}
|
||||
/>
|
||||
);
|
||||
tabs[3] = belly_sound_data && (
|
||||
<VoreSelectedBellySounds
|
||||
editMode={editMode}
|
||||
bellySoundData={belly_sound_data}
|
||||
/>
|
||||
);
|
||||
tabs[4] = belly_visual_data && (
|
||||
<VoreSelectedBellyVisuals
|
||||
editMode={editMode}
|
||||
bellyVisualData={belly_visual_data}
|
||||
/>
|
||||
);
|
||||
tabs[5] = belly_interaction_data && (
|
||||
<VoreSelectedBellyInteractions
|
||||
editMode={editMode}
|
||||
bellyDropdownNames={bellyDropdownNames}
|
||||
bellyInteractData={belly_interaction_data}
|
||||
/>
|
||||
);
|
||||
tabs[6] = (
|
||||
<VoreContentsPanel
|
||||
outside
|
||||
targetBelly={targetBelly}
|
||||
onTargetBely={setTargetBelly}
|
||||
bellyDropdownNames={bellyDropdownNames}
|
||||
contents={contents}
|
||||
show_pictures={show_pictures}
|
||||
icon_overflow={icon_overflow}
|
||||
/>
|
||||
);
|
||||
tabs[7] = belly_liquid_data && (
|
||||
<VoreSelectedBellyLiquidOptions
|
||||
editMode={editMode}
|
||||
bellyLiquidData={belly_liquid_data}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Tabs>
|
||||
{tabToNames.map((name, index) => (
|
||||
<Tabs.Tab
|
||||
key={name}
|
||||
selected={activeVoreTab === index}
|
||||
onClick={() => act('change_vore_tab', { tab: index })}
|
||||
>
|
||||
{tabToNames[index]}
|
||||
{!!(index === 6) && '(' + content_length + ')'}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>{tabs[activeVoreTab] || 'Error'}</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,209 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
Dropdown,
|
||||
LabeledList,
|
||||
Section,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
|
||||
import { noSelectionName } from '../constants';
|
||||
import type { abilities, DropdownEntry, soulcatcherData } from '../types';
|
||||
import { VorePanelEditToggle } from '../VorePanelElements/VorePanelCommonElements';
|
||||
import { VorePanelEditTextTabs } from '../VorePanelElements/VorePaneldEditTextTabs';
|
||||
import { VorePanelEditDropdown } from '../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditText } from '../VorePanelElements/VorePanelEditText';
|
||||
import { CatchSettings } from '../VoreSoulcatcherSettings/CatchSettings';
|
||||
import { GlobalOptions } from '../VoreSoulcatcherSettings/GlobalOptions';
|
||||
import { GlobalSettings } from '../VoreSoulcatcherSettings/GlobalSettings';
|
||||
import { SoulOptions } from '../VoreSoulcatcherSettings/SoulOptions';
|
||||
import { VoreAbilities } from './VoreAbilities';
|
||||
|
||||
export const VoreSoulcatcher = (props: {
|
||||
soulcatcher: soulcatcherData | null;
|
||||
our_bellies: Required<{ name: string; ref: string }[]> & {
|
||||
map(
|
||||
arg0: (belly: { name: string; ref: string }) => DropdownEntry,
|
||||
): DropdownEntry[];
|
||||
};
|
||||
abilities: abilities;
|
||||
toggleEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
editMode: boolean;
|
||||
}) => {
|
||||
const { soulcatcher, our_bellies, abilities, toggleEditMode, editMode } =
|
||||
props;
|
||||
|
||||
const getBellies = our_bellies.map((belly) => {
|
||||
return { displayText: belly.name, value: belly.ref };
|
||||
});
|
||||
|
||||
const locationNames = [...getBellies, noSelectionName];
|
||||
|
||||
return (
|
||||
<Section scrollable fill>
|
||||
<Stack vertical fill>
|
||||
{soulcatcher && (
|
||||
<Stack.Item>
|
||||
<VoreSoulcatcherSection
|
||||
soulcatcher={soulcatcher}
|
||||
overlayBellies={locationNames}
|
||||
toggleEditMode={toggleEditMode}
|
||||
editMode={editMode}
|
||||
/>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item>
|
||||
<VoreAbilities abilities={abilities} />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const VoreSoulcatcherSection = (props: {
|
||||
soulcatcher: soulcatcherData;
|
||||
overlayBellies: DropdownEntry[];
|
||||
toggleEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
editMode: boolean;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { soulcatcher, overlayBellies, toggleEditMode, editMode } = props;
|
||||
|
||||
const {
|
||||
active,
|
||||
name,
|
||||
caught_souls,
|
||||
selected_soul,
|
||||
catch_self,
|
||||
catch_prey,
|
||||
catch_drain,
|
||||
catch_ghost,
|
||||
ext_hearing,
|
||||
ext_vision,
|
||||
mind_backups,
|
||||
sr_projecting,
|
||||
see_sr_projecting,
|
||||
selected_sfx,
|
||||
show_vore_sfx,
|
||||
taken_over,
|
||||
sc_message_data,
|
||||
} = soulcatcher;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title={'Soulcatcher (' + name + ')'}
|
||||
fill
|
||||
buttons={
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<VorePanelEditSwitch
|
||||
action="soulcatcher_toggle"
|
||||
editMode={editMode}
|
||||
active={!!active}
|
||||
tooltipPosition="top"
|
||||
tooltip={
|
||||
(active ? 'Disables' : 'Enables') +
|
||||
' the ability to capture souls upon vore death.'
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<VorePanelEditToggle
|
||||
editMode={editMode}
|
||||
toggleEditMode={toggleEditMode}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
{!!active && (
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Captured Souls">
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<Dropdown
|
||||
width="200px"
|
||||
selected={selected_soul}
|
||||
options={caught_souls}
|
||||
onSelected={(value) =>
|
||||
act('soulcatcher_select', {
|
||||
selected_soul: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Box>{caught_souls.length}</Box>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
{!!selected_soul && <SoulOptions taken_over={taken_over} />}
|
||||
{!!caught_souls.length && (
|
||||
<GlobalOptions taken_over={taken_over} />
|
||||
)}
|
||||
<CatchSettings
|
||||
editMode={editMode}
|
||||
catch_self={catch_self}
|
||||
catch_prey={catch_prey}
|
||||
catch_drain={catch_drain}
|
||||
catch_ghost={catch_ghost}
|
||||
/>
|
||||
<GlobalSettings
|
||||
editMode={editMode}
|
||||
ext_hearing={ext_hearing}
|
||||
ext_vision={ext_vision}
|
||||
mind_backups={mind_backups}
|
||||
sr_projecting={sr_projecting}
|
||||
see_sr_projecting={see_sr_projecting}
|
||||
show_vore_sfx={show_vore_sfx}
|
||||
/>
|
||||
<LabeledList.Item label="Interior SFX">
|
||||
<VorePanelEditDropdown
|
||||
action="soulcatcher_sfx"
|
||||
editMode={editMode}
|
||||
options={overlayBellies}
|
||||
color={!editMode && !selected_sfx ? 'red' : undefined}
|
||||
entry={selected_sfx || 'Disabled'}
|
||||
tooltip="Allows you to link a belly FX to display to captured souls."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
{editMode && (
|
||||
<LabeledList.Item label="Edit Name">
|
||||
<VorePanelEditText
|
||||
action="soulcatcher_rename"
|
||||
editMode={editMode}
|
||||
tooltipPosition="top"
|
||||
limit={60}
|
||||
min={3}
|
||||
entry={name}
|
||||
tooltip={
|
||||
'Adjust the name of your soulcatcher. [3-60 characters].'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Divider />
|
||||
<Stack.Item>
|
||||
<VorePanelEditTextTabs
|
||||
noHighlight
|
||||
editMode={editMode}
|
||||
messsageOptions={sc_message_data.possible_messages}
|
||||
activeTab={sc_message_data.sc_subtab}
|
||||
tabAction="change_sc_message_option"
|
||||
tooltip={sc_message_data.tooltip}
|
||||
maxLength={sc_message_data.max_length}
|
||||
activeMessage={sc_message_data.active_message}
|
||||
action={sc_message_data.set_action}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, Section, Stack } from 'tgui-core/components';
|
||||
|
||||
import type { bellyData, generalPrefData } from '../types';
|
||||
import { VoreUserPreferencesAesthetic } from '../VoreUserPreferencesTabs/VoreUserPreferencesAesthetic';
|
||||
/**
|
||||
* Subtemplate of VoreBellySelectionAndCustomization
|
||||
*/
|
||||
export const VoreUserGeneral = (props: {
|
||||
general_pref_data?: generalPrefData;
|
||||
editMode: boolean;
|
||||
our_bellies: bellyData[];
|
||||
toggleEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { general_pref_data, editMode, our_bellies, toggleEditMode } = props;
|
||||
|
||||
return (
|
||||
<Section fill>
|
||||
<Stack vertical fill>
|
||||
{!!general_pref_data && (
|
||||
<Stack.Item grow>
|
||||
<VoreUserPreferencesAesthetic
|
||||
editMode={editMode}
|
||||
toggleEditMode={toggleEditMode}
|
||||
active_belly={general_pref_data.active_belly}
|
||||
belly_rub_target={general_pref_data.belly_rub_target}
|
||||
aestethicMessages={general_pref_data.aestethic_messages}
|
||||
our_bellies={our_bellies}
|
||||
vore_sprite_color={general_pref_data.vore_sprite_color}
|
||||
vore_sprite_multiply={general_pref_data.vore_sprite_multiply}
|
||||
vore_icon_options={general_pref_data.vore_icon_options}
|
||||
/>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Divider />
|
||||
<Stack.Item>
|
||||
<Section>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%">
|
||||
<Button fluid icon="save" onClick={() => act('saveprefs')}>
|
||||
Save Prefs
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<Button fluid icon="undo" onClick={() => act('reloadprefs')}>
|
||||
Reload Prefs
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+9
-63
@@ -1,25 +1,20 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, Divider, Section, Stack } from 'tgui-core/components';
|
||||
import { Section } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { digestModeToColor } from './constants';
|
||||
import type { localPrefs, prefData, selectedData } from './types';
|
||||
import { VoreUserPreferencesAesthetic } from './VoreUserPreferencesTabs/VoreUserPreferencesAesthetic';
|
||||
import { VoreUserPreferencesDevouring } from './VoreUserPreferencesTabs/VoreUserPreferencesDevouring';
|
||||
import { VoreUserPreferencesMechanical } from './VoreUserPreferencesTabs/VoreUserPreferencesMechanical';
|
||||
import { VoreUserPreferencesSoulcatcher } from './VoreUserPreferencesTabs/VoreUserPreferencesSoulcatcher';
|
||||
import { VoreUserPreferencesSpawn } from './VoreUserPreferencesTabs/VoreUserPreferencesSpawn';
|
||||
import { VoreUserPreferencesSpontaneous } from './VoreUserPreferencesTabs/VoreUserPreferencesSpontaneous';
|
||||
import { digestModeToColor } from '../constants';
|
||||
import type { localPrefs, prefData } from '../types';
|
||||
import { VoreUserPreferencesDevouring } from '../VoreUserPreferencesTabs/VoreUserPreferencesDevouring';
|
||||
import { VoreUserPreferencesMechanical } from '../VoreUserPreferencesTabs/VoreUserPreferencesMechanical';
|
||||
import { VoreUserPreferencesSoulcatcher } from '../VoreUserPreferencesTabs/VoreUserPreferencesSoulcatcher';
|
||||
import { VoreUserPreferencesSpawn } from '../VoreUserPreferencesTabs/VoreUserPreferencesSpawn';
|
||||
import { VoreUserPreferencesSpontaneous } from '../VoreUserPreferencesTabs/VoreUserPreferencesSpontaneous';
|
||||
|
||||
export const VoreUserPreferences = (props: {
|
||||
prefs: prefData;
|
||||
selected: selectedData | null;
|
||||
show_pictures: BooleanLike;
|
||||
icon_overflow: BooleanLike;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { prefs, selected, show_pictures, icon_overflow } = props;
|
||||
const { prefs, show_pictures, icon_overflow } = props;
|
||||
const {
|
||||
digestable,
|
||||
absorbable,
|
||||
@@ -61,10 +56,7 @@ export const VoreUserPreferences = (props: {
|
||||
no_spawnprey_warning_time,
|
||||
no_spawnpred_warning_save,
|
||||
no_spawnprey_warning_save,
|
||||
nutrition_message_visible,
|
||||
weight_message_visible,
|
||||
selective_active,
|
||||
belly_rub_target,
|
||||
soulcatcher_allow_capture,
|
||||
soulcatcher_allow_transfer,
|
||||
soulcatcher_allow_deletion,
|
||||
@@ -466,32 +458,6 @@ export const VoreUserPreferences = (props: {
|
||||
disabled: 'Mind Transfer Disabled',
|
||||
},
|
||||
},
|
||||
examine_nutrition: {
|
||||
action: 'toggle_nutrition_ex',
|
||||
test: nutrition_message_visible,
|
||||
tooltip: {
|
||||
main: '',
|
||||
enable: 'Click here to enable nutrition messages.',
|
||||
disable: 'Click here to disable nutrition messages.',
|
||||
},
|
||||
content: {
|
||||
enabled: 'Examine Nutrition Messages Active',
|
||||
disabled: 'Examine Nutrition Messages Inactive',
|
||||
},
|
||||
},
|
||||
examine_weight: {
|
||||
action: 'toggle_weight_ex',
|
||||
test: weight_message_visible,
|
||||
tooltip: {
|
||||
main: '',
|
||||
enable: 'Click here to enable weight messages.',
|
||||
disable: 'Click here to disable weight messages.',
|
||||
},
|
||||
content: {
|
||||
enabled: 'Examine Weight Messages Active',
|
||||
disabled: 'Examine Weight Messages Inactive',
|
||||
},
|
||||
},
|
||||
strippref: {
|
||||
action: 'toggle_strippref',
|
||||
test: strip_mechanics_active,
|
||||
@@ -748,26 +714,6 @@ export const VoreUserPreferences = (props: {
|
||||
no_spawnprey_warning_time={no_spawnprey_warning_time}
|
||||
no_spawnprey_warning_save={no_spawnprey_warning_save}
|
||||
/>
|
||||
<VoreUserPreferencesAesthetic
|
||||
preferences={preferences}
|
||||
belly_rub_target={belly_rub_target}
|
||||
selected={selected}
|
||||
/>
|
||||
<Divider />
|
||||
<Section>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%">
|
||||
<Button fluid icon="save" onClick={() => act('saveprefs')}>
|
||||
Save Prefs
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<Button fluid icon="undo" onClick={() => act('reloadprefs')}>
|
||||
Reload Prefs
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
import { useState } from 'react';
|
||||
import { Tabs } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { hostMob, selectedData } from './types';
|
||||
import { VoreContentsPanel } from './VoreContentsPanel';
|
||||
import { VoreSelectedBellyControls } from './VoreSelectedBellyTabs/VoreSelectedBellyControls';
|
||||
import { VoreSelectedBellyDescriptions } from './VoreSelectedBellyTabs/VoreSelectedBellyDescriptions';
|
||||
import { VoreSelectedBellyInteractions } from './VoreSelectedBellyTabs/VoreSelectedBellyInteractions';
|
||||
import { VoreSelectedBellyLiquidMessages } from './VoreSelectedBellyTabs/VoreSelectedBellyLiquidMessages';
|
||||
import { VoreSelectedBellyLiquidOptions } from './VoreSelectedBellyTabs/VoreSelectedBellyLiquidOptions';
|
||||
import { VoreSelectedBellyOptions } from './VoreSelectedBellyTabs/VoreSelectedBellyOptions';
|
||||
import { VoreSelectedBellySounds } from './VoreSelectedBellyTabs/VoreSelectedBellySounds';
|
||||
import { VoreSelectedBellyVisuals } from './VoreSelectedBellyTabs/VoreSelectedBellyVisuals';
|
||||
/**
|
||||
* Subtemplate of VoreBellySelectionAndCustomization
|
||||
*/
|
||||
export const VoreSelectedBelly = (props: {
|
||||
belly: selectedData;
|
||||
show_pictures: BooleanLike;
|
||||
host_mobtype: hostMob;
|
||||
icon_overflow: BooleanLike;
|
||||
vore_words: Record<string, string[]>;
|
||||
}) => {
|
||||
const { belly, show_pictures, host_mobtype, icon_overflow, vore_words } =
|
||||
props;
|
||||
const { contents } = belly;
|
||||
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
|
||||
const tabs: React.JSX.Element[] = [];
|
||||
|
||||
tabs[0] = <VoreSelectedBellyControls belly={belly} />;
|
||||
tabs[1] = (
|
||||
<VoreSelectedBellyDescriptions belly={belly} vore_words={vore_words} />
|
||||
);
|
||||
tabs[2] = (
|
||||
<VoreSelectedBellyOptions belly={belly} host_mobtype={host_mobtype} />
|
||||
);
|
||||
tabs[3] = <VoreSelectedBellySounds belly={belly} />;
|
||||
tabs[4] = <VoreSelectedBellyVisuals belly={belly} />;
|
||||
tabs[5] = <VoreSelectedBellyInteractions belly={belly} />;
|
||||
tabs[6] = (
|
||||
<VoreContentsPanel
|
||||
outside
|
||||
contents={contents}
|
||||
show_pictures={show_pictures}
|
||||
icon_overflow={icon_overflow}
|
||||
/>
|
||||
);
|
||||
tabs[7] = <VoreSelectedBellyLiquidOptions belly={belly} />;
|
||||
tabs[8] = <VoreSelectedBellyLiquidMessages belly={belly} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs>
|
||||
<Tabs.Tab selected={tabIndex === 0} onClick={() => setTabIndex(0)}>
|
||||
Controls
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 1} onClick={() => setTabIndex(1)}>
|
||||
Descriptions
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 2} onClick={() => setTabIndex(2)}>
|
||||
Options
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 3} onClick={() => setTabIndex(3)}>
|
||||
Sounds
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 4} onClick={() => setTabIndex(4)}>
|
||||
Visuals
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 5} onClick={() => setTabIndex(5)}>
|
||||
Interactions
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 6} onClick={() => setTabIndex(6)}>
|
||||
Contents ({contents.length})
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 7} onClick={() => setTabIndex(7)}>
|
||||
Liquid Options
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tabIndex === 8} onClick={() => setTabIndex(8)}>
|
||||
Liquid Messages
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{tabs[tabIndex] || 'Error'}
|
||||
</>
|
||||
);
|
||||
};
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export const VoreSelectedBellyDescriptionsBellymode = (props: {
|
||||
message_mode: BooleanLike;
|
||||
mode: string;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { message_mode, mode } = props;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Bellymode Messages">
|
||||
{(message_mode || mode === 'Digest' || mode === 'Selective') && (
|
||||
<Stack wrap>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'dmp' })
|
||||
}
|
||||
>
|
||||
Digest Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'dmo' })
|
||||
}
|
||||
>
|
||||
Digest Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
{(message_mode || mode === 'Absorb' || mode === 'Selective') && (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'amp' })
|
||||
}
|
||||
>
|
||||
Absorb Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'amo' })
|
||||
}
|
||||
>
|
||||
Absorb Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
{(message_mode || mode === 'Unabsorb') && (
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'uamp' })
|
||||
}
|
||||
>
|
||||
Unabsorb Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'uamo' })
|
||||
}
|
||||
>
|
||||
Unabsorb Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
-203
@@ -1,203 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { interactData } from '../types';
|
||||
|
||||
export const VoreSelectedBellyDescriptionsEscape = (props: {
|
||||
message_mode: BooleanLike;
|
||||
interacts: interactData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { message_mode, interacts } = props;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Escape Messages">
|
||||
<Stack wrap>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'escap' })
|
||||
}
|
||||
>
|
||||
Escape Attempt Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'escao' })
|
||||
}
|
||||
>
|
||||
Escape Attempt Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
{(message_mode || interacts.escapechance > 0) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'escp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Escape Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'esco',
|
||||
})
|
||||
}
|
||||
>
|
||||
Escape Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'escout',
|
||||
})
|
||||
}
|
||||
>
|
||||
Escape Message (outside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'escip' })
|
||||
}
|
||||
>
|
||||
Escape Item Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'escio' })
|
||||
}
|
||||
>
|
||||
Escape Item Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'esciout',
|
||||
})
|
||||
}
|
||||
>
|
||||
Escape Item Message (outside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'escfp' })
|
||||
}
|
||||
>
|
||||
Escape Fail Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'escfo' })
|
||||
}
|
||||
>
|
||||
Escape Fail Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'aescap' })
|
||||
}
|
||||
>
|
||||
Absorbed Escape Attempt Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'aescao' })
|
||||
}
|
||||
>
|
||||
Absorbed Escape Attempt Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
{(message_mode || interacts.escapechance_absorbed > 0) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'aescp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Absorbed Escape Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'aesco',
|
||||
})
|
||||
}
|
||||
>
|
||||
Absorbed Escape Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'aescout',
|
||||
})
|
||||
}
|
||||
>
|
||||
Absorbed Escape Message (outside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'aescfp' })
|
||||
}
|
||||
>
|
||||
Absorbed Escape Fail Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'aescfo' })
|
||||
}
|
||||
>
|
||||
Absorbed Escape Fail Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
-170
@@ -1,170 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export const VoreSelectedBellyDescriptionsIdle = (props: {
|
||||
message_mode: BooleanLike;
|
||||
mode: string;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { message_mode, mode } = props;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Idle Messages">
|
||||
<Stack wrap>
|
||||
{(message_mode || mode === 'Hold' || mode === 'Selective') && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_hold',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Hold)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_holdabsorbed',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Hold Absorbed)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
{(message_mode || mode === 'Digest' || mode === 'Selective') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_digest',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Digest)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Absorb' || mode === 'Selective') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_absorb',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Absorb)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Unabsorb') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_unabsorb',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Unabsorb)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Drain' || mode === 'Selective') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_drain',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Drain)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Heal') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_heal',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Heal)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Size Steal') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_steal',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Size Steal)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Shrink') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_shrink',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Shrink)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Grow') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'im_grow',
|
||||
})
|
||||
}
|
||||
>
|
||||
Idle Messages (Grow)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{(message_mode || mode === 'Encase In Egg') && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'im_egg' })
|
||||
}
|
||||
>
|
||||
Idle Messages (Encase In Egg)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { interactData } from '../types';
|
||||
|
||||
export const VoreSelectedBellyDescriptionsInteractionChance = (props: {
|
||||
message_mode: BooleanLike;
|
||||
interacts: interactData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { message_mode, interacts } = props;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Interaction Chance Messages">
|
||||
<Stack wrap>
|
||||
{(message_mode || interacts.digestchance > 0) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'stmodp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Interaction Chance Digest Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'stmodo',
|
||||
})
|
||||
}
|
||||
>
|
||||
Interaction Chance Digest Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
{(message_mode || interacts.absorbchance > 0) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'stmoap',
|
||||
})
|
||||
}
|
||||
>
|
||||
Interaction Chance Absorb Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'stmoao',
|
||||
})
|
||||
}
|
||||
>
|
||||
Interaction Chance Absorb Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
|
||||
export const VoreSelectedBellyDescriptionsStruggle = (props) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Struggle Messages">
|
||||
<Stack wrap>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'smo' })
|
||||
}
|
||||
>
|
||||
Struggle Message (outside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'smi' })
|
||||
}
|
||||
>
|
||||
Struggle Message (inside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'asmo' })
|
||||
}
|
||||
>
|
||||
Absorbed Struggle Message (outside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'asmi' })
|
||||
}
|
||||
>
|
||||
Absorbed Struggle Message (inside)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { autotransferData, interactData } from '../types';
|
||||
|
||||
export const VoreSelectedBellyDescriptionsTransfer = (props: {
|
||||
message_mode: BooleanLike;
|
||||
interacts: interactData;
|
||||
autotransfer: autotransferData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { message_mode, interacts, autotransfer } = props;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Transfer Messages">
|
||||
<Stack wrap>
|
||||
{(message_mode || !!interacts.transferlocation) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'trnspp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Primary Transfer Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'trnspo',
|
||||
})
|
||||
}
|
||||
>
|
||||
Primary Transfer Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
{(message_mode || !!interacts.transferlocation_secondary) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'trnssp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Secondary Transfer Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'trnsso',
|
||||
})
|
||||
}
|
||||
>
|
||||
Secondary Transfer Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
{(message_mode || !!autotransfer.autotransferlocation) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'atrnspp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Primary Auto-Transfer Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'atrnspo',
|
||||
})
|
||||
}
|
||||
>
|
||||
Primary Auto-Transfer Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
{(message_mode || !!autotransfer.autotransferlocation_secondary) && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'atrnssp',
|
||||
})
|
||||
}
|
||||
>
|
||||
Secondary Auto-Transfer Message (to prey)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'atrnsso',
|
||||
})
|
||||
}
|
||||
>
|
||||
Secondary Auto-Transfer Message (to you)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
);
|
||||
};
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Button,
|
||||
LabeledList,
|
||||
Section,
|
||||
Stack,
|
||||
Tabs,
|
||||
} from 'tgui-core/components';
|
||||
import { type BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { messageTabLabel } from '../../constants';
|
||||
import type { bellyDescriptionData } from '../../types';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditTextArea } from '../../VorePanelElements/VorePanelTextArea';
|
||||
|
||||
export const VoreSelectedBellyDescriptionMatrix = (props: {
|
||||
showAll: BooleanLike;
|
||||
showFormatHelp: boolean;
|
||||
onShowFormatHelp: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
editMode: boolean;
|
||||
bellyDescriptionData: bellyDescriptionData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
showAll,
|
||||
showFormatHelp,
|
||||
onShowFormatHelp,
|
||||
editMode,
|
||||
bellyDescriptionData,
|
||||
} = props;
|
||||
const {
|
||||
displayed_options,
|
||||
message_option,
|
||||
message_subtab,
|
||||
displayed_message_types,
|
||||
selected_message,
|
||||
} = bellyDescriptionData;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Messages"
|
||||
fill
|
||||
buttons={
|
||||
<Stack>
|
||||
{editMode && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
color="red"
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_msgs',
|
||||
msgtype: 'reset',
|
||||
})
|
||||
}
|
||||
>
|
||||
Reset Messages
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item>
|
||||
<Button
|
||||
tooltip={
|
||||
(showAll ? 'Hides' : 'Shows') + ' all possible belly messages.'
|
||||
}
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_message_mode',
|
||||
})
|
||||
}
|
||||
icon={'eye'}
|
||||
selected={showAll}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="question"
|
||||
tooltip="Formatting help"
|
||||
onClick={() => onShowFormatHelp(!showFormatHelp)}
|
||||
selected={showFormatHelp}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<Stack fill>
|
||||
<Stack.Item basis="16%">
|
||||
<Stack vertical>
|
||||
<Stack.Item basis="1.667rem" />
|
||||
<Stack.Item>
|
||||
<Tabs vertical>
|
||||
{displayed_options.map((index) => (
|
||||
<Tabs.Tab
|
||||
key={index}
|
||||
selected={index === message_option}
|
||||
onClick={() => {
|
||||
if (index !== message_option) {
|
||||
act('change_message_option', { tab: index });
|
||||
}
|
||||
}}
|
||||
>
|
||||
{messageTabLabel[index]}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Stack fill vertical ml="5px">
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
{!!displayed_message_types &&
|
||||
!!displayed_message_types.subtypes && (
|
||||
<Tabs>
|
||||
{displayed_message_types.subtypes.map((subtype) => (
|
||||
<Tabs.Tab
|
||||
key={subtype}
|
||||
selected={subtype === message_subtab}
|
||||
onClick={() => {
|
||||
if (subtype !== message_subtab) {
|
||||
act('change_message_type', { tab: subtype });
|
||||
}
|
||||
}}
|
||||
>
|
||||
{subtype}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item grow />
|
||||
<Stack.Item>
|
||||
{!!displayed_message_types &&
|
||||
!!displayed_message_types.possible_messages && (
|
||||
<Tabs>
|
||||
{displayed_message_types.possible_messages.map(
|
||||
(message_tyxpe) => (
|
||||
<Tabs.Tab
|
||||
key={message_tyxpe}
|
||||
selected={message_tyxpe === selected_message}
|
||||
onClick={() => {
|
||||
if (message_tyxpe !== selected_message) {
|
||||
act('set_current_message', {
|
||||
tab: message_tyxpe,
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{message_tyxpe}
|
||||
</Tabs.Tab>
|
||||
),
|
||||
)}
|
||||
</Tabs>
|
||||
)}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
{!!selected_message && !!displayed_message_types && (
|
||||
<Stack vertical fill>
|
||||
{!!displayed_message_types.button_action && (
|
||||
<Stack.Item>
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label={displayed_message_types.button_label}
|
||||
>
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction={displayed_message_types.button_action}
|
||||
editMode={editMode}
|
||||
active={!!displayed_message_types.button_data}
|
||||
tooltip={
|
||||
(displayed_message_types.button_data
|
||||
? 'Dis'
|
||||
: 'En') +
|
||||
'ables ' +
|
||||
displayed_message_types.button_tooltip
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<Stack.Item grow>
|
||||
<VorePanelEditTextArea
|
||||
editMode={editMode}
|
||||
tooltip={displayed_message_types.tooltip}
|
||||
limit={displayed_message_types.max_length}
|
||||
entry={displayed_message_types.active_message || ''}
|
||||
action={'set_attribute'}
|
||||
listAction={'b_msgs'}
|
||||
subAction={displayed_message_types.set_action}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
import { LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
|
||||
import type { autoTransferOption, DropdownEntry } from '../../types';
|
||||
import { VorePanelEditCheckboxes } from '../../VorePanelElements/VorePanelEditCheckboxes';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../../VorePanelElements/VorePanelEditNumber';
|
||||
|
||||
export const AutoTransferOptions = (props: {
|
||||
editMode: boolean;
|
||||
title: string;
|
||||
bellyDropdownNames: DropdownEntry[];
|
||||
locationNames: DropdownEntry[];
|
||||
autotransferData: autoTransferOption;
|
||||
}) => {
|
||||
const {
|
||||
editMode,
|
||||
title,
|
||||
bellyDropdownNames,
|
||||
locationNames,
|
||||
autotransferData,
|
||||
} = props;
|
||||
const {
|
||||
autotransferchance,
|
||||
autotransferlocation,
|
||||
autotransferextralocation,
|
||||
autotransfer_whitelist,
|
||||
autotransfer_blacklist,
|
||||
autotransfer_whitelist_items,
|
||||
autotransfer_blacklist_items,
|
||||
} = autotransferData;
|
||||
|
||||
const transferCheckboxes = bellyDropdownNames.map((entry) => {
|
||||
return {
|
||||
label: entry.displayText,
|
||||
ref: entry.value,
|
||||
selection: autotransferextralocation.includes(entry.displayText),
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<Section title={capitalize(title) + ' Auto-Transfer'}>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList.Item label="Auto-Transfer Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransferchance_' + title}
|
||||
editMode={editMode}
|
||||
value={autotransferchance}
|
||||
unit="%"
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
tooltip={
|
||||
'Set ' +
|
||||
title +
|
||||
' belly auto-transfer chance. You must also set the location for this to have any effect.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList.Item label="Auto-Transfer Location">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransferlocation_' + title}
|
||||
editMode={editMode}
|
||||
options={locationNames}
|
||||
color={!editMode && !autotransferlocation ? 'red' : undefined}
|
||||
entry={
|
||||
autotransferlocation ? autotransferlocation : 'Disabled'
|
||||
}
|
||||
tooltip={
|
||||
'Target location of the ' + title + ' auto-transfer.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Auto-Transfer Extra Location">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={transferCheckboxes}
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransferextralocation_' + title}
|
||||
tooltip={'Set additional ' + title + ' transfer locations.'}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Whitelist (Mobs)">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={autotransfer_whitelist}
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransfer_whitelist_' + title}
|
||||
tooltip={
|
||||
'Whitelist mob types for your ' +
|
||||
title +
|
||||
' transfer location.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Whitelist (Items)">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={autotransfer_whitelist_items}
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransfer_whitelist_items_' + title}
|
||||
tooltip={
|
||||
'Whitelist item types for your ' +
|
||||
title +
|
||||
' transfer location.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Blacklist (Mobs)">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={autotransfer_blacklist}
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransfer_blacklist_' + title}
|
||||
tooltip={
|
||||
'Blacklist mob types for your ' +
|
||||
title +
|
||||
' transfer location.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Blacklist (Items)">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={autotransfer_blacklist_items}
|
||||
action="set_attribute"
|
||||
subAction={'b_autotransfer_blacklist_items_' + title}
|
||||
tooltip={
|
||||
'Blacklist item types for your ' +
|
||||
title +
|
||||
' transfer location.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
import { Box, LabeledList, Stack } from 'tgui-core/components';
|
||||
|
||||
import { reagentToColor } from '../../constants';
|
||||
import type { liqInteractData } from '../../types';
|
||||
import { VorePanelEditColor } from '../../VorePanelElements/VorePanelEditColor';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditText } from '../../VorePanelElements/VorePanelEditText';
|
||||
|
||||
export const LiquidOptionsLeft = (props: {
|
||||
editMode: boolean;
|
||||
liquidInteract: liqInteractData;
|
||||
}) => {
|
||||
const { editMode, liquidInteract } = props;
|
||||
const {
|
||||
liq_reagent_gen,
|
||||
liq_reagent_type,
|
||||
liq_reagent_types,
|
||||
liq_custom_name_max,
|
||||
liq_custom_name_min,
|
||||
liq_reagent_name,
|
||||
liq_sloshing,
|
||||
custom_reagentcolor,
|
||||
custom_reagentalpha,
|
||||
liquid_overlay,
|
||||
mush_overlay,
|
||||
mush_color,
|
||||
mush_alpha,
|
||||
min_mush,
|
||||
metabolism_overlay,
|
||||
metabolism_mush_ratio,
|
||||
custom_ingested_color,
|
||||
custom_ingested_alpha,
|
||||
} = liquidInteract;
|
||||
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Generate Liquids">
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_gen"
|
||||
editMode={editMode}
|
||||
active={!!liq_reagent_gen}
|
||||
content={liq_reagent_gen ? 'On' : 'Off'}
|
||||
tooltip={
|
||||
(liq_reagent_gen ? 'Dis' : 'En') +
|
||||
'ables reagent creation for this belly.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Type">
|
||||
<VorePanelEditDropdown
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_type"
|
||||
color={reagentToColor[liq_reagent_type]}
|
||||
editMode={editMode}
|
||||
options={liq_reagent_types}
|
||||
entry={liq_reagent_type}
|
||||
tooltip="Select the reagent to produce."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Name">
|
||||
<VorePanelEditText
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_name"
|
||||
editMode={editMode}
|
||||
limit={liq_custom_name_max}
|
||||
min={liq_custom_name_min}
|
||||
entry={liq_reagent_name}
|
||||
tooltip={
|
||||
"New name for liquid shown when transfering and dumping on floor (The actual liquid's name is still the same) [" +
|
||||
liq_custom_name_min +
|
||||
'-' +
|
||||
liq_custom_name_max +
|
||||
' characters].'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Slosh Sounds">
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_sloshing"
|
||||
editMode={editMode}
|
||||
active={!!liq_sloshing}
|
||||
content={liq_sloshing ? 'On' : 'Off'}
|
||||
tooltip="Should this belly be considered for sloshing sounds when full?."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Overlay">
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liquid_overlay"
|
||||
editMode={editMode}
|
||||
active={!!liquid_overlay}
|
||||
content={liquid_overlay ? 'On' : 'Off'}
|
||||
tooltip="Should this belly display liquid overlays to prey?."
|
||||
/>
|
||||
</Stack.Item>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_custom_reagentcolor"
|
||||
value_of={null}
|
||||
back_color={custom_reagentcolor}
|
||||
tooltip="Select your reagent overlay color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_custom_reagentalpha"
|
||||
value_of={null}
|
||||
back_color="#FFFFFF"
|
||||
alpha={custom_reagentalpha || 0}
|
||||
tooltip="Set your reagent overlay transparency. 0 to use the Default."
|
||||
/>
|
||||
{!custom_reagentalpha && (
|
||||
<Stack.Item>
|
||||
<Box color="label">(Default)</Box>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Fullness Overlay">
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_mush_overlay"
|
||||
editMode={editMode}
|
||||
active={!!mush_overlay}
|
||||
content={mush_overlay ? 'On' : 'Off'}
|
||||
tooltip="Should this belly display mush overlays to prey?."
|
||||
/>
|
||||
</Stack.Item>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_mush_color"
|
||||
value_of={null}
|
||||
back_color={mush_color}
|
||||
tooltip="Select your mush overlay color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_mush_alpha"
|
||||
value_of={null}
|
||||
back_color="#FFFFFF"
|
||||
alpha={mush_alpha}
|
||||
tooltip="Set your mush overlay transparency."
|
||||
/>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Minimum Mush Level">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_min_mush"
|
||||
editMode={editMode}
|
||||
value={min_mush}
|
||||
unit="%"
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
tooltip="Set custom minimum mush level."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Overlay">
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_metabolism_overlay"
|
||||
editMode={editMode}
|
||||
active={!!metabolism_overlay}
|
||||
content={metabolism_overlay ? 'On' : 'Off'}
|
||||
tooltip="Should this belly display metabolism overlays to prey?."
|
||||
/>
|
||||
</Stack.Item>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_custom_ingested_color"
|
||||
value_of={null}
|
||||
back_color={custom_ingested_color}
|
||||
tooltip="Select your metabolism overlay color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_custom_ingested_alpha"
|
||||
value_of={null}
|
||||
back_color="#FFFFFF"
|
||||
alpha={custom_ingested_alpha}
|
||||
tooltip="Set your metabolism overlay transparency."
|
||||
/>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Mush Ratio">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_metabolism_mush_ratio"
|
||||
editMode={editMode}
|
||||
value={metabolism_mush_ratio}
|
||||
unit="fullness per u"
|
||||
minValue={0}
|
||||
maxValue={500}
|
||||
tooltip="How much should ingested reagents affect fullness overlay compared to nutrition? Nutrition units per reagent unit. Default 15."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
);
|
||||
};
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
import { LabeledList } from 'tgui-core/components';
|
||||
|
||||
import { nutriTimeToText } from '../../constants';
|
||||
import type { liqInteractData } from '../../types';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditText } from '../../VorePanelElements/VorePanelEditText';
|
||||
|
||||
export const LiquidOptionsRight = (props: {
|
||||
editMode: boolean;
|
||||
liquidInteract: liqInteractData;
|
||||
}) => {
|
||||
const { editMode, liquidInteract } = props;
|
||||
const {
|
||||
liq_reagent_transfer_verb,
|
||||
liq_reagent_nutri_rate,
|
||||
liq_reagent_capacity,
|
||||
liq_custom_name_max,
|
||||
liq_custom_name_min,
|
||||
max_liquid_level,
|
||||
reagent_touches,
|
||||
max_mush,
|
||||
item_mush_val,
|
||||
max_ingested,
|
||||
} = liquidInteract;
|
||||
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Liquid Capacity">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_capacity"
|
||||
editMode={editMode}
|
||||
value={liq_reagent_capacity}
|
||||
minValue={10}
|
||||
maxValue={300}
|
||||
unit="u"
|
||||
tooltip="Choose the amount of liquid the belly can contain at most. Ranges from 10 to 300."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Generation Time">
|
||||
<VorePanelEditDropdown
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_nutri_rate"
|
||||
editMode={editMode}
|
||||
options={Object.values(nutriTimeToText)}
|
||||
entry={nutriTimeToText[liq_reagent_nutri_rate]}
|
||||
tooltip="Choose the time it takes to fill the belly from empty state using nutrition."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Transfer Verb">
|
||||
<VorePanelEditText
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_transfer_verb"
|
||||
editMode={editMode}
|
||||
limit={liq_custom_name_max}
|
||||
min={liq_custom_name_min}
|
||||
entry={liq_reagent_transfer_verb}
|
||||
tooltip={
|
||||
'Adjust vore liquid verb. [' +
|
||||
liq_custom_name_min +
|
||||
'-' +
|
||||
liq_reagent_transfer_verb +
|
||||
' characters].'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Application to Prey">
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_reagent_touches"
|
||||
editMode={editMode}
|
||||
active={!!reagent_touches}
|
||||
content={reagent_touches ? 'On' : 'Off'}
|
||||
tooltip="Should liquids be applied to the prey during digestion?."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Max Liquid Level">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_max_liquid_level"
|
||||
editMode={editMode}
|
||||
value={max_liquid_level}
|
||||
unit="%"
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
tooltip="The overlay coverage of the screen."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mush Overlay Scaling">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_max_mush"
|
||||
editMode={editMode}
|
||||
value={max_mush}
|
||||
unit="nutrition"
|
||||
minValue={0}
|
||||
maxValue={6000}
|
||||
tooltip="Choose the amount of nutrition required for full mush overlay. Ranges from 0 to 6000. Default 500."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Item Mush Value">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_item_mush_val"
|
||||
editMode={editMode}
|
||||
value={item_mush_val}
|
||||
unit="fullness per item"
|
||||
minValue={0}
|
||||
maxValue={1000}
|
||||
tooltip="Set how much solid belly contents affect mush level per item."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Overlay Scaling">
|
||||
<VorePanelEditNumber
|
||||
action="liq_set_attribute"
|
||||
subAction="b_max_ingested"
|
||||
editMode={editMode}
|
||||
value={max_ingested}
|
||||
unit="u"
|
||||
minValue={0}
|
||||
maxValue={6000}
|
||||
tooltip="Choose the amount of reagents within ingested metabolism required for full mush overlay when not using mush overlay option. Ranges from 0 to 6000. Default 500."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
);
|
||||
};
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
import { LabeledList, Stack } from 'tgui-core/components';
|
||||
|
||||
import { eatingMessagePrivacy } from '../../constants';
|
||||
import { sanitize_color } from '../../functions';
|
||||
import type { bellyOptionData, hostMob } from '../../types';
|
||||
import { VorePanelColorBox } from '../../VorePanelElements/VorePanelCommonElements';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VoreSelectedWhitelist } from '../VisualTab/VoreSelecetedWhitelist';
|
||||
import { VoreSelectedMobTypeBellyButtons } from '../VisualTab/VoreSelectedMobTypeBellyButtons';
|
||||
|
||||
export const BellyOptionsLeft = (props: {
|
||||
editMode: boolean;
|
||||
bellyOptionData: bellyOptionData;
|
||||
host_mobtype: hostMob;
|
||||
}) => {
|
||||
const { editMode, bellyOptionData, host_mobtype } = props;
|
||||
const {
|
||||
can_taste,
|
||||
is_feedable,
|
||||
nutrition_percent,
|
||||
bulge_size,
|
||||
contaminates,
|
||||
contaminate_flavor,
|
||||
contaminate_color,
|
||||
contaminate_options,
|
||||
contaminate_colors,
|
||||
save_digest_mode,
|
||||
eating_privacy_local,
|
||||
private_struggle,
|
||||
mob_belly_controls,
|
||||
vorespawn_blacklist,
|
||||
vorespawn_whitelist,
|
||||
vorespawn_absorbed,
|
||||
} = bellyOptionData;
|
||||
|
||||
return (
|
||||
<>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Can Taste">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_tastes"
|
||||
editMode={editMode}
|
||||
active={!!can_taste}
|
||||
content={can_taste ? 'Yes' : 'No'}
|
||||
tooltip={
|
||||
(can_taste ? 'Dis' : 'En') +
|
||||
'ables the ability for this belly to taste prey.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Feedable">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_feedable"
|
||||
editMode={editMode}
|
||||
active={!!is_feedable}
|
||||
content={is_feedable ? 'Yes' : 'No'}
|
||||
tooltip={
|
||||
(is_feedable ? 'Dis' : 'En') +
|
||||
'ables the ability for this belly to have prey fed to.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Contaminates">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_contaminates"
|
||||
editMode={editMode}
|
||||
active={!!contaminates}
|
||||
content={contaminates ? 'Yes' : 'No'}
|
||||
tooltip={
|
||||
(contaminates ? 'Dis' : 'En') +
|
||||
'ables the ability for this belly to contaminate items, requiring them to be washed clean.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
{!!contaminates && (
|
||||
<>
|
||||
<LabeledList.Item label="Contamination Flavor">
|
||||
<VorePanelEditDropdown
|
||||
editMode={editMode}
|
||||
options={
|
||||
contaminate_options ? Object.keys(contaminate_options) : []
|
||||
}
|
||||
entry={contaminate_flavor ? contaminate_flavor : ''}
|
||||
action="set_attribute"
|
||||
subAction="b_contamination_flavor"
|
||||
tooltip="The flavour of your item contamination."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Contamination Color">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<VorePanelEditDropdown
|
||||
editMode={editMode}
|
||||
options={contaminate_colors ? contaminate_colors : []}
|
||||
entry={contaminate_color ? contaminate_color : ''}
|
||||
action="set_attribute"
|
||||
subAction="b_contamination_color"
|
||||
tooltip="The color overlay of your item contamination."
|
||||
/>
|
||||
</Stack.Item>
|
||||
{!editMode && (
|
||||
<Stack.Item>
|
||||
<VorePanelColorBox
|
||||
pixelSize={15}
|
||||
back_color={sanitize_color(contaminate_color) || 'white'}
|
||||
/>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</>
|
||||
)}
|
||||
<LabeledList.Item label="Nutritional Gain">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_nutritionpercent"
|
||||
editMode={editMode}
|
||||
value={nutrition_percent}
|
||||
minValue={0.01}
|
||||
maxValue={100}
|
||||
step={0.01}
|
||||
stepPixel={0.1}
|
||||
digits={2}
|
||||
unit="%"
|
||||
tooltip="The multiplier for nutrition you'll fain from prey."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Required Examine Size">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_bulge_size"
|
||||
editMode={editMode}
|
||||
value={bulge_size * 100}
|
||||
minValue={0}
|
||||
maxValue={200}
|
||||
unit="%"
|
||||
tooltip="The minimum size for prey to show in examine. Type 0 to disable."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Toggle Vore Privacy">
|
||||
<VorePanelEditDropdown
|
||||
editMode={editMode}
|
||||
options={Object.keys(eatingMessagePrivacy)}
|
||||
entry={eating_privacy_local}
|
||||
action="set_attribute"
|
||||
subAction="b_eating_privacy"
|
||||
color={eatingMessagePrivacy[eating_privacy_local]}
|
||||
tooltip="Allows to override the global audible range of your attempt and success messages for this belly."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Toggle Struggle Privacy">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_private_struggle"
|
||||
editMode={editMode}
|
||||
active={!!private_struggle}
|
||||
content={private_struggle ? 'Private' : 'Loud'}
|
||||
tooltip={
|
||||
(private_struggle ? 'Dis' : 'En') +
|
||||
'ables subtle struggle messages.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Save Digest Mode">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_save_digest_mode"
|
||||
editMode={editMode}
|
||||
active={!!save_digest_mode}
|
||||
tooltip={
|
||||
(save_digest_mode ? 'Dis' : 'En') +
|
||||
'ables persistent digest mode.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<VoreSelectedMobTypeBellyButtons
|
||||
editMode={editMode}
|
||||
bellyControl={mob_belly_controls}
|
||||
host_mobtype={host_mobtype}
|
||||
/>
|
||||
<VoreSelectedWhitelist
|
||||
editMode={editMode}
|
||||
vorespawnBlacklist={vorespawn_blacklist}
|
||||
vorespawnWhitelist={vorespawn_whitelist}
|
||||
vorespawnAbsorbed={vorespawn_absorbed}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
import { LabeledList } from 'tgui-core/components';
|
||||
|
||||
import { digestModeToColor, selectiveBellyOptions } from '../../constants';
|
||||
import type { bellyOptionData } from '../../types';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditText } from '../../VorePanelElements/VorePanelEditText';
|
||||
|
||||
export const BellyOptionsRight = (props: {
|
||||
editMode: boolean;
|
||||
bellyOptionData: bellyOptionData;
|
||||
}) => {
|
||||
const { editMode, bellyOptionData } = props;
|
||||
const {
|
||||
digest_brute,
|
||||
digest_burn,
|
||||
digest_oxy,
|
||||
digest_tox,
|
||||
digest_clone,
|
||||
digest_max,
|
||||
digest_free,
|
||||
shrink_grow_size,
|
||||
egg_type,
|
||||
egg_types,
|
||||
egg_name,
|
||||
egg_size,
|
||||
recycling,
|
||||
storing_nutrition,
|
||||
selective_preference,
|
||||
drainmode_options,
|
||||
drainmode,
|
||||
} = bellyOptionData;
|
||||
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Digest Brute Damage">
|
||||
<VorePanelEditNumber
|
||||
tooltip={
|
||||
'Choose the amount of brute damage prey will take per tick. Max of ' +
|
||||
digest_max +
|
||||
' across all damage types. ' +
|
||||
digest_free +
|
||||
' remaining.'
|
||||
}
|
||||
action="set_attribute"
|
||||
subAction="b_brute_dmg"
|
||||
editMode={editMode}
|
||||
value={digest_brute}
|
||||
minValue={0}
|
||||
step={0.001}
|
||||
stepPixel={0.1}
|
||||
digits={3}
|
||||
maxValue={digest_free + digest_brute}
|
||||
color="red"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Burn Damage">
|
||||
<VorePanelEditNumber
|
||||
tooltip={
|
||||
'Choose the amount of burn damage prey will take per tick. Max of ' +
|
||||
digest_max +
|
||||
' across all damage types. ' +
|
||||
digest_free +
|
||||
' remaining.'
|
||||
}
|
||||
action="set_attribute"
|
||||
subAction="b_burn_dmg"
|
||||
editMode={editMode}
|
||||
value={digest_burn}
|
||||
minValue={0}
|
||||
step={0.001}
|
||||
stepPixel={0.1}
|
||||
digits={3}
|
||||
maxValue={digest_free + digest_burn}
|
||||
color="orange"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Suffocation Damage">
|
||||
<VorePanelEditNumber
|
||||
tooltip={
|
||||
'Choose the amount of oxygen damage prey will take per tick. Max of ' +
|
||||
digest_max +
|
||||
' across all damage types. ' +
|
||||
digest_free +
|
||||
' remaining.'
|
||||
}
|
||||
action="set_attribute"
|
||||
subAction="b_oxy_dmg"
|
||||
editMode={editMode}
|
||||
value={digest_oxy}
|
||||
minValue={0}
|
||||
step={0.001}
|
||||
stepPixel={0.1}
|
||||
digits={3}
|
||||
maxValue={digest_free + digest_oxy}
|
||||
color="blue"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Toxins Damage">
|
||||
<VorePanelEditNumber
|
||||
tooltip={
|
||||
'Choose the amount of toxin damage prey will take per tick. Max of ' +
|
||||
digest_max +
|
||||
' across all damage types. ' +
|
||||
digest_free +
|
||||
' remaining.'
|
||||
}
|
||||
action="set_attribute"
|
||||
subAction="b_tox_dmg"
|
||||
editMode={editMode}
|
||||
value={digest_tox}
|
||||
minValue={0}
|
||||
step={0.001}
|
||||
stepPixel={0.1}
|
||||
digits={3}
|
||||
maxValue={digest_free + digest_tox}
|
||||
color="green"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Clone Damage">
|
||||
<VorePanelEditNumber
|
||||
tooltip={
|
||||
'Choose the amount of genetic (clone) damage prey will take per tick. Max of ' +
|
||||
digest_max +
|
||||
' across all damage types. ' +
|
||||
digest_free +
|
||||
' remaining.'
|
||||
}
|
||||
action="set_attribute"
|
||||
subAction="b_clone_dmg"
|
||||
editMode={editMode}
|
||||
value={digest_clone}
|
||||
minValue={0}
|
||||
step={0.001}
|
||||
stepPixel={0.1}
|
||||
digits={3}
|
||||
maxValue={digest_free + digest_clone}
|
||||
color="purple"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Drain Finishing Mode">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_drainmode"
|
||||
editMode={editMode}
|
||||
options={drainmode_options}
|
||||
entry={drainmode}
|
||||
tooltip="Event trigger once prey is fully drained of nutrition."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Shrink/Grow Size">
|
||||
<VorePanelEditNumber
|
||||
tooltip="Choose the size that prey will be grown/shrunk to, ranging from 25% to 200%"
|
||||
action="set_attribute"
|
||||
subAction="b_grow_shrink"
|
||||
editMode={editMode}
|
||||
value={shrink_grow_size * 100}
|
||||
minValue={25}
|
||||
maxValue={200}
|
||||
unit="%"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Egg Type">
|
||||
<VorePanelEditDropdown
|
||||
tooltip="Select the displayed egg type when you encase prey in one."
|
||||
action="set_attribute"
|
||||
subAction="b_egg_type"
|
||||
editMode={editMode}
|
||||
options={egg_types}
|
||||
entry={egg_type}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Egg Name">
|
||||
<VorePanelEditText
|
||||
action="set_attribute"
|
||||
subAction="b_egg_name"
|
||||
editMode={editMode}
|
||||
limit={0}
|
||||
entry={editMode ? egg_name : egg_name ? egg_name : 'Default'}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Egg Size">
|
||||
{!egg_size && !editMode ? (
|
||||
'Automatic'
|
||||
) : (
|
||||
<VorePanelEditNumber
|
||||
tooltip="Custom Egg Size 25% to 200% (0 for automatic item depending egg size from 25% to 200%)"
|
||||
action="set_attribute"
|
||||
subAction="b_egg_size"
|
||||
editMode={editMode}
|
||||
value={egg_size * 100}
|
||||
minValue={0}
|
||||
maxValue={200}
|
||||
unit="%"
|
||||
/>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Recycling">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_recycling"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to recycle items into small amounts of resources during digestion."
|
||||
active={!!recycling}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Storing Nutrition">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_storing_nutrition"
|
||||
editMode={editMode}
|
||||
content={storing_nutrition ? 'Storing' : 'Absorbing'}
|
||||
active={!!storing_nutrition}
|
||||
tooltip={
|
||||
'Toggle nutirion ' +
|
||||
(storing_nutrition ? 'storing' : 'absorbing') +
|
||||
'. Currently nutrition will be ' +
|
||||
(storing_nutrition ? 'stored as items' : 'absorbed') +
|
||||
'.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Selective Mode Preference">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_selective_mode_pref_toggle"
|
||||
editMode={editMode}
|
||||
options={selectiveBellyOptions}
|
||||
entry={selective_preference}
|
||||
color={digestModeToColor[selective_preference]}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
);
|
||||
};
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, Section, Stack } from 'tgui-core/components';
|
||||
import { type BooleanLike, classes } from 'tgui-core/react';
|
||||
|
||||
export const BellyFullscreenSelection = (props: {
|
||||
editMode: boolean;
|
||||
belly_fullscreen: string;
|
||||
colorization_enabled: BooleanLike;
|
||||
possible_fullscreens: string[];
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
editMode,
|
||||
belly_fullscreen,
|
||||
colorization_enabled,
|
||||
possible_fullscreens,
|
||||
} = props;
|
||||
|
||||
return editMode ? (
|
||||
<Section title="Belly Fullscreens Styles">
|
||||
<Stack wrap="wrap" justify="center">
|
||||
<Stack.Item basis="100%">
|
||||
<Button
|
||||
fluid
|
||||
selected={belly_fullscreen === '' || belly_fullscreen === null}
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_fullscreen', val: null })
|
||||
}
|
||||
>
|
||||
Disabled
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
{Object.keys(possible_fullscreens).map((key, index) => (
|
||||
<Stack.Item key={index} basis="32%">
|
||||
<Button
|
||||
width="256px"
|
||||
height="256px"
|
||||
selected={key === belly_fullscreen}
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_fullscreen', val: key })
|
||||
}
|
||||
>
|
||||
<Box
|
||||
className={classes([
|
||||
colorization_enabled ? 'vore240x240' : 'fixedvore240x240',
|
||||
key,
|
||||
])}
|
||||
style={{
|
||||
transform: 'translate(0%, 4%)',
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Section>
|
||||
) : (
|
||||
<Section fill title="Belly Fullscreen">
|
||||
<Stack align="center">
|
||||
<Stack.Item grow />
|
||||
<Stack.Item>
|
||||
{belly_fullscreen ? (
|
||||
<Box
|
||||
className={classes([
|
||||
colorization_enabled ? 'vore240x240' : 'fixedvore240x240',
|
||||
belly_fullscreen,
|
||||
])}
|
||||
/>
|
||||
) : (
|
||||
<Box>No overlay selected.</Box>
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item grow />
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
import { Divider, LabeledList, Section } from 'tgui-core/components';
|
||||
import { type BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { vorespawnAbsorbedColor, vorespawnAbsorbedText } from '../../constants';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditTextArea } from '../../VorePanelElements/VorePanelTextArea';
|
||||
|
||||
export const VoreSelectedWhitelist = (props: {
|
||||
editMode: boolean;
|
||||
vorespawnBlacklist: BooleanLike;
|
||||
vorespawnWhitelist: string[];
|
||||
vorespawnAbsorbed: number;
|
||||
}) => {
|
||||
const {
|
||||
editMode,
|
||||
vorespawnBlacklist,
|
||||
vorespawnWhitelist,
|
||||
vorespawnAbsorbed,
|
||||
} = props;
|
||||
|
||||
const ourEntry = editMode
|
||||
? (vorespawnWhitelist.length && vorespawnWhitelist.join(', ')) || ''
|
||||
: vorespawnWhitelist.length
|
||||
? vorespawnWhitelist.join(', ')
|
||||
: 'Anyone!';
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Vore Spawn"
|
||||
buttons={
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_vorespawn_blacklist"
|
||||
editMode={editMode}
|
||||
active={!vorespawnBlacklist}
|
||||
content={vorespawnBlacklist ? 'Hide' : 'Show'}
|
||||
tooltip={
|
||||
(vorespawnBlacklist ? 'Hide' : 'Show') +
|
||||
" this belly from potential prey's spawn selection list."
|
||||
}
|
||||
/>
|
||||
}
|
||||
width={'80%'}
|
||||
>
|
||||
{!vorespawnBlacklist && (
|
||||
<>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Vore Spawn Absorbed">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_vorespawn_absorbed"
|
||||
editMode={editMode}
|
||||
color={vorespawnAbsorbedColor[vorespawnAbsorbed]}
|
||||
options={vorespawnAbsorbedText}
|
||||
entry={vorespawnAbsorbedText[vorespawnAbsorbed]}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<Divider />
|
||||
<VorePanelEditTextArea
|
||||
disableLegacyInput
|
||||
tooltip="Input vore spawn allowed ckeys. Empty means anyone can spawn."
|
||||
editMode={editMode}
|
||||
limit={4096}
|
||||
entry={ourEntry}
|
||||
action="set_attribute"
|
||||
subAction="b_vorespawn_whitelist"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+18
-17
@@ -1,20 +1,20 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section } from 'tgui-core/components';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
import { Box, LabeledList, Section } from 'tgui-core/components';
|
||||
|
||||
import type { hostMob, selectedData } from '../types';
|
||||
import { robotBellyOptions } from '../../constants';
|
||||
import type { hostMob, siliconeBellyControls } from '../../types';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
|
||||
export const VoreSelectedMobTypeBellyButtons = (props: {
|
||||
belly: selectedData;
|
||||
editMode: boolean;
|
||||
bellyControl: siliconeBellyControls;
|
||||
host_mobtype: hostMob;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { belly, host_mobtype } = props;
|
||||
const { editMode, bellyControl, host_mobtype } = props;
|
||||
const {
|
||||
silicon_belly_overlay_preference,
|
||||
belly_sprite_option_shown,
|
||||
belly_sprite_to_affect,
|
||||
} = belly;
|
||||
} = bellyControl;
|
||||
|
||||
const { is_cyborg, is_vore_simple_mob } = host_mobtype;
|
||||
|
||||
@@ -24,13 +24,14 @@ export const VoreSelectedMobTypeBellyButtons = (props: {
|
||||
<Section title={'Cyborg Controls'} width={'80%'}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Toggle Belly Overlay Mode">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_silicon_belly' })
|
||||
}
|
||||
>
|
||||
{capitalize(silicon_belly_overlay_preference)}
|
||||
</Button>
|
||||
<VorePanelEditDropdown
|
||||
tooltip="Choose whether you'd like your belly overlay to show from sleepers, normal vore bellies, or an average of the two. NOTE: This ONLY applies to silicons, not human mobs!"
|
||||
action="set_attribute"
|
||||
subAction="b_silicon_belly"
|
||||
editMode={editMode}
|
||||
options={robotBellyOptions}
|
||||
entry={silicon_belly_overlay_preference}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
@@ -38,11 +39,11 @@ export const VoreSelectedMobTypeBellyButtons = (props: {
|
||||
} else {
|
||||
return (
|
||||
<Section title={'Cyborg Controls'} width={'80%'}>
|
||||
<span style={{ color: 'red' }}>
|
||||
<Box color="red">
|
||||
Your module does either not support vore sprites or you've
|
||||
selected a belly sprite other than the sleeper within the Visuals
|
||||
section.
|
||||
</span>
|
||||
</Box>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
import { Box, LabeledList, Stack } from 'tgui-core/components';
|
||||
|
||||
import { spriteToTooltip } from '../../constants';
|
||||
import type { bellyVisualData } from '../../types';
|
||||
import { VorePanelEditCheckboxes } from '../../VorePanelElements/VorePanelEditCheckboxes';
|
||||
import { VorePanelEditColor } from '../../VorePanelElements/VorePanelEditColor';
|
||||
import { VorePanelEditDropdown } from '../../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../../VorePanelElements/VorePanelEditSwitch';
|
||||
|
||||
export const VoreSpriteAffects = (props: {
|
||||
editMode: boolean;
|
||||
bellyVisualData: bellyVisualData;
|
||||
}) => {
|
||||
const { editMode, bellyVisualData } = props;
|
||||
const {
|
||||
vore_sprite_flags,
|
||||
absorbed_voresprite,
|
||||
absorbed_multiplier,
|
||||
liquid_voresprite,
|
||||
liquid_multiplier,
|
||||
item_voresprite,
|
||||
item_multiplier,
|
||||
health_voresprite,
|
||||
resist_animation,
|
||||
voresprite_size_factor,
|
||||
belly_sprite_to_affect,
|
||||
belly_sprite_options,
|
||||
undergarment_chosen,
|
||||
undergarment_if_none,
|
||||
undergarment_options,
|
||||
undergarment_options_if_none,
|
||||
undergarment_color,
|
||||
tail_option_shown,
|
||||
tail_to_change_to,
|
||||
tail_sprite_options,
|
||||
} = bellyVisualData;
|
||||
|
||||
return (
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Vore Sprite Mode">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={vore_sprite_flags}
|
||||
action="set_attribute"
|
||||
subAction="b_vore_sprite_flags"
|
||||
tooltipList={spriteToTooltip}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Count Absorbed prey for vore sprites">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_count_absorbed_prey_for_sprites"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to toggle if absorbed prey accounts for the vore sprite size."
|
||||
content={absorbed_voresprite ? 'Yes' : 'No'}
|
||||
active={!!absorbed_voresprite}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Count liquid reagents for vore sprites">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_count_liquid_for_sprites"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to toggle if belly liquids account for the vore sprite size."
|
||||
content={liquid_voresprite ? 'Yes' : 'No'}
|
||||
active={!!liquid_voresprite}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Count items for vore sprites">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_count_items_for_sprites"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to toggle if ingested items account for the vore sprite size."
|
||||
content={item_voresprite ? 'Yes' : 'No'}
|
||||
active={!!item_voresprite}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Prey health affects vore sprites">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_health_impacts_size"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to toggle if your prey's health is accounted for the vore sprite size. The lower the health, the less a prey will contribute."
|
||||
content={health_voresprite ? 'Yes' : 'No'}
|
||||
active={!!health_voresprite}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
{belly_sprite_options?.length ? (
|
||||
<LabeledList.Item label="Belly Sprite to affect">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_belly_sprite_to_affect"
|
||||
editMode={editMode}
|
||||
options={belly_sprite_options}
|
||||
entry={belly_sprite_to_affect}
|
||||
tooltip="Set the belly sprite to effect."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
) : (
|
||||
<LabeledList.Item label="Belly Sprite to affect">
|
||||
<Box textColor="red">You do not have any bellysprites.</Box>
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{!!tail_option_shown &&
|
||||
vore_sprite_flags
|
||||
.map((flag) => flag.label)
|
||||
.includes('Undergarment addition') && (
|
||||
<>
|
||||
<LabeledList.Item label="Undergarment type to affect">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_undergarment_choice"
|
||||
editMode={editMode}
|
||||
options={undergarment_options}
|
||||
entry={undergarment_chosen}
|
||||
tooltip="Set the undergarment sprite to effect."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Undergarment if none equipped">
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_undergarment_if_none"
|
||||
editMode={editMode}
|
||||
options={undergarment_options_if_none}
|
||||
entry={undergarment_if_none}
|
||||
tooltip="If no undergarment is equipped, which undergarment style do you want to use?"
|
||||
/>
|
||||
</Stack.Item>
|
||||
<VorePanelEditColor
|
||||
editMode={editMode}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_undergarment_color"
|
||||
value_of={null}
|
||||
back_color={undergarment_color}
|
||||
tooltip="Select your undergarment color."
|
||||
/>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</>
|
||||
)}
|
||||
{!!tail_option_shown &&
|
||||
vore_sprite_flags
|
||||
.map((flag) => flag.label)
|
||||
.includes('Tail adjustment') && (
|
||||
<LabeledList.Item label="Tail to change to">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_tail_to_change_to"
|
||||
editMode={editMode}
|
||||
options={tail_sprite_options}
|
||||
entry={
|
||||
typeof tail_to_change_to === 'string'
|
||||
? tail_to_change_to
|
||||
: 'None'
|
||||
}
|
||||
tooltip="Set the tail sprite to effect."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Absorbed Multiplier">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_absorbed_multiplier"
|
||||
editMode={editMode}
|
||||
value={absorbed_multiplier}
|
||||
minValue={0.1}
|
||||
maxValue={3}
|
||||
step={0.1}
|
||||
unit="x"
|
||||
digits={1}
|
||||
tooltip="Set the impact absorbed prey's size have on your vore sprite. 1 means no scaling, 0.5 means absorbed prey count half as much, 2 means absorbed prey count double. (Range from 0.1 - 3)"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Multiplier">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_liquid_multiplier"
|
||||
editMode={editMode}
|
||||
value={liquid_multiplier}
|
||||
minValue={0.1}
|
||||
maxValue={10}
|
||||
step={0.1}
|
||||
unit="x"
|
||||
digits={1}
|
||||
tooltip="Set the impact amount of liquid reagents will have on your vore sprite. 1 means a belly with 100 reagents of fluid will count as 1 normal sized prey-thing's worth, 0.5 means liquid counts half as much, 2 means liquid counts double. (Range from 0.1 - 10)"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Items Multiplier">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_item_multiplier"
|
||||
editMode={editMode}
|
||||
value={item_multiplier}
|
||||
minValue={0.1}
|
||||
maxValue={10}
|
||||
step={0.1}
|
||||
unit="x"
|
||||
digits={1}
|
||||
tooltip="Set the impact items will have on your vore sprite. 1 means a belly with 8 normal-sized items will count as 1 normal sized prey-thing's worth, 0.5 means items count half as much, 2 means items count double. (Range from 0.1 - 10)"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Vore Sprite Size Factor">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_size_factor_sprites"
|
||||
editMode={editMode}
|
||||
value={voresprite_size_factor}
|
||||
minValue={0.1}
|
||||
maxValue={3}
|
||||
step={0.1}
|
||||
unit="x"
|
||||
digits={1}
|
||||
tooltip="Set the impact all belly content's collective size has on your vore sprite. 1 means no scaling, 0.5 means content counts half as much, 2 means contents count double. (Range from 0.1 - 3)"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Animation when prey resist">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_resist_animation"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to toggle if prey resists trigger struggle animations if the sprite supports it."
|
||||
active={!!resist_animation}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,158 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
Image,
|
||||
LabeledList,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import { stats } from '../constants';
|
||||
import type { contentData, DropdownEntry } from '../types';
|
||||
|
||||
export const VoreContentsPanel = (props: {
|
||||
contents?: contentData[] | null;
|
||||
targetBelly?: string;
|
||||
onTargetBely?: React.Dispatch<React.SetStateAction<string>>;
|
||||
bellyDropdownNames?: DropdownEntry[];
|
||||
belly?: string;
|
||||
outside?: BooleanLike;
|
||||
show_pictures: BooleanLike;
|
||||
icon_overflow: BooleanLike;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
contents = [],
|
||||
targetBelly = '',
|
||||
onTargetBely,
|
||||
bellyDropdownNames,
|
||||
belly,
|
||||
outside = false,
|
||||
show_pictures,
|
||||
icon_overflow,
|
||||
} = props;
|
||||
|
||||
function bellyValueToName(value: string) {
|
||||
const bellyName = bellyDropdownNames
|
||||
?.map((entry) => {
|
||||
if (entry.value === value) {
|
||||
return entry.displayText;
|
||||
}
|
||||
})
|
||||
.filter((value) => value !== undefined);
|
||||
if (Array.isArray(bellyName) && bellyName.length) {
|
||||
return bellyName[0];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{!!outside && (
|
||||
<Stack>
|
||||
<Stack.Item grow>
|
||||
<Button.Confirm
|
||||
textAlign="center"
|
||||
confirmContent="Confirm Eject All?"
|
||||
fluid
|
||||
mb={1}
|
||||
onClick={() =>
|
||||
act('pick_from_outside', { pickall: true, intent: 'eject_all' })
|
||||
}
|
||||
>
|
||||
Eject All
|
||||
</Button.Confirm>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Button.Confirm
|
||||
textAlign="center"
|
||||
confirmContent="Confirm Move All?"
|
||||
fluid
|
||||
mb={1}
|
||||
onClick={() =>
|
||||
act('pick_from_outside', {
|
||||
pickall: true,
|
||||
intent: 'move_all',
|
||||
val: targetBelly,
|
||||
})
|
||||
}
|
||||
>
|
||||
Move All
|
||||
</Button.Confirm>
|
||||
</Stack.Item>
|
||||
{!!bellyDropdownNames && !!onTargetBely && (
|
||||
<Stack.Item>
|
||||
<Dropdown
|
||||
onSelected={(value) => onTargetBely(value)}
|
||||
options={bellyDropdownNames!}
|
||||
selected={bellyValueToName(targetBelly)}
|
||||
/>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
{(show_pictures && !icon_overflow && (
|
||||
<Stack wrap="wrap" justify="center" align="center">
|
||||
{contents?.map((thing) => (
|
||||
<Stack.Item key={thing.ref} basis="32%">
|
||||
<Button
|
||||
width="64px"
|
||||
color={thing.absorbed ? 'purple' : stats[thing.stat]}
|
||||
style={{
|
||||
verticalAlign: 'middle',
|
||||
marginRight: '5px',
|
||||
borderRadius: '20px',
|
||||
}}
|
||||
onClick={() =>
|
||||
act(
|
||||
thing.outside ? 'pick_from_outside' : 'pick_from_inside',
|
||||
{
|
||||
pick: thing.ref,
|
||||
belly: belly,
|
||||
},
|
||||
)
|
||||
}
|
||||
>
|
||||
<Image
|
||||
src={'data:image/jpeg;base64, ' + thing.icon}
|
||||
width="64px"
|
||||
height="64px"
|
||||
style={{
|
||||
marginLeft: '-5px',
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
{thing.name}
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
)) || (
|
||||
<LabeledList>
|
||||
{contents?.map((thing) => (
|
||||
<LabeledList.Item key={thing.ref} label={thing.name}>
|
||||
<Button
|
||||
fluid
|
||||
mt={-1}
|
||||
mb={-1}
|
||||
color={thing.absorbed ? 'purple' : stats[thing.stat]}
|
||||
onClick={() =>
|
||||
act(
|
||||
thing.outside ? 'pick_from_outside' : 'pick_from_inside',
|
||||
{
|
||||
pick: thing.ref,
|
||||
belly: belly,
|
||||
},
|
||||
)
|
||||
}
|
||||
>
|
||||
Interact
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
+112
-58
@@ -1,79 +1,133 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
|
||||
import { digestModeToColor } from '../constants';
|
||||
import type { selectedData } from '../types';
|
||||
import { digestModeToColor, modeToTooltip } from '../constants';
|
||||
import type { bellyModeData, DropdownEntry } from '../types';
|
||||
import { VorePanelEditCheckboxes } from '../VorePanelElements/VorePanelEditCheckboxes';
|
||||
import { VorePanelEditDropdown } from '../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditText } from '../VorePanelElements/VorePanelEditText';
|
||||
|
||||
export const VoreSelectedBellyControls = (props: { belly: selectedData }) => {
|
||||
export const VoreSelectedBellyControls = (props: {
|
||||
bellyDropdownNames: DropdownEntry[];
|
||||
editMode: boolean;
|
||||
belly_name: string;
|
||||
bellyModeData: bellyModeData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { belly } = props;
|
||||
const { belly_name, mode, item_mode, addons } = belly;
|
||||
const { bellyDropdownNames, belly_name, bellyModeData, editMode } = props;
|
||||
const {
|
||||
mode,
|
||||
item_mode,
|
||||
addons,
|
||||
name_length,
|
||||
name_min,
|
||||
mode_options,
|
||||
item_mode_options,
|
||||
} = bellyModeData;
|
||||
|
||||
const bellyNames = bellyDropdownNames.map((belly) => {
|
||||
return belly.displayText;
|
||||
});
|
||||
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item
|
||||
label="Name"
|
||||
buttons={
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="arrow-up"
|
||||
tooltipPosition="left"
|
||||
tooltip="Move this belly tab up."
|
||||
onClick={() => act('move_belly', { dir: -1 })}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="arrow-down"
|
||||
tooltipPosition="left"
|
||||
tooltip="Move this belly tab down."
|
||||
onClick={() => act('move_belly', { dir: 1 })}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
<Button onClick={() => act('set_attribute', { attribute: 'b_name' })}>
|
||||
{belly_name}
|
||||
</Button>
|
||||
{editMode && (
|
||||
<LabeledList.Item
|
||||
buttons={
|
||||
<Stack>
|
||||
{bellyNames.indexOf(belly_name) !== 0 && (
|
||||
<Stack.Item
|
||||
mr={
|
||||
bellyNames.indexOf(belly_name) === bellyNames.length - 1
|
||||
? '28px'
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Button
|
||||
icon="arrow-up"
|
||||
tooltipPosition="left"
|
||||
tooltip="Move this belly tab up."
|
||||
onClick={() => act('move_belly', { dir: -1 })}
|
||||
/>
|
||||
</Stack.Item>
|
||||
)}
|
||||
{bellyNames.indexOf(belly_name) !== bellyNames.length - 1 && (
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="arrow-down"
|
||||
tooltipPosition="left"
|
||||
tooltip="Move this belly tab down."
|
||||
onClick={() => act('move_belly', { dir: 1 })}
|
||||
/>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<LabeledList.Item label="Name">
|
||||
<VorePanelEditText
|
||||
editMode={editMode}
|
||||
limit={name_length}
|
||||
min={name_min}
|
||||
entry={belly_name}
|
||||
action={'set_attribute'}
|
||||
subAction={'b_name'}
|
||||
tooltip={
|
||||
'Adjust the name of your belly. [' +
|
||||
name_min +
|
||||
'-' +
|
||||
name_length +
|
||||
' characters].'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mode">
|
||||
<Button
|
||||
<VorePanelEditDropdown
|
||||
editMode={editMode}
|
||||
options={mode_options}
|
||||
entry={mode}
|
||||
action={'set_attribute'}
|
||||
subAction={'b_mode'}
|
||||
color={digestModeToColor[mode]}
|
||||
onClick={() => act('set_attribute', { attribute: 'b_mode' })}
|
||||
>
|
||||
{mode}
|
||||
</Button>
|
||||
tooltip="The digest mode which will be applied for prey."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mode Addons">
|
||||
{(addons.length && addons.join(', ')) || 'None'}
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_addons' })}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={addons}
|
||||
action={'set_attribute'}
|
||||
subAction={'b_addons'}
|
||||
tooltipList={modeToTooltip}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Item Mode">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_item_mode' })}
|
||||
>
|
||||
{item_mode}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item>
|
||||
<Button.Confirm
|
||||
fluid
|
||||
icon="exclamation-triangle"
|
||||
confirmIcon="trash"
|
||||
color="red"
|
||||
confirmContent="This is irreversable!"
|
||||
onClick={() => act('set_attribute', { attribute: 'b_del' })}
|
||||
>
|
||||
Delete Belly
|
||||
</Button.Confirm>
|
||||
<VorePanelEditDropdown
|
||||
editMode={editMode}
|
||||
options={item_mode_options}
|
||||
entry={item_mode}
|
||||
action={'set_attribute'}
|
||||
subAction={'b_item_mode'}
|
||||
color={digestModeToColor[item_mode]}
|
||||
tooltip="The digest mode which will be applied for items."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
{editMode && (
|
||||
<LabeledList.Item>
|
||||
<Button.Confirm
|
||||
fluid
|
||||
icon="exclamation-triangle"
|
||||
confirmIcon="trash"
|
||||
color="red"
|
||||
confirmContent="This is irreversable!"
|
||||
onClick={() => act('set_attribute', { attribute: 'b_del' })}
|
||||
>
|
||||
Delete Belly
|
||||
</Button.Confirm>
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
</LabeledList>
|
||||
);
|
||||
};
|
||||
|
||||
+134
-214
@@ -1,7 +1,5 @@
|
||||
import { type ReactNode, useEffect, useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dimmer,
|
||||
LabeledList,
|
||||
@@ -9,73 +7,35 @@ import {
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
|
||||
import { SYNTAX_COLOR, SYNTAX_REGEX } from '../constants';
|
||||
import type { selectedData } from '../types';
|
||||
import { VoreSelectedBellyDescriptionsBellymode } from '../VoreSelectedBellyDescriptionTexts/VoreSelectedBellyDescriptionsBellymode';
|
||||
import { VoreSelectedBellyDescriptionsEscape } from '../VoreSelectedBellyDescriptionTexts/VoreSelectedBellyDescriptionsEscape';
|
||||
import { VoreSelectedBellyDescriptionsIdle } from '../VoreSelectedBellyDescriptionTexts/VoreSelectedBellyDescriptionsIdle';
|
||||
import { VoreSelectedBellyDescriptionsInteractionChance } from '../VoreSelectedBellyDescriptionTexts/VoreSelectedBellyDescriptionsInteractionChance';
|
||||
import { VoreSelectedBellyDescriptionsStruggle } from '../VoreSelectedBellyDescriptionTexts/VoreSelectedBellyDescriptionsStruggle';
|
||||
import { VoreSelectedBellyDescriptionsTransfer } from '../VoreSelectedBellyDescriptionTexts/VoreSelectedBellyDescriptionsTransfer';
|
||||
|
||||
const DescriptionSyntaxHighlighting = (props: { desc: string }) => {
|
||||
const { desc } = props;
|
||||
const [htmlDesc, setHtmlDesc] = useState<ReactNode[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!desc || desc.length === 0) {
|
||||
setHtmlDesc([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const elements: ReactNode[] = [];
|
||||
|
||||
const regexCopy = new RegExp(SYNTAX_REGEX);
|
||||
|
||||
let lastIndex = 0;
|
||||
let result;
|
||||
while ((result = regexCopy.exec(desc)) !== null) {
|
||||
elements.push(<>{desc.substring(lastIndex, result.index)}</>);
|
||||
elements.push(
|
||||
<Box inline color={SYNTAX_COLOR[result[0]] || 'purple'}>
|
||||
{result[0]}
|
||||
</Box>,
|
||||
);
|
||||
lastIndex = result.index + result[0].length;
|
||||
}
|
||||
|
||||
elements.push(<>{desc.substring(lastIndex)}</>);
|
||||
|
||||
setHtmlDesc(elements);
|
||||
}, [desc]);
|
||||
|
||||
return <Box preserveWhitespace>{htmlDesc}</Box>;
|
||||
};
|
||||
import type { bellyDescriptionData } from '../types';
|
||||
import { VorePanelEditNumber } from '../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
import { VorePanelEditText } from '../VorePanelElements/VorePanelEditText';
|
||||
import { VoreSelectedBellyDescriptionMatrix } from './DescriptionTab/VoreSelectedBellyDescriptionMatrix';
|
||||
|
||||
export const VoreSelectedBellyDescriptions = (props: {
|
||||
belly: selectedData;
|
||||
editMode: boolean;
|
||||
bellyDescriptionData: bellyDescriptionData;
|
||||
vore_words: Record<string, string[]>;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const [showFormatHelp, setShowFormatHelp] = useState(false);
|
||||
|
||||
const { belly, vore_words } = props;
|
||||
const { editMode, bellyDescriptionData, vore_words } = props;
|
||||
const {
|
||||
verb,
|
||||
release_verb,
|
||||
desc,
|
||||
absorbed_desc,
|
||||
mode,
|
||||
message_mode,
|
||||
escapable,
|
||||
interacts,
|
||||
autotransfer_enabled,
|
||||
autotransfer,
|
||||
emote_active,
|
||||
} = belly;
|
||||
emote_time,
|
||||
show_liq_fullness,
|
||||
entrance_logs,
|
||||
item_digest_logs,
|
||||
name_length,
|
||||
name_min,
|
||||
} = bellyDescriptionData;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<>
|
||||
{showFormatHelp && (
|
||||
<Dimmer>
|
||||
<Section
|
||||
@@ -131,169 +91,129 @@ export const VoreSelectedBellyDescriptions = (props: {
|
||||
</Section>
|
||||
</Dimmer>
|
||||
)}
|
||||
<Stack>
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
<Box color="label" mt={1} mb={1}>
|
||||
Description:
|
||||
</Box>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Vore Verb">
|
||||
<VorePanelEditText
|
||||
editMode={editMode}
|
||||
limit={name_length}
|
||||
min={name_min}
|
||||
entry={verb}
|
||||
action={'set_attribute'}
|
||||
subAction={'b_verb'}
|
||||
tooltip={
|
||||
'Adjust vore verb. [' +
|
||||
name_min +
|
||||
'-' +
|
||||
name_length +
|
||||
' characters].'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Release Verb">
|
||||
<VorePanelEditText
|
||||
editMode={editMode}
|
||||
limit={name_length}
|
||||
min={name_min}
|
||||
entry={release_verb}
|
||||
action={'set_attribute'}
|
||||
subAction={'b_release_verb'}
|
||||
tooltip={
|
||||
'Adjust release verb. [' +
|
||||
name_min +
|
||||
'-' +
|
||||
name_length +
|
||||
' characters].'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Divider />
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="pencil"
|
||||
onClick={() => act('set_attribute', { attribute: 'b_desc' })}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Stack fill>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Idle Emotes">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_emoteactive"
|
||||
editMode={editMode}
|
||||
active={!!emote_active}
|
||||
content={emote_active ? 'Active' : 'Inactive'}
|
||||
tooltip={
|
||||
(emote_active ? 'Dis' : 'En') + 'ables idle emotes.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Idle Emote Delay">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_emotetime"
|
||||
editMode={editMode}
|
||||
value={emote_time}
|
||||
unit="seconds"
|
||||
tooltip="Choose the period it takes for idle belly emotes to be shown to prey."
|
||||
maxValue={600}
|
||||
minValue={60}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Fullness Examines">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_show_liq_fullness"
|
||||
editMode={editMode}
|
||||
active={!!show_liq_fullness}
|
||||
content={show_liq_fullness ? 'Active' : 'Inactive'}
|
||||
tooltip={
|
||||
(show_liq_fullness ? 'Dis' : 'En') +
|
||||
'ables liquid fullness examine messages.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Entrance Logs">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_entrance_logs"
|
||||
editMode={editMode}
|
||||
active={!!entrance_logs}
|
||||
tooltip={
|
||||
(entrance_logs ? 'Dis' : 'En') +
|
||||
'ables auto transfer messages and spawn messages being shown to yourself.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Item Digestion Logs">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_item_digest_logs"
|
||||
editMode={editMode}
|
||||
active={!!item_digest_logs}
|
||||
tooltip={
|
||||
(item_digest_logs ? 'Dis' : 'En') +
|
||||
'ables item digest messages being shown to yourself.'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
icon="question"
|
||||
tooltip="Formatting help"
|
||||
onClick={() => setShowFormatHelp(!showFormatHelp)}
|
||||
selected={showFormatHelp}
|
||||
<Stack.Item grow>
|
||||
<VoreSelectedBellyDescriptionMatrix
|
||||
showAll={message_mode}
|
||||
editMode={editMode}
|
||||
bellyDescriptionData={bellyDescriptionData}
|
||||
showFormatHelp={showFormatHelp}
|
||||
onShowFormatHelp={setShowFormatHelp}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
<DescriptionSyntaxHighlighting desc={desc} />
|
||||
<Box color="label" mt={2} mb={1}>
|
||||
Description (Absorbed):{' '}
|
||||
<Button
|
||||
icon="pencil"
|
||||
onClick={() => act('set_attribute', { attribute: 'b_absorbed_desc' })}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
</Box>
|
||||
<DescriptionSyntaxHighlighting desc={absorbed_desc} />
|
||||
<Box mb={2} />
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Vore Verb">
|
||||
<Button onClick={() => act('set_attribute', { attribute: 'b_verb' })}>
|
||||
{verb}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Release Verb">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_release_verb' })
|
||||
}
|
||||
>
|
||||
{release_verb}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Show All Messages">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_message_mode',
|
||||
})
|
||||
}
|
||||
icon={message_mode ? 'toggle-on' : 'toggle-off'}
|
||||
selected={message_mode}
|
||||
>
|
||||
{message_mode ? 'True' : 'False'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Examine Messages">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'em' })
|
||||
}
|
||||
>
|
||||
Examine Message (when full)
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'ema' })
|
||||
}
|
||||
>
|
||||
Examine Message (with absorbed victims)
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Trash Eater Messages">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_trasheater', msgtype: 'in' })
|
||||
}
|
||||
>
|
||||
Item Eat Message
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_trasheater',
|
||||
msgtype: 'out',
|
||||
})
|
||||
}
|
||||
>
|
||||
Item Expel Message
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
{message_mode || escapable ? (
|
||||
<>
|
||||
<VoreSelectedBellyDescriptionsStruggle />
|
||||
<VoreSelectedBellyDescriptionsEscape
|
||||
message_mode={message_mode}
|
||||
interacts={interacts}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{message_mode ||
|
||||
(escapable &&
|
||||
(!!interacts.transferlocation ||
|
||||
!!interacts.transferlocation_secondary)) ||
|
||||
(autotransfer_enabled &&
|
||||
(!!autotransfer.autotransferlocation ||
|
||||
!!autotransfer.autotransferlocation_secondary)) ? (
|
||||
<VoreSelectedBellyDescriptionsTransfer
|
||||
message_mode={message_mode}
|
||||
interacts={interacts}
|
||||
autotransfer={autotransfer}
|
||||
/>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{message_mode ||
|
||||
(escapable &&
|
||||
(interacts.digestchance > 0 || interacts.absorbchance > 0)) ? (
|
||||
<VoreSelectedBellyDescriptionsInteractionChance
|
||||
message_mode={message_mode}
|
||||
interacts={interacts}
|
||||
/>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{(message_mode ||
|
||||
mode === 'Digest' ||
|
||||
mode === 'Selective' ||
|
||||
mode === 'Absorb' ||
|
||||
mode === 'Unabsorb') && (
|
||||
<VoreSelectedBellyDescriptionsBellymode
|
||||
message_mode={message_mode}
|
||||
mode={mode}
|
||||
/>
|
||||
)}
|
||||
{emote_active ? (
|
||||
<VoreSelectedBellyDescriptionsIdle
|
||||
message_mode={message_mode}
|
||||
mode={mode}
|
||||
/>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<LabeledList.Item label="Reset Messages">
|
||||
<Button
|
||||
color="red"
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'reset' })
|
||||
}
|
||||
>
|
||||
Reset Messages
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
+266
-370
@@ -1,381 +1,277 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section } from 'tgui-core/components';
|
||||
import { LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
|
||||
import type { selectedData } from '../types';
|
||||
import { noSelectionName } from '../constants';
|
||||
import type { bellyInteractionData, DropdownEntry } from '../types';
|
||||
import { VorePanelEditDropdown } from '../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
import { AutoTransferOptions } from './InteractionTab/AutoTransferOptions';
|
||||
|
||||
export const VoreSelectedBellyInteractions = (props: {
|
||||
belly: selectedData;
|
||||
editMode: boolean;
|
||||
bellyDropdownNames: DropdownEntry[];
|
||||
bellyInteractData: bellyInteractionData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { editMode, bellyDropdownNames, bellyInteractData } = props;
|
||||
const { escapable, interacts, autotransfer_enabled, autotransfer } =
|
||||
bellyInteractData;
|
||||
|
||||
const { belly } = props;
|
||||
const { escapable, interacts, autotransfer_enabled, autotransfer } = belly;
|
||||
const escapeTimeSeconds = interacts.escapetime / 10;
|
||||
const autoTransferTimeSeconds = autotransfer.autotransferwait / 10;
|
||||
|
||||
const locationNames = [...bellyDropdownNames, noSelectionName];
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Belly Interactions"
|
||||
buttons={
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_escapable' })}
|
||||
icon={escapable ? 'toggle-on' : 'toggle-off'}
|
||||
selected={escapable}
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
<Section
|
||||
title="Belly Interactions"
|
||||
buttons={
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_escapable"
|
||||
editMode={editMode}
|
||||
active={!!escapable}
|
||||
tooltip={
|
||||
"These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, and you can change them to whatever you see fit. " +
|
||||
"Setting them to 0% will disable the possibility of that interaction. These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest/absorb) " +
|
||||
"will affect all prey in that belly, if one resists and triggers digestion/absorption. If multiple trigger at the same time, only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur."
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{escapable ? 'Interactions On' : 'Interactions Off'}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{escapable ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Escape Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_escapechance' })
|
||||
<Stack fill>
|
||||
{!!escapable && (
|
||||
<>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList.Item label="Escape Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_escapechance"
|
||||
editMode={editMode}
|
||||
value={interacts.escapechance}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set prey escape chance on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Escape Time">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_escapetime"
|
||||
editMode={editMode}
|
||||
value={escapeTimeSeconds}
|
||||
minValue={1}
|
||||
maxValue={60}
|
||||
unit={escapeTimeSeconds === 1 ? 'second' : 'seconds'}
|
||||
tooltip="Set number of seconds for prey to escape on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_digestchance"
|
||||
editMode={editMode}
|
||||
value={interacts.escapechance}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set belly digest mode chance on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Primary Transfer Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_transferchance"
|
||||
editMode={editMode}
|
||||
value={interacts.transferchance}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set the primary belly transfer chance on resist. You must also set the location for this to have any effect."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Secondary Transfer Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_transferchance_secondary"
|
||||
editMode={editMode}
|
||||
value={interacts.transferchance_secondary}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set the secondary belly transfer chance on resist. You must also set the secondary location for this to have any effect."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList.Item label="Absorbed Escape Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_escapechance_absorbed"
|
||||
editMode={editMode}
|
||||
value={interacts.escapechance_absorbed}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set absorbed prey escape chance on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Belch Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_belchchance"
|
||||
editMode={editMode}
|
||||
value={interacts.belchchance}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set chance for belch emote on prey resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Absorb Chance">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_absorbchance"
|
||||
editMode={editMode}
|
||||
value={interacts.absorbchance}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Set belly absorb mode chance on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Primary Transfer Location">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_transferlocation"
|
||||
editMode={editMode}
|
||||
options={locationNames}
|
||||
color={
|
||||
!editMode && !interacts.transferlocation
|
||||
? 'red'
|
||||
: undefined
|
||||
}
|
||||
entry={
|
||||
interacts.transferlocation
|
||||
? interacts.transferlocation
|
||||
: 'Disabled'
|
||||
}
|
||||
tooltip="Target location of the primary transfer trigger on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Secondary Transfer Location">
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_transferlocation_secondary"
|
||||
editMode={editMode}
|
||||
options={locationNames}
|
||||
color={
|
||||
!editMode && !interacts.transferlocation
|
||||
? 'red'
|
||||
: undefined
|
||||
}
|
||||
entry={
|
||||
interacts.transferlocation_secondary
|
||||
? interacts.transferlocation_secondary
|
||||
: 'Disabled'
|
||||
}
|
||||
tooltip="Target location of the secondary transfer trigger on resist."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
<Stack.Divider />
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item mt="5px">
|
||||
<Section
|
||||
title="Auto-Transfer Options"
|
||||
buttons={
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_autotransfer_enabled"
|
||||
editMode={editMode}
|
||||
active={!!escapable}
|
||||
tooltip={
|
||||
'Allows you to setup auto transfer options for this belly. So that prey is automatically moved depending on a timer or content count.'
|
||||
}
|
||||
>
|
||||
{interacts.escapechance + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Absorbed Escape Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_escapechance_absorbed' })
|
||||
}
|
||||
>
|
||||
{interacts.escapechance_absorbed + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Escape Time">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_escapetime' })
|
||||
}
|
||||
>
|
||||
{interacts.escapetime / 10 + 's'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Transfer Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_transferchance' })
|
||||
}
|
||||
>
|
||||
{interacts.transferchance + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Transfer Location">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_transferlocation' })
|
||||
}
|
||||
>
|
||||
{interacts.transferlocation
|
||||
? interacts.transferlocation
|
||||
: 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Secondary Transfer Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_transferchance_secondary',
|
||||
})
|
||||
}
|
||||
>
|
||||
{interacts.transferchance_secondary + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Secondary Transfer Location">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_transferlocation_secondary',
|
||||
})
|
||||
}
|
||||
>
|
||||
{interacts.transferlocation_secondary
|
||||
? interacts.transferlocation_secondary
|
||||
: 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Absorb Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_absorbchance' })
|
||||
}
|
||||
>
|
||||
{interacts.absorbchance + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_digestchance' })
|
||||
}
|
||||
>
|
||||
{interacts.digestchance + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Belch Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_belchchance' })
|
||||
}
|
||||
>
|
||||
{interacts.belchchance + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
</LabeledList>
|
||||
) : (
|
||||
'These options only display while interactions are turned on.'
|
||||
)}
|
||||
<Section
|
||||
title="Auto-Transfer Options"
|
||||
buttons={
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_autotransfer_enabled' })
|
||||
}
|
||||
icon={autotransfer_enabled ? 'toggle-on' : 'toggle-off'}
|
||||
selected={autotransfer_enabled}
|
||||
>
|
||||
{autotransfer_enabled
|
||||
? 'Auto-Transfer Enabled'
|
||||
: 'Auto-Transfer Disabled'}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{autotransfer_enabled ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Auto-Transfer Time">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_autotransferwait' })
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransferwait / 10 + 's'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Min Amount">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_min_amount',
|
||||
})
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransfer_min_amount}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Max Amount">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_max_amount',
|
||||
})
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransfer_max_amount}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Auto-Transfer Primary Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_autotransferchance' })
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransferchance + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Location">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_autotransferlocation' })
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransferlocation
|
||||
? autotransfer.autotransferlocation
|
||||
: 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Location Extras">
|
||||
{(autotransfer.autotransferextralocation &&
|
||||
autotransfer.autotransferextralocation.join(', ')) ||
|
||||
''}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransferextralocation',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Whitelist (Mobs)">
|
||||
{(autotransfer.autotransfer_whitelist.length &&
|
||||
autotransfer.autotransfer_whitelist.join(', ')) ||
|
||||
'Everything'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_whitelist',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Whitelist (Items)">
|
||||
{(autotransfer.autotransfer_whitelist_items.length &&
|
||||
autotransfer.autotransfer_whitelist_items.join(', ')) ||
|
||||
'Everything'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_whitelist_items',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Blacklist (Mobs)">
|
||||
{(autotransfer.autotransfer_blacklist.length &&
|
||||
autotransfer.autotransfer_blacklist.join(', ')) ||
|
||||
'Nothing'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_blacklist',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Primary Blacklist (Items)">
|
||||
{(autotransfer.autotransfer_blacklist_items.length &&
|
||||
autotransfer.autotransfer_blacklist_items.join(', ')) ||
|
||||
'Nothing'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_blacklist_items',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Divider />
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Chance">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransferchance_secondary',
|
||||
})
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransferchance_secondary + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Location">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransferlocation_secondary',
|
||||
})
|
||||
}
|
||||
>
|
||||
{autotransfer.autotransferlocation_secondary
|
||||
? autotransfer.autotransferlocation_secondary
|
||||
: 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Location Extras">
|
||||
{(autotransfer.autotransferextralocation_secondary &&
|
||||
autotransfer.autotransferextralocation_secondary.join(', ')) ||
|
||||
''}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransferextralocation_secondary',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Whitelist (Mobs)">
|
||||
{(autotransfer.autotransfer_secondary_whitelist.length &&
|
||||
autotransfer.autotransfer_secondary_whitelist.join(', ')) ||
|
||||
'Everything'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_secondary_whitelist',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Whitelist (Items)">
|
||||
{(autotransfer.autotransfer_secondary_whitelist_items.length &&
|
||||
autotransfer.autotransfer_secondary_whitelist_items.join(
|
||||
', ',
|
||||
)) ||
|
||||
'Everything'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_secondary_whitelist_items',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Blacklist (Mobs)">
|
||||
{(autotransfer.autotransfer_secondary_blacklist.length &&
|
||||
autotransfer.autotransfer_secondary_blacklist.join(', ')) ||
|
||||
'Nothing'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_secondary_blacklist',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Secondary Blacklist (Items)">
|
||||
{(autotransfer.autotransfer_secondary_blacklist_items.length &&
|
||||
autotransfer.autotransfer_secondary_blacklist_items.join(
|
||||
', ',
|
||||
)) ||
|
||||
'Nothing'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_autotransfer_secondary_blacklist_items',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
) : (
|
||||
'These options only display while Auto-Transfer is enabled.'
|
||||
)}
|
||||
</Section>
|
||||
</Section>
|
||||
/>
|
||||
}
|
||||
>
|
||||
{!!autotransfer_enabled && (
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList.Item label="Auto-Transfer Min Amount">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_autotransfer_min_amount"
|
||||
editMode={editMode}
|
||||
value={autotransfer.autotransfer_min_amount}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
tooltip="Set the minimum amount of items your belly can belly auto-transfer at once. Set to 0 for no limit."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Auto-Transfer Max Amount">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_autotransfer_max_amount"
|
||||
editMode={editMode}
|
||||
value={autotransfer.autotransfer_max_amount}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
tooltip="Set the minimum amount of items your belly can belly auto-transfer at once. Set to 0 for no limit."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList.Item label="Auto-Transfer Time">
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_autotransferwait"
|
||||
editMode={editMode}
|
||||
value={autoTransferTimeSeconds}
|
||||
unit={
|
||||
autoTransferTimeSeconds === 1 ? 'second' : 'seconds'
|
||||
}
|
||||
minValue={1}
|
||||
maxValue={1800}
|
||||
tooltip="Set minimum number of seconds for auto-transfer wait delay."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<AutoTransferOptions
|
||||
editMode={editMode}
|
||||
title={'primary'}
|
||||
bellyDropdownNames={bellyDropdownNames}
|
||||
locationNames={locationNames}
|
||||
autotransferData={autotransfer.primary_transfer}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<AutoTransferOptions
|
||||
editMode={editMode}
|
||||
title={'secondary'}
|
||||
bellyDropdownNames={bellyDropdownNames}
|
||||
locationNames={locationNames}
|
||||
autotransferData={autotransfer.secondary_transfer}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
-181
@@ -1,181 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
|
||||
import type { selectedData } from '../types';
|
||||
|
||||
export const VoreSelectedBellyLiquidMessages = (props: {
|
||||
belly: selectedData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { belly } = props;
|
||||
const { show_liq_fullness, liq_messages } = belly;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Liquid Messages"
|
||||
buttons={
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', { liq_messages: 'b_show_liq_fullness' })
|
||||
}
|
||||
icon={show_liq_fullness ? 'toggle-on' : 'toggle-off'}
|
||||
selected={show_liq_fullness}
|
||||
tooltipPosition="left"
|
||||
tooltip={
|
||||
'These are the settings for belly visibility when involving liquids fullness.'
|
||||
}
|
||||
>
|
||||
{show_liq_fullness ? 'Messages On' : 'Messages Off'}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{show_liq_fullness ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="0 to 20%">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', {
|
||||
liq_messages: 'b_liq_msg_toggle1',
|
||||
})
|
||||
}
|
||||
icon={
|
||||
liq_messages.liq_msg_toggle1 ? 'toggle-on' : 'toggle-off'
|
||||
}
|
||||
selected={liq_messages.liq_msg_toggle1}
|
||||
>
|
||||
{liq_messages.liq_msg_toggle1 ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', { liq_messages: 'b_liq_msg1' })
|
||||
}
|
||||
>
|
||||
Examine Message (0 to 20%)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="20 to 40%">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', {
|
||||
liq_messages: 'b_liq_msg_toggle2',
|
||||
})
|
||||
}
|
||||
icon={
|
||||
liq_messages.liq_msg_toggle2 ? 'toggle-on' : 'toggle-off'
|
||||
}
|
||||
selected={liq_messages.liq_msg_toggle2}
|
||||
>
|
||||
{liq_messages.liq_msg_toggle2 ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', { liq_messages: 'b_liq_msg2' })
|
||||
}
|
||||
>
|
||||
Examine Message (20 to 40%)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="40 to 60%">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', {
|
||||
liq_messages: 'b_liq_msg_toggle3',
|
||||
})
|
||||
}
|
||||
icon={
|
||||
liq_messages.liq_msg_toggle3 ? 'toggle-on' : 'toggle-off'
|
||||
}
|
||||
selected={liq_messages.liq_msg_toggle3}
|
||||
>
|
||||
{liq_messages.liq_msg_toggle3 ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', { liq_messages: 'b_liq_msg3' })
|
||||
}
|
||||
>
|
||||
Examine Message (40 to 60%)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="60 to 80%">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', {
|
||||
liq_messages: 'b_liq_msg_toggle4',
|
||||
})
|
||||
}
|
||||
icon={
|
||||
liq_messages.liq_msg_toggle4 ? 'toggle-on' : 'toggle-off'
|
||||
}
|
||||
selected={liq_messages.liq_msg_toggle4}
|
||||
>
|
||||
{liq_messages.liq_msg_toggle4 ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', { liq_messages: 'b_liq_msg4' })
|
||||
}
|
||||
>
|
||||
Examine Message (60 to 80%)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="80 to 100%">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', {
|
||||
liq_messages: 'b_liq_msg_toggle5',
|
||||
})
|
||||
}
|
||||
icon={
|
||||
liq_messages.liq_msg_toggle5 ? 'toggle-on' : 'toggle-off'
|
||||
}
|
||||
selected={liq_messages.liq_msg_toggle5}
|
||||
>
|
||||
{liq_messages.liq_msg_toggle5 ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_messages', { liq_messages: 'b_liq_msg5' })
|
||||
}
|
||||
>
|
||||
Examine Message (80 to 100%)
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
) : (
|
||||
'These options only display while liquid examination settings are turned on.'
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
+66
-308
@@ -1,329 +1,87 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Section } from 'tgui-core/components';
|
||||
import { Button, LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
|
||||
import { reagentToColor } from '../constants';
|
||||
import { LiquidColorInput } from '../LiquidColorInput';
|
||||
import type { selectedData } from '../types';
|
||||
import { liquidToTooltip } from '../constants';
|
||||
import type { bellyLiquidData } from '../types';
|
||||
import { VorePanelEditCheckboxes } from '../VorePanelElements/VorePanelEditCheckboxes';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
import { LiquidOptionsLeft } from './LiquidTab/LiquidOptionsLeft';
|
||||
import { LiquidOptionsRight } from './LiquidTab/LiquidOptionsRight';
|
||||
|
||||
export const VoreSelectedBellyLiquidOptions = (props: {
|
||||
belly: selectedData;
|
||||
editMode: boolean;
|
||||
bellyLiquidData: bellyLiquidData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { belly } = props;
|
||||
const { show_liq, liq_interacts } = belly;
|
||||
|
||||
const generationTime = (liq_interacts.liq_reagent_nutri_rate + 1) * 10;
|
||||
const generationMinutes = generationTime % 60;
|
||||
const generationHours = Math.floor(generationTime / 60);
|
||||
const { editMode, bellyLiquidData } = props;
|
||||
const { show_liq, liq_interacts } = bellyLiquidData;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Liquid Options"
|
||||
fill
|
||||
buttons={
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_show_liq' })
|
||||
}
|
||||
icon={show_liq ? 'toggle-on' : 'toggle-off'}
|
||||
selected={show_liq}
|
||||
tooltipPosition="left"
|
||||
tooltip={
|
||||
'These are the settings for liquid bellies, every belly has a liquid storage.'
|
||||
}
|
||||
>
|
||||
{show_liq ? 'Liquids On' : 'Liquids Off'}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{show_liq ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Generate Liquids">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_liq_reagent_gen' })
|
||||
}
|
||||
icon={liq_interacts.liq_reagent_gen ? 'toggle-on' : 'toggle-off'}
|
||||
selected={liq_interacts.liq_reagent_gen}
|
||||
>
|
||||
{liq_interacts.liq_reagent_gen ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Type">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_liq_reagent_type',
|
||||
})
|
||||
}
|
||||
icon="pen"
|
||||
color={reagentToColor[liq_interacts.liq_reagent_type]}
|
||||
>
|
||||
{liq_interacts.liq_reagent_type}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Name">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_liq_reagent_name',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.liq_reagent_name}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Transfer Verb">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_liq_reagent_transfer_verb',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.liq_reagent_transfer_verb}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Generation Time">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_liq_reagent_nutri_rate',
|
||||
})
|
||||
}
|
||||
icon="clock"
|
||||
>
|
||||
{(generationHours < 10
|
||||
? '0' + generationHours
|
||||
: generationHours) +
|
||||
':' +
|
||||
(generationMinutes < 10
|
||||
? '0' + generationMinutes
|
||||
: generationMinutes) +
|
||||
' hh:mm'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Capacity">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_liq_reagent_capacity',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.liq_reagent_capacity}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Slosh Sounds">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_liq_sloshing' })
|
||||
}
|
||||
icon={liq_interacts.liq_sloshing ? 'toggle-on' : 'toggle-off'}
|
||||
selected={liq_interacts.liq_sloshing}
|
||||
>
|
||||
{liq_interacts.liq_sloshing ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Addons">
|
||||
{(liq_interacts.liq_reagent_addons.length &&
|
||||
liq_interacts.liq_reagent_addons.join(', ')) ||
|
||||
'None'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_liq_reagent_addons',
|
||||
})
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Application to Prey">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_reagent_touches' })
|
||||
}
|
||||
icon={liq_interacts.reagent_touches ? 'toggle-on' : 'toggle-off'}
|
||||
selected={liq_interacts.reagent_touches}
|
||||
>
|
||||
{liq_interacts.reagent_touches ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Liquid Color">
|
||||
<LiquidColorInput
|
||||
action_name="b_custom_reagentcolor"
|
||||
value_of={null}
|
||||
back_color={liq_interacts.custom_reagentcolor}
|
||||
name_of="Custom Liquid Color"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Overlay">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_liquid_overlay' })
|
||||
}
|
||||
icon={liq_interacts.liquid_overlay ? 'toggle-on' : 'toggle-off'}
|
||||
selected={liq_interacts.liquid_overlay}
|
||||
>
|
||||
{liq_interacts.liquid_overlay ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Max Liquid Level">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_max_liquid_level',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.max_liquid_level + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Liquid Alpha">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_custom_reagentalpha',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.custom_reagentalpha}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Fullness Overlay">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_mush_overlay' })
|
||||
}
|
||||
icon={liq_interacts.mush_overlay ? 'toggle-on' : 'toggle-off'}
|
||||
selected={liq_interacts.mush_overlay}
|
||||
>
|
||||
{liq_interacts.mush_overlay ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mush Overlay Color">
|
||||
<LiquidColorInput
|
||||
action_name="b_mush_color"
|
||||
value_of={null}
|
||||
back_color={liq_interacts.mush_color}
|
||||
name_of="Custom Mush Color"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mush Overlay Alpha">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_mush_alpha',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.mush_alpha}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mush Overlay Scaling">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_max_mush',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.max_mush}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Minimum Mush Level">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_min_mush',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.min_mush + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Item Mush Value">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_item_mush_val',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.item_mush_val + ' fullness per item'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Overlay">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_metabolism_overlay',
|
||||
})
|
||||
}
|
||||
icon={
|
||||
liq_interacts.metabolism_overlay ? 'toggle-on' : 'toggle-off'
|
||||
}
|
||||
selected={liq_interacts.metabolism_overlay}
|
||||
>
|
||||
{liq_interacts.metabolism_overlay ? 'On' : 'Off'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Mush Ratio">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_metabolism_mush_ratio',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.metabolism_mush_ratio +
|
||||
' fullness per reagent unit'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Overlay Scaling">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_max_ingested',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.max_ingested}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Metabolism Color">
|
||||
<LiquidColorInput
|
||||
action_name="b_custom_ingested_color"
|
||||
value_of={null}
|
||||
back_color={liq_interacts.custom_ingested_color}
|
||||
name_of="Custom Metabolism Color"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Metabolism Overlay Alpha">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', {
|
||||
liq_attribute: 'b_custom_ingested_alpha',
|
||||
})
|
||||
}
|
||||
>
|
||||
{liq_interacts.custom_ingested_alpha}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Purge Liquids">
|
||||
<Button
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<Button.Confirm
|
||||
color="red"
|
||||
tooltip="Clear this belly's liquids."
|
||||
confirmContent="Confirm Purge?"
|
||||
onClick={() =>
|
||||
act('liq_set_attribute', { liq_attribute: 'b_liq_purge' })
|
||||
}
|
||||
>
|
||||
Purge Liquids
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
) : (
|
||||
'These options only display while liquid settings are turned on.'
|
||||
</Button.Confirm>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<VorePanelEditSwitch
|
||||
action="liq_set_attribute"
|
||||
subAction="b_show_liq"
|
||||
editMode={editMode}
|
||||
active={!!show_liq}
|
||||
tooltip={
|
||||
'These are the settings for liquid bellies, every belly has a liquid storage.'
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
{!!show_liq && (
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Liquid Addons">
|
||||
<VorePanelEditCheckboxes
|
||||
editMode={editMode}
|
||||
options={liq_interacts.liq_reagent_addons}
|
||||
action="liq_set_attribute"
|
||||
subAction="b_liq_reagent_addons"
|
||||
tooltipList={liquidToTooltip}
|
||||
tooltip='Liquid production modes to apply as soon as "Produce Liquids" is turned on.'
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item mt="5px">
|
||||
<Stack fill>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LiquidOptionsLeft
|
||||
editMode={editMode}
|
||||
liquidInteract={liq_interacts}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LiquidOptionsRight
|
||||
editMode={editMode}
|
||||
liquidInteract={liq_interacts}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
|
||||
+15
-355
@@ -1,370 +1,30 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
import { Stack } from 'tgui-core/components';
|
||||
|
||||
import { vorespawnAbsorbedColor, vorespawnAbsorbedText } from '../constants';
|
||||
import type { hostMob, selectedData } from '../types';
|
||||
import { VoreSelectedMobTypeBellyButtons } from './VoreSelectedMobTypeBellyButtons';
|
||||
import type { bellyOptionData, hostMob } from '../types';
|
||||
import { BellyOptionsLeft } from './OptionTab/BellyOptionsLeft';
|
||||
import { BellyOptionsRight } from './OptionTab/BellyOptionsRight';
|
||||
|
||||
export const VoreSelectedBellyOptions = (props: {
|
||||
belly: selectedData;
|
||||
editMode: boolean;
|
||||
bellyOptionData: bellyOptionData;
|
||||
host_mobtype: hostMob;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { belly, host_mobtype } = props;
|
||||
const {
|
||||
can_taste,
|
||||
is_feedable,
|
||||
nutrition_percent,
|
||||
digest_brute,
|
||||
digest_burn,
|
||||
digest_oxy,
|
||||
digest_tox,
|
||||
digest_clone,
|
||||
bulge_size,
|
||||
display_absorbed_examine,
|
||||
shrink_grow_size,
|
||||
emote_time,
|
||||
emote_active,
|
||||
contaminates,
|
||||
contaminate_flavor,
|
||||
contaminate_color,
|
||||
egg_type,
|
||||
egg_name,
|
||||
egg_size,
|
||||
recycling,
|
||||
storing_nutrition,
|
||||
entrance_logs,
|
||||
item_digest_logs,
|
||||
selective_preference,
|
||||
save_digest_mode,
|
||||
eating_privacy_local,
|
||||
vorespawn_blacklist,
|
||||
vorespawn_whitelist,
|
||||
vorespawn_absorbed,
|
||||
private_struggle,
|
||||
drainmode,
|
||||
} = belly;
|
||||
const { editMode, bellyOptionData, host_mobtype } = props;
|
||||
|
||||
return (
|
||||
<Stack wrap="wrap">
|
||||
<Stack fill>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Can Taste">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_tastes' })}
|
||||
icon={can_taste ? 'toggle-on' : 'toggle-off'}
|
||||
selected={can_taste}
|
||||
>
|
||||
{can_taste ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Feedable">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_feedable' })}
|
||||
icon={is_feedable ? 'toggle-on' : 'toggle-off'}
|
||||
selected={is_feedable}
|
||||
>
|
||||
{is_feedable ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Contaminates">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_contaminates' })
|
||||
}
|
||||
icon={contaminates ? 'toggle-on' : 'toggle-off'}
|
||||
selected={contaminates}
|
||||
>
|
||||
{contaminates ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
{contaminates ? (
|
||||
<>
|
||||
<LabeledList.Item label="Contamination Flavor">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_contamination_flavor',
|
||||
})
|
||||
}
|
||||
icon="pen"
|
||||
>
|
||||
{contaminate_flavor}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Contamination Color">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_contamination_color' })
|
||||
}
|
||||
icon="pen"
|
||||
>
|
||||
{!!contaminate_color && capitalize(contaminate_color)}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<LabeledList.Item label="Nutritional Gain">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_nutritionpercent' })
|
||||
}
|
||||
>
|
||||
{nutrition_percent + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Required Examine Size">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_bulge_size' })
|
||||
}
|
||||
>
|
||||
{bulge_size * 100 + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Display Absorbed Examines">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_display_absorbed_examine',
|
||||
})
|
||||
}
|
||||
icon={display_absorbed_examine ? 'toggle-on' : 'toggle-off'}
|
||||
selected={display_absorbed_examine}
|
||||
>
|
||||
{display_absorbed_examine ? 'True' : 'False'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Toggle Vore Privacy">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_eating_privacy' })
|
||||
}
|
||||
>
|
||||
{capitalize(eating_privacy_local)}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Toggle Struggle Privacy">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_private_struggle' })
|
||||
}
|
||||
icon={private_struggle ? 'toggle-on' : 'toggle-off'}
|
||||
selected={private_struggle}
|
||||
>
|
||||
{private_struggle ? 'Private' : 'Loud'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
|
||||
<LabeledList.Item label="Save Digest Mode">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_save_digest_mode' })
|
||||
}
|
||||
icon={save_digest_mode ? 'toggle-on' : 'toggle-off'}
|
||||
selected={save_digest_mode}
|
||||
>
|
||||
{save_digest_mode ? 'True' : 'False'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<VoreSelectedMobTypeBellyButtons
|
||||
belly={belly}
|
||||
<BellyOptionsLeft
|
||||
editMode={editMode}
|
||||
bellyOptionData={bellyOptionData}
|
||||
host_mobtype={host_mobtype}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Idle Emotes">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_emoteactive' })
|
||||
}
|
||||
icon={emote_active ? 'toggle-on' : 'toggle-off'}
|
||||
selected={emote_active}
|
||||
>
|
||||
{emote_active ? 'Active' : 'Inactive'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Idle Emote Delay">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_emotetime' })}
|
||||
>
|
||||
{emote_time + ' seconds'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Brute Damage">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_brute_dmg' })}
|
||||
>
|
||||
{digest_brute}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Burn Damage">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_burn_dmg' })}
|
||||
>
|
||||
{digest_burn}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Suffocation Damage">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_oxy_dmg' })}
|
||||
>
|
||||
{digest_oxy}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Toxins Damage">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_tox_dmg' })}
|
||||
>
|
||||
{digest_tox}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Digest Clone Damage">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_clone_dmg' })}
|
||||
>
|
||||
{digest_clone}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Drain Finishing Mode">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_drainmode' })}
|
||||
>
|
||||
{drainmode}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Shrink/Grow Size">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_grow_shrink' })
|
||||
}
|
||||
>
|
||||
{shrink_grow_size * 100 + '%'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Vore Spawn Blacklist">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_vorespawn_blacklist' })
|
||||
}
|
||||
icon={vorespawn_blacklist ? 'toggle-on' : 'toggle-off'}
|
||||
selected={vorespawn_blacklist}
|
||||
>
|
||||
{vorespawn_blacklist ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
{vorespawn_blacklist ? (
|
||||
''
|
||||
) : (
|
||||
<>
|
||||
<LabeledList.Item label="Vore Spawn Whitelist">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_vorespawn_whitelist' })
|
||||
}
|
||||
icon="pen"
|
||||
>
|
||||
{vorespawn_whitelist.length
|
||||
? vorespawn_whitelist.join(', ')
|
||||
: 'Anyone!'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Vore Spawn Absorbed">
|
||||
<Button
|
||||
color={vorespawnAbsorbedColor[vorespawn_absorbed]}
|
||||
tooltip="Click to toggle between No, Yes and Prey's Choice."
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_vorespawn_absorbed' })
|
||||
}
|
||||
>
|
||||
{vorespawnAbsorbedText[vorespawn_absorbed]}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</>
|
||||
)}
|
||||
<LabeledList.Item label="Egg Type">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_egg_type' })}
|
||||
icon="pen"
|
||||
>
|
||||
{capitalize(egg_type)}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Egg Name">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_egg_name' })}
|
||||
icon="pen"
|
||||
>
|
||||
{egg_name ? egg_name : 'Default'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Egg Size">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_egg_size' })}
|
||||
>
|
||||
{egg_size ? egg_size * 100 + '%' : 'Automatic'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Recycling">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_recycling' })}
|
||||
icon={recycling ? 'toggle-on' : 'toggle-off'}
|
||||
selected={recycling}
|
||||
>
|
||||
{recycling ? 'Enabled' : 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Storing Nutrition">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_storing_nutrition' })
|
||||
}
|
||||
icon={storing_nutrition ? 'toggle-on' : 'toggle-off'}
|
||||
selected={storing_nutrition}
|
||||
>
|
||||
{storing_nutrition ? 'Storing' : 'Absorbing'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Entrance Logs">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_entrance_logs' })
|
||||
}
|
||||
icon={entrance_logs ? 'toggle-on' : 'toggle-off'}
|
||||
selected={entrance_logs}
|
||||
>
|
||||
{entrance_logs ? 'Enabled' : 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Item Digestion Logs">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_item_digest_logs' })
|
||||
}
|
||||
icon={item_digest_logs ? 'toggle-on' : 'toggle-off'}
|
||||
selected={item_digest_logs}
|
||||
>
|
||||
{item_digest_logs ? 'Enabled' : 'Disabled'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Selective Mode Preference">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_selective_mode_pref_toggle',
|
||||
})
|
||||
}
|
||||
>
|
||||
{capitalize(selective_preference)}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<BellyOptionsRight
|
||||
editMode={editMode}
|
||||
bellyOptionData={bellyOptionData}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
+140
-68
@@ -1,12 +1,18 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
|
||||
import type { selectedData } from '../types';
|
||||
import { useBackend } from '../../../backend';
|
||||
import type { bellySoundData, DropdownEntry } from '../types';
|
||||
import { VorePanelEditDropdown } from '../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditNumber } from '../VorePanelElements/VorePanelEditNumber';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
|
||||
export const VoreSelectedBellySounds = (props: { belly: selectedData }) => {
|
||||
export const VoreSelectedBellySounds = (props: {
|
||||
editMode: boolean;
|
||||
bellySoundData: bellySoundData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { belly } = props;
|
||||
const { editMode, bellySoundData } = props;
|
||||
const {
|
||||
is_wet,
|
||||
wet_loop,
|
||||
@@ -15,82 +21,148 @@ export const VoreSelectedBellySounds = (props: { belly: selectedData }) => {
|
||||
release_sound,
|
||||
sound_volume,
|
||||
noise_freq,
|
||||
} = belly;
|
||||
min_voice_freq,
|
||||
max_voice_freq,
|
||||
vore_sound_list,
|
||||
release_sound_list,
|
||||
} = bellySoundData;
|
||||
|
||||
const ourPresets: DropdownEntry[] = [
|
||||
{ displayText: 'high', value: max_voice_freq.toString() },
|
||||
{ displayText: 'middle-high', value: '56250' },
|
||||
{ displayText: 'middle', value: '42500' },
|
||||
{ displayText: 'middle-low', value: '28750' },
|
||||
{ displayText: 'low', value: min_voice_freq.toString() },
|
||||
{ displayText: 'random', value: '0' },
|
||||
];
|
||||
|
||||
function getDropdownDisplay(currentFeq: number) {
|
||||
const ourEntry = ourPresets.find(
|
||||
(preset) => preset.value === currentFeq.toString(),
|
||||
);
|
||||
if (!ourEntry) {
|
||||
return 'custom';
|
||||
}
|
||||
return ourEntry.displayText;
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack wrap="wrap">
|
||||
<Stack>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Fleshy Belly">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_wetness' })}
|
||||
icon={is_wet ? 'toggle-on' : 'toggle-off'}
|
||||
selected={is_wet}
|
||||
>
|
||||
{is_wet ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Internal Loop">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_wetloop' })}
|
||||
icon={wet_loop ? 'toggle-on' : 'toggle-off'}
|
||||
selected={wet_loop}
|
||||
>
|
||||
{wet_loop ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Use Fancy Sounds">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_fancy_sound' })
|
||||
}
|
||||
icon={fancy ? 'toggle-on' : 'toggle-off'}
|
||||
selected={fancy}
|
||||
>
|
||||
{fancy ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Vore Sound">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_sound' })}
|
||||
>
|
||||
{sound}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_soundtest' })}
|
||||
icon="volume-up"
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_wetness"
|
||||
editMode={editMode}
|
||||
content={is_wet ? 'Yes' : 'No'}
|
||||
active={!!is_wet}
|
||||
tooltip="When enabled, noises are more fleshy and less rustly."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Release Sound">
|
||||
<Button
|
||||
onClick={() => act('set_attribute', { attribute: 'b_release' })}
|
||||
>
|
||||
{release_sound}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_releasesoundtest' })
|
||||
}
|
||||
icon="volume-up"
|
||||
<LabeledList.Item label="Internal Loop">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_wetloop"
|
||||
editMode={editMode}
|
||||
content={wet_loop ? 'Yes' : 'No'}
|
||||
active={!!wet_loop}
|
||||
tooltip="Loops belly sounds."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Use Fancy Sounds">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_fancy_sound"
|
||||
editMode={editMode}
|
||||
content={fancy ? 'Yes' : 'No'}
|
||||
active={!!fancy}
|
||||
tooltip="Switch between the fancy and classic sound set."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Sound Volume">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_sound_volume' })
|
||||
}
|
||||
>
|
||||
{sound_volume + '%'}
|
||||
</Button>
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_sound_volume"
|
||||
editMode={editMode}
|
||||
value={sound_volume}
|
||||
minValue={0}
|
||||
maxValue={100}
|
||||
unit="%"
|
||||
tooltip="Adjust the volume of your vore sounds."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Noise Frequency">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_noise_freq' })
|
||||
}
|
||||
>
|
||||
{noise_freq}
|
||||
</Button>
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<VorePanelEditNumber
|
||||
action="set_attribute"
|
||||
subAction="b_noise_freq"
|
||||
editMode={editMode}
|
||||
value={noise_freq}
|
||||
minValue={min_voice_freq}
|
||||
maxValue={max_voice_freq}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_noise_freq"
|
||||
editMode={editMode}
|
||||
options={ourPresets}
|
||||
entry={getDropdownDisplay(noise_freq)}
|
||||
tooltip="Adjust the frequency of your vore sounds. The dropdown contains presets."
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Vore Sound">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_sound"
|
||||
editMode={editMode}
|
||||
options={Object.keys(vore_sound_list)}
|
||||
entry={sound}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_soundtest' })
|
||||
}
|
||||
icon="volume-up"
|
||||
tooltip="Test your selected belly sound. Usually played to prey inside your belly."
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Release Sound">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<VorePanelEditDropdown
|
||||
action="set_attribute"
|
||||
subAction="b_release"
|
||||
editMode={editMode}
|
||||
options={Object.keys(release_sound_list)}
|
||||
entry={release_sound}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_releasesoundtest' })
|
||||
}
|
||||
icon="volume-up"
|
||||
tooltip="Test your selected release sound. Usually played once prey is released."
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
|
||||
+153
-348
@@ -1,368 +1,173 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Box, Button, LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
import { classes } from 'tgui-core/react';
|
||||
import { Button, LabeledList, Section, Stack } from 'tgui-core/components';
|
||||
|
||||
import { FeatureColorInput } from '../FeatureColorInput';
|
||||
import type { selectedData } from '../types';
|
||||
import type { bellyVisualData } from '../types';
|
||||
import { VorePanelEditColor } from '../VorePanelElements/VorePanelEditColor';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
import { BellyFullscreenSelection } from './VisualTab/BellyFullscreenSelection';
|
||||
import { VoreSpriteAffects } from './VisualTab/VoreSpriteAffect';
|
||||
|
||||
export const VoreSelectedBellyVisuals = (props: { belly: selectedData }) => {
|
||||
export const VoreSelectedBellyVisuals = (props: {
|
||||
editMode: boolean;
|
||||
bellyVisualData: bellyVisualData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { belly } = props;
|
||||
const { editMode, bellyVisualData } = props;
|
||||
const {
|
||||
belly_fullscreen,
|
||||
colorization_enabled,
|
||||
belly_fullscreen_color,
|
||||
belly_fullscreen_color2,
|
||||
belly_fullscreen_color3,
|
||||
belly_fullscreen_color4,
|
||||
colorization_enabled,
|
||||
belly_fullscreen_alpha,
|
||||
possible_fullscreens,
|
||||
disable_hud,
|
||||
vore_sprite_flags,
|
||||
affects_voresprite,
|
||||
absorbed_voresprite,
|
||||
absorbed_multiplier,
|
||||
liquid_voresprite,
|
||||
liquid_multiplier,
|
||||
item_voresprite,
|
||||
item_multiplier,
|
||||
health_voresprite,
|
||||
resist_animation,
|
||||
voresprite_size_factor,
|
||||
belly_sprite_option_shown,
|
||||
belly_sprite_to_affect,
|
||||
undergarment_chosen,
|
||||
undergarment_if_none,
|
||||
undergarment_color,
|
||||
tail_option_shown,
|
||||
tail_to_change_to,
|
||||
} = belly;
|
||||
} = bellyVisualData;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section title="Vore Sprites">
|
||||
<Stack direction="row">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Affect Vore Sprites">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_affects_vore_sprites' })
|
||||
}
|
||||
icon={affects_voresprite ? 'toggle-on' : 'toggle-off'}
|
||||
selected={affects_voresprite}
|
||||
>
|
||||
{affects_voresprite ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
{affects_voresprite ? (
|
||||
<>
|
||||
<LabeledList.Item label="Vore Sprite Mode">
|
||||
{(vore_sprite_flags.length && vore_sprite_flags.join(', ')) ||
|
||||
'None'}
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_vore_sprite_flags' })
|
||||
}
|
||||
ml={1}
|
||||
icon="plus"
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Count Absorbed prey for vore sprites">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_count_absorbed_prey_for_sprites',
|
||||
})
|
||||
}
|
||||
icon={absorbed_voresprite ? 'toggle-on' : 'toggle-off'}
|
||||
selected={absorbed_voresprite}
|
||||
>
|
||||
{absorbed_voresprite ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Absorbed Multiplier">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_absorbed_multiplier',
|
||||
})
|
||||
}
|
||||
>
|
||||
{absorbed_multiplier}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Count liquid reagents for vore sprites">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_count_liquid_for_sprites',
|
||||
})
|
||||
}
|
||||
icon={liquid_voresprite ? 'toggle-on' : 'toggle-off'}
|
||||
selected={liquid_voresprite}
|
||||
>
|
||||
{liquid_voresprite ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Liquid Multiplier">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_liquid_multiplier' })
|
||||
}
|
||||
>
|
||||
{liquid_multiplier}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Count items for vore sprites">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_count_items_for_sprites',
|
||||
})
|
||||
}
|
||||
icon={item_voresprite ? 'toggle-on' : 'toggle-off'}
|
||||
selected={item_voresprite}
|
||||
>
|
||||
{item_voresprite ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Items Multiplier">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_item_multiplier' })
|
||||
}
|
||||
>
|
||||
{item_multiplier}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Prey health affects vore sprites">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_health_impacts_size',
|
||||
})
|
||||
}
|
||||
icon={health_voresprite ? 'toggle-on' : 'toggle-off'}
|
||||
selected={health_voresprite}
|
||||
>
|
||||
{health_voresprite ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Animation when prey resist">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_resist_animation' })
|
||||
}
|
||||
icon={resist_animation ? 'toggle-on' : 'toggle-off'}
|
||||
selected={resist_animation}
|
||||
>
|
||||
{resist_animation ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Vore Sprite Size Factor">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_size_factor_sprites',
|
||||
})
|
||||
}
|
||||
>
|
||||
{voresprite_size_factor}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
{belly_sprite_option_shown ? (
|
||||
<LabeledList.Item label="Belly Sprite to affect">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_belly_sprite_to_affect',
|
||||
})
|
||||
}
|
||||
>
|
||||
{belly_sprite_to_affect}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
) : (
|
||||
<LabeledList.Item label="Belly Sprite to affect">
|
||||
<Box textColor="red">You do not have any bellysprites.</Box>
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{tail_option_shown &&
|
||||
vore_sprite_flags.includes('Undergarment addition') ? (
|
||||
<>
|
||||
<LabeledList.Item label="Undergarment type to affect">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_undergarment_choice',
|
||||
})
|
||||
}
|
||||
>
|
||||
{undergarment_chosen}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Undergarment if none equipped">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_undergarment_if_none',
|
||||
})
|
||||
}
|
||||
>
|
||||
{undergarment_if_none}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<FeatureColorInput
|
||||
action_name="b_undergarment_color"
|
||||
value_of={null}
|
||||
back_color={undergarment_color}
|
||||
name_of="Undergarment Color if none"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{tail_option_shown &&
|
||||
vore_sprite_flags.includes('Tail adjustment') ? (
|
||||
<LabeledList.Item label="Tail to change to">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', {
|
||||
attribute: 'b_tail_to_change_to',
|
||||
})
|
||||
}
|
||||
>
|
||||
{tail_to_change_to}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</LabeledList>
|
||||
</Stack>
|
||||
</Section>
|
||||
<Section title="Belly Fullscreens Preview and Coloring">
|
||||
<Stack align="center">
|
||||
<FeatureColorInput
|
||||
action_name="b_fullscreen_color"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color}
|
||||
name_of="1"
|
||||
/>
|
||||
<FeatureColorInput
|
||||
action_name="b_fullscreen_color2"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color2}
|
||||
name_of="2"
|
||||
/>
|
||||
<FeatureColorInput
|
||||
action_name="b_fullscreen_color3"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color3}
|
||||
name_of="3"
|
||||
/>
|
||||
<FeatureColorInput
|
||||
action_name="b_fullscreen_color4"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color4}
|
||||
name_of="4"
|
||||
/>
|
||||
<FeatureColorInput
|
||||
action_name="b_fullscreen_alpha"
|
||||
value_of={null}
|
||||
back_color="#FFFFFF"
|
||||
name_of="Alpha"
|
||||
/>
|
||||
</Stack>
|
||||
<Box mt={1}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Enable Coloration">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_colorization_enabled' })
|
||||
}
|
||||
icon={colorization_enabled ? 'toggle-on' : 'toggle-off'}
|
||||
selected={colorization_enabled}
|
||||
>
|
||||
{colorization_enabled ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Preview Belly">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_preview_belly' })
|
||||
}
|
||||
>
|
||||
Preview
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Clear Preview">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_clear_preview' })
|
||||
}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Box>
|
||||
</Section>
|
||||
<Section>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Section
|
||||
title="Affect Vore Sprites"
|
||||
buttons={
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_affects_vore_sprites"
|
||||
editMode={editMode}
|
||||
tooltip="Allows you to toggle if this belly should effect voresprites"
|
||||
active={!!affects_voresprite}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{!!affects_voresprite && (
|
||||
<VoreSpriteAffects
|
||||
editMode={editMode}
|
||||
bellyVisualData={bellyVisualData}
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Section title="Vore FX">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Disable Prey HUD">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_disable_hud' })
|
||||
}
|
||||
icon={disable_hud ? 'toggle-on' : 'toggle-off'}
|
||||
selected={disable_hud}
|
||||
>
|
||||
{disable_hud ? 'Yes' : 'No'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Enable Coloration">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_colorization_enabled"
|
||||
editMode={editMode}
|
||||
active={!!colorization_enabled}
|
||||
tooltip="Switches between the legacy pre-colored icon set and the modern colorable one."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Hide Prey HUD">
|
||||
<VorePanelEditSwitch
|
||||
action="set_attribute"
|
||||
subAction="b_disable_hud"
|
||||
editMode={editMode}
|
||||
active={!!disable_hud}
|
||||
tooltip="Allows you to hide your prey's game UI."
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Preview Belly">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_preview_belly' })
|
||||
}
|
||||
>
|
||||
Preview
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Clear Preview">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_clear_preview' })
|
||||
}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
{!!colorization_enabled && (
|
||||
<>
|
||||
<Stack.Divider />
|
||||
<Stack.Item>
|
||||
<Stack align="center">
|
||||
<VorePanelEditColor
|
||||
editMode={editMode}
|
||||
action="set_attribute"
|
||||
subAction="b_fullscreen_color"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color}
|
||||
name_of="Color 1:"
|
||||
tooltip="Set the Vore FX overlay's first color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
editMode={editMode}
|
||||
action="set_attribute"
|
||||
subAction="b_fullscreen_color2"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color2}
|
||||
name_of="Color 2:"
|
||||
tooltip="Set the Vore FX overlay's second color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
editMode={editMode}
|
||||
action="set_attribute"
|
||||
subAction="b_fullscreen_color3"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color3}
|
||||
name_of="Color 3:"
|
||||
tooltip="Set the Vore FX overlay's third color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
editMode={editMode}
|
||||
action="set_attribute"
|
||||
subAction="b_fullscreen_color4"
|
||||
value_of={null}
|
||||
back_color={belly_fullscreen_color4}
|
||||
name_of="Color 4:"
|
||||
tooltip="Set the Vore FX overlay's fourth color."
|
||||
/>
|
||||
<VorePanelEditColor
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="set_attribute"
|
||||
subAction="b_fullscreen_alpha"
|
||||
value_of={null}
|
||||
back_color="#FFFFFF"
|
||||
alpha={belly_fullscreen_alpha}
|
||||
name_of="Alpha:"
|
||||
tooltip="Set the Vore FX overlay's transparency."
|
||||
/>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
</Section>
|
||||
<Section title="Belly Fullscreens Styles" width="800px">
|
||||
Belly styles:
|
||||
<Button
|
||||
fluid
|
||||
selected={belly_fullscreen === '' || belly_fullscreen === null}
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_fullscreen', val: null })
|
||||
}
|
||||
>
|
||||
Disabled
|
||||
</Button>
|
||||
{Object.keys(possible_fullscreens).map((key, index) => (
|
||||
<span key={index} style={{ width: '256px' }}>
|
||||
<Button
|
||||
width="256px"
|
||||
height="256px"
|
||||
selected={key === belly_fullscreen}
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_fullscreen', val: key })
|
||||
}
|
||||
>
|
||||
<Box
|
||||
className={classes([
|
||||
colorization_enabled ? 'vore240x240' : 'fixedvore240x240',
|
||||
key,
|
||||
])}
|
||||
style={{
|
||||
transform: 'translate(0%, 4%)',
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
</span>
|
||||
))}
|
||||
</Section>
|
||||
</Section>
|
||||
</>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<BellyFullscreenSelection
|
||||
editMode={editMode}
|
||||
belly_fullscreen={belly_fullscreen}
|
||||
colorization_enabled={colorization_enabled}
|
||||
possible_fullscreens={possible_fullscreens}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Dropdown,
|
||||
LabeledList,
|
||||
Section,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
|
||||
import type {
|
||||
abilities,
|
||||
bellyData,
|
||||
DropdownEntry,
|
||||
soulcatcherData,
|
||||
} from './types';
|
||||
import { VoreAbilities } from './VoreAbilities';
|
||||
import { CatchSettings } from './VoreSoulcatcherSettings/CatchSettings';
|
||||
import { GlobalOptions } from './VoreSoulcatcherSettings/GlobalOptions';
|
||||
import { GlobalSettings } from './VoreSoulcatcherSettings/GlobalSettings';
|
||||
import { SoulOptions } from './VoreSoulcatcherSettings/SoulOptions';
|
||||
|
||||
export const VoreSoulcatcher = (props: {
|
||||
soulcatcher: soulcatcherData | null;
|
||||
our_bellies: Required<bellyData[]> & {
|
||||
map(arg0: (belly: bellyData) => DropdownEntry): DropdownEntry[];
|
||||
};
|
||||
abilities: abilities;
|
||||
}) => {
|
||||
const { soulcatcher, our_bellies, abilities } = props;
|
||||
|
||||
const getBellies = our_bellies.map((belly) => {
|
||||
return { ...belly, displayText: belly.name, value: belly.ref };
|
||||
});
|
||||
|
||||
return (
|
||||
<Section scrollable fill>
|
||||
{soulcatcher && (
|
||||
<VoreSoulcatcherSection
|
||||
soulcatcher={soulcatcher}
|
||||
overlayBellies={getBellies}
|
||||
/>
|
||||
)}
|
||||
<VoreAbilities abilities={abilities} />
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const VoreSoulcatcherSection = (props: {
|
||||
soulcatcher: soulcatcherData;
|
||||
overlayBellies: DropdownEntry[];
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { soulcatcher, overlayBellies } = props;
|
||||
|
||||
const {
|
||||
active,
|
||||
name,
|
||||
caught_souls,
|
||||
selected_soul,
|
||||
interior_design,
|
||||
catch_self,
|
||||
catch_prey,
|
||||
catch_drain,
|
||||
catch_ghost,
|
||||
ext_hearing,
|
||||
ext_vision,
|
||||
mind_backups,
|
||||
sr_projecting,
|
||||
see_sr_projecting,
|
||||
selected_sfx,
|
||||
show_vore_sfx,
|
||||
taken_over,
|
||||
} = soulcatcher;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title={'Soulcatcher (' + name + ')'}
|
||||
buttons={
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() => act('soulcatcher_rename')}
|
||||
icon="pen"
|
||||
tooltip="Click here to rename your soulcatcher."
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() => act('soulcatcher_toggle')}
|
||||
icon={active ? 'toggle-on' : 'toggle-off'}
|
||||
tooltip={
|
||||
(active ? 'Disables' : 'Enables') +
|
||||
' the ability to capture souls upon vore death.'
|
||||
}
|
||||
tooltipPosition="top"
|
||||
selected={active}
|
||||
>
|
||||
{active ? 'Soulcatcher On' : 'Soulcatcher Off'}
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
}
|
||||
>
|
||||
{active ? (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Captured Souls">
|
||||
<Stack inline align="center">
|
||||
<Stack.Item>
|
||||
<Dropdown
|
||||
width="200px"
|
||||
selected={selected_soul}
|
||||
options={caught_souls}
|
||||
onSelected={(value) =>
|
||||
act('soulcatcher_select', {
|
||||
selected_soul: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Box>{caught_souls.length}</Box>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
{selected_soul ? <SoulOptions taken_over={taken_over} /> : ''}
|
||||
{caught_souls.length ? <GlobalOptions taken_over={taken_over} /> : ''}
|
||||
<CatchSettings
|
||||
catch_self={catch_self}
|
||||
catch_prey={catch_prey}
|
||||
catch_drain={catch_drain}
|
||||
catch_ghost={catch_ghost}
|
||||
/>
|
||||
<GlobalSettings
|
||||
ext_hearing={ext_hearing}
|
||||
ext_vision={ext_vision}
|
||||
mind_backups={mind_backups}
|
||||
sr_projecting={sr_projecting}
|
||||
see_sr_projecting={see_sr_projecting}
|
||||
show_vore_sfx={show_vore_sfx}
|
||||
/>
|
||||
<LabeledList.Item
|
||||
label="Interior Design"
|
||||
buttons={
|
||||
<Button
|
||||
icon="wand-magic-sparkles"
|
||||
tooltip="Customize your soulcatcher flavour text."
|
||||
tooltipPosition="left"
|
||||
onClick={() => act('soulcatcher_interior_design')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{interior_design}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Interior SFX">
|
||||
<Dropdown
|
||||
width="200px"
|
||||
selected={selected_sfx}
|
||||
options={overlayBellies}
|
||||
onSelected={(value) =>
|
||||
act('soulcatcher_sfx', {
|
||||
selected_belly: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Custom Messages">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button onClick={() => act('soulcatcher_capture_message')}>
|
||||
Capture Message
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button onClick={() => act('soulcatcher_transit_message')}>
|
||||
Transit Message
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button onClick={() => act('soulcatcher_release_message')}>
|
||||
Release Message
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button onClick={() => act('soulcatcher_delete_message')}>
|
||||
Delete Message
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
) : (
|
||||
'Soulcatching disabled.'
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export const CatchSettings = (props: {
|
||||
editMode: boolean;
|
||||
catch_self: BooleanLike;
|
||||
catch_prey: BooleanLike;
|
||||
catch_drain: BooleanLike;
|
||||
@@ -10,13 +11,14 @@ export const CatchSettings = (props: {
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
|
||||
const { catch_self, catch_prey, catch_drain, catch_ghost } = props;
|
||||
const { editMode, catch_self, catch_prey, catch_drain, catch_ghost } = props;
|
||||
|
||||
return (
|
||||
<LabeledList.Item label="Catch Settings">
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="circle-user"
|
||||
tooltip={
|
||||
(catch_self ? 'Allow' : 'Disallow') +
|
||||
@@ -31,6 +33,7 @@ export const CatchSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="person"
|
||||
tooltip={
|
||||
(catch_prey ? 'Allow' : 'Disallow') +
|
||||
@@ -45,6 +48,7 @@ export const CatchSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="person-falling-burst"
|
||||
tooltip={
|
||||
(catch_drain ? 'Allow' : 'Disallow') +
|
||||
@@ -59,6 +63,7 @@ export const CatchSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="ghost"
|
||||
tooltip={
|
||||
(catch_ghost ? 'Allow' : 'Disallow') +
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Button, LabeledList, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export const GlobalSettings = (props: {
|
||||
editMode: boolean;
|
||||
ext_hearing: BooleanLike;
|
||||
ext_vision: BooleanLike;
|
||||
mind_backups: BooleanLike;
|
||||
@@ -13,6 +14,7 @@ export const GlobalSettings = (props: {
|
||||
const { act } = useBackend();
|
||||
|
||||
const {
|
||||
editMode,
|
||||
ext_hearing,
|
||||
ext_vision,
|
||||
mind_backups,
|
||||
@@ -26,6 +28,7 @@ export const GlobalSettings = (props: {
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon={ext_hearing ? 'ear-listen' : 'ear-deaf'}
|
||||
tooltip={
|
||||
(ext_hearing ? 'Allow' : 'Disallow') +
|
||||
@@ -40,6 +43,7 @@ export const GlobalSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon={ext_vision ? 'eye' : 'eye-slash'}
|
||||
tooltip={
|
||||
(ext_vision ? 'Allow' : 'Disallow') +
|
||||
@@ -54,6 +58,7 @@ export const GlobalSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="database"
|
||||
tooltip={
|
||||
(mind_backups ? 'Allow' : 'Disallow') +
|
||||
@@ -68,6 +73,7 @@ export const GlobalSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="street-view"
|
||||
tooltip={
|
||||
(sr_projecting ? 'Allow' : 'Disallow') +
|
||||
@@ -82,6 +88,7 @@ export const GlobalSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon="eye-low-vision"
|
||||
tooltip={
|
||||
(see_sr_projecting ? 'Enable' : 'Disable') +
|
||||
@@ -98,6 +105,7 @@ export const GlobalSettings = (props: {
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
disabled={!editMode}
|
||||
icon={show_vore_sfx ? 'circle-play' : 'circle-pause'}
|
||||
tooltip={
|
||||
(show_vore_sfx ? 'Show' : 'Hide') +
|
||||
|
||||
@@ -10,7 +10,7 @@ export const SoulOptions = (props: { taken_over: BooleanLike }) => {
|
||||
return (
|
||||
<LabeledList.Item label="Soul Options">
|
||||
<Stack>
|
||||
{!taken_over ? (
|
||||
{!taken_over && (
|
||||
<>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
@@ -46,8 +46,6 @@ export const SoulOptions = (props: { taken_over: BooleanLike }) => {
|
||||
</Button.Confirm>
|
||||
</Stack.Item>
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<Stack.Item>
|
||||
<Button
|
||||
|
||||
+145
-59
@@ -1,70 +1,156 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Button, Section, Stack } from 'tgui-core/components';
|
||||
import { LabeledList, NoticeBox, Section, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
|
||||
import type { localPrefs, selectedData } from '../types';
|
||||
import { VoreUserPreferenceItem } from '../VoreUserPreferenceItem';
|
||||
import { aestehticTabsToIcons } from '../constants';
|
||||
import { fixCorruptedData } from '../functions';
|
||||
import type { aestMessageData, bellyData } from '../types';
|
||||
import { VorePanelEditToggle } from '../VorePanelElements/VorePanelCommonElements';
|
||||
import { VorePanelEditTextTabs } from '../VorePanelElements/VorePaneldEditTextTabs';
|
||||
import { VorePanelEditColor } from '../VorePanelElements/VorePanelEditColor';
|
||||
import { VorePanelEditDropdown } from '../VorePanelElements/VorePanelEditDropdown';
|
||||
import { VorePanelEditSwitch } from '../VorePanelElements/VorePanelEditSwitch';
|
||||
|
||||
export const VoreUserPreferencesAesthetic = (props: {
|
||||
editMode: boolean;
|
||||
toggleEditMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
active_belly: string | null;
|
||||
our_bellies: bellyData[];
|
||||
belly_rub_target: string | null;
|
||||
selected: selectedData | null;
|
||||
preferences: localPrefs;
|
||||
vore_sprite_color: Record<string, string>;
|
||||
vore_sprite_multiply: Record<string, BooleanLike>;
|
||||
vore_icon_options: string[];
|
||||
aestethicMessages: aestMessageData;
|
||||
}) => {
|
||||
const { act } = useBackend();
|
||||
const { belly_rub_target, selected, preferences } = props;
|
||||
const {
|
||||
editMode,
|
||||
toggleEditMode,
|
||||
active_belly,
|
||||
belly_rub_target,
|
||||
our_bellies,
|
||||
vore_sprite_color,
|
||||
vore_sprite_multiply,
|
||||
vore_icon_options,
|
||||
aestethicMessages,
|
||||
} = props;
|
||||
|
||||
const sanitizeCorruption = fixCorruptedData(aestethicMessages.active_message);
|
||||
|
||||
const getBellies = our_bellies.map((belly) => {
|
||||
return belly.name;
|
||||
});
|
||||
|
||||
const locationNames = [...getBellies, 'Current Selected'];
|
||||
|
||||
const capitalizedName = active_belly && capitalize(active_belly);
|
||||
|
||||
return (
|
||||
<Section title="Aesthetic Preferences">
|
||||
<Stack wrap="wrap" justify="center">
|
||||
<Stack.Item basis="49%" grow>
|
||||
<Button fluid icon="grin-tongue" onClick={() => act('setflavor')}>
|
||||
Set Taste
|
||||
</Button>
|
||||
<Section
|
||||
fill
|
||||
title="Aesthetic Preferences"
|
||||
scrollable
|
||||
buttons={
|
||||
<VorePanelEditToggle
|
||||
editMode={editMode}
|
||||
toggleEditMode={toggleEditMode}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Stack>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
{vore_icon_options.map((entry) => (
|
||||
<LabeledList.Item key={entry} label={capitalize(entry)}>
|
||||
<Stack align="center">
|
||||
<VorePanelEditColor
|
||||
name_of="sprite color"
|
||||
removePlaceholder
|
||||
editMode={editMode}
|
||||
action="set_vs_color"
|
||||
subAction={entry}
|
||||
back_color={vore_sprite_color[entry]}
|
||||
tooltip={
|
||||
"Modify the sprite color of your '" +
|
||||
entry +
|
||||
"' sprite."
|
||||
}
|
||||
value_of={undefined}
|
||||
/>
|
||||
<Stack.Item>
|
||||
<VorePanelEditSwitch
|
||||
hideIcon
|
||||
editMode={editMode}
|
||||
action="toggle_vs_multiply"
|
||||
subAction={entry}
|
||||
active={!!vore_sprite_multiply[entry]}
|
||||
tooltip={
|
||||
"Switch between color multiply and add mode for your '" +
|
||||
entry +
|
||||
"' sprite."
|
||||
}
|
||||
color={!editMode ? 'white' : undefined}
|
||||
content={
|
||||
vore_sprite_multiply[entry] ? 'Multiply' : 'Add'
|
||||
}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Belly Rub Target">
|
||||
<VorePanelEditDropdown
|
||||
action={'set_belly_rub'}
|
||||
icon="crosshairs"
|
||||
editMode={editMode}
|
||||
options={locationNames}
|
||||
entry={
|
||||
belly_rub_target
|
||||
? belly_rub_target
|
||||
: 'Current Selected (' + capitalizedName + ')'
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%">
|
||||
<Button fluid icon="wind" onClick={() => act('setsmell')}>
|
||||
Set Smell
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'en' })
|
||||
}
|
||||
icon="flask"
|
||||
fluid
|
||||
>
|
||||
Set Nutrition Examine Message
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%">
|
||||
<Button
|
||||
onClick={() =>
|
||||
act('set_attribute', { attribute: 'b_msgs', msgtype: 'ew' })
|
||||
}
|
||||
icon="weight-hanging"
|
||||
fluid
|
||||
>
|
||||
Set Weight Examine Message
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<VoreUserPreferenceItem spec={preferences.examine_nutrition} />
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%">
|
||||
<VoreUserPreferenceItem spec={preferences.examine_weight} />
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%" grow>
|
||||
<Button fluid onClick={() => act('set_vs_color')} icon="palette">
|
||||
Vore Sprite Color
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item basis="49%">
|
||||
<Button fluid onClick={() => act('set_belly_rub')} icon="crosshairs">
|
||||
{'Belly Rub Target: ' +
|
||||
(belly_rub_target
|
||||
? belly_rub_target
|
||||
: 'Current Active (' + (selected && selected.belly_name) + ')')}
|
||||
</Button>
|
||||
<Stack.Divider />
|
||||
<Stack.Item grow>
|
||||
<Section fill>
|
||||
{!!sanitizeCorruption.corrupted && (
|
||||
<Stack.Item>
|
||||
<NoticeBox danger>
|
||||
Your {'>' + aestethicMessages.aest_subtab + '<'} messages are
|
||||
corrupted, please edit and save them!
|
||||
</NoticeBox>
|
||||
</Stack.Item>
|
||||
)}
|
||||
<VorePanelEditTextTabs
|
||||
exactLength
|
||||
editMode={editMode}
|
||||
messsageOptions={aestethicMessages.possible_messages}
|
||||
activeTab={aestethicMessages.aest_subtab}
|
||||
tabAction="change_aset_message_option"
|
||||
tabsToIcons={aestehticTabsToIcons}
|
||||
tooltip={aestethicMessages.tooltip}
|
||||
maxLength={aestethicMessages.max_length}
|
||||
activeMessage={sanitizeCorruption.data}
|
||||
action={aestethicMessages.set_action}
|
||||
listAction="b_msgs"
|
||||
disableLegacyInput={!Array.isArray(sanitizeCorruption)}
|
||||
subAction={aestethicMessages.sub_action}
|
||||
button_action={aestethicMessages.button_action}
|
||||
button_label={aestethicMessages.button_label}
|
||||
button_data={!!aestethicMessages.button_data}
|
||||
button_tooltip={aestethicMessages.button_tooltip}
|
||||
/>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import type { BooleanLike } from 'tgui-core/react';
|
||||
import { capitalize } from 'tgui-core/string';
|
||||
|
||||
import type { localPrefs } from '../types';
|
||||
import { VoreUserPreferenceItem } from '../VoreUserPreferenceItem';
|
||||
import { VoreUserPreferenceItem } from '../VorePanelElements/VoreUserPreferenceItem';
|
||||
|
||||
export const VoreUserPreferencesDevouring = (props: {
|
||||
devourable: BooleanLike;
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { Button, Section, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { localPrefs } from '../types';
|
||||
import { VoreUserPreferenceItem } from '../VoreUserPreferenceItem';
|
||||
import { VoreUserPreferenceItem } from '../VorePanelElements/VoreUserPreferenceItem';
|
||||
|
||||
export const VoreUserPreferencesMechanical = (props: {
|
||||
show_pictures: BooleanLike;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { Section, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { localPrefs } from '../types';
|
||||
import { VoreUserPreferenceItem } from '../VoreUserPreferenceItem';
|
||||
import { VoreUserPreferenceItem } from '../VorePanelElements/VoreUserPreferenceItem';
|
||||
|
||||
export const VoreUserPreferencesSoulcatcher = (props: {
|
||||
soulcatcher_allow_capture: BooleanLike;
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { Button, NumberInput, Section, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { localPrefs } from '../types';
|
||||
import { VoreUserPreferenceItem } from '../VoreUserPreferenceItem';
|
||||
import { VoreUserPreferenceItem } from '../VorePanelElements/VoreUserPreferenceItem';
|
||||
|
||||
export const VoreUserPreferencesSpawn = (props: {
|
||||
latejoin_vore: BooleanLike;
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { Section, Stack } from 'tgui-core/components';
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
import type { localPrefs } from '../types';
|
||||
import { VoreUserPreferenceItem } from '../VoreUserPreferenceItem';
|
||||
import { VoreUserPreferenceItem } from '../VorePanelElements/VoreUserPreferenceItem';
|
||||
|
||||
export const VoreUserPreferencesSpontaneous = (props: {
|
||||
can_be_drop_prey: BooleanLike;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
export const stats: (string | undefined)[] = [undefined, 'average', 'bad'];
|
||||
|
||||
export const vorespawnAbsorbedText: string[] = ['No', 'Yes', 'Prey Choice'];
|
||||
|
||||
export const vorespawnAbsorbedColor: (string | undefined)[] = [
|
||||
undefined,
|
||||
'green',
|
||||
'orange',
|
||||
];
|
||||
|
||||
export const selectiveBellyOptions = ['Digest', 'Absorb'];
|
||||
|
||||
export const digestModeToColor = {
|
||||
Default: undefined,
|
||||
Hold: undefined,
|
||||
@@ -19,6 +23,8 @@ export const digestModeToColor = {
|
||||
'Size Steal': 'teal',
|
||||
Heal: 'green',
|
||||
'Encase In Egg': 'blue',
|
||||
'Digest (Food Only)': 'red',
|
||||
'Digest (Dispersed Damage)': 'red',
|
||||
};
|
||||
|
||||
export const reagentToColor = {
|
||||
@@ -57,3 +63,86 @@ export const SYNTAX_COLOR = {
|
||||
'%pred': 'bad',
|
||||
'%prey': 'good',
|
||||
};
|
||||
|
||||
export const tabToNames = [
|
||||
'Controls',
|
||||
'Descriptions',
|
||||
'Options',
|
||||
'Sounds',
|
||||
'Visuals',
|
||||
'Interactions',
|
||||
'Contents',
|
||||
'Liquid Options',
|
||||
];
|
||||
|
||||
export const modeToTooltip = {
|
||||
Numbing: 'Prey will recieve no pain from vorgan damage.',
|
||||
Stripping: 'Strips prey of all equipped items.',
|
||||
'Leave Remains': 'Prey might leave remains like bones.',
|
||||
Muffles: 'Causes all prey messages to become subtles.',
|
||||
'Affect Worn Items': 'Allows vorgan to coat and digest equipped items.',
|
||||
'Jams Sensors': 'Blocks medical sensors, but not GPS.',
|
||||
'Complete Absorb': 'Limits conversation to direct pred / prey.',
|
||||
'Spare Prosthetics': 'Applies no damage to synthetic limbs. ',
|
||||
'Slow Body Digestion': 'Continues to digest a body after the prey has died.',
|
||||
'Muffle Items': ' Muffles noise from items inside the vorgan.',
|
||||
'TURBO MODE': 'Heavily increases tick speed of the vorgan (6x).',
|
||||
};
|
||||
|
||||
export const spriteToTooltip = {
|
||||
'Normal Belly Sprite':
|
||||
"This belly will effect the mob's belly sprite if available.",
|
||||
'Undergarment addition':
|
||||
"This belly will effect the mob's undergarment sprite if available.",
|
||||
};
|
||||
|
||||
export const liquidToTooltip = {
|
||||
'Produce Liquids': 'Enables automatic belly liquid porduction.',
|
||||
'Digestion Liquids':
|
||||
'Enables belly liquid production while prey is being diegested.',
|
||||
'Absorption Liquids':
|
||||
'Enables belly liquid production while prey is being absorbed.',
|
||||
'Draining Liquids':
|
||||
'Enables belly liquid production while prey is being drained.',
|
||||
};
|
||||
|
||||
export const messageTabLabel = [
|
||||
'Description',
|
||||
'Examine',
|
||||
'Trash Eater',
|
||||
'Struggle',
|
||||
'Escape',
|
||||
'Escape (Absorbed)',
|
||||
'Transfer',
|
||||
'Interaction Chance',
|
||||
'Bellymode',
|
||||
'Idle',
|
||||
'Liquid Fullness',
|
||||
];
|
||||
|
||||
export const eatingMessagePrivacy = {
|
||||
default: undefined,
|
||||
subtle: 'green',
|
||||
loud: 'red',
|
||||
};
|
||||
|
||||
export const robotBellyOptions = ['Sleeper', 'Vorebelly', 'Both'];
|
||||
|
||||
export const noSelectionName = { displayText: 'None - Remove', value: '' };
|
||||
|
||||
export const nutriTimeToText = {
|
||||
0: '10 minutes',
|
||||
2: '30 minutes',
|
||||
5: '1 hour',
|
||||
17: '3 hours',
|
||||
35: '6 hours',
|
||||
71: '12 hours',
|
||||
143: '24 hours',
|
||||
};
|
||||
|
||||
export const aestehticTabsToIcons = {
|
||||
'Set Taste': 'grin-tongue',
|
||||
'Set Smell': 'wind',
|
||||
'Set Nutrition Examine': 'flask',
|
||||
'Set Weight Examine': 'weight-hanging',
|
||||
};
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
export function abilitiy_usable(nutri: number, cost: number): boolean {
|
||||
return nutri >= cost;
|
||||
}
|
||||
|
||||
export function sanitize_color(color?: string | null, mirrorBlack?: boolean) {
|
||||
if (!color) {
|
||||
return undefined;
|
||||
}
|
||||
if (mirrorBlack && color === 'black') {
|
||||
return 'white';
|
||||
}
|
||||
const ctx = document.createElement('canvas').getContext('2d');
|
||||
if (!ctx) {
|
||||
return undefined;
|
||||
}
|
||||
ctx.fillStyle = color;
|
||||
return ctx.fillStyle;
|
||||
}
|
||||
|
||||
export function calcLineHeight(lim: number, height: number) {
|
||||
return (Math.ceil(lim / 25 / height + 0.5) * height).toFixed() + 'px';
|
||||
}
|
||||
|
||||
export function fixCorruptedData(
|
||||
toSanitize:
|
||||
| string
|
||||
| string[]
|
||||
| null
|
||||
| Record<string | number, string | number>,
|
||||
) {
|
||||
if (toSanitize === null) {
|
||||
return { data: '' };
|
||||
}
|
||||
if (typeof toSanitize === 'string') {
|
||||
return { data: toSanitize };
|
||||
}
|
||||
if (Array.isArray(toSanitize)) {
|
||||
return { data: toSanitize };
|
||||
}
|
||||
const clearedData = Object.entries(toSanitize).map((entry) => {
|
||||
if (typeof entry[0] === 'string') {
|
||||
return entry[0];
|
||||
} else if (typeof entry[1] === 'string') {
|
||||
return entry[1];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
return { corrupted: true, data: clearedData || [] };
|
||||
}
|
||||
|
||||
// Those can't be used currently, due to byond limitations
|
||||
export async function copy_to_clipboard(value: string | string[]) {
|
||||
let data = value;
|
||||
if (Array.isArray(data)) {
|
||||
data = data.join('\n\n');
|
||||
}
|
||||
await navigator.clipboard.writeText(data);
|
||||
}
|
||||
|
||||
export async function paste_from_clipboard(asArray = false) {
|
||||
const ourText = await navigator.clipboard.readText();
|
||||
if (asArray) {
|
||||
return ourText.split('\n\n');
|
||||
}
|
||||
return ourText;
|
||||
}
|
||||
@@ -4,10 +4,11 @@ import { Window } from 'tgui/layouts';
|
||||
import { Button, Icon, NoticeBox, Stack, Tabs } from 'tgui-core/components';
|
||||
|
||||
import type { Data } from './types';
|
||||
import { VoreBellySelectionAndCustomization } from './VoreBellySelectionAndCustomization';
|
||||
import { VoreInsidePanel } from './VoreInsidePanel';
|
||||
import { VoreSoulcatcher } from './VoreSoulcatcher';
|
||||
import { VoreUserPreferences } from './VoreUserPreferences';
|
||||
import { VoreBellySelectionAndCustomization } from './VorePanelMainTabs/VoreBellySelectionAndCustomization';
|
||||
import { VoreInsidePanel } from './VorePanelMainTabs/VoreInsidePanel';
|
||||
import { VoreSoulcatcher } from './VorePanelMainTabs/VoreSoulcatcher';
|
||||
import { VoreUserGeneral } from './VorePanelMainTabs/VoreUserGeneral';
|
||||
import { VoreUserPreferences } from './VorePanelMainTabs/VoreUserPreferences';
|
||||
|
||||
/**
|
||||
* There are three main sections to this UI.
|
||||
@@ -153,6 +154,8 @@ export const VorePanel = () => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
|
||||
const {
|
||||
active_tab,
|
||||
active_vore_tab,
|
||||
inside,
|
||||
our_bellies,
|
||||
selected,
|
||||
@@ -164,40 +167,53 @@ export const VorePanel = () => {
|
||||
host_mobtype,
|
||||
unsaved_changes,
|
||||
vore_words,
|
||||
general_pref_data,
|
||||
} = data;
|
||||
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
|
||||
const tabs: React.JSX.Element[] = [];
|
||||
const tabs: (React.JSX.Element | null | undefined)[] = [];
|
||||
|
||||
tabs[0] = (
|
||||
tabs[0] = our_bellies && selected && host_mobtype && (
|
||||
<VoreBellySelectionAndCustomization
|
||||
activeVoreTab={active_vore_tab}
|
||||
our_bellies={our_bellies}
|
||||
selected={selected}
|
||||
show_pictures={show_pictures}
|
||||
host_mobtype={host_mobtype}
|
||||
icon_overflow={icon_overflow}
|
||||
vore_words={vore_words}
|
||||
toggleEditMode={setEditMode}
|
||||
editMode={editMode}
|
||||
/>
|
||||
);
|
||||
tabs[1] = (
|
||||
tabs[1] = our_bellies && soulcatcher && abilities && (
|
||||
<VoreSoulcatcher
|
||||
our_bellies={our_bellies}
|
||||
soulcatcher={soulcatcher}
|
||||
abilities={abilities}
|
||||
toggleEditMode={setEditMode}
|
||||
editMode={editMode}
|
||||
/>
|
||||
);
|
||||
tabs[2] = (
|
||||
tabs[2] = general_pref_data && our_bellies && (
|
||||
<VoreUserGeneral
|
||||
general_pref_data={general_pref_data}
|
||||
our_bellies={our_bellies}
|
||||
editMode={editMode}
|
||||
toggleEditMode={setEditMode}
|
||||
/>
|
||||
);
|
||||
tabs[3] = prefs && (
|
||||
<VoreUserPreferences
|
||||
prefs={prefs}
|
||||
selected={selected}
|
||||
show_pictures={show_pictures}
|
||||
icon_overflow={icon_overflow}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Window width={1000} height={660} theme="abstract">
|
||||
<Window width={1030} height={760} theme="abstract">
|
||||
<Window.Content>
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
@@ -236,29 +252,36 @@ export const VorePanel = () => {
|
||||
<Stack.Item>
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 0}
|
||||
onClick={() => setTabIndex(0)}
|
||||
selected={active_tab === 0}
|
||||
onClick={() => act('change_tab', { tab: 0 })}
|
||||
>
|
||||
Bellies
|
||||
<Icon name="list" ml={0.5} />
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 1}
|
||||
onClick={() => setTabIndex(1)}
|
||||
selected={active_tab === 1}
|
||||
onClick={() => act('change_tab', { tab: 1 })}
|
||||
>
|
||||
Soulcatcher
|
||||
<Icon name="ghost" ml={0.5} />
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={tabIndex === 2}
|
||||
onClick={() => setTabIndex(2)}
|
||||
selected={active_tab === 2}
|
||||
onClick={() => act('change_tab', { tab: 2 })}
|
||||
>
|
||||
General
|
||||
<Icon name="user-circle" ml={0.5} />
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={active_tab === 3}
|
||||
onClick={() => act('change_tab', { tab: 3 })}
|
||||
>
|
||||
Preferences
|
||||
<Icon name="user-cog" ml={0.5} />
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>{tabs[tabIndex] || 'Error'}</Stack.Item>
|
||||
<Stack.Item grow>{tabs[active_tab] || 'Error'}</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
import type { BooleanLike } from 'tgui-core/react';
|
||||
|
||||
export type Data = {
|
||||
vore_words: Record<string, string[]>;
|
||||
unsaved_changes: BooleanLike;
|
||||
inside: insideData;
|
||||
show_pictures: BooleanLike;
|
||||
icon_overflow: BooleanLike;
|
||||
inside: insideData;
|
||||
host_mobtype: hostMob;
|
||||
our_bellies: bellyData[];
|
||||
selected: selectedData | null;
|
||||
prefs: prefData;
|
||||
soulcatcher: soulcatcherData | null;
|
||||
abilities: abilities;
|
||||
vore_words: Record<string, string[]>;
|
||||
active_tab: number;
|
||||
host_mobtype: hostMob | null;
|
||||
our_bellies?: bellyData[] | null;
|
||||
selected?: selectedData | null;
|
||||
prefs?: prefData | null;
|
||||
soulcatcher?: soulcatcherData | null;
|
||||
abilities?: abilities | null;
|
||||
active_vore_tab?: number;
|
||||
general_pref_data?: generalPrefData | null;
|
||||
};
|
||||
|
||||
export type abilities = {
|
||||
nutrition: number;
|
||||
size_change: abilitySizeChange;
|
||||
};
|
||||
|
||||
export type abilitySizeChange = {
|
||||
current_size: number;
|
||||
minimum_size: number;
|
||||
maximum_size: number;
|
||||
@@ -40,94 +47,115 @@ export type insideData = {
|
||||
contents?: contentData[];
|
||||
};
|
||||
|
||||
export type contentData = {
|
||||
name: string;
|
||||
absorbed: BooleanLike;
|
||||
stat: number;
|
||||
ref: string;
|
||||
outside: BooleanLike;
|
||||
icon: string;
|
||||
};
|
||||
|
||||
export type bellyData = {
|
||||
selected: BooleanLike;
|
||||
name: string;
|
||||
ref: string;
|
||||
digest_mode: string;
|
||||
contents: number;
|
||||
prevent_saving: BooleanLike;
|
||||
selected?: BooleanLike;
|
||||
digest_mode?: string;
|
||||
contents?: number;
|
||||
prevent_saving?: BooleanLike;
|
||||
};
|
||||
|
||||
export type selectedData = {
|
||||
belly_name: string;
|
||||
message_mode: BooleanLike;
|
||||
is_wet: BooleanLike;
|
||||
wet_loop: BooleanLike;
|
||||
export type bellyModeData = {
|
||||
mode: string;
|
||||
item_mode: string;
|
||||
addons: checkBoxEntry[];
|
||||
name_length: number;
|
||||
name_min: number;
|
||||
mode_options: string[];
|
||||
item_mode_options: string[];
|
||||
};
|
||||
|
||||
export type bellyDescriptionData = {
|
||||
verb: string;
|
||||
release_verb: string;
|
||||
desc: string;
|
||||
absorbed_desc: string;
|
||||
fancy: BooleanLike;
|
||||
sound: string;
|
||||
release_sound: string;
|
||||
message_mode: BooleanLike;
|
||||
displayed_options: number[];
|
||||
message_option: number;
|
||||
message_subtab: string;
|
||||
selected_message: string;
|
||||
emote_time: number;
|
||||
emote_active: BooleanLike;
|
||||
show_liq_fullness: BooleanLike;
|
||||
entrance_logs: BooleanLike;
|
||||
item_digest_logs: BooleanLike;
|
||||
name_length: number;
|
||||
name_min: number;
|
||||
displayed_message_types: {
|
||||
subtypes?: string[];
|
||||
possible_messages?: string[] | null;
|
||||
max_length: number;
|
||||
set_action: string;
|
||||
tooltip: string;
|
||||
active_message: string | string[] | null;
|
||||
button_action?: string;
|
||||
button_data?: BooleanLike;
|
||||
button_label?: string;
|
||||
button_tooltip?: string;
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type bellyOptionData = {
|
||||
can_taste: BooleanLike;
|
||||
is_feedable: BooleanLike;
|
||||
egg_type: string;
|
||||
egg_name: string;
|
||||
egg_size: number;
|
||||
recycling: BooleanLike;
|
||||
storing_nutrition: BooleanLike;
|
||||
entrance_logs: BooleanLike;
|
||||
nutrition_percent: number;
|
||||
digest_brute: number;
|
||||
digest_burn: number;
|
||||
digest_oxy: number;
|
||||
digest_tox: number;
|
||||
digest_clone: number;
|
||||
digest_max: number;
|
||||
digest_free: number;
|
||||
bulge_size: number;
|
||||
save_digest_mode: BooleanLike;
|
||||
display_absorbed_examine: BooleanLike;
|
||||
shrink_grow_size: number;
|
||||
emote_time: number;
|
||||
emote_active: BooleanLike;
|
||||
contaminates: BooleanLike;
|
||||
contaminate_flavor: string | null;
|
||||
contaminate_color: string | null;
|
||||
contaminate_options: Record<string, string>[] | null;
|
||||
contaminate_colors: string[] | null;
|
||||
egg_type: string;
|
||||
egg_types: string[];
|
||||
egg_name: string;
|
||||
egg_size: number;
|
||||
recycling: BooleanLike;
|
||||
storing_nutrition: BooleanLike;
|
||||
selective_preference: string;
|
||||
nutrition_ex: BooleanLike;
|
||||
weight_ex: BooleanLike;
|
||||
belly_fullscreen: string;
|
||||
save_digest_mode: BooleanLike;
|
||||
eating_privacy_local: string;
|
||||
silicon_belly_overlay_preference: string;
|
||||
belly_mob_mult: number;
|
||||
belly_item_mult: number;
|
||||
belly_overall_mult: number;
|
||||
vorespawn_blacklist: BooleanLike;
|
||||
vorespawn_whitelist: string[];
|
||||
vorespawn_absorbed: number;
|
||||
private_struggle: BooleanLike;
|
||||
drainmode_options: string[];
|
||||
drainmode: string;
|
||||
mob_belly_controls: siliconeBellyControls;
|
||||
};
|
||||
|
||||
export type bellySoundData = {
|
||||
is_wet: BooleanLike;
|
||||
wet_loop: BooleanLike;
|
||||
fancy: BooleanLike;
|
||||
sound: string;
|
||||
release_sound: string;
|
||||
sound_volume: number;
|
||||
noise_freq: number;
|
||||
min_voice_freq: number;
|
||||
max_voice_freq: number;
|
||||
vore_sound_list: Record<string, string>;
|
||||
release_sound_list: Record<string, string>;
|
||||
};
|
||||
|
||||
export type bellyVisualData = {
|
||||
belly_fullscreen: string;
|
||||
colorization_enabled: BooleanLike;
|
||||
belly_fullscreen_color: string;
|
||||
belly_fullscreen_color2: string;
|
||||
belly_fullscreen_color3: string;
|
||||
belly_fullscreen_color4: string;
|
||||
belly_fullscreen_alpha: number;
|
||||
colorization_enabled: BooleanLike;
|
||||
custom_reagentcolor: string;
|
||||
custom_reagentalpha: number;
|
||||
liquid_overlay: BooleanLike;
|
||||
max_liquid_level: number;
|
||||
reagent_touches: BooleanLike;
|
||||
mush_overlay: BooleanLike;
|
||||
mush_color: string;
|
||||
mush_alpha: number;
|
||||
max_mush: number;
|
||||
min_mush: number;
|
||||
item_mush_val: number;
|
||||
metabolism_overlay: BooleanLike;
|
||||
metabolism_mush_ratio: number;
|
||||
max_ingested: number;
|
||||
custom_ingested_color: string;
|
||||
custom_ingested_alpha: number;
|
||||
vorespawn_blacklist: BooleanLike;
|
||||
vorespawn_whitelist: string[];
|
||||
vorespawn_absorbed: number;
|
||||
sound_volume: number;
|
||||
possible_fullscreens: string[];
|
||||
disable_hud: BooleanLike;
|
||||
vore_sprite_flags: checkBoxEntry[];
|
||||
affects_voresprite: BooleanLike;
|
||||
absorbed_voresprite: BooleanLike;
|
||||
absorbed_multiplier: number;
|
||||
@@ -139,34 +167,55 @@ export type selectedData = {
|
||||
resist_animation: BooleanLike;
|
||||
voresprite_size_factor: number;
|
||||
belly_sprite_to_affect: string;
|
||||
belly_sprite_options: string[] | null;
|
||||
undergarment_chosen: string;
|
||||
undergarment_if_none: string;
|
||||
undergarment_options: string[];
|
||||
undergarment_options_if_none: string[];
|
||||
undergarment_color: string;
|
||||
belly_sprite_option_shown: BooleanLike;
|
||||
tail_option_shown: BooleanLike;
|
||||
tail_to_change_to: BooleanLike | string;
|
||||
tail_colouration: BooleanLike;
|
||||
tail_extra_overlay: BooleanLike;
|
||||
tail_extra_overlay2: BooleanLike;
|
||||
noise_freq: number;
|
||||
item_digest_logs: BooleanLike;
|
||||
private_struggle: BooleanLike;
|
||||
addons: string[];
|
||||
vore_sprite_flags: string[];
|
||||
contaminates: BooleanLike;
|
||||
contaminate_flavor: string | null;
|
||||
contaminate_color: string | null;
|
||||
tail_sprite_options: string[];
|
||||
};
|
||||
|
||||
export type bellyInteractionData = {
|
||||
escapable: BooleanLike;
|
||||
interacts: interactData;
|
||||
autotransfer_enabled: BooleanLike;
|
||||
autotransfer: autotransferData;
|
||||
disable_hud: BooleanLike;
|
||||
possible_fullscreens: string[];
|
||||
contents: contentData[];
|
||||
};
|
||||
|
||||
export type contentData = {
|
||||
name: string;
|
||||
absorbed: BooleanLike;
|
||||
stat: number;
|
||||
ref: string;
|
||||
outside: BooleanLike;
|
||||
icon: string;
|
||||
};
|
||||
|
||||
export type bellyLiquidData = {
|
||||
show_liq: BooleanLike;
|
||||
liq_interacts: liqInteractData;
|
||||
show_liq_fullness: BooleanLike;
|
||||
liq_messages: liqMessageData;
|
||||
};
|
||||
|
||||
export type siliconeBellyControls = {
|
||||
silicon_belly_overlay_preference: string;
|
||||
belly_sprite_option_shown: BooleanLike;
|
||||
belly_sprite_to_affect: string;
|
||||
};
|
||||
|
||||
export type selectedData = {
|
||||
belly_name: string;
|
||||
belly_mode_data?: bellyModeData;
|
||||
belly_description_data?: bellyDescriptionData;
|
||||
belly_option_data?: bellyOptionData;
|
||||
belly_sound_data?: bellySoundData;
|
||||
belly_visual_data?: bellyVisualData;
|
||||
belly_interaction_data?: bellyInteractionData;
|
||||
contents?: contentData[] | null;
|
||||
content_length: number;
|
||||
belly_liquid_data?: bellyLiquidData;
|
||||
};
|
||||
|
||||
export type interactData = {
|
||||
@@ -183,36 +232,37 @@ export type interactData = {
|
||||
};
|
||||
|
||||
export type autotransferData = {
|
||||
autotransferchance: number;
|
||||
autotransferwait: number;
|
||||
autotransferlocation: string;
|
||||
autotransferextralocation: string[];
|
||||
autotransferchance_secondary: number;
|
||||
autotransferlocation_secondary: string;
|
||||
autotransferextralocation_secondary: string[];
|
||||
autotransfer_min_amount: number;
|
||||
autotransfer_max_amount: number;
|
||||
autotransfer_whitelist: string[];
|
||||
autotransfer_blacklist: string[];
|
||||
autotransfer_whitelist_items: string[];
|
||||
autotransfer_blacklist_items: string[];
|
||||
autotransfer_secondary_whitelist: string[];
|
||||
autotransfer_secondary_blacklist: string[];
|
||||
autotransfer_secondary_whitelist_items: string[];
|
||||
autotransfer_secondary_blacklist_items: string[];
|
||||
primary_transfer: autoTransferOption;
|
||||
secondary_transfer: autoTransferOption;
|
||||
};
|
||||
|
||||
type liqInteractData = {
|
||||
export type autoTransferOption = {
|
||||
autotransferchance: number;
|
||||
autotransferlocation: string | null;
|
||||
autotransferextralocation: string[];
|
||||
autotransfer_whitelist: checkBoxEntry[];
|
||||
autotransfer_blacklist: checkBoxEntry[];
|
||||
autotransfer_whitelist_items: checkBoxEntry[];
|
||||
autotransfer_blacklist_items: checkBoxEntry[];
|
||||
};
|
||||
|
||||
export type liqInteractData = {
|
||||
liq_reagent_gen: BooleanLike;
|
||||
liq_reagent_type: string;
|
||||
liq_reagent_types: string[];
|
||||
liq_reagent_name: string;
|
||||
liq_custom_name_max: number;
|
||||
liq_custom_name_min: number;
|
||||
liq_reagent_transfer_verb: string;
|
||||
liq_reagent_nutri_rate: number;
|
||||
liq_reagent_capacity: number;
|
||||
liq_sloshing: BooleanLike;
|
||||
liq_reagent_addons: string[];
|
||||
liq_reagent_addons: checkBoxEntry[];
|
||||
custom_reagentcolor: string;
|
||||
custom_reagentalpha: number | string;
|
||||
custom_reagentalpha: number | null;
|
||||
liquid_overlay: BooleanLike;
|
||||
max_liquid_level: number;
|
||||
reagent_touches: BooleanLike;
|
||||
@@ -229,19 +279,6 @@ type liqInteractData = {
|
||||
custom_ingested_alpha: number;
|
||||
};
|
||||
|
||||
type liqMessageData = {
|
||||
liq_msg_toggle1: BooleanLike;
|
||||
liq_msg_toggle2: BooleanLike;
|
||||
liq_msg_toggle3: BooleanLike;
|
||||
liq_msg_toggle4: BooleanLike;
|
||||
liq_msg_toggle5: BooleanLike;
|
||||
liq_msg1: BooleanLike;
|
||||
liq_msg2: BooleanLike;
|
||||
liq_msg3: BooleanLike;
|
||||
liq_msg4: BooleanLike;
|
||||
liq_msg5: BooleanLike;
|
||||
};
|
||||
|
||||
export type prefData = {
|
||||
digestable: BooleanLike;
|
||||
devourable: BooleanLike;
|
||||
@@ -282,28 +319,30 @@ export type prefData = {
|
||||
phase_vore: BooleanLike;
|
||||
food_vore: BooleanLike;
|
||||
digest_pain: BooleanLike;
|
||||
nutrition_message_visible: BooleanLike;
|
||||
nutrition_messages: string[];
|
||||
weight_message_visible: BooleanLike;
|
||||
weight_messages: string[];
|
||||
eating_privacy_global: BooleanLike;
|
||||
allow_mimicry: BooleanLike;
|
||||
belly_rub_target: string | null;
|
||||
vore_sprite_color: { stomach: string; 'taur belly': string };
|
||||
vore_sprite_multiply: { stomach: BooleanLike; 'taur belly': BooleanLike };
|
||||
soulcatcher_allow_capture: BooleanLike;
|
||||
soulcatcher_allow_transfer: BooleanLike;
|
||||
soulcatcher_allow_deletion: BooleanLike;
|
||||
soulcatcher_allow_takeover: BooleanLike;
|
||||
};
|
||||
|
||||
export type scMessageData = {
|
||||
sc_subtab: string;
|
||||
possible_messages: string[];
|
||||
max_length: number;
|
||||
active_message: string;
|
||||
set_action: string;
|
||||
tooltip: string;
|
||||
};
|
||||
|
||||
export type soulcatcherData = {
|
||||
active: BooleanLike;
|
||||
name: string;
|
||||
caught_souls: DropdownEntry[];
|
||||
selected_sfx: string;
|
||||
selected_sfx: string | null;
|
||||
selected_soul: string;
|
||||
interior_design: string;
|
||||
sc_message_data: scMessageData;
|
||||
catch_self: BooleanLike;
|
||||
taken_over: BooleanLike;
|
||||
catch_prey: BooleanLike;
|
||||
@@ -322,6 +361,39 @@ export type DropdownEntry = {
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type checkBoxEntry = {
|
||||
label: string;
|
||||
selection: BooleanLike;
|
||||
ref?: string;
|
||||
};
|
||||
|
||||
export type generalPrefData = {
|
||||
active_belly: string | null;
|
||||
belly_rub_target: string | null;
|
||||
aestethic_messages: aestMessageData;
|
||||
vore_sprite_color: Record<string, string>;
|
||||
vore_sprite_multiply: Record<string, BooleanLike>;
|
||||
vore_icon_options: string[];
|
||||
};
|
||||
|
||||
export type aestMessageData = {
|
||||
possible_messages: string[];
|
||||
aest_subtab: string;
|
||||
max_length: number;
|
||||
active_message:
|
||||
| string
|
||||
| string[]
|
||||
| null
|
||||
| Record<string | number, string | number>; // The record is an ancient data corruption, it's not valid!
|
||||
set_action: string;
|
||||
tooltip: string;
|
||||
sub_action?: string;
|
||||
button_action?: string;
|
||||
button_data?: BooleanLike;
|
||||
button_label?: string;
|
||||
button_tooltip?: string;
|
||||
};
|
||||
|
||||
export type localPrefs = {
|
||||
digestion: preferenceData;
|
||||
absorbable: preferenceData;
|
||||
@@ -349,8 +421,6 @@ export type localPrefs = {
|
||||
pickuppref: preferenceData;
|
||||
spontaneous_tf: preferenceData;
|
||||
mind_transfer: preferenceData;
|
||||
examine_nutrition: preferenceData;
|
||||
examine_weight: preferenceData;
|
||||
strippref: preferenceData;
|
||||
eating_privacy_global: preferenceData;
|
||||
allow_mimicry: preferenceData;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import { Button, Section } from 'tgui-core/components';
|
||||
|
||||
import type { Data } from './types';
|
||||
import { downloadPrefs } from './VorePanelExportDownload';
|
||||
|
||||
export const VorePanelExport = () => {
|
||||
@@ -16,10 +14,6 @@ export const VorePanelExport = () => {
|
||||
};
|
||||
|
||||
const VorePanelExportContent = (props) => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
|
||||
const { bellies } = data;
|
||||
|
||||
return (
|
||||
<Section title="Vore Export Panel">
|
||||
<Section title="Export">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"marked": "^4.3.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"tgui-core": "^3.2.0",
|
||||
"tgui-core": "^4.0.1",
|
||||
"tgui-dev-server": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
.VorePanel__fLoating {
|
||||
height: 200px;
|
||||
background-color: var(--color-section);
|
||||
backdrop-filter: var(--blur-medium);
|
||||
border: var(--border-thickness-tiny) solid var(--color-border);
|
||||
border-radius: var(--border-radius-medium);
|
||||
box-shadow: var(--shadow-glow-medium) hsla(0, 0%, 0%, 0.5);
|
||||
margin: var(--space-m);
|
||||
color: var(--color-text);
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding: var(--space-m);
|
||||
}
|
||||
|
||||
.VorePanel__floatingButton {
|
||||
cursor: var(--cursor-pointer);
|
||||
display: inline-block;
|
||||
line-height: 1.667em;
|
||||
padding: 0 var(--space-m);
|
||||
outline: 0;
|
||||
border-radius: var(--button-border-radius);
|
||||
transition-property: background-color, color, opacity;
|
||||
transition-duration: var(--button-transition);
|
||||
transition-timing-function: var(--button-transition-timing);
|
||||
user-select: none;
|
||||
background-color: var(--button-background-default);
|
||||
}
|
||||
|
||||
.VorePanel__pasteArea {
|
||||
height: 200px;
|
||||
width: 600px;
|
||||
background-color: var(--color-section);
|
||||
backdrop-filter: var(--blur-medium);
|
||||
border: var(--border-thickness-tiny) solid var(--color-border);
|
||||
border-radius: var(--border-radius-medium);
|
||||
box-shadow: var(--shadow-glow-medium) hsla(0, 0%, 0%, 0.5);
|
||||
margin: var(--space-m);
|
||||
color: var(--color-text);
|
||||
overflow: hidden;
|
||||
padding: var(--space-m);
|
||||
}
|
||||
@@ -52,6 +52,7 @@
|
||||
@include meta.load-css('./interfaces/IDCard.scss');
|
||||
@include meta.load-css('./interfaces/TinderMessaging.scss');
|
||||
@include meta.load-css('./interfaces/Turbolift.scss');
|
||||
@include meta.load-css('./interfaces/VorePanel.scss');
|
||||
@include meta.load-css('./interfaces/Wires.scss');
|
||||
|
||||
// Layouts
|
||||
|
||||
+8
-8
@@ -19925,20 +19925,20 @@ __metadata:
|
||||
react: "npm:^19.1.0"
|
||||
react-dom: "npm:^19.1.0"
|
||||
tgui: "workspace:*"
|
||||
tgui-core: "npm:^3.2.0"
|
||||
tgui-core: "npm:^4.0.1"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"tgui-core@npm:^3.2.0":
|
||||
version: 3.2.0
|
||||
resolution: "tgui-core@npm:3.2.0"
|
||||
"tgui-core@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "tgui-core@npm:4.0.1"
|
||||
dependencies:
|
||||
"@floating-ui/react": "npm:^0.27.8"
|
||||
"@nozbe/microfuzz": "npm:^1.0.0"
|
||||
peerDependencies:
|
||||
react: ^19.1.0
|
||||
react-dom: ^19.1.0
|
||||
checksum: 10c0/86afb01b278b850aaf226c26889674e6c4933c9366e1c2a0d50a4a4452ed67edd96c10f34cbcbec25aec50cb7baaa2498fd13fff2d2f90f42e77fe20f892f440
|
||||
checksum: 10c0/dc15e1f615395fb62dc7445a68b5bb5b1a102993f5fbf2efe38c190e2608c13da7e78246e328bd5461059f554471ecd08e72719c7d409e5a79f8e2e96ddb81b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -19966,7 +19966,7 @@ __metadata:
|
||||
react: "npm:^19.1.0"
|
||||
react-dom: "npm:^19.1.0"
|
||||
tgui: "workspace:*"
|
||||
tgui-core: "npm:^3.2.0"
|
||||
tgui-core: "npm:^4.0.1"
|
||||
tgui-dev-server: "workspace:*"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
@@ -19981,7 +19981,7 @@ __metadata:
|
||||
react: "npm:^19.1.0"
|
||||
react-dom: "npm:^19.1.0"
|
||||
tgui: "workspace:*"
|
||||
tgui-core: "npm:^3.2.0"
|
||||
tgui-core: "npm:^4.0.1"
|
||||
vitest: "npm:^3.1.1"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
@@ -20043,7 +20043,7 @@ __metadata:
|
||||
marked: "npm:^4.3.0"
|
||||
react: "npm:^19.1.0"
|
||||
react-dom: "npm:^19.1.0"
|
||||
tgui-core: "npm:^3.2.0"
|
||||
tgui-core: "npm:^4.0.1"
|
||||
tgui-dev-server: "workspace:*"
|
||||
vitest: "npm:^3.1.1"
|
||||
languageName: unknown
|
||||
|
||||
@@ -4420,6 +4420,12 @@
|
||||
#include "code\modules\vore\eating\vertical_nom_vr.dm"
|
||||
#include "code\modules\vore\eating\vore_vr.dm"
|
||||
#include "code\modules\vore\eating\vorepanel_vr.dm"
|
||||
#include "code\modules\vore\eating\panel_databackend\vorepanel_pref_data.dm"
|
||||
#include "code\modules\vore\eating\panel_databackend\vorepanel_set_attribute.dm"
|
||||
#include "code\modules\vore\eating\panel_databackend\vorepanel_set_liqattribute.dm"
|
||||
#include "code\modules\vore\eating\panel_databackend\vorepanel_soulcatcher_data.dm"
|
||||
#include "code\modules\vore\eating\panel_databackend\vorepanel_vore_data.dm"
|
||||
#include "code\modules\vore\eating\panel_databackend\vorepanel_vore_subdata.dm"
|
||||
#include "code\modules\vore\fluffstuff\custom_boxes_vr.dm"
|
||||
#include "code\modules\vore\fluffstuff\custom_clothes_vr.dm"
|
||||
#include "code\modules\vore\fluffstuff\custom_implants_vr.dm"
|
||||
|
||||
Reference in New Issue
Block a user