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); }
public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation) { if (splatterChance > 0 && (!mana || mana.currentMana > 0) && (splatterChance >= 1 || splatterChance > (Random.Range(0f, 1f)))) { // splatter trigger CreateAbilityObjectOnDeath component = abilityObject.AddComponent <CreateAbilityObjectOnDeath>(); component.abilityToInstantiate = Ability.getAbility(AbilityID.bloodSplatter); // splatter mutator BloodSplatterMutator mutator = abilityObject.AddComponent <BloodSplatterMutator>(); mutator.increasedRadius = splatter_increasedRadius; mutator.increasedDamage = splatter_increasedDamage; mutator.chanceToPoison = splatter_chanceToPoison; mutator.armourReductionChance = splatter_armourReductionChance; mutator.armourReduction = splatter_armourReduction; mutator.armourReductionStacks = splatter_armourReductionStacks; mutator.increasedArmourDebuffDuration = splatter_increasedArmourDebuffDuration; mutator.increasedDamagePerMinion = splatter_increasedDamagePerMinion; mutator.minionBuffs = splatter_minionBuffs; mutator.reducesDarkProtectionInstead = splatter_reducesDarkProtectionInstead; mutator.necrotic = necrotic; } if (necrotic) { // replace vfx CreateOnDeath cod = abilityObject.GetComponent <CreateOnDeath>(); if (cod && cod.objectsToCreateOnDeath != null && cod.objectsToCreateOnDeath.Count > 0) { cod.objectsToCreateOnDeath[0] = new CreateOnDeath.GameObjectHolder(PrefabList.getPrefab("NecroticRipBloodOnDeathVFX")); } // convert damage foreach (DamageStatsHolder damage in abilityObject.GetComponents <DamageStatsHolder>()) { damage.convertAllDamageOfType(DamageType.PHYSICAL, DamageType.NECROTIC); } } if (targetsAlliesInstead) { // change the damage component to hit allies (only hits minions by default) DamageEnemyOnHit damageComponent = abilityObject.GetComponent <DamageEnemyOnHit>(); DamageAllyOnHit component = abilityObject.AddComponent <DamageAllyOnHit>(); component.baseDamageStats = damageComponent.baseDamageStats; damageComponent.deactivate(); Destroy(damageComponent); // make sure it still creates a blood orb CreateResourceReturnAbilityObjectOnEnemyHit component2 = abilityObject.GetComponent <CreateResourceReturnAbilityObjectOnEnemyHit>(); component2.hitsAlliesInstead = true; // change the targetting MoveToNearestEnemyOnCreation moveComponent = abilityObject.GetComponent <MoveToNearestEnemyOnCreation>(); if (moveComponent) { moveComponent.moveToAllyInstead = true; } } if (chanceToPoison > 0) { ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Poison); newComponent.chance = chanceToPoison; } if (chanceToBleed > 0) { ChanceToApplyStatusOnEnemyHit newComponent = abilityObject.AddComponent <ChanceToApplyStatusOnEnemyHit>(); newComponent.statusEffect = StatusEffectList.getEffect(StatusEffectID.Bleed); newComponent.chance = chanceToBleed; } if (addedHealthGained != 0 || increasedHealthGained != 0 || manaGained != 0 || convertHealthToWard || necrotic) { CreateResourceReturnAbilityObjectOnEnemyHit component = abilityObject.GetComponent <CreateResourceReturnAbilityObjectOnEnemyHit>(); // check if this behaviour needs to be removed if (increasedHealthGained < -1 && manaGained <= 0) { component.deactivated = true; } // if it does not then change its values else { component.health += addedHealthGained; component.health *= (1 + increasedHealthGained); if (increasedHealthGainedPerAttunement != 0) { component.health *= (1 + baseStats.GetStatValue(Tags.Properties.Attunement) * increasedHealthGainedPerAttunement); } component.mana += manaGained; if (convertHealthToWard) { component.ward = component.health; component.health = 0; } if (necrotic) { component.abilityObject = Ability.getAbility(AbilityID.necroticReturn); } } } if (increasedStunChance != 0) { foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>()) { holder.baseDamageStats.increasedStunChance += increasedStunChance; } } // increase damage based on the number of minions float realIncreasedDamage = increasedDamage; if (increasedDamagePerMinion != 0) { if (tracker && tracker.summons != null) { realIncreasedDamage += increasedDamagePerMinion * tracker.summons.Count; } } if (realIncreasedDamage != 0) { foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>()) { holder.increaseAllDamage(realIncreasedDamage); } } if (moreDamageInstances != null && moreDamageInstances.Count > 0) { float moreDamage = 1f; foreach (float instance in moreDamageInstances) { moreDamage *= 1 + instance; } foreach (DamageStatsHolder holder in abilityObject.GetComponents <DamageStatsHolder>()) { holder.increaseAllDamage(moreDamage - 1); } } return(abilityObject); }