示例#1
0
    public void beginDestruction()
    {
        DestroyAfterDuration destroyAfterDuration = GetComponent <DestroyAfterDuration>();

        if (destroyAfterDuration == null)
        {
            destroyAfterDuration          = gameObject.AddComponent <DestroyAfterDuration>();
            destroyAfterDuration.duration = duration;
        }
        if (destroyAfterDuration.duration > duration)
        {
            destroyAfterDuration.duration = duration;
        }
    }
 // Update is called once per frame
 void Update()
 {
     if (destroyer == null)
     {
         destroyer = GetComponent <DestroyAfterDuration>();
     }
     else
     {
         if (!faded && destroyer.duration - destroyer.age < 2)
         {
             faded = true;
             changeParam(change);
         }
     }
 }
 // Update is called once per frame
 void Update()
 {
     if (destroyer == null)
     {
         destroyer = GetComponent <DestroyAfterDuration>();
     }
     else
     {
         if (!faded && destroyer.duration - destroyer.age < 2)
         {
             faded = true;
             RecursivelyAttachFaders(transform);
         }
     }
 }
示例#4
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        ShieldRushEndMutator mutator = abilityObject.AddComponent <ShieldRushEndMutator>();

        mutator.increasedDamage         = increasedDamage;
        mutator.increasedRadius         = increasedRadius;
        mutator.timeRotChance           = timeRotChance;
        mutator.increasesDamageTaken    = increasesDamageTaken;
        mutator.increasesDoTDamageTaken = increasesDoTDamageTaken;
        mutator.increasedStunChance     = increasedStunChance;
        mutator.addedCritMultiplier     = addedCritMultiplier;
        mutator.addedCritChance         = addedCritChance;
        mutator.leaveDelayed            = leaveDelayed;
        mutator.addedVoidDamage         = addedVoidDamage;

        if (increasedDelayLength != 0)
        {
            DestroyAfterDuration component = abilityObject.GetComponent <DestroyAfterDuration>();
            if (component)
            {
                component.duration *= (1 + increasedDelayLength);
            }
        }


        if (increasedRadius > 0)
        {
            foreach (CreateOnDeath cod in abilityObject.GetComponents <CreateOnDeath>())
            {
                cod.increasedRadius = increasedRadius;
                cod.increasedHeight = increasedRadius;
            }
        }

        return(abilityObject);
    }
示例#5
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (additionalDuration > 0)
        {
            DestroyAfterDuration durationObject = abilityObject.GetComponent <DestroyAfterDuration>();
            if (durationObject != null)
            {
                durationObject.duration += additionalDuration;
            }
        }

        // increase the strength of the pull
        if (pullMultiplier != 1)
        {
            RepeatedlyPullEnemiesWithinRadius pull = abilityObject.GetComponent <RepeatedlyPullEnemiesWithinRadius>();
            if (pull)
            {
                pull.distanceMultiplier = 1 - (1 - pull.distanceMultiplier) * pullMultiplier;
            }
        }

        if (increasedBasePhysicalDamage > 0)
        {
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.addBaseDamage(DamageType.PHYSICAL, damage.getBaseDamage(DamageType.PHYSICAL) * increasedBasePhysicalDamage);
            }
        }

        if (fireTornado)
        {
            // change the vfx
            foreach (Transform t in abilityObject.transform)
            {
                if (t.name == "TornadoVFX")
                {
                    t.gameObject.SetActive(false);
                }
                if (t.name == "Tornado_Fire")
                {
                    t.gameObject.SetActive(true);
                }
            }
            // change the damage to fire
            foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>())
            {
                damage.addBaseDamage(DamageType.FIRE, damage.getBaseDamage(DamageType.PHYSICAL));
                damage.addBaseDamage(DamageType.PHYSICAL, -damage.getBaseDamage(DamageType.PHYSICAL));
            }
        }

        if (castsLightning)
        {
            RepeatedlyCastAtNearestEnemyWithinRadius cast = abilityObject.AddComponent <RepeatedlyCastAtNearestEnemyWithinRadius>();
            cast.abilityToCast = AbilityIDList.getAbility(AbilityID.lesserLightning);
            cast.castInterval  = lightningInterval;
            cast.radius        = lightningRange;
        }

        if (stationary)
        {
            abilityObject.GetComponent <UnityEngine.AI.NavMeshAgent>().speed = 0f;
            Destroy(abilityObject.GetComponent <RandomNavmeshMovement>());
        }

        if (attaches)
        {
            Destroy(abilityObject.GetComponent <UnityEngine.AI.NavMeshAgent>());
            Destroy(abilityObject.GetComponent <RandomNavmeshMovement>());
            AttachToCreatorOnCreation component = abilityObject.AddComponent <AttachToCreatorOnCreation>();
            component.replaceExistingBuff = false;
            component.displacement        = new Vector3(0, 1f, 0);
        }

        if (leavesStormOrbs)
        {
            CastAtRandomPointAfterDuration cast = abilityObject.AddComponent <CastAtRandomPointAfterDuration>();
            cast.ability    = Ability.getAbility(AbilityID.delayedStormOrb);
            cast.duration   = 1f / (1 + increasedStormOrbFrequency);
            cast.radius     = 0.5f;
            cast.limitCasts = false;
        }

        if (ignitesInAoe)
        {
            CastAfterDuration cad = abilityObject.AddComponent <CastAfterDuration>();
            cad.ability    = Ability.getAbility(AbilityID.invisibleIgniteNova);
            cad.interval   = 1f / (1 + increasedIgniteFrequency);
            cad.limitCasts = false;
        }

        if (movementSpeedOnCast != 0 || manaRegenOnCast != 0 || attackAndCastSpeedOnCast != 0)
        {
            float buffDuration = 2f * (1 + increasedBuffDuration);
            if (movementSpeedOnCast != 0)
            {
                statBuffs.addBuff(buffDuration, Tags.Properties.Movespeed, 0, movementSpeedOnCast, null, null, null, "tornadoMovementSpeed");
            }
            if (manaRegenOnCast != 0)
            {
                statBuffs.addBuff(buffDuration, Tags.Properties.ManaRegen, 0, manaRegenOnCast, null, null, null, "tornadoManaRegen");
            }
            if (attackAndCastSpeedOnCast != 0)
            {
                statBuffs.addBuff(buffDuration, Tags.Properties.AttackSpeed, 0, attackAndCastSpeedOnCast, null, null, null, "tornadoAttackSpeed");
                statBuffs.addBuff(buffDuration, Tags.Properties.CastSpeed, 0, attackAndCastSpeedOnCast, null, null, null, "tornadoCastSpeed");
            }
        }

        return(abilityObject);
    }
