initial commit, lordsawar source, slightly modified
[lordsawar] / src / prodslotlist.cpp
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 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 <stdio.h>
24 #include <algorithm>
25 #include <stdlib.h>
26 #include <sstream>
27 #include "prodslotlist.h"
28 #include "path.h"
29 #include "army.h"
30 #include "armyprodbase.h"
31 #include "hero.h"
32 #include "stacklist.h"
33 #include "stack.h"
34 #include "playerlist.h"
35 #include "armysetlist.h"
36 #include "citylist.h"
37 #include "GameMap.h"
38 #include "vectoredunitlist.h"
39 #include "vectoredunit.h"
40 #include "action.h"
41
42 using namespace std;
43
44 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
45 #define debug(x)
46
47 ProdSlotlist::ProdSlotlist(guint32 numslots)
48      : d_active_production_slot(-1), d_duration(-1)
49 {
50   // Initialise armytypes
51   for (unsigned int i = 0; i < numslots; i++)
52     push_back(new ProdSlot());
53
54 }
55
56 ProdSlotlist::ProdSlotlist(XML_Helper* helper)
57 {
58   clear();
59   helper->getData(d_active_production_slot, "active_production_slot");
60   helper->getData(d_duration, "duration");
61   helper->registerTag(ProdSlot::d_tag, 
62                       sigc::mem_fun(this, &ProdSlotlist::load));
63 }
64
65 bool ProdSlotlist::load(std::string tag, XML_Helper *helper)
66 {
67   if (tag == ProdSlot::d_tag)
68     {
69       push_back(new ProdSlot(helper));
70       return true;
71     }
72   return false;
73 }
74
75 ProdSlotlist::ProdSlotlist(const ProdSlotlist& c)
76     :d_active_production_slot(c.d_active_production_slot), 
77     d_duration(c.d_duration)
78 {
79   for (std::vector<ProdSlot*>::const_iterator it = c.begin(); 
80        it != c.end(); it++)
81       push_back(*it);
82 }
83
84 ProdSlotlist::~ProdSlotlist()
85 {
86 }
87
88 bool ProdSlotlist::save(XML_Helper* helper) const
89 {
90     bool retval = true;
91
92     retval &= helper->saveData("active_production_slot", 
93                                d_active_production_slot);
94     retval &= helper->saveData("duration", d_duration);
95
96     for (unsigned int i = 0; i < size(); i++)
97       {
98         if ((*this)[i])
99           retval &= (*this)[i]->save(helper);
100       }
101     return retval;
102 }
103
104 guint32 ProdSlotlist::getNoOfProductionBases() const
105 {
106   unsigned int max = 0;
107   for (unsigned int i = 0; i < getMaxNoOfProductionBases(); i++)
108     {
109       if (getProductionBase(i))
110         max++;
111     }
112   return max;
113 }
114
115 void ProdSlotlist::setActiveProductionSlot(int index)
116 {
117     if (index == -1)
118     {
119         d_active_production_slot = index;
120         d_duration = -1;
121         return;
122     }
123
124     // return on wrong data
125     if (((index >= (int)size())) || 
126         (index >= 0 && getArmytype(index) == -1))
127         return;
128
129     d_active_production_slot = index;
130     const ArmyProdBase* a = getProductionBase(index);
131
132     // set the duration to produce this armytype
133     if (a)
134         d_duration = a->getProduction(); 
135 }
136
137 int ProdSlotlist::getFreeSlot()  const
138 {
139      int index=-1;
140
141      debug(getName()<< " BASIC SLOTS=" << size()) 
142      for (unsigned int i = 0; i < size(); i++)
143      {
144          debug(getName()<< " Index Value=" << (*this)[i])
145          if ((*this)[i]->getArmyProdBase() == NULL)
146          {
147              index=i;
148              return i;
149          }         
150      }
151
152      return index;
153 }
154
155 bool ProdSlotlist::hasProductionBase(const ArmyProto * army) const
156 {
157   return hasProductionBase(army->getTypeId(), army->getArmyset());
158 }
159
160 void ProdSlotlist::addProductionBase(int idx, ArmyProdBase *army)
161 {
162     if (idx < 0)
163     {
164         // try to find an unoccupied production slot. If there is none, pick 
165         // the slot with the highest index.
166         for (unsigned int i = 0; i < size(); i++)
167             if ((*this)[i]->getArmyProdBase() == NULL)
168             {
169                 idx = i;
170                 break;
171             }
172
173         if (idx < 0)
174         {
175             idx = size() - 1;
176         }
177     }
178     if (idx >= (int)size())
179       return;
180     
181     if ((*this)[idx]->getArmyProdBase())
182       {
183         bool restore_production = false;
184         if (d_active_production_slot == idx)
185           restore_production = true;
186         removeProductionBase(idx);
187         (*this)[idx]->setArmyProdBase(army);
188         if (restore_production)
189           setActiveProductionSlot(idx);
190       }
191     else
192       (*this)[idx]->setArmyProdBase(army);
193 }
194
195 void ProdSlotlist::removeProductionBase(int idx)
196 {
197     if ((idx < 0) || (idx > (int)(getMaxNoOfProductionBases() - 1)))
198         return;
199
200     if ((*this)[idx]->getArmyProdBase() != NULL)
201       (*this)[idx]->clear();
202
203     if (d_active_production_slot == idx)
204         setActiveProductionSlot(-1);
205 }
206
207 bool ProdSlotlist::hasProductionBase(int type, guint32 set) const
208 {
209   if (type < 0)
210     return false;
211   for (unsigned int i = 0; i < size(); i++)
212     {
213       if ((*this)[i]->getArmyProdBase() == NULL)
214         continue;
215       if ((*this)[i]->getArmyProdBase()->getTypeId() == (unsigned int) type)
216         return true;
217     }
218
219   return false;
220 }
221
222 int ProdSlotlist::getArmytype(int slot) const
223 {
224   if (slot < 0)
225     return -1;
226
227   if (slot >= (int)size())
228     return -1;
229   if ((*this)[slot]->getArmyProdBase() == NULL)
230     return -1;
231   return (*this)[slot]->getArmyProdBase()->getTypeId();
232 }
233
234 const ArmyProdBase * ProdSlotlist::getProductionBase(int slot) const
235 {
236   if (getArmytype(slot) == -1)
237     return 0;
238   return (*this)[slot]->getArmyProdBase();
239 }
240
241 const ArmyProdBase *ProdSlotlist::getActiveProductionBase() const
242 {
243   return getProductionBase(d_active_production_slot);
244 }
245
246 const ArmyProdBase *ProdSlotlist::getProductionBaseBelongingTo(const Army *army) const
247 {
248   if (!army)
249     return NULL;
250   for (unsigned int i = 0; i < this->getMaxNoOfProductionBases(); i++)
251     {
252       const ArmyProdBase* armyprodbase = this->getProductionBase(i);
253       if (armyprodbase == NULL)
254         continue;
255       if (army->getArmyset() == armyprodbase->getArmyset() &&
256           army->getTypeId() == armyprodbase->getTypeId())
257         return armyprodbase;
258     }
259   return NULL;
260 }
261 // End of file