Checking and looking for advice on some code

Craig_Sutter

Deity
Joined
Aug 13, 2002
Messages
2,753
Location
Calgary, Canada
This code is meant to add buildings to a Player's Capital when it is Allies or Friends to a particular city state (The Jomsvikings) and they have TECH_THEOCRACY.

The building(s) are going to be adding particular strategic resources to the capital by way of dummy buildings. I am looking at 7 strategic resources for Allied and 2 for Friends... so the buildings will provide 5/2 resources respectively.

Below is a rough setup for said code... it does not include the code for determining the Capital and installing the buildings, but that is something I am familiar with.

My question is whether the below code is the most efficient. I can't help feeling that there is a better way to do this code... perhaps multiple copies of the same building rather than 2 separate buildings might be better. And I feel that looping through iPlayer every turn when the situation probably remains relatively static from turn to turn seems inefficient.

As well, are there any significant errors in the code below and is the set up as efficient as it could be?

Thank-you for your advice.

Code:
--After gaining Theocracy, when Player is Allied with Jomsvikings add 2 buildings to its capital.  If Friends with Jomsvikings add only 1 building.
--We want TeamIDs and Teams, not PlayerIDs.

function  eCivJomsviking(iPlayer)

	local pPlayer
	local pJomsviking
	local iJomsviking
	local eCivTeamID		
	local eCivTeam

	-- Set up Player
	local pPlayer = Players[iPlayer]				
			
	local eCivTeamID = pPlayer:GetTeam();
	local eCivTeam= Teams[ pPlayer:GetTeam() ]					
	if (eCivTeam:GetTeamTechs():HasTech( GameInfoTypes["TECH_THEOLOGY"] )) then		

		-- Set up Jomsviking Player
		for IDPlayer=GameDefines.MAX_MAJOR_CIVS, GameDefines.MAX_CIV_PLAYERS-1, 1 do 

			local pJomsviking = Players[IDPlayer]
			if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then
	
				--Check if Player and Jomsvikings exist
				if (pJomsviking:IsAlive() and pPlayer:IsAlive()) then

							
					--Check if Player and Jomsvikings are Allies.

                                        local pCity = pPlayer:GetCapitalCity()
					if pJomsviking:IsAllies(iPlayer) then


					--(install building #1)
					--(install building #2)


					--Check if Player and Jomsvikings are Friends.
					elseif pJomsviking:IsFriends(iPlayer) then


					--(remove building #1)
					--(install building #2)


					--Check if Player and Jomsvikings are neither Allies not Friends.
					elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then


					--(remove building #1)
					--(remove building #2)


					end

				end
			end
		end			
	end
end


--Operate functions to loop through all players

local function OnAllPlayersDoTurn(iPlayer)		
		
		eCivJomsviking(iPlayer)
			
end
GameEvents.PlayerDoTurn.Add(OnAllPlayersDoTurn)
 
If you're using WHowards DLL maybe this might be a little more efficient; instead of calling each turn, just call the function when minor relationships change, using:

Code:
//   GameEvents.MinorFriendsChanged.Add(function(iMinor, iMajor, bIsFriend, iOldFriendship, iNewFriendship) end)
//   GameEvents.MinorAlliesChanged.Add(function(iMinor, iMajor, bIsAlly, iOldFriendship, iNewFriendship) end)

If you're not using WHoward's DLL, I apologise.

Edit: Available in vanilla as pointed out by LeeS
 
According to William's API represented as xml, these should be standard to the non-modded dll as GameEvents:
Code:
  <event name="MinorAlliesChanged" type="Hook">
    <arg pos="1" type="PlayerTypes" name="eCS"/>
    <arg pos="2" type="PlayerTypes" name="ePlayer"/>
    <arg pos="3" type="bool" name="bGainedLost"/>
    <arg pos="4" type="int" name="iOldValue"/>
    <arg pos="5" type="int" name="iNewValue"/>
  </event>
  <event name="MinorFriendsChanged" type="Hook">
    <arg pos="1" type="PlayerTypes" name="eCS"/>
    <arg pos="2" type="PlayerTypes" name="ePlayer"/>
    <arg pos="3" type="bool" name="bGainedLost"/>
    <arg pos="4" type="int" name="iOldValue"/>
    <arg pos="5" type="int" name="iNewValue"/>
  </event>

Also see here
 
Here is my original, working code... on PlayerDoTurn...

Code:
--After gaining Theocracy, when Player is Allied with Jomsvikings add 7 buildings to its capital.  If Friends with Jomsvikings add only 2 buildings.
--We want TeamIDs and Teams, not PlayerIDs.

function  eCivJomsviking(iPlayer)

	local pPlayer
	local pJomsviking
	local iJomsviking
	local eCivTeamID		
	local eCivTeam

	-- Set up Player
	local pPlayer = Players[iPlayer]				
			
	local eCivTeamID = pPlayer:GetTeam();
	local eCivTeam= Teams[ pPlayer:GetTeam() ]					
	if (eCivTeam:GetTeamTechs():HasTech( GameInfoTypes["TECH_THEOLOGY"] )) then		

		-- Set up Jomsviking Player
		for IDPlayer=GameDefines.MAX_MAJOR_CIVS, GameDefines.MAX_CIV_PLAYERS-1, 1 do 

			local pJomsviking = Players[IDPlayer]
			if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then
	
				--Check if Player and Jomsvikings exist
				if (pJomsviking:IsAlive() and pPlayer:IsAlive()) then

							
					--Check if Player and Jomsvikings are Allies.
					local pCity = pPlayer:GetCapitalCity()
					if pJomsviking:IsAllies(iPlayer) then


					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
					--print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 7 Jomsviking Resources")

					--Check if Player and Jomsvikings are Friends.
					elseif pJomsviking:IsFriends(iPlayer) then


					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
					--print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 2 Jomsviking Resources")

					--Check if Player and Jomsvikings are neither Allies not Friends.
					elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then


					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);


					end

				end
			end
		end			
	end
end

Here is the code based upon GameEvent lua. It is untested as yet... one question I have is can the two events be worked in sycronicity as I have set them?

Code:
--After gaining Theocracy, when Player is Allied with Jomsvikings add 7 buildings to its capital.  If Friends with Jomsvikings add only 2 buildings.
--We want TeamIDs and Teams, not PlayerIDs.

function  eCivJomsviking(iJomsviking, iPlayer)

	local pPlayer
	local pJomsviking
	local iJomsviking
	local eCivTeamID		
	local eCivTeam

	-- Set up Player
	local pPlayer = Players[iPlayer]				
			
	local eCivTeamID = pPlayer:GetTeam();
	local eCivTeam= Teams[ pPlayer:GetTeam() ]					
	if (eCivTeam:GetTeamTechs():HasTech( GameInfoTypes["TECH_THEOLOGY"] )) then		

		-- Set up Jomsviking Player 

			local pJomsviking = Players[iJomsviking]
			if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then
	
				--Check if Player and Jomsvikings exist
				if (pJomsviking:IsAlive() and pPlayer:IsAlive()) then

							
					--Check if Player and Jomsvikings are Allies.
					local pCity = pPlayer:GetCapitalCity()
					if pJomsviking:IsAllies(iPlayer) then


					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
					--print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 7 Jomsviking Resources")

					--Check if Player and Jomsvikings are Friends.
					elseif pJomsviking:IsFriends(iPlayer) then


					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
					--print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 2 Jomsviking Resources")

					--Check if Player and Jomsvikings are neither Allies not Friends.
					elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then


					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);


					end

				end
			end
		end			
	
end

GameEvents.MinorAlliesChanged.Add(eCivJomsviking);
GameEvents.MinorFriendsChanged.Add(eCivJomsviking);

I am not certain if I need the IsAllies and IsFriends designations as the GameEvents include them as booleans.
 
Okay, something is not working...

I got rid of theocracy as a provision... the resource is not visible until then anyhow and I figured there could be situations when a civ could be Allied and not have Theocracy and upon gaining Theocracy not experience a change in Allied/Friendship state and not gain the building.

I am getting an error, though, with a nil value for pJomsviking being a nil value. iJomsviking is defined as variable in the GameEvent though, so I think pJomsviking is simple to derive from that. It could be as simple as a spelling error I am missing, or maybe something more fundamental is wrong.

Here is the code... the error is in red:

Code:
Thanks for the advice.

--When Player is Allied with Jomsvikings add 7 buildings to its capital.  If Friends with Jomsvikings add only 2 buildings.

function  eCivJomsviking(iJomsviking, iPlayer)

	local pPlayer
	local pJomsviking
	local iJomsviking	

	-- Set up Player
	local pPlayer = Players[iPlayer]

	-- Set up Jomsviking Player
	local pJomsviking = Players[iJomsviking]
	[COLOR="Red"]if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then[/COLOR]
	
		--Check if Player and Jomsvikings exist
		if (pJomsviking:IsAlive() and pPlayer:IsAlive()) then

							
			--Check if Player and Jomsvikings are Allies.
			local pCity = pPlayer:GetCapitalCity()
			if pJomsviking:IsAllies(iPlayer) then


			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
			print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 7 Jomsviking Resources")

			--Check if Player and Jomsvikings are Friends.
			elseif pJomsviking:IsFriends(iPlayer) then


			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
			print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 2 Jomsviking Resources")

			--Check if Player and Jomsvikings are neither Allies not Friends.
			elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then


			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);


			end
		end
	end
end

GameEvents.MinorAlliesChanged.Add(eCivJomsviking);
GameEvents.MinorFriendsChanged.Add(eCivJomsviking);
 
Eliminate all three of these:
Code:
local pPlayer
local pJomsviking
local iJomsviking
  • You do not need them since you are stating
    Code:
    local pPlayer = Players[iPlayer]
    etc., later anyway
  • local iJomsviking is creating a local for use in the function but assigning it a value of nil. This interferes with the argument variable on the definition-line of the function, and is I think the root of the trouble.
 
The code is working, sort of...

I had to add a check to see if pCity exists because some "Alliances" happened before a capital was founded, so pCity was nil.

Now it works, but it seems to do so quite inconsistently. I will be receiving 7 resources when I am in friendship, or 2 when I am allied. I cannot figure out why the result does not always mesh with how it ought to come out.

As well, when I split the code into two different events rather than both governing the same function, these inconsistencies still arose, and I was no longer getting print statements (odd) even though I was receiving the resources in question. Even then, the resources I was receiving were not always matching what ought to have been occurring.

Both GameEvents have a boolean for the third variable... bAllied for example. I am wondering if I ought to be using that within the code to check what the actual state is... I think the code may be inconsistent because it fires whenever the state changes, and this may be from Friend to Ally or regressing from Ally to Friend. This shouldn't matter as within the code, there are checks anyway, but perhaps it does.

I am quite perplexed.

Code:
--When Player is Allied with Jomsvikings add 7 buildings to its capital.  If Friends with Jomsvikings add only 2 buildings.

function  eCivJomsviking(iJomsviking, iPlayer)
	
	-- Set up Players
	local pPlayer = Players[iPlayer]
	local pJomsviking = Players[iJomsviking]
	if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then
	
		--Check if Player and Jomsvikings exist
		local pCity = pPlayer:GetCapitalCity()
		if (pJomsviking:IsAlive() and pPlayer:IsAlive() and pCity) then

							
			--Check if Player and Jomsvikings are Allies.
			
			if pJomsviking:IsAllies(iPlayer) then


			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
			print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 7 Jomsviking Resources")

			--Check if Player and Jomsvikings are Friends.
			elseif pJomsviking:IsFriends(iPlayer) then


			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
			print (pPlayer:GetName(), "gets a Jomsviking Hall in...", pCity:GetName(), "and gets 2 Jomsviking Resources")

			--Check if Player and Jomsvikings are neither Allies not Friends.
			elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then


			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);


			end
		end
	end
end

GameEvents.MinorAlliesChanged.Add(eCivJomsviking);
GameEvents.MinorFriendsChanged.Add(eCivJomsviking);
 
I'm getting 'false' from this method when a specified Minor Civ is in fact Ally to the Major civ:
Code:
if pMinor:IsAllies(iMajor) then
I am getting 'true' from the IsFriends(x) method for the same player, however.

I duplicated your code so I could run it with standard game-data to see if there was some issue there, and then just commented out everything except print statements:
Code:
--When Player is Allied with Jomsvikings add 7 buildings to its capital.  If Friends with Jomsvikings add only 2 buildings.
local iJomsvikingCiv = GameInfoTypes.MINOR_CIV_JERUSALEM
function SetCapitalBuildings(pCity, iMajor, pMinor)
	print("SetCapitalBuildings fired")
	if pMinor:IsAllies(iMajor) then
		--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
		print("We Are Allies With Jerusalem: 7 BUILDING_JOMSVIKING_HALL")
	else
		if pMinor:IsFriends(iMajor) then
			--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
			print("We Are Friends With Jerusalem: 2 BUILDING_JOMSVIKING_HALL")
		else
			--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);
			print("We Have No Status With Jerusalem: 0 BUILDING_JOMSVIKING_HALL")
		end
	end
end
function MinorAllyChanged(iMinor, iMajor, bIsAlly, iOldFriendship, iNewFriendship)
	print("MinorAllyChanged fired")
	local pPlayer = Players[iMajor]
	local pMinor = Players[iMinor]
	if (iJomsvikingCiv == pMinor:GetMinorCivType()) then
		print("MinorAllyChanged: iJomsvikingCiv == pMinor:GetMinorCivType()")
		if pPlayer:GetCapitalCity() ~= nil then
			print("MinorAllyChanged: pPlayer:GetCapitalCity() ~= nil")
			SetCapitalBuildings(pPlayer:GetCapitalCity(), iMajor, pMinor)
		end
	end
end
function MinorFriendChanged(iMinor, iMajor, bIsFriend, iOldFriendship, iNewFriendship)
	print("MinorFriendChanged fired")
	local pPlayer = Players[iMajor]
	local pMinor = Players[iMinor]
	if (iJomsvikingCiv == pMinor:GetMinorCivType()) then
		print("MinorFriendChanged: iJomsvikingCiv == pMinor:GetMinorCivType()")
		if pPlayer:GetCapitalCity() ~= nil then
			print("MinorFriendChanged: pPlayer:GetCapitalCity() ~= nil")
			SetCapitalBuildings(pPlayer:GetCapitalCity(), iMajor, pMinor)
		end
	end
end
GameEvents.MinorAlliesChanged.Add(MinorAllyChanged);
GameEvents.MinorFriendsChanged.Add(MinorFriendChanged);
Even though the two event functions are pretty much identical I also wanted to make sure there were not 'double-barrel' issues from the same code firing 1st for ally and second for friend, for example. Even though the way it is coded (and the way you coded) this should not make a difference.

When I gave myself boatloads of gold so I could buy ally status, what I got from the print statements to the lua log was:
Code:
[2554498.953] GeneralEventsScripting: MinorAllyChanged fired
[2554498.953] GeneralEventsScripting: MinorAllyChanged: iJomsvikingCiv == pMinor:GetMinorCivType()
[2554498.953] GeneralEventsScripting: MinorAllyChanged: pPlayer:GetCapitalCity() ~= nil
[2554498.953] GeneralEventsScripting: SetCapitalBuildings fired
[2554498.968] GeneralEventsScripting: We Are Friends With Jerusalem: 2 BUILDING_JOMSVIKING_HALL
 
You need to use the values of bIsAlly and/or bIsFriend from the events, as the events fire before the minor civ updates its concept of who is their ally.

This is intentional, as you can use pMinor:GetAlly() to get their old ally who the new ally is replacing (if bIsAlly == true)
 
Craig, try this code
Code:
--When Player is Allied with Jomsvikings add 7 buildings to its capital.  If Friends with Jomsvikings add only 2 buildings.
local iJomsvikingCiv = GameInfoTypes.MINOR_CIV_JERUSALEM
function MinorAllyChanged(iMinor, iMajor, bIsAlly, iOldFriendship, iNewFriendship)
	print("MinorAllyChanged fired")
	local pPlayer = Players[iMajor]
	local pMinor = Players[iMinor]
	if (iJomsvikingCiv == pMinor:GetMinorCivType()) then
		print("MinorAllyChanged: iJomsvikingCiv == pMinor:GetMinorCivType()")
		local pCity = pPlayer:GetCapitalCity()
		if pCity ~= nil then
			print("MinorAllyChanged: pPlayer:GetCapitalCity() ~= nil")
			if bIsAlly then
				print("MinorAllyChanged: bIsAlly is true, we are their new Ally")
				--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
				print("We Are Allies With Jerusalem: 7 BUILDING_JOMSVIKING_HALL")
			else
				print("MinorAllyChanged: bIsAlly is false, so we can no longer be their Ally")
				--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
				print("We Are Friends With Jerusalem: 2 BUILDING_JOMSVIKING_HALL")
			end
		end
	end
end
function MinorFriendChanged(iMinor, iMajor, bIsFriend, iOldFriendship, iNewFriendship)
	print("MinorFriendChanged fired")
	local pPlayer = Players[iMajor]
	local pMinor = Players[iMinor]
	if (iJomsvikingCiv == pMinor:GetMinorCivType()) then
		print("MinorFriendChanged: iJomsvikingCiv == pMinor:GetMinorCivType()")
		local pCity = pPlayer:GetCapitalCity()
		if pCity ~= nil then
			print("MinorFriendChanged: pPlayer:GetCapitalCity() ~= nil")
			if bIsFriend then
				print("MinorFriendChanged: bIsFriend is true, we are their new Friend")
				--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
				print("We Are Allies With Jerusalem: 2 BUILDING_JOMSVIKING_HALL")
			else
				print("MinorFriendChanged: bIsFriend is false, so we can no longer be their Friend")
				--pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);
				print("We Are Friends With Jerusalem: 0 BUILDING_JOMSVIKING_HALL")
			end
		end
	end
