Some things cannot be standardised when applying damage as it will always be different for every object, for example force and armour penetration. These will always be passed in if the damage dealing requires it.
Applying damage without an instantiated damage source:
target.apply_damage(/datum/damage_source/chemical, /datum/damage/burn, 20 * rem)
Apply damage with an instantiated damage source:
damage_source.apply_direct(target, /datum/damage/burn, 20 * rem)
Defines some parameters for what is dealing damage. These will be consistently applied.
For example, a battle hammer may have a heavy blunt damage source and things like knifes would have a short blade damage source. Toolboxes would have a light blunt damage source etc.
Things like chemicals and armour bypassing damage sources would have their own datums.
// This is for applying the damage directly to the target rather than from performing an attack.
/datum/damage_source/proc/apply_direct(mob/living/target, damage_type, damage_amount, target_zone, update_health = TRUE)
// Has an atom target to allow for easy refactoring to swing combat later
// Default behaviour is to just apply directly if the target is a mob or deal structural damage if the target is a structure (how?)
/datum/damage_source/proc/deal_attack(mob/living/attacker, obj/item/attacking_item, atom/target, damage_type, damage_amount, target_zone = null, update_health = TRUE)
Applies the damage source to the specified target with the provided damage amount. This will do different things depending on the damage source, chemical damage is internal and will apply the damage directly.
PowerfulBacon If we are instantiating a damage source for every object this will need to be done lazilly, otherwise we may get a decent performance cost at roundstart from instantiating so many of these objects.
Damage sources will be able to define stuff such as the actions/procs to call when damage is defined and how to mutate the damage type (For example, a sharp object may have a higher chance of inflicting bleeding damage as well).
What is applied here?
What ones will we need?
We can add other specific sources as needed which just use the default behaviour of applying the damage directly.
Simplies the type of damage that will be applied. For now these are just burn, brute, oxyloss, cloneloss, brain however will be expanded on in the future if we want a more complicated medical system.
This makes new damage types much easier to add as it is more modularised.
In the future these may be expanded to either:
/datum/damage/proc/apply(mob/living/target, damage)
/datum/damage/proc/apply(obj/item/organ/target, damage)
/datum/damage/proc/apply(obj/item/bodypart/target, damage)
Armour penetration is applied in the damage source and this simply applies the damage directly to the mob, in the specified amount by doing something like calling adjustBruteLoss.
What is applied here?
What ones will we need?
Q: We may want to move towards something like swing combat in the future. How can we make apply_damage either easy enough to refactor or have enough data that all we would need to do is modify the contents of the apply damage function?
This has been thought about and applied in the above proposal. This is why we have both apply_direct and deal_attack. Deal_attack will allow us to give certain damage sources different swing combat effects.
Q: Should we refactor things that can recieve damage into a datum or component so that we don't need to have 3 different apply procs? Really we need interfaces for this but byond doesn't support it.
For now, we will just do type checks for structures and organs.
Q: How should we handle healing damage?