Bazaar developer reference

CvUnitCombat::ApplyNuclearExplosionDamage(const CvCombatMemberEntry *, int, CvUnit *, CvPlot *, int)

Defined in
CvUnitCombat.cpp, line 2396
Class
CvUnitCombat
Hook name
CivHooks::CvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int

Hooks

static bool BeforeCvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int(const CvCombatMemberEntry* pkDamageArray, int iDamageMembers, CvUnit* pkAttacker, CvPlot* pkTargetPlot, int iDamageLevel, uint& result);static void AfterCvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int(const CvCombatMemberEntry* pkDamageArray, int iDamageMembers, CvUnit* pkAttacker, CvPlot* pkTargetPlot, int iDamageLevel, uint& result);static uint ReplaceCvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int(uint (*original)(const CvCombatMemberEntry*, int, CvUnit*, CvPlot*, int), const CvCombatMemberEntry* pkDamageArray, int iDamageMembers, CvUnit* pkAttacker, CvPlot* pkTargetPlot, int iDamageLevel);CivRegisterBefore<CivHooks::CvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int>(host, &BeforeCvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int);CivRegisterAfter<CivHooks::CvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int>(host, &AfterCvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int);CivRegisterReplace<CivHooks::CvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int>(host, &ReplaceCvUnitCombat_ApplyNuclearExplosionDamage_with_const_CvCombatMemberEntry_int_CvUnit_CvPlot_int);

Code

