getWorkingCity() returns what city?

Baldyr

"Hit It"
Joined
Dec 5, 2009
Messages
5,530
Location
Sweden
So I'm trying to figure out how I can find the nearest city to any owned plot belonging to the plot owner. So basically the city that "owns" the plot.

I found the CyPlot.getWorkingCity() method in the API but looking at the SDK function really only revealed that it is returning the value m_workingCity, which isn't very helpful to me.

My best guess is that the method will return a CyCity instance if and only if the plot is being actively worked on by a city. But what about CyPlot.getWorkingCityOverride() then? What is that method returning? :confused: (I guess I'm wondering what m_workingCityOverride is referencing.)
 
Tracking m_workingCityOverride in CvPlot led to these functions of interest:

Spoiler :
Code:
void CvPlot::setWorkingCityOverride( const CvCity* pNewValue)
{
	if (getWorkingCityOverride() != pNewValue)
	{
		if (pNewValue != NULL)
		{
			FAssertMsg(pNewValue->getOwnerINLINE() == getOwnerINLINE(), "Argument city pNewValue's owner is expected to be the same as the current instance");
			m_workingCityOverride = pNewValue->getIDInfo();
		}
		else
		{
			m_workingCityOverride.reset();
		}

		updateWorkingCity();
	}
}
Code:
void CvPlot::updateWorkingCity()
{
	CvCity* pOldWorkingCity;
	CvCity* pLoopCity;
	CvCity* pBestCity;
	CvPlot* pLoopPlot;
	int iBestPlot;
	int iI;

	pBestCity = getPlotCity();

	if (pBestCity == NULL)
	{
		pBestCity = getWorkingCityOverride();
		FAssertMsg((pBestCity == NULL) || (pBestCity->getOwnerINLINE() == getOwnerINLINE()), "pBest city is expected to either be NULL or the current plot instance's");
	}

	if ((pBestCity == NULL) && isOwned())
	{
		iBestPlot = 0;

		for (iI = 0; iI < NUM_CITY_PLOTS; ++iI)
		{
			pLoopPlot = plotCity(getX_INLINE(), getY_INLINE(), iI);

			if (pLoopPlot != NULL)
			{
				pLoopCity = pLoopPlot->getPlotCity();

				if (pLoopCity != NULL)
				{
					if (pLoopCity->getOwnerINLINE() == getOwnerINLINE())
					{
						// XXX use getGameTurnAcquired() instead???
						if ((pBestCity == NULL) ||
							  (GC.getCityPlotPriority()[iI] < GC.getCityPlotPriority()[iBestPlot]) ||
							  ((GC.getCityPlotPriority()[iI] == GC.getCityPlotPriority()[iBestPlot]) &&
							   ((pLoopCity->getGameTurnFounded() < pBestCity->getGameTurnFounded()) ||
							    ((pLoopCity->getGameTurnFounded() == pBestCity->getGameTurnFounded()) &&
							     (pLoopCity->getID() < pBestCity->getID())))))
						{
							iBestPlot = iI;
							pBestCity = pLoopCity;
						}
					}
				}
			}
		}
	}

	pOldWorkingCity = getWorkingCity();

	if (pOldWorkingCity != pBestCity)
	{
		if (pOldWorkingCity != NULL)
		{
			pOldWorkingCity->setWorkingPlot(this, false);
		}

		if (pBestCity != NULL)
		{
			FAssertMsg(isOwned(), "isOwned is expected to be true");
			FAssertMsg(!isBeingWorked(), "isBeingWorked did not return false as expected");
			m_workingCity = pBestCity->getIDInfo();
		}
		else
		{
			m_workingCity.reset();
		}

		if (pOldWorkingCity != NULL)
		{
			pOldWorkingCity->AI_setAssignWorkDirty(true);
		}
		if (getWorkingCity() != NULL)
		{
			getWorkingCity()->AI_setAssignWorkDirty(true);
		}

		updateYield();

		updateFog();
		updateShowCitySymbols();

		if (getOwnerINLINE() == GC.getGameINLINE().getActivePlayer())
		{
			if (gDLL->getGraphicOption(GRAPHICOPTION_CITY_RADIUS))
			{
				if (gDLL->getInterfaceIFace()->canSelectionListFound())
				{
					gDLL->getInterfaceIFace()->setDirty(ColoredPlots_DIRTY_BIT, true);
				}
			}
		}
	}
}
 
So what does it all mean? Anyone? (I'm terrible at reading the SDK.)
 
I didn't scour the code too completely, but at a cursory glance it looks like CvPlot::getWorkingCity() returns a CvCity object pointer for the city working a plot, and CvPlot::getWorkingCityOverride sets the plot to being worked by a new city.
 
So the override both changes what city is working the plot and returns the new "owner"?

Does anyone have a handle on how one would go about detecting what city's culture a plot is "part of"? I of course realize that there would be plots that are within the cultural reach of several cities, but then it would just be a matter of calculating which one is nearest/has most culture - or a combination thereof.

Or is the problem solveable by simply looking up the nearest city to the plot?
Spoiler :
Code:
def getNearestCity(pPlot):
	tCoords = pPlot.getX(), pPlot.getY()
	ePlayer = pPlot.getOwner()
	pNearestCity = gc.getPlayer(ePlayer).getCapitalCity()
	iStortestDistance = calcutaletDistance(tCoords, pNearestCity)
	for pCity in (city.GetCy() for city in PyHelpers.PyPlayer(ePlayer).getCityList()):
		if pCity == pNearestCity: continue
		iDistance = calcutaletDistance(tCoords, pCity)
		if iDistance < iShortestDistance:
			iShortestDistance = iDistance
			pNearestCity = pCity
		if iDistance < 3: break
	return pCity
	
def calcutaletDistance(tCoords, pInstance):
	iX, iY = tCoords
	iXDistance = abs(iX - pInstance.getX())
	iYDistance = abs(iY - pInstance.getY())
	return min(iXDistance, iYDistance)
I'm not crazy about looping through stuff in this manner... :rolleyes:
 
Sorry, the function CvPlot::setWorkingCityOverride sets the new working city. Apparently m_workingCityOverride stores an IDInfo, somehow that IDInfo (whatever it is) is used to return a CvCity Object pointer.
 
I guess I could do some practical testing with the Python console to figure this out. Oh, I just realized I forgot to search the boards, so I'll start with that. :blush:
 
Well, alot of times when I'm not sure what something is doing, I'll look to see where it is used. In the SDK it is used twice. It's used in CvCity::Kill, and if it returns the same city that's being killed, setWorkingCityOverride sets to NULL; it is also used in CvCityAI::StealPlots, pretty much the same way. Not sure if that helps in any way.
 
When I searched the SDK for "workingCity" I got tons of matches... It seemed to be something central to how some things are done in the game, but what it was is not clear to me... :p
 
workingCityOverride is an internal value used for the following case:

Let's say you have two cities A and B (of the same owner) which can work the same plot P.

If A is working P, and you go into the city screen of B, and select to work P there, then it overrides A's working plot and then P is worked by B.

This 'override' value marks the transfer of this plot between two cities of the same owner.


To find the nearest city to a plot you can use CyMap.findCity which is exposed to python (although I don't think it takes into account cultural influence).
 
All good answers. :king:

CyMap.findCity() looks like this:
CyCity findCity (INT iX, INT iY, PlayerType eOwner, TeamType eTeam, BOOL bSameArea, BOOL bCoastalOnly, TeamType eTeamAtWarWith, DirectionType eDirection, CyCity pSkipCity)
So its pretty comprehensive, not? I wonder if the eDirection parameter can be set as DirectionTypes.NO_DIRECTION...? And hopefully eTeamAtWarWith can be set to TeamTypes.NO_TEAM...
 
workingCityOverride is an internal value used for the following case:

Let's say you have two cities A and B (of the same owner) which can work the same plot P.

If A is working P, and you go into the city screen of B, and select to work P there, then it overrides A's working plot and then P is worked by B.

This 'override' value marks the transfer of this plot between two cities of the same owner.


To find the nearest city to a plot you can use CyMap.findCity which is exposed to python (although I don't think it takes into account cultural influence).

From looking at the code, this is exactly what I figured it did. But I don't understand how the get function can return a single CvCity object pointer... What happens if more then 3 cities can work a tile? Or does the getOverride return the same CvCity pointer as the general get call that calls the city that is working the tile? If so, what's the point in storing the same CvCity object pointer twice?
 
This override is set in exactly 2 cases:
- When the user clicks a plot in the city screen which causes the scenario I described
- When the AI decides to 'steal' a plot from one of its cities to another

In both of these cases the override working city is the 'stealing' city, even if there are more cities which can work this plot.

I'm not completely sure why they do it this way. There are things I don't understand about it (What's handleCityScreenPlotRightPicked? Is that a right click in the city screen? because apparently it clears this override).

My guess is that the override remains even if the city is not currently working the tile.

Imagine this scenario (I can't test it since I'm not on my gaming PC):
You have cities A & B (both belong to the same owner) and plot P which can be worked by both.
Currently A is working plot P, so when you look at B's city screen, P is darkened.
Now in B's city screen you use this override and start working P.

Let's say B stops working P (for another tile, or a specialists).

I'm guessing that the plot still belongs to B - it is the overriding working city of P, even though no city is actually working P.
You will still see P darkened in A's city screen.

Again, I'm guessing this, so we still need to verify I'm not just rumbling.
 
This sound all very familiar to me as to how the game actually plays...
 
So I'm trying to figure out how I can find the nearest city to any owned plot belonging to the plot owner. So basically the city that "owns" the plot.

I found the CyPlot.getWorkingCity() method in the API but looking at the SDK function really only revealed that it is returning the value m_workingCity, which isn't very helpful to me.

My best guess is that the method will return a CyCity instance if and only if the plot is being actively worked on by a city.

no, it returns the city that is allowed to work the plot (which is always only one or none). CvPlot has a method isBeingWorked() so you can check if the plot is actually used in case you need this.
 
no, it returns the city that is allowed to work the plot (which is always only one or none). CvPlot has a method isBeingWorked() so you can check if the plot is actually used in case you need this.

If that's the case then I have no idea why getWorkingCityOverride() is needed.
 
getWorkingCityOverride() is used do determine what value getWorkingCity returns (via updateWorkingCity()). But unless you want to change the actual mechanics you don't have to worry about that and just use getWorkingCity().
 
Top Bottom