View Full Version : A little modding help


DharmaMcLaren
Feb 09, 2008, 07:22 AM
I'm modding a new civ into FfH (which I may or may not release - at least, I won't unless I can get an image I have permission to use [Cuteunit?]). I've got the civ all set up fine, their unique unit (a panther replacement for the scout which is cheaper and starts hidden, has 4 defensive strength but can't attack) is working, and their unique building, a replacement for the grove, is in the game and working. However, I want to add something to the unique building so that when a unit is produced in the city that has the grove, there's a chance that an additional animal unit will be produced. I've looked through all the XML and can't begin to guess what might be able to do this - I was specifically looking at entries for the CoE Warrens and the Sheaim Planar Gate. Could anyone offer a bit of guidance?

Edit: Also, how would one make a new leader trait to give a new free promotion giving +1 defensive strength and the Subdue Animals promotion to all units?

Farmer Bobathan
Feb 09, 2008, 08:29 AM
I think to get the chance of an extra unit you would have to use python and for your edit go to the civiliztions xml folder and go to civ4traitinfos.xml and I think you would have to split that trait into two different ones to get it to work how you want. Hope this helped :)

DharmaMcLaren
Feb 09, 2008, 09:07 AM
I could just make a promotion combining Subdue Animals and +1 def, I suppose. Python, huh... Oh well, here goes nothing.

MaxAstro
Feb 09, 2008, 11:15 AM
The python for the Warrens building is in cvEventManager.py under "def onUnitBuilt".

Assuming you want to do the same thing, more or less, where the panther is only created if the unit being built is a living non-hero unit, you'd want to copy that block of code and paste it directly below itself. Make sure the spacing stays the same! Python uses tabs to indicate code blocks. Change "BUILDING_WARRENS" to the name of your unique grove (make sure you don't just change it to BUILDING_GROVE, or the code will trigger for all players). Then, in the very last line of the copied code, the one that starts newUnit = pPlayer.initUnit, you'll want to change "unit.getUnitType()" to "gc.getInfoTypeForString('UNIT_PANTHER')", replacing UNIT_PANTHER with whatever your panther unit is called.

So, assuming I haven't screwed anything up, your new block of code (which should be pasted directly below the Warrens code) should look like this:

if city.getNumRealBuilding(gc.getInfoTypeForString('B UILDING_GROVE_UNIQUE')) > 0:
if isWorldUnitClass(unit.getUnitClassType()) == False:
if isNationalUnitClass(unit.getUnitClassType()) == False:
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_SIEGE'):
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_NAVAL'):
newUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_PAN THER'), city.getX(), city.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)


Of course you need to replace BUILDING_GROVE_UNIQUE with whatever your unique grove is called, and UNIT_PANTHER with whatever your panther unit is called. If you wanted to change the code so that it will trigger even on the creation of hero and national units, you'd just have to cut out the relavent if statements and change the spacing to match. That would look something like this:

if city.getNumRealBuilding(gc.getInfoTypeForString('B UILDING_GROVE_UNIQUE')) > 0:
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_SIEGE'):
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_NAVAL'):
newUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_PAN THER'), city.getX(), city.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)


Note that just like the Warrens, this will trigger even on the creation of Workers and Settlers.

MagisterCultuum
Feb 09, 2008, 11:17 AM
It isn't hard to make a trait give multiple promotions to multiple unitcombats, usnig only xml. It won't apply to al units (not great people, settlers, workers, workboats, loki, etc), but it will be given to most of them. You can basically copy heroic defense promotion for your new promotion, but with different requirements probably, and apply both promos. Just create a new trait (and give it to some leader) with this at the end:

<FreePromotions>
<FreePromotion>
<PromotionType>PROMOTION_SUBDUE_ANIMAL</PromotionType>
<bFreePromotion>1</bFreePromotion>
</FreePromotion>
<FreePromotion>
<PromotionType>PROMOTION_NEW_PROMOTION</PromotionType>
<bFreePromotion>1</bFreePromotion>
</FreePromotion>
</FreePromotions>
<FreePromotionUnitCombats>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_MELEE</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_MOUNTED</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_ARCHER</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_NAVAL</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_DISCIPLE</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_SIEGE</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_RECON</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_ANIMAL</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
<FreePromotionUnitCombat>
<UnitCombatType>UNITCOMBAT_BEAST</UnitCombatType>
<bFreePromotionUnitCombat>1</bFreePromotionUnitCombat>
</FreePromotionUnitCombat>
</FreePromotionUnitCombats>

