mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
Productionizes #80615. The core optimization is this: ```patch - var/hint = to_delete.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up. + var/hint = to_delete.Destroy(force) // Let our friend know they're about to get fucked up. ``` We avoid a heap allocation in the form of copying the args over to a new list. A/B testing shows this results in 33% better overtime, and in a real round shaving off a full second of self time and 0.4 seconds of overtime--both of these would be doubled in the event this is merged as the new proc was only being run 50% of the time.
85 lines
4.1 KiB
Plaintext
85 lines
4.1 KiB
Plaintext
/**
|
|
* ### Enrage buffs component
|
|
*
|
|
* Scales some statistics of a living mob (speed or attack power or such) based on how hurt it is.
|
|
*/
|
|
/datum/component/health_scaling_effects
|
|
/// Health percentage (between 0 and 1) at which you are considered to get the full "max" effect
|
|
var/max_health_threshold
|
|
/// Health percentage (between 0 and 1) at which you are considered to get the full "min" effect
|
|
var/min_health_threshold
|
|
/// Modification to apply to the lower bound of your attack while your health is at or above the max threshold
|
|
var/max_health_attack_modifier_lower
|
|
/// Modification to apply to the lower bound of your attack while your health is at or above the min threshold
|
|
var/min_health_attack_modifier_lower
|
|
/// Modification to apply to the upper bound of your attack while your health is at or above the max threshold
|
|
var/max_health_attack_modifier_upper
|
|
/// Modification to apply to the upper bound of your attack while your health is at or above the min threshold
|
|
var/min_health_attack_modifier_upper
|
|
/// Modification to movement speed to apply while your health is at or above the max threshold
|
|
var/max_health_slowdown
|
|
/// Modification to movement speed to apply while your health is at or above the min threshold
|
|
var/min_health_slowdown
|
|
/// A callback which is sent the mob's current ratio between the max and min values, for updating mob-specific effects
|
|
var/datum/callback/additional_status_callback
|
|
|
|
/datum/component/health_scaling_effects/Initialize(
|
|
max_health_threshold = 1,
|
|
min_health_threshold = 0.25,
|
|
max_health_attack_modifier_lower = 0,
|
|
min_health_attack_modifier_lower = 0,
|
|
max_health_attack_modifier_upper = 0,
|
|
min_health_attack_modifier_upper = 0,
|
|
max_health_slowdown = 0,
|
|
min_health_slowdown = 0,
|
|
additional_status_callback = null,
|
|
)
|
|
if (!isliving(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.max_health_threshold = max_health_threshold
|
|
src.min_health_threshold = min_health_threshold
|
|
src.max_health_attack_modifier_lower = max_health_attack_modifier_lower
|
|
src.min_health_attack_modifier_lower = min_health_attack_modifier_lower
|
|
src.max_health_attack_modifier_upper = max_health_attack_modifier_upper
|
|
src.min_health_attack_modifier_upper = min_health_attack_modifier_upper
|
|
src.max_health_slowdown = max_health_slowdown
|
|
src.min_health_slowdown = min_health_slowdown
|
|
src.additional_status_callback = additional_status_callback
|
|
|
|
RegisterSignal(parent, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(on_health_changed))
|
|
|
|
/datum/component/health_scaling_effects/UnregisterFromParent()
|
|
UnregisterSignal(parent, COMSIG_LIVING_HEALTH_UPDATE)
|
|
return ..()
|
|
|
|
/datum/component/health_scaling_effects/Destroy(force)
|
|
additional_status_callback = null
|
|
return ..()
|
|
|
|
/// Called when mob health changes, recalculates the ratio between maximum and minimum
|
|
/datum/component/health_scaling_effects/proc/on_health_changed(mob/living/source)
|
|
SIGNAL_HANDLER
|
|
var/current_health_percentage = source.health / source.maxHealth
|
|
var/max_min_ratio = clamp(INVERSE_LERP(min_health_threshold, max_health_threshold, current_health_percentage), 0, 1)
|
|
|
|
INVOKE_ASYNC(src, PROC_REF(update_stats), source, max_min_ratio)
|
|
|
|
/// Update statistics based on provided interpolator between maximum and minimum values
|
|
/datum/component/health_scaling_effects/proc/update_stats(mob/living/source, max_min_ratio)
|
|
if (max_health_attack_modifier_lower != 0 || min_health_attack_modifier_lower != 0)
|
|
var/lower_modifier = LERP(min_health_attack_modifier_lower, max_health_attack_modifier_lower, max_min_ratio)
|
|
source.melee_damage_lower = initial(source.melee_damage_lower) + lower_modifier
|
|
if (max_health_attack_modifier_upper != 0 || min_health_attack_modifier_upper != 0)
|
|
var/upper_modifier = LERP(min_health_attack_modifier_upper, max_health_attack_modifier_upper, max_min_ratio)
|
|
source.melee_damage_upper = initial(source.melee_damage_upper) + upper_modifier
|
|
|
|
if (max_health_slowdown != 0 || min_health_slowdown != 0)
|
|
source.add_or_update_variable_movespeed_modifier(
|
|
/datum/movespeed_modifier/health_scaling_speed_buff,
|
|
multiplicative_slowdown = LERP(min_health_slowdown, max_health_slowdown, max_min_ratio),
|
|
)
|
|
|
|
if (additional_status_callback)
|
|
additional_status_callback.Invoke(max_min_ratio)
|