1 //  Copyright (C) 2007-2009, 2011, 2014, 2015, 2017 Ben Asselstine
2 //
3 //  This program is free software; you can redistribute it and/or modify
4 //  it under the terms of the GNU General Public License as published by
5 //  the Free Software Foundation; either version 3 of the License, or
6 //  (at your option) any later version.
7 //
8 //  This program is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //  GNU Library General Public License for more details.
12 //
13 //  You should have received a copy of the GNU General Public License
14 //  along with this program; if not, write to the Free Software
15 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 //  02110-1301, USA.
17 
18 #pragma once
19 #ifndef REWARD_H
20 #define REWARD_H
21 
22 #include <gtkmm.h>
23 #include <glibmm.h>
24 #include "vector.h"
25 #include "ruinlist.h"
26 
27 class SightMap;
28 class Player;
29 class Army;
30 class ArmyProto;
31 class Location;
32 class Item;
33 class XML_Helper;
34 class Ruin;
35 class StackReflist;
36 
37 //! A little something nice for the Player.
38 /**
39  * Reward objects are given to the Player upon completion of a difficult
40  * task.  Rewards are awarded when a ruin is successfully searched, or when a
41  * Hero completes a Quest, or visits a sage.
42  *
43  * Rewards come in 5 flavours (Reward::Type): an amount of gold pieces, a
44  * number of powerful allies, a useful item, a map that exposes part of a
45  * hidden map when playing with fog-of-war, and also a hidden ruin that only
46  * that Player who is awarded the Reward can search.
47  *
48  * This is the base class for each of the different kinds of rewards.  It
49  * holds the kind of reward and the name of the reward.
50  *
51  */
52 class Reward
53 {
54     public:
55 
56 	//! The xml tag of this object in a saved-game file.
57 	static Glib::ustring d_tag;
58 
59 	//! The different kinds of Reward objects.
60         enum Type {
61 	  //! A number of gold pieces.
62 	  GOLD = 1,
63 	  //! A number of powerful allies.
64 	  ALLIES= 2,
65 	  //! A useful item.
66 	  ITEM = 3,
67 	  //! A hidden ruin that only the rewarded Player can see.
68 	  RUIN = 4,
69 	  //! A portion of the hidden map to expose to the rewarded player.
70 	  MAP = 5
71 	};
72 
73         //! Default constructor.
74 	/**
75 	 * Make a new constructor of the given type and name.
76 	 *
77 	 * @param type  The kind of reward.
78 	 * @param name  The name of the reward.
79 	 *
80 	 * @note This constructor is only used in the constructors of other
81 	 *       Reward objects, and shouldn't be called directly.
82 	 */
83         Reward(Type type, Glib::ustring name = "");
84 
85 	//! Loading constructor.
86 	/**
87 	 * Make a new Reward by reading it in from the opened saved-game file.
88 	 *
89 	 * @param helper  The opened saved-game file to read the Reward from.
90 	 *
91 	 * @note This constructor is only used within the constructors of
92 	 *       other Reward objects, and shouldn't be called directly.
93 	 *       It only loads the parts common to all Reward objects.
94 	 */
95         Reward(XML_Helper* helper);
96 
97 	//! Copy constructor.
98 	/**
99 	 * Make a new Reward by copying it from another Reward object.
100 	 *
101 	 * @param orig  The Reward object to copy it from.
102 	 *
103 	 * @note This constructor is only used within the constructors of
104 	 *       other Reward objects, and shouldn't be called directly.
105 	 *       It only copies the parts common to all Reward objects.
106 	 */
107         Reward (const Reward& orig);
108 
109 	//! Destructor.
~Reward()110         virtual ~Reward() {};
111 
112 
113 	// Get Methods
114 
115         //! Get the type of the reward.
getType()116         Type getType() const { return d_type; }
117 
118         //! Returns the name of the reward.
getName()119         Glib::ustring getName() const {return d_name;}
120 
121 
122 	// Set Methods
123 
124 	//! Sets the name of the reward.
setName(Glib::ustring name)125 	void setName(Glib::ustring name) {d_name = name;}
126 
127 
128 	// Methods that operate on the class data but do not modify the class.
129 
130 	//! Generates a description of this reward.
131 	/**
132 	 * This method inspects the underlying reward and generates an
133 	 * appropriate description.
134 	 */
135 	Glib::ustring getDescription() const;
136 
137 	//! Saves the data elements common to all rewards.
138         /**
139          * @note This function is called by the actual reward and only saves
140          * the common data. It does NOT open/close tags etc. This has to be
141          * done by the derived classes.
142 	 *
143 	 * @param helper  The opened saved-game file to save the Reward object
144 	 *                to.
145          */
146         virtual bool save(XML_Helper* helper) const = 0;
147 
148 
149 	// Static Methods
150 
151 	//! Assist in the loading of Rewards of all kinds.
152         /**
153          * Whenever an reward item is loaded, this function is called. It
154          * examines the stored id and calls the constructor of the appropriate
155          * reward class.
156          *
157          * @param helper   The opened saved-game file to load the Reward from.
158          */
159         static Reward* handle_load(XML_Helper* helper);
160 
161 	//! Convert a Reward::Type enumerated value to a string.
162 	static Glib::ustring rewardTypeToString(const Reward::Type type);
163 
164 	//! Convert a Reward::Type string to an enumerated value.
165 	static Reward::Type rewardTypeFromString(const Glib::ustring str);
166 
167 	//! deep copy a reward into another one
168 	static Reward* copy(const Reward* r);
169 
170         //! get a random reward type.  (when not hidden map, we don't get maps)
171         static Type getRandomRewardType(bool no_ruins);
172 
173         //! Make a random reward. (like for when we complete a quest)
174         /**
175          * Usually rewards come from the rewardlist object, which is
176          * exhaustible, but this method can create a brand new reward.
177          * It won't give a map reward if we're not playing with a hidden map.
178          *
179          */
180         static Reward* createRandomReward(bool take_from_list, bool no_ruins);
181     protected:
182 
183 	// DATA
184 
185         //! Type of the reward.
186         Type d_type;
187 
188 	//! The name of the reward.
189 	Glib::ustring d_name;
190 
191 };
192 
193 //! A Reward of some gold pieces.
194 /**
195  * Gold pieces are added to the Player's treasury.
196  */
197 class Reward_Gold : public Reward
198 {
199     public:
200 	//! Default constructor.
201 	/**
202 	 * @param gold  The number of gold pieces to award the Player.
203 	 */
204         Reward_Gold(guint32 gold);
205 
206 	//! Loading constructor.
207 	Reward_Gold(XML_Helper *helper);
208 
209 	//! Copy constructor.
210 	Reward_Gold(const Reward_Gold& orig);
211 
212 	//! Destructor.
213         ~Reward_Gold();
214 
215 	// Get Methods
216 
217 	//! Return the number of gold pieces associated with this reward.
getGold()218 	guint32 getGold() const {return d_gold;}
219 
220 
221 	// Methods that operate on the class data but do not modify the class.
222 
223 	//! Save the gold reward to the opened saved-game file.
224         bool save(XML_Helper* helper) const;
225 
226 
227 	// Static Methods
228 
229 	//! Return a random number of gold pieces.
230 	/**
231 	 * This method provides a random number of gold pieces suitable for a
232 	 * reward in the game.
233 	 */
234 	static guint32 getRandomGoldPieces();
235 
236 	//! Return a random number of gold pieces that a Sage gives out.
237 	static guint32 getRandomSageGoldPieces();
238 
239         static Reward_Gold *createRandomReward();
240     private:
241 
242 	// DATA
243 
244 	//! The number of gold pieces to award the player.
245         guint32 d_gold;
246 };
247 
248 //! A number of powerful allies.
249 /**
250  * Up to 8 allies are awarded to the Player's stack being given the Reward.
251  * Allies are Army prototypes that have `Awardable' ability set.
252  */
253 class Reward_Allies: public Reward
254 {
255     public:
256 	//! Default constructor.  Make a new reward of allies.
257 	/**
258 	 * @param army  The Army prototype to create allies from.
259 	 * @param count The number of Army units to create from the prototype.
260 	 */
261         Reward_Allies(const ArmyProto *army, guint32 count);
262 
263 	//! Alternative constructor.  Make a new reward of allies.
264 	/**
265 	 * @param army_type  The Id of the Army prototype to create allies from.
266 	 * @param army_set   The Id of the Armyset that the type belongs to.
267 	 * @param count      The number of Armies to create from the prototype.
268 	 */
269         Reward_Allies(guint32 army_type, guint32 army_set, guint32 count);
270 
271 	//! Make a new reward of allies from another one.
272 	Reward_Allies(const Reward_Allies& orig);
273 
274 	//! Loading constructor.  Load the allies reward from a saved-game file.
275 	Reward_Allies(XML_Helper *helper);
276 
277 	//! Destructor.
278         ~Reward_Allies();
279 
280 	// Get Methods
281 
282 	//! Return the army prototype of the allies associated with this reward.
getArmy()283 	const ArmyProto * getArmy() const {return d_army;}
284 
285 	//! Return the number allies that this reward will create.
getNoOfAllies()286 	guint32 getNoOfAllies() const {return d_count;}
287 
288 
289 	// Methods that operate on the class data and do not modify the class.
290 
291 	//! Save the allies reward to the opened saved-game file.
292         bool save(XML_Helper* helper) const;
293 
294 
295 	// Static Methods
296 
297 	//! A static method that returns a random awardable Army prototype.
298         static const ArmyProto* randomArmyAlly();
299 
300 	//! A static method that returns a number of allies between 1 and 8.
301 	static guint32 getRandomAmountOfAllies();
302 
303         //! A static method that makes some allies.
304         static Reward_Allies *createRandomReward();
305 
306 	//! A static method for adding allies to the game map.
307 	/**
308 	 * Place the given number of the given allies onto the map at the given
309 	 * position.
310 	 *
311 	 * @param p           The player to make the new stack for, if the
312 	 *                    stack can't take all of the allies.
313 	 * @param pos         The place on the map to add the allies.
314 	 * @param army        The Army prototype that defines the allies.
315 	 * @param alliesCount The number of allies to add.
316          * @param stacks      Where the allies ended up.
317 	 *
318 	 * @return True if the armies could successfully be added to the game
319 	 *         map.  Returns false otherwise.
320 	 */
321         static bool addAllies(Player *p, Vector<int> pos, const ArmyProto *army, guint32 alliesCount, StackReflist *stacks);
322 
323 	//! A static method for adding allies to the game map.
324 	/**
325 	 * Place the given number of the given allies onto the map at the given
326 	 * location.
327 	 *
328 	 * @param p           The player to make the new stack for, if the
329 	 *                    stack can't take all of the allies.
330 	 * @param loc         The place on the map to add the allies.
331 	 * @param army        The Army prototype that defines the allies.
332 	 * @param alliesCount The number of allies to add.
333          * @param stacks      Where the allies ended up.
334 	 *
335 	 * @note This method tries to add the armies to the various tiles of
336 	 *       the location first, before placing it outside of the location.
337 	 *
338 	 * @return True if the armies could successfully be added to the game
339 	 *         map.  Returns false otherwise.
340 	 */
341         static bool addAllies(Player *p, Location *l, const Army *army, guint32 alliesCount, StackReflist *stacks);
342 
343     private:
344 	// DATA
345 
346 	//! The Army prototype that represents the allies to give the Player.
347         const ArmyProto *d_army;
348 
349 	//! The army type of the given prototype.
350 	guint32 d_army_type;
351 
352 	//! The army set of the given prototype.
353 	guint32 d_army_set;
354 
355 	//! The number of allies to give the Player.
356         guint32 d_count;
357 };
358 
359 //! A useful item to be awarded to a Hero.
360 /**
361  * Item objects are given to a Hero who has completed a Quest or searched a
362  * Ruin object.
363  */
364 class Reward_Item: public Reward
365 {
366     public:
367 	//! Default constructor.
368 	/**
369 	 * @param item  A pointer to the item to give to the Hero.
370 	 */
371         Reward_Item (Item *item);
372 
373 	//! Loading constructor.
374 	/**
375 	 * Make a new reward item by loading it from an opened saved-game file.
376 	 *
377 	 * @param helper  The opened saved-game file to load the item reward
378 	 *                from.
379 	 */
380 	Reward_Item(XML_Helper *helper);
381 
382 	//! Copy constructor.
383 	/**
384 	 * Make a new reward item by copying it from another one.
385 	 *
386 	 * @param orig  The reward item to copy from.
387 	 */
388 	Reward_Item(const Reward_Item& orig);
389 
390 	//! Destructor.
391         virtual ~Reward_Item();
392 
393 
394 	// Get Methods
395 
396 	//! Get the Item object associated with this reward.
getItem()397 	Item *getItem() const {return d_item;}
398 
399 
400 	// Methods that operate on the class data but do not modify the class.
401 
402 	//! Save the reward item to a file.
403 	/**
404 	 * @param helper  The opened saved-game file to save the reward item to.
405 	 */
406         bool save(XML_Helper* helper) const;
407 
408 
409 	// Static Methods
410 
411 	//! Return a random Item object.
412 	/**
413 	 * @note This method does not return an Reward_Item object.
414 	 *
415 	 * @note This method does not remove the Item object from the Itemlist.
416 	 *
417 	 * @return A pointer to a random Item object in the Itemlist.
418 	 */
419 	static Item *getRandomItem();
420 
421     private:
422 	//! Callback to load the Item object in the Reward_Item object.
423         bool loadItem(Glib::ustring tag, XML_Helper* helper);
424 
425 	// DATA
426 
427 	//! A pointer to the Item object associated with this Reward_Item.
428         Item *d_item;
429 };
430 
431 //! A hidden ruin to be awarded to a Player.
432 /**
433  * Hidden Ruin objects are only visitable by a single Player.
434  * Hidden ruins are not given out as a reward when a Hero searched it and is
435  * successful.  Hidden ruins are given out as a reward for a completed Quest.
436  */
437 class Reward_Ruin: public Reward
438 {
439     public:
440 	//! Default constructor.
441 	/**
442 	 * Make a new Reward_Ruin.
443 	 *
444 	 * @param ruin  A pointer to the hidden Ruin object to present to the
445 	 *              Player.
446 	 */
447         Reward_Ruin(Ruin *ruin);
448 
449 	//! Loading constructor.
450 	/**
451 	 * Make a new Reward_Ruin by loading it from an opened saved-game file.
452 	 *
453 	 * @param helper  The opened saved-game file to load the reward ruin
454 	 *                from.
455 	 */
456 	Reward_Ruin(XML_Helper *helper);
457 
458 	//! Copy constructor.
459 	/**
460 	 * Make a new reward ruin by copying it from another one.
461 	 *
462 	 * @param orig  The reward ruin to copy from.
463 	 */
464 	Reward_Ruin(const Reward_Ruin& orig);
465 
466 	//! Destructor.
467         ~Reward_Ruin();
468 
469 	// Get Methods
470 
471 	//! Return the Ruin object associated with this Reward_Ruin.
getRuin()472 	Ruin* getRuin() const
473 	  {return Ruinlist::getInstance()->getObjectAt(d_ruin_pos);}
474 
475 	// Methods that operate on the class data but do not modify the class.
476 
477 	//! Save the reward ruin to an opened saved-game file.
478 	/**
479 	 * @param helper  The opened saved-game file to write the ruin reward
480 	 *                to.
481 	 */
482         bool save(XML_Helper* helper) const;
483 
484 
485 	// Static Methods
486 
487 	//! Go get a random hidden ruin to give to the Player.
488 	/**
489 	 * Scan all of the Ruin objects in the game and find one that is
490 	 * hidden but only visible by Neutral.  Pick a random Ruin object
491 	 * out of the ones that qualify.
492 	 * It is up to the caller to change the owner of the hidden Ruin
493 	 * object..
494 	 *
495 	 * @return A pointer to a Ruin object in the Ruinlist that is a hidden
496 	 *         ruin and is owned by the neutral Player.  This method will
497 	 *         return NULL if there are no more Ruin objects that meet
498 	 *         that criteria.
499 	 */
500 	static Ruin *getRandomHiddenRuin();
501 
502     private:
503 
504 	// DATA
505 
506 	//! The position of the Ruin object associated with this reward.
507 	Vector<int> d_ruin_pos;
508 };
509 
510 //! A portion of a hidden map to reveal to a Player.
511 /**
512  * When playing on a hidden map, the Player can receive a map that uncovers a
513  * portion of the game map.  It only reveals a portion of the map for one
514  * Player.
515  * The map has a position (from the derived Location class), and as well as a
516  * height and a width.
517  */
518 class Reward_Map: public Reward
519 {
520     public:
521 	//! Default constructor.
522 	/**
523 	 * Make a new Reward_Map from the given parameters.
524 	 *
525 	 * @param pos     The position of the top left corner tile of the map.
526 	 * @param name    The name of this map.
527 	 * @param height  The height of the revealed portion of the game map.
528 	 * @param width   The width of the revealed portion of the game map.
529 	 */
530         Reward_Map(Vector<int> pos, Glib::ustring name,
531 		   guint32 height, guint32 width);
532 
533 	//! Loading constructor.
534 	/**
535 	 * Make a new Reward_Map by loading it from an opened saved-game file.
536 	 *
537 	 * @param helper  The opened saved-game file to load the reward map
538 	 *                from.
539 	 */
540 	Reward_Map(XML_Helper *helper);
541 
542 	//! Copy constructor.
543 	/**
544 	 * Make a new reward map by copying it from another one.
545 	 *
546 	 * @param orig  The reward map to copy from.
547 	 */
548 	Reward_Map(const Reward_Map& orig);
549 
550 	//! Destructor.
551         ~Reward_Map();
552 
553 
554 	// Set Methods
555 
556 	//! Set the name of the map in this reward.
557 	void setMapName(Glib::ustring name);
558 
559 
560 	// Get Methods
561 
562 	//! Return the top left corner of the map in this reward.
563 	Vector<int> getLocation() const;
564 
565 	//! Return the map in this reward.
566 	SightMap * getSightMap() const;
567 
568 	//! Return the name of the map in this reward.
569 	Glib::ustring getMapName() const;
570 
571 	// Methods that operate on the class data and modify the class.
572 
573 	bool loadMap(Glib::ustring tag, XML_Helper* helper);
574 
575 
576 	// Methods that operate on the class data and do not modify the class.
577 
578 	//! Save the reward map to an opened saved-game file.
579 	/**
580 	 * @param helper  The opened saved-game file to write the ruin map to.
581 	 */
582         bool save(XML_Helper* helper) const;
583 
584 
585 	// Static Methods
586 
587 	//! Return a description of a random map.
588 	/**
589 	 * @note This will produce random maps that overlap each other.
590 	 * @note x,y defines the top-left-most tile of the map.
591 	 *
592 	 * @param x       The number of tiles down in the vertical axis from the
593 	 *                topmost edge of the map.
594 	 * @param y       The number of tiles right in the horizontal axis from
595 	 *                the leftmost edge of the map.
596 	 * @param width   The width of the revealed portion of the game map.
597 	 * @param height  The height of the revealed portion of the game map.
598 	 */
599 	static void getRandomMap(int *x, int *y, int *width, int *height);
600 
601         static Reward_Map *createRandomReward();
602 
603         static Glib::ustring getRandomName();
604 
605     private:
606 
607 	// DATA
608 	SightMap *d_sightmap;
609 };
610 
611 #endif
612