1 /*
2  * Copyright (C) 2002-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (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 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  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_WUI_INTERACTIVE_GAMEBASE_H
21 #define WL_WUI_INTERACTIVE_GAMEBASE_H
22 
23 #include <memory>
24 
25 #include "io/profile.h"
26 #include "logic/game.h"
27 #include "ui_basic/dropdown.h"
28 #include "ui_basic/unique_window.h"
29 #include "wui/general_statistics_menu.h"
30 #include "wui/interactive_base.h"
31 
32 struct ChatProvider;
33 
34 enum PlayerType { NONE, OBSERVER, PLAYING, VICTORIOUS, DEFEATED };
35 
36 class InteractiveGameBase : public InteractiveBase {
37 public:
38 	InteractiveGameBase(Widelands::Game&,
39 	                    Section& global_s,
40 	                    PlayerType pt,
41 	                    bool multiplayer,
42 	                    ChatProvider* chat_provider);
~InteractiveGameBase()43 	~InteractiveGameBase() override {
44 	}
45 	Widelands::Game* get_game() const;
46 	Widelands::Game& game() const;
47 
48 	virtual bool can_see(Widelands::PlayerNumber) const = 0;
49 	virtual bool can_act(Widelands::PlayerNumber) const = 0;
50 	virtual Widelands::PlayerNumber player_number() const = 0;
51 
52 	// Only the 'InteractiveGameBase' has all information of what should be
53 	// drawn into a map_view (i.e. which overlays are available). The
54 	// 'WatchWindow' does not have this information, but needs to draw
55 	// 'map_views', hence this function.
56 	virtual void draw_map_view(MapView* given_map_view, RenderTarget* dst) = 0;
57 
58 	void set_sel_pos(Widelands::NodeAndTriangle<> const center) override;
59 
60 	virtual void node_action(const Widelands::NodeAndTriangle<>& node_and_triangle) = 0;
get_playertype()61 	const PlayerType& get_playertype() const {
62 		return playertype_;
63 	}
set_playertype(const PlayerType & pt)64 	void set_playertype(const PlayerType& pt) {
65 		playertype_ = pt;
66 	}
67 
68 	void add_wanted_building_window(const Widelands::Coords& coords,
69 	                                const Vector2i point,
70 	                                bool was_minimal,
71 	                                bool was_pinned);
72 	UI::UniqueWindow* show_building_window(const Widelands::Coords& coords,
73 	                                       bool avoid_fastclick,
74 	                                       bool workarea_preview_wanted);
75 	bool try_show_ship_window();
76 	void show_ship_window(Widelands::Ship* ship);
is_multiplayer()77 	bool is_multiplayer() {
78 		return multiplayer_;
79 	}
80 
81 	void show_game_summary();
82 	/// For the game host. Show a window and ask the host player what to do with the tribe of the
83 	/// leaving client.
84 	bool show_game_client_disconnected();
85 	void postload() override;
86 	void start() override;
87 	void toggle_mainmenu();
88 
89 protected:
90 	// For referencing the items in showhidemenu_
91 	enum class ShowHideEntry {
92 		kBuildingSpaces,
93 		kCensus,
94 		kStatistics,
95 		kSoldierLevels,
96 		kWorkareaOverlap
97 	};
98 
99 	// Adds the mapviewmenu_ to the toolbar
100 	void add_main_menu();
101 	// Adds the showhidemenu_ to the toolbar
102 	void add_showhide_menu();
103 	void rebuild_showhide_menu() override;
104 	// Adds the gamespeedmenu_ to the toolbar
105 	void add_gamespeed_menu();
106 
107 	// Adds a chat toolbar button and registers the chat console window
108 	void add_chat_ui();
109 
110 	bool handle_key(bool down, SDL_Keysym code) override;
111 
112 	void draw_overlay(RenderTarget&) override;
113 
114 	// All unique menu windows
115 	struct GameMenuWindows {
116 		UI::UniqueWindow::Registry sound_options;
117 		UI::UniqueWindow::Registry savegame;
118 
119 		GeneralStatisticsMenu::Registry stats_general;
120 		UI::UniqueWindow::Registry stats_wares;
121 		UI::UniqueWindow::Registry stats_stock;
122 		UI::UniqueWindow::Registry stats_buildings;
123 		UI::UniqueWindow::Registry stats_seafaring;
124 
125 		UI::UniqueWindow::Registry help;
126 	} menu_windows_;
127 
128 	ChatProvider* chat_provider_;
129 	UI::UniqueWindow::Registry chat_;
130 	bool multiplayer_;
131 	PlayerType playertype_;
132 
133 	// Show / Hide menu on the toolbar
134 	UI::Dropdown<ShowHideEntry> showhidemenu_;
135 
136 	UI::UniqueWindow::Registry fieldaction_;
137 	UI::UniqueWindow::Registry game_summary_;
138 	UI::UniqueWindow::Registry client_disconnected_;
139 
140 private:
141 	// For referencing the items in mainmenu_
142 	enum class MainMenuEntry {
143 #ifndef NDEBUG  //  only in debug builds
144 		kScriptConsole,
145 #endif
146 		kOptions,
147 		kSaveMap,
148 		kExitGame
149 	};
150 
151 	// For referencing the items in gamespeedmenu_
152 	enum class GameSpeedEntry { kIncrease, kDecrease, kPause };
153 
154 	// Takes the appropriate action when an item in the mainmenu_ is selected
155 	void main_menu_selected(MainMenuEntry entry);
156 	// Takes the appropriate action when an item in the showhidemenu_ is selected
157 	void showhide_menu_selected(ShowHideEntry entry);
158 	// Takes the appropriate action when an item in the gamespeedmenu_ is selected
159 	void gamespeed_menu_selected(GameSpeedEntry entry);
160 	// Rebuilds the gamespeedmenu_ according to current game settings
161 	void rebuild_gamespeed_menu();
162 
163 	// Increases the gamespeed
164 	void increase_gamespeed(uint16_t speed);
165 	// Decreases the gamespeed
166 	void decrease_gamespeed(uint16_t speed);
167 	// Pauses / Unpauses the game and calls rebuild_gamespeed_menu
168 	void toggle_game_paused();
169 	// Resets the speed to 1x
170 	void reset_gamespeed();
171 
172 	struct WantedBuildingWindow {
WantedBuildingWindowWantedBuildingWindow173 		explicit WantedBuildingWindow(const Vector2i& pos,
174 		                              bool was_minimized,
175 		                              bool was_pinned,
176 		                              bool was_showing_workarea)
177 		   : window_position(pos),
178 		     minimize(was_minimized),
179 		     pin(was_pinned),
180 		     show_workarea(was_showing_workarea) {
181 		}
182 		const Vector2i window_position;
183 		const bool minimize;
184 		const bool pin;
185 		const bool show_workarea;
186 	};
187 
188 	// Main menu on the toolbar
189 	UI::Dropdown<MainMenuEntry> mainmenu_;
190 	// Game speed menu on the toolbar
191 	UI::Dropdown<GameSpeedEntry> gamespeedmenu_;
192 
193 	// Building coordinates, window position, whether the window was minimized
194 	std::map<uint32_t, std::unique_ptr<const WantedBuildingWindow>> wanted_building_windows_;
195 	std::unique_ptr<Notifications::Subscriber<Widelands::NoteBuilding>> buildingnotes_subscriber_;
196 };
197 
198 #endif  // end of include guard: WL_WUI_INTERACTIVE_GAMEBASE_H
199