mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
New feature: additional decals adds blood spatters and structural wear on walls
Requires GameDir >= r2595 to work git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9113 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -937,6 +937,9 @@ void LoadGameExternalOptions()
|
||||
// anv: hide stuff on roof in explored rooms at ground level view (sandbags and other crap)
|
||||
gGameExternalOptions.fHideExploredRoomRoofStructures = iniReader.ReadBoolean("Graphics Settings", "HIDE_EXPLORED_ROOM_ROOF_STRUCTURES", TRUE);
|
||||
|
||||
// Flugente: additional decals on objects (cracked walls, blood spatters etc.)
|
||||
gGameExternalOptions.fAdditionalDecals = iniReader.ReadBoolean( "Graphics Settings", "ADDITIONAL_DECALS", FALSE );
|
||||
|
||||
//################# Sound Settings #################
|
||||
|
||||
gGameExternalOptions.guiWeaponSoundEffectsVolume = iniReader.ReadInteger("Sound Settings","WEAPON_SOUND_EFFECTS_VOLUME", 0, 0, 1000 /*1000 = 10x?*/);
|
||||
|
||||
@@ -898,6 +898,9 @@ typedef struct
|
||||
BOOLEAN fAutoHideProgressBar;
|
||||
// anv: hide stuff on roof in explored rooms at ground level view (sandbags and other crap)
|
||||
BOOLEAN fHideExploredRoomRoofStructures;
|
||||
|
||||
BOOLEAN fAdditionalDecals; // Flugente: show additional decals on objects (cracked walls, blood spatters etc.)
|
||||
|
||||
//enable ext mouse key
|
||||
BOOLEAN bAltAimEnabled;
|
||||
BOOLEAN bAimedBurstEnabled;
|
||||
|
||||
+2
-2
@@ -55,8 +55,8 @@
|
||||
|
||||
#endif
|
||||
|
||||
CHAR8 czVersionNumber[16] = { "Build 21.04.26" }; //YY.MM.DD
|
||||
CHAR8 czVersionNumber[16] = { "Build 21.06.27" }; //YY.MM.DD
|
||||
CHAR16 zTrackingNumber[16] = { L"Z" };
|
||||
CHAR16 zRevisionNumber[16] = { L"Revision 8980" };
|
||||
CHAR16 zRevisionNumber[16] = { L"Revision 9113" };
|
||||
|
||||
// SAVE_GAME_VERSION is defined in header, change it there
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "SkillCheck.h" // added by Flugente
|
||||
#include "ai.h" // sevenfm
|
||||
#include "GameInitOptionsScreen.h"
|
||||
#include "renderworld.h" // added by Flugente for SetRenderFlags( RENDER_FLAG_FULL );
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
@@ -3291,6 +3292,126 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
|
||||
send_hit( &SWeaponHit );
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: add blood spatter to wall next to target
|
||||
if ( gGameExternalOptions.fAdditionalDecals
|
||||
&&( pTarget->ubBodyType < ADULTFEMALEMONSTER || (pTarget->ubBodyType >= FATCIV && pTarget->ubBodyType <= BLOODCAT) )
|
||||
&& iDamage > 15 )
|
||||
{
|
||||
// the direction in SWeaponHit.usDirection is erversed for whatever reason
|
||||
UINT8 properdirection = gOppositeDirection[SWeaponHit.usDirection];
|
||||
|
||||
if ( properdirection == SOUTHWEST
|
||||
||properdirection == WEST
|
||||
|| properdirection == NORTHWEST
|
||||
|| properdirection == NORTH
|
||||
|| properdirection == NORTHEAST)
|
||||
{
|
||||
bool northwestalreadydone( false );
|
||||
|
||||
INT32 nextGridNoinSight = pBullet->sGridNo;
|
||||
|
||||
// If we're firing straight up (NORTHWEST), issues arise if we hit a corner.
|
||||
// If it's an outside corner, it would be enough to simply mark both outside walls.
|
||||
// This does not work in an inside corner, as the walls would be tied to the northern and western gridno from our position, not the northwest one.
|
||||
// It could also be the case that it's an inside corner in a full wall.
|
||||
// Solution: First check the northern and western gridnos for walls. Only if those don't exist, continue to the northwest gridno and check it's outside walls.
|
||||
if ( properdirection == NORTHWEST )
|
||||
{
|
||||
nextGridNoinSight = NewGridNo( pBullet->sGridNo, DirectionInc( WEST ) );
|
||||
|
||||
if ( gubWorldMovementCosts[nextGridNoinSight][WEST][0] >= TRAVELCOST_BLOCKED )
|
||||
{
|
||||
STRUCTURE* pStructureForBlood = FindStructure( nextGridNoinSight, STRUCTURE_WALL );
|
||||
while ( pStructureForBlood )
|
||||
{
|
||||
// add if not already set
|
||||
// add if of proper height
|
||||
if ( ( pStructureForBlood->ubWallOrientation == INSIDE_TOP_RIGHT ) )
|
||||
{
|
||||
northwestalreadydone = true;
|
||||
|
||||
if ( !( pStructureForBlood->ubDecalFlag & STRUCTURE_DECALFLAG_BLOOD )
|
||||
&& StructureHeight( pStructureForBlood ) == 4 )
|
||||
{
|
||||
// add blood to wall
|
||||
pStructureForBlood->ubDecalFlag |= STRUCTURE_DECALFLAG_BLOOD;
|
||||
|
||||
gpWorldLevelData[pStructureForBlood->sGridNo].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
|
||||
// enforce a full render, so that we can draw decals on time
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
}
|
||||
|
||||
pStructureForBlood = FindNextStructure( pStructureForBlood, STRUCTURE_WALL );
|
||||
}
|
||||
}
|
||||
|
||||
nextGridNoinSight = NewGridNo( pBullet->sGridNo, DirectionInc( NORTH ) );
|
||||
|
||||
if ( gubWorldMovementCosts[nextGridNoinSight][NORTH][0] >= TRAVELCOST_BLOCKED )
|
||||
{
|
||||
STRUCTURE* pStructureForBlood = FindStructure( nextGridNoinSight, STRUCTURE_WALL );
|
||||
while ( pStructureForBlood )
|
||||
{
|
||||
// add if not already set
|
||||
// add if of proper height
|
||||
if ( pStructureForBlood->ubWallOrientation == INSIDE_TOP_LEFT )
|
||||
{
|
||||
northwestalreadydone = true;
|
||||
|
||||
if ( !( pStructureForBlood->ubDecalFlag & STRUCTURE_DECALFLAG_BLOOD )
|
||||
&& StructureHeight( pStructureForBlood ) == 4 )
|
||||
{
|
||||
// add blood to wall
|
||||
pStructureForBlood->ubDecalFlag |= STRUCTURE_DECALFLAG_BLOOD;
|
||||
|
||||
gpWorldLevelData[pStructureForBlood->sGridNo].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
|
||||
// enforce a full render, so that we can draw decals on time
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
}
|
||||
|
||||
pStructureForBlood = FindNextStructure( pStructureForBlood, STRUCTURE_WALL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextGridNoinSight = NewGridNo( pBullet->sGridNo, DirectionInc( properdirection ) );
|
||||
|
||||
if ( !northwestalreadydone
|
||||
&& gubWorldMovementCosts[nextGridNoinSight][properdirection][0] >= TRAVELCOST_BLOCKED )
|
||||
{
|
||||
STRUCTURE* pStructureForBlood = FindStructure( nextGridNoinSight, STRUCTURE_WALL );
|
||||
while ( pStructureForBlood )
|
||||
{
|
||||
// add if not already set
|
||||
// add if of proper height
|
||||
if ( ( ( properdirection == NORTHWEST && ( pStructureForBlood->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructureForBlood->ubWallOrientation == OUTSIDE_TOP_RIGHT ) )
|
||||
|| ( properdirection == WEST && ( pStructureForBlood->ubWallOrientation == OUTSIDE_TOP_RIGHT || pStructureForBlood->ubWallOrientation == INSIDE_TOP_RIGHT ) )
|
||||
|| ( properdirection == SOUTHWEST && ( pStructureForBlood->ubWallOrientation == OUTSIDE_TOP_RIGHT || pStructureForBlood->ubWallOrientation == INSIDE_TOP_RIGHT ) )
|
||||
|| ( properdirection == NORTH && ( pStructureForBlood->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructureForBlood->ubWallOrientation == INSIDE_TOP_LEFT ) )
|
||||
|| ( properdirection == NORTHEAST && ( pStructureForBlood->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructureForBlood->ubWallOrientation == INSIDE_TOP_LEFT ) )
|
||||
)
|
||||
&& !( pStructureForBlood->ubDecalFlag & STRUCTURE_DECALFLAG_BLOOD )
|
||||
&& StructureHeight( pStructureForBlood ) == 4 )
|
||||
{
|
||||
// add blood to wall
|
||||
pStructureForBlood->ubDecalFlag |= STRUCTURE_DECALFLAG_BLOOD;
|
||||
|
||||
gpWorldLevelData[pStructureForBlood->sGridNo].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
|
||||
// enforce a full render, so that we can draw decals on time
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
|
||||
pStructureForBlood = FindNextStructure( pStructureForBlood, STRUCTURE_WALL );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fStopped)
|
||||
{
|
||||
|
||||
+52
-20
@@ -48,6 +48,7 @@ void RemoveMineFlagFromMap( INT32 usGridNo );
|
||||
void SetSectorsRevealedBit( UINT32 usMapIndex );
|
||||
void SetMapRevealedStatus();
|
||||
void DamageStructsFromMapTempFile( MODIFY_MAP * pMap );
|
||||
void AddDecalToStructsFromMapTempFile( MODIFY_MAP * pMap );
|
||||
BOOLEAN ModifyWindowStatus( INT32 uiMapIndex );
|
||||
//ppp
|
||||
|
||||
@@ -544,6 +545,10 @@ BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( )
|
||||
RemoveMineFlagFromMap( pMap->usGridNo );
|
||||
break;
|
||||
|
||||
case SLM_DECAL:
|
||||
AddDecalToStructsFromMapTempFile( pMap );
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg( 0, "ERROR! Map Type not in switch when loading map changes from temp file");
|
||||
break;
|
||||
@@ -836,11 +841,7 @@ void SaveBloodSmellAndRevealedStatesFromMapToTempFile()
|
||||
//if there is a structure that is damaged
|
||||
if( gpWorldLevelData[cnt].uiFlags & MAPELEMENT_STRUCTURE_DAMAGED )
|
||||
{
|
||||
STRUCTURE * pCurrent;
|
||||
|
||||
pCurrent = gpWorldLevelData[cnt].pStructureHead;
|
||||
|
||||
pCurrent = FindStructure( cnt, STRUCTURE_BASE_TILE );
|
||||
STRUCTURE* pCurrent = FindStructure( cnt, STRUCTURE_BASE_TILE );
|
||||
|
||||
//loop through all the structures and add all that are damaged
|
||||
while( pCurrent )
|
||||
@@ -848,11 +849,10 @@ void SaveBloodSmellAndRevealedStatesFromMapToTempFile()
|
||||
//if the structure has been damaged
|
||||
if( pCurrent->ubHitPoints < pCurrent->pDBStructureRef->pDBStructure->ubHitPoints )
|
||||
{
|
||||
UINT8 ubBitToSet = 0x80;
|
||||
UINT8 ubLevel=0;
|
||||
|
||||
if( pCurrent->sCubeOffset != 0 )
|
||||
ubLevel |= ubBitToSet;
|
||||
ubLevel |= STRUCTURE_SAVEGAMELEVELFLAG;
|
||||
|
||||
memset( &Map, 0, sizeof( MODIFY_MAP ) );
|
||||
|
||||
@@ -870,6 +870,23 @@ void SaveBloodSmellAndRevealedStatesFromMapToTempFile()
|
||||
SaveModifiedMapStructToMapTempFile( &Map, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
}
|
||||
|
||||
if ( pCurrent->ubDecalFlag )
|
||||
{
|
||||
UINT8 ubLevel = 0;
|
||||
if ( pCurrent->sCubeOffset != 0 )
|
||||
ubLevel |= STRUCTURE_SAVEGAMELEVELFLAG;
|
||||
|
||||
memset( &Map, 0, sizeof( MODIFY_MAP ) );
|
||||
|
||||
Map.usGridNo = cnt;
|
||||
Map.usImageType = StructureFlagToType( pCurrent->fFlags );
|
||||
Map.ubType = SLM_DECAL;
|
||||
Map.ubExtra = pCurrent->ubWallOrientation | ubLevel | STRUCTURE_DECALFLAG_BLOOD;
|
||||
|
||||
//Save the change to the map file
|
||||
SaveModifiedMapStructToMapTempFile( &Map, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
}
|
||||
|
||||
pCurrent = FindNextStructure( pCurrent, STRUCTURE_BASE_TILE );
|
||||
}
|
||||
}
|
||||
@@ -1086,23 +1103,15 @@ void SetMapRevealedStatus()
|
||||
|
||||
void DamageStructsFromMapTempFile( MODIFY_MAP * pMap )
|
||||
{
|
||||
STRUCTURE *pCurrent=NULL;
|
||||
INT8 bLevel;
|
||||
UINT8 ubWallOrientation;
|
||||
UINT8 ubBitToSet = 0x80;
|
||||
UINT8 ubType=0;
|
||||
|
||||
|
||||
//Find the base structure
|
||||
pCurrent = FindStructure( pMap->usGridNo, STRUCTURE_BASE_TILE );
|
||||
STRUCTURE* pCurrent = FindStructure( pMap->usGridNo, STRUCTURE_BASE_TILE );
|
||||
|
||||
if( pCurrent == NULL )
|
||||
if ( pCurrent == NULL )
|
||||
return;
|
||||
|
||||
bLevel = pMap->ubExtra & ubBitToSet;
|
||||
ubWallOrientation = pMap->ubExtra & ~ubBitToSet;
|
||||
ubType = (UINT8) pMap->usImageType;
|
||||
|
||||
INT8 bLevel = ( pMap->ubExtra & STRUCTURE_SAVEGAMELEVELFLAG ) ? 1 : 0;
|
||||
UINT8 ubWallOrientation = pMap->ubExtra & STRUCTURE_SAVEGAMELEVELFLAG_BLK;
|
||||
UINT8 ubType = (UINT8)pMap->usImageType;
|
||||
|
||||
//Check to see if the desired strucure node is in this tile
|
||||
pCurrent = FindStructureBySavedInfo( pMap->usGridNo, ubType, ubWallOrientation, bLevel );
|
||||
@@ -1116,6 +1125,29 @@ void DamageStructsFromMapTempFile( MODIFY_MAP * pMap )
|
||||
}
|
||||
}
|
||||
|
||||
void AddDecalToStructsFromMapTempFile( MODIFY_MAP * pMap )
|
||||
{
|
||||
//Find the base structure
|
||||
STRUCTURE* pCurrent = FindStructure( pMap->usGridNo, STRUCTURE_BASE_TILE );
|
||||
|
||||
if ( pCurrent == NULL )
|
||||
return;
|
||||
|
||||
INT8 bLevel = ( pMap->ubExtra & STRUCTURE_SAVEGAMELEVELFLAG ) ? 1 : 0;
|
||||
UINT8 ubWallOrientation = pMap->ubExtra & STRUCTURE_SAVEGAMELEVELFLAG_BLK;
|
||||
UINT8 ubType = (UINT8)pMap->usImageType;
|
||||
|
||||
//Check to see if the desired strucure node is in this tile
|
||||
pCurrent = FindStructureBySavedInfo( pMap->usGridNo, ubType, ubWallOrientation, bLevel );
|
||||
|
||||
if ( pCurrent != NULL )
|
||||
{
|
||||
pCurrent->ubDecalFlag |= STRUCTURE_DECALFLAG_BLOOD;
|
||||
|
||||
gpWorldLevelData[pCurrent->sGridNo].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ enum
|
||||
// sevenfm
|
||||
SLM_MINE_PRESENT,
|
||||
SLM_REMOVE_MINE_PRESENT, // silversurfer: we need this to get rid of the mine flag otherwise any tile that ever had a mine on it will forever be flagged with MAPELEMENT_PLAYER_MINE_PRESENT
|
||||
SLM_DECAL, // Flugente: add decals
|
||||
};
|
||||
|
||||
typedef struct//dnl ch86 250214
|
||||
|
||||
@@ -123,6 +123,12 @@ extern UINT8 AtHeight[PROFILE_Z_SIZE];
|
||||
#define TILE_ON_ROOF 0x01
|
||||
#define TILE_PASSABLE 0x02
|
||||
|
||||
// Flugente: flags that determine what decals we add on a structure
|
||||
#define STRUCTURE_DECALFLAG_BLOOD 0x08
|
||||
|
||||
#define STRUCTURE_SAVEGAMELEVELFLAG_BLK 0x07 // these flags are already in use for wall orientation
|
||||
#define STRUCTURE_SAVEGAMELEVELFLAG 0x80 // flag already in use for level
|
||||
|
||||
#define AddPosRelToBase(sBaseGridNo, pTile) (pTile->sPosRelToBase ? (sBaseGridNo + pTile->bXPosRelToBase + pTile->bYPosRelToBase * WORLD_COLS) : sBaseGridNo)//dnl ch83 080114
|
||||
|
||||
typedef struct TAG_STRUCTURE_TILE
|
||||
@@ -185,7 +191,7 @@ typedef struct TAG_STRUCTURE
|
||||
UINT8 ubWallOrientation;
|
||||
UINT8 ubVehicleHitLocation;
|
||||
UINT8 ubStructureHeight;// if 0, then unset; otherwise stores height of structure when last calculated
|
||||
UINT8 ubUnused;
|
||||
UINT8 ubDecalFlag;
|
||||
}STRUCTURE;// 36 bytes
|
||||
|
||||
typedef struct TAG_STRUCTURE_FILE_REF
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
|
||||
UINT32 guiShieldGraphic = 0;
|
||||
BOOLEAN fShieldGraphicInit = FALSE;
|
||||
#define WALLDAMAGEGRAPHICS_MAX 2
|
||||
UINT32 guiWallDamageGraphic[WALLDAMAGEGRAPHICS_MAX] = { 0 };
|
||||
BOOLEAN fWallDamageGraphicInit[WALLDAMAGEGRAPHICS_MAX] = { FALSE };
|
||||
UINT32 guiWallBloodGraphic = 0;
|
||||
BOOLEAN fWallBloodGraphicInit = FALSE;
|
||||
|
||||
extern CHAR8 gDebugStr[128];
|
||||
extern BOOLEAN fLandLayerDirty = TRUE;
|
||||
@@ -655,6 +660,219 @@ void ShowRiotShield( SOLDIERTYPE* pSoldier, UINT16 *pBuffer, UINT32 uiDestPitchB
|
||||
}
|
||||
}
|
||||
|
||||
// We can get graphical glitches here if we reserve too many background rectangles, as the entire array will be filled rapidly.
|
||||
// Additionally we get graphic glitches if we never free these background rectangles.
|
||||
// To prevent this, we reserve a limited amount and free them at the beginning of every rendering
|
||||
#define MAX_DECALS_ONSCREEN 200
|
||||
INT32 gDecalBackgroundRectangle[MAX_DECALS_ONSCREEN] = { 0 };
|
||||
int gDecalBackgroundRectableCounter = 0;
|
||||
|
||||
void ClearBackgroundRectanglesForDecal()
|
||||
{
|
||||
for ( int i = 0; i < gDecalBackgroundRectableCounter; ++i )
|
||||
{
|
||||
if ( gDecalBackgroundRectangle[i] != 0 && gDecalBackgroundRectangle[i] != -1 )
|
||||
{
|
||||
FreeBackgroundRect( gDecalBackgroundRectangle[i] );
|
||||
gDecalBackgroundRectangle[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gDecalBackgroundRectableCounter = 0;
|
||||
}
|
||||
|
||||
bool SetupBackgroundRectanglesForDecal( UINT32 uiFlags, INT16 *pSaveArea, INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
|
||||
{
|
||||
if ( gDecalBackgroundRectableCounter < MAX_DECALS_ONSCREEN )
|
||||
{
|
||||
gDecalBackgroundRectangle[gDecalBackgroundRectableCounter] = RegisterBackgroundRect( uiFlags, pSaveArea, sLeft, sTop, sRight, sBottom );
|
||||
|
||||
if ( gDecalBackgroundRectangle[gDecalBackgroundRectableCounter] != -1 )
|
||||
{
|
||||
SetBackgroundRectFilled( gDecalBackgroundRectangle[gDecalBackgroundRectableCounter] );
|
||||
|
||||
++gDecalBackgroundRectableCounter;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Flugente: display decal
|
||||
void ShowDecal( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, INT32 sGridNo )
|
||||
{
|
||||
// we mark locations with decals with the 'DAMAGED' flag for easier filtering
|
||||
if ( gGameExternalOptions.fAdditionalDecals
|
||||
&& gGameSettings.fOptions[TOPTION_BLOOD_N_GORE]
|
||||
&& !TileIsOutOfBounds( sGridNo )
|
||||
&& ( gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_STRUCTURE_DAMAGED ) )
|
||||
{
|
||||
for ( int i = 0; i < WALLDAMAGEGRAPHICS_MAX; ++i )
|
||||
{
|
||||
if ( !fWallDamageGraphicInit[i] )
|
||||
{
|
||||
VOBJECT_DESC VObjectDesc;
|
||||
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
|
||||
|
||||
CHAR8 filename[128];
|
||||
sprintf( filename, "Tilecache\\walldamage%d.sti", i );
|
||||
|
||||
FilenameForBPP( filename, VObjectDesc.ImageFile );
|
||||
if ( !AddVideoObject( &VObjectDesc, &guiWallDamageGraphic[i] ) )
|
||||
AssertMsg( 0, String( "Missing %s", VObjectDesc.ImageFile ) );
|
||||
|
||||
fWallDamageGraphicInit[i] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !fWallBloodGraphicInit )
|
||||
{
|
||||
VOBJECT_DESC VObjectDesc;
|
||||
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
|
||||
FilenameForBPP( "Tilecache\\bloodspatter_wall.sti", VObjectDesc.ImageFile );
|
||||
if ( !AddVideoObject( &VObjectDesc, &guiWallBloodGraphic ) )
|
||||
AssertMsg( 0, String( "Missing %s", VObjectDesc.ImageFile ) );
|
||||
|
||||
fWallBloodGraphicInit = TRUE;
|
||||
}
|
||||
|
||||
// rendering while scrolling is a pain in the ass, so we skip that
|
||||
if ( gfScrollPending || gfScrollInertia )
|
||||
return;
|
||||
|
||||
STRUCTURE* pStructure = FindStructure( sGridNo, STRUCTURE_WALL );
|
||||
if ( !pStructure )
|
||||
return;
|
||||
|
||||
// Get screen pos of gridno......
|
||||
INT16 sScreenX, sScreenY;
|
||||
GetGridNoScreenXY( sGridNo, &sScreenX, &sScreenY );
|
||||
|
||||
// For ease of use, the pics from the libraries are without an offset, we handle this here. Of course this assumes the painter starts with the proper template to begin with.
|
||||
INT32 displayX = sScreenX - WORLD_TILE_X / 2;
|
||||
INT32 displayY = sScreenY - WORLD_TILE_Y / 2 - 41;
|
||||
|
||||
// we need to reserve a background if we draw decals, but we only need to do that once
|
||||
bool backgroundrectregistered = false;
|
||||
|
||||
//loop through all the structures and add all that are damaged
|
||||
while ( pStructure )
|
||||
{
|
||||
// for now only for full walls
|
||||
if ( StructureHeight(pStructure) == 4
|
||||
&& ( pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT
|
||||
|| pStructure->ubWallOrientation == INSIDE_TOP_LEFT
|
||||
|| pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT
|
||||
|| pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ))
|
||||
{
|
||||
//if the structure has been damaged
|
||||
if ( pStructure->ubHitPoints < pStructure->pDBStructureRef->pDBStructure->ubHitPoints )
|
||||
{
|
||||
int graphiclib = sGridNo % WALLDAMAGEGRAPHICS_MAX;
|
||||
|
||||
HVOBJECT hSrcVObject;
|
||||
if ( GetVideoObject( &hSrcVObject, guiWallDamageGraphic[graphiclib] ) )
|
||||
{
|
||||
// redraw background to stop weird graphic remnants remaining
|
||||
// but don't do so while scrolling, because that looks weird
|
||||
if ( !backgroundrectregistered )
|
||||
{
|
||||
if ( !SetupBackgroundRectanglesForDecal( BGND_FLAG_ANIMATED, NULL, displayX - 50, displayY - 60, displayX + 50, displayY + 60 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
backgroundrectregistered = true;
|
||||
}
|
||||
|
||||
FLOAT ratio = (FLOAT)( pStructure->ubHitPoints ) / (FLOAT)( pStructure->pDBStructureRef->pDBStructure->ubHitPoints );
|
||||
|
||||
// The first half of the pics are for the left side, the second half for the right side
|
||||
UINT16 picsperside = hSrcVObject->usNumberOfObjects / 2;
|
||||
|
||||
UINT16 graphic = 0;
|
||||
displayX = sScreenX - WORLD_TILE_X / 2;
|
||||
|
||||
switch ( pStructure->ubWallOrientation )
|
||||
{
|
||||
case OUTSIDE_TOP_LEFT:
|
||||
case INSIDE_TOP_LEFT:
|
||||
{
|
||||
graphic = ratio * picsperside;
|
||||
}
|
||||
break;
|
||||
|
||||
case OUTSIDE_TOP_RIGHT:
|
||||
case INSIDE_TOP_RIGHT:
|
||||
{
|
||||
graphic = ratio * picsperside + picsperside;
|
||||
displayX += 16;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( BltIsClippedOrOffScreen( hSrcVObject, displayX, displayY, graphic, &gClippingRect ) )
|
||||
return;
|
||||
|
||||
Blt8BPPDataTo16BPPBufferTransZNB( pBuffer, uiDestPitchBYTES, pZBuffer, usZValue, hSrcVObject, displayX, displayY, graphic );
|
||||
}
|
||||
}
|
||||
|
||||
if ( pStructure->ubDecalFlag & STRUCTURE_DECALFLAG_BLOOD )
|
||||
{
|
||||
HVOBJECT hSrcVObject;
|
||||
if ( GetVideoObject( &hSrcVObject, guiWallBloodGraphic ) )
|
||||
{
|
||||
// redraw background to stop weird graphic remnants remaining
|
||||
// but don't do so while scrolling, because that looks weird
|
||||
if ( !backgroundrectregistered )
|
||||
{
|
||||
if ( !SetupBackgroundRectanglesForDecal( BGND_FLAG_ANIMATED, NULL, displayX - 50, displayY - 60, displayX + 50, displayY + 60 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
backgroundrectregistered = true;
|
||||
}
|
||||
|
||||
// The first half of the pics are for the left side, the second half for the right side
|
||||
UINT16 picsperside = hSrcVObject->usNumberOfObjects / 2;
|
||||
|
||||
UINT16 graphic = 0;
|
||||
displayX = sScreenX - WORLD_TILE_X / 2;
|
||||
|
||||
switch ( pStructure->ubWallOrientation )
|
||||
{
|
||||
case OUTSIDE_TOP_LEFT:
|
||||
case INSIDE_TOP_LEFT:
|
||||
// It is advised that the number of pics per side does not divide the map length per side - 160 or 360 - without remainder.
|
||||
// Otherwise the spatters along a '/' wall will all be the same
|
||||
graphic = ( sGridNo ) % picsperside;
|
||||
break;
|
||||
|
||||
case OUTSIDE_TOP_RIGHT:
|
||||
case INSIDE_TOP_RIGHT:
|
||||
graphic = ( sGridNo ) % picsperside + picsperside;
|
||||
displayX += 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( BltIsClippedOrOffScreen( hSrcVObject, displayX, displayY, graphic, &gClippingRect ) )
|
||||
return;
|
||||
|
||||
Blt8BPPDataTo16BPPBufferTransZNB( pBuffer, uiDestPitchBYTES, pZBuffer, usZValue, hSrcVObject, displayX, displayY, graphic );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pStructure = FindNextStructure( pStructure, STRUCTURE_WALL );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN RevealWalls(INT16 sX, INT16 sY, INT16 sRadius)
|
||||
{
|
||||
LEVELNODE *pStruct;
|
||||
@@ -1058,6 +1276,9 @@ void RenderTiles(UINT32 uiFlags, INT32 iStartPointX_M, INT32 iStartPointY_M, INT
|
||||
iAnchorPosX_S = iStartPointX_S;
|
||||
iAnchorPosY_S = iStartPointY_S;
|
||||
|
||||
// Flugente: clear rectangles reserved for decals
|
||||
ClearBackgroundRectanglesForDecal();
|
||||
|
||||
if (!(uiFlags&TILES_DIRTY))
|
||||
pDestBuf = LockVideoSurface(FRAME_BUFFER, &uiDestPitchBYTES);
|
||||
|
||||
@@ -2818,6 +3039,12 @@ void RenderTiles(UINT32 uiFlags, INT32 iStartPointX_M, INT32 iStartPointY_M, INT
|
||||
Blt8BPPDataTo8BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sXPos, sYPos, usImageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: additional decals
|
||||
if ( fWallTile )
|
||||
{
|
||||
ShowDecal( (UINT16*)pDestBuf, uiDestPitchBYTES, gpZBuffer, sZLevel, uiTileIndex );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "Animation Control.h"
|
||||
#include "Soldier Ani.h"
|
||||
#include "ASD.h" // added by Flugente
|
||||
#include "renderworld.h" // added by Flugente for SetRenderFlags( RENDER_FLAG_FULL );
|
||||
#endif
|
||||
|
||||
#ifdef COUNT_PATHS
|
||||
@@ -1992,6 +1993,9 @@ INT8 DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason, IN
|
||||
//Since the structure is being damaged, set the map element that a structure is damaged
|
||||
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
|
||||
|
||||
// Flugente: enforce a full render, so that we can draw decals on time
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
|
||||
// We are a little damaged....
|
||||
return( 2 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user