mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 02:56:44 +00:00 
			
		
		
		
	Fixes #417: Apply weather instantly when teleporting
Changed teleporting detection from "position tracking" to manually setting "teleportation" flag ( player->setTeleported(true) ). Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
This commit is contained in:
		
							parent
							
								
									c65f018760
								
							
						
					
					
						commit
						e9844e1b37
					
				
					 8 changed files with 92 additions and 91 deletions
				
			
		|  | @ -7,6 +7,7 @@ | |||
| 
 | ||||
| 
 | ||||
| #include "../mwworld/containerstore.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| 
 | ||||
| #include "../mwrender/animation.hpp" | ||||
| 
 | ||||
|  | @ -240,11 +241,15 @@ namespace MWMechanics | |||
| 
 | ||||
|             else if (effectId == ESM::MagicEffect::DivineIntervention) | ||||
|             { | ||||
|                 MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); | ||||
| 
 | ||||
|                 // We need to be able to get the world location of an interior cell before implementing this
 | ||||
|                 // or alternatively, the last known exterior location of the player, which is how vanilla does it.
 | ||||
|             } | ||||
|             else if (effectId == ESM::MagicEffect::AlmsiviIntervention) | ||||
|             { | ||||
|                 MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); | ||||
| 
 | ||||
|                 // Same as above
 | ||||
|             } | ||||
| 
 | ||||
|  | @ -254,6 +259,8 @@ namespace MWMechanics | |||
|             } | ||||
|             else if (effectId == ESM::MagicEffect::Recall) | ||||
|             { | ||||
|                 MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); | ||||
| 
 | ||||
|                 // TODO
 | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -43,10 +43,13 @@ namespace MWScript | |||
|                     ESM::Position pos; | ||||
|                     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||
| 
 | ||||
|                     if (world->findExteriorPosition(cell, pos)) { | ||||
|                     world->getPlayer().setTeleported(true); | ||||
|                     if (world->findExteriorPosition(cell, pos)) | ||||
|                     { | ||||
|                         world->changeToExteriorCell(pos); | ||||
|                     } | ||||
|                     else { | ||||
|                     else | ||||
|                     { | ||||
|                         // Change to interior even if findInteriorPosition()
 | ||||
|                         // yields false. In this case position will be zero-point.
 | ||||
|                         world->findInteriorPosition(cell, pos); | ||||
|  | @ -68,13 +71,14 @@ namespace MWScript | |||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     ESM::Position pos; | ||||
| 
 | ||||
|                     MWBase::Environment::get().getWorld()->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); | ||||
|                     MWBase::World *world = MWBase::Environment::get().getWorld(); | ||||
|                     world->getPlayer().setTeleported(true); | ||||
|                     world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); | ||||
|                     pos.pos[2] = 0; | ||||
| 
 | ||||
|                     pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; | ||||
| 
 | ||||
|                     MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); | ||||
|                     world->changeToExteriorCell (pos); | ||||
|                 } | ||||
|         }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -207,6 +207,10 @@ namespace MWScript | |||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWWorld::Ptr ptr = R()(runtime); | ||||
|                     if (ptr.getRefData().getHandle() == "player") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); | ||||
|                     } | ||||
| 
 | ||||
|                     std::string axis = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|  | @ -271,6 +275,10 @@ namespace MWScript | |||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWWorld::Ptr ptr = R()(runtime); | ||||
|                     if (ptr.getRefData().getHandle() == "player") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); | ||||
|                     } | ||||
| 
 | ||||
|                     Interpreter::Type_Float x = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
|  | @ -328,6 +336,10 @@ namespace MWScript | |||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWWorld::Ptr ptr = R()(runtime); | ||||
|                     if (ptr.getRefData().getHandle() == "player") | ||||
|                     { | ||||
|                         MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); | ||||
|                     } | ||||
| 
 | ||||
|                     Interpreter::Type_Float x = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| #include "player.hpp" | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|  | @ -14,9 +15,12 @@ namespace MWWorld | |||
| 
 | ||||
|     void ActionTeleport::executeImp (const Ptr& actor) | ||||
|     { | ||||
|         MWBase::World* world = MWBase::Environment::get().getWorld(); | ||||
|         world->getPlayer().setTeleported(true); | ||||
| 
 | ||||
|         if (mCellName.empty()) | ||||
|             MWBase::Environment::get().getWorld()->changeToExteriorCell (mPosition); | ||||
|             world->changeToExteriorCell (mPosition); | ||||
|         else | ||||
|             MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, mPosition); | ||||
|             world->changeToInteriorCell (mCellName, mPosition); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -19,7 +19,8 @@ namespace MWWorld | |||
|     Player::Player (const ESM::NPC *player, const MWBase::World& world) | ||||
|       : mCellStore(0), | ||||
|         mAutoMove(false), | ||||
|         mForwardBackward (0) | ||||
|         mForwardBackward (0), | ||||
|         mTeleported(false) | ||||
|     { | ||||
|         mPlayer.mBase = player; | ||||
|         mPlayer.mRef.mRefID = "player"; | ||||
|  | @ -145,4 +146,14 @@ namespace MWWorld | |||
|          MWWorld::Ptr ptr = getPlayer(); | ||||
|          return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState(); | ||||
|     } | ||||
| 
 | ||||
|     bool Player::wasTeleported() const | ||||
|     { | ||||
|         return mTeleported; | ||||
|     } | ||||
| 
 | ||||
