1 //---------------------------------------------------------------------------
2 #include "stdafx.h"
3 
4 #include <cassert>
5 #include <cmath> // n.b., needed on Linux at least
6 #include <cstdlib> // n.b., needed on Linux at least (for abs)
7 #include <cstdio> // n.b., needed on Linux at least
8 
9 #include <sstream>
10 using std::stringstream;
11 
12 #ifdef _WIN32
13 #include <windows.h>
14 #include <shellapi.h>
15 #endif
16 
17 #include "gui.h"
18 #include "sector.h"
19 #include "player.h"
20 #include "game.h"
21 #include "gamestate.h"
22 #include "utils.h"
23 #include "screen.h"
24 #include "image.h"
25 
26 //---------------------------------------------------------------------------
27 
28 const int offset_panel_x_c = 0;
29 const int offset_panel_y_c = 100;
30 const int offset_attack_x_c = 4;
31 const int space_attack_x_c = 18;
32 
33 const int build_step_y_c = 40;
34 
processClick(ClickFunc * clickFunc,PanelPage * panel,void * data,int arg,PanelPage * caller_button,bool m_left,bool m_middle,bool m_right,bool click)35 void processClick(ClickFunc *clickFunc, PanelPage *panel, void *data, int arg, PanelPage *caller_button, bool m_left, bool m_middle, bool m_right, bool click) {
36 	// wrapper function to handle one-mouse-button UI support
37 	if( game_g->oneMouseButtonMode() && click) {
38 		LOG("open onemousebutton panel\n");
39 		OneMouseButtonPanel *oneMouseButtonPanel = new OneMouseButtonPanel(clickFunc, data, arg, caller_button);
40 		//panel->addToPanel(panel->getPage(), oneMouseButtonPanel);
41 		panel->add(oneMouseButtonPanel);
42 		oneMouseButtonPanel->setModal();
43 		if( caller_button->getInfoLMB() != NULL && game_g->isMobileUI() ) {
44 			game_g->addTextEffect(new TextEffect(caller_button->getInfoLMB(), 160, caller_button->getTop(), 3000));
45 		}
46 		LOG("open onemousebutton panel done\n");
47 	}
48 	else if( !game_g->oneMouseButtonMode() && !click ) {
49 		//buttonNMenClick(panel, m_left, m_middle, m_right);
50 		//(*clickFunc)(panel, arg, m_left, m_middle, m_right);
51 		(*clickFunc)(data, arg, m_left, m_middle, m_right);
52 	}
53 }
54 
55 //OneMouseButtonPanel::OneMouseButtonPanel(ClickFunc *clickFunc, void *data, PanelPage *caller_button) : PanelPage(caller_button->getLeft() - 16, caller_button->getTop(), caller_button->getWidth() + 32, 64), clickFunc(clickFunc), data(data) {
OneMouseButtonPanel(ClickFunc * clickFunc,void * data,int arg,PanelPage * caller_button)56 OneMouseButtonPanel::OneMouseButtonPanel(ClickFunc *clickFunc, void *data, int arg, PanelPage *caller_button) : PanelPage(caller_button->getOffsetX() - 32, caller_button->getOffsetY(), caller_button->getWidth() + 64, 32), clickFunc(clickFunc), data(data), arg(arg) {
57 	this->button_left = new ImageButton(0, 0, game_g->arrow_left);
58     //this->button_left->setAlpha(true, 160);
59 	this->add(this->button_left);
60 	this->button_right = new ImageButton(32 + caller_button->getWidth(), 0, game_g->arrow_right);
61     //this->button_right->setAlpha(true, 160);
62     this->add(this->button_right);
63 }
64 
input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click)65 void OneMouseButtonPanel::input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click) {
66 	/*if( caller_button == NULL ) {
67 		LOG("caller_button NULL - delete onemousebuttonpanel\n");
68 		delete this;
69 	}
70 	else*/ if( m_left && !click && this->button_left->mouseOver(m_x, m_y) ) {
71 		(*clickFunc)(data, arg, true, false, false);
72 	}
73 	else if( m_left && !click && this->button_right->mouseOver(m_x, m_y) ) {
74 		(*clickFunc)(data, arg, false, false, true);
75 	}
76     else if( m_left && !this->mouseOver(m_x, m_y) ) {
77         // must do this whether click is true or false, so that the arrows can be removed, and another action taken, with the same click!
78 		LOG("delete onemousebuttonpanel\n");
79 		delete this;
80 	}
81 }
82 
ChooseGameTypePanel()83 ChooseGameTypePanel::ChooseGameTypePanel() : MultiPanel(1, 0, 0) {
84 	this->c_page = 0;
85 	this->addToPanel(0, new Button(105, 50, "CHOOSE A GAME TYPE", game_g->letters_large));
86 	if( !game_g->isUsingOldGfx() ) {
87 		// tutorial not supported due to font/layout being different
88 	    this->button_tutorial = new Button(132, 90, "TUTORIAL", game_g->letters_large);
89 		this->button_tutorial->setInfoLMB("play tutorial");
90 		this->addToPanel(0, button_tutorial);
91 	}
92 	else {
93 		button_tutorial = NULL;
94 	}
95     this->button_singleisland = new Button(120, 120, "SINGLE ISLAND", game_g->letters_large);
96 	this->button_singleisland->setInfoLMB("choose to play on\nany island");
97 	this->addToPanel(0, button_singleisland);
98     this->button_allislands = new Button(125, 150, "ALL ISLANDS", game_g->letters_large);
99 	this->button_allislands->setInfoLMB("start on first age and\nplay full game");
100 	this->addToPanel(0, button_allislands);
101 }
102 
input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click)103 void ChooseGameTypePanel::input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click) {
104 	MultiPanel::input(m_x, m_y, m_left, m_middle, m_right, click);
105 	if( this->hasModal() ) {
106 		return;
107 	}
108 	//bool m_left = mouse_left(m_b);
109 	//bool m_right = mouse_right(m_b);
110 
111 	if( m_left && click && button_tutorial != NULL && this->button_tutorial->mouseOver(m_x, m_y) ) {
112         registerClick();
113 		game_g->setGameType(GAMETYPE_TUTORIAL);
114         game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
115 	}
116 	else if( m_left && click && this->button_singleisland->mouseOver(m_x, m_y) ) {
117         registerClick();
118 		game_g->setGameType(GAMETYPE_SINGLEISLAND);
119         game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
120 	}
121 	else if( m_left && click && this->button_allislands->mouseOver(m_x, m_y) ) {
122         registerClick();
123 		game_g->setGameType(GAMETYPE_ALLISLANDS);
124 		//game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
125 		game_g->setGameStateID(GAMESTATEID_CHOOSEDIFFICULTY);
126 	}
127 }
128 
ChooseDifficultyPanel()129 ChooseDifficultyPanel::ChooseDifficultyPanel() : MultiPanel(1, 0, 0) {
130 	this->c_page = 0;
131 	this->addToPanel(0, new Button(105, 50, "CHOOSE DIFFICULTY", game_g->letters_large));
132     this->button_easy = new Button(120, 90, "EASY", game_g->letters_large);
133 	this->addToPanel(0, button_easy);
134     this->button_medium = new Button(120, 120, "MEDIUM", game_g->letters_large);
135 	this->addToPanel(0, button_medium);
136     this->button_hard = new Button(120, 150, "HARD", game_g->letters_large);
137 	this->addToPanel(0, button_hard);
138     this->button_ultra = new Button(120, 180, "ULTRA", game_g->letters_large);
139 	this->addToPanel(0, button_ultra);
140 }
141 
input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click)142 void ChooseDifficultyPanel::input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click) {
143 	MultiPanel::input(m_x, m_y, m_left, m_middle, m_right, click);
144 	if( this->hasModal() ) {
145 		return;
146 	}
147 	//bool m_left = mouse_left(m_b);
148 	//bool m_right = mouse_right(m_b);
149 
150 	if( m_left && click && this->button_easy->mouseOver(m_x, m_y) ) {
151         registerClick();
152 		game_g->setDifficultyLevel(DIFFICULTY_EASY);
153 		game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
154 	}
155 	else if( m_left && click && this->button_medium->mouseOver(m_x, m_y) ) {
156         registerClick();
157 		game_g->setDifficultyLevel(DIFFICULTY_MEDIUM);
158 		game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
159 	}
160 	else if( m_left && click && this->button_hard->mouseOver(m_x, m_y) ) {
161         registerClick();
162 		game_g->setDifficultyLevel(DIFFICULTY_HARD);
163 		game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
164 	}
165 	else if( m_left && click && this->button_ultra->mouseOver(m_x, m_y) ) {
166         registerClick();
167 		game_g->setDifficultyLevel(DIFFICULTY_ULTRA);
168 		game_g->setGameStateID(GAMESTATEID_CHOOSEPLAYER);
169 	}
170 }
171 
ChooseMenPanel(PlaceMenGameState * gamestate)172 ChooseMenPanel::ChooseMenPanel(PlaceMenGameState *gamestate) : MultiPanel(N_STATES, 0, 0), gamestate(gamestate) {
173 	this->c_page = (int)STATE_CHOOSEISLAND;
174 	this->n_men = 0;
175 
176 	this->button_nextisland = NULL;
177     int mx = 80;
178     const int start_y = 76;
179     int cy = start_y;
180     int step_y = 28;
181 	int fw = game_g->letters_large[0]->getScaledWidth();
182 	if( game_g->getMap(game_g->getStartEpoch(), 1) != NULL ) {
183         this->button_nextisland = new Button((int)(mx - 5.5*fw), cy, "NEXT ISLAND", game_g->letters_large);
184         cy += step_y;
185         this->addToPanel(STATE_CHOOSEISLAND, button_nextisland);
186 	}
187     else {
188         cy += step_y;
189     }
190 	this->button_nextepoch = NULL;
191 	if( game_g->getGameType() == GAMETYPE_SINGLEISLAND ) {
192         this->button_nextepoch = new Button((int)(mx - 4.0*fw), cy, "NEXT AGE", game_g->letters_large);
193         cy += step_y;
194         this->addToPanel(STATE_CHOOSEISLAND, button_nextepoch);
195 	}
196     this->button_options = new Button((int)(mx - 3.5*fw), cy, "OPTIONS", game_g->letters_large);
197     cy += step_y;
198     this->addToPanel(STATE_CHOOSEISLAND, button_options);
199     this->button_play = new Button((int)(mx - 5.5*fw), cy, "PLAY ISLAND", game_g->letters_large);
200     cy += step_y;
201     this->addToPanel(STATE_CHOOSEISLAND, button_play);
202 #if defined(_WIN32) || defined(__ANDROID__)
203     this->button_help = new Button((int)(mx - 5.5*fw), cy, "ONLINE HELP", game_g->letters_large);
204     cy += step_y;
205     this->addToPanel(STATE_CHOOSEISLAND, button_help);
206 #endif
207 #if defined(__ANDROID__)
208 	// user can use back button on Android to quit
209 	this->button_quit = NULL;
210 #else
211     this->button_quit = new Button((int)(mx - 2.0*fw), cy, "QUIT", game_g->letters_large);
212     cy += step_y;
213     this->addToPanel(STATE_CHOOSEISLAND, button_quit);
214 #endif
215 
216     //this->button_nmen = new PanelPage(mx - 12, 154, 24, 12);
217     this->button_nmen = new PanelPage(mx - 12, 154, 24, 32);
218     this->addToPanel(STATE_CHOOSEMEN, button_nmen);
219 
220 	this->button_cancel = new Button((int)(mx - 10.5*fw), 210, "CHOOSE ANOTHER ISLAND", game_g->letters_large);
221     this->addToPanel(STATE_CHOOSEMEN, button_cancel);
222 
223     cy = start_y - 52;
224     step_y = 26;
225 	if( game_g->getGameType() != GAMETYPE_ALLISLANDS ) {
226 		cy += 2*step_y; // so that options are aligned vertically better
227 	}
228     this->button_continue = new Button((int)(mx - 4.0*fw), cy, "CONTINUE", game_g->letters_large);
229     cy += step_y;
230     this->addToPanel(STATE_OPTIONS, button_continue);
231 
232     const char *sound_texts[] = { "SOUND ON", "SOUND OFF" };
233     this->button_sound = new CycleButton((int)(mx - 4.25*fw), cy, sound_texts, 2, game_g->letters_large);
234     cy += step_y;
235     this->button_sound->setActive( game_g->isPrefSoundOn() ? 0 : 1 );
236 	this->addToPanel(STATE_OPTIONS, button_sound);
237 
238     const char *music_texts[] = { "MUSIC ON", "MUSIC OFF" };
239     this->button_music = new CycleButton((int)(mx - 4.25*fw), cy, music_texts, 2, game_g->letters_large);
240     cy += step_y;
241     this->button_music->setActive( game_g->isPrefMusicOn() ? 0 : 1 );
242 	this->addToPanel(STATE_OPTIONS, button_music);
243 
244 #if defined(__ANDROID__)
245     this->button_onemousebutton = NULL;
246 #else
247 	const char *onemousebutton_texts[] = { "ONE MOUSE BUTTON UI", "TWO MOUSE BUTTON UI" };
248     this->button_onemousebutton = new CycleButton((int)(mx - 9.5*fw), cy, onemousebutton_texts, 2, game_g->letters_large);
249     cy += step_y;
250 	this->button_onemousebutton->setActive( game_g->isOneMouseButton() ? 0 : 1 );
251 	this->addToPanel(STATE_OPTIONS, button_onemousebutton);
252 #endif
253 
254     const char *disallow_nukes_texts[] = { "DISALLOW NUKES", "ALLOW NUKES" };
255     this->button_disallow_nukes = new CycleButton((int)(mx - 6.25*fw), cy, disallow_nukes_texts, 2, game_g->letters_large);
256     cy += step_y;
257     this->button_disallow_nukes->setActive( game_g->isPrefDisallowNukes() ? 0 : 1 );
258 	this->addToPanel(STATE_OPTIONS, button_disallow_nukes);
259 
260     this->button_new = new Button((int)(mx - 4.0*fw), cy, "NEW GAME", game_g->letters_large);
261     cy += step_y;
262     this->addToPanel(STATE_OPTIONS, button_new);
263 
264 	this->button_load = NULL;
265 	this->button_save = NULL;
266 	if( game_g->getGameType() == GAMETYPE_ALLISLANDS ) {
267         this->button_load = new Button((int)(mx - 2.0*fw), cy, "LOAD", game_g->letters_large);
268         cy += step_y;
269         this->addToPanel(STATE_OPTIONS, button_load);
270         this->button_save = new Button((int)(mx - 2.0*fw), cy, "SAVE", game_g->letters_large);
271         cy += step_y;
272         this->addToPanel(STATE_OPTIONS, button_save);
273 	}
274 
275 	this->button_load_cancel = new Button((int)(mx - 3.0*fw), 228, "CANCEL", game_g->letters_small);
276 	this->addToPanel(STATE_LOADGAME, button_load_cancel);
277 
278 	this->button_save_cancel = new Button((int)(mx - 3.0*fw), 228, "CANCEL", game_g->letters_small);
279 	this->addToPanel(STATE_SAVEGAME, button_save_cancel);
280 
281 	for(int i=0;i<n_slots_c;i++) {
282 		this->button_load_load[i] = NULL;
283 		this->button_save_save[i] = NULL;
284 	}
285 	if( game_g->getGameType() == GAMETYPE_ALLISLANDS ) {
286 		refreshLoadSaveButtons();
287 	}
288 
289 	this->setInfoText();
290 }
291 
setInfoText()292 void ChooseMenPanel::setInfoText() {
293 	if( game_g->isOneMouseButton() ) {
294 		this->button_nmen->setInfoLMB("change the number of men\nto play this island");
295 	}
296 	else {
297 		this->button_nmen->setInfoLMB("decrease the number of men\nto play this island");
298 		this->button_nmen->setInfoRMB("increase the number of men\nto play this island");
299 	}
300 }
301 
refreshLoadSaveButtons()302 void ChooseMenPanel::refreshLoadSaveButtons() {
303 	for(int i=0;i<n_slots_c;i++) {
304 		if( this->button_load_load[i] != NULL )
305 			delete this->button_load_load[i];
306 		this->button_load_load[i] = NULL;
307 		DifficultyLevel difficulty = DIFFICULTY_EASY;
308 		int player = 0;
309 		int n_men = 0;
310 		int epoch = 0;
311 		int suspended[n_players_c];
312 		bool completed[max_islands_per_epoch_c];
313 		if( game_g->loadGameInfo( &difficulty, &player, &n_men, suspended, &epoch, completed, i ) ) {
314 			char buffer[256] = "";
315 			char diff_ch = '\0';
316 			if( difficulty == DIFFICULTY_EASY )
317 				diff_ch = 'E';
318 			else if( difficulty == DIFFICULTY_MEDIUM )
319 				diff_ch = 'M';
320 			else if( difficulty == DIFFICULTY_HARD )
321 				diff_ch = 'H';
322 			else if( difficulty == DIFFICULTY_ULTRA )
323 				diff_ch = 'U';
324 			else {
325 				ASSERT(false);
326 			}
327 			sprintf(buffer, "%d %c %s Age %d  Men %d  Suspended %d", i, diff_ch, PlayerType::getName((PlayerType::PlayerTypeID)player), epoch+1, n_men, suspended[player]);
328 			//this->button_load_load[i] = new Button(96, 228 + (i-n_slots_c) * 8, buffer, game_g->letters_small);
329             //int xpos = 16;
330             //int ypos = 228 + (i-n_slots_c) * 8;
331             /*int xshift = i/4;
332             int yshift = i%4;
333             int xpos = 16 + 128 * xshift;
334             int ypos = 228 + (yshift-n_slots_c) * 8;*/
335             int xpos = 16;
336             int ypos = 8 + i*22;
337             this->button_load_load[i] = new Button(xpos, ypos, buffer, game_g->letters_small);
338 			this->addToPanel(STATE_LOADGAME, button_load_load[i]);
339 		}
340 	}
341 
342 	for(int i=0;i<n_slots_c;i++) {
343 		delete this->button_save_save[i];
344 		DifficultyLevel difficulty = DIFFICULTY_EASY;
345 		int player = 0;
346 		int n_men = 0;
347 		int epoch = 0;
348 		char buffer[256] = "";
349 		int suspended[n_players_c];
350 		bool completed[max_islands_per_epoch_c];
351 		if( game_g->loadGameInfo( &difficulty, &player, &n_men, suspended, &epoch, completed, i ) ) {
352 			char diff_ch = '\0';
353 			if( difficulty == DIFFICULTY_EASY )
354 				diff_ch = 'E';
355 			else if( difficulty == DIFFICULTY_MEDIUM )
356 				diff_ch = 'M';
357 			else if( difficulty == DIFFICULTY_HARD )
358 				diff_ch = 'H';
359 			else if( difficulty == DIFFICULTY_ULTRA )
360 				diff_ch = 'U';
361 			else {
362 				ASSERT(false);
363 			}
364 			//sprintf(buffer, "%d %c %s Age %d Men %d Stored %d", i, diff_ch, PlayerType::getName((PlayerType::PlayerTypeID)player), epoch+1, n_men, suspended[player]);
365 			sprintf(buffer, "%d %c %s Age %d  Men %d  Saved %d", i, diff_ch, PlayerType::getName((PlayerType::PlayerTypeID)player), epoch+1, n_men, suspended[player]);
366 		}
367 		else {
368 			sprintf(buffer, "UNUSED Slot %d", i);
369 		}
370 		//this->button_save_save[i] = new Button(96, 228 + (i-n_slots_c) * 8, buffer, game_g->letters_small);
371         //int xpos = 16;
372         //int ypos = 228 + (i-n_slots_c) * 8;
373         /*int xshift = i/4;
374         int yshift = i%4;
375         int xpos = 16 + 128 * xshift;
376         int ypos = 228 + (yshift-n_slots_c) * 8;*/
377         int xpos = 16;
378         int ypos = 8 + i*22;
379         this->button_save_save[i] = new Button(xpos, ypos, buffer, game_g->letters_small);
380 		this->addToPanel(STATE_SAVEGAME, button_save_save[i]);
381 	}
382 }
383 
draw()384 void ChooseMenPanel::draw() {
385     if( ( this->getPage() == STATE_LOADGAME || this->getPage() == STATE_SAVEGAME ) && !this->gamestate->hasConfirmWindow() ) {
386         // hide background
387         // (if request quit, then we'll hide background after drawing the GUI)
388 #if SDL_MAJOR_VERSION == 1
389         game_g->getScreen()->fillRect(0, 0, default_width_c*game_g->getScaleWidth(), default_height_c*game_g->getScaleHeight(), 0, 0, 0);
390 #else
391         game_g->getScreen()->fillRectWithAlpha(0, 0, (short)(default_width_c*game_g->getScaleWidth()), (short)(default_height_c*game_g->getScaleHeight()), 0, 0, 0, 255-32);
392 #endif
393     }
394 
395     MultiPanel::draw();
396 
397 	if( this->getPage() == STATE_CHOOSEMEN ) {
398 		// draw this after the popups, so we can see it...
399 		game_g->men[game_g->getStartEpoch()]->draw( this->button_nmen->getLeft() + 4, this->button_nmen->getTop() + 16);
400 		Image::writeNumbers( this->button_nmen->getXCentre(), this->button_nmen->getTop() + 2, game_g->numbers_white, this->n_men,Image::JUSTIFY_CENTRE);
401 		Image::writeNumbers( this->button_nmen->getXCentre(), this->button_nmen->getTop() + 36, game_g->numbers_white, game_g->getMenAvailable() - this->n_men,Image::JUSTIFY_CENTRE);
402 	}
403 }
404 
buttonNMenClick(void * data,int arg,bool m_left,bool m_middle,bool m_right)405 void ChooseMenPanel::buttonNMenClick(void *data, int arg, bool m_left, bool m_middle, bool m_right) {
406 	ChooseMenPanel *chooseMenPanel = static_cast<ChooseMenPanel *>(data);
407 
408 	int n = game_g->getNClicks();
409 	if( m_left && chooseMenPanel->n_men > 0 ) {
410 		chooseMenPanel->n_men -= n;
411 		if( chooseMenPanel->n_men < 0 )
412 			chooseMenPanel->n_men = 0;
413 	}
414 	else if( m_right ) {
415 		chooseMenPanel->n_men += n;
416 		if( chooseMenPanel->n_men > game_g->getMenAvailable() )
417 			chooseMenPanel->n_men = game_g->getMenAvailable();
418 	}
419 	for(int y=0;y<map_height_c;y++) {
420 		for(int x=0;x<map_width_c;x++) {
421 			if( game_g->getMap()->isSectorAt(x, y) ) {
422 				/*ASSERT( ((PlaceMenGameState *)gamestate)->map_panels[x][y] != NULL );
423 				((PlaceMenGameState *)gamestate)->map_panels[x][y]->setVisible( n_men > 0 );*/
424 				/*ASSERT( ((PlaceMenGameState *)gamestate)->getMapPanel(x, y) != NULL );
425 				((PlaceMenGameState *)gamestate)->getMapPanel(x, y)->setVisible( n_men > 0 );*/
426 				ASSERT( chooseMenPanel->gamestate->getMapPanel(x, y) != NULL );
427 				chooseMenPanel->gamestate->getMapPanel(x, y)->setVisible( chooseMenPanel->n_men > 0 );
428 			}
429 		}
430 	}
431 }
432 
input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click)433 void ChooseMenPanel::input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click) {
434 	MultiPanel::input(m_x, m_y, m_left, m_middle, m_right, click);
435 
436 	if( this->hasModal() ) {
437 		return;
438 	}
439 	//bool m_left = mouse_left(m_b);
440 	//bool m_right = mouse_right(m_b);
441     bool done = false;
442 
443     if( this->c_page == STATE_CHOOSEISLAND ) {
444 		if( m_left && click && this->button_nextisland != NULL && this->button_nextisland->mouseOver(m_x, m_y) ) {
445             done = true;
446             registerClick();
447             gamestate->closeConfirmWindow();
448 			game_g->nextIsland();
449 			// this panel is now destroyed, need to exit immediately!
450 			return;
451         }
452 		else if( m_left && click && this->button_nextepoch != NULL && this->button_nextepoch->mouseOver(m_x, m_y) ) {
453             done = true;
454             registerClick();
455             gamestate->closeConfirmWindow();
456 			game_g->nextEpoch();
457 			// this panel is now destroyed, need to exit immediately!
458 			return;
459         }
460 		else if( m_left && click && this->button_options->mouseOver(m_x, m_y) ) {
461             done = true;
462             registerClick();
463             this->c_page = STATE_OPTIONS;
464             gamestate->closeConfirmWindow();
465         }
466         else if( m_left && click && this->button_play->mouseOver(m_x, m_y) ) {
467             done = true;
468             registerClick();
469             this->setInfoText();
470             this->c_page = STATE_CHOOSEMEN;
471             game_g->setupPlayers();
472             gamestate->closeConfirmWindow();
473         }
474 #if defined(_WIN32) || defined(__ANDROID__)
475         else if( m_left && click && this->button_help->mouseOver(m_x, m_y) ) {
476 			LOG("clicked online help\n");
477             done = true;
478             registerClick();
479             gamestate->closeConfirmWindow();
480 			char help_url[] = "http://homepage.ntlworld.com/mark.harman/comp_gigalomania.html";
481 #if defined(_WIN32)
482 			ShellExecute(0, 0, help_url, 0, 0 , SW_SHOW );
483 #elif defined(__ANDROID__)
484 			launchUrl(help_url);
485 #endif
486         }
487 #endif
488         else if( m_left && click && this->button_quit != NULL && this->button_quit->mouseOver(m_x, m_y) ) {
489             done = true;
490             //quitGame();
491             gamestate->requestQuit(false);
492         }
493     }
494 	else if( this->c_page == STATE_CHOOSEMEN ) {
495 		if( ( m_left || m_right ) && this->button_nmen->mouseOver(m_x, m_y) ) {
496             done = true;
497 			processClick(buttonNMenClick, this->get(this->c_page), this, 0, button_nmen, m_left, m_middle, m_right, click);
498 		}
499 		else if( ( m_left || m_right ) && this->button_cancel->mouseOver(m_x, m_y) ) {
500             done = true;
501 			gamestate->requestQuit(false);
502 		}
503 	}
504 	else if( this->c_page == STATE_OPTIONS ) {
505 		if( m_left && click && this->button_continue->mouseOver(m_x, m_y) ) {
506             done = true;
507 			if( button_sound != NULL ) {
508 				game_g->setPrefSoundOn( button_sound->getActive() == 0 );
509 			}
510 			if( button_music != NULL ) {
511 				bool old_pref_music_on = game_g->isPrefMusicOn();
512 				game_g->setPrefMusicOn( button_music->getActive() == 0 );
513 				if( game_g->isPrefMusicOn() != old_pref_music_on ) {
514 					game_g->playMusic(); // this will start/stop music as required - only call if the pref actually changed, to avoid unnecessarily restarting music
515 				}
516 			}
517 			if( button_onemousebutton != NULL ) {
518 				game_g->setOneMouseButton(button_onemousebutton->getActive() == 0);
519 			}
520 			if( button_disallow_nukes != NULL ) {
521 				game_g->setPrefDisallowNukes( button_disallow_nukes->getActive() == 0 );
522 			}
523 			game_g->savePrefs();
524 
525 			registerClick();
526             this->c_page = STATE_CHOOSEISLAND;
527 		}
528 		else if( m_left && click && this->button_new != NULL && this->button_new->mouseOver(m_x, m_y) ) {
529             done = true;
530             registerClick();
531 			this->gamestate->requestNewGame();
532 		}
533 		else if( m_left && click && this->button_load != NULL && this->button_load->mouseOver(m_x, m_y) ) {
534             done = true;
535             registerClick();
536             this->c_page = STATE_LOADGAME;
537 		}
538 		else if( m_left && click && this->button_save != NULL && this->button_save->mouseOver(m_x, m_y) ) {
539             done = true;
540             registerClick();
541             //this->c_page = STATE_CHOOSEISLAND;
542 			this->c_page = STATE_SAVEGAME;
543 		}
544 	}
545 	else if( this->c_page == STATE_LOADGAME ) {
546 		if( m_left && click && this->button_load_cancel->mouseOver(m_x, m_y) ) {
547             done = true;
548             registerClick();
549             this->c_page = STATE_CHOOSEISLAND;
550 		}
551 		else if( m_left && click ) {
552             for(int i=0;i<n_slots_c && !done;i++) {
553 				if( this->button_load_load[i] != NULL && this->button_load_load[i]->mouseOver(m_x, m_y) ) {
554                     done = true;
555                     registerClick();
556                     game_g->loadGame(i);
557 					return; // hack - need to return, as loading the game destroys this class! (the gamestate will be reset - which will also switch the c_page back to STATE_CHOOSEISLAND)
558 				}
559 			}
560 		}
561 		/*else if( m_left && click && this->button_load_load->mouseOver(m_x, m_y) ) {
562 		loadGame(0);
563 		this->c_page = STATE_CHOOSEISLAND;
564 		}*/
565 	}
566 	else if( this->c_page == STATE_SAVEGAME ) {
567 		if( m_left && click && this->button_save_cancel->mouseOver(m_x, m_y) ) {
568             done = true;
569             registerClick();
570             this->c_page = STATE_CHOOSEISLAND;
571 		}
572 		else if( m_left && click ) {
573             for(int i=0;i<n_slots_c && !done;i++) {
574 				if( this->button_save_save[i]->mouseOver(m_x, m_y) ) {
575                     done = true;
576                     registerClick();
577                     game_g->saveGame(i);
578 					this->c_page = STATE_CHOOSEISLAND;
579 					this->refreshLoadSaveButtons();
580 				}
581 			}
582 		}
583 	}
584 }
585 
586 /*bool ChooseMenPanel::onemousebuttonOn() const {
587     if( button_onemousebutton == NULL )
588         return onemousebutton;
589     return ( button_onemousebutton->getActive() == 0 );
590 }*/
591 
GamePanel(PlayingGameState * gamestate,int client_player)592 GamePanel::GamePanel(PlayingGameState *gamestate, int client_player) : MultiPanel(GamePanel::N_STATES, offset_panel_x_c, offset_panel_y_c), gamestate(gamestate), client_player(client_player) {
593 	//this->state = STATE_SECTORCONTROL;
594 	this->c_page = (int)STATE_SECTORCONTROL;
595 	this->mousestate = MOUSESTATE_NORMAL;
596 
597 	this->deploy_shield = -1;
598 	this->deploy_defence = -1;
599 	this->deploy_weapon = -1;
600 	this->designinfo = NULL;
601 
602 	//this->setup();
603 }
604 
~GamePanel()605 GamePanel::~GamePanel() {
606 }
607 
setup()608 void GamePanel::setup() {
609 	char buffer[256] = "";
610 	this->free(false);
611 
612 	// SECTORCONTROL
613 
614 	const int start_x = 8;
615 	const int step_x = 20;
616 	const int step_y = 30;
617 	int xpos = start_x;
618 	//const int ypos = 224 - offset_panel_y_c;
619 	int ypos = 18;
620 	xpos += step_x;
621 	//ypos += step_y;
622 
623 	//
624 	//this->button_shield = new ImageButton(28, 18, panel_shield, "check on building\ndamage status\nand repair buildings");
625 	this->button_shield = new ImageButton(xpos, ypos, game_g->panel_shield, "check on building\ndamage status\nand repair buildings");
626 	this->addToPanel(STATE_SECTORCONTROL, button_shield);
627 	xpos += step_x;
628 
629 	//
630 	this->button_defence = new ImageButton(xpos, ypos, game_g->panel_defence, "view building weapon\nstocks and deploy\nbuilding weapons");
631 	this->addToPanel(STATE_SECTORCONTROL, button_defence);
632 	xpos += step_x;
633 
634 	//
635 	this->button_attack = new ImageButton(xpos, ypos, game_g->panel_attack, "view army weapon stocks\nand assemble army");
636 	this->button_attack->setId("button_attack");
637 	this->addToPanel(STATE_SECTORCONTROL, button_attack);
638 	//xpos += step_x;
639 	xpos = start_x;
640 	ypos += step_y;
641 
642 	//this->button_knowndesigns = new ImageButton(8, 18, panel_knowndesigns, "view blueprints\nof completed designs");
643 	this->button_knowndesigns = new ImageButton(xpos, ypos, game_g->panel_knowndesigns, "view blueprints\nof completed designs");
644 	this->addToPanel(STATE_SECTORCONTROL, button_knowndesigns);
645 	xpos += step_x;
646 
647 	//
648 	//this->button_design = new ImageButton(8, 40, panel_design, "view and alter\ncurrent design");
649 	this->button_design = new ImageButton(xpos, ypos, game_g->panel_design, "view and alter\ncurrent design");
650 	this->button_design->setId("button_design");
651 	this->addToPanel(STATE_SECTORCONTROL, button_design);
652 	this->button_ndesigners = new PanelPage(xpos, ypos+16, 16, 16);
653 	if( game_g->isOneMouseButton() ) {
654 		this->button_ndesigners->setInfoLMB("change the number of designers");
655 	}
656 	else {
657 		this->button_ndesigners->setInfoLMB("decrease the number of designers");
658 		this->button_ndesigners->setInfoRMB("increase the number of designers");
659 	}
660 	this->addToPanel(STATE_SECTORCONTROL, button_ndesigners);
661 	xpos += step_x;
662 
663 	//
664 	//this->button_elementstocks = new ImageButton(40, 70, mine_gatherable_small, "view element stocks");
665 	/*this->button_elementstocks = new ImageButton(xpos, ypos, mine_gatherable_small, "view element stocks");
666 	this->addToPanel(STATE_SECTORCONTROL, button_elementstocks);
667 	xpos += step_x;*/
668 
669 	//
670 	//this->button_factory = new ImageButton(68, 40, panel_factory, "view and alter current\nitem being manufactured");
671 	this->button_factory = new ImageButton(xpos, ypos, game_g->panel_factory, "view and alter current\nitem being manufactured");
672 	this->button_factory->setId("button_factory");
673 	this->addToPanel(STATE_SECTORCONTROL, button_factory);
674 	this->button_nworkers = new PanelPage(xpos, ypos+16, 16, 16);
675 	if( game_g->isOneMouseButton() ) {
676 		this->button_nworkers->setInfoLMB("change the number of workers");
677 	}
678 	else {
679 		this->button_nworkers->setInfoLMB("decrease the number of workers");
680 		this->button_nworkers->setInfoRMB("increase the number of workers");
681 	}
682 	this->addToPanel(STATE_SECTORCONTROL, button_nworkers);
683 	xpos += step_x;
684 
685 	xpos = start_x;
686 	ypos += step_y;
687 	//
688 	{
689 		for(int i=0;i<4;i++) {
690 			this->button_elements[i] = NULL;
691 			this->element_index[i] = -1;
692 		}
693 		int indx = 0;
694 		for(int i=0;i<N_ID;i++) {
695 			if( indx == 4 )
696 				break;
697 			int n_elements = 0, fraction = 0;
698 			gamestate->getCurrentSector()->getTotalElements(&n_elements, &fraction, (Id)i);
699 			if( n_elements > 0 || fraction > 0 ) {
700 				/*this->button_elements[indx] = new Button(8 + 24*indx, 90, icon_elements[i]);
701 				this->add(STATE_SECTORCONTROL, button_elements[indx]);*/
702 				this->element_index[indx] = i;
703 				/*this->button_nminers[indx] = new Button(8 + 24*indx, 98, 16, 24);
704 				this->add(STATE_SECTORCONTROL, button_nminers[indx]);*/
705 				indx++;
706 			}
707 		}
708 	}
709 	for(int i=0;i<4;i++) {
710 		if( this->element_index[i] == -1 ) {
711 			this->button_elements[i] = new PanelPage(0, 0, 0, 0);
712 			this->addToPanel(STATE_SECTORCONTROL, button_elements[i]);
713 			this->button_nminers[i] = new PanelPage(0, 0, 0, 0);
714 			this->addToPanel(STATE_SECTORCONTROL, button_nminers[i]);
715 			xpos += step_x;
716 			continue;
717 		}
718 		ASSERT_ELEMENT_ID( this->element_index[i] );
719 		//this->button_elements[i] = new ImageButton(8 + 24*i, 90, icon_elements[ this->element_index[i] ]);
720 		this->button_elements[i] = new ImageButton(xpos, ypos, game_g->icon_elements[ this->element_index[i] ], "view element stocks");
721 		sprintf(buffer, "button_elements_%d", i);
722 		this->button_elements[i]->setId(buffer);
723 		//this->button_elements[i]->setInfoLMB("view element stocks");
724 		this->addToPanel(STATE_SECTORCONTROL, button_elements[i]);
725 		this->button_nminers[i] = new PanelPage(xpos, ypos+16, 16, 12);
726 		if( game_g->isOneMouseButton() ) {
727 			this->button_nminers[i]->setInfoLMB("change the number of miners");
728 		}
729 		else {
730 			this->button_nminers[i]->setInfoLMB("decrease the number of miners");
731 			this->button_nminers[i]->setInfoRMB("increase the number of miners");
732 		}
733 		this->addToPanel(STATE_SECTORCONTROL, button_nminers[i]);
734 		xpos += step_x;
735 	}
736 	xpos = start_x;
737 	ypos += step_y;
738 
739 	//
740 	for(int i=0;i<N_BUILDINGS;i++) {
741 		this->button_build[i] = NULL;
742 		this->button_nbuilders[i] = NULL;
743 	}
744 
745 	//this->button_build[BUILDING_MINE] = new ImageButton(8, 118, panel_build[BUILDING_MINE]);
746 	this->button_build[BUILDING_MINE] = new ImageButton(xpos, ypos, game_g->panel_build[BUILDING_MINE]);
747 	this->button_build[BUILDING_MINE]->setId("button_build_mine");
748 	this->button_build[BUILDING_MINE]->setInfoLMB("change the number of builders");
749 	this->addToPanel(STATE_SECTORCONTROL, button_build[BUILDING_MINE]);
750 	//this->button_nbuilders[BUILDING_MINE] = new PanelPage(8, 134, 16, 12);
751 	this->button_nbuilders[BUILDING_MINE] = new PanelPage(xpos, ypos+16, 16, 12);
752 	if( game_g->isOneMouseButton() ) {
753 		this->button_nbuilders[BUILDING_MINE]->setInfoLMB("change the number of builders\nbuilding a mine");
754 	}
755 	else {
756 		this->button_nbuilders[BUILDING_MINE]->setInfoLMB("decrease the number of builders\nbuilding a mine");
757 		this->button_nbuilders[BUILDING_MINE]->setInfoRMB("increase the number of builders\nbuilding a mine");
758 	}
759 	this->addToPanel(STATE_SECTORCONTROL, button_nbuilders[BUILDING_MINE]);
760 	xpos += step_x;
761 
762 	//this->button_build[BUILDING_FACTORY] = new ImageButton(28, 118, panel_build[BUILDING_FACTORY]);
763 	this->button_build[BUILDING_FACTORY] = new ImageButton(xpos, ypos, game_g->panel_build[BUILDING_FACTORY]);
764 	this->button_build[BUILDING_FACTORY]->setId("button_build_factory");
765 	this->button_build[BUILDING_FACTORY]->setInfoLMB("change the number of builders");
766 	this->addToPanel(STATE_SECTORCONTROL, button_build[BUILDING_FACTORY]);
767 	//this->button_nbuilders[BUILDING_FACTORY] = new PanelPage(28, 134, 16, 12);
768 	this->button_nbuilders[BUILDING_FACTORY] = new PanelPage(xpos, ypos+16, 16, 12);
769 	if( game_g->isOneMouseButton() ) {
770 		this->button_nbuilders[BUILDING_FACTORY]->setInfoLMB("change the number of builders\nbuilding a factory");
771 	}
772 	else {
773 		this->button_nbuilders[BUILDING_FACTORY]->setInfoLMB("decrease the number of builders\nbuilding a factory");
774 		this->button_nbuilders[BUILDING_FACTORY]->setInfoRMB("increase the number of builders\nbuilding a factory");
775 	}
776 	this->addToPanel(STATE_SECTORCONTROL, button_nbuilders[BUILDING_FACTORY]);
777 	xpos += step_x;
778 
779 	//this->button_build[BUILDING_LAB] = new ImageButton(48, 118, panel_build[BUILDING_LAB]);
780 	this->button_build[BUILDING_LAB] = new ImageButton(xpos, ypos, game_g->panel_build[BUILDING_LAB]);
781 	this->button_build[BUILDING_LAB]->setId("button_build_lab");
782 	this->button_build[BUILDING_LAB]->setInfoLMB("change the number of builders");
783 	this->addToPanel(STATE_SECTORCONTROL, button_build[BUILDING_LAB]);
784 	//this->button_nbuilders[BUILDING_LAB] = new PanelPage(48, 134, 16, 12);
785 	this->button_nbuilders[BUILDING_LAB] = new PanelPage(xpos, ypos+16, 16, 12);
786 	if( game_g->isOneMouseButton() ) {
787 		this->button_nbuilders[BUILDING_LAB]->setInfoLMB("change the number of builders\nbuilding a research centre");
788 	}
789 	else {
790 		this->button_nbuilders[BUILDING_LAB]->setInfoLMB("decrease the number of builders\nbuilding a research centre");
791 		this->button_nbuilders[BUILDING_LAB]->setInfoRMB("increase the number of builders\nbuilding a research centre");
792 	}
793 	this->addToPanel(STATE_SECTORCONTROL, button_nbuilders[BUILDING_LAB]);
794 	xpos += step_x;
795 
796 	// SHIELD
797 	this->button_bigshield = new ImageButton(33, 0, 32, 16, game_g->panel_bigshield, "return to main screen");
798 	this->addToPanel(STATE_SHIELD, button_bigshield);
799 	for(int i=0;i<game_g->getNSubEpochs();i++) {
800 		this->button_deploy_shields[i] = new ImageButton(offset_attack_x_c + space_attack_x_c*i, 24, game_g->icon_shields[i]);
801 		this->button_deploy_shields[i]->setInfoLMB("select a shield to use");
802 		this->addToPanel(STATE_SHIELD, button_deploy_shields[i]);
803 	}
804 	this->button_shutdown = new ImageButton(8, 40, game_g->men[n_epochs_c-1], "get ready to\nshutdown the sector");
805 	this->addToPanel(STATE_SHIELD, button_shutdown);
806 
807 	// DEFENCE
808 	this->button_bigdefence = new ImageButton(33, 0, 32, 16, game_g->panel_bigdefence, "return to main screen");
809 	this->addToPanel(STATE_DEFENCE, button_bigdefence);
810 	for(int i=0;i<game_g->getNSubEpochs();i++) {
811 		this->button_deploy_defences[i] = new ImageButton(offset_attack_x_c + space_attack_x_c*i, 56, game_g->numbered_defences[game_g->getStartEpoch() + i]);
812 		sprintf(buffer, "deploy a %s", Invention::getInvention(Invention::DEFENCE, game_g->getStartEpoch() + i)->getName());
813 		this->button_deploy_defences[i]->setInfoLMB(buffer);
814 		this->addToPanel(STATE_DEFENCE, button_deploy_defences[i]);
815 	}
816 
817 	// ATTACK
818 	this->button_bigattack = new ImageButton(33, 0, 32, 16, game_g->panel_bigattack, "return to main screen");
819 	this->button_bigattack->setId("button_bigattack");
820 	this->addToPanel(STATE_ATTACK, button_bigattack);
821 	this->button_deploy_unarmedmen = new ImageButton(offset_attack_x_c, 24, 16, 28, game_g->unarmed_man);
822 	this->button_deploy_unarmedmen->setInfoLMB("add an unarmed man to the army");
823 	this->button_deploy_unarmedmen->setId("button_deploy_unarmedmen");
824 	this->addToPanel(STATE_ATTACK, button_deploy_unarmedmen);
825 	for(int i=0;i<game_g->getNSubEpochs();i++) {
826 		//this->button_deploy_attackers[i] = new ImageButton(offset_attack_x_c + space_attack_x_c*i, 56, 16, 28, numbered_weapons[game_g->getStartEpoch() + i]);
827 		this->button_deploy_attackers[i] = new ImageButton(offset_attack_x_c + space_attack_x_c*i, 56, 16, 40, game_g->numbered_weapons[game_g->getStartEpoch() + i]);
828 		sprintf(buffer, "button_deploy_attackers_%d", i);
829 		this->button_deploy_attackers[i]->setId(buffer);
830 		sprintf(buffer, "add a %s to the army", Invention::getInvention(Invention::WEAPON, game_g->getStartEpoch() + i)->getName());
831 		this->button_deploy_attackers[i]->setInfoLMB(buffer);
832 		this->addToPanel(STATE_ATTACK, button_deploy_attackers[i]);
833 	}
834 	this->button_return_attackers = new ImageButton(80, 96, 16, 28, game_g->panel_twoattack);
835 	this->button_return_attackers->setInfoLMB("return the assembled army");
836 	this->button_return_attackers->setId("button_return_attackers");
837 	this->addToPanel(STATE_ATTACK, button_return_attackers);
838 	this->button_select_all = new Button(4, 96, "SELECT ALL WEAPONS", game_g->letters_small);
839 	this->addToPanel(STATE_ATTACK, button_select_all);
840 
841 	// DESIGN
842 	this->button_bigdesign = new ImageButton(33, 0, 32, 16, game_g->panel_bigdesign, "return to main screen");
843 	this->button_bigdesign->setId("button_bigdesign");
844 	this->addToPanel(STATE_DESIGN, button_bigdesign);
845 	this->button_designers = new ImageButton(40, 16, 16, 40, game_g->men[gamestate->getCurrentSector()->getEpoch()]);
846 	this->button_designers->setId("button_designers");
847 	if( game_g->isOneMouseButton() ) {
848 		this->button_designers->setInfoLMB("change the number of designers");
849 	}
850 	else {
851 		this->button_designers->setInfoLMB("decrease the number of designers");
852 		this->button_designers->setInfoRMB("increase the number of designers");
853 	}
854 	this->addToPanel(STATE_DESIGN, button_designers);
855 	for(int i=0;i<game_g->getNSubEpochs();i++) {
856         //int this_y = 60 + i*16;
857         int this_y = 60 + i*20;
858         this->button_shields[i] = new ImageButton(8, this_y, game_g->icon_shields[i]);
859 		sprintf(buffer, "button_shields_%d", i);
860 		this->button_shields[i]->setId(buffer);
861 		this->button_shields[i]->setInfoLMB("design a shield");
862 		this->addToPanel(STATE_DESIGN, button_shields[i]);
863         this->button_defences[i] = new ImageButton(40, this_y, game_g->icon_defences[game_g->getStartEpoch() + i]);
864 		sprintf(buffer, "button_defences_%d", i);
865 		this->button_defences[i]->setId(buffer);
866 		sprintf(buffer, "design a %s", Invention::getInvention(Invention::DEFENCE, game_g->getStartEpoch() + i)->getName());
867 		this->button_defences[i]->setInfoLMB(buffer);
868 		this->addToPanel(STATE_DESIGN, button_defences[i]);
869         this->button_weapons[i] = new ImageButton(72, this_y, game_g->icon_weapons[game_g->getStartEpoch() + i]);
870 		sprintf(buffer, "button_weapons_%d", i);
871 		this->button_weapons[i]->setId(buffer);
872 		sprintf(buffer, "design a %s", Invention::getInvention(Invention::WEAPON, game_g->getStartEpoch() + i)->getName());
873 		this->button_weapons[i]->setInfoLMB(buffer);
874 		this->addToPanel(STATE_DESIGN, button_weapons[i]);
875 	}
876 
877 	// ELEMENTSTOCKS
878 	this->button_bigelementstocks = new ImageButton(33, 0, 32, 16, game_g->mine_gatherable_large, "return to main screen");
879 	this->button_bigelementstocks->setId("button_bigelementstocks");
880 	this->addToPanel(STATE_ELEMENTSTOCKS, button_bigelementstocks);
881 	for(int i=0;i<4;i++) {
882 		if( this->element_index[i] == -1 ) {
883 			this->button_elements2[i] = new PanelPage(0, 0, 0, 0);
884 			this->addToPanel(STATE_SECTORCONTROL, button_elements2[i]);
885 			this->button_nminers2[i] = new PanelPage(0, 0, 0, 0);
886 			sprintf(buffer, "button_nminers2_%d", i);
887 			this->button_nminers2[i]->setId(buffer);
888 			this->addToPanel(STATE_SECTORCONTROL, button_nminers2[i]);
889 			continue;
890 		}
891 		ASSERT_ELEMENT_ID( this->element_index[i] );
892         //int this_y = 20 + 28*i;
893         int this_y = 20 + 30*i;
894         this->button_elements2[i] = new ImageButton(64, this_y, 16, 24, game_g->icon_elements[ this->element_index[i] ]);
895 		this->addToPanel(STATE_ELEMENTSTOCKS, button_elements2[i]);
896         this->button_nminers2[i] = new PanelPage(40, this_y, 16, 16);
897 		sprintf(buffer, "button_nminers2_%d", i);
898 		this->button_nminers2[i]->setId(buffer);
899 		if( game_g->isOneMouseButton() ) {
900 			this->button_nminers2[i]->setInfoLMB("change the number of miners");
901 		}
902 		else {
903 			this->button_nminers2[i]->setInfoLMB("decrease the number of miners");
904 			this->button_nminers2[i]->setInfoRMB("increase the number of miners");
905 		}
906 		this->addToPanel(STATE_ELEMENTSTOCKS, button_nminers2[i]);
907 	}
908 
909 	// BUILD
910 	this->button_bigbuild = new ImageButton(33, 0, 32, 16, game_g->panel_bigbuild, "return to main screen");
911 	this->button_bigbuild->setId("button_bigbuild");
912 	this->addToPanel(STATE_BUILD, button_bigbuild);
913 	for(int i=0;i<N_BUILDINGS;i++)
914 		this->button_nbuilders2[i] = NULL;
915 	//this->button_nbuilders2[BUILDING_MINE] = new ImageButton(40, 20, 19, 28, panel_build[BUILDING_MINE]);
916 	this->button_nbuilders2[BUILDING_MINE] = new ImageButton(40, 20, 19, build_step_y_c, game_g->panel_build[BUILDING_MINE]);
917 	this->button_nbuilders2[BUILDING_MINE]->setId("button_nbuilders2_mine");
918 	if( game_g->isOneMouseButton() ) {
919 		this->button_nbuilders2[BUILDING_MINE]->setInfoLMB("change the number of builders\nbuilding a mine");
920 	}
921 	else {
922 		this->button_nbuilders2[BUILDING_MINE]->setInfoLMB("decrease the number of builders\nbuilding a mine");
923 		this->button_nbuilders2[BUILDING_MINE]->setInfoRMB("increase the number of builders\nbuilding a mine");
924 	}
925 	this->addToPanel(STATE_BUILD, button_nbuilders2[BUILDING_MINE]);
926     //this->button_nbuilders2[BUILDING_FACTORY] = new ImageButton(40, 20 + build_step_y_c, 19, 28, panel_build[BUILDING_FACTORY]);
927     this->button_nbuilders2[BUILDING_FACTORY] = new ImageButton(40, 20 + build_step_y_c, 19, build_step_y_c, game_g->panel_build[BUILDING_FACTORY]);
928 	this->button_nbuilders2[BUILDING_FACTORY]->setId("button_nbuilders2_factory");
929     if( game_g->isOneMouseButton() ) {
930 		this->button_nbuilders2[BUILDING_FACTORY]->setInfoLMB("change the number of builders\nbuilding a factory");
931 	}
932 	else {
933 		this->button_nbuilders2[BUILDING_FACTORY]->setInfoLMB("decrease the number of builders\nbuilding a factory");
934 		this->button_nbuilders2[BUILDING_FACTORY]->setInfoRMB("increase the number of builders\nbuilding a factory");
935 	}
936 	this->addToPanel(STATE_BUILD, button_nbuilders2[BUILDING_FACTORY]);
937     //this->button_nbuilders2[BUILDING_LAB] = new ImageButton(40, 20 + 2*build_step_y_c, 19, 28, panel_build[BUILDING_LAB]);
938     this->button_nbuilders2[BUILDING_LAB] = new ImageButton(40, 20 + 2*build_step_y_c, 19, build_step_y_c, game_g->panel_build[BUILDING_LAB]);
939 	this->button_nbuilders2[BUILDING_LAB]->setId("button_nbuilders2_lab");
940     if( game_g->isOneMouseButton() ) {
941 		this->button_nbuilders2[BUILDING_LAB]->setInfoLMB("change the number of builders\nbuilding a research centre");
942 	}
943 	else {
944 		this->button_nbuilders2[BUILDING_LAB]->setInfoLMB("decrease the number of builders\nbuilding a research centre");
945 		this->button_nbuilders2[BUILDING_LAB]->setInfoRMB("increase the number of builders\nbuilding a research centre");
946 	}
947 	this->addToPanel(STATE_BUILD, button_nbuilders2[BUILDING_LAB]);
948 
949 	// KNOWNDESIGNS
950 	this->button_bigknowndesigns = new ImageButton(33, 0, 32, 16, game_g->panel_bigknowndesigns, "return to main screen");
951 	this->addToPanel(STATE_KNOWNDESIGNS, button_bigknowndesigns);
952 	for(int i=0;i<game_g->getNSubEpochs();i++) {
953         //int this_y = 40 + i*16;
954         int this_y = 40 + i*20;
955         this->button_knownshields[i] = new ImageButton(8, this_y, game_g->icon_shields[i]);
956 		this->button_knownshields[i]->setInfoLMB("view blueprint for a shield");
957 		this->addToPanel(STATE_KNOWNDESIGNS, button_knownshields[i]);
958         this->button_knowndefences[i] = new ImageButton(40, this_y, game_g->icon_defences[game_g->getStartEpoch() + i]);
959 		sprintf(buffer, "view blueprint for a %s", Invention::getInvention(Invention::DEFENCE, game_g->getStartEpoch() + i)->getName());
960 		this->button_knowndefences[i]->setInfoLMB(buffer);
961 		this->addToPanel(STATE_KNOWNDESIGNS, button_knowndefences[i]);
962         this->button_knownweapons[i] = new ImageButton(72, this_y, game_g->icon_weapons[game_g->getStartEpoch() + i]);
963 		sprintf(buffer, "view blueprint for a %s", Invention::getInvention(Invention::WEAPON, game_g->getStartEpoch() + i)->getName());
964 		this->button_knownweapons[i]->setInfoLMB(buffer);
965 		this->addToPanel(STATE_KNOWNDESIGNS, button_knownweapons[i]);
966 	}
967 
968 	// DESIGNINFO
969 	this->button_bigdesigninfo = new ImageButton(33, 0, game_g->panel_bigknowndesigns, "view blueprints\nof completed designs");
970 	this->addToPanel(STATE_DESIGNINFO, button_bigdesigninfo);
971 	this->button_trashdesign = new ImageButton(64, 100, game_g->icon_trash);
972 	/*if( game_g->isOneMouseButton() ) {
973 		button_trashdesign->setInfoLMB("trash this design");
974 	}
975 	else {
976 		button_trashdesign->setInfoBMB("trash this design");
977 	}*/
978 	button_trashdesign->setInfoLMB("trash this design");
979 	this->addToPanel(STATE_DESIGNINFO, button_trashdesign);
980 
981 	// FACTORY
982 	this->button_bigfactory = new ImageButton(33, 0, 32, 16, game_g->panel_bigfactory, "return to main screen");
983 	this->button_bigfactory->setId("button_bigfactory");
984 	this->addToPanel(STATE_FACTORY, button_bigfactory);
985 	this->button_workers = new ImageButton(40, 14, 16, 26, game_g->men[gamestate->getCurrentSector()->getEpoch()]);
986 	this->button_workers->setId("button_workers");
987 	if( game_g->isOneMouseButton() ) {
988 		this->button_workers->setInfoLMB("change the number of workers");
989 	}
990 	else {
991 		this->button_workers->setInfoLMB("decrease the number of workers");
992 		this->button_workers->setInfoRMB("increase the number of workers");
993 	}
994 	this->addToPanel(STATE_FACTORY, button_workers);
995 	this->button_famount = new ImageButton(40, 40, 14, 28, game_g->men[gamestate->getCurrentSector()->getEpoch()]);
996 	this->button_famount->setId("button_famount");
997 	if( game_g->isOneMouseButton() ) {
998 		this->button_famount->setInfoLMB("change the number to produce");
999 	}
1000 	else {
1001 		this->button_famount->setInfoLMB("decrease the number to produce");
1002 		this->button_famount->setInfoRMB("increase the number to produce");
1003 	}
1004 	this->addToPanel(STATE_FACTORY, button_famount);
1005 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1006         const int this_y = 82 + i*14;
1007         this->button_fshields[i] = new ImageButton(8, this_y, 16, 14, game_g->icon_shields[i]);
1008 		sprintf(buffer, "button_fshields_%d", i);
1009 		this->button_fshields[i]->setId(buffer);
1010 		this->button_fshields[i]->setInfoLMB("manufacture a shield");
1011 		this->addToPanel(STATE_FACTORY, button_fshields[i]);
1012         this->button_fdefences[i] = new ImageButton(40, this_y, 16, 14, game_g->icon_defences[game_g->getStartEpoch() + i]);
1013 		sprintf(buffer, "button_fdefences_%d", i);
1014 		this->button_fdefences[i]->setId(buffer);
1015 		sprintf(buffer, "manufacture a %s", Invention::getInvention(Invention::DEFENCE, game_g->getStartEpoch() + i)->getName());
1016 		this->button_fdefences[i]->setInfoLMB(buffer);
1017 		this->addToPanel(STATE_FACTORY, button_fdefences[i]);
1018         this->button_fweapons[i] = new ImageButton(72, this_y, 16, 14, game_g->icon_weapons[game_g->getStartEpoch() + i]);
1019 		sprintf(buffer, "button_fweapons_%d", i);
1020 		this->button_fweapons[i]->setId(buffer);
1021 		sprintf(buffer, "manufacture a %s", Invention::getInvention(Invention::WEAPON, game_g->getStartEpoch() + i)->getName());
1022 		this->button_fweapons[i]->setInfoLMB(buffer);
1023 		this->addToPanel(STATE_FACTORY, button_fweapons[i]);
1024 	}
1025 
1026 	//printf(">>> %d\n", this->pages[STATE_SECTORCONTROL]->nChildren());
1027 	this->refresh();
1028 	//printf(">>> %d\n", this->pages[STATE_SECTORCONTROL]->nChildren());
1029 }
1030 
refreshCanDesign()1031 void GamePanel::refreshCanDesign() {
1032 	if( !gamestate->viewingActiveClientSector() ) {
1033 		return;
1034 	}
1035 	if( game_g->getStartEpoch() == end_epoch_c ) {
1036 		this->button_design->setVisible(false);
1037 		return;
1038 	}
1039 	bool any_design = false;
1040 	if( gamestate->getCurrentSector()->getCurrentDesign() != NULL ) {
1041 		any_design = true; // even though no new designs available anymore, we can keep designing the selected design
1042 	}
1043 	for(int i=0;i<n_epochs_c && !any_design;i++) {
1044 		if( gamestate->getCurrentSector()->canResearch(Invention::SHIELD, i) )
1045 			any_design = true;
1046 		else if( gamestate->getCurrentSector()->canResearch(Invention::DEFENCE, i) )
1047 			any_design = true;
1048 		else if( gamestate->getCurrentSector()->canResearch(Invention::WEAPON, i) )
1049 			any_design = true;
1050 	}
1051 	this->button_design->setVisible(any_design);
1052 	if( gamestate->getCurrentSector()->getBuilding(BUILDING_LAB) != NULL ) {
1053 		this->button_design->setImage(game_g->panel_lab);
1054 		this->button_bigdesign->setImage(game_g->panel_biglab);
1055 	}
1056 	else {
1057 		//this->button_design->image = any_design ? panel_design : panel_design_dark;
1058 		this->button_design->setImage(game_g->panel_design);
1059 		this->button_bigdesign->setImage(game_g->panel_bigdesign);
1060 	}
1061 	this->button_ndesigners->setVisible( gamestate->getCurrentSector()->getCurrentDesign() != NULL );
1062 }
1063 
refreshDesignInventions()1064 void GamePanel::refreshDesignInventions() {
1065 	if( !gamestate->viewingActiveClientSector() ) {
1066 		return;
1067 	}
1068 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1069 		this->button_shields[i]->setVisible(true);
1070 		this->button_defences[i]->setVisible(true);
1071 		this->button_weapons[i]->setVisible(true);
1072 
1073 		if( !gamestate->getCurrentSector()->canResearch(Invention::SHIELD, game_g->getStartEpoch() + i) )
1074 			this->button_shields[i]->setVisible(false);
1075 		if( !gamestate->getCurrentSector()->canResearch(Invention::DEFENCE, game_g->getStartEpoch() + i) )
1076 			this->button_defences[i]->setVisible(false);
1077 		if( !gamestate->getCurrentSector()->canResearch(Invention::WEAPON, game_g->getStartEpoch() + i) )
1078 			this->button_weapons[i]->setVisible(false);
1079 	}
1080 }
1081 
refreshManufactureInventions()1082 void GamePanel::refreshManufactureInventions() {
1083 	if( !gamestate->viewingActiveClientSector() ) {
1084 		return;
1085 	}
1086 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1087 		this->button_fshields[i]->setVisible(true);
1088 		this->button_fdefences[i]->setVisible(true);
1089 		this->button_fweapons[i]->setVisible(true);
1090 
1091 		if( game_g->getStartEpoch() + i < factory_epoch_c || !gamestate->getCurrentSector()->canBuildDesign(Invention::SHIELD, game_g->getStartEpoch() + i) )
1092 			this->button_fshields[i]->setVisible(false);
1093 		if( game_g->getStartEpoch() + i < factory_epoch_c || !gamestate->getCurrentSector()->canBuildDesign(Invention::DEFENCE, game_g->getStartEpoch() + i) )
1094 			this->button_fdefences[i]->setVisible(false);
1095 		if( game_g->getStartEpoch() + i < factory_epoch_c || !gamestate->getCurrentSector()->canBuildDesign(Invention::WEAPON, game_g->getStartEpoch() + i) )
1096 			this->button_fweapons[i]->setVisible(false);
1097 	}
1098 }
1099 
refreshDeployInventions()1100 void GamePanel::refreshDeployInventions() {
1101 	if( !gamestate->viewingActiveClientSector() ) {
1102 		return;
1103 	}
1104 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1105 		this->button_deploy_shields[i]->setVisible(false);
1106 		if( gamestate->getCurrentSector()->inventionKnown(Invention::SHIELD, game_g->getStartEpoch() + i) )
1107 			this->button_deploy_shields[i]->setVisible(true);
1108 	}
1109 
1110 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1111 		this->button_deploy_defences[i]->setVisible(false);
1112 		if( gamestate->getCurrentSector()->inventionKnown(Invention::DEFENCE, game_g->getStartEpoch() + i) )
1113 			this->button_deploy_defences[i]->setVisible(true);
1114 	}
1115 
1116 	this->button_deploy_unarmedmen->setVisible(true);
1117 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1118 		this->button_deploy_attackers[i]->setVisible(false);
1119 		if( gamestate->getCurrentSector()->inventionKnown(Invention::WEAPON, game_g->getStartEpoch() + i) ||
1120 			gamestate->getCurrentSector()->getStoredArmy()->getSoldiers(game_g->getStartEpoch() + i) > 0 )
1121 			this->button_deploy_attackers[i]->setVisible(true);
1122 	}
1123 }
1124 
refreshShutdown()1125 void GamePanel::refreshShutdown() {
1126 	if( !gamestate->viewingActiveClientSector() ) {
1127 		return;
1128 	}
1129 	this->button_shutdown->setVisible( gamestate->getCurrentSector()->canShutdown() );
1130 }
1131 
refresh()1132 void GamePanel::refresh() {
1133 	//LOG("GamePanel::refresh()\n");
1134 	// set all enabled to false
1135 	if( !gamestate->viewingActiveClientSector() ) {
1136 		this->setVisible(false);
1137 		return;
1138 	}
1139 
1140 	this->setVisible(true);
1141 
1142 	this->refreshCanDesign();
1143 
1144 	bool any_defences = false;
1145 	for(int i=0;i<n_epochs_c && !any_defences;i++)
1146 		any_defences = ( gamestate->getCurrentSector()->getStoredDefenders(i) > 0 || gamestate->getCurrentSector()->inventionKnown(Invention::DEFENCE, i) );
1147 	bool any_designs = ( gamestate->getCurrentSector()->getNDesigns() > 0 );
1148 
1149 	this->button_shield->setVisible(true);
1150 	this->button_defence->setVisible(any_defences);
1151 	this->button_attack->setVisible(true);
1152 	//this->button_elementstocks->setVisible(game_g->getStartEpoch() != end_epoch_c);
1153 	for(int i=0;i<4;i++) {
1154 		this->button_elements[i]->setVisible(false);
1155 		this->button_nminers[i]->setVisible(false);
1156 		this->button_elements2[i]->setVisible(false);
1157 		this->button_nminers2[i]->setVisible(false);
1158 
1159 		if( this->element_index[i] != -1 ) {
1160 			ASSERT_ELEMENT_ID( this->element_index[i] );
1161 			bool can_mine = gamestate->getCurrentSector()->canMine( (Id)this->element_index[i] );
1162 			int n_elements = 0, fraction = 0;
1163 			gamestate->getCurrentSector()->getElementStocks(&n_elements, &fraction, (Id)this->element_index[i]);
1164 			if( n_elements > 0 || fraction > 0 || can_mine ) {
1165 				this->button_elements[i]->setVisible(true);
1166 				this->button_elements2[i]->setVisible(true);
1167 			}
1168 			if( can_mine && game_g->elements[ this->element_index[i] ]->getType() != Element::GATHERABLE ) {
1169 				this->button_nminers[i]->setVisible(true);
1170 				this->button_nminers2[i]->setVisible(true);
1171 			}
1172 		}
1173 	}
1174 	/*if( game_g->isOneMouseButton() ) {
1175 		// if one mouse button, only allow changing via the sub-menu (otherwise problems with left/right icons going off screen)
1176 		this->button_nbuilders[BUILDING_MINE]->setVisible(false);
1177 		this->button_nbuilders[BUILDING_FACTORY]->setVisible(false);
1178 		this->button_nbuilders[BUILDING_LAB]->setVisible(false);
1179 	}*/
1180 	if( !gamestate->getCurrentSector()->canBuild( BUILDING_MINE ) ) {
1181 		this->button_build[BUILDING_MINE]->setVisible(false);
1182 		this->button_nbuilders[BUILDING_MINE]->setVisible(false);
1183 		this->button_nbuilders2[BUILDING_MINE]->setVisible(false);
1184 	}
1185 	if( !gamestate->getCurrentSector()->canBuild( BUILDING_FACTORY ) ) {
1186 		this->button_build[BUILDING_FACTORY]->setVisible(false);
1187 		this->button_nbuilders[BUILDING_FACTORY]->setVisible(false);
1188 		this->button_nbuilders2[BUILDING_FACTORY]->setVisible(false);
1189 	}
1190 	if( !gamestate->getCurrentSector()->canBuild( BUILDING_LAB ) ) {
1191 		this->button_build[BUILDING_LAB]->setVisible(false);
1192 		this->button_nbuilders[BUILDING_LAB]->setVisible(false);
1193 		this->button_nbuilders2[BUILDING_LAB]->setVisible(false);
1194 	}
1195 	this->button_bigbuild->setVisible(true);
1196 	this->button_knowndesigns->setVisible(any_designs);
1197 	if( gamestate->getCurrentSector()->getBuilding(BUILDING_FACTORY) == NULL ) {
1198 		this->button_factory->setVisible(false);
1199 	}
1200 	this->button_nworkers->setVisible( gamestate->getCurrentSector()->getCurrentManufacture() != NULL );
1201 
1202 	this->button_bigdesign->setVisible(true);
1203 	this->button_designers->setVisible( gamestate->getCurrentSector()->getCurrentDesign() != NULL );
1204 	this->button_designers->enableHelpText( gamestate->getCurrentSector()->getCurrentDesign() != NULL );
1205 	this->refreshDesignInventions();
1206 
1207 	this->button_bigshield->setVisible(true);
1208 	this->refreshShutdown();
1209 
1210 	this->button_bigdefence->setVisible(true);
1211 
1212 	this->button_bigattack->setVisible(true);
1213 	this->button_return_attackers->setVisible(true);
1214 	this->button_select_all->setVisible(true);
1215 
1216 	this->refreshDeployInventions();
1217 
1218 	this->button_bigelementstocks->setVisible(true);
1219 
1220 	this->button_bigknowndesigns->setVisible(true);
1221 	for(int i=0;i<game_g->getNSubEpochs();i++) {
1222 		if( !gamestate->getCurrentSector()->knownDesign(Invention::SHIELD, game_g->getStartEpoch() + i) )
1223 			this->button_knownshields[i]->setVisible(false);
1224 		if( !gamestate->getCurrentSector()->knownDesign(Invention::DEFENCE, game_g->getStartEpoch() + i) )
1225 			this->button_knowndefences[i]->setVisible(false);
1226 		if( !gamestate->getCurrentSector()->knownDesign(Invention::WEAPON, game_g->getStartEpoch() + i) )
1227 			this->button_knownweapons[i]->setVisible(false);
1228 	}
1229 
1230 	this->button_bigdesigninfo->setVisible(true);
1231 	this->button_trashdesign->setVisible(true);
1232 
1233 	this->button_bigfactory->setVisible(true);
1234 	this->button_workers->setVisible( gamestate->getCurrentSector()->getCurrentManufacture() != NULL );
1235 	this->button_workers->enableHelpText( gamestate->getCurrentSector()->getCurrentManufacture() != NULL );
1236 	this->button_famount->setVisible( gamestate->getCurrentSector()->getCurrentManufacture() != NULL );
1237 	this->button_famount->enableHelpText( gamestate->getCurrentSector()->getCurrentManufacture() != NULL );
1238 	this->refreshManufactureInventions();
1239 
1240 	//((PlayingGameState *)gamestate)->refreshButtons();
1241 	gamestate->refreshButtons();
1242 }
1243 
setPage(int page)1244 void GamePanel::setPage(int page) {
1245 	this->c_page = page;
1246 	this->setMouseState(MOUSESTATE_NORMAL);
1247 }
1248 
getMouseState() const1249 GamePanel::MouseState GamePanel::getMouseState() const {
1250 	return this->mousestate;
1251 }
1252 
setMouseState(MouseState mousestate)1253 void GamePanel::setMouseState(MouseState mousestate) {
1254 	this->mousestate = mousestate;
1255 	//((PlayingGameState *)gamestate)->refreshButtons();
1256 	gamestate->refreshButtons();
1257 }
1258 
draw()1259 void GamePanel::draw() {
1260 	if( this->c_page == STATE_SECTORCONTROL ) {
1261 		Image::writeMixedCase(offset_panel_x_c + 8, offset_panel_y_c - 1, game_g->letters_large, game_g->letters_small, NULL, game_g->getMap()->getName(), Image::JUSTIFY_LEFT);
1262 		if( game_g->getStartEpoch() != end_epoch_c ) {
1263 			int year = epoch_dates[gamestate->getCurrentSector()->getEpoch()];
1264 			bool shiny = gamestate->getCurrentSector()->getEpoch() == n_epochs_c-1;
1265 			Image::writeNumbers(offset_panel_x_c + 96, offset_panel_y_c, shiny ? game_g->numbers_largeshiny : game_g->numbers_largegrey, abs(year),Image::JUSTIFY_RIGHT);
1266 			Image *era = ( year < 0 ) ? game_g->icon_bc :
1267 				shiny ? game_g->icon_ad_shiny : game_g->icon_ad;
1268 			if( era != NULL )
1269 				era->draw(offset_panel_x_c + 88, offset_panel_y_c + 7);
1270 			else {
1271 				Image::write(offset_panel_x_c + 88, offset_panel_y_c + 8, game_g->letters_small, ( year < 0 ) ? "BC" : "AD", Image::JUSTIFY_LEFT);
1272 			}
1273 		}
1274 
1275 		if( gamestate->viewingActiveClientSector() ) {
1276 			const int xpos = 8, ypos = 18;
1277 			//const int xpos = 40, ypos = 40;
1278 			game_g->men[gamestate->getCurrentSector()->getEpoch()]->draw(offset_panel_x_c + xpos, offset_panel_y_c + ypos);
1279 			Image::writeNumbers(offset_panel_x_c + xpos + 8, offset_panel_y_c + ypos + 18, game_g->numbers_grey, gamestate->getCurrentSector()->getSparePopulation(),Image::JUSTIFY_CENTRE);
1280 			if( gamestate->getCurrentSector()->getCurrentDesign() != NULL ) {
1281 				Image::writeNumbers( this->button_ndesigners->getXCentre(), this->button_ndesigners->getTop() + 2, game_g->numbers_white, gamestate->getCurrentSector()->getDesigners(),Image::JUSTIFY_CENTRE);
1282 			}
1283 			for(int i=0;i<4;i++) {
1284 				Id element = (Id)this->element_index[i];
1285 				if( this->button_nminers[i]->isVisible() ) {
1286 					ASSERT_ELEMENT_ID( this->element_index[i] );
1287 					int n_miners = gamestate->getCurrentSector()->getMiners( element );
1288 					Image::writeNumbers( this->button_nminers[i]->getXCentre(), this->button_nminers[i]->getTop() + 2, game_g->numbers_white, n_miners,Image::JUSTIFY_CENTRE);
1289 				}
1290 			}
1291 			if( gamestate->getCurrentSector()->getCurrentManufacture() != NULL ) {
1292 				Image::writeNumbers( this->button_nworkers->getXCentre(), this->button_nworkers->getTop() + 2, game_g->numbers_white, gamestate->getCurrentSector()->getWorkers(),Image::JUSTIFY_CENTRE);
1293 			}
1294 			for(int i=0;i<N_BUILDINGS;i++) {
1295 				if( this->button_nbuilders[i] != NULL && this->button_nbuilders[i]->isVisible() ) {
1296 					Image::writeNumbers( this->button_nbuilders[i]->getXCentre(), this->button_nbuilders[i]->getBottom() - 8, game_g->numbers_white, gamestate->getCurrentSector()->getBuilders((Type)i),Image::JUSTIFY_CENTRE);
1297 				}
1298 			}
1299 		}
1300 		else if( gamestate->viewingAnyClientSector() ) {
1301 			ASSERT( gamestate->getCurrentSector()->isShutdown() );
1302 			game_g->men[gamestate->getCurrentSector()->getBuildingEpoch()]->draw(offset_panel_x_c + 40, offset_panel_y_c + 40);
1303 			Image::writeNumbers(offset_panel_x_c + 48, offset_panel_y_c + 58, game_g->numbers_grey, gamestate->getCurrentSector()->getPopulation(),Image::JUSTIFY_CENTRE);
1304 		}
1305 		else if( gamestate->getCurrentSector()->getPlayer() == -1 ) {
1306 			int n_players_in_sector = 0;
1307 			int player_in_sector = -1;
1308 			for(int i=0;i<n_players_c;i++) {
1309 				if( gamestate->getCurrentSector()->getArmy(i)->getTotal() > 0 ) {
1310 					player_in_sector = i;
1311 					n_players_in_sector++;
1312 				}
1313 			}
1314 			if( n_players_in_sector == 1 && player_in_sector == client_player ) {
1315 				int halfdays = 0, hours = 0;
1316 				gamestate->getCurrentSector()->buildingTowerTimeLeft(player_in_sector, &halfdays, &hours);
1317 				int clock_index = hours + 1;
1318 				game_g->icon_clocks[ clock_index ]->draw(offset_panel_x_c + 72, offset_panel_y_c + 16);
1319 				Image::writeNumbers(offset_panel_x_c + 80, offset_panel_y_c + 34, game_g->numbers_white, halfdays,Image::JUSTIFY_CENTRE);
1320 			}
1321 		}
1322 	}
1323 	else if( this->c_page == STATE_DESIGN ) {
1324 		this->button_designers->setImage( game_g->men[gamestate->getCurrentSector()->getEpoch()] );
1325 		if( gamestate->getCurrentSector()->getCurrentDesign() == NULL ) {
1326 			game_g->dash_grey->draw(offset_panel_x_c + 45, offset_panel_y_c + 36);
1327 		}
1328 		else {
1329 			Invention *current_invention = gamestate->getCurrentSector()->getCurrentDesign()->getInvention();
1330 			current_invention->getImage()->draw(offset_panel_x_c + 8, offset_panel_y_c + 16);
1331 			Image::writeNumbers(offset_panel_x_c + 48, offset_panel_y_c + 34, game_g->numbers_white, gamestate->getCurrentSector()->getDesigners(),Image::JUSTIFY_CENTRE);
1332 			if( gamestate->getCurrentSector()->getDesigners() > 0 ) {
1333 				int halfdays = 0, hours = 0;
1334 				gamestate->getCurrentSector()->inventionTimeLeft(&halfdays, &hours);
1335 				int clock_index = hours + 1;
1336 				game_g->icon_clocks[ clock_index ]->draw(offset_panel_x_c + 72, offset_panel_y_c + 16);
1337 				Image::writeNumbers(offset_panel_x_c + 80, offset_panel_y_c + 34, game_g->numbers_white, halfdays,Image::JUSTIFY_CENTRE);
1338 			}
1339 			else {
1340 				game_g->icon_clocks[ 0 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + 16);
1341 				game_g->icon_infinity->draw(offset_panel_x_c + 74, offset_panel_y_c + 32);
1342 			}
1343 		}
1344 		game_g->icon_shield->draw(offset_panel_x_c + 8, offset_panel_y_c + 44);
1345 		game_g->icon_defence->draw(offset_panel_x_c + 40, offset_panel_y_c + 44);
1346 		game_g->icon_weapon->draw(offset_panel_x_c + 72, offset_panel_y_c + 44);
1347 	}
1348 	else if( this->c_page == STATE_SHIELD ) {
1349 		for(int i=0;i<N_BUILDINGS;i++) {
1350 			if( gamestate->getCurrentSector()->getBuilding((Type)i) != NULL ) {
1351 				int width = game_g->building_health->getScaledWidth();
1352 				int health = gamestate->getCurrentSector()->getBuilding((Type)i)->getHealth();
1353 				int max_health = gamestate->getCurrentSector()->getBuilding((Type)i)->getMaxHealth();
1354 				//health = 50;
1355 				//max_health = 60;
1356 				int offx = offset_panel_x_c + 24;
1357 				short x = (short)(game_g->getScaleWidth() * offx + ( game_g->getScaleWidth() * health * width ) / (float)max_health);
1358 				short y = (short)(game_g->getScaleHeight() * ( offset_panel_y_c + 64 + 16 * i ));
1359 				short w = (short)ceil(( game_g->getScaleWidth() * (max_health - health) * width ) / (float)max_health);
1360 				short h = (short)(game_g->getScaleHeight() * 5);
1361 				game_g->building_health->draw(offx, (int)(y/game_g->getScaleHeight()));
1362 				game_g->getScreen()->fillRect(x, y, w, h, 0, 0, 0);
1363 				game_g->panel_building[i]->draw(offset_panel_x_c + 8, offset_panel_y_c + 64 - 5 + 16 * i);
1364 			}
1365 		}
1366 
1367 		for(int i=0;i<game_g->getNSubEpochs();i++) {
1368 			if( this->button_deploy_shields[i]->isVisible() ) {
1369 				int n_store = gamestate->getCurrentSector()->getStoredShields(i);
1370 				int pos_x = button_deploy_shields[i]->getLeft() + 8;
1371 				int pos_y = button_deploy_shields[i]->getBottom() + 2;
1372 				if( gamestate->getCurrentSector()->canBuildDesign(Invention::SHIELD, game_g->getStartEpoch()+i) || n_store > 0 ) {
1373 					if( n_store == 0 && game_g->getStartEpoch() + i < factory_epoch_c )
1374 						Image::write(pos_x, pos_y, game_g->letters_small, "OK", Image::JUSTIFY_CENTRE);
1375 					else
1376 						Image::writeNumbers(pos_x, pos_y, game_g->numbers_yellow, n_store, Image::JUSTIFY_CENTRE);
1377 				}
1378 				else {
1379 					game_g->dash_grey->draw(pos_x - 4, pos_y + 4);
1380 				}
1381 			}
1382 		}
1383 	}
1384 	else if( this->c_page == STATE_DEFENCE ) {
1385 		game_g->men[gamestate->getCurrentSector()->getEpoch()]->draw(offset_panel_x_c + 8, offset_panel_y_c + 24);
1386 		Image::writeNumbers(offset_panel_x_c + 16, offset_panel_y_c + 42, game_g->numbers_grey, gamestate->getCurrentSector()->getSparePopulation(), Image::JUSTIFY_CENTRE);
1387 		for(int i=0;i<game_g->getNSubEpochs();i++) {
1388 			if( this->button_deploy_defences[i]->isVisible() ) {
1389 				int n_store = gamestate->getCurrentSector()->getStoredDefenders(game_g->getStartEpoch()+i);
1390 				int pos_x = button_deploy_defences[i]->getLeft() + 8;
1391 				int pos_y = button_deploy_defences[i]->getBottom() + 2;
1392 				if( gamestate->getCurrentSector()->canBuildDesign(Invention::DEFENCE, game_g->getStartEpoch()+i) || n_store > 0 ) {
1393 					if( n_store == 0 && game_g->getStartEpoch() + i < factory_epoch_c )
1394 						Image::write(pos_x, pos_y, game_g->letters_small, "OK", Image::JUSTIFY_CENTRE);
1395 					else
1396 						Image::writeNumbers(pos_x, pos_y, game_g->numbers_yellow, n_store, Image::JUSTIFY_CENTRE);
1397 				}
1398 				else {
1399 					game_g->dash_grey->draw(pos_x - 4, pos_y + 4);
1400 				}
1401 			}
1402 		}
1403 	}
1404 	else if( this->c_page == STATE_ATTACK ) {
1405 		Image::writeNumbers(offset_panel_x_c + offset_attack_x_c + 8, offset_panel_y_c + 42, game_g->numbers_yellow, gamestate->getCurrentSector()->getSparePopulation(), Image::JUSTIFY_CENTRE);
1406 		for(int i=0;i<game_g->getNSubEpochs();i++) {
1407 			if( this->button_deploy_attackers[i]->isVisible() ) {
1408 				int n_store = gamestate->getCurrentSector()->getStoredArmy()->getSoldiers(game_g->getStartEpoch()+i);
1409 				if( gamestate->getCurrentSector()->canBuildDesign(Invention::WEAPON, game_g->getStartEpoch()+i) || n_store > 0 ) {
1410 					if( n_store == 0 && game_g->getStartEpoch() + i < factory_epoch_c )
1411 						Image::write(offset_panel_x_c + offset_attack_x_c + 8 + space_attack_x_c*i, offset_panel_y_c + 74, game_g->letters_small, "OK", Image::JUSTIFY_CENTRE);
1412 					else
1413 						Image::writeNumbers(offset_panel_x_c + offset_attack_x_c + 8 + space_attack_x_c*i, offset_panel_y_c + 74, game_g->numbers_yellow, n_store, Image::JUSTIFY_CENTRE);
1414 				}
1415 				else {
1416 					game_g->dash_grey->draw(offset_panel_x_c + offset_attack_x_c + 4 + space_attack_x_c*i, offset_panel_y_c + 78);
1417 				}
1418 			}
1419 		}
1420 
1421 		int n_army = gamestate->getCurrentSector()->getAssembledArmy()->getTotal();
1422 		if( n_army == 0 )
1423 			game_g->dash_grey->draw(offset_panel_x_c + 84, offset_panel_y_c + 116);
1424 		else
1425 			Image::writeNumbers(offset_panel_x_c + 88, offset_panel_y_c + 116, game_g->numbers_orange, n_army, Image::JUSTIFY_CENTRE);
1426 	}
1427 	else if( this->c_page == STATE_ELEMENTSTOCKS ) {
1428 		for(int i=0;i<4;i++) {
1429 			Id element = (Id)this->element_index[i];
1430 			if( element == -1 )
1431 				continue;
1432 			ASSERT_ELEMENT_ID( this->element_index[i] );
1433 			int n_elements = 0, fraction = 0;
1434 			gamestate->getCurrentSector()->getElementStocks(&n_elements, &fraction, element);
1435 			int off = 0;
1436 			int ypos = offset_panel_y_c + 42 + 28 * i;
1437 			if( n_elements > 0 ) {
1438 				Image::writeNumbers(offset_panel_x_c + 72, ypos, game_g->numbers_blue, n_elements, Image::JUSTIFY_LEFT);
1439 				off += game_g->numbers_blue[0]->getScaledWidth() * n_digits(n_elements);
1440 			}
1441 			if( fraction == 1 ) {
1442 				game_g->numbers_half->draw(offset_panel_x_c + 72 + off + 1, ypos);
1443 			}
1444 			if( this->button_nminers2[i]->isVisible() ) {
1445 				int n_miners = gamestate->getCurrentSector()->getMiners( element );
1446 				Image::writeNumbers( this->button_nminers2[i]->getXCentre(), this->button_nminers2[i]->getTop() + 2, game_g->numbers_white, n_miners,Image::JUSTIFY_CENTRE);
1447 			}
1448 		}
1449 	}
1450 	else if( this->c_page == STATE_BUILD ) {
1451 		for(int i=0;i<N_BUILDINGS;i++)
1452 		{
1453 			if( this->button_nbuilders2[i] != NULL && this->button_nbuilders2[i]->isVisible() ) {
1454 				Image::writeNumbers( this->button_nbuilders2[i]->getXCentre(), this->button_nbuilders2[i]->getTop() + 20, game_g->numbers_white, gamestate->getCurrentSector()->getBuilders((Type)i),Image::JUSTIFY_CENTRE);
1455 				if( gamestate->getCurrentSector()->getBuilders((Type)i) > 0 ) {
1456 					int halfdays = 0, hours = 0;
1457 					gamestate->getCurrentSector()->buildingTimeLeft((Type)i, &halfdays, &hours);
1458 					int clock_index = hours + 1;
1459 					game_g->icon_clocks[ clock_index ]->draw(offset_panel_x_c + 72, offset_panel_y_c + 16 + build_step_y_c*(i-1));
1460 					Image::writeNumbers(offset_panel_x_c + 80, offset_panel_y_c + 34 + build_step_y_c*(i-1), game_g->numbers_white, halfdays,Image::JUSTIFY_CENTRE);
1461 				}
1462 				else {
1463 					game_g->icon_clocks[ 0 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + 16 + build_step_y_c*(i-1));
1464 					game_g->icon_infinity->draw(offset_panel_x_c + 74, offset_panel_y_c + 32 + build_step_y_c*(i-1));
1465 				}
1466 			}
1467 		}
1468 	}
1469 	else if( this->c_page == STATE_KNOWNDESIGNS ) {
1470 		game_g->icon_shield->draw(offset_panel_x_c + 8, offset_panel_y_c + 24);
1471 		game_g->icon_defence->draw(offset_panel_x_c + 40, offset_panel_y_c + 24);
1472 		game_g->icon_weapon->draw(offset_panel_x_c + 72, offset_panel_y_c + 24);
1473 	}
1474 	else if( this->c_page == STATE_DESIGNINFO ) {
1475 		ASSERT(this->designinfo != NULL);
1476 		Design *design = gamestate->getCurrentSector()->knownDesign( this->designinfo->getType(), this->designinfo->getEpoch() );
1477 		ASSERT(design != NULL);
1478 		int cnt = 0;
1479 		for(int i=0;i<N_ID;i++) {
1480 			int cost = design->getCost((Id)i);
1481 			if( cost > 0 ) {
1482 				int whole = cost / element_multiplier_c;
1483 				int frac = cost % element_multiplier_c;
1484 				game_g->icon_elements[i]->draw(offset_panel_x_c + 16, offset_panel_y_c + 32 + 18 * cnt);
1485 				int off = 0;
1486 				if( whole > 0 ) {
1487 					Image::writeNumbers(offset_panel_x_c + 36, offset_panel_y_c + 34 + 18 * cnt, game_g->numbers_blue, whole, Image::JUSTIFY_LEFT);
1488 					off += game_g->numbers_blue[0]->getScaledWidth() * n_digits(whole);
1489 				}
1490 				if( frac == 1 ) {
1491 					game_g->numbers_half->draw(offset_panel_x_c + 36 + off + 1, offset_panel_y_c + 34 + 18 * cnt);
1492 				}
1493 				cnt++;
1494 			}
1495 		}
1496 		if( design->isErgonomicallyTerrific() ) {
1497 			game_g->icon_ergo->draw(offset_panel_x_c + 64, offset_panel_y_c + 32);
1498 		}
1499 	}
1500 	else if( this->c_page == STATE_FACTORY ) {
1501 		//const int y0 = 16;
1502 		const int y0 = 14;
1503 		//const int y1 = 44;
1504 		const int y1 = 40;
1505 		//const int y2 = 72;
1506 		const int y2 = 66;
1507 		this->button_workers->setImage( game_g->men[gamestate->getCurrentSector()->getEpoch()] );
1508 		if( gamestate->getCurrentSector()->getCurrentManufacture() == NULL ) {
1509 			game_g->dash_grey->draw(offset_panel_x_c + 45, offset_panel_y_c + y0 + 20);
1510 			this->button_famount->setImage(NULL);
1511 		}
1512 		else {
1513 			Invention *current_manufacture = gamestate->getCurrentSector()->getCurrentManufacture()->getInvention();
1514 			this->button_famount->setImage( current_manufacture->getImage() );
1515 			//current_manufacture->getImage()->draw(offset_panel_x_c + 8, offset_panel_y_c + 16, true);
1516 			Image::writeNumbers(offset_panel_x_c + 48, offset_panel_y_c + y0 + 20, game_g->numbers_white, gamestate->getCurrentSector()->getWorkers(),Image::JUSTIFY_CENTRE);
1517 			int famount = gamestate->getCurrentSector()->getFAmount();
1518 			int famount_x = offset_panel_x_c + 48;
1519 			int famount_y = offset_panel_y_c + y1 + 18;
1520 			if( famount == infinity_c ) {
1521 				game_g->icon_infinity->draw(famount_x - game_g->icon_infinity->getScaledWidth()/2 + 2, famount_y - 2);
1522 			}
1523 			else {
1524 				Image::writeNumbers(famount_x, famount_y, game_g->numbers_white, famount,Image::JUSTIFY_CENTRE);
1525 			}
1526 
1527 			if( gamestate->getCurrentSector()->getWorkers() > 0 ) {
1528 				int halfdays = 0, hours = 0;
1529 				int thalfdays = 0, thours = 0;
1530 				gamestate->getCurrentSector()->manufactureTimeLeft(&halfdays, &hours);
1531 				gamestate->getCurrentSector()->manufactureTotalTime(&thalfdays, &thours);
1532 				game_g->icon_clocks[ hours+1 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + y0);
1533 				Image::writeNumbers(offset_panel_x_c + 80, offset_panel_y_c + y0 + 18, game_g->numbers_white, halfdays,Image::JUSTIFY_CENTRE);
1534 				int amount = gamestate->getCurrentSector()->getFAmount();
1535 				if( amount == infinity_c ) {
1536 					game_g->icon_clocks[ 0 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + y1);
1537 					game_g->icon_infinity->draw(offset_panel_x_c + 74, offset_panel_y_c + y1 + 16);
1538 				}
1539 				else {
1540 					thours *= (amount-1);
1541 					thalfdays *= (amount-1);
1542 					thours += hours;
1543 					thalfdays += halfdays;
1544 					thalfdays += thours/12;
1545 					thours = thours % 12;
1546 					game_g->icon_clocks[ thours+1 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + y1);
1547 					Image::writeNumbers(offset_panel_x_c + 80, offset_panel_y_c + y1 + 18, game_g->numbers_white, thalfdays, Image::JUSTIFY_CENTRE);
1548 				}
1549 			}
1550 			else {
1551 				game_g->icon_clocks[ 0 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + y0);
1552 				game_g->icon_infinity->draw(offset_panel_x_c + 74, offset_panel_y_c + y0 + 16);
1553 				game_g->icon_clocks[ 0 ]->draw(offset_panel_x_c + 72, offset_panel_y_c + y1);
1554 				game_g->icon_infinity->draw(offset_panel_x_c + 74, offset_panel_y_c + y1 + 16);
1555 			}
1556 		}
1557 		game_g->icon_shield->draw(offset_panel_x_c + 8, offset_panel_y_c + y2);
1558 		game_g->icon_defence->draw(offset_panel_x_c + 40, offset_panel_y_c + y2);
1559 		game_g->icon_weapon->draw(offset_panel_x_c + 72, offset_panel_y_c + y2);
1560 	}
1561 
1562 	MultiPanel::draw();
1563 }
1564 
changeMiners(Id element,bool decrease,int n)1565 void GamePanel::changeMiners(Id element,bool decrease,int n) {
1566 	ASSERT(element >= 0 && element < N_ID);
1567 	ASSERT( game_g->elements[element]->getType() != Element::GATHERABLE );
1568 	int n_miners = gamestate->getCurrentSector()->getMiners( element );
1569 	int n_spare = gamestate->getCurrentSector()->getAvailablePopulation();
1570 	if( decrease && n_miners > 0 ) {
1571 		n_miners -= n;
1572 		if( n_miners < 0 )
1573 			n_miners = 0;
1574 		//gamestate->getCurrentSector()->setMiners( element, n_miners );
1575 		const Sector *current_sector = this->gamestate->getCurrentSector();
1576 		this->gamestate->setNMiners(current_sector->getXPos(), current_sector->getYPos(), element, n_miners);
1577 	}
1578 	else if( !decrease && n_spare > 0 ) {
1579 		if( n > n_spare )
1580 			n = n_spare;
1581 		n_miners += n;
1582 		//gamestate->getCurrentSector()->setMiners( element, n_miners );
1583 		const Sector *current_sector = this->gamestate->getCurrentSector();
1584 		this->gamestate->setNMiners(current_sector->getXPos(), current_sector->getYPos(), element, n_miners);
1585 	}
1586 }
1587 
buttonNDesignersClick(void * data,int arg,bool m_left,bool m_middle,bool m_right)1588 void GamePanel::buttonNDesignersClick(void *data, int arg, bool m_left, bool m_middle, bool m_right) {
1589 	GamePanel *gamePanel = static_cast<GamePanel *>(data);
1590 	if( gamePanel->gamestate->getCurrentSector()->getCurrentDesign() == NULL ) {
1591 		// no longer relevant
1592 		return;
1593 	}
1594 	int n_designers = gamePanel->gamestate->getCurrentSector()->getDesigners();
1595 	int n_spare = gamePanel->gamestate->getCurrentSector()->getAvailablePopulation();
1596 	int n = game_g->getNClicks();
1597 	if( m_left ) {
1598 		n_designers -= n;
1599 		if( n_designers < 0 )
1600 			n_designers = 0;
1601 		//gamePanel->gamestate->getCurrentSector()->setDesigners( n_designers );
1602 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1603 		gamePanel->gamestate->setNDesigners(current_sector->getXPos(), current_sector->getYPos(), n_designers);
1604 	}
1605 	else if( m_right ) {
1606 		if( n > n_spare )
1607 			n = n_spare;
1608 		n_designers += n;
1609 		//gamePanel->gamestate->getCurrentSector()->setDesigners( n_designers );
1610 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1611 		gamePanel->gamestate->setNDesigners(current_sector->getXPos(), current_sector->getYPos(), n_designers);
1612 	}
1613 }
1614 
buttonNManufacturersClick(void * data,int arg,bool m_left,bool m_middle,bool m_right)1615 void GamePanel::buttonNManufacturersClick(void *data, int arg, bool m_left, bool m_middle, bool m_right) {
1616 	GamePanel *gamePanel = static_cast<GamePanel *>(data);
1617 	if( gamePanel->gamestate->getCurrentSector()->getCurrentManufacture() == NULL ) {
1618 		// no longer relevant
1619 		return;
1620 	}
1621 	int n_workers = gamePanel->gamestate->getCurrentSector()->getWorkers();
1622 	int n_spare = gamePanel->gamestate->getCurrentSector()->getAvailablePopulation();
1623 	int n = game_g->getNClicks();
1624 	if( m_left ) {
1625 		n_workers -= n;
1626 		if( n_workers < 0 )
1627 			n_workers = 0;
1628 		//gamePanel->gamestate->getCurrentSector()->setWorkers( n_workers );
1629 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1630 		gamePanel->gamestate->setNWorkers(current_sector->getXPos(), current_sector->getYPos(), n_workers);
1631 	}
1632 	else if( m_right ) {
1633 		if( n > n_spare )
1634 			n = n_spare;
1635 		n_workers += n;
1636 		//gamePanel->gamestate->getCurrentSector()->setWorkers( n_workers );
1637 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1638 		gamePanel->gamestate->setNWorkers(current_sector->getXPos(), current_sector->getYPos(), n_workers);
1639 	}
1640 }
1641 
buttonFAmountClick(void * data,int arg,bool m_left,bool m_middle,bool m_right)1642 void GamePanel::buttonFAmountClick(void *data, int arg, bool m_left, bool m_middle, bool m_right) {
1643 	GamePanel *gamePanel = static_cast<GamePanel *>(data);
1644 	if( gamePanel->gamestate->getCurrentSector()->getCurrentManufacture() == NULL ) {
1645 		// no longer relevant
1646 		return;
1647 	}
1648 	int famount = gamePanel->gamestate->getCurrentSector()->getFAmount();
1649 	if( m_left ) {
1650 		if( famount > 1 ) {
1651 			//gamePanel->gamestate->getCurrentSector()->setFAmount( famount - 1 );
1652 			const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1653 			gamePanel->gamestate->setFAmount(current_sector->getXPos(), current_sector->getYPos(), famount - 1);
1654 		}
1655 	}
1656 	else if( m_right && famount != infinity_c ) {
1657 		//gamePanel->gamestate->getCurrentSector()->setFAmount( famount + 1 );
1658 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1659 		gamePanel->gamestate->setFAmount(current_sector->getXPos(), current_sector->getYPos(), famount + 1);
1660 	}
1661 }
1662 
buttonNMinersClick(void * data,int arg,bool m_left,bool m_middle,bool m_right)1663 void GamePanel::buttonNMinersClick(void *data, int arg, bool m_left, bool m_middle, bool m_right) {
1664 	GamePanel *gamePanel = static_cast<GamePanel *>(data);
1665     if( gamePanel->button_nminers[arg] == NULL || !gamePanel->button_nminers[arg]->isVisible() ) {
1666 		// no longer relevant
1667 		return;
1668 	}
1669     int n = game_g->getNClicks();
1670 	Id element = (Id)gamePanel->element_index[arg];
1671 	gamePanel->changeMiners(element, m_left, n);
1672 }
1673 
buttonNBuildersClick(void * data,int arg,bool m_left,bool m_middle,bool m_right)1674 void GamePanel::buttonNBuildersClick(void *data, int arg, bool m_left, bool m_middle, bool m_right) {
1675 	GamePanel *gamePanel = static_cast<GamePanel *>(data);
1676 	if( gamePanel->button_nbuilders[arg] == NULL || !gamePanel->button_nbuilders[arg]->isVisible() ) {
1677 		// no longer relevant
1678 		return;
1679 	}
1680 	int n_builders = gamePanel->gamestate->getCurrentSector()->getBuilders((Type)arg);
1681 	int n_spare = gamePanel->gamestate->getCurrentSector()->getAvailablePopulation();
1682 	int n = game_g->getNClicks();
1683 	if( m_left && n_builders > 0 ) {
1684 		n_builders -= n;
1685 		if( n_builders < 0 )
1686 			n_builders = 0;
1687 		//gamePanel->gamestate->getCurrentSector()->setBuilders((Type)arg, n_builders);
1688 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1689 		gamePanel->gamestate->setNBuilders(current_sector->getXPos(), current_sector->getYPos(), (Type)arg, n_builders);
1690 	}
1691 	else if( m_right && n_spare > 0 ) {
1692 		if( n > n_spare )
1693 			n = n_spare;
1694 		n_builders += n;
1695 		//gamePanel->gamestate->getCurrentSector()->setBuilders((Type)arg, n_builders);
1696 		const Sector *current_sector = gamePanel->gamestate->getCurrentSector();
1697 		gamePanel->gamestate->setNBuilders(current_sector->getXPos(), current_sector->getYPos(), (Type)arg, n_builders);
1698 	}
1699 }
1700 
input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click)1701 void GamePanel::input(int m_x,int m_y,bool m_left,bool m_middle,bool m_right,bool click) {
1702 	MultiPanel::input(m_x, m_y, m_left, m_middle, m_right, click);
1703 	if( this->hasModal() ) {
1704 		return;
1705 	}
1706 	//bool m_left = mouse_left(m_b);
1707 	//bool m_right = mouse_right(m_b);
1708     bool done = false;
1709 
1710 	const int help_delay_c = 1000;
1711 	const int help_x_c = 160;
1712 	const int help_y_c = 120;
1713 	const char help_elementstocks_c[] = "mine new elements";
1714 	const char help_build_c[] = "construct new buildings";
1715 
1716 	if( this->c_page == STATE_SECTORCONTROL ) {
1717 		if( m_left && click && this->button_design->mouseOver(m_x,m_y) ) {
1718             done = true;
1719             registerClick();
1720 			if( gamestate->getCurrentSector()->getCurrentDesign() == NULL ) {
1721 				game_g->addTextEffect(new TextEffect("click on a new design to invent", help_x_c, help_y_c, help_delay_c));
1722 			}
1723             this->setPage(STATE_DESIGN);
1724 		}
1725 		else if( m_left && click && this->button_shield->mouseOver(m_x,m_y) ) {
1726             done = true;
1727             registerClick();
1728 			game_g->addTextEffect(new TextEffect("displays strength of your buildings", help_x_c, help_y_c, help_delay_c));
1729             this->setPage(STATE_SHIELD);
1730 		}
1731 		else if( m_left && click && this->button_defence->mouseOver(m_x,m_y) ) {
1732             done = true;
1733             registerClick();
1734 			game_g->addTextEffect(new TextEffect("deploy defenders to your buildings", help_x_c, help_y_c, help_delay_c));
1735             this->setPage(STATE_DEFENCE);
1736 		}
1737 		else if( m_left && click && this->button_attack->mouseOver(m_x,m_y) ) {
1738             done = true;
1739             registerClick();
1740 			game_g->addTextEffect(new TextEffect("deploy your armies", help_x_c, help_y_c, help_delay_c));
1741             this->setPage(STATE_ATTACK);
1742 		}
1743 		/*else if( m_left && click && this->button_elementstocks->mouseOver(m_x,m_y) ) {
1744             done = true;
1745             registerClick();
1746             this->setPage(STATE_ELEMENTSTOCKS);
1747 x		}*/
1748 		else if( ( m_left || m_right ) && this->button_ndesigners->mouseOver(m_x,m_y) && gamestate->getCurrentSector()->getCurrentDesign() != NULL ) {
1749             done = true;
1750 			processClick(buttonNDesignersClick, this->get(this->c_page), this, 0, button_ndesigners, m_left, m_middle, m_right, click);
1751 		}
1752 		else if( ( m_left || m_right ) && this->button_nworkers->mouseOver(m_x,m_y) && gamestate->getCurrentSector()->getCurrentManufacture() != NULL ) {
1753             done = true;
1754 			processClick(buttonNManufacturersClick, this->get(this->c_page), this, 0, button_nworkers, m_left, m_middle, m_right, click);
1755 		}
1756 		else if( m_left && click && ( this->button_build[BUILDING_MINE]->mouseOver(m_x,m_y) || this->button_build[BUILDING_FACTORY]->mouseOver(m_x,m_y) || this->button_build[BUILDING_LAB]->mouseOver(m_x,m_y) )  ) {
1757             done = true;
1758             registerClick();
1759 			game_g->addTextEffect(new TextEffect(help_build_c, help_x_c, help_y_c, help_delay_c));
1760             this->setPage(STATE_BUILD);
1761 		}
1762 		else if( m_left && click && this->button_knowndesigns->mouseOver(m_x,m_y) ) {
1763             done = true;
1764             registerClick();
1765 			game_g->addTextEffect(new TextEffect("displays elements needed for each design", help_x_c, help_y_c, help_delay_c));
1766             this->setPage(STATE_KNOWNDESIGNS);
1767 		}
1768 		else if( m_left && click && this->button_factory->mouseOver(m_x,m_y) ) {
1769             done = true;
1770             registerClick();
1771 			if( gamestate->getCurrentSector()->getCurrentManufacture() == NULL ) {
1772 				game_g->addTextEffect(new TextEffect("use the factory to manufacture advanced weapons", help_x_c, help_y_c, help_delay_c));
1773 			}
1774             this->setPage(STATE_FACTORY);
1775 		}
1776 
1777         for(int i=0;i<4 && ( m_left || m_right ) && !done;i++) {
1778 			//Id element = (Id)this->element_index[i];
1779 			if( m_left && click && this->button_elements[i]->mouseOver(m_x, m_y) ) {
1780                 done = true;
1781                 registerClick();
1782 				game_g->addTextEffect(new TextEffect(help_elementstocks_c, help_x_c, help_y_c, help_delay_c));
1783                 this->setPage(STATE_ELEMENTSTOCKS);
1784 			}
1785             else if( this->button_nminers[i]->mouseOver(m_x,m_y) ) {
1786                 done = true;
1787                 // if one mouse button, only allow changing via the sub-menu (otherwise problems with left/right icons going off screen)
1788                 if( game_g->oneMouseButtonMode() ) {
1789 					if( click ) {
1790 	                    registerClick();
1791 						game_g->addTextEffect(new TextEffect(help_elementstocks_c, help_x_c, help_y_c, help_delay_c));
1792 		                this->setPage(STATE_ELEMENTSTOCKS);
1793 					}
1794                 }
1795                 else {
1796                     ASSERT_ELEMENT_ID( this->element_index[i] );
1797                     processClick(buttonNMinersClick, this->get(this->c_page), this, i, button_nminers[i], m_left, m_middle, m_right, click);
1798                 }
1799 			}
1800 		}
1801 
1802         for(int i=0;i<N_BUILDINGS && ( m_left || m_right ) && !done;i++) {
1803             if( button_nbuilders[i] != NULL && this->button_nbuilders[i]->mouseOver(m_x,m_y) ) {
1804                 done = true;
1805                 // if one mouse button, only allow changing via the sub-menu (otherwise problems with left/right icons going off screen)
1806                 if( game_g->oneMouseButtonMode() ) {
1807 					if( click ) {
1808 	                    registerClick();
1809 						game_g->addTextEffect(new TextEffect(help_build_c, help_x_c, help_y_c, help_delay_c));
1810 		                this->setPage(STATE_BUILD);
1811 					}
1812                 }
1813                 else {
1814                     processClick(buttonNBuildersClick, this->get(this->c_page), this, i, button_nbuilders[i], m_left, m_middle, m_right, click);
1815                 }
1816 			}
1817 		}
1818 	}
1819 	else if( this->c_page == STATE_DESIGN ) {
1820 		if( m_left && click && this->button_bigdesign->mouseOver(m_x,m_y) ) {
1821             done = true;
1822             registerClick();
1823             this->setPage(STATE_SECTORCONTROL);
1824 		}
1825         for(int i=0;i<game_g->getNSubEpochs() && !done && click;i++) {
1826 			if( m_left && this->button_shields[i]->mouseOver(m_x,m_y)
1827 				&& ( gamestate->getCurrentSector()->getCurrentDesign() == NULL
1828 				|| gamestate->getCurrentSector()->getCurrentDesign()->getInvention() != game_g->invention_shields[game_g->getStartEpoch() + i] )
1829 				) {
1830                     done = true;
1831                     Design *design = gamestate->getCurrentSector()->bestDesign(Invention::SHIELD, game_g->getStartEpoch() + i);
1832 					//gamestate->getCurrentSector()->setCurrentDesign( design );
1833 					gamestate->setCurrentDesign(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), design);
1834 					{
1835 						stringstream str;
1836 						str << "start designing a " << design->getInvention()->getName();
1837 						game_g->addTextEffect(new TextEffect(str.str(), help_x_c, help_y_c, help_delay_c));
1838 					}
1839 			}
1840 			else if( m_left && this->button_defences[i]->mouseOver(m_x,m_y)
1841 				&& ( gamestate->getCurrentSector()->getCurrentDesign() == NULL
1842 				|| gamestate->getCurrentSector()->getCurrentDesign()->getInvention() != game_g->invention_defences[game_g->getStartEpoch() + i] )
1843 				) {
1844                     done = true;
1845                     Design *design = gamestate->getCurrentSector()->bestDesign(Invention::DEFENCE, game_g->getStartEpoch() + i);
1846 					//gamestate->getCurrentSector()->setCurrentDesign( design );
1847 					gamestate->setCurrentDesign(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), design);
1848 					{
1849 						stringstream str;
1850 						str << "start designing a " << design->getInvention()->getName();
1851 						game_g->addTextEffect(new TextEffect(str.str(), help_x_c, help_y_c, help_delay_c));
1852 					}
1853 			}
1854 			else if( m_left && this->button_weapons[i]->mouseOver(m_x,m_y)
1855 				&& ( gamestate->getCurrentSector()->getCurrentDesign() == NULL
1856 				|| gamestate->getCurrentSector()->getCurrentDesign()->getInvention() != game_g->invention_weapons[game_g->getStartEpoch() + i] )
1857 				) {
1858                     done = true;
1859                     Design *design = gamestate->getCurrentSector()->bestDesign(Invention::WEAPON, game_g->getStartEpoch() + i);
1860 					//gamestate->getCurrentSector()->setCurrentDesign( design );
1861 					gamestate->setCurrentDesign(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), design);
1862 					{
1863 						stringstream str;
1864 						str << "start designing a " << design->getInvention()->getName();
1865 						game_g->addTextEffect(new TextEffect(str.str(), help_x_c, help_y_c, help_delay_c));
1866 					}
1867 			}
1868 		}
1869         if( ( m_left || m_right ) && !done && this->button_designers->mouseOver(m_x,m_y) ) {
1870             done = true;
1871 			processClick(buttonNDesignersClick, this->get(this->c_page), this, 0, button_designers, m_left, m_middle, m_right, click);
1872 		}
1873 	}
1874 	else if( this->c_page == STATE_SHIELD ) {
1875 		if( m_left && click && this->button_bigshield->mouseOver(m_x,m_y) ) {
1876             done = true;
1877             registerClick();
1878             this->setPage(STATE_SECTORCONTROL);
1879 		}
1880         for(int i=0;i<game_g->getNSubEpochs() && !done;i++) {
1881 			if( m_left && click && this->button_deploy_shields[i]->mouseOver(m_x,m_y) ) {
1882                 done = true;
1883                 registerClick();
1884                 if( mousestate == MOUSESTATE_DEPLOY_SHIELD && deploy_shield == i )
1885 					setMouseState(MOUSESTATE_NORMAL);
1886 				else {
1887 					int n_store = gamestate->getCurrentSector()->getStoredShields(i);
1888 					if( n_store > 0 || ( game_g->getStartEpoch() + i < factory_epoch_c && gamestate->getCurrentSector()->canBuildDesign(Invention::SHIELD, game_g->getStartEpoch()+i) ) ) {
1889 						setMouseState(MOUSESTATE_DEPLOY_SHIELD);
1890 						deploy_shield = i;
1891 						ASSERT_EPOCH(deploy_shield);
1892 					}
1893 				}
1894 			}
1895 		}
1896         if( m_left && click && !done && this->button_shutdown->mouseOver(m_x,m_y) ) {
1897             done = true;
1898             if( mousestate == MOUSESTATE_SHUTDOWN )
1899 				setMouseState(MOUSESTATE_NORMAL);
1900 			else
1901 				setMouseState(MOUSESTATE_SHUTDOWN);
1902 		}
1903 	}
1904 	else if( this->c_page == STATE_DEFENCE ) {
1905 		if( m_left && click && this->button_bigdefence->mouseOver(m_x,m_y) ) {
1906             done = true;
1907             registerClick();
1908             this->setPage(STATE_SECTORCONTROL);
1909 		}
1910         for(int i=0;i<game_g->getNSubEpochs() && !done;i++) {
1911 			if( m_left && click && this->button_deploy_defences[i]->mouseOver(m_x,m_y) ) {
1912                 done = true;
1913                 registerClick();
1914                 if( mousestate == MOUSESTATE_DEPLOY_DEFENCE && deploy_defence == game_g->getStartEpoch() + i )
1915 					setMouseState(MOUSESTATE_NORMAL);
1916 				else {
1917 					int n_store = gamestate->getCurrentSector()->getStoredDefenders(game_g->getStartEpoch() + i);
1918 					if( n_store > 0 || ( game_g->getStartEpoch() + i < factory_epoch_c && gamestate->getCurrentSector()->canBuildDesign(Invention::DEFENCE, game_g->getStartEpoch()+i) ) ) {
1919 						setMouseState(MOUSESTATE_DEPLOY_DEFENCE);
1920 						deploy_defence = game_g->getStartEpoch() + i;
1921 						ASSERT_EPOCH(deploy_defence);
1922 					}
1923 				}
1924 			}
1925 		}
1926 	}
1927 	else if( this->c_page == STATE_ATTACK ) {
1928 		int n_nukes = 0;
1929 		if( m_left ) {
1930 			n_nukes = gamestate->getCurrentSector()->getAssembledArmy()->getSoldiers(nuclear_epoch_c);
1931 		}
1932 		if( m_left && click && this->button_bigattack->mouseOver(m_x,m_y) ) {
1933             done = true;
1934             registerClick();
1935             // return assembled army
1936 			this->setPage(STATE_SECTORCONTROL);
1937 			//gamestate->getCurrentSector()->returnAssembledArmy();
1938 			gamestate->returnAssembledArmy(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos());
1939 			setMouseState(MOUSESTATE_NORMAL);
1940 		}
1941 		else if( m_left && click && this->button_return_attackers->mouseOver(m_x,m_y) ) {
1942             done = true;
1943             // return assembled army
1944 			//gamestate->getCurrentSector()->returnAssembledArmy();
1945 			gamestate->returnAssembledArmy(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos());
1946 			setMouseState(MOUSESTATE_NORMAL);
1947 		}
1948 		else if( m_left && !click && this->button_select_all->mouseOver(m_x,m_y) && n_nukes == 0 ) {
1949             done = true;
1950 			// note that we don't include unarmed men - otherwise this causes a problem with non-manufacture weapons that are made of gatherables
1951 			// it might be that we can quickly make more a moment later, but not if we've selected the remaining men as unarmed!
1952 			gamestate->assembleAll(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), false);
1953 			if( gamestate->getCurrentSector()->getAssembledArmy()->any(true) ) {
1954 				setMouseState(MOUSESTATE_DEPLOY_WEAPON);
1955 			}
1956 		}
1957 		else if( m_left && !click && this->button_deploy_unarmedmen->mouseOver(m_x,m_y) && n_nukes == 0 ) {
1958             done = true;
1959             // add unarmed man to assembled army
1960 			int n_spare = gamestate->getCurrentSector()->getAvailablePopulation();
1961 			int n = game_g->getNClicks();
1962 			ASSERT(n >= 1);
1963 			if( n_spare < n )
1964 				n = 1;
1965 			if( n_spare >= n ) {
1966 				//gamestate->getCurrentSector()->getAssembledArmy()->add(n_epochs_c, n);
1967 				//gamestate->getCurrentSector()->setPopulation( n_population - n );
1968 				gamestate->assembleArmyUnarmed(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), n);
1969 				setMouseState(MOUSESTATE_DEPLOY_WEAPON);
1970 			}
1971 		}
1972 		// add weapons to assembled army?
1973         for(int i=0;i<game_g->getNSubEpochs() && m_left && !click && !done;i++) {
1974 			bool ok = true;
1975 			if( game_g->getStartEpoch() + i == nuclear_epoch_c && n_nukes == 0 ) {
1976 				int n_selected = gamestate->getCurrentSector()->getAssembledArmy()->getTotal();
1977 				if( n_selected > 0 )
1978 					ok = false;
1979 			}
1980 			else if( n_nukes > 0 ) {
1981 				ok = false;
1982 			}
1983 			if( ok && this->button_deploy_attackers[i]->mouseOver(m_x,m_y) ) {
1984                 done = true;
1985                 int n = game_g->getNClicks();
1986 				//if( gamestate->getCurrentSector()->assembleArmy(game_g->getStartEpoch() + i, n) ) {
1987 				if( gamestate->assembleArmy(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), game_g->getStartEpoch() + i, n) ) {
1988 					setMouseState(MOUSESTATE_DEPLOY_WEAPON);
1989 				}
1990 			}
1991 		}
1992 	}
1993 	else if( this->c_page == STATE_ELEMENTSTOCKS ) {
1994 		if( m_left && click && this->button_bigelementstocks->mouseOver(m_x,m_y) ) {
1995             done = true;
1996             registerClick();
1997             this->setPage(STATE_SECTORCONTROL);
1998 		}
1999         for(int i=0;i<4 && !done;i++) {
2000 			//Id element = (Id)this->element_index[i];
2001 			/*int n_elements = 0, fraction = 0;
2002 			gamestate->getCurrentSector()->getElements(&n_elements, &fraction, element);
2003 			if( ( n_elements > 0 || fraction > 0 ) && elements[element]->type != Element::GATHERABLE && ( m_left || m_right ) && this->button_nminers2[i]->mouseOver(m_x,m_y) ) {*/
2004 			if( ( m_left || m_right ) && this->button_nminers2[i]->mouseOver(m_x,m_y) ) {
2005                 done = true;
2006                 ASSERT_ELEMENT_ID( this->element_index[i] );
2007 				/*int n = game_g->getNClicks();
2008 				changeMiners(element, m_left, n);*/
2009 				//processClick(buttonNMinersClick, this, i, button_nminers2[i], m_left, m_middle, m_right);
2010 				processClick(buttonNMinersClick, this->get(this->c_page), this, i, button_nminers2[i], m_left, m_middle, m_right, click);
2011 			}
2012 		}
2013 	}
2014 	else if( this->c_page == STATE_BUILD ) {
2015 		if( m_left && click && this->button_bigbuild->mouseOver(m_x,m_y) ) {
2016             done = true;
2017             registerClick();
2018             this->setPage(STATE_SECTORCONTROL);
2019 		}
2020 		else if( m_left || m_right ) {
2021             for(int i=0;i<N_BUILDINGS && !done;i++) {
2022 				if( button_nbuilders2[i] != NULL && this->button_nbuilders2[i]->mouseOver(m_x,m_y) ) {
2023                     done = true;
2024                     /*int n_builders = gamestate->getCurrentSector()->getBuilders((Type)i);
2025 					int n_spare = gamestate->getCurrentSector()->getAvailablePopulation();
2026 					int n = game_g->getNClicks();
2027 					if( m_left && n_builders > 0 ) {
2028 						n_builders -= n;
2029 						if( n_builders < 0 )
2030 							n_builders = 0;
2031 						gamestate->getCurrentSector()->setBuilders((Type)i, n_builders);
2032 					}
2033 					else if( m_right && n_spare > 0 ) {
2034 						if( n > n_spare )
2035 							n = n_spare;
2036 						n_builders += n;
2037 						gamestate->getCurrentSector()->setBuilders((Type)i, n_builders);
2038 					}*/
2039 					//processClick(buttonNBuildersClick, this, i, button_nbuilders2[i], m_left, m_middle, m_right);
2040 					processClick(buttonNBuildersClick, this->get(this->c_page), this, i, button_nbuilders2[i], m_left, m_middle, m_right, click);
2041 				}
2042 			}
2043 		}
2044 	}
2045 	else if( this->c_page == STATE_KNOWNDESIGNS ) {
2046 		if( m_left && click && this->button_bigknowndesigns->mouseOver(m_x,m_y) ) {
2047             done = true;
2048             registerClick();
2049             this->setPage(STATE_SECTORCONTROL);
2050 		}
2051         for(int i=0;i<game_g->getNSubEpochs() && !done;i++) {
2052 			if( m_left && click && this->button_knownshields[i]->mouseOver(m_x,m_y) ) {
2053                 done = true;
2054                 registerClick();
2055                 this->setPage(STATE_DESIGNINFO);
2056 				this->designinfo = Invention::getInvention(Invention::SHIELD,game_g->getStartEpoch()+i);
2057 			}
2058 			else if( m_left && click && this->button_knowndefences[i]->mouseOver(m_x,m_y) ) {
2059                 done = true;
2060                 registerClick();
2061                 this->setPage(STATE_DESIGNINFO);
2062 				this->designinfo = Invention::getInvention(Invention::DEFENCE,game_g->getStartEpoch()+i);
2063 			}
2064 			else if( m_left && click && this->button_knownweapons[i]->mouseOver(m_x,m_y) ) {
2065                 done = true;
2066                 registerClick();
2067                 this->setPage(STATE_DESIGNINFO);
2068 				this->designinfo = Invention::getInvention(Invention::WEAPON,game_g->getStartEpoch()+i);
2069 			}
2070 		}
2071 	}
2072 	else if( this->c_page == STATE_DESIGNINFO ) {
2073 		if( m_left && click && this->button_bigdesigninfo->mouseOver(m_x,m_y) ) {
2074             done = true;
2075             registerClick();
2076             this->setPage(STATE_KNOWNDESIGNS);
2077 		}
2078 		//if( ( onemousebutton ? m_left : ( m_left && m_right ) ) && click && this->button_trashdesign->mouseOver(m_x,m_y) ) {
2079 		if( m_left && click && this->button_trashdesign->mouseOver(m_x,m_y) ) {
2080             done = true;
2081             registerClick();
2082             this->setPage(STATE_KNOWNDESIGNS);
2083 			ASSERT(this->designinfo != NULL);
2084 			//gamestate->getCurrentSector()->trashDesign(this->designinfo);
2085 			gamestate->trashDesign(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), this->designinfo);
2086 		}
2087 	}
2088 	else if( this->c_page == STATE_FACTORY ) {
2089 		if( m_left && click && this->button_bigfactory->mouseOver(m_x,m_y) ) {
2090             done = true;
2091             registerClick();
2092             this->setPage(STATE_SECTORCONTROL);
2093 		}
2094         for(int i=0;i<game_g->getNSubEpochs() && !done && click;i++) {
2095 			if( m_left && this->button_fshields[i]->mouseOver(m_x,m_y)
2096 				&& ( gamestate->getCurrentSector()->getCurrentManufacture() == NULL
2097 				|| gamestate->getCurrentSector()->getCurrentManufacture()->getInvention() != game_g->invention_shields[game_g->getStartEpoch() + i] )
2098 				) {
2099                     done = true;
2100                     Design *design = gamestate->getCurrentSector()->knownDesign(Invention::SHIELD, game_g->getStartEpoch() + i);
2101 					//gamestate->getCurrentSector()->setCurrentManufacture( design );
2102 					gamestate->setCurrentManufacture(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), design);
2103 					{
2104 						stringstream str;
2105 						str << "start manufacturing a " << design->getInvention()->getName();
2106 						game_g->addTextEffect(new TextEffect(str.str(), help_x_c, help_y_c, help_delay_c));
2107 					}
2108 			}
2109 			else if( m_left && this->button_fdefences[i]->mouseOver(m_x,m_y)
2110 				&& ( gamestate->getCurrentSector()->getCurrentManufacture() == NULL
2111 				|| gamestate->getCurrentSector()->getCurrentManufacture()->getInvention() != game_g->invention_defences[game_g->getStartEpoch() + i] )
2112 				) {
2113                     done = true;
2114                     Design *design = gamestate->getCurrentSector()->knownDesign(Invention::DEFENCE, game_g->getStartEpoch() + i);
2115 					//gamestate->getCurrentSector()->setCurrentManufacture( design );
2116 					gamestate->setCurrentManufacture(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), design);
2117 					{
2118 						stringstream str;
2119 						str << "start manufacturing a " << design->getInvention()->getName();
2120 						game_g->addTextEffect(new TextEffect(str.str(), help_x_c, help_y_c, help_delay_c));
2121 					}
2122 			}
2123 			else if( m_left && this->button_fweapons[i]->mouseOver(m_x,m_y)
2124 				&& ( gamestate->getCurrentSector()->getCurrentManufacture() == NULL
2125 				|| gamestate->getCurrentSector()->getCurrentManufacture()->getInvention() != game_g->invention_weapons[game_g->getStartEpoch() + i] )
2126 				) {
2127                     done = true;
2128                     Design *design = gamestate->getCurrentSector()->knownDesign(Invention::WEAPON, game_g->getStartEpoch() + i);
2129 					//gamestate->getCurrentSector()->setCurrentManufacture( design );
2130 					gamestate->setCurrentManufacture(gamestate->getCurrentSector()->getXPos(), gamestate->getCurrentSector()->getYPos(), design);
2131 					{
2132 						stringstream str;
2133 						str << "start manufacturing a " << design->getInvention()->getName();
2134 						game_g->addTextEffect(new TextEffect(str.str(), help_x_c, help_y_c, help_delay_c));
2135 					}
2136 			}
2137 		}
2138         if( ( m_left || m_right ) && !done && this->button_workers->mouseOver(m_x,m_y) ) {
2139             done = true;
2140             /*int n_workers = gamestate->getCurrentSector()->getWorkers();
2141 			int n_spare = gamestate->getCurrentSector()->getAvailablePopulation();
2142 			int n = game_g->getNClicks();
2143 			if( m_left ) {
2144 				n_workers -= n;
2145 				if( n_workers < 0 )
2146 					n_workers = 0;
2147 				gamestate->getCurrentSector()->setWorkers( n_workers );
2148 			}
2149 			else if( m_right ) {
2150 				if( n > n_spare )
2151 					n = n_spare;
2152 				n_workers += n;
2153 				gamestate->getCurrentSector()->setWorkers( n_workers );
2154 			}*/
2155 			//processClick(buttonNManufacturersClick, this, 0, button_workers, m_left, m_middle, m_right);
2156 			processClick(buttonNManufacturersClick, this->get(this->c_page), this, 0, button_workers, m_left, m_middle, m_right, click);
2157 		}
2158         else if( ( m_left || m_right ) && !done && this->button_famount->mouseOver(m_x,m_y) ) {
2159             done = true;
2160             /*int famount = gamestate->getCurrentSector()->getFAmount();
2161 			if( m_left ) {
2162 				if( famount > 1 )
2163 					gamestate->getCurrentSector()->setFAmount( famount - 1 );
2164 			}
2165 			else if( m_right && famount != infinity_c ) {
2166 				gamestate->getCurrentSector()->setFAmount( famount + 1 );
2167 			}*/
2168 			//processClick(buttonFAmountClick, this, 0, button_famount, m_left, m_middle, m_right);
2169 			processClick(buttonFAmountClick, this->get(this->c_page), this, 0, button_famount, m_left, m_middle, m_right, click);
2170 		}
2171 	}
2172 }
2173