mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 11:13:16 +00:00
Adds a fairly simple system that allows adjusting various numbers like max health, incoming damage, outgoing melee damage, etc. The nice part is that changing certain variables this way (like max health) is a lot safer than manually setting the max health var directly. Changes a lot of short lines of code to point towards a variable's getter or setter helper instead of reading the var directly so the modifiers can work. Endoarmor, delayed toxin sting, Enfeebling sting, and recursive adrenaline overdose now use the modifier system. Enfeebling sting now only lasts two minutes, from five minutes, however it now also reduces the victim's melee damage by 25%/50%, and increases the damage they suffer by 10%/35%, for normal and recursive respectively. Delayed Toxin Sting's effects are now felt all at once instead of over the course of a few minutes.
106 lines
4.8 KiB
Plaintext
106 lines
4.8 KiB
Plaintext
// This is a datum that tells the mob that something is affecting them.
|
|
// The advantage of using this datum verses just setting a variable on the mob directly, is that there is no risk of two different procs overwriting
|
|
// each other, or other weirdness. An excellent example is adjusting max health.
|
|
|
|
/datum/modifier
|
|
var/name = null // Mostly used to organize, might show up on the UI in the Future(tm)
|
|
var/desc = null // Ditto.
|
|
var/icon_state = null // See above.
|
|
var/mob/living/holder = null // The mob that this datum is affecting.
|
|
var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else.
|
|
var/on_created_text = null // Text to show to holder upon being created.
|
|
var/on_expired_text = null // Text to show to holder when it expires.
|
|
var/hidden = FALSE // If true, it will not show up on the HUD in the Future(tm)
|
|
var/stacks = MODIFIER_STACK_FORBID // If true, attempts to add a second instance of this type will refresh expire_at instead.
|
|
var/flags = 0 // Flags for the modifier, see mobs.dm defines for more details.
|
|
|
|
// Now for all the different effects.
|
|
// Percentage modifiers are expressed as a multipler. (e.g. +25% damage should be written as 1.25)
|
|
var/max_health_flat // Adjusts max health by a flat (e.g. +20) amount. Note this is added to base health.
|
|
var/max_health_percent // Adjusts max health by a percentage (e.g. -30%).
|
|
var/disable_duration_percent // Adjusts duration of 'disables' (stun, weaken, paralyze, confusion, sleep, halloss, etc) Setting to 0 will grant immunity.
|
|
var/incoming_damage_percent // Adjusts all incoming damage.
|
|
var/incoming_brute_damage_percent // Only affects bruteloss.
|
|
var/incoming_fire_damage_percent // Only affects fireloss.
|
|
var/incoming_tox_damage_percent // Only affects toxloss.
|
|
var/incoming_oxy_damage_percent // Only affects oxyloss.
|
|
var/incoming_clone_damage_percent // Only affects cloneloss.
|
|
var/incoming_hal_damage_percent // Only affects halloss.
|
|
var/incoming_healing_percent // Adjusts amount of healing received.
|
|
var/outgoing_melee_damage_percent // Adjusts melee damage inflicted by holder by a percentage. Affects attacks by melee weapons and hand-to-hand.
|
|
var/slowdown // Negative numbers speed up, positive numbers slow down movement.
|
|
|
|
/datum/modifier/New(var/new_holder)
|
|
holder = new_holder
|
|
..()
|
|
|
|
// Checks to see if this datum should continue existing.
|
|
/datum/modifier/proc/check_if_valid()
|
|
if(expire_at && expire_at < world.time) // Is our time up?
|
|
src.expire()
|
|
|
|
/datum/modifier/proc/expire(var/silent = FALSE)
|
|
if(on_expired_text && !silent)
|
|
to_chat(holder, on_expired_text)
|
|
on_expire()
|
|
holder.modifiers.Remove(src)
|
|
qdel(src)
|
|
|
|
// Override this for special effects when it gets removed.
|
|
/datum/modifier/proc/on_expire()
|
|
return
|
|
|
|
/mob/living
|
|
var/list/modifiers = list() // A list of modifier datums, which can adjust certain mob numbers.
|
|
|
|
/mob/living/Destroy()
|
|
remove_all_modifiers(TRUE)
|
|
..()
|
|
|
|
// Called by Life().
|
|
/mob/living/proc/handle_modifiers()
|
|
if(!modifiers.len) // No work to do.
|
|
return
|
|
// Get rid of anything we shouldn't have.
|
|
for(var/datum/modifier/M in modifiers)
|
|
M.check_if_valid()
|
|
|
|
// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks.
|
|
// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES)
|
|
/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null)
|
|
// First, check if the mob already has this modifier.
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(ispath(modifier_type, M.type))
|
|
switch(M.stacks)
|
|
if(MODIFIER_STACK_FORBID)
|
|
return // Stop here.
|
|
if(MODIFIER_STACK_ALLOWED)
|
|
break // No point checking anymore.
|
|
if(MODIFIER_STACK_EXTEND)
|
|
// Not allow to add a second instance, but we can try to prolong the first instance.
|
|
if(expire_at && world.time + expire_at > M.expire_at)
|
|
M.expire_at = world.time + expire_at
|
|
return
|
|
|
|
// If we're at this point, the mob doesn't already have it, or it does but stacking is allowed.
|
|
var/datum/modifier/mod = new modifier_type(src)
|
|
if(expire_at)
|
|
mod.expire_at = world.time + expire_at
|
|
if(mod.on_created_text)
|
|
to_chat(src, mod.on_created_text)
|
|
modifiers.Add(mod)
|
|
|
|
// Removes a specific instance of modifier
|
|
/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE)
|
|
M.expire(silent)
|
|
|
|
// Removes all modifiers of a type
|
|
/mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE)
|
|
for(var/datum/modifier/M in modifiers)
|
|
if(ispath(modifier_type, M.type))
|
|
M.expire(silent)
|
|
|
|
// Removes all modifiers, useful if the mob's being deleted
|
|
/mob/living/proc/remove_all_modifiers(var/silent = FALSE)
|
|
for(var/datum/modifier/M in modifiers)
|
|
M.expire(silent) |