Symphony Of Empires
main_menu.cpp
Go to the documentation of this file.
1 // Symphony of Empires
2 // Copyright (C) 2021, Symphony of Empires contributors
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 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, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // client/interface/main_menu.cpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #include "eng3d/ttf.hpp"
26 #include "eng3d/log.hpp"
27 #include "eng3d/texture.hpp"
28 #include "eng3d/ui/button.hpp"
29 #include "eng3d/ui/input.hpp"
30 #include "eng3d/ui/tooltip.hpp"
31 #include "eng3d/ui/ui.hpp"
32 #include "eng3d/ui/slider.hpp"
33 #include "eng3d/ui/checkbox.hpp"
34 #include "eng3d/ui/group.hpp"
35 #include "eng3d/ui/image.hpp"
36 #include "eng3d/ui/close_button.hpp"
37 
41 #include "world.hpp"
42 #include "client/map.hpp"
43 #include "client/map_render.hpp"
45 
46 //
47 // Main menu connect server
48 //
50  : UI::Window(0, 0, 512, 128),
51  gs{ _gs }
52 {
53  this->is_scroll = false;
54  this->set_text("Internet multiplayer");
55  this->set_close_btn_function([this](Widget&) {
56  this->kill();
57  });
58 
59  ip_addr_inp = new UI::Input(0, 0, 128, 24, this);
60  ip_addr_inp->set_buffer("127.0.0.1");
61  ip_addr_inp->set_tooltip("IP Address of the server\n"
62  "127.x.x.x: Local host\n"
63  "192.x.x.x: LAN IP range");
64 
65  username_inp = new UI::Input(0, 24, 512, 24, this);
66  username_inp->set_buffer("PlayerUsername");
67  username_inp->set_tooltip("Your publicly visible username");
68 
69  conn_btn = new UI::Button(0, 48, 128, 24, this);
70  conn_btn->set_text("Connect");
71  conn_btn->set_on_click([this](UI::Widget&) {
72  Eng3D::Log::debug("ui", translate_format("Connecting to server on IP %s", this->ip_addr_inp->get_buffer().c_str()));
74  this->gs.host_mode = false;
75  this->gs.editor = false;
76  try {
77  this->gs.ui_ctx.clear();
79  this->gs.select_nation = new Interface::LobbySelectView(gs);
80  this->gs.client = std::make_unique<Client>(this->gs, this->ip_addr_inp->get_buffer(), 1836);
81  this->gs.client->username = this->username_inp->get_buffer();
82  this->gs.client->wait_for_snapshot();
83  return;
85  this->gs.ui_ctx.prompt("Network layer error", e.what());
86  } catch(ClientException& e) {
87  this->gs.ui_ctx.prompt("Client error", e.what());
88  } catch(ServerException& e) {
89  this->gs.ui_ctx.prompt("Server error", e.what());
90  }
91  this->gs.client.reset();
92  });
93 }
94 
95 //
96 // Main menu
97 //
99  : UI::Div(250, -270, 300, 540),
100  gs{ _gs }
101 {
103  this->is_pinned = true;
104  this->is_scroll = false;
105 
106  auto menu_font = gs.ttf_man.load(gs.package_man.get_unique("fonts/neon_euler/euler.ttf"));
107  auto menu_text_color = Eng3D::Color(1.f, 1.f, 1.f);
108 
109  this->current_texture = gs.tex_man.load(gs.package_man.get_unique("gfx/ui/bg/main_menu.png"));
110  auto main_menu_border = gs.tex_man.load(gs.package_man.get_unique("gfx/ui/bg/main_menu_border.png"));
111  this->border = UI::Border(main_menu_border, glm::ivec2(16), glm::ivec2(16));
112  this->make_widget<UI::Image>(0, 0, 300, 120, "gfx/ui/image/logo.png");
113 
114  auto button_image = gs.tex_man.load(gs.package_man.get_unique("gfx/ui/button/button.png"));
115  auto button_border_image = gs.tex_man.load(gs.package_man.get_unique("gfx/ui/button/button_border.png"));
116  glm::ivec2 size(3, 3);
117  glm::ivec2 texture_size(3, 3);
118  auto button_border = UI::Border(button_border_image, size, texture_size);
119 
120  auto& button_list = this->make_widget<UI::Div>(0, 200, 300, 320);
121  button_list.flex = UI::Flex::COLUMN;
122  button_list.flex_align = UI::Align::CENTER;
123  button_list.flex_gap = 8;
124 
125  int b_width = 225;
126  int b_height = 33;
127 
128  auto& demo_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
129  demo_btn.border = button_border;
130  demo_btn.current_texture = button_image;
131  demo_btn.font = menu_font;
132  demo_btn.text_color = menu_text_color;
133  demo_btn.text_align_x = UI::Align::CENTER;
134  demo_btn.text_align_y = UI::Align::CENTER;
135  demo_btn.set_text("Pre-alpha demo");
136  demo_btn.set_on_click([this](UI::Widget&) {
137  this->gs.ui_ctx.clear();
139  this->gs.host_mode = true;
140  this->gs.editor = false;
141  this->gs.singleplayer = true;
142 
143  for(auto& nation : this->gs.world->nations)
144  if(nation.ref_name.get_string() == "netherlands")
145  this->gs.curr_nation = &nation;
146 
147  if(this->gs.curr_nation == nullptr)
148  return;
149 
150  this->gs.ui_ctx.clear();
151  this->gs.in_game = true;
152  this->gs.play_nation();
153  });
154 
155  auto& single_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
156  single_btn.border = button_border;
157  single_btn.current_texture = button_image;
158  single_btn.font = menu_font;
159  single_btn.text_color = menu_text_color;
160  single_btn.text_align_x = single_btn.text_align_y = UI::Align::CENTER;
161  single_btn.set_text("Singleplayer");
162  single_btn.set_on_click([this](UI::Widget&) {
163  this->gs.ui_ctx.clear();
166  gs.host_mode = true;
167  gs.editor = false;
168  this->gs.singleplayer = true;
169  });
170 
171  auto& mp_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
172  mp_btn.border = button_border;
173  mp_btn.current_texture = button_image;
174  mp_btn.font = menu_font;
175  mp_btn.text_color = menu_text_color;
176  mp_btn.text_align_x = mp_btn.text_align_y = UI::Align::CENTER;
177  mp_btn.set_text("Multiplayer");
178  mp_btn.set_on_click([this](UI::Widget&) {
179  this->gs.singleplayer = false;
181  });
182 
183  auto& host_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
184  host_btn.border = button_border;
185  host_btn.current_texture = button_image;
186  host_btn.font = menu_font;
187  host_btn.text_color = menu_text_color;
188  host_btn.text_align_x = host_btn.text_align_y = UI::Align::CENTER;
189  host_btn.set_text("Host");
190  host_btn.set_on_click([this](UI::Widget&) {
191  this->gs.ui_ctx.clear();
193  this->gs.select_nation = new Interface::LobbySelectView(this->gs);
194  this->gs.host_mode = true;
195  this->gs.editor = false;
196  this->gs.singleplayer = false;
197  });
198 
199  auto& edit_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
200  edit_btn.border = button_border;
201  edit_btn.current_texture = button_image;
202  edit_btn.font = menu_font;
203  edit_btn.text_color = menu_text_color;
204  edit_btn.text_align_x = edit_btn.text_align_y = UI::Align::CENTER;
205  edit_btn.set_text("Editor");
206  edit_btn.set_on_click([this](UI::Widget&) {
208  // Create a local server in editor mode
209  this->gs.host_mode = true;
210  this->gs.editor = true;
211  this->gs.singleplayer = true;
212  this->gs.server.reset(new Server(gs, 1836));
213  this->gs.client.reset(new Client(gs, "127.0.0.1", 1836));
214  this->gs.ui_ctx.clear();
215  this->gs.curr_nation = &gs.world->nations[1];
216  this->gs.play_nation();
217  });
218 
219  auto& cfg_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
220  cfg_btn.border = button_border;
221  cfg_btn.current_texture = button_image;
222  cfg_btn.font = menu_font;
223  cfg_btn.text_color = menu_text_color;
224  cfg_btn.text_align_x = cfg_btn.text_align_y = UI::Align::CENTER;
225  cfg_btn.set_text("Settings");
226  cfg_btn.set_on_click([this](UI::Widget&) {
227  this->gs.world->lua.invoke_registered_callback("settings_window_invoke");
228  });
229 
230  auto& exit_btn = button_list.make_widget<UI::Button>(0, 0, b_width, b_height);
231  exit_btn.border = button_border;
232  exit_btn.current_texture = button_image;
233  exit_btn.font = menu_font;
234  exit_btn.text_color = menu_text_color;
235  exit_btn.text_align_x = exit_btn.text_align_y = UI::Align::CENTER;
236  exit_btn.set_text("Exit");
237  exit_btn.set_on_click([this](UI::Widget&) {
238  this->gs.paused = true;
239  this->gs.run = false;
240  });
241 }
242 
244  if(connect_window != nullptr)
245  connect_window->kill();
246 }
std::shared_ptr< Eng3D::IO::Asset::Base > get_unique(const Eng3D::IO::Path &path)
Obtaining an unique asset means the "first-found" policy applies.
Definition: io.cpp:146
virtual const char * what() const noexcept
Definition: network.hpp:74
UI::Context ui_ctx
Definition: state.hpp:128
std::atomic< bool > run
Variable telling if the game should quit, honored by most event loops but should be used explicitly i...
Definition: state.hpp:101
Eng3D::TrueType::Manager ttf_man
Definition: state.hpp:127
Eng3D::TextureManager tex_man
Definition: state.hpp:124
Eng3D::IO::PackageManager package_man
Definition: state.hpp:122
std::shared_ptr< Eng3D::Texture > load(const std::string &path, TextureOptions options=default_options)
Finds a texture in the list of a texture manager if the texture is already in the list we load the sa...
Definition: texture.cpp:432
std::shared_ptr< Eng3D::TrueType::Font > load(std::shared_ptr< Eng3D::IO::Asset::Base > asset)
Definition: ttf.cpp:58
std::unique_ptr< Client > client
Definition: game_state.hpp:143
void play_nation()
Definition: game_state.cpp:65
std::atomic< bool > paused
Definition: game_state.hpp:151
std::unique_ptr< Server > server
Definition: game_state.hpp:144
Nation * curr_nation
Definition: game_state.hpp:158
bool host_mode
Definition: game_state.hpp:185
Interface::LobbySelectView * select_nation
Definition: game_state.hpp:164
bool in_game
Definition: game_state.hpp:183
bool singleplayer
Definition: game_state.hpp:188
MapMode current_mode
Definition: game_state.hpp:162
World * world
Definition: game_state.hpp:156
MainMenuConnectServer(GameState &gs)
Definition: main_menu.cpp:49
GameState & gs
Definition: main_menu.hpp:52
~MainMenu() override
Definition: main_menu.cpp:243
MainMenuConnectServer * connect_window
Definition: main_menu.hpp:53
MainMenu(GameState &gs)
Definition: main_menu.cpp:98
Border class that defines the texture and size of borders of the widgets.
Definition: widget.hpp:153
Button widget.
Definition: button.hpp:32
void prompt(const std::string &title, const std::string &text)
Definition: ui.cpp:183
void clear()
Removes all widgets.
Definition: ui.cpp:121
Input widget for keyboard inputs.
Definition: input.hpp:34
void set_buffer(const std::string &_buffer)
Definition: input.cpp:64
std::string get_buffer() const
Definition: input.cpp:73
The master widget all the other widgets inherit from, do not use directly instead use one of the many...
Definition: widget.hpp:176
UI::Border border
Definition: widget.hpp:334
virtual void set_on_click(std::function< void(UI::Widget &)> _on_click)
Sets the on_click function of this widget.
Definition: widget.hpp:259
UI::Origin origin
Definition: widget.hpp:318
virtual void set_tooltip(UI::Tooltip *tooltip)
Set the tooltip to be shown when this widget is hovered, overrides the previous tooltip.
Definition: widget.cpp:458
bool is_scroll
Definition: widget.hpp:306
std::shared_ptr< Eng3D::Texture > current_texture
Definition: widget.hpp:327
void kill()
Kills the current widget, setting it up for deletion when dead widgets are cleared by the UI context.
Definition: widget.hpp:283
bool is_pinned
Definition: widget.hpp:302
Widget()=default
virtual void set_text(const std::string &text)
Generates text for the widget and overrides the current text texture.
Definition: widget.cpp:445
void set_close_btn_function(std::function< void(Widget &)> on_click)
Definition: window.cpp:65
Eng3D::LuaVM lua
Definition: world.hpp:216
@ COUNTRY_SELECT
@ MIDDLE_LEFT_SCREEN
void debug(const std::string_view category, const std::string_view msg)
Definition: log.cpp:58
std::string translate_format(const std::string_view format, Args &&... args)
String formatter, with translation.
Definition: string.hpp:128
Primitive color type used through the engine.
Definition: color.hpp:32
void invoke_registered_callback(const std::string &name)
Some UI functions are hardcoded, for example the main menu is hardcoded to appear when the game start...
Definition: luavm.cpp:376