root/Code/oMaE/oMaE/Screens/Map.cs @ 163

Revision 163, 23.8 KB (checked in by acarter, 2 years ago)

Touched up some comments

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Microsoft.Xna.Framework;
6using Microsoft.Xna.Framework.Audio;
7using Microsoft.Xna.Framework.Content;
8using Microsoft.Xna.Framework.GamerServices;
9using Microsoft.Xna.Framework.Graphics;
10using Microsoft.Xna.Framework.Input;
11using Microsoft.Xna.Framework.Media;
12using oMaE.Overworld.Objects;
13using Serializables;
14
15namespace oMaE.Overworld
16{
17    /// <summary>
18    /// The map of the game.
19    /// </summary>
20    public class Map : GameObject
21    {
22        /// <summary>
23        /// An ascii map.
24        /// </summary>
25        private string[] map;
26        /// <summary>
27        /// A minimap derived from the map.
28        /// </summary>
29        private int[][] minimap;
30        /// <summary>
31        /// The entrance of the warehouse.
32        /// </summary>
33        public Door Entrance;
34        /// <summary>
35        /// Starting location on minimap.
36        /// </summary>
37        public Point mStart;
38        /// <summary>
39        /// The current save.
40        /// </summary>
41        public Save Save;
42        /// <summary>
43        /// The number of doors on the map
44        /// </summary>
45        public int NumDoors = 0;
46        /// <summary>
47        /// The starting location of the person
48        /// </summary>
49        private Vector2 start = Vector2.Zero;
50        /// <summary>
51        /// All the wall in the compound.
52        /// </summary>
53        public LinkedList<Wall> Walls { get { return GenerateWalls(); } }
54        /// <summary>
55        /// All the doors in the compound.
56        /// </summary>
57        public LinkedList<Door> Doors { get { return GenerateDoors(); } }
58        /// <summary>
59        /// All the crates in the compound.
60        /// </summary>
61        public LinkedList<Crate> Crates { get { return GenerateCrates(); } }
62        /// <summary>
63        /// Makes a new map.
64        /// </summary>
65        /// <param name="num">The map number.</param>
66        public Map(int num)
67        {
68            Visible = false;
69        }
70        /// <summary>
71        /// Initializes the minimap.
72        /// </summary>
73        private void init()
74        {
75            minimap = new int[3 * map.Length + 2][];
76            for (int i = 0; i < minimap.Length; ++i)
77            {
78                minimap[i] = new int[3 * map[0].Length + 2];
79                for (int j = 0; j < minimap[i].Length; ++j)
80                    minimap[i][j] = 0;
81            }
82            for (int i = 0; i < map.Length; ++i)
83            {
84                for (int j = 0; j < map[i].Length; ++j)
85                {
86                    switch (map[i][j])
87                    {
88                        case '+':
89                            minimap[3 * i + 2][3 * j + 1] = -1;
90                            minimap[3 * i + 1][3 * j + 2] = -1;
91                            minimap[3 * i + 2][3 * j + 2] = -1;
92                            minimap[3 * i + 3][3 * j + 2] = -1;
93                            minimap[3 * i + 2][3 * j + 3] = -1;
94                            break;
95                        case '|':
96                            minimap[3 * i + 1][3 * j + 2] = -1;
97                            minimap[3 * i + 2][3 * j + 2] = -1;
98                            minimap[3 * i + 3][3 * j + 2] = -1;
99                            break;
100                        case '-':
101                            minimap[3 * i + 2][3 * j + 1] = -1;
102                            minimap[3 * i + 2][3 * j + 2] = -1;
103                            minimap[3 * i + 2][3 * j + 3] = -1;
104                            break;
105                        case 'I':
106                            minimap[3 * i + 2][3 * j + 1] = -2;
107                            minimap[3 * i + 2][3 * j + 2] = -2;
108                            minimap[3 * i + 2][3 * j + 3] = -2;
109                            NumDoors++;
110                            break;
111                        case 'E':
112                            minimap[3 * i + 2][3 * j + 1] = -4;
113                            minimap[3 * i + 2][3 * j + 2] = -4;
114                            minimap[3 * i + 2][3 * j + 3] = -4;
115                            NumDoors++;
116                            break;
117                        case 'd':
118                            minimap[3 * i + 1][3 * j + 2] = -2;
119                            minimap[3 * i + 2][3 * j + 2] = -2;
120                            minimap[3 * i + 3][3 * j + 2] = -2;
121                            NumDoors++;
122                            break;
123                        case 'r':
124                            minimap[3 * i + 2][3 * j + 2] = -1;
125                            minimap[3 * i + 3][3 * j + 2] = -1;
126                            minimap[3 * i + 2][3 * j + 3] = -1;
127                            break;
128                        case 'J':
129                            minimap[3 * i + 2][3 * j + 2] = -1;
130                            minimap[3 * i + 2][3 * j + 1] = -1;
131                            minimap[3 * i + 3][3 * j + 2] = -1;
132                            break;
133                        case '/':
134                            minimap[3 * i + 2][3 * j + 2] = -1;
135                            minimap[3 * i + 2][3 * j + 1] = -1;
136                            minimap[3 * i + 1][3 * j + 2] = -1;
137                            break;
138                        case 'L':
139                            minimap[3 * i + 2][3 * j + 2] = -1;
140                            minimap[3 * i + 1][3 * j + 2] = -1;
141                            minimap[3 * i + 2][3 * j + 3] = -1;
142                            break;
143                        case 'v':
144                            minimap[3 * i + 2][3 * j + 1] = -1;
145                            minimap[3 * i + 2][3 * j + 2] = -1;
146                            minimap[3 * i + 2][3 * j + 3] = -1;
147                            minimap[3 * i + 3][3 * j + 2] = -1;
148                            break;
149                        case 'n':
150                            minimap[3 * i + 2][3 * j + 1] = -1;
151                            minimap[3 * i + 2][3 * j + 2] = -1;
152                            minimap[3 * i + 2][3 * j + 3] = -1;
153                            minimap[3 * i + 1][3 * j + 2] = -1;
154                            break;
155                        case '<':
156                            minimap[3 * i + 1][3 * j + 2] = -1;
157                            minimap[3 * i + 2][3 * j + 2] = -1;
158                            minimap[3 * i + 3][3 * j + 2] = -1;
159                            minimap[3 * i + 2][3 * j + 1] = -1;
160                            break;
161                        case '>':
162                            minimap[3 * i + 1][3 * j + 2] = -1;
163                            minimap[3 * i + 2][3 * j + 2] = -1;
164                            minimap[3 * i + 3][3 * j + 2] = -1;
165                            minimap[3 * i + 2][3 * j + 3] = -1;
166                            break;
167                        case 'M':
168                        case '*':
169                            minimap[3 * i + 2][3 * j + 2] = 2;
170                            break;
171                        case 'Y':
172                            mStart = new Point(3 * i + 2, 3 * j + 2);
173                            start = new Vector2(j, i);
174                            break;
175
176                    }
177                }
178            }
179            floodFill(1 + 3 * (int)start.Y, 1 + 3 * (int)start.X);
180        }
181        /// <summary>
182        /// Opened a crate.
183        /// </summary>
184        /// <param name="p">The location of the crate.</param>
185        /// <param name="index">The index of the crate</param>
186        public void GetCrate(Point p, int index)
187        {
188            minimap[p.X][p.Y] = 1;
189            int[] temp = new int[Save.Gotten.Length+1];
190            for(int i = 0; i < Save.Gotten.Length; ++i)
191                temp[i] = Save.Gotten[i];
192            temp[Save.Gotten.Length] = index;
193            Save.Gotten = temp;
194        }
195        /// <summary>
196        /// Generates crates from linked list.
197        /// </summary>
198        /// <returns>A linked list of generated crates.</returns>
199        private LinkedList<Crate> GenerateCrates()
200        {
201            int count = 0;
202            LinkedList<Crate> crates = new LinkedList<Crate>();
203            for (int i = 0; i < map.Length; ++i)
204            {
205                for (int j = 0; j < map[i].Length; ++j)
206                {
207                    Vector2 center = 20 * (new Vector2(j, i) - start);
208                    switch (map[i][j])
209                    {
210                        case '*':
211                        case 'M':
212                            if (Save.Gotten.Contains(count))
213                                minimap[3 * i + 2][3 * j + 2] = 1;
214                            else
215                                crates.AddFirst(new Crate(center, new Point(3 * i + 2, 3 * j + 2), count));
216                            count++;
217                            break;
218                    }
219                }
220            }
221            return crates;
222        }
223        /// <summary>
224        /// Generates doors from linked list.
225        /// </summary>
226        /// <returns>A linked list of generated doors.</returns>
227        private LinkedList<Door> GenerateDoors()
228        {
229            LinkedList<Door> doors = new LinkedList<Door>();
230            for (int i = 0; i < map.Length; ++i)
231            {
232                for (int j = 0; j < map[i].Length; ++j)
233                {
234                    Vector2 top = 20 * (new Vector2(j, i) - new Vector2(0.0f, 0.5f) - start);
235                    Vector2 bottom = 20 * (new Vector2(j, i) + new Vector2(0.0f, 0.5f) - start);
236                    Vector2 left = 20 * (new Vector2(j, i) - new Vector2(0.5f, 0.0f) - start);
237                    Vector2 right = 20 * (new Vector2(j, i) + new Vector2(0.5f, 0.0f) - start);
238                    Vector2 center = 20 * (new Vector2(j, i) - start);
239                    Point mLoc = new Point(3 * i + 2, 3 * j + 2);
240                    Door partner;
241                    switch (map[i][j])
242                    {
243                        case 'E':
244                            doors.AddFirst(partner = new Door(Color.Black, Color.Black, Color.LightSlateGray, left, right, mLoc, 30, 40, ""));
245                            doors.AddFirst(new Door(Color.Black, Color.Black, Color.LightSlateGray, right, left, partner, 30, 40, ""));
246                            Entrance = partner;
247                            break;
248                        case 'I':
249                            doors.AddFirst(partner = new Door(Color.Red, Color.Green, Color.LightSlateGray, left, right, mLoc, 10, 40));
250                            doors.AddFirst(new Door(Color.Red, Color.Green, Color.LightSlateGray, right, left, partner, 10, 40));
251                            break;
252                        case 'd':
253                            doors.AddFirst(partner = new Door(Color.Red, Color.Green, Color.LightSlateGray, top, bottom, mLoc, 10, 40));
254                            doors.AddFirst(new Door(Color.Red, Color.Green, Color.LightSlateGray, bottom, top, partner, 10, 40));
255                            break;
256                    }
257                }
258            }
259            return doors;
260        }
261        /// <summary>
262        /// Generate walls from map
263        /// </summary>
264        /// <returns>Returns a linked list of generated walls.</returns>
265        private LinkedList<Wall> GenerateWalls()
266        {
267            LinkedList<Wall> walls = new LinkedList<Wall>();
268            for (int i = 0; i < map.Length; ++i)
269            {
270                for (int j = 0; j < map[i].Length; ++j)
271                {
272                    Vector2 top = 20 * (new Vector2(j, i) - new Vector2(0.0f, 0.5f) - start); 
273                    Vector2 bottom = 20 * (new Vector2(j, i) + new Vector2(0.0f, 0.5f) - start); 
274                    Vector2 left = 20 * (new Vector2(j, i) - new Vector2(0.5f, 0.0f) - start); 
275                    Vector2 right = 20 * (new Vector2(j, i) + new Vector2(0.5f, 0.0f) - start);
276                    Vector2 center = 20 * (new Vector2(j, i) - start);
277                    switch (map[i][j])
278                    {
279                        case '+':
280                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
281                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
282                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
283                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
284                            break;
285                        case '|':
286                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
287                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
288                            break;
289                        case '-':
290                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
291                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
292                            break;
293                        case 'r':
294                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, center, 40f));
295                            walls.AddFirst(new Wall(Color.LightSlateGray, center, bottom, 40f));
296                            walls.AddFirst(new Wall(Color.LightSlateGray, right, center, 40f));
297                            walls.AddFirst(new Wall(Color.LightSlateGray, center, right, 40f));
298                            break;
299                        case 'J':
300                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, center, 40f));
301                            walls.AddFirst(new Wall(Color.LightSlateGray, center, bottom, 40f));
302                            walls.AddFirst(new Wall(Color.LightSlateGray, left, center, 40f));
303                            walls.AddFirst(new Wall(Color.LightSlateGray, center, left, 40f));
304                            break;
305                        case '/':
306                            walls.AddFirst(new Wall(Color.LightSlateGray, left, center, 40f));
307                            walls.AddFirst(new Wall(Color.LightSlateGray, center, left, 40f));
308                            walls.AddFirst(new Wall(Color.LightSlateGray, top, center, 40f));
309                            walls.AddFirst(new Wall(Color.LightSlateGray, center, top, 40f));
310                            break;
311                        case 'L':
312                            walls.AddFirst(new Wall(Color.LightSlateGray, right, center, 40f));
313                            walls.AddFirst(new Wall(Color.LightSlateGray, center, right, 40f));
314                            walls.AddFirst(new Wall(Color.LightSlateGray, top, center, 40f));
315                            walls.AddFirst(new Wall(Color.LightSlateGray, center, top, 40f));
316                            break;
317                        case 'v':
318                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
319                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
320                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, center, 40f));
321                            walls.AddFirst(new Wall(Color.LightSlateGray, center, bottom, 40f));
322                            break;
323                        case 'n':
324                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
325                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
326                            walls.AddFirst(new Wall(Color.LightSlateGray, top, center, 40f));
327                            walls.AddFirst(new Wall(Color.LightSlateGray, center, top, 40f));
328                            break;
329                        case '>':
330                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
331                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
332                            walls.AddFirst(new Wall(Color.LightSlateGray, right, center, 40f));
333                            walls.AddFirst(new Wall(Color.LightSlateGray, center, right, 40f));
334                            break;
335                        case '<':
336                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
337                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
338                            walls.AddFirst(new Wall(Color.LightSlateGray, left, center, 40f));
339                            walls.AddFirst(new Wall(Color.LightSlateGray, center, left, 40f));
340                            break;
341                    }
342                }
343            }
344            return walls;
345        }
346        /// <summary>
347        /// Flood fills around a door when entering a new room.
348        /// </summary>
349        /// <param name="x">The x-coordinate on the minimap</param>
350        /// <param name="y">The y-coordinate on the minimap</param>
351        private void floodFill(int x, int y)
352        {
353            try
354            {
355                if (minimap[x][y] == 0)
356                {
357                    minimap[x][y] = 1;
358                    floodFill(x, y + 1);
359                    floodFill(x + 1, y);
360                    floodFill(x, y - 1);
361                    floodFill(x - 1, y);
362                }
363            }
364            catch (IndexOutOfRangeException)
365            {
366            }
367        }
368        /// <summary>
369        /// Flood fills a door when entering a new room.
370        /// </summary>
371        /// <param name="x">The x-coordinate on the minimap</param>
372        /// <param name="y">The y-coordinate on the minimap</param>
373        private void floodFillOpen(int x, int y)
374        {
375            try
376            {
377                if (minimap[x][y] == -2)
378                {
379                    minimap[x][y] = -3;
380                    floodFillOpen(x, y + 1);
381                    floodFillOpen(x + 1, y);
382                    floodFillOpen(x, y - 1);
383                    floodFillOpen(x - 1, y);
384                }
385                else
386                {
387                    floodFill(x, y);
388                }
389            }
390            catch (IndexOutOfRangeException)
391            {
392            }
393        }
394        /// <summary>
395        /// Loads content.
396        /// </summary>
397        /// <param name="Content">The content manager.</param>
398        public override void LoadContent(ContentManager Content)
399        {
400            string[][] test = Content.Load<string[][]>("AppData/Maps");
401            map = test[0];
402            base.LoadContent(Content);
403        }
404        /// <summary>
405        /// Resets the map
406        /// </summary>
407        /// <param name="save">The save to load/store map in</param>
408        public void Reset(Save save)
409        {
410            Save = save;
411            if (Save.Gotten == null)
412                Save.Gotten = new int[0];
413            init();
414        }
415        /// <summary>
416        /// Updates on the map
417        /// </summary>
418        /// <param name="gamestate">The current gamestate</param>
419        public override void Update(GameState gamestate)
420        {
421            if (gamestate.Pressed(MouseButton.LEFT))
422            {
423                gamestate.Handle(MouseButton.LEFT);
424                driver.CloseMap();
425            }
426            base.Update();
427        }
428        /// <summary>
429        /// Enter a new room.
430        /// </summary>
431        /// <param name="pos">Location of opening door.</param>
432        public void EnterRoom(Point pos)
433        {
434            // Console.WriteLine(pos);
435            floodFillOpen(pos.X, pos.Y);
436        }
437        /// <summary>
438        /// Draws the minimap to the screen.
439        /// </summary>
440        /// <param name="screen">The screen to be drawn on.</param>
441        public override void Draw(Screen2D screen)
442        {
443            screen.FillRectangle(new Rectangle(0, 0, 1000, 500), new Color(0, 0, 255, 127));
444            int majorSize = 200 / map.Length, minorSize = 75 / map.Length;
445            int xcoord, dxcoord, ycoord = 50, dycoord;
446            for (int i = 1; i < minimap.Length - 1; ++i)
447            {
448                xcoord = (1000 - map[(i - 1) / 3].Length * (2 * majorSize + minorSize)) / 2;
449                dycoord = (i % 3 == 2 ? minorSize : majorSize);
450                for (int j = 1; j < minimap[i].Length - 1; ++j)
451                {
452                    dxcoord = (j % 3 == 2 ? minorSize : majorSize);
453                    Color c;
454                    switch (minimap[i][j])
455                    {
456                        case -1:
457                            c = Color.Black;
458                            break;
459                        case -2:
460                            c = Color.Red;
461                            break;
462                        case -3:
463                            c = Color.Green;
464                            break;
465                        case -4:
466                            c = Color.Maroon;
467                            break;
468                        case 2:
469                            c = Color.Yellow;
470                            break;
471                        case 1:
472                            c = Color.Blue;
473                            break;
474                        default:
475                            c = Color.Gray;
476                            break;
477                    }
478                    screen.FillRectangle(new Rectangle(xcoord, ycoord, dxcoord, dycoord), c);
479                    xcoord += dxcoord;
480                }
481                ycoord += dycoord;
482            }
483            Vector2 loc = ((driver.World3D.CameraPosition2D * (1 / 20.0f)) + start) * (2 * majorSize + minorSize) + new Vector2((1000 - map[0].Length * (2 * majorSize + minorSize)) / 2, 50);
484            screen.FillRectangle(new Rectangle((int)loc.X + 5, (int)loc.Y + 5, 10, 10), Color.White);
485            screen.DrawText("Click anywhere to close", new Vector2(500, 10), TextHorizontal.CENTERED, TextVertical.TOP, Color.White);
486            // FIXME : Should be loaded via content pipeline
487            screen.FillRectangle(new Rectangle(830, 50, 150, 400), Color.MediumPurple);
488            screen.DrawText("Key", new Vector2(905, 60), FontSize.LARGE, TextHorizontal.CENTERED, TextVertical.TOP, Color.White);
489            screen.FillRectangle(new Rectangle(850, 120, 20, 20), Color.Black);
490            screen.DrawText("Wall", new Vector2(900, 130), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
491            screen.FillRectangle(new Rectangle(850, 160, 20, 20), Color.Blue);
492            screen.DrawText("Visited", new Vector2(900, 170), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
493            screen.FillRectangle(new Rectangle(850, 200, 20, 20), Color.Gray);
494            screen.DrawText("Unvisited", new Vector2(900, 210), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
495            screen.FillRectangle(new Rectangle(850, 240, 20, 20), Color.Maroon);
496            screen.DrawText("Entrance", new Vector2(900, 250), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
497            screen.FillRectangle(new Rectangle(850, 280, 20, 20), Color.Red);
498            screen.DrawText("Locked", new Vector2(900, 290), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
499            screen.FillRectangle(new Rectangle(850, 320, 20, 20), Color.Green);
500            screen.DrawText("Unlocked", new Vector2(900, 330), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
501            screen.FillRectangle(new Rectangle(850, 360, 20, 20), Color.Yellow);
502            screen.DrawText("Part", new Vector2(900, 370), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
503            screen.FillRectangle(new Rectangle(850, 400, 20, 20), Color.White);
504            screen.DrawText("You", new Vector2(900, 410), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
505            base.Draw(screen);
506        }
507    }
508}
Note: See TracBrowser for help on using the browser.