1 #include "stdafx.h"
2
3 #include "tutorial.h"
4 #include "game.h"
5 #include "gamestate.h"
6 #include "gui.h"
7 #include "utils.h"
8
getTutorialInfo()9 vector<TutorialInfo> TutorialManager::getTutorialInfo() {
10 vector<TutorialInfo> infos;
11 infos.push_back( TutorialInfo("intro", "play your first island") );
12 infos.push_back( TutorialInfo("army_maneuvers", "army maneuvers") );
13 infos.push_back( TutorialInfo("build_manufacture", "learn to build and manufacture") );
14 return infos;
15 }
16
setupTutorial(const string & id)17 Tutorial *TutorialManager::setupTutorial(const string &id) {
18 Tutorial *tutorial = NULL;
19 if( id == "intro" )
20 tutorial = new Tutorial1(id);
21 else if( id == "army_maneuvers" )
22 tutorial = new Tutorial2(id);
23 else if( id == "build_manufacture" )
24 tutorial = new Tutorial3(id);
25 return tutorial;
26 }
27
resetGUI(PlayingGameState * playing_gamestate)28 void GUIHandler::resetGUI(PlayingGameState *playing_gamestate) {
29 playing_gamestate->getGamePanel()->setEnabled(true);
30 playing_gamestate->getScreenPage()->setEnabled(true);
31 }
32
setGUI(PlayingGameState * playing_gamestate) const33 void GUIHandlerBlockAll::setGUI(PlayingGameState *playing_gamestate) const {
34 playing_gamestate->getGamePanel()->setEnabled(false);
35 playing_gamestate->getScreenPage()->setEnabled(false);
36 for(vector<string>::const_iterator iter = exceptions.begin(); iter != exceptions.end(); ++iter) {
37 const string exception = *iter;
38 PanelPage *panel = playing_gamestate->getGamePanel()->findById(exception);
39 if( panel != NULL ) {
40 panel->setEnabled(true);
41 }
42 else {
43 panel = playing_gamestate->getScreenPage()->findById(exception);
44 if( panel != NULL ) {
45 panel->setEnabled(true);
46 }
47 }
48 }
49 // the following are always exceptions
50 PanelPage *pause_button = playing_gamestate->getScreenPage()->findById("pause_button");
51 T_ASSERT( pause_button != NULL );
52 if( pause_button != NULL ) {
53 pause_button->setEnabled(true);
54 }
55 PanelPage *quit_button = playing_gamestate->getScreenPage()->findById("quit_button");
56 T_ASSERT( quit_button != NULL );
57 if( quit_button != NULL ) {
58 quit_button->setEnabled(true);
59 }
60 PanelPage *speed_button = playing_gamestate->getScreenPage()->findById("speed_button");
61 T_ASSERT( speed_button != NULL );
62 if( speed_button != NULL ) {
63 speed_button->setEnabled(true);
64 }
65 }
66
hasArrow(PlayingGameState * playing_gamestate) const67 bool TutorialCard::hasArrow(PlayingGameState *playing_gamestate) const {
68 if( this->show_arrow_on_page && playing_gamestate->getGamePanel()->getPage() != this->show_arrow_page )
69 return false;
70 if( this->show_arrow_on_sector && ( playing_gamestate->getCurrentSector()->getXPos() != this->show_arrow_sector_x || playing_gamestate->getCurrentSector()->getYPos() != this->show_arrow_sector_y ) )
71 return false;
72 return has_arrow;
73 }
74
setGUI(PlayingGameState * playing_gamestate) const75 void TutorialCard::setGUI(PlayingGameState *playing_gamestate) const {
76 playing_gamestate->getGamePanel()->setEnabled(true);
77 playing_gamestate->getScreenPage()->setEnabled(true);
78 if( gui_handler != NULL ) {
79 gui_handler->setGUI(playing_gamestate);
80 }
81 }
82
canProceed(PlayingGameState * playing_gamestate) const83 bool TutorialCardWaitForPanelPage::canProceed(PlayingGameState *playing_gamestate) const {
84 int c_page = playing_gamestate->getGamePanel()->getPage();
85 return c_page == wait_page;
86 }
87
canProceed(PlayingGameState * playing_gamestate) const88 bool TutorialCardWaitForDesign::canProceed(PlayingGameState *playing_gamestate) const {
89 if( wait_type == WAITTYPE_CURRENT_DESIGN || wait_type == WAITTYPE_CURRENT_MANUFACTURE ) {
90 const Design *current_design = wait_type == WAITTYPE_CURRENT_DESIGN ? sector->getCurrentDesign() : sector->getCurrentManufacture();
91 if( current_design == NULL )
92 return false;
93 const Invention *invention = current_design->getInvention();
94 if( require_type && invention->getType() != invention_type )
95 return false;
96 if( require_epoch && invention->getEpoch() != invention_epoch )
97 return false;
98 return true;
99 }
100 else if( wait_type == WAITTYPE_HAS_DESIGNED || wait_type == WAITTYPE_HAS_MANUFACTURED ) {
101 for(int i=0;i<Invention::N_TYPES;i++) {
102 if( require_type && i != invention_type )
103 continue;
104 int n_j = i == Invention::SHIELD ? n_shields_c : n_epochs_c;
105 for(int j=0;j<n_j;j++) {
106 if( require_epoch && j != invention_epoch )
107 continue;
108 if( wait_type == WAITTYPE_HAS_DESIGNED && sector->inventionKnown(static_cast<Invention::Type>(i), j) ) {
109 return true;
110 }
111 else if( wait_type == WAITTYPE_HAS_MANUFACTURED && i == Invention::SHIELD && sector->getStoredShields(j) > 0 ) {
112 return true;
113 }
114 else if( wait_type == WAITTYPE_HAS_MANUFACTURED && i == Invention::DEFENCE && sector->getStoredDefenders(j) > 0 ) {
115 return true;
116 }
117 else if( wait_type == WAITTYPE_HAS_MANUFACTURED && i == Invention::WEAPON && sector->getStoredArmy()->getSoldiers(j) > 0 ) {
118 return true;
119 }
120 }
121 }
122 return false;
123 }
124 ASSERT(false);
125 return true;
126 }
127
canProceed(PlayingGameState * playing_gamestate) const128 bool TutorialCardWaitForBuilding::canProceed(PlayingGameState *playing_gamestate) const {
129 if( sector->getBuilding(building_type) != NULL ) {
130 return true;
131 }
132 return false;
133 }
134
canProceed(PlayingGameState * playing_gamestate) const135 bool TutorialCardWaitForDeployedArmy::canProceed(PlayingGameState *playing_gamestate) const {
136 if( !inverse ) {
137 int str = require_bombard ? deploy_sector->getArmy(playing_gamestate->getClientPlayer())->getBombardStrength() : deploy_sector->getArmy(playing_gamestate->getClientPlayer())->getTotal();
138 if( require_unoccupied && deploy_sector->getPlayer() != PLAYER_NONE ) {
139 return false;
140 }
141 if( require_empty && str == 0 )
142 return true;
143 else if( !require_empty && str > 0 )
144 return true;
145 }
146 else {
147 for(int y=0;y<map_height_c;y++) {
148 for(int x=0;x<map_width_c;x++) {
149 if( game_g->getMap()->isSectorAt(x, y) ) {
150 const Sector *sector = game_g->getMap()->getSector(x, y);
151 if( sector == deploy_sector )
152 continue;
153 if( require_unoccupied && sector->getPlayer() != PLAYER_NONE ) {
154 continue;
155 }
156 int str = require_bombard ? sector->getArmy(playing_gamestate->getClientPlayer())->getBombardStrength() : sector->getArmy(playing_gamestate->getClientPlayer())->getTotal();
157 if( require_empty && str > 0 )
158 return false;
159 else if( !require_empty && str > 0 )
160 return true;
161 }
162 }
163 }
164 if( require_empty )
165 return true;
166 }
167 return false;
168 }
169
canProceed(PlayingGameState * playing_gamestate) const170 bool TutorialCardWaitForNewTower::canProceed(PlayingGameState *playing_gamestate) const {
171 if( !inverse ) {
172 bool has_tower = tower_sector->getPlayer() == playing_gamestate->getClientPlayer();
173 if( has_tower )
174 return true;
175 }
176 else {
177 for(int y=0;y<map_height_c;y++) {
178 for(int x=0;x<map_width_c;x++) {
179 if( game_g->getMap()->isSectorAt(x, y) ) {
180 const Sector *sector = game_g->getMap()->getSector(x, y);
181 if( sector == tower_sector )
182 continue;
183 bool has_tower = sector->getPlayer() == playing_gamestate->getClientPlayer();
184 if( has_tower )
185 return true;
186 }
187 }
188 }
189 }
190 return false;
191 }
192
~Tutorial()193 Tutorial::~Tutorial() {
194 for(vector<TutorialCard *>::const_iterator iter = cards.begin(); iter != cards.end(); ++iter) {
195 TutorialCard *card = *iter;
196 delete card;
197 }
198 }
199
jumpTo(const string & id)200 bool Tutorial::jumpTo(const string &id) {
201 int index = 0;
202 for(vector<TutorialCard *>::const_iterator iter = cards.begin(); iter != cards.end(); ++iter, index++) {
203 TutorialCard *card = *iter;
204 if( card->getId() == id ) {
205 card_index = index;
206 return true;
207 }
208 }
209 return false;
210 }
211
Tutorial1(const string & id)212 Tutorial1::Tutorial1(const string &id) : Tutorial(id) {
213 start_epoch = 0;
214 island = 0;
215 start_map_x = 1;
216 start_map_y = 2;
217 n_men = 20;
218 ai_allow_growth = false;
219 ai_allow_design = false;
220 ai_allow_ask_alliance = false;
221 ai_allow_deploy = false;
222 }
223
initCards()224 void Tutorial1::initCards() {
225 Sector *start_sector = game_g->getMap()->getSector(start_map_x, start_map_y);
226 ASSERT(start_sector != NULL);
227 Sector *enemy_sector = game_g->getMap()->getSector(2, 2);
228 ASSERT(enemy_sector != NULL);
229
230 TutorialCard *card = NULL;
231
232 #if defined(__ANDROID__)
233 card = new TutorialCard("0", "Welcome to Gigalomania!\nThis tutorial will introduce you to the game,\nand show you how to win your first island.\nUse the volume keys on your device to control the music volume.\nClick 'next' to continue when you're ready.");
234 #else
235 card = new TutorialCard("0", "Welcome to Gigalomania!\nThis tutorial will introduce you to the game,\nand show you how to win your first island.\nClick 'next' to continue when you're ready.");
236 #endif
237 card->setGUIHandler(new GUIHandlerBlockAll());
238 cards.push_back(card);
239
240 card = new TutorialCard("1", "At the top left you can see a map of the current island.\nThe island is split up into sectors.\nThe coloured squares represent sectors controlled by a player.");
241 card->setArrow(40, 56);
242 card->setGUIHandler(new GUIHandlerBlockAll());
243 cards.push_back(card);
244
245 card = new TutorialCard("2", "The age of this sector is 10,000 bc.\nThis represents the state of technology. \nIt's possible for different sectors to be in different ages.");
246 card->setArrow(80, 110);
247 card->setGUIHandler(new GUIHandlerBlockAll());
248 cards.push_back(card);
249
250 card = new TutorialCard("3", "Next we'll go over the control panel, which\nallows you to control your sector.");
251 card->setGUIHandler(new GUIHandlerBlockAll());
252 cards.push_back(card);
253
254 card = new TutorialCard("4", "The number below the person icon shows the number of people in your\nsector that are available.\nThe population will grow gradually with time.");
255 card->setArrow(16, 136);
256 card->setGUIHandler(new GUIHandlerBlockAll());
257 cards.push_back(card);
258
259 card = new TutorialCardWaitForPanelPage("5", "Now let's design a weapon!\nClick on the lightbulb icon to start researching.", (int)GamePanel::STATE_DESIGN);
260 card->setArrow(36, 156);
261 {
262 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
263 gui_handler->addException("button_design");
264 card->setGUIHandler(gui_handler);
265 }
266 cards.push_back(card);
267
268 card = new TutorialCard("6", "This page allows you to design new inventions:\nThe left hand column shows shields, which are used to repair buildings.\nThe middle shows defences for your sector.\nThe right shows weapons to attack the enemy!");
269 card->setGUIHandler(new GUIHandlerBlockAll());
270 cards.push_back(card);
271
272 card = new TutorialCardWaitForDesign("7", "For this tutorial, we're going to design a weapon.\nClick on one of the weapons.\nI recommend the Rock weapon, but any will do.", start_sector, TutorialCardWaitForDesign::WAITTYPE_CURRENT_DESIGN, true, Invention::WEAPON, false, -1);
273 card->setArrow(90, 168);
274 {
275 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
276 gui_handler->addException("button_weapons_0");
277 gui_handler->addException("button_weapons_1");
278 gui_handler->addException("button_weapons_2");
279 gui_handler->addException("button_weapons_3");
280 card->setGUIHandler(gui_handler);
281 }
282 cards.push_back(card);
283
284 if( game_g->isOneMouseButton() ) {
285 card = new TutorialCard("8", "Now put some of your people to work designing the weapon.\nClick on the number, then use the arrows to increase or decrease\nthe number of designers.");
286 }
287 else {
288 card = new TutorialCard("8", "Now put some of your people to work designing the weapon.\nUsing the right mouse button, click on the number to increase\nthe number of designers, left mouse button to decrease.");
289 }
290 card->setArrow(50, 130);
291 {
292 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
293 gui_handler->addException("button_weapons_0");
294 gui_handler->addException("button_weapons_1");
295 gui_handler->addException("button_weapons_2");
296 gui_handler->addException("button_weapons_3");
297 gui_handler->addException("button_designers");
298 card->setGUIHandler(gui_handler);
299 }
300 cards.push_back(card);
301
302 card = new TutorialCard("9", "While your designers are working, the clock shows the remaining time\nuntil the invention is ready.");
303 card->setArrow(86, 130);
304 {
305 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
306 gui_handler->addException("button_weapons_0");
307 gui_handler->addException("button_weapons_1");
308 gui_handler->addException("button_weapons_2");
309 gui_handler->addException("button_weapons_3");
310 gui_handler->addException("button_designers");
311 card->setGUIHandler(gui_handler);
312 }
313 cards.push_back(card);
314
315 if( game_g->isOneMouseButton() ) {
316 card = new TutorialCardWaitForDesign("10", "To hurry things up, you can make time go faster.\nClick the 1x icon to cycle through different time rates.", start_sector, TutorialCardWaitForDesign::WAITTYPE_HAS_DESIGNED, true, Invention::WEAPON, false, -1);
317 }
318 else {
319 card = new TutorialCardWaitForDesign("10", "To hurry things up, you can make time go faster.\nRight click on the 1x icon to speed time up.\nLeft click slows time back down.", start_sector, TutorialCardWaitForDesign::WAITTYPE_HAS_DESIGNED, true, Invention::WEAPON, false, -1);
320 }
321 card->setArrow(100, 10);
322 {
323 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
324 gui_handler->addException("button_weapons_0");
325 gui_handler->addException("button_weapons_1");
326 gui_handler->addException("button_weapons_2");
327 gui_handler->addException("button_weapons_3");
328 gui_handler->addException("button_designers");
329 card->setGUIHandler(gui_handler);
330 }
331 cards.push_back(card);
332
333 card = new TutorialCardWaitForPanelPage("11", "Great! Now click on the lightbulb to go back to the main interface.", (int)GamePanel::STATE_SECTORCONTROL);
334 card->setArrow(50, 110);
335 {
336 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
337 gui_handler->addException("button_weapons_0");
338 gui_handler->addException("button_weapons_1");
339 gui_handler->addException("button_weapons_2");
340 gui_handler->addException("button_weapons_3");
341 gui_handler->addException("button_designers");
342 gui_handler->addException("button_bigdesign");
343 card->setGUIHandler(gui_handler);
344 }
345 cards.push_back(card);
346
347 card = new TutorialCardWaitForPanelPage("11", "Time to attack our enemy. The shield and sword icon allows you to\nassemble your army.", (int)GamePanel::STATE_ATTACK);
348 card->setArrow(80, 125);
349 {
350 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
351 gui_handler->addException("button_attack");
352 card->setGUIHandler(gui_handler);
353 }
354 cards.push_back(card);
355
356 card = new TutorialCard("12", "This page shows you the available soldiers to deploy.\nThey can be unarmed or, preferably, armed with weapons\nyou have invented.");
357 card->setGUIHandler(new GUIHandlerBlockAll());
358 cards.push_back(card);
359
360 card = new TutorialCard("13", "Not only are armed soldiers stronger, but they are required to destroy\nan enemy's buildings. Unarmed soldiers can fight other soldiers,\nbut won't knock down the enemy tower.");
361 card->setGUIHandler(new GUIHandlerBlockAll());
362 cards.push_back(card);
363
364 card = new TutorialCard("14", "Click on the weapon icon to assemble soldiers with the weapon\nyou've just invented.\nAssemble as many soldiers as we have people available!");
365 card->setArrow(15, 170);
366 {
367 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
368 gui_handler->addException("button_deploy_attackers_0");
369 gui_handler->addException("button_deploy_attackers_1");
370 gui_handler->addException("button_deploy_attackers_2");
371 gui_handler->addException("button_deploy_attackers_3");
372 card->setGUIHandler(gui_handler);
373 }
374 cards.push_back(card);
375
376 card = new TutorialCardWaitForDeployedArmy("15", "Then click on the enemy's sector in the map - that's the\nright hand square - to send your army to attack.", enemy_sector, true);
377 card->setArrow(48, 56);
378 card->setArrowShowPage((int)GamePanel::STATE_ATTACK);
379 {
380 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
381 gui_handler->addException("button_deploy_attackers_0");
382 gui_handler->addException("button_deploy_attackers_1");
383 gui_handler->addException("button_deploy_attackers_2");
384 gui_handler->addException("button_deploy_attackers_3");
385 gui_handler->addException("map_1_2"); // need to allow the user to return to the player sector if necessary (as user can switch to the other sector without sending men)
386 gui_handler->addException("map_2_2");
387 gui_handler->addException("button_attack"); // allow the user to get back to the attack screen (a GUI resets to main if user switches current sector)
388 gui_handler->addException("button_bigattack"); // ...and for consistency, allow the user to go back to the main screen
389 // and in case the user wants to design some more:
390 gui_handler->addException("button_design");
391 gui_handler->addException("button_weapons_0");
392 gui_handler->addException("button_weapons_1");
393 gui_handler->addException("button_weapons_2");
394 gui_handler->addException("button_weapons_3");
395 gui_handler->addException("button_designers");
396 gui_handler->addException("button_bigdesign");
397 card->setGUIHandler(gui_handler);
398 }
399 cards.push_back(card);
400
401 card = new TutorialCard("16", "Now wait until the battle is won!\nRemember to speed up the time rate if you prefer.");
402 card->setNextText("Done");
403 cards.push_back(card);
404
405 // for debugging
406 //this->card_index = 13;
407 }
408
Tutorial2(const string & id)409 Tutorial2::Tutorial2(const string &id) : Tutorial(id) {
410 start_epoch = 0;
411 island = 2;
412 start_map_x = 2;
413 start_map_y = 2;
414 n_men = 25;
415 auto_end = true;
416 ai_allow_growth = false;
417 ai_allow_design = false;
418 ai_allow_ask_alliance = false;
419 ai_allow_deploy = false;
420 allow_retreat_loss = false;
421 }
422
initCards()423 void Tutorial2::initCards() {
424 Sector *start_sector = game_g->getMap()->getSector(start_map_x, start_map_y);
425 ASSERT(start_sector != NULL);
426
427 TutorialCard *card = NULL;
428
429 card = new TutorialCardWaitForPanelPage("0", "In this tutorial we'll learn some army maneuvers.\nSelect the shield and sword icon to deploy some soldiers.", (int)GamePanel::STATE_ATTACK);
430 card->setPlayerAllowBuildTower(false);
431 card->setArrow(80, 125);
432 {
433 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
434 gui_handler->addException("button_attack");
435 card->setGUIHandler(gui_handler);
436 }
437 cards.push_back(card);
438
439 card = new TutorialCard("1", "In the first tutorial you learnt how to design weapons.\nHere you'll be learning how to deploy and move your soldiers,\nso unarmed men will do.");
440 card->setPlayerAllowBuildTower(false);
441 card->setGUIHandler(new GUIHandlerBlockAll());
442 cards.push_back(card);
443
444 card = new TutorialCard("2", "Click to assemble some unarmed men.");
445 card->setPlayerAllowBuildTower(false);
446 card->setArrow(15, 145);
447 {
448 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
449 gui_handler->addException("button_deploy_unarmedmen");
450 gui_handler->addException("button_deploy_attackers_0");
451 gui_handler->addException("button_deploy_attackers_1");
452 gui_handler->addException("button_deploy_attackers_2");
453 gui_handler->addException("button_deploy_attackers_3");
454 gui_handler->addException("button_return_attackers");
455 card->setGUIHandler(gui_handler);
456 }
457 cards.push_back(card);
458
459 card = new TutorialCard("3", "Note that if you make a mistake assembling your army,\nyou can cancel by clicking the shield and sword icon at the bottom.");
460 card->setPlayerAllowBuildTower(false);
461 card->setArrow(87, 195);
462 {
463 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
464 gui_handler->addException("button_deploy_unarmedmen");
465 gui_handler->addException("button_deploy_attackers_0");
466 gui_handler->addException("button_deploy_attackers_1");
467 gui_handler->addException("button_deploy_attackers_2");
468 gui_handler->addException("button_deploy_attackers_3");
469 gui_handler->addException("button_return_attackers");
470 card->setGUIHandler(gui_handler);
471 }
472 cards.push_back(card);
473
474 card = new TutorialCardWaitForDeployedArmy("4", "Assemble some unarmed men, and send them to a\nsector by clicking on a new map square of your choice.", start_sector, false);
475 card->setPlayerAllowBuildTower(false);
476 static_cast<TutorialCardWaitForDeployedArmy *>(card)->setInverse(true);
477 card->setArrow(60, 70);
478 card->setArrowShowPage((int)GamePanel::STATE_ATTACK);
479 {
480 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
481 gui_handler->addException("button_deploy_unarmedmen");
482 gui_handler->addException("button_deploy_attackers_0");
483 gui_handler->addException("button_deploy_attackers_1");
484 gui_handler->addException("button_deploy_attackers_2");
485 gui_handler->addException("button_deploy_attackers_3");
486 gui_handler->addException("button_return_attackers");
487 gui_handler->addException("button_attack");
488 for(int y=0;y<map_height_c;y++) {
489 for(int x=0;x<map_width_c;x++) {
490 // enable the current square too, as we need to allow getting back if the user clicks another square without an assembled army!
491 if( game_g->getMap()->isSectorAt(x, y) ) {
492 char buffer[256] = "";
493 sprintf(buffer, "map_%d_%d", x, y);
494 gui_handler->addException(buffer);
495 }
496 }
497 }
498 card->setGUIHandler(gui_handler);
499 }
500 cards.push_back(card);
501
502 if( game_g->isOneMouseButton() ) {
503 card = new TutorialCard("5", "Now see if you can return them to the home sector.\nYou can select an army by clicking\non the main area to the right of the map.");
504 }
505 else {
506 card = new TutorialCard("5", "Now see if you can return them to the home sector.\nYou can select an army by right clicking,\neither on the current map square,\nor right clicking on the main area to the right.");
507 }
508 card->setPlayerAllowBuildTower(false);
509 cards.push_back(card);
510
511 card = new TutorialCardWaitForDeployedArmy("6", "When the army is selected, the shield icon will show,\nor a bloody sword icon if retreating from an enemy sector.\nMove the army back home by clicking on the square of your sector", start_sector, false);
512 card->setPlayerAllowBuildTower(false);
513 card->setArrow(47, 54);
514 cards.push_back(card);
515
516 // return back home
517
518 if( game_g->isOneMouseButton() ) {
519 card = new TutorialCardWaitForDeployedArmy("7", "Now let's return our men back to the tower.\nClick to select the army as before, then\nclick on your tower.", NULL, false);
520 }
521 else {
522 card = new TutorialCardWaitForDeployedArmy("7", "Now let's return our men back to the tower.\nRight click to select the army as before, then\nleft click on your tower.", NULL, false);
523 }
524 static_cast<TutorialCardWaitForDeployedArmy *>(card)->setInverse(true);
525 static_cast<TutorialCardWaitForDeployedArmy *>(card)->setRequireEmpty(true);
526 card->setPlayerAllowBuildTower(false);
527 card->setArrow(260, 80);
528 card->setArrowShowSector(start_map_x, start_map_y);
529 cards.push_back(card);
530
531 // build new tower
532
533 card = new TutorialCard("8", "So far you've only had a single tower,\nbut you can build new towers.");
534 card->setPlayerAllowBuildTower(false);
535 cards.push_back(card);
536
537 card = new TutorialCard("9", "Each tower can act independently, researching and\nconstructing different weapons.\nEach tower needs to invent its own weapons.");
538 card->setPlayerAllowBuildTower(false);
539 cards.push_back(card);
540
541 card = new TutorialCardWaitForDeployedArmy("10", "Assemble some unarmed men again, and this time\nsend them to a square that isn't occupied by the enemy", start_sector, false);
542 static_cast<TutorialCardWaitForDeployedArmy *>(card)->setInverse(true);
543 static_cast<TutorialCardWaitForDeployedArmy *>(card)->setRequireUnoccupied(true);
544 cards.push_back(card);
545
546 card = new TutorialCardWaitForNewTower("11", "Now sit back and wait until your new tower is constructed.\nRemember to speed up the rate of time if you want.", start_sector);
547 static_cast<TutorialCardWaitForNewTower *>(card)->setInverse(true);
548 cards.push_back(card);
549
550 card = new TutorialCard("12", "You have completed this tutorial!");
551 cards.push_back(card);
552
553 // for debugging
554 //this->card_index = 5;
555 }
556
Tutorial3(const string & id)557 Tutorial3::Tutorial3(const string &id) : Tutorial(id) {
558 start_epoch = 3;
559 island = 1;
560 start_map_x = 3;
561 start_map_y = 3;
562 n_men = 50;
563 //auto_end = true;
564 ai_allow_growth = false;
565 ai_allow_design = false;
566 ai_allow_ask_alliance = false;
567 ai_allow_deploy = false;
568 //allow_retreat_loss = false;
569 }
570
initCards()571 void Tutorial3::initCards() {
572 Sector *start_sector = game_g->getMap()->getSector(start_map_x, start_map_y);
573 ASSERT(start_sector != NULL);
574
575 TutorialCard *card = NULL;
576
577 card = new TutorialCard("0", "We're now thousands of years into the future since the last tutorial.\nIn this tutorial, you'll learn how to make use of newer technology\nto build weapons to destroy your enemies!");
578 card->setGUIHandler(new GUIHandlerBlockAll());
579 cards.push_back(card);
580
581 card = new TutorialCardWaitForPanelPage("1", "From the fourth age onwards, you can construct an additional building\nin your sector - a mine.\nSelect the pickaxe icon at the bottom left to build a mine.", (int)GamePanel::STATE_BUILD);
582 card->setArrow(25, 210);
583 {
584 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
585 gui_handler->addException("button_build_mine");
586 card->setGUIHandler(gui_handler);
587 }
588 cards.push_back(card);
589
590 card = new TutorialCardWaitForBuilding("2", "Assign some men to start building a mine, and then\nwait for it to be constructed.", start_sector, BUILDING_MINE);
591 card->setArrow(60, 130);
592 {
593 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
594 gui_handler->addException("button_nbuilders2_mine");
595 card->setGUIHandler(gui_handler);
596 }
597 cards.push_back(card);
598
599 card = new TutorialCardWaitForPanelPage("3", "Now click the bricks icon to go back to the main interface.", (int)GamePanel::STATE_SECTORCONTROL);
600 {
601 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
602 gui_handler->addException("button_bigbuild");
603 card->setGUIHandler(gui_handler);
604 }
605 card->setArrow(50, 110);
606 cards.push_back(card);
607
608 card = new TutorialCardWaitForPanelPage("4", "Your mine can extract elements from the ground, in order to\ncreate new inventions. To do this, click on any of the elements.", (int)GamePanel::STATE_ELEMENTSTOCKS);
609 card->setArrow(45, 185);
610 {
611 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
612 gui_handler->addException("button_elements_0");
613 gui_handler->addException("button_elements_1");
614 gui_handler->addException("button_elements_2");
615 gui_handler->addException("button_elements_3");
616 card->setGUIHandler(gui_handler);
617 }
618 cards.push_back(card);
619
620 card = new TutorialCard("5", "This page shows you the sector's current element stocks.\nSo far you've worked with gatherables, that your men automatically\npick up, without the need for a mine.");
621 card->setGUIHandler(new GUIHandlerBlockAll());
622 card->setArrow(80, 150);
623 cards.push_back(card);
624
625 card = new TutorialCard("6", "But more advanced elements require you to assign miners to them.\nClick on the 0 number to add some miners now, and wait\nuntil we have at least 1 unit.\nOnly use a few of your men for this.");
626 {
627 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
628 gui_handler->addException("button_nminers2_0");
629 gui_handler->addException("button_nminers2_1");
630 gui_handler->addException("button_nminers2_2");
631 gui_handler->addException("button_nminers2_3");
632 card->setGUIHandler(gui_handler);
633 }
634 card->setArrow(52, 183);
635 cards.push_back(card);
636
637 card = new TutorialCardWaitForPanelPage("7", "Now click the pickaxe icon to go back to the main screen.", (int)GamePanel::STATE_SECTORCONTROL);
638 {
639 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
640 gui_handler->addException("button_nminers2_0");
641 gui_handler->addException("button_nminers2_1");
642 gui_handler->addException("button_nminers2_2");
643 gui_handler->addException("button_nminers2_3");
644 gui_handler->addException("button_bigelementstocks");
645 card->setGUIHandler(gui_handler);
646 }
647 card->setArrow(50, 110);
648 cards.push_back(card);
649
650 card = new TutorialCardWaitForPanelPage("8", "Now let's design a weapon!\nClick on the lightbulb icon to start researching.", (int)GamePanel::STATE_DESIGN);
651 card->setArrow(36, 156);
652 card->setArrowShowPage((int)GamePanel::STATE_SECTORCONTROL);
653 {
654 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
655 gui_handler->addException("button_elements_0");
656 gui_handler->addException("button_elements_1");
657 gui_handler->addException("button_elements_2");
658 gui_handler->addException("button_elements_3");
659 gui_handler->addException("button_nminers2_0");
660 gui_handler->addException("button_nminers2_1");
661 gui_handler->addException("button_nminers2_2");
662 gui_handler->addException("button_nminers2_3");
663 gui_handler->addException("button_bigelementstocks");
664 gui_handler->addException("button_design");
665 card->setGUIHandler(gui_handler);
666 }
667 cards.push_back(card);
668
669 card = new TutorialCardWaitForDesign("9", "First, design a longbow", start_sector, TutorialCardWaitForDesign::WAITTYPE_HAS_DESIGNED, true, Invention::WEAPON, true, 3);
670 card->setArrow(90, 168);
671 card->setArrowShowPage((int)GamePanel::STATE_DESIGN);
672 {
673 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
674 gui_handler->addException("button_elements_0");
675 gui_handler->addException("button_elements_1");
676 gui_handler->addException("button_elements_2");
677 gui_handler->addException("button_elements_3");
678 gui_handler->addException("button_nminers2_0");
679 gui_handler->addException("button_nminers2_1");
680 gui_handler->addException("button_nminers2_2");
681 gui_handler->addException("button_nminers2_3");
682 gui_handler->addException("button_bigelementstocks");
683 gui_handler->addException("button_design");
684 gui_handler->addException("button_bigdesign");
685 gui_handler->addException("button_weapons_0");
686 gui_handler->addException("button_designers");
687 card->setGUIHandler(gui_handler);
688 }
689 cards.push_back(card);
690
691 card = new TutorialCardWaitForDesign("10", "Now design a trebuchet", start_sector, TutorialCardWaitForDesign::WAITTYPE_HAS_DESIGNED, true, Invention::WEAPON, true, 4);
692 card->setArrow(90, 188);
693 card->setArrowShowPage((int)GamePanel::STATE_DESIGN);
694 {
695 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
696 gui_handler->addException("button_elements_0");
697 gui_handler->addException("button_elements_1");
698 gui_handler->addException("button_elements_2");
699 gui_handler->addException("button_elements_3");
700 gui_handler->addException("button_nminers2_0");
701 gui_handler->addException("button_nminers2_1");
702 gui_handler->addException("button_nminers2_2");
703 gui_handler->addException("button_nminers2_3");
704 gui_handler->addException("button_bigelementstocks");
705 gui_handler->addException("button_design");
706 gui_handler->addException("button_bigdesign");
707 gui_handler->addException("button_weapons_1");
708 gui_handler->addException("button_designers");
709 card->setGUIHandler(gui_handler);
710 }
711 cards.push_back(card);
712
713 card = new TutorialCardWaitForPanelPage("11", "Now click the lightbulb icon to go back to the main screen.", (int)GamePanel::STATE_SECTORCONTROL);
714 card->setArrow(50, 110);
715 card->setArrowShowPage((int)GamePanel::STATE_DESIGN);
716 {
717 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
718 gui_handler->addException("button_elements_0");
719 gui_handler->addException("button_elements_1");
720 gui_handler->addException("button_elements_2");
721 gui_handler->addException("button_elements_3");
722 gui_handler->addException("button_nminers2_0");
723 gui_handler->addException("button_nminers2_1");
724 gui_handler->addException("button_nminers2_2");
725 gui_handler->addException("button_nminers2_3");
726 gui_handler->addException("button_bigelementstocks");
727 gui_handler->addException("button_bigdesign");
728 card->setGUIHandler(gui_handler);
729 }
730 cards.push_back(card);
731
732 card = new TutorialCardWaitForPanelPage("12", "As a result of your two inventions, we've moved forward to a new age.\nThis means we can build a factory, which is necessary to construct\ntrebuchets. Click the factory icon at the bottom to build a factory.", (int)GamePanel::STATE_BUILD);
733 card->setArrow(45, 210);
734 card->setArrowShowPage((int)GamePanel::STATE_SECTORCONTROL);
735 {
736 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
737 gui_handler->addException("button_elements_0");
738 gui_handler->addException("button_elements_1");
739 gui_handler->addException("button_elements_2");
740 gui_handler->addException("button_elements_3");
741 gui_handler->addException("button_nminers2_0");
742 gui_handler->addException("button_nminers2_1");
743 gui_handler->addException("button_nminers2_2");
744 gui_handler->addException("button_nminers2_3");
745 gui_handler->addException("button_bigelementstocks");
746 gui_handler->addException("button_build_factory");
747 card->setGUIHandler(gui_handler);
748 }
749 cards.push_back(card);
750
751 card = new TutorialCardWaitForBuilding("13", "Now assign some men to build a factory, as you did with the mine,\nand wait for it to be constructed.", start_sector, BUILDING_FACTORY);
752 card->setArrow(60, 160);
753 card->setArrowShowPage((int)GamePanel::STATE_BUILD);
754 {
755 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
756 gui_handler->addException("button_elements_0");
757 gui_handler->addException("button_elements_1");
758 gui_handler->addException("button_elements_2");
759 gui_handler->addException("button_elements_3");
760 gui_handler->addException("button_nminers2_0");
761 gui_handler->addException("button_nminers2_1");
762 gui_handler->addException("button_nminers2_2");
763 gui_handler->addException("button_nminers2_3");
764 gui_handler->addException("button_bigelementstocks");
765 gui_handler->addException("button_build_factory");
766 gui_handler->addException("button_bigbuild");
767 gui_handler->addException("button_nbuilders2_factory");
768 card->setGUIHandler(gui_handler);
769 }
770 cards.push_back(card);
771
772 card = new TutorialCardWaitForPanelPage("14", "Now click the bricks icon to go back to the main interface.", (int)GamePanel::STATE_SECTORCONTROL);
773 {
774 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
775 gui_handler->addException("button_elements_0");
776 gui_handler->addException("button_elements_1");
777 gui_handler->addException("button_elements_2");
778 gui_handler->addException("button_elements_3");
779 gui_handler->addException("button_nminers2_0");
780 gui_handler->addException("button_nminers2_1");
781 gui_handler->addException("button_nminers2_2");
782 gui_handler->addException("button_nminers2_3");
783 gui_handler->addException("button_bigelementstocks");
784 gui_handler->addException("button_bigbuild");
785 card->setGUIHandler(gui_handler);
786 }
787 card->setArrow(50, 110);
788 cards.push_back(card);
789
790 card = new TutorialCardWaitForPanelPage("15", "Click on the factory icon to start manufacturing.", (int)GamePanel::STATE_FACTORY);
791 card->setArrow(65, 156);
792 card->setArrowShowPage((int)GamePanel::STATE_SECTORCONTROL);
793 {
794 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
795 gui_handler->addException("button_elements_0");
796 gui_handler->addException("button_elements_1");
797 gui_handler->addException("button_elements_2");
798 gui_handler->addException("button_elements_3");
799 gui_handler->addException("button_nminers2_0");
800 gui_handler->addException("button_nminers2_1");
801 gui_handler->addException("button_nminers2_2");
802 gui_handler->addException("button_nminers2_3");
803 gui_handler->addException("button_bigelementstocks");
804 gui_handler->addException("button_factory");
805 card->setGUIHandler(gui_handler);
806 }
807 cards.push_back(card);
808
809 card = new TutorialCardWaitForDesign("16", "Select the trebuchet to start manufacturing", start_sector, TutorialCardWaitForDesign::WAITTYPE_CURRENT_MANUFACTURE, true, Invention::WEAPON, false, -1);
810 card->setArrow(90, 205);
811 card->setArrowShowPage((int)GamePanel::STATE_FACTORY);
812 {
813 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
814 gui_handler->addException("button_elements_0");
815 gui_handler->addException("button_elements_1");
816 gui_handler->addException("button_elements_2");
817 gui_handler->addException("button_elements_3");
818 gui_handler->addException("button_nminers2_0");
819 gui_handler->addException("button_nminers2_1");
820 gui_handler->addException("button_nminers2_2");
821 gui_handler->addException("button_nminers2_3");
822 gui_handler->addException("button_bigelementstocks");
823 gui_handler->addException("button_factory");
824 gui_handler->addException("button_bigfactory");
825 gui_handler->addException("button_fweapons_1");
826 card->setGUIHandler(gui_handler);
827 }
828 cards.push_back(card);
829
830 card = new TutorialCardWaitForDesign("17", "The top number shows the assigned number of workers,\nthe bottom shows the number of trebuchets to be manufactured.\nAssign workers by increasing the top number, then wait!", start_sector, TutorialCardWaitForDesign::WAITTYPE_HAS_MANUFACTURED, true, Invention::WEAPON, false, -1);
831 card->setArrow(90, 135);
832 card->setArrowShowPage((int)GamePanel::STATE_FACTORY);
833 {
834 GUIHandlerBlockAll *gui_handler = new GUIHandlerBlockAll();
835 gui_handler->addException("button_elements_0");
836 gui_handler->addException("button_elements_1");
837 gui_handler->addException("button_elements_2");
838 gui_handler->addException("button_elements_3");
839 gui_handler->addException("button_nminers2_0");
840 gui_handler->addException("button_nminers2_1");
841 gui_handler->addException("button_nminers2_2");
842 gui_handler->addException("button_nminers2_3");
843 gui_handler->addException("button_bigelementstocks");
844 gui_handler->addException("button_factory");
845 gui_handler->addException("button_bigfactory");
846 gui_handler->addException("button_fweapons_1");
847 gui_handler->addException("button_workers");
848 gui_handler->addException("button_famount");
849 card->setGUIHandler(gui_handler);
850 }
851 cards.push_back(card);
852
853 card = new TutorialCard("18", "You now have your first trebchet! Now manufacture some more,\nand use them to defeat your enemies. Good luck!");
854 card->setNextText("Done");
855 cards.push_back(card);
856 }
857