Example #1
0
    protected bool TryToAttackEnemy(Actor_Player player, Actor_Enemy enemy)
    {
        if (player.fTimeSinceLastAttack >= fAttackInterval * player.GetAttackSpeedMultiplier())
        {
            PlaySoundEffect(player);

            player.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);
            player.fTimeSinceLastAttack = 0.0f;

            if (player.render.attackParticles != null)
            {
                //player.render.attackParticles.Stop();
                player.render.attackParticles.Play();
            }

            for (int i = 0; i < numAttacks; i++)
            {
                IncrementCombo(player);
                if (DealDamageToEnemy(player, enemy, enemy.transform.position, 0.0f))
                {
                    return(true);
                }
            }
        }
        return(false);
    }
Example #2
0
    private void SpawnRandomGroup()
    {
        if (pendingSpawns.Count == 0)
        {
            Debug.Assert(false, "Ran out of spawns");
            return;
        }
        int iPick = Random.Range(0, pendingSpawns.Count);

        MinionTemplate template = pendingSpawns [iPick];

        pendingSpawns.RemoveAt(iPick);

        Vector3 spawnPos = GetBestSpawnPoint();

        {
            // Create new game object
            GameObject go = new GameObject("EnemyMinion_" + template.name);

            // Create a minion and attach it to the actor's game object. Enemy minions are less permanent data structures than player ones, so they can just be chucked into the battlefield
            MinionTemplateManager mtm = Core.GetMinionTemplateManager();
            Minion minion             = mtm.CreateMinion(template);
            minion.transform.SetParent(go.transform);
            minion.transform.localPosition = Vector3.zero;

            // Fill it with actor components
            Actor_Enemy actor = go.AddComponent <Actor_Enemy>();
            actor.InitFromMinion(minion);
            actor.iWave = iCurrentWave;
            aiNumSpawnedPerWave [iCurrentWave]++;
            Vector2 randomOffset = Random.insideUnitCircle * Random.Range(0.0f, 0.5f);
            actor.transform.position = spawnPos + new Vector3(randomOffset.x, 0.0f, randomOffset.y);
            // Push the next member of the group back a bit
            spawnPos = new Vector3(spawnPos.x + 1.0f, spawnPos.y, spawnPos.z);

            // Add renderer to actor
            RenderActor render = Instantiate <RenderActor>(template.render);
            render.transform.SetParent(actor.transform);
            render.transform.localPosition = Vector3.zero;
            render.Init(actor);
            actor.render = render;

            // Add audio sources
            actor.soundEffect                       = go.AddComponent <AudioSource>();
            actor.soundEffect.clip                  = minion.template.soundEffect;
            actor.soundEffect.playOnAwake           = false;
            actor.soundEffect.outputAudioMixerGroup = Core.GetAudioManager().soundEffectGroup;

            // Add healthbar
            Healthbar healthbar = Instantiate <Healthbar>(mtm.healthbarPrefab);
            healthbar.transform.SetParent(actor.transform);
            healthbar.transform.localPosition = new Vector3(0.0f, template.fHeight - 1.0f, 0.0f);
            actor.healthbar = healthbar;

            actor.CalculateMyAggregateBuffs();

            // Store a reference for later
            enemyActors.Add(actor);
        }
    }
Example #3
0
    private float GetScoreForCandidate(Actor_Player firer, Actor_Enemy candidate)
    {
        // Higher score is more likely to be picked
        switch (firer.minion.priority)
        {
        case TargetPriority.CLOSEST_ENEMY:
        {
            return(Core.GetLevel().GetRangedZoneMax() - candidate.transform.position.x);
        }

        case TargetPriority.FARTHEST_ENEMY:
        {
            return(candidate.transform.position.x - Core.GetLevel().GetRangedZoneMin());
        }

        case TargetPriority.HIGHEST_HP_ENEMY:
        {
            return(candidate.minion.fCurrentHealth);
        }

        case TargetPriority.LOWEST_HP_ENEMY:
        {
            return(1.0f / candidate.minion.fCurrentHealth);
        }
        }

        return(-1.0f);
    }
