mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 10:26:46 +00:00 
			
		
		
		
	Merge branch 'master' into characterpreview
This commit is contained in:
		
						commit
						d90af9c524
					
				
					 26 changed files with 591 additions and 284 deletions
				
			
		|  | @ -51,7 +51,7 @@ add_openmw_dir (mwworld | |||
|     refdata worldimp physicssystem scene globals class action nullaction actionteleport | ||||
|     containerstore actiontalk actiontake manualref player cellfunctors | ||||
|     cells localscripts customdata weather inventorystore ptr actionopen actionread | ||||
|     actionequip timestamp actionalchemy cellstore actionapply | ||||
|     actionequip timestamp actionalchemy cellstore actionapply actioneat | ||||
|     ) | ||||
| 
 | ||||
| add_openmw_dir (mwclass | ||||
|  |  | |||
|  | @ -162,6 +162,10 @@ void OMW::Engine::loadBSA() | |||
|         dataDirectory = iter->string(); | ||||
|         std::cout << "Data dir " << dataDirectory << std::endl; | ||||
|         Bsa::addDir(dataDirectory, mFSStrict); | ||||
| 
 | ||||
|         // Workaround: Mygui does not find textures in non-BSA subfolders, _unless_ they are explicitely added like this
 | ||||
|         // For splash screens, this is OK to do, but eventually we will need an investigation why this is necessary
 | ||||
|         Bsa::addDir(dataDirectory + "/Splash", mFSStrict); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -218,6 +218,7 @@ namespace MWBase | |||
|             virtual void executeInConsole (const std::string& path) = 0; | ||||
| 
 | ||||
|             virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total) = 0; | ||||
|             virtual void loadingDone() = 0; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
| #include "../mwworld/actiontake.hpp" | ||||
| #include "../mwworld/cellstore.hpp" | ||||
| #include "../mwworld/physicssystem.hpp" | ||||
| #include "../mwworld/actioneat.hpp" | ||||
| 
 | ||||
| #include "../mwgui/tooltips.hpp" | ||||
| 
 | ||||
|  | @ -19,6 +20,14 @@ | |||
| 
 | ||||
| namespace MWClass | ||||
| { | ||||
|     std::string Ingredient::getId (const MWWorld::Ptr& ptr) const | ||||
|     { | ||||
|         MWWorld::LiveCellRef<ESM::Ingredient> *ref = | ||||
|             ptr.get<ESM::Ingredient>(); | ||||
| 
 | ||||
|         return ref->base->mId; | ||||
|     } | ||||
|      | ||||
|     void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const | ||||
|     { | ||||
|         const std::string model = getModel(ptr); | ||||
|  | @ -84,6 +93,16 @@ namespace MWClass | |||
|         return ref->base->data.value; | ||||
|     } | ||||
| 
 | ||||
|     | ||||
|     boost::shared_ptr<MWWorld::Action> Ingredient::use (const MWWorld::Ptr& ptr) const | ||||
|     { | ||||
|         boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionEat (ptr)); | ||||
| 
 | ||||
|         action->setSound ("Swallow"); | ||||
| 
 | ||||
|         return action;     | ||||
|     } | ||||
|      | ||||
|     void Ingredient::registerSelf() | ||||
|     { | ||||
|         boost::shared_ptr<Class> instance (new Ingredient); | ||||
|  |  | |||
|  | @ -12,6 +12,9 @@ namespace MWClass | |||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             virtual std::string getId (const MWWorld::Ptr& ptr) const; | ||||
|             ///< Return ID of \a ptr
 | ||||
| 
 | ||||
|             virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const; | ||||
|             ///< Add reference into a cell for rendering
 | ||||
| 
 | ||||
|  | @ -37,6 +40,10 @@ namespace MWClass | |||
|             virtual int getValue (const MWWorld::Ptr& ptr) const; | ||||
|             ///< Return trade value of the object. Throws an exception, if the object can't be traded.
 | ||||
| 
 | ||||
|             virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) | ||||
|                 const; | ||||
|             ///< Generate action for using via inventory menu
 | ||||
|              | ||||
|             static void registerSelf(); | ||||
| 
 | ||||
|             virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const; | ||||
|  |  | |||
|  | @ -365,7 +365,7 @@ namespace MWClass | |||
| 
 | ||||
|         /// \todo consider instant effects
 | ||||
| 
 | ||||
|         return stats.getActiveSpells().addSpell (id); | ||||
|         return stats.getActiveSpells().addSpell (id, actor); | ||||
|     } | ||||
| 
 | ||||
|     void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const | ||||
|  |  | |||
|  | @ -11,6 +11,8 @@ | |||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/inputmanager.hpp" | ||||
| 
 | ||||
| #include "../mwbase/windowmanager.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
| 
 | ||||
|  | @ -20,6 +22,8 @@ namespace MWGui | |||
|         , WindowBase("openmw_loading_screen.layout", parWindowManager) | ||||
|         , mLoadingOn(false) | ||||
|         , mLastRenderTime(0.f) | ||||
|         , mLastWallpaperChangeTime(0.f) | ||||
|         , mFirstLoad(true) | ||||
|     { | ||||
|         getWidget(mLoadingText, "LoadingText"); | ||||
|         getWidget(mProgressBar, "ProgressBar"); | ||||
|  | @ -77,11 +81,7 @@ namespace MWGui | |||
|             mTotalRefsLoading = total; | ||||
|         } | ||||
| 
 | ||||
|         if (mTotalCellsLoading == 0) | ||||
|         { | ||||
|             loadingOff(); | ||||
|             return; | ||||
|         } | ||||
|         assert (mTotalCellsLoading != 0); | ||||
| 
 | ||||
|         float refProgress; | ||||
|         if (mTotalRefsLoading <= 1) | ||||
|  | @ -98,11 +98,6 @@ namespace MWGui | |||
| 
 | ||||
