diff --git a/GameSettings.cpp b/GameSettings.cpp index 49683fe6..9b47e519 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1112,6 +1112,23 @@ void LoadGameExternalOptions() // Sight range gGameExternalOptions.ubStraightSightRange = iniReader.ReadInteger("Tactical Vision Settings","BASE_SIGHT_RANGE",13, 5, 100); + gGameExternalOptions.ubBrightnessVisionMod[0] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_0", 80, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[1] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_1", 86, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[2] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_2", 93, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[3] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_3", 100, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[4] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_4", 94, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[5] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_5", 88, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[6] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_6", 82, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[7] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_7", 76, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[8] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_8", 70, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[9] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_9", 64, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[10] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_10", 58, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[11] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_11", 51, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[12] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_12", 43, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[13] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_13", 30, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[14] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_14", 17, 1, 100); + gGameExternalOptions.ubBrightnessVisionMod[15] = iniReader.ReadInteger("Tactical Vision Settings", "BRIGHTNESS_MOD_15", 9, 1, 100); + // Tunnel Vision gGameExternalOptions.gfAllowLimitedVision = iniReader.ReadBoolean("Tactical Vision Settings","ALLOW_TUNNEL_VISION",0); diff --git a/GameSettings.h b/GameSettings.h index 50f16e88..cace201a 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -518,6 +518,9 @@ typedef struct //Sight range UINT32 ubStraightSightRange; + + INT8 ubBrightnessVisionMod[16]; + UINT32 ubVisDistDecreasePerRainIntensity; BOOLEAN gfAllowLimitedVision; diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index f84306b7..9efb361b 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -998,6 +998,7 @@ typedef struct INT16 tohitbonus; INT16 bestlaserrange; INT16 rangebonus; + INT16 percentrangebonus; INT16 aimbonus; INT16 minrangeforaimbonus; INT16 percentapreduction; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index e767f00b..66878a20 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -12852,7 +12852,8 @@ UINT8 AllowedAimingLevelsNCTH( SOLDIERTYPE *pSoldier, INT32 sGridNo ) // Read from item aimLevels = Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].ubAimLevels; fTwoHanded = Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].twohanded; - weaponRange = Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usRange + GetRangeBonus(&pSoldier->inv[pSoldier->ubAttackingHand]); + weaponRange = ( Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].usRange * GetPercentRangeBonus(&pSoldier->inv[pSoldier->ubAttackingHand]) ) / 10000; + weaponRange += GetRangeBonus(&pSoldier->inv[pSoldier->ubAttackingHand]); weaponType = Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].ubWeaponType; fUsingBipod = FALSE; @@ -12984,7 +12985,8 @@ UINT8 AllowedAimingLevels(SOLDIERTYPE * pSoldier, INT32 sGridNo) UINT16 usRange = GetModifiedGunRange(pSoldier->inv[pSoldier->ubAttackingHand].usItem); - weaponRange = usRange + GetRangeBonus(&pSoldier->inv[pSoldier->ubAttackingHand]); + weaponRange = ( usRange * GetPercentRangeBonus(&pSoldier->inv[pSoldier->ubAttackingHand]) ) / 10000; + weaponRange += GetRangeBonus(&pSoldier->inv[pSoldier->ubAttackingHand]); fUsingBipod = FALSE; maxAimWithoutBipod = 4; @@ -13239,7 +13241,8 @@ UINT8 GetAllowedAimingLevelsForItem( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, UI // Read weapon data fTwoHanded = Item[pObj->usItem].twohanded; - weaponRange = Weapon[Item[pObj->usItem].ubClassIndex].usRange + GetRangeBonus(pObj); + weaponRange = ( Weapon[Item[pObj->usItem].ubClassIndex].usRange * GetPercentRangeBonus(pObj) ) / 10000; + weaponRange += GetRangeBonus(pObj); weaponType = Weapon[Item[pObj->usItem].ubClassIndex].ubWeaponType; fUsingBipod = FALSE; if(UsingNewCTHSystem() == true) @@ -15088,3 +15091,22 @@ BOOLEAN ItemCanBeAppliedToOthers( UINT16 usItem ) return FALSE; } + +//zwwooooo - IoV: change RangeBonus to ratable (Orange by kenkenkenken in IoV921) +INT32 GetPercentRangeBonus( OBJECTTYPE * pObj ) +{ + INT32 bonus = 10000; + if (pObj->exists() == true) { + bonus += ( BonusReduce( Item[pObj->usItem].percentrangebonus, (*pObj)[0]->data.objectStatus ) ) * 100; + + if ( (*pObj)[0]->data.gun.ubGunShotsLeft > 0 ) + bonus = ( bonus * ( 100 + Item[(*pObj)[0]->data.gun.usGunAmmoItem].percentrangebonus ) ) / 100; + + for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) { + if ( !Item[iter->usItem].duckbill || ( Item[iter->usItem].duckbill && (*pObj)[0]->data.gun.ubGunAmmoType == AMMO_BUCKSHOT )) + bonus = ( bonus * ( 100 + BonusReduce( Item[iter->usItem].percentrangebonus, (*iter)[0]->data.objectStatus ) ) ) / 100; + } + } + return( bonus ); +} + diff --git a/Tactical/Items.h b/Tactical/Items.h index 119b7f5a..a9b455ec 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -513,6 +513,9 @@ BOOLEAN GetItemFromRandomItem( UINT16 usRandomItem, UINT16* pusNewItem ); // Flugente: can item be applied to other people? BOOLEAN ItemCanBeAppliedToOthers( UINT16 usItem ); +//zwwooooo - IoV: change RangeBonus to ratable (Orange by kenkenkenken in IoV921) +INT32 GetPercentRangeBonus( OBJECTTYPE * pObj ); + #endif diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index e46ba8cf..71f5a3e7 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -8299,7 +8299,8 @@ FLOAT CalcBulletDeviation( SOLDIERTYPE *pShooter, FLOAT *dShotOffsetX, FLOAT *dS OBJECTTYPE* pObjAttHand = pShooter->GetUsedWeapon( &pShooter->inv[ pShooter->ubAttackingHand ] ); INT16 sAccuracy = GetGunAccuracy( pWeapon ); - UINT16 sEffRange = Weapon[Item[pObjAttHand->usItem].ubClassIndex].usRange + GetRangeBonus( pObjAttHand ); + UINT16 sEffRange = (Weapon[Item[pObjAttHand->usItem].ubClassIndex].usRange *GetPercentRangeBonus(pObjAttHand)) / 10000; + sEffRange += GetRangeBonus( pObjAttHand ); // WANNE: I got a CTD in a multiplayer test game, because sEffRange was 0 (division to zero). // I don't know why this happend? diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 8ce8eb90..598cf8fc 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -950,7 +950,8 @@ UINT16 GunRange( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier ) // SANDRO - added a UINT16 usRange = GetModifiedGunRange(pObj->usItem); // Snap: attachment status is factored into the range bonus calculation - rng = usRange + GetRangeBonus(pObj); + rng = (usRange * GetPercentRangeBonus(pObj))/10000; + rng += GetRangeBonus(pObj); // SANDRO - STOMP traits - Gunslinger bonus range with pistols if ( pSoldier != NULL && Item[ pObj->usItem ].usItemClass & IC_GUN ) @@ -996,6 +997,58 @@ INT32 EffectiveArmour( OBJECTTYPE * pObj ) return( max(iValue,1) ); } +//zwwooooo - IoV: Lbe can be bulletproof after adding bulletproof plate into it.(Like CRIAS, MBSS, HSGI WASATCH...) +INT32 EffectiveArmourLBE( OBJECTTYPE * pObj ) +{ + INT32 iValue; + + if (pObj == NULL || Item[pObj->usItem].usItemClass != IC_LBEGEAR) + { + return( 0 ); + } + + iValue = 0; + + for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) { + if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 ) + { + INT32 iValue2; + + iValue2 = Armour[ Item[ iter->usItem ].ubClassIndex ].ubProtection; + iValue2 = iValue2 * (*iter)[0]->data.objectStatus * Armour[ Item[ iter->usItem ].ubClassIndex ].ubCoverage / 10000; + + iValue += iValue2; + } + } + return( max(iValue,0) ); +} + +//zwwooooo - IoV: Lbe can be bulletproof after adding bulletproof plate into it.(Like CRIAS, MBSS, HSGI WASATCH...) +INT32 ExplosiveEffectiveArmourLBE( OBJECTTYPE * pObj ) +{ + INT32 iValue; + + if (pObj == NULL || Item[pObj->usItem].usItemClass != IC_LBEGEAR) + { + return( 0 ); + } + + iValue = 0; + + for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) { + if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 ) + { + INT32 iValue2; + + iValue2 = Armour[ Item[ iter->usItem ].ubClassIndex ].ubProtection; + iValue2 *= (*iter)[0]->data.objectStatus * Armour[ Item[ iter->usItem ].ubClassIndex ].ubCoverage / 10000; + + iValue += iValue2; + } + } + return( max(iValue,0) ); +} + INT32 ArmourPercent( SOLDIERTYPE * pSoldier ) { INT32 iVest, iHelmet, iLeg; @@ -1063,7 +1116,33 @@ INT32 ArmourPercent( SOLDIERTYPE * pSoldier ) { iLeg = 0; } - return( (iHelmet + iVest + iLeg) ); + + //zwwooooo - IoV: Add iVestPack + INT32 iVestPack; + if (pSoldier->inv[VESTPOCKPOS].exists() == true) + { + iVestPack = EffectiveArmourLBE( &(pSoldier->inv[VESTPOCKPOS]) ); + iDivideValue = ( ( Armour[ Item[ SPECTRA_VEST_18 ].ubClassIndex ].ubProtection * Armour[ Item[ SPECTRA_VEST_18 ].ubClassIndex ].ubCoverage ) + ( Armour[ Item[ CERAMIC_PLATES ].ubClassIndex ].ubProtection * Armour[ Item[ CERAMIC_PLATES ].ubClassIndex ].ubCoverage ) ); + + // WANNE: Just to be on the save side + if (iDivideValue > 0) + { + // convert to % of best; ignoring bug-treated stuff + iVestPack = 6500 * iVestPack / iDivideValue; +} + else + { + iVestPack = 65 * iVestPack / ( Armour[ Item[ SPECTRA_VEST_18 ].ubClassIndex ].ubProtection + Armour[ Item[ CERAMIC_PLATES ].ubClassIndex ].ubProtection ); + } + } + else + { + iVestPack = 0; + } + + //return( (iHelmet + iVest + iLeg) ); + //zwwooooo - IoV: Add iVestPack + return( (iHelmet + iVest + iLeg + iVestPack) ); } INT32 ExplosiveEffectiveArmour( OBJECTTYPE * pObj ) @@ -1133,7 +1212,23 @@ INT8 ArmourVersusExplosivesPercent( SOLDIERTYPE * pSoldier ) { iLeg = 0; } - return( (INT8) (iHelmet + iVest + iLeg) ); + + //zwwooooo - IoV: Add iVestPack + INT32 iVestPack; + if (pSoldier->inv[VESTPOCKPOS].exists() == true) + { + iVestPack = ExplosiveEffectiveArmourLBE( &(pSoldier->inv[VESTPOCKPOS]) ); + // convert to % of best; ignoring bug-treated stuff + iVestPack = __min( 65, 6500 * iVestPack / ( ( Armour[ Item[ SPECTRA_VEST_18 ].ubClassIndex ].ubProtection * Armour[ Item[ SPECTRA_VEST_18 ].ubClassIndex ].ubCoverage ) + ( Armour[ Item[ CERAMIC_PLATES ].ubClassIndex ].ubProtection * Armour[ Item[ CERAMIC_PLATES ].ubClassIndex ].ubCoverage ) ) ); +} + else + { + iVestPack = 0; + } + + //return( (INT8) (iHelmet + iVest + iLeg) ); + //zwwooooo - IoV: Add iVestPack + return( (INT8) (iHelmet + iVest + iLeg + iVestPack) ); } void AdjustImpactByHitLocation( INT32 iImpact, UINT8 ubHitLocation, INT32 * piNewImpact, INT32 * piImpactForCrits ) @@ -8774,6 +8869,31 @@ INT32 TotalArmourProtection( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 u } + //zwwooooo - IoV: It can plates for the LBE bulletproof. Like CRIAS, MBSS, HSGI WASATCH... + OBJECTTYPE * pVestPack; + pVestPack = &(pTarget->inv[VESTPOCKPOS]); + if (iSlot == VESTPOS && pVestPack->exists() == true) + { + for (attachmentList::iterator iter = (*pVestPack)[0]->attachments.begin(); iter != (*pVestPack)[0]->attachments.end(); ++iter) { + if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 ) + { + iTotalProtection += ArmourProtection( pTarget, Item[iter->usItem].ubClassIndex, &((*iter)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit ); + if ( (*iter)[0]->data.objectStatus < USABLE ) + { + pVestPack->RemoveAttachment(&(*iter)); + DirtyMercPanelInterface( pTarget, DIRTYLEVEL2 ); + if ( pTarget->bTeam == gbPlayerNum ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[61], pTarget->name ); + } + } + break; + } + } + } + + if ( iImpact > iTotalProtection ) + { pArmour = &(pTarget->inv[ iSlot ]); if (pArmour->exists() == true) { @@ -8820,6 +8940,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 u } } } + } return( iTotalProtection ); } diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index 122f36c9..7e4e2cab 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -250,7 +250,8 @@ INT8 gbSmellStrength[3] = UINT16 gsWhoThrewRock = NOBODY; // % values of sighting distance at various light levels - +//DBrot: use gGameExternalOptions.ubBrightnessVisionMod instead +/* INT8 gbLightSighting[1][SHADE_MIN+1] = { { // human @@ -271,7 +272,7 @@ INT8 gbLightSighting[1][SHADE_MIN+1] = 17, 9 } -}; +};*/ /* { { // human @@ -333,8 +334,8 @@ INT16 AdjustMaxSightRangeForEnvEffects( SOLDIERTYPE *pSoldier, INT8 bLightLevel, { INT16 sNewDist = 0; - sNewDist = sDistVisible * gbLightSighting[ 0 ][ bLightLevel ] / 100; - + //sNewDist = sDistVisible * gbLightSighting[ 0 ][ bLightLevel ] / 100; + sNewDist = sDistVisible * gGameExternalOptions.ubBrightnessVisionMod[ bLightLevel ] / 100; // Adjust it based on weather... if ( guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS ) ) { diff --git a/Tactical/opplist.h b/Tactical/opplist.h index 158f25e5..fb7bcd4b 100644 --- a/Tactical/opplist.h +++ b/Tactical/opplist.h @@ -165,7 +165,7 @@ UINT8 DoorOpeningNoise( SOLDIERTYPE * pSoldier ); void AddToShouldBecomeHostileOrSayQuoteList( UINT8 ubID ); -extern INT8 gbLightSighting[1][16]; +//extern INT8 gbLightSighting[1][16]; BOOLEAN SoldierHasLimitedVision(SOLDIERTYPE * pSoldier); diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp index 0e2ccc0f..7651cb4e 100644 --- a/TacticalAI/FindLocations.cpp +++ b/TacticalAI/FindLocations.cpp @@ -588,7 +588,8 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB else { fNight = TRUE; - ubBackgroundLightPercent = gbLightSighting[ 0 ][ ubBackgroundLightLevel ]; + ubBackgroundLightPercent = gGameExternalOptions.ubBrightnessVisionMod[ ubBackgroundLightLevel ]; + //ubBackgroundLightPercent = gbLightSighting[ 0 ][ ubBackgroundLightLevel ]; } } @@ -1009,7 +1010,9 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB // reduce cover at nighttime based on how bright the light is at that location // using the difference in sighting distance between the background and the // light for this tile - ubLightPercentDifference = (gbLightSighting[ 0 ][ LightTrueLevel( sGridNo, pSoldier->pathing.bLevel ) ] - ubBackgroundLightPercent ); + //ubLightPercentDifference = (gbLightSighting[ 0 ][ LightTrueLevel( sGridNo, pSoldier->pathing.bLevel ) ] - ubBackgroundLightPercent ); + ubLightPercentDifference = (gGameExternalOptions.ubBrightnessVisionMod[ LightTrueLevel( sGridNo, pSoldier->pathing.bLevel ) ] - ubBackgroundLightPercent ); + if ( iCoverValue >= 0 ) { iCoverValue -= (iCoverValue / 100) * ubLightPercentDifference; @@ -1610,8 +1613,8 @@ INT16 FindNearbyDarkerSpot( SOLDIERTYPE *pSoldier ) // screen out anything brighter than our current best spot bLightLevel = LightTrueLevel( sGridNo, pSoldier->pathing.bLevel ); - bLightDiff = gbLightSighting[0][ bCurrLightLevel ] - gbLightSighting[0][ bLightLevel ]; - + //bLightDiff = gbLightSighting[0][ bCurrLightLevel ] - gbLightSighting[0][ bLightLevel ]; + bLightDiff = gGameExternalOptions.ubBrightnessVisionMod[ bCurrLightLevel ] - gGameExternalOptions.ubBrightnessVisionMod[ bLightLevel ]; // if the spot is darker than our current location, then bLightDiff > 0 // plus ignore differences of just 1 light level if ( bLightDiff <= 1 ) diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index 185b493e..b081ce3d 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -156,6 +156,7 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "BestLaserRange") == 0 || strcmp(name, "ToHitBonus") == 0 || strcmp(name, "RangeBonus") == 0 || + strcmp(name, "PercentRangeBonus") == 0 || strcmp(name, "AimBonus") == 0 || strcmp(name, "MinRangeForAimBonus") == 0 || strcmp(name, "PercentAPReduction") == 0 || @@ -777,6 +778,11 @@ itemEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curItem.rangebonus = (INT16) atol(pData->szCharData); } + else if(strcmp(name, "PercentRangeBonus") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.percentrangebonus = (INT16) atol(pData->szCharData); + } else if(strcmp(name, "AimBonus") == 0) { pData->curElement = ELEMENT; @@ -1871,6 +1877,7 @@ BOOLEAN WriteItemStats() FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].hidemuzzleflash ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].bipod ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].rangebonus ); + FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].rangebonus ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].tohitbonus ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].aimbonus ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].minrangeforaimbonus );