Ejemplo n.º 1
0
        // Natural Disaster That Damages Buildings
        private void CreateEarthquake(ImpactRegion r)
        {
            List <LightningParticle> particles = new List <LightningParticle>();

            foreach (var ic in r.Cells)
            {
                Point c = new Point(ic.X * 2, ic.Y * 2);
                for (int x = 0; x < 2 && c.X + x < GameState.CGrid.numCells.X; x++)
                {
                    for (int y = 0; y < 2 && c.Y + y < GameState.CGrid.numCells.Y; y++)
                    {
                        RTSBuilding b = GameState.CGrid.EStatic[c.X + x, c.Y + y];
                        if (b != null && b.Team.Index != Team.Index)
                        {
                            bool takeDamage = (random.Next(100) <= EarthquakeHitP);
                            if (true)
                            {
                                b.Damage(EarthquakeDamage);
                                bool canSee = GameState.CGrid.GetFogOfWar(b.GridPosition, playerIndex) == FogOfWar.Active;
                                if (canSee)
                                {
                                    particles.Add(new LightningParticle(b.WorldPosition, 3, 10, 2, 0.6f, 1, Color.Red));
                                }
                            }
                        }
                    }
                }
            }
            GameState.AddParticles(particles);
        }
Ejemplo n.º 2
0
 public void OnBuildingSpawn(RTSBuilding b)
 {
     //DevConsole.AddCommand("added barracks");
     barracksControllers.Add(new BarracksController(this, b));
     Team.Buildings.Add(b);
     b.OnDestruction += OnBuildingDestruction;
 }
Ejemplo n.º 3
0
        public EnemyBuildingUpdater(GameState s, int tIndex, ViewedBuilding _vb, RTSBuilding b)
            : base(1)
        {
            state     = s;
            teamIndex = tIndex;
            Added     = false;
            isDead    = false;
            vb        = _vb;
            building  = b;

            if (b != null)
            {
                b.OnDestruction += OnBuildingDeath;
            }
            else
            {
                isDead = true;
            }

            RTSBuildingData data = state.teams[vb.Team].Race.Buildings[vb.Type];

            grids = new Point[data.GridSize.X * data.GridSize.Y];
            Point p  = vb.CellPoint;
            int   pi = 0;

            for (int y = 0; y < data.GridSize.Y; y++)
            {
                for (int x = 0; x < data.GridSize.X; x++)
                {
                    grids[pi++] = new Point(p.X + x, p.Y + y);
                }
            }
        }
Ejemplo n.º 4
0
        public void OnBuildingDestruction(IEntity b)
        {
            //DevConsole.AddCommand("building destroyed");
            BarracksController destroyed = null;

            foreach (var bc in barracksControllers)
            {
                if (bc.barracks.UUID == b.UUID)
                {
                    destroyed = bc;
                }
            }
            if (destroyed != null)
            {
                foreach (var u in destroyed.army)
                {
                    u.OnDestruction += OnUnitDeath;
                }
                foreach (var u in destroyed.sentArmy)
                {
                    u.OnDestruction += OnUnitDeath;
                }
                if (destroyed.active)
                {
                    numActive--;
                }
                destroyed.Dispose();
                barracksControllers.Remove(destroyed);
            }
            RTSBuilding bb = b as RTSBuilding;

            Team.Buildings.Remove(bb);
        }
Ejemplo n.º 5
0
        public static EnemyBuildingUpdater Deserialize(BinaryReader s, GameState state)
        {
            int            ti = s.ReadInt32();
            ViewedBuilding vb = new ViewedBuilding();

            vb.Team          = s.ReadInt32();
            vb.Type          = s.ReadInt32();
            vb.CellPoint     = s.ReadPoint();
            vb.WorldPosition = s.ReadVector3();
            vb.ViewDirection = s.ReadVector2();
            int         uuid = s.ReadInt32();
            RTSBuilding b    = null;

            foreach (var building in state.teams[vb.Team].Buildings)
            {
                if (building.UUID == uuid)
                {
                    b = building;
                    break;
                }
            }
            EnemyBuildingUpdater ebu = new EnemyBuildingUpdater(state, ti, vb, b);

            ebu.Added  = s.ReadBoolean();
            ebu.isDead = s.ReadBoolean();
            if (ebu.Added)
            {
                state.teams[ebu.teamIndex].ViewedEnemyBuildings.Add(vb);
            }
            return(ebu);
        }
