working on campaign
This commit is contained in:
1 parent
9fa120d4ad
commit
d38a75ea72
24 files changed
+929
-410
No files matched your search
+61
-61
@@ -2,6 +2,7 @@
|
||||
#include "Game.h"
|
||||
#include "Localization.h"
|
||||
#include "items/ItemRegistry.h"
|
||||
#include "Campaign.h"
|
||||
#include "render/TextRenderer.h"
|
||||
#include "utils/Utils.h"
|
||||
#include <iostream>
|
||||
@@ -323,6 +324,7 @@ namespace FRG {
|
||||
settingsGraphicsScreenRoot = loadLocalizedUi("resources/w/ui/screen_settings_graphics.json", zipFile);
|
||||
languageScreenRoot = loadLocalizedUi("resources/w/ui/screen_language.json", zipFile);
|
||||
loadSavedGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_load.json", zipFile);
|
||||
campaignScreenRoot = loadLocalizedUi("resources/w/ui/screen_campaign.json", zipFile);
|
||||
saveGameScreenRoot = loadLocalizedUi("resources/w/ui/screen_save.json", zipFile);
|
||||
}
|
||||
|
||||
@@ -337,7 +339,7 @@ namespace FRG {
|
||||
texItemSelected_ = renderer.textureManager.LoadFromPng("resources/w/ui/img/journal/ButtonBkg001.png", zipFile, true);
|
||||
texItemTransparent_ = renderer.textureManager.LoadFromPng("resources/w/ui/img/journal/ButtonBkgTransparent001.png", zipFile, true);
|
||||
|
||||
gameState_.questJournal.loadFromFile("resources/config/quests.json", zipFile);
|
||||
// Quest definitions are loaded per campaign by Game (see Game::activateCampaign).
|
||||
|
||||
toastTextureQuestNew = loadLocalizedTexture("resources/w/ui/img/toast/quest_new001.png", zipFile);
|
||||
toastTextureQuestCompleted = loadLocalizedTexture("resources/w/ui/img/toast/quest_completed001.png", zipFile);
|
||||
@@ -376,18 +378,19 @@ namespace FRG {
|
||||
showMainMenu();
|
||||
}
|
||||
|
||||
void MenuManager::startNewGame(const std::string& campaignId) {
|
||||
// The reset runs on a later main-thread task, which then shows the HUD itself;
|
||||
// the main menu stays up until then. Showing the HUD now would draw one frame
|
||||
// from the previous game's state (e.g. its phone/journal buttons).
|
||||
if (startGameFunc) startGameFunc(campaignId);
|
||||
}
|
||||
|
||||
void MenuManager::enterGameplay(bool isFromLoad) {
|
||||
if (isFromLoad) {
|
||||
uiManager.clearMenuStack();
|
||||
topUiManager.clearMenuStack();
|
||||
}
|
||||
// A new game resets the state on a later main-thread task, which then shows the
|
||||
// HUD itself; the main menu stays up until then. Showing the HUD now would draw
|
||||
// one frame from the previous game's state (e.g. its phone/journal buttons).
|
||||
if (!isFromLoad && uiState_ == GameUiState::MainMenu && startGameFunc)
|
||||
startGameFunc();
|
||||
else
|
||||
showGameplayHud();
|
||||
showGameplayHud();
|
||||
}
|
||||
|
||||
std::shared_ptr<UiNode> MenuManager::gameplayHudRoot() const {
|
||||
@@ -472,8 +475,7 @@ namespace FRG {
|
||||
|
||||
uiManager.setTextButtonCallback("menuStartButton", [this](const std::string&) {
|
||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||
enterGameplay();
|
||||
|
||||
showCampaignScreen();
|
||||
});
|
||||
uiManager.setTextButtonCallback("menuAboutButton", [this](const std::string&) {
|
||||
showAboutScreen();
|
||||
@@ -534,8 +536,7 @@ namespace FRG {
|
||||
|
||||
uiManager.setTextButtonCallback("menuStartButton", [this](const std::string&) {
|
||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||
enterGameplay();
|
||||
|
||||
showCampaignScreen();
|
||||
});
|
||||
uiManager.setTextButtonCallback("menuAboutButton", [this](const std::string&) {
|
||||
showAboutScreen();
|
||||
@@ -1034,7 +1035,8 @@ namespace FRG {
|
||||
|
||||
steps.push_back([this]() {
|
||||
ItemRegistry::instance().loadFromJson("resources/config/items.json", CONST_ZIP_FILE);
|
||||
gameState_.questJournal.reloadDefinitionsPreservingState("resources/config/quests.json", CONST_ZIP_FILE);
|
||||
if (const CampaignConfig* campaign = CampaignRegistry::instance().find(gameState_.campaignId))
|
||||
gameState_.questJournal.reloadDefinitionsPreservingState(campaign->questsPath, CONST_ZIP_FILE);
|
||||
});
|
||||
|
||||
steps.push_back([this]() {
|
||||
@@ -1074,22 +1076,7 @@ namespace FRG {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int slot = i + 1;
|
||||
if (getSlotInfoFunc) {
|
||||
SaveSlotInfo info = getSlotInfoFunc(slot);
|
||||
|
||||
std::string emptyText;
|
||||
if (FRG::g_currentLanguage == FRG::Language::Russian)
|
||||
{
|
||||
emptyText = EMPTY_LANGUAGE_RU;
|
||||
}
|
||||
else if (FRG::g_currentLanguage == FRG::Language::English)
|
||||
{
|
||||
emptyText = EMPTY_LANGUAGE_EN;
|
||||
}
|
||||
|
||||
std::string label = info.empty
|
||||
? emptyText
|
||||
: localizedLocationName[info.locationName][FRG::g_currentLanguage] + " " + info.savedAt;
|
||||
uiManager.setTextButtonText(kSlotButtons[i], label);
|
||||
uiManager.setTextButtonText(kSlotButtons[i], slotLabel(getSlotInfoFunc(slot)));
|
||||
}
|
||||
uiManager.setTextButtonCallback(kSlotButtons[i], [this, slot](const std::string&) {
|
||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||
@@ -1099,6 +1086,47 @@ namespace FRG {
|
||||
}
|
||||
}
|
||||
|
||||
std::string MenuManager::slotLabel(const SaveSlotInfo& info) {
|
||||
if (info.empty)
|
||||
return FRG::g_currentLanguage == FRG::Language::English ? EMPTY_LANGUAGE_EN : EMPTY_LANGUAGE_RU;
|
||||
|
||||
std::string label = localizedLocationName[info.locationName][FRG::g_currentLanguage] + " " + info.savedAt;
|
||||
// Name the campaign unless it's the main game, so saves of different campaigns are told apart.
|
||||
const CampaignConfig* campaign = CampaignRegistry::instance().find(info.campaignId);
|
||||
if (campaign && campaign->id != CampaignRegistry::kDefaultCampaignId)
|
||||
label = campaign->title(FRG::g_currentLanguage) + ": " + label;
|
||||
return label;
|
||||
}
|
||||
|
||||
void MenuManager::showCampaignScreen()
|
||||
{
|
||||
uiManager.pushMenuFromSavedRoot(campaignScreenRoot);
|
||||
uiManager.setTextButtonCallback("campaignBackButton", [this](const std::string&) {
|
||||
uiManager.popMenu();
|
||||
uiManager.updateAllLayouts();
|
||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||
});
|
||||
|
||||
// One button per campaign in campaigns.json order; spare buttons are hidden.
|
||||
static const char* kCampaignButtons[4] = {
|
||||
"campaignSlot1Button", "campaignSlot2Button", "campaignSlot3Button", "campaignSlot4Button"
|
||||
};
|
||||
const auto& campaigns = CampaignRegistry::instance().all();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
const bool used = i < static_cast<int>(campaigns.size());
|
||||
uiManager.setNodeVisible(kCampaignButtons[i], used);
|
||||
if (!used) continue;
|
||||
|
||||
const std::string campaignId = campaigns[i].id;
|
||||
uiManager.setTextButtonText(kCampaignButtons[i], campaigns[i].title(FRG::g_currentLanguage));
|
||||
uiManager.setTextButtonCallback(kCampaignButtons[i], [this, campaignId](const std::string&) {
|
||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||
uiManager.popMenu();
|
||||
startNewGame(campaignId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MenuManager::showSaveGameScreen()
|
||||
{
|
||||
uiManager.pushMenuFromSavedRoot(saveGameScreenRoot);
|
||||
@@ -1115,42 +1143,12 @@ namespace FRG {
|
||||
int slot = i + 1;
|
||||
const char* buttonName = kSlotButtons[i];
|
||||
if (getSlotInfoFunc) {
|
||||
SaveSlotInfo info = getSlotInfoFunc(slot);
|
||||
|
||||
std::string emptyText;
|
||||
if (FRG::g_currentLanguage == FRG::Language::Russian)
|
||||
{
|
||||
emptyText = EMPTY_LANGUAGE_RU;
|
||||
}
|
||||
else if (FRG::g_currentLanguage == FRG::Language::English)
|
||||
{
|
||||
emptyText = EMPTY_LANGUAGE_EN;
|
||||
}
|
||||
|
||||
std::string label = info.empty
|
||||
? emptyText
|
||||
: localizedLocationName[info.locationName][FRG::g_currentLanguage] + " " + info.savedAt;
|
||||
uiManager.setTextButtonText(buttonName, label);
|
||||
uiManager.setTextButtonText(buttonName, slotLabel(getSlotInfoFunc(slot)));
|
||||
}
|
||||
uiManager.setTextButtonCallback(buttonName, [this, slot, buttonName](const std::string&) {
|
||||
if (onSaveGame) onSaveGame(slot);
|
||||
if (getSlotInfoFunc) {
|
||||
SaveSlotInfo info = getSlotInfoFunc(slot);
|
||||
|
||||
std::string emptyText;
|
||||
if (FRG::g_currentLanguage == FRG::Language::Russian)
|
||||
{
|
||||
emptyText = EMPTY_LANGUAGE_RU;
|
||||
}
|
||||
else if (FRG::g_currentLanguage == FRG::Language::English)
|
||||
{
|
||||
emptyText = EMPTY_LANGUAGE_EN;
|
||||
}
|
||||
|
||||
std::string label = info.empty
|
||||
? emptyText
|
||||
: localizedLocationName[info.locationName][FRG::g_currentLanguage] + " " + info.savedAt;
|
||||
uiManager.setTextButtonText(buttonName, label);
|
||||
uiManager.setTextButtonText(buttonName, slotLabel(getSlotInfoFunc(slot)));
|
||||
audioPlayer_.playSoundAsync("resources/audio/751089__smallconfusion__mechanical-plastic-click-11.ogg");
|
||||
}
|
||||
});
|
||||
@@ -2142,6 +2140,8 @@ namespace FRG {
|
||||
|
||||
void MenuManager::onEnemyKilledInUniInterior()
|
||||
{
|
||||
// Every location's enemies report here; only the university interior drives the tutorial.
|
||||
if (gameState_.currentLocationName != "uni_interior") return;
|
||||
// The last tutorial step; like the attack hint, also ends the earlier darklands hints.
|
||||
if (gameState_.tutorialStep >= TutorialStep::DarklandsHealth)
|
||||
gameState_.tutorialStep = TutorialStep::Completed;
|
||||
|
||||
Reference in new issue
Block a user