C++/Lua Request Thread

pPlot:SetOwner() requires (at least) two parameters - owning player AND owning city, so it should be plot:SetOwner(iPlayer, pCity:GetID())
 
In an attempt to break the state of purgatory that a few of my mods have been stuck in, I attempted to play Frankenstein with some scattered, existing lua codes, and failed spectacularly. Could someone please help fix these abominations I've created? The first one, for my Yucatan civ's effect of "+5% Military Unit Production for each worked Plantation" is a bit of a combination of code from CL's Dene and Leugi's Tropico/my American Wonders, and doesn't work. The squeamish may want to avert their eyes:
Spoiler :
Code:
-- PlantationMilitary
-- Author: Sasquatch
-- DateCreated: 7/17/2014 1:13:31 AM
--------------------------------------------------------------

local Yucaunit = "BUILDING_YUCAUNIT"


function FindYucatanPlantations(PlayerID)
	local pPlayer = Players[PlayerID]
	if pPlayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_YUCATAN then
		for pCity in pPlayer:Cities() do
			local pTeam = Teams[pPlayer:GetTeam()]
			for pCityPlot = 0, pCity:GetNumCityPlots() - 1, 1 do
				local pSpecificPlot = pCity:GetCityIndexPlot(pCityPlot)
				if pSpecificPlot ~= nil then
					if pSpecificPlot:GetOwner() == pCity:GetOwner() then
						if pSpecificPlot:GetImprovementType() == GameInfoTypes.IMPROVEMENT_PLANTATION then
							if pCity:IsWorkingPlot(pSpecificPlot) then
									pCity:SetNumRealBuilding(GameInfoTypes["" .. Yucaunit .. ""], 1)
								end
							end
						end
					end
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(FindYucatanPlantations)

And the second one is an attempt at my desired "During Golden Ages, all tiles that yield at least 1 Gold also yield +1 Science" for California. I dunno how, even in theory, to add that yield to the likes of tile improvements in the middle of a Californian Golden Age (granting and taking away a hidden policy or something during Golden Ages?), so the effect is currently relying upon granting a hidden building that just increases the yields of all gold-yielding resources. I took the code from a script that would grant a building to the Capital during a civ's golden age, and of course, failed to make it apply to all cities:

Spoiler :
Code:
-- CaliforniasGoldAge
-- Author: JFD + LeeS
-- DateCreated: 6/30/2014 3:49:26 PM
--------------------------------------------------------------

GameEvents.PlayerDoTurn.Add(function(iPlayer)
local pPlayer = Players[iPlayer];
	if pPlayer:GetCivilizationType() == GameInfoTypes["CIVILIZATION_CALIFORNIA"] then
		for pCity in pPlayer:Cities() do
				if pPlayer:IsGoldenAge() then
					if not pCity:IsHasBuilding(GameInfoTypes.BUILDING_CALIFORNIAGOLDAGE) then
						pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_CALIFORNIAGOLDAGE, 1);
					end
				else
					if pCity:IsHasBuilding(GameInfoTypes.BUILDING_CALIFORNIAGOLDAGE) then
						pCity:SetNumRealBuilding(GameInfoTypes.BUILDING_CALIFORNIAGOLDAGE, 0);
					end
				end
			end
		end
	end
end)
Anyone who can attempt to rescue me with these is a true hero, and I thank them in advance.
 
pPlot:SetOwner() requires (at least) two parameters - owning player AND owning city, so it should be plot:SetOwner(iPlayer, pCity:GetID())

So if i understand you correctly, i just added the tiles to the civilization, rather then the city?

If so, the effect is almost identical (So long as there are no other cities from the same civilization in the vicinity).


Another lua request: Is it possible to script a function to distinguish between 2 diffrent units founding a city (say, to check if a city was founded by a conquistador or by a settler)?
 
pUnit:Found() and consequently the PlayerCityFounded event, is called before pUnit:Kill() so the founding unit will still be on the plot when the event is called. If you happened to have both a Conquistador and a Settler on the plot there would be no easy way to differentiate between them
 
