forked from teamnwah/openmw-tes3coop
Implement the ModRegion script function
This commit is contained in:
parent
1174b85ac8
commit
c94653dc49
7 changed files with 74 additions and 16 deletions
|
@ -201,6 +201,8 @@ namespace MWBase
|
|||
|
||||
virtual void setMoonColour (bool red) = 0;
|
||||
|
||||
virtual void modRegion(const std::string ®ionid, const std::vector<char> &chances) = 0;
|
||||
|
||||
virtual float getTimeScaleFactor() const = 0;
|
||||
|
||||
virtual void changeToInteriorCell (const std::string& cellName,
|
||||
|
|
|
@ -51,7 +51,8 @@ op 0x20022: AiFollow
|
|||
op 0x20023: AiFollow, explicit reference
|
||||
op 0x20024: AiFollowCell
|
||||
op 0x20025: AiFollowCell, explicit reference
|
||||
op s 0x20026-0x3ffff unused
|
||||
op 0x20026: ModRegion
|
||||
opcodes 0x20027-0x3ffff unused
|
||||
|
||||
Segment 4:
|
||||
(not implemented yet)
|
||||
|
|
|
@ -96,6 +96,28 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
class OpModRegion : public Interpreter::Opcode1
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
|
||||
{
|
||||
std::string region = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::vector<char> chances;
|
||||
chances.reserve(10);
|
||||
while(arg0 > 0)
|
||||
{
|
||||
chances.push_back(std::max(0, std::min(127, runtime[0].mInteger)));
|
||||
runtime.pop();
|
||||
arg0--;
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWorld()->modRegion(region, chances);
|
||||
}
|
||||
};
|
||||
|
||||
const int opcodeToggleSky = 0x2000021;
|
||||
const int opcodeTurnMoonWhite = 0x2000022;
|
||||
const int opcodeTurnMoonRed = 0x2000023;
|
||||
|
@ -103,6 +125,7 @@ namespace MWScript
|
|||
const int opcodeGetSecundaPhase = 0x2000025;
|
||||
const int opcodeGetCurrentWeather = 0x200013f;
|
||||
const int opcodeChangeWeather = 0x2000140;
|
||||
const int opcodeModRegion = 0x20026;
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
|
@ -114,6 +137,7 @@ namespace MWScript
|
|||
extensions.registerFunction ("getmasserphase", 'l', "", opcodeGetMasserPhase);
|
||||
extensions.registerFunction ("getsecundaphase", 'l', "", opcodeGetSecundaPhase);
|
||||
extensions.registerFunction ("getcurrentweather", 'l', "", opcodeGetCurrentWeather);
|
||||
extensions.registerInstruction ("modregion", "S/llllllllll", opcodeModRegion);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -125,6 +149,7 @@ namespace MWScript
|
|||
interpreter.installSegment5 (opcodeGetSecundaPhase, new OpGetSecundaPhase);
|
||||
interpreter.installSegment5 (opcodeGetCurrentWeather, new OpGetCurrentWeather);
|
||||
interpreter.installSegment5 (opcodeChangeWeather, new OpChangeWeather);
|
||||
interpreter.installSegment3 (opcodeModRegion, new OpModRegion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -537,8 +537,8 @@ void WeatherManager::stopSounds(bool stopAll)
|
|||
std::vector<std::string>::iterator it = mSoundsPlaying.begin();
|
||||
while (it!=mSoundsPlaying.end())
|
||||
{
|
||||
if (stopAll || \
|
||||
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) || \
|
||||
if (stopAll ||
|
||||
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) ||
|
||||
(*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)))
|
||||
{
|
||||
MWBase::Environment::get().getSoundManager()->stopSound(*it);
|
||||
|
@ -551,29 +551,38 @@ void WeatherManager::stopSounds(bool stopAll)
|
|||
|
||||
Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const
|
||||
{
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
std::vector<char> probability;
|
||||
|
||||
RegionModMap::const_iterator iter = mRegionMods.find(Misc::StringUtils::lowerCase(region->mId));
|
||||
if(iter != mRegionMods.end())
|
||||
probability = iter->second;
|
||||
else
|
||||
{
|
||||
probability.reserve(10);
|
||||
probability.push_back(region->mData.mClear);
|
||||
probability.push_back(region->mData.mCloudy);
|
||||
probability.push_back(region->mData.mFoggy);
|
||||
probability.push_back(region->mData.mOvercast);
|
||||
probability.push_back(region->mData.mRain);
|
||||
probability.push_back(region->mData.mThunder);
|
||||
probability.push_back(region->mData.mAsh);
|
||||
probability.push_back(region->mData.mBlight);
|
||||
probability.push_back(region->mData.mA);
|
||||
probability.push_back(region->mData.mB);
|
||||
}
|
||||
|
||||
/*
|
||||
* All probabilities must add to 100 (responsibility of the user).
|
||||
* If chances A and B has values 30 and 70 then by generating
|
||||
* 100 numbers 1..100, 30% will be lesser or equal 30 and
|
||||
* 70% will be greater than 30 (in theory).
|
||||
*/
|
||||
const int probability[] = {
|
||||
region->mData.mClear,
|
||||
region->mData.mCloudy,
|
||||
region->mData.mFoggy,
|
||||
region->mData.mOvercast,
|
||||
region->mData.mRain,
|
||||
region->mData.mThunder,
|
||||
region->mData.mAsh,
|
||||
region->mData.mBlight,
|
||||
region->mData.mA,
|
||||
region->mData.mB
|
||||
}; // 10 elements
|
||||
|
||||
int chance = (rand() % 100) + 1; // 1..100
|
||||
int sum = 0;
|
||||
int i = 0;
|
||||
for (; i < 10; ++i)
|
||||
for (; i < probability.size(); ++i)
|
||||
{
|
||||
sum += probability[i];
|
||||
if (chance < sum)
|
||||
|
@ -681,6 +690,15 @@ void WeatherManager::changeWeather(const std::string& region, const unsigned int
|
|||
setWeather(weather);
|
||||
}
|
||||
|
||||
void WeatherManager::modRegion(const std::string ®ionid, const std::vector<char> &chances)
|
||||
{
|
||||
mRegionMods[Misc::StringUtils::lowerCase(regionid)] = chances;
|
||||
// Start transitioning right away if the region no longer supports the current weather type
|
||||
unsigned int current = getWeatherID();
|
||||
if(current >= chances.size() || chances[current] == 0)
|
||||
mWeatherUpdateTime = 0.0f;
|
||||
}
|
||||
|
||||
float WeatherManager::getWindSpeed() const
|
||||
{
|
||||
return mWindSpeed;
|
||||
|
|
|
@ -149,6 +149,8 @@ namespace MWWorld
|
|||
|
||||
unsigned int getWeatherID() const;
|
||||
|
||||
void modRegion(const std::string ®ionid, const std::vector<char> &chances);
|
||||
|
||||
private:
|
||||
float mHour;
|
||||
int mDay, mMonth;
|
||||
|
@ -188,6 +190,9 @@ namespace MWWorld
|
|||
Ogre::String nextWeather(const ESM::Region* region) const;
|
||||
WeatherResult mResult;
|
||||
|
||||
typedef std::map<std::string,std::vector<char> > RegionModMap;
|
||||
RegionModMap mRegionMods;
|
||||
|
||||
float mSunriseTime;
|
||||
float mSunsetTime;
|
||||
float mSunriseDuration;
|
||||
|
|
|
@ -1374,6 +1374,11 @@ namespace MWWorld
|
|||
mWeatherManager->changeWeather(region, id);
|
||||
}
|
||||
|
||||
void World::modRegion(const std::string ®ionid, const std::vector<char> &chances)
|
||||
{
|
||||
mWeatherManager->modRegion(regionid, chances);
|
||||
}
|
||||
|
||||
OEngine::Render::Fader* World::getFader()
|
||||
{
|
||||
return mRendering->getFader();
|
||||
|
|
|
@ -237,6 +237,8 @@ namespace MWWorld
|
|||
|
||||
virtual void setMoonColour (bool red);
|
||||
|
||||
virtual void modRegion(const std::string ®ionid, const std::vector<char> &chances);
|
||||
|
||||
virtual float getTimeScaleFactor() const;
|
||||
|
||||
virtual void changeToInteriorCell (const std::string& cellName,
|
||||
|
|
Loading…
Reference in a new issue