// Kill them!
pDefender->setDamage(GC.getMAX_HIT_POINTS());
}
else
{
CvBattleDefinition kBattle;
kBattle.setUnit(BATTLE_UNIT_ATTACKER, this);
kBattle.setUnit(BATTLE_UNIT_DEFENDER, pDefender);
kBattle.setDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_BEGIN, getDamage());
kBattle.setDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_BEGIN, pDefender->getDamage());
//Added ST
CombatDetails cdAttackerDetails;
CombatDetails cdDefenderDetails;
iAttackerStrength = currCombatStr(NULL, NULL, &cdAttackerDetails);
iAttackerFirepower = currFirepower(NULL, NULL);
iDefenderStrength = pDefender->currCombatStr(pPlot, this, &cdDefenderDetails);
iDefenderFirepower = pDefender->currFirepower(pPlot, this);
FAssert((iAttackerStrength + iDefenderStrength) > 0);
FAssert((iAttackerFirepower + iDefenderFirepower) > 0);
iDefenderOdds = ((GC.getDefineINT("COMBAT_DIE_SIDES") * iDefenderStrength) / (iAttackerStrength + iDefenderStrength));
iStrengthFactor = ((iAttackerFirepower + iDefenderFirepower + 1) / 2);
bFirst = true;
if (isHuman() || pDefender->isHuman())
{
//Added ST
CyArgsList pyArgsCD;
pyArgsCD.add(gDLL->getPythonIFace()->makePythonObject(&cdAttackerDetails));
pyArgsCD.add(gDLL->getPythonIFace()->makePythonObject(&cdDefenderDetails));
pyArgsCD.add(getCombatOdds(this, pDefender));
gDLL->getEventReporterIFace()->genericEvent("combatLogCalc", pyArgsCD.makeFunctionArgs());
}
if (pDefender->isBarbarian())
{
if (GET_PLAYER(getOwnerINLINE()).getWinsVsBarbs() < GC.getHandicapInfo(GET_PLAYER(getOwnerINLINE()).getHandicapType()).getFreeWinsVsBarbs())
{
iDefenderOdds = min(10, iDefenderOdds);
}
}
if (isBarbarian())
{
if (GET_PLAYER(pDefender->getOwnerINLINE()).getWinsVsBarbs() < GC.getHandicapInfo(GET_PLAYER(pDefender->getOwnerINLINE()).getHandicapType()).getFreeWinsVsBarbs())
{
iDefenderOdds = max(90, iDefenderOdds);
}
}
while (true)
{
if (bFirst)
{
collateralCombat(pPlot, pDefender);
}
if (GC.getGameINLINE().getSorenRandNum(GC.getDefineINT("COMBAT_DIE_SIDES"), "Combat") < iDefenderOdds)
{
if (getCombatFirstStrikes() == 0)
{
iDamage = max(1, ((GC.getDefineINT("COMBAT_DAMAGE") * (iDefenderFirepower + iStrengthFactor)) / (iAttackerFirepower + iStrengthFactor)));
if (((getDamage() + iDamage) >= maxHitPoints()) && (GC.getGameINLINE().getSorenRandNum(100, "Withdrawal") < withdrawalProbability()))
{
// < Great Generals From Barbarian Combat Start >
bool xpFromCombat = true;
if(pDefender->isBarbarian() && !GC.getGameINLINE().isGreatGeneralFromBarbarianCombat())
{
xpFromCombat = false;
}
if(pDefender->isAnimal() && !GC.getGameINLINE().isGreatGeneralFromAnimalCombat())
{
xpFromCombat = false;
}
changeExperience(GC.getDefineINT("EXPERIENCE_FROM_WITHDRAWL"), pDefender->maxXPValue(), xpFromCombat, pPlot->getOwnerINLINE() == getOwnerINLINE());
// < Great Generals From Barbarian Combat End >
break;
}
changeDamage(iDamage, pDefender->getOwnerINLINE());
if (pDefender->getCombatFirstStrikes() > 0)
{
kBattle.addFirstStrikes(BATTLE_UNIT_DEFENDER, 1);
kBattle.addDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_RANGED, iDamage);
}
//Added ST
cdAttackerDetails.iCurrHitPoints=currHitPoints();
if (isHuman() || pDefender->isHuman())
{
CyArgsList pyArgs;
pyArgs.add(gDLL->getPythonIFace()->makePythonObject(&cdAttackerDetails));
pyArgs.add(gDLL->getPythonIFace()->makePythonObject(&cdDefenderDetails));
pyArgs.add(1);
pyArgs.add(iDamage);
gDLL->getEventReporterIFace()->genericEvent("combatLogHit", pyArgs.makeFunctionArgs());
}
}
}
else
{
if (pDefender->getCombatFirstStrikes() == 0)
{
iDamage = max(1, ((GC.getDefineINT("COMBAT_DAMAGE") * (iAttackerFirepower + iStrengthFactor)) / (iDefenderFirepower + iStrengthFactor)));
pDefender->changeDamage(iDamage);
if (getCombatFirstStrikes() > 0)
{
kBattle.addFirstStrikes(BATTLE_UNIT_ATTACKER, 1);
kBattle.addDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_RANGED, iDamage);
}
//Added ST
cdDefenderDetails.iCurrHitPoints=pDefender->currHitPoints();
if (isHuman() || pDefender->isHuman())
{
CyArgsList pyArgs;
pyArgs.add(gDLL->getPythonIFace()->makePythonObject(&cdAttackerDetails));
pyArgs.add(gDLL->getPythonIFace()->makePythonObject(&cdDefenderDetails));
pyArgs.add(0);
pyArgs.add(iDamage);
gDLL->getEventReporterIFace()->genericEvent("combatLogHit", pyArgs.makeFunctionArgs());
}
}
}
if (getCombatFirstStrikes() > 0)
{
changeCombatFirstStrikes(-1);
}
if (pDefender->getCombatFirstStrikes() > 0)
{
pDefender->changeCombatFirstStrikes(-1);
}
bFirst = false;
if (isDead() || pDefender->isDead())
{
// < Great Generals From Barbarian Combat Start >
bool xpFromCombat = true;
if(pDefender->isBarbarian() && !GC.getGameINLINE().isGreatGeneralFromBarbarianCombat())
{
xpFromCombat = false;
}
if(pDefender->isAnimal() && !GC.getGameINLINE().isGreatGeneralFromAnimalCombat())
{
xpFromCombat = false;
}
if (isDead())
{
iExperience = defenseXPValue();
iExperience = ((iExperience * iAttackerStrength) / iDefenderStrength);
iExperience = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
pDefender->changeExperience(iExperience, maxXPValue(), xpFromCombat, pPlot->getOwnerINLINE() == pDefender->getOwnerINLINE());
}
else
{
iExperience = pDefender->attackXPValue();
iExperience = ((iExperience * iDefenderStrength) / iAttackerStrength);
iExperience = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
changeExperience(iExperience, pDefender->maxXPValue(), xpFromCombat, pPlot->getOwnerINLINE() == getOwnerINLINE());
}
// < Great Generals From Barbarian Combat End >
break;
}
}
if (bVisible)
{
kBattle.setDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_END, getDamage());
kBattle.setDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_END, pDefender->getDamage());
kBattle.setAdvanceSquare(canAdvance(pPlot, 1));
if (isRanged() && pDefender->isRanged())
{
kBattle.setDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_RANGED, kBattle.getDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_END));
kBattle.setDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_RANGED, kBattle.getDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_END));
}
else
{
kBattle.addDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_RANGED, kBattle.getDamage(BATTLE_UNIT_ATTACKER, BATTLE_TIME_BEGIN));
kBattle.addDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_RANGED, kBattle.getDamage(BATTLE_UNIT_DEFENDER, BATTLE_TIME_BEGIN));
}
int iTurns = planBattle( kBattle);
kBattle.setMissionTime(iTurns * gDLL->getSecsPerTurn());
setCombatTimer(iTurns);
GC.getGameINLINE().incrementTurnTimer(getCombatTimer());
if (pPlot->isActiveVisible(false))
{
ExecuteMove(0.0f);
gDLL->getEntityIFace()->AddMission(&kBattle);
}
}
else
{
bFinish = true;
}
}
}
if (bFinish)
{
if (bVisible)
{
if (isCombatFocus() && gDLL->getInterfaceIFace()->isCombatFocus())
{
if (getOwnerINLINE() == GC.getGameINLINE().getActivePlayer())
{
gDLL->getInterfaceIFace()->releaseLockedCamera();
}
}
}