Merge pull request #124 from OpenMW/master

Add OpenMW commits up to 11 Jan
pull/133/head
David Cernat 8 years ago committed by GitHub
commit dfb87e9e0d

@ -71,6 +71,7 @@ Programmers
John Blomberg (fstp)
Jordan Ayers
Jordan Milne
Jules Blok (Armada651)
Julien Voisin (jvoisin/ap0)
Karl-Felix Glatzer (k1ll)
Kevin Poitra (PuppyKevin)
@ -80,6 +81,7 @@ Programmers
lazydev
Leon Krieg (lkrieg)
Leon Saunders (emoose)
logzero
lohikaarme
Lukasz Gromanowski (lgro)
Manuel Edelmann (vorenon)

@ -7,5 +7,5 @@ brew rm pkgconfig || true
brew rm qt5 || true
brew install cmake pkgconfig $macos_qt_formula
curl http://downloads.openmw.org/osx/dependencies/openmw-deps-263d4a8.zip -o ~/openmw-deps.zip
curl https://downloads.openmw.org/osx/dependencies/openmw-deps-0ecece4.zip -o ~/openmw-deps.zip
unzip ~/openmw-deps.zip -d /private/tmp/openmw-deps > /dev/null

@ -164,7 +164,7 @@ namespace MWClass
getContainerStore(ptr).fill(ref->mBase->mInventory, ptr.getCellRef().getRefId());
if (hasInventory)
getInventoryStore(ptr).autoEquip(ptr);
getInventoryStore(ptr).autoEquipShield(ptr);
}
}

@ -448,14 +448,14 @@ namespace MWDialogue
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
// Clamp permanent disposition change so that final disposition doesn't go below 0 (could happen with intimidate)
float curDisp = static_cast<float>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false));
if (curDisp + mPermanentDispositionChange < 0)
mPermanentDispositionChange = -curDisp;
// Apply disposition change to NPC's base disposition
if (mActor.getClass().isNpc())
{
// Clamp permanent disposition change so that final disposition doesn't go below 0 (could happen with intimidate)
float curDisp = static_cast<float>(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false));
if (curDisp + mPermanentDispositionChange < 0)
mPermanentDispositionChange = -curDisp;
MWMechanics::NpcStats& npcStats = mActor.getClass().getNpcStats(mActor);
npcStats.setBaseDisposition(static_cast<int>(npcStats.getBaseDisposition() + mPermanentDispositionChange));
}

@ -34,6 +34,7 @@
#include "movement.hpp"
#include "character.hpp"
#include "aicombat.hpp"
#include "aicombataction.hpp"
#include "aifollow.hpp"
#include "aipursue.hpp"
#include "actor.hpp"
@ -291,10 +292,12 @@ namespace MWMechanics
void Actors::engageCombat (const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, bool againstPlayer)
{
CreatureStats& creatureStats = actor1.getClass().getCreatureStats(actor1);
const CreatureStats& creatureStats1 = actor1.getClass().getCreatureStats(actor1);
if (creatureStats1.getAiSequence().isInCombat(actor2))
return;
if (actor2.getClass().getCreatureStats(actor2).isDead()
|| actor1.getClass().getCreatureStats(actor1).isDead())
const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
if (creatureStats1.isDead() || creatureStats2.isDead())
return;
const ESM::Position& actor1Pos = actor1.getRefData().getPosition();
@ -303,55 +306,26 @@ namespace MWMechanics
if (sqrDist > sqrAiProcessingDistance)
return;
// pure water creatures won't try to fight with the target on the ground
// except that creature is already hostile
if ((againstPlayer || !creatureStats.getAiSequence().isInCombat())
&& !MWMechanics::isEnvironmentCompatible(actor1, actor2)) // creature can't swim to target
{
return;
}
// no combat for totally static creatures (they have no movement or attack animations anyway)
// No combat for totally static creatures
if (!actor1.getClass().isMobile(actor1))
return;
bool aggressive;
if (againstPlayer)
{
// followers with high fight should not engage in combat with the player (e.g. bm_bear_black_summon)
const std::list<MWWorld::Ptr>& followers = getActorsSidingWith(actor2);
if (std::find(followers.begin(), followers.end(), actor1) != followers.end())
return;
aggressive = MWBase::Environment::get().getMechanicsManager()->isAggressive(actor1, actor2);
}
else
{
aggressive = false;
// Make guards fight aggressive creatures
if (!actor1.getClass().isNpc() && actor2.getClass().isClass(actor2, "Guard"))
{
if (creatureStats.getAiSequence().isInCombat() && MWBase::Environment::get().getMechanicsManager()->isAggressive(actor1, actor2))
aggressive = true;
}
}
// start combat if target actor is in combat with one of our followers
const std::list<MWWorld::Ptr>& followers = getActorsSidingWith(actor1);
const CreatureStats& creatureStats2 = actor2.getClass().getCreatureStats(actor2);
for (std::list<MWWorld::Ptr>::const_iterator it = followers.begin(); it != followers.end(); ++it)
// Start combat if target actor is in combat with one of our followers or escorters
const std::list<MWWorld::Ptr>& followersAndEscorters = getActorsSidingWith(actor1);
for (std::list<MWWorld::Ptr>::const_iterator it = followersAndEscorters.begin(); it != followersAndEscorters.end(); ++it)
{
// need to check both ways since player doesn't use AI packages
// Need to check both ways since player doesn't use AI packages
if ((creatureStats2.getAiSequence().isInCombat(*it)
|| it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(actor2))
&& !creatureStats.getAiSequence().isInCombat(*it))
aggressive = true;
&& !creatureStats1.getAiSequence().isInCombat(*it))
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
return;
}
}
// start combat if target actor is in combat with someone we are following
for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats.getAiSequence().begin(); it != creatureStats.getAiSequence().end(); ++it)
// Start combat if target actor is in combat with someone we are following through a follow package
for (std::list<MWMechanics::AiPackage*>::const_iterator it = creatureStats1.getAiSequence().begin(); it != creatureStats1.getAiSequence().end(); ++it)
{
if (!(*it)->sideWithTarget())
continue;
@ -361,20 +335,63 @@ namespace MWMechanics
if (followTarget.isEmpty())
continue;
if (creatureStats.getAiSequence().isInCombat(followTarget))
if (creatureStats1.getAiSequence().isInCombat(followTarget))
continue;
// need to check both ways since player doesn't use AI packages
// Need to check both ways since player doesn't use AI packages
if (creatureStats2.getAiSequence().isInCombat(followTarget)
|| followTarget.getClass().getCreatureStats(followTarget).getAiSequence().isInCombat(actor2))
aggressive = true;
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
return;
}
}
// Start combat with the player if we are already in combat with a player follower or escorter
const std::list<MWWorld::Ptr>& playerFollowersAndEscorters = getActorsSidingWith(getPlayer());
if (againstPlayer)
{
for (std::list<MWWorld::Ptr>::const_iterator it = playerFollowersAndEscorters.begin(); it != playerFollowersAndEscorters.end(); ++it)
{
if (creatureStats1.getAiSequence().isInCombat(*it))
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
return;
}
}
}
// Otherwise, don't initiate combat with an unreachable target
if (!MWMechanics::canFight(actor1,actor2))
return;
bool aggressive = false;
if (againstPlayer || std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), actor2) != playerFollowersAndEscorters.end())
{
// Player followers and escorters with high fight should not initiate combat here with the player or with
// other player followers or escorters
if (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), actor1) != playerFollowersAndEscorters.end())
return;
aggressive = MWBase::Environment::get().getMechanicsManager()->isAggressive(actor1, actor2);
}
else
{
// Make guards fight aggressive creatures
if (!actor1.getClass().isNpc() && actor2.getClass().isClass(actor2, "Guard"))
{
if (creatureStats1.getAiSequence().isInCombat() && MWBase::Environment::get().getMechanicsManager()->isAggressive(actor1, actor2))
aggressive = true;
}
}
if(aggressive)
if (aggressive)
{
bool LOS = MWBase::Environment::get().getWorld()->getLOS(actor1, actor2);
if (againstPlayer) LOS &= MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor2, actor1);
if (againstPlayer || std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), actor2) != playerFollowersAndEscorters.end())
LOS &= MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor2, actor1);
if (LOS)
{

@ -19,6 +19,7 @@
#include "aicombataction.hpp"
#include "combat.hpp"
#include "coordinateconverter.hpp"
#include "actorutil.hpp"
namespace
{
@ -210,13 +211,14 @@ namespace MWMechanics
else
{
timerReact = 0;
attack(actor, target, storage, characterController);
if (attack(actor, target, storage, characterController))
return true;
}
return false;
}
void AiCombat::attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController)
bool AiCombat::attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController)
{
const MWWorld::CellStore*& currentCell = storage.mCell;
bool cellChange = currentCell && (actor.getCell() != currentCell);
@ -231,7 +233,10 @@ namespace MWMechanics
storage.stopAttack();
characterController.setAttackingOrSpell(false);
storage.mActionCooldown = 0.f;
forceFlee = true;
if (target == MWMechanics::getPlayer())
forceFlee = true;
else
return true;
}
const MWWorld::Class& actorClass = actor.getClass();
@ -243,7 +248,7 @@ namespace MWMechanics
if (!forceFlee)
{
if (actionCooldown > 0)
return;
return false;
if (characterController.readyToPrepareAttack())
{
@ -258,7 +263,7 @@ namespace MWMechanics
}
if (!currentAction)
return;
return false;
if (storage.isFleeing() != currentAction->isFleeing())
{
@ -266,7 +271,7 @@ namespace MWMechanics
{
storage.startFleeing();
MWBase::Environment::get().getDialogueManager()->say(actor, "flee");
return;
return false;
}
else
storage.stopFleeing();
@ -311,6 +316,7 @@ namespace MWMechanics
storage.mMovement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos)); // using vAimDir results in spastic movements since the head is animated
}
}
return false;
}
void MWMechanics::AiCombat::updateLOS(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, MWMechanics::AiCombatStorage& storage)

