Colonialist Legacies: Histories of the New World | Colonial + Pre-Colonial civs

(I'd post it on Steam if it worked, but for some reason I can't. :( A ticket is pending.)
 
Looking for a bit of advice on this LUA script. I've been looking through it and trying to find out why it's not working, and I can't seem to find out what's wrong.

Posting this here will help.

What this is supposed to do is put special buildings in Only the first three cities that are on a Coast. It may also need to only count the cities that Australia founds, although I haven't built that in yet. But that should be easy.

Apparently it's putting the buildings in every single coastal city. :(

Anyhow, give it a whirl, and bask in how bad of a LUA writer I am.

Code:
-- BoundlessPlainsToShare
-- Author: Neirai
-- DateCreated: 11/11/2013 7:42:39 AM
--------------------------------------------------------------

-- When I enter the classical era, find me up to three possible Boundless Cities. Give them AUCOLONIALSETTLEMENT.
-- Whenever I found a city, check to see if I have enough Boundless Cities. If not, give the correct number of buildings to them, based on era.
-- Whenever I enter a new Boundless era, find me all my Boundless Cities and put the right building into them.
-- this could be messy.

function EraChangedForAussies(pEra, pPlayer)
	print(Players[pPlayer]:GetCivilizationType())
	print(GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
	print("We just changed an era, mate!")
	print(pEra)
		local BoundlessCount = 0
		if pEra == 1 then -- this should be the first time this ever runs successfully
			for pCity in Players[pPlayer]:Cities() do
				if pCity:IsCoastal(1) then
				print("This is a Coastal City, mate!")
				print("BoundlessCount is")
				print(BoundlessCount)
					if BoundlessCount < 3 then
						pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"], 1)
						BoundlessCount = BoundlessCount + 1
					else
						break
					end
				end
			end
		elseif pEra == 3 then -- there should be established Boundless Cities, and it's just a matter of finding them!
			for pCity in Players[pPlayer]:Cities() do
				if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUMININGTOWN"], 1)
				end
			end
		elseif pEra == 5 then -- there should be established Boundless Cities, and it's just a matter of finding them!
			for pCity in Players[pPlayer]:Cities() do
				if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUREFUGEEPROGRAMME"], 1)
				end
			end
		elseif pEra == 7 then -- there should be established Boundless Cities, and it's just a matter of finding them!
			for pCity in Players[pPlayer]:Cities() do
				if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUTOURISMDEPARTMENT"], 1)
				end
			end
		end
	end	
end
Events.SerialEventEraChanged.Add(EraChangedForAussies)

function AussiesFoundACity(uWhere, pPlayer, pCityID)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
	print("We founded a city, mate!")
		local pPlayerCity = Players[pPlayer]:GetCityByID(pCityID)
		local pEra = Players[pPlayer]:GetCurrentEra()
		if pEra > 0 then -- if we are past special Eras
			if pPlayerCity:IsCoastal(1) then -- I only care to run this if this is true.
				local pFoundedPlot = pPlayerCity:Plot()
				local BoundlessCities = 0
				print("This is a Coastal City")
				for pCity in Players[pPlayer]:Cities() do
					if pCity:Plot() ~= pFoundedPlot then -- make sure this isn't the same city.
						if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
							BoundlessCities = BoundlessCities + 1
							if BoundlessCities == 3 then
								break
							end
						end
					end
				end
				print("The number of BoundlessCities:")
				print(BoundlessCities)
				if BoundlessCities < 3 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"], 1)
				end 
				if pEra > 2 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUMININGTOWN"], 1)
				end
				if pEra > 4 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUREFUGEEPROGRAMME"], 1)
				end
				if pEra > 6 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUTOURISMDEPARTMENT"], 1)
				end
			else
				print("This is not a Coastal City!")
			end
		end
	end
end
Events.SerialEventCityCreated.Add(AussiesFoundACity)
 
Looking for a bit of advice on this LUA script. I've been looking through it and trying to find out why it's not working, and I can't seem to find out what's wrong.

Posting this here will help.

What this is supposed to do is put special buildings in Only the first three cities that are on a Coast. It may also need to only count the cities that Australia founds, although I haven't built that in yet. But that should be easy.

Apparently it's putting the buildings in every single coastal city. :(

Anyhow, give it a whirl, and bask in how bad of a LUA writer I am.

Code:
-- BoundlessPlainsToShare
-- Author: Neirai
-- DateCreated: 11/11/2013 7:42:39 AM
--------------------------------------------------------------

-- When I enter the classical era, find me up to three possible Boundless Cities. Give them AUCOLONIALSETTLEMENT.
-- Whenever I found a city, check to see if I have enough Boundless Cities. If not, give the correct number of buildings to them, based on era.
-- Whenever I enter a new Boundless era, find me all my Boundless Cities and put the right building into them.
-- this could be messy.

function EraChangedForAussies(pEra, pPlayer)
	print(Players[pPlayer]:GetCivilizationType())
	print(GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
	print("We just changed an era, mate!")
	print(pEra)
		local BoundlessCount = 0
		if pEra == 1 then -- this should be the first time this ever runs successfully
			for pCity in Players[pPlayer]:Cities() do
				if pCity:IsCoastal(1) then
				print("This is a Coastal City, mate!")
				print("BoundlessCount is")
				print(BoundlessCount)
					if BoundlessCount < 3 then
						pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"], 1)
						BoundlessCount = BoundlessCount + 1
					else
						break
					end
				end
			end
		elseif pEra == 3 then -- there should be established Boundless Cities, and it's just a matter of finding them!
			for pCity in Players[pPlayer]:Cities() do
				if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUMININGTOWN"], 1)
				end
			end
		elseif pEra == 5 then -- there should be established Boundless Cities, and it's just a matter of finding them!
			for pCity in Players[pPlayer]:Cities() do
				if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUREFUGEEPROGRAMME"], 1)
				end
			end
		elseif pEra == 7 then -- there should be established Boundless Cities, and it's just a matter of finding them!
			for pCity in Players[pPlayer]:Cities() do
				if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUTOURISMDEPARTMENT"], 1)
				end
			end
		end
	end	
end
Events.SerialEventEraChanged.Add(EraChangedForAussies)

function AussiesFoundACity(uWhere, pPlayer, pCityID)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
	print("We founded a city, mate!")
		local pPlayerCity = Players[pPlayer]:GetCityByID(pCityID)
		local pEra = Players[pPlayer]:GetCurrentEra()
		if pEra > 0 then -- if we are past special Eras
			if pPlayerCity:IsCoastal(1) then -- I only care to run this if this is true.
				local pFoundedPlot = pPlayerCity:Plot()
				local BoundlessCities = 0
				print("This is a Coastal City")
				for pCity in Players[pPlayer]:Cities() do
					if pCity:Plot() ~= pFoundedPlot then -- make sure this isn't the same city.
						if pCity:GetNumBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"]) > 0 then
							BoundlessCities = BoundlessCities + 1
							if BoundlessCities == 3 then
								break
							end
						end
					end
				end
				print("The number of BoundlessCities:")
				print(BoundlessCities)
				if BoundlessCities < 3 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"], 1)
				end 
				if pEra > 2 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUMININGTOWN"], 1)
				end
				if pEra > 4 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUREFUGEEPROGRAMME"], 1)
				end
				if pEra > 6 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUTOURISMDEPARTMENT"], 1)
				end
			else
				print("This is not a Coastal City!")
			end
		end
	end
end
Events.SerialEventCityCreated.Add(AussiesFoundACity)

You're going to have a bigger problem once you do get this working in that it will only work for the human player. The SerialEvent events only fire when the UI needs to deal with something (so only when the thing it is referring to is visible to the current player).

Also, you can concatenate strings with the .. operator. It will make your print statements less confusing. (And your print statements are often indented differently to the rest of your code, which makes it difficult to read.) Like this:

Code:
print("BoundlessCount is " .. BoundlessCount)

That's a stylistic issue though, not functional. I haven't tested your code to see what errors it may generate. Are you using FireTuner to see errors as they occur? And checking the Lua.log? (although the lua log is basically the output displayed for a FireTuner instance that has been open for the duration of play)
 
1. Events.SerialEventEraChanged.Add() - last time I had issues with this event (was forced to check era on PlayerDoTurn).
2.
Code:
[s]local[/s] BoundlessCities = 0
It should be global, otherwise it will ignore your counting there, adding building to every coastal city.
3. http://modiki.civfanatics.com/index.php/Player.GetBuildingClassCount_(Civ5_API)
4. http://modiki.civfanatics.com/index.php/City.GetOriginalOwner_(Civ5_API)
5. Important: You have to ask yourself how you want it to work. Should special buildings be capturable? I think yes. Then you have to store how many buildings you created (your code would create infinite buildings in newly founded cities as long as Australia lost previous cities). In this case point 3 will not be helpful.
6. Function should be run on CityCaptured event when Australia liberate its own city.
7. Since cities will be "razeable", counting only one building is pointless.
8. I am afraid there are serious issues in logic design.
 
Thanks for the input, guys.
Especially LastSword. Your advice is always helpful.
The issue with going global is what happens (in the rare time when it happens) if there is more than one Australian player? That's why I'm hoping to recalculate the cities each time. Problem is, as has been mentioned, this means it will recalculate wrong if stuff changes.

The problem that I always run into with LUA is that I don't know how to create an Array with a variable size, or to create variables that do or don't exist on a mechanical basis. What I'm getting at is if I could create code that did something like this:

For nPlayers in Game.Players (this is pseudocode, I don't know if it exists)
If Player == Australia then
global AustraliaCityCount# = 0 (# is a number equal to which Australian player this is)
global AustraliaColonyCount# = 0 (ditto)
global AustraliaMiningTownCount# = 0
etc, etc.

Is there any way to do this?
 
Oh, and S3rgeus, thanks so much for the concatenation tip. I will use and abuse it.
 
Code:
SomeTableVariable = {} [COLOR="Green"]//It has to be defined[/COLOR]
SomeTableVariable[sth] = sth2;
SomeTableVariable[sth3] = {} [COLOR="green"]//It is table in table, so SomeTableVariabl[sth3][sth4] = sth 5;[/COLOR]

Now, you will face the problem with losing data on game load. You will have to save/store this data somehow.
 
Okay, I couldn't follow that at all o.O
<<<Too bad at coding for this.

I tried a retool of the original code. It should work (I have yet to run it :p ) better than the above and avoid a number of problems, but it assumes there is only one Aussie player.

I'm not sure how to save this data, though. I assume that if you reload this code half-way through a game, it will forget who all the BoundlessCities were. :(

Code:
-- BoundlessPlainsToShare
-- Author: Neirai
-- DateCreated: 11/11/2013 7:42:39 AM
--------------------------------------------------------------

-- When I enter the classical era, find me up to three possible Boundless Cities. Give them AUCOLONIALSETTLEMENT.
-- Whenever I found a city, check to see if I have enough Boundless Cities. If not, give the correct number of buildings to them, based on era.
-- Whenever I enter a new Boundless era, find me all my Boundless Cities and put the right building into them.
-- this could be messy.

AustralianBoundlessCity1 = nil
AustralianBoundlessCity2 = nil
AustralianBoundlessCity3 = nil
AustralianPlayerEraNumber = 0

Events.SerialEventDawnOfManHide.Add(function(civID)
	print("The Civ ID is " .. civID)
	print("Aussie Civ ID is " .. GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA)
	if civID:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
		 local pEra = Players[pPlayer]:GetCurrentEra()
		 AustralianPlayerEraNumber = pEra
	end
end)

function AussieTurnChangedIsEraTheSame(pPlayer)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
		local pEra = Players[pPlayer]:GetCurrentEra()
		if pEra > AustralianPlayerEraNumber then
			EraChangedforAussies(pEra, pPlayer)
			AustralianPlayerEraNumber = pEra
		end
	end
end
GameEvents.PlayerDoTurn.Add(AussieTurnChangedIsEraTheSame)

function AussiesFoundACity(uWhere, pPlayer, pCityID)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
		print("We founded a city, mate!")
		local pPlayerCity = Players[pPlayer]:GetCityByID(pCityID)
		--no longer care about Eras when you do this. This is ONLY about the cities' locations, mate!
		if (pPlayerCity:IsCoastal(1) == true) and (pPlayerCity:GetOriginalOwner() == Players[pPlayer]) then -- I only care to run this if this is true.
			--local pFoundedPlot = pPlayerCity:Plot()
			print("This is a Coastal City founded by Australia")
			if AustralianBoundlessCity1 == nil then
				AustralianBoundlessCity1 = pPlayerCity
				print("Boundless City #1 is " .. AustralianBoundlessCity1:GetName())
			elseif AustralianBoundlessCity2 == nil then
				AustralianBoundlessCity2 = pPlayerCity
				print("Boundless City #2 is " .. AustralianBoundlessCity2:GetName())
			elseif AustralianBoundlessCity2 == nil then
				AustralianBoundlessCity3 = pPlayerCity
				print("Boundless City #3 is " .. AustralianBoundlessCity3:GetName())
			else 
				print("There are no remaining slots for Boundless Cities.")
			end
			if pPlayerCity == AustralianBoundlessCity1 or pPlayerCity == AustralianBoundlessCity2 or pPlayerCity == AustralianBoundlessCity3 then
				local pEra = Players[pPlayer]:GetCurrentEra()
				if pEra > 0 then pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"], 1)
				end 
				if pEra > 2 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUMININGTOWN"], 1)
				end
				if pEra > 4 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUREFUGEEPROGRAMME"], 1)
				end
				if pEra > 6 then
					pPlayerCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUTOURISMDEPARTMENT"], 1)
				end
			end
		else
			print("This is not a Coastal City or it was not founded by Australia.")
		end
	end
end
Events.SerialEventCityCreated.Add(AussiesFoundACity)
-- Change to PlayerCityFounded(PlayerID player, int cityX, int cityY)

function EraChangedForAussies(pEra, pPlayer)
	print(Players[pPlayer]:GetCivilizationType())
	print(GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA)
	if Players[pPlayer]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
		print("We just changed an era to era number" .. pEra .. ", mate!")
		print(pEra)
		for pCity in Players[pPlayer]:Cities() do
			if pCity == AustraliaBoundlessCity1 or pCity == AustraliaBoundlessCity2 or pCity == AustraliaBoundlessCity3 then
				print(pCity:GetName() .. " is a Boundless City, mate!")
				if pEra == 1 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUCOLONIALSETTLEMENT"], 1)
				elseif pEra == 3 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUMININGTOWN"], 1)
				elseif pEra == 5 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUREFUGEEPROGRAMME"], 1)
				elseif pEra == 7 then
					pCity:SetNumRealBuilding(GameInfoTypes["BUILDING_AUTOURISMDEPARTMENT"], 1)
				end
			end
		end
	end	
end
 
Alright, art question: How do you get the game to use multiple icons for the same unit, like say, baroque versus hair metal Great Artists?
 
Nurm Nurm Nurm, trying to figure out how to work TableSaverLoader is causing me fits. But I'm making progress.
 
Edit: For those following at home, I'm trying to keep this thread as on-topic as possible.
I figured out how to make "dynamic variables" by nesting my variables in tables. This means that I can now make multiple Aussie players work: see the code below!

Code:
	gT.AussiePlayers = {}          -- create the matrix
		for player in pairs(Players) do
			local PlayerNumber = Players[player]:GetID()
			if Players[player]:GetCivilizationType() == GameInfoTypes.CIVILIZATION_COLONIALAUSTRALIA then
				gT.AussiePlayers[PlayerNumber] = {}     -- create a new row
				gT.AussiePlayers[PlayerNumber][AustralianBoundlessCity1] = nil
				gT.AussiePlayers[PlayerNumber][AustralianBoundlessCity2] = nil
				gT.AussiePlayers[PlayerNumber][AustralianBoundlessCity3] = nil
				gT.AussiePlayers[PlayerNumber][AustralianPlayerEraNumber] = PreGame.GetEra()
			end
		end

Then comes using TableSaverLoader. I admit I'm very confused about how TSL works. I'm looking through Framedarchitecture's mods in order to try to figure it out and getting rather confused. Is it as simple as:

Copy the events from the Example and change "Ea" to, say, "ColonialAustralia".
When you call variables, upend a gT. in front of them and assign them either the data that's already in gT or a default variable, in that order.
?
 
Super close to finishing Australia - and then it's onto Canada!

There are some concerns regarding the Civilopedia:

1. Custom Worker (One that only builds Australian +2 Production Mines and can upgrade into Diggers) appears under UU - how do we hide this?
2. All custom buildings appear in the Ancient Era. Is there any way we can hide this or allot them to other eras (or hide them)?
3. Unique +2 Production mine appears under UI and in the Tech tree - is there anyway we can hide this?
 
1. Custom Worker (One that only builds Australian +2 Production Mines and can upgrade into Diggers) appears under UU - how do we hide this?
<ShowInPedia>false</ShowInPedia>

2. All custom buildings appear in the Ancient Era. Is there any way we can hide this or allot them to other eras (or hide them)?
Buildings are allocated to the Era their PrereqTech is in, if they have no PrereqTech, they will appear in the Ancient Era.

3. Unique +2 Production mine appears under UI and in the Tech tree - is there anyway we can hide this?
In the build (not the improvement) entry
<ShowInTechTree>false</ShowInTechTree>
<ShowInPedia>false</ShowInPedia>
but it'll still appear in the action panel for the unit (otherwise how is it going to get built?)
 
Thanks for the know-how. I'd never seen the way to hide improvements.

I once tried hiding buildings on a hidden tech, but the problem I had with that is the tech could show up in Ruins... no matter who you were playing.

Edit: is there any way to move the buildings to another Era (but not tech?)
 
Thanks for the know-how. I'd never seen the way to hide improvements.

I once tried hiding buildings on a hidden tech, but the problem I had with that is the tech could show up in Ruins... no matter who you were playing.

Edit: is there any way to move the buildings to another Era (but not tech?)

Did you leave <GoodyTech> true by accident if you copied your hidden tech from another existing one? I'm not 100% sure the game honors this tag, but it seems likely (the techs in the DB use it appropriately).
 
So there were two things I've noticed immediately when testing out this civ.

Firstly, and easily fixed, is that there seem to be some errors in the loading screen in the way of grammar and formatting, with words spaced oddly apart.

Secondly, regarding the issue of the double mines, wouldn't it be possible to have the worker as a UU replacing the worker that can build the special mine and not the normal one? And then if this is possible you could take the old mine picture off the tech tree so there's only one.
 
Secondly, regarding the issue of the double mines, wouldn't it be possible to have the worker as a UU replacing the worker that can build the special mine and not the normal one? And then if this is possible you could take the old mine picture off the tech tree so there's only one.

This is how it currently works - the Aussie Worker only builds the custom mines and can upgrade into Diggers. We are currently working on a fix for the Tech Tree mine bug!
 
Looooooooookin' good guys!

Spoiler :
 
Did you leave <GoodyTech> true by accident if you copied your hidden tech from another existing one? I'm not 100% sure the game honors this tag, but it seems likely (the techs in the DB use it appropriately).

It's veerrrrry possible.
 
Top Bottom