mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-29 18:32:36 +00:00
Merge branch 'project_warp_speed' into 'master'
[Lua] Set simulation time scale See merge request OpenMW/openmw!2053
This commit is contained in:
commit
132031c136
@ -1082,7 +1082,7 @@ void OMW::Engine::go()
|
||||
const double dt = std::chrono::duration_cast<std::chrono::duration<double>>(std::min(
|
||||
frameRateLimiter.getLastFrameDuration(),
|
||||
maxSimulationInterval
|
||||
)).count();
|
||||
)).count() * mEnvironment.getWorld()->getSimulationTimeScale();
|
||||
|
||||
mViewer->advance(simulationTime);
|
||||
|
||||
|
@ -43,6 +43,8 @@ namespace MWSound
|
||||
* much. */
|
||||
NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the
|
||||
* player is making it. */
|
||||
NoScaling = 1<<4, /* Don't scale audio with simulation time */
|
||||
NoEnvNoScaling = NoEnv | NoScaling,
|
||||
LoopNoEnv = Loop | NoEnv,
|
||||
LoopRemoveAtDistance = Loop | RemoveAtDistance
|
||||
};
|
||||
@ -72,6 +74,8 @@ namespace MWBase
|
||||
using PlayMode = MWSound::PlayMode;
|
||||
using Type = MWSound::Type;
|
||||
|
||||
float mSimulationTimeScale = 1.0;
|
||||
|
||||
public:
|
||||
SoundManager() {}
|
||||
virtual ~SoundManager() {}
|
||||
@ -181,6 +185,9 @@ namespace MWBase
|
||||
|
||||
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
|
||||
|
||||
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
|
||||
float getSimulationTimeScale() const { return mSimulationTimeScale; }
|
||||
|
||||
virtual void clear() = 0;
|
||||
};
|
||||
}
|
||||
|
@ -255,6 +255,10 @@ namespace MWBase
|
||||
|
||||
virtual float getTimeScaleFactor() const = 0;
|
||||
|
||||
virtual float getSimulationTimeScale() const = 0;
|
||||
|
||||
virtual void setSimulationTimeScale(float scale) = 0;
|
||||
|
||||
virtual void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent=true) = 0;
|
||||
///< Move to interior cell.
|
||||
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||
|
@ -2098,7 +2098,7 @@ namespace MWGui
|
||||
if (soundId.empty())
|
||||
return;
|
||||
|
||||
MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv);
|
||||
MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnvNoScaling);
|
||||
}
|
||||
|
||||
void WindowManager::updateSpellWindow()
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "eventqueue.hpp"
|
||||
#include "worldview.hpp"
|
||||
#include "luamanagerimp.hpp"
|
||||
#include "types/types.hpp"
|
||||
|
||||
namespace MWLua
|
||||
@ -20,8 +21,10 @@ namespace MWLua
|
||||
|
||||
static void addTimeBindings(sol::table& api, const Context& context, bool global)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
api["getSimulationTime"] = [world=context.mWorldView]() { return world->getSimulationTime(); };
|
||||
api["getSimulationTimeScale"] = [world=context.mWorldView]() { return world->getSimulationTimeScale(); };
|
||||
api["getSimulationTimeScale"] = [world]() { return world->getSimulationTimeScale(); };
|
||||
api["getGameTime"] = [world=context.mWorldView]() { return world->getGameTime(); };
|
||||
api["getGameTimeScale"] = [world=context.mWorldView]() { return world->getGameTimeScale(); };
|
||||
api["isWorldPaused"] = [world=context.mWorldView]() { return world->isPaused(); };
|
||||
@ -35,8 +38,12 @@ namespace MWLua
|
||||
|
||||
api["setGameTimeScale"] = [world=context.mWorldView](double scale) { world->setGameTimeScale(scale); };
|
||||
|
||||
// TODO: Ability to make game time slower or faster than real time (needed for example for mechanics like VATS)
|
||||
// api["setSimulationTimeScale"] = [](double scale) {};
|
||||
api["setSimulationTimeScale"] = [context, world](float scale)
|
||||
{
|
||||
context.mLuaManager->addAction([scale, world] {
|
||||
world->setSimulationTimeScale(scale);
|
||||
});
|
||||
};
|
||||
|
||||
// TODO: Ability to pause/resume world from Lua (needed for UI dehardcoding)
|
||||
// api["pause"] = []() {};
|
||||
@ -47,7 +54,7 @@ namespace MWLua
|
||||
{
|
||||
auto* lua = context.mLua;
|
||||
sol::table api(lua->sol(), sol::create);
|
||||
api["API_REVISION"] = 26;
|
||||
api["API_REVISION"] = 27;
|
||||
api["quit"] = [lua]()
|
||||
{
|
||||
Log(Debug::Warning) << "Quit requested by a Lua script.\n" << lua->debugTraceback();
|
||||
|
@ -30,7 +30,6 @@ namespace MWLua
|
||||
// The number of seconds passed from the beginning of the game.
|
||||
double getSimulationTime() const { return mSimulationTime; }
|
||||
void setSimulationTime(double t) { mSimulationTime = t; }
|
||||
double getSimulationTimeScale() const { return 1.0; }
|
||||
|
||||
// The game time (in game seconds) passed from the beginning of the game.
|
||||
// Note that game time generally goes faster than the simulation time.
|
||||
|
@ -1126,7 +1126,7 @@ bool OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset)
|
||||
}
|
||||
source = mFreeSources.front();
|
||||
|
||||
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(),
|
||||
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound),
|
||||
sound->getIsLooping(), sound->getUseEnv());
|
||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||
@ -1166,7 +1166,7 @@ bool OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset)
|
||||
source = mFreeSources.front();
|
||||
|
||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||
sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(),
|
||||
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(),
|
||||
sound->getUseEnv());
|
||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||
@ -1228,7 +1228,7 @@ void OpenAL_Output::updateSound(Sound *sound)
|
||||
ALuint source = GET_PTRID(sound->mHandle);
|
||||
|
||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
||||
sound->getPitch(), sound->getUseEnv());
|
||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
||||
getALError();
|
||||
}
|
||||
|
||||
@ -1245,7 +1245,7 @@ bool OpenAL_Output::streamSound(DecoderPtr decoder, Stream *sound, bool getLoudn
|
||||
if(sound->getIsLooping())
|
||||
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
||||
|
||||
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(),
|
||||
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound),
|
||||
false, sound->getUseEnv());
|
||||
if(getALError() != AL_NO_ERROR)
|
||||
return false;
|
||||
@ -1277,7 +1277,7 @@ bool OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream *sound, bool getLou
|
||||
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
||||
|
||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||
sound->getRealVolume(), sound->getPitch(), false, sound->getUseEnv());
|
||||
sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
|
||||
if(getALError() != AL_NO_ERROR)
|
||||
return false;
|
||||
|
||||
@ -1354,7 +1354,7 @@ void OpenAL_Output::updateStream(Stream *sound)
|
||||
ALuint source = stream->mSource;
|
||||
|
||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
||||
sound->getPitch(), sound->getUseEnv());
|
||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
||||
getALError();
|
||||
}
|
||||
|
||||
@ -1510,4 +1510,10 @@ OpenAL_Output::~OpenAL_Output()
|
||||
OpenAL_Output::deinit();
|
||||
}
|
||||
|
||||
float OpenAL_Output::getTimeScaledPitch(SoundBase *sound)
|
||||
{
|
||||
const bool shouldScale = !(sound->mParams.mFlags & PlayMode::NoScaling);
|
||||
return shouldScale ? sound->getPitch() * mManager.getSimulationTimeScale() : sound->getPitch();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
namespace MWSound
|
||||
{
|
||||
class SoundManager;
|
||||
class SoundBase;
|
||||
class Sound;
|
||||
class Stream;
|
||||
|
||||
@ -55,6 +56,8 @@ namespace MWSound
|
||||
|
||||
void updateCommon(ALuint source, const osg::Vec3f &pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv);
|
||||
|
||||
float getTimeScaledPitch(SoundBase *sound);
|
||||
|
||||
OpenAL_Output& operator=(const OpenAL_Output &rhs);
|
||||
OpenAL_Output(const OpenAL_Output &rhs);
|
||||
|
||||
|
@ -248,7 +248,7 @@ namespace MWSound
|
||||
mMusic->init([&] {
|
||||
SoundParams params;
|
||||
params.mBaseVolume = volumeFromType(Type::Music);
|
||||
params.mFlags = PlayMode::NoEnv | Type::Music | Play_2D;
|
||||
params.mFlags = PlayMode::NoEnvNoScaling | Type::Music | Play_2D;
|
||||
return params;
|
||||
} ());
|
||||
mOutput->streamSound(decoder, mMusic.get());
|
||||
@ -462,7 +462,7 @@ namespace MWSound
|
||||
track->init([&] {
|
||||
SoundParams params;
|
||||
params.mBaseVolume = volumeFromType(type);
|
||||
params.mFlags = PlayMode::NoEnv | type | Play_2D;
|
||||
params.mFlags = PlayMode::NoEnvNoScaling | type | Play_2D;
|
||||
return params;
|
||||
} ());
|
||||
if(!mOutput->streamSound(decoder, track.get()))
|
||||
|
@ -5,11 +5,11 @@ namespace MWSound
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
Sfx = 1 << 4, /* Normal SFX sound */
|
||||
Voice = 1 << 5, /* Voice sound */
|
||||
Foot = 1 << 6, /* Footstep sound */
|
||||
Music = 1 << 7, /* Music track */
|
||||
Movie = 1 << 8, /* Movie audio track */
|
||||
Sfx = 1 << 5, /* Normal SFX sound */
|
||||
Voice = 1 << 6, /* Voice sound */
|
||||
Foot = 1 << 7, /* Footstep sound */
|
||||
Music = 1 << 8, /* Music track */
|
||||
Movie = 1 << 9, /* Movie audio track */
|
||||
Mask = Sfx | Voice | Foot | Music | Movie
|
||||
};
|
||||
}
|
||||
|
@ -921,6 +921,12 @@ namespace MWWorld
|
||||
return mCurrentDate->getTimeScaleFactor();
|
||||
}
|
||||
|
||||
void World::setSimulationTimeScale(float scale)
|
||||
{
|
||||
mSimulationTimeScale = std::max(0.f, scale);
|
||||
MWBase::Environment::get().getSoundManager()->setSimulationTimeScale(mSimulationTimeScale);
|
||||
}
|
||||
|
||||
TimeStamp World::getTimeStamp() const
|
||||
{
|
||||
return mCurrentDate->getTimeStamp();
|
||||
|
@ -134,6 +134,8 @@ namespace MWWorld
|
||||
|
||||
uint32_t mRandomSeed{};
|
||||
|
||||
float mSimulationTimeScale = 1.0;
|
||||
|
||||
// not implemented
|
||||
World (const World&);
|
||||
World& operator= (const World&);
|
||||
@ -347,6 +349,10 @@ namespace MWWorld
|
||||
|
||||
float getTimeScaleFactor() const override;
|
||||
|
||||
float getSimulationTimeScale() const override { return mSimulationTimeScale; }
|
||||
|
||||
void setSimulationTimeScale(float scale) override;
|
||||
|
||||
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) override;
|
||||
///< Move to interior cell.
|
||||
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||
|
@ -34,6 +34,11 @@
|
||||
-- @function [parent=#world] getSimulationTimeScale
|
||||
-- @return #number
|
||||
|
||||
---
|
||||
-- Set the simulation time scale.
|
||||
-- @function [parent=#world] setSimulationTimeScale
|
||||
-- @param #number scale
|
||||
|
||||
---
|
||||
-- Game time in seconds.
|
||||
-- @function [parent=#world] getGameTime
|
||||
|
Loading…
x
Reference in New Issue
Block a user