#include "builddefines.h" #ifdef PRECOMPILEDHEADERS #include "TileEngine All.h" #else #include "debug.h" #include "animation control.h" #include "lighteffects.h" #include "isometric utils.h" #include "lighting.h" #include "Game Clock.h" #include "opplist.h" #include "Tactical Save.h" #endif #include "SaveLoadGame.h" #include "GameVersion.h" // added by Flugente //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; #define NUM_LIGHT_EFFECT_SLOTS 500 // 25 // Flugente: raised to 500 - lets see what happens // GLOBAL FOR LIGHT LISTING LIGHTEFFECT gLightEffectData[ NUM_LIGHT_EFFECT_SLOTS ]; UINT32 guiNumLightEffects = 0; INT32 GetFreeLightEffect( void ); void RecountLightEffects( void ); INT32 GetFreeLightEffect( void ) { UINT32 uiCount; for(uiCount=0; uiCount < guiNumLightEffects; uiCount++) { if(( gLightEffectData[uiCount].fAllocated==FALSE ) ) return( (INT32)uiCount ); } if( guiNumLightEffects < NUM_LIGHT_EFFECT_SLOTS ) return( (INT32) guiNumLightEffects++ ); return( -1 ); } void RecountLightEffects( void ) { INT32 uiCount; for(uiCount=guiNumLightEffects-1; (uiCount >=0) ; uiCount--) { if( ( gLightEffectData[uiCount].fAllocated ) ) { guiNumLightEffects=(UINT32)(uiCount+1); break; } } } void UpdateLightingSprite( LIGHTEFFECT *pLight ) { CHAR8 LightName[20]; // Build light.... sprintf( LightName, "Light%d", pLight->bRadius ); // Delete old one if one exists... if( pLight->iLight!=(-1) ) { LightSpriteDestroy( pLight->iLight ); pLight->iLight = -1; } // Effect light..... if( ( pLight->iLight = LightSpriteCreate( LightName, 0 ) )==(-1)) { // Could not light! return; } LightSpritePower( pLight->iLight, TRUE ); // LightSpriteFake( pLight->iLight ); LightSpritePosition( pLight->iLight, (INT16)( CenterX( pLight->sGridNo ) / CELL_X_SIZE ), (INT16)( CenterY( pLight->sGridNo ) / CELL_Y_SIZE ) ); } // Flugente: create a pure light, worry about updating sight in other functions INT32 NewLightEffectInternal( INT32 sGridNo, UINT8 ubDuration, UINT8 ubStartRadius ) { LIGHTEFFECT *pLight; INT32 iLightIndex; if( ( iLightIndex = GetFreeLightEffect() )==(-1) ) return(-1); memset( &gLightEffectData[ iLightIndex ], 0, sizeof( LIGHTEFFECT ) ); pLight = &gLightEffectData[ iLightIndex ]; // Set some values... pLight->sGridNo = sGridNo; pLight->iLight = -1; pLight->uiTimeOfLastUpdate = GetWorldTotalSeconds( ); pLight->ubDuration = ubDuration; pLight->bRadius = ubStartRadius; pLight->bAge = 0; pLight->fAllocated = TRUE; UpdateLightingSprite( pLight ); return iLightIndex; } INT32 NewLightEffect( INT32 sGridNo, UINT8 ubDuration, UINT8 ubStartRadius ) { INT32 iLightIndex = NewLightEffectInternal( sGridNo, ubDuration, ubStartRadius ); // Handle sight here.... AllTeamsLookForAll( FALSE ); //Play the breaklight sound // PlayJA2Sample( BREAK_LIGHT_IGNITING, RATE_11025, SoundVolume( LOWVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); // MAdd: for some reason this crashes the game! if ( iLightIndex > -1 ) { LIGHTEFFECT *pLight = &gLightEffectData[ iLightIndex ]; return( pLight->iLight ); } return -1; } void RemoveLightEffectFromTile( INT32 sGridNo ) { LIGHTEFFECT *pLight; UINT32 cnt; // Set to unallocated.... for ( cnt = 0; cnt < guiNumLightEffects; cnt++ ) { pLight = &gLightEffectData[ cnt ]; if ( pLight->fAllocated ) { if ( pLight->sGridNo == sGridNo ) { pLight->fAllocated = FALSE; // Remove light.... if( pLight->iLight != (-1) ) { LightSpriteDestroy( pLight->iLight ); } break; } } } } BOOLEAN IsLightEffectAtTile( INT32 sGridNo ) { LIGHTEFFECT *pLight; UINT32 cnt; // Set to unallocated.... for ( cnt = 0; cnt < guiNumLightEffects; cnt++ ) { pLight = &gLightEffectData[ cnt ]; if ( pLight->fAllocated ) { if ( pLight->sGridNo == sGridNo ) { return TRUE; } } } return FALSE; } void DecayLightEffects( UINT32 uiTime ) { LIGHTEFFECT *pLight; UINT32 cnt, cnt2; BOOLEAN fUpdate = FALSE; BOOLEAN fDelete = FALSE; BOOLEAN fAnyUpdate = FALSE; UINT16 usNumUpdates = 1; // age all active light effects, deactivate those that are just dispersing for ( cnt = 0; cnt < guiNumLightEffects; ++cnt ) { pLight = &gLightEffectData[ cnt ]; fDelete = FALSE; if ( pLight->fAllocated ) { usNumUpdates = 1; // Do things differently for combat /vs realtime // always try to update during combat if ( gTacticalStatus.uiFlags & INCOMBAT ) { fUpdate = TRUE; } // ATE: Do this every so often, to achieve the effect we want... else if ( (uiTime - pLight->uiTimeOfLastUpdate) >= 10 ) { fUpdate = TRUE; usNumUpdates = (UINT16)((uiTime - pLight->uiTimeOfLastUpdate) / 10); } if ( fUpdate ) { pLight->uiTimeOfLastUpdate = uiTime; for ( cnt2 = 0; cnt2 < usNumUpdates; ++cnt2 ) { ++pLight->bAge; if ( pLight->ubDuration <= 0 ) fDelete = TRUE; // if this light remains effective (duration not reached) if ( pLight->bAge < pLight->ubDuration) { // calculate the new cloud radius /*if ( ( pLight->bAge % 2 ) ) { --pLight->bRadius; }*/ if (pLight->ubDuration - pLight->bAge < pLight->bRadius) { pLight->bRadius--; } if ( pLight->bRadius == 0 ) { // Delete... fDelete = TRUE; break; } else { UpdateLightingSprite( pLight ); } } else { fDelete = TRUE; break; } } if ( fDelete ) { pLight->fAllocated = FALSE; if( pLight->iLight != (-1) ) { LightSpriteDestroy( pLight->iLight ); } } // we have to update sight later on if any light was updated fAnyUpdate = TRUE; } } } if ( fAnyUpdate ) { // Handle sight here.... AllTeamsLookForAll( FALSE ); } } BOOLEAN SaveLightEffectsToSaveGameFile( HWFILE hFile ) { /* UINT32 uiNumBytesWritten; UINT32 uiNumberOfLights=0; UINT32 uiCnt; //loop through and count the number of active slots for( uiCnt=0; uiCnt= DYNAMIC_FLASHLIGHTS) { //Load the Light effect Data FileRead( hFile, &gLightEffectData[ uiCnt ], sizeof( LIGHTEFFECT ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( LIGHTEFFECT ) ) { return( FALSE ); } } else { UINT16 bla = sizeof( LIGHTEFFECT ); //Load the Light effect Data FileRead( hFile, &gLightEffectData[ uiCnt ], LIGHTEFFECT_OLDSIZE, &uiNumBytesRead ); if( uiNumBytesRead != LIGHTEFFECT_OLDSIZE ) { return( FALSE ); } } } //loop through and apply the light effects to the map for(uiCount=0; uiCount < guiNumLightEffects; uiCount++) { if( gLightEffectData[uiCount].fAllocated ) UpdateLightingSprite( &( gLightEffectData[uiCount] ) ); } FileClose( hFile ); return( TRUE ); } void ResetLightEffects() { //Clear out the old list memset( gLightEffectData, 0, sizeof( LIGHTEFFECT ) * NUM_LIGHT_EFFECT_SLOTS ); guiNumLightEffects = 0; } // Flugente: create and destroy light sources tied to a person void CreatePersonalLight( INT32 sGridNo, UINT8 ubID ) { INT32 iLightIndex = NewLightEffectInternal( sGridNo, 0, 1 ); if ( iLightIndex > -1 ) { gLightEffectData[ iLightIndex ].ubOwner = ubID; gLightEffectData[ iLightIndex ].flags |= LIGHTEFFECT_FLASHLIGHT; } } void RemovePersonalLights( UINT8 ubID ) { LIGHTEFFECT *pLight; // Set to unallocated.... for ( UINT32 cnt = 0; cnt < guiNumLightEffects; ++cnt ) { pLight = &gLightEffectData[ cnt ]; if ( pLight->iLight != (-1) && pLight->flags & LIGHTEFFECT_FLASHLIGHT && pLight->ubOwner == ubID && pLight->fAllocated ) { pLight->fAllocated = FALSE; pLight->flags &= ~LIGHTEFFECT_FLASHLIGHT; LightSpriteDestroy( pLight->iLight ); } } }