예제 #1
0
    public void sendForward(GameObject caster)
    {
        if (SceneLoader.instance && SceneLoader.instance.sceneLoading)
        {
            return;
        }

        // force wait
        StateController stateController = caster.GetComponent <StateController>();

        if (stateController && stateController.waiting && (!stateController.currentState || stateController.currentState.priority < 95))
        {
            stateController.forceChangeState(stateController.waiting);
        }

        // send forward in time
        GameObject tardis = new GameObject();

        tardis.transform.position = caster.transform.position;
        tardis.AddComponent <SelfDestroyer>();
        DisableChildrenForDurationThenRelease chameleonCircuit = tardis.AddComponent <DisableChildrenForDurationThenRelease>();

        chameleonCircuit.duration = duration;
        CreateOnDeath cod = tardis.AddComponent <CreateOnDeath>();

        cod.objectsToCreateOnDeath.Add(new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("AnomalyEndEffect")));

        chameleonCircuit.disableSceneLoaderForDuration = true;
        chameleonCircuit.tag        = "Persistent";
        chameleonCircuit.nextParent = caster.transform.parent;
        caster.transform.parent     = tardis.transform;
    }
예제 #2
0
    // Use this for initialization
    protected override void Awake()
    {
        ability = AbilityIDList.getAbility(AbilityID.summonWraith);
        health  = GetComponent <BaseHealth>();
        mana    = GetComponent <BaseMana>();

        if (health)
        {
            statBuffs = Comp <StatBuffs> .GetOrAdd(gameObject);

            tracker = Comp <SummonTracker> .GetOrAdd(gameObject);

            AbilityEventListener listener = Comp <AbilityEventListener> .GetOrAdd(gameObject);

            listener.onCritEvent += OnCrit;
        }

        // get wraith prefabs
        if (flameWraithPrefab == null)
        {
            Ability wraithAbility = Ability.getAbility(AbilityID.summonFlameWraith);
            if (wraithAbility && wraithAbility.abilityPrefab)
            {
                SummonEntityOnDeath summon = wraithAbility.abilityPrefab.GetComponent <SummonEntityOnDeath>();
                if (summon)
                {
                    flameWraithPrefab = summon.entity;
                }
            }

            wraithAbility = Ability.getAbility(AbilityID.summonPutridWraith);
            if (wraithAbility && wraithAbility.abilityPrefab)
            {
                SummonEntityOnDeath summon = wraithAbility.abilityPrefab.GetComponent <SummonEntityOnDeath>();
                if (summon)
                {
                    putridWraithPrefab = summon.entity;
                }
            }

            wraithAbility = Ability.getAbility(AbilityID.summonBloodWraith);
            if (wraithAbility && wraithAbility.abilityPrefab)
            {
                SummonEntityOnDeath summon = wraithAbility.abilityPrefab.GetComponent <SummonEntityOnDeath>();
                if (summon)
                {
                    bloodWraithPrefab = summon.entity;
                }
            }
        }

        // spirit escape prefab
        if (spiritEscapePrefab == null)
        {
            spiritEscapePrefab = PrefabList.getPrefab("spiritEscape");
        }

        base.Awake();
    }
    public void sendForward(GameObject enemy)
    {
        if (enemy.transform.parent == null)
        {
            // force wait
            StateController stateController = enemy.GetComponent <StateController>();
            if (stateController && stateController.waiting && (!stateController.currentState || stateController.currentState.priority < 95))
            {
                stateController.forceChangeState(stateController.waiting);
            }

            // send forward in time
            GameObject tardis = new GameObject();
            tardis.transform.position = enemy.transform.position;
            enemy.transform.parent    = tardis.transform;
            tardis.AddComponent <SelfDestroyer>();
            DisableChildrenForDurationThenRelease chameleonCircuit = tardis.AddComponent <DisableChildrenForDurationThenRelease>();
            chameleonCircuit.duration = duration;
            CreateOnDeath cod = tardis.AddComponent <CreateOnDeath>();
            cod.objectsToCreateOnDeath.Add(new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("AnomalyEndEffect")));
        }
    }
