#include #include "DEBUG.H" #include "worlddef.h" #include "worldman.h" #include "Structure Wrap.h" #include "Isometric Utils.h" #include "worldman.h" #include "Overhead.h" #include "renderworld.h" #include "strategicmap.h" #include "Rotting Corpses.h" #include "WorldDat.h" // added by Flugente extern BOOLEAN DoesSAMExistHere( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, INT32 sGridNo ); //----------------legion by Jazz BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo, INT8 direction2, BOOLEAN fIntactWindowsAlso ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALLNWINDOW ); if ( pStructure ) { // anv: additional tile properties hook if(gGameExternalOptions.fAdditionalTileProperties) { LEVELNODE *pNode = FindLevelNodeBasedOnStructure( sGridNo, pStructure ); if(pNode != NULL) { if( gTileDatabase[ pNode->usIndex ].uiAdditionalFlags & ADDITIONAL_TILE_FLAG_BLOCKED_WINDOW ) // special tag disables jumping through specific windows (e.g. barred windows in Tixa) return( FALSE ); } } if ( ( direction2 == SOUTH || direction2 == NORTH ) && (pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT || pStructure->ubWallOrientation == INSIDE_TOP_LEFT ) && pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) ) { if ( fIntactWindowsAlso || ( pStructure->fFlags & STRUCTURE_OPEN ) ) return( TRUE ); } if ( ( direction2 == EAST || direction2 == WEST ) && ( pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT || pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ) && pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) ) { if ( fIntactWindowsAlso || ( pStructure->fFlags & STRUCTURE_OPEN ) ) return( TRUE ); } } return( FALSE ); } BOOLEAN IsOknoFencePresentAtGridno( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALLNWINDOW ); if ( pStructure ) { if ( pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) && ( pStructure->fFlags & STRUCTURE_OPEN ) ) { return( TRUE ); } } /* STRUCTURE * pStructure; STRUCTURE * pStructure2; pStructure = FindStructure( sGridNo, STRUCTURE_WALLNWINDOW ); if ( pStructure ) { // pStructure2 = FindStructure( sGridNo, STRUCTURE_WALL ); // if ( !pStructure2 ) // { if ( pStructure->fFlags & STRUCTURE_WALLNWINDOW && !(pStructure->fFlags & STRUCTURE_SPECIAL) && ( pStructure->fFlags & STRUCTURE_OPEN )) { return( TRUE ); } // } } */ return( FALSE ); } BOOLEAN IsLegionWallPresentAtGridno( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_FENCE ); if ( pStructure ) { if ( pStructure->fFlags & STRUCTURE_FENCE && pStructure->fFlags & STRUCTURE_SPECIAL && pStructure->fFlags & STRUCTURE_WALL ) { return( TRUE ); } } return( FALSE ); } //------------------------------------------------------------------------------------- BOOLEAN IsFencePresentAtGridNo( INT32 sGridNo ) { if ( FindStructure( sGridNo, STRUCTURE_ANYFENCE ) != NULL ) { return( TRUE ); } return( FALSE ); } BOOLEAN IsRoofPresentAtGridNo( INT32 sGridNo ) { if ( FindStructure( sGridNo, STRUCTURE_ROOF ) != NULL ) { return( TRUE ); } return( FALSE ); } BOOLEAN IsJumpableFencePresentAtGridNo( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_OBSTACLE ); if ( pStructure ) { if ( pStructure->fFlags & STRUCTURE_FENCE && !(pStructure->fFlags & STRUCTURE_SPECIAL) ) { return( TRUE ); } if ( pStructure->pDBStructureRef->pDBStructure->ubArmour == MATERIAL_SANDBAG && StructureHeight( pStructure ) <= 2 ) { return( TRUE ); } } return( FALSE ); } BOOLEAN IsDoorPresentAtGridNo( INT32 sGridNo ) { if ( FindStructure( sGridNo, STRUCTURE_ANYDOOR ) != NULL ) { return( TRUE ); } return( FALSE ); } BOOLEAN IsTreePresentAtGridNo( INT32 sGridNo ) { if ( FindStructure( sGridNo, STRUCTURE_TREE ) != NULL ) { return( TRUE ); } return( FALSE ); } LEVELNODE *IsWallPresentAtGridNo( INT32 sGridNo ) { LEVELNODE *pNode = NULL; STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF ); if ( pStructure != NULL ) { pNode = FindLevelNodeBasedOnStructure( sGridNo, pStructure ); } return( pNode ); } LEVELNODE *GetWallLevelNodeOfSameOrientationAtGridNo( INT32 sGridNo, INT8 ubOrientation ) { LEVELNODE *pNode = NULL; STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF ); while ( pStructure != NULL ) { // Check orientation if ( pStructure->ubWallOrientation == ubOrientation ) { pNode = FindLevelNodeBasedOnStructure( sGridNo, pStructure ); return( pNode ); } pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF ); } return( NULL ); } LEVELNODE *GetWallLevelNodeAndStructOfSameOrientationAtGridNo( INT32 sGridNo, INT8 ubOrientation, STRUCTURE **ppStructure ) { LEVELNODE *pNode = NULL; STRUCTURE * pStructure, * pBaseStructure; (*ppStructure) = NULL; pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF ); while ( pStructure != NULL ) { // Check orientation if ( pStructure->ubWallOrientation == ubOrientation ) { pBaseStructure = FindBaseStructure( pStructure ); if (pBaseStructure) { pNode = FindLevelNodeBasedOnStructure( pBaseStructure->sGridNo, pBaseStructure ); (*ppStructure) = pBaseStructure; return( pNode ); } } pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF ); } return( NULL ); } BOOLEAN IsDoorVisibleAtGridNo( INT32 sGridNo ) { STRUCTURE * pStructure; INT32 sNewGridNo; pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); if ( pStructure != NULL ) { // Check around based on orientation switch( pStructure->ubWallOrientation ) { case INSIDE_TOP_LEFT: case OUTSIDE_TOP_LEFT: // Here, check north direction sNewGridNo = NewGridNo( sGridNo, DirectionInc( NORTH ) ); if ( IsRoofVisible2( sNewGridNo ) ) { // OK, now check south, if true, she's not visible sNewGridNo = NewGridNo( sGridNo, DirectionInc( SOUTH ) ); if ( IsRoofVisible2( sNewGridNo ) ) { return( FALSE ); } } break; case INSIDE_TOP_RIGHT: case OUTSIDE_TOP_RIGHT: // Here, check west direction sNewGridNo = NewGridNo( sGridNo, DirectionInc( WEST ) ); if ( IsRoofVisible2( sNewGridNo ) ) { // OK, now check south, if true, she's not visible sNewGridNo = NewGridNo( sGridNo, DirectionInc( EAST ) ); if ( IsRoofVisible2( sNewGridNo ) ) { return( FALSE ); } } break; } } // Return true here, even if she does not exist return( TRUE ); } BOOLEAN DoesGridNoContainHiddenStruct( INT32 sGridNo, BOOLEAN *pfVisible ) { // ATE: These are ignored now - always return false //STRUCTURE *pStructure; //pStructure = FindStructure( sGridNo, STRUCTURE_HIDDEN ); //if ( pStructure != NULL ) //{ // if ( !(gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) ) // { // *pfVisible = FALSE; // } // else // { // *pfVisible = TRUE; // }// // // return( TRUE ); //} return( FALSE ); } BOOLEAN IsHiddenStructureVisible( INT32 sGridNo, UINT16 usIndex ) { // Check if it's a hidden struct and we have not revealed anything! if ( gTileDatabase[ usIndex ].uiFlags & HIDDEN_TILE ) { if ( !(gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) ) { // Return false return( FALSE ); } } return( TRUE ); } BOOLEAN WallExistsOfTopLeftOrientation( INT32 sGridNo ) { // CJC: changing to search only for normal walls, July 16, 1998 STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALL ); while ( pStructure != NULL ) { // Check orientation if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) { return( TRUE ); } pStructure = FindNextStructure( pStructure, STRUCTURE_WALL ); } return( FALSE ); } BOOLEAN WallExistsOfTopRightOrientation( INT32 sGridNo ) { // CJC: changing to search only for normal walls, July 16, 1998 STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALL ); while ( pStructure != NULL ) { // Check orientation if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) { return( TRUE ); } pStructure = FindNextStructure( pStructure, STRUCTURE_WALL ); } return( FALSE ); } BOOLEAN WallOrClosedDoorExistsOfTopLeftOrientation( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF ); while ( pStructure != NULL ) { // skip it if it's an open door if ( ! ( ( pStructure->fFlags & STRUCTURE_ANYDOOR ) && ( pStructure->fFlags & STRUCTURE_OPEN ) ) ) { // Check orientation if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) { return( TRUE ); } } pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF ); } return( FALSE ); } BOOLEAN WallOrClosedDoorExistsOfTopRightOrientation( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF ); while ( pStructure != NULL ) { // skip it if it's an open door if ( ! ( ( pStructure->fFlags & STRUCTURE_ANYDOOR ) && ( pStructure->fFlags & STRUCTURE_OPEN ) ) ) { // Check orientation if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) { return( TRUE ); } } pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF ); } return( FALSE ); } BOOLEAN OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); while ( pStructure != NULL && (pStructure->fFlags & STRUCTURE_OPEN) ) { // Check orientation if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT ) { if ( (pStructure->fFlags & STRUCTURE_DOOR) || (pStructure->fFlags & STRUCTURE_DDOOR_RIGHT) ) { return( TRUE ); } } pStructure = FindNextStructure( pStructure, STRUCTURE_ANYDOOR ); } return( FALSE ); } BOOLEAN OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR ); while ( pStructure != NULL && (pStructure->fFlags & STRUCTURE_OPEN) ) { // Check orientation if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT ) { if ( (pStructure->fFlags & STRUCTURE_DOOR) || (pStructure->fFlags & STRUCTURE_DDOOR_LEFT) ) { return( TRUE ); } } pStructure = FindNextStructure( pStructure, STRUCTURE_ANYDOOR ); } return( FALSE ); } STRUCTURE * FindCuttableWireFenceAtGridNo( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WIREFENCE ); if (pStructure != NULL && pStructure->ubWallOrientation != NO_ORIENTATION && !(pStructure->fFlags & STRUCTURE_OPEN) ) { return( pStructure ); } return( NULL ); } BOOLEAN CutWireFence( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindCuttableWireFenceAtGridNo( sGridNo ); if (pStructure) { pStructure = SwapStructureForPartnerAndStoreChangeInMap( sGridNo, pStructure ); if (pStructure) { RecompileLocalMovementCosts( sGridNo ); SetRenderFlags( RENDER_FLAG_FULL ); return( TRUE ); } } return( FALSE ); } BOOLEAN IsCuttableWireFenceAtGridNo( INT32 sGridNo ) { return( FindCuttableWireFenceAtGridNo( sGridNo ) != NULL ); } BOOLEAN IsRepairableStructAtGridNo( INT32 sGridNo, UINT16 * pubID ) { UINT16 ubMerc; // OK, first look for a vehicle.... ubMerc = WhoIsThere2( sGridNo, 0 ); if ( pubID != NULL ) { (*pubID) = ubMerc; } if ( ubMerc != NOBODY ) { if (MercPtrs[ubMerc]->flags.uiStatusFlags & SOLDIER_ROBOT) { return( 1 ); } else if ( MercPtrs[ ubMerc ]->flags.uiStatusFlags & SOLDIER_VEHICLE ) { return( 2 ); } } // Then for over a robot.... // then for SAM site.... if ( DoesSAMExistHere( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sGridNo ) ) { return( 3 ); } return( FALSE ); } BOOLEAN IsRefuelableStructAtGridNo( INT32 sGridNo, UINT16 * pubID ) { UINT16 ubMerc; // OK, first look for a vehicle.... ubMerc = WhoIsThere2( sGridNo, 0 ); if ( pubID != NULL ) { (*pubID) = ubMerc; } if ( ubMerc != NOBODY ) { if ( MercPtrs[ ubMerc ]->flags.uiStatusFlags & SOLDIER_VEHICLE ) { return( TRUE ); } } return( FALSE ); } // Flugente: determine wether a fortification can be built on this position BOOLEAN IsFortificationPossibleAtGridNo( INT32 sGridNo ) { INT8 bOverTerrainType = GetTerrainType( sGridNo ); if( bOverTerrainType == MED_WATER || bOverTerrainType == DEEP_WATER || bOverTerrainType == LOW_WATER ) return FALSE; STRUCTURE * pStructure = NULL; pStructure = FindStructure( sGridNo, (STRUCTURE_OBSTACLE|STRUCTURE_PERSON) ); return( pStructure == NULL ); } UINT16 InteractiveActionPossibleAtGridNo( INT32 sGridNo, UINT8 usLevel, UINT16& arusStructIndex ) { arusStructIndex = 0; if ( TileIsOutOfBounds( sGridNo ) ) return INTERACTIVE_STRUCTURE_NO_ACTION; INT32 tmpgridno = 0; UINT16 structurenumber = 0; INT32 structuregridno = NOWHERE; UINT32 uiTileType = 0; bool properdatafound( false ); STRUCTURE* pStruct = FindStructure( sGridNo, ( STRUCTURE_GENERIC ) ); // Wall decorations are on the gridno of the wall. This can be problematic if this gridno is 'behind' the wall, because then we might not find a path. // Thus we need to check for decorations on these walls if ( !pStruct ) { tmpgridno = NewGridNo( sGridNo, DirectionInc( NORTH ) ); pStruct = GetStructForLevelNodeOfTypeRange( tmpgridno, FIRSTDECORATIONS, FOURTHDECORATIONS ); // if struct is found but has wrong orientation, ignore it if ( pStruct && pStruct->ubWallOrientation != OUTSIDE_TOP_LEFT && pStruct->ubWallOrientation != INSIDE_TOP_LEFT ) pStruct = NULL; } if ( !pStruct ) { tmpgridno = NewGridNo( sGridNo, DirectionInc( WEST ) ); pStruct = GetStructForLevelNodeOfTypeRange( tmpgridno, FIRSTDECORATIONS, FOURTHDECORATIONS ); // if struct is found but has wrong orientation, ignore it if ( pStruct && pStruct->ubWallOrientation != OUTSIDE_TOP_RIGHT && pStruct->ubWallOrientation != INSIDE_TOP_RIGHT ) pStruct = NULL; } if ( pStruct ) { // if this is a multi-tile structure, be sure to use the base gridno if ( !( pStruct->fFlags & STRUCTURE_BASE_TILE ) ) { pStruct = FindBaseStructure( pStruct ); if ( !pStruct ) return INTERACTIVE_STRUCTURE_NO_ACTION; } structuregridno = pStruct->sGridNo; structurenumber = pStruct->pDBStructureRef->pDBStructure->usStructureNumber; LEVELNODE* pNode = FindLevelNodeBasedOnStructure( pStruct->sGridNo, pStruct ); if ( pNode && GetTileType( pNode->usIndex, &uiTileType ) ) { properdatafound = true; } } // With Decals we don't have structuredata for the node. Thus we have to work around that by getting the data from the TileElem if ( !properdatafound ) { tmpgridno = NewGridNo( sGridNo, DirectionInc( NORTH ) ); if ( GetTypeRegionIndexForLevelNodeOfTypeRange( tmpgridno, FIRSTWALLDECAL, FOURTHWALLDECAL, uiTileType, structurenumber ) || GetTypeRegionIndexForLevelNodeOfTypeRange( tmpgridno, FIFTHWALLDECAL, EIGTHWALLDECAL, uiTileType, structurenumber ) ) { properdatafound = true; } } if ( !properdatafound ) { tmpgridno = NewGridNo( sGridNo, DirectionInc( WEST ) ); if ( GetTypeRegionIndexForLevelNodeOfTypeRange( tmpgridno, FIRSTWALLDECAL, FOURTHWALLDECAL, uiTileType, structurenumber ) || GetTypeRegionIndexForLevelNodeOfTypeRange( tmpgridno, FIFTHWALLDECAL, EIGTHWALLDECAL, uiTileType, structurenumber ) ) { properdatafound = true; } } if ( properdatafound ) { // we loop over each action and determine whether it fits // multiple actions can fit, we chose whatever fits best // So, for example, we can set computers everywhere to be hackable with a generic result, and then define more precise results on specific computers // Other example: With just oen entry, with neither sector nor location set, we can make all water taps drinkable BOOLEAN foundmatch_precise = FALSE; BOOLEAN foundmatch_sector = FALSE; BOOLEAN foundmatch_any = FALSE; UINT8 sector = SECTOR( gWorldSectorX, gWorldSectorY ); int foundindex = 0; if ( gTilesets[giCurrentTilesetID].TileSurfaceFilenames[uiTileType][0] ) { for ( int i = 0; i < gMaxInteractiveStructureRead; ++i ) { if ( !_strnicmp( gTilesets[giCurrentTilesetID].TileSurfaceFilenames[uiTileType], gInteractiveStructure[i].szTileSetName, 11 ) ) { std::vector tmpvec = gInteractiveStructure[i].tileindexvector; std::vector::iterator it = std::find( tmpvec.begin( ), tmpvec.end( ), structurenumber ); if ( it != tmpvec.end( ) ) { if ( gInteractiveStructure[i].sector == sector && gInteractiveStructure[i].sectorlevel == gbWorldSectorZ ) { foundmatch_sector = TRUE; foundindex = i; if ( gInteractiveStructure[i].sLevel == usLevel || gInteractiveStructure[i].sLevel == -1 ) { std::vector tmpgridnovec = gInteractiveStructure[i].gridnovector; std::vector::iterator it_gridno = std::find( tmpgridnovec.begin( ), tmpgridnovec.end( ), structuregridno ); if ( it_gridno != tmpgridnovec.end( ) ) { foundmatch_precise = TRUE; break; } } } // some actions cen be defined everywhere else if ( !foundmatch_sector && gInteractiveStructure[i].sector == -1 && gInteractiveStructure[i].sectorlevel == -1 ) { foundmatch_any = TRUE; foundindex = i; } } } } } // otherwise, check first tileset (GENERIC 1) else if ( gTilesets[0].TileSurfaceFilenames[uiTileType][0] ) { for ( int i = 0; i < gMaxInteractiveStructureRead; ++i ) { if ( !_strnicmp( gTilesets[0].TileSurfaceFilenames[uiTileType], gInteractiveStructure[i].szTileSetName, 11 ) ) { std::vector tmpvec = gInteractiveStructure[i].tileindexvector; std::vector::iterator it = std::find( tmpvec.begin( ), tmpvec.end( ), structurenumber ); if ( it != tmpvec.end() ) { if ( gInteractiveStructure[i].sector == sector && gInteractiveStructure[i].sectorlevel == gbWorldSectorZ ) { foundmatch_sector = TRUE; foundindex = i; if ( gInteractiveStructure[i].sLevel == usLevel || gInteractiveStructure[i].sLevel == -1 ) { std::vector tmpgridnovec = gInteractiveStructure[i].gridnovector; std::vector::iterator it_gridno = std::find( tmpgridnovec.begin( ), tmpgridnovec.end( ), structuregridno ); if ( it_gridno != tmpgridnovec.end() ) { foundmatch_precise = TRUE; break; } } } else if ( !foundmatch_sector && gInteractiveStructure[i].sector == -1 && gInteractiveStructure[i].sectorlevel == -1 ) { foundmatch_any = TRUE; foundindex = i; } } } } } if ( foundmatch_any || foundmatch_sector || foundmatch_precise ) { arusStructIndex = foundindex; return gInteractiveStructure[foundindex].sActionType; } } return INTERACTIVE_STRUCTURE_NO_ACTION; } BOOLEAN IsCutWireFenceAtGridNo( INT32 sGridNo ) { STRUCTURE * pStructure; pStructure = FindStructure( sGridNo, STRUCTURE_WIREFENCE ); if (pStructure != NULL && (pStructure->ubWallOrientation != NO_ORIENTATION) && (pStructure->fFlags & STRUCTURE_OPEN) ) { return( TRUE ); } return( FALSE ); } INT32 FindDoorAtGridNoOrAdjacent( INT32 sGridNo ) { STRUCTURE * pStructure; STRUCTURE * pBaseStructure; INT32 sTestGridNo; sTestGridNo = sGridNo; pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR ); if (pStructure) { pBaseStructure = FindBaseStructure( pStructure ); return( pBaseStructure->sGridNo ); } sTestGridNo = sGridNo + DirectionInc( NORTH ); pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR ); if (pStructure) { pBaseStructure = FindBaseStructure( pStructure ); return( pBaseStructure->sGridNo ); } sTestGridNo = sGridNo + DirectionInc( WEST ); pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR ); if (pStructure) { pBaseStructure = FindBaseStructure( pStructure ); return( pBaseStructure->sGridNo ); } return( NOWHERE ); } BOOLEAN IsCorpseAtGridNo( INT32 sGridNo, UINT8 ubLevel ) { if ( GetCorpseAtGridNo( sGridNo , ubLevel ) != NULL ) { return( TRUE ); } else { return( FALSE ); } } BOOLEAN SetOpenableStructureToClosed( INT32 sGridNo, UINT8 ubLevel ) { STRUCTURE * pStructure; STRUCTURE * pNewStructure; pStructure = FindStructure( sGridNo, STRUCTURE_OPENABLE ); if ( !pStructure ) { return( FALSE ); } if ( pStructure->fFlags & STRUCTURE_OPEN ) { pNewStructure = SwapStructureForPartner( sGridNo, pStructure ); if ( pNewStructure != NULL) { RecompileLocalMovementCosts( sGridNo ); SetRenderFlags( RENDER_FLAG_FULL ); } } // else leave it as is! return( TRUE ); }