示例#6
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // add additional duration
        if (additionalDuration != 0)
        {
            DestroyAfterDuration durationObject = abilityObject.GetComponent <DestroyAfterDuration>();
            if (durationObject != null)
            {
                durationObject.duration += additionalDuration;
            }
        }

        // add additional ward regen
        if (additionalWardRegen > 0)
        {
            BuffParent protectionObject = abilityObject.GetComponent <BuffParent>();
            if (protectionObject != null)
            {
                protectionObject.wardRegen += additionalWardRegen;
            }
        }

        // add additional elemental protection
        if (additionalElementalProtection != 0 || igniteChanceGranted != 0 || grantsColdDamage || grantsLightningDamage)
        {
            BuffParent protectionObject = abilityObject.GetComponent <BuffParent>();
            if (protectionObject != null)
            {
                if (additionalElementalProtection != 0)
                {
                    TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.FireProtection, new List <Tags.AbilityTags>());
                    stat.addedValue = additionalElementalProtection;
                    protectionObject.taggedStats.Add(stat);
                    TaggedStatsHolder.TaggableStat stat2 = new TaggedStatsHolder.TaggableStat(Tags.Properties.ColdProtection, new List <Tags.AbilityTags>());
                    stat2.addedValue = additionalElementalProtection;
                    protectionObject.taggedStats.Add(stat2);
                    TaggedStatsHolder.TaggableStat stat3 = new TaggedStatsHolder.TaggableStat(Tags.Properties.LightningProtection, new List <Tags.AbilityTags>());
                    stat3.addedValue = additionalElementalProtection;
                    protectionObject.taggedStats.Add(stat3);
                }
                if (igniteChanceGranted != 0)
                {
                    TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.IgniteChance, new List <Tags.AbilityTags>());
                    stat.addedValue = igniteChanceGranted;
                    protectionObject.taggedStats.Add(stat);
                }
                if (grantsColdDamage)
                {
                    List <Tags.AbilityTags> tagList = new List <Tags.AbilityTags>();
                    tagList.Add(Tags.AbilityTags.Cold);
                    TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.Damage, tagList);
                    stat.increasedValue = 0.4f;
                    protectionObject.taggedStats.Add(stat);
                }
                if (grantsLightningDamage)
                {
                    List <Tags.AbilityTags> tagList = new List <Tags.AbilityTags>();
                    tagList.Add(Tags.AbilityTags.Lightning);
                    TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.Damage, tagList);
                    stat.increasedValue = 0.4f;
                    protectionObject.taggedStats.Add(stat);
                }
            }
        }

        // allow casting on allies
        if (canCastOnAllies)
        {
            abilityObject.GetComponent <AttachToCreatorOnCreation>().runOnCreation = false;
            abilityObject.AddComponent <AttachToNearestAllyOnCreation>();
            abilityObject.AddComponent <StartsAtTarget>();
        }

        // set damage threshold
        if (abilityObject.GetComponent <RetaliateWhenParentHit>())
        {
            abilityObject.GetComponent <RetaliateWhenParentHit>().damageTakenTrigger = (int)damageThreshold;
        }

        // aoe damage
        if (aoeDamage != 0)
        {
            RepeatedlyDamageEnemiesWithinRadius repeatDamage = abilityObject.GetComponent <RepeatedlyDamageEnemiesWithinRadius>();
            if (repeatDamage == null)
            {
                repeatDamage = abilityObject.AddComponent <RepeatedlyDamageEnemiesWithinRadius>();
            }
            if (repeatDamage.baseDamageStats.damage == null)
            {
                repeatDamage.baseDamageStats.damage = new List <DamageStatsHolder.DamageTypesAndValues>();
            }
            repeatDamage.baseDamageStats.damage.Add(new DamageStatsHolder.DamageTypesAndValues(DamageType.FIRE, aoeDamage));
            repeatDamage.damageInterval = 0.33f;
            repeatDamage.radius         = aoeRadius;
            repeatDamage.baseDamageStats.addedDamageScaling = 0.17f;
            repeatDamage.tags.Add(Tags.AbilityTags.AoE);
            repeatDamage.tags.Add(Tags.AbilityTags.Spell);
            repeatDamage.tags.Add(Tags.AbilityTags.DoT);
            foreach (Transform child in abilityObject.transform)
            {
                if (child.name == "Circle")
                {
                    child.gameObject.SetActive(true);
                    child.transform.localScale = new Vector3(1.3f * aoeRadius / 3.5f, 1, 1.3f * aoeRadius / 3.5f);
                }
            }
        }

        // igniting
        if (ignitesInAoe)
        {
            CastAfterDuration cad = abilityObject.AddComponent <CastAfterDuration>();
            cad.ability = AbilityIDList.getAbility(AbilityID.invisibleIgniteNova);
            if (increasedIgniteFrequency != 0)
            {
                if (increasedIgniteFrequency >= 0.9f)
                {
                    increasedIgniteFrequency = 0.9f;
                }
                cad.interval /= (1 + increasedIgniteFrequency);
            }
        }

        // mutating fireball
        if (fireballIgniteChance != 0 || fireballPierces || increasedFireballDamage != 0)
        {
            FireballMutator fireballMutator = abilityObject.AddComponent <FireballMutator>();
            fireballMutator.increasedDamage = increasedFireballDamage;
            fireballMutator.igniteChance    = fireballIgniteChance;
            if (fireballPierces)
            {
                fireballMutator.targetsToPierce += 1000;
            }
        }

        return(abilityObject);
    }
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // changing the repeated hit mutator
        if (increasedDamage != 0 || addedPoisonDamage != 0 || increasedRadius != 0)
        {
            EntanglingRootsHitMutator hitMutator = abilityObject.AddComponent <EntanglingRootsHitMutator>();
            hitMutator.increasedDamage   = increasedDamage;
            hitMutator.addedPoisonDamage = addedPoisonDamage;
            hitMutator.increasedRadius   = increasedRadius;
        }

        // create the initial hit
        CastInLine initialiHitCreator = abilityObject.AddComponent <CastInLine>();

        initialiHitCreator.ability         = AbilityIDList.getAbility(AbilityID.entanglingRootsInitialHit);
        initialiHitCreator.casts           = 1;
        initialiHitCreator.distancePerCast = 0;
        initialiHitCreator.targetPoint     = targetLocation;

        // changing the initial hit mutator
        EntanglingRootsInitialHitMutator initialHitMutator = abilityObject.AddComponent <EntanglingRootsInitialHitMutator>();

        initialHitMutator.increasedDamage        = initialHitIncreasedDamage;
        initialHitMutator.chanceToPoison         = initialHitChanceToPoison;
        initialHitMutator.increasedRadius        = increasedRadius;
        initialHitMutator.increasedBuffDuration  = increasedBuffDuration;
        initialHitMutator.damageBuff             = damageBuff;
        initialHitMutator.poisonChanceToWolves   = poisonChanceToWolves;
        initialHitMutator.bleedchanceToBears     = bleedchanceToBears;
        initialHitMutator.castSpeedToSpriggans   = castSpeedToSpriggans;
        initialHitMutator.healSpriggans          = healSpriggans;
        initialHitMutator.meleeScalingInitialHit = meleeScalingInitialHit;
        initialHitMutator.alwaysStuns            = InitialHitAlwaysStuns;

        // creating extra patches
        if (addedPatches > 0)
        {
            // add extra casts
            if (patchesInLine)
            {
                CastInLine component = abilityObject.AddComponent <CastInLine>();
                component.ability         = AbilityIDList.getAbility(AbilityID.entanglingRoots);
                component.casts           = addedPatches;
                component.distancePerCast = 4;
                component.targetPoint     = targetLocation;
            }
            else
            {
                CastAtRandomPointAfterDuration component = abilityObject.AddComponent <CastAtRandomPointAfterDuration>();
                component.ability        = AbilityIDList.getAbility(AbilityID.entanglingRoots);
                component.duration       = 0.01f;
                component.limitCasts     = true;
                component.remainingCasts = addedPatches;
                component.radius         = 5f;
            }
            // copy mutator
            EntanglingRootsMutator mutator = abilityObject.AddComponent <EntanglingRootsMutator>();
            mutator.increasedDamage           = increasedDamage;
            mutator.addedPoisonDamage         = addedPoisonDamage;
            mutator.increasedRadius           = increasedRadius;
            mutator.initialHitIncreasedDamage = initialHitIncreasedDamage;
            mutator.initialHitChanceToPoison  = initialHitChanceToPoison;
            mutator.increasedBuffDuration     = increasedBuffDuration;
            mutator.damageBuff             = damageBuff;
            mutator.poisonChanceToWolves   = poisonChanceToWolves;
            mutator.bleedchanceToBears     = bleedchanceToBears;
            mutator.castSpeedToSpriggans   = castSpeedToSpriggans;
            mutator.healSpriggans          = healSpriggans;
            mutator.meleeScalingInitialHit = meleeScalingInitialHit;
            mutator.InitialHitAlwaysStuns  = InitialHitAlwaysStuns;
            mutator.increasedDuration      = increasedDuration;
            mutator.healingNovaChance      = healingNovaChance;
        }

        if (increasedDuration != 0)
        {
            DestroyAfterDuration dad = abilityObject.GetComponent <DestroyAfterDuration>();
            if (dad)
            {
                dad.duration *= (1 + increasedDuration);
            }
        }

        if (increasedRadius != 0)
        {
            foreach (MagicalFX.FX_Tentacle_ultimate vfx in abilityObject.GetComponentsInChildren <MagicalFX.FX_Tentacle_ultimate>())
            {
                vfx.SpreadMin   *= (1 + increasedRadius);
                vfx.SpreadMax   *= (1 + increasedRadius);
                vfx.SpreadSpawn *= (1 + increasedRadius);
                vfx.Number       = (int)(((float)vfx.Number) * (1 + increasedRadius));
            }
        }

        if (healingNovaChance > 0)
        {
            float rand = Random.Range(0f, 1f);
            if (rand < healingNovaChance)
            {
                CreateAbilityObjectOnDeath component = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
                component.abilityToInstantiate = AbilityIDList.getAbility(AbilityID.healingNova);
            }
        }

        return(abilityObject);
    }
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (noChain)
        {
            CreateAbilityObjectOnNewEnemtHit component = abilityObject.GetComponent <CreateAbilityObjectOnNewEnemtHit>();
            if (component)
            {
                component.active = false;
            }
        }

        if (pullsOnHit)
        {
            DestroyAfterDuration dad = abilityObject.GetComponent <DestroyAfterDuration>();
            if (dad)
            {
                dad.duration = 0.1f;
            }
            RepeatedlyPullEnemiesWithinRadius component = abilityObject.AddComponent <RepeatedlyPullEnemiesWithinRadius>();
            component.distanceMultiplier = 0.92f / (1 + increasedPullStrength);
            component.limitDistanceToMax = false;
            component.interval           = 0.02f;
            component.radius             = 4f * (1 + increasedRadius);
        }

        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 (increasedDamage != 0)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.increaseAllDamage(increasedDamage);
            }
        }

        if (stacks)
        {
            ApplyStatusOnEnemyHit component = abilityObject.GetComponent <ApplyStatusOnEnemyHit>();
            component.statusEffect = StatusEffectList.getEffect(StatusEffectID.StackingAbyssalDecay);
        }

        if (speedDebuff != 0 || armourDebuff != 0 || dotTakenDebuff != 0)
        {
            DebuffOnEnemyHit component = Comp <DebuffOnEnemyHit> .GetOrAdd(abilityObject);

            if (speedDebuff != 0)
            {
                List <float> speedDebuffList = new List <float>();
                speedDebuffList.Add(speedDebuff * (1 + increasedDebuffStrength));
                component.addDebuffToList(Tags.Properties.AttackSpeed, 0f, 0f, speedDebuffList, null, 4f * (1 + increasedDebuffDuration), null, "AbyssalEchoesDebuffAttackSpeed");
                component.addDebuffToList(Tags.Properties.CastSpeed, 0f, 0f, speedDebuffList, null, 4f * (1 + increasedDebuffDuration), null, "AbyssalEchoesDebuffCastSpeed");
                component.addDebuffToList(Tags.Properties.Movespeed, 0f, 0f, speedDebuffList, null, 4f * (1 + increasedDebuffDuration), null, "AbyssalEchoesDebuffMoveSpeed");
            }
            if (armourDebuff != 0)
            {
                component.addDebuffToList(Tags.Properties.Movespeed, armourDebuff * (1 + increasedDebuffStrength), 0f, null, null, 4f * (1 + increasedDebuffDuration), null, "AbyssalEchoesDebuffArmour");
            }
            if (dotTakenDebuff != 0)
            {
                if (dotTakenDebuffStacks)
                {
                    component.addDebuffToList(Tags.Properties.DamageTaken, 0f, -dotTakenDebuff, null, null, 4f);
                }
                else
                {
                    component.addDebuffToList(Tags.Properties.DamageTaken, 0f, -dotTakenDebuff, null, null, 4f, null, "AbyssalEchoesDebuffDoTTaken");
                }
            }
        }

        return(abilityObject);
    }
