initial commit, lordsawar source, slightly modified
[lordsawar] / src / LocationBox.cpp
diff --git a/src/LocationBox.cpp b/src/LocationBox.cpp
new file mode 100644 (file)
index 0000000..341d314
--- /dev/null
@@ -0,0 +1,214 @@
+// Copyright (C) 2000, 2001, 2003 Michael Bartl
+// Copyright (C) 2000, 2001, 2002, 2004, 2005 Ulf Lorenz
+// Copyright (C) 2006 Andrea Paternesi
+// Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU Library General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
+//  02110-1301, USA.
+
+#include "LocationBox.h"
+#include "army.h"
+#include "player.h"
+#include "playerlist.h"
+#include "stacklist.h"
+#include "stack.h"
+#include "FogMap.h"
+#include "GameMap.h"
+#include "stacktile.h"
+
+#include "xmlhelper.h"
+
+LocationBox::LocationBox(Vector<int> pos, guint32 size)
+    :Immovable(pos), d_size(size)
+{
+}
+
+LocationBox::LocationBox(Vector<int> src, Vector<int> dest)
+    :Immovable(dist(Vector<int>(0,0), src) < dist(Vector<int>(0,0), dest) ?
+              src : dest)
+{
+  if (dest.x > src.x)
+    d_size =  dest.x - src.x + 1;
+  else if (dest.x < src.x)
+    d_size =  src.x - dest.x + 1;
+  else
+    {
+      if (dest.y > src.y)
+       d_size =  dest.y - src.y + 1;
+      else
+       d_size =  src.y - dest.y + 1;
+    }
+}
+
+LocationBox::LocationBox(const LocationBox& loc)
+  : Immovable(loc), d_size(loc.d_size)
+{
+}
+
+LocationBox::LocationBox(const LocationBox& loc, Vector<int> pos)
+  : Immovable(pos), d_size(loc.d_size)
+{
+}
+
+LocationBox::LocationBox(XML_Helper* helper, guint32 size)
+    :Immovable(helper)
+{
+    d_size = size;
+}
+
+LocationBox::~LocationBox()
+{
+}
+
+Stack *LocationBox::addArmy(Army *a) const
+{
+  Vector<int> pos = Vector<int>(-1,-1);
+  Stack* stack = getFreeStack(a->getOwner(), pos);
+
+  //no stacks with enough room for one more army, found lets create one.
+  if (!stack)
+    {
+      // No stack found in the entire location
+      if (pos == Vector<int>(-1,-1))
+       return NULL;
+           
+      Player *p = a->getOwner();
+      stack = new Stack(p, pos);
+      stack->add(a);
+      p->addStack(stack);
+    }
+  else
+    stack->add(a);
+
+  if (stack->size() > 1)
+    stack->sortForViewing(true);
+  stack->setDefending(false);
+  stack->setParked(false);
+  return stack;
+}
+
+bool LocationBox::isFull(Player *p) const
+{
+  for (unsigned int i = 0; i < d_size; i++)
+    for (unsigned int j = 0; j < d_size; j++)
+      {
+       Vector<int> pos = getPos() + Vector<int>(j,i);
+       StackTile *stile = GameMap::getInstance()->getTile(pos)->getStacks();
+       if (stile->canAdd(1, p) == true)
+         return false;
+      }
+    return true;
+}
+
+Stack* LocationBox::getFreeStack(Player *p, Vector<int> &tile) const
+{
+  for (unsigned int i = 0; i < d_size; i++)
+    for (unsigned int j = 0; j < d_size; j++)
+      {
+       Vector<int> pos = getPos() + Vector<int>(j,i);
+       if (GameMap::canAddArmy(pos) == false)
+         continue;
+       StackTile *stile = GameMap::getInstance()->getTile(pos)->getStacks();
+       Stack *stack = stile->getFriendlyStack(p);
+       if (stack == NULL)
+         {
+           tile = pos;
+           return NULL;
+         }
+       else 
+         {
+           Stack *enemy = stile->getEnemyStack(p);
+           if (!enemy && stack->isFull() == false)
+             return stack;
+         }
+        }
+  tile = Vector<int>(-1,-1);
+  return NULL;
+}
+
+bool LocationBox::isVisible(Player *player) const
+{
+  for (unsigned int i = 0; i < d_size; i++)
+    for (unsigned int j = 0; j < d_size; j++)
+      {
+        Vector<int> pos;
+        pos.x = getPos().x + i;
+        pos.y = getPos().y + j;
+       if (FogMap::isClear(pos, player))
+         return true;
+      }
+  return false;
+}
+
+void LocationBox::deFog() const
+{
+  Player *p = Playerlist::getActiveplayer();
+  if (!p)
+    return;
+  FogMap *fogmap = p->getFogMap();
+  fogmap->alterFogRadius (getPos(), 3, FogMap::OPEN);
+}
+
+void LocationBox::deFog(Player *p) const
+{
+  if (!p)
+    return;
+  FogMap *fogmap = p->getFogMap();
+  if (!fogmap)
+    return;
+  fogmap->alterFogRadius (getPos(), 3, FogMap::OPEN);
+}
+
+bool LocationBox::contains(Vector<int> pos) const
+{
+    return (pos.x >= getPos().x) && (pos.x < getPos().x + (int) d_size) 
+      && (pos.y >= getPos().y) && (pos.y < getPos().y + (int) d_size);
+}
+
+    
+bool LocationBox::isCompletelyObscuredByFog(Player *p) const
+{
+  for (unsigned int i = 0; i < d_size; i++)
+    for (unsigned int j = 0; j < d_size; j++)
+      {
+       Vector<int> pos = Vector<int>(i,j);
+       if (p->getFogMap()->isCompletelyObscuredFogTile(pos) == false)
+         return false;
+      }
+  return true;
+}
+
+Vector<int> LocationBox::getNearestPos(Movable *m) const
+{
+  return getNearestPos(m->getPos());
+}
+
+Vector<int> LocationBox::getNearestPos(Vector<int> pos) const
+{
+  int min_dist = -1;
+  Vector<int> closest_tile = Vector<int>(-1,-1);
+  for (unsigned int i = 0; i < d_size; i++)
+    for (unsigned int j = 0; j < d_size; j++)
+      {
+        Vector<int> target = Vector<int>(i,j) + getPos();
+        int d = dist(pos, target);
+        if (d < min_dist || min_dist == -1)
+          {
+            min_dist = d;
+            closest_tile = target;
+          }
+      }
+  return closest_tile;
+}