Untitled

 avatar
unknown
csharp
a year ago
6.3 kB
17
Indexable
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ProjectGeneralEnum;
using System.Linq;
using Unity.VisualScripting;
using JetBrains.Annotations;

public class StatusEffect : Skill
{
    public GeneralistAbilityManager source;

    public float duration;
    public float timeRunning;

    //The stacks is a recount of StatusEffect scripts of the same type on the entity if the StackingMode is Independant or ApplyLastRemoveOldest;
    //else its a parameter that determines the strenght of this one StatusEffect script over the entity. Only in this last case is this parameter used.
    public int currentStacks;


    public void Update()
    {

        if (timeRunning > duration) { TerminateStatus(); }
        else { timeRunning += Time.deltaTime; }

    }

    ///<param name="stackingMode"> IncreaseStackCount and IncreaseStackCountAndResetTimer ONLY accept one script per source at the same time </param>
    ///<param name="maxStacks"> How many times this effect can be stacked. Either by adding copies of the script or by increasing the strength of a single one </param>
    ///<param name="stacksToApply"> Only for IncreaseStackCount and IncreaseStackCountAndResetTimer stackingMode </param>
    public void InitializeStatus(string skillName, GeneralistAbilityManager source, StackingRestrictions stackingRestrictions, int maxStacks, StackingMode stackingMode, float duration, int stacksToApply = 1)
    {

        bool checkForSourceOnly = false;

        switch (stackingRestrictions) 
        {

            case StackingRestrictions.Fixed:
                
                checkForSourceOnly = false;

            break;
            
            case StackingRestrictions.FixedPerSource:
            
                checkForSourceOnly = true;

            break;

        }

        //This list should hold a register of all skills of the same name; if its relevant will also filter of the same name and from the same source
        List<StatusEffect> listOfStacks = StackOfStatusOfType(skillName, checkForSourceOnly, source);
        bool scriptStackCapReached = listOfStacks.Count >= maxStacks;

        switch (stackingMode) 
        {

            //Add the new status ONLY if the cap has NOT been reached, else do nothing
            case StackingMode.Independant:

                if (scriptStackCapReached) { Destroy(this); }

            break;

            //If the cap has been reached removes the oldest status and applies the new one in its place. Else add it normally. Rest of stacks run normally
            case StackingMode.ApplyLastRemoveOldest:

                if (scriptStackCapReached) 
                {
                    StatusEffect oldest = CheckForOldestStatus(listOfStacks);
                    Destroy(oldest);
                    listOfStacks.Remove(oldest); 
                }

            break;

            //The effect is meant to be stacked, run a single script and increase the stack parameter of it up to the cap, if there are none add this normally
            case StackingMode.IncreaseStackCount:

                //The list should only contain more than a single script before removing this one since this type of stacking uses only one script to stack
                //This case assumes the list contains just 2 items
                if (listOfStacks.Count > 1) 
                {
                    if (listOfStacks.Contains(this)) { listOfStacks.Remove(this); }
                    int totalStacks = Mathf.Clamp(listOfStacks[0].currentStacks + stacksToApply, 0, maxStacks);
                    listOfStacks[0].currentStacks = totalStacks;
                    Destroy(this);
                }
                
                else 
                {
                    currentStacks = stacksToApply;
                }

            break;

            //The effect is meant to be stacked and reset on new application, run a single script and increase the stack parameter of it up to the cap and reset its timer; if there are none add this normally
            case StackingMode.IncreaseStackCountAndResetTimer:

                //The list should only contain more than a single script before removing this one since this type of stacking uses only one script to stack
                //This case assumes the list contains just 2 items
                if (listOfStacks.Count > 1)
                {
                    if (listOfStacks.Contains(this)) { listOfStacks.Remove(this); }
                    int totalStacks = Mathf.Clamp(listOfStacks[0].currentStacks + stacksToApply, 0, maxStacks);
                    listOfStacks[0].currentStacks = totalStacks;
                    listOfStacks[0].timeRunning = 0;
                    Destroy(this);
                }

                else
                {
                    currentStacks = stacksToApply;
                }

            break;

        }

    }

    public List <StatusEffect> StackOfStatusOfType (string skillName, bool checkForThisSourceOnly, GeneralistAbilityManager source) 
    {

        List<StatusEffect> list = this.gameObject.GetComponents<StatusEffect>().ToList<StatusEffect>();

        foreach (StatusEffect statusEffect in list)
        {
            if (statusEffect.skillName != skillName) { list.Remove(statusEffect); }
        }

        if (checkForThisSourceOnly) 
        {
            foreach (StatusEffect statusEffect in list) 
            {
                if (statusEffect.source != source) { list.Remove(statusEffect); }
            }

        }

        return list;
    }

    public StatusEffect CheckForOldestStatus(List<StatusEffect> list) 
    {
        
        StatusEffect currentOlder = null;
        
        foreach (StatusEffect statusEffect in list) 
        {

            if (currentOlder == null || statusEffect.timeRunning > currentOlder.timeRunning) 
            {
                currentOlder = statusEffect;
            }

        }

        return currentOlder;
    }

    //Override this on child classes for different effects before removing an status
    public void TerminateStatus ()
    {
        Destroy(this);
    }
}
Editor is loading...
Leave a Comment