Added music

This commit is contained in:
Vladislav Khorev 2026-06-21 21:27:27 +03:00
parent 7db9ca8f70
commit 84f9fa37a8
13 changed files with 118 additions and 8 deletions

BIN
audio/bishkek fight calm.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/bishkek fight.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/bishkek univer day.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/main menu final.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
audio/obshaga.ogg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -99,9 +99,20 @@ void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, in
}
void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
std::cout << "AudioPlayerAsync::playMusicAsync called step 1" << std::endl;
if (!initialized) return;
std::cout << "AudioPlayerAsync::playMusicAsync called step 1" << std::endl;
if (filePath == currentTrack)
{
return;
}
currentTrack = filePath;
auto task = [filePath, loops]() {
std::cout << "AudioPlayerAsync::playMusicAsync called step 3" << std::endl;
Mix_Music* music = Mix_LoadMUS(filePath.c_str());
if (!music) {
std::cerr << "Failed to load music " << filePath << ": " << Mix_GetError() << std::endl;
@ -124,6 +135,9 @@ void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
void AudioPlayerAsync::stopMusicAsync() {
if (!initialized) return;
currentTrack = "";
#ifdef __EMSCRIPTEN__
Mix_HaltMusic();
#else

View File

@ -46,5 +46,7 @@ private:
std::unordered_map<std::string, Mix_Chunk*> soundCache;
std::mutex soundCacheMutex;
std::string currentTrack;
bool initialized = false;
};

View File

@ -74,8 +74,8 @@ namespace ZL
Game::Game()
: newTickCount(0)
, lastTickCount(0)
, menuManager(renderer, gameState)
, audioPlayer(std::make_unique<AudioPlayerAsync>())
, menuManager(renderer, gameState, *audioPlayer)
{
}
@ -327,14 +327,13 @@ namespace ZL
menuManager.startGameFunc = [this]() {
gameState.currentLocationName = "location_dorm";
currentLocation()->scriptEngine.callLocationEnterCallback();
this->audioPlayer->playMusicAsync("audio/obshaga.ogg");
};
menuManager.onSaveGame = [this](int slot) { saveGame(slot); };
menuManager.onLoadGame = [this](int slot) { loadGame(slot); };
menuManager.getSlotInfoFunc = [this](int slot) { return readSlotInfo(slot); };
loadingCompleted = true;
if (audioPlayer->init()) {
audioPlayer->setMusicVolume(100);
audioPlayer->setSoundVolume(80);
@ -344,6 +343,11 @@ namespace ZL
std::cout << "Audio initialization failed" << std::endl;
}
audioPlayer->playMusicAsync("audio/main menu final.ogg");
loadingCompleted = true;
}
void Game::createLocations()
@ -448,6 +452,12 @@ namespace ZL
}
}
gameState.locations["uni_interior"]->requestDarklandsPlayBattleMusic = [this]() {
audioPlayer->playMusicAsync("audio/bishkek fight.ogg");
};
gameState.locations["uni_interior"]->requestDarklandsPlayNormalMusic = [this]() {
audioPlayer->playMusicAsync("audio/bishkek fight calm.ogg");
};
LocationSetup uniExteriorParams = uniInteriorParams;
uniExteriorParams.gameObjectsJsonPath = "resources/config2/gameobjects_uni_exterior_x.json";
uniExteriorParams.interactiveObjectsJsonPath = "resources/config2/interactive_objects_uni_exterior_x.json";

View File

