1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-11 15:40:39 +00:00

references now initialized when they are needed

This commit is contained in:
terrorfisch 2014-10-10 23:32:15 +02:00
parent bbca942601
commit 4eb1668467
2 changed files with 66 additions and 49 deletions

View File

@ -43,7 +43,7 @@ namespace
float getXAngleToDir(const Ogre::Vector3& dir, float dirLen = 0.0f)
{
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)
{
// get or create temporary storage
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
if(actor.getClass().getCreatureStats(actor).isDead())
@ -233,9 +215,16 @@ namespace MWMechanics
{
actorClass.getCreatureStats(actor).setAttackingOrSpell(false);
return true;
}
}
//Update every frame
bool& combatMove = storage.mCombatMove;
float& timerCombatMove = storage.mTimerCombatMove;
MWMechanics::Movement& movement = storage.mMovement;
if(combatMove)
{
timerCombatMove -= duration;
@ -266,6 +255,16 @@ namespace MWMechanics
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 (!minMaxAttackDurationInitialised)
@ -287,8 +286,11 @@ namespace MWMechanics
actorClass.getCreatureStats(actor).setAttackingOrSpell(attack);
actionCooldown -= duration;
float& actionCooldown = storage.mActionCooldown;
actionCooldown -= duration;
float& timerReact = storage.mTimerReact;
float tReaction = 0.25f;
if(timerReact < tReaction)
{
@ -299,7 +301,7 @@ namespace MWMechanics
//Update with period = tReaction
timerReact = 0;
const MWWorld::CellStore*& currentCell = storage.mCell;
bool cellChange = currentCell && (actor.getCell() != currentCell);
if(!currentCell || cellChange)
{
@ -317,6 +319,7 @@ namespace MWMechanics
float rangeAttack = 0;
float rangeFollow = 0;
boost::shared_ptr<Action>& currentAction = storage.mCurrentAction;
if (anim->upperBodyReady())
{
currentAction = prepareNextAction(actor, target);
@ -382,6 +385,8 @@ namespace MWMechanics
weapRange = 150.f;
}
float& strength = storage.mStrength;
// start new attack
if(readyToAttack)
{
@ -447,6 +452,9 @@ namespace MWMechanics
Ogre::Vector3 vTargetPos(target.getRefData().getPosition().pos);
Ogre::Vector3 vDirToTarget = vTargetPos - vActorPos;
float distToTarget = vDirToTarget.length();
Ogre::Vector3& lastActorPos = storage.mLastActorPos;
bool& followTarget = storage.mFollowTarget;
bool isStuck = false;
float speed = 0.0f;
@ -473,6 +481,7 @@ namespace MWMechanics
// note: in getZAngleToDir if we preserve dir.z then horizontal angle can be inaccurate
if (distantCombat)
{
Ogre::Vector3& lastTargetPos = storage.mLastTargetPos;
Ogre::Vector3 vAimDir = AimDirToMovingTarget(actor, target, lastTargetPos, tReaction, weaptype, strength);
lastTargetPos = vTargetPos;
movement.mRotation[0] = getXAngleToDir(vAimDir);
@ -525,6 +534,9 @@ namespace MWMechanics
if (!distantCombat) inLOS = world->getLOS(actor, target);
// check if shortcut is available
bool& forceNoShortcut = storage.mForceNoShortcut;
ESM::Position& shortcutFailPos = storage.mShortcutFailPos;
if(inLOS && (!isStuck || readyToAttack)
&& (!forceNoShortcut || (Ogre::Vector3(shortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST))
{

View File

@ -33,7 +33,7 @@ namespace MWMechanics
{
// the z rotation angle (degrees) we want to reach
// used every frame when mRotate is true
float mTargetAngle;
Ogre::Radian mTargetAngle;
bool mRotate;
float mReaction; // update some actions infrequently
@ -166,31 +166,16 @@ namespace MWMechanics
*/
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>();
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;
bool& chooseAction = storage.mChooseAction;
bool& idleNow = storage.mIdleNow;
bool& moveNow = storage.mMoveNow;
bool& walking = storage.mWalking;
short unsigned& playedIdle = storage.mPlayedIdle;
const MWWorld::CellStore*& currentCell = storage.mCell;
MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor);
if(cStats.isDead() || cStats.getHealth().getCurrent() <= 0)
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)
{
currentCell = actor.getCell();
@ -202,7 +187,11 @@ namespace MWMechanics
cStats.setMovementFlag(CreatureStats::Flag_Run, false);
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
mDoorCheckDuration += duration;
if(mDoorCheckDuration >= DOOR_CHECK_INTERVAL)
@ -220,6 +209,7 @@ namespace MWMechanics
}
// Are we there yet?
bool& chooseAction = storage.mChooseAction;
if(walking &&
mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
{
@ -230,6 +220,8 @@ namespace MWMechanics
mHasReturnPosition = false;
}
if(walking) // have not yet reached the destination
{
// turn towards the next point in mPath
@ -275,16 +267,20 @@ namespace MWMechanics
}
//#endif
}
Ogre::Radian& targetAngle = storage.mTargetAngle;
bool& rotate = storage.mRotate;
if (rotate)
{
// Reduce the turning animation glitch by using a *HUGE* value of
// epsilon... TODO: a proper fix might be in either the physics or the
// animation subsystem
if (zTurn(actor, Ogre::Degree(targetAngle), Ogre::Degree(5)))
if (zTurn(actor, targetAngle, Ogre::Degree(5)))
rotate = false;
}
float& lastReaction = storage.mReaction;
lastReaction += duration;
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.
if(!mStoredAvailableNodes)
{
@ -435,6 +437,8 @@ namespace MWMechanics
}
}
AiWander::GreetingState& greetingState = storage.mSaidGreeting;
short unsigned& playedIdle = storage.mPlayedIdle;
if(chooseAction)
{
playedIdle = 0;
@ -491,6 +495,7 @@ namespace MWMechanics
Ogre::Vector3 actorPos(actor.getRefData().getPosition().pos);
float playerDistSqr = playerPos.squaredDistance(actorPos);
int& greetingTimer = storage.mGreetingTimer;
if (greetingState == Greet_None)
{
if ((playerDistSqr <= helloDistance*helloDistance) &&
@ -524,10 +529,10 @@ namespace MWMechanics
{
Ogre::Vector3 dir = playerPos - actorPos;
float faceAngle = Ogre::Math::ATan2(dir.x,dir.y).valueDegrees();
float actorAngle = actor.getRefData().getBaseNode()->getOrientation().getRoll().valueDegrees();
Ogre::Radian faceAngle = Ogre::Math::ATan2(dir.x,dir.y);
Ogre::Radian actorAngle = actor.getRefData().getBaseNode()->getOrientation().getRoll();
// 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;
rotate = true;