max units

username804

I am a meat popcycle
Joined
Aug 26, 2010
Messages
217
Location
The San Francisco of Texas
Hi all! :D

Is there a way to program units to max out based on number of cities?

Such as modifying Archers (numberofcities)*3 for instance? And being able to do that for each unit and making it harder to build 50 battleships for instance for a 4 city civ?

The goal is to deny Stacks of Doom.

for instance, before my crash, I had modified Earth18civs into a total war scenario .

i could never finish it because after taking Britain & Africa, and holding all of North & South America (this is why you play Roosevelt, large empire without communism) I would get bogged down in Eurasia. I could take Paris, but rarely could I produce enough units to break out of Paris. Russia, China, Persia, India, and Mongolia would cavalry spam me to death.

What i thought was funny was hundreds of carriers with no fighters, or scores of galleons for only a handful of catapults.

:goodjob:
 
I'm guessing that the way to do this would be to edit CvGameUtils - in def canTrain(). But you need to do some Python scripting to figure out how many units of the type there already is, and to check it against the cap. Then return a True/False (1/0) depending on the outcome.
 
There doesnt appear to be a way to count live units of a type however (although you can count how many have been built); meaning you would likely have to loop through all the civs live units and count each of a type, which would be bad performance-wise?
 
It can't be THAT much harder to implement than the Cathedral mechanic, where you can't have more than one Christian Cathedral for every four Christian Temples under your control...
 
There is already a PyPlayer.getUnitClassCountPlusMaking function (and also a PyPlayer.getUnitClassCount function, but it's the first one that you want - that one adds in the ones already in city build queues, this one doesn't).

So in canTrain check pPlayer.getUnitClassCountPlusMaking( theUnitClassInQuestion) where pPlayer is the owner of the city trying to train the unit and theUnitClassInQuestion is the unit class of the unit type it is checking (if that wasn't already obvious). If the resulting unit count is already >= the player's city count * 3 then return False, otherwise return True.

Or something like that.
 
There is already a PyPlayer.getUnitClassCountPlusMaking function (and also a PyPlayer.getUnitClassCount function, but it's the first one that you want - that one adds in the ones already in city build queues, this one doesn't).

So in canTrain check pPlayer.getUnitClassCountPlusMaking( theUnitClassInQuestion) where pPlayer is the owner of the city trying to train the unit and theUnitClassInQuestion is the unit class of the unit type it is checking (if that wasn't already obvious). If the resulting unit count is already >= the player's city count * 3 then return False, otherwise return True.

Or something like that.

Oh. Well, thats why Im a python n00b.
 
This is pretty much what you need then (in CvGameUtils.py):
Code:
	def canTrain(self,argsList):
		pCity = argsList[0]
		eUnit = argsList[1]
		bContinue = argsList[2]
		bTestVisible = argsList[3]
		bIgnoreCost = argsList[4]
		bIgnoreUpgrades = argsList[5]
[B]		#city cap code:
		eUnitClass = gc.getUnitInfo(eUnit).getUnitClassType()
		pOwner = gc.getPlayer(pCity.getOwner())
		iNumUnits = pOwner.getUnitClassCountPlusMaking(eUnitClass)
		iNumCities = pOwner.getNumCities()
		return iNumUnits <= iNumCities * 3[/B]
Note that you have to delete or comment out the following line (you can probably leave it after the marked code above however):
Code:
return False
The credit for this really goes to God-Emperor. :king:
Spoiler :
This would be the same code, by the way, all on one line:
Code:
	def canTrain(self,argsList):
		return gc.getPlayer(argsList[0].getOwner()).getUnitClassCountPlusMaking(gc.getUnitInfo(argsList[1]).getUnitClassType()) <= gc.getPlayer(argsList[0].getOwner()).getNumCities() * 3[/B]
 
OK, if I'll give this a try if you can tell me how to make it judge which unit is which.

For example:
unitclass archer = cities * 3

vs

unitclass cavalry = cities/3

for the time being I've set build limits in the xml of 20 units total.

This would suck if I created a massive empire in North and South America and tried to invade Asia, but I've left riflemen alone.

I may get bored and undo the whole thing anyway...
 
You can specify a limit (which is multiplied by the number of cities) for unit classes, and apply a default for those not specified, something like this:
Code:
	def canTrain(self,argsList):
		pCity = argsList[0]
		eUnit = argsList[1]
		bContinue = argsList[2]
		bTestVisible = argsList[3]
		bIgnoreCost = argsList[4]
		bIgnoreUpgrades = argsList[5]
		#city cap code with variable limits:
		iDefault = 3
		dLimits = {	gc.getInfoTypeForString('UNITCLASS_ARCHER') : 4,
				gc.getInfoTypeForString('UNITCLASS_CAVALRY') : 0.3334
				} # add things to this dictionary that should not use the default value
		eUnitClass = gc.getUnitInfo(eUnit).getUnitClassType()
		pOwner = gc.getPlayer(pCity.getOwner())
		iNumUnits = pOwner.getUnitClassCountPlusMaking(eUnitClass)
		iNumCities = pOwner.getNumCities()
		if eUnitClass in dLimits :
			fUnitLimit = dLimits[eUnitClass]
		else:
			fUnitLimit = iDefault
		iLimit = int(iNumCities * fUnitLimit)
		return iNumUnits < iLimit
As-is this should allow 4 archers per city and 0.3334 cavalry per city (rounded down). Everything else is 3 per city, as per the iDefault value.

BTW, I changed the return to use "<" instead of "<=" since that would actually allow 1 more than the calculated limit to be trained. You don't want it to tell you you can still train a unit if the number is already equal to the limit.

Oh, and Danger Will Robinson!
I have not actually tested this code.

You might want to test upgrading units. I think that calls this too, but I'm not sure.
 
This is awesome! When I learned, they just had BASIC.

10 goto line 10

if then, next

that's all I ever learned to do.
 
Back
Top Bottom