Exemple #1
0
        void SpawnEnemy()
        {
            Objects.Enemy e = new Objects.Enemy(m_Game, Balance.Waves[m_WaveNumber - 1].Level);
            SpawnGameObject(e);
            m_Enemies.Add(e);

            m_EnemiesThisWave--;
            // Stop spawning once we hit the limit
            if (m_EnemiesThisWave == 0)
            {
                m_Timer.RemoveTimer("SpawnEnemy");
            }
        }
Exemple #2
0
        // Find the closest enemy that's within range
        public Objects.Enemy GetClosestEnemyInRange(Vector3 vPosition, float fRange)
        {
            float fClosest = fRange + 1.0f;

            Objects.Enemy retVal = null;

            foreach (Objects.Enemy e in m_Enemies)
            {
                float fDist = Vector3.Distance(vPosition, e.Position);
                if (fDist < fClosest)
                {
                    retVal   = e;
                    fClosest = fDist;
                }
            }

            return(retVal);
        }
Exemple #3
0
        public void RemoveEnemy(Objects.Enemy e, bool bGiveMoney = false)
        {
            RemoveGameObject(e, true);
            m_Enemies.Remove(e);

            // Give them the well deserved money
            if (bGiveMoney)
            {
                Money += Balance.Enemies[e.Level - 1].Money;
            }

            // If there are no enemies left, the wave is over
            if (m_EnemiesThisWave == 0 && m_Enemies.Count == 0)
            {
                m_bWaveActive = false;
                // If we just finished the last wave, VICTORY!!
                if (m_WaveNumber == Balance.TotalWaves)
                {
                    GameOver(true);
                }
                else
                {
                    // If the next wave will have stronger enemies, give a warning
                    if (Balance.Waves[m_WaveNumber].Level == Balance.MaxEnemyLevel)
                    {
                        m_UIGameplay.ShowStatusMessage(Localization.Get().Text("ui_msg_boss"), 2.5f);
                        SoundManager.Get().PlaySoundCue("Alarm");
                    }
                    else if (Balance.Waves[m_WaveNumber].Level > Balance.Waves[m_WaveNumber - 1].Level)
                    {
                        m_UIGameplay.ShowStatusMessage(Localization.Get().Text("ui_msg_enemiesstronger"), 2.5f);
                        SoundManager.Get().PlaySoundCue("Alarm");
                    }
                    else
                    {
                        m_UIGameplay.ShowStatusMessage(Localization.Get().Text("ui_msg_waveover"), 2.5f);
                        SoundManager.Get().PlaySoundCue("Victory");
                    }
                    m_Timer.AddTimer("StartWave", Balance.Waves[m_WaveNumber - 1].NextWaveTime, StartWave, false);
                }
            }
        }
Exemple #4
0
 protected void SnareEnemy(Enemy e)
 {
     // We want to snare for a little bit longer than the reload time
     e.Snare(m_TowerData[m_Level - 1].Damage, m_TowerData[m_Level - 1].ReloadTime + 0.1f);
 }
        // Computes the enemy path using A*
        // Returns true if there is a valid path, false if not.
        // If the optional parameter is NOT set, it sets the global path that all enemies use by default
        // otherwise, this function calculates the path only for the passed in Enemy.
        // This is to allow recalculation of paths for currently active Enemiess.
        public bool ComputeAStar(Objects.Enemy e = null)
        {
            // Clear out the open/closed set from previous paths
            m_OpenSet.Clear();
            m_ClosedSet.Clear();

            Objects.Tile StartTile = GlobalStartTile;
            // If we have a specific Enemy, the starting tile is the one the Enemy is currently at
            if (e != null)
            {
                StartTile = e.CurrentTile;
            }

            // We start at the goal node instead of the start node
            // so that the parent linked list does not need to be reversed once the A* is complete.
            PathNode node = new PathNode();

            node.tile = GlobalGoalTile;
            node.g    = 0.0f;
            node.h    = 0.0f;
            node.f    = 0.0f;

            // Initialize the A* algorithm
            PathNode CurrentNode = node;

            m_ClosedSet.Add(CurrentNode.tile, CurrentNode);

            do
            {
                // Loop through all the nodes adjacent to the current one
                foreach (Objects.Tile t in CurrentNode.tile.m_Neighbors)
                {
                    // Is this tile already in the closed set?
                    if (m_ClosedSet.ContainsKey(t))
                    {
                        // If so, skip.
                        continue;
                    }
                    else if (m_OpenSet.ContainsKey(t))
                    {
                        // Check if node adoption should occur
                        float test_g = CurrentNode.g + Vector3.Distance(t.Position, CurrentNode.tile.Position);

                        // Is the new g(x) value lower than the current one?
                        node = m_OpenSet[t];
                        if (test_g < node.g)
                        {
                            // If so, change parent
                            node.parent = CurrentNode;
                            node.g      = test_g;
                            node.f      = node.g + node.h;
                        }
                    }
                    // Tiles with a building are not passable, so should be ignored...
                    // UNLESS it's the start node, which can happen if this is a Enemy repositioning
                    else if (t.Tower == null || t == StartTile)
                    {
                        // Add a new PathNode to open set with CurrentNode as parent
                        node        = new PathNode();
                        node.parent = CurrentNode;
                        node.tile   = t;

                        // Calculate h(x) using Euclidean distance
                        node.h = Vector3.Distance(GlobalGoalTile.Position, t.Position);

                        // Calculate g(x)
                        node.g = node.parent.g + Vector3.Distance(t.Position, node.parent.tile.Position);

                        // f(x) =  g(x) + h(x)
                        node.f = node.g + node.h;

                        // Add to open set
                        m_OpenSet.Add(t, node);
                    }
                }

                // If the open set is empty, we failed to find a path
                if (m_OpenSet.Count == 0)
                {
                    break;
                }

                // Search the open set for lowest f(x) cost
                float lowest_f = 10000000000.0f;
                foreach (PathNode p in m_OpenSet.Values)
                {
                    if (p.f < lowest_f)
                    {
                        CurrentNode = p;
                        lowest_f    = p.f;
                    }
                }

                // Move CurrentNode to closed set
                m_OpenSet.Remove(CurrentNode.tile);
                m_ClosedSet.Add(CurrentNode.tile, CurrentNode);
            }while (CurrentNode.tile != StartTile);

            // Check to see if we found a path
            if (CurrentNode.tile == StartTile)
            {
                // Set the start of the path to the current node
                // If there is no Enemy, this is the new global path
                if (e == null)
                {
                    GlobalPath = CurrentNode;
                }
                else
                {
                    e.m_Path = CurrentNode;
                    e.ResetPath(true);
                }

                return(true);
            }
            else
            {
                // If there is no Enemy, this is the new global path
                if (e == null)
                {
                    GlobalPath = null;
                }
                else
                {
                    e.m_Path = null;
                    e.ResetPath(true);
                }
                return(false);
            }
        }