LUA code for a complex UA

Firebug

Not-so Great Engineer
Joined
Sep 25, 2014
Messages
1,271
Location
Clevedon, England
I want my next Greek state, Thebes, to be able to take city states through both peace and force. This is as to represent their leadership of the Boeotian league. Here's the idea.

Boeotian League: While sending a trade route to a city state your influence with them goes up equal to a third of your culture per turn. Demanding tribute from an allied city state gives a random chance of them joining you.

But the UU and UB are pretty complex too. Here they are -

Sacred Band (Spearman): Has the 'Lover's Devotion' promotion. (Inflicts 25% more damage then normal when damaged)

Autocracy has a tenet for this, but i'm not sure if its accessible as a promotion.

UB - Cadmea (Castle): It yields +1 culture and an additional +1 culture for each city state that is your ally. Only gives +5 combat strength and +20 HP but is available at Masonry instead.

Only complex part is +1 culture for each allied city state.

Any ideas?
 
Boeotian League: While sending a trade route to a city state your influence with them goes up equal to a third of your culture per turn. Demanding tribute form an allied city state gives a random chance of them joining you.

I'm pretty sure in the Community Balance Patch that they revised Mongolia so it could take over city states through demanding tribute. You could take a look at the code but I'm not sure if their re-worked trait was done through DLL though.
 
Apologies in advance for being generic (not particularly familiar with Lua syntax...), but:

Boeotian League:

Assuming there is an event that you can hook along the lines of "on trade route sent" (I don't see one in the API though, someone correct me if I'm wrong)

- Check recipient: isMinorCiv()
- Get the player's total culture: GetTotalJONSCulturePerTurn()
- Change influence with the minor civ: ChangeMinorCivFriendshipWithMajor()

Assuming there is an event that fires/can be hooked (again, I don't see one in the API, someone correct me if I'm wrong):
- Rand to get the random number
- Change influence with the minor civ (by like 60?... there is no function that sets you automatically as an ally as far as I can tell): ChangeMinorCivFriendshipWithMajor()
 
I just took a look at the files, and it looks to be DLL.

Mongolia from the CBP wasn't quite the effect i'm looking for. I just hope the idea is possible through Lua.
 
Apologies in advance for being generic (not particularly familiar with Lua syntax...), but:

Boeotian League:

Assuming there is an event that you can hook along the lines of "on trade route sent" (I don't see one in the API though, someone correct me if I'm wrong)

- Check recipient: isMinorCiv()
- Get the player's total culture: GetTotalJONSCulturePerTurn()
- Change influence with the minor civ: ChangeMinorCivFriendshipWithMajor()

Assuming there is an event that fires/can be hooked (again, I don't see one in the API, someone correct me if I'm wrong):
- Rand to get the random number
- Change influence with the minor civ (by like 60?... there is no function that sets you automatically as an ally as far as I can tell): ChangeMinorCivFriendshipWithMajor()

I'll take a look at that first half.
With the second half, i just noticed i made a typo so i changed it.

It did say "demanding tribute form an allied city state gives a random chance of them joining you"
when it should of said "demanding tribute FROM an allied city state". and by join i mean puppet. (should explain that better)
 
Well, I think the first part of the UA should be feasible:

While sending a trade route to a city state your influence with them goes up equal to a third of your culture per turn.

I know that one of JFD's civs (although I can't remember which one, off-hand <.<; ) had this code for trade routes:

Code:
--------------------------------------------------------------------------------------------------------------------------
-- JFD_GetNumIncomingTradeRoutes
--------------------------------------------------------------------------------------------------------------------------
function JFD_GetNumIncomingTradeRoutes(playerID, city)
	local player = Players[playerID]
	local tradeRoutes = player:GetTradeRoutes()
	local numIncomingTRs = 0
	for i, v in ipairs(tradeRoutes) do
		local originatingCity = v.FromCity
		local targetCity = v.ToCity
		if targetCity == city then
			local originatingPlayer = originatingCity:GetOwner()
			local targetPlayer = targetCity:GetOwner()
			if originatingPlayer ~= targetPlayer then
				numIncomingTRs = numIncomingTRs + 1
			end
		end
	end
	
	return numIncomingTRs
