Bazaar developer reference

CvBarbarians::DoCamps()

Defined in
CvBarbarians.cpp, line 289
Class
CvBarbarians
Hook name
CivHooks::CvBarbarians_DoCamps
Lua events
GameEvents.BarbariansSpawnedUnit

Hooks

static bool BeforeCvBarbarians_DoCamps();static void AfterCvBarbarians_DoCamps();static void ReplaceCvBarbarians_DoCamps(void (*original)());CivRegisterBefore<CivHooks::CvBarbarians_DoCamps>(host, &BeforeCvBarbarians_DoCamps);CivRegisterAfter<CivHooks::CvBarbarians_DoCamps>(host, &AfterCvBarbarians_DoCamps);CivRegisterReplace<CivHooks::CvBarbarians_DoCamps>(host, &ReplaceCvBarbarians_DoCamps);

Code

289void CvBarbarians::DoCamps()290{291	CvGame& kGame = GC.getGame();292293	if(kGame.isOption(GAMEOPTION_NO_BARBARIANS))294	{295		return;296	}297298	int iNumNotVisiblePlots = 0;299	int iNumCampsInExistence = 0;300	CvPlot* pLoopPlot;301302	ImprovementTypes eCamp = (ImprovementTypes)GC.getBARBARIAN_CAMP_IMPROVEMENT();303304	bool bAlwaysRevealedBarbCamp = false;305306	// Is there an appropriate Improvement to place as a Barb Camp?307	if(eCamp != NO_IMPROVEMENT)308	{309		CvMap& kMap = GC.getMap();310		// Figure out how many Nonvisible tiles we have to base # of camps to spawn on311		for(int iI = 0; iI < kMap.numPlots(); iI++)312		{313			pLoopPlot = kMap.plotByIndexUnchecked(iI);314315			// See how many camps we already have316			if(pLoopPlot->getImprovementType() == eCamp)317			{318				iNumCampsInExistence++;319			}320321			if(!pLoopPlot->isWater())322			{323				if(!pLoopPlot->isVisibleToCivTeam())324				{325					iNumNotVisiblePlots++;326				}327			}328		}329330		int iNumValidCampPlots;331332		iNumValidCampPlots = iNumNotVisiblePlots;333334		int iFogTilesPerBarbarianCamp = kMap.getWorldInfo().getFogTilesPerBarbarianCamp();335		int iCampTargetNum = (iFogTilesPerBarbarianCamp != 0)? iNumValidCampPlots / iFogTilesPerBarbarianCamp : 0;//getHandicapInfo().getFogTilesPerBarbarianCamp();336		int iNumCampsToAdd = iCampTargetNum - iNumCampsInExistence;337338		int iMaxCampsThisArea;339340		if(iNumCampsToAdd > 0 && GC.getBARBARIAN_CAMP_ODDS_OF_NEW_CAMP_SPAWNING() > 0) // slewis - added the barbarian chance for the FoR scenario341		{342			// First turn of the game add 1/3 of the Target number of Camps343			if(kGame.getElapsedGameTurns() == 0)344			{345				iNumCampsToAdd *= /*33*/ GC.getBARBARIAN_CAMP_FIRST_TURN_PERCENT_OF_TARGET_TO_ADD();346				iNumCampsToAdd /= 100;347			}348			// Every other turn of the game there's a 1 in 2 chance of adding a new camp if we're still below the target349			else350			{351				if(kGame.getJonRandNum(/*2*/ GC.getBARBARIAN_CAMP_ODDS_OF_NEW_CAMP_SPAWNING(), "Random roll to see if Barb Camp spawns this turn") > 0)352				{353					iNumCampsToAdd = 1;354				}355				else356				{357					iNumCampsToAdd = 0;358				}359			}360361			// Don't want to get stuck in an infinite or almost so loop362			int iCount = 0;363			int iPlotIndex = -1;364			int iNumPlots = kMap.numPlots();365366			UnitTypes eBestUnit;367368			int iNumLandPlots = kMap.getLandPlots();369370			// Do a random roll to bias in favor of Coastal land Tiles so that the Barbs will spawn Boats :) - required 1/6 of the time371			bool bWantsCoastal = kGame.getJonRandNum(/*6*/ GC.getBARBARIAN_CAMP_COASTAL_SPAWN_ROLL(), "Barb Camp Plot-Finding Roll - Coastal Bias 1") == 0 ? true : false;372373			int iPlayerCapitalMinDistance = /*4*/ GC.getBARBARIAN_CAMP_MINIMUM_DISTANCE_CAPITAL();374			int iBarbCampMinDistance = /*7*/ GC.getBARBARIAN_CAMP_MINIMUM_DISTANCE_ANOTHER_CAMP();375			int iMaxDistanceToLook = iPlayerCapitalMinDistance > iBarbCampMinDistance ? iPlayerCapitalMinDistance : iBarbCampMinDistance;376			int iPlotDistance;377378			int iDX, iDY;379			CvPlot* pNearbyCampPlot;380			bool bSomethingTooClose;381382			CvString strBuffer;383384			int iPlayerLoop;385386			// Find Plots to put the Camps387			do388			{389				iCount++;390391				iPlotIndex = kGame.getJonRandNum(iNumPlots, "Barb Camp Plot-Finding Roll");392393				pLoopPlot = kMap.plotByIndex(iPlotIndex);394395				// Plot must be valid (not Water, nonvisible)396				if(!pLoopPlot->isWater())397				{398					if(!pLoopPlot->isImpassable() && !pLoopPlot->isMountain())399					{400#if defined(MOD_BUGFIX_BARB_CAMP_TERRAINS)401						CvImprovementEntry* pkImprovementInfo = GC.getImprovementInfo(eCamp);402						if(MOD_BUGFIX_BARB_CAMP_TERRAINS == false || pkImprovementInfo == NULL || (pkImprovementInfo->GetTerrainMakesValid(pLoopPlot->getTerrainType()) && pkImprovementInfo->GetFeatureMakesValid(pLoopPlot->getFeatureType()))) {403#endif404						if(!pLoopPlot->isOwned() && !pLoopPlot->isVisibleToCivTeam())405						{406							// JON: NO RESOURCES FOR NOW, MAY REPLACE WITH SOMETHING COOLER407							if(pLoopPlot->getResourceType() == NO_RESOURCE)408							{409								// No camps on 1-tile islands410								if(kMap.getArea(pLoopPlot->getArea())->getNumTiles() > 1)411								{412									if(pLoopPlot->isCoastalLand() || !bWantsCoastal)413									{414										// Max Camps for this area415										iMaxCampsThisArea = iCampTargetNum * pLoopPlot->area()->getNumTiles() / iNumLandPlots;416										// Add 1 just in case the above algorithm rounded something off417										iMaxCampsThisArea++;418419										// Already enough Camps in this Area?420										if(pLoopPlot->area()->getNumImprovements(eCamp) <= iMaxCampsThisArea)421										{422											// Don't look at Tiles that already have a Camp423											if(pLoopPlot->getImprovementType() == NO_IMPROVEMENT)424											{425												// Don't look at Tiles that can't have an improvement426												if(pLoopPlot->getFeatureType() == NO_FEATURE || !GC.getFeatureInfo(pLoopPlot->getFeatureType())->isNoImprovement())427												{428													bSomethingTooClose = false;429430													// Look at nearby Plots to make sure another camp isn't too close431													for(iDX = -(iMaxDistanceToLook); iDX <= iMaxDistanceToLook; iDX++)432													{433														for(iDY = -(iMaxDistanceToLook); iDY <= iMaxDistanceToLook; iDY++)434														{435															pNearbyCampPlot = plotXY(pLoopPlot->getX(), pLoopPlot->getY(), iDX, iDY);436437															if(pNearbyCampPlot != NULL)438															{439																iPlotDistance = plotDistance(pNearbyCampPlot->getX(), pNearbyCampPlot->getY(), pLoopPlot->getX(), pLoopPlot->getY());440441																// Can't be too close to a player442																if(iPlotDistance <= iPlayerCapitalMinDistance)443																{444																	if(pNearbyCampPlot->isCity())445																	{446																		if(pNearbyCampPlot->getPlotCity()->isCapital())447																		{448																			// Only care about Majors' capitals449																			if(pNearbyCampPlot->getPlotCity()->getOwner() < MAX_MAJOR_CIVS)450																			{451																				bSomethingTooClose = true;452																				break;453																			}454																		}455																	}456																}457458																// Can't be too close to another Camp459																if(iPlotDistance <= iBarbCampMinDistance)460																{461																	if(pNearbyCampPlot->getImprovementType() == eCamp)462																	{463																		bSomethingTooClose = true;464																		break;465																	}466																}467															}468														}469														if(bSomethingTooClose)470														{471															break;472														}473													}474475													// Found a camp too close, check another Plot476													if(bSomethingTooClose)477														continue;478479													// Last check480													if(!CvBarbarians::IsPlotValidForBarbCamp(pLoopPlot))481														continue;482483													pLoopPlot->setImprovementType(eCamp);484#if !defined(MOD_BUGFIX_BARB_CAMP_SPAWNING)485													// The notification has been moved into the CvPlot::setImprovementType() method486													DoCampActivationNotice(pLoopPlot);487#endif488489#if defined(MOD_EVENTS_BARBARIANS)490													eBestUnit = GetRandomBarbarianUnitType(pLoopPlot, UNITAI_DEFENSE);491#else492													eBestUnit = GetRandomBarbarianUnitType(kMap.getArea(pLoopPlot->getArea()), UNITAI_DEFENSE);493#endif494495													if(eBestUnit != NO_UNIT)496													{497														GET_PLAYER(BARBARIAN_PLAYER).initUnit(eBestUnit, pLoopPlot->getX(), pLoopPlot->getY(), (UnitAITypes) GC.getUnitInfo(eBestUnit)->GetDefaultUnitAIType());498499#if defined(MOD_EVENTS_BARBARIANS)500														if (MOD_EVENTS_BARBARIANS) {501															GAMEEVENTINVOKE_HOOK(GAMEEVENT_BarbariansSpawnedUnit, pLoopPlot->getX(), pLoopPlot->getY(), eBestUnit);502														}503#endif504													}505506													// If we should update Camp visibility (for Policy), do so507													PlayerTypes ePlayer;508													TeamTypes eTeam;509													for(iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)510													{511														ePlayer = (PlayerTypes) iPlayerLoop;512														eTeam = GET_PLAYER(ePlayer).getTeam();513514														if(GET_PLAYER(ePlayer).IsAlwaysSeeBarbCamps())515														{516															if(pLoopPlot->isRevealed(eTeam))517															{518																pLoopPlot->setRevealedImprovementType(eTeam, eCamp);519																if(GC.getGame().getActivePlayer() == ePlayer)520																	bAlwaysRevealedBarbCamp = true;521															}522														}523													}524525													// Add another Unit adjacent to the Camp to stir up some trouble (JON: Disabled for now 09/12/09)526													//doSpawnBarbarianUnit(pLoopPlot);527528													iNumCampsToAdd--;529530													// Seed the next Camp for Coast or not531													bWantsCoastal = kGame.getJonRandNum(/*5*/ GC.getBARBARIAN_CAMP_COASTAL_SPAWN_ROLL(), "Barb Camp Plot-Finding Roll - Coastal Bias 2") == 0 ? true : false;532												}533											}534										}535									}536								}537							}538						}539#if defined(MOD_BUGFIX_BARB_CAMP_TERRAINS)540						}541#endif542					}543				}544			}545			while(iNumCampsToAdd > 0 && iCount < iNumLandPlots);546		}547	}548549	if(bAlwaysRevealedBarbCamp)550		GC.getMap().updateDeferredFog();551}

Calls

Called by