Bazaar developer reference

CvCity::GetBuyablePlotList(std::vector<int> &)

Defined in
CvCity.cpp, line 12088
Class
CvCity
Hook name
CivHooks::CvCity_GetBuyablePlotList
Lua events
GameEvents.CityCanAcquirePlot

Hooks

static bool BeforeCvCity_GetBuyablePlotList(CvCity* self, std::vector<int>& aiPlotList);static void AfterCvCity_GetBuyablePlotList(CvCity* self, std::vector<int>& aiPlotList);static void ReplaceCvCity_GetBuyablePlotList(void (*original)(CvCity*, std::vector<int>&), CvCity* self, std::vector<int>& aiPlotList);CivRegisterBefore<CivHooks::CvCity_GetBuyablePlotList>(host, &BeforeCvCity_GetBuyablePlotList);CivRegisterAfter<CivHooks::CvCity_GetBuyablePlotList>(host, &AfterCvCity_GetBuyablePlotList);CivRegisterReplace<CivHooks::CvCity_GetBuyablePlotList>(host, &ReplaceCvCity_GetBuyablePlotList);

Code

12088void CvCity::GetBuyablePlotList(std::vector<int>& aiPlotList)12089{12090	VALIDATE_OBJECT12091	aiPlotList.resize(20, -1);12092	int iResultListIndex = 0;1209312094	int iLowestCost = INT_MAX;12095	CvPlot* pLoopPlot = NULL;12096	CvPlot* pThisPlot = plot();12097	const int iMaxRange = /*5*/ GC.getMAXIMUM_ACQUIRE_PLOT_DISTANCE();12098	CvMap& thisMap = GC.getMap();12099	TeamTypes thisTeam = getTeam();1210012101	int iPLOT_INFLUENCE_DISTANCE_MULTIPLIER =	/*100*/ GC.getPLOT_INFLUENCE_DISTANCE_MULTIPLIER();12102	int iPLOT_INFLUENCE_RING_COST =				/*100*/ GC.getPLOT_INFLUENCE_RING_COST();12103	int iPLOT_INFLUENCE_WATER_COST =			/* 25*/ GC.getPLOT_INFLUENCE_WATER_COST();12104	int iPLOT_INFLUENCE_IMPROVEMENT_COST =		/* -5*/ GC.getPLOT_INFLUENCE_IMPROVEMENT_COST();12105	int iPLOT_INFLUENCE_ROUTE_COST =			/*0*/	GC.getPLOT_INFLUENCE_ROUTE_COST();12106	int iPLOT_INFLUENCE_RESOURCE_COST =			/*-105*/ GC.getPLOT_INFLUENCE_RESOURCE_COST();12107	int iPLOT_INFLUENCE_NW_COST =				/*-105*/ GC.getPLOT_INFLUENCE_NW_COST();12108	int iPLOT_INFLUENCE_YIELD_POINT_COST =		/*-1*/	GC.getPLOT_INFLUENCE_YIELD_POINT_COST();1210912110	int iPLOT_INFLUENCE_NO_ADJACENT_OWNED_COST = /*1000*/ GC.getPLOT_INFLUENCE_NO_ADJACENT_OWNED_COST();1211112112	int iYieldLoop;1211312114	int iDirectionLoop;12115	bool bFoundAdjacentOwnedByCity;1211612117	int iDX, iDY;1211812119	ImprovementTypes eBarbCamptype = (ImprovementTypes)GC.getBARBARIAN_CAMP_IMPROVEMENT();1212012121	for (iDX = -iMaxRange; iDX <= iMaxRange; iDX++)12122	{12123		for (iDY = -iMaxRange; iDY <= iMaxRange; iDY++)12124		{12125			pLoopPlot = plotXYWithRangeCheck(getX(), getY(), iDX, iDY, iMaxRange);12126			if (pLoopPlot != NULL)12127			{12128				if (pLoopPlot->getOwner() != NO_PLAYER)12129				{12130					continue;12131				}1213212133#if defined(MOD_EVENTS_CITY_BORDERS)12134				// This can be used to implement a 12-mile limit12135				if (MOD_EVENTS_CITY_BORDERS) {12136					if (GAMEEVENTINVOKE_TESTALL(GAMEEVENT_CityCanAcquirePlot, getOwner(), GetID(), pLoopPlot->getX(), pLoopPlot->getY()) == GAMEEVENTRETURN_FALSE) {12137						continue;12138					}12139				} else {12140#endif				12141				ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();12142				if (pkScriptSystem) 12143				{12144					CvLuaArgsHandle args;12145					args->Push(getOwner());12146					args->Push(GetID());12147					args->Push(pLoopPlot->getX());12148					args->Push(pLoopPlot->getY());1214912150					bool bResult = false;12151					if (LuaSupport::CallTestAll(pkScriptSystem, "CityCanAcquirePlot", args.get(), bResult))12152					{12153						if (bResult == false) {12154							continue;12155						}12156					}12157				}12158#if defined(MOD_EVENTS_CITY_BORDERS)12159				}12160#endif				1216112162				// we can use the faster, but slightly inaccurate pathfinder here - after all we are using a rand in the equation12163				int iInfluenceCost = thisMap.calculateInfluenceDistance(pThisPlot, pLoopPlot, iMaxRange, false) * iPLOT_INFLUENCE_DISTANCE_MULTIPLIER;1216412165				if (iInfluenceCost > 0)12166				{12167					// Modifications for tie-breakers in a ring1216812169					// Resource Plots claimed first12170					ResourceTypes eResource = pLoopPlot->getResourceType(thisTeam);12171					if (eResource != NO_RESOURCE)12172					{12173						iInfluenceCost += iPLOT_INFLUENCE_RESOURCE_COST;12174						bool bBonusResource = GC.getResourceInfo(eResource)->getResourceUsage() == RESOURCEUSAGE_BONUS;12175						if (bBonusResource)12176						{12177#if defined(MOD_GLOBAL_CITY_WORKING)12178							if (plotDistance(pLoopPlot->getX(),pLoopPlot->getY(),getX(),getY()) > getWorkPlotDistance())12179#else	12180							if (plotDistance(pLoopPlot->getX(),pLoopPlot->getY(),getX(),getY()) > NUM_CITY_RINGS)12181#endif12182							{12183								// undo the bonus - we can't work this tile from this city12184								iInfluenceCost -= iPLOT_INFLUENCE_RESOURCE_COST;12185							}12186							else12187							{12188								// very slightly decrease value of bonus resources12189								++iInfluenceCost;12190							}12191						}12192					}12193					else 12194					{1219512196						// Water Plots claimed later12197						if (pLoopPlot->isWater())12198						{12199							iInfluenceCost += iPLOT_INFLUENCE_WATER_COST;12200						}1220112202						// if we can't work this tile in this city make it much less likely to be picked12203#if defined(MOD_GLOBAL_CITY_WORKING)12204						if (plotDistance(pLoopPlot->getX(),pLoopPlot->getY(),getX(),getY()) > getWorkPlotDistance())12205#else	12206						if (plotDistance(pLoopPlot->getX(),pLoopPlot->getY(),getX(),getY()) > NUM_CITY_RINGS)12207#endif12208						{12209							iInfluenceCost += iPLOT_INFLUENCE_RING_COST;12210						}1221112212					}1221312214					// improved tiles get a slight priority (unless they are barbarian camps!)12215					ImprovementTypes thisImprovement = pLoopPlot->getImprovementType();12216					if (thisImprovement != NO_IMPROVEMENT)12217					{12218						if (thisImprovement == eBarbCamptype)12219						{12220							iInfluenceCost += iPLOT_INFLUENCE_RING_COST;12221						}12222						else12223						{12224							iInfluenceCost += iPLOT_INFLUENCE_IMPROVEMENT_COST;12225						}12226					}1222712228					// roaded tiles get a priority - [not any more: weight above is 0 by default]12229					if (pLoopPlot->getRouteType() != NO_ROUTE)12230					{12231						iInfluenceCost += iPLOT_INFLUENCE_ROUTE_COST;12232					}1223312234					// while we're at it grab Natural Wonders quickly also12235					if (pLoopPlot->IsNaturalWonder())12236					{12237						iInfluenceCost += iPLOT_INFLUENCE_NW_COST;12238					}1223912240					// More Yield == more desirable12241					for (iYieldLoop = 0; iYieldLoop < NUM_YIELD_TYPES; iYieldLoop++)12242					{12243						iInfluenceCost += (iPLOT_INFLUENCE_YIELD_POINT_COST * pLoopPlot->getYield((YieldTypes) iYieldLoop));12244					}1224512246					// all other things being equal move towards unclaimed resources12247					bool bUnownedNaturalWonderAdjacentCount = false;12248					for (int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)12249					{12250						CvPlot* pAdjacentPlot = plotDirection(pLoopPlot->getX(), pLoopPlot->getY(), ((DirectionTypes)iI));1225112252						if (pAdjacentPlot != NULL)12253						{12254							if (pAdjacentPlot->getOwner() == NO_PLAYER)12255							{12256								int iPlotDistance = plotDistance(getX(), getY(), pAdjacentPlot->getX(), pAdjacentPlot->getY());12257								ResourceTypes eAdjacentResource = pAdjacentPlot->getResourceType(thisTeam);12258								if (eAdjacentResource != NO_RESOURCE)12259								{12260									// if we are close enough to work, or this is not a bonus resource12261#if defined(MOD_GLOBAL_CITY_WORKING)12262									if (iPlotDistance <= getWorkPlotDistance() || GC.getResourceInfo(eAdjacentResource)->getResourceUsage() != RESOURCEUSAGE_BONUS)12263#else	12264									if (iPlotDistance <= NUM_CITY_RINGS || GC.getResourceInfo(eAdjacentResource)->getResourceUsage() != RESOURCEUSAGE_BONUS)12265#endif12266									{12267										--iInfluenceCost;12268									}12269								}12270								if (pAdjacentPlot->IsNaturalWonder())12271								{12272#if defined(MOD_GLOBAL_CITY_WORKING)12273									if (iPlotDistance <= getWorkPlotDistance()) // grab for this city12274#else	12275									if (iPlotDistance <= NUM_CITY_RINGS) // grab for this city12276#endif12277									{12278										bUnownedNaturalWonderAdjacentCount = true;12279									}12280									--iInfluenceCost; // but we will slightly grow towards it for style in any case12281								}12282							}12283						}12284					}1228512286					// move towards unclaimed NW12287					iInfluenceCost += bUnownedNaturalWonderAdjacentCount ? -1 : 0;1228812289					// Plots not adjacent to another Plot acquired by this City are pretty much impossible to get12290					bFoundAdjacentOwnedByCity = false;12291					for (iDirectionLoop = 0; iDirectionLoop < NUM_DIRECTION_TYPES; iDirectionLoop++)12292					{12293						CvPlot* pAdjacentPlot = plotDirection(pLoopPlot->getX(), pLoopPlot->getY(), (DirectionTypes) iDirectionLoop);1229412295						if (pAdjacentPlot != NULL)12296						{12297							// Have to check plot ownership first because the City IDs match between different players!!!12298							if (pAdjacentPlot->getOwner() == getOwner() && pAdjacentPlot->GetCityPurchaseID() == GetID())12299							{12300								bFoundAdjacentOwnedByCity = true;12301								break;12302							}12303						}12304					}12305					if (!bFoundAdjacentOwnedByCity)12306					{12307						iInfluenceCost += iPLOT_INFLUENCE_NO_ADJACENT_OWNED_COST;12308					}1230912310#if defined(MOD_UI_CITY_EXPANSION)12311					// Group very similiar "cost" tiles - ie 683 and 684 cost tiles will appear to be the same value12312					int iDivisor = /*5*/ GC.getPLOT_INFLUENCE_COST_VISIBLE_DIVISOR();12313					iInfluenceCost /= iDivisor;12314					iInfluenceCost *= iDivisor;12315#endif1231612317					// Are we cheap enough to get picked next?12318					if (iInfluenceCost < iLowestCost)12319					{12320						// clear reset list12321						for(uint ui = 0; ui < aiPlotList.size(); ui++)12322						{12323							aiPlotList[ui] = -1;12324						}12325						iResultListIndex = 0;12326						iLowestCost = iInfluenceCost;12327						// this will "fall through" to the next conditional12328					}1232912330					if (iInfluenceCost == iLowestCost)12331					{12332						aiPlotList[iResultListIndex] = pLoopPlot->GetPlotIndex();12333						iResultListIndex++;12334					}12335				}12336			}12337		}12338	}1233912340}

Calls

Called by