1 // Copyright (C) 2009 Ben Asselstine
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.
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.
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
18 #include "stacktile.h"
23 #include "stacklist.h"
24 #include "playerlist.h"
27 StackTile::StackTile(Vector<int> pos)
32 StackTile::~StackTile()
36 bool StackTile::canAdd(const Stack *stack)
38 //it's not a bug if the stack is already on this tile.
39 //two or more stacks have to be on the same stacktile to join.
40 //it's not a bug if more than MAX_ARMIES_ON_A_SINGLE_TILE is exceeded
41 //temporarily. too large stacks can pass through, but not stay.
42 if (findStack(stack) != end())
44 return canAdd(stack->size(), stack->getOwner());
47 bool StackTile::canAdd(guint32 size, Player *owner)
51 if (countNumberOfArmies(owner) + size > MAX_ARMIES_ON_A_SINGLE_TILE)
56 bool StackTile::leaving(Stack *stack)
61 iterator it = findStack(stack);
74 void StackTile::arriving(Stack *stack)
79 void StackTile::add(Stack *stack)
81 iterator it = findStack(stack);
82 if (it != end()) //we replace existing entries, to make this work sans game.
84 struct StackTileRecord rec;
85 rec.stack_id = stack->getId();
86 rec.player_id = stack->getOwner()->getId();
88 //i could stack->setpos here, but i prefer to let Stack::moveToDest do that because it's movement related, and this class is not movement related.
91 guint32 StackTile::countNumberOfArmies(Player *owner) const
94 for (const_iterator it = begin(); it != end(); it++)
96 if ((*it).player_id == owner->getId())
98 Stack *stack = owner->getStacklist()->getStackById((*it).stack_id);
100 count += stack->size();
106 StackTile::iterator StackTile::findStack(Stack *s)
108 for (iterator it = begin(); it != end(); it++)
109 if (s->getId() == (*it).stack_id)
114 StackTile::const_iterator StackTile::findStack(const Stack *s) const
116 for (const_iterator it = begin(); it != end(); it++)
117 if (s->getId() == (*it).stack_id)
122 Stack *StackTile::getStack() const
126 StackTileRecord rec = front();
127 Player *p = Playerlist::getInstance()->getPlayer(rec.player_id);
128 return p->getStacklist()->getStackById(rec.stack_id);
133 std::list<Stack *> StackTile::getStacks() const
135 std::list<Stack *> stacks;
136 for (const_iterator it = begin(); it != end(); it++)
138 Playerlist *pl = Playerlist::getInstance();
139 for (Playerlist::iterator i = pl->begin(); i != pl->end(); i++)
141 Stack *stack = (*i)->getStacklist()->getStackById((*it).stack_id);
143 stacks.push_back(stack);
149 std::list<Stack *> StackTile::getFriendlyStacks(Player *owner) const
151 std::list<Stack *> stacks;
152 for (const_iterator it = begin(); it != end(); it++)
154 if ((*it).player_id != owner->getId())
156 Stack *stack = owner->getStacklist()->getStackById((*it).stack_id);
158 stacks.push_back(stack);
162 Stack *StackTile::getFriendlyStack(Player *owner) const
164 //return just one of the stacks located here, but owned by OWNER
165 for (const_iterator it = begin(); it != end(); it++)
167 if ((*it).player_id != owner->getId())
169 Stack *stack = owner->getStacklist()->getStackById((*it).stack_id);
176 Stack *StackTile::getEnemyStack(Player *owner) const
178 //return just one of the stacks located here, but not owned by OWNER
179 for (const_iterator it = begin(); it != end(); it++)
181 if ((*it).player_id == owner->getId())
183 Player *p = Playerlist::getInstance()->getPlayer((*it).player_id);
184 Stack *stack = p->getStacklist()->getStackById((*it).stack_id);
191 std::list<Stack *> StackTile::getEnemyStacks(Player *owner) const
193 std::list<Stack *> stacks;
194 for (const_iterator it = begin(); it != end(); it++)
196 if ((*it).player_id == owner->getId())
198 Player *p = Playerlist::getInstance()->getPlayer((*it).player_id);
199 Stack *stack = p->getStacklist()->getStackById((*it).stack_id);
201 stacks.push_back(stack);
206 Stack *StackTile::getOtherStack(Stack *stack) const
208 if (findStack(stack) == end())
210 for (const_iterator it = begin(); it != end(); it++)
212 if (stack->getId() != (*it).stack_id)
214 //great, this is a stack id that isn't us.
215 //now go get the stack from somebody's stacklist.
216 if (stack->getOwner()->getId() != (*it).player_id)
218 Player *p = stack->getOwner();
219 Stack *other = p->getStacklist()->getStackById((*it).stack_id);
227 bool StackTile::contains(guint32 id) const
229 for (const_iterator it = begin(); it != end(); it++)
230 if ((*it).stack_id == id)
235 Stack *StackTile::group(Player *owner)
237 return groupStacks(owner, NULL);
240 void StackTile::group(Player *owner, Stack *stack)
242 groupStacks(owner, stack);
246 Stack *StackTile::groupStacks(Player *owner, Stack *stack)
248 std::list<Stack*> stacks = getFriendlyStacks(owner);
251 if (stacks.size() > 0)
252 stack = stacks.front();
254 else if (findStack(stack) == end())
257 for (std::list<Stack*>::iterator i = stacks.begin(); i != stacks.end(); i++)
261 bool joined = owner->stackJoin(stack, *i);
262 assert (joined == true);
267 //! split all of the armies owned by OWNER into a stack by themselves
268 void StackTile::ungroup(Player *owner)
270 std::list<Stack*> stacks = getFriendlyStacks(owner);
271 std::list<Army *> armies;
272 for (std::list<Stack*>::iterator i = stacks.begin(); i != stacks.end(); i++)
275 for (Stack::iterator j = (*i)->begin(); j != (*i)->end(); j++)
279 //skip one army of every stack because it doesn't need a new one.
285 owner->stackSplitArmy(*i, *j);
293 void StackTile::setDefending(Player *owner, bool defending)
295 std::list<Stack *> stks = getFriendlyStacks(owner);
296 for (std::list<Stack *>::iterator it = stks.begin(); it != stks.end(); it++)
297 (*it)->setDefending(defending);
300 void StackTile::setParked(Player *owner, bool parked)
302 std::list<Stack *> stks = getFriendlyStacks(owner);
303 for (std::list<Stack *>::iterator it = stks.begin(); it != stks.end(); it++)
304 (*it)->setParked(parked);