end
GameEvents.MinorAlliesChanged.Add(MinorAllyChanged);
GameEvents.MinorFriendsChanged.Add(MinorFriendChanged);
It appears to be working correctly. You'll just have to edit away the print statements and remove the '--' comment commands where needed, and change MINOR_CIV_JERUSALEM.
 
I just woke up so I'm a little groggy. Late last night, I came up with the following code... it seems somewhat similar to yours and I tested briefly to see if it worked. It seems to...

That being said, I am certain yours is the more elegant and I will be using that.

I won't have time today to do any testing... I am going to sit down and compare them line by line to see how my own code is lacking and inefficient. It will be an interesting learning experience.

Code:
--When Player is Allied with Jomsvikings add 7 buildings to its capital.

function  eCivAlliedJomsviking(iJomsviking, iPlayer, IsAllies)
	
	-- Set up Players
	local pPlayer = Players[iPlayer]
	local pJomsviking = Players[iJomsviking]

	if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then
			
		local pCity = pPlayer:GetCapitalCity()
		if  pCity then

			if IsAllies then
			
			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
			print (pPlayer:GetName(), "AAA gets a Jomsviking Hall in...", pCity:GetName(), "and gets 7 Jomsviking Resources")

			elseif pJomsviking:IsFriends(iPlayer) then
			
			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
			print (pPlayer:GetName(), "AAA gets a Jomsviking Hall in...", pCity:GetName(), "and gets 2 Jomsviking Resources")	

			elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then

			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);
			print (pPlayer:GetName(), "AAA not allied to Jomsvikings so", pCity:GetName(), "no longer gets Jomsviking Resources")

			end
		end				
	end
