Era - how to find?

Joined
Jul 5, 2004
Messages
23,562
Location
Canberra, Australia
Can you find out what the "barbarian unit era is, ie what tells the game to produce random barbarians of sufficient strength to be a challenge in the game? Prompted by the swarms currently forming here in Australia.

I am back trying to get locust unit by Lord Tirian in game. I don't want the units to be built by anyone, barbarians included, so I need python to add some of them each turn. It works, but I have not figured out a way of choosing a swarm to match the strength of the defenders...
 
Barbarian unit production is AFAIK only determined by the barbarian tech level, so nothing special there :dunno:.

So if I can find out the era the barbarians are in I should be able to find the era I need for these units.

Humm... so that is probably
Code:
iEra = gc.getPlayer(gc.getBARBARIAN_PLAYER()).getCurrentEra()

thanks.
 
Era isn't relevant for units though, you should be checking the techs.
 
Player era is defined by their Techs, not?
 
No, not at all. You can call the team from the player, then loop through techs using gc.getNumTechInfos() and build a list of techs the player has, then use that list to figure out the valid units that are trainable for the player. Hell RevolutionDCM has a function right now I've added to CvPlayer, exposed to python, that allows you to call the best trainable unit type by UNIT_AI.

Also if you're planning on building a modcomp that you want usueable for other mods, I strongly recommend you work with the RevolutionDCM core, or the BUG mod, and set it up as a BUG module. Ensure you write the code so that values/techs/units/etc are pulled using softcoded techniques so that it can be easily plugged into any other mod that uses a RevolutionDCM or even better, BUG mod core.
 
I think the new function RevDCM added would work for you pretty well. I am assuming you can use a UNITAI type to select the unit as the best unit. For instance, here is an example of the function being used to select the best scout unit to spawn for a player during a revolution:

Code:
iScout = pRevPlayer.getBestUnitType(UnitAITypes.UNITAI_EXPLORE)
...
if(iScout != -1):
	pRevPlayer.initUnit( iScout, revSpawnLoc[0], revSpawnLoc[1], UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH )

Pretty slick huh?

If you want to see how the function CvPlayer::getBestUnitType works, check out the source. But I think this python function added to the RevDCM core (and thus in RoM: AND) will work for you.
 
If a pure Python fix is desired it wouldn't be hard at all to achieve.
Spoiler :
Map some variety of the Locust unit to each era, like with a list, a tuple or even a dictionary. Then get the current game era with CyGame.getCurrentEra(). You could have this helper funciton with a list array setup:
Code:
def getLocustType():
	lLocustEra = [ gc.getInfoTypeForString("UNIT_LOCUST1"), 
                       gc.getInfoTypeForString("UNIT_LOCUST1"), 
                       gc.getInfoTypeForString("UNIT_LOCUST2"), 
                       gc.getInfoTypeForString("UNIT_LOCUST3"), 
                       gc.getInfoTypeForString("UNIT_LOCUST4"), 
                       gc.getInfoTypeForString("UNIT_LOCUST4") ]
	iGameEra = CyGame().getCurrentEra
	return lLocustEra[iGameEra]
 
I think the new function RevDCM added would work for you pretty well. I am assuming you can use a UNITAI type to select the unit as the best unit. For instance, here is an example of the function being used to select the best scout unit to spawn for a player during a revolution:

Code:
iScout = pRevPlayer.getBestUnitType(UnitAITypes.UNITAI_EXPLORE)
...
if(iScout != -1):
	pRevPlayer.initUnit( iScout, revSpawnLoc[0], revSpawnLoc[1], UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH )

Pretty slick huh?

If you want to see how the function CvPlayer::getBestUnitType works, check out the source. But I think this python function added to the RevDCM core (and thus in RoM: AND) will work for you.

Very slick!:goodjob: So I would need to create a new UNITAI type. Although I have one question - does this work for units which can't be built i.e. have iCost of -1?

If a pure Python fix is desired it wouldn't be hard at all to achieve.
Spoiler :
Map some variety of the Locust unit to each era, like with a list, a tuple or even a dictionary. Then get the current game era with CyGame.getCurrentEra(). You could have this helper funciton with a list array setup:
Code:
def getLocustType():
	lLocustEra = [ gc.getInfoTypeForString("UNIT_LOCUST1"), 
                       gc.getInfoTypeForString("UNIT_LOCUST1"), 
                       gc.getInfoTypeForString("UNIT_LOCUST2"), 
                       gc.getInfoTypeForString("UNIT_LOCUST3"), 
                       gc.getInfoTypeForString("UNIT_LOCUST4"), 
                       gc.getInfoTypeForString("UNIT_LOCUST4") ]
	iGameEra = CyGame().getCurrentEra
	return lLocustEra[iGameEra]

I looked in the doco for getCurrentEra() and it says it is only on CyPlayer. It does not mention one ob CyGame. Your code almost matches what I was trying for, but then you were involved in teaching me about dictionaries!
 
I looked in the doco for getCurrentEra() and it says it is only on CyPlayer. It does not mention one ob CyGame.
You realize that you're using the API for Warlords? The BtS one is found here.

Note however that there is a difference between game era and player era.

Your code almost matches what I was trying for, but then you were involved in teaching me about dictionaries!
And that was a bad thing, I reckon? :p

A list works just as well, as you can see, as it is indexable with integer enums like EraType values. Its a good think I didn't go for the dictionary option, then. You might just have learned something. :rolleyes:
 
No I did not realise I was using the Warlords version! It may explain why somethings did not work in my various dropped mods :(.

I have to go for a dictionary type option because the eras and hence era number are not in order in "Rise of Mankind" or "Next War Advanced". That and the fact that I decided that locusts and humans live in harmony in the post modern eras ;).
 
What specifically are you trying to do?
 
I don't see why you have to use a dictionary, but the benefit of using a dictionary would be that you don't need to define every era. Instead you can use some default value.
Spoiler :
Code:
def getLocustType():
	"""Returns the appropriate Locust type for the current game era.
	Returns -1 in the modern era."""
	iDefaultLocust = gc.getInfoTypeForString("UNIT_LOCUST1")
	locustDict = { 2: gc.getInfoTypeForString("UNIT_LOCUST2"), 
                       3: gc.getInfoTypeForString("UNIT_LOCUST3"), 
                       4: gc.getInfoTypeForString("UNIT_LOCUST3"), 
                       5: -1 }
	iGameEra = CyGame().getCurrentEra()
	iLocust = locustDict.get(iGameEra, iDefaultLocust)
	return iLocust
The code calling this function would of course have to be able to handle the returned -1 value:
Code:
iLocustType = getLocustType()
if iLocustType > -1:
	CvUtil.spawnUnit(iLocustType, pPlot, pPlayer)
Note that you get access to the spawnUnit function by importing the CvUtil module. :king:
 
Top Bottom