mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 20:19:40 +00:00
references now initialized when they are needed
This commit is contained in:
parent
bbca942601
commit
4eb1668467
2 changed files with 66 additions and 49 deletions
|
@ -43,7 +43,7 @@ namespace
|
||||||
float getXAngleToDir(const Ogre::Vector3& dir, float dirLen = 0.0f)
|
float getXAngleToDir(const Ogre::Vector3& dir, float dirLen = 0.0f)
|
||||||
{
|
{
|
||||||
float len = (dirLen > 0.0f)? dirLen : dir.length();
|
float len = (dirLen > 0.0f)? dirLen : dir.length();
|
||||||
return -Ogre::Math::ASin(dir.z / len).valueRadians();
|
return -Ogre::Math::ASin(dir.z / len).valueDegrees();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,28 +185,10 @@ namespace MWMechanics
|
||||||
*/
|
*/
|
||||||
bool AiCombat::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
bool AiCombat::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
|
// get or create temporary storage
|
||||||
AiCombatStorage& storage = state.get<AiCombatStorage>();
|
AiCombatStorage& storage = state.get<AiCombatStorage>();
|
||||||
|
|
||||||
// PathFinder& mPathFinder;
|
|
||||||
// ObstacleCheck& mObstacleCheck = storage.mObstacleCheck;
|
|
||||||
float& timerAttack = storage.mTimerAttack;
|
|
||||||
float& timerReact = storage.mTimerReact;
|
|
||||||
float& timerCombatMove = storage.mTimerCombatMove;
|
|
||||||
bool& readyToAttack = storage.mReadyToAttack;
|
|
||||||
bool& attack = storage.mAttack;
|
|
||||||
bool& followTarget = storage.mFollowTarget;
|
|
||||||
bool& combatMove = storage.mCombatMove;
|
|
||||||
Ogre::Vector3& lastTargetPos = storage.mLastTargetPos;
|
|
||||||
const MWWorld::CellStore*& currentCell = storage.mCell;
|
|
||||||
boost::shared_ptr<Action>& currentAction = storage.mCurrentAction;
|
|
||||||
float& actionCooldown = storage.mActionCooldown;
|
|
||||||
float& strength = storage.mStrength;
|
|
||||||
float (&minMaxAttackDuration)[3][2] = storage.mMinMaxAttackDuration;
|
|
||||||
bool& minMaxAttackDurationInitialised = storage.mMinMaxAttackDurationInitialised;
|
|
||||||
bool& forceNoShortcut = storage.mForceNoShortcut;
|
|
||||||
ESM::Position& shortcutFailPos = storage.mShortcutFailPos;
|
|
||||||
Ogre::Vector3& lastActorPos = storage.mLastActorPos;
|
|
||||||
MWMechanics::Movement& movement = storage.mMovement;
|
|
||||||
|
|
||||||
//General description
|
//General description
|
||||||
if(actor.getClass().getCreatureStats(actor).isDead())
|
if(actor.getClass().getCreatureStats(actor).isDead())
|
||||||
|
@ -235,7 +217,14 @@ namespace MWMechanics
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Update every frame
|
//Update every frame
|
||||||
|
bool& combatMove = storage.mCombatMove;
|
||||||
|
float& timerCombatMove = storage.mTimerCombatMove;
|
||||||
|
MWMechanics::Movement& movement = storage.mMovement;
|
||||||
if(combatMove)
|
if(combatMove)
|
||||||
{
|
{
|
||||||
timerCombatMove -= duration;
|
timerCombatMove -= duration;
|
||||||
|
@ -266,6 +255,16 @@ namespace MWMechanics
|
||||||
|
|
||||||
ESM::Weapon::AttackType attackType;
|
ESM::Weapon::AttackType attackType;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool& attack = storage.mAttack;
|
||||||
|
bool& readyToAttack = storage.mReadyToAttack;
|
||||||
|
float& timerAttack = storage.mTimerAttack;
|
||||||
|
|
||||||
|
bool& minMaxAttackDurationInitialised = storage.mMinMaxAttackDurationInitialised;
|
||||||
|
float (&minMaxAttackDuration)[3][2] = storage.mMinMaxAttackDuration;
|
||||||
|
|
||||||
if(readyToAttack)
|
if(readyToAttack)
|
||||||
{
|
{
|
||||||
if (!minMaxAttackDurationInitialised)
|
if (!minMaxAttackDurationInitialised)
|
||||||
|
@ -287,8 +286,11 @@ namespace MWMechanics
|
||||||
|
|
||||||
actorClass.getCreatureStats(actor).setAttackingOrSpell(attack);
|
actorClass.getCreatureStats(actor).setAttackingOrSpell(attack);
|
||||||
|
|
||||||
|
|
||||||
|
float& actionCooldown = storage.mActionCooldown;
|
||||||
actionCooldown -= duration;
|
actionCooldown -= duration;
|
||||||
|
|
||||||
|
float& timerReact = storage.mTimerReact;
|
||||||
float tReaction = 0.25f;
|
float tReaction = 0.25f;
|
||||||
if(timerReact < tReaction)
|
if(timerReact < tReaction)
|
||||||
{
|
{
|
||||||
|
@ -299,7 +301,7 @@ namespace MWMechanics
|
||||||
//Update with period = tReaction
|
//Update with period = tReaction
|
||||||
|
|
||||||
timerReact = 0;
|
timerReact = 0;
|
||||||
|
const MWWorld::CellStore*& currentCell = storage.mCell;
|
||||||
bool cellChange = currentCell && (actor.getCell() != currentCell);
|
bool cellChange = currentCell && (actor.getCell() != currentCell);
|
||||||
if(!currentCell || cellChange)
|
if(!currentCell || cellChange)
|
||||||
{
|
{
|
||||||
|
@ -317,6 +319,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
float rangeAttack = 0;
|
float rangeAttack = 0;
|
||||||
float rangeFollow = 0;
|
float rangeFollow = 0;
|
||||||
|
boost::shared_ptr<Action>& currentAction = storage.mCurrentAction;
|
||||||
if (anim->upperBodyReady())
|
if (anim->upperBodyReady())
|
||||||
{
|
{
|
||||||
currentAction = prepareNextAction(actor, target);
|
currentAction = prepareNextAction(actor, target);
|
||||||
|
@ -382,6 +385,8 @@ namespace MWMechanics
|
||||||
weapRange = 150.f;
|
weapRange = 150.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float& strength = storage.mStrength;
|
||||||
// start new attack
|
// start new attack
|
||||||
if(readyToAttack)
|
if(readyToAttack)
|
||||||
{
|
{
|
||||||
|
@ -448,6 +453,9 @@ namespace MWMechanics
|
||||||
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
|
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
|
||||||
float distToTarget = vDirToTarget.length();
|
float distToTarget = vDirToTarget.length();
|
||||||
|
|
||||||
|
Ogre::Vector3& lastActorPos = storage.mLastActorPos;
|
||||||
|
bool& followTarget = storage.mFollowTarget;
|
||||||
|
|
||||||
bool isStuck = false;
|
bool isStuck = false;
|
||||||
float speed = 0.0f;
|
float speed = 0.0f;
|
||||||
if(movement.mPosition[1] && (lastActorPos - vActorPos).length() < (speed = actorClass.getSpeed(actor)) * tReaction / 2)
|
if(movement.mPosition[1] && (lastActorPos - vActorPos).length() < (speed = actorClass.getSpeed(actor)) * tReaction / 2)
|
||||||
|
@ -473,6 +481,7 @@ namespace MWMechanics
|
||||||
// note: in getZAngleToDir if we preserve dir.z then horizontal angle can be inaccurate
|
// note: in getZAngleToDir if we preserve dir.z then horizontal angle can be inaccurate
|
||||||
if (distantCombat)
|
if (distantCombat)
|
||||||
{
|
{
|
||||||
|
Ogre::Vector3& lastTargetPos = storage.mLastTargetPos;
|
||||||
Ogre::Vector3 vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
|
Ogre::Vector3 vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
|
||||||
lastTargetPos = vTargetPos;
|
lastTargetPos = vTargetPos;
|
||||||
movement.mRotation[0] = getXAngleToDir(vAimDir);
|
movement.mRotation[0] = getXAngleToDir(vAimDir);
|
||||||
|
@ -525,6 +534,9 @@ namespace MWMechanics
|
||||||
if (!distantCombat) inLOS = world->getLOS(actor, target);
|
if (!distantCombat) inLOS = world->getLOS(actor, target);
|
||||||
|
|
||||||
// check if shortcut is available
|
// check if shortcut is available
|
||||||
|
bool& forceNoShortcut = storage.mForceNoShortcut;
|
||||||
|
ESM::Position& shortcutFailPos = storage.mShortcutFailPos;
|
||||||
|
|
||||||
if(inLOS && (!isStuck || readyToAttack)
|
if(inLOS && (!isStuck || readyToAttack)
|
||||||
&& (!forceNoShortcut || (Ogre::Vector3(shortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST))
|
&& (!forceNoShortcut || (Ogre::Vector3(shortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST))
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
// the z rotation angle (degrees) we want to reach
|
// the z rotation angle (degrees) we want to reach
|
||||||
// used every frame when mRotate is true
|
// used every frame when mRotate is true
|
||||||
float mTargetAngle;
|
Ogre::Radian mTargetAngle;
|
||||||
bool mRotate;
|
bool mRotate;
|
||||||
float mReaction; // update some actions infrequently
|
float mReaction; // update some actions infrequently
|
||||||
|
|
||||||
|
@ -166,31 +166,16 @@ namespace MWMechanics
|
||||||
*/
|
*/
|
||||||
bool AiWander::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
bool AiWander::execute (const MWWorld::Ptr& actor, AiState& state, float duration)
|
||||||
{
|
{
|
||||||
// define references for readability
|
// get or create temporary storage
|
||||||
AiWanderStorage& storage = state.get<AiWanderStorage>();
|
AiWanderStorage& storage = state.get<AiWanderStorage>();
|
||||||
|
|
||||||
float& targetAngle = storage.mTargetAngle;
|
|
||||||
bool& rotate = storage.mRotate;
|
|
||||||
float& lastReaction = storage.mReaction;
|
|
||||||
AiWander::GreetingState& greetingState = storage.mSaidGreeting;
|
|
||||||
int& greetingTimer = storage.mGreetingTimer;
|
|
||||||
int& cachedCellX = storage.mCellX;
|
|
||||||
int& cachedCellY = storage.mCellY;
|
|
||||||
float& cachedCellXposition = storage.mXCell;
|
|
||||||
float& cachedCellYposition = storage.mYCell;
|
|
||||||
const MWWorld::CellStore*& currentCell = storage.mCell;
|
const MWWorld::CellStore*& currentCell = storage.mCell;
|
||||||
bool& chooseAction = storage.mChooseAction;
|
|
||||||
bool& idleNow = storage.mIdleNow;
|
|
||||||
bool& moveNow = storage.mMoveNow;
|
|
||||||
bool& walking = storage.mWalking;
|
|
||||||
short unsigned& playedIdle = storage.mPlayedIdle;
|
|
||||||
|
|
||||||
|
|
||||||
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
|
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
|
||||||
if(cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
|
if(cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
|
||||||
return true; // Don't bother with dead actors
|
return true; // Don't bother with dead actors
|
||||||
|
|
||||||
bool cellChange = storage.mCell && (actor.getCell() != storage.mCell);
|
bool cellChange = currentCell && (actor.getCell() != currentCell);
|
||||||
if(!currentCell || cellChange)
|
if(!currentCell || cellChange)
|
||||||
{
|
{
|
||||||
currentCell = actor.getCell();
|
currentCell = actor.getCell();
|
||||||
|
@ -203,6 +188,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
|
|
||||||
|
|
||||||
|
bool& idleNow = storage.mIdleNow;
|
||||||
|
bool& moveNow = storage.mMoveNow;
|
||||||
|
bool& walking = storage.mWalking;
|
||||||
// Check if an idle actor is too close to a door - if so start walking
|
// Check if an idle actor is too close to a door - if so start walking
|
||||||
mDoorCheckDuration += duration;
|
mDoorCheckDuration += duration;
|
||||||
if(mDoorCheckDuration >= DOOR_CHECK_INTERVAL)
|
if(mDoorCheckDuration >= DOOR_CHECK_INTERVAL)
|
||||||
|
@ -220,6 +209,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we there yet?
|
// Are we there yet?
|
||||||
|
bool& chooseAction = storage.mChooseAction;
|
||||||
if(walking &&
|
if(walking &&
|
||||||
mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
|
mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
|
||||||
{
|
{
|
||||||
|
@ -230,6 +220,8 @@ namespace MWMechanics
|
||||||
mHasReturnPosition = false;
|
mHasReturnPosition = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(walking) // have not yet reached the destination
|
if(walking) // have not yet reached the destination
|
||||||
{
|
{
|
||||||
// turn towards the next point in mPath
|
// turn towards the next point in mPath
|
||||||
|
@ -276,15 +268,19 @@ namespace MWMechanics
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ogre::Radian& targetAngle = storage.mTargetAngle;
|
||||||
|
bool& rotate = storage.mRotate;
|
||||||
if (rotate)
|
if (rotate)
|
||||||
{
|
{
|
||||||
// Reduce the turning animation glitch by using a *HUGE* value of
|
// Reduce the turning animation glitch by using a *HUGE* value of
|
||||||
// epsilon... TODO: a proper fix might be in either the physics or the
|
// epsilon... TODO: a proper fix might be in either the physics or the
|
||||||
// animation subsystem
|
// animation subsystem
|
||||||
if (zTurn(actor, Ogre::Degree(targetAngle), Ogre::Degree(5)))
|
if (zTurn(actor, targetAngle, Ogre::Degree(5)))
|
||||||
rotate = false;
|
rotate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float& lastReaction = storage.mReaction;
|
||||||
lastReaction += duration;
|
lastReaction += duration;
|
||||||
if(lastReaction < REACTION_INTERVAL)
|
if(lastReaction < REACTION_INTERVAL)
|
||||||
{
|
{
|
||||||
|
@ -322,6 +318,12 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int& cachedCellX = storage.mCellX;
|
||||||
|
int& cachedCellY = storage.mCellY;
|
||||||
|
float& cachedCellXposition = storage.mXCell;
|
||||||
|
float& cachedCellYposition = storage.mYCell;
|
||||||
// Initialization to discover & store allowed node points for this actor.
|
// Initialization to discover & store allowed node points for this actor.
|
||||||
if(!mStoredAvailableNodes)
|
if(!mStoredAvailableNodes)
|
||||||
{
|
{
|
||||||
|
@ -435,6 +437,8 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AiWander::GreetingState& greetingState = storage.mSaidGreeting;
|
||||||
|
short unsigned& playedIdle = storage.mPlayedIdle;
|
||||||
if(chooseAction)
|
if(chooseAction)
|
||||||
{
|
{
|
||||||
playedIdle = 0;
|
playedIdle = 0;
|
||||||
|
@ -491,6 +495,7 @@ namespace MWMechanics
|
||||||
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
|
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
|
||||||
float playerDistSqr = playerPos.squaredDistance(actorPos);
|
float playerDistSqr = playerPos.squaredDistance(actorPos);
|
||||||
|
|
||||||
|
int& greetingTimer = storage.mGreetingTimer;
|
||||||
if (greetingState == Greet_None)
|
if (greetingState == Greet_None)
|
||||||
{
|
{
|
||||||
if ((playerDistSqr <= helloDistance*helloDistance) &&
|
if ((playerDistSqr <= helloDistance*helloDistance) &&
|
||||||
|
@ -524,10 +529,10 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
Ogre::Vector3 dir = playerPos - actorPos;
|
Ogre::Vector3 dir = playerPos - actorPos;
|
||||||
|
|
||||||
float faceAngle = Ogre::Math::ATan2(dir.x,dir.y).valueDegrees();
|
Ogre::Radian faceAngle = Ogre::Math::ATan2(dir.x,dir.y);
|
||||||
float actorAngle = actor.getRefData().getBaseNode()->getOrientation().getRoll().valueDegrees();
|
Ogre::Radian actorAngle = actor.getRefData().getBaseNode()->getOrientation().getRoll();
|
||||||
// an attempt at reducing the turning animation glitch
|
// an attempt at reducing the turning animation glitch
|
||||||
if(abs(abs(faceAngle) - abs(actorAngle)) >= 5) // TODO: is there a better way?
|
if( Ogre::Math::Abs( faceAngle - actorAngle ) >= Ogre::Degree(5) ) // TODO: is there a better way?
|
||||||
{
|
{
|
||||||
targetAngle = faceAngle;
|
targetAngle = faceAngle;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
|
|
Loading…
Reference in a new issue