C++/Lua Request Thread

Chiphead, you could implement that with a "PlayerCanConstruct" restriction.
 
Thanks for the pointer, Machiavelli24. So it seems I'm looking at a function that goes through all cities and checks for Building1 OR Building2 that enables building the Wonder. Also, searching around seems to tell me PlayerCanConstruct doesn't give a tooltip like other National Wonders ("x buildings missing" or "missing in City1, City2"), so still wondering if there's a way to implement that a bit more like the original game.
 
So, there's something I want to do, but don't really know how to... I need to detect when a new luxury resoure has been connected to a civilization. When I say new I mean a resource that has never before being connected to said civ.

I suppose it'd require SaveUtils or something, but I still don't know how to use those well, so if anyone can figure it out I will be truly grateful.
 
I already wrote the lua you needed and posted it in your thread like last week:

Spoiler :
Code:
local sCitizen = GameInfo.Specialists.SPECIALIST_CITIZEN.ID;
local bDummy = GameInfoTypes.BUILDING_WHATEVER;

GameEvents.PlayerDoTurn.Add(
function(iPlayer)
	local pPlayer = Players[iPlayer];
	if (pPlayer:IsAlive()) then
		if (pPlayer:GetCivilizationType() == GameInfoTypes.WHATEVER) then -- or Whatever your trigger is
			for pCity in pPlayer:Cities() do
				local cCitizen = pCity:GetSpecialistCount(sCitizen);
				pCity:SetNumRealBuilding(bDummy, cCitizen );
			end
		end
	end
end)
All you had to do was make a dummy building that provides +2 food. With that code (no changes needed) it would have added 1 dummy building for every unemployed specialist in the city. (So if you had 8 unemployed specialists, it would have added 8 of the dummy building, so 16 food, remove one, 7, the city produces 14. If you want it to also give happiness, make that dummy building also give happiness). The only exception is tourism since that one counts once per building class and not type.

My bad, that code was indeed all I could ever want now that I got it working, sorry about that. For once the code was fine, but Modbuddy wasn't, everything's fine since the reinstall.

The only thing left to figure out now is whether or not it is possible for the Lua to instantly react. As it stands now there is a 1 turn delay on dummies, whereas specialists can be reassigned multiple times a turn. Is this actually possible to do at all, or have modders been forced to deal with it since forever?
 
So, there's something I want to do, but don't really know how to... I need to detect when a new luxury resoure has been connected to a civilization. When I say new I mean a resource that has never before being connected to said civ.

I suppose it'd require SaveUtils or something, but I still don't know how to use those well, so if anyone can figure it out I will be truly grateful.


Probably easiest to do this on a PlayerDoTurn, once the resource is connected, do whatever code.

I've never used SaveUtils; I always use Pazyryk's TableSaverLoader -- instructions how to implement it are in that thread. If you use that, it's as simple as making a sub-table in the gT, like gT.PreviouslyConnectedResources, and then set gT.PreviouslyConnectedResources[iPlayer] = iResourceID. Then have your code check to see if that is present in the table before executing the code.



The only thing left to figure out now is whether or not it is possible for the Lua to instantly react. As it stands now there is a 1 turn delay on dummies, whereas specialists can be reassigned multiple times a turn. Is this actually possible to do at all, or have modders been forced to deal with it since forever?

Use Events.SerialEventCityInfoDirty.Add(YourFunction). This will trigger the function whenever a City's information, such as what buildings it has, what population it has, what tiles it's working, etc., changes.
 
Hi there,

Could I get a code for a UA that adds 1% of Gold reserves to global Gold and Culture per turn? I don't think I can do it by editing XML files.
 
You can't set tourism dynamically through lua as far as I know...

You can use the following:

Code:
<EnhancedYieldTech>TECH_AGRICULTURE</EnhancedYieldTech>
			<TechEnhancedTourism>1</TechEnhancedTourism>

