Encounter / Assets / Scripts / InventoryManagement / Spell.cs
Spell.cs
Raw
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Retainer class for the information within the Spell Scriptable Object
/// </summary>
public class Spell
{
    #region Properties and Variables
    public int SpellID { get; private set; }
    public string SpellName { get; private set; }
    public string SpellDescription { get; private set; }
    public int SpellCost { get; set; }
    public Vector2Int SavingThrow { get; set; }
    public Sprite SpellSprite { get; private set; }
    public SpellSO.Element SpellType { get; private set; }
    public List<SpellSO.SpellEffect> SpellEffects { get; private set; }
    public bool DicelessSpell { get; private set; }
    public List<Dice.DiceR> Dice { get; private set; }
    public List<string> HelperEffects { get; private set; }
    public List<Dictionary<Entity.Entities, List<int>>> Paths { get; private set; }
    public bool HasRequirements { get; private set; }
    public List<SpellSO.PossReqs> Requirements { get; private set; }
    public GameObject SpellEffectSequence 
    {
        get => retainedSpellEffect;
        private set => retainedSpellEffect = value; 
    }

    private GameObject retainedSpellEffect;

    public readonly int numberOfStatReqs;
    public readonly List<Vector3Int> reqStatList;

    public readonly int numberOfSecStatReqs;
    public readonly List<Vector3Int> reqSecStatList;

    public readonly bool requiresSpecific;
    public readonly int numberOfItems;
    public readonly List<string> reqItems;
    public readonly bool requiresWeaponType;
    public readonly WeaponSO.Type weaponType;
    public readonly bool requiresApparelType;
    public readonly ApparelSO.Type apparelType;

    public readonly int numberOfAbilities;
    public readonly List<string> reqAbilities;

    public readonly List<SpellSO.OtherEffects> miscEffects;
    public readonly ClimateManager.Weather weatherToChangeTo;
    public readonly List<GameObject> minionSummons;

    public readonly ModifierSO Modifier;

    public readonly ModifierSO BuffModifier;
    public readonly ModifierSO DebuffModifier;

    public readonly SpellSO.SavingThrowFailEffect SaveFailEffect;

    public readonly bool CanChooseAllOfType;
    public readonly bool CanChooseEffects;
    public readonly bool Left;
    public readonly bool BuffLeft;
    public readonly bool DebuffLeft;
    public readonly bool Right;
    public readonly bool BuffRight;
    public readonly bool DebuffRight;
    public readonly bool UniqueTargetting;
    #endregion

    public bool IsDebuffLeftAndBuffRight()
        => DebuffLeft && BuffRight;
    public bool IsDebuffRightAndBuffLeft()
        => DebuffRight && BuffLeft;

    