|         float progress = (float(mCurrentCellLoading)+refProgress) / float(mTotalCellsLoading); | ||||
|         assert(progress <= 1 && progress >= 0); | ||||
|         if (progress >= 1) | ||||
|         { | ||||
|             loadingOff(); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         mLoadingText->setCaption(stage + "... "); | ||||
|         mProgressBar->setProgressPosition (static_cast<size_t>(progress * 1000)); | ||||
|  | @ -113,6 +108,11 @@ namespace MWGui | |||
|         { | ||||
|             mLastRenderTime = mTimer.getMilliseconds (); | ||||
| 
 | ||||
|             if (mFirstLoad && mTimer.getMilliseconds () > mLastWallpaperChangeTime + 3000*1) | ||||
|             { | ||||
|                 mLastWallpaperChangeTime = mTimer.getMilliseconds (); | ||||
|                 changeWallpaper(); | ||||
|             } | ||||
| 
 | ||||
|             // Turn off rendering except the GUI
 | ||||
|             mSceneMgr->clearSpecialCaseRenderQueues(); | ||||
|  | @ -139,8 +139,11 @@ namespace MWGui | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName()); | ||||
|                 mRectangle->setVisible(true); | ||||
|                 if (!mFirstLoad) | ||||
|                 { | ||||
|                     mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName()); | ||||
|                     mRectangle->setVisible(true); | ||||
|                 } | ||||
| 
 | ||||
|                 for (unsigned int i = 0; i<chain->getNumCompositors(); ++i) | ||||
|                 { | ||||
|  | @ -158,19 +161,37 @@ namespace MWGui | |||
|                 { | ||||
|                     Ogre::CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), chain->getCompositor(i)->getCompositor()->getName(), true); | ||||
|                 } | ||||
|                 mRectangle->setVisible(false); | ||||
|             } | ||||
| 
 | ||||
|             mRectangle->setVisible(false); | ||||
| 
 | ||||
|             // resume 3d rendering
 | ||||
|             mSceneMgr->clearSpecialCaseRenderQueues(); | ||||
|             mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void LoadingScreen::loadingDone() | ||||
|     { | ||||
|         loadingOff(); | ||||
|     } | ||||
| 
 | ||||