To give a building 1 Tourism. (It doesn't stack with the same building type though; so you may need more than one dummy building)
 
You can't set tourism dynamically through lua as far as I know...

You can't. It's because internally Tourism doesn't accumulate against the player turn-on-turn (like science, gold and culture do) but it accumulates against each other major that player has met turn-on-turn. So pPlayer:ChangeTourism(10) makes no sense - well it does to you and me, but it doesn't the way it's coded internally.
 
With respect to dynamically adding tourism via lua, has anyone investigated or implemented the following (convoluted) approach?

1) Create a new policy branch that can not be adopted (blocked via PlayerCanAdoptPolicyBranch)
2) Add a policy under this branch that provides Policy_TourismOnUnitCreation for an unbuildable unit.
3) Use Lua to give the player this policy, spawn X copies of the unit, killing the unit right after spawning it, then removing the policy from the player.

If there are effects which trigger on policy adoption than this approach is going to mess up a few things.
 
Couldn't you use FreeGreatWork (used by the Parthenon) to give your dummy building a dummy great work?

I can think of a number of problems with that
It doesn't work :(

You can't set tourism dynamically through lua as far as I know...

You can use the following:

Code:
<EnhancedYieldTech>TECH_AGRICULTURE</EnhancedYieldTech>
			<TechEnhancedTourism>1</TechEnhancedTourism>

To give a building 1 Tourism. (It doesn't stack with the same building type though; so you may need more than one dummy building)

<EnchancedYieldTech> isn't necessary, while at the same time <TechEnhancedTourism> is only checked for once per building class. If one dummy gives +1:tourism:, six dummies will also give +1.

With respect to dynamically adding tourism via lua, has anyone investigated or implemented the following (convoluted) approach?

1) Create a new policy branch that can not be adopted (blocked via PlayerCanAdoptPolicyBranch)
2) Add a policy under this branch that provides Policy_TourismOnUnitCreation for an unbuildable unit.
3) Use Lua to give the player this policy, spawn X copies of the unit, killing the unit right after spawning it, then removing the policy from the player.

If there are effects which trigger on policy adoption than this approach is going to mess up a few things.

Something like futurism from autocracy? I could see that happening.

If it doesn't work I'll just have to make twenty different dummy building classes, each called [BONUS FROM X UNEMPLOYED CITIZENS] since I can't make them invisible. Oh well.
 
If one dummy gives +1:tourism:, six dummies will also give +1.

Pretty much what I meant with not stacking :p ...

Anyway, using Futurism is an interesting idea. The only issue with it is that it doesn't apply Tourism modifiers for each civ, it just gives a direct amount of Tourism against all. Still useful.
 
Hi everyone! I just started trying out modding Civ-5 a few days ago and already have a functioning XML based mod for a new civilization. Fresh off of my success I thought I might try something a little more complicated for my second Civ and try using some Lua... which may have been a mistake as i cant wrap my head around it at all :crazyeye:.

I am trying to create a lua script which changes the combat strength of a faction specific unit, either by era or specific technology. If it is at all possible i would like to do it without creating a set of dummy promotions (as seen in the excellent Chola Civ mod from the Indian Subcontinent pack).

Here is the (mess of) code i am currently trying to use. I'm not going to lie, its an ugly mess, hacked together from other scripts which do (almost) what i want them to. Could i implore someone with a bit more experience to have a quick look at my little abomination and perhaps fix it up for me? (Or throw it out and build a new one).


Spoiler :
Code:
local HeroOfMan = GameInfoTypes["UNIT_HERO_OF_MAN"].ID

local BGLevel1Prereq = GameInfo.Technologies["TECH_STEEL"].ID
local BGLevel2Prereq = GameInfo.Technologies["TECH_GUNPOWDER"].ID
local BGLevel3Prereq = GameInfo.Technologies["TECH_RIFLING"].ID
local BGLevel4Prereq = GameInfo.Technologies["TECH_REPLACEABLE_PARTS"].ID
local BGLevel5Prereq = GameInfo.Technologies["TECH_PLASTICS"].ID
local BGLevel6Prereq = GameInfo.Technologies["TECH_MOBILE_TACTICS"].ID

