1
0
Fork 1
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:
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 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))
{ {

View file

@ -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;