public void createAbilityObject() { if (requireNotPartOfChain) { ChainOnHit chain = GetComponent <ChainOnHit>(); if (chain && (chain.chainsRemaining > 0 || chain.hasChained)) { return; } } HitDetector hitDetector = GetComponent <HitDetector>(); if (hitDetector) { List <GameObject> enemies = new List <GameObject>(); if (hitDetector.sharedHitDetector != null) { foreach (GameObject enemy in hitDetector.sharedHitDetector.enemiesHit) { if (enemy != null && !enemies.Contains(enemy)) { enemies.Add(enemy); } } } else { foreach (GameObject enemy in hitDetector.enemiesHit) { if (enemy != null && !enemies.Contains(enemy)) { enemies.Add(enemy); } } } CreationReferences references = GetComponent <CreationReferences>(); if (references) { Vector3 startPos = references.locationCreatedFrom; // create the first ability object if (enemies.Count >= 1 && castFromCreatorToo) { GetComponent <AbilityObjectConstructor>().constructAbilityObject(abilityToInstantiate, startPos + offset, enemies[0].transform.position + offset); } for (int i = 0; i < enemies.Count - 1; i++) { // create the other ability objects GetComponent <AbilityObjectConstructor>().constructAbilityObject(abilityToInstantiate, enemies[i].transform.position + offset, enemies[i + 1].transform.position + offset); } } } }
protected void chainTo(GameObject target, GameObject from) { AbilityObjectConstructor aoc = GetComponent <AbilityObjectConstructor>(); GameObject newAbilityObject = aoc.constructAbilityObject(abilityToChain, transform.position, target.transform.position + offset); // reduce the chains remaining if (limitNumberOfChains) { ChainOnHit newChain = newAbilityObject.GetComponent <ChainOnHit>(); if (!newChain) { newChain = newAbilityObject.AddComponent <ChainOnHit>(); } newChain.chainsRemaining = chainsRemaining - 1; newChain.abilityToChain = abilityToChain; newChain.range = range; newChain.destroyAfterChainAttempt = destroyAfterChainAttempt; newChain.cannotHitSame = cannotHitSame; newChain.offset = offset; } if (cannotHitSame) { HitDetector detector = newAbilityObject.GetComponent <HitDetector>(); if (hitsAllies) { detector.alliesHit.Add(from); if (detector.sharedHitDetector) { detector.sharedHitDetector.alliesHit.Add(from); } } else { detector.enemiesHit.Add(from); if (detector.sharedHitDetector) { detector.sharedHitDetector.enemiesHit.Add(from); } } } }
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); }
public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation) { if (chains > 0) { ChainOnHit chain = abilityObject.AddComponent <ChainOnHit>(); chain.chainsRemaining = chains; chain.abilityToChain = ability; chain.range = 8f; chain.cannotHitSame = true; chain.destroyAfterSuccessfulChainAttempt = 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 DarkBladeMutator newMutator = abilityObject.AddComponent <DarkBladeMutator>(); newMutator.chains = 0; newMutator.increasedDamage = increasedDamage; newMutator.armourShredChance = 0f; newMutator.noPierce = noPierce; newMutator.chanceForDoubleDamage = chanceForDoubleDamage; newMutator.increasedDamage = increasedDamage; newMutator.moreDamageAgainstStunned = moreDamageAgainstStunned; newMutator.increasedProjectileSpeed = increasedProjectileSpeed; newMutator.increasedStunChance = increasedStunChance; newMutator.hasChained = true; } // 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 (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); } return(abilityObject); }
public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation) { // increasedDamageToFirstEnemyHit is removed for additional chains, so it can be applied without checks if (increasedDamage != 0 || increasedDamageToFirstEnemyHit != 0) { foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>()) { holder.increaseAllDamage(increasedDamage + increasedDamageToFirstEnemyHit); } } if (chains > 0) { ChainOnHit chain = abilityObject.AddComponent <ChainOnHit>(); chain.chainsRemaining = chains; chain.abilityToChain = ability; // 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 LightningBlastMutator newMutator = abilityObject.AddComponent <LightningBlastMutator>(); newMutator.chains = 0; increasedDamageToFirstEnemyHit = 0; newMutator.increasedDamage = increasedDamage; newMutator.lightningStrikeChance = lightningStrikeChance; newMutator.chanceToBlind = chanceToBlind; // add the increased damage per chain newMutator.increasedDamage += increasedDamagePerChain; // add increased damage to last enemy hit if appropriate if (chain.chainsRemaining == 0) { newMutator.increasedDamage += increasedDamageToLastEnemy; } } // on cast stuff if (lightningProtectionOnCast != 0 || elementalProtectionOnCast != 0) { Buff buff = new Buff(); TaggedStatsHolder.Stat stat = new TaggedStatsHolder.Stat(Tags.Properties.LightningProtection); stat.addedValue = (lightningProtectionOnCast + elementalProtectionOnCast) * (1 + increasedProtectionOnCast); buff.stat = stat; buff.remainingDuration = 3 * (1 + increasedProtectionDuration); statBuffs.addBuff(buff); } if (elementalProtectionOnCast != 0) { Buff buff = new Buff(); TaggedStatsHolder.Stat stat = new TaggedStatsHolder.Stat(Tags.Properties.ColdProtection); stat.addedValue = (elementalProtectionOnCast) * (1 + increasedProtectionOnCast); buff.stat = stat; buff.remainingDuration = 3 * (1 + increasedProtectionDuration); statBuffs.addBuff(buff); } if (elementalProtectionOnCast != 0) { Buff buff = new Buff(); TaggedStatsHolder.Stat stat = new TaggedStatsHolder.Stat(Tags.Properties.FireProtection); stat.addedValue = (elementalProtectionOnCast) * (1 + increasedProtectionOnCast); buff.stat = stat; buff.remainingDuration = 3 * (1 + increasedProtectionDuration); statBuffs.addBuff(buff); } if (wardOnCast != 0) { float rand = Random.Range(0f, 1f); if (rand < wardOnCastChance) { protectionClass.currentWard += wardOnCast; } } if (lightningDamageOnCast != 0) { List <Tags.AbilityTags> tags = new List <Tags.AbilityTags>(); tags.Add(Tags.AbilityTags.Lightning); TaggedStatsHolder.TaggableStat stat = new TaggedStatsHolder.TaggableStat(Tags.Properties.Damage, tags); stat.increasedValue = lightningDamageOnCast; TaggedBuff buff = new TaggedBuff(); buff.stat = stat; buff.remainingDuration = 3 * (1 + increasedDamageBuffDuration); statBuffs.addTaggedBuff(buff); } if (increasedStunChance != 0) { foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>()) { damage.baseDamageStats.increasedStunChance += increasedStunChance; } } // maybe cast lightning too if (lightningStrikeChance > 0) { float rand = Random.Range(0f, 1f); if (rand <= lightningStrikeChance) { AbilityObjectConstructor aoc = GetComponent <AbilityObjectConstructor>(); if (aoc) { aoc.constructAbilityObject(AbilityIDList.getAbility(AbilityID.lightning), targetLocation, targetLocation); } } } // maybe blind if (chanceToBlind > 0) { ChanceToApplyStatusOnEnemyHit ctasoeh = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); ctasoeh.chance = chanceToBlind; ctasoeh.statusEffect = StatusEffectList.getEffect(StatusEffectID.Blind); } return(abilityObject); }