[SQL+Lua] Gathering Information from New Table

bane_

Howardianism High-Priest
Joined
Nov 27, 2013
Messages
1,559
So, I created a table:
Code:
CREATE TABLE UnitResistances	(
				 --ID INT PRIMARY KEY	NOT NULL
				 TYPE TEXT			NOT NULL,
				 Resistance BOOLEAN DEFAULT 0,
				 DamageType TEXT,
				 Value INT DEFAULT 0
				);

And populated it as such:
Code:
INSERT INTO UnitResistances	(Type,						DamageType,			Resistance,		Value) VALUES
	('UNIT_WBC_CENTAUR',		'Cold',				1,				10),
	('UNIT_WBC_CENTAUR',		'Crushing',			[COLOR="Red"][B]0[/B][/COLOR],				20),
	('UNIT_WBC_CONJURER',		'Fire',				1,				15),
	('UNIT_WBC_CONJURER',		'Piercing',			[COLOR="red"][B]0[/B][/COLOR],				35);

When I try to access this table, something incredible happens: every 0 turns into a 1.
If I look at the DebugDatabase.db, it is all normal. Funny, though, that when I used TEXT instead of BOOLEAN, it was still being change from 'Weakness' to 'Resistance'.

Here is the Lua snippet used to gather the information:
Code:
local eResDamageType
local iValue
print("[GetDamageInfo] Started...")
if bResistance then	
	print("[GetDamageInfo] Getting resistance.")
	for eUnitRes in GameInfo.UnitResistances("Value > 0") do
		iUnitType = GameInfoTypes[eUnitRes.Type]
		print("[GetDamageInfo] Iterating resistance.")
		print(eUnitRes.Resistance)
		if iUnitType == eUnit and eUnitRes.Resistance == 1 then
			print("[GetDamageInfo] Found Unit's resistance.")
			eResDamageType = eUnitRes.DamageType
			iValue = "+" ..eUnitRes.Value
			break
		end
	end
else
	print("[GetDamageInfo] Getting weakness.")
	for eUnitRes in GameInfo.UnitResistances("Value > 0") do
		iUnitType = GameInfoTypes[eUnitRes.Type]
		print("[GetDamageInfo] Iterating weakness.")
		[COLOR="red"][B]print(eUnitRes.Resistance)[/B][/COLOR]
		if iUnitType == eUnit and [COLOR="red"][B]eUnitRes.Resistance == 0 then[/B][/COLOR]
			print("[GetDamageInfo] Found unit's weaknes..")
			eResDamageType = eUnitRes.DamageType
			iValue = "-" ..eUnitRes.Value
			break
		end
	end
end

This is the log:
Code:
[22377.251] UnitPanel: [GetDamageInfo] Started...
[22377.251] UnitPanel: [GetDamageInfo] Getting resistance.
[22377.251] UnitPanel: [GetDamageInfo] Iterating resistance.
[22377.251] UnitPanel: 1
[22377.251] UnitPanel: [GetDamageInfo] Iterating resistance.
[COLOR="Red"][B][22377.251] UnitPanel: 1[/B][/COLOR]
[22377.251] UnitPanel: [GetDamageInfo] Iterating resistance.
[22377.251] UnitPanel: 1
[22377.251] UnitPanel: [GetDamageInfo] Found Unit's resistance.
[22377.251] UnitPanel: [GetDamageInfo] Started...
[22377.251] UnitPanel: [GetDamageInfo] Getting weakness.
[22377.251] UnitPanel: [GetDamageInfo] Iterating weakness.
[22377.251] UnitPanel: 1
[22377.251] UnitPanel: [GetDamageInfo] Iterating weakness.
[COLOR="red"][B][22377.251] UnitPanel: 1[/B][/COLOR]
[22377.251] UnitPanel: [GetDamageInfo] Iterating weakness.
[22377.251] UnitPanel: 1
[22377.251] UnitPanel: [GetDamageInfo] Iterating weakness.
[COLOR="red"][B][22377.251] UnitPanel: 1[/B][/COLOR]

