In which case would the 'Save Game' button become invalid?

Tokata_RuNeLess

Chieftain
Joined
Sep 17, 2015
Messages
39
Location
USTC in Hefei, China
I tried to use TableSaverLoader016 and TSLSerializerCoreV3 to save a table about improvements into database. Besides, am trying to use correct English right here, but I'm not sure. Anyway, thank you for any probable help!

The table used to be like this:
Code:
MapTable = {}

-- The table would finally contain these columns:
-- MapTable[plot].type
-- MapTable[plot].counterUp -- upgrade
-- MapTable[plot].counterDe -- degrade

And I managed to rewrite it like this:
Code:
MapModData.TiData	= MapModData.TiData or {}
TiData			= MapModData.TiData
TiData.MapTable		= TiData.MapTable or {}
MapTable			= TiData.MapTable

include("TableSaverLoader016.lua")
tableRoot = TiData
tableName = "TiData"
include("Tokata_Improvement_TSLSerializerV3.lua") -- Already defined yet
TableLoad(tableRoot, tableName)

and at the bottom of my code:

Code:
function OnModLoaded()
	local bNewGame = not TableLoad(tableRoot, tableName)
	TableSave(tableRoot, tableName)
end
OnModLoaded()

The VFS is correct, and the mod works well, but it comes out that once I have any data in the table 'MapTable', it becomes unable for me to click 'Save Game', nor 'Quicksave'. The only way to save the game is through IGE (with the table failed to save), or I can only save when the table is empty.
Is there something wrong? Sadly I'm not an experienced lua coder and am unable to point out the mistake.
 
You actually have two TableLoad statements.

--------------------------------------------------------------

Code:
local bNewGame = not TableLoad(tableRoot, tableName)
is actually an efficient bit of code in that not only does it create variable bNewGame but it also performs the TableLoad operation.

-----------------------------------------------------------------------------

Compare DarkScythe's method from his Holo mod:
Code:
MapModData.WWDataStore = MapModData.WWDataStore or {}
WWDataStore = MapModData.WWDataStore
WWDataStore.ResourcePlot = {}
WWDataStore.RowenGift = {}
WWDataStore.HoloUpgrades = {}
with what you have:
Code:
MapModData.TiData	= MapModData.TiData or {}
TiData			= MapModData.TiData
TiData.MapTable		= TiData.MapTable or {}
MapTable			= TiData.MapTable
I suspect you are breaking the TableSaver system because of the way you are defining the tables. I would change to
Code:
MapModData.TiData	= MapModData.TiData or {}
TiData			= MapModData.TiData
TiData.MapTable		=  {}
You should be able to directly write and read to/from subtable "TiData.MapTable" within your code such as:
Code:
table.insert(TiData.MapTable, "Mouse")
or
Code:
TiData.MapTable[#TiData.MapTable + 1] = "Mouse"
or
Code:
TiData.MapTable[iPlotID] = iPlotIDNumber
 
You actually have two TableLoad statements.

--------------------------------------------------------------

Code:
local bNewGame = not TableLoad(tableRoot, tableName)
is actually an efficient bit of code in that not only does it create variable bNewGame but it also performs the TableLoad operation.

......

Thanks for your help!:)

Firetuner suggests that I have used a table as a key. So maybe it is that I have to rebuild my table, and that a table like MapTable[plot].data can not be saved in this way because it contains '[plot]' as a part of its key.(Is that true?)
Maybe I should use 'MapTable.plotX.plotY', though. Anyway, I'm getting down to do this!:crazyeye:
 
You should be able to use a "table-name" as a "key", as in
Code:
TiData.MapTable["tPlotResources"] = {}
TiData.MapTable["tPlotResources"][iPlotID] = "RESOURCE_IRON"
  • iPlotId in that example would be a numerical PlotID#
  • tPlotResources would be both a "key" within MapTable but also its "value" would be an lua-table holding "key,value" pairs of "PlotID#, Resource-Type".

-----------------------------------------------------------------------

What table-saver does not like to save (and this may be an actual game limitation on what can be saved) is object-data such as "pCity" or "pUnit" or "pPlot", so using "pCity" as an example, TableSaverLoader does not like:
Code:
TiData.MapTable["tCoastalCities"] = {}
for pCity in pPlayer:Cities() do
	if pCity:IsCoastal() then
		table.insert(TiData.MapTable["tCoastalCities"], pCity)
	end
