test if any civ has a tech

wotan321

Emperor
Joined
Oct 25, 2001
Messages
1,228
Location
NC, USA
How do I test to see if any Civ in the game has reached a certain tech?

I'd like to have a mod kick into gear ONLY after a certain tech level has been reached in the game.

Any information is appreciated.
 
In CvEventManager.py you have a function onTechAcquired.

If it's general, all you would have to do is to check:
Code:
if iTechType == gc.getInfoTypeForString("TECH_XYZ"):
then fire what you want. It would be triggered when the first Civ finds the Tech. If another Civ finds it afterwards, you might want to prevent the code to trigger again.

If you have to check if the Tech has been discovered in a game in advanced start mode or else, the code would also have to be a bit more elaborated.
 
Though my question was answered, I didn't ask enough question to resolve my need.

I have merged one of Platyping's updated mods, BarbCivs, into my game. This mod creates new civs from Barbarians. But I also want to use Terra maps, so there is uninhabited land later in the game. BarbCivs starts plopping civs all over the map right away, so I would like to have the mod only start working after cross-ocean travel is possible.

I know only enough Python to stitch together solutions, but I haven't found a way to do what I am trying to do.

Any information is again appreciated.
 
Attached you will find a revised version of the CvEventManager file from Platyping's BarbCiv ModComp.

Look for "Barbarian Civ" to see that I added in some places a variable self.bTechBarbs which is rendered True when a technology TECH_XYZ has been researched.

I did not test it, tell me if it works (or not).
 

Attachments

It seems to be working, there are no python errors. I tacked a textbox onto it and tested it with an early tech, and that part worked.

Thank-you again, I am impressed by your python skills and your graciousness in helping.
 
You're welcome. :)

My Python skills come from copying Platyping's Python... :D
 
If you want to run a check from somewhere else, then you could use this function:

Code:
def hasTechCheck(iPlayer, iTechType):
	# Orion's Standard Functions
	# Returns True if the player has the specified tech type.
	# Returns False if the player does not have the specified tech type.
	pPlayer = gc.getPlayer(iPlayer)
	bTechCheck = False
	
	for iTech in range(gc.getNumTechInfos()):
		if (iTech != TechTypes.NO_TECH):
			# Does the player have this tech?
			if gc.getTeam(pPlayer.getTeam()).isHasTech(iTech):
				if iTech == iTechType:
					bTechCheck = True
					break
	
	return bTechCheck
 
Take note that isenchine method won't work for advanced start games where the tech is granted free.
 
I never play with advanced start, I rather play with "delayed" start... :)

Then the code in 'onLoadGame' should be repeated in 'onGameStart'.

@ OrionVeteran: I guess your alternate method with a specific function is good when you want to check from time to time if this or that Tech has been researched. Here, it would have to be called each turn which is not so good.
 
For Orion method, I frankly speaking don't understand the purpose of it.
What is the purpose of looping through every loop to check if each tech == iTechCheck?
 
For Orion method, I frankly speaking don't understand the purpose of it.
What is the purpose of looping through every loop to check if each tech == iTechCheck?
That's actually a good question. While it does the job, it appears to do lots of stuff it will not have to do, which makes it slow. A quick (untested) edit to improve it:

Code:
def hasTechCheck(iPlayer, iTechType):
	# Orion's Standard Functions
	# Returns True if the player has the specified tech type.
	# Returns False if the player does not have the specified tech type.
	pPlayer = gc.getPlayer(iPlayer)
	[S]bTechCheck = False[/S]
	
	[S]for iTech in range(gc.getNumTechInfos()):[/S]
	[B]if iTechType < gc.getNumTechInfos():[/B]
		[S]if (iTech != TechTypes.NO_TECH):[/S]
		[B]if iTechType != TechTypes.NO_TECH:[/B]
			# Does the player have this tech?
			if gc.getTeam(pPlayer.getTeam()).isHasTech(iTech[B]Type[/B]):
				[B]return True[/B]
				[S]if iTech == iTechType:[/S]
					[S]bTechCheck = True[/S]
					[S]break[/S]
	
	[S]return bTechCheck[/S]
	[B]return False[/B]
That should do the very same thing and should be way faster. Checking for valid pPlayer would make it even safer and should make it impossible to crash the game regardless of arguments. On the other hand, if we skip checking anything and just assume the caller to use correct arguments (could be dangerous), it could be reduced to:
Code:
def hasTechCheck(iPlayer, iTechType):
	# Orion's Standard Functions
	# Returns True if the player has the specified tech type.
	# Returns False if the player does not have the specified tech type.
	pPlayer = gc.getPlayer(iPlayer)
	return gc.getTeam(pPlayer.getTeam()).isHasTech(iTechType)
This is so simple that I would argue that it might not deserve a function.

My own take on this would likely be to make a function, which takes iTechType as argument and then loops all teams, check if they are alive and if so, return true when one is found, which has the tech in question. That shouldn't require lots of lines. Also the only thing, which could go wrong (if coded correctly) would be an out of range tech ID in arguments. This mean it should start by checking if it's >0 && < numTechs and return false if it is.

However isn't there already code for this. I mean isn't there techs, which goes "provides XX to the first civ to discover"? If so, at least the DLL would know the answer. Granted, it's not the same as it would be reachable from python, but it would make sense to check before coding the very same thing again.
 
The simplest answer is to use countKnownTechNumTeams.
One line will do :D
 
Back
Top Bottom