Mod-Modders Guide to Fall Further

Can't remember if we actually use PyOnDeath through any promotions, I know that Alcinus uses it for his resurrection capability. Can look at how he works for some ideas there.

I think pyondeath is part of unitinfos. Which would make the closest thing for promotions PythonPostCombatLost?

Here's something that almost works:

Spoiler :

Code:
def onPostCombatLostSurvival(caster):
    pPlayer = gc.getPlayer(caster.getOwner())
    iUnit = caster.getUnitType()
    
    if CyGame().getSorenRandNum(9, "Survival Roll ") >= 1:
        CyInterface().addMessage(caster.getOwner(),True,25,CyTranslator().getText("TXT_KEY_MESSAGE_SURVIVAL", (caster.getName(), )),'',1,'Art/Interface/Buttons/Promotions/Plaguecarrier.dds',ColorTypes(8),caster.getX(),caster.getY(),True,True)
        
#        pPlot = pCaster.plot()
#        pPlot2 = findClearPlot(-1, pCaster.plot())
#        if pPlot2 != -1:
#        newUnit = pPlayer.initUnit(iUnit, pPlot2.getX(), pPlot2.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
        newUnit = pPlayer.initUnit(iUnit, caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
        newUnit.convert(caster)
        newUnit.setDamage(90, False)
        newUnit.finishMoves()
        newUnit.setHasPromotion(gc.getInfoTypeForString('PROMOTION_SURVIVAL'), False)

I don't know if the commented-out plot-changing python works. I *do* know that newUnit.convert(caster) doesn't allow the creation of a new unit. The function works without it, but (obviously) doesn't carry over a unit's promotions.

Oh yeah - for testing purposes the "roll" is set to almost always succeed.
 
This may sound, well, useless but can you make use of icons (as :food:, :commerce: and :hammers:) in the pedia? Specifically, I would like them to show up in the strategy part and above all on the hint that you see when choosing what to build next in a city. Because I want to add buildings modifying the terrain yields and will be using python for these so they want show up in the pedia as part of the building.*

BTW, is there any way to link a promotion to the unit religion instead of the state one? It seems all PrereqReligion in XML are for state...

How can the odds of a unit getting a religion be increased with a building? I know that there exists a global defines but I think it would be nice that some buildings enhance chance of getting a religious unit. In fact, it could be great to weight it by religion. Take a city with OO, no state religion, no religious buildings. It would use base global defines odds. Add state religion and the odds would be increased by 10. Add in the first religious building: add 10 more to odds. Add in Shrine: 20 more to odds. This would do a 60 odds (granted that the global defines odds are untouched). This makes more sense than just 20% odds for such a highly religious city. For cities with two or more religion, it would be a bit more complicated, though. How can I find the code that gives a unit a religion?
 
I have a very weird Problem, maybe someone can help. When I do a canbuild check with an adept to see if he can build a mana mind node I get a true result if he does it on raw mana, but a false result if he tries it on mind mana.
 
You can link to Unit Religion, but if not written yet you'd have to use a python prereq for it, or modify the DLL.

You can use [ICON_FOOD] and associated commands in TXT_KEY entries to get the icons. Some other ones are instead _CHAR (ie - [STRENGTH_CHAR]). To use them from python you have other options, but honestly the text key winds up still being the quickest approach in the end

Code:
	szHelp = localText.getText("TXT_KEY_EVENT_YIELD_CHANGE_BUILDING", (gc.getBuildingInfo(kTriggeredData.eBuilding).getTextKey(), u"+4[ICON_CULTURE]"))

(from some BtS event which adds 4 culture to your building)


Modification to the odds for a unit to get a religion would have to be done in the DLL, or with an onUnitCreated function which checks for them not having a religion already, but then it isn't so much a modification as an additional check. Could also just write your own python function to completely override the default one in the DLL which runs for every unit built and will clear the religion off them if they had one via DLL application.
 
You can link to Unit Religion, but if not written yet you'd have to use a python prereq for it, or modify the DLL.

You can use [ICON_FOOD] and associated commands in TXT_KEY entries to get the icons. Some other ones are instead _CHAR (ie - [STRENGTH_CHAR]). To use them from python you have other options, but honestly the text key winds up still being the quickest approach in the end

Code:
	szHelp = localText.getText("TXT_KEY_EVENT_YIELD_CHANGE_BUILDING", (gc.getBuildingInfo(kTriggeredData.eBuilding).getTextKey(), u"+4[ICON_CULTURE]"))

(from some BtS event which adds 4 culture to your building)


Modification to the odds for a unit to get a religion would have to be done in the DLL, or with an onUnitCreated function which checks for them not having a religion already, but then it isn't so much a modification as an additional check. Could also just write your own python function to completely override the default one in the DLL which runs for every unit built and will clear the religion off them if they had one via DLL application.
Thanks for those answers :goodjob:

Another question: how do I change the yield value of one plot? I searched through python files but couldn't find anything helping me. As of now, I have this:
Code:
		if iBuildingType == gc.getInfoTypeForString('BUILDING_SMOKEHOUSE'):
			iPlains = gc.getInfoTypeForString('TERRAIN_PLAINS')
			iX = pCity.getX()
			iY = pCity.getY()
			for iiX in range(iX-2, iX+3, 1):
				for iiY in range(iY-2, iY+3, 1):
					pLoopPlot = CyMap().plot(iiX,iiY)
					if not pLoopPlot.isNone():
						if not pLoopPlot.isWater():
							if pLoopPlot.getTerrainType() == iPlains:
								iYield = pLoopPlot.calculateNatureYield(YieldTypes.YIELD_FOOD, TeamTypes(pPlayer.getTeam()), False)
What should I do next so that the food is baseFood + 1?
 
Careful with that one, since you want to be able to modify a plot multiple times and this one starts with SET, you probably need to find out what the modification currently is before setting the new value (and include the previous value manually along with the newest changes)
 
Found this in Def ApplySaltpeter in RandomEventInterface.py... Don't remember the event, but it should help. :lol:

Code:
gc.getGame().setPlotExtraYield(loopPlot[1].getX(), loopPlot[1].getY(), YieldTypes.YIELD_COMMERCE, 1)

This one looks like it could be fun. How to impliment such a change into the game to be repeatable (because I love being a builder) yet not broken, however, eludes me.
 
Just tried. The function adds extra yields so no need to worry about the exact amount it makes the tile have. I will have to try if it's possible to use calculateNaturalYields() to revert back to natural yields. Should be possible.

Another thing: the function makes plots outside cultural borders change, which I don't want. I think of adding a check to see if the plot is owned by pPlayer but that would mean that if the player build the building before having her BFC, those extra tiles won't be touched. Basically, the function I gave you higher up is doing the thing on a square range:
Code:
(M)  (P)   M
(M)  (M)  (M)
(C)  (P)  (P)
(W)  (P)  (P)
(W)  (P)   P
Where parenthesis mean "owned", C=City, P=Plains, M=Mountains, W=Water; Even the P and M are touched and gain +1 food.

How to impliment such a change into the game to be repeatable (because I love being a builder) yet not broken, however, eludes me.
This will not really be repeatable. It'd tied to buildings buildable only once, so it'd would be my job to make it not broken. Plus, I still can check if the yields are already too high to be extra-ed.
 
Very Interesting. I would probably modify the dll to allow buildings to modify yieldchanges based on terraintype, they already can do it for water terrain, river terrain etc.

Would solve lots of your problems (culture borders, building destroyed by event and rebuild, events overwriting the extrayield you set, etc.), but I understand that you go for python. good luck, hope you find solutions to all these exceptions.
 
Very Interesting. I would probably modify the dll to allow buildings to modify yieldchanges based on terraintype, they already can do it for water terrain, river terrain etc.

Would solve lots of your problems (culture borders, building destroyed by event and rebuild, events overwriting the extrayield you set, etc.), but I understand that you go for python. good luck, hope you find solutions to all these exceptions.
I would do that if I could. I have trouble learning to mod the dll, though... python is much more friendly for the moment. But if I can do this, I will erase this little python immediately :p
 
Huh. I tried a clunky method: disabling the process of adding extra yields for specific tiles.
Code:
		if iBuildingType == gc.getInfoTypeForString('BUILDING_SMOKEHOUSE'):
			iPlains = gc.getInfoTypeForString('TERRAIN_PLAINS')
			iX = pCity.getX()
			iY = pCity.getY()
			for iiX in range(iX-2, iX+3, 1):
				for iiY in range(iY-2, iY+3, 1):
					pLoopPlot = CyMap().plot(iiX,iiY)
					if not pLoopPlot.isNone():
						if not pLoopPlot.isWater():
							if not pLoopPlot.isPeak():
								if not pLoopPlot.getX() == iX+3 and not pLoopPlot.getY() == iY+3:
									if pLoopPlot.getTerrainType() == iPlains:
										iYield = pLoopPlot.calculateNatureYield(YieldTypes.YIELD_FOOD, TeamTypes(pPlayer.getTeam()), False)
										gc.getGame().setPlotExtraYield(pLoopPlot.getX(), pLoopPlot.getY(), YieldTypes.YIELD_FOOD, 1)
										CyEngine().triggerEffect(gc.getInfoTypeForString('EFFECT_CREATION'), pLoopPlot.getPoint())
I also tried disabling iX+3/iY-2 but it entirely disabled the second line of tile south of the city...
 
Ok, a question.

Is there a way to disallow a spell which a unit has been explicitly allowed?

Specifically, I want to make Drifa the White Dragon unable to breathe fire (tied to the dragon promo) and give her a Breathe Ice spell instead.

I can see this being do-able with a dummy dragon promo that just doesn't allow it, but that seems like a messy solution, and will only get messier as I edit other dragons. Is that the only way?

Or alternately, could I just remove Breathe Fire from the dragon promo entirely, and instead allow it explicitly by name to every other dragon? is there a limit on how many prereq units a spell can have?
 
If you completely disabled the bottom row I imagine that you had disabled iX3/iY-2 the same way you set up each of the rest (with an if(iY != -2) followed by if (iX != 3), instead of a single if not (iX == 3 && iY == -2).


To handle it so that plots previously unowned get updated you would really need to set up a callback for onPlotAcquired which fires any time that the owner of a plot changes. It has sounded like a useful callback so many other times that I will probably add it when I get back to writing code.


For the spell: Yes, your best solution would most likely be to link to unit instead of promotion. Not sure if there is a limit on how many units you can specify, if I haven't written a replacement tag (don't think I did) then you are limited to 1. If that is the case, just link it to a DIFFERENT promotion (or a combination of dragon and some other promotion)
 
Back
Top Bottom