Well actually i am going to try making an advanced settler using lua. So this wont be a problem : D
I wanted to make this kind of unit for almost a year now, and asking about it around the forum is how i got refered to you guys "Community patch" a few days ago (Which has amazing stuff in it tbh).

Anyway, i was under the impression that when the PlayerCityFounded event was being called, the units will have already been destroyed.
I was planning to use "GameEvents.UnitSetXY" (which is being called every time a unit moves) to save a table of locations for colonists, and after a city has been founded to check if a colonist was on that tile at the time.

So now i only need to get a list of units in the plot, and then check if one of them is a colonist. I will update as soon as i make it work, but if someone see's this before, I'd appreaciate help! (wink wink wHoward)


EDIT: I was able to get most of it working relatively easy (thanks wHoward for the tip).

However i only check if one of the first 2 units in the tile is a Colonist, making the mod incompatible with mods that allow for more units in one tile.

Can anyone tell me how to make a loop to check every unit in the tile?
The relevant part of my current code:


Spoiler :
local pUnit0 = pPlot:GetUnit(0);
local pUnit1 = pPlot:GetUnit(1);

if (pUnit0:GetUnitType() == GameInfoTypes["UNIT_COLONIST"]) or (pUnit1:GetUnitType() == GameInfoTypes["UNIT_COLONIST"]) then
(...)
 
Can anyone tell me how to make a loop to check every unit in the tile?
Code:
local iNumUnits = pPlot:GetNumUnits();
local pUnit;
							
-- Loop through all Units
for i = 0, iNumUnits do
	pUnit = pPlot:GetUnit(i);
	if (pUnit:GetUnitType() == GameInfoTypes["UNIT_COLONIST"]) then
(...)
 
Solved! - syntax was wrong. needed to use plot:SetOwner(iPlayer, pCity) (and not pPlayer)

Help! This code is supposed to add free tiles to a civ when founding a city with a colonist, however it always adds the tiles to the player!

However even trying to add just one tile to any city upon founding, it always adds the tiles to the human:

function OnCityFounded(iPlayer, iCityX, iCityY)
local pPlayer = Players[iPlayer];
if (pPlayer == nil) then return; end

local pPlot = Map.GetPlot(iCityX, iCityY);
if (pPlot == nil) then return; end

local pCity = pPlot:GetPlotCity();
if (pCity == nil) then return; end

local plot = pCity:GetNextBuyablePlot();
plot:SetOwner(pPlayer, pCity);

(...)
GameEvents.PlayerCityFounded.Add( OnCityFounded );



The complete code:
Spoiler :
function OnCityFounded(iPlayer, iCityX, iCityY)
local pPlayer = Players[iPlayer];
if (pPlayer == nil) then return; end
local pPlot = Map.GetPlot(iCityX, iCityY);
if (pPlot == nil) then return; end
(...)
IsColonist(pPlayer , pPlot); end


function IsColonist(pPlayer , pPlot)
(...) //if its a colonist settling the city
AddTerritory(pPlayer , pCity, 3);



function AddTerritory(lordOfTheLand , pCity, freePlots)


for i = 1, freePlots do
local plot = pCity:GetNextBuyablePlot();
plot:SetOwner(lordOfTheLand, pCity);
end
end
 
Can I get some guidance on how to implement this UA?

Unique Ability: Migrant Labor - Receive Production from incoming Trade Routes. Receive +1 Tourism for each 200 Gold in the Treasury.

My current, half-complete and non-functioning build is based on Tomatekh's Mali and JFD's Chruchill. Use this link: https://www.dropbox.com/s/jfxxv4bum6kub48/UAE (v 1).civ5mod
 
Hello fellow modders. I'm at my wits end when it comes to Lua and won't be able to do any of this without help.
I'm trying to work around unemployed citizens, known as SPECIALIST_CITIZEN in XML files, and DEFAULT_SPECIALIST in the DLL. They are hard coded in the DLL and cannot receive updates to their yields. All we can do is count them and let buildings/dummies do the yielding. Here's what I'm after.


