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 setMoonColour (bool red) = 0;
|
||||||
|
|
||||||
|
virtual void modRegion(const std::string ®ionid, const std::vector<char> &chances) = 0;
|
||||||
|
|
||||||
virtual float getTimeScaleFactor() const = 0;
|
virtual float getTimeScaleFactor() const = 0;
|
||||||
|
|
||||||
virtual void changeToInteriorCell (const std::string& cellName,
|
virtual void changeToInteriorCell (const std::string& cellName,
|
||||||
|
|
|
@ -51,7 +51,8 @@ op 0x20022: AiFollow
|
||||||
op 0x20023: AiFollow, explicit reference
|
op 0x20023: AiFollow, explicit reference
|
||||||
op 0x20024: AiFollowCell
|
op 0x20024: AiFollowCell
|
||||||
op 0x20025: AiFollowCell, explicit reference
|
op 0x20025: AiFollowCell, explicit reference
|
||||||
op s 0x20026-0x3ffff unused
|
op 0x20026: ModRegion
|
||||||
|
opcodes 0x20027-0x3ffff unused
|
||||||
|
|
||||||
Segment 4:
|
Segment 4:
|
||||||
(not implemented yet)
|
(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 opcodeToggleSky = 0x2000021;
|
||||||
const int opcodeTurnMoonWhite = 0x2000022;
|
const int opcodeTurnMoonWhite = 0x2000022;
|
||||||
const int opcodeTurnMoonRed = 0x2000023;
|
const int opcodeTurnMoonRed = 0x2000023;
|
||||||
|
@ -103,6 +125,7 @@ namespace MWScript
|
||||||
const int opcodeGetSecundaPhase = 0x2000025;
|
const int opcodeGetSecundaPhase = 0x2000025;
|
||||||
const int opcodeGetCurrentWeather = 0x200013f;
|
const int opcodeGetCurrentWeather = 0x200013f;
|
||||||
const int opcodeChangeWeather = 0x2000140;
|
const int opcodeChangeWeather = 0x2000140;
|
||||||
|
const int opcodeModRegion = 0x20026;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +137,7 @@ namespace MWScript
|
||||||
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);
|
||||||
|
extensions.registerInstruction ("modregion", "S/llllllllll", opcodeModRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -125,6 +149,7 @@ namespace MWScript
|
||||||
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);
|
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();
|
std::vector<std::string>::iterator it = mSoundsPlaying.begin();
|
||||||
while (it!=mSoundsPlaying.end())
|
while (it!=mSoundsPlaying.end())
|
||||||
{
|
{
|
||||||
if (stopAll || \
|
if (stopAll ||
|
||||||
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) || \
|
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) ||
|
||||||
(*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)))
|
(*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)))
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getSoundManager()->stopSound(*it);
|
MWBase::Environment::get().getSoundManager()->stopSound(*it);
|
||||||
|
@ -551,29 +551,38 @@ void WeatherManager::stopSounds(bool stopAll)
|
||||||
|
|
||||||
Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const
|
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).
|
* All probabilities must add to 100 (responsibility of the user).
|
||||||
* If chances A and B has values 30 and 70 then by generating
|
* 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
|
* 100 numbers 1..100, 30% will be lesser or equal 30 and
|
||||||
* 70% will be greater than 30 (in theory).
|
* 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 chance = (rand() % 100) + 1; // 1..100
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < 10; ++i)
|
for (; i < probability.size(); ++i)
|
||||||
{
|
{
|
||||||
sum += probability[i];
|
sum += probability[i];
|
||||||
if (chance < sum)
|
if (chance < sum)
|
||||||
|
@ -681,6 +690,15 @@ void WeatherManager::changeWeather(const std::string& region, const unsigned int
|
||||||
setWeather(weather);
|
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
|
float WeatherManager::getWindSpeed() const
|
||||||
{
|
{
|
||||||
return mWindSpeed;
|
return mWindSpeed;
|
||||||
|
|
|
@ -149,6 +149,8 @@ namespace MWWorld
|
||||||
|
|
||||||
unsigned int getWeatherID() const;
|
unsigned int getWeatherID() const;
|
||||||
|
|
||||||
|
void modRegion(const std::string ®ionid, const std::vector<char> &chances);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float mHour;
|
float mHour;
|
||||||
int mDay, mMonth;
|
int mDay, mMonth;
|
||||||
|
@ -188,6 +190,9 @@ namespace MWWorld
|
||||||
Ogre::String nextWeather(const ESM::Region* region) const;
|
Ogre::String nextWeather(const ESM::Region* region) const;
|
||||||
WeatherResult mResult;
|
WeatherResult mResult;
|
||||||
|
|
||||||
|
typedef std::map<std::string,std::vector<char> > RegionModMap;
|
||||||
|
RegionModMap mRegionMods;
|
||||||
|
|
||||||
float mSunriseTime;
|
float mSunriseTime;
|
||||||
float mSunsetTime;
|
float mSunsetTime;
|
||||||
float mSunriseDuration;
|
float mSunriseDuration;
|
||||||
|
|
|
@ -1374,6 +1374,11 @@ namespace MWWorld
|
||||||
mWeatherManager->changeWeather(region, id);
|
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()
|
OEngine::Render::Fader* World::getFader()
|
||||||
{
|
{
|
||||||
return mRendering->getFader();
|
return mRendering->getFader();
|
||||||
|
|
|
@ -237,6 +237,8 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void setMoonColour (bool red);
|
virtual void setMoonColour (bool red);
|
||||||
|
|
||||||
|
virtual void modRegion(const std::string ®ionid, const std::vector<char> &chances);
|
||||||
|
|
||||||
virtual float getTimeScaleFactor() const;
|
virtual float getTimeScaleFactor() const;
|
||||||
|
|
||||||
virtual void changeToInteriorCell (const std::string& cellName,
|
virtual void changeToInteriorCell (const std::string& cellName,
|
||||||
|
|
Loading…
Reference in a new issue