immobilized (#52578)

Adds an immobilized trait.
    Adds procs for several variable changes so we can respond to their events.
    Adds some signals for said variables changing.

Need to turn the variation in number of usable legs and arms (get_num_legs() and get_num_arms()) into events we can respond to, but they are pretty annoying to do so. Probably for a different PR.
This commit is contained in:
Rohesie
2020-08-10 23:44:01 -03:00
committed by GitHub
parent 3f35d5edf6
commit 8f917ff1d9
14 changed files with 160 additions and 27 deletions
+4
View File
@@ -278,6 +278,8 @@
#define COMSIG_MOVABLE_DISPOSING "movable_disposing"
///called when the movable sucessfully has it's anchored var changed, from base atom/movable/set_anchored(): (value)
#define COMSIG_MOVABLE_SET_ANCHORED "movable_set_anchored"
///from base of atom/movable/setGrabState(): (newstate)
#define COMSIG_MOVABLE_SET_GRAB_STATE "living_set_grab_state"
// /mob signals
@@ -364,6 +366,8 @@
#define COMSIG_LIVING_REVIVE "living_revive"
///from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs"
///from base of mob/living/set_buckled(): (new_buckled)
#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled"
///sent from borg recharge stations: (amount, repairs)
#define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge"
+6
View File
@@ -77,6 +77,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
//mob traits
#define TRAIT_KNOCKEDOUT "knockedout" //Forces the user to stay unconscious.
#define TRAIT_IMMOBILIZED "immobilized" //Prevents voluntary movement.
#define TRAIT_INCAPACITATED "incapacitated"
#define TRAIT_BLIND "blind"
#define TRAIT_MUTE "mute"
@@ -274,6 +275,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define CRIT_HEALTH_TRAIT "crit_health"
#define OXYLOSS_TRAIT "oxyloss"
#define TURF_TRAIT "turf"
#define BUCKLED_TRAIT "buckled" //trait associated to being buckled
#define CHOKEHOLD_TRAIT "chokehold" //trait associated to being held in a chokehold
#define RESTING_TRAIT "resting" //trait associated to resting
// unique trait sources, still defines
#define CLONING_POD_TRAIT "cloning-pod"
@@ -316,3 +320,5 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TIMESTOP_TRAIT "timestop"
#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name
#define SKILLCHIP_TRAIT "skillchip"
#define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit"
#define LOCKED_BORG_TRAIT "locked-borg"
+1 -2
View File
@@ -110,8 +110,7 @@
if (isliving(AM))
var/mob/living/L = AM
L.notransform = TRUE
L.Stun(200)
L.resting = TRUE
L.Paralyze(20 SECONDS)
var/oldtransform = AM.transform
var/oldcolor = AM.color
+24 -1
View File
@@ -33,19 +33,33 @@
if(!.)
return
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/stun/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
return ..()
//KNOCKDOWN
/datum/status_effect/incapacitating/knockdown
id = "knockdown"
//IMMOBILIZED
/datum/status_effect/incapacitating/immobilized
id = "immobilized"
/datum/status_effect/incapacitating/immobilized/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/immobilized/on_remove()
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
return ..()
/datum/status_effect/incapacitating/paralyzed
id = "paralyzed"
@@ -54,9 +68,11 @@
if(!.)
return
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/paralyzed/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
return ..()
//UNCONSCIOUS
@@ -163,12 +179,19 @@
if(.)
update_time_of_death()
owner.reagents?.end_metabolization(owner, FALSE)
owner.update_mobility()
/datum/status_effect/grouped/stasis/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
owner.update_mobility()
/datum/status_effect/grouped/stasis/tick()
update_time_of_death()
/datum/status_effect/grouped/stasis/on_remove()
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
owner.update_mobility()
update_time_of_death()
return ..()
+10
View File
@@ -6,6 +6,16 @@
var/icon/cube
var/can_melt = TRUE
/datum/status_effect/freon/on_apply()
. = ..()
if(!.)
return
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/freon/on_remove()
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
return ..()
/obj/screen/alert/status_effect/freon
name = "Frozen Solid"
desc = "You're frozen inside an ice cube, and cannot move! You can still do stuff, like shooting. Resist out of the cube!"
+25 -3
View File
@@ -224,7 +224,7 @@
log_combat(AM, AM.pulledby, "pulled from", src)
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
pulling = AM
AM.pulledby = src
AM.set_pulledby(src)
setGrabState(state)
if(ismob(AM))
var/mob/M = AM
@@ -236,14 +236,23 @@
/atom/movable/proc/stop_pulling()
if(pulling)
pulling.pulledby = null
pulling.set_pulledby(null)
var/mob/living/ex_pulled = pulling
setGrabState(GRAB_PASSIVE)
pulling = null
setGrabState(0)
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_mobility()// mob gets up if it was lyng down in a chokehold
///Reports the event of the change in value of the pulledby variable.
/atom/movable/proc/set_pulledby(new_pulledby)
if(new_pulledby == pulledby)
return FALSE //null signals there was a change, be sure to return FALSE if none happened here.
. = pulledby
pulledby = new_pulledby
/atom/movable/proc/Move_Pulled(atom/A)
if(!pulling)
return
@@ -969,7 +978,20 @@
* This exists to act as a hook for behaviour
*/
/atom/movable/proc/setGrabState(newstate)
if(newstate == grab_state)
return
SEND_SIGNAL(src, COMSIG_MOVABLE_SET_GRAB_STATE, newstate)
. = grab_state
grab_state = newstate
switch(.) //Previous state.
if(GRAB_PASSIVE, GRAB_AGGRESSIVE)
if(grab_state >= GRAB_NECK)
ADD_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
switch(grab_state) //Current state.
if(GRAB_PASSIVE, GRAB_AGGRESSIVE)
if(. >= GRAB_NECK)
REMOVE_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
/obj/item/proc/do_pickup_animation(atom/target)
set waitfor = FALSE
+2 -2
View File
@@ -94,7 +94,7 @@
M.forceMove(loc)
M.buckling = null
M.buckled = src
M.set_buckled(src)
M.setDir(dir)
buckled_mobs |= M
M.update_mobility()
@@ -114,7 +114,7 @@
/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force=FALSE)
if(istype(buckled_mob) && buckled_mob.buckled == src && (buckled_mob.can_unbuckle() || force))
. = buckled_mob
buckled_mob.buckled = null
buckled_mob.set_buckled(null)
buckled_mob.set_anchored(initial(buckled_mob.anchored))
buckled_mob.update_mobility()
buckled_mob.clear_alert("buckled")
+2 -4
View File
@@ -304,8 +304,7 @@
log_game("[key_name(user)] has put the MMI/posibrain of [key_name(M.brainmob)] into a cyborg shell at [AREACOORD(src)]")
if(!locomotion)
O.lockcharge = TRUE
O.update_mobility()
O.set_lockcharge(TRUE)
to_chat(O, "<span class='warning'>Error: Servo motors unresponsive.</span>")
else
@@ -342,8 +341,7 @@
forceMove(O)
O.robot_suit = src
if(!locomotion)
O.lockcharge = TRUE
O.update_mobility()
O.set_lockcharge(TRUE)
else if(istype(W, /obj/item/pen))
to_chat(user, "<span class='warning'>You need to use a multitool to name [src]!</span>")
@@ -528,11 +528,11 @@
step_towards(user, T2)
T1 = get_turf(user)
if(T1 == T2)
user.resting = TRUE //so people can jump into crates without slamming the lid on their head
user.set_resting(TRUE) //so people can jump into crates without slamming the lid on their head
if(!close(user))
to_chat(user, "<span class='warning'>You can't get [src] to close!</span>")
user.resting = FALSE
user.set_resting(FALSE)
return
user.resting = FALSE
user.set_resting(FALSE)
togglelock(user)
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
+2 -1
View File
@@ -79,7 +79,8 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
if(isliving(A))
var/mob/living/M = A
M.Paralyze(320) // Keep them from moving during the duration of the extraction
M.buckled = 0 // Unbuckle them to prevent anchoring problems
if(M.buckled)
M.buckled.unbuckle_mob(M, TRUE) // Unbuckle them to prevent anchoring problems
else
A.set_anchored(TRUE)
A.density = FALSE
+52 -4
View File
@@ -267,7 +267,7 @@
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
pulling = AM
AM.pulledby = src
AM.set_pulledby(src)
SEND_SIGNAL(src, COMSIG_LIVING_START_PULL, AM, state, force)
@@ -451,19 +451,26 @@
else
to_chat(src, "<span class='warning'>You fail to get up!</span>")
///Proc to hook behavior to the change of value in the resting variable.
/mob/living/proc/set_resting(rest, silent = TRUE)
if(rest == resting)
return
if(!silent)
if(rest)
to_chat(src, "<span class='notice'>You are now resting.</span>")
else
to_chat(src, "<span class='notice'>You get up.</span>")
. = rest
resting = rest
update_resting()
/mob/living/proc/update_resting()
update_rest_hud_icon()
update_mobility()
//Recursive function to find everything a mob is holding. Really shitty proc tbh.
/mob/living/get_contents()
var/list/ret = list()
@@ -1197,10 +1204,9 @@
var/has_legs = get_num_legs()
var/has_arms = get_num_arms()
var/paralyzed = IsParalyzed()
var/stun = IsStun()
var/knockdown = IsKnockdown()
var/ignore_legs = get_leg_ignore()
var/canmove = !IsImmobilized() && !stun && stat_conscious && !paralyzed && !buckled && (!stat_softcrit || !pulledby) && !chokehold && !IsFrozen() && !IS_IN_STASIS(src) && (has_arms || ignore_legs || has_legs)
var/canmove = !HAS_TRAIT(src, TRAIT_IMMOBILIZED) && (has_arms || ignore_legs || has_legs)
if(canmove)
mobility_flags |= MOBILITY_MOVE
else
@@ -1231,7 +1237,7 @@
var/canitem = !paralyzed && !stun && stat_conscious && !chokehold && !restrained && has_arms
var/canitem = !paralyzed && !IsStun() && stat_conscious && !chokehold && !restrained && has_arms
if(canitem)
mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
else
@@ -1627,12 +1633,54 @@
if(isnull(.))
return
switch(.) //Previous stat.
if(CONSCIOUS)
if(stat >= UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
if(SOFT_CRIT)
if(stat >= UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates
if(pulledby)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
if(UNCONSCIOUS)
cure_blind(UNCONSCIOUS_BLIND)
switch(stat) //Current stat.
if(CONSCIOUS)
if(. >= UNCONSCIOUS)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
if(SOFT_CRIT)
if(pulledby)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) //adding trait sources should come before removing to avoid unnecessary updates
if(. >= UNCONSCIOUS)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
if(UNCONSCIOUS)
become_blind(UNCONSCIOUS_BLIND)
///Reports the event of the change in value of the buckled variable.
/mob/living/proc/set_buckled(new_buckled)
if(new_buckled == buckled)
return
SEND_SIGNAL(src, COMSIG_LIVING_SET_BUCKLED, new_buckled)
. = buckled
buckled = new_buckled
if(buckled)
if(!.)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT)
else if(.)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT)
/mob/living/set_pulledby(new_pulledby)
. = ..()
if(. == FALSE) //null is a valid value here, we only want to return if FALSE is explicitly passed.
return
if(pulledby)
if(!. && stat == SOFT_CRIT)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
else if(. && stat == SOFT_CRIT)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
/// Only defined for carbons who can wear masks and helmets, we just assume other mobs have visible faces
/mob/living/proc/is_face_visible()
return TRUE
@@ -93,7 +93,7 @@
cut_overlay(fire_overlay)
/mob/living/silicon/robot/update_mobility()
if(stat || buckled || lockcharge)
if(HAS_TRAIT(src, TRAIT_IMMOBILIZED))
mobility_flags &= ~MOBILITY_MOVE
else
mobility_flags = MOBILITY_FLAGS_DEFAULT
+18 -5
View File
@@ -464,8 +464,7 @@
connected_ai.connected_robots -= src
src.connected_ai = null
lawupdate = FALSE
lockcharge = FALSE
mobility_flags |= MOBILITY_FLAGS_DEFAULT
set_lockcharge(FALSE)
scrambledcodes = TRUE
//Disconnect it's camera so it's not so easily tracked.
if(!QDELETED(builtInCamera))
@@ -487,17 +486,31 @@
W.attack_self(src)
/mob/living/silicon/robot/proc/SetLockdown(state = 1)
/mob/living/silicon/robot/proc/SetLockdown(state = TRUE)
// They stay locked down if their wire is cut.
if(wires.is_cut(WIRE_LOCKDOWN))
state = 1
state = TRUE
if(state)
throw_alert("locked", /obj/screen/alert/locked)
else
clear_alert("locked")
lockcharge = state
set_lockcharge(state)
///Reports the event of the change in value of the lockcharge variable.
/mob/living/silicon/robot/proc/set_lockcharge(new_lockcharge)
if(new_lockcharge == lockcharge)
return
. = lockcharge
lockcharge = new_lockcharge
if(lockcharge)
if(!.)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LOCKED_BORG_TRAIT)
else if(.)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LOCKED_BORG_TRAIT)
update_mobility()
/mob/living/silicon/robot/proc/SetEmagged(new_state)
emagged = new_state
module.rebuild_modules()
@@ -527,8 +527,17 @@
else
..()
/mob/living/simple_animal/update_resting()
if(resting)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, RESTING_TRAIT)
else
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, RESTING_TRAIT)
return ..()
/mob/living/simple_animal/update_mobility(value_otherwise = TRUE)
if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || IsParalyzed() || IsStun() || IsKnockdown() || IsParalyzed() || stat || resting)
if(HAS_TRAIT_NOT_FROM(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT))
drop_all_held_items()
mobility_flags = NONE
else if(buckled)