int CvUnit::maxCombatStr(const CvPlot* pPlot, const CvUnit* pAttacker, CombatDetails* pCombatDetails, bool bSurroundedModifier) const
// OLD CODE
// int CvUnit::maxCombatStr(const CvPlot* pPlot, const CvUnit* pAttacker, CombatDetails* pCombatDetails) const
/*** Dexy - Surround and Destroy END ****/
{
PROFILE_FUNC();
int iCombat;
//TB SubCombat Mod Begin
int iI;
UnitCombatTypes eUnitCombatType;
//TB SubCombat Mod End
FAssertMsg((pPlot == NULL) || (pPlot->getTerrainType() != NO_TERRAIN), "(pPlot == NULL) || (pPlot->getTerrainType() is not expected to be equal with NO_TERRAIN)");
// handle our new special case
const CvPlot* pAttackedPlot = NULL;
bool bAttackingUnknownDefender = false;
if (pAttacker == this)
{
bAttackingUnknownDefender = true;
pAttackedPlot = pPlot;
// reset these values, we will fiddle with them below
pPlot = NULL;
pAttacker = NULL;
}
// otherwise, attack plot is the plot of us (the defender)
else if (pAttacker != NULL)
{
pAttackedPlot = plot();
}
CombatStrCacheEntry* pCacheEntry = NULL;
const CvUnit* pOriginalAttacker = pAttacker;
if (pCombatDetails != NULL)
{
pCombatDetails->iExtraCombatPercent = 0;
pCombatDetails->iAnimalCombatModifierTA = 0;
pCombatDetails->iAIAnimalCombatModifierTA = 0;
pCombatDetails->iAnimalCombatModifierAA = 0;
pCombatDetails->iAIAnimalCombatModifierAA = 0;
pCombatDetails->iBarbarianCombatModifierTB = 0;
pCombatDetails->iAIBarbarianCombatModifierTB = 0;
pCombatDetails->iBarbarianCombatModifierAB = 0;
pCombatDetails->iAIBarbarianCombatModifierAB = 0;
pCombatDetails->iPlotDefenseModifier = 0;
pCombatDetails->iFortifyModifier = 0;
pCombatDetails->iCityDefenseModifier = 0;
pCombatDetails->iHillsAttackModifier = 0;
pCombatDetails->iHillsDefenseModifier = 0;
pCombatDetails->iFeatureAttackModifier = 0;
pCombatDetails->iFeatureDefenseModifier = 0;
pCombatDetails->iTerrainAttackModifier = 0;
pCombatDetails->iTerrainDefenseModifier = 0;
pCombatDetails->iCityAttackModifier = 0;
pCombatDetails->iDomainDefenseModifier = 0;
pCombatDetails->iCityBarbarianDefenseModifier = 0;
pCombatDetails->iClassDefenseModifier = 0;
pCombatDetails->iClassAttackModifier = 0;
pCombatDetails->iCombatModifierA = 0;
pCombatDetails->iCombatModifierT = 0;
pCombatDetails->iDomainModifierA = 0;
pCombatDetails->iDomainModifierT = 0;
pCombatDetails->iAnimalCombatModifierA = 0;
pCombatDetails->iAnimalCombatModifierT = 0;
pCombatDetails->iRiverAttackModifier = 0;
pCombatDetails->iAmphibAttackModifier = 0;
pCombatDetails->iKamikazeModifier = 0;
pCombatDetails->iModifierTotal = 0;
pCombatDetails->iBaseCombatStr = 0;
pCombatDetails->iCombat = 0;
pCombatDetails->iMaxCombatStr = 0;
pCombatDetails->iCurrHitPoints = 0;
pCombatDetails->iMaxHitPoints = 0;
pCombatDetails->iCurrCombatStr = 0;
pCombatDetails->eOwner = getOwnerINLINE();
pCombatDetails->eVisualOwner = getVisualOwner();
pCombatDetails->sUnitName = getName().GetCString();
}
else if (baseCombatStr() == 0)
{
return 0;
}
else if ( bSurroundedModifier )
{
PROFILE("maxCombatStr.Cachable");
if ( CombatStrCacheInitializedTurn != GC.getGameINLINE().getGameTurn() )
{
memset(CombatStrCache, 0, sizeof(CombatStrCache));
CombatStrCacheInitializedTurn = GC.getGameINLINE().getGameTurn();
}
int iBestLRU = MAX_INT;
for(iI = 0; iI < COMBATSTR_CACHE_SIZE; iI++)
{
CombatStrCacheEntry* pEntry = &CombatStrCache[iI];
if ( pEntry->iLRUIndex == 0 )
{
pCacheEntry = pEntry;
break;
}
else if ( pEntry->pPlot == pPlot && pEntry->pAttacker == pOriginalAttacker && pEntry->pForUnit == this )
{
//OutputDebugString("maxCombatStr.CachHit\n");
PROFILE("maxCombatStr.CachHit");
pEntry->iLRUIndex = iNextCombatCacheLRU++;
return pEntry->iResult;
}
else if ( pEntry->iLRUIndex < iBestLRU )
{
iBestLRU = pEntry->iLRUIndex;
pCacheEntry = pEntry;
}
}
//char buffer[300];
//sprintf(buffer,"maxCombatStr cache miss for unit %d, attacker %d @(%d,%d)\n", getID(), pOriginalAttacker == NULL ? -1 : pOriginalAttacker->getID(), pPlot == NULL ? -1 : pPlot->getX_INLINE(), pPlot == NULL ? -1 : pPlot->getY_INLINE());
//OutputDebugString(buffer);
}
int iModifier = 0;
int iExtraModifier;
//TB Combat Mods Begin
int iExtraModifier2;
//TB Combat Mods End
iExtraModifier = getExtraCombatPercent();
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iExtraCombatPercent = iExtraModifier;
}
// do modifiers for animals and barbarians (leaving these out for bAttackingUnknownDefender case)
if (pAttacker != NULL)
{
if (isAnimal())
{
if (pAttacker->isHuman())
{
iExtraModifier = GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAnimalCombatModifier();
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAnimalCombatModifierTA = iExtraModifier;
}
}
else
{
iExtraModifier = GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIAnimalCombatModifier();
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAIAnimalCombatModifierTA = iExtraModifier;
}
}
}
if (pAttacker->isAnimal())
{
if (isHuman())
{
iExtraModifier = -GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAnimalCombatModifier();
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAnimalCombatModifierAA = iExtraModifier;
}
}
else
{
iExtraModifier = -GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIAnimalCombatModifier();
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAIAnimalCombatModifierAA = iExtraModifier;
}
}
}
if (isBarbarian())
{
//TB Combat Mods Begin
if (!isAnimal())
{
iExtraModifier2 = -pAttacker->vsBarbsModifier();
}
else
{
iExtraModifier2 = 0;
}
//TB Combat Mods End (The lines that follow also include adjustments with iExtraModifier2)
if (pAttacker->isHuman())
{
iExtraModifier = GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getBarbarianCombatModifier();
iModifier += (iExtraModifier + iExtraModifier2);
if (pCombatDetails != NULL)
{
pCombatDetails->iBarbarianCombatModifierTB = (iExtraModifier + iExtraModifier2);
}
}
else
{
iExtraModifier = GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIBarbarianCombatModifier();
iModifier += (iExtraModifier + iExtraModifier2);
if (pCombatDetails != NULL)
{
pCombatDetails->iAIBarbarianCombatModifierTB = (iExtraModifier + iExtraModifier2);
}
}
}
if (pAttacker->isBarbarian())
{
//TB Combat Mods Begin
if (!(pAttacker->isAnimal()))
{
iExtraModifier2 = vsBarbsModifier();
}
else
{
iExtraModifier2 = 0;
}
//TB Combat Mods End (The following lines include references to iExtraModifier2 which is also a portion of this mod)
if (isHuman())
{
iExtraModifier = -GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getBarbarianCombatModifier();
iModifier += (iExtraModifier + iExtraModifier2);
if (pCombatDetails != NULL)
{
pCombatDetails->iBarbarianCombatModifierAB = (iExtraModifier + iExtraModifier2);
}
}
else
{
iExtraModifier = -GC.getHandicapInfo(GC.getGameINLINE().getHandicapType()).getAIBarbarianCombatModifier();
iModifier += (iExtraModifier + iExtraModifier2);
if (pCombatDetails != NULL)
{
pCombatDetails->iAIBarbarianCombatModifierTB = (iExtraModifier + iExtraModifier2);
}
}
}
}
// add defensive bonuses (leaving these out for bAttackingUnknownDefender case)
if (pPlot != NULL)
{
if (!noDefensiveBonus())
{
/************************************************************************************************/
/* BETTER_BTS_AI_MOD 03/30/10 jdog5000 */
/* */
/* General AI */
/************************************************************************************************/
// When pAttacker is NULL but pPlot is not, this is a computation for this units defensive value
// against an unknown attacker. Always ignoring building defense in this case is a conservative estimate,
// but causes AI to suicide against castle walls of low culture cities in early game. Using this units
// ignoreBuildingDefense does a little better ... in early game it corrects undervalue of castles. One
// downside is when medieval unit is defending a walled city against gunpowder. Here, the over value
// makes attacker a little more cautious, but with their tech lead it shouldn't matter too much. Also
// makes vulnerable units (ships, etc) feel safer in this case and potentially not leave, but ships
// leave when ratio is pretty low anyway.
//iExtraModifier = pPlot->defenseModifier(getTeam(), (pAttacker != NULL) ? pAttacker->ignoreBuildingDefense() : true);
iExtraModifier = pPlot->defenseModifier(getTeam(), (pAttacker != NULL) ? pAttacker->ignoreBuildingDefense() : ignoreBuildingDefense());
/************************************************************************************************/
/* BETTER_BTS_AI_MOD END */
/************************************************************************************************/
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iPlotDefenseModifier = iExtraModifier;
}
}
//TB Combat Mods (fortification)
int iFort = fortifyModifier();
int iOverrun = ((pAttacker != NULL) ? pAttacker->overrunTotal() : 0);
int iOverrunzero = ((iOverrun < 0) ? 0 : iOverrun);
int iOverruntotal = ((iOverrunzero > 100) ? 100 : iOverrunzero);
int iFortModTotal = ((iFort * (100 - iOverruntotal))/100);
iExtraModifier = iFortModTotal;
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iFortifyModifier = iExtraModifier;
}
if (pPlot->isCity(true, getTeam()))
{
iExtraModifier = cityDefenseModifier();
/************************************************************************************************/
/* Afforess Start 05/22/10 */
/* */
/* */
/************************************************************************************************/
if (pPlot->isCity(false))
{
iExtraModifier += 0;
//TB SubCombat Mod Begin
for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
{
if (hasCombatType((UnitCombatTypes)iI))
{
eUnitCombatType = ((UnitCombatTypes)iI);
iExtraModifier += pPlot->getPlotCity()->getUnitCombatExtraStrength(eUnitCombatType);
}
}
//TB SubCombat Mod End
}
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iCityDefenseModifier = iExtraModifier;
}
}
if (pPlot->isHills())
{
iExtraModifier = hillsDefenseModifier();
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iHillsDefenseModifier = iExtraModifier;
}
}
if (pPlot->getFeatureType() != NO_FEATURE)
{
iExtraModifier = featureDefenseModifier(pPlot->getFeatureType());
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iFeatureDefenseModifier = iExtraModifier;
}
}
iExtraModifier = terrainDefenseModifier(pPlot->getTerrainType());
iModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iTerrainDefenseModifier = iExtraModifier;
}
}
//TB note: this was further below, underneath the Attacker = this clause. The next if line was necessary to isolate these still, but hopefully this can debug the invisibility issue without creating a further problem.
int iTempModifier2 = 0;
if (pAttacker != NULL && pAttackedPlot != NULL)
{
iExtraModifier = unitClassDefenseModifier(pAttacker->getUnitClassType());
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iClassDefenseModifier = iExtraModifier;
}
iExtraModifier = -pAttacker->unitClassAttackModifier(getUnitClassType());
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iClassAttackModifier = iExtraModifier;
}
iExtraModifier = 0;
//TB SubCombat Mod Begin
for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
{
if (pAttacker->hasCombatType((UnitCombatTypes)iI))
{
eUnitCombatType = ((UnitCombatTypes)iI);
iExtraModifier += unitCombatModifier(eUnitCombatType);
}
}
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iCombatModifierA = iExtraModifier;
}
iExtraModifier = 0;
//TB SubCombat Mod Begin
for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
{
if (hasCombatType((UnitCombatTypes)iI))
{
eUnitCombatType = ((UnitCombatTypes)iI);
iExtraModifier -= pAttacker->unitCombatModifier(eUnitCombatType);
}
}
//TB SubCombat Mod End
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iCombatModifierT = iExtraModifier;
}
iExtraModifier = domainModifier(pAttacker->getDomainType());
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iDomainModifierA = iExtraModifier;
}
iExtraModifier = -pAttacker->domainModifier(getDomainType());
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iDomainModifierT = iExtraModifier;
}
if (pAttacker->isAnimal())
{
iExtraModifier = animalCombatModifier();
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAnimalCombatModifierA = iExtraModifier;
}
}
if (isAnimal())
{
iExtraModifier = -pAttacker->animalCombatModifier();
iTempModifier2 += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAnimalCombatModifierT = iExtraModifier;
}
}
}
// if we are attacking to an plot with an unknown defender, the calc the modifier in reverse
if (bAttackingUnknownDefender)
{
pAttacker = this;
}
// calc attacker bonueses
/************************************************************************************************/
/* UNOFFICIAL_PATCH 09/20/09 jdog5000 */
/* */
/* Bugfix */
/************************************************************************************************/
/* original code
if (pAttacker != NULL)
*/
if (pAttacker != NULL && pAttackedPlot != NULL)
/************************************************************************************************/
/* UNOFFICIAL_PATCH END */
/************************************************************************************************/
{
int iTempModifier = 0;
//TB note: part of above debug effort
iTempModifier += iTempModifier2;
if (pAttackedPlot->isCity(true, getTeam()))
{
iExtraModifier = -pAttacker->cityAttackModifier();
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iCityAttackModifier = iExtraModifier;
}
if (pAttacker->isBarbarian())
{
iExtraModifier = GC.getDefineINT("CITY_BARBARIAN_DEFENSE_MODIFIER");
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iCityBarbarianDefenseModifier = iExtraModifier;
}
}
}
if (pAttacker->attackCombatModifierTotal() > 0)
{
iExtraModifier = -pAttacker->attackCombatModifierTotal();
iTempModifier += iExtraModifier;
}
if (defenseCombatModifierTotal() > 0)
{
iExtraModifier = defenseCombatModifierTotal();
iTempModifier += iExtraModifier;
}
if (pAttackedPlot->isHills())
{
iExtraModifier = -pAttacker->hillsAttackModifier();
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iHillsAttackModifier = iExtraModifier;
}
}
if (pAttackedPlot->getFeatureType() != NO_FEATURE)
{
iExtraModifier = -pAttacker->featureAttackModifier(pAttackedPlot->getFeatureType());
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iFeatureAttackModifier = iExtraModifier;
}
}
else
{
iExtraModifier = -pAttacker->terrainAttackModifier(pAttackedPlot->getTerrainType());
/*** Dexy - Others' bug fixes START ****/
iTempModifier += iExtraModifier;
// OLD CODE
// iModifier += iExtraModifier;
/*** Dexy - Others' bug fixes END ****/
if (pCombatDetails != NULL)
{
pCombatDetails->iTerrainAttackModifier = iExtraModifier;
}
}
// only compute comparisions if we are the defender with a known attacker
// TB Debug: this exclusion appears to be fairly unnecessary and causes trouble for Assassins and such. The intention of it seems to be subverted in C2C in general.
// Thus we'll test disabling this exclusion entirely.
//if (!bAttackingUnknownDefender)
//{
// FAssertMsg(pAttacker != this, "pAttacker is not expected to be equal with this");
// Attempting to move the following above the Attacker = this clause.
//iExtraModifier = unitClassDefenseModifier(pAttacker->getUnitClassType());
//iTempModifier += iExtraModifier;
//if (pCombatDetails != NULL)
//{
// pCombatDetails->iClassDefenseModifier = iExtraModifier;
//}
//iExtraModifier = -pAttacker->unitClassAttackModifier(getUnitClassType());
//iTempModifier += iExtraModifier;
//if (pCombatDetails != NULL)
//{
// pCombatDetails->iClassAttackModifier = iExtraModifier;
//}
//iExtraModifier = 0;
////TB SubCombat Mod Begin
//for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
//{
// if (pAttacker->hasCombatType((UnitCombatTypes)iI))
// {
// eUnitCombatType = ((UnitCombatTypes)iI);
// iExtraModifier += unitCombatModifier(eUnitCombatType);
// }
//}
//iTempModifier += iExtraModifier;
//if (pCombatDetails != NULL)
//{
// pCombatDetails->iCombatModifierA = iExtraModifier;
//}
//iExtraModifier = 0;
////TB SubCombat Mod Begin
//for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
//{
// if (hasCombatType((UnitCombatTypes)iI))
// {
// eUnitCombatType = ((UnitCombatTypes)iI);
// iExtraModifier -= pAttacker->unitCombatModifier(eUnitCombatType);
// }
//}
////TB SubCombat Mod End
//iTempModifier += iExtraModifier;
//if (pCombatDetails != NULL)
//{
// pCombatDetails->iCombatModifierT = iExtraModifier;
//}
//iExtraModifier = domainModifier(pAttacker->getDomainType());
//iTempModifier += iExtraModifier;
//if (pCombatDetails != NULL)
//{
// pCombatDetails->iDomainModifierA = iExtraModifier;
//}
//iExtraModifier = -pAttacker->domainModifier(getDomainType());
//iTempModifier += iExtraModifier;
//if (pCombatDetails != NULL)
//{
// pCombatDetails->iDomainModifierT = iExtraModifier;
//}
//if (pAttacker->isAnimal())
//{
// iExtraModifier = animalCombatModifier();
// iTempModifier += iExtraModifier;
// if (pCombatDetails != NULL)
// {
// pCombatDetails->iAnimalCombatModifierA = iExtraModifier;
// }
//}
//if (isAnimal())
//{
// iExtraModifier = -pAttacker->animalCombatModifier();
// iTempModifier += iExtraModifier;
// if (pCombatDetails != NULL)
// {
// pCombatDetails->iAnimalCombatModifierT = iExtraModifier;
// }
//}
//}
if (!(pAttacker->isRiver()))
{
if (pAttacker->plot()->isRiverCrossing(directionXY(pAttacker->plot(), pAttackedPlot)))
{
iExtraModifier = -GC.getRIVER_ATTACK_MODIFIER();
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iRiverAttackModifier = iExtraModifier;
}
}
}
if (!(pAttacker->isAmphib()))
{
if (!(pAttackedPlot->isWater()) && pAttacker->plot()->isWater())
{
iExtraModifier = -GC.getAMPHIB_ATTACK_MODIFIER();
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iAmphibAttackModifier = iExtraModifier;
}
}
}
/************************************************************************************************/
/* Afforess Start 02/05/10 */
/* */
/* */
/************************************************************************************************/
if (GET_PLAYER(pAttacker->getOwnerINLINE()).isDarkAge())
{
iTempModifier += GC.getDefineINT("DARK_AGE_ATTACK_STRENGTH_PERCENT_DECREASE");
}
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
if (pAttacker->getKamikazePercent() != 0)
{
/************************************************************************************************/
/* Afforess Start 02/05/10 Dexy */
/* */
/* Unofficial Patch */
/************************************************************************************************/
iExtraModifier = -pAttacker->getKamikazePercent();
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
iTempModifier += iExtraModifier;
if (pCombatDetails != NULL)
{
pCombatDetails->iKamikazeModifier = iExtraModifier;
}
}
/************************************************************************************************/
/* Afforess Start 02/05/10 */
/* */
/* */
/************************************************************************************************/
if (bSurroundedModifier)
{
// the stronger the surroundings -> decrease the iModifier more
//TB Combat Mods (S&D promos) begin
int iSurround = pAttacker->surroundedDefenseModifier(pAttackedPlot, bAttackingUnknownDefender ? NULL : this);
int iDynamicDefense = dynamicDefenseTotal();
int iDynamicDefenseModifier = ((iSurround * iDynamicDefense) / 100);
int iSurroundTotalstepone = iSurround - iDynamicDefenseModifier;
int iSurroundTotal = (iSurroundTotalstepone < 0 ? 0 : iSurroundTotalstepone);
iExtraModifier = -iSurroundTotal;
iTempModifier += iExtraModifier;
//TB Combat Mods (S&D promos) end
}
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
//TB Combat Mods (StrAdjperAtt) begin
if (pAttacker->currentStrAdjperAttTotal() != 0)
{
iExtraModifier = -(pAttacker->currentStrAdjperAttTotal());
iTempModifier += iExtraModifier;
}
if (currentStrAdjperDefTotal() != 0)
{
iExtraModifier = currentStrAdjperDefTotal();
iTempModifier += iExtraModifier;
}
//TB Combat Mods (StrAdjperAtt) end
// if we are attacking an unknown defender, then use the reverse of the modifier
if (bAttackingUnknownDefender)
{
iModifier -= iTempModifier;
}
else
{
iModifier += iTempModifier;
}
}
if (pCombatDetails != NULL)
{
pCombatDetails->iModifierTotal = iModifier;
pCombatDetails->iBaseCombatStr = baseCombatStr();
}
if (iModifier > 0)
{
iCombat = (baseCombatStr() * (iModifier + 100));
}
else
{
iCombat = ((baseCombatStr() * 10000) / (100 - iModifier));
}
if (pCombatDetails != NULL)
{
pCombatDetails->iCombat = iCombat;
pCombatDetails->iMaxCombatStr = std::max(1, iCombat);
pCombatDetails->iCurrHitPoints = currHitPoints();
pCombatDetails->iMaxHitPoints = maxHitPoints();
pCombatDetails->iCurrCombatStr = ((pCombatDetails->iMaxCombatStr * pCombatDetails->iCurrHitPoints) / pCombatDetails->iMaxHitPoints);
}
if ( pCacheEntry != NULL )
{
pCacheEntry->iLRUIndex = iNextCombatCacheLRU++;
pCacheEntry->iResult = std::max(1, iCombat);
pCacheEntry->pPlot = pPlot;
pCacheEntry->pAttacker = pOriginalAttacker;
pCacheEntry->pForUnit = this;
//char buffer[300];
//sprintf(buffer,"maxCombatStr cache result (%d) for unit %d, attacker %d @(%d,%d)\n", pCacheEntry->iResult, getID(), pOriginalAttacker == NULL ? -1 : pOriginalAttacker->getID(), pPlot == NULL ? -1 : pPlot->getX_INLINE(), pPlot == NULL ? -1 : pPlot->getY_INLINE());
//OutputDebugString(buffer);
}
return std::max(1, iCombat);
}