Example #4
0
    public override void SimulateEnemyFixedUpdate(Actor_Enemy actor)
    {
        // Default support. Go stand in a player zone, leave it, stand in it, repeat

        // If we are waiting, do that.
        if (actor.fTimeToNextMove > 0.0f)
        {
            actor.fTimeToNextMove -= Core.GetEnemyDeltaTime();
            if (actor.fTimeToNextMove <= 0.0f)
            {
                if (actor.bPickedPositionInPlayerZone)
                {
                    // Last pick was in a zone, so wherever is fine this time.
                    actor.target = new Vector3(Random.Range(LevelController.fMIN_X_COORD, Core.GetLevel().GetRangedZoneMax() + 3.0f), 0.0f, Random.Range(-LevelController.GetWidth() + 0.25f, LevelController.GetWidth() - 0.25f));
                }
                else
                {
                    // We just wandered off wherever, so make sure we walk back through a zone this time.
                    if (Random.Range(0, 2) == 0)
                    {
                        actor.target = new Vector3(Random.Range(LevelController.fMIN_X_COORD, Core.GetLevel().GetMeleeZoneLimit()), 0.0f, Random.Range(-LevelController.GetWidth() + 0.25f, LevelController.GetWidth() - 0.25f));
                    }
                    else
                    {
                        actor.target = new Vector3(Random.Range(Core.GetLevel().GetRangedZoneMin(), Core.GetLevel().GetRangedZoneMax()), 0.0f, Random.Range(-LevelController.GetWidth() + 0.25f, LevelController.GetWidth() - 0.25f));
                    }
                }

                actor.bPickedPositionInPlayerZone = !actor.bPickedPositionInPlayerZone;
            }
        }
        // Else, if we just reached a target, start waiting
        else if ((actor.transform.position - actor.target).sqrMagnitude < 0.1f * 0.1f)
        {
            actor.fTimeToNextMove = 2.0f;
            actor.render.SetAnimState(AnimState.IDLE, false);
        }
        // Otherwise, we must be moving to a target
        else
        {
            Vector3 move = actor.target - actor.transform.position;
            move.Normalize();
            move *= fMoveSpeed;
            actor.Move(move);
            actor.render.SetAnimState(AnimState.WALKING, false);
        }

        actor.fTimeToNextAura -= Core.GetEnemyDeltaTime();

        if (actor.auraPFX != null && actor.fTimeToNextAura <= 0.0f)
        {
            actor.fTimeToNextAura = Random.Range(fTimeBetweenSFXMin, fTimeBetweenSFXMax);
            actor.auraPFX.Trigger();
            if (soundEffect != null)
            {
                actor.soundEffect.PlayOneShot(soundEffect);
            }
        }
    }
 public override void AssignActorReferences(Actor newActor)
 {
     base.AssignActorReferences(newActor);
     _enemy      = GetBehaviour <Actor_Enemy>();
     _navigation = GetBehaviour <Actor_Navigation>();
     _health     = GetBehaviour <Actor_Health>();
     _hitbox.hitEvent.AddListener(GetHit);
 }
Example #6
0
    protected bool DealDamageToEnemy(Actor_Player player, Actor_Enemy enemy, Vector3 position, float fRadius)
    {
        float fMultiplier = player.GetAttackDamageMultiplier();

        if (position.x <= Core.GetLevel().GetMeleeZoneLimit())
        {
            fMultiplier += player.minion.GetBuff(Stat.DAMAGE_MULTIPLIER_IN_MELEE_ZONE);
        }

        if (enemy.IsStunned())
        {
            fMultiplier += player.minion.GetBuff(Stat.ATTACK_DAMAGE_ON_STUNNED_ENEMIES);
        }

        if (damage.IsRadial())
        {
            Core.GetLevel().DamageRadius(damage,
                                         position,
                                         damage.fRadius * player.GetAttackRadiusMultiplier(),
                                         fMultiplier,
                                         player.GetStunTime(),
                                         player.minion.GetBuff(Stat.CRITICAL_CHANCE),
                                         player.minion.GetBuff(Stat.CRITICAL_DAMAGE),
                                         player.minion.GetBuff(Stat.VAMPIRISM),
                                         player.minion.GetBuff(Stat.ATTACK_DAMAGE_ABSOLUTE));

            return(enemy == null || enemy.IsDead());
        }
        else if (enemy != null)
        {
            if (enemy.IsDead())
            {
                return(true);
            }

            float fElementalMultiplier = Elements.GetDamageMultiplier(damage.GetElement(), enemy.minion.template.element);
            float fMod = enemy.GetInherentElementalResistanceModifier();
            if (fElementalMultiplier < 1.0f)
            {
                fElementalMultiplier = 1.0f - ((1.0f - fElementalMultiplier) * fMod);
            }

            fMultiplier *= fElementalMultiplier;

            player.OnDealtDamage(damage.fAmount * fMultiplier);

            return(enemy.Damage(damage,
                                fMultiplier,
                                player.GetStunTime(),
                                player.minion.GetBuff(Stat.CRITICAL_CHANCE),
                                player.minion.GetBuff(Stat.CRITICAL_DAMAGE),
                                player.minion.GetBuff(Stat.VAMPIRISM),
                                player.minion.GetBuff(Stat.ATTACK_DAMAGE_ABSOLUTE)));
        }

        return(true);
    }
