Resource "near" a city?

Define "near".

When coding up my Zombie Apocalypse mod I needed to check adjacent plots for various conditions, and whilst the loop in my implementation is unrolled I could provide a version that loops through all plots within the workable radius of a city.

You could also check the code used for the City State Greeting dialogs, extract follows...
Code:
	-- Nearby Resources
	
	local pCapital = pPlayer:GetCapitalCity();
	
	if (pCapital ~= nil) then
		
		local strResourceText = "";
		
		local iNumResourcesFound = 0;
		
		local thisX = pCapital:GetX();
		local thisY = pCapital:GetY();
		
		local iRange = 5;
		local iCloseRange = 2;
		
		for iDX = -iRange, iRange, 1 do
			for iDY = -iRange, iRange, 1 do
				local pTargetPlot = Map.GetPlotXY(thisX, thisY, iDX, iDY);
				
				if pTargetPlot ~= nil then
					
					local iOwner = pTargetPlot:GetOwner();
					
					if (iOwner == iPlayer or iOwner == -1) then
						local plotX = pTargetPlot:GetX();
						local plotY = pTargetPlot:GetY();
						local plotDistance = Map.PlotDistance(thisX, thisY, plotX, plotY);
						
						if (plotDistance <= iRange and (plotDistance <= iCloseRange or iOwner == iPlayer)) then
							
							local iResourceType = pTargetPlot:GetResourceType(Game.GetActiveTeam());
							
							if (iResourceType ~= -1) then
								
								if (Game.GetResourceUsageType(iResourceType) ~= ResourceUsageTypes.RESOURCEUSAGE_BONUS) then
									
									-- Add spacing if we already have found an entry
									if (iNumResourcesFound > 0) then
										strResourceText = strResourceText .. ", ";
									end
									
									local pResource = GameInfo.Resources[iResourceType];
									strResourceText = strResourceText .. pResource.IconString .. " [COLOR_POSITIVE_TEXT]" .. Locale.ConvertTextKey(pResource.Description) .. " (" .. pTargetPlot:GetNumResource() .. ") [ENDCOLOR]";
									
									iNumResourcesFound = iNumResourcesFound + 1;
									
								end
							end
						end
					end
					
				end
			end
		end
			
		Controls.ResourcesInfo:SetText(strResourceText);
		
		Controls.ResourcesLabel:SetHide(false);
		Controls.ResourcesInfo:SetHide(false);
		
		local strResourceTextTT = Locale.ConvertTextKey("TXT_KEY_CITY_STATE_RESOURCES_TT");
		Controls.ResourcesInfo:SetToolTipString(strResourceTextTT);
		Controls.ResourcesLabel:SetToolTipString(strResourceTextTT);
		
	else
		Controls.ResourcesLabel:SetHide(true);
		Controls.ResourcesInfo:SetHide(true);
	end
 
The game's definition, like "must be near" Building_LocalResourceOrs. I do recognize it's not determined solely by these factors:

  • Distance
  • If it's in cultural borders
I haven't been able to see a pattern of what else the game uses to determine which city a resource is near to. :think:
 
Replace "near" with "could be currently working" and it makes more sense. As in, it has to be in the workable area, has to not be worked by some other city, and then I'd guess it allocates to the closest city in case of no one working an overlapped tile.

As for how to check if a city has a resource nearby, I'd start with City:IsHasResourceLocal(id)
 
It's not "could be currently working"... for a tile equidistant from two cities, once city will always have access to the resource even if we change which city can work the tile. I'm not sure if this is determined by the plot ID, city ID, order cities were founded, XY coordinates, etc.

I don't see IsHasResourceLocal in the game's Lua files or the API, what are its parameters?
 
I had thought that for "must be near" the resource needed to be on a workable plot, so within 3 plots from the city. I'm also fairly sure that multiple cities can use the feature/resource for the purposes of building circus or observatory (for example), provided they are within workable range (ie. near), or "next to" depending on the buildings requirements.

So an adaptation of the code above should be able to scan for nearby resources. If you are interested I could write a function that took a city and resource id as parameters and returned true or false, or perhaps more efficient would be to populate a table with a list of resources and quantities.
 
I'm not sure if this is determined by the plot ID, city ID, order cities were founded, XY coordinates, etc.

My guess, then, is that it goes by nearest city, and in case of ties goes with the lowest ID (which means order they were founded, usually).

I don't see IsHasResourceLocal in the game's Lua files or the API, what are its parameters?

http://wiki.2kgames.com/civ5/index.php/Lua_Game_Objects/City#IsHasResourceLocal

One argument, the resource type. I'm not saying I trust that wiki, but it's on there so I'd at least try it.
 
I'm also fairly sure that multiple cities can use the feature/resource for the purposes of building circus or observatory (for example), provided they are within workable range (ie. near), or "next to" depending on the buildings requirements.

I tested that a while back, resources are fixed to a single city and can't be shifted to others. That's why I'm curious what else the game uses determine which city gets the resource.

Edit: Thanks Spatzimaus! That function worked. :goodjob:
 
Interesting that the function isn't used by the City State code, although it doesn't really matter in the context I suppose.

I think I'll still write a function to check for resources in the radius of a city, and then run IsHasResource on the ones found to ensure they are owned. That's just the kind of fun I like to have on Wednesday nights...
 
Back
Top Bottom