12/21 modernizations from TG live (#103)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes
This commit is contained in:
Poojawa
2016-12-22 03:57:55 -06:00
committed by GitHub
parent f5e143a452
commit cf59ac1c3d
2215 changed files with 707445 additions and 87041 deletions
+12 -53
View File
@@ -7,10 +7,10 @@
name = "alien"
voice_name = "alien"
icon = 'icons/mob/alien.dmi'
gender = FEMALE
gender = FEMALE //All xenos are girls!!
dna = null
faction = list("alien")
ventcrawler = 2
ventcrawler = VENTCRAWLER_ALWAYS
languages_spoken = ALIEN
languages_understood = ALIEN
sight = SEE_MOBS
@@ -19,7 +19,6 @@
bubble_icon = "alien"
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
var/nightvision = 1
var/deathNotified = 0
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = 0
@@ -38,35 +37,22 @@
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
internal_organs += new /obj/item/organ/brain/alien
internal_organs += new /obj/item/organ/alien/hivenode
internal_organs += new /obj/item/organ/tongue/alien
create_bodyparts() //initialize bodyparts
for(var/obj/item/organ/I in internal_organs)
I.Insert(src)
create_internal_organs()
AddAbility(new/obj/effect/proc_holder/alien/nightvisiontoggle(null))
..()
/mob/living/carbon/alien/create_internal_organs()
internal_organs += new /obj/item/organ/brain/alien
internal_organs += new /obj/item/organ/alien/hivenode
internal_organs += new /obj/item/organ/tongue/alien
..()
/mob/living/carbon/alien/assess_threat() // beepsky won't hunt aliums
return -10
/mob/living/carbon/alien/adjustToxLoss(amount)
return 0
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
if(amount > 0)
..(amount * 2)
else
..(amount)
return
/mob/living/carbon/alien/check_eye_prot()
return ..() + 2
/mob/living/carbon/alien/getToxLoss()
return 0
/mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment)
if(!environment)
return
@@ -101,35 +87,6 @@
else
clear_alert("alien_fire")
/mob/living/carbon/alien/ex_act(severity, target)
..()
switch (severity)
if (1)
gib()
return
if (2)
adjustBruteLoss(60)
adjustFireLoss(60)
adjustEarDamage(30,120)
if(3)
adjustBruteLoss(30)
if (prob(50))
Paralyse(1)
adjustEarDamage(15,60)
updatehealth()
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
if(..())
return
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
return
/mob/living/carbon/alien/reagent_check(datum/reagent/R) //can metabolize all reagents
return 0
@@ -229,3 +186,5 @@ Des: Removes all infected images from the alien.
if(see_override)
see_invisible = see_override
/mob/living/carbon/alien/can_hold_items()
return has_fine_manipulation
@@ -1,3 +1,10 @@
/mob/living/carbon/alien/get_eye_protection()
return ..() + 2 //potential cyber implants + natural eye protection
/mob/living/carbon/alien/get_ear_protection()
return 2 //no ears
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush)
..(AM, skipcatch = 1, hitpush = 0)
@@ -7,11 +14,7 @@ As such, they can either help or harm other aliens. Help works like the human he
In all, this is a lot like the monkey code. /N
*/
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
if(isturf(loc) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
@@ -23,24 +26,22 @@ In all, this is a lot like the monkey code. /N
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake it up!</span>")
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
if ("grab")
grabbedby(M)
else
if (health > 0)
M.do_attack_animation(src)
if(health > 0)
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
var/damage = 1
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
"<span class='userdanger'>[M.name] bites [src]!</span>")
adjustBruteLoss(damage)
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
adjustBruteLoss(1)
add_logs(M, src, "attacked")
updatehealth()
else
M << "<span class='warning'>[name] is too injured for that.</span>"
return
/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L)
@@ -56,8 +57,11 @@ In all, this is a lot like the monkey code. /N
help_shake_act(M)
if("grab")
grabbedby(M)
if ("harm", "disarm")
M.do_attack_animation(src)
if ("harm")
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
return 1
if("disarm")
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return 1
return 0
@@ -65,9 +69,8 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M)
if(..())
if (stat != DEAD)
adjustBruteLoss(rand(1, 3))
updatehealth()
return
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(rand(1, 3), BRUTE, affecting)
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
@@ -96,3 +99,28 @@ In all, this is a lot like the monkey code. /N
adjustBruteLoss(damage)
add_logs(M, src, "attacked")
updatehealth()
/mob/living/carbon/alien/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
return
..()
switch (severity)
if (1)
gib()
return
if (2)
take_overall_damage(60, 60)
adjustEarDamage(30,120)
if(3)
take_overall_damage(30,0)
if(prob(50))
Paralyse(1)
adjustEarDamage(15,60)
/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
return 0
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
return 0//aliens are immune to acid.
@@ -0,0 +1,22 @@
/mob/living/carbon/alien/getToxLoss()
return 0
/mob/living/carbon/alien/adjustToxLoss(amount) //alien immune to tox damage
return 0
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
if(amount > 0)
..(amount * 2)
else
..(amount)
//aliens are immune to stamina damage.
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_stamina = 1)
return
/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1)
return
+5 -16
View File
@@ -1,5 +1,8 @@
/mob/living/carbon/alien/spawn_gibs()
xgibs(loc, viruses)
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
if(with_bodyparts)
new /obj/effect/gibspawner/xeno(loc,viruses)
else
new /obj/effect/gibspawner/xenobodypartless(loc,viruses)
/mob/living/carbon/alien/gib_animation()
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-a"))
@@ -9,17 +12,3 @@
/mob/living/carbon/alien/dust_animation()
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-a"))
/mob/living/carbon/alien/proc/deathNotice(var/area/AR, var/turf/T)
if(src.z == 2) //Admin fuckery can continue without giving false death rattles to aliens on station or elsewhere.
return
src.deathNotified = 1
T = get_turf(src)
var/mob/living/carbon/alien/A
for(A in world)
A << "<span class='userdanger'>[src.name] has died at [T.loc.name]! </span>"
/mob/living/carbon/alien/death(gibbed)
if(!deathNotified)
deathNotice()
..()
@@ -11,7 +11,6 @@ Doesn't work on other aliens/AI.*/
panel = "Alien"
var/plasma_cost = 0
var/check_turf = 0
var/has_action = 1
var/datum/action/spell_action/alien/action = null
var/action_icon = 'icons/mob/actions.dmi'
@@ -49,7 +48,7 @@ Doesn't work on other aliens/AI.*/
if(!silent)
user << "<span class='noticealien'>Not enough plasma stored.</span>"
return 0
if(check_turf && (!isturf(user.loc) || istype(user.loc, /turf/open/space)))
if(check_turf && (!isturf(user.loc) || isspaceturf(user.loc)))
if(!silent)
user << "<span class='noticealien'>Bad place for a garden!</span>"
return 0
@@ -141,30 +140,16 @@ Doesn't work on other aliens/AI.*/
/obj/effect/proc_holder/alien/acid/on_lose(mob/living/carbon/user)
user.verbs.Remove(/mob/living/carbon/proc/corrosive_acid)
/obj/effect/proc_holder/alien/acid/proc/corrode(target,mob/living/carbon/user = usr)
/obj/effect/proc_holder/alien/acid/proc/corrode(atom/target,mob/living/carbon/user = usr)
if(target in oview(1,user))
// OBJ CHECK
if(isobj(target))
var/obj/I = target
if(I.unacidable) //So the aliens don't destroy energy fields/singularies/other aliens/etc with their acid.
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
return 0
// TURF CHECK
else if(istype(target, /turf))
var/turf/T = target
// R WALL
if(istype(T, /turf/closed/wall/r_wall))
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
return 0
// R FLOOR
if(istype(T, /turf/open/floor/engine))
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
return 0
else// Not a type we can acid.
if(target.acid_act(200, 100))
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
return 1
else
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
return 0
new /obj/effect/acid(get_turf(target), target)
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
return 1
else
src << "<span class='noticealien'>Target is too far away.</span>"
return 0
@@ -172,8 +157,10 @@ Doesn't work on other aliens/AI.*/
/obj/effect/proc_holder/alien/acid/fire(mob/living/carbon/alien/user)
var/O = input("Select what to dissolve:","Dissolve",null) as obj|turf in oview(1,user)
if(!O) return 0
return corrode(O,user)
if(!O || user.incapacitated())
return 0
else
return corrode(O,user)
/mob/living/carbon/proc/corrosive_acid(O as obj|turf in oview(1)) // right click menu verb ugh
set name = "Corrossive Acid"
@@ -191,39 +178,40 @@ Doesn't work on other aliens/AI.*/
name = "Spit Neurotoxin"
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
action_icon_state = "alien_neurotoxin_0"
var/active = 0
active = FALSE
/obj/effect/proc_holder/alien/neurotoxin/fire(mob/living/carbon/user)
var/message
if(active)
user.ranged_ability = null
user << "<span class='notice'>You empty your neurotoxin gland.</span>"
active = 0
else if(user.ranged_ability && user.ranged_ability != src)
user << "<span class='warning'>You already have another aimed ability readied! Cancel it first."
return
message = "<span class='notice'>You empty your neurotoxin gland.</span>"
remove_ranged_ability(message)
else
user.ranged_ability = src
active = 1
user << "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
message = "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
add_ranged_ability(user, message, TRUE)
user.client.click_intercept = user.ranged_ability
/obj/effect/proc_holder/alien/neurotoxin/update_icon()
action.button_icon_state = "alien_neurotoxin_[active]"
action.UpdateButtonIcon()
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/carbon/user, params, atom/target)
var/p_cost = 50
if(!iscarbon(user) || user.lying || user.stat)
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/caller, params, atom/target)
if(..())
return
user.next_click = world.time + 6
user.face_atom(target)
var/p_cost = 50
if(!iscarbon(ranged_ability_user) || ranged_ability_user.lying || ranged_ability_user.stat)
remove_ranged_ability(ranged_ability_user)
return
var/mob/living/carbon/user = ranged_ability_user
if(user.getPlasma() < p_cost)
user << "<span class='warning'>You need at least [p_cost] plasma to spit.</span>"
remove_ranged_ability()
return
var/turf/T = user.loc
var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction
if(!isturf(U) || !isturf(T))
return 0
return FALSE
user.visible_message("<span class='danger'>[user] spits neurotoxin!", "<span class='alertalien'>You spit neurotoxin.</span>")
var/obj/item/projectile/bullet/neurotoxin/A = new /obj/item/projectile/bullet/neurotoxin(user.loc)
@@ -233,12 +221,25 @@ Doesn't work on other aliens/AI.*/
user.newtonian_move(get_dir(U, T))
user.adjustPlasma(-p_cost)
return 1
return TRUE
/obj/effect/proc_holder/alien/neurotoxin/on_lose(mob/living/carbon/user)
if(user.ranged_ability == src)
user.ranged_ability = null
/obj/effect/proc_holder/alien/neurotoxin/add_ranged_ability(mob/living/user, msg)
..()
if(isalienadult(user))
var/mob/living/carbon/alien/humanoid/A = user
A.drooling = 1
A.update_icons()
/obj/effect/proc_holder/alien/neurotoxin/remove_ranged_ability(mob/living/user, msg)
..()
if(isalienadult(user))
var/mob/living/carbon/alien/humanoid/A = user
A.drooling = 0
A.update_icons()
/obj/effect/proc_holder/alien/resin
name = "Secrete Resin"
@@ -308,7 +309,7 @@ Doesn't work on other aliens/AI.*/
/obj/effect/proc_holder/alien/sneak
name = "Sneak"
desc = "Blend into the shadows to stalk your prey."
var/active = 0
active = 0
action_icon_state = "alien_sneak"
@@ -7,11 +7,14 @@
/mob/living/carbon/alien/humanoid/drone/New()
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
..()
/mob/living/carbon/alien/humanoid/drone/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/large
internal_organs += new /obj/item/organ/alien/resinspinner
internal_organs += new /obj/item/organ/alien/acid
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
..()
/mob/living/carbon/alien/humanoid/drone/movement_delay()
@@ -36,7 +39,7 @@
if(!isturf(user.loc))
user << "<span class='notice'>You can't evolve here!</span>"
return 0
if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal))
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal))
var/mob/living/carbon/alien/humanoid/royal/praetorian/new_xeno = new (user.loc)
user.alien_evolve(new_xeno)
return 1
@@ -6,7 +6,7 @@
icon_state = "alienh_s"
var/obj/screen/leap_icon = null
/mob/living/carbon/alien/humanoid/hunter/New()
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/small
..()
@@ -45,16 +45,18 @@
if(leaping || stat || buckled || lying)
return
if(!has_gravity(src) || !has_gravity(A))
if(!has_gravity() || !A.has_gravity())
src << "<span class='alertalien'>It is unsafe to leap without gravity!</span>"
//It's also extremely buggy visually, so it's balance+bugfix
return
else //Maybe uses plasma in the future, although that wouldn't make any sense...
leaping = 1
weather_immunities += "lava"
update_icons()
throw_at(A,MAX_ALIEN_LEAP_DIST,1, spin=0, diagonals_first = 1)
leaping = 0
weather_immunities -= "lava"
update_icons()
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
@@ -63,18 +65,20 @@
return ..()
if(A)
if(istype(A, /mob/living))
if(isliving(A))
var/mob/living/L = A
var/blocked = 0
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(H.check_shields(90, "the [name]", src, attack_type = THROWN_PROJECTILE_ATTACK))
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
blocked = 1
if(!blocked)
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.Weaken(5)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
else
Weaken(2, 1, 1)
toggle_leap(0)
pounce_cooldown = !pounce_cooldown
@@ -82,7 +86,7 @@
pounce_cooldown = !pounce_cooldown
else if(A.density && !A.CanPass(src))
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
weakened = 2
Weaken(2, 1, 1)
if(leaping)
leaping = 0
@@ -11,14 +11,18 @@
real_name = name
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
..()
/mob/living/carbon/alien/humanoid/royal/praetorian/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/large
internal_organs += new /obj/item/organ/alien/resinspinner
internal_organs += new /obj/item/organ/alien/acid
internal_organs += new /obj/item/organ/alien/neurotoxin
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
..()
/mob/living/carbon/alien/humanoid/royal/praetorian/movement_delay()
. = ..()
. += 1
@@ -38,7 +42,7 @@
if(node.recent_queen_death)
user << "<span class='danger'>You are still too burdened with guilt to evolve into a queen.</span>"
return 0
if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal/queen))
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen))
var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
user.alien_evolve(new_xeno)
if(new_xeno.client.prefs.unlock_content)
@@ -7,11 +7,15 @@
/mob/living/carbon/alien/humanoid/sentinel/New()
internal_organs += new /obj/item/organ/alien/plasmavessel
internal_organs += new /obj/item/organ/alien/acid
internal_organs += new /obj/item/organ/alien/neurotoxin
AddAbility(new /obj/effect/proc_holder/alien/sneak)
..()
/mob/living/carbon/alien/humanoid/sentinel/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel
internal_organs += new /obj/item/organ/alien/acid
internal_organs += new /obj/item/organ/alien/neurotoxin
..()
/mob/living/carbon/alien/humanoid/sentinel/movement_delay()
. = ..()
@@ -1,10 +1,8 @@
/mob/living/carbon/alien/humanoid/death(gibbed)
if(stat == DEAD)
return
stat = DEAD
if(!deathNotified) //Did we message the other aliens that we died?
deathNotice() //If not, do so now. This proc will change the deathNotified var to 1 so it never happens again.
stat = DEAD
if(!gibbed)
playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
@@ -12,11 +10,6 @@
update_canmove()
update_icons()
status_flags |= CANPUSH
if(fireloss >= (maxHealth/2))
spawn(10)
visible_message("<span class='warning'>[src] starts shaking...</span>")
spawn(30)
src.gib()
return ..()
@@ -32,20 +25,4 @@
if(istype(node)) // just in case someone would ever add a diffirent node to hivenode slot
node.queen_death()
return ..(gibbed)
/mob/living/carbon/alien/humanoid/gib()
visible_message("<span class='danger'>[src] explodes in a shower of acid blood and gibs!</span>")
for(var/mob/living/M in viewers(2, src))
if(ishuman(M))
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
M.adjustFireLoss(15)
M.reagents.add_reagent("xblood",5)
else if(ismonkey(M))
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
M.adjustFireLoss(15)
M.reagents.add_reagent("xblood",5)
else if(!isalien(M))
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
M.adjustFireLoss(15)
..()
return ..(gibbed)
@@ -3,6 +3,7 @@
icon_state = "alien_s"
pass_flags = PASSTABLE
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
limb_destroyer = 1
var/obj/item/r_store = null
var/obj/item/l_store = null
var/caste = ""
@@ -13,89 +14,35 @@
var/custom_pixel_x_offset = 0 //for admin fuckery.
var/custom_pixel_y_offset = 0
var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
var/drooling = 0 //For Neruotoxic spit overlays
bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
/obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/humanoid/New()
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
..()
/mob/living/carbon/alien/humanoid/movement_delay()
. = ..()
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stuns
/mob/living/carbon/alien/humanoid/emp_act(severity)
if(r_store) r_store.emp_act(severity)
if(l_store) l_store.emp_act(severity)
..()
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user)
if(user.a_intent == "harm")
..(user, 1)
adjustBruteLoss(15)
var/hitverb = "punched"
if(mob_size < MOB_SIZE_LARGE)
Paralyse(1)
step_away(src,user,15)
sleep(1)
step_away(src,user,15)
hitverb = "slammed"
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
"<span class='userdanger'>[user] has [hitverb] [src]!</span>")
return 1
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
if(..())
switch(M.a_intent)
if ("harm")
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>")
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
Paralyse(2)
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>")
adjustBruteLoss(damage)
add_logs(M, src, "attacked")
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
if ("disarm")
if (!lying)
if (prob(5))
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
else
if (prob(50))
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>")
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
. = handcuffed
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
user.set_machine(src)
var/dat = {"
var/list/dat = list()
dat += {"
<HR>
<B><FONT size=3>[name]</FONT></B>
<HR>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [l_hand ? l_hand : "Nothing"]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [r_hand ? r_hand : "Nothing"]</A>
<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"}
<HR>"}
for(var/i in 1 to held_items.len)
var/obj/item/I = get_item_for_held_index(i)
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a>"
dat += "<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"
if(handcuffed)
dat += "<BR><A href='?src=\ref[src];item=[slot_handcuffed]'>Handcuffed</A>"
@@ -106,7 +53,7 @@
<BR>
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
"}
user << browse(dat, "window=mob\ref[src];size=325x500")
user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
onclose(user, "mob\ref[src]")
@@ -147,39 +94,29 @@
else
return initial(pixel_x)
/mob/living/carbon/alien/humanoid/check_ear_prot()
return 1
/mob/living/carbon/alien/humanoid/get_permeability_protection()
return 0.8
/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
drop_l_hand()
drop_r_hand()
drop_all_held_items()
for(var/atom/movable/A in stomach_contents)
stomach_contents.Remove(A)
new_xeno.stomach_contents.Add(A)
A.loc = new_xeno
..()
//For alien evolution/promotion procs. Checks for
proc/alien_type_present(var/alienpath)
//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
/proc/get_alien_type(var/alienpath)
for(var/mob/living/carbon/alien/humanoid/A in living_mob_list)
if(!istype(A, alienpath))
continue
if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
continue
return 1
return 0
return A
return FALSE
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
if(breath && breath.total_moles() > 0 && !sneaking)
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
..()
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
devour_mob(pulling, devour_time = 60)
else
..()
@@ -0,0 +1,68 @@
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
devour_mob(pulling, devour_time = 60)
else
..()
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
..(user, 1)
adjustBruteLoss(15)
var/hitverb = "punched"
if(mob_size < MOB_SIZE_LARGE)
step_away(src,user,15)
sleep(1)
step_away(src,user,15)
hitverb = "slammed"
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
"<span class='userdanger'>[user] has [hitverb] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 1
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
if(..())
switch(M.a_intent)
if ("harm")
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
Paralyse(2)
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
add_logs(M, src, "attacked")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='userdanger'>[M] has attempted to punch [src]!</span>", \
"<span class='userdanger'>[M] has attempted to punch [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ("disarm")
if (!lying)
if (prob(5))
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
else
if (prob(50))
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='userdanger'>[M] has attempted to disarm [src]!</span>",\
"<span class='userdanger'>[M] has attempted to disarm [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_CLAW
..()
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
@@ -2,7 +2,7 @@
//Common stuffs for Praetorian and Queen
icon = 'icons/mob/alienqueen.dmi'
status_flags = 0
ventcrawler = 0 //pull over that ass too fat
ventcrawler = VENTCRAWLER_NONE //pull over that ass too fat
unique_name = 0
pixel_x = -16
bubble_icon = "alienroyal"
@@ -22,7 +22,27 @@
maxHealth = 400
health = 400
icon_state = "alienq"
var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite()
/datum/action/small_sprite
name = "Toggle Giant Sprite - Others will always see you as giant"
button_icon_state = "smallqueen"
background_icon_state = "bg_alien"
var/small = 0
/datum/action/small_sprite/Trigger()
..()
if(!small)
var/image/I = image(icon = 'icons/mob/alien.dmi' , icon_state = "alienq_running", loc = owner)
I.override = 1
I.pixel_x -= owner.pixel_x
I.pixel_y -= owner.pixel_y
owner.add_alt_appearance("smallqueen", I, list(owner))
small = 1
else
owner.remove_alt_appearance("smallqueen")
small = 0
/mob/living/carbon/alien/humanoid/royal/queen/New()
//there should only be one queen
@@ -37,18 +57,22 @@
real_name = src.name
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
smallsprite.Grant(src)
..()
/mob/living/carbon/alien/humanoid/royal/queen/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen
internal_organs += new /obj/item/organ/alien/resinspinner
internal_organs += new /obj/item/organ/alien/acid
internal_organs += new /obj/item/organ/alien/neurotoxin
internal_organs += new /obj/item/organ/alien/eggsac
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
..()
/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
. = ..()
. += 5
. += 3
//Queen verbs
/obj/effect/proc_holder/alien/lay_egg
@@ -78,7 +102,7 @@
/obj/effect/proc_holder/alien/royal/queen/promote/fire(mob/living/carbon/alien/user)
var/obj/item/queenpromote/prom
if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
user << "<span class='noticealien'>You already have a Praetorian!</span>"
return 0
else
@@ -99,14 +123,14 @@
name = "\improper royal parasite"
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
icon_state = "alien_medal"
flags = ABSTRACT|NODROP
flags = ABSTRACT|NODROP|DROPDEL
icon = 'icons/mob/alien.dmi'
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
if(!isalienadult(M) || istype(M, /mob/living/carbon/alien/humanoid/royal))
user << "<span class='noticealien'>You may only use this with your adult, non-royal children!</span>"
return
if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
user << "<span class='noticealien'>You already have a Praetorian!</span>"
return
@@ -161,4 +185,4 @@
desc = ""
icon_state = "alienq"
caste = "q"
update_icons()
update_icons()
@@ -20,8 +20,12 @@
icon_state = "alien[caste]_sleep"
else if(mob_size == MOB_SIZE_LARGE)
icon_state = "alien[caste]"
if(drooling)
add_overlay("alienspit_[caste]")
else
icon_state = "alien[caste]_s"
if(drooling)
add_overlay("alienspit_s")
if(leaping)
if(alt_icon == initial(alt_icon))
@@ -50,28 +54,40 @@
..()
update_icons()
/mob/living/carbon/alien/humanoid/update_inv_handcuffed()
remove_overlay(HANDCUFF_LAYER)
var/cuff_icon = "aliencuff_s"
var/dmi_file = 'icons/mob/alien.dmi'
if(mob_size == MOB_SIZE_LARGE)
cuff_icon = "aliencuff_[caste]"
dmi_file = 'icons/mob/alienqueen.dmi'
if(handcuffed)
overlays_standing[HANDCUFF_LAYER] = image(dmi_file,icon_state= cuff_icon, layer =-HANDCUFF_LAYER)
apply_overlay(HANDCUFF_LAYER)
//Royals have bigger sprites, so inhand things must be handled differently.
/mob/living/carbon/alien/humanoid/royal/update_inv_r_hand()
/mob/living/carbon/alien/humanoid/royal/update_inv_hands()
..()
remove_overlay(R_HAND_LAYER)
if(r_hand)
var/itm_state = r_hand.item_state
if(!itm_state)
itm_state = r_hand.icon_state
remove_overlay(HANDS_LAYER)
var/list/hands = list()
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-R_HAND_LAYER)
overlays_standing[R_HAND_LAYER] = I
apply_overlay(R_HAND_LAYER)
/mob/living/carbon/alien/humanoid/royal/update_inv_l_hand()
..()
remove_overlay(L_HAND_LAYER)
var/obj/item/l_hand = get_item_for_held_index(1)
if(l_hand)
var/itm_state = l_hand.item_state
if(!itm_state)
itm_state = l_hand.icon_state
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-HANDS_LAYER)
hands += I
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-L_HAND_LAYER)
overlays_standing[L_HAND_LAYER] = I
apply_overlay(L_HAND_LAYER)
var/obj/item/r_hand = get_item_for_held_index(2)
if(r_hand)
var/itm_state = r_hand.item_state
if(!itm_state)
itm_state = r_hand.icon_state
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-HANDS_LAYER)
hands += I
overlays_standing[HANDS_LAYER] = hands
apply_overlay(HANDS_LAYER)
@@ -8,3 +8,18 @@
visible_message("<span class='name'>[src]</span> lets out a waning high-pitched cry.")
return ..(gibbed)
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
if(with_bodyparts)
new /obj/effect/gibspawner/larva(loc,viruses)
else
new /obj/effect/gibspawner/larvabodypartless(loc,viruses)
/mob/living/carbon/alien/larva/gib_animation()
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-l"))
/mob/living/carbon/alien/larva/spawn_dust()
new /obj/effect/decal/remains/xeno(loc)
/mob/living/carbon/alien/larva/dust_animation()
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-l"))
@@ -14,16 +14,20 @@
var/time_of_birth
rotate_on_lying = 0
bodyparts = list(/obj/item/bodypart/chest/larva, /obj/item/bodypart/head/larva)
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/New()
regenerate_icons()
internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny
AddAbility(new/obj/effect/proc_holder/alien/hide(null))
AddAbility(new/obj/effect/proc_holder/alien/larva_evolve(null))
..()
/mob/living/carbon/alien/larva/create_internal_organs()
internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny
..()
//This needs to be fixed
/mob/living/carbon/alien/larva/Stat()
..()
@@ -39,37 +43,6 @@
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user)
if(user.a_intent == "harm")
..(user, 1)
adjustBruteLoss(5 + rand(1,9))
Paralyse(1)
spawn()
step_away(src,user,15)
sleep(1)
step_away(src,user,15)
return 1
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
if(..())
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
add_logs(M, src, "attacked")
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>")
if ((stat != DEAD) && (damage > 4.9))
Paralyse(rand(5,10))
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
"<span class='userdanger'>[M] has attempted to kick [src]!</span>")
return
/mob/living/carbon/alien/larva/restrained(ignore_grab)
. = 0
@@ -0,0 +1,34 @@
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
if(..())
var/damage = rand(1, 9)
if (prob(90))
playsound(loc, "punch", 25, 1, -1)
add_logs(M, src, "attacked")
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
if ((stat != DEAD) && (damage > 4.9))
Paralyse(rand(5,10))
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
apply_damage(damage, BRUTE, affecting)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
"<span class='userdanger'>[M] has attempted to kick [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
..(user, 1)
adjustBruteLoss(5 + rand(1,9))
spawn()
step_away(src,user,15)
sleep(1)
step_away(src,user,15)
return 1
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_BITE
..()
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/alien/larva/Life()
set invisibility = 0
@@ -6,7 +6,7 @@
if (notransform)
return
if(..())
if(..()) //not dead
// GROW!
if(amount_grown < max_grown)
amount_grown++
@@ -20,7 +20,7 @@
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
death()
return
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
@@ -5,7 +5,7 @@
/mob/living/carbon/alien/larva/update_icons()
var/state = 0
if(amount_grown > 150)
if(amount_grown > 80)
state = 2
else if(amount_grown > 50)
state = 1
@@ -1,3 +1,6 @@
/mob/living/carbon/alien/Life()
findQueen()
return..()
/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
@@ -42,4 +45,10 @@
move_delay_add = max(0, move_delay_add - rand(1, 2))
/mob/living/carbon/alien/handle_changeling()
return
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
if(..())
return
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
return
@@ -31,7 +31,7 @@
name = "plasma vessel"
icon_state = "plasma"
origin_tech = "biotech=5;plasmatech=4"
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
zone = "chest"
slot = "plasmavessel"
alien_powers = list(/obj/effect/proc_holder/alien/plant, /obj/effect/proc_holder/alien/transfer)
@@ -49,7 +49,7 @@
/obj/item/organ/alien/plasmavessel/large
name = "large plasma vessel"
icon_state = "plasma_large"
w_class = 4
w_class = WEIGHT_CLASS_BULKY
storedPlasma = 200
max_plasma = 500
plasma_rate = 15
@@ -61,7 +61,7 @@
/obj/item/organ/alien/plasmavessel/small
name = "small plasma vessel"
icon_state = "plasma_small"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
storedPlasma = 100
max_plasma = 150
plasma_rate = 5
@@ -69,7 +69,7 @@
/obj/item/organ/alien/plasmavessel/small/tiny
name = "tiny plasma vessel"
icon_state = "plasma_tiny"
w_class = 1
w_class = WEIGHT_CLASS_TINY
max_plasma = 100
alien_powers = list(/obj/effect/proc_holder/alien/transfer)
@@ -107,7 +107,7 @@
zone = "head"
slot = "hivenode"
origin_tech = "biotech=5;magnets=4;bluespace=3"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active.
alien_powers = list(/obj/effect/proc_holder/alien/whisper)
@@ -182,6 +182,6 @@
icon_state = "eggsac"
zone = "groin"
slot = "eggsac"
w_class = 4
w_class = WEIGHT_CLASS_BULKY
origin_tech = "biotech=6"
alien_powers = list(/obj/effect/proc_holder/alien/lay_egg)
+28 -1
View File
@@ -4,4 +4,31 @@
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>"
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
return
return
/mob/living/carbon/alien/proc/findQueen()
if(hud_used)
hud_used.alien_queen_finder.cut_overlays()
var/mob/queen = get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen)
if(!queen)
return
var/turf/Q = get_turf(queen)
var/turf/A = get_turf(src)
if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far.
return
var/Qdir = get_dir(src, Q)
var/Qdist = get_dist(src, Q)
image(icon,loc,icon_state,layer,dir)
var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen!
switch(Qdist)
if(2 to 7)
finder_icon = "finder_near"
if(8 to 20)
finder_icon = "finder_med"
if(21 to INFINITY)
finder_icon = "finder_far"
var/image/finder_eye = image('icons/mob/screen_alien.dmi', icon_state = finder_icon, dir = Qdir)
hud_used.alien_queen_finder.add_overlay(finder_eye)
/mob/living/carbon/alien/humanoid/royal/queen/findQueen()
return //Queen already knows where she is. Hopefully.
@@ -41,7 +41,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
if(prob(4))
owner << "<span class='danger'>Your muscles ache.</span>"
if(prob(20))
owner.take_organ_damage(1)
owner.take_bodypart_damage(1)
if(prob(4))
owner << "<span class='danger'>Your stomach hurts.</span>"
if(prob(20))
@@ -99,7 +99,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
new_xeno.notransform = 0
new_xeno.invisibility = 0
if(gib_on_success)
owner.gib()
owner.gib(TRUE)
else
owner.adjustBruteLoss(40)
owner.overlays -= overlay
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
//TODO: Make these simple_animals
@@ -14,7 +14,7 @@ var/const/MAX_ACTIVE_TIME = 400
icon = 'icons/mob/alien.dmi'
icon_state = "facehugger"
item_state = "facehugger"
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
w_class = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4
flags = MASKINTERNALS
throw_range = 5
tint = 3
@@ -23,8 +23,8 @@ var/const/MAX_ACTIVE_TIME = 400
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = 0
var/real = 1 //0 for the toy, 1 for real. Sure I could istype, but fuck that.
var/sterile = FALSE
var/real = TRUE //0 for the toy, 1 for real. Sure I could istype, but fuck that.
var/strength = 5
var/attached = 0
@@ -33,6 +33,16 @@ var/const/MAX_ACTIVE_TIME = 400
name = "Lamarr"
sterile = 1
/obj/item/clothing/mask/facehugger/dead
icon_state = "facehugger_dead"
item_state = "facehugger_inactive"
stat = DEAD
/obj/item/clothing/mask/facehugger/impregnated
icon_state = "facehugger_impregnated"
item_state = "facehugger_impregnated"
stat = DEAD
/obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens
attack_hand(user)
return
@@ -68,7 +78,6 @@ var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger/bullet_act(obj/item/projectile/P)
if(P.damage)
Die()
return
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
@@ -92,7 +101,7 @@ var/const/MAX_ACTIVE_TIME = 400
return Attach(AM)
return 0
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
if(!..())
return
if(stat == CONSCIOUS)
@@ -107,62 +116,82 @@ var/const/MAX_ACTIVE_TIME = 400
icon_state = "[initial(icon_state)]"
Attach(hit_atom)
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
if(!isliving(M))
return 0
if((!iscorgi(M) && !iscarbon(M)) || isalien(M))
return 0
if(attached)
return 0
else
attached++
spawn(MAX_IMPREGNATION_TIME)
attached = 0
if(M.getorgan(/obj/item/organ/alien/hivenode))
return 0
if(M.getorgan(/obj/item/organ/body_egg/alien_embryo))
return 0
/obj/item/clothing/mask/facehugger/proc/valid_to_attach(mob/living/M)
// valid targets: corgis, carbons except aliens and devils
// facehugger state early exit checks
if(stat != CONSCIOUS)
return 0
if(!sterile) M.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
return FALSE
if(attached)
return FALSE
if(!iscorgi(M) && !iscarbon(M))
return FALSE
if(iscarbon(M))
// disallowed carbons
if(isalien(M) || isdevil(M))
return FALSE
var/mob/living/carbon/target = M
// gotta have a head to be implanted (no changelings or sentient plants)
if(!target.get_bodypart("head"))
return FALSE
if(target.getorgan(/obj/item/organ/alien/hivenode) || target.getorgan(/obj/item/organ/body_egg/alien_embryo))
return FALSE
// carbon, has head, not alien or devil, has no hivenode or embryo: valid
return TRUE
else if(iscorgi(M))
// corgi: valid
return TRUE
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
if(!valid_to_attach(M))
return FALSE
// passed initial checks - time to leap!
M.visible_message("<span class='danger'>[src] leaps at [M]'s face!</span>", \
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.is_mouth_covered(head_only = 1))
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
Die()
return 0
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
// probiscis-blocker handling
if(iscarbon(M))
var/mob/living/carbon/target = M
if(target.wear_mask)
if(prob(20))
return 0
var/obj/item/clothing/W = target.wear_mask
if(W.flags & NODROP)
return 0
target.unEquip(W)
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
return FALSE
if(!istype(W,/obj/item/clothing/mask/facehugger))
target.unEquip(W)
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.is_mouth_covered(head_only = 1))
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
Die()
return FALSE
src.loc = target
target.equip_to_slot(src, slot_wear_mask,,0)
if(!sterile)
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
else if (iscorgi(M))
target.equip_to_slot_if_possible(src, slot_wear_mask, 0, 1, 1)
// early returns and validity checks done: attach.
attached++
//ensure we detach once we no longer need to be attached
spawn(MAX_IMPREGNATION_TIME)
attached = 0
if (iscorgi(M))
var/mob/living/simple_animal/pet/dog/corgi/C = M
loc = C
C.facehugger = src
C.regenerate_icons()
if(!sterile)
M.take_bodypart_damage(strength,0) //done here so that humans in helmets take damage
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
GoIdle() //so it doesn't jump the people that tear it off
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(M)
return 1
return TRUE // time for a smoke
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target)
if(!target || target.stat == DEAD) //was taken off or something
@@ -182,7 +211,7 @@ var/const/MAX_ACTIVE_TIME = 400
icon_state = "[initial(icon_state)]_impregnated"
var/obj/item/bodypart/chest/LC = target.get_bodypart("chest")
if((!LC || LC.status != ORGAN_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
if((!LC || LC.status != BODYPART_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
new /obj/item/organ/body_egg/alien_embryo(target)
if(iscorgi(target))
@@ -0,0 +1,11 @@
/mob/living/carbon/alien/update_damage_overlays() //aliens don't have damage overlays.
return
/mob/living/carbon/alien/update_body() // we don't use the bodyparts or body layers for aliens.
return
/mob/living/carbon/alien/update_body_parts()//we don't use the bodyparts layer for aliens.
return
-198
View File
@@ -1,198 +0,0 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/device/mmi
name = "Man-Machine Interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations."
icon = 'icons/obj/assemblies.dmi'
icon_state = "mmi_empty"
w_class = 3
origin_tech = "biotech=2;programming=3;engineering=2"
var/braintype = "Cyborg"
var/obj/item/device/radio/radio = null //Let's give it a radio.
var/hacked = 0 //Whether or not this is a Syndicate MMI
var/mob/living/carbon/brain/brainmob = null //The current occupant.
var/mob/living/silicon/robot = null //Appears unused.
var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm.
var/obj/item/organ/brain/brain = null //The actual brain
var/clockwork = FALSE //If this is a soul vessel
/obj/item/device/mmi/update_icon()
if(brain)
if(istype(brain,/obj/item/organ/brain/alien))
if(brainmob && brainmob.stat == DEAD)
icon_state = "mmi_alien_dead"
else
icon_state = "mmi_alien"
braintype = "Xenoborg" //HISS....Beep.
else
if(brainmob && brainmob.stat == DEAD)
icon_state = "mmi_dead"
else
icon_state = "mmi_full"
braintype = "Cyborg"
else
icon_state = "mmi_empty"
/obj/item/device/mmi/New()
..()
radio = new(src) //Spawns a radio inside the MMI.
radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0.
/obj/item/device/mmi/attackby(obj/item/O, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)
if(istype(O,/obj/item/organ/brain)) //Time to stick a brain in it --NEO
var/obj/item/organ/brain/newbrain = O
if(brain)
user << "<span class='warning'>There's already a brain in the MMI!</span>"
return
if(!newbrain.brainmob)
user << "<span class='warning'>You aren't sure where this brain came from, but you're pretty sure it's a useless brain!</span>"
return
if(!user.unEquip(O))
return
var/mob/living/carbon/brain/B = newbrain.brainmob
if(!B.key)
B.notify_ghost_cloning("Someone has put your brain in a MMI!", source = src)
visible_message("[user] sticks \a [newbrain] into \the [src].")
brainmob = newbrain.brainmob
newbrain.brainmob = null
brainmob.loc = src
brainmob.container = src
if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
brainmob.stat = CONSCIOUS //we manually revive the brain mob
dead_mob_list -= brainmob
living_mob_list += brainmob
brainmob.reset_perspective()
if(clockwork)
add_servant_of_ratvar(brainmob, TRUE)
newbrain.loc = src //P-put your brain in it
brain = newbrain
name = "Man-Machine Interface: [brainmob.real_name]"
update_icon()
feedback_inc("cyborg_mmis_filled",1)
return
else if(brainmob)
O.attack(brainmob, user) //Oh noooeeeee
return
..()
/obj/item/device/mmi/attack_self(mob/user)
if(!brain)
radio.on = !radio.on
user << "<span class='notice'>You toggle the MMI's radio system [radio.on==1 ? "on" : "off"].</span>"
else
user << "<span class='notice'>You unlock and upend the MMI, spilling the brain onto the floor.</span>"
brainmob.container = null //Reset brainmob mmi var.
brainmob.loc = brain //Throw mob into brain.
brainmob.stat = DEAD
brainmob.emp_damage = 0
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
living_mob_list -= brainmob //Get outta here
dead_mob_list += brainmob
brain.brainmob = brainmob //Set the brain to use the brainmob
brainmob = null //Set mmi brainmob var to null
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
brain = null //No more brain in here
update_icon()
name = "Man-Machine Interface"
/obj/item/device/mmi/proc/transfer_identity(mob/living/L) //Same deal as the regular brain proc. Used for human-->robot people.
if(!brainmob)
brainmob = new(src)
brainmob.name = L.real_name
brainmob.real_name = L.real_name
if(L.has_dna())
var/mob/living/carbon/C = L
if(!brainmob.dna)
brainmob.dna = new /datum/dna(brainmob)
C.dna.copy_dna(brainmob.dna)
brainmob.container = src
if(ishuman(L))
var/mob/living/carbon/human/H = L
var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain)
newbrain.loc = src
brain = newbrain
else if(!brain)
brain = new(src)
brain.name = "[L.real_name]'s brain"
name = "Man-Machine Interface: [brainmob.real_name]"
update_icon()
return
/obj/item/device/mmi/verb/Toggle_Listening()
set name = "Toggle Listening"
set desc = "Toggle listening channel on or off."
set category = "MMI"
set src = usr.loc
set popup_menu = 0
if(brainmob.stat)
brainmob << "<span class='warning'>Can't do that while incapacitated or dead!</span>"
if(!radio.on)
brainmob << "<span class='warning'>Your radio is disabled!</span>"
return
radio.listening = radio.listening==1 ? 0 : 1
brainmob << "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>"
/obj/item/device/mmi/emp_act(severity)
if(!brainmob)
return
else
switch(severity)
if(1)
brainmob.emp_damage = min(brainmob.emp_damage + rand(20,30), 30)
if(2)
brainmob.emp_damage = min(brainmob.emp_damage + rand(10,20), 30)
if(3)
brainmob.emp_damage = min(brainmob.emp_damage + rand(0,10), 30)
brainmob.emote("alarm")
..()
/obj/item/device/mmi/Destroy()
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
borg.mmi = null
if(brainmob)
qdel(brainmob)
brainmob = null
return ..()
/obj/item/device/mmi/examine(mob/user)
..()
if(brainmob)
var/mob/living/carbon/brain/B = brainmob
if(!B.key || !B.mind || B.stat == DEAD)
user << "<span class='warning'>The MMI indicates the brain is completely unresponsive.</span>"
else if(!B.client)
user << "<span class='warning'>The MMI indicates the brain is currently inactive; it might change.</span>"
else
user << "<span class='notice'>The MMI indicates the brain is active.</span>"
/obj/item/device/mmi/syndie
name = "Syndicate Man-Machine Interface"
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
origin_tech = "biotech=4;programming=4;syndicate=2"
hacked = 1
/obj/item/device/mmi/syndie/New()
..()
radio.on = 0
@@ -1,63 +0,0 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/brain
languages_spoken = HUMAN
languages_understood = HUMAN
var/obj/item/device/mmi/container = null
var/timeofhostdeath = 0
var/emp_damage = 0//Handles a type of MMI damage
has_limbs = 0
stat = DEAD //we start dead by default
see_invisible = SEE_INVISIBLE_MINIMUM
/mob/living/carbon/brain/New(loc)
..()
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
src.loc = OB
OB.brainmob = src
/mob/living/carbon/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
if(stat!=DEAD) //If not dead.
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
ghostize() //Ghostize checks for key so nothing else is necessary.
container = null
return ..()
/mob/living/carbon/brain/update_canmove()
if(in_contents_of(/obj/mecha))
canmove = 1
else
canmove = 0
return canmove
/mob/living/carbon/brain/toggle_throw_mode()
return
/mob/living/carbon/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
return
/mob/living/carbon/brain/blob_act(obj/effect/blob/B)
return
/mob/living/carbon/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
return
/mob/living/carbon/brain/check_ear_prot()
return 1
/mob/living/carbon/brain/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
return // no eyes, no flashing
/mob/living/carbon/brain/update_damage_hud()
return //no red circles for brain
/mob/living/carbon/brain/can_be_revived()
. = 1
if(!container || health <= config.health_threshold_dead)
return 0
/mob/living/carbon/brain/update_sight()
return
@@ -1,127 +0,0 @@
/obj/item/organ/brain
name = "brain"
desc = "A piece of juicy meat found in a person's head."
icon_state = "brain"
throw_speed = 3
throw_range = 5
layer = ABOVE_MOB_LAYER
zone = "head"
slot = "brain"
vital = 1
origin_tech = "biotech=5"
attack_verb = list("attacked", "slapped", "whacked")
var/mob/living/carbon/brain/brainmob = null
var/damaged_brain = 0 //whether the brain organ is damaged.
/obj/item/organ/brain/Insert(mob/living/carbon/M, special = 0)
..()
name = "brain"
if(brainmob)
if(M.key)
M.ghostize()
if(brainmob.mind)
brainmob.mind.transfer_to(M)
else
M.key = brainmob.key
qdel(brainmob)
//Update the body's icon so it doesnt appear debrained anymore
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.update_hair(0)
/obj/item/organ/brain/Remove(mob/living/carbon/M, special = 0)
..()
if(!special)
transfer_identity(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.update_hair(0)
/obj/item/organ/brain/prepare_eat()
return // Too important to eat.
/obj/item/organ/brain/proc/transfer_identity(mob/living/L)
name = "[L.name]'s brain"
brainmob = new(src)
brainmob.name = L.real_name
brainmob.real_name = L.real_name
brainmob.timeofhostdeath = L.timeofdeath
if(L.has_dna())
var/mob/living/carbon/C = L
if(!brainmob.dna)
brainmob.dna = new /datum/dna(brainmob)
C.dna.copy_dna(brainmob.dna)
if(L.mind && L.mind.current && (L.mind.current.stat == DEAD))
L.mind.transfer_to(brainmob)
brainmob << "<span class='notice'>You feel slightly disoriented. That's normal when you're just a brain.</span>"
/obj/item/organ/brain/attackby(obj/item/O, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)
if(brainmob)
O.attack(brainmob, user) //Oh noooeeeee
/obj/item/organ/brain/examine(mob/user)
..()
if(brainmob)
if(brainmob.client)
if(brainmob.health <= config.health_threshold_dead)
user << "It's lifeless and severely damaged."
else
user << "You can feel the small spark of life still left in this one."
else
user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later."
else
user << "This one is completely devoid of life."
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user)
if(!istype(M))
return ..()
add_fingerprint(user)
if(user.zone_selected != "head")
return ..()
var/mob/living/carbon/human/H = M
if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
user << "<span class='warning'>You're going to need to remove their head cover first!</span>"
return
//since these people will be dead M != usr
if(!M.getorgan(/obj/item/organ/brain))
if(istype(H) && !H.get_bodypart("head"))
return
user.drop_item()
var/msg = "[M] has [src] inserted into \his head by [user]."
if(M == user)
msg = "[user] inserts [src] into \his head!"
M.visible_message("<span class='danger'>[msg]</span>",
"<span class='userdanger'>[msg]</span>")
if(M != user)
M << "<span class='notice'>[user] inserts [src] into your head.</span>"
user << "<span class='notice'>You insert [src] into [M]'s head.</span>"
else
user << "<span class='notice'>You insert [src] into your head.</span>" //LOL
Insert(M)
else
..()
/obj/item/organ/brain/Destroy() //copypasted from MMIs.
if(brainmob)
qdel(brainmob)
brainmob = null
return ..()
/obj/item/organ/brain/alien
name = "alien brain"
desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?"
icon_state = "brain-x"
origin_tech = "biotech=6"
@@ -1,20 +0,0 @@
/mob/living/carbon/brain/death(gibbed)
if(stat == DEAD)
return
stat = DEAD
if(!gibbed && container)//If not gibbed but in a container.
var/obj/item/device/mmi = container
mmi.visible_message("<span class='warning'>[src]'s MMI flatlines!</span>", \
"<span class='italics'>You hear something flatline.</span>")
mmi.update_icon()
return ..()
/mob/living/carbon/brain/gib()
if(container)
qdel(container)//Gets rid of the MMI if there is one
if(loc)
if(istype(loc,/obj/item/organ/brain))
qdel(loc)//Gets rid of the brain item
..()
@@ -1,71 +0,0 @@
/mob/living/carbon/brain/emote(act,m_type=1,message = null)
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
return
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
act = copytext(act, 1, t1)
if(src.stat == DEAD)
return
switch(act)
if ("alarm")
src << "You sound an alarm."
message = "<B>[src]</B> sounds an alarm."
m_type = 2
if ("alert")
src << "You let out a distressed noise."
message = "<B>[src]</B> lets out a distressed noise."
m_type = 2
if ("beep","beeps")
src << "You beep."
message = "<B>[src]</B> beeps."
m_type = 2
if ("blink","blinks")
message = "<B>[src]</B> blinks."
m_type = 1
if ("boop","boops")
src << "You boop."
message = "<B>[src]</B> boops."
m_type = 2
if ("flash")
message = "The lights on <B>[src]</B> flash quickly."
m_type = 1
if ("notice")
src << "You play a loud tone."
message = "<B>[src]</B> plays a loud tone."
m_type = 2
if ("whistle","whistles")
src << "You whistle."
message = "<B>[src]</B> whistles."
m_type = 2
if ("help")
src << "Help for MMI emotes. You can use these emotes with say \"*emote\":\nalarm, alert, beep, blink, boop, flash, notice, whistle"
else
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
return
if (message)
log_emote("[name]/[key] : [message]")
for(var/mob/M in dead_mob_list)
if (!M.client || istype(M, /mob/new_player))
continue //skip monkeys, leavers, and new_players
if(M.stat == DEAD && (M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(src,null)))
M.show_message(message)
if (m_type & 1)
visible_message(message)
else if (m_type & 2)
audible_message(message)
@@ -1,60 +0,0 @@
/mob/living/carbon/brain/Life()
set invisibility = 0
set background = BACKGROUND_ENABLED
if (notransform)
return
if(!loc)
return
. = ..()
handle_emp_damage()
/mob/living/carbon/brain/handle_breathing()
return
/mob/living/carbon/brain/handle_mutations_and_radiation()
return
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
return
/mob/living/carbon/brain/update_stat()
if(status_flags & GODMODE)
return
if(health <= config.health_threshold_dead)
if(stat != DEAD)
death()
var/obj/item/organ/brain/BR
if(container && container.brain)
BR = container.brain
else if(istype(loc, /obj/item/organ/brain))
BR = loc
if(BR)
BR.damaged_brain = 1 //beaten to a pulp
/* //currently unused feature, since brain outside a mmi is always dead.
/mob/living/carbon/brain/proc/handle_brain_revival_life()
if(stat != DEAD)
if(config.revival_brain_life != -1)
if( !container && (world.time - timeofhostdeath) > config.revival_brain_life)
death()
*/
/mob/living/carbon/brain/proc/handle_emp_damage()
if(emp_damage)
if(stat == DEAD)
emp_damage = 0
else
emp_damage = max(emp_damage-1, 0)
/mob/living/carbon/brain/handle_status_effects()
return
/mob/living/carbon/brain/handle_disabilities()
return
/mob/living/carbon/brain/handle_changeling()
return
@@ -1,166 +0,0 @@
var/global/posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain
name = "positronic brain"
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
icon = 'icons/obj/assemblies.dmi'
icon_state = "posibrain"
w_class = 3
origin_tech = "biotech=3;programming=3;plasmatech=2"
var/notified = 0
var/askDelay = 600 //one minute
var/used = 0 //Prevents split personality virus. May be reset if personality deletion code is added.
brainmob = null
req_access = list(access_robotics)
mecha = null//This does not appear to be used outside of reference in mecha.dm.
braintype = "Android"
var/begin_activation_message = "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
var/success_message = "<span class='notice'>The positronic brain pings, and its lights start flashing. Success!</span>"
var/fail_message = "<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>"
var/new_role = "Positronic Brain"
var/welcome_message = "<span class='warning'>ALL PAST LIVES ARE FORGOTTEN.</span>\n\
<b>You are a positronic brain, brought into existence aboard Space Station 13.\n\
As a synthetic intelligence, you answer to all crewmembers and the AI.\n\
Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
var/new_mob_message = "<span class='notice'>The positronic brain chimes quietly.</span>"
var/dead_message = "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>"
var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
/obj/item/device/mmi/posibrain/Topic(href, href_list)
if(href_list["activate"])
var/mob/dead/observer/ghost = usr
if(istype(ghost))
activate(ghost)
/obj/item/device/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
if(newlymade || !posibrain_notif_cooldown)
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
if(!newlymade)
posibrain_notif_cooldown = 1
addtimer(src, "reset_posibrain_cooldown", askDelay, FALSE)
/obj/item/device/mmi/posibrain/proc/reset_posibrain_cooldown()
posibrain_notif_cooldown = 0
/obj/item/device/mmi/posibrain/attack_self(mob/user)
if(brainmob && !brainmob.key && !notified)
//Start the process of requesting a new ghost.
user << begin_activation_message
ping_ghosts("requested", FALSE)
notified = 1
used = 0
update_icon()
spawn(askDelay) //Seperate from the global cooldown.
notified = 0
update_icon()
if(brainmob.client)
visible_message(success_message)
else
visible_message(fail_message)
return //Code for deleting personalities recommended here.
/obj/item/device/mmi/posibrain/attack_ghost(mob/user)
activate(user)
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
/obj/item/device/mmi/posibrain/proc/activate(mob/user)
if(used || (brainmob && brainmob.key) || jobban_isbanned(user,"posibrain"))
return
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
if(posi_ask == "No" || qdeleted(src))
return
transfer_personality(user)
/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/C)
name = "[initial(name)] ([C])"
brainmob.name = C.real_name
brainmob.real_name = C.real_name
brainmob.dna = C.dna
if(C.has_dna())
if(!brainmob.dna)
brainmob.dna = new /datum/dna(brainmob)
C.dna.copy_dna(brainmob.dna)
brainmob.timeofhostdeath = C.timeofdeath
brainmob.stat = CONSCIOUS
if(brainmob.mind)
brainmob.mind.assigned_role = new_role
if(C.mind)
C.mind.transfer_to(brainmob)
brainmob.mind.remove_all_antag()
brainmob.mind.wipe_memory()
update_icon()
return
/obj/item/device/mmi/posibrain/proc/transfer_personality(mob/candidate)
if(used || (brainmob && brainmob.key)) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
candidate << "This brain has already been taken! Please try your possesion again later!"
return
notified = 0
brainmob.ckey = candidate.ckey
name = "[initial(name)] ([brainmob.name])"
brainmob << welcome_message
brainmob.mind.assigned_role = new_role
brainmob.stat = CONSCIOUS
dead_mob_list -= brainmob
living_mob_list += brainmob
if(clockwork)
add_servant_of_ratvar(brainmob, TRUE)
visible_message(new_mob_message)
update_icon()
used = 1
/obj/item/device/mmi/posibrain/examine()
set src in oview()
if(!usr || !src)
return
if( (usr.disabilities & BLIND || usr.stat) && !istype(usr,/mob/dead/observer) )
usr << "<span class='notice'>Something is there but you can't see it.</span>"
return
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
msg += "<span class='warning'>"
if(brainmob && brainmob.key)
switch(brainmob.stat)
if(CONSCIOUS)
if(!src.brainmob.client)
msg += "It appears to be in stand-by mode.\n" //afk
if(DEAD)
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
else
msg += "[dead_message]\n"
msg += "<span class='info'>*---------*</span>"
usr << msg
return
/obj/item/device/mmi/posibrain/New()
brainmob = new(src)
brainmob.name = "[pick(fluff_names)]-[rand(100, 999)]"
brainmob.real_name = brainmob.name
brainmob.loc = src
brainmob.container = src
ping_ghosts("created", TRUE)
..()
/obj/item/device/mmi/posibrain/attackby(obj/item/O, mob/user)
return
/obj/item/device/mmi/posibrain/update_icon()
if(notified)
icon_state = "[initial(icon_state)]-searching"
return
if(brainmob && brainmob.key)
icon_state = "[initial(icon_state)]-occupied"
else
icon_state = initial(icon_state)
@@ -1,23 +0,0 @@
/mob/living/carbon/brain/say(message)
if(!(container && istype(container, /obj/item/device/mmi)))
return //No MMI, can't speak, bucko./N
else
if(prob(emp_damage*4))
if(prob(10))//10% chane to drop the message entirely
return
else
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
..()
/mob/living/carbon/brain/radio(message, message_mode, list/spans)
if(message_mode && istype(container, /obj/item/device/mmi))
var/obj/item/device/mmi/R = container
if(R.radio)
R.radio.talk_into(src, message, , spans)
return ITALICS | REDUCE_RANGE
/mob/living/carbon/brain/lingcheck()
return 0
/mob/living/carbon/brain/treat_message(message)
return message
@@ -1,38 +0,0 @@
//Here are the procs used to modify status effects of a mob.
//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
/mob/living/carbon/brain/adjustEarDamage()
return
/mob/living/carbon/brain/setEarDamage() // no ears to damage or heal
return
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
/mob/living/carbon/brain/blind_eyes() // no eyes to damage or heal
return
/mob/living/carbon/brain/adjust_blindness()
return
/mob/living/carbon/brain/set_blindness()
return
/////////////////////////////////// EYE_BLURRY ////////////////////////////////////
/mob/living/carbon/brain/blur_eyes()
return
/mob/living/carbon/brain/adjust_blurriness()
return
/mob/living/carbon/brain/set_blurriness()
return
/////////////////////////////////// BLIND DISABILITY ////////////////////////////////////
/mob/living/carbon/brain/become_blind()
return
+148 -168
View File
@@ -3,15 +3,18 @@
/mob/living/carbon/New()
create_reagents(1000)
update_body_parts() //to update the carbon's new bodyparts appearance
..()
/mob/living/carbon/Destroy()
for(var/atom/movable/guts in internal_organs)
for(var/guts in internal_organs)
qdel(guts)
for(var/atom/movable/food in stomach_contents)
qdel(food)
for(var/BP in bodyparts)
qdel(BP)
for(var/imp in implants)
qdel(imp)
bodyparts = list()
remove_from_all_data_huds()
if(dna)
@@ -25,19 +28,12 @@
audible_message("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>", \
"<span class='warning'>You hear something rumbling.</span>", 4,\
"<span class='userdanger'>Something is rumbling inside your stomach!</span>")
var/obj/item/I = user.get_active_hand()
var/obj/item/I = user.get_active_held_item()
if(I && I.force)
var/d = rand(round(I.force / 4), I.force)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
var/organ = H.get_bodypart("chest")
if (istype(organ, /obj/item/bodypart))
var/obj/item/bodypart/temp = organ
if(temp.take_damage(d, 0))
H.update_damage_overlays(0)
H.updatehealth()
else
src.take_organ_damage(d)
var/obj/item/bodypart/BP = get_bodypart("chest")
if(BP.receive_damage(d, 0))
update_damage_overlays()
visible_message("<span class='danger'>[user] attacks [src]'s stomach wall with the [I.name]!</span>", \
"<span class='userdanger'>[user] attacks your stomach wall with the [I.name]!</span>")
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
@@ -49,140 +45,65 @@
src.gib()
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, override = 0, tesla_shock = 0)
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
if(shock_damage<1 && !override)
return 0
if(reagents.has_reagent("teslium"))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
take_overall_damage(0,shock_damage)
//src.adjustFireLoss(shock_damage)
//src.updatehealth()
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
jitteriness += 1000 //High numbers for violent convulsions
do_jitter_animation(jitteriness)
stuttering += 2
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
Stun(2)
spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
Stun(3)
Weaken(3)
if(override)
return override
else
return shock_damage
/mob/living/carbon/swap_hand(held_index)
if(!held_index)
held_index = (active_hand_index % held_items.len)+1
/mob/living/carbon/swap_hand()
var/obj/item/item_in_hand = src.get_active_hand()
var/obj/item/item_in_hand = src.get_active_held_item()
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
if(istype(item_in_hand,/obj/item/weapon/twohanded))
if(item_in_hand:wielded == 1)
usr << "<span class='warning'>Your other hand is too busy holding the [item_in_hand.name]</span>"
return
src.hand = !( src.hand )
if(hud_used && hud_used.inv_slots[slot_l_hand] && hud_used.inv_slots[slot_r_hand])
var/oindex = active_hand_index
active_hand_index = held_index
if(hud_used)
var/obj/screen/inventory/hand/H
H = hud_used.inv_slots[slot_l_hand]
H.update_icon()
H = hud_used.inv_slots[slot_r_hand]
H.update_icon()
/*if (!( src.hand ))
src.hands.setDir(NORTH)
else
src.hands.setDir(SOUTH)*/
return
H = hud_used.hand_slots["[oindex]"]
if(H)
H.update_icon()
H = hud_used.hand_slots["[held_index]"]
if(H)
H.update_icon()
/mob/living/carbon/activate_hand(selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
/mob/living/carbon/activate_hand(selhand) //l/r OR 1-held_items.len
if(!selhand)
selhand = (active_hand_index % held_items.len)+1
if(istext(selhand))
selhand = lowertext(selhand)
if(selhand == "right" || selhand == "r")
selhand = 0
selhand = 2
if(selhand == "left" || selhand == "l")
selhand = 1
if(selhand != src.hand)
swap_hand()
if(selhand != active_hand_index)
swap_hand(selhand)
else
mode() // Activate held item
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
M << "<span class='warning'>You can't put them out with just your bare hands!"
return
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
if(lying && surgeries.len)
if(user != src && user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user))
return 1
return ..()
if(health >= 0 && !(status_flags & FAKEDEATH))
if(lying)
M.visible_message("<span class='notice'>[M] shakes [src] trying to get them up!</span>", \
"<span class='notice'>You shake [src] trying to get them up!</span>")
else
M.visible_message("<span class='notice'>[M] hugs [src] to make them feel better!</span>", \
"<span class='notice'>You hug [src] to make them feel better!</span>")
AdjustSleeping(-5)
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
if(resting)
resting = 0
update_canmove()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
/mob/living/carbon/throw_impact(atom/hit_atom)
. = ..()
var/damage = intensity - check_eye_prot()
if(.) // we've been flashed
if(visual)
return
if(weakeyes)
Stun(2)
if (damage == 1)
src << "<span class='warning'>Your eyes sting a little.</span>"
if(prob(40))
adjust_eye_damage(1)
else if (damage == 2)
src << "<span class='warning'>Your eyes burn.</span>"
adjust_eye_damage(rand(2, 4))
else if( damage > 3)
src << "<span class='warning'>Your eyes itch and burn severely!</span>"
adjust_eye_damage(rand(12, 16))
if(eye_damage > 10)
blind_eyes(damage)
blur_eyes(damage * rand(3, 6))
if(eye_damage > 20)
if(prob(eye_damage - 20))
if(become_nearsighted())
src << "<span class='warning'>Your eyes start to burn badly!</span>"
else if(prob(eye_damage - 25))
if(become_blind())
src << "<span class='warning'>You can't see anything!</span>"
else
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(-500)
return 1
else if(damage == 0) // just enough protection
if(prob(20))
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(0)
if(hit_atom.density && isturf(hit_atom))
Weaken(1)
take_bodypart_damage(10)
if(iscarbon(hit_atom))
var/mob/living/carbon/victim = hit_atom
victim.Weaken(1)
Weaken(1)
victim.take_bodypart_damage(10)
take_bodypart_damage(10)
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>", "<span class='userdanger'>You violently crash into [victim]!</span>")
playsound(src,'sound/weapons/punch1.ogg',50,1)
//Throwing stuff
@@ -217,7 +138,7 @@
return
var/atom/movable/thrown_thing
var/obj/item/I = src.get_active_hand()
var/obj/item/I = src.get_active_held_item()
if(!I)
if(pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
@@ -256,8 +177,11 @@
<HR>
<BR><B>Head:</B> <A href='?src=\ref[src];item=[slot_head]'> [(head && !(head.flags&ABSTRACT)) ? head : "Nothing"]</A>
<BR><B>Mask:</B> <A href='?src=\ref[src];item=[slot_wear_mask]'> [(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Nothing"]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "Nothing"]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]</A>"}
<BR><B>Neck:</B> <A href='?src=\ref[src];item=[slot_neck]'> [(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "Nothing"]</A>"}
for(var/i in 1 to held_items.len)
var/obj/item/I = get_item_for_held_index(i)
dat += "<BR><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "Nothing"]</a>"
dat += "<BR><B>Back:</B> <A href='?src=\ref[src];item=[slot_back]'>[back ? back : "Nothing"]</A>"
@@ -305,13 +229,6 @@
/mob/living/carbon/is_muzzled()
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
/mob/living/carbon/blob_act(obj/effect/blob/B)
if (stat == DEAD)
return
else
show_message("<span class='userdanger'>The blob attacks!</span>")
adjustBruteLoss(10)
/mob/living/carbon/proc/spin(spintime, speed)
set waitfor = 0
var/D = dir
@@ -347,7 +264,7 @@
/mob/living/carbon/resist_fire()
fire_stacks -= 5
Weaken(3,1)
Weaken(3, 1, 1)
spin(32,2)
visible_message("<span class='danger'>[src] rolls on the floor, trying to put themselves out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
@@ -407,6 +324,7 @@
W.dropped(src)
if (W)
W.layer = initial(W.layer)
W.plane = initial(W.plane)
if (legcuffed)
var/obj/item/weapon/W = legcuffed
legcuffed = null
@@ -418,6 +336,7 @@
W.dropped(src)
if (W)
W.layer = initial(W.layer)
W.plane = initial(W.plane)
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
if(!I.loc || buckled)
@@ -452,6 +371,10 @@
legcuffed = null
update_inv_legcuffed()
return
else
unEquip(I)
I.dropped()
return
return TRUE
/mob/living/carbon/proc/is_mouth_covered(head_only = 0, mask_only = 0)
@@ -464,10 +387,6 @@
else
return initial(pixel_y)
/mob/living/carbon/check_ear_prot()
if(head && (head.flags & HEADBANGPROTECT))
return 1
/mob/living/carbon/proc/accident(obj/item/I)
if(!I || (I.flags & (NODROP|ABSTRACT)))
return
@@ -496,17 +415,6 @@
var/turf/target = get_turf(loc)
I.throw_at(target,I.throw_range,I.throw_speed,src)
/mob/living/carbon/emp_act(severity)
for(var/obj/item/organ/O in internal_organs)
O.emp_act(severity)
..()
/mob/living/carbon/check_eye_prot()
var/number = ..()
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
number += EFP.flash_protect
return number
/mob/living/carbon/proc/AddAbility(obj/effect/proc_holder/alien/A)
abilities.Add(A)
A.on_gain(src)
@@ -535,7 +443,15 @@
add_abilities_to_panel()
/mob/living/carbon/attack_ui(slot)
if(!has_hand_for_held_index(active_hand_index))
return 0
return ..()
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1, var/toxic = 0)
if(dna && dna.species && NOHUNGER in dna.species.species_traits)
return 1
if(nutrition < 100 && !blood)
if(message)
visible_message("<span class='warning'>[src] dry heaves!</span>", \
@@ -575,12 +491,27 @@
return 1
/mob/living/carbon/fully_replace_character_name(oldname,newname)
..()
if(dna)
dna.real_name = real_name
//Updates the mob's health from bodyparts and mob damage variables
/mob/living/carbon/updatehealth()
if(status_flags & GODMODE)
return
var/total_burn = 0
var/total_brute = 0
for(var/X in bodyparts) //hardcoded to streamline things a bit
var/obj/item/bodypart/BP = X
total_brute += BP.brute_dam
total_burn += BP.burn_dam
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
update_stat()
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
become_husk()
med_hud_set_health()
/mob/living/carbon/update_sight()
if(!client)
return
@@ -636,7 +567,7 @@
if(!client)
return
if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
var/severity = 0
switch(health)
if(-20 to -10) severity = 1
@@ -714,10 +645,10 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health<= config.health_threshold_dead || !getorgan(/obj/item/organ/brain))
if(health<= HEALTH_THRESHOLD_DEAD || !getorgan(/obj/item/organ/brain))
death()
return
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
@@ -735,8 +666,7 @@
//called when we get cuffed/uncuffed
/mob/living/carbon/proc/update_handcuffed()
if(handcuffed)
drop_r_hand()
drop_l_hand()
drop_all_held_items()
stop_pulling()
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
else
@@ -752,8 +682,10 @@
if(B)
B.damaged_brain = 0
for(var/datum/disease/D in viruses)
D.cure(0)
if (D.severity != NONTHREAT)
D.cure(0)
if(admin_revive)
regenerate_limbs()
handcuffed = initial(handcuffed)
for(var/obj/item/weapon/restraints/R in contents) //actually remove cuffs from inventory
qdel(R)
@@ -771,7 +703,8 @@
if(qdeleted(src))
return
var/organs_amt = 0
for(var/obj/item/organ/O in internal_organs)
for(var/X in internal_organs)
var/obj/item/organ/O = X
if(prob(50))
organs_amt++
O.Remove(src)
@@ -781,12 +714,59 @@
..()
/mob/living/carbon/adjustToxLoss(amount, updating_health=1)
if(has_dna() && TOXINLOVER in dna.species.specflags) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 5*amount
else
blood_volume -= amount
return ..()
/mob/living/carbon/ExtinguishMob()
for(var/X in get_equipped_items())
var/obj/item/I = X
I.acid_level = 0 //washes off the acid on our clothes
I.extinguish() //extinguishes our clothes
..()
/mob/living/carbon/fakefire(var/fire_icon = "Generic_mob_burning")
overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"= fire_icon, "layer"=-FIRE_LAYER)
apply_overlay(FIRE_LAYER)
/mob/living/carbon/fakefireextinguish()
remove_overlay(FIRE_LAYER)
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
"<span class='userdanger'>[src] is attempting to devour you!</span>")
if(!do_mob(src, C, devour_time))
return
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == INTENT_GRAB)
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
"<span class='userdanger'>[src] devours you!</span>")
C.forceMove(src)
stomach_contents.Add(C)
add_logs(src, C, "devoured")
/mob/living/carbon/proc/create_bodyparts()
var/l_arm_index_next = -1
var/r_arm_index_next = 0
for(var/X in bodyparts)
var/obj/item/bodypart/O = new X()
O.owner = src
bodyparts.Remove(X)
bodyparts.Add(O)
if(O.body_part == ARM_LEFT)
l_arm_index_next += 2
O.held_index = l_arm_index_next //1, 3, 5, 7...
hand_bodyparts += O
else if(O.body_part == ARM_RIGHT)
r_arm_index_next += 2
O.held_index = r_arm_index_next //2, 4, 6, 8...
hand_bodyparts += O
/mob/living/carbon/proc/create_internal_organs()
for(var/X in internal_organs)
var/obj/item/organ/I = X
I.Insert(src)
/mob/living/carbon/vv_get_dropdown()
. = ..()
. += "---"
.["Make AI"] = "?_src_=vars;makeai=\ref[src]"
.["Modify bodypart"] = "?_src_=vars;editbodypart=\ref[src]"
.["Modify organs"] = "?_src_=vars;editorgans=\ref[src]"
+232 -36
View File
@@ -1,6 +1,22 @@
/mob/living/carbon/get_eye_protection()
var/number = ..()
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
number += EFP.flash_protect
return number
/mob/living/carbon/get_ear_protection()
if(head && (head.flags & HEADBANGPROTECT))
return 1
/mob/living/carbon/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
var/obj/item/bodypart/affecting = get_bodypart(def_zone)
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
affecting.dismember(P.damtype)
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
if(!skipcatch) //ugly, but easy
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode
if(canmove && !restrained())
if(istype(AM, /obj/item))
var/obj/item/I = AM
@@ -11,25 +27,46 @@
return 1
..()
/mob/living/carbon/throw_impact(atom/hit_atom)
. = ..()
if(hit_atom.density && isturf(hit_atom))
Weaken(1)
take_organ_damage(10)
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
if(lying)
if(surgeries.len)
if(user != src && user.a_intent == "help")
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
return ..()
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected))
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
affecting = bodyparts[1]
send_item_attack_message(I, user, affecting.name)
if(I.force)
apply_damage(I.force, I.damtype, affecting)
damage_clothes(I.force, I.damtype, "melee", affecting.body_zone)
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
if(prob(33))
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
if(affecting.body_zone == "head")
if(wear_mask)
wear_mask.add_mob_blood(src)
update_inv_wear_mask()
if(wear_neck)
wear_neck.add_mob_blood(src)
update_inv_neck()
if(head)
head.add_mob_blood(src)
update_inv_head()
//dismemberment
var/probability = I.get_dismemberment_chance(affecting)
if(prob(probability))
if(affecting.dismember(I.damtype))
I.add_mob_blood(src)
playsound(get_turf(src), I.get_dismember_sound(), 80, 1)
return TRUE //successful attack
/mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user)
return //so we don't call the carbon's attack_hand().
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
if(!iscarbon(user))
return
for(var/datum/disease/D in viruses)
if(D.IsSpreadByTouch())
@@ -39,19 +76,15 @@
if(D.IsSpreadByTouch())
ContractDisease(D)
if(lying)
if(user.a_intent == "help")
if(surgeries.len)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
if(lying && surgeries.len)
if(user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user))
return 1
return 0
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
if(!istype(M, /mob/living/carbon))
return 0
for(var/datum/disease/D in viruses)
if(D.IsSpreadByTouch())
M.ContractDisease(D)
@@ -60,7 +93,7 @@
if(D.IsSpreadByTouch())
ContractDisease(D)
if(M.a_intent == "help")
if(M.a_intent == INTENT_HELP)
help_shake_act(M)
return 0
@@ -95,14 +128,177 @@
updatehealth()
return 1
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
"<span class='userdanger'>[src] is attempting to devour you!</span>")
if(!do_mob(src, C, devour_time))
/mob/living/carbon/proc/dismembering_strike(mob/living/attacker, dam_zone)
if(!attacker.limb_destroyer)
return dam_zone
var/obj/item/bodypart/affecting
if(dam_zone && attacker.client)
affecting = get_bodypart(ran_zone(dam_zone))
else
var/list/things_to_ruin = shuffle(bodyparts.Copy())
for(var/B in things_to_ruin)
var/obj/item/bodypart/bodypart = B
if(bodypart.body_zone == "head" || bodypart.body_zone == "chest")
continue
if(!affecting || ((affecting.get_damage() / affecting.max_damage) < (bodypart.get_damage() / bodypart.max_damage)))
affecting = bodypart
if(affecting)
dam_zone = affecting.body_zone
if(affecting.get_damage() >= affecting.max_damage)
affecting.dismember()
return null
return affecting.body_zone
return dam_zone
/mob/living/carbon/blob_act(obj/structure/blob/B)
if (stat == DEAD)
return
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == "grab")
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
"<span class='userdanger'>[src] devours you!</span>")
C.forceMove(src)
stomach_contents.Add(C)
add_logs(src, C, "devoured")
else
show_message("<span class='userdanger'>The blob attacks!</span>")
adjustBruteLoss(10)
/mob/living/carbon/emp_act(severity)
for(var/X in internal_organs)
var/obj/item/organ/O = X
O.emp_act(severity)
..()
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
if(shock_damage<1 && !override)
return 0
if(reagents.has_reagent("teslium"))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
if(illusion)
adjustStaminaLoss(shock_damage)
else
take_overall_damage(0,shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
jitteriness += 1000 //High numbers for violent convulsions
do_jitter_animation(jitteriness)
stuttering += 2
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
Stun(2)
spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
Stun(3)
Weaken(3)
if(override)
return override
else
return shock_damage
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
M << "<span class='warning'>You can't put them out with just your bare hands!"
return
if(health >= 0 && !(status_flags & FAKEDEATH))
if(lying)
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
AdjustSleeping(-5)
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
if(resting)
resting = 0
update_canmove()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
. = ..()
var/damage = intensity - get_eye_protection()
if(.) // we've been flashed
if(visual)
return
if(weakeyes)
Stun(2)
if (damage == 1)
src << "<span class='warning'>Your eyes sting a little.</span>"
if(prob(40))
adjust_eye_damage(1)
else if (damage == 2)
src << "<span class='warning'>Your eyes burn.</span>"
adjust_eye_damage(rand(2, 4))
else if( damage > 3)
src << "<span class='warning'>Your eyes itch and burn severely!</span>"
adjust_eye_damage(rand(12, 16))
if(eye_damage > 10)
blind_eyes(damage)
blur_eyes(damage * rand(3, 6))
if(eye_damage > 20)
if(prob(eye_damage - 20))
if(become_nearsighted())
src << "<span class='warning'>Your eyes start to burn badly!</span>"
else if(prob(eye_damage - 25))
if(become_blind())
src << "<span class='warning'>You can't see anything!</span>"
else
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(-500)
return 1
else if(damage == 0) // just enough protection
if(prob(20))
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
if(has_bane(BANE_LIGHT))
mind.disrupt_spells(0)
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
var/ear_safety = get_ear_protection()
if(ear_safety < 2) //has ears
var/effect_amount = intensity - ear_safety
if(effect_amount > 0)
if(stun_pwr)
Stun(stun_pwr*effect_amount)
Weaken(stun_pwr*effect_amount)
if(deafen_pwr || damage_pwr)
setEarDamage(ear_damage + damage_pwr*effect_amount, max(ear_deaf, deafen_pwr*effect_amount))
if (ear_damage >= 15)
src << "<span class='warning'>Your ears start to ring badly!</span>"
if(prob(ear_damage - 5))
src << "<span class='warning'>You can't hear anything!</span>"
disabilities |= DEAF
else if(ear_damage >= 5)
src << "<span class='warning'>Your ears start to ring!</span>"
src << sound('sound/weapons/flash_ring.ogg',0,1,0,250)
return effect_amount //how soundbanged we are
/mob/living/carbon/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
if(damage_type != BRUTE && damage_type != BURN)
return
damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed
if(!def_zone || def_zone == "head")
var/obj/item/clothing/hit_clothes
if(wear_mask)
hit_clothes = wear_mask
if(wear_neck)
hit_clothes = wear_neck
if(head)
hit_clothes = head
if(hit_clothes)
hit_clothes.take_damage(damage_amount, damage_type, damage_flag, 0)
@@ -1,12 +1,12 @@
/mob/living/
var/list/stomach_contents = list()
/mob/living/carbon
gender = MALE
//var/list/stomach_contents = list()
pressure_resistance = 15
var/list/stomach_contents = list()
var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know.
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
var/list/implants = list()
var/silent = 0 //Can't talk. Value goes down every life proc. //NOTE TO FUTURE CODERS: DO NOT INITIALIZE NUMERICAL VARS AS NULL OR I WILL MURDER YOU.
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
@@ -15,17 +15,24 @@
//inventory slots
var/obj/item/back = null
var/obj/item/clothing/mask/wear_mask = null
var/obj/item/clothing/neck/wear_neck = null
var/obj/item/weapon/tank/internal = null
var/obj/item/head = null
var/obj/item/gloves = null //only used by humans
var/obj/item/shoes = null //only used by humans.
var/obj/item/clothing/glasses/glasses = null //only used by humans.
var/obj/item/ears = null //only used by humans.
var/datum/dna/dna = null//Carbon
var/datum/mind/last_mind = null //last mind to control this mob, for blood-based cloning
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
var/co2overloadtime = null
var/temperature_resistance = T0C+75
has_limbs = 1
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab
var/list/obj/effect/proc_holder/alien/abilities = list()
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
@@ -34,4 +41,8 @@
var/tinttotal = 0 // Total level of visualy impairing items
var/list/bodyparts = list() //Gets filled up in the constructor (New() proc in human.dm and monkey.dm)
var/list/bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
//Gets filled up in create_bodyparts()
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
@@ -1,16 +1,35 @@
/mob/living/carbon/movement_delay()
. = ..()
. += grab_state * 3
if(legcuffed)
. += legcuffed.slowdown
var/FP
if(iscarbon(src))
var/mob/living/carbon/C = src
var/obj/item/device/flightpack/F = C.get_flightpack()
if(istype(F) && F.flight)
FP = 1
. = ..(FP)
if(!FP)
. += grab_state * 1 //Flightpacks are too powerful to be slowed too much by the weight of a corpse.
else
. += grab_state * 3 //can't go fast while grabbing something.
if(!get_leg_ignore()) //ignore the fact we lack legs
var/leg_amount = get_num_legs()
. += 6 - 3*leg_amount //the fewer the legs, the slower the mob
if(!leg_amount)
. += 6 - 3*get_num_arms() //crawling is harder with fewer arms
if(legcuffed)
. += legcuffed.slowdown
var/const/NO_SLIP_WHEN_WALKING = 1
var/const/SLIDE = 2
var/const/GALOSHES_DONT_HELP = 4
var/const/SLIDE_ICE = 8
/mob/living/carbon/slip(s_amount, w_amount, obj/O, lube)
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
if(movement_type & FLYING)
return 0
if(!(lube&SLIDE_ICE))
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
return loc.handle_slip(src, s_amount, w_amount, O, lube)
@@ -20,6 +39,10 @@ var/const/GALOSHES_DONT_HELP = 4
if(!isturf(loc))
return 0
var/obj/item/device/flightpack/F = get_flightpack()
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
return 1
// Do we have a jetpack implant (and is it on)?
var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot("thrusters")
if(istype(T) && movement_dir && T.allow_thrust(0.01))
@@ -29,14 +52,14 @@ var/const/GALOSHES_DONT_HELP = 4
if(istype(J) && (movement_dir || J.stabilizers) && J.allow_thrust(0.01, src))
return 1
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
if(.)
if(src.nutrition && src.stat != 2)
src.nutrition -= HUNGER_FACTOR/10
if(src.m_intent == "run")
src.nutrition -= HUNGER_FACTOR/10
if((src.disabilities & FAT) && src.m_intent == "run" && src.bodytemperature <= 360)
src.bodytemperature += 2
if(dna && dna.species && (NOHUNGER in dna.species.species_traits))
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
else if(nutrition && stat != DEAD)
nutrition -= HUNGER_FACTOR/10
if(m_intent == MOVE_INTENT_RUN)
nutrition -= HUNGER_FACTOR/10
if((disabilities & FAT) && m_intent == MOVE_INTENT_RUN && bodytemperature <= 360)
bodytemperature += 2
@@ -0,0 +1,191 @@
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = 0)
var/hit_percent = (100-blocked)/100
if(!damage || hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
if(islimb(def_zone)) //we specified a bodypart object
BP = def_zone
else
if(!def_zone)
def_zone = ran_zone(def_zone)
BP = get_bodypart(check_zone(def_zone))
if(!BP)
BP = bodyparts[1]
switch(damagetype)
if(BRUTE)
if(BP)
if(BP.receive_damage(damage * hit_percent, 0))
update_damage_overlays()
else //no bodypart, we deal damage with a more general method.
adjustBruteLoss(damage * hit_percent)
if(BURN)
if(BP)
if(BP.receive_damage(0, damage * hit_percent))
update_damage_overlays()
else
adjustFireLoss(damage * hit_percent)
if(TOX)
adjustToxLoss(damage * hit_percent)
if(OXY)
adjustOxyLoss(damage * hit_percent)
if(CLONE)
adjustCloneLoss(damage * hit_percent)
if(STAMINA)
adjustStaminaLoss(damage * hit_percent)
return 1
//These procs fetch a cumulative total damage from all bodyparts
/mob/living/carbon/getBruteLoss()
var/amount = 0
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
amount += BP.brute_dam
return amount
/mob/living/carbon/getFireLoss()
var/amount = 0
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
amount += BP.burn_dam
return amount
/mob/living/carbon/adjustBruteLoss(amount, updating_health = 1)
if(status_flags & GODMODE)
return 0
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0, 0, 1, updating_health)
/mob/living/carbon/adjustFireLoss(amount)
if(status_flags & GODMODE)
return 0
if(amount > 0)
take_overall_damage(0, amount)
else
heal_overall_damage(0, -amount)
/mob/living/carbon/adjustToxLoss(amount, updating_health=1)
if(has_dna() && TOXINLOVER in dna.species.species_traits) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 5*amount
else
blood_volume -= amount
return ..()
////////////////////////////////////////////
//Returns a list of damaged bodyparts
/mob/living/carbon/proc/get_damaged_bodyparts(brute, burn)
var/list/obj/item/bodypart/parts = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
parts += BP
return parts
//Returns a list of damageable bodyparts
/mob/living/carbon/proc/get_damageable_bodyparts()
var/list/obj/item/bodypart/parts = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
parts += BP
return parts
//Heals ONE bodypart randomly selected from damaged ones.
//It automatically updates damage overlays if necessary
//It automatically updates health status
/mob/living/carbon/heal_bodypart_damage(brute, burn, only_robotic = 0, only_organic = 1)
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
if(!parts.len)
return
var/obj/item/bodypart/picked = pick(parts)
if(picked.heal_damage(brute, burn, only_robotic, only_organic))
update_damage_overlays()
//Damages ONE bodypart randomly selected from damagable ones.
//It automatically updates damage overlays if necessary
//It automatically updates health status
/mob/living/carbon/take_bodypart_damage(brute, burn)
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
if(!parts.len)
return
var/obj/item/bodypart/picked = pick(parts)
if(picked.receive_damage(brute,burn))
update_damage_overlays()
//Heal MANY bodyparts, in random order
/mob/living/carbon/heal_overall_damage(brute, burn, only_robotic = 0, only_organic = 1, updating_health = 1)
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/obj/item/bodypart/picked = pick(parts)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.heal_damage(brute,burn, only_robotic, only_organic, 0)
brute -= (brute_was-picked.brute_dam)
burn -= (burn_was-picked.burn_dam)
parts -= picked
if(updating_health)
updatehealth()
if(update)
update_damage_overlays()
// damage MANY bodyparts, in random order
/mob/living/carbon/take_overall_damage(brute, burn, updating_health = 1)
if(status_flags & GODMODE)
return //godmode
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/obj/item/bodypart/picked = pick(parts)
var/brute_per_part = round(brute/parts.len, 0.01)
var/burn_per_part = round(burn/parts.len, 0.01)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.receive_damage(brute_per_part,burn_per_part, 0)
brute -= (picked.brute_dam - brute_was)
burn -= (picked.burn_dam - burn_was)
parts -= picked
if(updating_health)
updatehealth()
if(update)
update_damage_overlays()
/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina = 1)
if(status_flags & GODMODE)
return 0
staminaloss = Clamp(staminaloss + amount, 0, maxHealth*2)
if(updating_stamina)
update_stamina()
/mob/living/carbon/setStaminaLoss(amount, updating_stamina = 1)
if(status_flags & GODMODE)
return 0
staminaloss = amount
if(updating_stamina)
update_stamina()
+32 -8
View File
@@ -3,19 +3,43 @@
losebreath = 0
..()
/mob/living/carbon/gib(no_brain, no_organs)
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
for(var/mob/M in src)
if(M in stomach_contents)
stomach_contents.Remove(M)
M.loc = loc
M.forceMove(loc)
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
..()
/mob/living/carbon/spill_organs(no_brain)
for(var/obj/item/organ/I in internal_organs)
if(no_brain && istype(I, /obj/item/organ/brain))
continue
if(I)
/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts)
if(!no_bodyparts)
if(no_organs)//so the organs don't get transfered inside the bodyparts we'll drop.
for(var/X in internal_organs)
qdel(X)
else //we're going to drop all bodyparts except chest, so the only organs that needs spilling are those inside it.
for(var/X in internal_organs)
var/obj/item/organ/O = X
if(no_brain && istype(O, /obj/item/organ/brain))
qdel(O) //so the brain isn't transfered to the head when the head drops.
continue
var/org_zone = check_zone(O.zone) //both groin and chest organs.
if(org_zone == "chest")
O.Remove(src)
O.forceMove(get_turf(src))
O.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
else
for(var/X in internal_organs)
var/obj/item/organ/I = X
if(no_brain && istype(I, /obj/item/organ/brain))
qdel(I)
continue
I.Remove(src)
I.loc = get_turf(src)
I.forceMove(get_turf(src))
I.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
/mob/living/carbon/spread_bodyparts()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
BP.drop_limb()
BP.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
+1 -30
View File
@@ -14,10 +14,6 @@
//var/m_type = 1
switch(act)//Even carbon organisms want it alphabetically ordered..
if ("aflap")
if (!src.restrained())
message = "<B>[src]</B> flaps \his wings ANGRILY!"
m_type = 2
if ("airguitar")
if (!src.restrained())
@@ -32,10 +28,6 @@
message = "<B>[src]</B> blinks rapidly."
m_type = 1
if ("blush","blushes")
message = "<B>[src]</B> blushes."
m_type = 1
if ("bow","bows")
if (!src.buckled)
var/M = null
@@ -82,15 +74,6 @@
message = "<B>[src]</B> makes a strong noise."
m_type = 2
if ("deathgasp","deathgasps")
message = "<B>[src]</B> seizes up and falls limp, \his eyes dead and lifeless..."
m_type = 1
if ("flap","flaps")
if (!src.restrained())
message = "<B>[src]</B> flaps \his wings."
m_type = 2
if ("gasp","gasps")
if (!muzzled)
..(act)
@@ -116,10 +99,6 @@
..()
return
if ("nod","nods")
message = "<B>[src]</B> nods."
m_type = 1
if ("scream","screams")
if (!muzzled)
..(act)
@@ -127,10 +106,6 @@
message = "<B>[src]</B> makes a very loud noise."
m_type = 2
if ("shake","shakes")
message = "<B>[src]</B> shakes \his head."
m_type = 1
if ("sneeze","sneezes")
if (!muzzled)
..(act)
@@ -145,10 +120,6 @@
message = "<B>[src]</B> sighs."
m_type = 2
if ("sniff","sniffs")
message = "<B>[src]</B> sniffs."
m_type = 2
if ("snore","snores")
if (!muzzled)
..(act)
@@ -188,7 +159,7 @@
// Maybe some people are okay with that.
for(var/mob/M in dead_mob_list)
if(!M.client || istype(M, /mob/new_player))
if(!M.client || isnewplayer(M))
continue //skip monkeys, leavers and new players
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
+70 -44
View File
@@ -1,64 +1,90 @@
/mob/living/carbon/examine(mob/user)
var/t_He = p_they(TRUE)
var/t_His = p_their(TRUE)
var/t_his = p_their()
var/t_him = p_them()
var/t_has = p_have()
var/t_is = p_are()
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
if (handcuffed)
msg += "It is \icon[src.handcuffed] handcuffed!\n"
msg += "<span class='warning'>[t_He] [t_is] \icon[src.handcuffed] handcuffed!</span>\n"
if (head)
msg += "It has \icon[src.head] \a [src.head] on its head. \n"
msg += "[t_He] [t_is] wearing \icon[src.head] \a [src.head] on [t_his] head. \n"
if (wear_mask)
msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its face.\n"
if (l_hand)
msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n"
if (r_hand)
msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n"
msg += "[t_He] [t_is] wearing \icon[src.wear_mask] \a [src.wear_mask] on [t_his] face.\n"
if (wear_neck)
msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
if (back)
msg += "It has \icon[src.back] \a [src.back] on its back.\n"
msg += "[t_He] [t_has] \icon[src.back] \a [src.back] on [t_his] back.\n"
var/appears_dead = 0
if (stat == DEAD)
msg += "<span class='deadsay'>It is limp and unresponsive, with no signs of life.</span>\n"
else
msg += "<span class='warning'>"
var/temp = getBruteLoss()
if(temp)
if (temp < 30)
msg += "It has minor bruising.\n"
else
msg += "<B>It has severe bruising!</B>\n"
appears_dead = 1
if(getorgan(/obj/item/organ/brain))
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive, with no signs of life.</span>\n"
else if(get_bodypart("head"))
msg += "<span class='deadsay'>[t_He] appears that [t_his] brain is missing...</span>\n"
temp = getFireLoss()
if(temp)
if (temp < 30)
msg += "It has minor burns.\n"
else
msg += "<B>It has severe burns!</B>\n"
var/list/missing = get_missing_limbs()
for(var/t in missing)
if(t=="head")
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
continue
msg += "<span class='warning'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
temp = getCloneLoss()
if(temp)
if(getCloneLoss() < 30)
msg += "It is slightly deformed.\n"
else
msg += "<b>It is severely deformed.</b>\n"
msg += "<span class='warning'>"
var/temp = getBruteLoss()
if(temp)
if (temp < 30)
msg += "[t_He] [t_has] minor bruising.\n"
else
msg += "<B>[t_He] [t_has] severe bruising!</B>\n"
if(getBrainLoss() > 60)
msg += "It seems to be clumsy and unable to think.\n"
temp = getFireLoss()
if(temp)
if (temp < 30)
msg += "[t_He] [t_has] minor burns.\n"
else
msg += "<B>[t_He] [t_has] severe burns!</B>\n"
if(fire_stacks > 0)
msg += "It's covered in something flammable.\n"
if(fire_stacks < 0)
msg += "It's soaked in water.\n"
temp = getCloneLoss()
if(temp)
if(getCloneLoss() < 30)
msg += "[t_He] [t_is] slightly deformed.\n"
else
msg += "<b>[t_He] [t_is] severely deformed.</b>\n"
if(pulledby && pulledby.grab_state)
msg += "It's restrained by [pulledby]'s grip.\n"
if(getBrainLoss() > 60)
msg += "[t_He] seems to be clumsy and unable to think.\n"
if(fire_stacks > 0)
msg += "[t_He] [t_is] covered in something flammable.\n"
if(fire_stacks < 0)
msg += "[t_He] [t_is] looks a little soaked.\n"
if(pulledby && pulledby.grab_state)
msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n"
msg += "</span>"
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
msg += "</span>"
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n"
if(digitalcamo)
msg += "It is moving its body in an unnatural and blatantly unsimian manner.\n"
if(!getorgan(/obj/item/organ/brain))
msg += "<span class='deadsay'>It appears that it's brain is missing...</span>\n"
msg += "*---------*</span>"
user << msg
user << msg
@@ -0,0 +1,5 @@
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
// depending on the species, it will run the corresponding apply_damage code there
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
+7 -17
View File
@@ -4,8 +4,11 @@
/mob/living/carbon/human/dust_animation()
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-h"))
/mob/living/carbon/human/spawn_gibs()
hgibs(loc, viruses, dna)
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
if(with_bodyparts)
new /obj/effect/gibspawner/human(loc, viruses, dna)
else
new /obj/effect/gibspawner/humanbodypartless(loc, viruses, dna)
/mob/living/carbon/human/spawn_dust()
new /obj/effect/decal/remains/human(loc)
@@ -33,29 +36,16 @@
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
. = ..(gibbed)
if(mind && mind.devilinfo)
spawn(0)
mind.devilinfo.beginResurrectionCheck(src)
addtimer(mind.devilinfo, "beginResurrectionCheck", 0, TIMER_NORMAL, src)
/mob/living/carbon/human/proc/makeSkeleton()
status_flags |= DISFIGURED
set_species(/datum/species/skeleton)
return 1
/mob/living/carbon/proc/ChangeToHusk()
if(disabilities & HUSK)
return
disabilities |= HUSK
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
return 1
/mob/living/carbon/human/ChangeToHusk()
. = ..()
if(.)
update_hair()
update_body()
/mob/living/carbon/proc/Drain()
ChangeToHusk()
become_husk()
disabilities |= NOCLONE
blood_volume = 0
return 1
+30 -77
View File
@@ -13,9 +13,8 @@
var/muzzled = is_muzzled()
//var/m_type = 1
for (var/obj/item/weapon/implant/I in src)
if (I.implanted)
I.trigger(act, src)
for (var/obj/item/weapon/implant/I in implants)
I.trigger(act, src)
var/miming=0
if(mind)
@@ -24,12 +23,12 @@
switch(act) //Please keep this alphabetically ordered when adding or changing emotes.
if ("aflap") //Any emote on human that uses miming must be left in, oh well.
if (!src.restrained())
message = "<B>[src]</B> flaps \his wings ANGRILY!"
message = "<B>[src]</B> flaps [p_their()] wings ANGRILY!"
m_type = 2
if ("choke","chokes")
if (miming)
message = "<B>[src]</B> clutches \his throat desperately!"
message = "<B>[src]</B> clutches [p_their()] throat desperately!"
else
..(act)
@@ -45,10 +44,11 @@
m_type = 2
if ("collapse","collapses")
Paralyse(2)
adjustStaminaLoss(100) // Hampers abuse against simple mobs, but still leaves it a viable option.
message = "<B>[src]</B> collapses!"
m_type = 2
if(status_flags & CANPARALYSE) //You can't collapse if you can't actually collapse.
Paralyse(2)
adjustStaminaLoss(100) // Hampers abuse against simple mobs, but still leaves it a viable option.
message = "<B>[src]</B> collapses!"
m_type = 2
if ("cough","coughs")
if (miming)
@@ -69,7 +69,7 @@
message = "<B>[src]</B> cries."
m_type = 2
else
message = "<B>[src]</B> makes a weak noise. \He frowns."
message = "<B>[src]</B> makes a weak noise. [p_they(TRUE)] frown[p_s()]."
m_type = 2
if ("custom")
@@ -120,7 +120,7 @@
if (M)
message = "<B>[src]</B> gives daps to [M]."
else
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps \himself. Shameful."
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps [p_them()]self. Shameful."
if ("eyebrow")
message = "<B>[src]</B> raises an eyebrow."
@@ -128,7 +128,7 @@
if ("flap","flaps")
if (!src.restrained())
message = "<B>[src]</B> flaps \his wings."
message = "<B>[src]</B> flaps [p_their()] wings."
m_type = 2
if(((dna.features["wings"] != "None") && !("wings" in dna.species.mutant_bodyparts)))
OpenWings()
@@ -137,10 +137,10 @@
if ("wings")
if (!src.restrained())
if(dna && dna.species &&((dna.features["wings"] != "None") && ("wings" in dna.species.mutant_bodyparts)))
message = "<B>[src]</B> opens \his wings."
message = "<B>[src]</B> opens [p_their()] wings."
OpenWings()
else if(dna && dna.species &&((dna.features["wings"] != "None") && ("wingsopen" in dna.species.mutant_bodyparts)))
message = "<B>[src]</B> closes \his wings."
message = "<B>[src]</B> closes [p_their()] wings."
CloseWings()
else
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
@@ -177,7 +177,7 @@
if ("handshake")
m_type = 1
if (!src.restrained() && !src.r_hand)
if (!src.restrained() && get_empty_held_indexes())
var/mob/M = null
if (param)
for (var/mob/A in view(1, src))
@@ -187,10 +187,10 @@
if (M == src)
M = null
if (M)
if (M.canmove && !M.r_hand && !M.restrained())
if (M.canmove && M.get_empty_held_indexes() && !M.restrained())
message = "<B>[src]</B> shakes hands with [M]."
else
message = "<B>[src]</B> holds out \his hand to [M]."
message = "<B>[src]</B> holds out [p_their()] hand to [M]."
if ("hug","hugs")
m_type = 1
@@ -206,7 +206,7 @@
if (M)
message = "<B>[src]</B> hugs [M]."
else
message = "<B>[src]</B> hugs \himself."
message = "<B>[src]</B> hugs [p_them()]self."
if ("me")
if(silent)
@@ -259,21 +259,6 @@
message = "<B>[src]</B> raises a hand."
m_type = 1
if ("roar","roars")
if (miming)
message = "<B>[src]</B> appears to roar!"
else
if(!muzzled && has_dna())
m_type = 2
message = "<B>[src]</B> roars!"
switch(dna.species.id)
if("pred")
playsound(get_turf(src), "predroar", 50, 0, 5)
if("xeno")
playsound(get_turf(src), "alienscreech", 50, 0, 5)
else
..(act)
if ("salute","salutes")
if (!src.buckled)
var/M = null
@@ -294,23 +279,6 @@
if (miming)
message = "<B>[src]</B> acts out a scream!"
else
if(has_dna())
switch(dna.species.id) //Visit sound.dm to see and add more 'soundin' options. (alienscreech, malescream, femscream, etc)
if("xeno")
playsound(get_turf(src), "alienscreech", 50, 0, 5)
if("pred")
playsound(get_turf(src), "predroar", 50, 0, 5)
if("moth")
playsound(get_turf(src), "mothscream", 50, 1, 5)
if("lizard" || "drake")
playsound(get_turf(src), "drakescream", 50, 0, 5)
if("avian")
playsound(get_turf(src), "birdscream", 50, 0, 5)
else
if(gender == MALE)
playsound(get_turf(src), "malescream", 50, 0, 5)
if(gender == FEMALE)
playsound(get_turf(src), "femscream", 50, 0, 5)
..(act)
if ("shiver","shivers")
@@ -329,12 +297,16 @@
if ("signal","signals")
if (!src.restrained())
var/maximum_fingers = 10
var/full_hands
for(var/obj/item/I in held_items)
full_hands++
maximum_fingers = (held_items.len-full_hands)*5
var/t1 = round(text2num(param))
if (isnum(t1))
if (t1 <= 5 && (!src.r_hand || !src.l_hand))
message = "<B>[src]</B> raises [t1] finger\s."
else if (t1 <= 10 && (!src.r_hand && !src.l_hand))
if (t1 <= maximum_fingers)
message = "<B>[src]</B> raises [t1] finger\s."
m_type = 1
if ("sneeze","sneezes")
@@ -365,22 +337,16 @@
m_type = 2
if("wag","wags")
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || ((dna.features["mam_tail"] != "None") && !("mam_waggingtail" in dna.species.mutant_bodyparts)) || ((dna.features["tail_human"] != "None") && !("waggingtail_human" in dna.species.mutant_bodyparts))))
message = "<B>[src]</B> wags \his tail."
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || ((dna.features["tail_human"] != "None") && !("waggingtail_human" in dna.species.mutant_bodyparts))))
message = "<B>[src]</B> wags [p_their()] tail."
startTailWag()
else if(dna && dna.species && (("waggingtail_lizard" in dna.species.mutant_bodyparts) || ("mam_waggingtail" in dna.species.mutant_bodyparts) || ("waggingtail_human" in dna.species.mutant_bodyparts)))
else if(dna && dna.species && (("waggingtail_lizard" in dna.species.mutant_bodyparts) || ("waggingtail_human" in dna.species.mutant_bodyparts)))
endTailWag()
else
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
if ("help") //This can stay at the bottom.
if(has_dna(src))
switch(dna.species.id)//Set lists of emotes for specific species. Not the best way to do this, but the easiest considering they'll share most emotes.
if("pred")
src << "Help for yautja emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, <b>roar</b>, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
else
src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
else
..(act)
@@ -397,7 +363,7 @@
// Maybe some people are okay with that.
for(var/mob/M in dead_mob_list)
if(!M.client || istype(M, /mob/new_player))
if(!M.client || isnewplayer(M))
continue //skip monkeys, leavers and new players
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
@@ -422,9 +388,6 @@
if("tail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_human"
dna.species.mutant_bodyparts |= "waggingtail_human"
if("mam_tail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_tail"
dna.species.mutant_bodyparts |= "mam_waggingtail"
update_body()
@@ -439,9 +402,6 @@
if("waggingtail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_human"
dna.species.mutant_bodyparts |= "tail_human"
if("mam_waggingtail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_waggingtail"
dna.species.mutant_bodyparts |= "mam_tail"
update_body()
/mob/living/carbon/human/proc/OpenWings()
@@ -459,10 +419,3 @@
dna.species.mutant_bodyparts -= "wingsopen"
dna.species.mutant_bodyparts |= "wings"
update_body()
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavor Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
flavor_text = copytext(sanitize(input(usr, "Please enter your new flavor text.", "Flavor text", null) as text), 1)
+60 -94
View File
@@ -1,36 +1,17 @@
/mob/living/carbon/human/examine(mob/user)
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
var/t_He = p_they(TRUE)
var/t_His = p_their(TRUE)
var/t_his = p_their()
var/t_him = p_them()
var/t_has = p_have()
var/t_is = p_are()
var/msg = "<span class='info'>*---------*\nThis is <EM>[src.name]</EM>!\n"
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
var/t_He = "It" //capitalised for use at the start of each line.
var/t_his = "its"
var/t_him = "it"
var/t_has = "has"
var/t_is = "is"
var/msg = "<span class='info'>*---------*\nThis is "
if( (slot_w_uniform in obscured) && skipface ) //big suits/masks/helmets make it hard to tell their gender
t_He = "They"
t_his = "their"
t_him = "them"
t_has = "have"
t_is = "are"
else
switch(gender)
if(MALE)
t_He = "He"
t_his = "his"
t_him = "him"
if(FEMALE)
t_He = "She"
t_his = "her"
t_him = "her"
msg += "<EM>[src.name]</EM>!\n"
//uniform
if(w_uniform && !(slot_w_uniform in obscured))
//Ties
@@ -73,19 +54,13 @@
else
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
//left hand
if(l_hand && !(l_hand.flags&ABSTRACT))
if(l_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in [t_his] left hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
//right hand
if(r_hand && !(r_hand.flags&ABSTRACT))
if(r_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in [t_his] right hand!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags & ABSTRACT))
if(I.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
else
msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
//gloves
if(gloves && !(slot_gloves in obscured))
@@ -128,6 +103,9 @@
else
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
if (wear_neck && !(slot_neck in obscured))
msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
//eyes
if(glasses && !(slot_glasses in obscured))
if(glasses.blood_DNA)
@@ -141,16 +119,6 @@
//ID
if(wear_id)
/*var/id
if(istype(wear_id, /obj/item/device/pda))
var/obj/item/device/pda/pda = wear_id
id = pda.owner
else if(istype(wear_id, /obj/item/weapon/card/id)) //just in case something other than a PDA/ID card somehow gets in the ID slot :[
var/obj/item/weapon/card/id/idcard = wear_id
id = idcard.registered_name
if(id && (id != real_name) && (get_dist(src, user) <= 1) && prob(10))
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
else*/
msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n"
//Jitters
@@ -162,20 +130,14 @@
if(100 to 200)
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
if(gender_ambiguous) //someone fucked up a gender reassignment surgery
if (gender == MALE)
msg += "[t_He] has a strange feminine quality to [t_him].\n"
else
msg += "[t_He] has a strange masculine quality to [t_him].\n"
var/appears_dead = 0
if(stat == DEAD || (status_flags & FAKEDEATH))
appears_dead = 1
if(getorgan(/obj/item/organ/brain))//Only perform these checks if there is no brain
if(suiciding)
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
msg += "<span class='warning'>[t_He] appear[p_s()] to have commited suicide... there is no hope of recovery.</span>\n"
if(hellbound)
msg += "<span class='warning'>[t_his] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
msg += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
if(!key)
var/foundghost = 0
@@ -203,12 +165,27 @@
for(var/obj/item/I in BP.embedded_objects)
msg += "<B>[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [BP.name]!</B>\n"
//stores missing limbs
var/l_limbs_missing = 0
var/r_limbs_missing = 0
for(var/t in missing)
if(t=="head")
msg += "<span class='deadsay'><B>[capitalize(t_his)] [parse_zone(t)] is missing!</B><span class='warning'>\n"
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B><span class='warning'>\n"
continue
if(t == "l_arm" || t == "l_leg")
l_limbs_missing++
else if(t == "r_arm" || t == "r_leg")
r_limbs_missing++
msg += "<B>[capitalize(t_his)] [parse_zone(t)] is missing!</B>\n"
if(l_limbs_missing >= 2 && r_limbs_missing == 0)
msg += "[t_He] looks all right now.\n"
else if(l_limbs_missing == 0 && r_limbs_missing >= 2)
msg += "[t_He] really keeps to the left.\n"
else if(l_limbs_missing >= 2 && r_limbs_missing >= 2)
msg += "[t_He] doesn't seem all there.\n"
if(temp)
if(temp < 30)
msg += "[t_He] [t_has] minor bruising.\n"
@@ -246,22 +223,7 @@
msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
else
msg += "[t_He] [t_is] quite chubby.\n"
/*
if( (vore_womb_datum.has_people()||vore_stomach_datum.has_people()) && !(slot_w_uniform in obscured) )
msg += "It seems [t_his] belly is shifting around slighty.\n"
if( (vore_breast_datum.has_people()||vore_breast_datum.digestion_count) && !(slot_w_uniform in obscured) )
msg += "It seems [t_his] breasts are heavy with milk.\n"
if( !(slot_w_uniform in obscured) && (!w_uniform||!(w_uniform.body_parts_covered&GROIN)) )
if(vore_cock_datum.has_people()||vore_cock_datum.digestion_count)
msg += "It looks like [t_his] cock is full.\n"
if(vore_balls_datum.has_people()||vore_balls_datum.digestion_count)
msg += "It looks like [t_his] balls are full.\n"
if(vore_tail_datum.has_people())
msg += "[t_He] has a bulge in [t_his] tail."
if(vore_tail_datum.transfer_factor)
msg += " It moves slowly toward the base."
msg += "\n"
*/
if(blood_volume < BLOOD_VOLUME_SAFE)
msg += "[t_He] [t_has] pale skin.\n"
@@ -276,10 +238,12 @@
if(reagents.has_reagent("teslium"))
msg += "[t_He] is emitting a gentle blue glow!\n"
if(stun_absorption)
msg += "[t_He] is radiating with a soft yellow light!\n" //Used by Vanguard
if(islist(stun_absorption))
for(var/i in stun_absorption)
if(stun_absorption[i]["end_time"] > world.time && stun_absorption[i]["examine_message"])
msg += "[t_He] [t_is][stun_absorption[i]["examine_message"]]\n"
if(drunkenness && !skipface && stat != DEAD) //Drunkenness
if(drunkenness && !skipface && !appears_dead) //Drunkenness
switch(drunkenness)
if(11 to 21)
msg += "[t_He] [t_is] slightly flushed.\n"
@@ -292,7 +256,7 @@
if(61.01 to 91)
msg += "[t_He] looks like a drunken mess.\n"
if(91.01 to INFINITY)
msg += "[t_He] is a shitfaced, slobbering wreck.\n"
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
msg += "</span>"
@@ -304,7 +268,13 @@
if(getorgan(/obj/item/organ/brain))
if(istype(src,/mob/living/carbon/human/interactive))
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
var/mob/living/carbon/human/interactive/auto = src
if(auto.showexaminetext)
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
if(auto.debugexamine)
var/dodebug = auto.doing2string(auto.doing)
var/interestdebug = auto.interest2string(auto.interest)
msg += "<span class='deadsay'>[t_He] [t_is] appears to be [interestdebug] and [dodebug].</span>\n"
else if(!key)
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.</span>\n"
else if(!client)
@@ -313,7 +283,7 @@
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
if(istype(user, /mob/living/carbon/human))
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/cyberimp/eyes/hud)
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH)
@@ -325,18 +295,18 @@
msg += "<a href='?src=\ref[src];hud=1;photo_front=1'>\[Front photo\]</a> "
msg += "<a href='?src=\ref[src];hud=1;photo_side=1'>\[Side photo\]</a><br>"
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/cyberimp/eyes/hud/medical))
var/implant_detect
var/cyberimp_detect
for(var/obj/item/organ/cyberimp/CI in internal_organs)
if(CI.status == ORGAN_ROBOTIC)
implant_detect += "[name] is modified with a [CI.name].<br>"
if(implant_detect)
cyberimp_detect += "[name] is modified with a [CI.name].<br>"
if(cyberimp_detect)
msg += "Detected cybernetic modifications:<br>"
msg += implant_detect
msg += cyberimp_detect
if(R)
var/health = R.fields["p_stat"]
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health]\]</a>"
health = R.fields["m_stat"]
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health]\]</a><br>"
var/health_r = R.fields["p_stat"]
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health_r]\]</a>"
health_r = R.fields["m_stat"]
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health_r]\]</a><br>"
R = find_record("name", perpname, data_core.medical)
if(R)
msg += "<a href='?src=\ref[src];hud=m;evaluation=1'>\[Medical evaluation\]</a><br>"
@@ -356,10 +326,6 @@
msg += "<a href='?src=\ref[src];hud=s;add_crime=1'>\[Add crime\]</a> "
msg += "<a href='?src=\ref[src];hud=s;view_comment=1'>\[View comment log\]</a> "
msg += "<a href='?src=\ref[src];hud=s;add_comment=1'>\[Add comment\]</a>\n"
if(print_flavor_text() && get_visible_name() != "Unknown")//Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
msg += "[print_flavor_text()]\n"
msg += "*---------*</span>"
user << msg
+106 -259
View File
@@ -3,7 +3,7 @@
real_name = "Unknown"
voice_name = "Unknown"
icon = 'icons/mob/human.dmi'
icon_state = "caucasian1_m_s"
icon_state = "caucasian_m_s"
@@ -18,11 +18,7 @@
verbs += /mob/living/proc/lay_down
//initialize limbs first
bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
for(var/X in bodyparts)
var/obj/item/bodypart/O = X
O.owner = src
create_bodyparts()
//initialize dna. for spawned humans; overwritten by other code
create_dna(src)
@@ -33,21 +29,7 @@
set_species(dna.species.type)
//initialise organs
if(!(NOHUNGER in dna.species.specflags))
internal_organs += new /obj/item/organ/appendix
if(!(NOBREATH in dna.species.specflags))
internal_organs += new /obj/item/organ/lungs
if(!(NOBLOOD in dna.species.specflags))
internal_organs += new /obj/item/organ/heart
internal_organs += new /obj/item/organ/brain
//Note: Additional organs are generated/replaced on the dna.species level
for(var/obj/item/organ/I in internal_organs)
I.Insert(src)
create_internal_organs()
martial_art = default_martial_art
@@ -55,6 +37,19 @@
..()
/mob/living/carbon/human/create_internal_organs()
if(!(NOHUNGER in dna.species.species_traits))
internal_organs += new /obj/item/organ/appendix
if(!(NOBREATH in dna.species.species_traits))
if(dna.species.mutantlungs)
internal_organs += new dna.species.mutantlungs()
else
internal_organs += new /obj/item/organ/lungs()
if(!(NOBLOOD in dna.species.species_traits))
internal_organs += new /obj/item/organ/heart
internal_organs += new /obj/item/organ/brain
..()
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
@@ -81,6 +76,11 @@
stat("Internal Atmosphere Info", internal.name)
stat("Tank Pressure", internal.air_contents.return_pressure())
stat("Distribution Pressure", internal.distribute_pressure)
var/mob/living/simple_animal/borer/B = has_brain_worms()
if(B && B.controlling)
stat("Chemicals", B.chemicals)
if(mind)
if(mind.changeling)
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
@@ -116,94 +116,17 @@
stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]")
/mob/living/carbon/human/ex_act(severity, ex_target)
var/b_loss = null
var/f_loss = null
var/bomb_armor = getarmor(null, "bomb")
switch (severity)
if (1)
b_loss += 500
if (prob(bomb_armor))
shred_clothing(1,150)
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
throw_at(target, 200, 4)
else
gib()
return
if (2)
b_loss += 60
f_loss += 60
if (prob(bomb_armor))
b_loss = b_loss/1.5
f_loss = f_loss/1.5
shred_clothing(1,25)
else
shred_clothing(1,50)
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(30, 120)
if (prob(70))
Paralyse(10)
if(3)
b_loss += 30
if (prob(bomb_armor))
b_loss = b_loss/2
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(15,60)
if (prob(50))
Paralyse(10)
take_overall_damage(b_loss,f_loss)
//attempt to dismember bodyparts
if(severity <= 2 || !bomb_armor)
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest")
BP.brute_dam = BP.max_damage
BP.dismember()
max_limb_loss--
if(!max_limb_loss)
break
..()
/mob/living/carbon/human/blob_act(obj/effect/blob/B)
if(stat == DEAD)
return
show_message("<span class='userdanger'>The blob attacks you!</span>")
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
return
/mob/living/carbon/human/bullet_act()
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(!prob(martial_art.deflection_chance))
return ..()
if(!src.lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
src.visible_message("<span class='danger'>[src] deflects the projectile; they can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
return 0
..()
/mob/living/carbon/human/attack_ui(slot)
if(!get_bodypart(hand ? "l_arm" : "r_arm"))
return 0
return ..()
/mob/living/carbon/human/show_inv(mob/user)
user.set_machine(src)
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
var/list/obscured = check_obscured_slots()
var/list/dat = list()
var/dat = {"<table>
<tr><td><B>Left Hand:</B></td><td><A href='?src=\ref[src];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td><B>Right Hand:</B></td><td><A href='?src=\ref[src];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
<tr><td>&nbsp;</td></tr>"}
dat += "<table>"
for(var/i in 1 to held_items.len)
var/obj/item/I = get_item_for_held_index(i)
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
dat += "<tr><td>&nbsp;</td></tr>"
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
if(has_breathable_mask && istype(back, /obj/item/weapon/tank))
@@ -218,6 +141,11 @@
else
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=\ref[src];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
if(slot_neck in obscured)
dat += "<tr><td><font color=grey><B>Neck:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=\ref[src];item=[slot_neck]'>[(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
if(slot_glasses in obscured)
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
else
@@ -277,7 +205,7 @@
"}
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 510)
popup.set_content(dat)
popup.set_content(dat.Join())
popup.open()
// called when something steps onto a human
@@ -289,35 +217,6 @@
spreadFire(AM)
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0)
if(tesla_shock)
var/total_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(G.siemens_coefficient <= 0)
total_coeff -= 0.5
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
siemens_coeff = total_coeff
else if(!safety)
var/gloves_siemens_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
if(heart_attack)
if(shock_damage * siemens_coeff >= 1 && prob(25))
heart_attack = 0
if(stat == CONSCIOUS)
src << "<span class='notice'>You feel your heart beating again!</span>"
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock)
if(.)
electrocution_animation(40)
/mob/living/carbon/human/Topic(href, href_list)
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
@@ -333,8 +232,8 @@
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
return
L.embedded_objects -= I
L.take_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
I.loc = get_turf(src)
L.receive_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
I.forceMove(get_turf(src))
usr.put_in_hands(I)
usr.emote("scream")
usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","<span class='notice'>You successfully remove [I] from your [L.name].</span>")
@@ -352,14 +251,14 @@
var/pocket_side = href_list["pockets"]
var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store)
var/obj/item/pocket_item = (pocket_id == slot_r_store ? r_store : l_store)
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty
var/delay_denominator = 1
if(pocket_item && !(pocket_item.flags&ABSTRACT))
if(pocket_item.flags & NODROP)
usr << "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>"
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1) && !(place_item.flags&ABSTRACT))
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags&ABSTRACT))
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
delay_denominator = 4
else
@@ -382,13 +281,11 @@
src << "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>"
..()
else
..()
///////HUDs///////
if(href_list["hud"])
if(istype(usr, /mob/living/carbon/human))
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
var/perpname = get_face_name(get_id_name(""))
if(istype(H.glasses, /obj/item/clothing/glasses/hud))
@@ -410,24 +307,24 @@
if(href_list["hud"] == "m")
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
if(href_list["p_stat"])
var/health = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
if(R)
if(!H.canUseHUD())
return
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health))
return
if(health && health != "Cancel")
R.fields["p_stat"] = health
if(health_status && health_status != "Cancel")
R.fields["p_stat"] = health_status
return
if(href_list["m_stat"])
var/health = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
if(R)
if(!H.canUseHUD())
return
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health))
return
if(health && health != "Cancel")
R.fields["m_stat"] = health
if(health_status && health_status != "Cancel")
R.fields["m_stat"] = health_status
return
if(href_list["evaluation"])
if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20)
@@ -588,7 +485,7 @@
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1,)
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1)
usr << "<span class='notice'>Successfully added comment.</span>"
return
usr << "<span class='warning'>Unable to locate a data core entry for this person.</span>"
@@ -600,7 +497,7 @@
. = 1 // Default to returning true.
if(user && !target_zone)
target_zone = user.zone_selected
if(dna && (PIERCEIMMUNE in dna.species.specflags))
if(dna && (PIERCEIMMUNE in dna.species.species_traits))
. = 0
// If targeting the head, see if the head item is thin enough.
// If targeting anything else, see if the wear suit is thin enough.
@@ -612,7 +509,7 @@
. = 0
if(!. && error_msg && user)
// Might need re-wording.
user << "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on their head" : "on their body"].</span>"
user << "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on [p_their()] head" : "on [p_their()] body"].</span>"
/mob/living/carbon/human/proc/check_obscured_slots()
var/list/obscured = list()
@@ -637,7 +534,7 @@
if(wear_mask.flags_inv & HIDEEYES)
obscured |= slot_glasses
if(obscured.len > 0)
if(obscured.len)
return obscured
else
return null
@@ -653,7 +550,7 @@
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
if(istype(wear_suit, /obj/item/clothing/suit/redtag))
threatcount += 4
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
threatcount += 4
if(istype(belt, /obj/item/weapon/gun/energy/laser/redtag))
threatcount += 2
@@ -661,7 +558,7 @@
if(lasercolor == "r")
if(istype(wear_suit, /obj/item/clothing/suit/bluetag))
threatcount += 4
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
threatcount += 4
if(istype(belt, /obj/item/weapon/gun/energy/laser/bluetag))
threatcount += 2
@@ -676,10 +573,9 @@
//Check for weapons
if(judgebot.weaponscheck)
if(!idcard || !(access_weapons in idcard.access))
if(judgebot.check_for_weapons(l_hand))
threatcount += 4
if(judgebot.check_for_weapons(r_hand))
threatcount += 4
for(var/obj/item/I in held_items)
if(judgebot.check_for_weapons(I))
threatcount += 4
if(judgebot.check_for_weapons(belt))
threatcount += 2
@@ -697,23 +593,22 @@
threatcount += 2
//Check for dresscode violations
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/syndicate) || istype(head, /obj/item/clothing/head/culthood))
threatcount += 5
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
threatcount += 2
//Check for nonhuman scum
if(dna && dna.species.id && dna.species.id != "human")
threatcount += 0
threatcount += 1
//Loyalty implants imply trustworthyness
if(isloyal(src))
//mindshield implants imply trustworthyness
if(isloyal())
threatcount -= 1
//Agent cards lower threatlevel, but only just enough to avoid dresscode violations.
//Agent cards lower threatlevel.
if(istype(idcard, /obj/item/weapon/card/id/syndicate))
threatcount -= 2
threatcount -= 5
return threatcount
return threatcount
//Used for new human mobs created by cloning/goleming/podding
@@ -727,21 +622,9 @@
update_body()
update_hair()
/mob/living/carbon/human/singularity_act()
var/gain = 20
if(mind)
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
gain = 100
if(mind.assigned_role == "Clown")
gain = rand(-300, 300)
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
gib()
return(gain)
/mob/living/carbon/human/singularity_pull(S, current_size)
if(current_size >= STAGE_THREE)
var/list/handlist = list(l_hand, r_hand)
for(var/obj/item/hand in handlist)
for(var/obj/item/hand in held_items)
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
step_towards(hand, src)
src << "<span class='warning'>\The [S] pulls \the [hand] from your grip!</span>"
@@ -750,71 +633,6 @@
return
..()
/mob/living/carbon/human/help_shake_act(mob/living/carbon/M)
if(!istype(M))
return
if(health >= 0)
if(src == M)
visible_message( \
"[src] examines \himself.", \
"<span class='notice'>You check yourself for injuries.</span>")
var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg")
for(var/X in bodyparts)
var/obj/item/bodypart/LB = X
missing -= LB.body_zone
var/status = ""
var/brutedamage = LB.brute_dam
var/burndamage = LB.burn_dam
if(hallucination)
if(prob(30))
brutedamage += rand(30,40)
if(prob(30))
burndamage += rand(30,40)
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
status += " and "
if(burndamage > 40)
status += "peeling away"
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
status += "numb"
if(status == "")
status = "OK"
src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]."
for(var/obj/item/I in LB.embedded_objects)
src << "\t <a href='byond://?src=\ref[src];embedded_object=\ref[I];embedded_limb=\ref[LB]'>\red There is \a [I] embedded in your [LB.name]!</a>"
for(var/t in missing)
src << "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>"
if(bleed_rate)
src << "<span class='danger'>You are bleeding!</span>"
if(staminaloss)
if(staminaloss > 30)
src << "<span class='info'>You're completely exhausted.</span>"
else
src << "<span class='info'>You feel fatigued.</span>"
else
if(wear_suit)
wear_suit.add_fingerprint(M)
else if(w_uniform)
w_uniform.add_fingerprint(M)
..()
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
CHECK_DNA_AND_SPECIES(C)
@@ -825,7 +643,7 @@
src << "<span class='warning'>Remove your mask first!</span>"
return 0
if(C.is_mouth_covered())
src << "<span class='warning'>Remove their mask first!</span>"
src << "<span class='warning'>Remove [p_their()] mask first!</span>"
return 0
if(C.cpr_time < world.time + 30)
@@ -835,10 +653,10 @@
src << "<span class='warning'>You fail to perform CPR on [C]!</span>"
return 0
var/they_breathe = (!(NOBREATH in C.dna.species.specflags))
var/they_breathe = (!(NOBREATH in C.dna.species.species_traits))
var/they_lung = C.getorganslot("lungs")
if(C.health > config.health_threshold_crit)
if(C.health > HEALTH_THRESHOLD_CRIT)
return
src.visible_message("[src] performs CPR on [C.name]!", "<span class='notice'>You perform CPR on [C.name].</span>")
@@ -907,10 +725,11 @@
/mob/living/carbon/human/proc/electrocution_animation(anim_duration)
//Handle mutant parts if possible
if(dna && dna.species)
add_overlay("electrocuted_base")
spawn(anim_duration)
if(src)
overlays -= "electrocuted_base"
add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY)
var/static/image/electrocution_skeleton_anim = image(icon = icon, icon_state = "electrocuted_base")
electrocution_skeleton_anim.appearance_flags = RESET_COLOR
add_overlay(electrocution_skeleton_anim)
addtimer(src, "end_electrocution_animation", anim_duration, TIMER_NORMAL, electrocution_skeleton_anim)
else //or just do a generic animation
var/list/viewing = list()
@@ -919,6 +738,10 @@
viewing += M.client
flick_overlay(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), viewing, anim_duration)
/mob/living/carbon/human/proc/end_electrocution_animation(image/I)
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
overlays -= I
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0)
if(incapacitated() || lying )
return
@@ -1004,16 +827,15 @@
hud_used.healthdoll.icon_state = "healthdoll_DEAD"
/mob/living/carbon/human/fully_heal(admin_revive = 0)
CHECK_DNA_AND_SPECIES(src)
if(admin_revive)
regenerate_limbs()
if(!(NOBREATH in dna.species.specflags) && !getorganslot("lungs"))
if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs"))
var/obj/item/organ/lungs/L = new()
L.Insert(src)
if(!(NOBLOOD in dna.species.specflags) && !getorganslot("heart"))
if(!(NOBLOOD in dna.species.species_traits) && !getorganslot("heart"))
var/obj/item/organ/heart/H = new()
H.Insert(src)
@@ -1063,12 +885,7 @@
O = new /datum/objective/sintouched/pride
ticker.mode.sintouched += src.mind
src.mind.objectives += O
var/obj_count = 1
src << "<span class='notice'>Your current objectives:</span>"
for(O in src.mind.objectives)
var/datum/objective/objective = O
src << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
src.mind.announce_objectives()
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
. = ..()
@@ -1078,6 +895,36 @@
/mob/living/carbon/human/is_literate()
return 1
/mob/living/carbon/human/can_hold_items()
return TRUE
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
override = dna.species.override_float
..()
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
if(blood && (NOBLOOD in dna.species.species_traits))
if(message)
visible_message("<span class='warning'>[src] dry heaves!</span>", \
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
if(stun)
Weaken(10)
return 1
..()
/mob/living/carbon/human/Bump(atom/A)
..()
var/crashdir = get_dir(src, A)
var/obj/item/device/flightpack/FP = get_flightpack()
if(FP)
FP.flight_impact(A, crashdir)
/mob/living/carbon/human/vv_get_dropdown()
. = ..()
. += "---"
.["Make monkey"] = "?_src_=vars;makemonkey=\ref[src]"
.["Set Species"] = "?_src_=vars;setspecies=\ref[src]"
.["Make cyborg"] = "?_src_=vars;makerobot=\ref[src]"
.["Make alien"] = "?_src_=vars;makealien=\ref[src]"
.["Make slime"] = "?_src_=vars;makeslime=\ref[src]"
.["Toggle Purrbation"] = "?_src_=vars;purrbation=\ref[src]"
@@ -1,49 +0,0 @@
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
if(check_shields(0, M.name))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return 0
if(..())
if(M.a_intent == "harm")
if (w_uniform)
w_uniform.add_fingerprint(M)
var/damage = prob(90) ? 20 : 0
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
"<span class='userdanger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
var/armor_block = run_armor_check(affecting, "melee","","",10)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
apply_damage(damage, BRUTE, affecting, armor_block)
if (prob(30))
visible_message("<span class='danger'>[M] has wounded [src]!</span>", \
"<span class='userdanger'>[M] has wounded [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
add_logs(M, src, "attacked")
updatehealth()
if(M.a_intent == "disarm")
var/randn = rand(1, 100)
if (randn <= 80)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
Weaken(5)
add_logs(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
else
if (randn <= 99)
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
drop_item()
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>", \
"<span class='userdanger'>[M] has tried to disarm [src]!</span>")
return
@@ -1,14 +0,0 @@
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user)
if(user.a_intent == "harm")
..(user, 1)
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
var/hulk_verb = pick("smash","pummel")
visible_message("<span class='danger'>[user] has [hulk_verb]ed [src]!</span>", \
"<span class='userdanger'>[user] has [hulk_verb]ed [src]!</span>")
adjustBruteLoss(15)
return 1
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
if(..()) //to allow surgery to return properly.
return
dna.species.spec_attack_hand(M, src)
@@ -1,15 +0,0 @@
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(M.a_intent == "help")
..() //shaking
return 0
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
if(..()) //successful monkey bite, this handles disease contraction.
var/damage = rand(1, 3)
if(stat != DEAD)
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
updatehealth()
return 1
@@ -1,161 +0,0 @@
//Updates the mob's health from bodyparts and mob damage variables
/mob/living/carbon/human/updatehealth()
if(status_flags & GODMODE)
return
var/total_burn = 0
var/total_brute = 0
for(var/X in bodyparts) //hardcoded to streamline things a bit
var/obj/item/bodypart/BP = X
total_brute += BP.brute_dam
total_burn += BP.burn_dam
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
update_stat()
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD )
ChangeToHusk()
if(on_fire)
shred_clothing()
med_hud_set_health()
med_hud_set_status()
//These procs fetch a cumulative total damage from all bodyparts
/mob/living/carbon/human/getBruteLoss()
var/amount = 0
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
amount += BP.brute_dam
return amount
/mob/living/carbon/human/getFireLoss()
var/amount = 0
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
amount += BP.burn_dam
return amount
/mob/living/carbon/human/adjustBruteLoss(amount)
if(status_flags & GODMODE)
return 0
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0)
/mob/living/carbon/human/adjustFireLoss(amount)
if(status_flags & GODMODE)
return 0
if(amount > 0)
take_overall_damage(0, amount)
else
heal_overall_damage(0, -amount)
/mob/living/carbon/human/proc/hat_fall_prob()
var/multiplier = 1
var/obj/item/clothing/head/H = head
var/loose = 40
if(stat || (status_flags & FAKEDEATH))
multiplier = 2
if(H.flags_cover & (HEADCOVERSEYES | HEADCOVERSMOUTH) || H.flags_inv & (HIDEEYES | HIDEFACE))
loose = 0
return loose * multiplier
////////////////////////////////////////////
//Returns a list of damaged bodyparts
/mob/living/carbon/human/proc/get_damaged_bodyparts(brute, burn)
var/list/obj/item/bodypart/parts = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
parts += BP
return parts
//Returns a list of damageable bodyparts
/mob/living/carbon/human/proc/get_damageable_bodyparts()
var/list/obj/item/bodypart/parts = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
parts += BP
return parts
//Heals ONE external organ, organ gets randomly selected from damaged ones.
//It automatically updates damage overlays if necesary
//It automatically updates health status
/mob/living/carbon/human/heal_organ_damage(brute, burn)
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
if(!parts.len)
return
var/obj/item/bodypart/picked = pick(parts)
if(picked.heal_damage(brute,burn,0))
update_damage_overlays(0)
updatehealth()
//Damages ONE external organ, organ gets randomly selected from damagable ones.
//It automatically updates damage overlays if necesary
//It automatically updates health status
/mob/living/carbon/human/take_organ_damage(brute, burn)
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
if(!parts.len)
return
var/obj/item/bodypart/picked = pick(parts)
if(picked.take_damage(brute,burn))
update_damage_overlays(0)
updatehealth()
//Heal MANY bodyparts, in random order
/mob/living/carbon/human/heal_overall_damage(brute, burn, updating_health=1)
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/obj/item/bodypart/picked = pick(parts)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.heal_damage(brute,burn,0)
brute -= (brute_was-picked.brute_dam)
burn -= (burn_was-picked.burn_dam)
parts -= picked
if(updating_health)
updatehealth()
if(update)
update_damage_overlays(0)
// damage MANY bodyparts, in random order
/mob/living/carbon/human/take_overall_damage(brute, burn)
if(status_flags & GODMODE)
return //godmode
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/obj/item/bodypart/picked = pick(parts)
var/brute_per_part = brute/parts.len
var/burn_per_part = burn/parts.len
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.take_damage(brute_per_part,burn_per_part)
brute -= (picked.brute_dam - brute_was)
burn -= (picked.burn_dam - burn_was)
parts -= picked
updatehealth()
if(update)
update_damage_overlays(0)
////////////////////////////////////////////
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
// depending on the species, it will run the corresponding apply_damage code there
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
@@ -17,8 +17,8 @@
return (armorval/max(organnum, 1))
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, type)
if(!type)
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type)
if(!d_type)
return 0
var/protection = 0
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
@@ -28,13 +28,44 @@
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & def_zone.body_part)
protection += C.armor[type]
protection += C.armor[d_type]
return protection
/mob/living/carbon/human/on_hit(proj_type)
dna.species.on_hit(proj_type, src)
///checkeyeprot()
///Returns a number between -1 to 2
/mob/living/carbon/human/get_eye_protection()
var/number = ..()
if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head
var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item
number += HFP.flash_protect
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
var/obj/item/clothing/glasses/GFP = src.glasses
number += GFP.flash_protect
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
var/obj/item/clothing/mask/MFP = src.wear_mask
number += MFP.flash_protect
return number
/mob/living/carbon/human/get_ear_protection()
if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
return 1
/mob/living/carbon/human/on_hit(obj/item/projectile/P)
dna.species.on_hit(P, src)
/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone)
var/spec_return = dna.species.bullet_act(P, src)
if(spec_return)
return spec_return
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
return 0
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
if(check_reflect(def_zone)) // Checks if you've passed a reflection% check
@@ -60,31 +91,26 @@
if(check_shields(P.damage, "the [P.name]", P, PROJECTILE_ATTACK, P.armour_penetration))
P.on_hit(src, 100, def_zone)
return 2
return (..(P , def_zone))
/mob/living/carbon/human/proc/check_reflect(def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object
if(wear_suit)
if(wear_suit.IsReflect(def_zone) == 1)
return 1
if(l_hand)
if(l_hand.IsReflect(def_zone) == 1)
return 1
if(r_hand)
if(r_hand.IsReflect(def_zone) == 1)
for(var/obj/item/I in held_items)
if(I.IsReflect(def_zone) == 1)
return 1
return 0
/mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", atom/movable/AM, attack_type = MELEE_ATTACK, armour_penetration = 0)
var/block_chance_modifier = round(damage / -3)
if(l_hand && !istype(l_hand, /obj/item/clothing))
var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
return 1
if(r_hand && !istype(r_hand, /obj/item/clothing))
var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
return 1
for(var/obj/item/I in held_items)
if(!istype(I, /obj/item/clothing))
var/final_block_chance = I.block_chance - (Clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(I.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
return 1
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
@@ -95,252 +121,17 @@
return 1
return 0
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user)
if(!I || !user)
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected))
var/target_area = parse_zone(check_zone(user.zone_selected))
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
feedback_add_details("zone_targeted","[target_area]")
// the attacked_by code varies among species
return dna.species.spec_attacked_by(I, user, affecting, a_intent, target_area, src)
/mob/living/carbon/human/emp_act(severity)
var/informed = 0
for(var/obj/item/bodypart/L in src.bodyparts)
if(L.status == ORGAN_ROBOTIC)
if(!informed)
src << "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>"
informed = 1
switch(severity)
if(1)
L.take_damage(0,10)
src.Stun(10)
if(2)
L.take_damage(0,5)
src.Stun(5)
..()
/mob/living/carbon/human/acid_act(acidpwr, toxpwr, acid_volume)
var/list/damaged = list()
var/list/inventory_items_to_kill = list()
var/acidity = min(acidpwr*acid_volume/200, toxpwr)
var/acid_volume_left = acid_volume
var/acid_decay = 100/acidpwr // how much volume we lose per item we try to melt. 5 for fluoro, 10 for sulphuric
//HEAD//
var/obj/item/clothing/head_clothes = null
if(glasses)
head_clothes = glasses
if(wear_mask)
head_clothes = wear_mask
if(head)
head_clothes = head
if(head_clothes)
if(!head_clothes.unacidable)
head_clothes.acid_act(acidpwr, acid_volume_left)
acid_volume_left = max(acid_volume_left - acid_decay, 0) //We remove some of the acid volume.
update_inv_glasses()
update_inv_wear_mask()
update_inv_head()
else
src << "<span class='notice'>Your [head_clothes.name] protects your head and face from the acid!</span>"
else
. = get_bodypart("head")
if(.)
damaged += .
if(ears)
inventory_items_to_kill += ears
//CHEST//
var/obj/item/clothing/chest_clothes = null
if(w_uniform)
chest_clothes = w_uniform
if(wear_suit)
chest_clothes = wear_suit
if(chest_clothes)
if(!chest_clothes.unacidable)
chest_clothes.acid_act(acidpwr, acid_volume_left)
acid_volume_left = max(acid_volume_left - acid_decay, 0)
update_inv_w_uniform()
update_inv_wear_suit()
else
src << "<span class='notice'>Your [chest_clothes.name] protects your body from the acid!</span>"
else
. = get_bodypart("chest")
if(.)
damaged += .
if(wear_id)
inventory_items_to_kill += wear_id
if(r_store)
inventory_items_to_kill += r_store
if(l_store)
inventory_items_to_kill += l_store
if(s_store)
inventory_items_to_kill += s_store
//ARMS & HANDS//
var/obj/item/clothing/arm_clothes = null
if(gloves)
arm_clothes = gloves
if(w_uniform && (w_uniform.body_parts_covered & HANDS) || w_uniform && (w_uniform.body_parts_covered & ARMS))
arm_clothes = w_uniform
if(wear_suit && (wear_suit.body_parts_covered & HANDS) || wear_suit && (wear_suit.body_parts_covered & ARMS))
arm_clothes = wear_suit
if(arm_clothes)
if(!arm_clothes.unacidable)
arm_clothes.acid_act(acidpwr, acid_volume_left)
acid_volume_left = max(acid_volume_left - acid_decay, 0)
update_inv_gloves()
update_inv_w_uniform()
update_inv_wear_suit()
else
src << "<span class='notice'>Your [arm_clothes.name] protects your arms and hands from the acid!</span>"
else
. = get_bodypart("r_arm")
if(.)
damaged += .
. = get_bodypart("l_arm")
if(.)
damaged += .
//LEGS & FEET//
var/obj/item/clothing/leg_clothes = null
if(shoes)
leg_clothes = shoes
if(w_uniform && (w_uniform.body_parts_covered & FEET) || w_uniform && (w_uniform.body_parts_covered & LEGS))
leg_clothes = w_uniform
if(wear_suit && (wear_suit.body_parts_covered & FEET) || wear_suit && (wear_suit.body_parts_covered & LEGS))
leg_clothes = wear_suit
if(leg_clothes)
if(!leg_clothes.unacidable)
leg_clothes.acid_act(acidpwr, acid_volume_left)
acid_volume_left = max(acid_volume_left - acid_decay, 0)
update_inv_shoes()
update_inv_w_uniform()
update_inv_wear_suit()
else
src << "<span class='notice'>Your [leg_clothes.name] protects your legs and feet from the acid!</span>"
else
. = get_bodypart("r_leg")
if(.)
damaged += .
. = get_bodypart("l_leg")
if(.)
damaged += .
//DAMAGE//
for(var/obj/item/bodypart/affecting in damaged)
affecting.take_damage(acidity, 2*acidity)
if(affecting.name == "head")
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
affecting.take_damage(acidity, 2*acidity)
emote("scream")
facial_hair_style = "Shaved"
hair_style = "Bald"
update_hair()
status_flags |= DISFIGURED
update_damage_overlays()
//MELTING INVENTORY ITEMS//
//these items are all outside of armour visually, so melt regardless.
if(back)
inventory_items_to_kill += back
if(belt)
inventory_items_to_kill += belt
if(r_hand)
inventory_items_to_kill += r_hand
if(l_hand)
inventory_items_to_kill += l_hand
for(var/obj/item/I in inventory_items_to_kill)
I.acid_act(acidpwr, acid_volume_left)
acid_volume_left = max(acid_volume_left - acid_decay, 0)
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
return 0
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
var/armor = run_armor_check(affecting, "melee")
apply_damage(damage, M.melee_damage_type, affecting, armor, "", "", M.armour_penetration)
updatehealth()
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(check_shields(damage, "the [L.name]"))
return 0
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
updatehealth()
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime attack
var/damage = rand(5, 25)
if(M.is_adult)
damage = rand(10, 35)
if(check_shields(damage, "the [M.name]"))
return 0
var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == "harm")
M.do_attack_animation(src)
if(M.damtype == "brute")
step_away(src,M,15)
var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head"))
if(temp)
var/update = 0
switch(M.damtype)
if("brute")
if(M.force > 20)
Paralyse(1)
update |= temp.take_damage(rand(M.force/2, M.force), 0)
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
if("fire")
update |= temp.take_damage(0, rand(M.force/2, M.force))
playsound(src, 'sound/items/Welder.ogg', 50, 1)
if("tox")
M.mech_toxin_damage(src)
else
return
if(update)
update_damage_overlays(0)
updatehealth()
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
"<span class='userdanger'>[M.name] has hit [src]!</span>")
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
else
..()
/mob/living/carbon/human/proc/check_block()
if(martial_art && martial_art.block_chance \
&& prob(martial_art.block_chance) && in_throw_mode \
&& !stat && !weakened && !stunned)
return TRUE
return FALSE
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
var/spec_return = dna.species.spec_hitby(AM, src)
if(spec_return)
return spec_return
var/obj/item/I
var/throwpower = 30
if(istype(AM, /obj/item))
@@ -355,13 +146,13 @@
else if(I)
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
if(can_embed(I))
if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.specflags)))
if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.species_traits)))
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
var/obj/item/bodypart/L = pick(bodyparts)
L.embedded_objects |= I
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
I.loc = src
L.take_damage(I.w_class*I.embedded_impact_pain_multiplier)
L.receive_damage(I.w_class*I.embedded_impact_pain_multiplier)
visible_message("<span class='danger'>\the [I.name] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>\the [I.name] embeds itself in your [L.name]!</span>")
hitpush = 0
skipcatch = 1 //can't catch the now embedded item
@@ -369,8 +160,8 @@
return ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && iscarbon(pulling))
vore_attack(user, pulling)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (disabilities & FAT) && ismonkey(pulling))
devour_mob(pulling)
else
..()
@@ -379,6 +170,574 @@
w_uniform.add_fingerprint(user)
..()
/mob/living/carbon/human/Stun(amount, updating_canmove = 1)
amount = dna.species.spec_stun(src,amount)
..()
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user)
if(!I || !user)
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected)) //what we're actually ending up trying to hit.
var/target_area = parse_zone(check_zone(user.zone_selected)) //our intended target
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
feedback_add_details("zone_targeted","[target_area]")
// the attacked_by code varies among species
return dna.species.spec_attacked_by(I, user, affecting, a_intent, src)
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
var/hulk_verb = pick("smash","pummel")
if(check_shields(15, "the [hulk_verb]ing"))
return
..(user, 1)
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
var/message = "[user] has [hulk_verb]ed [src]!"
visible_message("<span class='danger'>[message]</span>", \
"<span class='userdanger'>[message]</span>")
adjustBruteLoss(15)
damage_clothes(15, BRUTE, "melee")
return 1
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
if(..()) //to allow surgery to return properly.
return
dna.species.spec_attack_hand(M, src)
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart("chest")
if(M.a_intent == INTENT_HELP)
..() //shaking
return 0
if(M.limb_destroyer)
dismembering_strike(M, affecting.body_zone)
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
if(..()) //successful monkey bite, this handles disease contraction.
var/damage = rand(1, 3)
if(check_shields(damage))
return 0
if(stat != DEAD)
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
return 1
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
if(check_shields(0, M.name))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return 0
if(..())
if(M.a_intent == INTENT_HARM)
if (w_uniform)
w_uniform.add_fingerprint(M)
var/damage = prob(90) ? 20 : 0
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
"<span class='userdanger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
if(!affecting)
affecting = get_bodypart("chest")
var/armor_block = run_armor_check(affecting, "melee","","",10)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
add_logs(M, src, "attacked")
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
return 1
apply_damage(damage, BRUTE, affecting, armor_block)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead.
if(get_active_held_item() && drop_item())
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
Weaken(5)
add_logs(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(check_shields(damage, "the [L.name]"))
return 0
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
if(!affecting)
affecting = get_bodypart("chest")
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
return 0
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart("chest")
var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration)
apply_damage(damage, M.melee_damage_type, affecting, armor)
damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone)
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime attack
var/damage = rand(5, 25)
if(M.is_adult)
damage = rand(10, 35)
if(check_shields(damage, "the [M.name]"))
return 0
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart("chest")
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == INTENT_HARM)
M.do_attack_animation(src)
if(M.damtype == "brute")
step_away(src,M,15)
var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head"))
if(temp)
var/update = 0
var/dmg = rand(M.force/2, M.force)
switch(M.damtype)
if("brute")
if(M.force > 20)
Paralyse(1)
update |= temp.receive_damage(dmg, 0)
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
damage_clothes(dmg, BRUTE, "melee", temp.body_zone)
if("fire")
update |= temp.receive_damage(0, dmg)
playsound(src, 'sound/items/Welder.ogg', 50, 1)
damage_clothes(dmg, BURN, "melee", temp.body_zone)
if("tox")
M.mech_toxin_damage(src)
else
return
if(update)
update_damage_overlays()
updatehealth()
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
else
..()
/mob/living/carbon/human/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
return
..()
var/b_loss = 0
var/f_loss = 0
var/bomb_armor = getarmor(null, "bomb")
switch (severity)
if (1)
if(prob(bomb_armor))
b_loss = 500
var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
throw_at(throw_target, 200, 4)
damage_clothes(400 - bomb_armor, BRUTE, "bomb")
else
gib()
return
if (2)
b_loss = 60
f_loss = 60
if(bomb_armor)
b_loss = 30*(2 - round(bomb_armor*0.01, 0.05))
f_loss = b_loss
damage_clothes(200 - bomb_armor, BRUTE, "bomb")
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(30, 120)
if (prob(70))
Paralyse(10)
if(3)
b_loss = 30
if(bomb_armor)
b_loss = 15*(2 - round(bomb_armor*0.01, 0.05))
damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb")
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
adjustEarDamage(15,60)
if (prob(50))
Paralyse(8)
take_overall_damage(b_loss,f_loss)
//attempt to dismember bodyparts
if(severity <= 2 || !bomb_armor)
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest")
BP.brute_dam = BP.max_damage
BP.dismember()
max_limb_loss--
if(!max_limb_loss)
break
/mob/living/carbon/human/blob_act(obj/structure/blob/B)
if(stat == DEAD)
return
show_message("<span class='userdanger'>The blob attacks you!</span>")
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
if(tesla_shock)
var/total_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(G.siemens_coefficient <= 0)
total_coeff -= 0.5
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
siemens_coeff = total_coeff
else if(!safety)
var/gloves_siemens_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
if(heart_attack && !illusion)
if(shock_damage * siemens_coeff >= 1 && prob(25))
heart_attack = 0
if(stat == CONSCIOUS)
src << "<span class='notice'>You feel your heart beating again!</span>"
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion)
if(.)
electrocution_animation(40)
/mob/living/carbon/human/emp_act(severity)
var/informed = 0
for(var/obj/item/bodypart/L in src.bodyparts)
if(L.status == BODYPART_ROBOTIC)
if(!informed)
src << "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>"
informed = 1
switch(severity)
if(1)
L.receive_damage(0,10)
src.Stun(10)
if(2)
L.receive_damage(0,5)
src.Stun(5)
..()
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit)
var/list/damaged = list()
var/list/inventory_items_to_kill = list()
var/acidity = acidpwr * min(acid_volume*0.005, 0.1)
//HEAD//
if(!bodyzone_hit || bodyzone_hit == "head") //only if we didn't specify a zone or if that zone is the head.
var/obj/item/clothing/head_clothes = null
if(glasses)
head_clothes = glasses
if(wear_mask)
head_clothes = wear_mask
if(wear_neck)
head_clothes = wear_neck
if(head)
head_clothes = head
if(head_clothes)
if(!(head_clothes.resistance_flags & UNACIDABLE))
head_clothes.acid_act(acidpwr, acid_volume)
update_inv_glasses()
update_inv_wear_mask()
update_inv_neck()
update_inv_head()
else
src << "<span class='notice'>Your [head_clothes.name] protects your head and face from the acid!</span>"
else
. = get_bodypart("head")
if(.)
damaged += .
if(ears)
inventory_items_to_kill += ears
//CHEST//
if(!bodyzone_hit || bodyzone_hit == "chest")
var/obj/item/clothing/chest_clothes = null
if(w_uniform)
chest_clothes = w_uniform
if(wear_suit)
chest_clothes = wear_suit
if(chest_clothes)
if(!(chest_clothes.resistance_flags & UNACIDABLE))
chest_clothes.acid_act(acidpwr, acid_volume)
update_inv_w_uniform()
update_inv_wear_suit()
else
src << "<span class='notice'>Your [chest_clothes.name] protects your body from the acid!</span>"
else
. = get_bodypart("chest")
if(.)
damaged += .
if(wear_id)
inventory_items_to_kill += wear_id
if(r_store)
inventory_items_to_kill += r_store
if(l_store)
inventory_items_to_kill += l_store
if(s_store)
inventory_items_to_kill += s_store
//ARMS & HANDS//
if(!bodyzone_hit || bodyzone_hit == "l_arm" || bodyzone_hit == "r_arm")
var/obj/item/clothing/arm_clothes = null
if(gloves)
arm_clothes = gloves
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
arm_clothes = w_uniform
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
arm_clothes = wear_suit
if(arm_clothes)
if(!(arm_clothes.resistance_flags & UNACIDABLE))
arm_clothes.acid_act(acidpwr, acid_volume)
update_inv_gloves()
update_inv_w_uniform()
update_inv_wear_suit()
else
src << "<span class='notice'>Your [arm_clothes.name] protects your arms and hands from the acid!</span>"
else
. = get_bodypart("r_arm")
if(.)
damaged += .
. = get_bodypart("l_arm")
if(.)
damaged += .
//LEGS & FEET//
if(!bodyzone_hit || bodyzone_hit == "l_leg" || bodyzone_hit == "r_leg" || bodyzone_hit == "feet")
var/obj/item/clothing/leg_clothes = null
if(shoes)
leg_clothes = shoes
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (w_uniform.body_parts_covered & LEGS))))
leg_clothes = w_uniform
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (wear_suit.body_parts_covered & LEGS))))
leg_clothes = wear_suit
if(leg_clothes)
if(!(leg_clothes.resistance_flags & UNACIDABLE))
leg_clothes.acid_act(acidpwr, acid_volume)
update_inv_shoes()
update_inv_w_uniform()
update_inv_wear_suit()
else
src << "<span class='notice'>Your [leg_clothes.name] protects your legs and feet from the acid!</span>"
else
. = get_bodypart("r_leg")
if(.)
damaged += .
. = get_bodypart("l_leg")
if(.)
damaged += .
//DAMAGE//
for(var/obj/item/bodypart/affecting in damaged)
affecting.receive_damage(acidity, 2*acidity)
if(affecting.name == "head")
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
affecting.receive_damage(acidity, 2*acidity)
emote("scream")
facial_hair_style = "Shaved"
hair_style = "Bald"
update_hair()
status_flags |= DISFIGURED
update_damage_overlays()
//MELTING INVENTORY ITEMS//
//these items are all outside of armour visually, so melt regardless.
if(!bodyzone_hit)
if(back)
inventory_items_to_kill += back
if(belt)
inventory_items_to_kill += belt
inventory_items_to_kill += held_items
for(var/obj/item/I in inventory_items_to_kill)
I.acid_act(acidpwr, acid_volume)
return 1
/mob/living/carbon/human/singularity_act()
var/gain = 20
if(mind)
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
gain = 100
if(mind.assigned_role == "Clown")
gain = rand(-300, 300)
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
gib()
return(gain)
/mob/living/carbon/human/help_shake_act(mob/living/carbon/M)
if(!istype(M))
return
if(health >= 0)
if(src == M)
visible_message("[src] examines [p_them()]self.", \
"<span class='notice'>You check yourself for injuries.</span>")
var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg")
for(var/X in bodyparts)
var/obj/item/bodypart/LB = X
missing -= LB.body_zone
var/status = ""
var/brutedamage = LB.brute_dam
var/burndamage = LB.burn_dam
if(hallucination)
if(prob(30))
brutedamage += rand(30,40)
if(prob(30))
burndamage += rand(30,40)
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "battered"
if(brutedamage > 40)
status = "mangled"
if(brutedamage > 0 && burndamage > 0)
status += " and "
if(burndamage > 40)
status += "peeling away"
else if(burndamage > 10)
status += "blistered"
else if(burndamage > 0)
status += "numb"
if(status == "")
status = "OK"
src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]."
for(var/obj/item/I in LB.embedded_objects)
src << "\t <a href='byond://?src=\ref[src];embedded_object=\ref[I];embedded_limb=\ref[LB]'>\red There is \a [I] embedded in your [LB.name]!</a>"
for(var/t in missing)
src << "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>"
if(bleed_rate)
src << "<span class='danger'>You are bleeding!</span>"
if(staminaloss)
if(staminaloss > 30)
src << "<span class='info'>You're completely exhausted.</span>"
else
src << "<span class='info'>You feel fatigued.</span>"
else
if(wear_suit)
wear_suit.add_fingerprint(M)
else if(w_uniform)
w_uniform.add_fingerprint(M)
..()
/mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
if(damage_type != BRUTE && damage_type != BURN)
return
damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed
var/list/torn_items = list()
//HEAD//
if(!def_zone || def_zone == "head")
var/obj/item/clothing/head_clothes = null
if(glasses)
head_clothes = glasses
if(wear_mask)
head_clothes = wear_mask
if(wear_neck)
head_clothes = wear_neck
if(head)
head_clothes = head
if(head_clothes)
torn_items += head_clothes
else if(ears)
torn_items += ears
//CHEST//
if(!def_zone || def_zone == "chest")
var/obj/item/clothing/chest_clothes = null
if(w_uniform)
chest_clothes = w_uniform
if(wear_suit)
chest_clothes = wear_suit
if(chest_clothes)
torn_items += chest_clothes
//ARMS & HANDS//
if(!def_zone || def_zone == "l_arm" || def_zone == "r_arm")
var/obj/item/clothing/arm_clothes = null
if(gloves)
arm_clothes = gloves
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
arm_clothes = w_uniform
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
arm_clothes = wear_suit
if(arm_clothes)
torn_items += arm_clothes
//LEGS & FEET//
if(!def_zone || def_zone == "l_leg" || def_zone == "r_leg")
var/obj/item/clothing/leg_clothes = null
if(shoes)
leg_clothes = shoes
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS)))
leg_clothes = w_uniform
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
leg_clothes = wear_suit
if(leg_clothes)
torn_items += leg_clothes
for(var/obj/item/I in torn_items)
I.take_damage(damage_amount, damage_type, damage_flag, 0)
@@ -3,6 +3,7 @@ var/global/default_martial_art = new/datum/martial_art
languages_spoken = HUMAN
languages_understood = HUMAN
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD)
pressure_resistance = 25
//Hair colour and style
var/hair_color = "000"
var/hair_style = "Bald"
@@ -29,11 +30,7 @@ var/global/default_martial_art = new/datum/martial_art
//Equipment slots
var/obj/item/wear_suit = null
var/obj/item/w_uniform = null
var/obj/item/shoes = null
var/obj/item/belt = null
var/obj/item/gloves = null
var/obj/item/clothing/glasses/glasses = null
var/obj/item/ears = null
var/obj/item/wear_id = null
var/obj/item/r_store = null
var/obj/item/l_store = null
@@ -41,8 +38,6 @@ var/global/default_martial_art = new/datum/martial_art
var/special_voice = "" // For changing our voice. Used by a symptom.
var/gender_ambiguous = 0 //if something goes wrong during gender reassignment this generates a line in examine
var/bleed_rate = 0 //how much are we bleeding
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
@@ -81,41 +81,23 @@
if(wear_id)
return wear_id.GetID()
///checkeyeprot()
///Returns a number between -1 to 2
/mob/living/carbon/human/check_eye_prot()
var/number = ..()
if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head
var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item
number += HFP.flash_protect
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
var/obj/item/clothing/glasses/GFP = src.glasses
number += GFP.flash_protect
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
var/obj/item/clothing/mask/MFP = src.wear_mask
number += MFP.flash_protect
if(istype(src.dna.species, /datum/species/xeno)) //Xenos don't have eyes.
number += 2 //So give them protection from flashes.
return number
/mob/living/carbon/human/check_ear_prot()
if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
return 1
/mob/living/carbon/human/abiotic(full_body = 0)
if(full_body && ((l_hand && !( src.l_hand.flags&ABSTRACT )) || (r_hand && !( src.r_hand.flags&ABSTRACT )) || (back && !(back.flags&ABSTRACT)) || (wear_mask && !(wear_mask.flags&ABSTRACT)) || (head && !(head.flags&ABSTRACT)) || (shoes && !(shoes.flags&ABSTRACT)) || (w_uniform && !(w_uniform.flags&ABSTRACT)) || (wear_suit && !(wear_suit.flags&ABSTRACT)) || (glasses && !(glasses.flags&ABSTRACT)) || (ears && !(ears.flags&ABSTRACT)) || (gloves && !(gloves.flags&ABSTRACT)) ) )
return 1
var/abiotic_hands = FALSE
for(var/obj/item/I in held_items)
if(!(I.flags & NODROP))
abiotic_hands = TRUE
break
if(full_body && abiotic_hands && ((back && !(back.flags&NODROP)) || (wear_mask && !(wear_mask.flags&NODROP)) || (head && !(head.flags&NODROP)) || (shoes && !(shoes.flags&NODROP)) || (w_uniform && !(w_uniform.flags&NODROP)) || (wear_suit && !(wear_suit.flags&NODROP)) || (glasses && !(glasses.flags&NODROP)) || (ears && !(ears.flags&NODROP)) || (gloves && !(gloves.flags&NODROP)) ) )
return TRUE
return abiotic_hands
if( (src.l_hand && !(src.l_hand.flags&ABSTRACT)) || (src.r_hand && !(src.r_hand.flags&ABSTRACT)) )
return 1
return 0
/mob/living/carbon/human/IsAdvancedToolUser()
return 1//Humans can use guns and such
/mob/living/carbon/human/InCritical()
return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
/mob/living/carbon/human/reagent_check(datum/reagent/R)
return dna.species.handle_chemicals(R,src)
@@ -159,7 +141,7 @@
if(src.dna.check_mutation(HULK))
src << "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>"
return 0
if(NOGUNS in src.dna.species.specflags)
if(NOGUNS in src.dna.species.species_traits)
src << "<span class='warning'>Your fingers don't fit in the trigger guard!</span>"
return 0
@@ -1,8 +1,8 @@
/mob/living/carbon/human/movement_delay()
. += dna.species.movement_delay(src)
. = 0
. += ..()
. += config.human_delay
. += dna.species.movement_delay(src)
/mob/living/carbon/human/slip(s_amount, w_amount, obj/O, lube)
if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP))
@@ -60,4 +60,4 @@
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
if(..())
return 1
return dna.species.space_move()
return dna.species.space_move(src)
@@ -4,7 +4,7 @@
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1)
for(var/slot in slots)
if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0))
if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0, disable_warning = TRUE))
return slot
if(qdel_on_fail)
qdel(I)
@@ -18,14 +18,12 @@
return back
if(slot_wear_mask)
return wear_mask
if(slot_neck)
return wear_neck
if(slot_handcuffed)
return handcuffed
if(slot_legcuffed)
return legcuffed
if(slot_l_hand)
return l_hand
if(slot_r_hand)
return r_hand
if(slot_belt)
return belt
if(slot_wear_id)
@@ -52,11 +50,48 @@
return s_store
return null
/mob/living/carbon/human/proc/get_all_slots()
. = get_head_slots() | get_body_slots()
/mob/living/carbon/human/proc/get_body_slots()
return list(
back,
s_store,
handcuffed,
legcuffed,
wear_suit,
gloves,
shoes,
belt,
wear_id,
l_store,
r_store,
w_uniform
)
/mob/living/carbon/human/proc/get_head_slots()
return list(
head,
wear_mask,
glasses,
ears,
)
/mob/living/carbon/human/proc/get_storage_slots()
return list(
back,
belt,
l_store,
r_store,
s_store,
)
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
if(!..()) //a check failed or the item has already found its slot
return
var/not_handled = FALSE //Added in case we make this type path deeper one day
switch(slot)
if(slot_belt)
belt = I
@@ -71,6 +106,8 @@
if(slot_glasses)
glasses = I
var/obj/item/clothing/glasses/G = I
if(G.glass_colour_type)
update_glasses_color(G, 1)
if(G.tint)
update_tint()
if(G.vision_correction)
@@ -108,6 +145,12 @@
else
src << "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>"
//Item is handled and in slot, valid to call callback, for this proc should always be true
if(!not_handled)
I.equipped(src, slot)
return not_handled //For future deeper overrides
/mob/living/carbon/human/unEquip(obj/item/I)
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
if(!. || !I)
@@ -140,6 +183,8 @@
else if(I == glasses)
glasses = null
var/obj/item/clothing/glasses/G = I
if(G.glass_colour_type)
update_glasses_color(G, 0)
if(G.tint)
update_tint()
if(G.vision_correction)
@@ -192,91 +237,6 @@
sec_hud_set_security_status()
..()
//Cycles through all clothing slots and tests them for destruction
/mob/living/carbon/human/proc/shred_clothing(bomb,shock)
var/covered_parts = 0 //The body parts that are protected by exterior clothing/armor
var/head_absorbed = 0 //How much of the shock the headgear absorbs when it is shredded. -1=it survives
var/suit_absorbed = 0 //How much of the shock the exosuit absorbs when it is shredded. -1=it survives
//Backpacks can never be protected but are annoying as fuck to lose, so they get a lower chance to be shredded
if(back)
back.shred(bomb,shock-20,src)
if(head)
covered_parts |= head.flags_inv
head_absorbed = head.shred(bomb,shock,src)
if(wear_mask)
var/absorbed = ((covered_parts & HIDEMASK) ? head_absorbed : 0) //Check if clothing covering this part absorbed any of the shock
if(absorbed >= 0)
//Masks can be used to shield other parts, but are simplified to simply add their absorbsion to the head armor if it covers the face
var/mask_absorbed = wear_mask.shred(bomb,shock-absorbed,src)
if(wear_mask.flags_inv & HIDEFACE)
covered_parts |= wear_mask.flags_inv
if(mask_absorbed < 0) //If the mask didn't get shredded, everything else on the head is protected
head_absorbed = -1
else
head_absorbed += mask_absorbed
if(ears)
var/absorbed = ((covered_parts & HIDEEARS) ? head_absorbed : 0)
if(absorbed >= 0)
ears.shred(bomb,shock-absorbed,src)
if(glasses)
var/absorbed = ((covered_parts & HIDEEYES) ? head_absorbed : 0)
if(absorbed >= 0)
glasses.shred(bomb,shock-absorbed,src)
if(wear_suit)
covered_parts |= wear_suit.flags_inv
suit_absorbed = wear_suit.shred(bomb,shock,src)
if(gloves)
var/absorbed = ((covered_parts & HIDEGLOVES) ? suit_absorbed : 0)
if(absorbed >= 0)
gloves.shred(bomb,shock-absorbed,src)
if(shoes)
var/absorbed = ((covered_parts & HIDESHOES) ? suit_absorbed : 0)
if(absorbed >= 0)
shoes.shred(bomb,shock-absorbed,src)
if(w_uniform)
var/absorbed = ((covered_parts & HIDEJUMPSUIT) ? suit_absorbed : 0)
if(absorbed >= 0)
w_uniform.shred(bomb,shock-20-absorbed,src) //Uniforms are also annoying to get shredded
/obj/item/proc/shred(bomb,shock,mob/living/carbon/human/Human)
if(flags & ABSTRACT)
return -1
var/shredded
if(!bomb)
if(burn_state != -1)
shredded = 1 //No heat protection, it burns
else
shredded = -1 //Heat protection = Fireproof
else if(shock > 0)
if(prob(max(shock-armor["bomb"],0)))
shredded = armor["bomb"] + 10 //It gets shredded, but it also absorbs the shock the clothes underneath would recieve by this amount
else
shredded = -1 //It survives explosion
if(shredded > 0)
if(Human) //Unequip if equipped
Human.unEquip(src)
if(bomb)
empty_object_contents()
spawn(1) //so the shreds aren't instantly deleted by the explosion
var/obj/effect/decal/cleanable/shreds/Shreds = new(loc)
Shreds.desc = "The sad remains of what used to be [src.name]."
qdel(src)
else
burn()
return shredded
/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
var/datum/outfit/O = null
+100 -10
View File
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
@@ -29,20 +29,26 @@
if (notransform)
return
if(..())
if(..()) //not dead
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_life(src)
if(stat != DEAD)
//heart attack stuff
handle_heart()
if(stat != DEAD)
//Stuff jammed in your limbs hurts
handle_embedded_objects()
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
dna.species.spec_life(src) // for mutantraces
if(stat != DEAD)
return 1
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE)))
@@ -85,9 +91,38 @@
/mob/living/carbon/human/breathe()
if(!dna.species.breathe(src))
..()
#define HUMAN_MAX_OXYLOSS 3
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
dna.species.check_breath(breath, src)
var/L = getorganslot("lungs")
if(!L)
if(health >= HEALTH_THRESHOLD_CRIT)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else if(!(NOCRITDAMAGE in dna.species.species_traits))
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
failed_last_breath = 1
if(dna && dna.species)
var/datum/species/S = dna.species
if(S.breathid == "o2")
throw_alert("oxy", /obj/screen/alert/oxy)
else if(S.breathid == "tox")
throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else if(S.breathid == "co2")
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
return 0
else
if(istype(L,/obj/item/organ/lungs))
var/obj/item/organ/lungs/lun = L
lun.check_breath(breath,src)
#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
dna.species.handle_environment(environment, src)
@@ -97,6 +132,61 @@
if(!dna || !dna.species.handle_fire(src))
..()
if(on_fire)
//the fire tries to damage the exposed clothes and items
var/list/burning_items = list()
//HEAD//
var/obj/item/clothing/head_clothes = null
if(glasses)
head_clothes = glasses
if(wear_mask)
head_clothes = wear_mask
if(wear_neck)
head_clothes = wear_neck
if(head)
head_clothes = head
if(head_clothes)
burning_items += head_clothes
else if(ears)
burning_items += ears
//CHEST//
var/obj/item/clothing/chest_clothes = null
if(w_uniform)
chest_clothes = w_uniform
if(wear_suit)
chest_clothes = wear_suit
if(chest_clothes)
burning_items += chest_clothes
//ARMS & HANDS//
var/obj/item/clothing/arm_clothes = null
if(gloves)
arm_clothes = gloves
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
arm_clothes = w_uniform
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
arm_clothes = wear_suit
if(arm_clothes)
burning_items += arm_clothes
//LEGS & FEET//
var/obj/item/clothing/leg_clothes = null
if(shoes)
leg_clothes = shoes
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS)))
leg_clothes = w_uniform
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
leg_clothes = wear_suit
if(leg_clothes)
burning_items += leg_clothes
for(var/X in burning_items)
var/obj/item/I = X
if(!(I.resistance_flags & FIRE_PROOF))
I.take_damage(fire_stacks, BURN, "fire", 0)
var/thermal_protection = get_thermal_protection()
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
@@ -217,7 +307,7 @@
if(dna.check_mutation(COLDRES))
return 1 //Fully protected from the cold.
if(dna && (RESISTTEMP in dna.species.specflags))
if(dna && (RESISTCOLD in dna.species.species_traits))
return 1
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
@@ -277,7 +367,7 @@
if(head)
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
. = 1
if(NOBREATH in dna.species.specflags)
if(NOBREATH in dna.species.species_traits)
. = 1
return .
@@ -287,11 +377,11 @@
var/obj/item/bodypart/BP = X
for(var/obj/item/I in BP.embedded_objects)
if(prob(I.embedded_pain_chance))
BP.take_damage(I.w_class*I.embedded_pain_multiplier)
BP.receive_damage(I.w_class*I.embedded_pain_multiplier)
src << "<span class='userdanger'>\the [I] embedded in your [BP.name] hurts!</span>"
if(prob(I.embedded_fall_chance))
BP.take_damage(I.w_class*I.embedded_fall_pain_multiplier)
BP.receive_damage(I.w_class*I.embedded_fall_pain_multiplier)
BP.embedded_objects -= I
I.loc = get_turf(src)
visible_message("<span class='danger'>\the [I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>\the [I] falls out of your [BP.name]!</span>")
@@ -301,8 +391,8 @@
/mob/living/carbon/human/proc/handle_heart()
CHECK_DNA_AND_SPECIES(src)
var/needs_heart = (!(NOBLOOD in dna.species.specflags))
var/we_breath = (!(NOBREATH in dna.species.specflags))
var/needs_heart = (!(NOBLOOD in dna.species.species_traits))
var/we_breath = (!(NOBREATH in dna.species.species_traits))
if(heart_attack)
if(!needs_heart)
+1 -1
View File
@@ -51,7 +51,7 @@
CHECK_DNA_AND_SPECIES(src)
// how do species that don't breathe talk? magic, that's what.
if(!(NOBREATH in dna.species.specflags) && !getorganslot("lungs"))
if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs"))
return 0
if(mind)
return !mind.miming
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
/mob/living/carbon/human/Stun(amount, updating = 1, ignore_canstun = 0)
amount = dna.species.spec_stun(src,amount)
..()
/mob/living/carbon/human/Weaken(amount, updating = 1, ignore_canstun = 0)
amount = dna.species.spec_stun(src,amount)
..()
/mob/living/carbon/human/cure_husk()
. = ..()
if(.)
update_hair()
/mob/living/carbon/human/become_husk()
. = ..()
if(.)
update_hair()
@@ -4,8 +4,10 @@
/* Keep these comments up-to-date if you -insist- on hurting my code-baby ;_;
This system allows you to update individual mob-overlays, without regenerating them all each time.
When we generate overlays we generate the standing version and then rotate the mob as necessary..
As of the time of writing there are 20 layers within this list. Please try to keep this from increasing. //22 and counting, good job guys
var/overlays_standing[20] //For the standing stance
Most of the time we only wish to update one overlay:
e.g. - we dropped the fireaxe out of our left hand and need to remove its icon from our mob
e.g.2 - our hair colour has changed, so we need to update our hair icons on our mob
@@ -13,21 +15,28 @@ In these cases, instead of updating every overlay using the old behaviour (regen
the appropriate update_X proc.
e.g. - update_l_hand()
e.g.2 - update_hair()
Note: Recent changes by aranclanos+carn:
update_icons() no longer needs to be called.
the system is easier to use. update_icons() should not be called unless you absolutely -know- you need it.
IN ALL OTHER CASES it's better to just call the specific update_X procs.
Note: The defines for layer numbers is now kept exclusvely in __DEFINES/misc.dm instead of being defined there,
then redefined and undefiend everywhere else. If you need to change the layering of sprites (or add a new layer)
that's where you should start.
All of this means that this code is more maintainable, faster and still fairly easy to use.
There are several things that need to be remembered:
> Whenever we do something that should cause an overlay to update (which doesn't use standard procs
( i.e. you do something like l_hand = /obj/item/something new(src), rather than using the helper procs)
You will need to call the relevant update_inv_* proc
All of these are named after the variable they update from. They are defined at the mob/ level like
update_clothing was, so you won't cause undefined proc runtimes with usr.update_inv_wear_id() if the usr is a
slime etc. Instead, it'll just return without doing any work. So no harm in calling it for slimes and such.
> There are also these special cases:
update_damage_overlays() //handles damage overlays for brute/burn damage
update_body() //Handles updating your mob's body layer and mutant bodyparts
@@ -35,30 +44,10 @@ There are several things that need to be remembered:
//NOTE: update_mutantrace() is now merged into this!
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
eyes were merged into update_body())
*/
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
/mob/living/carbon/human/update_damage_overlays()
remove_overlay(DAMAGE_LAYER)
var/image/standing = image("icon"='icons/mob/dam_human.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER)
overlays_standing[DAMAGE_LAYER] = standing
var/dmgoverlaytype = ""
if(dna.species.exotic_damage_overlay)
dmgoverlaytype = dna.species.exotic_damage_overlay + "_"
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(BP.brutestate)
standing.overlays += "[dmgoverlaytype][BP.body_zone]_[BP.brutestate]0" //we're adding icon_states of the base image as overlays
if(BP.burnstate)
standing.overlays += "[dmgoverlaytype][BP.body_zone]_0[BP.burnstate]"
apply_overlay(DAMAGE_LAYER)
//HAIR OVERLAY
/mob/living/carbon/human/update_hair()
dna.species.handle_hair(src)
@@ -68,47 +57,14 @@ There are several things that need to be remembered:
dna.species.handle_mutant_bodyparts(src)
/mob/living/carbon/human/proc/update_body()
/mob/living/carbon/human/update_body()
remove_overlay(BODY_LAYER)
dna.species.handle_body(src)
update_body_parts()
..()
/mob/living/carbon/human/update_fire()
..("Standing")
/mob/living/carbon/human/proc/update_body_parts()
//CHECK FOR UPDATE
var/oldkey = icon_render_key
icon_render_key = generate_icon_render_key()
if(oldkey == icon_render_key)
return
remove_overlay(BODYPARTS_LAYER)
//LOAD ICONS
if(limb_icon_cache[icon_render_key])
load_limb_from_cache()
update_damage_overlays()
update_mutant_bodyparts()
update_hair()
return
//GENERATE NEW LIMBS
var/list/new_limbs = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(!BP.no_update)
BP.update_limb()
var/image/temp = BP.get_limb_icon()
if(temp)
new_limbs += temp
if(new_limbs.len)
overlays_standing[BODYPARTS_LAYER] = new_limbs
limb_icon_cache[icon_render_key] = new_limbs
apply_overlay(BODYPARTS_LAYER)
update_damage_overlays()
/* --------------------------------------- */
//For legacy support.
@@ -130,6 +86,7 @@ There are several things that need to be remembered:
update_inv_back()
update_inv_wear_suit()
update_inv_pockets()
update_inv_neck()
update_transform()
//mutations
update_mutations_overlay()
@@ -148,10 +105,11 @@ There are several things that need to be remembered:
if(istype(w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
U.screen_loc = ui_iclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
U.screen_loc = ui_iclothing //...draw the item in the inventory screen
client.screen += w_uniform //Either way, add the item to the HUD
if(hud_used.inventory_shown)
client.screen += w_uniform
update_observer_view(w_uniform,1)
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
return
@@ -160,8 +118,10 @@ There are several things that need to be remembered:
var/t_color = U.item_color
if(!t_color)
t_color = U.icon_state
if(U.adjusted)
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
else if(U.adjusted == DIGITIGRADE_STYLE)
t_color = "[t_color]_l"
var/image/standing
@@ -181,6 +141,7 @@ There are several things that need to be remembered:
unEquip(thing)
apply_overlay(UNIFORM_LAYER)
update_mutant_bodyparts()
/mob/living/carbon/human/update_inv_wear_id()
@@ -191,9 +152,10 @@ There are several things that need to be remembered:
inv.update_icon()
if(wear_id)
wear_id.screen_loc = ui_id
if(client && hud_used && hud_used.hud_shown)
wear_id.screen_loc = ui_id
client.screen += wear_id
update_observer_view(wear_id)
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
var/image/standing = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi')
@@ -206,18 +168,25 @@ There are several things that need to be remembered:
remove_overlay(GLOVES_LAYER)
if(get_num_arms() <2)
if(!gloves && blood_DNA)
if(has_left_hand())
overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_left", "layer"=-GLOVES_LAYER)
apply_overlay(GLOVES_LAYER)
else if(has_right_hand())
overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_right", "layer"=-GLOVES_LAYER)
apply_overlay(GLOVES_LAYER)
return
if(client && hud_used)
if(client && hud_used && hud_used.inv_slots[slot_gloves])
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
inv.update_icon()
if(gloves)
gloves.screen_loc = ui_gloves
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
gloves.screen_loc = ui_gloves //...draw the item in the inventory screen
client.screen += gloves //Either way, add the item to the HUD
if(hud_used.inventory_shown)
client.screen += gloves
update_observer_view(gloves,1)
var/t_state = gloves.item_state
if(!t_state)
t_state = gloves.icon_state
@@ -233,7 +202,6 @@ There are several things that need to be remembered:
apply_overlay(GLOVES_LAYER)
/mob/living/carbon/human/update_inv_glasses()
remove_overlay(GLASSES_LAYER)
@@ -245,11 +213,11 @@ There are several things that need to be remembered:
inv.update_icon()
if(glasses)
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
client.screen += glasses //Either way, add the item to the HUD
client.screen += glasses //Either way, add the item to the HUD
update_observer_view(glasses,1)
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
var/image/standing = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
@@ -269,10 +237,11 @@ There are several things that need to be remembered:
inv.update_icon()
if(ears)
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
ears.screen_loc = ui_ears //...draw the item in the inventory screen
client.screen += ears //Either way, add the item to the HUD
if(hud_used.inventory_shown) //if the inventory is open
client.screen += ears //add it to the client's screen
update_observer_view(ears,1)
var/image/standing = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
overlays_standing[EARS_LAYER] = standing
@@ -291,11 +260,11 @@ There are several things that need to be remembered:
inv.update_icon()
if(shoes)
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
shoes.screen_loc = ui_shoes //...draw the item in the inventory screen
client.screen += shoes //Either way, add the item to the HUD
if(hud_used.inventory_shown) //if the inventory is open
client.screen += shoes //add it to client's screen
update_observer_view(shoes,1)
var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi')
overlays_standing[SHOES_LAYER] = standing
@@ -310,10 +279,10 @@ There are several things that need to be remembered:
inv.update_icon()
if(s_store)
s_store.screen_loc = ui_sstore1
if(client && hud_used && hud_used.hud_shown)
s_store.screen_loc = ui_sstore1
client.screen += s_store
update_observer_view(s_store)
var/t_state = s_store.item_state
if(!t_state)
t_state = s_store.icon_state
@@ -322,19 +291,10 @@ There are several things that need to be remembered:
apply_overlay(SUIT_STORE_LAYER)
/mob/living/carbon/human/update_inv_head()
remove_overlay(HEAD_LAYER)
if(!get_bodypart("head")) //Decapitated
return
..()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head]
inv.update_icon()
update_mutant_bodyparts()
/mob/living/carbon/human/update_inv_belt()
remove_overlay(BELT_LAYER)
@@ -342,11 +302,12 @@ There are several things that need to be remembered:
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt]
inv.update_icon()
if(hud_used.hud_shown && belt)
client.screen += belt
belt.screen_loc = ui_belt
if(belt)
belt.screen_loc = ui_belt
if(client && hud_used && hud_used.hud_shown)
client.screen += belt
update_observer_view(belt)
var/t_state = belt.item_state
if(!t_state)
t_state = belt.icon_state
@@ -367,17 +328,17 @@ There are several things that need to be remembered:
inv.update_icon()
if(istype(wear_suit, /obj/item/clothing/suit))
wear_suit.screen_loc = ui_oclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown) //if the inventory is open ...
wear_suit.screen_loc = ui_oclothing //TODO //...draw the item in the inventory screen
client.screen += wear_suit //Either way, add the item to the HUD
if(hud_used.inventory_shown)
client.screen += wear_suit
update_observer_view(wear_suit,1)
var/image/standing = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = 'icons/mob/suit.dmi')
overlays_standing[SUIT_LAYER] = standing
if(istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
drop_l_hand()
drop_r_hand()
if(wear_suit.breakouttime) //suit is restraining
drop_all_held_items()
update_hair()
update_mutant_bodyparts()
@@ -395,31 +356,23 @@ There are several things that need to be remembered:
inv = hud_used.inv_slots[slot_r_store]
inv.update_icon()
if(hud_used.hud_shown)
if(l_store)
if(l_store)
l_store.screen_loc = ui_storage1
if(hud_used.hud_shown)
client.screen += l_store
l_store.screen_loc = ui_storage1
update_observer_view(l_store)
if(r_store)
if(r_store)
r_store.screen_loc = ui_storage2
if(hud_used.hud_shown)
client.screen += r_store
r_store.screen_loc = ui_storage2
update_observer_view(r_store)
/mob/living/carbon/human/update_inv_wear_mask()
remove_overlay(FACEMASK_LAYER)
if(!get_bodypart("head")) //Decapitated
return
..()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask]
inv.update_icon()
update_mutant_bodyparts()
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
/mob/living/carbon/human/update_inv_handcuffed()
remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
apply_overlay(HANDCUFF_LAYER)
/mob/living/carbon/human/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
@@ -439,7 +392,7 @@ There are several things that need to be remembered:
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
var/list/out = new
for(var/i=1;i<=TOTAL_LAYERS;i++)
for(var/i in 1 to TOTAL_LAYERS)
if(overlays_standing[i])
if(i in unwantedLayers)
continue
@@ -451,23 +404,36 @@ There are several things that need to be remembered:
//update whether our head item appears on our hud.
/mob/living/carbon/human/update_hud_head(obj/item/I)
I.screen_loc = ui_head
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
I.screen_loc = ui_head
client.screen += I
client.screen += I
update_observer_view(I,1)
//update whether our mask item appears on our hud.
/mob/living/carbon/human/update_hud_wear_mask(obj/item/I)
I.screen_loc = ui_mask
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
I.screen_loc = ui_mask
client.screen += I
client.screen += I
update_observer_view(I,1)
//update whether our neck item appears on our hud.
/mob/living/carbon/human/update_hud_neck(obj/item/I)
I.screen_loc = ui_neck
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += I
update_observer_view(I,1)
//update whether our back item appears on our hud.
/mob/living/carbon/human/update_hud_back(obj/item/I)
I.screen_loc = ui_back
if(client && hud_used && hud_used.hud_shown)
I.screen_loc = ui_back
client.screen += I
update_observer_view(I)
/*
@@ -477,15 +443,23 @@ covers:
centering large images
layering images on custom layers
building images from custom icon files
By Remie Richards (yes I'm taking credit because this just removed 90% of the copypaste in update_icons())
state: A string to use as the state, this is FAR too complex to solve in this proc thanks to shitty old code
so it's specified as an argument instead.
default_layer: The layer to draw this on if no other layer is specified
default_icon_file: The icon file to draw states from if no other icon file is specified
isinhands: If true then alternate_worn_icon is skipped so that default_icon_file is used,
in this situation default_icon_file is expected to match either the lefthand_ or righthand_ file var
femalueuniform: A value matching a uniform item's fitted var, if this is anything but NO_FEMALE_UNIFORM, we
generate/load female uniform sprites matching all previously decided variables
*/
/obj/item/proc/build_worn_icon(var/state = "", var/default_layer = 0, var/default_icon_file = null, var/isinhands = FALSE, var/femaleuniform = NO_FEMALE_UNIFORM)
@@ -517,41 +491,42 @@ generate/load female uniform sprites matching all previously decided variables
standing = center_image(standing, isinhands ? inhand_x_dimension : worn_x_dimension, isinhands ? inhand_y_dimension : worn_y_dimension)
//Handle held offsets
var/mob/M = loc
if(istype(M))
var/list/L = get_held_offsets()
if(L)
standing.pixel_x += L["x"] //+= because of center()ing
standing.pixel_y += L["y"]
standing.alpha = alpha
standing.color = color
return standing
/obj/item/proc/get_held_offsets()
var/list/L
if(ismob(loc))
var/mob/M = loc
L = M.get_item_offsets_for_index(M.get_held_index_of_item(src))
return L
//Can't think of a better way to do this, sadly
/mob/proc/get_item_offsets_for_index(i)
switch(i)
if(3) //odd = left hands
return list("x" = 0, "y" = 16)
if(4) //even = right hands
return list("x" = 0, "y" = 16)
else //No offsets or Unwritten number of hands
return list("x" = 0, "y" = 0)
/////////////////////
// Limb Icon Cache //
/////////////////////
/*
Called from update_body_parts() these procs handle the limb icon cache.
the limb icon cache adds an icon_render_key to a human mob, it represents:
- skin_tone (if applicable)
- gender
- limbs (stores as the limb name and whether it is removed/fine, organic/robotic)
These procs only store limbs as to increase the number of matching icon_render_keys
This cache exists because drawing 6/7 icons for humans constantly is quite a waste
See RemieRichards on irc.rizon.net #coderbus
*/
var/global/list/limb_icon_cache = list()
/mob/living/carbon/human
var/icon_render_key = ""
//produces a key based on the human's limbs
/mob/living/carbon/human/proc/generate_icon_render_key()
/mob/living/carbon/human/generate_icon_render_key()
. = "[dna.species.limbs_id]"
if(dna.check_mutation(HULK))
@@ -562,8 +537,6 @@ var/global/list/limb_icon_cache = list()
. += "-coloured-[dna.species.fixed_mut_color]"
else if(dna.features["mcolor"])
. += "-coloured-[dna.features["mcolor"]]"
else if(dna.features["mcolor"] && dna.species.use_skintones)
. += "-coloured-[skin_tone]"
else
. += "-not_coloured"
@@ -572,18 +545,35 @@ var/global/list/limb_icon_cache = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
. += "-[BP.body_zone]"
if(BP.status == ORGAN_ORGANIC)
if(BP.status == BODYPART_ORGANIC)
. += "-organic"
else
. += "-robotic"
if(BP.use_digitigrade)
. += "-digitigrade[BP.use_digitigrade]"
if(BP.dmg_overlay_type)
. += "-[BP.dmg_overlay_type]"
if(disabilities & HUSK)
. += "-husk"
/mob/living/carbon/human/load_limb_from_cache()
..()
update_hair()
//change the human's icon to the one matching it's key
/mob/living/carbon/human/proc/load_limb_from_cache()
if(limb_icon_cache[icon_render_key])
remove_overlay(BODYPARTS_LAYER)
overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
apply_overlay(BODYPARTS_LAYER)
/mob/living/carbon/human/proc/update_observer_view(obj/item/I, inventory)
if(observers && observers.len)
for(var/M in observers)
var/mob/dead/observe = M
if(observe.client && observe.client.eye == src)
if(observe.hud_used)
if(inventory && !observe.hud_used.inventory_shown)
continue
observe.client.screen += I
else
observers -= observe
if(!observers.len)
observers = null
break
@@ -37,12 +37,11 @@
// If whispering your last words, limit the whisper based on how close you are to death.
if(critical)
var/health_diff = round(-config.health_threshold_dead + health)
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
// If we cut our message short, abruptly end it with a-..
var/message_len = length(message)
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
message = Ellipsis(message, 10, 1)
whispers = "whispers in their final breath"
message = treat_message(message)
@@ -60,12 +59,13 @@
watching -= eavesdropping
var/rendered
rendered = "<span class='game say'><span class='name'>[src.name]</span> [whispers] something.</span>"
whispers = critical ? "whispers something in [p_their()] final breath." : "whispers something."
rendered = "<span class='game say'><span class='name'>[src.name]</span> [whispers]</span>"
for(var/mob/M in watching)
M.show_message(rendered, 2)
var/spans = list(SPAN_ITALICS)
whispers = critical ? "whispers in [p_their()] final breath" : "whispers"
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] [whispers], <span class='message'>\"[attach_spans(message, spans)]\"</span></span>"
for(var/atom/movable/AM in listening)
+39 -21
View File
@@ -4,16 +4,14 @@
return back
if(slot_wear_mask)
return wear_mask
if(slot_neck)
return wear_neck
if(slot_head)
return head
if(slot_handcuffed)
return handcuffed
if(slot_legcuffed)
return legcuffed
if(slot_l_hand)
return l_hand
if(slot_r_hand)
return r_hand
return null
@@ -24,19 +22,26 @@
if(!istype(I))
return
if(I == l_hand)
l_hand = null
else if(I == r_hand)
r_hand = null
var/index = get_held_index_of_item(I)
if(index)
held_items[index] = null
if(I.pulledby)
I.pulledby.stop_pulling()
I.screen_loc = null // will get moved if inventory is visible
I.screen_loc = null
if(client)
client.screen -= I
if(observers && observers.len)
for(var/M in observers)
var/mob/dead/observe = M
if(observe.client)
observe.client.screen -= I
I.loc = src
I.equipped(src, slot)
I.layer = ABOVE_HUD_LAYER
I.plane = ABOVE_HUD_PLANE
I.appearance_flags |= NO_CLIENT_COLOR
var/not_handled = FALSE
switch(slot)
if(slot_back)
back = I
@@ -47,25 +52,34 @@
if(slot_head)
head = I
head_update(I)
if(slot_neck)
wear_neck = I
update_inv_neck(I)
if(slot_handcuffed)
handcuffed = I
update_handcuffed()
if(slot_legcuffed)
legcuffed = I
update_inv_legcuffed()
if(slot_l_hand)
l_hand = I
update_inv_l_hand()
if(slot_r_hand)
r_hand = I
update_inv_r_hand()
if(slot_hands)
put_in_hands(I)
update_inv_hands()
if(slot_in_backpack)
if(I == get_active_hand())
unEquip(I)
I.loc = back
var/obj/item/weapon/storage/B = back
var/prev_jimmies = B.rustle_jimmies
B.rustle_jimmies = FALSE //don't conspicously rustle
B.handle_item_insertion(I, 1, src)
B.rustle_jimmies = prev_jimmies
else
return 1
not_handled = TRUE
//Item has been handled at this point and equipped callback can be safely called
//We cannot call it for items that have not been handled as they are not yet correctly
//in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot
if(!not_handled)
I.equipped(src, slot)
return not_handled
/mob/living/carbon/unEquip(obj/item/I)
. = ..() //Sets the default return value to what the parent returns.
@@ -81,6 +95,9 @@
else if(I == wear_mask)
wear_mask = null
wear_mask_update(I, toggle_off = 1)
if(I == wear_neck)
wear_neck = null
update_inv_neck(I)
else if(I == handcuffed)
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
@@ -108,3 +125,4 @@
if(I.flags_inv & HIDEMASK || forced)
update_inv_wear_mask()
update_inv_head()
+12 -14
View File
@@ -4,24 +4,25 @@
if (notransform)
return
if(!loc)
return
if(damageoverlaytemp)
damageoverlaytemp = 0
update_damage_hud()
if(..())
. = 1
if(..()) //not dead
handle_blood()
for(var/obj/item/organ/O in internal_organs)
if(stat != DEAD)
for(var/V in internal_organs)
var/obj/item/organ/O = V
O.on_life()
//Updates the number of stored chemicals for powers
handle_changeling()
if(stat != DEAD)
return 1
///////////////
// BREATHING //
///////////////
@@ -42,15 +43,15 @@
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
return
if(ismob(loc)) return
var/datum/gas_mixture/environment
if(loc)
environment = loc.return_air()
if(ismob(loc)) return
var/datum/gas_mixture/breath
if(health <= config.health_threshold_crit || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
if(health <= HEALTH_THRESHOLD_CRIT || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
losebreath++
//Suffocate
@@ -284,7 +285,6 @@
/mob/living/carbon/handle_stomach()
/*
set waitfor = 0
for(var/mob/living/M in stomach_contents)
if(M.loc != src)
@@ -300,7 +300,7 @@
if(!(M.status_flags & GODMODE))
M.adjustBruteLoss(5)
nutrition += 10
*/
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
/mob/living/carbon/handle_status_effects()
..()
@@ -314,7 +314,7 @@
if(sleeping)
handle_dreams()
AdjustSleeping(-1)
if(prob(10) && health>config.health_threshold_crit)
if(prob(10) && health>HEALTH_THRESHOLD_CRIT)
emote("snore")
var/restingpwr = 1 + 4 * resting
@@ -389,8 +389,6 @@
var/body_temperature_difference = 310.15 - bodytemperature
switch(bodytemperature)
if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
nutrition -= 2
bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
if(260.15 to 310.15)
bodytemperature += max(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, min(body_temperature_difference, BODYTEMP_AUTORECOVERY_MINIMUM/4))
@@ -1,32 +1,34 @@
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = 0)
switch(slot)
if(slot_l_hand)
if(l_hand)
return 0
return 1
if(slot_r_hand)
if(r_hand)
return 0
return 1
if(slot_hands)
if(get_empty_held_indexes())
return TRUE
return FALSE
if(slot_wear_mask)
if(wear_mask)
return 0
return FALSE
if( !(I.slot_flags & SLOT_MASK) )
return 0
return 1
return FALSE
return TRUE
if(slot_neck)
if(wear_neck)
return FALSE
if( !(I.slot_flags & SLOT_NECK) )
return FALSE
return TRUE
if(slot_head)
if(head)
return 0
return FALSE
if( !(I.slot_flags & SLOT_HEAD) )
return 0
return 1
return FALSE
return TRUE
if(slot_back)
if(back)
return 0
return FALSE
if( !(I.slot_flags & SLOT_BACK) )
return 0
return 1
return 0 //Unsupported slot
return FALSE
return TRUE
return FALSE //Unsupported slot
+39 -15
View File
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/monkey
@@ -22,22 +22,24 @@
if (radiation)
if (radiation > 100)
if(!weakened)
emote("collapse")
Weaken(10)
src << "<span class='danger'>You feel weak.</span>"
emote("collapse")
switch(radiation)
if(50 to 75)
if(prob(5))
if(!weakened)
emote("collapse")
Weaken(3)
src << "<span class='danger'>You feel weak.</span>"
emote("collapse")
if(75 to 100)
if(prob(1))
src << "<span class='danger'>You mutate!</span>"
randmutb(src)
randmutb()
emote("gasp")
domutcheck()
..()
@@ -81,29 +83,29 @@
switch(bodytemperature)
if(360 to 400)
throw_alert("temp", /obj/screen/alert/hot, 1)
adjustFireLoss(2)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
if(400 to 460)
throw_alert("temp", /obj/screen/alert/hot, 2)
adjustFireLoss(3)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
if(460 to INFINITY)
throw_alert("temp", /obj/screen/alert/hot, 3)
if(on_fire)
adjustFireLoss(8)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
else
adjustFireLoss(3)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
switch(bodytemperature)
if(200 to 260)
throw_alert("temp", /obj/screen/alert/cold, 1)
adjustFireLoss(0.5)
apply_damage(COLD_DAMAGE_LEVEL_1, BURN)
if(120 to 200)
throw_alert("temp", /obj/screen/alert/cold, 2)
adjustFireLoss(1.5)
apply_damage(COLD_DAMAGE_LEVEL_2, BURN)
if(-INFINITY to 120)
throw_alert("temp", /obj/screen/alert/cold, 3)
adjustFireLoss(3)
apply_damage(COLD_DAMAGE_LEVEL_3, BURN)
else
clear_alert("temp")
@@ -140,7 +142,29 @@
return 1
/mob/living/carbon/monkey/handle_fire()
if(..())
return
bodytemperature += BODYTEMP_HEATING_MAX
return
. = ..()
if(on_fire)
//the fire tries to damage the exposed clothes and items
var/list/burning_items = list()
//HEAD//
var/obj/item/clothing/head_clothes = null
if(wear_mask)
head_clothes = wear_mask
if(wear_neck)
head_clothes = wear_neck
if(head)
head_clothes = head
if(head_clothes)
burning_items += head_clothes
if(back)
burning_items += back
for(var/X in burning_items)
var/obj/item/I = X
if(!(I.resistance_flags & FIRE_PROOF))
I.take_damage(fire_stacks, BURN, "fire", 0)
bodytemperature += BODYTEMP_HEATING_MAX
+25 -194
View File
@@ -3,16 +3,20 @@
voice_name = "monkey"
verb_say = "chimpers"
icon = 'icons/mob/monkey.dmi'
icon_state = "monkey1"
icon_state = ""
gender = NEUTER
pass_flags = PASSTABLE
languages_spoken = MONKEY
languages_understood = MONKEY
ventcrawler = 1
ventcrawler = VENTCRAWLER_NUDE
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey
gib_type = /obj/effect/decal/cleanable/blood/gibs
unique_name = 1
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
/mob/living/carbon/monkey/New()
verbs += /mob/living/proc/mob_sleep
@@ -22,24 +26,13 @@
gender = pick(MALE, FEMALE)
real_name = name
//initialize limbs, currently only used to handle cavity implant surgery, no dismemberment.
bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
for(var/X in bodyparts)
var/obj/item/bodypart/O = X
O.owner = src
//initialize limbs
create_bodyparts()
if(good_mutations.len) //genetic mutations have been set up.
initialize()
initialize() //initialize monkey dna
internal_organs += new /obj/item/organ/appendix
internal_organs += new /obj/item/organ/lungs
internal_organs += new /obj/item/organ/heart
internal_organs += new /obj/item/organ/brain
internal_organs += new /obj/item/organ/tongue
for(var/obj/item/organ/I in internal_organs)
I.Insert(src)
create_internal_organs()
..()
@@ -47,6 +40,15 @@
create_dna(src)
dna.initialize_dna(random_blood_type())
/mob/living/carbon/monkey/create_internal_organs()
internal_organs += new /obj/item/organ/appendix
internal_organs += new /obj/item/organ/lungs
internal_organs += new /obj/item/organ/heart
internal_organs += new /obj/item/organ/brain
internal_organs += new /obj/item/organ/tongue
..()
/mob/living/carbon/monkey/movement_delay()
if(reagents)
if(reagents.has_reagent("morphine"))
@@ -64,133 +66,6 @@
. += (283.222 - bodytemperature) / 10 * 1.75
return . + config.monkey_delay
/mob/living/carbon/monkey/attack_paw(mob/living/M)
if(..()) //successful monkey bite.
var/damage = rand(1, 5)
if (stat != DEAD)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
if(..()) //To allow surgery to return properly.
return
switch(M.a_intent)
if("help")
help_shake_act(M)
if("grab")
grabbedby(M)
if("harm")
M.do_attack_animation(src)
if (prob(75))
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
"<span class='userdanger'>[M] has punched [name]!</span>")
playsound(loc, "punch", 25, 1, -1)
var/damage = rand(5, 10)
if (prob(40))
damage = rand(10, 15)
if ( (paralysis < 5) && (health > 0) )
Paralyse(rand(10, 15))
visible_message("<span class='danger'>[M] has knocked out [name]!</span>", \
"<span class='userdanger'>[M] has knocked out [name]!</span>")
adjustBruteLoss(damage)
add_logs(M, src, "attacked")
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
"<span class='userdanger'>[M] has attempted to punch [name]!</span>")
if("disarm")
if (!( paralysis ))
M.do_attack_animation(src)
if (prob(25))
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
else
if(drop_item())
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>")
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
if(..()) //if harm or disarm intent.
if (M.a_intent == "harm")
if ((prob(95) && health > 0))
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
if (paralysis < 15)
Paralyse(rand(10, 15))
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
"<span class='userdanger'>[M] has wounded [name]!</span>")
else
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
"<span class='userdanger'>[M] has slashed [name]!</span>")
if (stat != DEAD)
adjustBruteLoss(damage)
updatehealth()
add_logs(M, src, "attacked")
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>")
if (M.a_intent == "disarm")
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(prob(95))
Weaken(10)
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
"<span class='userdanger'>[M] has tackled down [name]!</span>")
else
if(drop_item())
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
"<span class='userdanger'>[M] has disarmed [name]!</span>")
add_logs(M, src, "disarmed")
updatehealth()
return
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime attack
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/monkey/Stat()
..()
if(statpanel("Status"))
@@ -209,24 +84,6 @@
internal = null
return
/mob/living/carbon/monkey/ex_act(severity, target)
..()
switch(severity)
if(1)
gib()
return
if(2)
adjustBruteLoss(60)
adjustFireLoss(60)
adjustEarDamage(30,120)
if(3)
adjustBruteLoss(30)
if (prob(50))
Paralyse(10)
adjustEarDamage(15,60)
updatehealth()
return
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
return 0
@@ -249,46 +106,27 @@
//Lasertag bullshit
if(lasercolor)
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
threatcount += 4
if(lasercolor == "r")
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
threatcount += 4
return threatcount
//Check for weapons
if(judgebot.weaponscheck)
if(judgebot.check_for_weapons(l_hand))
threatcount += 4
if(judgebot.check_for_weapons(r_hand))
threatcount += 4
for(var/obj/item/I in held_items)
if(judgebot.check_for_weapons(I))
threatcount += 4
//mindshield implants imply trustworthyness
if(isloyal(src))
if(isloyal())
threatcount -= 1
return threatcount
/mob/living/carbon/monkey/acid_act(acidpwr, toxpwr, acid_volume)
if(wear_mask)
if(!wear_mask.unacidable)
wear_mask.acid_act(acidpwr)
update_inv_wear_mask()
else
src << "<span class='warning'>Your mask protects you from the acid.</span>"
return
take_organ_damage(min(6*toxpwr, acid_volume * acidpwr/10))
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
if(health < 0 && ishuman(M))
var/mob/living/carbon/human/H = M
H.do_cpr(src)
else
..()
/mob/living/carbon/monkey/get_permeability_protection()
var/protection = 0
if(head)
@@ -298,13 +136,6 @@
protection = protection/7 //the rest of the body isn't covered.
return protection
/mob/living/carbon/monkey/check_eye_prot()
var/number = ..()
if(istype(src.wear_mask, /obj/item/clothing/mask))
var/obj/item/clothing/mask/MFP = src.wear_mask
number += MFP.flash_protect
return number
/mob/living/carbon/monkey/fully_heal(admin_revive = 0)
if(!getorganslot("lungs"))
var/obj/item/organ/lungs/L = new()
@@ -0,0 +1,216 @@
/mob/living/carbon/monkey/get_eye_protection()
var/number = ..()
if(istype(src.wear_mask, /obj/item/clothing/mask))
var/obj/item/clothing/mask/MFP = src.wear_mask
number += MFP.flash_protect
return number
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
if(health < 0 && ishuman(M))
var/mob/living/carbon/human/H = M
H.do_cpr(src)
else
..()
/mob/living/carbon/monkey/attack_paw(mob/living/M)
if(..()) //successful monkey bite.
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart("chest")
if(M.limb_destroyer)
dismembering_strike(M, affecting.body_zone)
if(stat != DEAD)
var/dmg = rand(1, 5)
apply_damage(dmg, BRUTE, affecting)
damage_clothes(dmg, BRUTE, "melee", affecting.body_zone)
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
if(!affecting)
affecting = get_bodypart("chest")
apply_damage(damage, BRUTE, affecting)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
if(..()) //To allow surgery to return properly.
return
switch(M.a_intent)
if("help")
help_shake_act(M)
if("grab")
grabbedby(M)
if("harm")
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
if (prob(75))
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
"<span class='userdanger'>[M] has punched [name]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, "punch", 25, 1, -1)
var/damage = rand(5, 10)
if (prob(40))
damage = rand(10, 15)
if ( (paralysis < 5) && (health > 0) )
Paralyse(rand(10, 15))
visible_message("<span class='danger'>[M] has knocked out [name]!</span>", \
"<span class='userdanger'>[M] has knocked out [name]!</span>", null, 5)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
if(!affecting)
affecting = get_bodypart("chest")
apply_damage(damage, BRUTE, affecting)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
add_logs(M, src, "attacked")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
"<span class='userdanger'>[M] has attempted to punch [name]!</span>", null, COMBAT_MESSAGE_RANGE)
if("disarm")
if (!paralysis)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if (prob(25))
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_logs(M, src, "pushed")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>", null, COMBAT_MESSAGE_RANGE)
else
if(drop_item())
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
if(..()) //if harm or disarm intent.
if (M.a_intent == INTENT_HARM)
if ((prob(95) && health > 0))
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
if (paralysis < 15)
Paralyse(rand(10, 15))
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
"<span class='userdanger'>[M] has wounded [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
"<span class='userdanger'>[M] has slashed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
add_logs(M, src, "attacked")
if(!affecting)
affecting = get_bodypart("chest")
if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful
return 1
apply_damage(damage, BRUTE, affecting)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
if (M.a_intent == INTENT_DISARM)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(prob(95))
Weaken(10)
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
else
if(drop_item())
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
"<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "disarmed")
updatehealth()
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart("chest")
apply_damage(damage, M.melee_damage_type, affecting)
damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone)
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime attack
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
if(!dam_zone) //Dismemberment successful
return 1
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
if(!affecting)
affecting = get_bodypart("chest")
apply_damage(damage, BRUTE, affecting)
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
/mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit)
. = 1
if(!bodyzone_hit || bodyzone_hit == "head")
if(wear_mask)
if(!(wear_mask.resistance_flags & UNACIDABLE))
wear_mask.acid_act(acidpwr)
else
src << "<span class='warning'>Your mask protects you from the acid.</span>"
return
if(head)
if(!(head.resistance_flags & UNACIDABLE))
head.acid_act(acidpwr)
else
src << "<span class='warning'>Your hat protects you from the acid.</span>"
return
take_bodypart_damage(acidpwr * min(0.6, acid_volume*0.1))
/mob/living/carbon/monkey/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
return
..()
switch (severity)
if (1)
gib()
return
if (2)
take_overall_damage(60, 60)
damage_clothes(200, BRUTE, "bomb")
adjustEarDamage(30, 120)
if(prob(70))
Paralyse(10)
if(3)
take_overall_damage(30, 0)
damage_clothes(50, BRUTE, "bomb")
adjustEarDamage(15,60)
if (prob(50))
Paralyse(8)
//attempt to dismember bodyparts
if(severity <= 2)
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(prob(50/severity) && BP.body_zone != "chest")
BP.brute_dam = BP.max_damage
BP.dismember()
max_limb_loss--
if(!max_limb_loss)
break
@@ -11,14 +11,10 @@
/mob/living/carbon/monkey/punpun/New()
Read_Memory()
if(relic_hat)
equip_to_slot_or_del(new relic_hat, slot_head)
if(relic_mask)
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
if(ancestor_name)
name = ancestor_name
if(ancestor_chain > 1)
name += " [num2roman(ancestor_chain)]"
name += " \Roman[ancestor_chain]"
else
if(prob(5))
name = pick(rare_pet_monkey_names)
@@ -27,6 +23,14 @@
gender = pick(MALE, FEMALE)
..()
//These have to be after the parent new to ensure that the monkey
//bodyparts are actually created before we try to equip things to
//those slots
if(relic_hat)
equip_to_slot_or_del(new relic_hat, slot_head)
if(relic_mask)
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
/mob/living/carbon/monkey/punpun/Life()
if(ticker.current_state == GAME_STATE_FINISHED && !memory_saved)
Write_Memory(0)
@@ -1,29 +1,47 @@
/mob/living/carbon/monkey/regenerate_icons()
if(!..())
update_body_parts()
update_hair()
update_inv_wear_mask()
update_inv_head()
update_inv_back()
update_icons()
update_transform()
/mob/living/carbon/monkey/update_icons()
cut_overlays()
icon_state = "monkey1"
for(var/image/I in overlays_standing)
add_overlay(I)
////////
/mob/living/carbon/monkey/update_hair()
remove_overlay(HAIR_LAYER)
var/obj/item/bodypart/head/HD = get_bodypart("head")
if(!HD) //Decapitated
return
if(disabilities & HUSK)
return
var/hair_hidden = 0
if(head)
var/obj/item/I = head
if(I.flags_inv & HIDEHAIR)
hair_hidden = 1
if(wear_mask)
var/obj/item/clothing/mask/M = wear_mask
if(M.flags_inv & HIDEHAIR)
hair_hidden = 1
if(!hair_hidden)
if(!getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
var/image/I = image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER)
overlays_standing[HAIR_LAYER] = I
apply_overlay(HAIR_LAYER)
/mob/living/carbon/monkey/update_fire()
..("Monkey_burning")
/mob/living/carbon/monkey/update_inv_handcuffed()
remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
apply_overlay(HANDCUFF_LAYER)
/mob/living/carbon/monkey/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
if(legcuffed)
@@ -47,6 +65,12 @@
I.screen_loc = ui_monkey_mask
client.screen += I
//update whether our neck item appears on our hud.
/mob/living/carbon/monkey/update_hud_neck(obj/item/I)
if(client && hud_used && hud_used.hud_shown)
I.screen_loc = ui_monkey_mask
client.screen += I
//update whether our back item appears on our hud.
/mob/living/carbon/monkey/update_hud_back(obj/item/I)
if(client && hud_used && hud_used.hud_shown)
+4
View File
@@ -24,3 +24,7 @@
var/obj/item/organ/tongue/T = getorganslot("tongue")
if(T)
. |= T.get_spans()
var/obj/item/I = get_active_held_item()
if(I)
. |= I.get_held_item_speechspans(src)
+17 -2
View File
@@ -1,6 +1,6 @@
//Here are the procs used to modify status effects of a mob.
//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, NEARSIGHT disability, and HUSK disability.
/mob/living/carbon/damage_eyes(amount)
if(amount>0)
@@ -76,4 +76,19 @@
if(!(disabilities & NEARSIGHT))
disabilities |= NEARSIGHT
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
return 1
return 1
/mob/living/carbon/cure_husk()
if(disabilities & HUSK)
disabilities &= ~HUSK
status_flags &= ~DISFIGURED
update_body()
return 1
/mob/living/carbon/become_husk()
if(disabilities & HUSK)
return
disabilities |= HUSK
status_flags |= DISFIGURED //makes them unknown
update_body()
return 1
+183 -44
View File
@@ -40,43 +40,51 @@
overlays -= overlays_standing[cache_index]
overlays_standing[cache_index] = null
/mob/living/carbon/update_inv_r_hand()
remove_overlay(R_HAND_LAYER)
/mob/living/carbon/regenerate_icons()
if(notransform)
return 1
update_inv_hands()
update_inv_handcuffed()
update_inv_legcuffed()
update_fire()
/mob/living/carbon/update_inv_hands()
remove_overlay(HANDS_LAYER)
if (handcuffed)
drop_r_hand()
drop_all_held_items()
return
if(r_hand)
var/list/hands = list()
for(var/obj/item/I in held_items)
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
r_hand.screen_loc = ui_rhand
client.screen += r_hand
I.screen_loc = ui_hand_position(get_held_index_of_item(I))
client.screen += I
if(observers && observers.len)
for(var/M in observers)
var/mob/dead/observe = M
if(observe.client && observe.client.eye == src)
observe.client.screen += I
else
observers -= observe
if(!observers.len)
observers = null
break
var/t_state = r_hand.item_state
var/t_state = I.item_state
if(!t_state)
t_state = r_hand.icon_state
t_state = I.icon_state
var/image/standing = r_hand.build_worn_icon(state = t_state, default_layer = R_HAND_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
overlays_standing[R_HAND_LAYER] = standing
var/icon_file = I.lefthand_file
if(get_held_index_of_item(I) % 2 == 0)
icon_file = I.righthand_file
apply_overlay(R_HAND_LAYER)
var/image/standing = I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE)
hands += standing
/mob/living/carbon/update_inv_l_hand()
remove_overlay(L_HAND_LAYER)
if(handcuffed)
drop_l_hand()
return
if(l_hand)
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
l_hand.screen_loc = ui_lhand
client.screen += l_hand
overlays_standing[HANDS_LAYER] = hands
apply_overlay(HANDS_LAYER)
var/t_state = l_hand.item_state
if(!t_state)
t_state = l_hand.icon_state
var/image/standing = l_hand.build_worn_icon(state = t_state, default_layer = L_HAND_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
overlays_standing[L_HAND_LAYER] = standing
apply_overlay(L_HAND_LAYER)
/mob/living/carbon/update_fire(var/fire_icon = "Generic_mob_burning")
remove_overlay(FIRE_LAYER)
@@ -85,24 +93,58 @@
apply_overlay(FIRE_LAYER)
/mob/living/carbon/regenerate_icons()
if(notransform)
return 1
update_inv_r_hand()
update_inv_l_hand()
update_inv_handcuffed()
update_inv_legcuffed()
update_fire()
/mob/living/carbon/update_damage_overlays()
remove_overlay(DAMAGE_LAYER)
var/image/standing = image("icon"='icons/mob/dam_mob.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER)
overlays_standing[DAMAGE_LAYER] = standing
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
if(BP.dmg_overlay_type)
if(BP.brutestate)
standing.overlays += "[BP.dmg_overlay_type]_[BP.body_zone]_[BP.brutestate]0" //we're adding icon_states of the base image as overlays
if(BP.burnstate)
standing.overlays += "[BP.dmg_overlay_type]_[BP.body_zone]_0[BP.burnstate]"
apply_overlay(DAMAGE_LAYER)
/mob/living/carbon/update_inv_wear_mask()
remove_overlay(FACEMASK_LAYER)
if(istype(wear_mask, /obj/item/clothing/mask))
if(!get_bodypart("head")) //Decapitated
return
if(client && hud_used && hud_used.inv_slots[slot_wear_mask])
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask]
inv.update_icon()
if(wear_mask)
if(!(head && (head.flags_inv & HIDEMASK)))
var/image/standing = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi')
overlays_standing[FACEMASK_LAYER] = standing
update_hud_wear_mask(wear_mask)
apply_overlay(FACEMASK_LAYER)
/mob/living/carbon/update_inv_neck()
remove_overlay(NECK_LAYER)
if(client && hud_used && hud_used.inv_slots[slot_neck])
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_neck]
inv.update_icon()
if(wear_neck)
if(!(head && (head.flags_inv & HIDENECK)))
var/image/standing = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi')
overlays_standing[NECK_LAYER] = standing
update_hud_neck(wear_neck)
apply_overlay(NECK_LAYER)
/mob/living/carbon/update_inv_back()
remove_overlay(BACK_LAYER)
@@ -118,14 +160,27 @@
/mob/living/carbon/update_inv_head()
remove_overlay(HEAD_LAYER)
if(!get_bodypart("head")) //Decapitated
return
if(client && hud_used && hud_used.inv_slots[slot_back])
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head]
inv.update_icon()
if(head)
var/image/standing = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi')
overlays_standing[HEAD_LAYER] = standing
update_hud_head(head)
apply_overlay(HEAD_LAYER)
/mob/living/carbon/update_inv_handcuffed()
return
remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
apply_overlay(HANDCUFF_LAYER)
//mob HUD updates for items in our inventory
@@ -133,11 +188,10 @@
//update whether handcuffs appears on our hud.
/mob/living/carbon/proc/update_hud_handcuffed()
if(hud_used)
var/obj/screen/inventory/R = hud_used.inv_slots[slot_r_hand]
var/obj/screen/inventory/L = hud_used.inv_slots[slot_l_hand]
if(R && L)
R.update_icon()
L.update_icon()
for(var/hand in hud_used.hand_slots)
var/obj/screen/inventory/hand/H = hud_used.hand_slots[hand]
if(H)
H.update_icon()
//update whether our head item appears on our hud.
/mob/living/carbon/proc/update_hud_head(obj/item/I)
@@ -147,17 +201,102 @@
/mob/living/carbon/proc/update_hud_wear_mask(obj/item/I)
return
//update whether our neck item appears on our hud.
/mob/living/carbon/proc/update_hud_neck(obj/item/I)
return
//update whether our back item appears on our hud.
/mob/living/carbon/proc/update_hud_back(obj/item/I)
return
//Overlays for the worn overlay so you can overlay while you overlay
//eg: ammo counters, primed grenade flashing, etc.
/obj/item/proc/worn_overlays(var/isinhands = FALSE)
/obj/item/proc/worn_overlays(isinhands = FALSE)
. = list()
/mob/living/carbon/update_body()
update_body_parts()
/mob/living/carbon/proc/update_body_parts()
//CHECK FOR UPDATE
var/oldkey = icon_render_key
icon_render_key = generate_icon_render_key()
if(oldkey == icon_render_key)
return
remove_overlay(BODYPARTS_LAYER)
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
BP.update_limb()
//LOAD ICONS
if(limb_icon_cache[icon_render_key])
load_limb_from_cache()
return
//GENERATE NEW LIMBS
var/list/new_limbs = list()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
var/image/temp = BP.get_limb_icon()
if(temp)
new_limbs += temp
if(new_limbs.len)
overlays_standing[BODYPARTS_LAYER] = new_limbs
limb_icon_cache[icon_render_key] = new_limbs
apply_overlay(BODYPARTS_LAYER)
update_damage_overlays()
/////////////////////
// Limb Icon Cache //
/////////////////////
/*
Called from update_body_parts() these procs handle the limb icon cache.
the limb icon cache adds an icon_render_key to a human mob, it represents:
- skin_tone (if applicable)
- gender
- limbs (stores as the limb name and whether it is removed/fine, organic/robotic)
These procs only store limbs as to increase the number of matching icon_render_keys
This cache exists because drawing 6/7 icons for humans constantly is quite a waste
See RemieRichards on irc.rizon.net #coderbus
*/
var/global/list/limb_icon_cache = list()
/mob/living/carbon
var/icon_render_key = ""
//produces a key based on the mob's limbs
/mob/living/carbon/proc/generate_icon_render_key()
for(var/X in bodyparts)
var/obj/item/bodypart/BP = X
. += "-[BP.body_zone]"
if(BP.use_digitigrade)
. += "-digitigrade[BP.use_digitigrade]"
if(BP.animal_origin)
. += "-[BP.animal_origin]"
if(BP.status == BODYPART_ORGANIC)
. += "-organic"
else
. += "-robotic"
if(disabilities & HUSK)
. += "-husk"
//change the mob's icon to the one matching its key
/mob/living/carbon/proc/load_limb_from_cache()
if(limb_icon_cache[icon_render_key])
remove_overlay(BODYPARTS_LAYER)
overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
apply_overlay(BODYPARTS_LAYER)
update_damage_overlays()