Ejemplo n.º 6
0
        private void OnBuildingDamage(IEntity e, int d)
        {
            RTSBuilding building = e as RTSBuilding;
            int         imp      = building.Data.Impact * d;

            grid.AddImpact(e.GridPosition, imp);
            //DevConsole.AddCommand("Impact Added " + imp);
        }
Ejemplo n.º 7
0
 public BarracksController(AI input, RTSBuilding b)
 {
     army          = new List <IEntity>();
     sentArmy      = new List <IEntity>();
     AIInput       = input;
     barracks      = b;
     currentTarget = null;
     active        = false;
 }
Ejemplo n.º 8
0
    private void beginToBuildTheBuilding(Vector3 pos)
    {
        RTSBuilding  gameUnit = PrefabFactory.ShareInstance.createClone <RTSBuilding>(@"3rdPartyAssetPackage/Bitgem_RTS_Pack/Human_Buildings/Prefabs/house", pos, Quaternion.identity);
        MeshCollider collider = gameUnit.gameObject.AddComponent <MeshCollider>();

        collider.convex = true;
        //collider.isTrigger = true;
        //
    }
Ejemplo n.º 9
0
        private int ClosestBuilding(RTSBuilding b1, RTSBuilding b2)
        {
            BoundingBox bb1 = b1.BBox;
            BoundingBox bb2 = b2.BBox;
            float       d1  = (0.5f * (bb1.Max + bb1.Min) - Camera.CamOrigin).LengthSquared();
            float       d2  = (0.5f * (bb2.Max + bb2.Min) - Camera.CamOrigin).LengthSquared();

            return(d1.CompareTo(d2));
        }
Ejemplo n.º 10
0
 public virtual void SetBuilding(RTSBuilding b)
 {
     if (b == null)
     {
         return;
     }
     if (building != null)
     {
         throw new ArgumentException("Cannot Rebind This Controller To Another Building");
     }
     building = b;
     return;
 }
Ejemplo n.º 11
0
        public void Add(RTSBuilding b)
        {
            b.OnDestruction += OnBuildingDestruction;

            // Add To All The Cells
            Point p = HashHelper.Hash(b.GridStartPos, numCells, size);

            for (int y = 0; y < b.Data.GridSize.Y; y++)
            {
                for (int x = 0; x < b.Data.GridSize.X; x++)
                {
                    EStatic[p.X + x, p.Y + y] = b;
                }
            }
        }
Ejemplo n.º 12
0
 protected override void OnSetTargetUnit(RTSGameUnit unit)
 {
     base.OnSetTargetUnit(unit);
     //
     if (isWorking)
     {
         stopWork();
     }
     //
     if (unit is RTSResource)
     {
         //
         if (IsMiningHarvestedFull)
         {
             startReturning();
             //
         }
         else
         {
             goMine();
         }
         //
     }
     else if (unit is RTSBuilding)
     {
         RTSBuilding building = (RTSBuilding)unit;
         //
         if (miningAchievement > 0 && homeBuilding != null && building == homeBuilding)
         {
             startReturning();
         }
         else
         {
             //
             if (building.IsNeedRepair)
             {
                 goRepair();
             }
             else
             {
                 goMine();
             }
             //
         }
     }
     //
     move(unit.transform.position);
 }