示例#9
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // get a reference to the child's SummonEntityOnDeath component, this the component that makes the wolf
        SummonEntityOnDeath summoner = abilityObject.GetComponent <SummonEntityOnDeath>();

        // add additional stats
        summoner.statList.AddRange(statList);

        // crit on cast buff
        if (critFromManaCost && mana && statBuffs)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.CriticalChance, null);
            stat.increasedValue = mana.getManaCost(ability) * 0.01f;

            statBuffs.addTaggedBuff(new TaggedBuff(stat, 4f, "Summon wraith mana crit"));
        }

        // add corpse consumption stats
        bool corpseConsumed = false;

        if (corpseStatList != null && corpseStatList.Count > 0 && health && health.alignmentManager && health.alignmentManager.alignment != null)
        {
            float closestDistance = float.MaxValue;
            Dying closestDying    = null;
            float distance        = 0f;

            // check all corpses to find the closest
            foreach (Dying dying in Dying.all)
            {
                // check that the entity is dying and is an enemy
                if (dying.isDying() && dying.myHealth && dying.myHealth.alignmentManager && health.alignmentManager.alignment.foes.Contains(dying.myHealth.alignmentManager.alignment))
                {
                    // find the distance
                    distance = Maths.manhattanDistance(dying.transform.position, targetLocation);
                    // don't consume very distant corpses
                    if (distance <= 8f)
                    {
                        // if a closest one hasn't been found yet this is the closest
                        if (closestDying == null)
                        {
                            closestDying    = dying;
                            closestDistance = distance;
                        }
                        // otherwise compare distances
                        else
                        {
                            if (distance < closestDistance)
                            {
                                closestDying    = dying;
                                closestDistance = distance;
                            }
                        }
                    }
                }
            }

            // consume the closest corpse
            if (closestDying)
            {
                closestDying.setDelays(0f, 0f);
                corpseConsumed = true;
                // apply the stats
                summoner.statList.AddRange(corpseStatList);
                // create a death vfx
                Instantiate(spiritEscapePrefab).transform.position = closestDying.transform.position + spiritEscapeOffset;
            }
        }



        float realBloodWraithChance = 0f;

        if (corpseConsumed)
        {
            realBloodWraithChance = bloodWraithChance;
        }
        // summon a different type of wraith
        if (flameWraithChance != 0 || realBloodWraithChance != 0 || putridWraithChance != 0)
        {
            float rand = Random.Range(0f, 1f);
            if (rand < flameWraithChance)
            {
                summoner.entity = flameWraithPrefab;
            }
            else if (rand < flameWraithChance + realBloodWraithChance)
            {
                summoner.entity = bloodWraithPrefab;
            }
            else if (rand < flameWraithChance + realBloodWraithChance + putridWraithChance)
            {
                summoner.entity = putridWraithPrefab;
            }
        }

        if (targetting == WraithTargetType.onSpot)
        {
            StartsTowardsTarget component = abilityObject.GetComponent <StartsTowardsTarget>();
            if (component)
            {
                component.active = false;
            }

            if (summoner)
            {
                summoner.distance = 0.5f;
            }
        }

        if (targetting == WraithTargetType.atTarget)
        {
            StartsTowardsTarget component = abilityObject.GetComponent <StartsTowardsTarget>();
            if (component)
            {
                component.active = false;
            }

            abilityObject.AddComponent <StartsAtTarget>();
        }

        // delayed wraith casts
        if (delayedWraiths > 0)
        {
            CastAfterDuration cad = abilityObject.AddComponent <CastAfterDuration>();
            cad.ability        = ability;
            cad.interval       = 0.5f * (1 - reducedWraithInterval);
            cad.limitCasts     = true;
            cad.remainingCasts = delayedWraiths;

            DestroyAfterDuration dad = abilityObject.GetComponent <DestroyAfterDuration>();
            dad.duration = (0.5f * (1 + delayedWraiths)) * (1f - reducedWraithInterval);


            SummonWraithMutator mutator = abilityObject.AddComponent <SummonWraithMutator>();

            // copy stats
            mutator.reducedHealthDrain = reducedHealthDrain;
            mutator.stationary         = stationary;
            mutator.flameWraithChance  = flameWraithChance;
            mutator.bloodWraithChance  = realBloodWraithChance;
            mutator.putridWraithChance = putridWraithChance;

            // wraith prefabs
            mutator.flameWraithPrefab  = flameWraithPrefab;
            mutator.bloodWraithPrefab  = bloodWraithPrefab;
            mutator.putridWraithPrefab = putridWraithPrefab;

            // delayed wraith changes
            mutator.targetting            = WraithTargetType.onSpot;
            mutator.delayedWraiths        = 0;
            mutator.reducedWraithInterval = 0f;
            mutator.critFromManaCost      = false;
            mutator.healOnCrit            = 0f;

            // stats and corpse stats (does not consume multiple corpses)
            mutator.statList.AddRange(statList);
            if (corpseConsumed)
            {
                mutator.statList.AddRange(corpseStatList);
            }
        }

        // change the adapter
        WraithAdapter adapter = abilityObject.AddComponent <WraithAdapter>();

        adapter.reducedHealthDrain = reducedHealthDrain;
        adapter.stationary         = stationary;

        return(abilityObject);
    }