|     void LoadingScreen::loadingOn() | ||||
|     { | ||||
|         setVisible(true); | ||||
|         mLoadingOn = true; | ||||
| 
 | ||||
|         if (mFirstLoad) | ||||
|         { | ||||
|             changeWallpaper(); | ||||
| 
 | ||||
|             mWindowManager.pushGuiMode(GM_LoadingWallpaper); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             mBackgroundImage->setImageTexture(""); | ||||
|             mWindowManager.pushGuiMode(GM_Loading); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -178,5 +199,28 @@ namespace MWGui | |||
|     { | ||||
|         setVisible(false); | ||||
|         mLoadingOn = false; | ||||
|         mFirstLoad = false; | ||||
| 
 | ||||
|         mWindowManager.removeGuiMode(GM_Loading); | ||||
|         mWindowManager.removeGuiMode(GM_LoadingWallpaper); | ||||
|     } | ||||
| 
 | ||||
|     void LoadingScreen::changeWallpaper () | ||||
|     { | ||||
|         /// \todo use a directory listing here
 | ||||
|         std::vector<std::string> splash; | ||||
|         splash.push_back ("Splash_Bonelord.tga"); | ||||
|         splash.push_back ("Splash_ClannDaddy.tga"); | ||||
|         splash.push_back ("Splash_Clannfear.tga"); | ||||
|         splash.push_back ("Splash_Daedroth.tga"); | ||||
|         splash.push_back ("Splash_Hunger.tga"); | ||||
|         splash.push_back ("Splash_KwamaWarrior.tga"); | ||||
|         splash.push_back ("Splash_Netch.tga"); | ||||
|         splash.push_back ("Splash_NixHound.tga"); | ||||
|         splash.push_back ("Splash_Siltstriker.tga"); | ||||
|         splash.push_back ("Splash_Skeleton.tga"); | ||||
|         splash.push_back ("Splash_SphereCenturion.tga"); | ||||
| 
 | ||||
|         mBackgroundImage->setImageTexture (splash[rand() % splash.size()]); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -15,13 +15,17 @@ namespace MWGui | |||
|         virtual ~LoadingScreen(); | ||||
| 
 | ||||
|         void setLoadingProgress (const std::string& stage, int depth, int current, int total); | ||||
|         void loadingDone(); | ||||
| 
 | ||||
|         void onResChange(int w, int h); | ||||
| 
 | ||||
|     private: | ||||
|         bool mFirstLoad; | ||||
| 
 | ||||
|         Ogre::SceneManager* mSceneMgr; | ||||
|         Ogre::RenderWindow* mWindow; | ||||
| 
 | ||||
|         unsigned long mLastWallpaperChangeTime; | ||||
|         unsigned long mLastRenderTime; | ||||
|         Ogre::Timer mTimer; | ||||
| 
 | ||||
|  | @ -43,6 +47,8 @@ namespace MWGui | |||
| 
 | ||||
|         void loadingOn(); | ||||
|         void loadingOff(); | ||||
| 
 | ||||
|         void changeWallpaper(); | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -35,6 +35,9 @@ namespace MWGui | |||
|       // interactive MessageBox
 | ||||
|       GM_InterMessageBox, | ||||
| 
 | ||||
|       GM_Loading, | ||||
|       GM_LoadingWallpaper, | ||||
| 
 | ||||
|       GM_QuickKeysMenu | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -248,6 +248,8 @@ void WindowManager::updateVisible() | |||
|     mSpellWindow->setVisible(false); | ||||
|     mQuickKeysMenu->setVisible(false); | ||||
| 
 | ||||
|     mHud->setVisible(true); | ||||
| 
 | ||||
|     // Mouse is visible whenever we're not in game mode
 | ||||
|     MyGUI::PointerManager::getInstance().setVisible(isGuiMode()); | ||||
| 
 | ||||
|  | @ -340,6 +342,13 @@ void WindowManager::updateVisible() | |||
|         case GM_Journal: | ||||
|             mJournal->setVisible(true); | ||||
|             break; | ||||
|         case GM_LoadingWallpaper: | ||||
|             mHud->setVisible(false); | ||||
|             MyGUI::PointerManager::getInstance().setVisible(false); | ||||
|             break; | ||||
|         case GM_Loading: | ||||
|             MyGUI::PointerManager::getInstance().setVisible(false); | ||||
|             break; | ||||
|         default: | ||||
|             // Unsupported mode, switch back to game
 | ||||
|             break; | ||||
|  | @ -909,3 +918,8 @@ void WindowManager::setLoadingProgress (const std::string& stage, int depth, int | |||
| { | ||||
|     mLoadingScreen->setLoadingProgress (stage, depth, current, total); | ||||
| } | ||||
| 
 | ||||
| void WindowManager::loadingDone () | ||||
| { | ||||
|     mLoadingScreen->loadingDone (); | ||||
| } | ||||
|  |  | |||
|  | @ -197,6 +197,7 @@ namespace MWGui | |||
|     virtual void executeInConsole (const std::string& path); | ||||
| 
 | ||||
|     virtual void setLoadingProgress (const std::string& stage, int depth, int current, int total); | ||||
|     virtual void loadingDone(); | ||||
| 
 | ||||
|   private: | ||||
|     OEngine::GUI::MyGUIManager *mGuiManager; | ||||
|  |  | |||
|  | @ -5,12 +5,20 @@ | |||
| 
 | ||||
| #include <components/esm/loadalch.hpp> | ||||
| #include <components/esm/loadspel.hpp> | ||||
| #include <components/esm/loadingr.hpp> | ||||
| #include <components/esm/loadmgef.hpp> | ||||
| #include <components/esm/loadskil.hpp> | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| 
 | ||||
| #include "../mwworld/class.hpp" | ||||
| 
 | ||||
| #include "creaturestats.hpp" | ||||
| #include "npcstats.hpp" | ||||
| 
 | ||||
| namespace MWMechanics | ||||
| { | ||||
|     void ActiveSpells::update() const | ||||
|  | @ -41,47 +49,102 @@ namespace MWMechanics | |||
|         } | ||||
| 
 | ||||
|         if (rebuild) | ||||
|             rebuildEffects(); | ||||
|     } | ||||
| 
 | ||||
|     void ActiveSpells::rebuildEffects() const | ||||
|     { | ||||
|         MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp(); | ||||
|      | ||||
|         mEffects = MagicEffects(); | ||||
| 
 | ||||
|         for (TIterator iter (begin()); iter!=end(); ++iter) | ||||
|         { | ||||
|             mEffects = MagicEffects(); | ||||
|             std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first); | ||||
| 
 | ||||
|             for (TIterator iter (begin()); iter!=end(); ++iter) | ||||
|             const MWWorld::TimeStamp& start = iter->second.first; | ||||
|             float magnitude = iter->second.second; | ||||
| 
 | ||||
|             for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin()); | ||||
|                 iter!=effects.first.list.end(); ++iter) | ||||
|             { | ||||
|                 const ESM::EffectList& effects = getEffectList (iter->first); | ||||
| 
 | ||||
|                 const MWWorld::TimeStamp& start = iter->second.first; | ||||
|                 float magnitude = iter->second.second; | ||||
| 
 | ||||
|                 for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin()); | ||||
|                     iter!=effects.list.end(); ++iter) | ||||
|                 if (iter->duration) | ||||
|                 { | ||||
|                     if (iter->duration) | ||||
|                     { | ||||
|                         MWWorld::TimeStamp end = start; | ||||
|                         end += static_cast<double> (iter->duration)* | ||||
|                             MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60); | ||||
|                     int duration = iter->duration; | ||||
|                      | ||||
|                     if (effects.second) | ||||
|                         duration *= magnitude; | ||||
|                      | ||||
|                     MWWorld::TimeStamp end = start; | ||||
|                     end += static_cast<double> (duration)* | ||||
|                         MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60); | ||||
| 
 | ||||
|                         if (end>now) | ||||
|                     if (end>now) | ||||
|                     { | ||||
|                         EffectParam param; | ||||
|                          | ||||
|                         if (effects.second) | ||||
|                         { | ||||
|                             EffectParam param; | ||||
|                             param.mMagnitude = static_cast<int> ( | ||||
|                                 (iter->magnMax-iter->magnMin+1)*magnitude + iter->magnMin); | ||||
|                             mEffects.add (*iter, param); | ||||
|                             const ESM::MagicEffect *magicEffect = | ||||
|                                 MWBase::Environment::get().getWorld()->getStore().magicEffects.find ( | ||||
|                                 iter->effectID);                             | ||||
|                                  | ||||
|                             if (iter->duration==0) | ||||
|                             { | ||||
|                                 param.mMagnitude = | ||||
|                                     static_cast<int> (magnitude / (0.1 * magicEffect->data.baseCost)); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 param.mMagnitude = | ||||
|                                     static_cast<int> (0.05*magnitude / (0.1 * magicEffect->data.baseCost)); | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                             param.mMagnitude = static_cast<int> ( | ||||
|                                 (iter->magnMax-iter->magnMin)*magnitude + iter->magnMin); | ||||
|                                  | ||||
|                         mEffects.add (*iter, param); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         }     | ||||
|     } | ||||
| 
 | ||||
|     const ESM::EffectList& ActiveSpells::getEffectList (const std::string& id) const | ||||
|     std::pair<ESM::EffectList, bool> ActiveSpells::getEffectList (const std::string& id) const | ||||
|     { | ||||
|         if (const ESM::Spell *spell = | ||||
|             MWBase::Environment::get().getWorld()->getStore().spells.search (id)) | ||||
|             return spell->effects; | ||||
|             return std::make_pair (spell->effects, false); | ||||
| 
 | ||||
|         if (const ESM::Potion *potion = | ||||
|             MWBase::Environment::get().getWorld()->getStore().potions.search (id)) | ||||
|             return potion->effects; | ||||
|             return std::make_pair (potion->effects, false); | ||||
| 
 | ||||
|         if (const ESM::Ingredient *ingredient = | ||||
|             MWBase::Environment::get().getWorld()->getStore().ingreds.search (id)) | ||||
|         { | ||||
|             const ESM::MagicEffect *magicEffect = | ||||
|                 MWBase::Environment::get().getWorld()->getStore().magicEffects.find ( | ||||
|                 ingredient->data.effectID[0]); | ||||
|          | ||||
|             ESM::ENAMstruct effect; | ||||
|             effect.effectID = ingredient->data.effectID[0]; | ||||
|             effect.skill = ingredient->data.skills[0]; | ||||
|             effect.attribute = ingredient->data.attributes[0]; | ||||
|             effect.range = 0; | ||||
|             effect.area = 0; | ||||
|             effect.duration = magicEffect->data.flags & ESM::MagicEffect::NoDuration ? 0 : 1; | ||||
|             effect.magnMin = 1; | ||||
|             effect.magnMax = 1; | ||||
|              | ||||
|             std::pair<ESM::EffectList, bool> result; | ||||
|              | ||||
|             result.first.list.push_back (effect); | ||||
|             result.second = true; | ||||
|              | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         throw std::runtime_error ("ID " + id + " can not produce lasting effects"); | ||||
|     } | ||||
|  | @ -90,14 +153,14 @@ namespace MWMechanics | |||
|     : mSpellsChanged (false), mLastUpdate (MWBase::Environment::get().getWorld()->getTimeStamp()) | ||||
|     {} | ||||
| 
 | ||||
|     bool ActiveSpells::addSpell (const std::string& id) | ||||
|     bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor) | ||||
|     { | ||||
|         const ESM::EffectList& effects = getEffectList (id); | ||||
|         std::pair<ESM::EffectList, bool> effects = getEffectList (id); | ||||
| 
 | ||||
|         bool found = false; | ||||
| 
 | ||||
|         for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin()); | ||||
|             iter!=effects.list.end(); ++iter) | ||||
|         for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin()); | ||||
|             iter!=effects.first.list.end(); ++iter) | ||||
|         { | ||||
|             if (iter->duration) | ||||
|             { | ||||
|  | @ -113,6 +176,22 @@ namespace MWMechanics | |||
| 
 | ||||
|         float random = static_cast<float> (std::rand()) / RAND_MAX; | ||||
| 
 | ||||
|         if (effects.second) | ||||
|         { | ||||
|             // ingredient -> special treatment required.
 | ||||
|             const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor); | ||||
|             const NpcStats& npcStats = MWWorld::Class::get (actor).getNpcStats (actor); | ||||
|          | ||||
|             float x = | ||||
|                 (npcStats.getSkill (ESM::Skill::Alchemy).getModified() + | ||||
|                 0.2 * creatureStats.getAttribute (1).getModified() | ||||
|                 + 0.1 * creatureStats.getAttribute (7).getModified()) | ||||
|                 * creatureStats.getFatigueTerm(); | ||||
|             random *= 100; | ||||
|             random = random / std::min (x, 100.0f); | ||||
|             random *= 0.25 * x; | ||||
|         } | ||||
| 
 | ||||
|         if (iter==mSpells.end()) | ||||
|             mSpells.insert (std::make_pair (id, | ||||
|                 std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random))); | ||||
|  | @ -155,17 +234,20 @@ namespace MWMechanics | |||
| 
 | ||||
