From 48088508149313d1f3dd6d358e8604c1e4309211 Mon Sep 17 00:00:00 2001 From: silversurfer Date: Sat, 7 Sep 2013 12:10:45 +0000 Subject: [PATCH] Bugfix: Feature Swap merc faces When swapping merc faces in tactical the game will now rebuild the mercs squad. Changed NCTH behaviour for lasers: When USE_NEW_CTH_CALCULATION = TRUE in Ja2_Options.ini the game now uses the item property now for a laser specific bonus instead of . This bonus is a percentage reduction of the base aperture in NCTH. This functionality will only be used if one of the following new parameters in CTHConstants.ini is NOT 0. LASER_PERFORMANCE_BONUS_HIP LASER_PERFORMANCE_BONUS_IRON LASER_PERFORMANCE_BONUS_SCOPE This functionality also affects the laser property that is displayed in UDB. Changed NCTH behaviour for Iron Sights and other 1x sights: Iron sights and other 1x sights can now receive a bonus in NCTH to make them more useful compared to scopes. This bonus is a percentage reduction of the base aperture just like lasers can do. There is a new parameter in CTHConstants.ini for this: IRON_SIGHT_PERFORMANCE_BONUS git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6370 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 8 +- GameSettings.h | 4 + Tactical/Handle UI.h | 1 + Tactical/Interface Enhanced.cpp | 95 +++++++++++++++++++---- Tactical/Interface.cpp | 131 +++++++++++++++++++++++--------- Tactical/Items.cpp | 28 ++++++- Tactical/Items.h | 2 + Tactical/LOS.cpp | 50 +++++++++++- Tactical/Turn Based Input.cpp | 2 + Tactical/Weapons.cpp | 30 +++++--- Utils/Text.h | 2 +- Utils/_ChineseText.cpp | 1 + Utils/_DutchText.cpp | 1 + Utils/_EnglishText.cpp | 1 + Utils/_FrenchText.cpp | 1 + Utils/_GermanText.cpp | 1 + Utils/_ItalianText.cpp | 1 + Utils/_PolishText.cpp | 1 + Utils/_RussianText.cpp | 1 + Utils/_TaiwaneseText.cpp | 1 + 20 files changed, 295 insertions(+), 67 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index 60b3afedc..503d6d1ee 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -52,7 +52,7 @@ #define GAME_SETTINGS_FILE "Ja2_Settings.INI" -#define GAME_EXTERNAL_OPTIONS_FILE "Ja2_Options.ini" +#define GAME_EXTERNAL_OPTIONS_FILE "Ja2_Options.ini" #define AP_BP_CONSTANTS_FILE "APBPConstants.ini" @@ -1377,7 +1377,7 @@ void LoadGameExternalOptions() gGameExternalOptions.fAccessOtherMercInventories = iniReader.ReadBoolean("Tactical Gameplay Settings","ACCESS_OTHER_MERC_INVENTORIES", TRUE); gGameExternalOptions.fBackPackWeightLowersAP = iniReader.ReadBoolean("Tactical Gameplay Settings","BACKPACKWEIGHT_LOWERS_AP", TRUE); - + //################# Tactical Cover System Settings ################## // CPT: Cover System Settings @@ -2626,6 +2626,10 @@ void LoadCTHConstants() CIniReader iniReader(CTH_COEFFICIENTS_FILE); gGameCTHConstants.NORMAL_SHOOTING_DISTANCE = iniReader.ReadInteger("General","NORMAL_SHOOTING_DISTANCE", 70, 10, 10000); + gGameCTHConstants.IRON_SIGHT_PERFORMANCE_BONUS = iniReader.ReadFloat("General","IRON_SIGHT_PERFORMANCE_BONUS", 0.0f, -50.0f, 50.0f); + gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP = iniReader.ReadFloat("General","LASER_PERFORMANCE_BONUS_HIP", 0.0f, 0.0f, 50.0f); + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON = iniReader.ReadFloat("General","LASER_PERFORMANCE_BONUS_IRON", 0.0f, 0.0f, 50.0f); + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE = iniReader.ReadFloat("General","LASER_PERFORMANCE_BONUS_SCOPE", 0.0f, 0.0f, 50.0f); gGameCTHConstants.DEGREES_MAXIMUM_APERTURE = iniReader.ReadFloat("General", "DEGREES_MAXIMUM_APERTURE", 15.0, 0.0, 22.5); gGameCTHConstants.RANGE_COEFFICIENT = iniReader.ReadFloat("General", "RANGE_COEFFICIENT", 2.0, 0.001f, 100.0); gGameCTHConstants.GRAVITY_COEFFICIENT = iniReader.ReadFloat("General", "GRAVITY_COEFFICIENT", 1.0, 0.001f, 100.0); diff --git a/GameSettings.h b/GameSettings.h index 89cf074b1..7d76179c1 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1545,6 +1545,10 @@ typedef struct typedef struct { UINT32 NORMAL_SHOOTING_DISTANCE; // Distance at which 1x magnification is 100% effective. This is a major component of the entire shooting mechanism. + FLOAT IRON_SIGHT_PERFORMANCE_BONUS; // percentage bonus to base aperture size for iron sights + FLOAT LASER_PERFORMANCE_BONUS_HIP; // percentage bonus to base aperture size for laser pointers when shooting from hip + FLOAT LASER_PERFORMANCE_BONUS_IRON; // percentage bonus to base aperture size for laser pointers when using iron sights + FLOAT LASER_PERFORMANCE_BONUS_SCOPE; // percentage bonus to base aperture size for laser pointers when using scopes FLOAT DEGREES_MAXIMUM_APERTURE; // Maximum possible aperture for a 100% muzzle sway shot. Decrease to make all shots more accurate. FLOAT RANGE_COEFFICIENT; // Determines maximum range which decides when gravity forces bullets to drop FLOAT GRAVITY_COEFFICIENT; // Changes the way gravity works in the game. Higher values mean bullets don't drop as quickly after reaching max range. diff --git a/Tactical/Handle UI.h b/Tactical/Handle UI.h index 9ff3eafb8..db0ec0b6c 100644 --- a/Tactical/Handle UI.h +++ b/Tactical/Handle UI.h @@ -229,6 +229,7 @@ typedef struct UINT8 MuzzleSwayPercentage; FLOAT ScopeMagFactor; FLOAT ProjectionFactor; + INT16 iBestLaserRange; FLOAT FinalMagFactor; INT32 iShooterGridNo; INT32 iTargetGridNo; diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 09f69d67f..f676e34a0 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -1605,8 +1605,11 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } /////////////////// PROJECTION FACTOR - if (UsingNewCTHSystem() == true && - (Item[gpItemDescObject->usItem].projectionfactor > 1.0 || GetProjectionFactor( gpItemDescObject ) > 1.0) ) + // with the reworked NCTH code and the laser performance factor we will display BestLaserRange instead of ProjectionFactor but we still need the mouse region + if (UsingNewCTHSystem() == true && + ( (Item[gpItemDescObject->usItem].projectionfactor > 1.0 || GetProjectionFactor( gpItemDescObject ) > 1.0) || + ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) ) ) { ubRegionOffset = 6; MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + ubRegionOffset ] ); @@ -2957,7 +2960,29 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// PROJECTION FACTOR - if (GetProjectionFactor( gpItemDescObject ) > 1.0 ) + // with the reworked NCTH code and the laser performance factor we will display BestLaserRange instead of ProjectionFactor + if ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) + { + if( UsingNewCTHSystem() == true ) + { + if (cnt >= sFirstLine && cnt < sLastLine) + { + if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH)) + { + swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 64 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 14 ]); + } + else + { + swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 64 ], szUDBAdvStatsExplanationsTooltipText[ 14 ]); + } + SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr ); + MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] ); + } + cnt++; + } + } + else if (GetProjectionFactor( gpItemDescObject ) > 1.0 ) { if( UsingNewCTHSystem() == true ) { @@ -4100,8 +4125,11 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject ) } //////////////////// PROJECTION FACTOR + // with the reworked NCTH code and the laser performance factor we will display BestLaserRange instead of ProjectionFactor but we use the same icon if (UsingNewCTHSystem() == true && - (Item[gpItemDescObject->usItem].projectionfactor > 1.0 || GetProjectionFactor( gpItemDescObject ) > 1.0) ) + ( (Item[gpItemDescObject->usItem].projectionfactor > 1.0 || GetProjectionFactor( gpItemDescObject ) > 1.0) || + ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) ) ) { ubNumLine = 6; BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 14, gItemDescGenRegions[ubNumLine][0].sLeft+sOffsetX, gItemDescGenRegions[ubNumLine][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); @@ -4819,8 +4847,11 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// PROJECTION FACTOR + // with the reworked NCTH code and the laser performance factor we will display BestLaserRange instead of ProjectionFactor but we use the same icon if (cnt-sFirstLine < sLastLine && - GetProjectionFactor( gpItemDescObject ) > 1.0 ) + ( GetProjectionFactor( gpItemDescObject ) > 1.0 || + ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) ) ) { if( UsingNewCTHSystem() == true ) { @@ -6267,21 +6298,40 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject ) } ///////////////// (LASER) PROJECTION FACTOR + // with the reworked NCTH code and the laser performance factor we will display BestLaserRange instead of ProjectionFactor if (UsingNewCTHSystem() == true && - (Item[gpItemDescObject->usItem].projectionfactor > 1.0 || GetProjectionFactor( gpItemDescObject ) > 1.0) ) + ( (Item[gpItemDescObject->usItem].projectionfactor > 1.0 || GetProjectionFactor( gpItemDescObject ) > 1.0) || + ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) ) ) { // Set line to draw into ubNumLine = 6; // Set Y coordinates sTop = gItemDescGenRegions[ubNumLine][1].sTop; sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop; + FLOAT iProjectionValue = 0; + FLOAT iProjectionModifier = 0; + FLOAT iFinalProjectionValue = 0; - // Get base Projection value - FLOAT iProjectionValue = __max(1.0f, Item[ gpItemDescObject->usItem ].projectionfactor); - // Get best Projection value - FLOAT iProjectionModifier = GetProjectionFactor( gpItemDescObject ); - // Get final Projection value - FLOAT iFinalProjectionValue = __max( iProjectionValue, iProjectionModifier ); + if ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) + { + // Get base laser range + iProjectionValue = __max(1.0f, Item[ gpItemDescObject->usItem ].bestlaserrange / CELL_X_SIZE); + // Get best laser range + iProjectionModifier = ((FLOAT)GetBestLaserRange( gpItemDescObject ) / CELL_X_SIZE); + // Get final laser range + iFinalProjectionValue = __max( iProjectionValue, iProjectionModifier ); + } + else + { + // Get base Projection value + iProjectionValue = __max(1.0f, Item[ gpItemDescObject->usItem ].projectionfactor); + // Get best Projection value + iProjectionModifier = GetProjectionFactor( gpItemDescObject ); + // Get final Projection value + iFinalProjectionValue = __max( iProjectionValue, iProjectionModifier ); + } // Print base value SetFontForeground( 5 ); @@ -9490,11 +9540,21 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) cnt++; } + BOOLEAN bNewCode = FALSE; ///////////////////// PROJECTION FACTOR - iFloatModifier[0] = GetProjectionFactor( gpItemDescObject ); + // with the reworked NCTH code and the laser performance factor we will display BestLaserRange instead of ProjectionFactor + if ( gGameExternalOptions.fUseNewCTHCalculation && GetBestLaserRange( gpItemDescObject ) > 0 + && (gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) + { + iFloatModifier[0] = ((FLOAT)GetBestLaserRange( gpItemDescObject ) / CELL_X_SIZE); + bNewCode = TRUE; + } + else + iFloatModifier[0] = GetProjectionFactor( gpItemDescObject ); + iFloatModifier[1] = iFloatModifier[0]; iFloatModifier[2] = iFloatModifier[0]; - if (iFloatModifier[0] > 1.0 && UsingNewCTHSystem() == true ) + if ( UsingNewCTHSystem() == true && (iFloatModifier[0] > 1.0 || bNewCode) ) { if (cnt >= sFirstLine && cnt < sLastLine) { @@ -9508,10 +9568,13 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) SetFontForeground( 5 ); sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft; sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft; - if (iFloatModifier[cnt2] > 1.0) + if (iFloatModifier[cnt2] > 1.0 || bNewCode) { SetFontForeground( ITEMDESC_FONTPOSITIVE ); - swprintf( pStr, L"%3.1fx", iFloatModifier[cnt2] ); + if ( bNewCode ) + swprintf( pStr, L"%3.0f", iFloatModifier[cnt2] ); + else + swprintf( pStr, L"%3.1fx", iFloatModifier[cnt2] ); FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY); } else diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp index e05f6df49..11b599a8d 100644 --- a/Tactical/Interface.cpp +++ b/Tactical/Interface.cpp @@ -61,6 +61,7 @@ // HEADROCK HAM 4: Included for new CTH indicator #include "weapons.h" #include "Map Screen Interface.h" // added by Flugente for SquadNames + #include "environment.h" #endif @@ -2273,11 +2274,11 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID ) if ( zEnemyRank[iCounter2].Stats == 0 && pSoldier->stats.bExpLevel == zEnemyRank[iCounter2].ExpLevel ) { swprintf(NameStr, zEnemyRank[iCounter2].szCurRank); - + SetFont( TINYFONT1 ); SetFontBackground( FONT_MCOLOR_BLACK ); SetFontForeground( FONT_YELLOW ); - + // need to adjust sYPos because default position already occupied by the name if ( gGameExternalOptions.fSoldierProfiles_Enemy && pSoldier->usSoldierProfile || gGameExternalOptions.fEnemyNames ) FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 10 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY ); @@ -2451,6 +2452,54 @@ BOOLEAN DrawCTHIndicator() // Calculate the size of a "normal" aperture. This is how wide a shot can go at 1x Normal Distance. FLOAT iBasicAperture = (FLOAT)((sin(ddMaxAngleRadians) * gGameCTHConstants.NORMAL_SHOOTING_DISTANCE) * 2); // The *2 compensates for the difference between CellXY and ScreenXY + // when using the reworked NCTH code we do additional calculations for iron sights and lasers + if (gGameExternalOptions.fUseNewCTHCalculation) + { + // iron sights can get a percentage bonus to make them overall better but only when not shooting from hip + if ( gCTHDisplay.ScopeMagFactor <= 1.0 && !pSoldier->IsValidAlternativeFireMode( pSoldier->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) ) + + iBasicAperture = iBasicAperture * (FLOAT)( (100 - gGameCTHConstants.IRON_SIGHT_PERFORMANCE_BONUS) / 100); + + // laser pointers can provide a percentage bonus to base aperture + if ( gCTHDisplay.iBestLaserRange > 0 + && ( gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) + { + INT8 bLightLevel = LightTrueLevel(gCTHDisplay.iTargetGridNo, gsInterfaceLevel ); + INT32 iMaxLaserRange = ( gCTHDisplay.iBestLaserRange*( 2*bLightLevel + 3*NORMAL_LIGHTLEVEL_NIGHT - 5*NORMAL_LIGHTLEVEL_DAY ) ) / ( 2 * ( NORMAL_LIGHTLEVEL_NIGHT - NORMAL_LIGHTLEVEL_DAY ) ); + + // laser only has effect when in range + if ( iMaxLaserRange > d2DDistance ) + { + FLOAT fLaserBonus = 0; + // which bonus do we want to apply? + if ( pSoldier->IsValidAlternativeFireMode( pSoldier->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) ) + // shooting from hip + fLaserBonus = gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP; + else if ( gCTHDisplay.ScopeMagFactor <= 1.0 ) + // using iron sights or other 1x sights + fLaserBonus = gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON; + else + // must be using a scope + fLaserBonus = gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE; + + // light level influences how easy it is to spot the laser dot on the target + FLOAT fBrightnessModifier = 1.0 - ( (FLOAT)(bLightLevel - SHADE_MAX) / (FLOAT)(SHADE_MIN - SHADE_MAX) ); + + // laser fully efficient + if ( gCTHDisplay.iBestLaserRange > d2DDistance ) + // apply full bonus + iBasicAperture = iBasicAperture * (FLOAT)( (100 - (fLaserBonus * fBrightnessModifier)) / 100); + else + { + // beyond BestLaserRange laser bonus drops linearly to 0 + FLOAT fEffectiveLaserRatio = (FLOAT)(iMaxLaserRange - d2DDistance) / (FLOAT)(iMaxLaserRange - gCTHDisplay.iBestLaserRange); + // apply partial bonus + iBasicAperture = iBasicAperture * (FLOAT)( (100 - (fLaserBonus * fBrightnessModifier * fEffectiveLaserRatio)) / 100); + } + } + } + } + // Calculate the Maximum Aperture. This is the margin of error for the "worst" shot we can have given the // target's actual distance. This will later be used to draw the Outer Circle around the target. FLOAT iMaxAperture = iBasicAperture * iDistanceRatio; @@ -3152,18 +3201,18 @@ BOOLEAN DrawCTHIndicator() DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBar ); // Draw a border circle which is 1 point wider - curX = (INT16)((iMaxAperture+1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - curY = (INT16)(((iMaxAperture * dVerticalBias)+1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curX = (INT16)((iMaxAperture+1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curY = (INT16)(((iMaxAperture * dVerticalBias)+1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - if (curX != firstX || curY != firstY) - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); +// if (curX != firstX || curY != firstY) +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); // Draw a border circle which is 1 point narrower - curX = (INT16)((iMaxAperture-1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - curY = (INT16)(((iMaxAperture * dVerticalBias)-1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curX = (INT16)((iMaxAperture-1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curY = (INT16)(((iMaxAperture * dVerticalBias)-1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - if (curX != firstX || curY != firstY) - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); +// if (curX != firstX || curY != firstY) +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); } Circ = (INT32)((iAperture * RADIANS_IN_CIRCLE) * dVerticalBias); @@ -3178,18 +3227,18 @@ BOOLEAN DrawCTHIndicator() DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBar ); // Draw a border circle which is 1 point wider - curX = (INT16)((iAperture+1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - curY = (INT16)(((iAperture * dVerticalBias)+1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curX = (INT16)((iAperture+1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curY = (INT16)(((iAperture * dVerticalBias)+1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - if (curX != firstX || curY != firstY) - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); +// if (curX != firstX || curY != firstY) +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); // Draw a border circle which is 1 point narrower - curX = (INT16)((iAperture-1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - curY = (INT16)(((iAperture * dVerticalBias)-1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curX = (INT16)((iAperture-1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); +// curY = (INT16)(((iAperture * dVerticalBias)-1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ)); - if (curX != firstX || curY != firstY) - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); +// if (curX != firstX || curY != firstY) +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder ); } // Aperture Crosshairs @@ -3199,18 +3248,25 @@ BOOLEAN DrawCTHIndicator() DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, sStartScreenY+(INT16)zOffset, usCApertureBar ); DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, sStartScreenY+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBar ); // Darker borders - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+2)+(INT16)zOffset, usCApertureBorder ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+2)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+2)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+2)+(INT16)zOffset, usCApertureBorder ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-2)+(INT16)zOffset, usCApertureBorder ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-2)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-2)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-2)+(INT16)zOffset, usCApertureBorder ); + + // Darker borders + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBorder ); + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBorder ); + + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBorder ); + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBorder ); } for (INT16 cnt = (INT16)(iAperture * dVerticalBias); cnt <= (INT16)((iAperture * dVerticalBias) + uiApertureBarLength); cnt++) @@ -3219,18 +3275,25 @@ BOOLEAN DrawCTHIndicator() DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar ); DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar ); // Darker borders - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+2, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+2, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+2, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+2, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder ); + +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-2, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder ); +// DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-2, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder ); + + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder ); + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder ); + + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder ); + DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-2, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder ); - DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-2, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder ); } } diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index df09cdc3f..76aaffbeb 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -3128,7 +3128,7 @@ UINT32 CalculateCarriedWeight( SOLDIERTYPE * pSoldier ) { ubStrengthForCarrying = (ubStrengthForCarrying * (100 + gSkillTraitValues.ubBBCarryWeightBonus) / 100); // plus one third } - + ubStrengthForCarrying = (ubStrengthForCarrying * (100 + pSoldier->GetBackgroundValue(BG_PERC_CARRYSTRENGTH)) / 100); // for now, assume soldiers can carry 1/2 their strength in KGs without penalty. @@ -9406,7 +9406,7 @@ BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs pSoldier->bSoldierFlagMask |= SOLDIER_COVERT_SOLDIER; if ( pSoldier->bTeam == OUR_TEAM ) - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_DISGUISED_AS_SOLDIER], pSoldier->GetName() ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_DISGUISED_AS_SOLDIER], pSoldier->GetName() ); break; } @@ -9418,7 +9418,7 @@ BOOLEAN ApplyClothes( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, BOOLEAN fUseAPs pSoldier->bSoldierFlagMask |= SOLDIER_COVERT_CIV; if ( pSoldier->bTeam == OUR_TEAM ) - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_DISGUISED_AS_CIVILIAN], pSoldier->GetName() ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szCovertTextStr[STR_COVERT_DISGUISED_AS_CIVILIAN], pSoldier->GetName() ); } // reevaluate sight - otherwise we could hide by changing clothes in plain sight! @@ -13353,7 +13353,7 @@ INT16 GetWornStealth( SOLDIERTYPE * pSoldier ) // Add some default stealth ability to mercs with STEALTHY trait - SANDRO if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_NT )) - ttl += gSkillTraitValues.ubSTStealthBonus; + ttl += gSkillTraitValues.ubSTStealthBonus; ttl += pSoldier->GetBackgroundValue(BG_PERC_STEALTH); @@ -13499,6 +13499,26 @@ INT16 GetAverageBestLaserRange( OBJECTTYPE * pObj ) return( bonus ); } +// get the best laser range from the weapon and attachments +INT16 GetBestLaserRange( OBJECTTYPE * pObj ) +{ + INT16 range=0; + + if (Item[pObj->usItem].bestlaserrange > 0) + { + range = Item[pObj->usItem].bestlaserrange; + } + for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) + { + if (Item[iter->usItem].bestlaserrange > range && iter->exists()) + { + range = Item[iter->usItem].bestlaserrange; + } + } + + return( range ); +} + // HEADROCK: This function determines the bipod bonii of the gun or its attachments INT16 GetBipodBonus( OBJECTTYPE * pObj ) { diff --git a/Tactical/Items.h b/Tactical/Items.h index b6c62b988..2de929994 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -253,6 +253,8 @@ INT16 GetToHitBonus( OBJECTTYPE * pObj, INT32 iRange, UINT8 bLightLevel, BOOLEAN INT16 GetFlatToHitBonus( OBJECTTYPE * pObj ); // HEADROCK: Function to get average of best laser ranges from weapon and attachments INT16 GetAverageBestLaserRange( OBJECTTYPE * pObj ); +// get the best laser range from the weapon and attachments +INT16 GetBestLaserRange( OBJECTTYPE * pObj ); // HEADROCK: Function to get bipod bonus from weapon and its attachments INT16 GetBipodBonus( OBJECTTYPE * pObj ); INT16 GetBurstToHitBonus( OBJECTTYPE * pObj, BOOLEAN fProneStance = FALSE ); diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 53692ccf2..755d2e02e 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -7530,7 +7530,55 @@ void AdjustTargetCenterPoint( SOLDIERTYPE *pShooter, INT32 iTargetGridNo, FLOAT // First, let's calculate the basic Aperture. This is the size of an unmodified aperture at 1x Normal Distance. iBasicAperture = CalcBasicAperture( ); - + + // when using the reworked NCTH code we do additional calculations for iron sights and lasers + if (gGameExternalOptions.fUseNewCTHCalculation) + { + // iron sights can get a percentage bonus to make them overall better but only when not shooting from hip + if ( gCTHDisplay.ScopeMagFactor <= 1.0 && !pShooter->IsValidAlternativeFireMode( pShooter->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) ) + + iBasicAperture = iBasicAperture * (FLOAT)( (100 - gGameCTHConstants.IRON_SIGHT_PERFORMANCE_BONUS) / 100); + + // laser pointers can provide a percentage bonus to base aperture + if ( gCTHDisplay.iBestLaserRange > 0 + && ( gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) ) + { + INT8 bLightLevel = LightTrueLevel(gCTHDisplay.iTargetGridNo, gsInterfaceLevel ); + INT32 iMaxLaserRange = ( gCTHDisplay.iBestLaserRange*( 2*bLightLevel + 3*NORMAL_LIGHTLEVEL_NIGHT - 5*NORMAL_LIGHTLEVEL_DAY ) ) / ( 2 * ( NORMAL_LIGHTLEVEL_NIGHT - NORMAL_LIGHTLEVEL_DAY ) ); + + // laser only has effect when in range + if ( iMaxLaserRange > d2DDistance ) + { + FLOAT fLaserBonus = 0; + // which bonus do we want to apply? + if ( pShooter->IsValidAlternativeFireMode( pShooter->aiData.bAimTime, gCTHDisplay.iTargetGridNo ) ) + // shooting from hip + fLaserBonus = gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP; + else if ( gCTHDisplay.ScopeMagFactor <= 1.0 ) + // using iron sights or other 1x sights + fLaserBonus = gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON; + else + // must be using a scope + fLaserBonus = gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE; + + // light level influences how easy it is to spot the laser dot on the target + FLOAT fBrightnessModifier = 1.0 - ( (FLOAT)(bLightLevel - SHADE_MAX) / (FLOAT)(SHADE_MIN - SHADE_MAX) ); + + // laser fully efficient + if ( gCTHDisplay.iBestLaserRange > d2DDistance ) + // apply full bonus + iBasicAperture = iBasicAperture * (FLOAT)( (100 - (fLaserBonus * fBrightnessModifier)) / 100); + else + { + // beyond BestLaserRange laser bonus drops linearly to 0 + FLOAT fEffectiveLaserRatio = (FLOAT)(iMaxLaserRange - d2DDistance) / (FLOAT)(iMaxLaserRange - gCTHDisplay.iBestLaserRange); + // apply partial bonus + iBasicAperture = iBasicAperture * (FLOAT)( (100 - (fLaserBonus * fBrightnessModifier * fEffectiveLaserRatio)) / 100); + } + } + } + } + // Next, find out how large the aperture can be around the target, given range. The further the target is, the // larger the aperture can be. iDistanceAperture = iBasicAperture * (d2DDistance / gGameCTHConstants.NORMAL_SHOOTING_DISTANCE); diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 7410066ba..9c296392c 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -7222,6 +7222,8 @@ void SwapMercPortraits ( SOLDIERTYPE *pSoldier, INT8 bDirection ) RemovePlayerFromGroup( ubGroupID, MercPtrs[ ubTargetMerc ] ); AddPlayerToGroup( ubGroupID, MercPtrs[ ubSourceMerc ] ); AddPlayerToGroup( ubGroupID, MercPtrs[ ubTargetMerc ] ); + SortSquadByID( MercPtrs[ ubSourceMerc ]->bAssignment ); + RebuildCurrentSquad( ); // don't forget to renew selection of merc gusSelectedSoldier = ubTargetMerc; diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 034546a56..cb2ca2ef2 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -5188,11 +5188,11 @@ if (gGameExternalOptions.fUseNewCTHCalculation) // apply bonus from traits // Flugente: moved trait modifiers into a member function - UINT8 targetprofile = NOBODY; - if ( pTarget && pTarget->ubProfile != NOBODY ) - targetprofile = pTarget->ubProfile; + UINT8 targetprofile = NOBODY; + if ( pTarget && pTarget->ubProfile != NOBODY ) + targetprofile = pTarget->ubProfile; - fAimModifier += pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, targetprofile ); + fAimModifier += pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, targetprofile ); // Flugente: backgrounds if ( pTarget && pTarget->bTeam == CREATURE_TEAM ) @@ -6098,8 +6098,8 @@ else iChance = __max(iChance + (INT32)iAimPoints, iChance); iChance = __min(iChance, (INT32)uiCap); } - - // Impose global limits. + + // Impose global limits. // Flugente: backgrounds iChance = min(iChance, min(100, gGameExternalOptions.ubMaximumCTH + (UINT8)(pSoldier->GetBackgroundValue(BG_PERC_CTH_MAX))) ); iChance = __max(iChance, gGameExternalOptions.ubMinimumCTH); @@ -6941,7 +6941,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, targetprofile = pTarget->ubProfile; iChance += pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, targetprofile ); - + // Flugente: backgrounds if ( pTarget && pTarget->bTeam == CREATURE_TEAM ) iChance += pSoldier->GetBackgroundValue(BG_PERC_CTH_CREATURE); @@ -10297,7 +10297,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi else if ( bNumMercs > 0 ) iAttRating += 2; } - } + } // Flugente: backgrounds if (ubMode == HTH_MODE_STAB) @@ -11898,10 +11898,21 @@ void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTi gCTHDisplay.ScopeMagFactor = iScopeFactor; iScopeFactor = __min(iScopeFactor, __max(1.0f, iTargetMagFactor/rangeModifier)); - iProjectionFactor = CalcProjectionFactor(pSoldier, pWeapon, d2DDistance, (UINT8)bAimTime); + + // With the reworked NCTH code we don't want to use iProjectionFactor anymore. + // Instead we use the performance bonus if at least one bonus is != 0. Otherwise -> continue using Projection Factor. + if (gGameExternalOptions.fUseNewCTHCalculation + && ( gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0 )) + iProjectionFactor = 1.0; + else + iProjectionFactor = CalcProjectionFactor(pSoldier, pWeapon, d2DDistance, (UINT8)bAimTime); + // Set a display variable gCTHDisplay.ProjectionFactor = iProjectionFactor; + // Set a display variable + gCTHDisplay.iBestLaserRange = GetBestLaserRange( pWeapon ); + // The final factor is the largest of the two. iHighestMagFactor = __max( iScopeFactor, iProjectionFactor ); } @@ -11909,6 +11920,7 @@ void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTi { gCTHDisplay.ScopeMagFactor = 1.0; gCTHDisplay.ProjectionFactor = 1.0; + gCTHDisplay.iBestLaserRange = GetBestLaserRange( pWeapon ); iHighestMagFactor = 1.0; } diff --git a/Utils/Text.h b/Utils/Text.h index 9b4c5e646..53f6449ef 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -647,7 +647,7 @@ extern STR16 szUDBGenExplosiveStatsTooltipText[ 22 ]; extern STR16 szUDBGenExplosiveStatsExplanationsTooltipText[ 22 ]; extern STR16 szUDBGenSecondaryStatsTooltipText[ 32 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 JMich_SkillsModifiers: 31 for Defusal kit - covert item: 31->32 extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 32 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 JMich_SkillsModifiers: 31 for Defusal kit - covert item: 31->32 -extern STR16 szUDBAdvStatsTooltipText[ 64 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 dirt: 57->58 food:58->64 +extern STR16 szUDBAdvStatsTooltipText[ 65 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 dirt: 57->58 food:58->64 silversurfer Best Laser Range:65 extern STR16 szUDBAdvStatsExplanationsTooltipText[ 64 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 dirt: 57->58 food:58->64 extern STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[ 52 ]; // Flugente Overheating Weapons: 48->52 diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index e623183df..c57599760 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -7261,6 +7261,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index 9bf4facf1..267818507 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -7257,6 +7257,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index ddb83acb7..0c743c0f8 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -7246,6 +7246,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e", L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r", L"|D|e|c|a|y |M|o|d|i|f|i|e|r", + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e", }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index b9fb603a7..e146009fb 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -7241,6 +7241,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 5514225f8..0f9275a68 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -7070,6 +7070,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n|s |G|r|รถ|s|s|e", L"|M|o|r|a|l |M|o|d|i|f|i|k|a|t|o|r", L"|S|c|h|i|m|m|e|l |R|a|t|e", + L"|B|e|s|t|e |L|a|s|e|r |R|e|i|c|h|w|e|i|t|e", }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 6cb557850..54b093f2f 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -7243,6 +7243,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index f97fa2bb8..a22ccb141 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -7261,6 +7261,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 52e876f83..9008a2558 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -7246,6 +7246,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular. diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index 17d297e0f..e456199c2 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -7261,6 +7261,7 @@ STR16 szUDBAdvStatsTooltipText[]= L"|P|o|r|t|i|o|n |S|i|z|e",//TODO.translate L"|M|o|r|a|l|e |M|o|d|i|f|i|e|r",//TODO.translate L"|D|e|c|a|y |M|o|d|i|f|i|e|r",//TODO.translate + L"|B|e|s|t |L|a|s|e|r |R|a|n|g|e",//TODO.translate }; // Alternate tooltip text for weapon Advanced Stats. Just different wording, nothing spectacular.