示例#1
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 void updateMutator()
    {
        FireballMutator mutator                      = PlayerFinder.getPlayer().GetComponent <FireballMutator>();
        bool            explosion                    = false;
        int             extraProjectiles             = 0;
        int             targetsToPierce              = 0;
        float           chanceToCreateExplosionOnHit = 0f;
        float           igniteChance                 = 0f;
        bool            reduceBaseDamageBy80Percent  = false;
        bool            fireInSequence               = false;
        float           increasedCastSpeed           = 0f;
        float           increasedManaCost            = 0f;
        float           chanceForDoubleDamage        = 0f;
        float           fireAddedAsLightning         = 0f;
        float           moreDamageAgainstIgnited     = 0f;
        float           moreDamageAgainstChilled     = 0f;
        bool            homing            = false;
        float           increasedDamage   = 0f;
        bool            freeWhenOutOfMana = false;
        float           manaEfficiency    = 0f;
        bool            alwaysFree        = false;
        float           increasedSpeed    = 0f;
        float           increasedDuration = 0f;
        bool            inaccuracy        = false;
        bool            channelled        = false;

        foreach (SkillTreeNode node in GetComponentsInChildren <SkillTreeNode>())
        {
            if (node.name == "Fireball Skill Tree Explosion")
            {
                explosion = (node.GetComponent <SkillTreeNode>().pointsAllocated > 0);
            }
            if (node.name == "Fireball Skill Tree Extra Projectiles")
            {
                extraProjectiles   += node.GetComponent <SkillTreeNode>().pointsAllocated * 2;
                increasedCastSpeed += node.GetComponent <SkillTreeNode>().pointsAllocated * -0.15f;
            }
            if (node.name == "Fireball Skill Tree Pierce")
            {
                targetsToPierce += node.GetComponent <SkillTreeNode>().pointsAllocated;
            }
            if (node.name == "Fireball Skill Tree Damage Around Hit")
            {
                chanceToCreateExplosionOnHit = node.GetComponent <SkillTreeNode>().pointsAllocated * 0.25f;
            }
            if (node.name == "Fireball Skill Tree Ignite Chance")
            {
                igniteChance += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.2f;
            }
            if (node.name == "Fireball Skill Tree Ignite Keystone")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    reduceBaseDamageBy80Percent = true;
                    igniteChance += 1;
                }
            }
            // this is halved so it ends up as one
            if (node.name == "Fireball Skill Tree One Extra Projectile")
            {
                extraProjectiles  += node.GetComponent <SkillTreeNode>().pointsAllocated * 2;
                increasedDamage   += node.GetComponent <SkillTreeNode>().pointsAllocated * -0.07f;
                increasedManaCost += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.4f;
            }
            if (node.name == "Fireball Skill Tree Cast Speed")
            {
                increasedCastSpeed += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.06f;
            }
            if (node.name == "Fireball Skill Tree Cast Speed And Mana Cost")
            {
                increasedCastSpeed += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.12f;
                increasedManaCost  += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.25f;
            }
            if (node.name == "Fireball Skill Tree Extra Projectiles And Mana Cost")
            {
                extraProjectiles  += node.GetComponent <SkillTreeNode>().pointsAllocated * 2;
                increasedManaCost += node.GetComponent <SkillTreeNode>().pointsAllocated * 1f;
            }
            if (node.name == "Fireball Skill Tree Chance For Double Damage")
            {
                chanceForDoubleDamage += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.1f;
            }
            if (node.name == "Fireball Skill Tree Fire Added As Lightning")
            {
                fireAddedAsLightning += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.2f;
                increasedCastSpeed   += node.GetComponent <SkillTreeNode>().pointsAllocated * -0.04f;
            }
            if (node.name == "Fireball Skill Tree Damage Against Ignited")
            {
                moreDamageAgainstIgnited += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.2f;
            }
            if (node.name == "Fireball Skill Tree Damage Against Chilled")
            {
                moreDamageAgainstChilled += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.25f;
            }
            if (node.name == "Fireball Skill Tree Mana Efficiency")
            {
                manaEfficiency += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.28f;
            }
            if (node.name == "Fireball Skill Tree Homing")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    homing = true;
                }
            }
            if (node.name == "Fireball Skill Tree Damage Vs Speed")
            {
                increasedDamage += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.12f;
                increasedSpeed  += node.GetComponent <SkillTreeNode>().pointsAllocated * -0.06f;
            }
            if (node.name == "Fireball Skill Tree Duration")
            {
                increasedDuration += node.GetComponent <SkillTreeNode>().pointsAllocated * 0.06f;
            }
            if (node.name == "Fireball Skill Always Pierce")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    targetsToPierce += 100;
                    increasedDamage -= 0.2f;
                }
            }
        }

        // modifies number of projectiles granted from other nodes
        foreach (SkillTreeNode node in GetComponentsInChildren <SkillTreeNode>())
        {
            if (node.name == "Fireball Skill Tree Sequence")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    fireInSequence      = true;
                    increasedCastSpeed -= 0.25f;
                    extraProjectiles    = Mathf.CeilToInt((((float)extraProjectiles) / 2f));
                }
            }
        }

        // further modifies number of projectiles and ignite change
        foreach (SkillTreeNode node in GetComponentsInChildren <SkillTreeNode>())
        {
            if (node.name == "Fireball Skill Tree No Cost")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    freeWhenOutOfMana = true;
                    increasedDamage  += 0.1f * extraProjectiles;
                    extraProjectiles  = 0;
                }
            }
            if (node.name == "Fireball Skill Tree Zero Cost")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    alwaysFree       = true;
                    increasedDamage -= 0.2f;
                    igniteChance    *= 0.6f;
                }
            }
            // requires knowledge of increased cast speed
            if (node.name == "Fireball Skill Tree FlameThrower")
            {
                if (node.GetComponent <SkillTreeNode>().pointsAllocated > 0)
                {
                    channelled         = true;
                    increasedDuration -= 0.7f;
                    increasedDamage   += increasedCastSpeed;
                    increasedDamage   -= 0.5f;
                }
            }
        }

        if (homing == true && fireInSequence != true)
        {
            extraProjectiles = 0;
        }

        mutator.addedManaCostDivider         = manaEfficiency;
        mutator.addExplosion                 = explosion;
        mutator.extraProjectiles             = extraProjectiles;
        mutator.targetsToPierce              = targetsToPierce;
        mutator.chanceToCreateExplosionOnHit = chanceToCreateExplosionOnHit;
        mutator.igniteChance                 = igniteChance;
        mutator.reduceBaseDamageBy80Percent  = reduceBaseDamageBy80Percent;
        mutator.fireInSequence               = fireInSequence;
        mutator.increasedCastSpeed           = increasedCastSpeed;
        mutator.increasedManaCost            = increasedManaCost;
        mutator.chanceForDoubleDamage        = chanceForDoubleDamage;
        mutator.fireAddedAsLightning         = fireAddedAsLightning;
        mutator.moreDamageAgainstIgnited     = moreDamageAgainstIgnited;
        mutator.moreDamageAgainstChilled     = moreDamageAgainstChilled;
        mutator.homing            = homing;
        mutator.increasedDamage   = increasedDamage;
        mutator.freeWhenOutOfMana = freeWhenOutOfMana;
        mutator.alwaysFree        = alwaysFree;
        mutator.increasedSpeed    = increasedSpeed;
        mutator.increasedDuration = increasedDuration;
        mutator.inaccuracy        = inaccuracy;
        mutator.channelled        = channelled;
    }
