move the internal preview to canvas (#18930)

* move the internal preview to canvas

* use a helper

* basic readme prep

* .

* .

* transform  better

* byond can't handle icon states of large files...

* move fully to the rust version

* fix typing

* just wtf. NO

* fix the legacy path

* keep it all centralized

* tiny oversight

* unit test rewrite

* rename

* fix bad layering

* fixes a bunch of layering issues

* artifact

* move crash to log_runtime

* missing overlay warning

* why not
This commit is contained in:
Kashargul
2025-12-24 05:28:39 +01:00
committed by GitHub
parent c4134dbf04
commit 92182e0946
79 changed files with 477 additions and 310 deletions
+3 -3
View File
@@ -440,7 +440,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
/datum/asset/spritesheet/proc/queuedInsert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
if(!I || !length(cached_icon_states(I))) // that direction or state doesn't exist
if(!I || !length(icon_states_fast(I))) // that direction or state doesn't exist
return
var/size_id = "[I.Width()]x[I.Height()]"
var/size = sizes[size_id]
@@ -476,7 +476,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
if(!directions)
directions = list(SOUTH)
for(var/icon_state_name in cached_icon_states(I))
for(var/icon_state_name in icon_states_fast(I))
for(var/direction in directions)
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : ""
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
@@ -558,7 +558,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
var/generic_icon_names = FALSE //generate icon filenames using generate_asset_name() instead the above format
/datum/asset/simple/icon_states/register(_icon = icon)
for(var/icon_state_name in icon_states(_icon))
for(var/icon_state_name in icon_states_fast(_icon))
for(var/direction in directions)
var/asset = icon(_icon, icon_state_name, direction, frame, movement_states)
if(!asset)
@@ -1,3 +1,10 @@
/datum/overlay_previews
var/old_precolored = 'icons/mob/vore_fullscreens/ui_lists/screen_full_vore.dmi'
var/base = 'icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_base.dmi'
var/layer1 = 'icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_layer1.dmi'
var/layer2 = 'icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_layer2.dmi'
var/layer3 = 'icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_layer3.dmi'
/datum/belly_overlays
var/belly_icon
/*
@@ -273,13 +280,3 @@
/datum/belly_overlays/synth_flesh_mono_hole
belly_icon = 'icons/mob/vore_fullscreens/synth_flesh_mono_hole.dmi'
/datum/belly_overlays/yet_another_tumby
belly_icon = 'icons/mob/vore_fullscreens/yet_another_tumby.dmi'
//Compatibility assets due to renames...
/datum/belly_overlays/anim_belly
belly_icon = 'icons/mob/vore_fullscreens/VBOanim_belly1.dmi'
/datum/belly_overlays/a_anim_belly
belly_icon = 'icons/mob/vore_fullscreens/VBOanim_belly1.dmi'
@@ -58,7 +58,7 @@
var/obj/machinery/computer/C = item
var/screen = initial(C.icon_screen)
var/keyboard = initial(C.icon_keyboard)
var/all_states = cached_icon_states(icon_file)
var/all_states = icon_states_fast(icon_file)
if (screen && (screen in all_states))
transform.blend_icon(uni_icon(icon_file, screen), ICON_OVERLAY)
if (keyboard && (keyboard in all_states))
@@ -22,7 +22,7 @@
var/datum/universal_icon/I
var/icon_states_list = cached_icon_states(icon_file)
var/icon_states_list = icon_states_fast(icon_file)
if(icon_state in icon_states_list)
I = uni_icon(icon_file, icon_state, SOUTH)
var/c = initial(item.color)
@@ -1,15 +0,0 @@
/datum/asset/spritesheet/vore
name = "vore"
/datum/asset/spritesheet/vore/create_spritesheets()
var/icon/downscaled = icon('icons/mob/screen_full_vore_list.dmi') // preserving save data
downscaled.Scale(240, 240)
InsertAll("", downscaled)
/datum/asset/spritesheet/vore_fixed //This should be getting loaded in the TGUI vore panel but the game refuses to do so, for some reason. It only loads the vore spritesheet.
name = "fixedvore"
/datum/asset/spritesheet/vore_fixed/create_spritesheets() // preserving save data
var/icon/downscaledVF = icon('icons/mob/screen_full_vore.dmi')
downscaledVF.Scale(240, 240)
InsertAll("", downscaledVF)
@@ -158,7 +158,7 @@
if (!directions)
directions = list(SOUTH)
for (var/icon_state_name in icon_states(I))
for (var/icon_state_name in icon_states_fast(I))
for (var/direction in directions)
var/prefix2 = (directions.len > 1 && prefix_with_dirs) ? "[dir2text(direction)]-" : ""
insert_icon("[prefix][prefix2][icon_state_name]", uni_icon(I, icon_state_name, direction))
@@ -487,7 +487,7 @@
var/dir_count = state_data["dirs"]
if(dir_count == 1)
base_icon_dir = SOUTH
else if(!length(icon_states(icon(curicon, curstate, NORTH))))
else if(!length(icon_states_fast(icon(curicon, curstate, NORTH))))
base_icon_dir = SOUTH
var/list/icon_dimensions = get_icon_dimensions(curicon)
+1 -1
View File
@@ -1395,7 +1395,7 @@
// only override icon if a corresponding digitigrade replacement icon_state exists
// otherwise, keep the old non-digi icon_define (or nothing)
if(icon_state && cached_icon_states(update_icon_define_digi):Find(icon_state)) //Unsure what to do to this seeing as it does :Find()
if(icon_state && icon_states_fast(update_icon_define_digi):Find(icon_state)) //Unsure what to do to this seeing as it does :Find()
update_icon_define = update_icon_define_digi
+1 -1
View File
@@ -78,7 +78,7 @@
var/list/new_item_icons = list()
var/list/new_item_state_slots = list()
var/list/available_states = cached_icon_states(CUSTOM_ITEM_MOB)
var/list/available_states = icon_states_fast(CUSTOM_ITEM_MOB)
//If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots
//Then use icon_override to make every other slot use the custom sprites by default.
@@ -160,7 +160,7 @@
B.digest_brute = 0.5
B.digest_burn = 0.5
B.escapechance = 20
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.belly_fullscreen_color = "#660021"
B.belly_fullscreen_color2 = "#660021"
B.fancy_vore = 1
@@ -49,7 +49,7 @@
B.name = "stomach"
B.desc = "The hot churning stomach of a turkey girl! The doughy flesh presses inward to form to your figure, thick slime coating everything, and very shortly that includes you as well! There isn't any escaping that constant full body motion, as her body works to ball yours up into a tight little package. Gurgling and glubbing with every shifting movement, while her pulse throbs through the flesh all around you with every beat of her heart. All in all, one thing is for certain! You've become turkey stuffing! Oh no..."
B.mode_flags = DM_FLAG_THICKBELLY | DM_FLAG_NUMBING
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.digest_brute = 1
B.digest_burn = 6
B.digestchance = 0
@@ -47,7 +47,7 @@
B.name = "tail"
B.desc = "The small critter seems to suddenly panic, lunging at you with its massive fluffy tail, using it like a weapon. Despite the appearance of the tail, it seems to be much larger on the inside, suddenly engulfing you completely in a world of endless softness. Inside, you are bound up nice and tight in an oddly comfortable prison of hair, it ripples over your body tickling every bit of exposed body on offer."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 1
B.digest_burn = 1
B.digest_oxy = 0
@@ -48,7 +48,7 @@
B.name = "stomach"
B.desc = "The giant bat has managed to swallow you alive, which is particularly impressive given that it's still a rather small creature. It's belly bulges out as you're squeezed into the oppressively tight stomach, and it lands to manage the weight, wings curling over your form beneath. The body groans under your strain, burbling and growling as it gets to work on it's feed. However, at least for now, it seems to do you no physical harm. Instead, the damp walls that squelch across your body try to leech out your energy through some less direct means."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 2
B.digest_burn = 2
B.digest_oxy = 1
@@ -660,7 +660,7 @@ I think I covered everything.
mode_flags = DM_FLAG_NUMBING
struggle_messages_inside = list(
"Deciding that you've stayed long enough, you wriggle and writhe, stretching yourself out in the chamber, trying to thrust your hands and face up the way you entered. The beast stirs, and this churny pocket of flesh providing you safety clenches hard, aiding your entry back up into the lowermost depths of it's gullet. rhythmic clenches continue to invite you back down, however, should you reconsider.")
belly_fullscreen = "anim_belly"
belly_fullscreen = "VBOanim_belly1"
///
/// AI handling stuff
@@ -380,7 +380,7 @@
B.release_sound = "Pred Escape"
B.fancy_vore = 1
B.belly_fullscreen_color = "#380000"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.name = "fuel processor"
B.desc = "Uttering distorted growls and fragmented voice clips all the while, the corrupted hound gulps the rest of your squirming figure past its jaws... which snap shut with an audible click of metal on metal. Your trip down its slickly lubricated, rubbery gullet is a tight and efficient one... and once you spill out into the machine's fuel processor, your weight making it sag slightly, hot-and-thick slime begins oozing all over your form. Only time will tell if you're destined to become fuel for its next bout of rampaging... be it days, hours, or just mere minutes..."
@@ -76,7 +76,7 @@
B.release_sound = "Pred Escape"
B.fancy_vore = TRUE
B.belly_fullscreen_color = "#c47cb4"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
/datum/say_list/fennec
speak = list("SKREEEE!","Chrp?","Ararrrararr.")
@@ -131,7 +131,7 @@
B.contamination_color = "grey"
B.contamination_flavor = "Wet"
B.belly_fullscreen_color = "#c47cb4"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.emote_lists[DM_HOLD] = list(
"The wolf's idle wandering helps its stomach gently churn around you, slimily squelching against your figure.",
@@ -95,7 +95,7 @@
B.contamination_color = "grey"
B.contamination_flavor = "Wet"
B.belly_fullscreen_color = "#c47cb4"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.emote_lists[DM_HEAL] = list(
"The drake's idle movement helps its stomach gently churn around you, slimily squelching against your figure.",
"The draconic predator takes a moment to intentionally clench its gut around you, encapsulating you in a strange, fleshy hug.",
@@ -192,7 +192,7 @@
B.contamination_flavor = "Wet"
B.belly_fullscreen_color = "#df3dbc"
B.belly_fullscreen_alpha = 240
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.emote_lists[DM_HEAL] = list(
"The drake's idle movement helps its stomach gently churn around you, slimily squelching against your figure.",
"The draconic predator takes a moment to intentionally clench its gut around you, encapsulating you in a strange, fleshy hug.",
@@ -44,7 +44,7 @@
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.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 1
B.digest_burn = 1
B.digest_oxy = 1
@@ -60,7 +60,7 @@
B.name = "stomach"
B.desc = "You've somehow managed to get yourself eaten by one of the local peasants. After jamming you down into their stomach, you find yourself cramped up tight in a space that clearly shouldn't be able to accept you. They let out a relieved sigh as they heft around their new found weight, giving it a hearty pat, clearly content to get a good meal for once. The world around you groans and grumbles, but the gut is far from harmful to you right now, even as the walls clench down on your body."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 1
B.digest_burn = 1
B.digest_oxy = 0
@@ -103,7 +103,7 @@
B.release_sound = "Pred Escape"
B.fancy_vore = TRUE
B.belly_fullscreen_color = "#b15aac"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
/datum/say_list/rabbit
speak = list("chrrrs.")
@@ -82,7 +82,7 @@
B.release_sound = "Pred Escape"
B.fancy_vore = TRUE
B.belly_fullscreen_color = "#c47cb4"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.emote_lists[DM_HOLD] = list(
"As time passes, the massive rat's stomach slowly churns and squeezes down around you, packing you into an easier to carry bundle amidst that oddly soothing massage.",
@@ -102,7 +102,7 @@
B.vore_sound = "Tauric Swallow"
B.release_sound = "Pred Escape"
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "a_anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
B.fancy_vore = 1
B.selective_preference = DM_SELECT
B.vore_verb = "devour"
@@ -46,7 +46,7 @@
B.name = "stomach"
B.desc = "Despite the small size of the scrubble, it seems to have a lot of energy behind it. The critter dives atop you in a panic, its maw quickly engulfing your head as its paws flail scrabble against you, hot slobber slathering across your tightly trapped face. It takes a little repositioning to get itself in the right position, but soon the creature is gulping its way down your entire body. Somehow it manages to squeeze you completely into a gut that should rightly be far too small for anything but a mouse, bundling up your body into a tight ball as the walls around you clench in tightly to keep you nice and compact. The sounds of burbling and glorping echo through the intensely tight space as the stomach lining grinds in thick oozes against your skin, pressure so high that you can barely move a muscle."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 1
B.digest_burn = 1
B.digest_oxy = 0
@@ -49,7 +49,7 @@
B.name = "stomach"
B.desc = "The creature's huge maw drops down over your body, the long neck preventing it from barely having to shift its torso at all. The jaws quickly travel down you, slathering you in a drool as you're quickly stuffed through the flexible muscle of the throat. In a matter of seconds you are effortlessly lifted from the ground, your entire figure now reduced to a bulge within the neck of the beast, your feet soon vanishing into its mouth with a visceral gulp. The journey down is a long and slow one, the gullet squeezing you steadily along with heavy rippling contractions, the sonadile is quite content that you're heading in the right direction. With every inch, the world around you grows louder with the sound of a heartbeat and the gutteral grumbles of your upcoming destination. Before long you are squeezed down through a tight fleshy valve and deposited in the stomach of the reptile, walls immediately bearing down on you from every direction to ensure that you're tightly confined with little room to move. Hot, humid and slick with all manner of thick and thin liquids, this place isn't treating you any different from whatever else this animal likes to eat."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 2
B.digest_burn = 2
B.digest_oxy = 1
@@ -49,7 +49,7 @@
B.name = "stomach"
B.desc = "The lithe creature spends only minimal time with you pinned beneath it, before it's jaws stretch wide ahead of your face. The slightly blue hued interior squelches tightly over your head as the stalker's teeth prod against you, threatening to become much more of a danger if you put up too much of a fight. However, the process is quick, your body is efficiently squeezed through that tight gullet, contractions dragging you effortlessly towards the creature's gut. The stomach swells and hangs beneath the animal, swaying like a hammock under the newfound weight. The walls wrap incredibly tightly around you, compressing you tightly into a small ball as it grinds caustic juices over you."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 2
B.digest_burn = 2
B.digest_oxy = 1
@@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(succubus_safewords, list(
B.name = "stomach"
B.desc = "You find yourself tightly compressed into the stomach of the succubus, with immense pressure squeezing down on you from every direction. The wrinkled walls of the gut knead over you, like a swelteringly hot, wet massage. You can feel movement from the outside, as though the demoness is running her hands over your form with delight. The world around you groans and gurgles, but the fluids that ooze into this place don't seem harmful, yet. Instead, you feel your very energy being steadily depleted, much to the joy of the woman who's claiming it all for herself."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 2
B.digest_burn = 2
B.digest_oxy = 1
@@ -60,7 +60,7 @@
B.name = "stomach"
B.desc = "Having been rapidly gulped up by the vampire, you find yourself tightly contained with a set of groaning, wrinkled walls. It seems that the beast has decided against draining your lifeforce through you blood, and instead taking a more direct approach as it saps your strength from all around you. Your attacker seems content to just take that essence for now, but it is a gut afterall and struggling may set it off."
B.mode_flags = DM_FLAG_THICKBELLY
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.digest_brute = 3
B.digest_burn = 0
B.digest_oxy = 1
@@ -308,7 +308,7 @@
B.name = "interior"
B.desc = "An incredibly thick oozing slime surrounds you, filling in all the space around your form! It's hard to catch a breath here as the jiggling gel that makes up the body of the creature swiftly fills in the hole you made in its surface by entering. The gel is semi-transparent, and you can see your surroundings though its surface, and similarly you can be seen floating in the gel from the outside. When the cube moves, your whole body is wobbled along with it. There are clouds of still processing material floating all around you as the corrosive substance works on breaking everything down."
B.mode_flags = DM_FLAG_NUMBING
B.belly_fullscreen = "yet_another_tumby"
B.belly_fullscreen = "VBO_fleshs"
B.colorization_enabled = TRUE
B.belly_fullscreen_color = color
B.digest_brute = 2
@@ -51,7 +51,7 @@
B.release_sound = "Pred Escape"
B.fancy_vore = 1
B.belly_fullscreen_color = "#c47cb4"
B.belly_fullscreen = "anim_belly"
B.belly_fullscreen = "VBOanim_belly1"
// Space edition, stronger and bitier
/mob/living/simple_mob/vore/wolf/space
+1 -1
View File
@@ -25,7 +25,7 @@
author = _author
/obj/effect/decal/writing/Initialize(mapload)
var/list/random_icon_states = cached_icon_states(icon)
var/list/random_icon_states = icon_states_fast(icon)
for(var/obj/effect/decal/writing/writing in loc)
random_icon_states.Remove(writing.icon_state)
if(length(random_icon_states))
+1 -1
View File
@@ -235,7 +235,7 @@ GLOBAL_LIST_EMPTY(magazine_icondata_states)
/proc/magazine_icondata_cache_add(var/obj/item/ammo_magazine/M)
var/list/icon_keys = list()
var/list/ammo_states = list()
var/list/states = cached_icon_states(M.icon)
var/list/states = icon_states_fast(M.icon)
for(var/i = 0, i <= M.max_ammo, i++)
var/ammo_state = "[M.icon_state]-[i]"
if(ammo_state in states)
+2 -2
View File
@@ -105,7 +105,6 @@
#include "map_tests.dm"
#include "mapping.dm"
#include "material_tests.dm"
#include "mob_vbo_test.dm"
// #include "nuke_cinematic.dm" // TODO: This is probably fixed later on
#include "poster_tests.dm"
// #include "preferences.dm" // This unit test is missing some other stuff
@@ -121,7 +120,8 @@
#include "timer_sanity.dm"
#include "trait_tests.dm"
#include "unit_test.dm"
// #include "vore_tests.dm" // FIXME: REWRITE OR FIX THIS
#include "vbo_tests.dm"
#include "vore_tests.dm"
// END_INCLUDE
#ifdef REFERENCE_TRACKING_DEBUG //Don't try and parse this file if ref tracking isn't turned on. IE: don't parse ref tracking please mr linter
#include "find_reference_sanity.dm"
@@ -1,3 +1,12 @@
/// Tests that all mobs with assigned bellies use valid datums
/datum/unit_test/vbo_has_state
/datum/unit_test/vbo_has_state/Run()
for(var/datum/belly_overlays/test_path as anything in subtypesof(/datum/belly_overlays))
var/icon_name = icon_states_fast(initial(test_path.belly_icon))[1]
if(!(icon_exists('icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_base.dmi', icon_name)))
TEST_FAIL("[test_path] is missing inside the screen_full_vore_list_base list dmi file.")
/// Tests that all mobs with assigned bellies use valid datums
/datum/unit_test/mobs_use_valid_belly_overlays
+64 -175
View File
@@ -1,214 +1,103 @@
/// converted unit test, maybe should be fully refactored
/datum/unit_test/proc/create_test_human(turf/loc = null)
if(!loc)
for(var/turf/simulated/floor/tiled/T in world)
var/pressure = T.zone.air.return_pressure()
if(90 < pressure && pressure < 120) // Find a turf between 90 and 120
loc = T
break
// FIXME: THIS SHOULD BE REPLACED WITH ALLOCATE IN THE END
// SEE unit_test.dm NEW() WHY THIS ISNT IMPLEMENTED YET
/datum/unit_test
var/static/default_mobloc = null
TEST_ASSERT(loc, "No valid turf available for test mob")
// FIXME: THIS SHOULD BE REPLACED WITH ALLOCATE IN THE END
// SEE unit_test.dm NEW() WHY THIS ISNT IMPLEMENTED YET
/datum/unit_test/proc/create_test_mob(var/turf/mobloc = null, var/mobtype = /mob/living/carbon/human, var/with_mind = FALSE)
if(isnull(mobloc))
if(!default_mobloc)
for(var/turf/simulated/floor/tiled/T in world)
var/pressure = T.zone.air.return_pressure()
if(90 < pressure && pressure < 120) // Find a turf between 90 and 120
default_mobloc = T
break
mobloc = default_mobloc
if(!mobloc)
fail("Unable to find a location to create test mob")
return 0
var/mob/living/carbon/human/test_human = allocate(/mob/living/carbon/human, loc)
var/mob/living/carbon/human/H = new mobtype(mobloc)
return test_human
if(with_mind)
H.mind_initialize("TestKey[rand(0,10000)]")
return H
/// Test that a human mob does not suffocate in a belly
/datum/unit_test/belly_nonsuffocation
var/startLifeTick
var/startOxyloss
var/endOxyloss
var/mob/living/carbon/human/pred
var/mob/living/carbon/human/prey
/datum/unit_test/belly_nonsuffocation/Run()
pred = create_test_mob()
if(!istype(pred))
return 0
prey = create_test_mob(pred.loc)
if(!istype(prey))
return 0
var/mob/living/carbon/human/pred = create_test_human()
var/mob/living/carbon/human/prey = create_test_human()
return 1
TEST_ASSERT(pred && prey, "Failed to create test mobs")
/datum/unit_test/belly_nonsuffocation/check_result()
// Unfortuantely we need to wait for the pred's belly to initialize. (Currently after a spawn())
if(!pred.vore_organs || !pred.vore_organs.len)
return 0
pred.init_vore(TRUE)
TEST_ASSERT(pred.vore_selected, "[pred] has no vore_selected")
// Now that pred belly exists, we can eat the prey.
if(!pred.vore_selected)
fail("[pred] has no vore_selected.")
return 1
pred.vore_selected.nom_mob(prey)
// Attempt to eat the prey
if(prey.loc != pred.vore_selected)
pred.vore_selected.nom_mob(prey)
TEST_ASSERT(prey.loc == pred.vore_selected, "Prey not inside predator belly")
if(prey.loc != pred.vore_selected)
fail("[pred.vore_selected].nom_mob([prey]) did not put prey inside [pred]")
return 1
var/start_oxy = prey.getOxyLoss()
var/end_tick = pred.life_tick + 10
// Okay, we succeeded in eating them, now lets wait a bit
startLifeTick = pred.life_tick
startOxyloss = prey.getOxyLoss()
return 0
while(pred.life_tick < end_tick)
sleep(1)
if(pred.life_tick < (startLifeTick + 10))
return 0 // Wait for them to breathe a few times
var/end_oxy = prey.getOxyLoss()
if(end_oxy > start_oxy)
TEST_FAIL("Prey took oxygen damage in belly (before: [start_oxy], after: [end_oxy])")
// Alright lets check it!
endOxyloss = prey.getOxyLoss()
if(startOxyloss < endOxyloss)
fail("Prey takes oxygen damage in a pred's belly! (Before: [startOxyloss]; after: [endOxyloss])")
else
pass("Prey is not taking oxygen damage in pred's belly. (Before: [startOxyloss]; after: [endOxyloss])")
qdel(prey)
qdel(pred)
return 1
////////////////////////////////////////////////////////////////
/datum/unit_test/belly_spacesafe
name = "MOB: human mob protected from space in a belly"
var/startLifeTick
var/startOxyloss
var/endOxyloss
var/mob/living/carbon/human/pred
var/mob/living/carbon/human/prey
async = 1
/datum/unit_test/belly_spacesafe/start_test()
pred = create_test_mob()
if(!istype(pred))
return 0
prey = create_test_mob(pred.loc)
if(!istype(prey))
return 0
/datum/unit_test/belly_spacesafe/Run()
var/mob/living/carbon/human/pred = create_test_human()
var/mob/living/carbon/human/prey = create_test_human()
return 1
TEST_ASSERT(pred && prey, "Failed to create test mobs")
/datum/unit_test/belly_spacesafe/check_result()
// Unfortuantely we need to wait for the pred's belly to initialize. (Currently after a spawn())
if(!pred.vore_organs || !pred.vore_organs.len)
return 0
pred.init_vore(TRUE)
TEST_ASSERT(pred.vore_selected, "[pred] has no vore_selected")
// Now that pred belly exists, we can eat the prey.
if(!pred.vore_selected)
fail("[pred] has no vore_selected.")
return 1
pred.vore_selected.nom_mob(prey)
// Attempt to eat the prey
if(prey.loc != pred.vore_selected)
pred.vore_selected.nom_mob(prey)
TEST_ASSERT(prey.loc == pred.vore_selected, "Prey not inside predator belly")
if(prey.loc != pred.vore_selected)
fail("[pred.vore_selected].nom_mob([prey]) did not put prey inside [pred]")
return 1
else
// Get an empty space level instead of just picking a random space turf
var/empty_z = using_map.get_empty_zlevel()
if(!empty_z)
fail("Unable to get empty z-level for vore space protection test!")
return 1
var/empty_z = using_map.get_empty_zlevel()
TEST_ASSERT(empty_z, "Failed to get empty z-level")
// Away from map edges so they don't transit while we're testing
var/mid_w = round(world.maxx*0.5)
var/mid_h = round(world.maxy*0.5)
var/turf/space_turf = locate(
round(world.maxx * 0.5),
round(world.maxy * 0.5),
empty_z
)
var/turf/T = locate(mid_w, mid_h, empty_z)
TEST_ASSERT(space_turf, "Failed to locate space turf")
if(!T)
fail("Unable to get turf for vore space protection test!")
return 1
else
pred.forceMove(T)
pred.forceMove(space_turf)
// Okay, we succeeded in eating them, now lets wait a bit
startLifeTick = pred.life_tick
startOxyloss = prey.getOxyLoss()
return 0
var/start_oxy = prey.getOxyLoss()
var/end_tick = pred.life_tick + 10
if(pred.life_tick < (startLifeTick + 10))
return 0 // Wait for them to breathe a few times
while(pred.life_tick < end_tick)
sleep(1)
// Alright lets check it!
endOxyloss = prey.getOxyLoss()
if(startOxyloss < endOxyloss)
fail("Prey takes oxygen damage in space! (Before: [startOxyloss]; after: [endOxyloss])")
else
pass("Prey is not taking oxygen damage in space. (Before: [startOxyloss]; after: [endOxyloss])")
var/end_oxy = prey.getOxyLoss()
if(end_oxy > start_oxy)
TEST_FAIL("Prey took oxygen damage in space belly (before: [start_oxy], after: [end_oxy])")
qdel(prey)
qdel(pred)
return 1
////////////////////////////////////////////////////////////////
/datum/unit_test/belly_damage
name = "MOB: human mob takes damage from digestion"
var/startLifeTick
var/startBruteBurn
var/endBruteBurn
var/mob/living/carbon/human/pred
var/mob/living/carbon/human/prey
async = 1
/datum/unit_test/belly_damage/start_test()
pred = create_test_mob()
if(!istype(pred))
return 0
prey = create_test_mob(pred.loc)
if(!istype(prey))
return 0
/datum/unit_test/belly_damage/Run()
var/mob/living/carbon/human/pred = create_test_human()
var/mob/living/carbon/human/prey = create_test_human()
return 1
TEST_ASSERT(pred && prey, "Failed to create test mobs")
/datum/unit_test/belly_damage/check_result()
// Unfortuantely we need to wait for the pred's belly to initialize. (Currently after a spawn())
if(!pred.vore_organs || !pred.vore_organs.len)
return 0
pred.init_vore(TRUE)
TEST_ASSERT(pred.vore_selected, "[pred] has no vore_selected")
// Now that pred belly exists, we can eat the prey.
if(!pred.vore_selected)
fail("[pred] has no vore_selected.")
return 1
pred.vore_selected.nom_mob(prey)
// Attempt to eat the prey
if(prey.loc != pred.vore_selected)
pred.vore_selected.nom_mob(prey)
TEST_ASSERT(prey.loc == pred.vore_selected, "Prey not inside predator belly")
if(prey.loc != pred.vore_selected)
fail("[pred.vore_selected].nom_mob([prey]) did not put prey inside [pred]")
return 1
pred.vore_selected.digest_mode = DM_DIGEST
// Okay, we succeeded in eating them, now lets wait a bit
pred.vore_selected.digest_mode = DM_DIGEST
startLifeTick = pred.life_tick
startBruteBurn = prey.getBruteLoss() + prey.getFireLoss()
return 0
var/start_damage = prey.getBruteLoss() + prey.getFireLoss()
var/end_tick = pred.life_tick + 10
if(pred.life_tick < (startLifeTick + 10))
return 0 // Wait a few ticks for damage to happen
while(pred.life_tick < end_tick)
sleep(1)
// Alright lets check it!
endBruteBurn = prey.getBruteLoss() + prey.getFireLoss()
if(startBruteBurn >= endBruteBurn)
fail("Prey doesn't take damage in digesting belly! (Before: [startBruteBurn]; after: [endBruteBurn])")
else
pass("Prey is taking damage in pred's belly. (Before: [startBruteBurn]; after: [endBruteBurn])")
qdel(prey)
qdel(pred)
return 1
var/end_damage = prey.getBruteLoss() + prey.getFireLoss()
if(end_damage <= start_damage)
TEST_FAIL("Prey took no digestion damage (before: [start_damage], after: [end_damage])")
+2 -2
View File
@@ -828,9 +828,9 @@
if(new_disable_hud == 1)
new_belly.disable_hud = TRUE
var/possible_fullscreens = cached_icon_states('icons/mob/screen_full_vore_list.dmi')
var/possible_fullscreens = icon_states_fast('icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_base.dmi')
if(!new_belly.colorization_enabled)
possible_fullscreens = cached_icon_states('icons/mob/screen_full_vore.dmi')
possible_fullscreens = icon_states_fast('icons/mob/vore_fullscreens/ui_lists/screen_full_vore.dmi')
if(!(new_belly.belly_fullscreen in possible_fullscreens))
new_belly.belly_fullscreen = ""
@@ -39,11 +39,11 @@
continue
if(reagents.total_volume)
reagents.trans_to(I, affecting_amt, 1, FALSE)
SEND_SIGNAL(src, COMSIG_BELLY_UPDATE_VORE_FX, FALSE, reagents.total_volume) // Signals vore_fx() reagents updates.
SEND_SIGNAL(src, COMSIG_BELLY_UPDATE_VORE_FX, reagents.total_volume) // Signals vore_fx() reagents updates.
for(var/mob/living/L in contents)
vore_fx(L, FALSE, reagents.total_volume)
vore_fx(L, reagents.total_volume)
if(owner.previewing_belly == src)
vore_fx(owner, FALSE, reagents.total_volume)
vore_fx(owner, reagents.total_volume)
/obj/belly/proc/GenerateBellyReagents()
if(isrobot(owner))
@@ -57,7 +57,7 @@
if(count_liquid_for_sprite)
owner.handle_belly_update() //This is run whenever a belly's contents are changed.
if(LAZYLEN(belly_surrounding))
SEND_SIGNAL(src, COMSIG_BELLY_UPDATE_VORE_FX, FALSE, reagents.total_volume) // Signals vore_fx() reagents updates.
SEND_SIGNAL(src, COMSIG_BELLY_UPDATE_VORE_FX, reagents.total_volume) // Signals vore_fx() reagents updates.
//////////////////////////// REAGENT_DIGEST ////////////////////////
@@ -325,15 +325,15 @@
/obj/belly/proc/update_internal_overlay()
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.
SEND_SIGNAL(src, COMSIG_BELLY_UPDATE_VORE_FX) // Signals vore_fx() to listening atoms. Atoms must handle appropriate isliving() checks.
for(var/A in belly_surrounding)
if(isliving(A))
vore_fx(A,1)
vore_fx(A)
if(owner.previewing_belly == src)
if(isbelly(owner.loc))
owner.previewing_belly = null
return
vore_fx(owner,1)
vore_fx(owner)
/obj/belly/deserialize(var/list/data)
..()
+5 -7
View File
@@ -588,9 +588,9 @@
var/taste
if(can_taste && living_mob.loc == src && (taste = living_mob.get_taste_message(FALSE))) // Prevent indirect tasting
to_chat(owner, span_vnotice("[living_mob] tastes of [taste]."))
vore_fx(living_mob, TRUE)
vore_fx(living_mob)
if(owner.previewing_belly == src)
vore_fx(owner, TRUE)
vore_fx(owner)
//Stop AI processing in bellies
if(living_mob.ai_holder)
living_mob.ai_holder.go_sleep()
@@ -653,7 +653,7 @@
// SEND_SIGNAL(COMSIG_BELLY_UPDATE_VORE_FX) is sometimes used when calling vore_fx() to send belly visuals
// to certain non-belly atoms. Not called here as vore_fx() is usually only called if a mob is in the belly.
// Don't forget it if you need to rework vore_fx().
/obj/belly/proc/vore_fx(mob/living/L, var/update, var/severity = 0)
/obj/belly/proc/vore_fx(mob/living/L, var/severity = 0)
if(!istype(L))
return
if(!L.client)
@@ -667,8 +667,6 @@
L.clear_fullscreen("belly")
L.previewing_belly = null
return
if(update)
L.clear_fullscreen("belly")
if(belly_fullscreen)
if(colorization_enabled)
var/atom/movable/screen/fullscreen/F = L.overlay_fullscreen("belly", /atom/movable/screen/fullscreen/belly, severity) // preserving save data
@@ -677,7 +675,7 @@
var/used_fullscreen = belly_fullscreen
to_chat(owner, span_warning("The belly overlay ([used_fullscreen]) you've selected for [src] no longer exists. Please reselect your overlay."))
belly_fullscreen = null
CRASH("Icon datum was not defined for [used_fullscreen]")
log_runtime("Icon datum was not defined for [used_fullscreen]")
var/alpha = min(belly_fullscreen_alpha, L.max_voreoverlay_alpha)
F.icon = initial(lookup_belly_path.belly_icon)
@@ -750,7 +748,7 @@
F.update_for_view(L.client.view)
else
var/atom/movable/screen/fullscreen/F = L.overlay_fullscreen("belly", /atom/movable/screen/fullscreen/belly/fixed, severity) //preserving save data
F.icon = 'icons/mob/screen_full_vore.dmi'
F.icon = 'icons/mob/vore_fullscreens/ui_lists/screen_full_vore.dmi'
F.cut_overlays()
F.add_overlay(image(F.icon, belly_fullscreen))
F.add_overlay(image(F.icon, belly_fullscreen+"-2"))
-3
View File
@@ -1098,11 +1098,8 @@
// Full screen belly overlays!
/atom/movable/screen/fullscreen/belly
icon = 'icons/mob/vore_fullscreens/screen_full_vore_list.dmi'
/atom/movable/screen/fullscreen/belly/fixed
icon = 'icons/mob/screen_full_vore.dmi'
icon_state = ""
/mob/living/proc/vorebelly_printout() //Spew the vorepanel belly messages into chat window for copypasting.
set name = "X-Print Vorebelly Settings"
@@ -238,9 +238,9 @@
)
var/list/belly_fullscreens
if(selected.colorization_enabled)
belly_fullscreens = cached_icon_states('icons/mob/screen_full_vore_list.dmi') //Makes any icons inside of here selectable.
belly_fullscreens = icon_states_fast('icons/mob/vore_fullscreens/ui_lists/screen_full_vore_list_base.dmi') //Makes any icons inside of here selectable.
else
belly_fullscreens = cached_icon_states('icons/mob/screen_full_vore.dmi') //Non colorable
belly_fullscreens = icon_states_fast('icons/mob/vore_fullscreens/ui_lists/screen_full_vore.dmi') //Non colorable
var/list/vs_flags = list()
for(var/flag_name in selected.vore_sprite_flag_list)
+6 -6
View File
@@ -192,7 +192,7 @@
//Announce to host and other minds
notify_holder("New mind loaded: [brainmob.name]")
show_vore_fx(brainmob, TRUE)
show_vore_fx(brainmob)
brainmob.copy_from_prefs_vr(bellies = FALSE)
return TRUE
@@ -251,7 +251,7 @@
/obj/soulgem/proc/toggle_setting(var/flag)
setting_flags ^= flag
if(flag & SOULGEM_SHOW_VORE_SFX)
soulgem_show_vfx(TRUE)
soulgem_show_vfx()
soulgem_vfx()
if(flag & NIF_SC_BACKUPS)
soulgem_backup()
@@ -330,22 +330,22 @@
RegisterSignal(linked_belly, COMSIG_BELLY_UPDATE_VORE_FX, PROC_REF(soulgem_show_vfx))
// Handles the vore fx updates for the captured souls
/obj/soulgem/proc/soulgem_show_vfx(var/update, var/severity = 0)
/obj/soulgem/proc/soulgem_show_vfx(var/severity = 0)
SIGNAL_HANDLER
if(linked_belly)
for(var/mob/living/L in brainmobs)
if(flag_check(SOULGEM_SHOW_VORE_SFX))
show_vore_fx(L, update, severity)
show_vore_fx(L, severity)
else
clear_vore_fx(L)
// Function to show the vore fx overlay
/obj/soulgem/proc/show_vore_fx(var/mob/living/L, var/update, var/severity = 0)
/obj/soulgem/proc/show_vore_fx(var/mob/living/L, var/severity = 0)
if(!linked_belly || !flag_check(SOULGEM_SHOW_VORE_SFX))
return
if(!istype(L) || L.eyeobj)
return
linked_belly.vore_fx(L, update, severity)
linked_belly.vore_fx(L, severity)
// Function to clear the vore fx overlay
/obj/soulgem/proc/clear_vore_fx(var/mob/M)
+1 -1
View File
@@ -190,7 +190,7 @@
QDEL_NULL(eyeobj)
gem.notify_holder("[src] ended SR projection.")
gem.show_vore_fx(src, TRUE)
gem.show_vore_fx(src)
/mob/living/carbon/brain/caught_soul/vore/nsay_brain()
set name = "NSay"
+2 -7
View File
@@ -59,11 +59,6 @@
host = null
. = ..()
/datum/vore_look/ui_assets(mob/user)
. = ..()
. += get_asset_datum(/datum/asset/spritesheet/vore)
. += get_asset_datum(/datum/asset/spritesheet/vore_fixed) //Either this isn't working or my cache is corrupted and won't show them.
/datum/vore_look/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -530,7 +525,7 @@
host.client.prefs_vr.show_vore_fx = host.show_vore_fx
if (isbelly(host.loc))
var/obj/belly/B = host.loc
B.vore_fx(host, TRUE)
B.vore_fx(host)
else
host.clear_fullscreen("belly")
if(!host.hud_used.hud_shown)
@@ -548,7 +543,7 @@
host.client.prefs_vr.max_voreoverlay_alpha = host.max_voreoverlay_alpha
if (isbelly(host.loc))
var/obj/belly/B = host.loc
B.vore_fx(host, TRUE)
B.vore_fx(host)
unsaved_changes = TRUE
return TRUE
// liquid belly code