diff --git a/.travis.yml b/.travis.yml index c35d29201..233117718 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,6 @@ after_script: - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ./openmw_test_suite; fi notifications: recipients: - - lgromanowski+travis.ci@gmail.com - corrmage+travis-ci@gmail.com email: on_success: change diff --git a/CMakeLists.txt b/CMakeLists.txt index 37faeefb2..4d5c68cde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ message(STATUS "Configuring OpenMW...") set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MINOR 33) -set(OPENMW_VERSION_RELEASE 0) +set(OPENMW_VERSION_RELEASE 1) set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_TAGHASH "") diff --git a/apps/opencs/view/render/mousestate.cpp b/apps/opencs/view/render/mousestate.cpp index af835d0a5..45e846f74 100644 --- a/apps/opencs/view/render/mousestate.cpp +++ b/apps/opencs/view/render/mousestate.cpp @@ -255,7 +255,7 @@ namespace CSVRender std::pair result = terrainUnderCursor(event->x(), event->y()); if(result.first != "") { - // FIXME: terrain editing + // FIXME: terrain editing goes here } break; } @@ -267,6 +267,8 @@ namespace CSVRender void MouseState::mouseDoubleClickEvent (QMouseEvent *event) { event->ignore(); + //mPhysics->toggleDebugRendering(mSceneManager); + //mParent->flagAsModified(); } bool MouseState::wheelEvent (QWheelEvent *event) diff --git a/apps/opencs/view/world/physicsmanager.cpp b/apps/opencs/view/world/physicsmanager.cpp index f8e022e5d..fa8db9e1e 100644 --- a/apps/opencs/view/world/physicsmanager.cpp +++ b/apps/opencs/view/world/physicsmanager.cpp @@ -2,6 +2,8 @@ #include +#include + #include "../render/worldspacewidget.hpp" #include "physicssystem.hpp" @@ -54,6 +56,12 @@ namespace CSVWorld { mSceneWidgets.erase(it); } + + // cleanup global resources used by OEngine + if(mPhysics.empty()) + { + delete OEngine::Physic::BulletShapeManager::getSingletonPtr(); + } } // called from CSVRender::WorldspaceWidget() to get widgets' association with Document& @@ -74,6 +82,9 @@ namespace CSVWorld throw std::runtime_error("No physics system found for the given document."); } + // deprecated by removeDocument() and may be deleted in future code updates + // however there may be some value in removing the deleted scene widgets from the + // list so that the list does not grow forever void PhysicsManager::removeSceneWidget(CSVRender::WorldspaceWidget *widget) { CSVRender::SceneWidget *sceneWidget = static_cast(widget); diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index 73063b6be..57909f4d3 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -22,10 +22,7 @@ namespace CSVWorld PhysicsSystem::~PhysicsSystem() { - // FIXME: OEngine does not behave well when multiple instances are created - // and deleted, sometimes resulting in crashes. Skip the deletion until the physics - // code is moved out of OEngine. - //delete mEngine; + delete mEngine; } // looks up the scene manager based on the scene node name (inefficient) @@ -278,6 +275,8 @@ namespace CSVWorld void PhysicsSystem::addSceneManager(Ogre::SceneManager *sceneMgr, CSVRender::SceneWidget *sceneWidget) { mSceneWidgets[sceneMgr] = sceneWidget; + + mEngine->createDebugDraw(sceneMgr); } std::map PhysicsSystem::sceneWidgets() @@ -287,6 +286,8 @@ namespace CSVWorld void PhysicsSystem::removeSceneManager(Ogre::SceneManager *sceneMgr) { + mEngine->removeDebugDraw(sceneMgr); + mSceneWidgets.erase(sceneMgr); } @@ -310,8 +311,6 @@ namespace CSVWorld if(!sceneMgr) return; - mEngine->setSceneManager(sceneMgr); - CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); if(!(userSettings.setting("debug/mouse-picking", QString("false")) == "true" ? true : false)) { @@ -319,7 +318,7 @@ namespace CSVWorld return; } - mEngine->toggleDebugRendering(); - mEngine->stepSimulation(0.0167); // DebugDrawer::step() not directly accessible + mEngine->toggleDebugRendering(sceneMgr); + mEngine->stepDebug(sceneMgr); } } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 02594258d..2e835d57e 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -369,7 +369,7 @@ namespace MWMechanics void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration) { updateDrowning(ptr, duration); - calculateNpcStatModifiers(ptr); + calculateNpcStatModifiers(ptr, duration); updateEquippedLight(ptr, duration); } @@ -499,6 +499,9 @@ namespace MWMechanics effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).getMagnitude() - effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).getMagnitude()); + stat.damage(effects.get(EffectKey(ESM::MagicEffect::DamageAttribute, i)).getMagnitude() * duration * 1.5); + stat.restore(effects.get(EffectKey(ESM::MagicEffect::RestoreAttribute, i)).getMagnitude() * duration * 1.5); + creatureStats.setAttribute(i, stat); } @@ -855,7 +858,7 @@ namespace MWMechanics } } - void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr) + void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr, float duration) { NpcStats &npcStats = ptr.getClass().getNpcStats(ptr); const MagicEffects &effects = npcStats.getMagicEffects(); @@ -867,6 +870,9 @@ namespace MWMechanics skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).getMagnitude() - effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).getMagnitude() - effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).getMagnitude()); + + skill.damage(effects.get(EffectKey(ESM::MagicEffect::DamageSkill, i)).getMagnitude() * duration * 1.5); + skill.restore(effects.get(EffectKey(ESM::MagicEffect::RestoreSkill, i)).getMagnitude() * duration * 1.5); } } @@ -1534,6 +1540,6 @@ namespace MWMechanics adjustMagicEffects(ptr); calculateCreatureStatModifiers(ptr, 0.f); if (ptr.getClass().isNpc()) - calculateNpcStatModifiers(ptr); + calculateNpcStatModifiers(ptr, 0.f); } } diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 55f1719f6..0ccfaad78 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -34,7 +34,7 @@ namespace MWMechanics void calculateDynamicStats (const MWWorld::Ptr& ptr); void calculateCreatureStatModifiers (const MWWorld::Ptr& ptr, float duration); - void calculateNpcStatModifiers (const MWWorld::Ptr& ptr); + void calculateNpcStatModifiers (const MWWorld::Ptr& ptr, float duration); void calculateRestoration (const MWWorld::Ptr& ptr, float duration); diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 681f01f04..a1b73bc47 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -70,11 +70,13 @@ namespace MWMechanics if (mPermanentSpellEffects.find(lower) != mPermanentSpellEffects.end()) { MagicEffects & effects = mPermanentSpellEffects[lower]; - for (MagicEffects::Collection::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt) + for (MagicEffects::Collection::const_iterator effectIt = effects.begin(); effectIt != effects.end();) { const ESM::MagicEffect * magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->first.mId); if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful) - effects.remove(effectIt->first); + effects.remove((effectIt++)->first); + else + ++effectIt; } } mCorprusSpells.erase(corprusIt); diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 0fb4c5732..1c33db0fd 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -236,20 +236,20 @@ namespace MWMechanics { int mBase; int mModifier; - int mDamage; + float mDamage; // needs to be float to allow continuous damage public: AttributeValue() : mBase(0), mModifier(0), mDamage(0) {} - int getModified() const { return std::max(0, mBase - mDamage + mModifier); } + int getModified() const { return std::max(0, mBase - (int) mDamage + mModifier); } int getBase() const { return mBase; } int getModifier() const { return mModifier; } void setBase(int base) { mBase = std::max(0, base); } void setModifier(int mod) { mModifier = mod; } - void damage(int damage) { mDamage += damage; } - void restore(int amount) { mDamage -= std::min(mDamage, amount); } + void damage(float damage) { mDamage += damage; } + void restore(float amount) { mDamage -= std::min(mDamage, amount); } int getDamage() const { return mDamage; } void writeState (ESM::StatState& state) const; diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index a88c5a101..563a9dde3 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -125,6 +125,9 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); + if (!ptr.getRefData().isEnabled()) + return; + MWBase::Environment::get().getDialogueManager()->startDialogue (ptr); } }; diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index aba120baa..eecc4a02d 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -471,10 +472,9 @@ namespace MWWorld physicActor->setInertialForce(Ogre::Vector3(0.0f)); else { - float diff = time*-627.2f; + inertia.z += time * -627.2f; if (inertia.z < 0) - diff *= slowFall; - inertia.z += diff; + inertia.z *= slowFall; physicActor->setInertialForce(inertia); } physicActor->setOnGround(isOnGround); @@ -498,6 +498,7 @@ namespace MWWorld if (mWaterCollisionObject.get()) mEngine->mDynamicsWorld->removeCollisionObject(mWaterCollisionObject.get()); delete mEngine; + delete OEngine::Physic::BulletShapeManager::getSingletonPtr(); } OEngine::Physic::PhysicEngine* PhysicsSystem::getEngine() @@ -863,8 +864,8 @@ namespace MWWorld continue; physicActor->setCanWaterWalk(waterCollision); - // 100 points of slowfall reduce gravity by 90% (this is just a guess) - float slowFall = 1-std::min(std::max(0.f, (effects.get(ESM::MagicEffect::SlowFall).getMagnitude() / 100.f) * 0.9f), 0.9f); + // Slow fall reduces fall speed by a factor of (effect magnitude / 200) + float slowFall = 1.f - std::max(0.f, std::min(1.f, effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f)); Ogre::Vector3 newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum, world->isFlying(iter->first), diff --git a/components/esm/statstate.hpp b/components/esm/statstate.hpp index f1a3b4d79..801d0ce82 100644 --- a/components/esm/statstate.hpp +++ b/components/esm/statstate.hpp @@ -15,7 +15,7 @@ namespace ESM T mMod; // Note: can either be the modifier, or the modified value. // A bit inconsistent, but we can't fix this without breaking compatibility. T mCurrent; - T mDamage; + float mDamage; float mProgress; StatState(); @@ -36,8 +36,14 @@ namespace ESM esm.getHNOT (mMod, "STMO"); mCurrent = 0; esm.getHNOT (mCurrent, "STCU"); - mDamage = 0; - esm.getHNOT (mDamage, "STDA"); + + // mDamage was changed to a float; ensure backwards compatibility + T oldDamage = 0; + esm.getHNOT(oldDamage, "STDA"); + mDamage = oldDamage; + + esm.getHNOT (mDamage, "STDF"); + mProgress = 0; esm.getHNOT (mProgress, "STPR"); } @@ -54,7 +60,7 @@ namespace ESM esm.writeHNT ("STCU", mCurrent); if (mDamage) - esm.writeHNT ("STDA", mDamage); + esm.writeHNT ("STDF", mDamage); if (mProgress) esm.writeHNT ("STPR", mProgress); diff --git a/credits.txt b/credits.txt index 10065b44d..d7fe230c7 100644 --- a/credits.txt +++ b/credits.txt @@ -46,6 +46,7 @@ Jannik Heller (scrawl) Jason Hooks (jhooks) jeaye Jeffrey Haines (Jyby) +Jengerer Joel Graff (graffy) John Blomberg (fstp) Jordan Ayers diff --git a/files/openmw.cfg b/files/openmw.cfg index e105b6304..b60c1ba72 100644 --- a/files/openmw.cfg +++ b/files/openmw.cfg @@ -1,5 +1,5 @@ -data="?global?data" data="?mw?Data Files" +data=${MORROWIND_DATA_FILES} data-local="?userdata?data" resources=${OPENMW_RESOURCE_FILES} script-blacklist=Museum diff --git a/libs/openengine/bullet/BtOgreExtras.h b/libs/openengine/bullet/BtOgreExtras.h index 9572b8a7b..f8c1fe41d 100644 --- a/libs/openengine/bullet/BtOgreExtras.h +++ b/libs/openengine/bullet/BtOgreExtras.h @@ -212,8 +212,10 @@ public: ~DebugDrawer() { - Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines"); - Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre"); + if (Ogre::MaterialManager::getSingleton().resourceExists("BtOgre/DebugLines")) + Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines"); + if (Ogre::ResourceGroupManager::getSingleton().resourceGroupExists("BtOgre")) + Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre"); delete mLineDrawer; } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 0c61253bf..d7db81595 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -114,7 +114,7 @@ namespace Physic { mEngine->mDynamicsWorld->removeRigidBody(mBody); delete mBody; - } + } } void PhysicActor::enableCollisionMode(bool collision) @@ -356,7 +356,8 @@ namespace Physic delete broadphase; delete mShapeLoader; - delete BulletShapeManager::getSingletonPtr(); + // Moved the cleanup to mwworld/physicssystem + //delete BulletShapeManager::getSingletonPtr(); } void PhysicEngine::addHeightField(float* heights, @@ -863,5 +864,76 @@ namespace Physic } } + int PhysicEngine::toggleDebugRendering(Ogre::SceneManager *sceneMgr) + { + if(!sceneMgr) + return 0; + + std::map::iterator iter = + mDebugDrawers.find(sceneMgr); + if(iter != mDebugDrawers.end()) // found scene manager + { + if((*iter).second) + { + // set a new drawer each time (maybe with a different scene manager) + mDynamicsWorld->setDebugDrawer(mDebugDrawers[sceneMgr]); + if(!mDebugDrawers[sceneMgr]->getDebugMode()) + mDebugDrawers[sceneMgr]->setDebugMode(1 /*mDebugDrawFlags*/); + else + mDebugDrawers[sceneMgr]->setDebugMode(0); + mDynamicsWorld->debugDrawWorld(); + + return mDebugDrawers[sceneMgr]->getDebugMode(); + } + } + return 0; + } + + void PhysicEngine::stepDebug(Ogre::SceneManager *sceneMgr) + { + if(!sceneMgr) + return; + + std::map::iterator iter = + mDebugDrawers.find(sceneMgr); + if(iter != mDebugDrawers.end()) // found scene manager + { + if((*iter).second) + (*iter).second->step(); + else + return; + } + } + + void PhysicEngine::createDebugDraw(Ogre::SceneManager *sceneMgr) + { + if(mDebugDrawers.find(sceneMgr) == mDebugDrawers.end()) + { + mDebugSceneNodes[sceneMgr] = sceneMgr->getRootSceneNode()->createChildSceneNode(); + mDebugDrawers[sceneMgr] = new BtOgre::DebugDrawer(mDebugSceneNodes[sceneMgr], mDynamicsWorld); + mDebugDrawers[sceneMgr]->setDebugMode(0); + } + } + + void PhysicEngine::removeDebugDraw(Ogre::SceneManager *sceneMgr) + { + std::map::iterator iter = + mDebugDrawers.find(sceneMgr); + if(iter != mDebugDrawers.end()) + { + delete (*iter).second; + mDebugDrawers.erase(iter); + } + + std::map::iterator it = + mDebugSceneNodes.find(sceneMgr); + if(it != mDebugSceneNodes.end()) + { + std::string sceneNodeName = (*it).second->getName(); + if(sceneMgr->hasSceneNode(sceneNodeName)) + sceneMgr->destroySceneNode(sceneNodeName); + } + } + } } diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index a77b60ab6..fb6ae0ceb 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -348,6 +348,15 @@ namespace Physic bool isDebugCreated; bool mDebugActive; + // for OpenCS with multiple engines per document + std::map mDebugDrawers; + std::map mDebugSceneNodes; + + int toggleDebugRendering(Ogre::SceneManager *sceneMgr); + void stepDebug(Ogre::SceneManager *sceneMgr); + void createDebugDraw(Ogre::SceneManager *sceneMgr); + void removeDebugDraw(Ogre::SceneManager *sceneMgr); + private: PhysicEngine(const PhysicEngine&); PhysicEngine& operator=(const PhysicEngine&); diff --git a/readme.txt b/readme.txt index cb533e9fb..810a0e055 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.33.0 +Version: 0.33.1 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org @@ -98,6 +98,10 @@ Allowed options: CHANGELOG +0.33.1 + +Bug #2108: OpenCS fails to build + 0.33.0 Bug #371: If console assigned to ` (probably to any symbolic key), "`" symbol will be added to console every time it closed