initial commit, lordsawar source, slightly modified
[lordsawar] / src / QEnemyArmies.cpp
1 // Copyright (C) 2003, 2004, 2005 Ulf Lorenz
2 // Copyright (C) 2004 Andrea Paternesi
3 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
4 // Copyright (C) 2007, 2008 Ole Laursen
5 //
6 //  This program is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 3 of the License, or
9 //  (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU Library General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
19 //  02110-1301, USA.
20
21 #include <sstream>
22 #include <sigc++/functors/mem_fun.h>
23 #include "ucompose.hpp"
24
25 #include "QEnemyArmies.h"
26 #include "QuestsManager.h"
27 #include "playerlist.h"
28 #include "stacklist.h"
29 #include "GameMap.h"
30
31 using namespace std;
32
33 //go get an existing alive player,
34 //with the stipluation that player P is not taken into consideration
35 Player* getVictimPlayer(Player *p)
36 {
37   std::vector<Player*> players;
38   const Playerlist* pl = Playerlist::getInstance();
39   for (Playerlist::const_iterator it = pl->begin(); it != pl->end(); it++)
40     {
41       if ((*it) != p && (*it)->isDead() == false && (*it) != pl->getNeutral())
42         players.push_back((*it));
43     }
44   if (players.size() == 0)
45     return NULL;
46   else
47     return players[rand() % players.size()];
48 }
49
50 void QuestEnemyArmies::update_targets()
51 {
52   Stacklist::const_iterator sit ;
53   Stacklist *sl = d_victim_player->getStacklist();
54   d_targets.clear();
55   for (sit = sl->begin(); sit != sl->end(); sit++)
56     {
57       //is this not a city location?  no?  then it's a target.
58       if (GameMap::getCity((*sit)->getPos()) == NULL)
59         d_targets.push_back((*sit)->getPos());
60     }
61 }
62
63 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
64 #define debug(x)
65 QuestEnemyArmies::QuestEnemyArmies(QuestsManager& q_mgr, guint32 hero)
66   : Quest(q_mgr, hero, Quest::KILLARMIES), d_killed(0)
67 {
68   // have us be informed when hostilities break out
69   d_victim_player = getVictimPlayer(getHero()->getOwner());
70
71   /** we have to kill 14-20 units: 14 + rand(0..6) */
72   d_to_kill = 14 + (rand() % 7);
73
74   update_targets();
75   initDescription();
76 }
77
78 QuestEnemyArmies::QuestEnemyArmies(QuestsManager& q_mgr, XML_Helper* helper) 
79   : Quest(q_mgr, helper)
80 {
81   guint32 ui;
82
83   helper->getData(d_to_kill, "to_kill");
84   helper->getData(d_killed,  "killed");
85   helper->getData(ui, "victim_player");
86
87   d_victim_player = Playerlist::getInstance()->getPlayer(ui);
88
89   update_targets();
90   initDescription();
91 }
92
93 QuestEnemyArmies::QuestEnemyArmies(QuestsManager& q_mgr, guint32 hero,
94                                    guint32 armies_to_kill, guint32 victim_player)
95   : Quest(q_mgr, hero, Quest::KILLARMIES), d_killed(0)
96 {
97   // have us be informed when hostilities break out
98   d_victim_player = Playerlist::getInstance()->getPlayer(victim_player);
99   d_to_kill = armies_to_kill;
100
101   update_targets();
102   initDescription();
103 }
104
105 bool QuestEnemyArmies::save(XML_Helper *helper) const
106 {
107   bool retval = true;
108
109   retval &= helper->openTag(Quest::d_tag);
110   retval &= Quest::save(helper);
111   retval &= helper->saveData("to_kill", d_to_kill);
112   retval &= helper->saveData("killed",  d_killed);
113   retval &= helper->saveData("victim_player", d_victim_player->getId());
114   retval &= helper->closeTag();
115
116   return retval;
117 }
118
119 std::string QuestEnemyArmies::getProgress() const
120 {
121   return String::ucompose (_("You have killed %1 so far."), d_killed);
122 }
123
124 void QuestEnemyArmies::getSuccessMsg(std::queue<std::string>& msgs) const
125 {
126   msgs.push(String::ucompose(_("You have managed to slaughter %1 armies."), d_killed));
127   msgs.push(_("Well done!"));
128 }
129
130 void QuestEnemyArmies::getExpiredMsg(std::queue<std::string>& msgs) const
131 {
132   // This quest should never expire, so this is just a dummy function
133 }
134
135 void QuestEnemyArmies::initDescription()
136 {
137   d_description = String::ucompose(_("You shall slaughter %1 armies of the treacherous %2."),
138                                    d_to_kill, d_victim_player->getName());
139 }
140
141 bool QuestEnemyArmies::isFeasible(guint32 heroId)
142 {
143   if (getVictimPlayer(getHeroById(heroId)->getOwner()))
144     return true;
145   return false;
146 }
147
148 void QuestEnemyArmies::armyDied(Army *a, bool heroIsCulprit)
149 {
150   if (!isPendingDeletion())
151     return;
152   Hero *h = getHero();
153   if (!h || h->getHP() <= 0)
154     {
155       deactivate();
156       return;
157     }
158
159   if (heroIsCulprit == true && a->getOwner() == d_victim_player)
160     {
161       d_killed++;
162       if (d_killed >= d_to_kill)
163         {
164           debug("CONGRATULATIONS: QUEST 'ENEMY ARMIES' IS COMPLETED!");
165           d_q_mgr.questCompleted(d_hero);
166         }
167     }
168 }
169
170 void QuestEnemyArmies::cityAction(City *c, CityDefeatedAction action, 
171                                   bool heroIsCulprit, int gold)
172 {
173   ;//this quest doesn't care what happens to cities
174 }