Example #7
0
    protected void RangedAttackPlayer(Actor_Enemy attacker, Damage damage, MinionSlot slot = MinionSlot.NUM_MINION_SLOTS)
    {
        float fDamageDealt = Core.GetCurrentRoster().RangedAttack(attacker, damage, slot);

        if (attacker != null)
        {
            attacker.OnDealtDamage(fDamageDealt);
        }
    }
Example #8
0
    public override void InitEnemy(Actor_Enemy actor)
    {
        base.InitEnemy(actor);

        if (auraPFX != null)
        {
            actor.auraPFX = Instantiate <PFX_SupportAura>(auraPFX);
            actor.auraPFX.transform.SetParent(actor.transform);
            actor.auraPFX.transform.localPosition = Vector3.zero;
        }

        actor.fTimeToNextAura = Random.Range(fTimeBetweenSFXMin, fTimeBetweenSFXMax);
    }
Example #9
0
    public Actor_Enemy GetClosestEnemyToMeleeZone()
    {
        float       fBestDistance = 100.0f;
        Actor_Enemy bestActor     = null;

        foreach (Actor_Enemy enemy in enemyActors)
        {
            if (enemy.transform.position.x < fBestDistance)
            {
                fBestDistance = enemy.transform.position.x;
                bestActor     = enemy;
            }
        }

        return(bestActor);
    }
Example #10
0
    public override void SimulatePlayerFixedUpdate(Actor_Player actor)
    {
        if (damage.fAmount > 0.0f || damage.fPushAmount > 0.0f)         // 0 means no attack
        {
            actor.fTimeSinceLastAttack += Core.GetPlayerDeltaTime();

            if (actor.currentTarget == null || actor.currentTarget.minion.fCurrentHealth <= 0.0f || !actor.currentTarget.IsInMeleeZone())
            {
                actor.currentTarget = null;

                // Find new target
                Actor_Enemy closestEnemy = Core.GetLevel().GetClosestEnemyToMeleeZone();
                if (closestEnemy != null && closestEnemy.IsInMeleeZone())
                {
                    actor.currentTarget = closestEnemy;
                }
                else
                {
                    // No valid target.
                }
            }

            int       iSlot    = actor.minion.slot == MinionSlot.MELEE_1 ? 0 : 1;
            Transform reticule = Core.GetLevel().instance.meleeTargets [iSlot];
            Transform radius   = Core.GetLevel().instance.meleeRadii [iSlot];

            if (actor.currentTarget != null)
            {
                reticule.gameObject.SetActive(true);
                reticule.position = Vector3.Lerp(reticule.position, actor.currentTarget.transform.position + new Vector3(0.0f, 0.04f, 0.0f), Core.GetPlayerDeltaTime() * actor.minion.template.reticuleMoveSpeed * actor.GetAttackSpeedMultiplier());
                float fRadius = damage.fRadius * actor.GetAttackRadiusMultiplier() * 2.0f;
                radius.localScale = new Vector3(fRadius, 1.0f, fRadius);

                if (TryToAttackEnemy(actor, actor.currentTarget))
                {
                    // We killed them
                    actor.currentTarget = null;
                }
            }
            else
            {
                //reticule.gameObject.SetActive(false);
            }
        }
    }
Example #11
0
    public Actor_Enemy GetClosestEnemyToRangedZone()
    {
        float fRangedZoneCentre = (GetRangedZoneMin() + GetRangedZoneMax()) / 2.0f;

        float       fBestDistance = 100.0f;
        Actor_Enemy bestActor     = null;

        foreach (Actor_Enemy enemy in enemyActors)
        {
            float fX = enemy.transform.position.x;

            float fDist = Mathf.Abs(fX - fRangedZoneCentre);
            if (fDist < fBestDistance)
            {
                fBestDistance = fDist;
                bestActor     = enemy;
            }
        }

        return(bestActor);
    }
Example #12
0
 public void EnemyDied(Actor_Enemy enemy)
 {
     foreach (Actor_Player player in playerActors)
     {
         if (player == null)
         {
             continue;
         }
         player.minion.template.TriggerBuff(BuffTrigger.ENEMY_DIED, null);
         if (player.minion.template.bDeathtoll)
         {
             player.minion.template.IncrementCombo(player);
         }
         if (enemy.IsInMeleeZone())             // Approximation
         {
             player.minion.template.TriggerBuff(BuffTrigger.ENEMY_DIED_TO_MELEE, null);
         }
     }
     enemyActors.Remove(enemy);
     aiNumKilledPerWave [enemy.iWave]++;
 }
