diff --git a/code/__DEFINES/combat/stamina_combat.dm b/code/__DEFINES/combat/stamina_combat.dm
index 374439f9eb..c448e622f5 100644
--- a/code/__DEFINES/combat/stamina_combat.dm
+++ b/code/__DEFINES/combat/stamina_combat.dm
@@ -1,18 +1,4 @@
// Stamina Buffer
-/// Stamina buffer amount
-#define STAMINA_BUFFER_CAPACITY 30
-/// Stamina buffer regen per decisecond
-#define STAMINA_BUFFER_REGEN_PER_SECOND 1
-/// Stamina buffer regen multiplier while in combat mode
-#define STAMINA_BUFFER_REGEN_PER_SECOND_COMBAT 3
-/// Penalty time after an action (clickdelay counting action) ends for stamina buffer regeneration
-#define STAMINA_BUFFER_REGEN_ACTION_PENALTY_TIME 8
-/// Penalty regen multiplier
-#define STAMINA_BUFFER_REGEN_ACTION_PENALTY_FACTOR 0.5
-/// percent of regen to take away at stamcrit
-#define STAMINA_BUFFER_STAMCRIT_REGEN_PERCENT_PENALTY 0.75
-/// percent of capacity to take away at stamcrit
-#define STAMINA_BUFFER_STAMCRIT_CAPACITY_PERCENT_PENALTY 0.5
// Standard amounts for stamina usage
diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm
index e9881677ba..0eeb3862f4 100644
--- a/code/__DEFINES/configuration.dm
+++ b/code/__DEFINES/configuration.dm
@@ -3,6 +3,8 @@
#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
/// Gets the datum of the object, for when editing a const define.
#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X)
+/// Caches an entry in the proc
+#define CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(X, varname) var/static/datum/config_entry/##X/entrycache_##varname;if(!entrycache_##varname){entrycache_##varname=CONFIG_GET_ENTRY(##X);};var/##varname=entrycache_##varname.config_entry_value
#define CONFIG_MAPS_FILE "maps.txt"
diff --git a/code/_onclick/hud/screen_objects/stamina.dm b/code/_onclick/hud/screen_objects/stamina.dm
index bafe919045..98a387d32d 100644
--- a/code/_onclick/hud/screen_objects/stamina.dm
+++ b/code/_onclick/hud/screen_objects/stamina.dm
@@ -11,11 +11,9 @@
/obj/screen/staminas/Click(location,control,params)
if(isliving(usr))
var/mob/living/L = usr
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/buffer_max, buffer_max)
to_chat(L, "You have [L.getStaminaLoss()] stamina loss.
\
- Your stamina buffer is currently [L.stamina_buffer]/[L.stamina_buffer_max], and recharges at [L.stamina_buffer_regen] and [L.stamina_buffer_regen_combat] (combat mode on) per second.
\
- Your stamina buffer will have its capacity reduced by up to [STAMINA_BUFFER_STAMCRIT_CAPACITY_PERCENT_PENALTY * 100]% from stamina damage, up until stamcrit, and similarly will be impacted in regeneration by \
- [STAMINA_BUFFER_STAMCRIT_REGEN_PERCENT_PENALTY * 100]% from said damage.\
-
Your stamina buffer is [round((L.stamina_buffer / L.stamina_buffer_max) * 100, 0.1)]% full.")
+
Your stamina buffer is [round((L.stamina_buffer / buffer_max) * 100, 0.1)]% full.")
/obj/screen/staminas/update_icon_state()
var/mob/living/carbon/user = hud?.mymob
@@ -65,6 +63,7 @@
/obj/screen/staminabuffer/proc/update_to_mob()
var/mob/living/carbon/user = hud?.mymob
user.UpdateStaminaBuffer(FALSE)
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/buffer_max, buffer_max)
if(!user?.client)
return FALSE
if(user.stat == DEAD || (user.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (user.hal_screwyhud in 1 to 2))
@@ -73,9 +72,9 @@
else if(user.hal_screwyhud == 5)
icon_state = "stambuffer29"
return FALSE
- else if(user.stamina_buffer >= user.stamina_buffer_max)
+ else if(user.stamina_buffer >= buffer_max)
icon_state = "stambuffer29"
return FALSE
else
- icon_state = "stambuffer[FLOOR((user.stamina_buffer / user.stamina_buffer_max) * 29, 1)]"
+ icon_state = "stambuffer[FLOOR((user.stamina_buffer / buffer_max) * 29, 1)]"
return TRUE
diff --git a/code/controllers/configuration/entries/stamina_combat.dm b/code/controllers/configuration/entries/stamina_combat.dm
new file mode 100644
index 0000000000..b519f7403e
--- /dev/null
+++ b/code/controllers/configuration/entries/stamina_combat.dm
@@ -0,0 +1,31 @@
+/datum/config_entry/number/stamina_combat
+ integer = FALSE
+ abstract_type = /datum/config_entry/number/stamina_combat
+
+/// Maximum stamina buffer
+/datum/config_entry/number/stamina_combat/buffer_max
+ config_entry_value = 75
+
+/// Seconds until percent_regeneration_out_of_combat kicks in
+/datum/config_entry/number/stamina_combat/out_of_combat_timer
+ config_entry_value = 5
+
+/// Base regeneration per second
+/datum/config_entry/number/stamina_combat/base_regeneration
+ config_entry_value = 1
+
+/// Combat mode regeneration per second
+/datum/config_entry/number/stamina_combat/combat_regeneration
+ config_entry_value = 5
+
+/// After out_of_combat_timer elapses, additionally regenerate this percent of missing stamina per second. Unaffected by combat mode.
+/datum/config_entry/number/stamina_combat/missing_percent_regeneration_out_of_combat
+ config_entry_value = 30
+
+/// Seconds after an action for which your regeneration is penalized
+/datum/config_entry/number/stamina_combat/post_action_penalty_delay
+ config_entry_value = 2
+
+/// Factor to multiply by for penalizing post-action-stamina-regen
+/datum/config_entry/number/stamina_combat/post_action_penalty_factor
+ config_entry_value = 0.25
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 36acdc77a8..d34073ea24 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -8,6 +8,8 @@
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
faction += "[REF(src)]"
+ stamina_buffer = INFINITY
+ UpdateStaminaBuffer()
GLOB.mob_living_list += src
/mob/living/prepare_huds()
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index f6008cd7d6..126672312a 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -159,15 +159,9 @@
//---End
// Stamina Buffer---
- /// Our maximum stamina buffer
- var/stamina_buffer_max = STAMINA_BUFFER_CAPACITY
/// Our stamina buffer
- var/stamina_buffer = STAMINA_BUFFER_CAPACITY
+ var/stamina_buffer
/// Stamina buffer regen modifier
var/stamina_buffer_regen_mod = 1
- /// Standard stamina buffer regen per second
- var/stamina_buffer_regen = STAMINA_BUFFER_REGEN_PER_SECOND
- /// Standard stamina buffer regen per second with combat mode
- var/stamina_buffer_regen_combat = STAMINA_BUFFER_REGEN_PER_SECOND_COMBAT
/// Last time stamina buffer regen was done
var/stamina_buffer_regen_last = 0
diff --git a/code/modules/mob/living/stamina_buffer.dm b/code/modules/mob/living/stamina_buffer.dm
index c2495eb633..f7f450aa45 100644
--- a/code/modules/mob/living/stamina_buffer.dm
+++ b/code/modules/mob/living/stamina_buffer.dm
@@ -20,18 +20,28 @@
* Updates our stamina buffer amount.
*/
/mob/living/proc/UpdateStaminaBuffer(updating_hud = TRUE)
- var/time = world.time - stamina_buffer_regen_last
- var/missing_stamina_percent = getStaminaLoss() / STAMINA_CRIT
- var/stamina_buffer_max = src.stamina_buffer_max * (1 - (missing_stamina_percent * STAMINA_BUFFER_STAMCRIT_CAPACITY_PERCENT_PENALTY))
- stamina_buffer_regen_last = world.time
- if(stamina_buffer > stamina_buffer_max)
- stamina_buffer = stamina_buffer_max
+ if(!(combat_flags & COMBAT_FLAG_STAMINA_BUFFER))
return
- var/combat_mode = !SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)
- var/action_penalty = (((world.time - last_action) <= STAMINA_BUFFER_REGEN_ACTION_PENALTY_TIME) && STAMINA_BUFFER_REGEN_ACTION_PENALTY_FACTOR) || 1
- var/stamina_penalty = 1 - (missing_stamina_percent * STAMINA_BUFFER_STAMCRIT_REGEN_PERCENT_PENALTY)
- var/regen = time * 0.1 * ((combat_mode? stamina_buffer_regen_combat : stamina_buffer_regen) * stamina_buffer_regen_mod)
- stamina_buffer += min((stamina_buffer_max - stamina_buffer), action_penalty * stamina_penalty * regen)
+ var/time = world.time - stamina_buffer_regen_last
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/buffer_max, buffer_max)
+ stamina_buffer_regen_last = world.time
+ if(stamina_buffer >= buffer_max)
+ stamina_buffer = buffer_max
+ return
+ else if(!time)
+ return
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/out_of_combat_timer, out_of_combat_timer)
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/base_regeneration, base_regeneration)
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/combat_regeneration, combat_regeneration)
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/missing_percent_regeneration_out_of_combat, missing_percent_regeneration_out_of_combat)
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/post_action_penalty_delay, post_action_penalty_delay)
+ CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/post_action_penalty_factor, post_action_penalty_factor)
+ var/base_regen = (SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))? base_regeneration : combat_regeneration
+ var/time_since_last_action = world.time - last_action
+ var/action_penalty = (((time_since_last_action) < (post_action_penalty_delay * 10)) && post_action_penalty_factor) || 1
+ var/out_of_combat_bonus = (time_since_last_action < (out_of_combat_timer * 10))? ((buffer_max - stamina_buffer) * (missing_percent_regeneration_out_of_combat * 0.01)) : 0
+ var/regen = ((base_regen * action_penalty) + out_of_combat_bonus) * time * 0.1 * stamina_buffer_regen_mod
+ stamina_buffer += min((buffer_max - stamina_buffer), regen)
if(updating_hud)
hud_used?.staminabuffer?.mark_dirty()
@@ -39,7 +49,5 @@
* Boosts our stamina buffer by this much.
*/
/mob/living/proc/RechargeStaminaBuffer(amount)
- var/missing_stamina_percent = getStaminaLoss() / STAMINA_CRIT
- var/stamina_buffer_max = src.stamina_buffer_max * (1 - (missing_stamina_percent * STAMINA_BUFFER_STAMCRIT_CAPACITY_PERCENT_PENALTY))
- stamina_buffer += min(amount, stamina_buffer_max - stamina_buffer)
- hud_used?.staminabuffer?.mark_dirty()
+ stamina_buffer += abs(amount)
+ UpdateStaminaBuffer()
diff --git a/tgstation.dme b/tgstation.dme
index 5e92d0870a..db31db6000 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -291,6 +291,7 @@
#include "code\controllers\configuration\entries\plushies.dm"
#include "code\controllers\configuration\entries\policy.dm"
#include "code\controllers\configuration\entries\resources.dm"
+#include "code\controllers\configuration\entries\stamina_combat.dm"
#include "code\controllers\subsystem\acid.dm"
#include "code\controllers\subsystem\adjacent_air.dm"
#include "code\controllers\subsystem\air.dm"