Trying to make code more efficient (and failing)

Craig_Sutter

Deity
Joined
Aug 13, 2002
Messages
2,753
Location
Calgary, Canada
I have a bit of code in my scenario that forces a minor civ to DoW on another minor civilization after a certain year. The first bit of code works as intended, but strikes me as inefficient... it is set to go off at PlayerDoTurn(iPlayer). However, the "victim" civilization in the first code is being determined by a loop of the minor civilizations and selected within that loop. It works, but it strikes me that the loop is not needed as the "victim" civ is already known... hence the second code...

Code:
--At the end of year 550 , East Anglia declares war on London.  We want TeamIDs and Teams, not PlayerIDs.
--Then set permanent war, both ways.

local modData = Modding.OpenSaveData()
local modEastAngliaLondonKey = "EastAngliaLondon"
local haveEastAngliaLondon = (modData.GetValue(modEastAngliaLondonKey) == 1)

function  EastAngliaLondonWar()

if (haveEastAngliaLondon == false) then

	if (Game.GetGameTurnYear() >= 550) then

	haveEastAngliaLondon = true
	modData.SetValue(modEastAngliaLondonKey, 1)

	local EastAngliaTeam
	local EastAngliaTeamID
	local LondonTeam
	local LondonTeamID
	local EastAnglia
	local London

	-- Set up East Anglia Player

		for IDPlayer=GameDefines.MAX_MAJOR_CIVS, GameDefines.MAX_CIV_PLAYERS-1, 1 do 

		local pEastAnglia = Players[IDPlayer]

			if (GameInfo.MinorCivilizations.MINOR_CIV_EAST_ANGLIA.ID == pEastAnglia:GetMinorCivType()) then
	
			EastAnglia = pEastAnglia
			EastAngliaTeamID = EastAnglia:GetTeam();
			EastAngliaTeam= Teams[ EastAnglia:GetTeam() ]

			end	
		end

	-- Set up London Player

		for IDPlayer=GameDefines.MAX_MAJOR_CIVS, GameDefines.MAX_CIV_PLAYERS-1, 1 do 

		local pLondon = Players[IDPlayer]

			if (GameInfo.MinorCivilizations.MINOR_CIV_LONDON.ID == pLondon:GetMinorCivType()) then
	
			London = pLondon	
			LondonTeamID = London:GetTeam();
			LondonTeam= Teams[ London:GetTeam() ]

			end
		end

	-- Declare war and set Permanent War

		if(London:IsAlive() and EastAnglia:IsAlive() and not EastAngliaTeam:IsAtWar(LondonTeamID)) then

		EastAngliaTeam:DeclareWar( LondonTeamID, true );
		EastAngliaTeam:SetPermanentWarPeace(LondonTeamID, true);
		LondonTeam:SetPermanentWarPeace(EastAngliaTeamID, true);

		end
	
	-- Test for war

		if (EastAngliaTeam:IsAtWar(LondonTeamID)) then

		print (EastAnglia:GetName() ,"...is at war with... ", London:GetName());

		end
	end
	end
end


In this second function, I remove the loop and define the target iLondon player. However, it does not seem to work... I get a nil value for pLondon in my logs.

Question... do I have to do a player loop as in the first code above to find iLondon, or as below, can I define iLondon based on the fact that I alread know who it is?

Or have I made a basic error.

Code:
local modData = Modding.OpenSaveData()
local modEastAngliaLondonKey = "EastAngliaLondon"
local haveEastAngliaLondon = (modData.GetValue(modEastAngliaLondonKey) == 1)

function  EastAngliaLondonWar(iPlayer)

	if (haveEastAngliaLondon == false) then

		if (Game.GetGameTurnYear() >= 504) then
		
			local iLondon = GameInfo.MinorCivilizations.MINOR_CIV_LONDON.ID		
			local pLondon = Players[iLondon]
			local LondonTeamID = pLondon:GetTeam()
			local LondonTeam= Teams[ pLondon:GetTeam() ]
			local pEastAnglia = Players[iPlayer]

			if (GameInfo.MinorCivilizations.MINOR_CIV_EAST_ANGLIA.ID == pEastAnglia:GetMinorCivType()) then
	
			local EastAngliaTeamID = pEastAnglia:GetTeam()
			local EastAngliaTeam= Teams[ pEastAnglia:GetTeam() ]

				-- Declare war and set Permanent War

				if(pLondon:IsAlive() and pEastAnglia:IsAlive() and not EastAngliaTeam:IsAtWar(LondonTeamID)) then

				EastAngliaTeam:DeclareWar( LondonTeamID, true )
				EastAngliaTeam:SetPermanentWarPeace(LondonTeamID, true)
				LondonTeam:SetPermanentWarPeace(EastAngliaTeamID, true)
				haveEastAngliaLondon = true
				modData.SetValue(modEastAngliaLondonKey, 1)
				print (pEastAnglia:GetName() ,"...is at war with... ", pLondon:GetName())

				end
			end		
		end
	end
end

By the way, both sets of code store info after war is declared such that the functions will only fire one time after the year (504) in question. I realize that this storage should probably be repositioned in the first bit of code.

Thank-you.
 
Sorry... I copy-pasted identical codes for the first and second functions... I have corrected that above.

Also note that I do a loop of both players in the first code... I am certain that the loop is unnecessary in the attackers instance (EastAnglia) if I use PlayerDoTurn(iPlayer). It is just in that matter of the loop for the victim that I am confused.
 
With a little bit of rearrangement

In code #1
Code:
pLondon:GetMinorCivType() == GameInfo.MinorCivilizations.MINOR_CIV_LONDON.ID

In code #2
Code:
pLondon = Players[GameInfo.MinorCivilizations.MINOR_CIV_LONDON.ID]

which should help explain why you're getting a nil in code #2 for pLondon

To dereference the Players[] array, you need the player ID (where player 0 is the human in as SP game), NOT the (minor) civilization ID

You will still need to loop all players to find London, but you need to do it only once (and not every turn), as once the game starts it will be the same for the duration of the game
 
Top Bottom