MaxAstro
Feb 09, 2008, 11:20 AM
Note that giving Subdue Animal to Naval units would make your civ the only civ in the game that could easily capture Sea Serpents and Giant Turtles. :)

DharmaMcLaren
Feb 09, 2008, 02:31 PM
Thanks for all the advice with this. What I want to do with the animal-spawning building is have a 6% chance for a bear with every unit produced, a 5% chance for a tiger, a 5% chance for a panther, and a 4% chance for a gorilla.

This is what I (with my total lack of Python knowledge) came up with:

if city.getNumRealBuilding(gc.getInfoTypeForString('B UILDING_VILLALFAR_GROVE')) > 0:
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_SIEGE'):
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_NAVAL'):
if CyGame().getSorenRandNum(100, "Bob") <= 5, >0:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_PANTHER')
if CyGame().getSorenRandNum(100, "Bob") <= 10, >5:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_TIGER')
if CyGame().getSorenRandNum(100, "Bob") <= 14, >10:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_GORILLA')
if CyGame().getSorenRandNum(100, "Bob") <= 20, >14:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_BEAR')

Is this a good base? Does anyone know what's wrong with it? (I imagine that's a resounding "Yes" :blush: )

As for the leader trait, I COULD just make it give Subdue Animal and Heroic Defense 1, but I'd like it to go to ALL units - workers would be able to capture animals if attacked by them (if they won). The whole race are sort of FoL fanatics who place huge importance on attunement with nature, so I'd like it to go to everything except naval units and siege units (I'm pretty sure they can't build siege units anyway - I used the Ljosalfar as a base). I think I need to use Python to give the promotion the animal-taming qualities of Subdue Animal, which is what I'm going to try to tackle next.

MagisterCultuum
Feb 09, 2008, 02:51 PM
Can you do statements like x <= 20, >14 instead of typing out x <= 20 and x> 14? If so, then I've been doing way too much typing...

DharmaMcLaren
Feb 09, 2008, 03:04 PM
Hah, I have absolutely no idea - I just guessed how to do those because there was no example in the rest of the file. >.<

I'll try changing them all to ands... :P

Edit: Predictably, still doesn't work.

MagisterCultuum
Feb 09, 2008, 03:48 PM
I'm not actually sure the "," don't work, but would like to know if they do. You do realize that if you use "and" you will need to repeat the left side, right?

I think I see the real problem is in the .initUnit(), which does not have enough parameters in any of the lines you wrote. it should be like "pPlayer.initUnit(gc.getInfoTypeForString('UNIT_WAR RIOR'), caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)". The first parameter is the type of unit to to initialize, the second is the x coordinate, the third the y coordinate, the forth the ai for the unit (I think I've heard that only only no_unitAI works for some reason), and the direction the unit will face (I don't think that was necessary until BtS)

DharmaMcLaren
Feb 09, 2008, 04:15 PM
All right, here's the new code:

if city.getNumRealBuilding(gc.getInfoTypeForString('B UILDING_VILLALFAR_GROVE')) > 0:
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_SIEGE'):
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_NAVAL'):
if CyGame().getSorenRandNum(100, "Bob") <= 5 and CyGame().getSorenRandNum(100, "Bob") >0:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_PANTHER'), caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
if CyGame().getSorenRandNum(100, "Bob") <= 10 and CyGame().getSorenRandNum(100, "Bob") >5:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_TIGER'), caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
if CyGame().getSorenRandNum(100, "Bob") <= 15 and CyGame().getSorenRandNum(100, "Bob") >10:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_WOLF'), caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
if CyGame().getSorenRandNum(100, "Bob") <= 20 and CyGame().getSorenRandNum(100, "Bob") >15:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_BEAR'), caster.getX(), caster.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)

But it's still not working. The good news is that I just used Subdue Animals and a new promotion to get the leader trait right, and I've got their hero in the game now.

