Problem getting persistent property to work

Craig_Sutter

Deity
Joined
Aug 13, 2002
Messages
2,773
Location
Calgary, Canada
Having a little trouble with this code... it seems to work inconsistently. What is to happen is that all cities of a civilization will convert to a religion (Catholic) if a majority of its cities have converted to Catholicism. If there is one city, then there is no conversion via lua as the city has already converted and it is thus unnecessary. Two cities, if one converts then the conversion will execute. Three or more, I use the function pPlayer:HasReligionInMostCities(eReligion).

I am trying to create a persistent property so that each conversion only happens once. Previously, I had done this using a building -- in another function, Catholic cities were given a certain building and if this function detected the building, it would not run. This worked, but not perfectly, so I did some tinkering to add the modDate entries.

First, I experimented with Bruges. It is a one city minor civ. It worked and the expected result... a one time only conversion of the city occurred. The print statement came out.

Then I did the Franks. They have many cities (>2). Previously, when I used the presence of a building to determine if the function ran, my print statements all came out.

However, since I added the modData stuff, the function has stopped working. I cannot for the life of me, figure out why since it works adequately for Bruges.

The other civs are working normally and do convert. However, since I removed the building requirement, they repeat multiple times. The persistent property is not applied to them as yet since I wish to get the Franks working first.

I cannot figure out what is wrong...

Here is the code with color to indicate some of the relevant bits.

Code:
-- Converts certain minor civilization to Catholicism if a proportion of their cities convert to Catholicism

[COLOR="Red"]local modData = Modding.OpenSaveData()
local modConvertBrugesKey = "ConvertBruges"
local haveConvertBruges = (modData.GetValue(modConvertBrugesKey) == 1)
local modConvertFranksKey = "ConvertFranks"
local haveConvertFranks = (modData.GetValue(modConvertFranksKey) == 1)[/COLOR]

function MinorConvert(iPlayer, eReligion, iX, iY)

local plot = Map.GetPlot(iX, iY);
local pCity = plot:GetPlotCity();
local iPlayer = plot:GetOwner()
local pPlayer = Players[iPlayer]
local civType = pPlayer:GetMinorCivType()

