initial commit, lordsawar source, slightly modified
[lordsawar] / src / QEnemyArmytype.cpp
1 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
2 //
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.
7 //
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.
12 //
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 
16 //  02110-1301, USA.
17
18 #include <sstream>
19 #include <sigc++/functors/mem_fun.h>
20 #include "ucompose.hpp"
21
22 #include "QEnemyArmytype.h"
23 #include "QuestsManager.h"
24 #include "playerlist.h"
25 #include "stacklist.h"
26 #include "armysetlist.h"
27 #include "GameMap.h"
28
29 using namespace std;
30
31 //go get an existing army type,
32 //with the stipluation that player P's armies are not taken into consideration
33 int getVictimArmytype(Player *p, std::list<Vector<int> >&targets)
34 {
35   std::vector<Army*> specials;
36   Stacklist::const_iterator sit ;
37   Stack::iterator it ;
38   Stacklist *sl;
39   const Playerlist* pl = Playerlist::getInstance();
40   for (Playerlist::const_iterator pit = pl->begin(); pit != pl->end(); pit++)
41     {
42       if ((*pit) == p)
43         continue;
44       sl = (*pit)->getStacklist();
45       for (sit = sl->begin(); sit != sl->end(); sit++)
46         {
47           //is this stack not in a city?  no?  it's a target.
48           if (GameMap::getCity((*sit)->getPos()) == NULL)
49             targets.push_back((*sit)->getPos());
50           for (it = (*sit)->begin(); it != (*sit)->end(); it++)
51             {
52               if ((*it)->getAwardable())
53                 {
54                   specials.push_back((*it));
55                 }
56             }
57         }
58     }
59   if (specials.size() == 0)
60     return -1;
61   else
62     return specials[rand() % specials.size()]->getTypeId();
63 }
64
65 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
66 #define debug(x)
67 QuestEnemyArmytype::QuestEnemyArmytype(QuestsManager& q_mgr, guint32 hero)
68   : Quest(q_mgr, hero, Quest::KILLARMYTYPE)
69 {
70   Player *p = getHero()->getOwner();
71
72   // pick a victim
73   d_type_to_kill = getVictimArmytype (p, d_targets);
74
75   initDescription();
76 }
77
78 QuestEnemyArmytype::QuestEnemyArmytype(QuestsManager& q_mgr, XML_Helper* helper) 
79   : Quest(q_mgr, helper)
80 {
81   helper->getData(d_type_to_kill, "type_to_kill");
82
83   initDescription();
84 }
85
86 QuestEnemyArmytype::QuestEnemyArmytype(QuestsManager& q_mgr, guint32 hero,
87                                        guint32 type_to_kill)
88   : Quest(q_mgr, hero, Quest::KILLARMYTYPE)
89 {
90   // pick a victim
91   d_type_to_kill = type_to_kill;
92
93   initDescription();
94 }
95
96 bool QuestEnemyArmytype::save(XML_Helper *helper) const
97 {
98   bool retval = true;
99
100   retval &= helper->openTag(Quest::d_tag);
101   retval &= Quest::save(helper);
102   retval &= helper->saveData("type_to_kill", d_type_to_kill);
103   retval &= helper->closeTag();
104
105   return retval;
106 }
107
108 std::string QuestEnemyArmytype::getProgress() const
109 {
110   Armysetlist *al = Armysetlist::getInstance();
111   guint32 set = Playerlist::getInstance()->getActiveplayer()->getArmyset();
112   const ArmyProto *a = al->getArmy(set, d_type_to_kill);
113   return String::ucompose(
114                           _("You have not killed a unit of enemy %1 yet."), a->getName());
115 }
116
117 void QuestEnemyArmytype::getSuccessMsg(std::queue<std::string>& msgs) const
118 {
119   Armysetlist *al = Armysetlist::getInstance();
120   guint32 set = Playerlist::getInstance()->getActiveplayer()->getArmyset();
121   const ArmyProto *a = al->getArmy(set, d_type_to_kill);
122   msgs.push(String::ucompose(_("You have killed a unit of enemy %1."), a->getName()));
123   msgs.push(_("Well done!"));
124 }
125
126 void QuestEnemyArmytype::getExpiredMsg(std::queue<std::string>& msgs) const
127 {
128   // This quest should never expire, so this is just a dummy function
129 }
130
131 void QuestEnemyArmytype::initDescription()
132 {
133   Armysetlist *al = Armysetlist::getInstance();
134   guint32 set = Playerlist::getInstance()->getActiveplayer()->getArmyset();
135   const ArmyProto *a = al->getArmy(set, d_type_to_kill);
136   d_description = String::ucompose(_("You must destroy a unit of enemy %1."), 
137                                    a->getName());
138 }
139
140 bool QuestEnemyArmytype::isFeasible(guint32 heroId)
141 {
142   std::list< Vector<int> >targets;
143   int type = getVictimArmytype(getHeroById(heroId)->getOwner(), targets);
144   if (type >= 0)
145     return true;
146   return false;
147 }
148
149 void QuestEnemyArmytype::armyDied(Army *a, bool heroIsCulprit)
150 {
151   //was it the army type we were after?
152
153   debug("QuestEnemyArmytype: armyDied - pending = " << (int)d_pending);
154
155   if (!isPendingDeletion())
156     return;
157   Hero *h = getHero();
158   if (!h || h->getHP() <= 0)
159     {
160       deactivate();
161       return;
162     }
163
164   if (a->getTypeId() == d_type_to_kill)
165     {
166       if (heroIsCulprit)
167         {
168           debug("CONGRATULATIONS: QUEST 'KILL ENEMY ARMYTYPE' IS COMPLETED!");
169           d_q_mgr.questCompleted(d_hero);
170         }
171       else
172         {
173           ; 
174           //hopefully there are more armies of this type for hero to kill
175         }
176     }
177 }
178
179 void QuestEnemyArmytype::cityAction(City *c, CityDefeatedAction action, 
180                                     bool heroIsCulprit, int gold)
181 {
182   ;//this quest doesn't care what happens to cities
183 }