Querying to see if a promotion exists

Kael

Deity
Joined
May 6, 2002
Messages
17,403
Location
Paris, France
Im looking for a way to find out if a unit has a given promotion and how to set a promotion with Python.

The promotion class only looks to have the following function (from PyHelpers.py):

class PromotionInfo:
def __init__(self, iPromotionID):
def getDescription(self):
def getButton(self):
def getCityAttackPercent(self):
def getCityDefensePercent(self):
def getCombatPercent(self):
def getHillsDefensePercent(self):
def getChanceFirstStrikesChange(self):
def getCollateralDamageChange(self):
def getEnemyHealChange(self):
def getFirstStrikesChange(self):
def getFriendlyHealChange(self):
def getNeutralHealChange(self):
def getPrereqPromotionID(self):
def getMoveDiscountChange(self):
def getVisibilityChange(self):
def getWithdrawalChange(self):
def getFeatureDefensePercent(self, iFeature):
def getTerrainDefensePercent(self, iTerrain):
def getFeatureDefenseIDList(self):
def getFeatureDefenseInfoList(self):
def getTerrainDefenseIDList(self):
def getTerrainDefenseInfoList(self):
 
Where CyUnit is your unit entity:

Code:
CyUnit.isHasPromotion(gc.getInfoTypeForString("PROMOTION_BLAHBLAH"))

That will return a true or false for the unit, depending on if it has a promotion or not. You can replace "gc.getInfoTypeForString("PROMOTION_BLAHBLAH")" with the promotion number if you want, but that is far less versitile (if the order of the promotions is changed, it'll lead to the wrong promotion, for example).

Setting a promotion is very similar:

Code:
CyUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_BLAHBLAH"), true).
If you want to remove a promotion, just set "true" to "false"


EDIT: Check out the API at http://civilization4.net/files/modding/PythonAPI/index2.html - I find it very very very useful
 
I am officially naming my first born after you. Since she's already 15 she may object to being renamed 'The Great Apple' but she will have to accept it. I will play with this tonight and see how it works out.
 
Well, I have looked up the functions you mentioned and they seem perfect, but I'm not able to get it to kick. I suspect that the object I am using isn't a valid "unit" object. (bold is my additions, I treid it 2 ways to see if either of the definitions was valid).

def onCombatResult(self, argsList):
'Combat Result'
pWinner,pLoser = argsList
playerX = PyPlayer(pWinner.getOwner())
unitX = PyInfo.UnitInfo(pWinner.getUnitType())
playerY = PyPlayer(pLoser.getOwner())
unitY = PyInfo.UnitInfo(pLoser.getUnitType())
pWinner.setHasPromotion(1, True)
unitX.setHasPromotion(1, True)

if (not self.__LOG_COMBAT):
return
if playerX and playerX and unitX and playerY:
CvUtil.pyPrint('Player %d Civilization %s Unit %s has defeated Player %d Civilization %s Unit %s'
%(playerX.getID(), playerX.getCivilizationName(), unitX.getDescription(),
playerY.getID(), playerY.getCivilizationName(), unitY.getDescription()))

I noticed the following from the Desert War mod:

if bFoundUnit:
iUnit = gc.getGame().getSorenRandNum(len(uValidList), 'Desert War - Random Event Medic Added')
unit = uValidList[iUnit]
unit.setHasPromotion(iMedicI, True)

iMedicI is definied earlier in the file as a number (the offset from the begining of the promotions file). Any Idea how I can get my function to add a promotion to a unit during (or directly after) combat?
 
Kael said:
Well, I have looked up the functions you mentioned and they seem perfect, but I'm not able to get it to kick. I suspect that the object I am using isn't a valid "unit" object. (bold is my additions, I treid it 2 ways to see if either of the definitions was valid).



I noticed the following from the Desert War mod:



iMedicI is definied earlier in the file as a number (the offset from the begining of the promotions file). Any Idea how I can get my function to add a promotion to a unit during (or directly after) combat?

Ack, why do people keep using the "QUOTE" tags for CODE :p. Well, anyways, since I can't show you your code, your problem is that you're trying to getting the wrong object to call the function for. PyInfo.UnitInfo returns a class which does NOT have the sethasPromotion function. Instead, you need an object of the CyUnit class in order to call a sethasPromotion function.

I'm assuming that uValidList is basically a list of CyUnits which is why THAT code works..... I'm not even sure how yours compiles....

Req
 
Requies said:
Ack, why do people keep using the "QUOTE" tags for CODE :p. Well, anyways, since I can't show you your code, your problem is that you're trying to getting the wrong object to call the function for. PyInfo.UnitInfo returns a class which does NOT have the sethasPromotion function. Instead, you need an object of the CyUnit class in order to call a sethasPromotion function.

I'm assuming that uValidList is basically a list of CyUnits which is why THAT code works..... I'm not even sure how yours compiles....

Req

That makes sense. Any idea how I can get to the correct CyUnit object from either of the two events above, or any of the combat events that will let me get a valid CyUnit object?
 
Hmmm, I'm pretty certain pWinner is the correct object type. In one of my mods I successfully gave a promotion to "pWinner".

A few questions (they're simple, because I can't think of any complicated answers):
1) Did you try compiling them both at once? I can see python might not like that!
2) I'm assuming your unit does not already have the second promotion in the xml file, and that the promotion exists?
3) Are you sure the event is triggering?
4) Errr.... I'm fresh out of ideas.
 
Kael said:
That makes sense. Any idea how I can get to the correct CyUnit object from either of the two events above, or any of the combat events that will let me get a valid CyUnit object?

1) Set MessageLog and LoggingEnabled to 1 in your Civ.ini file. I'd bet you're getting an error for "unitX.setHasPromotion." This will let you know if you are in PythonErr.txt. If you're getting an error there, it won't continue to execute the code after that.

Req
 
Requies said:
1) Set MessageLog and LoggingEnabled to 1 in your Civ.ini file. I'd bet you're getting an error for "unitX.setHasPromotion." This will let you know if you are in PythonErr.txt. If you're getting an error there, it won't continue to execute the code after that.

Req
Yes yes yes! You also will want HidePythonExceptions = 0 for certain - then it actually tells you what is going wrong!
 
WooHoo! Thanks guys, it works! Promotions can now be given after combat. You were absolutly right, pWinner and pLoser were the objects I could use. I had a problem moving the CombatResults function into my custom events file, but when I did the mods int he origional file it worked great. I will have to see what it takes to get it into my file, but at least the trick works and I can build units based on the feature.
 
Back
Top Bottom