예제 #4
0
    // Use this for initialization
    protected override void Awake()
    {
        ability = AbilityIDList.getAbility(AbilityID.marrowShards);
        physTag.Add(Tags.AbilityTags.Physical);
        AbilityEventListener listener = Comp <AbilityEventListener> .GetOrAdd(gameObject);

        listener.onKillEvent += OnKill;
        listener.onCritEvent += OnCrit;
        health = GetComponent <BaseHealth>();
        if (health)
        {
            statBuffs = Comp <StatBuffs> .GetOrAdd(gameObject);

            tracker = Comp <SummonTracker> .GetOrAdd(gameObject);
        }
        aoc = Comp <AbilityObjectConstructor> .GetOrAdd(gameObject);

        mana               = GetComponent <BaseMana>();
        baseStats          = GetComponent <BaseStats>();
        boneNovaOffset     = new Vector3(0f, 1.2f, 0f);
        spiritEscapeOffset = new Vector3(0f, 1.1f, 0f);
        spiritEscapePrefab = PrefabList.getPrefab("spiritEscape");
        base.Awake();
    }
예제 #5
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (splatterChance > 0 && (!mana || mana.currentMana > 0) && (splatterChance >= 1 || splatterChance > (Random.Range(0f, 1f))))
        {
            // splatter trigger
            CreateAbilityObjectOnDeath component = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
            component.abilityToInstantiate = Ability.getAbility(AbilityID.bloodSplatter);

            // splatter mutator
            BloodSplatterMutator mutator = abilityObject.AddComponent <BloodSplatterMutator>();
            mutator.increasedRadius               = splatter_increasedRadius;
            mutator.increasedDamage               = splatter_increasedDamage;
            mutator.chanceToPoison                = splatter_chanceToPoison;
            mutator.armourReductionChance         = splatter_armourReductionChance;
            mutator.armourReduction               = splatter_armourReduction;
            mutator.armourReductionStacks         = splatter_armourReductionStacks;
            mutator.increasedArmourDebuffDuration = splatter_increasedArmourDebuffDuration;
            mutator.increasedDamagePerMinion      = splatter_increasedDamagePerMinion;
            mutator.minionBuffs = splatter_minionBuffs;
            mutator.reducesDarkProtectionInstead = splatter_reducesDarkProtectionInstead;
            mutator.necrotic = necrotic;
        }


        if (necrotic)
        {
            // replace vfx
            CreateOnDeath cod = abilityObject.GetComponent <CreateOnDeath>();
            if (cod && cod.objectsToCreateOnDeath != null && cod.objectsToCreateOnDeath.Count > 0)
            {
                cod.objectsToCreateOnDeath[0] = new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("NecroticRipBloodOnDeathVFX"));
            }

            // convert damage
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.convertAllDamageOfType(DamageType.PHYSICAL, DamageType.NECROTIC);
            }
        }

        if (targetsAlliesInstead)
        {
            // change the damage component to hit allies (only hits minions by default)
            DamageEnemyOnHit damageComponent = abilityObject.GetComponent <DamageEnemyOnHit>();
            DamageAllyOnHit  component       = abilityObject.AddComponent <DamageAllyOnHit>();
            component.baseDamageStats = damageComponent.baseDamageStats;
            damageComponent.deactivate();
            Destroy(damageComponent);

            // make sure it still creates a blood orb
            CreateResourceReturnAbilityObjectOnEnemyHit component2 = abilityObject.GetComponent <CreateResourceReturnAbilityObjectOnEnemyHit>();
            component2.hitsAlliesInstead = true;

            // change the targetting
            MoveToNearestEnemyOnCreation moveComponent = abilityObject.GetComponent <MoveToNearestEnemyOnCreation>();
            if (moveComponent)
            {
                moveComponent.moveToAllyInstead = true;
            }
        }


        if (chanceToPoison > 0)
        {
            ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Poison);
            newComponent.chance       = chanceToPoison;
        }

        if (chanceToBleed > 0)
        {
            ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Bleed);
            newComponent.chance       = chanceToBleed;
        }

        if (addedHealthGained != 0 || increasedHealthGained != 0 || manaGained != 0 || convertHealthToWard || necrotic)
        {
            CreateResourceReturnAbilityObjectOnEnemyHit component = abilityObject.GetComponent <CreateResourceReturnAbilityObjectOnEnemyHit>();

            // check if this behaviour needs to be removed
            if (increasedHealthGained < -1 && manaGained <= 0)
            {
                component.deactivated = true;
            }
            // if it does not then change its values
            else
            {
                component.health += addedHealthGained;
                component.health *= (1 + increasedHealthGained);
                if (increasedHealthGainedPerAttunement != 0)
                {
                    component.health *= (1 + baseStats.GetStatValue(Tags.Properties.Attunement) * increasedHealthGainedPerAttunement);
                }
                component.mana += manaGained;
                if (convertHealthToWard)
                {
                    component.ward   = component.health;
                    component.health = 0;
                }
                if (necrotic)
                {
                    component.abilityObject = Ability.getAbility(AbilityID.necroticReturn);
                }
            }
        }


        if (increasedStunChance != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.baseDamageStats.increasedStunChance += increasedStunChance;
            }
        }

        // increase damage based on the number of minions
        float realIncreasedDamage = increasedDamage;

        if (increasedDamagePerMinion != 0)
        {
            if (tracker && tracker.summons != null)
            {
                realIncreasedDamage += increasedDamagePerMinion * tracker.summons.Count;
            }
        }


        if (realIncreasedDamage != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(realIncreasedDamage);
            }
        }

        if (moreDamageInstances != null && moreDamageInstances.Count > 0)
        {
            float moreDamage = 1f;
            foreach (float instance in moreDamageInstances)
            {
                moreDamage *= 1 + instance;
            }

            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(moreDamage - 1);
            }
        }

        return(abilityObject);
    }