|     void Player::setTeleported(bool teleported) | ||||
|     { | ||||
|         mTeleported = teleported; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ namespace MWWorld | |||
| 
 | ||||
|         bool                    mAutoMove; | ||||
|         int                     mForwardBackward; | ||||
| 
 | ||||
|         bool                    mTeleported; | ||||
|     public: | ||||
| 
 | ||||
|         Player(const ESM::NPC *player, const MWBase::World& world); | ||||
|  | @ -64,6 +64,9 @@ namespace MWWorld | |||
|         void yaw(float yaw); | ||||
|         void pitch(float pitch); | ||||
|         void roll(float roll); | ||||
| 
 | ||||
|         bool wasTeleported() const; | ||||
|         void setTeleported(bool teleported); | ||||
|     }; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -324,42 +324,7 @@ void WeatherManager::update(float duration) | |||
| 
 | ||||
|     mWeatherUpdateTime -= timePassed; | ||||
| 
 | ||||
|     const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); | ||||
|     if (!exterior) | ||||
|     { | ||||
|         mRendering->sunDisable(false); | ||||
|         mRendering->skyDisable(); | ||||
|         mRendering->getSkyManager()->setLightningStrength(0.f); | ||||
|         stopSounds(true); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Exterior
 | ||||
|     std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); | ||||
| 
 | ||||
|     if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) | ||||
|     { | ||||
|         mCurrentRegion = regionstr; | ||||
|         mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; | ||||
| 
 | ||||
|         std::string weatherType = "clear"; | ||||
| 
 | ||||
|         if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) | ||||
|             weatherType = mRegionOverrides[regionstr]; | ||||
|         else | ||||
|         { | ||||
|             // get weather probabilities for the current region
 | ||||
|             const ESM::Region *region = | ||||
|                     MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr); | ||||
| 
 | ||||
|             if (region != 0) | ||||
|             { | ||||
|                 weatherType = nextWeather(region); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         setWeather(weatherType, false); | ||||
|     } | ||||
|     switchToNextWeather(false); | ||||
| 
 | ||||
|     if (mNextWeather != "") | ||||
|     { | ||||
|  | @ -710,42 +675,42 @@ float WeatherManager::getWindSpeed() const | |||
| 
 | ||||
| void WeatherManager::switchToNextWeather(bool instantly) | ||||
| { | ||||
|   const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); | ||||
|   if (!exterior) | ||||
|   { | ||||
|       mRendering->sunDisable(false); | ||||
|       mRendering->skyDisable(); | ||||
|       mRendering->getSkyManager()->setLightningStrength(0.f); | ||||
|       stopSounds(true); | ||||
|       return; | ||||
|   } | ||||
|     MWBase::World* world = MWBase::Environment::get().getWorld(); | ||||
|     const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior()); | ||||
|     if (!exterior) | ||||
|     { | ||||
|         mRendering->sunDisable(false); | ||||
|         mRendering->skyDisable(); | ||||
|         mRendering->getSkyManager()->setLightningStrength(0.f); | ||||
|         stopSounds(true); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|   // Exterior
 | ||||
|   std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); | ||||
|     // Exterior
 | ||||
|     std::string regionstr = Misc::StringUtils::lowerCase(world->getPlayer().getPlayer().getCell()->mCell->mRegion); | ||||
| 
 | ||||
|   if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) | ||||
|   { | ||||
|       mCurrentRegion = regionstr; | ||||
|       mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; | ||||
|     if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) | ||||
|     { | ||||
|         mCurrentRegion = regionstr; | ||||
|         mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; | ||||
| 
 | ||||
|       std::string weatherType = "clear"; | ||||
|         std::string weatherType = "clear"; | ||||
| 
 | ||||
|       if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) | ||||
|       { | ||||
|           weatherType = mRegionOverrides[regionstr]; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|           // get weather probabilities for the current region
 | ||||
|           const ESM::Region *region = | ||||
|                   MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr); | ||||
|         if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) | ||||
|         { | ||||
|             weatherType = mRegionOverrides[regionstr]; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // get weather probabilities for the current region
 | ||||
|             const ESM::Region *region = world->getStore().get<ESM::Region>().search (regionstr); | ||||
| 
 | ||||
|           if (region != 0) | ||||
|           { | ||||
|               weatherType = nextWeather(region); | ||||
|           } | ||||
|       } | ||||
|             if (region != 0) | ||||
|             { | ||||
|                 weatherType = nextWeather(region); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|       setWeather(weatherType, instantly); | ||||
|   } | ||||
|         setWeather(weatherType, instantly); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2247,19 +2247,14 @@ namespace MWWorld | |||
| 
 | ||||
|     void World::updateWeather(float duration) | ||||
|     { | ||||
|       static const float teleportationStepTreshold = 256.f; | ||||
|       static ESM::Position lastPlayerPos; | ||||
|       ESM::Position currentPos = mPlayer->getPlayer().getRefData().getPosition(); | ||||
| 
 | ||||
|       if (fabs(fabs(lastPlayerPos.pos[0]) - fabs(currentPos.pos[0])) >= teleportationStepTreshold | ||||
|           || fabs(fabs(lastPlayerPos.pos[1]) - fabs(currentPos.pos[1])) >= teleportationStepTreshold) | ||||
|       { | ||||
|         lastPlayerPos = currentPos; | ||||
|         mWeatherManager->switchToNextWeather(true); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         mWeatherManager->update (duration); | ||||
|       } | ||||
|         if (mPlayer->wasTeleported()) | ||||
|         { | ||||
|             mPlayer->setTeleported(false); | ||||
|             mWeatherManager->switchToNextWeather(true); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             mWeatherManager->update (duration); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue