Example #1
0
File: fov.c Project: bowlofstew/ja2
void RevealRoofsAndItems(SOLDIERTYPE *pSoldier, UINT32 itemsToo, BOOLEAN fShowLocators, UINT8 ubLevel, BOOLEAN fForce )
{
 UINT32 maincnt,markercnt,marker,tilesLeftToSee,cnt,prevmarker;
 INT32 Inc[6],Dir[6];
 INT8	itemVisible = FALSE;
 INT8 Blocking,twoMoreTiles,markerDir;
 INT8 nextDir=0,AlreadySawItem=FALSE;
 UINT8 who; //,itemIndex; // for each square checked
 UINT8 dir,range,Path2;
 UINT8	ubRoomNo;
 BOOLEAN	fCheckForRooms = FALSE;
 ITEM_POOL					*pItemPool;
 BOOLEAN			fHiddenStructVisible;
 UINT8				ubMovementCost;
 BOOLEAN			fTravelCostObs;
 BOOLEAN			fGoneThroughDoor = FALSE;
 BOOLEAN			fThroughWindow = FALSE;
 BOOLEAN			fItemsQuoteSaid = FALSE;
 UINT16				usIndex;
 BOOLEAN			fRevealItems = TRUE;
 BOOLEAN			fStopRevealingItemsAfterThisTile = FALSE;
 INT8					bTallestStructureHeight;
 INT32				iDoorGridNo;
 STRUCTURE *	pStructure, *pDummy;
 INT8         bStructHeight;
 INT8         bThroughWindowDirection;

	if ( pSoldier->uiStatusFlags & SOLDIER_ENEMY )
  {
   //pSoldier->needToLookForItems = FALSE;
   return;
  }

	if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE )
	{
		return;
	}

	// Return if this guy has no gridno, has bad life, etc
	if( pSoldier->sGridNo == NOWHERE || !pSoldier->bInSector || pSoldier->bLife < OKLIFE )
	{
	 return;
	}

	if (pSoldier->bBlindedCounter > 0)
	{
		return;
	}


 gubGridNoValue++;

 if ( gubGridNoValue == 255 )
 {
		// Reset!
		memset( gubGridNoMarkers, 0, sizeof( gubGridNoMarkers ) );
		gubGridNoValue = 1;
 }


	// OK, look for doors
	MercLooksForDoors( pSoldier, TRUE );


  who = pSoldier->ubID;
  dir = pSoldier->bDirection;

 //NumMessage("good old reveal",dir);

  // a gassed merc can only see 1 tile away due to blurred vision
	if ( pSoldier->uiStatusFlags & SOLDIER_GASSED )
	{
		range = 1;
	}
  else
	{
    range = pSoldier->bViewRange;
		// balance item viewing range between normal and the limit set by opplist-type functions -- CJC
		range = (AdjustMaxSightRangeForEnvEffects( pSoldier, LightTrueLevel( pSoldier->sGridNo, pSoldier->bLevel), range ) + range) / 2;
	}


  BuildSightDir(dir,&Dir[0],&Dir[1],&Dir[2],&Dir[3],&Dir[4]);
  for (cnt = 0; cnt < 5; cnt++)
     Inc[cnt] = DirectionInc( (INT16)Dir[cnt]);

  // create gridno increment for NOVIEW - in other words, no increment!
  Inc[5] = 0;
  Dir[5] = pSoldier->bDirection;

  if (dir % 2 == 1)	/* even numbers use ViewPath2 */
     Path2 = TRUE;
  else
     Path2 = FALSE;

	
	// ATE: if in this special cercumstance... our guys are moving on their own...
	// Stop sighting items
	// IN the future, we may want to do something else here...

	if ( gTacticalStatus.uiFlags & OUR_MERCS_AUTO_MOVE )
	{
		itemsToo = FALSE;
	}

  for (maincnt = 0; maincnt < MAXVIEWPATHS; maincnt++)
  {
   marker = pSoldier->sGridNo;
   Blocking = FALSE;
   twoMoreTiles = FALSE;
   tilesLeftToSee = 99;
	 fRevealItems = TRUE;
	 fStopRevealingItemsAfterThisTile = FALSE;

#ifdef _DEBUG
	 if ( _KeyDown( NUM_LOCK ) )
	 {
		 memset( gubFOVDebugInfoInfo, 0, sizeof( gubFOVDebugInfoInfo ) );

		 SetRenderFlags( RENDER_FLAG_FULL );
		 RenderWorld( );
	 }
#endif

   for (markercnt = 0; markercnt < range; markercnt++)
   {

		 //fGoneThroughDoor = FALSE;
		 //fThroughWindow		= FALSE;


     prevmarker = marker;

     nextDir = 99;
		 fCheckForRooms = FALSE;
		 fTravelCostObs = FALSE;
		 if ( fStopRevealingItemsAfterThisTile )
		 {
			 fRevealItems = FALSE;
			 fStopRevealingItemsAfterThisTile = FALSE;
		 }


     if (Path2)
     {
				markerDir = ViewPath2[maincnt][markercnt];
					if (markercnt < 12)
						 nextDir = ViewPath2[maincnt][markercnt+1];
     }
     else
     {
				markerDir = ViewPath[maincnt][markercnt];
					if (markercnt < 12)
						 nextDir = ViewPath[maincnt][markercnt+1];
     }


		 // OK, check flags for going through door/window last tile
		 if ( fThroughWindow == 1 )
		 {
       // ATE: Make sure we are going through the same direction!
       // THis is to solve the drassen SAM problem with seeing through walls
       if ( Dir[markerDir] == bThroughWindowDirection)
       {
			    fThroughWindow = 2;
       }
       else
       {
			    fThroughWindow = 0;
       }
		 }
		 else if ( fThroughWindow == 2 )
		 {
				// We've overstayed our welcome - remove!
			 fThroughWindow = 0;
		 }


		 if ( fGoneThroughDoor == 1 )
		 {
			 fGoneThroughDoor = 2;
		 }
		 else if ( fGoneThroughDoor == 2 )
		 {
				// We've overstayed our welcome - remove!
			 fGoneThroughDoor = 0;
		 }



		 //ATE CHECK FOR NOVIEW!
		 if ( nextDir == NOVIEW )
		 {
			 nextDir = 99;
		 }

     marker = NewGridNo((INT16)marker,(INT16)Inc[markerDir]);

     if ( marker == 12426 )
     {
      int i = 0;
     }

		 // End if this is a no view...
		 if ( markerDir == NOVIEW && markercnt != 0 )
		 {
			 break;
		 }

#ifdef _DEBUG
		 if ( _KeyDown( NUM_LOCK ) )
		 {
			 int cnt = GetJA2Clock( );

			 gubFOVDebugInfoInfo[ marker ] = (UINT8)markercnt;

			 StartFrameBufferRender();

			 RenderFOVDebug( );

			 SetFont( LARGEFONT1 );
			 SetFontBackground( FONT_MCOLOR_BLACK );
			 SetFontForeground( FONT_MCOLOR_WHITE );
			 mprintf( 10,  10 , L"%d", maincnt  );
			 //mprintf( 10,  20 , L"%d", marker  );
			 //mprintf( 50,  20 , L"%d", pSoldier->sGridNo  );

			 InvalidateScreen( );
			 EndFrameBufferRender();
			 RefreshScreen( NULL );

			 do
			 {

			 } while( ( GetJA2Clock( ) - cnt ) < 250 );
	 
		 }
#endif

		 // Check if we can get to this gridno from our direction in
		 ubMovementCost = gubWorldMovementCosts[ marker ][ Dir[ markerDir ] ][ ubLevel ];

     // ATE: Added: If our current sector is below ground, ignore any blocks!
     if ( gfCaves && ubMovementCost != TRAVELCOST_CAVEWALL )
     {
        ubMovementCost = TRAVELCOST_FLAT;
     }

		 if ( IS_TRAVELCOST_DOOR( ubMovementCost ) )
		 {
			 ubMovementCost = DoorTravelCost( pSoldier, marker, ubMovementCost, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), &iDoorGridNo );
			 pStructure = FindStructure( (INT16) iDoorGridNo, STRUCTURE_ANYDOOR );
			 if ( pStructure != NULL && pStructure->fFlags & STRUCTURE_TRANSPARENT)
			 {
				// cell door or somehow otherwise transparent; allow merc to see through
				ubMovementCost = TRAVELCOST_FLAT;
			 }
		 }

		 // If we have hit an obstacle, STOP HERE
		 if ( ubMovementCost >= TRAVELCOST_BLOCKED )
		 {
				// We have an obstacle here...

				// If it is bigger than a breadbox... err... taller than a man...
				// Then stop path altogether
				// otherwise just stop revealing items		
				
				// CJC:  only do this when the direction is horizontal; easier and faster to check 
				// and the effect should still be good enough

				if ( ubMovementCost == TRAVELCOST_WALL || ubMovementCost == TRAVELCOST_DOOR || ubMovementCost == TRAVELCOST_EXITGRID )
				{
					fTravelCostObs = TRUE;
					fRevealItems = FALSE;
				}
				else
				{
					// walls are handled above, so the blocking object is guaranteed not to be a wall
					bTallestStructureHeight = GetTallestStructureHeight( (INT16) marker, FALSE );
					if (bTallestStructureHeight >= 3)
					{
						fTravelCostObs = TRUE;
						fStopRevealingItemsAfterThisTile = TRUE;
					}			
					else if ( bTallestStructureHeight != 0 )
					{
						// stop revealing items after this tile but keep going
						fStopRevealingItemsAfterThisTile = TRUE;
					}

				}





				if ( (Dir[markerDir] % 2) == 1 )
				{
					// diagonal
					fTravelCostObs = TRUE;
					// cheap hack... don't reveal items
					fRevealItems = FALSE;
				}
				else
				{			

					bTallestStructureHeight = GetTallestStructureHeight( (INT16) marker, FALSE );
					if (bTallestStructureHeight >= 3)
					{
						fTravelCostObs = TRUE;
						fStopRevealingItemsAfterThisTile = TRUE;
					}			
					else if ( bTallestStructureHeight != 0 )
					{
						// stop revealing items after this tile but keep going
						fStopRevealingItemsAfterThisTile = TRUE;
					}
				}

		 }


		 // Check if it's been done already!
		 if ( gubGridNoMarkers[ marker ] != gubGridNoValue )
		 {

			 // Mark gridno
			 gubGridNoMarkers[ marker ] = gubGridNoValue;
			
			 // check and see if the gridno changed
			 // if the gridno is the same, avoid redundancy and break
			 if (marker==prevmarker && markercnt != 0 )
			 {
				
			 }
			 else	// it changed
			 {
				
				// Skip others if we have gone through a door but are too far away....
				if ( fGoneThroughDoor )
				{
					if (markercnt > 5 )   // Are we near the door?
					{
						break;
					}
				}				 
				 // DO MINE FINDING STUFF
				 // GET INDEX FOR ITEM HERE
				 // if there IS a direction after this one, nextdir WILL NOT be 99
				 if (nextDir != 99)
				 {
						Blocking = GetBlockingStructureInfo( (INT16)marker, (INT8)Dir[ markerDir ], (INT8)Dir[ nextDir ], ubLevel, &bStructHeight, &pDummy, FALSE );
				 }
				 else // no "next" direction, so pass in a NOWHERE so that
				 // "SpecialViewObstruction" will know not to take it UINT32o consideration
				 {
						Blocking = GetBlockingStructureInfo( (INT16)marker, (INT8)Dir[markerDir], (INT8)30, ubLevel, &bStructHeight, &pDummy, FALSE  );
				 }

         if ( gfCaves )
         {
            Blocking = NOTHING_BLOCKING;
         }

				 // CHECK FOR ROOMS
				 if ( Blocking == BLOCKING_TOPLEFT_WINDOW || Blocking == BLOCKING_TOPLEFT_OPEN_WINDOW )
				 {
						// CHECK FACING DIRECTION!
						if ( Dir[markerDir] == NORTH || Dir[markerDir] == SOUTH )
						{
							if (markercnt <= 1 )   // Are we right beside it?
							{
								fThroughWindow = TRUE;
                bThroughWindowDirection = ( INT8 ) Dir[ markerDir ];
							}
						}
				 }
				 if ( Blocking == BLOCKING_TOPRIGHT_WINDOW || Blocking == BLOCKING_TOPRIGHT_OPEN_WINDOW )
				 {
						// CHECK FACING DIRECTION!
						if ( Dir[markerDir] == EAST || Dir[markerDir] == WEST )
						{
							if (markercnt <= 1 )   // Are we right beside it?
							{
								fThroughWindow = TRUE;
                bThroughWindowDirection = ( INT8 ) Dir[ markerDir ];
							}
						}
				 }

				 if ( Blocking == BLOCKING_TOPLEFT_DOOR )
				 {
						fGoneThroughDoor = TRUE;
				 }
				 if ( Blocking == BLOCKING_TOPRIGHT_DOOR )
				 {
						fGoneThroughDoor = TRUE;
				 }

				 // ATE: If we hit this tile, find item always!
				 //if (Blocking < FULL_BLOCKING )
				 {

						// Handle special things for our mercs, like uncovering roofs
						// and revealing objects...
						//gpSoldier->shad |= SEENBIT;

						 //itemVisible = ObjList[itemIndex].visible;

						 // NOTE: don't allow object viewing if gassed XXX

						 if (itemsToo && fRevealItems ) // && itemIndex < MAXOBJECTLIST)
						 {
               	// OK, look for corpses...
	              LookForAndMayCommentOnSeeingCorpse( pSoldier, (INT16)marker, ubLevel );

								if ( GetItemPool( (INT16)marker, &pItemPool, ubLevel ) )
								{
										itemVisible = pItemPool->bVisible;

										if ( SetItemPoolVisibilityOn( pItemPool, INVISIBLE, fShowLocators ) )
										{
											SetRenderFlags(RENDER_FLAG_FULL);

											if ( fShowLocators )
											{
												// Set makred render flags
												//gpWorldLevelData[marker].uiFlags|=MAPELEMENT_REDRAW;
												//gpWorldLevelData[gusCurMousePos].pTopmostHead->uiFlags |= LEVELNODE_DYNAMIC;

												//SetRenderFlags(RENDER_FLAG_MARKED);
												SetRenderFlags(RENDER_FLAG_FULL);

												// Hault soldier
												// ATE: Only if in combat...
												if ( gTacticalStatus.uiFlags & INCOMBAT )
												{
													HaultSoldierFromSighting( pSoldier, FALSE );
												}
                        else
                        {
                          // ATE: Make sure we show locators...
                          gTacticalStatus.fLockItemLocators = FALSE;
                        }

												if ( !fItemsQuoteSaid && gTacticalStatus.fLockItemLocators == FALSE )
												{
													gTacticalStatus.fLockItemLocators = TRUE;

													if ( gTacticalStatus.ubAttackBusyCount > 0 && ( gTacticalStatus.uiFlags & INCOMBAT ) )
													{
														gTacticalStatus.fItemsSeenOnAttack = TRUE;
														gTacticalStatus.ubItemsSeenOnAttackSoldier = pSoldier->ubID;
														gTacticalStatus.usItemsSeenOnAttackGridNo  = (INT16)(marker);
													}
													else
													{
														// Display quote!
                            if ( !AM_AN_EPC( pSoldier ) )
                            {
														  TacticalCharacterDialogueWithSpecialEvent( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, (INT16)(marker), 0 );
                            }
                            else
                            {
			                        // Turn off item lock for locators...
			                        gTacticalStatus.fLockItemLocators = FALSE;
			                        // Slide to location!
			                        SlideToLocation( 0, (INT16)(marker) );
                            }
													}
													fItemsQuoteSaid = TRUE;
												}

											}
										}
								}

						 }

						 // if blood here, let the user see it now...
						 //if (ExtGrid[marker].patrolInfo < MAXBLOOD)
						 //		gpSoldier->blood = ExtGrid[marker].patrolInfo;

						 //DoRoofs(marker,gpSoldier);

						 tilesLeftToSee--;
				}

				 // CHECK FOR HIDDEN STRUCTS
				 // IF we had a hidden struct here that is not visible ( which will still be true because
				 // we set it revealed below...
				if ( DoesGridnoContainHiddenStruct( (UINT16)marker, &fHiddenStructVisible ) )
				{
					if ( !fHiddenStructVisible )
					{
						gpWorldLevelData[marker].uiFlags|=MAPELEMENT_REDRAW;
						SetRenderFlags(RENDER_FLAG_MARKED);
						RecompileLocalMovementCosts( (UINT16)marker );
					}
				}

				if (tilesLeftToSee <= 0)
					break;

				if ( Blocking == FULL_BLOCKING || ( fTravelCostObs && !fThroughWindow ) )
				{
					break;
				}

				//if ( Blocking == NOTHING_BLOCKING || Blocking == BLOCKING_NEXT_TILE )
				if ( Blocking == NOTHING_BLOCKING )
				{
					fCheckForRooms = TRUE;
				}

				if ( ubLevel != 0 )
				{
					fCheckForRooms = FALSE;
				}


				// CHECK FOR SLANT ROOF!
				{
					STRUCTURE							*pStructure, *pBase;

					pStructure = FindStructure( (INT16)marker, STRUCTURE_SLANTED_ROOF );

					if ( pStructure != NULL )
					{
						pBase = FindBaseStructure( pStructure );

						// ADD TO SLANTED ROOF LIST!
						AddSlantRoofFOVSlot( (INT16)marker );
					}
				}


			  // Set gridno as revealed
				if ( ubLevel == FIRST_LEVEL )
				{
					if ( gfBasement || gfCaves )
					{
						// OK, if we are underground, we don't want to reveal stuff if
						// 1 ) there is a roof over us and
						// 2 ) we are not in a room
						if ( gubWorldRoomInfo[ marker ] == NO_ROOM && TypeRangeExistsInRoofLayer( marker, FIRSTROOF, FOURTHROOF, &usIndex ) )
						{
							int i = 0;
						}
						else
						{
							gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED;
							if( gfCaves )
							{
								RemoveFogFromGridNo( marker );
							}
						}
					}
					else
					{
						gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED;
					}

					// CHECK FOR ROOMS
					//if ( fCheckForRooms )
					{
						if ( InAHiddenRoom( (INT16)marker, &ubRoomNo ) )
						{
							 RemoveRoomRoof( (INT16)marker, ubRoomNo, pSoldier );
							 if ( ubRoomNo == ROOM_SURROUNDING_BOXING_RING && gWorldSectorX == BOXING_SECTOR_X && gWorldSectorY == BOXING_SECTOR_Y && gbWorldSectorZ == BOXING_SECTOR_Z )
							 {
									// reveal boxing ring at same time
									RemoveRoomRoof( (INT16)marker, BOXING_RING, pSoldier );
							 }
						}
					}
				}
				else
				{
					gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED_ROOF;						
				}

				// Check for blood....
				UpdateBloodGraphics( (INT16)marker, ubLevel );


			  if ( Blocking != NOTHING_BLOCKING && Blocking != BLOCKING_TOPLEFT_DOOR && Blocking != BLOCKING_TOPRIGHT_DOOR && Blocking != BLOCKING_TOPLEFT_WINDOW && Blocking != BLOCKING_TOPRIGHT_WINDOW && Blocking != BLOCKING_TOPRIGHT_OPEN_WINDOW && Blocking != BLOCKING_TOPLEFT_OPEN_WINDOW)
				{
					 break;
				}

			 //gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_SHADELAND;

			}
		 } // End of duplicate check
		 else
		 {
			if ( fTravelCostObs )
			{
				break;
			}
		 }

	} 	// end of one path


 }     // end of path loop


	// Loop through all availible slant roofs we collected and perform cool stuff on them
	ExamineSlantRoofFOVSlots( );

  //pSoldier->needToLookForItems = FALSE;

 //LookForDoors(pSoldier,UNAWARE);
}
Example #2
0
void RenderPopupMenu()
{
	UINT16 usX, usY;
	UINT8 ubColumn, ubEntry, ubCounter;
	UINT8 *pDestBuf;
	UINT32 uiDestPitchBYTES;
	UINT16 usLineColor;
	UINT16 usStringWidth;
	UINT16 usStart;

	//Draw the menu
	ColorFillVideoSurfaceArea(FRAME_BUFFER, 
		gPopup.usLeft, gPopup.usTop, gPopup.usRight, gPopup.usBottom, 
		Get16BPPColor(FROMRGB(128, 128, 128) ) );
	pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );			
	SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
	usLineColor = Get16BPPColor( FROMRGB( 64, 64, 64 ) );
	RectangleDraw( TRUE, gPopup.usLeft, gPopup.usTop, gPopup.usRight, gPopup.usBottom, 
		usLineColor, pDestBuf );
	if( gPopup.ubColumns > 1 )
	{ //draw a vertical line between each column
		usStart = gPopup.usLeft + gPopup.ubColumnWidth[ 0 ];
		for( ubColumn = 1; ubColumn < gPopup.ubColumns; ubColumn++ )
		{
			LineDraw( TRUE, usStart, gPopup.usTop, usStart, gPopup.usBottom, usLineColor, pDestBuf );
		}
		usStart += (UINT16)gPopup.ubColumnWidth[ ubColumn ];
	}
	UnLockVideoSurface( FRAME_BUFFER );

	//Set up the text attributes.
	SetFont( gPopup.usFont);
	SetFontBackground( FONT_MCOLOR_BLACK );
	SetFontForeground( FONT_MCOLOR_WHITE );
	
	usX = gPopup.usLeft + 1;
	ubCounter = 0;
	usStart = gPopup.usLeft;
	for( ubColumn = 0; ubColumn < gPopup.ubColumns; ubColumn++ )
	{
		for( ubEntry = 0; ubEntry < gPopup.ubMaxEntriesPerColumn; ubEntry++ )
		{
			if( ubCounter >= gPopup.ubNumEntries )
				return; //done
			//Calc current string's width in pixels.  Adding 14 pixels which is the width of
			//two padded gPopup.usFont spaces not stored in the string.
			usStringWidth = 14 + StringPixLength( GetPopupMenuString( ubCounter ), gPopup.usFont );
			//Horizontally center the string inside the popup menu
			usX = usStart + ( gPopup.ubColumnWidth[ ubColumn ] - usStringWidth ) / 2;
			usY = gPopup.usTop + 1 + ubEntry * gusEntryHeight;
			if( ubCounter == gPopup.ubSelectedIndex - 1 )
			{
				//This is the highlighted menu entry.
				SetFontForeground( FONT_MCOLOR_LTBLUE );
				mprintf( usX, usY, L" %s ", GetPopupMenuString( ubCounter ) );
				SetFontForeground( FONT_MCOLOR_WHITE );
			}
			else
			{
				mprintf( usX, usY, L" %s ", GetPopupMenuString( ubCounter ) );
			}
			ubCounter++;
		}
		usStart += gPopup.ubColumnWidth[ ubColumn ];
	}
}