123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873 |
- #ifdef PRECOMPILEDHEADERS
- #include "TileEngine All.h"
- #else
- #include "worlddef.h"
- #include <stdio.h>
- #include <string.h>
- #include "wcheck.h"
- #include "stdlib.h"
- #include "time.h"
- #include "video.h"
- #include "debug.h"
- #include "smooth.h"
- #include "worldman.h"
- #include "lighting.h"
- #include "renderworld.h"
- #include "overhead.h"
- #include "ai.h"
- #include "Sound Control.h"
- #include "animation control.h"
- #include "isometric utils.h"
- #include "Font Control.h"
- #include "message.h"
- #include "tile animation.h"
- #include "tile cache.h"
- #include "explosion control.h"
- #include "weapons.h"
- #include "Keys.h"
- #include "bullets.h"
- #endif
- ANITILE *pAniTileHead = NULL;
- ANITILE *CreateAnimationTile( ANITILE_PARAMS *pAniParams )
- {
- ANITILE *pAniNode;
- ANITILE *pNewAniNode;
- LEVELNODE *pNode;
- INT32 iCachedTile=-1;
- INT16 sGridNo;
- UINT8 ubLevel;
- INT16 usTileType;
- INT16 usTileIndex;
- INT16 sDelay;
- INT16 sStartFrame=-1;
- UINT32 uiFlags;
- LEVELNODE *pGivenNode;
- INT16 sX, sY, sZ;
- UINT8 ubTempDir;
- // Get some parameters from structure sent in...
- sGridNo = pAniParams->sGridNo;
- ubLevel = pAniParams->ubLevelID;
- usTileType = pAniParams->usTileType;
- usTileIndex = pAniParams->usTileIndex;
- sDelay = pAniParams->sDelay;
- sStartFrame = pAniParams->sStartFrame;
- uiFlags = pAniParams->uiFlags;
- pGivenNode = pAniParams->pGivenLevelNode;
- sX = pAniParams->sX;
- sY = pAniParams->sY;
- sZ = pAniParams->sZ;
-
- pAniNode = pAniTileHead;
- // Allocate head
- pNewAniNode = MemAlloc( sizeof( ANITILE ) );
- if ( (uiFlags & ANITILE_EXISTINGTILE ) )
- {
- pNewAniNode->pLevelNode = pGivenNode;
- pNewAniNode->pLevelNode->pAniTile = pNewAniNode;
- }
- else
- {
- if ( ( uiFlags & ANITILE_CACHEDTILE ) )
- {
- iCachedTile = GetCachedTile( pAniParams->zCachedFile );
- if ( iCachedTile == -1 )
- {
- return( NULL );
- }
- usTileIndex = iCachedTile + TILE_CACHE_START_INDEX;
- }
- // ALLOCATE NEW TILE
- switch( ubLevel )
- {
- case ANI_STRUCT_LEVEL:
-
- pNode = ForceStructToTail( sGridNo, usTileIndex );
- break;
- case ANI_SHADOW_LEVEL:
-
- AddShadowToHead( sGridNo, usTileIndex );
- pNode = gpWorldLevelData[ sGridNo ].pShadowHead;
- break;
- case ANI_OBJECT_LEVEL:
-
- AddObjectToHead( sGridNo, usTileIndex );
- pNode = gpWorldLevelData[ sGridNo ].pObjectHead;
- break;
- case ANI_ROOF_LEVEL:
-
- AddRoofToHead( sGridNo, usTileIndex );
- pNode = gpWorldLevelData[ sGridNo ].pRoofHead;
- break;
- case ANI_ONROOF_LEVEL:
-
- AddOnRoofToHead( sGridNo, usTileIndex );
- pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- break;
- case ANI_TOPMOST_LEVEL:
-
- AddTopmostToHead( sGridNo, usTileIndex );
- pNode = gpWorldLevelData[ sGridNo ].pTopmostHead;
- break;
- default:
- return( NULL );
- }
- // SET NEW TILE VALUES
- pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
- pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
- pNewAniNode->pLevelNode = pNode;
- if ( ( uiFlags & ANITILE_CACHEDTILE ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_CACHEDANITILE );
- pNewAniNode->sCachedTileID = (INT16)iCachedTile;
- pNewAniNode->usCachedTileSubIndex = usTileType;
- pNewAniNode->pLevelNode->pAniTile = pNewAniNode;
- pNewAniNode->sRelativeX = sX;
- pNewAniNode->sRelativeY = sY;
- pNewAniNode->pLevelNode->sRelativeZ = sZ;
- }
- // Can't set relative X,Y,Z IF FLAGS ANITILE_CACHEDTILE set!
- else if ( (uiFlags & ANITILE_USEABSOLUTEPOS ) )
- {
- pNewAniNode->pLevelNode->sRelativeX = sX;
- pNewAniNode->pLevelNode->sRelativeY = sY;
- pNewAniNode->pLevelNode->sRelativeZ = sZ;
- pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS );
- }
- }
-
- switch( ubLevel )
- {
- case ANI_STRUCT_LEVEL:
-
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES );
- break;
- case ANI_SHADOW_LEVEL:
-
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_SHADOWS );
- break;
- case ANI_OBJECT_LEVEL:
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_OBJECTS );
- break;
- case ANI_ROOF_LEVEL:
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_ROOF );
- break;
- case ANI_ONROOF_LEVEL:
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_ONROOF );
- break;
- case ANI_TOPMOST_LEVEL:
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_TOPMOST );
- break;
- }
- // SET FLAGS FOR LEVELNODE
- pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_ANIMATION | LEVELNODE_USEZ | LEVELNODE_DYNAMIC );
- if ( ( uiFlags & ANITILE_NOZBLITTER ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_NOZBLITTER;
- }
- if ( ( uiFlags & ANITILE_ALWAYS_TRANSLUCENT ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_REVEAL;
- }
- if ( ( uiFlags & ANITILE_USEBEST_TRANSLUCENT ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_USEBESTTRANSTYPE;
- }
- if ( ( uiFlags & ANITILE_ANIMATE_Z ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_DYNAMICZ;
- }
- if ( ( uiFlags & ANITILE_PAUSED ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= ( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE );
- pNewAniNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
- }
-
- if ( ( uiFlags & ANITILE_OPTIMIZEFORSMOKEEFFECT ) )
- {
- pNewAniNode->pLevelNode->uiFlags |= LEVELNODE_NOWRITEZ;
- }
- // SET ANITILE VALUES
- pNewAniNode->ubLevelID = ubLevel;
- pNewAniNode->usTileIndex = usTileIndex;
- if ( ( uiFlags & ANITILE_CACHEDTILE ) )
- {
- pNewAniNode->usNumFrames = gpTileCache[ iCachedTile ].ubNumFrames;
- }
- else
- {
- Assert( gTileDatabase[ usTileIndex ].pAnimData != NULL );
- pNewAniNode->usNumFrames = gTileDatabase[ usTileIndex ].pAnimData->ubNumFrames;
- }
- if ( ( uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gOneCDirection[ pAniParams->uiUserData3 ];
- sStartFrame = (UINT16)sStartFrame + ( pNewAniNode->usNumFrames * ubTempDir );
- }
- if ( ( uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gb4DirectionsFrom8[ pAniParams->uiUserData3 ];
- sStartFrame = (UINT16)sStartFrame + ( pNewAniNode->usNumFrames * ubTempDir );
- }
- pNewAniNode->usTileType = usTileType;
- pNewAniNode->pNext = pAniNode;
- pNewAniNode->uiFlags = uiFlags;
- pNewAniNode->sDelay = sDelay;
- pNewAniNode->sCurrentFrame = sStartFrame;
- pNewAniNode->uiTimeLastUpdate = GetJA2Clock( );
- pNewAniNode->sGridNo = sGridNo;
- pNewAniNode->sStartFrame = sStartFrame;
- pNewAniNode->ubKeyFrame1 = pAniParams->ubKeyFrame1;
- pNewAniNode->uiKeyFrame1Code = pAniParams->uiKeyFrame1Code;
- pNewAniNode->ubKeyFrame2 = pAniParams->ubKeyFrame2;
- pNewAniNode->uiKeyFrame2Code = pAniParams->uiKeyFrame2Code;
- pNewAniNode->uiUserData = pAniParams->uiUserData;
- pNewAniNode->ubUserData2 = pAniParams->ubUserData2;
- pNewAniNode->uiUserData3 = pAniParams->uiUserData3;
- //Set head
- pAniTileHead = pNewAniNode;
- // Set some special stuff
- return( pNewAniNode );
- }
- // Loop throug all ani tiles and remove...
- void DeleteAniTiles( )
- {
- ANITILE *pAniNode = NULL;
- ANITILE *pNode = NULL;
- // LOOP THROUGH EACH NODE
- // And call delete function...
- pAniNode = pAniTileHead;
- while( pAniNode != NULL )
- {
- pNode = pAniNode;
- pAniNode = pAniNode->pNext;
- DeleteAniTile( pNode );
- }
- }
- void DeleteAniTile( ANITILE *pAniTile )
- {
- ANITILE *pAniNode = NULL;
- ANITILE *pOldAniNode = NULL;
- TILE_ELEMENT *TileElem;
- pAniNode = pAniTileHead;
- while( pAniNode!= NULL )
- {
- if ( pAniNode == pAniTile )
- {
- // OK, set links
- // Check for head or tail
- if ( pOldAniNode == NULL )
- {
- // It's the head
- pAniTileHead = pAniTile->pNext;
- }
- else
- {
- pOldAniNode->pNext = pAniNode->pNext;
- }
- if ( !(pAniNode->uiFlags & ANITILE_EXISTINGTILE ) )
- {
- // Delete memory assosiated with item
- switch( pAniNode->ubLevelID )
- {
- case ANI_STRUCT_LEVEL:
-
- RemoveStructFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
- break;
- case ANI_SHADOW_LEVEL:
-
- RemoveShadowFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
- break;
- case ANI_OBJECT_LEVEL:
-
- RemoveObject( pAniNode->sGridNo, pAniNode->usTileIndex );
- break;
- case ANI_ROOF_LEVEL:
-
- RemoveRoof( pAniNode->sGridNo, pAniNode->usTileIndex );
- break;
- case ANI_ONROOF_LEVEL:
-
- RemoveOnRoof( pAniNode->sGridNo, pAniNode->usTileIndex );
- break;
- case ANI_TOPMOST_LEVEL:
-
- RemoveTopmostFromLevelNode( pAniNode->sGridNo, pAniNode->pLevelNode );
- break;
- }
- if ( ( pAniNode->uiFlags & ANITILE_CACHEDTILE ) )
- {
- RemoveCachedTile( pAniNode->sCachedTileID );
- }
- if ( pAniNode->uiFlags & ANITILE_EXPLOSION )
- {
- // Talk to the explosion data...
- RemoveExplosionData( pAniNode->uiUserData3 );
- if ( !gfExplosionQueueActive )
- {
- // turn on sighting again
- // the explosion queue handles all this at the end of the queue
- gTacticalStatus.uiFlags &= (~DISALLOW_SIGHT);
- }
- // Freeup attacker from explosion
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Reducing attacker busy count..., EXPLOSION effect gone off") );
- ReduceAttackBusyCount( (UINT8)pAniNode->ubUserData2, FALSE );
- }
- if ( pAniNode->uiFlags & ANITILE_RELEASE_ATTACKER_WHEN_DONE )
- {
- // First delete the bullet!
- RemoveBullet( pAniNode->uiUserData3 );
-
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - miss finished animation") );
- FreeUpAttacker( (UINT8) pAniNode->ubAttackerMissed );
- }
- }
- else
- {
- TileElem = &( gTileDatabase[ pAniNode->usTileIndex ] );
- // OK, update existing tile usIndex....
- Assert( TileElem->pAnimData != NULL );
- pAniNode->pLevelNode->usIndex = TileElem->pAnimData->pusFrames[ pAniNode->pLevelNode->sCurrentFrame ];
- // OK, set our frame data back to zero....
- pAniNode->pLevelNode->sCurrentFrame = 0;
-
- // Set some flags to write to Z / update save buffer
- // pAniNode->pLevelNode->uiFlags |=( LEVELNODE_LASTDYNAMIC | LEVELNODE_UPDATESAVEBUFFERONCE );
- pAniNode->pLevelNode->uiFlags &= ~( LEVELNODE_DYNAMIC | LEVELNODE_USEZ | LEVELNODE_ANIMATION );
- if (pAniNode->uiFlags & ANITILE_DOOR)
- {
- // unset door busy!
- DOOR_STATUS * pDoorStatus;
- pDoorStatus = GetDoorStatus( pAniNode->sGridNo );
- if (pDoorStatus)
- {
- pDoorStatus->ubFlags &= ~(DOOR_BUSY);
- }
- if ( GridNoOnScreen( pAniNode->sGridNo ) )
- {
- SetRenderFlags(RENDER_FLAG_FULL);
- }
- }
- }
- MemFree( pAniNode );
- return;
- }
- pOldAniNode = pAniNode;
- pAniNode = pAniNode->pNext;
- }
- }
- void UpdateAniTiles( )
- {
- ANITILE *pAniNode = NULL;
- ANITILE *pNode = NULL;
- UINT32 uiClock = GetJA2Clock( );
- UINT16 usMaxFrames, usMinFrames;
- UINT8 ubTempDir;
- // LOOP THROUGH EACH NODE
- pAniNode = pAniTileHead;
- while( pAniNode != NULL )
- {
- pNode = pAniNode;
- pAniNode = pAniNode->pNext;
- if ( (uiClock - pNode->uiTimeLastUpdate ) > (UINT32)pNode->sDelay && !( pNode->uiFlags & ANITILE_PAUSED ) )
- {
- pNode->uiTimeLastUpdate = GetJA2Clock( );
-
- if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSLOWMOVING ) )
- {
- pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC );
- pNode->pLevelNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC);
- }
- else if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSMOKEEFFECT ) )
- {
- // pNode->pLevelNode->uiFlags |= LEVELNODE_DYNAMICZ;
- ResetSpecificLayerOptimizing( TILES_DYNAMIC_STRUCTURES );
- pNode->pLevelNode->uiFlags &= (~LEVELNODE_LASTDYNAMIC);
- pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC );
- }
- if ( pNode->uiFlags & ANITILE_FORWARD )
- {
- usMaxFrames = pNode->usNumFrames;
- if ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME )
- {
- ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
- usMaxFrames = (UINT16)usMaxFrames + ( pNode->usNumFrames * ubTempDir );
- }
- if ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME )
- {
- ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
- usMaxFrames = (UINT16)usMaxFrames + ( pNode->usNumFrames * ubTempDir );
- }
- if ( ( pNode->sCurrentFrame + 1 ) < usMaxFrames )
- {
- pNode->sCurrentFrame++;
- pNode->pLevelNode->sCurrentFrame = pNode->sCurrentFrame;
- if ( pNode->uiFlags & ANITILE_EXPLOSION )
- {
- // Talk to the explosion data...
- UpdateExplosionFrame( pNode->uiUserData3, pNode->sCurrentFrame );
- }
- // CHECK IF WE SHOULD BE DISPLAYING TRANSLUCENTLY!
- if ( pNode->sCurrentFrame == pNode->ubKeyFrame1 )
- {
- switch( pNode->uiKeyFrame1Code )
- {
- case ANI_KEYFRAME_BEGIN_TRANSLUCENCY:
- pNode->pLevelNode->uiFlags |= LEVELNODE_REVEAL;
- break;
- case ANI_KEYFRAME_CHAIN_WATER_EXPLOSION:
-
- IgniteExplosion( pNode->ubUserData2, pNode->pLevelNode->sRelativeX, pNode->pLevelNode->sRelativeY, 0, pNode->sGridNo, (UINT16)( pNode->uiUserData ), 0 );
- break;
- case ANI_KEYFRAME_DO_SOUND:
- PlayJA2Sample( pNode->uiUserData, RATE_11025, SoundVolume( MIDVOLUME, (INT16)pNode->uiUserData3 ), 1, SoundDir( (INT16)pNode->uiUserData3 ) );
- break;
- }
- }
- // CHECK IF WE SHOULD BE DISPLAYING TRANSLUCENTLY!
- if ( pNode->sCurrentFrame == pNode->ubKeyFrame2 )
- {
- UINT8 ubExpType;
- switch( pNode->uiKeyFrame2Code )
- {
- case ANI_KEYFRAME_BEGIN_DAMAGE:
- ubExpType = Explosive[ Item[ (UINT16)pNode->uiUserData ].ubClassIndex ].ubType;
- if ( ubExpType == EXPLOSV_TEARGAS || ubExpType == EXPLOSV_MUSTGAS ||
- ubExpType == EXPLOSV_SMOKE )
- {
- // Do sound....
- // PlayJA2Sample( AIR_ESCAPING_1, RATE_11025, SoundVolume( HIGHVOLUME, pNode->sGridNo ), 1, SoundDir( pNode->sGridNo ) );
- NewSmokeEffect( pNode->sGridNo, (UINT16)pNode->uiUserData, gExplosionData[ pNode->uiUserData3 ].Params.bLevel, (UINT8)pNode->ubUserData2 );
- }
- else
- {
- SpreadEffect( pNode->sGridNo, Explosive[ Item[ (UINT16)pNode->uiUserData ].ubClassIndex ].ubRadius, (UINT16)pNode->uiUserData, (UINT8)pNode->ubUserData2, FALSE, gExplosionData[ pNode->uiUserData3 ].Params.bLevel, -1 );
- }
- // Forfait any other animations this frame....
- return;
- }
- }
- }
- else
- {
- // We are done!
- if ( pNode->uiFlags & ANITILE_LOOPING )
- {
- pNode->sCurrentFrame = pNode->sStartFrame;
- if ( ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
- pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
- }
- if ( ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
- pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
- }
- }
- else if ( pNode->uiFlags & ANITILE_REVERSE_LOOPING )
- {
- // Turn off backwards flag
- pNode->uiFlags &= (~ANITILE_FORWARD );
- // Turn onn forwards flag
- pNode->uiFlags |= ANITILE_BACKWARD;
- }
- else
- {
- // Delete from world!
- DeleteAniTile( pNode );
- // Turn back on redunency checks!
- gTacticalStatus.uiFlags &= (~NOHIDE_REDUNDENCY);
- return;
- }
- }
- }
-
- if ( pNode->uiFlags & ANITILE_BACKWARD )
- {
- if ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER )
- {
- // ATE: Check if bounding box is on the screen...
- if ( pNode->bFrameCountAfterStart == 0 )
- {
- pNode->bFrameCountAfterStart = 1;
- pNode->pLevelNode->uiFlags |= (LEVELNODE_DYNAMIC );
- // Dangerous here, since we may not even be on the screen...
- SetRenderFlags( RENDER_FLAG_FULL );
- continue;
- }
- }
- usMinFrames = 0;
- if ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME )
- {
- ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
- usMinFrames = ( pNode->usNumFrames * ubTempDir );
- }
- if ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME )
- {
- ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
- usMinFrames = ( pNode->usNumFrames * ubTempDir );
- }
- if ( ( pNode->sCurrentFrame - 1 ) >= usMinFrames )
- {
- pNode->sCurrentFrame--;
- pNode->pLevelNode->sCurrentFrame = pNode->sCurrentFrame;
- if ( pNode->uiFlags & ANITILE_EXPLOSION )
- {
- // Talk to the explosion data...
- UpdateExplosionFrame( pNode->uiUserData3, pNode->sCurrentFrame );
- }
- }
- else
- {
- // We are done!
- if ( pNode->uiFlags & ANITILE_PAUSE_AFTER_LOOP )
- {
- // Turn off backwards flag
- pNode->uiFlags &= (~ANITILE_BACKWARD );
- // Pause
- pNode->uiFlags |= ANITILE_PAUSED;
- }
- else if ( pNode->uiFlags & ANITILE_LOOPING )
- {
- pNode->sCurrentFrame = pNode->sStartFrame;
- if ( ( pNode->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gOneCDirection[ pNode->uiUserData3 ];
- pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
- }
- if ( ( pNode->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gb4DirectionsFrom8[ pNode->uiUserData3 ];
- pNode->sCurrentFrame = (UINT16)( pNode->usNumFrames * ubTempDir );
- }
- }
- else if ( pNode->uiFlags & ANITILE_REVERSE_LOOPING )
- {
- // Turn off backwards flag
- pNode->uiFlags &= (~ANITILE_BACKWARD );
- // Turn onn forwards flag
- pNode->uiFlags |= ANITILE_FORWARD;
- }
- else
- {
- // Delete from world!
- DeleteAniTile( pNode );
- return;
- }
- if ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER )
- {
- // ATE: Check if bounding box is on the screen...
- pNode->bFrameCountAfterStart = 0;
- //pNode->pLevelNode->uiFlags |= LEVELNODE_UPDATESAVEBUFFERONCE;
- // Dangerous here, since we may not even be on the screen...
- SetRenderFlags( RENDER_FLAG_FULL );
- }
- }
- }
-
- }
- else
- {
- if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSLOWMOVING ) )
- {
- // ONLY TURN OFF IF PAUSED...
- if ( ( pNode->uiFlags & ANITILE_ERASEITEMFROMSAVEBUFFFER ) )
- {
- if ( pNode->uiFlags & ANITILE_PAUSED )
- {
- if ( pNode->pLevelNode->uiFlags & LEVELNODE_DYNAMIC )
- {
- pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
- pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC);
- SetRenderFlags( RENDER_FLAG_FULL );
- }
- }
- }
- else
- {
- pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
- pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC);
- }
- }
- else if ( pNode->uiFlags & ( ANITILE_OPTIMIZEFORSMOKEEFFECT ) )
- {
- pNode->pLevelNode->uiFlags |= (LEVELNODE_LASTDYNAMIC);
- pNode->pLevelNode->uiFlags &= (~LEVELNODE_DYNAMIC );
- }
- }
- }
- }
- void SetAniTileFrame( ANITILE *pAniTile, INT16 sFrame )
- {
- UINT8 ubTempDir;
- INT16 sStartFrame = 0;
- if ( (pAniTile->uiFlags & ANITILE_USE_DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gOneCDirection[ pAniTile->uiUserData3 ];
- sStartFrame = (UINT16)sFrame + ( pAniTile->usNumFrames * ubTempDir );
- }
- if ( (pAniTile->uiFlags & ANITILE_USE_4DIRECTION_FOR_START_FRAME ) )
- {
- // Our start frame is actually a direction indicator
- ubTempDir = gb4DirectionsFrom8[ pAniTile->uiUserData3 ];
- sStartFrame = (UINT16)sFrame + ( pAniTile->usNumFrames * ubTempDir );
- }
- pAniTile->sCurrentFrame = sStartFrame;
- }
- ANITILE *GetCachedAniTileOfType( INT16 sGridNo, UINT8 ubLevelID, UINT32 uiFlags )
- {
- LEVELNODE *pNode = NULL;
- switch( ubLevelID )
- {
- case ANI_STRUCT_LEVEL:
-
- pNode = gpWorldLevelData[ sGridNo ].pStructHead;
- break;
- case ANI_SHADOW_LEVEL:
-
- pNode = gpWorldLevelData[ sGridNo ].pShadowHead;
- break;
- case ANI_OBJECT_LEVEL:
-
- pNode = gpWorldLevelData[ sGridNo ].pObjectHead;
- break;
- case ANI_ROOF_LEVEL:
-
- pNode = gpWorldLevelData[ sGridNo ].pRoofHead;
- break;
- case ANI_ONROOF_LEVEL:
-
- pNode = gpWorldLevelData[ sGridNo ].pOnRoofHead;
- break;
- case ANI_TOPMOST_LEVEL:
-
- pNode = gpWorldLevelData[ sGridNo ].pTopmostHead;
- break;
- default:
- return( NULL );
- }
- while( pNode != NULL )
- {
- if ( pNode->uiFlags & LEVELNODE_CACHEDANITILE )
- {
- if ( pNode->pAniTile->uiFlags & uiFlags )
- {
- return( pNode->pAniTile );
- }
- }
- pNode = pNode->pNext;
- }
- return( NULL );
- }
- void HideAniTile( ANITILE *pAniTile, BOOLEAN fHide )
- {
- if ( fHide )
- {
- pAniTile->pLevelNode->uiFlags |= LEVELNODE_HIDDEN;
- }
- else
- {
- pAniTile->pLevelNode->uiFlags &= (~LEVELNODE_HIDDEN );
- }
- }
- void PauseAniTile( ANITILE *pAniTile, BOOLEAN fPause )
- {
- if ( fPause )
- {
- pAniTile->uiFlags |= ANITILE_PAUSED;
- }
- else
- {
- pAniTile->uiFlags &= (~ANITILE_PAUSED );
- }
- }
- void PauseAllAniTilesOfType( UINT32 uiType, BOOLEAN fPause )
- {
- ANITILE *pAniNode = NULL;
- ANITILE *pNode = NULL;
- // LOOP THROUGH EACH NODE
- pAniNode = pAniTileHead;
- while( pAniNode != NULL )
- {
- pNode = pAniNode;
- pAniNode = pAniNode->pNext;
- if ( pNode->uiFlags & uiType )
- {
- PauseAniTile( pNode, fPause );
- }
- }
- }
|