end

GameEvents.MinorAlliesChanged.Add(eCivAlliedJomsviking);

--When Player is Friends with Jomsvikings add 2 buildings to its capital.

function  eCivFriendJomsviking(iJomsviking, iPlayer, IsFriends)
	
	-- Set up Players
	local pPlayer = Players[iPlayer]
	local pJomsviking = Players[iJomsviking]

	if (GameInfo.MinorCivilizations.MINOR_CIV_JOMSVIKING.ID == pJomsviking:GetMinorCivType()) then
			
		local pCity = pPlayer:GetCapitalCity()
		if  pCity then

			if IsFriends then
			
			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
			print (pPlayer:GetName(), "BBB gets a Jomsviking Hall in...", pCity:GetName(), "and gets 2 Jomsviking Resources")

			elseif pJomsviking:IsAllies(iPlayer) then
			
			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
			print (pPlayer:GetName(), "BBB gets a Jomsviking Hall in...", pCity:GetName(), "and gets 7 Jomsviking Resources")	

			elseif not pJomsviking:IsAllies(iPlayer) and not pJomsviking:IsFriends(iPlayer) then

			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);
			print (pPlayer:GetName(), "BBB not Friends to Jomsvikings so", pCity:GetName(), "no longer gets Jomsviking Resources")

			end
		end				
	end
