From add3cd6456c07fc149bfc5e3aefdfd6507bca7e1 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 30 Apr 2013 18:22:59 +0200 Subject: [PATCH 01/19] Advance acrobatics on jump --- apps/openmw/mwmechanics/character.cpp | 13 ++++++++++--- apps/openmw/mwmechanics/character.hpp | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index b82fc4dc5..c762e6d14 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -104,7 +104,8 @@ static void getStateInfo(CharacterState state, std::string *group) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) - : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), mSecondsOfRunning(0), mSecondsOfSwimming(0) + : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), + mSecondsOfRunning(0), mSecondsOfSwimming(0), mSecondsOfFalling(0) { if(!mAnimation) return; @@ -176,10 +177,16 @@ void CharacterController::update(float duration, Movement &movement) } } - /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except - * for the initial thrust (which would be carried by "physics" until landing). */ + // FIXME: X/Y movement should be disallowed except for the initial thrust (which would be carried by "physics" until landing). if(onground && vec.z > 0.0f) { + //Advance acrobatics on jump + if(getState()!=CharState_Jump) + { + setState(CharState_Jump, true); + MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); + } + float x = cls.getJump(mPtr); if(vec.x == 0 && vec.y == 0) diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 4ee217d11..7dfd5d004 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -82,6 +82,7 @@ class CharacterController // counted for skill increase float mSecondsOfSwimming; float mSecondsOfRunning; + float mSecondsOfFalling; bool mMovingAnim; From 5a8c1661be8d688c6fcd7bd6cb65c85dbbe7eee4 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 30 Apr 2013 20:42:02 +0200 Subject: [PATCH 02/19] Jump acrobatics working, started falling acrobatics implementation --- apps/openmw/mwclass/npc.cpp | 28 +++++++++++++++++++++++++++ apps/openmw/mwclass/npc.hpp | 3 +++ apps/openmw/mwmechanics/character.cpp | 25 +++++++++++++++++++++++- apps/openmw/mwmechanics/character.hpp | 3 ++- apps/openmw/mwworld/class.cpp | 5 +++++ apps/openmw/mwworld/class.hpp | 3 +++ 6 files changed, 65 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ea49ae4a4..a90b85955 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -470,6 +470,34 @@ namespace MWClass return x; } + float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const + { + const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallDamageDistanceMin")->getFloat(); + + if(fallHeight>=fallDistanceMin) + { + const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill (ESM::Skill::Acrobatics).getModified(); + const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); + const float jumpSpellBonus = npcdata->mCreatureStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude; + const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallAcroBase")->getFloat(); + const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallAcroMult")->getFloat(); + const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallDistanceBase")->getFloat(); + const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallDistanceMult")->getFloat(); + + float x = fallHeight - fallDistanceMin; + x -= (1.5 * acrobaticsSkill) + jumpSpellBonus; + x = std::max(0.0f, x); + + float a = fallAcroBase + (fallAcroMult * (100 - acrobaticsSkill)); + x = fallDistanceBase + (fallDistanceMult * x); + x *= a; + + return x; + } + + return 0; + } + MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const { ensureCustomData (ptr); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index d1a9158fd..47d32d88f 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -91,6 +91,9 @@ namespace MWClass virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) + virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; + ///< Return amount of health points lost when falling + virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c762e6d14..9a8e34bb7 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -31,6 +31,8 @@ #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" +#include "../mwmechanics/stat.hpp" +#include "../mwmechanics/creaturestats.hpp" namespace MWMechanics { @@ -105,7 +107,7 @@ static void getStateInfo(CharacterState state, std::string *group) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), - mSecondsOfRunning(0), mSecondsOfSwimming(0), mSecondsOfFalling(0) + mSecondsOfRunning(0), mSecondsOfSwimming(0), mHighestPosition(0) { if(!mAnimation) return; @@ -200,8 +202,29 @@ void CharacterController::update(float duration, Movement &movement) movement.mPosition[2] += x * 0.707f * duration; } + //To calculate how much player will fall down + if(movement.mPosition[2] > mHighestPosition) + mHighestPosition = movement.mPosition[2]; + //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; } + else if(vec.z==0.0f && getState()==CharState_Jump) + { + float healthLost = cls.getFallDamage(mPtr, mHighestPosition); + + if(healthLost>0.0f) + { + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + int fatigue = MWWorld::Class::get (mPtr).getCreatureStats (mPtr).getFatigue().getBase(); + int iHealth = health.getBase(); + health.setBase (iHealth-(healthLost * (1 - (0.25 * fatigue)))); + cls.getCreatureStats(mPtr).setHealth (health); + MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + } + + setState(CharState_Idle, true); + mHighestPosition=0; + } if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f) { diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 7dfd5d004..460141880 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -82,7 +82,8 @@ class CharacterController // counted for skill increase float mSecondsOfSwimming; float mSecondsOfRunning; - float mSecondsOfFalling; + + float mHighestPosition; bool mMovingAnim; diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 03a55c7f0..db798537e 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -132,6 +132,11 @@ namespace MWWorld return 0; } + float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const + { + return 0; + } + float Class::getEnchantmentPoints (const MWWorld::Ptr& ptr) const { throw std::runtime_error ("class does not support enchanting"); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index e203fedc3..3901ea830 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -146,6 +146,9 @@ namespace MWWorld virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) + virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; + ///< Return amount of health points lost when falling + virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const; ///< Return desired movement. From d30e43784aab1d202c3a9457150b705a8ee84cda Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 30 Apr 2013 23:39:56 +0200 Subject: [PATCH 03/19] Fatigue decrease when jumping, live decrease when falling --- apps/openmw/mwmechanics/character.cpp | 29 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 9a8e34bb7..1b8ed0868 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -156,6 +156,10 @@ void CharacterController::update(float duration, Movement &movement) const Ogre::Vector3 &rot = cls.getRotationVector(mPtr); speed = cls.getSpeed(mPtr); + //To calculate how much player will fall down + if(movement.mPosition[2] > mHighestPosition) + mHighestPosition = movement.mPosition[2]; + // advance athletics if (vec.squaredLength() > 0 && mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) { @@ -182,11 +186,20 @@ void CharacterController::update(float duration, Movement &movement) // FIXME: X/Y movement should be disallowed except for the initial thrust (which would be carried by "physics" until landing). if(onground && vec.z > 0.0f) { - //Advance acrobatics on jump + //Advance acrobatics on jump, decrease fatigue if(getState()!=CharState_Jump) { setState(CharState_Jump, true); MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); + + const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); + const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get().find ("fFatigueJumpBase")->getFloat(); + const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFatigueJumpMult")->getFloat(); + DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); + int current = fatigue.getCurrent(); + fatigue.setModified(fatigue.getModified()-(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0); + fatigue.setCurrent(current-(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult))); + cls.getCreatureStats(mPtr).setDynamic (2, fatigue); } float x = cls.getJump(mPtr); @@ -201,14 +214,9 @@ void CharacterController::update(float duration, Movement &movement) //movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration; movement.mPosition[2] += x * 0.707f * duration; } - - //To calculate how much player will fall down - if(movement.mPosition[2] > mHighestPosition) - mHighestPosition = movement.mPosition[2]; - - //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; } - else if(vec.z==0.0f && getState()==CharState_Jump) + + if(vec.z<=0.0f && getState()==CharState_Jump) { float healthLost = cls.getFallDamage(mPtr, mHighestPosition); @@ -216,8 +224,9 @@ void CharacterController::update(float duration, Movement &movement) { DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); int fatigue = MWWorld::Class::get (mPtr).getCreatureStats (mPtr).getFatigue().getBase(); - int iHealth = health.getBase(); - health.setBase (iHealth-(healthLost * (1 - (0.25 * fatigue)))); + int current = health.getCurrent(); + health.setModified (health.getModified()-(healthLost * (1 - (0.25 * fatigue))), 0); + health.setCurrent (current-(healthLost * (1 - (0.25 * fatigue)))); cls.getCreatureStats(mPtr).setHealth (health); MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); } From 627c3fdb6bb9a27cdb40e43aff6947eaf0f8f1f5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 1 May 2013 11:15:43 +0200 Subject: [PATCH 04/19] Added GetStandingPC, GetStandingActor; Fixed GetStartingPos --- apps/openmw/mwbase/world.hpp | 3 ++ apps/openmw/mwscript/docs/vmformat.txt | 6 ++- apps/openmw/mwscript/miscextensions.cpp | 35 ++++++++++++++++- .../mwscript/transformationextensions.cpp | 6 +-- apps/openmw/mwworld/physicssystem.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 16 ++++++++ apps/openmw/mwworld/worldimp.hpp | 3 ++ libs/openengine/bullet/physic.cpp | 38 ++++++++++++++----- libs/openengine/bullet/physic.hpp | 4 +- 9 files changed, 96 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index a3b9d2cf2..abdad0fa8 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -331,6 +331,9 @@ namespace MWBase virtual void activateDoor(const MWWorld::Ptr& door) = 0; ///< activate (open or close) an non-teleport door + virtual bool getPlayerStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if the player is standing on \a object + virtual bool getActorStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if any actor is standing on \a object + virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; virtual int canRest() = 0; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index d02fc9289..d1df10489 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -331,5 +331,9 @@ op 0x2000208: MoveWorld op 0x2000209: MoveWorld, explicit op 0x200020a: Fall op 0x200020b: Fall, explicit +op 0x200020c: GetStandingPC +op 0x200020d: GetStandingPC, explicit +op 0x200020e: GetStandingActor +op 0x200020f: GetStandingActor, explicit -opcodes 0x200020c-0x3ffffff unused +opcodes 0x2000210-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index a08563877..b8a400ea6 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -565,6 +565,30 @@ namespace MWScript } }; + template + class OpGetStandingPc : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push (MWBase::Environment::get().getWorld()->getPlayerStandingOn(ptr)); + } + }; + + template + class OpGetStandingActor : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push (MWBase::Environment::get().getWorld()->getActorStandingOn(ptr)); + } + }; + const int opcodeXBox = 0x200000c; const int opcodeOnActivate = 0x200000d; const int opcodeActivate = 0x2000075; @@ -608,6 +632,10 @@ namespace MWScript const int opcodeGetSquareRoot = 0x20001e7; const int opcodeFall = 0x200020a; const int opcodeFallExplicit = 0x200020b; + const int opcodeGetStandingPc = 0x200020c; + const int opcodeGetStandingPcExplicit = 0x200020d; + const int opcodeGetStandingActor = 0x200020e; + const int opcodeGetStandingActorExplicit = 0x200020f; const int opcodePlayBink = 0x20001f7; @@ -650,6 +678,8 @@ namespace MWScript extensions.registerInstruction ("setdelete", "l", opcodeSetDelete, opcodeSetDeleteExplicit); extensions.registerFunction ("getsquareroot", 'f', "f", opcodeGetSquareRoot); extensions.registerInstruction ("fall", "", opcodeFall, opcodeFallExplicit); + extensions.registerFunction ("getstandingpc", 'l', "", opcodeGetStandingPc, opcodeGetStandingPcExplicit); + extensions.registerFunction ("getstandingactor", 'l', "", opcodeGetStandingActor, opcodeGetStandingActorExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -698,7 +728,10 @@ namespace MWScript interpreter.installSegment5 (opcodeGetSquareRoot, new OpGetSquareRoot); interpreter.installSegment5 (opcodeFall, new OpFall); interpreter.installSegment5 (opcodeFallExplicit, new OpFall); - + interpreter.installSegment5 (opcodeGetStandingPc, new OpGetStandingPc); + interpreter.installSegment5 (opcodeGetStandingPcExplicit, new OpGetStandingPc); + interpreter.installSegment5 (opcodeGetStandingActor, new OpGetStandingActor); + interpreter.installSegment5 (opcodeGetStandingActorExplicit, new OpGetStandingActor); } } } diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 327047cdc..0476870e4 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -247,15 +247,15 @@ namespace MWScript if(axis == "x") { - runtime.push(ptr.getRefData().getPosition().pos[0]); + runtime.push(ptr.getCellRef().mPos.pos[0]); } else if(axis == "y") { - runtime.push(ptr.getRefData().getPosition().pos[1]); + runtime.push(ptr.getCellRef().mPos.pos[1]); } else if(axis == "z") { - runtime.push(ptr.getRefData().getPosition().pos[2]); + runtime.push(ptr.getCellRef().mPos.pos[2]); } else throw std::runtime_error ("invalid axis: " + axis); diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 086950574..7abe94aa6 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -501,7 +501,7 @@ namespace MWWorld bool PhysicsSystem::toggleCollisionMode() { - for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) + for(std::map::iterator it = mEngine->mActorMap.begin(); it != mEngine->mActorMap.end();it++) { if (it->first=="player") { diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9a08a1635..3fb4ff8bd 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1583,4 +1583,20 @@ namespace MWWorld return !mDoorStates[door]; // if currently opening or closing, then do the opposite return door.getRefData().getLocalRotation().rot[2] == 0; } + + bool World::getPlayerStandingOn (const MWWorld::Ptr& object) + { + MWWorld::Ptr player = mPlayer->getPlayer(); + if (!mPhysEngine->getCharacter("player")->getOnGround()) + return false; + btVector3 from (player.getRefData().getPosition().pos[0], player.getRefData().getPosition().pos[1], player.getRefData().getPosition().pos[2]); + btVector3 to = from - btVector3(0,0,5); + std::pair result = mPhysEngine->rayTest(from, to); + return result.first == object.getRefData().getBaseNode()->getName(); + } + + bool World::getActorStandingOn (const MWWorld::Ptr& object) + { + return mPhysEngine->isAnyActorStandingOn(object.getRefData().getBaseNode()->getName()); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f61f67062..a4ae3adf4 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -381,6 +381,9 @@ namespace MWWorld virtual void activateDoor(const MWWorld::Ptr& door); ///< activate (open or close) an non-teleport door + virtual bool getPlayerStandingOn (const MWWorld::Ptr& object); ///< @return true if the player is standing on \a object + virtual bool getActorStandingOn (const MWWorld::Ptr& object); ///< @return true if any actor is standing on \a object + virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); virtual int canRest(); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index def69a2e8..2b59e0aad 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -267,8 +267,8 @@ namespace Physic } } - PhysicActorContainer::iterator pa_it = PhysicActorMap.begin(); - for (; pa_it != PhysicActorMap.end(); ++pa_it) + PhysicActorContainer::iterator pa_it = mActorMap.begin(); + for (; pa_it != mActorMap.end(); ++pa_it) { if (pa_it->second != NULL) { @@ -567,13 +567,13 @@ namespace Physic //dynamicsWorld->addAction( newActor->mCharacter ); - PhysicActorMap[name] = newActor; + mActorMap[name] = newActor; } void PhysicEngine::removeCharacter(const std::string &name) { - PhysicActorContainer::iterator it = PhysicActorMap.find(name); - if (it != PhysicActorMap.end() ) + PhysicActorContainer::iterator it = mActorMap.find(name); + if (it != mActorMap.end() ) { PhysicActor* act = it->second; if(act != NULL) @@ -581,16 +581,16 @@ namespace Physic delete act; } - PhysicActorMap.erase(it); + mActorMap.erase(it); } } PhysicActor* PhysicEngine::getCharacter(const std::string &name) { - PhysicActorContainer::iterator it = PhysicActorMap.find(name); - if (it != PhysicActorMap.end() ) + PhysicActorContainer::iterator it = mActorMap.find(name); + if (it != mActorMap.end() ) { - PhysicActor* act = PhysicActorMap[name]; + PhysicActor* act = mActorMap[name]; return act; } else @@ -700,4 +700,22 @@ namespace Physic max = btVector3(0,0,0); } } -}} + + bool PhysicEngine::isAnyActorStandingOn (const std::string& objectName) + { + for (PhysicActorContainer::iterator it = mActorMap.begin(); it != mActorMap.end(); ++it) + { + if (!it->second->getOnGround()) + continue; + Ogre::Vector3 pos = it->second->getPosition(); + btVector3 from (pos.x, pos.y, pos.z); + btVector3 to = from - btVector3(0,0,5); + std::pair result = rayTest(from, to); + if (result.first == objectName) + return true; + } + return false; + } + +} +} diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 8b246408a..67e94c8f8 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -288,6 +288,8 @@ namespace Physic void setSceneManager(Ogre::SceneManager* sceneMgr); + bool isAnyActorStandingOn (const std::string& objectName); + /** * Return the closest object hit by a ray. If there are no objects, it will return ("",-1). */ @@ -329,7 +331,7 @@ namespace Physic RigidBodyContainer mRaycastingObjectMap; typedef std::map PhysicActorContainer; - PhysicActorContainer PhysicActorMap; + PhysicActorContainer mActorMap; Ogre::SceneManager* mSceneMgr; From 5063d90dda2734cd6d438ee94c4d7c9d5fae3e0c Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 1 May 2013 11:22:46 +0200 Subject: [PATCH 05/19] GetStartingAngle was implemented, but not registered --- apps/openmw/mwscript/docs/vmformat.txt | 4 +++- apps/openmw/mwscript/transformationextensions.cpp | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index d1df10489..38fa677a7 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -335,5 +335,7 @@ op 0x200020c: GetStandingPC op 0x200020d: GetStandingPC, explicit op 0x200020e: GetStandingActor op 0x200020f: GetStandingActor, explicit +op 0x2000210: GetStartingAngle +op 0x2000211: GetStartingAngle, explicit -opcodes 0x2000210-0x3ffffff unused +opcodes 0x2000212-0x3ffffff unused diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 0476870e4..9b7b51a5a 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -721,6 +721,8 @@ namespace MWScript const int opcodeSetPosExplicit = 0x2000193; const int opcodeGetStartingPos = 0x2000194; const int opcodeGetStartingPosExplicit = 0x2000195; + const int opcodeGetStartingAngle = 0x2000210; + const int opcodeGetStartingAngleExplicit = 0x2000211; const int opcodePosition = 0x2000196; const int opcodePositionExplicit = 0x2000197; const int opcodePositionCell = 0x2000198; @@ -765,6 +767,7 @@ namespace MWScript extensions.registerInstruction("setatstart","",opcodeSetAtStart,opcodeSetAtStartExplicit); extensions.registerInstruction("move","cf",opcodeMove,opcodeMoveExplicit); extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit); + extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -804,6 +807,8 @@ namespace MWScript interpreter.installSegment5(opcodeMoveExplicit,new OpMove); interpreter.installSegment5(opcodeMoveWorld,new OpMoveWorld); interpreter.installSegment5(opcodeMoveWorldExplicit,new OpMoveWorld); + interpreter.installSegment5(opcodeGetStartingAngle, new OpGetStartingAngle); + interpreter.installSegment5(opcodeGetStartingAngleExplicit, new OpGetStartingAngle); } } } From 67422c397c883017b4ff6a7adfb405cdf767f807 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 1 May 2013 11:42:24 +0200 Subject: [PATCH 06/19] GetWindSpeed --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwscript/docs/vmformat.txt | 3 ++- apps/openmw/mwscript/miscextensions.cpp | 13 +++++++++++++ apps/openmw/mwworld/weather.cpp | 9 ++++++++- apps/openmw/mwworld/weather.hpp | 3 +++ apps/openmw/mwworld/worldimp.cpp | 8 ++++++++ apps/openmw/mwworld/worldimp.hpp | 1 + 7 files changed, 36 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index abdad0fa8..6c9fa6703 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -333,6 +333,7 @@ namespace MWBase virtual bool getPlayerStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if the player is standing on \a object virtual bool getActorStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if any actor is standing on \a object + virtual float getWindSpeed() = 0; virtual void setupExternalRendering (MWRender::ExternalRendering& rendering) = 0; diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 38fa677a7..85d8deaec 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -337,5 +337,6 @@ op 0x200020e: GetStandingActor op 0x200020f: GetStandingActor, explicit op 0x2000210: GetStartingAngle op 0x2000211: GetStartingAngle, explicit +op 0x2000212: GetWindSpeed -opcodes 0x2000212-0x3ffffff unused +opcodes 0x2000213-0x3ffffff unused diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index b8a400ea6..5ed26119c 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -589,6 +589,16 @@ namespace MWScript } }; + class OpGetWindSpeed : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + runtime.push(MWBase::Environment::get().getWorld()->getWindSpeed()); + } + }; + const int opcodeXBox = 0x200000c; const int opcodeOnActivate = 0x200000d; const int opcodeActivate = 0x2000075; @@ -636,6 +646,7 @@ namespace MWScript const int opcodeGetStandingPcExplicit = 0x200020d; const int opcodeGetStandingActor = 0x200020e; const int opcodeGetStandingActorExplicit = 0x200020f; + const int opcodeGetWindSpeed = 0x2000212; const int opcodePlayBink = 0x20001f7; @@ -680,6 +691,7 @@ namespace MWScript extensions.registerInstruction ("fall", "", opcodeFall, opcodeFallExplicit); extensions.registerFunction ("getstandingpc", 'l', "", opcodeGetStandingPc, opcodeGetStandingPcExplicit); extensions.registerFunction ("getstandingactor", 'l', "", opcodeGetStandingActor, opcodeGetStandingActorExplicit); + extensions.registerFunction ("getwindspeed", 'f', "", opcodeGetWindSpeed); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -732,6 +744,7 @@ namespace MWScript interpreter.installSegment5 (opcodeGetStandingPcExplicit, new OpGetStandingPc); interpreter.installSegment5 (opcodeGetStandingActor, new OpGetStandingActor); interpreter.installSegment5 (opcodeGetStandingActorExplicit, new OpGetStandingActor); + interpreter.installSegment5 (opcodeGetWindSpeed, new OpGetWindSpeed); } } } diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index c940398fa..b6a649bcb 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -65,7 +65,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), mMonth(0), mDay(0), - mTimePassed(0), mFallback(fallback) + mTimePassed(0), mFallback(fallback), mWindSpeed(0.f) { mRendering = rendering; //Globals @@ -367,6 +367,8 @@ void WeatherManager::update(float duration) else result = getResult(mCurrentWeather); + mWindSpeed = result.mWindSpeed; + mRendering->configureFog(result.mFogDepth, result.mFogColor); // disable sun during night @@ -653,3 +655,8 @@ void WeatherManager::changeWeather(const std::string& region, const unsigned int if (Misc::StringUtils::ciEqual(region, playerRegion)) setWeather(weather); } + +float WeatherManager::getWindSpeed() const +{ + return mWindSpeed; +} diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index f8c85b1fe..a1dc45420 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -131,6 +131,8 @@ namespace MWWorld void setHour(const float hour); + float getWindSpeed() const; + void setDate(const int day, const int month); void advanceTime(double hours) @@ -143,6 +145,7 @@ namespace MWWorld private: float mHour; int mDay, mMonth; + float mWindSpeed; MWWorld::Fallback* mFallback; void setFallbackWeather(Weather& weather,const std::string& name); MWRender::RenderingManager* mRendering; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 3fb4ff8bd..403ce37bc 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1599,4 +1599,12 @@ namespace MWWorld { return mPhysEngine->isAnyActorStandingOn(object.getRefData().getBaseNode()->getName()); } + + float World::getWindSpeed() + { + if (isCellExterior() || isCellQuasiExterior()) + return mWeatherManager->getWindSpeed(); + else + return 0.f; + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index a4ae3adf4..b051e2b93 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -383,6 +383,7 @@ namespace MWWorld virtual bool getPlayerStandingOn (const MWWorld::Ptr& object); ///< @return true if the player is standing on \a object virtual bool getActorStandingOn (const MWWorld::Ptr& object); ///< @return true if any actor is standing on \a object + virtual float getWindSpeed(); virtual void setupExternalRendering (MWRender::ExternalRendering& rendering); From 236ec3409fc02a187830c2f4ae9b1cd664d9b991 Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 1 May 2013 12:21:59 +0200 Subject: [PATCH 07/19] Finished acrobatics --- apps/openmw/mwbase/world.hpp | 1 + apps/openmw/mwmechanics/character.cpp | 64 ++++++++++++++++----------- apps/openmw/mwmechanics/character.hpp | 3 +- apps/openmw/mwworld/worldimp.cpp | 7 +++ apps/openmw/mwworld/worldimp.hpp | 1 + libs/openengine/bullet/physic.cpp | 2 +- 6 files changed, 50 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index a3b9d2cf2..0cf71ed8e 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -314,6 +314,7 @@ namespace MWBase virtual bool isSwimming(const MWWorld::Ptr &object) const = 0; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; + virtual bool isGravity(const MWWorld::Ptr &ptr) const = 0; virtual void togglePOV() = 0; virtual void togglePreviewMode(bool enable) = 0; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 1b8ed0868..a24d7daeb 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -33,6 +33,7 @@ #include "../mwmechanics/stat.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" namespace MWMechanics { @@ -107,7 +108,7 @@ static void getStateInfo(CharacterState state, std::string *group) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), - mSecondsOfRunning(0), mSecondsOfSwimming(0), mHighestPosition(0) + mSecondsOfRunning(0), mSecondsOfSwimming(0), mFallDistance(0), mLastHeight(0) { if(!mAnimation) return; @@ -149,6 +150,7 @@ void CharacterController::update(float duration, Movement &movement) const MWWorld::Class &cls = MWWorld::Class::get(mPtr); bool onground = world->isOnGround(mPtr); + bool gravity = world->isGravity(mPtr); bool inwater = world->isSwimming(mPtr); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); @@ -156,9 +158,36 @@ void CharacterController::update(float duration, Movement &movement) const Ogre::Vector3 &rot = cls.getRotationVector(mPtr); speed = cls.getSpeed(mPtr); - //To calculate how much player will fall down - if(movement.mPosition[2] > mHighestPosition) - mHighestPosition = movement.mPosition[2]; + //player is falling down + if(!onground && gravity && mLastHeight>mPtr.getRefData().getPosition().pos[2]) + mFallDistance+=(mLastHeight-mPtr.getRefData().getPosition().pos[2]); + + //player just finished falling + if(onground && gravity && mFallDistance>0) + { + float healthLost = cls.getFallDamage(mPtr, mFallDistance); + + if(healthLost>0.0f) + { + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + int current = health.getCurrent(); + float realHealthLost = healthLost * (1.0f - (0.25 * 1.25f/*fatigueTerm*/)); + health.setModified (health.getModified()-static_cast(realHealthLost), 0); + health.setCurrent (current-static_cast(realHealthLost)); + cls.getCreatureStats(mPtr).setHealth (health); + MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + std::cout< 0 && mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) @@ -184,7 +213,7 @@ void CharacterController::update(float duration, Movement &movement) } // FIXME: X/Y movement should be disallowed except for the initial thrust (which would be carried by "physics" until landing). - if(onground && vec.z > 0.0f) + if(onground && gravity && vec.z > 0.0f) { //Advance acrobatics on jump, decrease fatigue if(getState()!=CharState_Jump) @@ -197,8 +226,8 @@ void CharacterController::update(float duration, Movement &movement) const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFatigueJumpMult")->getFloat(); DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); int current = fatigue.getCurrent(); - fatigue.setModified(fatigue.getModified()-(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0); - fatigue.setCurrent(current-(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult))); + fatigue.setModified(fatigue.getModified()-static_cast(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0); + fatigue.setCurrent(current-static_cast(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult))); cls.getCreatureStats(mPtr).setDynamic (2, fatigue); } @@ -216,25 +245,6 @@ void CharacterController::update(float duration, Movement &movement) } } - if(vec.z<=0.0f && getState()==CharState_Jump) - { - float healthLost = cls.getFallDamage(mPtr, mHighestPosition); - - if(healthLost>0.0f) - { - DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int fatigue = MWWorld::Class::get (mPtr).getCreatureStats (mPtr).getFatigue().getBase(); - int current = health.getCurrent(); - health.setModified (health.getModified()-(healthLost * (1 - (0.25 * fatigue))), 0); - health.setCurrent (current-(healthLost * (1 - (0.25 * fatigue)))); - cls.getCreatureStats(mPtr).setHealth (health); - MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); - } - - setState(CharState_Idle, true); - mHighestPosition=0; - } - if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f) { if(vec.x > 0.0f) @@ -299,6 +309,8 @@ void CharacterController::update(float duration, Movement &movement) movement.mPosition[2] += moved.z; } mSkipAnim = false; + + mLastHeight = mPtr.getRefData().getPosition().pos[2]; } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 460141880..ffe407731 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -83,7 +83,8 @@ class CharacterController float mSecondsOfSwimming; float mSecondsOfRunning; - float mHighestPosition; + float mFallDistance; + float mLastHeight; bool mMovingAnim; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a903369ee..6b8a225bb 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1492,6 +1492,13 @@ namespace MWWorld return physactor && physactor->getOnGround(); } + bool World::isGravity(const MWWorld::Ptr &ptr) const + { + RefData &refdata = ptr.getRefData(); + const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle()); + return physactor && physactor->getCollisionMode(); + } + bool World::vanityRotateCamera(float * rot) { return mRendering->vanityRotateCamera(rot); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f61f67062..5932b5478 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -346,6 +346,7 @@ namespace MWWorld virtual bool isSwimming(const MWWorld::Ptr &object) const; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const; virtual bool isOnGround(const MWWorld::Ptr &ptr) const; + virtual bool isGravity(const MWWorld::Ptr &ptr) const; virtual void togglePOV() { mRendering->togglePOV(); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index dbb42a645..9c1d3a530 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -143,7 +143,7 @@ namespace Physic bool PhysicActor::getOnGround() const { - return collisionMode && onGround; + return onGround; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// From b8630239d74e8495ba5945b127a410e142a92a12 Mon Sep 17 00:00:00 2001 From: Glorf Date: Wed, 1 May 2013 12:25:02 +0200 Subject: [PATCH 08/19] Code cleanup --- apps/openmw/mwmechanics/character.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index a24d7daeb..f3c862947 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -176,7 +176,6 @@ void CharacterController::update(float duration, Movement &movement) health.setCurrent (current-static_cast(realHealthLost)); cls.getCreatureStats(mPtr).setHealth (health); MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); - std::cout< Date: Wed, 1 May 2013 12:47:50 +0200 Subject: [PATCH 09/19] Insert records that may not exist in vanilla MW --- apps/openmw/mwclass/npc.cpp | 3 +-- apps/openmw/mwworld/esmstore.hpp | 19 ++++++++++++++++ apps/openmw/mwworld/globals.cpp | 9 -------- apps/openmw/mwworld/store.hpp | 15 ++++++++++++ apps/openmw/mwworld/worldimp.cpp | 39 ++++++++++++++++++++++++++++++++ apps/openmw/mwworld/worldimp.hpp | 4 +++- 6 files changed, 77 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ea49ae4a4..d0f1bcfeb 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -137,8 +137,7 @@ namespace MWClass fJumpAcrobaticsBase = gmst.find("fJumpAcrobaticsBase"); fJumpAcroMultiplier = gmst.find("fJumpAcroMultiplier"); fJumpRunMultiplier = gmst.find("fJumpRunMultiplier"); - // Added in Tribunal/Bloodmoon, may not exist - fWereWolfRunMult = gmst.search("fWereWolfRunMult"); + fWereWolfRunMult = gmst.find("fWereWolfRunMult"); inited = true; } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 61a106e16..cde9e2425 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -171,6 +171,25 @@ namespace MWWorld return ptr; } + template + const T *insertStatic(const T &x) { + Store &store = const_cast &>(get()); + if (store.search(x.mId) != 0) { + std::ostringstream msg; + msg << "Try to override existing record '" << x.mId << "'"; + throw std::runtime_error(msg.str()); + } + T record = x; + + T *ptr = store.insertStatic(record); + for (iterator it = mStores.begin(); it != mStores.end(); ++it) { + if (it->second == &store) { + mIds[ptr->mId] = it->first; + } + } + return ptr; + } + // This method must be called once, after loading all master/plugin files. This can only be done // from the outside, so it must be public. void setUp(); diff --git a/apps/openmw/mwworld/globals.cpp b/apps/openmw/mwworld/globals.cpp index 72bebc049..a905f8aae 100644 --- a/apps/openmw/mwworld/globals.cpp +++ b/apps/openmw/mwworld/globals.cpp @@ -74,15 +74,6 @@ namespace MWWorld mVariables.insert (std::make_pair (iter->mId, std::make_pair (type, value))); } - - if (mVariables.find ("dayspassed")==mVariables.end()) - { - // vanilla Morrowind does not define dayspassed. - Data value; - value.mLong = 1; // but the addons start counting at 1 :( - - mVariables.insert (std::make_pair ("dayspassed", std::make_pair ('l', value))); - } } const Globals::Data& Globals::operator[] (const std::string& name) const diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 7949cbe00..65041e662 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -92,6 +92,7 @@ namespace MWWorld std::map mDynamic; typedef std::map Dynamic; + typedef std::map Static; friend class ESMStore; @@ -183,6 +184,20 @@ namespace MWWorld return ptr; } + T *insertStatic(const T &item) { + std::string id = Misc::StringUtils::lowerCase(item.mId); + std::pair result = + mStatic.insert(std::pair(id, item)); + T *ptr = &result.first->second; + if (result.second) { + mShared.push_back(ptr); + } else { + *ptr = item; + } + return ptr; + } + + bool eraseStatic(const std::string &id) { T item; item.mId = Misc::StringUtils::lowerCase(id); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9a08a1635..513c78482 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -211,6 +211,10 @@ namespace MWWorld mStore.load (mEsm[idx]); } + // insert records that may not be present in all versions of MW + if (mEsm[0].getFormat() == 0) + ensureNeededRecords(); + mStore.setUp(); // global variables @@ -230,6 +234,41 @@ namespace MWWorld } + void World::ensureNeededRecords() + { + if (!mStore.get().search("sCompanionShare")) + { + ESM::GameSetting sCompanionShare; + sCompanionShare.mId = "sCompanionShare"; + ESM::Variant value; + value.setType(ESM::VT_String); + value.setString("Companion Share"); + sCompanionShare.mValue = value; + mStore.insertStatic(sCompanionShare); + } + if (!mStore.get().search("dayspassed")) + { + // vanilla Morrowind does not define dayspassed. + ESM::Global dayspassed; + dayspassed.mId = "dayspassed"; + ESM::Variant value; + value.setType(ESM::VT_Long); + value.setInteger(1); // but the addons start counting at 1 :( + dayspassed.mValue = value; + mStore.insertStatic(dayspassed); + } + if (!mStore.get().search("fWereWolfRunMult")) + { + ESM::GameSetting fWereWolfRunMult; + fWereWolfRunMult.mId = "fWereWolfRunMult"; + ESM::Variant value; + value.setType(ESM::VT_Float); + value.setFloat(1.f); + fWereWolfRunMult.mValue = value; + mStore.insertStatic(fWereWolfRunMult); + } + } + World::~World() { delete mWeatherManager; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f61f67062..b55507729 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -115,9 +115,11 @@ namespace MWWorld void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell); void PCDropped (const Ptr& item); - virtual void processDoors(float duration); + void processDoors(float duration); ///< Run physics simulation and modify \a world accordingly. + void ensureNeededRecords(); + public: World (OEngine::Render::OgreRenderer& renderer, From 63407a662cdeea56216d589b9f82644dd04e1e8e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 1 May 2013 14:08:05 +0200 Subject: [PATCH 10/19] allow <== and >== as alternative for <= and >= in scripts --- components/compiler/scanner.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/compiler/scanner.cpp b/components/compiler/scanner.cpp index 38a9265a1..a547e6ec5 100644 --- a/components/compiler/scanner.cpp +++ b/components/compiler/scanner.cpp @@ -428,7 +428,12 @@ namespace Compiler if (get (c)) { if (c=='=') + { special = S_cmpLE; + + if (get (c) && c!='=') // <== is a allowed as an alternative to <= :( + putback (c); + } else { putback (c); @@ -443,7 +448,12 @@ namespace Compiler if (get (c)) { if (c=='=') + { special = S_cmpGE; + + if (get (c) && c!='=') // >== is a allowed as an alternative to >= :( + putback (c); + } else { putback (c); From fe038cef03453b4296378772f9e16dda9dbd5037 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 1 May 2013 14:20:09 +0200 Subject: [PATCH 11/19] turned redeclartion of local variables from an error into a warning --- components/compiler/lineparser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 210d18dc9..5a22309f9 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -98,10 +98,12 @@ namespace Compiler if (type!=' ') { - getErrorHandler().error ("catoLowern't re-declare local variable", loc); + /// \todo add option to make re-declared local variables an error + getErrorHandler().warning ("can't re-declare local variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); - return false; + mState = EndState; + return true; } mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'), From 1acfd849a2dc14ef9c9e066840448293627ab055 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 1 May 2013 16:38:16 +0200 Subject: [PATCH 12/19] Fix a case folding bug --- apps/openmw/mwworld/cells.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 87ac1c6d7..efabe2f63 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -11,11 +11,11 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) { if (cell->mData.mFlags & ESM::Cell::Interior) { - std::map::iterator result = mInteriors.find (cell->mName); + std::map::iterator result = mInteriors.find (Misc::StringUtils::lowerCase(cell->mName)); if (result==mInteriors.end()) { - result = mInteriors.insert (std::make_pair (cell->mName, Ptr::CellStore (cell))).first; + result = mInteriors.insert (std::make_pair (Misc::StringUtils::lowerCase(cell->mName), Ptr::CellStore (cell))).first; } return &result->second; From 95eeea2a271870e83885c4364435039b31ab3710 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 1 May 2013 16:56:16 +0200 Subject: [PATCH 13/19] Revert "Merge remote-tracking branch 'glorf/acrobatics'" This reverts commit 089ef7a2a02d62c1bdaf3fa0fda470189f5182bb, reversing changes made to 67422c397c883017b4ff6a7adfb405cdf767f807. --- apps/openmw/mwbase/world.hpp | 1 - apps/openmw/mwclass/npc.cpp | 28 ------------ apps/openmw/mwclass/npc.hpp | 3 -- apps/openmw/mwmechanics/character.cpp | 62 +++------------------------ apps/openmw/mwmechanics/character.hpp | 3 -- apps/openmw/mwworld/class.cpp | 5 --- apps/openmw/mwworld/class.hpp | 3 -- apps/openmw/mwworld/worldimp.cpp | 7 --- apps/openmw/mwworld/worldimp.hpp | 1 - libs/openengine/bullet/physic.cpp | 2 +- 10 files changed, 7 insertions(+), 108 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index d807a823b..6c9fa6703 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -314,7 +314,6 @@ namespace MWBase virtual bool isSwimming(const MWWorld::Ptr &object) const = 0; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; - virtual bool isGravity(const MWWorld::Ptr &ptr) const = 0; virtual void togglePOV() = 0; virtual void togglePreviewMode(bool enable) = 0; diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index cfcecc793..d0f1bcfeb 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -469,34 +469,6 @@ namespace MWClass return x; } - float Npc::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const - { - const float fallDistanceMin = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallDamageDistanceMin")->getFloat(); - - if(fallHeight>=fallDistanceMin) - { - const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill (ESM::Skill::Acrobatics).getModified(); - const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); - const float jumpSpellBonus = npcdata->mCreatureStats.getMagicEffects().get(MWMechanics::EffectKey(9/*jump*/)).mMagnitude; - const float fallAcroBase = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallAcroBase")->getFloat(); - const float fallAcroMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallAcroMult")->getFloat(); - const float fallDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallDistanceBase")->getFloat(); - const float fallDistanceMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFallDistanceMult")->getFloat(); - - float x = fallHeight - fallDistanceMin; - x -= (1.5 * acrobaticsSkill) + jumpSpellBonus; - x = std::max(0.0f, x); - - float a = fallAcroBase + (fallAcroMult * (100 - acrobaticsSkill)); - x = fallDistanceBase + (fallDistanceMult * x); - x *= a; - - return x; - } - - return 0; - } - MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const { ensureCustomData (ptr); diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 47d32d88f..d1a9158fd 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -91,9 +91,6 @@ namespace MWClass virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) - virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; - ///< Return amount of health points lost when falling - virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const; ///< Return desired movement. diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f3c862947..b82fc4dc5 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -31,9 +31,6 @@ #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" -#include "../mwmechanics/stat.hpp" -#include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/npcstats.hpp" namespace MWMechanics { @@ -107,8 +104,7 @@ static void getStateInfo(CharacterState state, std::string *group) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) - : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), - mSecondsOfRunning(0), mSecondsOfSwimming(0), mFallDistance(0), mLastHeight(0) + : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), mSecondsOfRunning(0), mSecondsOfSwimming(0) { if(!mAnimation) return; @@ -150,7 +146,6 @@ void CharacterController::update(float duration, Movement &movement) const MWWorld::Class &cls = MWWorld::Class::get(mPtr); bool onground = world->isOnGround(mPtr); - bool gravity = world->isGravity(mPtr); bool inwater = world->isSwimming(mPtr); bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); @@ -158,36 +153,6 @@ void CharacterController::update(float duration, Movement &movement) const Ogre::Vector3 &rot = cls.getRotationVector(mPtr); speed = cls.getSpeed(mPtr); - //player is falling down - if(!onground && gravity && mLastHeight>mPtr.getRefData().getPosition().pos[2]) - mFallDistance+=(mLastHeight-mPtr.getRefData().getPosition().pos[2]); - - //player just finished falling - if(onground && gravity && mFallDistance>0) - { - float healthLost = cls.getFallDamage(mPtr, mFallDistance); - - if(healthLost>0.0f) - { - DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - int current = health.getCurrent(); - float realHealthLost = healthLost * (1.0f - (0.25 * 1.25f/*fatigueTerm*/)); - health.setModified (health.getModified()-static_cast(realHealthLost), 0); - health.setCurrent (current-static_cast(realHealthLost)); - cls.getCreatureStats(mPtr).setHealth (health); - MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); - - const float acrobaticsSkill = cls.getNpcStats (mPtr).getSkill (ESM::Skill::Acrobatics).getModified(); - if(acrobaticsSkill*1.25f/*fatigueTerm*/ 0 && mPtr == MWBase::Environment::get().getWorld()->getPlayer().getPlayer()) { @@ -211,25 +176,10 @@ void CharacterController::update(float duration, Movement &movement) } } - // FIXME: X/Y movement should be disallowed except for the initial thrust (which would be carried by "physics" until landing). - if(onground && gravity && vec.z > 0.0f) + /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except + * for the initial thrust (which would be carried by "physics" until landing). */ + if(onground && vec.z > 0.0f) { - //Advance acrobatics on jump, decrease fatigue - if(getState()!=CharState_Jump) - { - setState(CharState_Jump, true); - MWWorld::Class::get(mPtr).skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 0); - - const float normalizedEncumbrance = cls.getEncumbrance(mPtr) / cls.getCapacity(mPtr); - const float fatigueJumpBase = MWBase::Environment::get().getWorld()->getStore().get().find ("fFatigueJumpBase")->getFloat(); - const float fatigueJumpMult = MWBase::Environment::get().getWorld()->getStore().get().find ("fFatigueJumpMult")->getFloat(); - DynamicStat fatigue = cls.getCreatureStats(mPtr).getDynamic(2); - int current = fatigue.getCurrent(); - fatigue.setModified(fatigue.getModified()-static_cast(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult)), 0); - fatigue.setCurrent(current-static_cast(fatigueJumpBase + ((1 - normalizedEncumbrance) * fatigueJumpMult))); - cls.getCreatureStats(mPtr).setDynamic (2, fatigue); - } - float x = cls.getJump(mPtr); if(vec.x == 0 && vec.y == 0) @@ -242,6 +192,8 @@ void CharacterController::update(float duration, Movement &movement) //movement += Ogre::Vector3(lat.x, lat.y, 1.0f) * x * 0.707f * duration; movement.mPosition[2] += x * 0.707f * duration; } + + //decrease fatigue by fFatigueJumpBase + (1 - normalizedEncumbrance) * fFatigueJumpMult; } if(std::abs(vec.x/2.0f) > std::abs(vec.y) && speed > 0.0f) @@ -308,8 +260,6 @@ void CharacterController::update(float duration, Movement &movement) movement.mPosition[2] += moved.z; } mSkipAnim = false; - - mLastHeight = mPtr.getRefData().getPosition().pos[2]; } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index ffe407731..4ee217d11 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -83,9 +83,6 @@ class CharacterController float mSecondsOfSwimming; float mSecondsOfRunning; - float mFallDistance; - float mLastHeight; - bool mMovingAnim; public: diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index db798537e..03a55c7f0 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -132,11 +132,6 @@ namespace MWWorld return 0; } - float Class::getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const - { - return 0; - } - float Class::getEnchantmentPoints (const MWWorld::Ptr& ptr) const { throw std::runtime_error ("class does not support enchanting"); diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 3901ea830..e203fedc3 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -146,9 +146,6 @@ namespace MWWorld virtual float getJump(const MWWorld::Ptr &ptr) const; ///< Return jump velocity (not accounting for movement) - virtual float getFallDamage(const MWWorld::Ptr &ptr, float fallHeight) const; - ///< Return amount of health points lost when falling - virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const; ///< Return desired movement. diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 4bbf505e4..d2a6d9af6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1532,13 +1532,6 @@ namespace MWWorld return physactor && physactor->getOnGround(); } - bool World::isGravity(const MWWorld::Ptr &ptr) const - { - RefData &refdata = ptr.getRefData(); - const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle()); - return physactor && physactor->getCollisionMode(); - } - bool World::vanityRotateCamera(float * rot) { return mRendering->vanityRotateCamera(rot); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 62d01585a..dadb701f5 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -348,7 +348,6 @@ namespace MWWorld virtual bool isSwimming(const MWWorld::Ptr &object) const; virtual bool isUnderwater(const MWWorld::Ptr::CellStore* cell, const Ogre::Vector3 &pos) const; virtual bool isOnGround(const MWWorld::Ptr &ptr) const; - virtual bool isGravity(const MWWorld::Ptr &ptr) const; virtual void togglePOV() { mRendering->togglePOV(); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index b024dd5c6..2b59e0aad 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -143,7 +143,7 @@ namespace Physic bool PhysicActor::getOnGround() const { - return onGround; + return collisionMode && onGround; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 28ef4d97da898eb9708922e5947c0ec10fd04984 Mon Sep 17 00:00:00 2001 From: kpp Date: Thu, 2 May 2013 07:35:25 +0400 Subject: [PATCH 14/19] Fixes Bug #734 'Book empty line problem' Hides buttons 'Next' and 'Prev' at the last and at the first page --- apps/openmw/mwgui/bookwindow.cpp | 17 ++++++++- apps/openmw/mwgui/formatting.cpp | 58 +++++++++++++++++++++++++----- apps/openmw/mwgui/formatting.hpp | 11 +++++- apps/openmw/mwgui/scrollwindow.cpp | 2 +- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 6d44e9d2c..12e5b466b 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -76,7 +76,7 @@ namespace MWGui parent = mRightPage; MyGUI::Widget* pageWidget = parent->createWidgetReal("", MyGUI::FloatCoord(0.0,0.0,1.0,1.0), MyGUI::Align::Default, "BookPage" + boost::lexical_cast(i)); - parser.parse(*it, pageWidget, mLeftPage->getSize().width); + parser.parsePage(*it, pageWidget, mLeftPage->getSize().width); mPages.push_back(pageWidget); ++i; } @@ -157,6 +157,21 @@ namespace MWGui } ++i; } + + //If it is the last page, hide the button "Next Page" + if ( (mCurrentPage+1)*2 == mPages.size() + || (mCurrentPage+1)*2 == mPages.size() + 1) + { + mNextPageButton->setVisible(false); + } else { + mNextPageButton->setVisible(true); + } + //If it is the fist page, hide the button "Prev Page" + if (mCurrentPage == 0) { + mPrevPageButton->setVisible(false); + } else { + mPrevPageButton->setVisible(true); + } } } diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index 2d72f2174..6f1e16ff1 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -6,7 +6,10 @@ #include #include +#include #include +#include +#include #include namespace @@ -74,6 +77,12 @@ namespace Ogre::UTFString string(s); return string.getChar(0); } + + bool is_not_empty(const std::string s) { + std::string temp = s; + boost::algorithm::trim(temp); + return !temp.empty(); + } } namespace MWGui @@ -88,6 +97,7 @@ namespace MWGui utf8Text = Interpreter::fixDefinesBook(utf8Text, interpreterContext); boost::algorithm::replace_all(utf8Text, "\n", ""); + boost::algorithm::replace_all(utf8Text, "\r", ""); boost::algorithm::replace_all(utf8Text, "
", "\n"); boost::algorithm::replace_all(utf8Text, "

