mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-14 07:52:54 +00:00
feat: minecart sound effects
This commit is contained in:
parent
a8f31211bf
commit
d82e1afd59
|
|
@ -109,6 +109,7 @@ enum EGameHostOptionWorldSize
|
|||
#define GAMESETTING_EXCLUSIVEFULLSCREEN 0x02000000
|
||||
#define GAMESETTING_CLASSICCRAFTING 0x04000000
|
||||
#define GAMESETTING_CAVESOUNDS 0x08000000
|
||||
#define GAMESETTING_MINECARTSOUNDS 0x10000000
|
||||
|
||||
|
||||
// defines for languages
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ enum eGameSetting
|
|||
//TU25
|
||||
eGameSetting_ClassicCrafting,
|
||||
eGameSetting_CaveSounds,
|
||||
eGameSetting_MinecartSounds,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -605,34 +605,8 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa
|
|||
m_activeSounds.push_back(s);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// startElytraSound / stopElytraSound
|
||||
// Manages a single persistent looping sound for elytra gliding.
|
||||
// Call startElytraSound every tick while gliding (it no-ops if already running,
|
||||
// just updates volume). Call stopElytraSound when gliding ends.
|
||||
//
|
||||
// IMPORTANT: m_elytraLoopingSound is NOT added to m_activeSounds.
|
||||
// The tick() cleanup loop deletes sounds where is_playing()==false.
|
||||
// A looping sound briefly reports is_playing()==false at the loop point,
|
||||
// which would cause tick() to free it and leave m_elytraLoopingSound dangling.
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
void SoundEngine::startElytraSound(float x, float y, float z, float volume, float pitch)
|
||||
MiniAudioSound* SoundEngine::startLoopingSound(const wstring& name, float x, float y, float z, float volume, float pitch, bool bIs3D)
|
||||
{
|
||||
// If already initialized just update volume and pitch - never reinitialize mid-flight.
|
||||
if (m_elytraLoopingSound != nullptr)
|
||||
{
|
||||
float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER;
|
||||
if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN;
|
||||
ma_sound_set_volume(&m_elytraLoopingSound->sound, finalVolume);
|
||||
ma_sound_set_pitch(&m_elytraLoopingSound->sound, pitch);
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve file path using the same logic as play().
|
||||
wstring name = wchSoundNames[eSoundType_ITEM_ELYTRA_FLYING];
|
||||
char* soundName = ConvertSoundPathToName(name);
|
||||
char basePath[256];
|
||||
sprintf_s(basePath, "Windows64Media/Sound/Minecraft/%s", soundName);
|
||||
|
|
@ -652,42 +626,100 @@ void SoundEngine::startElytraSound(float x, float y, float z, float volume, floa
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return;
|
||||
if (!found)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MiniAudioSound* s = new MiniAudioSound();
|
||||
memset(&s->info, 0, sizeof(AUDIO_INFO));
|
||||
s->info.volume = volume; s->info.pitch = pitch;
|
||||
s->info.bIs3D = false;
|
||||
s->info.iSound = eSoundType_ITEM_ELYTRA_FLYING + eSFX_MAX;
|
||||
s->info.x = x;
|
||||
s->info.y = y;
|
||||
s->info.z = z;
|
||||
s->info.volume = volume;
|
||||
s->info.pitch = pitch;
|
||||
s->info.bIs3D = bIs3D;
|
||||
s->info.bUseSoundsPitchVal = false;
|
||||
|
||||
// Synchronous load so the sound is immediately ready - no ASYNC gap.
|
||||
if (ma_sound_init_from_file(&m_engine, finalPath, 0,
|
||||
nullptr, nullptr, &s->sound) != MA_SUCCESS)
|
||||
if (ma_sound_init_from_file(&m_engine, finalPath, 0, nullptr, nullptr, &s->sound) != MA_SUCCESS)
|
||||
{
|
||||
delete s;
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE);
|
||||
ma_sound_set_spatialization_enabled(&s->sound, bIs3D ? MA_TRUE : MA_FALSE);
|
||||
ma_sound_set_looping(&s->sound, MA_TRUE);
|
||||
|
||||
float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER;
|
||||
if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN;
|
||||
if (finalVolume > SFX_MAX_GAIN)
|
||||
finalVolume = SFX_MAX_GAIN;
|
||||
ma_sound_set_volume(&s->sound, finalVolume);
|
||||
ma_sound_set_pitch(&s->sound, pitch);
|
||||
if (bIs3D)
|
||||
{
|
||||
ma_sound_set_position(&s->sound, x, y, z);
|
||||
}
|
||||
ma_sound_start(&s->sound);
|
||||
return s;
|
||||
}
|
||||
|
||||
void SoundEngine::updateLoopingSound(MiniAudioSound* sound, float x, float y, float z, float volume, float pitch)
|
||||
{
|
||||
if (sound == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER;
|
||||
if (finalVolume > SFX_MAX_GAIN)
|
||||
finalVolume = SFX_MAX_GAIN;
|
||||
ma_sound_set_volume(&sound->sound, finalVolume);
|
||||
ma_sound_set_pitch(&sound->sound, pitch);
|
||||
ma_sound_set_position(&sound->sound, x, y, z);
|
||||
}
|
||||
|
||||
void SoundEngine::stopLoopingSound(MiniAudioSound* sound)
|
||||
{
|
||||
if (sound == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ma_sound_stop(&sound->sound);
|
||||
ma_sound_uninit(&sound->sound);
|
||||
delete sound;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// startElytraSound / stopElytraSound
|
||||
// Manages a single persistent looping sound for elytra gliding.
|
||||
// Call startElytraSound every tick while gliding (it no-ops if already running,
|
||||
// just updates volume). Call stopElytraSound when gliding ends.
|
||||
//
|
||||
// IMPORTANT: m_elytraLoopingSound is NOT added to m_activeSounds.
|
||||
// The tick() cleanup loop deletes sounds where is_playing()==false.
|
||||
// A looping sound briefly reports is_playing()==false at the loop point,
|
||||
// which would cause tick() to free it and leave m_elytraLoopingSound dangling.
|
||||
//
|
||||
/////////////////////////////////////////////
|
||||
void SoundEngine::startElytraSound(float x, float y, float z, float volume, float pitch)
|
||||
{
|
||||
// If already initialized just update volume and pitch - never reinitialize mid-flight.
|
||||
if (m_elytraLoopingSound != nullptr)
|
||||
{
|
||||
updateLoopingSound(m_elytraLoopingSound, x, y, z, volume, pitch);
|
||||
return;
|
||||
}
|
||||
// NOT added to m_activeSounds - tick() cleanup would delete it at loop boundaries.
|
||||
m_elytraLoopingSound = s;
|
||||
m_elytraLoopingSound = startLoopingSound(wchSoundNames[eSoundType_ITEM_ELYTRA_FLYING], x, y, z, volume, pitch, false);
|
||||
}
|
||||
|
||||
void SoundEngine::stopElytraSound()
|
||||
{
|
||||
if (m_elytraLoopingSound == nullptr) return;
|
||||
|
||||
ma_sound_stop(&m_elytraLoopingSound->sound);
|
||||
ma_sound_uninit(&m_elytraLoopingSound->sound);
|
||||
delete m_elytraLoopingSound;
|
||||
stopLoopingSound(m_elytraLoopingSound);
|
||||
m_elytraLoopingSound = nullptr;
|
||||
}
|
||||
/////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -127,6 +127,9 @@ public:
|
|||
void GetSoundName(char *szSoundName,int iSound);
|
||||
#endif
|
||||
void play(int iSound, float x, float y, float z, float volume, float pitch) override;
|
||||
MiniAudioSound* startLoopingSound(const wstring& name, float x, float y, float z, float volume, float pitch, bool bIs3D = true);
|
||||
void updateLoopingSound(MiniAudioSound* sound, float x, float y, float z, float volume, float pitch);
|
||||
void stopLoopingSound(MiniAudioSound* sound);
|
||||
void startElytraSound(float x, float y, float z, float volume, float pitch);
|
||||
void stopElytraSound();
|
||||
void playStreaming(const wstring& name, float x, float y , float z, float volume, float pitch, bool bMusicDelay=true) override;
|
||||
|
|
|
|||
|
|
@ -1043,6 +1043,7 @@ int CMinecraftApp::SetDefaultOptions(C_4JProfile::PROFILESETTINGS *pSettings,con
|
|||
//TU25
|
||||
SetGameSettings(iPad, eGameSetting_ClassicCrafting, 0);
|
||||
SetGameSettings(iPad, eGameSetting_CaveSounds, 1);
|
||||
SetGameSettings(iPad, eGameSetting_MinecartSounds, 1);
|
||||
|
||||
// 4J-PB - leave these in, or remove from everywhere they are referenced!
|
||||
// Although probably best to leave in unless we split the profile settings into platform specific classes - having different meaning per platform for the same bitmask could get confusing
|
||||
|
|
@ -1504,6 +1505,7 @@ void CMinecraftApp::ApplyGameSettingsChanged(int iPad)
|
|||
//TU25
|
||||
ActionGameSettings(iPad, eGameSetting_ClassicCrafting);
|
||||
ActionGameSettings(iPad, eGameSetting_CaveSounds);
|
||||
ActionGameSettings(iPad, eGameSetting_MinecartSounds);
|
||||
}
|
||||
|
||||
void CMinecraftApp::ActionGameSettings(int iPad,eGameSetting eVal)
|
||||
|
|
@ -2529,6 +2531,21 @@ void CMinecraftApp::SetGameSettings(int iPad,eGameSetting eVal,unsigned char ucV
|
|||
GameSettingsA[iPad]->bSettingsChanged = true;
|
||||
}
|
||||
break;
|
||||
case eGameSetting_MinecartSounds:
|
||||
if ((GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_MINECARTSOUNDS) != (ucVal & 0x01) << 28)
|
||||
{
|
||||
if (ucVal == 1)
|
||||
{
|
||||
GameSettingsA[iPad]->uiBitmaskValues |= GAMESETTING_MINECARTSOUNDS;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameSettingsA[iPad]->uiBitmaskValues &= ~GAMESETTING_MINECARTSOUNDS;
|
||||
}
|
||||
ActionGameSettings(iPad, eVal);
|
||||
GameSettingsA[iPad]->bSettingsChanged = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2670,6 +2687,9 @@ unsigned char CMinecraftApp::GetGameSettings(int iPad,eGameSetting eVal)
|
|||
case eGameSetting_CaveSounds:
|
||||
return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_CAVESOUNDS) >> 27;
|
||||
|
||||
case eGameSetting_MinecartSounds:
|
||||
return (GameSettingsA[iPad]->uiBitmaskValues & GAMESETTING_MINECARTSOUNDS) >> 28;
|
||||
|
||||
case eGameSetting_VSync:
|
||||
return (GameSettingsA[iPad]->uiBitmaskValues&GAMESETTING_VSYNC)>>24;
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -16,6 +16,8 @@ UIScene_SettingsAudioMenu::UIScene_SettingsAudioMenu(int iPad, void *initData, U
|
|||
|
||||
m_checkboxCaveSounds.init(L"Cave Sounds",eControl_CaveSounds,(app.GetGameSettings(m_iPad,eGameSetting_CaveSounds)!=0));
|
||||
|
||||
m_checkboxMinecartSounds.init(L"Minecart Sounds",eControl_MinecartSounds,(app.GetGameSettings(m_iPad,eGameSetting_MinecartSounds)!=0));
|
||||
|
||||
doHorizontalResizeCheck();
|
||||
|
||||
if(app.GetLocalPlayerCount()>1)
|
||||
|
|
@ -124,5 +126,8 @@ void UIScene_SettingsAudioMenu::handleCheckboxToggled(F64 controlId, bool select
|
|||
case eControl_CaveSounds:
|
||||
app.SetGameSettings(m_iPad, eGameSetting_CaveSounds, selected ? 1 : 0);
|
||||
break;
|
||||
case eControl_MinecartSounds:
|
||||
app.SetGameSettings(m_iPad, eGameSetting_MinecartSounds, selected ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,15 +9,18 @@ private:
|
|||
{
|
||||
eControl_Music,
|
||||
eControl_Sound,
|
||||
eControl_CaveSounds
|
||||
eControl_CaveSounds,
|
||||
eControl_MinecartSounds
|
||||
};
|
||||
|
||||
UIControl_Slider m_sliderMusic, m_sliderSound; // Sliders
|
||||
UIControl_CheckBox m_checkboxCaveSounds; // Checkboxes
|
||||
UIControl_CheckBox m_checkboxMinecartSounds;
|
||||
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
|
||||
UI_MAP_ELEMENT( m_sliderMusic, "Music")
|
||||
UI_MAP_ELEMENT( m_sliderSound, "Sound")
|
||||
UI_MAP_ELEMENT( m_checkboxCaveSounds, "CaveSounds")
|
||||
UI_MAP_ELEMENT( m_checkboxMinecartSounds, "MinecartSounds")
|
||||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
|
||||
public:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -6582,6 +6582,10 @@ Would you like to install the mash-up pack or texture pack now?</value>
|
|||
<value>Cave Sounds</value>
|
||||
</data>
|
||||
|
||||
<data name="IDS_CHECKBOX_MINECART_SOUNDS">
|
||||
<value>Minecart Sounds</value>
|
||||
</data>
|
||||
|
||||
<data name="IDS_TEXT_SAVEOPTIONS">
|
||||
<value>What would you like to do with this save game?</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "../Minecraft.Client/ServerLevel.h"
|
||||
#include "com.mojang.nbt.h"
|
||||
#include "Minecart.h"
|
||||
#include "MinecartSoundInstance.h"
|
||||
#include "SharedConstants.h"
|
||||
|
||||
|
||||
|
|
@ -44,7 +45,8 @@ void Minecart::_init()
|
|||
blocksBuilding = true;
|
||||
setSize(0.98f, 0.7f);
|
||||
heightOffset = bbHeight / 2.0f;
|
||||
soundUpdater = nullptr;
|
||||
m_rollingSound = nullptr;
|
||||
m_ridingSound = nullptr;
|
||||
name = L"";
|
||||
//
|
||||
|
||||
|
|
@ -61,26 +63,43 @@ Minecart::Minecart(Level *level) : Entity( level )
|
|||
|
||||
Minecart::~Minecart()
|
||||
{
|
||||
delete soundUpdater;
|
||||
delete m_rollingSound;
|
||||
delete m_ridingSound;
|
||||
}
|
||||
|
||||
shared_ptr<Minecart> Minecart::createMinecart(Level *level, double x, double y, double z, int type)
|
||||
{
|
||||
shared_ptr<Minecart> minecart;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_CHEST:
|
||||
return std::make_shared<MinecartChest>(level, x, y, z);
|
||||
minecart = std::make_shared<MinecartChest>(level, x, y, z);
|
||||
break;
|
||||
case TYPE_FURNACE:
|
||||
return std::make_shared<MinecartFurnace>(level, x, y, z);
|
||||
minecart = std::make_shared<MinecartFurnace>(level, x, y, z);
|
||||
break;
|
||||
case TYPE_TNT:
|
||||
return std::make_shared<MinecartTNT>(level, x, y, z);
|
||||
minecart = std::make_shared<MinecartTNT>(level, x, y, z);
|
||||
break;
|
||||
case TYPE_SPAWNER:
|
||||
return std::make_shared<MinecartSpawner>(level, x, y, z);
|
||||
minecart = std::make_shared<MinecartSpawner>(level, x, y, z);
|
||||
break;
|
||||
case TYPE_HOPPER:
|
||||
return std::make_shared<MinecartHopper>(level, x, y, z);
|
||||
minecart = std::make_shared<MinecartHopper>(level, x, y, z);
|
||||
break;
|
||||
default:
|
||||
return std::make_shared<MinecartRideable>(level, x, y, z);
|
||||
minecart = std::make_shared<MinecartRideable>(level, x, y, z);
|
||||
break;
|
||||
}
|
||||
|
||||
if (level != nullptr && level->isClientSide)
|
||||
{
|
||||
minecart->m_rollingSound = new MinecartSoundInstance(minecart);
|
||||
minecart->m_ridingSound = new RidingMinecartSoundInstance(minecart);
|
||||
}
|
||||
|
||||
return minecart;
|
||||
}
|
||||
|
||||
bool Minecart::makeStepSound()
|
||||
|
|
@ -207,11 +226,36 @@ bool Minecart::isPickable()
|
|||
void Minecart::remove()
|
||||
{
|
||||
Entity::remove();
|
||||
// clean up sounds after invalidation
|
||||
if (m_rollingSound)
|
||||
{
|
||||
delete m_rollingSound;
|
||||
m_rollingSound = nullptr;
|
||||
}
|
||||
if (m_ridingSound)
|
||||
{
|
||||
delete m_ridingSound;
|
||||
m_ridingSound = nullptr;
|
||||
}
|
||||
//if (soundUpdater != nullptr) soundUpdater->tick();
|
||||
}
|
||||
|
||||
void Minecart::tick()
|
||||
{
|
||||
// minecart tick handler
|
||||
if (level->isClientSide)
|
||||
{
|
||||
if (m_rollingSound)
|
||||
{
|
||||
m_rollingSound->tick();
|
||||
}
|
||||
|
||||
if (m_ridingSound)
|
||||
{
|
||||
m_ridingSound->tick();
|
||||
}
|
||||
}
|
||||
|
||||
//if (soundUpdater != nullptr) soundUpdater->tick();
|
||||
// 4J - make minecarts (server-side) tick twice, to put things back to how they were when we were accidently ticking them twice
|
||||
for( int i = 0; i < 2; i++ )
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
#include "Entity.h"
|
||||
|
||||
class DamageSource;
|
||||
class Tickable;
|
||||
class MinecartSoundInstance;
|
||||
class RidingMinecartSoundInstance;
|
||||
|
||||
class Minecart : public Entity
|
||||
{
|
||||
|
|
@ -30,7 +31,8 @@ private:
|
|||
static const int DATA_ID_CUSTOM_DISPLAY = 22;
|
||||
|
||||
bool flipped;
|
||||
Tickable *soundUpdater;
|
||||
MinecartSoundInstance *m_rollingSound;
|
||||
RidingMinecartSoundInstance *m_ridingSound;
|
||||
wstring name;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
175
Minecraft.World/MinecartSoundInstance.cpp
Normal file
175
Minecraft.World/MinecartSoundInstance.cpp
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#include "stdafx.h"
|
||||
#include "MinecartSoundInstance.h"
|
||||
#include "Minecart.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "../Minecraft.Client/Minecraft.h"
|
||||
#include "../Minecraft.Client/Common/Audio/SoundEngine.h"
|
||||
|
||||
// MinecartSoundInstance
|
||||
|
||||
MinecartSoundInstance::MinecartSoundInstance(shared_ptr<Minecart> minecart)
|
||||
: m_minecart(minecart), m_bIsCurrentlyPlaying(false), m_sound(nullptr), m_volume(0.0f), m_pitch(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
MinecartSoundInstance::~MinecartSoundInstance()
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
}
|
||||
m_sound = nullptr;
|
||||
}
|
||||
|
||||
void MinecartSoundInstance::tick()
|
||||
{
|
||||
if (!m_minecart || m_minecart->removed)
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// minecart sound functionality check
|
||||
if (!app.GetGameSettings(0, eGameSetting_MinecartSounds))
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// volume + pitch calculations
|
||||
// relative to minecart velocity
|
||||
double xd = m_minecart->xd;
|
||||
double zd = m_minecart->zd;
|
||||
double velocity = sqrt(xd * xd + zd * zd);
|
||||
|
||||
if (velocity >= 0.01)
|
||||
{
|
||||
float clampedVel = (float)(velocity > 1.0 ? 1.0 : (velocity < 0.0 ? 0.0 : velocity));
|
||||
m_volume = clampedVel * 0.75f;
|
||||
m_pitch = 1.0f;
|
||||
|
||||
if (!m_bIsCurrentlyPlaying)
|
||||
{
|
||||
m_bIsCurrentlyPlaying = true;
|
||||
if (Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
m_sound = Minecraft::GetInstance()->soundEngine->startLoopingSound(L"mob.minecart.rolling", (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch, true);
|
||||
}
|
||||
}
|
||||
else if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->updateLoopingSound(m_sound, (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_volume = 0.0f;
|
||||
m_pitch = 0.0f;
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
}
|
||||
}
|
||||
|
||||
// RidingMinecartSoundInstance
|
||||
|
||||
RidingMinecartSoundInstance::RidingMinecartSoundInstance(shared_ptr<Minecart> minecart)
|
||||
: m_minecart(minecart), m_bIsCurrentlyPlaying(false), m_sound(nullptr), m_volume(0.0f), m_pitch(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
RidingMinecartSoundInstance::~RidingMinecartSoundInstance()
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
}
|
||||
m_sound = nullptr;
|
||||
}
|
||||
|
||||
void RidingMinecartSoundInstance::tick()
|
||||
{
|
||||
if (!m_minecart || m_minecart->removed)
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// minecart sound functionality check
|
||||
if (!app.GetGameSettings(0, eGameSetting_MinecartSounds))
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// minecart passenger check
|
||||
if (m_minecart->rider.lock() == nullptr)
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// volume + pitch calculations
|
||||
// relative to minecart velocity
|
||||
double xd = m_minecart->xd;
|
||||
double zd = m_minecart->zd;
|
||||
double velocity = sqrt(xd * xd + zd * zd);
|
||||
|
||||
if (velocity >= 0.01)
|
||||
{
|
||||
float clampedVel = (float)(velocity > 1.0 ? 1.0 : (velocity < 0.0 ? 0.0 : velocity));
|
||||
m_volume = clampedVel * 0.75f;
|
||||
m_pitch = 1.0f;
|
||||
|
||||
if (!m_bIsCurrentlyPlaying)
|
||||
{
|
||||
m_bIsCurrentlyPlaying = true;
|
||||
if (Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
m_sound = Minecraft::GetInstance()->soundEngine->startLoopingSound(L"mob.minecart.inside", (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch, false);
|
||||
}
|
||||
}
|
||||
else if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->updateLoopingSound(m_sound, (float)m_minecart->x, (float)m_minecart->y, (float)m_minecart->z, m_volume, m_pitch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_sound && Minecraft::GetInstance() && Minecraft::GetInstance()->soundEngine)
|
||||
{
|
||||
Minecraft::GetInstance()->soundEngine->stopLoopingSound(m_sound);
|
||||
m_sound = nullptr;
|
||||
}
|
||||
m_volume = 0.0f;
|
||||
m_bIsCurrentlyPlaying = false;
|
||||
}
|
||||
}
|
||||
43
Minecraft.World/MinecartSoundInstance.h
Normal file
43
Minecraft.World/MinecartSoundInstance.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Minecart;
|
||||
class SoundEngine;
|
||||
struct MiniAudioSound;
|
||||
|
||||
// minecart rolling sound
|
||||
class MinecartSoundInstance
|
||||
{
|
||||
protected:
|
||||
shared_ptr<Minecart> m_minecart;
|
||||
bool m_bIsCurrentlyPlaying;
|
||||
MiniAudioSound* m_sound;
|
||||
float m_volume;
|
||||
float m_pitch;
|
||||
|
||||
public:
|
||||
MinecartSoundInstance(shared_ptr<Minecart> minecart);
|
||||
virtual ~MinecartSoundInstance();
|
||||
|
||||
virtual void tick();
|
||||
bool isCurrentlyPlaying() const { return m_bIsCurrentlyPlaying; }
|
||||
};
|
||||
|
||||
// minecart passenger sound
|
||||
class RidingMinecartSoundInstance
|
||||
{
|
||||
protected:
|
||||
shared_ptr<Minecart> m_minecart;
|
||||
bool m_bIsCurrentlyPlaying;
|
||||
MiniAudioSound* m_sound;
|
||||
float m_volume;
|
||||
float m_pitch;
|
||||
|
||||
public:
|
||||
RidingMinecartSoundInstance(shared_ptr<Minecart> minecart);
|
||||
virtual ~RidingMinecartSoundInstance();
|
||||
|
||||
virtual void tick();
|
||||
bool isCurrentlyPlaying() const { return m_bIsCurrentlyPlaying; }
|
||||
};
|
||||
|
|
@ -838,6 +838,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_ENTITY_ITEM
|
|||
"${CMAKE_CURRENT_SOURCE_DIR}/ItemEntity.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Minecart.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Minecart.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MinecartSoundInstance.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MinecartSoundInstance.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MinecartChest.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MinecartChest.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/MinecartContainer.cpp"
|
||||
|
|
|
|||
Loading…
Reference in a new issue