Simple turn loop

Joined
Mar 6, 2003
Messages
775
The following code increases the culture output of the wheat resource each turn that its worked in a city.

It uses GameEvents.PlayerDoTurn in order to fire every time a player's turn is completed. It then loops through that player's cities, and then through the tiles indexed relative to that city, using City:GetCityIndexPlot.

All of the tiles of the map are indexed relative to the city, with the closest tiles having the lowest numbers. In order to stop the loop you have to test it against the number of city plots, which you can get by City:GetNumCityPlots. In this case, I'm also testing the number of worked tiles I found versus the number of workers available in the city. (I haven't checked if I have to figure in unemployed workers to that calculation). It tests each plot to see if its being worked using City:IsWorkingPlot and then checks if there's a wheat resource there.

Code:
[COLOR="Blue"]function[/COLOR] onPlayerDoTurn(playerID)
	[COLOR="Blue"]local[/COLOR] player = Players[playerID]
	[COLOR="blue"]for[/COLOR] city [COLOR="blue"][COLOR="blue"]in[/COLOR][/COLOR] player:Cities() [COLOR="blue"]do[/COLOR]
		[COLOR="blue"]local[/COLOR] plotsWorkable = city:GetNumCityPlots()
		[COLOR="blue"]local[/COLOR] workers = city:GetPopulation() - city:GetSpecialistCount() + 1
		[COLOR="blue"]local[/COLOR] plotsCounted = 0
		[COLOR="blue"]local[/COLOR] plotsWorked = 0
		[COLOR="blue"]while[/COLOR] plotsCounted < plotsWorkable [COLOR="blue"]and[/COLOR] plotsWorked < workers [COLOR="blue"]do[/COLOR]
			[COLOR="blue"]local[/COLOR] plot = city:GetCityIndexPlot(plotsCounted)
			[COLOR="blue"]if[/COLOR] city:IsWorkingPlot(plot) and plot:GetCulture() < 6 [COLOR="blue"]then[/COLOR]
				[COLOR="blue"]local[/COLOR] resourceID = plot:GetResourceType()
				[COLOR="blue"]local[/COLOR] resourceType = resourceID > -1 [COLOR="blue"]and[/COLOR] GameInfo.Resources{ID = resourceID}().Type [COLOR="Blue"]or[/COLOR] [COLOR="DarkRed"]"NULL"[/COLOR]
				[COLOR="blue"]if[/COLOR] resourceType == [COLOR="DarkRed"]"RESOURCE_WHEAT"[/COLOR] [COLOR="blue"]then[/COLOR]
					plot:ChangeCulture(1)
				[COLOR="blue"]end[/COLOR]
				plotsWorked = plotsWorked + 1
			[COLOR="blue"]end[/COLOR]
			plotsCounted = plotsCounted + 1
[COLOR="blue"]		end
	end
end[/COLOR]

GameEvents.PlayerDoTurn.Add(onPlayerDoTurn)

There's one issue: Although the culture yield displays on the WorldView update each turn, they don't update regularly on the CityView. They seem to update every time a city has a new worker, so at the time the city's population grows. I've tried playing around with UI.UpdateCityScreen with no success so far.

If someone can help me get the updating to function correctly, I'll be grateful. I'm going to be working something using culture yields into a mod.

Also note that there's an event listed on the Wiki Events.SerialEventHexCultureChanged , where the description says that it's triggered whenever a hex switches owners. However, though I haven't tested it out I believe that's wrong; I think its triggered when some the Culture output of a hex is changed.
 
What I've found out so far on the YieldIconManager state..

ShowYield(x, y, show)
Shows or hides the yields at a particular grid coordinate when in CityView. When the third variable is true it shows, when its false it hides.

BuildYield(x, y, int, ...
Draws the yields on the main map. I'm not sure what the third variable corresponds to, but it displays the yield slightly differently depending on what the number is. The difference seems to be based on some recorded value, since, for instance, if you have a yield increasing turn after turn, it doesn't go over the current yield value, but it shows yields below that.

DestroyYield(x, y, ...
I can't get this to do anything

yieldinfo = RecordYieldInfo(int, int, int, plot)
Returns a table with the food, gold, production, science, and culture for that plot. I'm not sure if the three first arguments have any affect.
 
OK I guess I should have just investigated the .lua file

function ShowHexYield( x, y, bShow )
function BuildYield( x, y, index )
function DestroyYield( index )

using local index = IndexFromGrid( x, y );

OnYieldChangeEvent hooks to Events.HexYieldsMightHaveChanged
 
OnPlayerDoTurn only gets called when the turn is processed. Your best bet is to do OnPlayerBeginTurn so it gets displayed properly, and then put an additional check if the city changes working plots.

Though, I thought it was possible to change the plot's yield permanently. At least, plot:ChangeCulture() seems to suggest as much. IF this is the case you should only need to perform this once, either in the XML or when the pre-requisite event happens (like making a building) or when the plot is lost/acquired.
 
OnPlayerDoTurn only gets called when the turn is processed. Your best bet is to do OnPlayerBeginTurn so it gets displayed properly, and then put an additional check if the city changes working plots.
Is there an OnPlayerBeginTurn GameEvent?
 
Is there an OnPlayerBeginTurn GameEvent?

Not as a GameEvent, but as an "Events". Use: Events.ActivePlayerTurnStart.Add( yourfunction )

Note, you'll have to iterate over all players because this doesn't get called on the AI players' turns.
 
Not as a GameEvent, but as an "Events". Use: Events.ActivePlayerTurnStart.Add( yourfunction )

Note, you'll have to iterate over all players because this doesn't get called on the AI players' turns.
Ah, and this is why the original set of Events isn't great for game rules - it's all UI-oriented. I thought there might be something else as you put it in CamelCase but not with the name of the Event that we're all familiar with.
 
Back
Top Bottom