diff --git a/code/__DEFINES/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index 75dcfbc3bd5..3daae1d0d8e 100644 --- a/code/__DEFINES/basic_mobs.dm +++ b/code/__DEFINES/basic_mobs.dm @@ -1,7 +1,11 @@ -#define BASIC_MOB_MAX_STAMINALOSS 200 - ///Basic mob flags +/// Stamina threshold to not experience stamina crit +#define BASIC_MOB_NO_STAMCRIT 0 + +/// Max stamina should be equal to max health +#define BASIC_MOB_STAMINA_MATCH_HEALTH -1 + /// Delete mob upon death #define DEL_ON_DEATH (1<<0) /// Rotate mob 180 degrees while it is dead diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 4a55734ca1a..f0d1364fac7 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -68,7 +68,7 @@ //Bitflags defining which status effects could be or are inflicted on a mob /// If set, this mob can be stunned. #define CANSTUN (1<<0) -/// If set, this mob can be knocked down (or stamcrit) +/// If set, this mob can be knocked down #define CANKNOCKDOWN (1<<1) /// If set, this mob can be knocked unconscious via status effect. /// NOTE, does not mean immune to sleep. Unconscious and sleep are two different things. diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 79727b9e8e3..f849817d24c 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -96,6 +96,8 @@ /// from base of mob/living/updatehealth() #define COMSIG_LIVING_HEALTH_UPDATE "living_health_update" +/// from base of mob/living/updatestamina() +#define COMSIG_LIVING_STAMINA_UPDATE "living_stamina_update" ///from base of mob/living/death(): (gibbed) #define COMSIG_LIVING_DEATH "living_death" diff --git a/code/datums/elements/basic_stamina_slowdown.dm b/code/datums/elements/basic_stamina_slowdown.dm new file mode 100644 index 00000000000..f1d6b4a29ca --- /dev/null +++ b/code/datums/elements/basic_stamina_slowdown.dm @@ -0,0 +1,33 @@ +/// Applies a simple scaling slowdown as a mob's stamina is depleted +/datum/element/basic_stamina_slowdown + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// How much stamina damage need we take before we start moving slower? + var/minium_stamina_threshold + /// How much stamina damage can we have at maximum? + var/maximum_stamina + /// How slow do we move with the maximum stamina damage? + var/maximum_slowdown + +/datum/element/basic_stamina_slowdown/Attach(datum/target, minium_stamina_threshold = 40, maximum_stamina = 120, maximum_slowdown = 12) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.minium_stamina_threshold = minium_stamina_threshold + src.maximum_stamina = maximum_stamina + src.maximum_slowdown = maximum_slowdown + RegisterSignal(target, COMSIG_LIVING_STAMINA_UPDATE, PROC_REF(on_stamina_changed)) + +/datum/element/basic_stamina_slowdown/Detach(datum/source) + . = ..() + UnregisterSignal(source, COMSIG_LIVING_STAMINA_UPDATE) + +/// When our stamina changes check how slow we should be +/datum/element/basic_stamina_slowdown/proc/on_stamina_changed(mob/living/source) + SIGNAL_HANDLER + if (source.staminaloss >= minium_stamina_threshold) + var/current_slowdown = (source.staminaloss / maximum_stamina) * maximum_slowdown + source.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/basic_stamina_slowdown, TRUE, multiplicative_slowdown = current_slowdown) + else + source.remove_movespeed_modifier(/datum/movespeed_modifier/basic_stamina_slowdown) diff --git a/code/datums/status_effects/debuffs/stamcrit.dm b/code/datums/status_effects/debuffs/stamcrit.dm index 0d4a844a61e..5c8c2b46234 100644 --- a/code/datums/status_effects/debuffs/stamcrit.dm +++ b/code/datums/status_effects/debuffs/stamcrit.dm @@ -22,12 +22,12 @@ // Same RegisterSignal(owner, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, PROC_REF(update_diminishing_return)) - RegisterSignal(owner, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(check_remove)) + RegisterSignal(owner, COMSIG_LIVING_STAMINA_UPDATE, PROC_REF(check_remove)) /datum/status_effect/incapacitating/stamcrit/on_apply() if(owner.stat == DEAD) return FALSE - if(owner.check_stun_immunity(CANKNOCKDOWN)) + if(owner.check_stun_immunity(CANSTUN)) return FALSE if(SEND_SIGNAL(owner, COMSIG_LIVING_ENTER_STAMCRIT) & STAMCRIT_CANCELLED) return FALSE @@ -72,7 +72,13 @@ return COMPONENT_IGNORE_CHANGE -/datum/status_effect/incapacitating/stamcrit/proc/check_remove(datum/source, ...) +/datum/status_effect/incapacitating/stamcrit/proc/check_remove(datum/source) SIGNAL_HANDLER + if (isbasicmob(owner)) + var/mob/living/basic/basic_owner = owner + if(basic_owner.staminaloss < basic_owner.stamina_crit_threshold) + qdel(src) + return + if(owner.maxHealth - owner.getStaminaLoss() > owner.crit_threshold) qdel(src) diff --git a/code/modules/mob/living/basic/alien/_alien.dm b/code/modules/mob/living/basic/alien/_alien.dm index 14d74409016..ee2c25e5199 100644 --- a/code/modules/mob/living/basic/alien/_alien.dm +++ b/code/modules/mob/living/basic/alien/_alien.dm @@ -18,6 +18,7 @@ bubble_icon = "alien" combat_mode = TRUE faction = list(ROLE_ALIEN) + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) // Going for a dark purple here lighting_cutoff_red = 30 diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index b7518a47765..d1d6756a4e5 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -4,17 +4,22 @@ icon = 'icons/mob/simple/animal.dmi' health = 20 maxHealth = 20 + max_stamina = BASIC_MOB_STAMINA_MATCH_HEALTH gender = PLURAL living_flags = MOVES_ON_ITS_OWN - status_flags = CANPUSH + status_flags = CANPUSH | CANSTUN fire_stack_decay_rate = -5 // Reasonably fast as NPCs will not usually actively extinguish themselves var/basic_mob_flags = NONE ///Defines how fast the basic mob can move. This is not a multiplier var/speed = 1 - ///How much stamina the mob recovers per second - var/stamina_recovery = 5 + ///How much stamina the mob recovers per second, if set to >0 stamina loses its normal function of resetting after a set amount of time + var/stamina_recovery = 0 + ///How slow will we get when we lose all our stamina? + var/max_stamina_slowdown = 3 + ///Percentage of max stamina loss we need to lose in order to get stunned + var/stamina_crit_threshold = 100 ///how much damage this basic mob does to objects, if any. var/obj_damage = 0 @@ -42,7 +47,7 @@ var/environment_smash = ENVIRONMENT_SMASH_STRUCTURES /// 1 for full damage, 0 for none, -1 for 1:1 heal from that source. - var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) + var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 1, OXY = 1) ///Verbs used for speaking e.g. "Says" or "Chitters". This can be elementized var/list/speak_emote = list() @@ -111,6 +116,8 @@ stack_trace("Basic mob being instantiated in nullspace") update_basic_mob_varspeed() + apply_target_randomisation() + make_stamina_slowable() if(speak_emote) speak_emote = string_list(speak_emote) @@ -121,7 +128,6 @@ return apply_atmos_requirements(mapload) apply_temperature_requirements(mapload) - apply_target_randomisation() /mob/living/basic/proc/on_ssair_init(datum/source) SIGNAL_HANDLER @@ -143,6 +149,14 @@ return AddElement(/datum/element/body_temp_sensitive, minimum_survivable_temperature, maximum_survivable_temperature, unsuitable_cold_damage, unsuitable_heat_damage, mapload) +/// Ensures that this mob can be slowed from taking stamina damage +/mob/living/basic/proc/make_stamina_slowable() + if (max_stamina == BASIC_MOB_STAMINA_MATCH_HEALTH) + max_stamina = maxHealth + if (damage_coeff[STAMINA] <= 0 || max_stamina <= 0 || max_stamina_slowdown <= 0) + return + AddElement(/datum/element/basic_stamina_slowdown, minium_stamina_threshold = max_stamina / 3, maximum_stamina = max_stamina, maximum_slowdown = max_stamina_slowdown) + /mob/living/basic/proc/apply_target_randomisation() if (basic_mob_flags & PRECISE_ATTACK_ZONES) return @@ -285,10 +299,6 @@ /mob/living/basic/compare_sentience_type(compare_type) return sentience_type == compare_type -/// Updates movement speed based on stamina loss -/mob/living/basic/update_stamina() - set_varspeed(initial(speed) + (staminaloss * 0.06)) - /mob/living/basic/on_fire_stack(seconds_per_tick, datum/status_effect/fire_handler/fire_stacks/fire_handler) adjust_bodytemperature((maximum_survivable_temperature + (fire_handler.stacks * 12)) * 0.5 * seconds_per_tick) diff --git a/code/modules/mob/living/basic/blob_minions/blob_mob.dm b/code/modules/mob/living/basic/blob_minions/blob_mob.dm index 1ebd53bb592..6c82eaed053 100644 --- a/code/modules/mob/living/basic/blob_minions/blob_mob.dm +++ b/code/modules/mob/living/basic/blob_minions/blob_mob.dm @@ -5,6 +5,7 @@ icon = 'icons/mob/nonhuman-player/blob.dmi' icon_state = "blob_head" unique_name = TRUE + status_flags = CANPUSH pass_flags = PASSBLOB faction = list(ROLE_BLOB) combat_mode = TRUE @@ -18,6 +19,7 @@ lighting_cutoff_blue = 30 initial_language_holder = /datum/language_holder/empty can_buckle_to = FALSE + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /mob/living/basic/blob_minion/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/basic/boss/boss.dm b/code/modules/mob/living/basic/boss/boss.dm index 57b28848e48..c488912b507 100644 --- a/code/modules/mob/living/basic/boss/boss.dm +++ b/code/modules/mob/living/basic/boss/boss.dm @@ -3,6 +3,7 @@ //im using it for stuff both of them get /mob/living/basic/boss combat_mode = TRUE + status_flags = NONE sentience_type = SENTIENCE_BOSS mob_biotypes = MOB_ORGANIC|MOB_SPECIAL faction = list(FACTION_MINING, FACTION_BOSS) diff --git a/code/modules/mob/living/basic/clown/clown.dm b/code/modules/mob/living/basic/clown/clown.dm index 58c32a53caa..db0cf2bbba4 100644 --- a/code/modules/mob/living/basic/clown/clown.dm +++ b/code/modules/mob/living/basic/clown/clown.dm @@ -380,7 +380,7 @@ speed = 1 melee_damage_lower = 10 melee_damage_upper = 15 - damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 1, OXY = 1) attack_verb_continuous = "slams" attack_verb_simple = "slam" loot = list( diff --git a/code/modules/mob/living/basic/cult/constructs/_construct.dm b/code/modules/mob/living/basic/cult/constructs/_construct.dm index 01004685607..53ecd0710df 100644 --- a/code/modules/mob/living/basic/cult/constructs/_construct.dm +++ b/code/modules/mob/living/basic/cult/constructs/_construct.dm @@ -8,6 +8,7 @@ unsuitable_atmos_damage = 0 minimum_survivable_temperature = 0 maximum_survivable_temperature = INFINITY + status_flags = CANPUSH damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, STAMINA = 0, OXY = 0) pressure_resistance = 100 speed = 0 diff --git a/code/modules/mob/living/basic/cult/shade.dm b/code/modules/mob/living/basic/cult/shade.dm index f5b0e757ed9..7c5520c71fe 100644 --- a/code/modules/mob/living/basic/cult/shade.dm +++ b/code/modules/mob/living/basic/cult/shade.dm @@ -9,6 +9,7 @@ mob_biotypes = MOB_SPIRIT maxHealth = 40 health = 40 + status_flags = CANPUSH speak_emote = list("hisses") response_help_continuous = "puts their hand through" response_help_simple = "put your hand through" @@ -27,6 +28,7 @@ faction = list(FACTION_CULT) basic_mob_flags = DEL_ON_DEATH initial_language_holder = /datum/language_holder/construct + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /// Theme controls color. THEME_CULT is red THEME_WIZARD is purple and THEME_HOLY is blue var/theme = THEME_CULT /// The different flavors of goop shades can drop, depending on theme. diff --git a/code/modules/mob/living/basic/cytology/vatbeast.dm b/code/modules/mob/living/basic/cytology/vatbeast.dm index 60ad869a969..8b938677e2b 100644 --- a/code/modules/mob/living/basic/cytology/vatbeast.dm +++ b/code/modules/mob/living/basic/cytology/vatbeast.dm @@ -12,7 +12,7 @@ speak_emote = list("roars") health = 250 maxHealth = 250 - damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 1, STAMINA = 0, OXY = 1) + damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 1, STAMINA = 1, OXY = 1) melee_damage_lower = 25 melee_damage_upper = 25 obj_damage = 40 diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm index 7e572c2d92f..dd8805fbf8c 100644 --- a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -27,7 +27,7 @@ melee_attack_cooldown = CLICK_CD_MELEE melee_damage_lower = 25 melee_damage_upper = 30 - damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, STAMINA = 0, OXY = 1.5) + damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, STAMINA = 1, OXY = 1.5) obj_damage = 40 attack_verb_continuous = "pummels" attack_verb_simple = "pummel" diff --git a/code/modules/mob/living/basic/festivus_pole.dm b/code/modules/mob/living/basic/festivus_pole.dm index 7ff4ab6c532..c676a89d33c 100644 --- a/code/modules/mob/living/basic/festivus_pole.dm +++ b/code/modules/mob/living/basic/festivus_pole.dm @@ -13,6 +13,7 @@ gender = NEUTER gold_core_spawnable = HOSTILE_SPAWN basic_mob_flags = DEL_ON_DEATH + status_flags = CANPUSH response_help_continuous = "rubs" response_help_simple = "rub" @@ -38,6 +39,7 @@ death_message = "is hacked into pieces!" + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ai_controller = /datum/ai_controller/basic_controller/festivus_pole /mob/living/basic/festivus/Initialize(mapload) diff --git a/code/modules/mob/living/basic/guardian/guardian.dm b/code/modules/mob/living/basic/guardian/guardian.dm index 9ddf2c1fc31..ba3bc0cb193 100644 --- a/code/modules/mob/living/basic/guardian/guardian.dm +++ b/code/modules/mob/living/basic/guardian/guardian.dm @@ -17,6 +17,7 @@ hud_type = /datum/hud/guardian faction = list() speed = 0 + status_flags = CANPUSH maxHealth = INFINITY // The spirit itself is invincible and passes damage to its host health = INFINITY damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) diff --git a/code/modules/mob/living/basic/health_adjustment.dm b/code/modules/mob/living/basic/health_adjustment.dm index ca98f98eb8e..d35178b9918 100644 --- a/code/modules/mob/living/basic/health_adjustment.dm +++ b/code/modules/mob/living/basic/health_adjustment.dm @@ -59,13 +59,24 @@ if(!can_adjust_stamina_loss(amount, forced, required_biotype)) return 0 . = staminaloss - if(forced) - staminaloss = max(0, min(BASIC_MOB_MAX_STAMINALOSS, staminaloss + amount)) - else - staminaloss = max(0, min(BASIC_MOB_MAX_STAMINALOSS, staminaloss + (amount * damage_coeff[STAMINA]))) - if(updating_stamina) + + var/stamina_delta = forced ? amount : amount * damage_coeff[STAMINA] + staminaloss = max(0, min(max_stamina, staminaloss + stamina_delta)) + + if(stamina_delta > 0) + received_stamina_damage(staminaloss, -1 * stamina_delta, amount) + if(updating_stamina && stamina_delta) update_stamina() . -= staminaloss /mob/living/basic/received_stamina_damage(current_level, amount_actual, amount) - return + if (stamina_recovery == 0) + return ..() + +/mob/living/basic/received_stamina_damage(current_level, amount_actual, amount) + . = ..() + if (stat == DEAD || stamina_crit_threshold == BASIC_MOB_NO_STAMCRIT) + return + + if (100 / (max_stamina / current_level) >= stamina_crit_threshold) + apply_status_effect(/datum/status_effect/incapacitating/stamcrit) diff --git a/code/modules/mob/living/basic/heretic/_heretic_summon.dm b/code/modules/mob/living/basic/heretic/_heretic_summon.dm index 8b8797133a2..4a5c8882486 100644 --- a/code/modules/mob/living/basic/heretic/_heretic_summon.dm +++ b/code/modules/mob/living/basic/heretic/_heretic_summon.dm @@ -9,6 +9,7 @@ mob_biotypes = NONE habitable_atmos = null + status_flags = CANPUSH damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, STAMINA = 0, OXY = 0) speed = 0 melee_attack_cooldown = CLICK_CD_MELEE diff --git a/code/modules/mob/living/basic/jungle/leaper/leaper.dm b/code/modules/mob/living/basic/jungle/leaper/leaper.dm index da957e72117..7e924bc0e20 100644 --- a/code/modules/mob/living/basic/jungle/leaper/leaper.dm +++ b/code/modules/mob/living/basic/jungle/leaper/leaper.dm @@ -25,7 +25,7 @@ attack_sound = 'sound/items/weapons/bladeslice.ogg' attack_vis_effect = ATTACK_EFFECT_SLASH - status_flags = NONE + status_flags = CANSTUN lighting_cutoff_red = 5 lighting_cutoff_green = 20 lighting_cutoff_blue = 25 diff --git a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid.dm b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid.dm index 059375a7ed6..bfbd222f89c 100644 --- a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid.dm +++ b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid.dm @@ -22,7 +22,7 @@ environment_smash = ENVIRONMENT_SMASH_WALLS minimum_survivable_temperature = T0C maximum_survivable_temperature = T0C + 450 - status_flags = NONE + status_flags = CANSTUN lighting_cutoff_red = 5 lighting_cutoff_green = 20 lighting_cutoff_blue = 25 diff --git a/code/modules/mob/living/basic/lavaland/mining.dm b/code/modules/mob/living/basic/lavaland/mining.dm index d683785b2ac..53085668ea4 100644 --- a/code/modules/mob/living/basic/lavaland/mining.dm +++ b/code/modules/mob/living/basic/lavaland/mining.dm @@ -13,6 +13,7 @@ lighting_cutoff_red = 25 lighting_cutoff_green = 15 lighting_cutoff_blue = 35 + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /// Message to output if throwing damage is absorbed var/throw_blocked_message = "bounces off" /// What crusher trophy this mob drops, if any diff --git a/code/modules/mob/living/basic/minebots/minebot.dm b/code/modules/mob/living/basic/minebots/minebot.dm index 819ae9e07dc..bf906208f67 100644 --- a/code/modules/mob/living/basic/minebots/minebot.dm +++ b/code/modules/mob/living/basic/minebots/minebot.dm @@ -31,6 +31,7 @@ light_on = FALSE combat_mode = FALSE ai_controller = /datum/ai_controller/basic_controller/minebot + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ///the gun we use to kill var/obj/item/gun/energy/recharge/kinetic_accelerator/minebot/stored_gun ///our normal overlay diff --git a/code/modules/mob/living/basic/pets/dog/dog_subtypes.dm b/code/modules/mob/living/basic/pets/dog/dog_subtypes.dm index 73f06dacfb8..1d6dc3e6ee4 100644 --- a/code/modules/mob/living/basic/pets/dog/dog_subtypes.dm +++ b/code/modules/mob/living/basic/pets/dog/dog_subtypes.dm @@ -90,7 +90,7 @@ health = 50 maxHealth = 50 gender = NEUTER - damage_coeff = list(BRUTE = 3, BURN = 3, TOX = 1, STAMINA = 0, OXY = 1) + damage_coeff = list(BRUTE = 3, BURN = 3, TOX = 1, STAMINA = 1, OXY = 1) butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/food/breadslice/plain = 3, \ /obj/item/food/meat/slab = 2) response_harm_continuous = "takes a bite out of" diff --git a/code/modules/mob/living/basic/pets/orbie/orbie.dm b/code/modules/mob/living/basic/pets/orbie/orbie.dm index 2ca8abce065..40a93f4b882 100644 --- a/code/modules/mob/living/basic/pets/orbie/orbie.dm +++ b/code/modules/mob/living/basic/pets/orbie/orbie.dm @@ -8,6 +8,7 @@ icon_living = "orbie" speed = 0 maxHealth = 100 + status_flags = CANPUSH light_on = FALSE light_system = OVERLAY_LIGHT light_range = 6 @@ -25,6 +26,7 @@ maximum_survivable_temperature = INFINITY death_message = "fades out of existence!" ai_controller = /datum/ai_controller/basic_controller/orbie + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ///are we happy or not? var/happy_state = FALSE ///overlay for our neutral eyes diff --git a/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm b/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm index 6287c1f25e1..4e6f19cdf72 100644 --- a/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm +++ b/code/modules/mob/living/basic/ruin_defender/cybersun_aicore.dm @@ -10,6 +10,7 @@ icon_state = "ai-red" icon_living = "ai-red" gender = NEUTER + status_flags = NONE basic_mob_flags = MOB_ROBOTIC mob_size = MOB_SIZE_HUGE basic_mob_flags = DEL_ON_DEATH diff --git a/code/modules/mob/living/basic/ruin_defender/living_floor.dm b/code/modules/mob/living/basic/ruin_defender/living_floor.dm index 82ad90bc80c..ac9627b8037 100644 --- a/code/modules/mob/living/basic/ruin_defender/living_floor.dm +++ b/code/modules/mob/living/basic/ruin_defender/living_floor.dm @@ -44,6 +44,7 @@ attack_vis_effect = ATTACK_EFFECT_BITE attack_verb_continuous = "bites" attack_verb_simple = "bite" + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ai_controller = /datum/ai_controller/basic_controller/living_floor melee_attack_cooldown = 0.5 SECONDS // get real diff --git a/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm b/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm index 59ce68cf573..2de36667472 100644 --- a/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm +++ b/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm @@ -30,6 +30,7 @@ GLOBAL_LIST_INIT(animatable_blacklist, typecacheof(list( faction = list(FACTION_MIMIC) basic_mob_flags = DEL_ON_DEATH combat_mode = TRUE + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /// can we stun people on hit var/knockdown_people = FALSE diff --git a/code/modules/mob/living/basic/ruin_defender/stickman.dm b/code/modules/mob/living/basic/ruin_defender/stickman.dm index 3435f873ea3..df39d77fbd3 100644 --- a/code/modules/mob/living/basic/ruin_defender/stickman.dm +++ b/code/modules/mob/living/basic/ruin_defender/stickman.dm @@ -20,6 +20,7 @@ unsuitable_atmos_damage = 7.5 unsuitable_cold_damage = 7.5 unsuitable_heat_damage = 7.5 + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ai_controller = /datum/ai_controller/basic_controller/stickman diff --git a/code/modules/mob/living/basic/ruin_defender/zombie.dm b/code/modules/mob/living/basic/ruin_defender/zombie.dm index b77920af8d1..4608b113a50 100644 --- a/code/modules/mob/living/basic/ruin_defender/zombie.dm +++ b/code/modules/mob/living/basic/ruin_defender/zombie.dm @@ -15,7 +15,7 @@ attack_vis_effect = ATTACK_EFFECT_BITE combat_mode = TRUE speed = 4 - status_flags = CANPUSH + status_flags = CANPUSH | CANSTUN death_message = "rapidly decays into a pile of bones!" unsuitable_atmos_damage = 0 unsuitable_cold_damage = 0 diff --git a/code/modules/mob/living/basic/slime/slime.dm b/code/modules/mob/living/basic/slime/slime.dm index 9df77ce0556..6a54ddc1871 100644 --- a/code/modules/mob/living/basic/slime/slime.dm +++ b/code/modules/mob/living/basic/slime/slime.dm @@ -26,7 +26,7 @@ wound_bonus = -45 can_buckle_to = FALSE - damage_coeff = list(BRUTE = 1, BURN = -1, TOX = 1, STAMINA = 0, OXY = 1) //Healed by fire + damage_coeff = list(BRUTE = 1, BURN = -1, TOX = 1, STAMINA = 1, OXY = 1) //Healed by fire unsuitable_cold_damage = 15 unsuitable_heat_damage = 0 maximum_survivable_temperature = INFINITY diff --git a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm index a84ec7a208e..75c9f44a53f 100644 --- a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm +++ b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm @@ -14,6 +14,7 @@ response_disarm_continuous = "gently pushes aside" response_disarm_simple = "gently push aside" + max_stamina = 120 maxHealth = 60 health = 60 speed = 0 @@ -88,7 +89,7 @@ maxHealth = 250 health = 250 faction = list(FACTION_NEUTRAL) - status_flags = CANPUSH + status_flags = CANPUSH | CANSTUN /mob/living/basic/bear/snow/ancient name = "ancient polar bear" diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm index 777fe42e276..7d50a58ae48 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -22,6 +22,7 @@ mob_biotypes = MOB_ORGANIC | MOB_BEAST | MOB_AQUATIC health = 25 maxHealth = 25 + max_stamina = 120 pressure_resistance = 200 combat_mode = TRUE obj_damage = 50 diff --git a/code/modules/mob/living/basic/space_fauna/cat_surgeon.dm b/code/modules/mob/living/basic/space_fauna/cat_surgeon.dm index 926ce374faf..164505df5ac 100644 --- a/code/modules/mob/living/basic/space_fauna/cat_surgeon.dm +++ b/code/modules/mob/living/basic/space_fauna/cat_surgeon.dm @@ -26,7 +26,7 @@ habitable_atmos = list("min_oxy" = 5, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 7.5 faction = list(FACTION_HOSTILE) - status_flags = CANPUSH + status_flags = CANPUSH | CANSTUN basic_mob_flags = DEL_ON_DEATH ai_controller = /datum/ai_controller/basic_controller/cat_butcherer diff --git a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm index 844535c01e9..34205124db6 100644 --- a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm +++ b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm @@ -41,6 +41,10 @@ lighting_cutoff_blue = 5 butcher_results = list(/obj/item/food/meat/slab/spider = 2, /obj/item/food/spiderleg = 8) ai_controller = /datum/ai_controller/basic_controller/giant_spider + max_stamina = 200 + stamina_crit_threshold = BASIC_MOB_NO_STAMCRIT + stamina_recovery = 5 + max_stamina_slowdown = 12 /mob/living/basic/flesh_spider/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/basic/space_fauna/changeling/headslug.dm b/code/modules/mob/living/basic/space_fauna/changeling/headslug.dm index f2585aecd62..a5cfd15f80b 100644 --- a/code/modules/mob/living/basic/space_fauna/changeling/headslug.dm +++ b/code/modules/mob/living/basic/space_fauna/changeling/headslug.dm @@ -12,6 +12,7 @@ gender = NEUTER health = 50 maxHealth = 50 + max_stamina = 120 melee_damage_lower = 5 melee_damage_upper = 5 attack_verb_continuous = "chomps" diff --git a/code/modules/mob/living/basic/space_fauna/demon/demon.dm b/code/modules/mob/living/basic/space_fauna/demon/demon.dm index f61591a10c7..ca574cefc5a 100644 --- a/code/modules/mob/living/basic/space_fauna/demon/demon.dm +++ b/code/modules/mob/living/basic/space_fauna/demon/demon.dm @@ -47,6 +47,8 @@ lighting_cutoff_green = 10 lighting_cutoff_blue = 20 + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) + /// Typepath of the antag datum to add to the demon when applicable var/datum/antagonist/antag_type = null diff --git a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm index 08e4cc7d2c0..597e7db1065 100644 --- a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm +++ b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm @@ -18,7 +18,7 @@ attack_verb_simple = "punch" attack_sound = 'sound/items/weapons/punch1.ogg' melee_attack_cooldown = 1.2 SECONDS - damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 1, OXY = 1) speak_emote = list("announces") unsuitable_atmos_damage = 0 diff --git a/code/modules/mob/living/basic/space_fauna/ghost.dm b/code/modules/mob/living/basic/space_fauna/ghost.dm index c240425d905..d8af15afa10 100644 --- a/code/modules/mob/living/basic/space_fauna/ghost.dm +++ b/code/modules/mob/living/basic/space_fauna/ghost.dm @@ -10,6 +10,7 @@ response_help_simple = "pass through" combat_mode = TRUE basic_mob_flags = DEL_ON_DEATH + status_flags = CANPUSH maxHealth = 40 health = 40 melee_damage_lower = 15 @@ -26,6 +27,7 @@ light_range = 2.5 // same glowing as visible player ghosts light_power = 0.6 ai_controller = /datum/ai_controller/basic_controller/ghost + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ///What hairstyle will this ghost have var/ghost_hairstyle diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm b/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm index b29718f8810..c4c7d4a3383 100644 --- a/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm +++ b/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm @@ -32,6 +32,7 @@ habitable_atmos = null minimum_survivable_temperature = TCMB ai_controller = /datum/ai_controller/basic_controller/hivebot + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ///does this type do range attacks? var/ranged_attacker = FALSE /// How often can we shoot? diff --git a/code/modules/mob/living/basic/space_fauna/lightgeist.dm b/code/modules/mob/living/basic/space_fauna/lightgeist.dm index 41bdb2600e7..2478beb5935 100644 --- a/code/modules/mob/living/basic/space_fauna/lightgeist.dm +++ b/code/modules/mob/living/basic/space_fauna/lightgeist.dm @@ -34,7 +34,7 @@ verb_exclaim = "zaps" verb_yell = "bangs" initial_language_holder = /datum/language_holder/lightbringer - damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, STAMINA = 0, OXY = 0) + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, STAMINA = 1, OXY = 0) light_range = 4 faction = list(FACTION_NEUTRAL) unsuitable_atmos_damage = 0 diff --git a/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm b/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm index 513ffde549e..561ced890cc 100644 --- a/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm +++ b/code/modules/mob/living/basic/space_fauna/meteor_heart/meteor_heart.dm @@ -10,6 +10,7 @@ icon = 'icons/mob/simple/meteor_heart.dmi' icon_state = "heart" icon_living = "heart" + status_flags = NONE mob_biotypes = MOB_ORGANIC basic_mob_flags = DEL_ON_DEATH mob_size = MOB_SIZE_HUGE @@ -27,6 +28,7 @@ maximum_survivable_temperature = 1500 combat_mode = TRUE move_resist = INFINITY // This mob IS the floor + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /// Looping heartbeat sound var/datum/looping_sound/heartbeat/soundloop diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm index 165c5b85f35..2f6b2aa10d1 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/blankbody.dm @@ -27,6 +27,7 @@ lighting_cutoff_blue = 40 ai_controller = /datum/ai_controller/basic_controller/simple/simple_hostile_obstacles + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /mob/living/basic/blankbody/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm index d9973142c12..916492c229a 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/creature.dm @@ -28,6 +28,7 @@ lighting_cutoff_blue = 15 ai_controller = /datum/ai_controller/basic_controller/simple/simple_hostile_obstacles + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) var/health_scaling = TRUE /mob/living/basic/creature/Initialize(mapload) diff --git a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm index 6bcac371480..3405b6e9bd7 100644 --- a/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm +++ b/code/modules/mob/living/basic/space_fauna/netherworld/migo.dm @@ -29,6 +29,7 @@ lighting_cutoff_blue = 50 ai_controller = /datum/ai_controller/basic_controller/simple/simple_hostile_obstacles + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) var/static/list/migo_sounds /// Odds migo will dodge var/dodge_prob = 10 diff --git a/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm b/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm index 0d97a10dffe..86e67e0392a 100644 --- a/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm +++ b/code/modules/mob/living/basic/space_fauna/paper_wizard/paper_wizard.dm @@ -13,6 +13,7 @@ response_disarm_simple = "push" basic_mob_flags = DEL_ON_DEATH + status_flags = CANPUSH maxHealth = 1000 health = 1000 melee_damage_lower = 10 @@ -20,6 +21,7 @@ obj_damage = 50 attack_sound = 'sound/effects/hallucinations/growl1.ogg' ai_controller = /datum/ai_controller/basic_controller/paper_wizard + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ///spell to summon minions var/datum/action/cooldown/spell/conjure/wizard_summon_minions/summon ///spell to summon clones diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm index 07ad70a29e3..0f2be5a8ac1 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm @@ -11,6 +11,7 @@ maxHealth = 70 health = 70 + max_stamina = 120 butcher_results = list(/obj/item/food/meat/slab/mouse = 2, /obj/item/clothing/head/costume/crown = 1) diff --git a/code/modules/mob/living/basic/space_fauna/robot_customer.dm b/code/modules/mob/living/basic/space_fauna/robot_customer.dm index a71127f1aa2..98f16e18832 100644 --- a/code/modules/mob/living/basic/space_fauna/robot_customer.dm +++ b/code/modules/mob/living/basic/space_fauna/robot_customer.dm @@ -11,6 +11,7 @@ icon_living = "amerifat" max_grab = GRAB_AGGRESSIVE + status_flags = CANPUSH basic_mob_flags = DEL_ON_DEATH mob_biotypes = MOB_ROBOTIC|MOB_HUMANOID sentience_type = SENTIENCE_ARTIFICIAL @@ -20,6 +21,7 @@ maximum_survivable_temperature = T0C + 1000 ai_controller = /datum/ai_controller/robot_customer + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /// The clothes that we draw on this tourist. var/clothes_set = "amerifat_clothes" diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index 4bc3531d811..05a2668cfe8 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -18,6 +18,7 @@ health_doll_icon = "spacedragon" faction = list(FACTION_CARP) mob_biotypes = MOB_SPECIAL + status_flags = CANPUSH flags_1 = PREVENT_CONTENTS_EXPLOSION_1 gender = NEUTER maxHealth = 400 @@ -51,6 +52,10 @@ lighting_cutoff_red = 12 lighting_cutoff_green = 15 lighting_cutoff_blue = 34 + max_stamina = 200 + stamina_crit_threshold = BASIC_MOB_NO_STAMCRIT + stamina_recovery = 5 + max_stamina_slowdown = 12 /// The colour of the space dragon var/chosen_colour diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm index d71f6791a9c..6c8f72bc11a 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm @@ -30,6 +30,11 @@ lighting_cutoff_red = 22 lighting_cutoff_green = 5 lighting_cutoff_blue = 5 + max_stamina = 200 + stamina_crit_threshold = BASIC_MOB_NO_STAMCRIT + stamina_recovery = 5 + max_stamina_slowdown = 12 + /// Speed modifier to apply if controlled by a human player var/player_speed_modifier = -4 /// What reagent the mob injects targets with diff --git a/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm b/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm index 9710421b408..2084b413014 100644 --- a/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm +++ b/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm @@ -9,8 +9,10 @@ maxHealth = 300 melee_damage_lower = 15 melee_damage_upper = 30 + status_flags = CANPUSH sentience_type = SENTIENCE_ARTIFICIAL ai_controller = /datum/ai_controller/basic_controller/stares_at_people + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) /// the path to a fake item we will hold in our right hand var/obj/item/held_item /// the path to a fake hat we will wear diff --git a/code/modules/mob/living/basic/space_fauna/statue/statue.dm b/code/modules/mob/living/basic/space_fauna/statue/statue.dm index 3bd308f34a6..6664c8c8291 100644 --- a/code/modules/mob/living/basic/space_fauna/statue/statue.dm +++ b/code/modules/mob/living/basic/space_fauna/statue/statue.dm @@ -29,6 +29,7 @@ attack_vis_effect = ATTACK_EFFECT_CLAW melee_attack_cooldown = 1 SECONDS + status_flags = CANPUSH faction = list(FACTION_STATUE) speak_emote = list("screams") death_message = "falls apart into a fine dust." @@ -50,6 +51,7 @@ move_resist = MOVE_FORCE_EXTREMELY_STRONG pull_force = MOVE_FORCE_EXTREMELY_STRONG + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) ai_controller = /datum/ai_controller/basic_controller/statue /mob/living/basic/statue/Initialize(mapload) diff --git a/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm b/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm index 8c879045a36..c794484990c 100644 --- a/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm +++ b/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm @@ -9,6 +9,7 @@ icon_dead = "smspider_dead" gender = NEUTER + status_flags = CANPUSH mob_biotypes = MOB_BUG|MOB_ROBOTIC speak_emote = list("vibrates") @@ -24,6 +25,7 @@ maximum_survivable_temperature = T0C + 1250 habitable_atmos = null death_message = "falls to the ground, its shard dulling to a miserable grey!" + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) faction = list(FACTION_HOSTILE) diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm index a3670c6e5ac..bbe27fed003 100644 --- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm +++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_fugu.dm @@ -16,7 +16,7 @@ health_doll_icon = "Fugu0" pixel_x = -16 base_pixel_x = -16 - status_flags = NONE + status_flags = CANSTUN gold_core_spawnable = HOSTILE_SPAWN mob_biotypes = MOB_ORGANIC | MOB_BEAST mob_size = MOB_SIZE_SMALL diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f978e095f23..0b82cf11052 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1483,6 +1483,7 @@ return TRUE /mob/living/proc/update_stamina() + SEND_SIGNAL(src, COMSIG_LIVING_STAMINA_UPDATE) update_stamina_hud() /mob/living/carbon/alien/update_stamina() diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index caa8e4a2043..483a14ca895 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -24,6 +24,9 @@ /datum/movespeed_modifier/resonance multiplicative_slowdown = 0.75 +/datum/movespeed_modifier/basic_stamina_slowdown + variable = TRUE + /datum/movespeed_modifier/damage_slowdown blacklisted_movetypes = FLOATING|FLYING variable = TRUE diff --git a/tgstation.dme b/tgstation.dme index 10c3f61ae82..07f60938ded 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1471,6 +1471,7 @@ #include "code\datums\elements\basic_allergenic_attack.dm" #include "code\datums\elements\basic_eating.dm" #include "code\datums\elements\basic_health_examine.dm" +#include "code\datums\elements\basic_stamina_slowdown.dm" #include "code\datums\elements\beauty.dm" #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\befriend_petting.dm"