Terrain yield on tech

Eloque

Chieftain
Joined
Dec 13, 2010
Messages
18
This is a repost from the 2K forum, people told me this community is far more active, so I'll try it here.

I want to add a Fishing technology that you would need to get food from ocean tiles.

Adding the tech is easy enough, but I want to change the yield of a piece of terrain based on the tech. Kinda like chemistry does for mining. I've changed the base yield of oceans food to 0, it should become 2 once the Fishing tech is researched.

Code:
<Improvement_TechYieldChanges>
	<Row>
		<ImprovementType>IMPROVEMENT_MINE</ImprovementType>
		<TechType>TECH_CHEMISTRY</TechType>
		<YieldType>YIELD_PRODUCTION</YieldType>
		<Yield>1</Yield>
	</Row>
</Improvement_TechYieldChanges>

The above bit improves the yield of mines one when Chemistry is researched. Is there something similair for terrains? So that the below code would work?

Code:
	<Row>
		<TerrainType>TERRAIN_OCEAN</TerrainType>
		<TechType>TECH_FISHING</TechType>
		<YieldType>YIELD_FOOD</YieldType>
		<Yield>2</Yield>
	</Row>
 
No, that probably won't work. The Improvement_TechYieldChanges tag applies specifically to improvements, not to native tile yields. There is no such thing as a way to have tile yields change with a Technology (with XML moding). You might make a work-around, perhaps add a new building which becomes available once you research Fishing (like a Pier) and have that add one food to every water tile, similar to how Lighthouse works. Of course you'll have to build the building, so even if you set the production cost to 1, you'll have to spend a turn on it. You can make the building a free building from Ancient Era, but it will still only appear in cities founded after you research the appropriate technology, so that won't solve that issue.
 
There is a WaterWork column in the Technologies table that allows the player to work water tiles after researching that technology (a la Civ4). You also need to change the CAN_WORK_WATER_FROM_GAME_START Define to make it work, as in normal game it's assumed that no tech is needed for working water tiles. This method seems to work well, I use it in my mod.

I haven't tested the code below (in my mod it's done partially with SQL), but it should work:

Code:
	<Defines>
		<Update>
			<Set Value = "0"/>
			<Where Name = "CAN_WORK_WATER_FROM_GAME_START"/>
		</Update>
	</Defines>

	<Technologies>
		<Update>
			<Set WaterWork = "1"/>
			<Where Type = "TECH_FISHING"/>
		</Update>
	</Technologies>

Edit: I realized it's not really what you wanted to achieve, as it works for both Coast and Ocean tiles. For Ocean only, using a building as suggested by kaspergm seems the best solution.
 
Using the building worked. I now use this code;

Code:
	<Building_SeaPlotYieldChanges>
		<Row>
			<BuildingType>BUILDING_DOCKS</BuildingType>
			<YieldType>YIELD_FOOD</YieldType>
			<Yield>2</Yield>
		</Row>
	</Building_SeaPlotYieldChanges>

To have a Civilization be able to drasticly increase food income from water tiles.

I am going to try PawelS his solution as well, as that is more in line with what I wanted. I only included ocean tiles in the example, but I wanted both. Actually, I would love to able to differentiate between them, one improvement gives ocean tiles +2 food, the other gives coastal tiles +2 food. Would that be possible?
 
No, that probably won't work. The Improvement_TechYieldChanges tag applies specifically to improvements, not to native tile yields. There is no such thing as a way to have tile yields change with a Technology (with XML moding). You might make a work-around, perhaps add a new building which becomes available once you research Fishing (like a Pier) and have that add one food to every water tile, similar to how Lighthouse works. Of course you'll have to build the building, so even if you set the production cost to 1, you'll have to spend a turn on it. You can make the building a free building from Ancient Era, but it will still only appear in cities founded after you research the appropriate technology, so that won't solve that issue.

Couldnt you:

1) make the invisible dummy building

2) Hook into TeamTechResearched event, loop through all the cities, and add the building?
 
I haven't tested this because I don't have the appropriate building, but I *think* the logic is sound.

Code:
function OnTeamTechResearched(teamID, techID, change)

	if (iTech == GameInfoTypes.TECH_FISHING) then
		for iPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do 
			if (Players[iPlayer] ~= nil) then
				local player = Players[iPlayer]

				if (player:GetTeam() = teamID)
					for city in player:Cities() do
						city:SetNumRealBuildings([COLOR="Red"]***BUILDING ID FOR YOUR DUMMY BUILDING****[/COLOR], 1)
					end
				end
			end
		end
	end
end
GameEvents.TeamTechResearched.Add(OnTeamTechResearched)

Just remember you would need to change the part in red to something like GameInfoTypes.BUILDING_DOCKS or whatever you specifically named it
 
Okay, wow, thanks. That is way faster then I could've done it. I was still reading up on the how and where of the LUA file an sich.

So, I should just put this in a LUA file, add that to my mod and be done?
 