MagisterCultuum
Feb 09, 2008, 04:52 PM
In your case there is no caster (this isn't a spell), so caster.getX() and caster.getY() make no sense.

I think that using either city.getX() and city.getY() or unit.getX() and unit.getY() might fix it. (assuming this code is put in the same place as warrens, these would be the same thing)


Also, there is no panther unit in FfH anymore (unless you added it back)

DharmaMcLaren
Feb 09, 2008, 05:35 PM
It works!... In a way. Now I get a Crown of Akharien for about 50% of units (rather than an animal for the intended 20%). It's a little bizarre.

if city.getNumRealBuilding(gc.getInfoTypeForString('B UILDING_VILLALFAR_GROVE')) > 0:
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_SIEGE'):
if unit.getUnitCombatType() != gc.getInfoTypeForString('UNITCOMBAT_NAVAL'):
if CyGame().getSorenRandNum(100, "Bob") <= 3 and CyGame().getSorenRandNum(100, "Bob") >0:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_GORILLA'), city.getX(), city.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
if CyGame().getSorenRandNum(100, "Bob") <= 8 and CyGame().getSorenRandNum(100, "Bob") >3:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_TIGER'), city.getX(), city.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
if CyGame().getSorenRandNum(100, "Bob") <= 15 and CyGame().getSorenRandNum(100, "Bob") >8:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_WOLF'), city.getX(), city.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
if CyGame().getSorenRandNum(100, "Bob") <= 20 and CyGame().getSorenRandNum(100, "Bob") >15:
newUnit = pPlayer.initUnit(unit.getUnitType() == gc.getInfoTypeForString('UNIT_BEAR'), city.getX(), city.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)

I don't really see how anything in there could be mistakened for a Crown of Akharien...

MagisterCultuum
Feb 09, 2008, 06:09 PM
That mistake is quite amusing, and it confused me at first as to how it was possible. Then I noticed one critical error that I somehow overlooked before (It seems like I find something new every time I read this code)

This time, I noticed that you do not define the unit you want to be give, you check to see if the unit you just built is the same type of unit. The "unit.getUnitType() == gc.getInfoTypeForString('UNIT_GORILLA')" returns a boolean value of false, which can also be read as a 0.


I knew from the BtS pytho API that unit types are, in fact, simple integers, but wasn't sure what kind of number it would be looking for. To find the number associated with the string "xyz" it one uses the call gc.getInfoTypeForString('xyz'). Now I realize that all this does is return the index of where that string is found in a list of units, which is taken directly from CIV4UnitInfos.xml. Since the game can read a value of false as a 0, it looked at index 0 in this list, and so initialized the first unit in CIV4UnitInfos.xml: the crown of Akarien equipment.

If you just built the same type of unit you were trying to initialize (not that these animals are buildable), it would return a true. This would be read as the integer 1, and so it would give you the unit found at index 1 of the list, or second in CIV4UnitInfos.xml, which is the Dragon's Horde equipment.

Case solved.


To fix this bug, replace unit.getUnitType() == gc.getInfoTypeForString('UNIT_GORILLA') with simply gc.getInfoTypeForString('UNIT_GORILLA'), and so on for the other units.

DharmaMcLaren
Feb 09, 2008, 06:35 PM
Thank you so much, Magister! You've been awfully patient with me. It works like a charm now, and my knowledge of Python is enhanced. I might be able to make a UB without help now. >.<
Now I've just got to think of and make a world spell, and this'll be ready for release. I could maybe reskin the Ljosalfar models that I'm currently using, too. And I've got a few Civilopedia entries to write...
Anyway, thanks muchly! 'Twas really nice of you to help, and it's much appreciated! :D

MagisterCultuum
Feb 09, 2008, 07:11 PM
You are welcome. It isn't like I anything else to do (except for a bunch of school work that I should have done by now, but don't feel like starting)


You do not need to do anything with python to make a promotion allow animal taming, just change the <CaptureUnitCombat>NONE</CaptureUnitCombat> to <CaptureUnitCombat>UNITCOMBAT_ANIMAL</CaptureUnitCombat> in your new promotion.

If you still want to give the promotion to all the units you build (including those with no unitcombat, like workers), just put this in the same place as you put the other piece of Python coding:

if pPlayer.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_NEW_CIV'):
if unit.isAlive():
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_NEW_PROMOTION'), True)
but change CIVILIZATION_NEW_CIV to your civ's name and PROMOTION_NEW_PROMOTION to your promotion's name.

The if unit.isAlive() part isn't necessary, itmeans it only applies if it is a living unit, so it won't apply to naval units, siege units, or undead/demon/angels/elementals. Animal handling just doesn't seem appropriate for any of those (well, possibly angels of nature UUs or elementls like treants, but it is easier to ignore that). You might also want to replace the 2 if statements making unitcombat_siege and unitcombat_naval not eligible with one using unit.isAlive() instead.

Note that this will only give the promotion to units you build, not those you start with or gain though events, goody huts, summons, etc. (you could make the promotion apply itself a <PromotionSummonPerk>, if you wanted your summons to have the promotion too)

If you want, you could instead stick with the trait based approach and give your workers, settlers, etc, a unitcombat. You could pick one of the existing ones, like UNITCOMBAT_RECON, or create a new one altogether (I've never done this, but it doesn't look hard. It would just involve adding a couple of lines to to the CIV4UnitCombatInfos.xml in the Basicinfos folder). Note that if you are changing the main unit then you may be giving some free promotions/xp/ability to gain promotions to your rivals units, and if you are creating a UU so as not to give them these boni then you might as well just give yourself a UU that starts with the promotion.

