Encounter / Assets / Scripts / AbilityBrain.cs
AbilityBrain.cs
Raw
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
using System.Linq;
using System;
using Unity.Collections;

/// <summary>
/// Handles affecting entities based on their abilities
/// </summary>
public static class AbilityBrain
{
    public static Dictionary<int, Ability> GetAbilityList()
        => abilityList;
    public static Dictionary<int, Spell> GetSpellList() 
        => spellList;
    public static Dictionary<string, Modifier> GetModifierList() 
        => modifierList;

    private static Dictionary<int, Ability> abilityList;                // Complete Ability list available for reference
    private static Dictionary<int, Spell> spellList;                    // Complete Spell list available for reference
    private static Dictionary<string, Modifier> modifierList;           // Complete Modifier list available for reference
    private static Task completeLoading;                                // Trigger for when all of the abilities have been loaded into the brain

    private static CursedAuraInteractions cursedAura;

    private const string ToHitAdd               = "ToHitAdd";
    private const string ToHitMinus             = "ToHitMinus";
    private const string AddDamageValue         = "AddDamageValue";
    private const string AddDamageType          = "AddDamageType";
    private const string MinusDamageValue       = "MinusDamageValue";
    private const string AddArmor               = "AddArmor";
    private const string MinusArmor             = "MinusArmor";
    private const string DamageBack             = "DamageBack";
    private const string HalfCrits              = "HalfCrits";
    private const string FullOffHandSignal      = "FullOffHandSignal";

    private static bool shallowHealRowdyBunch   = false;

    /// <summary>
    /// Acquirer for the state of loading
    /// Null is when loading is still occurring and complete is when the loading is complete
    /// </summary>
    /// <returns></returns>
    public static Task GetLoadingState()
        => completeLoading;
    /// <summary>
    /// Loads all of the abilities available in the resources folder
    /// </summary>
    public static async Task LoadAllAspects()
    {
        completeLoading = null;

        abilityList = new();
        AbilitySO[] abilityNodes = Resources.LoadAll<AbilitySO>("Abilities");
        foreach (AbilitySO abilityItem in abilityNodes)
        {
            Ability ability = Globals.TurnAbilityFromObject(abilityItem);
            if (!abilityList.ContainsKey(ability.AbilityID))
                abilityList.Add(ability.AbilityID, ability);
        }

        spellList = new();
        SpellSO[] spellNodes = Resources.LoadAll<SpellSO>("Spells");
        foreach (SpellSO spellItem in spellNodes)
        {
            Spell spell = Globals.TurnSpellFromObject(spellItem);
            if (!spellList.ContainsKey(spell.SpellID))
                spellList.Add(spell.SpellID, spell);
        }
        modifierList = new();
        ModifierSO[] modifierNodes = Resources.LoadAll<ModifierSO>("Modifiers");
        foreach (ModifierSO modifierItem in modifierNodes)
        {
            Modifier mod = Globals.TurnModifierFromObject(modifierItem);
            if (!modifierList.ContainsKey(mod.Name))
                modifierList.Add(mod.Name, mod);
        }

        completeLoading = Task.CompletedTask;
        await Task.CompletedTask;
    }
    public static Modifier RandomBuff()
    {
        List<Modifier> modifiers = new List<Modifier>(modifierList.Values);

        Modifier rolledModifier;

        do
        {
            rolledModifier = modifiers[UnityEngine.Random.Range(0, modifiers.Count)];

        } while (rolledModifier.Type is ModifierSO.Type.Debuff || IsIncompatibleModifier(rolledModifier));

        return rolledModifier;

        static bool IsIncompatibleModifier(Modifier modBeingChecked)
        {
            return modBeingChecked.Name switch
            {
                "Blue Shield" => true,
                "Tracked Target" => true,

                _ => false,
            };
        }
    }
    public static Modifier RandomDebuff()
    {
        List<Modifier> modifiers = new List<Modifier>(modifierList.Values);

        Modifier rolledModifier;

        do
        {
            rolledModifier = modifiers[UnityEngine.Random.Range(0, modifiers.Count)];

        } while (rolledModifier.Type is ModifierSO.Type.Buff || IsIncompatibleModifier(rolledModifier));

        return rolledModifier;

        static bool IsIncompatibleModifier(Modifier modBeingChecked)
        {
            return modBeingChecked.Name switch
            {
                "Impaled"                   => true,
                "Life Contract"             => true,
                "Experiencing Nightmare"    => true,
                "Snared"                    => true,
                "Bleeding"                  => true,
                "Attention Getter"          => true,

                _ => false,
            };
        }
    }
    public static void EventPreChecks(Player playerState, Ally[] allies)
    {
        // To be used when an event encounter is loading in

        // 1 ---> Cursed Aura
        if (cursedAura != null)
            cursedAura.RollEventPreEvent();
    }                
    public static void EventPostChecks(Player playerState, Ally[] allies)
    {
        // To be used when an event encounter has ended

        // 1 ---> Cursed Aura
        if (cursedAura != null)
            cursedAura.RollEventPostEvent();

        ModificationChecks(playerState, allies);
    }
    public static void ShopChecks(Player playerState, Ally[] allies, TownUI shopUI)
    {
        // To be used when the shop is loading in
        Inventory playerInven = playerState.GetInventory();
        List<Inventory> allyInvens = new();
        if (allies != null)
        {
            foreach (Ally a in allies)
                allyInvens.Add(a.GetInventory());
        }

        // 10 ---> Slick Barterer
        SlickBartererFunction(allies, shopUI, playerInven);

        // 80 ---> Missionary's Grace
        MissionarysGraceFunction(shopUI, playerInven, allyInvens);
    }

    public static async Task PostBattleChecks(Player player, Ally[] allies)
    {
        // To be activated when the loot screen is activated
        Inventory playerInven = player.GetInventory();
        List<Inventory> allyInvens = new();
        if (allies != null)
        {
            foreach (Ally a in allies)
            {
                try
                {
                    allyInvens.Add(a.GetInventory());
                }
                catch { continue; }
            }
        }

        // 1 ---> Cursed Aura Interactions
        if (cursedAura != null)
            await cursedAura.RollPostBattleEvent();

        await Task.CompletedTask;
    }
    public static Dictionary<string, object> StartTurnCheck(Entity entity, Player player, Ally[] allyRetainers, Enemy[] enemyRetainers)
    {
        Inventory invenToUse = entity.GetInventory();
        Dictionary<string, object> triggers = new Dictionary<string, object>();

        // 29 ---> Unstable Magical Core
        UnstableMagicalCoreFunction(invenToUse, triggers);

        // 37 ---> Adrenal Regeneration
        AdrenalRegenerationFunction(invenToUse, triggers);

        // 81 ---> Battle Shanties
        BattleShantiesFunction(player, allyRetainers, enemyRetainers, invenToUse);

        // 97 ---> Chaotic Energy
        ChaoticEnergyManaSurgeFunction(entity, invenToUse);

        return triggers;
    }

    public static Dictionary<string, (List<string>, List<object>)> PreTurnCompletionCheck(Entity attacker, Entity target, Player player, Ally[] leftComps, 
                                                                                Enemy[] rightEnemies, object toHitObject, 
                                                                                SortedDictionary<int, (int, Dice)> damageRolls, ref bool hasCrit)
    {
        Inventory attackingInven = attacker.GetInventory();
        Inventory targetInven = target.GetInventory();
        bool firstModifierCall = true;  // This bool needs to be injected into each of these lists

        SortedDictionary<int, (int, Dice)> toHitRolls = null;
        bool toHitSucceededEnemySide = false;

        if (toHitObject is SortedDictionary<int, (int, Dice)> alliedSideRolls)
            toHitRolls = alliedSideRolls;
        else if (toHitObject is bool check)
            toHitSucceededEnemySide = check;

        // Gather current weapon type
        WeaponSO.Type weaponType;
        try
        {
            weaponType = attacker is Enemy e ? e.GetDamageType() : attackingInven.GetPrimaryActiveWeapon().WeaponType;
        }
        catch
        {
            weaponType = (attacker as Ally).attackType;
        }
        Dictionary<string, (List<string>, List<object>)> triggers = new Dictionary<string, (List<string>, List<object>)>();

        // 2 ---> Ambidextrous
        AmbidextrousFunction(toHitRolls, attackingInven, triggers);

        // 5 ---> Sadism
        firstModifierCall = SadismFunction(attacker, target, weaponType, attackingInven, firstModifierCall);

        // 6 ---> Focused Target
        FocusedTargetFunction(attackingInven, target, triggers);

        // 7 ---> BoneCrusher
        firstModifierCall = BoneCrusherFunction(attacker, weaponType, attackingInven, firstModifierCall);

        // 12 ---> Scavenger
        ScavengerFunction(attackingInven, triggers);

        // 13 ---> Pack Tactics
        PackTacticsFunction(rightEnemies, attackingInven, triggers);

        // 14 ---> Venom Production
        VenomProductionFunction(damageRolls, attackingInven, triggers);

        // 15 ---> Sinister Presence
        SinisterPresenceAttackedFunction(targetInven, triggers);
        SinisterPresenceAttackingFunction(attackingInven, triggers);

        // 16 ---> Eye For Treasure
        EyeForTreasureFunction(attacker, targetInven, attackingInven, triggers);

        // 17 ---> Rowdy Bunch
        RowdyBunchArmorFunction(targetInven, rightEnemies, triggers);
        RowdyBunchDamageFunction(attacker, rightEnemies, damageRolls, attackingInven, triggers);

        // 27 ---> Riposte
        RiposteFunction(targetInven, attacker, triggers);

        // 28 ---> Unflinching
        UnflinchingFunction(targetInven, triggers);

        // 31 ---> Noxious Aura
        NoxiousAuraFunction(attacker, damageRolls, targetInven, triggers);

        // 37 ---> Adrenal Regeneration Trigger
        AdrenalRegenerationTriggerFunction(hasCrit, targetInven);

        // 44 ---> Kleptomaniac
        KleptomaniacFunction(attackingInven, targetInven, weaponType, triggers);

        // 46 ---> Interfering Abberation
        InterferingAbberationFunction(target, player, leftComps, rightEnemies, targetInven, triggers);

        // 47 ---> Blunt Weapon Adept
        BluntWeaponAdeptFunction(attackingInven, triggers);

        // 48 ---> Blunt Weapon Master Damage
        BluntWeaponMasterDamageFunction(attackingInven, triggers);

        // 49 ---> Extended Weapon Adept
        ExtendedWeaponAdeptFunction(attackingInven, triggers);

        // 50 ---> Extended Weapon Master Damage
        ExtendedWeaponMasterDamageFunction(attackingInven, triggers);

        // 51 ---> Magic Weapon Adept
        MagicWeaponAdeptFunction(attackingInven, triggers);

        // 52 ---> Magic Weapon Master Damage
        MagicWeaponMasterDamageFunction(attackingInven, triggers);

        // 53 ---> Ranged Weapon Adept
        RangedWeaponAdeptFunction(attackingInven, triggers);

        // 54 ---> Ranged Weapon Master Damage
        RangedWeaponMasterDamageFunction(attackingInven, triggers);

        // 55 ---> Sharp Weapon Adept
        SharpWeaponAdeptFunction(attackingInven, triggers);

        // 56 ---> Sharp Weapon Master Damage
        SharpWeaponMasterDamageFunction(attackingInven, triggers);

        // 76 ---> Firearm Weapon Adept 
        FirearmWeaponAdeptFunction(attackingInven, triggers);

        // 77 ---> Firearm Weapon Master Damage
        FirearmWeaponMasterDamageFunction(attackingInven, triggers);

        // 57 ---> Surprise!
        hasCrit = SurpriseFunction(hasCrit, attackingInven);

        // 59 ---> Poisonous Barbs
        PoisonousBarbsFunction(attacker, target, attackingInven, targetInven, toHitSucceededEnemySide);

        // 60 ---> Ingrained Roots
        IngrainedRootsToHitFunction(attackingInven, triggers);

        // 63 ---> Trapper
        TrapperProcFunction(targetInven, toHitSucceededEnemySide, triggers);

        // 69 ---> Trigger Finger
        TriggerFingerFunction(targetInven, triggers);

        // 79 ---> Telekinetic Damage Mitigation
        TelekineticDamageMitigationFunction(damageRolls, targetInven, triggers, attacker);

        // 82 ---> Steelskin
        SteelskinFunction(target, targetInven, triggers);

        // 132 ---> Double Tap
        DoubleTapFunction(attacker, target, damageRolls, attackingInven, triggers);

        // 133 ---> Deadly Assassin
        hasCrit = DeadlyAssassinFunction(hasCrit, attackingInven);

        // 135 ---> Stance of the Guardian
        StanceGuardianFunction(target, player, leftComps, rightEnemies, triggers);

        // 137 ---> Stance of the Cunning
        StanceCunningFunction(attacker, attackingInven, triggers);

        return triggers;
    }

    public static Task PostTurnCheck(List<Entity> entities, bool areFainted)
    {
        // To be used when an entity takes their turn
        Dictionary<Entity, List<Ability>> entityAbilities = new();
        foreach (Entity entity in entities)
        {
            Inventory invenToUse = entity.GetInventory();
            try
            {
                entityAbilities.Add(entity, invenToUse.Abilities);
                entityAbilities[entity].AddRange(invenToUse.limitedAbilities);
            }
            catch { }
        }

        // 0 ---> Defy Death (Revival)
        DefyDeathRevivalFunction(entityAbilities, areFainted);

        // 9 ---> Hemophilia 
        HemophiliaFunction(entityAbilities, areFainted);

        // 17 ---> Rowdy Bunch (Shallow Heal Removal)
        RowdyBunchShallowHealCheck(entityAbilities, areFainted);

        // 19 ---> Adrenaline Rush
        AdrenalineRushFunction(entityAbilities);

        // 20 ---> Berserker
        BerserkerFunction(entityAbilities);

        // 30 ---> Dream Master (Sleep Check Function)
        DreamMasterNullSleepFunction(entityAbilities);

        // 43 ---> Reconstitution
        ReconstitutionFunction();

        // 45 ---> Will of the Damned
        WillOfTheDamnedFunction(entityAbilities);

        // 143 ---> Thick Fat
        ThickFatFunction(entityAbilities);

        return Task.CompletedTask;
    }

