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); } }