示例#10
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        BuffParent buffObject = abilityObject.GetComponent <BuffParent>();

        // add additional duration
        if (additionalDuration != 0)
        {
            DestroyAfterDuration durationObject = abilityObject.GetComponent <DestroyAfterDuration>();
            if (durationObject != null)
            {
                durationObject.duration += additionalDuration;
            }
        }

        // add additional block chance
        if (additionalBlockChance > 0)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.BlockChance, new List <Tags.AbilityTags>());
            stat.addedValue = additionalBlockChance;
            buffObject.taggedStats.Add(stat);
        }

        // add additional block protections
        if (additionalBlockElementalProtection != 0)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.BlockFireProtection, new List <Tags.AbilityTags>());
            stat.addedValue = additionalBlockElementalProtection;
            buffObject.taggedStats.Add(stat);
            TaggedStatsHolder.TaggableStat stat2 = new TaggedStatsHolder.TaggableStat(Tags.Properties.BlockColdProtection, new List <Tags.AbilityTags>());
            stat2.addedValue = additionalBlockElementalProtection;
            buffObject.taggedStats.Add(stat2);
            TaggedStatsHolder.TaggableStat stat3 = new TaggedStatsHolder.TaggableStat(Tags.Properties.BlockLightningProtection, new List <Tags.AbilityTags>());
            stat3.addedValue = additionalBlockElementalProtection;
            buffObject.taggedStats.Add(stat3);
        }

        // add additional block armour
        if (additionalBlockArmour != 0)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.BlockArmor, new List <Tags.AbilityTags>());
            stat.addedValue = additionalBlockArmour;
            buffObject.taggedStats.Add(stat);
        }

        // add additional armour
        if (additionalArmour != 0)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.Armour, new List <Tags.AbilityTags>());
            stat.addedValue = additionalArmour;
            buffObject.taggedStats.Add(stat);
        }

        // allow casting on allies
        if (canCastOnAllies)
        {
            abilityObject.GetComponent <AttachToCreatorOnCreation>().runOnCreation = false;
            abilityObject.AddComponent <AttachToNearestAllyOnCreation>();
            abilityObject.AddComponent <StartsAtTarget>();
        }

        //adds ward gain on block
        if (wardOnBlock > 0)
        {
            List <Tags.AbilityTags> onBlock = new List <Tags.AbilityTags> ();
            onBlock.Add(Tags.AbilityTags.Block);
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.WardGain, onBlock);
            stat.addedValue = wardOnBlock;
            buffObject.taggedStats.Add(stat);
        }

        // ensure that reduced mana penalty is not greater than 1
        float newReducedManaPenalty = reducedManaPenalty;

        if (newReducedManaPenalty > 1)
        {
            newReducedManaPenalty = 1;
        }
        // reduced mana penalties
        if (reducedManaPenalty != 0)
        {
            // reduce the "less" penalty intrinsic to the skill
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.ManaDrain, new List <Tags.AbilityTags>());
            // reducing a 20% less penalty by 40% is the same as adding a 10% more multiplier
            stat.moreValues.Add(-newReducedManaPenalty);
            buffObject.taggedStats.Add(stat);
        }

        // add reduced mana regen (after being altered by reduced mana penalties)
        if (extraManaDrain != 0)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.ManaDrain, new List <Tags.AbilityTags>());
            stat.addedValue = extraManaDrain;
            buffObject.taggedStats.Add(stat);
        }

        // add ward retention
        if (additionalWardRetention != 0)
        {
            TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.WardRetention, new List <Tags.AbilityTags>());
            stat.addedValue = additionalWardRetention;
            buffObject.taggedStats.Add(stat);
        }

        // ice nova
        if (castsFrostNova)
        {
            CastAfterDuration cad = abilityObject.AddComponent <CastAfterDuration>();
            cad.limitCasts = false;
            cad.interval   = 3f / (1 + increasedFrostNovaFrequency);
            cad.ability    = AbilityIDList.getAbility(AbilityID.frostNova);

            FrostNovaMutator novaMutator = abilityObject.AddComponent <FrostNovaMutator>();
            novaMutator.increasedDamage     = novaDamage;
            novaMutator.addedCritChance     = novaCritChance;
            novaMutator.addedCritMultiplier = novaCritMulti;
        }

        // add additional ward regen
        if (additionalWardRegen > 0)
        {
            BuffParent protectionObject = abilityObject.GetComponent <BuffParent>();
            if (protectionObject != null)
            {
                protectionObject.wardRegen += additionalWardRegen;
            }
        }

        return(abilityObject);
    }
    public void Summon()
    {
        for (int i = 0; i < numberToSummon; i++)
        {
            // get a reference to this objects creation references
            CreationReferences myReferences = GetComponent <CreationReferences>();

            // remove previous summons if necessary
            if (limitNumber && myReferences && attachCreationReferences && entity.GetComponent <Prefabs>())
            {
                abilitiesThatCountForLimit.Add(myReferences.thisAbility);
                List <GameObject> existingSummons = new List <GameObject>();
                foreach (Summoned summoned in Summoned.all)
                {
                    if (abilitiesThatCountForLimit.Contains(summoned.references.thisAbility))
                    {
                        if (summoned.references.creator = myReferences.creator)
                        {
                            existingSummons.Add(summoned.gameObject);
                        }
                    }
                }

                // components for removing summons
                SelfDestroyer selfDestroyer = null;
                Dying         dying         = null;

                while (existingSummons.Count >= limit)
                {
                    GameObject SummonToKill = getLowestPriority(existingSummons);
                    existingSummons.Remove(SummonToKill);

                    selfDestroyer = SummonToKill.GetComponent <SelfDestroyer>();
                    dying         = SummonToKill.GetComponent <Dying>();

                    // death events
                    if (dying && dying.getController())
                    {
                        dying.unsummoned = true;
                        dying.die();
                    }

                    // self destroyer events
                    if (selfDestroyer)
                    {
                        selfDestroyer.die();
                    }

                    // if neither exist, resort to destroying the game object
                    if (!dying && !selfDestroyer)
                    {
                        Destroy(SummonToKill);
                    }
                }
            }

            // decide the position
            Vector3 pos = displacement;
            if (distance > 0)
            {
                float angle = Random.Range(0, Mathf.PI * 2);
                pos = new Vector3(distance * Mathf.Cos(angle), displacement.y, distance * Mathf.Sin(angle));
            }

            pos = transform.position + pos;
            pos = new Vector3(pos.x, getY(pos), pos.z);

            // create the entity
            GameObject summon = Instantiate(entity, pos, Quaternion.Euler(0, 0, 0));

            // adapt the entity
            foreach (EntityAdapter adapter in GetComponents <EntityAdapter>())
            {
                summon = adapter.adapt(summon);
            }

            // attach creation references if necessary, if not then update them
            CreationReferences references = null;
            if (attachCreationReferences && myReferences != null)
            {
                if (!summon.GetComponent <CreationReferences>())
                {
                    references = summon.AddComponent <CreationReferences>();
                }
                else
                {
                    references = summon.GetComponent <CreationReferences>();
                }
                references.creator     = myReferences.creator;
                references.thisAbility = myReferences.thisAbility;
            }

            // add a summoned component
            Summoned summonedComponent = summon.AddComponent <Summoned>();
            summonedComponent.singeCardForAllMinions = singeCardForAllMinions;

            // initialise the summoned component
            summonedComponent.references = references;
            summonedComponent.initialise();

            //adds recent events tracker
            summon.AddComponent <CharacterStatusTracker>();

            // get a reference to the minion's stats
            BaseStats stats = summon.GetComponent <BaseStats>();

            // give it damage bonuses based on a tagged stats holder
            if (GetComponent <TaggedStatsHolder>() && stats)
            {
                TaggedStatsHolder holder = GetComponent <TaggedStatsHolder>();
                foreach (TaggedStatsHolder.TaggableStat ts in holder.taggedStats)
                {
                    List <Tags.AbilityTags> newTagList = new List <Tags.AbilityTags>();
                    newTagList.AddRange(ts.tagList);
                    if (newTagList.Contains(Tags.AbilityTags.Minion))
                    {
                        newTagList.Remove(Tags.AbilityTags.Minion);

                        stats.ChangeStatModifier(ts.property, ts.addedValue, BaseStats.ModType.ADDED, newTagList);
                        stats.ChangeStatModifier(ts.property, ts.increasedValue, BaseStats.ModType.INCREASED, newTagList);
                        foreach (float value in ts.moreValues)
                        {
                            stats.ChangeStatModifier(ts.property, value, BaseStats.ModType.MORE, newTagList);
                        }
                        foreach (float value in ts.quotientValues)
                        {
                            stats.ChangeStatModifier(ts.property, value, BaseStats.ModType.QUOTIENT, newTagList);
                        }
                    }
                }
            }

            // make it follow the creator if necessary
            if (followsCreator)
            {
                if (GetComponent <CreationReferences>())
                {
                    // if no follow ranges have been defined then use the defaults
                    if (followRangesAndPriorities.Count <= 0)
                    {
                        summon.AddComponent <Following>().leader = myReferences.creator;
                    }
                    // otherwise create follow states for each entry in the list
                    Following following;
                    foreach (FollowRangeAndPriority frar in followRangesAndPriorities)
                    {
                        following        = summon.AddComponent <Following>();
                        following.leader = myReferences.creator;
                        following.startFollowingRange = frar.range;
                        following.priority            = frar.priority;
                    }
                }
            }

            // make it move away from the creator when close if necessary
            if (movesAwayFromSummonerWhenClose)
            {
                if (myReferences)
                {
                    summon.AddComponent <MovingAwayFromSummoner>().summoner = myReferences.creator;
                }
            }

            // if necessary limit the duration by adding a destroy after duration component
            if (limitDuration)
            {
                // use a self destroyer if it has ones, otherwise use the dying state
                if (summon.GetComponent <SelfDestroyer>())
                {
                    DestroyAfterDuration destroyer = summon.AddComponent <DestroyAfterDuration>();
                    destroyer.duration = duration;
                }
                else
                {
                    DieAfterDelay destroyer = null;
                    if (!summon.GetComponent <DieAfterDelay>())
                    {
                        destroyer = summon.AddComponent <DieAfterDelay>();
                        destroyer.timeUntilDeath = duration;
                    }
                    // if there is already a destroy after duration component, lower the duration if this component's duration is lower than the one already there
                    else
                    {
                        destroyer = summon.GetComponent <DieAfterDelay>();
                        destroyer.timeUntilDeath = Mathf.Min(destroyer.timeUntilDeath, duration);
                    }
                    // make the destroyer unsummon rather than kill
                    if (destroyer)
                    {
                        destroyer.countsAsUnsummoned = true;
                    }
                }
            }

            // pass on alignment if necessary, may require an alignment manager to be added to the entity
            if (passOnAlignment && GetComponent <AlignmentManager>())
            {
                AlignmentManager alignmentManager = null;
                if (!summon.GetComponent <AlignmentManager>())
                {
                    alignmentManager = summon.AddComponent <AlignmentManager>();
                }
                else
                {
                    alignmentManager = summon.GetComponent <AlignmentManager>();
                }
                alignmentManager.alignment = GetComponent <AlignmentManager>().alignment;
            }

            // give the entity a custom name if necessary, may require a display information component to be added to the entity
            if (giveCustomName && customNames.Count > 0)
            {
                DisplayInformation displayInformation = null;
                if (!summon.GetComponent <DisplayInformation>())
                {
                    displayInformation = summon.AddComponent <DisplayInformation>();
                }
                else
                {
                    displayInformation = summon.GetComponent <DisplayInformation>();
                }
                int nameIndex = Random.Range(0, customNames.Count);
                displayInformation.displayName = customNames[nameIndex];
            }

            // add stats
            if (statList != null && statList.Count > 0)
            {
                if (stats)
                {
                    foreach (TaggedStatsHolder.TaggableStat stat in statList)
                    {
                        stats.addStat(stat);
                    }
                    stats.UpdateStats();
                    stats.myHealth.currentHealth = stats.myHealth.maxHealth;
                }
            }

            // give the entity a custom tag if necessary
            if (giveCustomTag)
            {
                summon.tag = customTag;
            }

            if (stats)
            {
                stats.UpdateStats();
                if (stats.myHealth)
                {
                    stats.myHealth.currentHealth = stats.myHealth.maxHealth;
                }
            }

            // pass on this summon information to a summonChangeTracker
            SummonChangeTracker sct = summon.AddComponent <SummonChangeTracker>();
            sct.statList.AddRange(statList);
            sct.limitDuration = limitDuration;

            sct.followsCreator            = followsCreator;
            sct.followRangesAndPriorities = new List <FollowRangeAndPriority>();
            sct.followRangesAndPriorities.AddRange(followRangesAndPriorities);

            sct.limitDuration = limitDuration;
            sct.duration      = duration;
        }
    }