예제 #6
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // if this is a meteor shower
        if (additionalMeteors > 0)
        {
            Destroy(abilityObject);

            abilityObject = Instantiate(AbilityIDList.getAbility(AbilityID.meteorShower).abilityPrefab);
            abilityObject.transform.position = location;
            CastAtRandomPointAfterDuration meteorCaster = abilityObject.GetComponent <CastAtRandomPointAfterDuration>();
            meteorCaster.duration       /= (1 + increasedMeteorFrequency);
            meteorCaster.remainingCasts += additionalMeteors;
            meteorCaster.radius         *= (1 + increasedShowerRadius);

            if (line)
            {
                StartsAtTarget sat = meteorCaster.GetComponent <StartsAtTarget>();
                if (sat)
                {
                    sat.active = false;
                    Destroy(sat);
                }
                AbilityMover mover = Comp <AbilityMover> .GetOrAdd(abilityObject);

                mover.SetDirection(targetLocation - location);
                mover.speed         = 10 * (1 + increasedShowerRadius);
                meteorCaster.radius = 0;
                StartsTowardsTarget stt = abilityObject.AddComponent <StartsTowardsTarget>();
                stt.distance       = 1f;
                stt.addWeaponRange = false;
            }

            // create a mutator on the meteor shower object
            MeteorMutator newMutator = abilityObject.AddComponent <MeteorMutator>();



            // variables for all damage
            newMutator.moreDamageInstances = moreDamageInstances;

            // meteor variables (except use all mana)
            newMutator.increasedFallSpeed     = increasedFallSpeed;
            newMutator.increasedCastSpeed     = increasedCastSpeed;
            newMutator.shrapnelChance         = shrapnelChance;
            newMutator.increasedShrapnelSpeed = increasedShrapnelSpeed;
            newMutator.shrapnelPierces        = shrapnelPierces;
            newMutator.replaceFireCircle      = replaceFireCircle;

            // aoe variables
            newMutator.moreDamageAgainstFullHealth = moreDamageAgainstFullHealth;
            newMutator.increasedShrapnelDamage     = increasedShrapnelDamage;
            newMutator.increasedStunChance         = increasedStunChance;
            newMutator.moreDamageInstances         = new List <float>();
            newMutator.moreDamageInstances.AddRange(moreDamageInstances);

            // apply mana variable once for all meteors
            if (usesAllMana && myMana)
            {
                float totalCost = myMana.getManaCost(ability);
                totalCost += myMana.currentMana;

                float proportion = totalCost / myMana.maxMana;
                newMutator.moreDamageInstances.Add(proportion * 2);

                myMana.currentMana = 0;
            }

            return(abilityObject);
        }


        // if this is a regular meteor

        // apply aoe variables
        MeteorAoEMutator aoeMutator = abilityObject.AddComponent <MeteorAoEMutator>();

        aoeMutator.moreDamageAgainstFullHealth = moreDamageAgainstFullHealth;
        aoeMutator.increasedStunChance         = increasedStunChance;
        aoeMutator.moreDamageInstances         = new List <float>();
        aoeMutator.moreDamageInstances.AddRange(moreDamageInstances);


        // meteor variables

        if (increasedFallSpeed != 0)
        {
            abilityObject.GetComponent <AbilityMover>().speed *= (1 + increasedFallSpeed);
        }

        MeteorShrapnelMutator shrapnelMutator = null;

        if (shrapnelChance > 0)
        {
            float rand = Random.Range(0f, 1f);
            if (rand < shrapnelChance)
            {
                CreateAbilityObjectOnDeath caood = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
                caood.abilityToInstantiate = AbilityIDList.getAbility(AbilityID.meteorShrapnel);
                caood.createAtTarget       = true;
                caood.offset    = -caood.GetComponent <LocationDetector>().targetLocationOffset;
                shrapnelMutator = abilityObject.AddComponent <MeteorShrapnelMutator>();
                shrapnelMutator.increasedDamage     = increasedShrapnelDamage;
                shrapnelMutator.increasedSpeed      = increasedShrapnelSpeed;
                shrapnelMutator.pierces             = shrapnelPierces;
                shrapnelMutator.increasedStunChance = increasedStunChance;
                shrapnelMutator.moreDamageInstances = new List <float>();
                shrapnelMutator.moreDamageInstances.AddRange(moreDamageInstances);
            }
        }

        if (replaceFireCircle)
        {
            CreateAtTargetLocationOnCreation component = abilityObject.GetComponent <CreateAtTargetLocationOnCreation>();
            if (component)
            {
                component.objectsToCreate.Clear();
                GameObject prefab = PrefabList.getPrefab("EnemyMeteorCircle");
                if (prefab)
                {
                    CreateAtTargetLocationOnCreation.GameObjectHolder holder = new CreateAtTargetLocationOnCreation.GameObjectHolder();
                    holder.gameObject          = prefab;
                    holder.destroyWhenThisDies = true;
                    component.objectsToCreate.Add((holder));
                }
            }
        }

        if (usesAllMana && myMana)
        {
            float totalCost = myMana.getManaCost(ability);
            totalCost += myMana.currentMana;

            float proportion = totalCost / myMana.maxMana;

            aoeMutator.moreDamageInstances.Add(proportion * 2);
            if (shrapnelMutator)
            {
                shrapnelMutator.moreDamageInstances.Add(proportion * 2);
            }

            myMana.currentMana = 0;
        }


        return(abilityObject);
    }
