1 // Copyright (C) 2006-2010, 2014, 2015, 2016, 2017, 2020 Ben Asselstine 2 // Copyright (C) 2007, 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 #pragma once 20 #ifndef GAME_H 21 #define GAME_H 22 23 #include <sigc++/signal.h> 24 #include <glibmm/ustring.h> 25 #include <sigc++/connection.h> 26 #include <memory> 27 #include <list> 28 29 #include "sidebar-stats.h" 30 #include "map-tip-position.h" 31 #include "callback-enums.h" 32 #include "army.h" 33 #include "fight.h" 34 #include "player.h" 35 #include "select-city-map.h" 36 37 class NextTurn; 38 class GameBigMap; 39 class SmallMap; 40 class GameScenario; 41 class Hero; 42 class City; 43 class Stack; 44 class Player; 45 class Temple; 46 class Ruin; 47 class Signpost; 48 class Fight; 49 class Quest; 50 class Reward; 51 class StackTile; 52 class Sage; 53 54 //! Connects the various game classes with the GameWindow through signals. 55 /** Controls a game. 56 * 57 * Manages the big and small map, the game scenario and who's turn it is, etc. 58 * It's mostly a puppeteer class that connects the various other classes with 59 * signals and callbacks. 60 * 61 */ 62 class Game 63 { 64 public: 65 Game(GameScenario* gameScenario, NextTurn *nextTurn, bool headless = false); 66 ~Game(); 67 68 void redraw(); 69 void blank(bool on); 70 71 void select_next_movable_stack(); 72 void center_selected_stack(); 73 void defend_selected_stack(); 74 void park_selected_stack(); 75 void deselect_selected_stack(); 76 void search_selected_stack(); 77 void select_item_to_use(); 78 void search_stack(Stack *stack, bool &gotquest, bool &stackdied); 79 void move_selected_stack_along_path(); 80 void move_all_stacks(); 81 void end_turn(); 82 void recalculate_moves_for_stack(Stack *s); 83 void update_sidebar_stats(); 84 85 void startGame(); // initiate game flow 86 void loadGame(); 87 void stopGame(); // stop game flow, clean up 88 // save current game, returns true if successful 89 bool saveGame(Glib::ustring file); 90 91 static GameScenario *getScenario(); 92 GameBigMap &get_bigmap(); 93 SmallMap &get_smallmap(); 94 95 // signals 96 sigc::signal<void, Vector<int> > current_map_position; 97 sigc::signal<void, Cairo::RefPtr<Cairo::Surface>, Gdk::Rectangle> smallmap_changed; 98 sigc::signal<void, Cairo::RefPtr<Cairo::Surface> > bigmap_changed; 99 sigc::signal<void, SidebarStats> sidebar_stats_changed; 100 sigc::signal<void, Glib::ustring> progress_status_changed; 101 sigc::signal<void> progress_changed; 102 sigc::signal<void, bool> 103 can_select_next_movable_stack, 104 can_center_selected_stack, 105 can_defend_selected_stack, 106 can_park_selected_stack, 107 can_deselect_selected_stack, 108 can_search_selected_stack, 109 can_inspect, 110 can_see_hero_levels, 111 can_use_item, 112 can_plant_standard_selected_stack, 113 can_move_selected_stack_along_path, 114 can_move_selected_stack, 115 can_group_ungroup_selected_stack, 116 can_move_all_stacks, 117 can_disband_stack, 118 can_change_signpost, 119 can_see_history, 120 can_see_diplomacy, 121 received_diplomatic_proposal, 122 city_too_poor_to_produce, 123 can_end_turn; 124 sigc::signal<void, Stack *> stack_info_changed; 125 sigc::signal<void, Glib::ustring, MapTipPosition, bool> map_tip_changed; 126 sigc::signal<void, StackTile *, MapTipPosition> stack_tip_changed; 127 sigc::signal<void, City *, MapTipPosition> city_tip_changed; 128 sigc::signal<void, Ruin*, Stack*, Reward*> ruin_searched; 129 sigc::signal<Reward*, Ruin*, Sage*, Stack*> sage_visited; 130 sigc::signal<void, LocationBox, Fight &> fight_started; 131 sigc::signal<void, LocationBox> abbreviated_fight_started; 132 sigc::signal<void, Stack *, Keeper*> ruinfight_started; 133 sigc::signal<void, float> advice_asked; 134 sigc::signal<void, Fight::Result> ruinfight_finished; 135 sigc::signal<bool, Player *, HeroProto *, City *, int> hero_offers_service; 136 sigc::signal<bool, int > enemy_offers_surrender; 137 sigc::signal<void, bool> surrender_answered; 138 sigc::signal<bool, Stack *, Player *, Vector<int> > stack_considers_treachery; 139 sigc::signal<bool, Hero *, Temple *, int> temple_searched; 140 sigc::signal<void, Hero *, Quest *> quest_assigned; 141 sigc::signal<CityDefeatedAction, City *, int> city_defeated; 142 sigc::signal<void, City *, int, unsigned int> city_pillaged; 143 sigc::signal<void, City *, int, std::list<guint32> > city_sacked; 144 sigc::signal<void, City *> city_razed; 145 sigc::signal<void, City *> city_visited; 146 sigc::signal<void, Ruin *> ruin_visited; 147 sigc::signal<void, Temple *> temple_visited; 148 sigc::signal<void, Player *, unsigned int> next_player_turn; 149 sigc::signal<void> remote_next_player_turn; 150 sigc::signal<void, int> hero_arrives; 151 sigc::signal<void, Army *, int> medal_awarded_to_army; 152 sigc::signal<Army::Stat, Hero *> hero_gains_level; 153 sigc::signal<void, Player *> game_loaded; 154 sigc::signal<void, Player *> game_over; 155 sigc::signal<void, Player *> player_died; 156 sigc::signal<void> game_stopped; 157 sigc::signal<void, Glib::ustring> commentator_comments; 158 sigc::signal<void, Stack*, Vector<int> > stack_moves; 159 sigc::signal<Item*, std::list<Item*> > select_item; 160 sigc::signal<Player*> select_item_victim_player; 161 sigc::signal<City*, SelectCityMap::Type> select_city_to_use_item_on; 162 163 //! Results of using items 164 sigc::signal<void, Player*, guint32> stole_gold; 165 sigc::signal<void, Player*, guint32> sunk_ships; 166 sigc::signal<void, Hero*, guint32> bags_picked_up; 167 sigc::signal<void, Hero *, guint32> mp_added_to_hero_stack; 168 sigc::signal<void, Hero *, Glib::ustring, guint32> worms_killed; 169 sigc::signal<void, Hero *> bridge_burned; 170 sigc::signal<void, Hero *, Ruin*, Glib::ustring> keeper_captured; 171 sigc::signal<void, Hero *, Glib::ustring> monster_summoned; 172 sigc::signal<void, Hero *, Glib::ustring, guint32> city_diseased; 173 sigc::signal<void, Hero *, Glib::ustring, Glib::ustring, guint32> city_defended; 174 sigc::signal<void, Hero *, Glib::ustring, guint32> city_persuaded; 175 sigc::signal<void, Hero *, Glib::ustring> stack_teleported; 176 sigc::signal<void, Stack*> popup_stack_actions_menu; 177 sigc::signal<void, Vector<int> > pointing_at_new_tile; 178 179 void addPlayer(Player *p); 180 181 void inhibitAutosaveRemoval(bool inhibit); 182 183 void endOfGameRoaming(Player *winner); 184 private: 185 static Game *current_game; 186 187 // centers the map on a city of the active player 188 void center_view_on_city(); 189 190 void update_control_panel(); 191 void update_stack_info(); // emit stack_info_changed 192 void clear_stack_info(); 193 194 // locks/unlocks the input widgets during computer turns 195 void lock_inputs(); 196 void unlock_inputs(); 197 198 //! Maybe peform treachery 199 bool maybeTreachery(Stack *stack, Player *them, Vector<int> pos); 200 201 // bigmap callbacks 202 void on_stack_selected(); 203 void on_stack_grouped_or_ungrouped(); 204 void on_city_visted (City* c); 205 void on_ruin_queried (Ruin* r, bool brief); 206 void on_temple_queried (Temple* t, bool brief); 207 void on_signpost_queried (Signpost* s); 208 void on_show_path_turns (Vector<int> tile, guint32 turns); 209 void on_stack_queried (Vector<int> tile); 210 void on_stack_unqueried (); 211 void on_city_visited(City *city); // for city window 212 void on_city_queried (Vector<int>, City *city); // for city info tip 213 void on_city_unqueried (); 214 215 // smallmap callbacks 216 void on_smallmap_changed(Cairo::RefPtr<Cairo::Surface> map); 217 void on_bigmap_changed(Cairo::RefPtr<Cairo::Surface> map); 218 219 // misc. callbacks 220 void invading_city(City* city, int gold); 221 void init_turn_for_player(Player* p); 222 void on_player_died(Player *p); 223 bool stack_searches_ruin(Stack *stack); 224 bool stack_searches_temple(Stack *stack); 225 void on_use_item(Item *item); 226 void on_ruinfight_started(Stack *attacker, Keeper *keeper); 227 void on_ruinfight_finished(Fight::Result result); 228 229 //! Callback when the army of a human player reaches a new level. 230 Army::Stat heroGainsLevel(Hero * a); 231 //! Callback when an army gets a new medal. 232 void newMedalArmy(Army* a, int medaltype); 233 //! Called whenever a stack has changed, updates the map etc. 234 void stackUpdate(Stack* s); 235 //! Called whenever players fight 236 void on_fight_started(Fight &fight); 237 //! Called whenever a player receives an offer of surrender 238 void on_surrender_offered(Player *recipient); 239 void nextRound(); 240 //! Called after a player's stack attacks a city 241 void on_city_fight_finished(City *city, Fight::Result result); 242 243 void looting_city(City *city, int &gold); 244 void unselect_active_stack(); 245 void select_active_stack(); 246 bool recruitHero(HeroProto *hero, City *city, int gold); 247 248 void on_stack_grouped(Stack *stack); 249 void stack_arrives_on_tile(Stack *stack, Vector<int> tile); 250 void stack_leaves_tile(Stack *stack, Vector<int> tile); 251 void on_stack_halted(Stack *stack); 252 void on_stack_stopped(); 253 void on_stack_starts_moving(); 254 255 bool ask_if_treachery(Stack *stack, Player *them, Vector<int> pos); 256 void on_save_game(Glib::ustring filename); 257 guint32 on_get_round(); 258 void on_pointing_at_new_tile (Vector<int> tile); 259 260 void on_bag_dropped (); 261 void on_stack_died (); 262 263 GameScenario* d_gameScenario; 264 NextTurn* d_nextTurn; 265 std::unique_ptr<GameBigMap> bigmap; 266 std::unique_ptr<SmallMap> smallmap; 267 268 269 bool input_locked; 270 271 std::list<sigc::connection> connections[MAX_PLAYERS + 1]; 272 }; 273 274 #endif 275