initial commit, lordsawar source, slightly modified
[lordsawar] / src / reward.cpp
diff --git a/src/reward.cpp b/src/reward.cpp
new file mode 100644 (file)
index 0000000..5c96e16
--- /dev/null
@@ -0,0 +1,523 @@
+//  Copyright (C) 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 <stdlib.h>
+#include <sstream>
+#include <vector>
+#include <sigc++/functors/mem_fun.h>
+
+#include "reward.h"
+#include "army.h"
+#include "armysetlist.h"
+#include "playerlist.h"
+#include "ruinlist.h"
+#include "ruin.h"
+#include "rewardlist.h"
+#include "Itemlist.h"
+#include "Item.h"
+#include "GameMap.h"
+#include "ruin.h"
+#include "ucompose.hpp"
+#include "SightMap.h"
+
+std::string Reward::d_tag = "reward";
+
+using namespace std;
+
+Reward::Reward(Type type, std::string name)
+    :d_type(type), d_name(name)
+{
+}
+
+Reward::Reward(XML_Helper *helper)
+{
+  std::string type_str;
+  helper->getData(type_str, "type");
+  d_type = rewardTypeFromString(type_str);
+  helper->getData(d_name, "name");
+}
+
+Reward::Reward (const Reward& orig)
+       :d_type(orig.d_type), d_name(orig.d_name)
+{
+}
+
+Reward::~Reward()
+{
+}
+
+Reward* Reward::handle_load(XML_Helper* helper)
+{
+    guint32 t;
+    std::string type_str;
+    helper->getData(type_str, "type");
+    t = rewardTypeFromString(type_str);
+
+    switch (t)
+    {
+        case Reward::GOLD:
+            return (new Reward_Gold(helper));
+        case Reward::ALLIES:
+            return (new Reward_Allies(helper));
+        case Reward::ITEM:
+            return (new Reward_Item(helper));
+        case Reward::RUIN:
+            return (new Reward_Ruin(helper));
+        case Reward::MAP:
+            return (new Reward_Map(helper));
+    }
+
+    return 0;
+}
+
+Reward_Gold::Reward_Gold(guint32 gold)
+    :Reward(Reward::GOLD), d_gold(gold)
+{
+}
+
+Reward_Gold::Reward_Gold(XML_Helper* helper)
+    :Reward(helper)
+{
+  helper->getData(d_gold, "gold");
+}
+
+Reward_Gold::Reward_Gold (const Reward_Gold & orig)
+       :Reward(orig), d_gold(orig.d_gold)
+{
+}
+
+bool Reward_Gold::save(XML_Helper* helper) const
+{
+  bool retval = true;
+  retval &= helper->openTag(Reward::d_tag);
+  std::string type_str = rewardTypeToString(Reward::Type(d_type));
+  retval &= helper->saveData("type", type_str);
+  retval &= helper->saveData("name", d_name);
+  retval &= helper->saveData("gold", d_gold);
+  retval &= helper->closeTag();
+  return retval;
+}
+
+Reward_Gold::~Reward_Gold()
+{
+}
+
+guint32 Reward_Gold::getRandomGoldPieces()
+{
+  return 310 + (rand() % 1000);
+}
+
+Reward_Allies::Reward_Allies(guint32 army_type, guint32 army_set, guint32 count)
+    :Reward(Reward::ALLIES), d_count(count)
+{
+  Armysetlist *al = Armysetlist::getInstance();
+  d_army_type = army_type;
+  d_army_set = army_set;
+  d_army  = al->getArmy (army_set, army_type);
+}
+
+Reward_Allies::Reward_Allies(const ArmyProto *army, guint32 count)
+    :Reward(Reward::ALLIES), d_count(count)
+{
+  d_army_type = army->getTypeId();
+  d_army_set = army->getArmyset();
+  d_army = army;
+}
+
+Reward_Allies::Reward_Allies(XML_Helper* helper)
+    :Reward(helper)
+{
+  Armysetlist *al = Armysetlist::getInstance();
+  helper->getData(d_count, "num_allies");
+  helper->getData(d_army_type, "ally_type");
+  helper->getData(d_army_set, "ally_armyset");
+  d_army = al->getArmy (d_army_set, d_army_type);
+}
+
+Reward_Allies::Reward_Allies (const Reward_Allies& orig)
+       :Reward(orig), d_army(orig.d_army), d_army_type(orig.d_army_type), 
+       d_army_set(orig.d_army_set), d_count(orig.d_count)
+{
+}
+
+bool Reward_Allies::save(XML_Helper* helper) const
+{
+  bool retval = true;
+  retval &= helper->openTag(Reward::d_tag);
+  std::string type_str = rewardTypeToString(Reward::Type(d_type));
+  retval &= helper->saveData("type", type_str);
+  retval &= helper->saveData("name", d_name);
+  retval &= helper->saveData("num_allies", d_count);
+  retval &= helper->saveData("ally_type", d_army_type);
+  retval &= helper->saveData("ally_armyset", d_army_set);
+  retval &= helper->closeTag();
+  return retval;
+}
+       
+const guint32 Reward_Allies::getRandomAmountOfAllies()
+{
+  int percent = rand() % 100;
+  if (percent < 30)
+    return 1;
+  else if (percent < 50)
+    return 2;
+  else if (percent < 70)
+    return 3;
+  else if (percent < 80)
+    return 4;
+  else if (percent < 85)
+    return 5;
+  else if (percent < 90)
+    return 6;
+  else if (percent < 95)
+    return 7;
+  else if (percent < 100)
+    return 8;
+  else
+    return 1;
+}
+
+const ArmyProto* Reward_Allies::randomArmyAlly()
+{
+  Armysetlist *al = Armysetlist::getInstance();
+  Player *p = Playerlist::getInstance()->getActiveplayer();
+  if (!p)
+    p = Playerlist::getInstance()->getNeutral();
+  return al->getArmyset(p->getArmyset())->getRandomAwardableAlly();
+}
+
+bool Reward_Allies::addAllies(Player *p, Vector<int> pos, const ArmyProto *army, guint32 alliesCount)
+{
+  for (unsigned int i = 0; i < alliesCount; i++)
+    {
+      Army* ally = new Army(*army, p);
+      ally->setUpkeep(0);
+      if (GameMap::getInstance()->addArmyAtPos(pos, ally) == NULL)
+        return false;
+    }
+  return true;
+}
+
+bool Reward_Allies::addAllies(Player *p, Location *l, const Army *army, guint32 alliesCount)
+{
+  for (unsigned int i = 0; i < alliesCount; i++)
+    {
+      Army* ally = new Army(*army, p);
+      ally->setUpkeep(0);
+      if (GameMap::getInstance()->addArmy(l, ally) == NULL)
+        return false;
+    }
+  return true;
+}
+
+
+Reward_Allies::~Reward_Allies()
+{
+}
+
+Reward_Item::Reward_Item(Item *item)
+    :Reward(Reward::ITEM), d_item(item)
+{
+}
+
+bool Reward_Item::loadItem(std::string tag, XML_Helper* helper)
+{
+  if (tag == Item::d_tag)
+    {
+      d_item = new Item(helper);
+      return true;
+    }
+    
+  return false;
+}
+
+Reward_Item::Reward_Item(XML_Helper* helper)
+    :Reward(helper)
+{
+  helper->registerTag(Item::d_tag, sigc::mem_fun(this, &Reward_Item::loadItem));
+}
+
+Reward_Item::Reward_Item (const Reward_Item& orig)
+       :Reward(orig), d_item(orig.d_item)
+{
+}
+
+bool Reward_Item::save(XML_Helper* helper) const
+{
+  bool retval = true;
+  retval &= helper->openTag(Reward::d_tag);
+  std::string type_str = rewardTypeToString(Reward::Type(d_type));
+  retval &= helper->saveData("type", type_str);
+  retval &= helper->saveData("name", d_name);
+  retval &= d_item->save(helper);
+  retval &= helper->closeTag();
+  return retval;
+}
+
+Item *Reward_Item::getRandomItem()
+{
+  Itemlist *il = Itemlist::getInstance();
+  Itemlist::iterator it = il->begin();
+  std::advance(it, rand() % il->size());
+  ItemProto *i = it->second;
+  return new Item(*i);
+}
+
+Reward_Item::~Reward_Item()
+{
+  if (d_item)
+    delete d_item;
+}
+
+Reward_Ruin::Reward_Ruin(Ruin *ruin)
+    :Reward(Reward::RUIN), d_ruin_pos(ruin->getPos())
+{
+}
+
+Reward_Ruin::Reward_Ruin(XML_Helper* helper)
+    :Reward(helper)
+{
+  guint32 x;
+  guint32 y;
+  helper->getData(x, "x");
+  helper->getData(y, "y");
+  d_ruin_pos = Vector<int>(x,y);
+}
+
+Reward_Ruin::Reward_Ruin (const Reward_Ruin& orig)
+       :Reward(orig), d_ruin_pos(orig.d_ruin_pos)
+{
+}
+bool Reward_Ruin::save(XML_Helper* helper) const
+{
+  bool retval = true;
+  retval &= helper->openTag(Reward::d_tag);
+  std::string type_str = rewardTypeToString(Reward::Type(d_type));
+  retval &= helper->saveData("type", type_str);
+  retval &= helper->saveData("name", d_name);
+  retval &= helper->saveData("x", getRuin()->getPos().x);
+  retval &= helper->saveData("y", getRuin()->getPos().y);
+  retval &= helper->closeTag();
+  return retval;
+}
+
+Ruin *Reward_Ruin::getRandomHiddenRuin()
+{
+  std::vector<Ruin *>hidden_ruins;
+  Ruinlist *rl = Ruinlist::getInstance();
+  Rewardlist *rw = Rewardlist::getInstance();
+  for (Ruinlist::iterator it = rl->begin(); it != rl->end(); it++)
+    {
+      if ((*it)->isHidden())
+       if ((*it)->getOwner() == NULL || 
+           (*it)->getOwner() == Playerlist::getInstance()->getNeutral())
+         {
+           //is it already being pointed to by a reward in the rewardlist?
+           bool found = false;
+           for (Rewardlist::iterator i = rw->begin(); i != rw->end(); i++)
+             {
+               if ((*i)->getType() == Reward::RUIN)
+                 {
+                   Ruin *r = static_cast<Reward_Ruin*>(*i)->getRuin();
+                   if (r)
+                     {
+                       if (r->getPos() == (*it)->getPos())
+                         {
+                           found = true;
+                           break;
+                         }
+                     }
+                 }
+             }
+           if (found == false)
+             hidden_ruins.push_back(*it);
+         }
+    }
+ if (hidden_ruins.empty())
+   return NULL;
+ return hidden_ruins[rand() % hidden_ruins.size()];
+}
+
+Reward_Ruin::~Reward_Ruin()
+{
+}
+
+Reward_Map::Reward_Map(Vector<int> pos, std::string name, 
+                      guint32 height, guint32 width)
+    :Reward(Reward::MAP, name)
+{
+  d_sightmap = new SightMap(name, pos, height, width);
+}
+
+bool Reward_Map::loadMap(std::string tag, XML_Helper* helper)
+{
+  if (tag == SightMap::d_tag)
+    {
+      d_sightmap = new SightMap(helper);
+      return true;
+    }
+    
+  return false;
+}
+
+
+Reward_Map::Reward_Map(XML_Helper* helper)
+    :Reward(helper)
+{
+  helper->registerTag(SightMap::d_tag, sigc::mem_fun(this, &Reward_Map::loadMap));
+}
+
+Reward_Map::Reward_Map (const Reward_Map& orig)
+       :Reward(orig)
+{
+  d_sightmap = new SightMap(*orig.d_sightmap);
+}
+
+bool Reward_Map::save(XML_Helper* helper) const
+{
+  bool retval = true;
+  retval &= helper->openTag(Reward::d_tag);
+  std::string type_str = rewardTypeToString(Reward::Type(d_type));
+  retval &= helper->saveData("type", type_str);
+  retval &= helper->saveData("name", d_sightmap->getName());
+  retval &= d_sightmap->save(helper);
+  retval &= helper->closeTag();
+  return retval;
+}
+
+void Reward_Map::getRandomMap(int *x, int *y, int *width, int *height)
+{
+  int map_width = GameMap::getInstance()->getWidth();
+  *x = rand() % (map_width - (map_width / 10));
+  int map_height = GameMap::getInstance()->getHeight();
+  *y = rand() % (map_height - (map_height / 10));
+  *width = ((rand() % (map_width - *x)) + (map_width / 10));
+  *height = ((rand() % (map_height - *y)) + (map_height / 10));
+}
+
+Reward_Map::~Reward_Map()
+{
+  if (d_sightmap)
+    delete d_sightmap;
+}
+
+std::string Reward::getDescription() const
+{
+  Glib::ustring s = "";
+  switch (getType())
+    {
+    case Reward::GOLD:
+       {
+         const Reward_Gold *g = dynamic_cast<const Reward_Gold*>(this);
+         s += String::ucompose(ngettext("%1 Gold Piece", "%1 Gold Pieces", 
+                                        g->getGold()), g->getGold());
+         return s;
+       }
+    case Reward::ALLIES:
+       {
+         const Reward_Allies *a = dynamic_cast<const Reward_Allies *>(this);
+         if (a->getArmy())
+           s += String::ucompose(_("Allies: %1 x %2"), a->getArmy()->getName(),
+                                 a->getNoOfAllies());
+         return s;
+       }
+    case Reward::ITEM:
+       {
+         const Reward_Item *i = dynamic_cast<const Reward_Item *>(this);
+         if (i->getItem())
+           s += String::ucompose(_("Item: %1"), i->getItem()->getName());
+         return s;
+       }
+    case Reward::RUIN:
+       {
+         const Reward_Ruin *r = dynamic_cast<const Reward_Ruin *>(this);
+         if (r->getRuin())
+           s += String::ucompose(_("Site: %1"), r->getRuin()->getName());
+         return s;
+       }
+    case Reward::MAP:
+       {
+         const Reward_Map *m = dynamic_cast<const Reward_Map *>(this);
+         s += String::ucompose(_("Map: %1,%2 %3x%4"), 
+                                 m->getLocation().x,
+                                 m->getLocation().y,
+                                 m->getHeight(),
+                                 m->getWidth());
+         return s;
+       }
+    }
+  return s;
+}
+
+std::string Reward::rewardTypeToString(const Reward::Type type)
+{
+  switch (type)
+    {
+      case Reward::GOLD:
+       return "Reward::GOLD";
+       break;
+      case Reward::ALLIES:
+       return "Reward::ALLIES";
+       break;
+      case Reward::ITEM:
+       return "Reward::ITEM";
+       break;
+      case Reward::RUIN:
+       return "Reward::RUIN";
+       break;
+      case Reward::MAP:
+       return "Reward::MAP";
+       break;
+    }
+  return "Reward::GOLD";
+}
+
+Reward::Type Reward::rewardTypeFromString(const std::string str)
+{
+  if (str.size() > 0 && isdigit(str.c_str()[0]))
+    return Reward::Type(atoi(str.c_str()));
+  if (str == "Reward::GOLD")
+    return Reward::GOLD;
+  else if (str == "Reward::ALLIES")
+    return Reward::ALLIES;
+  else if (str == "Reward::ITEM")
+    return Reward::ITEM;
+  else if (str == "Reward::RUIN")
+    return Reward::RUIN;
+  else if (str == "Reward::MAP")
+    return Reward::MAP;
+  return Reward::GOLD;
+}
+
+Reward* Reward::copy(const Reward* r)
+{
+  switch(r->getType())
+    {
+    case  Reward::GOLD:
+      return (new Reward_Gold(*dynamic_cast<const Reward_Gold*>(r)));
+    case  Reward::ALLIES:
+      return (new Reward_Allies(*dynamic_cast<const Reward_Allies*>(r)));
+    case Reward::ITEM:
+      return (new Reward_Item(*dynamic_cast<const Reward_Item*>(r)));
+    case Reward::RUIN:
+      return (new Reward_Ruin(*dynamic_cast<const Reward_Ruin*>(r)));
+    case Reward::MAP:
+      return (new Reward_Map(*dynamic_cast<const Reward_Map*>(r)));
+    }
+
+  return 0;
+}