示例#12
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (increasedSpeed != 0)
        {
            AbilityMover component = abilityObject.GetComponent <AbilityMover>();
            if (component)
            {
                component.speed *= 1 + increasedSpeed;
            }
        }

        if (convertToCold)
        {
            foreach (Transform child in abilityObject.transform)
            {
                if (child.name == "VolcanicOrbVFX")
                {
                    child.gameObject.SetActive(false);
                }
                if (child.name == "FrozenOrbVFX")
                {
                    child.gameObject.SetActive(true);
                }
            }
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.addBaseDamage(DamageType.COLD, holder.getBaseDamage(DamageType.FIRE));
                holder.addBaseDamage(DamageType.FIRE, -holder.getBaseDamage(DamageType.FIRE));
            }
            foreach (CreateOnDeath cod in abilityObject.GetComponents <CreateOnDeath>())
            {
                cod.objectsToCreateOnDeath.Clear();
                //cod.objectsToCreateOnDeath.Add(new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("QuickIceCircleVFX")));
            }
        }

        ShrapnelMutator shrapMut = abilityObject.AddComponent <ShrapnelMutator>();

        shrapMut.increasedDamage          = increasedShrapnelDamage;
        shrapMut.increasedSpeed           = increasedShrapnelSpeed;
        shrapMut.increasedStunChance      = increasedShrapnelStunChance;
        shrapMut.convertToCold            = convertToCold;
        shrapMut.pierces                  = shrapnelPierces;
        shrapMut.chillChance              = chillChance;
        shrapMut.moreDamageInstances      = moreDamageInstances;
        shrapMut.moreDamageAgainstChilled = moreShrapnelDamageAgainstChilled;
        shrapMut.addedProjectiles         = addedShrapnelProjectiles;


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

        if (increasedDuration != 0 || baseDurationis2)
        {
            DestroyAfterDuration dad = abilityObject.GetComponent <DestroyAfterDuration>();
            if (dad)
            {
                if (baseDurationis2)
                {
                    dad.duration = 2f + (1f * increasedDuration);
                }
                else
                {
                    dad.duration *= (1f + increasedDuration);
                }
            }
        }

        if (leavesExplosion)
        {
            CreateAbilityObjectOnDeath component = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
            component.abilityToInstantiate = AbilityIDList.getAbility(AbilityID.fireCircle);
            component.offset = new Vector3(0f, -1f, 0f);

            FireCircleMutator circleMut = abilityObject.AddComponent <FireCircleMutator>();
            circleMut.chillChance     = chillChance;
            circleMut.convertToCold   = convertToCold;
            circleMut.igniteChance    = explosionIgniteChance;
            circleMut.increasedDamage = increasedExplosionDamage;
        }

        if (delayedExpolosionAtStart)
        {
            CastAfterDuration component = abilityObject.AddComponent <CastAfterDuration>();
            component.ability        = AbilityIDList.getAbility(AbilityID.delayedFireCircle);
            component.limitCasts     = true;
            component.remainingCasts = 1;
            component.age            = 10f;
            component.interval       = 1f;
            component.offset         = new Vector3(0f, -1.3f, 0f);

            DelayedFireCircleMutator circleMut = abilityObject.AddComponent <DelayedFireCircleMutator>();
            circleMut.chillChance     = chillChance;
            circleMut.convertToCold   = convertToCold;
            circleMut.igniteChance    = explosionIgniteChance;
            circleMut.increasedDamage = increasedExplosionDamage;
        }

        if (leavesExplosiveGround)
        {
            CastAfterDuration cad = abilityObject.AddComponent <CastAfterDuration>();
            if (convertToCold)
            {
                cad.ability = AbilityIDList.getAbility(AbilityID.shatteringGround);
            }
            else
            {
                cad.ability = AbilityIDList.getAbility(AbilityID.explosiveGround);
            }
            cad.limitCasts = false;
            cad.interval   = 0.79f / (1f + increasedExplosiveGroundFrequency);
            cad.age        = 0.6f / (1f + increasedExplosiveGroundFrequency);
        }

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


        return(abilityObject);
    }
