implemented ChangeWeather script function

This commit is contained in:
scrawl 2012-02-26 11:51:02 +01:00
parent a05ba97382
commit 528cff5a59
6 changed files with 120 additions and 51 deletions

View File

@ -120,4 +120,5 @@ op 0x200013c: FadeIn
op 0x200013d: FadeOut op 0x200013d: FadeOut
op 0x200013e: FadeTo op 0x200013e: FadeTo
op 0x200013f: GetCurrentWeather op 0x200013f: GetCurrentWeather
opcodes 0x2000140-0x3ffffff unused op 0x2000140: ChangeWeather
opcodes 0x2000141-0x3ffffff unused

View File

@ -93,12 +93,32 @@ namespace MWScript
} }
}; };
class OpChangeWeather : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
InterpreterContext& context =
static_cast<InterpreterContext&> (runtime.getContext());
std::string region = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
Interpreter::Type_Integer id = runtime[0].mInteger;
runtime.pop();
context.getWorld().changeWeather(region, id);
}
};
const int opcodeToggleSky = 0x2000021; const int opcodeToggleSky = 0x2000021;
const int opcodeTurnMoonWhite = 0x2000022; const int opcodeTurnMoonWhite = 0x2000022;
const int opcodeTurnMoonRed = 0x2000023; const int opcodeTurnMoonRed = 0x2000023;
const int opcodeGetMasserPhase = 0x2000024; const int opcodeGetMasserPhase = 0x2000024;
const int opcodeGetSecundaPhase = 0x2000025; const int opcodeGetSecundaPhase = 0x2000025;
const int opcodeGetCurrentWeather = 0x200013f; const int opcodeGetCurrentWeather = 0x200013f;
const int opcodeChangeWeather = 0x2000140;
void registerExtensions (Compiler::Extensions& extensions) void registerExtensions (Compiler::Extensions& extensions)
{ {
@ -106,6 +126,7 @@ namespace MWScript
extensions.registerInstruction ("ts", "", opcodeToggleSky); extensions.registerInstruction ("ts", "", opcodeToggleSky);
extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite); extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite);
extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed); extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed);
extensions.registerInstruction ("changeweather", "Sl", opcodeChangeWeather);
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase); extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase); extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather); extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather);
@ -119,6 +140,7 @@ namespace MWScript
interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase); interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase);
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase); interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase);
interpreter.installSegment5 (opcodeGetCurrentWeather, new OpGetCurrentWeather); interpreter.installSegment5 (opcodeGetCurrentWeather, new OpGetCurrentWeather);
interpreter.installSegment5 (opcodeChangeWeather, new OpChangeWeather);
} }
} }
} }

View File

@ -9,6 +9,8 @@
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <boost/algorithm/string.hpp>
using namespace Ogre; using namespace Ogre;
using namespace MWWorld; using namespace MWWorld;
using namespace MWSound; using namespace MWSound;
@ -483,12 +485,19 @@ void WeatherManager::update(float duration)
if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior()) if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
{ {
std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region; std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region;
boost::algorithm::to_lower(regionstr);
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{ {
mCurrentRegion = regionstr; mCurrentRegion = regionstr;
mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f; mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f;
std::string weather;
if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
weather = mRegionOverrides[regionstr];
else
{
// get weather probabilities for the current region // get weather probabilities for the current region
const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr); const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
@ -509,8 +518,6 @@ void WeatherManager::update(float duration)
srand(time(NULL)); srand(time(NULL));
float random = ((rand()%100)/100.f) * total; float random = ((rand()%100)/100.f) * total;
std::string weather;
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear) if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blizzard"; weather = "blizzard";
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear) else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
@ -531,6 +538,7 @@ void WeatherManager::update(float duration)
weather = "cloudy"; weather = "cloudy";
else else
weather = "clear"; weather = "clear";
}
setWeather(weather, false); setWeather(weather, false);
/* /*
@ -756,3 +764,32 @@ unsigned int WeatherManager::getWeatherID() const
else else
return 0; return 0;
} }
void WeatherManager::changeWeather(const std::string& region, const unsigned int id)
{
std::string weather;
if (id==0)
weather = "clear";
else if (id==1)
weather = "cloudy";
else if (id==2)
weather = "foggy";
else if (id==3)
weather = "overcast";
else if (id==4)
weather = "rain";
else if (id==5)
weather = "thunder";
else if (id==6)
weather = "ashstorm";
else if (id==7)
weather = "blight";
else if (id==8)
weather = "snow";
else if (id==9)
weather = "blizzard";
else
weather = "clear";
mRegionOverrides[region] = weather;
}

View File

@ -217,13 +217,11 @@ namespace MWWorld
WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*); WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*);
/** /**
* Change the weather setting * Change the weather in the specified region
* @param weather * @param region that should be changed
* new weather setting to use * @param ID of the weather setting to shift to
* @param instant
* if true, the weather changes instantly. if false, it slowly starts transitioning.
*/ */
void setWeather(const Ogre::String& weather, bool instant=false); void changeWeather(const std::string& region, const unsigned int id);
/** /**
* Per-frame update * Per-frame update
@ -246,6 +244,8 @@ namespace MWWorld
std::map<Ogre::String, Weather> mWeatherSettings; std::map<Ogre::String, Weather> mWeatherSettings;
std::map<std::string, std::string> mRegionOverrides;
Ogre::String mCurrentWeather; Ogre::String mCurrentWeather;
Ogre::String mNextWeather; Ogre::String mNextWeather;
@ -264,6 +264,8 @@ namespace MWWorld
WeatherResult transition(const float factor); WeatherResult transition(const float factor);
WeatherResult getResult(const Ogre::String& weather); WeatherResult getResult(const Ogre::String& weather);
void setWeather(const Ogre::String& weather, bool instant=false);
}; };
} }

View File

@ -741,6 +741,11 @@ namespace MWWorld
return mWeatherManager->getWeatherID(); return mWeatherManager->getWeatherID();
} }
void World::changeWeather(const std::string& region, const unsigned int id)
{
mWeatherManager->changeWeather(region, id);
}
OEngine::Render::Fader* World::getFader() OEngine::Render::Fader* World::getFader()
{ {
return mRendering->getFader(); return mRendering->getFader();

View File

@ -164,6 +164,8 @@ namespace MWWorld
bool toggleSky(); bool toggleSky();
///< \return Resulting mode ///< \return Resulting mode
void changeWeather(const std::string& region, const unsigned int id);
int getCurrentWeather() const; int getCurrentWeather() const;
int getMasserPhase() const; int getMasserPhase() const;