mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 03:26:31 +01:00
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:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user