end

GameEvents.MinorFriendsChanged.Add(eCivFriendJomsviking);

Thank-you. I will post in about 24 hours as I am busy until then and won't be able to go over things in detail until then.
 
I did a short bit of testing...

Generally, the code works; however, it does not take into account that a Civilization may DoW on its minor ally. Unlikely, but possible.

Testing shows this to be the case. A major Civilization DoW on its minor will leave it with the version of the building that gives 2 resources.

I will do a bit of an amalgamation of your code, LeeS, and mine... I think a check for friendship within the code for Allies might do it.

I will do that within the next 8 hours or so.
 
I think a check for friendship within the code for Allies might do it.
You can use the iNewFriendship and iOldFriendship parameters for that
 
I have done some changes to the code and I am still getting inconsistent results when I DoW or even go from Allied to Friend. I am not certain if the GREEN line is correctly implemented. The RED is my additions to LeeS' code to check if Friends.

For MinorAllyChanged function, it should check if Allied (so 7 buildings), then elseif Friend (so 2 buildings), else neither (so 0 buildings). It does not appear to be working in all cases. I suspect I am misusing iNewFriendship.

Code:
--When Player is Allied with Jomsvikings add 7 buildings to its capital.  
--If Friends with Jomsvikings add only 2 buildings.
--If neither Friends nor Allies with Jomsvikings 0 buildings.
local iJomsvikingCiv = GameInfoTypes.MINOR_CIV_JOMSVIKING
function MinorAllyChanged(iMinor, iMajor, bIsAlly, iOldFriendship, iNewFriendship)
	print("MinorAllyChanged fired")
	local pPlayer = Players[iMajor]
	local pMinor = Players[iMinor]
	if (iJomsvikingCiv == pMinor:GetMinorCivType()) then
		print("MinorAllyChanged: iJomsvikingCiv == pMinor:GetMinorCivType()")
		local pCity = pPlayer:GetCapitalCity()
		if pCity ~= nil then
			print("MinorAllyChanged: pPlayer:GetCapitalCity() ~= nil")
			if bIsAlly then
				print("MinorAllyChanged: bIsAlly is true", pPlayer:GetName(), "...is their new Ally")
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 7);
				print("We Are Allies With Jomsburg: 7 BUILDING_JOMSVIKING_HALL")
			[COLOR="Green"]elseif iNewFriendship == iMajor then[/COLOR]
				print("MinorAllyChanged: iNewFriendship is true", pPlayer:GetName(), "...is new Friend")
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
				print("We Are Friends With Jomsburg: 2 BUILDING_JOMSVIKING_HALL")
			[COLOR="Red"]else
				print("MinorAllyChanged: bIsAlly is false, iNewFriendship is false, so ", pPlayer:GetName(), "... can no longer be their Ally or Friend")
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);
				print("We Are not Friends or Allies With Jomsburg: 0 BUILDING_JOMSVIKING_HALL")
			end[/COLOR]
		end
	end
