1 /* AsteroidField.h
2 Copyright (c) 2014 by Michael Zahniser
3 
4 Endless Sky is free software: you can redistribute it and/or modify it under the
5 terms of the GNU General Public License as published by the Free Software
6 Foundation, either version 3 of the License, or (at your option) any later version.
7 
8 Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10 PARTICULAR PURPOSE.  See the GNU General Public License for more details.
11 */
12 
13 #ifndef ASTEROID_FIELD_H_
14 #define ASTEROID_FIELD_H_
15 
16 #include "Angle.h"
17 #include "Body.h"
18 #include "CollisionSet.h"
19 #include "Point.h"
20 
21 #include <list>
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 class DrawList;
27 class Flotsam;
28 class Minable;
29 class Projectile;
30 class Sprite;
31 class Visual;
32 
33 
34 
35 // Class representing a field of asteroids. The field actually "repeats" every
36 // 4096 pixels. That is, an asteroid present at (100, 200) is also present at
37 // (4196, 200), (100, 4296), etc. Other games often just "wrap" the asteroids
38 // to the screen, meaning that there are no actual asteroids beyond what the
39 // player can see, but that means that missiles are not in danger of hitting an
40 // asteroid unless they are on screen, and also causes trouble if the screen is
41 // resized on the fly. Asteroids never change direction or speed, even if they
42 // are hit by a projectile.
43 class AsteroidField {
44 public:
45 	// Constructor, to set up the collision set parameters.
46 	AsteroidField();
47 
48 	// Reset the asteroid field (typically because you entered a new system).
49 	void Clear();
50 	void Add(const std::string &name, int count, double energy = 1.);
51 	void Add(const Minable *minable, int count, double energy = 1., double beltRadius = 1500.);
52 
53 	// Move all the asteroids forward one time step, and populate the asteroid and minable collision sets.
54 	void Step(std::vector<Visual> &visuals, std::list<std::shared_ptr<Flotsam>> &flotsam, int step);
55 	// Draw the asteroid field, with the field of view centered on the given point.
56 	void Draw(DrawList &draw, const Point &center, double zoom) const;
57 	// Check if the given projectile has hit any of the asteroids, using the information
58 	// in the collision sets. If a collision occurs, returns a pointer to the hit body.
59 	Body *Collide(const Projectile &projectile, double *closestHit);
60 
61 	// Get the list of minable asteroids.
62 	const std::list<std::shared_ptr<Minable>> &Minables() const;
63 
64 
65 private:
66 	// This class represents an asteroid that cannot be destroyed or even
67 	// deflected from its trajectory, and that repeats every 4096 pixels.
68 	class Asteroid : public Body {
69 	public:
70 		Asteroid(const Sprite *sprite, double energy);
71 
72 		void Step();
73 		void Draw(DrawList &draw, const Point &center, double zoom) const;
74 
75 	private:
76 		Angle spin;
77 		Point size;
78 	};
79 
80 
81 private:
82 	std::vector<Asteroid> asteroids;
83 	std::list<std::shared_ptr<Minable>> minables;
84 
85 	CollisionSet asteroidCollisions;
86 	CollisionSet minableCollisions;
87 };
88 
89 
90 
91 #endif
92