From 3f6ff281a30f78d399fd366317fce4da47899ca8 Mon Sep 17 00:00:00 2001 From: AalaarDB Date: Tue, 21 Aug 2007 10:21:56 +0000 Subject: [PATCH] Fix for 1% chance to hit target when distance is > 52 Camo and other effects are taken into account when aiming at a body part Max Distance Visible is more consistent in being calculated based on the soldier and direction rather than a fixed number git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1239 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Strategic Town Loyalty.cpp | 4 +- Tactical/Dialogue Control.cpp | 4 +- Tactical/DisplayCover.cpp | 22 +-- Tactical/End Game.cpp | 10 +- Tactical/Handle Items.cpp | 2 +- Tactical/Handle UI.cpp | 20 +-- Tactical/Interface Dialogue.cpp | 4 +- Tactical/Interface Items.cpp | 5 +- Tactical/Interface Panels.cpp | 10 +- Tactical/Items.cpp | 144 ----------------- Tactical/Keys.cpp | 99 +++++------- Tactical/LOS.cpp | 223 +++++++++++++-------------- Tactical/LOS.h | 36 ++--- Tactical/Militia Control.cpp | 5 +- Tactical/Overhead.cpp | 9 +- Tactical/Rotting Corpses.cpp | 115 ++++++-------- Tactical/ShopKeeper Interface.cpp | 7 +- Tactical/Soldier Ani.cpp | 14 +- Tactical/Soldier Control.cpp | 2 +- Tactical/Soldier Control.h | 2 + Tactical/TeamTurns.cpp | 6 +- Tactical/Turn Based Input.cpp | 1 - Tactical/Weapons.cpp | 23 ++- Tactical/opplist.cpp | 107 +++++++------ Tactical/opplist.h | 4 +- TacticalAI/AIMain.cpp | 56 +++---- TacticalAI/AIUtils.cpp | 2 +- TacticalAI/Attacks.cpp | 3 +- TacticalAI/CreatureDecideAction.cpp | 2 +- TacticalAI/DecideAction.cpp | 24 +-- TacticalAI/Knowledge.cpp | 6 +- 31 files changed, 361 insertions(+), 610 deletions(-) diff --git a/Strategic/Strategic Town Loyalty.cpp b/Strategic/Strategic Town Loyalty.cpp index eb748df1..130791f9 100644 --- a/Strategic/Strategic Town Loyalty.cpp +++ b/Strategic/Strategic Town Loyalty.cpp @@ -779,13 +779,13 @@ void HandleMurderOfCivilian( SOLDIERTYPE *pSoldier, BOOLEAN fIntentional ) } // killer seen by civ? - if ( SoldierToSoldierLineOfSightTest( pCivSoldier, MercPtrs[ pSoldier->ubAttackerID ], gGameExternalOptions.ubStraightSightRange, TRUE ) != 0 ) + if ( SoldierToSoldierLineOfSightTest( pCivSoldier, MercPtrs[ pSoldier->ubAttackerID ], TRUE, gGameExternalOptions.ubStraightSightRange ) != 0 ) { bSeenState |= 1; } // victim seen by civ? - if( SoldierToSoldierLineOfSightTest( pCivSoldier, pSoldier, gGameExternalOptions.ubStraightSightRange, TRUE ) != 0 ) + if( SoldierToSoldierLineOfSightTest( pCivSoldier, pSoldier, TRUE, gGameExternalOptions.ubStraightSightRange ) != 0 ) { bSeenState |= 2; } diff --git a/Tactical/Dialogue Control.cpp b/Tactical/Dialogue Control.cpp index 19ae6c1c..5d6dfe7b 100644 --- a/Tactical/Dialogue Control.cpp +++ b/Tactical/Dialogue Control.cpp @@ -2559,7 +2559,7 @@ void SayQuoteFromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQuo { // Add guy if he's a candidate... if ( OK_INSECTOR_MERC( pTeamSoldier ) && PythSpacesAway( sGridNo, pTeamSoldier->sGridNo ) < bDistance && !AM_AN_EPC( pTeamSoldier ) && !( pTeamSoldier->uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pTeamSoldier )) && !pTeamSoldier->fMercAsleep && - SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, 0, 0, (UINT8)MaxDistanceVisible(), TRUE ) ) + SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, 0, 0, TRUE ) ) { if ( usQuoteNum == 66 && (INT8) Random( 100 ) > EffectiveWisdom( pTeamSoldier ) ) { @@ -2603,7 +2603,7 @@ void SayQuote58FromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQ { // Add guy if he's a candidate... if ( OK_INSECTOR_MERC( pTeamSoldier ) && PythSpacesAway( sGridNo, pTeamSoldier->sGridNo ) < bDistance && !AM_AN_EPC( pTeamSoldier ) && !( pTeamSoldier->uiStatusFlags & SOLDIER_GASSED ) && !(AM_A_ROBOT( pTeamSoldier )) && !pTeamSoldier->fMercAsleep && - SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, 0, 0, (UINT8)MaxDistanceVisible(), TRUE ) ) + SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, 0, 0, TRUE ) ) { // ATE: This is to check gedner for this quote... if ( QuoteExp_GenderCode[ pTeamSoldier->ubProfile ] == 0 && bSex == FEMALE ) diff --git a/Tactical/DisplayCover.cpp b/Tactical/DisplayCover.cpp index 6ce14d46..1c6e10ea 100644 --- a/Tactical/DisplayCover.cpp +++ b/Tactical/DisplayCover.cpp @@ -427,7 +427,6 @@ INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTa INT32 iCover=0; UINT16 usMaxRange; UINT16 usRange; - UINT16 usSightLimit; //loop through all the enemies and determine the cover for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) @@ -458,18 +457,8 @@ INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTa continue; // next merc } - usRange = (UINT16)GetRangeInCellCoordsFromGridNoDiff( pOpponent->sGridNo, sTargetGridNo ); - // Lesh: changed 2-nd parameter in DistanceVisible function call - usSightLimit = DistanceVisible( pOpponent, (SoldierHasLimitedVision(pOpponent) ? pOpponent->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sTargetGridNo, pSoldier->bLevel, pSoldier ); - - - if( usRange > ( usSightLimit * CELL_X_SIZE ) ) - { - continue; - } - // if actual LOS check fails, then chance to hit is 0, ignore this guy - if( SoldierToVirtualSoldierLineOfSightTest( pOpponent, sTargetGridNo, pSoldier->bLevel, bStance, (UINT8)usSightLimit, TRUE ) == 0 ) + if( SoldierToVirtualSoldierLineOfSightTest( pOpponent, sTargetGridNo, pSoldier->bLevel, bStance, TRUE ) == 0 ) { continue; } @@ -486,6 +475,7 @@ INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTa usMaxRange = Weapon[ GLOCK_18 ].usRange; } + usRange = (UINT16)GetRangeInCellCoordsFromGridNoDiff( pOpponent->sGridNo, sTargetGridNo ); iBulletGetThrough = __min( __max( (INT32)( ( ( ( ( usMaxRange - usRange ) / (FLOAT)( usMaxRange ) ) + .3 ) * 100 ) ), 0 ), 100 ); if( iBulletGetThrough > 5 && iGetThrough > 0 ) @@ -964,13 +954,13 @@ INT8 CalcIfSoldierCanSeeGridNo( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOL } // Lesh: changed 2-nd parameter in DistanceVisible function call - usSightLimit = DistanceVisible( pSoldier, (SoldierHasLimitedVision(pSoldier) ? pSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sTargetGridNo, fRoof, pSoldier ); + usSightLimit = DistanceVisible( pSoldier, (SoldierHasLimitedVision(pSoldier) ? pSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sTargetGridNo, fRoof ); // // Prone // - iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_PRONE, (UINT8)usSightLimit, bAware ); + iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_PRONE, bAware, usSightLimit ); if( iLosForGridNo != 0 ) { bRetVal++; @@ -979,7 +969,7 @@ INT8 CalcIfSoldierCanSeeGridNo( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOL // // Crouch // - iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_CROUCH, (UINT8)usSightLimit, bAware ); + iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_CROUCH, bAware, usSightLimit ); if( iLosForGridNo != 0 ) { bRetVal++; @@ -988,7 +978,7 @@ INT8 CalcIfSoldierCanSeeGridNo( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, BOOL // // Standing // - iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_STAND, (UINT8)usSightLimit, bAware ); + iLosForGridNo = SoldierToVirtualSoldierLineOfSightTest( pSoldier, sTargetGridNo, fRoof, ANIM_STAND, bAware, usSightLimit ); if( iLosForGridNo != 0 ) { bRetVal++; diff --git a/Tactical/End Game.cpp b/Tactical/End Game.cpp index e4f31142..04a6a0e4 100644 --- a/Tactical/End Game.cpp +++ b/Tactical/End Game.cpp @@ -185,10 +185,7 @@ void HandleDeidrannaDeath( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, INT8 bLev { if ( QuoteExp_WitnessDeidrannaDeath[ pTeamSoldier->ubProfile ] ) { - // Can we see location? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pTeamSoldier ); - - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, TRUE ) ) { TacticalCharacterDialogue( pTeamSoldier, QUOTE_KILLING_DEIDRANNA ); } @@ -477,10 +474,7 @@ void HandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, INT8 bLe { if ( QuoteExp_WitnessQueenBugDeath[ pTeamSoldier->ubProfile ] ) { - // Can we see location? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pTeamSoldier ); - - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, TRUE ) ) { TacticalCharacterDialogue( pTeamSoldier, QUOTE_KILLING_QUEEN ); } diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 84cecb83..120bab77 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -5028,7 +5028,7 @@ void TestPotentialOwner( SOLDIERTYPE * pSoldier ) { if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife >= OKLIFE ) { - if ( SoldierToSoldierLineOfSightTest( pSoldier, gpTempSoldier, (UINT8) DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, 0, gpTempSoldier->sGridNo, gpTempSoldier->bLevel, gpTempSoldier ), TRUE ) ) + if ( SoldierToSoldierLineOfSightTest( pSoldier, gpTempSoldier, TRUE ) ) { MakeNPCGrumpyForMinorOffense( pSoldier, gpTempSoldier ); } diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp index 2434cb38..977bca35 100644 --- a/Tactical/Handle UI.cpp +++ b/Tactical/Handle UI.cpp @@ -4744,7 +4744,6 @@ UINT32 UIHandleTOnTerrain( UI_EVENT *pUIEvent ) UINT16 usMapPos; BOOLEAN fValidTalkableGuy = FALSE; INT16 sTargetGridNo; - INT16 sDistVisible; // Get soldier if ( !GetSoldier( &pSoldier, gusSelectedSoldier ) ) @@ -4783,11 +4782,6 @@ UINT32 UIHandleTOnTerrain( UI_EVENT *pUIEvent ) uiRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sTargetGridNo ); - //ATE: Check if we have good LOS - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sTargetGridNo, pSoldier->bLevel, pSoldier ); - - if ( uiRange <= NPC_TALK_RADIUS ) { if ( fValidTalkableGuy ) @@ -4814,7 +4808,7 @@ UINT32 UIHandleTOnTerrain( UI_EVENT *pUIEvent ) if ( fValidTalkableGuy ) { - if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, sTargetGridNo, pSoldier->bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, sTargetGridNo, pSoldier->bLevel, 3, TRUE ) ) { //. ATE: Make range far, so we alternate cursors... guiNewUICursor = TALK_OUT_RANGE_A_UICURSOR; @@ -5573,7 +5567,6 @@ BOOLEAN HandleTalkInit( ) UINT8 ubNewDirection; UINT8 ubQuoteNum; UINT8 ubDiceRoll; - INT16 sDistVisible; INT16 sActionGridNo; UINT8 ubDirection; UINT8 commandRange; //lal @@ -5601,12 +5594,8 @@ BOOLEAN HandleTalkInit( ) { if ( !(( pTSoldier->bTeam == MILITIA_TEAM ) && ( CheckIfRadioIsEquipped() )) ) //lal { - //ATE: Check if we have good LOS - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pTSoldier->sGridNo, pTSoldier->bLevel, pTSoldier ); - // Check LOS! - if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, pTSoldier->sGridNo, pTSoldier->bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, pTSoldier->sGridNo, pTSoldier->bLevel, 3, TRUE ) ) { if ( pTSoldier->ubProfile != NO_PROFILE ) { @@ -6290,10 +6279,7 @@ BOOLEAN ValidQuickExchangePosition( ) { if ( PythSpacesAway( pSoldier->sGridNo, pOverSoldier->sGridNo ) == 1 ) { - // Check if we have LOS to them.... - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pOverSoldier->sGridNo, pOverSoldier->bLevel, pOverSoldier ); - - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pOverSoldier->sGridNo, pOverSoldier->bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pOverSoldier->sGridNo, pOverSoldier->bLevel, 3, TRUE ) ) { // ATE: // Check that the path is good! diff --git a/Tactical/Interface Dialogue.cpp b/Tactical/Interface Dialogue.cpp index 64f92cf5..c485f94d 100644 --- a/Tactical/Interface Dialogue.cpp +++ b/Tactical/Interface Dialogue.cpp @@ -1402,9 +1402,9 @@ BOOLEAN SourceSoldierPointerIsValidAndReachableForGive( SOLDIERTYPE * pGiver ) } // pointer should always be valid anyhow - if ( PythSpacesAway( pGiver->sGridNo, gpSrcSoldier->sGridNo ) > MaxDistanceVisible() ) + if( PythSpacesAway( pGiver->sGridNo, gpSrcSoldier->sGridNo ) > gpSrcSoldier->GetMaxDistanceVisible(pGiver->sGridNo, gpSrcSoldier->bLevel) ) { - return( FALSE ); + return FALSE; } sAdjGridNo = FindAdjacentGridEx( pGiver, gpSrcSoldier->sGridNo, NULL, NULL, FALSE, FALSE ); diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 73c85d41..6b8c6e4b 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -4812,7 +4812,6 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos ) OBJECTTYPE TempObject; INT16 sGridNo; INT16 sDist; - INT16 sDistVisible; if ( SelectedGuyInBusyAnimation( ) ) @@ -5100,10 +5099,8 @@ BOOLEAN HandleItemPointerClick( UINT16 usMapPos ) return( FALSE ); } - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, gpItemPointerSoldier->sGridNo, gpItemPointerSoldier->bLevel, gpItemPointerSoldier ); - // Check LOS.... - if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, gpItemPointerSoldier->sGridNo, gpItemPointerSoldier->bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( !SoldierTo3DLocationLineOfSightTest( pSoldier, gpItemPointerSoldier->sGridNo, gpItemPointerSoldier->bLevel, 3, TRUE ) ) { return( FALSE ); } diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index 6aa191c0..0c08816a 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -537,7 +537,6 @@ INT8 GetUIApsToDisplay( SOLDIERTYPE *pSoldier ) void CheckForDisabledForGiveItem( ) { INT16 sDist; - INT16 sDistVisible; INT16 sDestGridNo; INT8 bDestLevel; INT32 cnt; @@ -566,10 +565,8 @@ void CheckForDisabledForGiveItem( ) { sDist = PythSpacesAway( gpSMCurrentMerc->sGridNo, pSoldier->sGridNo ); - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->bLevel, gpSMCurrentMerc ); - // Check LOS.... - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->bLevel, 3, TRUE ) ) { if ( sDist <= PASSING_ITEM_DISTANCE_NOTOKLIFE ) { @@ -600,11 +597,8 @@ void CheckForDisabledForGiveItem( ) // Get distance.... sDist = PythSpacesAway( MercPtrs[ ubSrcSoldier ]->sGridNo, sDestGridNo ); - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( MercPtrs[ ubSrcSoldier ], DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sDestGridNo, bDestLevel, MercPtrs[ ubSrcSoldier ] ); - // Check LOS.... - if ( SoldierTo3DLocationLineOfSightTest( MercPtrs[ ubSrcSoldier ], sDestGridNo, bDestLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( MercPtrs[ ubSrcSoldier ], sDestGridNo, bDestLevel, 3, TRUE ) ) { // UNCONSCIOUS GUYS ONLY 1 tile AWAY if ( MercPtrs[ gusSMCurrentMerc ]->bLife < CONSCIOUSNESS ) diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index baf559f6..75435ed0 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -4536,18 +4536,6 @@ UINT16 UseKitPoints( OBJECTTYPE * pObj, UINT16 usPoints, SOLDIERTYPE *pSoldier ) extern BOOLEAN gfDrawPathPoints; - void DoChrisTest( SOLDIERTYPE * pSoldier ) - { - // GenerateMapEdgepoints(); - - //gfDrawPathPoints = !gfDrawPathPoints; - - //gfDrawPathPoints = TRUE; - //GlobalReachableTest( pSoldier->sGridNo ); - //gfDrawPathPoints = FALSE; - - } - #else #ifdef AI_TIMING_TESTS @@ -4557,138 +4545,6 @@ UINT16 UseKitPoints( OBJECTTYPE * pObj, UINT16 usPoints, SOLDIERTYPE *pSoldier ) extern UINT32 guiRedSeekCounter, guiRedHelpCounter; guiRedHideCounter; #endif - void DoChrisTest( SOLDIERTYPE * pSoldier ) - { - /* - UINT32 uiLoop; - - for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++ ) - { - if ( MercSlots[ uiLoop ] && MercSlots[ uiLoop ]->bTeam == ENEMY_TEAM ) - { - if ( MercSlots[ uiLoop ]->ubSkillTrait1 == NIGHTOPS ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier %d has nightops 1", MercSlots[ uiLoop ]->ubID ) ); - } - if ( MercSlots[ uiLoop ]->ubSkillTrait2 == NIGHTOPS ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Soldier %d has nightops 2", MercSlots[ uiLoop ]->ubID ) ); - } - if ( MercSlots[ uiLoop ]->inv[ HEAD1POS ].usItem != NOTHING ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "%S", ItemNames[ MercSlots[ uiLoop ]->inv[ HEAD1POS ].usItem ] ) ); - } - if ( MercSlots[ uiLoop ]->inv[ HEAD2POS ].usItem != NOTHING ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "%S", ItemNames[ MercSlots[ uiLoop ]->inv[ HEAD2POS ].usItem ] ) ); - } - - } - } - */ - - UINT32 uiLoop; - - - for ( uiLoop = 0; uiLoop <= HISTORY_MERC_KILLED_CHARACTER; uiLoop++ ) - { - switch( uiLoop ) - { - case HISTORY_FOUND_MONEY: - case HISTORY_ASSASSIN: - case HISTORY_DISCOVERED_TIXA: - case HISTORY_DISCOVERED_ORTA: - case HISTORY_GOT_ROCKET_RIFLES: - case HISTORY_DEIDRANNA_DEAD_BODIES: - case HISTORY_BOXING_MATCHES: - case HISTORY_SOMETHING_IN_MINES: - case HISTORY_DEVIN: - case HISTORY_MIKE: - case HISTORY_TONY: - case HISTORY_KROTT: - case HISTORY_KYLE: - case HISTORY_MADLAB: - case HISTORY_GABBY: - case HISTORY_KEITH_OUT_OF_BUSINESS: - case HISTORY_HOWARD_CYANIDE: - case HISTORY_KEITH: - case HISTORY_HOWARD: - case HISTORY_PERKO: - case HISTORY_SAM: - case HISTORY_FRANZ: - case HISTORY_ARNOLD: - case HISTORY_FREDO: - case HISTORY_RICHGUY_BALIME: - case HISTORY_JAKE: - case HISTORY_BUM_KEYCARD: - case HISTORY_WALTER: - case HISTORY_DAVE: - case HISTORY_PABLO: - case HISTORY_KINGPIN_MONEY: - //VARIOUS BATTLE CONDITIONS - case HISTORY_LOSTTOWNSECTOR: - case HISTORY_DEFENDEDTOWNSECTOR: - case HISTORY_LOSTBATTLE: - case HISTORY_WONBATTLE: - case HISTORY_FATALAMBUSH: - case HISTORY_WIPEDOUTENEMYAMBUSH: - case HISTORY_UNSUCCESSFULATTACK: - case HISTORY_SUCCESSFULATTACK: - case HISTORY_CREATURESATTACKED: - case HISTORY_KILLEDBYBLOODCATS: - case HISTORY_SLAUGHTEREDBLOODCATS: - case HISTORY_GAVE_CARMEN_HEAD: - case HISTORY_SLAY_MYSTERIOUSLY_LEFT: - AddHistoryToPlayersLog( (UINT8) uiLoop, 0, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY ); - break; - default: - break; - } - - } - - - /* - UINT32 uiEntryTime, uiExitTime; - UINT32 uiLoop; - - for ( uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++ ) - { - if ( MercSlots[ uiLoop ] && MercSlots[ uiLoop ]->bTeam == CIV_TEAM ) - { - pSoldier = MercSlots[ uiLoop ]; - if ( ExtractScheduleEntryAndExitInfo( pSoldier, &uiEntryTime, &uiExitTime ) ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Civ %d enters at %ld, exits at %ld", pSoldier->ubID, uiEntryTime, uiExitTime ); - } - } - } - */ -/* - UINT32 uiLoop; - - for ( uiLoop = 0; uiLoop <= 4; uiLoop++ ) - { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Team %d has %d people", uiLoop, gTacticalStatus.Team[ uiLoop ].bMenInSector ); - } - */ - /* - UINT32 uiLoop; - INT16 sGridNo; - UINT32 uiStartTime, uiEndTime; - - if (GetMouseMapPos( &sGridNo )) - { - uiStartTime = GetJA2Clock(); - for (uiLoop = 0; uiLoop < 50000; uiLoop++) - { - FindBestPath( pSoldier, sGridNo, pSoldier->bLevel, WALKING, COPYROUTE ); - } - uiEndTime = GetJA2Clock(); - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "50000 path calls from %d to %d took %ld ms", pSoldier->sGridNo, sGridNo, uiEndTime - uiStartTime ) ); - } - */ - } #endif diff --git a/Tactical/Keys.cpp b/Tactical/Keys.cpp index c37436c5..89ce68ba 100644 --- a/Tactical/Keys.cpp +++ b/Tactical/Keys.cpp @@ -1298,7 +1298,6 @@ BOOLEAN AllMercsLookForDoor( INT16 sGridNo, BOOLEAN fUpdateValue ) INT32 cnt, cnt2; INT8 bDirs[ 8 ] = { NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST }; SOLDIERTYPE *pSoldier; - INT16 sDistVisible; DOOR_STATUS *pDoorStatus; INT16 usNewGridNo; @@ -1319,14 +1318,25 @@ BOOLEAN AllMercsLookForDoor( INT16 sGridNo, BOOLEAN fUpdateValue ) // ATE: Ok, lets check for some basic things here! if ( pSoldier->bLife >= OKLIFE && pSoldier->sGridNo != NOWHERE && pSoldier->bActive && pSoldier->bInSector ) { - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, 0, pSoldier ); - - if (PythSpacesAway( pSoldier->sGridNo, sGridNo ) <= sDistVisible ) + // and we can trace a line of sight to his x,y coordinates? + // (taking into account we are definitely aware of this guy now) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, 0, 0, TRUE ) ) { + // Update status... + if ( fUpdateValue ) + { + InternalUpdateDoorsPerceivedValue( pDoorStatus ); + } + return( TRUE ); + } + + // Now try other adjacent gridnos... + for ( cnt2 = 0; cnt2 < 8; cnt2++ ) + { + usNewGridNo = NewGridNo( sGridNo, DirectionInc( bDirs[ cnt2 ] ) ); // and we can trace a line of sight to his x,y coordinates? // (taking into account we are definitely aware of this guy now) - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, 0, 0, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, usNewGridNo, 0, 0, TRUE ) ) { // Update status... if ( fUpdateValue ) @@ -1336,28 +1346,6 @@ BOOLEAN AllMercsLookForDoor( INT16 sGridNo, BOOLEAN fUpdateValue ) return( TRUE ); } } - - // Now try other adjacent gridnos... - for ( cnt2 = 0; cnt2 < 8; cnt2++ ) - { - usNewGridNo = NewGridNo( sGridNo, DirectionInc( bDirs[ cnt2 ] ) ); - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, usNewGridNo, 0, pSoldier ); - - if (PythSpacesAway( pSoldier->sGridNo, usNewGridNo ) <= sDistVisible ) - { - // and we can trace a line of sight to his x,y coordinates? - // (taking into account we are definitely aware of this guy now) - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, usNewGridNo, 0, 0, (UINT8) sDistVisible, TRUE ) ) - { - // Update status... - if ( fUpdateValue ) - { - InternalUpdateDoorsPerceivedValue( pDoorStatus ); - } - return( TRUE ); - } - } - } } } @@ -1368,7 +1356,6 @@ BOOLEAN AllMercsLookForDoor( INT16 sGridNo, BOOLEAN fUpdateValue ) BOOLEAN MercLooksForDoors( SOLDIERTYPE *pSoldier, BOOLEAN fUpdateValue ) { INT32 cnt, cnt2; - INT16 sDistVisible; INT16 sGridNo; DOOR_STATUS *pDoorStatus; INT8 bDirs[ 8 ] = { NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST }; @@ -1387,53 +1374,41 @@ BOOLEAN MercLooksForDoors( SOLDIERTYPE *pSoldier, BOOLEAN fUpdateValue ) } sGridNo = pDoorStatus->sGridNo; - - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, 0, pSoldier ); - - if ( PythSpacesAway( pSoldier->sGridNo, sGridNo ) <= sDistVisible ) + // and we can trace a line of sight to his x,y coordinates? + // (taking into account we are definitely aware of this guy now) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, 0, 0, TRUE ) ) { + // OK, here... update perceived value.... + if ( fUpdateValue ) + { + InternalUpdateDoorsPerceivedValue( pDoorStatus ); + + // Update graphic.... + InternalUpdateDoorGraphicFromStatus( pDoorStatus, TRUE, TRUE ); + } + return( TRUE ); + } + + // Now try other adjacent gridnos... + for ( cnt2 = 0; cnt2 < 8; cnt2++ ) + { + usNewGridNo = NewGridNo( sGridNo, DirectionInc( bDirs[ cnt2 ] ) ); // and we can trace a line of sight to his x,y coordinates? // (taking into account we are definitely aware of this guy now) - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, 0, 0, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, usNewGridNo, 0, 0, TRUE ) ) { - // OK, here... update perceived value.... + // Update status... if ( fUpdateValue ) { InternalUpdateDoorsPerceivedValue( pDoorStatus ); // Update graphic.... InternalUpdateDoorGraphicFromStatus( pDoorStatus, TRUE, TRUE ); + } return( TRUE ); } } - - // Now try other adjacent gridnos... - for ( cnt2 = 0; cnt2 < 8; cnt2++ ) - { - usNewGridNo = NewGridNo( sGridNo, DirectionInc( bDirs[ cnt2 ] ) ); - - if (PythSpacesAway( pSoldier->sGridNo, usNewGridNo ) <= sDistVisible ) - { - // and we can trace a line of sight to his x,y coordinates? - // (taking into account we are definitely aware of this guy now) - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, usNewGridNo, 0, 0, (UINT8) sDistVisible, TRUE ) ) - { - // Update status... - if ( fUpdateValue ) - { - InternalUpdateDoorsPerceivedValue( pDoorStatus ); - - // Update graphic.... - InternalUpdateDoorGraphicFromStatus( pDoorStatus, TRUE, TRUE ); - - } - return( TRUE ); - } - } - } - } return( FALSE ); diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index d62fa3df..203d5e07 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -640,7 +640,7 @@ BOOLEAN ResolveHitOnWall( STRUCTURE * pStructure, INT32 iGridNo, INT8 bLOSIndexX * - stops at other obstacles * */ -INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, UINT8 ubTileSightLimit, UINT8 ubTreeSightReduction, INT8 bAware, INT32 bCamouflage, BOOLEAN fSmell, INT16 * psWindowGridNo ) +INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, int iTileSightLimit, UINT8 ubTreeSightReduction, INT8 bAware, INT32 bCamouflage, BOOLEAN fSmell, INT16 * psWindowGridNo ) { // Parameters... // the X,Y,Z triplets should be obvious @@ -693,9 +693,6 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, FLOAT dDistance; INT32 iDistance; - INT32 iSightLimit = ubTileSightLimit * CELL_X_SIZE; - INT32 iAdjSightLimit = iSightLimit; - INT32 iLoop; MAP_ELEMENT * pMapElement; @@ -723,6 +720,13 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, return( 0 ); } + //ADB see notes at bottom as to why there is this 255 here + INT32 iSightLimit = iTileSightLimit * CELL_X_SIZE; + if (iTileSightLimit >= 255) { + iSightLimit = (iTileSightLimit - 255) * CELL_X_SIZE; + } + //for the CTGT calculation, clamp it to the average distance + INT32 iAdjSightLimit = iSightLimit; if (iSightLimit == 0) { // blind! @@ -767,11 +771,9 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, iDistance += 1; } - //ADB remove this check since I might have a scope that allows me to see past this arbitrary limit - //Lalien: just removing this check removes visibility limit completly - if ( iDistance > iSightLimit) + if ( iDistance > iTileSightLimit * CELL_X_SIZE) { - //out of visual range + // out of visual range return( 0 ); } @@ -1361,12 +1363,42 @@ INT32 LineOfSightTest( FLOAT dStartX, FLOAT dStartY, FLOAT dStartZ, FLOAT dEndX, #ifdef LOS_DEBUG gLOSTestResults.fLOSClear = TRUE; #endif + //ADB this was the original code and comments: // this somewhat complicated formula does the following: // it starts with the distance to the target // it adds the difference between the original and adjusted sight limit, = the amount of cover // it then scales the value based on the difference between the original sight limit and the // very maximum possible in best lighting conditions - return( (iDistance + (iSightLimit - iAdjSightLimit)) * (MaxDistanceVisible() * CELL_X_SIZE) / iSightLimit ); + //return( (iDistance + (iSightLimit - iAdjSightLimit)) * (MaxDistanceVisible() * CELL_X_SIZE) / iSightLimit ); + + //in the original code, iSightLimit could vary depending exactly on what I can see + //so assuming there was no cover, the returned value is altered exactly on iSightLimit + //if my sight is low, then the function returns a value higher than MaxNormalDistanceVisible + //this simulates a target farther away and harder to hit + //if my sight is higher than the max distance, via sniper scope etc, then the function returns a lower value + //this makes the target seem like it is closer and easier to hit + + + //ADB this is the new code + //the problem with the new code is there needs to be a way to calculate a line + //without stopping when my eyes stop, but also including my sight limit! + //so iTileSightLimit has 255 added to it if the line is supposed to be infinite + + int scalar = iSightLimit; + if (iTileSightLimit >= 255) { + //I know I am doing a CTGT calc, so don't get carried away + //just because I can see 999 tiles doesn't mean I can shoot it! + //this preserves the original intent of the scalar, but makes it less likely iAdjSightLimit + //is less than zero, which if it were the function would return, which we don't want if our sight is good + scalar = min(MaxNormalDistanceVisible() * CELL_X_SIZE, iSightLimit); + } + else { + //I know that my sight could be over the average distance, but I am not going to clamp it + //because I do not think the actual value matters, and if it does, + //then using the real value is closer to the original intent + //AFAIK all instances that aren't CTGT just use this as a boolean test + } + return( (iDistance + (iSightLimit - iAdjSightLimit)) * (MaxNormalDistanceVisible() * CELL_X_SIZE) / scalar ); } BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * pdZPos ) @@ -1555,7 +1587,7 @@ BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * p return( TRUE ); } -INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, UINT8 ubTileSightLimit, INT8 bAware ) +INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, INT8 bAware, int iTileSightLimit, UINT8 ubAimLocation ) { FLOAT dStartZPos, dEndZPos; BOOLEAN fOk; @@ -1563,7 +1595,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE INT16 bEffectiveCamo; INT16 bEffectiveStealth; UINT8 ubTreeReduction; - INT32 iTemp; + UINT8 ubPosType; // TO ADD: if target is camouflaged and in cover, reduce sight distance by 30% // TO ADD: if in tear gas, reduce sight limit to 2 tiles @@ -1599,7 +1631,27 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE } else { - fOk = CalculateSoldierZPos( pEndSoldier, LOS_POS, &dEndZPos ); + switch( ubAimLocation ) + { + case AIM_SHOT_HEAD: + ubPosType = HEAD_TARGET_POS; + break; + case AIM_SHOT_TORSO: + ubPosType = TORSO_TARGET_POS; + break; + case AIM_SHOT_LEGS: + ubPosType = LEGS_TARGET_POS; + break; + default: + ubPosType = TARGET_POS; + break; + } + + fOk = CalculateSoldierZPos( pEndSoldier, ubPosType, &dEndZPos ); + if (!fOk) + { + return( FALSE ); + } CHECKF( fOk ); fSmell = HasThermalOptics( pStartSoldier); } @@ -1647,34 +1699,32 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE if ( gAnimControl[ pEndSoldier->usAnimState ].ubEndHeight < ANIM_STAND ) { - iTemp = ubTileSightLimit; // reduce visibility by up to a third for camouflage! switch( pEndSoldier->bOverTerrainType ) { case LOW_GRASS: case HIGH_GRASS: // jungle camo bonus - iTemp -= iTemp * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; + iTileSightLimit -= iTileSightLimit * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; break; case FLAT_FLOOR: // flat floor = indoors case PAVED_ROAD: // urban camo bonus - iTemp -= iTemp * (urban * bEffectiveCamo / 3 / totalCamo) / 100; + iTileSightLimit -= iTileSightLimit * (urban * bEffectiveCamo / 3 / totalCamo) / 100; break; case DIRT_ROAD: // desert camo bonus case TRAIN_TRACKS: - iTemp -= iTemp * (desert * bEffectiveCamo / 3 / totalCamo) / 100; + iTileSightLimit -= iTileSightLimit * (desert * bEffectiveCamo / 3 / totalCamo) / 100; break; //case ??? : // snow camo bonus - // iTemp -= iTemp * (snow * bEffectiveCamo / 3 / totalCamo) / 100; + // iTileSightLimit -= iTileSightLimit * (snow * bEffectiveCamo / 3 / totalCamo) / 100; // break; case FLAT_GROUND: //in this case both desert and jungle can work: - iTemp -= iTemp * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; - iTemp -= iTemp * (desert * bEffectiveCamo / 3 / totalCamo) / 100; + iTileSightLimit -= iTileSightLimit * (jungle * bEffectiveCamo / 3 / totalCamo) / 100; + iTileSightLimit -= iTileSightLimit * (desert * bEffectiveCamo / 3 / totalCamo) / 100; break; default: break; } - ubTileSightLimit = (UINT8) iTemp; } } else @@ -1693,9 +1743,7 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE // reduce visibility by up to a third for Stealth! // stance and terrain don't matter - iTemp = ubTileSightLimit; - iTemp -= iTemp * (bEffectiveStealth / 3) / 100; - ubTileSightLimit = (UINT8) iTemp; + iTileSightLimit -= iTileSightLimit * (bEffectiveStealth / 3) / 100; } else { @@ -1711,7 +1759,14 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE ubTreeReduction = gubTreeSightReduction[ gAnimControl[pEndSoldier->usAnimState].ubEndHeight ]; } - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, ubTileSightLimit, ubTreeReduction, bAware, bEffectiveCamo + bEffectiveStealth, fSmell, NULL ) ); + if (iTileSightLimit == -1) { + iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( pEndSoldier->sGridNo, pEndSoldier->bLevel ); + } + else if (iTileSightLimit == 255) { + iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( pEndSoldier->sGridNo, pEndSoldier->bLevel ); + } + + return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, iTileSightLimit, ubTreeReduction, bAware, bEffectiveCamo + bEffectiveStealth, fSmell, NULL ) ); } INT16 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT16 sEndGridNo ) @@ -1741,37 +1796,11 @@ INT16 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT16 sEndGridNo return( sWindowGridNo ); } -BOOLEAN SoldierToSoldierLineOfSightTimingTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, UINT8 ubTileSightLimit, INT8 bAware ) -{ - UINT32 uiLoopLimit = 100000; - UINT32 uiLoop; - UINT32 uiStartTime, uiEndTime; - - FILE *OutFile; - - uiStartTime = GetJA2Clock(); - for (uiLoop = 0; uiLoop < uiLoopLimit; uiLoop++) - { - SoldierToSoldierLineOfSightTest( pStartSoldier, pEndSoldier, ubTileSightLimit, bAware ); - } - uiEndTime = GetJA2Clock(); - if ((OutFile = fopen("Timing.txt", "a+t")) != NULL) - { -#ifdef _DEBUG - fprintf(OutFile, "DEBUG: " ); -#endif - fprintf(OutFile, String( "Time for %d calls is %d milliseconds\n", uiLoopLimit, uiEndTime - uiStartTime)); - fclose(OutFile); - } - return( TRUE ); -} - -INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bCubeLevel, UINT8 ubTileSightLimit, INT8 bAware ) +INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bCubeLevel, INT8 bAware, int iTileSightLimit ) { FLOAT dStartZPos, dEndZPos; INT16 sXPos, sYPos; UINT8 ubTargetID; - SOLDIERTYPE * pTarget; BOOLEAN fOk; CHECKF( pStartSoldier ); @@ -1779,6 +1808,7 @@ INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGr fOk = CalculateSoldierZPos( pStartSoldier, LOS_POS, &dStartZPos ); CHECKF( fOk ); + if (bCubeLevel > 0) { dEndZPos = ((FLOAT) (bCubeLevel + bLevel * PROFILE_Z_SIZE ) - 0.5f) * HEIGHT_UNITS_PER_INDEX; @@ -1789,9 +1819,8 @@ INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGr ubTargetID = WhoIsThere2( sGridNo, bLevel ); if (ubTargetID != NOBODY) { - pTarget = MercPtrs[ubTargetID]; // there's a merc there; do a soldier-to-soldier test - return( SoldierToSoldierLineOfSightTest( pStartSoldier, pTarget, ubTileSightLimit, bAware) ); + return( SoldierToSoldierLineOfSightTest( pStartSoldier, MercPtrs[ubTargetID], bAware, iTileSightLimit) ); } // else... assume standing height dEndZPos = STANDING_LOS_POS + bLevel * HEIGHT_UNITS; @@ -1803,61 +1832,17 @@ INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGr sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2); sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2); - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, ubTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL ) ); + if (iTileSightLimit == -1) { + iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel ); + } + else if (iTileSightLimit == 255) { + iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel ); + } + + return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL ) ); } -INT32 SoldierToBodyPartLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, UINT8 ubAimLocation, UINT8 ubTileSightLimit, INT8 bAware ) -{ - SOLDIERTYPE * pEndSoldier; - UINT8 ubTargetID; - FLOAT dStartZPos, dEndZPos; - INT16 sXPos, sYPos; - BOOLEAN fOk; - UINT8 ubPosType; - - // CJC August 13, 2002: for this routine to work there MUST be a target at the location specified - ubTargetID = WhoIsThere2( sGridNo, bLevel ); - if (ubTargetID == NOBODY) - { - return( 0 ); - } - pEndSoldier = MercPtrs[ubTargetID]; - - CHECKF( pStartSoldier ); - - fOk = CalculateSoldierZPos( pStartSoldier, LOS_POS, &dStartZPos ); - CHECKF( fOk ); - - switch( ubAimLocation ) - { - case AIM_SHOT_HEAD: - ubPosType = HEAD_TARGET_POS; - break; - case AIM_SHOT_TORSO: - ubPosType = TORSO_TARGET_POS; - break; - case AIM_SHOT_LEGS: - ubPosType = LEGS_TARGET_POS; - break; - default: - ubPosType = TARGET_POS; - break; - } - - fOk = CalculateSoldierZPos( pEndSoldier, ubPosType, &dEndZPos ); - if (!fOk) - { - return( FALSE ); - } - - ConvertGridNoToXY( sGridNo, &sXPos, &sYPos ); - sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2); - sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2); - - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, ubTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL ) ); -} - -INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bStance, UINT8 ubTileSightLimit, INT8 bAware ) +INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bStance, INT8 bAware, int iTileSightLimit ) { FLOAT dStartZPos, dEndZPos; INT16 sXPos, sYPos; @@ -1894,15 +1879,17 @@ INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2); sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2); - return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, ubTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL ) ); + if (iTileSightLimit == -1) { + iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel ); + } + else if (iTileSightLimit == 255) { + iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel ); + } + + return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, HasThermalOptics( pStartSoldier), NULL ) ); } -INT32 SoldierToLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, UINT8 ubTileSightLimit, INT8 bAware ) -{ - return( SoldierTo3DLocationLineOfSightTest( pStartSoldier, sGridNo, 0, 0, ubTileSightLimit, bAware ) ); -} - -INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, INT16 sEndGridNo, INT8 bEndLevel, UINT8 ubTileSightLimit, INT8 bAware ) +INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, INT16 sEndGridNo, INT8 bEndLevel, INT8 bAware, int iTileSightLimit ) { FLOAT dStartZPos, dEndZPos; INT16 sStartXPos, sStartYPos, sEndXPos, sEndYPos; @@ -1911,7 +1898,7 @@ INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, I ubStartID = WhoIsThere2( sStartGridNo, bStartLevel ); if ( ubStartID != NOBODY ) { - return( SoldierTo3DLocationLineOfSightTest( MercPtrs[ ubStartID ], sEndGridNo, bEndLevel, 0, ubTileSightLimit, bAware ) ); + return( SoldierTo3DLocationLineOfSightTest( MercPtrs[ ubStartID ], sEndGridNo, bEndLevel, 0, bAware, iTileSightLimit ) ); } // else... assume standing heights @@ -1931,7 +1918,13 @@ INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, I sEndXPos = sEndXPos * CELL_X_SIZE + (CELL_X_SIZE / 2); sEndYPos = sEndYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2); - return( LineOfSightTest( (FLOAT)sStartXPos, (FLOAT)sStartYPos, dStartZPos, (FLOAT) sEndXPos, (FLOAT) sEndYPos, dEndZPos, ubTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, FALSE, NULL ) ); + if (iTileSightLimit == -1) { + iTileSightLimit = MaxNormalDistanceVisible(); + } + else if (iTileSightLimit == 255) { + iTileSightLimit = 255 + MaxNormalDistanceVisible(); + } + return( LineOfSightTest( (FLOAT)sStartXPos, (FLOAT)sStartYPos, dStartZPos, (FLOAT) sEndXPos, (FLOAT) sEndYPos, dEndZPos, iTileSightLimit, gubTreeSightReduction[ANIM_STAND], bAware, 0, FALSE, NULL ) ); } /* diff --git a/Tactical/LOS.h b/Tactical/LOS.h index 8e481a17..563b922b 100644 --- a/Tactical/LOS.h +++ b/Tactical/LOS.h @@ -44,6 +44,16 @@ enum CollisionEnums } ; +enum { + LOS_POS, + FIRING_POS, + TARGET_POS, + HEAD_TARGET_POS, + TORSO_TARGET_POS, + LEGS_TARGET_POS, + HEIGHT +}; + INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDeltaY, FLOAT dDeltaZ, INT16 *pusStructureID, FLOAT *pdNormalX, FLOAT *pdNormalY, FLOAT *pdNormalZ ); @@ -51,27 +61,19 @@ INT32 CheckForCollision( FLOAT dX, FLOAT dY, FLOAT dZ, FLOAT dDeltaX, FLOAT dDel INT8 ChanceToGetThrough( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ ); INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOAT dEndZ, UINT16 usHandItem, INT16 sHitBy, BOOLEAN fBuckshot, BOOLEAN fFake ); -INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, UINT8 ubSightLimit, INT8 bAware ); -INT32 SoldierToLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, UINT8 ubSightLimit, INT8 bAware ); -INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bCubeLevel, UINT8 ubSightLimit, INT8 bAware ); -INT32 SoldierToBodyPartLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, UINT8 ubAimLocation, UINT8 ubTileSightLimit, INT8 bAware ); -INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bStance, UINT8 ubTileSightLimit, INT8 bAware ); +INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, INT8 bAware, int iTileSightLimit = -1, UINT8 ubAimLocation = LOS_POS ); +INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bCubeLevel, INT8 bAware, int ubSightLimit = -1 ); +INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bStance, INT8 bAware, int iTileSightLimit = -1 ); UINT8 SoldierToSoldierChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier ); UINT8 SoldierToSoldierBodyPartChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, UINT8 ubAimLocation ); UINT8 AISoldierToSoldierChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier ); UINT8 AISoldierToLocationChanceToGetThrough( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bCubeLevel ); UINT8 SoldierToLocationChanceToGetThrough( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, INT8 bLevel, INT8 bCubeLevel, UINT8 ubTargetID ); -INT32 SoldierToLocationVisibleDistance( SOLDIERTYPE * pStartSoldier, INT16 sGridNo, UINT8 ubTileSightLimit, INT8 bAware ); INT16 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT16 sEndGridNo ); -INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, INT16 sEndGridNo, INT8 bEndLevel, UINT8 ubTileSightLimit, INT8 bAware ); +INT32 LocationToLocationLineOfSightTest( INT16 sStartGridNo, INT8 bStartLevel, INT16 sEndGridNo, INT8 bEndLevel, INT8 bAware, int iTileSightLimit = -1 ); BOOLEAN CalculateSoldierZPos( SOLDIERTYPE * pSoldier, UINT8 ubPosType, FLOAT * pdZPos ); -BOOLEAN SoldierToSoldierLineOfSightTimingTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, UINT8 ubSightLimit, INT8 bAware ); -BOOLEAN TestFireBullet( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier ); -void DoChrisTest( SOLDIERTYPE * pSoldier ); - - #define HEIGHT_UNITS 256 #define HEIGHT_UNITS_PER_INDEX (HEIGHT_UNITS / PROFILE_Z_SIZE) #define MAX_STRUCTURE_HEIGHT 50 @@ -89,16 +91,6 @@ void DoChrisTest( SOLDIERTYPE * pSoldier ); #define TREE_SIGHT_REDUCTION 6 #define NORMAL_TREES 10 -enum { - LOS_POS, - FIRING_POS, - TARGET_POS, - HEAD_TARGET_POS, - TORSO_TARGET_POS, - LEGS_TARGET_POS, - HEIGHT -}; - // 191 is 6' (structures of height 3) // 127 is 4' (structures of height 2) // 63 is 2' (structures of height 1) diff --git a/Tactical/Militia Control.cpp b/Tactical/Militia Control.cpp index a67750d7..fdab500a 100644 --- a/Tactical/Militia Control.cpp +++ b/Tactical/Militia Control.cpp @@ -1006,7 +1006,6 @@ void PositionCursorForMilitiaControlBox( void ) void HandleShadingOfLinesForMilitiaControlMenu( void ) { SOLDIERTYPE *pSoldier = NULL; - INT16 sDistVisible; // check if valid if( ( fShowMilitiaControlMenu == FALSE ) || ( ghMilitiaControlBox == - 1 ) ) @@ -1016,10 +1015,8 @@ void HandleShadingOfLinesForMilitiaControlMenu( void ) if ( GetSoldier( &pSoldier, gusSelectedSoldier ) ) { - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->bLevel, pSoldier ); - // Check LOS! - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->bLevel, 3, TRUE ) ) { UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ATTACK ); UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_HOLD ); diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index df8a8656..7ed438e7 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -3334,7 +3334,7 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld ) case JOEY: // check to see if Martha can see this pOther = FindSoldierByProfileID( MARTHA, FALSE ); - if ( pOther && (PythSpacesAway( pOther->sGridNo, pSoldierOld->sGridNo ) < 10 || SoldierToSoldierLineOfSightTest( pOther, pSoldierOld, (UINT8) MaxDistanceVisible(), TRUE ) != 0 ) ) + if ( pOther && (PythSpacesAway( pOther->sGridNo, pSoldierOld->sGridNo ) < 10 || SoldierToSoldierLineOfSightTest( pOther, pSoldierOld, TRUE ) != 0 ) ) { // Martha has a heart attack and croaks TriggerNPCRecord( MARTHA, 17 ); @@ -3727,8 +3727,8 @@ UINT8 CivilianGroupMembersChangeSidesWithinProximity( SOLDIERTYPE * pAttacked ) { // if in LOS of this guy's attacker if ( (pAttacked->ubAttackerID != NOBODY && pSoldier->bOppList[pAttacked->ubAttackerID] == SEEN_CURRENTLY) - || ( PythSpacesAway( pSoldier->sGridNo, pAttacked->sGridNo ) < MaxDistanceVisible() ) - || ( pAttacked->ubAttackerID != NOBODY && PythSpacesAway( pSoldier->sGridNo, MercPtrs[ pAttacked->ubAttackerID ]->sGridNo ) < MaxDistanceVisible() ) ) + || ( PythSpacesAway( pSoldier->sGridNo, pAttacked->sGridNo ) < pAttacked->GetMaxDistanceVisible(pSoldier->sGridNo, pSoldier->bLevel) ) + || ( pAttacked->ubAttackerID != NOBODY && PythSpacesAway( pSoldier->sGridNo, MercPtrs[ pAttacked->ubAttackerID ]->sGridNo ) < pAttacked->GetMaxDistanceVisible(MercPtrs[ pAttacked->ubAttackerID ]->sGridNo, MercPtrs[ pAttacked->ubAttackerID ]->bLevel) ) ) { MakeCivHostile( pSoldier, 2 ); if ( pSoldier->bOppCnt > 0 ) @@ -3873,9 +3873,8 @@ void HickCowAttacked( SOLDIERTYPE * pNastyGuy, SOLDIERTYPE * pTarget ) { if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife && pSoldier->bNeutral && pSoldier->ubCivilianGroup == HICKS_CIV_GROUP ) { - if ( SoldierToSoldierLineOfSightTest( pSoldier, pNastyGuy, (UINT8) MaxDistanceVisible(), TRUE ) ) + if ( SoldierToSoldierLineOfSightTest( pSoldier, pNastyGuy, TRUE ) ) { - CivilianGroupMemberChangesSides( pSoldier ); break; } diff --git a/Tactical/Rotting Corpses.cpp b/Tactical/Rotting Corpses.cpp index 86c013ed..6d7b462c 100644 --- a/Tactical/Rotting Corpses.cpp +++ b/Tactical/Rotting Corpses.cpp @@ -1253,7 +1253,6 @@ void AllMercsOnTeamLookForCorpse( ROTTING_CORPSE *pCorpse, INT8 bTeam ) { INT32 cnt; SOLDIERTYPE *pSoldier; - INT16 sDistVisible; INT16 sGridNo; // If this cump is already visible, return @@ -1275,23 +1274,17 @@ void AllMercsOnTeamLookForCorpse( ROTTING_CORPSE *pCorpse, INT8 bTeam ) // look for all mercs on the same team, for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ bTeam ].bLastID; cnt++,pSoldier++ ) { - // ATE: Ok, lets check for some basic things here! - if ( pSoldier->bLife >= OKLIFE && pSoldier->sGridNo != NOWHERE && pSoldier->bActive && pSoldier->bInSector ) + // ATE: Ok, lets check for some basic things here! + if ( pSoldier->bLife >= OKLIFE && pSoldier->sGridNo != NOWHERE && pSoldier->bActive && pSoldier->bInSector ) + { + // and we can trace a line of sight to his x,y coordinates? + // (taking into account we are definitely aware of this guy now) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pCorpse->def.bLevel, 3, TRUE ) ) { - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, pCorpse->def.bLevel, pSoldier ); - - if (PythSpacesAway( pSoldier->sGridNo, sGridNo ) <= sDistVisible ) - { - // and we can trace a line of sight to his x,y coordinates? - // (taking into account we are definitely aware of this guy now) - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pCorpse->def.bLevel, 3, (UINT8) sDistVisible, TRUE ) ) - { - MakeCorpseVisible( pSoldier, pCorpse ); - return; - } - } + MakeCorpseVisible( pSoldier, pCorpse ); + return; } + } } } @@ -1299,72 +1292,64 @@ void AllMercsOnTeamLookForCorpse( ROTTING_CORPSE *pCorpse, INT8 bTeam ) void MercLooksForCorpses( SOLDIERTYPE *pSoldier ) { INT32 cnt; - INT16 sDistVisible; INT16 sGridNo; ROTTING_CORPSE *pCorpse; // Should we say disgust quote? if ( ( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_ROTTINGCORPSE ) ) { - return; - } + return; + } - if ( pSoldier->ubProfile == NO_PROFILE ) - { - return; - } + if ( pSoldier->ubProfile == NO_PROFILE ) + { + return; + } - if ( AM_AN_EPC( pSoldier ) ) - { - return; - } + if ( AM_AN_EPC( pSoldier ) ) + { + return; + } - if ( QuoteExp_HeadShotOnly[ pSoldier->ubProfile ] == 1 ) - { - return; - } + if ( QuoteExp_HeadShotOnly[ pSoldier->ubProfile ] == 1 ) + { + return; + } - // Every so often... do a corpse quote... - if ( Random( 400 ) <= 2 ) - { - // Loop through all corpses.... - for ( cnt = 0; cnt < giNumRottingCorpse; cnt++ ) - { - pCorpse = &(gRottingCorpse[ cnt ] ); + // Every so often... do a corpse quote... + if ( Random( 400 ) <= 2 ) + { + // Loop through all corpses.... + for ( cnt = 0; cnt < giNumRottingCorpse; cnt++ ) + { + pCorpse = &(gRottingCorpse[ cnt ] ); - if ( !pCorpse->fActivated ) - { + if ( !pCorpse->fActivated ) + { continue; - } + } - // Has this corpse rotted enough? - if ( pCorpse->def.ubType == ROTTING_STAGE2 ) - { - sGridNo = pCorpse->def.sGridNo; + // Has this corpse rotted enough? + if ( pCorpse->def.ubType == ROTTING_STAGE2 ) + { + sGridNo = pCorpse->def.sGridNo; + // and we can trace a line of sight to his x,y coordinates? + // (taking into account we are definitely aware of this guy now) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pCorpse->def.bLevel, 3, TRUE ) ) + { + TacticalCharacterDialogue( pSoldier, QUOTE_HEADSHOT ); - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, pCorpse->def.bLevel, pSoldier ); - - if (PythSpacesAway( pSoldier->sGridNo, sGridNo ) <= sDistVisible ) - { - // and we can trace a line of sight to his x,y coordinates? - // (taking into account we are definitely aware of this guy now) - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pCorpse->def.bLevel, 3, (UINT8) sDistVisible, TRUE ) ) - { - TacticalCharacterDialogue( pSoldier, QUOTE_HEADSHOT ); + pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_ROTTINGCORPSE; - pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_ROTTINGCORPSE; + BeginMultiPurposeLocator( sGridNo, pCorpse->def.bLevel, FALSE ); - BeginMultiPurposeLocator( sGridNo, pCorpse->def.bLevel, FALSE ); + // Slide to... + SlideToLocation( 0, sGridNo ); - // Slide to... - SlideToLocation( 0, sGridNo ); - - return; - } - } - } - } + return; + } + } + } } } diff --git a/Tactical/ShopKeeper Interface.cpp b/Tactical/ShopKeeper Interface.cpp index 585ccff9..77424e99 100644 --- a/Tactical/ShopKeeper Interface.cpp +++ b/Tactical/ShopKeeper Interface.cpp @@ -7070,7 +7070,6 @@ BOOLEAN CanMercInteractWithSelectedShopkeeper( SOLDIERTYPE *pSoldier ) SOLDIERTYPE *pShopkeeper; INT16 sDestGridNo; INT8 bDestLevel; - INT16 sDistVisible; UINT32 uiRange; @@ -7092,12 +7091,8 @@ BOOLEAN CanMercInteractWithSelectedShopkeeper( SOLDIERTYPE *pSoldier ) { sDestGridNo = pShopkeeper->sGridNo; bDestLevel = pShopkeeper->bLevel; - - // is he close enough to see that gridno if he turns his head? - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sDestGridNo, bDestLevel, pSoldier ); - // If he has LOS... - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sDestGridNo, bDestLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sDestGridNo, bDestLevel, 3, TRUE ) ) { // Get range to shopkeeper uiRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sDestGridNo ); diff --git a/Tactical/Soldier Ani.cpp b/Tactical/Soldier Ani.cpp index cf0c5331..ab24dd19 100644 --- a/Tactical/Soldier Ani.cpp +++ b/Tactical/Soldier Ani.cpp @@ -2958,16 +2958,14 @@ void SayBuddyWitnessedQuoteFromKill( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, // TO LOS check to killed // Can we see location of killer? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, pKillerSoldier ); - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) == 0 ) + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, pKillerSoldier->sGridNo, pKillerSoldier->bLevel, (UINT8)3, TRUE ) == 0 ) { continue; } // Can we see location of killed? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pTeamSoldier ); - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) == 0 ) + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, (UINT8)3, TRUE ) == 0 ) { continue; } @@ -3025,9 +3023,7 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier gfLastMercTalkedAboutKillingID = pKilledSoldier->ubID; // Can we see location? - sDistVisible = DistanceVisible( pKillerSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pKillerSoldier ); - - fCanWeSeeLocation = ( SoldierTo3DLocationLineOfSightTest( pKillerSoldier, sGridNo, bLevel, (UINT8)3, (UINT8) sDistVisible, TRUE ) != 0 ); + fCanWeSeeLocation = ( SoldierTo3DLocationLineOfSightTest( pKillerSoldier, sGridNo, bLevel, (UINT8)3, TRUE ) != 0 ); // Are we killing mike? @@ -3088,9 +3084,7 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier if ( OK_INSECTOR_MERC( pTeamSoldier ) && !( pTeamSoldier->uiStatusFlags & SOLDIER_GASSED ) && !AM_AN_EPC( pTeamSoldier ) ) { // Can we see location? - sDistVisible = DistanceVisible( pTeamSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, bLevel, pTeamSoldier ); - - if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, TRUE ) ) { ubMercsInSector[ ubNumMercs ] = (UINT8)cnt; ubNumMercs++; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 3c824c5c..69400c9a 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -3322,7 +3322,7 @@ void SetSoldierGridNo( SOLDIERTYPE *pSoldier, INT16 sNewGridNo, BOOLEAN fForceRe // if we SEE this particular oppponent, and he DOESN'T see us... and he COULD see us... if ( (pSoldier->bOppList[ cnt ] == SEEN_CURRENTLY) && pEnemy->bOppList[ pSoldier->ubID ] != SEEN_CURRENTLY && - PythSpacesAway( pSoldier->sGridNo, pEnemy->sGridNo ) < DistanceVisible( pEnemy, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pSoldier->sGridNo, pSoldier->bLevel, pSoldier ) ) + PythSpacesAway( pSoldier->sGridNo, pEnemy->sGridNo ) < DistanceVisible( pEnemy, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pSoldier->sGridNo, pSoldier->bLevel ) ) { // AGILITY (5): Soldier snuck 1 square past unaware enemy StatChange( pSoldier, AGILAMT, 5, FALSE ); diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 2a058796..07496e52 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -427,6 +427,8 @@ public: void CopyOldInventoryToNew(); void CopyNewInventoryToOld(); + INT16 GetMaxDistanceVisible(INT16 sGridNo = -1, INT8 bLevel = -1); + // Note: Place all non-POD items at the end (after endOfPOD) // The format of this structure affects what is written into and read from various // files (maps, save files, etc.). If you change it then that code will not work diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp index 3dc3dd2e..c9cc848f 100644 --- a/Tactical/TeamTurns.cpp +++ b/Tactical/TeamTurns.cpp @@ -1511,11 +1511,11 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f // this soldier is moving, so give them a bonus for crawling or swatting at long distances if ( !gbSeenOpponents[ ubOpponentID ][ pSoldier->ubID ] ) { - if (pSoldier->usAnimState == SWATTING && ubDistance > (MaxDistanceVisible() / 2) ) // more than 1/2 sight distance + if (pSoldier->usAnimState == SWATTING && ubDistance > (MaxNormalDistanceVisible() / 2) ) // more than 1/2 sight distance { iPoints++; } - else if (pSoldier->usAnimState == CRAWLING && ubDistance > (MaxDistanceVisible() / 4) ) // more than 1/4 sight distance + else if (pSoldier->usAnimState == CRAWLING && ubDistance > (MaxNormalDistanceVisible() / 4) ) // more than 1/4 sight distance { iPoints += ubDistance / STRAIGHT; } @@ -1889,7 +1889,7 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType) if ( ubInterruptType == NOISEINTERRUPT ) { // don't grant noise interrupts at greater than max. visible distance - if ( PythSpacesAway( pSoldier->sGridNo, pOpponent->sGridNo ) > MaxDistanceVisible() ) + if ( PythSpacesAway( pSoldier->sGridNo, pOpponent->sGridNo ) > MaxNormalDistanceVisible() ) { pOpponent->bInterruptDuelPts = NO_INTERRUPT; diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 6d32fac5..3c3b07db 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -3418,7 +3418,6 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) { if ( INFORMATION_CHEAT_LEVEL( ) ) { - DoChrisTest( MercPtrs[ gusSelectedSoldier ] ); } } else diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 718b0b79..7613f3a7 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -3650,11 +3650,10 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, UINT16 sGridNo, UINT8 ubAimTime } // 0verhaul: Changed to take expanded range from shooting at different levels into account - sDistVis = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, pSoldier->bTargetLevel, pSoldier ); - - // give some leeway to allow people to spot for each other... - // use distance limitation for LOS routine of 2 x maximum distance EVER visible, so that we get accurate - // calculations out to around 50 tiles. Because we multiply max distance by 2, we must divide by 2 later + //ADB this change does nothing - either way it is random - we don't know what level we are shooting to, which is + //what the last parameter is, and the soldier's current level is as good a guess as ground level. + //so if you really want to fix this, pass in a value + sDistVis = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sGridNo, pSoldier->bTargetLevel ); // CJC August 13 2002: Wow, this has been wrong the whole time. bTargetCubeLevel seems to be generally set to 2 - // but if a character is shooting at an enemy in a particular spot, then we should be using the target position on the body. @@ -3663,20 +3662,20 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, UINT16 sGridNo, UINT8 ubAimTime // If the start soldier has a body part they are aiming at, and know about the person in the tile, then use that height instead iSightRange = -1; + // give some leeway to allow people to spot for each other... + //so make the range to calculate the bullet at 255+ ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel ); // best to use team knowledge as well, in case of spotting for someone else // 0verhaul: Why not use the distance visible as the max for line of sight testing? + //ADB because A) the bullet can travel farther than I can see and B) I might have a spotter if (ubTargetID != NOBODY && pSoldier->bOppList[ubTargetID] == SEEN_CURRENTLY || gbPublicOpplist[pSoldier->bTeam][ubTargetID] == SEEN_CURRENTLY) { - iSightRange = SoldierToBodyPartLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bAimShotLocation, (UINT8) sDistVis /*(MaxDistanceVisible() * 2) */, TRUE ); + iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, 255, pSoldier->bAimShotLocation ); } - if (iSightRange == -1) // didn't do a bodypart-based test { - iSightRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, (UINT8) sDistVis /* (MaxDistanceVisible() * 2) */, TRUE ); + iSightRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, TRUE, 255 ); } - - iSightRange *= 2; if ( iSightRange > (sDistVis * CELL_X_SIZE) ) { @@ -3846,11 +3845,11 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, UINT16 sGridNo, UINT8 ubAimTime } //iChance -= 20 * iRange / iMaxRange; - if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxDistanceVisible() ) ) + if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) ) { // tank; penalize at close range! // 2 percent per tile closer than max visible distance - iChance -= 2 * ( MaxDistanceVisible() - (iRange / CELL_X_SIZE) ); + iChance -= 2 * ( MaxNormalDistanceVisible() - (iRange / CELL_X_SIZE) ); } if (iSightRange == 0) diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index 92c9f2c1..28a49ad7 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -1077,12 +1077,24 @@ INT16 DistanceSmellable( SOLDIERTYPE *pSoldier, SOLDIERTYPE * pSubject ) return( sDistVisible ); } -INT16 MaxDistanceVisible( void ) +INT16 MaxNormalDistanceVisible( void ) { return( STRAIGHT * 2 ); } -INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, INT16 sSubjectGridNo, INT8 bLevel, SOLDIERTYPE *pOther ) +INT16 SOLDIERTYPE::GetMaxDistanceVisible(INT16 sGridNo, INT8 bLevel) +{ + if (sGridNo == -1) { + return MaxNormalDistanceVisible(); + } + if (bLevel == -1) { + bLevel = this->bLevel; + } + + return DistanceVisible( this, (SoldierHasLimitedVision(this) ? this->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sGridNo, bLevel ); +} + +INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, INT16 sSubjectGridNo, INT8 bLevel ) { INT16 sDistVisible; INT8 bLightLevel; @@ -1116,7 +1128,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, if ( !TANK( pSoldier ) && ( bFacingDir == DIRECTION_IRRELEVANT || (pSoldier->uiStatusFlags & SOLDIER_ROBOT) || (pSubject && pSubject->fMuzzleFlash) ) ) { - sDistVisible = MaxDistanceVisible(); + sDistVisible = MaxNormalDistanceVisible(); } else { @@ -1124,7 +1136,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, if (pSoldier->sGridNo == sSubjectGridNo) { // looking up or down or two people accidentally in same tile... don't want it to be 0! - sDistVisible = MaxDistanceVisible(); + sDistVisible = MaxNormalDistanceVisible(); } else { @@ -1133,6 +1145,9 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, { bSubjectDir = (INT8) GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, sSubjectGridNo ); } + if (bFacingDir == DIRECTION_IRRELEVANT) { + bFacingDir = pSoldier->bDirection; + } sDistVisible = gbLookDistance[bFacingDir][bSubjectDir]; @@ -1165,8 +1180,7 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, if ( gbLookDistance[bFacingDir][bSubjectDir] != STRAIGHT ) { // reduce sight when we're not looking in that direction... - // (20%?) - sDistVisible = (sDistVisible * 8) / 10; + sDistVisible = (INT16) (sDistVisible * ANGLE_RATIO); } } } @@ -1186,16 +1200,8 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, // valid map references then use the ambient light level instead. if(0 > sSubjectGridNo || sSubjectGridNo > WORLD_MAX) { - if(pSoldier != pOther) - { - DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("113/UC Warning! Tried to detect the light level when character %ls[%d] at gridno %d tries to look for character %ls[%d] who outside of the valid map (gridno %d). Assigning default %d", - pSoldier->name, pSoldier->ubID, pSoldier->sGridNo, pOther->name, pOther->ubID, pOther->sGridNo, ubAmbientLightLevel)); - } - else - { - DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("113/UC Warning! Tried to detect the light level when character %ls[%d] looks at a location outside of the valid map (gridno %d). Assigning default %d", - pSoldier->name, pSoldier->ubID, pSoldier->sGridNo, ubAmbientLightLevel)); - } + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("113/UC Warning! Tried to detect the light level when character %ls[%d] looks at a location outside of the valid map (gridno %d). Assigning default %d", + pSoldier->name, pSoldier->ubID, pSoldier->sGridNo, ubAmbientLightLevel)); bLightLevel = ubAmbientLightLevel; } @@ -1242,7 +1248,13 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, // let tanks see and be seen further (at night) if ( (TANK( pSoldier ) && sDistVisible > 0) || (pSubject && TANK( pSubject ) ) ) { - sDistVisible = __max( sDistVisible + 5, MaxDistanceVisible() ); + if ( TANK(pSoldier) && sDistVisible > 0 && pSubject) + { + sDistVisible = __max( sDistVisible + 5, pSubject->GetMaxDistanceVisible(pSoldier->sGridNo, pSoldier->bLevel) ); + } + else { + sDistVisible = __max( sDistVisible + 5, pSoldier->GetMaxDistanceVisible() ); + } } if ( gpWorldLevelData[ pSoldier->sGridNo ].ubExtFlags[ bLevel ] & (MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS) ) @@ -1293,7 +1305,7 @@ void EndMuzzleFlash( SOLDIERTYPE * pSoldier ) { if ( pOtherSoldier->sGridNo != NOWHERE ) { - if ( PythSpacesAway( pOtherSoldier->sGridNo, pSoldier->sGridNo ) > DistanceVisible( pOtherSoldier, (SoldierHasLimitedVision(pSoldier) ? pOtherSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, pSoldier->sGridNo, pSoldier->bLevel, pSoldier ) ) + if ( PythSpacesAway( pOtherSoldier->sGridNo, pSoldier->sGridNo ) > DistanceVisible( pOtherSoldier, (SoldierHasLimitedVision(pSoldier) ? pOtherSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, pSoldier->sGridNo, pSoldier->bLevel ) ) { // if this guy can no longer see us, change to seen this turn HandleManNoLongerSeen( pOtherSoldier, pSoldier, &(pOtherSoldier->bOppList[ pSoldier->ubID ]), &(gbPublicOpplist[ pOtherSoldier->bTeam ][ pSoldier->ubID ] ) ); @@ -1832,7 +1844,7 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall bAware = TRUE; // then we look for him full viewing distance in EVERY direction - sDistVisible = DistanceVisible(pSoldier, (SoldierHasLimitedVision(pSoldier) ? pSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), 0, pOpponent->sGridNo, pOpponent->bLevel, pOpponent ); + sDistVisible = pSoldier->GetMaxDistanceVisible( pOpponent->sGridNo, pOpponent->bLevel ); //if (pSoldier->ubID == 0) //sprintf(gDebugStr,"ALREADY KNOW: ME %d him %d val %d",pSoldier->ubID,pOpponent->ubID,pSoldier->bOppList[pOpponent->ubID]); } @@ -1843,7 +1855,7 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall // BIG NOTE: must use desdir instead of direction, since in a projected // situation, the direction may still be changing if it's one of the first // few animation steps when this guy's turn to do his stepped look comes up - sDistVisible = DistanceVisible(pSoldier,pSoldier->bDesiredDirection,bDir, pOpponent->sGridNo, pOpponent->bLevel, pOpponent ); + sDistVisible = DistanceVisible(pSoldier,pSoldier->bDesiredDirection,bDir, pOpponent->sGridNo, pOpponent->bLevel ); //if (pSoldier->ubID == 0) //sprintf(gDebugStr,"dist visible %d: my dir %d to him %d",sDistVisible,pSoldier->bDesiredDirection,bDir); } @@ -1860,7 +1872,7 @@ INT16 ManLooksForMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, UINT8 ubCall { // and we can trace a line of sight to his x,y coordinates // must use the REAL opplist value here since we may or may not know of him - if (SoldierToSoldierLineOfSightTest(pSoldier,pOpponent,(UINT8)sDistVisible,bAware)) + if (SoldierToSoldierLineOfSightTest(pSoldier,pOpponent,bAware,(UINT8)sDistVisible)) { ManSeesMan(pSoldier,pOpponent,pOpponent->sGridNo,pOpponent->bLevel,MANLOOKSFORMAN,ubCaller); bSuccess = TRUE; @@ -5676,15 +5688,15 @@ void HearNoise(SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, UINT16 sGridNo, INT8 b fMuzzleFlash = TRUE; } } - - sDistVisible = DistanceVisible( pSoldier, (SoldierHasLimitedVision(pSoldier) ? pSoldier->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, sGridNo, bLevel, pSoldier ); + + sDistVisible = pSoldier->GetMaxDistanceVisible( sGridNo, bLevel ); if ( fMuzzleFlash ) { // turn flash on again MercPtrs[ ubNoiseMaker ]->fMuzzleFlash = TRUE; } - + if (PythSpacesAway(pSoldier->sGridNo,sGridNo) <= sDistVisible ) { // just use the XXadjustedXX center of the gridno @@ -5706,7 +5718,7 @@ void HearNoise(SOLDIERTYPE *pSoldier, UINT8 ubNoiseMaker, UINT16 sGridNo, INT8 b // skip LOS check if we had to turn and we're a tank. sorry Mr Tank, no looking out of the sides for you! if ( !( bHadToTurn && TANK( pSoldier ) ) ) { - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, TRUE, sDistVisible ) ) { // he can actually see the spot where the noise came from! bSourceSeen = TRUE; @@ -6485,7 +6497,6 @@ void RecalculateOppCntsDueToBecomingNeutral( SOLDIERTYPE * pSoldier ) void NoticeUnseenAttacker( SOLDIERTYPE * pAttacker, SOLDIERTYPE * pDefender, INT8 bReason ) { INT8 bOldOppList; - UINT8 ubTileSightLimit; BOOLEAN fSeesAttacker = FALSE; INT8 bDirection; BOOLEAN fMuzzleFlash = FALSE; @@ -6512,30 +6523,26 @@ void NoticeUnseenAttacker( SOLDIERTYPE * pAttacker, SOLDIERTYPE * pDefender, INT } bOldOppList = pDefender->bOppList[ pAttacker->ubID ]; - if ( PythSpacesAway( pAttacker->sGridNo, pDefender->sGridNo ) <= MaxDistanceVisible() ) + // check LOS, considering we are now aware of the attacker + // ignore muzzle flashes when must turning head + if ( pAttacker->fMuzzleFlash ) { - // check LOS, considering we are now aware of the attacker - // ignore muzzle flashes when must turning head - if ( pAttacker->fMuzzleFlash ) + bDirection = atan8( pDefender->sX,pDefender->sY, pAttacker->sX, pAttacker->sY ); + if ( pDefender->bDirection != bDirection && pDefender->bDirection != gOneCDirection[ bDirection ] && pDefender->bDirection != gOneCCDirection[ bDirection ] ) { - bDirection = atan8( pDefender->sX,pDefender->sY, pAttacker->sX, pAttacker->sY ); - if ( pDefender->bDirection != bDirection && pDefender->bDirection != gOneCDirection[ bDirection ] && pDefender->bDirection != gOneCCDirection[ bDirection ] ) - { - // temporarily turn off muzzle flash so DistanceVisible can be calculated without it - pAttacker->fMuzzleFlash = FALSE; - fMuzzleFlash = TRUE; - } + // temporarily turn off muzzle flash so DistanceVisible can be calculated without it + pAttacker->fMuzzleFlash = FALSE; + fMuzzleFlash = TRUE; } + } - ubTileSightLimit = (UINT8) DistanceVisible( pDefender, (SoldierHasLimitedVision(pDefender) ? pDefender->bDesiredDirection : DIRECTION_IRRELEVANT), 0, pAttacker->sGridNo, pAttacker->bLevel, pAttacker ); - if (SoldierToSoldierLineOfSightTest( pDefender, pAttacker, ubTileSightLimit, TRUE ) != 0) - { - fSeesAttacker = TRUE; - } - if ( fMuzzleFlash ) - { - pAttacker->fMuzzleFlash = TRUE; - } + if (SoldierToSoldierLineOfSightTest( pDefender, pAttacker, TRUE ) != 0) + { + fSeesAttacker = TRUE; + } + if ( fMuzzleFlash ) + { + pAttacker->fMuzzleFlash = TRUE; } if (fSeesAttacker) @@ -6646,7 +6653,7 @@ void CheckForAlertWhenEnemyDies( SOLDIERTYPE * pDyingSoldier ) // distance we "see" then depends on the direction he is located from us bDir = atan8(pSoldier->sX,pSoldier->sY,pDyingSoldier->sX,pDyingSoldier->sY); - sDistVisible = DistanceVisible( pSoldier, pSoldier->bDesiredDirection, bDir, pDyingSoldier->sGridNo, pDyingSoldier->bLevel, pDyingSoldier ); + sDistVisible = DistanceVisible( pSoldier, pSoldier->bDesiredDirection, bDir, pDyingSoldier->sGridNo, pDyingSoldier->bLevel ); sDistAway = PythSpacesAway( pSoldier->sGridNo, pDyingSoldier->sGridNo ); // if we see close enough to see the soldier @@ -6654,7 +6661,7 @@ void CheckForAlertWhenEnemyDies( SOLDIERTYPE * pDyingSoldier ) { // and we can trace a line of sight to his x,y coordinates // assume enemies are always aware of their buddies... - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pDyingSoldier->sGridNo, pDyingSoldier->bLevel, 0, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pDyingSoldier->sGridNo, pDyingSoldier->bLevel, 0, TRUE, sDistVisible ) ) { pSoldier->bAlertStatus = STATUS_RED; CheckForChangingOrders( pSoldier ); @@ -6787,9 +6794,9 @@ INT8 GetHighestVisibleWatchedLoc( UINT8 ubID ) { if ( gsWatchedLoc[ ubID ][ bLoop ] != NOWHERE && gubWatchedLocPoints[ ubID ][ bLoop ] > bHighestPoints ) { - sDistVisible = DistanceVisible( MercPtrs[ ubID ], (SoldierHasLimitedVision(MercPtrs[ ubID ]) ? MercPtrs[ ubID ]->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, gsWatchedLoc[ ubID ][ bLoop ], gbWatchedLocLevel[ ubID ][ bLoop ], MercPtrs[ubID] ); + sDistVisible = DistanceVisible( MercPtrs[ ubID ], (SoldierHasLimitedVision(MercPtrs[ ubID ]) ? MercPtrs[ ubID ]->bDesiredDirection : DIRECTION_IRRELEVANT), DIRECTION_IRRELEVANT, gsWatchedLoc[ ubID ][ bLoop ], gbWatchedLocLevel[ ubID ][ bLoop ] ); // look at standing height - if ( SoldierTo3DLocationLineOfSightTest( MercPtrs[ ubID ], gsWatchedLoc[ ubID ][ bLoop ], gbWatchedLocLevel[ ubID ][ bLoop ], 3, (UINT8) sDistVisible, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( MercPtrs[ ubID ], gsWatchedLoc[ ubID ][ bLoop ], gbWatchedLocLevel[ ubID ][ bLoop ], 3, TRUE, sDistVisible ) ) { bHighestLoc = bLoop; bHighestPoints = gubWatchedLocPoints[ ubID ][ bLoop ]; diff --git a/Tactical/opplist.h b/Tactical/opplist.h index f12ff4d4..7f033a5e 100644 --- a/Tactical/opplist.h +++ b/Tactical/opplist.h @@ -99,8 +99,8 @@ void DecideTrueVisibility(SOLDIERTYPE *pSoldier, UINT8 ubLocate); void AddOneOpponent(SOLDIERTYPE *pSoldier); void RemoveOneOpponent(SOLDIERTYPE *pSoldier); void UpdatePersonal(SOLDIERTYPE *pSoldier, UINT8 ubID, INT8 bNewOpplist, INT16 sGridno, INT8 bLevel); -INT16 MaxDistanceVisible( void ); -INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, INT16 sSubjectGridNo, INT8 bLevel, SOLDIERTYPE *pOther ); +INT16 MaxNormalDistanceVisible( void ); +INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir, INT16 sSubjectGridNo, INT8 bLevel ); void ResetLastKnownLocs(SOLDIERTYPE *ptr); void RecalculateOppCntsDueToNoLongerNeutral( SOLDIERTYPE * pSoldier ); void ReevaluateBestSightingPosition( SOLDIERTYPE * pSoldier, INT8 bInterruptDuelPts ); diff --git a/TacticalAI/AIMain.cpp b/TacticalAI/AIMain.cpp index b92fd553..c79787f7 100644 --- a/TacticalAI/AIMain.cpp +++ b/TacticalAI/AIMain.cpp @@ -2781,7 +2781,6 @@ void ManChecksOnFriends(SOLDIERTYPE *pSoldier) { UINT32 uiLoop; SOLDIERTYPE *pFriend; - INT16 sDistVisible; // THIS ROUTINE SHOULD ONLY BE CALLED FOR SOLDIERS ON STATUS GREEN or YELLOW @@ -2803,45 +2802,40 @@ void ManChecksOnFriends(SOLDIERTYPE *pSoldier) if (pFriend->ubID == pSoldier->ubID) continue; // next merc - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, pFriend->sGridNo, pFriend->bLevel, pFriend ); // if we can see far enough to see this friend - if (PythSpacesAway(pSoldier->sGridNo,pFriend->sGridNo) <= sDistVisible) + // and can trace a line of sight to his x,y coordinates + if (SoldierToSoldierLineOfSightTest(pSoldier, pFriend, TRUE)) { - // and can trace a line of sight to his x,y coordinates - //if (1) //*** SoldierToSoldierLineOfSightTest(pSoldier,pFriend,STRAIGHT,TRUE)) - if (SoldierToSoldierLineOfSightTest(pSoldier, pFriend, (UINT8)sDistVisible, TRUE)) + // if my friend is in battle or something is clearly happening there + if ((pFriend->bAlertStatus >= STATUS_RED) || pFriend->bUnderFire || (pFriend->bLife < OKLIFE)) { - // if my friend is in battle or something is clearly happening there - if ((pFriend->bAlertStatus >= STATUS_RED) || pFriend->bUnderFire || (pFriend->bLife < OKLIFE)) - { #ifdef DEBUGDECISIONS - STR16 tempstr; - sprintf(tempstr,"%s sees %s on alert, goes to RED ALERT!",pSoldier->name,pFriend->name ); - AIPopMessage(tempstr); + STR16 tempstr; + sprintf(tempstr,"%s sees %s on alert, goes to RED ALERT!",pSoldier->name,pFriend->name ); + AIPopMessage(tempstr); #endif - pSoldier->bAlertStatus = STATUS_RED; - CheckForChangingOrders(pSoldier); - SetNewSituation( pSoldier ); - break; // don't bother checking on any other friends - } - else + pSoldier->bAlertStatus = STATUS_RED; + CheckForChangingOrders(pSoldier); + SetNewSituation( pSoldier ); + break; // don't bother checking on any other friends + } + else + { + // if he seems suspicious or acts like he thought he heard something + // and I'm still on status GREEN + if ((pFriend->bAlertStatus == STATUS_YELLOW) && + (pSoldier->bAlertStatus < STATUS_YELLOW)) { - // if he seems suspicious or acts like he thought he heard something - // and I'm still on status GREEN - if ((pFriend->bAlertStatus == STATUS_YELLOW) && - (pSoldier->bAlertStatus < STATUS_YELLOW)) - { #ifdef TESTVERSION - sprintf(tempstr,"TEST MSG: %s sees %s listening, goes to YELLOW ALERT!",pSoldier->name,ExtMen[pFriend->ubID].name); - PopMessage(tempstr); + sprintf(tempstr,"TEST MSG: %s sees %s listening, goes to YELLOW ALERT!",pSoldier->name,ExtMen[pFriend->ubID].name); + PopMessage(tempstr); #endif - pSoldier->bAlertStatus = STATUS_YELLOW; // also get suspicious - SetNewSituation( pSoldier ); - pSoldier->sNoiseGridno = pFriend->sGridNo; // pretend FRIEND made noise - pSoldier->ubNoiseVolume = 3; // remember this for 3 turns - // keep check other friends, too, in case any are already on RED - } + pSoldier->bAlertStatus = STATUS_YELLOW; // also get suspicious + SetNewSituation( pSoldier ); + pSoldier->sNoiseGridno = pFriend->sGridNo; // pretend FRIEND made noise + pSoldier->ubNoiseVolume = 3; // remember this for 3 turns + // keep check other friends, too, in case any are already on RED } } } diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index 159eac8e..c0bc4181 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -1034,7 +1034,7 @@ INT16 ClosestReachableDisturbance(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK, bLevel = *pbNoiseLevel; // if we are not NEAR the noise gridno... - if ( pSoldier->bLevel != bLevel || PythSpacesAway( pSoldier->sGridNo, sGridNo ) >= 6 || SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, (UINT8) MaxDistanceVisible(), FALSE ) == 0 ) + if ( pSoldier->bLevel != bLevel || PythSpacesAway( pSoldier->sGridNo, sGridNo ) >= 6 || SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, bLevel, 0, FALSE ) == 0 ) // if we are NOT there (at the noise gridno) // if (sGridNo != pSoldier->sGridNo) { diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index ee59e76c..a0c6e1b2 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -2469,7 +2469,8 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s RearrangePocket(pSoldier, HANDPOS, pBestShot->bWeaponIn, TEMPORARILY); } - if ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxDistanceVisible() ) || pSoldier->bOrders == SNIPER ) ) || + //if ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > pSoldier->MaxDistanceVisible(pBestShot->sTarget, pBestShot->bTargetLevel) ) || pSoldier->bOrders == SNIPER ) ) || + if ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxNormalDistanceVisible() ) || pSoldier->bOrders == SNIPER ) ) || (suppressionFire && IsGunAutofireCapable(pSoldier,pBestShot->bWeaponIn ) && GetMagSize(pObj) > 30 && pObj->ItemData.Gun.ubGunShotsLeft > 20 )) { // get the minimum cost to attack with this item diff --git a/TacticalAI/CreatureDecideAction.cpp b/TacticalAI/CreatureDecideAction.cpp index ec435347..894cbeb7 100644 --- a/TacticalAI/CreatureDecideAction.cpp +++ b/TacticalAI/CreatureDecideAction.cpp @@ -848,7 +848,7 @@ INT8 CreatureDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // if soldier is not already facing in that direction, // and the opponent is close enough that he could possibly be seen // note, have to change this to use the level returned from ClosestKnownOpponent - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sClosestOpponent, 0, pSoldier ); + sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sClosestOpponent, 0 ); if ((pSoldier->bDirection != ubOpponentDir) && (PythSpacesAway(pSoldier->sGridNo,sClosestOpponent) <= sDistVisible)) { diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 90df3f50..c5bd37cb 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -747,7 +747,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier) } } //else if ( (gTacticalStatus.bBoxingState == PRE_BOXING || gTacticalStatus.bBoxingState == BOXING) && ( PythSpacesAway( pSoldier->sGridNo, CENTER_OF_RING ) <= MaxDistanceVisible() ) ) - else if ( PythSpacesAway( pSoldier->sGridNo, CENTER_OF_RING ) <= MaxDistanceVisible() ) + else if ( PythSpacesAway( pSoldier->sGridNo, CENTER_OF_RING ) <= MaxNormalDistanceVisible() ) { UINT8 ubRingDir; // face ring! @@ -1356,7 +1356,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) // and the noise source is close enough that it could possibly be seen if ( !gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints ) { - if ((pSoldier->bDirection != ubNoiseDir) && PythSpacesAway(pSoldier->sGridNo,sNoiseGridNo) <= MaxDistanceVisible() ) + if ((pSoldier->bDirection != ubNoiseDir) && PythSpacesAway(pSoldier->sGridNo,sNoiseGridNo) <= pSoldier->GetMaxDistanceVisible(sNoiseGridNo) ) { // set base chance according to orders if ((pSoldier->bOrders == STATIONARY) || (pSoldier->bOrders == ONGUARD) ) @@ -1534,7 +1534,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) // IF WE ARE MILITIA/CIV IN REALTIME, CLOSE TO NOISE, AND CAN SEE THE SPOT WHERE THE NOISE CAME FROM, FORGET IT if ( fReachable && !fClimb && !gfTurnBasedAI && (pSoldier->bTeam == MILITIA_TEAM || pSoldier->bTeam == CIV_TEAM )&& PythSpacesAway( pSoldier->sGridNo, sNoiseGridNo ) < 5 ) { - if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sNoiseGridNo, pSoldier->bLevel, 0, 6, TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sNoiseGridNo, pSoldier->bLevel, 0, TRUE, 6 ) ) { // set reachable to false so we don't investigate fReachable = FALSE; @@ -2200,7 +2200,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // spotters haven't already been called for, then DO SO! if ( (BestThrow.bWeaponIn != NO_SLOT) && - (CalcMaxTossRange( pSoldier, pSoldier->inv[BestThrow.bWeaponIn].usItem, TRUE ) > MaxDistanceVisible() ) && + (CalcMaxTossRange( pSoldier, pSoldier->inv[BestThrow.bWeaponIn].usItem, TRUE ) > MaxNormalDistanceVisible() ) && (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && (gTacticalStatus.ubSpottersCalledForBy == NOBODY)) { @@ -2252,7 +2252,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) if (BestShot.bWeaponIn != NO_SLOT) { OBJECTTYPE * gun = &pSoldier->inv[BestShot.bWeaponIn]; DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: men in sector %d, ubspotters called by %d, nobody %d",gTacticalStatus.Team[pSoldier->bTeam].bMenInSector,gTacticalStatus.ubSpottersCalledForBy,NOBODY )); - if ( ( ( IsScoped(gun) && GunRange(gun) > MaxDistanceVisible() ) || pSoldier->bOrders == SNIPER ) && + //if ( ( ( IsScoped(gun) && GunRange(gun) > pSoldier->GetMaxDistanceVisible(BestShot.sTarget, BestShot.bTargetLevel) ) || pSoldier->bOrders == SNIPER ) && + if ( ( ( IsScoped(gun) && GunRange(gun) > MaxNormalDistanceVisible() ) || pSoldier->bOrders == SNIPER ) && (gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) && (gTacticalStatus.ubSpottersCalledForBy == NOBODY)) @@ -2613,7 +2614,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,AP_PRONE,AI_ACTION_SEEK_OPPONENT,0); - if ( LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, tempGridNo, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) + if ( LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, tempGridNo, pSoldier->bLevel, TRUE) ) { // reserve APs for a possible crouch plus a shot pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); @@ -2830,7 +2831,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,AP_CROUCH, AI_ACTION_SEEK_OPPONENT,0); //pSoldier->numFlanks = 0; - if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) + if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, TRUE ) ) { // reserve APs for a possible crouch plus a shot pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); @@ -2867,7 +2868,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) else { // let's be a bit cautious about going right up to a location without enough APs to shoot - if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, (UINT8) MaxDistanceVisible(), TRUE ) ) + if ( PythSpacesAway( pSoldier->usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->usActionData, pSoldier->bLevel, sClosestDisturbance, pSoldier->bLevel, TRUE ) ) { // reserve APs for a possible crouch plus a shot pSoldier->usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + AP_CROUCH), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS ); @@ -2901,7 +2902,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { // take a look at our highest watch point... if it's still visible, turn to face it and then wait bHighestWatchLoc = GetHighestVisibleWatchedLoc( pSoldier->ubID ); - //sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ], gbWatchedLocLevel[ pSoldier->ubID ][ bHighestWatchLoc ] ); + //sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, gsWatchedLoc[ pSoldier->ubID ][ bHighestWatchLoc ] ); if ( bHighestWatchLoc != -1 ) { // see if we need turn to face that location @@ -3160,7 +3161,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // if soldier is not already facing in that direction, // and the opponent is close enough that he could possibly be seen // note, have to change this to use the level returned from ClosestKnownOpponent - sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sClosestOpponent, 0, pSoldier ); + sDistVisible = DistanceVisible( pSoldier, DIRECTION_IRRELEVANT, DIRECTION_IRRELEVANT, sClosestOpponent, 0 ); if ((pSoldier->bDirection != ubOpponentDir) && (PythSpacesAway(pSoldier->sGridNo,sClosestOpponent) <= sDistVisible)) { @@ -3338,7 +3339,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) { sClosestOpponent = ClosestKnownOpponent(pSoldier, NULL, NULL); - if ( (sClosestOpponent != NOWHERE && PythSpacesAway( pSoldier->sGridNo, sClosestOpponent ) < (MaxDistanceVisible() * 3) / 2 ) || PreRandom( 4 ) == 0 ) + //if ( (sClosestOpponent != NOWHERE && PythSpacesAway( pSoldier->sGridNo, sClosestOpponent ) < (MaxNormalDistanceVisible() * 3) / 2 ) || PreRandom( 4 ) == 0 ) + if ( (sClosestOpponent != NOWHERE && PythSpacesAway( pSoldier->sGridNo, sClosestOpponent ) < (pSoldier->GetMaxDistanceVisible(sClosestOpponent) * 3) / 2 ) || PreRandom( 4 ) == 0 ) { if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints) { diff --git a/TacticalAI/Knowledge.cpp b/TacticalAI/Knowledge.cpp index 8428da17..7a784507 100644 --- a/TacticalAI/Knowledge.cpp +++ b/TacticalAI/Knowledge.cpp @@ -122,7 +122,7 @@ void CallEldinTo( INT16 sGridNo ) pSoldier = FindSoldierByProfileID( ELDIN, FALSE ); if ( pSoldier && pSoldier->bActive && pSoldier->bInSector && pSoldier->bLife >= OKLIFE && (pSoldier->bAlertStatus == STATUS_GREEN || pSoldier->ubNoiseVolume < (MAX_MISC_NOISE_DURATION / 2) ) ) { - if ( SoldierToLocationLineOfSightTest( pSoldier, sGridNo, (UINT8) MaxDistanceVisible(), TRUE ) ) + if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, 0, 0, TRUE ) ) { // sees the player now! TriggerNPCWithIHateYouQuote( ELDIN ); @@ -229,7 +229,7 @@ INT16 MostImportantNoiseHeard( SOLDIERTYPE *pSoldier, INT32 *piRetValue, BOOLEAN // if any "misc. noise" was also heard recently if (pSoldier->sNoiseGridno != NOWHERE) { - if ( pSoldier->bNoiseLevel != pSoldier->bLevel || PythSpacesAway( pSoldier->sGridNo, pSoldier->sNoiseGridno ) >= 6 || SoldierTo3DLocationLineOfSightTest( pSoldier, pSoldier->sNoiseGridno, pSoldier->bNoiseLevel, 0, (UINT8) MaxDistanceVisible(), FALSE ) == 0 ) + if ( pSoldier->bNoiseLevel != pSoldier->bLevel || PythSpacesAway( pSoldier->sGridNo, pSoldier->sNoiseGridno ) >= 6 || SoldierTo3DLocationLineOfSightTest( pSoldier, pSoldier->sNoiseGridno, pSoldier->bNoiseLevel, 0, FALSE, 255 ) == 0 ) { // calculate how far this noise was, and its relative "importance" iDistAway = SpacesAway(pSoldier->sGridNo,pSoldier->sNoiseGridno); @@ -258,7 +258,7 @@ INT16 MostImportantNoiseHeard( SOLDIERTYPE *pSoldier, INT32 *piRetValue, BOOLEAN if (*psNoiseGridNo != NOWHERE) { // if we are NOT there (at the noise gridno) - if ( *pbNoiseLevel != pSoldier->bLevel || PythSpacesAway( pSoldier->sGridNo, *psNoiseGridNo ) >= 6 || SoldierTo3DLocationLineOfSightTest( pSoldier, *psNoiseGridNo, *pbNoiseLevel, 0, (UINT8) MaxDistanceVisible(), FALSE ) == 0 ) + if ( *pbNoiseLevel != pSoldier->bLevel || PythSpacesAway( pSoldier->sGridNo, *psNoiseGridNo ) >= 6 || SoldierTo3DLocationLineOfSightTest( pSoldier, *psNoiseGridNo, *pbNoiseLevel, 0, FALSE, 255 ) == 0 ) { // calculate how far this noise was, and its relative "importance" iDistAway = SpacesAway(pSoldier->sGridNo,*psNoiseGridNo);