Example #13
0
    protected Actor_Enemy GetBestTarget(Actor_Player firer, bool bNotInMeleeZone = false)
    {
        Actor_Player otherRangedMinion = Core.GetLevel().playerActors [firer.minion.slot == MinionSlot.RANGED_1 ? (int)MinionSlot.RANGED_2 : (int)MinionSlot.RANGED_1];


        Actor_Enemy bestCandidate = null;
        float       fBestScore    = 0.0f;

        foreach (Actor_Enemy enemy in Core.GetLevel().enemyActors)
        {
            if (enemy == null || enemy.IsDead() || enemy.bAboutToDie)
            {
                continue;
            }
            if (!enemy.IsInRangedZone())
            {
                continue;
            }
            if (enemy.IsInMeleeZone() && bNotInMeleeZone)
            {
                continue;
            }

            float fScore = GetScoreForCandidate(firer, enemy);
            if (enemy == otherRangedMinion.currentTarget)
            {
                fScore *= 0.5f;
            }

            if (fScore > fBestScore)
            {
                bestCandidate = enemy;
                fBestScore    = fScore;
            }
        }

        return(bestCandidate);
    }
Example #14
0
    public override void SimulateEnemyFixedUpdate(Actor_Enemy actor)
    {
        if (actor.IsFrozen() || actor.IsStunned())
        {
            return;
        }

        float fDistance = actor.transform.position.x - LevelController.fMIN_X_COORD;

        Vector3 diagonal = new Vector3(-1.0f, 0.0f, -0.25f * Mathf.Sign(actor.transform.position.z) / (fDistance + 1.0f));

        diagonal.Normalize();
        actor.Move(diagonal * fMoveSpeed);

        // Small delay to give player actors first strike and therefore allow zephyrs to push before damage
        if (actor.GetDistanceFromPlayerArea() <= fAttackRange && !actor.IsStunned() && actor.fTimeInMeleeZone > 0.1f)
        {
            // ---- ATTACK CODE ----
            actor.fTimeSinceLastAttack += Core.GetEnemyFixedDeltaTime();
            if (actor.fTimeSinceLastAttack >= fAttackInterval)
            {
                actor.fTimeSinceLastAttack = 0.0f;
                PlaySoundEffect(actor);

                for (int i = 0; i < numAttacks; i++)
                {
                    MeleeAttackPlayer(actor, damage);
                }
                actor.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);
            }
        }
        else
        {
            actor.render.SetAnimState(AnimState.WALKING, false);
        }
    }
 public override void SimulateEnemy(Actor_Enemy actor)
 {
 }
    public override void SimulatePlayerFixedUpdate(Actor_Player actor)
    {
        actor.fTimeSinceLastAttack += Core.GetPlayerDeltaTime();

        //if (actor.currentTarget == null || actor.currentTarget.minion.fCurrentHealth <= 0.0f)
        {
            // Find new target
            actor.currentTarget = GetBestTarget(actor);
        }

        if (actor.currentTarget != null)
        {
            int       iSlot    = actor.minion.slot == MinionSlot.RANGED_1 ? 0 : 1;
            Transform reticule = Core.GetLevel().instance.targets [iSlot];
            Transform radius   = Core.GetLevel().instance.radii [iSlot];
            reticule.gameObject.SetActive(true);
            reticule.position = Vector3.Lerp(reticule.position, actor.currentTarget.transform.position + new Vector3(0.0f, 0.04f, 0.0f), Core.GetPlayerDeltaTime() * actor.minion.template.reticuleMoveSpeed * actor.GetAttackSpeedMultiplier());
            radius.localScale = new Vector3(0.0f, 1.0f, 0.0f);

            if (!actor.currentTarget.IsInRangedZone())
            {
                actor.currentTarget = null;
            }
            else if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier())
            {
                actor.fTimeSinceLastAttack = 0.0f;

                List <Vector3> pfxPositions = new List <Vector3> ();
                pfxPositions.Add(actor.transform.position + new Vector3(0.0f, fProjectileLaunchHeight, 0.0f));

                List <Actor_Enemy> alreadyHit    = new List <Actor_Enemy> ();
                Actor_Enemy        currentTarget = actor.currentTarget;
                float fChainRemaining            = iChain * actor.GetChainCountMultiplier();

                PlaySoundEffect(actor);

                while (fChainRemaining > 0.0f)
                {
                    DealDamageToEnemy(actor, currentTarget, currentTarget.transform.position, 0.0f);
                    if (currentTarget.HasWaterDebuff())
                    {
                        fChainRemaining -= 0.5f;
                    }
                    else
                    {
                        fChainRemaining -= 1.0f;
                    }

                    alreadyHit.Add(currentTarget);

                    // Add a line
                    Vector3 prevPos = pfxPositions [pfxPositions.Count - 1];
                    Vector3 newPos  = currentTarget.transform.position + new Vector3(0.0f, fProjectileLaunchHeight, 0.0f);
                    Vector3 dPos    = newPos - prevPos;
                    float   fLength = dPos.magnitude;
                    // If it is longer than 2 units, split it into segments
                    if (fLength >= 2.0f)
                    {
                        dPos.Normalize();
                        int numSegments = Mathf.FloorToInt(fLength / 2.0f);
                        for (int i = 0; i < numSegments; i++)
                        {
                            Vector3 pos    = prevPos + dPos * 2.0f * (i + 1);
                            Vector3 offset = Random.onUnitSphere;
                            offset.y = 0.0f;
                            pos     += offset;
                            pfxPositions.Add(pos);
                        }
                    }

                    pfxPositions.Add(newPos);

                    Actor_Enemy bestCandidate = null;
                    float       fBestDistance = fMaxChainGap * actor.GetChainGapMultiplier();
                    foreach (Actor_Enemy enemy in Core.GetLevel().enemyActors)
                    {
                        if (enemy != null && !alreadyHit.Contains(enemy))
                        {
                            float fDist = (currentTarget.transform.position - enemy.transform.position).magnitude;

                            if (fDist < fBestDistance)
                            {
                                fBestDistance = fDist;
                                bestCandidate = enemy;
                            }
                        }
                    }
                    if (bestCandidate == null)
                    {
                        break;
                    }

                    currentTarget = bestCandidate;
                }

                actor.render.SetChainPFXActive(fChainPFXDuration, pfxPositions.ToArray());
                actor.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);
            }
        }
    }
    public override void SimulateEnemyFixedUpdate(Actor_Enemy actor)
    {
        if (actor.IsFrozen() || actor.IsStunned())
        {
            return;
        }

        actor.fTimeSinceLastAttack += Core.GetPlayerDeltaTime();

        float fMin = Core.GetLevel().GetRangedZoneMin();         //GetTargetRangeMin();
        float fMax = Core.GetLevel().GetRangedZoneMax();         //GetTargetRangeMax();

        fMax -= (fMax - fMin) * 0.25f;

        bool bInRange = fMin <= actor.transform.position.x && actor.transform.position.x <= fMax;

        if (bInRange)
        {
            if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier())
            {
                actor.fTimeSinceLastAttack = 0.0f;

                PlaySoundEffect(actor);

                // Zap both player ranged characters
                RangedAttackPlayer(actor, damage, MinionSlot.RANGED_1);
                RangedAttackPlayer(actor, damage, MinionSlot.RANGED_2);

                List <Vector3> pfxPositions = new List <Vector3> ();
                pfxPositions.Add(actor.transform.position + new Vector3(0.0f, fProjectileLaunchHeight, 0.0f));

                int firstHit = Random.Range(0, 2);

                // Add a line
                Vector3      prevPos         = pfxPositions [pfxPositions.Count - 1];
                Actor_Player firstPlayerHit  = Core.GetLevel().playerActors[(int)MinionSlot.RANGED_1 + firstHit];
                Actor_Player secondPlayerHit = Core.GetLevel().playerActors[(int)MinionSlot.RANGED_1 + (1 - firstHit)];
                Vector3      newPos          = firstPlayerHit.transform.position + new Vector3(0.0f, fProjectileLaunchHeight, 0.0f);
                Vector3      dPos            = newPos - prevPos;
                float        fLength         = dPos.magnitude;
                // If it is longer than 2 units, split it into segments
                if (fLength >= 2.0f)
                {
                    dPos.Normalize();
                    int numSegments = Mathf.FloorToInt(fLength / 2.0f);
                    for (int i = 0; i < numSegments; i++)
                    {
                        Vector3 pos    = prevPos + dPos * 2.0f * (i + 1);
                        Vector3 offset = Random.onUnitSphere;
                        offset.y = 0.0f;
                        pos     += offset;
                        pfxPositions.Add(pos);
                    }
                }
                pfxPositions.Add(firstPlayerHit.transform.position);
                pfxPositions.Add(secondPlayerHit.transform.position);

                actor.render.SetChainPFXActive(fChainPFXDuration, pfxPositions.ToArray());
                actor.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);
            }
            else if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier() * 0.5f)
            {
                float fSpeed = fMoveSpeed;
                if (actor.transform.position.x - fMin < 1.0f)
                {
                    fSpeed *= (actor.transform.position.x - fMin);
                }

                actor.Move(new Vector3(-fSpeed, 0.0f, 0.0f));
                actor.render.SetAnimState(AnimState.WALKING, false);
            }
        }
        else
        {
            actor.Move(new Vector3(-fMoveSpeed, 0.0f, 0.0f));
            actor.render.SetAnimState(AnimState.WALKING, false);
        }
    }
