Adds crawling. (#17899)

* crawling?

* knockdown. CONTAINS CHANGES THAT NEED REVERTING

* plotting can_moves death

* CANMOVE IS DEAD

* mappers are insane

* removes todos as the are todone

* decreases crawling speed

* silly-con fixes

* surgery fixes

* fixes death

* pAI fixes

* removes var/lying

* runtime fix

* decreases default crawling speed

* correct crawling dir

* some more fixes

* stunbaton tweak, revert later

* rejuv fix

* restraint and incapacitated refactor

* crawling dir in line with TG

* fixes vehicle movement and grabs

* alien rest fixes

* antistun fixes

* fixed fall sounds

* forgor to stage this

* first review

* canmove zombie dispersal

* fix

* lots of fixes

* defines

* fixes the trait helper

* if you got no legs you can still crawl

* sillyconfix

* no reverty keepy

* jaunt fix

* hopefully fixes perma sleepy zzz

* admin rejuv temp fix

* rest canceling

* antistun chems now remove knockdown

* buckle offset fix

* fixes some stuff

* crawling delay = 4

* descuffs bed

* sleeping hotfix

* fixes simple mob resting

* V is the macro for resting

* projectiles no dodgy

* refines the projectile check

* god I hate strings

* MORE FIXES

* I hate buckling

* fixes capulettium plus

* winding down

* farie review

* bugs did stop showing up

* SEAN

* todo

* sean review

* ed209

* i HATE cyborgs

* steel review

* laaaaaast things

* reverts stun baton changes

* and done
This commit is contained in:
Charlie
2022-06-30 11:57:52 -05:00
committed by GitHub
parent 5e2f62800c
commit bead47ea29
190 changed files with 1012 additions and 725 deletions
+1 -2
View File
@@ -13,7 +13,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
layer = GHOST_LAYER
stat = DEAD
density = FALSE
canmove = FALSE
alpha = 127
move_resist = INFINITY // don't get pushed around
invisibility = INVISIBILITY_OBSERVER
@@ -739,7 +738,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return FALSE
/mob/dead/observer/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE)
/mob/dead/observer/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE)
return TRUE
//this is a mob verb instead of atom for performance reasons
+13 -8
View File
@@ -40,8 +40,8 @@
return null
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(obj/item/W, skip_lying_check = FALSE)
if(!put_in_hand_check(W, skip_lying_check))
/mob/proc/put_in_l_hand(obj/item/W, skip_blocked_hands_check = FALSE)
if(!put_in_hand_check(W, skip_blocked_hands_check))
return 0
if(!l_hand && has_left_hand())
W.forceMove(src) //TODO: move to equipped?
@@ -56,8 +56,8 @@
return 0
//Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_r_hand(obj/item/W, skip_lying_check = FALSE)
if(!put_in_hand_check(W, skip_lying_check))
/mob/proc/put_in_r_hand(obj/item/W, skip_blocked_hands_check = FALSE)
if(!put_in_hand_check(W, skip_blocked_hands_check))
return 0
if(!r_hand && has_right_hand())
W.forceMove(src)
@@ -71,10 +71,15 @@
return 1
return 0
/mob/proc/put_in_hand_check(obj/item/W, skip_lying_check)
if(!skip_lying_check && lying && !(W.flags & ABSTRACT)) return 0
if(!istype(W)) return 0
return 1
/mob/proc/put_in_hand_check(obj/item/W, skip_blocked_hands_check)
if(!istype(W))
return FALSE
return TRUE
/mob/living/put_in_hand_check(obj/item/W, skip_blocked_hands_check)
. = ..()
if(!skip_blocked_hands_check && HAS_TRAIT(src, TRAIT_HANDS_BLOCKED) && !(W.flags & ABSTRACT))
. = FALSE
//Puts the item into our active hand if possible. returns 1 on success.
/mob/proc/put_in_active_hand(obj/item/W)
+1 -1
View File
@@ -327,7 +327,7 @@
if((!rhand || !rhand.is_usable()) && (!lhand || !lhand.is_usable()))
to_chat(speaker,"<span class='warning'>You can't communicate without the ability to use your hands!</span>")
return FALSE
if(speaker.incapacitated(ignore_lying = 1))
if(HAS_TRAIT(speaker, TRAIT_HANDS_BLOCKED))
to_chat(speaker,"<span class='warning'>You can't communicate while unable to move your hands to your head!</span>")
return FALSE
@@ -17,7 +17,6 @@
status_flags = CANPARALYSE|CANPUSH
var/heal_rate = 5
var/large = FALSE
var/heat_protection = 0.5
var/leaping = FALSE
@@ -30,7 +29,7 @@
..()
create_reagents(1000)
verbs += /mob/living/verb/mob_sleep
verbs += /mob/living/verb/lay_down
verbs += /mob/living/verb/rest
alien_organs += new /obj/item/organ/internal/brain/xeno
alien_organs += new /obj/item/organ/internal/xenos/hivenode
alien_organs += new /obj/item/organ/internal/ears
@@ -255,3 +254,7 @@ Des: Removes all infected images from the alien.
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
/mob/living/carbon/alien/on_lying_down(new_lying_angle)
. = ..()
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LYING_DOWN_TRAIT) //Xenos can't crawl
@@ -13,10 +13,11 @@ In all, this is a lot like the monkey code. /N
switch(M.a_intent)
if(INTENT_HELP)
AdjustSleeping(-10 SECONDS)
StopResting()
AdjustParalysis(-6 SECONDS)
AdjustStunned(-6 SECONDS)
AdjustWeakened(-6 SECONDS)
AdjustKnockDown(-6 SECONDS)
stand_up()
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake it up!</span>")
if(INTENT_GRAB)
@@ -3,8 +3,7 @@
return FALSE
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -26,8 +25,7 @@
/mob/living/carbon/alien/dust()
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
dust_animation()
@@ -17,7 +17,7 @@
. += ..() //but they still need to slow down on stun
/mob/living/carbon/alien/humanoid/hunter/handle_environment()
if(m_intent == MOVE_INTENT_RUN || resting)
if(m_intent == MOVE_INTENT_RUN || IS_HORIZONTAL(src))
..()
else
adjustPlasma(-heal_rate)
@@ -54,7 +54,7 @@
to_chat(src, "<span class='alertalien'>It is unsafe to leap without gravity!</span>")
//It's also extremely buggy visually, so it's balance+bugfix
return
if(lying)
if(IS_HORIZONTAL(src))
return
else //Maybe uses plasma in the future, although that wouldn't make any sense...
@@ -99,7 +99,6 @@
if(leaping)
leaping = 0
update_icons()
update_canmove()
/mob/living/carbon/alien/humanoid/float(on)
@@ -24,7 +24,7 @@
overlays.Cut()
if(stat == DEAD)
icon_state = "prat_dead"
else if(stat == UNCONSCIOUS || lying || resting)
else if(stat == UNCONSCIOUS || IS_HORIZONTAL(src))
icon_state = "prat_sleep"
else
icon_state = "prat_s"
@@ -22,7 +22,7 @@
if(stat == DEAD)
icon_state = "empress_dead"
else if(stat == UNCONSCIOUS || lying || resting)
else if(stat == UNCONSCIOUS || IS_HORIZONTAL(src))
icon_state = "empress_sleep"
else
icon_state = "empress_s"
@@ -103,7 +103,7 @@
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
..(I, cuff_break = 1)
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset()
if(leaping)
return -32
else if(custom_pixel_y_offset)
@@ -38,7 +38,7 @@
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
if(INTENT_DISARM)
if(!lying)
if(!IS_HORIZONTAL(src))
if(prob(5))//Very small chance to push an alien down.
Paralyse(4 SECONDS)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
@@ -65,7 +65,7 @@
if(stat == DEAD)
icon_state = "queen_dead"
else if(stat == UNCONSCIOUS || lying || resting)
else if(stat == UNCONSCIOUS || IS_HORIZONTAL(src))
icon_state = "queen_sleep"
else
icon_state = "queen_s"
@@ -31,7 +31,7 @@
else if(leap_on_click)
icon_state = "alien[caste]_pounce"
else if(lying || resting)
else if(IS_HORIZONTAL(src))
icon_state = "alien[caste]_sleep"
else if(m_intent == MOVE_INTENT_RUN)
icon_state = "alien[caste]_running"
@@ -51,8 +51,8 @@
var/old_icon = icon
icon = alt_icon
alt_icon = old_icon
pixel_x = get_standard_pixel_x_offset(lying)
pixel_y = get_standard_pixel_y_offset(lying)
pixel_x = get_standard_pixel_x_offset()
pixel_y = get_standard_pixel_y_offset()
/mob/living/carbon/alien/humanoid/regenerate_icons()
..()
@@ -69,8 +69,6 @@
update_transform()
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
if(lying > 0)
lying = 90 //Anything else looks lousy
..()
update_icons()
@@ -84,11 +84,3 @@
/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
return FALSE
/* Commented out because it's duplicated in life.dm
/mob/living/carbon/alien/larva/proc/grow() // Larvae can grow into full fledged Xenos if they survive long enough -- TLE
if(icon_state == "larva_l" && !canmove) // This is a shit death check. It is made of shit and death. Fix later.
return
else
var/mob/living/carbon/alien/humanoid/A = new(loc)
A.key = key
qdel(src) */
@@ -14,7 +14,7 @@
icon_state = "larva[state]_dead"
else if(handcuffed || legcuffed) //This should be an overlay. Who made this an icon_state?
icon_state = "larva[state]_cuff"
else if(stat == UNCONSCIOUS || lying || resting)
else if(stat == UNCONSCIOUS || IS_HORIZONTAL(src))
icon_state = "larva[state]_sleep"
else if(IsStunned())
icon_state = "larva[state]_stun"
@@ -44,20 +44,6 @@
return 1
return ..()
/mob/living/carbon/brain/update_canmove(delay_action_updates = 0)
if(in_contents_of(/obj/mecha))
canmove = 1
use_me = 1 //If it can move, let it emote
else if(istype(loc, /obj/item/mmi))
canmove = 1 //mmi won't move anyways so whatever
else
canmove = 0
if(!delay_action_updates)
update_action_buttons_icon()
return canmove
/mob/living/carbon/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
return
@@ -12,8 +12,7 @@
// can we muster a parent call here?
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
+52 -49
View File
@@ -224,18 +224,19 @@
if(player_logged)
M.visible_message("<span class='notice'>[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \
"<span class='notice'>You shake [src], but [p_theyre()] unresponsive. Probably suffering from SSD.</span>")
if(lying) // /vg/: For hugs. This is how update_icon figgers it out, anyway. - N3X15
if(IS_HORIZONTAL(src)) // /vg/: For hugs. This is how update_icon figgers it out, anyway. - N3X15
add_attack_logs(M, src, "Shaked", ATKLOG_ALL)
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.w_uniform)
H.w_uniform.add_fingerprint(M)
AdjustSleeping(-10 SECONDS)
if(!AmountSleeping())
StopResting()
AdjustParalysis(-6 SECONDS)
AdjustStunned(-6 SECONDS)
AdjustWeakened(-6 SECONDS)
AdjustKnockDown(-6 SECONDS)
resting = FALSE
stand_up() // help them up if possible
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(!player_logged)
M.visible_message( \
@@ -441,8 +442,8 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
to_chat(src, "You must be conscious to do this!")
return
if(lying)
to_chat(src, "You can't vent crawl while you're stunned!")
if(!(mobility_flags & MOBILITY_MOVE))
to_chat(src, "You can't vent crawl while you cannot move!")
return
if(has_buckled_mobs())
@@ -749,41 +750,42 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/Topic(href, href_list)
..()
//strip panel
if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
if(href_list["internal"])
var/slot = text2num(href_list["internal"])
var/obj/item/ITEM = get_item_by_slot(slot)
if(ITEM && istype(ITEM, /obj/item/tank))
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>", \
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>")
if(usr.stat || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.restrained() || !in_range(src, usr))
return
if(href_list["internal"])
var/slot = text2num(href_list["internal"])
var/obj/item/ITEM = get_item_by_slot(slot)
if(ITEM && istype(ITEM, /obj/item/tank))
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>", \
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>")
var/no_mask
if(!get_organ_slot("breathing_tube"))
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
if(!(head && head.flags & AIRTIGHT))
no_mask = 1
if(no_mask)
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
return
var/no_mask
if(!get_organ_slot("breathing_tube"))
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
if(!(head && head.flags & AIRTIGHT))
no_mask = 1
if(no_mask)
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
return
if(do_mob(usr, src, POCKET_STRIP_DELAY))
if(internal)
internal = null
update_action_buttons_icon()
else
var/no_mask2
if(!get_organ_slot("breathing_tube"))
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
if(!(head && head.flags & AIRTIGHT))
no_mask2 = 1
if(no_mask2)
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
return
internal = ITEM
update_action_buttons_icon()
if(do_mob(usr, src, POCKET_STRIP_DELAY))
if(internal)
internal = null
update_action_buttons_icon()
else
var/no_mask2
if(!get_organ_slot("breathing_tube"))
if(!(wear_mask && wear_mask.flags & AIRTIGHT))
if(!(head && head.flags & AIRTIGHT))
no_mask2 = 1
if(no_mask2)
to_chat(usr, "<span class='warning'>[src] is not wearing a suitable mask or helmet!</span>")
return
internal = ITEM
update_action_buttons_icon()
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM].</span>", \
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM].</span>")
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM].</span>", \
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM].</span>")
/mob/living/carbon/get_item_by_slot(slot_id)
switch(slot_id)
@@ -830,8 +832,9 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/proc/canBeHandcuffed()
return FALSE
/mob/living/carbon/fall(forced)
loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing
/mob/living/carbon/fall()
..()
loc.handle_fall()//it's loc so it doesn't call the mob's handle_fall which does nothing
/mob/living/carbon/is_muzzled()
return(istype(wear_mask, /obj/item/clothing/mask/muzzle))
@@ -862,7 +865,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/resist_fire()
fire_stacks -= 5
Weaken(3, TRUE) //We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
update_canmove()
spin(32, 2)
visible_message("<span class='danger'>[src] rolls on the floor, trying to put [p_them()]self out!</span>",
"<span class='notice'>You stop, drop, and roll!</span>")
@@ -973,20 +975,21 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
drop_l_hand()
stop_pulling()
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
ADD_TRAIT(src, TRAIT_RESTRAINED, "handcuffed")
else
REMOVE_TRAIT(src, TRAIT_RESTRAINED, "handcuffed")
clear_alert("handcuffed")
update_action_buttons_icon() //some of our action buttons might be unusable when we're handcuffed.
update_inv_handcuffed()
update_hud_handcuffed()
/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
if(lying)
/mob/living/carbon/get_standard_pixel_y_offset()
if(IS_HORIZONTAL(src))
if(buckled)
return buckled.buckle_offset //tg just has this whole block removed, always returning -6. Paradise is special.
return buckled.buckle_offset
else
return -6
else
return initial(pixel_y)
return PIXEL_Y_OFFSET_LYING
return initial(pixel_y)
/mob/living/carbon/emp_act(severity)
..()
@@ -1039,11 +1042,11 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
W.plane = initial(W.plane)
/mob/living/carbon/proc/slip(description, weaken, tilesSlipped, walkSafely, slipAny, slipVerb = "slip")
/mob/living/carbon/proc/slip(description, knockdown, tilesSlipped, walkSafely, slipAny, slipVerb = "slip")
if(flying || buckled || (walkSafely && m_intent == MOVE_INTENT_WALK))
return FALSE
if((lying) && (!(tilesSlipped)))
if(IS_HORIZONTAL(src) && !tilesSlipped)
return FALSE
if(!(slipAny))
@@ -1062,7 +1065,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3)
// Something something don't run with scissors
moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
Weaken(weaken)
KnockDown(knockdown)
return TRUE
/mob/living/carbon/proc/can_eat(flags = 255)
@@ -1,6 +1,6 @@
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(!skipcatch)
if(in_throw_mode && canmove && !restrained()) //Makes sure player is in throw mode
if(in_throw_mode && !HAS_TRAIT(src, TRAIT_HANDS_BLOCKED) && !restrained()) //Makes sure player is in throw mode
if(!istype(AM,/obj/item) || !isturf(AM.loc))
return FALSE
if(get_active_hand())
@@ -20,7 +20,7 @@
wetlevel = min(wetlevel + 1,5)
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
if(lying && surgeries.len)
if(IS_HORIZONTAL(src) && surgeries.len)
if(user != src && user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
@@ -41,7 +41,7 @@
if(D.IsSpreadByTouch())
ContractDisease(D)
if(lying && surgeries.len)
if(IS_HORIZONTAL(src) && length(surgeries))
if(user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
@@ -2,8 +2,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
if(!ismachineperson(src))
@@ -50,7 +49,6 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = TRUE
canmove = FALSE
dust_animation()
QDEL_IN(src, 20)
return TRUE
@@ -69,8 +67,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -600,7 +600,7 @@
dna.species.spec_electrocute_act(src, shock_damage, source, siemens_coeff, flags = NONE)
/mob/living/carbon/human/Topic(href, href_list)
if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
if(!usr.stat && !HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) && !usr.restrained() && in_range(src, usr))
var/thief_mode = 0
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
@@ -37,7 +37,7 @@ emp_act
return 2
if(mind?.martial_art?.deflection_chance) //Some martial arts users can deflect projectiles!
if(!lying && !HAS_TRAIT(src, TRAIT_HULK) && mind.martial_art.try_deflect(src)) //But only if they're not lying down, and hulks can't do it
if(!IS_HORIZONTAL(src) && !HAS_TRAIT(src, TRAIT_HULK) && mind.martial_art.try_deflect(src)) //But only if they're not lying down, and hulks can't do it
add_attack_logs(P.firer, src, "hit by [P.type] but got deflected by martial arts '[mind.martial_art]'")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, TRUE)
if(HAS_TRAIT(src, TRAIT_PACIFISM) || !P.is_reflectable(REFLECTABILITY_PHYSICAL)) //if it cannot be reflected, it hits the floor. This is the exception to the rule
@@ -748,3 +748,7 @@ emp_act
to_chat(src, "<span class='danger'>Your [head.name] protects you from the [hot ? "hot" : "cold"] liquid!</span>")
return FALSE
return TRUE
/mob/living/carbon/human/projectile_hit_check(obj/item/projectile/P)
return HAS_TRAIT(src, TRAIT_FLOORED) && !density // hit mobs that are intentionally lying down to prevent combat crawling.
@@ -332,7 +332,7 @@
var/mob/living/carbon/human/human_target = target
if(human_target.canmove && !human_target.r_hand && !human_target.restrained())
if(!HAS_TRAIT(human_target, TRAIT_HANDS_BLOCKED) && !human_target.r_hand && !human_target.restrained())
message_param = "shakes hands with %t."
else
message_param = "holds out [user.p_their()] hand to %t."
@@ -350,7 +350,7 @@
)
return TRUE
if(target.canmove && !target.r_hand && !target.restrained())
if(!HAS_TRAIT(target, TRAIT_HANDS_BLOCKED) && !target.r_hand && !target.restrained())
message_param = "shakes hands with %t."
else
message_param = "holds out [user.p_their()] hand to %t."
@@ -35,7 +35,7 @@
/mob/living/carbon/human/Move(NewLoc, direct)
. = ..()
if(.) // did we actually move?
if(!lying && !buckled && !throwing)
if(!IS_HORIZONTAL(src) && !buckled && !throwing)
for(var/obj/item/organ/external/splinted in splinted_limbs)
splinted.update_splints()
@@ -44,7 +44,7 @@
var/obj/item/clothing/shoes/S = shoes
if(S && !lying && loc == NewLoc)
if(S && !IS_HORIZONTAL(src) && loc == NewLoc)
SEND_SIGNAL(S, COMSIG_SHOES_STEP_ACTION)
//Bloody footprints
@@ -19,7 +19,7 @@
var/obj/item/organ/external/E = Y
E.process()
if(!lying && world.time - l_move_time < 15)
if(!IS_HORIZONTAL(src) && world.time - l_move_time < 15)
//Moving around with fractured ribs won't do you any good
if(E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
var/obj/item/organ/internal/I = pick(E.internal_organs)
@@ -34,7 +34,7 @@
/mob/living/carbon/human/proc/handle_stance()
// Don't need to process any of this if they aren't standing anyways
// unless their stance is damaged, and we want to check if they should stay down
if(!stance_damage && (lying || resting) && (life_tick % 4) == 0)
if(!stance_damage && IS_HORIZONTAL(src) && (life_tick % 4) == 0)
return
stance_damage = 0
@@ -64,11 +64,11 @@
// standing is poor
if(stance_damage >= 8)
if(!(lying || resting))
if(!IS_HORIZONTAL(src))
if(!HAS_TRAIT(src, TRAIT_NOPAIN))
emote("scream")
emote("collapses")
Weaken(10 SECONDS) //can't emote while weakened, apparently.
KnockDown(10 SECONDS)
/mob/living/carbon/human/proc/handle_grasp()
@@ -239,10 +239,13 @@
. = 0 //We start at 0.
if(has_gravity(H))
if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST))
. -= 1
else if(HAS_TRAIT(H, TRAIT_GOTTAGONOTSOFAST))
. -= 0.5
if(!IS_HORIZONTAL(H))
if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST))
. -= 1
else if(HAS_TRAIT(H, TRAIT_GOTTAGONOTSOFAST))
. -= 0.5
else
. += GLOB.configuration.movement.crawling_speed_reduction
var/ignoreslow = FALSE
if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
@@ -505,7 +508,7 @@
"<span class='userdanger'>[user] has weakened [target]!</span>")
target.apply_effect(8 SECONDS, WEAKEN, armor_block)
target.forcesay(GLOB.hit_appends)
else if(target.lying)
else if(IS_HORIZONTAL(target))
target.forcesay(GLOB.hit_appends)
SEND_SIGNAL(target, COMSIG_PARENT_ATTACKBY)
@@ -131,7 +131,7 @@
return
if(!robohead.is_monitor) //If they've got a prosthetic head and it isn't a monitor, they've no screen to adjust. Instead, let them change the colour of their optics!
var/optic_colour = input(H, "Select optic colour", H.m_colours["head"]) as color|null
if(H.incapacitated(TRUE, TRUE, TRUE))
if(H.incapacitated(TRUE, TRUE))
to_chat(H, "<span class='warning'>You were interrupted while changing the colour of your optics.</span>")
return
if(optic_colour)
@@ -153,7 +153,7 @@
var/new_style = input(H, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair
var/new_color = input("Please select hair color.", "Monitor Color", head_organ.hair_colour) as null|color
if(H.incapacitated(TRUE, TRUE, TRUE))
if(H.incapacitated(TRUE, TRUE))
to_chat(H, "<span class='warning'>You were interrupted while changing your monitor display.</span>")
return
@@ -40,7 +40,7 @@
/datum/species/monkey/handle_npc(mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
return
if(prob(33) && H.canmove && isturf(H.loc) && !H.pulledby) //won't move if being pulled
if(prob(33) && (H.mobility_flags & MOBILITY_MOVE) && isturf(H.loc) && !H.pulledby) //won't move if being pulled
step(H, pick(GLOB.cardinal))
if(prob(1))
H.emote(pick("scratch","jump","roll","tail"))
@@ -139,7 +139,7 @@
return
H.visible_message("<span class='notice'>[H] begins to hold still and concentrate on weaving a cocoon...</span>", "<span class='notice'>You begin to focus on weaving a cocoon... (This will take [COCOON_WEAVE_DELAY / 10] seconds, and you must hold still.)</span>")
if(do_after(H, COCOON_WEAVE_DELAY, FALSE, H))
if(H.incapacitated(ignore_lying = TRUE))
if(H.incapacitated())
to_chat(H, "<span class='warning'>You cannot weave a cocoon in your current state.</span>")
return
H.visible_message("<span class='notice'>[H] finishes weaving a cocoon!</span>", "<span class='notice'>You finish weaving your cocoon.</span>")
@@ -152,7 +152,7 @@
H.visible_message("<span class='notice'>[H] begins to hold still and concentrate on [H.p_their()] missing [limb_select]...</span>", "<span class='notice'>You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)</span>")
if(do_after(H, SLIMEPERSON_REGROWTHDELAY, FALSE, H, extra_checks = list(CALLBACK(H, /mob/living.proc/IsStunned)), use_default_checks = FALSE)) // Override the check for weakness, only check for stunned
if(H.incapacitated(ignore_lying = TRUE, extra_checks = list(CALLBACK(H, /mob/living.proc/IsStunned)), use_default_checks = FALSE)) // Override the check for weakness, only check for stunned
if(H.incapacitated(extra_checks = list(CALLBACK(H, /mob/living.proc/IsStunned)), use_default_checks = FALSE)) // Override the check for weakness, only check for stunned
to_chat(H, "<span class='warning'>You cannot regenerate missing limbs in your current state.</span>")
return
@@ -10,6 +10,8 @@
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
var/prev = stam_paralyzed
stam_paralyzed = TRUE
update_canmove()
ADD_TRAIT(src, TRAIT_IMMOBILIZED, "stam_crit") // make defines later
ADD_TRAIT(src, TRAIT_FLOORED, "stam_crit")
ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, "stam_crit")
if(!prev && getStaminaLoss() < 120) // Puts you a little further into the initial stamcrit, makes stamcrit harder to outright counter with chems.
adjustStaminaLoss(30, FALSE)
+9 -14
View File
@@ -1,5 +1,3 @@
//LOOK G-MA, I'VE JOINED CARBON PROCS THAT ARE IDENTICAL IN ALL CASES INTO ONE PROC, I'M BETTER THAN LIFE()
//I thought about mob/living but silicons and simple_animals don't want this just yet.
//Right now just handles lying down, but could handle other cases later.
//IMPORTANT: Multiple animate() calls do not stack well, so try to do them all at once if you can.
/mob/living/carbon/update_transform()
@@ -7,29 +5,26 @@
var/final_pixel_y = pixel_y
var/final_dir = dir
var/changed = 0
if(lying != lying_prev)
if(lying_angle != lying_prev)
changed++
ntransform.TurnTo(lying_prev,lying)
if(lying == 0) //Lying to standing
final_pixel_y = get_standard_pixel_y_offset()
ntransform.TurnTo(lying_prev , lying_angle)
if(!lying_angle) //Lying to standing
final_pixel_y = pixel_y
else //if(lying != 0)
if(lying_prev == 0) //Standing to lying
pixel_y = get_standard_pixel_y_offset()
final_pixel_y = get_standard_pixel_y_offset(lying)
pixel_y = pixel_y
final_pixel_y = pixel_y + PIXEL_Y_OFFSET_LYING
if(dir & (EAST|WEST)) //Facing east or west
final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
lying_prev = lying //so we don't try to animate until there's been another change.
if(resize != RESIZE_DEFAULT_SIZE)
changed++
ntransform.Scale(resize)
resize = RESIZE_DEFAULT_SIZE
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
handle_transform_change()
floating = FALSE // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
floating = FALSE
animate(src, transform = ntransform, time = (lying_prev == 0 || lying_angle == 0) ? 2 : 0, pixel_y = final_pixel_y, dir = final_dir, easing = (EASE_IN|EASE_OUT))
/mob/living/carbon/proc/handle_transform_change()
return
@@ -25,7 +25,9 @@
enter_stamcrit()
else if(stam_paralyzed)
stam_paralyzed = FALSE
update_canmove()
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, "stam_crit") // make defines later
REMOVE_TRAIT(src, TRAIT_FLOORED, "stam_crit")
REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, "stam_crit")
/mob/living/carbon/can_hear()
. = FALSE
+4 -10
View File
@@ -4,8 +4,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
// hide and freeze for the GC
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -22,8 +21,7 @@
return FALSE
new /obj/effect/decal/cleanable/ash(loc)
// hide and freeze them while they get GC'd
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
QDEL_IN(src, 0)
@@ -33,8 +31,7 @@
if(!death(TRUE) && stat != DEAD)
return FALSE
// hide and freeze them while they get GC'd
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
QDEL_IN(src, 0)
@@ -70,7 +67,7 @@
hud_used?.reload_fullscreen()
update_sight()
update_action_buttons_icon()
ADD_TRAIT(src, TRAIT_FLOORED, STAT_TRAIT)
update_damage_hud()
update_health_hud()
med_hud_set_health()
@@ -78,9 +75,6 @@
if(!gibbed && !QDELETED(src))
addtimer(CALLBACK(src, .proc/med_hud_set_status), DEFIB_TIME_LIMIT + 1)
if(!gibbed)
update_canmove()
GLOB.alive_mob_list -= src
GLOB.dead_mob_list += src
if(mind)
+136
View File
@@ -0,0 +1,136 @@
/// Called on [/mob/living/Initialize(mapload)], for the mob to register to relevant signals.
/mob/living/proc/register_init_signals()
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_KNOCKEDOUT), .proc/on_knockedout_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_KNOCKEDOUT), .proc/on_knockedout_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_FAKEDEATH), .proc/on_fakedeath_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_FAKEDEATH), .proc/on_fakedeath_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), .proc/on_immobilized_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED), .proc/on_immobilized_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_FLOORED), .proc/on_floored_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_FLOORED), .proc/on_floored_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), .proc/on_handsblocked_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED), .proc/on_handsblocked_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_UI_BLOCKED), .proc/on_ui_blocked_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_UI_BLOCKED), .proc/on_ui_blocked_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_CANNOT_PULL), .proc/on_pull_blocked_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_CANNOT_PULL), .proc/on_pull_blocked_trait_loss)
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_RESTRAINED), .proc/on_restrained_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_RESTRAINED), .proc/on_restrained_trait_loss)
/// Called when [TRAIT_KNOCKEDOUT] is added to the mob.
/mob/living/proc/on_knockedout_trait_gain(datum/source)
SIGNAL_HANDLER
if(stat < UNCONSCIOUS)
KnockOut()
/// Called when [TRAIT_KNOCKEDOUT] is removed from the mob.
/mob/living/proc/on_knockedout_trait_loss(datum/source)
SIGNAL_HANDLER
if(stat <= UNCONSCIOUS)
WakeUp()
/// Called when [TRAIT_IMMOBILIZED] is added to the mob.
/mob/living/proc/on_immobilized_trait_gain(datum/source)
SIGNAL_HANDLER
mobility_flags &= ~MOBILITY_MOVE
/// Called when [TRAIT_IMMOBILIZED] is removed from the mob.
/mob/living/proc/on_immobilized_trait_loss(datum/source)
SIGNAL_HANDLER
mobility_flags |= MOBILITY_MOVE
/// Called when [TRAIT_FLOORED] is added to the mob.
/mob/living/proc/on_floored_trait_gain(datum/source)
SIGNAL_HANDLER
mobility_flags &= ~MOBILITY_STAND
on_floored_start()
/mob/living/proc/on_floored_start()
if(body_position == STANDING_UP) //force them on the ground
fall()
/// Called when [TRAIT_FLOORED] is removed from the mob.
/mob/living/proc/on_floored_trait_loss(datum/source)
SIGNAL_HANDLER
mobility_flags |= MOBILITY_STAND
on_floored_end()
/mob/living/proc/on_floored_end()
if(!resting)
stand_up(FALSE)
/// Called when [TRAIT_HANDS_BLOCKED] is added to the mob.
/mob/living/proc/on_handsblocked_trait_gain(datum/source)
SIGNAL_HANDLER
mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP)
on_handsblocked_start()
/mob/living/proc/on_handsblocked_start()
drop_l_hand()
drop_r_hand()
ADD_TRAIT(src, TRAIT_UI_BLOCKED, TRAIT_HANDS_BLOCKED)
ADD_TRAIT(src, TRAIT_CANNOT_PULL, TRAIT_HANDS_BLOCKED)
/// Called when [TRAIT_HANDS_BLOCKED] is removed from the mob.
/mob/living/proc/on_handsblocked_trait_loss(datum/source)
SIGNAL_HANDLER
mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP)
on_handsblocked_end()
/mob/living/proc/on_handsblocked_end()
REMOVE_TRAIT(src, TRAIT_UI_BLOCKED, TRAIT_HANDS_BLOCKED)
REMOVE_TRAIT(src, TRAIT_CANNOT_PULL, TRAIT_HANDS_BLOCKED)
/// Called when [TRAIT_UI_BLOCKED] is added to the mob.
/mob/living/proc/on_ui_blocked_trait_gain(datum/source)
SIGNAL_HANDLER
unset_machine()
update_action_buttons_icon()
/// Called when [TRAIT_UI_BLOCKED] is removed from the mob.
/mob/living/proc/on_ui_blocked_trait_loss(datum/source)
SIGNAL_HANDLER
update_action_buttons_icon()
/// Called when [TRAIT_CANNOT_PULL] is added to the mob.
/mob/living/proc/on_pull_blocked_trait_gain(datum/source)
SIGNAL_HANDLER
mobility_flags &= ~(MOBILITY_PULL)
if(pulling)
stop_pulling()
/// Called when [TRAIT_CANNOT_PULL] is removed from the mob.
/mob/living/proc/on_pull_blocked_trait_loss(datum/source)
SIGNAL_HANDLER
mobility_flags |= MOBILITY_PULL
/// Called when [TRAIT_RESTRAINED] is added to the mob.
/mob/living/proc/on_restrained_trait_gain(datum/source)
SIGNAL_HANDLER
ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_RESTRAINED)
/// Called when [TRAIT_RESTRAINED] is removed from the mob.
/mob/living/proc/on_restrained_trait_loss(datum/source)
SIGNAL_HANDLER
REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_RESTRAINED)
/// Called when [TRAIT_FAKEDEATH] is added to the mob.
/mob/living/proc/on_fakedeath_trait_gain(datum/source)
SIGNAL_HANDLER
ADD_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_FAKEDEATH)
/// Called when [TRAIT_FAKEDEATH] is removed from the mob.
/mob/living/proc/on_fakedeath_trait_loss(datum/source)
SIGNAL_HANDLER
REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_FAKEDEATH)
+15 -10
View File
@@ -2,6 +2,7 @@
. = ..()
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medhud.add_to_hud(src)
register_init_signals()
faction += "\ref[src]"
determine_move_and_pull_forces()
GLOB.mob_living_list += src
@@ -243,7 +244,7 @@
//same as above
/mob/living/pointed(atom/A as mob|obj|turf in view())
if(incapacitated(ignore_lying = TRUE))
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return FALSE
if(HAS_TRAIT(src, TRAIT_FAKEDEATH))
return FALSE
@@ -450,6 +451,7 @@
SetWeakened(0, TRUE)
SetSlowed(0)
SetImmobilized(0)
SetKnockDown(0)
SetLoseBreath(0)
SetDizzy(0)
SetJitter(0)
@@ -495,7 +497,6 @@
human_mob.restore_blood()
human_mob.decaylevel = 0
human_mob.remove_all_embedded_objects()
SEND_SIGNAL(src, COMSIG_LIVING_AHEAL)
restore_all_organs()
surgeries.Cut() //End all surgeries.
@@ -510,10 +511,14 @@
if(human_mob)
human_mob.update_eyes()
human_mob.update_dna()
resting = FALSE
stand_up() // wake the fuck up badmin, we've got an "event" to burn
return
/mob/living/proc/remove_CC(should_update_canmove = TRUE)
/mob/living/proc/remove_CC()
SetWeakened(0)
SetKnockDown(0)
SetStunned(0)
SetParalysis(0)
SetImmobilized(0)
@@ -537,7 +542,7 @@
if(pullee && !isturf(pullee.loc) && pullee.loc != loc)
log_game("DEBUG: [src]'s pull on [pullee] was broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
stop_pulling()
if(restrained())
if(restrained() || HAS_TRAIT(src, TRAIT_CANNOT_PULL))
stop_pulling()
var/turf/old_loc = loc
@@ -563,7 +568,7 @@
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
if(isliving(pulling))
var/mob/living/M = pulling
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
if(IS_HORIZONTAL(M) && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
M.makeTrail(dest)
pulling.Move(dest, get_dir(pulling, dest), movetime) // the pullee tries to reach our previous position
if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up
@@ -706,7 +711,7 @@
*///////////////////////
/mob/living/can_resist()
return !((next_move > world.time) || incapacitated(ignore_restraints = TRUE, ignore_lying = TRUE))
return !((next_move > world.time) || incapacitated(ignore_restraints = TRUE))
/mob/living/verb/resist()
set name = "Resist"
@@ -731,7 +736,7 @@
var/obj/C = loc
C.container_resist(src)
else if(canmove)
else if(mobility_flags & MOBILITY_MOVE)
if(on_fire)
resist_fire() //stop, drop, and roll
else
@@ -812,7 +817,7 @@
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
floating = TRUE
else if(((!on || fixed) && floating))
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
animate(src, pixel_y = get_standard_pixel_y_offset(), time = 10)
floating = FALSE
/mob/living/proc/can_use_vents()
@@ -936,10 +941,10 @@
return loc_temp
/mob/living/proc/get_standard_pixel_x_offset(lying = 0)
/mob/living/proc/get_standard_pixel_x_offset()
return initial(pixel_x)
/mob/living/proc/get_standard_pixel_y_offset(lying = 0)
/mob/living/proc/get_standard_pixel_y_offset()
return initial(pixel_y)
/mob/living/proc/spawn_dust()
@@ -72,3 +72,11 @@
var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added
var/stam_regen_start_time = 0 //used to halt stamina regen temporarily
var/stam_paralyzed = FALSE //knocks you down
/// Number of degrees of rotation of a mob. 0 means no rotation, up-side facing NORTH. 90 means up-side rotated to face EAST, and so on.
VAR_PROTECTED/lying_angle = 0
/// if a mob is choosing to lay down
var/resting = FALSE
var/body_position = STANDING_UP
var/mobility_flags = MOBILITY_FLAGS_DEFAULT
+1 -4
View File
@@ -145,7 +145,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
aiPDA = new/obj/item/pda/silicon/ai(src)
rename_character(null, pickedName)
anchored = 1
canmove = 0
density = 1
loc = loc
@@ -173,7 +172,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
add_ai_verbs(src)
// Remove inherited verbs that effectively do nothing for AIs, or lead to unintended behaviour.
verbs -= /mob/living/verb/lay_down
verbs -= /mob/living/verb/rest
verbs -= /mob/living/verb/mob_sleep
verbs -= /mob/living/verb/resist
verbs -= /mob/living/verb/stop_pulling1
@@ -588,8 +587,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]")
/mob/living/silicon/ai/update_canmove()
return FALSE
/mob/living/silicon/ai/proc/announcement()
set name = "Announcement"
+2 -4
View File
@@ -1,8 +1,7 @@
/mob/living/silicon/gib()
death(1)
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -24,8 +23,7 @@
/mob/living/silicon/dust()
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
dust_animation()
@@ -3,7 +3,7 @@
icon = 'icons/mob/ai.dmi'//
icon_state = "ai"
anchored = 1 // -- TLE
canmove = 0
mobility_flags = 0
a_intent = INTENT_HARM // This is apparently the only thing that stops other mobs walking through them as if they were thin air.
/mob/living/silicon/decoy/attackby(obj/item/W, mob/user, params)
+10 -14
View File
@@ -328,19 +328,19 @@
verbs -= /mob/living/silicon/pai/proc/choose_verbs
/mob/living/silicon/pai/lay_down()
/mob/living/silicon/pai/rest()
set name = "Rest"
set category = "IC"
// Pass lying down or getting up to our pet human, if we're in a rig.
if(stat == CONSCIOUS && istype(loc,/obj/item/paicard))
resting = 0
resting = !resting
if(resting)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LYING_DOWN_TRAIT)
else
resting = !resting
to_chat(src, "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>")
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LYING_DOWN_TRAIT)
to_chat(src, "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>")
update_icons()
update_canmove()
//Overriding this will stop a number of headaches down the track.
/mob/living/silicon/pai/attackby(obj/item/W as obj, mob/user as mob, params)
@@ -385,7 +385,7 @@
/mob/living/silicon/pai/proc/close_up()
last_special = world.time + 200
resting = 0
stand_up()
if(loc == card)
return
@@ -420,10 +420,6 @@
/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = pull_force, show_message = FALSE)
return FALSE
/mob/living/silicon/pai/update_canmove(delay_action_updates = 0)
. = ..()
density = 0 //this is reset every canmove update otherwise
/mob/living/silicon/pai/examine(mob/user)
. = ..()
@@ -471,9 +467,9 @@
H.icon = 'icons/mob/pai.dmi'
H.icon_state = "[chassis]_dead"
return
if(resting)
if(IS_HORIZONTAL(src))
icon_state = "[chassis]"
resting = 0
stand_up()
if(custom_sprite)
H.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
H.icon_override = 'icons/mob/custom_synthetic/custom_head.dmi'
@@ -3,8 +3,7 @@
return FALSE
//robots don't die when gibbed. instead they drop their MMI'd brain
var/atom/movable/overlay/animation = null
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -27,8 +26,7 @@
/mob/living/silicon/robot/dust()
if(!death(TRUE) && stat != DEAD)
return FALSE
notransform = 1
canmove = 0
notransform = TRUE
invisibility = 101
dust_animation()
if(mmi)
@@ -359,10 +359,6 @@
/mob/living/silicon/robot/drone/remove_robot_verbs()
verbs -= silicon_subsystems
/mob/living/silicon/robot/drone/update_canmove(delay_action_updates = FALSE)
. = ..()
density = emagged //this is reset every canmove update otherwise
/mob/living/silicon/robot/drone/add_ventcrawl(obj/machinery/atmospherics/starting_machine)
..()
update_headlamp(TRUE, 0, FALSE)
@@ -53,8 +53,8 @@
var/obj/item/holder/H = ..()
if(!istype(H))
return
if(resting)
resting = 0
if(IS_HORIZONTAL(src))
stand_up()
if(custom_sprite)
H.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
H.icon_override = 'icons/mob/custom_synthetic/custom_head.dmi'
@@ -48,13 +48,13 @@
var/mob/living/carbon/human/H
if(!gripped_item && proximity && target && ishuman(target))
H = target
if(H.lying)
if(IS_HORIZONTAL(H))
H.AdjustSleeping(-10 SECONDS)
if(!H.IsSleeping())
H.StopResting()
H.AdjustParalysis(-6 SECONDS)
H.AdjustStunned(-6 SECONDS)
H.AdjustWeakened(-6 SECONDS)
H.AdjustKnockDown(-6 SECONDS)
H.stand_up()
playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
user.visible_message( \
"<span class='notice'>[user] shakes [H] trying to wake [H.p_them()] up!</span>",\
@@ -132,16 +132,6 @@
weapon_lock = 0
weaponlock_time = 120
/mob/living/silicon/robot/update_canmove(delay_action_updates = 0)
if(IsParalyzed() || IsStunned() || IsWeakened() || buckled || lockcharge || stat)
canmove = FALSE
else
canmove = TRUE
update_transform()
if(!delay_action_updates)
update_action_buttons_icon()
return canmove
//Robots on fire
/mob/living/silicon/robot/handle_fire()
. = ..()
@@ -162,7 +162,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
add_robot_verbs()
// Remove inherited verbs that effectively do nothing for cyborgs, or lead to unintended behaviour.
verbs -= /mob/living/verb/lay_down
verbs -= /mob/living/verb/rest
verbs -= /mob/living/verb/mob_sleep
// Install a default cell into the borg if none is there yet
@@ -1167,10 +1167,10 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
disconnect_from_ai()
lawupdate = 0
lockcharge = 0
canmove = 1
REMOVE_TRAITS_IN(src, LOCKDOWN_TRAIT)
scrambledcodes = 1
//Disconnect it's camera so it's not so easily tracked.
QDEL_NULL(src.camera)
QDEL_NULL(camera)
// I'm trying to get the Cyborg to not be listed in the camera list
// Instead of being listed as "deactivated". The downside is that I'm going
// to have to check if every camera is null or not before doing anything, to prevent runtime errors.
@@ -1208,7 +1208,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
else
clear_alert("locked")
lockcharge = state
update_canmove()
if(state) // turn them off
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LOCKDOWN_TRAIT)
ADD_TRAIT(src, TRAIT_UI_BLOCKED, LOCKDOWN_TRAIT)
ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, LOCKDOWN_TRAIT)
else
REMOVE_TRAITS_IN(src, LOCKDOWN_TRAIT)
/mob/living/silicon/robot/proc/choose_icon(triesleft, list/module_sprites)
@@ -1,6 +1,6 @@
/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M)
if(M.a_intent == INTENT_DISARM)
if(!lying)
if(mobility_flags & MOBILITY_MOVE)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
var/obj/item/I = get_active_hand()
if(I)
@@ -461,7 +461,7 @@
I.clean_blood()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(!cleaned_human.lying)
if(!IS_HORIZONTAL(cleaned_human))
continue
cleaned_human.clean_blood()
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
@@ -1,5 +1,5 @@
// No args for restraints because robots don't have those
/mob/living/silicon/robot/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE)
/mob/living/silicon/robot/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE)
if(stat || lockcharge || IsWeakened() || IsStunned() || IsParalyzed() || !is_component_functioning("actuator"))
return TRUE
@@ -14,7 +14,7 @@
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || IsParalyzed() || IsSleeping() || resting || IsStunned() || IsWeakened() || getOxyLoss() > maxHealth * 0.5)
if(!is_component_functioning("actuator") || !is_component_functioning("power cell") || HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || IsStunned() || IsWeakened() || getOxyLoss() > maxHealth * 0.5)
if(stat == CONSCIOUS)
KnockOut()
update_headlamp()
@@ -367,3 +367,15 @@
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
/mob/living/silicon/can_hear()
. = TRUE
/mob/living/silicon/on_floored_start()
return // Silicons are always standing by default.
/mob/living/silicon/on_floored_end()
return // Silicons are always standing by default.
/mob/living/silicon/on_lying_down()
return // Silicons are always standing by default.
/mob/living/silicon/on_standing_up()
return // Silicons are always standing by default.
@@ -126,6 +126,7 @@
if(stat)
return 0
on = 1
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, "depowered")
set_light(initial(light_range))
update_icon()
update_controls()
@@ -134,6 +135,7 @@
/mob/living/simple_animal/bot/proc/turn_off()
on = 0
ADD_TRAIT(src, TRAIT_IMMOBILIZED, "depowered")
set_light(0)
bot_reset() //Resets an AI's call, should it exist.
update_icon()
@@ -192,11 +194,6 @@
/mob/living/simple_animal/bot/med_hud_set_status()
return //we use a different hud
/mob/living/simple_animal/bot/update_canmove(delay_action_updates = 0)
. = ..()
if(!on)
. = 0
canmove = .
/mob/living/simple_animal/bot/Destroy()
if(paicard)
@@ -228,7 +228,7 @@
var/list/targets = list()
for(var/mob/living/carbon/C in view(7, src)) //Let's find us a target
var/threatlevel = 0
if((C.stat) || (C.lying))
if(C.stat || !(mobility_flags & MOBILITY_MOVE))
continue
threatlevel = C.assess_threat(src, lasercolor)
//speak(C.real_name + text(": threat: []", threatlevel))
@@ -240,9 +240,9 @@
continue
targets += C
if(targets.len>0)
if(length(targets))
var/mob/living/carbon/t = pick(targets)
if((t.stat!=2) && (t.lying != 1) && (!t.handcuffed)) //we don't shoot people who are dead, cuffed or lying down.
if(t.stat != DEAD && !HAS_TRAIT(t, TRAIT_FLOORED) && !t.handcuffed) //we don't shoot people who are dead, cuffed or lying down.
shootAt(t)
switch(mode)
@@ -339,7 +339,7 @@
// can load anything if hacked
/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
if(user.incapacitated() || user.lying || get_dist(user, src) > 1)
if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || get_dist(user, src) > 1)
return
if(!istype(AM))
@@ -104,17 +104,16 @@
if(!stat && !buckled)
if(prob(1))
custom_emote(EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
StartResting()
lay_down()
else if(prob(1))
custom_emote(EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert."))
icon_state = "[icon_living]_sit"
collar_type = "[initial(collar_type)]_sit"
resting = TRUE
update_canmove()
lay_down()
else if(prob(1))
if(resting)
if(IS_HORIZONTAL(src))
custom_emote(EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting."))
StopResting()
stand_up()
else
custom_emote(EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
@@ -135,24 +134,26 @@
/mob/living/simple_animal/pet/cat/handle_automated_movement()
. = ..()
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
walk_to(src,0)
turns_since_scan = 0
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
movement_target = null
stop_automated_movement = 0
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
movement_target = null
stop_automated_movement = 0
for(var/mob/living/simple_animal/mouse/snack in oview(src,3))
if(isturf(snack.loc) && !snack.stat)
movement_target = snack
break
if(movement_target)
stop_automated_movement = 1
walk_to(src,movement_target,0,3)
if(stat || IS_HORIZONTAL(src) || buckled)
return
turns_since_scan++
if(turns_since_scan > 5)
walk_to(src,0)
turns_since_scan = 0
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc)))
movement_target = null
stop_automated_movement = 0
if( !movement_target || !(movement_target.loc in oview(src, 3)) )
movement_target = null
stop_automated_movement = 0
for(var/mob/living/simple_animal/mouse/snack in oview(src,3))
if(isturf(snack.loc) && !snack.stat)
movement_target = snack
break
if(movement_target)
stop_automated_movement = 1
walk_to(src,movement_target,0,3)
/mob/living/simple_animal/pet/cat/Proc
name = "Proc"
@@ -23,13 +23,14 @@
/mob/living/simple_animal/crab/handle_automated_movement()
//CRAB movement
if(!stat)
if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
var/east_vs_west = pick(4, 8)
if(Process_Spacemove(east_vs_west))
Move(get_step(src, east_vs_west), east_vs_west)
if(!stat || !isturf(loc) || IS_HORIZONTAL(src) || buckled)
return
turns_since_move++
if(turns_since_move >= turns_per_move)
var/east_vs_west = pick(4, 8)
if(Process_Spacemove(east_vs_west))
Move(get_step(src, east_vs_west), east_vs_west)
/mob/living/simple_animal/crab/npc_safe(mob/user)
return TRUE
@@ -479,7 +479,7 @@
/mob/living/simple_animal/pet/dog/corgi/Ian/handle_automated_movement()
. = ..()
//Feeding, chasing food, FOOOOODDDD
if(resting || buckled)
if(IS_HORIZONTAL(src) || buckled)
return
if(++turns_since_scan > 5)
@@ -633,7 +633,7 @@
/mob/living/simple_animal/pet/dog/corgi/Lisa/handle_automated_movement()
. = ..()
if(!resting && !buckled)
if(!IS_HORIZONTAL(src) && !buckled)
if(prob(1))
custom_emote(EMOTE_VISIBLE, pick("dances around.","chases her tail."))
spin(20, 1)
@@ -729,7 +729,7 @@
/mob/living/simple_animal/pet/dog/pug/handle_automated_movement()
. = ..()
if(!resting && !buckled)
if(!IS_HORIZONTAL(src) && !buckled)
if(prob(1))
custom_emote(EMOTE_VISIBLE, pick("chases its tail."))
spawn(0)
@@ -63,13 +63,13 @@
/mob/living/simple_animal/mouse/handle_automated_movement()
. = ..()
if(resting)
if(IS_HORIZONTAL(src))
if(prob(1))
StopResting()
stand_up()
else if(prob(5))
custom_emote(EMOTE_AUDIBLE, "snuffles")
else if(prob(0.5))
StartResting()
lay_down()
/mob/living/simple_animal/mouse/New()
..()
@@ -45,14 +45,14 @@
/mob/living/simple_animal/hostile/hellhound/handle_automated_action()
if(!..())
return
if(resting)
if(IS_HORIZONTAL(src))
if(!wants_to_rest())
custom_emote(EMOTE_VISIBLE, "growls, and gets up.")
playsound(get_turf(src), 'sound/hallucinations/growl2.ogg', 50, 1)
StopResting()
stand_up()
else if(wants_to_rest())
custom_emote(EMOTE_VISIBLE, "lays down, and starts to lick their wounds.")
StartResting()
lay_down()
/mob/living/simple_animal/hostile/hellhound/examine(mob/user)
. = ..()
@@ -68,7 +68,7 @@
msgs += "<span class='warning'>It has many injuries.</span>"
else if(health > (maxHealth*0.25))
msgs += "<span class='warning'>It is covered in wounds!</span>"
if(resting)
if(IS_HORIZONTAL(src))
if(getBruteLoss() || getFireLoss())
msgs += "<span class='warning'>It is currently licking its wounds, regenerating the damage to its body!</span>"
else
@@ -77,7 +77,7 @@
/mob/living/simple_animal/hostile/hellhound/Life(seconds, times_fired)
. = ..()
if(stat != DEAD && resting && (getBruteLoss() || getFireLoss()))
if(stat != DEAD && IS_HORIZONTAL(src) && (getBruteLoss() || getFireLoss()))
if(life_regen_cycles >= life_regen_cycle_trigger)
life_regen_cycles = 0
to_chat(src, "<span class='notice'>You lick your wounds, helping them close.</span>")
@@ -318,7 +318,7 @@ Difficulty: Hard
return TRUE
if(isliving(target))
var/mob/living/livingtarget = target
return (livingtarget.stat != CONSCIOUS || livingtarget.lying)
return (livingtarget.stat != CONSCIOUS || IS_HORIZONTAL(livingtarget))
return FALSE
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_retreat_distance()
@@ -177,7 +177,7 @@
return TRUE
if(isliving(mover))
var/mob/living/M = mover
if(M.lying)
if(!(M.mobility_flags & MOBILITY_MOVE))
return TRUE
return prob(80)
if(istype(mover, /obj/item/projectile))
@@ -153,7 +153,7 @@
/mob/living/simple_animal/parrot/Topic(href, href_list)
//Can the usr physically do this?
if(!usr.canmove || usr.stat || usr.restrained() || !usr.Adjacent(src))
if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.stat || usr.restrained() || !usr.Adjacent(src))
return
//Is the usr's mob type able to do this?
@@ -308,8 +308,8 @@
parrot_state = PARROT_WANDER
return
if(!isturf(loc) || !canmove || buckled)
return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove)
if(!isturf(loc) || !(mobility_flags & MOBILITY_MOVE) || buckled)
return //If it can't move, dont let it move.
//-----SPEECH
/* Parrot speech mimickry!
@@ -42,7 +42,7 @@
var/response = alert(src, "End your possession of this object? (It will not stop you from respawning later)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
StartResting()
lay_down()
var/mob/dead/observer/ghost = ghostize(1)
ghost.timeofdeath = world.time
death(0) // Turn back into a regular object.
@@ -164,15 +164,16 @@
health = clamp(health, 0, maxHealth)
med_hud_set_health()
/mob/living/simple_animal/StartResting(updating = 1)
/mob/living/simple_animal/lay_down()
..()
if(icon_resting && stat != DEAD)
icon_state = icon_resting
if(collar_type)
collar_type = "[initial(collar_type)]_rest"
regenerate_icons()
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LYING_DOWN_TRAIT) //simple mobs cannot crawl
/mob/living/simple_animal/StopResting(updating = 1)
/mob/living/simple_animal/stand_up()
..()
if(icon_resting && stat != DEAD)
icon_state = icon_living
@@ -202,7 +203,7 @@
/mob/living/simple_animal/proc/handle_automated_movement()
set waitfor = FALSE
if(!stop_automated_movement && wander)
if((isturf(loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
if((isturf(loc) || allow_movement_on_non_turfs) && !IS_HORIZONTAL(src) && !buckled && (mobility_flags & MOBILITY_MOVE)) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
if(!(stop_automated_movement_when_pulled && pulledby)) //Soma animals don't move when pulled
@@ -429,7 +430,6 @@
icon = initial(icon)
icon_state = icon_living
density = initial(density)
update_canmove()
flying = initial(flying)
if(collar_type)
collar_type = "[initial(collar_type)]"
@@ -526,23 +526,6 @@
if(pcollar)
. |= pcollar.GetAccess()
/mob/living/simple_animal/update_canmove(delay_action_updates = 0)
if(IsParalyzed() || IsStunned() || IsWeakened() || stat || resting)
drop_r_hand()
drop_l_hand()
canmove = 0
else if(buckled)
canmove = 0
else
canmove = 1
if(!canmove)
walk(src, 0) //stop mid walk
update_transform()
if(!delay_action_updates)
update_action_buttons_icon()
return canmove
/mob/living/simple_animal/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = FALSE
@@ -43,8 +43,11 @@
AIproc = 1
while(AIproc && stat != DEAD && (attacked || hungry || rabid || buckled))
if(!canmove) //also covers buckling. Not sure why buckled is in the while condition if we're going to immediately break, honestly
while(AIproc && stat != DEAD && (attacked || hungry || rabid))
if(buckled)
break
if(!(mobility_flags & MOBILITY_MOVE))
break
if(!Target || client)
@@ -72,7 +75,7 @@
if(Target.Adjacent(src))
Target.attack_slime(src)
break
if(!Target.lying && prob(80))
if(!(mobility_flags & MOBILITY_MOVE) && prob(80))
if(Target.client && Target.health >= 20)
if(!Atkcool)
@@ -258,12 +261,11 @@
/mob/living/simple_animal/slime/proc/handle_targets()
update_canmove()
if(Tempstun)
if(!buckled) // not while they're eating!
canmove = 0
ADD_TRAIT(src, TRAIT_IMMOBILIZED, SLIME_TRAIT)
else
canmove = 1
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, SLIME_TRAIT)
if(attacked > 50)
attacked = 50
@@ -281,7 +283,7 @@
Discipline--
if(!client)
if(!canmove)
if(!(mobility_flags & MOBILITY_MOVE))
return
if(buckled)
@@ -358,16 +360,16 @@
target_patience += 3
if(!Target) // If we have no target, we are wandering or following orders
if (Leader)
if(Leader)
if(holding_still)
holding_still = max(holding_still - 1, 0)
else if(canmove && isturf(loc))
else if(isturf(loc))
step_to(src, Leader)
else if(hungry)
if (holding_still)
holding_still = max(holding_still - hungry, 0)
else if(canmove && isturf(loc) && prob(50))
else if(isturf(loc) && prob(50))
step(src, pick(GLOB.cardinal))
else
@@ -375,7 +377,7 @@
holding_still = max(holding_still - 1, 0)
else if (docile && pulledby)
holding_still = 10
else if(canmove && isturf(loc) && prob(33))
else if(isturf(loc) && prob(33))
step(src, pick(GLOB.cardinal))
else if(!AIproc)
INVOKE_ASYNC(src, .proc/AIprocess)
@@ -481,13 +481,13 @@
SStun = world.time + rand(20,60)
spawn(0)
canmove = FALSE
ADD_TRAIT(src, TRAIT_IMMOBILIZED, SLIME_TRAIT)
if(user)
step_away(src,user,15)
sleep(3)
if(user)
step_away(src,user,15)
update_canmove()
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, SLIME_TRAIT)
/mob/living/simple_animal/slime/pet
docile = TRUE
+6 -4
View File
@@ -10,10 +10,12 @@
add_attack_logs(src, null, "Fallen unconscious", ATKLOG_ALL)
log_game("[key_name(src)] fell unconscious at [atom_loc_line(get_turf(src))]")
set_stat(UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_FLOORED, STAT_TRAIT)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, STAT_TRAIT)
ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, STAT_TRAIT)
if(updating)
update_sight()
update_blind_effects()
update_canmove()
set_typing_indicator(FALSE)
return 1
@@ -27,10 +29,10 @@
add_attack_logs(src, null, "Woken up", ATKLOG_ALL)
log_game("[key_name(src)] woke up at [atom_loc_line(get_turf(src))]")
set_stat(CONSCIOUS)
REMOVE_TRAITS_IN(src, STAT_TRAIT)
if(updating)
update_sight()
update_blind_effects()
update_canmove()
return 1
// death() is used to make a mob die
@@ -42,14 +44,14 @@
create_attack_log("<font color='red'>Came back to life at [atom_loc_line(get_turf(src))]</font>")
add_attack_logs(src, null, "Came back to life", ATKLOG_ALL)
log_game("[key_name(src)] came back to life at [atom_loc_line(get_turf(src))]")
set_stat(CONSCIOUS)
set_stat(UNCONSCIOUS) // this is done as `WakeUp` early returns if they are `stat = DEAD`
WakeUp()
GLOB.dead_mob_list -= src
GLOB.alive_mob_list |= src
if(mind)
remove_from_respawnable_list()
timeofdeath = null
if(updating)
update_canmove()
update_blind_effects()
update_sight()
updatehealth("update revive")
+126 -17
View File
@@ -79,30 +79,89 @@
#define IS_STUN_IMMUNE(source, ignore_canstun) ((source.status_flags & GODMODE) || (!ignore_canstun && !(source.status_flags & CANSTUN)))
/mob/living
/*
STATUS EFFECTS
*/
// Booleans
var/resting = FALSE
/mob/living/proc/lay_down()
set_body_position(LYING_DOWN)
/*
STATUS EFFECTS
*/
/mob/living/proc/stand_up(instant = TRUE, work_when_dead = FALSE)
set waitfor = FALSE
// RESTING
if(stat == DEAD && !work_when_dead)
return
if(!instant && !do_mob(src, src, 1 SECONDS, extra_checks = list(CALLBACK(src, /mob/living/proc/cannot_stand)), only_use_extra_checks = TRUE))
return
if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED))
return
set_body_position(STANDING_UP)
/mob/living/proc/StartResting(updating = 1)
var/val_change = !resting
resting = TRUE
/mob/living/proc/set_body_position(new_value)
if(body_position == new_value)
return FALSE
if(buckled) // if they are buckled they aint movin nowhere
return FALSE
. = TRUE
body_position = new_value
if(new_value == LYING_DOWN) // From standing to lying down.
on_lying_down()
else // From lying down to standing up.
on_standing_up()
if(updating && val_change)
update_canmove()
/mob/living/proc/on_lying_down(new_lying_angle)
if(layer == initial(layer)) //to avoid things like hiding larvas.
layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
pixel_y = PIXEL_Y_OFFSET_LYING
ADD_TRAIT(src, TRAIT_UI_BLOCKED, LYING_DOWN_TRAIT)
ADD_TRAIT(src, TRAIT_CANNOT_PULL, LYING_DOWN_TRAIT)
RegisterSignal(src, COMSIG_ATOM_DIR_CHANGE, .proc/orient_crawling)
set_density(FALSE)
set_lying_angle(pick(90, 270))
/mob/living/proc/StopResting(updating = 1)
var/val_change = !!resting
resting = FALSE
/mob/living/proc/on_standing_up()
if(layer == LYING_MOB_LAYER)
layer = initial(layer)
set_density(initial(density))
REMOVE_TRAITS_IN(src, LYING_DOWN_TRAIT)
UnregisterSignal(src, COMSIG_ATOM_DIR_CHANGE)
set_lying_angle(0)
pixel_y = 0
if(updating && val_change)
update_canmove()
/* makes sure the crawlers head is pointing in the direction they crawl
* effectively splits dirs down the middle.
# | #
moving this way points the head left # | # moving this way points the head right
# | #
moving up or down retains their old lying angle
*/
/mob/living/proc/orient_crawling(datum/source, old_dir, new_dir)
SIGNAL_HANDLER
if(new_dir in list(WEST, NORTHWEST, SOUTHWEST))
set_lying_angle(270) // point right
if(new_dir in list(EAST, NORTHEAST, SOUTHEAST))
set_lying_angle(90) //point left
/**
* Changes the inclination angle of a mob, used by humans and others to differentiate between standing up and prone positions.
*
* In BYOND-angles 0 is NORTH, 90 is EAST, 180 is SOUTH and 270 is WEST.
* This usually means that 0 is standing up, 90 and 270 are horizontal positions to right and left respectively, and 180 is upside-down.
* Mobs that do now follow these conventions due to unusual sprites should require a special handling or redefinition of this proc, due to the density and layer changes.
* The return of this proc is the previous value of the modified lying_angle if a change was successful (might include zero), or null if no change was made.
*/
/mob/living/proc/set_lying_angle(new_lying)
if(new_lying == lying_angle)
return
. = lying_angle
lying_angle = new_lying
if(lying_angle != lying_prev)
update_transform()
lying_prev = lying_angle
// SCALAR STATUS EFFECTS
@@ -636,6 +695,56 @@
P = apply_status_effect(STATUS_EFFECT_WEAKENED, amount)
return P
/mob/living/proc/IsKnockedDown()
return has_status_effect(STATUS_EFFECT_FLOORED)
/mob/living/proc/AmountKnockDown()
var/datum/status_effect/incapacitating/floored/F = IsKnockedDown()
if(F)
return F.duration - world.time
return 0
/mob/living/proc/KnockDown(amount, ignore_canstun = FALSE) //Can't go below remaining duration
if(IS_STUN_IMMUNE(src, ignore_canstun))
return
if(absorb_stun(amount, ignore_canstun))
return
var/datum/status_effect/incapacitating/floored/F = IsKnockedDown()
if(F)
F.duration = max(world.time + amount, F.duration)
else if(amount > 0)
F = apply_status_effect(STATUS_EFFECT_FLOORED, amount)
return F
/mob/living/proc/SetKnockDown(amount, ignore_canstun = FALSE) //Sets remaining duration
if(IS_STUN_IMMUNE(src, ignore_canstun))
return
var/datum/status_effect/incapacitating/floored/F = IsKnockedDown()
if(amount <= 0)
if(F)
qdel(F)
else
if(absorb_stun(amount, ignore_canstun))
return
if(F)
F.duration = world.time + amount
else
F = apply_status_effect(STATUS_EFFECT_FLOORED, amount)
return F
/mob/living/proc/AdjustKnockDown(amount, ignore_canstun = FALSE) //Adds to remaining duration
if(IS_STUN_IMMUNE(src, ignore_canstun))
return
if(absorb_stun(amount, ignore_canstun))
return
var/datum/status_effect/incapacitating/floored/F = IsKnockedDown()
if(F)
F.duration += amount
else if(amount > 0)
F = apply_status_effect(STATUS_EFFECT_WEAKENED, amount)
return F
//
// DISABILITIES
//
+4 -33
View File
@@ -63,49 +63,20 @@
return TRUE
// Whether the mob is capable of standing or not
/mob/living/proc/can_stand()
return !(IsWeakened() || IsParalyzed() || stat || HAS_TRAIT(src, TRAIT_FAKEDEATH))
/mob/living/proc/cannot_stand()
return HAS_TRAIT(src, TRAIT_FLOORED)
// Whether the mob is capable of actions or not
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE, list/extra_checks = list(), use_default_checks = TRUE)
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, list/extra_checks = list(), use_default_checks = TRUE)
// By default, checks for weakness and stunned get added to the extra_checks list.
// Setting `use_default_checks` to FALSE means that you don't want it checking for these statuses or you are supplying your own checks.
if(use_default_checks)
extra_checks += CALLBACK(src, /mob/living.proc/IsWeakened)
extra_checks += CALLBACK(src, /mob/living.proc/IsStunned)
if(stat || IsParalyzed() || (!ignore_restraints && restrained()) || (!ignore_lying && lying) || check_for_true_callbacks(extra_checks))
if(stat || HAS_TRAIT_NOT_FROM(src, TRAIT_HANDS_BLOCKED, TRAIT_RESTRAINED) || (!ignore_restraints && restrained()) || check_for_true_callbacks(extra_checks))
return TRUE
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/living/update_canmove(delay_action_updates = 0)
var/fall_over = !can_stand()
var/buckle_lying = !(buckled && !buckled.buckle_lying)
if(fall_over || resting || IsStunned() || (buckled && buckle_lying != 0))
drop_r_hand()
drop_l_hand()
else
lying = 0
canmove = 1
if(buckled)
lying = 90 * buckle_lying
else if((fall_over || resting) && !lying)
fall(fall_over)
canmove = !(fall_over || resting || IsStunned() || IsFrozen() || buckled || IsImmobilized())
density = !lying
if(lying)
if(layer == initial(layer))
layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
else
if(layer == LYING_MOB_LAYER)
layer = initial(layer)
update_transform()
if(!delay_action_updates)
update_action_buttons_icon()
return canmove
/mob/living/proc/update_stamina()
return
+23 -9
View File
@@ -1061,19 +1061,33 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
// facing verbs
/mob/proc/canface()
if(!canmove) return 0
if(client.moving) return 0
if(world.time < client.move_delay) return 0
if(stat==2) return 0
if(anchored) return 0
if(notransform) return 0
if(restrained()) return 0
return 1
if(client.moving)
return FALSE
if(world.time < client.move_delay)
return FALSE
if(stat == DEAD)
return FALSE
if(anchored)
return FALSE
if(notransform)
return FALSE
if(restrained())
return FALSE
return TRUE
/mob/proc/fall(forced)
/mob/living/canface()
if(!(mobility_flags & MOBILITY_MOVE))
return FALSE
. = ..()
/mob/proc/fall()
drop_l_hand()
drop_r_hand()
/mob/living/fall()
..()
set_body_position(LYING_DOWN)
/mob/proc/facedir(ndir)
if(!canface())
return 0
-1
View File
@@ -50,7 +50,6 @@
var/med_record = ""
var/sec_record = ""
var/gen_record = ""
var/lying = 0
var/lying_prev = 0
var/lastpuke = 0
var/can_strip = 1
+1 -1
View File
@@ -130,7 +130,7 @@
var/mob/living/L = user
if(user.lying || (istype(L) && L.IsWeakened()))
if(IS_HORIZONTAL(L))
message = "flops and flails around on the floor."
return ..()
else if(params)
+3 -3
View File
@@ -195,7 +195,7 @@
return
if(!assailant.Adjacent(affecting)) // To prevent teleportation via grab
return
if(affecting.lying && state != GRAB_KILL)
if(IS_HORIZONTAL(affecting) && state != GRAB_KILL)
animate(affecting, pixel_x = 0, pixel_y = 0, 5, 1, LINEAR_EASING)
return //KJK
/* if(force_down) //THIS GOES ABOVE THE RETURN LABELED KJK
@@ -246,7 +246,7 @@
return
if(world.time < (last_upgrade + UPGRADE_COOLDOWN))
return
if(!assailant.canmove || assailant.lying)
if(!(assailant.mobility_flags & MOBILITY_MOVE) || IS_HORIZONTAL(assailant))
qdel(src)
return
@@ -335,7 +335,7 @@
if(INTENT_HARM) //This checks that the user is on harm intent.
if(last_hit_zone == "head") //This checks the hitzone the user has selected. In this specific case, they have the head selected.
if(affecting.lying)
if(IS_HORIZONTAL(affecting))
return
assailant.visible_message("<span class='danger'>[assailant] thrusts [assailant.p_their()] head into [affecting]'s skull!</span>") //A visible message for what is going on.
var/damage = 5
+12 -7
View File
@@ -463,17 +463,22 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
if(alert(src, "You sure you want to sleep for a while?", "Sleep", "Yes", "No") == "Yes")
SetSleeping(40 SECONDS, voluntary = TRUE) //Short nap
/mob/living/verb/lay_down()
/mob/living/verb/rest()
set name = "Rest"
set category = "IC"
if(!resting)
client.move_delay = world.time + 20
resting = !resting // this happens before the do_mob so that you can stay resting if you are stunned.
if(!do_mob(src, src, 1 SECONDS, extra_checks = list(CALLBACK(src, /mob/living/proc/cannot_stand)), only_use_extra_checks = TRUE))
return
if(resting)
to_chat(src, "<span class='notice'>You are now resting.</span>")
StartResting()
else if(resting)
to_chat(src, "<span class='notice'>You are now getting up.</span>")
StopResting()
lay_down()
else
to_chat(src, "<span class='notice'>You are now trying to get up.</span>")
stand_up()
/proc/get_multitool(mob/user as mob)
// Get tool
+16 -9
View File
@@ -1,10 +1,15 @@
/mob/CanPass(atom/movable/mover, turf/target, height=0)
var/horizontal = FALSE
if(isliving(src))
var/mob/living/L = src
horizontal = IS_HORIZONTAL(L)
if(height==0)
return 1
if(istype(mover, /obj/item/projectile))
return (!density || lying)
return projectile_hit_check(mover)
if(mover.throwing)
return (!density || lying || (mover.throwing.thrower == src))
return (!density || horizontal || (mover.throwing.thrower == src))
if(mover.checkpass(PASSMOB))
return 1
if(buckled == mover)
@@ -15,8 +20,10 @@
return FALSE
if(mover in buckled_mobs)
return TRUE
return (!mover.density || !density || lying)
return (!mover.density || !density || horizontal)
/mob/proc/projectile_hit_check(obj/item/projectile/P)
return !density
/client/verb/toggle_throw_mode()
set hidden = 1
@@ -74,9 +81,10 @@
if(moving)
return 0
var/mob/living/living_mob = null
if(isliving(mob))
var/mob/living/L = mob
if(L.incorporeal_move)//Move though walls
living_mob = mob
if(living_mob.incorporeal_move)//Move though walls
Process_Incorpmove(direct)
return
@@ -96,7 +104,7 @@
if(mob.buckled) //if we're buckled to something, tell it we moved.
return mob.buckled.relaymove(mob, direct)
if(!mob.canmove)
if(living_mob && !(living_mob.mobility_flags & MOBILITY_MOVE))
return
if(!mob.lastarea)
@@ -135,7 +143,6 @@
if(locate(/obj/item/grab, mob))
delay += 7
var/mob/living/living_mob = mob
if(istype(living_mob))
var/newdir = NONE
var/confusion = living_mob.get_confusion()
@@ -192,7 +199,7 @@
///Checks to see if you are being grabbed and if so attemps to break it
/client/proc/Process_Grab()
if(mob.grabbed_by.len)
if(mob.incapacitated(FALSE, TRUE, TRUE)) // Can't break out of grabs if you're incapacitated
if(mob.incapacitated(FALSE, TRUE)) // Can't break out of grabs if you're incapacitated
return TRUE
var/list/grabbing = list()
@@ -340,7 +347,7 @@
return 0
/mob/proc/Move_Pulled(atom/A)
if(!canmove || restrained() || !pulling)
if(HAS_TRAIT(src, TRAIT_CANNOT_PULL) || restrained() || !pulling)
return
if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src))
stop_pulling()
+1 -2
View File
@@ -8,8 +8,7 @@
invisibility = 101
density = 0
stat = 2
canmove = 0
stat = DEAD
/mob/new_player/Initialize(mapload)
SHOULD_CALL_PARENT(FALSE)
+6 -13
View File
@@ -12,8 +12,7 @@
return
for(var/obj/item/W in src)
unEquip(W)
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
return ..()
@@ -57,8 +56,7 @@
for(var/obj/item/W in src)
unEquip(W)
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -121,8 +119,7 @@
for(var/obj/item/W in src)
unEquip(W)
regenerate_icons()
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
for(var/t in bodyparts)
@@ -149,7 +146,6 @@
if(notransform)
return
notransform = TRUE
canmove = FALSE
for(var/obj/item/I in src)
unEquip(I)
regenerate_icons()
@@ -184,8 +180,7 @@
for(var/obj/item/W in src)
unEquip(W)
regenerate_icons()
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
for(var/t in bodyparts) //this really should not be necessary
@@ -209,8 +204,7 @@
unEquip(W)
regenerate_icons()
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
@@ -248,8 +242,7 @@
for(var/obj/item/W in src)
unEquip(W)
regenerate_icons()
notransform = 1
canmove = 0
notransform = TRUE
icon = null
invisibility = 101
for(var/t in bodyparts) //this really should not be necessary
+1 -4
View File
@@ -43,7 +43,7 @@
/mob/proc/can_speak()
return 1
/mob/proc/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE)
/mob/proc/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE)
return FALSE
/mob/proc/restrained(ignore_grab)
@@ -60,6 +60,3 @@
/mob/proc/update_health_hud()
return
/mob/proc/update_canmove()
return 1