    public static (bool, bool, bool) PreToHitRollCheck(Entity attacker, Entity target, Ally[] allyComps, Enemy[] enemyComps)
    {
        bool isDisadvantaged = false;
        bool isAdvantaged = false;
        bool autoHit = false;

        // 58 ---> Sap Production (UNIQUE TO PHYLL)
        isDisadvantaged = SapProductionFunction(target, allyComps, isDisadvantaged);

        // 78 ---> Executioner
        autoHit = ExecutionerCheck(attacker, target, autoHit);

        // 109 ---> Overkill
        OverkillCritFunction(attacker);

        // 118 ---> Rumbling Onslaught
        if (attacker.GetInventory().Abilities.Contains(abilityList[118]) || attacker.GetInventory().limitedAbilities.Contains(abilityList[118]))
            isAdvantaged = true;

        // 122 ---> Guardian Angel
        if (target.GetInventory().Abilities.Contains(abilityList[122]) || target.GetInventory().limitedAbilities.Contains(abilityList[122]))
            isDisadvantaged = true;

        // 130 ---> Roulette
        if (attacker.GetInventory().Abilities.Contains(abilityList[130]))
            isAdvantaged = true;

        if (isDisadvantaged)
        {
            // 113 ---> Disciplined
            if (attacker.GetInventory().Abilities.Contains(abilityList[113]) || attacker.GetInventory().limitedAbilities.Contains(abilityList[113]))
                isDisadvantaged = false;

            // 140 ---> Tactical Recovery
            if (attacker.GetInventory().Abilities.Contains(abilityList[140]) || attacker.GetInventory().limitedAbilities.Contains(abilityList[140]))
                isDisadvantaged = false;
        }

        return (isDisadvantaged, isAdvantaged, autoHit);
    }
    public static async Task PreBattleChecks(Player player, Ally[] allyComps, Enemy[] enemyComps)
    {
        // To be activated before anybody takes their turn (potentially call the action text?);
        ClimateManager.Weather currentWeather = ClimateManager.Instance.GetWeather();
        List<Inventory> genInvens = new List<Inventory>
        {
            player.GetInventory()
        };

        if (allyComps != null)
        {
            foreach (Ally ally in allyComps)
                genInvens.Add(ally.GetInventory());
        }
        foreach (Enemy enemy in enemyComps)
            genInvens.Add(enemy.GetInventory());

        // 11 ---> Photosynthesis (Strength Portion)
        PhotosynthesisStrengthFunction(currentWeather, player, genInvens);

        // 17 ---> Rowdy Bunch (Shallow Healing Portion)
        RowdyBunchShallowHealFunction(enemyComps, genInvens);

        // 21 ---> Life of the Party
        LifeOfThePartyDebuffFunction(genInvens);

        // 23 ---> Golden Horseshoe
        GoldenHorseshoeFunction(enemyComps, genInvens);

        // 26 ---> Quick Learner
        QuickLearnerExpFunction(enemyComps, genInvens);

        // 30 ---> Dream Master Flag Switch Function
        foreach (Inventory inven in genInvens)
        {
            if (inven.Abilities.Contains(abilityList[30]) || inven.limitedAbilities.Contains(abilityList[30]))
            {
                if (!inven.AttachedEntity.EntityFlags.Contains("Dream Master"))
                    inven.AttachedEntity.EntityFlags.Add("Dream Master");
            }
        }

        // 57 ---> Surprise!
        SurpriseHideFunction(genInvens);

        // 67 ---> Sharp Tracker
        SharpTrackerFunction(player, allyComps, enemyComps, genInvens);

        // 133 ---> Deadly Assassin
        DeadlyAssassinHideFunction(genInvens);

        await Task.CompletedTask;
    }
    public static int DamageChecks(int damage, SpellSO.Element attackerElement, Entity attacker, Entity target, SortedDictionary<int, (int, Dice)> damageRolls, Spell spellUsed = null)
    {
        Inventory attackerInven = attacker.GetInventory();
        Inventory targetInven = target.GetInventory();

        bool rollsNull = damageRolls is null;

        // 32 ---> Earth Elemental More Damage)
        damage = EarthElementalDamageFunction(damage, attackerElement, damageRolls, attackerInven, rollsNull);

        // 33 ---> Ice Elemental Increase Mana
        IceElementalManaFunction(attackerElement, attacker, attackerInven);

        // 34 ---> Fire Elemental Burn Effect
        FireElementalBurnFunction(damage, attackerElement, target, attackerInven);

        // 35 ---> Air Elemental Amped Effect
        AirElementalAmpedFunction(damage, attackerElement, attacker, attackerInven);        

        // 110 ---> Sinister Thoughts
        if (attackerInven.Abilities.Contains(abilityList[110]) || attackerInven.limitedAbilities.Contains(abilityList[110]))
            damage += 2;

        // 32 - 35 ---> Elemental Absorption Function
        damage = ElementalAbsorptionFunction(damage, attackerElement, target, targetInven, spellUsed);

        return damage;
    }
    public static int SpellChecks(Spell currentSpell, Entity spellUser, Entity spellTarget, int spellValue, bool[] indicators, bool isConsume = false)
    {
        // Indicators { Healing, Refill, Buff, Debuff, Damage, Misc }

        Inventory userInven = spellUser.GetInventory();
        Inventory targetInven = spellTarget.GetInventory();

        if (indicators[0])              // Healing
        {
            // 39 ---> Medically Competent
            spellValue = MedicallyCompetentFunction(spellValue, isConsume, targetInven);

            // 41 ---> Nutrient Bank Healing
            spellValue = NutrientBankFunction(spellValue, userInven, targetInven);

            // 111 ---> Harmonious Thoughts Bonus
            if (userInven.Abilities.Contains(abilityList[111]) || userInven.limitedAbilities.Contains(abilityList[111]))
                spellValue += 2;
        }
        else if (indicators[1])         // Refilling
        {
            // Saturated Conduits Refilling
            spellValue = SaturatedConduitsRefillFunction(spellValue, targetInven);

            // 111 ---> Harmonious Thoughts Bonus
            if (userInven.Abilities.Contains(abilityList[111]) || userInven.limitedAbilities.Contains(abilityList[111]))
                spellValue += 2;
        }
        else if (indicators[2])         // Buffing
        {
            
        }
        else if (indicators[3])         // Debuffing
        {

        }
        else if (indicators[4])         // Damage
        {
            // Magical Resilience
            if (spellTarget.GetInventory().Abilities.Contains(abilityList[117]) || spellTarget.GetInventory().limitedAbilities.Contains(abilityList[117]))
                spellValue /= 2;
        }
        else if (indicators[5])         // Misc/Other
        {
            
        }

        // Death and Decay increase check
        if (spellUser.GetInventory().Abilities.Contains(abilityList[114]) && currentSpell is not null)
        {
            if (currentSpell.SpellType is SpellSO.Element.Necro)
                spellValue += 3;
        }

        return spellValue;
    }
    public static int ConsumableChecks(Entity conUser, Entity conTarget, int conValue, bool[] indicators)
    {
        // Indicators { Healing, Refill, Buff, Debuff, Damage, Misc }
        return SpellChecks(null, conUser, conTarget, conValue, indicators, true);
    }
    public static void ModificationChecks(Player player, Ally[] allies = null)
    {
        // When an ability like Vampirism is gained at any point this function is called to immediately affect the individuals afflicted
        List<Ability> playerAbilities = new List<Ability>(player.GetInventory().Abilities);
        playerAbilities.AddRange(player.GetInventory().limitedAbilities);
        Dictionary<Ally, List<Ability>> allyAbilities = new Dictionary<Ally, List<Ability>>();
        if (allies != null)
        {
            foreach (Ally ally in allies)
            {
                allyAbilities.Add(ally, ally.GetInventory().Abilities);
                allyAbilities[ally].AddRange(ally.GetInventory().limitedAbilities);
            }
        }

        // 4 ---> Vampirism
        VampirismFunction(player, allyAbilities, playerAbilities);

        // 21 ---> Life of the Party Event Encounter effect
        LifeOfThePartyEventFunction(playerAbilities, allyAbilities);

        // 22 ---> Devout Follower
        DevoutFollowerFunction(player, allyAbilities, playerAbilities);

        // 25 ---> Magical Apprentice
        MagicalApprenticeFunction(player, allyAbilities, playerAbilities);

        // 26 ---> Quick Learner
        QuickLearnerSpellDiscountFunction(player, allyAbilities, playerAbilities);

        // 38 ---> Dense Setae
        DenseSetaeFunction(player, playerAbilities, allyAbilities);

        // 40 ---> Saturated Conduits
        SaturatedConduitsIncreaseManaFunction(player, playerAbilities, allyAbilities);

        // 48 ---> Blunt Weapon Master
        BluntWeaponMasterTriggerFunction(player, playerAbilities, allyAbilities);

        // 50 ---> Extended Weapon Master
        ExtendedWeaponMasterTriggerFunction(player, playerAbilities, allyAbilities);

        // 52 ---> Magic Weapon Master
        MagicWeaponMasterTriggerFunction(player, playerAbilities, allyAbilities);

        // 54 ---> Ranged Weapon Master
        RangedWeaponMasterTriggerFunction(player, playerAbilities, allyAbilities);

        // 56 ---> Sharp Weapon Master
        SharpWeaponMasterTriggerFunction(player, playerAbilities, allyAbilities);

        // 77 ---> Firearm Weapon Master
        FirearmWeaponMasterTriggerFunction(player, playerAbilities, allyAbilities);

        // 72 ---> Servant of the Divine
        ServantOfTheDivineFunction(player, playerAbilities);

        // 73 ---> Servant of the Hells
        ServantOfTheHellsFunction(player, playerAbilities);

        // 74 ---> Servant of the Deep
        ServantOfTheDeepFunction(player, playerAbilities);

        // 75 ---> Servant of the Eldritch
        ServantOfTheEldritchFunction(player, playerAbilities);

        // 84 ---> Fixated Focus
        FixatedFocusFunction(player, allyAbilities);

        // 85 ---> Inquisitive Soul
        InquisitiveSoulFunction(player, playerAbilities, allyAbilities);

        // 93 ---> Field Focus
        FieldFocusManaReductionFunction(player, playerAbilities);

        // 94 ---> Elemental Mastery
        ElementalMasteryFunction(player, playerAbilities);

        // 97 ---> Chaotic Energy
        ChaoticEnergyMaxManaIncrease(player, playerAbilities, allyAbilities);

        // 98 ---> Pirate Legacy
        PiratyLegacyFunction(player, playerAbilities);

        // 99 ---> Bandit Legacy
        BanditLegacyFunction(player, playerAbilities);

        // 100 ---> Man-At-Arms Legacy
        ManAtArmsFunction(player, playerAbilities);

        // 104 ---> Death Knight
        DeathKnightFunction(player, playerAbilities);

        // 105 ---> Paladin
        PaladinFunction(player, playerAbilities);

        // 107 ---> Great Wizard
        GreatWizardFunction(player, playerAbilities);

        // 110 ---> Sinister Thoughts
        SinisterThoughtsFunction(player, playerAbilities);

        // 111 ---> Harmonious Thoughts
        HarmoniousThoughtsFunction(player, playerAbilities);

        // 114 ---> Death and Decay
        DeathAndDecayElementFunction(player, playerAbilities);

        // 115 ---> Hold the Line
        HoldTheLineArmorFunction(player, playerAbilities);

        // 119 ---> Patron's Solution
        PatronsSolutionFunction(player, playerAbilities);

        // 120 ---> Manic Breakthrough
        ManicBreakthroughFunction(player, playerAbilities);

        // 121 ---> Sin Incarnation
        SinIncarnationFunction(player, playerAbilities);

        // 122 ---> Guardian Angel
        GuardianAngelFunction(player, playerAbilities);

        // 123 ---> Monstrous Form
        MonstrousFormFunction(player, playerAbilities);

        // 124 ---> Psionic Nexus
        PsionicNexusFunction(player, playerAbilities);

        // 135 ---> Stance of the Guardian
        StanceGuardianModFunction(player, playerAbilities);

        // 136 ---> Stance of the Slayer
        StanceSlayerModFunction(player, playerAbilities);

        // 137 ---> Stance of the Cunning
        StanceCunningModFunction(player, playerAbilities);

        // 138 ---> Multi Attack
        MultiAttackFunction(player, playerAbilities, allyAbilities);

        // 139 ---> Rapid Decisions
        RapidDecisionsFunction(player, playerAbilities, allyAbilities);
    }
    public static void EndEncounterChecks(Player playerState, Ally[] allies = null)
    {
        List<Inventory> invens = new List<Inventory>()
        {
            playerState.GetInventory()
        };
        if (allies != null)
        {
            foreach (Ally a in allies)
                invens.Add(a.GetInventory());
        }

        // 0 ---> Defy Death (Cooldown)
        DefyDeathCooldownFunction(invens);

        // 1 ---> Cursed Aura
        if (cursedAura != null)
            cursedAura.RollEndEncounterEvent();

        // 8 ---> Survivalist
        SurvivalistFunction(playerState, invens);

        // 11 ---> Photosynthesis
        PhotosynthesisHealingFunction(playerState, invens);
        PhotosynthesisStrengthResetFunction(playerState, invens);

        // 63 ---> Trapper Reset Trap
        TrapperResetFunction(invens);

        // 65 ---> Natural Herbalist
        NaturalHerbalistFunction(invens);

        ModificationChecks(playerState, allies);
        TurnOffAllChecks();
    }
    private static void TurnOffAllChecks()
    {
        shallowHealRowdyBunch = false;
    }
    #region General Ability Functions
    private static Task PhotosynthesisHealingFunction(Player playerState, List<Inventory> invensToCheck)
    {
        foreach (Inventory inven in invensToCheck)
        {
            if (inven.Abilities.Contains(abilityList[11]))
            {
                bool check = inven.Abilities.Find(a => a.AbilityID is 11).uniqueCounter % 2 is 0;
                if (check)
                {
                    inven.AttachedEntity.IncreaseHealth(DiceRoller.RollDice(new DFour()));
                    inven.AttachedEntity.StatusChanged();
                }

                ++inven.Abilities.Find(a => a.AbilityID is 11).uniqueCounter;
            }
        }

        return Task.CompletedTask;
    }
    private static void PhotosynthesisStrengthFunction(ClimateManager.Weather currentWeather, Player player, List<Inventory> genInvens)
    {
        if (currentWeather is not ClimateManager.Weather.Sunny)
            return;

        foreach (var inven in genInvens.Where(inven => inven.Abilities.Contains(abilityList[11]) || inven.limitedAbilities.Contains(abilityList[11])))
        {
            List<Ability> abilityCol = new List<Ability>();
            abilityCol.AddRange(inven.Abilities);
            abilityCol.AddRange(inven.limitedAbilities);

            Ability abRef = abilityCol.Where(ability => ability.AbilityID is 11).FirstOrDefault();
            
            inven.EntityStatLink.SetModifierToStat(EntityStats.Stat.Strength, 1);
            abRef.active = true;
        }
            
    }
    private static Task PhotosynthesisStrengthResetFunction(Player playerState, List<Inventory> genInvens)
    {
        if (ClimateManager.Instance.GetWeather() is ClimateManager.Weather.Sunny)
        {
            foreach (Inventory inven in genInvens)
            {
                if (inven.Abilities.Contains(abilityList[11]) || inven.limitedAbilities.Contains(abilityList[11]))
                {
                    List<Ability> abilityCollection = new List<Ability>();
                    abilityCollection.AddRange(inven.Abilities);
                    abilityCollection.AddRange(inven.limitedAbilities);

                    Ability abRef = abilityCollection.Where(ability => ability.AbilityID is 11).FirstOrDefault();

                    if (abRef.active)
                    {
                        inven.EntityStatLink.RemoveModifierToStat(EntityStats.Stat.Strength, 1);
                        abRef.active = false;
                    }
                }
            }
        }

        return Task.CompletedTask;
    }
    private static Task SurvivalistFunction(Player player, List<Inventory> invensToCheck)
    {
        foreach (Inventory inven in invensToCheck)
        {
            if (inven.Abilities.Contains(abilityList[8]))
            {
                if (inven.AttachedEntity == null)
                {
                    player.IncreaseHealth((int)Math.Ceiling(player.RetrieveMaxHealth() * .05f));
                    GeneralUI.Instance.SetInformation(false);
                }
                else if (inven.AttachedEntity is Ally ally)
                {
                    ally.IncreaseHealth((int)(ally.RetrieveMaxHealth() * .05f));
                    ally.StatusChanged();
                }
            }
        }

        return Task.CompletedTask;
    }
    private static Task SlickBartererFunction(Ally[] allies, TownUI shopUI, Inventory playerInven)
    {
        bool discount_10 = false;                       // Trigger for the Slick Barterer ability that can be activated only once

        if (playerInven.Abilities.Contains(abilityList[10]) || playerInven.limitedAbilities.Contains(abilityList[10]))
        {
            shopUI.ModifyShopQualities("Slick Barterer");
            discount_10 = true;
        }
        foreach (Ally ally in allies)
        {
            if ((ally.GetInventory().Abilities.Contains(abilityList[10]) || ally.GetInventory().limitedAbilities.Contains(abilityList[10])) && !discount_10)
            {
                shopUI.ModifyShopQualities("Slick Barterer");
                discount_10 = true;
                break;
            }
        }

        return Task.CompletedTask;
    }
    private static void HemophiliaFunction(Dictionary<Entity, List<Ability>> entityInventories, bool areFainted)
    {
        if (areFainted)
            return;

        foreach (KeyValuePair<Entity, List<Ability>> entity in entityInventories)
        {
            if (entity.Value.Contains(abilityList[9]))
            {
                if (!entity.Key.GatherModList().SmartModCheck("Bleeding"))
                    return;

                Ability abRef = entity.Value.Find(a => a.AbilityID == 9);
                int counter = abRef.uniqueCounter;

                if (counter < 5 && counter != 0)
                    counter++;
                else if (counter is 0)
                {
                    entity.Key.AddModToList(abRef.Mod);
                    counter++;
                }
                else if (counter is 5)
                    counter = 0;

                abRef.uniqueCounter = counter;
            }
        }
    }
    private static bool BoneCrusherFunction(Entity entity, WeaponSO.Type weaponType, Inventory invenToUse, bool firstModifierCall)
    {
        if (invenToUse.Abilities.Contains(abilityList[7]) || invenToUse.limitedAbilities.Contains(abilityList[7]))
        {
            if (weaponType is WeaponSO.Type.Blunt)
            {
                entity.SetModifierAndChance(abilityList[7].Mod, abilityList[7].SavingThrow, firstModifierCall);
                return false;
            }
        }

        return firstModifierCall;
    }
    private static bool SadismFunction(Entity entity, Entity target, WeaponSO.Type weaponType, Inventory invenToUse, bool firstModifierCall)
    {
        try
        {
            if (invenToUse.Abilities.Contains(abilityList[5]) || invenToUse.limitedAbilities.Contains(abilityList[5]))
            {
                List<Ability> abilities = new List<Ability>(invenToUse.Abilities);
                abilities.AddRange(invenToUse.limitedAbilities);
                Ability abRef = abilities.Find(ability => ability.AbilityID == 5);

                if (weaponType is WeaponSO.Type.Sharp)
                {
                    if (target.GatherModList().Contains(abRef.Mod) && !abRef.active)
                    {
                        entity.GatherStats().SetModifierToStat(EntityStats.Stat.ToCritMod, 1);
                        abRef.active = true;
                        return firstModifierCall;
                    }
                    else if (abRef.active)
                    {
                        entity.GatherStats().RemoveModifierToStat(EntityStats.Stat.ToCritMod, 1);
                        abRef.active = false;
                    } 

                    entity.SetModifierAndChance(abRef.Mod, abRef.SavingThrow, firstModifierCall);
                    return false;
                }
            }
        }
        catch (NullReferenceException) when (target == null)
        {
            Debug.LogWarning("Null Reference Exception detected trying to activate Sadism Function... Skipping...");
        }

        return firstModifierCall;
    }
    private static void DefyDeathRevivalFunction(Dictionary<Entity, List<Ability>> entityInventories, bool areFainted)
    {
        if (!areFainted)
            return;

        foreach (KeyValuePair<Entity, List<Ability>> entity in entityInventories)
        {
            if (entity.Value.Contains(abilityList[0]))
            {
                Ability ability = entity.Value[0];

                if (!ability.active)
                    return;

                if (ability.active && entity.Key.RetrieveHealth() <= 0)
                {
                    entity.Key.Revive();
                    ability.active = false;
                }
            }
        }
    }
    private static void DefyDeathCooldownFunction(List<Inventory> invens)
    {
        foreach (Inventory inven in invens)
        {
            if (inven.Abilities.Contains(abilityList[0]))
            {
                Ability a = inven.Abilities[0];

                if (!a.active)
                {
                    a.uniqueCounter++;
                    if (a.uniqueCounter == 10)
                    {
                        a.active = true;
                        a.uniqueCounter = 0;
                    }
                }
            }
        }
    }
    private static void VampirismFunction(Player player, Dictionary<Ally, List<Ability>> allies, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[4]))
        {
            Ability a = playerAbilities.Find(ability => ability.AbilityID == 4);

            if (a.HasNotModifiedEntity is not false)
            {
                player.GetInventory().Add(spellList[6]);
                player.GetInventory().Add(spellList[9]);

                a.HasNotModifiedEntity = false;
            }
        }
        if (allies != null)
        {
            foreach (KeyValuePair<Ally, List<Ability>> ally in allies)
            {
                if (ally.Value.Contains(abilityList[4]))
                {
                    Ability a = ally.Value.Find(ability => ability.AbilityID == 4);

                    if (a.HasNotModifiedEntity is not false)
                    {
                        ally.Key.GetInventory().Add(spellList[6]);
                        ally.Key.GetInventory().Add(spellList[9]);

                        a.HasNotModifiedEntity = false;
                    }
                }
            }
        }
    }
    private static void FocusedTargetFunction(Inventory invenToUse, Entity target, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[6]) || invenToUse.limitedAbilities.Contains(abilityList[6]))
        {
            List<Ability> abilities = invenToUse.Abilities;
            abilities.AddRange(invenToUse.limitedAbilities);
            Ability a = abilities.Find(a => a.AbilityID == 6);

            if (a.priorTarget == null)
            {
                a.priorTarget = target;
                return;
            }

            try
            {
                if (a.priorTarget == null)
                    throw new NullReferenceException();

                // This is a null check for referencing the same target in case they already passed
                if (a.priorTarget == target)
                {
                    const int BreakPoint = 5;
                    int v = DiceRoller.RollDice(new DHundred());

                    if (v <= BreakPoint)
                    {
                        if (triggers.ContainsKey("DoubleDamage"))
                        {
                            triggers["DoubleDamage"].Item1.Add("Focused Target");
                            triggers["DoubleDamage"].Item2.Add(-1);
                        }
                        else
                            triggers.Add("DoubleDamage", (new List<string> { "Focused Target"}, new List<object> { -1 }));    
                    }
                }
            }
            catch (NullReferenceException) when (a.priorTarget == null)
            {
                a.priorTarget = target != null ? target : null;
            }
        }
    }
    private static void AmbidextrousFunction(SortedDictionary<int, (int, Dice)> diceRolls, Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[2]) || attackingInven.limitedAbilities.Contains(abilityList[2]))
        {
            List<Ability> abilities = new List<Ability>(attackingInven.Abilities);
            abilities.AddRange(attackingInven.limitedAbilities);
            Ability a = abilities.Find(a => a.AbilityID == 2);

            int rolledValue = UtilityHandler.RollValue(Dice.DiceR.Four);
            if (triggers.ContainsKey(ToHitAdd))
            {
                List<object> inceptionValues = new List<object>
                {
                    rolledValue,
                    Dice.DiceR.Four
                };

                triggers[ToHitAdd].Item1.Add("Ambidextrous");
                triggers[ToHitAdd].Item2.Add(inceptionValues);
            }
            else
                triggers.Add(ToHitAdd, (new List<string> { "Ambidextrous" }, new List<object> { new List<object> { rolledValue, Dice.DiceR.Four } }));

            if (diceRolls is not null)
            {
                int currentDice = diceRolls.Last().Key;
                diceRolls.Add(++currentDice, (rolledValue, new DFour()));
            }
        }
    }
    private static void PackTacticsFunction(Enemy[] rightEnemies, Inventory invenToUse, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[13]) || invenToUse.limitedAbilities.Contains(abilityList[13]))
        {
            int addedValue = 0;
            foreach (Enemy enemy in rightEnemies)
            {
                if (enemy.GetName().Contains("Hound"))
                    addedValue++;
            }
            if (addedValue > 0)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Pack Tactics");
                    triggers[ToHitAdd].Item2.Add(addedValue);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Pack Tactics"}, new List<object> { addedValue }));
            }
        }
    }
    private static void ScavengerFunction(Inventory invenToUse, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[12]) || invenToUse.limitedAbilities.Contains(abilityList[12]))
        {
            int v = DiceRoller.RollDice(new DFour());
            if (v > 3)
                triggers.Add("Scavenge", (new List<string> { "Scavenger" }, new List<object> { .25f }));
        }
    }
    private static void VenomProductionFunction(SortedDictionary<int, (int, Dice)> damageRolls, Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[14]) || attackingInven.limitedAbilities.Contains(abilityList[14]))
        {
            int v = DiceRoller.RollDice(new DFour());

            if (v > 3)
            {
                int rolledValue = DiceRoller.RollDice(new DFour());

                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Venom Production");
                    triggers[AddDamageValue].Item2.Add(new DFour());
                    triggers[AddDamageType].Item2.Add(SpellSO.Element.Earth);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Venom Production" }, new List<object> { new DFour() }));
                    triggers.Add(AddDamageType, (new List<string>(), new List<object> { SpellSO.Element.Earth }));
                } 

                if (damageRolls is not null)
                {
                    if (damageRolls.Count > 0)
                    {
                        int currentDice = damageRolls.Last().Key;
                        damageRolls.Add(++currentDice, (rolledValue, new DFour()));
                    }
                    else
                        damageRolls.Add(0, (rolledValue, new DFour()));
                }
            }
        }
    }
    private static void SinisterPresenceAttackedFunction(Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[15]) || targetInven.limitedAbilities.Contains(abilityList[15]))
        {
            if (triggers.ContainsKey(ToHitMinus))
            {
                triggers[ToHitMinus].Item1.Add("Sinister Presence");
                triggers[ToHitMinus].Item2.Add(-1);
            }
            else
                triggers.Add(ToHitMinus, (new List<string> { "Sinister Presence" }, new List<object> { -1 }));
        }
    }
    private static void SinisterPresenceAttackingFunction(Inventory invenToUse, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[15]) || invenToUse.limitedAbilities.Contains(abilityList[15]))
        {
            if (triggers.ContainsKey(ToHitAdd))
            {
                triggers[ToHitAdd].Item1.Add("Sinister Presence");
                triggers[ToHitAdd].Item2.Add(1);
            }
            else
                triggers.Add(ToHitAdd, (new List<string> { "Sinister Presence" }, new List<object> { 1 }));
        }
    }
    private static void EyeForTreasureFunction(Entity entity, Inventory targetInven, Inventory invenToUse, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[16]) || invenToUse.limitedAbilities.Contains(abilityList[16]))
        {
            int damageToAdd = 0;

            int counter = 0;
            foreach (KeyValuePair<Item, int> item in targetInven.GetAllItems())
            {
                if (item.Value is 1)
                {
                    if (counter == 3)
                    {
                        ++damageToAdd;
                        counter = 0;
                    }
                    else
                        ++counter;
                }
                else
                {
                    for (int v = 0; v < item.Value; ++v)
                    {
                        if (counter == 3)
                        {
                            ++damageToAdd;
                            counter = 0;
                        }
                        else
                            ++counter;
                    }
                }
            }

            int goldAmount = targetInven.GetGold();
            
            WeaponSO.Type weaponType;
            if (invenToUse.GetPrimaryActiveWeapon() is not null)
                weaponType = invenToUse.GetPrimaryActiveWeapon().WeaponType;
            else if (invenToUse.GetPrimaryActiveWeapon() is null && entity is Enemy enemy)
                weaponType = enemy.GetDamageType();
            else
                weaponType = (entity as Ally).attackType;

            damageToAdd += goldAmount / 50;

            if (triggers.ContainsKey(AddDamageValue))
            {
                List<string> currentNameList = new List<string>(triggers[AddDamageValue].Item1);
                List<object> currentObjectList = new List<object>(triggers[AddDamageValue].Item2);
                List<object> currentTypeList = new List<object>(triggers[AddDamageType].Item2);

                triggers.Remove(AddDamageValue);
                triggers.Remove(AddDamageType);

                currentNameList.Add("Eye For Treasure");
                currentObjectList.Add(damageToAdd);
                currentTypeList.Add(weaponType);

                triggers.Add(AddDamageValue, (currentNameList, currentObjectList));
                triggers.Add(AddDamageType, (new List<string>(), currentTypeList));
            }
            else
            {
                triggers.Add(AddDamageValue, (new List<string> { "Eye for Treasure" }, new List<object> { damageToAdd }));
                triggers.Add(AddDamageType, (new List<string>(), new List<object> { weaponType }));
            }
        }
    }
    private static void RowdyBunchShallowHealFunction(Enemy[] enemyComps, List<Inventory> genInvens)
    {
        foreach (Inventory inven in genInvens)
        {
            if (inven.Abilities.Contains(abilityList[17]) || inven.limitedAbilities.Contains(abilityList[17]))
            {
                int goblinAmount = 0;
                foreach (Enemy enemy in enemyComps)
                {
                    if (enemy.GetName().Equals("Goblin"))
                        ++goblinAmount;
                }

                if (goblinAmount >= 3)
                {
                    foreach (Enemy enemy in enemyComps)
                    {
                        if (enemy.GetName().Equals("Goblin"))
                            enemy.AddSpell(Resources.Load<SpellSO>("Spells/1_Shallow_Heal"));
                    }

                    shallowHealRowdyBunch = true;
                }
            }
        }
    }
    private static void RowdyBunchShallowHealCheck(Dictionary<Entity, List<Ability>> entityAbilities, bool areFainted)
    {
        if (!shallowHealRowdyBunch || areFainted)
            return;

        int goblinAmount = 0;
        foreach (KeyValuePair<Entity, List<Ability>> entity in entityAbilities)
        {
            if (goblinAmount >= 3)
                break;

            if (entity.Value.Contains(abilityList[17]) && entity.Key is Enemy e && e.GetName().Equals("Goblin"))
                ++goblinAmount;
        }

        if (goblinAmount < 3)
        {
            foreach (KeyValuePair<Entity, List<Ability>> entity in entityAbilities)
            {
                if (entity.Key is Enemy e && e.GetName().Equals("Goblin") && e.GetInventory().Spells.Contains(spellList[1]))
                    e.RemoveSpell(Resources.Load<SpellSO>("Spells/1_Shallow_Heal"));
            }

            shallowHealRowdyBunch = false;
        }
    }
    private static void RowdyBunchArmorFunction(Inventory targetInven, Enemy[] rightEnemies, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[17]) || targetInven.limitedAbilities.Contains(abilityList[17]))
        {
            int goblinAmount = 0;

            foreach (Enemy enemy in rightEnemies)
            {
                if (enemy.GetName().Equals("Goblin"))
                    ++goblinAmount;
            }

            if (goblinAmount >= 2)
            {
                if (triggers.ContainsKey(AddArmor))
                {
                    triggers[AddArmor].Item1.Add("Rowdy Bunch");
                    triggers[AddArmor].Item2.Add(1);
                }
                else
                    triggers.Add(AddArmor, (new List<string> { "Rowdy Bunch" }, new List<object> { 1 }));
            }
        }
    }
    private static void RowdyBunchDamageFunction(Entity entity, Enemy[] rightEnemies, SortedDictionary<int, (int, Dice)> damageRolls, Inventory attackingInven, 
                                                Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[17]) || attackingInven.limitedAbilities.Contains(abilityList[17]))
        {
            int goblinAmount = 0;
            foreach (Enemy enemy in rightEnemies)
            {
                if (enemy.GetName().Equals("Goblin"))
                    ++goblinAmount;
            }

            if (goblinAmount is 4)
            {
                WeaponSO.Type weaponType = ((Enemy)attackingInven.AttachedEntity).GetDamageType();

                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Rowdy Bunch");
                    triggers[AddDamageValue].Item2.Add(new DFour());
                    triggers[AddDamageType].Item2.Add(weaponType);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Rowdy Bunch" }, new List<object> { new DFour() }));
                    triggers.Add(AddDamageType, (new List<string>(), new List<object> { weaponType }));
                }
            }
        }
    }
    private static void AdrenalineRushFunction(Dictionary<Entity, List<Ability>> entityAbilities)
    {
        foreach (KeyValuePair<Entity, List<Ability>> pair in entityAbilities)
        {
            if (pair.Value.Contains(abilityList[19]))
            {
                Modifier bleedMod = modifierList["Bleeding"];
                foreach (Entity entity in entityAbilities.Keys)
                {
                    if (entity.GatherModList().Contains(bleedMod))
                    {
                        pair.Key.AddModToList(abilityList[19].Mod);
                        break;
                    }
                }
            }
        }
    }
    private static void BerserkerFunction(Dictionary<Entity, List<Ability>> entityAbilities)
    {
        foreach (KeyValuePair<Entity, List<Ability>> pair in entityAbilities)
        {
            if (pair.Value.Contains(abilityList[20]) && pair.Key.RetrieveHealth() <= pair.Key.RetrieveMaxHealth() * .2f)
                pair.Key.AddModToList(abilityList[20].Mod);
        }
    }
    private static void LifeOfThePartyDebuffFunction(List<Inventory> genInvens)
    {
        foreach (Inventory inven in genInvens)
        {
            // Adds Attention Getter Modifier if ability is found
            if (inven.Abilities.Contains(abilityList[21]) || inven.limitedAbilities.Contains(abilityList[21]))
                inven.AttachedEntity.AddModToList(abilityList[21].Mod);
        }
    }
    private static void LifeOfThePartyEventFunction(List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        foreach (Ability ability in playerAbilities)
        {
            if (ability == abilityList[21])
            {
                if (ability.HasNotModifiedEntity)
                {
                    GameManager.Instance.GetEncounterGenerator().ChangeChanceRates(10, new bool[3] { false, false, true });
                    ability.HasNotModifiedEntity = false;
                }
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> allyAbilityLink in allyAbilities)
        {
            if (allyAbilityLink.Value.Contains(abilityList[21]))
            {
                Ability ability = allyAbilityLink.Value.Find(ability => ability.AbilityID is 21);

                if (ability.HasNotModifiedEntity)
                {
                    GameManager.Instance.GetEncounterGenerator().ChangeChanceRates(10, new bool[3] { false, false, true });
                    ability.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void DevoutFollowerFunction(Player player, Dictionary<Ally, List<Ability>> allies, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[22]))
        {
            Ability ability = playerAbilities.Find(ability => ability.AbilityID is 22);

            if (ability.HasNotModifiedEntity)
            {
                player.GetInventory().Add(spellList[16]);
                ability.HasNotModifiedEntity = false;
            }
        }
        if (allies != null)
        {
            foreach (KeyValuePair<Ally, List<Ability>> ally in allies)
            {
                if (ally.Value.Contains(abilityList[22]))
                {
                    Ability ability = ally.Value.Find(ability => ability.AbilityID is 22);

                    if (ability.HasNotModifiedEntity)
                    {
                        ally.Key.GetInventory().Add(spellList[16]);
                        ability.HasNotModifiedEntity = false;
                    }
                }
            }
        }
    }
    private static void GoldenHorseshoeFunction(Enemy[] enemyComps, List<Inventory> genInvens)
    {
        foreach (Inventory entityInven in genInvens)
        {
            if (entityInven.Abilities.Contains(abilityList[23]) || entityInven.limitedAbilities.Contains(abilityList[23]))
            {
                for (int i = 0; i < enemyComps.Length; i++)
                {
                    enemyComps[i].AlterGoldRange(.3f);
                    enemyComps[i].AlterLootRanges(.15f);
                }
            }
        }
    }
    private static void MagicalApprenticeFunction(Player player, Dictionary<Ally, List<Ability>> allies, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[25]))
        {
            Ability ability = playerAbilities.Find(ability => ability.AbilityID is 25);

            if (ability.HasNotModifiedEntity)
            {
                player.GetInventory().Add(spellList[17]);
                player.AlterManaRegenerationRate(.25f);
                ability.HasNotModifiedEntity = false;
            }
        }
        if (allies != null)
        {
            foreach (KeyValuePair<Ally, List<Ability>> ally in allies)
            {
                if (ally.Value.Contains(abilityList[25]))
                {
                    Ability ability = ally.Value.Find(ability => ability.AbilityID is 25);

                    if (ability.HasNotModifiedEntity)
                    {
                        ally.Key.GetInventory().Add(spellList[17]);
                        ally.Key.AlterManaRegenerationRate(.25f);
                        ability.HasNotModifiedEntity = false;
                    }
                }
            }
        }
    }
    private static void QuickLearnerExpFunction(Enemy[] enemyComps, List<Inventory> genInvens)
    {
        foreach (Inventory entityInventory in genInvens)
        {
            if (entityInventory.Abilities.Contains(abilityList[26]) || entityInventory.limitedAbilities.Contains(abilityList[26]))
            {
                for (int i = 0; i < enemyComps.Length; i++)
                    enemyComps[i].AlterExperienceValue(.25f);
            }
        }
    }
    private static void QuickLearnerSpellDiscountFunction(Player player, Dictionary<Ally, List<Ability>> allies, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[26]))
        {
            Ability ability = playerAbilities.Find(ability => ability.AbilityID is 26);
            List<Spell> spells = player.GetInventory().Spells;
            List<Spell> limitedSpells = player.GetInventory().limitedSpells;

            if (ability.ReferenceObject is null)
            {
                for (int i = 0; i < spells.Count; i++)
                    spells[i].SpellCost -= 1;
                for (int i = 0; i < limitedSpells.Count; ++i)
                    limitedSpells[i].SpellCost -= 1;
                player.GetInventory().Spells = spells;
                player.GetInventory().limitedSpells = limitedSpells;
                ability.ReferenceObject = spells;
                ((List<Spell>)ability.ReferenceObject).AddRange(limitedSpells);
                return;
            }

            bool spellRangeCheck = false;

            foreach (Spell check in spells)
            {
                if (!((List<Spell>)ability.ReferenceObject).Contains(check))
                {
                    spellRangeCheck = true;
                    break;
                }
            }
            if (!spellRangeCheck)
            {
                foreach (Spell check in limitedSpells)
                {
                    if (!((List<Spell>)ability.ReferenceObject).Contains(check)) 
                    {
                        spellRangeCheck = true;
                        break;
                    }
                }
            }

            if (spellRangeCheck)
            {
                foreach (Spell spell in spells)
                {
                    if (!((List<Spell>)ability.ReferenceObject).Contains(spell))
                        spell.SpellCost -= 1;
                }
                foreach (Spell spell in limitedSpells)
                {
                    if (!((List<Spell>)ability.ReferenceObject).Contains(spell))
                        spell.SpellCost -= 1;
                }

                player.GetInventory().Spells = spells;
                player.GetInventory().limitedSpells = limitedSpells;
                ability.ReferenceObject = spells;
                ((List<Spell>)ability.ReferenceObject).AddRange(limitedSpells);
            }
        }
        if (allies != null)
        {
            foreach (KeyValuePair<Ally, List<Ability>> ally in allies)
            {
                if (ally.Value.Contains(abilityList[26]))
                {
                    Ability ability = ally.Value.Find(ability => ability.AbilityID is 26);
                    List<Spell> spells = ally.Key.GetInventory().Spells;
                    List<Spell> limitedSpells = ally.Key.GetInventory().limitedSpells;

                    if (ability.ReferenceObject is null)
                    {
                        for (int i = 0; i < spells.Count; i++)
                            spells[i].SpellCost -= 1;
                        for (int i = 0; i < limitedSpells.Count; i++)
                            limitedSpells[i].SpellCost -= 1;

                        ally.Key.GetInventory().Spells = spells;
                        ally.Key.GetInventory().limitedSpells = limitedSpells;
                        ability.ReferenceObject = spells;
                        ((List<Spell>)ability.ReferenceObject).AddRange(limitedSpells);
                        continue;
                    }

                    bool spellRangeCheck = false;

                    foreach (Spell check in spells)
                    {
                        if (!((List<Spell>)ability.ReferenceObject).Contains(check))
                        {
                            spellRangeCheck = true;
                            break;
                        }
                    }
                    if (!spellRangeCheck)
                    {
                        foreach (Spell check in limitedSpells)
                        {
                            if (!((List<Spell>)ability.ReferenceObject).Contains(check))
                            {
                                spellRangeCheck = true;
                                break;
                            }
                        }
                    }

                    if (spellRangeCheck)
                    {
                        foreach (Spell spell in spells)
                        {
                            if (!((List<Spell>)ability.ReferenceObject).Contains(spell))
                                spell.SpellCost -= 1;
                        }
                        foreach (Spell spell in limitedSpells)
                        {
                            if (!((List<Spell>)ability.ReferenceObject).Contains(spell))
                                spell.SpellCost -= 1;
                        }

                        ally.Key.GetInventory().Spells = spells;
                        ally.Key.GetInventory().limitedSpells = limitedSpells;
                        ability.ReferenceObject = spells;
                        ((List<Spell>)ability.ReferenceObject).AddRange(limitedSpells);
                    }
                }
            }
        }
    }
    private static void RiposteFunction(Inventory targetInven, Entity attacker, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if ((targetInven.Abilities.Contains(abilityList[27]) || targetInven.limitedAbilities.Contains(abilityList[27])))
        {
            // Collection of conditionals determine if the primary weapon for the attacker is not a magic or ranged base attack
            // Catches for player and ally signal if no primary is available/is null
            if (attacker is Player player)
            {
                try
                {
                    WeaponSO.Type playerWeaponType = player.GetInventory().GetPrimaryActiveWeapon().WeaponType;
                    if (playerWeaponType is WeaponSO.Type.Ranged || playerWeaponType is WeaponSO.Type.Magic)
                        return;
                }
                catch { return; }
            }
            else if (attacker is Ally ally)
            {
                try
                {
                    WeaponSO.Type allyAttackType = ally.attackType is WeaponSO.Type.None ? ally.GetInventory().GetPrimaryActiveWeapon().WeaponType : ally.attackType;
                    if (allyAttackType is WeaponSO.Type.Ranged || allyAttackType is WeaponSO.Type.Magic)
                        return;
                }
                catch { return; }
            }
            else if (attacker is Enemy enemy)
            {
                WeaponSO.Type damageType = enemy.GetDamageType();
                if (damageType is WeaponSO.Type.Ranged || damageType is WeaponSO.Type.Magic)
                    return;
            }

            if (triggers.ContainsKey(DamageBack))
            {
                triggers[DamageBack].Item1.Add("Riposte");
                triggers[DamageBack].Item2.Add(.25f);
            }
            else
                triggers.Add(DamageBack, (new List<string> { "Riposte" }, new List<object> { .25f }));
        }
    }
    private static void UnflinchingFunction(Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[28]) || targetInven.limitedAbilities.Contains(abilityList[28]))
        {
            if (triggers.ContainsKey(HalfCrits))
            {
                triggers[HalfCrits].Item1.Add("Unflinching");
                triggers[HalfCrits].Item2.Add(.5f);
            }       
            else
                triggers.Add(HalfCrits, (new List<string> { "Unflinching" }, new List<object> { .5f }));
        }
    }
    private static void UnstableMagicalCoreFunction(Inventory invenToUse, Dictionary<string, object> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[29]) || invenToUse.limitedAbilities.Contains(abilityList[29]))
        {
            int rollValue = DiceRoller.RollDice(new DHundred());

            if (rollValue <= 3)
                triggers.Add("CoreSpell", spellList[UnityEngine.Random.Range(0, spellList.Count)]);
        }
    }
    private static void DreamMasterNullSleepFunction(Dictionary<Entity, List<Ability>> entityAbilities)
    {
        foreach (KeyValuePair<Entity, List<Ability>> pair in entityAbilities)
        {
            if (pair.Value.Contains(abilityList[30]))
            {
                // Checks if sleeping is in the entities mod list before removing it since Dream 
                // Master nullifies the modifier
                if (pair.Key.GatherModList().Contains(modifierList["Sleeping"]))
                    pair.Key.GatherModList().RemoveModifier(modifierList["Sleeping"]);
            }
        }
    }
    private static void NoxiousAuraFunction(Entity attacker, SortedDictionary<int, (int, Dice)> damageRolls, Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[31]) || targetInven.limitedAbilities.Contains(abilityList[31]))
        {
            if (attacker.GatherModList().SmartModCheck("Sick"))
            {
                Dice[] damageDice = new Dice[2] { new DTwelve(), new DTwelve() };

                foreach (Dice dice in damageDice)
                {
                    int rolledValue = DiceRoller.RollDice(dice);

                    if (damageRolls is not null)
                    {
                        if (damageRolls.Count > 0)
                        {
                            int currentDice = damageRolls.Last().Key;
                            damageRolls.Add(++currentDice, (rolledValue, dice));
                        }
                        else
                            damageRolls.Add(0, (rolledValue, dice));
                    }
                }

                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Noxious Aura");
                    triggers[AddDamageValue].Item2.Add(damageDice);
                    triggers[AddDamageType].Item2.Add(SpellSO.Element.Poison);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Noxious Aura" }, new List<object> { damageDice }));
                    triggers.Add(AddDamageType, (new List<string>(), new List<object> { SpellSO.Element.Poison }));
                }
            }
            else
                attacker.AddModToList(modifierList["Sick"]);
        }
    }
    private static void AirElementalAmpedFunction(int damage, SpellSO.Element attackerElement, Entity attacker, Inventory attackerInven)
    {
        if (attackerElement is SpellSO.Element.Wind && (attackerInven.Abilities.Contains(abilityList[35]) || attackerInven.limitedAbilities.Contains(abilityList[35])) && damage is not 0)
        {
            int rollValue = UtilityHandler.RollValue(Dice.DiceR.Hundred);
            const int AmpedChance = 10;

            if (rollValue <= AmpedChance)
            {
                attacker.AddModToList(modifierList["Amped"]);
                attacker.AfflictedStatus();
            }
        }
    }
    private static void FireElementalBurnFunction(int damage, SpellSO.Element attackerElement, Entity target, Inventory attackerInven)
    {
        if (attackerElement is SpellSO.Element.Fire && (attackerInven.Abilities.Contains(abilityList[34]) || attackerInven.limitedAbilities.Contains(abilityList[34])) && damage is not 0)
        {
            int rollValue = UtilityHandler.RollValue(Dice.DiceR.Hundred);
            const int BurnChance = 30;

            if (rollValue <= BurnChance)
            {
                target.AddModToList(modifierList["Burned"]);
                target.AfflictedStatus();
            }
        }
    }
    private static int ElementalAbsorptionFunction(int damage, SpellSO.Element attackerElement, Entity target, Inventory targetInven, Spell spellUsed)
    {
        // 32 ---> Earth Elemental Absorption
        if ((targetInven.Abilities.Contains(abilityList[32]) || targetInven.limitedAbilities.Contains(abilityList[32])) && attackerElement is SpellSO.Element.Earth)
        {
            if (spellUsed != null)
            {
                if (spellUsed.SpellName is "Earth Shatter")
                    return damage * 2;

                target.IncreaseHealth(damage);
                target.StatusChanged();
                damage = 0;
            }
            else  // So this indicates a Earth WEAPON was used
            {
                target.IncreaseHealth(damage / 2);
                target.StatusChanged();
                damage /= 2;
            }
        }
        // 33 ---> Ice Elemental Absorption
        else if ((targetInven.Abilities.Contains(abilityList[33]) || targetInven.limitedAbilities.Contains(abilityList[33])) && attackerElement is SpellSO.Element.Ice)
        {
            if (spellUsed != null)
            {
                target.IncreaseHealth(damage);
                target.StatusChanged();
                damage = 0;
            }
            else  // So this indicates a Earth WEAPON was used
            {
                target.IncreaseHealth(damage / 2);
                target.StatusChanged();
                damage /= 2;
            }
        }
        // 34 ---> Fire Elemental Absorption
        else if ((targetInven.Abilities.Contains(abilityList[34]) || targetInven.limitedAbilities.Contains(abilityList[34])) && attackerElement is SpellSO.Element.Fire)
        {
            if (spellUsed != null)
            {
                target.IncreaseHealth(damage);
                target.StatusChanged();
                damage = 0;
            }
            else  // So this indicates a Earth WEAPON was used
            {
                target.IncreaseHealth(damage / 2);
                target.StatusChanged();
                damage /= 2;
            }
        }
        // 35 ---> Air Elemental Absorption
        else if ((targetInven.Abilities.Contains(abilityList[35]) || targetInven.limitedAbilities.Contains(abilityList[35])) && attackerElement is SpellSO.Element.Wind)
        {
            if (spellUsed != null)
            {
                target.IncreaseHealth(damage);
                target.StatusChanged();
                damage = 0;
            }
            else  // So this indicates a Earth WEAPON was used
            {
                target.IncreaseHealth(damage / 2);
                target.StatusChanged();
                damage /= 2;
            }
        }

        return damage;
    }
    private static void IceElementalManaFunction(SpellSO.Element attackerElement, Entity attacker, Inventory attackerInven)
    {
        if (attackerElement is SpellSO.Element.Ice && (attackerInven.Abilities.Contains(abilityList[33]) || attackerInven.limitedAbilities.Contains(abilityList[33])))
        {
            attacker.IncreaseMana(UtilityHandler.RollValue(Dice.DiceR.Four));
            attacker.StatusChanged();
        }
    }
    private static int EarthElementalDamageFunction(int damage, SpellSO.Element attackerElement, SortedDictionary<int, (int, Dice)> damageRolls, Inventory attackerInven, bool rollsNull)
    {
        if (attackerElement is SpellSO.Element.Earth && (attackerInven.Abilities.Contains(abilityList[32]) || attackerInven.limitedAbilities.Contains(abilityList[32])))
        {
            int rolledValue = UtilityHandler.RollValue(Dice.DiceR.Six);
            damage += rolledValue;

            // If minion earth golem
            if (!rollsNull)
            {
                if (damageRolls.Count > 0)
                {
                    int currentDice = damageRolls.Last().Key;
                    damageRolls.Add(++currentDice, (rolledValue, new DSix()));
                }
                else
                    damageRolls.Add(0, (rolledValue, new DSix()));
            }
        }

        return damage;
    }
    private static void KleptomaniacFunction(Inventory attackingInven, Inventory targetInven, WeaponSO.Type weaponType, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[44]) || attackingInven.limitedAbilities.Contains(abilityList[44]))
        {
            int damageToAdd = targetInven.GetAllItems().Keys.Count / 3;

            if (triggers.ContainsKey(AddDamageValue))
            {
                triggers[AddDamageValue].Item1.Add("Kleptomaniac");
                triggers[AddDamageValue].Item2.Add(damageToAdd);
                triggers[AddDamageType].Item2.Add(weaponType);
            }
            else
            {
                triggers.Add(AddDamageValue, (new List<string> { "Kleptomaniac" }, new List<object> { damageToAdd }));
                triggers.Add(AddDamageType, (new List<string>(), new List<object> { weaponType }));
            }
        }
    }
    private static int NutrientBankFunction(int spellValue, Inventory userInven, Inventory targetInven)
    {
        // If user has ability then heal extra 2 points and add buff modifier
        if (userInven.Abilities.Contains(abilityList[36]) || userInven.limitedAbilities.Contains(abilityList[36]))
        {
            spellValue += 2;

            targetInven.AttachedEntity.AddModToList(modifierList["Nutritional Supplements"]);
        }

        // If target has ability then add 2 extra points
        if (targetInven.Abilities.Contains(abilityList[36]) || targetInven.limitedAbilities.Contains(abilityList[36]))
            spellValue += 2;

        return spellValue;
    }
    private static void SaturatedConduitsIncreaseManaFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[40]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 40).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.IncreaseMaxMana(5);
                player.IncreaseMana(5);
                player.StatusChanged();

                abRef.HasNotModifiedEntity = false;
            }
        }

        foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
        {
            if (ally.Value.Contains(abilityList[40]))
            {
                Ability abRef = ally.Value.Where(ability => ability.AbilityID is 40).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    ally.Key.IncreaseMaxMana(5);
                    ally.Key.IncreaseMana(5);
                    ally.Key.StatusChanged();

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void ReconstitutionFunction()
    {
        // TODO ---> Implement
    }
    private static int MedicallyCompetentFunction(int spellValue, bool isConsume, Inventory targetInven)
    {
        if (targetInven.Abilities.Contains(abilityList[39]) || targetInven.limitedAbilities.Contains(abilityList[39]))
        {
            spellValue += 1;

            if (isConsume)
            {
                int noConsumeRoll = UnityEngine.Random.Range(0, 101);

                if (noConsumeRoll <= 25)
                    ConsumableManagement.IndicateNoConsume();
            }
        }

        return spellValue;
    }
    private static int SaturatedConduitsRefillFunction(int spellValue, Inventory targetInven)
    {
        if (targetInven.Abilities.Contains(abilityList[40]) || targetInven.limitedAbilities.Contains(abilityList[40]))
            spellValue += 1;

        return spellValue;
    }
    private static void DenseSetaeFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[38]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 38).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GatherStats().SetModifierToStat(EntityStats.Stat.Armor, 1);
                player.GatherStats().SetModifierToStat(EntityStats.Stat.Dexterity, 1);

                abRef.HasNotModifiedEntity = false;
            }
        }

        foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
        {
            if (ally.Value.Contains(abilityList[38]))
            {
                Ability abRef = ally.Value.Where(ability => ability.AbilityID is 38).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    ally.Key.GatherStats().SetModifierToStat(EntityStats.Stat.Armor, 1);
                    ally.Key.GatherStats().SetModifierToStat(EntityStats.Stat.Dexterity, 1);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void AdrenalRegenerationTriggerFunction(bool hasCrit, Inventory targetInven)
    {
        if (hasCrit && (targetInven.Abilities.Contains(abilityList[37]) || targetInven.limitedAbilities.Contains(abilityList[37])))
        {
            List<Ability> colAbilities = new List<Ability>(targetInven.Abilities);
            colAbilities.AddRange(targetInven.limitedAbilities);

            Ability abRef = colAbilities.Where(ability => ability.AbilityID is 37).FirstOrDefault();
            abRef.active = true;
        }
    }
    private static void AdrenalRegenerationFunction(Inventory invenToUse, Dictionary<string, object> triggers)
    {
        if (invenToUse.Abilities.Contains(abilityList[37]) || invenToUse.limitedAbilities.Contains(abilityList[37]))
        {
            List<Ability> abCollective = new List<Ability>(invenToUse.Abilities);
            abCollective.AddRange(invenToUse.limitedAbilities);

            Ability abRef = abCollective.Where(ability => ability.AbilityID is 37).FirstOrDefault();

            if (abRef.active) // Was Critted
            {
                triggers.Add("Adrenal Surge", 10);
                abRef.active = false;
            }
            else              // Otherwise base ability regeneration
                triggers.Add("Adrenal Surge", 5);
        }
    }
    private static void WillOfTheDamnedFunction(Dictionary<Entity, List<Ability>> entityAbilities)
    {
        foreach (KeyValuePair<Entity, List<Ability>> entity in entityAbilities)
        {
            if (entity.Value.Contains(abilityList[45]))
            {
                EntityModList modList = entity.Key.GatherModList();

                if (modList.SmartModCheck("Sleeping"))
                {
                    modList.RemoveModifier(modifierList["Sleeping"]);
                    entity.Key.AddModToList(modifierList["Bloodlust"]);
                }
                if (modList.SmartModCheck("Feared"))
                {
                    modList.RemoveModifier(modifierList["Feared"]);
                    entity.Key.AddModToList(modifierList["Bloodlust"]);
                }
                if (modList.SmartModCheck("Silenced"))
                {
                    modList.RemoveModifier(modifierList["Silenced"]);
                    entity.Key.AddModToList(modifierList["Bloodlust"]);
                }
            }
        }
    }
    private static void InterferingAbberationFunction(Entity target, Player player, Ally[] leftComps, Enemy[] rightEnemies, Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (target is Enemy)
        {
            bool hasAbility = targetInven.Abilities.Contains(abilityList[46]) || targetInven.limitedAbilities.Contains(abilityList[46]);
            bool otherHasAbility = rightEnemies.Any(enemy =>
            (enemy.GetInventory().Abilities.Contains(abilityList[46]) || enemy.GetInventory().limitedAbilities.Contains(abilityList[46]))
            &&
            target.GetUniqueID() != enemy.GetUniqueID()
            );

            if (!hasAbility && otherHasAbility)
            {
                if (triggers.ContainsKey(ToHitMinus))
                {
                    triggers[ToHitMinus].Item1.Add("Interfering Abberation");
                    triggers[ToHitMinus].Item2.Add(-1);
                }
                else
                    triggers.Add(ToHitMinus, (new List<string> { "Interfering Abberation" }, new List<object> { -1 }));
            }
        }
        else if (target is Player || target is Ally)
        {
            bool hasAbility = targetInven.Abilities.Contains(abilityList[46]) || targetInven.limitedAbilities.Contains(abilityList[46]);
            bool otherHasAbility = leftComps.Any(ally => (ally.GetInventory().Abilities.Contains(abilityList[46]) || ally.GetInventory().limitedAbilities.Contains(abilityList[46])) && target.GetUniqueID() != ally.GetUniqueID())
                || ((player.GetInventory().Abilities.Contains(abilityList[46]) || player.GetInventory().limitedAbilities.Contains(abilityList[46])) && player.GetUniqueID() != target.GetUniqueID());

            if (!hasAbility && otherHasAbility)
            {
                if (triggers.ContainsKey(ToHitMinus))
                {
                    triggers[ToHitMinus].Item1.Add("Interfering Abberation");
                    triggers[ToHitMinus].Item2.Add(-1);
                }
                else
                    triggers.Add(ToHitMinus, (new List<string> { "Interfering Abberation" }, new List<object> { -1 }));
            }
        }
    }
    private static void SharpWeaponAdeptFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[55]))
        {
            bool hasToHitAdded = false;
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Sharp)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Sharp Adept");
                    triggers[ToHitAdd].Item2.Add(1);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Sharp Adept" }, new List<object> { 1 }));

                hasToHitAdded = true;
            }

            try
            {
                if (attackingInven.GetSecondaryActiveWeapon().WeaponType is WeaponSO.Type.Sharp)
                {
                    if (!hasToHitAdded)
                    {
                        if (triggers.ContainsKey(ToHitAdd))
                        {
                            triggers[ToHitAdd].Item1.Add("Sharp Adept");
                            triggers[ToHitAdd].Item2.Add(1);
                        }
                        else
                            triggers.Add(ToHitAdd, (new List<string> { "Sharp Adept" }, new List<object> { 1 }));
                    }

                    triggers.Add(FullOffHandSignal, (null, null));
                }
            }
            catch { }
        }
    }
    private static void RangedWeaponAdeptFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[53]))
        {
            bool hasToHitAdded = false;
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Ranged)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Ranged Adept");
                    triggers[ToHitAdd].Item2.Add(1);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Ranged Adept" }, new List<object> { 1 }));

                hasToHitAdded = true;
            }

            try
            {
                if (attackingInven.GetSecondaryActiveWeapon().WeaponType is WeaponSO.Type.Ranged)
                {
                    if (!hasToHitAdded)
                    {
                        if (triggers.ContainsKey(ToHitAdd))
                        {
                            triggers[ToHitAdd].Item1.Add("Ranged Adept");
                            triggers[ToHitAdd].Item2.Add(1);
                        }
                        else
                            triggers.Add(ToHitAdd, (new List<string> { "Ranged Adept" }, new List<object> { 1 }));
                    }

                    triggers.Add(FullOffHandSignal, (null, null));
                }
            }
            catch { }
        }
    }
    private static void MagicWeaponAdeptFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[51]))
        {
            bool hasToHitAdded = false;
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Magic)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Magic Adept");
                    triggers[ToHitAdd].Item2.Add(1);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Magic Adept" }, new List<object> { 1 }));

                hasToHitAdded = true;
            }

            try
            {
                if (attackingInven.GetSecondaryActiveWeapon().WeaponType is WeaponSO.Type.Magic)
                {
                    if (!hasToHitAdded)
                    {
                        if (triggers.ContainsKey(ToHitAdd))
                        {
                            triggers[ToHitAdd].Item1.Add("Magic Adept");
                            triggers[ToHitAdd].Item2.Add(1);
                        }
                        else
                            triggers.Add(ToHitAdd, (new List<string> { "Magic Adept" }, new List<object> { 1 }));
                    }

                    triggers.Add(FullOffHandSignal, (null, null));
                }
            }
            catch { }
        }
    }
    private static void ExtendedWeaponAdeptFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[49]))
        {
            bool hasToHitAdded = false;
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Extended)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Extended Adept");
                    triggers[ToHitAdd].Item2.Add(1);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Extended Adept" }, new List<object> { 1 }));

                hasToHitAdded = true;
            }

            try
            {
                if (attackingInven.GetSecondaryActiveWeapon().WeaponType is WeaponSO.Type.Extended)
                {
                    if (!hasToHitAdded)
                    {
                        if (triggers.ContainsKey(ToHitAdd))
                        {
                            triggers[ToHitAdd].Item1.Add("Extended Adept");
                            triggers[ToHitAdd].Item2.Add(1);
                        }
                        else
                            triggers.Add(ToHitAdd, (new List<string> { "Extended Adept" }, new List<object> { 1 }));
                    }

                    triggers.Add(FullOffHandSignal, (null, null));
                }
            }
            catch { }
        }
    }
    private static void BluntWeaponAdeptFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[47]))
        {
            bool hasToHitAdded = false;
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Blunt)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Blunt Adept");
                    triggers[ToHitAdd].Item2.Add(1);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Blunt Adept" }, new List<object> { 1 }));

                hasToHitAdded = true;
            }

            try
            {
                if (attackingInven.GetSecondaryActiveWeapon().WeaponType is WeaponSO.Type.Blunt)
                {
                    if (!hasToHitAdded)
                    {
                        if (triggers.ContainsKey(ToHitAdd))
                        {
                            triggers[ToHitAdd].Item1.Add("Blunt Adept");
                            triggers[ToHitAdd].Item2.Add(1);
                        }
                        else
                            triggers.Add(ToHitAdd, (new List<string> { "Blunt Adept" }, new List<object> { 1 }));
                    }

                    triggers.Add(FullOffHandSignal, (null, null));
                }
            }
            catch { }
        }
    }
    private static void SharpWeaponMasterTriggerFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[56]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 56).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GetInventory().SignalOffHandedChange(WeaponSO.Type.Sharp);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> pair in allyAbilities)
        {
            if (pair.Value.Contains(abilityList[56]))
            {
                Ability abRef = pair.Value.Where(ability => ability.AbilityID is 56).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    pair.Key.GetInventory().SignalOffHandedChange(WeaponSO.Type.Sharp);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void RangedWeaponMasterTriggerFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[54]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 54).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GetInventory().SignalOffHandedChange(WeaponSO.Type.Ranged);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> pair in allyAbilities)
        {
            if (pair.Value.Contains(abilityList[54]))
            {
                Ability abRef = pair.Value.Where(ability => ability.AbilityID is 54).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    pair.Key.GetInventory().SignalOffHandedChange(WeaponSO.Type.Ranged);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void MagicWeaponMasterTriggerFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[52]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 52).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GetInventory().SignalOffHandedChange(WeaponSO.Type.Magic);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> pair in allyAbilities)
        {
            if (pair.Value.Contains(abilityList[52]))
            {
                Ability abRef = pair.Value.Where(ability => ability.AbilityID is 52).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    pair.Key.GetInventory().SignalOffHandedChange(WeaponSO.Type.Magic);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void ExtendedWeaponMasterTriggerFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[50]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 50).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GetInventory().SignalOffHandedChange(WeaponSO.Type.Extended);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> pair in allyAbilities)
        {
            if (pair.Value.Contains(abilityList[50]))
            {
                Ability abRef = pair.Value.Where(ability => ability.AbilityID is 50).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    pair.Key.GetInventory().SignalOffHandedChange(WeaponSO.Type.Extended);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void BluntWeaponMasterTriggerFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[48]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 48).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GetInventory().SignalOffHandedChange(WeaponSO.Type.Blunt);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> pair in allyAbilities)
        {
            if (pair.Value.Contains(abilityList[48]))
            {
                Ability abRef = pair.Value.Where(ability => ability.AbilityID is 48).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    pair.Key.GetInventory().SignalOffHandedChange(WeaponSO.Type.Blunt);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void SharpWeaponMasterDamageFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[56]))
        {
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Sharp)
            {
                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Sharp Master");
                    triggers[AddDamageValue].Item2.Add(.3f);
                    triggers[AddDamageType].Item2.Add(WeaponSO.Type.Sharp);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Sharp Master" }, new List<object> { .3f }));
                    triggers.Add(AddDamageType, (new List<string> { }, new List<object> { WeaponSO.Type.Sharp }));
                }
            }
        }
    }
    private static void RangedWeaponMasterDamageFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[54]))
        {
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Ranged)
            {
                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Ranged Master");
                    triggers[AddDamageValue].Item2.Add(.3f);
                    triggers[AddDamageType].Item2.Add(WeaponSO.Type.Ranged);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Ranged Master" }, new List<object> { .3f }));
                    triggers.Add(AddDamageType, (new List<string> { }, new List<object> { WeaponSO.Type.Ranged }));
                }
            }
        }
    }
    private static void MagicWeaponMasterDamageFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[52]))
        {
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Magic)
            {
                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Magic Master");
                    triggers[AddDamageValue].Item2.Add(.3f);
                    triggers[AddDamageType].Item2.Add(WeaponSO.Type.Magic);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Magic Master" }, new List<object> { .3f }));
                    triggers.Add(AddDamageType, (new List<string> { }, new List<object> { WeaponSO.Type.Magic }));
                }
            }
        }
    }
    private static void ExtendedWeaponMasterDamageFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[50]))
        {
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Extended)
            {
                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Extended Master");
                    triggers[AddDamageValue].Item2.Add(.3f);
                    triggers[AddDamageType].Item2.Add(WeaponSO.Type.Extended);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Extended Master" }, new List<object> { .3f }));
                    triggers.Add(AddDamageType, (new List<string> { }, new List<object> { WeaponSO.Type.Extended }));
                }
            }
        }
    }
    private static void BluntWeaponMasterDamageFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[48]))
        {
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Blunt)
            {
                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Blunt Master");
                    triggers[AddDamageValue].Item2.Add(.3f);
                    triggers[AddDamageType].Item2.Add(WeaponSO.Type.Blunt);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Blunt Master" }, new List<object> { .3f }));
                    triggers.Add(AddDamageType, (new List<string> { }, new List<object> { WeaponSO.Type.Blunt }));
                }
            }
        }
    }
    private static bool SurpriseFunction(bool hasCrit, Inventory attackingInven)
    {
        if (attackingInven.Abilities.Contains(abilityList[57]))
        {
            Ability abRef = attackingInven.Abilities.Where(ability => ability.AbilityID is 57).FirstOrDefault();

            if (abRef.active)
            {
                hasCrit = true;
                attackingInven.AttachedEntity.ShowEntity();
                abRef.active = false;
            }
        }

        return hasCrit;
    }
    private static bool SapProductionFunction(Entity target, Ally[] allyComps, bool output)
    {
        if (target is Ally || target is Player)
        {
            if (target.GetInventory().Abilities.Contains(abilityList[58]) && !target.HasDied)
                output = true;
            foreach (Ally ally in allyComps)
            {
                if (ally.GetInventory().Abilities.Contains(abilityList[58]) && !target.HasDied)
                    output = true;
            }
        }

        return output;
    }
    private static void PoisonousBarbsFunction(Entity attacker, Entity target, Inventory attackingInven, Inventory targetInven, bool toHitSucceededEnemySide)
    {
        Ability abRef = abilityList[59];

        if (targetInven.Abilities.Contains(abilityList[59]) && toHitSucceededEnemySide)
        {
            int savingThrow = UtilityHandler.RollSavingThrow(EntityStats.Stat.Constitution, attacker, null);
            int baseLine = abRef.SavingThrow.y + target.GatherStats().GetStat(EntityStats.Stat.Constitution);

            if (savingThrow < baseLine)
                attacker.AddModToList(abilityList[59].Mod);
        }
        else if (attackingInven.Abilities.Contains(abilityList[59]))
        {
            int savingThrow = UtilityHandler.RollSavingThrow(EntityStats.Stat.Constitution, target);
            int baseLine = abRef.SavingThrow.y + attacker.GatherStats().GetStat(EntityStats.Stat.Constitution);

            if (savingThrow < baseLine)
                target.AddModToList(abilityList[59].Mod);
        }
    }
    private static void IngrainedRootsToHitFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[60]))
        {
            if (triggers.ContainsKey(ToHitAdd))
            {
                triggers[ToHitAdd].Item1.Add("Ingrained Roots");
                triggers[ToHitAdd].Item2.Add(1);
            }
            else
                triggers.Add(ToHitAdd, (new List<string> { "Ingrained Roots" }, new List<object> { 1 }));
        }
    }
    private static void TrapperProcFunction(Inventory targetInven, bool toHitSucceededEnemySide, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[63]) || targetInven.limitedAbilities.Contains(abilityList[63]))
        {
            if (toHitSucceededEnemySide)
            {
                List<Ability> abilityList = new List<Ability>(targetInven.Abilities);
                abilityList.AddRange(targetInven.limitedAbilities);

                Ability abRef = abilityList.Where(ability => ability.AbilityID is 63).FirstOrDefault();
                if (abRef.active)
                {
                    int rolledValue = DiceRoller.RollDice(new DSix());

                    if (triggers.ContainsKey(DamageBack))
                    {
                        triggers[DamageBack].Item1.Add("Trapper");
                        triggers[DamageBack].Item2.Add(rolledValue);
                    }
                    else
                        triggers.Add(DamageBack, (new List<string> { "Trapper" }, new List<object> { rolledValue }));

                    abRef.active = false;
                }
            }
        }
    }
    private static void TrapperResetFunction(List<Inventory> invens)
    {
        foreach (Inventory allyInven in invens)
        {
            if (allyInven.Abilities.Contains(abilityList[63]) || allyInven.limitedAbilities.Contains(abilityList[63]))
            {
                List<Ability> abilityList = new List<Ability>(allyInven.Abilities);
                abilityList.AddRange(allyInven.limitedAbilities);

                Ability abRef = abilityList.Where(ability => ability.AbilityID is 63).FirstOrDefault();
                abRef.active = true;
            }
        }
    }
    private static void NaturalHerbalistFunction(List<Inventory> invens)
    {
        foreach (Inventory inven in invens)
        {
            if (inven.Abilities.Contains(abilityList[65]) || inven.limitedAbilities.Contains(abilityList[65]))
            {
                int rolledValue = DiceRoller.RollDice(new DHundred());

                if (rolledValue <= 5)
                {
                    List<ItemSO> potentialItems = JsonReader.AspectCollector<ItemSO>.GatherAspects("General.json", new int[] { 18, 19, 20, 21, 22, 23, 24 });

                    Item rolledItem = Globals.TurnItemFromObject(potentialItems[UnityEngine.Random.Range(0, potentialItems.Count)]);
                    inven.Add(rolledItem, 1);
                }
            }
        }
    }
    private static void TriggerFingerFunction(Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[69]) || targetInven.limitedAbilities.Contains(abilityList[69]))
        {
            int diceValue = DiceRoller.RollDice(new DTwenty());

            if (diceValue % 2 is 0)
            {
                Dice.DiceR damageDice = targetInven.GetPrimaryActiveWeapon().WeaponDamage[0];
                int rolledDamage = UtilityHandler.RollValue(damageDice);

                if (triggers.ContainsKey(DamageBack))
                {
                    triggers[DamageBack].Item1.Add("Trigger Finger");
                    triggers[DamageBack].Item2.Add(rolledDamage);
                }
                else
                    triggers.Add(DamageBack, (new List<string> { "Trigger Finger" }, new List<object> { rolledDamage }));
            }
        }
    }
    private static void FirearmWeaponAdeptFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[76]))
        {
            bool hasToHitAdded = false;
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Firearm)
            {
                if (triggers.ContainsKey(ToHitAdd))
                {
                    triggers[ToHitAdd].Item1.Add("Firearm Adept");
                    triggers[ToHitAdd].Item2.Add(1);
                }
                else
                    triggers.Add(ToHitAdd, (new List<string> { "Firearm Adept" }, new List<object> { 1 }));

                hasToHitAdded = true;
            }

            try
            {
                if (attackingInven.GetSecondaryActiveWeapon().WeaponType is WeaponSO.Type.Firearm)
                {
                    if (!hasToHitAdded)
                    {
                        if (triggers.ContainsKey(ToHitAdd))
                        {
                            triggers[ToHitAdd].Item1.Add("Firearm Adept");
                            triggers[ToHitAdd].Item2.Add(1);
                        }
                        else
                            triggers.Add(ToHitAdd, (new List<string> { "Firearm Adept" }, new List<object> { 1 }));
                    }

                    triggers.Add(FullOffHandSignal, (null, null));
                }
            }
            catch { }
        }
    }
    private static void FirearmWeaponMasterDamageFunction(Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[77]))
        {
            if (attackingInven.GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Firearm)
            {
                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Firearm Master");
                    triggers[AddDamageValue].Item2.Add(.3f);
                    triggers[AddDamageType].Item2.Add(WeaponSO.Type.Firearm);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Firearm Master" }, new List<object> { .3f }));
                    triggers.Add(AddDamageType, (new List<string> { }, new List<object> { WeaponSO.Type.Firearm }));
                }
            }
        }
    }
    private static void FirearmWeaponMasterTriggerFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[77]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 77).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GetInventory().SignalOffHandedChange(WeaponSO.Type.Firearm);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> pair in allyAbilities)
        {
            if (pair.Value.Contains(abilityList[77]))
            {
                Ability abRef = pair.Value.Where(ability => ability.AbilityID is 77).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    pair.Key.GetInventory().SignalOffHandedChange(WeaponSO.Type.Firearm);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static bool ExecutionerCheck(Entity attacker, Entity target, bool autoHit)
    {
        Inventory attackerInven = attacker.GetInventory();
        if (attackerInven.Abilities.Contains(abilityList[78]) || attackerInven.limitedAbilities.Contains(abilityList[78]))
        {
            Dice.DiceR indexDice = attackerInven.GetPrimaryActiveWeapon().WeaponDamage[0];
            if (target.RetrieveHealth() < UtilityHandler.RetrieveMaxValue(indexDice))
                autoHit = true;
        }

        return autoHit;
    }
    private static void TelekineticDamageMitigationFunction(SortedDictionary<int, (int, Dice)> damageRolls, Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers, Entity attacker)
    {
        if (targetInven.Abilities.Contains(abilityList[79]) || targetInven.limitedAbilities.Contains(abilityList[79]))
        {
            if (attacker is Enemy enemy && enemy.GetDamageType() is WeaponSO.Type.Ranged)
                DamageMitigation(damageRolls, triggers);
            else if (attacker is Ally ally)
            {
                try
                {
                    DamageMitigation(damageRolls, triggers);
                }
                catch
                {
                    if (ally.attackType is WeaponSO.Type.Ranged)
                        DamageMitigation(damageRolls, triggers);
                }
                
            }
            else if (attacker is Player player && player.GetInventory().GetPrimaryActiveWeapon().WeaponType is WeaponSO.Type.Ranged)
                DamageMitigation(damageRolls, triggers);
        }

        static void DamageMitigation(SortedDictionary<int, (int, Dice)> damageRolls, Dictionary<string, (List<string>, List<object>)> triggers)
        {
            int rolledValue = UtilityHandler.RollValue(Dice.DiceR.Four);
            if (triggers.ContainsKey(MinusDamageValue))
            {
                triggers[MinusDamageValue].Item1.Add("Telekinesis Mitigation");
                triggers[MinusDamageValue].Item2.Add(new List<object> { rolledValue, new DFour() });
            }
            else
                triggers.Add(MinusDamageValue, (new List<string> { "Telekinesis Mitigation" }, new List<object> { new List<object> { rolledValue, new DFour() } }));

            if (damageRolls is not null)
            {
                if (damageRolls.Count > 0)
                {
                    int currentDice = damageRolls.Last().Key;
                    damageRolls.Add(++currentDice, (rolledValue, new DFour()));
                }
                else
                    damageRolls.Add(0, (rolledValue, new DFour()));
            }
        }
    }
    private static void MissionarysGraceFunction(TownUI shopUI, Inventory playerInven, List<Inventory> allyInvens)
    {
        if (playerInven.Abilities.Contains(abilityList[80]) || playerInven.limitedAbilities.Contains(abilityList[80]))
        {
            int tithe = UnityEngine.Random.Range(50, 500);
            playerInven.AddGold(tithe);

            shopUI.AdjustInnRate(UnityEngine.Random.Range(.1f, .3f), false);
            return;
        }
        foreach (Inventory allyInven in allyInvens)
        {
            if (allyInven.Abilities.Contains(abilityList[80]) || allyInven.limitedAbilities.Contains(abilityList[80]))
            {
                int tithe = UnityEngine.Random.Range(50, 500);
                playerInven.AddGold(tithe);

                shopUI.AdjustInnRate(UnityEngine.Random.Range(.1f, .3f), false);
                return;
            }
        }
    }
    private static void ServantOfTheDivineFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[72]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 72).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add Exorcise and Divine Knowledge
                player.GetInventory().Add(spellList[16]);
                player.GetInventory().Add(spellList[54]);

                // Add Missionary's Grace
                player.GetInventory().Add(abilityList[80]);

                // Add Resistance to Light
                player.GatherStats().AddElementalResistance(SpellSO.Element.Light);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void ServantOfTheHellsFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[73]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 73).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add Life Contract, Touch of Death, and Summon Demonic Soldier
                player.GetInventory().Add(spellList[33]);
                player.GetInventory().Add(spellList[53]);
                player.GetInventory().Add(spellList[55]);

                // Add Resistances to Fire and Darkness
                player.GatherStats().AddElementalResistance(SpellSO.Element.Fire);
                player.GatherStats().AddElementalResistance(SpellSO.Element.Darkness);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void BattleShantiesFunction(Player player, Ally[] allyRetainers, Enemy[] enemyRetainers, Inventory invenToUse)
    {
        if (invenToUse.Abilities.Contains(abilityList[81]) || invenToUse.limitedAbilities.Contains(abilityList[81]))
        {
            List<Entity> entityList = new List<Entity>() { player };
            entityList.AddRange(allyRetainers);
            entityList.AddRange(enemyRetainers);

            foreach (Entity potentialEntity in entityList)
            {
                int rolledValue = DiceRoller.RollDice(new DHundred());

                if (rolledValue <= 5)
                {
                    if (potentialEntity is Ally || potentialEntity is Player)
                        potentialEntity.AddModToList(RandomBuff());
                    else
                        potentialEntity.AddModToList(RandomDebuff());

                    potentialEntity.AfflictedStatus();
                }
            }
        }
    }
    private static void ServantOfTheDeepFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[74]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 74).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Adds spells 'Aqua Ball', 'Summon Rain', and 'Chain Lightning'
                player.GetInventory().Add(spellList[56]);
                player.GetInventory().Add(spellList[57]);
                player.GetInventory().Add(spellList[58]);

                // Adds ability 'Battle Shanties'
                player.GetInventory().Add(abilityList[81]);

                // Add Water Resistance
                player.GatherStats().AddElementalResistance(SpellSO.Element.Water);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void ServantOfTheEldritchFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[75]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 75).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add spells Mind Blast, Mind Control, and Sacrificial Rite
                player.GetInventory().Add(spellList[59]);
                player.GetInventory().Add(spellList[60]);
                player.GetInventory().Add(spellList[61]);

                // Add ability Telekinetic
                player.GetInventory().Add(abilityList[79]);

                // Add Strange Resistance
                player.GatherStats().AddElementalResistance(SpellSO.Element.Strange);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void SteelskinFunction(Entity target, Inventory targetInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (targetInven.Abilities.Contains(abilityList[82]) || targetInven.limitedAbilities.Contains(abilityList[82]))
        {
            if (triggers.ContainsKey(AddArmor))
            {
                triggers[AddArmor].Item1.Add("Steelskin");
                triggers[AddArmor].Item2.Add(target.GatherStats().GetStat(EntityStats.Stat.Strength));
            }
            else
                triggers.Add(AddArmor, (new List<string> { "Steelskin" }, new List<object> { target.GatherStats().GetStat(EntityStats.Stat.Strength) }));
        }
    }
    private static void FixatedFocusFunction(Player player, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (player.GetInventory().Abilities.Contains(abilityList[84]))
        {
            Ability abRef = player.GetInventory().Abilities.Where(ability => ability.AbilityID is 84).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.GatherStats().ModifySavingThrow(EntityStats.Stat.Strength, 1);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
        {
            if (ally.Value.Contains(abilityList[84]))
            {
                Ability abRef = ally.Value.Where(ability => ability.AbilityID is 84).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    ally.Key.GatherStats().ModifySavingThrow(EntityStats.Stat.Strength, 1);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void InquisitiveSoulFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[85]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 85).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                EntityStats statRef = player.GatherStats();
                int oldINT = statRef.GetBaseStat(EntityStats.Stat.Intelligence);

                statRef.SetStat("INT", oldINT + 2);

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
        {
            if (ally.Value.Contains(abilityList[85]))
            {
                Ability abRef = ally.Value.Where(ability => ability.AbilityID is 85).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    EntityStats statRef = ally.Key.GatherStats();
                    int oldINT = statRef.GetBaseStat(EntityStats.Stat.Intelligence);

                    statRef.SetStat("INT", oldINT + 2);

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void FieldFocusManaReductionFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[93]))
        {
            Ability abRef = playerAbilities.Find(ability => ability.AbilityID is 93);

            SpellSO.Element elementChosen = (SpellSO.Element)((List<object>)playerAbilities
                                                .Where(ability => ability.AbilityID is 93).FirstOrDefault().ReferenceObject)[0];

            List<Spell> spells = new List<Spell>(player.GetInventory().Spells.Where(spell => spell.SpellType == elementChosen));
            List<Spell> limitedSpells = new List<Spell>(player.GetInventory().limitedSpells.Where(spell => spell.SpellType == elementChosen));

            bool isNull = false;
            try
            {
                List<Spell> gatheredList = (List<Spell>)((List<object>)abRef.ReferenceObject)[1];
            }
            catch { isNull = true; }

            if (isNull)
            {
                for (int i = 0; i < spells.Count; i++)
                    spells[i].SpellCost -= (int)Math.Floor(spells[i].SpellCost * .3f);
                for (int i = 0; i < limitedSpells.Count; i++)
                    limitedSpells[i].SpellCost -= (int)Math.Floor(limitedSpells[i].SpellCost * .3f);

                foreach (Spell moddedSpell in spells)
                    player.GetInventory().ReplaceSpell(moddedSpell);

                foreach (Spell moddedSpell in limitedSpells)
                    player.GetInventory().ReplaceLimitedSpell(moddedSpell);

                ((List<object>)abRef.ReferenceObject).Add(spells);
                ((List<object>)abRef.ReferenceObject).AddRange(limitedSpells);
                return;
            }

            bool spellRangeCheck = false;
            List<Spell> currentSpellList = (List<Spell>)((List<object>)abRef.ReferenceObject)[1];

            foreach (Spell check in spells)
            {
                if (!currentSpellList.Contains(check))
                {
                    spellRangeCheck = true;
                    break;
                }
            }

            if (!spellRangeCheck)
            {
                foreach (Spell check in limitedSpells)
                {
                    if (!currentSpellList.Contains(check))
                    {
                        spellRangeCheck = true;
                        break;
                    }
                }
            }

            if (spellRangeCheck)
            {
                foreach (Spell spell in spells)
                {
                    if (!currentSpellList.Contains(spell))
                        spell.SpellCost -= (int)Math.Floor(spell.SpellCost * .3f);
                }
                foreach (Spell spell in limitedSpells)
                {
                    if (!currentSpellList.Contains(spell))
                        spell.SpellCost -= (int)Math.Floor(spell.SpellCost * .3f);
                }

                foreach (Spell moddedSpell in spells)
                    player.GetInventory().ReplaceSpell(moddedSpell);

                foreach (Spell moddedSpell in limitedSpells)
                    player.GetInventory().ReplaceLimitedSpell(moddedSpell);

                ((List<object>)abRef.ReferenceObject)[1] = spells;
                ((List<Spell>)((List<object>)abRef.ReferenceObject)[1]).AddRange(limitedSpells);
            }
        }
    }
    private static void ChaoticEnergyMaxManaIncrease(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        if (playerAbilities.Contains(abilityList[97]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 97).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.IncreaseMaxMana(15);
                player.IncreaseMana(15);
                player.StatusChanged();

                abRef.HasNotModifiedEntity = false;
            }
        }
        foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
        {
            if (ally.Value.Contains(abilityList[97]))
            {
                Ability abRef = ally.Value.Where(ability => ability.AbilityID is 97).FirstOrDefault();

                if (abRef.HasNotModifiedEntity)
                {
                    ally.Key.IncreaseMaxMana(15);
                    ally.Key.IncreaseMana(15);
                    ally.Key.StatusChanged();

                    abRef.HasNotModifiedEntity = false;
                }
            }
        }
    }
    private static void ChaoticEnergyManaSurgeFunction(Entity entity, Inventory invenToUse)
    {
        if (invenToUse.Abilities.Contains(abilityList[97]) || invenToUse.limitedAbilities.Contains(abilityList[97]))
        {
            int rolledValue = DiceRoller.RollDice(new DHundred());

            if (rolledValue <= 5)
            {
                entity.AddModToList(modifierList["Mana Surge"]);
                entity.AfflictedStatus();
            }
        }
    }
    private static void ElementalMasteryFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[94]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 94).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                SpellSO.Element elementChosen = (SpellSO.Element)((List<object>)playerAbilities
                                                .Where(ability => ability.AbilityID is 93).FirstOrDefault().ReferenceObject)[0];

                switch (elementChosen)
                {
                    case SpellSO.Element.Normal:
                        // Silence
                        player.GetInventory().Add(spellList[24]);
                        break;
                    case SpellSO.Element.Fire:
                        // Fireball
                        player.GetInventory().Add(spellList[68]);
                        break;
                    case SpellSO.Element.Water:
                        // Torrent
                        player.GetInventory().Add(spellList[70]);
                        break;
                    case SpellSO.Element.Earth:
                        // Rock Blast
                        player.GetInventory().Add(spellList[27]);
                        break;
                    case SpellSO.Element.Wind:
                        // Whirlwind
                        player.GetInventory().Add(spellList[30]);
                        break;
                    case SpellSO.Element.Ice:
                        // Ray of Frost
                        player.GetInventory().Add(spellList[38]);
                        break;
                    case SpellSO.Element.Poison:
                        // Poison Splash
                        player.GetInventory().Add(spellList[40]);
                        break;
                    case SpellSO.Element.Darkness:
                        // Yog's Abyssal Hold
                        player.GetInventory().Add(spellList[71]);
                        break;
                    case SpellSO.Element.Light:
                        // Resurrection
                        player.GetInventory().Add(spellList[67]);
                        break;
                    case SpellSO.Element.Necro:
                        // Grasp Heart
                        player.GetInventory().Add(spellList[69]);
                        break;
                    case SpellSO.Element.Strange:
                        // Mind Blast
                        player.GetInventory().Add(spellList[59]);
                        break;
                    case SpellSO.Element.Energy:
                        // Chain Lightning
                        player.GetInventory().Add(spellList[58]);
                        break;

                }

                abRef.HasNotModifiedEntity = false;
            }

            if (abRef.ReferenceObject is null)
            {
                List<Spell> newSpells = new List<Spell>(player.GetInventory().Spells);
                List<Spell> newLimitedSpells = new List<Spell>(player.GetInventory().limitedSpells);

                foreach (Spell spell in newSpells)
                    spell.SpellCost -= (int)Math.Floor(spell.SpellCost * .2f);
                foreach (Spell spell in newLimitedSpells)
                    spell.SpellCost -= (int)Math.Floor(spell.SpellCost * .2f);
                
                foreach (Spell moddedSpell in newSpells)
                    player.GetInventory().ReplaceSpell(moddedSpell);

                foreach (Spell moddedSpell in newLimitedSpells)
                    player.GetInventory().ReplaceLimitedSpell(moddedSpell);

                abRef.ReferenceObject = newSpells;
                ((List<Spell>)abRef.ReferenceObject).AddRange(newLimitedSpells);
                return;
            }

            List<Spell> playerSpells = new List<Spell>(player.GetInventory().Spells);
            List<Spell> playerLimitedSpells = new List<Spell>(player.GetInventory().limitedSpells);

            List<Spell> referenceSpells = (List<Spell>)abRef.ReferenceObject;

            bool noChange = false;
            foreach (Spell spell in playerSpells)
            {
                if (!referenceSpells.Contains(spell))
                {
                    noChange = true;
                    break;
                }
            }
            if (!noChange)
            {
                foreach (Spell spell in playerLimitedSpells)
                {
                    if (!referenceSpells.Contains(spell))
                    {
                        noChange = true;
                        break;
                    }
                }
            }

            if (noChange)
            {
                foreach (Spell spell in playerSpells)
                {
                    if (!referenceSpells.Contains(spell))
                        spell.SpellCost -= (int)Math.Floor(spell.SpellCost * .2f);
                }
                foreach (Spell spell in playerLimitedSpells)
                {
                    if (!referenceSpells.Contains(spell))
                        spell.SpellCost -= (int)Math.Floor(spell.SpellCost * .2f);
                }

                foreach (Spell moddedSpell in playerSpells)
                    player.GetInventory().ReplaceSpell(moddedSpell);

                foreach (Spell moddedSpell in playerLimitedSpells)
                    player.GetInventory().ReplaceLimitedSpell(moddedSpell);

                abRef.ReferenceObject = playerSpells;
                ((List<Spell>)abRef.ReferenceObject).AddRange(playerLimitedSpells);
            }
        }
    }
    private static void PiratyLegacyFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[98]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 98).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Increase DEX and WIS by 1 point each
                int newDEX = player.GatherStats().GetBaseStat(EntityStats.Stat.Dexterity) + 1;
                int newWIS = player.GatherStats().GetBaseStat(EntityStats.Stat.Wisdom) + 1;

                player.GatherStats().SetStat("DEX", newDEX);
                player.GatherStats().SetStat("WIS", newWIS);

                // Add Pillage Spell
                player.GetInventory().Add(spellList[72]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void BanditLegacyFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[99]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 99).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Increase DEX by 1
                int newDex = player.GatherStats().GetBaseStat(EntityStats.Stat.Dexterity) + 1;
                player.GatherStats().SetStat("DEX", newDex);

                // Add Extortion and Dirty Tactics abilities
                player.GetInventory().Add(abilityList[103]);
                player.GetInventory().Add(abilityList[112]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void ManAtArmsFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[100]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 100).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Increase WIS by 1
                int newWIS = player.GatherStats().GetBaseStat(EntityStats.Stat.Wisdom) + 1;
                player.GatherStats().SetStat("WIS", newWIS);

                // Add Disciplined ability
                player.GetInventory().Add(abilityList[113]);

                // Add Magical Volley spell
                player.GetInventory().Add(spellList[73]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void DeathKnightFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[104]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 104).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add 1 point to CON
                int newCON = player.GatherStats().GetBaseStat(EntityStats.Stat.Constitution) + 1;
                player.GatherStats().SetStat("CON", newCON);

                // Add Touch of Death and Defiling Breath spells
                player.GetInventory().Add(spellList[55]);
                player.GetInventory().Add(spellList[74]);

                // Gain the Death and Decay ability
                player.GetInventory().Add(abilityList[114]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void PaladinFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[105]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 105).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add 2 points to STR
                int newSTR = player.GatherStats().GetBaseStat(EntityStats.Stat.Strength) + 2;
                player.GatherStats().SetStat("STR", newSTR);

                // Add Heal and Raise Morale spells
                player.GetInventory().Add(spellList[67]);
                player.GetInventory().Add(spellList[75]);

                // Add Hold the Line ability
                player.GetInventory().Add(abilityList[115]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void GreatWizardFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[107]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 107).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Increase INT by 2
                int newINT = player.GatherStats().GetBaseStat(EntityStats.Stat.Intelligence) + 2;
                player.GatherStats().SetStat("INT", newINT);

                // Increase Max Mana by 15
                player.IncreaseMaxMana(15);
                player.IncreaseMana(15);
                player.StatusChanged();

                // Add 'Mana Singularity' ability
                player.GetInventory().Add(abilityList[116]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void OverkillCritFunction(Entity attacker)
    {
        if (attacker.GetInventory().Abilities.Contains(abilityList[109]) || attacker.GetInventory().Abilities.Contains(abilityList[109]))
        {
            List<Ability> attackerList = new List<Ability>(attacker.GetInventory().Abilities);
            attackerList.AddRange(attacker.GetInventory().limitedAbilities);

            Ability abRef = attackerList.Where(ability => ability.AbilityID is 109).FirstOrDefault();

            if (!abRef.active)
            {
                attacker.GatherStats().SetModifierToStat(EntityStats.Stat.ToCritMod, 1);

                abRef.active = true;
            }
        }
    }
    private static void HoldTheLineArmorFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[115]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 115).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                int newArmor = player.RetrieveMaxArmor() + 1;
                player.SetArmor(newArmor);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void DeathAndDecayElementFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[114]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 114).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add Darkness and Necro Resistances
                player.GatherStats().AddElementalResistance(SpellSO.Element.Darkness);
                player.GatherStats().AddElementalResistance(SpellSO.Element.Necro);

                // Add Light Weakness
                player.GatherStats().AddElementalWeakness(SpellSO.Element.Light);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void SinisterThoughtsFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[110]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 110).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                EntityStats stats = player.GatherStats();

                // Decrease CHA by 1
                int newCHA = stats.GetBaseStat(EntityStats.Stat.Charisma) - 1;
                stats.SetStat("CHA", newCHA);

                // Increase LCK by 1
                int newLCK = stats.GetBaseStat(EntityStats.Stat.Luck) + 1;
                stats.SetStat("LCK", newLCK);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void HarmoniousThoughtsFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[111]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 111).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                EntityStats stats = player.GatherStats();

                // Increase CHA by 1
                int newCHA = stats.GetBaseStat(EntityStats.Stat.Charisma) + 1;
                stats.SetStat("CHA", newCHA);

                // Decrease LCK by 1
                int newLCK = stats.GetBaseStat(EntityStats.Stat.Luck) - 1;
                stats.SetStat("LCK", newLCK);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void PatronsSolutionFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[119]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 119).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Add unique spell based on patron
                Ability patronAbility = playerAbilities.Where(ability => ability.AbilityID is 72 || ability.AbilityID is 73 || ability.AbilityID is 74 || ability.AbilityID is 75).FirstOrDefault();

                switch (patronAbility.AbilityName)
                {
                    case "Servant of the Divine":   // Add Divine Ray
                        player.GetInventory().Add(spellList[80]);
                        break;
                    case "Servant of the Hells":    // Add Incineration Maelstrom
                        player.GetInventory().Add(spellList[64]);
                        break;
                    case "Servant of the Deep":     // Add Lightning Storm
                        player.GetInventory().Add(spellList[79]);
                        break;
                    case "Servant of the Eldritch": // Add Mass Confusion
                        player.GetInventory().Add(spellList[81]);
                        break;
                }

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void ManicBreakthroughFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[120]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 120).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                Ability patronAbility = playerAbilities.Where(ability => ability.AbilityID is 72 || ability.AbilityID is 73 || ability.AbilityID is 74 || ability.AbilityID is 75).FirstOrDefault();

                switch (patronAbility.AbilityName)
                {
                    case "Servant of the Divine":   // Add Guardian Angel
                        player.GetInventory().Add(abilityList[122]);
                        break;
                    case "Servant of the Hells":    // Add Sin Incarnation
                        player.GetInventory().Add(abilityList[121]);
                        break;
                    case "Servant of the Deep":     // Add Monstrous Form
                        player.GetInventory().Add(abilityList[123]);
                        break;
                    case "Servant of the Eldritch": // Add Psionic Nexus
                        player.GetInventory().Add(abilityList[124]);
                        break;
                }

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void SinIncarnationFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[121]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 121).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                EntityStats statRef = player.GatherStats();

                // Increase Armor by 1 and CHA by 2
                int newCHA = statRef.GetBaseStat(EntityStats.Stat.Charisma) + 2;
                statRef.SetStat("CHA", newCHA);

                int newArmor = player.RetrieveMaxArmor() + 1;
                player.SetArmor(newArmor);

                // Add Hellfire ability
                player.GetInventory().Add(abilityList[127]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void GuardianAngelFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[122]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 122).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                EntityStats statRef = player.GatherStats();

                // Increase WIS and LCK by 1
                int newWIS = statRef.GetBaseStat(EntityStats.Stat.Wisdom) + 1;
                statRef.SetStat("WIS", newWIS);

                int newLCK = statRef.GetBaseStat(EntityStats.Stat.Luck) + 1;
                statRef.SetStat("LCK", newLCK);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void PsionicNexusFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[124]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 124).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Increase INT by 3
                int newINT = player.GatherStats().GetBaseStat(EntityStats.Stat.Intelligence) + 3;
                player.GatherStats().SetStat("INT", newINT);

                // Increase maximum mana by 50
                player.IncreaseMaxMana(50);
                player.IncreaseMana(50);
                player.StatusChanged();

                // Gain the spells Psionic Overload and Psionic Detonation
                player.GetInventory().Add(spellList[84]);
                player.GetInventory().Add(spellList[85]);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void MonstrousFormFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[123]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 123).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                // Increase CON by 2 and STR by 1
                EntityStats statRef = player.GatherStats();

                int newCON = statRef.GetBaseStat(EntityStats.Stat.Constitution) + 2;
                statRef.SetStat("CON", newCON);

                int newSTR = statRef.GetBaseStat(EntityStats.Stat.Strength) + 1;
                statRef.SetStat("STR", newSTR);

                // Add Engorge spell
                player.GetInventory().Add(spellList[83]);

                // Add Resistances
                statRef.AddTypeResistance(WeaponSO.Type.Blunt);
                statRef.AddTypeResistance(WeaponSO.Type.Sharp);
                statRef.AddTypeResistance(WeaponSO.Type.Extended);
                statRef.AddTypeResistance(WeaponSO.Type.Ranged);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void DoubleTapFunction(Entity attacker, Entity target, SortedDictionary<int, (int, Dice)> damageRolls, Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[132]) || attackingInven.limitedAbilities.Contains(abilityList[132]))
        {
            bool succeeded = UtilityHandler.RollSavingThrow(EntityStats.Stat.Dexterity, target) >= 11 + attacker.GetStat(EntityStats.Stat.Dexterity);

            if (succeeded)
            {
                Weapon primeWeapon = attackingInven.GetPrimaryActiveWeapon();
                List<Dice.DiceR> weaponDamage = primeWeapon.WeaponDamage;

                int totalValue = 0;
                foreach (Dice.DiceR damageDice in weaponDamage)
                {
                    int rolledValue = UtilityHandler.RollValue(damageDice);
                    totalValue += rolledValue;

                    Dice dice = damageDice switch
                    {
                        Dice.DiceR.Four         => new DFour(),
                        Dice.DiceR.Six          => new DSix(),
                        Dice.DiceR.Eight        => new DEight(),
                        Dice.DiceR.Ten          => new DTen(),
                        Dice.DiceR.Twelve       => new DTwelve(),
                        Dice.DiceR.Twenty       => new DTwenty(),
                        Dice.DiceR.Hundred      => new DHundred(),

                        _ => throw new InvalidOperationException(),
                    };

                    if (damageRolls is not null)
                    {
                        if (damageRolls.Count > 0)
                        {
                            int currentDice = damageRolls.Last().Key;
                            damageRolls.Add(++currentDice, (rolledValue, dice));
                        }
                        else
                            damageRolls.Add(0, (rolledValue, dice));
                    }
                }

                if (triggers.ContainsKey(AddDamageValue))
                {
                    triggers[AddDamageValue].Item1.Add("Double Tap");
                    triggers[AddDamageValue].Item2.Add(weaponDamage.ToArray());
                    triggers[AddDamageType].Item2.Add(primeWeapon.WeaponType);
                }
                else
                {
                    triggers.Add(AddDamageValue, (new List<string> { "Double Tap" }, new List<object> { weaponDamage.ToArray() }));
                    triggers.Add(AddDamageType, (new List<string>(), new List<object> { primeWeapon.WeaponType }));
                }
            }
        }
    }
    private static void DeadlyAssassinHideFunction(List<Inventory> genInvens)
    {
        foreach (Inventory inven in genInvens)
        {
            if (inven.Abilities.Contains(abilityList[133]) || inven.limitedAbilities.Contains(abilityList[133]))
            {
                List<Ability> collectedAbilities = new List<Ability>(inven.Abilities);
                collectedAbilities.AddRange(inven.limitedAbilities);

                Ability abRef = collectedAbilities.Where(ability => ability.AbilityID is 133).FirstOrDefault();

                abRef.active = true;
                inven.AttachedEntity.HideEntity();
            }
        }
    }
    private static void SurpriseHideFunction(List<Inventory> genInvens)
    {
        foreach (Inventory inven in genInvens)
        {
            if (inven.Abilities.Contains(abilityList[57]) || inven.limitedAbilities.Contains(abilityList[57]))
            {
                List<Ability> collectedAbilities = new List<Ability>(inven.Abilities);
                collectedAbilities.AddRange(inven.limitedAbilities);

                Ability abRef = collectedAbilities.Where(ability => ability.AbilityID is 57).FirstOrDefault();

                inven.AttachedEntity.HideEntity();
                abRef.active = true;
            }
        }
    }
    private static bool DeadlyAssassinFunction(bool hasCrit, Inventory attackingInven)
    {
        if (attackingInven.Abilities.Contains(abilityList[133]) || attackingInven.limitedAbilities.Contains(abilityList[133]))
        {
            List<Ability> collectedAbilities = new List<Ability>(attackingInven.Abilities);
            collectedAbilities.AddRange(attackingInven.limitedAbilities);

            Ability abRef = collectedAbilities.Where(ability => ability.AbilityID is 133).FirstOrDefault();

            if (abRef.active)
            {
                hasCrit = true;
                attackingInven.AttachedEntity.ShowEntity();
                abRef.active = false;
            }
        }

        return hasCrit;
    }
    private static void StanceGuardianModFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[135]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 135).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                int newCON = player.GetBaseStat(EntityStats.Stat.Constitution) + 1;
                player.GatherStats().SetStat("CON", newCON);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void StanceSlayerModFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[136]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 136).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                int newSTR = player.GetBaseStat(EntityStats.Stat.Strength) + 1;
                player.GatherStats().SetStat("STR", newSTR);

                player.GatherStats().SetModifierToStat(EntityStats.Stat.ToCritMod, 1);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void StanceCunningModFunction(Player player, List<Ability> playerAbilities)
    {
        if (playerAbilities.Contains(abilityList[137]))
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 137).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                int newDEX = player.GetBaseStat(EntityStats.Stat.Dexterity) + 1;
                player.GatherStats().SetStat("DEX", newDEX);

                abRef.HasNotModifiedEntity = false;
            }
        }
    }
    private static void StanceGuardianFunction(Entity target, Player player, Ally[] leftComps, Enemy[] rightEnemies, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (target is Enemy targettedEnemy)
        {
            foreach (Enemy enemy in rightEnemies)
            {
                if (enemy.GetUniqueID() == targettedEnemy.GetUniqueID())
                    continue;
                else
                {
                    if (enemy.GetInventory().Abilities.Contains(abilityList[135]))
                    {
                        int addedArmor = Globals.GatherModifier(enemy.GetBaseStat(EntityStats.Stat.Dexterity));

                        if (triggers.ContainsKey(AddArmor))
                        {
                            triggers[AddArmor].Item1.Add("Stance of the Guardian");
                            triggers[AddArmor].Item2.Add(addedArmor);
                        }
                        else
                            triggers.Add(AddArmor, (new List<string> { "Stance of the Guardian" }, new List<object> { addedArmor }));
                    }
                }
            }
        }
        else if (target is Player)
        {
            foreach (Ally ally in leftComps)
            {
                if (ally.GetInventory().Abilities.Contains(abilityList[135]))
                {
                    int addedArmor = Globals.GatherModifier(ally.GetBaseStat(EntityStats.Stat.Dexterity));

                    if (triggers.ContainsKey(AddArmor))
                    {
                        triggers[AddArmor].Item1.Add("Stance of the Guardian");
                        triggers[AddArmor].Item2.Add(addedArmor);
                    }
                    else
                        triggers.Add(AddArmor, (new List<string> { "Stance of the Guardian" }, new List<object> { addedArmor }));
                }
            }
        }
        else if (target is Ally targettedAlly)
        {
            if (player.GetInventory().Abilities.Contains(abilityList[135]))
            {
                int addedArmor = Globals.GatherModifier(player.GetBaseStat(EntityStats.Stat.Dexterity));

                if (triggers.ContainsKey(AddArmor))
                {
                    triggers[AddArmor].Item1.Add("Stance of the Guardian");
                    triggers[AddArmor].Item2.Add(addedArmor);
                }
                else
                    triggers.Add(AddArmor, (new List<string> { "Stance of the Guardian" }, new List<object> { addedArmor }));
            }

            foreach (Ally ally in leftComps)
            {
                if (targettedAlly.GetUniqueID() == ally.GetUniqueID())
                    continue;
                else
                {
                    if (ally.GetInventory().Abilities.Contains(abilityList[135]))
                    {
                        int addedArmor = Globals.GatherModifier(ally.GetBaseStat(EntityStats.Stat.Dexterity));

                        if (triggers.ContainsKey(AddArmor))
                        {
                            triggers[AddArmor].Item1.Add("Stance of the Guardian");
                            triggers[AddArmor].Item2.Add(addedArmor);
                        }
                        else
                            triggers.Add(AddArmor, (new List<string> { "Stance of the Guardian" }, new List<object> { addedArmor }));
                    }
                }
            }
        }
    }
    private static void StanceCunningFunction(Entity attacker, Inventory attackingInven, Dictionary<string, (List<string>, List<object>)> triggers)
    {
        if (attackingInven.Abilities.Contains(abilityList[137]))
        {
            int armorValue = Globals.GatherModifier(attacker.GetBaseStat(EntityStats.Stat.Dexterity));

            if (triggers.ContainsKey(MinusArmor))
            {
                triggers[MinusArmor].Item1.Add("Stance of the Cunning");
                triggers[MinusArmor].Item2.Add(armorValue);
            }
            else
                triggers.Add(MinusArmor, (new List<string> { "Stance of the Cunning" }, new List<object> { armorValue }));
        }
    }
    private static void RapidDecisionsFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        bool playerContains = playerAbilities.Contains(abilityList[139]);
        bool alliesContain = allyAbilities.Any(pair => pair.Value.Contains(abilityList[139]));

        if (playerContains)
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 139).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.ActionCount += 1;

                abRef.HasNotModifiedEntity = false;
            }
        }
        else if (alliesContain)
        {
            foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
            {
                if (ally.Value.Contains(abilityList[139]))
                {
                    Ability abRef = ally.Value.Where(ability => ability.AbilityID is 139).FirstOrDefault();

                    if (abRef.HasNotModifiedEntity)
                    {
                        ally.Key.ActionCount += 1;

                        abRef.HasNotModifiedEntity = false;
                    }
                }
            }
        }
    }
    private static void MultiAttackFunction(Player player, List<Ability> playerAbilities, Dictionary<Ally, List<Ability>> allyAbilities)
    {
        bool playerContains = playerAbilities.Contains(abilityList[138]);
        bool alliesContain = allyAbilities.Any(pair => pair.Value.Contains(abilityList[138]));

        if (playerContains)
        {
            Ability abRef = playerAbilities.Where(ability => ability.AbilityID is 138).FirstOrDefault();

            if (abRef.HasNotModifiedEntity)
            {
                player.AttackCount += 1;

                abRef.HasNotModifiedEntity = false;
            }
        }
        else if (alliesContain)
        {
            foreach (KeyValuePair<Ally, List<Ability>> ally in allyAbilities)
            {
                if (ally.Value.Contains(abilityList[138]))
                {
                    Ability abRef = ally.Value.Where(ability => ability.AbilityID is 138).FirstOrDefault();

                    if (abRef.HasNotModifiedEntity)
                    {
                        ally.Key.AttackCount += 1;

                        abRef.HasNotModifiedEntity = false;
                    }
                }

            }
        }
    }
    private static void ThickFatFunction(Dictionary<Entity, List<Ability>> entityAbilities)
    {
        foreach (KeyValuePair<Entity, List<Ability>> entity in entityAbilities)
        {
            if (entity.Value.Contains(abilityList[143]))
            {
                if (entity.Key.GatherModList().SmartModCheck("Frozen"))
                {
                    entity.Key.GatherModList().RemoveModifier(modifierList["Frozen"]);
                    entity.Key.AfflictedStatus();
                }
                else if (entity.Key.GatherModList().SmartModCheck("Burned"))
                {
                    entity.Key.GatherModList().RemoveModifier(modifierList["Burned"]);
                    entity.Key.AfflictedStatus();
                }
                else if (entity.Key.GatherModList().SmartModCheck("Envenomated"))
                {
                    entity.Key.GatherModList().RemoveModifier(modifierList["Envenomated"]);
                    entity.Key.AfflictedStatus();
                }
            }
        }
    }
    private static void SharpTrackerFunction(Player player, Ally[] allyComps, Enemy[] enemyComps, List<Inventory> genInvens)
    {
        foreach (Inventory inven in genInvens)
        {
            if (inven.Abilities.Contains(abilityList[67]) || inven.limitedAbilities.Contains(abilityList[67]))
            {
                if (inven.AttachedEntity is Player)
                {
                    Modifier modToAdd = modifierList["Tracked Target"];
                    modToAdd.RetentionObject = inven.AttachedEntity as Player;

                    Enemy chosenTarget;
                    int targetAttempts = 0;
                    do
                    {
                        chosenTarget = enemyComps[UnityEngine.Random.Range(0, enemyComps.Length)];
                        targetAttempts++;

                    } while (chosenTarget.GatherModList().SmartModCheck("Tracked Target") && targetAttempts < 10);

                    if (targetAttempts < 10)
                        chosenTarget.AddModToList(modToAdd);
                }
                else if (inven.AttachedEntity is Ally)
                {
                    Modifier modToAdd = modifierList["Tracked Target"];
                    modToAdd.RetentionObject = inven.AttachedEntity as Ally;

                    Enemy chosenTarget;
                    int targetAttempts = 0;
                    do
                    {
                        chosenTarget = enemyComps[UnityEngine.Random.Range(0, enemyComps.Length)];
                        targetAttempts++;

                    } while (chosenTarget.GatherModList().SmartModCheck("Tracked Target") && targetAttempts < 10);

                    if (targetAttempts < 10)
                        chosenTarget.AddModToList(modToAdd);
                }
                else
                {
                    Modifier modToAdd = modifierList["Tracked Target"];
                    modToAdd.RetentionObject = inven.AttachedEntity as Enemy;

                    Entity chosenTarget;
                    int targetAttempts = 0;
                    do
                    {
                        int indexRoll = UnityEngine.Random.Range(-1, allyComps.Length);
                        chosenTarget = indexRoll is -1 ? player : allyComps[indexRoll];

                    } while (chosenTarget.GatherModList().SmartModCheck("Tracked Target") && targetAttempts < 10);

                    if (targetAttempts < 10)
                        chosenTarget.AddModToList(modToAdd);
                }
            }
        }
    }
    #endregion
    /// <summary>
    /// Handles intialization of cursed aura component to the Game Manager when the player has the ability
    /// </summary>
    public static void InitializeCursedAuraComponents()
        => cursedAura = GameManager.Instance.gameObject.AddComponent<CursedAuraInteractions>();
    public static Ability GetCurseAbilityReference()
        => abilityList[1];
}