diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md index 60f2305a8c3..3e5639a5217 100644 --- a/ATTRIBUTIONS.md +++ b/ATTRIBUTIONS.md @@ -73,3 +73,10 @@ **Creator:** Poojawa (https://github.com/VOREStation/VOREStation/pull/6052)
**License:** [General License](sound/vore/sunesound/LICENSE.txt)
**Notes:** Permission to use assets also given in writing. All files under this folder is NOT licensed under CC3. Seek separate permission before copying/using.
+
+**File:** `icons/rogue-star/loafs_64x32.dmi`and `icons/rogue-star/tails_64x32_rs.dmi`
+**Title:** Rogue Star Tails
+**Icon-States:** `flagtail`, derivs by VerySoft, `bnytr`, derivs by Verysoft, `chonksqrl`, derivs by Verysoft
+**Creator:** VerySoft (https://github.com/TS-Rogue-Star/Rogue-Star/pull/435)
+**URL:** [Website](https://rogue-star.net/)
+**License:** Permission granting in writing for use by Virgo and Chomp with proper attribution diff --git a/code/__defines/admin.dm b/code/__defines/admin.dm index 38af7830888..4895a51ae6c 100644 --- a/code/__defines/admin.dm +++ b/code/__defines/admin.dm @@ -46,6 +46,7 @@ #define SMITE_BLUESPACEARTILLERY "Bluespace Artillery" #define SMITE_SPONTANEOUSCOMBUSTION "Spontaneous Combustion" #define SMITE_LIGHTNINGBOLT "Lightning Bolt" +#define SMITE_TERROR "Terrify" #define ADMIN_QUE(user) "(?)" #define ADMIN_FLW(user) "(FLW)" diff --git a/code/__defines/admin_vr.dm b/code/__defines/admin_vr.dm index 40e408d3ed7..b4893b94345 100644 --- a/code/__defines/admin_vr.dm +++ b/code/__defines/admin_vr.dm @@ -4,6 +4,8 @@ #define SMITE_AD_SPAM "Ad Spam" #define SMITE_AUTOSAVE "10 Second Autosave" #define SMITE_AUTOSAVE_WIDE "10 Second Autosave (AoE)" +#define SMITE_SPICEREQUEST "Give Them Spice (Harmless)" +#define SMITE_PEPPERNADE "Give Them Spice (Extra Spicy)" #define MODIFIY_ROBOT_MODULE_ADD "Add a Module" #define MODIFIY_ROBOT_MODULE_REMOVE "Remove a Module" #define MODIFIY_ROBOT_APPLY_UPGRADE "Apply an Upgrade" diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 38646ccbc33..8841c19aa86 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -132,7 +132,10 @@ layer = FULLSCREEN_LAYER /obj/screen/fullscreen/fishbed - icon_state = "fishbed" + icon_state = "fishbed" + +/obj/screen/fullscreen/fear + icon_state = "fear" /obj/screen/fullscreen/lighting_backdrop icon = 'icons/mob/screen_gen.dmi' diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b2ec1627ca3..d2568ffcc35 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -153,7 +153,7 @@ var/answer = tgui_alert(user, "Would you like to [density ? "open" : "close"] this [src.name]?[ alarmed && density ? "\nNote that by doing so, you acknowledge any damages from opening this\n[src.name] as being your own fault, and you will be held accountable under the law." : ""]",\ "\The [src]", list("Yes, [density ? "open" : "close"]", "No")) - if(answer == "No") + if(!answer || answer == "No") return if(user.incapacitated() || (get_dist(src, user) > 1 && !issilicon(user))) to_chat(user, "Sorry, you must remain able bodied and close to \the [src] in order to use it.") diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index aa8764ea6a3..2340df56814 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -97,4 +97,6 @@ var/mob/living/carbon/human/H = user if(H.species) P.accuracy += H.species.gun_accuracy_mod - P.dispersion = max(P.dispersion + H.species.gun_accuracy_dispersion_mod, 0) \ No newline at end of file + P.dispersion = max(P.dispersion + H.species.gun_accuracy_dispersion_mod, 0) + if(H.fear > 30) + P.accuracy -= 35 diff --git a/code/game/objects/items/devices/body_snatcher_vr.dm b/code/game/objects/items/devices/body_snatcher_vr.dm index c5d0456f5ba..8239ec65c37 100644 --- a/code/game/objects/items/devices/body_snatcher_vr.dm +++ b/code/game/objects/items/devices/body_snatcher_vr.dm @@ -25,6 +25,10 @@ to_chat(usr,"A warning pops up on the device, informing you that [M] appears braindead.") return + if(!M.allow_mind_transfer) + to_chat(usr,"The target's mind is too complex to be affected!") + return + if(M.stat == DEAD) //Are they dead? to_chat(usr,"A warning pops up on the device, informing you that [M] is dead, and, as such, the mind transfer can not be done.") return diff --git a/code/modules/admin/verbs/grief_fixers.dm b/code/modules/admin/verbs/grief_fixers.dm index 1024fb7d323..f30bf04b3b6 100644 --- a/code/modules/admin/verbs/grief_fixers.dm +++ b/code/modules/admin/verbs/grief_fixers.dm @@ -5,7 +5,7 @@ if(!check_rights(R_ADMIN|R_DEBUG|R_EVENT)) return - if(tgui_alert(usr, "WARNING: Executing this command will perform a full reset of atmosphere. All pipelines will lose any gas that may be in them, and all zones will be reset to contain air mix as on roundstart. The supermatter engine will also be stopped (to prevent overheat due to removal of coolant). Do not use unless the station is suffering serious atmospheric issues due to grief or bug.", "Full Atmosphere Reboot", list("No", "Yes")) == "No") + if(tgui_alert(usr, "WARNING: Executing this command will perform a full reset of atmosphere. All pipelines will lose any gas that may be in them, and all zones will be reset to contain air mix as on roundstart. The supermatter engine will also be stopped (to prevent overheat due to removal of coolant). Do not use unless the station is suffering serious atmospheric issues due to grief or bug.", "Full Atmosphere Reboot", list("No", "Yes")) != "Yes") return feedback_add_details("admin_verb","FA") diff --git a/code/modules/admin/verbs/smite.dm b/code/modules/admin/verbs/smite.dm index 9ecaeec1a54..d183738cf23 100644 --- a/code/modules/admin/verbs/smite.dm +++ b/code/modules/admin/verbs/smite.dm @@ -8,8 +8,7 @@ if(!istype(target)) return - var/list/smite_types = list(SMITE_BREAKLEGS,SMITE_BLUESPACEARTILLERY,SMITE_SPONTANEOUSCOMBUSTION,SMITE_LIGHTNINGBOLT, - SMITE_SHADEKIN_ATTACK,SMITE_SHADEKIN_NOMF,SMITE_AD_SPAM,SMITE_REDSPACE_ABDUCT,SMITE_AUTOSAVE,SMITE_AUTOSAVE_WIDE) + var/list/smite_types = list(SMITE_BREAKLEGS,SMITE_BLUESPACEARTILLERY,SMITE_SPONTANEOUSCOMBUSTION,SMITE_LIGHTNINGBOLT,SMITE_SHADEKIN_ATTACK,SMITE_SHADEKIN_NOMF,SMITE_AD_SPAM,SMITE_REDSPACE_ABDUCT,SMITE_AUTOSAVE,SMITE_AUTOSAVE_WIDE,SMITE_SPICEREQUEST,SMITE_PEPPERNADE,SMITE_TERROR) var/smite_choice = tgui_input_list(usr, "Select the type of SMITE for [target]","SMITE Type Choice", smite_types) if(!smite_choice) @@ -158,6 +157,21 @@ if(target.client) target.client.create_fake_ad_popup_multiple(/obj/screen/popup/default, 15) + if(SMITE_PEPPERNADE) + var/obj/item/weapon/grenade/chem_grenade/teargas/grenade = new /obj/item/weapon/grenade/chem_grenade/teargas + grenade.loc = target.loc + to_chat(target,"GRENADE?!") + grenade.detonate() + + if(SMITE_SPICEREQUEST) + var/obj/item/weapon/reagent_containers/food/condiment/spacespice/spice = new /obj/item/weapon/reagent_containers/food/condiment/spacespice + spice.loc = target.loc + to_chat(target,"A bottle of spices appears at your feet... be careful what you wish for!") + + if(SMITE_TERROR) + if(ishuman(target)) + target.fear = 200 + else return //Injection? Don't print any messages. diff --git a/code/modules/client/preference_setup/vore/07_traits.dm b/code/modules/client/preference_setup/vore/07_traits.dm index 549b54be820..85c97bcbb7e 100644 --- a/code/modules/client/preference_setup/vore/07_traits.dm +++ b/code/modules/client/preference_setup/vore/07_traits.dm @@ -279,7 +279,8 @@ var/global/list/valid_bloodreagents = list("default","iron","copper","phoron","s for(var/T in pref.pos_traits + pref.neg_traits) points_left -= traits_costs[T] - traits_left-- + if(T in pref.pos_traits) + traits_left-- . += "Traits Left: [traits_left]
" . += "Points Left: [points_left]
" if(points_left < 0 || traits_left < 0 || (!pref.custom_species && pref.species == SPECIES_CUSTOM)) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 5c7aa8575aa..86613af1fd2 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -494,6 +494,10 @@ var/list/preferences_datums = list() error("Player picked [choice] slot to copy to, but that wasn't one we sent.") return - overwrite_character(slotnum) - sanitize_preferences() - ShowChoices(user) + if(tgui_alert(user, "Are you sure you want to override slot [slotnum], [name][nickname ? " ([nickname])" : ""]'s savedata?", "Confirm Override", list("No", "Yes")) == "Yes") + overwrite_character(slotnum) + sanitize_preferences() + save_preferences() + save_character() + attempt_vr(user.client?.prefs_vr,"load_vore","") + ShowChoices(user) diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index 38142fc4667..5e17e9cc99a 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -4873,6 +4873,7 @@ /mob/living/simple_mob/slime composition_reagent = "slimejelly" + allow_mind_transfer = TRUE /mob/living/simple_mob var/kitchen_tag = "animal" //Used for cooking with animals diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index 307f2de2047..e8540dba548 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -41,6 +41,8 @@ var/frustration = 0 var/max_frustration = 0 + allow_mind_transfer = TRUE + /mob/living/bot/New() ..() //update_icons() //VOREstation edit: moved to Init diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index a7c8a2689bb..d72299dcac2 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -310,7 +310,7 @@ else if(!client) msg += "[T.He] [T.is] [ssd_msg]." //VOREStation Add Start - if(away_from_keyboard && manual_afk) + if(client && away_from_keyboard && manual_afk) msg += "\[Away From Keyboard for [round((client.inactivity/10)/60)] minutes\]" else if(client && ((client.inactivity / 10) / 60 > 10)) //10 Minutes msg += "\[Inactive for [round((client.inactivity/10)/60)] minutes\]" diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 71ea0a949e7..c3241e9af3e 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -438,7 +438,7 @@ organ.applied_pressure = null if(user == src) - user.visible_message("\The [user] stops applying pressure to [TU.his] [organ.name]!", "You stop applying pressure to your [organ]!") + user.visible_message("\The [user] stops applying pressure to [TU.his] [organ.name]!", "You stop applying pressure to your [organ]!") else user.visible_message("\The [user] stops applying pressure to [src]'s [organ.name]!", "You stop applying pressure to [src]'s [organ.name]!") diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 2a0bf0dc140..5b816be2941 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -162,4 +162,6 @@ // Custom Species Name var/custom_species - var/block_hud \ No newline at end of file + var/block_hud + + var/phobias //For holding a list of phobias \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 12e7fa470ce..6a75c780f24 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -73,6 +73,8 @@ handle_heartbeat() handle_nif() //VOREStation Addition + if(phobias) + handle_phobias() if(!client) species.handle_npc(src) @@ -1244,6 +1246,27 @@ if(tiredness >= 100) Sleeping(5) + if(fear) + fear = (fear - 1) + if(fear >= 80 && is_preference_enabled(/datum/client_preference/play_ambiance)) + if(last_fear_sound + 51 SECONDS <= world.time) + src << sound('sound/effects/Heart Beat.ogg',0,0,0,25) + last_fear_sound = world.time + if(fear >= 80 && !isSynthetic()) + if(prob(1) && get_active_hand()) + var/stuff_to_drop = get_active_hand() + drop_item() + visible_message("\The [src] suddenly drops their [stuff_to_drop].","You drop your [stuff_to_drop]!") + if(prob(5)) + var/fear_self = pick(fear_message_self) + var/fear_other = pick(fear_message_other) + visible_message("\The [src][fear_other]","[fear_self]") + else if(fear >= 30 && !isSynthetic()) + if(prob(2)) + var/fear_self = pick(fear_message_self) + var/fear_other = pick(fear_message_other) + visible_message("\The [src][fear_other]","[fear_self]") + if(paralysis || sleeping) blinded = 1 set_stat(UNCONSCIOUS) @@ -1442,6 +1465,19 @@ else clear_fullscreen("tired") + if(fear) + var/severity = 0 + switch(fear) + if(10 to 20) severity = 1 + if(20 to 30) severity = 2 + if(30 to 50) severity = 3 + if(50 to 70) severity = 4 + if(70 to 90) severity = 5 + if(90 to INFINITY) severity = 6 + overlay_fullscreen("fear", /obj/screen/fullscreen/fear, severity) + else + clear_fullscreen("fear") + if(healths) if (chem_effects[CE_PAINKILLER] > 100) healths.icon_state = "health_numb" diff --git a/code/modules/mob/living/carbon/human/phobias.dm b/code/modules/mob/living/carbon/human/phobias.dm new file mode 100644 index 00000000000..24c2c02efb1 --- /dev/null +++ b/code/modules/mob/living/carbon/human/phobias.dm @@ -0,0 +1,58 @@ +//Handling and defining of phobias and fears +#define NYCTOPHOBIA 1 +#define ARACHNOPHOBIA 2 +#define HEMOPHOBIA 4 +#define THALASSOPHOBIA 8 +#define CLAUSTROPHOBIA_MINOR 16 +#define CLAUSTROPHOBIA_MAJOR 32 +#define ANATIDAEPHOBIA 64 +#define AGRAVIAPHOBIA 128 + +/mob/living/carbon/human/proc/handle_phobias() + if(phobias & NYCTOPHOBIA) + var/turf/T = get_turf(src) + var/brightness = T.get_lumcount() + if(brightness < 0.2) + fear = min((fear + 3), 102) + if(phobias & ARACHNOPHOBIA) + for (var/mob/living/simple_mob/animal/giant_spider/S in viewers(src, null)) + if(!istype(S) || S.stat) + continue + fear = min((fear + 6), 102) + if(phobias & HEMOPHOBIA) + for(var/obj/effect/decal/cleanable/blood/B in view(7, src)) + var/obj/effect/decal/cleanable/blood/oil/O = B + var/obj/effect/decal/cleanable/blood/tracks/T = B + if(istype(O) || istype(T)) + continue + fear = min((fear + 2), 102) + for(var/turf/simulated/floor/water/blood/T in view(7, src)) + fear = min((fear + 2), 102) + if(phobias & THALASSOPHOBIA) + var/turf/T = get_turf(src) + if(istype(T,/turf/simulated/floor/water/underwater) || istype(T,/turf/simulated/floor/water/deep)) + fear = min((fear + 4), 102) + if(phobias & CLAUSTROPHOBIA_MINOR) + if(!isturf(loc)) + if(!istype(loc,/obj/belly) && !istype(loc,/obj/item/weapon/holder/micro)) + fear = min((fear + 3), 102) + if(phobias & CLAUSTROPHOBIA_MAJOR) //Also activated inside of a belly + if(!isturf(loc)) + if(!istype(loc,/obj/item/weapon/holder/micro)) + fear = min((fear + 3), 102) + if(phobias & ANATIDAEPHOBIA) + for (var/mob/living/simple_mob/animal/space/goose/G in viewers(src, null)) + if(!istype(G) || G.stat) + continue + fear = min((fear + 3), 102) + for (var/mob/living/simple_mob/animal/sif/duck/D in viewers(src, null)) + if(!istype(D) || D.stat) + continue + fear = min((fear + 3), 102) + for(var/obj/item/weapon/bikehorn/rubberducky/R in view(7, src)) + if(!istype(R)) + continue + fear = min((fear + 2), 102) + if(phobias & AGRAVIAPHOBIA) + if(is_floating) + fear = min((fear + 4), 102) diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index ffdbfcc3a9a..d35fd9832c8 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -1563,7 +1563,7 @@ to_chat(src, "You prepare to inject [trait_injection_amount] units of [trait_injection_selected ? "[trait_injection_selected]" : "...nothing. Select a reagent before trying to inject anything."]") return if(choice == "Change amount") - var/amount_choice = tgui_input_number(usr, "How much of the reagent do you want to inject? (Up to 5 units) (Can select 0 for a bite that doesn't inject venom!)", "How much?", trait_injection_amount, 5, 0) + var/amount_choice = tgui_input_number(usr, "How much of the reagent do you want to inject? (Up to 5 units) (Can select 0 for a bite that doesn't inject venom!)", "How much?", trait_injection_amount, 5, 0, round_value = FALSE) if(amount_choice >= 0) trait_injection_amount = amount_choice to_chat(src, "You prepare to inject [trait_injection_amount] units of [trait_injection_selected ? "[trait_injection_selected]" : "...nothing. Select a reagent before trying to inject anything."]") diff --git a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm index 2575d52dcfa..d2257ee6699 100644 --- a/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm +++ b/code/modules/mob/living/carbon/human/species/station/traits_vr/neutral.dm @@ -1088,3 +1088,86 @@ /datum/trait/neutral/food_pref/coffee ) our_allergens = list(ALLERGEN_STIMULANT) + + +//////////////PHOBIAS///////////////// + +/datum/trait/neutral/nyctophobia + name = "Phobia: Nyctophobia" + desc = "You are afraid of the dark. When in very dark conditions, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/nyctophobia/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= NYCTOPHOBIA + +/datum/trait/neutral/arachnophobia + name = "Phobia: Arachnophobia" + desc = "You are afraid of spiders. When you can see a large spider, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/arachnophobia/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= ARACHNOPHOBIA + +/datum/trait/neutral/hemophobia + name = "Phobia: Hemophobia" + desc = "You are afraid of blood. When you can see large amounts of blood, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/hemophobia/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= HEMOPHOBIA + +/datum/trait/neutral/thalassophobia + name = "Phobia: Thalassophobia" + desc = "You are afraid of deep water. When in deep water, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/thalassophobia/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= THALASSOPHOBIA + +/datum/trait/neutral/clasutrophobia_minor + name = "Phobia: Claustrophobia (non-vore)" + desc = "You are afraid of tight, enclosed spaces. When inside of another object, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/clasutrophobia_minor/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= CLAUSTROPHOBIA_MINOR + +/datum/trait/neutral/clasutrophobia_major + name = "Phobia: Claustrophobia (vore)" + desc = "You are afraid of tight, enclosed spaces. When inside of another object, including vore bellies, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/clasutrophobia_major/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= CLAUSTROPHOBIA_MAJOR + +/datum/trait/neutral/anatidaephobia + name = "Phobia: Anatidaephobia" + desc = "You are afraid of ducks. When you can see a duck (even rubber ones), you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/anatidaephobia/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= ANATIDAEPHOBIA + +/datum/trait/neutral/agraviaphobia + name = "Phobia: Agraviaphobia" + desc = "You are afraid of a lack of gravity. When you find yourself floating, you will become afraid." + cost = 0 + custom_only = FALSE + +/datum/trait/neutral/agraviaphobia/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/trait_prefs = null) + ..() + H.phobias |= AGRAVIAPHOBIA diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index c27553b787b..ae5008e27e6 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -1356,7 +1356,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(tail_style.extra_overlay) var/icon/overlay = new/icon("icon" = (tail_style?.can_loaf && resting) ? tail_style.icon_loaf : tail_style.icon, "icon_state" = tail_style.extra_overlay) //CHOMPEdit if(wagging && tail_style.ani_state) - overlay = new/icon("icon" = tail_style.icon, "icon_state" = tail_style.extra_overlay_w) + overlay = new/icon("icon" = (tail_style?.can_loaf && resting) ? tail_style.icon_loaf : tail_style.icon, "icon_state" = tail_style.extra_overlay_w) //RS EDIT overlay.Blend(rgb(src.r_tail2, src.g_tail2, src.b_tail2), tail_style.color_blend_mode) tail_s.Blend(overlay, ICON_OVERLAY) qdel(overlay) @@ -1368,7 +1368,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() if(tail_style.extra_overlay2) var/icon/overlay = new/icon("icon" = (tail_style?.can_loaf && resting) ? tail_style.icon_loaf : tail_style.icon, "icon_state" = tail_style.extra_overlay2) //CHOMPEdit if(wagging && tail_style.ani_state) - overlay = new/icon("icon" = tail_style.icon, "icon_state" = tail_style.extra_overlay2_w) + overlay = new/icon("icon" = (tail_style?.can_loaf && resting) ? tail_style.icon_loaf : tail_style.icon, "icon_state" = tail_style.extra_overlay2_w) //RS EDIT overlay.Blend(rgb(src.r_tail3, src.g_tail3, src.b_tail3), tail_style.color_blend_mode) tail_s.Blend(overlay, ICON_OVERLAY) qdel(overlay) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 6635200baae..697337a26da 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -83,3 +83,26 @@ var/datum/inventory_panel/inventory_panel var/last_resist_time = 0 // world.time of the most recent resist that wasn't on cooldown. var/tiredness = 0 //For vore draining + var/fear = 0 //For fear effects and phobias + var/last_fear_sound = 0 //For making sure the heartbeats don't play over each other + + var/list/fear_message_self = list( + "Your heart is racing, it feels like it's going burst from your chest.", + "Your stomach clenches and churns with anxiety.", + "It's getting hard to breathe, you're panting heavily.", + "You feel your eyes straining.", + "A sharp shiver runs down your spine.", + "You feel like you are drowning.", + "You feel your palms clamming up.", + "Your legs feel weak, you can barely control them.", + "You have difficulty even swallowing." + ) + var/list/fear_message_other = list( + "'s eyes are darting around the room rapidly.", + " looks like they are shivering, literally shaking.", + " is breathing rapidly.", + " looks profoundly uncomfortable.", + "s literally trembling in front of you.", + "'s hands are shaking.", + " is rocking slightly from side to side." + ) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm b/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm index bcc4d8558a5..4bcfc145a16 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/alien animals/catslug.dm @@ -60,6 +60,8 @@ var/picked_color = FALSE + allow_mind_transfer = TRUE + can_enter_vent_with = list( /obj/item/weapon/implant, /obj/item/device/radio/borg, diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm index d2631cb1ec1..49a22fb990c 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm @@ -117,6 +117,8 @@ /obj/item/stack/material/chitin = 1\ ) + allow_mind_transfer = TRUE + /mob/living/simple_mob/animal/giant_spider/apply_melee_effects(var/atom/A) if(isliving(A)) var/mob/living/L = A diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm index 6450259f9c1..ea32372b329 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/passive.dm @@ -2,4 +2,5 @@ // They can also be displaced by all mobs. /mob/living/simple_mob/animal/passive ai_holder_type = /datum/ai_holder/simple_mob/passive - mob_bump_flag = 0 \ No newline at end of file + mob_bump_flag = 0 + allow_mind_transfer = TRUE diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm index be88baab273..6ef4f5b0093 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/sif.dm @@ -3,6 +3,7 @@ minbodytemp = 175 cold_resist = 0.75 heat_resist = -0.5 + allow_mind_transfer = TRUE tame_items = list( /obj/item/weapon/reagent_containers/food/snacks/crabmeat = 20, diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm index 9330af19840..4356f778f2f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/bear.dm @@ -27,6 +27,8 @@ say_list_type = /datum/say_list/bear + allow_mind_transfer = TRUE + /datum/say_list/bear speak = list("RAWR!","Rawr!","GRR!","Growl!") emote_see = list("stares ferociously", "stomps") diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/squirrel.dm b/code/modules/mob/living/simple_mob/subtypes/animal/squirrel.dm index 9b62bc7da49..4611e3fe609 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/squirrel.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/squirrel.dm @@ -52,6 +52,8 @@ var/do_seasons = TRUE var/picked_color = FALSE + allow_mind_transfer = TRUE + /////////////////////////////////////// Vore stuff/////////////////////////////////////////// swallowTime = 4 SECONDS diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/bat.dm b/code/modules/mob/living/simple_mob/subtypes/vore/bat.dm index 6d6328dfeff..9d67740a5c6 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/bat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/bat.dm @@ -24,6 +24,8 @@ faction = "vampire" + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/bat vore_active = 1 @@ -55,4 +57,3 @@ B.escapechance = 15 B.selective_preference = DM_DRAIN B.escape_stun = 5 - diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm b/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm index 010dbafed19..9424d0b7949 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/bee.dm @@ -44,6 +44,8 @@ var/poison_chance = 10 // Chance for injection to occur. var/poison_per_bite = 1 // Amount added per injection. + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/bee/Process_Spacemove(var/check_drift = 0) return 1 //No drifting in space for space bee! diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm b/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm index 37ef332a14d..fde53a7120f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/bigdragon.dm @@ -325,6 +325,7 @@ I think I covered everything. /// /mob/living/simple_mob/vore/bigdragon/update_icon() + ..() update_fullness() build_icons() @@ -342,9 +343,10 @@ I think I covered everything. /mob/living/simple_mob/vore/bigdragon/proc/build_icons(var/random) cut_overlays() if(stat == DEAD) - icon_state = "dragon-dead" plane = MOB_LAYER return + else + plane = ABOVE_MOB_PLANE if(random) var/list/bodycolors = list("#1E1E1E","#3F3F3F","#545454","#969696","#DBDBDB","#ABBBD8","#3D0B00","#3A221D","#77554F","#281D1B","#631F00","#964421","#936B24","#381313","#380000","#682121","#700E00","#44525B","#283035","#29353D","#353E44","#281000","#38261A","#302F3D","#322E3A","#262738") under = pick(underbelly_styles) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm index d3ad0c3c875..eb9a6199fdf 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm @@ -73,6 +73,8 @@ loot_list = list(/obj/item/borg/upgrade/basic/syndicate = 6, /obj/item/borg/upgrade/basic/vtec = 6, /obj/item/weapon/material/knife/ritual = 6, /obj/item/weapon/disk/nifsoft/compliance = 6) + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi name = "corrupt corrupt hound" desc = "Bad boy machine broke as well. Seems an attempt was made to achieve a less threatening look, and this one is definitely having some conflicting feelings about it." diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm index 8ad2e26f1dc..e2f32e3790d 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm @@ -59,6 +59,8 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee/deathclaw + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/aggressive/deathclaw vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm b/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm index c1f0068abff..c9c42899814 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/dino.dm @@ -39,6 +39,8 @@ max_n2 = 0 minbodytemp = 0 + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/aggressive/dino vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/dominated_brain.dm b/code/modules/mob/living/simple_mob/subtypes/vore/dominated_brain.dm index f5e93af8220..6058a4320dd 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/dominated_brain.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/dominated_brain.dm @@ -194,6 +194,10 @@ to_chat(prey, "You cannot do that in your current state.") return + if(!pred.allow_mind_transfer) + to_chat(prey, "[pred] is unable to be dominated.") + return + if(!pred.ckey) to_chat(prey, "\The [pred] isn't able to be dominated.") return @@ -316,7 +320,7 @@ var/list/possible_mobs = list() for(var/obj/belly/B in src.vore_organs) for(var/mob/living/L in B) - if(isliving(L) && L.ckey) + if(isliving(L) && L.ckey && L.allow_mind_transfer) possible_mobs |= L else continue @@ -327,6 +331,9 @@ if(!input) return var/mob/living/M = input + if(!M.allow_mind_transfer) //check if the dominated mob pref is enabled + to_chat(src, "[M] is unable to be dominated.") + return if(tgui_alert(src, "You selected [M] to attempt to dominate. Are you sure?", "Dominate Prey",list("No","Yes")) != "Yes") return log_admin("[key_name_admin(src)] offered to use dominate prey on [M] ([M.ckey]).") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm b/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm index 297bb7a7d31..7766b7fdc88 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/fennec.dm @@ -52,6 +52,8 @@ say_list_type = /datum/say_list/fennec ai_holder_type = /datum/ai_holder/simple_mob/passive + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/fennec vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm b/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm index 7d16df1049a..d6924a090d7 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/fennix.dm @@ -27,6 +27,8 @@ say_list_type = /datum/say_list/fennix ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative + allow_mind_transfer = TRUE + /datum/say_list/fennix speak = list("SQUEL!","SQEL?","Skree.") emote_hear = list("Screeeeecheeeeessss!","Chirrup.") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm b/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm index dfa3bfe5419..f7c40f8b0ce 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/frog.dm @@ -44,6 +44,8 @@ special_attack_max_range = 5 special_attack_cooldown = 100 + allow_mind_transfer = TRUE + // Pepe is love, not hate. /mob/living/simple_mob/vore/aggressive/frog/New() if(rand(1,1000000) == 1) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm index afe0c96324e..2bcf95cf814 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm @@ -35,6 +35,8 @@ say_list_type = /datum/say_list/horse ai_holder_type = /datum/ai_holder/simple_mob/retaliate + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/horse/big name = "horse" icon_state = "horse" @@ -194,4 +196,4 @@ holder.set_dir(moving_to) holder.IMove(get_step(holder,moving_to)) wander_delay = base_wander_delay - ai_log("handle_wander_movement() : Exited.", AI_LOG_TRACE) \ No newline at end of file + ai_log("handle_wander_movement() : Exited.", AI_LOG_TRACE) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm b/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm index 00e360e9d81..4a4ab6c1181 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/jelly.dm @@ -27,6 +27,8 @@ max_n2 = 0 minbodytemp = 0 + allow_mind_transfer = TRUE + // Activate Noms! vore_active = 1 vore_pounce_chance = 0 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/meowl.dm b/code/modules/mob/living/simple_mob/subtypes/vore/meowl.dm new file mode 100644 index 00000000000..421a1dc64bd --- /dev/null +++ b/code/modules/mob/living/simple_mob/subtypes/vore/meowl.dm @@ -0,0 +1,260 @@ +/mob/living/simple_mob/vore/meowl + name = "Meowl" + desc = "A rather cute looking creature that seems to have the features of both a cat and an owl." + catalogue_data = list(/datum/category_item/catalogue/fauna/meowl) + tt_desc = "Strigiline" + icon = 'icons/mob/vore.dmi' + icon_dead = "meowl-dead" + icon_living = "meowl" + icon_state = "meowl" + icon_rest = "meowl_rest" + faction = "meowl" + friendly = list("nudges", "sniffs on", "rumbles softly at", "nuzzles") + response_help = "pets" + response_disarm = "shoves" + response_harm = "attacks" + movement_cooldown = 2 + harm_intent_damage = 1 + melee_damage_lower = 1 + melee_damage_upper = 2 + maxHealth = 100 + attacktext = list("scratches") + see_in_dark = 8 + minbodytemp = 0 + ai_holder_type = /datum/ai_holder/simple_mob/vore/meowl + var/well_fed = 0 + + vore_bump_chance = 0 + vore_digest_chance = 50 + vore_escape_chance = 5 + vore_pounce_chance = 1000 + vore_active = 1 + vore_icons = 1 + vore_icons = SA_ICON_LIVING | SA_ICON_REST + vore_capacity = 1 + swallowTime = 50 + vore_ignores_undigestable = FALSE + vore_default_mode = DM_HOLD + vore_pounce_maxhealth = 1000 + vore_bump_emote = "pounces on" + +/mob/living/simple_mob/vore/meowl/init_vore() + ..() + var/obj/belly/B = vore_selected + B.name = "stomach" + B.desc = "The strange critter suddenly takes advantage of you being alone to pounce atop you and quickly engulf your head within its maw! Before you even have a chance to react, the world goes dark with the inside of the meowls mouth covering your face, a rough tounge lapping smearing wet hot slobber over you. The rest of the process is pretty quick as the cat-owl begins to gulp your head down through a surprisingly stretchy throat and along the tight, flexing tunnel of its gullet. Before long you are pushing face first into the creature's stomach, the wrinkled walls quickly beginning grind slick flesh across it like any other piece of food. The rest of your body soon follows into the increasingly tight space, forced to curl up over yourself as the stomach lining bears down on you from every angle. At first, the stomach itself seems rather inactive, happily just squeezing and massaging you as the meowl settles down to slowly enjoy their snack. Though, struggling might risk setting off the gut one way or another..." + B.mode_flags = DM_FLAG_THICKBELLY + B.belly_fullscreen = "yet_another_tumby" + B.digest_brute = 1 + B.digest_burn = 1 + B.digest_oxy = 1 + B.selectchance = 25 + B.digestchance = 0 + B.absorbchance = 0 + B.escapechance = 10 + B.selective_preference = DM_DIGEST + B.escape_stun = 5 + B.transferlocation_absorb = "chub" + + var/obj/belly/chub = new /obj/belly(src) + chub.immutable = TRUE + chub.name = "chub" + chub.desc = "Your body quickly begins to feel very... different? In fact, you can't really feel your body much at all any more, but you certainly still feel something. The pressure of the gut that was practically crushing you before is relieved, but somehow still present as though you were now on the other side of the interaction. Your being feels much more spread out and practically intertwined with the world around, that world being the meowl itself. The strange cat-owl's purring feels like it's reverberating throughout your entire form, whatever that might be. Every time the critter shakes to ruffle its feathers, you feel yourself shake with it. Even the creatures emotions feel tangible to you, as though you share themselves, and mostly they are ones of fullness and content." + chub.digest_mode = DM_HOLD // like, its got you already, doesn't need to get you more + chub.mode_flags = DM_FLAG_FORCEPSAY + chub.escapable = TRUE // good luck + chub.escapechance = 40 // high chance of STARTING a successful escape attempt + chub.escapechance_absorbed = 5 // m i n e + chub.vore_verb = "soak" + chub.count_absorbed_prey_for_sprite = FALSE + chub.absorbed_struggle_messages_inside = list( + "You try and push free from %pred's %belly, but can't seem to will yourself to move.", + "Your fruitless mental struggles only cause %pred to purr happily.", + "You can't make any progress freeing yourself from %pred's %belly.") + chub.escape_attempt_absorbed_messages_owner = list( + "%prey is attempting to free themselves from your %belly!") + + chub.escape_attempt_absorbed_messages_prey = list( + "You try to force yourself out of %pred's %belly.", + "You strain and push, attempting to reach out of %pred's %belly.", + "You work up the will to try and force yourself free of %pred's clutches.") + + chub.escape_absorbed_messages_owner = list( + "%prey forces themselves free of your %belly!") + + chub.escape_absorbed_messages_prey = list( + "You finally manage to wrest yourself free from %pred's %belly, re-asserting your more usual form.", + "You heave and push, eventually spilling out from %pred's %belly, eliciting a mildly annoyed flurry of wing flapping.") + + chub.escape_absorbed_messages_outside = list( + "%prey suddenly forces themselves free of %pred's %belly!") + + chub.escape_fail_absorbed_messages_owner = list( + "%prey's attempt to escape form your %belly has failed!") + + chub.escape_fail_absorbed_messages_prey = list( + "Before you manage to reach freedom, you feel yourself getting dragged back into %pred's %belly!", + "%pred cheeps playfully, simply pressing your wrigging form back into their %belly before you get anywhere.", + "%pred holds a wing down on their %belly, the gentle pressure breaking your concentration and sending you sinking back into its form.", + "Try as you might, you barely make an impression before %pred simply clenches with the most minimal effort, binding you back into their %belly.", + "Unfortunately, %pred seems to have absolutely no intention of letting you go, and your futile effort goes nowhere.", + "Strain as you might, you can't keep up the effort long enough before you sink back into %pred's %belly.") + +/mob/living/simple_mob/vore/meowl/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item/weapon/reagent_containers/food)) + if(health <= 0) + return + user.visible_message("\The [src] happily gulps down \the [O] right out of \the [user]'s hand, it seems pretty content now.","\The [src] happily gulps down \the [O] right out of your hand, it seems pretty content now.") + user.drop_from_inventory(O) + qdel(O) + well_fed = world.time + return + return ..() + +/mob/living/simple_mob/vore/meowl/PounceTarget(var/mob/living/M, var/successrate = 100) + vore_pounce_cooldown = world.time + 1 SECONDS // don't attempt another pounce for a while + if(prob(max(successrate,33))) // pounce success! + M.Weaken(5) + M.visible_message("\The [src] pounces on \the [M]!!") + else // pounce misses! + M.visible_message("\The [src] attempts to pounce \the [M] but misses!!") + playsound(src, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + + if(will_eat(M) && (!M.canmove || vore_standing_too)) //if they're edible then eat them too + return EatTarget(M) + else + return //just leave them + +/datum/category_item/catalogue/fauna/meowl + name = "Extra-Realspace Fauna - Meowl" + desc = "Classification: Strigiline\ +

\ + These unusual creatures are sometimes found within redgate locations and seem to exhibit both the characteristics of a cat and of an owl. \ + Whilst these animals at a glance appear to be rather sweet and friendly, they are actually very competent predators and excellent opportunists. \ + They will very rarely attack their prey when there are other creatures nearby, preferring to wait until their target is alone and unprotected. \ + Despite this, these creatues can be rather docile in the right conditions, and will not attack those who it believes it can get food from reliably." + value = CATALOGUER_REWARD_HARD + +/datum/ai_holder/simple_mob/vore/meowl + var/last_friend_time = 0 + +/datum/ai_holder/simple_mob/vore/meowl/engage_target() + ai_log("engage_target() : Entering.", AI_LOG_DEBUG) + + // Can we still see them? + if(!target || !can_attack(target)) + ai_log("engage_target() : Lost sight of target.", AI_LOG_TRACE) + if(lose_target()) // We lost them (returns TRUE if we found something else to do) + ai_log("engage_target() : Pursuing other options (last seen, or a new target).", AI_LOG_TRACE) + return + + var/distance = get_dist(holder, target) + ai_log("engage_target() : Distance to target ([target]) is [distance].", AI_LOG_TRACE) + holder.face_atom(target) + last_conflict_time = world.time + + // Check if there is more than one person nearby and if they allow eating them + if(!check_attacker(target)) //Only act friendly if you haven't been attacked yet + var/list/crowd = list_targets() + + var/mob/living/L = target + if(istype(L)) + if(!L.allowmobvore && vore_hostile && distance <= 8) + play_friend(target) + set_stance(STANCE_APPROACH) + return + + if(crowd.len > 1 && distance <= 8) + play_friend(target) + set_stance(STANCE_APPROACH) + return + + // Don't attack if you're well fed! + + var/mob/living/simple_mob/vore/meowl/M = holder + + if(istype(M)) + if(M.well_fed + 10 MINUTES > world.time) + set_stance(STANCE_APPROACH) + return + + + // Do a 'special' attack, if one is allowed. +// if(prob(special_attack_prob) && (distance >= special_attack_min_range) && (distance <= special_attack_max_range)) + if(holder.ICheckSpecialAttack(target)) + ai_log("engage_target() : Attempting a special attack.", AI_LOG_TRACE) + on_engagement(target) + if(special_attack(target)) // If this fails, then we try a regular melee/ranged attack. + ai_log("engage_target() : Successful special attack. Exiting.", AI_LOG_DEBUG) + return + + // Stab them. + else if(distance <= 1 && !pointblank) + ai_log("engage_target() : Attempting a melee attack.", AI_LOG_TRACE) + on_engagement(target) + melee_attack(target) + + else if(distance <= 1 && !holder.ICheckRangedAttack(target)) // Doesn't have projectile, but is pointblank + ai_log("engage_target() : Attempting a melee attack.", AI_LOG_TRACE) + on_engagement(target) + melee_attack(target) + + // Shoot them. + else if(holder.ICheckRangedAttack(target) && (distance <= max_range(target)) ) + on_engagement(target) + if(firing_lanes && !test_projectile_safety(target)) + // Nudge them a bit, maybe they can shoot next time. + var/turf/T = get_step(holder, pick(cardinal)) + if(T) + holder.IMove(T) // IMove() will respect movement cooldown. + holder.face_atom(target) + ai_log("engage_target() : Could not safely fire at target. Exiting.", AI_LOG_DEBUG) + return + + ai_log("engage_target() : Attempting a ranged attack.", AI_LOG_TRACE) + ranged_attack(target) + + // Run after them. + else if(!stand_ground) + ai_log("engage_target() : Target ([target]) too far away. Exiting.", AI_LOG_DEBUG) + set_stance(STANCE_APPROACH) + +/datum/ai_holder/simple_mob/vore/meowl/proc/play_friend(target) + if(last_friend_time + 60 SECONDS > world.time) + return + + var/list/friend_text_close = list("nuzzles its head against \the [target] sweetly.", + "lets out a cute little chirp and flaps its wings.", + "wriggles its tail excitedly and begins to purr.", + "hops up and down on the spot!", + "looks at \the [target] with the biggest, roundest eyes that it can manage.", + "claws at the ground for a moment, as if looking for something.", + "stares off into the distance before letting out a quiet meow.", + "cheeps a high pitch sound, before looking up.", + "rubs its head gently against \the [target].", + "raises a wing to wash under it.", + "lets out a long, sing-songy mrowl.", + "purrs happily as it snuggles up to \the [target].", + "flaps its wings and wiggles its whole body.", + "shakes rapidly to ruffle its own feathers." + ) + var/list/friend_text_far = list("lets out a cute little chirp and flaps its wings.", + "wriggles its tail excitedly and begins to purr.", + "hops up and down on the spot!", + "claws at the ground for a moment, as if looking for something.", + "stares off into the distance before letting out a quiet meow.", + "cheeps a high pitch sound, before looking up.", + "raises a wing to wash under it.", + "lets out a long, sing-songy mrowl.", + "flaps its wings and wiggles its whole body.", + "shakes rapidly to ruffle its own feathers." + ) + + var/distance = get_dist(holder, target) + if(distance <= 1) + var/talkies = pick(friend_text_close) + holder.visible_message("\The [holder] [talkies]") + else + var/talkies = pick(friend_text_far) + holder.visible_message("\The [holder] [talkies]") + last_friend_time = world.time diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm index 8dae71b3bf1..50d8df80853 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm @@ -265,48 +265,45 @@ var/list/possible_mobs = list() for(var/obj/belly/B in src.vore_organs) for(var/mob/living/H in B) - if( (ishuman(H) || isrobot(H)) && H.ckey ) + if((ishuman(H) || isrobot(H)) && H.ckey) possible_mobs += H else continue - var/mob/living/carbon/human/M - var/input = tgui_input_list(src, "Select a mob to take over:", "Take Over Prey", possible_mobs) - if(!input) - return - M = input - if(!M) + var/mob/living/L = tgui_input_list(src, "Select a mob to take over:", "Take Over Prey", possible_mobs) + if(!L) return // Adding a ishuman check here, since silicon mobs don't have a resleeve_lock from what I can tell. - if(ishuman(M)) + if(ishuman(L)) + var/mob/living/carbon/human/M = L if(M.resleeve_lock && ckey != M.resleeve_lock) to_chat(src, "\The [M] cannot be impersonated!") return - if(tgui_alert(src, "You selected [M] to attempt to take over. Are you sure?", "Take Over Prey",list("No","Yes")) == "Yes") - log_admin("[key_name_admin(src)] offered [M] to swap bodies as a morph.") - if(tgui_alert(M, "\The [src] has elected to attempt to take over your body and control you. Is this something you will allow to happen?", "Allow Morph To Take Over",list("No","Yes")) == "Yes") - if(tgui_alert(M, "Are you sure? The only way to undo this on your own is to OOC Escape.", "Allow Morph To Take Over",list("No","Yes")) == "Yes") + if(tgui_alert(src, "You selected [L] to attempt to take over. Are you sure?", "Take Over Prey",list("No","Yes")) == "Yes") + log_admin("[key_name_admin(src)] offered [L] to swap bodies as a morph.") + if(tgui_alert(L, "\The [src] has elected to attempt to take over your body and control you. Is this something you will allow to happen?", "Allow Morph To Take Over",list("No","Yes")) == "Yes") + if(tgui_alert(L, "Are you sure? The only way to undo this on your own is to OOC Escape.", "Allow Morph To Take Over",list("No","Yes")) == "Yes") if(buckled) buckled.unbuckle_mob() - if(M.buckled) - M.buckled.unbuckle_mob() + if(L.buckled) + L.buckled.unbuckle_mob() if(LAZYLEN(buckled_mobs)) for(var/buckledmob in buckled_mobs) riding_datum.force_dismount(buckledmob) - if(LAZYLEN(M.buckled_mobs)) - for(var/p_buckledmob in M.buckled_mobs) - M.riding_datum.force_dismount(p_buckledmob) + if(LAZYLEN(L.buckled_mobs)) + for(var/p_buckledmob in L.buckled_mobs) + L.riding_datum.force_dismount(p_buckledmob) if(pulledby) pulledby.stop_pulling() - if(M.pulledby) - M.pulledby.stop_pulling() + if(L.pulledby) + L.pulledby.stop_pulling() stop_pulling() original_ckey = ckey - log_and_message_admins("[key_name_admin(src)] has swapped bodies with [key_name_admin(M)] as a morph at [get_area(src)] - [COORD(src)].") - new /mob/living/simple_mob/vore/morph/dominated_prey(M.vore_selected, M.ckey, src, M) + log_and_message_admins("[key_name_admin(src)] has swapped bodies with [key_name_admin(L)] as a morph at [get_area(src)] - [COORD(src)].") + new /mob/living/simple_mob/vore/morph/dominated_prey(L.vore_selected, L.ckey, src, L) else - to_chat(src, "\The [M] declined your request for control.") + to_chat(src, "\The [L] declined your request for control.") else - to_chat(src, "\The [M] declined your request for control.") + to_chat(src, "\The [L] declined your request for control.") /mob/living/simple_mob/vore/morph/dominated_prey name = "subservient node" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm b/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm index 4ae558a9fd6..aca3e82b3a8 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm @@ -47,6 +47,8 @@ var/tamed = 0 var/tame_chance = 50 //It's a fiddy-fiddy default you may get a buddy pal or you may get mauled and ate. Win-win! + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/otie diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/pakkun.dm b/code/modules/mob/living/simple_mob/subtypes/vore/pakkun.dm index 2ec34f4c3db..78e01d66432 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/pakkun.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/pakkun.dm @@ -58,6 +58,8 @@ maxHealth = 100 health = 100 + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/pakkun/Life() . = ..() if(client) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm index 2a3bf5cf25f..5cdcac41690 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm @@ -42,6 +42,8 @@ say_list_type = /datum/say_list/panther ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/aggressive/panther vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm index e02075c4cbc..baf40f32dd9 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rabbit.dm @@ -43,6 +43,8 @@ vore_default_mode = DM_HOLD vore_icons = SA_ICON_LIVING + allow_mind_transfer = TRUE + var/body_color //brown, black and white, leave blank for random var/grumpiness = 0 // This determines how grumpy we are. Pet us to increase it, leave us alone to decrease. diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/raptor.dm b/code/modules/mob/living/simple_mob/subtypes/vore/raptor.dm index 95769934ee6..5ad3ffd2b8c 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/raptor.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/raptor.dm @@ -48,6 +48,8 @@ "raptorwhite" ) + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/raptor vore_bump_chance = 25 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm index c7e3e71fca8..ea72824e422 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm @@ -70,6 +70,8 @@ say_list_type = /datum/say_list/rat ai_holder_type = /datum/ai_holder/simple_mob/melee/rat + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/aggressive/rat/init_vore() ..() var/obj/belly/B = vore_selected diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm b/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm index 1ab50769eaa..dc989894055 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/redpanda.dm @@ -28,6 +28,8 @@ say_list_type = /datum/say_list/redpanda ai_holder_type = /datum/ai_holder/simple_mob/passive + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/redpanda vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/scel.dm b/code/modules/mob/living/simple_mob/subtypes/vore/scel.dm index 7f58ae433a2..316ae35d285 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/scel.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/scel.dm @@ -56,6 +56,8 @@ "scel_green" ) + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/scel/New() ..() if(random_skin) @@ -75,7 +77,7 @@ vore_icons = SA_ICON_LIVING | SA_ICON_REST vore_capacity = 1 swallowTime = 50 - vore_ignores_undigestable = TRUE + vore_ignores_undigestable = FALSE vore_default_mode = DM_SELECT vore_pounce_maxhealth = 125 vore_bump_emote = "tries to devour" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm b/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm index 36fb413b100..4c8c0b6e47f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/sect_drone.dm @@ -84,6 +84,8 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee say_list_type = /datum/say_list/sect_drone + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/sect_drone/Login() . = ..() verbs |= /mob/living/simple_mob/vore/sect_drone/proc/set_abdomen_color diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm b/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm index bec6074f058..6aed85c9561 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/sect_queen.dm @@ -85,6 +85,8 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee say_list_type = /datum/say_list/sect_queen + allow_mind_transfer = TRUE + /mob/living/simple_mob/vore/sect_queen/Login() . = ..() verbs |= /mob/living/simple_mob/vore/sect_queen/proc/set_abdomen_color diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm index 4b381ec462d..aeba46b1ec4 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm @@ -54,6 +54,8 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/aggressive/giant_snake vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm index 8fe16269765..8cf651e69a6 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub.dm @@ -51,6 +51,7 @@ List of things solar grubs should be able to do: var/shock_chance = 10 // Beware var/tracked = FALSE + allow_mind_transfer = TRUE glow_override = TRUE /datum/say_list/solargrub diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm b/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm index 229e0430eb2..ed1467d2699 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/vore.dm @@ -46,6 +46,7 @@ show_vore_fx = client.prefs_vr.show_vore_fx step_mechanics_pref = client.prefs_vr.step_mechanics_pref pickup_pref = client.prefs_vr.pickup_pref + allow_mind_transfer = client.prefs_vr.allow_mind_transfer /mob/living/simple_mob/proc/set_name() set name = "Set Name" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/weretiger.dm b/code/modules/mob/living/simple_mob/subtypes/vore/weretiger.dm index a98e5592e71..53e68d59a4d 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/weretiger.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/weretiger.dm @@ -31,6 +31,8 @@ has_hands = 1 + allow_mind_transfer = TRUE + // Nomnomn /mob/living/simple_mob/vore/weretiger vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm b/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm index 890ab933c4d..a9d20b8cf9f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/wolf.dm @@ -33,6 +33,8 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive catalogue_data = list(/datum/category_item/catalogue/fauna/wolf) + allow_mind_transfer = TRUE + // Activate Noms! /mob/living/simple_mob/vore/wolf vore_active = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/xeno_vore.dm b/code/modules/mob/living/simple_mob/subtypes/vore/xeno_vore.dm index b09c5c3ff8a..9d673bd73b3 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/xeno_vore.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/xeno_vore.dm @@ -28,7 +28,7 @@ maxHealth = 150 health = 150 see_in_dark = 10 - + //Something something, phoron mutation. min_oxy = 0 max_oxy = 0 @@ -64,5 +64,7 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee say_list_type = /datum/say_list/xeno_defanged + allow_mind_transfer = TRUE + /datum/say_list/xeno_defanged - say_got_target = list("hisses angrily!") \ No newline at end of file + say_got_target = list("hisses angrily!") diff --git a/code/modules/mob/new_player/new_player_vr.dm b/code/modules/mob/new_player/new_player_vr.dm index 0c159d8627c..4306327dbd3 100644 --- a/code/modules/mob/new_player/new_player_vr.dm +++ b/code/modules/mob/new_player/new_player_vr.dm @@ -39,35 +39,35 @@ pass = FALSE to_chat(src,"You have to name your custom species. Do this on the VORE tab in character setup.") - //Check traits/costs - var/list/megalist = client.prefs.pos_traits + client.prefs.neu_traits + client.prefs.neg_traits - var/points_left = client.prefs.starting_trait_points - var/traits_left = client.prefs.max_traits - var/pref_synth = client.prefs.dirty_synth - var/pref_meat = client.prefs.gross_meatbag - for(var/datum/trait/T as anything in megalist) - var/cost = traits_costs[T] + //Check traits/costs + var/list/megalist = client.prefs.pos_traits + client.prefs.neu_traits + client.prefs.neg_traits + var/points_left = client.prefs.starting_trait_points + var/traits_left = client.prefs.max_traits + var/pref_synth = client.prefs.dirty_synth + var/pref_meat = client.prefs.gross_meatbag + for(var/datum/trait/T as anything in megalist) + var/cost = traits_costs[T] - if(cost) - traits_left-- + if(T.category == TRAIT_TYPE_POSITIVE) + traits_left-- - //A trait was removed from the game - if(isnull(cost)) - pass = FALSE - to_chat(src,"Your custom species is not playable. One or more traits appear to have been removed from the game or renamed. Enter character setup to correct this.") - break - else - points_left -= traits_costs[T] - - var/take_flags = initial(T.can_take) - if((pref_synth && !(take_flags & SYNTHETICS)) || (pref_meat && !(take_flags & ORGANICS))) - pass = FALSE - to_chat(src, "Some of your traits are not usable by your character type (synthetic traits on organic, or vice versa).") - - //Went into negatives - if(points_left < 0 || traits_left < 0) + //A trait was removed from the game + if(isnull(cost)) pass = FALSE - to_chat(src,"Your custom species is not playable. Reconfigure your traits on the VORE tab.") + to_chat(src,"Your species is not playable. One or more traits appear to have been removed from the game or renamed. Enter character setup to correct this.") + break + else + points_left -= traits_costs[T] + + var/take_flags = initial(T.can_take) + if((pref_synth && !(take_flags & SYNTHETICS)) || (pref_meat && !(take_flags & ORGANICS))) + pass = FALSE + to_chat(src, "Some of your traits are not usable by your character type (synthetic traits on organic, or vice versa).") + + //Went into negatives + if(points_left < 0 || traits_left < 0) + pass = FALSE + to_chat(src,"Your species is not playable. Reconfigure your traits on the VORE tab. Trait points: [points_left]. Traits left: [traits_left].") //Final popup notice if (!pass) diff --git a/code/modules/mob/new_player/sprite_accessories_tail_vr.dm b/code/modules/mob/new_player/sprite_accessories_tail_vr.dm index 963eed182ab..e38e7a501db 100644 --- a/code/modules/mob/new_player/sprite_accessories_tail_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_tail_vr.dm @@ -1532,3 +1532,21 @@ extra_overlay2 = "kaiju_long_a_spikes_glow" do_colouration = 1 color_blend_mode = ICON_MULTIPLY + +//RS ADD START + +/datum/sprite_accessory/tail/longtail/flagtail + name = "Flagtail" + icon = 'icons/rogue-star/tails_64x32_rs.dmi' + icon_state = "flagtail" + extra_overlay = "flagtail-1" + extra_overlay2 = "flagtail-2" + +/datum/sprite_accessory/tail/longtail/chonksqrl + name = "Squirrel (Big)" + icon = 'icons/rogue-star/tails_64x32_rs.dmi' + icon_state = "chonksqrl" + extra_overlay = "chonksqrl-m1" + extra_overlay2 = "chonksqrl-m2" + +//RS ADD END \ No newline at end of file diff --git a/code/modules/mob/new_player/sprite_accessories_taur.dm b/code/modules/mob/new_player/sprite_accessories_taur.dm index 89a264c82e4..d6758f093ae 100644 --- a/code/modules/mob/new_player/sprite_accessories_taur.dm +++ b/code/modules/mob/new_player/sprite_accessories_taur.dm @@ -363,69 +363,3 @@ /datum/sprite_accessory/tail/taur/zorgoia/fat name = "Zorgoia (Fat Taur)" extra_overlay = "zorgoia_fat" - - -/datum/sprite_accessory/tail/taur/wolf - vore_tail_sprite_variant = "N" - fullness_icons = 3 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/naga/naga_2c - vore_tail_sprite_variant = "Naga" - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/horse - vore_tail_sprite_variant = "Horse" - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/cow - vore_tail_sprite_variant = "Cow" - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/lizard - vore_tail_sprite_variant = "Lizard" - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/lizard/synthlizard - vore_tail_sprite_variant = "SynthLiz" - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/feline - vore_tail_sprite_variant = "Feline" - belly_variant_when_loaf = TRUE - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/slug - vore_tail_sprite_variant = "Slug" - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/drake - vore_tail_sprite_variant = "Drake" - belly_variant_when_loaf = TRUE - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/otie - vore_tail_sprite_variant = "Otie" - belly_variant_when_loaf = TRUE - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/deer - vore_tail_sprite_variant = "Deer" - belly_variant_when_loaf = TRUE - fullness_icons = 1 - struggle_anim = TRUE - -/datum/sprite_accessory/tail/taur/skunk - vore_tail_sprite_variant = "Skunk" - belly_variant_when_loaf = TRUE - fullness_icons = 1 - struggle_anim = TRUE diff --git a/code/modules/mob/new_player/sprite_accessories_taur_vr.dm b/code/modules/mob/new_player/sprite_accessories_taur_vr.dm index 2a85dda15f4..0d9e9a1539f 100644 --- a/code/modules/mob/new_player/sprite_accessories_taur_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_taur_vr.dm @@ -84,22 +84,22 @@ /datum/sprite_accessory/tail/taur/wolf/fatwolf_2c name = "Fat Wolf 3-color (Taur)" - icon = 'icons/mob/vore/taurs_ch.dmi' //CHOMPEdit + icon = 'icons/mob/vore/taurs_ch.dmi' //Ported from Chomp icon_state = "fatwolf_s" extra_overlay = "fatwolf_markings" - extra_overlay2 = "fatwolf_markings_2" //CHOMPEdit + extra_overlay2 = "fatwolf_markings_2" //Ported from Chomp //icon_sprite_tag = "fatwolf2c" loaf_offset = 3 /datum/sprite_accessory/tail/taur/wolf/wolf_2c_wag name = "Wolf 3-color (Taur, Fat vwag)" - icon = 'icons/mob/vore/taurs_ch.dmi' //CHOMPEdit + icon = 'icons/mob/vore/taurs_ch.dmi' //Ported from Chomp icon_state = "wolf_s" extra_overlay = "wolf_markings" extra_overlay2 = "wolf_markings_2" ani_state = "fatwolf_s" extra_overlay_w = "fatwolf_markings" - extra_overlay2_w = "fatwolf_markings_2" //CHOMPEdit + extra_overlay2_w = "fatwolf_markings_2" //Ported from Chomp /datum/sprite_accessory/tail/taur/wolf/synthwolf name = "SynthWolf dual-color (Taur)" @@ -323,7 +323,7 @@ /datum/sprite_accessory/tail/taur/lizard name = "Lizard (Taur)" icon_state = "lizard_s" -// suit_sprites = 'icons/mob/taursuits_lizard_vr.dmi' ///Chomp edit +// suit_sprites = 'icons/mob/taursuits_lizard_vr.dmi' //Ported from Chomp suit_sprites = 'icons/mob/taursuits_lizard_ch.dmi' icon_sprite_tag = "lizard" can_loaf = TRUE @@ -488,10 +488,10 @@ /datum/sprite_accessory/tail/taur/feline/fatfeline_2c name = "Fat Feline 3-color (Taur)" - icon = 'icons/mob/vore/taurs_ch.dmi' //CHOMPEdit + icon = 'icons/mob/vore/taurs_ch.dmi' //Ported from Chomp icon_state = "fatfeline_s" extra_overlay = "fatfeline_markings" - extra_overlay2 = "fatfeline_markings_2" //CHOMPEdit + extra_overlay2 = "fatfeline_markings_2" //Ported from Chomp //icon_sprite_tag = "fatfeline2c" can_loaf = TRUE icon_loaf = 'icons/mob/vore/taurs_vr_loaf.dmi' @@ -499,13 +499,13 @@ /datum/sprite_accessory/tail/taur/feline/feline_2c_wag name = "Feline 3-color (Taur, Fat vwag)" - icon = 'icons/mob/vore/taurs_ch.dmi' //CHOMPEdit + icon = 'icons/mob/vore/taurs_ch.dmi' //Ported from Chomp icon_state = "feline_s" extra_overlay = "feline_markings" extra_overlay2 = "feline_markings_2" ani_state = "fatfeline_s" extra_overlay_w = "fatfeline_markings" - extra_overlay2_w = "fatfeline_markings_2" //CHOMPEdit + extra_overlay2_w = "fatfeline_markings_2" //Ported from Chomp loaf_offset = 3 /datum/sprite_accessory/tail/taur/feline/synthfeline @@ -930,7 +930,7 @@ name = "Fat Sect Drone (Taur)" icon_state = "fat_sect_drone" extra_overlay = "fat_sect_drone_markings" - icon_sprite_tag = "sect_drone" //CHOMPEdit addition + icon_sprite_tag = "sect_drone" //Ported from Chomp /datum/sprite_accessory/tail/taur/sect_drone/drone_wag name = "Sect Drone (Taur, Fat vwag)" @@ -938,7 +938,7 @@ extra_overlay = "sect_drone_markings" ani_state = "fat_sect_drone" extra_overlay_w = "fat_sect_drone_markings" - icon_sprite_tag = "sect_drone" //CHOMPEdit addition + icon_sprite_tag = "sect_drone" //Ported from Chomp /datum/sprite_accessory/tail/taur/giantspider_colorable//these are honestly better fit for vass icontypes whoops name = "Giant Spider dual-color (Taur)" @@ -1119,3 +1119,22 @@ offset_y = -11 mob_offset_y = 11 */ + +//RS ADD START + + +/datum/sprite_accessory/tail/taur/bunny + name = "Bunny (Taur, Fat vwag)" + icon = 'icons/rogue-star/tails_64x32_rs.dmi' + icon_state = "bnytr" + extra_overlay = "bnytr-m1" + extra_overlay2 = "bnytr-m2" + ani_state = "bnytr-f" + extra_overlay_w = "bnytr-m1" + extra_overlay2_w = "bnytr-f-m2" + + can_loaf = TRUE + icon_loaf = 'icons/rogue-star/loafs_64x32.dmi' + loaf_offset = 4 + +//RS ADD END \ No newline at end of file diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index 405cb397182..33a356fb574 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -512,6 +512,15 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ modular_bodyparts = MODULAR_BODYPART_PROSTHETIC parts = list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT) +/datum/robolimb/digi + company = "DSI Digitigrade Legs" //yup that's how I'm fixing this, you NEED to have digi on or else oh god it looks weird + desc = "Synthflesh-wrapped robotic digitigrade legs, for the animal in all of us." + icon = 'icons/mob/human_races/r_digi.dmi' + lifelike = 1 + unavailable_to_build = 1 + skin_tone = 1 + parts = list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT) + /obj/item/weapon/disk/limb/New(var/newloc) ..() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 6c2aafb0c8d..ac6faeb4123 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -658,6 +658,8 @@ if(H.species) P.accuracy += H.species.gun_accuracy_mod P.dispersion = max(P.dispersion + H.species.gun_accuracy_dispersion_mod, 0) + if(H.fear > 30) + P.accuracy -= 35 //does the actual launching of the projectile /obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null) diff --git a/code/modules/reagents/reagents/drugs.dm b/code/modules/reagents/reagents/drugs.dm index 28a42a5b48f..f24d1c8397d 100644 --- a/code/modules/reagents/reagents/drugs.dm +++ b/code/modules/reagents/reagents/drugs.dm @@ -232,6 +232,11 @@ high_message_list = list("Everything feels a bit more steady.", "Your mind feels stable.") sober_message_list = list("You feel a little tired.", "You feel a little more listless...") +/datum/reagent/drugs/citalopram/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + + M.fear = max((M.fear - 3),0) + /datum/reagent/drugs/paroxetine name = "Paroxetine" id = "paroxetine" @@ -243,6 +248,8 @@ /datum/reagent/drugs/paroxetine/affect_blood(mob/living/carbon/M, var/alien, var/removed) ..() + + M.fear = max((M.fear - 6),0) if(prob(5) && prob_proc == TRUE) to_chat(M, "Everything feels out of control...") M.hallucination += 200 diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index b79088238fe..d6224e978e3 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -929,28 +929,35 @@ // 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_messages(raw_text, type, delim = "\n\n") +// Give them a limit for each type... +/obj/belly/proc/set_messages(raw_text, type, delim = "\n\n", limit) + if(!limit) + CRASH("[src] set message called without limit!") ASSERT(type == "smo" || type == "smi" || type == "asmo" || type == "asmi" || type == "escao" || type == "escap" || type == "escp" || type == "esco" || type == "escout" || type == "escip" || type == "escio" || type == "esciout" || type == "escfp" || type == "escfo" || type == "aescao" || type == "aescap" || type == "aescp" || type == "aesco" || type == "aescout" || type == "aescfp" || type == "aescfo" || type == "trnspp" || type == "trnspo" || type == "trnssp" || type == "trnsso" || type == "stmodp" || type == "stmodo" || type == "stmoap" || type == "stmoao" || type == "dmo" || type == "dmp" || type == "amo" || type == "amp" || type == "uamo" || type == "uamp" || type == "em" || type == "ema" || type == "im_digest" || type == "im_hold" || type == "im_holdabsorbed" || type == "im_absorb" || type == "im_heal" || type == "im_drain" || type == "im_steal" || type == "im_egg" || type == "im_shrink" || type == "im_grow" || type == "im_unabsorb") - var/list/raw_list = splittext(html_encode(raw_text),delim) + var/list/raw_list + + if(findtext(raw_text, delim)) + raw_list = splittext(html_encode(raw_text), delim) + else + raw_list = list(raw_text) if(raw_list.len > 10) raw_list.Cut(11) log_debug("[owner] tried to set [lowertext(name)] with 11+ messages") + var/realIndex = 0 for(var/i = 1, i <= raw_list.len, i++) - if((length(raw_list[i]) > 160 || length(raw_list[i]) < 10) && !(type == "im_digest" || type == "im_hold" || type == "im_holdabsorbed" || type == "im_absorb" || type == "im_heal" || type == "im_drain" || type == "im_steal" || type == "im_egg" || type == "im_shrink" || type == "im_grow" || type == "im_unabsorb")) //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 if((type == "im_digest" || type == "im_hold" || type == "im_holdabsorbed" || type == "im_absorb" || type == "im_heal" || type == "im_drain" || type == "im_steal" || type == "im_egg" || type == "im_shrink" || type == "im_grow" || type == "im_unabsorb") && (length(raw_list[i]) > 510 || length(raw_list[i]) < 10)) - raw_list.Cut(i,i) - log_debug("[owner] tried to set [lowertext(name)] idle message with >501 or <10 char message") - else if((type == "em" || type == "ema") && (length(raw_list[i]) > 260 || length(raw_list[i]) < 10)) - raw_list.Cut(i,i) - log_debug("[owner] tried to set [lowertext(name)] examine message with >260 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],"%","%") + realIndex++ + raw_list[i] = readd_quotes(raw_list[i]) + //Also fix % sign for var replacement + raw_list[i] = replacetext(raw_list[i],"%","%") + if(length(raw_list[i]) > limit || length(raw_list[i]) < 10) + to_chat(owner, span_warning("One of the message for [lowertext(name)] exceeded the limit of [limit] characters or has been below the lower limit of 10 characters and has been removed. Actual length: [length(raw_list[i])]")) + //Reflect message to the player so that they don't just lose it + to_chat(owner, span_warning("Message [realIndex]: [raw_list[i]]")) + log_debug("[owner] tried to set [lowertext(name)] [type] message with >[limit] or <10 characters") + raw_list.Cut(i, i + 1) + i-- ASSERT(raw_list.len <= 10) //Sanity diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 447bf1b260e..470c6d9b7c0 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -264,6 +264,7 @@ P.nutrition_messages = src.nutrition_messages P.weight_message_visible = src.weight_message_visible P.weight_messages = src.weight_messages + P.allow_mind_transfer = src.allow_mind_transfer P.vore_sprite_color = istype(src, /mob/living/carbon/human) ? src:vore_sprite_color : null @@ -316,6 +317,7 @@ nutrition_messages = P.nutrition_messages weight_message_visible = P.weight_message_visible weight_messages = P.weight_messages + allow_mind_transfer = P.allow_mind_transfer if (istype(src, /mob/living/carbon/human)) @@ -331,6 +333,78 @@ return TRUE +/mob/proc/load_vore_prefs_from_slot() + + var/datum/preferences/P = client.prefs + + var/remembered_default = P.load_vore_prefs_from_client(src) //Loads the preferences of a chosen slot + if(!remembered_default) + return + + apply_vore_prefs() //Applies the vore preferences of said slot + + if(remembered_default) + P.return_to_character_slot(src, remembered_default) //sets you back to the original default slot + + return TRUE + + +/datum/preferences/proc/load_vore_prefs_from_client(mob/user) + if(selecting_slots) + to_chat(user, "You already have a slot selection dialog open!") + return + var/savefile/S = new /savefile(path) + if(!S) + error("Somehow missing savefile path?! [path]") + return + + var/name + var/nickname //vorestation edit - This set appends nicknames to the save slot + var/list/charlist = list() + var/default //VOREStation edit + for(var/i=1, i<= config.character_slots, i++) + S.cd = "/character[i]" + S["real_name"] >> name + S["nickname"] >> nickname //vorestation edit + if(!name) + name = "[i] - \[Unused Slot\]" + else if(i == default_slot) + name = "â–º[i] - [name]" + else + name = "[i] - [name]" + if (i == default_slot) //VOREStation edit + default = "[name][nickname ? " ([nickname])" : ""]" + charlist["[name][nickname ? " ([nickname])" : ""]"] = i + + var/remember_default = default_slot + + selecting_slots = TRUE + var/choice = tgui_input_list(user, "Select a character to load:", "Load Slot", charlist, default) + selecting_slots = FALSE + if(!choice) + return + + var/slotnum = charlist[choice] + if(!slotnum) + error("Player picked [choice] slot to load, but that wasn't one we sent.") + return + + load_character(slotnum) + attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit + sanitize_preferences() + + return remember_default + +/datum/preferences/proc/return_to_character_slot(mob/user, var/remembered_default) + var/savefile/S = new /savefile(path) + if(!S) + error("Somehow missing savefile path?! [path]") + return + + load_character(remembered_default) + attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit + sanitize_preferences() + // // Release everything in every vore organ // @@ -1135,6 +1209,7 @@ dispvoreprefs += "Food Vore: [food_vore ? "Enabled" : "Disabled"]
" dispvoreprefs += "Inbelly Spawning: [allow_inbelly_spawning ? "Allowed" : "Disallowed"]
" dispvoreprefs += "Spontaneous transformation: [allow_spontaneous_tf ? "Enabled" : "Disabled"]
" + dispvoreprefs += "Mind transfer: [allow_mind_transfer ? "Allowed" : "Disallowed"]
" dispvoreprefs += "Can be stepped on/over: [step_mechanics_pref ? "Allowed" : "Disallowed"]
" dispvoreprefs += "Can be picked up: [pickup_pref ? "Allowed" : "Disallowed"]
" dispvoreprefs += "Global Vore Privacy is: [eating_privacy_global ? "Subtle" : "Loud"]
" diff --git a/code/modules/vore/eating/mob_vr.dm b/code/modules/vore/eating/mob_vr.dm index 7567b3beb36..a49de81205e 100644 --- a/code/modules/vore/eating/mob_vr.dm +++ b/code/modules/vore/eating/mob_vr.dm @@ -27,6 +27,7 @@ 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_mind_transfer = FALSE //Allows ones mind to be taken over or swapped var/nutrition_message_visible = TRUE var/list/nutrition_messages = list( "They are starving! You can hear their stomach snarling from across the room!", diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm index d7fe76ed5a2..3a255108761 100644 --- a/code/modules/vore/eating/vore_vr.dm +++ b/code/modules/vore/eating/vore_vr.dm @@ -70,6 +70,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE var/pickup_pref = TRUE var/vore_sprite_color = list("stomach" = "#000", "taur belly" = "#000") + var/allow_mind_transfer = FALSE var/list/belly_prefs = list() var/vore_taste = "nothing in particular" @@ -196,6 +197,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE weight_messages = json_from_file["weight_messages"] eating_privacy_global = json_from_file["eating_privacy_global"] vore_sprite_color = json_from_file["vore_sprite_color"] + allow_mind_transfer = json_from_file["allow_mind_transfer"] //Quick sanitize if(isnull(digestable)) @@ -284,6 +286,8 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE weight_messages.Add("") if(isnull(vore_sprite_color)) vore_sprite_color = list("stomach" = "#000", "taur belly" = "#000") + if(isnull(allow_mind_transfer)) + allow_mind_transfer = FALSE return TRUE /datum/vore_preferences/proc/save_vore() @@ -317,6 +321,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE "slip_vore" = slip_vore, "stumble_vore" = stumble_vore, "throw_vore" = throw_vore, + "allow_mind_transfer" = allow_mind_transfer, "food_vore" = food_vore, "digest_pain" = digest_pain, "nutrition_message_visible" = nutrition_message_visible, diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index d2286f78b59..3223b50f858 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -335,6 +335,7 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono", "step_mechanics_active" = host.step_mechanics_pref, "pickup_mechanics_active" = host.pickup_pref, "noisy" = host.noisy, + "allow_mind_transfer" = host.allow_mind_transfer, "drop_vore" = host.drop_vore, "slip_vore" = host.slip_vore, "stumble_vore" = host.stumble_vore, @@ -444,6 +445,16 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono", to_chat(usr,"Virgo-specific preferences applied from active slot!") unsaved_changes = FALSE return TRUE + if("loadprefsfromslot") + var/alert = tgui_alert(usr, "Are you sure you want to load another character slot's preferences? This will remove your current vore organs and eject their contents. This will not be immediately saved to your character slot, and you will need to save manually to overwrite your current bellies and preferences.","Confirmation",list("Load","Cancel")) + if(alert != "Load") + return FALSE + if(!host.load_vore_prefs_from_slot()) + tgui_alert_async(usr, "ERROR: Virgo-specific preferences failed to apply!","Error") + else + to_chat(usr,"Virgo-specific preferences applied from active slot!") + unsaved_changes = TRUE + return TRUE if("exportpanel") var/mob/living/user = usr if(!user) @@ -569,6 +580,12 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono", host.client.prefs_vr.pickup_pref = host.pickup_pref unsaved_changes = TRUE return TRUE + if("toggle_allow_mind_transfer") + host.allow_mind_transfer = !host.allow_mind_transfer + if(host.client.prefs_vr) + host.client.prefs_vr.allow_mind_transfer = host.allow_mind_transfer + unsaved_changes = TRUE + return TRUE if("toggle_healbelly") host.permit_healbelly = !host.permit_healbelly if(host.client.prefs_vr) @@ -1070,193 +1087,193 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono", . = TRUE if("b_msgs") if(user.text_warnings) - if(tgui_alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message (250 for examines, 500 for idle messages), max 10 messages per topic.","Really, don't.",list("OK", "Disable Warnings")) == "Disable Warnings") // Should remain tgui_alert() (blocking) + if(tgui_alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max [MAX_MESSAGE_LEN / 4] characters per message ([MAX_MESSAGE_LEN / 2] for examines, [MAX_MESSAGE_LEN / 4] for idle messages), max 10 messages per topic or a total of [MAX_MESSAGE_LEN * 1.5] characters.","Really, don't.",list("OK", "Disable Warnings")) == "Disable Warnings") // Should remain tgui_alert() (blocking) user.text_warnings = FALSE var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name. '%count' will be replaced with the number of anything in your belly. '%countprey' will be replaced with the number of living prey in your belly." switch(params["msgtype"]) if("dmp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they expire. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Digest Message (to prey)",host.vore_selected.get_messages("dmp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they expire. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Digest Message (to prey)",host.vore_selected.get_messages("dmp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"dmp") + host.vore_selected.set_messages(new_message,"dmp", limit = MAX_MESSAGE_LEN / 4) if("dmo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey expires in you. Write them in 2nd person ('you feel X'). Avoid using %pred in this type."+help,"Digest Message (to you)",host.vore_selected.get_messages("dmo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey expires in you. Write them in 2nd person ('you feel X'). Avoid using %pred in this type."+help,"Digest Message (to you)",host.vore_selected.get_messages("dmo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"dmo") + host.vore_selected.set_messages(new_message,"dmo", limit = MAX_MESSAGE_LEN / 4) if("amp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when their absorption finishes. Write them in 2nd person ('you feel X'). Avoid using %prey in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Digest Message (to prey)",host.vore_selected.get_messages("amp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when their absorption finishes. Write them in 2nd person ('you feel X'). Avoid using %prey in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Absorb Message (to prey)",host.vore_selected.get_messages("amp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"amp") + host.vore_selected.set_messages(new_message,"amp", limit = MAX_MESSAGE_LEN / 4) if("amo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey's absorption finishes. Write them in 2nd person ('you feel X'). Avoid using %pred in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Digest Message (to you)",host.vore_selected.get_messages("amo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey's absorption finishes. Write them in 2nd person ('you feel X'). Avoid using %pred in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Absorb Message (to you)",host.vore_selected.get_messages("amo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"amo") + host.vore_selected.set_messages(new_message,"amo", limit = MAX_MESSAGE_LEN / 4) if("uamp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when their unnabsorption finishes. Write them in 2nd person ('you feel X'). Avoid using %prey in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Digest Message (to prey)",host.vore_selected.get_messages("uamp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when their unnabsorption finishes. Write them in 2nd person ('you feel X'). Avoid using %prey in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Unabsorb Message (to prey)",host.vore_selected.get_messages("uamp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"uamp") + host.vore_selected.set_messages(new_message,"uamp", limit = MAX_MESSAGE_LEN / 4) if("uamo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey's unabsorption finishes. Write them in 2nd person ('you feel X'). Avoid using %pred in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Digest Message (to you)",host.vore_selected.get_messages("uamo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey's unabsorption finishes. Write them in 2nd person ('you feel X'). Avoid using %pred in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Unabsorb Message (to you)",host.vore_selected.get_messages("uamo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"uamo") + host.vore_selected.set_messages(new_message,"uamo", limit = MAX_MESSAGE_LEN / 4) if("smo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to those nearby when prey struggles. Write them in 3rd person ('X's Y bulges')."+help,"Struggle Message (outside)",host.vore_selected.get_messages("smo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to those nearby when prey struggles. Write them in 3rd person ('X's Y bulges')."+help,"Struggle Message (outside)",host.vore_selected.get_messages("smo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"smo") + host.vore_selected.set_messages(new_message,"smo", limit = MAX_MESSAGE_LEN / 4) if("smi") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Struggle Message (inside)",host.vore_selected.get_messages("smi"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type."+help,"Struggle Message (inside)",host.vore_selected.get_messages("smi"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"smi") + host.vore_selected.set_messages(new_message,"smi", limit = MAX_MESSAGE_LEN / 4) if("asmo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to those nearby when absorbed prey struggles. Write them in 3rd person ('X's Y bulges'). %count will not work for this type, and %countprey will only count absorbed victims."+help,"Struggle Message (outside)",host.vore_selected.get_messages("asmo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to those nearby when absorbed prey struggles. Write them in 3rd person ('X's Y bulges'). %count will not work for this type, and %countprey will only count absorbed victims."+help,"Absorbed Struggle Message (outside)",host.vore_selected.get_messages("asmo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"asmo") + host.vore_selected.set_messages(new_message,"asmo", limit = MAX_MESSAGE_LEN / 4) if("asmi") - var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Struggle Message (inside)",host.vore_selected.get_messages("asmi"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they struggle. Write them in 2nd person ('you feel X'). Avoid using %prey in this type. %count will not work for this type, and %countprey will only count absorbed victims."+help,"Absorbed Struggle Message (inside)",host.vore_selected.get_messages("asmi"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"asmi") + host.vore_selected.set_messages(new_message,"asmi", limit = MAX_MESSAGE_LEN / 4) if("escap") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they try to escape from within you. Write them in 2nd person ('you start to X')."+help,"Escape Attempt Message (to prey)",host.vore_selected.get_messages("escap"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they try to escape from within you. Write them in 2nd person ('you start to X')."+help,"Escape Attempt Message (to prey)",host.vore_selected.get_messages("escap"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escap") + host.vore_selected.set_messages(new_message,"escap", limit = MAX_MESSAGE_LEN / 4) if("escao") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey tries to escape from within you. Write them in 2nd person ('X ... from your Y')."+help,"Escape Attempt Message (to you)",host.vore_selected.get_messages("escao"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey tries to escape from within you. Write them in 2nd person ('X ... from your Y')."+help,"Escape Attempt Message (to you)",host.vore_selected.get_messages("escao"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escao") + host.vore_selected.set_messages(new_message,"escao", limit = MAX_MESSAGE_LEN / 4) if("escp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they escape from within you. Write them in 2nd person ('you climb out of Y)."+help,"Escape Message (to prey)",host.vore_selected.get_messages("escp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they escape from within you. Write them in 2nd person ('you climb out of Y)."+help,"Escape Message (to prey)",host.vore_selected.get_messages("escp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escp") + host.vore_selected.set_messages(new_message,"escp", limit = MAX_MESSAGE_LEN / 4) if("esco") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey escapes from within you. Write them in 2nd person ('X ... from your Y')."+help,"Escape Message (to you)",host.vore_selected.get_messages("esco"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey escapes from within you. Write them in 2nd person ('X ... from your Y')."+help,"Escape Message (to you)",host.vore_selected.get_messages("esco"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"esco") + host.vore_selected.set_messages(new_message,"esco", limit = MAX_MESSAGE_LEN / 4) if("escout") - var/new_message = sanitize(tgui_input_text(user,"These are sent to those around you when prey escapes from within you. Write them in 3rd person ('X climbs out of Z's Y')."+help,"Escape Message (outside)",host.vore_selected.get_messages("escout"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to those around you when prey escapes from within you. Write them in 3rd person ('X climbs out of Z's Y')."+help,"Escape Message (outside)",host.vore_selected.get_messages("escout"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escout") + host.vore_selected.set_messages(new_message,"escout", limit = MAX_MESSAGE_LEN / 4) if("escip") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they manage to eject an item from within you. Write them in 2nd person ('you manage to O'). Use %item to refer to the ejected item in this type."+help,"Escape Item Message (to prey)",host.vore_selected.get_messages("escip"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they manage to eject an item from within you. Write them in 2nd person ('you manage to O'). Use %item to refer to the ejected item in this type."+help,"Escape Item Message (to prey)",host.vore_selected.get_messages("escip"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escip") + host.vore_selected.set_messages(new_message,"escip", limit = MAX_MESSAGE_LEN / 4) if("escio") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey manages to eject an item from within you. Write them in 2nd person ('O slips from Y'). Use %item to refer to the ejected item in this type."+help,"Escape Item Message (to you)",host.vore_selected.get_messages("escio"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey manages to eject an item from within you. Write them in 2nd person ('O slips from Y'). Use %item to refer to the ejected item in this type."+help,"Escape Item Message (to you)",host.vore_selected.get_messages("escio"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escio") + host.vore_selected.set_messages(new_message,"escio", limit = MAX_MESSAGE_LEN / 4) if("esciout") - var/new_message = sanitize(tgui_input_text(user,"These are sent to those around you when prey manages to eject an item from within you. Write them in 3rd person ('O from Y'). Use %item to refer to the ejected item in this type."+help,"Escape Item Message (outside)",host.vore_selected.get_messages("esciout"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to those around you when prey manages to eject an item from within you. Write them in 3rd person ('O from Y'). Use %item to refer to the ejected item in this type."+help,"Escape Item Message (outside)",host.vore_selected.get_messages("esciout"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"esciout") + host.vore_selected.set_messages(new_message,"esciout", limit = MAX_MESSAGE_LEN / 4) if("escfp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they fail to escape from within you. Write them in 2nd person ('you failed to Y')."+help,"Escape Fail Message (to prey)",host.vore_selected.get_messages("escfp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they fail to escape from within you. Write them in 2nd person ('you failed to Y')."+help,"Escape Fail Message (to prey)",host.vore_selected.get_messages("escfp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escfp") + host.vore_selected.set_messages(new_message,"escfp", limit = MAX_MESSAGE_LEN / 4) if("escfo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey fails to escape from within you. Write them in 2nd person ('X failed ... your Y')."+help,"Escape Fail Message (to you)",host.vore_selected.get_messages("escfo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey fails to escape from within you. Write them in 2nd person ('X failed ... your Y')."+help,"Escape Fail Message (to you)",host.vore_selected.get_messages("escfo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"escfo") + host.vore_selected.set_messages(new_message,"escfo", limit = MAX_MESSAGE_LEN / 4) if("aescap") - var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they try to escape from within you. Write them in 2nd person ('you start to X')."+help,"Absorbed Escape Attempt Message (to prey)",host.vore_selected.get_messages("aescap"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they try to escape from within you. Write them in 2nd person ('you start to X')."+help,"Absorbed Escape Attempt Message (to prey)",host.vore_selected.get_messages("aescap"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aescap") + host.vore_selected.set_messages(new_message,"aescap", limit = MAX_MESSAGE_LEN / 4) if("aescao") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when absorbed prey tries to escape from within you. Write them in 2nd person ('X ... from your Y')."+help,"Absorbed Escape Attempt Message (to you)",host.vore_selected.get_messages("aescao"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when absorbed prey tries to escape from within you. Write them in 2nd person ('X ... from your Y')."+help,"Absorbed Escape Attempt Message (to you)",host.vore_selected.get_messages("aescao"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aescao") + host.vore_selected.set_messages(new_message,"aescao", limit = MAX_MESSAGE_LEN / 4) if("aescp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they escape from within you. Write them in 2nd person ('you escape from Y')."+help,"Absorbed Escape Message (to prey)",host.vore_selected.get_messages("aescp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they escape from within you. Write them in 2nd person ('you escape from Y')."+help,"Absorbed Escape Message (to prey)",host.vore_selected.get_messages("aescp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aescp") + host.vore_selected.set_messages(new_message,"aescp", limit = MAX_MESSAGE_LEN / 4) if("aesco") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when absorbed prey escapes from within you. Write them in 2nd person ('X ... from your Y')."+help,"Absorbed Escape Message (to you)",host.vore_selected.get_messages("aesco"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when absorbed prey escapes from within you. Write them in 2nd person ('X ... from your Y')."+help,"Absorbed Escape Message (to you)",host.vore_selected.get_messages("aesco"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aesco") + host.vore_selected.set_messages(new_message,"aesco", limit = MAX_MESSAGE_LEN / 4) if("aescout") - var/new_message = sanitize(tgui_input_text(user,"These are sent to those around you when absorbed prey escapes from within you. Write them in 3rd person ('X escapes from Z's Y')."+help,"Absorbed Escape Message (outside)",host.vore_selected.get_messages("aescout"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to those around you when absorbed prey escapes from within you. Write them in 3rd person ('X escapes from Z's Y')."+help,"Absorbed Escape Message (outside)",host.vore_selected.get_messages("aescout"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aescout") + host.vore_selected.set_messages(new_message,"aescout", limit = MAX_MESSAGE_LEN / 4) if("aescfp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they fail to escape from within you. Write them in 2nd person ('you failed to Y')."+help,"Absorbed Escape Fail Message (to prey)",host.vore_selected.get_messages("aescfp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to absorbed prey when they fail to escape from within you. Write them in 2nd person ('you failed to Y')."+help,"Absorbed Escape Fail Message (to prey)",host.vore_selected.get_messages("aescfp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aescfp") + host.vore_selected.set_messages(new_message,"aescfp", limit = MAX_MESSAGE_LEN / 4) if("aescfo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when absorbed prey fails to escape from within you. Write them in 2nd person ('X failed ... your Y')."+help,"Absorbed Escape Fail Message (to you)",host.vore_selected.get_messages("aescfo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when absorbed prey fails to escape from within you. Write them in 2nd person ('X failed ... your Y')."+help,"Absorbed Escape Fail Message (to you)",host.vore_selected.get_messages("aescfo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"aescfo") + host.vore_selected.set_messages(new_message,"aescfo", limit = MAX_MESSAGE_LEN / 4) if("trnspp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they are automatically transferred into your primary destination. Write them in 2nd person ('you slide into Y'). Use %dest to refer to the target location in this type."+help,"Primary Transfer Message (to prey)",host.vore_selected.get_messages("trnspp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they are automatically transferred into your primary destination. Write them in 2nd person ('you slide into Y'). Use %dest to refer to the target location in this type."+help,"Primary Transfer Message (to prey)",host.vore_selected.get_messages("trnspp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"trnspp") + host.vore_selected.set_messages(new_message,"trnspp", limit = MAX_MESSAGE_LEN / 4) if("trnspo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey is automatically transferred into your primary destination. Write them in 2nd person ('X slid into your Y'). Use %dest to refer to the target location in this type."+help,"Primary Transfer Message (to you)",host.vore_selected.get_messages("trnspo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey is automatically transferred into your primary destination. Write them in 2nd person ('X slid into your Y'). Use %dest to refer to the target location in this type."+help,"Primary Transfer Message (to you)",host.vore_selected.get_messages("trnspo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"trnspo") + host.vore_selected.set_messages(new_message,"trnspo", limit = MAX_MESSAGE_LEN / 4) if("trnssp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they are automatically transferred into your secondary destination. Write them in 2nd person ('you slide into Y'). Use %dest to refer to the target location in this type."+help,"Secondary Transfer Message (to prey)",host.vore_selected.get_messages("trnssp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they are automatically transferred into your secondary destination. Write them in 2nd person ('you slide into Y'). Use %dest to refer to the target location in this type."+help,"Secondary Transfer Message (to prey)",host.vore_selected.get_messages("trnssp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"trnssp") + host.vore_selected.set_messages(new_message,"trnssp", limit = MAX_MESSAGE_LEN / 4) if("trnsso") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey is automatically transferred into your primary destination. Write them in 2nd person ('X slid into your Y'). Use %dest to refer to the target location in this type."+help,"Secondary Transfer Message (to you)",host.vore_selected.get_messages("trnsso"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey is automatically transferred into your primary destination. Write them in 2nd person ('X slid into your Y'). Use %dest to refer to the target location in this type."+help,"Secondary Transfer Message (to you)",host.vore_selected.get_messages("trnsso"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"trnsso") + host.vore_selected.set_messages(new_message,"trnsso", limit = MAX_MESSAGE_LEN / 4) if("stmodp") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they trigger the interaction digest chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to prey)",host.vore_selected.get_messages("stmodp"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they trigger the interaction digest chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to prey)",host.vore_selected.get_messages("stmodp"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"stmodp") + host.vore_selected.set_messages(new_message,"stmodp", limit = MAX_MESSAGE_LEN / 4) if("stmodo") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey triggers the interaction digest chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to you)",host.vore_selected.get_messages("stmodo"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey triggers the interaction digest chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to you)",host.vore_selected.get_messages("stmodo"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"stmodo") + host.vore_selected.set_messages(new_message,"stmodo", limit = MAX_MESSAGE_LEN / 4) if("stmoap") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they trigger the interaction absorb chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to prey)",host.vore_selected.get_messages("stmoap"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey when they trigger the interaction absorb chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to prey)",host.vore_selected.get_messages("stmoap"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"stmoap") + host.vore_selected.set_messages(new_message,"stmoap", limit = MAX_MESSAGE_LEN / 4) if("stmoao") - var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey triggers the interaction absorb chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to you)",host.vore_selected.get_messages("stmoao"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to you when prey triggers the interaction absorb chance. Write them in 2nd person ('you feel X')."+help,"Stomach Mode Digest Message (to you)",host.vore_selected.get_messages("stmoao"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"stmoao") + host.vore_selected.set_messages(new_message,"stmoao", limit = MAX_MESSAGE_LEN / 4) if("em") - var/new_message = sanitize(tgui_input_text(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging')."+help,"Examine Message (when full)",host.vore_selected.get_messages("em"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging')."+help,"Examine Message (when full)",host.vore_selected.get_messages("em"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"em") + host.vore_selected.set_messages(new_message,"em", limit = MAX_MESSAGE_LEN / 2) if("ema") - var/new_message = sanitize(tgui_input_text(user,"These are sent to people who examine you when this belly has absorbed victims. Write them in 3rd person ('Their %belly is larger'). %count will not work for this type, and %countprey will only count absorbed victims."+help,"Examine Message (with absorbed victims)",host.vore_selected.get_messages("ema"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to people who examine you when this belly has absorbed victims. Write them in 3rd person ('Their %belly is larger'). %count will not work for this type, and %countprey will only count absorbed victims."+help,"Examine Message (with absorbed victims)",host.vore_selected.get_messages("ema"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"ema") + host.vore_selected.set_messages(new_message,"ema", limit = MAX_MESSAGE_LEN / 2) if("en") var/list/indices = list(1,2,3,4,5,6,7,8,9,10) @@ -1285,59 +1302,59 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono", host.weight_messages[index] = new_message if("im_digest") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Digest mode. Write them in 2nd person ('%pred's %belly squishes down on you.')."+help,"Idle Message (Digest)",host.vore_selected.get_messages("im_digest"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Digest mode. Write them in 2nd person ('%pred's %belly squishes down on you.')."+help,"Idle Message (Digest)",host.vore_selected.get_messages("im_digest"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_digest") + host.vore_selected.set_messages(new_message,"im_digest", limit = MAX_MESSAGE_LEN / 4) if("im_hold") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Hold mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Hold)",host.vore_selected.get_messages("im_hold"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Hold mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Hold)",host.vore_selected.get_messages("im_hold"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_hold") + host.vore_selected.set_messages(new_message,"im_hold", limit = MAX_MESSAGE_LEN / 4) if("im_holdabsorbed") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are absorbed. Write them in 2nd person ('%pred's %belly squishes down on you.') %count will not work for this type, and %countprey will only count absorbed victims."+help,"Idle Message (Hold Absorbed)",host.vore_selected.get_messages("im_holdabsorbed"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are absorbed. Write them in 2nd person ('%pred's %belly squishes down on you.') %count will not work for this type, and %countprey will only count absorbed victims."+help,"Idle Message (Hold Absorbed)",host.vore_selected.get_messages("im_holdabsorbed"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_holdabsorbed") + host.vore_selected.set_messages(new_message,"im_holdabsorbed", limit = MAX_MESSAGE_LEN / 4) if("im_absorb") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Absorb mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Absorb)",host.vore_selected.get_messages("im_absorb"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Absorb mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Absorb)",host.vore_selected.get_messages("im_absorb"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_absorb") + host.vore_selected.set_messages(new_message,"im_absorb", limit = MAX_MESSAGE_LEN / 4) if("im_heal") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Heal mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Heal)",host.vore_selected.get_messages("im_heal"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Heal mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Heal)",host.vore_selected.get_messages("im_heal"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_heal") + host.vore_selected.set_messages(new_message,"im_heal", limit = MAX_MESSAGE_LEN / 4) if("im_drain") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Drain mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Drain)",host.vore_selected.get_messages("im_drain"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Drain mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Drain)",host.vore_selected.get_messages("im_drain"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_drain") + host.vore_selected.set_messages(new_message,"im_drain", limit = MAX_MESSAGE_LEN / 4) if("im_steal") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Size Steal mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Size Steal)",host.vore_selected.get_messages("im_steal"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Size Steal mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Size Steal)",host.vore_selected.get_messages("im_steal"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_steal") + host.vore_selected.set_messages(new_message,"im_steal", limit = MAX_MESSAGE_LEN / 4) if("im_egg") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Encase In Egg mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Encase In Egg)",host.vore_selected.get_messages("im_egg"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Encase In Egg mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Encase In Egg)",host.vore_selected.get_messages("im_egg"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_egg") + host.vore_selected.set_messages(new_message,"im_egg", limit = MAX_MESSAGE_LEN / 4) if("im_shrink") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Shrink mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Shrink)",host.vore_selected.get_messages("im_shrink"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Shrink mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Shrink)",host.vore_selected.get_messages("im_shrink"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_shrink") + host.vore_selected.set_messages(new_message,"im_shrink", limit = MAX_MESSAGE_LEN / 4) if("im_grow") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Grow mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Grow)",host.vore_selected.get_messages("im_grow"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Grow mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Grow)",host.vore_selected.get_messages("im_grow"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_grow") + host.vore_selected.set_messages(new_message,"im_grow", limit = MAX_MESSAGE_LEN / 4) if("im_unabsorb") - var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Unabsorb mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Unabsorb)",host.vore_selected.get_messages("im_unabsorb"), multiline = TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN,0,0,0) + var/new_message = sanitize(tgui_input_text(user,"These are sent to prey every [host.vore_selected.emote_time] seconds when you are on Unabsorb mode. Write them in 2nd person ('%pred's %belly squishes down on you.')"+help,"Idle Message (Unabsorb)",host.vore_selected.get_messages("im_unabsorb"), MAX_MESSAGE_LEN * 1.5, TRUE, prevent_enter = TRUE),MAX_MESSAGE_LEN * 1.5,0,0,0) if(new_message) - host.vore_selected.set_messages(new_message,"im_unabsorb") + host.vore_selected.set_messages(new_message,"im_unabsorb", limit = MAX_MESSAGE_LEN / 4) if("reset") var/confirm = tgui_alert(user,"This will delete any custom messages. Are you sure?","Confirmation",list("Cancel","DELETE")) diff --git a/code/modules/vore/mouseray.dm b/code/modules/vore/mouseray.dm index 3e3ead048e2..997f79d67a8 100644 --- a/code/modules/vore/mouseray.dm +++ b/code/modules/vore/mouseray.dm @@ -250,6 +250,7 @@ new_mob.allow_spontaneous_tf = allow_spontaneous_tf new_mob.eating_privacy_global = eating_privacy_global new_mob.text_warnings = text_warnings + new_mob.allow_mind_transfer = allow_mind_transfer /////SUBTYPES///// diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen_full.dmi index e8602a41ced..14d3b54d9fc 100644 Binary files a/icons/mob/screen_full.dmi and b/icons/mob/screen_full.dmi differ diff --git a/icons/mob/vore.dmi b/icons/mob/vore.dmi index e11ef54c8d7..a0842ddb42b 100644 Binary files a/icons/mob/vore.dmi and b/icons/mob/vore.dmi differ diff --git a/icons/rogue-star/loafs_64x32.dmi b/icons/rogue-star/loafs_64x32.dmi new file mode 100644 index 00000000000..23ee1451944 Binary files /dev/null and b/icons/rogue-star/loafs_64x32.dmi differ diff --git a/icons/rogue-star/tails_64x32_rs.dmi b/icons/rogue-star/tails_64x32_rs.dmi new file mode 100644 index 00000000000..72dac326eec Binary files /dev/null and b/icons/rogue-star/tails_64x32_rs.dmi differ diff --git a/tgui/package.json b/tgui/package.json index bb59cc24c74..332f0ec273d 100644 --- a/tgui/package.json +++ b/tgui/package.json @@ -50,7 +50,7 @@ "swc-loader": "^0.2.6", "typescript": "^5.4.3", "url-loader": "^4.1.1", - "webpack": "^5.91.0", + "webpack": "^5.94.0", "webpack-bundle-analyzer": "^4.10.1", "webpack-cli": "^5.1.4" } diff --git a/tgui/packages/tgui-dev-server/package.json b/tgui/packages/tgui-dev-server/package.json index 3a92ec35c95..aaa72cdcd8e 100644 --- a/tgui/packages/tgui-dev-server/package.json +++ b/tgui/packages/tgui-dev-server/package.json @@ -4,7 +4,7 @@ "version": "5.0.1", "type": "module", "dependencies": { - "axios": "^1.6.8", + "axios": "^1.7.4", "glob": "^7.2.3", "source-map": "^0.7.4", "stacktrace-parser": "^0.1.10", diff --git a/tgui/packages/tgui/components/DraggableControl.jsx b/tgui/packages/tgui/components/DraggableControl.jsx index bb55287b02a..86287c940d5 100644 --- a/tgui/packages/tgui/components/DraggableControl.jsx +++ b/tgui/packages/tgui/components/DraggableControl.jsx @@ -137,12 +137,10 @@ export class DraggableControl extends Component { } else if (this.inputRef) { const input = this.inputRef.current; input.value = internalValue; - // IE8: Dies when trying to focus a hidden element - // (Error: Object does not support this action) - try { + setTimeout(() => { input.focus(); input.select(); - } catch {} + }, 100); } }; } diff --git a/tgui/packages/tgui/components/NumberInput.tsx b/tgui/packages/tgui/components/NumberInput.tsx index 85971120b0a..858874e9026 100644 --- a/tgui/packages/tgui/components/NumberInput.tsx +++ b/tgui/packages/tgui/components/NumberInput.tsx @@ -174,12 +174,10 @@ export class NumberInput extends Component { } else if (this.inputRef) { const input = this.inputRef.current!; input.value = String(internalValue); - // IE8: Dies when trying to focus a hidden element - // (Error: Object does not support this action) - try { + setTimeout(() => { input.focus(); input.select(); - } catch {} + }, 100); } }; } diff --git a/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenu.tsx b/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenu.tsx index 5ccc1ce104f..7a844408261 100644 --- a/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenu.tsx +++ b/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenu.tsx @@ -17,7 +17,7 @@ export const SupplyConsoleMenu = (props) => { tab[4] = ; return ( -
+
{ } return ( -
+
{receipts.map((r, ri) => (
diff --git a/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenuOrderList.tsx b/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenuOrderList.tsx index 7c2fe705910..88ad5829102 100644 --- a/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenuOrderList.tsx +++ b/tgui/packages/tgui/interfaces/SupplyConsole/SupplyConsoleMenuOrderList.tsx @@ -16,7 +16,7 @@ export const SupplyConsoleMenuOrderList = (props) => { } return ( -
+
{mode === 'Requested' && order_auth ? ( + + - - - - - - - - - - - - {message_mode || escapable ? ( - <> - - + {release_verb} + + + + + + + + + + {message_mode || escapable ? ( + <> + + + {(message_mode || + !!interacts.transferlocation || + !!interacts.transferlocation_secondary) && ( + + )} + {(message_mode || + interacts.digestchance > 0 || + interacts.absorbchance > 0) && ( + + )} + + ) : ( + '' + )} + {(message_mode || + mode === 'Digest' || + mode === 'Selective' || + mode === 'Absorb' || + mode === 'Unabsorb') && ( + - {(message_mode || - !!interacts.transferlocation || - !!interacts.transferlocation_secondary) && ( - - )} - {(message_mode || - interacts.digestchance > 0 || - interacts.absorbchance > 0) && ( - - )} - - ) : ( - '' - )} - {(message_mode || - mode === 'Digest' || - mode === 'Selective' || - mode === 'Absorb' || - mode === 'Unabsorb') && ( - - )} - {emote_active ? ( - - ) : ( - '' - )} - + )} + {emote_active ? ( + + ) : ( + '' + )} + + + + + + Description:{' '} - - + + + + Description (Absorbed):{' '} + + + + + ); }; diff --git a/tgui/packages/tgui/interfaces/VorePanel/VoreSelectedBellyTabs/VoreSelectedBellyVisuals.tsx b/tgui/packages/tgui/interfaces/VorePanel/VoreSelectedBellyTabs/VoreSelectedBellyVisuals.tsx index 763daa2e0d2..c0afa7fd392 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/VoreSelectedBellyTabs/VoreSelectedBellyVisuals.tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/VoreSelectedBellyTabs/VoreSelectedBellyVisuals.tsx @@ -1,7 +1,14 @@ import { classes } from 'common/react'; import { useBackend } from '../../../backend'; -import { Box, Button, Flex, LabeledList, Section } from '../../../components'; +import { + Box, + Button, + Flex, + LabeledList, + Section, + Stack, +} from '../../../components'; import { selectedData } from '../types'; export const VoreSelectedBellyVisuals = (props: { belly: selectedData }) => { @@ -211,85 +218,104 @@ export const VoreSelectedBellyVisuals = (props: { belly: selectedData }) => {
- - - - - - - - + + + + + - - - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + +
@@ -307,7 +333,7 @@ export const VoreSelectedBellyVisuals = (props: { belly: selectedData }) => {
-
+
Belly styles: +
diff --git a/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical .tsx b/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical .tsx index 21d32e32fdb..8433d9dab9a 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical .tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/VoreUserPreferencesTabs/VoreUserPreferencesMechanical .tsx @@ -112,7 +112,10 @@ export const VoreUserPreferencesMechanical = (props: { Selective Mode Preference - + + + + diff --git a/tgui/packages/tgui/interfaces/VorePanel/constants.ts b/tgui/packages/tgui/interfaces/VorePanel/constants.ts index b87bf1be2e1..0eea572af9a 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/constants.ts +++ b/tgui/packages/tgui/interfaces/VorePanel/constants.ts @@ -27,3 +27,10 @@ export const digestModeToPreyMode = { Heal: 'being healed.', 'Encase In Egg': 'being encased in an egg.', }; + +export const SYNTAX_REGEX = /%belly|%pred|%prey/g; +export const SYNTAX_COLOR = { + '%belly': 'average', + '%pred': 'bad', + '%prey': 'good', +}; diff --git a/tgui/packages/tgui/interfaces/VorePanel/index.tsx b/tgui/packages/tgui/interfaces/VorePanel/index.tsx index e285075fa3d..7e5bdfe4825 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/index.tsx +++ b/tgui/packages/tgui/interfaces/VorePanel/index.tsx @@ -37,7 +37,7 @@ export const VorePanel = (props) => { return ( - + {(data.unsaved_changes && ( diff --git a/tgui/packages/tgui/interfaces/VorePanel/types.ts b/tgui/packages/tgui/interfaces/VorePanel/types.ts index 9d62b52dcb8..508d0fb6f00 100644 --- a/tgui/packages/tgui/interfaces/VorePanel/types.ts +++ b/tgui/packages/tgui/interfaces/VorePanel/types.ts @@ -160,6 +160,7 @@ export type prefData = { step_mechanics_active: BooleanLike; pickup_mechanics_active: BooleanLike; noisy: BooleanLike; + allow_mind_transfer: BooleanLike; drop_vore: BooleanLike; slip_vore: BooleanLike; stumble_vore: BooleanLike; @@ -198,6 +199,7 @@ export type localPrefs = { remains: preferenceData; pickuppref: preferenceData; spontaneous_tf: preferenceData; + mind_transfer: preferenceData; examine_nutrition: preferenceData; examine_weight: preferenceData; eating_privacy_global: preferenceData; diff --git a/tgui/public/tgui-panel.bundle.js b/tgui/public/tgui-panel.bundle.js index fbad176d862..0977b15185b 100644 --- a/tgui/public/tgui-panel.bundle.js +++ b/tgui/public/tgui-panel.bundle.js @@ -6,7 +6,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */function r(e,n){return n!=null&&typeof Symbol!="undefined"&&n[Symbol.hasInstance]?!!n[Symbol.hasInstance](e):e instanceof n}function o(e){"@swc/helpers - typeof";return e&&typeof Symbol!="undefined"&&e.constructor===Symbol?"symbol":typeof e}var i=t(61358),s=t(20686);function u(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,a=1;an}return!1}function j(e,n,a,c,O,M,$){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=c,this.attributeNamespace=O,this.mustUseProperty=a,this.propertyName=e,this.type=n,this.sanitizeURL=M,this.removeEmptyString=$}var B={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){B[e]=new j(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];B[n]=new j(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){B[e]=new j(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){B[e]=new j(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){B[e]=new j(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){B[e]=new j(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){B[e]=new j(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){B[e]=new j(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){B[e]=new j(e,5,!1,e.toLowerCase(),null,!1,!1)});var F=/[\-:]([a-z])/g;function C(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(F,C);B[n]=new j(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(F,C);B[n]=new j(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(F,C);B[n]=new j(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){B[e]=new j(e,1,!1,e.toLowerCase(),null,!1,!1)}),B.xlinkHref=new j("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){B[e]=new j(e,1,!1,e.toLowerCase(),null,!0,!0)});function N(e,n,a,c){var O=B.hasOwnProperty(n)?B[n]:null;(O!==null?O.type!==0:c||!(2X||O[$]!==M[X]){var dt="\n"+O[$].replace(" at new "," at ");return e.displayName&&dt.includes("")&&(dt=dt.replace("",e.displayName)),dt}while(1<=$&&0<=X);break}}}finally{vt=!1,Error.prepareStackTrace=a}return(e=e?e.displayName||e.name:"")?nt(e):""}function bt(e){switch(e.tag){case 5:return nt(e.type);case 16:return nt("Lazy");case 13:return nt("Suspense");case 19:return nt("SuspenseList");case 0:case 2:case 15:return e=mt(e.type,!1),e;case 11:return e=mt(e.type.render,!1),e;case 1:return e=mt(e.type,!0),e;default:return""}}function gt(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case K:return"Fragment";case z:return"Portal";case J:return"Profiler";case k:return"StrictMode";case ct:return"Suspense";case ot:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case _:return(e.displayName||"Context")+".Consumer";case G:return(e._context.displayName||"Context")+".Provider";case Q:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ut:return n=e.displayName||null,n!==null?n:gt(e.type)||"Memo";case W:n=e._payload,e=e._init;try{return gt(e(n))}catch(a){}}return null}function pt(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return gt(n);case 8:return n===k?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Dt(e){switch(typeof e=="undefined"?"undefined":o(e)){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ve(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function fe(e){var n=ve(e)?"checked":"value",a=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),c=""+e[n];if(!e.hasOwnProperty(n)&&typeof a!="undefined"&&typeof a.get=="function"&&typeof a.set=="function"){var O=a.get,M=a.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return O.call(this)},set:function(X){c=""+X,M.call(this,X)}}),Object.defineProperty(e,n,{enumerable:a.enumerable}),{getValue:function(){return c},setValue:function(X){c=""+X},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function Jt(e){e._valueTracker||(e._valueTracker=fe(e))}function Ct(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var a=n.getValue(),c="";return e&&(c=ve(e)?e.checked?"true":"false":e.value),e=c,e!==a?(n.setValue(e),!0):!1}function Nt(e){if(e=e||(typeof document!="undefined"?document:void 0),typeof e=="undefined")return null;try{return e.activeElement||e.body}catch(n){return e.body}}function Wt(e,n){var a=n.checked;return Z({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a!=null?a:e._wrapperState.initialChecked})}function zt(e,n){var a=n.defaultValue==null?"":n.defaultValue,c=n.checked!=null?n.checked:n.defaultChecked;a=Dt(n.value!=null?n.value:a),e._wrapperState={initialChecked:c,initialValue:a,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function ae(e,n){n=n.checked,n!=null&&N(e,"checked",n,!1)}function ie(e,n){ae(e,n);var a=Dt(n.value),c=n.type;if(a!=null)c==="number"?(a===0&&e.value===""||e.value!=a)&&(e.value=""+a):e.value!==""+a&&(e.value=""+a);else if(c==="submit"||c==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?Ft(e,n.type,a):n.hasOwnProperty("defaultValue")&&Ft(e,n.type,Dt(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function te(e,n,a){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var c=n.type;if(!(c!=="submit"&&c!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,a||n===e.value||(e.value=n),e.defaultValue=n}a=e.name,a!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,a!==""&&(e.name=a)}function Ft(e,n,a){(n!=="number"||Nt(e.ownerDocument)!==e)&&(a==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+a&&(e.defaultValue=""+a))}var Bt=Array.isArray;function At(e,n,a,c){if(e=e.options,n){n={};for(var O=0;O"+n.valueOf().toString()+"",n=Se.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function le(e,n){if(n){var a=e.firstChild;if(a&&a===e.lastChild&&a.nodeType===3){a.nodeValue=n;return}}e.textContent=n}var $t={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Gt=["Webkit","ms","Moz","O"];Object.keys($t).forEach(function(e){Gt.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),$t[n]=$t[e]})});function Me(e,n,a){return n==null||typeof n=="boolean"||n===""?"":a||typeof n!="number"||n===0||$t.hasOwnProperty(e)&&$t[e]?(""+n).trim():n+"px"}function Ze(e,n){e=e.style;for(var a in n)if(n.hasOwnProperty(a)){var c=a.indexOf("--")===0,O=Me(a,n[a],c);a==="float"&&(a="cssFloat"),c?e.setProperty(a,O):e[a]=O}}var tr=Z({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function fn(e,n){if(n){if(tr[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(u(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(u(60));if(typeof n.dangerouslySetInnerHTML!="object"||!("__html"in n.dangerouslySetInnerHTML))throw Error(u(61))}if(n.style!=null&&typeof n.style!="object")throw Error(u(62))}}function Un(e,n){if(e.indexOf("-")===-1)return typeof n.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Pn=null;function cr(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var rt=null,xt=null,st=null;function yt(e){if(e=Ma(e)){if(typeof rt!="function")throw Error(u(280));var n=e.stateNode;n&&(n=ja(n),rt(e.stateNode,e.type,n))}}function Tt(e){xt?st?st.push(e):st=[e]:xt=e}function Lt(){if(xt){var e=xt,n=st;if(st=xt=null,yt(e),n)for(e=0;e>>=0,e===0?32:31-(Dn(e)/Er|0)|0}var er=64,hn=4194304;function pr(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Ln(e,n){var a=e.pendingLanes;if(a===0)return 0;var c=0,O=e.suspendedLanes,M=e.pingedLanes,$=a&268435455;if($!==0){var X=$&~O;X!==0?c=pr(X):(M&=$,M!==0&&(c=pr(M)))}else $=a&~O,$!==0?c=pr($):M!==0&&(c=pr(M));if(c===0)return 0;if(n!==0&&n!==c&&!(n&O)&&(O=c&-c,M=n&-n,O>=M||O===16&&(M&4194240)!==0))return n;if(c&4&&(c|=a&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=c;0a;a++)n.push(e);return n}function Bn(e,n,a){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-On(n),e[n]=a}function To(e,n){var a=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var c=e.eventTimes;for(e=e.expirationTimes;0=_a),Pi=" ",Ci=!1;function ms(e,n){switch(e){case"keyup":return mu.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function gs(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var so=!1;function ys(e,n){switch(e){case"compositionend":return gs(n);case"keypress":return n.which!==32?null:(Ci=!0,Pi);case"textInput":return e=n.data,e===Pi&&Ci?null:e;default:return null}}function xs(e,n){if(so)return e==="compositionend"||!Ai&&ms(e,n)?(e=gn(),be=se=Vt=null,so=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:a,offset:n-e};e=c}t:{for(;a;){if(a.nextSibling){a=a.nextSibling;break t}a=a.parentNode}a=void 0}a=Es(a)}}function Sa(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?Sa(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function Ts(){for(var e=window,n=Nt();r(n,e.HTMLIFrameElement);){try{var a=typeof n.contentWindow.location.href=="string"}catch(c){a=!1}if(a)e=n.contentWindow;else break;n=Nt(e.document)}return n}function Ni(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}function na(e){var n=Ts(),a=e.focusedElem,c=e.selectionRange;if(n!==a&&a&&a.ownerDocument&&Sa(a.ownerDocument.documentElement,a)){if(c!==null&&Ni(a)){if(n=c.start,e=c.end,e===void 0&&(e=n),"selectionStart"in a)a.selectionStart=n,a.selectionEnd=Math.min(e,a.value.length);else if(e=(n=a.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var O=a.textContent.length,M=Math.min(c.start,O);c=c.end===void 0?M:Math.min(c.end,O),!e.extend&&M>c&&(O=c,c=M,M=O),O=Os(a,M);var $=Os(a,c);O&&$&&(e.rangeCount!==1||e.anchorNode!==O.node||e.anchorOffset!==O.offset||e.focusNode!==$.node||e.focusOffset!==$.offset)&&(n=n.createRange(),n.setStart(O.node,O.offset),e.removeAllRanges(),M>c?(e.addRange(n),e.extend($.node,$.offset)):(n.setEnd($.node,$.offset),e.addRange(n)))}}for(n=[],e=a;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof a.focus=="function"&&a.focus(),a=0;a=document.documentMode,Mo=null,Li=null,Ea=null,Is=!1;function Bi(e,n,a){var c=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;Is||Mo==null||Mo!==Nt(c)||(c=Mo,"selectionStart"in c&&Ni(c)?c={start:c.selectionStart,end:c.selectionEnd}:(c=(c.ownerDocument&&c.ownerDocument.defaultView||window).getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}),Ea&&xa(Ea,c)||(Ea=c,c=Pa(Li,"onSelect"),0ba||(e.current=js[ba],js[ba]=null,ba--)}function rn(e,n){ba++,js[ba]=e.current,e.current=n}var Ko={},nr=eo(Ko),gr=eo(!1),Vo=Ko;function Ho(e,n){var a=e.type.contextTypes;if(!a)return Ko;var c=e.stateNode;if(c&&c.__reactInternalMemoizedUnmaskedChildContext===n)return c.__reactInternalMemoizedMaskedChildContext;var O={},M;for(M in a)O[M]=n[M];return c&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=O),O}function Ir(e){return e=e.childContextTypes,e!=null}function Zi(){ln(gr),ln(nr)}function aa(e,n,a){if(nr.current!==Ko)throw Error(u(168));rn(nr,n),rn(gr,a)}function bs(e,n,a){var c=e.stateNode;if(n=n.childContextTypes,typeof c.getChildContext!="function")return a;c=c.getChildContext();for(var O in c)if(!(O in n))throw Error(u(108,pt(e)||"Unknown",O));return Z({},a,c)}function Ji(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Ko,Vo=nr.current,rn(nr,e),rn(gr,gr.current),!0}function qi(e,n,a){var c=e.stateNode;if(!c)throw Error(u(169));a?(e=bs(e,n,Vo),c.__reactInternalMemoizedMergedChildContext=e,ln(gr),ln(nr),rn(nr,e)):ln(gr),rn(gr,a)}var Hr=null,ii=!1,_i=!1;function si(e){Hr===null?Hr=[e]:Hr.push(e)}function Mu(e){ii=!0,si(e)}function vo(){if(!_i&&Hr!==null){_i=!0;var e=0,n=Ke;try{var a=Hr;for(Ke=1;e>=$,O-=$,ho=1<<32-On(n)+O|a<Ue?(or=De,De=null):or=De.sibling;var _e=kt(St,De,Ot[Ue],re);if(_e===null){De===null&&(De=or);break}e&&De&&_e.alternate===null&&n(St,De),ht=M(_e,ht,Ue),Ne===null?Ae=_e:Ne.sibling=_e,Ne=_e,De=or}if(Ue===Ot.length)return a(St,De),xn&&ia(St,Ue),Ae;if(De===null){for(;UeUe?(or=De,De=null):or=De.sibling;var va=kt(St,De,_e.value,re);if(va===null){De===null&&(De=or);break}e&&De&&va.alternate===null&&n(St,De),ht=M(va,ht,Ue),Ne===null?Ae=va:Ne.sibling=va,Ne=va,De=or}if(_e.done)return a(St,De),xn&&ia(St,Ue),Ae;if(De===null){for(;!_e.done;Ue++,_e=Ot.next())_e=Yt(St,_e.value,re),_e!==null&&(ht=M(_e,ht,Ue),Ne===null?Ae=_e:Ne.sibling=_e,Ne=_e);return xn&&ia(St,Ue),Ae}for(De=c(St,De);!_e.done;Ue++,_e=Ot.next())_e=me(De,St,Ue,_e.value,re),_e!==null&&(e&&_e.alternate!==null&&De.delete(_e.key===null?Ue:_e.key),ht=M(_e,ht,Ue),Ne===null?Ae=_e:Ne.sibling=_e,Ne=_e);return e&&De.forEach(function(mf){return n(St,mf)}),xn&&ia(St,Ue),Ae}function Fn(St,ht,Ot,re){if(typeof Ot=="object"&&Ot!==null&&Ot.type===K&&Ot.key===null&&(Ot=Ot.props.children),typeof Ot=="object"&&Ot!==null){switch(Ot.$$typeof){case D:t:{for(var Ae=Ot.key,Ne=ht;Ne!==null;){if(Ne.key===Ae){if(Ae=Ot.type,Ae===K){if(Ne.tag===7){a(St,Ne.sibling),ht=O(Ne,Ot.props.children),ht.return=St,St=ht;break t}}else if(Ne.elementType===Ae||typeof Ae=="object"&&Ae!==null&&Ae.$$typeof===W&&at(Ae)===Ne.type){a(St,Ne.sibling),ht=O(Ne,Ot.props),ht.ref=it(St,Ne,Ot),ht.return=St,St=ht;break t}a(St,Ne);break}else n(St,Ne);Ne=Ne.sibling}Ot.type===K?(ht=Ha(Ot.props.children,St.mode,re,Ot.key),ht.return=St,St=ht):(re=qs(Ot.type,Ot.key,Ot.props,null,St.mode,re),re.ref=it(St,ht,Ot),re.return=St,St=re)}return $(St);case z:t:{for(Ne=Ot.key;ht!==null;){if(ht.key===Ne)if(ht.tag===4&&ht.stateNode.containerInfo===Ot.containerInfo&&ht.stateNode.implementation===Ot.implementation){a(St,ht.sibling),ht=O(ht,Ot.children||[]),ht.return=St,St=ht;break t}else{a(St,ht);break}else n(St,ht);ht=ht.sibling}ht=cl(Ot,St.mode,re),ht.return=St,St=ht}return $(St);case W:return Ne=Ot._init,Fn(St,ht,Ne(Ot._payload),re)}if(Bt(Ot))return Ee(St,ht,Ot,re);if(H(Ot))return Te(St,ht,Ot,re);q(St,Ot)}return typeof Ot=="string"&&Ot!==""||typeof Ot=="number"?(Ot=""+Ot,ht!==null&&ht.tag===6?(a(St,ht.sibling),ht=O(ht,Ot),ht.return=St,St=ht):(a(St,ht),ht=ll(Ot,St.mode,re),ht.return=St,St=ht),$(St)):a(St,ht)}return Fn}var Mt=Rt(!0),It=Rt(!1),Ut=eo(null),Zt=null,_t=null,ee=null;function pe(){ee=_t=Zt=null}function Ie(e){var n=Ut.current;ln(Ut),e._currentValue=n}function Kt(e,n,a){for(;e!==null;){var c=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,c!==null&&(c.childLanes|=n)):c!==null&&(c.childLanes&n)!==n&&(c.childLanes|=n),e===a)break;e=e.return}}function de(e,n){Zt=e,ee=_t=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&n&&(Br=!0),e.firstContext=null)}function he(e){var n=e._currentValue;if(ee!==e)if(e={context:e,memoizedValue:n,next:null},_t===null){if(Zt===null)throw Error(u(308));_t=e,Zt.dependencies={lanes:0,firstContext:e}}else _t=_t.next=e;return n}var Be=null;function we(e){Be===null?Be=[e]:Be.push(e)}function We(e,n,a,c){var O=n.interleaved;return O===null?(a.next=a,we(n)):(a.next=O.next,O.next=a),n.interleaved=a,Qt(e,c)}function Qt(e,n){e.lanes|=n;var a=e.alternate;for(a!==null&&(a.lanes|=n),a=e,e=e.return;e!==null;)e.childLanes|=n,a=e.alternate,a!==null&&(a.childLanes|=n),a=e,e=e.return;return a.tag===3?a.stateNode:null}var Ce=!1;function Re(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Xe(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function en(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function Rn(e,n,a){var c=e.updateQueue;if(c===null)return null;if(c=c.shared,Je&2){var O=c.pending;return O===null?n.next=n:(n.next=O.next,O.next=n),c.pending=n,Qt(e,a)}return O=c.interleaved,O===null?(n.next=n,we(c)):(n.next=O.next,O.next=n),c.interleaved=n,Qt(e,a)}function on(e,n,a){if(n=n.updateQueue,n!==null&&(n=n.shared,(a&4194240)!==0)){var c=n.lanes;c&=e.pendingLanes,a|=c,n.lanes=a,Kn(e,a)}}function Zn(e,n){var a=e.updateQueue,c=e.alternate;if(c!==null&&(c=c.updateQueue,a===c)){var O=null,M=null;if(a=a.firstBaseUpdate,a!==null){do{var $={eventTime:a.eventTime,lane:a.lane,tag:a.tag,payload:a.payload,callback:a.callback,next:null};M===null?O=M=$:M=M.next=$,a=a.next}while(a!==null);M===null?O=M=n:M=M.next=n}else O=M=n;a={baseState:c.baseState,firstBaseUpdate:O,lastBaseUpdate:M,shared:c.shared,effects:c.effects},e.updateQueue=a;return}e=a.lastBaseUpdate,e===null?a.firstBaseUpdate=n:e.next=n,a.lastBaseUpdate=n}function Dr(e,n,a,c){var O=e.updateQueue;Ce=!1;var M=O.firstBaseUpdate,$=O.lastBaseUpdate,X=O.shared.pending;if(X!==null){O.shared.pending=null;var dt=X,Pt=dt.next;dt.next=null,$===null?M=Pt:$.next=Pt,$=dt;var jt=e.alternate;jt!==null&&(jt=jt.updateQueue,X=jt.lastBaseUpdate,X!==$&&(X===null?jt.firstBaseUpdate=Pt:X.next=Pt,jt.lastBaseUpdate=dt))}if(M!==null){var Yt=O.baseState;$=0,jt=Pt=dt=null,X=M;do{var kt=X.lane,me=X.eventTime;if((c&kt)===kt){jt!==null&&(jt=jt.next={eventTime:me,lane:0,tag:X.tag,payload:X.payload,callback:X.callback,next:null});t:{var Ee=e,Te=X;switch(kt=n,me=a,Te.tag){case 1:if(Ee=Te.payload,typeof Ee=="function"){Yt=Ee.call(me,Yt,kt);break t}Yt=Ee;break t;case 3:Ee.flags=Ee.flags&-65537|128;case 0:if(Ee=Te.payload,kt=typeof Ee=="function"?Ee.call(me,Yt,kt):Ee,kt==null)break t;Yt=Z({},Yt,kt);break t;case 2:Ce=!0}}X.callback!==null&&X.lane!==0&&(e.flags|=64,kt=O.effects,kt===null?O.effects=[X]:kt.push(X))}else me={eventTime:me,lane:kt,tag:X.tag,payload:X.payload,callback:X.callback,next:null},jt===null?(Pt=jt=me,dt=Yt):jt=jt.next=me,$|=kt;if(X=X.next,X===null){if(X=O.shared.pending,X===null)break;kt=X,X=kt.next,kt.next=null,O.lastBaseUpdate=kt,O.shared.pending=null}}while(!0);if(jt===null&&(dt=Yt),O.baseState=dt,O.firstBaseUpdate=Pt,O.lastBaseUpdate=jt,n=O.shared.interleaved,n!==null){O=n;do $|=O.lane,O=O.next;while(O!==n)}else M===null&&(O.shared.lanes=0);Wa|=$,e.lanes=$,e.memoizedState=Yt}}function qe(e,n,a){if(e=n.effects,n.effects=null,e!==null)for(n=0;na?a:4,e(!0);var c=es.transition;es.transition={};try{e(!1),n()}finally{Ke=a,es.transition=c}}function zl(){return Pr().memoizedState}function zc(e,n,a){var c=ca(e);if(a={lane:c,action:a,hasEagerState:!1,eagerState:null,next:null},Wl(e))$l(n,a);else if(a=We(e,n,a,c),a!==null){var O=wr();So(a,e,c,O),Kl(a,n,c)}}function Wc(e,n,a){var c=ca(e),O={lane:c,action:a,hasEagerState:!1,eagerState:null,next:null};if(Wl(e))$l(n,O);else{var M=e.alternate;if(e.lanes===0&&(M===null||M.lanes===0)&&(M=n.lastRenderedReducer,M!==null))try{var $=n.lastRenderedState,X=M($,a);if(O.hasEagerState=!0,O.eagerState=X,Mr(X,$)){var dt=n.interleaved;dt===null?(O.next=O,we(n)):(O.next=dt.next,dt.next=O),n.interleaved=O;return}}catch(Pt){}finally{}a=We(e,n,O,c),a!==null&&(O=wr(),So(a,e,c,O),Kl(a,n,c))}}function Wl(e){var n=e.alternate;return e===vn||n!==null&&n===vn}function $l(e,n){Gr=ci=!0;var a=e.pending;a===null?n.next=n:(n.next=a.next,a.next=n),e.pending=n}function Kl(e,n,a){if(a&4194240){var c=n.lanes;c&=e.pendingLanes,a|=c,n.lanes=a,Kn(e,a)}}var Us={readContext:he,useCallback:qn,useContext:qn,useEffect:qn,useImperativeHandle:qn,useInsertionEffect:qn,useLayoutEffect:qn,useMemo:qn,useReducer:qn,useRef:qn,useState:qn,useDebugValue:qn,useDeferredValue:qn,useTransition:qn,useMutableSource:qn,useSyncExternalStore:qn,useId:qn,unstable_isNewReconciler:!1},$c={readContext:he,useCallback:function(n,a){return kr().memoizedState=[n,a===void 0?null:a],n},useContext:he,useEffect:jl,useImperativeHandle:function(n,a,c){return c=c!=null?c.concat([n]):null,Bs(4194308,4,Dl.bind(null,a,n),c)},useLayoutEffect:function(n,a){return Bs(4194308,4,n,a)},useInsertionEffect:function(n,a){return Bs(4,2,n,a)},useMemo:function(n,a){var c=kr();return a=a===void 0?null:a,n=n(),c.memoizedState=[n,a],n},useReducer:function(n,a,c){var O=kr();return a=c!==void 0?c(a):a,O.memoizedState=O.baseState=a,n={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:n,lastRenderedState:a},O.queue=n,n=n.dispatch=zc.bind(null,vn,n),[O.memoizedState,n]},useRef:function(n){var a=kr();return n={current:n},a.memoizedState=n},useState:Rl,useDebugValue:Bu,useDeferredValue:function(n){return kr().memoizedState=n},useTransition:function(){var n=Rl(!1),a=n[0];return n=Uc.bind(null,n[1]),kr().memoizedState=n,[a,n]},useMutableSource:function(){},useSyncExternalStore:function(n,a,c){var O=vn,M=kr();if(xn){if(c===void 0)throw Error(u(407));c=c()}else{if(c=a(),rr===null)throw Error(u(349));Go&30||Il(O,a,c)}M.memoizedState=c;var $={value:c,getSnapshot:a};return M.queue=$,jl(Pl.bind(null,O,$,n),[n]),O.flags|=2048,rs(9,Al.bind(null,O,$,c,a),void 0,null),c},useId:function(){var n=kr(),a=rr.identifierPrefix;if(xn){var c=No,O=ho;c=(O&~(1<<32-On(O)-1)).toString(32)+c,a=":"+a+"R"+c,c=Lo++,0<\/script>",e=e.removeChild(e.firstChild)):typeof c.is=="string"?e=$.createElement(a,{is:c.is}):(e=$.createElement(a),a==="select"&&($=e,c.multiple?$.multiple=!0:c.size&&($.size=c.size))):e=$.createElementNS(e,a),e[Vr]=n,e[$o]=c,uc(e,n,!1,!1),n.stateNode=e;t:{switch($=Un(a,c),a){case"dialog":un("cancel",e),un("close",e),O=c;break;case"iframe":case"object":case"embed":un("load",e),O=c;break;case"video":case"audio":for(O=0;Omi&&(n.flags|=128,c=!0,os(M,!1),n.lanes=4194304)}else{if(!c)if(e=li($),e!==null){if(n.flags|=128,c=!0,a=e.updateQueue,a!==null&&(n.updateQueue=a,n.flags|=4),os(M,!0),M.tail===null&&M.tailMode==="hidden"&&!$.alternate&&!xn)return xr(n),null}else 2*Ye()-M.renderingStartTime>mi&&a!==1073741824&&(n.flags|=128,c=!0,os(M,!1),n.lanes=4194304);M.isBackwards?($.sibling=n.child,n.child=$):(a=M.last,a!==null?a.sibling=$:n.child=$,M.last=$)}return M.tail!==null?(n=M.tail,M.rendering=n,M.tail=n.sibling,M.renderingStartTime=Ye(),n.sibling=null,a=cn.current,rn(cn,c?a&1|2:a&1),n):(xr(n),null);case 22:case 23:return il(),c=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==c&&(n.flags|=8192),c&&n.mode&1?Yr&1073741824&&(xr(n),n.subtreeFlags&6&&(n.flags|=8192)):xr(n),null;case 24:return null;case 25:return null}throw Error(u(156,n.tag))}function Qc(e,n){switch(Ds(n),n.tag){case 1:return Ir(n.type)&&Zi(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return ro(),ln(gr),ln(nr),ts(),e=n.flags,e&65536&&!(e&128)?(n.flags=e&-65537|128,n):null;case 5:return mo(n),null;case 13:if(ln(cn),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(u(340));U()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return ln(cn),null;case 4:return ro(),null;case 10:return Ie(n.type._context),null;case 22:case 23:return il(),null;case 24:return null;default:return null}}var Ks=!1,Sr=!1,Zc=typeof WeakSet=="function"?WeakSet:Set,ye=null;function pi(e,n){var a=e.ref;if(a!==null)if(typeof a=="function")try{a(null)}catch(c){jn(e,n,c)}else a.current=null}function Xu(e,n,a){try{a()}catch(c){jn(e,n,c)}}var fc=!1;function Jc(e,n){if(Ki=$r,e=Ts(),Ni(e)){if("selectionStart"in e)var a={start:e.selectionStart,end:e.selectionEnd};else t:{a=(a=e.ownerDocument)&&a.defaultView||window;var c=a.getSelection&&a.getSelection();if(c&&c.rangeCount!==0){a=c.anchorNode;var O=c.anchorOffset,M=c.focusNode;c=c.focusOffset;try{a.nodeType,M.nodeType}catch(re){a=null;break t}var $=0,X=-1,dt=-1,Pt=0,jt=0,Yt=e,kt=null;e:for(;;){for(var me;Yt!==a||O!==0&&Yt.nodeType!==3||(X=$+O),Yt!==M||c!==0&&Yt.nodeType!==3||(dt=$+c),Yt.nodeType===3&&($+=Yt.nodeValue.length),(me=Yt.firstChild)!==null;)kt=Yt,Yt=me;for(;;){if(Yt===e)break e;if(kt===a&&++Pt===O&&(X=$),kt===M&&++jt===c&&(dt=$),(me=Yt.nextSibling)!==null)break;Yt=kt,kt=Yt.parentNode}Yt=me}a=X===-1||dt===-1?null:{start:X,end:dt}}else a=null}a=a||{start:0,end:0}}else a=null;for(Vi={focusedElem:e,selectionRange:a},$r=!1,ye=n;ye!==null;)if(n=ye,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,ye=e;else for(;ye!==null;){n=ye;try{var Ee=n.alternate;if(n.flags&1024)switch(n.tag){case 0:case 11:case 15:break;case 1:if(Ee!==null){var Te=Ee.memoizedProps,Fn=Ee.memoizedState,St=n.stateNode,ht=St.getSnapshotBeforeUpdate(n.elementType===n.type?Te:go(n.type,Te),Fn);St.__reactInternalSnapshotBeforeUpdate=ht}break;case 3:var Ot=n.stateNode.containerInfo;Ot.nodeType===1?Ot.textContent="":Ot.nodeType===9&&Ot.documentElement&&Ot.removeChild(Ot.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(u(163))}}catch(re){jn(n,n.return,re)}if(e=n.sibling,e!==null){e.return=n.return,ye=e;break}ye=n.return}return Ee=fc,fc=!1,Ee}function as(e,n,a){var c=n.updateQueue;if(c=c!==null?c.lastEffect:null,c!==null){var O=c=c.next;do{if((O.tag&e)===e){var M=O.destroy;O.destroy=void 0,M!==void 0&&Xu(n,a,M)}O=O.next}while(O!==c)}}function Vs(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var a=n=n.next;do{if((a.tag&e)===e){var c=a.create;a.destroy=c()}a=a.next}while(a!==n)}}function Qu(e){var n=e.ref;if(n!==null){var a=e.stateNode;switch(e.tag){case 5:e=a;break;default:e=a}typeof n=="function"?n(e):n.current=e}}function dc(e){var n=e.alternate;n!==null&&(e.alternate=null,dc(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[Vr],delete n[$o],delete n[Xi],delete n[Qi],delete n[Ru])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function vc(e){return e.tag===5||e.tag===3||e.tag===4}function pc(e){t:for(;;){for(;e.sibling===null;){if(e.return===null||vc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue t;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zu(e,n,a){var c=e.tag;if(c===5||c===6)e=e.stateNode,n?a.nodeType===8?a.parentNode.insertBefore(e,n):a.insertBefore(e,n):(a.nodeType===8?(n=a.parentNode,n.insertBefore(e,a)):(n=a,n.appendChild(e)),a=a._reactRootContainer,a!=null||n.onclick!==null||(n.onclick=ai));else if(c!==4&&(e=e.child,e!==null))for(Zu(e,n,a),e=e.sibling;e!==null;)Zu(e,n,a),e=e.sibling}function Ju(e,n,a){var c=e.tag;if(c===5||c===6)e=e.stateNode,n?a.insertBefore(e,n):a.appendChild(e);else if(c!==4&&(e=e.child,e!==null))for(Ju(e,n,a),e=e.sibling;e!==null;)Ju(e,n,a),e=e.sibling}var ur=null,yo=!1;function sa(e,n,a){for(a=a.child;a!==null;)hc(e,n,a),a=a.sibling}function hc(e,n,a){if(dn&&typeof dn.onCommitFiberUnmount=="function")try{dn.onCommitFiberUnmount(nn,a)}catch(X){}switch(a.tag){case 5:Sr||pi(a,n);case 6:var c=ur,O=yo;ur=null,sa(e,n,a),ur=c,yo=O,ur!==null&&(yo?(e=ur,a=a.stateNode,e.nodeType===8?e.parentNode.removeChild(a):e.removeChild(a)):ur.removeChild(a.stateNode));break;case 18:ur!==null&&(yo?(e=ur,a=a.stateNode,e.nodeType===8?Ra(e.parentNode,a):e.nodeType===1&&Ra(e,a),Wr(e)):Ra(ur,a.stateNode));break;case 4:c=ur,O=yo,ur=a.stateNode.containerInfo,yo=!0,sa(e,n,a),ur=c,yo=O;break;case 0:case 11:case 14:case 15:if(!Sr&&(c=a.updateQueue,c!==null&&(c=c.lastEffect,c!==null))){O=c=c.next;do{var M=O,$=M.destroy;M=M.tag,$!==void 0&&(M&2||M&4)&&Xu(a,n,$),O=O.next}while(O!==c)}sa(e,n,a);break;case 1:if(!Sr&&(pi(a,n),c=a.stateNode,typeof c.componentWillUnmount=="function"))try{c.props=a.memoizedProps,c.state=a.memoizedState,c.componentWillUnmount()}catch(X){jn(a,n,X)}sa(e,n,a);break;case 21:sa(e,n,a);break;case 22:a.mode&1?(Sr=(c=Sr)||a.memoizedState!==null,sa(e,n,a),Sr=c):sa(e,n,a);break;default:sa(e,n,a)}}function mc(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var a=e.stateNode;a===null&&(a=e.stateNode=new Zc),n.forEach(function(c){var O=sf.bind(null,e,c);a.has(c)||(a.add(c),c.then(O,O))})}}function xo(e,n){var a=n.deletions;if(a!==null)for(var c=0;cO&&(O=$),c&=~M}if(c=O,c=Ye()-c,c=(120>c?120:480>c?480:1080>c?1080:1920>c?1920:3e3>c?3e3:4320>c?4320:1960*_c(c/1960))-c,10e?16:e,la===null)var c=!1;else{if(e=la,la=null,Xs=0,Je&6)throw Error(u(331));var O=Je;for(Je|=4,ye=e.current;ye!==null;){var M=ye,$=M.child;if(ye.flags&16){var X=M.deletions;if(X!==null){for(var dt=0;dtYe()-tl?Ka(e,0):_u|=a),Ur(e,n)}function Rc(e,n){n===0&&(e.mode&1?(n=hn,hn<<=1,!(hn&130023424)&&(hn=4194304)):n=1);var a=wr();e=Qt(e,n),e!==null&&(Bn(e,n,a),Ur(e,a))}function af(e){var n=e.memoizedState,a=0;n!==null&&(a=n.retryLane),Rc(e,a)}function sf(e,n){var a=0;switch(e.tag){case 13:var c=e.stateNode,O=e.memoizedState;O!==null&&(a=O.retryLane);break;case 19:c=e.stateNode;break;default:throw Error(u(314))}c!==null&&c.delete(n),Rc(e,a)}var Mc;Mc=function(n,a,c){if(n!==null)if(n.memoizedProps!==a.pendingProps||gr.current)Br=!0;else{if(!(n.lanes&c)&&!(a.flags&128))return Br=!1,Yc(n,a,c);Br=!!(n.flags&131072)}else Br=!1,xn&&a.flags&1048576&&ui(a,La,a.index);switch(a.lanes=0,a.tag){case 2:var O=a.type;$s(n,a),n=a.pendingProps;var M=Ho(a,nr.current);de(a,c),M=fi(null,a,O,n,M,c);var $=di();return a.flags|=1,typeof M=="object"&&M!==null&&typeof M.render=="function"&&M.$$typeof===void 0?(a.tag=1,a.memoizedState=null,a.updateQueue=null,Ir(O)?($=!0,Ji(a)):$=!1,a.memoizedState=M.state!==null&&M.state!==void 0?M.state:null,Re(a),M.updater=zs,a.stateNode=M,M._reactInternals=a,Uu(a,O,n,c),a=Ku(null,a,O,!0,$,c)):(a.tag=0,xn&&$&&Ns(a),Cr(null,a,M,c),a=a.child),a;case 16:O=a.elementType;t:{switch($s(n,a),n=a.pendingProps,M=O._init,O=M(O._payload),a.type=O,M=a.tag=lf(O),n=go(O,n),M){case 0:a=$u(null,a,O,n,c);break t;case 1:a=nc(null,a,O,n,c);break t;case 11:a=Jl(null,a,O,n,c);break t;case 14:a=ql(null,a,O,go(O.type,n),c);break t}throw Error(u(306,O,""))}return a;case 0:return O=a.type,M=a.pendingProps,M=a.elementType===O?M:go(O,M),$u(n,a,O,M,c);case 1:return O=a.type,M=a.pendingProps,M=a.elementType===O?M:go(O,M),nc(n,a,O,M,c);case 3:t:{if(rc(a),n===null)throw Error(u(387));O=a.pendingProps,$=a.memoizedState,M=$.element,Xe(n,a),Dr(a,O,null,c);var X=a.memoizedState;if(O=X.element,$.isDehydrated)if($={element:O,isDehydrated:!1,cache:X.cache,pendingSuspenseBoundaries:X.pendingSuspenseBoundaries,transitions:X.transitions},a.updateQueue.baseState=$,a.memoizedState=$,a.flags&256){M=vi(Error(u(423)),a),a=oc(n,a,O,c,M);break t}else if(O!==M){M=vi(Error(u(424)),a),a=oc(n,a,O,c,M);break t}else for(Nr=Kr(a.stateNode.containerInfo.firstChild),br=a,xn=!0,Ar=null,c=It(a,null,O,c),a.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{if(U(),O===M){a=ko(n,a,c);break t}Cr(n,a,O,c)}a=a.child}return a;case 5:return Ba(a),n===null&&g(a),O=a.type,M=a.pendingProps,$=n!==null?n.memoizedProps:null,X=M.children,wa(O,M)?X=null:$!==null&&wa(O,$)&&(a.flags|=32),ec(n,a),Cr(n,a,X,c),a.child;case 6:return n===null&&g(a),null;case 13:return ac(n,a,c);case 4:return no(a,a.stateNode.containerInfo),O=a.pendingProps,n===null?a.child=Mt(a,null,O,c):Cr(n,a,O,c),a.child;case 11:return O=a.type,M=a.pendingProps,M=a.elementType===O?M:go(O,M),Jl(n,a,O,M,c);case 7:return Cr(n,a,a.pendingProps,c),a.child;case 8:return Cr(n,a,a.pendingProps.children,c),a.child;case 12:return Cr(n,a,a.pendingProps.children,c),a.child;case 10:t:{if(O=a.type._context,M=a.pendingProps,$=a.memoizedProps,X=M.value,rn(Ut,O._currentValue),O._currentValue=X,$!==null)if(Mr($.value,X)){if($.children===M.children&&!gr.current){a=ko(n,a,c);break t}}else for($=a.child,$!==null&&($.return=a);$!==null;){var dt=$.dependencies;if(dt!==null){X=$.child;for(var Pt=dt.firstContext;Pt!==null;){if(Pt.context===O){if($.tag===1){Pt=en(-1,c&-c),Pt.tag=2;var jt=$.updateQueue;if(jt!==null){jt=jt.shared;var Yt=jt.pending;Yt===null?Pt.next=Pt:(Pt.next=Yt.next,Yt.next=Pt),jt.pending=Pt}}$.lanes|=c,Pt=$.alternate,Pt!==null&&(Pt.lanes|=c),Kt($.return,c,a),dt.lanes|=c;break}Pt=Pt.next}}else if($.tag===10)X=$.type===a.type?null:$.child;else if($.tag===18){if(X=$.return,X===null)throw Error(u(341));X.lanes|=c,dt=X.alternate,dt!==null&&(dt.lanes|=c),Kt(X,c,a),X=$.sibling}else X=$.child;if(X!==null)X.return=$;else for(X=$;X!==null;){if(X===a){X=null;break}if($=X.sibling,$!==null){$.return=X.return,X=$;break}X=X.return}$=X}Cr(n,a,M.children,c),a=a.child}return a;case 9:return M=a.type,O=a.pendingProps.children,de(a,c),M=he(M),O=O(M),a.flags|=1,Cr(n,a,O,c),a.child;case 14:return O=a.type,M=go(O,a.pendingProps),M=go(O.type,M),ql(n,a,O,M,c);case 15:return _l(n,a,a.type,a.pendingProps,c);case 17:return O=a.type,M=a.pendingProps,M=a.elementType===O?M:go(O,M),$s(n,a),a.tag=1,Ir(O)?(n=!0,Ji(a)):n=!1,de(a,c),Hl(a,O,M),Uu(a,O,M,c),Ku(null,a,O,!0,n,c);case 19:return sc(n,a,c);case 22:return tc(n,a,c)}throw Error(u(156,a.tag))};function jc(e,n){return Qe(e,n)}function uf(e,n,a,c){this.tag=e,this.key=a,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=c,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function ao(e,n,a,c){return new uf(e,n,a,c)}function ul(e){return e=e.prototype,!(!e||!e.isReactComponent)}function lf(e){if(typeof e=="function")return ul(e)?1:0;if(e!=null){if(e=e.$$typeof,e===Q)return 11;if(e===ut)return 14}return 2}function da(e,n){var a=e.alternate;return a===null?(a=ao(e.tag,n,e.key,e.mode),a.elementType=e.elementType,a.type=e.type,a.stateNode=e.stateNode,a.alternate=e,e.alternate=a):(a.pendingProps=n,a.type=e.type,a.flags=0,a.subtreeFlags=0,a.deletions=null),a.flags=e.flags&14680064,a.childLanes=e.childLanes,a.lanes=e.lanes,a.child=e.child,a.memoizedProps=e.memoizedProps,a.memoizedState=e.memoizedState,a.updateQueue=e.updateQueue,n=e.dependencies,a.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},a.sibling=e.sibling,a.index=e.index,a.ref=e.ref,a}function qs(e,n,a,c,O,M){var $=2;if(c=e,typeof e=="function")ul(e)&&($=1);else if(typeof e=="string")$=5;else t:switch(e){case K:return Ha(a.children,O,M,n);case k:$=8,O|=8;break;case J:return e=ao(12,a,n,O|2),e.elementType=J,e.lanes=M,e;case ct:return e=ao(13,a,n,O),e.elementType=ct,e.lanes=M,e;case ot:return e=ao(19,a,n,O),e.elementType=ot,e.lanes=M,e;case V:return _s(a,O,M,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case G:$=10;break t;case _:$=9;break t;case Q:$=11;break t;case ut:$=14;break t;case W:$=16,c=null;break t}throw Error(u(130,e==null?e:typeof e=="undefined"?"undefined":o(e),""))}return n=ao($,a,n,O),n.elementType=e,n.type=c,n.lanes=M,n}function Ha(e,n,a,c){return e=ao(7,e,c,n),e.lanes=a,e}function _s(e,n,a,c){return e=ao(22,e,c,n),e.elementType=V,e.lanes=a,e.stateNode={isHidden:!1},e}function ll(e,n,a){return e=ao(6,e,null,n),e.lanes=a,e}function cl(e,n,a){return n=ao(4,e.children!==null?e.children:[],e.key,n),n.lanes=a,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function cf(e,n,a,c,O){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Oo(0),this.expirationTimes=Oo(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Oo(0),this.identifierPrefix=c,this.onRecoverableError=O,this.mutableSourceEagerHydrationData=null}function fl(e,n,a,c,O,M,$,X,dt){return e=new cf(e,n,a,X,dt),n===1?(n=1,M===!0&&(n|=8)):n=0,M=ao(3,null,null,n),e.current=M,M.stateNode=e,M.memoizedState={element:c,isDehydrated:a,cache:null,transitions:null,pendingSuspenseBoundaries:null},Re(M),e}function ff(e,n,a){var c=3Et.length)&&(wt=Et.length);for(var Ht=0,ue=new Array(wt);Ht1?Ht-1:0),Se=1;Se/gm),Ct=R(/\${[\w\W]*}/gm),Nt=R(/^data-[\-\w.\u00B7-\uFFFF]/),Wt=R(/^aria-[\-\w]+$/),zt=R(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),ae=R(/^(?:\w+script|data):/i),ie=R(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),te=R(/^html$/i),Ft=R(/^[a-z][.\w]*(-[.\w]+)+$/i),Bt=function(){return typeof window=="undefined"?null:window},At=function(wt,Ht){if(t(wt)!=="object"||typeof wt.createPolicy!="function")return null;var ue=null,Se="data-tt-policy-suffix";Ht.currentScript&&Ht.currentScript.hasAttribute(Se)&&(ue=Ht.currentScript.getAttribute(Se));var xe="dompurify"+(ue?"#"+ue:"");try{return wt.createPolicy(xe,{createHTML:function($t){return $t},createScriptURL:function($t){return $t}})}catch(le){return console.warn("TrustedTypes policy "+xe+" could not be created."),null}};function Xt(){var Et=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Bt(),wt=function(lt){return Xt(lt)};if(wt.version="2.5.3",wt.removed=[],!Et||!Et.document||Et.document.nodeType!==9)return wt.isSupported=!1,wt;var Ht=Et.document,ue=Et.document,Se=Et.DocumentFragment,xe=Et.HTMLTemplateElement,le=Et.Node,$t=Et.Element,Gt=Et.NodeFilter,Me=Et.NamedNodeMap,Ze=Me===void 0?Et.NamedNodeMap||Et.MozNamedAttrMap:Me,tr=Et.HTMLFormElement,fn=Et.DOMParser,Un=Et.trustedTypes,Pn=$t.prototype,cr=tt(Pn,"cloneNode"),rt=tt(Pn,"nextSibling"),xt=tt(Pn,"childNodes"),st=tt(Pn,"parentNode");if(typeof xe=="function"){var yt=ue.createElement("template");yt.content&&yt.content.ownerDocument&&(ue=yt.content.ownerDocument)}var Tt=At(Un,Ht),Lt=Tt?Tt.createHTML(""):"",oe=ue,ne=oe.implementation,Oe=oe.createNodeIterator,qt=oe.createDocumentFragment,Fe=oe.getElementsByTagName,$e=Ht.importNode,ze={};try{ze=V(ue).documentMode?ue.documentMode:{}}catch(ge){}var je={};wt.isSupported=typeof st=="function"&&ne&&ne.createHTMLDocument!==void 0&&ze!==9;var Ve=fe,Ge=Jt,Le=Ct,Cn=Nt,pn=Wt,bn=ae,fr=ie,Pe=Ft,zn=zt,tn=null,dr=W({},[].concat(s(H),s(Z),s(ft),s(vt),s(bt))),ke=null,Nn=W({},[].concat(s(gt),s(pt),s(Dt),s(ve))),Qe=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),In=null,vr=null,Wn=!0,Ye=!0,ar=!1,En=!0,$n=!1,ir=!0,wn=!1,Yn=!1,nn=!1,dn=!1,Rr=!1,On=!1,Dn=!0,Er=!1,Xr="user-content-",er=!0,hn=!1,pr={},Ln=null,Xo=W({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),io=null,hr=W({},["audio","video","img","source","image","track"]),Eo=null,Oo=W({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Bn="http://www.w3.org/1998/Math/MathML",To="http://www.w3.org/2000/svg",Kn="http://www.w3.org/1999/xhtml",Ke=Kn,Io=!1,zr=null,Qo=W({},[Bn,To,Kn],z),Qr,Ga=["application/xhtml+xml","text/html"],ka="text/html",mn,Or=null,mr=255,Zr=ue.createElement("form"),Tr=function(lt){return h(lt,RegExp)||h(lt,Function)},Jr=function(lt){Or&&Or===lt||((!lt||t(lt)!=="object")&&(lt={}),lt=V(lt),Qr=Ga.indexOf(lt.PARSER_MEDIA_TYPE)===-1?Qr=ka:Qr=lt.PARSER_MEDIA_TYPE,mn=Qr==="application/xhtml+xml"?z:D,tn="ALLOWED_TAGS"in lt?W({},lt.ALLOWED_TAGS,mn):dr,ke="ALLOWED_ATTR"in lt?W({},lt.ALLOWED_ATTR,mn):Nn,zr="ALLOWED_NAMESPACES"in lt?W({},lt.ALLOWED_NAMESPACES,z):Qo,Eo="ADD_URI_SAFE_ATTR"in lt?W(V(Oo),lt.ADD_URI_SAFE_ATTR,mn):Oo,io="ADD_DATA_URI_TAGS"in lt?W(V(hr),lt.ADD_DATA_URI_TAGS,mn):hr,Ln="FORBID_CONTENTS"in lt?W({},lt.FORBID_CONTENTS,mn):Xo,In="FORBID_TAGS"in lt?W({},lt.FORBID_TAGS,mn):{},vr="FORBID_ATTR"in lt?W({},lt.FORBID_ATTR,mn):{},pr="USE_PROFILES"in lt?lt.USE_PROFILES:!1,Wn=lt.ALLOW_ARIA_ATTR!==!1,Ye=lt.ALLOW_DATA_ATTR!==!1,ar=lt.ALLOW_UNKNOWN_PROTOCOLS||!1,En=lt.ALLOW_SELF_CLOSE_IN_ATTR!==!1,$n=lt.SAFE_FOR_TEMPLATES||!1,ir=lt.SAFE_FOR_XML!==!1,wn=lt.WHOLE_DOCUMENT||!1,dn=lt.RETURN_DOM||!1,Rr=lt.RETURN_DOM_FRAGMENT||!1,On=lt.RETURN_TRUSTED_TYPE||!1,nn=lt.FORCE_BODY||!1,Dn=lt.SANITIZE_DOM!==!1,Er=lt.SANITIZE_NAMED_PROPS||!1,er=lt.KEEP_CONTENT!==!1,hn=lt.IN_PLACE||!1,zn=lt.ALLOWED_URI_REGEXP||zn,Ke=lt.NAMESPACE||Kn,Qe=lt.CUSTOM_ELEMENT_HANDLING||{},lt.CUSTOM_ELEMENT_HANDLING&&Tr(lt.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Qe.tagNameCheck=lt.CUSTOM_ELEMENT_HANDLING.tagNameCheck),lt.CUSTOM_ELEMENT_HANDLING&&Tr(lt.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Qe.attributeNameCheck=lt.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),lt.CUSTOM_ELEMENT_HANDLING&&typeof lt.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(Qe.allowCustomizedBuiltInElements=lt.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),$n&&(Ye=!1),Rr&&(dn=!0),pr&&(tn=W({},s(bt)),ke=[],pr.html===!0&&(W(tn,H),W(ke,gt)),pr.svg===!0&&(W(tn,Z),W(ke,pt),W(ke,ve)),pr.svgFilters===!0&&(W(tn,ft),W(ke,pt),W(ke,ve)),pr.mathMl===!0&&(W(tn,vt),W(ke,Dt),W(ke,ve))),lt.ADD_TAGS&&(tn===dr&&(tn=V(tn)),W(tn,lt.ADD_TAGS,mn)),lt.ADD_ATTR&&(ke===Nn&&(ke=V(ke)),W(ke,lt.ADD_ATTR,mn)),lt.ADD_URI_SAFE_ATTR&&W(Eo,lt.ADD_URI_SAFE_ATTR,mn),lt.FORBID_CONTENTS&&(Ln===Xo&&(Ln=V(Ln)),W(Ln,lt.FORBID_CONTENTS,mn)),er&&(tn["#text"]=!0),wn&&W(tn,["html","head","body"]),tn.table&&(W(tn,["tbody"]),delete In.tbody),A&&A(lt),Or=lt)},Ao=W({},["mi","mo","mn","ms","mtext"]),Xn=W({},["foreignobject","annotation-xml"]),Ya=W({},["title","style","font","a","script"]),Po=W({},Z);W(Po,ft),W(Po,nt);var sr=W({},vt);W(sr,mt);var Fo=function(lt){var Vt=st(lt);(!Vt||!Vt.tagName)&&(Vt={namespaceURI:Ke,tagName:"template"});var se=D(lt.tagName),be=D(Vt.tagName);return zr[lt.namespaceURI]?lt.namespaceURI===To?Vt.namespaceURI===Kn?se==="svg":Vt.namespaceURI===Bn?se==="svg"&&(be==="annotation-xml"||Ao[be]):!!Po[se]:lt.namespaceURI===Bn?Vt.namespaceURI===Kn?se==="math":Vt.namespaceURI===To?se==="math"&&Xn[be]:!!sr[se]:lt.namespaceURI===Kn?Vt.namespaceURI===To&&!Xn[be]||Vt.namespaceURI===Bn&&!Ao[be]?!1:!sr[se]&&(Ya[se]||!Po[se]):!!(Qr==="application/xhtml+xml"&&zr[lt.namespaceURI]):!1},Vn=function(lt){L(wt.removed,{element:lt});try{lt.parentNode.removeChild(lt)}catch(Vt){try{lt.outerHTML=Lt}catch(se){lt.remove()}}},Tn=function(lt,Vt){try{L(wt.removed,{attribute:Vt.getAttributeNode(lt),from:Vt})}catch(se){L(wt.removed,{attribute:null,from:Vt})}if(Vt.removeAttribute(lt),lt==="is"&&!ke[lt])if(dn||Rr)try{Vn(Vt)}catch(se){}else try{Vt.setAttribute(lt,"")}catch(se){}},pa=function(lt){var Vt,se;if(nn)lt=""+lt;else{var be=K(lt,/^[\r\n\t ]+/);se=be&&be[0]}Qr==="application/xhtml+xml"&&Ke===Kn&&(lt=''+lt+"");var gn=Tt?Tt.createHTML(lt):lt;if(Ke===Kn)try{Vt=new fn().parseFromString(gn,Qr)}catch(an){}if(!Vt||!Vt.documentElement){Vt=ne.createDocument(Ke,"template",null);try{Vt.documentElement.innerHTML=Io?Lt:gn}catch(an){}}var An=Vt.body||Vt.documentElement;return lt&&se&&An.insertBefore(ue.createTextNode(se),An.childNodes[0]||null),Ke===Kn?Fe.call(Vt,wn?"html":"body")[0]:wn?Vt.documentElement:An},Xa=function(lt){return Oe.call(lt.ownerDocument||lt,lt,Gt.SHOW_ELEMENT|Gt.SHOW_COMMENT|Gt.SHOW_TEXT|Gt.SHOW_PROCESSING_INSTRUCTION|Gt.SHOW_CDATA_SECTION,null,!1)},Co=function(lt){return h(lt,tr)&&(typeof lt.__depth!="undefined"&&typeof lt.__depth!="number"||typeof lt.__removalCount!="undefined"&&typeof lt.__removalCount!="number"||typeof lt.nodeName!="string"||typeof lt.textContent!="string"||typeof lt.removeChild!="function"||!h(lt.attributes,Ze)||typeof lt.removeAttribute!="function"||typeof lt.setAttribute!="function"||typeof lt.namespaceURI!="string"||typeof lt.insertBefore!="function"||typeof lt.hasChildNodes!="function")},Wr=function(lt){return t(le)==="object"?h(lt,le):lt&&t(lt)==="object"&&typeof lt.nodeType=="number"&&typeof lt.nodeName=="string"},Qn=function(lt,Vt,se){je[lt]&&C(je[lt],function(be){be.call(wt,Vt,se,Or)})},$r=function(lt){var Vt;if(Qn("beforeSanitizeElements",lt,null),Co(lt)||_(/[\u0080-\uFFFF]/,lt.nodeName))return Vn(lt),!0;var se=mn(lt.nodeName);if(Qn("uponSanitizeElement",lt,{tagName:se,allowedTags:tn}),lt.hasChildNodes()&&!Wr(lt.firstElementChild)&&(!Wr(lt.content)||!Wr(lt.content.firstElementChild))&&_(/<[/\w]/g,lt.innerHTML)&&_(/<[/\w]/g,lt.textContent)||se==="select"&&_(/