", "\n\n"); @@ -106,6 +116,14 @@ namespace MWGui size_t currentWordStart = 0; size_t index = 0; + + { + std::string texToTrim = text.asUTF8(); + boost::algorithm::trim( texToTrim ); + text = UTFString(texToTrim); + } + + while (currentHeight <= height - spacing && index < text.size()) { const UTFString::unicode_char ch = text.getChar(index); @@ -176,8 +194,10 @@ namespace MWGui result.push_back(text.substr(0, pageEnd).asUTF8()); text.erase(0, pageEnd); } - - return result; + + std::vector nonEmptyPages; + boost::copy(result | boost::adaptors::filtered(is_not_empty), std::back_inserter(nonEmptyPages)); + return nonEmptyPages; } float BookTextParser::widthForCharGlyph(unsigned unicodeChar) const @@ -193,7 +213,30 @@ namespace MWGui return MyGUI::FontManager::getInstance().getByName(fontName)->getDefaultHeight(); } - MyGUI::IntSize BookTextParser::parse(std::string text, MyGUI::Widget* parent, const int width) + MyGUI::IntSize BookTextParser::parsePage(std::string text, MyGUI::Widget* parent, const int width) + { + MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor + text = Interpreter::fixDefinesBook(text, interpreterContext); + + mParent = parent; + mWidth = width; + mHeight = 0; + + assert(mParent); + while (mParent->getChildCount()) + { + MyGUI::Gui::getInstance().destroyWidget(mParent->getChildAt(0)); + } + + // remove trailing " + if (text[text.size()-1] == '\"') + text.erase(text.size()-1); + + parseSubText(text); + return MyGUI::IntSize(mWidth, mHeight); + } + + MyGUI::IntSize BookTextParser::parseScroll(std::string text, MyGUI::Widget* parent, const int width) { MWScript::InterpreterContext interpreterContext(NULL, MWWorld::Ptr()); // empty arguments, because there is no locals or actor text = Interpreter::fixDefinesBook(text, interpreterContext); @@ -209,12 +252,10 @@ namespace MWGui } boost::algorithm::replace_all(text, "\n", ""); + boost::algorithm::replace_all(text, "\r", ""); boost::algorithm::replace_all(text, "
", "\n"); boost::algorithm::replace_all(text, "

", "\n\n"); - - // remove leading newlines - // while (text[0] == '\n') - // text.erase(0); + boost::algorithm::trim_left(text); // remove trailing " if (text[text.size()-1] == '\"') @@ -223,6 +264,7 @@ namespace MWGui parseSubText(text); return MyGUI::IntSize(mWidth, mHeight); } + void BookTextParser::parseImage(std::string tag, bool createWidget) { @@ -309,7 +351,7 @@ namespace MWGui parseImage(tag); if (boost::algorithm::starts_with(tag, "FONT")) parseFont(tag); - if (boost::algorithm::starts_with(tag, "DOV")) + if (boost::algorithm::starts_with(tag, "DIV")) parseDiv(tag); text.erase(0, tagEnd + 1); diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index ab1ee3af4..a32d98fe5 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -32,7 +32,16 @@ namespace MWGui * @param maximum width * @return size of the created widgets */ - MyGUI::IntSize parse(std::string text, MyGUI::Widget* parent, const int width); + MyGUI::IntSize parsePage(std::string text, MyGUI::Widget* parent, const int width); + + /** + * Parse markup as MyGUI widgets + * @param markup to parse + * @param parent for the created widgets + * @param maximum width + * @return size of the created widgets + */ + MyGUI::IntSize parseScroll(std::string text, MyGUI::Widget* parent, const int width); /** * Split the specified text into pieces that fit in the area specified by width and height parameters diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index 95bf17635..b44c21c6e 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -39,7 +39,7 @@ namespace MWGui MWWorld::LiveCellRef *ref = mScroll.get(); BookTextParser parser; - MyGUI::IntSize size = parser.parse(ref->mBase->mText, mTextView, 390); + MyGUI::IntSize size = parser.parseScroll(ref->mBase->mText, mTextView, 390); if (size.height > mTextView->getSize().height) mTextView->setCanvasSize(MyGUI::IntSize(410, size.height)); From f1a659e2acb859e4a28ef120c180d4cf96b89cb0 Mon Sep 17 00:00:00 2001 From: Glorf Date: Thu, 2 May 2013 14:49:30 +0200 Subject: [PATCH 15/19] Bugfix #730 --- files/mygui/openmw_settings_window.layout | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 693c5a9cb..77d14d0f6 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -16,7 +16,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -65,35 +65,35 @@ - + - + - + - + - + @@ -118,7 +118,7 @@ - + @@ -134,7 +134,7 @@ - + @@ -199,7 +199,7 @@ - + @@ -224,7 +224,7 @@ - + @@ -232,7 +232,7 @@ - + From dcccfd9f22bff4d6e34ca5fbcb291df1fe486d0f Mon Sep 17 00:00:00 2001 From: kpp Date: Thu, 2 May 2013 22:43:21 +0400 Subject: [PATCH 16/19] Initialize values --- apps/openmw/mwgui/loadingscreen.cpp | 1 + apps/openmw/mwmechanics/character.cpp | 9 ++++++++- apps/openmw/mwrender/water.hpp | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 3b341574d..018f51feb 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -22,6 +22,7 @@ namespace MWGui , mLastRenderTime(0.f) , mLastWallpaperChangeTime(0.f) , mFirstLoad(true) + , mTotalRefsLoading(0) { getWidget(mLoadingText, "LoadingText"); getWidget(mProgressBar, "ProgressBar"); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index b82fc4dc5..24a8e53ee 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -104,7 +104,14 @@ static void getStateInfo(CharacterState state, std::string *group) CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state, bool loop) - : mPtr(ptr), mAnimation(anim), mCharState(state), mSkipAnim(false), mMovingAnim(false), mSecondsOfRunning(0), mSecondsOfSwimming(0) + : mPtr(ptr) + , mAnimation(anim) + , mCharState(state) + , mSkipAnim(false) + , mMovingAnim(false) + , mSecondsOfRunning(0) + , mSecondsOfSwimming(0) + , mLooping(false) { if(!mAnimation) return; diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 6c0323637..a21d03ad6 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -41,7 +41,9 @@ namespace MWRender { { public: Reflection(Ogre::SceneManager* sceneManager) - : mSceneMgr(sceneManager) {} + : mSceneMgr(sceneManager) + , mIsUnderwater(false) + {} virtual ~Reflection() {} virtual void setHeight (float height) {} From a8b17066783fd9e3f1297d411723b9aa5d9a9784 Mon Sep 17 00:00:00 2001 From: greye Date: Fri, 3 May 2013 10:51:42 +0400 Subject: [PATCH 17/19] init pointer value to prevent segfault --- apps/openmw/mwrender/terrainmaterial.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index b9c055acd..892dab7cf 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -49,6 +49,7 @@ namespace MWRender TerrainMaterial::Profile::Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc) : Ogre::TerrainMaterialGenerator::Profile(parent, name, desc) , mGlobalColourMap(false) + , mMaterial(0) { } From 57f22c77c00b59a27dcc825524a55fa6e75b2bb4 Mon Sep 17 00:00:00 2001 From: Glorf Date: Fri, 3 May 2013 12:44:27 +0200 Subject: [PATCH 18/19] Bugfix #732 part 1 --- apps/openmw/mwbase/windowmanager.hpp | 2 ++ apps/openmw/mwgui/messagebox.cpp | 14 ++++++++++++-- apps/openmw/mwgui/messagebox.hpp | 4 +++- apps/openmw/mwgui/settingswindow.cpp | 4 +++- apps/openmw/mwgui/windowmanagerimp.cpp | 10 ++++++++++ apps/openmw/mwgui/windowmanagerimp.hpp | 2 ++ apps/openmw/mwinput/inputmanagerimp.cpp | 4 ++++ 7 files changed, 36 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 976d7d84c..1832bf542 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -201,6 +201,8 @@ namespace MWBase ///< Hides dialog and schedules dialog to be deleted. virtual void messageBox (const std::string& message, const std::vector& buttons = std::vector()) = 0; + virtual void staticMessageBox(const std::string& message) = 0; + virtual void removeStaticMessageBox() = 0; virtual void enterPressed () = 0; virtual int readPressedButton() = 0; diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 876fb3522..2fc50f257 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -13,6 +13,7 @@ namespace MWGui // defines mMessageBoxSpeed = 0.1; mInterMessageBoxe = NULL; + mStaticMessageBox = NULL; } void MessageBoxManager::onFrame (float frameDuration) @@ -68,11 +69,14 @@ namespace MWGui } } - void MessageBoxManager::createMessageBox (const std::string& message) + void MessageBoxManager::createMessageBox (const std::string& message, bool stat) { MessageBox *box = new MessageBox(*this, message); - removeMessageBox(message.length()*mMessageBoxSpeed, box); + if(stat) + mStaticMessageBox = box; + else + removeMessageBox(message.length()*mMessageBoxSpeed, box); mMessageBoxes.push_back(box); std::vector::iterator it; @@ -90,6 +94,12 @@ namespace MWGui } } + void MessageBoxManager::removeStaticMessageBox () + { + removeMessageBox(mStaticMessageBox); + mStaticMessageBox = NULL; + } + bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector& buttons) { if(mInterMessageBoxe != NULL) { diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 0df6f3544..0e47b0323 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -31,7 +31,8 @@ namespace MWGui public: MessageBoxManager (); void onFrame (float frameDuration); - void createMessageBox (const std::string& message); + void createMessageBox (const std::string& message, bool stat = false); + void removeStaticMessageBox (); bool createInteractiveMessageBox (const std::string& message, const std::vector& buttons); bool isInteractiveMessageBox (); @@ -52,6 +53,7 @@ namespace MWGui private: std::vector mMessageBoxes; InteractiveMessageBox* mInterMessageBoxe; + MessageBox* mStaticMessageBox; std::vector mTimers; float mMessageBoxSpeed; }; diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 39ee4e01d..413171dd4 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -551,6 +551,8 @@ namespace MWGui while (mControlsBox->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mControlsBox->getChildAt(0)); + MWBase::Environment::get().getWindowManager ()->removeStaticMessageBox(); + std::vector actions = MWBase::Environment::get().getInputManager()->getActionSorting (); const int h = 18; @@ -585,7 +587,7 @@ namespace MWGui static_cast(_sender)->setCaptionWithReplacing("#{sNone}"); - MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}"); + MWBase::Environment::get().getWindowManager ()->staticMessageBox ("#{sControlsMenu3}"); MWBase::Environment::get().getWindowManager ()->disallowMouse(); MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index ff83f5f67..be947cb8a 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -600,6 +600,16 @@ namespace MWGui } } + void WindowManager::staticMessageBox(const std::string& message) + { + mMessageBoxManager->createMessageBox(message, true); + } + + void WindowManager::removeStaticMessageBox() + { + mMessageBoxManager->removeStaticMessageBox(); + } + void WindowManager::enterPressed () { mMessageBoxManager->enterPressed(); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index acac77bf3..f3413ca2f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -192,6 +192,8 @@ namespace MWGui virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted. virtual void messageBox (const std::string& message, const std::vector& buttons = std::vector()); + virtual void staticMessageBox(const std::string& message); + virtual void removeStaticMessageBox(); virtual void enterPressed (); virtual int readPressedButton (); ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 1cd716413..01ef36177 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -917,6 +917,10 @@ namespace MWInput void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction) { + //Disallow binding escape key + if(key==OIS::KC_ESCAPE) + return + clearAllBindings(control); ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction); MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); From 517dfb4d75b28899c08dbdb48db5542f8c865aa1 Mon Sep 17 00:00:00 2001 From: Glorf Date: Fri, 3 May 2013 13:24:34 +0200 Subject: [PATCH 19/19] Bugfix #732 part 2 --- apps/openmw/mwinput/inputmanagerimp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 01ef36177..a7ec4d4d2 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -917,8 +917,8 @@ namespace MWInput void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction) { - //Disallow binding escape key - if(key==OIS::KC_ESCAPE) + //Disallow binding escape key, and unassigned keys + if(key==OIS::KC_ESCAPE || key==OIS::KC_UNASSIGNED) return clearAllBindings(control);