DharmaMcLaren
Feb 09, 2008, 07:32 PM
Ta very much! :D :D :D

If you're ever stuck for something to do again, the model for their palace isn't working. It's the Jade College model here (http://forums.civfanatics.com/showthread.php?t=253212&highlight=jade+college), and I've used JadeCollege.nif as the model, but only the treetops show in colour, the rest is pink. Think you can solve that one, too? :P

MagisterCultuum
Feb 09, 2008, 07:53 PM
Sorry, but I really don't know anything when it comes to making the models/skins/animations/effects/graphics/icons/art for the game. It sounds like you probably know more than me in that area.

My modding knowledge is limited to xml/python. (although when I have the time, maybe over the summer, I may try to teach myself C++ too. It doesn't look that hard, when looking at the code snippets I've seen in the forum instead of the nonsensical complied form.) I typically just refer to preexisting art for all my new buildings/wonders/units/heroes, and have never added custom art except for the female Sidar leader that Cute Unit convinced me to add, since I was provided with the files. You might actually be able to help me with the graphical parts of my modmod more than I could help you. I probably won't try anything fancy at least in the short term, but buttons for new promotions and graphics for new resources would be nice.

DharmaMcLaren
Feb 09, 2008, 08:17 PM
Well, I could certainly try. If there's anything you need, feel free to PM me about it and I'll try my best to help.

xienwolf
Feb 09, 2008, 09:59 PM
Is the shape all correct, just the color is messed up?

MC: Python is VERY similar to C++, so if you are comfy with Python it won't take you too long to get acquainted with C++. You can look through the SDK pre-compiled in the Beyond the Sword\CvGameCoreDLL folder.

DharmaMcLaren
Feb 10, 2008, 05:31 AM
Yep, the shape's just fine. Everything that ought to be there is there, but only the treetops have colour on them. The rest of the building is bright pink.

xienwolf
Feb 10, 2008, 11:36 AM
Well, hopefully the treetop is the WRONG color then, it could just be that your skin is assigned a higher z-plane setting than your model. Doesn't seem like a sound way to design things, but I wouldn't put it past a program to have that flaw.

DharmaMcLaren
Feb 10, 2008, 12:06 PM
It looks like the right colours. As I said, I didn't make the model, it's the Jade College model from the link in page 1. It came with a whole bunch of .nifs and .dds-es, and I'm not sure what they actually do. I just picked the most obvious one.

xienwolf
Feb 10, 2008, 01:49 PM
Well, if you aretistically geared, you can check out White Rabbit's Signature (http://forums.civfanatics.com/member.php?u=76988) for some help files on how you might be able to fix it. Not completely sure, but I think that the .nif is the shape, and the .dds is the color, so check to make certain you nabbed all the appropriate dds files.

DharmaMcLaren
Feb 10, 2008, 01:55 PM
Say, Magister: You know if I wanted to make it so that adepts of my new civ could only use life, spirit, nature, mind, body, earth, air, water and shadow mana, how would I do that?

I thought of making it happen when the unit was made, but I can't quite figure out how... I got as far as "if the building civ is Villalfar, if the unit is of UNITCLASS_ADEPT," and then I couldn't get much further than that. I thought of making a new unit type with XML, but then I thought "Nah, I'd rather do it with one short script in Python".

Edit: Decided to approach this from a different direction. I thought it might be possible to write something triggered at the start of every turn (in Python, not English) like:
"If the building civ is Villalfar,
If the unit has gained enough XP to gain a level (or 'if the unit can gain a promotion')
Do not allow the unit to promote to Chaos 1, Entropy 1, etc."

I made another script to ensure that any unit built that started with any of the promotions that aren't allowed would lose them, so it wouldn't need to include the 2 and 3 levels of that magic type, as it would be impossible for the unit to gain any beyond 1 from promotion.

MagisterCultuum
Feb 10, 2008, 04:01 PM
In the "def onUnitBuilt(self, argsList):" define of CvEventManager.py (the same place as the other changes I showed you), there is this function which gives out free promotions to adepts based on mana:

