1 #pragma once
2 
3 /** Classes to manage the various gamestates.
4 */
5 
6 #include "TinyXML/tinyxml.h"
7 
8 using std::vector;
9 using std::string;
10 using std::stringstream;
11 
12 //#include "game.h"
13 #include "common.h"
14 
15 namespace Gigalomania {
16 	class Image;
17 	class ImageButton;
18 	class Button;
19 	class PanelPage;
20 }
21 
22 using namespace Gigalomania;
23 
24 class PlayingGameState;
25 class ChooseGameTypePanel;
26 class ChooseDifficultyPanel;
27 class ChooseMenPanel;
28 class GamePanel;
29 class Sector;
30 class Army;
31 class Soldier;
32 class Building;
33 class Map;
34 class Design;
35 class Invention;
36 
37 const int offset_map_x_c = 8;
38 const int offset_map_y_c = 16;
39 
40 const int offset_land_x_c = 96;
41 const int offset_land_y_c = 50;
42 //const int offset_land_y_c = 34;
43 
44 // mustn't be too low, otherwise difficult to touch on Android (Galaxy Nexus)
45 //const int quit_button_offset_c = 16;
46 const int quit_button_offset_c = 24;
47 
48 const int offset_openpitmine_x_c = 32;
49 const int offset_openpitmine_y_c = 32;
50 
51 /*const int land_width_c =  300 - offset_land_x_c;
52 const int land_height_c = 210 - offset_land_y_c;*/
53 const int land_width_c =  204;
54 const int land_height_c = 160;
55 
56 //const int max_soldiers_in_sector_c = 1000;
57 
58 class Feature {
59 protected:
60 	Image **image;
61 	int n_frames;
62 	int xpos, ypos;
63 	bool at_front;
64 public:
Feature(Image * image[],int n_frames,int xpos,int ypos)65 	Feature(Image *image[],int n_frames,int xpos,int ypos) {
66 		this->image = image;
67 		this->n_frames = n_frames;
68 		this->xpos = xpos;
69 		this->ypos = ypos;
70 		this->at_front = false;
71 	}
72 
getImage(int counter)73 	const Image *getImage(int counter) const {
74 		return this->image[counter % n_frames];
75 	}
setImage(Image * image[],int n_frames)76 	void setImage(Image *image[], int n_frames) {
77 		this->image = image;
78 		this->n_frames = n_frames;
79 	}
80 	void draw() const;
getX()81 	int getX() const {
82 		return this->xpos;
83 	}
getY()84 	int getY() const {
85 		return this->ypos;
86 	}
setAtFront(bool at_front)87 	void setAtFront(bool at_front) {
88 		this->at_front = at_front;
89 	}
isAtFront()90 	bool isAtFront() const {
91 		return this->at_front;
92 	}
93 };
94 
95 class TimedEffect {
96 protected:
97 	int timeset;
98 	void (*func_finish) ();
99 public:
100 	TimedEffect();
101 	TimedEffect(int delay, void (*func_finish)());
~TimedEffect()102 	virtual ~TimedEffect() {
103 		if( func_finish != NULL ) {
104 			// we need to make a copy, incase this class is
105 			// destroyed from within the called function
106 			void (*temp_func_finish) ();
107 			temp_func_finish = func_finish;
108 			func_finish = NULL;
109 			temp_func_finish();
110 		}
111 	}
render()112 	virtual bool render() const {
113 		return false;
114 	}
115 };
116 
117 class AmmoEffect : public TimedEffect {
118 	PlayingGameState *gamestate;
119 	int gametimeset;
120 	int epoch;
121 	AmmoDirection dir;
122 	int xpos, ypos;
123 public:
124 	AmmoEffect(PlayingGameState *gamestate, int epoch, AmmoDirection dir, int xpos, int ypos);
125 	virtual bool render() const;
126 };
127 
128 class FadeEffect : public TimedEffect {
129 	Image *image; // used by SDL 1.2 (note, we still declare for SDL 2, to avoid having to include the SDL directories to find out the SDL_MAJOR_VERSION value)
130 	bool white;
131 	bool out;
132 public:
133 	FadeEffect(bool white,bool out,int delay, void (*func_finish)());
134 	virtual ~FadeEffect();
135 	virtual bool render() const;
136 };
137 
138 class FlashingSquare : public TimedEffect {
139 	int xpos, ypos;
140 public:
FlashingSquare(int xpos,int ypos)141 	FlashingSquare(int xpos, int ypos) : TimedEffect() {
142 		this->xpos = xpos;
143 		this->ypos = ypos;
144 	}
145 
146 	virtual bool render() const;
147 };
148 
149 class AnimationEffect : public TimedEffect {
150 	Image **images;
151 	int n_images;
152 	int xpos, ypos;
153 	int time_per_frame;
154 	bool dir;
155 public:
AnimationEffect(int xpos,int ypos,Image ** images,int n_images,int time_per_frame,bool dir)156 	AnimationEffect(int xpos, int ypos,Image **images, int n_images,int time_per_frame,bool dir) : TimedEffect() {
157 		this->images = images;
158 		this->n_images = n_images;
159 		this->xpos = xpos;
160 		this->ypos = ypos;
161 		this->time_per_frame = time_per_frame;
162 		this->dir = dir;
163 	}
164 	virtual bool render() const;
165 };
166 
167 class TextEffect : public TimedEffect {
168 	int xpos, ypos;
169 	string text;
170 	int duration;
171 public:
TextEffect(string text,int xpos,int ypos,int duration)172 	TextEffect(string text, int xpos, int ypos, int duration) : TimedEffect(), xpos(xpos), ypos(ypos), text(text), duration(duration) {
173 	}
174 	virtual bool render() const;
175 };
176 
177 class GameState {
178 protected:
179 	int client_player;
180 	FadeEffect *fade;
181 	FadeEffect *whitefade;
182 	PanelPage *screen_page;
183 	bool mobile_ui_display_mouse; // if mobile_ui is true, should we display the mouse icon?
184 	Image *mouse_image;
185 	int mouse_off_x, mouse_off_y;
186 	enum ConfirmType {
187 		CONFIRMTYPE_UNKNOWN = -1,
188 		CONFIRMTYPE_NEWGAME = 0,
189 		CONFIRMTYPE_QUITGAME = 1
190 	};
191 	ConfirmType confirm_type;
192     PanelPage *confirm_window;
193     Button *confirm_button_1;
194     Button *confirm_button_2;
195     Button *confirm_button_3;
196 
197 	void setDefaultMouseImage();
198     virtual void createQuitWindow();
199 
200 public:
201 	GameState(int client_player);
202 	virtual ~GameState();
203 
getScreenPage()204 	PanelPage *getScreenPage() {
205 		return screen_page;
206 	}
setClientPlayer(int client_player)207 	void setClientPlayer(int client_player) {
208 		this->client_player = client_player;
209 	}
getClientPlayer()210 	int getClientPlayer() const {
211 		return this->client_player;
212 	}
213 	virtual void reset();
214 	virtual void draw();
update()215 	virtual void update() {};
216 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
217     virtual void requestQuit(bool force_quit);
requestConfirm()218 	virtual void requestConfirm() {
219 	}
220 
221 	void fadeScreen(bool out, int delay, void (*func_finish)());
222 	void whiteFlash();
addTextEffect(TextEffect * effect)223 	virtual void addTextEffect(TextEffect *effect) {
224 		// only implemented for PlayingGameState
225 	}
226     void closeConfirmWindow();
hasConfirmWindow()227     bool hasConfirmWindow() const {
228         return confirm_window != NULL;
229     }
230 
saveState(stringstream & stream)231 	virtual void saveState(stringstream &stream) const {
232 	}
233 };
234 
235 class ChooseGameTypeGameState : public GameState {
236 	ChooseGameTypePanel *choosegametypePanel;
237 
238 public:
239 	ChooseGameTypeGameState(int client_player);
240 	virtual ~ChooseGameTypeGameState();
241 
242 	virtual void reset();
243 	virtual void draw();
244 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
245 
246 	ChooseGameTypePanel *getChooseGameTypePanel();
247 };
248 
249 class ChooseDifficultyGameState : public GameState {
250 	ChooseDifficultyPanel *choosedifficultyPanel;
251 
252 public:
253 	ChooseDifficultyGameState(int client_player);
254 	virtual ~ChooseDifficultyGameState();
255 
256 	virtual void reset();
257 	virtual void draw();
258 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
259 
260 	ChooseDifficultyPanel *getChooseDifficultyPanel();
261 };
262 
263 class ChoosePlayerGameState : public GameState {
264 	Button *button_red;
265 	Button *button_yellow;
266 	Button *button_green;
267 	Button *button_blue;
268 public:
269 	ChoosePlayerGameState(int client_player);
270 	virtual ~ChoosePlayerGameState();
271 
272 	virtual void reset();
273 	virtual void draw();
274 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
275 };
276 
277 class ChooseTutorialGameState : public GameState {
278 	vector<Button *> buttons;
279 public:
280 	ChooseTutorialGameState(int client_player);
~ChooseTutorialGameState()281 	virtual ~ChooseTutorialGameState() {
282 	}
283 
284 	virtual void reset();
285 	virtual void draw();
286 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
287 };
288 
289 class PlaceMenGameState : public GameState {
290 	ChooseMenPanel *choosemenPanel;
291 	int off_x, off_y;
292 	PanelPage *map_panels[map_width_c][map_height_c];
293 	int start_map_x, start_map_y;
294 
295 public:
296 	PlaceMenGameState(int client_player);
297 	virtual ~PlaceMenGameState();
298 
299 	virtual void reset();
300 	virtual void draw();
301 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
302     virtual void requestQuit(bool force_quit);
303 	virtual void requestConfirm();
304 
305 	ChooseMenPanel *getChooseMenPanel();
306 	const PanelPage *getMapPanel(int x, int y) const;
307 	PanelPage *getMapPanel(int x, int y);
getStartMapX()308 	int getStartMapX() const {
309 		return this->start_map_x;
310 	}
getStartMapY()311 	int getStartMapY() const {
312 		return this->start_map_y;
313 	}
314 	void setStartMapPos(int start_map_x, int start_map_y );
315 	void requestNewGame();
316 };
317 
318 class PlayingGameState : public GameState {
319 	const Sector *current_sector; // saved
320 	GamePanel *gamePanel;
321 	ImageButton *speed_button;
322 	ImageButton *shield_buttons[n_players_c];
323 	ImageButton *shield_blank_button;
324 	PanelPage *shield_number_panels[n_players_c];
325 	PanelPage *land_panel;
326 	Button *pause_button;
327 	Button *quit_button;
328 	Button *tutorial_next_button;
329 	int flag_frame_step;
330 	int defenders_last_time_update;
331 	int soldier_last_time_moved_x;
332 	int soldier_last_time_moved_y;
333 	int cannon_last_time_moved_x;
334 	int cannon_last_time_moved_y;
335 	int air_last_time_moved;
336 	int soldiers_last_time_turned;
337 	const Army *selected_army;
338 	//int n_soldiers[n_players_c];
339 	//Vector *soldiers[n_players_c];
340 	vector<Soldier *> soldiers[n_players_c];
341 	vector<TimedEffect *> effects;
342 	//Vector *ammo_effects;
343 	vector<TimedEffect *> ammo_effects;
344 	TextEffect *text_effect;
345 	/*SmokeParticleSystem *smokeParticleSystem;
346 	SmokeParticleSystem *smokeParticleSystem_busy;*/
347 	enum MapDisplay {
348 		MAPDISPLAY_MAP = 0,
349 		MAPDISPLAY_UNITS = 1
350 	};
351 	MapDisplay map_display;
352 	int player_asking_alliance; // saved
353 	PanelPage *map_panels[map_width_c][map_height_c];
354 	Button *alliance_yes;
355 	Button *alliance_no;
356 	int n_deaths[n_players_c][n_epochs_c+1]; // saved
357 
358 	void getFlagOffset(int *offset_x, int *offset_y, int epoch) const;
359 	bool openPitMine();
360 	bool validSoldierLocation(int epoch,int xpos,int ypos);
361 	bool buildingMouseClick(int s_m_x,int s_m_y,bool m_left,bool m_right,Building *building);
362 	void moveTo(int map_x,int map_y);
363 	void blueEffect(int xpos,int ypos,bool dir);
364 	void refreshShieldNumberPanels();
365 	void setupMapGUI();
366 	bool readSectorsProcessLine(Map *map, char *line, bool *done_header, int *sec_x, int *sec_y);
367 	bool readSectors(Map *map);
368 	void loadStateParseXMLMapXY(int *map_x, int *map_y, const TiXmlAttribute *attribute);
369     virtual void createQuitWindow();
370 
371 	//static void buttonSpeedClick(void *data, int arg, bool m_left, bool m_middle, bool m_right);
372 public:
373 
374 	PlayingGameState(int client_player);
375 	virtual ~PlayingGameState();
376 
377 	void createSectors( int x, int y, int n_men);
378 
379 	virtual void reset();
380 	virtual void draw();
381 	virtual void update();
382 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
383     virtual void requestQuit(bool force_quit);
384 	virtual void requestConfirm();
385 
386 	GamePanel *getGamePanel();
387 	//Sector *getCurrentSector();
388 	const Sector *getCurrentSector() const;
389 	bool viewingActiveClientSector() const;
390 	bool viewingAnyClientSector() const; // includes shutdown sectors
391 	void resetShieldButtons();
392 	void setFlashingSquare(int xpos,int ypos);
393 	void addBuilding(Building *building);
394 	void refreshSoldiers(bool flash);
395 	void deathEffect(int xpos,int ypos);
396 	void explosionEffect(int xpos,int ypos);
addTextEffect(TextEffect * effect)397 	virtual void addTextEffect(TextEffect *effect) {
398 		if( text_effect != NULL ) {
399 			delete text_effect;
400 		}
401 		text_effect = effect;
402 	}
403 	void refreshButtons();
getSelectedArmy()404 	const Army *getSelectedArmy() const {
405 		return this->selected_army;
406 	}
clearSelectedArmy()407 	void clearSelectedArmy() {
408 		this->selected_army = NULL;
409 	}
410 	bool canRequestAlliance(int player,int i) const;
411 	void requestAlliance(int player,int i,bool human);
412 	void makeAlliance(int player,int i);
getPlayerAskingAlliance()413 	const int getPlayerAskingAlliance() const {
414 		return this->player_asking_alliance;
415 	}
416 	void cancelPlayerAskingAlliance();
registerDeath(int player,int epoch)417 	void registerDeath(int player, int epoch) {
418 		n_deaths[player][epoch]++;
419 	}
420 	void refreshTimeRate();
421 
422 	// functions for requesting a modification to the game world based on client user input
423 	// for now, these functions make the modification themselves directly - later on, we can go via a server class
424 	void setNDesigners(int sector_x, int sector_y, int n_designers);
425 	void setNWorkers(int sector_x, int sector_y, int n_workers);
426 	void setFAmount(int sector_x, int sector_y, int n_famount);
427 	void setNMiners(int sector_x, int sector_y, Id element, int n_miners);
428 	void setNBuilders(int sector_x, int sector_y, Type type, int n_builders);
429 
430 	void setCurrentDesign(int sector_x, int sector_y, Design *design);
431 	void setCurrentManufacture(int sector_x, int sector_y, Design *design);
432 
433 	void assembledArmyEmpty(int sector_x, int sector_y);
434 	bool assembleArmyUnarmed(int sector_x, int sector_y, int n);
435 	bool assembleArmy(int sector_x, int sector_y, int epoch, int n);
436 	bool assembleAll(int sector_x, int sector_y, bool include_unarmed);
437 	void returnAssembledArmy(int sector_x, int sector_y);
438 	bool returnArmy(int sector_x, int sector_y, int src_x, int src_y);
439 	bool moveArmyTo(int src_x, int src_y, int target_x, int target_y);
440 	bool moveAssembledArmyTo(int src_x, int src_y, int target_x, int target_y);
441 	bool nukeSector(int src_x, int src_y, int target_x, int target_y);
442 
443 	void deployDefender(int sector_x, int sector_y, Type type, int turret, int epoch);
444 	void returnDefender(int sector_x, int sector_y, Type type, int turret);
445 	void useShield(int sector_x, int sector_y, Type type, int shield);
446 
447 	void trashDesign(int sector_x, int sector_y, Invention *invention);
448 
449 	void shutdown(int sector_x, int sector_y);
450 	//current_sector->shutdown();
451 
452 	virtual void saveState(stringstream &stream) const;
453 	void loadStateParseXMLNode(const TiXmlNode *parent);
454 };
455 
456 class EndIslandGameState : public GameState {
457 public:
EndIslandGameState(int client_player)458 	EndIslandGameState(int client_player) : GameState(client_player) {
459 	}
~EndIslandGameState()460 	virtual ~EndIslandGameState() {
461 	}
462 
463 	virtual void reset();
464 	virtual void draw();
465 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
466     virtual void requestQuit(bool force_quit);
467 };
468 
469 class GameCompleteGameState : public GameState {
470 public:
GameCompleteGameState(int client_player)471 	GameCompleteGameState(int client_player) : GameState(client_player) {
472 	}
~GameCompleteGameState()473 	virtual ~GameCompleteGameState() {
474 	}
475 
476 	virtual void reset();
477 	virtual void draw();
478 	virtual void mouseClick(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click);
479     virtual void requestQuit(bool force_quit);
480 };
481