@ -275,7 +275,8 @@ namespace MWWorld
+ mStore . countSavedGameRecords ( )
+ mGlobalVariables . countSavedGameRecords ( )
+ 1 // player record
+ 1 ; // weather record
+ 1 // weather record
+ 1 ; // actorId counter
}
void World : : write ( ESM : : ESMWriter & writer , Loading : : Listener & progress ) const
@ -288,6 +289,9 @@ namespace MWWorld
mRendering - > writeFog ( cellstore ) ;
}
MWMechanics : : CreatureStats : : writeActorIdCounter ( writer ) ;
progress . increaseProgress ( ) ;
mCells . write ( writer , progress ) ;
mStore . write ( writer , progress ) ;
mGlobalVariables . write ( writer , progress ) ;
@ -298,6 +302,12 @@ namespace MWWorld
void World : : readRecord ( ESM : : ESMReader & reader , int32_t type ,
const std : : map < int , int > & contentFileMap )
{
if ( type = = ESM : : REC_ACTC )
{
MWMechanics : : CreatureStats : : readActorIdCounter ( reader ) ;
return ;
}
if ( ! mStore . readRecord ( reader , type ) & &
! mGlobalVariables . readRecord ( reader , type ) & &
! mPlayer - > readRecord ( reader , type ) & &
@ -547,17 +557,17 @@ namespace MWWorld
{
if ( mPlayer - > getPlayer ( ) . getRefData ( ) . getHandle ( ) = = handle )
return mPlayer - > getPlayer ( ) ;
for ( Scene : : CellStoreCollection : : const_iterator iter ( mWorldScene - > getActiveCells ( ) . begin ( ) ) ;
iter ! = mWorldScene - > getActiveCells ( ) . end ( ) ; + + iter )
{
CellStore * cellstore = * iter ;
Ptr ptr = cellstore - > searchViaHandle ( handle ) ;
if ( ! ptr . isEmpty ( ) )
return ptr ;
}
return mWorldScene - > searchPtrViaHandle ( handle ) ;
}
return MWWorld : : Ptr ( ) ;
Ptr World : : searchPtrViaActorId ( int actorId )
{
// The player is not registered in any CellStore so must be checked manually
if ( actorId = = getPlayerPtr ( ) . getClass ( ) . getCreatureStats ( getPlayerPtr ( ) ) . getActorId ( ) )
return getPlayerPtr ( ) ;
// Now search cells
return mWorldScene - > searchPtrViaActorId ( actorId ) ;
}
void World : : addContainerScripts ( const Ptr & reference , CellStore * cell )
@ -1196,36 +1206,48 @@ namespace MWWorld
while ( it ! = mDoorStates . end ( ) )
{
if ( ! mWorldScene - > isCellActive ( * it - > first . getCell ( ) ) | | ! it - > first . getRefData ( ) . getBaseNode ( ) )
{
// The door is no longer in an active cell, or it was disabled.
// Erase from mDoorStates, since we no longer need to move it.
// Once we load the door's cell again (or re-enable the door), Door::insertObject will reinsert to mDoorStates.
mDoorStates . erase ( it + + ) ;
}
else
{
float oldRot = Ogre : : Radian ( it - > first . getRefData ( ) . getLocalRotation ( ) . rot [ 2 ] ) . valueDegrees ( ) ;
float diff = duration * 90 ;
float targetRot = std : : min ( std : : max ( 0.f , oldRot + diff * ( it - > second ? 1 : - 1 ) ) , 90.f ) ;
float targetRot = std : : min ( std : : max ( 0.f , oldRot + diff * ( it - > second == 1 ? 1 : - 1 ) ) , 90.f ) ;
localRotateObject ( it - > first , 0 , 0 , targetRot ) ;
bool reached = ( targetRot = = 90.f & & it - > second ) | | targetRot = = 0.f ;
/// \todo should use convexSweepTest here
std : : vector < std : : string > collisions = mPhysics - > getCollisions ( it - > first ) ;
for ( std : : vector < std : : string > : : iterator cit = collisions . begin ( ) ; cit ! = collisions . end ( ) ; + + cit )
{
MWWorld : : Ptr ptr = getPtrViaHandle ( * cit ) ;
if ( MWWorld: : Class : : get ( ptr ) . isActor ( ) )
if ( ptr. getClass ( ) . isActor ( ) )
{
// Collided with actor, ask actor to try to avoid door
if ( ptr ! = MWBase : : Environment : : get ( ) . getWorld ( ) - > getPlayerPtr ( ) ) {
MWMechanics : : AiSequence & seq = MWWorld: : Class : : get ( ptr ) . getCreatureStats ( ptr ) . getAiSequence ( ) ;
MWMechanics : : AiSequence & seq = ptr. getClass ( ) . getCreatureStats ( ptr ) . getAiSequence ( ) ;
if ( seq . getTypeId ( ) ! = MWMechanics : : AiPackage : : TypeIdAvoidDoor ) //Only add it once
seq . stack ( MWMechanics : : AiAvoidDoor ( it - > first ) , ptr ) ;
}
// we need to undo the rotation
localRotateObject ( it - > first , 0 , 0 , oldRot ) ;
reached = false ;
//break; //Removed in case multiple actors are touching
}
}
if ( ( targetRot = = 90.f & & it - > second ) | | targetRot = = 0.f )
if ( reached )
{
// Mark as non-moving
it - > first . getClass ( ) . setDoorState ( it - > first , 0 ) ;
mDoorStates . erase ( it + + ) ;
}
else
+ + it ;
}
@ -1843,31 +1865,32 @@ namespace MWWorld
void World : : activateDoor ( const MWWorld : : Ptr & door )
{
if ( mDoorStates . find ( door ) ! = mDoorStates . end ( ) )
{
// if currently opening, then close, if closing, then open
mDoorStates [ door ] = ! mDoorStates [ door ] ;
}
else
int state = door . getClass ( ) . getDoorState ( door ) ;
switch ( state )
{
case 0 :
if ( door . getRefData ( ) . getLocalRotation ( ) . rot [ 2 ] = = 0 )
mDoorStates[ door ] = 1 ; // open
state = 1 ; // if closed, then open
else
mDoorStates [ door ] = 0 ; // close
state = 2 ; // if open, then close
break ;
case 2 :
state = 1 ; // if closing, then open
break ;
case 1 :
default :
state = 2 ; // if opening, then close
break ;
}
door . getClass ( ) . setDoorState ( door , state ) ;
mDoorStates [ door ] = state ;
}
bool World : : getOpenOrCloseDoor ( const Ptr & door )
{
if ( mDoorStates . find ( door ) ! = mDoorStates . end ( ) )
return ! mDoorStates [ door ] ; // if currently opening or closing, then do the opposite
return door . getRefData ( ) . getLocalRotation ( ) . rot [ 2 ] = = 0 ;
}
bool World : : getIsMovingDoor ( const Ptr & door )
void World : : activateDoor ( const Ptr & door , bool open )
{
bool result = mDoorStates . find ( door ) ! = mDoorStates . end ( ) ;
return result ;
int state = open ? 1 : 2 ;
door . getClass ( ) . setDoorState ( door , state ) ;
mDoorStates [ door ] = state ;
}
bool World : : getPlayerStandingOn ( const MWWorld : : Ptr & object )
@ -2231,7 +2254,7 @@ namespace MWWorld
const Ogre : : Vector3 & worldPos , const Ogre : : Quaternion & orient , MWWorld : : Ptr bow , float speed )
{
ProjectileState state ;
state . mActor Handle = actor . getRefData ( ) . getHandle ( ) ;
state . mActor Id = actor . getClass ( ) . getCreatureStats ( actor ) . getActorId ( ) ;
state . mBow = bow ;
state . mVelocity = orient . yAxis ( ) * speed ;
@ -2318,7 +2341,7 @@ namespace MWWorld
MagicBoltState state ;
state . mSourceName = sourceName ;
state . mId = id ;
state . mActor Handle = actor . getRefData ( ) . getHandle ( ) ;
state . mActor Id = actor . getClass ( ) . getCreatureStats ( actor ) . getActorId ( ) ;
state . mSpeed = speed ;
state . mStack = stack ;
@ -2382,7 +2405,7 @@ namespace MWWorld
if ( obstacle = = ptr )
continue ;
MWWorld : : Ptr caster = searchPtrVia Handle( it - > second . mActorHandle ) ;
MWWorld : : Ptr caster = searchPtrVia ActorId( it - > second . mActorId ) ;
// Arrow intersects with player immediately after shooting :/
if ( obstacle = = caster )
@ -2468,7 +2491,7 @@ namespace MWWorld
if ( obstacle = = ptr )
continue ;
MWWorld : : Ptr caster = searchPtrVia Handle( it - > second . mActorHandle ) ;
MWWorld : : Ptr caster = searchPtrVia ActorId( it - > second . mActorId ) ;
if ( caster . isEmpty ( ) )
caster = obstacle ;
@ -2491,7 +2514,7 @@ namespace MWWorld
if ( explode )
{
MWWorld : : Ptr caster = searchPtrVia Handle( it - > second . mActorHandle ) ;
MWWorld : : Ptr caster = searchPtrVia ActorId( it - > second . mActorId ) ;
explodeSpell ( Ogre : : Vector3 ( ptr . getRefData ( ) . getPosition ( ) . pos ) , ptr , it - > second . mEffects , caster , it - > second . mId , it - > second . mSourceName ) ;
deleteObject ( ptr ) ;