mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
Vore fixes and a few additions (#6032)
* Fixes saving memes, Adds absorbing and OOC escape Also allows for people to reload from a slot if they fuck up and delete a belly * makes sure travis won't flip the fuck out * fixes some sound issues * cleaning up some extra sounds, also dragon vore sound settings * fixes resisting out of guts * BRACKETS * Prey now become blind after being eaten. Use the audible subtle message to continue roleplaying with them! * Actually make bulges show up in examine * Fixes cases where transfering between bellies would blind twice Because, y'know, that make sense. Also added self reminders if any changes happen to JSONs
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, "<span class='notice'><B>[desc]</B></span>")
|
||||
var/taste
|
||||
if(can_taste && (taste = M.get_taste_message(FALSE)))
|
||||
to_chat(owner, "<span class='notice'>[M] tastes of [taste].</span>")
|
||||
|
||||
// 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,"<span class='warning'>You attempt to climb out of \the [lowertext(name)]. (This will take around 5 seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
|
||||
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,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
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 = "<span class='alert'>" + struggle_outer_message + "</span>"
|
||||
struggle_user_message = "<span class='alert'>" + struggle_user_message + "</span>"
|
||||
|
||||
if((owner.stat || !owner.client) && (R.a_intent != INTENT_HELP)) //If owner is stat (dead, KO) we can actually escape
|
||||
to_chat(R,"<span class='warning'>You attempt to climb out of \the [lowertext(name)]. (This will take around 5 seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
|
||||
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,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
return
|
||||
else //failsafe to make sure people are able to struggle out. friendly ERP should be on help intent.
|
||||
to_chat(R,"<span class='warning'>You attempt to climb out of [lowertext(name)]. (This will take around [escapetime] seconds.)</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
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,"<span class='warning'>You start to climb out of \the [lowertext(name)].</span>")
|
||||
to_chat(owner,"<span class='warning'>Someone is attempting to climb out of your [lowertext(name)]!</span>")
|
||||
if(do_after(R, escapetime, owner))
|
||||
if((owner.stat || !owner.client || escapable) && (R in contents))
|
||||
release_specific_contents(R)
|
||||
to_chat(R,"<span class='warning'>You climb out of \the [lowertext(name)].</span>")
|
||||
to_chat(owner,"<span class='warning'>[R] climbs out of your [lowertext(name)]!</span>")
|
||||
for(var/mob/M in hearers(4, owner))
|
||||
M.show_message("<span class='warning'>[R] climbs out of [owner]'s [lowertext(name)]!</span>", 2)
|
||||
return
|
||||
else if(!istype(loc, /obj/belly)) //Aren't even in the belly. Quietly fail.
|
||||
return
|
||||
else //Belly became inescapable.
|
||||
to_chat(R,"<span class='warning'>Your attempt to escape [lowertext(name)] has failed!</span>")
|
||||
to_chat(owner,"<span class='notice'>The attempt to escape from your [lowertext(name)] has failed!</span>")
|
||||
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,"<span class='warning'>Someone slid into your [transferlocation] due to their struggling inside your [lowertext(name)]!</span>")
|
||||
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,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to cling more tightly...</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] start to cling onto its contents...</span>")
|
||||
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,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to cling more tightly...</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] start to cling onto its contents...</span>")
|
||||
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,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to get more active...</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] beginning to become active!</span>")
|
||||
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,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to get more active...</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] beginning to become active!</span>")
|
||||
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,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to get even more active!</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] beginning to become even more active!</span>")
|
||||
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,"<span class='warning'>In response to your struggling, \the [lowertext(name)] begins to get even more active!</span>")
|
||||
to_chat(owner,"<span class='warning'>You feel your [lowertext(name)] beginning to become even more active!</span>")
|
||||
digest_mode = DM_DIGEST
|
||||
return */
|
||||
else if(prob(digestchance)) //Finally, let's see if it should run the digest chance.)
|
||||
to_chat(R, "<span class='warning'>In response to your struggling, \the [name] begins to get more active...</span>")
|
||||
to_chat(owner, "<span class='warning'>You feel your [name] beginning to become active!</span>")
|
||||
@@ -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
|
||||
|
||||
@@ -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,"<span class='notice'>You suddenly feel solid again </span>")
|
||||
to_chat(owner,"<span class='notice'>You feel like a part of you is missing.</span>")
|
||||
owner.nutrition -= 100
|
||||
|
||||
//////////////////////////DM_DRAGON /////////////////////////////////////
|
||||
//because dragons need snowflake guts
|
||||
if(digest_mode == DM_DRAGON)
|
||||
|
||||
@@ -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,"<span class='warning'>ERROR: You seem to have saved vore prefs, but they couldn't be loaded.</span>")
|
||||
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,"<span class='warning'>ERROR: You seem to have saved vore prefs, but they couldn't be loaded.</span>")
|
||||
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, "<span class='alert'>You aren't inside anything, you clod.</span>")
|
||||
to_chat(src,"<span class='alert'>You aren't inside anyone, though, is the thing.</span>")
|
||||
|
||||
//
|
||||
// Verb for saving vore preferences to save file
|
||||
|
||||
@@ -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
|
||||
@@ -113,6 +113,8 @@
|
||||
spanstyle = "color:green;"
|
||||
if(DM_NOISY)
|
||||
spanstyle = "color:purple;"
|
||||
if(DM_ABSORB)
|
||||
spanstyle = "color:purple;"
|
||||
|
||||
dat += "<span style='[spanstyle]'> ([B.contents.len])</span></a></li>"
|
||||
|
||||
@@ -199,6 +201,10 @@
|
||||
dat += "<br><a href='?src=\ref[src];b_escapetime=\ref[selected]'>Set Belly Escape Time</a>"
|
||||
dat += " [selected.escapetime/10]s"
|
||||
|
||||
dat += "<br style='line-height:5px;'>"
|
||||
dat += "<br><a href='?src=\ref[src];b_absorbchance=\ref[selected]'>Set Belly Absorb Chance</a>"
|
||||
dat += " [selected.absorbchance]%"
|
||||
|
||||
//Special <br> here to add a gap
|
||||
dat += "<br style='line-height:5px;'>"
|
||||
dat += "<br><a href='?src=\ref[src];b_transferchance=\ref[selected]'>Set Belly Transfer Chance</a>"
|
||||
@@ -228,6 +234,7 @@
|
||||
//Under the last HR, save and stuff.
|
||||
dat += "<a href='?src=\ref[src];saveprefs=1'>Save Prefs</a>"
|
||||
dat += "<a href='?src=\ref[src];refresh=1'>Refresh</a>"
|
||||
dat += "<a href='?src=\ref[src];applyprefs=1'>Reload Slot Prefs</a>"
|
||||
|
||||
dat += "<HR>"
|
||||
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,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return 1
|
||||
return
|
||||
|
||||
to_chat(user,"<font color='green'>You begin to push [M] to freedom!</font>")
|
||||
to_chat(M,"[usr] begins to push you to freedom!")
|
||||
to_chat(M.loc,"<span class='warning'>Someone is trying to escape from inside you!</span>")
|
||||
to_chat(OB.owner,"<span class='warning'>Someone is trying to escape from inside you!</span>")
|
||||
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,"<span class='warning'>You can't do that in your state!</span>")
|
||||
return 1
|
||||
return
|
||||
|
||||
if(!user.vore_selected)
|
||||
to_chat(user,"<span class='warning'>Pick a belly on yourself first!</span>")
|
||||
return 1
|
||||
return
|
||||
|
||||
var/obj/belly/TB = user.vore_selected
|
||||
to_chat(user,"<span class='warning'>You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!</span>")
|
||||
@@ -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,"<span class='danger'>Everything is released from [user]!</span>")
|
||||
|
||||
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,"<span class='warning'>You're squished from [user]'s [lowertext(selected)] to their [lowertext(choice.name)]!</span>")
|
||||
|
||||
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 << "<span class='danger'>[tgt] is released from [user]!</span>"
|
||||
|
||||
if("Move")
|
||||
@@ -406,9 +404,6 @@
|
||||
|
||||
to_chat(tgt,"<span class='warning'>You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(choice.name)]!</span>")
|
||||
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, "<span class='notice'>Belly Preferences were saved!</span>")
|
||||
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,"<span class='notice'>Vore preferences applied from active slot!</span>")
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user