Bazaar developer reference

CvUnitCombat::GenerateNuclearExplosionDamage(CvPlot *, int, CvUnit *, CvCombatMemberEntry *, int *, int)

Defined in
CvUnitCombat.cpp, line 2559
Class
CvUnitCombat
Hook name
CivHooks::CvUnitCombat_GenerateNuclearExplosionDamage

Hooks

static bool BeforeCvUnitCombat_GenerateNuclearExplosionDamage(CvPlot* pkTargetPlot, int iDamageLevel, CvUnit* pkAttacker, CvCombatMemberEntry* pkDamageArray, int* piDamageMembers, int iMaxDamageMembers);static void AfterCvUnitCombat_GenerateNuclearExplosionDamage(CvPlot* pkTargetPlot, int iDamageLevel, CvUnit* pkAttacker, CvCombatMemberEntry* pkDamageArray, int* piDamageMembers, int iMaxDamageMembers);static void ReplaceCvUnitCombat_GenerateNuclearExplosionDamage(void (*original)(CvPlot*, int, CvUnit*, CvCombatMemberEntry*, int*, int), CvPlot* pkTargetPlot, int iDamageLevel, CvUnit* pkAttacker, CvCombatMemberEntry* pkDamageArray, int* piDamageMembers, int iMaxDamageMembers);CivRegisterBefore<CivHooks::CvUnitCombat_GenerateNuclearExplosionDamage>(host, &BeforeCvUnitCombat_GenerateNuclearExplosionDamage);CivRegisterAfter<CivHooks::CvUnitCombat_GenerateNuclearExplosionDamage>(host, &AfterCvUnitCombat_GenerateNuclearExplosionDamage);CivRegisterReplace<CivHooks::CvUnitCombat_GenerateNuclearExplosionDamage>(host, &ReplaceCvUnitCombat_GenerateNuclearExplosionDamage);

Code

