Mod-Modders Guide to Fall Further

Does <PythonPostCombatWon> in PromotionInfos work? Trying to use it, getting this error...

Edit: Here's the code I'm using, bottom of SpellInterface.

Code:
def postCombatScavenger(pCaster, pOpponent):
	if pOpponent.isAlive():
		pCaster.setHasPromotion(gc.getInfoTypeForString('PROMOTION_SCAVENGER'), True)
 
I'm apparently getting a syntax error with the first line of this code block... I don't see what's wrong with it.

Code:
def spellDovielloDuel(caster):
	pPlot = caster.plot()
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		iRnd = CyGame().getSorenRandNum(100, "Doviello Duel")
		if pUnit.getID() != caster.getID() and pUnit.getUnitType() == caster.getUnitType() and pUnit.getOwner() == iOwner:					
			if iRnd < 43:
				caster.changeExperience(pUnit.getExperienceTimes100() / 4, -1, False, False, False)
				caster.setDamage(25, caster.getOwner())
				CyInterface().addMessage(caster.getOwner(),True,25,CyTranslator().getText("TXT_KEY_MESSAGE_DOVIELLO_DUEL_WIN", ()),'',1,'Art/Interface/Buttons/Buildings/Arena.dds',ColorTypes(8),caster.getX(),caster.getY(),True,True)
				pUnit.kill(True, PlayerTypes.NO_PLAYER)
			if (iRnd >=43 and iRnd < 86):
				pUnit.changeExperience(caster.getExperienceTimes100() / 4, -1, False, False, False)
				pUnit.setDamage(25, pUnit.getOwner())
				CyInterface().addMessage(caster.getOwner(),True,25,CyTranslator().getText("TXT_KEY_MESSAGE_DOVIELLO_DUEL_LOSS", ()),'',1,'Art/Interface/Buttons/Buildings/Arena.dds',ColorTypes(8),caster.getX(),caster.getY(),True,True)
				caster.kill(True, PlayerTypes.NO_PLAYER)
			if (iRnd >=86 and iRnd < 96):
				caster.changeExperience(pUnit.getExperienceTimes100() / 10, -1, False, False, False)
				caster.setDamage(75, caster.getOwner())
				pUnit.changeExperience(caster.getExperienceTimes100() / 10, -1, False, False, False)
				pUnit.setDamage(75, pUnit.getOwner())
				CyInterface().addMessage(caster.getOwner(),True,25,CyTranslator().getText("TXT_KEY_MESSAGE_DOVIELLO_DUEL_DRAW", ()),'',1,'Art/Interface/Buttons/Buildings/Arena.dds',ColorTypes(8),caster.getX(),caster.getY(),True,True)
			else:
				CyInterface().addMessage(caster.getOwner(),True,25,CyTranslator().getText("TXT_KEY_MESSAGE_ARENA_DEATH", ()),'',1,'Art/Interface/Buttons/Buildings/Arena.dds',ColorTypes(7),caster.getX(),caster.getY(),True,True)
				caster.kill(True, PlayerTypes.NO_PLAYER)
				pUnit.kill(True, PlayerTypes.NO_PLAYER)
 
Ha. I'm a moron, apparently... The error actually had nothing to do with the code I posted. It was from
Code:
def postCombatScavenger(argsList):
	if pOpponent.isAlive():
		pCaster.setHasPromotion(gc.getInfoTypeForString('PROMOTION_SCAVENGER'), True

Since the pythonpostcombatwon function doesn't work in the current patch, it messed up my later additions when I forgot to delete the function. :p
 
I'd want to add a new tag for BuildingInfos.xml that would enable buildings to modify any plot yield or terrain specific plot yield in the BFC of the city they're built in. Kinda like the RiverPlot changes but for other plots. I've looked in the python and source files but I can't get through this. I found several mention of RiverPlot, getYieldInfo, getCityChange, etc. but I never seem to find anything that actually change or specify yields.

I'm not asking anyone to do this instead of me, I mostly want to understand how I could do it, if it's too complicated (and thus if there is a easier way to do so) or if it has bad consequences I've not thought of.

BTW, it's for Orbis, but I'd like to have your opinion on this :)
 
Your best approach is probably to come in through CvPlot::calculateNatureYields or whatever the function is called. The one which decides the base value of the tile. If you look at how the Illians (and now numerous others) adjust the yields for their favored terrain, that'll point you at the right function for making the tile worth a different amount.


Then instead of making the check which is in place (see if the CvPlayer object wants to change values) you would instead check for getWorkingCity() != NULL, and if so, then check the CvCity object to see if it wants to change values.
 
Having some issues with limiting my spell. Trying to have it check for an effect promo, and if it finds it, the spell cannot be cast. Sadly, it's disabling the spell completely... What am I doing wrong?
Code:
def reqDovielloChallenge(caster):
	pPlot = caster.plot()
	iChallenger = gc.getInfoTypeForString('PROMOTION_CHALLENGER')
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.isHasPromotion(iChallenger) == True:					
			return False
 