Example #18
0
    public override void SimulateEnemyFixedUpdate(Actor_Enemy actor)
    {
        if (actor.fTargetX == 0.0f)
        {
            actor.fTargetX = Random.Range(Core.GetLevel().GetRangedZoneMin(), Core.GetLevel().GetRangedZoneMax());
        }

        if (actor.IsStunned() || actor.IsFrozen())
        {
            return;
        }

        actor.fTimeSinceLastAttack += Core.GetPlayerDeltaTime();

        float fMin = actor.fTargetX;
        float fMax = Core.GetLevel().GetRangedZoneMax();

        fMax -= (fMax - fMin) * 0.25f;

        bool bInRange = actor.transform.position.x <= fMax;

        if (bInRange)
        {
            actor.render.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f);
            if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier())
            {
                actor.fTimeSinceLastAttack = 0.0f;
                // Spawn a projectile
                for (int i = 0; i < numAttacks; i++)
                {
                    Projectile projectile = Instantiate <Projectile>(projectilePrefab);
                    projectile.firer              = actor;
                    projectile.firerTemplate      = this;
                    projectile.launchPos          = actor.transform.position + new Vector3(0.5f * i, fProjectileLaunchHeight, 0.0f);
                    projectile.fProgress          = i * 0.1f;
                    projectile.target             = Core.GetLevel().GetRangedTarget();
                    projectile.transform.position = projectile.launchPos;
                }

                PlaySoundEffect(actor);

                actor.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);
            }
            else if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier() * 0.5f)
            {
                float fSpeed = fMoveSpeed;
                if (actor.transform.position.x - fMin < 1.0f)
                {
                    fSpeed *= (actor.transform.position.x - fMin);
                }

                // Cap backwards speed to prevent magnetic bugs being useless
                if (fSpeed < 0.0f)
                {
                    fSpeed = -1.0f;
                }

                actor.Move(new Vector3(-fSpeed, 0.0f, 0.0f));
                actor.render.SetAnimState(AnimState.WALKING, false);
                actor.render.transform.localScale = new Vector3(fSpeed > 0.0f ? 1.0f : -1.0f, 1.0f, 1.0f);
            }
        }
        else
        {
            actor.Move(new Vector3(-fMoveSpeed, 0.0f, 0.0f));
            actor.render.SetAnimState(AnimState.WALKING, false);
        }
    }