local BGLevel1Combat = 23
local BGLevel2Combat = 26
local BGLevel3Combat = 37
local BGLevel4Combat = 55
local BGLevel5Combat = 77
local BGLevel6Combat = 132

function NorthHero(iPlayer)
	for _, pPlayer in pairs(Players) do
	local teamID = pPlayer:GetTeam();
	local pTeam = Teams[teamID];
	if (pPlayer:IsAlive()) then
			if (pTeam:IsHasTech(BGLevel1Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel1Combat then 
						bgunit:SetBaseCombatStrength(BGLevel1Combat)
						print ("A Hero of the North Level 1 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel2Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel2Combat then
						bgunit:SetBaseCombatStrength(BGLevel2Combat)
						print ("A Hero of the North Level 2 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel3Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel3Combat then
						bgunit:SetBaseCombatStrength(BGLevel3Combat)
						print ("A Hero of the North Level 3 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel4Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel4Combat then
						bgunit:SetBaseCombatStrength(BGLevel4Combat)
						print ("A Hero of the North Level 4 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel5Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel5Combat then
						bgunit:SetBaseCombatStrength(BGLevel5Combat)
						print ("A Hero of the North Level 5 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel6Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel6Combat then
						bgunit:SetBaseCombatStrength(BGLevel6Combat)
						print ("A Hero of the North Level 6 is here!");
						end
					end
				end
			end
	end
	end
end

GameEvents.PlayerAdoptPolicy.Add(NorthHero);
GameEvents.PlayerDoTurn.Add(NorthHero);

I would be grateful for any help, and of course credit will be given in the mod.
 
Hi everyone! I just started trying out modding Civ-5 a few days ago and already have a functioning XML based mod for a new civilization. Fresh off of my success I thought I might try something a little more complicated for my second Civ and try using some Lua... which may have been a mistake as i cant wrap my head around it at all :crazyeye:.

I am trying to create a lua script which changes the combat strength of a faction specific unit, either by era or specific technology. If it is at all possible i would like to do it without creating a set of dummy promotions (as seen in the excellent Chola Civ mod from the Indian Subcontinent pack).

Here is the (mess of) code i am currently trying to use. I'm not going to lie, its an ugly mess, hacked together from other scripts which do (almost) what i want them to. Could i implore someone with a bit more experience to have a quick look at my little abomination and perhaps fix it up for me? (Or throw it out and build a new one).


Spoiler :
Code:
local HeroOfMan = GameInfoTypes["UNIT_HERO_OF_MAN"].ID

local BGLevel1Prereq = GameInfo.Technologies["TECH_STEEL"].ID
local BGLevel2Prereq = GameInfo.Technologies["TECH_GUNPOWDER"].ID
local BGLevel3Prereq = GameInfo.Technologies["TECH_RIFLING"].ID
local BGLevel4Prereq = GameInfo.Technologies["TECH_REPLACEABLE_PARTS"].ID
local BGLevel5Prereq = GameInfo.Technologies["TECH_PLASTICS"].ID
local BGLevel6Prereq = GameInfo.Technologies["TECH_MOBILE_TACTICS"].ID

local BGLevel1Combat = 23
local BGLevel2Combat = 26
local BGLevel3Combat = 37
local BGLevel4Combat = 55
local BGLevel5Combat = 77
local BGLevel6Combat = 132

function NorthHero(iPlayer)
	for _, pPlayer in pairs(Players) do
	local teamID = pPlayer:GetTeam();
	local pTeam = Teams[teamID];
	if (pPlayer:IsAlive()) then
			if (pTeam:IsHasTech(BGLevel1Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel1Combat then 
						bgunit:SetBaseCombatStrength(BGLevel1Combat)
						print ("A Hero of the North Level 1 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel2Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel2Combat then
						bgunit:SetBaseCombatStrength(BGLevel2Combat)
						print ("A Hero of the North Level 2 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel3Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel3Combat then
						bgunit:SetBaseCombatStrength(BGLevel3Combat)
						print ("A Hero of the North Level 3 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel4Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel4Combat then
						bgunit:SetBaseCombatStrength(BGLevel4Combat)
						print ("A Hero of the North Level 4 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel5Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel5Combat then
						bgunit:SetBaseCombatStrength(BGLevel5Combat)
						print ("A Hero of the North Level 5 is here!");
						end
					end
				end
			end
			if (pTeam:IsHasTech(BGLevel6Prereq)) then
				for bgunit in pPlayer:Units() do
					if (bgunit:GetUnitType().ID == HeroOfMan) then
					if (bgunit:GetBaseCombatStrength() < BGLevel6Combat then
						bgunit:SetBaseCombatStrength(BGLevel6Combat)
						print ("A Hero of the North Level 6 is here!");
						end
					end
				end
			end
	end
	end
end

GameEvents.PlayerAdoptPolicy.Add(NorthHero);
GameEvents.PlayerDoTurn.Add(NorthHero);

I would be grateful for any help, and of course credit will be given in the mod.

Edit: Also it appears that i have accidentally deleted the credit for the original hacked lua. Credit for the orginal script goes to sukritact and Leugi.
 
Hello, firstable can somebody say to me if is possible to redefine toupper function for few characters? Instead of &#940; > &#902;, &#941; > &#904;, &#974; > &#911;, to &#940; > &#913;, &#941; > &#917;, &#974; > &#937;...?

And secondary how to change lua code, that it would enable using forms from XML files? For example
<Row Tag="TXT_KEY_PROCESSING_TURN_FOR">
<Text>Processing Turn For {1_CivilizationName[2]}</Text>
</Row>
<Row Tag="TXT_KEY_CIV_AMERICA_SHORT_DESC">
<Text>Amerika|Ameriky</Text>
<Gender>neuter:an</Gender>
</Row>
Needed word "Ameriky" but it gives only 1st form. In most cases it supports forms like in notifications, logs and so on, but in few cases not. How to make it work?
 
city:ChangeResistanceTurns(int) will handle the first part. Detecting when a building is sold will be tricky. Short of modding the DLL the closest you can get is storing which cities have the building and searching each turn to see if those cities no longer have the building. However, unless you make the building nuke immune than having it destroyed by a nuke would trigger resistance (there are some ways to get around this but they would make the logic more complex).
 
Edit: Also it appears that i have accidentally deleted the credit for the original hacked lua. Credit for the orginal script goes to sukritact and Leugi.

Try this

Spoiler :
--------------------------------------------------------------

function updateHeroesCombatStrength()
--local pPlayer = Players[ Game.GetActivePlayer() ]
for i,player in pairs(Players) do
local combat_str = 10--(10*player:GetCurrentEra())+10
if (player:GetCurrentEra()==GameInfoTypes.ERA_PREHISTORIC) then combat_str = 7
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_ANCIENT) then combat_str = 9
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_CLASSICAL) then combat_str = 13
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_MEDIEVAL) then combat_str = 18
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_RENAISSANCE) then combat_str = 25
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_INDUSTRIAL) then combat_str = 34
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_MODERN) then combat_str = 60
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_POSTMODERN) then combat_str = 70
elseif (player:GetCurrentEra()==GameInfoTypes.ERA_FUTURE) then combat_str = 120
else combat_str = 10 end

for unit in player:Units() do
local iUnit = unit:GetID();
if (unit:GetUnitType()==GameInfoTypes.UNIT_GREAT_GENERAL) then
unit:SetBaseCombatStrength(combat_str)
end
end

end
end

Events.ActivePlayerTurnStart.Add(updateHeroesCombatStrength)
Events.SerialEventEraChanged.Add(updateHeroesCombatStrength)
Events.SerialEventUnitCreated.Add(updateHeroesCombatStrength)
print("Heros!")


It changes the strength per era, in that case for the great general.
 
Thank you Gilgamesch I shall give that a try later this evening, when i have the time. I'm grateful that you took the time to help me :).

EDIT: Just tested it, and it works flawlessly. A simple tweak to the unit name and it now only updates the combat strength of the unique unit i was making. Thank you Gilgamesch, you are a gentleman and a scholar. Is there an easy way to do it with specific technologies or is that significantly more complicated?
 
Back
Top Bottom