RPG damage/heal over time

Hi, i was actually trying to implement HOTs and DOTs,
i missed the other topic and just saw it when it got closed.
I saved those scripts for now, in my ever growing “made by Brian” folder xD
What would we do without him!

I did it like this, with a coroutine in the existing HealthEffect we already had,
just enable the bool, and set the amount of ticks and the interval.
have not found any problems with it so far, is this an acceptable way of doing it?

using RPG.Attributes;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace RPG.Abilities.Effects
{
    [CreateAssetMenu(fileName = "Health Effect", menuName = "RPG/Abilities/Effects/Health")]
    public class HealthEffect : EffectStrategy
    {
        [SerializeField] float healthChange;

        //Only when Hot or Dot
        [SerializeField] bool healthChangeOverTime = false;
        [SerializeField] int numberOfTicks = 5;
        [SerializeField] float timeBetweenTicks = 2f;
        float healthPerTick;
        float ticksRemaining;

        public override void StartEffect(AbilityData data, Action finished)
        {
            foreach(var target in data.GetTargets())
            {
                var health = target.GetComponent<Health>();

                if (health)
                {
                    if (healthChangeOverTime)
                    {
                        data.StartCoroutine(HealthChangeOverTime(data.GetUser(), health, finished));
                    }
                    else
                    {
                        if (healthChange < 0)
                        {
                            health.TakeDamage(data.GetUser(), -healthChange);
                        }
                        else
                        {
                            health.Heal(healthChange);
                        }
                    }
                }
            }

            if(healthChangeOverTime) { return; }
            finished();
        }

        public IEnumerator HealthChangeOverTime(GameObject user, Health health, Action finished)
        {
            healthPerTick = healthChange / numberOfTicks;
            ticksRemaining = numberOfTicks;

            while (ticksRemaining > 0 && !health.IsDead())
            {
                if(healthPerTick < 0)
                {
                    health.TakeDamage(user, -healthPerTick);
                }
                else
                {
                    health.Heal(healthPerTick);
                }

                yield return new WaitForSeconds(timeBetweenTicks);
                ticksRemaining--;
            }
            finished();
            yield break;
        }
    }
}

Forgot to say, i tested this on myself by changing a heal to -health.
When it killed me i got a null reference, which was caused by;
Me killing myself and not being able to gain Exp from it because i was dead…

Absolutely. There are many paths to the same goal!

That’s caused because your player does not have an ExperienceGained stat (nor do you want him to unless you want your enemies to level up when they kill you.)
There’s actually a quick fix for this in Progression.GetStat:

        public float GetStat(Stat stat, CharacterClass characterClass, int level, float fallback=0)
        {
            BuildLookup();

            if (!lookupTable[characterClass].ContainsKey(stat))
            {
                return fallback;
            }

            float[] levels = lookupTable[characterClass][stat];

            if (levels.Length == 0)
            {
                return fallback;
            }

            if (levels.Length < level)
            {
                return levels[levels.Length - 1];
            }

            return levels[level - 1];
        }
1 Like

Thank you once more for taking the time Brian!

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

Privacy & Terms