Ashdrake noms (#2868)
* Initial commit * probably a better way to check this * It compiled boys. Let's see if it works. * IT WAS ALL NULLS, BOYS * Hooray, it's not broken anymore boys! * Well it works, but we need transfer IDs to work locating them post-initialize would help, probably. Then assigning their links soon after. * Bellies linked, autotransfer, LoseTarget * half-thought sanity check needs to go away * A few last minute tweaks.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
var/vore_verb = "ingest" // Verb for eating with this in messages
|
||||
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/emoteTime = 30 SECONDS // 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
|
||||
@@ -25,15 +25,21 @@
|
||||
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/transferchance = 0 // % Chance of prey being transferred to transfer location when resisting
|
||||
var/autotransferchance = 0 // % Chance of prey being autotransferred to transfer location
|
||||
var/autotransferwait = 10 // Time between trying to transfer.
|
||||
var/can_taste = FALSE // If this belly prints the flavor of prey when it eats someone.
|
||||
|
||||
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.
|
||||
var/tmp/list/internal_contents = list() // People/Things you've eaten into this belly!
|
||||
var/tmp/is_full // Flag for if digested remeans are present. (for disposal messages)
|
||||
var/tmp/emotePend = FALSE // If there's already a spawned thing counting for the next emote
|
||||
var/tmp/mob/living/owner // The mob whose belly this is.
|
||||
var/tmp/list/internal_contents = list() // People/Things you've eaten into this belly!
|
||||
var/tmp/is_full // Flag for if digested remeans are present. (for disposal messages)
|
||||
var/tmp/emotePend = FALSE // If there's already a spawned thing counting for the next emote
|
||||
var/swallow_time = 10 SECONDS // for mob transfering automation
|
||||
var/vore_capacity = 1 // The capacity (in people) this person can hold
|
||||
|
||||
// Don't forget to watch your commas at the end of each line if you change these.
|
||||
var/list/struggle_messages_outside = list(
|
||||
@@ -153,8 +159,41 @@
|
||||
// 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)
|
||||
|
||||
// Handle prey messages
|
||||
if(inside_flavor)
|
||||
to_chat(prey, "<span class='warning'><B>[src.inside_flavor]</B></span>")
|
||||
if(isliving(prey))
|
||||
var/mob/living/M = prey
|
||||
if(can_taste && M.get_taste_message(0))
|
||||
to_chat(owner, "<span class='notice'>[M] tastes of [M.get_taste_message(0)].</span>")
|
||||
|
||||
// Setup the autotransfer checks if needed
|
||||
if(transferlocation && autotransferchance > 0)
|
||||
addtimer(CALLBACK(src, /datum/belly/.proc/check_autotransfer, prey), autotransferwait)
|
||||
|
||||
/datum/belly/proc/check_autotransfer(var/mob/prey)
|
||||
// Some sanity checks
|
||||
if(transferlocation && (autotransferchance > 0) && (prey in internal_contents))
|
||||
if(prob(autotransferchance))
|
||||
// Double check transferlocation isn't insane
|
||||
if(verify_transferlocation())
|
||||
transfer_contents(prey, transferlocation)
|
||||
else
|
||||
// Didn't transfer, so wait before retrying
|
||||
addtimer(CALLBACK(src, /datum/belly/.proc/check_autotransfer, prey), autotransferwait)
|
||||
|
||||
/datum/belly/proc/verify_transferlocation()
|
||||
for(var/I in owner.vore_organs)
|
||||
var/datum/belly/B = owner.vore_organs[I]
|
||||
if(B == transferlocation)
|
||||
return TRUE
|
||||
|
||||
for(var/I in owner.vore_organs)
|
||||
var/datum/belly/B = owner.vore_organs[I]
|
||||
if(B.name == transferlocation.name)
|
||||
transferlocation = B
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// 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,
|
||||
@@ -323,23 +362,9 @@
|
||||
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
|
||||
var/location_ok = verify_transferlocation()
|
||||
|
||||
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)
|
||||
if(!location_ok)
|
||||
to_chat(owner, "<span class='warning'>Something went wrong with your belly transfer settings.</span>")
|
||||
transferlocation = null
|
||||
return
|
||||
@@ -358,18 +383,14 @@
|
||||
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
|
||||
|
||||
//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>")
|
||||
// Re-use nom_mob
|
||||
target.nom_mob(content, target.owner)
|
||||
if(!silent)
|
||||
for(var/mob/hearer in range(1,owner))
|
||||
hearer << sound(target.vore_sound,volume=80)
|
||||
@@ -398,6 +419,8 @@
|
||||
dupe.escapechance = escapechance
|
||||
dupe.transferchance = transferchance
|
||||
dupe.transferlocation = transferlocation
|
||||
dupe.autotransferchance = autotransferchance
|
||||
dupe.autotransferwait = autotransferwait
|
||||
|
||||
//// Object-holding variables
|
||||
//struggle_messages_outside - strings
|
||||
|
||||
@@ -91,3 +91,53 @@
|
||||
playsound(get_turf(owner),"digest_pred",35,0,-6,0,channel=CHANNEL_PRED)
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
M.playsound_local(get_turf(M), null, 45, S = prey_gurgle)
|
||||
|
||||
|
||||
//////////////////////////DM_DRAGON /////////////////////////////////////
|
||||
//because dragons need snowflake guts
|
||||
if(digest_mode == DM_DRAGON)
|
||||
for (var/mob/living/M in internal_contents)
|
||||
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)
|
||||
M.playsound_local(get_turf(M), null, 45, S = prey_gurgle)
|
||||
|
||||
//No digestion protection for megafauna.
|
||||
|
||||
//Person just died in guts!
|
||||
if(M.stat == DEAD)
|
||||
var/digest_alert_owner = pick(digest_messages_owner)
|
||||
var/digest_alert_prey = pick(digest_messages_prey)
|
||||
|
||||
//Replace placeholder vars
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%pred",owner)
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%prey",M)
|
||||
digest_alert_owner = replacetext(digest_alert_owner,"%belly",lowertext(name))
|
||||
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%pred",owner)
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%prey",M)
|
||||
digest_alert_prey = replacetext(digest_alert_prey,"%belly",lowertext(name))
|
||||
|
||||
//Send messages
|
||||
to_chat(owner, "<span class='warning'>[digest_alert_owner]</span>")
|
||||
to_chat(M, "<span class='warning'>[digest_alert_prey]</span>")
|
||||
M.visible_message("<span class='notice'>You watch as [owner]'s guts loudly rumble as it finishes off a meal.</span>")
|
||||
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
playsound(get_turf(owner),"death_pred",45,0,-6,0,channel=CHANNEL_PRED)
|
||||
M.stop_sound_channel(CHANNEL_PRED)
|
||||
M.playsound_local(get_turf(M), null, 45, S = prey_digest)
|
||||
M.spill_organs(FALSE,TRUE,TRUE)
|
||||
M << sound(null, repeat = 0, wait = 0, volume = 80, channel = CHANNEL_PREYLOOP)
|
||||
digestion_death(M)
|
||||
owner.update_icons()
|
||||
continue
|
||||
|
||||
|
||||
// Deal digestion damage (and feed the pred)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustFireLoss(digest_burn)
|
||||
M.adjustToxLoss(4) // something something plasma based acids
|
||||
M.adjustCloneLoss(3) // eventually this'll kill you if you're healing everything else, you nerds.
|
||||
return
|
||||
@@ -121,6 +121,42 @@
|
||||
var/belly = input("Choose Belly") in pred.vore_organs
|
||||
return perform_the_nom(user, prey, pred, belly)
|
||||
|
||||
//Dragon noms need to be faster
|
||||
/mob/living/proc/dragon_feeding(var/mob/living/user, var/mob/living/prey)
|
||||
var/belly = user.vore_selected
|
||||
return perform_dragon(user, prey, user, belly)
|
||||
|
||||
/mob/living/proc/perform_dragon(var/mob/living/user, var/mob/living/prey, var/mob/living/pred, var/belly, swallow_time = 20)
|
||||
//Sanity
|
||||
if(!user || !prey || !pred || !belly || !(belly in pred.vore_organs))
|
||||
return
|
||||
|
||||
// The belly selected at the time of noms
|
||||
var/datum/belly/belly_target = pred.vore_organs[belly]
|
||||
var/attempt_msg = "ERROR: Vore message couldn't be created. Notify a dev. (at)"
|
||||
var/success_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)"
|
||||
|
||||
// Prepare messages
|
||||
if(user == pred) //Feeding someone to yourself
|
||||
attempt_msg = text("<span class='warning'>[] starts to [] [] into their []!</span>",pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name))
|
||||
success_msg = text("<span class='warning'>[] manages to [] [] into their []!</span>",pred,lowertext(belly_target.vore_verb),prey,lowertext(belly_target.name))
|
||||
|
||||
// Announce that we start the attempt!
|
||||
user.visible_message(attempt_msg)
|
||||
|
||||
if(!do_mob(src, user, swallow_time)) // one second should be good enough, right?
|
||||
return FALSE // Prey escaped (or user disabled) before timer expired.
|
||||
|
||||
// If we got this far, nom successful! Announce it!
|
||||
user.visible_message(success_msg)
|
||||
playsound(user, belly_target.vore_sound, 100, 1)
|
||||
|
||||
// Actually shove prey into the belly.
|
||||
belly_target.nom_mob(prey, user)
|
||||
if (pred == user)
|
||||
message_admins("[key_name(pred)] ate [key_name(prey)].")
|
||||
log_attack("[key_name(pred)] ate [key_name(prey)]")
|
||||
return TRUE
|
||||
//
|
||||
// Master vore proc that actually does vore procedures
|
||||
//
|
||||
@@ -250,6 +286,7 @@
|
||||
if(M.loc != src)
|
||||
B.internal_contents.Remove(M)
|
||||
|
||||
|
||||
// OOC Escape code for pref-breaking or AFK preds
|
||||
//
|
||||
/mob/living/proc/escapeOOC()
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
//
|
||||
/datum/vore_look
|
||||
var/datum/belly/selected
|
||||
var/show_interacts = FALSE
|
||||
var/show_interacts = TRUE
|
||||
var/datum/browser/popup
|
||||
var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user