diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index c7daff49ed..82f38eb092 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -12,6 +12,7 @@
#define ui_boxcraft "EAST-4:22,SOUTH+1:6"
#define ui_boxarea "EAST-4:6,SOUTH+1:6"
#define ui_boxlang "EAST-5:22,SOUTH+1:6"
+#define ui_boxvore "EAST-4:22,SOUTH+1:6"
//Filters
#define CIT_FILTER_STAMINACRIT filter(type="drop_shadow", x=0, y=0, size=-3, border=0, color="#04080F")
@@ -130,5 +131,7 @@
//component stuff
#define COMSIG_COMBAT_TOGGLED "combatmode_toggled" //called by combat mode toggle on all equipped items. args: (mob/user, combatmode)
+#define COMSIG_VORE_TOGGLED "voremode_toggled" // totally not copypasta
+
//belly sound pref things
#define NORMIE_HEARCHECK 4
diff --git a/code/__DEFINES/voreconstants.dm b/code/__DEFINES/voreconstants.dm
index a133297315..710b11ae16 100644
--- a/code/__DEFINES/voreconstants.dm
+++ b/code/__DEFINES/voreconstants.dm
@@ -18,39 +18,6 @@
/* // removing sizeplay again
GLOBAL_LIST_INIT(player_sizes_list, list("Macro" = SIZESCALE_HUGE, "Big" = SIZESCALE_BIG, "Normal" = SIZESCALE_NORMAL, "Small" = SIZESCALE_SMALL, "Tiny" = SIZESCALE_TINY))
// Edited to make the new travis check go away
-
-
-GLOBAL_LIST_INIT(digest_pred, list(
- 'sound/vore/pred/digest_01.ogg',
- 'sound/vore/pred/digest_02.ogg',
- 'sound/vore/pred/digest_03.ogg',
- 'sound/vore/pred/digest_04.ogg',
- 'sound/vore/pred/digest_05.ogg',
- 'sound/vore/pred/digest_06.ogg',
- 'sound/vore/pred/digest_07.ogg',
- 'sound/vore/pred/digest_08.ogg',
- 'sound/vore/pred/digest_09.ogg',
- 'sound/vore/pred/digest_10.ogg',
- 'sound/vore/pred/digest_11.ogg',
- 'sound/vore/pred/digest_12.ogg',
- 'sound/vore/pred/digest_13.ogg',
- 'sound/vore/pred/digest_14.ogg',
- 'sound/vore/pred/digest_15.ogg',
- 'sound/vore/pred/digest_16.ogg',
- 'sound/vore/pred/digest_17.ogg',
- 'sound/vore/pred/digest_18.ogg'))
-
-GLOBAL_LIST_INIT(death_pred, list(
- 'sound/vore/pred/death_01.ogg',
- 'sound/vore/pred/death_02.ogg',
- 'sound/vore/pred/death_03.ogg',
- 'sound/vore/pred/death_04.ogg',
- 'sound/vore/pred/death_05.ogg',
- 'sound/vore/pred/death_06.ogg',
- 'sound/vore/pred/death_07.ogg',
- 'sound/vore/pred/death_08.ogg',
- 'sound/vore/pred/death_09.ogg',
- 'sound/vore/pred/death_10.ogg'))
*/
GLOBAL_LIST_INIT(vore_sounds, list(
@@ -66,79 +33,21 @@ GLOBAL_LIST_INIT(vore_sounds, list(
"Squish3" = 'sound/vore/pred/squish_03.ogg',
"Squish4" = 'sound/vore/pred/squish_04.ogg',
"Rustle (cloth)" = 'sound/effects/rustle5.ogg',
- "rustle2(cloth)" = 'sound/effects/rustle2.ogg',
- "rustle3(cloth)" = 'sound/effects/rustle3.ogg',
- "rustle4(cloth)" = 'sound/effects/rustle4.ogg',
- "rustle5(cloth)" = 'sound/effects/rustle5.ogg',
- "None" = null))
-/*
-GLOBAL_LIST_INIT(pred_struggle_sounds, list(
- "Struggle1" = 'sound/vore/pred/struggle_01.ogg',
- "Struggle2" = 'sound/vore/pred/struggle_02.ogg',
- "Struggle3" = 'sound/vore/pred/struggle_03.ogg',
- "Struggle4" = 'sound/vore/pred/struggle_04.ogg',
- "Struggle5" = 'sound/vore/pred/struggle_05.ogg'))
-
-GLOBAL_LIST_INIT(prey_vore_sounds, list(
- "Gulp" = 'sound/vore/prey/swallow_01.ogg',
- "Swallow" = 'sound/vore/prey/swallow_02.ogg',
- "Insertion1" = 'sound/vore/prey/insertion_01.ogg',
- "Insertion2" = 'sound/vore/prey/insertion_02.ogg',
- "Tauric Swallow" = 'sound/vore/prey/taurswallow.ogg',
- "Schlorp" = 'sound/vore/prey/schlorp.ogg',
- "Squish1" = 'sound/vore/prey/squish_01.ogg',
- "Squish2" = 'sound/vore/prey/squish_02.ogg',
- "Squish3" = 'sound/vore/prey/squish_03.ogg',
- "Squish4" = 'sound/vore/prey/squish_04.ogg'))
-
-
-GLOBAL_LIST_INIT(prey_struggle_sounds, list(
- "Struggle1" = 'sound/vore/prey/struggle_01.ogg',
- "Struggle2" = 'sound/vore/prey/struggle_02.ogg',
- "Struggle3" = 'sound/vore/prey/struggle_03.ogg',
- "Struggle4" = 'sound/vore/prey/struggle_04.ogg',
- "Struggle5" = 'sound/vore/prey/struggle_05.ogg'))
-
-GLOBAL_LIST_INIT(digest_prey, list(
- "digest1" = 'sound/vore/prey/digest_01.ogg',
- "digest2" = 'sound/vore/prey/digest_02.ogg',
- "digest3" = 'sound/vore/prey/digest_03.ogg',
- "digest4" = 'sound/vore/prey/digest_04.ogg',
- "digest5" = 'sound/vore/prey/digest_05.ogg',
- "digest6" = 'sound/vore/prey/digest_06.ogg',
- "digest7" = 'sound/vore/prey/digest_07.ogg',
- "digest8" = 'sound/vore/prey/digest_08.ogg',
- "digest9" = 'sound/vore/prey/digest_09.ogg',
- "digest10" = 'sound/vore/prey/digest_10.ogg',
- "digest11" = 'sound/vore/prey/digest_11.ogg',
- "digest12" = 'sound/vore/prey/digest_12.ogg',
- "digest13" = 'sound/vore/prey/digest_13.ogg',
- "digest14" = 'sound/vore/prey/digest_14.ogg',
- "digest15" = 'sound/vore/prey/digest_15.ogg',
- "digest16" = 'sound/vore/prey/digest_16.ogg',
- "digest17" = 'sound/vore/prey/digest_17.ogg',
- "digest18" = 'sound/vore/prey/digest_18.ogg'))
-
-GLOBAL_LIST_INIT(death_prey, list(
- "death1" = 'sound/vore/prey/death_01.ogg',
- "death2" = 'sound/vore/prey/death_02.ogg',
- "death3" = 'sound/vore/prey/death_03.ogg',
- "death4" = 'sound/vore/prey/death_04.ogg',
- "death5" = 'sound/vore/prey/death_05.ogg',
- "death6" = 'sound/vore/prey/death_06.ogg',
- "death7" = 'sound/vore/prey/death_07.ogg',
- "death8" = 'sound/vore/prey/death_08.ogg',
- "death9" = 'sound/vore/prey/death_09.ogg',
- "death10" = 'sound/vore/prey/death_10.ogg'))
- */
+ "Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
+ "Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
+ "Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg',
+ "Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg',
+ "None" = null
+ ))
GLOBAL_LIST_INIT(release_sounds, list(
- "rustle (cloth)" = 'sound/effects/rustle1.ogg',
- "rustle2 (cloth)" = 'sound/effects/rustle2.ogg',
- "rustle3 (cloth)" = 'sound/effects/rustle3.ogg',
- "rustle4 (cloth)" = 'sound/effects/rustle4.ogg',
- "rustle5 (cloth)" = 'sound/effects/rustle5.ogg',
- "Stomach Move" = 'sound/vore/pred/stomachmove.ogg',
- "Pred Escape" = 'sound/vore/pred/escape.ogg',
- "Splatter" = 'sound/effects/splat.ogg',
- "None" = null))
\ No newline at end of file
+ "Rustle (cloth)" = 'sound/effects/rustle1.ogg',
+ "Rustle 2 (cloth)" = 'sound/effects/rustle2.ogg',
+ "Rustle 3 (cloth)" = 'sound/effects/rustle3.ogg',
+ "Rustle 4 (cloth)" = 'sound/effects/rustle4.ogg',
+ "Rustle 5 (cloth)" = 'sound/effects/rustle5.ogg',
+ "Stomach Move" = 'sound/vore/pred/stomachmove.ogg',
+ "Pred Escape" = 'sound/vore/pred/escape.ogg',
+ "Splatter" = 'sound/effects/splat.ogg',
+ "None" = null
+ ))
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index b558e7c87c..a987f70d7b 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -85,6 +85,7 @@
#define ui_crafting "EAST-5:20,SOUTH:5"//CIT CHANGE - moves this over one tile to accommodate for combat mode toggle
#define ui_building "EAST-5:20,SOUTH:21"//CIT CHANGE - ditto
#define ui_language_menu "EAST-5:4,SOUTH:21"//CIT CHANGE - ditto
+#define ui_voremode "EAST-5:20,SOUTH:5"
#define ui_borg_pull "EAST-2:26,SOUTH+1:7"
#define ui_borg_radio "EAST-1:28,SOUTH+1:7"
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 1106bee711..01e118aaed 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -109,6 +109,13 @@
using.screen_loc = ui_boxarea // CIT CHANGE
static_inventory += using
+ using = new /obj/screen/voretoggle() //We fancy Vore now
+ using.icon = tg_ui_icon_to_cit_ui(ui_style)
+ using.screen_loc = ui_voremode
+ if(!widescreenlayout)
+ using.screen_loc = ui_boxvore
+ static_inventory += using
+
action_intent = new /obj/screen/act_intent/segmented
action_intent.icon_state = mymob.a_intent
static_inventory += action_intent
diff --git a/code/game/sound.dm b/code/game/sound.dm
index cceed31cfb..5503c6103d 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -213,6 +213,9 @@
'sound/vore/prey/death_04.ogg','sound/vore/prey/death_05.ogg','sound/vore/prey/death_06.ogg',
'sound/vore/prey/death_07.ogg','sound/vore/prey/death_08.ogg','sound/vore/prey/death_09.ogg',
'sound/vore/prey/death_10.ogg')
+ if("hunger_sounds")
+ soundin = pick( 'sound/vore/growl1.ogg','sound/vore/growl2.ogg','sound/vore/growl3.ogg','sound/vore/growl4.ogg',
+ 'sound/vore/growl5.ogg')
if("clang")
soundin = pick('sound/effects/clang1.ogg', 'sound/effects/clang2.ogg')
if("clangsmall")
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index e1935a9b5d..3fd710fcc6 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1143,7 +1143,15 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.add_trait(TRAIT_FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
-
+
+ if(H.noisy && H.nutrition <= NUTRITION_LEVEL_STARVING)
+ if(prob(10))
+ playsound(get_turf(H),"hunger_sounds",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
+
+ else if(H.noisy && H.nutrition <= NUTRITION_LEVEL_HUNGRY)
+ if(prob(10))
+ playsound(get_turf(H),"hunger_sounds",15,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
+
// nutrition decrease and satiety
if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER))
// THEY HUNGER
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index f6888a21ec..11e0c56d9e 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -8,6 +8,8 @@
spill_organs(no_brain, no_organs, no_bodyparts)
+ release_vore_contents(silent = TRUE) // return of the bomb safe internals.
+
if(!no_bodyparts)
spread_bodyparts(no_brain, no_organs)
@@ -36,6 +38,7 @@
buckled.unbuckle_mob(src, force = TRUE)
dust_animation()
+ release_vore_contents(silent = TRUE) //technically grief protection, I guess? if they're SM'd it doesn't matter seconds after anyway.
spawn_dust(just_ash)
QDEL_IN(src,5) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes.
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index f5b44db70f..643c91b95a 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -127,8 +127,18 @@
IgniteMob()
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
- if(user == src || anchored || !isturf(user.loc))
+ if(user == anchored || !isturf(user.loc))
return FALSE
+
+ if(user.pulling && user.grab_state == GRAB_AGGRESSIVE && user.voremode)
+ if(ismob(user.pulling))
+ var/mob/P = user.pulling
+ user.vore_attack(user, P, src) // User, Pulled, Predator target (which can be user, pulling, or src)
+ return
+
+ if(user == src) //we want to be able to self click if we're voracious
+ return FALSE
+
if(!user.pulling || user.pulling != src)
user.start_pulling(src, supress_message)
return
@@ -163,6 +173,8 @@
return 0
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
return 0
+ if(user.voremode && user.grab_state == GRAB_AGGRESSIVE)
+ return 0
user.grab_state++
switch(user.grab_state)
if(GRAB_AGGRESSIVE)
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 8c6300fab5..bf45c9cc73 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -63,6 +63,9 @@
..()
/mob/living/simple_animal/mouse/handle_automated_action()
+ if(isbelly(loc))
+ return
+
if(prob(chew_probability))
var/turf/open/floor/F = get_turf(src)
if(istype(F) && !F.intact)
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index d8635060ee..941ba0ec69 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -100,7 +100,7 @@
if(!target || !isturf(target.loc) || !isturf(loc) || stat == DEAD)
return
var/target_dir = get_dir(src,target)
-
+
var/static/list/cardinal_sidestep_directions = list(-90,-45,0,45,90)
var/static/list/diagonal_sidestep_directions = list(-45,0,45)
var/chosen_dir = 0
@@ -202,6 +202,8 @@
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
return FALSE
+ if(isbelly(the_target.loc)) //Target's inside a gut, forget about it too
+ return FALSE
if(search_objects < 2)
if(isliving(the_target))
var/mob/living/L = the_target
@@ -301,7 +303,7 @@
if(target)
if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack
MeleeAction()
- else
+ else
if(rapid_melee > 1 && target_distance <= melee_queue_distance)
MeleeAction(FALSE)
in_melee = FALSE //If we're just preparing to strike do not enter sidestep mode
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 43bc2c26f8..92ac07b1a0 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -83,18 +83,12 @@
if(L.stat != DEAD)
if(!client && ranged && ranged_cooldown <= world.time)
OpenFire()
-
- else if(L.stat >= SOFT_CRIT)
- if(vore_active == TRUE && L.devourable == TRUE)
- if(isliving(target) && !target.Adjacent(targets_from))
- return
- else
+ if(L.Adjacent(src) && (L.stat != CONSCIOUS))
+ if(vore_active && L.devourable == TRUE)
dragon_feeding(src,L)
- if(L.loc == src.contents)
- LoseTarget()
- return 0
- else
- devour(L)
+ LoseTarget()
+ else
+ devour(L)
/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L)
if(!L)
diff --git a/modular_citadel/code/_onclick/hud/screen_objects.dm b/modular_citadel/code/_onclick/hud/screen_objects.dm
index 5a193335f3..511627b81f 100644
--- a/modular_citadel/code/_onclick/hud/screen_objects.dm
+++ b/modular_citadel/code/_onclick/hud/screen_objects.dm
@@ -47,3 +47,21 @@
icon_state = "combat"
else
icon_state = "combat_off"
+
+/obj/screen/voretoggle
+ name = "toggle vore mode"
+ icon = 'modular_citadel/icons/ui/screen_midnight.dmi'
+ icon_state = "nom_off"
+
+/obj/screen/voretoggle/Click()
+ if(iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ C.toggle_vore_mode()
+
+/obj/screen/voretoggle/proc/rebaseintomygut(mob/living/carbon/C)
+ if(!C)
+ return
+ if(C.voremode && !C.combatmode)
+ icon_state = "nom"
+ else
+ icon_state = "nom_off"
diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm
index d52cc6eabb..cd24bfc8a2 100644
--- a/modular_citadel/code/modules/mob/living/carbon/carbon.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm
@@ -5,6 +5,9 @@
var/lastdirchange
var/combatmessagecooldown
+ //oh no vore time
+ var/voremode = FALSE
+
/mob/living/carbon/CanPass(atom/movable/mover, turf/target)
. = ..()
if(.)
@@ -19,6 +22,8 @@
if(recoveringstam)
return TRUE
combatmode = !combatmode
+ if(voremode)
+ toggle_vore_mode()
if(combatmode)
playsound_local(src, 'modular_citadel/sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
else
@@ -34,6 +39,16 @@
SEND_SIGNAL(src, COMSIG_COMBAT_TOGGLED, src, combatmode)
return TRUE
+mob/living/carbon/proc/toggle_vore_mode()
+ voremode = !voremode
+ if(hud_used && hud_used.static_inventory)
+ for(var/obj/screen/voretoggle/selector in hud_used.static_inventory)
+ selector.rebaseintomygut(src)
+ if(combatmode)
+ return FALSE //let's not override the main draw of the game these days
+ SEND_SIGNAL(src, COMSIG_VORE_TOGGLED, src, voremode)
+ return TRUE
+
/mob/living/carbon/Move(atom/newloc, direct = 0)
var/currentdirection = dir
. = ..()
diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm
index c1fc6623de..bbff8ee750 100644
--- a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm
@@ -1,9 +1,3 @@
-/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
- if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
- vore_attack(user, pulling)
- else
- ..()
-
/mob/living/carbon/human/alt_attack_hand(mob/user)
if(..())
return
diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index edc36ae3af..c34146a90c 100644
--- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -233,3 +233,5 @@
/mob/living/carbon/human/vore
devourable = TRUE
+ digestable = TRUE
+ feeding = TRUE
diff --git a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm
index 1aa8122be5..e931f37520 100644
--- a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm
+++ b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm
@@ -15,7 +15,7 @@
desc = "It's a belly! You're in it!" // Flavor text description of inside sight/sound/smells/feels.
var/vore_sound = "Gulp" // Sound when ingesting someone
var/vore_verb = "ingest" // Verb for eating with this in messages
- var/release_sound = "Splatter"
+ var/release_sound = "Splatter" // Sound for letting someone out.
var/human_prey_swallow_time = 100 // Time in deciseconds to swallow /mob/living/carbon/human
var/nonhuman_prey_swallow_time = 30 // Time in deciseconds to swallow anything else
var/emote_time = 60 SECONDS // How long between stomach emotes at prey
@@ -26,18 +26,18 @@
var/escapetime = 20 SECONDS // Deciseconds, how long to escape this belly
var/digestchance = 0 // % Chance of stomach beginning to digest if prey struggles
var/absorbchance = 0 // % Chance of stomach beginning to absorb if prey struggles
- var/escapechance = 100 // % Chance of prey beginning to escape if prey struggles.
+ var/escapechance = 0 // % Chance of prey beginning to escape if prey struggles.
var/can_taste = FALSE // If this belly prints the flavor of prey when it eats someone.
var/bulge_size = 0.25 // The minimum size the prey has to be in order to show up on examine.
// var/shrink_grow_size = 1 // This horribly named variable determines the minimum/maximum size it will shrink/grow prey to.
- var/silent = FALSE
- var/transferlocation = null // Location that the prey is released if they struggle and get dropped off.
+ var/transferlocation // Location that the prey is released if they struggle and get dropped off.
var/transferchance = 0 // % Chance of prey being transferred to transfer location when resisting
var/autotransferchance = 0 // % Chance of prey being autotransferred to transfer location
var/autotransferwait = 10 // Time between trying to transfer.
var/swallow_time = 10 SECONDS // for mob transfering automation
var/vore_capacity = 1 // simple animal nom capacity
+ var/is_wet = TRUE // Is this belly inside slimy parts?
//I don't think we've ever altered these lists. making them static until someone actually overrides them somewhere.
var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_NOISY,DM_ABSORB,DM_UNABSORB) // Possible digest modes
@@ -126,7 +126,6 @@
"escapechance",
"can_taste",
"bulge_size",
- "silent",
"transferlocation",
"transferchance",
"autotransferchance",
@@ -138,7 +137,8 @@
"digest_messages_owner",
"digest_messages_prey",
"examine_messages",
- "emote_lists"
+ "emote_lists",
+ "is_wet"
)
//ommitted list
@@ -167,10 +167,11 @@
to_chat(owner,"[thing] slides into your [lowertext(name)].")
//Sound w/ antispam flag setting
- if(!silent && !recent_sound)
- for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
+ if(is_wet && !recent_sound)
+ for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
- playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
+ var/sound/devourments = GLOB.vore_sounds[vore_sound]
+ playsound(get_turf(owner),devourments,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
recent_sound = TRUE
//Messages if it's a mob
@@ -182,8 +183,12 @@
// Release all contents of this belly into the owning mob's location.
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
// Returns the number of mobs so released.
-/obj/belly/proc/release_all_contents(var/include_absorbed = FALSE)
+/obj/belly/proc/release_all_contents(var/include_absorbed = FALSE, var/silent = FALSE)
var/atom/destination = drop_location()
+ //Don't bother if we don't have contents
+ if(!contents.len)
+ return 0
+
var/count = 0
for(var/thing in contents)
var/atom/movable/AM = thing
@@ -201,9 +206,16 @@
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
AM.forceMove(destination) // Move the belly contents into the same location as belly's owner.
count++
- for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
+ for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
- playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
+ var/sound/releasement = GLOB.release_sounds[release_sound]
+ playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
+
+ //Clean up our own business
+ items_preserved.Cut()
+ if(isanimal(owner))
+ owner.update_icons()
+
if(!silent)
owner.visible_message("[owner] expels everything from their [lowertext(name)]!")
items_preserved.Cut()
@@ -214,16 +226,16 @@
// Release a specific atom from the contents of this belly into the owning mob's location.
// If that location is another mob, the atom is transferred into whichever of its bellies the owning mob is in.
// Returns the number of atoms so released.
-/obj/belly/proc/release_specific_contents(var/atom/movable/M)
+/obj/belly/proc/release_specific_contents(var/atom/movable/M, var/silent = FALSE)
if (!(M in contents))
return FALSE // They weren't in this belly anyway
M.forceMove(drop_location()) // Move the belly contents into the same location as belly's owner.
items_preserved -= M
- if(release_sound)
- for(var/mob/H in get_hearers_in_view(5, get_turf(owner)))
- if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES))
- playsound(get_turf(owner),"[src.release_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
+ for(var/mob/H in get_hearers_in_view(2, get_turf(owner)))
+ if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES))
+ var/sound/releasement = GLOB.release_sounds[release_sound]
+ playsound(get_turf(owner),releasement,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
if(istype(M,/mob/living))
var/mob/living/ML = M
@@ -245,6 +257,11 @@
if(P.absorbed)
absorbed_count++
Pred.reagents.trans_to(Prey, Pred.reagents.total_volume / absorbed_count)
+
+ //Clean up our own business
+ if(isanimal(owner))
+ owner.update_icons()
+
if(!silent)
owner.visible_message("[owner] expels [M] from their [lowertext(name)]!")
owner.update_icons()
@@ -268,8 +285,10 @@
prey.forceMove(src)
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
- if(!silent)
+
+ if(is_wet)
prey.playsound_local(loc,preyloop,70,0, channel = CHANNEL_PREYLOOP)
+
owner.updateVRPanel()
for(var/mob/living/M in contents)
@@ -299,7 +318,8 @@
if(!silent)
for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
- playsound(get_turf(owner),"[src.vore_sound]",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
+ var/sound/devourments = GLOB.vore_sounds[vore_sound]
+ playsound(get_turf(owner),devourments,50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED)
owner.updateVRPanel()
for(var/mob/living/M in contents)
M.updateVRPanel()
@@ -461,6 +481,9 @@
//Yes, it's ""safe"" to drop items here
/obj/belly/AllowDrop()
return TRUE
+/*
+/obj/belly/onDropInto(var/atom/movable/AM)
+ return null */
//Handle a mob struggling
// Called from /mob/living/carbon/relaymove()
@@ -469,6 +492,23 @@
return // User is not in this belly
R.setClickCooldown(50)
+
+ if(owner.stat) //If owner is stat (dead, KO) we can actually escape
+ to_chat(R,"You attempt to climb out of \the [lowertext(name)]. (This will take around [escapetime/10] seconds.)")
+ to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!")
+
+ if(do_after(R, owner, escapetime))
+ if((owner.stat || escapable) && (R.loc == src)) //Can still escape?
+ release_specific_contents(R)
+ return
+ else if(R.loc != src) //Aren't even in the belly. Quietly fail.
+ return
+ else //Belly became inescapable or mob revived
+ to_chat(R,"Your attempt to escape [lowertext(name)] has failed!")
+ to_chat(owner,"The attempt to escape from your [lowertext(name)] has failed!")
+ return
+ return
+
var/struggle_outer_message = pick(struggle_messages_outside)
var/struggle_user_message = pick(struggle_messages_inside)
@@ -483,41 +523,38 @@
struggle_outer_message = "" + struggle_outer_message + ""
struggle_user_message = "" + struggle_user_message + ""
- if((owner.stat || !owner.client) && (R.a_intent != INTENT_HELP)) //If owner is stat (dead, KO) we can actually escape
- to_chat(R,"You attempt to climb out of \the [lowertext(name)]. (This will take around 5 seconds.)")
- to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!")
-
- if(!do_mob(R,owner,50))
- return
- if(!(R in contents)) //Aren't even in the belly. Quietly fail.
- return
- if(R.a_intent != INTENT_HELP) //still want to?
- release_specific_contents(R)
- return
- else //Belly became inescapable or mob revived
- to_chat(R,"Your attempt to escape [lowertext(name)] has failed!")
- to_chat(owner,"The attempt to escape from your [lowertext(name)] has failed!")
- return
- else if(R.a_intent != INTENT_HELP) //failsafe to make sure people are able to struggle out. friendly ERP should be on help intent.
- to_chat(R,"You attempt to climb out of [lowertext(name)]. (This will take around [escapetime] seconds.)")
- to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!")
- if(!do_mob(R,owner,escapetime))
- return
- release_specific_contents(R)
- return
- else if (R.a_intent == INTENT_HELP)
- for(var/mob/M in get_hearers_in_view(3, get_turf(owner)))
- M.show_message(struggle_outer_message, 1) // visible
- to_chat(R,struggle_user_message)
-
- if(!silent)
- for(var/mob/M in get_hearers_in_view(5, get_turf(owner)))
+ if(is_wet)
+ for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
playsound(get_turf(owner),"struggle_sound",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
R.stop_sound_channel(CHANNEL_PRED)
var/sound/prey_struggle = sound(get_sfx("prey_struggle"))
R.playsound_local(get_turf(R),prey_struggle,45,0)
+ else
+ for(var/mob/M in get_hearers_in_view(2, get_turf(owner)))
+ if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
+ playsound(get_turf(owner),"rustle",35,0,-5,1,ignore_walls = FALSE,channel=CHANNEL_PRED)
+
+ for(var/mob/M in get_hearers_in_view(3, get_turf(owner)))
+ if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) //Might as well censor the normies here too.
+ M.show_message(struggle_outer_message, 1) // visible
+ to_chat(R,struggle_user_message)
+
+ if(escapable) //If the stomach has escapable enabled.
+ if(prob(escapechance)) //Let's have it check to see if the prey escapes first.
+ to_chat(R,"You start to climb out of \the [lowertext(name)].")
+ to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]!")
+ if(do_after(R, escapetime))
+ if((owner.stat || escapable) && (R.loc == src)) //Can still escape?
+ release_specific_contents(R)
+ return
+ else if(R.loc != src) //Aren't even in the belly. Quietly fail.
+ return
+ else //Belly became inescapable or mob revived
+ to_chat(R,"Your attempt to escape [lowertext(name)] has failed!")
+ to_chat(owner,"The attempt to escape from your [lowertext(name)] has failed!")
+ return
else if(prob(transferchance) && transferlocation) //Next, let's have it see if they end up getting into an even bigger mess then when they started.
var/obj/belly/dest_belly
for(var/belly in owner.vore_organs)
@@ -525,6 +562,7 @@
if(B.name == transferlocation)
dest_belly = B
break
+
if(!dest_belly)
to_chat(owner, "Something went wrong with your belly transfer settings. Your [lowertext(name)] has had it's transfer chance and transfer location cleared as a precaution.")
transferchance = 0
@@ -541,21 +579,10 @@
to_chat(owner,"You feel your [lowertext(name)] start to cling onto its contents...")
digest_mode = DM_ABSORB
return
-/*
- else if(prob(digestchance) && digest_mode != DM_ITEMWEAK && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
+
+ else if(prob(digestchance) && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to get more active...")
to_chat(owner,"You feel your [lowertext(name)] beginning to become active!")
- digest_mode = DM_ITEMWEAK
- return
-
- else if(prob(digestchance) && digest_mode == DM_ITEMWEAK) //Oh god it gets even worse if you fail twice!
- to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to get even more active!")
- to_chat(owner,"You feel your [lowertext(name)] beginning to become even more active!")
- digest_mode = DM_DIGEST
- return */
- else if(prob(digestchance)) //Finally, let's see if it should run the digest chance.)
- to_chat(R, "In response to your struggling, \the [name] begins to get more active...")
- to_chat(owner, "You feel your [name] beginning to become active!")
digest_mode = DM_DIGEST
return
@@ -602,13 +629,13 @@
dupe.escapechance = escapechance
dupe.can_taste = can_taste
dupe.bulge_size = bulge_size
- dupe.silent = silent
dupe.transferlocation = transferlocation
dupe.transferchance = transferchance
dupe.autotransferchance = autotransferchance
dupe.autotransferwait = autotransferwait
dupe.swallow_time = swallow_time
dupe.vore_capacity = vore_capacity
+ dupe.is_wet = is_wet
//// Object-holding variables
//struggle_messages_outside - strings
diff --git a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm
index 6c528f75a9..542241e9f2 100644
--- a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm
+++ b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm
@@ -25,7 +25,7 @@
for(var/mob/living/M in contents)
if(isbelly(M.loc))
if(world.time > M.next_preyloop)
- if(!silent)
+ if(is_wet)
M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case
var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
M.playsound_local(get_turf(src),preyloop,80,0, channel = CHANNEL_PREYLOOP)
diff --git a/modular_citadel/code/modules/vore/eating/living_vr.dm b/modular_citadel/code/modules/vore/eating/living_vr.dm
index 2e6018f112..469dcee276 100644
--- a/modular_citadel/code/modules/vore/eating/living_vr.dm
+++ b/modular_citadel/code/modules/vore/eating/living_vr.dm
@@ -1,15 +1,16 @@
///////////////////// Mob Living /////////////////////
/mob/living
var/digestable = FALSE // Can the mob be digested inside a belly?
- var/obj/belly/vore_selected // Default to no vore capability.
- var/list/vore_organs = list() // List of vore containers inside a mob
+ var/showvoreprefs = TRUE // Determines if the mechanical vore preferences button will be displayed on the mob or not.
+ var/obj/belly/vore_selected // Default to no vore capability.
+ var/list/vore_organs = list() // List of vore containers inside a mob
var/devourable = FALSE // Can the mob be vored at all?
-// var/feeding = FALSE // Are we going to feed someone else?
- var/vore_taste = null // What the character tastes like
+ var/feeding = FALSE // Are we going to feed someone else?
+ var/vore_taste = null // What the character tastes like
var/no_vore = FALSE // If the character/mob can vore.
- var/openpanel = 0 // Is the vore panel open?
- var/noisy = FALSE // tummies are rumbly?
- var/absorbed = FALSE //are we absorbed?
+ var/openpanel = 0 // Is the vore panel open?
+ var/noisy = TRUE // tummies are rumbly?
+ var/absorbed = FALSE //are we absorbed?
var/next_preyloop
//
@@ -26,7 +27,8 @@
//Tries to load prefs if a client is present otherwise gives freebie stomach
spawn(10 SECONDS) // long delay because the server delays in its startup. just on the safe side.
- M.init_vore()
+ if(M)
+ M.init_vore()
//Return 1 to hook-caller
return 1
@@ -75,31 +77,42 @@
// Critical adjustments due to TG grab changes - Poojawa
-/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey)
- if(!user || !prey)
+/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
+ if(!user || !prey || !pred)
return
- if(prey == src && user.zone_selected == "mouth") //you click your target
-// if(!feeding(src))
-// return
- if(!is_vore_predator(prey))
+ if(!isliving(pred)) //no badmin, you can't feed people to ghosts or objects.
+ return
+
+ if(pred == prey) //you click your target
+ if(!pred.feeding)
+ to_chat(user, "They aren't able to be fed.")
+ to_chat(pred, "[user] tried to feed you themselves, but you aren't voracious enough to be fed.")
+ return
+ if(!is_vore_predator(pred))
to_chat(user, "They aren't voracious enough.")
return
- feed_self_to_grabbed(user, src)
+ feed_self_to_grabbed(user, pred)
- if(user == src) //you click yourself
+ if(pred == user) //you click yourself
if(!is_vore_predator(src))
to_chat(user, "You aren't voracious enough.")
return
- user.feed_grabbed_to_self(src, prey)
+ feed_grabbed_to_self(user, prey)
else // click someone other than you/prey
-// if(!feeding(src))
-// return
- if(!is_vore_predator(src))
+ if(!pred.feeding)
+ to_chat(user, "They aren't voracious enough to be fed.")
+ to_chat(pred, "[user] tried to feed you [prey], but you aren't voracious enough to be fed.")
+ return
+ if(!prey.feeding)
+ to_chat(user, "They aren't able to be fed to someone.")
+ to_chat(prey, "[user] tried to feed you to [pred], but you aren't able to be fed to them.")
+ return
+ if(!is_vore_predator(pred))
to_chat(user, "They aren't voracious enough.")
return
- feed_grabbed_to_other(user, prey, src)
+ feed_grabbed_to_other(user, prey, pred)
//
// Eating procs depending on who clicked what
//
@@ -120,7 +133,7 @@
return perform_the_nom(user, user, pred, belly)
/mob/living/proc/feed_grabbed_to_other(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
- return//disabled until I can make that toggle work
+// return//disabled until I can make that toggle work
var/belly = input("Choose Belly") in pred.vore_organs
return perform_the_nom(user, prey, pred, belly)
@@ -281,7 +294,7 @@
*/
//
-// Custom resist catches for /mob/living
+// Our custom resist catches for /mob/living
//
/mob/living/proc/vore_process_resist()
@@ -293,7 +306,7 @@
//Other overridden resists go here
- return FALSE
+ return 0
// internal slimy button in case the loop stops playing but the player wants to hear it
/mob/living/proc/preyloop_refresh()
@@ -320,9 +333,9 @@
return
//Actual escaping
forceMove(get_turf(src)) //Just move me up to the turf, let's not cascade through bellies, there's been a problem, let's just leave.
- if(is_blind(src) && !has_trait(TRAIT_BLIND))
- src.adjust_blindness(-1)
+ src.cure_blind("belly_[REF(src)]")
src.stop_sound_channel(CHANNEL_PREYLOOP)
+ SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
for(var/mob/living/simple_animal/SA in range(10))
SA.prey_excludes[src] = world.time
@@ -374,6 +387,7 @@
P.digestable = src.digestable
P.devourable = src.devourable
+ P.feeding = src.feeding
P.vore_taste = src.vore_taste
var/list/serialized = list()
@@ -397,6 +411,7 @@
digestable = P.digestable
devourable = P.devourable
+ feeding = P.feeding
vore_taste = P.vore_taste
release_vore_contents(silent = TRUE)
diff --git a/modular_citadel/code/modules/vore/eating/vore_vr.dm b/modular_citadel/code/modules/vore/eating/vore_vr.dm
index 16366bbb14..4cf223c3c4 100644
--- a/modular_citadel/code/modules/vore/eating/vore_vr.dm
+++ b/modular_citadel/code/modules/vore/eating/vore_vr.dm
@@ -28,7 +28,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
// The datum type bolted onto normal preferences datums for storing Vore stuff
//
-#define VORE_VERSION 2
+#define VORE_VERSION 3
GLOBAL_LIST_EMPTY(vore_preferences_datums)
@@ -39,6 +39,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
//Actual preferences
var/digestable = FALSE
var/devourable = FALSE
+ var/feeding = FALSE
// var/allowmobvore = TRUE
var/list/belly_prefs = list()
var/vore_taste = "nothing in particular"
@@ -105,6 +106,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
digestable = json_from_file["digestable"]
devourable = json_from_file["devourable"]
+ feeding = json_from_file["feeding"]
vore_taste = json_from_file["vore_taste"]
belly_prefs = json_from_file["belly_prefs"]
@@ -113,6 +115,8 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
digestable = FALSE
if(isnull(devourable))
devourable = FALSE
+ if(isnull(feeding))
+ feeding = FALSE
if(isnull(belly_prefs))
belly_prefs = list()
@@ -127,6 +131,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
"version" = version,
"digestable" = digestable,
"devourable" = devourable,
+ "feeding" = feeding,
"vore_taste" = vore_taste,
"belly_prefs" = belly_prefs,
)
diff --git a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm
index 30209b6da2..c83ee788cb 100644
--- a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm
+++ b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm
@@ -18,9 +18,10 @@
var/dat = picker_holder.gen_vui(src)
- picker_holder.popup = new(src, "insidePanel","Vore Panel", 400, 600, picker_holder)
+ picker_holder.popup = new(src, "insidePanel","Vore Panel", 450, 700, picker_holder)
picker_holder.popup.set_content(dat)
picker_holder.popup.open()
+ src.openpanel = 1
/mob/living/proc/updateVRPanel() //Panel popup update call from belly events.
if(src.openpanel == 1)
@@ -30,7 +31,7 @@
var/dat = picker_holder.gen_vui(src)
- picker_holder.popup = new(src, "insidePanel","Vore Panel", 400, 600, picker_holder)
+ picker_holder.popup = new(src, "insidePanel","Vore Panel", 450, 700, picker_holder)
picker_holder.popup.set_content(dat)
picker_holder.popup.open()
@@ -39,7 +40,7 @@
//
/datum/vore_look
var/obj/belly/selected
- var/show_interacts = TRUE
+ var/show_interacts = 0
var/datum/browser/popup
var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
@@ -55,13 +56,14 @@
/datum/vore_look/proc/gen_vui(var/mob/living/user)
var/dat
-
+ dat += "Remember to toggle the vore mode, it's to the left of your combat toggle. Open mouth means you're voracious!
"
+ dat += "