Code
1178// Function: ResolveCityMeleeCombat1179//1180// Resolves combat between a melee unit and a city.1181// The unit does not have to be a hand-to-hand combat type unit, just a unit doing1182// a non-ranged attack to an adjacent city. The visualization of the attack will1183// usually appear as if it is ranged, simply because we don't want the unit members1184// running through a city and they wouldn't have anything to attack.1185// This is also the case where a city is able to attack back.1186void CvUnitCombat::ResolveCityMeleeCombat(const CvCombatInfo& kCombatInfo, uint uiParentEventID)1187{1188 CvUnit* pkAttacker = kCombatInfo.getUnit(BATTLE_UNIT_ATTACKER);1189 CvCity* pkDefender = kCombatInfo.getCity(BATTLE_UNIT_DEFENDER);11901191 CvAssert_Debug(pkAttacker && pkDefender);11921193 CvPlot* pkPlot = kCombatInfo.getPlot();1194 if(!pkPlot && pkDefender)1195 pkPlot = pkDefender->plot();11961197 CvAssert_Debug(pkPlot);11981199 int iAttackerDamageInflicted = kCombatInfo.getDamageInflicted(BATTLE_UNIT_ATTACKER);1200 int iDefenderDamageInflicted = kCombatInfo.getDamageInflicted(BATTLE_UNIT_DEFENDER);12011202 if(pkAttacker && pkDefender)1203 {1204#if defined(MOD_API_UNIT_STATS)1205 pkAttacker->changeDamage(iDefenderDamageInflicted, pkDefender->getOwner(), pkDefender->GetID());1206#else1207 pkAttacker->changeDamage(iDefenderDamageInflicted, pkDefender->getOwner());1208#endif1209 pkDefender->changeDamage(iAttackerDamageInflicted);12101211#if defined(MOD_UNITS_XP_TIMES_100)1212 pkAttacker->changeExperienceTimes100(100 * kCombatInfo.getExperience(BATTLE_UNIT_ATTACKER),1213#else1214 pkAttacker->changeExperience(kCombatInfo.getExperience(BATTLE_UNIT_ATTACKER),1215#endif1216 kCombatInfo.getMaxExperienceAllowed(BATTLE_UNIT_ATTACKER),1217 true,1218 false,1219 kCombatInfo.getUpdateGlobal(BATTLE_UNIT_ATTACKER));1220 }12211222 bool bCityConquered = false;12231224 if(pkDefender)1225 pkDefender->clearCombat();1226 else1227 bCityConquered = true;12281229 if(pkAttacker)1230 {1231 pkAttacker->setCombatUnit(NULL);1232 pkAttacker->ClearMissionQueue(GetPostCombatDelay());12331234 if(pkAttacker->isSuicide())1235 {1236 pkAttacker->setCombatUnit(NULL); // Must clear this if doing a delayed kill, should this be part of the kill method?1237 pkAttacker->kill(true);1238 }1239 }12401241 CvString strBuffer;1242 int iActivePlayerID = GC.getGame().getActivePlayer();12431244 // Barbarians don't capture Cities1245 if(pkAttacker && pkDefender)1246 {1247 if(pkAttacker->isBarbarian() && (pkDefender->getDamage() >= pkDefender->GetMaxHitPoints()))1248 {1249 // 1 HP left1250 pkDefender->setDamage(pkDefender->GetMaxHitPoints() - 1);12511252 int iNumGoldStolen = GC.getBARBARIAN_CITY_GOLD_RANSOM(); // 20012531254 if(iNumGoldStolen > GET_PLAYER(pkDefender->getOwner()).GetTreasury()->GetGold())1255 {1256 iNumGoldStolen = GET_PLAYER(pkDefender->getOwner()).GetTreasury()->GetGold();1257 }12581259 // City is ransomed for Gold1260 GET_PLAYER(pkDefender->getOwner()).GetTreasury()->ChangeGold(-iNumGoldStolen);12611262 if(pkDefender->getOwner() == iActivePlayerID)1263 {1264 strBuffer = GetLocalizedText("TXT_KEY_MISC_YOU_CITY_RANSOMED_BY_BARBARIANS", pkDefender->getNameKey(), iNumGoldStolen);1265 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkDefender->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*,GC.getEraInfo(GC.getGame().getCurrentEra())->getAudioUnitDefeatScript(), MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pkPlot->getX(), pkPlot->getY()*/);1266 MILITARYLOG(pkDefender->getOwner(), strBuffer.c_str(), pkDefender->plot(), pkAttacker->getOwner());1267 }12681269#if !defined(NO_ACHIEVEMENTS)1270 if( pkDefender->GetPlayer()->GetID() == GC.getGame().getActivePlayer() && pkDefender->isHuman() && !GC.getGame().isGameMultiPlayer())1271 {1272 gDLL->UnlockAchievement(ACHIEVEMENT_REALLY_SUCK);1273 }1274#endif12751276 // Barb goes away after ransom1277 pkAttacker->kill(true, NO_PLAYER);12781279 // Treat this as a conquest1280 bCityConquered = true;1281 }1282 // Attacker died1283 else if(pkAttacker->IsDead())1284 {1285 auto_ptr<ICvUnit1> pAttacker = GC.WrapUnitPointer(pkAttacker);1286 gDLL->GameplayUnitDestroyedInCombat(pAttacker.get());1287 if(pkAttacker->getOwner() == iActivePlayerID)1288 {1289 strBuffer = GetLocalizedText("TXT_KEY_MISC_YOU_UNIT_DIED_ATTACKING_CITY", pkAttacker->getNameKey(), pkDefender->getNameKey(), iAttackerDamageInflicted);1290 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkAttacker->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*, GC.getEraInfo(GC.getGame().getCurrentEra())->getAudioUnitDefeatScript(), MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pkPlot->getX(), pkPlot->getY()*/);1291 MILITARYLOG(pkAttacker->getOwner(), strBuffer.c_str(), pkAttacker->plot(), pkDefender->getOwner());1292 }1293 if(pkDefender->getOwner() == iActivePlayerID)1294 {1295 strBuffer = GetLocalizedText("TXT_KEY_MISC_YOU_KILLED_ENEMY_UNIT_CITY", pkDefender->getNameKey(), iAttackerDamageInflicted, pkAttacker->getNameKey(), pkAttacker->getVisualCivAdjective(pkDefender->getTeam()));1296 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkDefender->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*, GC.getEraInfo(GC.getGame().getCurrentEra())->getAudioUnitVictoryScript(), MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pkPlot->getX(), pkPlot->getY()*/);1297 MILITARYLOG(pkDefender->getOwner(), strBuffer.c_str(), pkDefender->plot(), pkAttacker->getOwner());1298 }1299 }1300 // City conquest1301 else if(pkDefender->getDamage() >= pkDefender->GetMaxHitPoints())1302 {1303 if(!pkAttacker->isNoCapture())1304 {1305 if(pkAttacker->getOwner() == iActivePlayerID)1306 {1307 strBuffer = GetLocalizedText("TXT_KEY_MISC_YOU_UNIT_CAPTURED_ENEMY_CITY", pkAttacker->getNameKey(), iDefenderDamageInflicted, pkDefender->getNameKey());1308 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkAttacker->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*, GC.getEraInfo(GC.getGame().getCurrentEra())->getAudioUnitVictoryScript(), MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pkPlot->getX(), pkPlot->getY()*/);1309 MILITARYLOG(pkAttacker->getOwner(), strBuffer.c_str(), pkDefender->plot(), pkDefender->getOwner());1310 }1311 if(pkDefender->getOwner() == iActivePlayerID)1312 {1313 strBuffer = GetLocalizedText("TXT_KEY_MISC_YOU_CITY_WAS_CAPTURED", pkDefender->getNameKey(), pkAttacker->getNameKey(), pkAttacker->getVisualCivAdjective(pkDefender->getTeam()), iDefenderDamageInflicted);1314 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkDefender->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*,GC.getEraInfo(GC.getGame().getCurrentEra())->getAudioUnitDefeatScript(), MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pkPlot->getX(), pkPlot->getY()*/);1315 MILITARYLOG(pkDefender->getOwner(), strBuffer.c_str(), pkDefender->plot(), pkAttacker->getOwner());1316 }13171318 pkAttacker->UnitMove(pkPlot, true, pkAttacker);13191320 bCityConquered = true;1321 }1322 }1323 // Neither side lost1324 else1325 {1326 if(pkAttacker->getOwner() == iActivePlayerID)1327 {1328 strBuffer = GetLocalizedText("TXT_KEY_MISC_YOU_UNIT_WITHDRAW_CITY", pkAttacker->getNameKey(), iDefenderDamageInflicted, pkDefender->getNameKey(), iAttackerDamageInflicted);1329 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkAttacker->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*, "AS2D_OUR_WITHDRAWL", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pkPlot->getX(), pkPlot->getY()*/);1330 MILITARYLOG(pkAttacker->getOwner(), strBuffer.c_str(), pkAttacker->plot(), pkDefender->getOwner());1331 }1332 if(pkDefender->getOwner() == iActivePlayerID)1333 {1334 strBuffer = GetLocalizedText("TXT_KEY_MISC_ENEMY_UNIT_WITHDRAW_CITY", pkAttacker->getNameKey(), iDefenderDamageInflicted, pkDefender->getNameKey(), iAttackerDamageInflicted);1335 GC.GetEngineUserInterface()->AddMessage(uiParentEventID, pkDefender->getOwner(), true, GC.getEVENT_MESSAGE_TIME(), strBuffer/*, "AS2D_THEIR_WITHDRAWL", MESSAGE_TYPE_INFO, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pkPlot->getX(), pkPlot->getY()*/);1336 MILITARYLOG(pkDefender->getOwner(), strBuffer.c_str(), pkDefender->plot(), pkAttacker->getOwner());1337 }1338 pkAttacker->changeMoves(-GC.getMOVE_DENOMINATOR());13391340 ApplyPostCityCombatEffects(pkAttacker, pkDefender, iAttackerDamageInflicted);1341 }1342 }13431344 if(pkAttacker)1345 {1346 pkAttacker->PublishQueuedVisualizationMoves();13471348 if(!pkAttacker->canMoveAfterAttacking())1349 {1350 pkAttacker->finishMoves();1351 GC.GetEngineUserInterface()->changeCycleSelectionCounter(1);1352 }13531354 // Report that combat is over in case we want to queue another attack1355 GET_PLAYER(pkAttacker->getOwner()).GetTacticalAI()->CombatResolved(pkAttacker, bCityConquered);1356 }1357 1358 BATTLE_FINISHED();1359}