feat: Add bare in-game options and save/load menus

This commit is contained in:
Vsevolod Kremianskii 2020-11-07 12:43:30 +07:00
parent 07d13abbeb
commit 304520473b
12 changed files with 343 additions and 100 deletions

View file

@ -362,9 +362,11 @@ set(GAME_HEADERS
src/game/gui/ingame/journal.h
src/game/gui/ingame/map.h
src/game/gui/ingame/messages.h
src/game/gui/ingame/options.h
src/game/gui/loadscreen.h
src/game/gui/mainmenu.h
src/game/gui/partyselect.h
src/game/gui/saveload.h
src/game/gui/selectoverlay.h
src/game/object/area.h
src/game/object/creature.h
@ -436,9 +438,11 @@ set(GAME_SOURCES
src/game/gui/ingame/journal.cpp
src/game/gui/ingame/map.cpp
src/game/gui/ingame/messages.cpp
src/game/gui/ingame/options.cpp
src/game/gui/loadscreen.cpp
src/game/gui/mainmenu.cpp
src/game/gui/partyselect.cpp
src/game/gui/saveload.cpp
src/game/gui/selectoverlay.cpp
src/game/object/area.cpp
src/game/object/creature.cpp

Binary file not shown.

View file

@ -129,6 +129,9 @@ void Game::openMainMenu() {
if (!_mainMenu) {
loadMainMenu();
}
if (!_saveLoad) {
loadSaveLoad();
}
playMusic(getMainMenuMusic());
_screen = GameScreen::MainMenu;
}
@ -322,6 +325,11 @@ void Game::loadPartySelection() {
_partySelect->load();
}
void Game::loadSaveLoad() {
_saveLoad.reset(new SaveLoad(this));
_saveLoad->load();
}
void Game::loadInGame() {
_inGame.reset(new InGameMenu(this));
_inGame->load();
@ -345,6 +353,8 @@ GUI *Game::getScreenGUI() const {
return _container.get();
case GameScreen::PartySelection:
return _partySelect.get();
case GameScreen::SaveLoad:
return _saveLoad.get();
default:
return nullptr;
}
@ -482,6 +492,9 @@ void Game::openInGameMenu(InGameMenu::Tab tab) {
case InGameMenu::Tab::Map:
_inGame->openMap();
break;
case InGameMenu::Tab::Options:
_inGame->openOptions();
break;
default:
break;
}
@ -506,6 +519,12 @@ void Game::openPartySelection(const PartySelection::Context &ctx) {
_screen = GameScreen::PartySelection;
}
void Game::openSaveLoad(SaveLoad::Mode mode) {
setCursorType(CursorType::Default);
_saveLoad->setMode(mode);
_screen = GameScreen::SaveLoad;
}
void Game::scheduleModuleTransition(const string &moduleName, const string &entry) {
_nextModule = moduleName;
_nextEntry = entry;

View file

@ -40,6 +40,7 @@
#include "gui/loadscreen.h"
#include "gui/mainmenu.h"
#include "gui/partyselect.h"
#include "gui/saveload.h"
#include "object/module.h"
#include "object/objectfactory.h"
#include "object/spatial.h"
@ -74,11 +75,12 @@ public:
void loadModule(const std::string &name, const std::string &entry = "");
void onCameraChanged(CameraType camera);
void openContainer(SpatialObject *container);
void openInGame();
void openInGameMenu(InGameMenu::Tab tab);
void openMainMenu();
void openSaveLoad(SaveLoad::Mode mode);
void openPartySelection(const PartySelection::Context &ctx);
void openMainMenu();
void openInGameMenu(InGameMenu::Tab tab);
void openInGame();
void openContainer(SpatialObject *container);
void scheduleModuleTransition(const std::string &moduleName, const std::string &entry);
void startCharacterGeneration();
void startDialog(SpatialObject &owner, const std::string &resRef);
@ -133,7 +135,8 @@ private:
InGameMenu,
Dialog,
Container,
PartySelection
PartySelection,
SaveLoad
};
struct UserDefinedEvent {
@ -175,6 +178,7 @@ private:
std::unique_ptr<Dialog> _dialog;
std::unique_ptr<Container> _container;
std::unique_ptr<PartySelection> _partySelect;
std::unique_ptr<SaveLoad> _saveLoad;
// END GUI
@ -225,6 +229,7 @@ private:
void loadLoadingScreen();
void loadMainMenu();
void loadPartySelection();
void loadSaveLoad();
// END Loading

View file

@ -193,6 +193,8 @@ void HUD::onClick(const string &control) {
_game->openInGameMenu(InGameMenu::Tab::Journal);
} else if (control == "BTN_MAP") {
_game->openInGameMenu(InGameMenu::Tab::Map);
} else if (control == "BTN_OPT") {
_game->openInGameMenu(InGameMenu::Tab::Options);
}
}

View file

@ -17,6 +17,8 @@
#include "ingame.h"
#include <unordered_map>
#include "../../game.h"
using namespace std;
@ -29,6 +31,17 @@ namespace reone {
namespace game {
static unordered_map<InGameMenu::Tab, string> g_tabTags {
{ InGameMenu::Tab::Equipment, "LBLH_EQU" },
{ InGameMenu::Tab::Inventory, "LBLH_INV" },
{ InGameMenu::Tab::Character, "LBLH_CHA" },
{ InGameMenu::Tab::Abilities, "LBLH_ABI" },
{ InGameMenu::Tab::Messages, "LBLH_MSG" },
{ InGameMenu::Tab::Journal, "LBLH_JOU" },
{ InGameMenu::Tab::Map, "LBLH_MAP" },
{ InGameMenu::Tab::Options, "LBLH_OPT" }
};
InGameMenu::InGameMenu(Game *game) :
GUI(game->version(), game->options().graphics),
_game(game) {
@ -48,64 +61,65 @@ void InGameMenu::load() {
hideControl("BTN_MAP");
hideControl("BTN_OPT");
setControlFocusable("LBLH_EQU", false);
setControlFocusable("LBLH_INV", false);
setControlFocusable("LBLH_CHA", false);
setControlFocusable("LBLH_ABI", false);
setControlFocusable("LBLH_MSG", false);
setControlFocusable("LBLH_JOU", false);
setControlFocusable("LBLH_MAP", false);
setControlFocusable("LBLH_OPT", false);
loadEquipment();
loadInventory();
loadCharacter();
loadAbilities();
loadMessages();
loadJournal();
loadMap();
loadOptions();
loadEquipmentMenu();
loadInventoryMenu();
loadCharacterMenu();
loadAbilitiesMenu();
loadMessagesMenu();
loadJournalMenu();
loadMapMenu();
for (auto &tag : g_tabTags) {
setControlFocusable(tag.second, false);
}
}
void InGameMenu::loadEquipmentMenu() {
void InGameMenu::loadEquipment() {
_equip = make_unique<Equipment>(_game);
_equip->load();
}
void InGameMenu::loadInventoryMenu() {
void InGameMenu::loadInventory() {
_inventory = make_unique<InventoryMenu>(_game);
_inventory->load();
}
void InGameMenu::loadCharacterMenu() {
void InGameMenu::loadCharacter() {
_character = make_unique<CharacterMenu>(_game);
_character->load();
}
void InGameMenu::loadAbilitiesMenu() {
void InGameMenu::loadAbilities() {
_abilities = make_unique<AbilitiesMenu>(_game);
_abilities->load();
}
void InGameMenu::loadMessagesMenu() {
void InGameMenu::loadMessages() {
_messages = make_unique<MessagesMenu>(_game);
_messages->load();
}
void InGameMenu::loadJournalMenu() {
void InGameMenu::loadJournal() {
_journal = make_unique<JournalMenu>(_game);
_journal->load();
}
void InGameMenu::loadMapMenu() {
void InGameMenu::loadMap() {
_map = make_unique<MapMenu>(_game);
_map->load();
}
void InGameMenu::loadOptions() {
_options = make_unique<OptionsMenu>(_game);
_options->load();
}
bool InGameMenu::handle(const SDL_Event &event) {
GUI *tabGui = getActiveTabGUI();
if (tabGui && tabGui->handle(event)) return true;
if (_tab != Tab::Map && GUI::handle(event)) return true;
if (GUI::handle(event)) return true;
return false;
}
@ -126,6 +140,8 @@ GUI *InGameMenu::getActiveTabGUI() const {
return _journal.get();
case Tab::Map:
return _map.get();
case Tab::Options:
return _options.get();
default:
return nullptr;
}
@ -149,98 +165,53 @@ void InGameMenu::render() const {
}
void InGameMenu::openEquipment() {
setControlFocus("LBLH_EQU", true);
setControlFocus("LBLH_INV", false);
setControlFocus("LBLH_CHA", false);
setControlFocus("LBLH_ABI", false);
setControlFocus("LBLH_MSG", false);
setControlFocus("LBLH_JOU", false);
setControlFocus("LBLH_MAP", false);
setControlFocus("LBLH_OPT", false);
_equip->update();
_tab = Tab::Equipment;
updateTabButtons();
}
void InGameMenu::updateTabButtons() {
for (auto &tag : g_tabTags) {
setControlFocus(tag.second, tag.first == _tab);
}
}
void InGameMenu::openInventory() {
setControlFocus("LBLH_EQU", false);
setControlFocus("LBLH_INV", true);
setControlFocus("LBLH_CHA", false);
setControlFocus("LBLH_ABI", false);
setControlFocus("LBLH_MSG", false);
setControlFocus("LBLH_JOU", false);
setControlFocus("LBLH_MAP", false);
setControlFocus("LBLH_OPT", false);
_inventory->updatePortraits();
_tab = Tab::Inventory;
updateTabButtons();
}
void InGameMenu::openCharacter() {
setControlFocus("LBLH_EQU", false);
setControlFocus("LBLH_INV", false);
setControlFocus("LBLH_CHA", true);
setControlFocus("LBLH_ABI", false);
setControlFocus("LBLH_MSG", false);
setControlFocus("LBLH_JOU", false);
setControlFocus("LBLH_MAP", false);
setControlFocus("LBLH_OPT", false);
_character->updatePortraits();
_tab = Tab::Character;
updateTabButtons();
}
void InGameMenu::openAbilities() {
setControlFocus("LBLH_EQU", false);
setControlFocus("LBLH_INV", false);
setControlFocus("LBLH_CHA", false);
setControlFocus("LBLH_ABI", true);
setControlFocus("LBLH_MSG", false);
setControlFocus("LBLH_JOU", false);
setControlFocus("LBLH_MAP", false);
setControlFocus("LBLH_OPT", false);
_abilities->updatePortraits();
_tab = Tab::Abilities;
updateTabButtons();
}
void InGameMenu::openMessages() {
setControlFocus("LBLH_EQU", false);
setControlFocus("LBLH_INV", false);
setControlFocus("LBLH_CHA", false);
setControlFocus("LBLH_ABI", false);
setControlFocus("LBLH_MSG", true);
setControlFocus("LBLH_JOU", false);
setControlFocus("LBLH_MAP", false);
setControlFocus("LBLH_OPT", false);
_tab = Tab::Messages;
updateTabButtons();
}
void InGameMenu::openJournal() {
setControlFocus("LBLH_EQU", false);
setControlFocus("LBLH_INV", false);
setControlFocus("LBLH_CHA", false);
setControlFocus("LBLH_ABI", false);
setControlFocus("LBLH_MSG", false);
setControlFocus("LBLH_JOU", true);
setControlFocus("LBLH_MAP", false);
setControlFocus("LBLH_OPT", false);
_tab = Tab::Journal;
updateTabButtons();
}
void InGameMenu::openMap() {
setControlFocus("LBLH_EQU", false);
setControlFocus("LBLH_INV", false);
setControlFocus("LBLH_CHA", false);
setControlFocus("LBLH_ABI", false);
setControlFocus("LBLH_MSG", false);
setControlFocus("LBLH_JOU", false);
setControlFocus("LBLH_MAP", true);
setControlFocus("LBLH_OPT", false);
_tab = Tab::Map;
updateTabButtons();
}
void InGameMenu::openOptions() {
_tab = Tab::Options;
updateTabButtons();
}
void InGameMenu::onClick(const string &control) {
@ -258,6 +229,8 @@ void InGameMenu::onClick(const string &control) {
openJournal();
} else if (control == "LBLH_MAP") {
openMap();
} else if (control == "LBLH_OPT") {
openOptions();
}
}

View file

@ -26,6 +26,7 @@
#include "journal.h"
#include "map.h"
#include "messages.h"
#include "options.h"
namespace reone {
@ -43,7 +44,8 @@ public:
Abilities,
Messages,
Journal,
Map
Map,
Options
};
InGameMenu(Game *game);
@ -60,6 +62,7 @@ public:
void openMessages();
void openJournal();
void openMap();
void openOptions();
private:
Game *_game { nullptr };
@ -72,16 +75,20 @@ private:
std::unique_ptr<MessagesMenu> _messages;
std::unique_ptr<JournalMenu> _journal;
std::unique_ptr<MapMenu> _map;
std::unique_ptr<OptionsMenu> _options;
void onClick(const std::string &control) override;
void loadCharacterMenu();
void loadEquipmentMenu();
void loadInventoryMenu();
void loadAbilitiesMenu();
void loadMessagesMenu();
void loadJournalMenu();
void loadMapMenu();
void loadCharacter();
void loadEquipment();
void loadInventory();
void loadAbilities();
void loadMessages();
void loadJournal();
void loadMap();
void loadOptions();
void updateTabButtons();
GUI *getActiveTabGUI() const;
};

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2020 Vsevolod Kremianskii
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "options.h"
#include "../../game.h"
#include "../colors.h"
using namespace std;
using namespace reone::gui;
using namespace reone::resource;
namespace reone {
namespace game {
OptionsMenu::OptionsMenu(Game *game) :
GUI(game->version(), game->options().graphics),
_game(game) {
_resRef = getResRef("optionsingame");
_backgroundType = BackgroundType::Menu;
_hasDefaultHilightColor = true;
_defaultHilightColor = getHilightColor(_version);
if (game->version() == GameVersion::TheSithLords) {
_resolutionX = 800;
_resolutionY = 600;
}
}
void OptionsMenu::load() {
GUI::load();
}
void OptionsMenu::onClick(const string &control) {
if (control == "BTN_LOADGAME") {
_game->openSaveLoad(SaveLoad::Mode::LoadFromInGame);
} else if (control == "BTN_SAVEGAME") {
_game->openSaveLoad(SaveLoad::Mode::Save);
} else if (control == "BTN_EXIT") {
_game->openInGame();
}
}
} // namespace game
} // namespace reone

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2020 Vsevolod Kremianskii
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../../../gui/gui.h"
namespace reone {
namespace game {
class Game;
class OptionsMenu : public gui::GUI {
public:
OptionsMenu(Game *game);
void load() override;
private:
Game *_game { nullptr };
void onClick(const std::string &control) override;
};
} // namespace game
} // namespace reone

View file

@ -85,7 +85,6 @@ void MainMenu::load() {
hideControl("LBL_BW");
hideControl("LBL_LUCAS");
setControlDisabled("BTN_LOADGAME", true);
setControlDisabled("BTN_MOVIES", true);
setControlDisabled("BTN_OPTIONS", true);
@ -152,6 +151,8 @@ shared_ptr<ModelSceneNode> MainMenu::getKotorModel(SceneGraph &sceneGraph) {
void MainMenu::onClick(const string &control) {
if (control == "BTN_NEWGAME") {
_game->startCharacterGeneration();
} else if (control == "BTN_LOADGAME") {
_game->openSaveLoad(SaveLoad::Mode::LoadFromMainMenu);
} else if (control == "BTN_EXIT") {
_game->quit();
} else if (control == "BTN_WARP") {

75
src/game/gui/saveload.cpp Normal file
View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2020 Vsevolod Kremianskii
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "saveload.h"
#include "../game.h"
#include "colors.h"
using namespace std;
using namespace reone::gui;
using namespace reone::resource;
namespace reone {
namespace game {
SaveLoad::SaveLoad(Game *game) :
GUI(game->version(), game->options().graphics),
_game(game) {
_resRef = getResRef("saveload");
_backgroundType = BackgroundType::Menu;
_hasDefaultHilightColor = true;
_defaultHilightColor = getHilightColor(_version);
if (game->version() == GameVersion::TheSithLords) {
_resolutionX = 800;
_resolutionY = 600;
}
}
void SaveLoad::load() {
GUI::load();
disableControl("BTN_DELETE");
disableControl("BTN_SAVELOAD");
}
void SaveLoad::setMode(Mode mode) {
_mode = mode;
}
void SaveLoad::onClick(const string &control) {
if (control == "BTN_BACK") {
switch (_mode) {
case Mode::Save:
case Mode::LoadFromInGame:
_game->openInGame();
break;
default:
_game->openMainMenu();
break;
}
}
}
} // namespace game
} // namespace reone

51
src/game/gui/saveload.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2020 Vsevolod Kremianskii
*
* 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 <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "../../gui/gui.h"
namespace reone {
namespace game {
class Game;
class SaveLoad : public gui::GUI {
public:
enum class Mode {
Save,
LoadFromMainMenu,
LoadFromInGame
};
SaveLoad(Game *game);
void load() override;
void setMode(Mode mode);
private:
Game *_game { nullptr };
Mode _mode { Mode::Save };
void onClick(const std::string &control) override;
};
} // namespace game
} // namespace reone