Python Unit Creation & Starting Promotions

westamastaflash

Lord Commander
Joined
Nov 1, 2007
Messages
933
When creating a unit via python, is there a way to tell the system *not* to give the unit the traits of the Civilization?

I didn't see a function that does a "clear all promotions" or "give me a list of promotions"...

So I wrote some code that goes through all the promotions and removes them all, then adds the ones that I want.

Code:
	newUnit = pPlayer.initUnit(standardMeleeUnit, caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_NORTH)
                	
        def clearAllPromotions(objUnit):
               def clearPromotion(iPromotion):
        		objUnit.setHasPromotion(iPromotion, False)
        	map(clearPromotion, range(0, gc.getNumPromotionInfos() - 1))
        
        # Clear Promotions
        clearAllPromotions(newUnit)

Is there any other way to do this that doesn't require the map?
 
I can't say for certain that there is no better function, but mimics go through all possible promotions to get a list of the defeated units promotions.

Your code looks very strange to me though. Creating a new function each time you want to remove promotion and using map instad of a for-loop. Also, deducting one from gc.getNumPromotionInfos() should mean you miss removing whatever promotion happens to be last. Unlikely to matter on new units, but still...

Assuming gc is a global bound to the global context manager:
Code:
def clearAllPromotions(objUnit):
    for iPromotion in range( gc.getNumPromotionInfos() ):
        objUnit.setHasPromotion(iPromotion, False)

Should work.
 
Heh, I'm used to functional programming & code reuse - having that function there means I can put it somewhere else (outside in an include or something and map it if I want to.)

Also, I read that using map is faster than a for loop...

Wait, so lists in python are indexed from 1, not 0?
 
Is there any other way to do this that doesn't require the map?

"newUnit.SetHasPromotion(gc.getInfoTypeForString('PROMOTION_SUPERDWARFSMASHA'), False)" (or whatever) for each Promotion you don't want that the unit might have?

Though I think there's a "Race" function that could get all the racial promotions.

Someone who actually knows this stuff should be along soonish.
I'm taking up an ambush position. It counts as a hit if Xienwolf posts just after this...
:hammer:
 
Python isn't my Territory, but I'll give you your hit if you want it :)


Best approach I know of to do this from Python is the loop or map to cycle all promotions in the game and clear them off. Or to query the unit itself for what free promotions he had. You still wind up doing a full loop of the promotions though in that case, as you have to query one by one.

Complication you'll run into is that from what I have been reading, 3.17 introduced the ability to have access to any promotion which you started with when you level up, even if you are not normally able to acquire such a promotion with XP (racial Promotions mostly, but also Losha's Immortality and some Goody Hero fellow's Recruiter, any Hero's Equipment). This would wind up applying in your case here as well I imagine, unless Kael already fixed that up.
 
There is a quote about premature optimization...

Lol!

Thanks. I'm not a python coder (I'm from a VB / PL/SQL / Objective-C background) so I'm jumping in feet first to see how I do. I'll probably write crazy code that breaks all the object oriented rules. I'm still figuring out scope in python (what's this crazy "global" keyword!!)
 
Complication you'll run into is that from what I have been reading, 3.17 introduced the ability to have access to any promotion which you started with when you level up, even if you are not normally able to acquire such a promotion with XP (racial Promotions mostly, but also Losha's Immortality and some Goody Hero fellow's Recruiter, any Hero's Equipment). This would wind up applying in your case here as well I imagine, unless Kael already fixed that up.

Strange, I leveled up a warrior to xp 730 and didn't see the racial promo anywhere. I guess it only happens on certain units? and it looks like .33 fixes the equipment issue?
 
global means it is a variable which can be used in any function throughout that file IIRC.


If you have dealt with C before, I'd say you really ought to just jump straight to working with the DLL anyways :) You can do more, and you break less.

And yes, it appears that 33 fixes the issue. It only would have come up for your Warrior if he was supposed to have started with a racial Promo, and instead started with another, which isn't really possible, and I don't think any warriors have defined racial Promotions for starting. It mostly just comes up with Summons who are granted Illusion.
 
I had Svartalfar units starting with dark elf...

Oh and I rewrote my clearAllPromotions function:
Code:
	def clearAllPromotions(pUnit):
		map(lambda iPromotion : pUnit.setHasPromotion(iPromotion, False), range(gc.getNumPromotionInfos()))

Now if only python let you attach methods arbitrarily to objects like Javascript does, then I could attach this to CvUnit and then call pUnit.clearAllPromotions!
 
Now if only python let you attach methods arbitrarily to objects like Javascript does, then I could attach this to CvUnit and then call pUnit.clearAllPromotions!

Python does. Unless CvUnit specifically disallows it.

Try:
Code:
whateverModuleCvUnitComesFrom.CvUnit.clearAllPromotions = clearAllPromotions
(You need to attach the function to the class.)

Then "pUnit.clearAllPromotions()" should clear them all.

If you get an AttributeError (or possibly TypeError) from the assignment it means that CvUnit doesn't have a __dict__ and so can't receive new attributes.

I have never done it myself, so I may have missed something, but that is the way I read it should work.
 
Python does. Unless CvUnit specifically disallows it.

Try:
Code:
whateverModuleCvUnitComesFrom.CvUnit.clearAllPromotions = clearAllPromotions
(You need to attach the function to the class.)

Then "pUnit.clearAllPromotions()" should clear them all.

If you get an AttributeError (or possibly TypeError) from the assignment it means that CvUnit doesn't have a __dict__ and so can't receive new attributes.

I have never done it myself, so I may have missed something, but that is the way I read it should work.

I think CvUnit is part of the CvPythonExtensions C++ library that is imported to python (or something like that).

I'll give it a try though.
 
Top Bottom