Skip to content

Commit

Permalink
/tg/ Status Effects Part 2 - datum, KD, KO, Stuns (#4842)
Browse files Browse the repository at this point in the history
# About the pull request

<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

Part 2 - this includes porting the actual status_effect datum, modifying
it to fit our purposes by backing it with timers similarly to old
system, and finally implementing KD, KO and Stun with it.

This contains Part 1 PR (#4828) so if you want to take a look at it I'd
advise checking the last commits or setting up a compare between both
branches.

# Explain why it's good for the game
Predictable status timers. Current ones are bogus in their handling of
"life tick correction" and will "stack" time even when they're not
supposed to.

Also provides a more robust backend for general effects, and integrates
status effects into it.

# Testing Photographs and Procedure

Summary testing of buckling interactions, explosion knock times,
crawling, resting. Will have to be expanded once part 1 is ready


# Changelog
:cl:
add: Added Buckled, Handcuffed and Legcuffed screen alerts
code: Ported /tg/ status effects backend, modified with timers to let
effects end at appropriate time
code: Stun, Knockdown and Knockout now use the new effects backend
balance: Due to backend change, all KO/KD/Stuns may behave differently
timing wise. This is of course subject to adjustments.
balance: Endurance is now set at 8% effect duration reduction per level
above 1. However it now compounds with species bonus. Feel free to
adjust.
balance: Knockdowns are not inherently incapacitating anymore and many
sources of it have been updated to also stun to make up for it.
fix: KO/KD/Stuns do not artificially and randomly ''stack'' due to
incorrect timer offset calculation anymore.
fix: Stuns now correctly apply Stun reduction values instead of
Knockdown reductions.
fix: Crawling can now be interrupted by a normal move, if you are fit
enough to do so.
/:cl:

---------

Co-authored-by: forest2001 <[email protected]>
  • Loading branch information
fira and realforest2001 committed Dec 19, 2023
1 parent 553fa38 commit 55f9dd8
Show file tree
Hide file tree
Showing 75 changed files with 1,172 additions and 439 deletions.
7 changes: 7 additions & 0 deletions code/__DEFINES/alerts.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#define ALERT_BUCKLED "buckled"
#define ALERT_HANDCUFFED "handcuffed"
#define ALERT_LEGCUFFED "legcuffed"
#define ALERT_FLOORED "floored"
#define ALERT_INCAPACITATED "incapacitated"
#define ALERT_KNOCKEDOUT "knockedout"
#define ALERT_IMMOBILIZED "immobilized"
5 changes: 0 additions & 5 deletions code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@
#define COMSIG_LIVING_SPEAK "living_speak"
#define COMPONENT_OVERRIDE_SPEAK (1<<0)

#define COMSIG_LIVING_APPLY_EFFECT "living_apply_effect"
#define COMSIG_LIVING_ADJUST_EFFECT "living_adjust_effect"
#define COMSIG_LIVING_SET_EFFECT "living_set_effect"
#define COMPONENT_CANCEL_EFFECT (1<<0)

/// From /obj/structure/proc/do_climb(var/mob/living/user, mods)
#define COMSIG_LIVING_CLIMB_STRUCTURE "climb_over_structure"
/// From /mob/living/Collide(): (atom/A)
Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@
#define COMSIG_MOB_MOVE_OR_LOOK "mob_move_or_look"
#define COMPONENT_OVERRIDE_MOB_MOVE_OR_LOOK (1<<0)

///from rejuv
#define COMSIG_LIVING_POST_FULLY_HEAL "living_post_fully_heal"

///from /mob/living/emote(): ()
#define COMSIG_MOB_EMOTE "mob_emote"

Expand Down
3 changes: 3 additions & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/// Multiplier for Stun/KD/KO/etc durations in new backend, due to old system being based on life ticks
#define GLOBAL_STATUS_MULTIPLIER 20 // each in-code unit is worth 20ds of duration

#define HEALTH_THRESHOLD_DEAD -100
#define HEALTH_THRESHOLD_CRIT -50

Expand Down
25 changes: 25 additions & 0 deletions code/__DEFINES/status_effects.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
///if it allows multiple instances of the effect
#define STATUS_EFFECT_MULTIPLE 0
///if it allows only one, preventing new instances
#define STATUS_EFFECT_UNIQUE 1
///if it allows only one, but new instances replace
#define STATUS_EFFECT_REPLACE 2
/// if it only allows one, and new instances just instead refresh the timer
#define STATUS_EFFECT_REFRESH 3

///Processing flags - used to define the speed at which the status will work
///This is fast - 0.2s between ticks (I believe!)
#define STATUS_EFFECT_FAST_PROCESS 0
///This is slower and better for more intensive status effects - 1s between ticks
#define STATUS_EFFECT_NORMAL_PROCESS 1

//Incapacitated status effect flags
/// If the incapacitated status effect will ignore a mob in restraints (handcuffs)
#define IGNORE_RESTRAINTS (1<<0)
/// If the incapacitated status effect will ignore a mob in stasis (stasis beds)
#define IGNORE_STASIS (1<<1)
/// If the incapacitated status effect will ignore a mob being agressively grabbed
#define IGNORE_GRAB (1<<2)

/// Time threshold after which we launch ending timer - this should be higher than the slowest processing rate
#define STATUS_EFFECT_TIME_THRESHOLD (2 SECONDS)
4 changes: 3 additions & 1 deletion code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,11 @@
#define SS_PRIORITY_FAST_OBJECTS 105
#define SS_PRIORITY_OBJECTS 104
#define SS_PRIORITY_DECORATOR 99
#define SS_PRIORITY_EFFECTS 97
#define SS_PRIORITY_FASTEFFECTS 96
#define SS_PRIORITY_HIJACK 97
#define SS_PRIORITY_POWER 95
#define SS_PRIORITY_EFFECTS 92
#define SS_PRIORITY_OLDEFFECTS 92
#define SS_PRIORITY_MACHINERY 90
#define SS_PRIORITY_FZ_TRANSITIONS 88
#define SS_PRIORITY_ROUND_RECORDING 83
Expand Down
1 change: 1 addition & 0 deletions code/_onclick/hud/hud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@
hud_version = display_hud_version
persistent_inventory_update(screenmob)
mymob.update_action_buttons(TRUE)
reorganize_alerts(screenmob)
mymob.reload_fullscreens()

// ensure observers get an accurate and up-to-date view
Expand Down
1 change: 0 additions & 1 deletion code/controllers/subsystem/processing/effects.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
PROCESSING_SUBSYSTEM_DEF(effects)
name = "Effects"
wait = 1 SECONDS
flags = SS_NO_INIT | SS_KEEP_TIMING
priority = SS_PRIORITY_EFFECTS
4 changes: 4 additions & 0 deletions code/controllers/subsystem/processing/fasteffects.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PROCESSING_SUBSYSTEM_DEF(fasteffects)
name = "Fast Effects"
wait = 0.2 SECONDS
priority = SS_PRIORITY_FASTEFFECTS
5 changes: 5 additions & 0 deletions code/controllers/subsystem/processing/oldeffects.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(oldeffects)
name = "Old Effects"
wait = 1 SECONDS
flags = SS_NO_INIT | SS_KEEP_TIMING
priority = SS_PRIORITY_OLDEFFECTS
3 changes: 2 additions & 1 deletion code/datums/ammo/ammo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@
/datum/ammo/proc/knockback_effects(mob/living/living_mob, obj/projectile/fired_projectile)
if(iscarbonsizexeno(living_mob))
var/mob/living/carbon/xenomorph/target = living_mob
target.apply_effect(0.7, WEAKEN) // 0.9 seconds of stun, per agreement from Balance Team when switched from MC stuns to exact stuns
target.Stun(0.7) // Previous comment said they believed 0.7 was 0.9s and that the balance team approved this. Geez...
target.KnockDown(0.7)
target.apply_effect(1, SUPERSLOW)
target.apply_effect(2, SLOW)
to_chat(target, SPAN_XENODANGER("You are shaken by the sudden impact!"))
Expand Down
3 changes: 2 additions & 1 deletion code/datums/ammo/bullet/rifle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@
if(iscarbonsizexeno(living_mob))
var/mob/living/carbon/xenomorph/target = living_mob
to_chat(target, SPAN_XENODANGER("You are shaken and slowed by the sudden impact!"))
target.apply_effect(0.5, WEAKEN)
target.KnockDown(0.5) // purely for visual effect, noone actually cares
target.Stun(0.5)
target.apply_effect(2, SUPERSLOW)
target.apply_effect(5, SLOW)
else
Expand Down
12 changes: 8 additions & 4 deletions code/datums/ammo/bullet/shotgun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
if(iscarbonsizexeno(living_mob))
var/mob/living/carbon/xenomorph/target = living_mob
to_chat(target, SPAN_XENODANGER("You are shaken and slowed by the sudden impact!"))
target.apply_effect(0.5, WEAKEN)
target.KnockDown(0.5) // If you ask me the KD should be left out, but players like their visual cues
target.Stun(0.5)
target.apply_effect(1, SUPERSLOW)
target.apply_effect(3, SLOW)
else
Expand Down Expand Up @@ -249,7 +250,8 @@
if(iscarbonsizexeno(living_mob))
var/mob/living/carbon/xenomorph/target = living_mob
to_chat(target, SPAN_XENODANGER("You are shaken and slowed by the sudden impact!"))
target.apply_effect(0.5, WEAKEN)
target.KnockDown(0.5) // If you ask me the KD should be left out, but players like their visual cues
target.Stun(0.5)
target.apply_effect(2, SUPERSLOW)
target.apply_effect(5, SLOW)
else
Expand Down Expand Up @@ -338,7 +340,8 @@
return

shake_camera(M, 3, 4)
M.apply_effect(2, WEAKEN)
M.KnockDown(2) // If you ask me the KD should be left out, but players like their visual cues
M.Stun(2)
M.apply_effect(4, SLOW)
if(iscarbonsizexeno(M))
to_chat(M, SPAN_XENODANGER("The impact knocks you off your feet!"))
Expand All @@ -351,7 +354,8 @@
if(iscarbonsizexeno(living_mob))
var/mob/living/carbon/xenomorph/target = living_mob
to_chat(target, SPAN_XENODANGER("You are shaken and slowed by the sudden impact!"))
target.apply_effect(0.5, WEAKEN)
target.KnockDown(0.5) // If you ask me the KD should be left out, but players like their visual cues
target.Stun(0.5)
target.apply_effect(2, SUPERSLOW)
target.apply_effect(5, SLOW)
else
Expand Down
17 changes: 4 additions & 13 deletions code/datums/ammo/energy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@
icon_state = "shrapnel_plasma"
damage_type = BURN

/datum/ammo/bullet/shrapnel/plasma/on_hit_mob(mob/hit_mob, obj/projectile/hit_projectile)
hit_mob.apply_effect(2, WEAKEN)
/datum/ammo/bullet/shrapnel/plasma/on_hit_mob(mob/living/hit_mob, obj/projectile/hit_projectile)
hit_mob.Stun(2)

/datum/ammo/energy/yautja/caster
name = "root caster bolt"
Expand Down Expand Up @@ -141,12 +141,8 @@
log_attack("[key_name(C)] was stunned by a high power stun bolt from [key_name(P.firer)] at [get_area(P)]")

if(ishuman(C))
var/mob/living/carbon/human/H = C
stun_time++
H.apply_effect(stun_time, WEAKEN)
else
M.apply_effect(stun_time, WEAKEN)

C.apply_effect(stun_time, WEAKEN)
C.apply_effect(stun_time, STUN)
..()

Expand Down Expand Up @@ -217,12 +213,7 @@
continue
to_chat(M, SPAN_DANGER("A powerful electric shock ripples through your body, freezing you in place!"))
M.apply_effect(stun_time, STUN)

if (ishuman(M))
var/mob/living/carbon/human/H = M
H.apply_effect(stun_time, WEAKEN)
else
M.apply_effect(stun_time, WEAKEN)
M.apply_effect(stun_time, WEAKEN)

/datum/ammo/energy/yautja/rifle/bolt
name = "plasma rifle bolt"
Expand Down
2 changes: 0 additions & 2 deletions code/datums/ammo/rocket.dm
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
/datum/ammo/rocket/ap/on_hit_mob(mob/M, obj/projectile/P)
var/turf/T = get_turf(M)
M.ex_act(150, P.dir, P.weapon_cause_data, 100)
M.apply_effect(2, WEAKEN)
M.apply_effect(2, PARALYZE)
if(ishuman_strict(M)) // No yautya or synths. Makes humans gib on direct hit.
M.ex_act(300, P.dir, P.weapon_cause_data, 100)
Expand All @@ -84,7 +83,6 @@
var/hit_something = 0
for(var/mob/M in T)
M.ex_act(150, P.dir, P.weapon_cause_data, 100)
M.apply_effect(4, WEAKEN)
M.apply_effect(4, PARALYZE)
hit_something = 1
continue
Expand Down
16 changes: 9 additions & 7 deletions code/datums/ammo/xeno.dm
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@

if(!isxeno(M))
if(insta_neuro)
if(M.GetKnockDownValueNotADurationDoNotUse() < 3) // If they have less than somewhere random between 4 and 6 seconds KD left and assuming it doesnt get refreshed itnernally
M.adjust_effect(1 * power, WEAKEN)
if(M.GetKnockDownDuration() < 3) // Why are you not using KnockDown(3) ? Do you even know 3 is SIX seconds ? So many questions left unanswered.
M.KnockDown(power)
M.Stun(power)
return

if(ishuman(M))
Expand All @@ -65,8 +66,9 @@
no_clothes_neuro = TRUE

if(no_clothes_neuro)
if(M.GetKnockDownValueNotADurationDoNotUse() < 5) // If they have less than somewhere random between 8 and 10 seconds KD left and assuming it doesnt get refreshed itnernally
M.adjust_effect(1 * power, WEAKEN) // KD them a bit more
if(M.GetKnockDownDuration() < 5) // Nobody actually knows what this means. Supposedly it means less than 10 seconds. Frankly if you get locked into 10s of knockdown to begin with there are bigger issues.
M.KnockDown(power)
M.Stun(power)
M.visible_message(SPAN_DANGER("[M] falls prone."))

/proc/apply_scatter_neuro(mob/living/M)
Expand All @@ -79,9 +81,9 @@
H.visible_message(SPAN_DANGER("[M] shrugs off the neurotoxin!"))
return

if(M.GetKnockDownValueNotADurationDoNotUse() < 0.7) // basically (knocked_down && prob(90))
M.apply_effect(0.7, WEAKEN)
M.visible_message(SPAN_DANGER("[M] falls prone."))
M.KnockDown(0.7) // Completely arbitrary values from another time where stun timers incorrectly stacked. Kill as needed.
M.Stun(0.7)
M.visible_message(SPAN_DANGER("[M] falls prone."))

/datum/ammo/xeno/toxin/on_hit_mob(mob/M,obj/projectile/P)
if(ishuman(M))
Expand Down
4 changes: 2 additions & 2 deletions code/datums/effects/_effects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
if(!validate_atom(thing) || QDELETED(thing))
qdel(src)
return
START_PROCESSING(SSeffects, src)
START_PROCESSING(SSoldeffects, src)

affected_atom = thing
LAZYADD(affected_atom.effects_list, src)
Expand Down Expand Up @@ -118,7 +118,7 @@
if(affected_atom)
LAZYREMOVE(affected_atom.effects_list, src)
affected_atom = null
STOP_PROCESSING(SSeffects, src)
STOP_PROCESSING(SSoldeffects, src)
. = ..()


Expand Down
Loading

0 comments on commit 55f9dd8

Please sign in to comment.