mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-02-09 15:49:19 +00:00
988 lines
29 KiB
Plaintext
988 lines
29 KiB
Plaintext
//mob verbs are faster than object verbs. See mob/verb/examine.
|
|
/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1))
|
|
set name = "Pull"
|
|
set category = "Object"
|
|
|
|
if(AM.Adjacent(src))
|
|
src.start_pulling(AM)
|
|
|
|
return
|
|
|
|
//mob verbs are faster than object verbs. See above.
|
|
/mob/living/pointed(atom/A as mob|obj|turf in view())
|
|
if(src.stat || !src.canmove || src.restrained())
|
|
return 0
|
|
if(src.status_flags & FAKEDEATH)
|
|
return 0
|
|
if(!..())
|
|
return 0
|
|
|
|
usr.visible_message("<b>[src]</b> points to [A]")
|
|
return 1
|
|
|
|
/*one proc, four uses
|
|
swapping: if it's 1, the mobs are trying to switch, if 0, non-passive is pushing passive
|
|
default behaviour is:
|
|
- non-passive mob passes the passive version
|
|
- passive mob checks to see if its mob_bump_flag is in the non-passive's mob_bump_flags
|
|
- if si, the proc returns
|
|
*/
|
|
/mob/living/proc/can_move_mob(var/mob/living/swapped, swapping = 0, passive = 0)
|
|
if(!swapped)
|
|
return 1
|
|
if(!passive)
|
|
return swapped.can_move_mob(src, swapping, 1)
|
|
else
|
|
var/context_flags = 0
|
|
if(swapping)
|
|
context_flags = swapped.mob_swap_flags
|
|
else
|
|
context_flags = swapped.mob_push_flags
|
|
if(!mob_bump_flag) //nothing defined, go wild
|
|
return 1
|
|
if(mob_bump_flag & context_flags)
|
|
return 1
|
|
return 0
|
|
|
|
/mob/living/Bump(atom/movable/AM, yes)
|
|
spawn(0)
|
|
if ((!( yes ) || now_pushing) || !loc)
|
|
return
|
|
now_pushing = 1
|
|
if (istype(AM, /mob/living))
|
|
var/mob/living/tmob = AM
|
|
|
|
//Even if we don't push/swap places, we "touched" them, so spread fire
|
|
spread_fire(tmob)
|
|
|
|
for(var/mob/living/M in range(tmob, 1))
|
|
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
|
|
if ( !(world.time % 5) )
|
|
src << "<span class='warning'>[tmob] is restrained, you cannot push past</span>"
|
|
now_pushing = 0
|
|
return
|
|
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
|
|
if ( !(world.time % 5) )
|
|
src << "<span class='warning'>[tmob] is restraining [M], you cannot push past</span>"
|
|
now_pushing = 0
|
|
return
|
|
|
|
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
|
|
var/dense = 0
|
|
if(loc.density)
|
|
dense = 1
|
|
for(var/atom/movable/A in loc)
|
|
if(A == src)
|
|
continue
|
|
if(A.density)
|
|
if(A.flags&ON_BORDER)
|
|
dense = !A.CanPass(src, src.loc)
|
|
else
|
|
dense = 1
|
|
if(dense) break
|
|
|
|
//Leaping mobs just land on the tile, no pushing, no anything.
|
|
if(status_flags & LEAPING)
|
|
loc = tmob.loc
|
|
status_flags &= ~LEAPING
|
|
now_pushing = 0
|
|
return
|
|
|
|
if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around!
|
|
var/turf/oldloc = loc
|
|
forceMove(tmob.loc)
|
|
tmob.forceMove(oldloc)
|
|
now_pushing = 0
|
|
return
|
|
|
|
if(!can_move_mob(tmob, 0, 0))
|
|
now_pushing = 0
|
|
return
|
|
if(a_intent == I_HELP || src.restrained())
|
|
now_pushing = 0
|
|
return
|
|
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
|
if(prob(40) && !(FAT in src.mutations))
|
|
src << "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>"
|
|
now_pushing = 0
|
|
return
|
|
if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot))
|
|
if(prob(99))
|
|
now_pushing = 0
|
|
return
|
|
if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot))
|
|
if(prob(99))
|
|
now_pushing = 0
|
|
return
|
|
if(!(tmob.status_flags & CANPUSH))
|
|
now_pushing = 0
|
|
return
|
|
|
|
tmob.LAssailant = src
|
|
|
|
now_pushing = 0
|
|
spawn(0)
|
|
..()
|
|
if (!istype(AM, /atom/movable) || AM.anchored)
|
|
if(confused && prob(50) && m_intent=="run")
|
|
Weaken(2)
|
|
playsound(loc, "punch", 25, 1, -1)
|
|
visible_message("<span class='warning'>[src] [pick("ran", "slammed")] into \the [AM]!</span>")
|
|
src.apply_damage(5, BRUTE)
|
|
src << ("<span class='warning'>You just [pick("ran", "slammed")] into \the [AM]!</span>")
|
|
return
|
|
if (!now_pushing)
|
|
now_pushing = 1
|
|
|
|
var/t = get_dir(src, AM)
|
|
if (istype(AM, /obj/structure/window))
|
|
for(var/obj/structure/window/win in get_step(AM,t))
|
|
now_pushing = 0
|
|
return
|
|
step(AM, t)
|
|
if(ishuman(AM) && AM:grabbed_by)
|
|
for(var/obj/item/weapon/grab/G in AM:grabbed_by)
|
|
step(G:assailant, get_dir(G:assailant, AM))
|
|
G.adjust_position()
|
|
now_pushing = 0
|
|
return
|
|
return
|
|
|
|
/mob/living/verb/succumb()
|
|
set hidden = 1
|
|
if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable
|
|
src.adjustOxyLoss(src.health + src.getMaxHealth() * 2) // Deal 2x health in OxyLoss damage, as before but variable.
|
|
src.health = src.getMaxHealth() - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
|
|
src << "<font color='blue'>You have given up life and succumbed to death.</font>"
|
|
|
|
|
|
/mob/living/proc/updatehealth()
|
|
if(status_flags & GODMODE)
|
|
health = 100
|
|
stat = CONSCIOUS
|
|
else
|
|
health = getMaxHealth() - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss
|
|
|
|
|
|
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
|
|
//affects them once clothing is factored in. ~Errorage
|
|
/mob/living/proc/calculate_affecting_pressure(var/pressure)
|
|
return
|
|
|
|
|
|
//sort of a legacy burn method for /electrocute, /shock, and the e_chair
|
|
/mob/living/proc/burn_skin(burn_amount)
|
|
if(istype(src, /mob/living/carbon/human))
|
|
//world << "DEBUG: burn_skin(), mutations=[mutations]"
|
|
if(mShock in src.mutations) //shockproof
|
|
return 0
|
|
if (COLD_RESISTANCE in src.mutations) //fireproof
|
|
return 0
|
|
var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part
|
|
var/divided_damage = (burn_amount)/(H.organs.len)
|
|
var/extradam = 0 //added to when organ is at max dam
|
|
for(var/obj/item/organ/external/affecting in H.organs)
|
|
if(!affecting) continue
|
|
if(affecting.take_damage(0, divided_damage+extradam)) //TODO: fix the extradam stuff. Or, ebtter yet...rewrite this entire proc ~Carn
|
|
H.UpdateDamageIcon()
|
|
H.updatehealth()
|
|
return 1
|
|
else if(istype(src, /mob/living/silicon/ai))
|
|
return 0
|
|
|
|
/mob/living/proc/adjustBodyTemp(actual, desired, incrementboost)
|
|
var/temperature = actual
|
|
var/difference = abs(actual-desired) //get difference
|
|
var/increments = difference/10 //find how many increments apart they are
|
|
var/change = increments*incrementboost // Get the amount to change by (x per increment)
|
|
|
|
// Too cold
|
|
if(actual < desired)
|
|
temperature += change
|
|
if(actual > desired)
|
|
temperature = desired
|
|
// Too hot
|
|
if(actual > desired)
|
|
temperature -= change
|
|
if(actual < desired)
|
|
temperature = desired
|
|
// if(istype(src, /mob/living/carbon/human))
|
|
// world << "[src] ~ [src.bodytemperature] ~ [temperature]"
|
|
return temperature
|
|
|
|
|
|
// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching.
|
|
// Stop! ... Hammertime! ~Carn
|
|
// I touched them without asking... I'm soooo edgy ~Erro (added nodamage checks)
|
|
|
|
/mob/living/proc/getBruteLoss()
|
|
return bruteloss
|
|
|
|
/mob/living/proc/getShockBruteLoss() //Only checks for things that'll actually hurt (not robolimbs)
|
|
return bruteloss
|
|
|
|
/mob/living/proc/getActualBruteLoss() // Mostly for humans with robolimbs.
|
|
return getBruteLoss()
|
|
|
|
/mob/living/proc/adjustBruteLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_damage_percent))
|
|
amount *= M.incoming_damage_percent
|
|
if(!isnull(M.incoming_brute_damage_percent))
|
|
amount *= M.incoming_brute_damage_percent
|
|
else if(amount < 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_healing_percent))
|
|
amount *= M.incoming_healing_percent
|
|
|
|
bruteloss = min(max(bruteloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/getOxyLoss()
|
|
return oxyloss
|
|
|
|
/mob/living/proc/adjustOxyLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_damage_percent))
|
|
amount *= M.incoming_damage_percent
|
|
if(!isnull(M.incoming_oxy_damage_percent))
|
|
amount *= M.incoming_oxy_damage_percent
|
|
else if(amount < 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_healing_percent))
|
|
amount *= M.incoming_healing_percent
|
|
|
|
oxyloss = min(max(oxyloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/setOxyLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
oxyloss = amount
|
|
|
|
/mob/living/proc/getToxLoss()
|
|
return toxloss
|
|
|
|
/mob/living/proc/adjustToxLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_damage_percent))
|
|
amount *= M.incoming_damage_percent
|
|
if(!isnull(M.incoming_tox_damage_percent))
|
|
amount *= M.incoming_tox_damage_percent
|
|
else if(amount < 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_healing_percent))
|
|
amount *= M.incoming_healing_percent
|
|
|
|
toxloss = min(max(toxloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/setToxLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
toxloss = amount
|
|
|
|
/mob/living/proc/getFireLoss()
|
|
return fireloss
|
|
|
|
/mob/living/proc/getShockFireLoss() //Only checks for things that'll actually hurt (not robolimbs)
|
|
return fireloss
|
|
|
|
/mob/living/proc/getActualFireLoss() // Mostly for humans with robolimbs.
|
|
return getBruteLoss()
|
|
|
|
/mob/living/proc/adjustFireLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_damage_percent))
|
|
amount *= M.incoming_damage_percent
|
|
if(!isnull(M.incoming_fire_damage_percent))
|
|
amount *= M.incoming_fire_damage_percent
|
|
else if(amount < 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_healing_percent))
|
|
amount *= M.incoming_healing_percent
|
|
|
|
fireloss = min(max(fireloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/getCloneLoss()
|
|
return cloneloss
|
|
|
|
/mob/living/proc/adjustCloneLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_damage_percent))
|
|
amount *= M.incoming_damage_percent
|
|
if(!isnull(M.incoming_clone_damage_percent))
|
|
amount *= M.incoming_clone_damage_percent
|
|
else if(amount < 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_healing_percent))
|
|
amount *= M.incoming_healing_percent
|
|
|
|
cloneloss = min(max(cloneloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/setCloneLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
cloneloss = amount
|
|
|
|
/mob/living/proc/getBrainLoss()
|
|
return brainloss
|
|
|
|
/mob/living/proc/adjustBrainLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
brainloss = min(max(brainloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/setBrainLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
brainloss = amount
|
|
|
|
/mob/living/proc/getHalLoss()
|
|
return halloss
|
|
|
|
/mob/living/proc/adjustHalLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_damage_percent))
|
|
amount *= M.incoming_damage_percent
|
|
if(!isnull(M.incoming_hal_damage_percent))
|
|
amount *= M.incoming_hal_damage_percent
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount *= M.incoming_hal_damage_percent
|
|
else if(amount < 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.incoming_healing_percent))
|
|
amount *= M.incoming_healing_percent
|
|
halloss = min(max(halloss + amount, 0),(getMaxHealth()*2))
|
|
|
|
/mob/living/proc/setHalLoss(var/amount)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
halloss = amount
|
|
|
|
// Use this to get a mob's max health whenever possible. Reading maxHealth directly will give inaccurate results if any modifiers exist.
|
|
/mob/living/proc/getMaxHealth()
|
|
var/result = maxHealth
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.max_health_flat))
|
|
result += M.max_health_flat
|
|
// Second loop is so we can get all the flat adjustments first before multiplying, otherwise the result will be different.
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.max_health_percent))
|
|
result *= M.max_health_percent
|
|
return result
|
|
|
|
/mob/living/proc/setMaxHealth(var/newMaxHealth)
|
|
maxHealth = newMaxHealth
|
|
|
|
/mob/living/Stun(amount)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/AdjustStunned(amount)
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/Weaken(amount)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/AdjustWeakened(amount)
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/Paralyse(amount)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/AdjustParalysis(amount)
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/Sleeping(amount)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/AdjustSleeping(amount)
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/Confuse(amount)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/AdjustConfused(amount)
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/Blind(amount)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
/mob/living/AdjustBlinded(amount)
|
|
if(amount > 0)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(!isnull(M.disable_duration_percent))
|
|
amount = round(amount * M.disable_duration_percent)
|
|
..(amount)
|
|
|
|
// ++++ROCKDTBEN++++ MOB PROCS //END
|
|
|
|
/mob/proc/get_contents()
|
|
|
|
|
|
//Recursive function to find everything a mob is holding.
|
|
/mob/living/get_contents(var/obj/item/weapon/storage/Storage = null)
|
|
var/list/L = list()
|
|
|
|
if(Storage) //If it called itself
|
|
L += Storage.return_inv()
|
|
|
|
//Leave this commented out, it will cause storage items to exponentially add duplicate to the list
|
|
//for(var/obj/item/weapon/storage/S in Storage.return_inv()) //Check for storage items
|
|
// L += get_contents(S)
|
|
|
|
for(var/obj/item/weapon/gift/G in Storage.return_inv()) //Check for gift-wrapped items
|
|
L += G.gift
|
|
if(istype(G.gift, /obj/item/weapon/storage))
|
|
L += get_contents(G.gift)
|
|
|
|
for(var/obj/item/smallDelivery/D in Storage.return_inv()) //Check for package wrapped items
|
|
L += D.wrapped
|
|
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
|
|
L += get_contents(D.wrapped)
|
|
return L
|
|
|
|
else
|
|
|
|
L += src.contents
|
|
for(var/obj/item/weapon/storage/S in src.contents) //Check for storage items
|
|
L += get_contents(S)
|
|
|
|
for(var/obj/item/weapon/gift/G in src.contents) //Check for gift-wrapped items
|
|
L += G.gift
|
|
if(istype(G.gift, /obj/item/weapon/storage))
|
|
L += get_contents(G.gift)
|
|
|
|
for(var/obj/item/smallDelivery/D in src.contents) //Check for package wrapped items
|
|
L += D.wrapped
|
|
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
|
|
L += get_contents(D.wrapped)
|
|
return L
|
|
|
|
/mob/living/proc/check_contents_for(A)
|
|
var/list/L = src.get_contents()
|
|
|
|
for(var/obj/B in L)
|
|
if(B.type == A)
|
|
return 1
|
|
return 0
|
|
|
|
|
|
/mob/living/proc/can_inject()
|
|
return 1
|
|
|
|
/mob/living/proc/get_organ_target()
|
|
var/mob/shooter = src
|
|
var/t = shooter:zone_sel.selecting
|
|
if ((t in list( O_EYES, O_MOUTH )))
|
|
t = BP_HEAD
|
|
var/obj/item/organ/external/def_zone = ran_zone(t)
|
|
return def_zone
|
|
|
|
|
|
// heal ONE external organ, organ gets randomly selected from damaged ones.
|
|
/mob/living/proc/heal_organ_damage(var/brute, var/burn)
|
|
adjustBruteLoss(-brute)
|
|
adjustFireLoss(-burn)
|
|
src.updatehealth()
|
|
|
|
// damage ONE external organ, organ gets randomly selected from damaged ones.
|
|
/mob/living/proc/take_organ_damage(var/brute, var/burn, var/emp=0)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
adjustBruteLoss(brute)
|
|
adjustFireLoss(burn)
|
|
src.updatehealth()
|
|
|
|
// heal MANY external organs, in random order
|
|
/mob/living/proc/heal_overall_damage(var/brute, var/burn)
|
|
adjustBruteLoss(-brute)
|
|
adjustFireLoss(-burn)
|
|
src.updatehealth()
|
|
|
|
// damage MANY external organs, in random order
|
|
/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
adjustBruteLoss(brute)
|
|
adjustFireLoss(burn)
|
|
src.updatehealth()
|
|
|
|
/mob/living/proc/restore_all_organs()
|
|
return
|
|
|
|
|
|
|
|
/mob/living/proc/revive()
|
|
rejuvenate()
|
|
if(buckled)
|
|
buckled.unbuckle_mob()
|
|
if(iscarbon(src))
|
|
var/mob/living/carbon/C = src
|
|
|
|
if (C.handcuffed && !initial(C.handcuffed))
|
|
C.drop_from_inventory(C.handcuffed)
|
|
C.handcuffed = initial(C.handcuffed)
|
|
|
|
if (C.legcuffed && !initial(C.legcuffed))
|
|
C.drop_from_inventory(C.legcuffed)
|
|
C.legcuffed = initial(C.legcuffed)
|
|
BITSET(hud_updateflag, HEALTH_HUD)
|
|
BITSET(hud_updateflag, STATUS_HUD)
|
|
BITSET(hud_updateflag, LIFE_HUD)
|
|
ExtinguishMob()
|
|
fire_stacks = 0
|
|
|
|
/mob/living/proc/rejuvenate()
|
|
if(reagents)
|
|
reagents.clear_reagents()
|
|
|
|
// shut down various types of badness
|
|
setToxLoss(0)
|
|
setOxyLoss(0)
|
|
setCloneLoss(0)
|
|
setBrainLoss(0)
|
|
SetParalysis(0)
|
|
SetStunned(0)
|
|
SetWeakened(0)
|
|
|
|
// shut down ongoing problems
|
|
radiation = 0
|
|
nutrition = 400
|
|
bodytemperature = T20C
|
|
sdisabilities = 0
|
|
disabilities = 0
|
|
|
|
// fix blindness and deafness
|
|
blinded = 0
|
|
SetBlinded(0)
|
|
eye_blurry = 0
|
|
ear_deaf = 0
|
|
ear_damage = 0
|
|
heal_overall_damage(getBruteLoss(), getFireLoss())
|
|
|
|
// fix all of our organs
|
|
restore_all_organs()
|
|
|
|
// remove the character from the list of the dead
|
|
if(stat == DEAD)
|
|
dead_mob_list -= src
|
|
living_mob_list += src
|
|
tod = null
|
|
timeofdeath = 0
|
|
|
|
// restore us to conciousness
|
|
stat = CONSCIOUS
|
|
|
|
// make the icons look correct
|
|
regenerate_icons()
|
|
|
|
BITSET(hud_updateflag, HEALTH_HUD)
|
|
BITSET(hud_updateflag, STATUS_HUD)
|
|
BITSET(hud_updateflag, LIFE_HUD)
|
|
|
|
failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
|
|
reload_fullscreen()
|
|
|
|
return
|
|
|
|
/mob/living/proc/UpdateDamageIcon()
|
|
return
|
|
|
|
|
|
/mob/living/proc/Examine_OOC()
|
|
set name = "Examine Meta-Info (OOC)"
|
|
set category = "OOC"
|
|
set src in view()
|
|
|
|
if(config.allow_Metadata)
|
|
if(client)
|
|
usr << "[src]'s Metainfo:<br>[client.prefs.metadata]"
|
|
else
|
|
usr << "[src] does not have any stored infomation!"
|
|
else
|
|
usr << "OOC Metadata is not supported by this server!"
|
|
|
|
return
|
|
|
|
/mob/living/Move(a, b, flag)
|
|
|
|
if (buckled && buckled.loc != a) //not updating position
|
|
if (!buckled.anchored)
|
|
return buckled.Move(a, b)
|
|
else
|
|
return 0
|
|
|
|
if (restrained())
|
|
stop_pulling()
|
|
|
|
|
|
var/t7 = 1
|
|
if (restrained())
|
|
for(var/mob/living/M in range(src, 1))
|
|
if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
|
|
t7 = null
|
|
if ((t7 && (pulling && ((get_dist(src, pulling) <= 1 || pulling.loc == loc) && (client && client.moving)))))
|
|
var/turf/T = loc
|
|
. = ..()
|
|
|
|
if (pulling && pulling.loc)
|
|
if(!( isturf(pulling.loc) ))
|
|
stop_pulling()
|
|
return
|
|
|
|
/////
|
|
if(pulling && pulling.anchored)
|
|
stop_pulling()
|
|
return
|
|
|
|
if (!restrained())
|
|
var/diag = get_dir(src, pulling)
|
|
if ((diag - 1) & diag)
|
|
else
|
|
diag = null
|
|
if ((get_dist(src, pulling) > 1 || diag))
|
|
if (isliving(pulling))
|
|
var/mob/living/M = pulling
|
|
var/atom/movable/t = M.pulling
|
|
M.stop_pulling()
|
|
|
|
if(!istype(M.loc, /turf/space))
|
|
var/area/A = get_area(M)
|
|
if(A.has_gravity)
|
|
//this is the gay blood on floor shit -- Added back -- Skie
|
|
if (M.lying && (prob(M.getBruteLoss() / 6)))
|
|
var/turf/location = M.loc
|
|
if (istype(location, /turf/simulated))
|
|
location.add_blood(M)
|
|
//pull damage with injured people
|
|
if(prob(25))
|
|
M.adjustBruteLoss(1)
|
|
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
|
|
if(M.pull_damage())
|
|
if(prob(25))
|
|
M.adjustBruteLoss(2)
|
|
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
|
|
var/turf/location = M.loc
|
|
if (istype(location, /turf/simulated))
|
|
location.add_blood(M)
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
|
|
if(blood_volume > 0)
|
|
H.vessel.remove_reagent("blood", 1)
|
|
|
|
|
|
step(pulling, get_dir(pulling.loc, T))
|
|
if(t)
|
|
M.start_pulling(t)
|
|
else
|
|
if (pulling)
|
|
if (istype(pulling, /obj/structure/window))
|
|
var/obj/structure/window/W = pulling
|
|
if(W.is_full_window())
|
|
for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T)))
|
|
stop_pulling()
|
|
if (pulling)
|
|
step(pulling, get_dir(pulling.loc, T))
|
|
else
|
|
stop_pulling()
|
|
. = ..()
|
|
|
|
if (s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
|
s_active.close(src)
|
|
|
|
/mob/living/proc/handle_footstep(turf/T)
|
|
return FALSE
|
|
|
|
/mob/living/verb/resist()
|
|
set name = "Resist"
|
|
set category = "IC"
|
|
|
|
if(!incapacitated(INCAPACITATION_KNOCKOUT) && canClick())
|
|
setClickCooldown(20)
|
|
resist_grab()
|
|
if(!weakened)
|
|
process_resist()
|
|
|
|
/mob/living/proc/process_resist()
|
|
//Getting out of someone's inventory.
|
|
if(istype(src.loc, /obj/item/weapon/holder))
|
|
escape_inventory(src.loc)
|
|
return
|
|
|
|
//unbuckling yourself
|
|
if(buckled)
|
|
spawn() escape_buckle()
|
|
return TRUE
|
|
|
|
//Breaking out of a locker?
|
|
if( src.loc && (istype(src.loc, /obj/structure/closet)) )
|
|
var/obj/structure/closet/C = loc
|
|
spawn() C.mob_breakout(src)
|
|
return TRUE
|
|
|
|
/mob/living/proc/escape_inventory(obj/item/weapon/holder/H)
|
|
if(H != src.loc) return
|
|
|
|
var/mob/M = H.loc //Get our mob holder (if any).
|
|
|
|
if(istype(M))
|
|
M.drop_from_inventory(H)
|
|
M << "<span class='warning'>\The [H] wriggles out of your grip!</span>"
|
|
src << "<span class='warning'>You wriggle out of \the [M]'s grip!</span>"
|
|
|
|
// Update whether or not this mob needs to pass emotes to contents.
|
|
for(var/atom/A in M.contents)
|
|
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
|
|
return
|
|
M.status_flags &= ~PASSEMOTES
|
|
|
|
else if(istype(H.loc,/obj/item/clothing/accessory/holster))
|
|
var/obj/item/clothing/accessory/holster/holster = H.loc
|
|
if(holster.holstered == H)
|
|
holster.clear_holster()
|
|
src << "<span class='warning'>You extricate yourself from \the [holster].</span>"
|
|
H.forceMove(get_turf(H))
|
|
else if(istype(H.loc,/obj/item))
|
|
src << "<span class='warning'>You struggle free of \the [H.loc].</span>"
|
|
H.forceMove(get_turf(H))
|
|
|
|
/mob/living/proc/escape_buckle()
|
|
if(buckled)
|
|
buckled.user_unbuckle_mob(src)
|
|
|
|
/mob/living/proc/resist_grab()
|
|
var/resisting = 0
|
|
for(var/obj/item/weapon/grab/G in grabbed_by)
|
|
resisting++
|
|
G.handle_resist()
|
|
if(resisting)
|
|
visible_message("<span class='danger'>[src] resists!</span>")
|
|
|
|
/mob/living/verb/lay_down()
|
|
set name = "Rest"
|
|
set category = "IC"
|
|
|
|
resting = !resting
|
|
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>"
|
|
|
|
/mob/living/proc/cannot_use_vents()
|
|
if(mob_size > MOB_SMALL)
|
|
return "You can't fit into that vent."
|
|
return null
|
|
|
|
/mob/living/proc/has_brain()
|
|
return 1
|
|
|
|
/mob/living/proc/has_eyes()
|
|
return 1
|
|
|
|
/mob/living/proc/slip(var/slipped_on,stun_duration=8)
|
|
return 0
|
|
|
|
/mob/living/carbon/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
|
|
if(W in internal_organs)
|
|
return
|
|
..()
|
|
|
|
/mob/living/touch_map_edge()
|
|
|
|
//check for nuke disks
|
|
if(client && stat != DEAD) //if they are clientless and dead don't bother, the parent will treat them as any other container
|
|
if(ticker && istype(ticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear
|
|
var/datum/game_mode/nuclear/G = ticker.mode
|
|
if(G.check_mob(src))
|
|
if(x <= TRANSITIONEDGE)
|
|
inertia_dir = 4
|
|
else if(x >= world.maxx -TRANSITIONEDGE)
|
|
inertia_dir = 8
|
|
else if(y <= TRANSITIONEDGE)
|
|
inertia_dir = 1
|
|
else if(y >= world.maxy -TRANSITIONEDGE)
|
|
inertia_dir = 2
|
|
src << "<span class='warning'>Something you are carrying is preventing you from leaving.</span>"
|
|
return
|
|
|
|
..()
|
|
|
|
//damage/heal the mob ears and adjust the deaf amount
|
|
/mob/living/adjustEarDamage(var/damage, var/deaf)
|
|
ear_damage = max(0, ear_damage + damage)
|
|
ear_deaf = max(0, ear_deaf + deaf)
|
|
|
|
//pass a negative argument to skip one of the variable
|
|
/mob/living/setEarDamage(var/damage, var/deaf)
|
|
if(damage >= 0)
|
|
ear_damage = damage
|
|
if(deaf >= 0)
|
|
ear_deaf = deaf
|
|
|
|
/mob/living/proc/vomit(var/skip_wait, var/blood_vomit)
|
|
|
|
if(isSynthetic())
|
|
src << "<span class='danger'>A sudden, dizzying wave of internal feedback rushes over you!</span>"
|
|
src.Weaken(5)
|
|
return
|
|
|
|
if(!check_has_mouth())
|
|
return
|
|
|
|
if(!lastpuke)
|
|
lastpuke = 1
|
|
if (nutrition <= 100)
|
|
src << "<span class='danger'>You gag as you want to throw up, but there's nothing in your stomach!</span>"
|
|
src.Weaken(10)
|
|
else
|
|
src << "<span class='warning'>You feel nauseous...</span>"
|
|
|
|
if(!skip_wait)
|
|
sleep(150) //15 seconds until second warning
|
|
src << "<span class='warning'>You feel like you are about to throw up!</span>"
|
|
sleep(100) //and you have 10 more for mad dash to the bucket
|
|
|
|
//Damaged livers cause you to vomit blood.
|
|
if(!blood_vomit)
|
|
if(ishuman(src))
|
|
var/mob/living/carbon/human/H = src
|
|
if(!H.isSynthetic())
|
|
var/obj/item/organ/internal/liver/L = H.internal_organs_by_name["liver"]
|
|
if(L.is_broken())
|
|
blood_vomit = 1
|
|
|
|
Stun(5)
|
|
src.visible_message("<span class='warning'>[src] throws up!</span>","<span class='warning'>You throw up!</span>")
|
|
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
|
|
|
var/turf/simulated/T = get_turf(src) //TODO: Make add_blood_floor remove blood from human mobs
|
|
if(istype(T))
|
|
if(blood_vomit)
|
|
T.add_blood_floor(src)
|
|
else
|
|
T.add_vomit_floor(src, 1)
|
|
|
|
if(blood_vomit)
|
|
if(getBruteLoss() < 50)
|
|
adjustBruteLoss(3)
|
|
else
|
|
nutrition -= 40
|
|
adjustToxLoss(-3)
|
|
|
|
sleep(350)
|
|
lastpuke = 0
|
|
|
|
/mob/living/update_canmove()
|
|
if(!resting && cannot_stand() && can_stand_overridden())
|
|
lying = 0
|
|
canmove = 1
|
|
else
|
|
if(istype(buckled, /obj/vehicle))
|
|
var/obj/vehicle/V = buckled
|
|
if(is_physically_disabled())
|
|
lying = 0
|
|
canmove = 1
|
|
pixel_y = V.mob_offset_y - 5
|
|
else
|
|
if(buckled.buckle_lying != -1) lying = buckled.buckle_lying
|
|
canmove = 1
|
|
pixel_y = V.mob_offset_y
|
|
else if(buckled)
|
|
anchored = 1
|
|
canmove = 0
|
|
if(istype(buckled))
|
|
if(buckled.buckle_lying != -1)
|
|
lying = buckled.buckle_lying
|
|
if(buckled.buckle_movable)
|
|
anchored = 0
|
|
canmove = 1
|
|
else
|
|
lying = incapacitated(INCAPACITATION_KNOCKDOWN)
|
|
canmove = !incapacitated(INCAPACITATION_DISABLED)
|
|
|
|
if(lying)
|
|
density = 0
|
|
if(l_hand) unEquip(l_hand)
|
|
if(r_hand) unEquip(r_hand)
|
|
update_water() // Submerges the mob.
|
|
else
|
|
density = initial(density)
|
|
|
|
for(var/obj/item/weapon/grab/G in grabbed_by)
|
|
if(G.state >= GRAB_AGGRESSIVE)
|
|
canmove = 0
|
|
break
|
|
|
|
//Temporarily moved here from the various life() procs
|
|
//I'm fixing stuff incrementally so this will likely find a better home.
|
|
//It just makes sense for now. ~Carn
|
|
if( update_icon ) //forces a full overlay update
|
|
update_icon = 0
|
|
regenerate_icons()
|
|
else if( lying != lying_prev )
|
|
update_icons()
|
|
return canmove
|
|
|
|
// Adds overlays for specific modifiers.
|
|
// You'll have to add your own implementation for non-humans currently, just override this proc.
|
|
/mob/living/proc/update_modifier_visuals()
|
|
return
|
|
|
|
/mob/living/proc/update_water() // Involves overlays for humans. Maybe we'll get submerged sprites for borgs in the future?
|
|
return
|
|
|
|
/mob/living/proc/can_feel_pain(var/check_organ)
|
|
if(isSynthetic())
|
|
return FALSE
|
|
return TRUE
|
|
|
|
// Gets the correct icon_state for being on fire. See OnFire.dmi for the icons.
|
|
/mob/living/proc/get_fire_icon_state()
|
|
return "generic"
|
|
|
|
// Called by job_controller.
|
|
/mob/living/proc/equip_post_job()
|
|
return
|