end
but would be okay if it were done this way:
Code:
TiData.MapTable["tCoastalCities"] = {}
for pCity in pPlayer:Cities() do
	if pCity:IsCoastal() then
		table.insert(TiData.MapTable["tCoastalCities"], pCity:GetID())
	end
end
The thing to remember is that on the "value" side of a "key, value" pair TableSaverLoader wants integer, boolean, or string data.

I have not experimented with whether TableSaverLoader will accept a 'pointer object' like "pCity" as the "key" of a "key, value" pair.
 
You should be able to use a "table-name" as a "key", as in
Code:
TiData.MapTable["tPlotResources"] = {}
TiData.MapTable["tPlotResources"][iPlotID] = "RESOURCE_IRON"
  • iPlotId in that example would be a numerical PlotID#
  • tPlotResources would be both a "key" within MapTable but also its "value" would be an lua-table holding "key,value" pairs of "PlotID#, Resource-Type".

……

Thank you very much!:goodjob:

By the way, I have found another problem that, are there any cryptic improvements on the map?
I have already defined a column 'Threshold' in sql:
Code:
ALTER TABLE Improvements	ADD COLUMN Threshold				integer		DEFAULT 0;
If I'm not mistaken, every improvements should have a value of threshold at 0. But while I tried to get the Threshold of every improvement, it turned out that there are still some 'hidden' improvements on the map which have no threshold. And these cryptic improvements are right on the lower left of each start points. Ei a capital on (39, 17) and the mysterious improvement on (39, 16).
I tried to put another improvement on these plots, and no error reports any longer. But I'm curious about what are they, do you know anything about that?
 
I tried to put another improvement on these plots, and no error reports any longer. But I'm curious about what are they, do you know anything about that?

Are you testing for "no improvement" before you try to get the threshold?

Code:
GameInfo.Improvements[pPlot:GetImprovementType()].Threshold

will thrown an error for all plots that don't have an improvement, as for those plots pPlot:GetImprovementType() returns -1 and that's an invalid key for GameInfo.Improvements[]

Without the mod, and hence the code, you're basically asking us to crystal ball gaze.
 
Are you testing for "no improvement" before you try to get the threshold?

......

I used the following code to test.
Code:
local pImprovement = plot:GetImprovementType()
if pImprovement ~= nil then
local pThreshold = GameInfo.Improvements[pImprovement].Threshold
And the error right came from the 3rd line. Only the plots on the lower left of starting plots reports so, no other plots. It seemed just like that there 'is an improvement', and that's what I'm confused about.
 
GetImprovementType() returns the integer ID of the improvement, so it will never be nil

If a tile doesn't have an improvement it will return -1
 
Enabled debugging and check lua.log

Almost certainly the error at the first plot without a resource aborted the remainder of the script
 
Is it able to check if a plot has a trade route (or more) passing by? I mean, in BNW.
The route can be displayed on the map, but it seems that 'plot:IsTradeRoute()' is defined in the Vanilla way, and it returns if the plot is at the city connection (of roads.)
 
Not easily in Lua. (Which is a shame as there happens to be a C++ method - GetNumTradeRoutesInPlot(CvPlot*) - that does exactly what you want!)

But you can loop all players and use pPlayer:GetInternationalTradeRoutePlotToolTip(pPlot) and check the response for containing text (ie ~= "")
 
Not easily in Lua. (Which is a shame as there happens to be a C++ method - GetNumTradeRoutesInPlot(CvPlot*) - that does exactly what you want!)

But you can loop all players and use pPlayer:GetInternationalTradeRoutePlotToolTip(pPlot) and check the response for containing text (ie ~= "")

Oh thanks!:goodjob:
By the way, I didn't see this in the modiki, are there any way to find these functions?
 
I found GetInternationalTradeRoutePlotToolTip() by a) realising that hovering the mouse over a plot gave you something along these lines, and b) looking in the core lua file (MouseOverInclude.lua IIRC) to find out how it did it

Best reference for the Lua API is the C++ source code, second best is the game core Lua source code.
 
I found GetInternationalTradeRoutePlotToolTip() by a) realising that hovering the mouse over a plot gave you something along these lines, and b) looking in the core lua file (MouseOverInclude.lua IIRC) to find out how it did it

Best reference for the Lua API is the C++ source code, second best is the game core Lua source code.

Get it, thanks!:goodjob:
 
Top Bottom