mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
- Fix BigMaps cliff-prone problem. Details: - Bug which prevent merc to go prone and crawl in big maps with cliffs was reported by Buggler who already find source of problem which lies in DB_STRUCTURE_TILE struct variable sPosRelToBase. This variable contains relative position to base tile which and cannot simply be change to INT32 as data from JSD files are loaded into it. However reason for problem is because sPosRelToBase is not updated for quite bunch of structures when map size is changed so add macro which in real time perform conversion and update sPosRelToBase value. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6740 3b4a5df2-a311-0410-b5c6-a8a6f20db521
365 lines
8.8 KiB
C++
365 lines
8.8 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "TileEngine All.h"
|
|
#else
|
|
#include "math.h"
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
|
|
#include "Render Fun.h"
|
|
#include "worlddef.h"
|
|
#include "input.h"
|
|
#include "sysutil.h"
|
|
#include "debug.h"
|
|
#include "worldman.h"
|
|
#include "jascreens.h"
|
|
#include "Isometric Utils.h"
|
|
#include "renderworld.h"
|
|
#include "fov.h"
|
|
#include "Fog Of War.h"
|
|
#include "environment.h"
|
|
#include "dialogue control.h"
|
|
#include "Random.h"
|
|
#include "gamesettings.h"
|
|
#endif
|
|
|
|
// Room Information
|
|
//UINT8 gubWorldRoomInfo[ WORLD_MAX ];
|
|
//DBrot: More Rooms
|
|
//UINT8* gubWorldRoomInfo = NULL;
|
|
UINT16* gusWorldRoomInfo = NULL;
|
|
UINT8 gubWorldRoomHidden[ MAX_ROOMS ];
|
|
|
|
|
|
BOOLEAN InitRoomDatabase( )
|
|
{
|
|
//memset( gubWorldRoomInfo, NO_ROOM, sizeof( gubWorldRoomInfo ) );
|
|
memset( gubWorldRoomHidden, TRUE, sizeof( gubWorldRoomHidden ) );
|
|
return( TRUE );
|
|
}
|
|
|
|
void ShutdownRoomDatabase( )
|
|
{
|
|
|
|
}
|
|
//DBrot: More Rooms
|
|
void SetTileRoomNum( INT32 sGridNo, UINT16 usRoomNum )
|
|
{
|
|
// Add to global room list
|
|
gusWorldRoomInfo[ sGridNo ] = usRoomNum;
|
|
}
|
|
//DBrot: More Rooms
|
|
void SetTileRangeRoomNum( SGPRect *pSelectRegion, UINT8 usRoomNum )
|
|
{
|
|
INT32 cnt1, cnt2;
|
|
|
|
for ( cnt1 = pSelectRegion->iTop; cnt1 <= pSelectRegion->iBottom; cnt1++ )
|
|
{
|
|
for ( cnt2 = pSelectRegion->iLeft; cnt2 <= pSelectRegion->iRight; cnt2++ )
|
|
{
|
|
gusWorldRoomInfo[ MAPROWCOLTOPOS( cnt1, cnt2 ) ] = usRoomNum;
|
|
}
|
|
}
|
|
|
|
}
|
|
//DBrot: More Rooms
|
|
BOOLEAN InARoom( INT32 sGridNo, UINT16 *pusRoomNo )
|
|
{
|
|
// WANNE: Bugzilla #360: Crash when moving via helicopter from museum sector
|
|
if ( sGridNo >= 0 && gusWorldRoomInfo[ sGridNo ] != NO_ROOM )
|
|
{
|
|
if ( pusRoomNo )
|
|
{
|
|
*pusRoomNo = gusWorldRoomInfo[ sGridNo ];
|
|
}
|
|
return( TRUE );
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
//DBrot: More Rooms
|
|
BOOLEAN InAHiddenRoom( INT32 sGridNo, UINT16 *pusRoomNo )
|
|
{
|
|
if ( sGridNo >= 0 && gusWorldRoomInfo[ sGridNo ] != NO_ROOM )
|
|
{
|
|
if ( (gubWorldRoomHidden[ gusWorldRoomInfo[ sGridNo ] ] ) )
|
|
{
|
|
*pusRoomNo = gusWorldRoomInfo[ sGridNo ];
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
// @@ATECLIP TO WORLD!
|
|
void SetRecalculateWireFrameFlagRadius(INT16 sX, INT16 sY, INT16 sRadius)
|
|
{
|
|
INT16 sCountX, sCountY;
|
|
UINT32 uiTile;
|
|
|
|
for(sCountY=sY-sRadius; sCountY < (sY+sRadius+2); sCountY++)
|
|
{
|
|
for(sCountX=sX-sRadius; sCountX < (sX+sRadius+2); sCountX++)
|
|
{
|
|
uiTile=MAPROWCOLTOPOS(sCountY, sCountX);
|
|
|
|
gpWorldLevelData[uiTile].uiFlags |= MAPELEMENT_RECALCULATE_WIREFRAMES;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SetGridNoRevealedFlag( INT32 sGridNo )
|
|
{
|
|
// UINT32 cnt;
|
|
// ITEM_POOL *pItemPool;
|
|
// INT16 sX, sY;
|
|
LEVELNODE *pNode = NULL;
|
|
STRUCTURE *pStructure, *pBase;
|
|
|
|
// Set hidden flag, for any roofs
|
|
SetRoofIndexFlagsFromTypeRange( sGridNo, FIRSTROOF, FOURTHROOF, LEVELNODE_HIDDEN );
|
|
|
|
// ATE: Do this only if we are in a room...
|
|
if ( gusWorldRoomInfo[ sGridNo ] != NO_ROOM )
|
|
{
|
|
SetStructAframeFlags( sGridNo, LEVELNODE_HIDDEN );
|
|
// Find gridno one east as well...
|
|
|
|
if ( ( sGridNo + WORLD_COLS ) < MAX_MAP_POS )
|
|
{
|
|
SetStructAframeFlags( sGridNo + WORLD_COLS, LEVELNODE_HIDDEN );
|
|
}
|
|
|
|
if ( ( sGridNo + 1 ) < MAX_MAP_POS )
|
|
{
|
|
SetStructAframeFlags( sGridNo + 1, LEVELNODE_HIDDEN );
|
|
}
|
|
}
|
|
|
|
// Set gridno as revealed
|
|
gpWorldLevelData[ sGridNo ].uiFlags |= MAPELEMENT_REVEALED;
|
|
if( gfCaves )
|
|
{
|
|
RemoveFogFromGridNo( sGridNo );
|
|
}
|
|
|
|
// ATE: If there are any structs here, we can render them with the obscured flag!
|
|
// Look for anything but walls pn this gridno!
|
|
pStructure = gpWorldLevelData[ sGridNo ].pStructureHead;
|
|
|
|
while ( pStructure != NULL )
|
|
{
|
|
if ( pStructure->sCubeOffset == STRUCTURE_ON_GROUND || ( pStructure->fFlags & STRUCTURE_SLANTED_ROOF ) )
|
|
{
|
|
if ( ( (pStructure->fFlags & STRUCTURE_OBSTACLE ) && !( pStructure->fFlags & ( STRUCTURE_PERSON | STRUCTURE_CORPSE ) ) ) || ( pStructure->fFlags & STRUCTURE_SLANTED_ROOF ) )
|
|
{
|
|
pBase = FindBaseStructure( pStructure );
|
|
//Ja25: DEF: 10/12/99 Added because ...
|
|
if( pBase == NULL )
|
|
{
|
|
pStructure = pStructure->pNext;
|
|
Assert( 0 );
|
|
continue;
|
|
}
|
|
|
|
// Get LEVELNODE for struct and remove!
|
|
pNode = FindLevelNodeBasedOnStructure( pBase->sGridNo, pBase );
|
|
|
|
if( pNode )
|
|
pNode->uiFlags |= LEVELNODE_SHOW_THROUGH;
|
|
|
|
if ( pStructure->fFlags & STRUCTURE_SLANTED_ROOF )
|
|
{
|
|
AddSlantRoofFOVSlot( pBase->sGridNo );
|
|
|
|
// Set hidden...
|
|
pNode->uiFlags |= LEVELNODE_HIDDEN;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
pStructure = pStructure->pNext;
|
|
}
|
|
|
|
gubWorldRoomHidden[ gusWorldRoomInfo[ sGridNo ] ] = FALSE;
|
|
|
|
}
|
|
|
|
|
|
void ExamineGridNoForSlantRoofExtraGraphic( INT32 sCheckGridNo )
|
|
{
|
|
LEVELNODE *pNode = NULL;
|
|
STRUCTURE *pStructure, *pBase;
|
|
UINT8 ubLoop;
|
|
DB_STRUCTURE_TILE ** ppTile;
|
|
INT32 sGridNo;
|
|
UINT16 usIndex;
|
|
BOOLEAN fChanged = FALSE;
|
|
|
|
// CHECK FOR A SLANTED ROOF HERE....
|
|
pStructure = FindStructure( sCheckGridNo, STRUCTURE_SLANTED_ROOF );
|
|
|
|
if ( pStructure != NULL )
|
|
{
|
|
// We have a slanted roof here ... find base and remove...
|
|
pBase = FindBaseStructure( pStructure );
|
|
|
|
// Get LEVELNODE for struct and remove!
|
|
pNode = FindLevelNodeBasedOnStructure( pBase->sGridNo, pBase );
|
|
|
|
// Loop through each gridno and see if revealed....
|
|
for ( ubLoop = 0; ubLoop < pBase->pDBStructureRef->pDBStructure->ubNumberOfTiles; ubLoop++ )
|
|
{
|
|
ppTile = pBase->pDBStructureRef->ppTile;
|
|
#if 0//dnl ch83 080114
|
|
sGridNo = pBase->sGridNo + ppTile[ ubLoop ]->sPosRelToBase;
|
|
#else
|
|
sGridNo = AddPosRelToBase(pBase->sGridNo, ppTile[ubLoop]);
|
|
#endif
|
|
if (sGridNo < 0 || sGridNo > WORLD_MAX)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Given gridno,
|
|
// IF NOT REVEALED AND HIDDEN....
|
|
if ( !( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && pNode->uiFlags & LEVELNODE_HIDDEN )
|
|
{
|
|
// Add graphic if one does not already exist....
|
|
if ( !TypeExistsInRoofLayer( sGridNo, SLANTROOFCEILING, &usIndex ) )
|
|
{
|
|
// Add
|
|
AddRoofToHead( sGridNo, SLANTROOFCEILING1 );
|
|
fChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
// Revealed?
|
|
if ( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED )
|
|
{
|
|
///Remove any slant roof items if they exist
|
|
if ( TypeExistsInRoofLayer( sGridNo, SLANTROOFCEILING, &usIndex ) )
|
|
{
|
|
RemoveRoof( sGridNo, usIndex );
|
|
fChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if ( fChanged )
|
|
{
|
|
// DIRTY THE WORLD!
|
|
InvalidateWorldRedundency();
|
|
SetRenderFlags(RENDER_FLAG_FULL );
|
|
}
|
|
|
|
}
|
|
|
|
//DBrot: More Rooms
|
|
void RemoveRoomRoof( INT32 sGridNo, UINT16 usRoomNum, SOLDIERTYPE *pSoldier )
|
|
{
|
|
INT32 cnt;
|
|
ITEM_POOL *pItemPool;
|
|
INT16 sX, sY;
|
|
BOOLEAN fSaidItemSeenQuote = FALSE;
|
|
|
|
// STRUCTURE *pStructure;//, *pBase;
|
|
|
|
// LOOP THORUGH WORLD AND CHECK ROOM INFO
|
|
for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
|
|
{
|
|
if ( gusWorldRoomInfo[ cnt ] == usRoomNum )
|
|
{
|
|
|
|
SetGridNoRevealedFlag( cnt );//dnl ch56 141009
|
|
|
|
RemoveRoofIndexFlagsFromTypeRange( cnt, FIRSTROOF, SECONDSLANTROOF, LEVELNODE_REVEAL );
|
|
|
|
// Reveal any items if here!
|
|
if ( GetItemPoolFromGround( cnt, &pItemPool ) )
|
|
{
|
|
// Set visible! ( only if invisible... )
|
|
if ( SetItemPoolVisibilityOn( pItemPool, INVISIBLE, TRUE ) )
|
|
{
|
|
if ( !fSaidItemSeenQuote )
|
|
{
|
|
fSaidItemSeenQuote = TRUE;
|
|
|
|
if ( pSoldier != NULL )
|
|
{
|
|
//ddd
|
|
//TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) );
|
|
if(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) )
|
|
TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) );
|
|
//ddd
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// OK, re-set writeframes ( in a radius )
|
|
// Get XY
|
|
ConvertGridNoToXY( cnt, &sX, &sY );
|
|
SetRecalculateWireFrameFlagRadius( sX, sY, 2 );
|
|
|
|
}
|
|
}
|
|
|
|
//for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
|
|
//{
|
|
// if ( gubWorldRoomInfo[ cnt ] == bRoomNum )
|
|
// {
|
|
// ExamineGridNoForSlantRoofExtraGraphic( (INT16)cnt );
|
|
// }
|
|
//}
|
|
|
|
// DIRTY THE WORLD!
|
|
InvalidateWorldRedundency();
|
|
SetRenderFlags(RENDER_FLAG_FULL );
|
|
|
|
|
|
CalculateWorldWireFrameTiles( FALSE );
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN AddSpecialTileRange( SGPRect *pSelectRegion )
|
|
{
|
|
INT32 cnt1, cnt2;
|
|
|
|
for ( cnt1 = pSelectRegion->iTop; cnt1 <= pSelectRegion->iBottom; cnt1++ )
|
|
{
|
|
for ( cnt2 = pSelectRegion->iLeft; cnt2 <= pSelectRegion->iRight; cnt2++ )
|
|
{
|
|
AddObjectToHead( MAPROWCOLTOPOS( cnt1, cnt2 ), SPECIALTILE_MAPEXIT );
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN RemoveSpecialTileRange( SGPRect *pSelectRegion )
|
|
{
|
|
INT32 cnt1, cnt2;
|
|
|
|
for ( cnt1 = pSelectRegion->iTop; cnt1 <= pSelectRegion->iBottom; cnt1++ )
|
|
{
|
|
for ( cnt2 = pSelectRegion->iLeft; cnt2 <= pSelectRegion->iRight; cnt2++ )
|
|
{
|
|
RemoveObject( MAPROWCOLTOPOS( cnt1, cnt2 ), SPECIALTILE_MAPEXIT );
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|