forked from mirror/openmw-tes3mp
Merge pull request #147 from OpenMW/master
Add OpenMW commits up to 11 Feb 2017
This commit is contained in:
commit
d528a0edb5
7 changed files with 44 additions and 38 deletions
|
@ -328,7 +328,7 @@ namespace MWClass
|
||||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
|
|
||||||
// NOTE: 'object' and/or 'attacker' may be empty.
|
// NOTE: 'object' and/or 'attacker' may be empty.
|
||||||
if (!attacker.isEmpty() && !stats.getAiSequence().isInCombat(attacker))
|
if (!attacker.isEmpty() && attacker.getClass().isActor() && !stats.getAiSequence().isInCombat(attacker))
|
||||||
stats.setAttacked(true);
|
stats.setAttacked(true);
|
||||||
|
|
||||||
// Self defense
|
// Self defense
|
||||||
|
@ -339,7 +339,7 @@ namespace MWClass
|
||||||
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||||
|
|
||||||
// Attacker and target store each other as hitattemptactor if they have no one stored yet
|
// Attacker and target store each other as hitattemptactor if they have no one stored yet
|
||||||
if (!attacker.isEmpty() && !ptr.isEmpty())
|
if (!attacker.isEmpty() && attacker.getClass().isActor() && !ptr.isEmpty() && ptr.getClass().isActor())
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker);
|
MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker);
|
||||||
// First handle the attacked actor
|
// First handle the attacked actor
|
||||||
|
|
|
@ -682,14 +682,14 @@ namespace MWClass
|
||||||
bool setOnPcHitMe = true;
|
bool setOnPcHitMe = true;
|
||||||
|
|
||||||
// NOTE: 'object' and/or 'attacker' may be empty.
|
// NOTE: 'object' and/or 'attacker' may be empty.
|
||||||
if (!attacker.isEmpty() && !stats.getAiSequence().isInCombat(attacker))
|
if (!attacker.isEmpty() && attacker.getClass().isActor() && !stats.getAiSequence().isInCombat(attacker))
|
||||||
{
|
{
|
||||||
stats.setAttacked(true);
|
stats.setAttacked(true);
|
||||||
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attacker and target store each other as hitattemptactor if they have no one stored yet
|
// Attacker and target store each other as hitattemptactor if they have no one stored yet
|
||||||
if (!attacker.isEmpty() && !ptr.isEmpty())
|
if (!attacker.isEmpty() && attacker.getClass().isActor() && !ptr.isEmpty() && ptr.getClass().isActor())
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker);
|
MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker);
|
||||||
// First handle the attacked actor
|
// First handle the attacked actor
|
||||||
|
|
|
@ -304,10 +304,6 @@ namespace MWMechanics
|
||||||
if (!actor1.getClass().isMobile(actor1))
|
if (!actor1.getClass().isMobile(actor1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Stop here if target is unreachable
|
|
||||||
if (!MWMechanics::canFight(actor1, actor2))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If this is set to true, actor1 will start combat with actor2 if the awareness check at the end of the method returns true
|
// If this is set to true, actor1 will start combat with actor2 if the awareness check at the end of the method returns true
|
||||||
bool aggressive = false;
|
bool aggressive = false;
|
||||||
|
|
||||||
|
@ -383,6 +379,10 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop here if target is unreachable
|
||||||
|
if (!MWMechanics::canFight(actor1, actor2))
|
||||||
|
return;
|
||||||
|
|
||||||
// Do aggression check if actor2 is the player or a player follower or escorter
|
// Do aggression check if actor2 is the player or a player follower or escorter
|
||||||
if (!aggressive)
|
if (!aggressive)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "aisequence.hpp"
|
#include "aisequence.hpp"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <components/esm/aisequence.hpp>
|
#include <components/esm/aisequence.hpp>
|
||||||
|
|
||||||
|
@ -229,6 +230,8 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (package->execute (actor,characterController,state,duration))
|
if (package->execute (actor,characterController,state,duration))
|
||||||
{
|
{
|
||||||
// Put repeating noncombat AI packages on the end of the stack so they can be used again
|
// Put repeating noncombat AI packages on the end of the stack so they can be used again
|
||||||
|
@ -251,6 +254,11 @@ void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& charac
|
||||||
mDone = false;
|
mDone = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "Error during AiSequence::execute: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiSequence::clear()
|
void AiSequence::clear()
|
||||||
|
|
|
@ -1221,14 +1221,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
bool MechanicsManager::actorAttacked(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker)
|
bool MechanicsManager::actorAttacked(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker)
|
||||||
{
|
{
|
||||||
|
if (target == getPlayer() || !attacker.getClass().isActor())
|
||||||
|
return false;
|
||||||
|
|
||||||
std::list<MWWorld::Ptr> followersAttacker = getActorsSidingWith(attacker);
|
std::list<MWWorld::Ptr> followersAttacker = getActorsSidingWith(attacker);
|
||||||
std::list<MWWorld::Ptr> followersTarget = getActorsSidingWith(target);
|
|
||||||
|
|
||||||
MWMechanics::CreatureStats& statsTarget = target.getClass().getCreatureStats(target);
|
MWMechanics::CreatureStats& statsTarget = target.getClass().getCreatureStats(target);
|
||||||
|
|
||||||
if (target == getPlayer())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (std::find(followersAttacker.begin(), followersAttacker.end(), target) != followersAttacker.end())
|
if (std::find(followersAttacker.begin(), followersAttacker.end(), target) != followersAttacker.end())
|
||||||
{
|
{
|
||||||
statsTarget.friendlyHit();
|
statsTarget.friendlyHit();
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace MWPhysics
|
||||||
static const float sStepSizeUp = 34.0f;
|
static const float sStepSizeUp = 34.0f;
|
||||||
static const float sStepSizeDown = 62.0f;
|
static const float sStepSizeDown = 62.0f;
|
||||||
static const float sMinStep = 10.f;
|
static const float sMinStep = 10.f;
|
||||||
|
static const float sGroundOffset = 1.0f;
|
||||||
|
|
||||||
// Arbitrary number. To prevent infinite loops. They shouldn't happen but it's good to be prepared.
|
// Arbitrary number. To prevent infinite loops. They shouldn't happen but it's good to be prepared.
|
||||||
static const int sMaxIterations = 8;
|
static const int sMaxIterations = 8;
|
||||||
|
@ -237,13 +238,12 @@ namespace MWPhysics
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, osg::Vec3f position, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight)
|
static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight)
|
||||||
{
|
{
|
||||||
osg::Vec3f offset = actor->getCollisionObjectPosition() - ptr.getRefData().getPosition().asVec3();
|
osg::Vec3f offset = actor->getCollisionObjectPosition() - ptr.getRefData().getPosition().asVec3();
|
||||||
position += offset;
|
|
||||||
|
|
||||||
ActorTracer tracer;
|
ActorTracer tracer;
|
||||||
tracer.findGround(actor, position, position-osg::Vec3f(0,0,maxHeight), collisionWorld);
|
tracer.findGround(actor, position + offset, position + offset - osg::Vec3f(0,0,maxHeight), collisionWorld);
|
||||||
if(tracer.mFraction >= 1.0f)
|
if(tracer.mFraction >= 1.0f)
|
||||||
{
|
{
|
||||||
actor->setOnGround(false);
|
actor->setOnGround(false);
|
||||||
|
@ -266,18 +266,18 @@ namespace MWPhysics
|
||||||
collisionWorld->rayTest(from, to, resultCallback1);
|
collisionWorld->rayTest(from, to, resultCallback1);
|
||||||
|
|
||||||
if (resultCallback1.hasHit() &&
|
if (resultCallback1.hasHit() &&
|
||||||
( (toOsg(resultCallback1.m_hitPointWorld) - tracer.mEndPos).length2() > 35*35
|
( (toOsg(resultCallback1.m_hitPointWorld) - (tracer.mEndPos-offset)).length2() > 35*35
|
||||||
|| !isWalkableSlope(tracer.mPlaneNormal)))
|
|| !isWalkableSlope(tracer.mPlaneNormal)))
|
||||||
{
|
{
|
||||||
actor->setOnSlope(!isWalkableSlope(resultCallback1.m_hitNormalWorld));
|
actor->setOnSlope(!isWalkableSlope(resultCallback1.m_hitNormalWorld));
|
||||||
return toOsg(resultCallback1.m_hitPointWorld) + osg::Vec3f(0.f, 0.f, 1.f);
|
return toOsg(resultCallback1.m_hitPointWorld) + osg::Vec3f(0.f, 0.f, sGroundOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
actor->setOnSlope(!isWalkableSlope(tracer.mPlaneNormal));
|
actor->setOnSlope(!isWalkableSlope(tracer.mPlaneNormal));
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracer.mEndPos;
|
return tracer.mEndPos-offset + osg::Vec3f(0.f, 0.f, sGroundOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
osg::Vec3f from = newPosition;
|
osg::Vec3f from = newPosition;
|
||||||
osg::Vec3f to = newPosition - (physicActor->getOnGround() ?
|
osg::Vec3f to = newPosition - (physicActor->getOnGround() ?
|
||||||
osg::Vec3f(0,0,sStepSizeDown+2.f) : osg::Vec3f(0,0,2.f));
|
osg::Vec3f(0,0,sStepSizeDown + 2*sGroundOffset) : osg::Vec3f(0,0,2*sGroundOffset));
|
||||||
tracer.doTrace(colobj, from, to, collisionWorld);
|
tracer.doTrace(colobj, from, to, collisionWorld);
|
||||||
if(tracer.mFraction < 1.0f
|
if(tracer.mFraction < 1.0f
|
||||||
&& tracer.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup != CollisionType_Actor)
|
&& tracer.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup != CollisionType_Actor)
|
||||||
|
@ -461,7 +461,7 @@ namespace MWPhysics
|
||||||
if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
|
if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
|
||||||
physicActor->setWalkingOnWater(true);
|
physicActor->setWalkingOnWater(true);
|
||||||
if (!isFlying)
|
if (!isFlying)
|
||||||
newPosition.z() = tracer.mEndPos.z() + 1.0f;
|
newPosition.z() = tracer.mEndPos.z() + sGroundOffset;
|
||||||
|
|
||||||
isOnGround = true;
|
isOnGround = true;
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,8 @@ void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& star
|
||||||
|
|
||||||
void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world)
|
void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world)
|
||||||
{
|
{
|
||||||
const btVector3 btstart(start.x(), start.y(), start.z()+1.0f);
|
const btVector3 btstart(start.x(), start.y(), start.z());
|
||||||
const btVector3 btend(end.x(), end.y(), end.z()+1.0f);
|
const btVector3 btend(end.x(), end.y(), end.z());
|
||||||
|
|
||||||
const btTransform &trans = actor->getCollisionObject()->getWorldTransform();
|
const btTransform &trans = actor->getCollisionObject()->getWorldTransform();
|
||||||
btTransform from(trans.getBasis(), btstart);
|
btTransform from(trans.getBasis(), btstart);
|
||||||
|
@ -112,7 +112,6 @@ void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const
|
||||||
mFraction = newTraceCallback.m_closestHitFraction;
|
mFraction = newTraceCallback.m_closestHitFraction;
|
||||||
mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z());
|
mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z());
|
||||||
mEndPos = (end-start)*mFraction + start;
|
mEndPos = (end-start)*mFraction + start;
|
||||||
mEndPos[2] += 1.0f;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue