1 // Copyright (C) 2000, 2001, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2004, 2005 Andrea Paternesi
4 // Copyright (C) 2007, 2008 Ben Asselstine
5 // Copyright (C) 2007, 2008 Ole Laursen
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3 of the License, or
10 // (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Library General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "armyprodbase.h"
27 #include "armyproto.h"
28 #include "armysetlist.h"
30 #include "xmlhelper.h"
31 #include "stacklist.h"
32 #include "templelist.h"
33 #include "ucompose.hpp"
37 std::string Army::d_tag = "army";
39 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<std::flush;}
42 sigc::signal<void, Army*> Army::sdying;
44 Army::Army(const Army& a, Player* p)
45 :ArmyBase(a), UniquelyIdentified(a), Ownable(p), d_type_id(a.d_type_id),
46 d_armyset(a.d_armyset), d_max_hp(a.d_max_hp),
47 d_max_moves_multiplier(a.d_max_moves_multiplier),
48 d_max_moves_rest_bonus(a.d_max_moves_rest_bonus),
49 d_ship(a.d_ship), d_hp(a.d_hp), d_moves(a.d_moves), d_xp(a.d_xp),
50 d_level(a.d_level), d_battles_number(a.d_battles_number),
51 d_number_hashit(a.d_number_hashit),
52 d_number_hasbeenhit(a.d_number_hasbeenhit),
53 d_visitedTemples(a.d_visitedTemples)
55 for(int i = 0; i < 3; i++)
56 d_medal_bonus[i] = a.d_medal_bonus[i];
59 Army::Army(const ArmyProto& a, Player* p)
60 :ArmyBase(a), UniquelyIdentified(), Ownable(p),
61 d_type_id(a.getTypeId()), d_armyset(a.getArmyset()),
62 d_max_hp(2), d_max_moves_multiplier(1), d_max_moves_rest_bonus(0),
63 d_ship(false), d_hp(2), d_moves(a.getMaxMoves()), d_xp(0), d_level(0),
64 d_battles_number(0), d_number_hashit(0), d_number_hasbeenhit(0)
66 for(int i = 0; i < 3; i++)
68 d_visitedTemples.clear();
71 Army::Army(const ArmyProto& a, guint32 id, Player *p)
72 :ArmyBase(a), UniquelyIdentified(id), Ownable(p),
73 d_type_id(a.getTypeId()), d_armyset(a.getArmyset()),
74 d_max_hp(2), d_max_moves_multiplier(1), d_max_moves_rest_bonus(0),
75 d_ship(false), d_hp(2), d_moves(a.getMaxMoves()), d_xp(0), d_level(0),
76 d_battles_number(0), d_number_hashit(0), d_number_hasbeenhit(0)
78 for(int i = 0; i < 3; i++)
80 d_visitedTemples.clear();
83 Army::Army(const ArmyProdBase& a, guint32 id, Player *p)
84 :ArmyBase(a), UniquelyIdentified(id), Ownable(p),
85 d_type_id(a.getTypeId()), d_armyset(a.getArmyset()),
86 d_max_hp(2), d_max_moves_multiplier(1), d_max_moves_rest_bonus(0),
87 d_ship(false), d_hp(2), d_moves(a.getMaxMoves()), d_xp(0), d_level(0),
88 d_battles_number(0), d_number_hashit(0), d_number_hasbeenhit(0)
90 for(int i = 0; i < 3; i++)
92 d_visitedTemples.clear();
95 Army* Army::createNonUniqueArmy(const ArmyProto& a, Player *player)
97 return new Army(a, (guint32) 0, player);
100 Army* Army::createNonUniqueArmy(const ArmyProdBase& a, Player *player)
102 return new Army(a, (guint32) 0, player);
105 Army::Army(const ArmyProdBase& a, Player* p)
106 :ArmyBase(a), UniquelyIdentified(), Ownable(p),
107 d_type_id(a.getTypeId()), d_armyset(a.getArmyset()),
108 d_max_hp(2), d_max_moves_multiplier(1), d_max_moves_rest_bonus(0),
109 d_ship(false), d_hp(2), d_moves(a.getMaxMoves()), d_xp(0), d_level(0),
110 d_battles_number(0), d_number_hashit(0), d_number_hasbeenhit(0)
112 for(int i = 0; i < 3; i++)
113 d_medal_bonus[i] = 0;
114 d_visitedTemples.clear();
118 :ArmyBase(), UniquelyIdentified(), Ownable((Player *)0),
119 d_type_id(0), d_armyset(0), d_max_hp(2), d_max_moves_multiplier(1),
120 d_max_moves_rest_bonus(0), d_ship(false), d_hp(2), d_moves(0), d_xp(0),
121 d_level(0), d_battles_number(0), d_number_hashit(0), d_number_hasbeenhit(0)
123 d_visitedTemples.clear();
126 Army::Army(XML_Helper* helper)
127 :ArmyBase(helper), UniquelyIdentified(helper), Ownable((XML_Helper*) 0),
128 d_type_id(0), d_armyset(0), d_max_hp(2), d_max_moves_multiplier(1),
129 d_max_moves_rest_bonus(0), d_ship(false), d_hp(2), d_moves(0), d_xp(0),
130 d_level(0), d_battles_number(0), d_number_hashit(0), d_number_hasbeenhit(0)
132 //d_owner is not read in here. it is set to the owner of the stack
134 d_visitedTemples.clear();
137 //get the information which army we are
138 helper->getData(d_type_id, "type");
139 helper->getData(d_armyset, "armyset");
141 helper->getData(d_hp, "hp");
142 helper->getData(d_ship, "ship");
143 helper->getData(d_moves, "moves");
144 helper->getData(d_max_moves_multiplier, "max_moves_multiplier");
145 helper->getData(d_xp, "xp");
146 helper->getData(d_level, "level");
149 std::stringstream smedals;
152 helper->getData(medals, "medals");
158 d_medal_bonus[i]=val;
159 debug("ARMY-XML-CONSTRUCTOR medalsbonus[" << i << "]=" << d_medal_bonus[i])
162 helper->getData(d_battles_number, "battlesnumber");
165 std::stringstream stemples;
166 helper->getData(temples, "visited_temples");
167 stemples.str(temples);
169 while (stemples.eof() == false)
174 d_visitedTemples.push_front(ival);
184 void Army::setStat(Army::Stat stat, guint32 value)
190 if (d_strength > MAX_ARMY_STRENGTH)
191 d_strength = MAX_ARMY_STRENGTH;
200 if (d_moves > d_max_moves)
203 case MOVES_MULTIPLIER:
204 d_max_moves_multiplier = value;
206 case MOVE_BONUS: d_move_bonus = value;
208 case ARMY_BONUS: d_army_bonus = value;
210 case SIGHT: d_sight = value;
212 case SHIP: value == 0 ? d_ship = false : d_ship = true;
217 guint32 Army::getStat(Stat stat, bool modified) const
228 return (d_max_moves + d_max_moves_rest_bonus) * d_max_moves_multiplier;
240 case MOVES_MULTIPLIER:
241 return d_max_moves_multiplier;
244 // should never come to this
248 void Army::resetMoves()
252 case 0: d_max_moves_rest_bonus = 0; break;
253 case 1: d_max_moves_rest_bonus = 1; break;
254 case 2: d_max_moves_rest_bonus = 2; break;
255 default: d_max_moves_rest_bonus = 2; break;
258 d_moves = MAX_BOAT_MOVES;
260 d_moves = getStat(MOVES);
263 /* is this temple one we've already visited? */
264 bool Army::bless(Temple *temple)
266 bool visited = false;
271 guint32 templeId = temple->getId();
272 std::list<unsigned int>::const_iterator tit = d_visitedTemples.begin();
273 std::list<unsigned int>::const_iterator tend = d_visitedTemples.end();
274 for(;tit != tend;++tit)
276 if ((*tit) == templeId)
283 if (visited == false) /* no? increase strength */
285 d_visitedTemples.push_back(templeId);
286 setStat(STRENGTH, d_strength + 1);
292 void Army::heal(guint32 hp)
296 // if no hp are specified, we assume that the healing at the end of
297 // the turn takes place. In this case the algorithm is: Heal 10%
298 // plus 1HP for each point of vitality above 5 (or one less for each
299 // point below 5), heal a minimum of 1 HP per turn
308 if (d_hp > getStat(HP))
312 bool Army::damage(guint32 damageDone)
314 if (damageDone >= d_hp)
321 void Army::decrementMoves(guint32 moves)
323 if (moves >= d_moves)
329 void Army::gainXp(double n)
334 bool Army::save(XML_Helper* helper) const
338 retval &= helper->openTag(Army::d_tag);
339 retval &= saveData(helper);
340 retval &= helper->closeTag();
345 bool Army::saveData(XML_Helper* helper) const
349 retval &= ArmyBase::saveData(helper);
350 retval &= helper->saveData("id", d_id);
351 retval &= helper->saveData("armyset", d_armyset);
352 retval &= helper->saveData("type", d_type_id);
353 retval &= helper->saveData("hp", d_hp);
354 retval &= helper->saveData("ship", d_ship);
355 retval &= helper->saveData("moves", d_moves);
356 retval &= helper->saveData("xp", d_xp);
357 retval &= helper->saveData("max_moves_multiplier",
358 d_max_moves_multiplier);
359 retval &= helper->saveData("level", d_level);
361 std::stringstream medals;
362 for (int i=0;i<3;i++)
364 medals << d_medal_bonus[i] << " ";
366 retval &= helper->saveData("medals", medals.str());
367 retval &= helper->saveData("battlesnumber",d_battles_number);
369 std::stringstream temples;
370 std::list<unsigned int>::const_iterator tit = d_visitedTemples.begin();
371 std::list<unsigned int>::const_iterator tend = d_visitedTemples.end();
372 for(;tit != tend;++tit)
373 temples << (*tit) << " ";
374 retval &= helper->saveData("visited_temples", temples.str());
379 void Army::printAllDebugInfo() const
381 std::cerr << "name = " << getName() << std::endl;
382 std::cerr << "max_hp = " << d_max_hp << std::endl;
383 std::cerr << "xp_value = " << d_xp_value << std::endl;
384 std::cerr << "strength = " << d_strength << std::endl;
385 std::cerr << "max_moves = " << d_max_moves << std::endl;
386 std::cerr << "max_moves_multiplier = "
387 << d_max_moves_multiplier << std::endl;
388 std::cerr << "max_moves_rest_bonus = "
389 << d_max_moves_rest_bonus << std::endl;
390 std::cerr << "upkeep = " << d_upkeep << std::endl;
391 std::cerr << "move_bonus = " << d_move_bonus << std::endl;
392 std::cerr << "ship = " << d_ship << std::endl;
393 std::cerr << "army_bonus = " << d_army_bonus << std::endl;
395 std::cerr << "type = " << d_type_id << std::endl;
396 std::cerr << "level = " << d_level << std::endl;
397 std::cerr << "xp = " << d_xp << std::endl;
399 std::cerr << "medal[0] = " << d_medal_bonus[0] << std::endl;
400 std::cerr << "medal[1] = " << d_medal_bonus[1] << std::endl;
401 std::cerr << "medal[2] = " << d_medal_bonus[2] << std::endl;
403 std::cerr << "battle number = " << d_battles_number << std::endl;
404 std::cerr << "has hit = " << d_number_hashit << std::endl;
405 std::cerr << "has been hit = " << d_number_hasbeenhit << std::endl;
406 std::stringstream temples;
407 std::list<unsigned int>::const_iterator tit = d_visitedTemples.begin();
408 std::list<unsigned int>::const_iterator tend = d_visitedTemples.end();
409 for(;tit != tend;++tit)
410 temples << (*tit) << " ";
411 std::cerr << "visited temples with ids = " << temples << std::endl;
414 void Army::setInShip (bool s)
419 //! Sets this army as being fortified (+1 to stack)
420 void Army::setFortified (bool f)
422 if (getFortified() == true && f == true)
424 else if (getFortified() == true && f == false)
425 d_army_bonus ^= Army::FORTIFY;
426 else if (getFortified() == false && f == true)
427 d_army_bonus |= Army::FORTIFY;
428 else if (getFortified() == false && f == false)
432 //! get the fortify flag for this army
433 bool Army::getFortified () const
435 return (d_army_bonus & Army::FORTIFY) == Army::FORTIFY;
438 bool Army::blessedAtTemple(guint32 temple_id) const
440 unsigned int id = temple_id;
441 if (std::find (d_visitedTemples.begin(), d_visitedTemples.end(), id) ==
442 d_visitedTemples.end())
448 bool Army::getDefendsRuins() const
450 ArmyProto *a = Armysetlist::getInstance()->getArmy(d_armyset, d_type_id);
452 return a->getDefendsRuins();
457 bool Army::getAwardable() const
459 ArmyProto *a = Armysetlist::getInstance()->getArmy(d_armyset, d_type_id);
461 return a->getAwardable();
466 std::string Army::getName() const
468 ArmyProto *a = Armysetlist::getInstance()->getArmy(d_armyset, d_type_id);
475 void Army::morph(const ArmyProto *army)
477 setStat(Army::STRENGTH, army->getStrength());
478 setStat(Army::MOVES, army->getMaxMoves());
479 setStat(Army::MOVE_BONUS, army->getMoveBonus());
480 setStat(Army::ARMY_BONUS, army->getArmyBonus());
481 d_type_id = army->getTypeId();
482 d_armyset = army->getArmyset();