end

which shows how you can use the table GetTradeRoutes() to get the origin and destination for all the trade routes the civ has. So you'd check at the start to see if it's your Sparta civ, and if so then get the table of trade routes, and go through to find out which ones are going to city-states by checking to see if the owner of the destination city IsMinorCiv() (I think). Then you can use ChangeMinorCivFriendshipWithMajor to add the amount of influence to the city state that you want.

I hope that makes sense... <.<;

Sacred Band (Spearman): Has the 'Lover's Devotion' promotion. (Inflicts 25% more damage then normal when damaged)

On PlayerDoTurn, go through your units, and if they are Sacred Bands and damaged, give them a promotion that gives them a +25% bonus to Attack?
 
This is some code adapted from something that never got used. It won't update in "realtime", but will do so during turn processing. There's some extra few lines of code that should not interfere with what you want. You need to use the lua file you create from this as a InGameUIAddinIn in Modbuddy.

This will add 1 extra culture per turn per city-state ally to any city of CIVILIZATION_X that has BUILDING_X, so all you need to do is change the civ name and the building name.
Spoiler :
Code:
gRequiredCivName = "CIVILIZATION_X"
gBuildingForCode = GameInfoTypes.BUILDING_X

--gTable = {}
--gTable.gNumberCSAllies = 0
--gTable.gNumberCSFriends = 0


-------------------------------------------------------------------------------------------------
--Calculate during turn processing the number of City State Allies and Friends
--this updates the number of city state allies during game play
-------------------------------------------------------------------------------------------------

function CSAlliesFriends(iPlayer)
	local pPlayer = Players[iPlayer]
	if pPlayer:GetCivilizationType() == GameInfoTypes[gRequiredCivName] then
		--local pCity = pPlayer:GetCapitalCity();
		gNumberCSAllies = 0
		gNumberCSFriends = 0
		iCivPlayerNumber = iPlayer
		for i = 0, GameDefines.MAX_PLAYERS - 1 do
			if i ~= iCivPlayerNumber then
				if Players[i]:IsMinorCiv() then
					local iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber)
					--print("results from iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber) is " .. tostring(iFriend))

					if iFriend == 1 then
						--print("Is a Friend")
						gNumberCSFriends = gNumberCSFriends + 1
					end

					if iFriend == 2 then
						--print("Is an Ally")
						gNumberCSAllies = gNumberCSAllies + 1
					end
				end
			end
		end

		-------------------------------------------------------------------------
		--Ally and Friend city commands here
		-------------------------------------------------------------------------

		for pCity in pPlayer:Cities() do
			if pCity:IsHasBuilding(gBuildingForCode) then
				pPlayer:ChangeJONSCulture(gNumberCSAllies)
			end
		end

		--gTable.gNumberCSAllies = gNumberCSAllies
		--gTable.gNumberCSFriends = gNumberCSFriends
	end
end
GameEvents.PlayerDoTurn.Add(CSAlliesFriends)
The unique unit thing, however, is going to be far more difficult to crack, mainly because we do not have access to a reliable combat event.

-------------------

[edit] duh. I was mis-reading, I think, what you were saying you wanted for the unique unit.
 
Sorry to bump this back up to the top, but it'd be nice if i could get some feedback on whether on not the
"Random chance for an allied city state to become a puppet when demanding tribute from them"
and making the chance more based on how much culture you output.
 
This is some code adapted from something that never got used. It won't update in "realtime", but will do so during turn processing. There's some extra few lines of code that should not interfere with what you want. You need to use the lua file you create from this as a InGameUIAddinIn in Modbuddy.

This will add 1 extra culture per turn per city-state ally to any city of CIVILIZATION_X that has BUILDING_X, so all you need to do is change the civ name and the building name.
Spoiler :
Code:
gRequiredCivName = "CIVILIZATION_X"
gBuildingForCode = GameInfoTypes.BUILDING_X

