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); } } }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }
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>(); }
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) { // 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); }