Ejemplo n.º 13
0
        public void UpdateSelections(out VertexPositionColorTexture[] verts, out int[] inds)
        {
            // Check If We Need To Render Any Selected Entities
            if (teamInput.selected.Count < 1)
            {
                verts = null;
                inds  = null;
                return;
            }

            // Build The Selections
            verts = new VertexPositionColorTexture[teamInput.selected.Count * 4];
            int i    = 0;
            var sarr = teamInput.selected.ToArray();

            foreach (var e in sarr)
            {
                Vector2 c = e.GridPosition;
                float   r = e.CollisionGeometry.BoundingRadius * SELECTION_RADIUS_MODIFIER;
                float   h = e.Height;
                h += (e.BBox.Max.Y - e.BBox.Min.Y) * SELECTION_HEIGHT_PLACEMENT;

                // No Visualizing Unbuilt Buildings
                RTSBuilding eb = e as RTSBuilding;
                if (eb != null && eb.BuildAmountLeft > 0)
                {
                    continue;
                }

                Color cHealth = Color.Lerp(HEALTH_EMPTY_COLOR, HEALTH_FULL_COLOR, e.GetHealthRatio());
                verts[i++] = new VertexPositionColorTexture(new Vector3(c.X - r, h, c.Y - r), cHealth, Vector2.Zero);
                verts[i++] = new VertexPositionColorTexture(new Vector3(c.X + r, h, c.Y - r), cHealth, Vector2.UnitX);
                verts[i++] = new VertexPositionColorTexture(new Vector3(c.X - r, h, c.Y + r), cHealth, Vector2.UnitY);
                verts[i++] = new VertexPositionColorTexture(new Vector3(c.X + r, h, c.Y + r), cHealth, Vector2.One);
            }

            inds = new int[(verts.Length * 3) / 2];
            for (int vi = 0, ii = 0; vi < verts.Length;)
            {
                inds[ii++] = vi + 0;
                inds[ii++] = vi + 1;
                inds[ii++] = vi + 2;
                inds[ii++] = vi + 2;
                inds[ii++] = vi + 1;
                inds[ii++] = vi + 3;
                vi        += 4;
            }
        }
Ejemplo n.º 14
0
        public void OnBuildingDestruction(IEntity o)
        {
            o.OnDestruction -= OnBuildingDestruction;
            RTSBuilding b = o as RTSBuilding;

            // Add To All The Cells
            Point p = HashHelper.Hash(b.GridStartPos, numCells, size);

            for (int y = 0; y < b.Data.GridSize.Y; y++)
            {
                for (int x = 0; x < b.Data.GridSize.X; x++)
                {
                    EStatic[p.X + x, p.Y + y] = null;
                }
            }
        }
Ejemplo n.º 15
0
        public override void Init(RTSEngine.Data.GameState s, RTSEngine.Controllers.GameplayController c, object args)
        {
            cc = unit.CombatController;
            mc = unit.MovementController;

            unit.TargetingOrders = BehaviorFSM.TargetPassively;
            unit.CombatOrders    = BehaviorFSM.UseMeleeAttack;
            unit.MovementOrders  = BehaviorFSM.JustMove;
            SetState(BehaviorFSM.Rest);

            teamIndex = unit.Team.Index;

            // Worker Specific Stuff
            targetResource = null;
            targetDistro   = null;
            depositing     = false;
        }
Ejemplo n.º 16
0
        private void ApplyInput(GameState s, float dt, SpawnBuildingEvent e)
        {
            RTSTeam team = s.teams[e.Team];

            // Check If We Can Add A Building There
            Vector2 wp = new Vector2(e.GridPosition.X + 0.5f, e.GridPosition.Y + 0.5f) * s.CGrid.cellSize;

            if (!s.CGrid.CanAddBuilding(wp, team.Race.Buildings[e.Type].GridSize))
            {
                return;
            }

            RTSBuilding building = team.AddBuilding(e.Type, wp);

            if (building == null)
            {
                return;
            }

            // Check For Instant Building
            if (e.InstantBuild)
            {
                building.BuildAmountLeft = 0;
            }
            else
            {
                building.OnBuildingFinished += (b) => {
                    s.SendAlert(building.Data.FriendlyName + " Is Built", AlertLevel.Passive);
                };
            }

            // Check If A Building Was Possible
            if (building == null)
            {
                return;
            }
            s.EntityHashSet.Add(building.UUID, building);

            // Set Default Height
            building.Height = s.CGrid.HeightAt(building.GridPosition);
            building.CollisionGeometry.Height = building.Height;
            s.CGrid.Add(building);
            // Add Building Decision Task
            AddTask(s, building, e.Team, e.Type);
        }
