initial commit, lordsawar source, slightly modified
[lordsawar] / src / network_player.cpp
1 // Copyright (C) 2008, 2009 Ben Asselstine
2 // Copyright (C) 2008 Ole Laursen
3 //
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.
8 //
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.
13 //
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 
17 //  02110-1301, USA.
18
19 #include <fstream>
20 #include <algorithm>
21 #include <stdlib.h>
22 #include <assert.h>
23
24 #include "network_player.h"
25 #include "playerlist.h"
26 #include "armysetlist.h"
27 #include "stacklist.h"
28 #include "citylist.h"
29 #include "portlist.h"
30 #include "templelist.h"
31 #include "ruinlist.h"
32 #include "signpostlist.h"
33 #include "Itemlist.h"
34 #include "rewardlist.h"
35 #include "QuestsManager.h"
36 #include "Quest.h"
37 #include "path.h"
38 #include "GameMap.h"
39 #include "army.h"
40 #include "armyprodbase.h"
41 #include "hero.h"
42 #include "heroproto.h"
43 #include "action.h"
44 #include "MoveResult.h"
45 #include "Configuration.h"
46 #include "FogMap.h"
47 #include "xmlhelper.h"
48 #include "ruinlist.h"
49 #include "game-parameters.h"
50 #include "signpost.h"
51 #include "history.h"
52 #include "vectoredunit.h"
53 #include "Backpack.h"
54 #include "MapBackpack.h"
55
56 using namespace std;
57
58 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
59 #define debug(x)
60
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)
65 {
66 }
67
68 NetworkPlayer::NetworkPlayer(const Player& player)
69     :Player(player), d_connected(false)
70 {
71     d_type = Player::NETWORKED;
72     d_abort_requested = false;
73 }
74
75 NetworkPlayer::NetworkPlayer(XML_Helper* helper)
76     :Player(helper), d_connected(false)
77 {
78     d_abort_requested = false;
79 }
80
81 NetworkPlayer::~NetworkPlayer()
82 {
83 }
84
85 bool NetworkPlayer::save(XML_Helper* helper) const
86 {
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.
89     bool retval = true;
90     retval &= helper->openTag(Player::d_tag);
91     retval &= Player::save(helper);
92     retval &= helper->closeTag();
93
94     return retval;
95 }
96
97 void NetworkPlayer::abortTurn()
98 {
99   d_abort_requested = true;
100 }
101
102 bool NetworkPlayer::startTurn()
103 {
104   //d_stacklist->setActivestack(0);
105
106   return false;
107 }
108
109 void NetworkPlayer::endTurn()
110 {
111 }
112
113 void NetworkPlayer::invadeCity(City* c)
114 {
115   assert(false);
116 }
117 bool NetworkPlayer::chooseHero(HeroProto *hero, City *city, int gold)
118 {
119   assert(false);
120   return true;
121 }
122
123 Reward *NetworkPlayer::chooseReward(Ruin *ruin, Sage *sage, Stack *stack)
124 {
125   assert(false);
126   return NULL;
127 }
128
129 void NetworkPlayer::heroGainsLevel(Hero * a)
130 {
131   assert(false);
132 }
133
134 bool NetworkPlayer::chooseTreachery (Stack *stack, Player *player, Vector <int> pos)
135 {
136   assert(false);
137   return true;
138 }
139
140 Army::Stat NetworkPlayer::chooseStat(Hero *hero)
141 {
142   assert(false);
143   return Army::STRENGTH;
144 }
145
146 bool NetworkPlayer::chooseQuest(Hero *hero)
147 {
148   assert(false);
149   return true;
150 }
151
152 void NetworkPlayer::decodeActions(std::list<Action *> actions)
153 {
154   if (isDead())
155     return;
156   std::list<Action*>::iterator it = actions.begin();
157   pruneActionlist();
158   for (; it != actions.end(); it++)
159     {
160      decodeAction(*it);
161     }
162 }
163
164 void NetworkPlayer::decodeAction(const Action *a)
165 {
166   d_actions.push_back(Action::copy(a));
167   switch(a->getType())
168     {
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));
197     case Action::REWARD: 
198       return decodeActionReward(dynamic_cast<const Action_Reward*>(a));
199     case Action::QUEST:
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));
218     case Action::RESIGN:
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));
257     }
258
259   return;
260 }
261
262 // decode helpers
263   
264 Stack *findStackById(guint32 id)
265 {
266   for (Playerlist::iterator j = Playerlist::getInstance()->begin(), jend = Playerlist::getInstance()->end();
267        j != jend; ++j) {
268     Stack *s = (*j)->getStacklist()->getStackById(id);
269     if (s)
270       return s;
271   }
272   return 0;
273 }
274
275
276 // decoders
277
278 void NetworkPlayer::decodeActionMove(const Action_Move *action)
279 {
280   Stack *stack = d_stacklist->getStackById(action->getStackId());
281   if (stack == NULL)
282     {
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++)
287           {
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);
291             if (s)
292               printf ("stack id is %d\n", s->getId());
293           }
294     }
295   assert (stack != NULL);
296   stack->moveToDest(action->getEndingPosition());
297   stack->sortForViewing(true);
298   supdatingStack.emit(stack);
299 }
300
301 void NetworkPlayer::decodeActionSplit(const Action_Split *action)
302 {
303   guint32 stack_id = action->getStackId();
304   Stack *stack = d_stacklist->getStackById(stack_id);
305   assert (stack != NULL);
306   
307   std::list<guint32> armies;
308   for (unsigned int i = 0; i < MAX_STACK_SIZE; ++i) 
309     armies.push_back(action->getGroupedArmyId(i));
310
311   Stack *new_stack = NULL;
312   doStackSplitArmies(stack, armies, new_stack);
313   assert (new_stack != NULL);
314   if (new_stack->getId() != action->getNewStackId())
315     {
316       printf ("created stack with id %d, but expected %d\n", new_stack->getId(),
317               action->getNewStackId());
318     }
319   assert (new_stack->getId() == action->getNewStackId());
320   new_stack->sortForViewing(true);
321   stack->sortForViewing(true);
322
323 }
324
325 void NetworkPlayer::decodeActionFight(const Action_Fight *action)
326 {
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));
332
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));
337
338   Stack *attack = &*attackers.front();
339   Fight fight(attackers, defenders, action->getBattleHistory());
340   Fight::Result result = fight.battleFromHistory();
341   fight_started.emit(fight);
342
343   cleanupAfterFight(attackers, defenders);
344   if (result == Fight::ATTACKER_WON)
345     {
346       printf ("there are %d attackers left in %d at %d,%d\n", attack->size(),attack->getId(), attack->getPos().x, attack->getPos().y);
347     }
348 }
349
350 void NetworkPlayer::decodeActionJoin(const Action_Join *action)
351 {
352   Stack *receiver = d_stacklist->getStackById(action->getReceivingStackId());
353   Stack *joining = d_stacklist->getStackById(action->getJoiningStackId());
354
355   assert (receiver != NULL);
356   assert (joining != NULL);
357   doStackJoin(receiver, joining);
358   receiver->sortForViewing(true);
359   supdatingStack.emit(0);
360 }
361
362 void NetworkPlayer::decodeActionRuin(const Action_Ruin *action)
363 {
364   Stack *explorer = d_stacklist->getStackById(action->getStackId());
365   Ruin *r = Ruinlist::getInstance()->getById(action->getRuinId());
366   bool searched = action->getSearchSuccessful();
367
368   Stack* keeper = r->getOccupant();
369
370   // now simulate the fight that might have happened on the other side
371   if (keeper) {
372     if (searched) {
373       // whack the keeper
374       for (Stack::iterator i = keeper->begin(); i != keeper->end(); ++i)
375         (*i)->setHP(0);
376     }
377     else {
378       // whack the hero
379       explorer->getFirstHero()->setHP(0);
380     }
381
382     std::list<Stack *> attackers, defenders;
383     attackers.push_back(explorer);
384     defenders.push_back(keeper);
385     
386     cleanupAfterFight(attackers, defenders);
387
388     if (searched) {
389         r->setOccupant(0);
390         delete keeper;
391     }
392   }
393
394   r->setSearched(searched);
395
396   //the reward is given to the player via the decodeActionReward method.
397   supdatingStack.emit(0);
398 }
399
400 void NetworkPlayer::decodeActionTemple(const Action_Temple *action)
401 {
402   Stack *stack = d_stacklist->getStackById(action->getStackId());
403   Temple *temple = Templelist::getInstance()->getById(action->getTempleId());
404   doStackVisitTemple(stack, temple);
405 }
406
407 void NetworkPlayer::decodeActionOccupy(const Action_Occupy *action)
408 {
409   City *city = Citylist::getInstance()->getById(action->getCityId());
410   doCityOccupy(city);
411 }
412
413 void NetworkPlayer::decodeActionPillage(const Action_Pillage *action)
414 {
415   City *city = Citylist::getInstance()->getById(action->getCityId());
416   int gold, pillaged_army_type;
417   doCityPillage(city, gold, &pillaged_army_type);
418 }
419
420 void NetworkPlayer::decodeActionSack(const Action_Sack *action)
421 {
422   City *city = Citylist::getInstance()->getById(action->getCityId());
423   int gold;
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
428 }
429
430 void NetworkPlayer::decodeActionRaze(const Action_Raze *action)
431 {
432   City *city = Citylist::getInstance()->getById(action->getCityId());
433   doCityRaze(city);
434 }
435
436 void NetworkPlayer::decodeActionUpgrade(const Action_Upgrade *action)
437 {
438   // doesn't exist, not handled
439   assert(false);
440 }
441
442 void NetworkPlayer::decodeActionBuy(const Action_Buy *action)
443 {
444   City *city = Citylist::getInstance()->getById(action->getCityId());
445   doCityBuyProduction(city, action->getProductionSlot(), 
446                       action->getBoughtArmyTypeId());
447 }
448
449 void NetworkPlayer::decodeActionProduction(const Action_Production *action)
450 {
451   City *city = Citylist::getInstance()->getById(action->getCityId());
452   doCityChangeProduction(city, action->getSlot());
453 }
454
455 void NetworkPlayer::decodeActionReward(const Action_Reward *action)
456 {
457   Stack *stack = d_stacklist->getStackById(action->getStackId());
458   doGiveReward(stack, action->getReward());
459   supdatingStack.emit(stack); // make sure we get a redraw
460 }
461
462 void NetworkPlayer::decodeActionQuest(const Action_Quest *action)
463 {
464   QuestsManager *qm = QuestsManager::getInstance();
465   switch (Quest::Type(action->getQuestType()))
466     {
467     case Quest::KILLHERO: 
468       qm->createNewKillHeroQuest(action->getHeroId(), action->getData());
469       break;
470     case Quest::KILLARMIES:
471       qm->createNewEnemyArmiesQuest(action->getHeroId(), action->getData(), 
472                                     action->getVictimPlayerId());
473       break;
474     case Quest::CITYSACK:
475       qm->createNewCitySackQuest(action->getHeroId(), action->getData());
476       break;
477     case Quest::CITYRAZE:
478       qm->createNewCityRazeQuest(action->getHeroId(), action->getData());
479       break;
480     case Quest::CITYOCCUPY:
481       qm->createNewCityOccupyQuest(action->getHeroId(), action->getData());
482       break;
483     case Quest::KILLARMYTYPE:
484       qm->createNewEnemyArmytypeQuest(action->getHeroId(), action->getData());
485       break;
486     case Quest::PILLAGEGOLD:
487       qm->createNewPillageGoldQuest(action->getHeroId(), action->getData());
488       break;
489     }
490 }
491
492 void NetworkPlayer::decodeActionEquip(const Action_Equip *action)
493 {
494   Stack *stack = d_stacklist->getArmyStackById(action->getHeroId());
495   if (stack == NULL)
496     {
497       printf ("couldn't find hero with id %d\n", action->getHeroId());
498     }
499   assert (stack != NULL);
500   Hero *hero = dynamic_cast<Hero *>(stack->getArmyById(action->getHeroId()));
501   Item *item = 0;
502
503   switch (action->getToBackpackOrToGround())
504   {
505   case Action_Equip::BACKPACK:
506     item = GameMap::getInstance()->getTile(action->getItemPos())->getBackpack()->getItemById(action->getItemId());
507     doHeroPickupItem(hero, item, action->getItemPos());
508     break;
509
510   case Action_Equip::GROUND:
511     item = hero->getBackpack()->getItemById(action->getItemId());
512     doHeroDropItem(hero, item, action->getItemPos());
513     break;
514   }
515 }
516
517 void NetworkPlayer::decodeActionLevel(const Action_Level *action)
518 {
519   Stack *stack = d_stacklist->getArmyStackById(action->getArmyId());
520   Hero*hero= dynamic_cast<Hero*>(stack->getArmyById(action->getArmyId()));
521
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());
525 }
526
527 void NetworkPlayer::decodeActionDisband(const Action_Disband *action)
528 {
529   Stack *stack = d_stacklist->getStackById(action->getStackId());
530   if (stack == NULL)
531     {
532       printf ("couldn't find stack with id %d\n", action->getStackId());
533     }
534   assert (stack != NULL);
535   bool found = doStackDisband(stack);
536   assert (found == true);
537 }
538
539 void NetworkPlayer::decodeActionModifySignpost(const Action_ModifySignpost *act)
540 {
541   Signpost *sign = Signpostlist::getInstance()->getById(act->getSignpostId());
542   doSignpostChange(sign, act->getSignContents());
543 }
544
545 void NetworkPlayer::decodeActionRenameCity(const Action_RenameCity *action)
546 {
547   City *city = Citylist::getInstance()->getById(action->getCityId());
548   doCityRename(city, action->getNewCityName());
549 }
550
551 void NetworkPlayer::decodeActionVector(const Action_Vector *action)
552 {
553   City *city = Citylist::getInstance()->getById(action->getCityId());
554   doVectorFromCity(city, action->getVectoringDestination());
555 }
556
557 void NetworkPlayer::decodeActionFightOrder(const Action_FightOrder *action)
558 {
559   doSetFightOrder(action->getFightOrder());
560 }
561
562 void NetworkPlayer::decodeActionResign(const Action_Resign *action)
563 {
564   doResign();
565 }
566
567 void NetworkPlayer::decodeActionPlant(const Action_Plant *action)
568 {
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());
572     
573   doHeroPlantStandard(hero, item, stack->getPos());
574 }
575
576 void NetworkPlayer::decodeActionProduce(const Action_Produce *action)
577 {
578   //if it was vectored, we just wait for the Action_ProduceVectored later on.
579   if (action->getVectored() == true)
580     {
581       printf ("produced unit but it's vectored.\n");
582     return;
583     }
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);
592 }
593
594 void NetworkPlayer::decodeActionProduceVectored(const Action_ProduceVectored *action)
595 {
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());
604 }
605
606 void NetworkPlayer::decodeActionDiplomacyState(const Action_DiplomacyState *action)
607 {
608   Player *player = Playerlist::getInstance()->getPlayer(action->getOpponentId());
609   doDeclareDiplomacy(action->getDiplomaticState(), player);
610 }
611
612 void NetworkPlayer::decodeActionDiplomacyProposal(const Action_DiplomacyProposal *action)
613 {
614   Player *player = Playerlist::getInstance()->getPlayer(action->getOpponentId());
615   doProposeDiplomacy(action->getDiplomaticProposal(), player);
616 }
617
618 void NetworkPlayer::decodeActionDiplomacyScore(const Action_DiplomacyScore *action)
619 {
620   Player *player = Playerlist::getInstance()->getPlayer(action->getOpponentId());
621   alterDiplomaticRelationshipScore(player, action->getAmountChange());
622 }
623
624 void NetworkPlayer::decodeActionEndTurn(const Action_EndTurn *action)
625 {
626   printf ("ending turn!!\n");
627   ending_turn.emit();
628 }
629
630 void NetworkPlayer::decodeActionConquerCity(const Action_ConquerCity *action)
631 {
632   City *city = Citylist::getInstance()->getById(action->getCityId());
633   Stack *stack = d_stacklist->getStackById(action->getStackId());
634   doConquerCity(city, stack);
635 }
636
637 void NetworkPlayer::decodeActionRecruitHero(const Action_RecruitHero *action)
638 {
639
640   City *city = Citylist::getInstance()->getById(action->getCityId());
641   ArmyProto *ally = 0;
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());
649   //hero->syncNewId();
650   d_stacklist->getArmyStackById(hero->getId())->sortForViewing(true);
651 }
652
653 void NetworkPlayer::decodeActionRenamePlayer(const Action_RenamePlayer *action)
654 {
655   doRename(action->getName());
656 }
657
658 void NetworkPlayer::decodeActionCityTooPoorToProduce(const Action_CityTooPoorToProduce *action)
659 {
660   //this action is only used for reporting purposes.
661 }
662
663 void NetworkPlayer::decodeActionInitTurn(const Action_InitTurn*action)
664 {
665 }
666
667 void NetworkPlayer::decodeActionLoot (const Action_Loot *action)
668 {
669   guint32 player_id = action->getLootedPlayerId();
670   Player *looted = Playerlist::getInstance()->getPlayer(player_id);
671   doLootCity(looted, action->getAmountToAdd(), action->getAmountToSubtract());
672 }
673
674 // End of file