Database:
Spoiler :


It never finds a weakness because the table is being changed by something inside the game itself (I have nothing in my files changing that value).
Ideas?
 
To makes things worse (or better, because it adds new information) if I add a Weakness without a resistance, it actually gets displayed AND is recognized as a '0'. :confused:

I'll use two different functions for now, that should solve the issue (EDIT: Nope) BUT, I still wanna understand why this occurs.
 
I found this an intersting issue, primarily because I've been doing a lot of 'table-adding' in mods lately and I had not run into anything similar, so I was concerned there might be a hidden gotcha somewhere in the way lua reads from the database. I kept getting the same sort of thing you were no matter what I did with the construction of the new game-table. Nor did it matter whether I defined the table in SQL or XML.

Changing column definitions from boolean to integer to text made no difference, nor did swapping everything over from SQL to XML.

Then I realized you were using 'Type' as a column in a non-primary table. The last change before I got the following (correct output) was to change column name 'Type' to 'UnitType':
Code:
[789655.593] Lua Script1:  
[789655.593] Lua Script1:  
[789655.593] Lua Script1: [GetDamageInfo] Started...
[789655.593] Lua Script1:  
[789655.593] Lua Script1:  
[789655.593] Lua Script1: For Type of UNIT_WARRIOR eUnitRes.Resistance is reported as true
[789655.593] Lua Script1: [GetDamageInfo] Found Unit's resistance.
[color="blue"][789655.593] Lua Script1: for UNIT_WARRIOR and bResistance = true, the eResDamageType is Cold and the iValue is +10[/color]
[789655.593] Lua Script1: For Type of UNIT_WARRIOR eUnitRes.Resistance is reported as true
[789655.593] Lua Script1: For Type of UNIT_WARRIOR eUnitRes.Resistance is reported as false
[789655.593] Lua Script1: [GetDamageInfo] Found Unit's resistance.
[color="green"][789655.593] Lua Script1: for UNIT_WARRIOR and bResistance = false, the eResDamageType is Crushing and the iValue is -20[/color]
[789655.593] Lua Script1: For Type of UNIT_BARBARIAN_WARRIOR eUnitRes.Resistance is reported as true
[789655.593] Lua Script1: [GetDamageInfo] Found Unit's resistance.
[color="red"][789655.593] Lua Script1: for UNIT_BARBARIAN_WARRIOR and bResistance = true, the eResDamageType is Fire and the iValue is +15[/color]
[789655.593] Lua Script1: For Type of UNIT_BARBARIAN_WARRIOR eUnitRes.Resistance is reported as true
[789655.593] Lua Script1: For Type of UNIT_BARBARIAN_WARRIOR eUnitRes.Resistance is reported as false
[789655.593] Lua Script1: [GetDamageInfo] Found Unit's resistance.
[color="magenta"][789655.593] Lua Script1: for UNIT_BARBARIAN_WARRIOR and bResistance = false, the eResDamageType is Piercing and the iValue is -35[/color]
[789655.593] Lua Script1:  
[789655.593] Lua Script1:
There's still a bit of print clutter which might make it seem like the code is not running properly, so I color-coded which print lines in the log align to which lines in the lua script, and which also align to which lines in the XML code. All the print commands inside the function GetResistanceData are actually creating the confusion because I did not delete them even after I redrafted Bane_'s original code when I was thinking there might have been a localization or similar issue.

Lua Code Being Run:
Code:
function GetResistanceData(eUnit, bResistance)
	local eResDamageType = "NONE"
	local iValue = 0
	local sUnitType = GameInfo.Units[eUnit].Type
	local sPrefix = "+"
	if bResistance == nil then
		bResistance = false
	end
	if bResistance == false then
		sPrefix = "-"
	end
	for eUnitRes in GameInfo.UnitResistances("UnitType='" .. sUnitType .. "'") do
		--print("[GetDamageInfo] Iterating resistance.")
		print("For Type of " .. eUnitRes.UnitType .. " eUnitRes.Resistance is reported as " .. tostring(eUnitRes.Resistance))
		if eUnitRes.Resistance == bResistance then
			print("[GetDamageInfo] Found Unit's resistance.")
			eResDamageType = eUnitRes.DamageType
			iValue = sPrefix .. eUnitRes.Value
			break
		end
	end
	return eResDamageType, iValue