Ejemplo n.º 17
0
        public void OnUnitSpawn(RTSUnit u)
        {
            DevConsole.AddCommand("spawn");
            Point       cc = HashHelper.Hash(u.GridPosition, GameState.CGrid.numCells, GameState.CGrid.size);
            RTSBuilding b  = GameState.CGrid.EStatic[cc.X, cc.Y];

            if (b != null)
            {
                foreach (var bc in barracksControllers)
                {
                    if (b.UUID == bc.barracks.UUID)
                    {
                        bc.army.Add(u);
                        u.OnDestruction += bc.OnUnitDeath;
                    }
                }
            }
        }
Ejemplo n.º 18
0
        private void AddTask(GameState s, RTSBuilding building)
        {
            // Init The Building
            if (building.ActionController != null)
            {
                building.ActionController.Init(s, this, building.Data.ActionControllerInitArgs);
            }
            for (int i = 0; i < building.ButtonControllers.Count; i++)
            {
                building.ButtonControllers[i].Init(s, this, building.Data.DefaultButtonControllerInitArgs[i]);
            }

            var btu = new BTaskBuildingDecision(s, building);

            building.OnDestruction += (o) => {
                tbEntityDecisions.RemoveTask(btu);
            };
            tbEntityDecisions.AddTask(btu);
        }
Ejemplo n.º 19
0
        private void AddTask(GameState s, RTSBuilding building, int fTeam, int type)
        {
            AddTask(s, building);
            ViewedBuilding vb = new ViewedBuilding();

            vb.Team          = fTeam;
            vb.Type          = type;
            vb.ViewDirection = building.ViewDirection;
            vb.WorldPosition = building.WorldPosition;
            vb.CellPoint     = HashHelper.Hash(building.GridPosition, s.CGrid.numCells, s.CGrid.size);
            for (int i = 0; i < s.teams.Length; i++)
            {
                if (i == fTeam || s.teams[i] == null)
                {
                    continue;
                }
                var ebu = new EnemyBuildingUpdater(s, i, vb, building);
                s.tbMemBuildings.AddTask(ebu);
            }
        }
Ejemplo n.º 20
0
        public void SetData(RTSBuilding b)
        {
            if (prevBuilding != null)
            {
                prevBuilding.OnDamage -= u_OnDamage;
            }
            prevBuilding = b;

            b.OnDamage          += u_OnDamage;
            rectHealthFore.Width = (int)(b.GetHealthRatio() * uic.IconSize);
            rectHealthFore.Color = Color.Lerp(uic.HealthMinColor, uic.HealthMaxColor, b.GetHealthRatio());

            Texture2D t;

            if (iconLib.TryGetValue(b.IconKey, out t))
            {
                icon.Texture = t;
            }

            txtName.Text = b.Data.FriendlyName;
            Update();
        }
Ejemplo n.º 21
0
        public CollisionGrid(int w, int h)
        {
            cellSize = RTSConstants.CGRID_SIZE;
            numCells = new Point(w, h);
            size     = new Vector2(w, h) * cellSize;

            EDynamic = new List <RTSUnit> [numCells.X, numCells.Y];
            EStatic  = new RTSBuilding[numCells.X, numCells.Y];
            for (int x = 0; x < numCells.X; x++)
            {
                for (int y = 0; y < numCells.Y; y++)
                {
                    EDynamic[x, y] = new List <RTSUnit>();
                }
            }
            ActiveGrids     = new List <Point>();
            Fog             = new uint[numCells.X, numCells.Y];
            Collision       = new bool[numCells.X, numCells.Y];
            Walls           = new CollisionRect[numCells.X, numCells.Y][];
            WallInformation = new byte[numCells.X, numCells.Y];
            Array.Clear(WallInformation, 0, WallInformation.Length);
            heights = new HeightTile[numCells.X, numCells.Y];
        }
