1 // Copyright (C) 2006, 2007, 2008, 2009 Ben Asselstine
2 // Copyright (C) 2007, 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
25 #include <sigc++/functors/mem_fun.h>
26 #include <sigc++/adaptors/bind.h>
30 #include "ucompose.hpp"
31 #include "rectangle.h"
33 #include "GraphicsCache.h"
34 #include "GameScenario.h"
35 #include "NextTurnNetworked.h"
36 #include "NextTurnHotseat.h"
37 #include "NextTurnPbm.h"
39 #include "gamebigmap.h"
45 #include "heroproto.h"
46 #include "stacklist.h"
49 #include "templelist.h"
50 #include "signpostlist.h"
56 #include "playerlist.h"
58 #include "Configuration.h"
63 #include "game-parameters.h"
67 #include "pbm-game-server.h"
68 #include "LocationBox.h"
70 #include "MapBackpack.h"
71 #include "stacktile.h"
73 #include "herotemplates.h"
74 #include "GameScenarioOptions.h"
78 #include "Commentator.h"
80 Game *Game::current_game = 0;
82 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<flush<<endl;}
84 void Game::addPlayer(Player *p)
87 //disconnect prior players' connections
88 for (std::list<sigc::connection>::iterator it =
89 connections[p->getId()].begin();
90 it != connections[p->getId()].end(); it++)
92 connections[p->getId()].clear();
94 //now setup the connections that are specific for human players
95 if (p->getType() == Player::HUMAN)
97 connections[p->getId()].push_back
98 (p->sheroGainsLevel.connect(sigc::mem_fun(this, &Game::heroGainsLevel)));
99 connections[p->getId()].push_back
100 (p->snewMedalArmy.connect(sigc::mem_fun(this, &Game::newMedalArmy)));
102 connections[p->getId()].push_back
103 (p->streachery.connect
106 (stack_considers_treachery,
107 &sigc::signal<bool, Player *, Stack *, Player *, Vector<int> >::emit), p)));
108 connections[p->getId()].push_back
109 (p->hero_arrives_with_allies.connect
111 (hero_arrives, &sigc::signal<void, int>::emit)));
112 connections[p->getId()].push_back
113 (p->advice_asked.connect
114 (sigc::mem_fun(advice_asked, &sigc::signal<void, float>::emit)));
115 connections[p->getId()].push_back
116 (p->shaltedStack.connect
117 (sigc::mem_fun(this, &Game::on_stack_halted)));
118 connections[p->getId()].push_back
119 (p->getStacklist()->sgrouped.connect
120 (sigc::mem_fun(this, &Game::on_stack_grouped)));
124 //now do all of the common connections
126 connections[p->getId()].push_back
127 (p->getStacklist()->snewpos.connect
128 (sigc::mem_fun(stack_moves, &sigc::signal<void, Stack*, Vector<int> >::emit)));
129 connections[p->getId()].push_back
130 (p->srecruitingHero.connect(sigc::mem_fun(this, &Game::recruitHero)));
131 connections[p->getId()].push_back
132 (p->svisitingTemple.connect
133 (sigc::mem_fun(this, &Game::stack_searches_temple)));
134 connections[p->getId()].push_back
135 (p->ssearchingRuin.connect
136 (sigc::mem_fun(this, &Game::stack_searches_ruin)));
137 connections[p->getId()].push_back
138 (p->getStacklist()->snewpos.connect
139 (sigc::mem_fun(this, &Game::stack_arrives_on_tile)));
140 connections[p->getId()].push_back
141 (p->getStacklist()->soldpos.connect
142 (sigc::mem_fun(this, &Game::stack_leaves_tile)));
143 connections[p->getId()].push_back
144 (p->aborted_turn.connect (sigc::mem_fun
145 (game_stopped, &sigc::signal<void>::emit)));
147 connections[p->getId()].push_back
148 (p->schangingStats.connect
149 (sigc::mem_fun(this, &Game::update_sidebar_stats)));
151 connections[p->getId()].push_back
152 (p->schangingStatus.connect
153 (sigc::mem_fun(progress_status_changed, &sigc::signal<void, std::string>::emit)));
155 connections[p->getId()].push_back
156 (p->sbusy.connect (sigc::mem_fun (progress_changed,
157 &sigc::signal<void>::emit)));
158 connections[p->getId()].push_back
159 (p->supdatingStack.connect (sigc::mem_fun(this, &Game::stackUpdate)));
160 connections[p->getId()].push_back
161 (p->sinvadingCity.connect(sigc::mem_fun(this, &Game::invading_city)));
162 connections[p->getId()].push_back
163 (p->streacheryStack.connect(sigc::mem_fun(this, &Game::maybeTreachery)));
164 connections[p->getId()].push_back
165 (p->fight_started.connect (sigc::mem_fun(*this, &Game::on_fight_started)));
166 connections[p->getId()].push_back
167 (p->ruinfight_started.connect
169 (ruinfight_started, &sigc::signal<void, Stack *, Stack *>::emit)));
170 connections[p->getId()].push_back
171 (p->ruinfight_finished.connect
173 (ruinfight_finished, &sigc::signal<void, Fight::Result>::emit)));
174 connections[p->getId()].push_back
175 (p->cityfight_finished.connect (sigc::mem_fun(*this, &Game::on_city_fight_finished)));
176 if (p->getType() == Player::NETWORKED && p == Playerlist::getActiveplayer())
178 if (p->getType() == Player::HUMAN && p == Playerlist::getActiveplayer())
182 void Game::on_stack_halted(Stack *stack)
186 bigmap->reset_path_calculator(stack);
187 //tell gamebigmap that a stack just stopped
189 void Game::on_stack_grouped(Stack *stack, bool grouped)
191 bigmap->reset_path_calculator(stack);
192 //tell gamebigmap that we just grouped/ungrouped a stack.
195 #include "game-server.h"
197 Game::Game(GameScenario* gameScenario, NextTurn *nextTurn)
198 : d_gameScenario(gameScenario), d_nextTurn(nextTurn)
201 input_locked = false;
204 bigmap.reset(new GameBigMap
205 (GameScenario::s_intense_combat,
206 GameScenario::s_see_opponents_production,
207 GameScenario::s_see_opponents_stacks,
208 GameScenario::s_military_advisor));
209 bigmap->stack_selected.connect(
210 sigc::mem_fun(this, &Game::on_stack_selected));
211 bigmap->stack_grouped_or_ungrouped.connect(
212 sigc::mem_fun(this, &Game::on_stack_grouped_or_ungrouped));
213 bigmap->path_set.connect(
214 sigc::mem_fun(this, &Game::update_control_panel));
215 bigmap->city_visited.connect(
216 sigc::mem_fun(this, &Game::on_city_visited));
217 bigmap->city_queried.connect(
218 sigc::mem_fun(this, &Game::on_city_queried));
219 bigmap->city_unqueried.connect(
220 sigc::mem_fun(this, &Game::on_city_unqueried));
221 bigmap->ruin_queried.connect(
222 sigc::mem_fun(this, &Game::on_ruin_queried));
223 bigmap->signpost_queried.connect(
224 sigc::mem_fun(this, &Game::on_signpost_queried));
225 bigmap->temple_queried.connect(
226 sigc::mem_fun(this, &Game::on_temple_queried));
227 bigmap->stack_queried.connect(
228 sigc::mem_fun(this, &Game::on_stack_queried));
229 bigmap->stack_unqueried.connect(
230 sigc::mem_fun(this, &Game::on_stack_unqueried));
233 smallmap.reset(new SmallMap);
234 // pass map changes directly through
236 smallmap->map_changed.connect(
237 sigc::mem_fun(smallmap_changed,
238 &sigc::signal<void, Glib::RefPtr<Gdk::Pixmap>,
239 Gdk::Rectangle>::emit));
241 // connect the two maps
242 bigmap->view_changed.connect(
243 sigc::mem_fun(smallmap.get(), &SmallMap::set_view));
244 bigmap->map_changed.connect(
245 sigc::mem_fun(bigmap_changed,
246 &sigc::signal<void, Glib::RefPtr<Gdk::Pixmap> >::emit));
247 smallmap->view_changed.connect(
248 sigc::mem_fun(bigmap.get(), &GameBigMap::set_view));
250 // get the maps up and running
251 bigmap->screen_size_changed(Gtk::Allocation(0,0,320,200));
253 // connect player callbacks
254 Playerlist* pl = Playerlist::getInstance();
255 for (Playerlist::iterator i = pl->begin(); i != pl->end(); ++i)
260 if (gameScenario->getPlayMode() == GameScenario::HOTSEAT)
261 pl->splayerDead.connect(sigc::mem_fun(this, &Game::on_player_died));
262 pl->ssurrender.connect(sigc::mem_fun(this, &Game::on_surrender_offered));
264 d_nextTurn->splayerStart.connect(
265 sigc::mem_fun(this, &Game::init_turn_for_player));
266 d_nextTurn->snextRound.connect(
267 sigc::mem_fun(d_gameScenario, &GameScenario::nextRound));
268 d_nextTurn->snextRound.connect(
269 sigc::mem_fun(this, &Game::nextRound));
270 d_nextTurn->supdating.connect(
271 sigc::mem_fun(this, &Game::redraw));
274 center_view_on_city();
275 update_control_panel();
277 HeroTemplates::getInstance();
282 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
284 for (std::list<sigc::connection>::iterator it = connections[i].begin();
285 it != connections[i].end(); it++)
287 connections[i].clear();
289 delete d_gameScenario;
292 HeroTemplates::deleteInstance();
295 GameScenario *Game::getScenario()
297 return current_game->d_gameScenario;
300 void Game::end_turn()
302 //only human players hit this.
303 unselect_active_stack();
305 update_control_panel();
308 bool trigger_next_remote_player = false;
309 if (d_gameScenario->getPlayMode() == GameScenario::NETWORKED &&
310 Playerlist::getActiveplayer()->getType() == Player::NETWORKED)
311 trigger_next_remote_player = true;
312 d_nextTurn->endTurn();
313 if (trigger_next_remote_player)
314 remote_next_player_turn.emit();
317 void Game::update_stack_info()
319 Stack* stack = Playerlist::getActiveplayer()->getActivestack();
321 //if (Playerlist::getActiveplayer()->getType() != Player::HUMAN &&
322 //GameScenario::s_hidden_map == true)
324 stack_info_changed.emit(stack);
327 void Game::clear_stack_info()
329 stack_info_changed.emit(0);
332 void Game::update_sidebar_stats()
335 Player *player = Playerlist::getActiveplayer();
336 if (player == Playerlist::getInstance()->getNeutral())
339 s.name = player->getName();
340 s.gold = player->getGold();
341 s.income = s.cities = 0;
342 s.income = player->getIncome();
343 s.cities = Citylist::getInstance()->countCities(player);
346 s.upkeep = player->getUpkeep() + player->getCostOfUnitsProducedThisTurn();
347 Stacklist *sl = player->getStacklist();
348 for (Stacklist::iterator i = sl->begin(), iend = sl->end(); i != iend; ++i)
349 s.units += (*i)->size();
351 s.turns = d_gameScenario->getRound();
353 sidebar_stats_changed.emit(s);
360 bigmap->draw(Playerlist::getViewingplayer());
364 //if (Playerlist::getActiveplayer()->getType() == Player::HUMAN ||
365 //GameScenario::s_hidden_map == false)
366 smallmap->draw(Playerlist::getActiveplayer());
370 void Game::select_next_movable_stack()
372 Stacklist *sl = Playerlist::getActiveplayer()->getStacklist();
373 Stack* stack = sl->getNextMovable();
374 sl->setActivestack(stack);
375 select_active_stack();
378 void Game::move_map_dir(int diffx, int diffy)
380 smallmap->move_map_in_dir(Vector<int>(diffx, diffy));
383 void Game::move_selected_stack_dir(int diffx, int diffy)
385 Stack *stack = Playerlist::getActiveplayer()->getActivestack();
388 // Get rid of the old path if there is one
389 if (stack->getPath()->size())
390 stack->getPath()->clear();
391 //See if we can move there
392 Vector<int> dest = stack->getPos();
393 dest += Vector<int>(diffx, diffy);
394 int mp = stack->getPath()->calculate(stack, dest);
396 move_selected_stack_along_path();
399 Playerlist::getActiveplayer()->setActivestack(0);
400 unselect_active_stack();
404 void Game::move_selected_stack_northwest()
406 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
407 move_selected_stack_dir(-1, -1);
412 void Game::move_selected_stack_north()
414 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
415 move_selected_stack_dir(0, -1);
420 void Game::move_selected_stack_northeast()
422 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
423 move_selected_stack_dir(1, -1);
428 void Game::move_selected_stack_east()
430 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
431 move_selected_stack_dir(1, 0);
436 void Game::move_selected_stack_west()
438 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
439 move_selected_stack_dir(-1, 0);
444 void Game::move_selected_stack_southwest()
446 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
447 move_selected_stack_dir(-1, 1);
452 void Game::move_selected_stack_south()
454 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
455 move_selected_stack_dir(0, 1);
460 void Game::move_selected_stack_southeast()
462 if (Playerlist::getActiveplayer()->getActivestack() != NULL)
463 move_selected_stack_dir(1, 1);
468 void Game::move_selected_stack_along_path()
470 Stack *stack = Playerlist::getActiveplayer()->getActivestack();
472 Playerlist::getActiveplayer()->stackMove(stack);
474 //maybe we joined another stack
475 stack = Playerlist::getActiveplayer()->getActivestack();
476 if (stack && stack->canMove() == false)
478 Playerlist::getActiveplayer()->setActivestack(0);
479 unselect_active_stack();
483 void Game::move_all_stacks()
485 Player *player = Playerlist::getActiveplayer();
486 Stacklist* sl = player->getStacklist();
488 for (Stacklist::iterator i = sl->begin(), end = sl->end(); i != end; ++i)
491 if (!(s.empty()) && !(s.getPath()->empty()) && s.enoughMoves())
493 sl->setActivestack(&s);
494 select_active_stack();
495 bool moved = player->stackMove(player->getActivestack());
502 if (sl->getActivestack()->canMove() == false)
504 Playerlist::getActiveplayer()->setActivestack(0);
505 unselect_active_stack();
509 void Game::defend_selected_stack()
511 Player *player = Playerlist::getActiveplayer();
512 Stack *stack = player->getActivestack();
515 stack->setDefending(true);
517 stack = player->getStacklist()->getNextMovable();
518 player->setActivestack(stack);
521 select_active_stack();
523 unselect_active_stack();
526 void Game::park_selected_stack()
528 Player *player = Playerlist::getActiveplayer();
529 Stack *stack = player->getActivestack();
531 stack->setParked(true);
533 stack = player->getStacklist()->getNextMovable();
534 player->setActivestack(stack);
537 select_active_stack();
539 unselect_active_stack();
542 void Game::deselect_selected_stack()
544 Player *player = Playerlist::getActiveplayer();
545 player->setActivestack(0);
546 unselect_active_stack();
549 void Game::center_selected_stack()
551 Stack *stack = Playerlist::getActiveplayer()->getActivestack();
553 select_active_stack();
556 void Game::search_stack(Stack *stack)
558 Player *player = Playerlist::getActiveplayer();
559 Ruin* ruin = GameMap::getRuin(stack);
560 Temple* temple = GameMap::getTemple(stack);
562 if (ruin && !ruin->isSearched() && stack->hasHero() &&
563 stack->getFirstHero()->getMoves() > 0 &&
564 ((ruin->isHidden() == true && ruin->getOwner() == player) ||
565 ruin->isHidden() == false))
569 reward = player->stackSearchRuin(stack, ruin);
570 if (ruin->hasSage() == true)
572 Sage *sage = ruin->generateSage();
573 if (player->isComputer() == false)
574 reward = sage_visited.emit(ruin, sage, stack);
576 reward = player->chooseReward(ruin, sage, stack);
581 player->giveReward(stack, reward);
582 //FIXME: delete this reward, but don't delete the item, or map
585 update_control_panel();
586 if (player->isComputer() == false)
587 ruin_searched.emit(ruin, stack, reward);
593 update_control_panel();
596 update_sidebar_stats();
598 else if (temple && temple->searchable() && stack->getMoves() > 0)
601 blessCount = player->stackVisitTemple(stack, temple);
603 Hero *hero = stack->getFirstHeroWithoutAQuest();
604 if (player->isComputer() == false)
605 wants_quest = temple_searched.emit(hero, temple, blessCount);
607 wants_quest = player->chooseQuest(hero);
608 if (wants_quest && stack->hasHero())
610 Quest *q = player->heroGetQuest
612 GameScenario::s_razing_cities != GameParameters::NEVER);
616 if (player->isComputer() == false)
619 Army *a = stack->getArmyById(q->getHeroId());
621 hero = dynamic_cast<Hero*>(a);
622 quest_assigned.emit(hero, q);
629 void Game::search_selected_stack()
631 Player *player = Playerlist::getActiveplayer();
632 Stack* stack = player->getActivestack();
633 return search_stack(stack);
636 void Game::stackUpdate(Stack* s)
639 s = Playerlist::getActiveplayer()->getActivestack();
641 //if player is not to be observed, bail now
642 if (s != NULL && s->getOwner()->isObservable() == false)
646 smallmap->center_view_on_tile(s->getPos(), true);
651 update_control_panel();
655 Army::Stat Game::heroGainsLevel(Hero * h)
657 // don't show a dialog if computer or enemy's armies advance
658 if (h->getOwner()->isComputer() == true ||
659 h->getOwner() != Playerlist::getInstance()->getActiveplayer())
660 return Playerlist::getInstance()->getActiveplayer()->chooseStat(h);
662 return hero_gains_level.emit(h);
665 void Game::newMedalArmy(Army* a, int medaltype)
667 // We don't want to have medal awards of computer players displayed
669 || (a->getOwner()->getType() != Player::HUMAN)
670 || a->getOwner() != Playerlist::getInstance()->getActiveplayer())
673 medal_awarded_to_army.emit(a, medaltype);
677 void Game::on_stack_grouped_or_ungrouped(Stack *s)
679 //this only happens when we double-click on a stack on the bigmap.
681 update_control_panel();
684 void Game::on_stack_selected(Stack* s)
687 update_control_panel();
690 void Game::on_city_queried (Vector<int> tile, City *c)
692 MapTipPosition mpos = bigmap->map_tip_position(tile);
693 city_tip_changed.emit(c, mpos);
696 void Game::on_city_unqueried ()
698 city_tip_changed.emit(NULL, MapTipPosition());
701 void Game::on_city_visited(City* c)
705 city_visited.emit(c);
706 // some visible city properties (razed) may have changed
711 void Game::on_ruin_queried (Ruin* r, bool brief)
722 // note to translators: whether a ruin has been searched
723 str += _("Explored");
725 // note to translators: whether a ruin has been searched
726 str += _("Unexplored");
728 MapTipPosition mpos = bigmap->map_tip_position(r->getArea());
729 map_tip_changed.emit(str, mpos);
733 ruin_visited.emit(r);
737 map_tip_changed.emit("", MapTipPosition());
740 void Game::on_signpost_queried (Signpost* s)
748 MapTipPosition mpos = bigmap->map_tip_position(s->getArea());
749 map_tip_changed.emit(str, mpos);
752 map_tip_changed.emit("", MapTipPosition());
755 void Game::on_stack_unqueried ()
757 stack_tip_changed.emit(NULL, MapTipPosition());
759 void Game::on_stack_queried (Vector<int> tile)
761 MapTipPosition mpos = bigmap->map_tip_position(tile);
762 stack_tip_changed.emit(GameMap::getStacks(tile), mpos);
765 void Game::on_temple_queried (Temple* t, bool brief)
775 MapTipPosition mpos = bigmap->map_tip_position(t->getArea());
776 map_tip_changed.emit(str, mpos);
780 temple_visited.emit(t);
784 map_tip_changed.emit("", MapTipPosition());
787 void Game::looting_city(City* city, int &gold)
789 Citylist *clist = Citylist::getInstance();
790 Playerlist *plist = Playerlist::getInstance();
791 Player *attacker = plist->getActiveplayer();
792 Player *defender = city->getOwner();
793 int amt = (defender->getGold() / (2 * clist->countCities (defender)) * 2);
794 // give (Enemy-Gold/(2Enemy-Cities)) to the attacker
795 // and then take away twice that from the defender.
796 // the idea here is that some money is taken in the invasion
797 // and other monies are lost forever
798 defender->withdrawGold (amt);
800 attacker->addGold (amt);
805 void Game::invading_city(City* city, int gold)
807 Player *player = Playerlist::getInstance()->getActiveplayer();
809 if (player->getType() == Player::HUMAN)
812 CityDefeatedAction a = city_defeated.emit(city, gold);
816 case CITY_DEFEATED_OCCUPY:
817 player->cityOccupy(city);
820 case CITY_DEFEATED_RAZE:
821 //the razing just happened in the are-you-sure dialog, and the user
823 city_razed.emit(city);
824 player->deteriorateDiplomaticRelationship (5);
827 case CITY_DEFEATED_PILLAGE:
829 int pillaged_army_type = -1;
830 player->cityPillage(city, gold, &pillaged_army_type);
831 city_pillaged.emit(city, gold, pillaged_army_type);
835 case CITY_DEFEATED_SACK:
836 std::list<guint32> sacked_types;
837 player->citySack(city, gold, &sacked_types);
838 city_sacked.emit(city, gold, sacked_types);
842 if (!city->isBurnt())
843 city_visited.emit(city);
848 update_sidebar_stats();
849 update_control_panel();
852 void Game::lock_inputs()
854 // don't accept modifying user input from now on
855 bigmap->reset_zoom();
856 bigmap->set_input_locked(true);
857 smallmap->set_input_locked(true);
859 update_control_panel();
862 void Game::unlock_inputs()
864 bigmap->set_input_locked(false);
865 smallmap->set_input_locked(false);
866 input_locked = false;
867 update_control_panel();
870 void Game::update_control_panel()
874 can_select_next_movable_stack.emit(false);
875 can_center_selected_stack.emit(false);
876 can_defend_selected_stack.emit(false);
877 can_park_selected_stack.emit(false);
878 can_deselect_selected_stack.emit(false);
879 can_search_selected_stack.emit(false);
880 can_plant_standard_selected_stack.emit(false);
881 can_move_selected_stack.emit(false);
882 can_move_selected_stack_along_path.emit(false);
883 can_move_all_stacks.emit(false);
884 can_group_ungroup_selected_stack.emit(false);
885 can_end_turn.emit(false);
886 can_disband_stack.emit(false);
887 can_change_signpost.emit(false);
888 can_see_history.emit(false);
889 can_see_diplomacy.emit(false);
894 Player *player = Playerlist::getActiveplayer();
895 Stacklist* sl = player->getStacklist();
897 bool all_defending_or_parked = true;
898 for (Stacklist::iterator i = sl->begin(); i != sl->end(); ++i)
899 if (!(*i)->getDefending() && !(*i)->getParked()
900 && *i != sl->getActivestack())
902 all_defending_or_parked = false;
906 bool all_immobile = true;
907 for (Stacklist::iterator i = sl->begin(); i != sl->end(); ++i)
908 if (!(*i)->getDefending() && !(*i)->getParked() && (*i)->canMove()
909 && *i != sl->getActivestack())
911 all_immobile = false;
914 can_select_next_movable_stack.emit(!all_defending_or_parked && !all_immobile);
916 // if any stack can move, enable the moveall button
917 can_move_all_stacks.emit(sl->enoughMoves());
919 Stack *stack = player->getActivestack();
921 can_defend_selected_stack.emit(stack != 0);
922 can_park_selected_stack.emit(stack != 0);
923 can_deselect_selected_stack.emit(stack != 0);
924 can_center_selected_stack.emit(stack != 0);
928 can_move_selected_stack_along_path.emit
929 ((!stack->getPath()->empty() && stack->enoughMoves()) ||
930 (!stack->getPath()->empty() && stack->getPath()->getMovesExhaustedAtPoint() > 0));
933 * a note about searching.
934 * ruins can be searched by stacks that have a hero, and when the
935 * hero has moves left. also the ruin must be unexplored.
936 * temples can be searched by any stack, when the stack has
939 if (stack->getMoves() > 0)
942 temple = GameMap::getTemple(stack);
943 can_search_selected_stack.emit(temple);
944 can_move_selected_stack.emit(true);
947 if (stack->hasHero())
949 Ruin *ruin = GameMap::getRuin(stack);
950 if (stack->getFirstHero()->getMoves() > 0 && ruin)
951 can_search_selected_stack.emit(!ruin->isSearched());
953 //does the hero have the player's standard?
954 for (Stack::iterator it = stack->begin(); it != stack->end(); it++)
958 Hero *hero = dynamic_cast<Hero*>((*it));
959 if (hero->getBackpack()->getPlantableItem(player))
961 //can't plant on city/ruin/temple/signpost
962 City *city = GameMap::getCity(stack->getPos());
963 Temple *temple = GameMap::getTemple(stack);
964 Ruin *ruin = GameMap::getRuin(stack);
965 Signpost *sign = GameMap::getSignpost(stack);
966 if (!city && !temple && !ruin && !sign)
968 GameMap *gm = GameMap::getInstance();
969 MapBackpack *backpack;
970 Vector<int> pos = stack->getPos();
971 backpack = gm->getTile(pos)->getBackpack();
972 bool standard_already_planted =
973 backpack->getFirstPlantedItem() != NULL;
974 //are there any other standards here?
975 if (standard_already_planted == false)
976 can_plant_standard_selected_stack.emit(true);
984 can_plant_standard_selected_stack.emit(false);
987 if (GameMap::getSignpost(stack))
988 can_change_signpost.emit(true);
990 can_disband_stack.emit(true);
991 can_group_ungroup_selected_stack.emit(true);
995 can_search_selected_stack.emit(false);
996 can_move_selected_stack.emit(false);
997 can_move_selected_stack_along_path.emit(false);
998 can_disband_stack.emit(false);
999 can_group_ungroup_selected_stack.emit(false);
1000 can_plant_standard_selected_stack.emit(false);
1003 if (d_gameScenario->getRound() > 1)
1004 can_see_history.emit(true);
1006 can_see_history.emit(false);
1008 can_see_diplomacy.emit(GameScenarioOptions::s_diplomacy);
1010 can_end_turn.emit(true);
1013 GameBigMap &Game::get_bigmap()
1015 assert(bigmap.get());
1016 return *bigmap.get();
1019 SmallMap &Game::get_smallmap()
1021 assert(smallmap.get());
1022 return *smallmap.get();
1025 void Game::startGame()
1027 debug ("start_game()");
1029 center_view_on_city();
1030 update_sidebar_stats();
1031 update_control_panel();
1032 update_stack_info();
1035 d_nextTurn->start();
1036 if (Playerlist::getInstance()->countPlayersAlive())
1037 update_control_panel();
1040 void Game::loadGame()
1043 //if pbm and not human, then bail
1045 Player *player = Playerlist::getActiveplayer();
1048 Playerlist::getInstance()->nextPlayer();
1049 player = Playerlist::getActiveplayer();
1052 if (player->getType() == Player::HUMAN && (d_gameScenario->getPlayMode() == GameScenario::HOTSEAT))
1054 //human players want access to the controls and an info box
1056 player->setActivestack(0);
1057 center_view_on_city();
1058 update_sidebar_stats();
1059 update_control_panel();
1060 update_stack_info();
1061 game_loaded.emit(player);
1062 if (player->getType() == Player::HUMAN)
1063 d_nextTurn->setContinuingTurn();
1065 else if (player->getType() == Player::HUMAN &&
1066 d_gameScenario->getPlayMode() == GameScenario::PLAY_BY_MAIL)
1068 if (player->hasAlreadyInitializedTurn())
1071 player->setActivestack(0);
1072 center_view_on_city();
1073 update_sidebar_stats();
1074 update_control_panel();
1075 update_stack_info();
1076 game_loaded.emit(player);
1077 player->loadPbmGame();
1078 d_nextTurn->setContinuingTurn();
1088 d_nextTurn->start();
1093 update_sidebar_stats();
1094 player->startTurn();
1095 d_nextTurn->endTurn();
1096 if (Playerlist::getInstance()->countPlayersAlive())
1097 update_control_panel();
1102 void Game::stopGame()
1107 bool Game::saveGame(std::string file)
1109 return d_gameScenario->saveGame(file);
1112 void Game::blank(bool on)
1114 if (GameScenarioOptions::s_hidden_map == true)
1117 smallmap->blank(on);
1121 void Game::init_turn_for_player(Player* p)
1123 Playerlist* pl = Playerlist::getInstance();
1127 next_player_turn.emit(p, d_gameScenario->getRound());
1131 if (p->isObservable() == true)
1132 center_view_on_city();
1134 if (p->getType() == Player::HUMAN)
1136 if (Commentator::getInstance()->hasComment() == true)
1138 std::vector<std::string> comments =
1139 Commentator::getInstance()->getComments(p);
1140 if (comments.size() > 0)
1141 commentator_comments.emit(comments[rand() % comments.size()]);
1145 p->maybeRecruitHero();
1147 if (p->getType() == Player::HUMAN)
1151 update_sidebar_stats();
1152 update_stack_info();
1153 update_control_panel();
1156 // update the diplomacy icon if we've received a proposal
1157 bool proposal_received = false;
1158 for (Playerlist::iterator it = pl->begin(); it != pl->end(); ++it)
1160 if ((*it) == pl->getNeutral())
1166 if ((*it)->getDiplomaticProposal(p) != Player::NO_PROPOSAL)
1168 proposal_received = true;
1172 received_diplomatic_proposal.emit(proposal_received);
1173 //check to see if we've turned off production due to destitution.
1174 bool destitute = false;
1175 if (p->countDestituteCitiesThisTurn() > 0)
1177 city_too_poor_to_produce.emit(destitute);
1185 void Game::on_player_died(Player *player)
1187 const Playerlist* pl = Playerlist::getInstance();
1188 if (pl->getNoOfPlayers() <= 1)
1189 game_over.emit(pl->getFirstLiving());
1191 player_died.emit(player);
1195 void Game::on_fight_started(Fight &fight)
1198 //don't show the battle if the ai is attacking neutral
1199 bool ai_attacking_neutral = false;
1200 if (fight.getDefenders().front()->getOwner() == Playerlist::getInstance()->getNeutral() && Playerlist::getActiveplayer()->getType() != Player::HUMAN)
1201 ai_attacking_neutral = true;
1203 //show the battle if we're attacking an observable player
1204 bool attacking_observable_player = false;
1205 if (fight.getDefenders().front()->getOwner()->isObservable())
1206 attacking_observable_player = true;
1208 //don't show the battle if we're ai and we're on a hidden map
1209 bool ai_attacking_on_hidden_map = false;
1210 if (fight.getAttackers().front()->getOwner()->getType() != Player::HUMAN &&
1211 GameScenario::s_hidden_map == true)
1212 ai_attacking_on_hidden_map = true;
1214 if ((Playerlist::getActiveplayer()->isObservable() == true ||
1215 attacking_observable_player) && !ai_attacking_neutral &&
1216 !ai_attacking_on_hidden_map)
1218 Vector<int> pos = fight.getAttackers().front()->getPos();
1219 if (GameScenario::s_hidden_map == false)
1220 smallmap->center_view_on_tile(pos, true);
1221 fight_started.emit(Fight::calculateFightBox(fight), fight);
1223 else if ((Playerlist::getActiveplayer()->isObservable() == true ||
1224 attacking_observable_player) && ai_attacking_neutral &&
1225 !ai_attacking_on_hidden_map)
1227 Vector<int> pos = fight.getAttackers().front()->getPos();
1228 if (GameScenario::s_hidden_map == false)
1229 smallmap->center_view_on_tile(pos, true);
1230 abbreviated_fight_started.emit(Fight::calculateFightBox(fight));
1234 void Game::center_view_on_city()
1236 const Player* p = Playerlist::getInstance()->getActiveplayer();
1238 if (p == Playerlist::getInstance()->getNeutral())
1240 if (Playerlist::getActiveplayer()->getType() != Player::HUMAN &&
1241 GameScenario::s_hidden_map == true)
1243 //FIXME: if player is not to be observed, bail now
1244 // preferred city is a capital city that belongs to the player
1245 for (Citylist::iterator i = Citylist::getInstance()->begin();
1246 i != Citylist::getInstance()->end(); i++)
1249 if (c->getOwner() == p && c->isCapital() &&
1250 c->getCapitalOwner() == p)
1252 smallmap->center_view_on_tile(c->getPos(),
1253 !GameScenario::s_hidden_map);
1258 // okay, then find any city that belongs to the player and center on it
1259 for (Citylist::iterator i = Citylist::getInstance()->begin();
1260 i != Citylist::getInstance()->end(); i++)
1263 if (c->getOwner() == p)
1265 smallmap->center_view_on_tile(c->getPos(),
1266 !GameScenario::s_hidden_map);
1271 void Game::select_active_stack()
1273 //if (Playerlist::getActiveplayer()->getType() != Player::HUMAN &&
1274 //GameScenario::s_hidden_map == true)
1276 Player *p = Playerlist::getInstance()->getActiveplayer();
1277 smallmap->center_view_on_tile (p->getActivestack()->getPos(), true);
1278 bigmap->select_active_stack();
1280 void Game::unselect_active_stack()
1282 bigmap->unselect_active_stack();
1285 bool Game::maybeTreachery(Stack *stack, Player *them, Vector<int> pos)
1287 Player *me = stack->getOwner();
1288 bool treachery = false;
1289 if (me->isComputer())
1291 if (me->getType() == Player::AI_FAST)
1293 AI_Fast *ai = dynamic_cast<AI_Fast*>(me);
1294 treachery = ai->chooseTreachery (stack, them, pos);
1296 else if (me->getType() == Player::AI_SMART)
1298 AI_Smart *ai = dynamic_cast<AI_Smart*>(me);
1299 treachery = ai->chooseTreachery (stack, them, pos);
1302 if (treachery == false)
1304 me->proposeDiplomacy (Player::NO_PROPOSAL, them);
1305 me->declareDiplomacy (Player::AT_WAR, them);
1306 them->proposeDiplomacy (Player::NO_PROPOSAL, me);
1307 them->declareDiplomacy (Player::AT_WAR, me);
1308 History_DiplomacyTreachery *item = new History_DiplomacyTreachery();
1309 item->fillData(them);
1310 me->addHistory(item);
1312 me->deteriorateDiplomaticRelationship (5);
1313 them->improveDiplomaticRelationship (2, me);
1318 void Game::nextRound()
1320 Playerlist::getInstance()->nextRound
1321 (GameScenarioOptions::s_diplomacy,
1322 &GameScenarioOptions::s_surrender_already_offered);
1325 void Game::on_surrender_offered(Player *recipient)
1327 Playerlist *plist = Playerlist::getInstance();
1328 if (enemy_offers_surrender.emit(plist->countPlayersAlive() - 1))
1331 surrender_answered.emit(true);
1332 game_over.emit(recipient);
1335 surrender_answered.emit(false);
1338 void Game::recalculate_moves_for_stack(Stack *s)
1341 s = Playerlist::getActiveplayer()->getActivestack();
1344 s->getPath()->recalculate(s);
1346 update_control_panel();
1350 void Game::on_city_fight_finished(City *city, Fight::Result result)
1352 if (result != Fight::ATTACKER_WON)
1354 // we didn't suceed in defeating the defenders
1355 //if this is a neutral city, and we're playing with
1356 //active neutral cities, AND it hasn't already been attacked
1357 //then it's production gets turned on
1358 Player *neu = city->getOwner(); //neutral player
1359 if (GameScenario::s_neutral_cities == GameParameters::ACTIVE &&
1360 neu == Playerlist::getInstance()->getNeutral() &&
1361 city->getActiveProductionSlot() == -1)
1363 //great, then let's turn on the production.
1364 //well, we already made a unit, and we want to produce more
1366 Stack *o = GameMap::getStacks(city->getPos())->getFriendlyStack(neu);
1369 int army_type = o->getStrongestArmy()->getTypeId();
1370 for (guint32 i = 0; i < city->getMaxNoOfProductionBases(); i++)
1372 if (city->getArmytype(i) == army_type)
1374 // hey, we found the droid we were looking for
1375 city->setActiveProductionSlot(i);
1385 bool Game::recruitHero(HeroProto *hero, City *city, int gold)
1388 if (city->getOwner()->isComputer())
1389 retval = city->getOwner()->chooseHero (hero, city, gold);
1392 retval = hero_offers_service.emit (city->getOwner(), hero, city, gold);
1393 if (d_gameScenario->getRound() == 1)
1394 city_visited.emit(city);
1399 bool Game::saveTurnFile(std::string turnfile)
1402 //trigger the GameServer to spit out a set of networkactions and networkhistory events for the active player, into a file.
1403 if (d_gameScenario->getPlayMode() == GameScenario::PLAY_BY_MAIL)
1404 PbmGameServer::getInstance()->endTurn(turnfile, broken);
1408 void Game::inhibitAutosaveRemoval(bool inhibit)
1411 d_gameScenario->inhibitAutosaveRemoval(inhibit);
1414 void Game::endOfGameRoaming(Player *winner)
1416 Playerlist* pl = Playerlist::getInstance();
1417 pl->setWinningPlayer(winner);
1419 winner->immobilize();
1420 d_gameScenario->s_see_opponents_stacks = true;
1421 d_gameScenario->s_see_opponents_production = true;
1422 bigmap->d_see_opponents_stacks = true;
1423 bigmap->d_see_opponents_production = true;
1424 center_view_on_city();
1428 update_sidebar_stats();
1429 update_stack_info();
1430 update_control_panel();
1434 void Game::stack_arrives_on_tile(Stack *stack, Vector<int> tile)
1436 StackTile *stile = GameMap::getInstance()->getTile(tile)->getStacks();
1437 stile->arriving(stack);
1440 void Game::stack_leaves_tile(Stack *stack, Vector<int> tile)
1442 StackTile *stile = GameMap::getInstance()->getTile(tile)->getStacks();
1443 bool left = stile->leaving(stack);
1448 printf("stack is %p\n", stack);
1449 printf("WTFFF!!!!!!!!!!!!!!!!!!!!\n");
1455 void Game::stack_searches_ruin(Ruin *ruin, Stack *stack)
1457 search_stack(stack);
1460 void Game::stack_searches_temple(Temple *temple, Stack *stack)
1462 search_stack(stack);