--gTable = {}
--gTable.gNumberCSAllies = 0
--gTable.gNumberCSFriends = 0


-------------------------------------------------------------------------------------------------
--Calculate during turn processing the number of City State Allies and Friends
--this updates the number of city state allies during game play
-------------------------------------------------------------------------------------------------

function CSAlliesFriends(iPlayer)
	local pPlayer = Players[iPlayer]
	if pPlayer:GetCivilizationType() == GameInfoTypes[gRequiredCivName] then
		--local pCity = pPlayer:GetCapitalCity();
		gNumberCSAllies = 0
		gNumberCSFriends = 0
		iCivPlayerNumber = iPlayer
		for i = 0, GameDefines.MAX_PLAYERS - 1 do
			if i ~= iCivPlayerNumber then
				if Players[i]:IsMinorCiv() then
					local iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber)
					--print("results from iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber) is " .. tostring(iFriend))

					if iFriend == 1 then
						--print("Is a Friend")
						gNumberCSFriends = gNumberCSFriends + 1
					end

					if iFriend == 2 then
						--print("Is an Ally")
						gNumberCSAllies = gNumberCSAllies + 1
					end
				end
			end
		end

		-------------------------------------------------------------------------
		--Ally and Friend city commands here
		-------------------------------------------------------------------------

		for pCity in pPlayer:Cities() do
			if pCity:IsHasBuilding(gBuildingForCode) then
				pPlayer:ChangeJONSCulture(gNumberCSAllies)
			end
		end

		--gTable.gNumberCSAllies = gNumberCSAllies
		--gTable.gNumberCSFriends = gNumberCSFriends
	end
end
GameEvents.PlayerDoTurn.Add(CSAlliesFriends)
The unique unit thing, however, is going to be far more difficult to crack, mainly because we do not have access to a reliable combat event.

-------------------

[edit] duh. I was mis-reading, I think, what you were saying you wanted for the unique unit.

Oh wow, this is actually something I've been looking for in my own mod. Do you happen to know a quick way to A) increase the culture per turn per city-state ally, and B) change it to earn culture for every declaration of friendship with a major civ?
 
Oh wow, this is actually something I've been looking for in my own mod. Do you happen to know a quick way to A) increase the culture per turn per city-state ally, and B) change it to earn culture for every declaration of friendship with a major civ?
The most expediant way is to make the line
pPlayer:ChangeJONSCulture(gNumberCSAllies)
just add the amount of culture you calculate should be added, and remove the lines that "wrap" it to make it based on whether a city has a building, so if you want 2 culture for every CS ally, it becomes:
Code:
		-------------------------------------------------------------------------
		--Ally and Friend city commands here
		-------------------------------------------------------------------------

		pPlayer:ChangeJONSCulture(gNumberCSAllies * 2)

		--gTable.gNumberCSAllies = gNumberCSAllies
		--gTable.gNumberCSFriends = gNumberCSFriends
	end
It won't show using this method within the CPT in the Top Panel, but the culture will be added. The other method would be to use the dummy building approach and give each copy of the dummy 1 Culture Yield in the XML, so you would do something like this, adding the required number of dummies in the capital city:
Code:
		-------------------------------------------------------------------------
		--Ally and Friend city commands here
		-------------------------------------------------------------------------

		pCapitalCity = pPlayer:GetCapitalCity()

		pCapitalCity:SetNumRealBuilding(gBuildingForCode, gNumberCSAllies * 2)

		--gTable.gNumberCSAllies = gNumberCSAllies
		--gTable.gNumberCSFriends = gNumberCSFriends
	end
Using a dummy building will make the Culture Per Turn in the Top Panel reflect the change where the player can see it in the xxxxx/+yyyyy part of the display for culture, but it will not be line-itemed separate from the other culture coming from cities when you hover over the CPT in the top panel.

Note that both of these methods will not be reflected in "real-time" when the number of CS allies changes, it will be updated only when the player hits the "Next Turn" button as part of the turn processing.

-----------------------------------------------------------------------------------------------