Ejemplo n.º 22
0
        public void OnNewSelection(ACInputController ic, List <IEntity> entities)
        {
            Clear();
            if (IconLibrary == null)
            {
                return;
            }

            var units     = new Dictionary <RTSUnitData, List <IEntity> >();
            var buildings = new Dictionary <RTSBuildingData, List <IEntity> >();

            for (int i = 0; i < entities.Count; i++)
            {
                RTSUnit u = entities[i] as RTSUnit;
                if (u != null)
                {
                    if (units.ContainsKey(u.Data))
                    {
                        units[u.Data].Add(u);
                    }
                    else
                    {
                        var lu = new List <IEntity>();
                        lu.Add(u);
                        units.Add(u.Data, lu);
                    }
                }
                else
                {
                    RTSBuilding b = entities[i] as RTSBuilding;
                    if (buildings.ContainsKey(b.Data))
                    {
                        buildings[b.Data].Add(b);
                    }
                    else
                    {
                        var lb = new List <IEntity>();
                        lb.Add(b);
                        buildings.Add(b.Data, lb);
                    }
                }
            }

            int wi = 0;

            foreach (var kv in buildings)
            {
                if (wi >= groups.Length)
                {
                    break;
                }
                Texture2D t = IconLibrary[kv.Key.IconKey];
                if (t == null)
                {
                    continue;
                }
                groups[wi].Widget.Texture = t;
                groups[wi].Data           = kv.Value;
                Show(groups[wi]);
                wi++;
            }
            foreach (var kv in units)
            {
                if (wi >= groups.Length)
                {
                    break;
                }
                Texture2D t = IconLibrary[kv.Key.IconKey];
                if (t == null)
                {
                    continue;
                }
                groups[wi].Widget.Texture = t;
                groups[wi].Data           = kv.Value;
                Show(groups[wi]);
                wi++;
            }
        }
Ejemplo n.º 23
0
 public override void SetBuilding(RTSBuilding b)
 {
     base.SetBuilding(b);
 }
Ejemplo n.º 24
0
        private void FireWorkThread(Object l)
        {
            DevConsole.AddCommand("started");

            List <Point>        fires     = l as List <Point>;
            HashSet <Point>     hitCells  = new HashSet <Point>();
            List <FireParticle> particles = new List <FireParticle>();
            int  hitChance = 80;
            bool canSee;

            while (FireRunning)
            {
                if (fires.Count < 1)
                {
                    DevConsole.AddCommand("return");
                    return;
                }

                foreach (var f in fires)
                {
                    // Apply Fire Damage To Units and Buildings In Fire
                    Point c = new Point(f.X * 2, f.Y * 2);
                    for (int x = 0; x < 2 && c.X + x < GameState.CGrid.numCells.X; x++)
                    {
                        for (int y = 0; y < 2 && c.Y + y < GameState.CGrid.numCells.Y; y++)
                        {
                            foreach (var u in GameState.CGrid.EDynamic[c.X + x, c.Y + y])
                            {
                                if (u.Team.Index != Team.Index)
                                {
                                    bool takeDamage = (random.Next(100) <= FireHitUnitP);
                                    if (true)
                                    {
                                        u.Damage(FireUnitDamage);
                                        canSee = GameState.CGrid.GetFogOfWar(u.GridPosition, playerIndex) == FogOfWar.Active;
                                        if (canSee)
                                        {
                                            particles.Add(new FireParticle(u.WorldPosition, 3, 2, 2, 7));
                                        }
                                    }
                                }
                            }
                            RTSBuilding b = GameState.CGrid.EStatic[c.X, c.Y];
                            if (b != null && b.Team.Index != Team.Index)
                            {
                                bool takeDamage = (random.Next(100) <= FireHitBuildingP);
                                if (true)
                                {
                                    //b.Damage(FireBuildingDamage);
                                    canSee = GameState.CGrid.GetFogOfWar(b.GridPosition, playerIndex) == FogOfWar.Active;
                                    if (canSee)
                                    {
                                        particles.Add(new FireParticle(b.WorldPosition, 5, 1, 2, 6));
                                    }
                                }
                            }
                        }
                    }
                    // Add Fire Particle If Not In Player's Fog Of War
                    Vector2 p = new Vector2(f.X, f.Y) * grid.cellSize + Vector2.One;
                    canSee = GameState.CGrid.GetFogOfWar(p, playerIndex) == FogOfWar.Active;
                    if (canSee)
                    {
                        Vector3 pos = new Vector3(p.X, GameState.CGrid.HeightAt(p), p.Y);
                        particles.Add(new FireParticle(pos, 4, 3, 10, 9));
                    }
                    // Fire Spreading
                    for (int x = -1; x < 2; x++)
                    {
                        if (f.X + x < grid.numCells.X && f.X + x >= 0)
                        {
                            for (int y = -1; y < 2; y++)
                            {
                                if (f.Y + y < grid.numCells.Y && f.Y + y >= 0)
                                {
                                    bool isHit = (random.Next(100) <= hitChance);
                                    if (isHit)
                                    {
                                        bool added = hitCells.Add(new Point(f.X + x, f.Y + y));
                                    }
                                }
                            }
                        }
                    }
                }
                hitChance = (int)((float)hitChance * 0.7);
                fires.Clear();
                foreach (var hc in hitCells)
                {
                    fires.Add(hc);
                }
                hitCells.Clear();
                GameState.AddParticles(particles);
                particles.Clear();
                Thread.Sleep(3000);
            }
        }
Ejemplo n.º 25
0
 public T SetBuilding <T>(RTSBuilding b) where T : ACUnitController
 {
     SetBuilding(b);
     return(this as T);
 }
Ejemplo n.º 26
0
        // Adds An Impact Generator To The Appropriate Cell In The Impact Grid
        public void AddImpactGenerator(RTSBuilding b)
        {
            Point p = HashHelper.Hash(b.GridPosition, numCells, size);

            ImpactGenerators[p.X, p.Y].Add(b);
        }
Ejemplo n.º 27
0
 public static bool IsBuildingDead(RTSBuilding b)
 {
     return(IsEntityDead(b));
 }
Ejemplo n.º 28
0
        public void OnNewSelection(ACInputController ic, List <IEntity> entities)
        {
            Clear();
            if (IconLibrary == null)
            {
                return;
            }

            int bType = -1;
            List <RTSBuilding> sBuildings = new List <RTSBuilding>();

            for (int i = 0; i < entities.Count; i++)
            {
                if (entities[i] as RTSUnit != null)
                {
                    return;
                }
                RTSBuilding b = entities[i] as RTSBuilding;
                if (b == null || b.Team.Index != ic.TeamIndex || !b.IsBuilt || !b.IsAlive)
                {
                    continue;
                }

                if (bType < 0)
                {
                    bType = b.Data.Index;
                }
                else if (bType != b.Data.Index)
                {
                    return;
                }

                sBuildings.Add(b);
            }

            if (bType < 0)
            {
                return;
            }

            int wi = 0;
            var bd = ic.Team.Race.Buildings[bType].DefaultButtonControllers;

            foreach (var bc in sBuildings[0].ButtonControllers)
            {
                if (wi >= groups.Length)
                {
                    break;
                }
                if (!IconLibrary.ContainsKey(bc.IconKey))
                {
                    continue;
                }
                groups[wi].Widget.Texture = IconLibrary[bc.IconKey];
                var bcs = new List <ACBuildingButtonController>();
                foreach (var nb in sBuildings)
                {
                    bcs.Add(nb.ButtonControllers[wi]);
                }
                groups[wi].Data = bcs;
                Show(groups[wi]);
                wi++;
            }
        }
