123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- // SuperTux
- // Copyright (C) 2021 A. Semphris <semphris@protonmail.com>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- #include "supertux/menu/multiplayer_player_menu.hpp"
- #include <fmt/format.h>
- #include <SDL.h>
- #include "control/game_controller_manager.hpp"
- #include "control/input_manager.hpp"
- #include "control/joystick_manager.hpp"
- #include "gui/dialog.hpp"
- #include "supertux/gameconfig.hpp"
- #include "supertux/game_session.hpp"
- #include "supertux/globals.hpp"
- #include "supertux/savegame.hpp"
- #include "supertux/sector.hpp"
- #include "object/player.hpp"
- #include "util/gettext.hpp"
- #include "util/log.hpp"
- MultiplayerPlayerMenu::MultiplayerPlayerMenu(int player_id)
- {
- add_label(fmt::format(_("Player {}"), player_id + 1));
- add_hl();
- add_toggle(-1, _("Play with the keyboard"), &InputManager::current()->m_uses_keyboard[player_id]);
- if (player_id != 0 && GameSession::current()
- && !GameSession::current()->get_savegame().is_title_screen())
- {
- bool player_is_in_sector = false;
- for (const auto* player : GameSession::current()->get_current_sector().get_players())
- {
- if (player->get_id() == player_id)
- {
- player_is_in_sector = true;
- break;
- }
- }
- if (player_is_in_sector)
- {
- add_entry(_("Remove Player"), [player_id] {
- // Re-check everything that concerns the sector, it might have changed
- // (e. g. when unplugging a controller with auto-management enabled)
- if (!GameSession::current() || GameSession::current()->get_savegame().is_title_screen())
- {
- log_warning << "Attempt to force player to despawn while not in session"
- << std::endl;
- return;
- }
- for (auto* player : GameSession::current()->get_current_sector().get_players())
- {
- if (player->get_id() == player_id)
- {
- player->remove_me();
- return;
- }
- }
- log_warning << "Could not find player with ID " << player_id
- << " (number " << (player_id + 1) << "in sector"
- << std::endl;
- });
- add_entry(_("Respawn Player"), [player_id] {
- // Re-check everything that concerns the sector, it might have changed
- // (e. g. when unplugging a controller with auto-management enabled)
- if (!GameSession::current() || GameSession::current()->get_savegame().is_title_screen())
- {
- log_warning << "Attempt to force player to respawn while not in session"
- << std::endl;
- return;
- }
- for (auto* player : GameSession::current()->get_current_sector().get_players())
- {
- if (player->get_id() == player_id)
- {
- player->multiplayer_prepare_spawn();
- return;
- }
- }
- log_warning << "Could not find player with ID " << player_id
- << " (number " << (player_id + 1) << "in sector"
- << std::endl;
- });
- }
- else
- {
- add_entry(_("Spawn Player"), [player_id] {
- // Re-check everything that concerns the sector, it might have changed
- // (e. g. when unplugging a controller with auto-management enabled)
- if (!GameSession::current() || GameSession::current()->get_savegame().is_title_screen())
- {
- log_warning << "Attempt to force player to spawn while not in session"
- << std::endl;
- return;
- }
- auto& sector = GameSession::current()->get_current_sector();
- auto& player_status = GameSession::current()->get_savegame().get_player_status();
- // TODO: This is probably needed because adding/removing users manually
- // or automatically by plugging in controllers might not always fix the
- // player_status object; check if that statement is correct
- if (player_status.m_num_players <= player_id)
- player_status.add_player();
- // ID = 0 is impossible, so no need to write `(id == 0) ? "" : ...`
- auto& player = sector.add<Player>(player_status, "Tux" + std::to_string(player_id + 1), player_id);
- player.multiplayer_prepare_spawn();
- });
- }
- }
- add_hl();
- add_label(_("Controllers"));
- if (InputManager::current()->m_use_game_controller)
- {
- for (auto& pair : InputManager::current()->game_controller_manager->get_controller_mapping())
- {
- auto controller = pair.first;
- std::string prefix = (pair.second == -1) ? "" : (pair.second == player_id) ? "-> " : ("[" + std::to_string(pair.second + 1) + "] ");
- add_entry(prefix + std::string(SDL_GameControllerName(pair.first)), [controller, player_id] {
- InputManager::current()->game_controller_manager->bind_controller(controller, player_id);
- auto err = InputManager::current()->game_controller_manager->rumble(controller);
- switch (err)
- {
- case 1:
- Dialog::show_message(_("This controller does not support rumbling;"
- "\nplease check the controllers manually."));
- break;
- case 2:
- Dialog::show_message(_("This SuperTux build does not support "
- "rumbling\ncontrollers; please check the "
- "controllers manually."));
- break;
- default:
- break;
- }
- MenuManager::instance().set_menu(std::make_unique<MultiplayerPlayerMenu>(player_id));
- });
- }
- }
- else
- {
- for (auto& pair : InputManager::current()->joystick_manager->get_joystick_mapping())
- {
- auto joystick = pair.first;
- std::string prefix = (pair.second == -1) ? "" : (pair.second == player_id) ? "-> " : ("[" + std::to_string(pair.second + 1) + "] ");
- add_entry(prefix + std::string(SDL_JoystickName(pair.first)), [joystick, player_id] {
- InputManager::current()->joystick_manager->bind_joystick(joystick, player_id);
- auto err = InputManager::current()->joystick_manager->rumble(joystick);
- switch (err)
- {
- case 1:
- Dialog::show_message(_("This joystick does not support rumbling;"
- "\nplease check the joysticks manually."));
- break;
- case 2:
- Dialog::show_message(_("This SuperTux build does not support "
- "rumbling\njoysticks; please check the "
- "joysticks manually."));
- break;
- default:
- break;
- }
- MenuManager::instance().set_menu(std::make_unique<MultiplayerPlayerMenu>(player_id));
- });
- }
- }
- add_hl();
- add_back(_("Back"));
- }
- /* EOF */
|