Status Effect damage

How would you code, status damage. For instance an axe, hits with both a blunt damage and fire damage. How would you code the fire damage?.

Well, for starters, sharpen that axe! My Axe cuts for chopping damage!

On a more serious note, there is a bit of work involved with this… You’ll need to have an enum for the various damage types, as you’ve probably guessed already.

For single damage types, it would be easy enough to pass the damage type along with the damage in TakeDamage, but your axe (your Unsharpened Flaming Axe of Bludgeoning) imparts two different types of damage. That’s going to require some extra work… in this case, I’d probably use a class with the Damage Type, and the Damage Weight… something like this…


Then in the WeaponConfig:

[SerializeField] List<DamageCharacteristic> characteristics = new List<DamageCharacteristic>;
        public enum DamageType
	{
		Normal,
		Blunt,
		Slashing,
		Piercing,
		Freezing,
		Flaming,
		Nature,
		Air,
		Light,
		Dark
	}
	
	[System.Serializable]
	public class DamageCharacteristic
	{
		public DamageType damageType = DamageType.Normal;
		public float amount=1; //0=none, .5=50%, 1=100%
	}

In WeaponConfig we’ll need a couple of new entries:

    [SerializeField] private List<DamageCharacteristic> characteristics = new List<DamageCharacteristic>();

    public IEnumerable<DamageCharacteristic> GetCharacteristics()
    {
        if (characteristics.Count == 0)
        {
            yield return new DamageCharacteristic();
        }
        else
        {
            foreach (var characteristic in characteristics)
            {
                yield return characteristic;
            }
        }
    }

Now TakeDamage in Health will need an extra field

        public void TakeDamage(int amount, GameObject damageDealer, IEnumerable<DamageCharacteristic> characteristics)
        {
            foreach (var characteristic in characteristics)
            {
                float assignedDamage = amount * characteristic.amount;
                // Deal with the rest of TakeDamage here, including adjustments for damage type (in characteristic.damageType)  
                //If character dies in any of these iterations, simply return; to end the damage cycle.
            }
        }

And of course, in Hit, or anywhere that assesses damage, you’ll need to pass on the WeaponConfig.GetCharacteristics() to the TakeDamage field.

So the way this will work is that by default, a weapon will have a damage characteristic of 100% normal damage. If this is the case, there’s really not a need to serialize any entries for this… just leave the list blank, and the GetCharacteristics method will automatically return a default Characteristic in the collection of Normal, 100%.
If we have a Characteristic, then we’ll add it to the list, along with the percent of weapon damage that applies to that characteristic. For example, your axe may impart 1/2 of it’s damage as blunt (sharpen that axe!) and the other 1/2 of it’s damage as Flaming, so two characteristics, each with 0.5 as the amount.
Then in TakeDamage, you’ll cycle through each of the characteristics, applying the damage. From there, it’s up to you to determine how blunt damage affects a character vs. Normal damage (same with flaming damage).

Wow, just wow. You’re amazing, last question, so how would I characterize an enemy to only be weak to fire. Or weak to physical damage?.

Probably by storing a list of weaknesses (or more likely strengths)…
The same DamageCharacteristic class could be used to demonstrate a defense against a given class…
So… a damage calculation might check to see if the character had a DamageCharacteristic that matched the characteristic of the incoming damage, then multiply the incoming damage by (1-amount).

If it would receive normal damage (no bonuses or penalties), then no entry is needed. If the enemy is weak to fire (takes 50% more damage, for example, then a negative number would be in the entry (-.5f would be 50% more damage from fire). If the enemy is immune to the damage, then an entry of 1 would do the trick (1-1=0% damage received).

About the math I understand, but not about using the same list in the enemy class.

List<DamageCharacteristic> defensiveCharacteristics = new List<DamageCharacteristic>();

public float AdjustDamage(float amount, DamageType damageType)
{
    foreach(var characteristic in defensiveCharacteristics)
    {
          if(characteristic.damageType == damageType)
          {
               return amount * (1-characteristic.amount);
          }
    }
    return amount;
}
1 Like

Thank you. So the damage characteristics. It’s better if it’s its own class, or it should be in all classes?.

It needs to be accessible from Health… but it might be best to have a Monobehavior that stores this list to put on the enemies. I’d probably also put them on the StatsEquipableItem class, and make StatsEquipment a provider as well… perhaps through an interface to get the damage characteristics… You’ll have to play around with it.

Can an interface return a list?. I thought it just returns method signatures

An interface can have a method signature that includes a list as the return type (or I actually prefer IEnumerables… like:

public interface IDamageCharacteristicProvider
{
     IEnumerable<DamageCharacteristic> GetDamageCharacteristics();
}

I didn’t know, that something like this . Can be done, I have to research more on ienumerable

Thank you

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms