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:
@@ -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