예제 #7
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (convertToCold)
        {
            foreach (CreateOnDeath cod in abilityObject.GetComponents <CreateOnDeath>())
            {
                cod.objectsToCreateOnDeath.Clear();
                cod.objectsToCreateOnDeath.Add(new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("QuickIceCircleVFX")));
            }
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.addBaseDamage(DamageType.COLD, holder.getBaseDamage(DamageType.FIRE));
                holder.addBaseDamage(DamageType.FIRE, -holder.getBaseDamage(DamageType.FIRE));
            }
            foreach (ConstantRotation rot in abilityObject.GetComponents <ConstantRotation>())
            {
                rot.degreesPerSecond = 0f;
            }
        }

        if (increasedStunChance != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.baseDamageStats.increasedStunChance += increasedStunChance;
            }
        }

        if (increasedDamage != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(increasedDamage);
            }
        }

        if (moreDamageInstances != null && moreDamageInstances.Count > 0)
        {
            float moreDamage = 1f;
            foreach (float instance in moreDamageInstances)
            {
                moreDamage *= 1 + instance;
            }

            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(moreDamage - 1);
            }
        }

        if (chillChance > 0)
        {
            ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Chill);
            newComponent.chance       = chillChance;
        }

        if (igniteChance > 0)
        {
            ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Ignite);
            if (convertToCold)
            {
                newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Chill);
            }
            newComponent.chance = igniteChance;
        }

        return(abilityObject);
    }
