Exemplo n.º 1
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);
    }
Exemplo n.º 2
0
    public override GameObject Mutate(GameObject abilityObject, Vector3 location, Vector3 targetLocation)
    {
        // if this is a meteor shower
        if (additionalMeteors > 0)
        {
            Destroy(abilityObject);

            abilityObject = Instantiate(AbilityIDList.getAbility(AbilityID.meteorShower).abilityPrefab);
            abilityObject.transform.position = location;
            CastAtRandomPointAfterDuration meteorCaster = abilityObject.GetComponent <CastAtRandomPointAfterDuration>();
            meteorCaster.duration       /= (1 + increasedMeteorFrequency);
            meteorCaster.remainingCasts += additionalMeteors;
            meteorCaster.radius         *= (1 + increasedShowerRadius);

            if (line)
            {
                StartsAtTarget sat = meteorCaster.GetComponent <StartsAtTarget>();
                if (sat)
                {
                    sat.active = false;
                    Destroy(sat);
                }
                AbilityMover mover = Comp <AbilityMover> .GetOrAdd(abilityObject);

                mover.SetDirection(targetLocation - location);
                mover.speed         = 10 * (1 + increasedShowerRadius);
                meteorCaster.radius = 0;
                StartsTowardsTarget stt = abilityObject.AddComponent <StartsTowardsTarget>();
                stt.distance       = 1f;
                stt.addWeaponRange = false;
            }

            // create a mutator on the meteor shower object
            MeteorMutator newMutator = abilityObject.AddComponent <MeteorMutator>();



            // variables for all damage
            newMutator.moreDamageInstances = moreDamageInstances;

            // meteor variables (except use all mana)
            newMutator.increasedFallSpeed     = increasedFallSpeed;
            newMutator.increasedCastSpeed     = increasedCastSpeed;
            newMutator.shrapnelChance         = shrapnelChance;
            newMutator.increasedShrapnelSpeed = increasedShrapnelSpeed;
            newMutator.shrapnelPierces        = shrapnelPierces;
            newMutator.replaceFireCircle      = replaceFireCircle;

            // aoe variables
            newMutator.moreDamageAgainstFullHealth = moreDamageAgainstFullHealth;
            newMutator.increasedShrapnelDamage     = increasedShrapnelDamage;
            newMutator.increasedStunChance         = increasedStunChance;
            newMutator.moreDamageInstances         = new List <float>();
            newMutator.moreDamageInstances.AddRange(moreDamageInstances);

            // apply mana variable once for all meteors
            if (usesAllMana && myMana)
            {
                float totalCost = myMana.getManaCost(ability);
                totalCost += myMana.currentMana;

                float proportion = totalCost / myMana.maxMana;
                newMutator.moreDamageInstances.Add(proportion * 2);

                myMana.currentMana = 0;
            }

            return(abilityObject);
        }


        // if this is a regular meteor

        // apply aoe variables
        MeteorAoEMutator aoeMutator = abilityObject.AddComponent <MeteorAoEMutator>();

        aoeMutator.moreDamageAgainstFullHealth = moreDamageAgainstFullHealth;
        aoeMutator.increasedStunChance         = increasedStunChance;
        aoeMutator.moreDamageInstances         = new List <float>();
        aoeMutator.moreDamageInstances.AddRange(moreDamageInstances);


        // meteor variables

        if (increasedFallSpeed != 0)
        {
            abilityObject.GetComponent <AbilityMover>().speed *= (1 + increasedFallSpeed);
        }

        MeteorShrapnelMutator shrapnelMutator = null;

        if (shrapnelChance > 0)
        {
            float rand = Random.Range(0f, 1f);
            if (rand < shrapnelChance)
            {
                CreateAbilityObjectOnDeath caood = abilityObject.AddComponent <CreateAbilityObjectOnDeath>();
                caood.abilityToInstantiate = AbilityIDList.getAbility(AbilityID.meteorShrapnel);
                caood.createAtTarget       = true;
                caood.offset    = -caood.GetComponent <LocationDetector>().targetLocationOffset;
                shrapnelMutator = abilityObject.AddComponent <MeteorShrapnelMutator>();
                shrapnelMutator.increasedDamage     = increasedShrapnelDamage;
                shrapnelMutator.increasedSpeed      = increasedShrapnelSpeed;
                shrapnelMutator.pierces             = shrapnelPierces;
                shrapnelMutator.increasedStunChance = increasedStunChance;
                shrapnelMutator.moreDamageInstances = new List <float>();
                shrapnelMutator.moreDamageInstances.AddRange(moreDamageInstances);
            }
        }

        if (replaceFireCircle)
        {
            CreateAtTargetLocationOnCreation component = abilityObject.GetComponent <CreateAtTargetLocationOnCreation>();
            if (component)
            {
                component.objectsToCreate.Clear();
                GameObject prefab = PrefabList.getPrefab("EnemyMeteorCircle");
                if (prefab)
                {
                    CreateAtTargetLocationOnCreation.GameObjectHolder holder = new CreateAtTargetLocationOnCreation.GameObjectHolder();
                    holder.gameObject          = prefab;
                    holder.destroyWhenThisDies = true;
                    component.objectsToCreate.Add((holder));
                }
            }
        }

        if (usesAllMana && myMana)
        {
            float totalCost = myMana.getManaCost(ability);
            totalCost += myMana.currentMana;

            float proportion = totalCost / myMana.maxMana;

            aoeMutator.moreDamageInstances.Add(proportion * 2);
            if (shrapnelMutator)
            {
                shrapnelMutator.moreDamageInstances.Add(proportion * 2);
            }

            myMana.currentMana = 0;
        }


        return(abilityObject);
    }