Understanding the stacking of Civ 5 terrain and features and modifying it.

I think I have a rough idea of what's going on. Playing with a lua script outside of civ, it seemed to be that it doesn't like you creating new rows on the fly
Not true. Lua's tables are dynamic. You just have to create them correctly. There is no 2-dimensional array - 2-d arrays are just 1-d arrays of 1-d arrays.

In the same way that you do

Code:
grid = {}
grid[0] = {}
grid[0][0] = -1
grid[0][1] = -1

at the start, you'll need to do

Code:
[B][COLOR="Red"]grid[iThing + 1] = {}[/COLOR][/B]
grid[iThing + 1][0] = 0
grid[iThing + 1][1] = 0
 
OK, it's finally working! Only problem is that it decides to continue to apply this added production. This means that lua variables are saved between turns. That's pretty neat! I should be able to fix this problem easy enough.
 
Right fixed that! On to the next great hurdle- getting it to GROW. I do have a question though. Is there any way to get modbuddy to save in "revisions", such that if I mess up a build, I can just go back to a previous one?
 
Also, another question- is it possible to create new missions like route to, and have them appear in the builds section of the workers UI. I ask because I want to make harvesting not an improvement, so existing improvements can get contaminated and be harvested.
 
Right fixed that! On to the next great hurdle- getting it to GROW. I do have a question though. Is there any way to get modbuddy to save in "revisions", such that if I mess up a build, I can just go back to a previous one?

You can increase the version, each time you debug it will make a different package (per version, that is). :D

Also, another question- is it possible to create new missions like route to, and have them appear in the builds section of the workers UI. I ask because I want to make harvesting not an improvement, so existing improvements can get contaminated and be harvested.

Yes! There is a modification of the UnitPanel.lua created by whoward (obviously) and adapted to BNW by ViceVirtuoso that let you create custom missions. If you don't mind using a DLL, there are also Events on whoward's/CP's DLL to make those. :)
I use it in my Tokugawa's Japan mod. Set it VFS=true (instead of loading with the Action tab stuff) and you're good to go making your custom Missions.
 
Update, finally got the growth to work!

MFW It finally works:
Spoiler :

twuc8ijebczyye1mliiv.gif


It was a difficult task. Borrowed heavily from Bhruic's treegrowth mod, but some of his stuff I couldn't understand, so I replaced it. The end result is that the mod works, but I fear that it increases the in between turn times by too much. The code might also look horribly inefficient to you more experienced coders. There are some kinks:
  • Growth % chance is based on what pass number it is, not the contamination level of the referring tile (tile that was searched around to find this tile) (should be easy-ish to fix, might be messy though)
  • Doesn't wrap around world boundaries (should be easy to fix)
  • Harvesting is still an improvement- needs to be NOT an improvement- a build forcibly activated by a mission (like route to)? (have to learn how to do this)

Then there is the final, most difficult part of the mod left before I release the first version: replacing the BNW trade routes with something different: Production trading only. I need trade routes to carry a certain percentage (% defined by player) of all production to the recipient city (total of generated by city + received via trade routes + or locally harvested (fiveout harvesting)). This would subtract from the donor city. In this way fiveout can be harvested in a few select locations, and "shipped" around a players empire.
Some other stuff that I need in that regard:
  • Caravans only go on railroad. If the railroad route is broken, and another cannot be found that doesn't take the caravan over it's range limit, then the route is broken
  • This production trading should be able to be done between cities of a different civ

And thanks to all you guys in helping! I'll be sure to credit you in my mod

Attached is the mod in it's current state.
 

Attachments

I manage to wrap it around the grid and I changed the proliferation method to something more "natural". Only problem is, now I get random tiles in the middle of contiguous L5 areas of no contamination. I cannot think why this would happen. It's a bit of an ask, given how bloated my code is atm, but if anyone is reading this, could you take a look at the attached code, and help me figure out what's wrong.
Also, I need to make a new button in the builds section of a worker's UI that forces him to do a build (as defined in CIV5Builds.xml). Any idea how I do this?
 

Attachments

I can't figure out whowards modular UnitPanel.lua. I have it under UI/InGame/WorldView/. In the Lua folder, I have a MissionButtons.Lua (which is activated in the contents tab as InGameUIAddin) containing this code:

