1 // Copyright (C) 2000, 2001, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2002 Mark L. Amidon
4 // Copyright (C) 2005 Andrea Paternesi
5 // Copyright (C) 2006, 2007, 2008, 2014, 2015 Ben Asselstine
6 // Copyright (C) 2008 Ole Laursen
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // 02110-1301, USA.
22
23 #include <sstream>
24 #include "prodslotlist.h"
25 #include "path.h"
26 #include "army.h"
27 #include "armyprodbase.h"
28 #include "hero.h"
29 #include "stacklist.h"
30 #include "stack.h"
31 #include "playerlist.h"
32 #include "armysetlist.h"
33 #include "citylist.h"
34 #include "GameMap.h"
35 #include "vectoredunitlist.h"
36 #include "vectoredunit.h"
37 #include "action.h"
38 #include "xmlhelper.h"
39
40 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<std::flush;}
41 #define debug(x)
42
ProdSlotlist(guint32 numslots)43 ProdSlotlist::ProdSlotlist(guint32 numslots)
44 : d_active_production_slot(-1), d_duration(-1)
45 {
46 // Initialise armytypes
47 for (unsigned int i = 0; i < numslots; i++)
48 push_back(new ProdSlot());
49
50 }
51
ProdSlotlist(XML_Helper * helper)52 ProdSlotlist::ProdSlotlist(XML_Helper* helper)
53 {
54 helper->getData(d_active_production_slot, "active_production_slot");
55 helper->getData(d_duration, "duration");
56 helper->registerTag(ProdSlot::d_tag,
57 sigc::mem_fun(this, &ProdSlotlist::load));
58 }
59
load(Glib::ustring tag,XML_Helper * helper)60 bool ProdSlotlist::load(Glib::ustring tag, XML_Helper *helper)
61 {
62 if (tag == ProdSlot::d_tag)
63 {
64 push_back(new ProdSlot(helper));
65 return true;
66 }
67 return false;
68 }
69
ProdSlotlist(const ProdSlotlist & c)70 ProdSlotlist::ProdSlotlist(const ProdSlotlist& c)
71 :std::vector<ProdSlot*>(),
72 d_active_production_slot(c.d_active_production_slot),
73 d_duration(c.d_duration)
74 {
75 for (std::vector<ProdSlot*>::const_iterator it = c.begin();
76 it != c.end(); it++)
77 push_back(new ProdSlot(*(*it)));
78 }
79
save(XML_Helper * helper) const80 bool ProdSlotlist::save(XML_Helper* helper) const
81 {
82 bool retval = true;
83
84 retval &= helper->saveData("active_production_slot",
85 d_active_production_slot);
86 retval &= helper->saveData("duration", d_duration);
87
88 for (unsigned int i = 0; i < size(); i++)
89 {
90 if ((*this)[i])
91 retval &= (*this)[i]->save(helper);
92 }
93 return retval;
94 }
95
~ProdSlotlist()96 ProdSlotlist::~ProdSlotlist()
97 {
98 for (unsigned int i = 0; i < size(); i++)
99 delete (*this)[i];
100 clear();
101 }
102
getNoOfProductionBases() const103 guint32 ProdSlotlist::getNoOfProductionBases() const
104 {
105 unsigned int max = 0;
106 for (unsigned int i = 0; i < getMaxNoOfProductionBases(); i++)
107 {
108 if (getProductionBase(i))
109 max++;
110 }
111 return max;
112 }
113
setActiveProductionSlot(int index)114 void ProdSlotlist::setActiveProductionSlot(int index)
115 {
116 if (index == -1)
117 {
118 d_active_production_slot = index;
119 d_duration = -1;
120 return;
121 }
122
123 // return on wrong data
124 if (((index >= (int)size())) ||
125 (index >= 0 && getArmytype(index) == -1))
126 return;
127
128 d_active_production_slot = index;
129 const ArmyProdBase* a = getProductionBase(index);
130
131 // set the duration to produce this armytype
132 if (a)
133 d_duration = a->getProduction();
134 }
135
getFreeSlot() const136 int ProdSlotlist::getFreeSlot() const
137 {
138 int index=-1;
139
140 debug(getName()<< " BASIC SLOTS=" << size())
141 for (unsigned int i = 0; i < size(); i++)
142 {
143 debug(getName()<< " Index Value=" << (*this)[i])
144 if ((*this)[i]->getArmyProdBase() == NULL)
145 {
146 index=i;
147 return i;
148 }
149 }
150
151 return index;
152 }
153
hasProductionBase(const ArmyProto * army) const154 bool ProdSlotlist::hasProductionBase(const ArmyProto * army) const
155 {
156 return hasProductionBase(army->getId());
157 }
158
addProductionBase(int idx,ArmyProdBase * army)159 void ProdSlotlist::addProductionBase(int idx, ArmyProdBase *army)
160 {
161 if (idx < 0)
162 {
163 // try to find an unoccupied production slot. If there is none, pick
164 // the slot with the highest index.
165 for (unsigned int i = 0; i < size(); i++)
166 if ((*this)[i]->getArmyProdBase() == NULL)
167 {
168 idx = i;
169 break;
170 }
171
172 if (idx < 0)
173 {
174 idx = size() - 1;
175 }
176 }
177 if (idx >= (int)size())
178 return;
179
180 if ((*this)[idx]->getArmyProdBase())
181 {
182 bool restore_production = false;
183 if (d_active_production_slot == idx)
184 restore_production = true;
185 removeProductionBase(idx);
186 (*this)[idx]->setArmyProdBase(army);
187 if (restore_production)
188 setActiveProductionSlot(idx);
189 }
190 else
191 (*this)[idx]->setArmyProdBase(army);
192 }
193
removeProductionBase(int idx)194 void ProdSlotlist::removeProductionBase(int idx)
195 {
196 if ((idx < 0) || (idx > (int)(getMaxNoOfProductionBases() - 1)))
197 return;
198
199 if ((*this)[idx]->getArmyProdBase() != NULL)
200 (*this)[idx]->clear();
201
202 if (d_active_production_slot == idx)
203 setActiveProductionSlot(-1);
204 }
205
hasProductionBase(int type) const206 bool ProdSlotlist::hasProductionBase(int type) const
207 {
208 if (type < 0)
209 return false;
210 for (unsigned int i = 0; i < size(); i++)
211 {
212 if ((*this)[i]->getArmyProdBase() == NULL)
213 continue;
214 if ((*this)[i]->getArmyProdBase()->getTypeId() == (unsigned int) type)
215 return true;
216 }
217
218 return false;
219 }
220
getArmytype(int slot) const221 int ProdSlotlist::getArmytype(int slot) const
222 {
223 if (slot < 0)
224 return -1;
225
226 if (slot >= (int)size())
227 return -1;
228 if ((*this)[slot]->getArmyProdBase() == NULL)
229 return -1;
230 return (*this)[slot]->getArmyProdBase()->getTypeId();
231 }
232
getProductionBase(int slot) const233 const ArmyProdBase * ProdSlotlist::getProductionBase(int slot) const
234 {
235 if (getArmytype(slot) == -1)
236 return 0;
237 return (*this)[slot]->getArmyProdBase();
238 }
239
getActiveProductionBase() const240 const ArmyProdBase *ProdSlotlist::getActiveProductionBase() const
241 {
242 return getProductionBase(d_active_production_slot);
243 }
244
getProductionBaseBelongingTo(const Army * army) const245 const ArmyProdBase *ProdSlotlist::getProductionBaseBelongingTo(const Army *army) const
246 {
247 if (!army)
248 return NULL;
249 for (unsigned int i = 0; i < this->getMaxNoOfProductionBases(); i++)
250 {
251 const ArmyProdBase* armyprodbase = this->getProductionBase(i);
252 if (armyprodbase == NULL)
253 continue;
254 if (army->getArmyset() == armyprodbase->getArmyset() &&
255 army->getTypeId() == armyprodbase->getTypeId())
256 return armyprodbase;
257 }
258 return NULL;
259 }
260
removeArmyProdBasesWithoutAType(guint32 armyset)261 bool ProdSlotlist::removeArmyProdBasesWithoutAType(guint32 armyset)
262 {
263 bool removed = false;
264 for (unsigned int i = 0; i < size(); i++)
265 {
266 const ArmyProdBase* armyprodbase = this->getProductionBase(i);
267 if (armyprodbase == NULL)
268 continue;
269 ArmyProto *a = Armysetlist::getInstance()->getArmy (armyset, armyprodbase->getTypeId());
270 if (!a)
271 removeProductionBase(i);
272 //XXX XXX XXX should we squeeze out the empty spaces?
273 }
274 return removed;
275 }
276 // End of file
277