-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.h
427 lines (372 loc) · 11.6 KB
/
game.h
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
#pragma once
/** Main game file, mainly contains various setup functions.
*/
namespace Gigalomania {
class Screen;
class Image;
class PanelPage;
class Sample;
}
using namespace Gigalomania;
class Invention;
class Weapon;
class Element;
class Sector;
class GameState;
class PlayingGameState;
class Player;
class Application;
class TextEffect;
#include "common.h"
using std::string;
/*struct FSOUND_SAMPLE;
typedef FSOUND_SAMPLE Sample;*/
extern bool onemousebutton;
extern bool mobile_ui;
bool oneMouseButtonMode();
extern bool using_old_gfx;
extern bool is_testing;
extern Application *application;
extern const char *maps_dirname;
#if !defined(__ANDROID__) && defined(__linux)
extern const char *alt_maps_dirname;
#endif
extern int offset_flag_x_c;
extern int offset_flag_y_c;
//extern int lastmouseclick_time;
enum GameStateID {
GAMESTATEID_UNDEFINED = -1,
GAMESTATEID_CHOOSEGAMETYPE = 0,
GAMESTATEID_CHOOSEDIFFICULTY,
GAMESTATEID_CHOOSEPLAYER,
GAMESTATEID_PLACEMEN,
GAMESTATEID_PLAYING,
GAMESTATEID_ENDISLAND,
GAMESTATEID_GAMECOMPLETE
};
extern GameStateID gameStateID;
extern bool state_changed;
//extern bool paused;
enum GameResult {
GAMERESULT_UNDEFINED = 0,
GAMERESULT_WON,
GAMERESULT_QUIT,
GAMERESULT_LOST
};
extern GameResult gameResult;
const int default_width_c = 320;
//const int default_height_c = 256;
const int default_height_c = 240;
//extern int default_width_c;
//extern int default_height_c;
extern float scale_width;
extern float scale_height;
//extern int screen_width;
//extern int screen_height;
/*const int screen_width = scale_width * default_width_c;
//const int screen_height = scale_height * default_height_c;
const int screen_height = scale_height * 256;
//const int screen_height = scale_height * 240;*/
const int infinity_c = 31;
//const int end_epoch_c = 9; // use this to have the last epoch game
const int end_epoch_c = -1; // use this to have the last epoch as being 2100AD
const int biplane_epoch_c = 6;
const int jetplane_epoch_c = 7;
const int nuclear_epoch_c = 8;
const int spaceship_epoch_c = 9;
const int laser_epoch_c = 9;
const int n_shields_c = 4;
const int n_playershields_c = 16;
const int n_flag_frames_c = 4;
const int n_defender_frames_c = 8;
//const int n_attacker_frames_c = 16;
const int n_attacker_directions_c = 4;
const int max_attacker_frames_c = 9;
const int n_trees_c = 4;
const int n_clutter_c = 3;
const int n_tree_frames_c = 4;
const int n_nuke_frames_c = 2;
const int n_saucer_frames_c = 4;
const int n_death_flashes_c = 3;
const int n_blue_flashes_c = 7;
const int n_explosions_c = 59;
const int n_coast_c = 15;
const int n_map_sq_c = 16;
//extern Image *player_select;
extern Image *background;
extern Image *land[];
extern Image *fortress[];
extern Image *mine[];
extern Image *factory[];
extern Image *lab[];
extern Image *men[];
extern Image *unarmed_man;
extern Image *flags[n_players_c][n_flag_frames_c];
extern Image *panel_design;
//extern Image *panel_design_dark;
extern Image *panel_lab;
extern Image *panel_factory;
extern Image *panel_shield;
extern Image *panel_defence;
extern Image *panel_attack;
extern Image *panel_bloody_attack;
extern Image *panel_knowndesigns;
extern Image *panel_twoattack;
extern Image *panel_build[];
extern Image *panel_building[];
extern Image *panel_bigdesign;
extern Image *panel_biglab;
extern Image *panel_bigfactory;
extern Image *panel_bigshield;
extern Image *panel_bigdefence;
extern Image *panel_bigattack;
extern Image *panel_bigbuild;
extern Image *panel_bigknowndesigns;
extern Image *numbers_blue[];
extern Image *numbers_grey[];
extern Image *numbers_white[];
extern Image *numbers_orange[];
extern Image *numbers_yellow[];
extern Image *numbers_largegrey[];
extern Image *numbers_largeshiny[];
extern Image *numbers_small[n_players_c][10];
extern Image *numbers_half;
extern Image *letters_large[];
extern Image *letters_small[];
extern Image *mouse_pointers[];
extern Image *playershields[];
extern Image *building_health;
extern Image *dash_grey;
extern Image *icon_shield;
extern Image *icon_defence;
extern Image *icon_weapon;
extern Image *icon_shields[];
extern Image *icon_defences[];
extern Image *icon_weapons[];
extern Image *numbered_defences[];
extern Image *numbered_weapons[];
extern Image *icon_elements[];
extern Image *icon_clocks[];
extern Image *icon_infinity;
extern Image *icon_bc;
extern Image *icon_ad;
extern Image *icon_ad_shiny;
extern Image *icon_towers[];
extern Image *icon_armies[];
extern Image *icon_nuke_hole;
extern Image *mine_gatherable_small;
extern Image *mine_gatherable_large;
extern Image *icon_ergo;
extern Image *icon_trash;
extern Image *coast_icons[n_coast_c];
extern Image *map_sq[MAP_N_COLOURS][n_map_sq_c];
extern Image *defenders[n_players_c][n_epochs_c][n_defender_frames_c];
extern Image *nuke_defences[]; // epoch 8
//extern Image *attackers_walking[n_players_c][n_epochs_c+1][n_attacker_frames_c]; // epochs 6-9 are special case!
extern int n_attacker_frames[n_epochs_c+1][n_attacker_directions_c];
extern Image *attackers_walking[n_players_c][n_epochs_c+1][n_attacker_directions_c][max_attacker_frames_c]; // epochs 6-9 are special case!
extern Image *planes[n_players_c][n_epochs_c]; // epochs 6,7 only
extern Image *nukes[n_players_c][n_nuke_frames_c]; // epoch 8
extern Image *saucers[n_players_c][n_saucer_frames_c]; // epoch 9
extern Image *attackers_ammo[n_epochs_c][N_ATTACKER_AMMO_DIRS];
extern Image *icon_openpitmine;
extern Image *icon_trees[n_trees_c][n_tree_frames_c];
extern Image *icon_clutter[n_clutter_c];
extern Image *flashingmapsquare;
extern Image *mapsquare;
extern Image *arrow_left;
extern Image *arrow_right;
extern Image *death_flashes[];
extern Image *blue_flashes[];
extern Image *explosions[];
extern Image *icon_mice[];
extern Image *icon_speeds[];
extern Image *smoke_image;
extern Image *background_islands;
extern Sample *s_design_is_ready;
extern Sample *s_ergo;
extern Sample *s_advanced_tech;
extern Sample *s_fcompleted;
extern Sample *s_on_hold;
extern Sample *s_running_out_of_elements;
extern Sample *s_tower_critical;
extern Sample *s_sector_destroyed;
extern Sample *s_mine_destroyed;
extern Sample *s_factory_destroyed;
extern Sample *s_lab_destroyed;
extern Sample *s_itis_all_over;
extern Sample *s_conquered;
extern Sample *s_won;
extern Sample *s_weve_nuked_them;
extern Sample *s_weve_been_nuked;
extern Sample *s_alliance_yes[n_players_c];
extern Sample *s_alliance_no[n_players_c];
extern Sample *s_alliance_ask[n_players_c];
extern Sample *s_cant_nuke_ally;
extern Sample *s_explosion;
extern Sample *s_scream;
extern Sample *s_buildingdestroyed;
extern Sample *s_guiclick;
extern Sample *s_biplane;
extern Sample *s_jetplane;
extern Sample *s_spaceship;
extern const int epoch_dates[];
extern const char *epoch_names[];
extern Invention *invention_shields[];
extern Invention *invention_defences[];
extern Weapon *invention_weapons[];
extern Element *elements[];
extern Player *players[];
enum GameMode {
GAMEMODE_SINGLEPLAYER = 0,
GAMEMODE_MULTIPLAYER_SERVER = 1,
GAMEMODE_MULTIPLAYER_CLIENT = 2
};
extern GameMode gameMode;
enum GameType {
GAMETYPE_SINGLEISLAND = 0,
GAMETYPE_ALLISLANDS = 1
};
extern GameType gameType;
enum DifficultyLevel {
DIFFICULTY_EASY = 0,
DIFFICULTY_MEDIUM,
DIFFICULTY_HARD,
DIFFICULTY_N_LEVELS
};
extern DifficultyLevel difficulty_level;
int getMenAvailable();
int getNSuspended();
//extern int n_men_store;
//extern int n_men_for_this_island;
extern int start_epoch;
extern int n_sub_epochs;
enum PlayerMode {
PLAYER_DEMO = -2,
PLAYER_NONE = -1
};
bool isDemo();
//extern int human_player;
extern int end_game_time;
extern bool pref_sound_on;
extern bool pref_music_on;
extern bool pref_disallow_nukes;
void savePrefs();
class Map {
string name;
string filename;
MapColour colour;
int n_opponents;
Sector *sectors[map_width_c][map_height_c];
bool sector_at[map_width_c][map_height_c];
bool reserved[map_width_c][map_height_c]; // if true, don't use for starting players - used for testing
//bool temp[map_width_c][map_height_c];
//void clearTemp();
public:
Map(MapColour colour,int n_opponents,const char *name);
~Map();
MapColour getColour() const {
return this->colour;
}
int getNOpponents() const {
return this->n_opponents;
}
const Sector *getSector(int x, int y) const;
Sector *getSector(int x, int y);
bool isSectorAt(int x, int y) const;
void newSquareAt(int x,int y);
void createSectors(PlayingGameState *gamestate, int epoch);
#if 0
void checkSectors() const;
#endif
void freeSectors();
const char *getName() const {
return name.c_str();
}
const char *getFilename() const {
return filename.c_str();
}
void setFilename(const char *filename) {
this->filename = filename;
}
int getNSquares() const;
void draw(int offset_x, int offset_y) const;
void findRandomSector(int *rx,int *ry) const;
bool isReserved(int x, int y) const {
return this->reserved[x][y];
}
void setReserved(int x, int y, bool r) {
this->reserved[x][y] = r;
}
void canMoveTo(bool temp[map_width_c][map_height_c], int sx,int sy,int player) const;
void calculateStats() const;
};
extern Screen *screen;
//extern GameState *gamestate;
const int max_islands_per_epoch_c = 3;
extern Map *maps[n_epochs_c][max_islands_per_epoch_c];
extern Map *map;
const Map *getMap();
bool readLineFromRWOps(bool &ok, struct SDL_RWops *file, char *buffer, char *line, int MAX_LINE, int &buffer_offset, int &newline_index, bool &reached_end);
void keypressEscape();
void togglePause();
bool isPaused();
void mouseClick(int m_x, int m_y, bool m_left, bool m_middle, bool m_right, bool click);
void updateGame();
void drawGame();
void fadeMusic(int duration_ms);
void playGame(int n_args, char *args[]);
void placeTower();
bool playerAlive(int player);
void quitGame();
void setClientPlayer(int set_client_player);
void newGame();
void nextEpoch();
void nextIsland();
void returnToChooseIsland();
void startNewGame();
void setGameStateID(GameStateID state);
void endIsland();
void setupPlayers();
bool loadGameInfo(DifficultyLevel *difficulty, int *player, int *n_men, int suspended[n_players_c], int *epoch, bool completed[max_islands_per_epoch_c], int slot);
bool loadGame(int slot);
void saveGame(int slot);
bool validPlayer(int player);
void addTextEffect(TextEffect *effect);
#if defined(__ANDROID__)
// JNI for Android
void launchUrl(string url);
#endif
// game constants
const int SHORT_DELAY = 4000;
const int nuke_delay_c = 250;
const int gameticks_per_hour_c = 200;
const int hours_per_day_c = 12;
const int mine_epoch_c = 3;
const int factory_epoch_c = 4;
const int lab_epoch_c = 5;
//const int air_epoch_c = 6;
/* These values have been checked to be correct (for Epoch 1, at least -
* presumably this doesn't affect things?)
*/
const int DESIGNTIME_M3 = 20;
const int DESIGNTIME_M2 = 30;
const int DESIGNTIME_M1 = 40;
const int DESIGNTIME_0 = 50;
const int DESIGNTIME_1 = 100;
const int DESIGNTIME_2 = 200;
const int DESIGNTIME_3 = 400;
/* These values have been checked to be correct (for Epoch 1, at least -
* presumably this doesn't affect things?)
*/
const int MANUFACTURETIME_0 = 15;
const int MANUFACTURETIME_1 = 30;
const int MANUFACTURETIME_2 = 45;
const int MANUFACTURETIME_3 = 60; // unknown
/* These values have been checked to be correct (for Epoch 1, at least -
* presumably this doesn't affect things?)
*/
const int BUILDTIME_TOWER = 80;
const int BUILDTIME_MINE = 40;
const int BUILDTIME_FACTORY = 40;
const int BUILDTIME_LAB = 40;