Example #19
0
    private float Attack(Actor_Enemy attacker, Damage damage, float fMod, MinionSlotType slotType, MinionSlot slot)
    {
        float fTotalDealt = 0.0f;

        float fDamage = damage.fAmount * fMod;

        if (fDamage > 0.0f)
        {
            float fTotalMultiplierFromMinions = 0.0f;
            for (int i = 0; i < slotType.GetNumSlots(); i++)
            {
                Minion minion = minions [(int)slotType.GetFirst() + i];
                if (minion != null)
                {
                    float fBuffModifier = minion.GetBuff(Stats.GetStatForDamageMultiplier(damage.GetElement()));
                    fBuffModifier += minion.GetBuff(Stat.DAMAGE_MULTIPLIER);
                    fBuffModifier += minion.GetBuff(slotType == MinionSlotType.MELEE ? Stat.DAMAGE_MULTIPLIER_MELEE : Stat.DAMAGE_MULTIPLIER_RANGED);
                    fBuffModifier += minion.GetBuff(Stat.DAMAGE_MULTIPLIER_PER_COMBO) * minion.iCombo;

                    fTotalMultiplierFromMinions += (1.0f + fBuffModifier) * Elements.GetDamageMultiplier(damage.GetElement(), minion.template.element);
                }
                else
                {
                    fTotalMultiplierFromMinions += 1.0f;
                }
            }
            float fAverageMinionMultiplier = fTotalMultiplierFromMinions / slotType.GetNumSlots();
            fDamage *= fAverageMinionMultiplier;

            fDamage *= (1.0f + Mathf.Clamp(damage.fRadius, 0.0f, 5.0f));
            if (attacker != null && attacker.minion.template.canCombo)
            {
                fDamage *= 3.0f;
            }

            float fDamageToDeal = Mathf.Min(afGroupHealths [(int)slotType], fDamage);
            if (fDamageToDeal > 0.0f)
            {
                float fParametricHealthPreDamage = afGroupHealths[(int)slotType] / afGroupMaxHealths[(int)slotType];
                afGroupHealths [(int)slotType] -= fDamageToDeal;

                float fParametricHealthPostDamage = afGroupHealths[(int)slotType] / afGroupMaxHealths[(int)slotType];
                if (!bHasTriggeredVolatileYet && fParametricHealthPreDamage > 0.25f && fParametricHealthPostDamage <= 0.25f)
                {
                    bHasTriggeredVolatileYet = true;
                    for (int i = 0; i < slotType.GetNumSlots(); i++)
                    {
                        if (minions [(int)slotType.GetFirst() + i].template.bVolatile)
                        {
                            // TODO: Play PFX
                            // Play sound
                            Core.GetLevel().KillAllEnemies();
                        }
                    }
                }

                // Do damage numbers
                Actor_Player actorHit = null;
                if (slot == MinionSlot.NUM_MINION_SLOTS)
                {
                    actorHit = Core.GetLevel().playerActors [(int)slotType.GetFirst() + Random.Range(0, slotType.GetNumSlots())];
                }
                else
                {
                    actorHit = Core.GetLevel().playerActors [(int)slot];
                }
                if (actorHit != null)
                {
                    int iDamage = Mathf.FloorToInt(fDamage);
                    actorHit.MakeDamageNumbers(iDamage, Core.GetMinionTemplateManager().playerDamage);
                }

                if (afGroupHealths [(int)slotType] <= 0.0f)
                {
                    KillGroup(slotType);
                }
                fDamage     -= fDamageToDeal;
                fTotalDealt += fDamageToDeal;

                Core.GetLevel().bHasSomeDamageBeenTaken = true;
            }
        }

        return(fTotalDealt);
    }
