diff --git a/code/__DEFINES/voreconstants.dm b/code/__DEFINES/voreconstants.dm index 19830c9f72..a133297315 100644 --- a/code/__DEFINES/voreconstants.dm +++ b/code/__DEFINES/voreconstants.dm @@ -4,6 +4,8 @@ #define DM_HEAL "Heal" #define DM_NOISY "Noisy" #define DM_DRAGON "Dragon" +#define DM_ABSORB "Absorb" +#define DM_UNABSORB "Un-absorb" #define isbelly(A) istype(A, /obj/belly) @@ -51,12 +53,13 @@ GLOBAL_LIST_INIT(death_pred, list( 'sound/vore/pred/death_10.ogg')) */ -GLOBAL_LIST_INIT(pred_vore_sounds, list( +GLOBAL_LIST_INIT(vore_sounds, list( "Gulp" = 'sound/vore/pred/swallow_01.ogg', "Swallow" = 'sound/vore/pred/swallow_02.ogg', "Insertion1" = 'sound/vore/pred/insertion_01.ogg', "Insertion2" = 'sound/vore/pred/insertion_02.ogg', "Tauric Swallow" = 'sound/vore/pred/taurswallow.ogg', + "Stomach Move" = 'sound/vore/pred/stomachmove.ogg', "Schlorp" = 'sound/vore/pred/schlorp.ogg', "Squish1" = 'sound/vore/pred/squish_01.ogg', "Squish2" = 'sound/vore/pred/squish_02.ogg', @@ -75,7 +78,7 @@ GLOBAL_LIST_INIT(pred_struggle_sounds, list( "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', @@ -88,7 +91,7 @@ GLOBAL_LIST_INIT(prey_vore_sounds, list( "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', @@ -129,7 +132,7 @@ GLOBAL_LIST_INIT(death_prey, list( "death10" = 'sound/vore/prey/death_10.ogg')) */ -GLOBAL_LIST_INIT(release_sound, list( +GLOBAL_LIST_INIT(release_sounds, list( "rustle (cloth)" = 'sound/effects/rustle1.ogg', "rustle2 (cloth)" = 'sound/effects/rustle2.ogg', "rustle3 (cloth)" = 'sound/effects/rustle3.ogg', diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index a280928731..4e6c12e1b2 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -96,6 +96,8 @@ for(var/obj/item/organ/genital/dicc in internal_organs) if(istype(dicc) && dicc.is_exposed()) msg += "[dicc.desc]\n" + + msg += attempt_vr(src,"examine_bellies",args) //vore Code //END OF CIT CHANGES //Status effects msg += status_effect_examines() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm index 1af22a8960..1fa204bcfd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm @@ -23,7 +23,7 @@ name = "maw" desc = "The maw of the dreaded Ash drake closes around you, engulfing you into a swelteringly hot, disgusting enviroment. The acidic saliva tingles over your form while that tongue pushes you further back...towards the dark gullet beyond." vore_verb = "scoop" - vore_sound = 'sound/vore/pred/taurswallow.ogg' + vore_sound = "Stomach Move" swallow_time = 20 escapechance = 25 // From above, will transfer into gullet @@ -36,6 +36,7 @@ desc = "A ripple of muscle and arching of the tongue pushes you down like any other food. No choice in the matter, you're simply consumed. The dark ambiance of the outside world is replaced with working, wet flesh. Your only light being what you brought with you." swallow_time = 60 // costs extra time to eat directly to here escapechance = 5 + vore_sound = "Squish2" // From above, will transfer into gut transferchance = 25 autotransferchance = 50 @@ -44,6 +45,7 @@ /obj/belly/megafauna/dragon/gut name = "stomach" vore_capacity = 5 //I doubt this many people will actually last in the gut, but... + vore_sound = "Tauric Swallow" desc = "With a rush of burning ichor greeting you, you're introduced to the Drake's stomach. Wrinkled walls greedily grind against you, acidic slimes working into your body as you become fuel and nutriton for a superior predator. All that's left is your body's willingness to resist your destiny." digest_mode = DM_DRAGON digest_burn = 5 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 3a59c37618..cea77c7adf 100644 --- a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm +++ b/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm @@ -13,9 +13,9 @@ /obj/belly name = "belly" // Name of this location desc = "It's a belly! You're in it!" // Flavor text description of inside sight/sound/smells/feels. - var/vore_sound = 'sound/vore/pred/swallow_01.ogg' // Sound when ingesting someone + var/vore_sound = "Gulp" // Sound when ingesting someone var/vore_verb = "ingest" // Verb for eating with this in messages - var/release_sound = 'sound/effects/splat.ogg' + var/release_sound = "Splatter" 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 @@ -40,7 +40,7 @@ var/vore_capacity = 1 // simple animal nom capacity //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) // Possible digest modes + var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_NOISY,DM_ABSORB,DM_UNABSORB) // Possible digest modes var/tmp/mob/living/owner // The mob whose belly this is. var/tmp/digest_mode = DM_HOLD // Current mode the belly is set to from digest_modes (+transform_modes if human) @@ -103,7 +103,7 @@ //List has indexes that are the digestion mode strings, and keys that are lists of strings. var/tmp/list/emote_lists = list() -//For serialization, keep this updated, required for bellies to save correctly. +//For serialization, keep this updated AND IN ORDER OF VARS LISTED ABOVE AND IN DUPE AT THE BOTTOM!!, required for bellies to save correctly. /obj/belly/vars_to_save() return ..() + list( "name", @@ -117,22 +117,22 @@ "digest_brute", "digest_burn", "immutable", - "can_taste", "escapable", "escapetime", "digestchance", "absorbchance", "escapechance", + "can_taste", + "bulge_size", + "silent", "transferchance", "transferlocation", - "bulge_size", "struggle_messages_outside", "struggle_messages_inside", "digest_messages_owner", "digest_messages_prey", "examine_messages", - "emote_lists", - "silent" + "emote_lists" ) //ommitted list @@ -172,9 +172,6 @@ var/mob/living/M = thing if(desc) to_chat(M, "[desc]") - var/taste - if(can_taste && (taste = M.get_taste_message(FALSE))) - to_chat(owner, "[M] tastes of [taste].") // 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. @@ -189,8 +186,8 @@ if(L.absorbed && !include_absorbed) continue L.absorbed = FALSE - for(var/mob/living/W in AM) - W.stop_sound_channel(CHANNEL_PREYLOOP) + L.stop_sound_channel(CHANNEL_PREYLOOP) + L.cure_blind("belly_[REF(src)]") 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))) @@ -211,8 +208,6 @@ M.forceMove(drop_location()) // Move the belly contents into the same location as belly's owner. items_preserved -= M - for(var/mob/living/P in M) - P.stop_sound_channel(CHANNEL_PREYLOOP) 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) @@ -221,6 +216,8 @@ if(istype(M,/mob/living)) var/mob/living/ML = M var/mob/living/OW = owner + ML.stop_sound_channel(CHANNEL_PREYLOOP) + ML.cure_blind("belly_[REF(src)]") if(ML.absorbed) ML.absorbed = FALSE if(ishuman(M) && ishuman(OW)) @@ -252,6 +249,9 @@ for(var/mob/living/M in contents) M.updateVRPanel() + M.become_blind("belly_[REF(src)]") + + // Setup the autotransfer checks if needed if(transferlocation && autotransferchance > 0) @@ -400,6 +400,8 @@ // Delete the digested mob qdel(M) + //Update owner + owner.updateVRPanel() // Handle a mob being absorbed /obj/belly/proc/absorb_living(var/mob/living/M) @@ -464,6 +466,10 @@ qdel(src) //final option, I guess. testing("[src] (\ref[src]) was QDEL'd for not having a drop_location!") +//Yes, it's ""safe"" to drop items here +/obj/belly/AllowDrop() + return TRUE + //Handle a mob struggling // Called from /mob/living/carbon/relaymove() /obj/belly/proc/relay_resist(var/mob/living/R) @@ -471,22 +477,6 @@ return // User is not in this belly R.setClickCooldown(50) - - 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_after(R, 50, owner)) - if(owner.stat && (R in contents) && R.a_intent != INTENT_HELP) //Can still escape and want to? - release_specific_contents(R) - return - else if(!(R in contents)) //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) @@ -501,9 +491,32 @@ 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 //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 + for(var/mob/M in get_hearers_in_view(3, get_turf(owner))) - M.show_message(struggle_outer_message, 2) // hearable - to_chat(R,struggle_user_message) + 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))) @@ -513,24 +526,6 @@ var/sound/prey_struggle = sound(get_sfx("prey_struggle")) R.playsound_local(get_turf(R),prey_struggle,45,0) - if(R.a_intent != INTENT_HELP) //If on non help intent - 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, owner)) - if((owner.stat || !owner.client || escapable) && (R in contents)) - release_specific_contents(R) - to_chat(R,"You climb out of \the [lowertext(name)].") - to_chat(owner,"[R] climbs out of your [lowertext(name)]!") - for(var/mob/M in hearers(4, owner)) - M.show_message("[R] climbs out of [owner]'s [lowertext(name)]!", 2) - return - else if(!istype(loc, /obj/belly)) //Aren't even in the belly. Quietly fail. - return - else //Belly became inescapable. - 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) @@ -548,24 +543,24 @@ to_chat(owner,"Someone slid into your [transferlocation] due to their struggling inside your [lowertext(name)]!") transfer_contents(R, dest_belly) return + + else if(prob(absorbchance) && digest_mode != DM_ABSORB) //After that, let's have it run the absorb chance. + to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to cling more tightly...") + to_chat(owner,"You feel your [lowertext(name)] start to cling onto its contents...") + digest_mode = DM_ABSORB + return /* - else if(prob(absorbchance) && digest_mode != DM_ABSORB) //After that, let's have it run the absorb chance. - to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to cling more tightly...") - 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. + 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 && 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) && 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!") @@ -581,6 +576,8 @@ /obj/belly/proc/transfer_contents(var/atom/movable/content, var/obj/belly/target, silent = FALSE) if(!(content in src) || !istype(target)) return + for(var/mob/living/M in contents) + M.cure_blind("belly_[REF(src)]") target.nom_mob(content, target.owner) if(!silent) for(var/mob/M in get_hearers_in_view(5, get_turf(owner))) @@ -591,7 +588,7 @@ M.updateVRPanel() // Belly copies and then returns the copy -// Needs to be updated for any var changes +// Needs to be updated for any var changes AND KEPT IN ORDER OF THE VARS ABOVE AS WELL! /obj/belly/proc/copy(mob/new_owner) var/obj/belly/dupe = new /obj/belly(new_owner) @@ -607,16 +604,20 @@ dupe.digest_brute = digest_brute dupe.digest_burn = digest_burn dupe.immutable = immutable - dupe.can_taste = can_taste dupe.escapable = escapable dupe.escapetime = escapetime dupe.digestchance = digestchance dupe.absorbchance = absorbchance dupe.escapechance = escapechance - dupe.transferchance = transferchance - dupe.transferlocation = transferlocation + dupe.can_taste = can_taste dupe.bulge_size = bulge_size -// dupe.shrink_grow_size = shrink_grow_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 //// Object-holding variables //struggle_messages_outside - strings @@ -650,6 +651,4 @@ dupe.emote_lists[K] = list() for(var/I in emote_lists[K]) dupe.emote_lists[K] += I - dupe.silent = silent - return dupe diff --git a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm index e2919ad3ec..97918afc99 100644 --- a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm +++ b/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm @@ -26,6 +26,11 @@ if(!length(touchable_items)) return SSBELLIES_PROCESSED +//////////////////////// Absorbed Handling //////////////////////// + for(var/mob/living/M in contents) + if(M.absorbed) + M.Stun(5) + ////////////////////////// Sound vars ///////////////////////////// var/sound/prey_digest = sound(get_sfx("digest_prey")) var/sound/prey_death = sound(get_sfx("death_prey")) @@ -126,6 +131,39 @@ M.playsound_local(get_turf(M), prey_digest, 65) +//////////////////////////// DM_ABSORB //////////////////////////// + else if(digest_mode == DM_ABSORB) + + for (var/mob/living/M in contents) + + if(prob(10)) //Less often than gurgles. People might leave this on forever. + M.stop_sound_channel(CHANNEL_DIGEST) + for(var/mob/H in get_hearers_in_view(5, get_turf(owner))) + if(H.client && H.client.prefs.toggles & DIGESTION_NOISES) + playsound(get_turf(owner),"digest_pred",50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_DIGEST) + M.stop_sound_channel(CHANNEL_PRED) + M.playsound_local(get_turf(M), prey_digest, 65) + + if(M.absorbed) + continue + + if(M.nutrition >= 100) //Drain them until there's no nutrients left. Slowly "absorb" them. + var/oldnutrition = (M.nutrition * 0.05) + M.nutrition = (M.nutrition * 0.95) + owner.nutrition += oldnutrition + else if(M.nutrition < 100) //When they're finally drained. + absorb_living(M) + +//////////////////////////// DM_UNABSORB //////////////////////////// + else if(digest_mode == DM_UNABSORB) + + for (var/mob/living/M in contents) + if(M.absorbed && owner.nutrition >= 100) + M.absorbed = 0 + to_chat(M,"You suddenly feel solid again ") + to_chat(owner,"You feel like a part of you is missing.") + owner.nutrition -= 100 + //////////////////////////DM_DRAGON ///////////////////////////////////// //because dragons need snowflake guts if(digest_mode == DM_DRAGON) diff --git a/modular_citadel/code/modules/vore/eating/living_vr.dm b/modular_citadel/code/modules/vore/eating/living_vr.dm index ea66f824b8..50496c5c31 100644 --- a/modular_citadel/code/modules/vore/eating/living_vr.dm +++ b/modular_citadel/code/modules/vore/eating/living_vr.dm @@ -17,35 +17,44 @@ /hook/living_new/proc/vore_setup(mob/living/M) M.verbs += /mob/living/proc/preyloop_refresh M.verbs += /mob/living/proc/lick + M.verbs += /mob/living/proc/escapeOOC + if(M.no_vore) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach. return 1 M.verbs += /mob/living/proc/insidePanel //Tries to load prefs if a client is present otherwise gives freebie stomach - if(!M.vore_organs || !M.vore_organs.len) - spawn(20) //Wait a couple of seconds to make sure copy_to or whatever has gone - if(!M) return - - if(M.client && M.client.prefs_vr) - if(!M.copy_from_prefs_vr()) - to_chat(M,"ERROR: You seem to have saved vore prefs, but they couldn't be loaded.") - return 0 - if(M.vore_organs && M.vore_organs.len) - M.vore_selected = M.vore_organs[1] - - if(!M.vore_organs || !M.vore_organs.len) - if(!M.vore_organs) - M.vore_organs = list() - var/obj/belly/B = new /obj/belly(M) - M.vore_selected = B - B.immutable = TRUE - B.name = "Stomach" - B.desc = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [M.name]." - B.can_taste = FALSE + spawn(20 SECONDS) // long delay because the server delays in its startup. just on the safe side. + M.init_vore() //Return 1 to hook-caller return 1 +/mob/living/proc/init_vore() + //Something else made organs, meanwhile. + if(LAZYLEN(vore_organs)) + return TRUE + + //We'll load our client's organs if we have one + if(client && client.prefs_vr) + if(!copy_from_prefs_vr()) + to_chat(src,"ERROR: You seem to have saved vore prefs, but they couldn't be loaded.") + return FALSE + if(LAZYLEN(vore_organs)) + vore_selected = vore_organs[1] + return TRUE + + //Or, we can create a basic one for them + if(!LAZYLEN(vore_organs)) + LAZYINITLIST(vore_organs) + var/obj/belly/B = new /obj/belly(src) + vore_selected = B + B.immutable = 1 + B.name = "Stomach" + B.desc = "It appears to be rather warm and wet. Makes sense, considering it's inside [name]." + B.can_taste = 1 + return TRUE + /* // Hide vore organs in contents // @@ -287,7 +296,7 @@ /mob/living/proc/preyloop_refresh() set name = "Internal loop refresh" set category = "Vore" - if(istype(src.loc, /obj/belly)) + if(isbelly(loc)) src.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE) src.playsound_local(get_turf(src),preyloop,80,0, channel = CHANNEL_PREYLOOP) @@ -297,28 +306,38 @@ // OOC Escape code for pref-breaking or AFK preds // /mob/living/proc/escapeOOC() - set name = "Animal Escape" + set name = "OOC Escape" set category = "Vore" - //You're in an animal! - if(istype(src.loc,/mob/living/simple_animal)) - var/mob/living/simple_animal/pred = src.loc - var/confirm = alert(src, "You're in a mob. Use this as a trick to get out of hostile animals. If you are in more than one pred, use this more than once.", "Confirmation", "Okay", "Cancel") - if(confirm == "Okay") - for(var/I in pred.vore_organs) - var/obj/belly/B = pred.vore_organs[I] - B.release_specific_contents(src) + //You're in a belly! + if(isbelly(loc)) + var/obj/belly/B = loc + var/confirm = alert(src, "You're in a mob. If you're otherwise unable to escape from a pred AFK for a long time, use this.", "Confirmation", "Okay", "Cancel") + if(!confirm == "Okay" || loc != B) + 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.stop_sound_channel(CHANNEL_PREYLOOP) + for(var/mob/living/simple_animal/SA in range(10)) + SA.prey_excludes[src] = world.time - for(var/mob/living/simple_animal/SA in range(10)) - SA.prey_excludes += src - spawn(18000) - if(src && SA) - SA.prey_excludes -= src + if(isanimal(B.owner)) + var/mob/living/simple_animal/SA = B.owner + SA.update_icons() - pred.update_icons() + //You're in a dogborg! + else if(istype(loc, /obj/item/device/dogborg/sleeper)) + var/obj/item/device/dogborg/sleeper/belly = loc //The belly! + var/confirm = alert(src, "You're in a dogborg sleeper. This is for escaping from preference-breaking or if your predator disconnects/AFKs. You can also resist out naturally too.", "Confirmation", "Okay", "Cancel") + if(!confirm == "Okay" || loc != belly) + return + //Actual escaping + belly.go_out(src) //Just force-ejects from the borg as if they'd clicked the eject button. else - to_chat(src, "You aren't inside anything, you clod.") + to_chat(src,"You aren't inside anyone, though, is the thing.") // // Verb for saving vore preferences to save file diff --git a/modular_citadel/code/modules/vore/eating/vore_vr.dm b/modular_citadel/code/modules/vore/eating/vore_vr.dm index f0ceb97e31..76698d5041 100644 --- a/modular_citadel/code/modules/vore/eating/vore_vr.dm +++ b/modular_citadel/code/modules/vore/eating/vore_vr.dm @@ -108,10 +108,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE digestable = json_from_file["digestable"] devourable = json_from_file["devourable"] -// allowmobvore = json_from_file["allowmobvore"] vore_taste = json_from_file["vore_taste"] -// can_be_drop_prey = json_from_file["can_be_drop_prey"] -// can_be_drop_prey = json_from_file["can_be_drop_pred"] belly_prefs = json_from_file["belly_prefs"] //Quick sanitize @@ -119,16 +116,21 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE digestable = TRUE if(isnull(devourable)) devourable = FALSE -/* if(isnull(allowmobvore)) + if(isnull(belly_prefs)) + belly_prefs = list() + + return TRUE +/* + allowmobvore = json_from_file["allowmobvore"] + can_be_drop_prey = json_from_file["can_be_drop_prey"] + can_be_drop_prey = json_from_file["can_be_drop_pred"] + + if(isnull(allowmobvore)) allowmobvore = TRUE if(isnull(can_be_drop_prey)) allowmobvore = FALSE if(isnull(can_be_drop_pred)) allowmobvore = FALSE */ - if(isnull(belly_prefs)) - belly_prefs = list() - - return TRUE /datum/vore_preferences/proc/save_vore() if(!path) return FALSE @@ -142,11 +144,6 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE "belly_prefs" = belly_prefs, ) - /* commented out list things - "allowmobvore" = allowmobvore, - "can_be_drop_prey" = can_be_drop_prey, - "can_be_drop_pred" = can_be_drop_pred, */ - //List to JSON var/json_to_file = json_encode(settings_list) if(!json_to_file) @@ -163,6 +160,11 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE return TRUE +/* commented out list things + "allowmobvore" = allowmobvore, + "can_be_drop_prey" = can_be_drop_prey, + "can_be_drop_pred" = can_be_drop_pred, */ + //Can do conversions here /datum/vore_preferences/proc/patch_version(var/list/json_from_file,var/version) return json_from_file \ No newline at end of file diff --git a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm index a3593278b2..1ef0fb2ddc 100644 --- a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm +++ b/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm @@ -113,6 +113,8 @@ spanstyle = "color:green;" if(DM_NOISY) spanstyle = "color:purple;" + if(DM_ABSORB) + spanstyle = "color:purple;" dat += " ([B.contents.len])" @@ -199,6 +201,10 @@ dat += "
Set Belly Escape Time" dat += " [selected.escapetime/10]s" + dat += "
" + dat += "
Set Belly Absorb Chance" + dat += " [selected.absorbchance]%" + //Special
here to add a gap dat += "
" dat += "
Set Belly Transfer Chance" @@ -228,6 +234,7 @@ //Under the last HR, save and stuff. dat += "Save Prefs" dat += "Refresh" + dat += "Reload Slot Prefs" dat += "
" switch(user.digestable) @@ -262,7 +269,7 @@ and you can change them to whatever you see fit. Setting them to 0% will disable the possibility of that interaction. \ These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest) \ will affect all prey in that belly, if one resists and triggers digestion. If multiple trigger at the same time, \ - only the first in the order of 'Escape > Transfer > Digest' will occur.") + only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur.") return TRUE //Force update if(href_list["outsidepick"]) @@ -282,11 +289,11 @@ if("Help Out") //Help the inside-mob out if(user.stat || user.absorbed || M.absorbed) to_chat(user,"You can't do that in your state!") - return 1 + return to_chat(user,"You begin to push [M] to freedom!") to_chat(M,"[usr] begins to push you to freedom!") - to_chat(M.loc,"Someone is trying to escape from inside you!") + to_chat(OB.owner,"Someone is trying to escape from inside you!") sleep(50) if(prob(33)) OB.release_specific_contents(M) @@ -302,11 +309,11 @@ if("Devour") //Eat the inside mob if(user.absorbed || user.stat) to_chat(user,"You can't do that in your state!") - return 1 + return if(!user.vore_selected) to_chat(user,"Pick a belly on yourself first!") - return 1 + return var/obj/belly/TB = user.vore_selected to_chat(user,"You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!") @@ -354,9 +361,6 @@ return selected.release_all_contents() - for(var/mob/M in get_hearers_in_view(5, get_turf(user))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) - playsound(get_turf(user),'sound/vore/pred/escape.ogg',50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) to_chat(user.loc,"Everything is released from [user]!") if("Move all") @@ -370,9 +374,6 @@ for(var/atom/movable/tgt in selected) selected.transfer_contents(tgt, choice, 1) - for(var/mob/M in get_hearers_in_view(5, get_turf(user))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) - playsound(get_turf(user),'sound/vore/pred/stomachmove.ogg',50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) to_chat(tgt,"You're squished from [user]'s [lowertext(selected)] to their [lowertext(choice.name)]!") var/atom/movable/tgt = locate(href_list["insidepick"]) @@ -390,9 +391,6 @@ return FALSE selected.release_specific_contents(tgt) - for(var/mob/M in get_hearers_in_view(5, get_turf(user))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) - playsound(get_turf(user),'sound/vore/pred/escape.ogg',50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) user.loc << "[tgt] is released from [user]!" if("Move") @@ -406,9 +404,6 @@ to_chat(tgt,"You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(choice.name)]!") selected.transfer_contents(tgt, choice) - for(var/mob/M in get_hearers_in_view(5, get_turf(user))) - if(M.client && M.client.prefs.cit_toggles & EATING_NOISES) - playsound(get_turf(user),'sound/vore/pred/stomachmove.ogg',50,0,-5,0,ignore_walls = FALSE,channel=CHANNEL_PRED) if(href_list["newbelly"]) if(user.vore_organs.len >= BELLIES_MAX) @@ -540,28 +535,28 @@ selected.vore_verb = new_verb if(href_list["b_release"]) - var/choice = input(user,"Currently set to [selected.release_sound]","Select Sound") as null|anything in GLOB.release_sound + var/choice = input(user,"Currently set to [selected.release_sound]","Select Sound") as null|anything in GLOB.release_sounds if(!choice) return - selected.release_sound = GLOB.release_sound[choice] + selected.release_sound = GLOB.release_sounds[choice] if(href_list["b_releasesoundtest"]) - var/soundfile = GLOB.release_sound[selected.release_sound] + var/soundfile = selected.release_sound if(soundfile) user << soundfile if(href_list["b_sound"]) - var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in GLOB.pred_vore_sounds + var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in GLOB.vore_sounds if(!choice) return - selected.vore_sound = GLOB.pred_vore_sounds[choice] + selected.vore_sound = GLOB.vore_sounds[choice] if(href_list["b_soundtest"]) - var/soundfile = GLOB.pred_vore_sounds[selected.vore_sound] + var/soundfile = selected.vore_sound if(soundfile) user << soundfile @@ -670,6 +665,15 @@ to_chat(user, "Belly Preferences were saved!") log_admin("Could not save vore prefs on USER: [user].") + if(href_list["applyprefs"]) + var/alert = alert("Are you sure you want to reload character slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel") + if(!alert == "Reload") + return 0 + if(!user.apply_vore_prefs()) + alert("ERROR: Vore preferences failed to apply!","Error") + else + to_chat(user,"Vore preferences applied from active slot!") + if(href_list["setflavor"]) var/new_flavor = html_encode(input(usr,"What your character tastes like (40ch limit). This text will be printed to the pred after 'X tastes of...' so just put something like 'strawberries and cream':","Character Flavor",user.vore_taste) as text|null) if(!new_flavor)