end

print(" ")
print(" ")
print("[GetDamageInfo] Started...")
print(" ")
print(" ")
local eResDamageType, iValue = GetResistanceData(GameInfoTypes.UNIT_WARRIOR, true)
[color="blue"]print("for UNIT_WARRIOR and bResistance = true, the eResDamageType is " .. eResDamageType .. " and the iValue is " .. iValue)[/color]
local eResDamageType, iValue = GetResistanceData(GameInfoTypes.UNIT_WARRIOR, false)
[color="green"]print("for UNIT_WARRIOR and bResistance = false, the eResDamageType is " .. eResDamageType .. " and the iValue is " .. iValue)[/color]

local eResDamageType, iValue = GetResistanceData(GameInfoTypes.UNIT_BARBARIAN_WARRIOR, true)
[color="red"]print("for UNIT_BARBARIAN_WARRIOR and bResistance = true, the eResDamageType is " .. eResDamageType .. " and the iValue is " .. iValue)[/color]
local eResDamageType, iValue = GetResistanceData(GameInfoTypes.UNIT_BARBARIAN_WARRIOR, false)
[color="magenta"]print("for UNIT_BARBARIAN_WARRIOR and bResistance = false, the eResDamageType is " .. eResDamageType .. " and the iValue is " .. iValue)[/color]
print(" ")
print(" ")
Final Version of the 'Database' code (I had moved over to XML just to confirm there was not some bizarre non-obvious effect from defining the table in SQL):
Code:
<GameData>
	<Table name="UnitResistances">
		<Column name="UnitType" type="text" />
		<Column name="Resistance" type="boolean" default="false"/>
		<Column name="DamageType" type="text" />
		<Column name="Value" type="integer" default="0"/>
	</Table>

	<UnitResistances>
		[color="blue"]<Row UnitType="UNIT_WARRIOR" DamageType="Cold" Resistance="true" Value="10" />[/color]
		[color="green"]<Row UnitType="UNIT_WARRIOR" DamageType="Crushing" Resistance="false" Value="20" />[/color]
		[color="red"]<Row UnitType="UNIT_BARBARIAN_WARRIOR" DamageType="Fire" Resistance="true" Value="15" />[/color]
		[color="magenta"]<Row UnitType="UNIT_BARBARIAN_WARRIOR" DamageType="Piercing" Resistance="false" Value="35" />[/color]
	</UnitResistances>
</GameData>
I altered to using Warriors and Barbarian Warriors so I would not have to define any new units.
 
Spoiler :


Not only did you fix it, but you also provided the reason behind the bug: it is not a primary table.
Now I wonder... how that caused the table to 'mix up'? The answer most surely lies in the DLL, and it's about time I start to delve into this macarronic jungle.

Thank you very much, LeeS!
 
The answer most surely lies in the DLL

It will lie in a DLL, but not the DLL. All the database code is in "CvGameDatabaseWin32Final Release.dll" and we don't have the source code for that one.

The answer lies in the second post of this thread - although I find it strange that the GameInfoTypes magic kicks in for a table without both a Type and an ID column.

Depending on the load order and what's happening with a table with a Type column but without an ID column, you've either set
  • GameInfoTypes.UNIT_WBC_CENTAUR to 1 and GameInfoTypes.UNIT_WBC_CONJURER to 3 - but I think that's highly unlikely
  • GameInfoTypes.UNIT_WBC_CENTAUR to 1 and GameInfoTypes.UNIT_WBC_CONJURER to 3 but they've both been over-ridden by their values from the Units table - but I'd expect this to throw "nil value" errors in your code
  • both GameInfoTypes.UNIT_WBC_CENTAUR and GameInfoTypes.UNIT_WBC_CONJURER to 0 - which I think is more likely
you could find out by printing out their values.
 
Top Bottom