[PYTHON] need help w/modified item code

CyrusOrlandeau

Everescan
Joined
Feb 8, 2008
Messages
82
Location
Lost in my head.
I'm not sure where else to post this, so after this question please redirect me to the proper area to post future questions like this. Thank you!

This is my problem: I wanted to make a simple modification to the code for equipments/items so that it would work with regular promotions, for example:

When one unit in a stack has the "Commander" promo, any other unit in the stack can use the "Train" spell, and instead of taking an item from the other unit, it gains a different promo (the "train" promo).
I'm working on something to add to the tower concept earlier, but I'm not sure what exactly is causing the problem in this code. Help is much appreciated, I'm stumped. :confused:

Code:
def reqCommanderOrder(caster,unit):
	if caster.getUnitCombatType() == gc.getInfoTypeForString ('UNITCOMBAT_NAVAL'):
		return False
	if caster.getUnitCombatType() == gc.getInfoTypeForString ('UNITCOMBAT_SIEGE'):
		return False
	if caster.getSpecialUnitType() == gc.getInfoTypeForString ('SPECIALUNIT_SPELL'):
		return False
	if caster.isHasPromotion(gc.getInfoTypeForString ('PROMOTION_ILLUSION')):
		return False
	iUnit = gc.getInfoTypeForString(unit)
	iProm = gc.getUnitInfo(iUnit).getPromotionInfo()
	if caster.isHasPromotion(iProm):
		return False
	iPlayer = caster.getOwner()
	pPlot = caster.plot()
	pHolder = -1
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if (pUnit.getOwner() == iPlayer and pUnit.isHasPromotion (iProm)):
			pHolder = pUnit
	if pHolder == -1:
		return False
	if pHolder.isHasCasted():
		return False
	if pHolder.getUnitType() == gc.getInfoTypeForString ('UNIT_BARNAXUS'):
		if iProm == gc.getInfoTypeForString ('PROMOTION_PIECES_OF_BARNAXUS'):
			return False
	pPlayer = gc.getPlayer(iPlayer)
	if pPlayer.isHuman() == False:
		if caster.baseCombatStr() - 1 <= pHolder.baseCombatStr():
			return False
		if gc.getUnitInfo(pHolder.getUnitType()).getFreePromotions (iProm):
			return False
	return True

def spellCommanderOrder(caster,unit):
	iUnit = gc.getInfoTypeForString(unit)
	iProm = gc.getUnitInfo(iUnit).getPromotionInfo()
	iPlayer = caster.getOwner()
	pPlot = caster.plot()
	pHolder = -1
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if (pUnit.getOwner() == iPlayer and pUnit.isHasPromotion (iProm) and pUnit != caster):
			pHolder = pUnit
	if pHolder != -1:
		caster.setHasPromotion(iProm, True)

-A9A
 
You want a spell that requires a promotion on another unit in the stack, that grants a promotion to the caster? This should work:

Code:
<SpellInfo>
            <Type>SPELL_TRAIN</Type>
            <Description>Train</Description>
            <PromotionInStackPrereq>PROMOTION_COMMANDER</PromotionInStackPrereq>
            <bCasterMustBeAlive>1</bCasterMustBeAlive>
            <bCasterNoDuration>1</bCasterNoDuration>
            <bHasCasted>1</bHasCasted>
            <AddPromotionType1>PROMOTION_TRAIN</AddPromotionType1>
            <bBuffCasterOnly>1</bBuffCasterOnly>
            <Button>Art/Interface/Buttons/Spells/Add to City.dds</Button>
        </SpellInfo>

It prevents Naval, Siege, Summoned units... Also undead, demons, and angels, so if you don't want them blocked you may want to write a quick REQ function to check the unitclasses specifically.

Other than that, it checks the stack for a promotion, then adds a promotion to the caster.

As for where to post questions, I'd be fine with you posting them like you have been... Not enough questions to warrant a modder's thread. :lol:
 
Valkrionn, thank you for the effort, but that's not what I needed. :lol: I already have the XML promotion and spell, what I need is the tweaked code so that the units can cast that spell to get that promo.

Okay, here's the spoiler of what I'm doing. I'm making a Field Commander unit that starts with the 'Field Commander' promo. This is meant to work like the item code, but for multiple promotions.
You know how when one unit has an item an ability pops up on all other units in that stack that allows them to take that item? well, the "Field Commander" is the item, essentially, but instead of taking the item and removing the "Field Commander" promo from the commander and adding it to the other unit, I need it to allow a spell that only adds a different promotion to the caster.
Simple in theory, difficult in execution. I tried tweaking the above code the way I needed it, but it causes my game to crash. I believe the first problem is in the def reqCommanderOrder because i don't see the icon where it should be in game on the other unit in the commander's tile and then it crashes.