2557//	Generate nuclear explosion damage for all the units and cities in the radius of the specified plot.2558//	The attacker is optional, this is also called for a meltdown2559void CvUnitCombat::GenerateNuclearExplosionDamage(CvPlot* pkTargetPlot, int iDamageLevel, CvUnit* pkAttacker, CvCombatMemberEntry* pkDamageArray, int* piDamageMembers, int iMaxDamageMembers)2560{2561	int iBlastRadius = GC.getNUKE_BLAST_RADIUS();25622563#if defined(MOD_EVENTS_BATTLES)2564	CvCity* pDefenderCity = NULL;2565	CvUnit* pDefenderUnit = NULL;25662567	if (pkTargetPlot->isCity())2568	{2569		pDefenderCity = pkTargetPlot->getPlotCity();2570	}2571	else2572	{2573		pDefenderUnit = pkTargetPlot->getBestDefender(NO_PLAYER, pkAttacker->getOwner()).pointer();2574	}2575#endif25762577	*piDamageMembers = 0;25782579	for(int iDX = -(iBlastRadius); iDX <= iBlastRadius; iDX++)2580	{2581		for(int iDY = -(iBlastRadius); iDY <= iBlastRadius; iDY++)2582		{2583			CvPlot* pLoopPlot = plotXYWithRangeCheck(pkTargetPlot->getX(), pkTargetPlot->getY(), iDX, iDY, iBlastRadius);25842585			if(pLoopPlot != NULL)2586			{2587				CvCity* pLoopCity = pLoopPlot->getPlotCity();25882589				FFastSmallFixedList<IDInfo, 25, true, c_eCiv5GameplayDLL > oldUnits;2590				IDInfo* pUnitNode = pLoopPlot->headUnitNode();25912592				while(pUnitNode != NULL)2593				{2594					oldUnits.insertAtEnd(pUnitNode);2595					pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);2596				}25972598				pUnitNode = oldUnits.head();25992600				while(pUnitNode != NULL)2601				{2602					CvUnit* pLoopUnit = ::getUnit(*pUnitNode);2603					pUnitNode = oldUnits.next(pUnitNode);26042605					if(pLoopUnit != NULL)2606					{2607						if(pLoopUnit != pkAttacker)2608						{2609							if(!pLoopUnit->isNukeImmune() && !pLoopUnit->isDelayedDeath())2610							{2611								int iNukeDamage;2612								// How much destruction is unleashed on nearby Units?2613								if(iDamageLevel == 1 && pLoopPlot != pkTargetPlot)	// Nuke level 1, but NOT the plot that got hit directly (units there are killed)2614								{2615									iNukeDamage = (/*3*/ GC.getNUKE_UNIT_DAMAGE_BASE() + /*4*/ GC.getGame().getJonRandNum(GC.getNUKE_UNIT_DAMAGE_RAND_1(), "Nuke Damage 1") + /*4*/ GC.getGame().getJonRandNum(GC.getNUKE_UNIT_DAMAGE_RAND_2(), "Nuke Damage 2"));2616								}2617								// Wipe everything out2618								else2619								{2620#if defined(MOD_UNITS_MAX_HP)2621									iNukeDamage = pLoopUnit->GetMaxHitPoints();2622#else2623									iNukeDamage = GC.getMAX_HIT_POINTS();2624#endif2625								}26262627								if(pLoopCity != NULL)2628								{2629									iNukeDamage *= std::max(0, (pLoopCity->getNukeModifier() + 100));2630									iNukeDamage /= 100;2631								}26322633								CvCombatMemberEntry* pkDamageEntry = AddCombatMember(pkDamageArray, piDamageMembers, iMaxDamageMembers, pLoopUnit);2634								if(pkDamageEntry)2635								{2636#if defined(MOD_EVENTS_BATTLES)2637									if (pLoopUnit != pDefenderUnit)2638									{2639										BATTLE_JOINED(pLoopUnit, BATTLE_UNIT_COUNT, false); // Bit of a fudge, as BATTLE_UNIT_COUNT happens to correspond to BATTLEUNIT_BYSTANDER2640									}2641#endif2642									pkDamageEntry->SetDamage(iNukeDamage);2643#if defined(MOD_UNITS_MAX_HP)2644									pkDamageEntry->SetFinalDamage(std::min(iNukeDamage + pLoopUnit->getDamage(), pLoopUnit->GetMaxHitPoints()));2645									pkDamageEntry->SetMaxHitPoints(pLoopUnit->GetMaxHitPoints());2646#else2647									pkDamageEntry->SetFinalDamage(std::min(iNukeDamage + pLoopUnit->getDamage(), GC.getMAX_HIT_POINTS()));2648									pkDamageEntry->SetMaxHitPoints(GC.getMAX_HIT_POINTS());2649#endif2650									if(pkAttacker)2651										pLoopUnit->setCombatUnit(pkAttacker);2652								}2653								else2654								{2655									CvAssertMsg(*piDamageMembers < iMaxDamageMembers, "Ran out of entries for the nuclear damage array");2656								}2657							}2658						}2659					}2660				}26612662				if(pLoopCity != NULL)2663				{2664					bool bKillCity = false;26652666					// Is the city wiped out? - no capitals!2667					if(!pLoopCity->IsOriginalCapital())2668					{2669						if(iDamageLevel > 2)2670						{2671							bKillCity = true;2672						}2673						else if(iDamageLevel > 1)2674						{2675							if(pLoopCity->getPopulation() < /*5*/ GC.getNUKE_LEVEL2_ELIM_POPULATION_THRESHOLD())2676							{2677								bKillCity = true;2678							}2679						}2680					}26812682					int iTotalDamage;2683					if(bKillCity)2684					{2685						iTotalDamage = pLoopCity->GetMaxHitPoints();2686					}2687					else2688					{2689						// Add damage to the city2690						iTotalDamage = (pLoopCity->GetMaxHitPoints() - pLoopCity->getDamage()) * /*50*/ GC.getNUKE_CITY_HIT_POINT_DAMAGE();2691						iTotalDamage /= 100;26922693						iTotalDamage += pLoopCity->getDamage();26942695						// Can't bring a city below 1 HP2696						iTotalDamage = min(iTotalDamage, pLoopCity->GetMaxHitPoints() - 1);2697					}26982699					CvCombatMemberEntry* pkDamageEntry = AddCombatMember(pkDamageArray, piDamageMembers, iMaxDamageMembers, pLoopCity);2700					if(pkDamageEntry)2701					{2702#if defined(MOD_EVENTS_BATTLES)2703						if (pLoopCity != pDefenderCity)2704						{2705							BATTLE_JOINED(pLoopCity, BATTLE_UNIT_COUNT, true); // Bit of a fudge, as BATTLE_UNIT_COUNT happens to correspond to BATTLEUNIT_BYSTANDER2706						}2707#endif2708						pkDamageEntry->SetDamage(iTotalDamage - pLoopCity->getDamage());2709						pkDamageEntry->SetFinalDamage(iTotalDamage);2710						pkDamageEntry->SetMaxHitPoints(pLoopCity->GetMaxHitPoints());27112712						if(pkAttacker)2713							pLoopCity->setCombatUnit(pkAttacker);2714					}2715					else2716					{2717						CvAssertMsg(*piDamageMembers < iMaxDamageMembers, "Ran out of entries for the nuclear damage array");2718					}2719				}2720			}2721		}2722	}2723}

Calls

Called by