예제 #8
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        firstHit           = true;
        lastTargetPosition = targetLocation;

        if (movesRandomly)
        {
            RandomiseDirection component = abilityObject.AddComponent <RandomiseDirection>();
            component.maximumAngleChange      = 180f * (1 + increasedRandomisation);
            component.timeToRandomise         = RandomiseDirection.TimeToRandomise.DirectionMode;
            component.directionChangeInterval = directionChangeInterval;
            component.boundingAngle           = boundingAngle;
        }

        if (chanceToPoison > 0)
        {
            ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Poison);
            newComponent.chance       = chanceToPoison;
        }

        if (chanceToIgnite > 0)
        {
            ChanceToApplyStatusOnEnemyHit chanceTo = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            chanceTo.chance       = chanceToIgnite;
            chanceTo.statusEffect = StatusEffectList.getEffect(StatusEffectID.Ignite);
        }

        if (chanceToShredArmour > 0)
        {
            ChanceToApplyStatusOnEnemyHit chanceTo = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            chanceTo.chance       = chanceToShredArmour;
            chanceTo.statusEffect = StatusEffectList.getEffect(StatusEffectID.ArmourShred);
        }

        if (addedCritChance != 0)
        {
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.baseDamageStats.critChance += addedCritChance;
            }
        }

        if (addedCritMultiplier != 0)
        {
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.baseDamageStats.critMultiplier += addedCritMultiplier;
            }
        }

        if (cullPercent > 0)
        {
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.baseDamageStats.cullPercent += cullPercent;
            }
        }

        if (increasedDamage != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(increasedDamage);
                //holder.addBaseDamage(DamageType.PHYSICAL, holder.getBaseDamage(DamageType.PHYSICAL) * increasedDamage);
            }
        }

        if (addedFireDamage > 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.addBaseDamage(DamageType.FIRE, addedFireDamage);
            }
            // change the vfx
            abilityObject.GetComponent <CreateOnDeath>().objectsToCreateOnDeath.RemoveAt(0);
            abilityObject.GetComponent <CreateOnDeath>().add(PrefabList.getPrefab("animalSwipeVFXOrange"));
        }

        if (addedPhysicalDamage > 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.addBaseDamage(DamageType.PHYSICAL, addedPhysicalDamage);
            }
        }

        if (slows)
        {
            AttachAttachableOnEnemyHit newComponent = abilityObject.AddComponent <AttachAttachableOnEnemyHit>();
            newComponent.attachable = AbilityIDList.getAbility(AbilityID.slow).abilityPrefab;
        }

        if (travels)
        {
            // enable the vfx on the ability object itself
            foreach (Transform child in abilityObject.transform)
            {
                if (child.name == "SwipeVFX" && addedFireDamage <= 0)
                {
                    child.gameObject.SetActive(true);
                }
                if (child.name == "SwipeVFXOrange" && addedFireDamage > 0)
                {
                    child.gameObject.SetActive(true);
                }
            }
            // disable creating the vfx on death
            abilityObject.GetComponent <CreateOnDeath>().objectsToCreateOnDeath.RemoveAt(0);
            // set duration
            abilityObject.GetComponent <DestroyAfterDuration>().duration = 0.18f * (1 + increasedDuration);
            // set speed
            abilityObject.GetComponent <AbilityMover>().speed = 12f + addedSpeed;
            // remove start towards target
            abilityObject.GetComponent <StartsTowardsTarget>().distance = 0f;

            // add extra projectiles
            if (chanceOfExtraProjectiles > 0)
            {
                float rand2 = Random.Range(0f, 1f);
                if (rand2 < chanceOfExtraProjectiles)
                {
                    ExtraProjectiles extraProjectiles = abilityObject.AddComponent <ExtraProjectiles>();
                    extraProjectiles.angle        = 180f;
                    extraProjectiles.randomAngles = true;
                }
            }
        }


        return(abilityObject);
    }
