1 // Copyright (C) 2003, 2004, 2005 Ulf Lorenz
2 // Copyright (C) 2004, 2005, 2006 Andrea Paternesi
3 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
4 // Copyright (C) 2007, 2008 Ole Laursen
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.
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.
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
21 #include <sigc++/functors/mem_fun.h>
23 #include "QuestsManager.h"
26 #include "QKillHero.h"
27 #include "QEnemyArmies.h"
28 #include "QCitySack.h"
29 #include "QCityRaze.h"
30 #include "QCityOccupy.h"
31 #include "QEnemyArmytype.h"
32 #include "QPillageGold.h"
33 #include "stacklist.h"
34 #include "rewardlist.h"
36 #include "xmlhelper.h"
39 std::string QuestsManager::d_tag = "questlist";
41 QuestsManager* QuestsManager::s_instance = NULL;
45 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
49 QuestsManager* QuestsManager::getInstance()
52 s_instance = new QuestsManager();
56 QuestsManager* QuestsManager::getInstance(XML_Helper* helper)
61 s_instance = new QuestsManager(helper);
65 void QuestsManager::deleteInstance()
67 debug("QuestsManager: deleteInstance")
72 QuestsManager::QuestsManager()
77 QuestsManager::QuestsManager(XML_Helper* helper)
80 debug("QuestsManager: registerTag!");
81 helper->registerTag(Quest::d_tag, sigc::mem_fun(this, &QuestsManager::load));
84 QuestsManager::~QuestsManager()
86 std::map<guint32,Quest*>::iterator it;
88 for (it = d_quests.begin(); it != d_quests.end(); it++)
93 Quest* QuestsManager::createNewQuest(guint32 heroId, bool razing_possible)
95 // don't let a hero have more than one quest
96 if (d_quests.count(heroId))
102 which = 1 + rand() % 7;
103 // if this quest is not feasible - try again with another
105 if ((*(d_questsFeasible[which-1]))(heroId) == 0)
108 // ok - this quest can be completed
114 quest = new QuestKillHero(*this, heroId);
117 quest = new QuestEnemyArmies(*this, heroId);
120 quest = new QuestCitySack(*this, heroId);
124 quest = new QuestCityRaze(*this, heroId);
126 quest = new QuestCitySack(*this, heroId);
129 quest = new QuestCityOccupy(*this, heroId);
132 quest = new QuestEnemyArmytype(*this, heroId);
135 quest = new QuestPillageGold(*this, heroId);
141 d_quests[heroId] = quest;
147 Quest* QuestsManager::createNewKillHeroQuest(guint32 heroId, guint32 targetHeroId)
149 Quest *quest = new QuestKillHero(*this, heroId, targetHeroId);
151 d_quests[heroId] = quest;
156 Quest* QuestsManager::createNewEnemyArmiesQuest(guint32 heroId,
158 guint32 victim_player_id)
160 Quest *quest = new QuestEnemyArmies(*this, heroId, num_armies,
163 d_quests[heroId] = quest;
168 Quest* QuestsManager::createNewCitySackQuest(guint32 heroId, guint32 cityId)
170 Quest *quest = new QuestCitySack(*this, heroId, cityId);
172 d_quests[heroId] = quest;
177 Quest* QuestsManager::createNewCityRazeQuest(guint32 heroId, guint32 cityId)
179 Quest *quest = new QuestCityRaze(*this, heroId, cityId);
181 d_quests[heroId] = quest;
186 Quest* QuestsManager::createNewCityOccupyQuest(guint32 heroId, guint32 cityId)
188 Quest *quest = new QuestCityOccupy(*this, heroId, cityId);
190 d_quests[heroId] = quest;
195 Quest* QuestsManager::createNewEnemyArmytypeQuest(guint32 heroId,
198 Quest *quest = new QuestEnemyArmytype(*this, heroId, armyTypeId);
200 d_quests[heroId] = quest;
205 Quest* QuestsManager::createNewPillageGoldQuest(guint32 heroId, guint32 amount)
207 Quest *quest = new QuestPillageGold(*this, heroId, amount);
209 d_quests[heroId] = quest;
214 void QuestsManager::questCompleted(guint32 heroId)
216 Quest *quest = d_quests[heroId];
217 Player *p = quest->getHero()->getOwner();
219 p->heroCompletesQuest(quest->getHero());
220 Stack *stack = p->getStacklist()->getArmyStackById(heroId);
222 int num = rand() % 4;
225 int gold = Reward_Gold::getRandomGoldPieces();
226 Reward_Gold reward(gold);
227 p->giveReward(stack, &reward);
228 quest_completed.emit(quest, &reward);
232 int num = (rand() % 8) + 1;
233 const ArmyProto *a = Reward_Allies::randomArmyAlly();
234 Reward_Allies reward(a, num);
235 p->giveReward(stack, &reward);
236 quest_completed.emit(quest, &reward);
238 History_HeroFindsAllies* item = new History_HeroFindsAllies();
239 item->fillData(quest->getHero());
244 Reward *itemReward = Rewardlist::getInstance()->popRandomItemReward();
247 p->giveReward(stack, itemReward);
248 quest_completed.emit(quest, itemReward);
250 else //no items left to give!
252 int gold = Reward_Gold::getRandomGoldPieces();
253 Reward_Gold reward(gold);
254 p->giveReward(stack, &reward);
255 quest_completed.emit(quest, &reward);
260 Reward *ruinReward = Rewardlist::getInstance()->popRandomRuinReward();
263 p->giveReward(stack, ruinReward);
264 quest_completed.emit(quest, ruinReward);
266 else //no ruins left to give!
268 int gold = Reward_Gold::getRandomGoldPieces();
269 Reward_Gold reward(gold);
270 p->giveReward(stack, &reward);
271 quest_completed.emit(quest, &reward);
275 //debug("deactivate quest");
276 //deactivateQuest(heroId);
277 d_quests.erase(heroId);
278 //debug("quest deactivated");
281 void QuestsManager::questExpired(guint32 heroId)
283 Quest *quest = d_quests[heroId];
288 //quest_expired.emit(quest);
290 debug("deactivate quest");
291 deactivateQuest(heroId);
292 debug("quest deactivated");
295 std::vector<Quest*> QuestsManager::getPlayerQuests(const Player *player) const
297 std::vector<Quest*> res;
298 // loop through the player's heroes
299 // for every hero check any pending quests
300 const Stacklist* sl = player->getStacklist();
301 std::list<Hero*> heroes = sl->getHeroes();
302 for (std::list<Hero*>::iterator it = heroes.begin(); it != heroes.end(); it++)
304 guint32 heroId = (*it)->getId();
306 if (d_quests.count(heroId) > 0)
308 std::map<guint32, Quest*>::const_iterator qit = d_quests.find(heroId);
309 if (qit == d_quests.end())
311 Quest *q = (*qit).second;
312 if (q && q->isPendingDeletion() == true)
314 debug("heroId = " << heroId << " - has quest: " << q);
321 Quest* QuestsManager::getHeroQuest(guint32 hero_id) const
323 std::map<guint32, Quest*>::const_iterator qit;
324 qit = d_quests.find(hero_id);
325 if (qit == d_quests.end())
327 Quest *q = (*qit).second;
328 if (q && q->isPendingDeletion() == true)
330 return (*qit).second;
333 bool QuestsManager::save(XML_Helper* helper) const
335 debug("Saving quests\n");
338 retval &= helper->openTag(QuestsManager::d_tag);
340 for (std::map<guint32,Quest*>::const_iterator it = d_quests.begin();
341 it != d_quests.end(); it++)
343 if ((*it).second == NULL)
345 retval &= ((*it).second)->save(helper);
347 for (std::list<Quest *>::const_iterator it = d_inactive_quests.begin();
348 it != d_inactive_quests.end(); it++)
349 retval &= (*it)->save(helper);
351 debug("Quests saved\n");
352 retval &= helper->closeTag();
356 bool QuestsManager::load(string tag, XML_Helper* helper)
358 debug("QuestsManager: load tag = " << tag);
360 if (tag == Quest::d_tag)
362 guint32 questType, hero;
363 std::string quest_type_str;
364 helper->getData(quest_type_str, "type");
365 questType = Quest::questTypeFromString(quest_type_str);
366 helper->getData(hero, "hero");
368 debug("quest load: type = " << questType << ", heroId = " << hero);
371 switch (static_cast<Quest::Type>(questType)) {
372 case Quest::KILLHERO:
373 quest = new QuestKillHero(*this, helper);
375 case Quest::KILLARMIES:
376 quest = new QuestEnemyArmies(*this, helper);
378 case Quest::CITYSACK:
379 quest = new QuestCitySack(*this, helper);
381 case Quest::CITYRAZE:
382 quest = new QuestCityRaze(*this, helper);
384 case Quest::CITYOCCUPY:
385 quest = new QuestCityOccupy(*this, helper);
387 case Quest::KILLARMYTYPE:
388 quest = new QuestEnemyArmytype(*this, helper);
390 case Quest::PILLAGEGOLD:
391 quest = new QuestPillageGold(*this, helper);
395 debug("quest created: q = " << quest);
398 if (quest->isPendingDeletion())
399 d_inactive_quests.push_back(quest);
401 d_quests[hero] = quest;
410 void QuestsManager::sharedInit()
412 debug("QuestsManager constructor")
414 // now prepare the vector of pointers to the
415 // functions (class static members) checking feasibility
417 d_questsFeasible.push_back(&(QuestKillHero::isFeasible));
418 d_questsFeasible.push_back(&(QuestEnemyArmies::isFeasible));
419 d_questsFeasible.push_back(&(QuestCitySack::isFeasible));
420 d_questsFeasible.push_back(&(QuestCityRaze::isFeasible));
421 d_questsFeasible.push_back(&(QuestCityOccupy::isFeasible));
422 d_questsFeasible.push_back(&(QuestEnemyArmytype::isFeasible));
423 d_questsFeasible.push_back(&(QuestPillageGold::isFeasible));
426 void QuestsManager::deactivateQuest(guint32 heroId)
428 Quest *q = d_quests[heroId];
430 d_inactive_quests.push_back(q);
431 // delete it from hash of active quests
432 d_quests.erase(heroId);
435 void QuestsManager::cleanup(Player::Type type)
437 debug("QuestsManager: cleanup!");
439 std::list<Quest *>::iterator it = d_inactive_quests.begin();
440 while(it != d_inactive_quests.end())
443 it = d_inactive_quests.erase(it);
449 void QuestsManager::armyDied(Army *a, std::vector<guint32>& culprits)
451 //tell all quests that an army died
452 //each quest takes care of what happens when an army dies
453 std::map<guint32,Quest*>::iterator it;
454 for (it = d_quests.begin(); it != d_quests.end(); it++)
456 if ((*it).second == NULL)
458 if ((*it).second->isPendingDeletion() == true)
460 //was this hero a perpetrator?
461 bool heroIsCulprit = false;
462 for (unsigned int i = 0; i <culprits.size(); i++)
464 if (culprits[i] == (*it).second->getHeroId())
466 heroIsCulprit = true;
470 (*it).second->armyDied(a, heroIsCulprit);
473 //is it a hero that has an outstanding quest?
474 //this is what deactivates a quest upon hero death
475 Quest *quest = d_quests[a->getId()];
476 if (quest && quest->isPendingDeletion() == false)
477 questExpired(a->getId());
481 void QuestsManager::cityAction(City *c, Stack *s,
482 CityDefeatedAction action, int gold)
484 std::map<guint32,Quest*>::iterator it;
485 //did any of the heroes who have outstanding quests do this?
486 for (it = d_quests.begin(); it != d_quests.end(); it++)
488 if ((*it).second == NULL)
490 if ((*it).second->isPendingDeletion() == true)
493 (*it).second->cityAction(c, action, false, gold);
496 for (Stack::iterator sit = s->begin(); sit != s->end(); sit++)
498 if ((*it).second == NULL) //fixme: how is this null sometimes?
500 if ((*sit)->getId() == (*it).second->getHeroId())
501 (*it).second->cityAction(c, action, true, gold);
503 (*it).second->cityAction(c, action, false, gold);
509 void QuestsManager::cityRazed(City *c, Stack *s)
511 cityAction(c, s, CITY_DEFEATED_RAZE, 0);
512 //did we raze a city we care about in another quest?
515 void QuestsManager::citySacked(City *c, Stack *s, int gold)
517 cityAction(c, s, CITY_DEFEATED_SACK, gold);
520 void QuestsManager::cityPillaged(City *c, Stack *s, int gold)
522 cityAction(c, s, CITY_DEFEATED_PILLAGE, gold);
525 void QuestsManager::cityOccupied(City *c, Stack *s)
527 cityAction(c, s, CITY_DEFEATED_OCCUPY, 0);
530 void QuestsManager::nextTurn(Player *p)
532 // go through our inactive list and remove quests belonging to us
533 for (std::list<Quest*>::iterator it = d_inactive_quests.begin();
534 it != d_inactive_quests.end(); it++)
536 if ((*it)->getOwner() == p)
539 quest_expired.emit(q);
540 it = d_inactive_quests.erase(it);