implemented ChangeWeather script function

actorid
scrawl 13 years ago
parent a05ba97382
commit 528cff5a59

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

@ -92,6 +92,25 @@ namespace MWScript
runtime.push (context.getWorld().getCurrentWeather());
}
};
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 opcodeTurnMoonWhite = 0x2000022;
@ -99,6 +118,7 @@ namespace MWScript
const int opcodeGetMasserPhase = 0x2000024;
const int opcodeGetSecundaPhase = 0x2000025;
const int opcodeGetCurrentWeather = 0x200013f;
const int opcodeChangeWeather = 0x2000140;
void registerExtensions (Compiler::Extensions& extensions)
{
@ -106,6 +126,7 @@ namespace MWScript
extensions.registerInstruction ("ts", "", opcodeToggleSky);
extensions.registerInstruction ("turnmoonwhite", "", opcodeTurnMoonWhite);
extensions.registerInstruction ("turnmoonred", "", opcodeTurnMoonRed);
extensions.registerInstruction ("changeweather", "Sl", opcodeChangeWeather);
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather);
@ -119,6 +140,7 @@ namespace MWScript
interpreter.installSegment5 (opcodeGetMasserPhase, new OpGetMasserPhase);
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase);
interpreter.installSegment5 (opcodeGetCurrentWeather, new OpGetCurrentWeather);
interpreter.installSegment5 (opcodeChangeWeather, new OpChangeWeather);
}
}
}

@ -9,6 +9,8 @@
#include <cstdlib>
#include <iostream>
#include <boost/algorithm/string.hpp>
using namespace Ogre;
using namespace MWWorld;
using namespace MWSound;
@ -483,54 +485,60 @@ void WeatherManager::update(float duration)
if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
{
std::string regionstr = mEnvironment->mWorld->getPlayer().getPlayer().getCell()->cell->region;
boost::algorithm::to_lower(regionstr);
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{
mCurrentRegion = regionstr;
mWeatherUpdateTime = WeatherGlobals::mWeatherUpdateTime*60.f;
// get weather probabilities for the current region
const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
float clear = region->data.clear/255.f;
float cloudy = region->data.cloudy/255.f;
float foggy = region->data.foggy/255.f;
float overcast = region->data.overcast/255.f;
float rain = region->data.rain/255.f;
float thunder = region->data.thunder/255.f;
float ash = region->data.ash/255.f;
float blight = region->data.blight/255.f;
float snow = region->data.a/255.f;
float blizzard = region->data.b/255.f;
// re-scale to 100 percent
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
srand(time(NULL));
float random = ((rand()%100)/100.f) * total;
std::string weather;
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blizzard";
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "snow";
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blight";
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
weather = "ashstorm";
else if (random >= rain+overcast+foggy+cloudy+clear)
weather = "thunderstorm";
else if (random >= overcast+foggy+cloudy+clear)
weather = "rain";
else if (random >= foggy+cloudy+clear)
weather = "overcast";
else if (random >= cloudy+clear)
weather = "foggy";
else if (random >= clear)
weather = "cloudy";
if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
weather = mRegionOverrides[regionstr];
else
weather = "clear";
{
// get weather probabilities for the current region
const ESM::Region *region = mEnvironment->mWorld->getStore().regions.find (regionstr);
float clear = region->data.clear/255.f;
float cloudy = region->data.cloudy/255.f;
float foggy = region->data.foggy/255.f;
float overcast = region->data.overcast/255.f;
float rain = region->data.rain/255.f;
float thunder = region->data.thunder/255.f;
float ash = region->data.ash/255.f;
float blight = region->data.blight/255.f;
float snow = region->data.a/255.f;
float blizzard = region->data.b/255.f;
// re-scale to 100 percent
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
srand(time(NULL));
float random = ((rand()%100)/100.f) * total;
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blizzard";
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "snow";
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blight";
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
weather = "ashstorm";
else if (random >= rain+overcast+foggy+cloudy+clear)
weather = "thunderstorm";
else if (random >= overcast+foggy+cloudy+clear)
weather = "rain";
else if (random >= foggy+cloudy+clear)
weather = "overcast";
else if (random >= cloudy+clear)
weather = "foggy";
else if (random >= clear)
weather = "cloudy";
else
weather = "clear";
}
setWeather(weather, false);
/*
@ -756,3 +764,32 @@ unsigned int WeatherManager::getWeatherID() const
else
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;
}

@ -112,14 +112,14 @@ namespace MWWorld
static const std::string mThunderSoundID2;
static const std::string mThunderSoundID3;
};
/// Defines the actual weather that results from weather setting (see below), time of day and weather transition
struct WeatherResult
{
Ogre::String mCloudTexture;
Ogre::String mNextCloudTexture;
float mCloudBlendFactor;
Ogre::ColourValue mFogColor;
Ogre::ColourValue mAmbientColor;
@ -217,13 +217,11 @@ namespace MWWorld
WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*);
/**
* Change the weather setting
* @param weather
* new weather setting to use
* @param instant
* if true, the weather changes instantly. if false, it slowly starts transitioning.
* Change the weather in the specified region
* @param region that should be changed
* @param ID of the weather setting to shift to
*/
void setWeather(const Ogre::String& weather, bool instant=false);
void changeWeather(const std::string& region, const unsigned int id);
/**
* Per-frame update
@ -240,12 +238,14 @@ namespace MWWorld
private:
float mHour;
int mDay, mMonth;
MWRender::RenderingManager* mRendering;
MWWorld::Environment* mEnvironment;
std::map<Ogre::String, Weather> mWeatherSettings;
std::map<std::string, std::string> mRegionOverrides;
Ogre::String mCurrentWeather;
Ogre::String mNextWeather;
@ -256,7 +256,7 @@ namespace MWWorld
float mWeatherUpdateTime;
float mRemainingTransitionTime;
float mThunderFlash;
float mThunderChance;
float mThunderChanceNeeded;
@ -264,6 +264,8 @@ namespace MWWorld
WeatherResult transition(const float factor);
WeatherResult getResult(const Ogre::String& weather);
void setWeather(const Ogre::String& weather, bool instant=false);
};
}

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

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

Loading…
Cancel
Save