Indirect VoreFX (#7518)

This commit is contained in:
Eli
2024-01-18 14:03:02 +11:00
committed by GitHub
parent c820b6f0e5
commit 46d9a4979f
7 changed files with 97 additions and 26 deletions

View File

@@ -1596,7 +1596,8 @@
else
clear_alert("high")
if(!isbelly(loc) && !previewing_belly) //VOREStation Add - Belly fullscreens safety //CHOMPEdit
//CHOMPEdit - surrounding_belly() used instead of isbelly(loc) to not clear indirect vorefx
if(!surrounding_belly() && !previewing_belly) //VOREStation Add - Belly fullscreens safety //CHOMPEdit
clear_fullscreen("belly")
//clear_fullscreen("belly2") //Chomp disable, using our own implementation
//clear_fullscreen("belly3") //Chomp disable, using our own implementation

View File

@@ -137,6 +137,8 @@
var/item_digest_logs = FALSE // Chat messages for digested items.
var/storing_nutrition = FALSE // Storing gained nutrition as paste instead of absorbing it.
var/list/belly_surrounding = list() // A list of living mobs surrounded by this belly, including inside containers, food, on mobs, etc. Exclusing inside other bellies.
/obj/belly/proc/GetFullnessFromBelly()
if(!affects_vore_sprites)
return 0
@@ -521,9 +523,9 @@
/////////////////////////// CHOMP PCL END ///////////////////////////
/obj/belly/proc/update_internal_overlay()
if(LAZYLEN(contents))
if(LAZYLEN(belly_surrounding))
SEND_SIGNAL(src, COMSIG_BELLY_UPDATE_VORE_FX, TRUE) // Signals vore_fx() to listening atoms. Atoms must handle appropriate isliving() checks.
for(var/A in contents)
for(var/A in belly_surrounding)
if(isliving(A))
vore_fx(A,1)
if(owner.previewing_belly == src)
@@ -609,4 +611,25 @@
stored_nutrition = 0
qdel(src)
return
.=..()
.=..()
// Updates the belly_surrounding list variable. Called in bellymodes_vr.dm
/obj/belly/proc/update_belly_surrounding()
if(!contents.len)
belly_surrounding = list()
return
belly_surrounding = get_belly_surrounding(contents)
// Recursive proc that returns all living mobs directly and indirectly inside a belly
// This can also be called more generically to get all living mobs not in bellies within any contents list
/obj/belly/proc/get_belly_surrounding(var/list/C)
var/list/surrounding = list()
for(var/thing in C)
if(istype(thing,/mob/living))
var/mob/living/L = thing
surrounding.Add(L)
surrounding.Add(get_belly_surrounding(L.contents))
if(istype(thing,/obj/item))
var/obj/item/I = thing
surrounding.Add(get_belly_surrounding(I.contents))
return surrounding

View File

@@ -538,8 +538,17 @@
if(reagents.total_volume >= 5 && !isliving(thing) && (item_digest_mode == IM_DIGEST || item_digest_mode == IM_DIGEST_PARALLEL)) //CHOMPAdd
reagents.trans_to(thing, reagents.total_volume * 0.1, 1 / max(LAZYLEN(contents), 1), FALSE) //CHOMPAdd
//Messages if it's a mob
//CHOMPEdit Start - Include indirect viewers in seeing vorefx
var/list/startfx = list()
if(isliving(thing))
var/mob/living/M = thing
var/mob/living/L = thing
startfx.Add(L)
startfx.Add(get_belly_surrounding(L.contents))
if(istype(thing,/obj/item))
var/obj/item/I = thing
startfx.Add(get_belly_surrounding(I.contents))
for(var/mob/living/M in startfx) //CHOMPEdit End of indirect vorefx changes
M.updateVRPanel()
var/raw_desc //Let's use this to avoid needing to write the reformat code twice
if(absorbed_desc && M.absorbed)
@@ -570,7 +579,7 @@
if(digest_mode == DM_DIGEST)
reagents.trans_to(M, reagents.total_volume * 0.1, 1 / max(LAZYLEN(contents), 1), FALSE)
to_chat(M, "<span class='vwarning'><B>You splash into a pool of [reagent_name]!</B></span>")
else if(count_items_for_sprite) //CHOMPEdit - If this is enabled also update fullness for non-living things
if(!isliving(thing) && count_items_for_sprite) //CHOMPEdit - If this is enabled also update fullness for non-living things
owner.update_fullness() //CHOMPEdit - This is run whenever a belly's contents are changed.
//if(istype(thing, /obj/item/capture_crystal)) //CHOMPEdit start: Capture crystal occupant gets to see belly text too. Moved to modular_chomp capture_crystal.dm.
//var/obj/item/capture_crystal/CC = thing
@@ -596,18 +605,31 @@
if(count_items_for_sprite && !NB.count_items_for_sprite)
owner.update_fullness()
return //CHOMPEdit End
if(isliving(thing) && !isbelly(thing.loc))
owner.update_fullness() //CHOMPEdit - This is run whenever a belly's contents are changed.
//CHOMPEdit Start - Remove vorefx from all those indirectly viewing as well
var/list/endfx = list()
if(isliving(thing))
var/mob/living/L = thing
L.clear_fullscreen("belly")
//L.clear_fullscreen("belly2") // CHOMP Disable - using our implementation, not upstream's
//L.clear_fullscreen("belly3") // CHOMP Disable - using our implementation, not upstream's
//L.clear_fullscreen("belly4") // CHOMP Disable - using our implementation, not upstream's
if(L.hud_used)
if(!L.hud_used.hud_shown)
L.toggle_hud_vis()
if((L.stat != DEAD) && L.ai_holder)
L.ai_holder.go_wake()
endfx.Add(L)
endfx.Add(get_belly_surrounding(L.contents))
if(istype(thing,/obj/item))
var/obj/item/I = thing
endfx.Add(get_belly_surrounding(I.contents))
if(!isbelly(thing.loc))
for(var/mob/living/L in endfx) //CHOMPEdit End
if(L.surrounding_belly()) continue
owner.update_fullness() //CHOMPEdit - This is run whenever a belly's contents are changed.
L.clear_fullscreen("belly")
//L.clear_fullscreen("belly2") // CHOMP Disable - using our implementation, not upstream's
//L.clear_fullscreen("belly3") // CHOMP Disable - using our implementation, not upstream's
//L.clear_fullscreen("belly4") // CHOMP Disable - using our implementation, not upstream's
if(L.hud_used)
if(!L.hud_used.hud_shown)
L.toggle_hud_vis()
if((L.stat != DEAD) && L.ai_holder)
L.ai_holder.go_wake()
L.stop_sound_channel(CHANNEL_PREYLOOP) //CHOMPAdd - This was on release_specific_contents proc, why is it not here on belly exit?
//CHOMPEdit End of indirect vorefx changes
if(isitem(thing) && !isbelly(thing.loc)) //CHOMPEdit: Digest stage effects. Don't bother adding overlays to stuff that won't make it back out.
if(count_items_for_sprite) //CHOMPEdit - If this is enabled also update fullness for non-living things
owner.update_fullness() //CHOMPEdit - This is run whenever a belly's contents are changed.

View File

@@ -11,6 +11,7 @@
return
HandleBellyReagents() //CHOMP reagent belly stuff, here to jam it into subsystems and avoid too much cpu usage
update_belly_surrounding() //CHOMPAdd - Updates belly_surrounding list for indirect vore usage
// VERY early exit
if(!contents.len)
return
@@ -46,10 +47,11 @@
log_debug("Digest mode [digest_mode] didn't exist in the digest_modes list!!")
return FALSE
if(digest_mode == DM_EGG)
prey_loop() //CHOMPAdd - Apparently on Egg mode the sound loop never played before? Just slapping this here to fix that
if(DM.handle_atoms(src, contents))
updateVRPanels()
return
if(!length(touchable_atoms))
if(!length(touchable_atoms) && !belly_surrounding.len) //CHOMPEdit - Needed to not exit early for indirect vorefx
return
/////////////////////////// Sound Selections ///////////////////////////
@@ -93,7 +95,7 @@
SEND_SOUND(M, prey_digest)
play_sound = pred_digest
if(!LAZYLEN(touchable_mobs))
if(!LAZYLEN(belly_surrounding)) //CHOMPEdit - Changed to belly_surrounding from touchable_mobs so indirect vore viewers get this too
if(to_update)
updateVRPanels()
if(play_sound)
@@ -263,7 +265,7 @@
return list("to_update" = to_update, "touchable_mobs" = touchable_mobs, "digestion_noise_chance" = digestion_noise_chance)
/obj/belly/proc/prey_loop()
for(var/mob/living/M in contents)
for(var/mob/living/M in belly_surrounding) //CHOMPEdit - contents changed to belly_surrounding to loop sound for indirect viewers too
//We don't bother executing any other code if the prey doesn't want to hear the noises.
if(!M.is_preference_enabled(/datum/client_preference/digestion_noises))
M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case, because byond is whack and you can't trust it
@@ -272,7 +274,7 @@
// We don't want the sounds to overlap, but we do want them to steadily replay.
// We also don't want the sounds to play if the pred hasn't marked this belly as fleshy, or doesn't
// have the right sounds to play.
if(isbelly(M.loc) && is_wet && wet_loop && (world.time > M.next_preyloop))
if(is_wet && wet_loop && (world.time > M.next_preyloop)) //CHOMPEdit - Removed isbelly(M.loc) as some viewers might be indirectly in the belly
M.stop_sound_channel(CHANNEL_PREYLOOP)
var/sound/preyloop = sound('sound/vore/sunesound/prey/loop.ogg')
M.playsound_local(get_turf(src), preyloop, 80, 0, channel = CHANNEL_PREYLOOP, frequency = noise_freq) //CHOMPEdit
@@ -388,7 +390,7 @@
owner_adjust_nutrition(oldnutrition) //CHOMPedit end
/obj/belly/proc/updateVRPanels()
for(var/mob/living/M in contents)
for(var/mob/living/M in belly_surrounding) //CHOMPEdit - Changed to belly_surrounding from contents so updates happen for indirect viewers too
if(M.client)
M.updateVRPanel()
if(owner.client)

View File

@@ -351,3 +351,12 @@
set category = "Abilities"
set desc = "Check your current nutrition level."
to_chat(src, "<span class='vnotice'>Current nutrition level: [nutrition].</span>")
// This proc will either return the first belly the mob is in or return null if they're not in one
/mob/living/proc/surrounding_belly()
var/atom/curloc = src.loc
while(curloc && !isbelly(curloc))
if(istype(curloc, /turf)) break
if(!curloc.loc || curloc == curloc.loc) break
curloc = curloc.loc
if(isbelly(curloc)) return curloc

View File

@@ -120,6 +120,11 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono",
data["show_pictures"] = show_pictures
var/atom/hostloc = host.loc
//CHOMPAdd Start - Allow VorePanel to show pred belly details even while indirectly inside
if(istype(host, /mob/living))
var/mob/living/H = host
hostloc = H.surrounding_belly()
//CHOMPAdd End of indirect vorefx additions
var/list/inside = list()
if(isbelly(hostloc))
var/obj/belly/inside_belly = hostloc
@@ -1950,11 +1955,14 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono",
return TRUE // Aren't here anymore, need to update menu
var/intent = "Examine"
if(isliving(target))
intent = tgui_alert(usr, "What do you want to do to them?","Query",list("Examine","Help Out","Devour"))
//CHOMPEdit Start - Only allow indirect belly viewers to examine
if(user in OB)
if(isliving(target))
intent = tgui_alert(usr, "What do you want to do to them?","Query",list("Examine","Help Out","Devour"))
else if(istype(target, /obj/item))
intent = tgui_alert(usr, "What do you want to do to that?","Query",list("Examine","Use Hand"))
else if(istype(target, /obj/item))
intent = tgui_alert(usr, "What do you want to do to that?","Query",list("Examine","Use Hand"))
//CHOMPEdit End of indirect vorefx changes
switch(intent)
if("Examine") //Examine a mob inside another mob
@@ -2050,6 +2058,8 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono",
for(var/atom/movable/target in host.vore_selected)
to_chat(target,"<span class='warning'>You're squished from [host]'s [lowertext(host.vore_selected)] to their [lowertext(choice.name)]!</span>")
//CHOMPAdd - Send the transfer message to indirect targets as well. Slightly different message because why not.
to_chat(host.vore_selected.get_belly_surrounding(target.contents),"<span class='warning'>You're squished along with [target] from [host]'s [lowertext(host.vore_selected)] to their [lowertext(choice.name)]!</span>")
host.vore_selected.transfer_contents(target, choice, 1)
return TRUE
return
@@ -2095,6 +2105,8 @@ var/global/list/belly_colorable_only_fullscreens = list("a_synth_flesh_mono",
if(!choice || !(target in host.vore_selected))
return TRUE
to_chat(target,"<span class='warning'>You're squished from [host]'s [lowertext(host.vore_selected.name)] to their [lowertext(choice.name)]!</span>")
//CHOMPAdd - Send the transfer message to indirect targets as well. Slightly different message because why not.
to_chat(host.vore_selected.get_belly_surrounding(target.contents),"<span class='warning'>You're squished along with [target] from [host]'s [lowertext(host.vore_selected)] to their [lowertext(choice.name)]!</span>")
host.vore_selected.transfer_contents(target, choice)

View File

@@ -2,6 +2,7 @@
var/spawn_mob_name = "A mob"
var/obj/belly/in_gut = null
/* No longer need the vorefx additions as these will be handled for all indirect viewers now, including those in capture crystals
// Signals detect important procs from the host belly. Necessary to update visuals and sound loop for the player inside.
/obj/item/capture_crystal/enter_belly(obj/belly/B)
if(isbelly(B)) // Sanity
@@ -128,6 +129,7 @@
UnregisterSignal(in_gut, COMSIG_BELLY_UPDATE_VORE_FX)
UnregisterSignal(in_gut, COMSIG_BELLY_UPDATE_PREY_LOOP)
in_gut = null
*/
/obj/item/capture_crystal/loadout
active = TRUE