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