+2:c5food: from unemployed citizens
Would it be possible to have one building do this? Have a single special building output +16:c5food: if there are 8 unemployed citizens, and go down to 14 as soon as you remove one of them? Can invisible food be avoided, or can I at least have dynamic tooltips show +2*[Number of unemployed citizens][Food] ?

Hard mode
+1:tourism: or +1:c5happy: from unemployed citizens
Same as above, only tourism and happiness are of course much harder to work with than actual yields.


Any help would be greatly appreciated. I'm looking forward to dissect and learn anything you throw at me.
 
UltimatePotato, +2 food from unemployed citizens should be easy. Use:
Code:
<Building_SpecialistYieldChanges>
  <Row>
    <BuildingType>BUILDING_XXX</BuildingType>
    <SpecialistType>SPECIALIST_CITIZEN</SpecialistType>
    <YieldType>YIELD_FOOD</YieldType>
    <Yield>2</Yield>
  </Row>
</Building_SpecialistYieldChanges>
Ensure the player only has one copy of the building at a time (the effect is global across the player's empire).

As for happiness and tourism, that will be much trickier.
 
UltimatePotato, +2 food from unemployed citizens should be easy. Use:
Spoiler :
Code:
<Building_SpecialistYieldChanges>
  <Row>
    <BuildingType>BUILDING_XXX</BuildingType>
    <SpecialistType>SPECIALIST_CITIZEN</SpecialistType>
    <YieldType>YIELD_FOOD</YieldType>
    <Yield>2</Yield>
  </Row>
</Building_SpecialistYieldChanges>
Ensure the player only has one copy of the building at a time (the effect is global across the player's empire).

As for happiness and tourism, that will be much trickier.

If only it was that easy :(
SPECIALIST_CITIZEN is hardcoded to ignore updates. This is why they don't benefit from secularism, Korea's UA or the statue of liberty. It's possible to set their base yield, but that will affect every civilization simultaneously.

How about something like this.
Building XXX
+:c5production: equal to the number of citizens in this city
It should be simpler (though still impossible for me :hammer2: ). What would the Lua file look like, and how would the building XML reference it. That's really all I need to get started.
 
Building XXX
+ :c5production: equal to the number of citizens in this city
It should be simpler (though still impossible for me :hammer2: ). What would the Lua file look like, and how would the building XML reference it. That's really all I need to get started.

If you mean all population in the city, not just SPECIALIST_CITIZEN, it's very simple and doesn't require Lua at all - just use the Building_YieldChangesPerPop table:
Code:
	<Building_YieldChangesPerPop>
		<Row>
			<BuildingType>BUILDING_XXX</BuildingType>
			<YieldType>YIELD_PRODUCTION</YieldType>
			<Yield>100</Yield>
		</Row>
	</Building_YieldChangesPerPop>

(100 means 1 production per citizen, you can adjust this value to get fractional amounts)
 
If you mean all population in the city, not just SPECIALIST_CITIZEN, it's very simple and doesn't require Lua at all - just use the Building_YieldChangesPerPop table:
Code:
	<Building_YieldChangesPerPop>
		<Row>
			<BuildingType>BUILDING_XXX</BuildingType>
			<YieldType>YIELD_PRODUCTION</YieldType>
			<Yield>100</Yield>
		</Row>
	</Building_YieldChangesPerPop>

(100 means 1 production per citizen, you can adjust this value to get fractional amounts)

Hm, that was a lot easier than I thought. How would I do it if I was strictly looking to solve this through Lua though?
Once I have a code that gives 1 production for every citizen, I should be able to replace [count.citizens] with [count.specialist_citizens], and hopefully [+production] with [+tourism or +happiness]
 
I'm currently working on a religious-belief modpack, and plan to add beliefs with the following effects. How much Lua scripting would these require?

  1. Follower belief: A "Missionary Ship" unit, able to spread religion to cities (and city-states) at a defined distance. (Ever lost one Missionary too many at sea, or had no good place to disembark one?)
  2. Reformation belief: A small global Culture bonus (say 2%) for each belief-linked building in cities controlled by the player. I'd probably need a cap on this bonus, too, so that Cultural Victory hounds don't spam their map with 20-odd cities and put a Monastery in each one.)
  3. Reformation belief: Allowing Monasteries to produce some random luxury resources normally associated with city-states -- one selected resource for each player who adopts the belief. Some real-life orders did support themselves by producing trade goods (Benedictine liqueur, Muenster cheese, and so forth), so allowing it in Civ5 makes "game sense".


If any of those call for a more complicated script than I could figure out from the modding wiki, could someone please help me with the code? Thank you so much!
 
Hello fellow modders. I'm at my wits end when it comes to Lua and won't be able to do any of this without help.
I'm trying to work around unemployed citizens, known as SPECIALIST_CITIZEN in XML files, and DEFAULT_SPECIALIST in the DLL. They are hard coded in the DLL and cannot receive updates to their yields. All we can do is count them and let buildings/dummies do the yielding. Here's what I'm after.

Would it be possible to have one building do this? Have a single special building output +16:c5food: if there are 8 unemployed citizens, and go down to 14 as soon as you remove one of them? [Food]

I already wrote the lua you needed and posted it in your thread like last week:

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.
 
I'm assuming this needs some Lua, but am really hoping that it doesn't need a DLL mod since it's for a one-civ mod: How to make a building give +1 :c5culture: Culture for every mountain inside your territory? However this should not stack (so if I have two of this building, I will still get +1 :c5culture: Culture per mountain), so maybe a function to check if one of that kind of building exists, and if so then all mountains yield +1 :c5culture: Culture, then make mountains stop giving the bonus if for any reason there are none of that building in the empire?
Thanks
 
I'm assuming this needs some Lua, but am really hoping that it doesn't need a DLL mod since it's for a one-civ mod: How to make a building give +1 :c5culture: Culture for every mountain inside your territory? However this should not stack (so if I have two of this building, I will still get +1 :c5culture: Culture per mountain), so maybe a function to check if one of that kind of building exists, and if so then all mountains yield +1 :c5culture: Culture, then make mountains stop giving the bonus if for any reason there are none of that building in the empire?
Thanks

For my Moriya shrine civ, Vicevirtuoso gave me this bit of code I adapted to have Mountains generate Science and Faith through dummy buildings:

Code:
iCiv = GameInfoTypes.CIVILIZATION_YOURCIV
iDummy = GameInfoTypes.BUILDING_YOURDUMMYBUILDING
iFeature = GameInfoTypes.FEATURE_MOUNTAIN

function YieldFromFeature(iPlayer)
	if iPlayer < GameDefines.MAX_MAJOR_CIVS then
		local pPlayer = Players[iPlayer]
		if pPlayer:GetCivilizationType() == iCiv then
			for pCity in pPlayer:Cities() do
				local iNumPlots = pCity:GetNumCityPlots();
				local iNumBuildings = 0;
				for iPlot = 0, iNumPlots - 1 do
					local pPlot = pCity:GetCityIndexPlot(iPlot)
					if pPlot and pPlot:GetOwner() == iPlayer and pPlot:GetFeatureType() == iFeature then
						iNumBuildings = iNumBuildings + 1
					end
				end
				pCity:SetNumRealBuilding(iDummy, iNumBuildings)
			end
		end
	end
end

GameEvents.PlayerDoTurn.Add(YieldFromFeature)

Although Civ 5 code being the magical thing it is, you have to use "pPlot:IsMountain()" instead of "pPlot:GetFeatureType() == iFeature" in order to determine whether or not the tile is a mountain.

For your purposes, you'd need to add an extra check in the cities loop to determine whether or not the city has one or more of your buildings in it.
 
I'm trying to add a National Wonder requiring either of two buildings in every city; something like Nuclear OR Solar Plant, for instance. I'm pretty sure this isn't possible through XML only, any ideas?
 
Back
Top Bottom