initial commit, lordsawar source, slightly modified
[lordsawar] / src / QCitySack.cpp
1 //  Copyright (C) 2007, 2008 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 <iostream>
19 #include <sstream>
20 #include <assert.h>
21 #include <sigc++/functors/mem_fun.h>
22 #include "ucompose.hpp"
23
24 #include "QCitySack.h"
25 #include "QuestsManager.h"
26 #include "citylist.h"
27 #include "playerlist.h"
28 #include "stack.h"
29 #include "xmlhelper.h"
30
31 using namespace std;
32
33 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
34 #define debug(x)
35
36 QuestCitySack::QuestCitySack (QuestsManager& mgr, guint32 hero) 
37   : Quest(mgr, hero, Quest::CITYSACK)
38 {
39   // find us a victim
40   City* c = chooseToSack(getHero()->getOwner());
41   assert(c);      // should never fail because isFeasible is checked first
42
43   d_city = c->getId();
44   d_targets.push_back(c->getPos());
45   debug("city_id = " << d_city);
46   initDescription();
47 }
48
49 QuestCitySack::QuestCitySack (QuestsManager& q_mgr, XML_Helper* helper) 
50   : Quest(q_mgr, helper)
51 {
52   // let us stay in touch with the world...
53   helper->getData(d_city, "city");
54   d_targets.push_back(getCity()->getPos());
55   initDescription();
56 }
57
58 QuestCitySack::QuestCitySack (QuestsManager& mgr, guint32 hero, guint32 target) 
59   : Quest(mgr, hero, Quest::CITYSACK)
60 {
61   d_city = target;
62   d_targets.push_back(getCity()->getPos());
63   initDescription();
64 }
65
66 bool QuestCitySack::isFeasible(guint32 heroId)
67 {
68   if (QuestCitySack::chooseToSack(getHeroById(heroId)->getOwner()))
69     return true;
70   return false;
71 }
72
73 bool QuestCitySack::save(XML_Helper* helper) const
74 {
75   bool retval = true;
76
77   retval &= helper->openTag(Quest::d_tag);
78   retval &= Quest::save(helper);
79   retval &= helper->saveData("city", d_city);
80   retval &= helper->closeTag();
81
82   return retval;
83 }
84
85 std::string QuestCitySack::getProgress() const
86 {
87   return _("You aren't afraid of doing it, are you?");
88 }
89
90 void QuestCitySack::getSuccessMsg(std::queue<std::string>& msgs) const
91 {
92   msgs.push(_("The priests thank you for sacking this evil place."));
93 }
94
95 void QuestCitySack::getExpiredMsg(std::queue<std::string>& msgs) const
96 {
97   const City* c = getCity();
98   msgs.push(String::ucompose(_("The sacking of \"%1\" could not be accomplished."), 
99                              c->getName()));
100 }
101
102 City* QuestCitySack::getCity() const
103 {
104   Citylist* cl = Citylist::getInstance();
105   for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
106     if ((*it)->getId() == d_city)
107       return (*it);
108
109   return 0;
110 }
111
112 void QuestCitySack::initDescription()
113 {
114   const City* c = getCity();
115   d_description = String::ucompose (_("You must take over and sack the city of \"%1\"."), c->getName());
116 }
117
118 City * QuestCitySack::chooseToSack(Player *p)
119 {
120   std::vector<City*> cities;
121
122   // Collect all cities
123   Citylist* cl = Citylist::getInstance();
124   for (Citylist::iterator it = cl->begin(); it != cl->end(); ++it)
125     if (!(*it)->isBurnt() && (*it)->getOwner() != p && 
126         (*it)->getNoOfProductionBases() > 1 &&
127         (*it)->getOwner() != Playerlist::getInstance()->getNeutral())
128       cities.push_back((*it));
129
130   // Find a suitable city for us to sack
131   if (cities.empty())
132     return 0;
133
134   return cities[rand() % cities.size()];
135 }
136
137 void QuestCitySack::armyDied(Army *a, bool heroIsCulprit)
138 {
139   ;
140   //this quest does nothing when an army dies
141 }
142
143 void QuestCitySack::cityAction(City *c, CityDefeatedAction action, 
144                                bool heroIsCulprit, int gold)
145 {
146   if (isPendingDeletion())
147     return;
148   Hero *h = getHero();
149   if (!h || h->getHP() <= 0)
150     {
151       deactivate();
152       return;
153     }
154   if (!c)
155     return;
156   if (c->getId() != d_city)
157     return;
158   //did our hero sack the city? success.
159   //did our hero do something else with the city?  expire.
160   //did another of our stacks take the city?  expire.
161   //did another player take the city? do nothing
162   switch (action)
163     {
164     case CITY_DEFEATED_OCCUPY: //somebody occupied
165       if (heroIsCulprit) //quest hero did
166         d_q_mgr.questExpired(d_hero);
167       else if (c->getOwner() == getHero()->getOwner()) //our stack did
168         d_q_mgr.questExpired(d_hero);
169       break;
170     case CITY_DEFEATED_RAZE: //somebody razed
171       if (heroIsCulprit) // quest hero
172         d_q_mgr.questExpired(d_hero);
173       else if (c->getOwner() == getHero()->getOwner()) // our stack razed
174         d_q_mgr.questExpired(d_hero);
175       else // their stack did
176         d_q_mgr.questExpired(d_hero);
177       break;
178     case CITY_DEFEATED_SACK: //somebody sacked
179       if (heroIsCulprit) // quest hero did
180         d_q_mgr.questCompleted(d_hero);
181       else if (c->getOwner() == getHero()->getOwner()) // our stack did
182         d_q_mgr.questExpired(d_hero);
183       else // their stack did
184         d_q_mgr.questExpired(d_hero);
185       break;
186     case CITY_DEFEATED_PILLAGE: //somebody pillaged
187       if (heroIsCulprit) // quest hero did
188         d_q_mgr.questExpired(d_hero);
189       else if (c->getOwner() == getHero()->getOwner()) // our stack did
190         d_q_mgr.questExpired(d_hero);
191       break;
192     }
193 }