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) 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
24 #include <sigc++/functors/mem_fun.h>
25 #include "ucompose.hpp"
28 #include "QKillHero.h"
29 #include "QuestsManager.h"
30 #include "playerlist.h"
31 #include "stacklist.h"
35 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
38 QuestKillHero::QuestKillHero(QuestsManager& mgr, guint32 hero)
39 : Quest(mgr, hero, Quest::KILLHERO)
41 // find a suitable hero for us
42 Hero *hunted = chooseToKill();
43 assert(hunted); // should never fail, since isFeasible is checked
45 d_victim = hunted->getId();
46 d_targets.push_back(hunted->getOwner()->getStacklist()->getPosition(d_victim));
50 QuestKillHero::QuestKillHero(QuestsManager& q_mgr, XML_Helper* helper)
51 : Quest(q_mgr, helper)
53 helper->getData(d_victim, "to_kill");
54 debug("load: hero_to_kill = " << d_victim);
56 // double and triple check :)
57 Hero *hero = Quest::getHeroById(d_victim);
59 d_targets.push_back(hero->getOwner()->getStacklist()->getPosition(d_victim));
64 QuestKillHero::QuestKillHero(QuestsManager& q_mgr, guint32 hero, guint32 victim)
65 : Quest(q_mgr, hero, Quest::KILLHERO)
69 // double and triple check :)
70 Hero *h = Quest::getHeroById(d_victim);
72 d_targets.push_back(h->getOwner()->getStacklist()->getPosition(d_victim));
77 bool QuestKillHero::isFeasible(guint32 heroId)
79 // chooseToKill returns 0 if no enemy heroes exist
80 return (chooseToKill() != 0);
83 bool QuestKillHero::save(XML_Helper* helper) const
87 retval &= helper->openTag(Quest::d_tag);
88 retval &= Quest::save(helper);
89 retval &= helper->saveData("to_kill", d_victim);
90 retval &= helper->closeTag();
95 std::string QuestKillHero::getProgress() const
99 // add info about the location of the hunted:
101 Quest::getHeroById(d_victim, &s);
103 ss <<_("You're still searching for him...");
104 ss << _("Seen lately near (") << s->getPos().x << ", " << s->getPos().y
109 void QuestKillHero::getSuccessMsg(std::queue<std::string>& msgs) const
111 std::string name = getHeroNameForDeadHero(d_victim);
112 msgs.push(String::ucompose(_("You have slain the wicked hero %1."), name));
115 void QuestKillHero::getExpiredMsg(std::queue<std::string>& msgs) const
117 msgs.push(String::ucompose(_("You could not slay the wicked hero %1"),
118 getHeroNameForDeadHero(d_victim)));
119 msgs.push(_("The hero was slain by someone else!"));
122 void QuestKillHero::initDescription()
124 Hero* v = Quest::getHeroById(d_victim);
125 d_description = String::ucompose(_("Kill the hero named %1, servant of player %2."),
126 v->getName(), v->getOwner()->getName());
129 Hero* QuestKillHero::chooseToKill()
131 std::vector<Hero*> heroes;
133 // Collect all enemy heroes in the vector
134 const Playerlist* pl = Playerlist::getInstance();
135 Player* active = Playerlist::getActiveplayer();
137 for (Playerlist::const_iterator pit = pl->begin(); pit != pl->end(); pit++)
139 if ((*pit) == active)
142 const Stacklist* sl = (*pit)->getStacklist();
143 for (Stacklist::const_iterator it = sl->begin(); it != sl->end(); it++)
144 for (Stack::iterator sit = (*it)->begin(); sit != (*it)->end(); sit++)
145 if ((*sit)->isHero())
146 heroes.push_back(dynamic_cast<Hero*>(*sit));
149 // isFeasible() should depend on this behaviour...
154 return heroes[rand() % heroes.size()];
157 void QuestKillHero::armyDied(Army *a, bool heroIsCulprit)
159 if (!isPendingDeletion())
162 if (!h || h->getHP() <= 0)
168 // is it a hero we were hunting for?
169 if (a->getId() != d_victim)
172 // Answer: yes; now check if he was killed by our hero
173 if (heroIsCulprit == false)
175 /*The Hero was killed by a stack without heroes so the quest expires*/
176 //debug("SORRY: YOUR QUEST 'KILL HERO' HS EXPIRED BECAUSE THE HERO TO KILL WAS KILLED BY ANOTHER ONE");
177 d_q_mgr.questExpired(d_hero);
178 //hopefully this is handled by questsmanager, and not here!
183 debug("CONGRATULATIONS: QUEST 'KILL HERO' IS COMPLETED!");
184 d_q_mgr.questCompleted(d_hero);
191 void QuestKillHero::cityAction(City *c, CityDefeatedAction action,
192 bool heroIsCulprit, int gold)
194 ;//this quest doesn't care what happens to cities