initial commit, lordsawar source, slightly modified
[lordsawar] / src / ItemProto.cpp
1 // Copyright (C) 2008 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 #include <sstream>
19 #include <vector>
20 #include "ItemProto.h"
21 #include "ucompose.hpp"
22 #include "defs.h"
23
24 std::string ItemProto::d_tag = "itemproto";
25 using namespace std;
26
27 ItemProto::ItemProto(XML_Helper* helper)
28         : Renamable (helper)
29 {
30     
31     // Loading of items is a bit complicated, so i'd better loose some words.
32     // In general, items can be loaded from the items description file or
33     // from a savegame. They both differ a bit, more on that when we encounter
34     // such a situation. First, let us deal with the common things.
35
36     std::string bonus_str;
37     helper->getData(bonus_str, "bonus");
38     d_bonus = bonusFlagsFromString(bonus_str);
39
40 }
41
42 ItemProto::ItemProto(std::string name, guint32 id)
43         : Renamable(name)
44 {
45   d_bonus = 0;
46   d_type_id = id;
47 }
48
49 ItemProto::ItemProto(const ItemProto& orig)
50 :Renamable(orig), d_bonus(orig.d_bonus), d_type_id(orig.d_type_id)
51 {
52 }
53
54 ItemProto::~ItemProto()
55 {
56 }
57
58 bool ItemProto::save(XML_Helper* helper) const
59 {
60   bool retval = true;
61
62   // A template is never saved, so we assume this class is a real-life item
63   retval &= helper->openTag(d_tag);
64   retval &= helper->saveData("name", getName(false));
65   std::string bonus_str = bonusFlagsToString(d_bonus);
66   retval &= helper->saveData("bonus", bonus_str);
67
68   retval &= helper->closeTag();
69
70   return retval;
71 }
72
73 bool ItemProto::getBonus(ItemProto::Bonus bonus) const
74 {
75   return (d_bonus & bonus) == 0 ? false : true;
76 }
77
78 void ItemProto::addBonus(ItemProto::Bonus bonus)
79 {
80   d_bonus |= bonus;
81 }
82
83 void ItemProto::removeBonus(ItemProto::Bonus bonus)
84 {
85   d_bonus ^= bonus;
86 }
87
88 std::string ItemProto::getBonusDescription() const
89 {
90   guint32 battle = 0;
91   guint32 command = 0;
92   guint32 goldpercity = 0;
93   // the attributes column
94   std::vector<Glib::ustring> s;
95   if (getBonus(ItemProto::ADD1STR))
96     battle++;
97   if (getBonus(ItemProto::ADD2STR))
98     battle+=2;
99   if (getBonus(ItemProto::ADD3STR))
100     battle+=3;
101   if (getBonus(ItemProto::ADD1STACK))
102     command++;
103   if (getBonus(ItemProto::ADD2STACK))
104     command+=2;
105   if (getBonus(ItemProto::ADD3STACK))
106     command+=3;
107   if (getBonus(ItemProto::FLYSTACK))
108     s.push_back(_("Allows Flight"));
109   if (getBonus(ItemProto::DOUBLEMOVESTACK))
110     s.push_back(_("Doubles Movement"));
111   if (getBonus(ItemProto::ADD2GOLDPERCITY))
112     goldpercity+=2;
113   if (getBonus(ItemProto::ADD3GOLDPERCITY))
114     goldpercity+=3;
115   if (getBonus(ItemProto::ADD4GOLDPERCITY))
116     goldpercity+=4;
117   if (getBonus(ItemProto::ADD5GOLDPERCITY))
118     goldpercity+=5;
119
120   if (battle > 0)
121     s.push_back(String::ucompose(_("+%1 Battle"), battle));
122   if (command > 0)
123     s.push_back(String::ucompose(_("+%1 Command"), command));
124   if (goldpercity > 0)
125     s.push_back(String::ucompose(_("+%1 gold per city"), goldpercity));
126
127   Glib::ustring str;
128   bool first = true;
129   for (std::vector<Glib::ustring>::iterator i = s.begin(), end = s.end();
130        i != end; ++i)
131     {
132       if (first)
133         first = false;
134       else
135         str += "\n";
136       str += *i;
137     }
138   return str;
139 }
140
141 std::string ItemProto::bonusFlagToString(ItemProto::Bonus bonus)
142 {
143   switch (bonus)
144     {
145     case ItemProto::ADD1STR:
146       return "ItemProto::ADD1STR";
147     case ItemProto::ADD2STR:
148       return "ItemProto::ADD2STR";
149     case ItemProto::ADD3STR:
150       return "ItemProto::ADD3STR";
151     case ItemProto::ADD1STACK:
152       return "ItemProto::ADD1STACK";
153     case ItemProto::ADD2STACK:
154       return "ItemProto::ADD2STACK";
155     case ItemProto::ADD3STACK:
156       return "ItemProto::ADD3STACK";
157     case ItemProto::FLYSTACK:
158       return "ItemProto::FLYSTACK";
159     case ItemProto::DOUBLEMOVESTACK:
160       return "ItemProto::DOUBLEMOVESTACK";
161     case ItemProto::ADD2GOLDPERCITY:
162       return "ItemProto::ADD2GOLDPERCITY";
163     case ItemProto::ADD3GOLDPERCITY:
164       return "ADD3GOLDPERCITY";
165     case ItemProto::ADD4GOLDPERCITY:
166       return "ItemProto::ADD4GOLDPERCITY";
167     case ItemProto::ADD5GOLDPERCITY:
168       return "ItemProto::ADD5GOLDPERCITY";
169     }
170   return "ItemProto::ADD1STR";
171 }
172
173 std::string ItemProto::bonusFlagsToString(guint32 bonus)
174 {
175   std::string bonuses;
176   if (bonus & ItemProto::ADD1STR)
177     bonuses += " " + bonusFlagToString(ItemProto::ADD1STR);
178   if (bonus & ItemProto::ADD2STR)
179     bonuses += " " + bonusFlagToString(ItemProto::ADD2STR);
180   if (bonus & ItemProto::ADD3STR)
181     bonuses += " " + bonusFlagToString(ItemProto::ADD3STR);
182   if (bonus & ItemProto::ADD1STACK)
183     bonuses += " " + bonusFlagToString(ItemProto::ADD1STACK);
184   if (bonus & ItemProto::ADD2STACK)
185     bonuses += " " + bonusFlagToString(ItemProto::ADD2STACK);
186   if (bonus & ItemProto::ADD3STACK)
187     bonuses += " " + bonusFlagToString(ItemProto::ADD3STACK);
188   if (bonus & ItemProto::FLYSTACK)
189     bonuses += " " + bonusFlagToString(ItemProto::FLYSTACK);
190   if (bonus & ItemProto::DOUBLEMOVESTACK)
191     bonuses += " " + bonusFlagToString(ItemProto::DOUBLEMOVESTACK);
192   if (bonus & ItemProto::ADD2GOLDPERCITY)
193     bonuses += " " + bonusFlagToString(ItemProto::ADD2GOLDPERCITY);
194   if (bonus & ItemProto::ADD3GOLDPERCITY)
195     bonuses += " " + bonusFlagToString(ItemProto::ADD3GOLDPERCITY);
196   if (bonus & ItemProto::ADD4GOLDPERCITY)
197     bonuses += " " + bonusFlagToString(ItemProto::ADD4GOLDPERCITY);
198   if (bonus & ItemProto::ADD5GOLDPERCITY)
199     bonuses += " " + bonusFlagToString(ItemProto::ADD5GOLDPERCITY);
200   return bonuses;
201 }
202
203 guint32 ItemProto::bonusFlagsFromString(std::string str)
204 {
205   guint32 total = 0;
206   std::stringstream bonuses;
207   bonuses.str(str);
208
209   while (bonuses.eof() == false)
210     {
211       std::string bonus;
212       bonuses >> bonus;
213       if (bonus.size() == 0)
214         break;
215       total += bonusFlagFromString(bonus);
216     }
217   return total;
218 }
219
220 ItemProto::Bonus ItemProto::bonusFlagFromString(std::string str)
221 {
222   if (str.size() > 0 && isdigit(str.c_str()[0]))
223     return ItemProto::Bonus(atoi(str.c_str()));
224   if (str == "ItemProto::ADD1STR")
225     return ItemProto::ADD1STR;
226   else if (str == "ItemProto::ADD2STR")
227     return ItemProto::ADD2STR;
228   else if (str == "ItemProto::ADD3STR")
229     return ItemProto::ADD3STR;
230   else if (str == "ItemProto::ADD1STACK")
231     return ItemProto::ADD1STACK;
232   else if (str == "ItemProto::ADD2STACK")
233     return ItemProto::ADD2STACK;
234   else if (str == "ItemProto::ADD3STACK")
235     return ItemProto::ADD3STACK;
236   else if (str == "ItemProto::FLYSTACK")
237     return ItemProto::FLYSTACK;
238   else if (str == "ItemProto::DOUBLEMOVESTACK")
239     return ItemProto::DOUBLEMOVESTACK;
240   else if (str == "ItemProto::ADD2GOLDPERCITY")
241     return ItemProto::ADD2GOLDPERCITY;
242   else if (str == "ItemProto::ADD3GOLDPERCITY")
243     return ItemProto::ADD3GOLDPERCITY;
244   else if (str == "ItemProto::ADD4GOLDPERCITY")
245     return ItemProto::ADD4GOLDPERCITY;
246   else if (str == "ItemProto::ADD5GOLDPERCITY")
247     return ItemProto::ADD5GOLDPERCITY;
248   return ItemProto::ADD1STR;
249 }