1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111 |
- #ifdef PRECOMPILEDHEADERS
- #include "TileEngine All.h"
- #else
- #include <stdio.h>
- #include <stdarg.h>
- #include <time.h>
- #include "sgp.h"
- #include "himage.h"
- #include "vsurface.h"
- #include "vsurface_private.h"
- #include "wcheck.h"
- #include "sysutil.h"
- #include "renderworld.h"
- #include "interface.h"
- #include "Sound Control.h"
- #include "worlddef.h"
- #include "Interactive Tiles.h"
- #include "interface cursors.h"
- #include "worldman.h"
- #include "structure.h"
- #include "Animation Control.h"
- #include "points.h"
- #include "overhead.h"
- #include "structure wrap.h"
- #include "tile animation.h"
- #include "tile cache.h"
- #include "handle doors.h"
- #include "Strategicmap.h"
- #include "Quests.h"
- #include "Dialogue Control.h"
- #include "Random.h"
- #include "english.h"
- #include "handle items.h"
- #include "message.h"
- #include "handle ui.h"
- #endif
- #define MAX_INTTILE_STACK 10
- typedef struct
- {
- INT16 sGridNo;
- UINT8 ubFlags;
- INT16 sTileIndex;
- INT16 sMaxScreenY;
- INT16 sHeighestScreenY;
- BOOLEAN fFound;
- LEVELNODE *pFoundNode;
- INT16 sFoundGridNo;
- UINT16 usStructureID;
- BOOLEAN fStructure;
- } CUR_INTERACTIVE_TILE;
- typedef struct
- {
- INT8 bNum;
- CUR_INTERACTIVE_TILE bTiles[ MAX_INTTILE_STACK ];
- INT8 bCur;
- } INTERACTIVE_TILE_STACK_TYPE;
-
- INTERACTIVE_TILE_STACK_TYPE gCurIntTileStack;
- BOOLEAN gfCycleIntTile = FALSE;
- CUR_INTERACTIVE_TILE gCurIntTile;
- BOOLEAN gfOverIntTile = FALSE;
- // Values to determine if we should check or not
- INT16 gsINTOldRenderCenterX = 0;
- INT16 gsINTOldRenderCenterY = 0;
- UINT16 gusINTOldMousePosX = 0;
- UINT16 gusINTOldMousePosY = 0;
- BOOLEAN RefinePointCollisionOnStruct( INT16 sGridNo, INT16 sTestX, INT16 sTestY, INT16 sSrcX, INT16 sSrcY, LEVELNODE *pNode );
- BOOLEAN CheckVideoObjectScreenCoordinateInData( HVOBJECT hSrcVObject, UINT16 usIndex, INT32 iTextX, INT32 iTestY );
- BOOLEAN RefineLogicOnStruct( INT16 sGridNo, LEVELNODE *pNode );
- BOOLEAN InitInteractiveTileManagement( )
- {
- return( TRUE );
- }
- void ShutdownInteractiveTileManagement( )
- {
- }
- BOOLEAN AddInteractiveTile( INT16 sGridNo, LEVELNODE *pLevelNode, UINT32 uiFlags, UINT16 usType )
- {
- return( TRUE );
- }
- BOOLEAN StartInteractiveObject( INT16 sGridNo, UINT16 usStructureID, SOLDIERTYPE *pSoldier, UINT8 ubDirection )
- {
- STRUCTURE * pStructure;
- // ATE: Patch fix: Don't allow if alreay in animation
- if ( pSoldier->usAnimState == OPEN_STRUCT || pSoldier->usAnimState == OPEN_STRUCT_CROUCHED ||
- pSoldier->usAnimState == BEGIN_OPENSTRUCT || pSoldier->usAnimState == BEGIN_OPENSTRUCT_CROUCHED )
- {
- return( FALSE );
- }
- pStructure = FindStructureByID( sGridNo, usStructureID );
- if (pStructure == NULL)
- {
- return( FALSE );
- }
- if (pStructure->fFlags & STRUCTURE_ANYDOOR)
- {
- // Add soldier event for opening door....
- pSoldier->ubPendingAction = MERC_OPENDOOR;
- pSoldier->uiPendingActionData1 = usStructureID;
- pSoldier->sPendingActionData2 = sGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- }
- else
- {
- // Add soldier event for opening door....
- pSoldier->ubPendingAction = MERC_OPENSTRUCT;
- pSoldier->uiPendingActionData1 = usStructureID;
- pSoldier->sPendingActionData2 = sGridNo;
- pSoldier->bPendingActionData3 = ubDirection;
- pSoldier->ubPendingActionAnimCount = 0;
- }
- return( TRUE );
- }
- BOOLEAN CalcInteractiveObjectAPs( INT16 sGridNo, STRUCTURE * pStructure, INT16 *psAPCost, INT16 *psBPCost )
- {
- if (pStructure == NULL)
- {
- return( FALSE );
- }
- if (pStructure->fFlags & STRUCTURE_ANYDOOR)
- {
- // For doors, if open, we can safely add APs for closing
- // If closed, we do not know what to do yet...
- //if ( pStructure->fFlags & STRUCTURE_OPEN )
- //{
- *psAPCost = AP_OPEN_DOOR;
- *psBPCost = AP_OPEN_DOOR;
- //}
- //else
- //{
- // *psAPCost = 0;
- // *psBPCost = 0;
- //}
- }
- else
- {
- *psAPCost = AP_OPEN_DOOR;
- *psBPCost = AP_OPEN_DOOR;
- }
- return( TRUE );
- }
- BOOLEAN InteractWithInteractiveObject( SOLDIERTYPE *pSoldier, STRUCTURE *pStructure, UINT8 ubDirection )
- {
- BOOLEAN fDoor = FALSE;
- if (pStructure == NULL)
- {
- return( FALSE );
- }
- if (pStructure->fFlags & STRUCTURE_ANYDOOR)
- {
- fDoor = TRUE;
- }
- InteractWithOpenableStruct( pSoldier, pStructure, ubDirection, fDoor );
- return( TRUE );
- }
- BOOLEAN SoldierHandleInteractiveObject( SOLDIERTYPE *pSoldier )
- {
- STRUCTURE *pStructure;
- UINT16 usStructureID;
- INT16 sGridNo;
-
- sGridNo = pSoldier->sPendingActionData2;
- usStructureID = (UINT16)pSoldier->uiPendingActionData1;
- // HANDLE SOLDIER ACTIONS
- pStructure = FindStructureByID( sGridNo, usStructureID );
- if (pStructure == NULL)
- {
- //DEBUG MSG!
- return( FALSE );
- }
-
- return( HandleOpenableStruct( pSoldier, sGridNo, pStructure ) );
- }
- void HandleStructChangeFromGridNo( SOLDIERTYPE *pSoldier, INT16 sGridNo )
- {
- STRUCTURE *pStructure, *pNewStructure;
- INT16 sAPCost = 0, sBPCost = 0;
- ITEM_POOL *pItemPool;
- BOOLEAN fDidMissingQuote = FALSE;
- pStructure = FindStructure( sGridNo, STRUCTURE_OPENABLE );
- if ( pStructure == NULL )
- {
- #ifdef JA2TESTVERSION
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"ERROR: Told to handle struct that does not exist at %d.", sGridNo );
- #endif
- return;
- }
- // Do sound...
- if ( !( pStructure->fFlags & STRUCTURE_OPEN ) )
- {
- // Play Opening sound...
- PlayJA2Sample( GetStructureOpenSound( pStructure, FALSE ), RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) );
- }
- else
- {
- // Play Opening sound...
- PlayJA2Sample( ( GetStructureOpenSound( pStructure, TRUE ) ), RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) );
- }
- // ATE: Don't handle switches!
- if ( !( pStructure->fFlags & STRUCTURE_SWITCH ) )
- {
- if ( pSoldier->bTeam == gbPlayerNum )
- {
- if ( sGridNo == BOBBYR_SHIPPING_DEST_GRIDNO && gWorldSectorX == BOBBYR_SHIPPING_DEST_SECTOR_X && gWorldSectorY == BOBBYR_SHIPPING_DEST_SECTOR_Y && gbWorldSectorZ == BOBBYR_SHIPPING_DEST_SECTOR_Z && CheckFact( FACT_PABLOS_STOLE_FROM_LATEST_SHIPMENT, 0 ) && !(CheckFact( FACT_PLAYER_FOUND_ITEMS_MISSING, 0) ) )
- {
- SayQuoteFromNearbyMercInSector( BOBBYR_SHIPPING_DEST_GRIDNO, 3, QUOTE_STUFF_MISSING_DRASSEN );
- fDidMissingQuote = TRUE;
- }
- }
- else if ( pSoldier->bTeam == CIV_TEAM )
- {
- if ( pSoldier->ubProfile != NO_PROFILE )
- {
- TriggerNPCWithGivenApproach( pSoldier->ubProfile, APPROACH_DONE_OPEN_STRUCTURE, FALSE );
- }
- }
- // LOOK for item pool here...
- if ( GetItemPool( (INT16)sGridNo, &pItemPool, pSoldier->bLevel ) )
- {
- // Update visiblity....
- if ( !( pStructure->fFlags & STRUCTURE_OPEN ) )
- {
- BOOLEAN fDoHumm = TRUE;
- BOOLEAN fDoLocators = TRUE;
- if ( pSoldier->bTeam != gbPlayerNum )
- {
- fDoHumm = FALSE;
- fDoLocators = FALSE;
- }
- // Look for ownership here....
- if ( gWorldItems[ pItemPool->iItemIndex ].o.usItem == OWNERSHIP )
- {
- fDoHumm = FALSE;
- TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_DO_BATTLE_SND, BATTLE_SOUND_NOTHING , 500 );
- }
- // If now open, set visible...
- SetItemPoolVisibilityOn( pItemPool, ANY_VISIBILITY_VALUE, fDoLocators );
- // Display quote!
- //TacticalCharacterDialogue( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ) );
- // ATE: Check now many things in pool.....
- if ( !fDidMissingQuote )
- {
- if ( pItemPool->pNext != NULL )
- {
- if ( pItemPool->pNext->pNext != NULL )
- {
- fDoHumm = FALSE;
- TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_DO_BATTLE_SND, BATTLE_SOUND_COOL1 , 500 );
- }
- }
- if ( fDoHumm )
- {
- TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_DO_BATTLE_SND, BATTLE_SOUND_HUMM , 500 );
- }
- }
- }
- else
- {
- SetItemPoolVisibilityHidden( pItemPool );
- }
- }
- else
- {
- if ( !( pStructure->fFlags & STRUCTURE_OPEN ) )
- {
- TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_DO_BATTLE_SND, BATTLE_SOUND_NOTHING , 500 );
- }
- }
- }
- // Deduct points!
- // CalcInteractiveObjectAPs( sGridNo, pStructure, &sAPCost, &sBPCost );
- // DeductPoints( pSoldier, sAPCost, sBPCost );
- pNewStructure = SwapStructureForPartner( sGridNo, pStructure );
- if ( pNewStructure != NULL)
- {
- RecompileLocalMovementCosts( sGridNo );
- SetRenderFlags( RENDER_FLAG_FULL );
- if ( pNewStructure->fFlags & STRUCTURE_SWITCH )
- {
- // just turned a switch on!
- ActivateSwitchInGridNo( pSoldier->ubID, sGridNo );
- }
- }
- }
- UINT32 GetInteractiveTileCursor( UINT32 uiOldCursor, BOOLEAN fConfirm )
- {
- LEVELNODE *pIntNode;
- STRUCTURE *pStructure;
- INT16 sGridNo;
- // OK, first see if we have an in tile...
- pIntNode = GetCurInteractiveTileGridNoAndStructure( &sGridNo, &pStructure );
- if ( pIntNode != NULL && pStructure != NULL )
- {
- if( pStructure->fFlags & STRUCTURE_ANYDOOR )
- {
- SetDoorString( sGridNo );
- if ( fConfirm )
- {
- return( OKHANDCURSOR_UICURSOR );
- }
- else
- {
- return( NORMALHANDCURSOR_UICURSOR );
- }
- }
- else
- {
- if( pStructure->fFlags & STRUCTURE_SWITCH )
- {
- wcscpy( gzIntTileLocation, gzLateLocalizedString[ 25 ] );
- gfUIIntTileLocation = TRUE;
- }
- if ( fConfirm )
- {
- return( OKHANDCURSOR_UICURSOR );
- }
- else
- {
- return( NORMALHANDCURSOR_UICURSOR );
- }
- }
- }
- return( uiOldCursor );
- }
-
- void SetActionModeDoorCursorText( )
- {
- LEVELNODE *pIntNode;
- STRUCTURE *pStructure;
- INT16 sGridNo;
- // If we are over a merc, don't
- if ( gfUIFullTargetFound )
- {
- return;
- }
- // OK, first see if we have an in tile...
- pIntNode = GetCurInteractiveTileGridNoAndStructure( &sGridNo, &pStructure );
- if ( pIntNode != NULL && pStructure != NULL )
- {
- if( pStructure->fFlags & STRUCTURE_ANYDOOR )
- {
- SetDoorString( sGridNo );
- }
- }
- }
- void GetLevelNodeScreenRect( LEVELNODE *pNode, SGPRect *pRect, INT16 sXPos, INT16 sYPos, INT16 sGridNo )
- {
- INT16 sScreenX, sScreenY;
- INT16 sOffsetX, sOffsetY;
- INT16 sTempX_S, sTempY_S;
- ETRLEObject *pTrav;
- UINT32 usHeight, usWidth;
- TILE_ELEMENT *TileElem;
-
- // Get 'TRUE' merc position
- sOffsetX = sXPos - gsRenderCenterX;
- sOffsetY = sYPos - gsRenderCenterY;
- FromCellToScreenCoordinates( sOffsetX, sOffsetY, &sTempX_S, &sTempY_S );
- if ( pNode->uiFlags & LEVELNODE_CACHEDANITILE )
- {
- pTrav = &(gpTileCache[ pNode->pAniTile->sCachedTileID ].pImagery->vo->pETRLEObject[ pNode->pAniTile->sCurrentFrame ] );
- }
- else
- {
- TileElem = &(gTileDatabase[pNode->usIndex]);
-
- //Adjust for current frames and animations....
- if ( TileElem->uiFlags & ANIMATED_TILE)
- {
- Assert( TileElem->pAnimData != NULL );
- TileElem = &gTileDatabase[TileElem->pAnimData->pusFrames[TileElem->pAnimData->bCurrentFrame]];
- }
- else if( ( pNode->uiFlags & LEVELNODE_ANIMATION ) )
- {
- if ( pNode->sCurrentFrame != -1 )
- {
- Assert( TileElem->pAnimData != NULL );
- TileElem = &gTileDatabase[TileElem->pAnimData->pusFrames[pNode->sCurrentFrame]];
- }
- }
- pTrav = &(TileElem->hTileSurface->pETRLEObject[ TileElem->usRegionIndex ] );
- }
- sScreenX = ( ( gsVIEWPORT_END_X - gsVIEWPORT_START_X ) /2 ) + (INT16)sTempX_S;
- sScreenY = ( ( gsVIEWPORT_END_Y - gsVIEWPORT_START_Y ) /2 ) + (INT16)sTempY_S;
- // Adjust for offset position on screen
- sScreenX -= gsRenderWorldOffsetX;
- sScreenY -= gsRenderWorldOffsetY;
- sScreenY -= gpWorldLevelData[ sGridNo ].sHeight;
- // Adjust based on interface level
- if ( gsInterfaceLevel > 0 )
- {
- sScreenY += ROOF_LEVEL_HEIGHT;
- }
- // Adjust for render height
- sScreenY += gsRenderHeight;
- usHeight = (UINT32)pTrav->usHeight;
- usWidth = (UINT32)pTrav->usWidth;
- // Add to start position of dest buffer
- sScreenX += ( pTrav->sOffsetX - ( WORLD_TILE_X/2 ) );
- sScreenY += ( pTrav->sOffsetY - ( WORLD_TILE_Y/2 ) );
- // Adjust y offset!
- sScreenY += ( WORLD_TILE_Y/2);
- pRect->iLeft = sScreenX;
- pRect->iTop = sScreenY;
- pRect->iBottom = sScreenY + usHeight;
- pRect->iRight = sScreenX + usWidth;
- }
- void CompileInteractiveTiles( )
- {
- }
- void LogMouseOverInteractiveTile( INT16 sGridNo )
- {
- SGPRect aRect;
- INT16 sXMapPos, sYMapPos, sScreenX, sScreenY;
- LEVELNODE *pNode;
- // OK, for now, don't allow any interactive tiles on higher interface level!
- if ( gsInterfaceLevel > 0 )
- {
- return;
- }
- // Also, don't allow for mercs who are on upper level...
- if ( gusSelectedSoldier != NOBODY && MercPtrs[ gusSelectedSoldier ]->bLevel == 1 )
- {
- return;
- }
- // Get World XY From gridno
- ConvertGridNoToCellXY( sGridNo, &sXMapPos, &sYMapPos );
- // Set mouse stuff
- sScreenX = gusMouseXPos;
- sScreenY = gusMouseYPos;
- pNode = gpWorldLevelData[ sGridNo ].pStructHead;
- while( pNode != NULL )
- {
- {
- GetLevelNodeScreenRect( pNode, &aRect, sXMapPos, sYMapPos , sGridNo );
- // Make sure we are always on guy if we are on same gridno
- if ( IsPointInScreenRect( sScreenX, sScreenY, &aRect ) )
- {
- // OK refine it!
- if ( RefinePointCollisionOnStruct( sGridNo, sScreenX, sScreenY, (INT16)aRect.iLeft, (INT16)aRect.iBottom, pNode ) )
- {
- // Do some additional checks here!
- if ( RefineLogicOnStruct( sGridNo, pNode ) )
- {
- gCurIntTile.fFound = TRUE;
- // Only if we are not currently cycling....
- if ( !gfCycleIntTile )
- {
- // Accumulate them!
- gCurIntTileStack.bTiles[ gCurIntTileStack.bNum ].pFoundNode = pNode;
- gCurIntTileStack.bTiles[ gCurIntTileStack.bNum ].sFoundGridNo = sGridNo;
- gCurIntTileStack.bNum++;
- // Determine if it's the best one
- if ( aRect.iBottom > gCurIntTile.sHeighestScreenY )
- {
- gCurIntTile.sMaxScreenY = (UINT16)aRect.iBottom;
- gCurIntTile.sHeighestScreenY = gCurIntTile.sMaxScreenY;
- // Set it!
- gCurIntTile.pFoundNode = pNode;
- gCurIntTile.sFoundGridNo = sGridNo;
- // Set stack current one...
- gCurIntTileStack.bCur = gCurIntTileStack.bNum-1;
- }
- }
- }
- }
- }
- pNode = pNode->pNext;
- }
- }
- }
- LEVELNODE *InternalGetCurInteractiveTile( BOOLEAN fRejectItemsOnTop )
- {
- LEVELNODE *pNode = NULL;
- STRUCTURE *pStructure = NULL;
- // OK, Look for our tile!
- // Check for shift down!
- if ( _KeyDown( SHIFT ) )
- {
- return( NULL );
- }
- if ( gfOverIntTile )
- {
- pNode = gpWorldLevelData[ gCurIntTile.sGridNo ].pStructHead;
- while( pNode != NULL )
- {
- if ( pNode->usIndex == gCurIntTile.sTileIndex )
- {
- if ( fRejectItemsOnTop )
- {
- // get strucuture here...
- if ( gCurIntTile.fStructure )
- {
- pStructure = FindStructureByID( gCurIntTile.sGridNo, gCurIntTile.usStructureID );
- if (pStructure != NULL)
- {
- if ( pStructure->fFlags & STRUCTURE_HASITEMONTOP )
- {
- return( NULL );
- }
- }
- else
- {
- return( NULL );
- }
- }
- }
- return( pNode );
- }
- pNode = pNode->pNext;
- }
- }
- return( NULL );
- }
- LEVELNODE *GetCurInteractiveTile( )
- {
- return( InternalGetCurInteractiveTile( TRUE ) );
- }
- LEVELNODE *GetCurInteractiveTileGridNo( INT16 *psGridNo )
- {
- LEVELNODE *pNode;
-
- pNode = GetCurInteractiveTile( );
- if ( pNode != NULL )
- {
- *psGridNo = gCurIntTile.sGridNo;
- }
- else
- {
- *psGridNo = NOWHERE;
- }
- return( pNode );
- }
- LEVELNODE *ConditionalGetCurInteractiveTileGridNoAndStructure( INT16 *psGridNo, STRUCTURE **ppStructure, BOOLEAN fRejectOnTopItems )
- {
- LEVELNODE *pNode;
- STRUCTURE *pStructure;
- *ppStructure = NULL;
-
- pNode = InternalGetCurInteractiveTile( fRejectOnTopItems );
- if ( pNode != NULL )
- {
- *psGridNo = gCurIntTile.sGridNo;
- }
- else
- {
- *psGridNo = NOWHERE;
- }
- if ( pNode != NULL )
- {
- if ( gCurIntTile.fStructure )
- {
- pStructure = FindStructureByID( gCurIntTile.sGridNo, gCurIntTile.usStructureID );
- if (pStructure == NULL)
- {
- *ppStructure = NULL;
- return( NULL );
- }
- else
- {
- *ppStructure = pStructure;
- }
- }
- }
- return( pNode );
- }
- LEVELNODE *GetCurInteractiveTileGridNoAndStructure( INT16 *psGridNo, STRUCTURE **ppStructure )
- {
- return( ConditionalGetCurInteractiveTileGridNoAndStructure( psGridNo, ppStructure, TRUE ) );
- }
- void BeginCurInteractiveTileCheck( UINT8 bCheckFlags )
- {
- gfOverIntTile = FALSE;
- // OK, release our stack, stuff could be different!
- gfCycleIntTile = FALSE;
- // Reset some highest values
- gCurIntTile.sHeighestScreenY = 0;
- gCurIntTile.fFound = FALSE;
- gCurIntTile.ubFlags = bCheckFlags;
- // Reset stack values
- gCurIntTileStack.bNum = 0;
- }
- void EndCurInteractiveTileCheck( )
- {
- CUR_INTERACTIVE_TILE *pCurIntTile;
- if ( gCurIntTile.fFound )
- {
- // Set our currently cycled guy.....
- if ( gfCycleIntTile )
- {
- // OK, we're over this cycled node
- pCurIntTile = &( gCurIntTileStack.bTiles[ gCurIntTileStack.bCur ] );
- }
- else
- {
- // OK, we're over this levelnode,
- pCurIntTile = &gCurIntTile;
- }
- gCurIntTile.sGridNo = pCurIntTile->sFoundGridNo;
- gCurIntTile.sTileIndex = pCurIntTile->pFoundNode->usIndex;
- if ( pCurIntTile->pFoundNode->pStructureData != NULL )
- {
- gCurIntTile.usStructureID = pCurIntTile->pFoundNode->pStructureData->usStructureID;
- gCurIntTile.fStructure = TRUE;
- }
- else
- {
- gCurIntTile.fStructure = FALSE;
- }
- gfOverIntTile = TRUE;
- }
- else
- {
- // If we are in cycle mode, end it
- if ( gfCycleIntTile )
- {
- gfCycleIntTile = FALSE;
- }
- }
- }
- BOOLEAN RefineLogicOnStruct( INT16 sGridNo, LEVELNODE *pNode )
- {
- TILE_ELEMENT *TileElem;
- STRUCTURE *pStructure;
-
- if ( pNode->uiFlags & LEVELNODE_CACHEDANITILE )
- {
- return ( FALSE );
- }
- TileElem = &(gTileDatabase[pNode->usIndex]);
- if ( gCurIntTile.ubFlags == INTILE_CHECK_SELECTIVE )
- {
- // See if we are on an interactable tile!
- // Try and get struct data from levelnode pointer
- pStructure = pNode->pStructureData;
- // If no data, quit
- if ( pStructure == NULL )
- {
- return( FALSE );
- }
- if ( !( pStructure->fFlags & ( STRUCTURE_OPENABLE | STRUCTURE_HASITEMONTOP ) ) )
- {
- return( FALSE );
- }
- if ( gusSelectedSoldier != NOBODY && MercPtrs[ gusSelectedSoldier ]->ubBodyType == ROBOTNOWEAPON )
- {
- return( FALSE );
- }
- // If we are a door, we need a different definition of being visible than other structs
- if ( pStructure->fFlags & STRUCTURE_ANYDOOR )
- {
- if ( !IsDoorVisibleAtGridNo( sGridNo ) )
- {
- return( FALSE );
- }
- // OK, For a OPENED door, addition requirements are: need to be in 'HAND CURSOR' mode...
- if ( pStructure->fFlags & STRUCTURE_OPEN )
- {
- //Are we in hand cursor mode?
- if ( gCurrentUIMode != HANDCURSOR_MODE && gCurrentUIMode != ACTION_MODE )
- {
- return( FALSE );
- }
- }
- // If this option is on...
- if ( !gGameSettings.fOptions[ TOPTION_SNAP_CURSOR_TO_DOOR ] )
- {
- if ( gCurrentUIMode != HANDCURSOR_MODE )
- {
- return( FALSE );
- }
- }
- }
- else
- {
- // IF we are a switch, reject in another direction...
- if ( pStructure->fFlags & STRUCTURE_SWITCH )
- {
- // Find a new gridno based on switch's orientation...
- INT16 sNewGridNo = NOWHERE;
- switch( pStructure->pDBStructureRef->pDBStructure->ubWallOrientation )
- {
- case OUTSIDE_TOP_LEFT:
- case INSIDE_TOP_LEFT:
- // Move south...
- sNewGridNo = NewGridNo( sGridNo, DirectionInc( SOUTH ) );
- break;
- case OUTSIDE_TOP_RIGHT:
- case INSIDE_TOP_RIGHT:
- // Move east...
- sNewGridNo = NewGridNo( sGridNo, DirectionInc( EAST ) );
- break;
- }
- if ( sNewGridNo != NOWHERE )
- {
- // If we are hidden by a roof, reject it!
- if ( !gfBasement && IsRoofVisible2( sNewGridNo ) && !( gTacticalStatus.uiFlags&SHOW_ALL_ITEMS ) )
- {
- return( FALSE );
- }
- }
- }
- else
- {
- // If we are hidden by a roof, reject it!
- if ( !gfBasement && IsRoofVisible( sGridNo ) && !( gTacticalStatus.uiFlags&SHOW_ALL_ITEMS ) )
- {
- return( FALSE );
- }
- }
- }
-
- // Check if it's a hidden struct and we have not revealed anything!
- if ( TileElem->uiFlags & HIDDEN_TILE )
- {
- if ( !IsHiddenStructureVisible( sGridNo, pNode->usIndex ) )
- {
- // Return false
- return( FALSE );
- }
- }
- }
- return( TRUE );
- }
- BOOLEAN RefinePointCollisionOnStruct( INT16 sGridNo, INT16 sTestX, INT16 sTestY, INT16 sSrcX, INT16 sSrcY, LEVELNODE *pNode )
- {
- TILE_ELEMENT *TileElem;
- if ( pNode->uiFlags & LEVELNODE_CACHEDANITILE )
- {
- //Check it!
- return ( CheckVideoObjectScreenCoordinateInData( gpTileCache[ pNode->pAniTile->sCachedTileID ].pImagery->vo, pNode->pAniTile->sCurrentFrame, (INT32)( sTestX - sSrcX ), (INT32)( -1 * ( sTestY - sSrcY ) ) ) );
- }
- else
- {
- TileElem = &( gTileDatabase[pNode->usIndex] );
- //Adjust for current frames and animations....
- if ( TileElem->uiFlags & ANIMATED_TILE)
- {
- Assert( TileElem->pAnimData != NULL );
- TileElem = &gTileDatabase[TileElem->pAnimData->pusFrames[TileElem->pAnimData->bCurrentFrame]];
- }
- else if( ( pNode->uiFlags & LEVELNODE_ANIMATION ) )
- {
- if ( pNode->sCurrentFrame != -1 )
- {
- Assert( TileElem->pAnimData != NULL );
- TileElem = &gTileDatabase[TileElem->pAnimData->pusFrames[pNode->sCurrentFrame]];
- }
- }
- //Check it!
- return ( CheckVideoObjectScreenCoordinateInData( TileElem->hTileSurface, TileElem->usRegionIndex, (INT32)( sTestX - sSrcX ), (INT32)( -1 * ( sTestY - sSrcY ) ) ) );
- }
- }
- // This function will check the video object at SrcX and SrcY for the lack of transparency
- // will return true if data found, else false
- BOOLEAN CheckVideoObjectScreenCoordinateInData( HVOBJECT hSrcVObject, UINT16 usIndex, INT32 iTestX, INT32 iTestY )
- {
- UINT32 uiOffset;
- UINT32 usHeight, usWidth;
- UINT8 *SrcPtr;
- UINT32 LineSkip;
- ETRLEObject *pTrav;
- BOOLEAN fDataFound = FALSE;
- INT32 iTestPos, iStartPos;
-
- // Assertions
- Assert( hSrcVObject != NULL );
- // Get Offsets from Index into structure
- pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
- usHeight = (UINT32)pTrav->usHeight;
- usWidth = (UINT32)pTrav->usWidth;
- uiOffset = pTrav->uiDataOffset;
- // Calculate test position we are looking for!
- // Calculate from 0, 0 at top left!
- iTestPos = ( ( usHeight - iTestY ) * usWidth ) + iTestX;
- iStartPos = 0;
- LineSkip = usWidth;
- SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
- __asm {
- mov esi, SrcPtr
- mov edi, iStartPos
- xor eax, eax
- xor ebx, ebx
- xor ecx, ecx
- BlitDispatch:
- mov cl, [esi]
- inc esi
- or cl, cl
- js BlitTransparent
- jz BlitDoneLine
- //BlitNonTransLoop:
- clc
- rcr cl, 1
- jnc BlitNTL2
- inc esi
-
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
- BlitNTL2:
- clc
- rcr cl, 1
- jnc BlitNTL3
- add esi, 2
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
- BlitNTL3:
- or cl, cl
- jz BlitDispatch
- xor ebx, ebx
- BlitNTL4:
- add esi, 4
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
-
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
- // Check
- cmp edi, iTestPos
- je BlitFound
- add edi, 1
- dec cl
- jnz BlitNTL4
- jmp BlitDispatch
- BlitTransparent:
- and ecx, 07fH
- // shl ecx, 1
- add edi, ecx
- jmp BlitDispatch
- BlitDoneLine:
-
- // Here check if we have passed!
- cmp edi, iTestPos
- jge BlitDone
- dec usHeight
- jz BlitDone
- // add edi, LineSkip
- jmp BlitDispatch
- BlitFound:
- mov fDataFound, 1
- BlitDone:
- }
- return(fDataFound);
- }
- BOOLEAN ShouldCheckForMouseDetections( )
- {
- BOOLEAN fOK = FALSE;
- if ( gsINTOldRenderCenterX != gsRenderCenterX || gsINTOldRenderCenterY != gsRenderCenterY ||
- gusINTOldMousePosX != gusMouseXPos || gusINTOldMousePosY != gusMouseYPos )
- {
- fOK = TRUE;
- }
- // Set old values
- gsINTOldRenderCenterX = gsRenderCenterX;
- gsINTOldRenderCenterY = gsRenderCenterY;
- gusINTOldMousePosX = gusMouseXPos;
- gusINTOldMousePosY = gusMouseYPos;
- return( fOK );
- }
- void CycleIntTileFindStack( UINT16 usMapPos )
- {
- gfCycleIntTile = TRUE;
- // Cycle around!
- gCurIntTileStack.bCur++;
- //PLot new movement
- gfPlotNewMovement = TRUE;
- if ( gCurIntTileStack.bCur == gCurIntTileStack.bNum )
- {
- gCurIntTileStack.bCur = 0;
- }
- }
|