2396uint CvUnitCombat::ApplyNuclearExplosionDamage(const CvCombatMemberEntry* pkDamageArray, int iDamageMembers, CvUnit* pkAttacker, CvPlot* pkTargetPlot, int iDamageLevel)2397{2398	uint uiOpposingDamageCount = 0;2399	PlayerTypes eAttackerOwner = pkAttacker?pkAttacker->getOwner():NO_PLAYER;24002401	// Do all the units first2402	for(int i = 0; i < iDamageMembers; ++i)2403	{2404		const CvCombatMemberEntry& kEntry = pkDamageArray[i];2405		if(kEntry.IsUnit())2406		{2407			CvUnit* pkUnit = GET_PLAYER(kEntry.GetPlayer()).getUnit(kEntry.GetUnitID());2408			if(pkUnit)2409			{2410				// Apply the damage2411				pkUnit->setCombatUnit(NULL);2412				pkUnit->ClearMissionQueue();2413				pkUnit->SetAutomateType(NO_AUTOMATE); // kick unit out of automation24142415				if((eAttackerOwner == NO_PLAYER || pkUnit->getOwner() != eAttackerOwner) && !pkUnit->isBarbarian())2416					uiOpposingDamageCount++;	// Count the number of non-barbarian opposing units24172418				if(pkUnit->IsCombatUnit() || pkUnit->IsCanAttackRanged())2419				{2420#if defined(MOD_API_UNIT_STATS)2421					pkUnit->changeDamage(kEntry.GetDamage(), eAttackerOwner, pkAttacker ? pkAttacker->GetID() : -1);2422#else2423					pkUnit->changeDamage(kEntry.GetDamage(), eAttackerOwner);2424#endif2425				}2426				else if(kEntry.GetDamage() >= /*6*/ GC.getNUKE_NON_COMBAT_DEATH_THRESHOLD())2427				{2428					pkUnit->kill(false, eAttackerOwner);2429				}24302431				GET_PLAYER(kEntry.GetPlayer()).GetDiplomacyAI()->ChangeNumTimesNuked(pkAttacker->getOwner(), 1);2432			}2433		}2434	}24352436	// Then the terrain effects2437	int iBlastRadius = GC.getNUKE_BLAST_RADIUS();24382439	for(int iDX = -(iBlastRadius); iDX <= iBlastRadius; iDX++)2440	{2441		for(int iDY = -(iBlastRadius); iDY <= iBlastRadius; iDY++)2442		{2443			CvPlot* pLoopPlot = plotXYWithRangeCheck(pkTargetPlot->getX(), pkTargetPlot->getY(), iDX, iDY, iBlastRadius);24442445			if(pLoopPlot != NULL)2446			{2447				// if we remove roads, don't remove them on the city... XXX2448				CvCity* pLoopCity = pLoopPlot->getPlotCity();24492450				if(pLoopCity == NULL)2451				{2452					if(!(pLoopPlot->isWater()) && !(pLoopPlot->isImpassable()))2453					{2454						if(pLoopPlot->getFeatureType() != NO_FEATURE)2455						{2456							CvFeatureInfo* pkFeatureInfo = GC.getFeatureInfo(pLoopPlot->getFeatureType());2457							if(pkFeatureInfo && !pkFeatureInfo->isNukeImmune())2458							{2459								if(pLoopPlot == pkTargetPlot || GC.getGame().getJonRandNum(100, "Nuke Fallout") < GC.getNUKE_FALLOUT_PROB())2460								{2461									if(pLoopPlot->getImprovementType() != NO_IMPROVEMENT)2462									{2463										pLoopPlot->SetImprovementPillaged(true);2464									}2465									pLoopPlot->setFeatureType((FeatureTypes)(GC.getNUKE_FEATURE()));2466								}2467							}2468						}2469						else2470						{2471							if(pLoopPlot == pkTargetPlot || GC.getGame().getJonRandNum(100, "Nuke Fallout") < GC.getNUKE_FALLOUT_PROB())2472							{2473								if(pLoopPlot->getImprovementType() != NO_IMPROVEMENT)2474								{2475									pLoopPlot->SetImprovementPillaged(true);2476								}2477								pLoopPlot->setFeatureType((FeatureTypes)(GC.getNUKE_FEATURE()));2478							}2479						}2480#if defined(MOD_GLOBAL_NUKES_MELT_ICE)2481					} else if (MOD_GLOBAL_NUKES_MELT_ICE && pLoopPlot->getFeatureType() == FEATURE_ICE) {2482						if (pLoopPlot == pkTargetPlot || GC.getGame().getJonRandNum(100, "Nuke Fallout") < GC.getNUKE_FALLOUT_PROB()) {2483							pLoopPlot->setFeatureType(NO_FEATURE);2484						}2485#endif2486					}2487				}2488			}2489		}2490	}24912492	// Then the cities2493	for(int i = 0; i < iDamageMembers; ++i)2494	{2495		const CvCombatMemberEntry& kEntry = pkDamageArray[i];2496		if(kEntry.IsCity())2497		{2498			CvCity* pkCity = GET_PLAYER(kEntry.GetPlayer()).getCity(kEntry.GetCityID());2499			if(pkCity)2500			{2501				pkCity->setCombatUnit(NULL);25022503				if(eAttackerOwner == NO_PLAYER || pkCity->getOwner() != eAttackerOwner)2504					uiOpposingDamageCount++;25052506				if(kEntry.GetFinalDamage() >= pkCity->GetMaxHitPoints() && !pkCity->IsOriginalCapital())2507				{2508					auto_ptr<ICvCity1> pkDllCity(new CvDllCity(pkCity));2509					gDLL->GameplayCitySetDamage(pkDllCity.get(), 0, pkCity->getDamage()); // to stop the fires2510					gDLL->GameplayCityDestroyed(pkDllCity.get(), NO_PLAYER);25112512					PlayerTypes eOldOwner = pkCity->getOwner();2513					pkCity->kill();25142515					// slewis - check for killing a player2516					GET_PLAYER(pkAttacker->getOwner()).CheckForMurder(eOldOwner);2517				}2518				else2519				{2520					// Unlike the city hit points, the population damage is calculated when the pre-calculated damage is applied.2521					// This is simply to save space in the damage array, since the combat visualization does not need it.2522					// It can be moved into the pre-calculated damage array if needed.2523					int iBaseDamage, iRandDamage1, iRandDamage2;2524					// How much destruction is unleashed on nearby Cities?2525					if(iDamageLevel == 1)2526					{2527						iBaseDamage = /*30*/ GC.getNUKE_LEVEL1_POPULATION_DEATH_BASE();2528						iRandDamage1 = GC.getGame().getJonRandNum(/*20*/ GC.getNUKE_LEVEL1_POPULATION_DEATH_RAND_1(), "Population Nuked 1");2529						iRandDamage2 = GC.getGame().getJonRandNum(/*20*/ GC.getNUKE_LEVEL1_POPULATION_DEATH_RAND_2(), "Population Nuked 2");2530					}2531					else2532					{2533						iBaseDamage = /*60*/ GC.getNUKE_LEVEL2_POPULATION_DEATH_BASE();2534						iRandDamage1 = GC.getGame().getJonRandNum(/*10*/ GC.getNUKE_LEVEL2_POPULATION_DEATH_RAND_1(), "Population Nuked 1");2535						iRandDamage2 = GC.getGame().getJonRandNum(/*10*/ GC.getNUKE_LEVEL2_POPULATION_DEATH_RAND_2(), "Population Nuked 2");2536					}25372538					int iNukedPopulation = pkCity->getPopulation() * (iBaseDamage + iRandDamage1 + iRandDamage2) / 100;25392540					iNukedPopulation *= std::max(0, (pkCity->getNukeModifier() + 100));2541					iNukedPopulation /= 100;25422543					pkCity->changePopulation(-(std::min((pkCity->getPopulation() - 1), iNukedPopulation)));25442545					// Add damage to the city2546					pkCity->setDamage(kEntry.GetFinalDamage());25472548					GET_PLAYER(pkCity->getOwner()).GetDiplomacyAI()->ChangeNumTimesNuked(pkAttacker->getOwner(), 1);2549				}2550			}2551		}2552	}2553	return uiOpposingDamageCount;2554}

Calls

Called by