--check if player alive, Catholic and city has majority Catholic

	if eReligion == GameInfoTypes["RELIGION_CHRISTIANITY"] and pCity:GetReligiousMajority() == GameInfoTypes["RELIGION_CHRISTIANITY"] and pPlayer:IsAlive () then

		if	civType == GameInfo.MinorCivilizations["MINOR_CIV_SUSSEX"].ID or
			civType == GameInfo.MinorCivilizations["MINOR_CIV_ESSEX"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_KENT"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_EAST_ANGLIA"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_LONDON"].ID or
			 [COLOR="Red"]civType == GameInfo.MinorCivilizations["MINOR_CIV_FRANKS"].ID[/COLOR] or
			[COLOR="Red"] civType == GameInfo.MinorCivilizations["MINOR_CIV_BRUGES"].ID[/COLOR] or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_BRITTANY"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_UTRECHT"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_DEVENTER"].ID then
		
			-- Sussex is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_SUSSEX"].ID then
			
			pPlayer = Players[iPlayer];

			CitiesConvert(pPlayer, eReligion)

			end

			-- Essex is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_ESSEX"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- Kent is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_KENT"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- East Anglia is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_EAST_ANGLIA"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- London is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_LONDON"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			[COLOR="Blue"]-- The Franks are set

			if (haveConvertFranks == false) then

				if	civType == GameInfo.MinorCivilizations["MINOR_CIV_FRANKS"].ID then
			
				pPlayer = Players[iPlayer]

				CitiesConvert(pPlayer, eReligion)

				haveConvertFranks = true
				modData.SetValue(modConvertFranksKey, 1)

				end

			end

			-- Bruges is set

			if (haveConvertBruges == false) then

				if	civType == GameInfo.MinorCivilizations["MINOR_CIV_BRUGES"].ID then
				
				pPlayer = Players[iPlayer]

				CitiesConvert(pPlayer, eReligion)
				
				haveConvertBruges = true
				modData.SetValue(modConvertBrugesKey, 1)
			
				end

			end[/COLOR]

			-- Brittany is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_BRITTANY"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- Utrecht is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_UTRECHT"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- Deventer is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_DEVENTER"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end
		end
	end
end	
	

GameEvents.CityConvertsReligion.Add (MinorConvert);


function CitiesConvert(pPlayer, eReligion)

	--if only one city stop

	if pPlayer:GetNumCities() == 1 then
	pPlayer:ChangeFaith(75);
	print(pPlayer:GetName(), "...is adding faith...");

	--if 2 cities	

	elseif pPlayer:GetNumCities() == 2 then

		for pCity in pPlayer:Cities() do

		Building = pCity:GetNumRealBuilding(GameInfoTypes["BUILDING_CATHOLIC_MISSION"])

			if pCity ~= nil and Building == 0 then

			pCity:ConvertPercentFollowers(2, -1, 75);
			pCity:ConvertPercentFollowers(2, 1, 75);
			pCity:ConvertPercentFollowers(2, 3, 50);
			pCity:ConvertPercentFollowers(2, 4, 50);
			print(pCity:GetName(), "...is getting Catholic followers...");
			pPlayer:ChangeFaith(75);
			print(pPlayer:GetName(), "...is adding faith...");

			end
			
		end
								
	--if majority of cities is Catholic	

	elseif (pPlayer:HasReligionInMostCities(eReligion)) then

		for pCity in pPlayer:Cities() do

		--Building = pCity:GetNumRealBuilding(GameInfoTypes["BUILDING_CATHOLIC_MISSION"])

			[COLOR="SeaGreen"]--if pCity ~= nil and Building == 0 then[/COLOR]
			if pCity ~= nil then

			pCity:ConvertPercentFollowers(2, -1, 75);
			pCity:ConvertPercentFollowers(2, 1, 75);
			pCity:ConvertPercentFollowers(2, 3, 50);
			pCity:ConvertPercentFollowers(2, 4, 50);
			print(pCity:GetName(), "...is getting Catholic followers...");
			pPlayer:ChangeFaith(25);
			print(pPlayer:GetName(), "...is adding faith...");

			end	
		end
	end
end

Here is the code with color removed if anyone wishes to put it through Firetuner.

Code:
-- Converts certain minor civilization to Catholicism if a proportion of their cities convert to Catholicism

local modData = Modding.OpenSaveData()
local modConvertBrugesKey = "ConvertBruges"
local haveConvertBruges = (modData.GetValue(modConvertBrugesKey) == 1)
local modConvertFranksKey = "ConvertFranks"
local haveConvertFranks = (modData.GetValue(modConvertFranksKey) == 1)

function MinorConvert(iPlayer, eReligion, iX, iY)

local plot = Map.GetPlot(iX, iY);
local pCity = plot:GetPlotCity();
local iPlayer = plot:GetOwner()
local pPlayer = Players[iPlayer]
local civType = pPlayer:GetMinorCivType()

--check if player alive, Catholic and city has majority Catholic

	if eReligion == GameInfoTypes["RELIGION_CHRISTIANITY"] and pCity:GetReligiousMajority() == GameInfoTypes["RELIGION_CHRISTIANITY"] and pPlayer:IsAlive () then

		if	civType == GameInfo.MinorCivilizations["MINOR_CIV_SUSSEX"].ID or
			civType == GameInfo.MinorCivilizations["MINOR_CIV_ESSEX"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_KENT"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_EAST_ANGLIA"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_LONDON"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_FRANKS"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_BRUGES"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_BRITTANY"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_UTRECHT"].ID or
			 civType == GameInfo.MinorCivilizations["MINOR_CIV_DEVENTER"].ID then
		
			-- Sussex is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_SUSSEX"].ID then
			
			pPlayer = Players[iPlayer];

			CitiesConvert(pPlayer, eReligion)

			end

			-- Essex is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_ESSEX"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- Kent is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_KENT"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- East Anglia is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_EAST_ANGLIA"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- London is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_LONDON"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- The Franks are set

			if (haveConvertFranks == false) then

				if	civType == GameInfo.MinorCivilizations["MINOR_CIV_FRANKS"].ID then
			
				pPlayer = Players[iPlayer]

				CitiesConvert(pPlayer, eReligion)

				haveConvertFranks = true
				modData.SetValue(modConvertFranksKey, 1)

				end

			end

			-- Bruges is set

			if (haveConvertBruges == false) then

				if	civType == GameInfo.MinorCivilizations["MINOR_CIV_BRUGES"].ID then
				
				pPlayer = Players[iPlayer]

				CitiesConvert(pPlayer, eReligion)
				
				haveConvertBruges = true
				modData.SetValue(modConvertBrugesKey, 1)
			
				end

			end

			-- Brittany is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_BRITTANY"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- Utrecht is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_UTRECHT"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end

			-- Deventer is set

			if	civType == GameInfo.MinorCivilizations["MINOR_CIV_DEVENTER"].ID then
			
			pPlayer = Players[iPlayer]

			CitiesConvert(pPlayer, eReligion)

			end
		end
	end
end	
	

GameEvents.CityConvertsReligion.Add (MinorConvert);


function CitiesConvert(pPlayer, eReligion)

	--if only one city stop

	if pPlayer:GetNumCities() == 1 then
	pPlayer:ChangeFaith(75);
	print(pPlayer:GetName(), "...is adding faith...");

	--if 2 cities	

	elseif pPlayer:GetNumCities() == 2 then

		for pCity in pPlayer:Cities() do

		Building = pCity:GetNumRealBuilding(GameInfoTypes["BUILDING_CATHOLIC_MISSION"])

			if pCity ~= nil and Building == 0 then

			pCity:ConvertPercentFollowers(2, -1, 75);
			pCity:ConvertPercentFollowers(2, 1, 75);
			pCity:ConvertPercentFollowers(2, 3, 50);
			pCity:ConvertPercentFollowers(2, 4, 50);
			print(pCity:GetName(), "...is getting Catholic followers...");
			pPlayer:ChangeFaith(75);
			print(pPlayer:GetName(), "...is adding faith...");

			end
			
		end
								
	--if majority of cities is Catholic	

	elseif (pPlayer:HasReligionInMostCities(eReligion)) then

		for pCity in pPlayer:Cities() do

		--Building = pCity:GetNumRealBuilding(GameInfoTypes["BUILDING_CATHOLIC_MISSION"])

			--if pCity ~= nil and Building == 0 then
			if pCity ~= nil then

			pCity:ConvertPercentFollowers(2, -1, 75);
			pCity:ConvertPercentFollowers(2, 1, 75);
			pCity:ConvertPercentFollowers(2, 3, 50);
			pCity:ConvertPercentFollowers(2, 4, 50);
			print(pCity:GetName(), "...is getting Catholic followers...");
			pPlayer:ChangeFaith(25);
			print(pPlayer:GetName(), "...is adding faith...");

			end	
		end
	end
end

I'm hoping my error will be obvious to experienced coders as it is not to me. I just don't understand why Bruges works while the Franks do not. Thanks for any assistance.
 
in non-code, just to clarify:

- run code when a city converts via event.
- check if the city has majority Catholic and is a minor
- loop through the players to find city owner
- if modData=false
- run conversion function for that player
- if one city, give faith.
- if two cities, loop cities ,check for building and convert and give faith for each
- if majority of cities are catholic loop cities ,check for building and convert and give faith for each
- set modData=true and store result

The red is the persistent property, which apparently works for 1 city, but not for the majority city minor civ. I have not done the two city loop but presumably if I fix the problem with the Franks, it will work too.

The green is my previous solution, which worked but was cumbersome.
 
I have decided to use the building to limit the times the function will fire rather than a persistent property. The latter requires me to deal with each civ individually while I can install buildings and determine their existence by looping through all civs... a simpler task and one that currently works. Sorry for bothering anyone though I am still curious about the error.
 
You don't want to use OpenSaveData, that is for persisting across save games. You want MapModData.

Code:
MapModData.g_bDebug	= MapModData.g_haveConvertBruges or false
local g_haveConvertBruges = MapModData.g_haveConvertBruges

MapModData is only useful for sharing data between Lua contexts. All this code is in one context. However, it would be necessary to persist the data across saves, so OpenSaveData() is correct.

However, why it's not working I haven't looked into as the code needs seriously refactoring.
 
Back
Top Bottom