Example #20
0
 public float RangedAttack(Actor_Enemy attacker, Damage damage, MinionSlot slot)
 {
     mostRecentRangedAttacker = attacker;
     return(Attack(attacker, damage, fRangedIncomingDamageModifier, MinionSlotType.RANGED, slot));
 }
Example #21
0
 public float MeleeAttack(Actor_Enemy attacker, Damage damage, MinionSlot slot)
 {
     return(Attack(attacker, damage, fMeleeIncomingDamageModifier, MinionSlotType.MELEE, slot));
 }
Example #22
0
 public abstract void SimulateEnemy(Actor_Enemy actor);
Example #23
0
 public abstract void SimulateEnemyFixedUpdate(Actor_Enemy actor);
    public override void SimulateEnemyFixedUpdate(Actor_Enemy actor)
    {
        actor.fTimeSinceLastAttack += Core.GetPlayerDeltaTime();

        float fMin = Core.GetLevel().GetRangedZoneMin();         //GetTargetRangeMin();
        float fMax = Core.GetLevel().GetRangedZoneMax();         //GetTargetRangeMax();

        fMax -= (fMax - fMin) * 0.25f;

        if (actor.targetSlot == MinionSlot.NUM_MINION_SLOTS)
        {
            actor.targetSlot = (MinionSlot)((int)MinionSlotType.RANGED.GetFirst() + Random.Range(0, MinionSlotType.RANGED.GetNumSlots()));
        }

        if (bLoopingSoundEffect && !actor.soundEffect.isPlaying)
        {
            actor.soundEffect.loop = true;
            actor.soundEffect.clip = soundEffect;
            actor.soundEffect.Play();
        }

        if (actor.summon == null)
        {
            // TODO : Do spawn PFX
            actor.summon = Instantiate <RenderActor>(summonPrefab);
            actor.summon.transform.position = actor.transform.position;

            if (summonEffect != null)
            {
                summonEffect.Play();
            }
        }

        if (actor.summon != null && Core.GetLevel().playerActors [(int)actor.targetSlot] != null)
        {
            Vector3 targetPos = Core.GetLevel().playerActors [(int)actor.targetSlot].transform.position;
            targetPos.y += fSummonHeight;
            actor.summon.transform.position = Vector3.Lerp(actor.summon.transform.position, targetPos, Core.GetEnemyDeltaTime() * reticuleMoveSpeed);
        }

        bool bInRange = fMin <= actor.transform.position.x && actor.transform.position.x <= fMax;

        if (bInRange)
        {
            if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier())
            {
                actor.fTimeSinceLastAttack = 0.0f;

                RangedAttackPlayer(actor, damage, actor.targetSlot);

                if (!bLoopingSoundEffect)
                {
                    PlaySoundEffect(actor);
                }

                actor.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);

                // Pick a new target slot for the next attack
                actor.targetSlot = (MinionSlot)((int)MinionSlotType.RANGED.GetFirst() + Random.Range(0, MinionSlotType.RANGED.GetNumSlots()));
            }
            else if (actor.fTimeSinceLastAttack >= fAttackInterval * actor.GetAttackSpeedMultiplier() * 0.5f)
            {
                float fSpeed = fMoveSpeed;
                if (actor.transform.position.x - fMin < 1.0f)
                {
                    fSpeed *= (actor.transform.position.x - fMin);
                }

                actor.Move(new Vector3(-fSpeed, 0.0f, 0.0f));
                actor.render.SetAnimState(AnimState.WALKING, false);
            }
        }
        else
        {
            actor.Move(new Vector3(-fMoveSpeed, 0.0f, 0.0f));
            actor.render.SetAnimState(AnimState.WALKING, false);
        }
    }
