Vore Datums implemented, awaiting integration&testing

This commit is contained in:
ShadowLarkens
2020-04-30 16:37:41 -07:00
parent e8fa5768c3
commit dc61ee2ffe
4 changed files with 346 additions and 183 deletions

View File

@@ -203,6 +203,13 @@ var/global/list/string_slot_flags = list(
var/datum/poster/P = new T var/datum/poster/P = new T
NT_poster_designs += P NT_poster_designs += P
// VOREStation Add - Vore Modes!
paths = typesof(/datum/digest_mode) - /datum/digest_mode/transform
for(var/T in paths)
var/datum/digest_mode/DM = new T
GLOB.digest_modes[DM.id] = DM
// VOREStation Add End
return 1 return 1
/* // Uncomment to debug chemical reaction list. /* // Uncomment to debug chemical reaction list.

View File

@@ -0,0 +1,249 @@
GLOBAL_LIST_INIT(digest_modes, list())
/datum/digest_mode
var/id = DM_HOLD
var/noise_chance = 0
/datum/digest_mode/process_mob(obj/belly/B, mob/living/L)
return
/datum/digest_mode/digest
id = DM_DIGEST
noise_chance = 50
/datum/digest_mode/digest/process_mob(obj/belly/B, mob/living/L)
//Pref protection!
if(!L.digestable || L.absorbed)
return
//Person just died in guts!
if(L.stat == DEAD)
if(L.is_preference_enabled(/datum/client_preference/digestion_noises))
if(!B.fancy_vore)
SEND_SOUND(L, sound(get_sfx("classic_death_sounds")))
else
SEND_SOUND(L, sound(get_sfx("fancy_death_prey")))
B.handle_digestion_death(L)
to_update = TRUE
if(!B.fancy_vore)
return sound(get_sfx("classic_death_sounds"))
return sound(get_sfx("fancy_death_pred"))
// Deal digestion damage (and feed the pred)
var/old_brute = L.getBruteLoss()
var/old_burn = L.getFireLoss()
L.adjustBruteLoss(digest_brute)
L.adjustFireLoss(digest_burn)
var/actual_brute = L.getBruteLoss() - old_brute
var/actual_burn = L.getFireLoss() - old_burn
var/damage_gain = actual_brute + actual_burn
var/offset = (1 + ((L.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02
var/difference = B.owner.size_multiplier / L.size_multiplier
if(isrobot(B.owner))
var/mob/living/silicon/robot/R = B.owner
R.cell.charge += 25 * damage_gain
if(offset) // If any different than default weight, multiply the % of offset.
B.owner.adjust_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
B.owner.adjust_nutrition((nutrition_percent / 100) * 4.5 * (damage_gain) / difference)
/datum/digest_mode/absorb
id = DM_ABSORB
noise_chance = 10
/datum/digest_mode/absorb/process_mob(obj/belly/B, mob/living/L)
if(!L.absorbable || L.absorbed)
continue
digestion_noise_chance = 10
steal_nutrition(L)
if(L.nutrition < 100)
absorb_living(L)
to_update = TRUE
/datum/digest_mode/unabsorb
id = DM_UNABSORB
/datum/digest_mode/unabsorb/process_mob(obj/belly/B, mob/living/L)
if(L.absorbed && B.owner.nutrition >= 100)
L.absorbed = FALSE
to_chat(L, "<span class='notice'>You suddenly feel solid again.</span>")
to_chat(B.owner,"<span class='notice'>You feel like a part of you is missing.</span>")
B.owner.adjust_nutrition(-100)
to_update = TRUE
/datum/digest_mode/drain
id = DM_DRAIN
noise_chance = 10
/datum/digest_mode/drain/process_mob(obj/belly/B, mob/living/L)
steal_nutrition(L)
/datum/digest_mode/drain/shrink
id = DM_SHRINK
/datum/digest_mode/drain/shrink/process_mob(obj/belly/B, mob/living/L)
if(L.size_multiplier > B.shrink_grow_size)
L.resize(L.size_multiplier - 0.01) // Shrink by 1% per tick
. = ..()
/datum/digest_mode/grow
id = DM_GROW
noise_chance = 10
/datum/digest_mode/grow/process_mob(obj/belly/B, mob/living/L)
if(L.size_multiplier < B.shrink_grow_size)
L.resize(L.size_multiplier + 0.01) // Shrink by 1% per tick
/datum/digest_mode/drain/sizesteal
id = DM_SIZE_STEAL
/datum/digest_mode/drain/sizesteal/process_mob(obj/belly/B, mob/living/L)
if(L.size_multiplier > B.shrink_grow_size && B.owner.size_multiplier < 2) //Grow until either pred is large or prey is small.
B.owner.resize(B.owner.size_multiplier + 0.01) //Grow by 1% per tick.
L.resize(L.size_multiplier - 0.01) //Shrink by 1% per tick
. = ..()
/datum/digest_mode/heal
id = DM_HEAL
noise_chance = 50 //Wet heals! The secret is you can leave this on for gurgle noises for fun.
/datum/digest_mode/heal/process_mob(obj/belly/B, mob/living/L)
if(L.stat == DEAD)
continue // Can't heal the dead with healbelly
if(B.owner.nutrition > 90 && (L.health < L.maxHealth))
L.adjustBruteLoss(-2.5)
L.adjustFireLoss(-2.5)
L.adjustToxLoss(-5)
L.adjustOxyLoss(-5)
L.adjustCloneLoss(-1.25)
B.owner.adjust_nutrition(-2)
if(L.nutrition <= 400)
L.adjust_nutrition(1)
else if(B.owner.nutrition > 90 && (L.nutrition <= 400))
B.owner.adjust_nutrition(-1)
L.adjust_nutrition(1)
// TRANSFORM MODES
/datum/digest_mode/transform
var/stabilize_nutrition = FALSE
var/changes_eyes = FALSE
var/changes_hair_solo = FALSE
var/changes_hairandskin = FALSE
var/changes_gender = FALSE
var/changes_gender_to = null
var/changes_species = FALSE
var/changes_ears_tail_wing_nocolor = FALSE
var/changes_ears_tail_wing_color = FALSE
var/eggs = FALSE
/datum/digest_mode/transform/process_mob(obj/belly/B, mob/living/carbon/human/H)
if(!istype(H) || H.stat == DEAD)
return
if(stabilize_nutrition)
if(B.owner.nutrition > 400 && H.nutrition < 400)
B.owner.adjust_nutrition(-2)
H.adjust_nutrition(1.5)
if(changes_eyes && B.check_eyes(H))
B.change_eyes(H, 1)
return
if(changes_hair_solo && B.check_hair(H))
B.change_hair(H)
return
if(changes_hairandskin && (B.check_hair(H) || B.check_skin(H)))
B.change_hair(H)
B.change_skin(H, 1)
return
if(changes_species)
if(changes_ears_tail_wing_nocolor && (B.check_ears(H) || B.check_tail_nocolor(H) || B.check_wing_nocolor(H) || B.check_species(H)))
B.change_ears(H)
B.change_tail_nocolor(H)
B.change_wing_nocolor(H)
B.change_species(H, 1, 1) // ,1) preserves coloring
return
if(changes_ears_tail_wing_color && (B.check_ears(H) || B.check_tail(H) || B.check_wing(H) || B.check_species(H)))
B.change_ears(H)
B.change_tail(H)
B.change_wing(H)
B.change_species(H, 1, 2) // ,2) does not preserve coloring.
return
if(changes_gender && B.check_gender(H, changes_gender_to))
B.change_gender(H, changes_gender_to, 1)
return
if(eggs && (!H.absorbed))
B.put_in_egg(H, 1)
return
// Regular TF Modes
/datum/digest_mode/transform/hairandeyes
id = DM_TRANSFORM_HAIR_AND_EYES
stabilize_nutrition = TRUE
changes_eyes = TRUE
changes_hair_solo = TRUE
/datum/digest_mode/transform/gender
id = DM_TRANSFORM_FEMALE
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_gender = TRUE
changes_gender_to = FEMALE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/gender/male
id = DM_TRANSFORM_FEMALE
changes_gender_to = MALE
/datum/digest_mode/transform/keepgender
id = DM_TRANSFORM_KEEP_GENDER
changes_eyes = TRUE
changes_hairandskin = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/speciesandtaur
id = DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR
changes_species = TRUE
changes_ears_tail_wing_nocolor = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/replica
id = DM_TRANSFORM_REPLICA
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_species = TRUE
changes_ears_tail_wing_color = TRUE
// E G G
/datum/digest_mode/transform/egg
id = DM_EGG
eggs = TRUE
/datum/digest_mode/transform/egg/gender
id = DM_TRANSFORM_FEMALE_EGG
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_gender = TRUE
changes_gender_to = FEMALE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/egg/gender/male
id = DM_TRANSFORM_MALE_EGG
changes_gender_to = MALE
/datum/digest_mode/transform/egg/nogender
id = DM_TRANSFORM_KEEP_GENDER_EGG
changes_eyes = TRUE
changes_hairandskin = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/egg/speciesandtaur
id = DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG
changes_species = TRUE
changes_ears_tail_wing_nocolor = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/egg/replica
id = DM_TRANSFORM_REPLICA_EGG
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_species = TRUE
changes_ears_tail_wing_color = TRUE

View File

@@ -1,92 +0,0 @@
/obj/belly/proc/process_tf(mode, list/touchable_mobs) //We pass mode so it's mega-ultra local.
/* May not be necessary... Transform only shows up in the panel for humans.
if(!ishuman(owner))
return //Need DNA and junk for this.
*/
//Cast here for reduced duplication
var/mob/living/carbon/human/O = owner
var/stabilize_nutrition = FALSE
var/changes_eyes = FALSE
var/changes_hair_solo = FALSE
var/changes_hairandskin = FALSE
var/changes_gender = FALSE
var/changes_gender_to = null
var/changes_species = FALSE
var/changes_ears_tail_wing_nocolor = FALSE
var/changes_ears_tail_wing_color = FALSE
var/eggs = FALSE
switch(mode)
if(DM_TRANSFORM_HAIR_AND_EYES)
stabilize_nutrition = TRUE
changes_eyes = TRUE
changes_hair_solo = TRUE
if(DM_TRANSFORM_MALE, DM_TRANSFORM_FEMALE, DM_TRANSFORM_MALE_EGG, DM_TRANSFORM_FEMALE_EGG)
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_gender = TRUE
changes_gender_to = (mode == DM_TRANSFORM_MALE || mode == DM_TRANSFORM_MALE_EGG) ? MALE : FEMALE
stabilize_nutrition = TRUE
eggs = (mode == DM_TRANSFORM_MALE_EGG || mode == DM_TRANSFORM_FEMALE_EGG)
if(DM_TRANSFORM_KEEP_GENDER, DM_TRANSFORM_KEEP_GENDER_EGG)
changes_eyes = TRUE
changes_hairandskin = TRUE
stabilize_nutrition = TRUE
eggs = (mode == DM_TRANSFORM_KEEP_GENDER_EGG)
if(DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR, DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG)
changes_species = TRUE
changes_ears_tail_wing_nocolor = TRUE
stabilize_nutrition = TRUE
eggs = (mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG)
if(DM_TRANSFORM_REPLICA, DM_TRANSFORM_REPLICA_EGG)
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_species = TRUE
changes_ears_tail_wing_color = TRUE
eggs = (mode == DM_TRANSFORM_REPLICA_EGG)
if(DM_EGG)
eggs = TRUE
/* This is designed to do *gradual* transformations.
* For each human in the TF belly per cycle, they can only have one "stage" of transformation applied to them.
* Some transformation modes have different amounts of stages than others and that's okay.
* All stages in order: Eyes, Hair & Skin, Ears & Tail & Wings & Species, Gender, Egg
*/
for(var/mob/living/carbon/human/H in touchable_mobs)
if(H.stat == DEAD)
continue
if(stabilize_nutrition)
if(O.nutrition > 400 && H.nutrition < 400)
O.adjust_nutrition(-2)
H.adjust_nutrition(1.5)
if(changes_eyes && check_eyes(H))
change_eyes(H, 1)
continue
if(changes_hair_solo && check_hair(H))
change_hair(H)
continue
if(changes_hairandskin && (check_hair(H) || check_skin(H)))
change_hair(H)
change_skin(H, 1)
continue
if(changes_species)
if(changes_ears_tail_wing_nocolor && (check_ears(H) || check_tail_nocolor(H) || check_wing_nocolor(H) || check_species(H)))
change_ears(H)
change_tail_nocolor(H)
change_wing_nocolor(H)
change_species(H, 1, 1) // ,1) preserves coloring
continue
if(changes_ears_tail_wing_color && (check_ears(H) || check_tail(H) || check_wing(H) || check_species(H)))
change_ears(H)
change_tail(H)
change_wing(H)
change_species(H, 1, 2) // ,2) does not preserve coloring.
continue
if(changes_gender && check_gender(H, changes_gender_to))
change_gender(H, changes_gender_to, 1)
continue
if(eggs && (!H.absorbed))
put_in_egg(H, 1)
continue

View File

@@ -17,19 +17,13 @@
/////////////////////////// Sound Selections /////////////////////////// /////////////////////////// Sound Selections ///////////////////////////
var/sound/prey_digest var/sound/prey_digest
var/sound/prey_death
var/sound/pred_digest var/sound/pred_digest
var/sound/pred_death
if(!fancy_vore) if(!fancy_vore)
prey_digest = sound(get_sfx("classic_digestion_sounds")) prey_digest = sound(get_sfx("classic_digestion_sounds"))
prey_death = sound(get_sfx("classic_death_sounds"))
pred_digest = sound(get_sfx("classic_digestion_sounds")) pred_digest = sound(get_sfx("classic_digestion_sounds"))
pred_death = sound(get_sfx("classic_death_sounds"))
else else
prey_digest = sound(get_sfx("fancy_digest_prey")) prey_digest = sound(get_sfx("fancy_digest_prey"))
prey_death = sound(get_sfx("fancy_death_prey"))
pred_digest = sound(get_sfx("fancy_digest_pred")) pred_digest = sound(get_sfx("fancy_digest_pred"))
pred_death = sound(get_sfx("fancy_death_pred"))
/////////////////////////// Exit Early //////////////////////////// /////////////////////////// Exit Early ////////////////////////////
var/list/touchable_atoms = contents - items_preserved var/list/touchable_atoms = contents - items_preserved
@@ -99,11 +93,13 @@
else if(istype(A, /obj/effect/decal/cleanable)) else if(istype(A, /obj/effect/decal/cleanable))
qdel(A) qdel(A)
if(digest_mode == DM_HOLD) var/datum/digest_mode/DM = GLOB.digest_modes["[digest_mode]"]
//We deliberately do not want any gurgly noises if the belly is in DM_HOLD if(!DM)
if(to_update) log_debug("Digest mode [digest_mode] didn't exist in the digest_modes list!!")
updateVRPanels() return FALSE
return
if(!digestion_noise_chance)
digestion_noise_chance = DM.noise_chance
if(digest_mode == DM_TRANSFORM) if(digest_mode == DM_TRANSFORM)
process_tf(tf_mode, touchable_mobs) process_tf(tf_mode, touchable_mobs)
@@ -112,89 +108,92 @@
var/mob/living/L = target var/mob/living/L = target
if(!istype(L)) if(!istype(L))
continue continue
switch(digest_mode) var/sound/soundToPlay = DM.process(src, target)
if(DM_DIGEST) if(soundToPlay && !play_sound)
digestion_noise_chance = 50 play_sound = soundToPlay
//Pref protection! //switch(digest_mode)
if(!L.digestable || L.absorbed) // if(DM_DIGEST)
continue // digestion_noise_chance = 50
// //Pref protection!
// if(!L.digestable || L.absorbed)
// continue
//Person just died in guts! // //Person just died in guts!
if(L.stat == DEAD) // if(L.stat == DEAD)
play_sound = pred_death // play_sound = pred_death
if(L.is_preference_enabled(/datum/client_preference/digestion_noises)) // if(L.is_preference_enabled(/datum/client_preference/digestion_noises))
SEND_SOUND(L, prey_death) // SEND_SOUND(L, prey_death)
handle_digestion_death(L) // handle_digestion_death(L)
to_update = TRUE // to_update = TRUE
continue // continue
// Deal digestion damage (and feed the pred) // // Deal digestion damage (and feed the pred)
var/old_brute = L.getBruteLoss() // var/old_brute = L.getBruteLoss()
var/old_burn = L.getFireLoss() // var/old_burn = L.getFireLoss()
L.adjustBruteLoss(digest_brute) // L.adjustBruteLoss(digest_brute)
L.adjustFireLoss(digest_burn) // L.adjustFireLoss(digest_burn)
var/actual_brute = L.getBruteLoss() - old_brute // var/actual_brute = L.getBruteLoss() - old_brute
var/actual_burn = L.getFireLoss() - old_burn // var/actual_burn = L.getFireLoss() - old_burn
var/damage_gain = actual_brute + actual_burn // var/damage_gain = actual_brute + actual_burn
var/offset = (1 + ((L.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02 // var/offset = (1 + ((L.weight - 137) / 137)) // 130 pounds = .95 140 pounds = 1.02
var/difference = owner.size_multiplier / L.size_multiplier // var/difference = owner.size_multiplier / L.size_multiplier
if(isrobot(owner)) // if(isrobot(owner))
var/mob/living/silicon/robot/R = owner // var/mob/living/silicon/robot/R = owner
R.cell.charge += 25 * damage_gain // R.cell.charge += 25 * damage_gain
if(offset) // If any different than default weight, multiply the % of offset. // if(offset) // If any different than default weight, multiply the % of offset.
owner.adjust_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. // owner.adjust_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 // else
owner.adjust_nutrition((nutrition_percent / 100) * 4.5 * (damage_gain) / difference) // owner.adjust_nutrition((nutrition_percent / 100) * 4.5 * (damage_gain) / difference)
if(DM_ABSORB) // if(DM_ABSORB)
if(!L.absorbable || L.absorbed) // if(!L.absorbable || L.absorbed)
continue // continue
digestion_noise_chance = 10 // digestion_noise_chance = 10
steal_nutrition(L) // steal_nutrition(L)
if(L.nutrition < 100) // if(L.nutrition < 100)
absorb_living(L) // absorb_living(L)
to_update = TRUE // to_update = TRUE
if(DM_UNABSORB) // if(DM_UNABSORB)
if(L.absorbed && owner.nutrition >= 100) // if(L.absorbed && owner.nutrition >= 100)
L.absorbed = FALSE // L.absorbed = FALSE
to_chat(L, "<span class='notice'>You suddenly feel solid again.</span>") // to_chat(L, "<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>") // to_chat(owner,"<span class='notice'>You feel like a part of you is missing.</span>")
owner.adjust_nutrition(-100) // owner.adjust_nutrition(-100)
to_update = TRUE // to_update = TRUE
if(DM_DRAIN) // if(DM_DRAIN)
digestion_noise_chance = 10 // digestion_noise_chance = 10
steal_nutrition(L) // steal_nutrition(L)
if(DM_SHRINK) // if(DM_SHRINK)
digestion_noise_chance = 10 // digestion_noise_chance = 10
if(L.size_multiplier > shrink_grow_size) // if(L.size_multiplier > shrink_grow_size)
L.resize(L.size_multiplier - 0.01) // Shrink by 1% per tick // L.resize(L.size_multiplier - 0.01) // Shrink by 1% per tick
steal_nutrition(L) // steal_nutrition(L)
if(DM_GROW) // if(DM_GROW)
digestion_noise_chance = 10 // digestion_noise_chance = 10
if(L.size_multiplier < shrink_grow_size) // if(L.size_multiplier < shrink_grow_size)
L.resize(L.size_multiplier - 0.01) // Grow by 1% per tick // L.resize(L.size_multiplier - 0.01) // Grow by 1% per tick
if(DM_SIZE_STEAL) // if(DM_SIZE_STEAL)
digestion_noise_chance = 10 // digestion_noise_chance = 10
if(L.size_multiplier > shrink_grow_size && owner.size_multiplier < 2) //Grow until either pred is large or prey is small. // if(L.size_multiplier > shrink_grow_size && owner.size_multiplier < 2) //Grow until either pred is large or prey is small.
owner.resize(owner.size_multiplier+0.01) //Grow by 1% per tick. // owner.resize(owner.size_multiplier+0.01) //Grow by 1% per tick.
L.resize(L.size_multiplier-0.01) //Shrink by 1% per tick // L.resize(L.size_multiplier-0.01) //Shrink by 1% per tick
steal_nutrition(L) // steal_nutrition(L)
if(DM_HEAL) // if(DM_HEAL)
digestion_noise_chance = 50 //Wet heals! The secret is you can leave this on for gurgle noises for fun. // digestion_noise_chance = 50 //Wet heals! The secret is you can leave this on for gurgle noises for fun.
if(L.stat == DEAD) // if(L.stat == DEAD)
continue // Can't heal the dead with healbelly // continue // Can't heal the dead with healbelly
if(owner.nutrition > 90 && (L.health < L.maxHealth)) // if(owner.nutrition > 90 && (L.health < L.maxHealth))
L.adjustBruteLoss(-2.5) // L.adjustBruteLoss(-2.5)
L.adjustFireLoss(-2.5) // L.adjustFireLoss(-2.5)
L.adjustToxLoss(-5) // L.adjustToxLoss(-5)
L.adjustOxyLoss(-5) // L.adjustOxyLoss(-5)
L.adjustCloneLoss(-1.25) // L.adjustCloneLoss(-1.25)
owner.adjust_nutrition(-2) // owner.adjust_nutrition(-2)
if(L.nutrition <= 400) // if(L.nutrition <= 400)
L.adjust_nutrition(1) // L.adjust_nutrition(1)
else if(owner.nutrition > 90 && (L.nutrition <= 400)) // else if(owner.nutrition > 90 && (L.nutrition <= 400))
owner.adjust_nutrition(-1) // owner.adjust_nutrition(-1)
L.adjust_nutrition(1) // L.adjust_nutrition(1)
/////////////////////////// Make any noise /////////////////////////// /////////////////////////// Make any noise ///////////////////////////
if(digestion_noise_chance && prob(digestion_noise_chance)) if(digestion_noise_chance && prob(digestion_noise_chance))