diff --git a/code/__DEFINES/assert.dm b/code/__DEFINES/assert.dm
new file mode 100644
index 000000000000..cff78107714c
--- /dev/null
+++ b/code/__DEFINES/assert.dm
@@ -0,0 +1,13 @@
+#undef ASSERT
+
+/// Override BYOND's native ASSERT to optionally specify a message
+#define ASSERT(condition, message...) \
+ if (!(condition)) { \
+ CRASH(assertion_message(__FILE__, __LINE__, #condition, ##message)) \
+ }
+
+/proc/assertion_message(file, line, condition, message)
+ if (!isnull(message))
+ message = " - [message]"
+
+ return "[file]:[line]:Assertion failed: [condition][message]"
diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm
index 89a65dad230e..56cd4dd8cd8e 100644
--- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm
+++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm
@@ -33,3 +33,8 @@
/// From /mob/living/Collide(): (atom/A)
#define COMSIG_LIVING_PRE_COLLIDE "living_pre_collide"
#define COMPONENT_LIVING_COLLIDE_HANDLED (1<<0)
+
+///from base of mob/living/set_buckled(): (new_buckled)
+#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled"
+///from base of mob/living/set_body_position()
+#define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position"
diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm
index e9862be49dd5..debe99d15aa7 100644
--- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm
+++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm
@@ -62,3 +62,6 @@
/// For any additional things that should happen when a xeno's melee_attack_additional_effects_self() proc is called
#define COMSIG_XENO_SLASH_ADDITIONAL_EFFECTS_SELF "xeno_slash_additional_effects_self"
+
+/// Cancels all running cloaking effects on target
+#define COMSIG_MOB_EFFECT_CLOAK_CANCEL "mob_effect_cloak_cancel"
diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm
index bab6064cfdbf..b5df0e963e78 100644
--- a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm
+++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm
@@ -1,3 +1,5 @@
+///from base of mob/set_stat(): (new_stat, old_stat)
+#define COMSIG_MOB_STATCHANGE "mob_statchange"
/// From /obj/structure/machinery/door/airlock/proc/take_damage
#define COMSIG_MOB_DESTROY_AIRLOCK "mob_destroy_airlock"
@@ -35,10 +37,6 @@
#define COMSIG_MOB_FIRED_GUN_ATTACHMENT "mob_fired_gun_attachment"
/// From /mob/proc/death
#define COMSIG_MOB_DEATH "mob_death"
-/// From /mob/proc/update_canmove()
-#define COMSIG_MOB_GETTING_UP "mob_getting_up"
-/// From /mob/proc/update_canmove()
-#define COMSIG_MOB_KNOCKED_DOWN "mob_knocked_down"
/// For when a mob is dragged
#define COMSIG_MOB_DRAGGED "mob_dragged"
/// From /obj/item/proc/unequipped()
@@ -84,8 +82,6 @@
//from /mob/proc/on_deafness_loss()
#define COMSIG_MOB_REGAINED_HEARING "mob_regained_hearing"
-#define COMSIG_MOB_POST_UPDATE_CANMOVE "mob_can_move"
-
#define COMSIG_ATTEMPT_MOB_PULL "attempt_mob_pull"
#define COMPONENT_CANCEL_MOB_PULL (1<<0)
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 072738184807..8cff004045b0 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -418,3 +418,29 @@ var/list/default_xeno_onmob_icons = list(
#define EXTREMITY_LIMBS list("l_leg","l_foot","r_leg","r_foot","l_arm","l_hand","r_arm","r_hand")
#define CORE_LIMBS list("chest","head","groin")
+// Body position defines.
+/// Mob is standing up, usually associated with lying_angle value of 0.
+#define STANDING_UP 0
+/// Mob is lying down, usually associated with lying_angle values of 90 or 270.
+#define LYING_DOWN 1
+
+/// Possible value of [/atom/movable/buckle_lying]. If set to a different (positive-or-zero) value than this, the buckling thing will force a lying angle on the buckled.
+#define NO_BUCKLE_LYING -1
+
+// ====================================
+// /mob/living /tg/ mobility_flags
+// These represent in what capacity the mob is capable of moving
+// Because porting this is underway, NOT ALL FLAGS ARE CURRENTLY IN.
+
+/// can move
+#define MOBILITY_MOVE (1<<0)
+/// can, and is, standing up
+#define MOBILITY_STAND (1<<1)
+/// can rest
+#define MOBILITY_REST (1<<7)
+/// can lie down
+#define MOBILITY_LIEDOWN (1<<8)
+
+#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND)
+#define MOBILITY_FLAGS_CARBON_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_REST | MOBILITY_LIEDOWN)
+#define MOBILITY_FLAGS_REST_CAPABLE_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_REST | MOBILITY_LIEDOWN)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index ef500b6af9f8..88665a3a8c39 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -1,63 +1,76 @@
-//shamelessly ripped from TG
#define SIGNAL_ADDTRAIT(trait_ref) "addtrait [trait_ref]"
#define SIGNAL_REMOVETRAIT(trait_ref) "removetrait [trait_ref]"
// trait accessor defines
-//here be dragons
#define ADD_TRAIT(target, trait, source) \
do { \
var/list/_L; \
- if (!target.status_traits) { \
- target.status_traits = list(); \
- _L = target.status_traits; \
+ if (!target._status_traits) { \
+ target._status_traits = list(); \
+ _L = target._status_traits; \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \
- if(trait in GLOB.traits_with_elements){ \
- target.AddElement(GLOB.traits_with_elements[trait]); \
- } \
} else { \
- _L = target.status_traits; \
+ _L = target._status_traits; \
if (_L[trait]) { \
_L[trait] |= list(source); \
} else { \
_L[trait] = list(source); \
SEND_SIGNAL(target, SIGNAL_ADDTRAIT(trait), trait); \
- if(trait in GLOB.traits_with_elements){ \
- target.AddElement(GLOB.traits_with_elements[trait]); \
- } \
} \
} \
} while (0)
#define REMOVE_TRAIT(target, trait, sources) \
do { \
- var/list/_L = target.status_traits; \
+ var/list/_L = target._status_traits; \
var/list/_S; \
if (sources && !islist(sources)) { \
_S = list(sources); \
} else { \
_S = sources\
}; \
- if (_L && _L[trait]) { \
+ if (_L?[trait]) { \
for (var/_T in _L[trait]) { \
- if ((!_S && (_T != TRAIT_SOURCE_QUIRK)) || (_T in _S)) { \
+ if ((!_S && (_T != ROUNDSTART_TRAIT)) || (_T in _S)) { \
_L[trait] -= _T \
} \
};\
if (!length(_L[trait])) { \
_L -= trait; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \
- if(trait in GLOB.traits_with_elements) { \
- target.RemoveElement(GLOB.traits_with_elements[trait]); \
- } \
}; \
if (!length(_L)) { \
- target.status_traits = null \
+ target._status_traits = null \
+ }; \
+ } \
+ } while (0)
+#define REMOVE_TRAIT_NOT_FROM(target, trait, sources) \
+ do { \
+ var/list/_traits_list = target._status_traits; \
+ var/list/_sources_list; \
+ if (sources && !islist(sources)) { \
+ _sources_list = list(sources); \
+ } else { \
+ _sources_list = sources\
+ }; \
+ if (_traits_list?[trait]) { \
+ for (var/_trait_source in _traits_list[trait]) { \
+ if (!(_trait_source in _sources_list)) { \
+ _traits_list[trait] -= _trait_source \
+ } \
+ };\
+ if (!length(_traits_list[trait])) { \
+ _traits_list -= trait; \
+ SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \
+ }; \
+ if (!length(_traits_list)) { \
+ target._status_traits = null \
}; \
} \
} while (0)
#define REMOVE_TRAITS_NOT_IN(target, sources) \
do { \
- var/list/_L = target.status_traits; \
+ var/list/_L = target._status_traits; \
var/list/_S = sources; \
if (_L) { \
for (var/_T in _L) { \
@@ -65,20 +78,17 @@
if (!length(_L[_T])) { \
_L -= _T; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T), _T); \
- if(_T in GLOB.traits_with_elements) { \
- target.RemoveElement(GLOB.traits_with_elements[_T]); \
}; \
};\
- };\
if (!length(_L)) { \
- target.status_traits = null\
+ target._status_traits = null\
};\
}\
} while (0)
#define REMOVE_TRAITS_IN(target, sources) \
do { \
- var/list/_L = target.status_traits; \
+ var/list/_L = target._status_traits; \
var/list/_S = sources; \
if (sources && !islist(sources)) { \
_S = list(sources); \
@@ -91,46 +101,37 @@
if (!length(_L[_T])) { \
_L -= _T; \
SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(_T)); \
- if(_T in GLOB.traits_with_elements) { \
- target.RemoveElement(GLOB.traits_with_elements[_T]); \
}; \
};\
- };\
if (!length(_L)) { \
- target.status_traits = null\
+ target._status_traits = null\
};\
}\
} while (0)
-/// Will 100% nuke a trait regardless of source. Preferably use this as little as possible
-#define REMOVE_TRAIT_ALLSOURCES(target, trait) \
- do { \
- var/list/_L = target.status_traits; \
- if (_L?[trait]) { \
- if (length(_L)) { \
- _L -= trait; \
- SEND_SIGNAL(target, SIGNAL_REMOVETRAIT(trait), trait); \
- }; \
- else { \
- target.status_traits = null \
- }; \
- } \
- } while (0)
-
-#define HAS_TRAIT(target, trait) (target.status_traits ? (target.status_traits[trait] ? TRUE : FALSE) : FALSE)
-#define HAS_TRAIT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (source in target.status_traits[trait]) : FALSE) : FALSE)
-#define HAS_TRAIT_FROM_ONLY(target, trait, source) (\
- target.status_traits ?\
- (target.status_traits[trait] ?\
- ((source in target.status_traits[trait]) && (length(target.status_traits) == 1))\
- : FALSE)\
- : FALSE)
-#define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE)
+#define HAS_TRAIT(target, trait) (target._status_traits?[trait] ? TRUE : FALSE)
+#define HAS_TRAIT_FROM(target, trait, source) (HAS_TRAIT(target, trait) && (source in target._status_traits[trait]))
+#define HAS_TRAIT_FROM_ONLY(target, trait, source) (HAS_TRAIT(target, trait) && (source in target._status_traits[trait]) && (length(target._status_traits[trait]) == 1))
+#define HAS_TRAIT_NOT_FROM(target, trait, source) (HAS_TRAIT(target, trait) && (length(target._status_traits[trait] - source) > 0))
+/// Returns a list of trait sources for this trait. Only useful for wacko cases and internal futzing
+/// You should not be using this
+#define GET_TRAIT_SOURCES(target, trait) (target._status_traits?[trait] || list())
+/// Returns the amount of sources for a trait. useful if you don't want to have a "thing counter" stuck around all the time
+#define COUNT_TRAIT_SOURCES(target, trait) length(GET_TRAIT_SOURCES(target, trait))
+/// A simple helper for checking traits in a mob's mind
+#define HAS_MIND_TRAIT(target, trait) (HAS_TRAIT(target, trait) || (target.mind ? HAS_TRAIT(target.mind, trait) : FALSE))
/// Example trait
// #define TRAIT_X "t_x"
+
+/// cannot be removed without admin intervention
+#define ROUNDSTART_TRAIT "roundstart"
+
//-- mob traits --
+/// Apply this to make a mob not dense, and remove it when you want it to no longer make them undense, other sorces of undesity will still apply. Always define a unique source when adding a new instance of this!
+#define TRAIT_UNDENSE "undense"
+
// SPECIES TRAITS
/// Knowledge of Yautja technology
#define TRAIT_YAUTJA_TECH "t_yautja_tech"
@@ -145,6 +146,14 @@
/// Makes it impossible to strip the inventory of this mob.
#define TRAIT_UNSTRIPPABLE "t_unstrippable"
+/// Forces the user to stay unconscious.
+#define TRAIT_KNOCKEDOUT "knockedout"
+/// Prevents voluntary movement.
+#define TRAIT_IMMOBILIZED "immobilized"
+/// Prevents voluntary standing or staying up on its own.
+#define TRAIT_FLOORED "floored"
+#define TRAIT_INCAPACITATED "incapacitated"
+
// HIVE TRAITS
/// If the Hive is a Xenonid Hive
#define TRAIT_XENONID "t_xenonid"
@@ -279,6 +288,10 @@ GLOBAL_LIST_INIT(mob_traits, list(
*/
GLOBAL_LIST_INIT(traits_by_type, list(
/mob = list(
+ "TRAIT_KNOCKEDOUT" = TRAIT_KNOCKEDOUT,
+ "TRAIT_IMMOBILIZED" = TRAIT_IMMOBILIZED,
+ "TRAIT_FLOORED" = TRAIT_FLOORED,
+ "TRAIT_UNDENSE" = TRAIT_UNDENSE,
"TRAIT_YAUTJA_TECH" = TRAIT_YAUTJA_TECH,
"TRAIT_SUPER_STRONG" = TRAIT_SUPER_STRONG,
"TRAIT_FOREIGN_BIO" = TRAIT_FOREIGN_BIO,
@@ -379,6 +392,8 @@ GLOBAL_LIST(trait_name_map)
#define TRAIT_SOURCE_ABILITY(ability) "t_s_ability_[ability]"
///Status trait forced by the xeno action charge
#define TRAIT_SOURCE_XENO_ACTION_CHARGE "t_s_xeno_action_charge"
+///Status trait coming from a xeno nest
+#define XENO_NEST_TRAIT "xeno_nest"
//-- structure traits --
///Status trait coming from being flipped or unflipped.
#define TRAIT_SOURCE_FLIP_TABLE "t_s_flip_table"
@@ -390,3 +405,42 @@ GLOBAL_LIST(trait_name_map)
//Status trait coming from clothing.
#define TRAIT_SOURCE_CLOTHING "t_s_clothing"
+
+/// trait associated to being buckled
+#define BUCKLED_TRAIT "buckled" // Yes the name doesn't conform. /tg/ appears to have changed naming style inbetween
+/// trait source when an effect is coming from a fakedeath effect (refactor this)
+#define FAKEDEATH_TRAIT "fakedeath"
+/// trait source where a condition comes from body state
+#define BODY_TRAIT "body"
+/// Trait associated to lying down (having a [lying_angle] of a different value than zero).
+#define LYING_DOWN_TRAIT "lying-down"
+/// trait associated to a stat value or range of
+#define STAT_TRAIT "stat"
+/// trait effect related to the queen ovipositor
+#define OVIPOSITOR_TRAIT "ovipositor"
+/// trait effect related to active specialist gear
+#define SPECIALIST_GEAR_TRAIT "specialist_gear"
+/// trait associated to being held in a chokehold
+#define CHOKEHOLD_TRAIT "chokehold"
+/// traits associated with usage of snowflake dropship double seats
+#define DOUBLE_SEATS_TRAIT "double_seats"
+/// traits associated with xeno on-ground weeds
+#define XENO_WEED_TRAIT "xeno_weed"
+/// traits associated with actively interacted machinery
+#define INTERACTION_TRAIT "interaction"
+/// traits bound by stunned status effects
+#define STUNNED_TRAIT "stunned"
+/// traits bound by knocked_down status effect
+#define KNOCKEDDOWN_TRAIT "knockeddown"
+/// traits bound by knocked_out status effect
+#define KNOCKEDOUT_TRAIT "knockedout"
+/// traits from being pounced
+#define POUNCED_TRAIT "pounced"
+/// traits added by manual intervention
+#define ADMIN_ACTION_TRAIT "admin_action"
+/// traits from cloroform usage
+#define CLOROFORM_TRAIT "cloroform"
+/// traits from step_triggers on the map
+#define STEP_TRIGGER_TRAIT "step_trigger"
+/// traits from hacked machine interactions
+#define HACKED_TRAIT "hacked"
diff --git a/code/__HELPERS/animations.dm b/code/__HELPERS/animations.dm
new file mode 100644
index 000000000000..f85fb763a4a6
--- /dev/null
+++ b/code/__HELPERS/animations.dm
@@ -0,0 +1,2 @@
+/// The duration of the animate call in mob/living/update_transform
+#define UPDATE_TRANSFORM_ANIMATION_TIME (0.2 SECONDS)
diff --git a/code/__HELPERS/job.dm b/code/__HELPERS/job.dm
index 43902b07cfd9..89fe6877647e 100644
--- a/code/__HELPERS/job.dm
+++ b/code/__HELPERS/job.dm
@@ -26,13 +26,6 @@
if(I.assignment in GLOB.joblist) return I.assignment
return "Unknown"
-/proc/FindNameFromID(mob/living/carbon/human/H)
- ASSERT(istype(H))
- var/obj/item/card/id/I = H.wear_id
- if(istype(I)) return I.registered_name
- I = H.get_active_hand()
- if(istype(I)) return I.registered_name
-
/proc/get_all_job_icons() return GLOB.joblist + list("Prisoner")//For all existing HUD icons
/obj/proc/GetJobName() //Used in secHUD icon generation
diff --git a/code/__HELPERS/status_effects.dm b/code/__HELPERS/status_effects.dm
new file mode 100644
index 000000000000..d06cb687f6a5
--- /dev/null
+++ b/code/__HELPERS/status_effects.dm
@@ -0,0 +1 @@
+#define TRAIT_STATUS_EFFECT(effect_id) "[effect_id]-trait"
diff --git a/code/__HELPERS/traits.dm b/code/__HELPERS/traits.dm
new file mode 100644
index 000000000000..ba99b2e1e7ff
--- /dev/null
+++ b/code/__HELPERS/traits.dm
@@ -0,0 +1,43 @@
+#define TRAIT_CALLBACK_ADD(target, trait, source) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___TraitAdd), ##target, ##trait, ##source)
+#define TRAIT_CALLBACK_REMOVE(target, trait, source) CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(___TraitRemove), ##target, ##trait, ##source)
+
+///DO NOT USE ___TraitAdd OR ___TraitRemove as a replacement for ADD_TRAIT / REMOVE_TRAIT defines. To be used explicitly for callback.
+/proc/___TraitAdd(target,trait,source)
+ if(!target || !trait || !source)
+ return
+ if(islist(target))
+ for(var/i in target)
+ if(!isatom(i))
+ continue
+ var/atom/the_atom = i
+ ADD_TRAIT(the_atom,trait,source)
+ else if(isatom(target))
+ var/atom/the_atom2 = target
+ ADD_TRAIT(the_atom2,trait,source)
+
+///DO NOT USE ___TraitAdd OR ___TraitRemove as a replacement for ADD_TRAIT / REMOVE_TRAIT defines. To be used explicitly for callback.
+/proc/___TraitRemove(target,trait,source)
+ if(!target || !trait || !source)
+ return
+ if(islist(target))
+ for(var/i in target)
+ if(!isatom(i))
+ continue
+ var/atom/the_atom = i
+ REMOVE_TRAIT(the_atom,trait,source)
+ else if(isatom(target))
+ var/atom/the_atom2 = target
+ REMOVE_TRAIT(the_atom2,trait,source)
+
+
+/// Proc that handles adding multiple traits to a target via a list. Must have a common source and target.
+/datum/proc/add_traits(list/list_of_traits, source)
+ ASSERT(islist(list_of_traits), "Invalid arguments passed to add_traits! Invoked on [src] with [list_of_traits], source being [source].")
+ for(var/trait in list_of_traits)
+ ADD_TRAIT(src, trait, source)
+
+/// Proc that handles removing multiple traits from a target via a list. Must have a common source and target.
+/datum/proc/remove_traits(list/list_of_traits, source)
+ ASSERT(islist(list_of_traits), "Invalid arguments passed to remove_traits! Invoked on [src] with [list_of_traits], source being [source].")
+ for(var/trait in list_of_traits)
+ REMOVE_TRAIT(src, trait, source)
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 9a6ee4362088..80e21e8da168 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1089,7 +1089,7 @@ var/global/image/action_purple_power_up
target_orig_turf = get_turf(target)
var/obj/user_holding = busy_user.get_active_hand()
var/obj/target_holding
- var/cur_user_lying = busy_user.lying
+ var/cur_user_lying = busy_user.body_position
var/cur_target_lying
var/expected_total_time = delayfraction*numticks
var/time_remaining = expected_total_time
@@ -1097,7 +1097,7 @@ var/global/image/action_purple_power_up
if(has_target && istype(T))
cur_target_zone_sel = T.zone_selected
target_holding = T.get_active_hand()
- cur_target_lying = T.lying
+ cur_target_lying = T.body_position
. = TRUE
for(var/i in 1 to numticks)
@@ -1121,13 +1121,13 @@ var/global/image/action_purple_power_up
)
. = FALSE
break
- if(user_flags & INTERRUPT_KNOCKED_DOWN && busy_user.knocked_down || \
- target_is_mob && (target_flags & INTERRUPT_KNOCKED_DOWN && T.knocked_down)
+ if(user_flags & INTERRUPT_KNOCKED_DOWN && HAS_TRAIT(busy_user, TRAIT_FLOORED) || \
+ target_is_mob && (target_flags & INTERRUPT_KNOCKED_DOWN && HAS_TRAIT(T, TRAIT_FLOORED))
)
. = FALSE
break
- if(user_flags & INTERRUPT_STUNNED && busy_user.stunned || \
- target_is_mob && (target_flags & INTERRUPT_STUNNED && T.stunned)
+ if(user_flags & INTERRUPT_STUNNED && HAS_TRAIT(busy_user, TRAIT_INCAPACITATED)|| \
+ target_is_mob && (target_flags & INTERRUPT_STUNNED && HAS_TRAIT(T, TRAIT_INCAPACITATED))
)
. = FALSE
break
@@ -1201,8 +1201,8 @@ var/global/image/action_purple_power_up
)
. = FALSE
break
- if(user_flags & INTERRUPT_CHANGED_LYING && busy_user.lying != cur_user_lying || \
- target_is_mob && (target_flags & INTERRUPT_CHANGED_LYING && T.lying != cur_target_lying)
+ if(user_flags & INTERRUPT_CHANGED_LYING && busy_user.body_position != cur_user_lying || \
+ target_is_mob && (target_flags & INTERRUPT_CHANGED_LYING && T.body_position != cur_target_lying)
)
. = FALSE
break
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 53dd40ff6035..91687b19d2dd 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -370,6 +370,13 @@ DEFINE_BITFIELD(mob_flags, list(
"NOBIOSCAN" = NOBIOSCAN,
))
+DEFINE_BITFIELD(mobility_flags, list(
+ "MOVE" = MOBILITY_MOVE,
+ "STAND" = MOBILITY_STAND,
+ "REST" = MOBILITY_REST,
+ "LIEDOWN" = MOBILITY_LIEDOWN
+))
+
DEFINE_BITFIELD(flags, list(
"NO_BLOOD" = NO_BLOOD,
"NO_BREATHE" = NO_BREATHE,
diff --git a/code/_onclick/human.dm b/code/_onclick/human.dm
index cb71e27f9d1a..4dbf77144df9 100644
--- a/code/_onclick/human.dm
+++ b/code/_onclick/human.dm
@@ -64,7 +64,7 @@
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, click_parameters)
- if(lying) //No attacks while laying down
+ if(body_position) //No attacks while laying down
return 0
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
@@ -88,7 +88,7 @@
/atom/proc/attack_hand(mob/user)
return
-/mob/living/carbon/human/MouseDrop_T(atom/dropping, mob/user)
+/mob/living/carbon/human/MouseDrop_T(atom/dropping, mob/living/user)
if(user != src)
return . = ..()
@@ -153,6 +153,4 @@
target.Move(user.loc, get_dir(target.loc, user.loc))
target.update_transform(TRUE)
- target.update_canmove()
-
diff --git a/code/_onclick/ventcrawl.dm b/code/_onclick/ventcrawl.dm
index b079cffe2afe..d3811e042ea5 100644
--- a/code/_onclick/ventcrawl.dm
+++ b/code/_onclick/ventcrawl.dm
@@ -45,7 +45,7 @@
to_chat(src, SPAN_WARNING("You must be conscious to do this!"))
return
- if(lying)
+ if(body_position)
to_chat(src, SPAN_WARNING("You can't vent crawl while you're stunned!"))
return
@@ -88,7 +88,7 @@
return
updatehealth()
- if(stat || stunned || dazed || knocked_down || lying || health < 0 || !client || !ventcrawl_carry())
+ if(is_mob_incapacitated(src) || health < 0 || !client || !ventcrawl_carry())
vent_found.animate_ventcrawl_reset()
return
diff --git a/code/_onclick/xeno.dm b/code/_onclick/xeno.dm
index 62d612790930..c881baf08dff 100644
--- a/code/_onclick/xeno.dm
+++ b/code/_onclick/xeno.dm
@@ -3,7 +3,7 @@
*/
/mob/living/carbon/xenomorph/UnarmedAttack(atom/target, proximity, click_parameters, tile_attack = FALSE, ignores_resin = FALSE)
- if(lying || burrow) //No attacks while laying down
+ if(body_position == LYING_DOWN || burrow) //No attacks while laying down
return FALSE
var/mob/alt
@@ -21,7 +21,7 @@
if (!L.is_xeno_grabbable() || L == src) //Xenos never attack themselves.
continue
- if (L.lying)
+ if (L.body_position)
alt = L
continue
target = L
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 47b302e09aac..0510a43415a7 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -187,8 +187,10 @@
I.ui_action_click(owner, holder_item)
/datum/action/item_action/can_use_action()
- if(ishuman(owner) && !owner.is_mob_incapacitated() && !owner.lying)
- return TRUE
+ if(ishuman(owner) && !owner.is_mob_incapacitated())
+ var/mob/living/carbon/human/human = owner
+ if(human.body_position == STANDING_UP)
+ return TRUE
/datum/action/item_action/update_button_icon()
button.overlays.Cut()
diff --git a/code/datums/agents/tools/chloroform.dm b/code/datums/agents/tools/chloroform.dm
index 464533309bcc..6c575ba6daec 100644
--- a/code/datums/agents/tools/chloroform.dm
+++ b/code/datums/agents/tools/chloroform.dm
@@ -47,10 +47,9 @@
/obj/item/weapon/chloroform/proc/grab_stun(mob/living/M, mob/living/user)
M.anchored = TRUE
- M.frozen = TRUE
- M.density = FALSE
+ ADD_TRAIT(M, TRAIT_IMMOBILIZED, CLOROFORM_TRAIT)
+ ADD_TRAIT(M, TRAIT_UNDENSE, CLOROFORM_TRAIT)
M.able_to_speak = FALSE
- M.update_canmove()
M.drop_inv_item_on_ground(M.wear_mask, force = TRUE)
@@ -79,10 +78,10 @@
/obj/item/weapon/chloroform/proc/remove_stun(mob/living/M)
animate(M, pixel_x = 0, pixel_y = 0, time = 0.2 SECONDS, easing = QUAD_EASING)
M.anchored = FALSE
- M.density = TRUE
M.able_to_speak = TRUE
M.layer = MOB_LAYER
- M.unfreeze()
+ REMOVE_TRAIT(M, TRAIT_IMMOBILIZED, CLOROFORM_TRAIT)
+ REMOVE_TRAIT(M, TRAIT_UNDENSE, CLOROFORM_TRAIT)
QDEL_NULL(mask_item)
diff --git a/code/datums/ammo/ammo.dm b/code/datums/ammo/ammo.dm
index a858c6b1f5a7..8d201df07911 100644
--- a/code/datums/ammo/ammo.dm
+++ b/code/datums/ammo/ammo.dm
@@ -138,7 +138,7 @@
/datum/ammo/proc/knockback(mob/living/living_mob, obj/projectile/fired_projectile, max_range = 2)
if(!living_mob || living_mob == fired_projectile.firer)
return
- if(fired_projectile.distance_travelled > max_range || living_mob.lying)
+ if(fired_projectile.distance_travelled > max_range || living_mob.body_position)
return //Two tiles away or more, basically.
if(living_mob.mob_size >= MOB_SIZE_BIG)
@@ -180,8 +180,8 @@
else
living_mob.apply_stamina_damage(fired_projectile.ammo.damage, fired_projectile.def_zone, ARMOR_BULLET)
-/datum/ammo/proc/pushback(mob/target_mob, obj/projectile/fired_projectile, max_range = 2)
- if(!target_mob || target_mob == fired_projectile.firer || fired_projectile.distance_travelled > max_range || target_mob.lying)
+/datum/ammo/proc/pushback(mob/living/target_mob, obj/projectile/fired_projectile, max_range = 2)
+ if(!target_mob || target_mob == fired_projectile.firer || fired_projectile.distance_travelled > max_range || target_mob.body_position)
return
if(target_mob.mob_size >= MOB_SIZE_BIG)
diff --git a/code/datums/ammo/bullet/shotgun.dm b/code/datums/ammo/bullet/shotgun.dm
index 4cedb8b3ee69..4ace992a0d94 100644
--- a/code/datums/ammo/bullet/shotgun.dm
+++ b/code/datums/ammo/bullet/shotgun.dm
@@ -334,7 +334,7 @@
if(P.distance_travelled > 8)
knockback(M, P, 12)
- else if(!M || M == P.firer || M.lying) //These checks are included in knockback and would be redundant above.
+ else if(!M || M == P.firer || M.body_position) //These checks are included in knockback and would be redundant above.
return
shake_camera(M, 3, 4)
diff --git a/code/datums/ammo/xeno.dm b/code/datums/ammo/xeno.dm
index 9d91920ac6f8..e57f3e9972e5 100644
--- a/code/datums/ammo/xeno.dm
+++ b/code/datums/ammo/xeno.dm
@@ -49,8 +49,7 @@
if(!isxeno(M))
if(insta_neuro)
- if(M.knocked_down < 3)
- M.adjust_effect(1 * power, WEAKEN)
+ M.adjust_effect(1 * power, WEAKEN)
return
if(ishuman(M))
@@ -65,9 +64,8 @@
no_clothes_neuro = TRUE
if(no_clothes_neuro)
- if(M.knocked_down < 5)
- M.adjust_effect(1 * power, WEAKEN) // KD them a bit more
- M.visible_message(SPAN_DANGER("[M] falls prone."))
+ M.adjust_effect(1 * power, WEAKEN) // KD them a bit more
+ M.visible_message(SPAN_DANGER("[M] falls prone."))
/proc/apply_scatter_neuro(mob/M)
if(ishuman(M))
@@ -79,9 +77,8 @@
H.visible_message(SPAN_DANGER("[M] shrugs off the neurotoxin!"))
return
- if(M.knocked_down < 0.7) // apply knockdown only if current knockdown is less than 0.7 second
- M.apply_effect(0.7, WEAKEN)
- M.visible_message(SPAN_DANGER("[M] falls prone."))
+ M.apply_effect(0.5, WEAKEN)
+ M.visible_message(SPAN_DANGER("[M] falls prone."))
/datum/ammo/xeno/toxin/on_hit_mob(mob/M,obj/projectile/P)
if(ishuman(M))
diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm
index ef77aaf471dc..487993877e2b 100644
--- a/code/datums/components/footstep.dm
+++ b/code/datums/components/footstep.dm
@@ -47,7 +47,7 @@
if(!T)
return
var/mob/living/parent_mob = parent
- if(parent_mob.lying && (isfile(drag_sounds) || istext(drag_sounds)))
+ if(parent_mob.body_position && (isfile(drag_sounds) || istext(drag_sounds)))
playsound(T, drag_sounds, volume, rand(20000, 25000), range, falloff = falloff)
else if(isfile(footstep_sounds) || istext(footstep_sounds))
playsound(T, footstep_sounds, volume, rand(20000, 25000), range, falloff = falloff)
diff --git a/code/datums/components/weed_food.dm b/code/datums/components/weed_food.dm
index ce6c17e0af95..16be8665f55b 100644
--- a/code/datums/components/weed_food.dm
+++ b/code/datums/components/weed_food.dm
@@ -259,7 +259,7 @@
active = FALSE
merged = TRUE
- parent_mob.density = FALSE
+ ADD_TRAIT(parent_mob, TRAIT_UNDENSE, XENO_WEED_TRAIT)
parent_mob.anchored = TRUE
parent_mob.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
parent_mob.plane = FLOOR_PLANE
diff --git a/code/datums/datum.dm b/code/datums/datum.dm
index b26c6afe4d91..7d497785a72a 100644
--- a/code/datums/datum.dm
+++ b/code/datums/datum.dm
@@ -19,8 +19,8 @@
/// Active timers with this datum as the target
var/list/active_timers
- /// Status traits attached.
- var/list/status_traits
+ /// Status traits attached to this datum. associative list of the form: list(trait name (string) = list(source1, source2, source3,...))
+ var/list/_status_traits
/**
* Components attached to this datum
diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm
index 46cd8952dda1..71c2dc548937 100644
--- a/code/datums/diseases/cold.dm
+++ b/code/datums/diseases/cold.dm
@@ -20,7 +20,7 @@
cure()
return
*/
- if(affected_mob.lying && prob(40)) //changed FROM prob(10) until sleeping is fixed
+ if(affected_mob.body_position && prob(40)) //changed FROM prob(10) until sleeping is fixed
to_chat(affected_mob, SPAN_NOTICE(" You feel better."))
cure()
return
@@ -43,7 +43,7 @@
cure()
return
*/
- if(affected_mob.lying && prob(25)) //changed FROM prob(5) until sleeping is fixed
+ if(affected_mob.body_position && prob(25)) //changed FROM prob(5) until sleeping is fixed
to_chat(affected_mob, SPAN_NOTICE(" You feel better."))
cure()
return
diff --git a/code/datums/diseases/flu.dm b/code/datums/diseases/flu.dm
index f2c029587616..135da4f85745 100644
--- a/code/datums/diseases/flu.dm
+++ b/code/datums/diseases/flu.dm
@@ -21,7 +21,7 @@
stage--
return
*/
- if(affected_mob.lying && prob(20)) //added until sleeping is fixed --Blaank
+ if(affected_mob.body_position && prob(20)) //added until sleeping is fixed --Blaank
to_chat(affected_mob, SPAN_NOTICE(" You feel better."))
stage--
return
@@ -46,7 +46,7 @@
stage--
return
*/
- if(affected_mob.lying && prob(15)) //added until sleeping is fixed
+ if(affected_mob.resting && prob(15)) //added until sleeping is fixed
to_chat(affected_mob, SPAN_NOTICE(" You feel better."))
stage--
return
diff --git a/code/datums/effects/xeno_strains/boiler_trap.dm b/code/datums/effects/xeno_strains/boiler_trap.dm
index 61451391e816..29cc1f41b81c 100644
--- a/code/datums/effects/xeno_strains/boiler_trap.dm
+++ b/code/datums/effects/xeno_strains/boiler_trap.dm
@@ -4,19 +4,17 @@
effect_name = "boiler trap"
duration = null
flags = INF_DURATION
- /// Ghetto flag indicating whether we actually placed the freeze or not, until we have an actual effects system
- var/freezer = FALSE
-/datum/effects/boiler_trap/New(atom/A, mob/from, last_dmg_source, zone)
+/datum/effects/boiler_trap/New(atom/A, mob/living/from, last_dmg_source, zone)
. = ..()
if(!QDELETED(src))
- var/mob/M = affected_atom
- freezer = M.freeze()
+ var/mob/living/M = affected_atom
+ ADD_TRAIT(M, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY(effect_name))
/datum/effects/boiler_trap/Destroy(force)
- if(ismob(affected_atom) && freezer)
- var/mob/M = affected_atom
- M.unfreeze()
+ if(ismob(affected_atom))
+ var/mob/living/M = affected_atom
+ REMOVE_TRAIT(M, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY(effect_name))
return ..()
/datum/effects/boiler_trap/validate_atom(atom/A)
@@ -28,8 +26,6 @@
/datum/effects/boiler_trap/process_mob()
. = ..()
if(!.) return FALSE
- var/mob/M = affected_atom
- if(M.frozen) return TRUE
- if(!freezer)
- freezer = M.freeze()
+ var/mob/living/M = affected_atom
+ ADD_TRAIT(M, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY(effect_name))
return TRUE
diff --git a/code/datums/elements/mouth_drop_item.dm b/code/datums/elements/mouth_drop_item.dm
index 42c61bd275cc..7a546c6b3933 100644
--- a/code/datums/elements/mouth_drop_item.dm
+++ b/code/datums/elements/mouth_drop_item.dm
@@ -19,9 +19,9 @@
SIGNAL_HANDLER
if(slot == WEAR_FACE)
- I.RegisterSignal(user, COMSIG_MOB_KNOCKED_DOWN, TYPE_PROC_REF(/obj/item, drop_to_floor))
+ I.RegisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION, TYPE_PROC_REF(/obj/item, drop_to_floor))
/datum/element/mouth_drop_item/proc/item_dropped(obj/item/I, mob/living/carbon/human/user)
SIGNAL_HANDLER
- I.UnregisterSignal(user, COMSIG_MOB_KNOCKED_DOWN)
+ I.UnregisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION)
diff --git a/code/datums/mob_hud.dm b/code/datums/mob_hud.dm
index 65c5a47896fa..72d8c8dec3fe 100644
--- a/code/datums/mob_hud.dm
+++ b/code/datums/mob_hud.dm
@@ -797,8 +797,8 @@ var/global/image/hud_icon_hudfocus
if (tag_found)
tag_holder.overlays += image('icons/mob/hud/hud.dmi', src, "prae_tag")
- // Hacky, but works. Currently effects are hard to make with precise timings
- var/freeze_found = frozen
+ // Hacky, but works. Currently effects are hard to make with precise timings // Dont worry i'm working on it --fira
+ var/freeze_found = HAS_TRAIT(src, TRAIT_IMMOBILIZED) // This is gonna trigger all the time...
if (freeze_found)
freeze_holder.overlays += image('icons/mob/hud/hud.dmi', src, "xeno_freeze")
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index e1541f8368b8..31879d79f216 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -116,7 +116,14 @@ directive is properly returned.
//===========================================================================
-
+// TODO make all atoms use set_density, do not rely on it at present
+///Setter for the `density` variable to append behavior related to its changing.
+/atom/proc/set_density(new_value)
+ SHOULD_CALL_PARENT(TRUE)
+ if(density == new_value)
+ return
+ . = density
+ density = new_value
//atmos procs
@@ -142,14 +149,20 @@ directive is properly returned.
return loc.return_gas()
// Updates the atom's transform
-/atom/proc/apply_transform(matrix/M)
+/atom/proc/apply_transform(matrix/M, time = 0)
if(!base_transform)
transform = M
return
var/matrix/base_copy = matrix(base_transform)
// Compose the base and applied transform in that order
- transform = base_copy.Multiply(M)
+ var/matrix/complete = base_copy.Multiply(M)
+
+ if(!time)
+ transform = complete
+ return
+
+ animate(src, transform = complete, time = time, easing = (EASE_IN|EASE_OUT))
/atom/proc/on_reagent_change()
return
diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm
index e7d7b7a67edf..12779d1fc1bc 100644
--- a/code/game/gamemodes/colonialmarines/whiskey_outpost.dm
+++ b/code/game/gamemodes/colonialmarines/whiskey_outpost.dm
@@ -459,10 +459,10 @@
unacidable = TRUE
var/working = 0
-/obj/structure/machinery/wo_recycler/attack_hand(mob/user)
+/obj/structure/machinery/wo_recycler/attack_hand(mob/living/user)
if(inoperable(MAINT))
return
- if(user.lying || user.stat)
+ if(user.body_position || user.stat)
return
if(ismaintdrone(usr) || \
istype(usr, /mob/living/carbon/xenomorph))
diff --git a/code/game/gamemodes/colonialmarines/xenovsxeno.dm b/code/game/gamemodes/colonialmarines/xenovsxeno.dm
index 5623295f1915..a408a91f7f63 100644
--- a/code/game/gamemodes/colonialmarines/xenovsxeno.dm
+++ b/code/game/gamemodes/colonialmarines/xenovsxeno.dm
@@ -144,7 +144,6 @@
original.statistic_exempt = TRUE
original.buckled = start_nest
original.setDir(start_nest.dir)
- original.update_canmove()
start_nest.buckled_mob = original
start_nest.afterbuckle(original)
diff --git a/code/game/jobs/job/antag/xeno/xenomorph.dm b/code/game/jobs/job/antag/xeno/xenomorph.dm
index 53b06147e28c..d807cd3be38b 100644
--- a/code/game/jobs/job/antag/xeno/xenomorph.dm
+++ b/code/game/jobs/job/antag/xeno/xenomorph.dm
@@ -90,7 +90,6 @@
human_to_transform.statistic_exempt = TRUE
human_to_transform.buckled = start_nest
human_to_transform.setDir(start_nest.dir)
- human_to_transform.update_canmove()
start_nest.buckled_mob = human_to_transform
start_nest.afterbuckle(human_to_transform)
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index c9092a750f73..03c013703b07 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -19,7 +19,7 @@
active_power_usage = 5
var/strapped = 0
can_buckle = TRUE
- buckle_lying = TRUE
+ buckle_lying = 90
var/buckling_y = -4
surgery_duration_multiplier = SURGERY_SURFACE_MULT_IDEAL //Ideal surface for surgery.
var/patient_exam = 0
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index d82591994e7b..4ad40a6058bb 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -763,7 +763,6 @@
M.stop_pulling()
M.apply_effect(8, STUN)
M.apply_effect(5, WEAKEN)
- M.lying = 1
..()
/obj/structure/machinery/bot/mulebot/alter_health()
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 67e4e8ed35ab..3a809620d7e6 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -68,7 +68,6 @@
src.occupant.updatehealth()
if (src.occupant.health >= 0 && src.occupant.stat == DEAD)
src.occupant.set_stat(CONSCIOUS)
- src.occupant.lying = 0
GLOB.dead_mob_list -= src.occupant
GLOB.alive_mob_list += src.occupant
occupant.reload_fullscreens()
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index fe85599018ae..7ad223093130 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -24,7 +24,7 @@
set name = "Eject ID Card"
set src in oview(1)
- if(!usr || usr.stat || usr.lying) return
+ if(!usr || usr.is_mob_incapacitated()) return
if(scan)
to_chat(usr, "You remove \the [scan] from \the [src].")
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index c5a13e2c3e74..19e3ac900af6 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -51,11 +51,11 @@
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
- else if (!R.canmove)
+ else if (HAS_TRAIT_FROM(R, TRAIT_IMMOBILIZED, HACKED_TRAIT))
dat += " Locked Down |"
else
dat += " Operating Normally |"
- if(R.canmove && R.cell)
+ if(R.cell)
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
else
dat += " No Cell Installed |"
@@ -70,7 +70,8 @@
if (isRemoteControlling(user))
if((user.mind.original == user))
dat += "(Hack) "
- dat += "([R.canmove ? "Lockdown" : "Release"]) "
+ var/canmove = HAS_TRAIT_FROM(src, TRAIT_IMMOBILIZED, HACKED_TRAIT)
+ dat += "([canmove ? "Lockdown" : "Release"]) "
dat += "(Destroy)"
dat += "
"
dat += "(Return to Main Menu)
"
@@ -161,20 +162,22 @@
else if (href_list["stopbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"])
+ var/canmove = HAS_TRAIT_FROM(src, TRAIT_IMMOBILIZED, HACKED_TRAIT)
if(R && istype(R)) // Extra sancheck because of input var references
- var/choice = tgui_input_list(usr, "Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?", "Hack machine", list("Confirm", "Abort"))
+ var/choice = tgui_input_list(usr, "Are you certain you wish to [canmove ? "lock down" : "release"] [R.name]?", "Hack machine", list("Confirm", "Abort"))
if(choice == "Confirm")
if(R && istype(R))
- message_admins("[key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!")
- log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [R.name]!")
- R.canmove = !R.canmove
+ message_admins("[key_name_admin(usr)] [canmove ? "locked down" : "released"] [R.name]!")
+ log_game("[key_name(usr)] [canmove ? "locked down" : "released"] [R.name]!")
+ if(canmove)
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, HACKED_TRAIT)
+ else
+ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, HACKED_TRAIT)
if (R.lockcharge)
- // R.cell.charge = R.lockcharge
R.lockcharge = !R.lockcharge
to_chat(R, "Your lockdown has been lifted!")
else
R.lockcharge = !R.lockcharge
- // R.cell.charge = 0
to_chat(R, "You have been locked down!")
else
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index b7257ff4e7d3..df032301ee45 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -91,7 +91,7 @@ GLOBAL_LIST_INIT(airlock_wire_descriptions, list(
else if(user.hallucination > 50 && prob(10) && operating == 0)
to_chat(user, SPAN_DANGER("You feel a powerful shock course through your body!"))
user.halloss += 10
- user.stunned += 10
+ user.apply_effect(10, STUN)
return
..(user)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 065816567ca1..d236b9616620 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -135,7 +135,7 @@
"Would you like to [density ? "open" : "close"] this [src.name]?[ alarmed && density ? "\nNote that by doing so, you acknowledge any damages from opening this\n[src.name] as being your own fault, and you will be held accountable under the law." : ""]",\
"\The [src]", list("Yes", "No")) != "Yes")
return
- if(user.is_mob_incapacitated() || (!user.canmove && !isRemoteControlling(user)) || (get_dist(src, user) > 1 && !isRemoteControlling(user)))
+ if(user.is_mob_incapacitated() || (get_dist(src, user) > 1 && !isRemoteControlling(user)))
to_chat(user, "Sorry, you must remain able bodied and close to \the [src] in order to use it.")
return
if(density && (inoperable())) //can still close without power
diff --git a/code/game/machinery/fax_machine.dm b/code/game/machinery/fax_machine.dm
index 7bbc86681eb1..87398700691d 100644
--- a/code/game/machinery/fax_machine.dm
+++ b/code/game/machinery/fax_machine.dm
@@ -109,7 +109,8 @@ var/list/alldepartments = list()
set category = "Object"
set name = "Eject ID Card"
set src in view(1)
- if(!usr || usr.stat || usr.lying) return
+ if(usr.is_mob_incapacitated())
+ return
if(ishuman(usr) && scan)
to_chat(usr, "You remove \the [scan] from \the [src].")
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index 516cdad380b1..a19c99aaac04 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -36,12 +36,12 @@
update_icon()
-/obj/structure/machinery/floodlight/attack_hand(mob/user)
+/obj/structure/machinery/floodlight/attack_hand(mob/living/user)
if(!toggleable)
to_chat(user, SPAN_NOTICE("[src] doesn't seem to have a switch to toggle the light."))
return
- if(user.lying || user.stat)
+ if(user.body_position || user.stat)
return
if(!is_valid_user(user))
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index ef6c74a052cd..13bde056eb12 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -57,7 +57,7 @@
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
- if(user.stat || get_dist(user, src) > 1 || user.blinded || user.lying)
+ if(user.stat || get_dist(user, src) > 1 || user.blinded || user.body_position)
return
if(!skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE))
@@ -179,7 +179,7 @@
if(!istype(usr, /mob/living))
return
- if(usr.stat || usr.lying)
+ if(usr.stat || usr.is_mob_incapacitated())
return
mode = !mode
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index f4ad7a63ba77..d60e193bf696 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -229,7 +229,11 @@ Class Procs:
return TRUE
if(inoperable())
return 1
- if(usr.is_mob_restrained() || usr.lying || usr.stat)
+ if(isliving(usr))
+ var/mob/living/living = usr
+ if(living.body_position == LYING_DOWN) // legacy. if you too find it doesn't make sense, consider removing it
+ return TRUE
+ if(usr.is_mob_restrained())
return 1
if(!is_valid_user(usr))
to_chat(usr, SPAN_DANGER("You don't have the dexterity to do this!"))
@@ -251,10 +255,10 @@ Class Procs:
else
return src.attack_hand(user)
-/obj/structure/machinery/attack_hand(mob/user as mob)
+/obj/structure/machinery/attack_hand(mob/living/user as mob)
if(inoperable(MAINT))
return TRUE
- if(user.lying || user.stat)
+ if(user.body_position == LYING_DOWN || user.stat)
return TRUE
if(!is_valid_user(user))
to_chat(usr, SPAN_DANGER("You don't have the dexterity to do this!"))
diff --git a/code/game/machinery/medical_pod/bodyscanner.dm b/code/game/machinery/medical_pod/bodyscanner.dm
index fdcd0ceb62e6..16584605a8c5 100644
--- a/code/game/machinery/medical_pod/bodyscanner.dm
+++ b/code/game/machinery/medical_pod/bodyscanner.dm
@@ -204,7 +204,7 @@
"toxloss" = H.getToxLoss(),
"cloneloss" = H.getCloneLoss(),
"brainloss" = H.getBrainLoss(),
- "knocked_out" = H.knocked_out,
+// "knocked_out" = H.knocked_out,
"bodytemp" = H.bodytemperature,
"inaprovaline_amount" = H.reagents.get_reagent_amount("inaprovaline"),
"dexalin_amount" = H.reagents.get_reagent_amount("dexalin"),
@@ -263,7 +263,7 @@
s_class = occ["brainloss"] < 1 ? INTERFACE_GOOD : INTERFACE_BAD
dat += "[SET_CLASS("  Approx. Brain Damage:", INTERFACE_PINK)] [SET_CLASS("[occ["brainloss"]]%", s_class)]
"
- dat += "[SET_CLASS("Knocked Out Summary:", "#40628a")] [occ["knocked_out"]]% ([round(occ["knocked_out"] / 4)] seconds left!)
"
+ //dat += "[SET_CLASS("Knocked Out Summary:", "#40628a")] [occ["knocked_out"]]% ([round(occ["knocked_out"] / 4)] seconds left!)
"
dat += "[SET_CLASS("Body Temperature:", "#40628a")] [occ["bodytemp"]-T0C]°C ([occ["bodytemp"]*1.8-459.67]°F)
"
s_class = occ["blood_amount"] > 448 ? INTERFACE_OKAY : INTERFACE_BAD
diff --git a/code/game/machinery/medical_pod/medical_pod.dm b/code/game/machinery/medical_pod/medical_pod.dm
index b284d71ad4a7..62c8eef1f72c 100644
--- a/code/game/machinery/medical_pod/medical_pod.dm
+++ b/code/game/machinery/medical_pod/medical_pod.dm
@@ -155,7 +155,6 @@
if(exit_stun)
occupant.apply_effect(exit_stun, STUN) //Action delay when going out
- occupant.update_canmove() //Force the delay to go in action immediately
occupant.visible_message(SPAN_WARNING("[occupant] pops out of \the [src]!"),
SPAN_WARNING("You get out of \the [src] and get your bearings!"))
diff --git a/code/game/machinery/medical_pod/sleeper.dm b/code/game/machinery/medical_pod/sleeper.dm
index 35d9a44863d2..e6216c9ef0f9 100644
--- a/code/game/machinery/medical_pod/sleeper.dm
+++ b/code/game/machinery/medical_pod/sleeper.dm
@@ -392,7 +392,7 @@
to_chat(user, "[]\t -Toxin Content %: []", (occupant.getToxLoss() < 60 ? SPAN_NOTICE("") : SPAN_DANGER("")), occupant.getToxLoss())
to_chat(user, "[]\t -Burn Severity %: []", (occupant.getFireLoss() < 60 ? SPAN_NOTICE("") : SPAN_DANGER("")), occupant.getFireLoss())
to_chat(user, SPAN_NOTICE(" Expected time till occupant can safely awake: (note: If health is below 20% these times are inaccurate)"))
- to_chat(user, SPAN_NOTICE(" \t [occupant.knocked_out / 5] second\s (if around 1 or 2 the sleeper is keeping them asleep.)"))
+// to_chat(user, SPAN_NOTICE(" \t [occupant.knocked_out / 5] second\s (if around 1 or 2 the sleeper is keeping them asleep.)"))
else
to_chat(user, SPAN_NOTICE(" There is no one inside!"))
return
diff --git a/code/game/machinery/nuclearbomb.dm b/code/game/machinery/nuclearbomb.dm
index 743f53e4f03b..f3c09dfecdd2 100644
--- a/code/game/machinery/nuclearbomb.dm
+++ b/code/game/machinery/nuclearbomb.dm
@@ -99,7 +99,7 @@ var/bomb_set = FALSE
..()
/obj/structure/machinery/nuclearbomb/attack_hand(mob/user as mob)
- if(user.is_mob_incapacitated() || !user.canmove || get_dist(src, user) > 1 || isRemoteControlling(user))
+ if(user.is_mob_incapacitated() || get_dist(src, user) > 1 || isRemoteControlling(user))
return
if(isyautja(user))
@@ -291,7 +291,7 @@ var/bomb_set = FALSE
set name = "Make Deployable"
set src in oview(1)
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || being_used || timing)
+ if(usr.is_mob_incapacitated() || being_used || timing)
return
if(!ishuman(usr))
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index fc8815b0511f..e007ada79a0e 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -75,7 +75,7 @@
/obj/structure/machinery/pipedispenser/Topic(href, href_list)
if(..())
return
- if(unwrenched || !usr.canmove || usr.stat || usr.is_mob_restrained() || !in_range(loc, usr))
+ if(unwrenched || usr.is_mob_incapacitated() || !in_range(loc, usr))
close_browser(usr, "pipedispenser")
return
usr.set_interaction(src)
@@ -150,7 +150,7 @@ Nah
//Allow you to drag-drop disposal pipes into it
/obj/structure/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/disposalconstruct/pipe as obj, mob/usr as mob)
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return
if (!istype(pipe) || get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 )
@@ -192,7 +192,7 @@ Nah
usr.set_interaction(src)
src.add_fingerprint(usr)
if(href_list["dmake"])
- if(unwrenched || !usr.canmove || usr.stat || usr.is_mob_restrained() || !in_range(loc, usr))
+ if(unwrenched || usr.is_mob_incapacitated() || !in_range(loc, usr))
close_browser(usr, "pipedispenser")
return
if(!wait)
diff --git a/code/game/machinery/vending/cm_vending.dm b/code/game/machinery/vending/cm_vending.dm
index 861f5b37ebca..16b8f3e47e35 100644
--- a/code/game/machinery/vending/cm_vending.dm
+++ b/code/game/machinery/vending/cm_vending.dm
@@ -847,7 +847,7 @@ GLOBAL_LIST_EMPTY(vending_products)
if(inoperable())
return
- if(user.stat || user.is_mob_restrained() || user.lying)
+ if(user.stat || user.is_mob_restrained())
return
if(get_dist(user, src) > 1 || get_dist(src, A) > 1)
diff --git a/code/game/machinery/vending/vending.dm b/code/game/machinery/vending/vending.dm
index 414ab4a562e1..b5f2c6181c93 100644
--- a/code/game/machinery/vending/vending.dm
+++ b/code/game/machinery/vending/vending.dm
@@ -820,7 +820,7 @@ GLOBAL_LIST_EMPTY_TYPED(total_vending_machines, /obj/structure/machinery/vending
if(inoperable())
return
- if(user.stat || user.is_mob_restrained() || user.lying)
+ if(user.stat || user.is_mob_restrained())
return
if(get_dist(user, src) > 1 || get_dist(src, A) > 1)
diff --git a/code/game/objects/effects/acid_hole.dm b/code/game/objects/effects/acid_hole.dm
index 415df0e7e5a7..5adc84233682 100644
--- a/code/game/objects/effects/acid_hole.dm
+++ b/code/game/objects/effects/acid_hole.dm
@@ -50,18 +50,18 @@
return XENO_NO_DELAY_ACTION
/obj/effect/acid_hole/proc/expand_hole(mob/living/carbon/xenomorph/user)
- if(user.action_busy || user.lying)
+ if(user.action_busy || user.is_mob_incapacitated())
return
playsound(src, "pry", 25, 1)
xeno_attack_delay(user)
- if(do_after(user, 60, INTERRUPT_ALL, BUSY_ICON_GENERIC) && !QDELETED(src) && holed_wall && !user.lying && istype(holed_wall))
+ if(do_after(user, 60, INTERRUPT_ALL, BUSY_ICON_GENERIC) && !QDELETED(src) && holed_wall && istype(holed_wall))
holed_wall.take_damage(rand(2000,3500))
user.emote("roar")
-/obj/effect/acid_hole/proc/use_wall_hole(mob/user)
+/obj/effect/acid_hole/proc/use_wall_hole(mob/living/user)
- if(user.mob_size >= MOB_SIZE_BIG || user.is_mob_incapacitated() || user.lying || user.buckled || user.anchored)
+ if(user.mob_size >= MOB_SIZE_BIG || user.is_mob_incapacitated() || user.body_position || user.buckled || user.anchored)
return FALSE
var/mob_dir = get_dir(user, src)
@@ -95,7 +95,7 @@
to_chat(user, SPAN_NOTICE("You start crawling through the hole."))
if(do_after(user, 15, INTERRUPT_NO_NEEDHAND, BUSY_ICON_GENERIC))
- if(!user.is_mob_incapacitated() && !user.lying && !user.buckled)
+ if(!user.is_mob_incapacitated() && !user.buckled)
if (T.density)
return
for(var/obj/O in T)
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index 867c6924b39d..0b44c0bb4443 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -160,7 +160,7 @@
//damages human that comes in contact
/obj/effect/xenomorph/spray/proc/apply_spray(mob/living/carbon/H, should_stun = TRUE)
- if(!H.lying)
+ if(H.body_position == STANDING_UP)
to_chat(H, SPAN_DANGER("Your feet scald and burn! Argh!"))
if(ishuman(H))
H.emote("pain")
@@ -264,7 +264,7 @@
else
PAS.increment_stack_count(2)
- if(!H.lying)
+ if(H.body_position == STANDING_UP)
to_chat(H, SPAN_DANGER("Your feet scald and burn! Argh!"))
H.emote("pain")
H.last_damage_data = cause_data
diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm
index 2499810cbd3f..ab3c248c797f 100644
--- a/code/game/objects/effects/step_triggers.dm
+++ b/code/game/objects/effects/step_triggers.dm
@@ -50,7 +50,7 @@
if(ismob(AM))
var/mob/M = AM
if(immobilize)
- M.canmove = 0
+ ADD_TRAIT(M, TRAIT_IMMOBILIZED, STEP_TRIGGER_TRAIT)
affecting.Add(AM)
while(AM && !stopthrow)
@@ -87,7 +87,7 @@
if(ismob(AM))
var/mob/M = AM
if(immobilize)
- M.canmove = 1
+ REMOVE_TRAIT(M, TRAIT_IMMOBILIZED, STEP_TRIGGER_TRAIT)
/* Stops things thrown by a thrower, doesn't do anything */
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index bf24b0758262..08d7a7ef0b5a 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -517,14 +517,14 @@ cases. Override_icon_state should be a list.*/
if(WEAR_L_HAND)
if(H.l_hand)
return FALSE
- if(H.lying)
+ if(H.body_position == LYING_DOWN)
to_chat(H, SPAN_WARNING("You can't equip that while lying down."))
return
return TRUE
if(WEAR_R_HAND)
if(H.r_hand)
return FALSE
- if(H.lying)
+ if(H.body_position == LYING_DOWN)
to_chat(H, SPAN_WARNING("You can't equip that while lying down."))
return
return TRUE
@@ -922,9 +922,10 @@ cases. Override_icon_state should be a list.*/
mob_state += GLOB.slot_to_contained_sprite_shorthand[slot]
return mob_state
-/obj/item/proc/drop_to_floor(mob/wearer)
+/obj/item/proc/drop_to_floor(mob/wearer, body_position)
SIGNAL_HANDLER
- wearer.drop_inv_item_on_ground(src)
+ if(body_position == LYING_DOWN)
+ wearer.drop_inv_item_on_ground(src)
// item animatzionen
diff --git a/code/game/objects/items/devices/autopsy_scanner.dm b/code/game/objects/items/devices/autopsy_scanner.dm
index c4c7ec665e23..8aa2053fee8b 100644
--- a/code/game/objects/items/devices/autopsy_scanner.dm
+++ b/code/game/objects/items/devices/autopsy_scanner.dm
@@ -174,7 +174,7 @@
M.update_inv_r_hand()
/obj/item/device/autopsy_scanner/attack(mob/living/carbon/human/M as mob, mob/living/carbon/user as mob)
- if(!istype(M) || !M.lying)
+ if(!istype(M) || !M.is_mob_incapacitated())
return
var/table
diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm
index 2d44ce076f30..f8cf52473114 100644
--- a/code/game/objects/items/devices/binoculars.dm
+++ b/code/game/objects/items/devices/binoculars.dm
@@ -422,7 +422,7 @@
if(!(GLOB.character_traits[/datum/character_trait/skills/spotter] in human.traits))
to_chat(human, SPAN_WARNING("You have no idea how to use this!"))
return FALSE
- if(istype(human) && !human.is_mob_incapacitated() && !human.lying && (holder_item == human.r_hand || holder_item || human.l_hand))
+ if(istype(human) && !human.is_mob_incapacitated() && (holder_item == human.r_hand || holder_item || human.l_hand))
return TRUE
/datum/action/item_action/specialist/spotter_target/proc/use_ability(atom/targeted_atom)
diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm
index 0b8cbc303c06..bc97cf04fdfb 100644
--- a/code/game/objects/items/devices/radio/beacon.dm
+++ b/code/game/objects/items/devices/radio/beacon.dm
@@ -27,7 +27,7 @@
set category = "Object"
set src in usr
- if ((usr.canmove && !( usr.is_mob_restrained() )))
+ if (usr.is_mob_incapacitated())
src.code = t
if (!( src.code ))
src.code = "beacon"
diff --git a/code/game/objects/items/explosives/grenades/flashbang.dm b/code/game/objects/items/explosives/grenades/flashbang.dm
index 365dfe26df89..eadf47dd9b21 100644
--- a/code/game/objects/items/explosives/grenades/flashbang.dm
+++ b/code/game/objects/items/explosives/grenades/flashbang.dm
@@ -256,6 +256,7 @@
//decide how banged mob is
var/bang_effect = 0
+ var/lying = H.body_position
//flashbang effect depends on eye protection only, so we will process this case first
//A bit dumb, but headsets don't have ear protection and even earmuffs are a fluff now
@@ -264,7 +265,7 @@
if((get_dist(H, T) <= 1 || src.loc == H.loc || src.loc == H))
H.apply_damage(5, BRUTE)
H.apply_damage(5, BURN)
- if(H.lying)
+ if(lying)
bang_effect = 1
else
bang_effect = 2
@@ -277,13 +278,13 @@
H.apply_damage(5, BRUTE)
H.apply_damage(5, BURN)
- if(H.lying)
+ if(lying)
bang_effect = 4
else
bang_effect = 5
else if(get_dist(H, T) <= 5)
- if(H.lying)
+ if(lying)
bang_effect = 3
else
bang_effect = 4
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 71fb02cf3f07..72a385e10b20 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -33,7 +33,7 @@
var/mob/living/carbon/human/user = usr
if (!istype(user))
return
- if (user.stat || get_dist(user, src) > 1 || get_dist(user, H) > 1 || H.lying)
+ if (user.stat || get_dist(user, src) > 1 || get_dist(user, H) > 1 || H.body_position)
return
if (!istype(H))
return
diff --git a/code/game/objects/items/hoverpack.dm b/code/game/objects/items/hoverpack.dm
index c2bfacd3c3ad..027b9d77f581 100644
--- a/code/game/objects/items/hoverpack.dm
+++ b/code/game/objects/items/hoverpack.dm
@@ -184,7 +184,7 @@
warning.forceMove(path[max_distance])
/obj/item/hoverpack/proc/can_use_hoverpack(mob/living/carbon/human/user)
- if(user.is_mob_incapacitated() || user.lying)
+ if(user.is_mob_incapacitated())
to_chat(user, SPAN_WARNING("You're a bit too incapacitated for that."))
return FALSE
@@ -204,7 +204,7 @@
/datum/action/item_action/hover/can_use_action()
var/mob/living/carbon/human/H = owner
- if(!H.is_mob_incapacitated() && !H.lying && holder_item == H.back)
+ if(!H.is_mob_incapacitated() && holder_item == H.back)
return TRUE
/datum/action/item_action/hover/action_activate()
diff --git a/code/game/objects/items/implants/implantneurostim.dm b/code/game/objects/items/implants/implantneurostim.dm
index a46cc31a2ca4..5893ad5fd233 100644
--- a/code/game/objects/items/implants/implantneurostim.dm
+++ b/code/game/objects/items/implants/implantneurostim.dm
@@ -63,7 +63,7 @@
var/mob_pain_msg = "Excruciating pain shoots through [part ? "your [part.display_name]" : "you"]!"
M.visible_message(SPAN_DANGER("[M] convulses in pain!"), SPAN_DANGER(mob_pain_msg))
M.flash_eyes(1, TRUE)
- M.stunned += 10
+ M.apply_effect(10, STUN)
M.apply_effect(10, WEAKEN)
M.apply_damage(100, HALLOSS, part)
M.apply_damage(5, BURN, part, 0, 0, src)
diff --git a/code/game/objects/items/reagent_containers/blood_pack.dm b/code/game/objects/items/reagent_containers/blood_pack.dm
index 0879dcffdc68..92c68e81c9d2 100644
--- a/code/game/objects/items/reagent_containers/blood_pack.dm
+++ b/code/game/objects/items/reagent_containers/blood_pack.dm
@@ -163,7 +163,7 @@
if(!istype(usr, /mob/living))
return
- if(usr.stat || usr.lying)
+ if(usr.stat || usr.is_mob_incapacitated())
return
mode = !mode
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index 3b65811b05b3..957cbd13f39b 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -745,6 +745,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
RegisterSignal(H, COMSIG_GRENADE_PRE_PRIME, PROC_REF(cloak_grenade_callback))
RegisterSignal(H, COMSIG_HUMAN_EXTINGUISH, PROC_REF(wrapper_fizzle_camouflage))
+ RegisterSignal(H, COMSIG_MOB_EFFECT_CLOAK_CANCEL, PROC_REF(deactivate_camouflage))
camo_active = TRUE
ADD_TRAIT(H, TRAIT_CLOAKED, TRAIT_SOURCE_EQUIPMENT(WEAR_BACK))
@@ -774,12 +775,14 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
deactivate_camouflage(wearer, TRUE, TRUE)
/obj/item/storage/backpack/marine/satchel/scout_cloak/proc/deactivate_camouflage(mob/living/carbon/human/H, anim = TRUE, forced)
+ SIGNAL_HANDLER
if(!istype(H))
return FALSE
UnregisterSignal(H, list(
COMSIG_GRENADE_PRE_PRIME,
- COMSIG_HUMAN_EXTINGUISH
+ COMSIG_HUMAN_EXTINGUISH,
+ COMSIG_MOB_EFFECT_CLOAK_CANCEL,
))
if(forced)
@@ -829,7 +832,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r
/datum/action/item_action/specialist/toggle_cloak/can_use_action()
var/mob/living/carbon/human/H = owner
- if(istype(H) && !H.is_mob_incapacitated() && !H.lying && holder_item == H.back)
+ if(istype(H) && !H.is_mob_incapacitated() && holder_item == H.back)
return TRUE
/datum/action/item_action/specialist/toggle_cloak/action_activate()
diff --git a/code/game/objects/items/storage/internal.dm b/code/game/objects/items/storage/internal.dm
index 68bdda8d7e7b..96750b23ffe6 100644
--- a/code/game/objects/items/storage/internal.dm
+++ b/code/game/objects/items/storage/internal.dm
@@ -25,10 +25,10 @@
//Items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour.
//Returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of
//Doing it without the ability to call another proc's parent, really.
-/obj/item/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj)
+/obj/item/storage/internal/proc/handle_mousedrop(mob/living/carbon/human/user, obj/over_object as obj)
if(ishuman(user))
- if(user.lying) //Can't use your inventory when lying
+ if(user.body_position) //Can't use your inventory when lying
return
if(QDELETED(master_object))
@@ -84,8 +84,8 @@
//Items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour.
//Returns 1 if the master item's parent's attack_hand() should be called, 0 otherwise.
//It's strange, but no other way of doing it without the ability to call another proc's parent, really.
-/obj/item/storage/internal/proc/handle_attack_hand(mob/user as mob, mods)
- if(user.lying)
+/obj/item/storage/internal/proc/handle_attack_hand(mob/living/user as mob, mods)
+ if(user.body_position == LYING_DOWN) // this should probably be is_mob_incapacitated
return FALSE
if(ishuman(user))
diff --git a/code/game/objects/items/storage/large_holster.dm b/code/game/objects/items/storage/large_holster.dm
index b4a6c3a8c1af..a2af23600e11 100644
--- a/code/game/objects/items/storage/large_holster.dm
+++ b/code/game/objects/items/storage/large_holster.dm
@@ -364,7 +364,7 @@
/datum/action/item_action/specialist/toggle_fuel/can_use_action()
var/mob/living/carbon/human/H = owner
- if(istype(H) && !H.is_mob_incapacitated() && !H.lying && holder_item == H.back)
+ if(istype(H) && !H.is_mob_incapacitated() && H.body_position == STANDING_UP && holder_item == H.back)
return TRUE
/datum/action/item_action/specialist/toggle_fuel/action_activate()
diff --git a/code/game/objects/items/storage/smartpack.dm b/code/game/objects/items/storage/smartpack.dm
index 8df079c92ca4..d012e773617b 100644
--- a/code/game/objects/items/storage/smartpack.dm
+++ b/code/game/objects/items/storage/smartpack.dm
@@ -144,7 +144,7 @@
immobile_form = FALSE
M.status_flags |= CANPUSH
M.anchored = FALSE
- M.unfreeze()
+ REMOVE_TRAIT(M, TRAIT_IMMOBILIZED, TRAIT_SOURCE_EQUIPMENT(WEAR_BACK))
..()
/obj/item/storage/backpack/marine/smartpack/attack_self(mob/user)
@@ -223,7 +223,7 @@
user.remove_filter("synth_protective_form")
-/obj/item/storage/backpack/marine/smartpack/proc/immobile_form(mob/user)
+/obj/item/storage/backpack/marine/smartpack/proc/immobile_form(mob/living/user)
if(activated_form)
return
@@ -236,7 +236,7 @@
battery_charge -= IMMOBILE_COST
user.status_flags &= ~CANPUSH
user.anchored = TRUE
- user.frozen = TRUE
+ ADD_TRAIT(user, TRAIT_IMMOBILIZED, TRAIT_SOURCE_EQUIPMENT(WEAR_BACK))
to_chat(user, SPAN_DANGER("[name] beeps, \"You are anchored in place and cannot be moved.\""))
to_chat(user, SPAN_INFO("The current charge reads [battery_charge]/[SMARTPACK_MAX_POWER_STORED]"))
@@ -248,7 +248,7 @@
else
user.status_flags |= CANPUSH
user.anchored = FALSE
- user.unfreeze()
+ REMOVE_TRAIT(user, TRAIT_IMMOBILIZED, TRAIT_SOURCE_EQUIPMENT(WEAR_BACK))
to_chat(user, SPAN_DANGER("[name] beeps, \"You can now move again.\""))
user.remove_filter("synth_immobile_form")
diff --git a/code/game/objects/items/tools/experimental_tools.dm b/code/game/objects/items/tools/experimental_tools.dm
index d27272881e1e..221aa279a53b 100644
--- a/code/game/objects/items/tools/experimental_tools.dm
+++ b/code/game/objects/items/tools/experimental_tools.dm
@@ -279,7 +279,7 @@
return
if(ishuman(user))
- if(user.stat || user.blinded || user.lying)
+ if(user.stat || user.blinded || user.body_position == LYING_DOWN)
return
if(attaching)
diff --git a/code/game/objects/items/toys/toy_weapons.dm b/code/game/objects/items/toys/toy_weapons.dm
index 9acf6f2943c3..80f94cab8e2e 100644
--- a/code/game/objects/items/toys/toy_weapons.dm
+++ b/code/game/objects/items/toys/toy_weapons.dm
@@ -156,10 +156,10 @@
O.show_message(SPAN_DANGER("[user] realized they were out of ammo and starting scrounging for some!"), SHOW_MESSAGE_VISIBLE)
-/obj/item/toy/crossbow/attack(mob/M as mob, mob/user as mob)
+/obj/item/toy/crossbow/attack(mob/living/M as mob, mob/user as mob)
src.add_fingerprint(user)
- if (src.bullets > 0 && M.lying)
+ if (src.bullets > 0 && M.body_position == LYING_DOWN)
for(var/mob/O in viewers(M, null))
if(O.client)
@@ -169,7 +169,7 @@
playsound(user.loc, 'sound/items/syringeproj.ogg', 15, 1)
new /obj/item/toy/crossbow_ammo(M.loc)
src.bullets--
- else if (M.lying && src.bullets == 0)
+ else if (M.body_position == LYING_DOWN && src.bullets == 0)
for(var/mob/O in viewers(M, null))
if (O.client)
O.show_message(SPAN_DANGER("[user] casually lines up a shot with [M]'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!"), SHOW_MESSAGE_VISIBLE, SPAN_DANGER("You hear someone fall"), SHOW_MESSAGE_AUDIBLE)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 3fa16af05875..109747f476c3 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -14,7 +14,8 @@
/// If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
var/in_use = FALSE
var/mob/living/buckled_mob
- var/buckle_lying = FALSE //Is the mob buckled in a lying position
+ /// Bed-like behaviour, forces mob.lying = buckle_lying if not set to [NO_BUCKLE_LYING].
+ var/buckle_lying = NO_BUCKLE_LYING
var/can_buckle = FALSE
/**Applied to surgery times for mobs buckled prone to it or lying on the same tile, if the surgery
cares about surface conditions. The lowest multiplier of objects on the tile is used.**/
@@ -224,7 +225,7 @@
else . = ..()
/obj/proc/afterbuckle(mob/M as mob) // Called after somebody buckled / unbuckled
- handle_rotation()
+ handle_rotation() // To be removed when we have full dir support in set_buckled
SEND_SIGNAL(src, COSMIG_OBJ_AFTER_BUCKLE, buckled_mob)
if(!buckled_mob)
UnregisterSignal(M, COMSIG_PARENT_QDELETING)
@@ -235,9 +236,8 @@
/obj/proc/unbuckle()
SIGNAL_HANDLER
if(buckled_mob && buckled_mob.buckled == src)
- buckled_mob.buckled = null
+ buckled_mob.set_buckled(null)
buckled_mob.anchored = initial(buckled_mob.anchored)
- buckled_mob.update_canmove()
var/M = buckled_mob
REMOVE_TRAITS_IN(buckled_mob, TRAIT_SOURCE_BUCKLE)
@@ -268,7 +268,7 @@
//trying to buckle a mob
/obj/proc/buckle_mob(mob/M, mob/user)
- if (!ismob(M) || (get_dist(src, user) > 1) || user.is_mob_restrained() || user.lying || user.stat || buckled_mob || M.buckled || !isturf(user.loc))
+ if (!ismob(M) || (get_dist(src, user) > 1) || user.is_mob_restrained() || user.stat || buckled_mob || M.buckled || !isturf(user.loc))
return
if (isxeno(user))
@@ -299,20 +299,15 @@
// the actual buckling proc
// Yes I know this is not style but its unreadable otherwise
-/obj/proc/do_buckle(mob/target, mob/user)
+/obj/proc/do_buckle(mob/living/target, mob/user)
send_buckling_message(target, user)
if (src && src.loc)
- target.buckled = src
+ target.set_buckled(src)
target.forceMove(src.loc)
target.setDir(dir)
- target.update_canmove()
src.buckled_mob = target
src.add_fingerprint(user)
afterbuckle(target)
- if(buckle_lying) // Make sure buckling to beds/nests etc only turns, and doesn't give a random offset
- var/matrix/new_matrix = matrix()
- new_matrix.Turn(90)
- target.apply_transform(new_matrix)
return TRUE
/obj/proc/send_buckling_message(mob/M, mob/user)
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 9b0b8cf30aae..1249bce9a3d2 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -150,7 +150,7 @@
for(var/mob/living/M in get_turf(src))
- if(M.lying) return //No spamming this on people.
+ if(M.body_position == LYING_DOWN) return //No spamming this on people.
M.apply_effect(5, WEAKEN)
to_chat(M, SPAN_WARNING("You topple as \the [src] moves under you!"))
@@ -191,7 +191,7 @@
H.updatehealth()
return
-/obj/structure/proc/can_touch(mob/user)
+/obj/structure/proc/can_touch(mob/living/user)
if(!user)
return 0
if(!Adjacent(user) || !isturf(user.loc))
@@ -199,7 +199,7 @@
if(user.is_mob_restrained() || user.buckled)
to_chat(user, SPAN_NOTICE("You need your hands and legs free for this."))
return 0
- if(user.is_mob_incapacitated(TRUE) || user.lying)
+ if(user.is_mob_incapacitated(TRUE) || user.body_position == LYING_DOWN)
return 0
if(isRemoteControlling(user))
to_chat(user, SPAN_NOTICE("You need hands for this."))
diff --git a/code/game/objects/structures/barricade/deployable.dm b/code/game/objects/structures/barricade/deployable.dm
index 77aa6b7e6816..0d5275f98a3d 100644
--- a/code/game/objects/structures/barricade/deployable.dm
+++ b/code/game/objects/structures/barricade/deployable.dm
@@ -63,7 +63,7 @@
if(!ishuman(usr))
return
- if(usr.lying)
+ if(usr.is_mob_incapacitated())
return
if(over_object == usr && Adjacent(usr))
diff --git a/code/game/objects/structures/bookcase.dm b/code/game/objects/structures/bookcase.dm
index becb0906e3c6..ce338de47b35 100644
--- a/code/game/objects/structures/bookcase.dm
+++ b/code/game/objects/structures/bookcase.dm
@@ -33,7 +33,7 @@
if(contents.len)
var/obj/item/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
if(choice)
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !in_range(loc, usr))
+ if(usr.is_mob_incapacitated() || !in_range(loc, usr))
return
if(ishuman(user))
if(!user.get_active_hand())
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index a7394f3a7586..d6148b23b7f0 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -79,10 +79,11 @@
M.forceMove(loc)
if(exit_stun)
M.apply_effect(exit_stun, STUN) //Action delay when going out of a closet
- M.update_canmove() //Force the delay to go in action immediately
- if(!M.lying)
- M.visible_message(SPAN_WARNING("[M] suddenly gets out of [src]!"),
- SPAN_WARNING("You get out of [src] and get your bearings!"))
+ if(isliving(M))
+ var/mob/living/living_M = M
+ if(living_M.mobility_flags & MOBILITY_MOVE)
+ M.visible_message(SPAN_WARNING("[M] suddenly gets out of [src]!"),
+ SPAN_WARNING("You get out of [src] and get your bearings!"))
/obj/structure/closet/proc/open()
if(opened)
@@ -333,7 +334,7 @@
set category = "Object"
set name = "Toggle Open"
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return
if(usr.loc == src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
index d6b4a35b04f7..3206da86b197 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm
@@ -78,7 +78,7 @@
set src in oview(1) // One square distance
set category = "Object"
set name = "Reset Lock"
- if(!usr.canmove || usr.stat || usr.is_mob_restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
+ if(usr.is_mob_incapacitated()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
return
if(ishuman(usr))
src.add_fingerprint(usr)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index e290a23a61e9..ed0b1ae05c08 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -121,7 +121,7 @@
set category = "Object"
set name = "Toggle Lock"
- if(!usr.canmove || usr.stat || usr.is_mob_restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
+ if(usr.is_mob_incapacitated()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
return
if(ishuman(usr))
diff --git a/code/game/objects/structures/crates_lockers/secure_crates.dm b/code/game/objects/structures/crates_lockers/secure_crates.dm
index a308c4c0a21c..9e9d16ec8e74 100644
--- a/code/game/objects/structures/crates_lockers/secure_crates.dm
+++ b/code/game/objects/structures/crates_lockers/secure_crates.dm
@@ -52,7 +52,7 @@
set category = "Object"
set name = "Toggle Lock"
- if(!usr.canmove || usr.stat || usr.is_mob_restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
+ if(usr.is_mob_incapacitated()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
return
if(ishuman(usr))
diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index f2e6b172ad88..da6d4f1a8254 100644
--- a/code/game/objects/structures/ladders.dm
+++ b/code/game/objects/structures/ladders.dm
@@ -67,8 +67,8 @@
else //wtf make your ladders properly assholes
icon_state = "ladder00"
-/obj/structure/ladder/attack_hand(mob/user)
- if(user.stat || get_dist(user, src) > 1 || user.blinded || user.lying || user.buckled || user.anchored) return
+/obj/structure/ladder/attack_hand(mob/living/user)
+ if(user.stat || get_dist(user, src) > 1 || user.blinded || user.body_position == LYING_DOWN || user.buckled || user.anchored) return
if(busy)
to_chat(user, SPAN_WARNING("Someone else is currently using [src]."))
return
@@ -94,7 +94,7 @@
SPAN_NOTICE("You start climbing [ladder_dir_name] [src]."))
busy = TRUE
if(do_after(user, 20, INTERRUPT_INCAPACITATED|INTERRUPT_OUT_OF_RANGE|INTERRUPT_RESIST, BUSY_ICON_GENERIC, src, INTERRUPT_NONE))
- if(!user.is_mob_incapacitated() && get_dist(user, src) <= 1 && !user.blinded && !user.lying && !user.buckled && !user.anchored)
+ if(!user.is_mob_incapacitated() && get_dist(user, src) <= 1 && !user.blinded && user.body_position != LYING_DOWN && !user.buckled && !user.anchored)
visible_message(SPAN_NOTICE("[user] climbs [ladder_dir_name] [src].")) //Hack to give a visible message to the people here without duplicating user message
user.visible_message(SPAN_NOTICE("[user] climbs [ladder_dir_name] [src]."),
SPAN_NOTICE("You climb [ladder_dir_name] [src]."))
@@ -103,9 +103,9 @@
busy = FALSE
add_fingerprint(user)
-/obj/structure/ladder/check_eye(mob/user)
+/obj/structure/ladder/check_eye(mob/living/user)
//Are we capable of looking?
- if(user.is_mob_incapacitated() || get_dist(user, src) > 1 || user.blinded || user.lying || !user.client)
+ if(user.is_mob_incapacitated() || get_dist(user, src) > 1 || user.blinded || user.body_position == LYING_DOWN || !user.client)
user.unset_interaction()
//Are ladder cameras ok?
@@ -140,7 +140,7 @@
//Peeking up/down
/obj/structure/ladder/MouseDrop(over_object, src_location, over_location)
if((over_object == usr && (in_range(src, usr))))
- if(islarva(usr) || isobserver(usr) || usr.is_mob_incapacitated() || usr.blinded || usr.lying)
+ if(islarva(usr) || isobserver(usr) || usr.is_mob_incapacitated() || usr.blinded)
to_chat(usr, "You can't do that in your current state.")
return
if(is_watching)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index dc8cf08d13f1..f1717f5bf0f5 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -113,13 +113,12 @@
else
. = ..()
-/obj/structure/morgue/relaymove(mob/user)
+/obj/structure/morgue/relaymove(mob/living/user)
if(user.is_mob_incapacitated())
return
if(exit_stun)
- user.stunned = max(user.stunned, exit_stun) //Action delay when going out of a closet (or morgue in this case)
- user.update_canmove() //Force the delay to go in action immediately
- if(!user.lying)
+ user.apply_effect(exit_stun, STUN)
+ if(user.mobility_flags & MOBILITY_MOVE)
user.visible_message(SPAN_WARNING("[user] suddenly gets out of [src]!"),
SPAN_WARNING("You get out of [src] and get your bearings!"))
toggle_morgue(user)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 7979994915f4..24598e7460bb 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -13,7 +13,7 @@
icon_state = "bed"
icon = 'icons/obj/objects.dmi'
can_buckle = TRUE
- buckle_lying = TRUE
+ buckle_lying = 90
throwpass = TRUE
debris = list(/obj/item/stack/sheet/metal)
var/buildstacktype = /obj/item/stack/sheet/metal
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 4186ae8608a9..e523906f4cfe 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -6,7 +6,7 @@
name = "chair"
desc = "A rectangular metallic frame sitting on four legs with a back panel. Designed to fit the sitting position, more or less comfortably."
icon_state = "chair"
- buckle_lying = FALSE
+ buckle_lying = 0
var/propelled = FALSE //Check for fire-extinguisher-driven chairs
var/can_rotate = TRUE
var/picked_up_item = /obj/item/weapon/twohanded/folded_metal_chair
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 2b42e641f0cf..986ae99739aa 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -20,7 +20,7 @@
if(world.time <= l_move_time + move_delay)
return
// Redundant check?
- if(user.is_mob_incapacitated() || user.lying)
+ if(user.is_mob_incapacitated())
return
if(propelled) //can't manually move it mid-propelling.
diff --git a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
index 7a4274c2c16e..1531367459b1 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm
@@ -10,7 +10,7 @@
health = 100
layer = ABOVE_MOB_LAYER
plane = GAME_PLANE
- buckle_lying = FALSE
+ buckle_lying = 0
var/on_fire = 0
var/resisting = 0
var/resisting_ready = 0
@@ -53,7 +53,7 @@
current_mob.pixel_y = buckling_y["[dir]"]
current_mob.pixel_x = buckling_x["[dir]"]
current_mob.dir = turn(dir, 180)
- current_mob.density = FALSE
+ ADD_TRAIT(current_mob, TRAIT_UNDENSE, XENO_NEST_TRAIT)
pixel_y = buckling_y["[dir]"]
pixel_x = buckling_x["[dir]"]
if(dir == SOUTH)
@@ -67,7 +67,9 @@
current_mob.pixel_y = initial(buckled_mob.pixel_y)
current_mob.pixel_x = initial(buckled_mob.pixel_x)
- current_mob.density = !(current_mob.lying || current_mob.stat == DEAD)
+ //current_mob.density = !(current_mob.lying || current_mob.stat == DEAD)
+ REMOVE_TRAIT(current_mob, TRAIT_UNDENSE, XENO_NEST_TRAIT)
+
if(dir == SOUTH)
current_mob.layer = initial(current_mob.layer)
if(!ishuman(current_mob))
@@ -145,7 +147,7 @@
if(!(buckled_mob && buckled_mob.buckled == src && buckled_mob != user))
return
- if(user.stat || user.lying || user.is_mob_restrained())
+ if(user.stat || user.body_position == LYING_DOWN || user.is_mob_restrained())
return
if(isxeno(user))
@@ -167,7 +169,7 @@
if(H.stat != DEAD)
if(alert(user, "[H] is still alive and kicking! Are you sure you want to remove them from the nest?", "Confirmation", "Yes", "No") != "Yes")
return
- if(!buckled_mob || !user.Adjacent(H) || user.stat || user.lying || user.is_mob_restrained())
+ if(!buckled_mob || !user.Adjacent(H) || user.is_mob_incapacitated(FALSE))
return
if(ishuman(user))
@@ -191,7 +193,7 @@
/obj/structure/bed/nest/buckle_mob(mob/mob, mob/user)
. = FALSE
- if(!isliving(mob) || islarva(user) || (get_dist(src, user) > 1) || user.is_mob_restrained() || user.stat || user.lying || mob.buckled || !iscarbon(user))
+ if(!isliving(mob) || islarva(user) || (get_dist(src, user) > 1) || user.is_mob_incapacitated(FALSE))
return
if(isxeno(mob))
@@ -220,7 +222,7 @@
var/mob/living/carbon/human/human = null
if(ishuman(mob))
human = mob
- if(!human.lying) //Don't ask me why is has to be
+ if(human.body_position != LYING_DOWN) //Don't ask me why is has to be
to_chat(user, SPAN_WARNING("[mob] is resisting, ground them."))
return
@@ -242,7 +244,7 @@
return
if(human) //Improperly stunned Marines won't be nested
- if(!human.lying) //Don't ask me why is has to be
+ if(human.body_position != LYING_DOWN) //Don't ask me why is has to be
to_chat(user, SPAN_WARNING("[mob] is resisting, ground them."))
return
diff --git a/code/game/objects/structures/vulture_spotter.dm b/code/game/objects/structures/vulture_spotter.dm
index 50505ab239b8..ab23a8086759 100644
--- a/code/game/objects/structures/vulture_spotter.dm
+++ b/code/game/objects/structures/vulture_spotter.dm
@@ -78,7 +78,7 @@
try_scope(user)
-/obj/structure/vulture_spotter_tripod/on_set_interaction(mob/user)
+/obj/structure/vulture_spotter_tripod/on_set_interaction(mob/living/user)
var/obj/item/attachable/vulture_scope/scope = get_vulture_scope()
scope.spotter_spotting = TRUE
to_chat(scope.scope_user, SPAN_NOTICE("You notice that [scope] drifts less."))
@@ -92,7 +92,7 @@
user.lighting_alpha = 127
user.sync_lighting_plane_alpha()
user.overlay_fullscreen("vulture_spotter", /atom/movable/screen/fullscreen/vulture/spotter)
- user.freeze()
+ ADD_TRAIT(user, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Vulture spotter"))
user.status_flags |= IMMOBILE_ACTION
user.visible_message(SPAN_NOTICE("[user] looks through [src]."),SPAN_NOTICE("You look through [src], ready to go!"))
user.forceMove(loc)
@@ -102,10 +102,10 @@
give_action(user, /datum/action/vulture_tripod_unscope, null, null, src)
set_scope_loc(user, scope)
-/obj/structure/vulture_spotter_tripod/on_unset_interaction(mob/user)
+/obj/structure/vulture_spotter_tripod/on_unset_interaction(mob/living/user)
user.status_flags &= ~IMMOBILE_ACTION
user.visible_message(SPAN_NOTICE("[user] looks up from [src]."),SPAN_NOTICE("You look up from [src]."))
- user.unfreeze()
+ REMOVE_TRAIT(user, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Vulture spotter"))
user.reset_view(null)
user.Move(get_step(src, reverse_direction(src.dir)))
user.client?.change_view(world_view_size, src)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index cccc1211bfb0..60c37fcdc607 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -8,6 +8,7 @@
density = FALSE
anchored = TRUE
can_buckle = TRUE
+ buckle_lying = 0
var/open = 0 //if the lid is up
var/cistern = 0 //if the cistern bit is open
var/w_items = 0 //the combined w_class of all the items in the cistern
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 5042167023e6..38b63b94570c 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -261,7 +261,7 @@
if("Remove")
if(!GLOB.trait_name_map)
GLOB.trait_name_map = generate_trait_name_map()
- for(var/trait in D.status_traits)
+ for(var/trait in D._status_traits)
var/name = GLOB.trait_name_map[trait] || trait
available_traits[name] = trait
@@ -282,7 +282,7 @@
if("All")
source = null
if("Specific")
- source = input("Source to be removed","Trait Remove/Add") as null|anything in sort_list(D.status_traits[chosen_trait])
+ source = input("Source to be removed","Trait Remove/Add") as null|anything in sort_list(D._status_traits[chosen_trait])
if(!source)
return
REMOVE_TRAIT(D,chosen_trait,source)
diff --git a/code/modules/admin/player_panel/actions/general.dm b/code/modules/admin/player_panel/actions/general.dm
index 174dfef55ad8..d75ad858ad99 100644
--- a/code/modules/admin/player_panel/actions/general.dm
+++ b/code/modules/admin/player_panel/actions/general.dm
@@ -109,9 +109,13 @@
name = "Toggle Frozen"
/datum/player_action/toggle_frozen/act(client/user, mob/target, list/params)
- target.frozen = text2num(params["freeze"])
+ var/frozen = text2num(params["freeze"])
+ if(frozen)
+ ADD_TRAIT(target, TRAIT_IMMOBILIZED, ADMIN_ACTION_TRAIT)
+ else
+ REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, ADMIN_ACTION_TRAIT)
- message_admins("[key_name_admin(user)] [target.frozen? "froze" : "unfroze"] [key_name_admin(target)]")
+ message_admins("[key_name_admin(user)] [frozen? "froze" : "unfroze"] [key_name_admin(target)]")
return TRUE
// MESSAGE
diff --git a/code/modules/admin/player_panel/player_panel.dm b/code/modules/admin/player_panel/player_panel.dm
index 12686e683521..87258571f950 100644
--- a/code/modules/admin/player_panel/player_panel.dm
+++ b/code/modules/admin/player_panel/player_panel.dm
@@ -489,7 +489,7 @@
.["mob_name"] = targetMob.name
.["mob_sleeping"] = targetMob.sleeping
- .["mob_frozen"] = targetMob.frozen
+ .["mob_frozen"] = HAS_TRAIT_FROM(targetMob, TRAIT_IMMOBILIZED, ADMIN_ACTION_TRAIT)
.["mob_speed"] = targetMob.speed
.["mob_status_flags"] = targetMob.status_flags
diff --git a/code/modules/admin/topic/topic.dm b/code/modules/admin/topic/topic.dm
index f78b6a844d4b..420f71d2c281 100644
--- a/code/modules/admin/topic/topic.dm
+++ b/code/modules/admin/topic/topic.dm
@@ -642,17 +642,6 @@
message_admins("[key_name_admin(usr)] attempting to monkeyize [key_name_admin(H)]")
H.monkeyize()
- else if(href_list["corgione"])
- if(!check_rights(R_SPAWN)) return
-
- var/mob/living/carbon/human/H = locate(href_list["corgione"])
- if(!istype(H))
- to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human")
- return
-
- message_admins("[key_name_admin(usr)] attempting to corgize [key_name_admin(H)]")
- H.corgize()
-
else if(href_list["forcespeech"])
if(!check_rights(R_ADMIN)) return
diff --git a/code/modules/animations/animation_library.dm b/code/modules/animations/animation_library.dm
index 2bbff8d4cfcd..d4fd8feeaf24 100644
--- a/code/modules/animations/animation_library.dm
+++ b/code/modules/animations/animation_library.dm
@@ -249,7 +249,7 @@ Can look good elsewhere as well.*/
var/pre_rappel_alpha = alpha
alpha = 20
dir = WEST
- canmove = FALSE
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, INTERACTION_TRAIT)
var/matrix/initial_matrix = matrix()
initial_matrix.Turn(45)
apply_transform(initial_matrix)
@@ -257,4 +257,4 @@ Can look good elsewhere as well.*/
var/matrix/reset_matrix = matrix()
animate(src, 3, transform = reset_matrix, pixel_y = 0, alpha = pre_rappel_alpha, flags = ANIMATION_PARALLEL)
sleep(3)
- canmove = TRUE
+ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, INTERACTION_TRAIT)
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 05ad7c5a87c7..929e2d6af7b2 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -137,7 +137,7 @@
/obj/item/device/assembly/infra/Topic(href, href_list)
..()
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !in_range(loc, usr))
+ if(usr.is_mob_incapacitated() || !in_range(loc, usr))
close_browser(usr, "infra")
return
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index a6462b7a9214..02e69802d5af 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -507,7 +507,7 @@
set name = "Adjust welding goggles"
set src in usr
- if(usr.canmove && !usr.stat && !usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
if(active)
active = 0
vision_impair = vision_impair_off
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 1a133eee0dfe..e4f9bdde48cb 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -36,7 +36,7 @@
return
/datum/action/item_action/view_publications/can_use_action()
- if(owner && !owner.is_mob_incapacitated() && !owner.lying && owner.faction != FACTION_SURVIVOR)
+ if(owner && !owner.is_mob_incapacitated() && owner.faction != FACTION_SURVIVOR)
return TRUE
/datum/action/item_action/view_publications/action_activate()
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index e6c8391ac0a1..15a4cf742464 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -88,7 +88,7 @@
playsound(loc, knockout_sound, 50, FALSE)
M.show_message(FONT_SIZE_LARGE(SPAN_WARNING("KNOCKOUT!")), SHOW_MESSAGE_VISIBLE)
return 1
- if (L.lying == 1 || L.stat == UNCONSCIOUS)//Can't beat 'em while they're down.
+ if (L.body_position == LYING_DOWN || L.stat == UNCONSCIOUS)//Can't beat 'em while they're down.
to_chat(M, SPAN_WARNING("You can't box with [A], they're already down!"))
return 1
M.visible_message(SPAN_DANGER("[M] [boxing_verb] [A]!"))
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 102d8241754f..edbd831d9909 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -45,7 +45,7 @@
set name = "Adjust welding mask"
set src in usr
- if(usr.canmove && !usr.stat && !usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
if(up)
vision_impair = VISION_IMPAIR_MAX
flags_inventory |= COVEREYES|COVERMOUTH|BLOCKSHARPOBJ
diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm
index 76d61b4e3cc9..ffdda93f8a73 100644
--- a/code/modules/clothing/masks/breath.dm
+++ b/code/modules/clothing/masks/breath.dm
@@ -16,7 +16,7 @@
set name = "Adjust mask"
set src in usr
- if(usr.canmove && !usr.stat && !usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
if(!src.hanging)
src.hanging = !src.hanging
gas_transfer_coefficient = 1 //gas is now escaping to the turf and vice versa
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index a28a143f4ff0..5b97051852a6 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -385,7 +385,7 @@
set category = "Object"
set src in usr
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return 0
switch(icon_state)
diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm
index 278ffb666bfd..1c2fb2a9f29d 100644
--- a/code/modules/clothing/suits/labcoat.dm
+++ b/code/modules/clothing/suits/labcoat.dm
@@ -52,7 +52,7 @@
set category = "Object"
set src in usr
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return 0
if(src.buttoned == TRUE)
diff --git a/code/modules/clothing/suits/marine_armor.dm b/code/modules/clothing/suits/marine_armor.dm
index 94361c420d2b..af6a3f914252 100644
--- a/code/modules/clothing/suits/marine_armor.dm
+++ b/code/modules/clothing/suits/marine_armor.dm
@@ -626,7 +626,7 @@
set category = "Object"
set src in usr
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return 0
if(!injections)
@@ -901,11 +901,10 @@
COMSIG_MOB_DEATH,
COMSIG_HUMAN_EXTINGUISH
), PROC_REF(deactivate_camouflage))
- RegisterSignal(H, COMSIG_MOB_POST_UPDATE_CANMOVE, PROC_REF(fix_density))
camo_active = TRUE
H.alpha = full_camo_alpha
H.FF_hit_evade = 1000
- H.density = FALSE
+ ADD_TRAIT(H, TRAIT_UNDENSE, SPECIALIST_GEAR_TRAIT)
RegisterSignal(H, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(handle_mob_move_or_look))
@@ -930,7 +929,6 @@
COMSIG_MOB_FIRED_GUN,
COMSIG_MOB_FIRED_GUN_ATTACHMENT,
COMSIG_MOB_DEATH,
- COMSIG_MOB_POST_UPDATE_CANMOVE,
COMSIG_HUMAN_EXTINGUISH,
COMSIG_MOB_MOVE_OR_LOOK
))
@@ -938,9 +936,7 @@
camo_active = FALSE
animate(H, alpha = initial(H.alpha), flags = ANIMATION_END_NOW)
H.FF_hit_evade = initial(H.FF_hit_evade)
- if(!H.lying)
- H.density = TRUE
- H.update_canmove()
+ REMOVE_TRAIT(H, TRAIT_UNDENSE, SPECIALIST_GEAR_TRAIT)
var/datum/mob_hud/security/advanced/SA = huds[MOB_HUD_SECURITY_ADVANCED]
SA.add_to_hud(H)
@@ -960,11 +956,6 @@
addtimer(CALLBACK(src, PROC_REF(fade_out_finish), H), camouflage_break, TIMER_OVERRIDE|TIMER_UNIQUE)
animate(H, alpha = full_camo_alpha + 5, time = camouflage_break, easing = LINEAR_EASING, flags = ANIMATION_END_NOW)
-/obj/item/clothing/suit/storage/marine/ghillie/proc/fix_density(mob/user)
- SIGNAL_HANDLER
- if(camo_active)
- user.density = FALSE
-
/obj/item/clothing/suit/storage/marine/ghillie/proc/fade_out_finish(mob/living/carbon/human/H)
if(camo_active && H.wear_suit == src)
to_chat(H, SPAN_BOLDNOTICE("The smoke clears and your position is once again hidden completely!"))
@@ -990,7 +981,7 @@
/datum/action/item_action/specialist/prepare_position/can_use_action()
var/mob/living/carbon/human/H = owner
- if(istype(H) && !H.is_mob_incapacitated() && !H.lying && holder_item == H.wear_suit)
+ if(istype(H) && !H.is_mob_incapacitated() && H.body_position == STANDING_UP && holder_item == H.wear_suit)
return TRUE
/datum/action/item_action/specialist/prepare_position/action_activate()
diff --git a/code/modules/clothing/suits/marine_coat.dm b/code/modules/clothing/suits/marine_coat.dm
index 73d7e0981859..3aa43706c7d8 100644
--- a/code/modules/clothing/suits/marine_coat.dm
+++ b/code/modules/clothing/suits/marine_coat.dm
@@ -53,7 +53,7 @@
set category = "Object"
set src in usr
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return 0
if(src.buttoned == TRUE)
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 2a3cff05ee1e..b5859bb6f2d4 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -332,7 +332,7 @@
set category = "Object"
set src in usr
- if(!usr.canmove || usr.stat || usr.is_mob_restrained())
+ if(usr.is_mob_incapacitated())
return 0
if(src.icon_state == "suitjacket_blue_open")
diff --git a/code/modules/clothing/under/under.dm b/code/modules/clothing/under/under.dm
index f452628a1cb9..ec20ed6f6b1a 100644
--- a/code/modules/clothing/under/under.dm
+++ b/code/modules/clothing/under/under.dm
@@ -106,7 +106,7 @@
if ((flags_item & NODROP) || loc != usr)
return
- if (!usr.is_mob_incapacitated() && !(usr.buckled && usr.lying))
+ if (!usr.is_mob_incapacitated() && !(usr.buckled))
if(over_object)
switch(over_object.name)
if("r_hand")
diff --git a/code/modules/cm_aliens/XenoStructures.dm b/code/modules/cm_aliens/XenoStructures.dm
index 73ced8099427..a1d530e2e366 100644
--- a/code/modules/cm_aliens/XenoStructures.dm
+++ b/code/modules/cm_aliens/XenoStructures.dm
@@ -160,7 +160,8 @@
/obj/effect/alien/resin/sticky/Crossed(atom/movable/AM)
. = ..()
var/mob/living/carbon/human/H = AM
- if(istype(H) && !H.lying && !H.ally_of_hivenumber(hivenumber))
+ // Wait doesn't this stack slows if you get dragged over it? What's going on here?
+ if(istype(H) && !H.ally_of_hivenumber(hivenumber))
H.next_move_slowdown = H.next_move_slowdown + slow_amt
return .
var/mob/living/carbon/xenomorph/X = AM
@@ -560,7 +561,7 @@
return FALSE
burning_friendly = TRUE
- else if(current_mob.lying || current_mob.is_mob_incapacitated(TRUE))
+ else if(current_mob.body_position == LYING_DOWN || current_mob.is_mob_incapacitated(TRUE))
return FALSE
if(!burning_friendly && current_mob.health < 0)
diff --git a/code/modules/cm_aliens/structures/fruit.dm b/code/modules/cm_aliens/structures/fruit.dm
index 318bc6ba6cf2..09983c930031 100644
--- a/code/modules/cm_aliens/structures/fruit.dm
+++ b/code/modules/cm_aliens/structures/fruit.dm
@@ -442,7 +442,7 @@
/obj/effect/alien/resin/fruit/MouseDrop(atom/over_object)
var/mob/living/carbon/xenomorph/X = over_object
- if(!istype(X) || !Adjacent(X) || X != usr || X.is_mob_incapacitated() || X.lying) return ..()
+ if(!istype(X) || !Adjacent(X) || X != usr || X.is_mob_incapacitated() || X.body_position == LYING_DOWN) return ..()
X.pickup_fruit(src)
// Handles xenos picking up fruit
diff --git a/code/modules/cm_aliens/structures/trap.dm b/code/modules/cm_aliens/structures/trap.dm
index bc8eb7e6c7c0..d885e4d14a91 100644
--- a/code/modules/cm_aliens/structures/trap.dm
+++ b/code/modules/cm_aliens/structures/trap.dm
@@ -106,7 +106,7 @@
var/mob/living/carbon/human/H = AM
if(issynth(H) || isyautja(H))
return
- if(H.stat == DEAD || H.lying)
+ if(H.stat == DEAD || H.body_position == LYING_DOWN)
return
if(H.ally_of_hivenumber(hivenumber))
return
diff --git a/code/modules/cm_aliens/structures/tunnel.dm b/code/modules/cm_aliens/structures/tunnel.dm
index f716d69b5b7e..f08215fa432a 100644
--- a/code/modules/cm_aliens/structures/tunnel.dm
+++ b/code/modules/cm_aliens/structures/tunnel.dm
@@ -127,7 +127,7 @@
/obj/structure/tunnel/proc/pick_tunnel(mob/living/carbon/xenomorph/X)
. = FALSE //For peace of mind when it comes to dealing with unintended proc failures
- if(!istype(X) || X.stat || X.lying || !isfriendly(X) || !hive)
+ if(!istype(X) || X.is_mob_incapacitated(TRUE) || !isfriendly(X) || !hive)
return FALSE
if(X in contents)
var/list/tunnels = list()
@@ -195,7 +195,7 @@
. = attack_alien(M)
/obj/structure/tunnel/attack_alien(mob/living/carbon/xenomorph/M)
- if(!istype(M) || M.stat || M.lying)
+ if(!istype(M) || M.is_mob_incapacitated(TRUE))
return XENO_NO_DELAY_ACTION
if(!isfriendly(M))
diff --git a/code/modules/cm_marines/Donator_Items.dm b/code/modules/cm_marines/Donator_Items.dm
index e8eb3f75ae60..6d2f46490d13 100644
--- a/code/modules/cm_marines/Donator_Items.dm
+++ b/code/modules/cm_marines/Donator_Items.dm
@@ -23,7 +23,7 @@
set src in usr
if(!ishuman(usr)) return
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !usr.loc || !isturf(usr.loc))
+ if(usr.is_mob_incapacitated() || !isturf(usr.loc))
to_chat(usr, SPAN_WARNING("Not right now!"))
return
@@ -35,7 +35,7 @@
set src in usr
if(!ishuman(usr)) return
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !usr.loc || !isturf(usr.loc))
+ if(usr.is_mob_incapacitated() || !isturf(usr.loc))
to_chat(usr, SPAN_WARNING("Not right now!"))
return
@@ -91,7 +91,7 @@
set src in usr
if(!ishuman(usr)) return
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !usr.loc || !isturf(usr.loc))
+ if(usr.is_mob_incapacitated() || !isturf(usr.loc))
to_chat(usr, SPAN_WARNING("Not right now!"))
return
@@ -103,7 +103,7 @@
set src in usr
if(!ishuman(usr)) return
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !usr.loc || !isturf(usr.loc))
+ if(usr.is_mob_incapacitated() || !isturf(usr.loc))
to_chat(usr, SPAN_WARNING("Not right now!"))
return
diff --git a/code/modules/cm_marines/m2c.dm b/code/modules/cm_marines/m2c.dm
index a0943bb7f0a6..ff16c924cddc 100644
--- a/code/modules/cm_marines/m2c.dm
+++ b/code/modules/cm_marines/m2c.dm
@@ -445,7 +445,7 @@
//ATTACK WITH BOTH HANDS COMBO
-/obj/structure/machinery/m56d_hmg/auto/attack_hand(mob/user)
+/obj/structure/machinery/m56d_hmg/auto/attack_hand(mob/living/user)
..()
var/turf/user_turf = get_turf(user)
@@ -466,7 +466,7 @@
return
if(user.get_active_hand() == null && user.get_inactive_hand() == null)
- user.freeze()
+ ADD_TRAIT(user, TRAIT_IMMOBILIZED, INTERACTION_TRAIT)
user.set_interaction(src)
give_action(user, /datum/action/human_action/mg_exit)
else
@@ -515,16 +515,13 @@
..()
ADD_TRAIT(user, TRAIT_OVERRIDE_CLICKDRAG, TRAIT_SOURCE_WEAPON)
RegisterSignal(user, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(disable_interaction))
- RegisterSignal(user, COMSIG_MOB_POST_UPDATE_CANMOVE, PROC_REF(disable_canmove_interaction))
+ RegisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(body_position_changed))
// DISMOUNT THE MG
/obj/structure/machinery/m56d_hmg/auto/on_unset_interaction(mob/user)
REMOVE_TRAIT(user, TRAIT_OVERRIDE_CLICKDRAG, TRAIT_SOURCE_WEAPON)
- UnregisterSignal(user, list(
- COMSIG_MOVABLE_PRE_MOVE,
- COMSIG_MOB_POST_UPDATE_CANMOVE
- ))
+ UnregisterSignal(user, COMSIG_MOVABLE_PRE_MOVE)
..()
// GET ANIMATED
@@ -598,16 +595,16 @@
to_chat(user, SPAN_NOTICE("You rotate [src], using the tripod to support your pivoting movement."))
-/obj/structure/machinery/m56d_hmg/auto/proc/disable_interaction(mob/user, NewLoc, direction)
+/obj/structure/machinery/m56d_hmg/auto/proc/disable_interaction(mob/living/user, NewLoc, direction)
SIGNAL_HANDLER
- if(user.lying || get_dist(user,src) > 0 || user.is_mob_incapacitated() || !user.client)
+ if(user.body_position != STANDING_UP || get_dist(user,src) > 0 || user.is_mob_incapacitated() || !user.client)
user.unset_interaction()
-/obj/structure/machinery/m56d_hmg/auto/proc/disable_canmove_interaction(mob/user, canmove, laid_down, lying)
+/obj/structure/machinery/m56d_hmg/auto/proc/body_position_changed(mob/living/user, body_position, old_body_position)
SIGNAL_HANDLER
- if(laid_down)
+ if(body_position != STANDING_UP)
user.unset_interaction()
/obj/structure/machinery/m56d_hmg/auto/proc/handle_rotating_gun(mob/user)
diff --git a/code/modules/cm_marines/marines_consoles.dm b/code/modules/cm_marines/marines_consoles.dm
index a3bea392c201..734972ac7bab 100644
--- a/code/modules/cm_marines/marines_consoles.dm
+++ b/code/modules/cm_marines/marines_consoles.dm
@@ -432,7 +432,7 @@
set name = "Eject ID Card"
set src in oview(1)
- if(!usr || usr.stat || usr.lying) return
+ if(!usr || usr.is_mob_incapacitated()) return
if(user_id_card)
user_id_card.loc = get_turf(src)
@@ -498,7 +498,7 @@
set name = "Eject ID Card"
set src in view(1)
- if(!usr || usr.stat || usr.lying) return
+ if(!usr || usr.is_mob_incapacitated()) return
if(ishuman(usr) && ID_to_modify)
to_chat(usr, "You remove \the [ID_to_modify] from \the [src].")
diff --git a/code/modules/cm_marines/orbital_cannon.dm b/code/modules/cm_marines/orbital_cannon.dm
index 1d49c42f5e0d..b51c5b8b11cb 100644
--- a/code/modules/cm_marines/orbital_cannon.dm
+++ b/code/modules/cm_marines/orbital_cannon.dm
@@ -424,7 +424,7 @@ var/list/ob_type_fuel_requirements
shake_camera(user, 3, total_shake_factor, shake_frequency)
user.KnockDown(rand(max_knockdown_time * distance_percent, (max_knockdown_time * distance_percent + 1)))
- if(!user.knocked_down)
+ if(HAS_TRAIT(user, TRAIT_FLOORED))
continue
to_chat(user, SPAN_WARNING("You are thrown off balance and fall to the ground!"))
diff --git a/code/modules/cm_marines/smartgun_mount.dm b/code/modules/cm_marines/smartgun_mount.dm
index 5fa83d1fa06b..7b17af1cd514 100644
--- a/code/modules/cm_marines/smartgun_mount.dm
+++ b/code/modules/cm_marines/smartgun_mount.dm
@@ -830,7 +830,7 @@
to_chat(user, SPAN_WARNING("You aren't allowed to use firearms!"))
return
else
- user.freeze()
+ ADD_TRAIT(user, TRAIT_IMMOBILIZED, INTERACTION_TRAIT)
user.set_interaction(src)
give_action(user, /datum/action/human_action/mg_exit)
@@ -838,7 +838,7 @@
to_chat(usr, SPAN_NOTICE("You are too far from the handles to man [src]!"))
/obj/structure/machinery/m56d_hmg/on_set_interaction(mob/user)
- RegisterSignal(user, list(COMSIG_MOB_MG_EXIT, COMSIG_MOB_RESISTED, COMSIG_MOB_DEATH, COMSIG_MOB_KNOCKED_DOWN), PROC_REF(exit_interaction))
+ RegisterSignal(user, list(COMSIG_MOB_MG_EXIT, COMSIG_MOB_RESISTED, COMSIG_MOB_DEATH, COMSIG_LIVING_SET_BODY_POSITION), PROC_REF(exit_interaction))
flags_atom |= RELAY_CLICK
user.status_flags |= IMMOBILE_ACTION
user.visible_message(SPAN_NOTICE("[user] mans \the [src]."),SPAN_NOTICE("You man \the [src], locked and loaded!"))
@@ -853,11 +853,11 @@
update_pixels(user)
operator = user
-/obj/structure/machinery/m56d_hmg/on_unset_interaction(mob/user)
+/obj/structure/machinery/m56d_hmg/on_unset_interaction(mob/living/user)
flags_atom &= ~RELAY_CLICK
user.status_flags &= ~IMMOBILE_ACTION
user.visible_message(SPAN_NOTICE("[user] lets go of \the [src]."),SPAN_NOTICE("You let go of \the [src], letting the gun rest."))
- user.unfreeze()
+ REMOVE_TRAIT(user, TRAIT_IMMOBILIZED, INTERACTION_TRAIT)
UnregisterSignal(user, list(COMSIG_MOB_MOUSEUP, COMSIG_MOB_MOUSEDOWN, COMSIG_MOB_MOUSEDRAG))
user.reset_view(null)
user.remove_temp_pass_flags(PASS_MOB_THRU) // this is necessary because being knocked over while using the gun makes you incorporeal
@@ -873,7 +873,7 @@
COMSIG_MOB_MG_EXIT,
COMSIG_MOB_RESISTED,
COMSIG_MOB_DEATH,
- COMSIG_MOB_KNOCKED_DOWN,
+ COMSIG_LIVING_SET_BODY_POSITION,
))
@@ -913,8 +913,8 @@
user.client.pixel_y = 0
animate(user, pixel_x=user_old_x, pixel_y=user_old_y, 4, 1)
-/obj/structure/machinery/m56d_hmg/check_eye(mob/user)
- if(user.lying || get_dist(user,src) > 0 || user.is_mob_incapacitated() || !user.client)
+/obj/structure/machinery/m56d_hmg/check_eye(mob/living/user)
+ if(user.body_position != STANDING_UP || get_dist(user,src) > 0 || user.is_mob_incapacitated() || !user.client)
user.unset_interaction()
/obj/structure/machinery/m56d_hmg/clicked(mob/user, list/mods)
diff --git a/code/modules/cm_preds/thrall_procs.dm b/code/modules/cm_preds/thrall_procs.dm
index 50a2800ef855..120150ab86d5 100644
--- a/code/modules/cm_preds/thrall_procs.dm
+++ b/code/modules/cm_preds/thrall_procs.dm
@@ -14,7 +14,7 @@
to_chat(wearer, SPAN_WARNING("You've already claimed your equipment."))
return
- if(wearer.is_mob_incapacitated() || wearer.lying || wearer.buckled)
+ if(wearer.is_mob_incapacitated() || wearer.body_position == LYING_DOWN /* replace by mobility_flags */ || wearer.buckled)
to_chat(wearer, SPAN_WARNING("You're not able to do that right now."))
return
diff --git a/code/modules/cm_preds/yaut_bracers.dm b/code/modules/cm_preds/yaut_bracers.dm
index c10d148a2136..32b1aef81e07 100644
--- a/code/modules/cm_preds/yaut_bracers.dm
+++ b/code/modules/cm_preds/yaut_bracers.dm
@@ -106,6 +106,7 @@
/// handles decloaking only on HUNTER gloves
/obj/item/clothing/gloves/yautja/proc/decloak()
+ SIGNAL_HANDLER
return
/// Called to update the minimap icon of the predator
@@ -407,7 +408,7 @@
. = wristblades_internal(usr, FALSE)
/obj/item/clothing/gloves/yautja/hunter/proc/wristblades_internal(mob/living/carbon/human/caller, forced = FALSE)
- if(!caller.loc || !caller.canmove || caller.stat || !ishuman(caller))
+ if(!caller.loc || caller.is_mob_incapacitated() || !ishuman(caller))
return
. = check_random_function(caller, forced)
@@ -577,6 +578,7 @@
RegisterSignal(M, COMSIG_HUMAN_EXTINGUISH, PROC_REF(wrapper_fizzle_camouflage))
RegisterSignal(M, COMSIG_HUMAN_PRE_BULLET_ACT, PROC_REF(bullet_hit))
+ RegisterSignal(M, COMSIG_MOB_EFFECT_CLOAK_CANCEL, PROC_REF(decloak))
cloak_timer = world.time + 1.5 SECONDS
if(true_cloak)
@@ -614,6 +616,7 @@
UnregisterSignal(user, COMSIG_HUMAN_EXTINGUISH)
UnregisterSignal(user, COMSIG_HUMAN_PRE_BULLET_ACT)
+ UnregisterSignal(user, COMSIG_MOB_EFFECT_CLOAK_CANCEL)
var/decloak_timer = (DECLOAK_STANDARD * force_multipler)
if(forced)
@@ -645,7 +648,7 @@
. = caster_internal(usr, FALSE)
/obj/item/clothing/gloves/yautja/hunter/proc/caster_internal(mob/living/carbon/human/caller, forced = FALSE)
- if(!caller.loc || !caller.canmove || caller.stat || !ishuman(caller))
+ if(!caller.loc || caller.is_mob_incapacitated() || !ishuman(caller))
return
. = check_random_function(caller, forced)
diff --git a/code/modules/cm_preds/yaut_items.dm b/code/modules/cm_preds/yaut_items.dm
index c86a3fdd23e2..a648f2392d47 100644
--- a/code/modules/cm_preds/yaut_items.dm
+++ b/code/modules/cm_preds/yaut_items.dm
@@ -430,12 +430,12 @@
if(do_after(user, 10 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC))
// Display fancy animation for you and the person you might be pulling (Legacy)
- REMOVE_TRAIT_ALLSOURCES(user, TRAIT_CLOAKED)
+ SEND_SIGNAL(user, COMSIG_MOB_EFFECT_CLOAK_CANCEL)
user.visible_message(SPAN_WARNING("[icon2html(user, viewers(src))][user] disappears!"))
var/tele_time = animation_teleport_quick_out(user)
var/mob/living/M = user.pulling
if(istype(M)) // Pulled person
- REMOVE_TRAIT_ALLSOURCES(M, TRAIT_CLOAKED)
+ SEND_SIGNAL(M, COMSIG_MOB_EFFECT_CLOAK_CANCEL)
M.visible_message(SPAN_WARNING("[icon2html(M, viewers(src))][M] disappears!"))
animation_teleport_quick_out(M)
diff --git a/code/modules/cm_preds/yaut_procs.dm b/code/modules/cm_preds/yaut_procs.dm
index 32d532da72a0..9c99ff9c0c67 100644
--- a/code/modules/cm_preds/yaut_procs.dm
+++ b/code/modules/cm_preds/yaut_procs.dm
@@ -48,7 +48,7 @@
set name = "Butcher"
set desc = "Butcher a corpse you're standing on for its tasty meats."
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || body_position || buckled)
return
var/list/choices = list()
@@ -77,7 +77,7 @@
to_chat(src, SPAN_WARNING("This tiny worm is not even worth using your tools on."))
return
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || body_position || buckled)
return
if(issynth(T))
@@ -236,7 +236,7 @@
to_chat(src, SPAN_WARNING("You've already claimed your equipment."))
return
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || body_position || buckled)
to_chat(src, SPAN_WARNING("You're not able to do that right now."))
return
diff --git a/code/modules/cm_tech/hologram.dm b/code/modules/cm_tech/hologram.dm
index 5c0e986f45b2..3509c0a73a7d 100644
--- a/code/modules/cm_tech/hologram.dm
+++ b/code/modules/cm_tech/hologram.dm
@@ -5,7 +5,6 @@ GLOBAL_LIST_EMPTY_TYPED(hologram_list, /mob/hologram)
desc = "It seems to be a visual projection of someone" //jinkies!
icon = 'icons/mob/mob.dmi'
icon_state = "hologram"
- canmove = TRUE
blinded = FALSE
invisibility = INVISIBILITY_OBSERVER
diff --git a/code/modules/defenses/defenses.dm b/code/modules/defenses/defenses.dm
index d2c5e63fee29..5be308b9579c 100644
--- a/code/modules/defenses/defenses.dm
+++ b/code/modules/defenses/defenses.dm
@@ -408,9 +408,9 @@
damaged_action(damage)
if(stat == DEFENSE_DAMAGED)
- density = FALSE
+ set_density(FALSE)
else
- density = initial(density)
+ set_density(initial(density))
update_icon()
diff --git a/code/modules/desert_dam/filtration/filtration.dm b/code/modules/desert_dam/filtration/filtration.dm
index 6c079f3dcd60..a0fd1b2933be 100644
--- a/code/modules/desert_dam/filtration/filtration.dm
+++ b/code/modules/desert_dam/filtration/filtration.dm
@@ -198,7 +198,7 @@ var/global/east_riverstart = 0
M.apply_damage(0.5,BURN)
else
var/dam_amount = 3
- if(M.lying)
+ if(M.body_position == LYING_DOWN)
M.apply_damage(dam_amount,BURN)
M.apply_damage(dam_amount,BURN)
M.apply_damage(dam_amount,BURN)
diff --git a/code/modules/desert_dam/motion_sensor/sensortower.dm b/code/modules/desert_dam/motion_sensor/sensortower.dm
index 5783d0ce9f20..f9554cee2488 100644
--- a/code/modules/desert_dam/motion_sensor/sensortower.dm
+++ b/code/modules/desert_dam/motion_sensor/sensortower.dm
@@ -211,7 +211,7 @@
if(do_after(M, 40, INTERRUPT_ALL, BUSY_ICON_HOSTILE))
if(M.loc != cur_loc)
return XENO_NO_DELAY_ACTION //Make sure we're still there
- if(M.lying)
+ if(M.is_mob_incapacitated())
return XENO_NO_DELAY_ACTION
if(buildstate == SENSORTOWER_BUILDSTATE_BLOWTORCH)
return XENO_NO_DELAY_ACTION
diff --git a/code/modules/droppod/container_droppod.dm b/code/modules/droppod/container_droppod.dm
index 270f15011c5c..a9432933fa90 100644
--- a/code/modules/droppod/container_droppod.dm
+++ b/code/modules/droppod/container_droppod.dm
@@ -126,7 +126,7 @@
. = ..()
if(loc)
collect_objects(loc.contents)
- density = TRUE
+ set_density(TRUE)
/obj/structure/droppod/container/proc/collect_objects(list/L)
for(var/atom/movable/A in L)
diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm
index 2e9142dcef91..b166f9a4961d 100644
--- a/code/modules/economy/ATM.dm
+++ b/code/modules/economy/ATM.dm
@@ -465,7 +465,7 @@ log transactions
set name = "Eject ID Card"
set src in view(1)
- if(!usr || usr.stat || usr.lying) return
+ if(!usr || usr.is_mob_incapacitated()) return
if(ishuman(usr) && held_card)
to_chat(usr, "You remove \the [held_card] from \the [src].")
diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm
index 9503eee267e0..e62ad15a649e 100644
--- a/code/modules/flufftext/Dreaming.dm
+++ b/code/modules/flufftext/Dreaming.dm
@@ -21,7 +21,7 @@
for(var/i = rand(1,4),i > 0, i--)
to_chat(src, SPAN_NOTICE("... [pick(POSSIBLE_DREAM_TOPICS)] ..."))
sleep(rand(40,70))
- if(knocked_out <= 0)
+ if(!stat)
dreaming = 0
return
dreaming = 0
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index c7b1d65c7da2..1f8dcb2f81c7 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -351,7 +351,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/device/aicard,\
var/clone_weapon = null
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(H.stat || H.lying) continue
+ if(H.stat) continue
// possible_clones += H
clone = H
break //changed the code a bit. Less randomised, but less work to do. Should be ok, world.contents aren't stored in any particular order.
diff --git a/code/modules/gear_presets/corpses.dm b/code/modules/gear_presets/corpses.dm
index b66f3b236e3b..031ebcfa615e 100644
--- a/code/modules/gear_presets/corpses.dm
+++ b/code/modules/gear_presets/corpses.dm
@@ -39,7 +39,6 @@
if(nest)
new_human.buckled = nest
new_human.setDir(nest.dir)
- new_human.update_canmove()
nest.buckled_mob = new_human
nest.afterbuckle(new_human)
new_human.spawned_corpse = TRUE
diff --git a/code/modules/hydroponics/vines.dm b/code/modules/hydroponics/vines.dm
index 14091a1d29bb..0b7987e82bad 100644
--- a/code/modules/hydroponics/vines.dm
+++ b/code/modules/hydroponics/vines.dm
@@ -124,7 +124,6 @@
if(V && (V.stat != DEAD) && (V.buckled != src)) // If mob exists and is not dead or captured.
V.buckled = src
V.forceMove(src.loc)
- V.update_canmove()
src.buckled_mob = V
to_chat(V, SPAN_DANGER("The vines [pick("wind", "tangle", "tighten")] around you!"))
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 4d06d1e07142..8b95e4217266 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -25,7 +25,6 @@
icon = 'icons/mob/mob.dmi'
icon_state = "ghost"
density = FALSE
- canmove = TRUE
blinded = FALSE
anchored = TRUE // don't get pushed around
invisibility = INVISIBILITY_OBSERVER
@@ -80,6 +79,9 @@
GLOB.observer_list += src
+ // Ghosts don't move, they teleport via a special case in mob code
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_INHERENT)
+
var/turf/spawn_turf
if(ismob(body))
spawn_turf = get_turf(body) //Where is the body located?
diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm
index 6c825ec50994..115e78fa7f58 100644
--- a/code/modules/mob/death.dm
+++ b/code/modules/mob/death.dm
@@ -57,8 +57,6 @@
set_stat(DEAD)
- update_canmove()
-
dizziness = 0
jitteriness = 0
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 933e9490d39e..de2969259cf0 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -29,8 +29,6 @@
//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)
- if(lying)
- return FALSE
if(!istype(W))
return FALSE
if(!l_hand)
@@ -48,8 +46,6 @@
//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)
- if(lying)
- return FALSE
if(!istype(W))
return FALSE
if(!r_hand)
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index 60fe422c0e4b..d9480fab4c49 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -41,15 +41,6 @@
return 1
return ..()
-
-/mob/living/brain/update_canmove()
- canmove = FALSE
- return canmove
-
-
-
-
-
/mob/living/brain/update_sight()
if (stat == DEAD)
sight |= SEE_TURFS
diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm
index c085f06b0052..2c9c99736867 100644
--- a/code/modules/mob/living/brain/life.dm
+++ b/code/modules/mob/living/brain/life.dm
@@ -18,7 +18,6 @@
//Status updates, death etc.
handle_regular_status_updates()
- update_canmove()
if(client)
handle_regular_hud_updates()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index a4eb3b99a13a..f5247c52264c 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -74,7 +74,7 @@
/mob/living/carbon/ex_act(severity, direction, datum/cause_data/cause_data)
- if(lying)
+ if(body_position == LYING_DOWN)
severity *= EXPLOSION_PRONE_MULTIPLIER
if(severity >= 30)
@@ -265,12 +265,11 @@
t_him = "him"
else if(gender == FEMALE)
t_him = "her"
- if(lying || sleeping)
+ if(body_position || sleeping)
if(client)
sleeping = max(0,sleeping-5)
if(sleeping == 0)
resting = 0
- update_canmove()
M.visible_message(SPAN_NOTICE("[M] shakes [src] trying to wake [t_him] up!"), \
SPAN_NOTICE("You shake [src] trying to wake [t_him] up!"), null, 4)
else
@@ -452,19 +451,19 @@
/mob/living/carbon/slip(slip_source_name, stun_level, weaken_level, run_only, override_noslip, slide_steps)
set waitfor = 0
if(buckled) return FALSE //can't slip while buckled
- if(lying) return FALSE //can't slip if already lying down.
+ if(body_position != STANDING_UP) return FALSE //can't slip if already lying down.
stop_pulling()
to_chat(src, SPAN_WARNING("You slipped on \the [slip_source_name? slip_source_name : "floor"]!"))
playsound(src.loc, 'sound/misc/slip.ogg', 25, 1)
apply_effect(stun_level, STUN)
apply_effect(weaken_level, WEAKEN)
. = TRUE
- if(slide_steps && lying)//lying check to make sure we downed the mob
+ if(slide_steps && body_position)//lying check to make sure we downed the mob
var/slide_dir = dir
for(var/i=1, i<=slide_steps, i++)
step(src, slide_dir)
sleep(2)
- if(!lying)
+ if(!body_position)
break
@@ -518,3 +517,17 @@
. += SPAN_GREEN("[src] was thralled by [src.hunter_data.thralled_set.real_name] for '[src.hunter_data.thralled_reason]'.")
else if(src.hunter_data.gear)
. += SPAN_RED("[src] was marked as carrying gear by [src.hunter_data.gear_set].")
+
+
+/mob/living/carbon/on_lying_down(new_lying_angle)
+ . = ..()
+ if(!buckled || buckled.buckle_lying != 0)
+ lying_angle_on_lying_down(new_lying_angle)
+
+
+/// Special carbon interaction on lying down, to transform its sprite by a rotation.
+/mob/living/carbon/proc/lying_angle_on_lying_down(new_lying_angle)
+ if(!new_lying_angle)
+ set_lying_angle(pick(90, 270))
+ else
+ set_lying_angle(new_lying_angle)
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 5cac9db53cc6..6ff2a96b72f0 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -1,5 +1,6 @@
/mob/living/carbon
gender = MALE
+ mobility_flags = MOBILITY_FLAGS_CARBON_DEFAULT
var/list/stomach_contents = list()
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm
index c493559ff0d8..3f88d6beccb1 100644
--- a/code/modules/mob/living/carbon/give.dm
+++ b/code/modules/mob/living/carbon/give.dm
@@ -28,7 +28,7 @@
I = giver.r_hand
if(!istype(I) || (I.flags_item & (DELONDROP|NODROP|ITEM_ABSTRACT)))
return
- if(lying)
+ if(body_position == LYING_DOWN) // replace by mobiilty_flags probably
to_chat(giver, SPAN_WARNING("[src] can't hold that while lying down."))
return
if(r_hand && l_hand)
@@ -47,7 +47,7 @@
to_chat(giver, SPAN_WARNING("You need to keep the item in your active hand."))
to_chat(src, SPAN_WARNING("[giver] seem to have given up on giving [I] to you."))
return
- if(lying)
+ if(body_position == LYING_DOWN)
to_chat(src, SPAN_WARNING("You can't hold that while lying down."))
to_chat(giver, SPAN_WARNING("[src] can't hold that while lying down."))
return
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index c9092ed479b9..ab7db57c54e1 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -129,7 +129,7 @@
. += "Evacuation: [eta_status]"
/mob/living/carbon/human/ex_act(severity, direction, datum/cause_data/cause_data)
- if(lying)
+ if(body_position == LYING_DOWN)
severity *= EXPLOSION_PRONE_MULTIPLIER
@@ -1047,7 +1047,7 @@
/mob/living/carbon/human/proc/handle_embedded_objects()
- if((stat == DEAD) || lying || buckled) // Shouldnt be needed, but better safe than sorry
+ if((stat == DEAD) || body_position || buckled) // Shouldnt be needed, but better safe than sorry
return
for(var/obj/item/W in embedded_items)
diff --git a/code/modules/mob/living/carbon/human/human_abilities.dm b/code/modules/mob/living/carbon/human/human_abilities.dm
index fda4cea20ad1..75aa0de09a06 100644
--- a/code/modules/mob/living/carbon/human/human_abilities.dm
+++ b/code/modules/mob/living/carbon/human/human_abilities.dm
@@ -455,22 +455,20 @@ CULT
return
to_chat(chosen, SPAN_HIGHDANGER("You feel a dangerous presence in the back of your head. You find yourself unable to move!"))
-
- chosen.frozen = TRUE
- chosen.update_canmove()
+ ADD_TRAIT(chosen, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Cultist Stun"))
chosen.update_xeno_hostile_hud()
if(!do_after(H, 2 SECONDS, INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE, chosen, INTERRUPT_ALL, BUSY_ICON_HOSTILE))
to_chat(H, SPAN_XENOMINORWARNING("You decide not to stun [chosen]."))
- unroot_human(chosen)
+ unroot_human(chosen, TRAIT_SOURCE_ABILITY("Cultist Stun"))
enter_cooldown(5 SECONDS)
return
enter_cooldown()
- unroot_human(chosen)
+ unroot_human(chosen, TRAIT_SOURCE_ABILITY("Cultist Stun"))
chosen.apply_effect(10, PARALYZE)
chosen.make_jittery(105)
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 805b3d7e1744..2bb113d67739 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -206,12 +206,11 @@
w_uniform.add_fingerprint(M)
- if(lying || sleeping)
+ if(body_position == LYING_DOWN || sleeping)
if(client)
sleeping = max(0,src.sleeping-5)
if(!sleeping)
- resting = 0
- update_canmove()
+ set_resting(FALSE)
M.visible_message(SPAN_NOTICE("[M] shakes [src] trying to wake [t_him] up!"), \
SPAN_NOTICE("You shake [src] trying to wake [t_him] up!"), null, 4)
else if(stunned)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index a8734afd7301..ede57d64241b 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -378,16 +378,6 @@ Contains most of the procs that are called when a mob is attacked by something
var/list/overlap = compare_group & access_to_check
return length(overlap)
-/mob/living/carbon/human/freeze()
- . = ..()
- if(.)
- update_xeno_hostile_hud()
-
-/mob/living/carbon/human/unfreeze()
- . = ..()
- if(.)
- update_xeno_hostile_hud()
-
/mob/living/carbon/human/get_target_lock(access_to_check)
if(isnull(access_to_check))
return
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 4416ba74fda3..cd6abd2262e0 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,5 +1,6 @@
/mob/living/carbon/human
light_system = MOVABLE_LIGHT
+ rotate_on_lying = TRUE
//Hair color and style
var/r_hair = 0
var/g_hair = 0
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 7f36df8ceae2..08ddd11da5b3 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -219,18 +219,9 @@
return 0
-
-/mob/living/carbon/human/has_legs()
- . = 0
- if(has_limb("r_foot") && has_limb("r_leg"))
- .++
- if(has_limb("l_foot") && has_limb("l_leg"))
- .++
-
/mob/living/carbon/human/proc/disable_special_flags()
status_flags |= CANPUSH
anchored = FALSE
- frozen = FALSE
/mob/living/carbon/human/proc/disable_special_items()
set waitfor = FALSE // Scout decloak animation uses sleep(), which is problematic for taser gun
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 1a906dfa5c11..f0ca5fe27f19 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -108,7 +108,7 @@
//Do we have a working jetpack
if(istype(back, /obj/item/tank/jetpack))
var/obj/item/tank/jetpack/J = back
- if(((!check_drift) || (check_drift && J.stabilization_on)) && (!lying) && (J.allow_thrust(0.01, src)))
+ if(((!check_drift) || (check_drift && J.stabilization_on)) && (body_position == STANDING_UP) && (J.allow_thrust(0.01, src)))
inertia_dir = 0
return 1
// if(!check_drift && J.allow_thrust(0.01, src))
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index fded3d5e3f77..be1c7833c5c1 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -82,8 +82,6 @@
//Status updates, death etc.
handle_regular_status_updates() //Optimized a bit
- update_canmove()
-
handle_regular_hud_updates()
pulse = handle_pulse()
diff --git a/code/modules/mob/living/carbon/human/life/handle_disabilities.dm b/code/modules/mob/living/carbon/human/life/handle_disabilities.dm
index 9ab234212108..77358ca45b89 100644
--- a/code/modules/mob/living/carbon/human/life/handle_disabilities.dm
+++ b/code/modules/mob/living/carbon/human/life/handle_disabilities.dm
@@ -3,7 +3,7 @@
/mob/living/carbon/human/proc/handle_disabilities()
if(disabilities & EPILEPSY)
- if((prob(1) && knocked_out < 1))
+ if(prob(1) && !HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
visible_message(SPAN_DANGER("\The [src] starts having a seizure!"), \
SPAN_DANGER("You start having a seizure!"), null, 5)
apply_effect(10, PARALYZE)
@@ -11,14 +11,14 @@
return
if(disabilities & COUGHING)
- if((prob(5) && knocked_out <= 1))
+ if(prob(5) && !HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
drop_held_item()
INVOKE_ASYNC(src, PROC_REF(emote), "cough")
return
if(disabilities & TOURETTES)
speech_problem_flag = TRUE
- if((prob(10) && knocked_out <= 1))
+ if((prob(10) && !HAS_TRAIT(src, TRAIT_KNOCKEDOUT)))
apply_effect(10, STUN)
spawn()
switch(rand(1, 3))
@@ -56,6 +56,6 @@
to_chat(src, SPAN_DANGER("Your hand won't respond properly, you drop what you're holding."))
drop_held_item()
if(10 to 12)
- if(getBrainLoss() >= 50 && !lying)
+ if(getBrainLoss() >= 50 && body_position == STANDING_UP)
to_chat(src, SPAN_DANGER("Your legs won't respond properly, you fall down."))
resting = 1
diff --git a/code/modules/mob/living/carbon/human/life/handle_organs.dm b/code/modules/mob/living/carbon/human/life/handle_organs.dm
index 2c978f2295ed..706e8567a50c 100644
--- a/code/modules/mob/living/carbon/human/life/handle_organs.dm
+++ b/code/modules/mob/living/carbon/human/life/handle_organs.dm
@@ -16,7 +16,7 @@
else
E.process()
- if(!lying && world.time - l_move_time < 15)
+ if(body_position == STANDING_UP && world.time - l_move_time < 15)
// Moving around with fractured ribs won't do you any good
if(E.is_broken() && E.internal_organs && prob(15))
var/datum/internal_organ/I = pick(E.internal_organs)
@@ -32,7 +32,7 @@
custom_pain("You feel broken bones cutting at you in your [E.display_name]!", 1)
pain.apply_pain(damage * 1.5)
- if(!lying && !buckled && prob(2))
+ if(body_position == STANDING_UP && !buckled && prob(2))
var/left_leg_crippled = FALSE
var/right_leg_crippled = FALSE
diff --git a/code/modules/mob/living/carbon/human/life/handle_regular_status_updates.dm b/code/modules/mob/living/carbon/human/life/handle_regular_status_updates.dm
index 5c951a8112bf..41554f056744 100644
--- a/code/modules/mob/living/carbon/human/life/handle_regular_status_updates.dm
+++ b/code/modules/mob/living/carbon/human/life/handle_regular_status_updates.dm
@@ -1,6 +1,6 @@
//Refer to life.dm for caller
-/mob/living/carbon/human/handle_regular_status_updates(regular_update = TRUE)
+/mob/living/carbon/human/handle_regular_status_updates(regular_update = TRUE) // you're next, evil proc --fira
if(status_flags & GODMODE)
return 0
@@ -53,9 +53,8 @@
if(!already_in_crit)
new /datum/effects/crit/human(src)
- if(knocked_out)
+ if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
blinded = TRUE
- set_stat(UNCONSCIOUS)
if(regular_update && halloss > 0)
apply_damage(-3, HALLOSS)
else if(sleeping)
diff --git a/code/modules/mob/living/carbon/human/life/handle_stasis_bag.dm b/code/modules/mob/living/carbon/human/life/handle_stasis_bag.dm
index 9d257da720b9..024235b78156 100644
--- a/code/modules/mob/living/carbon/human/life/handle_stasis_bag.dm
+++ b/code/modules/mob/living/carbon/human/life/handle_stasis_bag.dm
@@ -4,6 +4,7 @@
//Handle side effects from stasis
switch(in_stasis)
if(STASIS_IN_BAG)
+ // I hate whoever wrote this and statuses with a passion
knocked_down = knocked_down? --knocked_down : knocked_down + 10 //knocked_down set.
if(STASIS_IN_CRYO_CELL)
if(sleeping < 10) sleeping += 10 //Puts the mob to sleep indefinitely.
diff --git a/code/modules/mob/living/carbon/human/life/life_helpers.dm b/code/modules/mob/living/carbon/human/life/life_helpers.dm
index fedeaf9fd48c..25f020a9f8b6 100644
--- a/code/modules/mob/living/carbon/human/life/life_helpers.dm
+++ b/code/modules/mob/living/carbon/human/life/life_helpers.dm
@@ -25,33 +25,6 @@
pressure_adjustment_coefficient = min(1, max(pressure_adjustment_coefficient, 0)) //So it isn't less than 0 or larger than 1.
return pressure_adjustment_coefficient
-//Calculate how much of the enviroment pressure-difference affects the human.
-/mob/living/carbon/human/calculate_affecting_pressure(pressure)
- var/pressure_difference
-
- //First get the absolute pressure difference.
- if(pressure < ONE_ATMOSPHERE) //We are in an underpressure.
- pressure_difference = ONE_ATMOSPHERE - pressure
-
- else //We are in an overpressure or standard atmosphere.
- pressure_difference = pressure - ONE_ATMOSPHERE
-
- if(pressure_difference < 5) //If the difference is small, don't bother calculating the fraction.
- pressure_difference = 0
-
- else
- //Otherwise calculate how much of that absolute pressure difference affects us, can be 0 to 1 (equals 0% to 100%).
- //This is our relative difference.
- pressure_difference *= get_pressure_weakness()
-
- //The difference is always positive to avoid extra calculations.
- //Apply the relative difference on a standard atmosphere to get the final result.
- //The return value will be the adjusted_pressure of the human that is the basis of pressure warnings and damage.
- if(pressure < ONE_ATMOSPHERE)
- return ONE_ATMOSPHERE - pressure_difference
- else
- return ONE_ATMOSPHERE + pressure_difference
-
/mob/living/carbon/human/proc/stabilize_body_temperature()
@@ -320,9 +293,7 @@
emote("gasp")
regenerate_icons()
reload_fullscreens()
- update_canmove()
flash_eyes()
apply_effect(10, EYE_BLUR)
apply_effect(10, PARALYZE)
- update_canmove()
updatehealth() //One more time, so it doesn't show the target as dead on HUDs
diff --git a/code/modules/mob/living/carbon/human/powers/human_powers.dm b/code/modules/mob/living/carbon/human/powers/human_powers.dm
index 10b13225b314..188398ab5735 100644
--- a/code/modules/mob/living/carbon/human/powers/human_powers.dm
+++ b/code/modules/mob/living/carbon/human/powers/human_powers.dm
@@ -9,7 +9,7 @@
if(last_special > world.time)
return
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || buckled)
to_chat(src, "You cannot tackle someone in your current state.")
return
@@ -27,7 +27,7 @@
if(last_special > world.time)
return
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || buckled)
to_chat(src, "You cannot tackle in your current state.")
return
@@ -56,7 +56,7 @@
if(last_special > world.time)
return
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || body_position != STANDING_UP || buckled)
to_chat(src, "You cannot leap in your current state.")
return
@@ -74,7 +74,7 @@
if(last_special > world.time)
return
- if(is_mob_incapacitated() || lying || buckled)
+ if(is_mob_incapacitated() || body_position || buckled)
to_chat(src, "You cannot leap in your current state.")
return
@@ -110,7 +110,7 @@
if(last_special > world.time)
return
- if(is_mob_incapacitated(TRUE) || lying)
+ if(is_mob_incapacitated() || body_position)
to_chat(src, SPAN_DANGER("You cannot do that in your current state."))
return
@@ -193,13 +193,42 @@
/mob/living/verb/lay_down()
set name = "Rest"
set category = "IC"
+ set_resting(!resting, FALSE, TRUE)
- if(!resting)
- apply_effect(1, WEAKEN) //so that the mob immediately falls over
+///Proc to hook behavior to the change of value in the resting variable.
+/mob/living/proc/set_resting(new_resting, silent = TRUE, instant = FALSE)
+ if(!(mobility_flags & MOBILITY_REST))
+ return
+ if(new_resting == resting)
+ return
- resting = !resting
+ . = resting
+ resting = new_resting
+ if(new_resting)
+ if(body_position == LYING_DOWN)
+ if(!silent)
+ to_chat(src, SPAN_NOTICE("You will now try to stay lying down on the floor."))
+// else if(HAS_TRAIT(src, TRAIT_FORCED_STANDING) || (buckled && buckled.buckle_lying != NO_BUCKLE_LYING))
+// if(!silent)
+// to_chat(src, SPAN_NOTICE("You will now lay down as soon as you are able to."))
+ else
+ if(!silent)
+ to_chat(src, SPAN_NOTICE("You lay down."))
+ set_lying_down()
+ else
+ if(body_position == STANDING_UP)
+ if(!silent)
+ to_chat(src, SPAN_NOTICE("You will now try to remain standing up."))
+ else if(HAS_TRAIT(src, TRAIT_FLOORED) || (buckled && buckled.buckle_lying != NO_BUCKLE_LYING))
+ if(!silent)
+ to_chat(src, SPAN_NOTICE("You will now stand up as soon as you are able to."))
+ else
+ if(!silent)
+ to_chat(src, SPAN_NOTICE("You stand up."))
+ get_up(instant)
- to_chat(src, SPAN_NOTICE("You are now [resting ? "resting." : "getting up."]"))
+// SEND_SIGNAL(src, COMSIG_LIVING_RESTING, new_resting, silent, instant)
+// update_resting() // HUD icons
/mob/living/carbon/human/proc/toggle_inherent_nightvison()
set category = "Synthetic"
diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm
index 6c774432e776..4c10788992c7 100644
--- a/code/modules/mob/living/carbon/human/species/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/monkey.dm
@@ -46,7 +46,7 @@
/datum/species/monkey/handle_npc(mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
return
- if(prob(33) && isturf(H.loc) && !H.pulledby && !H.lying && !H.is_mob_restrained()) //won't move if being pulled
+ if(prob(33) && isturf(H.loc) && !H.pulledby && (H.mobility_flags & MOBILITY_MOVE) && !H.is_mob_restrained()) //won't move if being pulled
step(H, pick(cardinal))
var/obj/held = H.get_active_hand()
diff --git a/code/modules/mob/living/carbon/human/species/zombie.dm b/code/modules/mob/living/carbon/human/species/zombie.dm
index 5fa928a67f36..ef2d7ef415ff 100644
--- a/code/modules/mob/living/carbon/human/species/zombie.dm
+++ b/code/modules/mob/living/carbon/human/species/zombie.dm
@@ -53,8 +53,8 @@
if(zombie.glasses) zombie.drop_inv_item_on_ground(zombie.glasses, FALSE, TRUE)
if(zombie.wear_mask) zombie.drop_inv_item_on_ground(zombie.wear_mask, FALSE, TRUE)
- if(zombie.lying)
- zombie.lying = FALSE
+// if(zombie.lying)
+// zombie.lying = FALSE
var/obj/item/weapon/zombie_claws/ZC = new(zombie)
ZC.icon_state = "claw_r"
@@ -116,7 +116,7 @@
/datum/species/zombie/proc/revive_from_death(mob/living/carbon/human/zombie)
if(zombie && zombie.loc && zombie.stat == DEAD)
zombie.revive(TRUE)
- zombie.stunned = 4
+ zombie.apply_effect(4, STUN)
zombie.make_jittery(500)
zombie.visible_message(SPAN_WARNING("[zombie] rises from the ground!"))
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index fd9c786bd147..306fb2e70936 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -89,25 +89,6 @@ There are several things that need to be remembered:
overlays -= I
overlays_standing[cache_index] = null
-
-/mob/living/carbon/human/update_transform(force = FALSE)
- if(lying == lying_prev && !force)
- return
- lying_prev = lying
- var/matrix/new_matrix = matrix()
- if(lying)
- if(pulledby && pulledby.grab_level >= GRAB_CARRY)
- new_matrix.Turn(90)
- else
- if(prob(50))
- new_matrix.Turn(90)
- else
- new_matrix.Turn(270)
- new_matrix.Translate(rand(-10,10), rand(-10,10))
- apply_transform(new_matrix)
- else
- apply_transform(new_matrix)
-
/mob/living/carbon/human/UpdateDamageIcon()
for(var/obj/limb/O in limbs)
if(!(O.status & LIMB_DESTROYED))
@@ -131,6 +112,13 @@ There are several things that need to be remembered:
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body()
+ if((has_limb("r_foot") && has_limb("r_leg")) || (has_limb("l_foot") && has_limb("l_leg")))
+ // temporary crutch. i know this is in effect an icons proc, but this is literally "update_body" material.
+ // remove this when we can migrate it to signal based limb handling.
+ REMOVE_TRAIT(src, TRAIT_FLOORED, BODY_TRAIT)
+ else
+ ADD_TRAIT(src, TRAIT_FLOORED, BODY_TRAIT)
+
appearance_flags |= KEEP_TOGETHER // sanity
update_damage_overlays()
@@ -799,3 +787,11 @@ Applied by gun suicide and high impact bullet executions, removed by rejuvenate,
#undef FIRE_LAYER
#undef BURST_LAYER
+// Crutch so that immobilized Xeno HUD Icon shows properly. Try to find a better way if possible...
+/mob/living/carbon/human/on_immobilized_trait_gain(datum/source)
+ . = ..()
+ update_xeno_hostile_hud()
+
+/mob/living/carbon/human/on_immobilized_trait_loss(datum/source)
+ . = ..()
+ update_xeno_hostile_hud()
diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm
index cc76999358a2..bb706824b92a 100644
--- a/code/modules/mob/living/carbon/update_icons.dm
+++ b/code/modules/mob/living/carbon/update_icons.dm
@@ -6,6 +6,5 @@
return
/mob/living/carbon/update_transform()
- if(lying != lying_prev )
- lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
- update_icons()
+ . = ..()
+ update_icons()
diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm
index 2a3ff577a245..9c27b250b817 100644
--- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm
@@ -102,7 +102,7 @@
switch(stage)
if(2)
if(prob(4))
- if(affected_mob.knocked_out < 1)
+ if(!HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
affected_mob.pain.apply_pain(PAIN_CHESTBURST_WEAK)
affected_mob.visible_message(SPAN_DANGER("[affected_mob] starts shaking uncontrollably!"), \
SPAN_DANGER("You feel something moving inside you! You start shaking uncontrollably!"))
@@ -123,7 +123,7 @@
else if(prob(2))
affected_mob.emote("[pick("sneeze", "cough")]")
if(prob(5))
- if(affected_mob.knocked_out < 1)
+ if(!HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
affected_mob.pain.apply_pain(PAIN_CHESTBURST_WEAK)
affected_mob.visible_message(SPAN_DANGER("\The [affected_mob] starts shaking uncontrollably!"), \
SPAN_DANGER("You feel something moving inside you! You start shaking uncontrollably!"))
@@ -139,7 +139,7 @@
if(prob(50))
affected_mob.emote("scream")
if(prob(6))
- if(affected_mob.knocked_out < 1)
+ if(!HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
affected_mob.pain.apply_pain(PAIN_CHESTBURST_WEAK)
affected_mob.visible_message(SPAN_DANGER("[affected_mob] starts shaking uncontrollably!"), \
SPAN_DANGER("You feel something moving inside you! You start shaking uncontrollably!"))
@@ -295,7 +295,7 @@
return
victim.chestburst = TRUE
to_chat(src, SPAN_DANGER("You start bursting out of [victim]'s chest!"))
- if(victim.knocked_out < 1)
+ if(!HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
victim.apply_effect(20, DAZE)
victim.visible_message(SPAN_DANGER("\The [victim] starts shaking uncontrollably!"), \
SPAN_DANGER("You feel something ripping up your insides!"))
diff --git a/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm b/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm
index 65ae240e201d..5d019cc8195d 100644
--- a/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm
@@ -116,8 +116,8 @@
attack_hand(user)//Not a carrier, or already full? Just pick it up.
return XENO_NO_DELAY_ACTION
-/obj/item/clothing/mask/facehugger/attack(mob/M, mob/user)
- if(!can_hug(M, hivenumber) || !(M.is_mob_incapacitated() || M.lying || M.buckled && !isyautja(M)))
+/obj/item/clothing/mask/facehugger/attack(mob/living/M, mob/user)
+ if(!can_hug(M, hivenumber) || !(M.is_mob_incapacitated() || M.body_position == LYING_DOWN || M.buckled && !isyautja(M)))
to_chat(user, SPAN_WARNING("The facehugger refuses to attach."))
..()
return
@@ -130,7 +130,7 @@
if(!do_after(user, 2 SECONDS, INTERRUPT_ALL, BUSY_ICON_HOSTILE, M, INTERRUPT_MOVED, BUSY_ICON_HOSTILE))
return
- if(!can_hug(M, hivenumber) || !(M.is_mob_incapacitated() || M.lying || M.buckled))
+ if(!can_hug(M, hivenumber) || !(M.is_mob_incapacitated() || M.body_position || M.buckled))
return
attach(M)
@@ -525,7 +525,7 @@
var/catch_chance = 50
if(target.dir == reverse_dir[hugger.dir])
catch_chance += 20
- if(target.lying)
+ if(target.body_position == LYING_DOWN)
catch_chance -= 50
catch_chance -= ((target.maxHealth - target.health) / 3)
if(target.get_active_hand())
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
index 3fd8e53024d5..4c31437d0021 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
@@ -150,7 +150,7 @@
//A simple handler for checking your state. Used in pretty much all the procs.
/mob/living/carbon/xenomorph/proc/check_state(permissive = FALSE)
if(!permissive)
- if(is_mob_incapacitated() || lying || buckled || evolving || !isturf(loc))
+ if(is_mob_incapacitated() || body_position == LYING_DOWN || buckled || evolving || !isturf(loc))
to_chat(src, SPAN_WARNING("You cannot do this in your current state."))
return FALSE
else if(caste_type != XENO_CASTE_QUEEN && observed_xeno)
@@ -319,9 +319,8 @@
if (pounceAction.freeze_self)
if(pounceAction.freeze_play_sound)
playsound(loc, rand(0, 100) < 95 ? 'sound/voice/alien_pounce.ogg' : 'sound/voice/alien_pounce2.ogg', 25, 1)
- canmove = FALSE
- frozen = TRUE
- pounceAction.freeze_timer_id = addtimer(CALLBACK(src, PROC_REF(unfreeze)), pounceAction.freeze_time, TIMER_STOPPABLE)
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, POUNCED_TRAIT)
+ pounceAction.freeze_timer_id = addtimer(CALLBACK(src, PROC_REF(unfreeze_pounce)), pounceAction.freeze_time, TIMER_STOPPABLE)
pounceAction.additional_effects(M)
@@ -330,6 +329,9 @@
throwing = FALSE //Reset throwing since something was hit.
+/mob/living/carbon/xenomorph/proc/unfreeze_pounce()
+ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, POUNCED_TRAIT)
+
/mob/living/carbon/xenomorph/proc/pounced_mob_wrapper(mob/living/L)
pounced_mob(L)
@@ -626,7 +628,7 @@
if(!TC)
TC = new(tackle_min + tackle_min_offset, tackle_max + tackle_max_offset, tackle_chance*tackle_mult)
LAZYSET(tackle_counter, M, TC)
- RegisterSignal(M, COMSIG_MOB_KNOCKED_DOWN, PROC_REF(tackle_handle_lying_changed))
+ RegisterSignal(M, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(tackle_handle_lying_changed))
if (TC.tackle_reset_id)
deltimer(TC.tackle_reset_id)
@@ -638,8 +640,11 @@
else
reset_tackle(M)
-/mob/living/carbon/xenomorph/proc/tackle_handle_lying_changed(mob/M)
+/mob/living/carbon/xenomorph/proc/tackle_handle_lying_changed(mob/living/M, body_position)
SIGNAL_HANDLER
+ if(body_position != LYING_DOWN)
+ return
+
// Infected mobs do not have their tackle counter reset if
// they get knocked down or get up from a knockdown
if(M.status_flags & XENO_HOST)
@@ -652,7 +657,7 @@
if (TC)
qdel(TC)
LAZYREMOVE(tackle_counter, M)
- UnregisterSignal(M, COMSIG_MOB_KNOCKED_DOWN)
+ UnregisterSignal(M, COMSIG_LIVING_SET_BODY_POSITION)
/mob/living/carbon/xenomorph/burn_skin(burn_amount)
@@ -771,3 +776,6 @@
SSminimaps.remove_marker(src)
add_minimap_marker()
+
+/mob/living/carbon/xenomorph/lying_angle_on_lying_down(new_lying_angle)
+ return // Do not rotate xenos around on the floor, their sprite is already top-down'ish
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 90c22e19c483..c4c9363033a9 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -823,7 +823,7 @@
if(!new_hive)
return
- for(var/T in status_traits)
+ for(var/T in _status_traits) // Seriously you see this here? Don't do that. Please don't do it.
REMOVE_TRAIT(src, T, TRAIT_SOURCE_HIVE)
new_hive.add_xeno(src)
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm
index 705837699275..180f3f1126ae 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm
@@ -160,12 +160,11 @@
SPAN_XENOWARNING("You vomit globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!"), null, 5)
playsound(loc, "sound/bullets/acid_impact1.ogg", 25)
-/proc/unroot_human(mob/living/carbon/H)
+/proc/unroot_human(mob/living/carbon/H, trait_source)
if (!isxeno_human(H))
return
- H.frozen = 0
- H.update_canmove()
+ REMOVE_TRAIT(H, TRAIT_IMMOBILIZED, trait_source)
if(ishuman(H))
var/mob/living/carbon/human/T = H
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm
index 4d3aae33ae9c..49558ee83607 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/burrower/burrower_powers.dm
@@ -36,19 +36,16 @@
// TODO Make immune to all damage here.
to_chat(src, SPAN_XENOWARNING("You burrow yourself into the ground."))
burrow = TRUE
- frozen = TRUE
invisibility = 101
anchored = TRUE
- density = FALSE
if(caste.fire_immunity == FIRE_IMMUNITY_NONE)
RegisterSignal(src, COMSIG_LIVING_PREIGNITION, PROC_REF(fire_immune))
RegisterSignal(src, list(
COMSIG_LIVING_FLAMER_CROSSED,
COMSIG_LIVING_FLAMER_FLAMED,
), PROC_REF(flamer_crossed_immune))
- ADD_TRAIT(src, TRAIT_ABILITY_BURROWED, TRAIT_SOURCE_ABILITY("Burrow"))
+ add_traits(list(TRAIT_ABILITY_BURROWED, TRAIT_UNDENSE, TRAIT_IMMOBILIZED), TRAIT_SOURCE_ABILITY("Burrow"))
playsound(src.loc, 'sound/effects/burrowing_b.ogg', 25)
- update_canmove()
update_icons()
addtimer(CALLBACK(src, PROC_REF(do_burrow_cooldown)), (caste ? caste.burrow_cooldown : 5 SECONDS))
burrow_timer = world.time + 90 // How long we can be burrowed
@@ -75,18 +72,15 @@
COMSIG_LIVING_FLAMER_CROSSED,
COMSIG_LIVING_FLAMER_FLAMED,
))
- REMOVE_TRAIT(src, TRAIT_ABILITY_BURROWED, TRAIT_SOURCE_ABILITY("Burrow"))
- frozen = FALSE
+ remove_traits(list(TRAIT_ABILITY_BURROWED, TRAIT_UNDENSE, TRAIT_IMMOBILIZED), TRAIT_SOURCE_ABILITY("Burrow"))
invisibility = FALSE
anchored = FALSE
- density = TRUE
playsound(loc, 'sound/effects/burrowoff.ogg', 25)
for(var/mob/living/carbon/mob in loc)
if(!can_not_harm(mob))
mob.apply_effect(2, WEAKEN)
addtimer(CALLBACK(src, PROC_REF(do_burrow_cooldown)), (caste ? caste.burrow_cooldown : 5 SECONDS))
- update_canmove()
update_icons()
/mob/living/carbon/xenomorph/proc/do_burrow_cooldown()
@@ -166,9 +160,7 @@
/mob/living/carbon/xenomorph/proc/do_tunnel(turf/T)
to_chat(src, SPAN_NOTICE("You tunnel to your destination."))
anchored = FALSE
- unfreeze()
forceMove(T)
- UnregisterSignal(src, COMSIG_LIVING_FLAMER_FLAMED)
burrow_off()
/mob/living/carbon/xenomorph/proc/do_tunnel_cooldown()
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm
index 6405428de7cb..63051a94efa9 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm
@@ -120,6 +120,10 @@
var/momentum = 0
+/datum/action/xeno_action/onclick/charger_charge/proc/handle_position_change(mob/living/carbon/xenomorph/xeno, body_position)
+ SIGNAL_HANDLER
+ if(body_position == LYING_DOWN)
+ handle_movement(xeno)
/datum/action/xeno_action/onclick/charger_charge/proc/handle_movement(mob/living/carbon/xenomorph/Xeno, atom/oldloc, dir, forced)
SIGNAL_HANDLER
@@ -178,7 +182,7 @@
playsound(Xeno, 'sound/effects/alien_footstep_charge1.ogg', 50)
for(var/mob/living/carbon/human/Mob in Xeno.loc)
- if(Mob.lying && Mob.stat != DEAD)
+ if(Mob.body_position == LYING_DOWN && Mob.stat != DEAD)
Xeno.visible_message(SPAN_DANGER("[Xeno] runs [Mob] over!"),
SPAN_DANGER("You run [Mob] over!")
)
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm
index ce4a631e281f..34a9a4833fec 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm
@@ -252,7 +252,7 @@
to_chat(Xeno, SPAN_XENONOTICE("You will [will_charge] charge when moving."))
if(activated)
RegisterSignal(Xeno, COMSIG_MOVABLE_MOVED, PROC_REF(handle_movement))
- RegisterSignal(Xeno, COMSIG_MOB_KNOCKED_DOWN, PROC_REF(handle_movement))
+ RegisterSignal(Xeno, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(handle_position_change))
RegisterSignal(Xeno, COMSIG_ATOM_DIR_CHANGE, PROC_REF(handle_dir_change))
RegisterSignal(Xeno, COMSIG_XENO_RECALCULATE_SPEED, PROC_REF(update_speed))
RegisterSignal(Xeno, COMSIG_XENO_STOP_MOMENTUM, PROC_REF(stop_momentum))
@@ -264,7 +264,7 @@
stop_momentum()
UnregisterSignal(Xeno, list(
COMSIG_MOVABLE_MOVED,
- COMSIG_MOB_KNOCKED_DOWN,
+ COMSIG_LIVING_SET_BODY_POSITION,
COMSIG_ATOM_DIR_CHANGE,
COMSIG_XENO_RECALCULATE_SPEED,
COMSIG_MOVABLE_ENTERED_RIVER,
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm
index 67e16d4b70de..8a36e4d5cdf7 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm
@@ -215,10 +215,9 @@
else
X.armor_deflection_buff += 30
X.armor_explosive_buff += 60
- X.frozen = TRUE
+ ADD_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Fortify"))
X.anchored = TRUE
X.small_explosives_stun = FALSE
- X.update_canmove()
RegisterSignal(owner, COMSIG_XENO_PRE_CALCULATE_ARMOURED_DAMAGE_PROJECTILE, PROC_REF(check_directional_armor))
X.mob_size = MOB_SIZE_IMMOBILE //knockback immune
X.mob_flags &= ~SQUEEZE_UNDER_VEHICLES
@@ -226,7 +225,7 @@
X.fortify = TRUE
else
to_chat(X, SPAN_XENOWARNING("You resume your normal stance."))
- X.frozen = FALSE
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Fortify"))
X.anchored = FALSE
if(X.steelcrest)
X.armor_deflection_buff -= 10
@@ -240,7 +239,6 @@
UnregisterSignal(owner, COMSIG_XENO_PRE_CALCULATE_ARMOURED_DAMAGE_PROJECTILE)
X.mob_size = MOB_SIZE_XENO //no longer knockback immune
X.mob_flags |= SQUEEZE_UNDER_VEHICLES
- X.update_canmove()
X.update_icons()
X.fortify = FALSE
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm
index c1b1ee5f8902..29172fd9b1d3 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm
@@ -251,8 +251,7 @@
if(freeze_timer_id == TIMER_ID_NULL)
return
var/mob/living/carbon/xenomorph/X = owner
- X.frozen = FALSE
- X.update_canmove()
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Pounce"))
deltimer(freeze_timer_id)
freeze_timer_id = TIMER_ID_NULL
to_chat(X, SPAN_XENONOTICE("Slashing frenzies you! You feel free to move immediately!"))
@@ -285,7 +284,7 @@
/datum/action/xeno_action/onclick/toggle_long_range/can_use_action()
var/mob/living/carbon/xenomorph/xeno = owner
- if(xeno && !xeno.is_mob_incapacitated() && !xeno.lying && !xeno.buckled)
+ if(xeno && !xeno.is_mob_incapacitated() && !xeno.buckled)
return TRUE
/datum/action/xeno_action/onclick/toggle_long_range/give_to(mob/living/living_mob)
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm
index 7a8151d8aa02..250d024041a4 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm
@@ -411,24 +411,21 @@
if (windup)
X.set_face_dir(get_cardinal_dir(X, A))
if (!windup_interruptable)
- X.frozen = TRUE
+ ADD_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Pounce"))
X.anchored = TRUE
- X.update_canmove()
pre_windup_effects()
if (!do_after(X, windup_duration, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE))
to_chat(X, SPAN_XENODANGER("You cancel your [ability_name]!"))
if (!windup_interruptable)
- X.frozen = FALSE
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Pounce"))
X.anchored = FALSE
- X.update_canmove()
post_windup_effects(interrupted = TRUE)
return
if (!windup_interruptable)
- X.frozen = FALSE
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Pounce"))
X.anchored = FALSE
- X.update_canmove()
post_windup_effects()
X.visible_message(SPAN_XENOWARNING("\The [X] [ability_name][findtext(ability_name, "e", -1) || findtext(ability_name, "p", -1) ? "s" : "es"] at [A]!"), SPAN_XENOWARNING("You [ability_name] at [A]!"))
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/hivelord/hivelord_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/hivelord/hivelord_abilities.dm
index 8c39228e3567..02e7fd814453 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/hivelord/hivelord_abilities.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/hivelord/hivelord_abilities.dm
@@ -18,7 +18,7 @@
/datum/action/xeno_action/active_toggle/toggle_speed/can_use_action()
var/mob/living/carbon/xenomorph/hivelord/xeno = owner
- if(xeno && !xeno.is_mob_incapacitated() && !xeno.lying && !xeno.buckled)
+ if(xeno && !xeno.is_mob_incapacitated() && xeno.body_position == STANDING_UP && !xeno.buckled) // do we rly need standing up?
return TRUE
/datum/action/xeno_action/active_toggle/toggle_speed/give_to(mob/living/living_mob)
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm
index b58d94a6ed5b..06c3a05cc0e6 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm
@@ -265,7 +265,7 @@
if(xeno.can_not_harm(target_carbon))
return
- if(!(target_carbon.knocked_out || target_carbon.stat == UNCONSCIOUS)) //called knocked out because for some reason .stat seems to have a delay .
+ if(!(HAS_TRAIT(target_carbon, TRAIT_KNOCKEDOUT) || target_carbon.stat == UNCONSCIOUS)) //called knocked out because for some reason .stat seems to have a delay .
to_chat(xeno, SPAN_XENOHIGHDANGER("You can only headbite an unconscious, adjacent target!"))
return
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm
index e926349af60d..c9d306f112b0 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm
@@ -174,15 +174,13 @@
var/root_duration = buffed ? root_duration_buffed : root_duration_unbuffed
vanguard_user.visible_message(SPAN_XENODANGER("[vanguard_user] slams [target_atom] into the ground!"), SPAN_XENOHIGHDANGER("You slam [target_atom] into the ground!"))
-
- target_carbon.frozen = TRUE
- target_carbon.update_canmove()
+ ADD_TRAIT(target_carbon, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Abduct"))
if (ishuman(target_carbon))
var/mob/living/carbon/human/Hu = target_carbon
Hu.update_xeno_hostile_hud()
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), target_carbon), get_xeno_stun_duration(target_carbon, root_duration))
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), target_carbon, TRAIT_SOURCE_ABILITY("Cleave")), get_xeno_stun_duration(target_carbon, root_duration))
to_chat(target_carbon, SPAN_XENOHIGHDANGER("[vanguard_user] has pinned you to the ground! You cannot move!"))
vanguard_user.flick_attack_overlay(target_carbon, "punch")
@@ -292,8 +290,7 @@
var/throw_target_turf = get_step(X.loc, facing)
- X.frozen = TRUE
- X.update_canmove()
+ ADD_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Abduct"))
if(!do_after(X, windup, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE, numticks = 1))
to_chat(X, SPAN_XENOWARNING("You relax your tail."))
apply_cooldown()
@@ -302,16 +299,14 @@
telegraph_atom_list -= XT
qdel(XT)
- X.frozen = FALSE
- X.update_canmove()
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Abduct"))
return
if(!check_and_use_plasma_owner())
return
- X.frozen = FALSE
- X.update_canmove()
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Abduct"))
playsound(get_turf(X), 'sound/effects/bang.ogg', 25, 0)
X.visible_message(SPAN_XENODANGER("\The [X] suddenly uncoils its tail, firing it towards [A]!"), SPAN_XENODANGER("You uncoil your tail, sending it out towards \the [A]!"))
@@ -339,13 +334,11 @@
new /datum/effects/xeno_slow(H, X, , ,25)
H.apply_effect(1, SLOW)
else if (LAZYLEN(targets) == 2)
-
- H.frozen = TRUE
- H.update_canmove()
+ ADD_TRAIT(H, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Abduct"))
if (ishuman(H))
var/mob/living/carbon/human/Hu = H
Hu.update_xeno_hostile_hud()
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), H), get_xeno_stun_duration(H, 25))
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), H, TRAIT_SOURCE_ABILITY("Abduct")), get_xeno_stun_duration(H, 25))
to_chat(H, SPAN_XENOHIGHDANGER("[X] has pinned you to the ground! You cannot move!"))
H.set_effect(2, DAZE)
@@ -409,16 +402,15 @@
oppressor_user.animation_attack_on(target_carbon)
oppressor_user.flick_attack_overlay(target_carbon, "punch")
- if (target_carbon.frozen || target_carbon.slowed || target_carbon.knocked_down)
+ if (!(target_carbon.mobility_flags & MOBILITY_MOVE) || !(target_carbon.mobility_flags & MOBILITY_STAND) || target_carbon.slowed)
target_carbon.apply_damage(get_xeno_damage_slash(target_carbon, damage), BRUTE, target_limb? target_limb.name : "chest")
- target_carbon.frozen = TRUE
- target_carbon.update_canmove()
+ ADD_TRAIT(target_carbon, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Oppressor Punch"))
if (ishuman(target_carbon))
var/mob/living/carbon/human/Hu = target_carbon
Hu.update_xeno_hostile_hud()
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), target_carbon), get_xeno_stun_duration(target_carbon, 12))
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), target_carbon, TRAIT_SOURCE_ABILITY("Oppressor Punch")), get_xeno_stun_duration(target_carbon, 12))
to_chat(target_carbon, SPAN_XENOHIGHDANGER("[oppressor_user] has pinned you to the ground! You cannot move!"))
var/datum/action/xeno_action/activable/prae_abduct/abduct_action = get_xeno_action_by_type(oppressor_user, /datum/action/xeno_action/activable/prae_abduct)
@@ -1012,8 +1004,7 @@
if(!(behind_turf.density))
throw_target_turf = behind_turf
- X.frozen = TRUE
- X.update_canmove()
+ ADD_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Praetorian Retrieve"))
if(windup)
if(!do_after(X, windup, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE, numticks = 1))
to_chat(X, SPAN_XENOWARNING("You cancel your retrieve."))
@@ -1023,13 +1014,12 @@
telegraph_atom_list -= XT
qdel(XT)
- X.frozen = FALSE
- X.update_canmove()
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Praetorian Retrieve"))
return
- X.frozen = FALSE
- X.update_canmove()
+ REMOVE_TRAIT(X, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Praetorian Retrieve"))
+
playsound(get_turf(X), 'sound/effects/bang.ogg', 25, 0)
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm
index 3b52a60419df..3c475743c0bf 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm
@@ -78,14 +78,13 @@
for(var/mob/living/carbon/carbon in oview(round(behavior.kills * 0.5 + 2), xeno))
if(!xeno.can_not_harm(carbon) && carbon.stat != DEAD)
- carbon.frozen = 1
- carbon.update_canmove()
+ ADD_TRAIT(carbon, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Smash"))
if (ishuman(carbon))
var/mob/living/carbon/human/human = carbon
human.update_xeno_hostile_hud()
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), carbon), get_xeno_stun_duration(carbon, freeze_duration))
+ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(unroot_human), carbon, TRAIT_SOURCE_ABILITY("Smash")), get_xeno_stun_duration(carbon, freeze_duration))
for(var/mob/M in view(xeno))
@@ -125,8 +124,7 @@
if (!check_and_use_plasma_owner())
return
- carbon.frozen = 1
- carbon.update_canmove()
+ ADD_TRAIT(carbon, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate"))
if (ishuman(carbon))
var/mob/living/carbon/human/human = carbon
@@ -134,9 +132,8 @@
apply_cooldown()
- xeno.frozen = 1
+ ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate"))
xeno.anchored = TRUE
- xeno.update_canmove()
if (do_after(xeno, activation_delay, INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE))
xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] rips open the guts of [carbon]!"), SPAN_XENOHIGHDANGER("You rip open the guts of [carbon]!"))
@@ -151,11 +148,9 @@
playsound(owner, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0)
- xeno.frozen = 0
+ REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate"))
xeno.anchored = FALSE
- xeno.update_canmove()
-
- unroot_human(carbon)
+ unroot_human(carbon, TRAIT_SOURCE_ABILITY("Devastate"))
xeno.visible_message(SPAN_XENODANGER("[xeno] rapidly slices into [carbon]!"))
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm
index cd4533eabc83..c61c5096090e 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm
@@ -385,9 +385,8 @@
else
xeno.visible_message(SPAN_XENODANGER("[xeno] begins digging in for a strike!"), SPAN_XENOHIGHDANGER("You begin digging in for a strike!"))
- xeno.frozen = 1
+ ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Eviscerate"))
xeno.anchored = TRUE
- xeno.update_canmove()
if (do_after(xeno, (activation_delay - windup_reduction), INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE))
xeno.emote("roar")
@@ -430,9 +429,8 @@
if(!xeno.on_fire)
xeno.gain_health(Clamp(valid_count * lifesteal_per_marine, 0, max_lifesteal))
- xeno.frozen = 0
+ REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Eviscerate"))
xeno.anchored = FALSE
- xeno.update_canmove()
return ..()
diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
index f4d4628e41f2..f0917ef48dc4 100644
--- a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
+++ b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm
@@ -71,7 +71,7 @@
if(!owner)
return FALSE
var/mob/living/carbon/xenomorph/X = owner
- if(X && !X.is_mob_incapacitated() && !X.dazed && !X.lying && !X.buckled && X.plasma_stored >= plasma_cost)
+ if(X && !X.is_mob_incapacitated() && !X.dazed && X.body_position == STANDING_UP && !X.buckled && X.plasma_stored >= plasma_cost)
return TRUE
/datum/action/xeno_action/give_to(mob/living/L)
diff --git a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm
index 25f6108c14f6..a5a179acd07b 100644
--- a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm
+++ b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm
@@ -209,7 +209,7 @@
SPAN_DANGER("You tackle down [src]!"), null, 5, CHAT_TYPE_XENO_COMBAT)
else
playsound(loc, 'sound/weapons/alien_claw_swipe.ogg', 25, 1)
- if (knocked_down)
+ if (HAS_TRAIT(src, TRAIT_FLOORED))
M.visible_message(SPAN_DANGER("[M] tries to tackle [src], but they are already down!"), \
SPAN_DANGER("You try to tackle [src], but they are already down!"), null, 5, CHAT_TYPE_XENO_COMBAT)
else
@@ -555,7 +555,7 @@
if(M.action_busy)
return XENO_NO_DELAY_ACTION
- if(M.lying)
+ if(M.body_position)
return XENO_NO_DELAY_ACTION
var/delay
@@ -574,7 +574,7 @@
if(do_after(M, delay, INTERRUPT_ALL, BUSY_ICON_HOSTILE))
if(M.loc != cur_loc)
return XENO_NO_DELAY_ACTION //Make sure we're still there
- if(M.lying)
+ if(M.body_position)
return XENO_NO_DELAY_ACTION
if(locked)
to_chat(M, SPAN_WARNING("[src] is bolted down tight."))
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm b/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm
index ead254344e0a..32d98d43a5c4 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Burrower.dm
@@ -84,13 +84,6 @@
. = ..()
sight |= SEE_TURFS
-/mob/living/carbon/xenomorph/burrower/update_canmove()
- . = ..()
- if(burrow)
- density = FALSE
- canmove = FALSE
- return canmove
-
/mob/living/carbon/xenomorph/burrower/ex_act(severity)
if(burrow)
return
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
index 6b847a6a4fec..e3b2295479d0 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
@@ -109,8 +109,8 @@
for(var/i in hugger_image_index)
if(stat == DEAD)
hugger_overlays_icon.overlays += icon(icon, "clinger_[i] Knocked Down")
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position == LYING_DOWN)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
hugger_overlays_icon.overlays += icon(icon, "clinger_[i] Sleeping")
else
hugger_overlays_icon.overlays +=icon(icon, "clinger_[i] Knocked Down")
@@ -154,8 +154,8 @@
i = 1
if(stat != DEAD)
- if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ if(body_position)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
eggsac_overlays_icon.overlays += icon(icon, "eggsac_[i] Sleeping")
else
eggsac_overlays_icon.overlays +=icon(icon, "eggsac_[i] Knocked Down")
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
index c9ceaaa85cfb..3f52f1d2699e 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Facehugger.dm
@@ -70,7 +70,7 @@
if(stat == DEAD)
return ..()
- if(!lying && !(mutation_type == FACEHUGGER_WATCHER) && !(locate(/obj/effect/alien/weeds) in get_turf(src)))
+ if(body_position == STANDING_UP && !(mutation_type == FACEHUGGER_WATCHER) && !(locate(/obj/effect/alien/weeds) in get_turf(src)))
adjustBruteLoss(1)
return ..()
@@ -86,8 +86,8 @@
if(stat == DEAD)
icon_state = "[mutation_type] [caste.caste_type] Dead"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
icon_state = "[mutation_type] [caste.caste_type] Sleeping"
else
icon_state = "[mutation_type] [caste.caste_type] Knocked Down"
@@ -110,8 +110,8 @@
if(!caste)
return FALSE
- if(lying) //No attacks while laying down
- return FALSE
+ if(body_position == LYING_DOWN) //No attacks while laying down
+ return FALSE // Yoooo replace this by a mobility_flag for attacks or something
if(istype(A, /obj/effect/alien/resin/special/eggmorph))
var/obj/effect/alien/resin/special/eggmorph/morpher = A
@@ -130,7 +130,7 @@
if(ishuman(A))
var/mob/living/carbon/human/human = A
- if(!human.lying)
+ if(human.body_position != LYING_DOWN)
to_chat(src, SPAN_WARNING("You can't reach \the [human], they need to be lying down."))
return
if(!can_hug(human, hivenumber))
@@ -139,7 +139,7 @@
visible_message(SPAN_WARNING("\The [src] starts climbing onto \the [human]'s face..."), SPAN_XENONOTICE("You start climbing onto \the [human]'s face..."))
if(!do_after(src, FACEHUGGER_WINDUP_DURATION, INTERRUPT_ALL, BUSY_ICON_HOSTILE, human, INTERRUPT_MOVED, BUSY_ICON_HOSTILE))
return
- if(!human.lying)
+ if(human.body_position != LYING_DOWN)
to_chat(src, SPAN_WARNING("You can't reach \the [human], they need to be lying down."))
return
if(!can_hug(human, hivenumber))
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm b/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm
index 82d80752ec54..e37507109fd7 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm
@@ -130,8 +130,8 @@
else if(handcuffed || legcuffed)
icon_state = "[state_override || state]Larva Cuff"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position == LYING_DOWN)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
icon_state = "[state_override || state]Larva Sleeping"
else
icon_state = "[state_override || state]Larva Stunned"
@@ -155,7 +155,7 @@
if(!caste)
return FALSE
- if(lying) //No attacks while laying down
+ if(body_position) //No attacks while laying down
return FALSE
A.attack_larva(src)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm
index c106eb30781b..285d64a04498 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm
@@ -102,7 +102,7 @@
if (!isxeno_human(target_carbon))
return
- if (target_carbon.knocked_down)
+ if (HAS_TRAIT(target_carbon, TRAIT_FLOORED))
new /datum/effects/xeno_slow(target_carbon, bound_xeno, null, null, get_xeno_stun_duration(target_carbon, slash_slow_duration))
return
@@ -114,6 +114,12 @@
if (LIA && istype(LIA))
LIA.invisibility_off()
+/datum/behavior_delegate/lurker_base/proc/decloak_handler(mob/source)
+ SIGNAL_HANDLER
+ var/datum/action/xeno_action/onclick/lurker_invisibility/LIA = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility)
+ if(istype(LIA))
+ LIA.invisibility_off()
+
// What to do when we go invisible
/datum/behavior_delegate/lurker_base/proc/on_invisibility()
var/datum/action/xeno_action/activable/pounce/lurker/LPA = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker)
@@ -121,6 +127,7 @@
LPA.knockdown = TRUE // pounce knocks down
LPA.freeze_self = TRUE
ADD_TRAIT(bound_xeno, TRAIT_CLOAKED, TRAIT_SOURCE_ABILITY("cloak"))
+ RegisterSignal(bound_xeno, COMSIG_MOB_EFFECT_CLOAK_CANCEL, PROC_REF(decloak_handler))
bound_xeno.stealth = TRUE
can_go_invisible = FALSE
invis_start_time = world.time
@@ -132,6 +139,7 @@
LPA.freeze_self = FALSE
bound_xeno.stealth = FALSE
REMOVE_TRAIT(bound_xeno, TRAIT_CLOAKED, TRAIT_SOURCE_ABILITY("cloak"))
+ UnregisterSignal(bound_xeno, COMSIG_MOB_EFFECT_CLOAK_CANCEL)
// SLIGHTLY hacky because we need to maintain lots of other state on the lurker
// whenever invisibility is on/off CD and when it's active.
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
index b83b33e2eee5..e6f4dfae8a44 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
@@ -791,6 +791,9 @@
if(ovipositor)
return //sanity check
ovipositor = TRUE
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, OVIPOSITOR_TRAIT)
+ set_body_position(STANDING_UP)
+ set_resting(FALSE)
set_resin_build_order(GLOB.resin_build_order_ovipositor) // This needs to occur before we update the abilities so we can update the choose resin icon
for(var/datum/action/xeno_action/action in actions)
@@ -843,7 +846,6 @@
egg_planting_range = 3
anchored = TRUE
resting = FALSE
- update_canmove()
update_icons()
bubble_icon_x_offset = 32
bubble_icon_y_offset = 32
@@ -871,6 +873,7 @@
if(!ovipositor)
return
ovipositor = FALSE
+ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, OVIPOSITOR_TRAIT)
update_icons()
bubble_icon_x_offset = initial(bubble_icon_x_offset)
bubble_icon_y_offset = initial(bubble_icon_y_offset)
@@ -899,7 +902,6 @@
ovi_ability.apply_cooldown()
break
anchored = FALSE
- update_canmove()
for(var/mob/living/carbon/xenomorph/L in hive.xeno_leader_list)
L.handle_xeno_leader_pheromones()
@@ -909,14 +911,6 @@
SEND_SIGNAL(src, COMSIG_QUEEN_DISMOUNT_OVIPOSITOR, instant_dismount)
-/mob/living/carbon/xenomorph/queen/update_canmove()
- . = ..()
- if(ovipositor)
- lying = FALSE
- density = TRUE
- canmove = FALSE
- return canmove
-
/mob/living/carbon/xenomorph/queen/handle_special_state()
if(ovipositor)
return TRUE
diff --git a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
index 51ceee153368..b6ceb2043458 100644
--- a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
@@ -36,7 +36,7 @@
/mob/living/carbon/xenomorph/ex_act(severity, direction, datum/cause_data/cause_data, pierce=0)
- if(lying)
+ if(body_position == LYING_DOWN)
severity *= EXPLOSION_PRONE_MULTIPLIER
if(severity >= 30)
diff --git a/code/modules/mob/living/carbon/xenomorph/life.dm b/code/modules/mob/living/carbon/xenomorph/life.dm
index 65839e9c8caf..0c2c019e81bc 100644
--- a/code/modules/mob/living/carbon/xenomorph/life.dm
+++ b/code/modules/mob/living/carbon/xenomorph/life.dm
@@ -10,7 +10,8 @@
..()
- if(is_zoomed && (stat || lying))
+ // replace this by signals or trait signals
+ if(is_zoomed && (stat || body_position == LYING_DOWN))
zoom_out()
if(stat != DEAD) //Stop if dead. Performance boost
@@ -23,7 +24,6 @@
handle_regular_status_updates()
handle_stomach_contents()
handle_overwatch() // For new Xeno hivewide overwatch - Fourk, 6/24/19
- update_canmove()
update_icons()
handle_luminosity()
handle_blood()
@@ -187,9 +187,8 @@
ear_damage = 0
SetEyeBlind(0)
- if(knocked_out) //If they're down, make sure they are actually down.
+ if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT)) //If they're down, make sure they are actually down.
blinded = TRUE
- set_stat(UNCONSCIOUS)
if(regular_update && halloss > 0)
apply_damage(-3, HALLOSS)
else if(sleeping)
@@ -342,7 +341,7 @@ Make sure their actual health updates immediately.*/
if(recovery_aura)
plasma_stored += round(plasma_gain * plasma_max / 100 * recovery_aura/4) //Divided by four because it gets massive fast. 1 is equivalent to weed regen! Only the strongest pheromones should bypass weeds
if(health < maxHealth && !hardcore && is_hive_living(hive) && last_hit_time + caste.heal_delay_time <= world.time)
- if(lying || resting)
+ if(body_position == LYING_DOWN || resting)
if(health < 0) //Unconscious
heal_wounds(caste.heal_knocked_out * regeneration_multiplier, recoveryActual) //Healing is much slower. Warding pheromones make up for the rest if you're curious
else
@@ -536,8 +535,6 @@ Make sure their actual health updates immediately.*/
if(layer != initial(layer)) //Unhide
layer = initial(layer)
recalculate_move_delay = TRUE
- if(!lying)
- update_canmove()
/mob/living/carbon/xenomorph/proc/handle_luminosity()
var/new_luminosity = 0
@@ -583,16 +580,14 @@ Make sure their actual health updates immediately.*/
return superslowed
/mob/living/carbon/xenomorph/handle_knocked_down()
- if(knocked_down)
+ if(HAS_TRAIT(src, TRAIT_FLOORED))
adjust_effect(life_knockdown_reduction, WEAKEN, EFFECT_FLAG_LIFE)
knocked_down_callback_check()
- return knocked_down
/mob/living/carbon/xenomorph/handle_knocked_out()
- if(knocked_out)
+ if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
adjust_effect(life_knockout_reduction, PARALYZE, EFFECT_FLAG_LIFE)
knocked_out_callback_check()
- return knocked_out
//Returns TRUE if xeno is on weeds
//Returns TRUE if xeno is off weeds AND doesn't need weeds for healing AND is not on Almayer UNLESS Queen is also on Almayer (aka - no solo Lurker Almayer hero)
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm
index f7daee71df38..5e986020bb48 100644
--- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm
+++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/crusher/charger.dm
@@ -82,7 +82,7 @@
return
/datum/behavior_delegate/crusher_charger/on_update_icons()
- if(HAS_TRAIT(bound_xeno, TRAIT_CHARGING) && !bound_xeno.lying)
+ if(HAS_TRAIT(bound_xeno, TRAIT_CHARGING) && bound_xeno.body_position == STANDING_UP)
bound_xeno.icon_state = "[bound_xeno.mutation_icon_state || bound_xeno.mutation_type] Crusher Charging"
return TRUE
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/gardener.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/gardener.dm
index 303e1c94692d..105a7e92f911 100644
--- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/gardener.dm
+++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/gardener.dm
@@ -379,8 +379,8 @@
if(bound_xeno.stat == DEAD)
fruit_sac_overlay_icon.icon_state = "Gardener Drone Dead"
- else if(bound_xeno.lying)
- if((bound_xeno.resting || bound_xeno.sleeping) && (!bound_xeno.knocked_down && !bound_xeno.knocked_out && bound_xeno.health > 0))
+ else if(bound_xeno.body_position == LYING_DOWN)
+ if((bound_xeno.resting || bound_xeno.sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && bound_xeno.health > 0))
fruit_sac_overlay_icon.icon_state = "Gardener Drone Sleeping"
else
fruit_sac_overlay_icon.icon_state = "Gardener Drone Knocked Down"
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/healer.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/healer.dm
index 5caab38529e6..c378f8dc64d4 100644
--- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/healer.dm
+++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/drone/healer.dm
@@ -160,8 +160,8 @@
if(bound_xeno.stat == DEAD)
salve_applied_icon.icon_state = "Healer Drone Dead"
- else if(bound_xeno.lying)
- if((bound_xeno.resting || bound_xeno.sleeping) && (!bound_xeno.knocked_down && !bound_xeno.knocked_out && bound_xeno.health > 0))
+ else if(bound_xeno.body_position == LYING_DOWN)
+ if((bound_xeno.resting || bound_xeno.sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && bound_xeno.health > 0))
salve_applied_icon.icon_state = "Healer Drone Sleeping"
else
salve_applied_icon.icon_state = "Healer Drone Knocked Down"
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/oppressor.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/oppressor.dm
index 4a3bd3a7d182..4beaedf8d6a8 100644
--- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/oppressor.dm
+++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/praetorian/oppressor.dm
@@ -52,14 +52,12 @@
var/tearing_damage = 15
/datum/behavior_delegate/oppressor_praetorian/melee_attack_additional_effects_target(mob/living/carbon/target_carbon)
-
if(target_carbon.stat == DEAD)
return
- if(!(target_carbon.knocked_down || target_carbon.frozen || target_carbon.slowed))
- return
+ // impaired in some capacity
+ if(!(target_carbon.mobility_flags & MOBILITY_STAND) || !(target_carbon.mobility_flags & MOBILITY_MOVE) || target_carbon.slowed)
+ target_carbon.apply_armoured_damage(get_xeno_damage_slash(target_carbon, tearing_damage), ARMOR_MELEE, BRUTE, bound_xeno.zone_selected ? bound_xeno.zone_selected : "chest")
+ target_carbon.visible_message(SPAN_DANGER("[bound_xeno] tears into [target_carbon]!"))
+ playsound(bound_xeno, 'sound/weapons/alien_tail_attack.ogg', 25, TRUE)
- target_carbon.apply_armoured_damage(get_xeno_damage_slash(target_carbon, tearing_damage), ARMOR_MELEE, BRUTE, bound_xeno.zone_selected ? bound_xeno.zone_selected : "chest")
- target_carbon.visible_message(SPAN_DANGER("[bound_xeno] tears into [target_carbon]!"))
- playsound(bound_xeno, 'sound/weapons/alien_tail_attack.ogg', 25, TRUE)
- return
diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/runner/acid.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/runner/acid.dm
index 630edf26d353..490e5ca36cba 100644
--- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/runner/acid.dm
+++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/runner/acid.dm
@@ -87,7 +87,7 @@
if(embryo?.stage >= 4) //very late stage hugged in case the runner unnests them
return
- if(target_mob.lying)
+ if(target_mob.body_position == LYING_DOWN)
modify_acid(acid_slash_regen_lying)
return
modify_acid(acid_slash_regen_standing)
diff --git a/code/modules/mob/living/carbon/xenomorph/update_icons.dm b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
index 30e78a5fed94..39628fe453a8 100644
--- a/code/modules/mob/living/carbon/xenomorph/update_icons.dm
+++ b/code/modules/mob/living/carbon/xenomorph/update_icons.dm
@@ -69,8 +69,8 @@
icon_state = "[mutation_caste_state] Dead"
if(!(icon_state in icon_states(icon_xeno)))
icon_state = "Normal [caste.caste_type] Dead"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position == LYING_DOWN)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
icon_state = "[mutation_caste_state] Sleeping"
if(!(icon_state in icon_states(icon_xeno)))
icon_state = "Normal [caste.caste_type] Sleeping"
@@ -142,8 +142,8 @@
var/state_modifier = ""
if(stat == DEAD)
state_modifier = " Dead"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
state_modifier = " Sleeping"
else
state_modifier = " Knocked Down"
@@ -237,7 +237,7 @@
if(on_fire && fire_reagent)
var/image/I
if(mob_size >= MOB_SIZE_BIG)
- if((!initial(pixel_y) || lying) && !resting && !sleeping)
+ if((!initial(pixel_y) || body_position) && !resting && !sleeping)
I = image("icon"='icons/mob/xenos/overlay_effects64x64.dmi', "icon_state"="alien_fire", "layer"=-X_FIRE_LAYER)
else
I = image("icon"='icons/mob/xenos/overlay_effects64x64.dmi', "icon_state"="alien_fire_lying", "layer"=-X_FIRE_LAYER)
@@ -278,8 +278,8 @@
if(health > HEALTH_THRESHOLD_DEAD)
if(health_threshold > 3)
wound_icon_carrier.icon_state = "none"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position == LYING_DOWN)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
wound_icon_carrier.icon_state = "[caste.caste_type]_rest_[health_threshold]"
else
wound_icon_carrier.icon_state = "[caste.caste_type]_downed_[health_threshold]"
diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm
new file mode 100644
index 000000000000..8d6341c29323
--- /dev/null
+++ b/code/modules/mob/living/init_signals.dm
@@ -0,0 +1,75 @@
+/// 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_REF(on_knockedout_trait_gain))
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_KNOCKEDOUT), PROC_REF(on_knockedout_trait_loss))
+
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), PROC_REF(on_immobilized_trait_gain))
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED), PROC_REF(on_immobilized_trait_loss))
+
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_FLOORED), PROC_REF(on_floored_trait_gain))
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_FLOORED), PROC_REF(on_floored_trait_loss))
+
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), PROC_REF(on_incapacitated_trait_gain))
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED), PROC_REF(on_incapacitated_trait_loss))
+
+ RegisterSignal(src, list(SIGNAL_ADDTRAIT(TRAIT_UNDENSE), SIGNAL_REMOVETRAIT(TRAIT_UNDENSE)), PROC_REF(undense_changed))
+
+/// Called when [TRAIT_KNOCKEDOUT] is added to the mob.
+/mob/living/proc/on_knockedout_trait_gain(datum/source)
+ SIGNAL_HANDLER
+ if(stat < UNCONSCIOUS)
+ set_stat(UNCONSCIOUS)
+
+/// Called when [TRAIT_KNOCKEDOUT] is removed from the mob.
+/mob/living/proc/on_knockedout_trait_loss(datum/source)
+ SIGNAL_HANDLER
+ if(stat <= UNCONSCIOUS)
+ update_stat()
+
+/// Called when [TRAIT_IMMOBILIZED] is added to the mob.
+/mob/living/proc/on_immobilized_trait_gain(datum/source)
+ SIGNAL_HANDLER
+ mobility_flags &= ~MOBILITY_MOVE
+// if(living_flags & MOVES_ON_ITS_OWN)
+// SSmove_manager.stop_looping(src) //stop mid walk //This is also really dumb
+
+/// 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
+ if(buckled && buckled.buckle_lying != NO_BUCKLE_LYING)
+ return // Handled by the buckle.
+// if(HAS_TRAIT(src, TRAIT_FORCED_STANDING))
+// return // Don't go horizontal if mob has forced standing trait.
+ mobility_flags &= ~MOBILITY_STAND
+ on_floored_start()
+
+
+/// 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()
+
+/// Called when [TRAIT_INCAPACITATED] is added to the mob.
+/mob/living/proc/on_incapacitated_trait_gain(datum/source)
+ SIGNAL_HANDLER
+ //add_traits(list(TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED), TRAIT_INCAPACITATED)
+ //update_appearance()
+ return
+
+/// Called when [TRAIT_INCAPACITATED] is removed from the mob.
+/mob/living/proc/on_incapacitated_trait_loss(datum/source)
+ SIGNAL_HANDLER
+ //remove_traits(list(TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED), TRAIT_INCAPACITATED)
+ //update_appearance()
+ return
+
+/// Called when [TRAIT_UNDENSE] is gained or lost
+/mob/living/proc/undense_changed(datum/source)
+ SIGNAL_HANDLER
+ update_density()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 1190e55925a1..0fd67c03b151 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -16,6 +16,7 @@
attack_icon = image("icon" = 'icons/effects/attacks.dmi',"icon_state" = "", "layer" = 0)
+ register_init_signals()
initialize_incision_depths()
initialize_pain()
initialize_stamina()
@@ -33,11 +34,6 @@
QDEL_NULL(stamina)
QDEL_NULL(hallucinations)
-//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
-//affects them once clothing is factored in. ~Errorage
-/mob/living/proc/calculate_affecting_pressure(pressure)
- return
-
/mob/living/proc/initialize_pain()
pain = new /datum/pain(src)
@@ -150,6 +146,8 @@
return
/mob/living/Move(NewLoc, direct)
+ if(lying_angle != 0)
+ lying_angle_on_movement(direct)
if (buckled && buckled.loc != NewLoc) //not updating position
if (!buckled.anchored)
return buckled.Move(NewLoc, direct)
@@ -453,13 +451,204 @@
for(var/h in src.hud_possible)
src.clone.hud_list[h].icon_state = src.hud_list[h].icon_state
+// Note that this might CLASH with handle_regular_status_updates until it is ELIMINATED
+// and everything is switched from updates to signaling - due to not accounting for all cases.
+// If this proc causes issues you can probably disable it until then.
+/mob/living/carbon/update_stat()
+ if(stat != DEAD)
+ if(health <= HEALTH_THRESHOLD_DEAD)
+ death()
+ return
+ else if(HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
+ set_stat(UNCONSCIOUS)
+ else
+ set_stat(CONSCIOUS)
+
/mob/living/set_stat(new_stat)
. = ..()
if(isnull(.))
return
- switch(.)
+
+ switch(.) //Previous stat.
+ if(CONSCIOUS)
+ if(stat >= UNCONSCIOUS)
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ add_traits(list(/*TRAIT_HANDS_BLOCKED, */ TRAIT_INCAPACITATED, TRAIT_FLOORED), STAT_TRAIT)
+ if(UNCONSCIOUS)
+ if(stat >= UNCONSCIOUS)
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates
if(DEAD)
SEND_SIGNAL(src, COMSIG_MOB_STAT_SET_ALIVE)
- switch(stat)
+// remove_from_dead_mob_list()
+// add_to_alive_mob_list()
+
+ switch(stat) //Current stat.
+ if(CONSCIOUS)
+ if(. >= UNCONSCIOUS)
+ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ remove_traits(list(/*TRAIT_HANDS_BLOCKED, */ TRAIT_INCAPACITATED, TRAIT_FLOORED, /*TRAIT_CRITICAL_CONDITION*/), STAT_TRAIT)
+ if(UNCONSCIOUS)
+ if(. >= UNCONSCIOUS)
+ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
if(DEAD)
SEND_SIGNAL(src, COMSIG_MOB_STAT_SET_DEAD)
+// REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT)
+// remove_from_alive_mob_list()
+// add_to_dead_mob_list()
+
+/**
+ * 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
+
+///Called by mob Move() when the lying_angle is different than zero, to better visually simulate crawling.
+/mob/living/proc/lying_angle_on_movement(direct)
+ if(direct & EAST)
+ set_lying_angle(90)
+ else if(direct & WEST)
+ set_lying_angle(270)
+
+///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(!HAS_TRAIT(buckled, TRAIT_NO_IMMOBILIZE))
+// ADD_TRAIT(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT)
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, BUCKLED_TRAIT)
+ switch(buckled.buckle_lying)
+ if(NO_BUCKLE_LYING) // The buckle doesn't force a lying angle.
+ REMOVE_TRAIT(src, TRAIT_FLOORED, BUCKLED_TRAIT)
+ if(0) // Forcing to a standing position.
+ REMOVE_TRAIT(src, TRAIT_FLOORED, BUCKLED_TRAIT)
+ set_body_position(STANDING_UP)
+ set_lying_angle(0)
+ else // Forcing to a lying position.
+ ADD_TRAIT(src, TRAIT_FLOORED, BUCKLED_TRAIT)
+ set_body_position(LYING_DOWN)
+ set_lying_angle(buckled.buckle_lying)
+ else
+ remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_FLOORED), BUCKLED_TRAIT)
+ if(.) // We unbuckled from something.
+ //var/atom/movable/old_buckled = .
+ var/obj/old_buckled = . // /tg/ code has buckling defined on /atom/movable - consider refactoring this sometime
+ if(old_buckled.buckle_lying == 0 && (resting || HAS_TRAIT(src, TRAIT_FLOORED))) // The buckle forced us to stay up (like a chair)
+ set_lying_down() // We want to rest or are otherwise floored, so let's drop on the ground.
+
+/mob/living/proc/get_up(instant = FALSE) // arg ignored
+// set waitfor = FALSE
+// if(!instant && !do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP))
+// return
+ if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED))
+ return
+ set_body_position(STANDING_UP)
+ set_lying_angle(0)
+
+/// Change the [body_position] to [LYING_DOWN] and update associated behavior.
+/mob/living/proc/set_lying_down(new_lying_angle)
+ set_body_position(LYING_DOWN)
+
+/// Proc to append behavior related to lying down.
+/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
+ add_traits(list(/*TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED,*/ TRAIT_UNDENSE), LYING_DOWN_TRAIT)
+ if(HAS_TRAIT(src, TRAIT_FLOORED) && !(dir & (NORTH|SOUTH)))
+ setDir(pick(NORTH, SOUTH)) // We are and look helpless.
+// if(rotate_on_lying)
+// body_position_pixel_y_offset = PIXEL_Y_OFFSET_LYING
+
+ // CM legacy canmove procs, replace this with signal procs probably
+ drop_l_hand()
+ drop_r_hand()
+ add_temp_pass_flags(PASS_MOB_THRU)
+ //so mob lying always appear behind standing mobs, but dead ones appear behind living ones
+ if(pulledby && pulledby.grab_level == GRAB_CARRY)
+ layer = ABOVE_MOB_LAYER
+ else if (stat == DEAD)
+ layer = LYING_DEAD_MOB_LAYER // Dead mobs should layer under living ones
+ else if(layer == initial(layer)) //to avoid things like hiding larvas.
+ layer = LYING_LIVING_MOB_LAYER
+
+/// Changes the value of the [living/body_position] variable. Call this before set_lying_angle()
+/mob/living/proc/set_body_position(new_value)
+ if(body_position == new_value)
+ return
+ if((new_value == LYING_DOWN) && !(mobility_flags & MOBILITY_LIEDOWN))
+ return
+ . = body_position
+ body_position = new_value
+ SEND_SIGNAL(src, COMSIG_LIVING_SET_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()
+
+/// Proc to append behavior related to lying down.
+/mob/living/proc/on_standing_up()
+ //if(layer == LYING_MOB_LAYER)
+ // layer = initial(layer)
+ remove_traits(list(/*TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED,*/ TRAIT_UNDENSE), LYING_DOWN_TRAIT)
+ // Make sure it doesn't go out of the southern bounds of the tile when standing.
+ //body_position_pixel_y_offset = get_pixel_y_offset_standing(current_size)
+ // CM stuff below
+ remove_temp_pass_flags(PASS_MOB_THRU)
+ if(layer == LYING_DEAD_MOB_LAYER || layer == LYING_LIVING_MOB_LAYER)
+ layer = initial(layer)
+
+/mob/living/proc/update_density()
+ if(HAS_TRAIT(src, TRAIT_UNDENSE))
+ set_density(FALSE)
+ else
+ set_density(TRUE)
+
+/// Proc to append behavior to the condition of being floored. Called when the condition starts.
+/mob/living/proc/on_floored_start()
+ if(body_position == STANDING_UP) //force them on the ground
+ set_body_position(LYING_DOWN)
+ set_lying_angle(pick(90, 270))
+// on_fall()
+
+
+/// Proc to append behavior to the condition of being floored. Called when the condition ends.
+/mob/living/proc/on_floored_end()
+ if(!resting)
+ get_up()
+
+
+/mob/living/update_transform()
+ var/visual_angle = lying_angle
+ if(!rotate_on_lying)
+ return
+ var/matrix/base = matrix()
+ if(pulledby && pulledby.grab_level >= GRAB_CARRY)
+ visual_angle = 90 // CM code - for fireman carry
+ else if(lying_angle)
+ base.Translate(rand(-10,10), rand(-10,10))
+ apply_transform(base.Turn(visual_angle), UPDATE_TRANSFORM_ANIMATION_TIME)
+
+
+// legacy procs
+/mob/living/put_in_l_hand(obj/item/W)
+ if(body_position == LYING_DOWN)
+ return
+ return ..()
+/mob/living/put_in_r_hand(obj/item/W)
+ if(body_position == LYING_DOWN)
+ return
+ return ..()
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 4293595e1a51..add16048887c 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -14,6 +14,11 @@
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
var/halloss = 0 //Hallucination damage. 'Fake' damage obtained through hallucinating or the holodeck. Sleeping should cause it to wear off.
+ // please don't use these
+ VAR_PROTECTED/knocked_out = 0
+ VAR_PROTECTED/knocked_down = 0
+ VAR_PROTECTED/stunned = 0
+
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm
@@ -110,3 +115,15 @@
/// This is what the value is changed to when the mob dies. Actual BMV definition in atom/movable.
var/dead_black_market_value = 0
+
+ /// Variable to track the body position of a mob, regardgless of the actual angle of rotation (usually matching it, but not necessarily).
+ var/body_position = STANDING_UP
+ /// 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
+ /// Value of lying lying_angle before last change. TODO: Remove the need for this.
+ var/lying_prev = 0
+ /// Does the mob rotate when lying
+ var/rotate_on_lying = FALSE
+
+ /// Flags that determine the potential of a mob to perform certain actions. Do not change this directly.
+ var/mobility_flags = MOBILITY_FLAGS_DEFAULT
diff --git a/code/modules/mob/living/living_health_procs.dm b/code/modules/mob/living/living_health_procs.dm
index 14f017fd459f..a4bc9f526383 100644
--- a/code/modules/mob/living/living_health_procs.dm
+++ b/code/modules/mob/living/living_health_procs.dm
@@ -82,10 +82,303 @@
maxHealth = newMaxHealth
+/mob/living
+ VAR_PROTECTED/stun_timer = TIMER_ID_NULL
+
+/mob/living/proc/stun_callback()
+ REMOVE_TRAIT(src, TRAIT_INCAPACITATED, STUNNED_TRAIT)
+ stunned = 0
+ handle_regular_status_updates(FALSE)
+ if(stun_timer != TIMER_ID_NULL)
+ deltimer(stun_timer)
+ stun_timer = TIMER_ID_NULL
+
+/mob/living/proc/stun_callback_check()
+ if(knocked_out)
+ ADD_TRAIT(src, TRAIT_INCAPACITATED, STUNNED_TRAIT)
+ if(stunned && stunned < recovery_constant)
+ stun_timer = addtimer(CALLBACK(src, PROC_REF(stun_callback)), (stunned/recovery_constant) * 2 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_STOPPABLE)
+ return
+
+ if(stun_timer != TIMER_ID_NULL)
+ deltimer(stun_timer)
+ stun_timer = TIMER_ID_NULL
+
+// adjust stun if needed, do not call it in adjust stunned
+/mob/living/proc/stun_clock_adjustment()
+ return
+
+/mob/living/proc/Stun(amount)
+ if(status_flags & CANSTUN)
+ stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
+ stun_clock_adjustment()
+ stun_callback_check()
+ return
+
+/mob/living/proc/SetStun(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
+ if(status_flags & CANSTUN)
+ stunned = max(amount,0)
+ stun_clock_adjustment()
+ stun_callback_check()
+ return
+
+/mob/living/proc/AdjustStun(amount)
+ if(status_flags & CANSTUN)
+ stunned = max(stunned + amount,0)
+ stun_callback_check()
+ return
+
+/mob/living/proc/Daze(amount)
+ if(status_flags & CANDAZE)
+ dazed = max(max(dazed,amount),0)
+ return
+
+/mob/living/proc/SetDaze(amount)
+ if(status_flags & CANDAZE)
+ dazed = max(amount,0)
+ return
+
+/mob/living/proc/AdjustDaze(amount)
+ if(status_flags & CANDAZE)
+ dazed = max(dazed + amount,0)
+ return
+
+/mob/living/proc/Slow(amount)
+ if(status_flags & CANSLOW)
+ slowed = max(slowed, amount, 0)
+ return
+
+/mob/living/proc/SetSlow(amount)
+ if(status_flags & CANSLOW)
+ slowed = max(amount,0)
+ return
+
+/mob/living/proc/AdjustSlow(amount)
+ SetSlow(amount + slowed)
+ return
+
+/mob/living/proc/Superslow(amount)
+ if(status_flags & CANSLOW)
+ superslowed = max(superslowed, amount, 0)
+ return
+
+/mob/living/proc/SetSuperslow(amount)
+ if(status_flags & CANSLOW)
+ superslowed = max(amount,0)
+ return
+
+/mob/living/proc/AdjustSuperslow(amount)
+ SetSuperslow(superslowed + amount)
+ return
+
+/mob/living
+ VAR_PRIVATE/knocked_down_timer
+
+/mob/living/proc/knocked_down_callback()
+ REMOVE_TRAIT(src, TRAIT_FLOORED, KNOCKEDDOWN_TRAIT)
+ knocked_down = 0
+ handle_regular_status_updates(FALSE)
+ knocked_down_timer = null
+
+/mob/living/proc/knocked_down_callback_check()
+ if(knocked_down)
+ ADD_TRAIT(src, TRAIT_FLOORED, KNOCKEDDOWN_TRAIT)
+
+ if(knocked_down && knocked_down < recovery_constant)
+ knocked_down_timer = addtimer(CALLBACK(src, PROC_REF(knocked_down_callback)), (knocked_down/recovery_constant) * 2 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_STOPPABLE) // times whatever amount we have per tick
+ return
+
+ if(knocked_down_timer)
+ deltimer(knocked_down_timer)
+ knocked_down_timer = null
+
+/mob/living
+ VAR_PRIVATE/knocked_out_timer
+
+/mob/living/proc/knocked_out_start()
+ return
+
+/mob/living/proc/knocked_out_callback()
+ REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, KNOCKEDOUT_TRAIT)
+ knocked_out = 0
+ handle_regular_status_updates(FALSE)
+ knocked_out_timer = null
+
+/mob/living/proc/knocked_out_callback_check()
+ if(knocked_out)
+ ADD_TRAIT(src, TRAIT_KNOCKEDOUT, KNOCKEDOUT_TRAIT)
+ if(knocked_out && knocked_out < recovery_constant)
+ knocked_out_timer = addtimer(CALLBACK(src, PROC_REF(knocked_out_callback)), (knocked_out/recovery_constant) * 2 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_STOPPABLE) // times whatever amount we have per tick
+ return
+ else if(!knocked_out)
+ //It's been called, and we're probably inconscious, so fix that.
+ knocked_out_callback()
+
+ if(knocked_out_timer)
+ deltimer(knocked_out_timer)
+ knocked_out_timer = null
+
+// adjust knockdown if needed, do not call it in adjust knockdown
+/mob/living/proc/knockdown_clock_adjustment()
+ return
+
+/mob/living/proc/KnockDown(amount, force)
+ if((status_flags & CANKNOCKDOWN) || force)
+ knocked_down = max(max(knocked_down,amount),0)
+ knockdown_clock_adjustment()
+ knocked_down_callback_check()
+ return
+
+/mob/living/proc/SetKnockDown(amount)
+ if(status_flags & CANKNOCKDOWN)
+ knocked_down = max(amount,0)
+ knockdown_clock_adjustment()
+ knocked_down_callback_check()
+ return
+
+/mob/living/proc/AdjustKnockDown(amount)
+ if(status_flags & CANKNOCKDOWN)
+ knocked_down = max(knocked_down + amount,0)
+ knocked_down_callback_check()
+ return
+
+/mob/living/proc/knockout_clock_adjustment()
+ return
+
+/mob/living/proc/KnockOut(amount)
+ if(status_flags & CANKNOCKOUT)
+ knocked_out = max(max(knocked_out,amount),0)
+ knockout_clock_adjustment()
+ knocked_out_callback_check()
+ return
+
+/mob/living/proc/SetKnockOut(amount)
+ if(status_flags & CANKNOCKOUT)
+ knocked_out = max(amount,0)
+ knockout_clock_adjustment()
+ knocked_out_callback_check()
+ return
+
+/mob/living/proc/AdjustKnockOut(amount)
+ if(status_flags & CANKNOCKOUT)
+ knocked_out = max(knocked_out + amount,0)
+ knocked_out_callback_check()
+ return
+
+/mob/living/proc/Sleeping(amount)
+ sleeping = max(max(sleeping,amount),0)
+ return
+
+/mob/living/proc/SetSleeping(amount)
+ sleeping = max(amount,0)
+ return
+
+/mob/living/proc/AdjustSleeping(amount)
+ sleeping = max(sleeping + amount,0)
+ return
+
+/mob/living/proc/Resting(amount)
+ resting = max(max(resting,amount),0)
+ return
+
+/mob/living/proc/SetResting(amount)
+ resting = max(amount,0)
+ return
+/mob/living/proc/AdjustResting(amount)
+ resting = max(resting + amount,0)
+ return
+/mob/living/proc/EyeBlur(amount)
+ eye_blurry = max(max(eye_blurry, amount), 0)
+ update_eye_blur()
+ return
+/mob/living/proc/SetEyeBlur(amount)
+ eye_blurry = max(amount, 0)
+ update_eye_blur()
+ return
+/mob/living/proc/AdjustEyeBlur(amount)
+ eye_blurry = max(eye_blurry + amount, 0)
+ update_eye_blur()
+ return
+
+/mob/living/proc/ReduceEyeBlur(amount)
+ eye_blurry = max(eye_blurry - amount, 0)
+ update_eye_blur()
+ return
+
+///Apply the blurry overlays to a mobs clients screen
+/mob/living/proc/update_eye_blur()
+ if(!client)
+ return
+ var/atom/movable/plane_master_controller/game_plane_master_controller = hud_used.plane_master_controllers[PLANE_MASTERS_GAME]
+
+ if(!eye_blurry)
+ clear_fullscreen("eye_blur", 0.5 SECONDS)
+ game_plane_master_controller.remove_filter("eye_blur")
+ return
+
+ switch(client.prefs?.pain_overlay_pref_level)
+ if(PAIN_OVERLAY_IMPAIR)
+ overlay_fullscreen("eye_blur", /atom/movable/screen/fullscreen/impaired, CEILING(clamp(eye_blurry * 0.3, 1, 6), 1))
+ if(PAIN_OVERLAY_LEGACY)
+ overlay_fullscreen("eye_blur", /atom/movable/screen/fullscreen/blurry)
+ else // PAIN_OVERLAY_BLURRY
+ game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(clamp(eye_blurry * 0.1, 0.6, 3)))
+
+
+/mob/living/proc/TalkStutter(amount)
+ stuttering = max(max(stuttering, amount), 0)
+ return
+
+/mob/living/proc/SetTalkStutter(amount)
+ stuttering = max(amount, 0)
+ return
+
+/mob/living/proc/AdjustTalkStutter(amount)
+ stuttering = max(stuttering + amount,0)
+ return
+
+/mob/living/proc/SetEyeBlind(amount)
+ eye_blind = max(amount, 0)
+ return
+
+/mob/living/proc/AdjustEyeBlind(amount)
+ eye_blind = max(eye_blind + amount, 0)
+ return
+
+/mob/living/proc/ReduceEyeBlind(amount)
+ eye_blind = max(eye_blind - amount, 0)
+ return
+
+/mob/living/proc/AdjustEarDeafness(amount)
+ var/prev_deaf = ear_deaf
+ ear_deaf = max(ear_deaf + amount, 0)
+ if(prev_deaf)
+ if(ear_deaf == 0)
+ on_deafness_loss()
+ else if(ear_deaf)
+ on_deafness_gain()
+
+
+/mob/living/proc/SetEarDeafness(amount)
+ var/prev_deaf = ear_deaf
+ ear_deaf = max(amount, 0)
+ if(prev_deaf)
+ if(ear_deaf == 0)
+ on_deafness_loss()
+ else if(ear_deaf)
+ on_deafness_gain()
+
+/mob/living/proc/on_deafness_gain()
+ to_chat(src, SPAN_WARNING("You notice you can't hear anything... you're deaf!"))
+ SEND_SIGNAL(src, COMSIG_MOB_DEAFENED)
+
+/mob/living/proc/on_deafness_loss()
+ to_chat(src, SPAN_WARNING("You start hearing things again!"))
+ SEND_SIGNAL(src, COMSIG_MOB_REGAINED_HEARING)
// heal ONE limb, organ gets randomly selected from damaged ones.
/mob/living/proc/heal_limb_damage(brute, burn)
@@ -205,9 +498,14 @@
var/mob/living/carbon/human/H = src
H.update_body()
+/mob/living/canface()
+ if(!(mobility_flags & MOBILITY_MOVE))
+ return FALSE // Choice by default, feel free to change
+ return ..()
+
/mob/living/keybind_face_direction(direction)
if(!canface())
return
if(stat >= UNCONSCIOUS)
return
- return ..()
+ face_dir(direction)
diff --git a/code/modules/mob/living/living_verbs.dm b/code/modules/mob/living/living_verbs.dm
index fe95f14182ea..3b6779752989 100644
--- a/code/modules/mob/living/living_verbs.dm
+++ b/code/modules/mob/living/living_verbs.dm
@@ -163,7 +163,7 @@
return
//breaking out of handcuffs & putting out fires
- if(canmove && !knocked_down)
+ if(!is_mob_incapacitated(TRUE))
if(on_fire)
resist_fire()
@@ -179,7 +179,7 @@
if(!iscarbon(src))
return
var/mob/living/carbon/C = src
- if((C.handcuffed || C.legcuffed) && C.canmove && (C.last_special <= world.time))
+ if((C.handcuffed || C.legcuffed) && (C.mobility_flags & MOBILITY_MOVE) && (C.last_special <= world.time))
resist_restraints()
/mob/living/proc/resist_buckle()
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 18d6ece8e238..b4e5b6d855b4 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -101,8 +101,8 @@ var/list/ai_verbs_default = list(
// aiPDA = new/obj/item/device/pda/ai(src)
SetName(pickedName)
anchored = TRUE
- canmove = 0
- density = TRUE
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_INHERENT)
+ set_density(TRUE)
forceMove(loc)
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
diff --git a/code/modules/mob/living/silicon/decoy/decoy.dm b/code/modules/mob/living/silicon/decoy/decoy.dm
index b625b19b172d..5b41078eea4c 100644
--- a/code/modules/mob/living/silicon/decoy/decoy.dm
+++ b/code/modules/mob/living/silicon/decoy/decoy.dm
@@ -4,7 +4,6 @@
icon = 'icons/obj/structures/machinery/ai.dmi'
icon_state = "hydra"
anchored = TRUE
- canmove = 0
density = TRUE //Do not want to see past it.
bound_height = 64 //putting this in so we can't walk through our machine.
bound_width = 96
@@ -23,6 +22,7 @@
ai_headset = new(src)
ai_mob_list += src
real_name = MAIN_AI_SYSTEM
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_INHERENT)
/mob/living/silicon/decoy/ship_ai/Destroy()
QDEL_NULL(ai_headset)
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index b0230bba5dba..2c4a510f4c68 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -18,7 +18,6 @@
use_power()
process_killswitch()
process_locks()
- update_canmove()
/mob/living/silicon/robot/proc/clamp_values()
@@ -79,14 +78,14 @@
death()
if (stat != DEAD) //Alive.
- if (knocked_out || stunned || knocked_down || !has_power) //Stunned etc.
+ if (HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || HAS_TRAIT(src, TRAIT_INCAPACITATED)|| HAS_TRAIT(src, TRAIT_FLOORED) || !has_power) //Stunned etc.
set_stat(UNCONSCIOUS)
if(regular_update)
- if (src.stunned > 0)
+ if (HAS_TRAIT(src, TRAIT_INCAPACITATED))
adjust_effect(-1, STUN)
- if (src.knocked_down > 0)
+ if (HAS_TRAIT(src, TRAIT_FLOORED))
adjust_effect(-1, WEAKEN)
- if (src.knocked_out > 0)
+ if (HAS_TRAIT(src, TRAIT_KNOCKEDOUT))
adjust_effect(-1, PARALYZE)
src.blinded = TRUE
else
@@ -113,8 +112,6 @@
src.ear_damage -= 0.05
src.ear_damage = max(src.ear_damage, 0)
- src.density = !( src.lying )
-
if ((src.sdisabilities & DISABILITY_BLIND))
src.blinded = TRUE
if ((src.sdisabilities & DISABILITY_DEAF))
@@ -271,8 +268,3 @@
to_chat(src, SPAN_DANGER("Weapon Lock Timed Out!"))
weapon_lock = 0
weaponlock_time = 120
-
-/mob/living/silicon/robot/update_canmove()
- if(knocked_out || stunned || knocked_down || buckled || lockcharge || !is_component_functioning("actuator")) canmove = 0
- else canmove = 1
- return canmove
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 4ad29179daec..844cf2b429a8 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -840,7 +840,7 @@ var/list/robot_verbs_default = list(
cleaned_item.clean_blood()
else if(istype(A, /mob/living/carbon/human))
var/mob/living/carbon/human/cleaned_human = A
- if(cleaned_human.lying)
+ if(cleaned_human.body_position)
if(cleaned_human.head)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head(0)
@@ -866,7 +866,7 @@ var/list/robot_verbs_default = list(
src.connected_ai = null
lawupdate = 0
lockcharge = 0
- canmove = 1
+ //canmove = 1 // Yes this will probably break something, whatevver it is
scrambledcodes = 1
//Disconnect it's camera so it's not so easily tracked.
if(src.camera)
diff --git a/code/modules/mob/living/simple_animal/bat.dm b/code/modules/mob/living/simple_animal/bat.dm
index a95d97be6e1a..eea7998bda67 100644
--- a/code/modules/mob/living/simple_animal/bat.dm
+++ b/code/modules/mob/living/simple_animal/bat.dm
@@ -27,4 +27,3 @@
set_stat(CONSCIOUS)
icon_state = "bat"
wander = 1
- canmove = 1
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index fa93399683d8..11064634d498 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -46,7 +46,6 @@
set_stat(CONSCIOUS)
icon_state = "mouse_[body_color]"
wander = 1
- canmove = 1
else if(prob(5))
INVOKE_ASYNC(src, PROC_REF(emote), "snuffles")
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index ffe85017bb28..b060465eb222 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -64,18 +64,18 @@
icon_dead = "Normal [caste_name] Dead"
/mob/living/simple_animal/hostile/alien/update_transform()
- if(lying != lying_prev)
- lying_prev = lying
+ // TODO: Move all this mess outside of update_transform
if(stat == DEAD)
icon_state = "Normal [caste_name] Dead"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position == LYING_DOWN)
+ if((resting || sleeping) && (!is_mob_incapacitated(src) && health > 0))
icon_state = "Normal [caste_name] Sleeping"
else
icon_state = "Normal [caste_name] Knocked Down"
else
icon_state = "Normal [caste_name] Running"
update_wounds()
+ return ..()
/mob/living/simple_animal/hostile/alien/evaluate_target(mob/living/carbon/target)
. = ..()
@@ -114,8 +114,8 @@
if(health > HEALTH_THRESHOLD_DEAD)
if(health_threshold > 3)
wound_icon_carrier.icon_state = "none"
- else if(lying)
- if((resting || sleeping) && (!knocked_down && !knocked_out && health > 0))
+ else if(body_position == LYING_DOWN)
+ if((resting || sleeping) && (!HAS_TRAIT(src, TRAIT_KNOCKEDOUT) && health > 0))
wound_icon_carrier.icon_state = "[caste_name]_rest_[health_threshold]"
else
wound_icon_carrier.icon_state = "[caste_name]_downed_[health_threshold]"
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index b47b14f0d1d5..b285ec11799f 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -125,7 +125,7 @@
if(client)
return 0
- if(!stat && canmove)
+ if(!stat && mobility_flags & MOBILITY_MOVE)
switch(stance)
if(HOSTILE_STANCE_IDLE)
target_mob = FindTarget()
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 0f15bd1d8f7b..f1452d95c294 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -127,7 +127,7 @@
/mob/living/simple_animal/parrot/Topic(href, href_list)
//Can the usr physically do this?
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !in_range(loc, usr))
+ if(usr.is_mob_incapacitated() || !in_range(loc, usr))
return
//Is the usr's mob type able to do this?
@@ -284,7 +284,7 @@
if(client || stat)
return //Lets not force players or dead/incap parrots to move
- if(!isturf(src.loc) || !canmove || buckled)
+ if(!isturf(src.loc) || !(mobility_flags & MOBILITY_MOVE) || buckled)
return //If it can't move, dont let it move. (The buckled check probably isn't necessary thanks to canmove)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 8b1cc1e26be2..3dd9907ce2eb 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -81,8 +81,8 @@
GLOB.dead_mob_list -= src
GLOB.alive_mob_list += src
set_stat(CONSCIOUS)
- lying = 0
- density = TRUE
+// lying = 0
+// density = TRUE
reload_fullscreens()
return 0
@@ -96,11 +96,10 @@
handle_stunned()
handle_knocked_down(TRUE)
handle_knocked_out(TRUE)
- update_canmove()
//Movement
if(!client && !stop_automated_movement && wander && !anchored)
- if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
+ if(isturf(src.loc) && !resting && !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
@@ -361,10 +360,17 @@
..(message, null, verb, nolog = !ckey) //if the animal has a ckey then it will log the message
-/mob/living/simple_animal/update_canmove()
+/mob/living/simple_animal/on_immobilized_trait_gain(datum/source)
. = ..()
- if(!canmove)
- stop_moving()
+ stop_moving()
+
+/mob/living/simple_animal/on_knockedout_trait_gain(datum/source)
+ . = ..()
+ stop_moving()
+
+/mob/living/simple_animal/on_incapacitated_trait_gain(datum/source)
+ . = ..()
+ stop_moving()
/mob/living/simple_animal/proc/stop_moving()
walk_to(src, 0) // stops us dead in our tracks
diff --git a/code/modules/mob/living/simple_animal/slug.dm b/code/modules/mob/living/simple_animal/slug.dm
index e09d2c715e54..3f2ceb57b838 100644
--- a/code/modules/mob/living/simple_animal/slug.dm
+++ b/code/modules/mob/living/simple_animal/slug.dm
@@ -33,7 +33,6 @@
set_stat(CONSCIOUS)
icon_state = "slug_movement"
wander = 1
- canmove = 1
/mob/living/simple_animal/alien_slug/Initialize()
. = ..()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ec8249fdca5c..02a686320b04 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -454,7 +454,7 @@
if(!Adjacent(usr)) return
if(!ishuman(M) && !ismonkey(M)) return
if(!ishuman(src) && !ismonkey(src)) return
- if(M.lying || M.is_mob_incapacitated())
+ if(M.is_mob_incapacitated())
return
if(M.pulling == src && (M.a_intent & INTENT_GRAB) && M.grab_level == GRAB_AGGRESSIVE)
return
@@ -699,7 +699,6 @@ note dizziness decrements automatically in the mob's Life() proc.
// facing verbs
/mob/proc/canface()
- if(!canmove) return 0
if(client.moving) return 0
if(stat==2) return 0
if(anchored) return 0
@@ -707,54 +706,6 @@ note dizziness decrements automatically in the mob's Life() proc.
if(is_mob_restrained()) return 0
return 1
-//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
-/mob/proc/update_canmove()
- var/laid_down = (stat || knocked_down || knocked_out || !has_legs() || resting || (status_flags & FAKEDEATH) || (pulledby && pulledby.grab_level >= GRAB_AGGRESSIVE))
-
- if(laid_down)
- lying = TRUE
- flags_atom &= ~DIRLOCK
- else
- lying = FALSE
- if(buckled)
- if(buckled.buckle_lying)
- lying = TRUE
- flags_atom &= ~DIRLOCK
- else
- lying = FALSE
-
- canmove = !(stunned || frozen)
- if(!can_crawl && lying)
- canmove = FALSE
-
- if(lying_prev != lying)
- if(lying)
- density = FALSE
- add_temp_pass_flags(PASS_MOB_THRU)
- drop_l_hand()
- drop_r_hand()
- SEND_SIGNAL(src, COMSIG_MOB_KNOCKED_DOWN)
- else
- density = TRUE
- SEND_SIGNAL(src, COMSIG_MOB_GETTING_UP)
- remove_temp_pass_flags(PASS_MOB_THRU)
- update_transform()
-
- if(lying)
- //so mob lying always appear behind standing mobs, but dead ones appear behind living ones
- if(pulledby && pulledby.grab_level == GRAB_CARRY)
- layer = ABOVE_MOB_LAYER
- else if (stat == DEAD)
- layer = LYING_DEAD_MOB_LAYER // Dead mobs should layer under living ones
- else if(layer == initial(layer)) //to avoid things like hiding larvas.
- layer = LYING_LIVING_MOB_LAYER
- else if(layer == LYING_DEAD_MOB_LAYER || layer == LYING_LIVING_MOB_LAYER)
- layer = initial(layer)
-
- SEND_SIGNAL(src, COMSIG_MOB_POST_UPDATE_CANMOVE, canmove, laid_down, lying)
-
- return canmove
-
/mob/proc/face_dir(ndir, specific_dir)
if(!canface()) return 0
if(dir != ndir)
@@ -789,22 +740,6 @@ note dizziness decrements automatically in the mob's Life() proc.
/mob/proc/get_species()
return ""
-/// Sets freeze if possible and wasn't already set, returning success
-/mob/proc/freeze()
- if(frozen)
- return FALSE
- frozen = TRUE
- update_canmove()
- return TRUE
-
-/// Attempts to unfreeze mob, returning success
-/mob/proc/unfreeze()
- if(!frozen)
- return FALSE
- frozen = FALSE
- update_canmove()
- return TRUE
-
/mob/proc/flash_weak_pain()
overlay_fullscreen("pain", /atom/movable/screen/fullscreen/pain, 1)
clear_fullscreen("pain")
@@ -937,13 +872,13 @@ note dizziness decrements automatically in the mob's Life() proc.
/mob/living/proc/handle_knocked_down(bypass_client_check = FALSE)
if(knocked_down && (bypass_client_check || client))
- knocked_down = max(knocked_down-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
+ knocked_down = max(knocked_down-1,0)
knocked_down_callback_check()
return knocked_down
/mob/living/proc/handle_knocked_out(bypass_client_check = FALSE)
if(knocked_out && (bypass_client_check || client))
- knocked_out = max(knocked_out-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
+ knocked_out = max(knocked_out-1,0)
knocked_out_callback_check()
return knocked_out
@@ -1136,5 +1071,9 @@ note dizziness decrements automatically in the mob's Life() proc.
/mob/proc/set_stat(new_stat)
if(new_stat == stat)
return
- . = stat //old stat
+ . = stat
stat = new_stat
+ SEND_SIGNAL(src, COMSIG_MOB_STATCHANGE, new_stat, .)
+
+/mob/proc/update_stat()
+ return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 3e765e167ec1..a27d8a6c2bad 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -65,10 +65,6 @@
var/dizziness = 0//Carbon
var/jitteriness = 0//Carbon
var/floatiness = 0
- var/knocked_out = 0
- var/stunned = 0
- var/frozen = 0
- var/knocked_down = 0
var/losebreath = 0.0//Carbon
var/dazed = 0
var/slowed = 0 // X_SLOW_AMOUNT
@@ -95,9 +91,6 @@
var/exploit_record = ""
var/gibbing = FALSE
- var/lying = FALSE
- var/lying_prev = 0
- var/canmove = 1
var/lastpuke = 0
unacidable = FALSE
var/mob_size = MOB_SIZE_HUMAN
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index 39cc5b25e519..48e371f3d544 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -83,21 +83,21 @@
if(GRAB_AGGRESSIVE)
progress_aggressive(user, victim)
-/obj/item/grab/proc/progress_passive(mob/living/carbon/human/user, mob/victim)
+ if(user.grab_level >= GRAB_AGGRESSIVE)
+ ADD_TRAIT(victim, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
+
+/obj/item/grab/proc/progress_passive(mob/living/carbon/human/user, mob/living/victim)
user.grab_level = GRAB_AGGRESSIVE
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25, 1, 7)
user.visible_message(SPAN_WARNING("[user] has grabbed [victim] aggressively!"), null, null, 5)
- victim.update_canmove()
-/obj/item/grab/proc/progress_aggressive(mob/living/carbon/human/user, mob/victim)
+/obj/item/grab/proc/progress_aggressive(mob/living/carbon/human/user, mob/living/victim)
user.grab_level = GRAB_CHOKE
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25, 1, 7)
user.visible_message(SPAN_WARNING("[user] holds [victim] by the neck and starts choking them!"), null, null, 5)
victim.Move(user.loc, get_dir(victim.loc, user.loc))
victim.update_transform(TRUE)
- victim.update_canmove()
-
/obj/item/grab/attack(mob/living/M, mob/living/user)
if(M == grabbed_thing)
attack_self(user)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 56951097a12c..229ce4c5a7f6 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -311,13 +311,12 @@ var/global/list/limb_types_by_name = list(
/mob/proc/is_mob_restrained()
return
+/// Returns if the mob is incapacitated and unable to perform general actions
/mob/proc/is_mob_incapacitated(ignore_restrained)
- return (stat || stunned || knocked_down || knocked_out || (!ignore_restrained && is_mob_restrained()) || status_flags & FAKEDEATH)
-
-
-//returns how many non-destroyed legs the mob has (currently only useful for humans)
-/mob/proc/has_legs()
- return 2
+ // TODO: Replace this by signal/traits entirely eventually
+ // TRAIT_FLOORED being considered incapacitated is a legacy CM Feature that should be removed at some point
+ // note that stat includes knockout via unconscious
+ return (stat || (!ignore_restrained && is_mob_restrained()) || (status_flags & FAKEDEATH) || HAS_TRAIT(src, TRAIT_FLOORED) || HAS_TRAIT(src, TRAIT_INCAPACITATED))
/mob/proc/get_eye_protection()
return EYE_PROTECTION_NONE
@@ -480,7 +479,7 @@ var/global/list/limb_types_by_name = list(
set name = "Pick Up"
set category = "Object"
- if(!canmove || stat || is_mob_restrained() || !Adjacent(pickupify))
+ if(is_mob_incapacitated() || !Adjacent(pickupify))
return
if(world.time <= next_move)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 64253fbac5df..d041db13bfc5 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -95,7 +95,13 @@
mob.next_delay_update = world.time + mob.next_delay_delay
/client/Move(n, direct)
- if(world.time < next_movement || (mob.lying && mob.crawling))
+ var/mob/living/living_mob
+ if(isliving(mob))
+ living_mob = mob
+
+ if(world.time < next_movement)
+ return
+ if(living_mob && living_mob.body_position == LYING_DOWN && mob.crawling)
return
next_move_dir_add = 0
@@ -134,7 +140,11 @@
if(!isliving(mob))
return mob.Move(n, direct)
- if(!mob.canmove || mob.is_mob_incapacitated(TRUE) || (mob.lying && !mob.can_crawl))
+ if(mob.is_mob_incapacitated(TRUE))
+ return
+ if(!(living_mob.mobility_flags & MOBILITY_MOVE))
+ return
+ if(living_mob.body_position == LYING_DOWN && !living_mob.can_crawl)
return
//Check if you are being grabbed and if so attemps to break it
@@ -172,7 +182,7 @@
//We are now going to move
moving = TRUE
mob.move_intentionally = TRUE
- if(mob.lying)
+ if(living_mob && living_mob.body_position == LYING_DOWN)
//check for them not being a limbless blob (only humans have limbs)
if(ishuman(mob))
var/mob/living/carbon/human/human = mob
diff --git a/code/modules/mob/mob_status_procs.dm b/code/modules/mob/mob_status_procs.dm
index b700fad2c136..ced7b7bdaf45 100644
--- a/code/modules/mob/mob_status_procs.dm
+++ b/code/modules/mob/mob_status_procs.dm
@@ -1,301 +1,3 @@
-/mob/var/stun_timer = TIMER_ID_NULL
-
-/mob/proc/stun_callback()
- stunned = 0
- handle_regular_status_updates(FALSE)
- update_canmove()
- if(stun_timer != TIMER_ID_NULL)
- deltimer(stun_timer)
- stun_timer = TIMER_ID_NULL
-
-/mob/proc/stun_callback_check()
- if(stunned && stunned < recovery_constant)
- stun_timer = addtimer(CALLBACK(src, PROC_REF(stun_callback)), (stunned/recovery_constant) * 2 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_STOPPABLE)
- return
-
- if(stun_timer != TIMER_ID_NULL)
- deltimer(stun_timer)
- stun_timer = TIMER_ID_NULL
-
-// adjust stun if needed, do not call it in adjust stunned
-/mob/proc/stun_clock_adjustment()
- return
-
-/mob/proc/Stun(amount)
- if(status_flags & CANSTUN)
- stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
- stun_clock_adjustment()
- stun_callback_check()
- update_canmove()
- return
-
-/mob/proc/SetStun(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
- if(status_flags & CANSTUN)
- stunned = max(amount,0)
- stun_clock_adjustment()
- stun_callback_check()
- update_canmove()
- return
-
-/mob/proc/AdjustStun(amount)
- if(status_flags & CANSTUN)
- stunned = max(stunned + amount,0)
- stun_callback_check()
- update_canmove()
- return
-
-/mob/proc/Daze(amount)
- if(status_flags & CANDAZE)
- dazed = max(max(dazed,amount),0)
- return
-
-/mob/proc/SetDaze(amount)
- if(status_flags & CANDAZE)
- dazed = max(amount,0)
- return
-
-/mob/proc/AdjustDaze(amount)
- if(status_flags & CANDAZE)
- dazed = max(dazed + amount,0)
- return
-
-/mob/proc/Slow(amount)
- if(status_flags & CANSLOW)
- slowed = max(slowed, amount, 0)
- return
-
-/mob/proc/SetSlow(amount)
- if(status_flags & CANSLOW)
- slowed = max(amount,0)
- return
-
-/mob/proc/AdjustSlow(amount)
- SetSlow(amount + slowed)
- return
-
-/mob/proc/Superslow(amount)
- if(status_flags & CANSLOW)
- superslowed = max(superslowed, amount, 0)
- return
-
-/mob/proc/SetSuperslow(amount)
- if(status_flags & CANSLOW)
- superslowed = max(amount,0)
- return
-
-/mob/proc/AdjustSuperslow(amount)
- SetSuperslow(superslowed + amount)
- return
-
-/mob/var/knocked_down_timer
-
-/mob/proc/knocked_down_callback()
- knocked_down = 0
- handle_regular_status_updates(FALSE)
- update_canmove()
- knocked_down_timer = null
-
-/mob/proc/knocked_down_callback_check()
- if(knocked_down && knocked_down < recovery_constant)
- knocked_down_timer = addtimer(CALLBACK(src, PROC_REF(knocked_down_callback)), (knocked_down/recovery_constant) * 2 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_STOPPABLE) // times whatever amount we have per tick
- return
-
- if(knocked_down_timer)
- deltimer(knocked_down_timer)
- knocked_down_timer = null
-
-/mob/var/knocked_out_timer
-
-/mob/proc/knocked_out_start()
- return
-
-/mob/proc/knocked_out_callback()
- knocked_out = 0
- handle_regular_status_updates(FALSE)
- update_canmove()
- knocked_out_timer = null
-
-/mob/proc/knocked_out_callback_check()
- if(knocked_out && knocked_out < recovery_constant)
- knocked_out_start()
- knocked_out_timer = addtimer(CALLBACK(src, PROC_REF(knocked_out_callback)), (knocked_out/recovery_constant) * 2 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE|TIMER_STOPPABLE) // times whatever amount we have per tick
- return
- else if(!knocked_out)
- //It's been called, and we're probably inconscious, so fix that.
- knocked_out_callback()
-
- if(knocked_out_timer)
- deltimer(knocked_out_timer)
- knocked_out_timer = null
-
-// adjust knockdown if needed, do not call it in adjust knockdown
-/mob/proc/knockdown_clock_adjustment()
- return
-
-/mob/proc/KnockDown(amount, force)
- if((status_flags & CANKNOCKDOWN) || force)
- knocked_down = max(max(knocked_down,amount),0)
- knockdown_clock_adjustment()
- knocked_down_callback_check()
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/SetKnockDown(amount)
- if(status_flags & CANKNOCKDOWN)
- knocked_down = max(amount,0)
- knockdown_clock_adjustment()
- knocked_down_callback_check()
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/AdjustKnockDown(amount)
- if(status_flags & CANKNOCKDOWN)
- knocked_down = max(knocked_down + amount,0)
- knocked_down_callback_check()
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/knockout_clock_adjustment()
- return
-
-/mob/proc/KnockOut(amount)
- if(status_flags & CANKNOCKOUT)
- knocked_out = max(max(knocked_out,amount),0)
- knockout_clock_adjustment()
- knocked_out_callback_check()
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/SetKnockOut(amount)
- if(status_flags & CANKNOCKOUT)
- knocked_out = max(amount,0)
- knockout_clock_adjustment()
- knocked_out_callback_check()
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/AdjustKnockOut(amount)
- if(status_flags & CANKNOCKOUT)
- knocked_out = max(knocked_out + amount,0)
- knocked_out_callback_check()
- update_canmove() //updates lying, canmove and icons
- return
-
-/mob/proc/Sleeping(amount)
- sleeping = max(max(sleeping,amount),0)
- return
-
-/mob/proc/SetSleeping(amount)
- sleeping = max(amount,0)
- return
-
-/mob/proc/AdjustSleeping(amount)
- sleeping = max(sleeping + amount,0)
- return
-
-/mob/proc/Resting(amount)
- resting = max(max(resting,amount),0)
- return
-
-/mob/proc/SetResting(amount)
- resting = max(amount,0)
- return
-
-/mob/proc/AdjustResting(amount)
- resting = max(resting + amount,0)
- return
-
-/mob/proc/EyeBlur(amount)
- eye_blurry = max(max(eye_blurry, amount), 0)
- update_eye_blur()
- return
-
-/mob/proc/SetEyeBlur(amount)
- eye_blurry = max(amount, 0)
- update_eye_blur()
- return
-
-/mob/proc/AdjustEyeBlur(amount)
- eye_blurry = max(eye_blurry + amount, 0)
- update_eye_blur()
- return
-
-/mob/proc/ReduceEyeBlur(amount)
- eye_blurry = max(eye_blurry - amount, 0)
- update_eye_blur()
- return
-
-///Apply the blurry overlays to a mobs clients screen
-/mob/proc/update_eye_blur()
- if(!client)
- return
- var/atom/movable/plane_master_controller/game_plane_master_controller = hud_used.plane_master_controllers[PLANE_MASTERS_GAME]
-
- if(!eye_blurry)
- clear_fullscreen("eye_blur", 0.5 SECONDS)
- game_plane_master_controller.remove_filter("eye_blur")
- return
-
- switch(client.prefs?.pain_overlay_pref_level)
- if(PAIN_OVERLAY_IMPAIR)
- overlay_fullscreen("eye_blur", /atom/movable/screen/fullscreen/impaired, CEILING(clamp(eye_blurry * 0.3, 1, 6), 1))
- if(PAIN_OVERLAY_LEGACY)
- overlay_fullscreen("eye_blur", /atom/movable/screen/fullscreen/blurry)
- else // PAIN_OVERLAY_BLURRY
- game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(clamp(eye_blurry * 0.1, 0.6, 3)))
-
-
-/mob/proc/TalkStutter(amount)
- stuttering = max(max(stuttering, amount), 0)
- return
-
-/mob/proc/SetTalkStutter(amount)
- stuttering = max(amount, 0)
- return
-
-/mob/proc/AdjustTalkStutter(amount)
- stuttering = max(stuttering + amount,0)
- return
-
-/mob/proc/SetEyeBlind(amount)
- eye_blind = max(amount, 0)
- return
-
-/mob/proc/AdjustEyeBlind(amount)
- eye_blind = max(eye_blind + amount, 0)
- return
-
-/mob/proc/ReduceEyeBlind(amount)
- eye_blind = max(eye_blind - amount, 0)
- return
-
-/mob/proc/AdjustEarDeafness(amount)
- var/prev_deaf = ear_deaf
- ear_deaf = max(ear_deaf + amount, 0)
- if(prev_deaf)
- if(ear_deaf == 0)
- on_deafness_loss()
- else if(ear_deaf)
- on_deafness_gain()
-
-
-/mob/proc/SetEarDeafness(amount)
- var/prev_deaf = ear_deaf
- ear_deaf = max(amount, 0)
- if(prev_deaf)
- if(ear_deaf == 0)
- on_deafness_loss()
- else if(ear_deaf)
- on_deafness_gain()
-
-/mob/proc/on_deafness_gain()
- to_chat(src, SPAN_WARNING("You notice you can't hear anything... you're deaf!"))
- SEND_SIGNAL(src, COMSIG_MOB_DEAFENED)
-
-/mob/proc/on_deafness_loss()
- to_chat(src, SPAN_WARNING("You start hearing things again!"))
- SEND_SIGNAL(src, COMSIG_MOB_REGAINED_HEARING)
-
/mob/proc/getBruteLoss()
return
diff --git a/code/modules/mob/mob_verbs.dm b/code/modules/mob/mob_verbs.dm
index 19296ba90b20..67d45092a4d8 100644
--- a/code/modules/mob/mob_verbs.dm
+++ b/code/modules/mob/mob_verbs.dm
@@ -222,6 +222,7 @@
set category = "IC"
if(pulling)
+ REMOVE_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
var/mob/M = pulling
pulling.pulledby = null
pulling = null
@@ -244,4 +245,3 @@
//so we must undo it here so the victim can move right away
M.client.next_movement = world.time
M.update_transform(TRUE)
- M.update_canmove()
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index dda2487c24d9..0d4af805d253 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -6,7 +6,6 @@
invisibility = 101
density = FALSE
- canmove = FALSE
anchored = TRUE
universal_speak = TRUE
stat = DEAD
@@ -15,6 +14,7 @@
. = ..()
GLOB.new_player_list += src
GLOB.dead_mob_list -= src
+ ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_INHERENT)
/mob/new_player/Destroy()
if(ready)
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index dcb478d0fc7c..51c9ba9e13fd 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -7,8 +7,8 @@
drop_inv_item_on_ground(W)
regenerate_icons()
monkeyizing = 1
- canmove = 0
- stunned = 1
+ anchored = TRUE
+ ADD_TRAIT(src, TRAIT_INCAPACITATED, "Terminal Monkeyziation")
icon = null
invisibility = 101
for(var/t in limbs)
@@ -68,7 +68,7 @@
for(var/obj/item/W in src)
drop_inv_item_on_ground(W)
monkeyizing = 1
- canmove = 0
+ ADD_TRAIT(src, TRAIT_INCAPACITATED, "Terminal Monkeyziation")
icon = null
invisibility = 101
return ..()
@@ -85,7 +85,7 @@
drop_inv_item_on_ground(W)
regenerate_icons()
monkeyizing = 1
- canmove = 0
+ ADD_TRAIT(src, TRAIT_INCAPACITATED, "Terminal Monkeyziation")
icon = null
invisibility = 101
for(var/t in limbs)
@@ -131,7 +131,7 @@
drop_inv_item_on_ground(W)
regenerate_icons()
monkeyizing = 1
- canmove = 0
+ ADD_TRAIT(src, TRAIT_INCAPACITATED, "Terminal Monkeyziation")
icon = null
invisibility = 101
for(var/t in limbs)
@@ -186,28 +186,6 @@
qdel(src)
return
-/mob/living/carbon/human/proc/corgize()
- if (monkeyizing)
- return
- for(var/obj/item/W in src)
- drop_inv_item_on_ground(W)
- regenerate_icons()
- monkeyizing = 1
- canmove = 0
- icon = null
- invisibility = 101
- for(var/t in limbs) //this really should not be necessary
- qdel(t)
-
- var/mob/living/simple_animal/corgi/new_corgi = new /mob/living/simple_animal/corgi (loc)
- new_corgi.a_intent = INTENT_HARM
- new_corgi.key = key
- if(new_corgi.client) new_corgi.client.change_view(world_view_size)
-
- to_chat(new_corgi, "You are now a Corgi. Yap Yap!")
- qdel(src)
- return
-
/mob/living/carbon/human/Animalize()
var/list/mobtypes = typesof(/mob/living/simple_animal)
@@ -224,7 +202,7 @@
regenerate_icons()
monkeyizing = 1
- canmove = 0
+ ADD_TRAIT(src, TRAIT_INCAPACITATED, "Terminal Monkeyziation")
icon = null
invisibility = 101
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index ce01931f5daf..69263ed02e3f 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -177,9 +177,13 @@ nanoui is used to open and update nano browser uis
close()
return
+ var/mob/living/living_user
+ if(isliving(user))
+ living_user = user
+
if ((allowed_user_stat > -1) && (user.stat > allowed_user_stat))
set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility)
- else if (user.is_mob_restrained() || user.lying)
+ else if (user.is_mob_restrained() || (living_user && living_user.body_position == LYING_DOWN))
set_status(STATUS_UPDATE, push_update) // update only (orange visibility)
else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0
set_status(STATUS_DISABLED, push_update) // interactive (green visibility)
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index dbd490792e8f..b62161b802c1 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -213,7 +213,7 @@
// Check if we're looking at a mob that's lying down
if(istype(cur_atom, /mob/living))
var/mob/living/cur_mob = cur_atom
- if(!isxeno(cur_mob) && cur_mob.lying) //xenos don't use icon rotatin for lying.
+ if(!isxeno(cur_mob) && cur_mob.body_position == LYING_DOWN) //xenos don't use icon rotatin for lying.
cur_icon.BecomeLying()
// Calculate where we are relative to the center of the photo
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index fc3f213fff35..bce7051abb1c 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -1000,7 +1000,7 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
SEND_SIGNAL(user, COMSIG_MOB_APC_POWER_PULSE, src)
addtimer(VARSET_CALLBACK(src, shorted, FALSE), 2 MINUTES)
-/obj/structure/machinery/power/apc/proc/can_use(mob/user as mob, loud = 0) //used by attack_hand() and Topic()
+/obj/structure/machinery/power/apc/proc/can_use(mob/living/user as mob, loud = 0) //used by attack_hand() and Topic()
if(user.client && user.client.remote_control)
return TRUE
@@ -1016,7 +1016,7 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
if(user.is_mob_restrained())
to_chat(user, SPAN_WARNING("You must have free hands to use [src]."))
return 0
- if(user.lying)
+ if(user.body_position == LYING_DOWN)
to_chat(user, SPAN_WARNING("You can't reach [src]!"))
return 0
autoflag = 5
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 9d16574aa9da..950b4bdf614c 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -1404,7 +1404,7 @@ and you're good to go.
var/damage_buff = BASE_BULLET_DAMAGE_MULT
//if target is lying or unconscious - add damage bonus
- if(attacked_mob.lying == TRUE || attacked_mob.stat == UNCONSCIOUS)
+ if(!(attacked_mob.mobility_flags & MOBILITY_STAND) || attacked_mob.stat == UNCONSCIOUS)
damage_buff += BULLET_DAMAGE_MULT_TIER_4
projectile_to_fire.damage *= damage_buff //Multiply the damage for point blank.
if(bullets_fired == 1) //First shot gives the PB message.
@@ -1428,7 +1428,7 @@ and you're good to go.
projectile_to_fire.give_bullet_traits(BP)
if(bullets_fired > 1)
BP.original = attacked_mob //original == the original target of the projectile. If the target is downed and this isn't set, the projectile will try to fly over it. Of course, it isn't going anywhere, but it's the principle of the thing. Very embarrassing.
- if(!BP.handle_mob(attacked_mob) && attacked_mob.lying) //This is the 'handle impact' proc for a flying projectile, including hit RNG, on_hit_mob and bullet_act. If it misses, it doesn't go anywhere. We'll pretend it slams into the ground or punches a hole in the ceiling, because trying to make it bypass the xeno or shoot from the tile beyond it is probably more spaghet than my life is worth.
+ if(!BP.handle_mob(attacked_mob) && attacked_mob.body_position == LYING_DOWN) //This is the 'handle impact' proc for a flying projectile, including hit RNG, on_hit_mob and bullet_act. If it misses, it doesn't go anywhere. We'll pretend it slams into the ground or punches a hole in the ceiling, because trying to make it bypass the xeno or shoot from the tile beyond it is probably more spaghet than my life is worth.
if(BP.ammo.sound_bounce)
playsound(attacked_mob.loc, BP.ammo.sound_bounce, 35, 1)
attacked_mob.visible_message(SPAN_AVOIDHARM("[BP] slams into [get_turf(attacked_mob)]!"), //Managing to miss an immobile target flat on the ground deserves some recognition, don't you think?
@@ -1441,7 +1441,7 @@ and you're good to go.
if(bullets_fired > 1)
projectile_to_fire.original = attacked_mob
- if(!projectile_to_fire.handle_mob(attacked_mob) && attacked_mob.lying)
+ if(!projectile_to_fire.handle_mob(attacked_mob) && attacked_mob.body_position == LYING_DOWN)
if(projectile_to_fire.ammo.sound_bounce)
playsound(attacked_mob.loc, projectile_to_fire.ammo.sound_bounce, 35, 1)
attacked_mob.visible_message(SPAN_AVOIDHARM("[projectile_to_fire] slams into [get_turf(attacked_mob)]!"),
diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm
index 20781639a579..e08db17db2ac 100644
--- a/code/modules/projectiles/gun_attachables.dm
+++ b/code/modules/projectiles/gun_attachables.dm
@@ -2671,7 +2671,7 @@ Defined in conflicts.dm of the #defines folder.
/obj/item/attachable/attached_gun/grenade/unique_action(mob/user)
if(!ishuman(usr))
return
- if(!user.canmove || user.stat || user.is_mob_restrained() || !user.loc || !isturf(usr.loc))
+ if(user.is_mob_incapacitated() || !isturf(usr.loc))
to_chat(user, SPAN_WARNING("Not right now."))
return
diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm
index ba5f8e491590..8e73124a8b92 100644
--- a/code/modules/projectiles/gun_helpers.dm
+++ b/code/modules/projectiles/gun_helpers.dm
@@ -462,7 +462,7 @@ DEFINES in setup.dm, referenced here.
/obj/item/weapon/gun/proc/get_active_firearm(mob/user, restrictive = TRUE)
if(!ishuman(usr))
return
- if(!user.canmove || user.stat || user.is_mob_restrained() || !user.loc || !isturf(usr.loc))
+ if(user.is_mob_incapacitated() || !isturf(usr.loc))
to_chat(user, SPAN_WARNING("Not right now."))
return
diff --git a/code/modules/projectiles/guns/specialist/launcher/rocket_launcher.dm b/code/modules/projectiles/guns/specialist/launcher/rocket_launcher.dm
index 6d998002134c..356d0e6c3b48 100644
--- a/code/modules/projectiles/guns/specialist/launcher/rocket_launcher.dm
+++ b/code/modules/projectiles/guns/specialist/launcher/rocket_launcher.dm
@@ -190,7 +190,7 @@
smoke.start()
playsound(src, 'sound/weapons/gun_rocketlauncher.ogg', 100, TRUE, 10)
for(var/mob/living/carbon/C in backblast_loc)
- if(!C.lying && !HAS_TRAIT(C, TRAIT_EAR_PROTECTION)) //Have to be standing up to get the fun stuff
+ if(C.body_position == STANDING_UP && !HAS_TRAIT(C, TRAIT_EAR_PROTECTION)) //Have to be standing up to get the fun stuff
C.apply_damage(15, BRUTE) //The shockwave hurts, quite a bit. It can knock unarmored targets unconscious in real life
C.apply_effect(4, STUN) //For good measure
C.apply_effect(6, STUTTER)
@@ -362,7 +362,7 @@
smoke.start()
playsound(src, 'sound/weapons/gun_rocketlauncher.ogg', 100, TRUE, 10)
for(var/mob/living/carbon/C in backblast_loc)
- if(!C.lying && !HAS_TRAIT(C, TRAIT_EAR_PROTECTION)) //Have to be standing up to get the fun stuff
+ if(C.body_position == STANDING_UP && !HAS_TRAIT(C, TRAIT_EAR_PROTECTION)) //Have to be standing up to get the fun stuff
C.apply_damage(15, BRUTE) //The shockwave hurts, quite a bit. It can knock unarmored targets unconscious in real life
C.apply_effect(4, STUN) //For good measure
C.apply_effect(6, STUTTER)
diff --git a/code/modules/projectiles/guns/specialist/sniper.dm b/code/modules/projectiles/guns/specialist/sniper.dm
index 17a2c0f26887..59b93275ca9a 100644
--- a/code/modules/projectiles/guns/specialist/sniper.dm
+++ b/code/modules/projectiles/guns/specialist/sniper.dm
@@ -75,7 +75,7 @@
/datum/action/item_action/specialist/aimed_shot/can_use_action()
var/mob/living/carbon/human/H = owner
- if(istype(H) && !H.is_mob_incapacitated() && !H.lying && (holder_item == H.r_hand || holder_item || H.l_hand))
+ if(istype(H) && !H.is_mob_incapacitated() && (holder_item == H.r_hand || holder_item || H.l_hand))
return TRUE
/datum/action/item_action/specialist/aimed_shot/proc/use_ability(atom/A)
@@ -450,7 +450,7 @@
. = ..()
if(.)
var/mob/living/carbon/human/PMC_sniper = user
- if(PMC_sniper.lying == 0 && !istype(PMC_sniper.wear_suit,/obj/item/clothing/suit/storage/marine/smartgunner/veteran/pmc) && !istype(PMC_sniper.wear_suit,/obj/item/clothing/suit/storage/marine/veteran))
+ if(PMC_sniper.body_position == STANDING_UP && !istype(PMC_sniper.wear_suit,/obj/item/clothing/suit/storage/marine/smartgunner/veteran/pmc) && !istype(PMC_sniper.wear_suit,/obj/item/clothing/suit/storage/marine/veteran))
PMC_sniper.visible_message(SPAN_WARNING("[PMC_sniper] is blown backwards from the recoil of the [src.name]!"),SPAN_HIGHDANGER("You are knocked prone by the blowback!"))
step(PMC_sniper,turn(PMC_sniper.dir,180))
PMC_sniper.apply_effect(5, WEAKEN)
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index adb97e3a1c43..4ed142d12aee 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -517,7 +517,7 @@
X.behavior_delegate.on_hitby_projectile(ammo)
. = TRUE
- else if(!L.lying)
+ else if(L.body_position != LYING_DOWN)
animatation_displace_reset(L)
if(ammo.sound_miss) playsound_client(L.client, ammo.sound_miss, get_turf(L), 75, TRUE)
L.visible_message(SPAN_AVOIDHARM("[src] misses [L]!"),
@@ -766,7 +766,7 @@
//mobs use get_projectile_hit_chance instead of get_projectile_hit_boolean
/mob/living/proc/get_projectile_hit_chance(obj/projectile/P)
- if(lying && src != P.original)
+ if(body_position == LYING_DOWN && src != P.original)
return FALSE
var/ammo_flags = P.ammo.flags_ammo_behavior | P.projectile_override_flags
if(ammo_flags & AMMO_XENO)
@@ -775,7 +775,7 @@
. = P.get_effective_accuracy()
- if(lying && stat)
+ if(body_position == LYING_DOWN && stat)
. += 15 //Bonus hit against unconscious people.
if(isliving(P.firer))
diff --git a/code/modules/reagents/chemistry_machinery/acid_harness.dm b/code/modules/reagents/chemistry_machinery/acid_harness.dm
index ae54474c3aed..52a1a5f13bd7 100644
--- a/code/modules/reagents/chemistry_machinery/acid_harness.dm
+++ b/code/modules/reagents/chemistry_machinery/acid_harness.dm
@@ -443,7 +443,7 @@
else if(inject_conditions & ACID_SCAN_CONDITION_DEFIB && vitals_scan < ACID_VITALS_DEAD && last_vitals_scan & ACID_SCAN_CONDITION_DEATH)
condition_scan |= ACID_SCAN_CONDITION_DEFIB //If we were previously dead and are now alive, we assume we got defibbed
- if(inject_conditions & ACID_SCAN_CONDITION_CONCUSSION && (user.knocked_down || user.knocked_out))
+ if(inject_conditions & ACID_SCAN_CONDITION_CONCUSSION && (HAS_TRAIT(src, TRAIT_KNOCKEDOUT) || HAS_TRAIT(src, TRAIT_FLOORED)))
condition_scan |= ACID_SCAN_CONDITION_CONCUSSION
if(inject_conditions & ACID_SCAN_CONDITION_INTOXICATION && (user.dazed || user.slowed || user.confused || user.drowsyness || user.dizziness || user.druggy))
diff --git a/code/modules/reagents/chemistry_properties/prop_neutral.dm b/code/modules/reagents/chemistry_properties/prop_neutral.dm
index d420623879ce..b3ec6620fb04 100644
--- a/code/modules/reagents/chemistry_properties/prop_neutral.dm
+++ b/code/modules/reagents/chemistry_properties/prop_neutral.dm
@@ -199,8 +199,9 @@
M.druggy = min(M.druggy + 0.5 * potency * delta_time, potency * 10)
/datum/chem_property/neutral/hallucinogenic/process_overdose(mob/living/M, potency = 1, delta_time)
- if(isturf(M.loc) && !istype(M.loc, /turf/open/space) && M.canmove && !M.is_mob_restrained())
- step(M, pick(cardinal))
+ // Disabled automove because it's antiquated and won't work properly. Use Move() for this probably
+ //if(isturf(M.loc) && !istype(M.loc, /turf/open/space) && M.canmove && !M.is_mob_restrained())
+ // step(M, pick(cardinal))
M.hallucination += 10
M.make_jittery(5)
diff --git a/code/modules/reagents/chemistry_properties/prop_positive.dm b/code/modules/reagents/chemistry_properties/prop_positive.dm
index 971051e9bf88..8bf7eadc5d77 100644
--- a/code/modules/reagents/chemistry_properties/prop_positive.dm
+++ b/code/modules/reagents/chemistry_properties/prop_positive.dm
@@ -455,7 +455,7 @@
if(prob(10 * delta_time))
to_chat(M, SPAN_WARNING("You feel like you have the worst brain freeze ever!"))
M.apply_effect(20, PARALYZE)
- M.stunned = max(M.stunned,21)
+ M.apply_effect(20, STUN)
/datum/chem_property/positive/neurocryogenic/process_overdose(mob/living/M, potency = 1, delta_time)
M.bodytemperature = max(M.bodytemperature - 2.5 * potency * delta_time,0)
diff --git a/code/modules/reagents/chemistry_reagents/drink.dm b/code/modules/reagents/chemistry_reagents/drink.dm
index 3bd7336c32b6..66ce0844556b 100644
--- a/code/modules/reagents/chemistry_reagents/drink.dm
+++ b/code/modules/reagents/chemistry_reagents/drink.dm
@@ -555,7 +555,8 @@
/datum/reagent/neurotoxin/on_mob_life(mob/living/carbon/M)
. = ..()
if(!.) return
- M.knocked_down = max(M.knocked_down, 3)
+ if(!HAS_TRAIT(src, TRAIT_FLOORED))
+ M.apply_effect(5, WEAKEN)
if(!data) data = 1
data++
M.dizziness +=6
diff --git a/code/modules/reagents/chemistry_reagents/toxin.dm b/code/modules/reagents/chemistry_reagents/toxin.dm
index 6ffd14ea8ae3..d9be565a85b2 100644
--- a/code/modules/reagents/chemistry_reagents/toxin.dm
+++ b/code/modules/reagents/chemistry_reagents/toxin.dm
@@ -113,6 +113,7 @@
if(!. || deleted)
return
M.status_flags |= FAKEDEATH
+ ADD_TRAIT(M, TRAIT_IMMOBILIZED, FAKEDEATH_TRAIT)
M.apply_damage(0.5*REM, OXY)
M.apply_effect(2, WEAKEN)
M.silent = max(M.silent, 10)
@@ -125,6 +126,7 @@
var/mob/living/holder_mob = .
holder_mob.status_flags &= ~FAKEDEATH
+ REMOVE_TRAIT(holder_mob, TRAIT_IMMOBILIZED, FAKEDEATH_TRAIT)
/datum/reagent/toxin/mindbreaker
name = "Mindbreaker Toxin"
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index b4b4f68ed99d..429f56003286 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -112,7 +112,7 @@
// attack with hand, move pulled object onto conveyor
/obj/structure/machinery/conveyor/attack_hand(mob/user as mob)
- if ((!( user.canmove ) || user.is_mob_restrained() || !( user.pulling )))
+ if (( user.is_mob_incapacitated() || !( user.pulling )))
return
if (user.pulling.anchored)
return
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 2c7401ac278c..1af940dcbd43 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -222,21 +222,20 @@
///Attempt to move while inside
/obj/structure/machinery/disposal/relaymove(mob/user)
- if(user.stat || user.stunned || user.knocked_down || flushing)
+ if(user.is_mob_incapacitated(TRUE) || flushing)
return FALSE
if(user.loc == src)
go_out(user)
return TRUE
///Leave the disposal
-/obj/structure/machinery/disposal/proc/go_out(mob/user)
+/obj/structure/machinery/disposal/proc/go_out(mob/living/user)
if(user.client)
user.client.eye = user.client.mob
user.client.perspective = MOB_PERSPECTIVE
user.forceMove(loc)
- user.stunned = max(user.stunned, 2) //Action delay when going out of a bin
- user.update_canmove() //Force the delay to go in action immediately
- if(!user.lying)
+ user.apply_effect(2, STUN)
+ if(user.mobility_flags & MOBILITY_MOVE)
user.visible_message(SPAN_WARNING("[user] suddenly climbs out of [src]!"),
SPAN_WARNING("You climb out of [src] and get your bearings!"))
update()
@@ -302,13 +301,11 @@
for(var/atom/movable/AM in src)
AM.forceMove(loc)
AM.pipe_eject(0)
- if(ismob(AM))
- var/mob/M = AM
- M.stunned = max(M.stunned, 2) //Action delay when going out of a bin
- M.update_canmove() //Force the delay to go in action immediately
- if(!M.lying)
- M.visible_message(SPAN_WARNING("[M] is suddenly pushed out of [src]!"),
- SPAN_WARNING("You get pushed out of [src] and get your bearings!"))
+ if(isliving(AM))
+ var/mob/living/M = AM
+ M.apply_effect(2, STUN)
+ M.visible_message(SPAN_WARNING("[M] is suddenly pushed out of [src]!"),
+ SPAN_WARNING("You get pushed out of [src] and get your bearings!"))
update()
///Pipe affected by explosion
diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm
index dccdfad920f4..da1923730e4e 100644
--- a/code/modules/shuttles/shuttle_console.dm
+++ b/code/modules/shuttles/shuttle_console.dm
@@ -82,8 +82,6 @@ GLOBAL_LIST_EMPTY(shuttle_controls)
user.visible_message(SPAN_NOTICE("[user] starts to type on the [src]."),
SPAN_NOTICE("You try to take back the control over the shuttle. It will take around 3 minutes."))
if(do_after(user, 3 MINUTES, INTERRUPT_ALL, BUSY_ICON_FRIENDLY))
- if(user.lying)
- return 0
shuttle.last_locked = world.time
shuttle.queen_locked = 0
shuttle.last_door_override = world.time
diff --git a/code/modules/sorokyne/sorokyne_cold_water.dm b/code/modules/sorokyne/sorokyne_cold_water.dm
index adf7e3de6228..345014a1e460 100644
--- a/code/modules/sorokyne/sorokyne_cold_water.dm
+++ b/code/modules/sorokyne/sorokyne_cold_water.dm
@@ -48,13 +48,13 @@
var/dam_amount = COLD_WATER_DAMAGE
if(issynth(M) || isyautja(M))
dam_amount -= 0.5
- if(M.lying)
- M.apply_damage(5*dam_amount,BURN)
- else
+ if(M.body_position == STANDING_UP)
M.apply_damage(dam_amount,BURN,"l_leg")
M.apply_damage(dam_amount,BURN,"l_foot")
M.apply_damage(dam_amount,BURN,"r_leg")
M.apply_damage(dam_amount,BURN,"r_foot")
+ else
+ M.apply_damage(5*dam_amount,BURN)
if (ishuman(M))
if (M.bodytemperature > MINIMUM_TEMP)
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 8b7506c9b7b8..706b28d0e94e 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -43,7 +43,7 @@
continue
//Lying and self-surgery checks.
- if(surgeryloop.lying_required && !target.lying)
+ if(surgeryloop.lying_required && target.body_position != LYING_DOWN)
continue
if(!surgeryloop.self_operable && target == user)
continue
@@ -134,7 +134,7 @@
[target_zone == "r_hand"||target_zone == "l_hand" ? "hand":"arm"] you're using!"))
return TRUE
- if(surgeryinstance.lying_required && !target.lying)
+ if(surgeryinstance.lying_required && target.body_position != LYING_DOWN)
return TRUE
if(surgery_limb)
diff --git a/code/modules/surgery/surgery_procedure.dm b/code/modules/surgery/surgery_procedure.dm
index 1e11516a8079..8620c557eb4b 100644
--- a/code/modules/surgery/surgery_procedure.dm
+++ b/code/modules/surgery/surgery_procedure.dm
@@ -90,7 +90,7 @@
to_chat(user, SPAN_WARNING("You can't operate on [target], \he is being carried by [target.pulledby]!"))
return FALSE
- if(lying_required && !target.lying)
+ if(lying_required && target.body_position != LYING_DOWN)
to_chat(user, SPAN_WARNING("[user == target ? "You need" : "[target] needs"] to be lying down for this operation!"))
return FALSE
diff --git a/code/modules/tgui/status_composers.dm b/code/modules/tgui/status_composers.dm
index 6d7b5897863e..ba1b29d8152e 100644
--- a/code/modules/tgui/status_composers.dm
+++ b/code/modules/tgui/status_composers.dm
@@ -56,17 +56,6 @@
/mob/living/silicon/proc/get_ui_access(atom/source)
return UI_INTERACTIVE // Ubiquitous networking. Do not abuse.
-/// Returns UI_INTERACTIVE if the user is conscious and lying down.
-/// Returns UI_UPDATE otherwise.
-/proc/ui_status_user_is_conscious_and_lying_down(mob/user)
- if (!isliving(user))
- return UI_UPDATE
-
- var/mob/living/living_user = user
- return (living_user.lying && living_user.stat == CONSCIOUS) \
- ? UI_INTERACTIVE \
- : UI_UPDATE
-
/// Return UI_INTERACTIVE if the user is strictly adjacent to the target atom, whether they can see it or not.
/// Return UI_CLOSE otherwise.
/proc/ui_status_user_strictly_adjacent(mob/user, atom/target)
diff --git a/code/modules/vehicles/interior/interactable/seats.dm b/code/modules/vehicles/interior/interactable/seats.dm
index 3e298ba48f1a..ebd002ba0c76 100644
--- a/code/modules/vehicles/interior/interactable/seats.dm
+++ b/code/modules/vehicles/interior/interactable/seats.dm
@@ -376,14 +376,14 @@
//if both seats on same tile have buckled mob, we become dense, otherwise, not dense.
if(buckled_mob)
if(VS.buckled_mob)
- buckled_mob.density = TRUE
- VS.buckled_mob.density = TRUE
+ REMOVE_TRAIT(buckled_mob, TRAIT_UNDENSE, DOUBLE_SEATS_TRAIT)
+ REMOVE_TRAIT(VS.buckled_mob, TRAIT_UNDENSE, DOUBLE_SEATS_TRAIT)
else
- buckled_mob.density = FALSE
+ ADD_TRAIT(buckled_mob, TRAIT_UNDENSE, DOUBLE_SEATS_TRAIT)
else
if(VS.buckled_mob)
- VS.buckled_mob.density = FALSE
- M.density = TRUE
+ ADD_TRAIT(VS.buckled_mob, TRAIT_UNDENSE, DOUBLE_SEATS_TRAIT)
+ REMOVE_TRAIT(M, TRAIT_UNDENSE, DOUBLE_SEATS_TRAIT)
break
handle_rotation()
@@ -392,7 +392,6 @@
if(buckled_mob && buckled_mob.buckled == src)
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
- buckled_mob.update_canmove()
var/M = buckled_mob
buckled_mob = null
diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles/train.dm
index 92358a1e0f27..cbad4535df72 100644
--- a/code/modules/vehicles/train.dm
+++ b/code/modules/vehicles/train.dm
@@ -54,8 +54,8 @@
//-------------------------------------------
-/obj/vehicle/train/MouseDrop_T(atom/movable/C, mob/user as mob)
- if(user.buckled || user.stat || user.is_mob_restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C) || (user == C && !user.canmove))
+/obj/vehicle/train/MouseDrop_T(atom/movable/C, mob/living/user as mob)
+ if(user.buckled || user.stat || user.is_mob_restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C) || (user == C && !(user.mobility_flags & MOBILITY_MOVE)))
return
if(istype(C,/obj/vehicle/train))
latch(C, user)
@@ -71,7 +71,7 @@
if(!istype(usr, /mob/living/carbon/human))
return
- if(!usr.canmove || usr.stat || usr.is_mob_restrained() || !Adjacent(usr))
+ if(usr.is_mob_incapacitated() || !Adjacent(usr))
return
unattach(usr)
diff --git a/code/modules/vehicles/van/van.dm b/code/modules/vehicles/van/van.dm
index fdb2f397bb2e..c4aa64360ec0 100644
--- a/code/modules/vehicles/van/van.dm
+++ b/code/modules/vehicles/van/van.dm
@@ -92,13 +92,13 @@
if(mover in mobs_under) //can't collide with the thing you're buckled to
return NO_BLOCKED_MOVEMENT
- if(ismob(mover))
- var/mob/M = mover
+ if(isliving(mover))
+ var/mob/living/M = mover
if(M.mob_flags & SQUEEZE_UNDER_VEHICLES)
add_under_van(M)
return NO_BLOCKED_MOVEMENT
- if(M.lying)
+ if(M.body_position == LYING_DOWN)
return NO_BLOCKED_MOVEMENT
if(M.mob_size >= MOB_SIZE_IMMOBILE && next_push < world.time)
diff --git a/colonialmarines.dme b/colonialmarines.dme
index fe2fadba5c0e..71c72701f0f4 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -33,6 +33,7 @@
#include "code\__DEFINES\access.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\ARES.dm"
+#include "code\__DEFINES\assert.dm"
#include "code\__DEFINES\atmospherics.dm"
#include "code\__DEFINES\autofire.dm"
#include "code\__DEFINES\autolathe.dm"
@@ -142,6 +143,7 @@
#include "code\__HELPERS\#maths.dm"
#include "code\__HELPERS\_lists.dm"
#include "code\__HELPERS\_time.dm"
+#include "code\__HELPERS\animations.dm"
#include "code\__HELPERS\chat.dm"
#include "code\__HELPERS\cmp.dm"
#include "code\__HELPERS\datums.dm"
@@ -163,7 +165,9 @@
#include "code\__HELPERS\qdel.dm"
#include "code\__HELPERS\sanitize_values.dm"
#include "code\__HELPERS\shell.dm"
+#include "code\__HELPERS\status_effects.dm"
#include "code\__HELPERS\text.dm"
+#include "code\__HELPERS\traits.dm"
#include "code\__HELPERS\type2type.dm"
#include "code\__HELPERS\unsorted.dm"
#include "code\__HELPERS\verb_helpers.dm"
@@ -1812,6 +1816,7 @@
#include "code\modules\mob\language\languages.dm"
#include "code\modules\mob\living\blood.dm"
#include "code\modules\mob\living\damage_procs.dm"
+#include "code\modules\mob\living\init_signals.dm"
#include "code\modules\mob\living\living.dm"
#include "code\modules\mob\living\living_defense.dm"
#include "code\modules\mob\living\living_defines.dm"