示例#13
0
    private void OnCollisionEnter(Collision other)
    {
        if (validLayersForCollision.value == (validLayersForCollision.value | (1 << other.gameObject.layer)))
        {
            Debug.LogFormat(gameObject, "Collided with {0}", other.transform.GetHierarchyPath());

            DestroyAfterDuration destroyAfterDuration = other.collider.gameObject.GetComponent <DestroyAfterDuration>();
            if (destroyAfterDuration != null)
            {
                Destroy(destroyAfterDuration);
            }

            // Adding to bouleJaquot
            {
                GameObject jaquotOther            = GameObject.Instantiate(other.gameObject);
                Vector3    bigBallToOtherPosition = transform.InverseTransformDirection(other.rigidbody.position - transform.position);

                Vector3 bigBallToOtherUp      = transform.InverseTransformDirection(other.transform.up);
                Vector3 bigBallToOtherForward = transform.InverseTransformDirection(other.transform.forward);

                Destroy(jaquotOther.GetComponent <Rigidbody>());//.useGravity = false;
                //JaquotFakeGravity otherFakeGravitiy = jaquotOther.AddComponent<JaquotFakeGravity>();
                //otherFakeGravitiy.bouleJaquot = bouleJaquot.transform;
                //jaquotOther.transform.SetParent(bouleJaquot.transform);
                jaquotOther.transform.position   = bouleJaquot.position + bouleJaquot.transform.TransformDirection(bigBallToOtherPosition) / scaleRatioBigBallToJaquotBoule;
                jaquotOther.transform.rotation   = Quaternion.LookRotation(bouleJaquot.transform.TransformDirection(bigBallToOtherForward), bouleJaquot.transform.TransformDirection(bigBallToOtherUp));
                jaquotOther.transform.localScale = jaquotOther.transform.localScale / scaleRatioBigBallToJaquotBoule;

                jaquotOther.AddComponent <DestroyLinked>().linked = other.gameObject;
                other.collider.gameObject.AddComponent <DestroyLinked>().linked = jaquotOther;
            }

            // Sticking to Big Ball
            {
                Destroy(other.gameObject.GetComponent <Rigidbody>());
                other.transform.SetParent(transform);
                other.gameObject.layer = gameObject.layer;

                Vector3[] cubeCorners = new Vector3[]
                {
                    new Vector3(1, 1, 1),
                    new Vector3(1, 1, -1),
                    new Vector3(1, -1, 1),
                    new Vector3(1, -1, -1),
                    new Vector3(-1, 1, 1),
                    new Vector3(-1, 1, -1),
                    new Vector3(-1, -1, 1),
                    new Vector3(-1, -1, -1),
                };

/*                 float maxRadius = 0f;
 *              foreach (Vector3 cubeCorner in cubeCorners)
 *              {
 *                  Vector3 closestPoint = other.collider.ClosestPoint(1000f * cubeCorner);
 *                  float distToSmallBall = Vector3.Distance(smallBall.transform.position, closestPoint);
 *                  if (distToSmallBall > maxRadius)
 *                  {
 *                      maxRadius = distToSmallBall;
 *                  }
 *              }
 *
 *              bonGarsToSmallBallJoint.autoConfigureConnectedAnchor = false;
 *              bonGarsToSmallBallJoint.connectedAnchor = new Vector3(0f, bonGarsToSmallBallJoint.connectedAnchor.y, padding * (-maxRadius) / smallBall.transform.localScale.y); */
            }
        }
    }
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        VoidRiftMutator voidRiftMutator = Comp <VoidRiftMutator> .GetOrAdd(abilityObject);

        voidRiftMutator.increasedDamage              = voidRift_increasedDamage;
        voidRiftMutator.increasedRadius              = voidRift_increasedRadius;
        voidRiftMutator.timeRotChance                = voidRift_timeRotChance;
        voidRiftMutator.increasesDamageTaken         = voidRift_increasesDamageTaken;
        voidRiftMutator.increasesDoTDamageTaken      = voidRift_increasesDoTDamageTaken;
        voidRiftMutator.increasedStunChance          = voidRift_increasedStunChance;
        voidRiftMutator.moreDamageAgainstStunned     = voidRift_moreDamageAgainstStunned;
        voidRiftMutator.igniteChance                 = voidRift_igniteChance;
        voidRiftMutator.moreDamageAgainstIgnited     = voidRift_damageAgainstIgnited;
        voidRiftMutator.moreDamageAgainstTimeRotting = voidRift_damageAgainstTimeRotting;
        if (voidRift_noGrowth)
        {
            voidRiftMutator.areaGainOnNearbyDeath   = 0f;
            voidRiftMutator.damageGainOnNearbyDeath = 0f;
        }
        else
        {
            voidRiftMutator.areaGainOnNearbyDeath   *= (1 + voidRift_increasedAreaGrowth);
            voidRiftMutator.damageGainOnNearbyDeath *= (1 + voidRift_increasedDamageGrowth);
        }

        if (dealsDamage)
        {
            SphereCollider col = abilityObject.AddComponent <SphereCollider>();
            col.radius    = 0.3f;
            col.isTrigger = true;
        }


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

        if (movementSpeedOnCast != 0)
        {
            TaggedStatsHolder.Stat stat = new TaggedStatsHolder.Stat(Tags.Properties.Movespeed);
            stat.increasedValue = movementSpeedOnCast;
            Buff buff = new Buff(stat, 4f);
            statBuffs.addBuff(buff);
        }

        if (orbitsCaster)
        {
            SpiralMovement movement = abilityObject.AddComponent <SpiralMovement>();
            movement.outwardDistance       = 2f + increasedOrbitDistance;
            movement.angleChangedPerSecond = 180f;
            movement.constantVelocity      = SpiralMovement.ConstantType.AngularVelocity;
            movement.centreOnCaster        = true;
            movement.offsetFromTransform   = new Vector3(0, 1, 0);
            movement.outwardSpeed          = 0f;
            movement.randomStartAngle      = true;
        }

        if (castsAbyssalOrb)
        {
            CastAtRandomPointAfterDuration component = abilityObject.AddComponent <CastAtRandomPointAfterDuration>();
            component.ability    = Ability.getAbility(AbilityID.abyssalOrb);
            component.radius     = 5f;
            component.limitCasts = false;
            component.duration   = 3f / (1f + increasedAbyssalOrbFrequency);
        }

        if (voidEruptionOnDeath)
        {
            CreateAbilityObjectOnDeath component = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
            component.abilityToInstantiate = Ability.getAbility(AbilityID.voidEruption);
            component.aimingMethod         = CreateAbilityObjectOnDeath.AimingMethod.Random;
        }

        if (increasedDuration != 0)
        {
            DestroyAfterDuration dad = abilityObject.GetComponent <DestroyAfterDuration>();
            if (dad)
            {
                dad.duration *= (1 + increasedDuration);
            }
        }


        return(abilityObject);
    }
