mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- if a a roof collapses, any structures built on it (fans, sandbags) are destroyed
- if a a roof collapses, any corpses on it are moved to the floor git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7623 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -5934,6 +5934,32 @@ void RoofDestruction( INT32 sGridNo )
|
||||
SoldierDropThroughRoof( pSoldier, soldierdropoffgridno );
|
||||
}
|
||||
|
||||
// there can be non-roof structures on roofs. In order to collapse those, check for all structures who are above a certain height, and destroy them
|
||||
STRUCTURE* pStruct = GetTallestStructureOnGridno( sGridNo, 1 );
|
||||
while ( pStruct )
|
||||
{
|
||||
LEVELNODE* pNode = FindLevelNodeBasedOnStructure( pStruct->sGridNo, pStruct );
|
||||
|
||||
if ( pNode )
|
||||
{
|
||||
if ( RemoveOnRoofStruct( sGridNo, pNode->usIndex ) )
|
||||
pStruct = GetTallestStructureOnGridno( sGridNo, 1 );
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// very important: if applying changes to map files is turned on, adding corpses will corrupt the map (only noticeable if you reload it)
|
||||
// for this reason we turn this off and on again
|
||||
ApplyMapChangesToMapTempFile( FALSE );
|
||||
|
||||
// if there is a corpse here, drop that down as well
|
||||
ShiftCorpse( sGridNo , 1);
|
||||
|
||||
ApplyMapChangesToMapTempFile( TRUE );
|
||||
|
||||
// play an animation of falling roof tiles
|
||||
// if we merely collected the tiles that collapse and then call them all together, it would be possible to have animations for multi-tile collapses
|
||||
static UINT16 usRoofCollapseExplosionIndex = 1727;
|
||||
@@ -6016,7 +6042,7 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
||||
(*it).second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Nodes might have been removed, and the roof might have degenerated into several networks
|
||||
gridnoarmournetworkmap roofnetworkmap = GetConnectedRoofNetworks( floorarmourvector );
|
||||
|
||||
|
||||
@@ -461,6 +461,22 @@ BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( )
|
||||
++uiNumberOfElementsSavedBackToFile;
|
||||
break;
|
||||
case SLM_REMOVE_ONROOF:
|
||||
if ( pMap->usImageType >= FIRSTTEXTURE && pMap->usImageType <= WIREFRAMES )
|
||||
{
|
||||
RemoveAllOnRoofsOfTypeRange( pMap->usGridNo, FIRSTTEXTURE, WIREFRAMES );
|
||||
}
|
||||
else
|
||||
{
|
||||
GetTileIndexFromTypeSubIndex( pMap->usImageType, pMap->usSubImageIndex, &usIndex );
|
||||
|
||||
RemoveOnRoofAdjustSavefile( pMap->usGridNo, usIndex );
|
||||
}
|
||||
|
||||
// Save this struct back to the temp file
|
||||
SaveModifiedMapStructToMapTempFile( pMap, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
|
||||
//Since the element is being saved back to the temp file, increment the #
|
||||
++uiNumberOfElementsSavedBackToFile;
|
||||
break;
|
||||
case SLM_REMOVE_TOPMOST:
|
||||
break;
|
||||
@@ -706,6 +722,33 @@ void RemoveRoofFromMapTempFile( INT32 uiMapIndex, UINT16 usIndex )
|
||||
SaveModifiedMapStructToMapTempFile( &Map, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
}
|
||||
|
||||
void RemoveOnRoofFromMapTempFile( INT32 uiMapIndex, UINT16 usIndex )
|
||||
{
|
||||
MODIFY_MAP Map;
|
||||
UINT32 uiType;
|
||||
UINT16 usSubIndex;
|
||||
|
||||
if ( !gfApplyChangesToTempFile )
|
||||
return;
|
||||
|
||||
if ( gTacticalStatus.uiFlags & LOADING_SAVED_GAME )
|
||||
return;
|
||||
|
||||
GetTileType( usIndex, &uiType );
|
||||
GetSubIndexFromTileIndex( usIndex, &usSubIndex );
|
||||
|
||||
memset( &Map, 0, sizeof(MODIFY_MAP) );
|
||||
|
||||
Map.usGridNo = uiMapIndex;
|
||||
// Map.usIndex = usIndex;
|
||||
Map.usImageType = (UINT16)uiType;
|
||||
Map.usSubImageIndex = usSubIndex;
|
||||
|
||||
Map.ubType = SLM_REMOVE_ONROOF;
|
||||
|
||||
SaveModifiedMapStructToMapTempFile( &Map, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
}
|
||||
|
||||
|
||||
void RemoveSavedStructFromMap( INT32 uiMapIndex, UINT16 usIndex )
|
||||
{
|
||||
|
||||
@@ -82,8 +82,9 @@ BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( );
|
||||
|
||||
void RemoveStructFromMapTempFile( INT32 uiMapIndex, UINT16 usIndex );
|
||||
|
||||
// Flugente: permanently remove roof tiles
|
||||
// Flugente: permanently remove other tiles
|
||||
void RemoveRoofFromMapTempFile( INT32 uiMapIndex, UINT16 usIndex );
|
||||
void RemoveOnRoofFromMapTempFile( INT32 uiMapIndex, UINT16 usIndex );
|
||||
|
||||
void AddRemoveObjectToMapTempFile( INT32 uiMapIndex, UINT16 usIndex );
|
||||
|
||||
|
||||
@@ -2460,6 +2460,44 @@ BOOLEAN FiniStructureDB( void )
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
STRUCTURE* GetTallestStructureOnGridno( INT32 sGridNo, INT8 bLevel )
|
||||
{
|
||||
STRUCTURE* pCurrent = NULL;
|
||||
STRUCTURE* pStruct = NULL;
|
||||
INT8 bestheight = -1;
|
||||
INT16 sDesiredLevel = STRUCTURE_ON_GROUND;
|
||||
|
||||
if ( bLevel )
|
||||
sDesiredLevel = STRUCTURE_ON_ROOF;
|
||||
|
||||
pCurrent = gpWorldLevelData[sGridNo].pStructureHead;
|
||||
|
||||
while ( pCurrent != NULL )
|
||||
{
|
||||
// Check level!
|
||||
if ( pCurrent->sCubeOffset == sDesiredLevel )
|
||||
{
|
||||
if ( pCurrent->fFlags & (STRUCTURE_CORPSE | STRUCTURE_PERSON | STRUCTURE_ROOF) )
|
||||
{
|
||||
// we are interested in building tiles, not people
|
||||
pCurrent = pCurrent->pNext;
|
||||
continue;
|
||||
}
|
||||
|
||||
INT8 height = StructureHeight( pCurrent );
|
||||
if ( height > bestheight )
|
||||
{
|
||||
bestheight = height;
|
||||
pStruct = pCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
|
||||
return pStruct;
|
||||
}
|
||||
|
||||
|
||||
INT8 GetBlockingStructureInfo( INT32 sGridNo, INT8 bDir, INT8 bNextDir, INT8 bLevel, INT8 *pStructHeight, STRUCTURE ** ppTallestStructure, BOOLEAN fWallsBlock )
|
||||
{
|
||||
|
||||
@@ -82,6 +82,9 @@ void DebugStructurePage1( void );
|
||||
|
||||
BOOLEAN AddZStripInfoToVObject( HVOBJECT hVObject, STRUCTURE_FILE_REF * pStructureFileRef, BOOLEAN fFromAnimation, INT16 sSTIStartIndex );
|
||||
|
||||
// Flugente: return the highest structure (no person, roof or corpse) on a gridno and level
|
||||
STRUCTURE* GetTallestStructureOnGridno( INT32 sGridNo, INT8 bLevel );
|
||||
|
||||
// FUNCTIONS FOR DETERMINING STUFF THAT BLOCKS VIEW FOR TILE_bASED LOS
|
||||
INT8 GetBlockingStructureInfo( INT32 sGridNo, INT8 bDir, INT8 bNextDir, INT8 bLevel, INT8 *pStructHeight, STRUCTURE ** ppTallestStructure, BOOLEAN fWallsBlock );
|
||||
|
||||
|
||||
+159
-13
@@ -1429,7 +1429,7 @@ BOOLEAN RemoveStruct( INT32 iMapIndex, UINT16 usIndex )
|
||||
if ( pOldStruct == NULL )
|
||||
{
|
||||
// It's the head
|
||||
gpWorldLevelData[ iMapIndex ].pStructHead = pStruct->pNext;
|
||||
gpWorldLevelData[iMapIndex].pStructHead = pStruct->pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1462,7 +1462,7 @@ BOOLEAN RemoveStruct( INT32 iMapIndex, UINT16 usIndex )
|
||||
}
|
||||
}
|
||||
MemFree( pStruct );
|
||||
guiLevelNodes--;
|
||||
--guiLevelNodes;
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
@@ -1476,10 +1476,75 @@ BOOLEAN RemoveStruct( INT32 iMapIndex, UINT16 usIndex )
|
||||
RemoveWorldFlagsFromNewNode( iMapIndex, usIndex );
|
||||
|
||||
return( FALSE );
|
||||
|
||||
}
|
||||
|
||||
// Flugente: permanently remove roof tiles
|
||||
// same as RemoveStruct(...), except that this focuses on .pOnRoofHead instead of .pStructHead
|
||||
BOOLEAN RemoveOnRoofStruct( INT32 iMapIndex, UINT16 usIndex )
|
||||
{
|
||||
LEVELNODE *pStruct = NULL;
|
||||
LEVELNODE *pOldStruct = NULL;
|
||||
|
||||
pStruct = gpWorldLevelData[iMapIndex].pOnRoofHead;
|
||||
|
||||
// Look through all structs and remove index if found
|
||||
while ( pStruct != NULL )
|
||||
{
|
||||
if ( pStruct->usIndex == usIndex )
|
||||
{
|
||||
// OK, set links
|
||||
// Check for head or tail
|
||||
if ( pOldStruct == NULL )
|
||||
{
|
||||
// It's the head
|
||||
gpWorldLevelData[iMapIndex].pOnRoofHead = pStruct->pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOldStruct->pNext = pStruct->pNext;
|
||||
}
|
||||
|
||||
//Check for special flag to stop burn-through on same-tile structs...
|
||||
if ( pStruct->pStructureData != NULL )
|
||||
{
|
||||
// If we are NOT a wall and NOT multi-tiles, set mapelement flag...
|
||||
//if ( !( pStruct->pStructureData->fFlags & STRUCTURE_WALLSTUFF ) && pStruct->pStructureData->pDBStructureRef->pDBStructure->ubNumberOfTiles == 1 )
|
||||
//{
|
||||
// UNSet flag...
|
||||
// gpWorldLevelData[ iMapIndex ].ubExtFlags[0] &= ( ~MAPELEMENT_EXT_NOBURN_STRUCT );
|
||||
//}
|
||||
}
|
||||
|
||||
// Delete memory assosiated with item
|
||||
DeleteStructureFromWorld( pStruct->pStructureData );
|
||||
|
||||
//If we have to, make sure to remove this node when we reload the map from a saved game
|
||||
RemoveOnRoofFromMapTempFile( iMapIndex, usIndex );
|
||||
|
||||
if ( usIndex < giNumberOfTiles )
|
||||
{
|
||||
// Check flags for tiledat and set a shadow if we have a buddy
|
||||
if ( !GridNoIndoors( iMapIndex ) && gTileDatabase[usIndex].uiFlags & HAS_SHADOW_BUDDY && gTileDatabase[usIndex].sBuddyNum != -1 )
|
||||
{
|
||||
RemoveShadow( iMapIndex, gTileDatabase[usIndex].sBuddyNum );
|
||||
}
|
||||
}
|
||||
MemFree( pStruct );
|
||||
--guiLevelNodes;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
pOldStruct = pStruct;
|
||||
pStruct = pStruct->pNext;
|
||||
}
|
||||
|
||||
// Could not find it, return FALSE
|
||||
RemoveWorldFlagsFromNewNode( iMapIndex, usIndex );
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// Flugente: permanently remove structures
|
||||
BOOLEAN RemoveRoofAdjustSavefile( INT32 iMapIndex, UINT16 usIndex )
|
||||
{
|
||||
LEVELNODE *pStruct = NULL;
|
||||
@@ -1527,6 +1592,53 @@ BOOLEAN RemoveRoofAdjustSavefile( INT32 iMapIndex, UINT16 usIndex )
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
BOOLEAN RemoveOnRoofAdjustSavefile( INT32 iMapIndex, UINT16 usIndex )
|
||||
{
|
||||
LEVELNODE *pStruct = NULL;
|
||||
LEVELNODE *pOldStruct = NULL;
|
||||
|
||||
pStruct = gpWorldLevelData[iMapIndex].pOnRoofHead;
|
||||
|
||||
// Look through all structs and remove index if found
|
||||
|
||||
while ( pStruct != NULL )
|
||||
{
|
||||
if ( pStruct->usIndex == usIndex )
|
||||
{
|
||||
// OK, set links
|
||||
// Check for head or tail
|
||||
if ( pOldStruct == NULL )
|
||||
{
|
||||
// It's the head
|
||||
gpWorldLevelData[iMapIndex].pOnRoofHead = pStruct->pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOldStruct->pNext = pStruct->pNext;
|
||||
}
|
||||
|
||||
// Delete memory assosiated with item
|
||||
DeleteStructureFromWorld( pStruct->pStructureData );
|
||||
|
||||
//If we have to, make sure to remove this node when we reload the map from a saved game
|
||||
RemoveOnRoofFromMapTempFile( iMapIndex, usIndex );
|
||||
|
||||
MemFree( pStruct );
|
||||
--guiLevelNodes;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
pOldStruct = pStruct;
|
||||
pStruct = pStruct->pNext;
|
||||
}
|
||||
|
||||
// Could not find it, return FALSE
|
||||
RemoveWorldFlagsFromNewNode( iMapIndex, usIndex );
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN RemoveStructFromLevelNode( INT32 iMapIndex, LEVELNODE *pNode )
|
||||
{
|
||||
@@ -1632,7 +1744,7 @@ BOOLEAN RemoveAllStructsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32
|
||||
return fRetVal;
|
||||
}
|
||||
|
||||
// Flugente: permanently remove roof tiles
|
||||
// Flugente: permanently remove structures
|
||||
BOOLEAN RemoveAllRoofsOfTypeRangeAdjustSaveFile( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType )
|
||||
{
|
||||
LEVELNODE *pStruct = NULL;
|
||||
@@ -1672,6 +1784,45 @@ BOOLEAN RemoveAllRoofsOfTypeRangeAdjustSaveFile( INT32 iMapIndex, UINT32 fStartT
|
||||
return fRetVal;
|
||||
}
|
||||
|
||||
BOOLEAN RemoveAllOnRoofsOfTypeRangeAdjustSaveFile( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType )
|
||||
{
|
||||
LEVELNODE *pStruct = NULL;
|
||||
LEVELNODE *pOldStruct = NULL;
|
||||
UINT32 fTileType;
|
||||
BOOLEAN fRetVal = FALSE;
|
||||
|
||||
LEVELNODE *pRoof = NULL;
|
||||
LEVELNODE *pOldRoof = NULL;
|
||||
|
||||
pRoof = gpWorldLevelData[iMapIndex].pOnRoofHead;
|
||||
|
||||
// Look through all Roofs and Search for type
|
||||
|
||||
if ( pRoof != NULL )
|
||||
{
|
||||
if ( pRoof->usIndex != NO_TILE )
|
||||
{
|
||||
GetTileType( pRoof->usIndex, &fTileType );
|
||||
|
||||
// Advance to next
|
||||
pOldRoof = pRoof;
|
||||
pRoof = pRoof->pNext;
|
||||
|
||||
if ( fTileType >= fStartType && fTileType <= fEndType )
|
||||
{
|
||||
// Remove Item
|
||||
if ( pOldRoof->usIndex < giNumberOfTiles )
|
||||
{
|
||||
RemoveOnRoofAdjustSavefile( iMapIndex, pOldRoof->usIndex );
|
||||
fRetVal = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fRetVal;
|
||||
}
|
||||
|
||||
//Kris: This was a serious problem. When saving the map and then reloading it, the structure
|
||||
// information was invalid if you changed the types, etc. This is the bulletproof way.
|
||||
BOOLEAN ReplaceStructIndex( INT32 iMapIndex, UINT16 usOldIndex, UINT16 usNewIndex )
|
||||
@@ -2741,9 +2892,9 @@ void AdjustAllRoofShadeLevels( INT32 iMapIndex, INT8 bShadeDiff )
|
||||
BOOLEAN RemoveAllRoofsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType )
|
||||
{
|
||||
LEVELNODE *pRoof = NULL;
|
||||
LEVELNODE *pOldRoof = NULL;
|
||||
UINT32 fTileType;
|
||||
BOOLEAN fRetVal = FALSE;
|
||||
LEVELNODE *pOldRoof = NULL;
|
||||
UINT32 fTileType;
|
||||
BOOLEAN fRetVal = FALSE;
|
||||
|
||||
pRoof = gpWorldLevelData[ iMapIndex ].pRoofHead;
|
||||
|
||||
@@ -2751,10 +2902,8 @@ BOOLEAN RemoveAllRoofsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32 fE
|
||||
|
||||
while( pRoof != NULL )
|
||||
{
|
||||
|
||||
if ( pRoof->usIndex != NO_TILE )
|
||||
{
|
||||
|
||||
GetTileType( pRoof->usIndex, &fTileType );
|
||||
|
||||
// Advance to next
|
||||
@@ -2767,15 +2916,12 @@ BOOLEAN RemoveAllRoofsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32 fE
|
||||
RemoveRoof( iMapIndex, pOldRoof->usIndex );
|
||||
fRetVal = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Could not find it, return FALSE
|
||||
|
||||
return fRetVal;
|
||||
|
||||
}
|
||||
|
||||
void RemoveRoofIndexFlagsFromTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType, UINT32 uiFlags )
|
||||
|
||||
@@ -69,9 +69,11 @@ BOOLEAN WaterTooDeepForAttacks( INT32 sGridNo );
|
||||
|
||||
// Structure manipulation routines
|
||||
BOOLEAN RemoveStruct( INT32 iMapIndex, UINT16 usIndex );
|
||||
BOOLEAN RemoveOnRoofStruct( INT32 iMapIndex, UINT16 usIndex );
|
||||
|
||||
// Flugente: permanently remove roof tiles
|
||||
// Flugente: permanently remove structures
|
||||
BOOLEAN RemoveRoofAdjustSavefile( INT32 iMapIndex, UINT16 usIndex );
|
||||
BOOLEAN RemoveOnRoofAdjustSavefile( INT32 iMapIndex, UINT16 usIndex );
|
||||
|
||||
LEVELNODE *AddStructToTail( INT32 iMapIndex, UINT16 usIndex );
|
||||
LEVELNODE *AddStructToTailCommon( INT32 iMapIndex, UINT16 usIndex, BOOLEAN fAddStructDBInfo );
|
||||
@@ -81,8 +83,9 @@ BOOLEAN AddStructToHead( INT32 iMapIndex, UINT16 usIndex );
|
||||
BOOLEAN TypeExistsInStructLayer( INT32 iMapIndex, UINT32 fType, UINT16 *pusStructIndex );
|
||||
BOOLEAN RemoveAllStructsOfTypeRange( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
|
||||
|
||||
// Flugente: permanently remove roof tiles
|
||||
// Flugente: permanently remove structures
|
||||
BOOLEAN RemoveAllRoofsOfTypeRangeAdjustSaveFile( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
|
||||
BOOLEAN RemoveAllOnRoofsOfTypeRangeAdjustSaveFile( INT32 iMapIndex, UINT32 fStartType, UINT32 fEndType );
|
||||
|
||||
BOOLEAN AddWallToStructLayer( INT32 iMapIndex, UINT16 usIndex, BOOLEAN fReplace );
|
||||
BOOLEAN ReplaceStructIndex( INT32 iMapIndex, UINT16 usOldIndex, UINT16 usNewIndex );
|
||||
|
||||
Reference in New Issue
Block a user