After you add it to your mod, you'll need to go tot he "Content" tab of the mod properties, and set the lua file to be an InGameUIAddin. (Its the tab right under where you set your XML file to be OnModActivated).

Edit: typo up there

if (player:GetTeam() = teamID)

should be: if (player:GetTeam() == teamID)
 
Anything else I need to do? The LUA file doesn't show up in the pulldown menu I have for adding content.
 
It's a known problem with ModBuddy - it lists only XML files instead of LUA files. You need to select the file first, and then set the type to "InGameUIAddin".
 
Sadly, I did not work yet, I'll will try again tomorrow, this is what I have so far;

Code:
function OnTeamTechResearched(teamID, techID, change)

	if (iTech == GameInfoTypes.TECH_FISHING) then
		for iPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do 
			if (Players[iPlayer] ~= nil) then
				local player = Players[iPlayer]

				if (player:GetTeam() == teamID))
					for city in player:Cities() do
						city:SetNumRealBuildings(GameInfoTypes.BUILDING_DOCKS, 1)
					end
				end
			end
		end
	end
end

GameEvents.TeamTechResearched.Add(OnTeamTechResearched)
 
Ah, my fault. I was copy-pasting things over and forgot to change a variable name, and the "then" after one of the if statements.

Anyways, this version should work.

Code:
function OnTeamTechResearched(teamID, techID, change)

	if (techID == GameInfoTypes.TECH_FISHING) then
		for iPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do 
			if (Players[iPlayer] ~= nil) then
				local player = Players[iPlayer]

				if (player:GetTeam() == teamID) then
					for city in player:Cities() do
						city:SetNumRealBuilding(GameInfoTypes.BUILDING_DOCKS, 1)
					end
				end
			end
		end
	end
end

GameEvents.TeamTechResearched.Add(OnTeamTechResearched)

I tested it by changing TECH_FISHING to TECH_POTTERY, and BUILDING_DOCKS to BUILDING_LIBRARY, and when I researched Pottery, it built the Library in my cities.

Let me know if you have any troubles.
 
Pretty awesome, I am going to try that. I am building a mod that requires a civlization to discover several techs before they can effectivly gather food.

This is to simulate the transition from hunter/gatherers to farmers. Thus it will make the amount of food available suddenly explode once those techs become available.

Edit: It does look deliciously like python, I can do Python me :)
 
So I was randomly thinking about this again, and I realized that that function would only give you the new building in cities that were already built when you finished researching Fishing. Any cities founded after you research it won't get the free dummy buildings, and any cities that you capture won't get it unless they already have it either. To fix this, you need to hook into events that trigger when you found a city or capture one (or a catch-all on player do turn, but that will give you 1 turn without having the building. Not a big deal in this case, but not good practice, IMO).

Anyways!

Code:
function OnCityFounded(playerID, cityX, cityY)

	local player = Players[playerID]
	local teamID = player:GetTeam()
	local team = Teams[teamID]
	local plot = Map:GetPlot(cityX, cityY)
	local city = plot:GetPlotCity()
	
	if (team:HasTech(GameInfoTypes.TECH_FISHING)) then
		city:SetNumRealBuilding(GameInfoTypes.BUILDING_DOCKS, 1)
	end
end
GameEvents.PlayerCityFounded.Add(OnCityFounded)

function OnCityCaptured(oldOwnerID, isCapital, cityX, cityY, newOwnerID, population, bConquest)

	local player = Players[newOwnerID]
	local plot = Map:GetPlot(cityX, cityY)
	local city = plot:GetPlotCity()
	local team = Teams[player:GetTeam()]
	
	if (team:HasTech(GameInfoTypes.TECH_FISHING)) then
		city:SetNumRealBuilding(GameInfoTypes.BUILDING_DOCKS, 1)
	end
end
GameEvents.CityCaptureComplete.Add(OnCityCaptured)
 
So I was randomly thinking about this again, and I realized that that function would only give you the new building in cities that were already built when you finished researching Fishing. Any cities founded after you research it won't get the free dummy buildings, and any cities that you capture won't get it unless they already have it either. To fix this, you need to hook into events that trigger when you found a city or capture one (or a catch-all on player do turn, but that will give you 1 turn without having the building. Not a big deal in this case, but not good practice, IMO).
You can solve that problem in a different way also through simple XML coding. If you add the tag <FreeStartEra>ERA_ANCIENT</FreeStartEra> to the XML section of where you define the building, all cities founded after you research the proper tech will get the building for free. The lua code should take care of the rest.
 
I found this thread while trying to solve a similar problem, but I think what I'm trying to do requires something a bit fancier.

I want to change the yields of basic terrains based on what techs you have researched, but as far as I can see this only works for improvements, features, resources, lakes, ocean/coast tiles and river tiles, because those are the only types of yields that buildings can change.

Is this correct, or is there some way to get around this using the method described above? If not, how tricky does it get?

A simple, non-representative example to describe more cleary what I'm after: Once you've researched the "Hunting" technology, grasslands give +1 food.
 
Back
Top Bottom