示例#15
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // Leech on cast buff
        if (statBuffs)
        {
            statBuffs.addBuff(4f, Tags.Properties.PercentLifeLeech, 0, physLeechOnCast, null, null, physTag, "marrow shards phys leech on cast buff");
            if (tracker && tracker.numberOfMinions() == 2)
            {
                statBuffs.addBuff(2f, Tags.Properties.CriticalChance, 0, critChanceOnCast, null, null, physTag, "marrow shards phys leech on cast buff");
            }
        }

        if (createsSplintersAtEnd)
        {
            // nova trigger(s)
            CreateAbilityObjectOnDeath component = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
            component.abilityToInstantiate = Ability.getAbility(AbilityID.boneNova);
            component.failsIfFailedAbility = true;
            component.offset       = boneNovaOffset;
            component.aimingMethod = CreateAbilityObjectOnDeath.AimingMethod.TravelDirection;

            // nova mutator
            BoneNovaMutator mutator = abilityObject.AddComponent <BoneNovaMutator>();
            mutator.increasedSpeed      = nova_increasedSpeed;
            mutator.pierces             = true;
            mutator.increasedDamage     = nova_increasedDamage;
            mutator.increasedStunChance = nova_increasedStunChance;
            mutator.bleedChance         = nova_bleedChance;
            mutator.addedCritChance     = nova_addedCritChance;
            mutator.addedCritMultiplier = nova_addedCritMultiplier;
            mutator.cone                      = true;
            mutator.randomAngles              = true;
            mutator.noVFX                     = true;
            mutator.dontAttach                = true;
            mutator.dontMoveToTarget          = true;
            mutator.moreDamageAgainstBleeding = nova_moreDamageAgainstBleeding;
        }

        if (returnHealthChance != 0 && returnHealthChance > (Random.Range(0f, 1f)))
        {
            CreateResourceReturnAbilityObjectOnEnemyHit component = abilityObject.AddComponent <CreateResourceReturnAbilityObjectOnEnemyHit>();
            component.abilityObject = Ability.getAbility(AbilityID.bloodReturn);
            component.health        = healthReturned;
            if (manaReturnChance != 0 && manaReturnChance > (Random.Range(0f, 1f)))
            {
                component.mana = manaReturned;
            }
        }

        if (increasedHealthCost != 0)
        {
            DamageCreatorOnCreation component = abilityObject.GetComponent <DamageCreatorOnCreation>();
            if (component)
            {
                component.flatDamage *= (1 + increasedHealthCost);
                component.percentCurrentHealthTaken *= (1 + increasedHealthCost);
            }
        }

        if (doesntPierce)
        {
            Comp <Pierce> .GetOrAdd(abilityObject).objectsToPierce = 0;

            abilityObject.AddComponent <DestroyOnFailingToPierceEnemy>();
        }

        if (endsAtTargetPoint)
        {
            if (!abilityObject.GetComponent <LocationDetector>())
            {
                abilityObject.AddComponent <LocationDetector>();
            }
            DestroyAfterDurationAfterReachingTargetLocation component = abilityObject.AddComponent <DestroyAfterDurationAfterReachingTargetLocation>();
            component.duration = 0f;
        }

        if (increasedDuration != 0)
        {
            DestroyAfterDuration dad = abilityObject.GetComponent <DestroyAfterDuration>();
            dad.duration *= 1 + increasedDuration;
        }

        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 (moreDamageAgainstBleeding != 0)
        {
            // create the conditional
            DamageConditionalEffect    conditionalEffect = new DamageConditionalEffect();
            HasStatusEffectConditional conditional       = new HasStatusEffectConditional();
            conditional.statusEffect      = StatusEffectID.Bleed;
            conditionalEffect.conditional = conditional;
            conditionalEffect.effect      = new DamageEffectMoreDamage(moreDamageAgainstBleeding);
            // add the conditional to all damage stats holders
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.baseDamageStats.conditionalEffects.Add(conditionalEffect);
            }
        }

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

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

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

        // more damage if you only have one minion
        if (increasedDamageWithOneMinion != 0)
        {
            if (tracker && tracker.numberOfMinions() == 1)
            {
                realIncreasedDamage += increasedDamageWithOneMinion;
            }
        }

        if (increasedDamageFromMinionDrain != 0 && tracker && tracker.summons != null && tracker.summons.Count > 0)
        {
            // choose a minion to drain
            BaseHealth minionHealth = tracker.summons[Random.Range(0, tracker.summons.Count - 1)].GetComponent <BaseHealth>();

            if (minionHealth)
            {
                // gain extra damage
                realIncreasedDamage += increasedDamageFromMinionDrain;
                // create a death vfx
                Instantiate(spiritEscapePrefab).transform.position = minionHealth.transform.position + spiritEscapeOffset;
                // kill the minion
                minionHealth.HealthDamage(minionHealth.currentHealth + 1);
            }
        }

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

        if (damagesMinions)
        {
            DamageEnemyOnHit deoh = abilityObject.GetComponent <DamageEnemyOnHit>();
            if (deoh)
            {
                DamageCreatorMinionOnHit component = abilityObject.AddComponent <DamageCreatorMinionOnHit>();
                component.baseDamageStats = deoh.baseDamageStats;

                if (doesntPierce)
                {
                    abilityObject.GetComponent <DestroyOnFailingToPierceEnemy>().alsoDestroyOnFailingToPierceCreatorMinion();
                }
            }
        }

        return(abilityObject);
    }
 // Use this for initialization
 void Start()
 {
     stateController      = GetComponent <StateController>();
     destroyAfterDuration = GetComponent <DestroyAfterDuration>();
 }