Ok, I'm trying to add a new hero for the Bannor. Hopefully entirely in an xml module.

The things I want him to have.
things I'm not entirely sure about.


Where are all the text keys?

As far as I can tell, I have to fill in 3 things

Description
Pedia
Strategy


I'd presume the former, is the mouseover "Sid's Tips" that you get ini the city screen
The second one is obvious
And the latter, is for the popup that appears when a hero is built?

Where are all these stored?

Also, how can I make him a world unit. I don't see a <bWorldUnit> tag or anything of that sort in sphener's xml, which is what I'm using as a template.
 
Description - Name.
Pedia - Pedia.
Strategy - For a unit, also Pedia. Simply strategy for how to use it, rather than flavour text.

If you want a module, just copy a text file, wipe it of all entries, add yours, and rename it Sabathiel_Civ4GameText.xml.

To make him a world unit, you'll have to add a unitclass for him.

Code:
<UnitClassInfo>
	<Type>UNITCLASS_SABATHIEL</Type>
	<Description>TXT_KEY_UNIT_SABATHIEL</Description>
	<iMaxGlobalInstances>1</iMaxGlobalInstances>
	<iMaxTeamInstances>-1</iMaxTeamInstances>
	<iMaxPlayerInstances>-1</iMaxPlayerInstances>
	<iInstanceCostModifier>0</iInstanceCostModifier>
	<bUnique>1</bUnique>
	<DefaultUnit>UNIT_SABATHIEL</DefaultUnit>
</UnitClassInfo>

By setting the bUnique tag to 1, you only have to add him to the Bannor civilization infos.

Code:
<Unit>
	<UnitClassType>UNITCLASS_SABATHIEL</UnitClassType>
	<UnitType>UNIT_SABATHIEL</UnitType>
</Unit>
 
Ah yes, that other problem

How to make him only buildable by the bannor? Is it possible to do this in a modular manner?


Also, how can I make him build x% faster with Law Mana ?
 
Setting the <bUnique> tag on his unitclass, and adding him to the Bannor civilization info like I showed, will make him only buildable by the Bannor.

For the production bonus, add
Code:
<BonusProductionModifiers>
	<BonusProductionModifier>
		<BonusType>BONUS_MANA_LAW</BonusType>
		<iProductonModifier>x</iProductonModifier>
	</BonusProductionModifier>
</BonusProductionModifiers>
Replace x with whatever bonus you want.
 
Having some issues with limiting my spell. Trying to have it check for an effect promo, and if it finds it, the spell cannot be cast. Sadly, it's disabling the spell completely... What am I doing wrong?
Code:
def reqDovielloChallenge(caster):
    pPlot = caster.plot()
    iChallenger = gc.getInfoTypeForString('PROMOTION_CHALLENGER')
    for i in range(pPlot.getNumUnits()):
        pUnit = pPlot.getUnit(i)
        if pUnit.isHasPromotion(iChallenger) == True:                    
            return False

This one is easy: you never told it to return true if the promotion was not found. Just add return true after the for loop and it should work perfectly.

(Also, there is no need to use == True. Just using if pUnit.isHasPromotion(iChallenger): would work just as well.)
 
Yep, tried that before I posted here. :p Doesn't work with this either... Even if I remove == True.

Code:
def reqDovielloChallenge(caster):
	pPlot = caster.plot()
	iChallenger = gc.getInfoTypeForString('PROMOTION_CHALLENGER')
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.isHasPromotion(iChallenger) == True:					
			return False
	return True

Hell, I even tried introducing a variable, increasing it by one if it finds the promotion, and then blocking the spell if the variable > 0....

Edit: You know, I probably have the return True in the wrong location, don't I....

Edit2: Nope. This version doesn't work either.

Code:
def reqDovielloChallenge(caster):
	pPlot = caster.plot()
	iChallenger = gc.getInfoTypeForString('PROMOTION_CHALLENGER')
	for i in range(pPlot.getNumUnits()):
		pUnit = pPlot.getUnit(i)
		if pUnit.isHasPromotion(iChallenger) == True:					
			return False
		return True
 
Oh holy hell. Yeah, I'm a moron. XML error.... Had <PyRequirement>reqDovielloChallenge</PyRequirement> rather than <PyRequirement>reqDovielloChallenge(pCaster)</PyRequirement>

Working perfectly now. I'd never have noticed it... Thought it was a python screwup. :lol:

Now to make it require at least one other unit in the stack...

Edit: Got that working as well. Even better, turns out that even if you try to cast it with the entire stack, only the first unit will actually be able to. No getting around the one unit per stack limit. :goodjob:
 
Back
Top Bottom