Need HELP of UA creating for a new civ

zwei833

Emperor
Joined
Feb 26, 2011
Messages
1,228
Hello everyone!
I'm a newbie to New Civilization modding. I try to make new civilizations by myself, now nearly everything of my first mod -- German Empire Civ is already besides the UA(aka. TRAIT). I have totally no idea about how to create a UA. I will be grateful if some one can help me to do the UA below:

UA: Verfassungsreich (Eng: Constitutionalism Empire)
After researching Printing Press, +1 :c5happy: per city when none of cities found by you are occupied:c5occupied: by other civilizations, +1 :c5happy: and +2:c5culture: in all cities which are not puppet:c5puppet: cities.

And I don't mind to simplify or change the UA, so discuss about the design itself are also welcome.
 
Code:
function freehappinessforall
if Players[iPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_UNIFIEDGERMANY then
	if Team:IsHasTech(GameInfo.Technologies["TECH_PRINTING_PRESS"]) then
		for pCity in Players[iPlayer]:Cities() do
			if not (pCity:IsPuppet()) then
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_HAPPINESSANDCULTUREDUMMY"], 1)
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(freehappinessforall)
After that, make adjustments to the appropriate type and create a dummy building that yields out 5% culture and one free happiness.

Got no clue how to do the first part though.
 
Code:
function freehappinessforall
if Players[iPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_UNIFIEDGERMANY then
	if Team:IsHasTech(GameInfo.Technologies["TECH_PRINTING_PRESS"]) then
		for pCity in Players[iPlayer]:Cities() do
			if not (pCity:IsPuppet()) then
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_HAPPINESSANDCULTUREDUMMY"], 1)
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(freehappinessforall)
After that, make adjustments to the appropriate type and create a dummy building that yields out 5% culture and one free happiness.

Got no clue how to do the first part though.

Thank you sir! That's so helpful, At least the most important part of the UA is done!
 
Code:
function freehappinessforall
if Players[iPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_UNIFIEDGERMANY then
	if Team:IsHasTech(GameInfo.Technologies["TECH_PRINTING_PRESS"]) then
		for pCity in Players[iPlayer]:Cities() do
			if not (pCity:IsPuppet()) then
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_HAPPINESSANDCULTUREDUMMY"], 1)
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(freehappinessforall)
After that, make adjustments to the appropriate type and create a dummy building that yields out 5% culture and one free happiness.

Got no clue how to do the first part though.

Is it just add this code into a LUA file(with adjustments) or some other codes are also needed?
I add this(with adjustments) and the event doesn't work, no building add to the cities with printing press tech and do turns. Is there something wrong?
Code:
function freehappinessforall
if Players[iPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY then
	if Team:IsHasTech(GameInfo.Technologies["TECH_PRINTING_PRESS"]) then
		for pCity in Players[iPlayer]:Cities() do
			if not (pCity:IsPuppet()) then
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY"], 1)
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(freehappinessforall)
 
I forgot that I can't interchangeably use different identifiers if the function does not provide it hence I have to use other game events to summon it up. Sorry for the inconvenience.
Code:
function OnPrintingPressResearched(teamID, techID)
local printyTechInfo = GameInfo.Technologies["TECH_PRINTING_PRESS"]
	if Players[iPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY and (techID == printyTechInfo.ID) then --You are Zwei Germany and having Printing Press?
	GameEvents.PlayerDoTurn.Add(freehappinessforall) --Opening you up!
	GameEvents.TeamTechResearched.Remove(OnTechResearched) --Turning you off because you're not necessary anymore!
	end
end
function freehappinessforall (iPlayer)
local pplayer = Players[iPlayer]
for pCity in pplayers:Cities() do
	if not (pCity:IsPuppet()) then --Is your city a puppet? No puppets allowed below here!
		pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY"], 1) --Make this building pop out.
		end
	end
end
GameEvents.TeamTechResearched.Add(OnPrintingPressResearched)
 
I forgot that I can't interchangeably use different identifiers if the function does not provide it hence I have to use other game events to summon it up. Sorry for the inconvenience.
Code:
function OnPrintingPressResearched(teamID, techID)
local printyTechInfo = GameInfo.Technologies["TECH_PRINTING_PRESS"]
	if Players[iPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY and (techID == printyTechInfo.ID) then --You are Zwei Germany and having Printing Press?
	GameEvents.PlayerDoTurn.Add(freehappinessforall) --Opening you up!
	GameEvents.TeamTechResearched.Remove(OnTechResearched) --Turning you off because you're not necessary anymore!
	end
end
function freehappinessforall (iPlayer)
local pplayer = Players[iPlayer]
for pCity in pplayers:Cities() do
	if not (pCity:IsPuppet()) then --Is your city a puppet? No puppets allowed below here!
		pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY"], 1) --Make this building pop out.
		end
	end
end
GameEvents.TeamTechResearched.Add(OnPrintingPressResearched)

Sorry, but it still doesn't work. I upload a test version of the mod here, could you please check it if there is something wrong? Thank you very much.

P.S. I put the code into Lua\1848_Functions.lua

Download:http://forums.civfanatics.com/downloads.php?do=file&id=24519
 
  • mis-matched variable names within the same function (ie, freehappinessforall)
  • mis-match of function names between
    Code:
    GameEvents.TeamTechResearched.Add(OnPrintingPressResearched)
    GameEvents.TeamTechResearched.Remove(OnTechResearched)
  • non-existent variable iPlayer being used within function called OnPrintingPressResearched
  • Possible conceptual errors of code: what happens when a player reloads a saved game and they have already researched technology TECH_PRINTING_PRESS ?
    Spoiler Hint :
    the possible issue lies in the fact that there will never be a match between techID and printyTechInfo.ID because a player(team) can only discover a single tech one time.)
 
Possible conceptual errors of code: what happens when a player reloads a saved game
Yeah I just noticed the errors when the lua.log started to pop them out.

Anyway, I don't believe there could be possible conceptual errors, because if I can recall the LUA code is reloaded every save since that's how the Reforestation by framedarchitecture coding works and no one seems to be complaining about any issues with those.

Edit: Alright got it working the new code should be(Just remember to click next turn, since "freehappinessforall" repeats itself for every next turn):
Code:
function OnPrintingPressResearched(teamID, techID)
local printyTechInfo = GameInfo.Technologies["TECH_PRINTING_PRESS"]
  if printyTechInfo and (techID == printyTechInfo.ID) then
	GameEvents.PlayerDoTurn.Add(freehappinessforall)
	GameEvents.TeamTechResearched.Remove(OnPrintingPressResearched)
	end
end
function freehappinessforall (iPlayer)
local pplayer = Players[iPlayer]
	if pplayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY then
		for pCity in pplayer:Cities() do
			if not (pCity:IsPuppet()) then
			pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY"], 1)
			end
		end
	end
end
GameEvents.TeamTechResearched.Add(OnPrintingPressResearched)
Please set your dummy build of NeverCapture to be true(We don't want enemies to have it!) and your Happiness to be UnmoddedHappiness(No requirements, just free happiness think Circus Maximums) if you want your dummy building to be giving out local happiness(Requires that the population is higher than the addition of local happiness! think Circus and Colosseum!)
 
Thank you! The code finally works!

But a little problem, it doesn't work if I start the game in a later Era(Industrial Era, etc) when I already have the Priting Press tech from the start of the game. Is it possible to fix this?
 
Code:
function freehappinessforall (iPlayer)
local pplayer = Players[iPlayer]
local pTeamTechs = Teams[pplayer:GetTeam()]:GetTeamTechs();
local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
	if pplayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY then
		if (pTeamTechs:HasTech(iPrinting)) then
			for pCity in pplayer:Cities() do
				if not (pCity:IsPuppet()) then
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY"], 1)
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(freehappinessforall)

Just replace everything with this code.
 
Code:
function freehappinessforall (iPlayer)
local pplayer = Players[iPlayer]
local pTeamTechs = Teams[pplayer:GetTeam()]:GetTeamTechs();
local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
	if pplayer:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY then
		if (pTeamTechs:HasTech(iPrinting)) then
			for pCity in pplayer:Cities() do
				if not (pCity:IsPuppet()) then
				pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY"], 1)
				end
			end
		end
	end
end
GameEvents.PlayerDoTurn.Add(freehappinessforall)

Just replace everything with this code.

Everything works fine now! Thank you!
 
I made this really quickly so I don't expect it to work but it might anyway:

Code:
function ZweiGermanyNoCaptureHappiness (playerID)
local player = Players[playerID]
local pTeamTechs = Teams[player:GetTeam()]:GetTeamTechs();
local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
local numGermanCitiesCaptured = 0
if (player:IsAlive() and player:GetCivilizationType() == GameInfoTypes.ZWEI_GERMANY) then 
		for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
			local otherPlayer = Players[otherPlayerID]
			for city in otherPlayer:Cities() do
				if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
					numGermanCitiesCaptured = numGermanCitiesCaptured + 1
		                if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured = 0 then                 
			for city in player:Cities() do
				city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY_FIRST_HALF"], 1)
				end
			end
		end
	end
end
end
end
GameEvents.PlayerDoTurn.Add(ZweiGermanyNoCaptureHappiness)
 
I made this really quickly so I don't expect it to work but it might anyway:

Code:
function ZweiGermanyNoCaptureHappiness (playerID)
local player = Players[playerID]
local pTeamTechs = Teams[player:GetTeam()]:GetTeamTechs();
local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
local numGermanCitiesCaptured = 0
if (player:IsAlive() and player:GetCivilizationType() == GameInfoTypes.ZWEI_GERMANY) then 
		for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
			local otherPlayer = Players[otherPlayerID]
			for city in otherPlayer:Cities() do
				if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
					numGermanCitiesCaptured = numGermanCitiesCaptured + 1
		                if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured = 0 then                 
			for city in player:Cities() do
				city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_GERMANY_FIRST_HALF"], 1)
				end
			end
		end
	end
end
end
end
GameEvents.PlayerDoTurn.Add(ZweiGermanyNoCaptureHappiness)

Thank you for the code! I'm going out now, will test the code later
 
@Uighur_Caesar

I did a little adjustment to the code:
Code:
function ZweiGermanyNoCaptureHappiness (playerID)
local player = Players[playerID]
local pTeamTechs = Teams[player:GetTeam()]:GetTeamTechs();
local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
local numGermanCitiesCaptured = 0
if (player:IsAlive() and player:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY) then 
		for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
			local otherPlayer = Players[otherPlayerID]
			for city in otherPlayer:Cities() do
				if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
					numGermanCitiesCaptured = numGermanCitiesCaptured + 1
		                if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured = 0 then                 
			for city in player:Cities() do
				city:SetNumRealBuilding(GameInfoTypes["BUILDINGCLASS_ZWEI_UNIFIED"], 1)
				end
			end
		end
	end
end
end
end
GameEvents.PlayerDoTurn.Add(ZweiGermanyNoCaptureHappiness)

And added it into my LUA file.

It seems that it doesn't work in the game and even block other codes in the same LUA file.

LUA and Log in the attachment.

P.S. TEST VERSION also updated, included Uighur_Caesar's code.
 

Attachments

  • LUA + LOG.rar
    6.6 KB · Views: 17
You need another equal sign for numeric values.

Code:
function ZweiGermanyNoCaptureHappiness (playerID)
local player = Players[playerID]
local pTeamTechs = Teams[player:GetTeam()]:GetTeamTechs();
local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
local numGermanCitiesCaptured = 0
if (player:IsAlive() and player:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY) then 
		for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
			local otherPlayer = Players[otherPlayerID]
			for city in otherPlayer:Cities() do
				if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
					numGermanCitiesCaptured = numGermanCitiesCaptured + 1
		                if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured == 0 then                 
			for city in player:Cities() do
				city:SetNumRealBuilding(GameInfoTypes["BUILDINGCLASS_ZWEI_UNIFIED"], 1)
				end
			end
		end
	end
end
end
end
GameEvents.PlayerDoTurn.Add(ZweiGermanyNoCaptureHappiness)

And LUA is sort of like XML. If one part of the code is broken, then the game throws all the code out.
 
  1. Buildings-Class is being referenced here, which is going to give wildly different results than anticipated because the ID# for the Building-Class will not be anything like the ID# for the Building, which is what is required with
    Code:
    city:SetNumRealBuilding(BuildingID#)
    See the red highlight for the error being made:
    Code:
    function ZweiGermanyNoCaptureHappiness (playerID)
    	local player = Players[playerID]
    	local pTeamTechs = Teams[player:GetTeam()]:GetTeamTechs();
    	local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
    	local numGermanCitiesCaptured = 0
    	if (player:IsAlive() and player:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY) then 
    		for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
    			local otherPlayer = Players[otherPlayerID]
    			for city in otherPlayer:Cities() do
    				if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
    					numGermanCitiesCaptured = numGermanCitiesCaptured + 1
    					if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured == 0 then                 
    						for city in player:Cities() do
    							city:SetNumRealBuilding(GameInfoTypes["[color="red"]BUILDINGCLASS_ZWEI_UNIFIED[/color]"], 1)
    						end
    					end
    				end
    			end
    		end
    	end
    end
    GameEvents.PlayerDoTurn.Add(ZweiGermanyNoCaptureHappiness)
  2. The code as written will not perform correctly even if the usage of a Building-Class reference is corrected:
  3. This part of the code won't actually impliment correctly:
    Code:
    for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
    	local otherPlayer = Players[otherPlayerID]
    	for city in otherPlayer:Cities() do
    		if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
    			numGermanCitiesCaptured = numGermanCitiesCaptured + 1
    			if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured == 0 then                 
    				for city in player:Cities() do
    					city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_UNIFIED"], 1)
    				end
    			end
    		end
    	end
    end
    • You need to scan through all otherplayer cities before executing this portion of the code:
      Code:
      if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured == 0 then                 
      	for city in player:Cities() do
      		city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_UNIFIED"], 1)
      	end
      end
    • Otherwise you get false positive results when the 1st otherplayer has no german cities, but the second or third otherplayer does have german cities it has captured. So, you would need to restructure the "for" loop-portion of the code as like:
      Code:
      for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
      	local otherPlayer = Players[otherPlayerID]
      	for city in otherPlayer:Cities() do
      		if (city:GetOriginalOwner() == playerID and city:GetOwner() ~= playerID) then
      			numGermanCitiesCaptured = numGermanCitiesCaptured + 1
      		end
      	end
      end
      if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured == 0 then                 
      	for city in player:Cities() do
      		city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_UNIFIED"], 1)
      	end
      end
      In this way the scan is done through all the otherplayers before the decision is made as to whether any original german cities are in the wrong hands.
    • This can still cause trouble, potentially, however, because MAX_PLAYERS is 64 and there is no guarantee there will be 64 players in any one game. It is better when making "for" loops like this through all players or all major civ players or all city-state players to add the following couple of lines:
      Code:
      for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
      	if (Players[otherPlayerID] ~= nil) and Players[otherPlayerID]:IsAlive() and (otherPlayerID ~= playerID) then
      		local otherPlayer = Players[otherPlayerID]
      		for city in otherPlayer:Cities() do
      			if (city:GetOriginalOwner() == playerID) then
      				numGermanCitiesCaptured = numGermanCitiesCaptured + 1
      			end
      		end
      	end
      end
      if (pTeamTechs:HasTech(iPrinting)) and numGermanCitiesCaptured == 0 then                 
      	for city in player:Cities() do
      		city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_UNIFIED"], 1)
      	end
      end
  4. I would re-structure the code as follows:
    Code:
    function ZweiGermanyNoCaptureHappiness (playerID)
    	local player = Players[playerID]
    	if (player:IsAlive() and player:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ZWEI_GERMANY) then 
    		local pTeamTechs = Teams[player:GetTeam()]:GetTeamTechs();
    		local iPrinting = GameInfoTypes["TECH_PRINTING_PRESS"];
    		if (pTeamTechs:HasTech(iPrinting)) then
    			local bAGermanCityIsInTheWrongHands = false
    			for otherPlayerID = 0, GameDefines.MAX_PLAYERS - 1 do
    				if (Players[otherPlayerID] ~= nil) and Players[otherPlayerID]:IsAlive() and (otherPlayerID ~= playerID) then
    					for city in Players[otherPlayerID]:Cities() do
    						if (city:GetOriginalOwner() == playerID) then
    							bAGermanCityIsInTheWrongHands = true
    							break
    						end
    					end
    				end
    				if bAGermanCityIsInTheWrongHands then
    					break
    				end
    			end
    			for city in player:Cities() do
    				city:SetNumRealBuilding(GameInfoTypes["BUILDING_ZWEI_UNIFIED"], bAGermanCityIsInTheWrongHands and 0 or 1)
    			end
    		end
    	end
    end
    GameEvents.PlayerDoTurn.Add(ZweiGermanyNoCaptureHappiness)
  5. There is always a possibility of a code-goof, so if it doesn't seem to work, attach the mod whoward69's zip your mods and attach tutorial so we can trouble-shoot the goof on our end.
 
Top Bottom