1 // Copyright (C) 2008, 2009 Ben Asselstine
2 // Copyright (C) 2008 Ole Laursen
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Library General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "network_player.h"
25 #include "playerlist.h"
26 #include "armysetlist.h"
27 #include "stacklist.h"
30 #include "templelist.h"
32 #include "signpostlist.h"
34 #include "rewardlist.h"
35 #include "QuestsManager.h"
40 #include "armyprodbase.h"
42 #include "heroproto.h"
44 #include "MoveResult.h"
45 #include "Configuration.h"
47 #include "xmlhelper.h"
49 #include "game-parameters.h"
52 #include "vectoredunit.h"
54 #include "MapBackpack.h"
58 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
61 NetworkPlayer::NetworkPlayer(string name, guint32 armyset, Gdk::Color color, int width,
62 int height, Player::Type type, int player_no)
63 :Player(name, armyset, color, width, height, type, player_no),
64 d_connected(false), d_abort_requested(false)
68 NetworkPlayer::NetworkPlayer(const Player& player)
69 :Player(player), d_connected(false)
71 d_type = Player::NETWORKED;
72 d_abort_requested = false;
75 NetworkPlayer::NetworkPlayer(XML_Helper* helper)
76 :Player(helper), d_connected(false)
78 d_abort_requested = false;
81 NetworkPlayer::~NetworkPlayer()
85 bool NetworkPlayer::save(XML_Helper* helper) const
87 // This may seem a bit dumb, but allows derived players (especially
88 // AI's) to save additional data, such as character types or so.
90 retval &= helper->openTag(Player::d_tag);
91 retval &= Player::save(helper);
92 retval &= helper->closeTag();
97 void NetworkPlayer::abortTurn()
99 d_abort_requested = true;
102 bool NetworkPlayer::startTurn()
104 //d_stacklist->setActivestack(0);
109 void NetworkPlayer::endTurn()
113 void NetworkPlayer::invadeCity(City* c)
117 bool NetworkPlayer::chooseHero(HeroProto *hero, City *city, int gold)
123 Reward *NetworkPlayer::chooseReward(Ruin *ruin, Sage *sage, Stack *stack)
129 void NetworkPlayer::heroGainsLevel(Hero * a)
134 bool NetworkPlayer::chooseTreachery (Stack *stack, Player *player, Vector <int> pos)
140 Army::Stat NetworkPlayer::chooseStat(Hero *hero)
143 return Army::STRENGTH;
146 bool NetworkPlayer::chooseQuest(Hero *hero)
152 void NetworkPlayer::decodeActions(std::list<Action *> actions)
156 std::list<Action*>::iterator it = actions.begin();
158 for (; it != actions.end(); it++)
164 void NetworkPlayer::decodeAction(const Action *a)
166 d_actions.push_back(Action::copy(a));
169 case Action::STACK_MOVE:
170 return decodeActionMove(dynamic_cast<const Action_Move*>(a));
171 case Action::STACK_SPLIT:
172 return decodeActionSplit(dynamic_cast<const Action_Split*>(a));
173 case Action::STACK_FIGHT:
174 return decodeActionFight(dynamic_cast<const Action_Fight*>(a));
175 case Action::STACK_JOIN:
176 return decodeActionJoin(dynamic_cast<const Action_Join*>(a));
177 case Action::RUIN_SEARCH:
178 return decodeActionRuin(dynamic_cast<const Action_Ruin*>(a));
179 case Action::TEMPLE_SEARCH:
180 return decodeActionTemple(dynamic_cast<const Action_Temple*>(a));
181 case Action::CITY_OCCUPY:
182 return decodeActionOccupy(dynamic_cast<const Action_Occupy*>(a));
183 case Action::CITY_PILLAGE:
184 return decodeActionPillage
185 (dynamic_cast<const Action_Pillage*>(a));
186 case Action::CITY_SACK:
187 return decodeActionSack(dynamic_cast<const Action_Sack*>(a));
188 case Action::CITY_RAZE:
189 return decodeActionRaze(dynamic_cast<const Action_Raze*>(a));
190 case Action::CITY_UPGRADE:
191 return decodeActionUpgrade (dynamic_cast<const Action_Upgrade*>(a));
192 case Action::CITY_BUY:
193 return decodeActionBuy(dynamic_cast<const Action_Buy*>(a));
194 case Action::CITY_PROD:
195 return decodeActionProduction
196 (dynamic_cast<const Action_Production*>(a));
198 return decodeActionReward(dynamic_cast<const Action_Reward*>(a));
200 return decodeActionQuest(dynamic_cast<const Action_Quest*>(a));
201 case Action::HERO_EQUIP:
202 return decodeActionEquip(dynamic_cast<const Action_Equip*>(a));
203 case Action::UNIT_ADVANCE:
204 return decodeActionLevel(dynamic_cast<const Action_Level*>(a));
205 case Action::STACK_DISBAND:
206 return decodeActionDisband (dynamic_cast<const Action_Disband*>(a));
207 case Action::MODIFY_SIGNPOST:
208 return decodeActionModifySignpost
209 (dynamic_cast<const Action_ModifySignpost*>(a));
210 case Action::CITY_RENAME:
211 return decodeActionRenameCity
212 (dynamic_cast<const Action_RenameCity*>(a));
213 case Action::CITY_VECTOR:
214 return decodeActionVector (dynamic_cast<const Action_Vector*>(a));
215 case Action::FIGHT_ORDER:
216 return decodeActionFightOrder
217 (dynamic_cast<const Action_FightOrder*>(a));
219 return decodeActionResign(dynamic_cast<const Action_Resign*>(a));
220 case Action::ITEM_PLANT:
221 return decodeActionPlant(dynamic_cast<const Action_Plant*>(a));
222 case Action::PRODUCE_UNIT:
223 return decodeActionProduce (dynamic_cast<const Action_Produce*>(a));
224 case Action::PRODUCE_VECTORED_UNIT:
225 return decodeActionProduceVectored
226 (dynamic_cast<const Action_ProduceVectored*>(a));
227 case Action::DIPLOMATIC_STATE:
228 return decodeActionDiplomacyState
229 (dynamic_cast<const Action_DiplomacyState*>(a));
230 case Action::DIPLOMATIC_PROPOSAL:
231 return decodeActionDiplomacyProposal
232 (dynamic_cast<const Action_DiplomacyProposal*>(a));
233 case Action::DIPLOMATIC_SCORE:
234 return decodeActionDiplomacyScore
235 (dynamic_cast<const Action_DiplomacyScore*>(a));
236 case Action::END_TURN:
237 return decodeActionEndTurn
238 (dynamic_cast<const Action_EndTurn*>(a));
239 case Action::CITY_CONQUER:
240 return decodeActionConquerCity
241 (dynamic_cast<const Action_ConquerCity*>(a));
242 case Action::RECRUIT_HERO:
243 return decodeActionRecruitHero
244 (dynamic_cast<const Action_RecruitHero*>(a));
245 case Action::PLAYER_RENAME:
246 return decodeActionRenamePlayer
247 (dynamic_cast<const Action_RenamePlayer*>(a));
248 case Action::CITY_DESTITUTE:
249 return decodeActionCityTooPoorToProduce
250 (dynamic_cast<const Action_CityTooPoorToProduce*>(a));
251 case Action::INIT_TURN:
252 return decodeActionInitTurn
253 (dynamic_cast<const Action_InitTurn*>(a));
254 case Action::CITY_LOOT:
255 return decodeActionLoot
256 (dynamic_cast<const Action_Loot*>(a));
264 Stack *findStackById(guint32 id)
266 for (Playerlist::iterator j = Playerlist::getInstance()->begin(), jend = Playerlist::getInstance()->end();
268 Stack *s = (*j)->getStacklist()->getStackById(id);
278 void NetworkPlayer::decodeActionMove(const Action_Move *action)
280 Stack *stack = d_stacklist->getStackById(action->getStackId());
283 printf ("couldn't find stack with id %d\n", action->getStackId());
284 printf ("is there a stack near the ending position?\n");
285 for (int x = -1; x <= 1; x++)
286 for (int y = -1; y <= 1; y++)
288 Vector<int> dest = action->getEndingPosition() + Vector<int>(x,y);
289 Stack *s = GameMap::getFriendlyStack(dest);
290 printf ("stack at position %d,%d is %p\n", dest.x, dest.y, s);
292 printf ("stack id is %d\n", s->getId());
295 assert (stack != NULL);
296 stack->moveToDest(action->getEndingPosition());
297 stack->sortForViewing(true);
298 supdatingStack.emit(stack);
301 void NetworkPlayer::decodeActionSplit(const Action_Split *action)
303 guint32 stack_id = action->getStackId();
304 Stack *stack = d_stacklist->getStackById(stack_id);
305 assert (stack != NULL);
307 std::list<guint32> armies;
308 for (unsigned int i = 0; i < MAX_STACK_SIZE; ++i)
309 armies.push_back(action->getGroupedArmyId(i));
311 Stack *new_stack = NULL;
312 doStackSplitArmies(stack, armies, new_stack);
313 assert (new_stack != NULL);
314 if (new_stack->getId() != action->getNewStackId())
316 printf ("created stack with id %d, but expected %d\n", new_stack->getId(),
317 action->getNewStackId());
319 assert (new_stack->getId() == action->getNewStackId());
320 new_stack->sortForViewing(true);
321 stack->sortForViewing(true);
325 void NetworkPlayer::decodeActionFight(const Action_Fight *action)
327 std::list<Stack *> attackers, defenders;
328 std::list<guint32> attacker_army_ids = action->getAttackerArmyIds();
329 for (std::list<guint32>::const_iterator i = attacker_army_ids.begin(),
330 end = attacker_army_ids.end(); i != end; ++i)
331 attackers.push_back(d_stacklist->getStackById(*i));
333 std::list<guint32> defender_army_ids = action->getDefenderArmyIds();
334 for (std::list<guint32>::const_iterator i = defender_army_ids.begin(),
335 end = defender_army_ids.end(); i != end; ++i)
336 defenders.push_back(findStackById(*i));
338 Stack *attack = &*attackers.front();
339 Fight fight(attackers, defenders, action->getBattleHistory());
340 Fight::Result result = fight.battleFromHistory();
341 fight_started.emit(fight);
343 cleanupAfterFight(attackers, defenders);
344 if (result == Fight::ATTACKER_WON)
346 printf ("there are %d attackers left in %d at %d,%d\n", attack->size(),attack->getId(), attack->getPos().x, attack->getPos().y);
350 void NetworkPlayer::decodeActionJoin(const Action_Join *action)
352 Stack *receiver = d_stacklist->getStackById(action->getReceivingStackId());
353 Stack *joining = d_stacklist->getStackById(action->getJoiningStackId());
355 assert (receiver != NULL);
356 assert (joining != NULL);
357 doStackJoin(receiver, joining);
358 receiver->sortForViewing(true);
359 supdatingStack.emit(0);
362 void NetworkPlayer::decodeActionRuin(const Action_Ruin *action)
364 Stack *explorer = d_stacklist->getStackById(action->getStackId());
365 Ruin *r = Ruinlist::getInstance()->getById(action->getRuinId());
366 bool searched = action->getSearchSuccessful();
368 Stack* keeper = r->getOccupant();
370 // now simulate the fight that might have happened on the other side
374 for (Stack::iterator i = keeper->begin(); i != keeper->end(); ++i)
379 explorer->getFirstHero()->setHP(0);
382 std::list<Stack *> attackers, defenders;
383 attackers.push_back(explorer);
384 defenders.push_back(keeper);
386 cleanupAfterFight(attackers, defenders);
394 r->setSearched(searched);
396 //the reward is given to the player via the decodeActionReward method.
397 supdatingStack.emit(0);
400 void NetworkPlayer::decodeActionTemple(const Action_Temple *action)
402 Stack *stack = d_stacklist->getStackById(action->getStackId());
403 Temple *temple = Templelist::getInstance()->getById(action->getTempleId());
404 doStackVisitTemple(stack, temple);
407 void NetworkPlayer::decodeActionOccupy(const Action_Occupy *action)
409 City *city = Citylist::getInstance()->getById(action->getCityId());
413 void NetworkPlayer::decodeActionPillage(const Action_Pillage *action)
415 City *city = Citylist::getInstance()->getById(action->getCityId());
416 int gold, pillaged_army_type;
417 doCityPillage(city, gold, &pillaged_army_type);
420 void NetworkPlayer::decodeActionSack(const Action_Sack *action)
422 City *city = Citylist::getInstance()->getById(action->getCityId());
424 std::list<guint32> sacked_types;
425 doCitySack(city, gold, &sacked_types);
426 // FIXME: the game class doesn't listen for sack signals, so it doesn't
427 // redraw the map as it should
430 void NetworkPlayer::decodeActionRaze(const Action_Raze *action)
432 City *city = Citylist::getInstance()->getById(action->getCityId());
436 void NetworkPlayer::decodeActionUpgrade(const Action_Upgrade *action)
438 // doesn't exist, not handled
442 void NetworkPlayer::decodeActionBuy(const Action_Buy *action)
444 City *city = Citylist::getInstance()->getById(action->getCityId());
445 doCityBuyProduction(city, action->getProductionSlot(),
446 action->getBoughtArmyTypeId());
449 void NetworkPlayer::decodeActionProduction(const Action_Production *action)
451 City *city = Citylist::getInstance()->getById(action->getCityId());
452 doCityChangeProduction(city, action->getSlot());
455 void NetworkPlayer::decodeActionReward(const Action_Reward *action)
457 Stack *stack = d_stacklist->getStackById(action->getStackId());
458 doGiveReward(stack, action->getReward());
459 supdatingStack.emit(stack); // make sure we get a redraw
462 void NetworkPlayer::decodeActionQuest(const Action_Quest *action)
464 QuestsManager *qm = QuestsManager::getInstance();
465 switch (Quest::Type(action->getQuestType()))
467 case Quest::KILLHERO:
468 qm->createNewKillHeroQuest(action->getHeroId(), action->getData());
470 case Quest::KILLARMIES:
471 qm->createNewEnemyArmiesQuest(action->getHeroId(), action->getData(),
472 action->getVictimPlayerId());
474 case Quest::CITYSACK:
475 qm->createNewCitySackQuest(action->getHeroId(), action->getData());
477 case Quest::CITYRAZE:
478 qm->createNewCityRazeQuest(action->getHeroId(), action->getData());
480 case Quest::CITYOCCUPY:
481 qm->createNewCityOccupyQuest(action->getHeroId(), action->getData());
483 case Quest::KILLARMYTYPE:
484 qm->createNewEnemyArmytypeQuest(action->getHeroId(), action->getData());
486 case Quest::PILLAGEGOLD:
487 qm->createNewPillageGoldQuest(action->getHeroId(), action->getData());
492 void NetworkPlayer::decodeActionEquip(const Action_Equip *action)
494 Stack *stack = d_stacklist->getArmyStackById(action->getHeroId());
497 printf ("couldn't find hero with id %d\n", action->getHeroId());
499 assert (stack != NULL);
500 Hero *hero = dynamic_cast<Hero *>(stack->getArmyById(action->getHeroId()));
503 switch (action->getToBackpackOrToGround())
505 case Action_Equip::BACKPACK:
506 item = GameMap::getInstance()->getTile(action->getItemPos())->getBackpack()->getItemById(action->getItemId());
507 doHeroPickupItem(hero, item, action->getItemPos());
510 case Action_Equip::GROUND:
511 item = hero->getBackpack()->getItemById(action->getItemId());
512 doHeroDropItem(hero, item, action->getItemPos());
517 void NetworkPlayer::decodeActionLevel(const Action_Level *action)
519 Stack *stack = d_stacklist->getArmyStackById(action->getArmyId());
520 Hero*hero= dynamic_cast<Hero*>(stack->getArmyById(action->getArmyId()));
522 doHeroGainsLevel(hero, Army::Stat(action->getStatToIncrease()));
523 printf ("army is hero? %d\n", hero->isHero());
524 printf ("new level is %d\n", hero->getLevel());
527 void NetworkPlayer::decodeActionDisband(const Action_Disband *action)
529 Stack *stack = d_stacklist->getStackById(action->getStackId());
532 printf ("couldn't find stack with id %d\n", action->getStackId());
534 assert (stack != NULL);
535 bool found = doStackDisband(stack);
536 assert (found == true);
539 void NetworkPlayer::decodeActionModifySignpost(const Action_ModifySignpost *act)
541 Signpost *sign = Signpostlist::getInstance()->getById(act->getSignpostId());
542 doSignpostChange(sign, act->getSignContents());
545 void NetworkPlayer::decodeActionRenameCity(const Action_RenameCity *action)
547 City *city = Citylist::getInstance()->getById(action->getCityId());
548 doCityRename(city, action->getNewCityName());
551 void NetworkPlayer::decodeActionVector(const Action_Vector *action)
553 City *city = Citylist::getInstance()->getById(action->getCityId());
554 doVectorFromCity(city, action->getVectoringDestination());
557 void NetworkPlayer::decodeActionFightOrder(const Action_FightOrder *action)
559 doSetFightOrder(action->getFightOrder());
562 void NetworkPlayer::decodeActionResign(const Action_Resign *action)
567 void NetworkPlayer::decodeActionPlant(const Action_Plant *action)
569 Stack *stack = d_stacklist->getArmyStackById(action->getHeroId());
570 Hero *hero = dynamic_cast<Hero *>(stack->getArmyById(action->getHeroId()));
571 Item *item = hero->getBackpack()->getItemById(action->getItemId());
573 doHeroPlantStandard(hero, item, stack->getPos());
576 void NetworkPlayer::decodeActionProduce(const Action_Produce *action)
578 //if it was vectored, we just wait for the Action_ProduceVectored later on.
579 if (action->getVectored() == true)
581 printf ("produced unit but it's vectored.\n");
584 ArmyProdBase *a = action->getArmy();
585 City *c = Citylist::getInstance()->getById(action->getCityId());
586 Army *army = new Army (*a, this);
587 Stack *s = c->addArmy(army);
588 printf ("created army id %d, in stack %d of size %d\n", army->getId(), s->getId(), s->size());
589 assert (s->getPos() == action->getDestination());
590 assert (army->getId() == action->getArmyId());
591 s->sortForViewing(true);
594 void NetworkPlayer::decodeActionProduceVectored(const Action_ProduceVectored *action)
596 //create a vectored unit.
597 VectoredUnit v(action->getOrigination(), action->getDestination(),
598 action->getArmy(), 0, this);
599 Army *army = doVectoredUnitArrives(&v);
600 printf ("army is %p\n", army);
601 Stack *s = d_stacklist->getArmyStackById(army->getId());
602 s->sortForViewing(true);
603 printf ("created vectored army id %d, in stack %d of size %d\n", army->getId(), s->getId(), s->size());
606 void NetworkPlayer::decodeActionDiplomacyState(const Action_DiplomacyState *action)
608 Player *player = Playerlist::getInstance()->getPlayer(action->getOpponentId());
609 doDeclareDiplomacy(action->getDiplomaticState(), player);
612 void NetworkPlayer::decodeActionDiplomacyProposal(const Action_DiplomacyProposal *action)
614 Player *player = Playerlist::getInstance()->getPlayer(action->getOpponentId());
615 doProposeDiplomacy(action->getDiplomaticProposal(), player);
618 void NetworkPlayer::decodeActionDiplomacyScore(const Action_DiplomacyScore *action)
620 Player *player = Playerlist::getInstance()->getPlayer(action->getOpponentId());
621 alterDiplomaticRelationshipScore(player, action->getAmountChange());
624 void NetworkPlayer::decodeActionEndTurn(const Action_EndTurn *action)
626 printf ("ending turn!!\n");
630 void NetworkPlayer::decodeActionConquerCity(const Action_ConquerCity *action)
632 City *city = Citylist::getInstance()->getById(action->getCityId());
633 Stack *stack = d_stacklist->getStackById(action->getStackId());
634 doConquerCity(city, stack);
637 void NetworkPlayer::decodeActionRecruitHero(const Action_RecruitHero *action)
640 City *city = Citylist::getInstance()->getById(action->getCityId());
642 if (action->getNumAllies())
643 ally = Armysetlist::getInstance()->getArmy(getArmyset(),
644 action->getAllyArmyType());
645 Hero *hero = doRecruitHero(action->getHero(), city, action->getCost(),
646 action->getNumAllies(), ally);
647 printf ("created hero with id %d, in stack %d\n", hero->getId(),
648 d_stacklist->getArmyStackById(hero->getId())->getId());
650 d_stacklist->getArmyStackById(hero->getId())->sortForViewing(true);
653 void NetworkPlayer::decodeActionRenamePlayer(const Action_RenamePlayer *action)
655 doRename(action->getName());
658 void NetworkPlayer::decodeActionCityTooPoorToProduce(const Action_CityTooPoorToProduce *action)
660 //this action is only used for reporting purposes.
663 void NetworkPlayer::decodeActionInitTurn(const Action_InitTurn*action)
667 void NetworkPlayer::decodeActionLoot (const Action_Loot *action)
669 guint32 player_id = action->getLootedPlayerId();
670 Player *looted = Playerlist::getInstance()->getPlayer(player_id);
671 doLootCity(looted, action->getAmountToAdd(), action->getAmountToSubtract());