mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
In some cases fire_act() wasn't even checking the applied temperature. Reworks how fire damages flooring.
481 lines
15 KiB
Plaintext
481 lines
15 KiB
Plaintext
/mob/living/carbon/New()
|
|
//setup reagent holders
|
|
bloodstr = new/datum/reagents/metabolism(1000, src, CHEM_BLOOD)
|
|
ingested = new/datum/reagents/metabolism(1000, src, CHEM_INGEST)
|
|
touching = new/datum/reagents/metabolism(1000, src, CHEM_TOUCH)
|
|
reagents = bloodstr
|
|
|
|
..()
|
|
|
|
/mob/living/carbon/Life()
|
|
..()
|
|
|
|
handle_viruses()
|
|
|
|
// Increase germ_level regularly
|
|
if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
|
|
germ_level++
|
|
|
|
/mob/living/carbon/Destroy()
|
|
for(var/guts in internal_organs)
|
|
qdel(guts)
|
|
for(var/food in stomach_contents)
|
|
qdel(food)
|
|
return ..()
|
|
|
|
/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((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
|
|
src.bodytemperature += 2
|
|
|
|
// Moving around increases germ_level faster
|
|
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
|
germ_level++
|
|
|
|
/mob/living/carbon/relaymove(var/mob/living/user, direction)
|
|
if((user in src.stomach_contents) && istype(user))
|
|
if(user.last_special <= world.time)
|
|
user.last_special = world.time + 50
|
|
src.visible_message("<span class='danger'>You hear something rumbling inside [src]'s stomach...</span>")
|
|
var/obj/item/I = user.get_active_hand()
|
|
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/obj/item/organ/external/organ = H.get_organ("chest")
|
|
if (istype(organ))
|
|
if(organ.take_damage(d, 0))
|
|
H.UpdateDamageIcon()
|
|
H.updatehealth()
|
|
else
|
|
src.take_organ_damage(d)
|
|
user.visible_message("<span class='danger'>[user] attacks [src]'s stomach wall with the [I.name]!</span>")
|
|
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
|
|
|
if(prob(src.getBruteLoss() - 50))
|
|
for(var/atom/movable/A in stomach_contents)
|
|
A.loc = loc
|
|
stomach_contents.Remove(A)
|
|
src.gib()
|
|
|
|
/mob/living/carbon/gib()
|
|
for(var/mob/M in src)
|
|
if(M in src.stomach_contents)
|
|
src.stomach_contents.Remove(M)
|
|
M.loc = src.loc
|
|
for(var/mob/N in viewers(src, null))
|
|
if(N.client)
|
|
N.show_message(text("\red <B>[M] bursts out of [src]!</B>"), 2)
|
|
..()
|
|
|
|
/mob/living/carbon/attack_hand(mob/M as mob)
|
|
if(!istype(M, /mob/living/carbon)) return
|
|
if (ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
|
|
if (H.hand)
|
|
temp = H.organs_by_name["l_hand"]
|
|
if(temp && !temp.is_usable())
|
|
H << "\red You can't use your [temp.name]"
|
|
return
|
|
|
|
for(var/datum/disease/D in viruses)
|
|
|
|
if(D.spread_by_touch())
|
|
|
|
M.contract_disease(D, 0, 1, CONTACT_HANDS)
|
|
|
|
for(var/datum/disease/D in M.viruses)
|
|
|
|
if(D.spread_by_touch())
|
|
|
|
contract_disease(D, 0, 1, CONTACT_HANDS)
|
|
|
|
return
|
|
|
|
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
|
|
if(status_flags & GODMODE) return 0 //godmode
|
|
shock_damage *= siemens_coeff
|
|
if (shock_damage<1)
|
|
return 0
|
|
|
|
src.apply_damage(shock_damage, BURN, def_zone, used_weapon="Electrocution")
|
|
playsound(loc, "sparks", 50, 1, -1)
|
|
if (shock_damage > 15)
|
|
src.visible_message(
|
|
"\red [src] was shocked by the [source]!", \
|
|
"\red <B>You feel a powerful shock course through your body!</B>", \
|
|
"\red You hear a heavy electrical crack." \
|
|
)
|
|
Stun(10)//This should work for now, more is really silly and makes you lay there forever
|
|
Weaken(10)
|
|
else
|
|
src.visible_message(
|
|
"\red [src] was mildly shocked by the [source].", \
|
|
"\red You feel a mild shock course through your body.", \
|
|
"\red You hear a light zapping." \
|
|
)
|
|
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
|
s.set_up(5, 1, loc)
|
|
s.start()
|
|
|
|
return shock_damage
|
|
|
|
|
|
/mob/living/carbon/proc/swap_hand()
|
|
var/obj/item/item_in_hand = src.get_active_hand()
|
|
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
|
|
if(istype(item_in_hand,/obj/item/weapon/material/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.l_hand_hud_object && hud_used.r_hand_hud_object)
|
|
if(hand) //This being 1 means the left hand is in use
|
|
hud_used.l_hand_hud_object.icon_state = "hand_active"
|
|
hud_used.r_hand_hud_object.icon_state = "hand_inactive"
|
|
else
|
|
hud_used.l_hand_hud_object.icon_state = "hand_inactive"
|
|
hud_used.r_hand_hud_object.icon_state = "hand_active"
|
|
/*if (!( src.hand ))
|
|
src.hands.set_dir(NORTH)
|
|
else
|
|
src.hands.set_dir(SOUTH)*/
|
|
return
|
|
|
|
/mob/living/carbon/proc/activate_hand(var/selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
|
|
|
|
if(istext(selhand))
|
|
selhand = lowertext(selhand)
|
|
|
|
if(selhand == "right" || selhand == "r")
|
|
selhand = 0
|
|
if(selhand == "left" || selhand == "l")
|
|
selhand = 1
|
|
|
|
if(selhand != src.hand)
|
|
swap_hand()
|
|
|
|
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
|
if (src.health >= config.health_threshold_crit)
|
|
if(src == M && istype(src, /mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = src
|
|
src.visible_message( \
|
|
text("\blue [src] examines [].",src.gender==MALE?"himself":"herself"), \
|
|
"\blue You check yourself for injuries." \
|
|
)
|
|
|
|
for(var/obj/item/organ/external/org in H.organs)
|
|
var/list/status = list()
|
|
var/brutedamage = org.brute_dam
|
|
var/burndamage = org.burn_dam
|
|
if(halloss > 0)
|
|
if(prob(30))
|
|
brutedamage += halloss
|
|
if(prob(30))
|
|
burndamage += halloss
|
|
switch(brutedamage)
|
|
if(1 to 20)
|
|
status += "bruised"
|
|
if(20 to 40)
|
|
status += "wounded"
|
|
if(40 to INFINITY)
|
|
status += "mangled"
|
|
|
|
switch(burndamage)
|
|
if(1 to 10)
|
|
status += "numb"
|
|
if(10 to 40)
|
|
status += "blistered"
|
|
if(40 to INFINITY)
|
|
status += "peeling away"
|
|
|
|
if(org.status & ORGAN_DESTROYED)
|
|
status += "MISSING"
|
|
if(org.status & ORGAN_MUTATED)
|
|
status += "weirdly shapen"
|
|
if(org.dislocated == 2)
|
|
status += "dislocated"
|
|
if(org.status & ORGAN_BROKEN)
|
|
status += "hurts when touched"
|
|
if(org.status & ORGAN_DEAD)
|
|
status += "is bruised and necrotic"
|
|
if(!org.is_usable())
|
|
status += "dangling uselessly"
|
|
if(status.len)
|
|
src.show_message("My [org.name] is <span class='warning'> [english_list(status)].",1)
|
|
else
|
|
src.show_message("My [org.name] is <span class='notice'> OK.",1)
|
|
|
|
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
|
|
H.play_xylophone()
|
|
else if (on_fire)
|
|
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
|
if (M.on_fire)
|
|
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames, but to no avail!</span>", \
|
|
"<span class='warning'>You try to pat out [src]'s flames, but to no avail! Put yourself out first!</span>")
|
|
else
|
|
M.visible_message("<span class='warning'>[M] tries to pat out [src]'s flames!</span>", \
|
|
"<span class='warning'>You try to pat out [src]'s flames! Hot!</span>")
|
|
if(do_mob(M, src, 15))
|
|
if (prob(10) && (M.fire_stacks <= 0))
|
|
src.fire_stacks -= 2
|
|
M.fire_stacks += 1
|
|
M.IgniteMob()
|
|
if (M.on_fire)
|
|
M.visible_message("<span class='danger'>The fire spreads from [src] to [M]!</span>", \
|
|
"<span class='danger'>The fire spreads to you as well!</span>")
|
|
else
|
|
src.fire_stacks -= 3 //Less effective than stop, drop, and roll
|
|
if (src.fire_stacks <= 0)
|
|
M.visible_message("<span class='warning'>[M] successfully pats out [src]'s flames.</span>", \
|
|
"<span class='warning'>You successfully pat out [src]'s flames.</span>")
|
|
src.ExtinguishMob()
|
|
src.fire_stacks = 0
|
|
else
|
|
var/t_him = "it"
|
|
if (src.gender == MALE)
|
|
t_him = "him"
|
|
else if (src.gender == FEMALE)
|
|
t_him = "her"
|
|
if (istype(src,/mob/living/carbon/human) && src:w_uniform)
|
|
var/mob/living/carbon/human/H = src
|
|
H.w_uniform.add_fingerprint(M)
|
|
|
|
var/show_ssd
|
|
var/mob/living/carbon/human/H = src
|
|
if(istype(H)) show_ssd = H.species.show_ssd
|
|
if(show_ssd && (!client || !key || player_logged))
|
|
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
|
|
"<span class='notice'>You shake [src], but they do not respond... Maybe they have S.S.D?</span>")
|
|
else if(lying || src.sleeping)
|
|
src.sleeping = max(0,src.sleeping-5)
|
|
if(src.sleeping == 0)
|
|
src.resting = 0
|
|
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
|
|
"<span class='notice'>You shake [src] trying to wake [t_him] up!</span>")
|
|
else
|
|
if(istype(H))
|
|
H.species.hug(H,src)
|
|
else
|
|
M.visible_message("<span class='notice'>[M] hugs [src] to make [t_him] feel better!</span>", \
|
|
"<span class='notice'>You hug [src] to make [t_him] feel better!</span>")
|
|
if(M.fire_stacks >= (src.fire_stacks + 3))
|
|
src.fire_stacks += 1
|
|
M.fire_stacks -= 1
|
|
if(M.on_fire)
|
|
src.IgniteMob()
|
|
AdjustParalysis(-3)
|
|
AdjustStunned(-3)
|
|
AdjustWeakened(-3)
|
|
|
|
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
|
|
|
/mob/living/carbon/proc/eyecheck()
|
|
return 0
|
|
|
|
// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching.
|
|
// Stop! ... Hammertime! ~Carn
|
|
|
|
/mob/living/carbon/proc/getDNA()
|
|
return dna
|
|
|
|
/mob/living/carbon/proc/setDNA(var/datum/dna/newDNA)
|
|
dna = newDNA
|
|
|
|
// ++++ROCKDTBEN++++ MOB PROCS //END
|
|
|
|
/mob/living/carbon/clean_blood()
|
|
. = ..()
|
|
if(ishuman(src))
|
|
var/mob/living/carbon/human/H = src
|
|
if(H.gloves)
|
|
if(H.gloves.clean_blood())
|
|
H.update_inv_gloves(0)
|
|
H.gloves.germ_level = 0
|
|
else
|
|
if(H.bloody_hands)
|
|
H.bloody_hands = 0
|
|
H.update_inv_gloves(0)
|
|
H.germ_level = 0
|
|
update_icons() //apply the now updated overlays to the mob
|
|
|
|
|
|
//Throwing stuff
|
|
|
|
/mob/living/carbon/proc/toggle_throw_mode()
|
|
if (src.in_throw_mode)
|
|
throw_mode_off()
|
|
else
|
|
throw_mode_on()
|
|
|
|
/mob/living/carbon/proc/throw_mode_off()
|
|
src.in_throw_mode = 0
|
|
if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
|
|
src.throw_icon.icon_state = "act_throw_off"
|
|
|
|
/mob/living/carbon/proc/throw_mode_on()
|
|
src.in_throw_mode = 1
|
|
if(src.throw_icon)
|
|
src.throw_icon.icon_state = "act_throw_on"
|
|
|
|
/mob/proc/throw_item(atom/target)
|
|
return
|
|
|
|
/mob/living/carbon/throw_item(atom/target)
|
|
src.throw_mode_off()
|
|
if(usr.stat || !target)
|
|
return
|
|
if(target.type == /obj/screen) return
|
|
|
|
var/atom/movable/item = src.get_active_hand()
|
|
|
|
if(!item) return
|
|
|
|
if (istype(item, /obj/item/weapon/grab))
|
|
var/obj/item/weapon/grab/G = item
|
|
item = G.throw_held() //throw the person instead of the grab
|
|
if(ismob(item))
|
|
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
|
var/turf/end_T = get_turf(target)
|
|
if(start_T && end_T)
|
|
var/mob/M = item
|
|
var/start_T_descriptor = "<font color='#6b5d00'>tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]</font>"
|
|
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
|
|
|
|
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been thrown by [usr.name] ([usr.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]</font>")
|
|
usr.attack_log += text("\[[time_stamp()]\] <font color='red'>Has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]</font>")
|
|
msg_admin_attack("[usr.name] ([usr.ckey]) has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[usr.x];Y=[usr.y];Z=[usr.z]'>JMP</a>)")
|
|
|
|
if(!item) return //Grab processing has a chance of returning null
|
|
|
|
|
|
src.remove_from_mob(item)
|
|
item.loc = src.loc
|
|
|
|
//actually throw it!
|
|
if (item)
|
|
src.visible_message("\red [src] has thrown [item].")
|
|
|
|
if(!src.lastarea)
|
|
src.lastarea = get_area(src.loc)
|
|
if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
|
|
src.inertia_dir = get_dir(target, src)
|
|
step(src, inertia_dir)
|
|
|
|
|
|
/*
|
|
if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction
|
|
src.inertia_dir = get_dir(target, src)
|
|
step(src, inertia_dir)
|
|
*/
|
|
|
|
|
|
item.throw_at(target, item.throw_range, item.throw_speed, src)
|
|
|
|
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
|
..()
|
|
var/temp_inc = max(BODYTEMP_HEATING_MAX*(1-get_heat_protection()), 0)
|
|
bodytemperature = min(bodytemperature + temp_inc, exposed_temperature)
|
|
|
|
/mob/living/carbon/can_use_hands()
|
|
if(handcuffed)
|
|
return 0
|
|
if(buckled && ! istype(buckled, /obj/structure/bed/chair)) // buckling does not restrict hands
|
|
return 0
|
|
return 1
|
|
|
|
/mob/living/carbon/restrained()
|
|
if (handcuffed)
|
|
return 1
|
|
return
|
|
|
|
/mob/living/carbon/u_equip(obj/item/W as obj)
|
|
if(!W) return 0
|
|
|
|
else if (W == handcuffed)
|
|
handcuffed = null
|
|
update_inv_handcuffed()
|
|
if(buckled && buckled.buckle_require_restraints)
|
|
buckled.unbuckle_mob()
|
|
|
|
else if (W == legcuffed)
|
|
legcuffed = null
|
|
update_inv_legcuffed()
|
|
else
|
|
..()
|
|
|
|
return
|
|
|
|
//generates realistic-ish pulse output based on preset levels
|
|
/mob/living/carbon/proc/get_pulse(var/method) //method 0 is for hands, 1 is for machines, more accurate
|
|
var/temp = 0 //see setup.dm:694
|
|
switch(src.pulse)
|
|
if(PULSE_NONE)
|
|
return "0"
|
|
if(PULSE_SLOW)
|
|
temp = rand(40, 60)
|
|
return num2text(method ? temp : temp + rand(-10, 10))
|
|
if(PULSE_NORM)
|
|
temp = rand(60, 90)
|
|
return num2text(method ? temp : temp + rand(-10, 10))
|
|
if(PULSE_FAST)
|
|
temp = rand(90, 120)
|
|
return num2text(method ? temp : temp + rand(-10, 10))
|
|
if(PULSE_2FAST)
|
|
temp = rand(120, 160)
|
|
return num2text(method ? temp : temp + rand(-10, 10))
|
|
if(PULSE_THREADY)
|
|
return method ? ">250" : "extremely weak and fast, patient's artery feels like a thread"
|
|
// output for machines^ ^^^^^^^output for people^^^^^^^^^
|
|
|
|
/mob/living/carbon/verb/mob_sleep()
|
|
set name = "Sleep"
|
|
set category = "IC"
|
|
|
|
if(usr.sleeping)
|
|
usr << "\red You are already sleeping"
|
|
return
|
|
if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes")
|
|
usr.sleeping = 20 //Short nap
|
|
|
|
/mob/living/carbon/Bump(var/atom/movable/AM, yes)
|
|
if(now_pushing || !yes)
|
|
return
|
|
..()
|
|
if(istype(AM, /mob/living/carbon) && prob(10))
|
|
src.spread_disease_to(AM, "Contact")
|
|
|
|
/mob/living/carbon/can_use_vents()
|
|
return
|
|
|
|
/mob/living/carbon/slip(var/slipped_on,stun_duration=8)
|
|
if(buckled)
|
|
return 0
|
|
stop_pulling()
|
|
src << "<span class='warning'>You slipped on [slipped_on]!</span>"
|
|
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
|
|
Stun(stun_duration)
|
|
Weaken(Floor(stun_duration/2))
|
|
return 1
|
|
|
|
/mob/living/carbon/proc/add_chemical_effect(var/effect, var/magnitude = 1)
|
|
if(effect in chem_effects)
|
|
chem_effects[effect] += magnitude
|
|
else
|
|
chem_effects[effect] = magnitude
|
|
|
|
/mob/living/carbon/get_default_language()
|
|
if(default_language)
|
|
return default_language
|
|
|
|
if(!species)
|
|
return null
|
|
return species.default_language ? all_languages[species.default_language] : null
|