예제 #9
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (increasedRadius != 0)
        {
            foreach (CreateOnDeath cod in abilityObject.GetComponents <CreateOnDeath>())
            {
                cod.increasedRadius = increasedRadius;
                cod.increasedHeight = increasedRadius;
            }
            foreach (CapsuleCollider col in abilityObject.GetComponents <CapsuleCollider>())
            {
                col.height *= (1 + increasedRadius);
                col.radius *= (1 + increasedRadius);
            }
        }

        if (necrotic)
        {
            // replace vfx
            CreateOnDeath cod = abilityObject.GetComponent <CreateOnDeath>();
            if (cod && cod.objectsToCreateOnDeath != null && cod.objectsToCreateOnDeath.Count > 0)
            {
                cod.objectsToCreateOnDeath[0] = new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("NecroticBloodSplatterOnDeathVFX"));
            }

            // convert damage
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.convertAllDamageOfType(DamageType.PHYSICAL, DamageType.NECROTIC);
            }
        }

        if (chanceToPoison > 0)
        {
            ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Poison);
            newComponent.chance       = chanceToPoison;
        }

        if (armourReductionChance > 0 && Random.Range(0f, 1f) < armourReductionChance)
        {
            DebuffOnEnemyHit component = abilityObject.AddComponent <DebuffOnEnemyHit>();
            if (reducesDarkProtectionInstead)
            {
                if (armourReductionStacks)
                {
                    component.addDebuffToList(Tags.Properties.DarkProtection, armourReduction, 0f, null, null, 4f * (1 + increasedArmourDebuffDuration));
                }
                else
                {
                    component.addDebuffToList(Tags.Properties.DarkProtection, armourReduction, 0f, null, null, 4f * (1 + increasedArmourDebuffDuration), null, "blood splatter armour reduction");
                }
            }
            else
            {
                if (armourReductionStacks)
                {
                    component.addDebuffToList(Tags.Properties.Armour, armourReduction, 0f, null, null, 4f * (1 + increasedArmourDebuffDuration));
                }
                else
                {
                    component.addDebuffToList(Tags.Properties.Armour, armourReduction, 0f, null, null, 4f * (1 + increasedArmourDebuffDuration), null, "blood splatter armour reduction");
                }
            }
        }

        if (minionBuffs != null && minionBuffs.Count > 0)
        {
            string        buffName  = "blood splatter buff";
            BuffOnAllyHit component = abilityObject.AddComponent <BuffOnAllyHit>();
            component.onlyApplyToCreatorsMinions = true;
            for (int i = 0; i < minionBuffs.Count; i++)
            {
                string fullBuffName = buffName + minionBuffs[i].property;
                foreach (Tags.AbilityTags _tag in minionBuffs[i].tagList)
                {
                    fullBuffName += _tag;
                }
                component.addBuffToList(minionBuffs[i].property, minionBuffs[i].addedValue, minionBuffs[i].increasedValue, minionBuffs[i].moreValues,
                                        minionBuffs[i].quotientValues, 4f, minionBuffs[i].tagList, fullBuffName);
            }
        }


        if (increasedStunChance != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.baseDamageStats.increasedStunChance += increasedStunChance;
            }
        }


        // increase damage based on the number of minions
        float realIncreasedDamage = increasedDamage;

        if (increasedDamagePerMinion != 0)
        {
            if (references && references.creator)
            {
                SummonTracker tracker = references.creator.GetComponent <SummonTracker>();
                if (tracker && tracker.summons != null)
                {
                    realIncreasedDamage += increasedDamagePerMinion * tracker.summons.Count;
                }
            }
        }


        if (realIncreasedDamage != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(realIncreasedDamage);
            }
        }

        if (moreDamageInstances != null && moreDamageInstances.Count > 0)
        {
            float moreDamage = 1f;
            foreach (float instance in moreDamageInstances)
            {
                moreDamage *= 1 + instance;
            }

            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(moreDamage - 1);
            }
        }

        return(abilityObject);
    }