示例#17
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        if (extraProjectiles > 0 && !spiralMovement)
        {
            foreach (DamageEnemyOnHit component in abilityObject.GetComponents <DamageEnemyOnHit>())
            {
                component.canDamageSameEnemyAgain = false;
            }
        }

        if (chains > 0)
        {
            ChainOnHit chain = abilityObject.AddComponent <ChainOnHit>();
            chain.chainsRemaining          = chains;
            chain.abilityToChain           = ability;
            chain.range                    = 8f;
            chain.destroyAfterChainAttempt = true;
            chain.cannotHitSame            = true;
            chain.offset                   = new Vector3(0f, 1.2f, 0f);
        }

        if (chains > 0 || hasChained)
        {
            // add a copy of this mutator to the ability object, but remove the chains (because it will chain anyway), the increased damage to first enemy hit, and the on cast stuff
            HammerThrowMutator newMutator = Comp <HammerThrowMutator> .GetOrAdd(abilityObject);

            newMutator.chains            = 0;
            newMutator.increasedDamage   = increasedDamage;
            newMutator.extraProjectiles  = 0;
            newMutator.armourShredChance = 0f;

            newMutator.noPierce = noPierce;
            newMutator.chanceForDoubleDamage    = chanceForDoubleDamage;
            newMutator.increasedDamage          = increasedDamage;
            newMutator.moreDamageAgainstStunned = moreDamageAgainstStunned;

            newMutator.spiralMovement = false;

            newMutator.aoeVoidDamage          = aoeVoidDamage;
            newMutator.increasedAoEBaseDamage = increasedAoEBaseDamage;

            newMutator.increasedProjectileSpeed = increasedProjectileSpeed;
            newMutator.increasedStunChance      = increasedStunChance;
            newMutator.moreDamage = moreDamage;
            newMutator.noReturn   = true;
            newMutator.canDamageSameEnemyAgain = false;
            newMutator.hasChained = true;
        }

        if (noReturn)
        {
            DestroyAfterDuration        dad       = abilityObject.GetComponent <DestroyAfterDuration>();
            ReturnToCasterAfterDuration component = abilityObject.GetComponent <ReturnToCasterAfterDuration>();
            component.duration = 10000f;
            if (spiralMovement)
            {
                dad.duration = 6f;
            }
            else
            {
                dad.duration = 2.5f;
            }
            if (!hasChained)
            {
                abilityObject.AddComponent <DestroyOnInanimateCollison>();
                ReturnOnInanimateCollision ret = abilityObject.GetComponent <ReturnOnInanimateCollision>();
                if (ret)
                {
                    Destroy(ret);
                }
            }
        }

        // aoe void damage
        if (aoeVoidDamage)
        {
            foreach (Transform child in abilityObject.GetComponentsInChildren <Transform>(true))
            {
                if (child.name == "aura")
                {
                    child.gameObject.SetActive(true);
                }
            }
            RepeatedlyDamageEnemiesWithinRadius repeatDamage = abilityObject.GetComponent <RepeatedlyDamageEnemiesWithinRadius>();
            if (repeatDamage == null)
            {
                repeatDamage = abilityObject.AddComponent <RepeatedlyDamageEnemiesWithinRadius>();
            }
            if (repeatDamage.baseDamageStats.damage == null)
            {
                repeatDamage.baseDamageStats.damage = new List <DamageStatsHolder.DamageTypesAndValues>();
            }
            repeatDamage.addBaseDamage(DamageType.VOID, 6f * (1 + increasedAoEBaseDamage));
            repeatDamage.damageInterval = 0.5f;
            repeatDamage.radius         = 1.5f;
            repeatDamage.baseDamageStats.addedDamageScaling = 0.2f;
            repeatDamage.tags.Add(Tags.AbilityTags.AoE);
            repeatDamage.tags.Add(Tags.AbilityTags.Throwing);
            repeatDamage.tags.Add(Tags.AbilityTags.DoT);
        }

        // add extra projectiles
        if (extraProjectiles != 0)
        {
            ExtraProjectiles extraProjectilesObject = abilityObject.GetComponent <ExtraProjectiles>();
            if (extraProjectilesObject == null)
            {
                extraProjectilesObject = abilityObject.AddComponent <ExtraProjectiles>(); extraProjectilesObject.numberOfExtraProjectiles = 0;
            }
            extraProjectilesObject.numberOfExtraProjectiles += extraProjectiles;
            if (projectileNova)
            {
                extraProjectilesObject.angle = 144f;
                if (extraProjectiles >= 6)
                {
                    extraProjectilesObject.angle = 160;
                }
            }
        }

        // remove pierce
        if (noPierce && chains <= 0 && !hasChained)
        {
            Pierce pierce = abilityObject.GetComponent <Pierce>();
            if (pierce == null)
            {
                pierce = abilityObject.AddComponent <Pierce>(); pierce.objectsToPierce = 0;
            }
            if (chains <= 0 && !hasChained)
            {
                abilityObject.AddComponent <DestroyOnFailingToPierceEnemy>();
            }
        }

        // add chance to shred armour
        if (armourShredChance > 0)
        {
            ChanceToApplyStatusOnEnemyHit chanceTo = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            chanceTo.chance       = armourShredChance;
            chanceTo.statusEffect = StatusEffectList.getEffect(StatusEffectID.ArmourShred);
        }

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

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

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

        if (chanceForDoubleDamage > 0)
        {
            float rand = Random.Range(0f, 1f);
            if (rand < chanceForDoubleDamage)
            {
                foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
                {
                    for (int i = 0; i < holder.baseDamageStats.damage.Count; i++)
                    {
                        holder.addBaseDamage(holder.baseDamageStats.damage[i].damageType, holder.getBaseDamage(holder.baseDamageStats.damage[i].damageType));
                    }
                }
            }
        }

        if (moreDamageAgainstStunned != 0)
        {
            // create the conditional
            DamageConditionalEffect conditionalEffect = new DamageConditionalEffect();
            StunnedConditional      conditional       = new StunnedConditional();
            conditionalEffect.conditional = conditional;
            conditionalEffect.effect      = new DamageEffectMoreDamage(moreDamageAgainstStunned);
            // add the conditional to all damage stats holders
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.baseDamageStats.conditionalEffects.Add(conditionalEffect);
            }
        }

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

        if (spiralMovement)
        {
            SpiralMovement spira = abilityObject.AddComponent <SpiralMovement>();
            spira.constantVelocity      = SpiralMovement.ConstantType.BothAreMaxima;
            spira.tangentialVelocity    = 5.3f * (1 + increasedProjectileSpeed);
            spira.angleChangedPerSecond = 157f * (1 + increasedProjectileSpeed);
            spira.outwardSpeed          = 1.15f;
            spira.outwardDistance       = 0.6f;

            AbilityMover mover = abilityObject.GetComponent <AbilityMover>();
            mover.speed = 0;

            if (centreOnCaster)
            {
                spira.centreOnCaster      = true;
                spira.offsetFromTransform = new Vector3(0f, 1.2f, 0f);
            }

            if (extraProjectiles > 0)
            {
                spira.randomStartAngle = true;
            }
        }



        return(abilityObject);
    }
示例#18
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // add additional duration
        if (increasedDuration != 0)
        {
            DestroyAfterDuration durationObject = abilityObject.GetComponent <DestroyAfterDuration>();
            if (durationObject != null)
            {
                durationObject.duration *= (1 + increasedDuration);
            }
        }

        // set damage threshold
        if (additionalRetaliations != 0)
        {
            RetaliateWhenParentHit retaliator = abilityObject.GetComponent <RetaliateWhenParentHit>();
            if (retaliator)
            {
                retaliator.retaliationsRemaining += additionalRetaliations;
            }
        }

        // add dark blade retaliation
        if (darkBladeRetaliationChance > 0)
        {
            if (Random.Range(0f, 1f) < darkBladeRetaliationChance)
            {
                RetaliateWhenParentHit retaliator = abilityObject.AddComponent <RetaliateWhenParentHit>();
                retaliator.limitRetaliations           = true;
                retaliator.onlyCountHitDamage          = true;
                retaliator.ability                     = Ability.getAbility(AbilityID.darkBlade);
                retaliator.damageTakenTrigger          = 1;
                retaliator.destroyAfterLastRetaliation = false;
                retaliator.sourceOfAbility             = RetaliateWhenParentHit.SourceOfAbilityObjectConstructor.Parent;
                retaliator.retaliationsRemaining       = 1;
            }
        }

        // stats while prepped
        if (statsWhilePrepped != null && statsWhilePrepped.Count > 0)
        {
            BuffParent bp = abilityObject.GetComponent <BuffParent>();
            if (!bp)
            {
                bp = abilityObject.AddComponent <BuffParent>();
            }

            List <TaggedStatsHolder.TaggableStat> stats = new List <TaggedStatsHolder.TaggableStat>();

            foreach (TaggedStatsHolder.TaggableStat stat in statsWhilePrepped)
            {
                TaggedStatsHolder.TaggableStat newStat = new TaggedStatsHolder.TaggableStat(stat);
                stats.Add(newStat);
            }

            bp.taggedStats.AddRange(stats);
        }


        return(abilityObject);
    }