@ -59,7 +59,8 @@ namespace MWMechanics
int mTargetActorId;
void attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController);
/// Returns true if combat should end
bool attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController);
void updateLOS(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, AiCombatStorage& storage);

@ -617,6 +617,11 @@ namespace MWMechanics
return true;
}
}
else if (target.getClass().isActor() && effectId == ESM::MagicEffect::Dispel)
{
target.getClass().getCreatureStats(target).getActiveSpells().purgeAll(magnitude);
return true;
}
else if (target.getClass().isActor() && target == getPlayer())
{
MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(mCaster);
@ -1154,9 +1159,6 @@ namespace MWMechanics
case ESM::MagicEffect::CureCorprusDisease:
actor.getClass().getCreatureStats(actor).getSpells().purgeCorprusDisease();
break;
case ESM::MagicEffect::Dispel:
actor.getClass().getCreatureStats(actor).getActiveSpells().purgeAll(magnitude);
break;
case ESM::MagicEffect::RemoveCurse:
actor.getClass().getCreatureStats(actor).getSpells().purgeCurses();
break;

@ -55,29 +55,46 @@ namespace MWPhysics
static const float sMaxSlope = 49.0f;
static const float sStepSizeUp = 34.0f;
static const float sStepSizeDown = 62.0f;
static const float sMinStep = 10.f;
// Arbitrary number. To prevent infinite loops. They shouldn't happen but it's good to be prepared.
static const int sMaxIterations = 8;
// FIXME: move to a separate file
class MovementSolver
static bool isActor(const btCollisionObject *obj)
{
assert(obj);
return obj->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor;
}
template <class Vec3>
static bool isWalkableSlope(const Vec3 &normal)
{
static const float sMaxSlopeCos = std::cos(osg::DegreesToRadians(sMaxSlope));
return (normal.z() > sMaxSlopeCos);
}
static bool canStepDown(const ActorTracer &stepper)
{
return stepper.mHitObject && isWalkableSlope(stepper.mPlaneNormal) && !isActor(stepper.mHitObject);
}
class Stepper
{
private:
static float getSlope(osg::Vec3f normal)
{
normal.normalize();
return osg::RadiansToDegrees(std::acos(normal * osg::Vec3f(0.f, 0.f, 1.f)));
}
const btCollisionWorld *mColWorld;
const btCollisionObject *mColObj;
enum StepMoveResult
{
Result_Blocked, // unable to move over obstacle
Result_MaxSlope, // unable to end movement on this slope
Result_Success
};
ActorTracer mTracer, mUpStepper, mDownStepper;
bool mHaveMoved;
static StepMoveResult stepMove(const btCollisionObject *colobj, osg::Vec3f &position,
const osg::Vec3f &toMove, float &remainingTime, const btCollisionWorld* collisionWorld)
public:
Stepper(const btCollisionWorld *colWorld, const btCollisionObject *colObj)
: mColWorld(colWorld)
, mColObj(colObj)
, mHaveMoved(true)
{}
bool step(osg::Vec3f &position, const osg::Vec3f &toMove, float &remainingTime)
{
/*
* Slide up an incline or set of stairs. Should be called only after a
@ -123,12 +140,14 @@ namespace MWPhysics
* +--+ +--------
* ==============================================
*/
ActorTracer tracer, stepper;
stepper.doTrace(colobj, position, position+osg::Vec3f(0.0f,0.0f,sStepSizeUp), collisionWorld);
if(stepper.mFraction < std::numeric_limits<float>::epsilon())
return Result_Blocked; // didn't even move the smallest representable amount
// (TODO: shouldn't this be larger? Why bother with such a small amount?)
if (mHaveMoved)
{
mHaveMoved = false;
mUpStepper.doTrace(mColObj, position, position+osg::Vec3f(0.0f,0.0f,sStepSizeUp), mColWorld);
if(mUpStepper.mFraction < std::numeric_limits<float>::epsilon())
return false; // didn't even move the smallest representable amount
// (TODO: shouldn't this be larger? Why bother with such a small amount?)
}
/*
* Try moving from the elevated position using tracer.
@ -143,9 +162,10 @@ namespace MWPhysics
* +--+
* ==============================================
*/
tracer.doTrace(colobj, stepper.mEndPos, stepper.mEndPos + toMove, collisionWorld);
if(tracer.mFraction < std::numeric_limits<float>::epsilon())
return Result_Blocked; // didn't even move the smallest representable amount
osg::Vec3f tracerPos = mUpStepper.mEndPos;
mTracer.doTrace(mColObj, tracerPos, tracerPos + toMove, mColWorld);
if(mTracer.mFraction < std::numeric_limits<float>::epsilon())
return false; // didn't even move the smallest representable amount
/*
* Try moving back down sStepSizeDown using stepper.
@ -162,26 +182,40 @@ namespace MWPhysics
* +--+ +--+
* ==============================================
*/
stepper.doTrace(colobj, tracer.mEndPos, tracer.mEndPos-osg::Vec3f(0.0f,0.0f,sStepSizeDown), collisionWorld);
if (getSlope(stepper.mPlaneNormal) > sMaxSlope)
return Result_MaxSlope;
if(stepper.mFraction < 1.0f)
mDownStepper.doTrace(mColObj, mTracer.mEndPos, mTracer.mEndPos-osg::Vec3f(0.0f,0.0f,sStepSizeDown), mColWorld);
if (!canStepDown(mDownStepper))
{
// Try again with increased step length
if (mTracer.mFraction < 1.0f || toMove.length2() > sMinStep*sMinStep)
return false;
osg::Vec3f direction = toMove;
direction.normalize();
mTracer.doTrace(mColObj, tracerPos, tracerPos + direction*sMinStep, mColWorld);
if (mTracer.mFraction < 0.001f)
return false;
mDownStepper.doTrace(mColObj, mTracer.mEndPos, mTracer.mEndPos-osg::Vec3f(0.0f,0.0f,sStepSizeDown), mColWorld);
if (!canStepDown(mDownStepper))
return false;
}
if (mDownStepper.mFraction < 1.0f)
{
// don't allow stepping up other actors
if (stepper.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor)
return Result_Blocked;
// only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall.
// TODO: stepper.mPlaneNormal does not appear to be reliable - needs more testing
// NOTE: caller's variables 'position' & 'remainingTime' are modified here
position = stepper.mEndPos;
remainingTime *= (1.0f-tracer.mFraction); // remaining time is proportional to remaining distance
return Result_Success;
position = mDownStepper.mEndPos;
remainingTime *= (1.0f-mTracer.mFraction); // remaining time is proportional to remaining distance
mHaveMoved = true;
return true;
}
return Result_Blocked;
return false;
}
};
class MovementSolver
{
private:
///Project a vector u on another vector v
static inline osg::Vec3f project(const osg::Vec3f& u, const osg::Vec3f &v)
{
@ -229,14 +263,14 @@ namespace MWPhysics
collisionWorld->rayTest(from, to, resultCallback1);
if (resultCallback1.hasHit() &&
( (toOsg(resultCallback1.m_hitPointWorld) - tracer.mEndPos).length() > 35
|| getSlope(tracer.mPlaneNormal) > sMaxSlope))
( (toOsg(resultCallback1.m_hitPointWorld) - tracer.mEndPos).length2() > 35*35
|| !isWalkableSlope(tracer.mPlaneNormal)))
{
actor->setOnGround(getSlope(toOsg(resultCallback1.m_hitNormalWorld)) <= sMaxSlope);
actor->setOnGround(isWalkableSlope(resultCallback1.m_hitNormalWorld));
return toOsg(resultCallback1.m_hitPointWorld) + osg::Vec3f(0.f, 0.f, 1.f);
}
actor->setOnGround(getSlope(tracer.mPlaneNormal) <= sMaxSlope);
actor->setOnGround(isWalkableSlope(tracer.mPlaneNormal));
return tracer.mEndPos;
}
@ -312,8 +346,8 @@ namespace MWPhysics
velocity *= 1.f-(fStromWalkMult * (angleDegrees/180.f));
}
Stepper stepper(collisionWorld, colobj);
osg::Vec3f origVelocity = velocity;
osg::Vec3f newPosition = position;
/*
* A loop to find newPosition using tracer, if successful different from the starting position.
@ -332,10 +366,7 @@ namespace MWPhysics
newPosition.z() <= swimlevel)
{
const osg::Vec3f down(0,0,-1);
float movelen = velocity.normalize();
osg::Vec3f reflectdir = reflect(velocity, down);
reflectdir.normalize();
velocity = slide(reflectdir, down)*movelen;
velocity = slide(velocity, down);
// NOTE: remainingTime is unchanged before the loop continues
continue; // velocity updated, calculate nextpos again
}
@ -364,19 +395,25 @@ namespace MWPhysics
break;
}
// We are touching something.
if (tracer.mFraction < 1E-9f)
{
// Try to separate by backing off slighly to unstuck the solver
const osg::Vec3f backOff = (newPosition - tracer.mHitPoint) * 1E-3f;
newPosition += backOff;
}
// We hit something. Check if we can step up.
float hitHeight = tracer.mHitPoint.z() - tracer.mEndPos.z() + halfExtents.z();
osg::Vec3f oldPosition = newPosition;
// We hit something. Try to step up onto it. (NOTE: stepMove does not allow stepping over)
// NOTE: stepMove modifies newPosition if successful
const float minStep = 10.f;
StepMoveResult result = stepMove(colobj, newPosition, velocity*remainingTime, remainingTime, collisionWorld);
if (result == Result_MaxSlope && (velocity*remainingTime).length() < minStep) // to make sure the maximum stepping distance isn't framerate-dependent or movement-speed dependent
bool result = false;
if (hitHeight < sStepSizeUp && !isActor(tracer.mHitObject))
{
osg::Vec3f normalizedVelocity = velocity;
normalizedVelocity.normalize();
result = stepMove(colobj, newPosition, normalizedVelocity*minStep, remainingTime, collisionWorld);
// Try to step up onto it.
// NOTE: stepMove does not allow stepping over, modifies newPosition if successful
result = stepper.step(newPosition, velocity*remainingTime, remainingTime);
}
if(result == Result_Success)
if (result)
{
// don't let pure water creatures move out of water after stepMove
if (ptr.getClass().isPureWaterCreature(ptr)
@ -386,23 +423,19 @@ namespace MWPhysics
else
{
// Can't move this way, try to find another spot along the plane
osg::Vec3f direction = velocity;
float movelen = direction.normalize();
osg::Vec3f reflectdir = reflect(velocity, tracer.mPlaneNormal);
reflectdir.normalize();
osg::Vec3f newVelocity = slide(velocity, tracer.mPlaneNormal);
// Do not allow sliding upward if there is gravity.
// Stepping will have taken care of that.
if(!(newPosition.z() < swimlevel || isFlying))
newVelocity.z() = std::min(newVelocity.z(), 0.0f);
osg::Vec3f newVelocity = slide(reflectdir, tracer.mPlaneNormal)*movelen;
if ((newVelocity-velocity).length2() < 0.01)
break;
if ((velocity * origVelocity) <= 0.f)
if ((newVelocity * origVelocity) <= 0.f)
break; // ^ dot product
velocity = newVelocity;
// Do not allow sliding upward if there is gravity. Stepping will have taken
// care of that.
if(!(newPosition.z() < swimlevel || isFlying))
velocity.z() = std::min(velocity.z(), 0.0f);
}
}
@ -413,7 +446,7 @@ namespace MWPhysics
osg::Vec3f to = newPosition - (physicActor->getOnGround() ?
osg::Vec3f(0,0,sStepSizeDown+2.f) : osg::Vec3f(0,0,2.f));
tracer.doTrace(colobj, from, to, collisionWorld);
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope
if(tracer.mFraction < 1.0f && isWalkableSlope(tracer.mPlaneNormal)
&& tracer.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup != CollisionType_Actor)
{
const btCollisionObject* standingOn = tracer.mHitObject;

@ -78,6 +78,7 @@ void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& star
mFraction = newTraceCallback.m_closestHitFraction;
mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z());
mEndPos = (end-start)*mFraction + start;
mHitPoint = toOsg(newTraceCallback.m_hitPointWorld);
mHitObject = newTraceCallback.m_hitCollisionObject;
}
else
@ -85,6 +86,7 @@ void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& star
mEndPos = end;
mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f);
mFraction = 1.0f;
mHitPoint = end;
mHitObject = NULL;
}
}

@ -15,6 +15,7 @@ namespace MWPhysics
{
osg::Vec3f mEndPos;
osg::Vec3f mPlaneNormal;
osg::Vec3f mHitPoint;
const btCollisionObject* mHitObject;
float mFraction;

@ -7,6 +7,7 @@
#include <osg/Group>
#include <osg/Geometry>
#include <osg/Depth>
#include <osg/TexEnvCombine>
#include <osgDB/WriteFile>
@ -144,6 +145,10 @@ namespace MWRender
image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE);
unsigned char* data = image->data();
osg::ref_ptr<osg::Image> alphaImage = new osg::Image;
alphaImage->allocateImage(mWidth, mHeight, 1, GL_ALPHA, GL_UNSIGNED_BYTE);
unsigned char* alphaData = alphaImage->data();
for (int x = mMinX; x <= mMaxX; ++x)
{
for (int y = mMinY; y <= mMaxY; ++y)
@ -208,6 +213,8 @@ namespace MWRender
data[texelY * mWidth * 3 + texelX * 3] = r;
data[texelY * mWidth * 3 + texelX * 3+1] = g;
data[texelY * mWidth * 3 + texelX * 3+2] = b;
alphaData[texelY * mWidth+ texelX] = (y2 < 0) ? static_cast<unsigned char>(0) : static_cast<unsigned char>(255);
}
}
loadingListener->increaseProgress();
@ -224,6 +231,14 @@ namespace MWRender
mBaseTexture->setImage(image);
mBaseTexture->setResizeNonPowerOfTwoHint(false);
mAlphaTexture = new osg::Texture2D;
mAlphaTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
mAlphaTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
mAlphaTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mAlphaTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mAlphaTexture->setImage(alphaImage);
mAlphaTexture->setResizeNonPowerOfTwoHint(false);
clear();
loadingListener->loadingOff();
@ -299,6 +314,28 @@ namespace MWRender
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
if (mAlphaTexture)
{
osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array;
float x1 = x / static_cast<float>(mWidth);
float x2 = (x + width) / static_cast<float>(mWidth);
float y1 = y / static_cast<float>(mHeight);
float y2 = (y + height) / static_cast<float>(mHeight);
texcoords->push_back(osg::Vec2f(x1, y1));
texcoords->push_back(osg::Vec2f(x1, y2));
texcoords->push_back(osg::Vec2f(x2, y2));
texcoords->push_back(osg::Vec2f(x2, y1));
geom->setTexCoordArray(1, texcoords, osg::Array::BIND_PER_VERTEX);
stateset->setTextureAttributeAndModes(1, mAlphaTexture, osg::StateAttribute::ON);
osg::ref_ptr<osg::TexEnvCombine> texEnvCombine = new osg::TexEnvCombine;
texEnvCombine->setCombine_RGB(osg::TexEnvCombine::REPLACE);
texEnvCombine->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
stateset->setTextureAttributeAndModes(1, texEnvCombine);
}
camera->addChild(geom);
}

@ -107,6 +107,7 @@ namespace MWRender
std::vector< std::pair<int,int> > mExploredCells;
osg::ref_ptr<osg::Texture2D> mBaseTexture;
osg::ref_ptr<osg::Texture2D> mAlphaTexture;
// GPU copy of overlay
// Note, uploads are pushed through a Camera, instead of through mOverlayImage

@ -437,7 +437,9 @@ bool OpenAL_SoundStream::process()
alGetSourcei(mSource, AL_SOURCE_STATE, &state);
if(state != AL_PLAYING && state != AL_PAUSED)
{
// Ensure all processed buffers are removed so we don't replay them.
refillQueue();
alSourcePlay(mSource);
}
}
@ -906,7 +908,10 @@ void OpenAL_Output::finishSound(MWBase::SoundPtr sound)
ALuint source = GET_PTRID(sound->mHandle);
sound->mHandle = 0;
alSourceStop(source);
// Rewind the stream instead of stopping it, this puts the source into an AL_INITIAL state,
// which works around a bug in the MacOS OpenAL implementation which would otherwise think
// the initial queue already played when it hasn't.
alSourceRewind(source);
alSourcei(source, AL_BUFFER, 0);
mFreeSources.push_back(source);
@ -1006,7 +1011,10 @@ void OpenAL_Output::finishStream(MWBase::SoundStreamPtr sound)
sound->mHandle = 0;
mStreamThread->remove(stream);
alSourceStop(source);
// Rewind the stream instead of stopping it, this puts the source into an AL_INITIAL state,
// which works around a bug in the MacOS OpenAL implementation which would otherwise think
// the initial queue already played when it hasn't.
alSourceRewind(source);
alSourcei(source, AL_BUFFER, 0);
mFreeSources.push_back(source);

@ -139,7 +139,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr,
// Auto-equip items if an armor/clothing or weapon item is added, but not for the player nor werewolves
if (actorPtr != MWMechanics::getPlayer()
&& !(actorPtr.getClass().isNpc() && actorPtr.getClass().getNpcStats(actorPtr).isWerewolf()))
&& actorPtr.getClass().isNpc() && !actorPtr.getClass().getNpcStats(actorPtr).isWerewolf())
{
std::string type = itemPtr.getTypeName();
if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name())
@ -243,10 +243,6 @@ bool MWWorld::InventoryStore::canActorAutoEquip(const MWWorld::Ptr& actor, const
void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
{
if (!actor.getClass().isNpc())
// autoEquip is no-op for creatures
return;
const MWBase::World *world = MWBase::Environment::get().getWorld();
const MWWorld::Store<ESM::GameSetting> &store = world->getStore().get<ESM::GameSetting>();
MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor);
@ -449,6 +445,50 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
}
}
void MWWorld::InventoryStore::autoEquipShield(const MWWorld::Ptr& actor)
{
bool updated = false;
mUpdatesEnabled = false;
for (ContainerStoreIterator iter(begin(ContainerStore::Type_Armor)); iter != end(); ++iter)
{
if (iter->get<ESM::Armor>()->mBase->mData.mType != ESM::Armor::Shield)
continue;
if (iter->getClass().canBeEquipped(*iter, actor).first != 1)
continue;
if (iter->getClass().getItemHealth(*iter) <= 0)
continue;
std::pair<std::vector<int>, bool> shieldSlots =
iter->getClass().getEquipmentSlots(*iter);
if (shieldSlots.first.empty())
continue;
int slot = shieldSlots.first[0];
const ContainerStoreIterator& shield = mSlots[slot];
if (shield != end()
&& shield.getType() == Type_Armor && shield->get<ESM::Armor>()->mBase->mData.mType == ESM::Armor::Shield)
{
if (shield->getClass().getItemHealth(*shield) >= iter->getClass().getItemHealth(*iter))
continue;
}
equip(slot, iter, actor);
updated = true;
}
mUpdatesEnabled = true;
if (updated)
{
fireEquipmentChangedEvent(actor);
updateMagicEffects(actor);
}
}
const MWMechanics::MagicEffects& MWWorld::InventoryStore::getMagicEffects() const
{
return mMagicEffects;
@ -628,7 +668,7 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
// If an armor/clothing item is removed, try to find a replacement,
// but not for the player nor werewolves.
if (wasEquipped && (actor != MWMechanics::getPlayer())
&& !(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()))
&& actor.getClass().isNpc() && !actor.getClass().getNpcStats(actor).isWerewolf())
{
std::string type = item.getTypeName();
if (type == typeid(ESM::Armor).name() || type == typeid(ESM::Clothing).name())

@ -162,6 +162,9 @@ namespace MWWorld
void autoEquip (const MWWorld::Ptr& actor);
///< Auto equip items according to stats and item value.
void autoEquipShield(const MWWorld::Ptr& actor);
///< Auto-equip the shield with most health.
const MWMechanics::MagicEffects& getMagicEffects() const;
///< Return magic effects from worn items.

@ -280,7 +280,9 @@ namespace MWWorld
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
for (size_t it = 0; it != state.mSoundIds.size(); it++)
{
state.mSounds.push_back(sndMgr->playSound3D(pos, state.mSoundIds.at(it), 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop));
MWBase::SoundPtr sound = sndMgr->playSound3D(pos, state.mSoundIds.at(it), 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
if (sound)
state.mSounds.push_back(sound);
}
mMagicBolts.push_back(state);
@ -571,8 +573,10 @@ namespace MWWorld
for (size_t soundIter = 0; soundIter != state.mSoundIds.size(); soundIter++)
{
state.mSounds.push_back(sndMgr->playSound3D(esm.mPosition, state.mSoundIds.at(soundIter), 1.0f, 1.0f,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop));
MWBase::SoundPtr sound = sndMgr->playSound3D(esm.mPosition, state.mSoundIds.at(soundIter), 1.0f, 1.0f,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
if (sound)
state.mSounds.push_back(sound);
}
mMagicBolts.push_back(state);

@ -19,9 +19,9 @@ The largest difference between OpenMW and Morrowind in terms of data structure i
To install mods via this new feature:
#. Open ``openmw.cfg`` with your preffered text editor. It is located as described in https://wiki.openmw.org/index.php?title=Paths and *not* in your OpenMW root directory.
#. Open ``openmw.cfg`` with your preffered text editor. It is located as described in :doc:`paths` and *not* in your OpenMW root directory.
#. Find or search for ``data=``. This is located very near the bottom of the file.
#. Add a new line below this line and make a new entry of the format ``data=path/to/your/mod``
#. Add a new line below this line and make a new entry of the format ``data="path/to/your/mod"``
#. Make as many of these entries as you need for each mod folder you want to include.
#. Save ``openmw.cfg``

@ -0,0 +1,77 @@
Fonts
#####
Morrowind .fnt fonts
--------------------
Morrowind uses a custom ``.fnt`` file format. It is not compatible with the Windows Font File ``.fnt`` format, nor compatible with ``.fnt`` formats from any other Bethesda games. To our knowledge, the format is undocumented and no tools for viewing or editing these fonts exist.
OpenMW can load this format and convert it on the fly into something usable (see font loader `source code <https://github.com/OpenMW/openmw/blob/master/components/fontloader/fontloader.cpp#L210>`_). In OpenMW 0.32, an --export-fonts command line option was added to write the converted font (a PNG image and an XML file describing the position of each glyph in the image) to the current directory.
TrueType fonts
--------------
Unlike vanilla Morrowind, OpenMW directly supports TrueType (``.ttf``) fonts. This is the recommended way to create new fonts.
- To replace the primary "Magic Cards" font:
#. Download `Pelagiad <http://isaskar.github.io/Pelagiad/>`_ by Isak Larborn (aka Isaskar).
#. Install the ``openmw_font.xml`` file into ``resources/mygui/openmw_font.xml`` in your OpenMW installation.
#. Copy ``Pelagiad.ttf`` into ``resources/mygui/`` as well.
#. If desired, you can now delete the original ``Magic_Cards.*`` files from your Data Files/Fonts directory.
- You can also replace the Daedric font:
#. Download `Ayembedt <https://github.com/georgd/OpenMW-Fonts>`_ by Georg Duffner.
#. Install ``OMWAyembedt.otf`` into ``/resources/mygui/`` folder in your OpenMW installation.
#. Add the following lines to openmw_font.xml::
<Resource type="ResourceTrueTypeFont" name="Daedric">
<Property key="Source" value="OMWAyembedt.otf"/>
<Property key="Size" value="24"/>
<Property key="Resolution" value="50"/>
<Property key="Antialias" value="false"/>
<Property key="TabWidth" value="8"/>
<Property key="OffsetHeight" value="0"/>
<Codes>
<Code range="32"/>
<Code range="65 90"/>
<Code range="97 122"/>
</Codes>
</Resource>
#. This font is missing a few glyphs (mostly punctuation), but is complete in the primary glyphs. If desired, you can now delete the original ``daedric.*`` files from your Data Files/Fonts directory.
- Another replacement for the Daedric font is `Oblivion <http://www.uesp.net/wiki/File:Obliviontt.zip>`_ by Dongle.
#. Install the ``Oblivion.ttf`` file resources/mygui/.
#. The openmw_fonts.xml entry is::
<Resource type="ResourceTrueTypeFont" name="Daedric">
<Property key="Source" value="Oblivion.ttf"/>
<Property key="Size" value="30"/>
<Property key="Resolution" value="50"/>
<Property key="Antialias" value="false"/>
<Property key="TabWidth" value="8"/>
<Property key="OffsetHeight" value="0"/>
<Codes>
<Code range="32 34"/>
<Code range="39"/>
<Code range="44 46"/>
<Code range="48 59"/>
<Code range="63"/>
<Code range="65 90"/>
<Code range="97 122"/>
<Code range="172 173"/>
<Code range="255"/>
<Code range="376"/>
<Code range="894"/>
<Code range="8211 8212"/>
<Code range="8216 8217"/>
<Code range="8220 8221"/>
</Codes>
</Resource>
Bitmap fonts
------------
Morrowind ``.fnt`` files are essentially a bitmap font, but using them is discouraged because of no Unicode support. MyGUI has its own format for bitmap fonts. An example can be seen by using the --export-fonts command line option (see above), which converts Morrowind ``.fnt`` to a MyGUI bitmap font. This is the recommended format to use if you wish to edit Morrowind's bitmap font or create a new bitmap font.

@ -14,4 +14,7 @@ The following document is the complete reference guide to modifying, or modding,
foreword
differences
mod-install
settings/index
fonts
convert_bump_mapped_mods
paths

@ -8,13 +8,20 @@ Install
#. Your mod probably comes in some kind of archive, such as ``.zip``, ``.rar``, ``.7z``, or something along those lines. Unpack this archive into its own folder.
#. Ensure the structure of this folder is correct.
#. Locate the plugin files, ``.esp`` or ``.omwaddon``. The folder containing the plugin files we will call your *data folder*
#. Check that all resource folders (``Meshes``, ``Textures``, etc.) containing additional resource files (the actual meshes, textures, etc.) are in the *data folder*.
.. note::
There may be multiple levels of folders, but the location of the plugins must be the same as the resource folders.
#. Open your ``openmw.cfg`` file in your preferred plain text editor. It is located as described in https://wiki.openmw.org/index.php?title=Paths and *not* in your OpenMW root directory.
.. note::
There may be multiple levels of folders, but the location of the plugins must be the same as the resource folders.
#. Open your ``openmw.cfg`` file in your preferred plain text editor. It is located as described in :doc:`paths` and *not* in your OpenMW root directory.
#. Find or search for ``data=``. This is located very near the bottom of the file. If you are using Morrowind, this first entry should already point to your Morrowind data directory, ``Data Files``; otherwise it will point to your game file, ``.omwgame``.
#. Create a new line underneath and type: ``data="path/to/your/data folder"`` Remember, the *data folder* is where your mod's plugin files are. The double quotes around this path name are *required*.
.. note::
Some text editors, such as TextEdit on Mac, will autocorrect your double quotes to typographical "curly" quotes instead of leaving them as the propper neutral vertical quotes ``""``.
#. Save your ``openmw.cfg`` file.
You have now installed your mod. Any simple replacer mods that only contain resource files such as meshes or textures will now automatically be loaded in the order of their ``data=*`` entry. This is important to note because replacer mods that replace the same resource will overwrite previous ones as you go down the list.
@ -22,6 +29,15 @@ You have now installed your mod. Any simple replacer mods that only contain reso
Enable
------
Any mods that have plugin files must be enabled to work.
Any mods that have plugin files must be enabled to work. Master game files and plugin files can only be enabled if they have been properly installed within a *data folder* as described above.
#. Open the OpenMW Launcher.
#. Click on the Data Files tab.
#. In the Content List box, select the content list you wish to modify in the dropdown menu, or make a new one by:
#.
#. Click the New Content List button and enter the name of your content list, then click OK. New lists are useful for keeping track of the mods used for different characters or for different games if you play more than one game using OpenMW.
#. In the Content box, select your game file (``.esm`` or ``.omwgame``) from the dropdown menu.
#. Now you must activate the plugins you wish to use by checking the box next to their entry in the Content box list.
#. Load order can be changed simply by dragging the entries around within the list. Mods are loaded from the top down, so if one plugin depends on another, it must be lower on the list.
#. Click Play to run OpenMW with your game and enabled mods!

@ -0,0 +1,28 @@
Paths
#####
The following describes the locations for the various OpenMW file paths for different types of files on different operating systems.
.. note::
Actual location depends on your computer's setup. Username, harddrive, and language may vary.
Configuration files and log files
---------------------------------
:Linux: ``$HOME/.config/openmw``
:Mac: ``$HOME/Library/Preferences/openmw``
:Windows: ``C:\Users\Username\Documents\my games\openmw``
Savegames
---------
:Linux: ``$HOME/.local/share/openmw/saves``
:Mac: ``$HOME/Library/Application Support/openmw/saves``
:Windows: ``C:\Users\Username\Documents\my games\openmw\saves``
Screenshots
-----------
:Linux: ``$HOME/.local/share/openmw``
:Mac: ``$HOME/Library/Application Support/openmw``
:Windows: ``C:\Users\Username\Documents\my games\openmw``

@ -0,0 +1,104 @@
GUI Settings
############
scaling factor
--------------
:Type: floating point
:Range: > 0.0
:Default: 1.0
This floating point setting scales the GUI interface windows. The value must be greater than 0.0. A value of 1.0 results in the normal scale. Values much larger than 2.0 may result in user interface components being inaccessible. Until a gamepad interface is created, increasing this setting is helpful for simulating the larger interface used in console games.
The default value is 1.0. This setting can only be configured by editing the settings configuration file.
menu transparency
-----------------
:Type: floating point
:Range: 0.0 (transparent) to 1.0 (opaque)
:Default: 0.84
This floating point setting controls the transparency of the GUI windows. The value should be between 0.0 (transparent) and 1.0 (opaque).
The default value is 0.84. This setting can be adjusted in game with the Menu Transparency slider in the Prefs panel of the Options menu.
tooltip delay
-------------
:Type: floating point
:Range: > 0.0
:Default: 0.0
This floating point value determines the number of seconds between when you begin hovering over an item and when its tooltip appears. This setting only affects the tooltip delay for objects under the crosshair in GUI mode windows. There does not appear to be a setting to control the tool tip delay in outside of GUI mode.
The tooltip displays context sensitive information on the selected GUI element, such as weight, value, damage, armor rating, magical effects, and detailed description.
The default value is 0.0. This setting can be adjusted between 0.0 and 1.0 in game with the Menu Help Delay slider in the Prefs panel of the Options menu.
stretch menu background
-----------------------
:Type: boolean
:Range: True/False
:Default: False
Stretch or shrink the main menu screen, loading splash screens, introductory movie, and cut scenes to fill the specified video resolution, distorting their aspect ratio. The Bethesda provided assets have a 4:3 aspect ratio, but other assets are permitted to have other aspect ratios. If this setting is false, the assets will be centered in their correct aspect ratio, with black bars filling the remainder of the screen.
The default value is false. This setting can only be configured by editing the settings configuration file.
subtitles
---------
:Type: boolean
:Range: True/False
:Default: False
Enable or disable subtitles for NPC spoken dialog (and some sound effects). Subtitles will appear in a tool tip box in the lower center of the screen.
The default value is false. This setting can be toggled in game with the Subtitles button in the Prefs panel of Options menu.
hit fader
---------
:Type: boolean
:Range: True/False
:Default: True
This boolean setting enables or disables the "red flash" overlay that provides a visual clue when the character has taken damage.
If this setting is disabled, the player will "bleed" like NPCs do.
The default value is true. This setting can only be configured by editing the settings configuration file.
werewolf overlay
----------------
:Type: boolean
:Range: True/False
:Default: True
Enable or disable the werewolf overlay.
The default value is true. This setting can only be configured by editing the settings configuration file.
color background owned
----------------------
:Type: RGBA floating point
:Range: 0.0 to 1.0
:Default: 0.15 0.0 0.0 1.0
The following two settings determine the background color of the tool tip and the crosshair when hovering over an item owned by an NPC. The color definitions are composed of four floating point values between 0.0 and 1.0 inclusive, representing the red, green, blue and alpha channels. The alpha value is currently ignored. The crosshair color will have no effect if the crosshair setting in the HUD section is disabled.
The default value is "0.15 0.0 0.0 1.0", which is a dark red color. This setting can only be configured by editing the settings configuration file. This setting has no effect if the show owned setting in the Game Settings Section is false.
color crosshair owned
---------------------
:Type: RGBA floating point
:Range: 0.0 to 1.0
:Default: 1.0 0.15 0.15 1.0
This setting sets the color of the crosshair when hovering over an item owned by an NPC. The value is composed of four floating point values representing the red, green, blue and alpha channels. The alpha value is currently ignored.
The default value is "1.0 0.15 0.15 1.0" which is a bright red color. This setting can only be configured by editing the settings configuration file. This setting has no effect if the crosshair setting in the HUD Settings Section is false. This setting has no effect if the show owned setting in the Game Settings Section is false.

@ -0,0 +1,13 @@
HUD Settings
############
crosshair
---------
:Type: boolean
:Range: True/False
:Default: True
This boolean setting determines whether the crosshair or reticle is displayed. Some players perceive that disabling the crosshair provides a more immersive experience. Another common use is to disable the crosshair for screen shots. Enabling the crosshair provides more immediate feedback about which object that is currently the focus of actions.
The default value is true. This setting can be toggled with the Crosshair button in the Prefs panel of the Options menu.

@ -0,0 +1,75 @@
Camera Settings
###############
near clip
---------
:Type: floating point
:Range: > 0
:Default: 1.0
This floating point setting controls the distance to the near clipping plane. The value must be greater than zero. Values greater than approximately 18.0 will occasionally clip objects in the world in front of the character. Values greater than approximately 8.0 will clip the character's hands in first person view and/or the back of their head in third person view.
The default value is 1.0. This setting can only be configured by editing the settings configuration file. The value must be greater than 0.0, but it's unclear if the engine enforces this limitation.
small feature culling
---------------------
:Type: boolean
:Range: True/False
:Default: True
This boolean setting determines whether objects that render to a few pixels or smaller will be culled (not drawn). It generally improves performance to enable this feature, and by definition the culled objects will be very small on screen. It appears that the default definition of "small" in OpenSceneGraph is 2x2 pixels.
The default value is true. This setting can only be configured by editing the settings configuration file.
viewing distance
----------------
:Type: floating point
:Range: > 0
:Default: 6666.0
This floating point values controls the maximum visible distance (also called the far clipping plane). Larger values significantly improve rendering in exterior spaces, but also increase the amount of rendered geometry and significantly reduce the frame rate. This value interacts with the exterior cell load distance setting in that it's probably undesired for this value to provide visibility into cells that have not yet been loaded. When cells are visible before loading, the geometry will "pop-in" suddenly, creating a jarring visual effect. To prevent this effect, this value must be less than::
(8192 * exterior cell load distance - 1024) * 0.93
The constant 8192 is the size of a cell, and 1024 is the threshold distance for loading a new cell. Additionally, the field of view setting also interacts with this setting because the view frustrum end is a plane, so you can see further at the edges of the screen than you should be able to. This can be observed in game by looking at distant objects and rotating the camera so the objects are near the edge of the screen. As a result, this setting should further be reduced by a factor that depends on the field of view setting. In the default configuration this reduction is 7%, hence the factor of 0.93 above. Using this factor, approximate values recommended for other exterior cell load distance settings are:
======= ========
Cells Viewing
Distance
======= ========
2 14285
3 21903
4 29522
5 35924
======= ========
Reductions of up to 25% or more can be required to completely eliminate pop-in for wide fields of view and long viewing distances near the edges of the screen, but such situations are unusual and probably not worth the performance penalty introduced by loading geometry obscured by fog in the center of the screen. See RenderingManager::configureFog for the relevant source code.
Enabling the distant land setting is an alternative to increasing exterior cell load distance. Note that the distant land setting does not include rendering of distant static objects, so the resulting visual effect is not the same.
The default value is 6666.0. This setting can be adjusted in game from the ridiculously low value of 2000.0 to a maximum of 6666.0, using the View Distance slider in the Detail tab of the Video panel of the Options menu.
field of view
-------------
:Type: floating point
:Range: 0-360
:Default: 55.0
Sets the camera field of view in degrees. Recommended values range from 30 degrees to 110 degrees. Small values provide a very narrow field of view that creates a "zoomed in" effect, while large values cause distortion at the edges of the screen. The "field of view" setting interacts with aspect ratio of your video resolution in that more square aspect ratios (e.g. 4:3) need a wider field of view to more resemble the same field of view on a widescreen (e.g. 16:9) monitor.
The default value is 55.0. This setting can be changed in game using the Field of View slider from the Video tab of the Video panel of the Options menu.
first person field of view
--------------------------
:Type: floating point
:Range: 0-360
:Default: 55.0
The floating point setting controls the field of view for first person meshes such as the player's hands and held objects. It is not recommended to change this value from its default value because the Bethesda provided Morrowind assets do not adapt well to large values, while small values can result in the hands not being visible.
The default value is 55.0. This setting can only be configured by editing the settings configuration file.

@ -0,0 +1,17 @@
Cells Settings
##############
exterior cell load distance
---------------------------
:Type: integer
:Range: >= 1
:Default: 1
This integer setting determines the number of exterior cells adjacent to the character that will be loaded for rendering. Values greater than one may significantly affect loading times when exiting interior spaces or loading additional exterior cells. Caution is advised when increasing this setting.
This setting interacts with viewing distance and field of view settings.
It is generally very wasteful for this value to load geometry than will almost never be visible due to viewing distance and fog. For low frame rate screen shots of scenic vistas, this setting should be set high, and viewing distances adjusted accordingly.
The default value is 1. This value must be greater than or equal to 1. This setting can only be configured by editing the settings configuration file.

@ -0,0 +1,46 @@
Game Settings
#############
show owned
----------
:Type: integer
:Range: 0, 1, 2, 3
:Default: 0
Enable visual clues for items owned by NPCs when the crosshair is on the object. If the setting is 0, no clues are provided which is the default Morrowind behavior. If the setting is 1, the background of the tool tip for the object is highlight in the color specified by the color background owned setting in the GUI Settings Section. If the setting is 2, the crosshair is the color of the color crosshair owned setting in the GUI Settings section. If the setting is 3, both the tool tip background and the crosshair are colored. The crosshair is not visible if crosshair is false.
The default value is 0 (no clues). This setting can only be configured by editing the settings configuration file.
best attack
-----------
:Type: boolean
:Range: True/False
:Default: False
If this boolean setting is true, the player character will always use the most powerful attack when striking with a weapon (chop, slash or thrust). If this setting is false, the type of attack is determined by the direction that the character is moving at the time the attack begins.
The default value is false. This setting can be toggled with the Always Use Best Attack button in the Prefs panel of the Options menu.
difficulty
----------
:Type: integer
:Range: -500 to 500
:Default: 0
This integer setting adjusts the difficulty of the game and is intended to be in the range -100 to 100 inclusive. Given the default game setting for fDifficultyMult of 5.0, a value of -100 results in the player taking 80% of the usual damage, doing 6 times the normal damage. A value of 100 results in the player taking 6 times as much damage, but inflicting only 80% of the usual damage. Values less than -500 will result in the player receiving no damage, and values greater than 500 will result in the player inflicting no damage.
The default value is 0. This setting can be controlled in game with the Difficulty slider in the Prefs panel of the Options menu.
show effect duration
--------------------
:Type: boolean
:Range: True/False
:Default: False
Show the remaining duration of magic effects and lights if this boolean setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect.
The default value is false. This setting can only be configured by editing the settings configuration file.

@ -0,0 +1,35 @@
General Settings
################
anisotropy
----------
:Type: integer
:Range: 0 to 16
:Default: 4
Set the maximum anisotropic filtering on textures. Anisotropic filtering is a method of enhancing the image quality of textures on surfaces that are at oblique viewing angles with respect to the camera. Valid values range from 0 to 16. Modern video cards can often perform 8 or 16 anisotropic filtering with a minimal performance impact. This effect of this setting can be seen in the Video panel of the Options menu by finding a location with straight lines (striped rugs and Balmora cobblestones work well) radiating into the distance, and adjusting the anisotropy slider.
The default value is 4. This setting can be changed in game using the Anisotropy slider in the Detail tab of the Video panel of the Options menu.
screenshot format
-----------------
:Type: string
:Range: jpg, png, tga
:Default: png
Specify the format for screen shots taken by pressing the screen shot key (bound to F12 by default). This setting should be the file extension commonly associated with the desired format. The formats supported will be determined at compilation, but "jpg", "png", and "tga" should be allowed.
The default value is "png". This setting can only be configured by editing the settings configuration file.
texture filtering
-----------------
:Type: string
:Range: bilinear, trilinear
:Default: trilinear
Set the isotropic texture filtering mode to bilinear or trilinear. Bilinear filtering is a texture filtering method used to smooth textures when displayed larger or smaller than they actually are. Bilinear filtering is reasonably accurate until the scaling of the texture gets below half or above double the original size of the texture. Trilinear filtering is an extension of the bilinear texture filtering method, which also performs linear interpolation between mipmaps. Both methods use mipmaps in OpenMW, and the corresponding OpenGL modes are LINEAR_MIPMAP_NEAREST and LINEAR_MIPMAP_LINEAR. Trilinear filtering produces better texturing at a minimal cost on modern video cards.
The default value is trilinear. This setting can be changed in game using the Texture filtering pull down in the Detail tab of the Video panel of the Options menu.

@ -0,0 +1,28 @@
###############################
Advanced Settings Configuration
###############################
This part of the guide will cover how to make modifications to the more arcane settings in OpenMW, most of which are not available from in-game menus, to optimize or customize your OpenMW experience. If you are familiar with ``.ini`` tweaks in Morrowind or the other games, this will be quite similar. All settings described in this section are changed in ``settings.cfg``, located in your OpenMW user directory. See :doc:`paths` for this location.
Although this guide attempts to be comprehensive and up to date. You will always be able to find the full list of settings available and their default values in ``settings-default.cfg`` in your main OpenMW installation directory. The ranges I have included with each setting are the physically possible ranges, not recommendations.
.. warning::
As the title suggests, these are advanced settings. If digging around plain text files and manually editing settings sounds scary to you, you may want to stear clear of altering these files. That being said, this guide should be plenty clear enough that you can find the setting you want to change and safely edit it.
.. toctree::
:caption: Table of Contents
:maxdepth: 2
camera
cells
map
GUI
HUD
game
general
input
saves
sound
video
water
windows

@ -0,0 +1,83 @@
Input Settings
##############
grab cursor
-----------
:Type: boolean
:Range: True/False
:Default: True
OpenMW will capture control of the cursor if this boolean setting is true.
In "look mode", OpenMW will center the cursor regardless of the value of this setting (since the cursor/crosshair is always centered in the OpenMW window). However, in GUI mode, this setting determines the behavior when the cursor is moved outside the OpenMW window. If true, the cursor movement stops at the edge of the window preventing access to other applications. If false, the cursor is allowed to move freely on the desktop.
This setting does not apply to the screen where escape has been pressed, where the cursor is never captured. Regardless of this setting "Alt-Tab" or some other operating system dependent key sequence can be used to allow the operating system to regain control of the mouse cursor. This setting interacts with the minimize on focus loss setting by affecting what counts as a focus loss. Specifically on a two-screen configuration it may be more convenient to access the second screen with setting disabled.
Note for developers: it's desirable to have this setting disabled when running the game in a debugger, to prevent the mouse cursor from becoming unusable when the game pauses on a breakpoint.
The default value is true. This setting can only be configured by editing the settings configuration file.
toggle sneak
------------
:Type: boolean
:Range: True/False
:Default: False
This boolean setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled.
The default value is false. This setting can only be configured by editing the settings configuration file.
always run
----------
:Type: boolean
:Range: True/False
:Default: False
If this boolean setting is true, the character is running by default, otherwise the character is walking by default. The shift key will temporarily invert this setting, and the caps lock key will invert this setting while it's "locked". This setting is updated every time you exit the game, based on whether the caps lock key was on or off at the time you exited.
The default value is false. This settings can be toggled in game by pressing the CapsLock key and exiting.
allow third person zoom
-----------------------
:Type: boolean
:Range: True/False
:Default: False
Allow zooming in and out using the middle mouse wheel in third person view. This feature may not work correctly if the mouse wheel is bound to other actions, and may be triggered accidentally in some cases, so is disabled by default. This setting can only be configured by editing the settings configuration file.
camera sensitivity
------------------
:Type: floating point
:Range: > 0
:Default: 1.0
This floating point setting controls the overall camera/mouse sensitivity when not in GUI mode. The default sensitivity is 1.0, with smaller values requiring more mouse movement, and larger values requiring less. This setting is multiplicative in magnitude. This setting does not affect mouse speed in GUI mode, which is instead controlled by your operating system mouse speed setting.
The default value is 1.0. This setting can be changed with the Camera Sensitivity slider in the Controls panel of the Options menu.
camera y multiplier
-------------------
:Type: floating point
:Range: > 0
:Default: 1.0
This floating point setting controls the vertical camera/mouse sensitivity relative to the horizontal sensitivity (see camera sensitivity above). It is multiplicative with the previous setting, meaning that it should remain set at 1.0 unless the player desires to have different sensitivities in the two axes.
The default value is 1.0. This setting can only be configured by editing the settings configuration file.
invert y axis
-------------
:Type: boolean
:Range: True/False
:Default: False
Invert the vertical axis while not in GUI mode. If this setting is true, moving the mouse away from the player will look down, while moving it towards the player will look up. This setting does not affect cursor movement in GUI mode.
The default value is false. This setting can be toggled in game with the Invert Y Axis button in the Controls panel of the Options menu.

@ -0,0 +1,53 @@
Map Settings
############
global map size
---------------
:Type: integer
:Range: >= 1
:Default: 18
This integer setting adjusts the scale of the world map in the GUI mode map window. The value is the width in pixels of each cell in the map, so larger values result in larger more detailed world maps, while smaller values result in smaller less detailed world maps. However, the native resolution of the map source material appears to be 9 pixels per unexplored cell and approximately 18 pixels per explored cell, so values larger than 36 don't produce much additional detail. Similarly, the size of place markers is currently fixed at 12 pixels, so values smaller than this result in overlapping place markers. Values from 12 to 36 are recommended. For reference, Vvardenfell is approximately 41x36 cells.
Warning: Changing this setting affects saved games. The currently explored area is stored as an image in the save file that's overlayed on the default world map in game. When you increase the resolution of the map, the overlay of earlier saved games will be scaled up on load, and appear blurry. When you visit the cell again, the overlay for that cell is regenerated at the new resolution, so the blurry areas can be corrected by revisiting all the cells you've already visited.
The default value for this setting is 18. This setting can not be configured except by editing the settings configuration file.
local map hud widget size
-------------------------
:Type: integer
:Range: >= 1
:Default: 256
This integer setting controls the zoom level for the HUD map widget (the map in the lower right corner of the window). A value of 64 results in the HUD map widget displaying one entire exterior cell. Since the GUI mode map displays 3x3 cells, a value of approximately 21 displays the same area as the GUI mode map. Larger values increase the level of zoom, while smaller values are wasteful since there's no map data to display beyond the 3x3 cell grid.
Note that the actual size of the widget is always the same on the screen unless the scaling factor setting in the "GUI" section is changed. Increasing both the scaling factor of the GUI and this setting does result in a higher resolution HUD map, but unfortunately with a scaled direction pointer on top of it.
The default value for this setting is 256. This setting can not be configured except by editing the settings configuration file.
local map resolution
--------------------
:Type: integer
:Range: >= 1
:Default: 256
This integer setting controls the resolution of the GUI mode local map window. Larger values generally increase the visible detail in map. If this setting is half the local map widget size or smaller, the map will generally be be fairly blurry. Setting both options to the same value results in a map with good detail. Values that exceed the local map widget size setting by more than a factor of two are unlikely to provide much of an improvement in detail since they're subsequently scaled back to the approximately the map widget size before display. The video resolution settings interacts with this setting in that regard.
.. warning::
Increasing this setting can increase cell load times, because the map is rendered on demand each time you enter a new cell. Large values may exceed video card limits or exhaust VRAM.
The default value for this setting is 256. This setting can not be configured except by editing the settings configuration file.
local map widget size
---------------------
:Type: integer
:Range: >= 1
:Default: 512
This integer setting controls the canvas size of the GUI mode local map window. Larger values result in a larger physical map size on screen, and typically require more panning to see all available portions of the map. This larger size also enables an overall greater level of detail if the local map resolution setting is also increased.
The default value for this setting is 512. This setting can not be configured except by editing the settings configuration file.

@ -0,0 +1,35 @@
Saves Settings
##############
character
---------
:Type: string
:Range:
:Default: ""
This string setting contains the default character name for loading saved games.
The default value is the empty string, which results in no character being selected by default. This setting is automatically updated from the Load menu when a different character is selected.
autosave
--------
:Type: boolean
:Range: True/False
:Default: True
This boolean setting determines whether the game will be automatically saved when the character rests.
The default value is true. This setting can be toggled in game with the Auto-Save when Rest button in the Prefs panel of the Options menu.
timeplayed
----------
:Type: boolean
:Range: True/False
:Default: False
This boolean setting determines whether the amount of the time the player has spent playing will be displayed for each saved game in the Load menu.
The default value is false. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW 0.37.

@ -0,0 +1,113 @@
Sound Settings
##############
device
------
:Type: string
:Range:
:Default: ""
This string setting determines which audio device to use. A blank or missing setting means to use the default device, which should usually be sufficient, but if you need to explicitly specify a device use this setting.
The names of detected devices can be found in the openmw.log file in your configuration directory.
The default value is the empty string. This setting can only be configured by editing the settings configuration file.
master volume
-------------
:Type: floating point
:Range: 0.0 to 1.0
:Default: 1.0
This floating point setting controls the overall volume. The master volume is multiplied with all other volume settings to determine the final volume.
The default value is 1.0. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Master slider from the Audio panel of the Options menu.
footsteps volume
----------------
:Type: floating point
:Range: 0.0 to 1.0
:Default: 0.2
This floating point setting controls the volume of footsteps from the character and other actors.
The default value is 0.2. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Footsteps slider from the Audio panel of the Options menu.
music volume
------------
:Type: floating point
:Range: 0.0 to 1.0
:Default: 0.5
This floating point setting controls the volume for music tracks.
The default value is 0.5. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Music slider from the Audio panel of the Options menu.
sfx volume
----------
:Type: floating point
:Range: 0.0 to 1.0
:Default: 1.0
This floating point setting controls the volume for special sound effects such as combat noises.
The default value is 1.0. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Effects slider from the Audio panel of the Options menu.
voice volume
------------
:Type: floating point
:Range: 0.0 to 1.0
:Default: 0.8
This floating point setting controls the volume for spoken dialog from NPCs.
The default value is 0.8. Valid values range from 0.0 (silent) to 1.0 (maximum volume). This setting can be changed in game using the Voice slider from the Audio panel of the Options menu.
buffer cache min
----------------
:Type: integer
:Range: > 0
:Default: 14
This integer setting determines the minimum size of the sound buffer cache in megabytes. When the cache reaches the size specified by the buffer cache max setting, old buffers will be unloaded until it's using no more memory than specified by this setting. This setting must be less than or equal to the buffer cache max setting.
The default value is 14. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38.
buffer cache max
----------------
:Type: integer
:Range: > 0
:Default: 16
This integer setting determines the maximum size of the sound buffer cache in megabytes. When the cache reaches this size, old buffers will be unloaded until it reaches the size specified by the buffer cache min setting. This setting must be greater than or equal to the buffer cache min setting.
The default value is 16. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38.
hrtf enable
-----------
:Type: integer
:Range: -1, 0, 1
:Default: -1
This integer setting determines whether to enable head-related transfer function (HRTF) audio processing. HRTF audio processing creates the perception of sounds occurring in a three dimensional space when wearing headphones. Enabling HRTF may also require an OpenAL Soft version greater than 1.17.0, and possibly some operating system configuration. A value of 0 disables HRTF processing, while a value of 1 explicitly enables HRTF processing.
The default value is -1, which should enable the feature automatically for most users when possible. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38.
hrtf
----
:Type: string
:Range:
:Default: ""
This string setting specifies which HRTF profile to use when HRTF is enabled. Blank means use the default. This setting has no effect if HRTF is not enabled based on the hrtf enable setting. Allowed values for this field are enumerated in openmw.log file is an HRTF enabled ausio system is installed.
The default value is the empty string, which uses the default profile. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW version 0.38.

@ -0,0 +1,135 @@
Video Settings
##############
resolution x
------------
:Type: integer
:Range: > 0
:Default: 800
This setting determines the horizontal resolution of the OpenMW game window. Larger values produce more detailed images within the constraints of your graphics hardware but also significantly reduce the frame rate.
The default value is 800. The window resolution can be selected from a menu of common screen sizes in the Video tab of the Video Panel of the Options menu, or in the Graphics tab of the OpenMW Launcher. The horizontal resolution can also be set to a custom value in the Graphics tab of the OpenMW Launcher.
resolution y
------------
:Type: integer
:Range: > 0
:Default: 600
This setting determines the vertical resolution of the OpenMW game window. Larger values produce more detailed images within the constraints of your graphics hardware but also significantly reduce the frame rate.
The default value is 600. The window resolution can be selected from a menu of common screen sizes in the Video tab of the Video Panel of the Options menu, or in the Graphics tab of the OpenMW Launcher. The vertical resolution can also be set to a custom value in the Graphics tab of the OpenMW Launcher.
fullscreen
----------
:Type: boolean
:Range: True/False
:Default: False
This boolean setting determines whether the entire screen is used for the specified resolution.
The default value is false. This setting can be toggled in game using the Fullscreen button in the Video tab of the Video panel in the Options menu. It can also be toggled with the Full Screen check box in the Graphics tab of the OpenMW Launcher.
screen
------
:Type: integer
:Range: >= 0
:Default: 0
This integer setting determines which screen the game will open on in multi-monitor configurations. This setting is particularly important when the fullscreen setting is true, since this is the only way to control which screen is used, but it can also be used to control which screen a normal window or a borderless window opens on as well. The screens are numbered in increasing order, beginning with 0.
The default value is 0. This setting can be selected from a pull down menu in the Graphics tab of the OpenMW Launcher, but cannot be changed during game play.
minimize on focus loss
----------------------
:Type: boolean
:Range: True/False
:Default: False
Minimize the OpenMW window if it loses cursor focus. This setting is primarily useful for single screen configurations, so that the OpenMW screen in full screen mode can be minimized when the operating system regains control of the mouse and keyboard. On multiple screen configurations, disabling this option makes it easier to switch between screens while playing OpenMW.
Note that a minimized game window consumes less system resources and produces less heat, since the game does not need to render in minimized state. It is therefore advisable to minimize the game during pauses (either via use of this setting, or by minimizing the window manually).
This setting has no effect if the fullscreen setting is false.
Developer note: corresponds to SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS.
The default value is true. This setting can only be configured by editing the settings configuration file.
window border
-------------
:Type: boolean
:Range: True/False
:Default: True
This boolean setting determines whether there's an operating system border drawn around the OpenMW window. If this setting is true, the window can be moved and resized with the operating system window controls. If this setting is false, the window has no operating system border.
This setting has no effect if the fullscreen setting is true.
The default value is true. This setting can be toggled in game using the Window Border button in the Video tab of the Video panel in the Options menu. It can also be toggled with the Window Border check box in the OpenMW Launcher.
antialiasing
------------
:Type: integer
:Range: 0, 2, 4, 8, 16
:Default: 0
This integer setting controls anti-aliasing. Anti-aliasing is a technique designed to improve the appearance of polygon edges, so they do not appear to be "jagged". Anti-aliasing can smooth these edges at the cost of a minor reduction in the frame rate. A value of 0 disables anti-aliasing. Other powers of two (e.g. 2, 4, 8, 16) are supported according to the capabilities of your graphics hardware. Higher values do a better job of smoothing out the image but have a greater impact on frame rate.
This setting can be configured from a list of valid choices in the Graphics panel of the OpenMW Launcher, but cannot be changed during game play - due to a technical limitation that may be addressed in a future version of OpenMW.
vsync
-----
:Type: boolean
:Range: True/False
:Default: False
This boolean setting determines whether frame draws are synchronized with the vertical refresh rate of your monitor. Enabling this setting can reduce screen tearing, a visual defect caused by updating the image buffer in the middle of a screen draw. Enabling this option typically implies limiting the framerate to 60 frames per second, but may also introduce additional delays caused by having to wait until the appropriate time (the vertical blanking interval) to draw a frame.
The default value is false. This setting can be adjusted in game using the VSync button in the Video tab of the Video panel in the Options menu. It can also be changed by toggling the Vertical Sync check box in the Graphics tab of the OpenMW Launcher.
framerate limit
---------------
:Type: floating point
:Range: >= 0.0
:Default: 0.0
This floating point setting determines the maximum frame rate in frames per second. If this setting is 0.0, the frame rate is unlimited.
There are several reasons to consider capping your frame rate, especially if you're already experiencing a relatively high frame rate (greater than 60 frames per second). Lower frame rates will consume less power and generate less heat and noise. Frame rates above 60 frames per second rarely produce perceptible improvements in visual quality, but may improve input responsiveness. Capping the frame rate may in some situations reduce the perception of choppiness (highly variable frame rates during game play) by lowering the peak frame rates.
This setting interacts with the vsync setting in the Video section in the sense that enabling vertical sync limits the frame rate to the refresh rate of your monitor (often 60 frames per second). Choosing to limit the frame rate using this setting instead of vsync may reduce input lag due to the game not having to wait for the vertical blanking interval.
The default value is 0.0. This setting can only be configured by editing the settings configuration file. This setting was added in OpenMW 0.37.
contrast
--------
:Type: floating point
:Range: > 0.0
:Default: 1.0
This floating point setting controls the contrast correction for all video in the game.
The default value is 1.0. This setting can only be configured by editing the settings configuration file. This setting does not currently work under Linux.
gamma
-----
:Type: floating point
:Range: > 0.0
:Default: 1.0
This floating point setting controls the gamma correction for all video in the game. Gamma is an exponent that makes colors brighter if greater than 1.0 and darker if less than 1.0.
The default value is 1.0. This setting can be changed in the Detail tab of the Video panel of the Options menu. This setting does not currently work under Linux, and the in-game setting in the Options menu has been disabled.

@ -0,0 +1,43 @@
Water Settings
############
.. note::
The settings for the water shader are difficult to describe, but can be seen immediately in the Water tab of the Video panel in the Options menu. Changes there will be saved to these settings. It is suggested to stand on the shore of a moderately broad body of water with trees or other objects on the far shore to test reflection textures, underwater plants in shallow water near by to test refraction textures, and some deep water visible from your location to test deep water visibility.
shader
------
:Type: boolean
:Range: True/False
:Default: False
This boolean setting enables or disables the water shader, which results in much more realistic looking water surfaces, including reflected objects and a more detailed wavy surface.
The default value is false. This setting can be toggled with the Shader button in the Water tab of the Video panel of the Options menu.
rtt size
--------
:Type: integer
:Range: > 0
:Default: 512
The integer setting determines the size of the texture used for reflection and refraction (if enabled). For reflection, the texture size determines the detail of reflected images on the surface of the water. For refraction, the texture size determines the detail of the objects on the other side of the plane of water (which have a wavy appearance caused by the refraction). RTT is an acronym for Render to Texture which allows rendering of the scene to be saved as a texture.
Higher values produces better visuals and result in a marginally lower frame rate depending on your graphics hardware.
In the Water tab of the Video panel of the Options menu, the choices are Low (512), Medium (1024) and High (2048). This setting has no effect if the shader setting is false. It is recommended to use values that are a power of two because this results in more efficient use of video hardware.
This setting has no effect if the shader setting is false.
refraction
----------
:Type: boolean
:Range: True/False
:Default: False
This boolean setting enables the refraction rendering feature of the water shader. Refraction causes deep water to be more opaque and objects seen through the plane of the water to have a wavy appearance. Enabling this feature results in better visuals, and a marginally lower frame rate depending on your graphics hardware.
This setting has no effect if the shader setting is false.
The default setting is false. This setting can be toggled with the Refraction button in the Water tab of the Video panel of the Options menu.

@ -0,0 +1,149 @@
Windows Settings
############
:Type: floating point
:Range: 0.0 to 1.0
This section controls the location and size of each window in GUI mode. Each setting is a floating point number representing a *fraction* of the resolution x or resolution y setting in the Video Settings Section. The X and Y values locate the top left corner of the window, while the W value determines the width of the window and the H value determines the height of the window.
Unlike the documentation for most sections which lists the exact setting name, this page instead lists the names of the windows. For example, to configure the alchemy window, the actual settings would be::
alchemy x = 0.25
alchemy y = 0.25
alchemy h = 0.5
alchemy w = 0.5
Each window in the GUI mode remembers it's previous location when exiting the game. By far the easiest way to configure these settings is to simply move the windows around in game. Hand editing the configuration file might result in some fine tuning for alignment, but the settings will be overwritten if a window is moved.
.. note::
To scale the windows, making the widgets proportionally larger, see the scaling factor setting instead.
stats
-----
:Default: x = 0.0
y = 0.0
h = 0.375
w = 0.4275
The stats window, displaying level, race, class, skills and stats. Activated by clicking on any of the three bars in the lower left corner of the HUD.
spells
------
:Default: x = 0.625
y = 0.5725
h = 0.375
w = 0.4275
The spells window, displaying powers, spells, and magical items. Activated by clicking on the spells widget (third from left) in the bottom left corner of the HUD.
map
---
:Default: x = 0.625
y = 0.0
h = 0.375
w = 0.5725
The local and world map window. Activated by clicking on the map widget in the bottom right corner of the HUD.
dialogue
--------
:Default: x = 0.095
y = 0.095
h = 0.810
w = 0.810
The dialog window, for talking with NPCs. Activated by clicking on a NPC.
alchemy
-------
:Default: x = 0.25
y = 0.25
h = 0.5
w = 0.5
The alchemy window, for crafting potions. Activated by dragging an alchemy tool on to the rag doll. Unlike most other windows, this window hides all other windows when opened.
console
-------
:Default: x = 0.0
y = 0.0
h = 1.0
w = 0.5
The console command window. Activated by pressing the tilde (~) key.
inventory
---------
:Default: x = 0.0
y = 0.4275
h = 0.6225
w = 0.5725
The inventory window, displaying the paper doll and possessions, when activated by clicking on the inventory widget (second from left) in the bottom left corner of the HUD.
inventory container
-------------------
:Default: x = 0.0
y = 0.4275
h = 0.6225
w = 0.5725
The player's inventory window while searching a container, showing the contents of the character's inventory. Activated by clicking on a container. The same window is used for searching dead bodies, and pickpocketing people.
inventory barter
----------------
:Default: x = 0.0
y = 0.4275
h = 0.6225
w = 0.5725
The player's inventory window while bartering. It displays goods owned by the character while bartering. Activated by clicking on the Barter choice in the dialog window for an NPC.
inventory companion
-------------------
:Default: x = 0.0
y = 0.4275
h = 0.6225
w = 0.5725
The player's inventory window while interacting with a companion. The companion windows were added in the Tribunal expansion, but are available everywhere in the OpenMW engine.
container
---------
:Default: x = 0.25
y = 0.0
h = 0.75
w = 0.375
The container window, showing the contents of the container. Activated by clicking on a container. The same window is used for searching dead bodies, and pickpocketing people.
barter
------
:Default: x = 0.25
y = 0.0
h = 0.75
w = 0.375
The NPC bartering window, displaying goods owned by the shopkeeper while bartering. Activated by clicking on the Barter choice in the dialog window for an NPC.
companion
---------
:Default: x = 0.25
y = 0.0
h = 0.75
w = 0.375
The NPC's inventory window while interacting with a companion. The companion windows were added in the Tribunal expansion, but are available everywhere in the OpenMW engine.
Loading…
Cancel
Save