// Use this for initialization void Start() { if (transform.parent) { Dying dying = transform.parent.GetComponent <Dying>(); if (dying) { dying.setDelays(0f, 0f); } if (detach) { transform.parent = null; } } }
public void Cast(Ability killingAbility, GameObject corpse) { if (castFromCorpse) { constructor.constructAbilityObject(abilityToCast, corpse.transform.position, corpse.transform.position + Vector3.Normalize(corpse.transform.position - transform.position)); } else { constructor.constructAbilityObject(abilityToCast, transform.position, corpse.transform.position); } if (eraseCorpse) { Dying dying = corpse.GetComponent <Dying>(); if (dying) { dying.setDelays(0f, 0f); } } }
public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation) { // work out whether a corpse has been consumed to empower the skeleton 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; } } // self stat buffs on corpse consumption if (corpseConsumed) { TaggedBuff newBuff; for (int i = 0; i < corpseSelfBuffStatList.Count; i++) { newBuff = new TaggedBuff(); newBuff.stat = new TaggedStatsHolder.TaggableStat(corpseSelfBuffStatList[i]); newBuff.remainingDuration = 4f; newBuff.name = "skeleton corpse buff " + newBuff.stat.property; if (newBuff.stat.tagList != null) { foreach (Tags.AbilityTags tag in newBuff.stat.tagList) { newBuff.name += " " + tag; } } statBuffs.addTaggedBuff(newBuff); } } // control the weights of each minion type CreateRandomAbilityObjectOnDeath randomSummoner = abilityObject.GetComponent <CreateRandomAbilityObjectOnDeath>(); randomSummoner.possibleAbilities.Clear(); randomSummoner.weights.Clear(); if (!cannotSummonWarriors) { randomSummoner.possibleAbilities.Add(summonWarrior); // add extra weight if there are no warriors if (summonTracker.numberOfMinions(summonWarrior) <= 0) { randomSummoner.weights.Add(4); } else { randomSummoner.weights.Add(1); } } if (!cannotSummonMages) { randomSummoner.possibleAbilities.Add(summonMage); randomSummoner.weights.Add(1); } if (canSummonArchers) { randomSummoner.possibleAbilities.Add(summonArcher); randomSummoner.weights.Add(1); } if (canSummonWarlords) { randomSummoner.possibleAbilities.Add(summonWarlord); randomSummoner.weights.Add(0.45f); } if (cannotSummonWarriors && cannotSummonMages && !canSummonArchers && !canSummonWarlords) { randomSummoner.possibleAbilities.Add(summonBrawler); randomSummoner.weights.Add(1); } // skeleton warrior if (!cannotSummonWarriors) { SummonSkeletonWarriorMutator warrior = abilityObject.AddComponent <SummonSkeletonWarriorMutator>(); warrior.statList.AddRange(statList); warrior.usesDeathSlash = usesDeathSlash; warrior.increasedDeathSlashCooldownRecovery = increasedDeathSlashCooldownRecovery; warrior.additionalDuration = additionalDuration; warrior.additionalSkeletons = additionalSkeletons; warrior.limitDuration = limitDuration; if (corpseConsumed) { warrior.tempStats.AddRange(corpseStatList); } } // skeleton mage if (!cannotSummonMages) { SummonSkeletonMageMutator mage = abilityObject.AddComponent <SummonSkeletonMageMutator>(); mage.statList.AddRange(statList); mage.usesNecroticMortar = usesNecroticMortar; mage.increasedNecroticMortarCooldownRecovery = increasedNecroticMortarCooldownRecovery; mage.additionalDuration = additionalDuration; mage.additionalSkeletons = additionalSkeletons; mage.limitDuration = limitDuration; if (corpseConsumed) { mage.tempStats.AddRange(corpseStatList); } } // skeleton archer if (canSummonArchers) { SummonSkeletonArcherMutator archer = abilityObject.AddComponent <SummonSkeletonArcherMutator>(); archer.statList.AddRange(statList); archer.usesPoisonArrow = usesPoisonArrow; archer.increasedPoisonArrowCooldownSpeed = increasedPoisonArrowCooldownSpeed; archer.increasedPoisonArrowCooldown = increasedPoisonArrowCooldown; archer.poisonArrowPierces = poisonArrowPierces; archer.poisonArrowInaccurate = poisonArrowInaccurate; archer.poisonArrowIncreasedDamage = poisonArrowIncreasedDamage; archer.poisonArrowDelayedAttacks = poisonArrowDelayedAttacks; archer.usesMultishot = usesMultishot; archer.increasedMultishotCooldownSpeed = increasedMultishotCooldownSpeed; archer.additionalDuration = additionalDuration; archer.additionalSkeletons = additionalSkeletons; archer.limitDuration = limitDuration; if (corpseConsumed) { archer.tempStats.AddRange(corpseStatList); } } // skeleton warlord if (canSummonWarlords) { SummonSkeletonWarlordMutator warlord = abilityObject.AddComponent <SummonSkeletonWarlordMutator>(); warlord.statList.AddRange(statList); warlordStatList.AddRange(warlordStatList); warlord.usesInspire = usesInspire; warlord.increasedInspireCooldownRecovery = increasedInspireCooldownRecovery; warlord.additionalDuration = additionalDuration; warlord.additionalSkeletons = additionalWarlords; warlord.limitDuration = limitDuration; if (corpseConsumed) { warlord.tempStats.AddRange(corpseStatList); } } // skeleton brawler if (cannotSummonWarriors && cannotSummonMages && !canSummonArchers && !canSummonWarlords) { SummonSkeletonBrawlerMutator brawler = abilityObject.AddComponent <SummonSkeletonBrawlerMutator>(); brawler.statList.AddRange(statList); brawler.additionalDuration = additionalDuration; brawler.additionalSkeletons = additionalSkeletons; brawler.limitDuration = limitDuration; if (corpseConsumed) { brawler.tempStats.AddRange(corpseStatList); } } return(abilityObject); }
// Use this for initialization public override void onCreation() { bool success = false; CreationReferences references = GetComponent <CreationReferences>(); if (!references || !references.creator) { if (destroyIfFailedToMove) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.failedAbility = true; dest.die(); } return; } SummonTracker tracker = references.creator.GetComponent <SummonTracker>(); if (!tracker) { if (destroyIfFailedToMove) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.failedAbility = true; dest.die(); } return; } // find a lit of summon List <Summoned> summons = new List <Summoned>(); foreach (Summoned summoned in tracker.summons) { if (summoned) { summons.Add(summoned); } } // remove inactive objects from the list for (int i = summons.Count - 1; i >= 0; i--) { if (!summons[i].gameObject.activeSelf) { summons.Remove(summons[i]); } } // remove dying objects from the list if (requiredLifeState == lifeState.alive) { for (int i = summons.Count - 1; i >= 0; i--) { if (summons[i].GetComponent <Dying>() != null) { if (summons[i].GetComponent <StateController>().currentState == summons[i].GetComponent <StateController>().dying) { summons.Remove(summons[i]); } } } } // or remove living objects from the list else if (requiredLifeState == lifeState.dead) { for (int i = summons.Count - 1; i >= 0; i--) { if (summons[i].GetComponent <Dying>() != null) { if (summons[i].GetComponent <StateController>().currentState != summons[i].GetComponent <StateController>().dying) { summons.Remove(summons[i]); } } else { summons.Remove(summons[i]); } } } if (summons.Count == 0) { if (destroyIfFailedToMove) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.failedAbility = true; dest.die(); } return; } else { // find the nearest summon Summoned nearest = summons[0]; float distance = Vector3.Distance(transform.position, nearest.transform.position); foreach (Summoned summon in summons) { if (Vector3.Distance(transform.position, summon.transform.position) < distance) { nearest = summon; distance = Vector3.Distance(transform.position, summon.transform.position); } } // move to the summon's location transform.position = nearest.transform.position; // change to the summon's rotation transform.rotation = nearest.transform.rotation; success = true; if (kill) { Dying dying = nearest.GetComponent <Dying>(); if (dying) { if (eraseCorpse) { dying.setDelays(0.01f, 0.02f); } dying.myHealth.HealthDamage(dying.myHealth.maxHealth * 200); } } } if (destroyIfFailedToMove && success == false) { SelfDestroyer dest = Comp <SelfDestroyer> .GetOrAdd(gameObject); dest.failedAbility = true; dest.die(); } }
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); }