Example #25
0
 public virtual void OnDeath(Actor_Enemy actor)
 {
 }
Example #26
0
 public virtual void InitEnemy(Actor_Enemy actor)
 {
     Init();
 }
 public override void OnDeath(Actor_Enemy actor)
 {
     actor.summon.PlayDeathAnimation();
     actor.summon = null;
 }
Example #28
0
    public override void SimulateEnemyFixedUpdate(Actor_Enemy actor)
    {
        // Wurm acts like a support, but teleports between spots. Go stand in a player zone, leave it, stand in it, repeat
        if (actor.IsFrozen() || actor.IsStunned())
        {
            return;
        }

        actor.fTimeSinceLastAttack += Core.GetEnemyDeltaTime();
        if (actor.GetDistanceFromPlayerArea() <= fAttackRange && actor.fTimeSinceLastAttack >= fAttackInterval)
        {
            // ---- ATTACK CODE ----
            if (actor.fTimeSinceLastAttack >= fAttackInterval)
            {
                PlaySoundEffect(actor);

                actor.fTimeSinceLastAttack = 0.0f;
                MeleeAttackPlayer(actor, damage, MinionSlot.MELEE_1);
                MeleeAttackPlayer(actor, damage, MinionSlot.MELEE_2);
                RangedAttackPlayer(actor, damage, MinionSlot.RANGED_1);
                RangedAttackPlayer(actor, damage, MinionSlot.RANGED_2);
                actor.render.SetAnimStateAndNext(AnimState.ATTACK, AnimState.IDLE);
                if (actor.render.attackParticles != null)
                {
                    actor.render.attackParticles.Play();
                }
            }
        }
        // If we are waiting, do that.
        else if (actor.fTimeToNextMove > 0.0f)
        {
            actor.fTimeToNextMove -= Core.GetEnemyDeltaTime();
            if (actor.fTimeToNextMove <= 0.0f && actor.render.GetAnimState() != AnimState.ATTACK)
            {
                if (actor.bPickedPositionInPlayerZone)
                {
                    // Last pick was in a zone, so wherever is fine this time.
                    actor.target = new Vector3(Random.Range(LevelController.fMIN_X_COORD, Core.GetLevel().GetRangedZoneMax() + 3.0f), 0.0f, Random.Range(LevelController.fMIN_Z_COORD, LevelController.fMAX_Z_COORD));
                }
                else
                {
                    // We just wandered off wherever, so make sure we walk back through a zone this time.
                    if (Random.Range(0, 2) == 0)
                    {
                        actor.target = new Vector3(Random.Range(LevelController.fMIN_X_COORD, Core.GetLevel().GetMeleeZoneLimit()), 0.0f, Random.Range(LevelController.fMIN_Z_COORD, LevelController.fMAX_Z_COORD));
                    }
                    else
                    {
                        actor.target = new Vector3(Random.Range(Core.GetLevel().GetRangedZoneMin(), Core.GetLevel().GetRangedZoneMax()), 0.0f, Random.Range(LevelController.fMIN_Z_COORD, LevelController.fMAX_Z_COORD));
                    }
                }

                actor.bPickedPositionInPlayerZone = !actor.bPickedPositionInPlayerZone;

                actor.render.SetAnimStateAndNext(AnimState.WALKING, AnimState.IDLE);
                if (actor.render.moveParticles != null)
                {
                    actor.render.moveParticles.Play();
                }
            }
        }
        // Else, we made it to idle, so teleport and re-emerge by playing a reverse walk
        else if (actor.render.GetAnimState() == AnimState.IDLE)
        {
            actor.Move(actor.target - actor.transform.position, true);
            actor.render.SetAnimStateAndNext(AnimState.WALKING, AnimState.IDLE);
            actor.render.SetReverse(true);
            actor.fTimeToNextMove = 2.0f;
        }
    }