Merge pull request #235 from Shadowfire117/Fluidvorebellies

Liquid vore bellies!
This commit is contained in:
Razgriz
2020-02-19 01:28:34 -07:00
committed by GitHub
16 changed files with 811 additions and 8 deletions
+9
View File
@@ -0,0 +1,9 @@
//CHOMP belly modes
//Belly Reagents mode flags
#define DM_FLAG_REAGENTSNUTRI 0x1
#define DM_FLAG_REAGENTSDIGEST 0x2
#define DM_FLAG_REAGENTSABSORB 0x4
#define DM_FLAG_REAGENTSDRAIN 0x8
+1
View File
@@ -5,6 +5,7 @@
#define CHEM_TOUCH 1
#define CHEM_INGEST 2
#define CHEM_BLOOD 3
#define CHEM_VORE 4 //CHOMP vore belly interactions
#define MINIMUM_CHEMICAL_VOLUME 0.01
@@ -34,6 +34,7 @@ SUBSYSTEM_DEF(bellies)
if(QDELETED(B))
belly_list -= B
else
B.HandleBellyReagents() //CHOMP reagent belly stuff, here to jam it into subsystems and avoid too much cpu usage
if(B.process_belly(times_fired,wait) == SSBELLIES_IGNORED)
ignored_bellies++
@@ -291,6 +291,7 @@
msg += attempt_vr(src,"examine_weight",args) //VOREStation Code
msg += attempt_vr(src,"examine_nutrition",args) //VOREStation Code
msg += attempt_vr(src,"examine_reagent_bellies",args) //CHOMP reagent bellies
msg += attempt_vr(src,"examine_bellies",args) //VOREStation Code
msg += attempt_vr(src,"examine_pickup_size",args) //VOREStation Code
msg += attempt_vr(src,"examine_step_size",args) //VOREStation Code
@@ -7,6 +7,7 @@
if(!src.client) msg += "\nIt appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "\n<span class='warning'>It doesn't seem to be responding.</span>\n"
if(DEAD) msg += "\n<span class='deadsay'>It looks completely unsalvageable.</span>\n"
msg += attempt_vr(src,"examine_reagent_bellies",args) //CHOMP reagent bellies
msg += attempt_vr(src,"examine_bellies",args) //VOREStation Edit
// VOREStation Edit: Start
@@ -32,6 +32,7 @@
msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"
if(DEAD) msg += "<span class='deadsay'>It looks completely unsalvageable.</span>\n"
msg += attempt_vr(src,"examine_reagent_bellies",args) //CHOMP reagent bellies
msg += attempt_vr(src,"examine_bellies_borg",args) //VOREStation Edit
// VOREStation Edit: Start
@@ -0,0 +1,25 @@
//CHOMP code for transfer specifically into vore bellies
/datum/reagents/proc/vore_trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_VORE, var/multiplier = 1, var/copy = 0, var/obj/belly/target_belly = null) // Transfer after checking into which holder...
if(!target || !istype(target))
return
if(iscarbon(target))
var/mob/living/carbon/C = target
if(type == CHEM_VORE)
var/datum/reagents/R = target_belly.reagents
return trans_to_holder(R, amount, multiplier, copy)
if(type == CHEM_INGEST)
var/datum/reagents/R = C.ingested
return C.ingest(src, R, amount, multiplier, copy)
else //Retaining this code as a backup
var/datum/reagents/R = new /datum/reagents(amount)
. = trans_to_holder(R, amount, multiplier, copy)
R.touch_mob(target)
/datum/reagents/proc/vore_trans_to_con(var/obj/item/weapon/reagent_containers/T, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder...
if(!T || !istype(T))
return
return trans_to_holder(T.reagents, amount, multiplier, copy)
+265
View File
@@ -0,0 +1,265 @@
#define VORE_SOUND_FALLOFF 0.1
#define VORE_SOUND_RANGE 3
//CHOMP vore additions, currently only consists of reagent stuff - Jack
/obj/belly
//CHOMP - liquid bellies
var/reagentbellymode = FALSE // Belly has abilities to make liquids from digested/absorbed/drained prey and/or nutrition
var/reagent_mode_flags = 0
var/tmp/static/list/reagent_mode_flag_list= list(
"Produce Liquids" = DM_FLAG_REAGENTSNUTRI,
"Digestion Liquids" = DM_FLAG_REAGENTSDIGEST,
"Absorption Liquids" = DM_FLAG_REAGENTSABSORB,
"Draining Liquids" = DM_FLAG_REAGENTSDRAIN
)
var/nutri_reagent_gen = FALSE //if belly produces reagent over time using nutrition, needs to be optimized to use subsystem - Jack
var/list/generated_reagents = list("water" = 1) //Any number of reagents, the associated value is how many units are generated per process()
var/reagent_name = "water" //What is shown when reagents are removed, doesn't need to be an actual reagent
var/gen_cost = 1 //amount of nutrient taken from the host everytime nutrition is used to make reagents
var/gen_amount = 1 //Does not actually influence amount produced, but is used as a way to tell the system how much total reagent it has to take into account when filling a belly
var/gen_interval = 0 //Interval in seconds for generating fluids, once it reaches the value of gen_time one cycle of reagents generation will occur
var/gen_time = 30 //Time it takes in seconds to produce one cycle of reagents
var/digest_nutri_gain = 0 //variable to store temporary nutrition gain from digestion and allow a seperate proc to ease up on the wall of code
var/liquid_fullness1_messages = FALSE
var/liquid_fullness2_messages = FALSE
var/liquid_fullness3_messages = FALSE
var/liquid_fullness4_messages = FALSE
var/liquid_fullness5_messages = FALSE
var/list/fullness1_messages = list(
"%pred's %belly looks empty"
)
var/list/fullness2_messages = list(
"%pred's %belly looks filled"
)
var/list/fullness3_messages = list(
"%pred's %belly looks like it's full of liquid"
)
var/list/fullness4_messages = list(
"%pred's %belly is quite full!"
)
var/list/fullness5_messages = list(
"%pred's %belly is completely filled to it's limit!"
)
// Stuff to add in future!
/*
var/list/empty_message = list("You feel as though your internal reagent implant is almost empty.")
var/list/full_message = "You feel as though your internal reagent implant is full."
var/list/emote_descriptor = list("tranfers something") //In format of [x] [emote_descriptor] into [container]
var/list/self_emote_descriptor = list("transfer") //In format of You [self_emote_descriptor] some [generated_reagent] into [container]
var/list/random_emote = list() //An emote the person with the implant may be forced to perform after a prob check, such as [X] meows. //Potential future settings to have custom messages set by player when someone extracts fluids from them - Jack
*/
var/tmp/reagent_chosen = "Water" // variable for switch to figure out what to set variables when a certain reagent is selected
var/tmp/static/list/reagent_choices = list( // List of reagents people can chose, maybe one day expand so it covers criterias like dogborgs who can make meds, booze, etc - Jack
"Water",
"Milk",
"Cream",
"Honey"
)
///////////////////// NUTRITION REAGENT PRODUCTION /////////////////
/obj/belly/proc/HandleBellyReagents()
if(reagent_mode_flags & DM_FLAG_REAGENTSNUTRI && reagents.total_volume < reagents.maximum_volume)
if(owner.nutrition >= gen_cost && gen_interval >= gen_time)
GenerateBellyReagents()
gen_interval = 0
else
gen_interval++
/obj/belly/proc/GenerateBellyReagents()
owner.nutrition -= gen_cost
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent])
//////////////////////////// REAGENT_DIGEST ////////////////////////
/obj/belly/proc/GenerateBellyReagents_digesting() //The rate isnt based on selected reagent, due to the fact that the price of the reagent is already paid by nutrient not gained.
if(reagents.total_volume + (digest_nutri_gain * gen_amount) <= reagents.maximum_volume) //By default a reagent with an amount of 1 should result in pred getting 100 units from a full health prey
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] * digest_nutri_gain)
else
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] / gen_amount * (reagents.maximum_volume - reagents.total_volume))
/obj/belly/proc/GenerateBellyReagents_digested()
if(reagents.total_volume <= reagents.maximum_volume - 25 * gen_amount)
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] * 25)
else
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] / gen_amount * (reagents.maximum_volume - reagents.total_volume))
//////////////////////////// REAGENT_ABSORB ////////////////////////
/obj/belly/proc/GenerateBellyReagents_absorbing()
if(reagents.total_volume <= reagents.maximum_volume - 1.5 * gen_amount) //Going for 1.5 amount of reagent per cycle, can be adjusted in future if need adjustments
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] * 1.5)
else
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] / gen_amount * (reagents.maximum_volume - reagents.total_volume))
/obj/belly/proc/GenerateBellyReagents_absorbed()
if(reagents.total_volume <= reagents.maximum_volume - 25 * gen_amount) //Going for 25 amount of reagent for absorbing the prey, can be adjusted in future if need adjustments
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] * 10)
else
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent] / gen_amount * (reagents.maximum_volume - reagents.total_volume))
//////////////////////////// REAGENT_DRAIN ///////////////////////// //Currently not needed, maybe later a specific proc for drain needs to be made - Jack
//////////////////////////// REAGENT SELECTION /////////////////////
//This is gonna end up a long proc, but its gonna have to make do for now
/obj/belly/proc/ReagentSwitch()
switch(reagent_chosen)
if("Water")
generated_reagents = list("water" = 1)
reagent_name = "water"
gen_amount = 1
gen_cost = 1
if("Milk")
generated_reagents = list("milk" = 1)
reagent_name = "milk"
gen_amount = 1
gen_cost = 1.5
if("Cream")
generated_reagents = list("cream" = 1)
reagent_name = "cream"
gen_amount = 1
gen_cost = 1.5
if("Honey")
generated_reagents = list("honey" = 1)
reagent_name = "honey"
gen_amount = 1
gen_cost = 1.5
/////////////////////// FULLNESS MESSAGES //////////////////////
// Get the line that should show up in Examine message if the owner of this belly is examined.
// Returns a string which shoul be appended to the Examine output.
// Yes I know it doesnt look great with 5 almost identical procs in a row, I didnt have a better idea at the time - Jack
/obj/belly/proc/get_reagent_examine_msg1()
if(fullness1_messages.len)
var/formatted_message
var/raw_message = pick(fullness1_messages)
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
formatted_message = replacetext(formatted_message,"%pred",owner)
return("<span class='warning'>[formatted_message]</span><BR>")
/obj/belly/proc/get_reagent_examine_msg2()
if(fullness1_messages.len)
var/formatted_message
var/raw_message = pick(fullness2_messages)
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
formatted_message = replacetext(formatted_message,"%pred",owner)
return("<span class='warning'>[formatted_message]</span><BR>")
/obj/belly/proc/get_reagent_examine_msg3()
if(fullness1_messages.len)
var/formatted_message
var/raw_message = pick(fullness3_messages)
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
formatted_message = replacetext(formatted_message,"%pred",owner)
return("<span class='warning'>[formatted_message]</span><BR>")
/obj/belly/proc/get_reagent_examine_msg4()
if(fullness1_messages.len)
var/formatted_message
var/raw_message = pick(fullness4_messages)
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
formatted_message = replacetext(formatted_message,"%pred",owner)
return("<span class='warning'>[formatted_message]</span><BR>")
/obj/belly/proc/get_reagent_examine_msg5()
if(fullness1_messages.len)
var/formatted_message
var/raw_message = pick(fullness5_messages)
formatted_message = replacetext(raw_message,"%belly",lowertext(name))
formatted_message = replacetext(formatted_message,"%pred",owner)
return("<span class='warning'>[formatted_message]</span><BR>")
// The next function gets the messages set on the belly, in human-readable format.
// This is useful in customization boxes and such. The delimiter right now is \n\n so
// in message boxes, this looks nice and is easily delimited.
/obj/belly/proc/get_reagent_messages(var/type, var/delim = "\n\n")
ASSERT(type == "full1" || type == "full2" || type == "full3" || type == "full4" || type == "full5")
var/list/raw_messages
switch(type)
if("full1")
raw_messages = fullness1_messages
if("full2")
raw_messages = fullness2_messages
if("full3")
raw_messages = fullness3_messages
if("full4")
raw_messages = fullness4_messages
if("full5")
raw_messages = fullness5_messages
var/messages = list2text(raw_messages,delim)
return messages
// The next function sets the messages on the belly, from human-readable var
// replacement strings and linebreaks as delimiters (two \n\n by default).
// They also sanitize the messages.
/obj/belly/proc/set_reagent_messages(var/raw_text, var/type, var/delim = "\n\n")
ASSERT(type == "full1" || type == "full2" || type == "full3" || type == "full4" || type == "full5")
var/list/raw_list = text2list(html_encode(raw_text),delim)
if(raw_list.len > 10)
raw_list.Cut(11)
log_debug("[owner] tried to set [lowertext(name)] with 11+ messages")
for(var/i = 1, i <= raw_list.len, i++)
if(length(raw_list[i]) > 160 || length(raw_list[i]) < 10) //160 is fudged value due to htmlencoding increasing the size
raw_list.Cut(i,i)
log_debug("[owner] tried to set [lowertext(name)] with >121 or <10 char message")
else
raw_list[i] = readd_quotes(raw_list[i])
//Also fix % sign for var replacement
raw_list[i] = replacetext(raw_list[i],"&#37;","%")
ASSERT(raw_list.len <= 10) //Sanity
switch(type)
if("full1")
fullness1_messages = raw_list
if("full2")
fullness2_messages = raw_list
if("full3")
fullness3_messages = raw_list
if("full4")
fullness4_messages = raw_list
if("full5")
fullness5_messages = raw_list
return
+69 -1
View File
@@ -158,7 +158,24 @@
"release_sound",
"fancy_vore",
"is_wet",
"wet_loop"
"wet_loop",
"reagent_mode_flags", //CHOMP start of variables from CHOMP
"liquid_fullness1_messages",
"liquid_fullness2_messages",
"liquid_fullness3_messages",
"liquid_fullness4_messages",
"liquid_fullness5_messages",
"reagent_name",
"reagent_chosen",
"gen_cost",
"gen_amount",
"gen_time",
"generated_reagents",
"fullness1_messages",
"fullness2_messages",
"fullness3_messages",
"fullness4_messages",
"fullness5_messages" //CHOMP end of variables from CHOMP
)
/obj/belly/New(var/newloc)
@@ -168,6 +185,8 @@
owner = loc
owner.vore_organs |= src
SSbellies.belly_list += src
create_reagents(100) //CHOMP So we can have some liquids in bellies
flags |= NOREACT // We dont want bellies to start bubling nonstop due to people mixing when transfering and making different reagents
/obj/belly/Destroy()
SSbellies.belly_list -= src
@@ -690,6 +709,18 @@
dupe.fancy_vore = fancy_vore
dupe.is_wet = is_wet
dupe.wet_loop = wet_loop
dupe.reagent_mode_flags = reagent_mode_flags //CHOMP start of variables from CHOMP
dupe.liquid_fullness1_messages = liquid_fullness1_messages
dupe.liquid_fullness2_messages = liquid_fullness2_messages
dupe.liquid_fullness3_messages = liquid_fullness3_messages
dupe.liquid_fullness4_messages = liquid_fullness4_messages
dupe.liquid_fullness5_messages = liquid_fullness5_messages
dupe.reagent_name = reagent_name
dupe.reagent_chosen = reagent_chosen
dupe.gen_cost = gen_cost
dupe.gen_amount = gen_amount
dupe.gen_time = gen_time //CHOMP end of variables from CHOMP
//// Object-holding variables
//struggle_messages_outside - strings
@@ -717,6 +748,43 @@
for(var/I in examine_messages)
dupe.examine_messages += I
// CHOMP reagent belly
//generated_reagents - strings
dupe.generated_reagents.Cut()
for(var/I in generated_reagents)
dupe.generated_reagents += I
// CHOMP fullness messages stage 1
//fullness1_messages - strings
dupe.fullness1_messages.Cut()
for(var/I in fullness1_messages)
dupe.fullness1_messages += I
// CHOMP fullness messages stage 2
//fullness2_messages - strings
dupe.fullness2_messages.Cut()
for(var/I in fullness2_messages)
dupe.fullness2_messages += I
// CHOMP fullness messages stage 3
//fullness3_messages - strings
dupe.fullness3_messages.Cut()
for(var/I in fullness3_messages)
dupe.fullness3_messages += I
// CHOMP fullness messages stage 4
//fullness4_messages - strings
dupe.fullness4_messages.Cut()
for(var/I in fullness4_messages)
dupe.fullness4_messages += I
// CHOMP fullness messages stage 5
//generated_reagents - strings
dupe.fullness5_messages.Cut()
for(var/I in fullness5_messages)
dupe.fullness5_messages += I
//emote_lists - index: digest mode, key: list of strings
dupe.emote_lists.Cut()
for(var/K in emote_lists)
+36 -7
View File
@@ -191,9 +191,17 @@
if(compensation > 0)
if(isrobot(owner))
var/mob/living/silicon/robot/R = owner
R.cell.charge += 25*compensation
if(reagent_mode_flags & DM_FLAG_REAGENTSDIGEST && reagents.total_volume < reagents.maximum_volume) //CHOMP digestion producing reagents
R.cell.charge += 15*compensation
GenerateBellyReagents_digested()
else
R.cell.charge += 25*compensation
else
owner.nutrition += (nutrition_percent / 100)*4.5*compensation
if(reagent_mode_flags & DM_FLAG_REAGENTSDIGEST && reagents.total_volume < reagents.maximum_volume) //CHOMP digestion producing reagents
owner.nutrition += (nutrition_percent / 100)*3.0*compensation
GenerateBellyReagents_digested()
else
owner.nutrition += (nutrition_percent / 100)*4.5*compensation
to_update = TRUE
continue
@@ -210,10 +218,20 @@
var/offset = (1 + ((M.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02
var/difference = owner.size_multiplier / M.size_multiplier
if(isrobot(owner))
var/mob/living/silicon/robot/R = owner
R.cell.charge += 25*damage_gain
if(reagent_mode_flags & DM_FLAG_REAGENTSDIGEST && reagents.total_volume < reagents.maximum_volume) //CHOMP digestion producing reagents
var/mob/living/silicon/robot/R = owner
R.cell.charge += 20*damage_gain
GenerateBellyReagents_digesting()
else
var/mob/living/silicon/robot/R = owner
R.cell.charge += 25*damage_gain
if(offset) // If any different than default weight, multiply the % of offset.
owner.nutrition += offset*((nutrition_percent / 100)*4.5*(damage_gain)/difference) //4.5 nutrition points per health point. Normal same size 100+100 health prey with average weight would give 900 points if the digestion was instant. With all the size/weight offset taxes plus over time oxyloss+hunger taxes deducted with non-instant digestion, this should be enough to not leave the pred starved.
if(reagent_mode_flags & DM_FLAG_REAGENTSDIGEST && reagents.total_volume < reagents.maximum_volume) //CHOMP digestion producing reagents
owner.nutrition += offset*((nutrition_percent / 100)*4.5/(gen_cost*1.25)*(damage_gain)/difference)//Uncertain if balanced fairly, can adjust by multiplier for the cost of reagent, dont go below 1 or else it will result in more nutrition than normal - Jack
digest_nutri_gain = offset*((nutrition_percent / 100)*0.5/(gen_cost*1.25)*(damage_gain)/difference) //for transfering nutrition value over to GenerateBellyReagents_digesting()
GenerateBellyReagents_digesting()
else
owner.nutrition += offset*((nutrition_percent / 100)*4.5*(damage_gain)/difference)//4.5 nutrition points per health point. Normal same size 100+100 health prey with average weight would give 900 points if the digestion was instant. With all the size/weight offset taxes plus over time oxyloss+hunger taxes deducted with non-instant digestion, this should be enough to not leave the pred starved.
else
owner.nutrition += (nutrition_percent / 100)*4.5*(damage_gain)/difference
@@ -237,9 +255,15 @@
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
if(reagent_mode_flags & DM_FLAG_REAGENTSABSORB && reagents.total_volume < reagents.maximum_volume) //CHOMP absorption reagent production
owner.nutrition += oldnutrition * 0.75 //keeping the price static, due to how much nutrition can flunctuate
GenerateBellyReagents_absorbing()
else
owner.nutrition += oldnutrition
else if(M.nutrition < 100) //When they're finally drained.
absorb_living(M)
if(reagent_mode_flags & DM_FLAG_REAGENTSABSORB && reagents.total_volume < reagents.maximum_volume) //CHOMP absorption reagent production
GenerateBellyReagents_absorbed() //A bonus for pred, I know for a fact prey is usually at zero nutrition when absorption finally happens
to_update = TRUE
//////////////////////////// DM_UNABSORB ////////////////////////////
@@ -269,7 +293,11 @@
if(M.nutrition >= 100) //Drain them until there's no nutrients left.
var/oldnutrition = (M.nutrition * 0.05)
M.nutrition = (M.nutrition * 0.95)
owner.nutrition += oldnutrition
if(reagent_mode_flags & DM_FLAG_REAGENTSDRAIN && reagents.total_volume < reagents.maximum_volume) //CHOMP draining reagent production
owner.nutrition += oldnutrition * 0.75 //keeping the price static, due to how much nutrition can flunctuate
GenerateBellyReagents_absorbing() //Dont need unique proc so far
else
owner.nutrition += oldnutrition
//////////////////////////// DM_SHRINK ////////////////////////////
else if(digest_mode == DM_SHRINK)
@@ -372,6 +400,7 @@
else
M.playsound_local(owner.loc, play_sound, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF)
//these are all external sound triggers now, so it's ok.
if(to_update)
for(var/mob/living/M in contents)
if(M.client)
+138
View File
@@ -0,0 +1,138 @@
///////////////////// Mob Living /////////////////////
/mob/living
var/receive_reagents = FALSE //Pref for people to avoid others transfering reagents into them.
var/give_reagents = FALSE //Pref for people to avoid others taking reagents from them.
//
// Returns examine messages for how much reagents are in bellies
//
/mob/living/proc/examine_reagent_bellies()
if(!show_pudge()) //Some clothing or equipment can hide this. Reagent inflation is not very different in this aspect.
return ""
var/message = ""
for (var/belly in vore_organs)
var/obj/belly/B = belly
if(0 <= B.reagents.total_volume && B.reagents.total_volume <= 20 && B.liquid_fullness1_messages)
message += B.get_reagent_examine_msg1()
if(20 < B.reagents.total_volume && B.reagents.total_volume <= 40 && B.liquid_fullness2_messages)
message += B.get_reagent_examine_msg2()
if(40 < B.reagents.total_volume && B.reagents.total_volume <= 60 && B.liquid_fullness3_messages)
message += B.get_reagent_examine_msg3()
if(60 < B.reagents.total_volume && B.reagents.total_volume <= 80 && B.liquid_fullness4_messages)
message += B.get_reagent_examine_msg4()
if(80 < B.reagents.total_volume && B.reagents.total_volume <= 100 && B.liquid_fullness5_messages)
message += B.get_reagent_examine_msg5()
return message
/mob/living/proc/vore_transfer_reagents()
set name = "Transfer Liquid (Vore)"
set category = "Abilities"
set desc = "Transfer liquid from an organ to another or stomach, or into another person or container."
set popup_menu = FALSE
if(!canClick() || incapacitated(INCAPACITATION_ALL))
return FALSE
var/mob/living/user = usr
var/mob/living/TG = input("Choose who is transfered from") as null| mob in view(user.loc,1)
if(!TG)
return FALSE
var/obj/belly/RTB = input("Choose which organ to transfer from") as null|anything in TG.vore_organs //First they choose the belly to transfer from.
if(!RTB)
return FALSE
if(TG.give_reagents == FALSE && user != TG) //User isnt forced to allow giving in prefs if they are the one doing it
to_chat(user, "<span class='warning'>This person's prefs dont allow that!</span>")
return FALSE
var/transfer_amount = input("How much to transfer?") in list(5,10,25,50,100)
if(!transfer_amount)
return FALSE
switch(input(user,"Choose what to transfer to","Select Target") in list("Organs", "Stomachs", "Containers", "Cancel"))
if("Cancel")
return FALSE
if("Organs")
var/mob/living/TR = input(user,"Choose who to transfer to","Select Target") as null|mob in view(user.loc,1)
if(!TR) return FALSE
if(TR == user) //Proceed, we dont need to have prefs enabled for transfer within user
var/obj/belly/TB = input("Choose which organ to transfer to") as null|anything in user.vore_organs
if(!TB)
return FALSE
if(!TR.reagents.get_free_space())
to_chat(user, "<span class='notice'>[TB] is full!</span>")
return FALSE
RTB.reagents.vore_trans_to_mob(TR, transfer_amount, CHEM_VORE, 1, 0, TB)
if(TG != user)
user.visible_message("<span class='notice'>[user] fills their [TB] with [RTB.reagent_name] from [TG]'s [RTB].</span>")
else
user.visible_message("<span class='notice'>[user] fills their [TB] with [RTB.reagent_name] from their [RTB].</span>")
else if(TR.receive_reagents == FALSE)
to_chat(user, "<span class='warning'>This person's prefs dont allow that!</span>")
return FALSE
else
var/obj/belly/TB = input("Choose which organ to transfer to") as null|anything in TR.vore_organs
if(!TB)
return FALSE
if(!TR.reagents.get_free_space())
to_chat(user, "<span class='notice'>[TR]'s [TB] is full!</span>")
return FALSE
RTB.reagents.vore_trans_to_mob(TR, transfer_amount, CHEM_VORE, 1, 0, TB)
if(TG == user)
user.visible_message("<span class='notice'>[user] fills [TR]'s [TB] with [RTB.reagent_name] from their [RTB].</span>")
else
user.visible_message("<span class='notice'>[user] fills [TR]'s [TB] with [RTB.reagent_name] from [TG]'s [RTB].</span>")
add_attack_logs(user,TR,"Transfered reagents from [TG]'s [RTB] to [TR]'s [TB]") //Bonus for staff so they can see if people have abused transfer and done pref breaks
if("Stomachs")
var/mob/living/TR = input(user,"Choose who to transfer to","Select Target") as null|mob in view(user.loc,1)
if(!TR) return
if(TR == user) //Proceed, we dont need to have prefs enabled for transfer within user
RTB.reagents.vore_trans_to_mob(TR, transfer_amount, CHEM_INGEST, 1, 0, null)
if(TG != user)
user.visible_message("<span class='notice'>[user] fills their stomach with [RTB.reagent_name] from [TG]'s [RTB].</span>")
else
user.visible_message("<span class='notice'>[user] fills their stomach with [RTB.reagent_name] from their [RTB].</span>")
else if(TR.receive_reagents == FALSE)
to_chat(user, "<span class='warning'>This person's prefs dont allow that!</span>")
return FALSE
else
RTB.reagents.vore_trans_to_mob(TR, transfer_amount, CHEM_INGEST, 1, 0, null)
if(TG == user)
user.visible_message("<span class='notice'>[user] fills [TR]'s stomach with [RTB.reagent_name] from their [RTB].</span>")
else
user.visible_message("<span class='notice'>[user] fills [TR]'s stomach with [RTB.reagent_name] from [TG]'s [RTB].</span>")
add_attack_logs(user,TR,"Transfered reagents from [TG]'s [RTB] to [TR]'s Stomach") //Bonus for staff so they can see if people have abused transfer and done pref breaks
if("Containers")
var/list/choices = list()
for(var/obj/item/weapon/reagent_containers/rc in view(user.loc,1))
choices += rc
var/obj/item/weapon/reagent_containers/T = input(user,"Choose what to transfer to","Select Target") as null|anything in choices
RTB.reagents.vore_trans_to_con(T, transfer_amount, 1, 0)
if(TG == user)
user.visible_message("<span class='notice'>[user] fills the [T] with [RTB.reagent_name] from their [RTB].</span>")
else
user.visible_message("<span class='notice'>[user] fills the [T] with [RTB.reagent_name] from [TG]'s [RTB].</span>")
+13
View File
@@ -42,6 +42,7 @@
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 TRUE
M.verbs += /mob/living/proc/insidePanel
M.verbs += /mob/living/proc/vore_transfer_reagents //CHOMP If mob doesnt have bellies it cant use this verb for anything
//Tries to load prefs if a client is present otherwise gives freebie stomach
spawn(2 SECONDS)
@@ -229,6 +230,12 @@
P.can_be_drop_prey = src.can_be_drop_prey
P.can_be_drop_pred = src.can_be_drop_pred
//CHOMP reagent belly
P.receive_reagents = src.receive_reagents
P.give_reagents = src.give_reagents
var/list/serialized = list()
for(var/belly in src.vore_organs)
var/obj/belly/B = belly
@@ -259,6 +266,12 @@
can_be_drop_prey = P.can_be_drop_prey
can_be_drop_pred = P.can_be_drop_pred
//CHOMP reagents belly
receive_reagents = P.receive_reagents
give_reagents = P.give_reagents
release_vore_contents(silent = TRUE)
vore_organs.Cut()
for(var/entry in P.belly_prefs)
+18
View File
@@ -55,6 +55,12 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
var/can_be_drop_prey = FALSE
var/can_be_drop_pred = FALSE
//CHOMP reagent belly
var/receive_reagents = FALSE
var/give_reagents = FALSE
//Mechanically required
var/path
var/slot
@@ -126,6 +132,12 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
can_be_drop_pred = json_from_file["can_be_drop_pred"]
belly_prefs = json_from_file["belly_prefs"]
//CHOMP reagent belly
receive_reagents = json_from_file["receive_reagents"]
give_reagents = json_from_file["give_reagents"]
//Quick sanitize
if(isnull(digestable))
digestable = TRUE
@@ -148,6 +160,12 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE
if(isnull(belly_prefs))
belly_prefs = list()
//CHOMP reagent belly
if(isnull(receive_reagents))
receive_reagents = FALSE
if(isnull(give_reagents))
give_reagents = FALSE
return TRUE
/datum/vore_preferences/proc/save_vore()
+6
View File
@@ -0,0 +1,6 @@
//CHOMP - liquid bellies
/datum/vore_look
var/show_liquids = FALSE
var/show_fullness_messages = FALSE
+222
View File
@@ -306,6 +306,78 @@
dat += " [selected.digestchance]%"
dat += "<HR>"
//CHOMP belly reagent container start
dat += "<br><a href='?src=\ref[src];b_liquidcontainer=\ref[selected]'>Belly liquids ([selected.reagentbellymode ? "On" : "Off"])</a>"
if(selected.reagentbellymode)
dat += "<a href='?src=\ref[src];show_liq=\ref[selected]'>[show_liquids ? "Hide" : "Show"]</a>"
if(show_liquids && selected.reagentbellymode)
dat += "<HR>"
dat += "Liquid Settings <a href='?src=\ref[src];liq_help=\ref[selected]'>?</a>"
//Special <br> here to add a gap
dat += "<br style='line-height:5px;'>"
//Reagent Select Button
dat += "<br><a href='?src=\ref[src];reagent_choices=\ref[selected]'>Selected Liquid:</a>"
dat += " [selected.reagent_chosen]"
//Liquid addons button
dat += "<br><a href='?src=\ref[src];reagents_addons=\ref[selected]'>Liquid Addons:</a>"
var/list/reagent_flag_list = list()
for(var/reagent_flag_name in selected.reagent_mode_flag_list)
if(selected.reagent_mode_flags & selected.reagent_mode_flag_list[reagent_flag_name])
reagent_flag_list += reagent_flag_name
if(reagent_flag_list.len)
dat += " [english_list(reagent_flag_list)]"
else
dat += " None"
//Special <br> here to add a gap
dat += "<br style='line-height:5px;'>"
//Rate of production of reagents from nutrition, goes from 10 to 100 seconds
dat += "<br><a href='?src=\ref[src];reagent_nutri_rate=\ref[selected]'>Liquid Production Rate:</a>"
dat += " [selected.gen_time] seconds"
//Shows how full stomach is of reagents
dat += "<br> Capacity [selected.reagents.total_volume] / [selected.reagents.maximum_volume]"
dat += "<br> Liquid fullness messages <a href='?src=\ref[src];liq_fullness_help=\ref[selected]'>?</a>"
dat += "<a href='?src=\ref[src];show_liq_fullness=\ref[selected]'>[show_fullness_messages ? "Hide" : "Show"]</a>"
if(show_fullness_messages)
dat += "<br><a href='?src=\ref[src];b_liq_msgs1=\ref[selected]'>0-20% Fullness Messages</a>"
dat += "<a href='?src=\ref[src];b_liq_msgs1_toggle=\ref[selected]'>[selected.liquid_fullness1_messages ? "On" : "Off"]</a>"
dat += "<br><a href='?src=\ref[src];b_liq_msgs2=\ref[selected]'>21-40% Fullness Messages</a>"
dat += "<a href='?src=\ref[src];b_liq_msgs2_toggle=\ref[selected]'>[selected.liquid_fullness2_messages ? "On" : "Off"]</a>"
dat += "<br><a href='?src=\ref[src];b_liq_msgs3=\ref[selected]'>41-60% Fullness Messages</a>"
dat += "<a href='?src=\ref[src];b_liq_msgs3_toggle=\ref[selected]'>[selected.liquid_fullness3_messages ? "On" : "Off"]</a>"
dat += "<br><a href='?src=\ref[src];b_liq_msgs4=\ref[selected]'>61-80% Fullness Messages</a>"
dat += "<a href='?src=\ref[src];b_liq_msgs4_toggle=\ref[selected]'>[selected.liquid_fullness4_messages ? "On" : "Off"]</a>"
dat += "<br><a href='?src=\ref[src];b_liq_msgs5=\ref[selected]'>81-100% Fullness Messages</a>"
dat += "<a href='?src=\ref[src];b_liq_msgs5_toggle=\ref[selected]'>[selected.liquid_fullness5_messages ? "On" : "Off"]</a>"
//Special <br> here to add a gap
dat += "<br style='line-height:5px;'>"
dat += "<a style='background:#990000;' href='?src=\ref[src];b_purge_liq=\ref[selected]'>Purge liquids from belly</a>"
switch(user.receive_reagents)
if(TRUE)
dat += "<br><a style='background:#173d15;' href='?src=\ref[src];toggle_liq_rec=1'>Toggle Receiving (Currently: ON)</a>"
if(FALSE)
dat += "<br><a style='background:#990000;' href='?src=\ref[src];toggle_liq_rec=1'>Toggle Receiving (Currently: OFF)</a>"
switch(user.give_reagents)
if(TRUE)
dat += "<a style='background:#173d15;' href='?src=\ref[src];toggle_liq_giv=1'>Toggle Giving (Currently: ON)</a>"
if(FALSE)
dat += "<a style='background:#990000;' href='?src=\ref[src];toggle_liq_giv=1'>Toggle Giving (Currently: OFF)</a>"
//CHOMP belly reagent container end
dat += "<HR>"
//Delete button
dat += "<br><a style='background:#990000;' href='?src=\ref[src];b_del=\ref[selected]'>Delete Belly</a>"
@@ -1032,5 +1104,155 @@
if("Disable audible hunger")
user.noisy = FALSE
//CHOMP belly reagent container start
if(href_list["show_liq"])
show_liquids = !show_liquids
return 1 //Force update
if(href_list["show_liq_fullness"])
show_fullness_messages = !show_fullness_messages
return 1 //Force update
if(href_list["b_liq_msgs1_toggle"])
selected.liquid_fullness1_messages = !selected.liquid_fullness1_messages
return 1 //Force update
if(href_list["b_liq_msgs2_toggle"])
selected.liquid_fullness2_messages = !selected.liquid_fullness2_messages
return 1 //Force update
if(href_list["b_liq_msgs3_toggle"])
selected.liquid_fullness3_messages = !selected.liquid_fullness3_messages
return 1 //Force update
if(href_list["b_liq_msgs4_toggle"])
selected.liquid_fullness4_messages = !selected.liquid_fullness4_messages
return 1 //Force update
if(href_list["b_liq_msgs5_toggle"])
selected.liquid_fullness5_messages = !selected.liquid_fullness5_messages
return 1 //Force update
if(href_list["b_liq_msgs1"])
alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.")
var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name."
var/new_message = input(user,"These are sent to people who examine you when this belly is 0 to 20% full. Write them in 3rd person ('Their %belly is bulging')."+help,"Liquid Examine Message (0 - 20%)",selected.get_reagent_messages("full1")) as message
if(new_message)
selected.set_reagent_messages(new_message,"full1")
if(href_list["b_liq_msgs2"])
alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.")
var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name."
var/new_message = input(user,"These are sent to people who examine you when this belly is 0 to 20% full. Write them in 3rd person ('Their %belly is bulging')."+help,"Liquid Examine Message (0 - 20%)",selected.get_reagent_messages("full2")) as message
if(new_message)
selected.set_reagent_messages(new_message,"full2")
if(href_list["b_liq_msgs3"])
alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.")
var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name."
var/new_message = input(user,"These are sent to people who examine you when this belly is 0 to 20% full. Write them in 3rd person ('Their %belly is bulging')."+help,"Liquid Examine Message (0 - 20%)",selected.get_reagent_messages("full3")) as message
if(new_message)
selected.set_reagent_messages(new_message,"full3")
if(href_list["b_liq_msgs4"])
alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.")
var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name."
var/new_message = input(user,"These are sent to people who examine you when this belly is 0 to 20% full. Write them in 3rd person ('Their %belly is bulging')."+help,"Liquid Examine Message (0 - 20%)",selected.get_reagent_messages("full4")) as message
if(new_message)
selected.set_reagent_messages(new_message,"full4")
if(href_list["b_liq_msgs5"])
alert(user,"Setting abusive or deceptive messages will result in a ban. Consider this your warning. Max 150 characters per message, max 10 messages per topic.","Really, don't.")
var/help = " Press enter twice to separate messages. '%pred' will be replaced with your name. '%prey' will be replaced with the prey's name. '%belly' will be replaced with your belly's name."
var/new_message = input(user,"These are sent to people who examine you when this belly is 0 to 20% full. Write them in 3rd person ('Their %belly is bulging')."+help,"Liquid Examine Message (0 - 20%)",selected.get_reagent_messages("full5")) as message
if(new_message)
selected.set_reagent_messages(new_message,"full5")
if(href_list["liq_help"])
alert("This is the settings for liquid bellies, every belly has a liquid storage that can be filled up and emptied by you and others (if your prefs allow them). Currently there are four belly modes, three that determines if digestion, absorption, and/or draining will produce a selected liquid at the cost of reduced nutrition. The fourth setting allows for producing a liquid over time using your nutrition. You can set the rate as well if you want it to be fast or slow. (Currently prefs of giving and receiving are not saved to avoid people leaving them on and risk abuse in initial period of release where community tries it out)")
return 0 //Force update
if(href_list["liq_fullness_help"])
alert("These are the settings for belly visibility when involving liquids, you can write custom messages for each interval of fullness. You can also decide if you want messages for a certain interval disabled, though this will not mean other interval's messages will show.")
return 0 //Force update
if(href_list["reagents_addons"])
var/list/menu_list = selected.reagent_mode_flag_list.Copy()
var/reagent_toggle_addon = input("Toggle Addon") as null|anything in menu_list
if(!reagent_toggle_addon)
return FALSE
selected.reagent_mode_flags ^= selected.reagent_mode_flag_list[reagent_toggle_addon]
if(href_list["b_liquidcontainer"])
if(selected.reagentbellymode == FALSE) //liquid container adjustments and interactions.
selected.reagentbellymode = TRUE
to_chat(usr,"<span class='warning'>Your [lowertext(selected.name)] now has interactions with prey that can produce liquids.</span>")
else if(selected.reagentbellymode == TRUE) //Doesnt produce liquids
selected.reagentbellymode = FALSE
to_chat(usr,"<span class='warning'>Your [lowertext(selected.name)] wont produce liquids when interacting with prey, liquids already in your [lowertext(selected.name)] must be emptied out or removed with purge.</span>")
show_liquids = 0 //Force the hiding of the panel
else
alert("Something went wrong. Your stomach will now not have special liquid abilities. Press the button enable them again and tell a dev.","Error") //If they somehow have a varable that's not 0 or 1
selected.reagentbellymode = FALSE
show_liquids = 0 //Force the hiding of the panel
if(href_list["reagent_choices"])
var/list/menu_list = selected.reagent_choices.Copy() //Useful if we want to make certain races, synths, borgs, and other things result in additional reagents to produce - Jack
var/new_reagent = input("Choose Reagent (currently [selected.reagent_chosen])") as null|anything in menu_list
if(!new_reagent)
return FALSE
selected.reagent_chosen = new_reagent
selected.ReagentSwitch() // For changing variables when a new reagent is chosen
if(href_list["reagent_nutri_rate"])
var/new_reagent_rate = input(user, "Choose the time it takes to produce more liquid from nutrition. Ranges from 10 to 100 seconds.", "Set Liquid Production Rate.", selected.gen_time) as num|null
if(new_reagent_rate == null)
return
var/new_new_reagent_rate = CLAMP(new_reagent_rate, 10, 100)
selected.gen_time = new_new_reagent_rate
if(href_list["b_purge_liq"])
var/alert = alert("Are you sure you want to delete the liquids in your [lowertext(selected.name)]?","Confirmation","Delete","Cancel")
if(!(alert == "Delete"))
return FALSE
else
selected.reagents.clear_reagents()
if(href_list["toggle_liq_rec"])
var/choice = alert(user, "This button is for allowing or preventing others from giving you liquids from their vore organs, isnt needed on if you are the one peforming the action. It is currently: [user.receive_reagents ? "Allowed" : "Prevented"]", "", "Allow Receiving", "Cancel", "Prevent Receiving")
switch(choice)
if("Cancel")
return FALSE
if("Allow Receiving")
user.receive_reagents = TRUE
if("Prevent Receiving")
user.receive_reagents = FALSE
if(user.client.prefs_vr)
user.client.prefs_vr.receive_reagents = user.receive_reagents
if(href_list["toggle_liq_giv"])
var/choice = alert(user, "This button is for allowing or preventing others from taking liquids from your vore organs, isnt needed on if you are the one peforming the action. It is currently: [user.give_reagents ? "Allowed" : "Prevented"]", "", "Allow Giving", "Cancel", "Prevent Giving")
switch(choice)
if("Cancel")
return FALSE
if("Allow Giving")
user.give_reagents = TRUE
if("Prevent Giving")
user.give_reagents = FALSE
//CHOMP belly reagent container end
if(user.client.prefs_vr)
user.client.prefs_vr.give_reagents = user.give_reagents
//Refresh when interacted with, returning 1 makes vore_look.Topic update
return TRUE
+5
View File
@@ -35,6 +35,7 @@
#include "code\__defines\admin_vr.dm"
#include "code\__defines\appearance.dm"
#include "code\__defines\atmos.dm"
#include "code\__defines\belly_modes_ch.dm"
#include "code\__defines\belly_modes_vr.dm"
#include "code\__defines\callbacks.dm"
#include "code\__defines\chemistry.dm"
@@ -3135,6 +3136,7 @@
#include "code\modules\random_map\noise\tundra.dm"
#include "code\modules\reagents\Chemistry-Colours.dm"
#include "code\modules\reagents\Chemistry-Holder.dm"
#include "code\modules\reagents\Chemistry-Holder_ch.dm"
#include "code\modules\reagents\Chemistry-Logging.dm"
#include "code\modules\reagents\Chemistry-Machinery.dm"
#include "code\modules\reagents\Chemistry-Machinery_vr.dm"
@@ -3416,18 +3418,21 @@
#include "code\modules\vore\appearance\sprite_accessories_yw.dm"
#include "code\modules\vore\appearance\update_icons_vr.dm"
#include "code\modules\vore\eating\belly_dat_vr.dm"
#include "code\modules\vore\eating\belly_obj_ch.dm"
#include "code\modules\vore\eating\belly_obj_vr.dm"
#include "code\modules\vore\eating\bellymodes_tf_vr.dm"
#include "code\modules\vore\eating\bellymodes_vr.dm"
#include "code\modules\vore\eating\contaminate_vr.dm"
#include "code\modules\vore\eating\digest_act_vr.dm"
#include "code\modules\vore\eating\leave_remains_vr.dm"
#include "code\modules\vore\eating\living_ch.dm"
#include "code\modules\vore\eating\living_vr.dm"
#include "code\modules\vore\eating\silicon_vr.dm"
#include "code\modules\vore\eating\simple_animal_vr.dm"
#include "code\modules\vore\eating\transforming_vr.dm"
#include "code\modules\vore\eating\vore_vr.dm"
#include "code\modules\vore\eating\vorehooks_vr.dm"
#include "code\modules\vore\eating\vorepanel_ch.dm"
#include "code\modules\vore\eating\vorepanel_vr.dm"
#include "code\modules\vore\fluffstuff\custom_boxes_vr.dm"
#include "code\modules\vore\fluffstuff\custom_boxes_yw.dm"