-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.hpp
executable file
·267 lines (215 loc) · 7.55 KB
/
model.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#ifndef MODEL_HPP
#define MODEL_HPP
#include "types.hpp"
#include "image.hpp"
#include "unitinfo.hpp"
#include "util.hpp"
#include "effects.hpp"
#include <vector>
#include <list>
#include <stdexcept>
//////////////////////////////////////////////////////////////////////////////
class Model
{
public:
class Tile;
struct TileType;
class Unit;
class Player;
class Scrapyard;
class OilWell;
class Projectile;
Model(const char *filename); ///< Initialize the game state from the map given by #filename
~Model();
Tile *getTile(unsigned x, unsigned y); ///< Return the tile at (x,y)
const Tile *getTile(unsigned x, unsigned y) const;
Unit *getUnitAt(unsigned x, unsigned y, bool air); ///< Return the unit on the tile at (x, y), or NULL if that tile is empty
Unit *getUnit(unitID id); ///< Return the unit with the given unit ID
Unit *getUnitType(const char *type); ///< Get a unit representative of #type to construct a new unit with
void getUnitList(std::vector<unitID> &vec); ///< Get a list of unitIDs of all living units
void getScrapyardList(std::vector<Scrapyard*> &vec);
Scrapyard *getScrapyard(int id);
ICoord nearestScrapyardTo(int x, int y);
ICoord nearestFriendlyScrapyardTo(int x, int y, playerID owner);
ICoord spaceNearestTo(unsigned x, unsigned y, bool flying) const; ///< The nearest empty space, with a spiral search
inline unsigned getSizeX() const { return sizeX; }
inline unsigned getSizeY() const { return sizeY; }
bool isInBounds(int x, int y) { return x>0 && y>0 && x<(int)sizeX && y<(int)sizeY; }
void setRandomPlayers(int size);
unitID newUnitID();
void setUnitPosition(unitID unit, double x, double y);
void setUnitDestination(unitID unit, int x, int y);
void setUnitPath(unitID unit, int x, int y);
void putUnitInTransport(unitID unitId, unitID transport);
void deleteUnit(unitID id); ///< Remove unit #id (because it was killed)
unitID addUnit(playerID player, std::string unit, double x, double y, unitID unitId = 0);
playerID addPlayer();
playerID addPlayer(playerID id);
std::vector<Projectile> shotsPending;
std::list<Effect> effects;
std::vector<OilWell> oilWells;
unsigned short** getFog(playerID player);
void revealFogAround(unitID unit);
void revealFog(playerID player, int radius, int x, int y);
void concealFog(playerID player, int radius, int x, int y);
bool playerCanSee(playerID player, unsigned x, unsigned y);
std::map<playerID, unsigned short**> fogOfWar;
unsigned maxPlayers; // Max. players this map can have
unsigned maxPlayerID; // Highest player ID of a player who has actually joined
protected:
typedef std::map<unitID, Unit*> UnitMap;
typedef std::map<playerID, Player *> PlayerMap;
PlayerMap players;
unsigned sizeX, sizeY;
Tile **map;
std::vector<Scrapyard> scrapyards;
UnitMap units;
unsigned maxUnitID;
std::vector<int> randomPlayerIDs;
class MapLoadError : std::runtime_error {
public: MapLoadError(const std::string &message) : std::runtime_error(message) {}
};
void loadTileset(std::string filename, std::map<std::string, TileType*> &result);
};
//////////////////////////////////////////////////////////////////////////////
class Model::Tile
{
public:
Tile();
bool passable(bool air) const;
Image image() const;
/// This tile's type (eg dirt, grass, dirt-grass transition, etc.)
/// \sa Model::TileType
Model::TileType *type;
/// The index of any scrapyard this tile is a part of, or -1 for none.
int scrapyard;
int providesFuel :1;
/// The ID of any unit which is on this tile, or 0 if unoccupied.
/// (If a unit is moving, it may occupy more than one tile.)
unitID &unitAt(bool air) { return air?airUnit:unit; }
const unitID &unitAt(bool air) const { return air?airUnit:unit; }
protected:
unitID unit;
unitID airUnit;
};
struct Model::TileType
{
TileType(const char* name, Image image, bool passable)
: name(name), image(image), passable(passable) {}
const char* name;
Image image;
bool passable;
};
//////////////////////////////////////////////////////////////////////////////
class Model::Unit
{
public:
Unit(const char *filename);
const std::vector<UnitFrame*> getFrame(int frame);
Image mapViewImage();
inline unitID getId() const { return id; }
inline double getX() const { return x; }
inline double getY() const { return y; }
inline void setX(double x) { this->x = x; }
inline void setY(double y) { this->y = y; }
float getSpeed() const { return type->getSpeed(); }
//protected:
enum State {
move, // Will move to (destX,destY), shooting along the way
attack, // Will move to (destX,destY) and chase any targets encountered
fighting, // Attack-moved and encountered a target, now chasing it
patrol,
follow,
sinking, // Singing into the ground to convert a scrapyard (z goes from 0 to -1)
};
unitID id;
playerID owner;
const UnitInfo *type;
int hp;
int fuelMax; // measured in tiles
double fuel;
double x, y;
float z;
int nextX, nextY;
int destX, destY;
int destAngle, turretDestAngle; // What direction should this unit be facing? (degrees)
float angle, turretAngle;
bool turningToShoot;
bool inTransport;
float animTime;
float shootAnimTime;
State state;
bool moving;
unitID target, escort;
bool explicitTarget; // Whether this target was given by the player (otherwise it was assigned automatically)
double nextShotTime;
int burstFireTimer;
std::vector<unitID> loadedUnits;
};
//////////////////////////////////////////////////////////////////////////////
class Model::Player
{
public:
Player(const char *playerName, playerID playerId);
// Could add some more stuff, like score, or whatever
std::string name;
playerID id;
};
//////////////////////////////////////////////////////////////////////////////
const int scrapyardSightRadius = 10;
class Model::Scrapyard
{
public:
Scrapyard(playerID owner, unsigned x, unsigned y, unsigned sizeX, unsigned sizeY, int scrapyardId);
void produceNext();
std::string currentProduction() const;
void enqueue(std::string unit);
void cancel(int index);
void clear();
int getId() const { return id; }
playerID owner;
double startTime;
ICoord center;
ICoord size;
ICoord rally;
//std::string unitType, nextType;
std::vector<std::string> buildQueue;
int queuePos;
bool repeating;
protected:
int id;
};
//////////////////////////////////////////////////////////////////////////////
class Model::OilWell
{
public:
OilWell(unsigned x, unsigned y, unsigned sizeX, unsigned sizeY);
ICoord center, size;
};
//////////////////////////////////////////////////////////////////////////////
class Model::Projectile
{
public:
enum ProjectileType {
none = 0,
tankShell,
missile,
artilleryShell,
};
static ProjectileType getProjectileType(std::string str);
Projectile(Model *model, unitID shooter, ProjectileType type, int explosionType,
double targetX, double targetY, float speed, int damage, float splash, bool hitsAir);
float splash;
double startTime;
double startX, startY, startZ;
double targetX, targetY, targetZ;
float speed;
int damage;
bool hitsAir;
ProjectileType type;
int explosionType;
};
//////////////////////////////////////////////////////////////////////////////
inline Model::Tile *Model::getTile(unsigned x, unsigned y) { return &map[y][x]; }
inline const Model::Tile *Model::getTile(unsigned x, unsigned y) const { return &map[y][x]; }
#endif