1 // Copyright (C) 2000, 2001, 2002, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2004, 2005 Andrea Paternesi
4 // Copyright (C) 2004 John Farrell
5 // Copyright (C) 2005 Bryan Duff
6 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
7 // Copyright (C) 2007, 2008 Ole Laursen
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 3 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 #include <sigc++/functors/mem_fun.h>
32 #include "playerlist.h"
33 #include "stacklist.h"
35 #include "templelist.h"
38 #include "armysetlist.h"
39 #include "real_player.h"
43 #include "network_player.h"
48 #include "heroproto.h"
49 #include "herotemplates.h"
50 #include "Configuration.h"
51 #include "GameScenarioOptions.h"
53 #include "network-action.h"
55 #include "network-history.h"
56 #include "AI_Analysis.h"
57 #include "AI_Allocation.h"
59 #include "QuestsManager.h"
61 #include "vectoredunit.h"
62 #include "ucompose.hpp"
63 #include "armyprodbase.h"
66 #include "MapBackpack.h"
67 #include "PathCalculator.h"
68 #include "stacktile.h"
69 #include "templelist.h"
71 #include "QCityOccupy.h"
72 #include "QCitySack.h"
73 #include "QCityRaze.h"
74 #include "QPillageGold.h"
76 #include "QKillHero.h"
77 #include "QEnemyArmies.h"
78 #include "QEnemyArmytype.h"
79 #include "callback-enums.h"
83 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<flush<<endl;}
86 std::string Player::d_tag = "player";
88 Player::Player(string name, guint32 armyset, Gdk::Color color, int width,
89 int height, Type type, int player_no)
90 :d_color(color), d_name(name), d_armyset(armyset), d_gold(1000),
91 d_dead(false), d_immortal(false), d_type(type), d_upkeep(0), d_income(0),
92 d_observable(true), surrendered(false), abort_requested(false)
97 d_id = fl_counter->getNextId();
98 d_stacklist = new Stacklist();
99 debug("type of " << d_name << " is " << type)
101 d_fogmap = new FogMap(width, height);
103 //initial fight order is the order in which the armies appear
104 //in the default.xml file.
105 guint32 size = Armysetlist::getInstance()->getSize(d_armyset);
106 for (unsigned int i = 0; i < size; i++)
108 d_fight_order.push_back(i);
111 for (unsigned int i = 0 ; i < MAX_PLAYERS; i++)
113 d_diplomatic_state[i] = AT_PEACE;
114 d_diplomatic_proposal[i] = NO_PROPOSAL;
115 d_diplomatic_score[i] = DIPLOMACY_STARTING_SCORE;
117 d_diplomatic_rank = 0;
118 d_diplomatic_title = std::string("");
120 d_triumphs = new Triumphs();
123 Player::Player(const Player& player)
124 :d_color(player.d_color), d_name(player.d_name), d_armyset(player.d_armyset),
125 d_gold(player.d_gold), d_dead(player.d_dead), d_immortal(player.d_immortal),
126 d_type(player.d_type), d_id(player.d_id),
127 d_fight_order(player.d_fight_order), d_upkeep(player.d_upkeep),
128 d_income(player.d_income), d_observable(player.d_observable),
129 surrendered(player.surrendered),abort_requested(player.abort_requested)
131 // as the other player is propably dumped somehow, we need to deep copy
133 d_stacklist = new Stacklist();
134 for (Stacklist::iterator it = player.d_stacklist->begin();
135 it != player.d_stacklist->end(); it++)
137 Stack* mine = new Stack(**it);
138 // change the stack's loyalty
139 mine->setPlayer(this);
140 d_stacklist->add(mine);
144 std::list<Action*>::const_iterator ait;
145 for (ait = player.d_actions.begin(); ait != player.d_actions.end(); ait++)
146 d_actions.push_back(Action::copy(*ait));
149 std::list<History*>::const_iterator pit;
150 for (pit = player.d_history.begin(); pit != player.d_history.end(); pit++)
151 d_history.push_back(History::copy(*pit));
154 d_fogmap = new FogMap(*player.getFogMap());
156 // copy diplomatic states
157 for (unsigned int i = 0 ; i < MAX_PLAYERS; i++)
159 d_diplomatic_state[i] = player.d_diplomatic_state[i];
160 d_diplomatic_proposal[i] = player.d_diplomatic_proposal[i];
161 d_diplomatic_score[i] = player.d_diplomatic_score[i];
163 d_diplomatic_rank = player.d_diplomatic_rank;
164 d_diplomatic_title = player.d_diplomatic_title;
166 d_triumphs = new Triumphs(*player.getTriumphs());
169 Player::Player(XML_Helper* helper)
170 :d_stacklist(0), d_fogmap(0), surrendered(false), abort_requested(false)
172 helper->getData(d_id, "id");
173 helper->getData(d_name, "name");
174 helper->getData(d_gold, "gold");
175 helper->getData(d_dead, "dead");
176 helper->getData(d_immortal, "immortal");
177 std::string type_str;
178 helper->getData(type_str, "type");
179 d_type = playerTypeFromString(type_str);
180 helper->getData(d_upkeep, "upkeep");
181 helper->getData(d_income, "income");
182 helper->getData(d_color, "color");
183 helper->getData(d_armyset, "armyset");
185 // Read in Fight Order. One ranking per army type.
186 std::string fight_order;
187 std::stringstream sfight_order;
189 helper->getData(fight_order, "fight_order");
190 sfight_order.str(fight_order);
191 guint32 size = Armysetlist::getInstance()->getSize(d_armyset);
192 for (unsigned int i = 0; i < size; i++)
195 d_fight_order.push_back(val);
198 // Read in Diplomatic States. One state per player.
199 std::string diplomatic_states;
200 std::stringstream sdiplomatic_states;
201 helper->getData(diplomatic_states, "diplomatic_states");
202 sdiplomatic_states.str(diplomatic_states);
203 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
205 sdiplomatic_states >> val;
206 d_diplomatic_state[i] = DiplomaticState(val);
209 helper->getData(d_diplomatic_rank, "diplomatic_rank");
210 helper->getData(d_diplomatic_title, "diplomatic_title");
212 // Read in Diplomatic Proposals. One proposal per player.
213 std::string diplomatic_proposals;
214 std::stringstream sdiplomatic_proposals;
215 helper->getData(diplomatic_proposals, "diplomatic_proposals");
216 sdiplomatic_proposals.str(diplomatic_proposals);
217 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
219 sdiplomatic_proposals>> val;
220 d_diplomatic_proposal[i] = DiplomaticProposal(val);
223 // Read in Diplomatic Scores. One score per player.
224 std::string diplomatic_scores;
225 std::stringstream sdiplomatic_scores;
226 helper->getData(diplomatic_scores, "diplomatic_scores");
227 sdiplomatic_scores.str(diplomatic_scores);
228 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
230 sdiplomatic_scores >> val;
231 d_diplomatic_score[i] = val;
233 helper->getData(d_observable, "observable");
235 helper->registerTag(Action::d_tag, sigc::mem_fun(this, &Player::load));
236 helper->registerTag(History::d_tag, sigc::mem_fun(this, &Player::load));
237 helper->registerTag(Stacklist::d_tag, sigc::mem_fun(this, &Player::load));
238 helper->registerTag(FogMap::d_tag, sigc::mem_fun(this, &Player::load));
239 helper->registerTag(Triumphs::d_tag, sigc::mem_fun(this, &Player::load));
247 //d_stacklist->flClear();
255 d_fight_order.clear();
258 Player* Player::create(std::string name, guint32 armyset, Gdk::Color color, int width, int height, Type type)
263 return (new RealPlayer(name, armyset, color, width, height));
265 return (new AI_Fast(name, armyset, color, width, height));
267 return (new AI_Dummy(name, armyset, color, width, height));
269 return (new AI_Smart(name, armyset, color, width, height));
271 return (new NetworkPlayer(name, armyset, color, width, height));
277 Player* Player::create(Player* orig, Type type)
282 return new RealPlayer(*orig);
284 return new AI_Fast(*orig);
286 return new AI_Dummy(*orig);
288 return new AI_Smart(*orig);
290 return new NetworkPlayer(*orig);
296 void Player::initTurn()
299 History_StartTurn* item = new History_StartTurn();
301 Action_InitTurn* action = new Action_InitTurn();
305 void Player::setColor(Gdk::Color c)
310 void Player::addGold(int gold)
313 schangingStats.emit();
316 void Player::withdrawGold(int gold)
320 d_gold = 0; /* bankrupt. should we start turning off city production? */
321 schangingStats.emit();
324 std::string Player::getName(bool translate) const
332 void Player::dumpActionlist() const
334 for (list<Action*>::const_iterator it = d_actions.begin();
335 it != d_actions.end(); it++)
337 cerr <<(*it)->dump() << endl;
341 void Player::dumpHistorylist() const
343 for (list<History*>::const_iterator it = d_history.begin();
344 it != d_history.end(); it++)
346 cerr <<(*it)->dump() << endl;
350 void Player::clearActionlist()
352 for (list<Action*>::iterator it = d_actions.begin();
353 it != d_actions.end(); it++)
360 void Player::clearHistorylist()
362 for (list<History*>::iterator it = d_history.begin();
363 it != d_history.end(); it++)
370 void Player::addStack(Stack* stack)
372 stack->setPlayer(this);
373 d_stacklist->add(stack);
376 bool Player::deleteStack(Stack* stack)
378 if (isComputer() == true)
380 AI_Analysis::deleteStack(stack->getId());
381 AI_Allocation::deleteStack(stack);
383 return d_stacklist->flRemove(stack);
391 void Player::doKill()
397 d_observable = false;
398 History_PlayerVanquished* item;
399 item = new History_PlayerVanquished();
403 //drop the bags of stuff that the heroes might be carrying
404 std::list<Hero*> h = getHeroes();
405 for (std::list<Hero*>::iterator it = h.begin(); it != h.end(); it++)
407 Stack *s = d_stacklist->getArmyStackById((*it)->getId());
411 //get rid of all of the other stacks.
412 d_stacklist->flClear();
414 // Since in some cases the player can be killed rather innocently
415 // (using reactions), we also need to clear the player's traces in the
417 Citylist* cl = Citylist::getInstance();
418 for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
419 if ((*it)->getOwner() == this && (*it)->isBurnt() == false)
420 Playerlist::getInstance()->getNeutral()->takeCityInPossession(*it);
422 d_diplomatic_rank = 0;
423 d_diplomatic_title = std::string("");
426 bool Player::save(XML_Helper* helper) const
430 retval &= helper->saveData("id", d_id);
431 retval &= helper->saveData("name", d_name);
432 retval &= helper->saveData("color", d_color);
433 retval &= helper->saveData("armyset", d_armyset);
434 retval &= helper->saveData("gold", d_gold);
435 retval &= helper->saveData("dead", d_dead);
436 retval &= helper->saveData("immortal", d_immortal);
437 std::string type_str = playerTypeToString(Player::Type(d_type));
438 retval &= helper->saveData("type", type_str);
439 debug("type of " << d_name << " is " << d_type)
440 retval &= helper->saveData("upkeep", d_upkeep);
441 retval &= helper->saveData("income", d_income);
443 // save the fight order, one ranking per army type
444 std::stringstream fight_order;
445 for (std::list<guint32>::const_iterator it = d_fight_order.begin();
446 it != d_fight_order.end(); it++)
448 fight_order << (*it) << " ";
450 retval &= helper->saveData("fight_order", fight_order.str());
452 // save the diplomatic states, one state per player
453 std::stringstream diplomatic_states;
454 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
456 diplomatic_states << d_diplomatic_state[i] << " ";
458 retval &= helper->saveData("diplomatic_states", diplomatic_states.str());
460 retval &= helper->saveData("diplomatic_rank", d_diplomatic_rank);
461 retval &= helper->saveData("diplomatic_title", d_diplomatic_title);
463 // save the diplomatic proposals, one proposal per player
464 std::stringstream diplomatic_proposals;
465 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
467 diplomatic_proposals << d_diplomatic_proposal[i] << " ";
469 retval &= helper->saveData("diplomatic_proposals",
470 diplomatic_proposals.str());
472 // save the diplomatic scores, one score per player
473 std::stringstream diplomatic_scores;
474 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
476 diplomatic_scores << d_diplomatic_score[i] << " ";
478 retval &= helper->saveData("diplomatic_scores", diplomatic_scores.str());
480 retval &= helper->saveData("observable", d_observable);
482 //save the actionlist
483 for (list<Action*>::const_iterator it = d_actions.begin();
484 it != d_actions.end(); it++)
485 retval &= (*it)->save(helper);
487 //save the pasteventlist
488 for (list<History*>::const_iterator it = d_history.begin();
489 it != d_history.end(); it++)
490 retval &= (*it)->save(helper);
492 retval &= d_stacklist->save(helper);
493 retval &= d_fogmap->save(helper);
494 retval &= d_triumphs->save(helper);
499 Player* Player::loadPlayer(XML_Helper* helper)
502 std::string type_str;
503 helper->getData(type_str, "type");
504 type = playerTypeFromString(type_str);
509 return new RealPlayer(helper);
511 return new AI_Fast(helper);
513 return new AI_Smart(helper);
515 return new AI_Dummy(helper);
517 return new NetworkPlayer(helper);
523 bool Player::load(string tag, XML_Helper* helper)
525 if (tag == Action::d_tag)
528 action = Action::handle_load(helper);
529 d_actions.push_back(action);
531 if (tag == History::d_tag)
534 history = History::handle_load(helper);
535 d_history.push_back(history);
538 if (tag == Stacklist::d_tag)
539 d_stacklist = new Stacklist(helper);
541 if (tag == FogMap::d_tag)
542 d_fogmap = new FogMap(helper);
544 if (tag == Triumphs::d_tag)
545 d_triumphs = new Triumphs(helper);
550 void Player::addAction(Action *action)
552 d_actions.push_back(action);
553 NetworkAction *copy = new NetworkAction(action, getId());
555 //free'd in game-server
558 void Player::addHistory(History *history)
560 d_history.push_back(history);
561 NetworkHistory *copy = new NetworkHistory(history, getId());
562 history_written.emit(copy);
563 //free'd in game-server
567 guint32 Player::getScore() const
569 //go get our last published score in the history
571 std::list<History*>::const_iterator it = d_history.begin();
572 for (; it != d_history.end(); it++)
574 if ((*it)->getType() == History::SCORE)
575 score = static_cast<History_Score*>(*it)->getScore();
580 void Player::calculateUpkeep()
583 Stacklist *sl = getStacklist();
584 for (Stacklist::iterator i = sl->begin(), iend = sl->end(); i != iend; ++i)
585 d_upkeep += (*i)->getUpkeep();
588 void Player::calculateIncome()
591 Citylist *cl = Citylist::getInstance();
592 for (Citylist::iterator i = cl->begin(), iend = cl->end(); i != iend; ++i)
594 if ((*i)->getOwner() == this)
595 d_income += (*i)->getGold();
599 void Player::doSetFightOrder(std::list<guint32> order)
601 d_fight_order = order;
604 void Player::setFightOrder(std::list<guint32> order)
606 doSetFightOrder(order);
608 Action_FightOrder * item = new Action_FightOrder();
609 item->fillData(order);
613 bool Player::doStackSplitArmy(Stack *s, Army *a, Stack *& new_stack)
615 new_stack = s->splitArmy(a);
616 if (new_stack != NULL)
625 bool Player::doStackSplitArmies(Stack *stack, std::list<guint32> armies,
628 new_stack = stack->splitArmies(armies);
629 if (new_stack != NULL)
637 Stack *Player::stackSplitArmies(Stack *stack, std::list<guint32> armies)
639 Stack *new_stack = NULL;
640 bool retval = doStackSplitArmies(stack, armies, new_stack);
643 Action_Split* item = new Action_Split();
644 item->fillData(stack, new_stack);
650 Stack *Player::stackSplitArmy(Stack *stack, Army *a)
652 Stack *new_stack = NULL;
653 bool retval = doStackSplitArmy(stack, a, new_stack);
656 Action_Split* item = new Action_Split();
657 item->fillData(stack, new_stack);
663 void Player::doStackJoin(Stack* receiver, Stack* joining)
665 receiver->join(joining);
666 deleteStack(joining);
667 //d_stacklist->flRemove(joining);
669 d_stacklist->setActivestack(receiver);
672 bool Player::stackJoin(Stack* receiver, Stack* joining)
675 if ((receiver == 0) || (joining == 0))
677 debug("Player::stackJoin("<<receiver->getId()<<","<<joining->getId()<<")");
679 assert (receiver->getPos() == joining->getPos());
680 if (GameMap::canJoin(joining, receiver) == false)
683 Action_Join* item = new Action_Join();
684 item->fillData(receiver, joining);
687 doStackJoin(receiver, joining);
689 supdatingStack.emit(0);
693 bool Player::stackSplitAndMove(Stack* s, Stack *& new_stack)
695 if (s->hasPath() == false)
697 Vector<int> pos = s->getLastReachablePointInPath();
698 if (pos == Vector<int>(-1,-1))
700 Stack *join = GameMap::getFriendlyStack(pos);
702 return stackSplitAndMoveToJoin(s, join, new_stack);
704 return stackSplitAndMoveToAttack(s, new_stack);
707 bool Player::stackSplitAndMoveToJoin(Stack* s, Stack *join, Stack *& new_stack)
709 //the stack can't get there, but maybe part of the stack can.
710 if (s->hasPath() == false)
713 std::list<guint32> ids;
714 ids = s->determineReachableArmies(s->getLastPointInPath());
717 //if they're all reachable and we can join, just move them
718 if (ids.size() == s->size() && GameMap::canJoin(s, join) == true)
721 //let's take who we can fit.
722 if (ids.size() > join->getMaxArmiesToJoin())
724 int diff = ids.size() - join->getMaxArmiesToJoin();
725 for (int i = 0; i < diff; i++)
731 //okay, ids.size armies can make the move. but can that tile accept it?
732 new_stack = stackSplitArmies(s, ids);
735 setActivestack(new_stack);
736 return stackMove(new_stack);
737 //if (getActivestack() != NULL)
738 //GameMap::groupStacks(new_stack);
743 bool Player::stackSplitAndMoveToAttack(Stack* s, Stack *& new_stack)
745 //the stack can't get there, but maybe part of the stack can.
746 if (s->getPath()->empty())
749 std::list<guint32> ids;
750 ids = s->determineReachableArmies(s->getLastPointInPath());
753 if (ids.size() == s->size())
756 new_stack = stackSplitArmies(s, ids);
759 setActivestack(new_stack);
760 return stackMove(new_stack);
765 bool Player::stackMove(Stack* s)
767 debug("Player::stackMove(Stack*)")
769 if (s->getPath()->empty())
774 MoveResult *result = stackMove(s, s->getLastPointInPath(), true);
775 bool ret = result->didSomething();//result->moveSucceeded();
782 bool Player::nextStepOnEnemyStackOrCity(Stack *s) const
784 Vector<int> dest = s->getFirstPointInPath();
785 if (dest != Vector<int>(-1,-1))
787 if (GameMap::getEnemyStack(dest))
789 if (GameMap::getEnemyCity(dest))
795 MoveResult *Player::stackMove(Stack* s, Vector<int> dest)
797 if (dest == Vector<int>(-1,-1))
798 return stackMove(s, dest, true);
800 return stackMove(s, dest, false);
803 MoveResult *Player::stackMove(Stack* s, Vector<int> dest, bool follow)
806 debug("Player::stack_move()");
807 //if follow is set to true, follow an already calculated way, else
811 s->getPath()->calculate(s, dest);
814 if (s->getPath()->empty())
816 MoveResult *result = new MoveResult;
817 result->setReachedEndOfPath(true);
822 int moves_left = s->getPath()->getMovesExhaustedAtPoint();
825 if (abortRequested())
827 MoveResult *result = new MoveResult;
828 result->fillData(s, stepCount);
829 result->setMoveAborted(true);
832 if (s->getPath()->size() <= 1)
834 if (nextStepOnEnemyStackOrCity(s) == true)
838 step = stackMoveOneStep(s);
840 step = stackMoveOneStepOverTooLargeFriendlyStacks(s);
845 supdatingStack.emit(0);
853 //the idea here is that we're one move away from our destination.
854 //but in some cases we've already reached the end of the path
855 //because a fight has to happen.
857 //did we jump over a too large friendly stack to an enemy stack or city?
859 //alright, we've walked up to the last place in the path.
860 if (s->getPath()->size() >= 1 && s->enoughMoves())
861 //now look for fight targets, joins etc.
864 Vector<int> pos = s->getFirstPointInPath();
865 City* city = GameMap::getCity(pos);
866 Stack* target =GameMap::getStack(pos);
869 //first fight_city to avoid ambiguity with fight_army
870 if (city && (city->getOwner() != this) && (!city->isBurnt()))
872 bool treachery = false;
873 if (this->getDiplomaticState (city->getOwner()) != AT_WAR)
875 if (streacheryStack.emit (s, city->getOwner(),
876 city->getPos()) == false)
878 //we decided not to be treacherous
879 s->getPath()->clear();
880 MoveResult *moveResult = new MoveResult;
881 moveResult->setConsideredTreachery(true);
882 moveResult->fillData(s, stepCount);
888 MoveResult *moveResult = new MoveResult;
889 moveResult->setTreachery(treachery);
890 moveResult->setConsideredTreachery(treachery);
891 if (stackMoveOneStep(s))
897 moveResult->fillData(s, stepCount);
898 shaltedStack.emit(s);
902 moveResult->fillData(s, stepCount);
903 Fight::Result result;
904 vector<Stack*> def_in_city = city->getDefenders();
905 if (!def_in_city.empty())
907 // This is a hack to circumvent the limitations of stackFight.
909 target = def_in_city[0];
911 result = stackFight(&s, &target);
914 result = Fight::ATTACKER_WON;
916 moveResult->setFightResult(result);
918 // We may only take the city if we have defeated all defenders
919 if (result == Fight::ATTACKER_WON)
921 adjustDiplomacyFromConqueringCity(city);
922 conquerCity(city, s);
923 invadeCity(city); //let AIs determine what to do with city
924 shaltedStack.emit(s);
927 cityfight_finished(city, result);
928 supdatingStack.emit(0);
933 //another friendly stack => share the tile if we're human
934 else if (target && target->getOwner() == this /*&&
935 getType() == Player::HUMAN*/)
937 MoveResult *moveResult = new MoveResult;
939 if (stackMoveOneStep(s))
945 moveResult->setTooLargeStackInTheWay(true);
947 supdatingStack.emit(0);
948 shaltedStack.emit(d_stacklist->getActivestack());
950 moveResult->fillData(s, stepCount);
954 //enemy stack => fight
957 bool treachery = false;
958 if (this->getDiplomaticState (target->getOwner()) == AT_PEACE)
960 if (streacheryStack.emit (s, target->getOwner(),
961 target->getPos()) == false)
963 s->getPath()->clear();
964 MoveResult *moveResult = new MoveResult;
965 moveResult->setConsideredTreachery(true);
966 moveResult->fillData(s, stepCount);
972 MoveResult *moveResult = new MoveResult;
973 moveResult->setTreachery(treachery);
974 moveResult->setConsideredTreachery(treachery);
976 moveResult->fillData(s, stepCount);
977 Fight::Result result = stackFight(&s, &target);
978 moveResult->setFightResult(result);
981 if (stackMoveOneStep(s))
983 moveResult->fillData(s, stepCount);
986 supdatingStack.emit(0);
987 if (result == Fight::ATTACKER_WON)
988 shaltedStack.emit(s);
993 if (stackMoveOneStep(s))
995 supdatingStack.emit(0);
999 shaltedStack.emit(s);
1001 MoveResult *moveResult = new MoveResult;
1002 moveResult->fillData(s, stepCount);
1005 else if (s->getPath()->size() >= 1 && s->enoughMoves() == false)
1008 MoveResult *moveResult = new MoveResult;
1009 moveResult->fillData(s, stepCount);
1010 /* if we can't attack a city, don't remember it in the stack's path. */
1011 Vector<int> pos = s->getFirstPointInPath();
1012 City* city = GameMap::getCity(pos);
1013 if (city && city->getOwner() != this)
1019 MoveResult *moveResult = new MoveResult;
1020 moveResult->setStepCount(stepCount);
1025 bool Player::stackMoveOneStepOverTooLargeFriendlyStacks(Stack *s)
1030 if (!s->enoughMoves())
1033 if (s->getPath()->size() <= 1)
1036 Vector<int> dest = s->getFirstPointInPath();
1037 Stack *another_stack = GameMap::getStack(dest);
1041 if (another_stack->getOwner() != s->getOwner())
1044 if (d_stacklist->canJumpOverTooLargeStack(s) == false)
1047 Action_Move* item = new Action_Move();
1048 item->fillData(s, dest);
1051 s->moveOneStep(true);
1055 bool Player::stackMoveOneStep(Stack* s)
1062 if (!s->enoughMoves())
1065 Vector<int> dest = s->getFirstPointInPath();
1067 Stack *another_stack = GameMap::getStack(dest);
1070 if (another_stack->getOwner() == s->getOwner())
1072 if (GameMap::canJoin(s,another_stack) == false)
1077 //if we're attacking, then jump onto the square with the enemy.
1078 if (s->getPath()->size() != 1)
1083 Action_Move* item = new Action_Move();
1084 item->fillData(s, dest);
1092 void Player::cleanupAfterFight(std::list<Stack*> &attackers,
1093 std::list<Stack*> &defenders)
1095 // get attacker and defender heroes and more...
1096 std::vector<guint32> attackerHeroes, defenderHeroes;
1098 getHeroes(attackers, attackerHeroes);
1099 getHeroes(defenders, defenderHeroes);
1101 // here we calculate also the total XP to add when a player have a battle
1102 // clear dead defenders
1103 debug("clean dead defenders");
1104 double defender_xp = removeDeadArmies(defenders, attackerHeroes);
1106 // and dead attackers
1107 debug("clean dead attackers");
1108 double attacker_xp = removeDeadArmies(attackers, defenderHeroes);
1110 debug("after fight: attackers empty? " << attackers.empty()
1111 << "(" << attackers.size() << ")");
1113 if (!attackers.empty() && defender_xp != 0)
1114 updateArmyValues(attackers, defender_xp);
1116 if (attacker_xp != 0)
1117 updateArmyValues(defenders, attacker_xp);
1119 supdatingStack.emit(0);
1122 Fight::Result Player::stackFight(Stack** attacker, Stack** defender)
1124 debug("stackFight: player = " << getName()<<" at position "
1125 <<(*defender)->getPos().x<<","<<(*defender)->getPos().y);
1127 // save the defender's player for future use
1128 Player* pd = (*defender)->getOwner();
1130 // I suppose, this should be always true, but one can never be sure
1131 bool attacker_active = *attacker == d_stacklist->getActivestack();
1133 Fight fight(*attacker, *defender);
1134 fight.battle(GameScenarioOptions::s_intense_combat);
1136 fight_started.emit(fight);
1139 // add a fight item about the combat
1140 Action_Fight* item = new Action_Fight();
1141 item->fillData(&fight);
1144 std::list<Stack *> attackers = fight.getAttackers(),
1145 defenders = fight.getDefenders();
1147 cleanupAfterFight(attackers, defenders);
1149 // Set the attacker and defender stack to 0 if neccessary. This is a great
1150 // help for the functions calling stackFight (e.g. if a stack attacks
1151 // another stack and destroys it without winning the battle, it may take the
1152 // position of this stack)
1154 // First, the attacker...
1156 std::find(d_stacklist->begin(), d_stacklist->end(), *attacker)
1157 != d_stacklist->end();
1162 if (attacker_active)
1163 d_stacklist->setActivestack(0);
1166 // ...then the defender.
1170 std::find(pd->getStacklist()->begin(), pd->getStacklist()->end(),
1171 *defender) != pd->getStacklist()->end();
1177 return fight.getResult();
1182 * To help factor in the advantage of hero experience/strength and
1183 * ruin-monster strength as well as the stack strength, I think you'll
1184 * find it'll be easier to calculate in terms of the odds of failure [than
1185 * the odds of success]. A new hero (minimum strength) with nothing in
1186 * the stack to help him might have 10-20% odds of failure at a wimpy ruin.
1187 * The same novice hero facing a dragon in the ruin might have 50% odds of
1188 * failure. So a rule of thumb would be to start with a 25% chance of
1189 * failure. The odds would be doubled by the worst monster and halved by
1190 * the easiest. I agree that a strength-9 hero with 8 in the stack should i
1191 * definitely be at 99%. A reasonable formula might be:
1193 * OddsOfFailure = BaseOdds * MonsterFactor * StackFactor * HeroFactor,
1198 * MonsterFactor = 2, 1 or 0.5 depending on hard vs. easy
1200 * StackFactor = (9 - SizeOfStack)/8,
1202 * HeroFactor = (10-StrengthOfHero)/5.
1204 Fight::Result ruinfight (Stack **attacker, Stack **defender)
1207 Fight::Result result;
1208 guint32 hero_strength, monster_strength;
1209 hero_strength = (*attacker)->getFirstHero()->getStat(Army::STRENGTH, true);
1210 monster_strength = (*defender)->getStrongestArmy()->getStat(Army::STRENGTH, true);
1211 float base_factor = 0.28;
1212 float stack_factor = ((float)(MAX_STACK_SIZE + 1) - (*attacker)->size()) / (float)MAX_STACK_SIZE;
1213 float hero_factor = (10.0 - hero_strength) / 5.0;
1214 float monster_factor;
1215 if (monster_strength >= 8)
1216 monster_factor = 2.0;
1217 else if (monster_strength >= 6)
1218 monster_factor = 1.0;
1220 monster_factor = 0.5;
1221 float fail = base_factor * monster_factor * stack_factor * hero_factor;
1223 if (rand() % 100 > (int)(fail * 100.0))
1225 result = Fight::ATTACKER_WON;
1227 for (Stack::iterator sit = loser->begin(); sit != loser->end();)
1235 result = Fight::DEFENDER_WON;
1237 loser->getFirstHero()->setHP(0); /* only the hero dies */
1243 Fight::Result Player::stackRuinFight (Stack **attacker, Stack **defender)
1245 Fight::Result result = Fight::DRAW;
1246 if (*defender == NULL)
1247 return Fight::ATTACKER_WON;
1248 debug("stackRuinFight: player = " << getName()<<" at position "
1249 <<(*defender)->getPos().x<<","<<(*defender)->getPos().y);
1251 ruinfight_started.emit(*attacker, *defender);
1252 result = ruinfight (attacker, defender);
1253 ruinfight_finished.emit(result);
1257 // add a ruin fight item about the combat
1258 //Action_RuinFight* item = new Action_RuinFight();
1259 //item->fillData(*attacker, *defender, result);
1261 /* FIXME: do we need an Action_RuinFight? */
1263 // get attacker and defender heroes and more...
1264 std::list<Stack*> attackers;
1265 attackers.push_back(*attacker);
1266 std::list<Stack*> defenders;
1267 defenders.push_back(*defender);
1269 cleanupAfterFight(attackers, defenders);
1274 bool Player::treachery (Stack *stack, Player *player, Vector <int> pos)
1276 return streachery.emit(stack, player, pos);
1279 Reward* Player::stackSearchRuin(Stack* s, Ruin* r)
1281 Reward *retReward = NULL;
1282 debug("Player::stack_search_ruin");
1284 //throw out impossible actions
1285 if ((s->getPos().x != r->getPos().x) ||
1286 (s->getPos().y != r->getPos().y))
1288 cerr << "Error: searching stack and ruin to be searched not on same position\n" ;
1292 if (r->isSearched())
1295 // start the action item
1296 Action_Ruin* item = new Action_Ruin();
1297 item->fillData(r, s);
1299 Stack* keeper = r->getOccupant();
1303 stackRuinFight(&s, &keeper);
1305 // did the explorer not win?
1306 if (keeper && !keeper->empty())
1308 item->setSearched(false);
1321 History_FoundSage* history = new History_FoundSage();
1322 history->fillData(dynamic_cast<Hero *>(s->getFirstHero()));
1323 addHistory(history);
1327 if (r->getReward() == NULL)
1328 r->populateWithRandomReward();
1331 retReward = r->getReward();
1333 r->setSearched(true);
1334 r->setOwner(s->getOwner());
1336 item->setSearched(true);
1339 History_HeroRuinExplored *history_item = new History_HeroRuinExplored();
1340 history_item->fillData(dynamic_cast<Hero*>(s->getFirstHero()), r);
1341 addHistory(history_item);
1343 supdatingStack.emit(0);
1347 int Player::doStackVisitTemple(Stack *s, Temple *t)
1349 // you have your stack blessed (+1 strength)
1350 int count = s->bless();
1352 supdatingStack.emit(0);
1357 int Player::stackVisitTemple(Stack* s, Temple* t)
1359 debug("Player::stackVisitTemple");
1361 assert(s && t->getPos().x == s->getPos().x && t->getPos().y == s->getPos().y);
1363 Action_Temple* item = new Action_Temple();
1364 item->fillData(t, s);
1367 return doStackVisitTemple(s, t);
1370 Quest* Player::doHeroGetQuest(Hero *hero, Temple* t, bool except_raze)
1372 QuestsManager *qm = QuestsManager::getInstance();
1374 std::vector<Quest*> quests = qm->getPlayerQuests(Playerlist::getActiveplayer());
1375 if (quests.size() > 0 && GameScenarioOptions::s_play_with_quests == GameParameters::ONE_QUEST_PER_PLAYER)
1381 q = qm->createNewQuest (hero->getId(), except_raze);
1384 // couldn't assign a quest for various reasons
1390 Quest* Player::heroGetQuest(Hero *hero, Temple* t, bool except_raze)
1392 debug("Player::stackGetQuest")
1394 Quest *q = doHeroGetQuest(hero, t, except_raze);
1398 // Now fill the action item
1399 Action_Quest* action = new Action_Quest();
1400 action->fillData(q);
1403 // and record it for posterity
1404 History_HeroQuestStarted * history = new History_HeroQuestStarted();
1405 history->fillData(hero);
1406 addHistory(history);
1410 float Player::stackFightAdvise(Stack* s, Vector<int> tile,
1411 bool intense_combat)
1413 float percent = 0.0;
1415 City* city = GameMap::getCity(tile);
1416 Stack* target = GameMap::getEnemyStack(tile);
1418 if (!target && city)
1420 vector<Stack*> def_in_city = city->getDefenders();
1421 if (def_in_city.empty())
1423 target = def_in_city[0];
1426 //what chance is there that stack will defeat defenders?
1428 for (unsigned int i = 0; i < 100; i++)
1430 Fight fight(s, target, Fight::FOR_KICKS);
1431 fight.battle(intense_combat);
1432 if (fight.getResult() == Fight::ATTACKER_WON)
1436 advice_asked.emit(percent);
1440 void Player::adjustDiplomacyFromConqueringCity(City *city)
1442 Player *defender = city->getOwner();
1444 // See if this is the last city for that player, and alter the
1445 // diplomatic scores.
1446 if (Citylist::getInstance()->countCities(defender) == 1)
1448 if (defender->getDiplomaticRank() < getDiplomaticRank())
1449 deteriorateDiplomaticRelationship (2);
1450 else if (defender->getDiplomaticRank() > getDiplomaticRank())
1451 improveDiplomaticRelationship (2, defender);
1455 void Player::calculateLoot(Player *looted, guint32 &added, guint32 &subtracted)
1457 Player *defender = looted;
1460 // if the attacked city isn't neutral, loot some gold
1461 if (defender != Playerlist::getInstance()->getNeutral())
1463 Citylist *clist = Citylist::getInstance();
1464 int amt = (defender->getGold() / (2 * (clist->countCities (defender)+1)) * 2);
1465 // give (Enemy-Gold/(2Enemy-Cities)) to the attacker
1466 // and then take away twice that from the defender.
1467 // the idea here is that some money is taken in the invasion
1468 // and other monies are lost forever
1469 // NOTE: +1 because the looted player just lost a city
1479 void Player::doConquerCity(City *city, Stack *stack)
1481 takeCityInPossession(city);
1483 History_CityWon *item = new History_CityWon();
1484 item->fillData(city);
1486 if (stack->hasHero())
1488 History_HeroCityWon *another = new History_HeroCityWon();
1489 Hero *hero = dynamic_cast<Hero *>(stack->getFirstHero());
1490 another->fillData(hero, city);
1491 addHistory(another);
1495 void Player::conquerCity(City *city, Stack *stack)
1498 Action_ConquerCity *action = new Action_ConquerCity();
1499 action->fillData(city, stack);
1502 Player *looted = city->getOwner();
1503 doConquerCity(city, stack);
1504 if (getType() != Player::NETWORKED)
1505 lootCity(city, looted);
1508 void Player::lootCity(City *city, Player *looted)
1511 guint32 subtracted = 0;
1512 calculateLoot(looted, added, subtracted);
1513 sinvadingCity.emit(city, added);
1514 doLootCity(looted, added, subtracted);
1515 Action_Loot *item = new Action_Loot();
1516 item->fillData(this, looted, added, subtracted);
1521 void Player::doLootCity(Player *looted, guint32 added, guint32 subtracted)
1524 looted->withdrawGold(subtracted);
1528 void Player::takeCityInPossession(City* c)
1532 //set the production to the cheapest armytype
1533 c->setActiveProductionSlot(-1);
1534 if (c->getArmytype(0) != -1)
1535 c->setActiveProductionSlot(0);
1537 supdatingCity.emit(c);
1540 void Player::doCityOccupy(City *c)
1542 assert (c->getOwner() == this);
1544 soccupyingCity.emit(c, getActivestack());
1545 QuestsManager::getInstance()->cityOccupied(c, getActivestack());
1548 void Player::cityOccupy(City* c)
1550 debug("cityOccupy");
1553 Action_Occupy* item = new Action_Occupy();
1558 void Player::doCityPillage(City *c, int& gold, int* pillaged_army_type)
1561 if (pillaged_army_type)
1562 *pillaged_army_type = -1;
1564 // get rid of the most expensive army type and trade it in for
1566 // it is presumed that the last army type is the most expensive
1568 if (c->getNoOfProductionBases() > 0)
1571 unsigned int max_cost = 0;
1573 for (i = 0; i < c->getNoOfProductionBases(); i++)
1575 const ArmyProdBase *a = c->getProductionBase(i);
1578 if (a->getNewProductionCost() == 0)
1583 if (a->getNewProductionCost() > max_cost)
1585 max_cost = a->getNewProductionCost();
1592 const ArmyProdBase *a = c->getProductionBase(slot);
1593 if (pillaged_army_type)
1594 *pillaged_army_type = a->getTypeId();
1595 if (a->getNewProductionCost() == 0)
1598 gold += a->getNewProductionCost() / 2;
1599 c->removeProductionBase(slot);
1601 //*pillaged_army_type = 10;
1604 Stack *s = getActivestack();
1605 //printf ("%s emitting %p, %p, %d, %d\n", getName().c_str(), c, s, gold, *pillaged_army_type);
1606 spillagingCity.emit(c, s, gold, *pillaged_army_type);
1607 QuestsManager::getInstance()->cityPillaged(c, s, gold);
1610 //takeCityInPossession(c);
1613 void Player::cityPillage(City* c, int& gold, int* pillaged_army_type)
1615 debug("Player::cityPillage");
1617 Action_Pillage* item = new Action_Pillage();
1621 doCityPillage(c, gold, pillaged_army_type);
1624 void Player::doCitySack(City* c, int& gold, std::list<guint32> *sacked_types)
1627 //trade in all of the army types except for one
1628 //presumes that the army types are listed in order of expensiveness
1630 if (c->getNoOfProductionBases() > 1)
1632 const ArmyProdBase *a;
1633 unsigned int i, max = 0;
1634 for (i = 0; i < c->getNoOfProductionBases(); i++)
1636 a = c->getProductionBase(i);
1641 i = c->getNoOfProductionBases() - 1;
1644 a = c->getProductionBase(i);
1647 sacked_types->push_back(a->getTypeId());
1648 if (a->getNewProductionCost() == 0)
1651 gold += a->getNewProductionCost() / 2;
1652 c->removeProductionBase(i);
1660 Stack *s = getActivestack();
1661 ssackingCity.emit(c, s, gold, *sacked_types);
1662 printf("notifying quests manager of city sacking!\n");
1663 QuestsManager::getInstance()->citySacked(c, s, gold);
1665 //takeCityInPossession(c);
1668 void Player::citySack(City* c, int& gold, std::list<guint32> *sacked_types)
1670 debug("Player::citySack");
1672 Action_Sack* item = new Action_Sack();
1676 doCitySack(c, gold, sacked_types);
1679 void Player::doCityRaze(City *c)
1681 History_CityRazed* history = new History_CityRazed();
1682 history->fillData(c);
1683 addHistory(history);
1688 supdatingCity.emit(c);
1690 srazingCity.emit(c, getActivestack());
1691 QuestsManager::getInstance()->cityRazed(c, getActivestack());
1694 void Player::cityRaze(City* c)
1696 debug("Player::cityRaze");
1698 Action_Raze* action = new Action_Raze();
1699 action->fillData(c);
1705 void Player::doCityBuyProduction(City* c, int slot, int type)
1707 const Armysetlist* al = Armysetlist::getInstance();
1708 guint32 as = c->getOwner()->getArmyset();
1710 c->removeProductionBase(slot);
1711 c->addProductionBase(slot, new ArmyProdBase(*al->getArmy(as, type)));
1713 // and do the rest of the neccessary actions
1714 withdrawGold(al->getArmy(as, type)->getNewProductionCost());
1717 bool Player::cityBuyProduction(City* c, int slot, int type)
1719 const Armysetlist* al = Armysetlist::getInstance();
1720 guint32 as = c->getOwner()->getArmyset();
1722 // sort out unusual values (-1 is allowed and means "scrap production")
1723 if ((type <= -1) || (type >= (int)al->getSize(as)))
1726 // return if we don't have enough money
1727 if ((type != -1) && ((int)al->getArmy(as, type)->getNewProductionCost() > d_gold))
1730 // return if the city already has the production
1731 if (c->hasProductionBase(type, as))
1734 // can't put it in that slot
1735 if (slot >= (int)c->getMaxNoOfProductionBases())
1738 Action_Buy* item = new Action_Buy();
1739 item->fillData(c, slot, al->getArmy(as, type));
1742 doCityBuyProduction(c, slot, type);
1747 void Player::doCityChangeProduction(City* c, int slot)
1749 c->setActiveProductionSlot(slot);
1752 bool Player::cityChangeProduction(City* c, int slot)
1754 doCityChangeProduction(c, slot);
1756 Action_Production* item = new Action_Production();
1757 item->fillData(c, slot);
1763 void Player::doGiveReward(Stack *s, Reward *reward)
1765 switch (reward->getType())
1768 addGold(dynamic_cast<Reward_Gold*>(reward)->getGold());
1770 case Reward::ALLIES:
1772 const ArmyProto *a = dynamic_cast<Reward_Allies*>(reward)->getArmy();
1774 Reward_Allies::addAllies(s->getOwner(), s->getPos(), a,
1775 dynamic_cast<Reward_Allies*>(reward)->getNoOfAllies());
1780 static_cast<Hero*>(s->getFirstHero())->getBackpack()->addToBackpack
1781 (dynamic_cast<Reward_Item*>(reward)->getItem());
1785 //assign the hidden ruin to this player
1786 Ruin *r = dynamic_cast<Reward_Ruin*>(reward)->getRuin();
1794 Reward_Map *map = dynamic_cast<Reward_Map*>(reward);
1795 d_fogmap->alterFog(map->getSightMap());
1801 bool Player::giveReward(Stack *s, Reward *reward)
1803 debug("Player::give_reward");
1805 doGiveReward(s, reward);
1807 Action_Reward* item = new Action_Reward();
1808 item->fillData(s, reward);
1811 if (reward->getType() == Reward::RUIN)
1813 Ruin *r = dynamic_cast<Reward_Ruin*>(reward)->getRuin();
1814 History_HeroRewardRuin* history_item = new History_HeroRewardRuin();
1815 history_item->fillData(dynamic_cast<Hero*>(s->getFirstHero()), r);
1816 addHistory(history_item);
1818 //FIXME: get rid of this reward now that we're done with it
1819 //but we need to show it still... (in the case of quest completions)
1824 bool Player::doStackDisband(Stack* s)
1826 getStacklist()->setActivestack(0);
1827 bool found = d_stacklist->flRemove(s);
1828 supdatingStack.emit(0);
1832 bool Player::stackDisband(Stack* s)
1834 debug("Player::stackDisband(Stack*)")
1836 s = getActivestack();
1838 Action_Disband* item = new Action_Disband();
1842 return doStackDisband(s);
1845 void Player::doHeroDropItem(Hero *h, Item *i, Vector<int> pos)
1847 GameMap::getInstance()->getTile(pos)->getBackpack()->addToBackpack(i);
1848 h->getBackpack()->removeFromBackpack(i);
1851 bool Player::heroDropItem(Hero *h, Item *i, Vector<int> pos)
1853 doHeroDropItem(h, i, pos);
1855 Action_Equip* item = new Action_Equip();
1856 item->fillData(h, i, Action_Equip::GROUND, pos);
1862 bool Player::heroDropAllItems(Hero *h, Vector<int> pos)
1864 while (h->getBackpack()->empty() == false)
1865 heroDropItem(h, h->getBackpack()->front(), pos);
1869 bool Player::doHeroDropAllItems(Hero *h, Vector<int> pos)
1871 while (h->getBackpack()->empty() == false)
1872 doHeroDropItem(h, h->getBackpack()->front(), pos);
1876 void Player::doHeroPickupItem(Hero *h, Item *i, Vector<int> pos)
1878 bool found = GameMap::getInstance()->getTile(pos)->getBackpack()->removeFromBackpack(i);
1880 h->getBackpack()->addToBackpack(i);
1883 bool Player::heroPickupItem(Hero *h, Item *i, Vector<int> pos)
1885 doHeroPickupItem(h, i, pos);
1887 Action_Equip* item = new Action_Equip();
1888 item->fillData(h, i, Action_Equip::BACKPACK, pos);
1894 bool Player::heroPickupAllItems(Hero *h, Vector<int> pos)
1896 MapBackpack *backpack = GameMap::getInstance()->getTile(pos)->getBackpack();
1897 while (backpack->empty() == false)
1898 heroPickupItem(h, backpack->front(), pos);
1902 bool Player::heroCompletesQuest(Hero *h)
1904 // record it for posterity
1905 History_HeroQuestCompleted* item = new History_HeroQuestCompleted();
1911 void Player::doResign()
1913 //disband all stacks
1914 getStacklist()->flClear();
1917 Citylist *cl = Citylist::getInstance();
1918 for (Citylist::iterator it = cl->begin(); it != cl->end(); it++)
1920 if ((*it)->getOwner() == this)
1922 (*it)->setBurnt(true);
1923 History_CityRazed* history = new History_CityRazed();
1924 history->fillData((*it));
1925 addHistory(history);
1928 withdrawGold(getGold()); //empty the coffers!
1930 getStacklist()->setActivestack(0);
1931 supdatingStack.emit(0);
1934 void Player::resign()
1938 Action_Resign* item = new Action_Resign();
1943 void Player::doSignpostChange(Signpost *s, std::string message)
1945 s->setName(message);
1948 bool Player::signpostChange(Signpost *s, std::string message)
1953 doSignpostChange(s, message);
1955 Action_ModifySignpost* item = new Action_ModifySignpost();
1956 item->fillData(s, message);
1961 void Player::doCityRename(City *c, std::string name)
1966 bool Player::cityRename(City *c, std::string name)
1971 doCityRename(c, name);
1973 Action_RenameCity* item = new Action_RenameCity();
1974 item->fillData(c, name);
1979 void Player::doRename(std::string name)
1984 void Player::rename(std::string name)
1987 Action_RenamePlayer * item = new Action_RenamePlayer();
1988 item->fillData(name);
1993 void Player::doVectorFromCity(City * c, Vector<int> dest)
1995 c->setVectoring(dest);
1998 bool Player::vectorFromCity(City * c, Vector<int> dest)
2000 if (dest != Vector<int>(-1,-1))
2002 std::list<City*> cities;
2003 cities = Citylist::getInstance()->getCitiesVectoringTo(dest);
2004 if (cities.size() >= MAX_CITIES_VECTORED_TO_ONE_CITY)
2007 doVectorFromCity(c, dest);
2009 Action_Vector* item = new Action_Vector();
2010 item->fillData(c, dest);
2015 bool Player::doChangeVectorDestination(Vector<int> src, Vector<int> dest,
2016 std::list<City*> &vectored)
2018 //DEST can be a flag.
2019 //SRC can be a flag too.
2020 //Note: we don't actually have a way in the gui to change the vectoring
2021 //from the planted standard (flag).
2024 //disallow changing vectoring from or to a city that isn't ours
2025 //disallow vectoring to something that isn't our city or our planted
2027 Citylist *cl = Citylist::getInstance();
2028 City *src_city = GameMap::getCity(src);
2029 if (src_city == NULL)
2031 //maybe it's a flag we're changing the vector destination from.
2032 if (GameMap::getInstance()->findPlantedStandard(this) != src)
2037 if (src_city->getOwner() != this)
2040 City *dest_city = GameMap::getCity(dest);
2041 if (dest_city == NULL)
2043 if (GameMap::getInstance()->findPlantedStandard(this) != dest)
2048 if (dest_city->getOwner() != this)
2052 //check to see if the destination has enough room to accept all of the
2053 //cities we want to send to it.
2054 std::list<City*> sources = cl->getCitiesVectoringTo(src);
2055 std::list<City*> alreadyvectored = cl->getCitiesVectoringTo(dest);
2057 if (alreadyvectored.size() + sources.size() > MAX_CITIES_VECTORED_TO_ONE_CITY)
2060 //okay, do the vectoring changes.
2061 std::list<City*>::iterator it = sources.begin();
2062 for (; it != sources.end(); it++)
2063 retval &= (*it)->changeVectorDestination(dest);
2068 bool Player::changeVectorDestination(Vector<int> src, Vector<int> dest)
2070 std::list<City*> vectored;
2071 bool retval = doChangeVectorDestination(src, dest, vectored);
2072 if (retval == false)
2075 std::list<City*>::iterator it = vectored.begin();
2076 for (; it != vectored.end(); it++)
2078 Action_Vector* item = new Action_Vector();
2079 item->fillData((*it), dest);
2085 bool Player::heroPlantStandard(Stack* s)
2087 debug("Player::heroPlantStandard(Stack*)");
2089 s = getActivestack();
2091 for (Stack::iterator it = s->begin(); it != s->end(); it++)
2093 if ((*it)->isHero())
2095 Hero *hero = dynamic_cast<Hero*>((*it));
2096 Item *item = hero->getBackpack()->getPlantableItem(this);
2099 //drop the item, and plant it
2100 doHeroPlantStandard(hero, item, s->getPos());
2102 Action_Plant * i = new Action_Plant();
2103 i->fillData(hero, item);
2112 void Player::doHeroPlantStandard(Hero *hero, Item *item, Vector<int> pos)
2114 item->setPlanted(true);
2115 GameMap *gm = GameMap::getInstance();
2116 gm->getTile(pos)->getBackpack()->addToBackpack(item);
2117 hero->getBackpack()->removeFromBackpack(item);
2120 void Player::getHeroes(const std::list<Stack*> stacks, std::vector<guint32>& dst)
2122 std::list<Stack*>::const_iterator it;
2123 for (it = stacks.begin(); it != stacks.end(); it++)
2124 (*it)->getHeroes(dst);
2127 double Player::removeDeadArmies(std::list<Stack*>& stacks,
2128 std::vector<guint32>& culprits)
2131 Player *owner = NULL;
2132 if (stacks.empty() == 0)
2134 owner = (*stacks.begin())->getOwner();
2135 debug("Owner = " << owner);
2137 debug("Owner of the stacks: " << owner->getName()
2138 << ", his stacklist = " << owner->getStacklist());
2140 for (unsigned int i = 0; i < culprits.size(); i++)
2141 debug("Culprit: " << culprits[i]);
2143 std::list<Stack*>::iterator it;
2144 for (it = stacks.begin(); it != stacks.end(); )
2147 debug("Stack: " << (*it))
2148 for (Stack::iterator sit = (*it)->begin(); sit != (*it)->end();)
2150 debug("Army: " << (*sit))
2151 if ((*sit)->getHP() <= 0)
2153 //Tally up the triumphs
2154 if ((*sit)->getAwardable()) //hey a special died
2155 d_triumphs->tallyTriumph((*sit)->getOwner(),
2156 Triumphs::TALLY_SPECIAL);
2157 else if ((*sit)->isHero() == false)
2158 d_triumphs->tallyTriumph((*sit)->getOwner(),
2159 Triumphs::TALLY_NORMAL);
2160 if ((*sit)->getStat(Army::SHIP, false)) //hey it was on a boat
2161 d_triumphs->tallyTriumph((*sit)->getOwner(),
2162 Triumphs::TALLY_SHIP);
2163 debug("Army: " << (*sit)->getName())
2164 debug("Army: " << (*sit)->getXpReward())
2165 if ((*sit)->isHero())
2167 d_triumphs->tallyTriumph((*sit)->getOwner(),
2168 Triumphs::TALLY_HERO);
2169 Hero *hero = dynamic_cast<Hero*>((*sit));
2170 guint32 count = hero->getBackpack()->countPlantableItems();
2171 for (guint32 i = 0; i < count; i++)
2172 d_triumphs->tallyTriumph((*sit)->getOwner(),
2173 Triumphs::TALLY_FLAG);
2175 //one of our heroes died
2177 Hero *h = static_cast<Hero *>(*sit);
2178 //now record the details of the death
2179 GameMap *gm = GameMap::getInstance();
2180 Maptile *tile = gm->getTile((*it)->getPos());
2181 if (tile->getBuilding() == Maptile::RUIN)
2183 History_HeroKilledSearching* item;
2184 item = new History_HeroKilledSearching();
2186 h->getOwner()->addHistory(item);
2187 doHeroDropAllItems (h, (*it)->getPos());
2189 else if (tile->getBuilding() == Maptile::CITY)
2191 City* c = GameMap::getCity((*it)->getPos());
2192 History_HeroKilledInCity* item;
2193 item = new History_HeroKilledInCity();
2194 item->fillData(h, c);
2195 h->getOwner()->addHistory(item);
2196 doHeroDropAllItems (h, (*it)->getPos());
2198 else //somewhere else
2200 History_HeroKilledInBattle* item;
2201 item = new History_HeroKilledInBattle();
2203 h->getOwner()->addHistory(item);
2204 doHeroDropAllItems (h, (*it)->getPos());
2207 //Add the XP bonus to the total of the battle;
2208 total+=(*sit)->getXpReward();
2209 //tell the quest manager that someone died
2210 //(maybe it was a hero, or a target that's an army)
2211 QuestsManager::getInstance()->armyDied(*sit, culprits);
2212 // here we destroy the army, so we send
2213 // the signal containing the fight data
2214 debug("sending sdyingArmy!")
2215 sdyingArmy.emit(*sit, culprits);
2216 sit = (*it)->flErase(sit);
2220 // heal this army to full hitpoints
2221 (*sit)->heal((*sit)->getStat(Army::HP));
2226 debug("Is stack empty?")
2232 debug("Removing this stack from the owner's stacklist");
2233 bool found = owner->deleteStack(*it);
2234 assert (found == true);
2236 else // there is no owner - like for the ruin's occupants
2237 debug("No owner for this stack - do stacklist too");
2239 debug("Removing from the vector too (the vector had "
2240 << stacks.size() << " elt)");
2241 it = stacks.erase(it);
2246 debug("after removeDead: size = " << stacks.size());
2250 void Player::doHeroGainsLevel(Hero *hero, Army::Stat stat)
2252 hero->gainLevel(stat);
2256 void Player::updateArmyValues(std::list<Stack*>& stacks, double xp_sum)
2258 std::list<Stack*>::iterator it;
2259 double numberarmy = 0;
2261 for (it = stacks.begin(); it != stacks.end(); it++)
2262 numberarmy += (*it)->size();
2264 for (it = stacks.begin(); it != stacks.end(); )
2266 debug("Stack: " << (*it))
2268 for (Stack::iterator sit = (*it)->begin(); sit != (*it)->end();)
2271 debug("Army: " << army)
2274 army->gainXp((double)((xp_sum)/numberarmy));
2275 debug("Army gets " << (double)((xp_sum)/numberarmy) << " XP")
2277 // here we adds 1 to number of battles
2278 army->setBattlesNumber(army->getBattlesNumber()+1);
2279 debug("Army battles " << army->getBattlesNumber())
2281 // medals only go to non-ally armies.
2282 if ((*it)->hasHero() && army->isHero() == false &&
2283 army->getAwardable() == false)
2285 if((army->getBattlesNumber())>10 &&
2286 !(army->getMedalBonus(2)))
2288 army->setMedalBonus(2,true);
2289 // We must recalculate the XPValue of this unit since it
2291 army->setXpReward(army->getXpReward()+1);
2292 // We get the medal bonus here
2293 army->setStat(Army::STRENGTH, army->getStat(Army::STRENGTH, false)+1);
2295 snewMedalArmy.emit(army, 2);
2298 debug("Army hits " << army->getNumberHasHit())
2300 // Only give medals if the unit has attacked often enough, else
2301 // medals lose the flair of something special; a value of n
2302 // means roughly to hit an equally strong unit around n
2303 // times. (note: one hit! An attack can consist of up to
2305 if((army->getNumberHasHit()>50) && !army->getMedalBonus(0))
2307 army->setMedalBonus(0,true);
2308 // We must recalculate the XPValue of this unit since it
2310 army->setXpReward(army->getXpReward()+1);
2311 // We get the medal bonus here
2312 army->setStat(Army::STRENGTH, army->getStat(Army::STRENGTH, false)+1);
2314 snewMedalArmy.emit(army, 0);
2317 debug("army being hit " << army->getNumberHasBeenHit())
2319 // Gives the medal for good defense. The more negative the
2320 // number the more blows the unit evaded. n means roughly
2321 // avoid n hits from an equally strong unit. Since we want
2322 // to punish the case of the unit hiding among many others,
2323 // we set this value quite high.
2324 if((army->getNumberHasBeenHit() < -100) && !army->getMedalBonus(1))
2326 army->setMedalBonus(1,true);
2327 // We must recalculate the XPValue of this unit since it
2329 army->setXpReward(army->getXpReward()+1);
2330 // We get the medal bonus here
2331 army->setStat(Army::STRENGTH, army->getStat(Army::STRENGTH, false)+1);
2333 snewMedalArmy.emit(army, 1);
2335 debug("Army hits " << army->getNumberHasHit())
2337 for(int i=0;i<3;i++)
2339 debug("MEDAL[" << i << "]==" << army->getMedalBonus(i))
2343 // We reset the hit values after the battle
2344 army->setNumberHasHit(0);
2345 army->setNumberHasBeenHit(0);
2347 if (army->isHero() && getType() != Player::NETWORKED)
2349 Hero *h = dynamic_cast<Hero*>(army);
2350 while(h->canGainLevel())
2352 // Units not associated to a player never raise levels.
2353 if (h->getOwner() ==
2354 Playerlist::getInstance()->getNeutral())
2357 //Here this for is to check if army must raise 2 or more
2358 //levels per time depending on the XP and level itself
2360 h->getOwner()->heroGainsLevel(h);
2362 debug("Hero new XP=" << h->getXP())
2370 Hero* Player::doRecruitHero(HeroProto* herotemplate, City *city, int cost, int alliesCount, const ArmyProto *ally)
2372 Hero *newhero = new Hero(*herotemplate);
2373 newhero->setOwner(this);
2374 GameMap::getInstance()->addArmy(city, newhero);
2376 if (alliesCount > 0)
2378 Reward_Allies::addAllies(this, city->getPos(), ally, alliesCount);
2379 hero_arrives_with_allies.emit(alliesCount);
2384 // Initially give the first hero the player's standard.
2385 std::string name = String::ucompose(_("%1 Standard"), getName());
2386 Item *battle_standard = new Item (name, true, this);
2387 battle_standard->addBonus(Item::ADD1STACK);
2388 newhero->getBackpack()->addToBackpack(battle_standard, 0);
2391 supdatingStack.emit(0);
2395 void Player::recruitHero(HeroProto* heroproto, City *city, int cost, int alliesCount, const ArmyProto *ally)
2397 //alright, we may have picked another sex for the hero.
2399 std::string name = heroproto->getName();
2400 Hero::Gender g = Hero::Gender(heroproto->getGender());
2401 h = HeroTemplates::getInstance()->getRandomHero(g, getId());
2404 Action_RecruitHero *action = new Action_RecruitHero();
2405 action->fillData(h, city, cost, alliesCount, ally);
2408 Hero *hero = doRecruitHero(h, city, cost, alliesCount, ally);
2411 History_HeroEmerges *item = new History_HeroEmerges();
2412 item->fillData(hero, city);
2417 void Player::doDeclareDiplomacy (DiplomaticState state, Player *player)
2419 Playerlist *pl = Playerlist::getInstance();
2420 if (pl->getNeutral() == player)
2424 if (state == d_diplomatic_state[player->getId()])
2426 d_diplomatic_state[player->getId()] = state;
2429 void Player::declareDiplomacy (DiplomaticState state, Player *player)
2431 doDeclareDiplomacy(state, player);
2433 Action_DiplomacyState * item = new Action_DiplomacyState();
2434 item->fillData(player, state);
2437 // FIXME: update diplomatic scores?
2440 void Player::doProposeDiplomacy (DiplomaticProposal proposal, Player *player)
2442 if (GameScenarioOptions::s_diplomacy == false)
2444 Playerlist *pl = Playerlist::getInstance();
2445 if (pl->getNeutral() == player)
2449 if (proposal == d_diplomatic_proposal[player->getId()])
2451 if (proposal == PROPOSE_PEACE)
2453 std::string s = _("Peace negotiated with ") + player->getName();
2454 if (getDiplomaticState(player) == AT_PEACE ||
2455 getDiplomaticProposal(player) == PROPOSE_PEACE)
2456 schangingStatus.emit(s);
2458 else if (proposal == PROPOSE_WAR)
2460 std::string s = _("War declared with ") + player->getName();
2461 if (getDiplomaticState(player) == AT_WAR ||
2462 getDiplomaticProposal(player) == PROPOSE_WAR)
2463 schangingStatus.emit(s);
2465 d_diplomatic_proposal[player->getId()] = proposal;
2468 void Player::proposeDiplomacy (DiplomaticProposal proposal, Player *player)
2470 doProposeDiplomacy(proposal, player);
2472 Action_DiplomacyProposal * item = new Action_DiplomacyProposal();
2473 item->fillData(player, proposal);
2476 // FIXME: update diplomatic scores?
2479 Player::DiplomaticState Player::negotiateDiplomacy (Player *player)
2481 DiplomaticState state = getDiplomaticState(player);
2482 DiplomaticProposal them = player->getDiplomaticProposal(this);
2483 DiplomaticProposal me = getDiplomaticProposal(player);
2484 DiplomaticProposal winning_proposal;
2486 /* Check if we both want the status quo. */
2487 if (me == NO_PROPOSAL && them == NO_PROPOSAL)
2490 /* Okay, we both want a change from the status quo. */
2492 /* In the absense of a new proposal, the status quo is the proposal. */
2493 if (me == NO_PROPOSAL)
2497 case AT_PEACE: me = PROPOSE_PEACE; break;
2498 case AT_WAR_IN_FIELD: me = PROPOSE_WAR_IN_FIELD; break;
2499 case AT_WAR: me = PROPOSE_WAR; break;
2502 if (them == NO_PROPOSAL)
2506 case AT_PEACE: them = PROPOSE_PEACE; break;
2507 case AT_WAR_IN_FIELD: them = PROPOSE_WAR_IN_FIELD; break;
2508 case AT_WAR: them = PROPOSE_WAR; break;
2512 /* Check if we have agreement. */
2513 if (me == PROPOSE_PEACE && them == PROPOSE_PEACE)
2515 else if (me == PROPOSE_WAR_IN_FIELD && them == PROPOSE_WAR_IN_FIELD)
2516 return AT_WAR_IN_FIELD;
2517 else if (me == PROPOSE_WAR && them == PROPOSE_WAR)
2520 /* Still we don't have an agreement.
2521 Unfortunately the greater violence is the new diplomatic state.
2522 Because there are two different proposals and the proposal with
2523 greater violence will be the new status quo, there can't
2524 possibly be peace at this juncture. */
2526 winning_proposal = me;
2528 winning_proposal = them;
2530 switch (winning_proposal)
2532 case PROPOSE_WAR_IN_FIELD: return AT_WAR_IN_FIELD; break;
2533 case PROPOSE_WAR: return AT_WAR; break;
2534 default: return AT_PEACE; break; //impossible
2539 Player::DiplomaticState Player::getDiplomaticState (Player *player) const
2541 if (player == Playerlist::getInstance()->getNeutral())
2545 return d_diplomatic_state[player->getId()];
2548 Player::DiplomaticProposal Player::getDiplomaticProposal (Player *player) const
2550 if (player == Playerlist::getInstance()->getNeutral())
2554 return d_diplomatic_proposal[player->getId()];
2557 guint32 Player::getDiplomaticScore (Player *player) const
2559 Playerlist *pl = Playerlist::getInstance();
2560 if (pl->getNeutral() == player)
2562 return d_diplomatic_score[player->getId()];
2565 void Player::alterDiplomaticRelationshipScore (Player *player, int amount)
2569 if (d_diplomatic_score[player->getId()] + amount > DIPLOMACY_MAX_SCORE)
2570 d_diplomatic_score[player->getId()] = DIPLOMACY_MAX_SCORE;
2572 d_diplomatic_score[player->getId()] += amount;
2574 else if (amount < 0)
2576 if ((guint32) (amount * -1) > d_diplomatic_score[player->getId()])
2577 d_diplomatic_score[player->getId()] = DIPLOMACY_MIN_SCORE;
2579 d_diplomatic_score[player->getId()] += amount;
2583 void Player::improveDiplomaticRelationship (Player *player, guint32 amount)
2585 Playerlist *pl = Playerlist::getInstance();
2586 if (pl->getNeutral() == player || player == this)
2589 alterDiplomaticRelationshipScore (player, amount);
2591 Action_DiplomacyScore* item = new Action_DiplomacyScore();
2592 item->fillData(player, amount);
2596 void Player::deteriorateDiplomaticRelationship (Player *player, guint32 amount)
2598 Playerlist *pl = Playerlist::getInstance();
2599 if (pl->getNeutral() == player || player == this)
2602 alterDiplomaticRelationshipScore (player, -amount);
2604 Action_DiplomacyScore* item = new Action_DiplomacyScore();
2605 item->fillData(player, -amount);
2609 void Player::deteriorateDiplomaticRelationship (guint32 amount)
2611 Playerlist *pl = Playerlist::getInstance();
2612 for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
2614 if ((*it)->isDead())
2616 if (pl->getNeutral() == (*it))
2620 (*it)->deteriorateDiplomaticRelationship (this, amount);
2624 void Player::improveDiplomaticRelationship (guint32 amount, Player *except)
2626 Playerlist *pl = Playerlist::getInstance();
2627 for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
2629 if ((*it)->isDead())
2631 if (pl->getNeutral() == (*it))
2635 if (except && *it == except)
2637 (*it)->improveDiplomaticRelationship (this, amount);
2641 void Player::deteriorateAlliesRelationship(Player *player, guint32 amount,
2642 Player::DiplomaticState state)
2644 Playerlist *pl = Playerlist::getInstance();
2645 for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
2647 if ((*it)->isDead())
2649 if (pl->getNeutral() == (*it))
2653 if (getDiplomaticState(*it) == state)
2654 (*it)->deteriorateDiplomaticRelationship (player, amount);
2658 void Player::improveAlliesRelationship(Player *player, guint32 amount,
2659 Player::DiplomaticState state)
2661 Playerlist *pl = Playerlist::getInstance();
2662 for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
2664 if ((*it)->isDead())
2666 if (pl->getNeutral() == (*it))
2670 if (player->getDiplomaticState(*it) == state)
2671 (*it)->improveDiplomaticRelationship (this, amount);
2675 void Player::AI_maybeBuyScout(City *c)
2677 bool one_turn_army_exists = false;
2678 //do we already have something that can be produced in one turn?
2679 for (unsigned int i = 0; i < c->getMaxNoOfProductionBases(); i++)
2681 if (c->getArmytype(i) == -1) // no production in this slot
2684 const ArmyProdBase *proto = c->getProductionBase(i);
2685 if (proto->getProduction() == 1)
2687 one_turn_army_exists = true;
2691 if (one_turn_army_exists == false)
2693 const Armysetlist* al = Armysetlist::getInstance();
2694 int free_slot = c->getFreeSlot();
2695 if (free_slot == -1)
2697 ArmyProto *scout = al->getScout(getArmyset());
2698 cityBuyProduction(c, free_slot, scout->getTypeId());
2702 bool Player::AI_maybePickUpItems(Stack *s, int max_dist, int max_mp,
2703 bool &picked_up, bool &stack_died)
2706 bool stack_moved = false;
2707 Vector<int> item_tile(-1, -1);
2709 // do we not have a hero?
2710 if (s->hasHero() == false)
2713 //ok, which bag of stuff is closest?
2714 std::vector<Vector<int> > tiles = GameMap::getInstance()->getItems();
2715 std::vector<Vector<int> >::iterator it = tiles.begin();
2716 for(; it != tiles.end(); it++)
2718 Vector<int> tile = *it;
2719 //don't consider bags of stuff that are inside enemy cities
2720 City *c = GameMap::getCity(tile);
2723 if (c->getOwner() != s->getOwner())
2727 int distance = dist (tile, s->getPos());
2728 if (distance < min_dist || min_dist == -1)
2730 min_dist = distance;
2735 //if no bags of stuff, or the bag is too far away
2736 if (min_dist == -1 || min_dist > max_dist)
2739 //are we not standing on it?
2740 if (s->getPos() != item_tile)
2742 //can we really reach it?
2743 Vector<int> old_dest(-1,-1);
2744 if (s->getPath()->size())
2745 old_dest = s->getLastPointInPath();
2746 guint32 mp = s->getPath()->calculate(s, item_tile);
2747 if ((int)mp > max_mp)
2749 //nope. unreachable. set in our old path.
2750 if (old_dest != Vector<int>(-1,-1))
2751 s->getPath()->calculate(s, old_dest);
2754 stack_moved = stackMove(s);
2755 //maybe we died -- an enemy stack was guarding the bag.
2756 if (!d_stacklist->getActivestack())
2761 s = d_stacklist->getActivestack();
2764 //are we standing on it now?
2765 if (s->getPos() == item_tile)
2767 Hero *hero = static_cast<Hero*>(s->getFirstHero());
2769 picked_up = heroPickupAllItems(hero, s->getPos());
2775 bool Player::AI_maybeVisitTempleForQuest(Stack *s, int dist, int max_mp,
2778 bool stack_moved = false;
2779 Templelist *tl = Templelist::getInstance();
2781 //if this stack doesn't have a hero then we can't get a quest with this stack.
2782 if (s->hasHero() == false)
2785 //if the player already has a hero who has a quest, then we can't get a
2786 //quest with this stack when playing one quest per player.
2787 if (QuestsManager::getInstance()->getPlayerQuests(this).size() > 0 &&
2788 GameScenarioOptions::s_play_with_quests ==
2789 GameParameters::ONE_QUEST_PER_PLAYER)
2792 Temple *temple = tl->getNearestVisibleTemple(s->getPos(), dist);
2796 //if we're not there yet
2797 if (temple->contains(s->getPos()) == false)
2799 //can we really reach it?
2800 Vector<int> old_dest(-1,-1);
2801 if (s->getPath()->size())
2802 old_dest = s->getLastPointInPath();
2803 guint32 mp = s->getPath()->calculate(s, temple->getPos());
2804 if ((int)mp > max_mp)
2806 //nope. unreachable. set in our old path.
2807 if (old_dest != Vector<int>(-1,-1))
2808 s->getPath()->calculate(s, old_dest);
2811 stack_moved = stackMove(s);
2813 //maybe we died -- an enemy stack was guarding the temple
2814 if (!d_stacklist->getActivestack())
2819 s = d_stacklist->getActivestack();
2823 if (temple->contains(s->getPos()) == true)
2824 svisitingTemple.emit(temple, s);
2829 bool Player::AI_maybeVisitRuin(Stack *s, int dist, int max_mp,
2832 bool stack_moved = false;
2833 Ruinlist *rl = Ruinlist::getInstance();
2835 //if this stack doesn't have a hero then we can't search the ruin.
2836 if (s->hasHero() == false)
2839 Ruin *ruin = rl->getNearestUnsearchedRuin(s->getPos(), dist);
2843 //if we're not there yet
2844 if (ruin->contains(s->getPos()) == false)
2846 //can we really reach it?
2847 Vector<int> old_dest(-1,-1);
2848 if (s->getPath()->size())
2849 old_dest = s->getLastPointInPath();
2850 guint32 mp = s->getPath()->calculate(s, ruin->getPos());
2851 if ((int)mp > max_mp)
2853 //nope. unreachable. set in our old path.
2854 if (old_dest != Vector<int>(-1,-1))
2855 s->getPath()->calculate(s, old_dest);
2858 stack_moved = stackMove(s);
2860 //maybe we died -- an enemy stack was guarding the temple
2861 if (!d_stacklist->getActivestack())
2866 s = d_stacklist->getActivestack();
2870 if (ruin->contains(s->getPos()) == true)
2871 ssearchingRuin.emit(ruin, s);
2875 bool Player::AI_maybeVisitTempleForBlessing(Stack *s, int dist, int max_mp,
2876 double percent_can_be_blessed,
2877 bool &blessed, bool &stack_died)
2879 bool stack_moved = false;
2880 Templelist *tl = Templelist::getInstance();
2882 Temple *temple = tl->getNearestVisibleAndUsefulTemple(s, percent_can_be_blessed, dist);
2886 //if we're not there yet
2887 if (s->getPos() != temple->getPos())
2889 //can we really reach it?
2890 Vector<int> old_dest(-1,-1);
2891 if (s->getPath()->size())
2892 old_dest = s->getLastPointInPath();
2893 guint32 mp = s->getPath()->calculate(s, temple->getPos());
2894 if ((int)mp > max_mp)
2896 //nope. unreachable. set in our old path.
2897 if (old_dest != Vector<int>(-1,-1))
2898 s->getPath()->calculate(s, old_dest);
2901 stack_moved = stackMove(s);
2903 //maybe we died -- an enemy stack was guarding the temple
2904 if (!d_stacklist->getActivestack())
2909 s = d_stacklist->getActivestack();
2912 int num_blessed = 0;
2914 if (s->getPos() == temple->getPos())
2916 num_blessed = stackVisitTemple(s, temple);
2919 blessed = num_blessed > 0;
2923 bool Player::safeFromAttack(City *c, guint32 safe_mp, guint32 min_defenders)
2925 //if there isn't an enemy city nearby to the source
2926 // calculate mp to nearest enemy city
2927 // needs to be less than 18 mp with a scout
2928 //does the source city contain at least 3 defenders?
2930 City *enemy_city = Citylist::getInstance()->getNearestEnemyCity(c->getPos());
2933 PathCalculator pc(c->getOwner(), c->getPos());
2934 int mp = pc.calculate(enemy_city->getPos());
2935 if (mp <= 0 || mp >= (int)safe_mp)
2937 if (c->countDefenders() >= min_defenders)
2945 bool Player::AI_maybeDisband(Stack *s, int safe_mp, bool &stack_killed)
2947 bool disbanded = false;
2948 //see if we're near to enemy stacks
2949 PathCalculator pc(s);
2950 if (GameMap::getEnemyStacks(pc.getReachablePositions(safe_mp)).size() > 0)
2953 //upgroup the whole stack if it doesn't contain a hero
2954 if (s->hasHero() == false)
2956 stack_killed = stackDisband (s);
2957 return stack_killed;
2960 //ungroup the lucky ones not being disbanded
2961 for (Stack::reverse_iterator i = s->rbegin(); i != s->rend(); i++)
2963 if ((*i)->isHero() == false)
2965 Stack *new_stack = stackSplitArmy(s, *i);
2968 if (stackDisband(new_stack))
2976 bool Player::AI_maybeDisband(Stack *s, City *city, guint32 min_defenders,
2977 int safe_mp, bool &stack_killed)
2979 bool disbanded = false;
2980 //is the city in danger from a city?
2981 if (safeFromAttack(city, safe_mp, 0) == false)
2984 if (city->countDefenders() - s->size() >= min_defenders)
2987 min_defenders = s->size() + 1;
2990 stack_killed = stackDisband(s);
2991 return stack_killed;
2995 //okay, we need to disband part of our stack
2997 //before we move, ungroup the lucky ones not being disbanded
2998 unsigned int count = 0;
2999 for (Stack::reverse_iterator i = s->rbegin(); i != s->rend(); i++)
3001 if (count == min_defenders)
3003 if ((*i)->isHero() == false)
3005 Stack *new_stack = stackSplitArmy(s, *i);
3009 if (stackDisband(new_stack))
3017 bool Player::AI_maybeVector(City *c, guint32 safe_mp, guint32 min_defenders,
3018 City *target, City **vector_city)
3020 assert (c->getOwner() == this);
3022 *vector_city = NULL;
3023 Citylist *cl = Citylist::getInstance();
3025 //is this city producing anything that we can vector?
3026 if (c->getActiveProductionSlot() == -1)
3029 //is it safe to vector from this city?
3030 bool safe = safeFromAttack(c, 18, 3);
3035 //get the nearest city to the enemy city that can accept vectored units
3036 City *near_city = cl->getNearestFriendlyVectorableCity(target->getPos());
3039 assert (near_city->getOwner() == this);
3040 if (GameMap::getCity(near_city->getPos()) != near_city)
3042 printf("nearCity is %s (%d)\n", near_city->getName().c_str(), near_city->getId());
3043 printf("it is located at %d,%d\n", near_city->getPos().x, near_city->getPos().y);
3044 City *other = GameMap::getCity(near_city->getPos());
3047 printf("the OTHER nearCity is %s (%d)\n", other->getName().c_str(), other->getId());
3048 printf("it is located at %d,%d\n", other->getPos().x, other->getPos().y);
3051 printf("no city there!\n");
3055 //if it's us then it's easier to just walk.
3059 //is that city already vectoring?
3060 if (near_city->getVectoring() != Vector<int>(-1, -1))
3063 //can i just walk there faster?
3065 //find mp from source to target city
3066 const ArmyProdBase *proto = c->getActiveProductionBase();
3067 PathCalculator pc1(c->getOwner(), c->getPos(), proto);
3068 int mp_from_source_city = pc1.calculate(target->getPos());
3070 //find mp from nearer vectorable city to target city
3071 PathCalculator pc2(c->getOwner(), near_city->getPos(), proto);
3072 int mp_from_near_city = pc2.calculate(target->getPos());
3074 guint32 max_moves_per_turn = proto->getMaxMoves();
3076 double turns_to_move_from_source_city =
3077 (double)mp_from_source_city / (double)max_moves_per_turn;
3078 double turns_to_move_from_near_city =
3079 (double)mp_from_near_city / (double)max_moves_per_turn;
3080 turns_to_move_from_near_city += 1.0; //add extra turn to vector
3082 //yes i can walk there faster, so don't vector
3083 if (turns_to_move_from_source_city <= turns_to_move_from_near_city)
3086 //great. now do the vectoring.
3087 c->changeVectorDestination(near_city->getPos());
3090 *vector_city = near_city;
3094 void Player::AI_setupVectoring(guint32 safe_mp, guint32 min_defenders,
3095 guint32 mp_to_front)
3097 Citylist *cl = Citylist::getInstance();
3098 //turn off vectoring where it isn't safe anymore
3099 //turn off vectoring for destinations that are far away from the
3100 //nearest enemy city
3103 for (Citylist::iterator cit = cl->begin(); cit != cl->end(); ++cit)
3107 if (c->getOwner() != this || c->isBurnt())
3109 Vector<int> dest = c->getVectoring();
3110 if (dest == Vector<int>(-1, -1))
3112 if (safeFromAttack(c, safe_mp, min_defenders) == false)
3114 //City *target_city = Citylist::getInstance()->getObjectAt(dest);
3115 //debug("stopping vectoring from " << c->getName() <<" to " << target_city->getName() << " because it's not safe to anymore!\n")
3116 c->setVectoring(Vector<int>(-1,-1));
3120 City *enemy_city = cl->getNearestEnemyCity(dest);
3123 //City *target_city = Citylist::getInstance()->getObjectAt(dest);
3124 //debug("stopping vectoring from " << c->getName() <<" to " << target_city->getName() << " because there aren't any more enemy cities!\n")
3125 c->setVectoring(Vector<int>(-1,-1));
3129 PathCalculator pc(this, dest, NULL);
3130 int mp = pc.calculate(enemy_city->getPos());
3131 if (mp <= 0 || mp > (int)mp_to_front)
3134 //City *target_city = Citylist::getInstance()->getObjectAt(dest);
3135 //debug("stopping vectoring from " << c->getName() <<" to " << target_city->getName() << " because it's too far away from an enemy city!\n")
3136 c->setVectoring(Vector<int>(-1,-1));
3141 for (Citylist::iterator cit = cl->begin(); cit != cl->end(); ++cit)
3145 if (c->getOwner() != this || c->isBurnt())
3147 City *enemy_city = cl->getNearestEnemyCity(c->getPos());
3150 City *vector_city = NULL;
3151 //if the city isn't already vectoring
3152 if (c->getVectoring() == Vector<int>(-1,-1))
3154 bool vectored = AI_maybeVector(c, safe_mp, min_defenders, enemy_city,
3157 debug("begin vectoring from " << c->getName() <<" to " << vector_city->getName() << "!\n");
3162 const Army * Player::doCityProducesArmy(City *city, Vector<int> &pos)
3164 int cost = city->getActiveProductionBase()->getProductionCost();
3168 const Army *a = city->armyArrives(pos);
3172 bool Player::cityProducesArmy(City *city)
3174 assert(city->getOwner() == this);
3175 Action_Produce *item = new Action_Produce();
3177 const Army *army = doCityProducesArmy(city, pos);
3180 const ArmyProdBase *source_army;
3181 source_army = city->getProductionBaseBelongingTo(army);
3182 if (city->getVectoring() == Vector<int>(-1, -1))
3183 item->fillData(source_army, city, false, pos, army->getId());
3185 item->fillData(source_army, city, true, city->getVectoring(), army->getId());
3191 Army* Player::doVectoredUnitArrives(VectoredUnit *unit)
3193 Army *army = unit->armyArrives();
3197 bool Player::vectoredUnitArrives(VectoredUnit *unit)
3199 Action_ProduceVectored *item = new Action_ProduceVectored();
3200 item->fillData(unit->getArmy(), unit->getDestination(), unit->getPos());
3202 Army *army = doVectoredUnitArrives(unit);
3205 printf("this was supposed to be impossible because of operations on the vectoredunitlist after the city is conquered.\n");
3206 printf("whooops... this vectored unit failed to show up.\n");
3207 City *dest = GameMap::getCity(unit->getDestination());
3208 printf("the unit was being vectored to: %s, from %s by %s\n",
3209 dest->getName().c_str(),
3210 GameMap::getCity(unit->getPos())->getName().c_str(), getName().c_str());
3211 printf("Army is a %s, turns is %d + 1\n", unit->getArmy()->getName().c_str(), unit->getArmy()->getProduction());
3215 std::list<History*> h = dest->getOwner()->getHistoryForCityId(dest->getId());
3216 std::list<History*>::const_iterator pit;
3217 for (pit = h.begin(); pit != h.end(); pit++)
3219 switch ((*pit)->getType())
3221 case History::START_TURN:
3226 case History::CITY_WON:
3228 History_CityWon *event;
3229 event = dynamic_cast<History_CityWon*>(*pit);
3230 //printf("on turn %d, player %s took %s\n", turn, dest->getOwner()->getName().c_str(), dest->getName().c_str());
3233 case History::CITY_RAZED:
3235 History_CityRazed *event;
3236 event = dynamic_cast<History_CityRazed*>(*pit);
3237 printf("on turn %d, player %s razed %s\n", turn, dest->getOwner()->getName().c_str(), dest->getName().c_str());
3244 printf("was the destination city owned by us way back then?\n");
3251 std::list<Action_Produce *> Player::getUnitsProducedThisTurn() const
3253 std::list<Action_Produce *> actions;
3254 std::list<Action *>::const_reverse_iterator it = d_actions.rbegin();
3255 for (; it != d_actions.rend(); it++)
3257 if ((*it)->getType() == Action::PRODUCE_UNIT)
3258 actions.push_back(dynamic_cast<Action_Produce*>(*it));
3259 else if ((*it)->getType() == Action::INIT_TURN)
3264 std::list<Action *> Player::getReportableActions() const
3266 std::list<Action *> actions;
3267 std::list<Action *>::const_iterator it = d_actions.begin();
3268 for (; it != d_actions.end(); it++)
3270 if ((*it)->getType() == Action::PRODUCE_UNIT ||
3271 (*it)->getType() == Action::PRODUCE_VECTORED_UNIT ||
3272 (*it)->getType() == Action::CITY_DESTITUTE)
3273 actions.push_back(*it);
3278 void Player::cityTooPoorToProduce(City *city, int slot)
3280 cityChangeProduction(city, -1);
3281 const ArmyProdBase *a = city->getProductionBase(slot);
3282 Action_CityTooPoorToProduce *action = new Action_CityTooPoorToProduce();
3283 action->fillData(city, a);
3287 void Player::pruneActionlist()
3289 pruneActionlist(d_actions);
3292 void Player::pruneCityProductions(std::list<Action*> actions)
3294 //remove duplicate city production actions
3296 //enumerate the ones we want
3297 std::list<Action_Production*> keepers;
3298 std::list<Action*>::reverse_iterator ait;
3299 for (ait = actions.rbegin(); ait != actions.rend(); ait++)
3301 if ((*ait)->getType() != Action::CITY_PROD)
3303 //if this city isn't already in the keepers list, then add it.
3305 Action_Production *action = static_cast<Action_Production*>(*ait);
3307 std::list<Action_Production*>::const_iterator it;
3308 for (it = keepers.begin(); it != keepers.end(); it++)
3310 if (action->getCityId() == (*it)->getCityId())
3317 keepers.push_back(action);
3321 //now delete all city production events that aren't in keepers
3323 std::list<Action*>::iterator bit;
3324 for (bit = actions.begin(); bit != actions.end(); bit++)
3326 if ((*bit)->getType() != Action::CITY_PROD)
3328 if (find (keepers.begin(), keepers.end(), (*bit)) == keepers.end())
3331 actions.erase (bit);
3332 bit = actions.begin();
3337 //printf ("pruned %d city production actions.\n", total);
3340 void Player::pruneCityVectorings(std::list<Action*> actions)
3342 //remove duplicate city vectoring actions
3344 //enumerate the ones we want
3345 std::list<Action_Vector*> keepers;
3346 std::list<Action*>::reverse_iterator ait;
3347 for (ait = actions.rbegin(); ait != actions.rend(); ait++)
3349 if ((*ait)->getType() != Action::CITY_VECTOR)
3351 //if this city isn't already in the keepers list, then add it.
3353 Action_Vector *action = static_cast<Action_Vector *>(*ait);
3355 std::list<Action_Vector*>::const_iterator it;
3356 for (it = keepers.begin(); it != keepers.end(); it++)
3358 if (action->getCityId() == (*it)->getCityId())
3365 keepers.push_back(action);
3369 //now delete all city vector events that aren't in keepers
3371 std::list<Action*>::iterator bit;
3372 for (bit = actions.begin(); bit != actions.end(); bit++)
3374 if ((*bit)->getType() != Action::CITY_VECTOR)
3376 if (find (keepers.begin(), keepers.end(), (*bit)) == keepers.end())
3379 actions.erase (bit);
3380 bit = actions.begin();
3385 //printf ("pruned %d city vector actions.\n", total);
3388 void Player::pruneActionlist(std::list<Action*> actions)
3390 pruneCityProductions(actions);
3391 pruneCityVectorings(actions);
3395 std::string Player::playerTypeToString(const Player::Type type)
3400 return "Player::HUMAN";
3401 case Player::AI_FAST:
3402 return "Player::AI_FAST";
3403 case Player::AI_DUMMY:
3404 return "Player::AI_DUMMY";
3405 case Player::AI_SMART:
3406 return "Player::AI_SMART";
3407 case Player::NETWORKED:
3408 return "Player::NETWORKED";
3410 return "Player::HUMAN";
3413 Player::Type Player::playerTypeFromString(const std::string str)
3415 if (str.size() > 0 && isdigit(str.c_str()[0]))
3416 return Player::Type(atoi(str.c_str()));
3417 if (str == "Player::HUMAN")
3418 return Player::HUMAN;
3419 else if (str == "Player::AI_FAST")
3420 return Player::AI_FAST;
3421 else if (str == "Player::AI_DUMMY")
3422 return Player::AI_DUMMY;
3423 else if (str == "Player::AI_SMART")
3424 return Player::AI_SMART;
3425 else if (str == "Player::NETWORKED")
3426 return Player::NETWORKED;
3427 return Player::HUMAN;
3430 bool Player::hasAlreadyInitializedTurn() const
3432 for (list<Action*>::const_iterator it = d_actions.begin();
3433 it != d_actions.end(); it++)
3434 if ((*it)->getType() == Action::INIT_TURN)
3439 bool Player::hasAlreadyEndedTurn() const
3441 for (list<Action*>::const_iterator it = d_actions.begin();
3442 it != d_actions.end(); it++)
3443 if ((*it)->getType() == Action::END_TURN)
3448 std::list<History*> Player::getHistoryForThisTurn() const
3450 std::list<History*> history;
3451 for (list<History*>::const_reverse_iterator it = d_history.rbegin();
3452 it != d_history.rend(); it++)
3454 history.push_front(*it);
3455 if ((*it)->getType() == History::START_TURN)
3461 guint32 Player::countEndTurnHistoryEntries() const
3464 for (list<History*>::const_iterator it = d_history.begin();
3465 it != d_history.end(); it++)
3467 if ((*it)->getType() == History::END_TURN)
3473 void Player::loadPbmGame()
3475 for (list<Action*>::const_iterator it = d_actions.begin();
3476 it != d_actions.end(); it++)
3478 NetworkAction *copy = new NetworkAction(*it, getId());
3481 std::list<History*> history = getHistoryForThisTurn();
3482 for (list<History*>::const_iterator it = history.begin();
3483 it != history.end(); it++)
3485 NetworkHistory *copy = new NetworkHistory(*it, getId());
3486 history_written.emit(copy);
3490 void Player::saveNetworkActions(XML_Helper *helper) const
3492 for (list<Action*>::const_iterator it = d_actions.begin();
3493 it != d_actions.end(); it++)
3495 NetworkAction *copy = new NetworkAction(*it, getId());
3500 bool Player::searchedRuin(Ruin *r) const
3504 for (list<History*>::const_iterator it = d_history.begin();
3505 it != d_history.end(); it++)
3507 if ((*it)->getType() == History::HERO_RUIN_EXPLORED)
3509 History_HeroRuinExplored *event =
3510 dynamic_cast<History_HeroRuinExplored*>(*it);
3511 if (event->getRuinId() == r->getId())
3518 bool Player::conqueredCity(City *c) const
3522 for (list<History*>::const_iterator it = d_history.begin();
3523 it != d_history.end(); it++)
3525 if ((*it)->getType() == History::CITY_WON)
3527 History_CityWon *event = dynamic_cast<History_CityWon*>(*it);
3528 if (event->getCityId() == c->getId())
3535 std::list<Vector<int> > Player::getStackTrack(Stack *s) const
3537 std::list<Vector<int> > points;
3538 Vector<int> delta = Vector<int>(0,0);
3539 for (list<Action*>::const_iterator it = d_actions.begin();
3540 it != d_actions.end(); it++)
3542 if ((*it)->getType() == Action::STACK_MOVE)
3544 Action_Move *action = dynamic_cast<Action_Move*>(*it);
3545 if (action->getStackId() == s->getId())
3547 if (points.size() == 0)
3548 delta = action->getPositionDelta();
3549 points.push_back(action->getEndingPosition());
3553 if (points.size() >= 1)
3555 Vector<int> pos = points.front() + delta;
3556 if (pos != points.front())
3557 points.push_front(pos);
3562 std::list<History *>Player::getHistoryForCityId(guint32 id) const
3564 std::list<History*> events;
3565 std::list<History*>::const_iterator pit;
3566 for (pit = d_history.begin(); pit != d_history.end(); pit++)
3568 switch ((*pit)->getType())
3570 case History::START_TURN:
3572 events.push_back(*pit);
3575 case History::CITY_WON:
3577 History_CityWon *event;
3578 event = dynamic_cast<History_CityWon*>(*pit);
3579 if (event->getCityId() == id)
3580 events.push_back(*pit);
3583 case History::CITY_RAZED:
3585 History_CityRazed *event;
3586 event = dynamic_cast<History_CityRazed*>(*pit);
3587 if (event->getCityId() == id)
3588 events.push_back(*pit);
3598 std::list<History *>Player::getHistoryForHeroId(guint32 id) const
3600 std::string hero_name = "";
3601 std::list<History*> events;
3602 std::list<History*>::const_iterator pit;
3603 for (pit = d_history.begin(); pit != d_history.end(); pit++)
3605 switch ((*pit)->getType())
3607 case History::HERO_EMERGES:
3609 History_HeroEmerges *event;
3610 event = dynamic_cast<History_HeroEmerges *>(*pit);
3611 if (event->getHeroId() == id)
3613 hero_name = event->getHeroName();
3614 events.push_back(*pit);
3618 case History::FOUND_SAGE:
3620 History_FoundSage *event;
3621 event = dynamic_cast<History_FoundSage*>(*pit);
3622 if (event->getHeroName() == hero_name)
3623 events.push_back(*pit);
3626 case History::HERO_QUEST_STARTED:
3628 History_HeroQuestStarted *event;
3629 event = dynamic_cast<History_HeroQuestStarted*>(*pit);
3630 if (event->getHeroName() == hero_name)
3631 events.push_back(*pit);
3634 case History::HERO_QUEST_COMPLETED:
3636 History_HeroQuestCompleted *event;
3637 event = dynamic_cast<History_HeroQuestCompleted*>(*pit);
3638 if (event->getHeroName() == hero_name)
3639 events.push_back(*pit);
3642 case History::HERO_KILLED_IN_CITY:
3644 History_HeroKilledInCity *event;
3645 event = dynamic_cast<History_HeroKilledInCity*>(*pit);
3646 if (event->getHeroName() == hero_name)
3647 events.push_back(*pit);
3650 case History::HERO_KILLED_IN_BATTLE:
3652 History_HeroKilledInBattle *event;
3653 event = dynamic_cast<History_HeroKilledInBattle*>(*pit);
3654 if (event->getHeroName() == hero_name)
3655 events.push_back(*pit);
3658 case History::HERO_KILLED_SEARCHING:
3660 History_HeroKilledSearching*event;
3661 event = dynamic_cast<History_HeroKilledSearching*>(*pit);
3662 if (event->getHeroName() == hero_name)
3663 events.push_back(*pit);
3666 case History::HERO_CITY_WON:
3668 History_HeroCityWon *event;
3669 event = dynamic_cast<History_HeroCityWon*>(*pit);
3670 if (event->getHeroName() == hero_name)
3671 events.push_back(*pit);
3674 case History::HERO_FINDS_ALLIES:
3676 History_HeroFindsAllies *event;
3677 event = dynamic_cast<History_HeroFindsAllies*>(*pit);
3678 if (event->getHeroName() == hero_name)
3679 events.push_back(*pit);
3689 void Player::setSurrendered(bool surr)
3693 std::list<Hero*> Player::getHeroes() const
3695 return d_stacklist->getHeroes();
3697 guint32 Player::countArmies() const
3699 return d_stacklist->countArmies();
3701 guint32 Player::countAllies() const
3703 return d_stacklist->countAllies();
3705 Stack * Player::getActivestack() const
3707 return d_stacklist->getActivestack();
3709 void Player::setActivestack(Stack *s)
3711 d_stacklist->setActivestack(s);
3714 Vector<int> Player::getPositionOfArmyById(guint32 id) const
3716 return d_stacklist->getPosition(id);
3719 void Player::immobilize()
3721 d_stacklist->drainAllMovement();
3724 guint32 Player::getCostOfUnitsProducedThisTurn() const
3727 std::list<Action_Produce *> units = getUnitsProducedThisTurn();
3728 for (std::list<Action_Produce *>::const_iterator it = units.begin(); it != units.end(); it++)
3729 gold +=(*it)->getArmy()->getProductionCost();
3735 void Player::clearStacklist()
3737 d_stacklist->flClear();
3740 void Player::clearFogMap()
3742 d_fogmap->fill(FogMap::OPEN);
3746 std::list<Action *> Player::getActionsThisTurn(int type) const
3748 std::list<Action *> actions;
3749 std::list<Action *>::const_iterator it = d_actions.begin();
3750 for (; it != d_actions.end(); it++)
3752 if ((*it)->getType() == Action::Type(type))
3753 actions.push_back(*it);
3757 std::list<Action *> Player::getFightsThisTurn() const
3759 return getActionsThisTurn(Action::STACK_FIGHT);
3762 int Player::countFightsThisTurn() const
3764 return getFightsThisTurn().size();
3767 std::list<Action *> Player::getMovesThisTurn() const
3769 return getActionsThisTurn(Action::STACK_MOVE);
3772 int Player::countMovesThisTurn() const
3774 return getMovesThisTurn().size();
3777 int Player::countDestituteCitiesThisTurn() const
3779 return getActionsThisTurn(Action::CITY_DESTITUTE).size();
3782 Vector<int> Player::AI_getQuestDestination(Quest *quest, Stack *stack) const
3784 Playerlist *pl = Playerlist::getInstance();
3785 Vector<int> dest = Vector<int>(-1,-1);
3786 switch (quest->getType())
3788 case Quest::KILLHERO:
3790 QuestKillHero *q = dynamic_cast<QuestKillHero*>(quest);
3791 guint32 hero_id = q->getVictim();
3792 Stack *enemy = NULL;
3793 for (Playerlist::iterator it = pl->begin(); it != pl->end(); it++)
3797 enemy = (*it)->getStacklist()->getArmyStackById(hero_id);
3802 dest = enemy->getPos();
3806 case Quest::KILLARMYTYPE:
3808 QuestEnemyArmytype *q = dynamic_cast<QuestEnemyArmytype*>(quest);
3809 guint32 army_type = q->getArmytypeToKill();
3810 std::list<Stack*> s =
3811 GameMap::getNearbyEnemyStacks(stack->getPos(), GameMap::getWidth());
3812 for (std::list<Stack*>::iterator i = s.begin(); i != s.end(); i++)
3814 if ((*i)->hasArmyType(army_type) == true)
3816 dest = (*i)->getPos();
3822 case Quest::KILLARMIES:
3824 QuestEnemyArmies *q = dynamic_cast<QuestEnemyArmies*>(quest);
3825 Player *enemy = pl->getPlayer(q->getVictimPlayerId());
3826 std::list<Stack*> s =
3827 GameMap::getNearbyEnemyStacks(stack->getPos(), GameMap::getWidth());
3828 for (std::list<Stack*>::iterator i = s.begin(); i != s.end(); i++)
3830 if ((*i)->getOwner() != enemy)
3832 dest = (*i)->getPos();
3837 case Quest::PILLAGEGOLD:
3838 case Quest::CITYSACK:
3839 case Quest::CITYRAZE:
3840 case Quest::CITYOCCUPY:
3841 //attack the nearest enemy city.
3843 City *c = Citylist::getInstance()->getClosestEnemyCity(stack);
3845 dest = c->getNearestPos(stack->getPos());
3852 bool Player::AI_invadeCityQuestPreference(City *c, CityDefeatedAction &action) const
3855 std::vector<Quest*> q = QuestsManager::getInstance()->getPlayerQuests(this);
3856 for (std::vector<Quest*>::iterator i = q.begin(); i != q.end(); i++)
3858 switch ((*i)->getType())
3860 case Quest::CITYOCCUPY:
3862 QuestCityOccupy* qu = dynamic_cast<QuestCityOccupy*>(*i);
3863 if (qu->getCityId() == c->getId())
3865 action = CITY_DEFEATED_OCCUPY;
3870 case Quest::CITYSACK:
3872 QuestCitySack * qu = dynamic_cast<QuestCitySack*>(*i);
3873 if (qu->getCityId() == c->getId())
3875 action = CITY_DEFEATED_SACK;
3880 case Quest::CITYRAZE:
3882 QuestCityRaze* qu = dynamic_cast<QuestCityRaze*>(*i);
3883 if (qu->getCityId() == c->getId())
3885 action = CITY_DEFEATED_RAZE;
3890 case Quest::PILLAGEGOLD:
3891 action = CITY_DEFEATED_SACK;
3901 * what are the chances of a hero showing up?
3903 * 1 in 6 if you have enough gold, where "enough gold" is...
3905 * ... 1500 if the player already has a hero, then: 1500 is generally
3906 * enough to buy all the heroes. I forget the exact distribution of
3907 * hero prices but memory says from 1000 to 1500. (But, if you don't
3908 * have 1500 gold, and the price is less, you still get the offer...
3909 * So, calculate price, compare to available gold, then decided whether
3910 * or not to offer...)
3912 * ...500 if all your heroes are dead: then prices are cut by about
3915 bool Player::maybeRecruitHero ()
3917 bool accepted = false;
3920 int gold_needed = 0;
3921 if (Citylist::getInstance()->countCities(this) == 0)
3923 //give the player a hero if it's the first round.
3924 //otherwise we get a hero based on chance
3925 //a hero costs a random number of gold pieces
3926 if (GameScenarioOptions::s_round == 1 && getHeroes().size() == 0)
3930 bool exists = false;
3931 if (getHeroes().size() > 0)
3934 gold_needed = (rand() % 500) + 1000;
3935 if (exists == false)
3939 if ((((rand() % 6) == 0 && gold_needed < getGold()) || gold_needed == 0))
3941 HeroProto *heroproto =
3942 HeroTemplates::getInstance()->getRandomHero(getId());
3943 if (gold_needed == 0)
3945 //we do it this way because maybe quickstart is on.
3946 Citylist* cl = Citylist::getInstance();
3947 for (Citylist::iterator it = cl->begin(); it != cl->end(); ++it)
3948 if (!(*it)->isBurnt() && (*it)->getOwner() == this &&
3949 (*it)->getCapitalOwner() == this && (*it)->isCapital())
3954 if (!city) //no capital cities
3955 city = Citylist::getInstance()->getFirstCity(this);
3959 std::vector<City*> cities;
3960 Citylist* cl = Citylist::getInstance();
3961 for (Citylist::iterator it = cl->begin(); it != cl->end(); ++it)
3962 if (!(*it)->isBurnt() && (*it)->getOwner() == this)
3963 cities.push_back((*it));
3966 city = cities[rand() % cities.size()];
3969 if (srecruitingHero.empty())
3972 accepted = srecruitingHero.emit(heroproto, city, gold_needed);
3975 /* now maybe add a few allies */
3977 if (gold_needed > 1300)
3979 else if (gold_needed > 1000)
3981 else if (gold_needed > 800)
3986 const ArmyProto *ally = 0;
3987 if (alliesCount > 0)
3989 ally = Reward_Allies::randomArmyAlly();
3994 recruitHero(heroproto, city, gold_needed, alliesCount, ally);