Please help, I really am stumped on just exactly what I need to do to get this working.

-A9A
 
You need to show all your work, that includes that xml. You also need to repeat the whole error message you get and ensure that exceptions are turned on. (I have no idea why they are tuned off in the first place.) Being clear about what you actually want to do is also important. Further reading: asking smart questions.

If you do all that it is much easier to home in on the problem, often you'll find it yourself.

That said, my guess is that PyResult in the xml is badly written. You have two arguments to reqCommanderOrder and usually there is only one.


As to what you want to do, my impression is that you want one unit to get a promotion (undisclosed), while another loses another promotion (Commander).

Edit: If all you want to do is give a promotion to units on the tile based on the existence of another promotion on the tile, you don't even need a spell. Just use the prereqs of promotions.
 
From what you've described, I see no reason for you to use any python at all. Valkrionn's xml-only implementation appears far superior.

The whole point of the python part is to remove the equipment promotion from the unit that had it before. If you don't want to remove it, then using <AddPromotionType1> and <bBuffCasterOnly> to give the caster a new promotion is all you need.

I don't really think you need a Field Commander promotion either. From the sounds of it, only a field commander unit can have said promotion, so why not just use <UnitInStackPrereq>UNIT_FIELD_COMMANDER</UnitInStackPrereq> instead of <PromotionInStackPrereq>PROMOTION_FIELD_COMMANDER<PromotionInStackPrereq> and eliminate the superfluous promotion?
 
If the Commander is not intended to LOSE his Commander Promotion (doesn't make much sense that he should), what WarKirby posted does EXACTLY what you describe wanting to do. There needs to be someone with PROMOTION_COMMANDER on the tile, and if there is, you can cast a spell to gain PROMOTION_TRAIN.

Also, unless you modded the DLL, gc.getUnitInfo(iUnit).getPromotionInfo() is not a valid command, and should cause you an error and stop your python well before it actually does anything.
 
If the Commander is not intended to LOSE his Commander Promotion (doesn't make much sense that he should), what WarKirby posted does EXACTLY what you describe wanting to do. There needs to be someone with PROMOTION_COMMANDER on the tile, and if there is, you can cast a spell to gain PROMOTION_TRAIN.

Also, unless you modded the DLL, gc.getUnitInfo(iUnit).getPromotionInfo() is not a valid command, and should cause you an error and stop your python well before it actually does anything.
Yeah, you've come the closest to what I need. I knew the different tag would cause a problem, I just knew that the takeEquipmentPromotion wouldn't correlate exactly with a regular promotion. my sad attempt at fixing it. XP

I don't really think you need a Field Commander promotion either. From the sounds of it, only a field commander unit can have said promotion, so why not just use <UnitInStackPrereq>UNIT_FIELD_COMMANDER</UnitInStackPrereq> instead of <PromotionInStackPrereq>PROMOTION_FIELD_COMMANDER< PromotionInStackPrereq> and eliminate the superfluous promotion?
I'll likely use that for now, but the reason I have the promotion is because I wan to apply the promotion to other units as well for another idea of mine (add-on for the tower I was working on earlier) and so I wanted the promotion to make the rest of my concepts easier to create.

You need to show all your work, that includes that xml. You also need to repeat the whole error message you get and ensure that exceptions are turned on. (I have no idea why they are tuned off in the first place.) Being clear about what you actually want to do is also important. Further reading: asking smart questions.
I'll be sure to improve my queries for the future, I'm sorry I wasn't eryclear, I wasn't sure how to do it the way it needs to be done. Thank you for the link. ^_^

I hope I'm not being difficult, the last thing I want to do is get on someone's nerves.
I'm just trying to get experience and create something at the same time, and sometimes I am a little short-sighted on that subject. ^_^

-A9A
 
I wish. I had some other bugs spring up which I'm still not sure why, but they've been fixed now.
First the terrain defaulted to the regular graphics, then once I finally fixed it I had another recursive error that said it had a problem with UnitClassInfos. I had to trial-and-error it down to what was causing it by replacing the files with those from FF+, then adding in my changes bit by bit. I did keep a backup of my changes so this wouldn't happen, but somehow it got screwed up too with that graphic problem. :cringe:

Anyways, so now I can finally see if the code and what not will work. Meantime I have a friend who I promised to play a few games with online and I was trying to debug at the same time. Maybe now I can have a little peace, of mind that is. :lol:

-A9A
 
Back
Top Bottom