示例#3
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // return a channelled fireball object if this is channelled
        if (channelled)
        {
            Destroy(abilityObject);
            abilityObject = Instantiate(Ability.getAbility(AbilityID.channelledFireball).abilityPrefab, location, Quaternion.Euler(targetLocation - location));

            // change the mutator on the new abilityObject
            FireballMutator mut = Comp <FireballMutator> .GetOrAdd(abilityObject);

            mut.extraProjectiles             = extraProjectiles;
            mut.addExplosion                 = addExplosion;
            mut.chanceToCreateExplosionOnHit = chanceToCreateExplosionOnHit;
            mut.igniteChance                 = igniteChance;
            mut.targetsToPierce              = targetsToPierce;
            mut.reduceBaseDamageBy80Percent  = reduceBaseDamageBy80Percent;
            mut.increasedCastSpeed           = increasedCastSpeed;
            mut.chanceForDoubleDamage        = chanceForDoubleDamage;
            mut.fireAddedAsLightning         = fireAddedAsLightning;
            mut.increasedDamage              = increasedDamage;
            mut.moreDamageAgainstIgnited     = moreDamageAgainstIgnited;
            mut.moreDamageAgainstChilled     = moreDamageAgainstChilled;
            mut.homing            = homing;
            mut.freeWhenOutOfMana = freeWhenOutOfMana;
            mut.alwaysFree        = alwaysFree;
            mut.increasedSpeed    = increasedSpeed;
            mut.increasedDuration = increasedDuration;
            mut.inaccuracy        = inaccuracy;

            // some are always false
            mut.channelled     = false;
            mut.fireInSequence = false;

            // this will be the channelled fireball object
            mut.channelledFireballObject = true;

            // return the new ability object and do not change it further
            return(abilityObject);
        }

        // disable shared hit detector for channelling
        if (channelledFireballObject)
        {
            foreach (HitDetector detector in abilityObject.GetComponents <HitDetector>())
            {
                detector.cannotHaveSharedhitDetector = true;
            }
        }

        // add an explosion
        if (addExplosion)
        {
            abilityObject.AddComponent <CreateAbilityObjectOnDeath>().abilityToInstantiate = AbilityIDList.getAbility(AbilityID.fireballAoe);
        }

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

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

        // slightly randomise target location
        if (inaccuracy)
        {
            targetLocation += new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f)) * 0.25f * Vector3.Distance(location, targetLocation);
        }

        // add extra projectiles
        if (extraProjectiles != 0 && !fireInSequence)
        {
            ExtraProjectiles extraProjectilesObject = abilityObject.GetComponent <ExtraProjectiles>();
            if (extraProjectilesObject == null)
            {
                extraProjectilesObject = abilityObject.AddComponent <ExtraProjectiles>(); extraProjectilesObject.numberOfExtraProjectiles = 0;
            }
            extraProjectilesObject.numberOfExtraProjectiles += extraProjectiles;
        }

        // add pierce change
        if (targetsToPierce > 0)
        {
            Pierce pierce = abilityObject.GetComponent <Pierce>();
            if (pierce == null)
            {
                pierce = abilityObject.AddComponent <Pierce>(); pierce.objectsToPierce = 0;
            }
            pierce.objectsToPierce += targetsToPierce;
        }

        // add chance to create explosion on hit
        if (chanceToCreateExplosionOnHit > 0)
        {
            ChanceToCreateAbilityObjectOnNewEnemyHit ctcaooneh = abilityObject.AddComponent <ChanceToCreateAbilityObjectOnNewEnemyHit>();
            ctcaooneh.chance               = chanceToCreateExplosionOnHit;
            ctcaooneh.spawnAtHit           = true;
            ctcaooneh.abilityToInstantiate = AbilityIDList.getAbility(AbilityID.fireballAoe);
        }

        // add chance to ignite
        if (igniteChance > 0)
        {
            ChanceToApplyStatusOnEnemyHit chanceTo = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>();
            chanceTo.chance       = igniteChance;
            chanceTo.statusEffect = StatusEffectList.getEffect(StatusEffectID.Ignite);
        }

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

        // reduce hit damage
        if (reduceBaseDamageBy80Percent)
        {
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                for (int i = 0; i < holder.baseDamageStats.damage.Count; i++)
                {
                    holder.baseDamageStats.damage[i] = new DamageStatsHolder.DamageTypesAndValues(holder.baseDamageStats.damage[i].damageType, holder.baseDamageStats.damage[i].value * 0.2f);
                }
            }
        }

        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 (fireAddedAsLightning > 0)
        {
            abilityObject.GetComponentInChildren <DisableOnStart>().active = false;
            foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>())
            {
                holder.addBaseDamage(DamageType.LIGHTNING, holder.getBaseDamage(DamageType.FIRE) * fireAddedAsLightning);
            }
        }

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

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

        if (homing)
        {
            abilityObject.AddComponent <HomingMovement>();
        }


        return(abilityObject);
    }