1 // Copyright (C) 2003, 2005 Ulf Lorenz
2 // Copyright (C) 2004 Andrea Paternesi
3 // Copyright (C) 2007, 2008, 2009, 2014 Ben Asselstine
4 // Copyright (C) 2007, 2008 Ole Laursen
5 //
6 //  This program is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 3 of the License, or
9 //  (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU Library General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 //  02110-1301, USA.
20 
21 #pragma once
22 #ifndef QUEST_MANAGER_H
23 #define QUEST_MANAGER_H
24 
25 #include <queue>
26 #include <map>
27 #include <vector>
28 #include <sigc++/trackable.h>
29 #include <sigc++/signal.h>
30 #include "callback-enums.h"
31 
32 #include "player.h"
33 
34 class Quest;
35 class XML_Helper;
36 class Army;
37 class Reward;
38 
39 
40 //! Manages Quest objects.
41 /**
42  * This class creates new quests and assigns them to heroes.  It also keeps
43  * track of pending quests and invalidates quests due to Hero death.  It
44  * acts as a central place to catch army death events, and city conquered
45  * events, and it passes these events on to the Quest objects it manages.
46  *
47  * This object equates to the lordsawar.questlist XML entity in the saved-game
48  * file.
49  *
50  * This class is implemented as a singleton.
51  *
52  */
53 class QuestsManager : public sigc::trackable
54 {
55     public:
56 
57 	//! The xml tag of this object in a saved-game file.
58 	static Glib::ustring d_tag;
59 
60 	// Methods that operate on the class data and modify it.
61 
62 	//! Create a new quest for the given hero.
63 	/**
64 	 * Check and see which quests are possible and give the specified hero
65 	 * a random quest.
66 	 *
67 	 * @param heroId  The Id of the Hero object to be responsible for the
68 	 *                new Quest.
69 	 * @param razing_possible  Whether or not razing cities is allowed in
70 	 *                         the scenario.  If this is set to true, the
71 	 *                         quests that involve razing will be
72 	 *                         considered.  Otherwise a razing quest will
73 	 *                         not be considered at all, and not returned.
74 	 *
75 	 * @return A pointer to the new Quest object.
76 	 */
77         Quest* createNewQuest(guint32 heroId, bool razing_possible);
78 
79         //! Create new kill hero quest from remote action.
80 	Quest* createNewKillHeroQuest(guint32 heroId, guint32 targetHeroId);
81 
82         //! Create new enemy armies quest from remote action.
83 	Quest* createNewEnemyArmiesQuest(guint32 heroId, guint32 num_armies,
84 					 guint32 victim_player_id);
85 
86         //! Create new city sacking quest from remote action.
87 	Quest* createNewCitySackQuest(guint32 heroId, guint32 cityId);
88 
89         //! Create new city razing quest from remote action.
90 	Quest* createNewCityRazeQuest(guint32 heroId, guint32 cityId);
91 
92         //! Create new city occupation quest from remote action.
93 	Quest* createNewCityOccupyQuest(guint32 heroId, guint32 cityId);
94 
95         //! Create new kill enemy army type quest from remote action.
96 	Quest* createNewEnemyArmytypeQuest(guint32 heroId, guint32 armyTypeId);
97 
98         //! Create new pillage gold quest from remote action.
99 	Quest* createNewPillageGoldQuest(guint32 heroId, guint32 amount);
100 
101 	//! Mark the Quest that the given Hero object is on to be completed.
102         /**
103          *  This method deactivates the quest and saves the completion
104 	 *  notification message which will be presented to the player.
105 	 *
106 	 *  @param heroId  The id of the Hero object who has a Quest that we
107 	 *                 want to mark as complete.
108          */
109         void questCompleted(guint32 heroId);
110 
111 	//! Mark the Quest that the given Hero object is on to be expired.
112         /**
113          *  This method deactivates the quest and saves the expiry notification
114          *  message which will be presented to the player.
115 	 *
116 	 *  @param heroId  The id of the Hero object who has a Quest that we
117 	 *                 want to mark as expired.
118          */
119         void questExpired(guint32 heroId);
120 
121 	//! Callback when an Army object is killed.
122         /**
123          *  Here we account for a dead army.   maybe it's our hero,
124 	 *  maybe it's a target hero, maybe we're somebody else's target hero
125 	 *  or maybe we're some other army we're supposed to kill.
126 	 *
127 	 *  @param army      The army who was killed.
128 	 *  @param culprits  The list of Army object Ids that were involved in
129 	 *                   killing the given army.
130          */
131 	void armyDied(Army *army, std::vector<guint32>& culprits);
132 
133 	//! Callback when a city is razed.
134 	/**
135 	 * Other classes call this to trigger this razing event.  Derived
136 	 * classes of Quest catch this event via the Quest::cityAction
137 	 * callback.
138 	 *
139 	 * @param city   A pointer to the City object being razed.
140 	 * @param stack  A pointer to the stack that conquered and is razing
141 	 *               the given city.
142 	 */
143 	void cityRazed(City *city, Stack *stack);
144 
145 	//! Callback when a city is sacked.
146 	/**
147 	 * Other classes call this to trigger this sacking event.  Derived
148 	 * classes of Quest catch this event via the Quest::cityAction
149 	 * callback.
150 	 *
151 	 * @param city   A pointer to the City object being sacked.
152 	 * @param stack  A pointer to the stack that conquered and is sacking
153 	 *               the given city.
154 	 * @param gold   The number of gold pieces that the sacking resulted in.
155 	 */
156 	void citySacked(City *city, Stack *stack, int gold);
157 
158 	//! Callback when a city is pillaged.
159 	/**
160 	 * Other classes call this to trigger this pillaging event.  Derived
161 	 * classes of Quest catch this event via the Quest::cityAction
162 	 * callback.
163 	 *
164 	 * @param city   A pointer to the City object being pillaged.
165 	 * @param stack  A pointer to the stack that conquered and is pillaging
166 	 *               the given city.
167 	 * @param gold   The number of gold pieces that the pillaging resulted
168 	 *               in.
169 	 */
170 	void cityPillaged(City *city, Stack *stack, int gold);
171 
172 	//! Callback when a city is occupied.
173 	/**
174 	 * Other classes call this to trigger this occupying event.  Derived
175 	 * classes of Quest catch this event via the Quest::cityAction
176 	 * callback.
177 	 *
178 	 * @param city   A pointer to the City object being occupied.
179 	 * @param stack  A pointer to the stack that conquered and is occupying
180 	 *               the given city.
181 	 */
182 	void cityOccupied(City *city, Stack *stack);
183 
184 	//! Process the Quests at the start of every turn for the given player.
185 	/**
186 	 * @param player  The player to process Quest objects for.  The Hero
187 	 *                object must be owned by this player to be processed.
188 	 */
189 	void nextTurn(Player *player);
190 
191 
192 	// Methods that operate on the class data and do not modify it.
193 
194 	//! Return a list of active Quest objects that belong to the player.
195 	/**
196 	 * @param player  The player to get active Quest objects for.
197 	 */
198         std::vector<Quest*> getPlayerQuests(const Player *player) const;
199 
200         Quest* getHeroQuest(guint32 hero_id) const;
201 
202 	//! Save the quests to an opened saved-game file.
203 	/**
204 	 * Saves the lordsawar.questlist XML entity to the saved-game file.
205 	 *
206 	 * @param helper  The opened saved-game file to save the Quest objects
207 	 *                to.
208 	 */
209         bool save(XML_Helper* helper) const;
210 
211 
212 	// Signals
213 
214 	//! Emitted when a Hero object completes a Quest.
215 	/**
216 	 * @param quest   A pointer to the Quest object that was successfully
217 	 *                completed.
218 	 * @param reward  A pointer to the reward that the Hero is receiving.
219 	 */
220 	sigc::signal<void, Quest *, Reward *> quest_completed;
221 
222 	//! Emitted when a Hero object fails to complete a Quest.
223 	/**
224 	 * @param quest  A pointer to the Ques tobject that was expired.
225 	 */
226 	sigc::signal<void, Quest *> quest_expired;
227 
228 
229 	// Static Methods
230 
231         //! Gets the singleton instance or creates a new one.
232         static QuestsManager* getInstance();
233 
234 	/**
235 	 * Make a new QuestsManager object by loading all Quest objects from
236 	 * an opened saved-game file.
237 	 *
238 	 * @param helper     The opened saved-game file to read from.
239 	 *
240 	 * @return A pointer to the new QuestsManager object.
241 	 */
242         //! Loads the questlist from a saved-game file.
243         static QuestsManager* getInstance(XML_Helper* helper);
244 
245         //! Explicitly deletes the singleton instance.
246         static void deleteInstance();
247 
248     protected:
249 
250 	//! Default constructor.
251         QuestsManager();
252 
253 	//! Loading constructor.
254 	/**
255 	 * Loads the lordsawar.questlist XML entity from the saved-game file.
256 	 *
257 	 * @param helper  The opened saved-game file to load the questlist from.
258 	 */
259         QuestsManager(XML_Helper* helper);
260 
261 	//! Destructor.
262 	~QuestsManager();
263 
264     private:
265 
266 	//! Definition of a function pointer for the Quest::isFeasible methods.
267         typedef bool (*QFeasibilityType)(guint32);
268 
269 	//! Callback for loading Quest objects into the QuestsManager.
270         bool load(Glib::ustring tag, XML_Helper* helper);
271 
272         //! Does some setup that has to be done on loading as well as creation.
273         void sharedInit();
274 
275         //! Deactivates a given quest, i.e. marks it as 'to-delete'.
276 	/**
277 	 * @note A Hero can only have one quest, so giving the heroId is as
278 	 *       good as specifying a particular quest.
279 	 */
280         void deactivateQuest(guint32 heroId);
281 
282         //! This method performs cleanup of the marked quests
283 	/**
284 	 * Remove the quests marked as deactivated.
285 	 */
286         void cleanup();
287 
288 	//! Callback when a city is conquered.
289 	/**
290 	 * This method calls the other simlarly named methods in the derived
291 	 * Quest classes.
292 	 *
293 	 * @param city   A pointer to the city that was defeated.
294 	 * @param stack  A pointer to the stack doing the conquering.
295 	 * @param action What action was taken: pillaging, sacking, razing, or
296 	 *               occupying.
297 	 * @param gold   The number of gold pieces achieved in the sacking or
298 	 *               pillaging.
299 	 */
300 	void cityAction(City *c, Stack *s, CityDefeatedAction action, int gold);
301 
302 
303         std::vector<Quest*> getActiveQuests ();
304         // DATA
305 
306 	//! A hash of all Quests in this QuestsManager.  Lookup by HeroId.
307         std::map<guint32,Quest*> d_quests;
308 
309         //! A list of quests that have been marked as expiring
310         std::list<Quest*> d_inactive_quests;
311 
312         //! A list of quests that have been marked as completed
313         std::list<Quest*> d_completed_quests;
314 
315 	//! A vector of isFeasible function pointers.
316         /**
317 	 * This list of function pointers is used to see if it makes sense to
318 	 * give out a quest of a particular kind (Quest::Type).
319          */
320         std::vector<QFeasibilityType> d_questsFeasible;
321 
322         //! A static pointer for the singleton instance.
323         static QuestsManager * s_instance;
324 };
325 
326 #endif
327