Spoiler :
local HarvestButton = {
Name = "HarvestButton",
Title = "TXT_KEY_BUILD_SCRUB_FIVEOUT", -- or a TXT_KEY
OrderPriority = 200, -- default is 200
IconAtlas = "UNIT_ACTION_ATLAS", -- 45 and 64 variations required
PortraitIndex = 51,
ToolTip = function(build, unit)
local sTooltip = Locale.ConvertTextKey("TXT_KEY_BUILD_SCRUB_FIVEOUT_HELP");
local resourceType = unit:GetPlot():GetResourceType()
if ( resourceType == -1 ) then
sTooltip = sTooltip .. "[NEWLINE][NEWLINE]" ..Locale.ConvertTextKey("TXT_KEY_BUILD_SCRUB_FIVEOUT_NO_FIVEOUT_TEXT")
end;
if ( resourceType == GameInfoTypes["RESOURCE_L5"] ) then
sTooltip = sTooltip .. "[NEWLINE][NEWLINE]" ..Locale.ConvertTextKey("TXT_KEY_BUILD_SCRUB_FIVEOUT_RED_ZONE_TEXT")
end;
return sTooltip;
end,

Condition = function(build, unit)
local resourceType = unit:GetPlot():GetResourceType()
if ( resourceType == GameInfoTypes["RESOURCE_L2"] ) then return true end;
if ( resourceType == GameInfoTypes["RESOURCE_L3"] ) then return true end;
if ( resourceType == GameInfoTypes["RESOURCE_L4"] ) then return true end;
return false
end,

Disabled = function(build, unit)
if unit:GetUnitType() ~= GameInfoTypes["UNIT_WORKER"] then return true end
if unit:GetBuildType() == 0 then return true end
if unit:GetBuildType() then return true end
local resourceType = unit:GetPlot():GetResourceType()
if ( resourceType == GameInfoTypes["RESOURCE_L2"] ) then return false end;
if ( resourceType == GameInfoTypes["RESOURCE_L3"] ) then return false end;
if ( resourceType == GameInfoTypes["RESOURCE_L4"] ) then return false end;
--if unit is on tile with fiveout 2,3,4 return false
return true
end,

Build = function(build, unit, eClick)
if unit:MovesLeft() > 0 then
return GameInfoTypes["BUILD_SCRUB_FIVEOUT2"]
end
end,
}
LuaEvents.UnitPanelBuildAddin(HarvestButton)


And it doesn't work. No button appearing in the builds section of the worker's UI when on valid tiles. What am I doing wrong? How should I get it to work?
 
HOLY SH*T! It's in there- just disabled atm- Will update
UPDATE: The button appears, but it doesn't do anything when pressed.
Here's my code for the button now:

Spoiler :
Code:
local HarvestButton = {
	Name = "HarvestButton",
	Title = "TXT_KEY_BUILD_SCRUB_FIVEOUT", -- or a TXT_KEY
	OrderPriority = 200, -- default is 200
	IconAtlas = "UNIT_ACTION_ATLAS", -- 45 and 64 variations required
	PortraitIndex = 51,
	ToolTip = function(build, unit)
		local sTooltip = Locale.ConvertTextKey("TXT_KEY_BUILD_SCRUB_FIVEOUT_HELP");
		local resourceType = unit:GetPlot():GetResourceType()
		if ( resourceType == -1 ) then 
			sTooltip = sTooltip .. "[NEWLINE][NEWLINE]" ..Locale.ConvertTextKey("TXT_KEY_BUILD_SCRUB_FIVEOUT_NO_FIVEOUT_TEXT")
		end;
		if ( resourceType == GameInfoTypes["RESOURCE_L5"] ) then 
			sTooltip = sTooltip .. "[NEWLINE][NEWLINE]" ..Locale.ConvertTextKey("TXT_KEY_BUILD_SCRUB_FIVEOUT_RED_ZONE_TEXT")
		end;
		return sTooltip;
	end,
	
	Condition = function(build, unit)
		
		if unit:GetMoves() == 0 then return false end;
		local resourceType = unit:GetPlot():GetResourceType()
		if ( resourceType == GameInfoTypes["RESOURCE_L2"] ) then return true end;
		if ( resourceType == GameInfoTypes["RESOURCE_L3"] ) then return true end;
		if ( resourceType == GameInfoTypes["RESOURCE_L4"] ) then return true end;
		return false
	end,

	Disabled = function(build, unit)
		if unit:GetUnitType() ~= GameInfoTypes["UNIT_WORKER"] then return true end;
		
		local resourceType = unit:GetPlot():GetResourceType()
		if ( resourceType == GameInfoTypes["RESOURCE_L2"] ) then return false end;
		if ( resourceType == GameInfoTypes["RESOURCE_L3"] ) then return false end;
		if ( resourceType == GameInfoTypes["RESOURCE_L4"] ) then return false end;
		return true
	end,

	Build = function(build, unit, eClick)
		return GameInfo.Builds.BUILD_SCRUB_FIVEOUT2
	end,
}
LuaEvents.UnitPanelBuildAddin(HarvestButton)

The last part just doesn't work. What am I doing wrong?
 
It's almost impossible to read code like that, if you are human. Wrap code blocks around it (press Go Advanced below and look for #).
 
Nvm, I'm circumventing the need for that by using marsh as a "dummy feature" (in my mod, marsh will no longer exist- a necessary sacrifice). Clear marsh is now harvest, and now I just need to detect if a marsh has finished clearing to assign production to the nearby city.
 
From what I have encountered, global variables that are defined in lua files persist between turns. How can I then get the data stored in those global variables for use in UI elements (that are obviously in a different lua file). Is this possible. Also, can I replace UI popup lua and xml files by simply having my own that are imported into the VFS?
 
Any variable will persist until there are no more valid references to it (it has gone out of scope). Local variables can persist between turns just fine:

Code:
local counter = 0
function IncrementCounter()
	counter = counter + 1
end

The counter above will hold its value between turns, incrementing when you call that function. If I declared it local inside the function, however, it wouldn't be accessible outside and would disappear when the function is done.


For UI, these are runnging in different "states" than your main mod code, and these states don't share global labels. It has nothing to do with files. If your mod uses include statements then it's state may span many files all of which share global labels.

The reason I say global labels is that I'm really referring to the names of the variables, not the variables themselves. However, there are global labels shared across states. One of these is for a table called MapModData. If you print MapModData from different UI states, you will see that they all refer to the same table. (Really, try changing states in Fire Tuner and typing "print(MapModData)" ). So this is a convenient place to put stuff you want to share with UI.
 
Back
Top Bottom