1 #pragma once
2 
3 /** Classes to handle the Tutorials.
4 */
5 
6 using std::vector;
7 using std::string;
8 
9 class PlayingGameState;
10 class Tutorial;
11 
12 #include "sector.h"
13 
14 class TutorialInfo {
15 public:
16 	string id;
17 	string text;
18 
TutorialInfo(const string & id,const string & text)19 	TutorialInfo(const string &id, const string &text) : id(id), text(text) {
20 	}
21 };
22 
23 class TutorialManager {
24 public:
25 	static vector<TutorialInfo> getTutorialInfo();
26 	static Tutorial *setupTutorial(const string &id);
27 };
28 
29 class GUIHandler {
30 public:
setGUI(PlayingGameState * playing_gamestate)31 	virtual void setGUI(PlayingGameState *playing_gamestate) const {
32 	}
~GUIHandler()33 	virtual ~GUIHandler() {
34 		// need a virtual destructor even though it doesn't do anything, to ensure that subclass destructors are called (see warning on Linux GCC)
35 	}
36 
37 	static void resetGUI(PlayingGameState *playing_gamestate);
38 };
39 
40 class GUIHandlerBlockAll : public GUIHandler {
41 	vector<string> exceptions;
42 public:
43 	virtual void setGUI(PlayingGameState *playing_gamestate) const;
addException(const string & exception)44 	void addException(const string &exception) {
45 		exceptions.push_back(exception);
46 	}
47 };
48 
49 class TutorialCard {
50 	string id;
51 	string text;
52 	string next_text;
53 	bool has_arrow;
54 	int arrow_x, arrow_y;
55 	bool show_arrow_on_page;
56 	int show_arrow_page;
57 	bool show_arrow_on_sector;
58 	int show_arrow_sector_x;
59 	int show_arrow_sector_y;
60 	bool auto_proceed;
61 
62 	bool player_allow_build_tower;
63 
64 	GUIHandler *gui_handler;
65 public:
TutorialCard(const string & id,const string & text)66 	TutorialCard(const string &id, const string &text) : id(id), text(text), next_text("Next"), has_arrow(false), arrow_x(-1), arrow_y(-1), show_arrow_on_page(false), show_arrow_page(-1), show_arrow_on_sector(false), show_arrow_sector_x(-1), show_arrow_sector_y(-1), auto_proceed(false), player_allow_build_tower(true), gui_handler(NULL) {
67 	}
~TutorialCard()68 	virtual ~TutorialCard() {
69 		if( gui_handler != NULL ) {
70 			delete gui_handler;
71 		}
72 	}
73 
getId()74 	string getId() const {
75 		return id;
76 	}
getText()77 	string getText() const {
78 		return text;
79 	}
80 
setNextText(const string & next_text)81 	void setNextText(const string &next_text) {
82 		this->next_text = next_text;
83 	}
getNextText()84 	string getNextText() const {
85 		return next_text;
86 	}
87 
setArrow(int arrow_x,int arrow_y)88 	void setArrow(int arrow_x, int arrow_y) {
89 		this->has_arrow = true;
90 		this->arrow_x = arrow_x;
91 		this->arrow_y = arrow_y;
92 	}
setArrowShowPage(int show_arrow_page)93 	void setArrowShowPage(int show_arrow_page) {
94 		this->show_arrow_on_page = true;
95 		this->show_arrow_page = show_arrow_page;
96 	}
setArrowShowSector(int show_arrow_sector_x,int show_arrow_sector_y)97 	void setArrowShowSector(int show_arrow_sector_x, int show_arrow_sector_y) {
98 		this->show_arrow_on_sector = true;
99 		this->show_arrow_sector_x = show_arrow_sector_x;
100 		this->show_arrow_sector_y = show_arrow_sector_y;
101 	}
102 	bool hasArrow(PlayingGameState *playing_gamestate) const;
getArrowX()103 	int getArrowX() const {
104 		return arrow_x;
105 	}
getArrowY()106 	int getArrowY() const {
107 		return arrow_y;
108 	}
109 
setAutoProceed(bool auto_proceed)110 	void setAutoProceed(bool auto_proceed) {
111 		this->auto_proceed = auto_proceed;
112 	}
autoProceed()113 	bool autoProceed() const {
114 		return auto_proceed;
115 	}
116 
canProceed(PlayingGameState * playing_gamestate)117 	virtual bool canProceed(PlayingGameState *playing_gamestate) const {
118 		return true;
119 	}
120 
setPlayerAllowBuildTower(bool player_allow_build_tower)121 	void setPlayerAllowBuildTower(bool player_allow_build_tower) {
122 		this->player_allow_build_tower = player_allow_build_tower;
123 	}
playerAllowBuildTower()124 	bool playerAllowBuildTower() const {
125 		return player_allow_build_tower;
126 	}
127 	virtual void setGUI(PlayingGameState *playing_gamestate) const;
setGUIHandler(GUIHandler * gui_handler)128 	void setGUIHandler(GUIHandler *gui_handler) {
129 		this->gui_handler = gui_handler;
130 	}
131 };
132 
133 class TutorialCardWaitForPanelPage : public TutorialCard {
134 	int wait_page;
135 public:
TutorialCardWaitForPanelPage(const string & id,const string & text,int wait_page)136 	TutorialCardWaitForPanelPage(const string &id, const string &text, int wait_page) : TutorialCard(id, text), wait_page(wait_page) {
137 		this->setAutoProceed(true);
138 	}
139 
140 	virtual bool canProceed(PlayingGameState *playing_gamestate) const;
141 };
142 
143 class TutorialCardWaitForDesign : public TutorialCard {
144 public:
145 	enum WaitType {
146 		WAITTYPE_CURRENT_DESIGN = 0,
147 		WAITTYPE_HAS_DESIGNED = 1,
148 		WAITTYPE_CURRENT_MANUFACTURE = 2,
149 		WAITTYPE_HAS_MANUFACTURED = 3
150 	};
151 private:
152 	const Sector *sector;
153 	WaitType wait_type;
154 	bool require_type;
155 	Invention::Type invention_type;
156 	bool require_epoch;
157 	int invention_epoch;
158 public:
TutorialCardWaitForDesign(const string & id,const string & text,const Sector * sector,WaitType wait_type,bool require_type,Invention::Type invention_type,bool require_epoch,int invention_epoch)159 	TutorialCardWaitForDesign(const string &id, const string &text, const Sector *sector, WaitType wait_type, bool require_type, Invention::Type invention_type, bool require_epoch, int invention_epoch) : TutorialCard(id, text), sector(sector), wait_type(wait_type), require_type(require_type), invention_type(invention_type), require_epoch(require_epoch), invention_epoch(invention_epoch) {
160 		this->setAutoProceed(true);
161 	}
162 
163 	virtual bool canProceed(PlayingGameState *playing_gamestate) const;
164 };
165 
166 class TutorialCardWaitForBuilding : public TutorialCard {
167 	const Sector *sector;
168 	Type building_type;
169 public:
TutorialCardWaitForBuilding(const string & id,const string & text,const Sector * sector,Type building_type)170 	TutorialCardWaitForBuilding(const string &id, const string &text, const Sector *sector, Type building_type) : TutorialCard(id, text), sector(sector), building_type(building_type) {
171 		this->setAutoProceed(true);
172 	}
173 
174 	virtual bool canProceed(PlayingGameState *playing_gamestate) const;
175 };
176 
177 class TutorialCardWaitForDeployedArmy : public TutorialCard {
178 	Sector *deploy_sector;
179 	bool require_bombard;
180 	bool inverse; // if true, wait until an army is deployed anywhere other than deploy_sector (or anywhere, if deploy_sector is NULL)
181 	bool require_empty; // if true, check the square(s) is empty instead
182 	bool require_unoccupied; // if true, require that the square is not occupied by a player's tower
183 public:
TutorialCardWaitForDeployedArmy(const string & id,const string & text,Sector * deploy_sector,bool require_bombard)184 	TutorialCardWaitForDeployedArmy(const string &id, const string &text, Sector *deploy_sector, bool require_bombard) : TutorialCard(id, text), deploy_sector(deploy_sector), require_bombard(require_bombard), inverse(false), require_empty(false), require_unoccupied(false) {
185 		this->setAutoProceed(true);
186 	}
187 
setInverse(bool inverse)188 	void setInverse(bool inverse) {
189 		this->inverse = inverse;
190 	}
setRequireEmpty(bool require_empty)191 	void setRequireEmpty(bool require_empty) {
192 		this->require_empty = require_empty;
193 	}
setRequireUnoccupied(bool require_unoccupied)194 	void setRequireUnoccupied(bool require_unoccupied) {
195 		this->require_unoccupied = require_unoccupied;
196 	}
197 
198 	virtual bool canProceed(PlayingGameState *playing_gamestate) const;
199 };
200 
201 class TutorialCardWaitForNewTower : public TutorialCard {
202 	Sector *tower_sector;
203 	bool inverse; // if true, wait until a tower is built anywhere other than tower_sector (or anywhere, if tower_sector is NULL)
204 public:
TutorialCardWaitForNewTower(const string & id,const string & text,Sector * tower_sector)205 	TutorialCardWaitForNewTower(const string &id, const string &text, Sector *tower_sector) : TutorialCard(id, text), tower_sector(tower_sector), inverse(false)  {
206 		this->setAutoProceed(true);
207 	}
208 
setInverse(bool inverse)209 	void setInverse(bool inverse) {
210 		this->inverse = inverse;
211 	}
212 
213 	virtual bool canProceed(PlayingGameState *playing_gamestate) const;
214 };
215 
216 class Tutorial {
217 protected:
218 	string id;
219 	int start_epoch;
220 	int island;
221 	int start_map_x, start_map_y;
222 	int n_men;
223 	bool auto_end;
224 	size_t card_index;
225 	vector<TutorialCard *> cards;
226 	bool ai_allow_growth;
227 	bool ai_allow_design;
228 	bool ai_allow_ask_alliance;
229 	bool ai_allow_deploy;
230 	bool allow_retreat_loss;
231 
232 public:
Tutorial(const string & id)233 	Tutorial(const string &id) : id(id), start_epoch(0), island(0), start_map_x(0), start_map_y(0), n_men(0), auto_end(false), card_index(0), ai_allow_growth(true), ai_allow_design(true), ai_allow_ask_alliance(true), ai_allow_deploy(true), allow_retreat_loss(true) {
234 	}
235 	virtual ~Tutorial();
236 
getId()237 	string getId() const {
238 		return id;
239 	}
getStartEpoch()240 	int getStartEpoch() const {
241 		return start_epoch;
242 	}
getIsland()243 	int getIsland() const {
244 		return island;
245 	}
getStartMapX()246 	int getStartMapX() const {
247 		return start_map_x;
248 	}
getStartMapY()249 	int getStartMapY() const {
250 		return start_map_y;
251 	}
getNMen()252 	int getNMen() const {
253 		return n_men;
254 	}
aiAllowGrowth()255 	bool aiAllowGrowth() const {
256 		return ai_allow_growth;
257 	}
aiAllowDesign()258 	bool aiAllowDesign() const {
259 		return ai_allow_design;
260 	}
aiAllowAskAlliance()261 	bool aiAllowAskAlliance() const {
262 		return ai_allow_ask_alliance;
263 	}
aiAllowDeploy()264 	bool aiAllowDeploy() const {
265 		return ai_allow_deploy;
266 	}
allowRetreatLoss()267 	bool allowRetreatLoss() const {
268 		return allow_retreat_loss;
269 	}
getCard()270 	const TutorialCard *getCard() const {
271 		if( card_index >= cards.size() )
272 			return NULL;
273 		return cards.at(card_index);
274 	}
proceed()275 	void proceed() {
276 		card_index++;
277 	}
278 	bool jumpTo(const string &id);
jumpToEnd()279 	void jumpToEnd() {
280 		card_index = cards.size();
281 	}
autoEnd()282 	bool autoEnd() const {
283 		return auto_end;
284 	}
285 
286 	virtual void initCards()=0;
287 };
288 
289 class Tutorial1 : public Tutorial {
290 public:
291 	Tutorial1(const string &id);
292 
293 	virtual void initCards();
294 };
295 
296 class Tutorial2 : public Tutorial {
297 public:
298 	Tutorial2(const string &id);
299 
300 	virtual void initCards();
301 };
302 
303 class Tutorial3 : public Tutorial {
304 public:
305 	Tutorial3(const string &id);
306 
307 	virtual void initCards();
308 };
309