initial commit, lordsawar source, slightly modified
[lordsawar] / src / armybase.cpp
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
6 //
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.
11 //
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.
16 //
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 
20 //  02110-1301, USA.
21
22 #include <iostream>
23 #include <sstream>
24 #include <algorithm>
25 #include "ucompose.hpp"
26 #include "armybase.h"
27 #include "xmlhelper.h"
28 #include "Tile.h"
29 #include "defs.h"
30
31 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<std::flush;}
32 #define debug(x)
33
34 ArmyBase::ArmyBase(const ArmyBase& a)
35 : d_upkeep(a.d_upkeep), d_strength(a.d_strength), d_max_moves(a.d_max_moves), 
36     d_sight(a.d_sight), d_move_bonus(a.d_move_bonus),
37     d_army_bonus(a.d_army_bonus), d_xp_value(a.d_xp_value)
38 {
39 }
40
41 ArmyBase::ArmyBase()
42   : d_upkeep(0), 
43     d_strength(0), d_max_moves(0), d_sight(0), 
44     d_move_bonus(0), d_army_bonus(0), d_xp_value(0.0)
45 {
46 }
47
48 ArmyBase::ArmyBase(XML_Helper* helper)
49 {
50   helper->getData(d_upkeep, "upkeep");
51   std::string move_bonus_str;
52   helper->getData(move_bonus_str, "move_bonus");
53   d_move_bonus = moveFlagsFromString(move_bonus_str);
54   std::string army_bonus_str;
55   helper->getData(army_bonus_str, "army_bonus");
56   d_army_bonus = bonusFlagsFromString(army_bonus_str);
57   helper->getData(d_max_moves, "max_moves");
58   helper->getData(d_strength, "strength");
59   helper->getData(d_sight, "sight");
60   helper->getData(d_xp_value, "expvalue");
61 }
62
63 ArmyBase::~ArmyBase()
64 {
65 }
66
67 bool ArmyBase::saveData(XML_Helper* helper) const
68 {
69   bool retval = true;
70   retval &= helper->saveData("upkeep", d_upkeep);
71   std::string move_bonus_str = moveFlagsToString(d_move_bonus);
72   retval &= helper->saveData("move_bonus", move_bonus_str);
73   std::string army_bonus_str = bonusFlagsToString(d_army_bonus);
74   retval &= helper->saveData("army_bonus", army_bonus_str);
75   retval &= helper->saveData("max_moves", d_max_moves);
76   retval &= helper->saveData("strength", d_strength);
77   retval &= helper->saveData("sight", d_sight);
78   retval &= helper->saveData("expvalue", d_xp_value);
79   return retval;
80 }
81
82 std::string ArmyBase::getArmyBonusDescription() const
83 {
84   guint32 bonus = d_army_bonus;
85   Glib::ustring s = "";
86   if (bonus & ArmyBase::ADD1STRINOPEN)
87     s += String::ucompose(_("%1%2"), s == "" ? " " : "& ", 
88                           _("+1 str in open"));
89   if (bonus & ArmyBase::ADD2STRINOPEN)
90     s += String::ucompose(_("%1%2"), s == "" ? " " : "& ", 
91                           _("+2 str in open"));
92   if (bonus & ArmyBase::ADD1STRINFOREST)
93     s += String::ucompose(_("%1%2"), s == "" ? " " : "& ", 
94                           _("+1 str in woods"));
95   if (bonus & ArmyBase::ADD1STRINHILLS)
96     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
97                           _("+1 str in hills"));
98   if (bonus & ArmyBase::ADD1STRINCITY)
99     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
100                           _("+1 str in city"));
101   if (bonus & ArmyBase::ADD2STRINCITY)
102     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
103                           _("+2 str in city"));
104   if (bonus & ArmyBase::ADD1STACKINHILLS)
105     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
106                           _("+1 stack in hills"));
107   if (bonus & ArmyBase::SUBALLCITYBONUS)
108     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
109                           _("Cancel city bonus"));
110   if (bonus & ArmyBase::SUB1ENEMYSTACK)
111     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
112                           _("-1 enemy stack"));
113   if (bonus & ArmyBase::ADD1STACK)
114     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", _("+1 stack"));
115   if (bonus & ArmyBase::ADD2STACK)
116     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", _("+2 stack"));
117   if (bonus & ArmyBase::SUBALLNONHEROBONUS)
118     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
119                           _("cancel non-hero"));
120   if (bonus & ArmyBase::SUBALLHEROBONUS)
121     s += String::ucompose(_("%1%2"), s == "" ? " " : " & ", 
122                           _("cancel hero"));
123   return s;
124 }
125
126 std::string ArmyBase::moveFlagsToString(const guint32 bonus)
127 {
128   std::string move_bonuses;
129   //we don't add grass, because it's always implied.
130   if (bonus & Tile::WATER)
131     move_bonuses += " " + Tile::tileTypeToString(Tile::WATER);
132   if (bonus & Tile::FOREST)
133     move_bonuses += " " + Tile::tileTypeToString(Tile::FOREST);
134   if (bonus & Tile::HILLS)
135     move_bonuses += " " + Tile::tileTypeToString(Tile::HILLS);
136   if (bonus & Tile::MOUNTAIN)
137     move_bonuses += " " + Tile::tileTypeToString(Tile::MOUNTAIN);
138   if (bonus & Tile::SWAMP)
139     move_bonuses += " " + Tile::tileTypeToString(Tile::SWAMP);
140   if (bonus & Tile::VOID)
141     move_bonuses += " " + Tile::tileTypeToString(Tile::VOID);
142   return move_bonuses;
143 }
144
145 guint32 ArmyBase::moveFlagsFromString(const std::string str)
146 {
147   guint32 total = 0;
148   std::stringstream bonuses;
149   bonuses.str(str);
150
151   while (bonuses.eof() == false)
152     {
153       std::string bonus;
154       bonuses >> bonus;
155       if (bonus.size() == 0)
156         break;
157       total += Tile::tileTypeFromString(bonus);
158     }
159   return total;
160 }
161
162 std::string ArmyBase::bonusFlagToString(const ArmyBase::Bonus bonus)
163 {
164   switch (bonus)
165     {
166     case ArmyBase::ADD1STRINOPEN:
167       return "ArmyBase::ADD1STRINOPEN";
168     case ArmyBase::ADD2STRINOPEN:
169       return "ArmyBase::ADD2STRINOPEN";
170     case ArmyBase::ADD1STRINFOREST:
171       return "ArmyBase::ADD1STRINFOREST";
172     case ArmyBase::ADD1STRINHILLS:
173       return "ArmyBase::ADD1STRINHILLS";
174     case ArmyBase::ADD1STRINCITY:
175       return "ArmyBase::ADD1STRINCITY";
176     case ArmyBase::ADD2STRINCITY:
177       return "ArmyBase::ADD2STRINCITY";
178     case ArmyBase::ADD1STACKINHILLS:
179       return "ArmyBase::ADD1STACKINHILLS";
180     case ArmyBase::SUBALLCITYBONUS:
181       return "ArmyBase::SUBALLCITYBONUS";
182     case ArmyBase::SUB1ENEMYSTACK:
183       return "ArmyBase::SUB1ENEMYSTACK";
184     case ArmyBase::ADD1STACK:
185       return "ArmyBase::ADD1STACK";
186     case ArmyBase::ADD2STACK:
187       return "ArmyBase::ADD2STACK";
188     case ArmyBase::SUBALLNONHEROBONUS:
189       return "ArmyBase::SUBALLNONHEROBONUS";
190     case ArmyBase::SUBALLHEROBONUS:
191       return "ArmyBase::SUBALLHEROBONUS";
192     case ArmyBase::FORTIFY:
193       return "ArmyBase::FORTIFY";
194     }
195   return "";
196 }
197
198 std::string ArmyBase::bonusFlagsToString(const guint32 bonus)
199 {
200   std::string bonuses;
201   if (bonus & ArmyBase::ADD1STRINOPEN)
202     bonuses += " " + bonusFlagToString(ArmyBase::ADD1STRINOPEN);
203   if (bonus & ArmyBase::ADD2STRINOPEN)
204     bonuses += " " + bonusFlagToString(ArmyBase::ADD2STRINOPEN);
205   if (bonus & ArmyBase::ADD1STRINFOREST)
206     bonuses += " " + bonusFlagToString(ArmyBase::ADD1STRINFOREST);
207   if (bonus & ArmyBase::ADD1STRINHILLS)
208     bonuses += " " + bonusFlagToString(ArmyBase::ADD1STRINHILLS);
209   if (bonus & ArmyBase::ADD1STRINCITY)
210     bonuses += " " + bonusFlagToString(ArmyBase::ADD1STRINCITY);
211   if (bonus & ArmyBase::ADD2STRINCITY)
212     bonuses += " " + bonusFlagToString(ArmyBase::ADD2STRINCITY);
213   if (bonus & ArmyBase::ADD1STACKINHILLS)
214     bonuses += " " + bonusFlagToString(ArmyBase::ADD1STACKINHILLS);
215   if (bonus & ArmyBase::SUBALLCITYBONUS)
216     bonuses += " " + bonusFlagToString(ArmyBase::SUBALLCITYBONUS);
217   if (bonus & ArmyBase::SUB1ENEMYSTACK)
218     bonuses += " " + bonusFlagToString(ArmyBase::SUB1ENEMYSTACK);
219   if (bonus & ArmyBase::ADD1STACK)
220     bonuses += " " + bonusFlagToString(ArmyBase::ADD1STACK);
221   if (bonus & ArmyBase::ADD2STACK)
222     bonuses += " " + bonusFlagToString(ArmyBase::ADD2STACK);
223   if (bonus & ArmyBase::SUBALLNONHEROBONUS)
224     bonuses += " " + bonusFlagToString(ArmyBase::SUBALLNONHEROBONUS);
225   if (bonus & ArmyBase::SUBALLHEROBONUS)
226     bonuses += " " + bonusFlagToString(ArmyBase::SUBALLHEROBONUS);
227   if (bonus & ArmyBase::FORTIFY)
228     bonuses += " " + bonusFlagToString(ArmyBase::FORTIFY);
229   return bonuses;
230 }
231
232 guint32 ArmyBase::bonusFlagsFromString(const std::string str)
233 {
234   guint32 total = 0;
235   std::stringstream bonuses;
236   bonuses.str(str);
237
238   while (bonuses.eof() == false)
239     {
240       std::string bonus;
241       bonuses >> bonus;
242       if (bonus.size() == 0)
243         break;
244       total += bonusFlagFromString(bonus);
245     }
246   return total;
247 }
248
249 ArmyBase::Bonus ArmyBase::bonusFlagFromString(const std::string str)
250 {
251   if (str.size() > 0 && isdigit(str.c_str()[0]))
252     return ArmyBase::Bonus(atoi(str.c_str()));
253   if (str == "ArmyBase::ADD1STRINOPEN")
254     return ArmyBase::ADD1STRINOPEN;
255   else if (str == "ArmyBase::ADD2STRINOPEN")
256     return ArmyBase::ADD2STRINOPEN;
257   else if (str == "ArmyBase::ADD1STRINFOREST")
258     return ArmyBase::ADD1STRINFOREST;
259   else if (str == "ArmyBase::ADD1STRINHILLS")
260     return ArmyBase::ADD1STRINHILLS;
261   else if (str == "ArmyBase::ADD1STRINCITY")
262     return ArmyBase::ADD1STRINCITY;
263   else if (str == "ArmyBase::ADD2STRINCITY")
264     return ArmyBase::ADD2STRINCITY;
265   else if (str == "ArmyBase::ADD1STACKINHILLS")
266     return ArmyBase::ADD1STACKINHILLS;
267   else if (str == "ArmyBase::SUBALLCITYBONUS")
268     return ArmyBase::SUBALLCITYBONUS;
269   else if (str == "ArmyBase::ADD2GOLDPERCITY")
270     return ArmyBase::SUB1ENEMYSTACK;
271   else if (str == "ArmyBase::SUB1ENEMYSTACK")
272     return ArmyBase::ADD1STACK;
273   else if (str == "ArmyBase::ADD1STACK")
274     return ArmyBase::ADD2STACK;
275   else if (str == "ArmyBase::ADD2STACK")
276     return ArmyBase::ADD2STACK;
277   else if (str == "ArmyBase::SUBALLNONHEROBONUS")
278     return ArmyBase::SUBALLNONHEROBONUS;
279   else if (str == "ArmyBase::SUBALLHEROBONUS")
280     return ArmyBase::SUBALLHEROBONUS;
281   else if (str == "ArmyBase::FORTIFY")
282     return ArmyBase::FORTIFY;
283   return ArmyBase::ADD1STRINOPEN;
284 }