@ -57,6 +57,8 @@ namespace ZL {
bool startDarklandsTransition();
bool startNightTransition();
std::unique_ptr<AudioPlayerAsync> audioPlayer;
MenuManager menuManager;
void activateSlowMoEffect();
@ -91,8 +93,7 @@ namespace ZL {
float dragStartAzimuth = 0.0f;
float dragStartInclination = 0.0f;
std::unique_ptr<AudioPlayerAsync> audioPlayer;
Location* currentLocation() const;
void saveGame(int slot);

View File

@ -1516,9 +1516,32 @@ namespace ZL
dialogueSystem.update(static_cast<int>(delta));
updateTriggerZones(player->state.position);
}
bool npcAttacking = false;
for (auto& npc : npcs)
{
npc->update(delta, resolver);
if (npc->state.enabled && npc->state.canAttack && (!npc->state.pathWaypoints.empty() || npc->state.battle_state != 0) && npc->getHp() > 0.f)
{
//std::cout << "[NPC] NPC '" << npc->state.npcId << "' is attacking target index " << npc->state.attackTargetIndex << std::endl;
npcAttacking = true;
}
}
if (state.isDarklands)
{
if (npcAttacking && !playBattleMusic)
{
playBattleMusic = true;
if (requestDarklandsPlayBattleMusic) requestDarklandsPlayBattleMusic();
}
else if (!npcAttacking && playBattleMusic)
{
playBattleMusic = false;
if (requestDarklandsPlayNormalMusic) requestDarklandsPlayNormalMusic();
}
}
resolveCharacterCollisions();

View File

@ -114,6 +114,10 @@ namespace ZL
std::function<void()> requestReturnToMainMenu;
std::function<void(int, bool, const std::string&)> requestSetChatUnread;
std::function<void()> requestDarklandsPlayBattleMusic;
std::function<void()> requestDarklandsPlayNormalMusic;
// Navigation editor — toggle with 'N', save with 'B', right-click to finalize polygon
EditorMode editorMode = EditorMode::None;
LocationEditor editor;
@ -126,6 +130,8 @@ namespace ZL
int lastMouseX = 0;
int lastMouseY = 0;
bool playBattleMusic = false;
void setup(const LocationSetup& params, Quest::QuestJournal* journal);
void setupNavigation(const std::vector<std::string>& paths);

View File

@ -92,9 +92,10 @@ namespace ZL {
}
}
MenuManager::MenuManager(Renderer& iRenderer, GameState& gameState) :
MenuManager::MenuManager(Renderer& iRenderer, GameState& gameState, AudioPlayerAsync& audioPlayer) :
renderer(iRenderer),
gameState_(gameState)
gameState_(gameState),
audioPlayer_(audioPlayer)
{
}
@ -250,6 +251,9 @@ namespace ZL {
void MenuManager::showMainMenu() {
if (onResetGame) onResetGame();
audioPlayer_.playMusicAsync("audio/main menu final.ogg");
uiState_ = GameUiState::MainMenu;
uiManager.clearMenuStack();
topUiManager.replaceRoot(nullptr);
@ -900,13 +904,46 @@ namespace ZL {
uiManager.replaceRoot(gameState_.isDarklands ? hudUniExtDarkRoot : hudUniExtRoot);
applyCurrentHealthBar();
setupGameplayHudCallbacks();
if (gameState_.isDarklands)
{
audioPlayer_.playMusicAsync("audio/bishkek fight calm.ogg");
}
else if (gameState_.isNight)
{
audioPlayer_.playMusicAsync("audio/bishkek fight calm.ogg");
}
else
{
audioPlayer_.playMusicAsync("audio/bishkek univer day.ogg");
}
} else if (locationName == "uni_interior") {
applyUniIntHud();
if (gameState_.isDarklands)
{
audioPlayer_.playMusicAsync("audio/bishkek fight calm.ogg");
}
else if (gameState_.isNight)
{
audioPlayer_.playMusicAsync("audio/bishkek fight calm.ogg");
}
else
{
audioPlayer_.playMusicAsync("audio/bishkek univer day.ogg");
}
} else {
// Returning to dorm: reuse step5ab, suppress already-completed hints
uiManager.replaceRoot(hudStep5abRoot);
applyCurrentHealthBar();
setupStep5Callbacks();
if (gameState_.isNight)
{
audioPlayer_.playMusicAsync("audio/bishkek fight calm.ogg");
}
else
{
audioPlayer_.playMusicAsync("audio/obshaga.ogg");
}
}
}

View File

@ -9,6 +9,7 @@
#include <deque>
#include <string>
#include <memory>
#include "AudioPlayerAsync.h"
// Forward-declared here to avoid pulling Game.h into MenuManager.h.
namespace ZL { struct SaveSlotInfo; }
@ -31,7 +32,7 @@ namespace ZL {
UiManager uiManager;
UiManager topUiManager;
MenuManager(Renderer& iRenderer, GameState& gameState);
MenuManager(Renderer& iRenderer, GameState& gameState, AudioPlayerAsync& audioPlayer);
void setup(Inventory& inv, const std::string& zipFile);
@ -101,6 +102,7 @@ namespace ZL {
private:
GameState& gameState_;
AudioPlayerAsync& audioPlayer_;
void enterGameplay(bool isFromLoad = false);
void applyHudForCurrentState();