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:
Poojawa
2018-03-26 04:46:50 -05:00
committed by GitHub
parent bf63fa766a
commit c579d81f4c
8 changed files with 221 additions and 152 deletions
@@ -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)