|     double ActiveSpells::timeToExpire (const TIterator& iterator) const | ||||
|     { | ||||
|         const ESM::EffectList& effects = getEffectList (iterator->first); | ||||
|         std::pair<ESM::EffectList, bool> effects = getEffectList (iterator->first); | ||||
| 
 | ||||
|         int duration = 0; | ||||
| 
 | ||||
|         for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin()); | ||||
|             iter!=effects.list.end(); ++iter) | ||||
|         for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin()); | ||||
|             iter!=effects.first.list.end(); ++iter) | ||||
|         { | ||||
|             if (iter->duration>duration) | ||||
|                 duration = iter->duration; | ||||
|         } | ||||
| 
 | ||||
|         if (effects.second) | ||||
|             duration *= iterator->second.second; | ||||
| 
 | ||||
|         double scaledDuration = duration * | ||||
|               MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60); | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,11 @@ namespace ESM | |||
|     struct EffectList; | ||||
| } | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|     class Ptr; | ||||
| } | ||||
| 
 | ||||
| namespace MWMechanics | ||||
| { | ||||
|     /// \brief Lasting spell effects
 | ||||
|  | @ -36,14 +41,16 @@ namespace MWMechanics | |||
|             mutable MWWorld::TimeStamp mLastUpdate; | ||||
| 
 | ||||
|             void update() const; | ||||
|              | ||||
|             void rebuildEffects() const; | ||||
| 
 | ||||
|             const ESM::EffectList& getEffectList (const std::string& id) const; | ||||
|             std::pair<ESM::EffectList, bool> getEffectList (const std::string& id) const; | ||||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             ActiveSpells(); | ||||
| 
 | ||||
|             bool addSpell (const std::string& id); | ||||
|             bool addSpell (const std::string& id, const MWWorld::Ptr& actor); | ||||
|             ///< Overwrites an existing spell with the same ID. If the spell does not have any
 | ||||
|             /// non-instant effects, it is ignored.
 | ||||
|             ///
 | ||||
|  |  | |||
|  | @ -1,51 +1,14 @@ | |||
| #include "creaturestats.hpp" | ||||
| 
 | ||||
| #include <algorithm> | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| 
 | ||||
| namespace MWMechanics | ||||
| { | ||||
|     CreatureStats::CreatureStats() | ||||
|     {} | ||||
|      | ||||
|     // Can't use all benefits of members initialization because of
 | ||||
|     // lack of copy constructors
 | ||||
|     CreatureStats::CreatureStats(const CreatureStats &orig) | ||||
|       : mLevel(orig.mLevel), mHello(orig.mHello), mFight(orig.mFight), | ||||
|       mFlee(orig.mFlee), mAlarm(orig.mAlarm) | ||||
|     { | ||||
|         for (int i = 0; i < 8; ++i) { | ||||
|             mAttributes[i] = orig.mAttributes[i]; | ||||
|         } | ||||
|         for (int i = 0; i < 3; ++i) { | ||||
|             mDynamic[i] = orig.mDynamic[i]; | ||||
|         } | ||||
|         mSpells = orig.mSpells; | ||||
|         mActiveSpells = orig.mActiveSpells; | ||||
|         mMagicEffects = orig.mMagicEffects; | ||||
|     } | ||||
| 
 | ||||
|     CreatureStats::~CreatureStats() | ||||
|     {} | ||||
| 
 | ||||
|     const CreatureStats & | ||||
|     CreatureStats::operator=(const CreatureStats &orig) | ||||
|     { | ||||
|         for (int i = 0; i < 8; ++i) { | ||||
|             mAttributes[i] = orig.mAttributes[i]; | ||||
|         } | ||||
|         for (int i = 0; i < 3; ++i) { | ||||
|             mDynamic[i] = orig.mDynamic[i]; | ||||
|         } | ||||
|         mLevel = orig.mLevel; | ||||
|         mSpells = orig.mSpells; | ||||
|         mActiveSpells = orig.mActiveSpells; | ||||
|         mMagicEffects = orig.mMagicEffects; | ||||
|         mHello = orig.mHello; | ||||
|         mFight = orig.mFight; | ||||
|         mFlee = orig.mFlee; | ||||
|         mAlarm = orig.mAlarm; | ||||
| 
 | ||||
|         return *this; | ||||
|     } | ||||
|      | ||||
| {   | ||||
|     const AiSequence& CreatureStats::getAiSequence() const | ||||
|     { | ||||
|         return mAiSequence; | ||||
|  | @ -55,4 +18,189 @@ namespace MWMechanics | |||
|     { | ||||
|         return mAiSequence;    | ||||
|     } | ||||
|      | ||||
|     float CreatureStats::getFatigueTerm() const   | ||||
|     { | ||||
|         int max = getFatigue().getModified(); | ||||
|         int current = getFatigue().getCurrent(); | ||||
|          | ||||
|         float normalised = max==0 ? 1 : std::max (0.0f, static_cast<float> (current)/max); | ||||
| 
 | ||||
|         const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); | ||||
|           | ||||
|         return store.gameSettings.find ("fFatigueBase")->getFloat() | ||||
|             - store.gameSettings.find ("fFatigueMult")->getFloat() * (1-normalised); | ||||
|     } | ||||
|      | ||||
|     const Stat<int> &CreatureStats::getAttribute(int index) const | ||||
|     { | ||||
|         if (index < 0 || index > 7) { | ||||
|             throw std::runtime_error("attribute index is out of range"); | ||||
|         } | ||||
|         return mAttributes[index]; | ||||
|     } | ||||
| 
 | ||||
|     const DynamicStat<int> &CreatureStats::getHealth() const | ||||
|     { | ||||
|         return mDynamic[0]; | ||||
|     } | ||||
| 
 | ||||
|     const DynamicStat<int> &CreatureStats::getMagicka() const | ||||
|     { | ||||
|         return mDynamic[1]; | ||||
|     } | ||||
| 
 | ||||
|     const DynamicStat<int> &CreatureStats::getFatigue() const | ||||
|     { | ||||
|         return mDynamic[2]; | ||||
|     } | ||||
| 
 | ||||
|     const Spells &CreatureStats::getSpells() const | ||||
|     { | ||||
|         return mSpells; | ||||
|     } | ||||
| 
 | ||||
|     const ActiveSpells &CreatureStats::getActiveSpells() const | ||||
|     { | ||||
|         return mActiveSpells; | ||||
|     } | ||||
| 
 | ||||
|     const MagicEffects &CreatureStats::getMagicEffects() const | ||||
|     { | ||||
|         return mMagicEffects; | ||||
|     } | ||||
| 
 | ||||
|     int CreatureStats::getLevel() const | ||||
|     { | ||||
|         return mLevel; | ||||
|     } | ||||
|     | ||||
|     int CreatureStats::getHello() const | ||||
|     { | ||||
|         return mHello; | ||||
|     } | ||||
| 
 | ||||
|     int CreatureStats::getFight() const | ||||
|     { | ||||
|         return mFight; | ||||
|     } | ||||
| 
 | ||||
|     int CreatureStats::getFlee() const | ||||
|     { | ||||
|         return mFlee; | ||||
|     } | ||||
| 
 | ||||
|     int CreatureStats::getAlarm() const | ||||
|     { | ||||
|         return mAlarm; | ||||
|     } | ||||
| 
 | ||||
|     Stat<int> &CreatureStats::getAttribute(int index) | ||||
|     { | ||||
|         if (index < 0 || index > 7) { | ||||
|             throw std::runtime_error("attribute index is out of range"); | ||||
|         } | ||||
|         return mAttributes[index]; | ||||
|     } | ||||
| 
 | ||||
|     DynamicStat<int> &CreatureStats::getHealth() | ||||
|     { | ||||
|         return mDynamic[0]; | ||||
|     } | ||||
| 
 | ||||
|     DynamicStat<int> &CreatureStats::getMagicka() | ||||
|     { | ||||
|         return mDynamic[1]; | ||||
|     } | ||||
| 
 | ||||
|     DynamicStat<int> &CreatureStats::getFatigue() | ||||
|     { | ||||
|         return mDynamic[2]; | ||||
|     } | ||||
| 
 | ||||
|     DynamicStat<int> &CreatureStats::getDynamic(int index) | ||||
|     { | ||||
|         if (index < 0 || index > 2) { | ||||
|             throw std::runtime_error("dynamic stat index is out of range"); | ||||
|         } | ||||
|         return mDynamic[index]; | ||||
|     } | ||||
| 
 | ||||
|     Spells &CreatureStats::getSpells() | ||||
|     { | ||||
|         return mSpells; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setSpells(const Spells &spells) | ||||
|     { | ||||
|         mSpells = spells; | ||||
|     } | ||||
| 
 | ||||
|     ActiveSpells &CreatureStats::getActiveSpells() | ||||
|     { | ||||
|         return mActiveSpells; | ||||
|     } | ||||
| 
 | ||||
|     MagicEffects &CreatureStats::getMagicEffects() | ||||
|     { | ||||
|         return mMagicEffects; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setAttribute(int index, const Stat<int> &value) | ||||
|     { | ||||
|         if (index < 0 || index > 7) { | ||||
|             throw std::runtime_error("attribute index is out of range"); | ||||
|         } | ||||
|         mAttributes[index] = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setHealth(const DynamicStat<int> &value) | ||||
|     { | ||||
|         mDynamic[0] = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setMagicka(const DynamicStat<int> &value) | ||||
|     { | ||||
|         mDynamic[1] = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setFatigue(const DynamicStat<int> &value) | ||||
|     { | ||||
|         mDynamic[2] = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setLevel(int level) | ||||
|     { | ||||
|         mLevel = level; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setActiveSpells(const ActiveSpells &active) | ||||
|     { | ||||
|         mActiveSpells = active; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setMagicEffects(const MagicEffects &effects) | ||||
|     { | ||||
|         mMagicEffects = effects; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setHello(int value) | ||||
|     { | ||||
|         mHello = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setFight(int value) | ||||
|     { | ||||
|         mFight = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setFlee(int value) | ||||
|     { | ||||
|         mFlee = value; | ||||
|     } | ||||
| 
 | ||||
|     void CreatureStats::setAlarm(int value) | ||||
|     { | ||||
|         mAlarm = value; | ||||
|     }     | ||||
| } | ||||
|  |  | |||
|  | @ -31,11 +31,6 @@ namespace MWMechanics | |||
|         AiSequence mAiSequence; | ||||
| 
 | ||||
|     public: | ||||
|         CreatureStats(); | ||||
|         CreatureStats(const CreatureStats &); | ||||
|         virtual ~CreatureStats(); | ||||
| 
 | ||||
|         const CreatureStats & operator=(const CreatureStats &); | ||||
| 
 | ||||
|         const Stat<int> & getAttribute(int index) const; | ||||
| 
 | ||||
|  | @ -106,185 +101,10 @@ namespace MWMechanics | |||
|         const AiSequence& getAiSequence() const; | ||||
|          | ||||
|         AiSequence& getAiSequence(); | ||||
|     }; | ||||
| 
 | ||||
|     // Inline const getters
 | ||||
| 
 | ||||
|     inline const Stat<int> & | ||||
|     CreatureStats::getAttribute(int index) const { | ||||
|         if (index < 0 || index > 7) { | ||||
|             throw std::runtime_error("attribute index is out of range"); | ||||
|         } | ||||
|         return mAttributes[index]; | ||||
|     } | ||||
| 
 | ||||
|     inline const DynamicStat<int> & | ||||
|     CreatureStats::getHealth() const { | ||||
|         return mDynamic[0]; | ||||
|     } | ||||
| 
 | ||||
|     inline const DynamicStat<int> & | ||||
|     CreatureStats::getMagicka() const { | ||||
|         return mDynamic[1]; | ||||
|     } | ||||
| 
 | ||||
|     inline const DynamicStat<int> & | ||||
|     CreatureStats::getFatigue() const { | ||||
|         return mDynamic[2]; | ||||
|     } | ||||
| 
 | ||||
|     inline const Spells & | ||||
|     CreatureStats::getSpells() const { | ||||
|         return mSpells; | ||||
|     } | ||||
| 
 | ||||
|     inline const ActiveSpells &  | ||||
|     CreatureStats::getActiveSpells() const { | ||||
|         return mActiveSpells; | ||||
|     } | ||||
| 
 | ||||
|     inline const MagicEffects &  | ||||
|     CreatureStats::getMagicEffects() const { | ||||
|         return mMagicEffects; | ||||
|     } | ||||
| 
 | ||||
|     inline int | ||||
|     CreatureStats::getLevel() const { | ||||
|         return mLevel; | ||||
|     } | ||||
|     | ||||
|     inline int | ||||
|     CreatureStats::getHello() const { | ||||
|         return mHello; | ||||
|     } | ||||
| 
 | ||||
|     inline int | ||||
|     CreatureStats::getFight() const { | ||||
|         return mFight; | ||||
|     } | ||||
| 
 | ||||
|     inline int | ||||
|     CreatureStats::getFlee() const { | ||||
|         return mFlee; | ||||
|     } | ||||
| 
 | ||||
|     inline int | ||||
|     CreatureStats::getAlarm() const { | ||||
|         return mAlarm; | ||||
|     } | ||||
| 
 | ||||
|     // Inline non-const getters
 | ||||
| 
 | ||||
|     inline Stat<int> & | ||||
|     CreatureStats::getAttribute(int index) { | ||||
|         if (index < 0 || index > 7) { | ||||
|             throw std::runtime_error("attribute index is out of range"); | ||||
|         } | ||||
|         return mAttributes[index]; | ||||
|     } | ||||
| 
 | ||||
|     inline DynamicStat<int> & | ||||
|     CreatureStats::getHealth() { | ||||
|         return mDynamic[0]; | ||||
|     } | ||||
| 
 | ||||
|     inline DynamicStat<int> & | ||||
|     CreatureStats::getMagicka() { | ||||
|         return mDynamic[1]; | ||||
|     } | ||||
| 
 | ||||
|     inline DynamicStat<int> & | ||||
|     CreatureStats::getFatigue() { | ||||
|         return mDynamic[2]; | ||||
|     } | ||||
| 
 | ||||
|     inline DynamicStat<int> & | ||||
|     CreatureStats::getDynamic(int index) { | ||||
|         if (index < 0 || index > 2) { | ||||
|             throw std::runtime_error("dynamic stat index is out of range"); | ||||
|         } | ||||
|         return mDynamic[index]; | ||||
|     } | ||||
| 
 | ||||
|     inline Spells &  | ||||
|     CreatureStats::getSpells() { | ||||
|         return mSpells; | ||||
|     } | ||||
| 
 | ||||
|     inline void  | ||||
|     CreatureStats::setSpells(const Spells &spells) { | ||||
|         mSpells = spells; | ||||
|     } | ||||
| 
 | ||||
|     inline ActiveSpells &  | ||||
|     CreatureStats::getActiveSpells() { | ||||
|         return mActiveSpells; | ||||
|     } | ||||
| 
 | ||||
|     inline MagicEffects &  | ||||
|     CreatureStats::getMagicEffects() { | ||||
|         return mMagicEffects; | ||||
|     } | ||||
| 
 | ||||
|     // Inline setters
 | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setAttribute(int index, const Stat<int> &value) { | ||||
|         if (index < 0 || index > 7) { | ||||
|             throw std::runtime_error("attribute index is out of range"); | ||||
|         } | ||||
|         mAttributes[index] = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setHealth(const DynamicStat<int> &value) { | ||||
|         mDynamic[0] = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setMagicka(const DynamicStat<int> &value) { | ||||
|         mDynamic[1] = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setFatigue(const DynamicStat<int> &value) { | ||||
|         mDynamic[2] = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setLevel(int level) { | ||||
|         mLevel = level; | ||||
|     } | ||||
| 
 | ||||
|     inline void  | ||||
|     CreatureStats::setActiveSpells(const ActiveSpells &active) { | ||||
|         mActiveSpells = active; | ||||
|     } | ||||
| 
 | ||||
|     inline void  | ||||
|     CreatureStats::setMagicEffects(const MagicEffects &effects) { | ||||
|         mMagicEffects = effects; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setHello(int value) { | ||||
|         mHello = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setFight(int value) { | ||||
|         mFight = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setFlee(int value) { | ||||
|         mFlee = value; | ||||
|     } | ||||
| 
 | ||||
|     inline void | ||||
|     CreatureStats::setAlarm(int value) { | ||||
|         mAlarm = value; | ||||
|     } | ||||
|         float getFatigueTerm() const; | ||||
|         ///< Return effective fatigue
 | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -11,9 +11,6 @@ | |||
| #include <OgreBillboardSet.h> | ||||
| #include <OgreEntity.h> | ||||
| #include <OgreSubEntity.h> | ||||
| #include <OgreOverlay.h> | ||||
| #include <OgreOverlayManager.h> | ||||
| #include <OgreOverlayContainer.h> | ||||
| 
 | ||||
| #include <boost/lexical_cast.hpp> | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ namespace Ogre | |||
|     class Entity; | ||||
|     class BillboardSet; | ||||
|     class TextureUnitState; | ||||
|     class Overlay; | ||||
| } | ||||
| 
 | ||||
| namespace MWRender | ||||
|  |  | |||
							
								
								
									
										49
									
								
								apps/openmw/mwworld/actioneat.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								apps/openmw/mwworld/actioneat.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| 
 | ||||
| #include "actioneat.hpp" | ||||
| 
 | ||||
| #include <cstdlib> | ||||
| 
 | ||||
| #include <components/esm/loadskil.hpp> | ||||
| 
 | ||||
| #include <components/esm_store/store.hpp> | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/world.hpp" | ||||
| 
 | ||||
| #include "../mwmechanics/creaturestats.hpp" | ||||
| #include "../mwmechanics/npcstats.hpp" | ||||
| 
 | ||||
| #include "class.hpp" | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|     void ActionEat::executeImp (const Ptr& actor) | ||||
|     { | ||||
|         // remove used item
 | ||||
|         getTarget().getRefData().setCount (getTarget().getRefData().getCount()-1); | ||||
| 
 | ||||
|         // check for success
 | ||||
|         const MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor); | ||||
|         MWMechanics::NpcStats& npcStats = MWWorld::Class::get (actor).getNpcStats (actor); | ||||
|      | ||||
|         float x = | ||||
|             (npcStats.getSkill (ESM::Skill::Alchemy).getModified() + | ||||
|             0.2 * creatureStats.getAttribute (1).getModified() | ||||
|             + 0.1 * creatureStats.getAttribute (7).getModified()) | ||||
|             * creatureStats.getFatigueTerm(); | ||||
| 
 | ||||
|         if (x>=100*static_cast<float> (std::rand()) / RAND_MAX) | ||||
|         { | ||||
|             // apply to actor
 | ||||
|             std::string id = Class::get (getTarget()).getId (getTarget()); | ||||
|              | ||||
|             Class::get (actor).apply (actor, id, actor); | ||||
|             // we ignore the result here. Skill increases no matter if the ingredient did something or not.      
 | ||||
|          | ||||
|             // increase skill
 | ||||
|             Class::get (actor).skillUsageSucceeded (actor, ESM::Skill::Alchemy, 1); | ||||
|         } | ||||
|     }     | ||||
| 
 | ||||
|     ActionEat::ActionEat (const MWWorld::Ptr& object) : Action (false, object) {} | ||||
| } | ||||
							
								
								
									
										19
									
								
								apps/openmw/mwworld/actioneat.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								apps/openmw/mwworld/actioneat.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| #ifndef GAME_MWWORLD_ACTIONEAT_H | ||||
| #define GAME_MWWORLD_ACTIONEAT_H | ||||
| 
 | ||||
| #include "action.hpp" | ||||
| #include "ptr.hpp" | ||||
| 
 | ||||
| namespace MWWorld | ||||
| { | ||||
|     class ActionEat : public Action | ||||
|     { | ||||
|             virtual void executeImp (const Ptr& actor); | ||||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             ActionEat (const MWWorld::Ptr& object); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -290,7 +290,6 @@ namespace MWWorld | |||
| 
 | ||||
|         mCurrentCell = *iter; | ||||
| 
 | ||||
| 
 | ||||
|         // adjust player
 | ||||
|         playerCellChange (mCurrentCell, position, adjustPlayerPos); | ||||
| 
 | ||||
|  | @ -300,6 +299,8 @@ namespace MWWorld | |||
|         mRendering.switchToExterior(); | ||||
| 
 | ||||
|         mCellChanged = true; | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager ()->loadingDone (); | ||||
|     } | ||||
| 
 | ||||
|     //We need the ogre renderer and a scene node.
 | ||||
|  | @ -369,6 +370,8 @@ namespace MWWorld | |||
|         MWBase::Environment::get().getWorld()->adjustSky(); | ||||
| 
 | ||||
|         mCellChanged = true; | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager ()->loadingDone (); | ||||
|     } | ||||
| 
 | ||||
|     void Scene::changeToExteriorCell (const ESM::Position& position) | ||||
|  |  | |||
|  | @ -1,8 +1,15 @@ | |||
| #include "loadgmst.hpp" | ||||
| 
 | ||||
| #include <stdexcept> | ||||
| 
 | ||||
| #include "defs.hpp" | ||||
| 
 | ||||
| namespace ESM | ||||
| { | ||||
| 
 | ||||
| /// \todo Review GMST "fixing". Probably remove completely or at least make it optional. Its definitely not
 | ||||
| /// working properly in its current state and I doubt it can be fixed without breaking other stuff.
 | ||||
| 
 | ||||
| // Some handy macros
 | ||||
| #define cI(s,x) { if(id == (s)) return (i == (x)); } | ||||
| #define cF(s,x) { if(id == (s)) return (f == (x)); } | ||||
|  | @ -169,4 +176,32 @@ void GameSetting::load(ESMReader &esm) | |||
|         dirty = true; | ||||
| } | ||||
| 
 | ||||
| int GameSetting::getInt() const | ||||
| { | ||||
|     switch (type) | ||||
|     { | ||||
|         case VT_Float: return static_cast<int> (f); | ||||
|         case VT_Int: return i; | ||||
|         default: throw std::runtime_error ("GMST " + id + " is not of a numeric type"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int GameSetting::getFloat() const | ||||
| { | ||||
|     switch (type) | ||||
|     { | ||||
|         case VT_Float: return f; | ||||
|         case VT_Int: return i; | ||||
|         default: throw std::runtime_error ("GMST " + id + " is not of a numeric type"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::string GameSetting::getString() const | ||||
| { | ||||
|     if (type==VT_String) | ||||
|         return str; | ||||
|          | ||||
|     throw std::runtime_error ("GMST " + id + " is not a string"); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -83,6 +83,15 @@ struct GameSetting | |||
|     bool isDirtyBloodmoon(); | ||||
| 
 | ||||
|     void load(ESMReader &esm); | ||||
|      | ||||
|     int getInt() const; | ||||
|     ///< Throws an exception if GMST is not of type int or float.
 | ||||
|      | ||||
|     int getFloat() const; | ||||
|     ///< Throws an exception if GMST is not of type int or float.
 | ||||
|      | ||||
|     std::string getString() const; | ||||
|     ///< Throwns an exception if GMST is not of type string.
 | ||||
| }; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,5 +1,30 @@ | |||
| #include "loadmgef.hpp" | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
|     const int NumberOfHardcodedFlags = 143; | ||||
|     const int HardcodedFlags[NumberOfHardcodedFlags] = { | ||||
|         0x11c8, 0x11c0, 0x11c8, 0x11e0, 0x11e0, 0x11e0, 0x11e0, 0x11d0, | ||||
|         0x11c0, 0x11c0, 0x11e0, 0x11c0, 0x11184, 0x11184, 0x1f0, 0x1f0, | ||||
|         0x1f0, 0x11d2, 0x11f0, 0x11d0, 0x11d0, 0x11d1, 0x1d2, 0x1f0, | ||||
|         0x1d0, 0x1d0, 0x1d1, 0x1f0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, | ||||
|         0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x1d0, 0x1d0, 0x11c8, | ||||
|         0x31c0, 0x11c0, 0x11c0, 0x11c0, 0x1180, 0x11d8, 0x11d8, 0x11d0, | ||||
|         0x11d0, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, | ||||
|         0x11180, 0x11c4, 0x111b8, 0x1040, 0x104c, 0x104c, 0x104c, 0x104c, | ||||
|         0x1040, 0x1040, 0x1040, 0x11c0, 0x11c0, 0x1cc, 0x1cc, 0x1cc, | ||||
|         0x1cc, 0x1cc, 0x1c2, 0x1c0, 0x1c0, 0x1c0, 0x1c1, 0x11c2, | ||||
|         0x11c0, 0x11c0, 0x11c0, 0x11c1, 0x11c0, 0x21192, 0x20190, 0x20190, | ||||
|         0x20190, 0x21191, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, | ||||
|         0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x1c0, 0x11190, 0x9048, 0x9048, | ||||
|         0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, | ||||
|         0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x11c0, 0x1180, 0x1180, | ||||
|         0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x1188, 0x5048, | ||||
|         0x5048, 0x5048, 0x5048, 0x5048, 0x1048, 0x104c, 0x1048, 0x40, | ||||
|         0x11c8, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048 | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| namespace ESM | ||||
| { | ||||
| 
 | ||||
|  | @ -8,6 +33,10 @@ void MagicEffect::load(ESMReader &esm) | |||
|   esm.getHNT(index, "INDX"); | ||||
| 
 | ||||
|   esm.getHNT(data, "MEDT", 36); | ||||
|    | ||||
|   if (index>=0 && index<NumberOfHardcodedFlags) | ||||
|     data.flags |= HardcodedFlags[index]; | ||||
|    | ||||
|   icon = esm.getHNOString("ITEX"); | ||||
|   particle = esm.getHNOString("PTEX"); | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ struct MagicEffect | |||
| { | ||||
|     enum Flags | ||||
|     { | ||||
|         NoDuration = 0x4, | ||||
|         SpellMaking = 0x0200, | ||||
|         Enchanting = 0x0400, | ||||
|         Negative = 0x0800 // A harmful effect. Will determine whether
 | ||||
|  |  | |||
|  | @ -164,6 +164,13 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | |||
|     // the flags we currently use, at least.
 | ||||
|     flags |= node->flags; | ||||
| 
 | ||||
|     // Marker objects: no collision
 | ||||
|     /// \todo don't do this in the editor
 | ||||
|     if (node->name.find("marker") != std::string::npos) | ||||
|     { | ||||
|         flags |= 0x800; | ||||
|     } | ||||
| 
 | ||||
|     // Check for extra data
 | ||||
|     Nif::Extra *e = node; | ||||
|     while (!e->extra.empty()) | ||||
|  | @ -178,12 +185,10 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | |||
|             // affecting the entire subtree of this node
 | ||||
|             Nif::NiStringExtraData *sd = (Nif::NiStringExtraData*)e; | ||||
| 
 | ||||
|             if (sd->string == "NCO" && !raycastingOnly) | ||||
|             if (sd->string == "NCO") | ||||
|             { | ||||
|                 // No collision. Use an internal flag setting to mark this.
 | ||||
|                 // We ignor this node!
 | ||||
|                 flags |= 0x800; | ||||
|                 return; | ||||
|             } | ||||
|             else if (sd->string == "MRK" && !raycastingOnly) | ||||
|                 // Marker objects. These are only visible in the
 | ||||
|  | @ -229,7 +234,7 @@ void ManualBulletShapeLoader::handleNode(Nif::Node *node, int flags, | |||
|     } | ||||
|     else if (node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode)) | ||||
|     { | ||||
|         cShape->collide = true; | ||||
|         cShape->collide = !(flags&0x800); | ||||
|         handleNiTriShape(dynamic_cast<Nif::NiTriShape*>(node), flags,node->trafo.rotation,node->trafo.pos,node->trafo.scale,raycastingOnly); | ||||
|     } | ||||
|     else if(node->recType == Nif::RC_RootCollisionNode) | ||||
|  |  | |||
|  | @ -940,6 +940,11 @@ public: | |||
|     { | ||||
|         flags |= node->flags; | ||||
| 
 | ||||
|         // Marker objects: just skip the entire node
 | ||||
|         /// \todo don't do this in the editor
 | ||||
|         if (node->name.find("marker") != std::string::npos) | ||||
|             return; | ||||
| 
 | ||||
|         Nif::ExtraPtr e = node->extra; | ||||
|         while(!e.empty()) | ||||
|         { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue