1 //#define DisplayRegions
2 #define DisplayFinalRegions
5 using System.Collections.Generic;
8 using Microsoft.Xna.Framework;
13 /// AI infomation to be used by monsters. The map is split into deferent regions,
14 /// each region is then linked to other regions that it can see.
20 List<Region> regionList;
26 regions = new int[game.State.Map.Width, game.State.Map.Height];
27 regionList = new List<Region>();
30 //set all square to -1 to show they have not been assigned to a region yet.
31 for (int y = 0; y < regions.GetLength(1); y++)
33 for (int x = 0; x < regions.GetLength(0); x++)
38 regionList.Add(new Region(0)); //region 0 will represent all walls and things like it.
45 foreach (Region r in regionList)
49 #if (DisplayRegions || DisplayFinalRegions)
56 /// check to see if a spot on the map is visible from another spot
58 /// <param name="curX">Current X position</param>
59 /// <param name="curY">Current Y position</param>
60 /// <param name="testX">X location to test</param>
61 /// <param name="testY">Y location to test</param>
62 public bool spaceVisible(int curX, int curY, int testX, int testY)
64 return regionList[regions[curX, curY]].VisibleRegions.Contains(regions[testX, testY]);
67 //find regions in map. these regions will be large groups of connected grid squares.
68 public int setUpRegions()
71 //find open space that has not been assigned yet
72 for (int y = 0; y < regions.GetLength(1); y++)
74 for (int x = 0; x < regions.GetLength(0); x++)
76 if (regions[x, y] == -1 && spaceOpen(x, y))
79 regionList.Add(new Region(regionCnt));
82 else if (regions[x, y] == -1) //grid square is a wall
86 else //grid already assigned to region, do nothing
92 return regionList.Count;
95 #region Private Methods
96 private void createRegion(int x, int y)
98 regionList[regionCnt].Left = x;
99 regionList[regionCnt].Top = y;
101 for (int rY = 0; rY < 5 && y + rY < regions.GetLength(1); rY++) // creates a region as large as possible up to 5x5
103 for (int rX = 0; rX < 5 && x + rX < regions.GetLength(0); rX++)
105 if (regions[x + rX, y + rY] == -1 && spaceOpen(x + rX, y + rY))
107 regions[x + rX, y + rY] = regionCnt;
109 else if (regions[x + rX, y + rY] == -1) //grid square is a wall
111 regions[x + rX, y + rY] = 0;
112 regionList[regionCnt].Right = x + rX;
113 regionList[regionCnt].Bottom = y + rY;
117 if (!spaceOpen(x + rX + 1, y + rY)) // hit horizontal wall end region
118 if(x + rX >= regions.GetLength(0)-1)
125 //todo: figure out how to get region to stop being created when
127 else //grid already assigned to region, do nothing
130 regionList[regionCnt].Right = x + rX;
133 regionList[regionCnt].Bottom = y + rY;
140 private bool spaceOpen(int x, int y)
142 if (x >= regions.GetLength(0)) return false;
143 if (y >= regions.GetLength(1)) return false;
144 return !game.State.Map.IsWall(x, y);
146 //TODO: scans out from each corner, some areas are still missed
147 private void linkRegions()
149 foreach (Region r in regionList)
160 for (int t = 1; spaceOpen(x, y - t); t++)
162 if ( regions[x, y] != regions[x, y - t] )
164 regionList[regions[x, y]].AddVisible(regions[x, y - t]);
168 for (int t = 1; spaceOpen(x - t, y); t++)
170 if ( regions[x, y] != regions[x - t, y] )
172 regionList[regions[x, y]].AddVisible(regions[x - t, y]);
176 for (int t = 1; spaceOpen(x - t, y - t); t++)
178 if (regions[x, y] != regions[x - t, y - t])
180 regionList[regions[x, y]].AddVisible(regions[x - t, y - t]);
188 for (int t = 1; spaceOpen(x, y - t); t++)
190 if (regions[x, y] != regions[x, y - t])
192 regionList[regions[x, y]].AddVisible(regions[x, y - t]);
196 for (int t = 1; spaceOpen(x + t, y); t++)
198 if (regions[x, y] != regions[x + t, y])
200 regionList[regions[x, y]].AddVisible(regions[x + t, y]);
204 for (int t = 1; spaceOpen(x + t, y - t); t++)
206 if (regions[x, y] != regions[x + t, y - t])
208 regionList[regions[x, y]].AddVisible(regions[x + t, y - t]);
216 for (int t = 1; spaceOpen(x, y + t); t++)
218 if (regions[x, y] != regions[x, y + t])
220 regionList[regions[x, y]].AddVisible(regions[x, y + t]);
224 for (int t = 1; spaceOpen(x + t, y); t++)
226 if (regions[x, y] != regions[x + t, y])
228 regionList[regions[x, y]].AddVisible(regions[x + t, y]);
232 for (int t = 1; spaceOpen(x + t, y + t); t++)
234 if (regions[x, y] != regions[x + t, y + t])
236 regionList[regions[x, y]].AddVisible(regions[x + t, y + t]);
244 for (int t = 1; spaceOpen(x, y + t); t++)
246 if (regions[x, y] != regions[x, y + t])
248 regionList[regions[x, y]].AddVisible(regions[x, y + t]);
252 for (int t = 1; spaceOpen(x - t, y); t++)
254 if (regions[x, y] != regions[x - t, y])
256 regionList[regions[x, y]].AddVisible(regions[x - t, y]);
260 for (int t = 1; spaceOpen(x - t, y + t); t++)
262 if (regions[x, y] != regions[x - t, y + t])
264 regionList[regions[x, y]].AddVisible(regions[x - t, y + t]);
270 //for testing print the region grid to the console
271 public void printRegions()
273 Console.WriteLine("--Printing Regions--");
274 for (int y = 0; y < regions.GetLength(1); y++)
276 for (int x = 0; x < regions.GetLength(0); x++)
278 Console.Write(regions[x, y]);
280 Console.WriteLine("");
286 /// a chuck of the map that is at most 5x5 used to determine line of sight
290 List<int> visibleRegions; //other regions that are in this regions sight
296 int left, right, top, bottom;
298 public Region(int _label)
301 visibleRegions = new List<int>();
304 public void AddVisible(int region)
306 if(!visibleRegions.Contains(region))
307 visibleRegions.Add(region);
310 public void CalcCenter()
312 if (right != left) centerX = right + (right - left) / 2;
313 else centerX = right;
314 if (top != bottom) centerY = top + (bottom - top) / 2;
321 set { left = value; }
325 get { return right; }
326 set { right = value; }
335 get { return bottom; }
336 set { bottom = value; }
339 public Point Center { get { return new Point(centerX, centerY); } }
340 public int Label { get { return label; } }
342 public List<int> VisibleRegions { get { return visibleRegions; } }