if unit.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_ADEPT'):
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_AIR'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_AIR1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_AIR2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_BODY'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_BODY1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_BODY2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_CHAOS'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_CHAOS1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_CHAOS2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_DEATH'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_DEATH1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_DEATH2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_DIMENSIONAL'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_DIMENSIONAL1'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_EARTH'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_EARTH1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_EARTH2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_ENCHANTMENT'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_ENCHANTMENT1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_ENCHANTMENT2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_ENTROPY'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_ENTROPY1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_ENTROPY2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_FIRE'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_FIRE1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_FIRE2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_LAW'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_LAW1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_LAW2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_LIFE'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_LIFE1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_LIFE2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_MIND'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_MIND1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_MIND2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_NATURE'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_NATURE1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_NATURE2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_SHADOW'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_SHADOW1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_SHADOW2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_SPIRIT'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_SPIRIT1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_SPIRIT2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_SUN'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_SUN1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_SUN2'), True)
iNum = city.getNumBonuses(gc.getInfoTypeForString('BONUS_ MANA_WATER'))
if iNum > 1:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_WATER1'), True)
if iNum > 2:
unit.setHasPromotion(gc.getInfoTypeForString('PROM OTION_WATER2'), True)


You could add an if pPlayer.getCivilizationType() != gc.getInfoTypeForString('CIVILIZATION_NEW_CIV'): statement before the section that gives out the mana types that you don't want your civ to use would work. (remembering to change the indentations, ect). If I were you, I'd probably rearrange the if statements for each mana type, so that you could use only one added if statement to block all the unwanted promotions.

Bear in mind that if you capture Govannon (can you still capture heroes? I forget. Anyway, you could cheat in world builder to get him) that he could still teach your adepts spells from other spheres.

DharmaMcLaren
Feb 11, 2008, 08:38 AM
That would mean that if you had an Entropy mana node, they could still promote to Entropy 1, though; right? I think I already blocked the script above from working.

MaxAstro
Feb 11, 2008, 11:43 AM
You could always give them a unique adept that was incapable of building certain nodes. They'd still be able to get the mana through trade and wonders, but that's neccessary so a ToM victory isn't impossible with them.

DharmaMcLaren
Feb 11, 2008, 03:22 PM
Okay! At last: everything, except the world spell (which I still need an idea for) and a few minor graphical problems, is working.
As to those few minor graphical problems: There was the one I mentioned above about the palace (I might just use a different model), and there's a new one surrounding the adept replacement/mage replacement. The adept and mage replacements are set to work off the adept and mage art defines, but they appear as human mages rather than Ljosalfar mages, which is what they should be (all the unit models are Ljosalfar). Can anyone offer help with that?

MaxAstro
Feb 11, 2008, 03:24 PM
Are they getting the Elven racial promotion properly? The art defines for the Elven units are set by their racial promotion, not by civ.

DharmaMcLaren
Feb 11, 2008, 03:43 PM
To remedy whatever was causing that problem, I added the PROMOTION_ELF promotion to the replacement units, since the new civ are the only one can build them anyway. Another problem has occured to me: the caster line for my new civ goes:

Preserver -> Warden -> Druid

The problem is, the Druid there is actually a replica of the Druid that replaces the Archmage and can learn spells from spheres other than Life and Nature. The reason that's a problem is that it can be built - meaning that, instead of needing a level 6 Warden to promote to it, it can just be trained in a city. Is there a XML tag for that, or is that done with Python?

MaxAstro
Feb 11, 2008, 03:54 PM
I would imagine there is one of two problems. For one, there is an XML tag somewhere in the unit infos that sets "required level to upgrade to". Check that.

For two, you did give the unique druid a different name other than UNIT_DRUID, right? Because UNIT_DRUID is already used for the actual druid, so creating a duplicate will likely cause problems.

You might want to give a name to your unique druid of something other than Druid...

DharmaMcLaren
Feb 11, 2008, 04:13 PM
UNIT_VILLALFAR_DRUID is the unit's XML name, and its English name is just "Druid", so it appears that the player has 6 druids rather than the usually allowed 3. <iMinLevel>, I think the tag is for "required level to upgrade to" is set to 6, like the Archmage. Maybe I'm just confusing it with the regular, buildable druid. I'll check that.

BeefontheBone
Feb 11, 2008, 04:25 PM
Need a negative hammer cost to prevent building normally. Labelling them something other than Druid seems like a good idea to me, otherwise they're a bit confusing in terms of how you get them - 3 built with groves and 3 upgraded from mages isn't very intuitive.

xienwolf
Feb 11, 2008, 04:27 PM
Beef beat me to it :)

DharmaMcLaren
Feb 11, 2008, 04:59 PM
And I think that I'm now just a placeholder image away from first release. :D

DharmaMcLaren
Feb 15, 2008, 02:35 PM
And I face my first post-release problem. What would a line of Python to check whether the number of animal units in the world is less than 40 look like? Belonging to all players, that is.