Ejemplo n.º 29
0
 public void OnBuildingSpawn(RTSBuilding b)
 {
     Add(b);
 }
Ejemplo n.º 30
0
        private void SpawnUnits(ImpactRegion r, int level)
        {
            // Decide Spawn Cap
            int spawnCap;

            if (level == 1)
            {
                spawnCap = L1SpawnCap;
            }
            else if (level == 2)
            {
                spawnCap = L2SpawnCap;
            }
            else if (level == 3)
            {
                spawnCap = L3SpawnCap;
            }
            else
            {
                spawnCap = 0;
            }

            // Return If Population Count Of Region Is Greater Than The Spawn Cap For The Region
            if (r.PopCount >= spawnCap)
            {
                return;
            }

            // Decide On A Starting Point
            Point start = new Point(-1, -1);

            foreach (var u in GameState.activeTeams[playerIndex].Team.Units)
            {
                Point cc = HashHelper.Hash(u.GridPosition, GameState.CGrid.numCells, GameState.CGrid.size);
                start = cc;
            }

            // Find Possible Spawn Points
            List <Point>  spawnPoints = new List <Point>();
            Queue <Point> unvisited   = new Queue <Point>();
            int           width       = GameState.CGrid.numCells.X;
            int           height      = GameState.CGrid.numCells.Y;

            bool[,] visited = new bool[width, height];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    visited[x, y] = false;
                }
            }
            if (start.X > 0 && start.Y > 0)
            {
                unvisited.Enqueue(start);
                visited[start.X, start.Y] = true;
            }

            while (unvisited.Count > 0)
            {
                Point at = unvisited.Dequeue();

                for (int x = -1; x < 2; x++)
                {
                    for (int y = -1; y < 2; y++)
                    {
                        Point p = new Point(at.X + x, at.Y + y);
                        if ((p.X != at.X || p.Y != at.Y) && p.X > 0 && p.Y > 0 && p.X < width && p.Y < height)
                        {
                            ImpactRegion pr = FindRegion(p);
                            RTSBuilding  b  = GameState.CGrid.EStatic[p.X, p.Y];
                            if (pr.Cells.First() == r.Cells.First() && b != null)
                            {
                                bool isOre  = b.Data.FriendlyName.Equals(OreData.FriendlyName);
                                bool isTree = b.Data.FriendlyName.Equals(FloraData.FriendlyName);
                                if (isOre || isTree)
                                {
                                    spawnPoints.Add(at);
                                }
                            }
                            else if (pr.Cells.First() == r.Cells.First() && b == null && !visited[p.X, p.Y])
                            {
                                unvisited.Enqueue(p);
                                visited[p.X, p.Y] = true;
                            }
                        }
                    }
                }
            }

            if (spawnPoints.Count > 0)
            {
                // Choose A Random Spawn Point
                int     ii         = random.Next(spawnPoints.Count);
                Point   spawnPoint = spawnPoints.ElementAt(ii);
                Vector2 spawnPos   = new Vector2(spawnPoint.X, spawnPoint.Y) * GameState.CGrid.cellSize + Vector2.One;

                // Spawn Environmental Units
                int numSpawn;
                int ti = 0;
                foreach (var spawnType in Spawns)
                {
                    numSpawn = random.Next(minNumSpawn[level - 1][ti], maxNumSpawn[level - 1][ti]);
                    for (int j = 0; j < numSpawn && r.PopCount < spawnCap; j++)
                    {
                        AddEvent(new SpawnUnitEvent(TeamIndex, spawnType, spawnPos));
                        r.PopCount++;
                    }
                    ti++;
                }
            }
            SetInitTarget(r);
        }