The DoF issue can be calculated at the same time as all this is going on:
Code:
		for i = 0, GameDefines.MAX_PLAYERS - 1 do
			if i ~= iCivPlayerNumber then
				if Players[i]:IsMinorCiv() then
					local iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber)
					--print("results from iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber) is " .. tostring(iFriend))

					if iFriend == 1 then
						--print("Is a Friend")
						gNumberCSFriends = gNumberCSFriends + 1
					end

					if iFriend == 2 then
						--print("Is an Ally")
						gNumberCSAllies = gNumberCSAllies + 1
					end
				end
			end
		end
but requires a bit of a redraft of it. I think JFD's Belgium mod may have a sample of lua code in it on how to find the number of DoF a player has with other major civs.
 
the Community Balance Patch Mongolia has a trait similar to what i'm after. It annexes cities that you demand tribute from. However, in an attempt to find out how they did it, i can't find the files.

I say similar because i'm hoping for it to PUPPET rather then annex, and only from Allied city states.
 
The most expediant way is to make the line
just add the amount of culture you calculate should be added, and remove the lines that "wrap" it to make it based on whether a city has a building, so if you want 2 culture for every CS ally, it becomes:
Code:
		-------------------------------------------------------------------------
		--Ally and Friend city commands here
		-------------------------------------------------------------------------

		pPlayer:ChangeJONSCulture(gNumberCSAllies * 2)

		--gTable.gNumberCSAllies = gNumberCSAllies
		--gTable.gNumberCSFriends = gNumberCSFriends
	end
It won't show using this method within the CPT in the Top Panel, but the culture will be added. The other method would be to use the dummy building approach and give each copy of the dummy 1 Culture Yield in the XML, so you would do something like this, adding the required number of dummies in the capital city:
Code:
		-------------------------------------------------------------------------
		--Ally and Friend city commands here
		-------------------------------------------------------------------------

		pCapitalCity = pPlayer:GetCapitalCity()

		pCapitalCity:SetNumRealBuilding(gBuildingForCode, gNumberCSAllies * 2)

		--gTable.gNumberCSAllies = gNumberCSAllies
		--gTable.gNumberCSFriends = gNumberCSFriends
	end
Using a dummy building will make the Culture Per Turn in the Top Panel reflect the change where the player can see it in the xxxxx/+yyyyy part of the display for culture, but it will not be line-itemed separate from the other culture coming from cities when you hover over the CPT in the top panel.

Note that both of these methods will not be reflected in "real-time" when the number of CS allies changes, it will be updated only when the player hits the "Next Turn" button as part of the turn processing.

-----------------------------------------------------------------------------------------------

The DoF issue can be calculated at the same time as all this is going on:
Code:
		for i = 0, GameDefines.MAX_PLAYERS - 1 do
			if i ~= iCivPlayerNumber then
				if Players[i]:IsMinorCiv() then
					local iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber)
					--print("results from iFriend = Players[i]:GetMinorCivFriendshipLevelWithMajor(iCivPlayerNumber) is " .. tostring(iFriend))

					if iFriend == 1 then
						--print("Is a Friend")
						gNumberCSFriends = gNumberCSFriends + 1
					end

					if iFriend == 2 then
						--print("Is an Ally")
						gNumberCSAllies = gNumberCSAllies + 1
					end
				end
			end
		end
but requires a bit of a redraft of it. I think JFD's Belgium mod may have a sample of lua code in it on how to find the number of DoF a player has with other major civs.

LeeS, you are beautiful person. Thank you.

Also, I've never used Lua before, do I have to set VFS=True, or anything like that?
 
Lua only needs to be set to VFS = true if you are planning on either replacing a stock game Lua file, or calling it from within another Lua file.

If it is your only / main Lua file, you need to add it as an InGameUIAddin under the 'Content' tab of your mod properties page.
 
Lua only needs to be set to VFS = true if you are planning on either replacing a stock game Lua file, or calling it from within another Lua file.

If it is your only / main Lua file, you need to add it as an InGameUIAddin under the 'Content' tab of your mod properties page.

Ah, ok. Thanks!
 
Top Bottom