mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-12 07:35:31 +01:00
Refactors vore code to allow for instant-vore that does not sleep (#18219)
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
@@ -343,7 +343,7 @@
|
||||
m.drop_from_inventory(S.OurRig)
|
||||
if(wearer && devour) //We're being worn. Engulf em', if prefs align.. otherwise just drop off.
|
||||
if(P.can_be_drop_pred && wearer.devourable && wearer.can_be_drop_prey && P.vore_selected)
|
||||
perform_the_nom(P,wearer,P,P.vore_selected,-1)
|
||||
begin_instant_nom(P,wearer,P,P.vore_selected)
|
||||
else
|
||||
to_chat(P, span_vwarning("You can't assimilate your current host."))
|
||||
P.forceMove(get_turf(S.OurRig))
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
. = ..()
|
||||
movement_cooldown = 10
|
||||
|
||||
/mob/living/simple_mob/vore/alienanimals/dustjumper/begin_instant_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
. = ..()
|
||||
movement_cooldown = 10
|
||||
|
||||
/datum/ai_holder/simple_mob/melee/evasive/dustjumper
|
||||
hostile = FALSE
|
||||
retaliate = TRUE
|
||||
|
||||
@@ -152,6 +152,10 @@
|
||||
return //If it can do normal vore mechanics, it can carry players to the OM,
|
||||
//and release them there. I think that's probably a bad idea.
|
||||
|
||||
/mob/living/simple_mob/vore/overmap/stardog/begin_instant_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
to_chat(src, span_warning("You can't do that."))
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/vore/overmap/stardog/Initialize(mapload)
|
||||
. = ..()
|
||||
child_om_marker.set_light(5, 1, "#ff8df5")
|
||||
|
||||
@@ -813,24 +813,38 @@ GLOBAL_VAR_INIT(teppi_count, 0) // How mant teppi DO we have?
|
||||
|
||||
|
||||
/mob/living/simple_mob/vore/alienanimals/teppi/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay_time)
|
||||
if(!client)
|
||||
var/teppi_checks = teppi_checks(user, prey, pred, belly)
|
||||
if(teppi_checks)
|
||||
belly = teppi_checks
|
||||
ai_holder.set_busy(TRUE)
|
||||
prey.stop_pulling()
|
||||
..()
|
||||
if(!client)
|
||||
ai_holder.set_busy(FALSE)
|
||||
|
||||
/mob/living/simple_mob/vore/alienanimals/teppi/begin_instant_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
if(!client)
|
||||
var/teppi_checks = teppi_checks(user, prey, pred, belly)
|
||||
if(teppi_checks)
|
||||
belly = teppi_checks
|
||||
ai_holder.set_busy(TRUE)
|
||||
prey.stop_pulling()
|
||||
..()
|
||||
if(!client)
|
||||
ai_holder.set_busy(FALSE)
|
||||
|
||||
///Retrns the belly we'll be using if we are friends.
|
||||
/mob/living/simple_mob/vore/alienanimals/teppi/proc/teppi_checks(mob/living/user, mob/living/prey, mob/living/pred)
|
||||
if(!pred)
|
||||
pred = user
|
||||
if(client)
|
||||
return ..()
|
||||
var/current_affinity = affinity[prey.real_name]
|
||||
ai_holder.set_busy(TRUE)
|
||||
prey.stop_pulling()
|
||||
if(current_affinity >= 50)
|
||||
belly = friend_zone
|
||||
..()
|
||||
ai_holder.set_busy(FALSE)
|
||||
return
|
||||
return friend_zone
|
||||
if(current_affinity <= -50)
|
||||
vore_selected.digest_mode = DM_DIGEST
|
||||
else
|
||||
vore_selected.digest_mode = DM_DRAIN
|
||||
..()
|
||||
ai_holder.set_busy(FALSE)
|
||||
|
||||
//Instead of copying this everywhere let's just make a proc
|
||||
/mob/living/simple_mob/vore/alienanimals/teppi/proc/lets_eat(person)
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
if(L in eaten_mobs)
|
||||
return
|
||||
if(L.devourable && L.allowmobvore && (src.vore_fullness < src.vore_capacity))
|
||||
perform_the_nom(src,L,src,src.vore_selected,-1)
|
||||
begin_instant_nom(src,L,src,src.vore_selected)
|
||||
eaten_mobs += L
|
||||
|
||||
|
||||
|
||||
@@ -678,118 +678,6 @@
|
||||
var/belly = tgui_input_list(user, "Choose Belly", "Belly Choice", pred.feedable_bellies())
|
||||
return perform_the_nom(user, prey, pred, belly)
|
||||
|
||||
//
|
||||
// Master vore proc that actually does vore procedures
|
||||
//
|
||||
/mob/living/proc/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay_time)
|
||||
//Sanity
|
||||
if(!user || !prey || !pred || !istype(belly) || !(belly in pred.vore_organs))
|
||||
log_debug("[user] attempted to feed [prey] to [pred], via [belly ? lowertext(belly.name) : "*null*"] but it went wrong.")
|
||||
return FALSE
|
||||
if(pred == prey)
|
||||
return FALSE
|
||||
|
||||
// The belly selected at the time of noms
|
||||
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)"
|
||||
|
||||
//Final distance check. Time has passed, menus have come and gone. Can't use do_after adjacent because doesn't behave for held micros
|
||||
var/user_to_pred = get_dist(get_turf(user),get_turf(pred))
|
||||
var/user_to_prey = get_dist(get_turf(user),get_turf(prey))
|
||||
|
||||
if(user == pred && isAI(user))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
if(AI.holo && AI.holo.masters[AI])
|
||||
user_to_prey = get_dist(get_turf(AI.holo.masters[AI]), get_turf(prey))
|
||||
|
||||
if(user_to_pred > 1 || user_to_prey > 1)
|
||||
return FALSE
|
||||
|
||||
if(!prey.devourable)
|
||||
to_chat(user, span_vnotice("They aren't able to be devoured."))
|
||||
log_and_message_admins("attempted to devour [key_name_admin(prey)] against their prefs ([prey ? ADMIN_JMP(prey) : "null"])", src)
|
||||
return FALSE
|
||||
if(prey.absorbed || pred.absorbed)
|
||||
to_chat(user, span_vwarning("They aren't aren't in a state to be devoured."))
|
||||
return FALSE
|
||||
|
||||
//Determining vore attempt privacy
|
||||
var/message_range = world.view
|
||||
if(!pred.is_slipping && !prey.is_slipping) //We only care about privacy preference if it's NOT a spontaneous vore.
|
||||
switch(belly.eating_privacy_local) //if("loud") case not added, as it would not modify message_range
|
||||
if("default")
|
||||
if(pred.eating_privacy_global)
|
||||
message_range = 1
|
||||
if("subtle")
|
||||
message_range = 1
|
||||
|
||||
// Prepare messages
|
||||
if(prey.is_slipping)
|
||||
attempt_msg = span_vwarning("It seems like [prey] is about to slide into [pred]'s [lowertext(belly.name)]!")
|
||||
success_msg = span_vwarning("[prey] suddenly slides into [pred]'s [lowertext(belly.name)]!")
|
||||
else if(pred.is_slipping)
|
||||
attempt_msg = span_vwarning("It seems like [prey] is gonna end up inside [pred]'s [lowertext(belly.name)] as [pred] comes sliding over!")
|
||||
success_msg = span_vwarning("[prey] suddenly slips inside of [pred]'s [lowertext(belly.name)] as [pred] slides into them!")
|
||||
else if(user == pred) //Feeding someone to yourself
|
||||
attempt_msg = span_vwarning("[pred] is attempting to [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
success_msg = span_vwarning("[pred] manages to [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
else //Feeding someone to another person
|
||||
attempt_msg = span_vwarning("[user] is attempting to make [pred] [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
success_msg = span_vwarning("[user] manages to make [pred] [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
|
||||
// Announce that we start the attempt!
|
||||
|
||||
user.visible_message(attempt_msg, range = message_range)
|
||||
|
||||
// Now give the prey time to escape... return if they did
|
||||
var/swallow_time
|
||||
if(delay_time < 0)
|
||||
swallow_time = 0 //No delay!
|
||||
else if(delay_time)
|
||||
swallow_time = delay_time
|
||||
else
|
||||
swallow_time = ishuman(prey) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
|
||||
|
||||
// Their AI should get notified so they can stab us
|
||||
prey.ai_holder?.react_to_attack(user)
|
||||
|
||||
//Timer and progress bar
|
||||
if(!user.client && prey.weakened > 0) // stop crwaling instantly break swallow attempt for mobvore
|
||||
prey.Stun(min(prey.weakened, 2)) // stop crwaling instantly break swallow attempt for mobvore
|
||||
if(!do_after(user, swallow_time, prey, exclusive = TASK_USER_EXCLUSIVE))
|
||||
return FALSE // Prey escaped (or user disabled) before timer expired.
|
||||
|
||||
// If we got this far, nom successful! Announce it!
|
||||
user.visible_message(success_msg, range = message_range)
|
||||
|
||||
// Actually shove prey into the belly.
|
||||
if(istype(prey.loc, /obj/item/holder))
|
||||
var/obj/item/holder/H = prey.loc
|
||||
for(var/mob/living/M in H.contents)
|
||||
belly.nom_mob(M, user)
|
||||
if(M.loc == H) // In case nom_mob failed somehow.
|
||||
M.forceMove(get_turf(src))
|
||||
H.held_mob = null
|
||||
qdel(H)
|
||||
else
|
||||
belly.nom_mob(prey, user)
|
||||
|
||||
user.update_icon()
|
||||
|
||||
var/mob/living/carbon/victim = prey // Check for afk vore
|
||||
if(istype(victim) && !victim.client && !victim.ai_holder && victim.ckey)
|
||||
log_and_message_admins("ate [key_name_admin(prey)] whilst the prey was AFK ([pred ? ADMIN_JMP(pred) : "null"])", pred)
|
||||
var/mob/living/carbon/victim_pred = pred // Check for afk vore
|
||||
if(istype(victim_pred) && !victim_pred.client && !victim_pred.ai_holder && victim_pred.ckey)
|
||||
log_and_message_admins("ate [key_name_admin(prey)] whilst the pred was AFK ([pred ? ADMIN_JMP(pred) : "null"])", pred)
|
||||
|
||||
// Inform Admins
|
||||
if(pred == user)
|
||||
add_attack_logs(pred, prey, "Eaten via [belly.name]")
|
||||
else
|
||||
add_attack_logs(user, pred, "Forced to eat [key_name(prey)]")
|
||||
return TRUE
|
||||
|
||||
//
|
||||
// Magical pred-air breathing for inside preds
|
||||
// overrides a proc defined on atom called by breathe.dm
|
||||
@@ -869,7 +757,7 @@
|
||||
if(user.is_incorporeal())
|
||||
return FALSE
|
||||
var/belly = user.vore_selected
|
||||
return perform_the_nom(user, prey, user, belly, -1)
|
||||
return begin_instant_nom(user, prey, user, belly)
|
||||
|
||||
/mob/living/proc/glow_toggle()
|
||||
set name = "Glow (Toggle)"
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
belly = vore_selected
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/begin_instant_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
if(vore_active && !voremob_loaded && pred == src) //Only init your own bellies.
|
||||
init_vore(TRUE)
|
||||
belly = vore_selected
|
||||
return ..()
|
||||
//
|
||||
// Simple proc for animals to have their digestion toggled on/off externally
|
||||
// Added as a verb in /mob/living/simple_mob/init_vore() if vore is enabled for this mob.
|
||||
|
||||
@@ -48,12 +48,12 @@
|
||||
var/mob/living/target = AM
|
||||
if(istype(target) && !target.is_incorporeal() && !src.is_incorporeal()) //The slip vore begins
|
||||
if(can_slip_vore(target) && !src.slip_vore_in_progress && !target.slip_vore_in_progress) //If we can vore them go for it
|
||||
perform_the_nom(src,target,src,src.vore_selected,-1)
|
||||
begin_instant_nom(src,target,src,src.vore_selected)
|
||||
target.slip_vore_in_progress = FALSE
|
||||
target.is_slipping = FALSE
|
||||
return
|
||||
else if(can_be_slip_vored_by(target) && !src.slip_vore_in_progress && !target.slip_vore_in_progress) //Otherwise, if they can vore us, make it happen.
|
||||
perform_the_nom(target,src,target,target.vore_selected,-1)
|
||||
begin_instant_nom(target,src,target,target.vore_selected)
|
||||
slip_vore_in_progress = FALSE
|
||||
is_slipping = FALSE
|
||||
return
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
if(CanStumbleVore(M)) //This is if the person stumbling into us is able to eat us!
|
||||
visible_message(span_vwarning("[M] flops carelessly into [src]!"))
|
||||
M.forceMove(get_turf(src))
|
||||
perform_the_nom(src,M,src,src.vore_selected,-1)
|
||||
begin_instant_nom(src,M,src,src.vore_selected)
|
||||
return
|
||||
|
||||
if(M.CanStumbleVore(src)) //This is if the person stumbling into us is able to be eaten by us! BROKEN!
|
||||
visible_message(span_vwarning("[M] flops carelessly into [src]!"))
|
||||
M.forceMove(get_turf(src))
|
||||
perform_the_nom(M,src,M,M.vore_selected,-1)
|
||||
begin_instant_nom(M,src,M,M.vore_selected)
|
||||
return
|
||||
|
||||
if(istype(S) && S.species.lightweight == 1)
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
//Vore procs! Can be delayed or instant.
|
||||
//If delayed, the chain is: perform_the_nom -> begin_delayed_nom -> vore_sanity_checks -> attempt_to_devour_prey -> devour_and_move_prey
|
||||
//If instant, the chain is: perform_the_nom -> begin_instant_nom -> vore_sanity_checks -> devour_and_move_prey
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Vore proc that actually does the main part of eating
|
||||
* Written to be compatible with instant or delayed noms. Alternatively, call begin_instant_nom if the vore is going to be instant.
|
||||
* Params: user, prey, pred, belly, delay_time
|
||||
*/
|
||||
/mob/living/proc/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay_time)
|
||||
if(!delay_time || delay_time > 0)
|
||||
return begin_delayed_nom(user, prey, pred, belly, delay_time)
|
||||
else //This is here to catch when delay_time is set to a negative number, aka, 'we want this to be instant.' Any uses of this should be replaced by begin_instant_nom
|
||||
return begin_instant_nom(user, prey, pred, belly)
|
||||
|
||||
/**
|
||||
* Vore proc that actually does the main part of eating
|
||||
* Params: user, prey, pred, belly, delay_time
|
||||
*/
|
||||
/proc/begin_delayed_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay_time)
|
||||
if(vore_sanity_checks(user, prey, pred, belly))
|
||||
return attempt_to_devour_prey(user, prey, pred, belly, delay_time)
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Vore proc that actually tries to instantly eat the preey
|
||||
* Params: user, prey, pred, belly
|
||||
* NOTE: THIS MUST NOT SLEEP, THIS IS CALLED BY THINGS THAT USE SIGNAL_HANDLER
|
||||
*/
|
||||
/mob/living/proc/begin_instant_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(vore_sanity_checks(user, prey, pred, belly))
|
||||
return devour_and_move_prey(user, prey, pred, belly)
|
||||
else
|
||||
return FALSE //We failed
|
||||
|
||||
/proc/attempt_to_devour_prey(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay_time)
|
||||
var/message_range = get_vore_message_range(user, pred, prey, belly)
|
||||
var/attempt_msg = generate_vore_attempt_message(user, prey, pred, belly)
|
||||
// Announce that we start the attempt!
|
||||
user.visible_message(attempt_msg, range = message_range)
|
||||
// Now give the prey time to escape... return if they did
|
||||
var/swallow_time
|
||||
if(delay_time < 0) //Shouldn't happen, but let's just be sane..
|
||||
swallow_time = 0
|
||||
else if(delay_time)
|
||||
swallow_time = delay_time
|
||||
else
|
||||
swallow_time = ishuman(prey) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
|
||||
|
||||
// Their AI should get notified so they can stab us
|
||||
prey.ai_holder?.react_to_attack(user)
|
||||
|
||||
//Timer and progress bar
|
||||
if(!user.client && prey.weakened > 0) // stop crwaling instantly break swallow attempt for mobvore
|
||||
prey.Stun(min(prey.weakened, 2)) // stop crawling instantly break swallow attempt for mobvore
|
||||
if(!do_after(user, swallow_time, prey, exclusive = TASK_USER_EXCLUSIVE))
|
||||
return FALSE // Prey escaped (or user disabled) before timer expired.
|
||||
|
||||
// If we got this far, nom successful! Announce it and move the prey!
|
||||
return devour_and_move_prey(user, prey, pred, belly, message_range)
|
||||
|
||||
/proc/devour_and_move_prey(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, message_range)
|
||||
var/success_msg = generate_vore_success_message(user, prey, pred, belly)
|
||||
if(!message_range)
|
||||
message_range = get_vore_message_range(user, pred, prey, belly)
|
||||
user.visible_message(success_msg, range = message_range)
|
||||
// Actually shove prey into the belly.
|
||||
if(istype(prey.loc, /obj/item/holder))
|
||||
var/obj/item/holder/H = prey.loc
|
||||
for(var/mob/living/M in H.contents)
|
||||
belly.nom_mob(M, user)
|
||||
if(M.loc == H) // In case nom_mob failed somehow.
|
||||
M.forceMove(get_turf(user))
|
||||
H.held_mob = null
|
||||
qdel(H)
|
||||
else
|
||||
belly.nom_mob(prey, user)
|
||||
|
||||
user.update_icon()
|
||||
|
||||
var/mob/living/carbon/victim = prey // Check for afk vore
|
||||
if(istype(victim) && !victim.client && !victim.ai_holder && victim.ckey)
|
||||
log_and_message_admins("ate [key_name_admin(prey)] whilst the prey was AFK ([pred ? ADMIN_JMP(pred) : "null"])", pred)
|
||||
var/mob/living/carbon/victim_pred = pred // Check for afk vore
|
||||
if(istype(victim_pred) && !victim_pred.client && !victim_pred.ai_holder && victim_pred.ckey)
|
||||
log_and_message_admins("ate [key_name_admin(prey)] whilst the pred was AFK ([pred ? ADMIN_JMP(pred) : "null"])", pred)
|
||||
|
||||
// Inform Admins
|
||||
if(pred == user)
|
||||
add_attack_logs(pred, prey, "Eaten via [belly.name]")
|
||||
else
|
||||
add_attack_logs(user, pred, "Forced to eat [key_name(prey)]")
|
||||
return TRUE
|
||||
|
||||
///VORE HELPER PROCS UNDER HERE
|
||||
|
||||
/**
|
||||
* Vore helper proc that creates the vore success message we'll be using
|
||||
* Params: user, prey, pred, belly, delay_time
|
||||
* Returns: success_msg
|
||||
*/
|
||||
/proc/generate_vore_success_message(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
//Determining vore attempt privacy
|
||||
var/success_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)"
|
||||
|
||||
if(prey.is_slipping)
|
||||
success_msg = span_vwarning("[prey] suddenly slides into [pred]'s [lowertext(belly.name)]!")
|
||||
else if(pred.is_slipping)
|
||||
success_msg = span_vwarning("[prey] suddenly slips inside of [pred]'s [lowertext(belly.name)] as [pred] slides into them!")
|
||||
else if(user == pred) //Feeding someone to yourself
|
||||
success_msg = span_vwarning("[pred] manages to [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
else //Feeding someone to another person
|
||||
success_msg = span_vwarning("[user] manages to make [pred] [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
return success_msg
|
||||
|
||||
/**
|
||||
* Vore proc helper that creates the vore attempt message we'll be using
|
||||
* Params: user, prey, pred, belly, delay_time
|
||||
* Returns: attempt_msg
|
||||
*/
|
||||
/proc/generate_vore_attempt_message(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
//Determining vore attempt privacy
|
||||
var/attempt_msg = "ERROR: Vore message couldn't be created. Notify a dev. (sc)"
|
||||
|
||||
if(prey.is_slipping)
|
||||
attempt_msg = span_vwarning("It seems like [prey] is about to slide into [pred]'s [lowertext(belly.name)]!")
|
||||
else if(pred.is_slipping)
|
||||
attempt_msg = span_vwarning("It seems like [prey] is gonna end up inside [pred]'s [lowertext(belly.name)] as [pred] comes sliding over!")
|
||||
else if(user == pred) //Feeding someone to yourself
|
||||
attempt_msg = span_vwarning("[pred] is attempting to [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
else //Feeding someone to another person
|
||||
attempt_msg = span_vwarning("[user] is attempting to make [pred] [lowertext(belly.vore_verb)] [prey] into their [lowertext(belly.name)]!")
|
||||
return attempt_msg
|
||||
|
||||
/**
|
||||
* Vore proc helper that finds what range our message should be
|
||||
* Params: user, prey, pred, belly, delay_time
|
||||
* Returns: attempt_msg
|
||||
*/
|
||||
/proc/get_vore_message_range(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
var/message_range = world.view
|
||||
if(!pred.is_slipping && !prey.is_slipping) //We only care about privacy preference if it's NOT a spontaneous vore.
|
||||
switch(belly.eating_privacy_local) //if("loud") case not added, as it would not modify message_range
|
||||
if("default")
|
||||
if(pred.eating_privacy_global)
|
||||
message_range = 1
|
||||
if("subtle")
|
||||
message_range = 1
|
||||
return message_range
|
||||
|
||||
/**
|
||||
* Vore proc helper that sees if we can actually do the vore attempt
|
||||
* Params: user, prey, pred, belly
|
||||
* Returns: TRUE/FALSE
|
||||
* FALSE: Can not eat.
|
||||
* TRUE: Can eat.
|
||||
*/
|
||||
/proc/vore_sanity_checks(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly)
|
||||
//Sanity
|
||||
if(!user || !prey || !pred || !istype(belly) || !(belly in pred.vore_organs))
|
||||
log_debug("[user] attempted to feed [prey] to [pred], via [belly ? lowertext(belly.name) : "*null*"] but it went wrong.")
|
||||
return FALSE
|
||||
if(pred == prey)
|
||||
return FALSE
|
||||
|
||||
//Final distance check. Time has passed, menus have come and gone. Can't use do_after adjacent because doesn't behave for held micros
|
||||
var/user_to_pred = get_dist(get_turf(user),get_turf(pred))
|
||||
var/user_to_prey = get_dist(get_turf(user),get_turf(prey))
|
||||
|
||||
if(user == pred && isAI(user))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
if(AI.holo && AI.holo.masters[AI])
|
||||
user_to_prey = get_dist(get_turf(AI.holo.masters[AI]), get_turf(prey))
|
||||
|
||||
if(user_to_pred > 1 || user_to_prey > 1)
|
||||
return FALSE
|
||||
|
||||
if(!prey.devourable)
|
||||
to_chat(user, span_vnotice("They aren't able to be devoured."))
|
||||
log_and_message_admins("attempted to devour [key_name_admin(prey)] against their prefs ([prey ? ADMIN_JMP(prey) : "null"])", user)
|
||||
return FALSE
|
||||
if(prey.absorbed || pred.absorbed)
|
||||
to_chat(user, span_vwarning("They aren't aren't in a state to be devoured."))
|
||||
return FALSE
|
||||
return TRUE
|
||||
Reference in New Issue
Block a user