// 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;
         }
     }
 }
Example #2
0
 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);
         }
     }
 }
Example #3
0
    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();
        }
    }
Example #5
0
    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);
    }