Vore system updates (#2864)

* Tasting, digest/transfer chance, improvements

* more vague for defaults

* Actually let's hold off on silenced mode 'cuz broke

* make sure it's all commented out

* reverts vorepanel updater, buggy af. Adds mob vore

Ian can eat you now. \o/
This commit is contained in:
Poojawa
2017-09-19 14:03:13 -05:00
committed by GitHub
parent b4e6519b51
commit 4ab7f126ed
9 changed files with 414 additions and 73 deletions
@@ -95,6 +95,9 @@
real_name = name
if(!loc)
stack_trace("Simple animal being instantiated in nullspace")
if(vore_active)
init_belly()
verbs |= /mob/living/proc/animal_nom
/mob/living/simple_animal/Login()
@@ -2,3 +2,71 @@
// List of targets excluded (for now) from being eaten by this mob.
var/list/prey_exclusions = list()
devourable = FALSE //insurance because who knows.
var/vore_active = FALSE // If vore behavior is enabled for this mob
var/vore_capacity = 1 // The capacity (in people) this person can hold
var/vore_default_mode = DM_DIGEST // Default bellymode (DM_DIGEST, DM_HOLD, DM_ABSORB)
var/vore_digest_chance = 25 // Chance to switch to digest mode if resisted
var/vore_absorb_chance = 0 // Chance to switch to absorb mode if resisted
var/vore_escape_chance = 25 // Chance of resisting out of mob
var/vore_stomach_name // The name for the first belly if not "stomach"
var/vore_stomach_flavor // The flavortext for the first belly if not the default
// Release belly contents beforey being gc'd!
/mob/living/simple_animal/Destroy()
for(var/I in vore_organs)
var/datum/belly/B = vore_organs[I]
B.release_all_contents() // When your stomach is empty
prey_excludes.Cut()
. = ..()
/mob/living/simple_animal/death()
for(var/I in vore_organs)
var/datum/belly/B = vore_organs[I]
B.release_all_contents() // When your stomach is empty
..() // then you have my permission to die.
// Simple animals have only one belly. This creates it (if it isn't already set up)
/mob/living/simple_animal/proc/init_belly()
if(vore_organs.len)
return
if(no_vore) //If it can't vore, let's not give it a stomach.
return
var/datum/belly/B = new /datum/belly(src)
B.immutable = TRUE
B.name = vore_stomach_name ? vore_stomach_name : "stomach"
B.inside_flavor = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
B.digest_mode = vore_default_mode
B.escapable = vore_escape_chance > 0
B.escapechance = vore_escape_chance
B.digestchance = vore_digest_chance
B.human_prey_swallow_time = swallowTime
B.nonhuman_prey_swallow_time = swallowTime
B.vore_verb = "swallow"
// TODO - Customizable per mob
B.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace
"The insides knead at you gently for a moment.",
"The guts glorp wetly around you as some air shifts.",
"The predator takes a deep breath and sighs, shifting you somewhat.",
"The stomach squeezes you tight for a moment, then relaxes harmlessly.",
"The predator's calm breathing and thumping heartbeat pulses around you.",
"The warm walls kneads harmlessly against you.",
"The liquids churn around you, though there doesn't seem to be much effect.",
"The sound of bodily movements drown out everything for a moment.",
"The predator's movements gently force you into a different position.")
B.emote_lists[DM_DIGEST] = list(
"The burning acids eat away at your form.",
"The muscular stomach flesh grinds harshly against you.",
"The caustic air stings your chest when you try to breathe.",
"The slimy guts squeeze inward to help the digestive juices soften you up.",
"The onslaught against your body doesn't seem to be letting up; you're food now.",
"The predator's body ripples and crushes against you as digestive enzymes pull you apart.",
"The juices pooling beneath you sizzle against your sore skin.",
"The churning walls slowly pulverize you into meaty nutrients.",
"The stomach glorps and gurgles as it tries to work you into slop.")
src.vore_organs[B.name] = B
src.vore_selected = B.name
+71 -11
View File
@@ -13,16 +13,21 @@
var/inside_flavor // Flavor text description of inside sight/sound/smells/feels.
var/vore_sound = 'sound/vore/pred/swallow_01.ogg' // Sound when ingesting someone
var/vore_verb = "ingest" // Verb for eating with this in messages
var/human_prey_swallow_time = 100 // Time in deciseconds to swallow /mob/living/carbon/human
var/nonhuman_prey_swallow_time = 60 // Time in deciseconds to swallow anything else
var/human_prey_swallow_time = 10 SECONDS // Time in deciseconds to swallow /mob/living/carbon/human
var/nonhuman_prey_swallow_time = 5 SECONDS // Time in deciseconds to swallow anything else
var/emoteTime = 300 // How long between stomach emotes at prey
var/digest_brute = 0 // Brute damage per tick in digestion mode
var/digest_burn = 1 // Burn damage per tick in digestion mode
var/digest_tickrate = 9 // Modulus this of air controller tick number to iterate gurgles on
var/immutable = FALSE // Prevents this belly from being deleted
var/escapable = TRUE // Belly can be resisted out of at any time
var/escapetime = 200 // Deciseconds, how long to escape this belly
var/escapechance = 45 // % Chance of prey beginning to escape if prey struggles.
var/escapable = FALSE // Belly can be resisted out of at any time
var/escapetime = 60 SECONDS // Deciseconds, how long to escape this belly
var/digestchance = 0 // % Chance of stomach beginning to digest if prey struggles
// var/silenced = FALSE // Will the heartbeat/fleshy internal loop play?
var/escapechance = 0 // % Chance of prey beginning to escape if prey struggles.
var/transferchance = 0 // % Chance of prey being
var/can_taste = FALSE // If this belly prints the flavor of prey when it eats someone.
var/datum/belly/transferlocation = null // Location that the prey is released if they struggle and get dropped off.
var/tmp/digest_mode = DM_HOLD // Whether or not to digest. Default to not digest.
var/tmp/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_NOISY) // Possible digest modes
var/tmp/mob/living/owner // The mob whose belly this is.
@@ -125,7 +130,7 @@
M.forceMove(owner.loc) // Move the belly contents into the same location as belly's owner.
M << sound(null, repeat = 0, wait = 0, volume = 80, channel = CHANNEL_PREYLOOP)
src.internal_contents.Add(M) // Remove from the belly contents
src.internal_contents.Remove(M) // Remove from the belly contents
var/datum/belly/B = check_belly(owner)
if(B)
B.internal_contents.Add(M)
@@ -143,10 +148,13 @@
prey.forceMove(owner)
internal_contents.Add(prey)
// var/datum/belly/B = check_belly(owner)
// if(B.silenced == FALSE) //this needs more testing later
prey << sound('sound/vore/prey/loop.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_PREYLOOP)
if(inside_flavor)
prey << "<span class='notice'><B>[inside_flavor]</B></span>"
to_chat(prey, "<span class='warning'><B>[src.inside_flavor]</B></span>")
// Get the line that should show up in Examine message if the owner of this belly
// is examined. By making this a proc, we not only take advantage of polymorphism,
@@ -158,6 +166,8 @@
var/raw_message = pick(examine_messages)
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
formatted_message = replacetext(formatted_message,"%pred",owner)
formatted_message = replacetext(formatted_message,"%prey",english_list(internal_contents))
return("<span class='warning'>[formatted_message]</span><BR>")
@@ -226,8 +236,8 @@
internal_contents.Remove(M)
M << sound(null, repeat = 0, wait = 0, volume = 80, channel = CHANNEL_PREYLOOP)
// If digested prey is also a pred... anyone inside their bellies gets moved up.
if (is_vore_predator(M))
for (var/bellytype in M.vore_organs)
if(is_vore_predator(M))
for(var/bellytype in M.vore_organs)
var/datum/belly/belly = M.vore_organs[bellytype]
for (var/obj/thing in belly.internal_contents)
thing.loc = owner
@@ -237,7 +247,7 @@
internal_contents.Add(subprey)
to_chat(subprey, "As [M] melts away around you, you find yourself in [owner]'s [name]")
//Drop all items into the belly.
//Drop all items into the belly/floor.
for(var/obj/item/W in M)
if(!M.dropItemToGround(W))
qdel(W)
@@ -312,12 +322,57 @@
to_chat(owner, "<span class='notice'>The attempt to escape from your [name] has failed!/span>")
return
else if(prob(transferchance) && istype(transferlocation)) //Next, let's have it see if they end up getting into an even bigger mess then when they started.
var/location_found = FALSE
var/name_found = FALSE
for(var/I in owner.vore_organs)
var/datum/belly/B = owner.vore_organs[I]
if(B == transferlocation)
location_found = TRUE
break
if(!location_found)
for(var/I in owner.vore_organs)
var/datum/belly/B = owner.vore_organs[I]
if(B.name == transferlocation.name)
name_found = TRUE
transferlocation = B
break
if(!location_found && !name_found)
to_chat(owner, "<span class='warning'>Something went wrong with your belly transfer settings.</span>")
transferlocation = null
return
to_chat(R, "<span class='warning'>Your attempt to escape [name] has failed and your struggles only results in you sliding into [owner]'s [transferlocation]!</span>")
to_chat(owner, "<span class='warning'>Someone slid into your [transferlocation] due to their struggling inside your [name]!</span>")
transfer_contents(R, transferlocation)
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>")
digest_mode = DM_DIGEST
return
else //Nothing interesting happened.
to_chat(R, "<span class='warning'>But make no progress in escaping [owner]'s [name].</span>")
to_chat(owner, "<span class='warning'>But appears to be unable to make any progress in escaping your [name].</span>")
return
else
//Transfers contents from one belly to another
/datum/belly/proc/transfer_contents(var/atom/movable/content, var/datum/belly/target, silent = 0)
if(!(content in internal_contents))
return
internal_contents.Remove(content)
target.internal_contents.Add(content)
if(isliving(content))
var/mob/living/M = content
if(target.inside_flavor)
to_chat(M, "<span class='notice'><B>[target.inside_flavor]</B></span>")
if(target.can_taste && M.get_taste_message(0))
to_chat(owner, "<span class='notice'>[M] tastes of [M.get_taste_message(0)].</span>")
if(!silent)
for(var/mob/hearer in range(1,owner))
hearer << sound(target.vore_sound,volume=80)
// Belly copies and then returns the copy
// Needs to be updated for any var changes
@@ -336,8 +391,13 @@
dupe.digest_burn = digest_burn
dupe.digest_tickrate = digest_tickrate
dupe.immutable = immutable
dupe.can_taste = can_taste
dupe.escapable = escapable
dupe.escapetime = escapetime
dupe.digestchance = digestchance
dupe.escapechance = escapechance
dupe.transferchance = transferchance
dupe.transferlocation = transferlocation
//// Object-holding variables
//struggle_messages_outside - strings
+3 -3
View File
@@ -21,7 +21,7 @@
//////////////////////////// DM_DIGEST ////////////////////////////
if(digest_mode == DM_DIGEST)
for (var/mob/living/M in internal_contents)
if(prob(15))
if(prob(25))
M.stop_sound_channel(CHANNEL_PRED)
playsound(get_turf(owner),"digest_pred",50,0,-6,0,channel=CHANNEL_PRED)
M.stop_sound_channel(CHANNEL_PRED)
@@ -62,14 +62,14 @@
// Deal digestion damage (and feed the pred)
if(!(M.status_flags & GODMODE))
M.adjustFireLoss(1)
M.adjustFireLoss(digest_burn)
owner.nutrition += 1
return
///////////////////////////// DM_HEAL /////////////////////////////
if(digest_mode == DM_HEAL)
for (var/mob/living/M in internal_contents)
if(prob(15))
if(prob(25))
M.stop_sound_channel(CHANNEL_PRED)
playsound(get_turf(owner),"digest_pred",35,0,-6,0,channel=CHANNEL_PRED)
M.stop_sound_channel(CHANNEL_PRED)
+50 -3
View File
@@ -5,14 +5,20 @@
var/list/vore_organs = list() // List of vore containers inside a mob
var/devourable = FALSE // Can the mob be vored at all?
// var/feeding = FALSE // Are we going to feed someone else?
var/vore_taste = null // What the character tastes like
var/no_vore = FALSE // If the character/mob can vore.
var/openpanel = 0 // Is the vore panel open?
//
// Hook for generic creation of stuff on new creatures
//
/hook/living_new/proc/vore_setup(mob/living/M)
M.verbs += /mob/living/proc/insidePanel
M.verbs += /mob/living/proc/escapeOOC
M.verbs += /mob/living/proc/lick
if(M.no_vore) //If the mob isn's supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach.
M << "<span class='warning'>The creature that you are can not eat others.</span>"
return TRUE
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)
@@ -32,7 +38,8 @@
var/datum/belly/B = new /datum/belly(M)
B.immutable = TRUE
B.name = "Stomach"
B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [M.name]."
B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [M.name]"
B.can_taste = TRUE
M.vore_organs[B.name] = B
M.vore_selected = B.name
@@ -302,6 +309,7 @@
P.digestable = src.digestable
P.devourable = src.devourable
P.belly_prefs = src.vore_organs
P.vore_taste = src.vore_taste
return TRUE
@@ -318,9 +326,48 @@
src.digestable = P.digestable
src.devourable = P.devourable
src.vore_organs = list()
src.vore_taste = P.vore_taste
for(var/I in P.belly_prefs)
var/datum/belly/Bp = P.belly_prefs[I]
src.vore_organs[Bp.name] = Bp.copy(src)
return TRUE
//
// Clearly super important. Obviously.
//
/mob/living/proc/lick(var/mob/living/tasted in oview(1))
set name = "Lick Someone"
set category = "Vore"
set desc = "Lick someone nearby!"
if(!istype(tasted))
return
if(src == stat)
return
src.setClickCooldown(50)
src.visible_message("<span class='warning'>[src] licks [tasted]!</span>","<span class='notice'>You lick [tasted]. They taste rather like [tasted.get_taste_message()].</span>","<b>Slurp!</b>")
/mob/living/proc/get_taste_message(allow_generic = TRUE, datum/species/mrace)
if(!vore_taste && !allow_generic)
return FALSE
var/taste_message = ""
if(vore_taste && (vore_taste != ""))
taste_message += "[vore_taste]"
else
if(ishuman(src))
taste_message += "normal, like a critter should"
else
taste_message += "a plain old normal [src]"
/* if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.touching.reagent_list.len) //Just the first one otherwise I'll go insane.
var/datum/reagent/R = H.touching.reagent_list[1]
taste_message += " You also get the flavor of [R.taste_description] from something on them"*/
return taste_message
+21 -16
View File
@@ -1,19 +1,9 @@
///////////////////// Simple Animal /////////////////////
/mob/living/simple_animal
var/isPredator = 0 //Are they capable of performing and pre-defined vore actions for their species?
var/swallowTime = 30 //How long it takes to eat its prey in 1/10 of a second. The default is 3 seconds.
var/isPredator = FALSE //Are they capable of performing and pre-defined vore actions for their species?
var/swallowTime = 5 SECONDS //How long it takes to eat its prey in 1/10 of a second. The default is 5 seconds.
var/list/prey_excludes = list() //For excluding people from being eaten.
//
// Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs.
/*
/mob/living/proc/animal_nom(var/mob/living/T in oview(1))
set name = "Animal Nom"
set category = "Vore"
set desc = "Since you can't grab, you get a verb!"
feed_grabbed_to_self(src,T)
*/
//
// Simple proc for animals to have their digestion toggled on/off externally
//
@@ -25,15 +15,30 @@
var/datum/belly/B = vore_organs[vore_selected]
if(faction != usr.faction)
usr << "<span class='warning'>This predator isn't friendly, and doesn't give a shit about your opinions of it digesting you.</span>"
to_chat(usr,"<span class='warning'>This predator isn't friendly, and doesn't give a shit about your opinions of it digesting you.</span>")
return
if(B.digest_mode == "Hold")
var/confirm = alert(usr, "Enabling digestion on [name] will cause it to digest all stomach contents. Using this to break OOC prefs is against the rules. Digestion will disable itself after 20 minutes.", "Enabling [name]'s Digestion", "Enable", "Cancel")
if(confirm == "Enable")
B.digest_mode = "Digest"
spawn(12000) //12000=20 minutes
if(src) B.digest_mode = "Hold"
sleep(20 MINUTES) //12000=20 minutes
B.digest_mode = "Hold"
else
var/confirm = alert(usr, "This mob is currently set to digest all stomach contents. Do you want to disable this?", "Disabling [name]'s Digestion", "Disable", "Cancel")
if(confirm == "Disable")
B.digest_mode = "Hold"
B.digest_mode = "Hold"
//
// Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs.
//
/mob/living/proc/animal_nom(var/mob/living/T in oview(1))
set name = "Animal Nom"
set category = "Vore"
set desc = "Since you can't grab, you get a verb!"
if (stat != CONSCIOUS)
return
if (T.devourable == FALSE)
to_chat(usr, "<span class='warning'>You can't eat this!</span>")
return
return feed_grabbed_to_self(src,T)
+3
View File
@@ -41,6 +41,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
var/digestable = TRUE
var/devourable = FALSE
var/list/belly_prefs = list()
var/vore_taste
//Mechanically required
var/path
@@ -101,6 +102,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
S["digestable"] >> digestable
S["devourable"] >> devourable
S["belly_prefs"] >> belly_prefs
S["vore_taste"] >> vore_taste
if(isnull(digestable))
digestable = TRUE
@@ -121,6 +123,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
WRITE_FILE(S["digestable"], digestable)
WRITE_FILE(S["devourable"], devourable)
WRITE_FILE(S["belly_prefs"], belly_prefs)
WRITE_FILE(S["vore_taste"], vore_taste)
return TRUE
+194 -39
View File
@@ -2,6 +2,12 @@
// Vore management panel for players
//
#define BELLIES_MAX 20
#define BELLIES_NAME_MIN 2
#define BELLIES_NAME_MAX 12
#define BELLIES_DESC_MAX 1024
#define FLAVOR_MAX 40
/mob/living/proc/insidePanel()
set name = "Vore Panel"
set category = "Vore"
@@ -21,9 +27,15 @@
//
/datum/vore_look
var/datum/belly/selected
var/show_interacts = FALSE
var/datum/browser/popup
var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
/datum/vore_look/Destroy()
loop = null
selected = null
return QDEL_HINT_HARDDEL
/datum/vore_look/Topic(href,href_list[])
if (vp_interact(href, href_list))
popup.set_content(gen_vui(usr))
@@ -55,6 +67,8 @@
continue
//Anything else
dat += "<a href='?src=\ref[src];outsidepick=\ref[O];outsidebelly=\ref[inside_belly]'>[O]</a>"
//Zero-width space, for wrapping
dat += "&#8203;"
else
dat += "You aren't inside anyone."
@@ -79,7 +93,7 @@
dat += "<span style='[spanstyle]'> ([B.internal_contents.len])</span></a></li>"
if(user.vore_organs.len < 10)
if(user.vore_organs.len < BELLIES_MAX)
dat += "<li style='float: left'><a href='?src=\ref[src];newbelly=1'>New+</a></li>"
dat += "</ol>"
dat += "<HR>"
@@ -93,6 +107,8 @@
for(var/O in selected.internal_contents)
dat += "<a href='?src=\ref[src];insidepick=\ref[O]'>[O]</a>"
//Zero-width space, for wrapping
dat += "&#8203;"
//If there's more than one thing, add an [All] button
if(selected.internal_contents.len > 1)
dat += "<a href='?src=\ref[src];insidepick=1;pickall=1'>\[All\]</a>"
@@ -119,9 +135,44 @@
dat += "<br><a href='?src=\ref[src];b_sound=\ref[selected]'>Set Vore Sound</a>"
dat += "<a href='?src=\ref[src];b_soundtest=\ref[selected]'>Test</a>"
// //Belly silence
// dat += "<br><a href='?src=\ref[src];silenced=\ref[selected]'>Belly Silence ([selected.silenced ? "Silenced" : "Noisy"])</a>"
//Belly messages
dat += "<br><a href='?src=\ref[src];b_msgs=\ref[selected]'>Belly Messages</a>"
//Can belly taste?
dat += "<br><a href='?src=\ref[src];b_tastes=\ref[selected]'>Can Taste:</a>"
dat += " [selected.can_taste ? "Yes" : "No"]"
//Belly escapability
dat += "<br><a href='?src=\ref[src];b_escapable=\ref[selected]'>Belly Interactions ([selected.escapable ? "On" : "Off"])</a>"
if(selected.escapable)
dat += "<a href='?src=\ref[src];show_int=\ref[selected]'>[show_interacts ? "Hide" : "Show"]</a>"
if(show_interacts && selected.escapable)
dat += "<HR>"
dat += "Interaction Settings <a href='?src=\ref[src];int_help=\ref[selected]'>?</a>"
dat += "<br><a href='?src=\ref[src];b_escapechance=\ref[selected]'>Set Belly Escape Chance</a>"
dat += " [selected.escapechance]%"
dat += "<br><a href='?src=\ref[src];b_escapetime=\ref[selected]'>Set Belly Escape Time</a>"
dat += " [selected.escapetime/10]s"
//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>"
dat += " [selected.transferchance]%"
dat += "<br><a href='?src=\ref[src];b_transferlocation=\ref[selected]'>Set Belly Transfer Location</a>"
dat += " [selected.transferlocation ? selected.transferlocation : "Disabled"]"
//Special <br> here to add a gap
dat += "<br style='line-height:5px;'>"
dat += "<br><a href='?src=\ref[src];b_digestchance=\ref[selected]'>Set Belly Digest Chance</a>"
dat += " [selected.digestchance]%"
dat += "<HR>"
//Delete button
dat += "<br><a style='background:#990000;' href='?src=\ref[src];b_del=\ref[selected]'>Delete Belly</a>"
@@ -130,7 +181,9 @@
//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];setflavor=1'>Set Flavor</a>"
dat += "<HR>"
switch(user.digestable)
if(TRUE)
dat += "<a href='?src=\ref[src];toggledg=1'>Toggle Digestable (Currently: ON)</a>"
@@ -151,12 +204,26 @@
for(var/H in href_list)
if(href_list["close"])
del(src) // Cleanup
qdel(src) // Cleanup
return
if(href_list["show_int"])
show_interacts = !show_interacts
return TRUE //Force update
if(href_list["int_help"])
to_chat(usr,"These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, \
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.")
return TRUE //Force update
if(href_list["outsidepick"])
var/tgt = locate(href_list["outsidepick"])
var/atom/movable/tgt = locate(href_list["outsidepick"])
var/datum/belly/OB = locate(href_list["outsidebelly"])
if(!(tgt in OB.internal_contents)) //Aren't here anymore, need to update menu.
return TRUE
var/intent = "Examine"
if(istype(tgt,/mob/living))
@@ -184,7 +251,7 @@
if("Devour") //Eat the inside mob
if(!user.vore_selected)
to_chat(user, "<span class='warning'>Pick a belly on yourself first!</span>")
return TRUE
return
var/datum/belly/TB = user.vore_organs[user.vore_selected]
to_chat(user, "<span class='warning'>You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]!</span>")
@@ -202,6 +269,9 @@
else if(istype(tgt,/obj/item))
var/obj/item/T = tgt
if(!(tgt in OB.internal_contents))
//Doesn't exist anymore, update.
return TRUE
intent = alert("What do you want to do to that?","Query","Examine","Use Hand")
switch(intent)
if("Examine")
@@ -210,7 +280,7 @@
if("Use Hand")
if(user.stat)
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
return TRUE
return
user.ClickOn(T)
sleep(5) //Seems to exit too fast for the panel to update
@@ -223,40 +293,38 @@
intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all")
switch(intent)
if("Cancel")
return 1
return
if("Eject all")
if(user.stat)
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
return TRUE
return
selected.release_all_contents()
playsound(user, 'sound/vore/pred/escape.ogg', volume=80)
user.loc << "<span class='danger'>Everything is released from [user]!</span>"
playsound(user, 'sound/vore/pred/escape.ogg', vol=80)
to_chat(user.loc,"<span class='danger'>Everything is released from [user]!</span>")
if("Move all")
if(user.stat)
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
return TRUE
return
var/choice = input("Move all where?","Select Belly") in user.vore_organs + "Cancel - Don't Move"
if(choice == "Cancel - Don't Move")
return TRUE
return
else
var/datum/belly/B = user.vore_organs[choice]
for(var/atom/movable/tgt in selected.internal_contents)
selected.internal_contents -= tgt
B.internal_contents += tgt
to_chat(tgt, "<span class='warning'>You're squished from [user]'s [selected] to their [B]!</span>")
selected.transfer_contents(tgt, B, 1)
for(var/mob/hearer in range(1,user))
hearer << sound('sound/vore/pred/stomachmove.ogg',volume=80)
return TRUE
var/atom/movable/tgt = locate(href_list["insidepick"])
if(!(tgt in selected.internal_contents)) //Old menu, needs updating because they aren't really there.
return TRUE//Forces update
intent = "Examine"
intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move")
switch(intent)
@@ -266,7 +334,7 @@
if("Eject")
if(user.stat)
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
return TRUE
return FALSE
selected.release_specific_contents(tgt)
playsound(user, 'sound/effects/splat.ogg', 50, 1)
@@ -275,28 +343,28 @@
if("Move")
if(user.stat)
to_chat(user, "<span class='warning'>You can't do that in your state!</span>")
return TRUE
return FALSE
var/choice = input("Move [tgt] where?","Select Belly") in user.vore_organs + "Cancel - Don't Move"
if(choice == "Cancel - Don't Move")
return TRUE
return
else
var/datum/belly/B = user.vore_organs[choice]
selected.internal_contents -= tgt
B.internal_contents += tgt
to_chat(tgt, "<span class='warning'>You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(B.name)]!</span>")
if (!(tgt in selected.internal_contents))
return FALSE
to_chat(tgt, "<span class='warning'>You're moved from [user]'s [lowertext(selected.name)] to their [lowertext(B.name)]!</span>")
for(var/mob/hearer in range(1,user))
hearer << sound('sound/vore/pred/stomachmove.ogg',volume=80)
selected.transfer_contents(tgt, B)
if(href_list["newbelly"])
if(user.vore_organs.len >= 10)
if(user.vore_organs.len >= BELLIES_MAX)
return TRUE
var/new_name = html_encode(input(usr,"New belly's name:","New Belly") as text|null)
if(length(new_name) > 12 || length(new_name) < 2)
if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN)
to_chat(usr, "<span class='warning'>Entered belly name is too long.</span>")
return FALSE
if(new_name in user.vore_organs)
@@ -313,10 +381,13 @@
selected = locate(href_list["bellypick"])
user.vore_selected = selected.name
////
//Please keep these the same order they are on the panel UI for ease of coding
////
if(href_list["b_name"])
var/new_name = html_encode(input(usr,"Belly's new name:","New Name") as text|null)
if(length(new_name) > 12 || length(new_name) < 2)
if(length(new_name) > BELLIES_NAME_MAX || length(new_name) < BELLIES_NAME_MIN)
to_chat(usr, "<span class='warning'>Entered belly name length invalid (must be longer than 2, shorter than 12).</span>")
return FALSE
if(new_name in user.vore_organs)
@@ -344,14 +415,16 @@
if(href_list["b_desc"])
var/new_desc = html_encode(input(usr,"Belly Description (1024 char limit):","New Description",selected.inside_flavor) as message|null)
new_desc = readd_quotes(new_desc)
if(new_desc)
new_desc = readd_quotes(new_desc)
if(length(new_desc) > BELLIES_DESC_MAX)
to_chat(usr, "<span class='warning'>Entered belly desc too long. [BELLIES_DESC_MAX] character limit.</span>")
return FALSE
if(length(new_desc) > 1024)
to_chat(usr, "<span class='warning'>Entered belly desc too long. 1024 character limit.</span>")
selected.inside_flavor = new_desc
else //Returned null
return FALSE
selected.inside_flavor = new_desc
if(href_list["b_msgs"])
var/list/messages = list(
"Digest Message (to prey)",
@@ -389,7 +462,7 @@
selected.set_messages(new_message,"smi")
if("Examine Message (when full)")
var/new_message = input(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging'). Do not use %pred or %prey in this type."+help,"Examine Message (when full)",selected.get_messages("em")) as message
var/new_message = input(user,"These are sent to people who examine you when this belly has contents. Write them in 3rd person ('Their %belly is bulging'). "+help,"Examine Message (when full)",selected.get_messages("em")) as message
if(new_message)
selected.set_messages(new_message,"em")
@@ -402,13 +475,13 @@
selected.struggle_messages_inside = initial(selected.struggle_messages_inside)
if("Cancel - No Changes")
return TRUE
return
if(href_list["b_verb"])
var/new_verb = html_encode(input(usr,"New verb when eating (infinitive tense, e.g. nom or swallow):","New Verb") as text|null)
if(length(new_verb) > 12 || length(new_verb) < 2)
to_chat(usr, "<span class='warning'>Entered verb length invalid (must be longer than 2, shorter than 12).</span>")
if(length(new_verb) > BELLIES_NAME_MAX || length(new_verb) < BELLIES_NAME_MIN)
to_chat(usr, "<span class='warning'>Entered verb length invalid (must be longer than [BELLIES_NAME_MIN], no longer than [BELLIES_NAME_MAX]).</span>")
return FALSE
selected.vore_verb = new_verb
@@ -417,20 +490,90 @@
var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") in GLOB.pred_vore_sounds + "Cancel - No Changes"
if(choice == "Cancel")
return 1
return
selected.vore_sound = GLOB.pred_vore_sounds[choice]
if(href_list["b_soundtest"])
user << selected.vore_sound
/*
if(href_list["silenced"])
if(selected.silenced == FALSE)
selected.silenced = TRUE
to_chat(usr,"<span class='warning'>The [selected.name] is now silenced, it will not play the internal loop to prey within it.</span>")
else if(selected.silenced == TRUE)
selected.silenced = FALSE
to_chat(usr,"<span class='warning'>The [selected.name] will play the internal loop to prey within it.</span>")
*/
if(href_list["b_tastes"])
selected.can_taste = !selected.can_taste
if(href_list["b_escapable"])
if(selected.escapable == FALSE) //Possibly escapable and special interactions.
selected.escapable = TRUE
to_chat(usr,"<span class='warning'>Prey now have special interactions with your [selected.name] depending on your settings.</span>")
else if(selected.escapable == TRUE) //Never escapable.
selected.escapable = FALSE
to_chat(usr,"<span class='warning'>Prey will not be able to have special interactions with your [selected.name].</span>")
show_interacts = FALSE //Force the hiding of the panel
else
to_chat(usr,"<span class='warning'>Something went wrong. Your stomach will now not have special interactions. Press the button enable them again and tell a dev.") //If they somehow have a varable that's not 0 or 1
selected.escapable = FALSE
show_interacts = FALSE //Force the hiding of the panel
if(href_list["b_escapechance"])
var/escape_chance_input = input(user, "Set prey escape chance on resist (as %)", "Prey Escape Chance") as num|null
if(!isnull(escape_chance_input)) //These have to be 'null' because both cancel and 0 are valid, separate options
selected.escapechance = sanitize_integer(escape_chance_input, 0, 100, initial(selected.escapechance))
if(href_list["b_escapetime"])
var/escape_time_input = input(user, "Set number of seconds for prey to escape on resist (1-60)", "Prey Escape Time") as num|null
if(!isnull(escape_time_input))
selected.escapetime = sanitize_integer(escape_time_input*10, 10, 600, initial(selected.escapetime))
if(href_list["b_transferchance"])
var/transfer_chance_input = input(user, "Set belly transfer chance on resist (as %). You must also set the location for this to have any effect.", "Prey Escape Time") as num|null
if(!isnull(transfer_chance_input))
selected.transferchance = sanitize_integer(transfer_chance_input, 0, 100, initial(selected.transferchance))
if(href_list["b_transferlocation"])
var/choice = input("Where do you want your [selected.name] to lead if prey resists?","Select Belly") as null|anything in (user.vore_organs + "None - Remove" - selected.name)
if(!choice) //They cancelled, no changes
return
else if(choice == "None - Remove")
selected.transferlocation = null
else
selected.transferlocation = user.vore_organs[choice]
if(href_list["b_digestchance"])
var/digest_chance_input = input(user, "Set belly digest mode chance on resist (as %)", "Prey Digest Chance") as num|null
if(!isnull(digest_chance_input))
selected.digestchance = sanitize_integer(digest_chance_input, 0, 100, initial(selected.digestchance))
if(href_list["b_del"])
var/dest_for = FALSE //Check to see if it's the destination of another vore organ.
for(var/I in user.vore_organs)
var/datum/belly/B = user.vore_organs[I]
if(B.transferlocation == selected)
dest_for = B.name
break
if(dest_for)
alert("This is the destiantion for at least '[dest_for]' belly transfers. Remove it as the destination from any bellies before deleting it.","Error")
return TRUE
else if(selected.internal_contents.len)
alert("Can't delete bellies with contents!","Error")
return TRUE
if(selected.internal_contents.len)
to_chat(usr, "<span class='warning'>Can't delete bellies with contents!</span>")
return
else if(selected.immutable)
to_chat(usr, "<span class='warning'>This belly is marked as undeletable.</span>")
return
else if(user.vore_organs.len == 1)
to_chat(usr, "<span class='warning'>You must have at least one belly.</span>")
return
else
var/alert = alert("Are you sure you want to delete [selected]?","Confirmation","Delete","Cancel")
if(alert == "Delete" && !selected.internal_contents.len)
@@ -438,6 +581,7 @@
user.vore_organs.Remove(selected)
selected = user.vore_organs[1]
user.vore_selected = user.vore_organs[1]
to_chat(usr,"<span class='warning'>Note: If you had this organ selected as a transfer location, please remove the transfer location by selecting Cancel - None - Remove on this stomach.</span>")
if(href_list["saveprefs"])
if(user.save_vore_prefs())
@@ -447,12 +591,23 @@
to_chat(user, "<span class='warning'>ERROR: Belly Preferences were not saved!</span>")
log_admin("Could not save vore prefs on USER: [user].")
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)
new_flavor = readd_quotes(new_flavor)
if(length(new_flavor) > FLAVOR_MAX)
alert("Entered flavor/taste text too long. [FLAVOR_MAX] character limit.","Error")
return FALSE
user.vore_taste = new_flavor
else //Returned null
return FALSE
if(href_list["toggledg"])
var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable to all mobs. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion")
switch(choice)
if("Cancel")
return 1
return
if("Allow Digestion")
user.digestable = TRUE
if("Prevent Digestion")
@@ -465,7 +620,7 @@
var/choice = alert(user, "This button is for those who don't like vore at all. Devouring you is currently: [user.devourable ? "Allowed" : "Prevented"]", "", "Allow Devourment", "Cancel", "Prevent Devourment")
switch(choice)
if("Cancel")
return 1
return
if("Allow Devourment")
user.devourable = TRUE
if("Prevent Devourment")
@@ -475,4 +630,4 @@
user.client.prefs_vr.devourable = user.devourable
//Refresh when interacted with, returning 1 makes vore_look.Topic update
return 1
return TRUE
+1 -1
View File
@@ -412,7 +412,6 @@
#include "code\game\gamemodes\objective.dm"
#include "code\game\gamemodes\objective_items.dm"
#include "code\game\gamemodes\objective_team.dm"
#include "code\game\gamemodes\brother\traitor_bro.dm"
#include "code\game\gamemodes\blob\blob.dm"
#include "code\game\gamemodes\blob\blob_finish.dm"
#include "code\game\gamemodes\blob\blob_report.dm"
@@ -425,6 +424,7 @@
#include "code\game\gamemodes\blob\blobs\node.dm"
#include "code\game\gamemodes\blob\blobs\resource.dm"
#include "code\game\gamemodes\blob\blobs\shield.dm"
#include "code\game\gamemodes\brother\traitor_bro.dm"
#include "code\game\gamemodes\changeling\cellular_emporium.dm"
#include "code\game\gamemodes\changeling\changeling.dm"
#include "code\game\gamemodes\changeling\changeling_power.dm"