end
function MinorFriendChanged(iMinor, iMajor, bIsFriend, iOldFriendship, iNewFriendship)
	print("MinorFriendChanged fired")
	local pPlayer = Players[iMajor]
	local pMinor = Players[iMinor]
	if (iJomsvikingCiv == pMinor:GetMinorCivType()) then
		print("MinorFriendChanged: iJomsvikingCiv == pMinor:GetMinorCivType()")
		local pCity = pPlayer:GetCapitalCity()
		if pCity ~= nil then
			print("MinorFriendChanged: pPlayer:GetCapitalCity() ~= nil")
			if bIsFriend then
				print("MinorFriendChanged: bIsFriend is true", pPlayer:GetName(), "...is their new Friend")
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 2);
				print("We Are Friends With Jomsburg: 2 BUILDING_JOMSVIKING_HALL")
			else
				print("MinorFriendChanged: bIsFriend is false, so ", pPlayer:GetName(), "...can no longer be their Friend")
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_JOMSVIKING_HALL"], 0);
				print("We Are Not Friends With Jomsburg: 0 BUILDING_JOMSVIKING_HALL")
			end
		end
	end
end
GameEvents.MinorAlliesChanged.Add(MinorAllyChanged);
GameEvents.MinorFriendsChanged.Add(MinorFriendChanged);

Thank-you.
 
I would change the top of the function to be like this since it is not clear what the two final integer arguments are reporting. I would have interpretted them as an influence level (I actually meant amount but typed level), but they might be a player ID#

Code:
function MinorAllyChanged(iMinor, iMajor, bIsAlly, iOldFriendship, iNewFriendship)
	print("MinorAllyChanged fired")
	print("bIsAlly " .. tostring(bIsAlly))
	print("iOldFriendship " .. tostring(iOldFriendship))
	print("iNewFriendship " .. tostring(iNewFriendship))
The two final parameters give iMajor's influence amounts with the city state. So you would need to compare iNewFriendship against the amount of influence needed to be Friends. Uh, I don't remember if this scales to gamespeed or not.
 
Top Bottom