Using CanEverResearch to lock techs...

Ethidium

Chieftain
Joined
Feb 29, 2016
Messages
16
Hi Folks,

I'm trying to make a mod where techs require certain resources (iron working demands that you have iron, horse riding needs horses, etc)

I've written an SQL that adds a prereqResource column to the technologies table, and a lua test that I think will make techs unavailable if and only if the prerequisites are not met. The database definitely updates, but I can't find any evidence in the logs that the lua is being run at all...

Here's my lua:
Spoiler :
function ResourceCheck(iPlayerID, iTechType)
print ('Running Resource checker...') --test to see if it runs at all
local prereqResource = GameInfo.Technologies[iTechType].PrereqResource
if prereqResource then
local pPlayer = Players[iPlayerID]
local resourceID = GameInfo.Resources[prereqResource].ID
local resAvailable = pPlayer:GetNumResourceAvailable(resourceID, true)
if res_total > 0 then
return true
else
return false
end
print ('Tech = 'GameInfo.Technologies[iTechType] ' Status: ' GameEvents.PlayerCanEverResearch) --prints the boolean outcome of CanEverResearch on anything that had a resource dependency
end
return true
print ('Resource Checker finished')
end

GameEvents.PlayerCanEverResearch.Add(ResourceCheck)


and the full mod is hopefully attached. Would greatly appreciate any pointers on what I'm doing wrong here... Thanks in advance.

Thanks also to Pazyryk and Whoward for their extremely helpful posts - that's the only way I got this far!
 

Attachments

Why not just do CanResearch? Whichever. I think it's because you're unable to detect the resources without the technology causing an issue with pPlayer:GetNumResourceAvailable as the resource may be there, but without the discovery, the function can't extract the number out of it preventing any technology from ever being earned.
 
Your Lua contains several errors ... ironically in the debug print statements, and doubly so because neither print can actually be reached!

Code:
function ResourceCheck(iPlayerID, iTechType) 
	print ('Running Resource checker...') --test to see if it runs at all
	local prereqResource = GameInfo.Technologies[iTechType].PrereqResource
	if prereqResource then
		local pPlayer = Players[iPlayerID]
		local resourceID = GameInfo.Resources[prereqResource].ID
		local resAvailable = pPlayer:GetNumResourceAvailable(resourceID, true)
		if res_total > 0 then
			return true
		else
			return false
		end
		[COLOR="red"][B]-- The next line can never be reached, because of the return true and return false lines above
		-- and ironically it has compile time errors, so is causing the entire Lua file to be ignore[/B][/COLOR]
		print ('Tech = 'GameInfo.Technologies[iTechType] ' Status: ' GameEvents.PlayerCanEverResearch) --prints the boolean outcome of CanEverResearch on anything that had a resource dependency
	end
	return true
[B][COLOR="Red"]	-- The next line can never be reached, due to the return above, it needs moving before that line
[/COLOR][/B]	print ('Resource Checker finished')
end

GameEvents.PlayerCanEverResearch.Add(ResourceCheck)

The line
Code:
print ('Tech = 'GameInfo.Technologies[iTechType] ' Status: ' GameEvents.PlayerCanEverResearch)
is either missing commas or .. (string contatenation) between the various bits, eg
Code:
print ('Tech = ' .. GameInfo.Technologies[iTechType] .. ' Status: ' .. GameEvents.PlayerCanEverResearch)
Also GameEvents.PlayerCanEverResearch will print something like function:12345678 and not the result of calling the event - which would need brackets and the correct parameters. However, DO NOT DO THIS as you will end up with an infinite recursive loop!

Finally, the file ResourceChecker.xml is very confused. It is being needless loaded into the VFS manually (VFS=true), however, due to the InGameUIAddin that references ResourceChecker.lua it is also being loaded into the VFS automatically and is expected to be a UI context file. It is also (correctly) being specified as a Database action. This file really needs to be renamed so as not to clash with ResourceChecker.lua

Edit: There may be other logic errors, I didn't check for them.
 
Aha, brilliant. Thanks so much for taking a look at it for me :)

I'll try it with those fixes when I finish work and see if that got everything. How did you spot the compile time errors, please? I didn't see anything in modbuddy or in the logs...

Enginseer - Is that how CanResearch works? I thought that was "player can research right now", whereas canEverResearch is like "this is something that you might ever be able to research". It doesn't do the check before you have the resource, though - I made mining discover iron...

Thanks again for quick feedback!
 
CanResearch() and CanEverResearch() pretty much do the same thing - with one major exception. CanResearch() is ignored by the tech tree, so you can still pick techs in the future that it would otherwise lock, whereas CanEverResearch() will lock out those techs. See the discussion in one of the threads that mentions the "No Tech Tree Beelining" mod by LeeS for further details
 
How did you spot the compile time errors, please?

Using SciTE with the Lua environment - can't remember exactly what I downloaded (edit - but probably something from here), but the main site is here
 
Ok, that looks like progress. I changed the points you highlighted and also changed to CanResearch as Engi suggested... it still doesn't quite work, but now it at least does something. In the log it turns out line after line - it's clearly running many times each turn (as you'd expect), and after a few turns it starts to spit out an error: "attempt to compare number with nil" which is probably the iron showing up as a resource from mining, and me not having any... interesting that it would be listed as nil, not as the number zero, though - maybe I'm wrong about that interpretation.
 
See the discussion in one of the threads that mentions the "No Tech Tree Beelining" mod by LeeS for further details

I did look quite closely at that mod. I'll see if I can find that thread
 
I also do not see where you have defined "res_total " before trying to use it. So that variable looks like it ought always to be evaluated as 'nil' and should always make the line
Code:
if res_total > 0 then
fail in one way or another, most likely an error for attempting to compare 'nil' to a number.

You are defining this variable
Code:
local [COLOR="Blue"]resAvailable[/COLOR] = pPlayer:GetNumResourceAvailable(resourceID, true)
but then never using it anywhere.

I assume you meant to use resAvailable where you instead used res_total.
 
Aha, I did indeed - well spotted! I fixed that and the comparison doesn't fail now - thanks for that. It still lets me research whatever I please, though :/

Should I go back to using CanEverResearch? You used that in your mod, as I recall. I'm currently trying to find the thread Whoward mentioned before, where you discussed this. Is it better for this sort of thing?

-Edit- Yes, that fixes it - the tech is locked now. Has to be CanEverResearch. Just got to speed play through and see if it unlocks as expected...
 
Works like a charm. Thanks all for your help :)

Final version of lua here for reference:
Spoiler :

function ResourceCheck(iPlayerID, iTechType)
print ('Running Resource checker...') --test to see if it runs
local prereqResource = GameInfo.Technologies[iTechType].PrereqResource
if prereqResource then
local pPlayer = Players[iPlayerID]
local resourceID = GameInfo.Resources[prereqResource].ID
local resAvailable = pPlayer:GetNumResourceAvailable(resourceID, true)
if resAvailable > 0 then
return true
else
return false
end
end
print ('Resource Checker finished')
return true
end

GameEvents.PlayerCanEverResearch.Add(ResourceCheck)
 
Back
Top Bottom