    public Spell(SpellSO reference)
    {
        try
        {
            if (string.IsNullOrEmpty(reference.Name) || string.IsNullOrEmpty(reference.Description) || reference.ID < 0 || reference.Spell_Sprite == null)
                throw new ArgumentNullException("An impossible value was shown in creating a Spell class. Creating error Spell.");

            this.SpellID                   = reference.ID;
            this.SpellName                 = reference.Name;
            this.SpellDescription          = reference.Description;
            this.SpellCost                 = reference.Mana_Cost;
            
            if (reference.HasSavingThrow)
            {
                this.SavingThrow            = reference.SavingThrow;
                this.SaveFailEffect         = reference.FailedThrowEffect;
            }
            else
                this.SavingThrow = new Vector2Int(-1, -1);

            this.SpellSprite               = reference.Spell_Sprite;
            this.SpellType                 = reference.Type;
            this.SpellEffects              = new List<SpellSO.SpellEffect>(reference.Effects);
            this.CanChooseAllOfType        = reference.Can_Choose_All_Of_Type;
            this.CanChooseEffects          = reference.Can_Choose_Effect;
            this.Paths                     = new List<Dictionary<Entity.Entities, List<int>>>();
            for (int i = 0; i < reference.EntityAffiliations.Count; i++)
            {
                switch (i)
                {
                    case 0:
                        Dictionary<Entity.Entities, List<int>> map1 = new Dictionary<Entity.Entities, List<int>>
                        {
                            { reference.EntityAffiliations[i], reference.PathOne }
                        };
                        Paths.Add(map1);
                        break;
                    case 1:
                        Dictionary<Entity.Entities, List<int>> map2 = new Dictionary<Entity.Entities, List<int>>
                        {
                            { reference.EntityAffiliations[i], reference.PathTwo }
                        };
                        Paths.Add(map2);
                        break;
                    case 2:
                        Dictionary<Entity.Entities, List<int>> map3 = new Dictionary<Entity.Entities, List<int>>
                        {
                            { reference.EntityAffiliations[i], reference.PathThree }
                        };
                        Paths.Add(map3);
                        break;
                }
            }

            this.HasRequirements            = reference.Has_Requirement;
            if (this.HasRequirements)
            {
                this.Requirements = new List<SpellSO.PossReqs>(reference.Requirements);

                if (this.Requirements.Contains(SpellSO.PossReqs.Stats))
                {
                    this.numberOfStatReqs = reference.Number_Of_Stat_Reqs;
                    this.reqStatList = new List<Vector3Int>(reference.Stats_List);
                }
                if (this.Requirements.Contains(SpellSO.PossReqs.Sec_Stats))
                {
                    this.numberOfSecStatReqs = reference.Number_Of_Sec_Stat_Reqs;
                    this.reqSecStatList = new List<Vector3Int>(reference.Sec_Stats_List);
                }
                if (this.Requirements.Contains(SpellSO.PossReqs.Item))
                {
                    this.requiresSpecific = reference.Requires_Specific;
                    this.numberOfItems = reference.Number_Of_Items;
                    this.reqItems = new List<string>(reference.Item_List);
                    this.requiresWeaponType = reference.Requires_WType;
                    this.requiresApparelType = reference.Requires_AType;
                    this.weaponType = reference.W_Type;
                    this.apparelType = reference.A_Type;
                }
                if (this.Requirements.Contains(SpellSO.PossReqs.Ability))
                {
                    this.numberOfAbilities = reference.Number_Of_Abs;
                    this.reqAbilities = new List<string>(reference.Ability_List);
                }
            }

            this.Left                       = reference.Left;
            this.Right                      = reference.Right;
            this.BuffLeft                   = reference.BuffLeft;
            this.BuffRight                  = reference.BuffRight;
            this.DebuffLeft                 = reference.DebuffLeft;
            this.DebuffRight                = reference.DebuffRight;
            this.BuffModifier               = reference.BuffModifier;
            this.DebuffModifier             = reference.DebuffModifier;
            this.UniqueTargetting           = reference.UniqueTargetting;
            
            if (!reference.Requires_Dice && !this.SpellEffects.Contains(SpellSO.SpellEffect.Damage) && !this.SpellEffects.Contains(SpellSO.SpellEffect.Heal))
                this.DicelessSpell         = true;

            if (this.SpellEffects.Contains(SpellSO.SpellEffect.Buff) || this.SpellEffects.Contains(SpellSO.SpellEffect.Debuff))
                Modifier                    = reference.Modifier;

            this.Dice                       = new List<Dice.DiceR>(reference.Dice);
            this.HelperEffects              = new List<string>(reference.HelperEffects);

            if (reference.Effects.Contains(SpellSO.SpellEffect.Other))
            {
                this.miscEffects = new List<SpellSO.OtherEffects>(reference.EffectsPerformed);
                if (this.miscEffects.Contains(SpellSO.OtherEffects.ManipulateWeather))
                    this.weatherToChangeTo = reference.WeatherChange;
                if (this.miscEffects.Contains(SpellSO.OtherEffects.SummonMinions))
                    this.minionSummons = new List<GameObject>(reference.Minions);
            }
        }
        catch
        {
            this.SpellID                   = -1;
            this.SpellName                 = "I am Error";
            this.SpellDescription          = "Magic bursts from an unknown source, ultimately unusable";
            this.SpellCost                 = 0;
            this.SpellSprite               = Resources.Load<Sprite>("Sprites/Error");
            this.SpellType                 = SpellSO.Element.Strange;
            this.SpellEffects              = new List<SpellSO.SpellEffect>
            {
                global::SpellSO.SpellEffect.Damage
            };

            this.HasRequirements            = false;
            this.CanChooseAllOfType         = false;
            this.CanChooseEffects           = false;
            this.Paths                      = new List<Dictionary<Entity.Entities, List<int>>>();
            this.Left                       = false;
            this.Right                      = false;
            this.BuffLeft                   = false;
            this.BuffRight                  = false;
            this.DebuffLeft                 = false;
            this.DebuffRight                = false;
            this.BuffModifier               = null;
            this.DebuffModifier             = null;

            this.Dice                       = new List<Dice.DiceR>
            {
                global::Dice.DiceR.Four
            };

            this.HelperEffects = new List<string>()
            {
                "Error",
                "Error",
                "Error"
            };
        }

        try
        {
            string spellNameSearch = this.SpellName;

            if (spellNameSearch.Contains(':'))
                spellNameSearch = spellNameSearch.Remove(spellNameSearch.IndexOf(':'), 1);
            else if (spellNameSearch.Contains('\''))
                spellNameSearch = spellNameSearch.Remove(spellNameSearch.IndexOf('\''), 1);

            this.SpellEffectSequence = Resources.Load<GameObject>($"SpellEffects/{spellNameSearch}");
        }
        catch
        {
            this.SpellEffectSequence = null;
        }
    }

    public void AlterHelperEffect(int index, string newHelperString)
        => HelperEffects[index] = newHelperString;
    public void AlterDescription(string newDescription)
        => SpellDescription = newDescription;
    public static bool operator ==(Spell left, Spell right)
    {
        bool isLeftNull = false;
        bool isRightNull = false;
        try
        {
            string check = left.SpellName;
        }
        catch { isLeftNull = true; }
        try
        {
            string check = right.SpellName;
        }
        catch { isRightNull = true; }

        if (isLeftNull && isRightNull)
            return true;
        else if ((isLeftNull && !isRightNull) || (!isLeftNull && isRightNull))
            return false;

        return left.SpellID == right.SpellID && left.SpellName == right.SpellName;
    }

    public static bool operator !=(Spell left, Spell right)
    {
        return !(left == right);
    }
    public override bool Equals(object obj)
    {
        if (obj is not Spell)
            return false;

        return obj as Spell == this;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(SpellID, SpellName);
    }
}