mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
Accelerated roof collapse code
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8379 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -5832,59 +5832,16 @@ gridnoarmourvector GetConnectedRoofGridnoArmours( INT32 sGridNo )
|
|||||||
INT32 currentgridno = vec[cnt++].first;
|
INT32 currentgridno = vec[cnt++].first;
|
||||||
|
|
||||||
// determine all neighbouring gridnos. If they have a roof, add them to the list
|
// determine all neighbouring gridnos. If they have a roof, add them to the list
|
||||||
|
for ( int i = 0; i < 4; ++i )
|
||||||
{
|
{
|
||||||
INT32 nextgridno = currentgridno + 1;
|
INT32 nextgridno = currentgridno + 1;
|
||||||
if ( !TileIsOutOfBounds( nextgridno ) && IsRoofPresentAtGridNo( nextgridno ) )
|
if ( i == 1 )
|
||||||
{
|
nextgridno = currentgridno - 1;
|
||||||
UINT8 armour = 0;
|
else if ( i == 2 )
|
||||||
STRUCTURE* pStruct = FindStructure( nextgridno, (STRUCTURE_WALL) );
|
nextgridno = currentgridno + WORLD_COLS;
|
||||||
|
if ( i == 3 )
|
||||||
|
nextgridno = currentgridno - WORLD_COLS;
|
||||||
|
|
||||||
if ( pStruct )
|
|
||||||
armour = gubMaterialArmour[pStruct->pDBStructureRef->pDBStructure->ubArmour];
|
|
||||||
|
|
||||||
gridnoarmourpair pair( nextgridno, armour );
|
|
||||||
|
|
||||||
if ( std::find( vec.begin( ), vec.end( ), pair ) == vec.end( ) )
|
|
||||||
vec.push_back( pair );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
INT32 nextgridno = currentgridno - 1;
|
|
||||||
if ( !TileIsOutOfBounds( nextgridno ) && IsRoofPresentAtGridNo( nextgridno ) )
|
|
||||||
{
|
|
||||||
UINT8 armour = 0;
|
|
||||||
STRUCTURE* pStruct = FindStructure( nextgridno, (STRUCTURE_WALL) );
|
|
||||||
|
|
||||||
if ( pStruct )
|
|
||||||
armour = gubMaterialArmour[pStruct->pDBStructureRef->pDBStructure->ubArmour];
|
|
||||||
|
|
||||||
std::pair<INT32, UINT8> pair( nextgridno, armour );
|
|
||||||
|
|
||||||
if ( std::find( vec.begin( ), vec.end( ), pair ) == vec.end( ) )
|
|
||||||
vec.push_back( pair );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
INT32 nextgridno = currentgridno + WORLD_COLS;
|
|
||||||
if ( !TileIsOutOfBounds( nextgridno ) && IsRoofPresentAtGridNo( nextgridno ) )
|
|
||||||
{
|
|
||||||
UINT8 armour = 0;
|
|
||||||
STRUCTURE* pStruct = FindStructure( nextgridno, (STRUCTURE_WALL) );
|
|
||||||
|
|
||||||
if ( pStruct )
|
|
||||||
armour = gubMaterialArmour[pStruct->pDBStructureRef->pDBStructure->ubArmour];
|
|
||||||
|
|
||||||
gridnoarmourpair pair( nextgridno, armour );
|
|
||||||
|
|
||||||
if ( std::find( vec.begin( ), vec.end( ), pair ) == vec.end( ) )
|
|
||||||
vec.push_back( pair );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
INT32 nextgridno = currentgridno - WORLD_COLS;
|
|
||||||
if ( !TileIsOutOfBounds( nextgridno ) && IsRoofPresentAtGridNo( nextgridno ) )
|
if ( !TileIsOutOfBounds( nextgridno ) && IsRoofPresentAtGridNo( nextgridno ) )
|
||||||
{
|
{
|
||||||
UINT8 armour = 0;
|
UINT8 armour = 0;
|
||||||
@@ -6165,9 +6122,7 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
|||||||
// only if there is significant damage done
|
// only if there is significant damage done
|
||||||
if ( sDamage < 1 || !gGameExternalOptions.fRoofCollapse || TileIsOutOfBounds( sGridNo ) || !IsRoofPresentAtGridNo( sGridNo ) )
|
if ( sDamage < 1 || !gGameExternalOptions.fRoofCollapse || TileIsOutOfBounds( sGridNo ) || !IsRoofPresentAtGridNo( sGridNo ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ApplyMapChangesToMapTempFile( TRUE );
|
|
||||||
|
|
||||||
gridnoarmourvector floorarmourvector = GetConnectedRoofGridnoArmours( sGridNo );
|
gridnoarmourvector floorarmourvector = GetConnectedRoofGridnoArmours( sGridNo );
|
||||||
|
|
||||||
INT16 bestarmour = 0;
|
INT16 bestarmour = 0;
|
||||||
@@ -6175,6 +6130,12 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
|||||||
for ( gridnoarmourvector::iterator it = floorarmourvector.begin( ); it != itend; ++it )
|
for ( gridnoarmourvector::iterator it = floorarmourvector.begin( ); it != itend; ++it )
|
||||||
bestarmour = max( bestarmour, (INT16)(*it).second );
|
bestarmour = max( bestarmour, (INT16)(*it).second );
|
||||||
|
|
||||||
|
// armour above 127 is deemed indestructable
|
||||||
|
if ( bestarmour >= 127 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ApplyMapChangesToMapTempFile( TRUE );
|
||||||
|
|
||||||
for ( gridnoarmourvector::iterator it = floorarmourvector.begin( ); it != itend; ++it )
|
for ( gridnoarmourvector::iterator it = floorarmourvector.begin( ); it != itend; ++it )
|
||||||
{
|
{
|
||||||
INT32 sNewGridno = (*it).first;
|
INT32 sNewGridno = (*it).first;
|
||||||
@@ -6186,14 +6147,13 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
|||||||
|
|
||||||
// only remove tile if enough damage has been done
|
// only remove tile if enough damage has been done
|
||||||
// it might be necessary to tweak the damage formula here
|
// it might be necessary to tweak the damage formula here
|
||||||
// armour above 127 is deemed indestructable
|
if ( sDamage > distance * bestarmour )
|
||||||
if ( bestarmour < 127 && sDamage > distance * bestarmour )
|
|
||||||
{
|
{
|
||||||
if ( DamageRoof( sNewGridno, sDamage - distance * bestarmour ) )
|
if ( DamageRoof( sNewGridno, sDamage - distance * bestarmour ) )
|
||||||
(*it).second = 0;
|
(*it).second = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes might have been removed, and the roof might have degenerated into several networks
|
// Nodes might have been removed, and the roof might have degenerated into several networks
|
||||||
gridnoarmournetworkmap roofnetworkmap = GetConnectedRoofNetworks( floorarmourvector );
|
gridnoarmournetworkmap roofnetworkmap = GetConnectedRoofNetworks( floorarmourvector );
|
||||||
|
|
||||||
@@ -6201,14 +6161,16 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
|||||||
gridnoarmournetworkmap::iterator roofnetworkitend = roofnetworkmap.end( );
|
gridnoarmournetworkmap::iterator roofnetworkitend = roofnetworkmap.end( );
|
||||||
for ( gridnoarmournetworkmap::iterator roofnetworkit = roofnetworkmap.begin( ); roofnetworkit != roofnetworkitend; ++roofnetworkit )
|
for ( gridnoarmournetworkmap::iterator roofnetworkit = roofnetworkmap.begin( ); roofnetworkit != roofnetworkitend; ++roofnetworkit )
|
||||||
{
|
{
|
||||||
|
gridnoarmourvector roofnetwork = (*roofnetworkit).second;
|
||||||
|
|
||||||
// sadly the calculating time is somewhat high if there are many nodes connected to the roof, like Alma prison.
|
// sadly the calculating time is somewhat high if there are many nodes connected to the roof, like Alma prison.
|
||||||
// therefore this part is commented out. Can be commented in once the speed issues have been resolved
|
// therefore this part is commented out. Can be commented in once the speed issues have been resolved
|
||||||
// properly done, this would simulat the 'structural integrity' of the building
|
// properly done, this would simulate the 'structural integrity' of the building
|
||||||
// for each remaining node, determine the distance to the closest node with a wall-connection inside the remaining network. If the distance is high enough, the roof will come down
|
// for each remaining node, determine the distance to the closest node with a wall-connection inside the remaining network. If the distance is high enough, the roof will come down
|
||||||
gridnoarmourvector roofarmoursharednetwork = GetArmourSharedRoofNetwork( (*roofnetworkit).second );
|
if ( roofnetwork.size( ) < 200 )
|
||||||
|
|
||||||
if ( roofarmoursharednetwork.size() < 200 )
|
|
||||||
{
|
{
|
||||||
|
gridnoarmourvector roofarmoursharednetwork = GetArmourSharedRoofNetwork( roofnetwork );
|
||||||
|
|
||||||
for ( gridnoarmourvector::iterator it = roofarmoursharednetwork.begin( ); it != roofarmoursharednetwork.end( ); ++it )
|
for ( gridnoarmourvector::iterator it = roofarmoursharednetwork.begin( ); it != roofarmoursharednetwork.end( ); ++it )
|
||||||
{
|
{
|
||||||
gridnoarmourpair pair = (*it);
|
gridnoarmourpair pair = (*it);
|
||||||
@@ -6220,6 +6182,7 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// destroy non-supported roofs
|
||||||
if ( pair.second < 1 )
|
if ( pair.second < 1 )
|
||||||
{
|
{
|
||||||
if ( DamageRoof( pair.first, 255 ) )
|
if ( DamageRoof( pair.first, 255 ) )
|
||||||
@@ -6227,21 +6190,21 @@ void HandleRoofDestruction( INT32 sGridNo, INT16 sDamage )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// for now, determine the best armour for each remaining network, and collapse it if there is no armou - and thus no wall connection - left
|
|
||||||
gridnoarmourvector roofnetwork = (*roofnetworkit).second;
|
|
||||||
|
|
||||||
UINT8 bestarmour = 0;
|
|
||||||
for ( gridnoarmourvector::iterator it = roofnetwork.begin( ); it != roofnetwork.end( ); ++it )
|
|
||||||
bestarmour = max( bestarmour, (*it).second );
|
|
||||||
|
|
||||||
// if a network has no wall connection at all, collapse the entire thing
|
|
||||||
if ( bestarmour < 1 )
|
|
||||||
{
|
{
|
||||||
|
// for now, determine the best armour for each remaining network, and collapse it if there is no armour - and thus no wall connection - left
|
||||||
|
bestarmour = 0;
|
||||||
for ( gridnoarmourvector::iterator it = roofnetwork.begin( ); it != roofnetwork.end( ); ++it )
|
for ( gridnoarmourvector::iterator it = roofnetwork.begin( ); it != roofnetwork.end( ); ++it )
|
||||||
|
bestarmour = max( bestarmour, (*it).second );
|
||||||
|
|
||||||
|
// if a network has no wall connection at all, collapse the entire thing
|
||||||
|
if ( bestarmour < 1 )
|
||||||
{
|
{
|
||||||
if ( DamageRoof( (*it).first, 255 ) )
|
for ( gridnoarmourvector::iterator it = roofnetwork.begin( ); it != roofnetwork.end( ); ++it )
|
||||||
(*it).second = 0;
|
{
|
||||||
|
if ( DamageRoof( (*it).first, 255 ) )
|
||||||
|
(*it).second = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user