Is there any mod project, which adds/fixes Lua-functions (and XML-entries)? It might not only solve some of my problems but also make different mods more compatible.
Edit: E.g. TurnsToReachTarget might be a nice function for exporting it in Lua.
I'm looking to make the following trait happen for my Roanapur civ:
Trait: The Worst of the World (+1 Trade route, and 10% gold yield of all trade routes for every active war that does not involve Roanapur. Gold yield from plundering trade routes is tripled.)
Well, I'm still a bit of an XML-Apostle when SQL is simply of no advantage. Since he is going to need to specify the Palace in the table anyway, the XML method is actually simpler. Compare your two code-methods with a very jaundiced view. Is the SQL method really simpler? Is the XML method really more ugly? Obviously everyone's mileage is going to vary, but for me the answers to both these questions is "no" -- which my engineering background leads me to believe there is no "better" in this specific application, there is only user-defined variable-values of "easier", "simpler", "more-direct", "less-ugly", except that in this case there is another consideration to examine: what happens to such an SQL method if another mod loads into the game 1st and eliminates CIVILIZATION_AMERICA from the game's database ?
He will, however, require lua for the 10% per trade route thing, but without better definition from DocApplejuice as to what exactly he means, and under what conditions the % should be 'calculated' and 'applied', it is a little difficult to think my way through to a solution. For example:
10% of whose trade route(s) ?
Only the trade-routes originating in your civ,?
or those originating from your civ and those ending in your civ?
If for both, do both players get the bonus?
what of those originating in your civ and terminating in a civ who is at war with someone else? does this matter? what of the reverse, where the originating Civ-A is at war with Civ-B, but not at war with your Civ?
an additional 10% of someone's (whose?) trade-routes for every war? So if four player-pairs are at war (A-B, B-C, C-A, A-D) there should be 40% bump of (whose?) trade routes?
That just gives me a flat +1 Trade route, and 10% gold one time for the entire game.
I'm looking for +1 Trade route, and 10% gold yield of all trade routes for every active war that does not involve Roanapur. So, something that'll spawn in one copy of the dummy building in the capital each time a war that doesn't involve that civ is declared.
He will, however, require lua for the 10% per trade route thing, but without better definition from DocApplejuice as to what exactly he means, and under what conditions the % should be 'calculated' and 'applied', it is a little difficult to think my way through to a solution. For example:
10% of whose trade route(s) ?
Only the trade-routes originating in your civ,?
or those originating from your civ and those ending in your civ?
If for both, do both players get the bonus?
what of those originating in your civ and terminating in a civ who is at war with someone else? does this matter? what of the reverse, where the originating Civ-A is at war with Civ-B, but not at war with your Civ?
an additional 10% of someone's (whose?) trade-routes for every war? So if four player-pairs are at war (A-B, B-C, C-A, A-D) there should be 40% bump of (whose?) trade routes?
Well, I'm still a bit of an XML-Apostle when SQL is simply of no advantage. Since he is going to need to specify the Palace in the table anyway, the XML method is actually simpler. Compare your two code-methods with a very jaundiced view. Is the SQL method really simpler? Is the XML method really more ugly? Obviously everyone's mileage is going to vary, but for me the answers to both these questions is "no" -- which my engineering background leads me to believe there is no "better" in this specific application, there is only user-defined variable-values of "easier", "simpler", "more-direct", "less-ugly", except that in this case there is another consideration to examine: what happens to such an SQL method if another mod loads into the game 1st and eliminates CIVILIZATION_AMERICA from the game's database?
Yeah, it's a problem due to me using CIVILIZATION_AMERICA as the base for my test civ where I teste random stuff. Here is a version that will work without ever failing.
Besides, I find XML not so much as ugly as "I screwed up somewhere, it now won't load anything and it's probably something small and stupid but more annoying than the rest of small and stupid things".
Code:
INSERT INTO Civilization_FreeBuildingClasses
(CivilizationType, BuildingClassType)
VALUES ('CIVILIZATION_YOUR_CIV_HERE', 'BUILDINGCLASS_SPECIFIC_DUMMY_HERE'),
('CIVILIZATION_YOUR_CIV_HERE', 'BUILDINGCLASS_PALACE');
That just gives me a flat +1 Trade route, and 10% gold one time for the entire game.
I'm looking for +1 Trade route, and 10% gold yield of all trade routes for every active war that does not involve Roanapur. So, something that'll spawn in one copy of the dummy building in the capital each time a war that doesn't involve that civ is declared.
actually translates to "2" total gold bonus. Similar for the "Sea" one, except that "100" equals "2" GPT because sea trade routes automatically have all gold doubled.
Does "for every active war" count civs that Roanapur has not met?
I'm not asking these questions to be a pita or a pestilence -- I'm asking because the answers drive how such a code needs to be written. I'm also assuming by "trade routes" you mean those of Caravans/Cargo Ships and not the "city connection trade routes" -- is this correct?
actually translates to "2" total gold bonus. Similar for the "Sea" one, except that "100" equals "2" GPT because sea trade routes automatically have all gold doubled.
Does "for every active war" count civs that Roanapur has not met?
I'm not asking these questions to be a pita or a pestilence -- I'm asking because the answers drive how such a code needs to be written. I'm also assuming by "trade routes" you mean those of Caravans/Cargo Ships and not the "city connection trade routes" -- is this correct?
I should have something you can try sometime tomorrow. I nearly had it done and then I realised I was making a huge conceptual error -- oops.
If I haven't re-made another eggregious goof this should work. Obviously, though, I have not had an opporunity to test it. If you find the code is toast because of something I've overlooked then I'll have to set it up as a "listener" in one of the mods I'm currently testing and see where the goofs are at, if any.
Spoiler:
Code:
local iCivilizationRoanapur = GameInfoTypes.CIVILIZATION_ROANAPUR
local iBuildingGoldBonus = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER
function NumberMajorWars(iPlayer)
local iNumberMajorWars = 0
tTableOfWarringCivs = {}
for iMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if iMajPlayer ~= iPlayer then
local pMajorPlayer = Players[iMajPlayer]
if pMajorPlayer:IsAlive() then
local MajorPlayerTeam = pMajorPlayer:GetTeam()
for iOtherMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if (iOtherMajPlayer ~= iPlayer) and (iOtherMajPlayer ~= iMajPlayer) and (Players[iOtherMajPlayer]:IsAlive()) then
local OtherPlayerTeam = Players[iOtherMajPlayer]:GetTeam()
if (Teams[MajorPlayerTeam]:IsAtWar(OtherPlayerTeam)) then
local bWarStateRecorded = false
if tTableOfWarringCivs[iMajPlayer] == nil then
tTableOfWarringCivs[iMajPlayer] = {}
end
if not tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] then
tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] = "War"
bWarStateRecorded = true
iNumberMajorWars = iNumberMajorWars + 1
end
if tTableOfWarringCivs[iOtherMajPlayer] == nil then
tTableOfWarringCivs[iOtherMajPlayer] = {}
end
if not tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] then
tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] = "War"
if not bWarStateRecorded then
iNumberMajorWars = iNumberMajorWars + 1
end
end
end
end
end
end
end
end
return iNumberMajorWars
end
function NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tPlayerTradeRoutes, iNumberMajorWars)
local iTradeRouteGoldTotal = 0
local iNumberCityTradeRoutes = 0
for i = 1, #tPlayerTradeRoutes do
if (tPlayerTradeRoutes[i]["FromID"] == iPlayer) and not (tPlayerTradeRoutes[i]["ToID"] == iPlayer) then
if tPlayerTradeRoutes[i]["FromCity"] == pCity then
iTradeRouteGoldTotal = iTradeRouteGoldTotal + tPlayerTradeRoutes[i]["FromGPT"]
iNumberCityTradeRoutes = iNumberCityTradeRoutes + 1
end
end
end
iTradeRouteGoldTotal = math.ceil(((iTradeRouteGoldTotal * (iNumberMajorWars * .1))/100)/iNumberCityTradeRoutes)
pCity:SetNumRealBuilding(iBuildingGoldBonus, iTradeRouteGoldTotal)
end
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local tTradeRoutes = Players[iPlayer]:GetTradeRoutes()
if #tTradeRoutes > 0 then
local iNumberMajorWars = NumberMajorWars(iPlayer)
if iNumberMajorWars >= 1 then
for pCity in pPlayer:Cities() do
NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tTradeRoutes, iNumberMajorWars)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
so that each copy of the dummy building added to City-X will increase sea-traderoute and land-traderoute gold by +1GPT.
The code will only add dummy buildings to Roanapur cities that have trade routes going out to cities of other players, and there will be rounding up that may in certain circumstances create an extra GPT or two. Also if the same city has multiple trade routes going out to other cities in other civs, the code will count the number of such trade routes and apply the average bonus so that (average * number routes * percentage original gold) should end up being the correct total amount added, +/- rounding issues.
only apply to outgoing trade-routes, so the code only looks at outgoing trade-routes. Buildings (hidden or otherwise) with these columns will have no effect on incoming trade routes in any case.
The only thing I am not sure of with those two columns is whether or not they "stack" for multiple copies of the same building within the same city. I have never had a chance to verify one way or another. If the effect seems to refuse to "stack" then it will be necessary to change to a dummy building with a gold alteration in <Building_YieldChanges> instead of the two trade route goldbonus columns.
I should have something you can try sometime tomorrow. I nearly had it done and then I realised I was making a huge conceptual error -- oops.
If I haven't re-made another eggregious goof this should work. Obviously, though, I have not had an opporunity to test it. If you find the code is toast because of something I've overlooked then I'll have to set it up as a "listener" in one of the mods I'm currently testing and see where the goofs are at, if any.
Spoiler:
Code:
local iCivilizationRoanapur = GameInfoTypes.CIVILIZATION_ROANAPUR
local iBuildingGoldBonus = GameInfoTypes.BUILDING_SOMETHING_OR_OTHER
function NumberMajorWars(iPlayer)
local iNumberMajorWars = 0
tTableOfWarringCivs = {}
for iMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if iMajPlayer ~= iPlayer then
local pMajorPlayer = Players[iMajPlayer]
if pMajorPlayer:IsAlive() then
local MajorPlayerTeam = pMajorPlayer:GetTeam()
for iOtherMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if (iOtherMajPlayer ~= iPlayer) and (iOtherMajPlayer ~= iMajPlayer) and (Players[iOtherMajPlayer]:IsAlive()) then
local OtherPlayerTeam = Players[iOtherMajPlayer]:GetTeam()
if (Teams[MajorPlayerTeam]:IsAtWar(OtherPlayerTeam)) then
local bWarStateRecorded = false
if tTableOfWarringCivs[iMajPlayer] == nil then
tTableOfWarringCivs[iMajPlayer] = {}
end
if not tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] then
tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] = "War"
bWarStateRecorded = true
iNumberMajorWars = iNumberMajorWars + 1
end
if tTableOfWarringCivs[iOtherMajPlayer] == nil then
tTableOfWarringCivs[iOtherMajPlayer] = {}
end
if not tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] then
tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] = "War"
if not bWarStateRecorded then
iNumberMajorWars = iNumberMajorWars + 1
end
end
end
end
end
end
end
end
return iNumberMajorWars
end
function NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tPlayerTradeRoutes, iNumberMajorWars)
local iTradeRouteGoldTotal = 0
local iNumberCityTradeRoutes = 0
for i = 1, #tPlayerTradeRoutes do
if (tPlayerTradeRoutes[i]["FromID"] == iPlayer) and not (tPlayerTradeRoutes[i]["ToID"] == iPlayer) then
if tPlayerTradeRoutes[i]["FromCity"] == pCity then
iTradeRouteGoldTotal = iTradeRouteGoldTotal + tPlayerTradeRoutes[i]["FromGPT"]
iNumberCityTradeRoutes = iNumberCityTradeRoutes + 1
end
end
end
iTradeRouteGoldTotal = math.ceil(((iTradeRouteGoldTotal * (iNumberMajorWars * .1))/100)/iNumberCityTradeRoutes)
pCity:SetNumRealBuilding(iBuildingGoldBonus, iTradeRouteGoldTotal)
end
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local tTradeRoutes = Players[iPlayer]:GetTradeRoutes()
if #tTradeRoutes > 0 then
local iNumberMajorWars = NumberMajorWars(iPlayer)
if iNumberMajorWars >= 1 then
for pCity in pPlayer:Cities() do
NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tTradeRoutes, iNumberMajorWars)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
so that each copy of the dummy building added to City-X will increase sea-traderoute and land-traderoute gold by +1GPT.
The code will only add dummy buildings to Roanapur cities that have trade routes going out to cities of other players, and there will be rounding up that may in certain circumstances create an extra GPT or two. Also if the same city has multiple trade routes going out to other cities in other civs, the code will count the number of such trade routes and apply the average bonus so that (average * number routes * percentage original gold) should end up being the correct total amount added, +/- rounding issues.
only apply to outgoing trade-routes, so the code only looks at outgoing trade-routes. Buildings (hidden or otherwise) with these columns will have no effect on incoming trade routes in any case.
The only thing I am not sure of with those two columns is whether or not they "stack" for multiple copies of the same building within the same city. I have never had a chance to verify one way or another. If the effect seems to refuse to "stack" then it will be necessary to change to a dummy building with a gold alteration in <Building_YieldChanges> instead of the two trade route goldbonus columns.
It works like a charm, thank you a million times over!
Though just one question; as you mentioned, the code only affects cities with outgoing trade routes. Is there a way to have it either cover all cities, regardless of trade routes? I tried changing:
Spoiler:
Code:
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local tTradeRoutes = Players[iPlayer]:GetTradeRoutes()
if #tTradeRoutes > 0 then
local iNumberMajorWars = NumberMajorWars(iPlayer)
if iNumberMajorWars >= 1 then
for pCity in pPlayer:Cities() do
NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tTradeRoutes, iNumberMajorWars)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
to
Spoiler:
Code:
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local tTradeRoutes = Players[iPlayer]:GetTradeRoutes()
[COLOR="Blue"]if #tTradeRoutes >= 0[/COLOR] then
local iNumberMajorWars = NumberMajorWars(iPlayer)
if iNumberMajorWars >= 1 then
for pCity in pPlayer:Cities() do
NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tTradeRoutes, iNumberMajorWars)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
Though just one question; as you mentioned, the code only affects cities with outgoing trade routes. Is there a way to have it either cover all cities, regardless of trade routes?
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local tTradeRoutes = Players[iPlayer]:GetTradeRoutes()
if #tTradeRoutes > 0 then
local iNumberMajorWars = NumberMajorWars(iPlayer)
if iNumberMajorWars >= 1 then
for pCity in pPlayer:Cities() do
NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tTradeRoutes, iNumberMajorWars)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
to
Spoiler:
Code:
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local tTradeRoutes = Players[iPlayer]:GetTradeRoutes()
[COLOR="Blue"]if #tTradeRoutes >= 0[/COLOR] then
local iNumberMajorWars = NumberMajorWars(iPlayer)
if iNumberMajorWars >= 1 then
for pCity in pPlayer:Cities() do
NumberCityTradeRoutesGoldBonusBuildings(iPlayer, pCity, tTradeRoutes, iNumberMajorWars)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
Yeah, that wouldn't have much of an effect, because
The number of trade routes the player has is always going to meet the condition ">= 0"
variable tTradeRoutes is actually an lua-table holding all the info for a particular player's trade routes
the command #tTradeRoutes is shorthand for getting how many items are held within lua-table tTradeRoutes, so in this case will give the total number of traderoutes the player has "active", and this is always going to be >= 0
The purpose for the line
Code:
if #tTradeRoutes > 0 then
and its matching "end" line farther down is to not require the rest of the code to run when Roanapur has no trade routes going anywhere.
the real magic for placing the dummy buildings in the player's cities is happening within function NumberCityTradeRoutesGoldBonusBuildings so any fundamental changes to the way the script works would really need to be done inside that function.
Well, the thing is that the extra trade route is only showing up when you already have a trade route running when a war breaks out.
Let's say you're playing as Roanapur, and it's still somewhat early in the game, so you don't have any outgoing trade routes going. So, when one civ declares on another, you don't get the extra trade route bonus. Then, if you have enough money to buy a cargo ship and a caravan in the same turn, you can't, since you aren't receiving the extra trade route you should.
It's an unlikely scenario, but not outside the realm of possibilities. Plus, people will probably see in their notifications "Genghis Khan has declares war on an unmet player", see that they don't have an additional trade route, and assume that the mod isn't working. Also, if you wanted to found a new trade route in a city that didn't have one previously, the extra gold income from the trait won't show up in the tooltip.
Are you talking about this column from table <Buildings> as well as the other two columns:<NumTradeRouteBonus> ?
The code as I wrote it gathers the total gold being yielded from the city's traderoutes, multiplies that by 10% for every war occuring anywhere between major players, and calculates a total "extra gold amount" for that city. This extra gold amount is then divided by the number of trade routes the city has, and the result is the number of buildings that have <TradeRouteLandGoldBonus>100</TradeRouteLandGoldBonus> which are added to the city. You can't using dummy buildings to get this effect individualize the effect for each individual trade route the city has, nor can you apply it to cities that do not already have a trade route. Remember that <TradeRouteLandGoldBonus> and its "Sea" twin are applied to all trade-routes originating in the city, and are direct gold amount additions instead of percentage modifiers -- it would be so much easier to do if they were percentage modifiers.
Plus, I am still not sure that further testing is not going to reveal that you get "creeping" upward calculations in that at 1st turn the trade route from city 1 yields 20 gold, so we add an additional +2 GPT (10% of 20) via the dummy buildings. Now the yield of the trade route is 22, so on the next turn we set a total of 3 buildings for +3 GPT (10% of 22 rounded up), which makes the yield of the trade route now 23, etc. This will be fixable once you have a better idea of whether or not this seems to be occuring.
Are you talking about this column from table <Buildings> as well as the other two columns:<NumTradeRouteBonus> ?
The code as I wrote it gathers the total gold being yielded from the city's traderoutes, multiplies that by 10% for every war occuring anywhere between major players, and calculates a total "extra gold amount" for that city. This extra gold amount is then divided by the number of trade routes the city has, and the result is the number of buildings that have <TradeRouteLandGoldBonus>100</TradeRouteLandGoldBonus> which are added to the city. You can't using dummy buildings to get this effect individualize the effect for each individual trade route the city has, nor can you apply it to cities that do not already have a trade route. Remember that <TradeRouteLandGoldBonus> and its "Sea" twin are applied to all trade-routes originating in the city, and are direct gold amount additions instead of percentage modifiers -- it would be so much easier to do if they were percentage modifiers.
Plus, I am still not sure that further testing is not going to reveal that you get "creeping" upward calculations in that at 1st turn the trade route from city 1 yields 20 gold, so we add an additional +2 GPT (10% of 20) via the dummy buildings. Now the yield of the trade route is 22, so on the next turn we set a total of 3 buildings for +3 GPT (10% of 22 rounded up), which makes the yield of the trade route now 23, etc. This will be fixable once you have a better idea of whether or not this seems to be occuring.
What code would be required in order to spawn in one copy of BUILDING_ROANAPUR_DUMMY1 in every city (regardless of whether or not they have trade routes running at the time), and BUILDING_ROANAPUR_DUMMY2 only in the capital, for every war that doesn't involve Roanapur?
I tried to figure out at least the first part on my own, using your
Spoiler:
Code:
function NumberMajorWars(iPlayer)
local iNumberMajorWars = 0
tTableOfWarringCivs = {}
for iMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if iMajPlayer ~= iPlayer then
local pMajorPlayer = Players[iMajPlayer]
if pMajorPlayer:IsAlive() then
local MajorPlayerTeam = pMajorPlayer:GetTeam()
for iOtherMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if (iOtherMajPlayer ~= iPlayer) and (iOtherMajPlayer ~= iMajPlayer) and (Players[iOtherMajPlayer]:IsAlive()) then
local OtherPlayerTeam = Players[iOtherMajPlayer]:GetTeam()
if (Teams[MajorPlayerTeam]:IsAtWar(OtherPlayerTeam)) then
local bWarStateRecorded = false
if tTableOfWarringCivs[iMajPlayer] == nil then
tTableOfWarringCivs[iMajPlayer] = {}
end
if not tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] then
tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] = "War"
bWarStateRecorded = true
iNumberMajorWars = iNumberMajorWars + 1
end
if tTableOfWarringCivs[iOtherMajPlayer] == nil then
tTableOfWarringCivs[iOtherMajPlayer] = {}
end
if not tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] then
tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] = "War"
if not bWarStateRecorded then
iNumberMajorWars = iNumberMajorWars + 1
end
end
end
end
end
end
end
end
return iNumberMajorWars
end
[/spoiler]
I worked out this much, which is likely horribly wrong:
Spoiler:
Code:
function BalalaikaGoldFromTradeRoutes(PlayerID)
local pPlayer = Players[PlayerID]
local pCiv = pPlayer:GetCivilizationType()
if pCiv == GameInfoTypes.CIVILIZATION_ROANAPUR then
for pCity in pPlayer:Cities() do
print(pCity:GetName())
local ExtraTradeRoute = false
??????
end
if ExtraTradeRoute == true then
if pCity:GetNumBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1) > 0 then
elseif (pCity:GetNumBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1) == 0 or pCity:GetNumBuilding(BUILDING_ROANAPUR_DUMMY1) == nil) then
pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1, iNumberMajorWars)
end
elseif (sExtraTradeRoute == false) or (ExtraTradeRoute == nil) then
if pCity:GetNumBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1) > 0 then
pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1, 0)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(BalalaikaGoldFromTradeRoutes)
I feel horrible that you spent all that time to come up with the Lua you gave me, when I couldn't accurately relay what it was I was looking for. I really do apologize for that.
What code would be required in order to spawn in one copy of BUILDING_ROANAPUR_DUMMY1 in every city (regardless of whether or not they have trade routes running at the time), and BUILDING_ROANAPUR_DUMMY2 only in the capital, for every war that doesn't involve Roanapur?
I tried to figure out at least the first part on my own, using your
Spoiler:
Code:
function NumberMajorWars(iPlayer)
local iNumberMajorWars = 0
tTableOfWarringCivs = {}
for iMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if iMajPlayer ~= iPlayer then
local pMajorPlayer = Players[iMajPlayer]
if pMajorPlayer:IsAlive() then
local MajorPlayerTeam = pMajorPlayer:GetTeam()
for iOtherMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if (iOtherMajPlayer ~= iPlayer) and (iOtherMajPlayer ~= iMajPlayer) and (Players[iOtherMajPlayer]:IsAlive()) then
local OtherPlayerTeam = Players[iOtherMajPlayer]:GetTeam()
if (Teams[MajorPlayerTeam]:IsAtWar(OtherPlayerTeam)) then
local bWarStateRecorded = false
if tTableOfWarringCivs[iMajPlayer] == nil then
tTableOfWarringCivs[iMajPlayer] = {}
end
if not tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] then
tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] = "War"
bWarStateRecorded = true
iNumberMajorWars = iNumberMajorWars + 1
end
if tTableOfWarringCivs[iOtherMajPlayer] == nil then
tTableOfWarringCivs[iOtherMajPlayer] = {}
end
if not tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] then
tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] = "War"
if not bWarStateRecorded then
iNumberMajorWars = iNumberMajorWars + 1
end
end
end
end
end
end
end
end
return iNumberMajorWars
end
[/spoiler]
I worked out this much, which is likely horribly wrong:
Spoiler:
Code:
function BalalaikaGoldFromTradeRoutes(PlayerID)
local pPlayer = Players[PlayerID]
local pCiv = pPlayer:GetCivilizationType()
if pCiv == GameInfoTypes.CIVILIZATION_ROANAPUR then
for pCity in pPlayer:Cities() do
print(pCity:GetName())
local ExtraTradeRoute = false
??????
end
if ExtraTradeRoute == true then
if pCity:GetNumBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1) > 0 then
elseif (pCity:GetNumBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1) == 0 or pCity:GetNumBuilding(BUILDING_ROANAPUR_DUMMY1) == nil) then
pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1, iNumberMajorWars)
end
elseif (sExtraTradeRoute == false) or (ExtraTradeRoute == nil) then
if pCity:GetNumBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1) > 0 then
pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_ROANAPUR_DUMMY1, 0)
end
end
end
end
end
GameEvents.PlayerDoTurn.Add(BalalaikaGoldFromTradeRoutes)
I feel horrible that you spent all that time to come up with the Lua you gave me, when I couldn't accurately relay what it was I was looking for. I really do apologize for that.
I can re-write. It won't be too much a big deal since half or more of the previous code will still be directly usable. Real Life and OtherIronsCreatingFires may cause it to require a couple+ hours to make the re-draft, just depending on how big the flames rise from the other Fires and that irksome Real Life stuff.
Given clearer understanding of what you want I think I can tie the code into the "WarStateChanged" event rather than only the PlayerDoTurn to make things adjust in real-time when war or peace break out. Probably will write it so that PlayerDoTurn also runs the code in order to "cure" any missed issues from changes in conditions that might not have been caught -- have to think that through tho.
Players may freak out when the number of available trade routes suddenly drops when two warring civs make peace, tho. So you'll have to be clear on your mod description that when peace breaks out, they will lose one of their trade routes, and this may cause them to not be able to finish or start on that Cargo Ship or Caravan they were planning on using.
local iCivilizationRoanapur = GameInfoTypes.CIVILIZATION_ROANAPUR
local iBuildingGoldBonus = GameInfoTypes.BUILDING_ROANAPUR_DUMMY1 --added to every city in the same quantity as wars currently occuring that do not involve ROANAPUR
local iBuildingTradeRouteExtras = GameInfoTypes.BUILDING_ROANAPUR_DUMMY2 --added to capital city in the same quantity as wars currently occuring that do not involve ROANAPUR
function NumberMajorWars(iPlayer)
local iNumberMajorWars = 0
tTableOfWarringCivs = {}
for iMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if iMajPlayer ~= iPlayer then
local pMajorPlayer = Players[iMajPlayer]
if pMajorPlayer:IsAlive() then
local MajorPlayerTeam = pMajorPlayer:GetTeam()
for iOtherMajPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1 do
if (iOtherMajPlayer ~= iPlayer) and (iOtherMajPlayer ~= iMajPlayer) and (Players[iOtherMajPlayer]:IsAlive()) then
local OtherPlayerTeam = Players[iOtherMajPlayer]:GetTeam()
if (Teams[MajorPlayerTeam]:IsAtWar(OtherPlayerTeam)) then
local bWarStateRecorded = false
if tTableOfWarringCivs[iMajPlayer] == nil then
tTableOfWarringCivs[iMajPlayer] = {}
end
if not tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] then
tTableOfWarringCivs[iMajPlayer][iOtherMajPlayer] = "War"
bWarStateRecorded = true
iNumberMajorWars = iNumberMajorWars + 1
end
if tTableOfWarringCivs[iOtherMajPlayer] == nil then
tTableOfWarringCivs[iOtherMajPlayer] = {}
end
if not tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] then
tTableOfWarringCivs[iOtherMajPlayer][iMajPlayer] = "War"
if not bWarStateRecorded then
iNumberMajorWars = iNumberMajorWars + 1
end
end
end
end
end
end
end
end
return iNumberMajorWars
end
function WarOrPeaceDeclared(iTeamOneID, iTeamTwoID)
local pTeamOne, pTeamTwo = Teams[iTeamOneID], Teams[iTeamTwoID]
if pTeamOne:IsBarbarian() or pTeamTwo:IsBarbarian() then return end
if pTeamOne:IsMinorCiv() or pTeamTwo:IsMinorCiv() then return end
local iRoanapurPlayerID, iPlayerOneID, iPlayerTwoID
for iPlayer = 0, GameDefines.MAX_MAJOR_CIVS - 1, 1 do
if (Players[iPlayer] ~= nil) then
if Players[iPlayer]:GetCivilizationType() == iCivilizationRoanapur then
iRoanapurPlayerID = iPlayer
elseif (Players[iPlayer]:GetTeam() == iTeamOneID) then
iPlayerOneID = iPlayer
elseif (Players[iPlayer]:GetTeam() == iTeamTwoID) then
iPlayerTwoID = iPlayer
end
end
end
if iRoanapurPlayerID ~= nil then
if (iRoanapurPlayerID == iPlayerOneID) or (iRoanapurPlayerID == iPlayerTwoID) then
return
else
RoanapurTradeRouteBonuses(iRoanapurPlayerID)
end
end
end
function RoanapurTradeRouteBonuses(iPlayer)
local pPlayer = Players[iPlayer]
if pPlayer:GetCivilizationType() == iCivilizationRoanapur then
local iNumberMajorWars = NumberMajorWars(iPlayer)
for pCity in pPlayer:Cities() do
if pCity:IsCapital() then
pCity:SetNumRealBuilding(iBuildingTradeRouteExtras, iNumberMajorWars)
end
pCity:SetNumRealBuilding(iBuildingGoldBonus, iNumberMajorWars)
end
end
end
GameEvents.PlayerDoTurn.Add(RoanapurTradeRouteBonuses)
Events.WarStateChanged.Add(WarOrPeaceDeclared)
I added a hook for the WarStateChanged event to try to make the code more real-time-reactive
If left the hook into the turn processing PlayerDoTurn because this should act as extra insurance that everything gets 'corrected' if my understanding of how and when the WarStateChanged event fires is faulty.
As mentioned in the previous version I haven't had a chance to test it, so if it is buggy in some way because I overlooked something, you'll have to let me know and I'll set it up and run it in test-mode on my end. Though I think if there is a bug it might be better to start a thread specific to this rather than bloating and blockading the general lua-request thread more than we already have.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.