You can't just add new XML fields without telling the game what to do with them in the SDK. That's what you need to edit for the desired effect.
<?xml version="1.0"?>
<!-- edited with XMLSPY v2004 rel. 2 U (http://www.xmlspy.com) by Jesse Smith (Firaxis Games) -->
<!-- Sid Meier's Civilization 4 -->
<!-- Copyright Firaxis Games 2005 -->
<!-- -->
<!-- Yield Infos -->
<Civ4YieldInfos xmlns="x-schema:CIV4TerrainSchema.xml">
<YieldInfos>
<YieldInfo>
<Type>YIELD_FOOD</Type>
<Description>TXT_KEY_YIELD_FOOD</Description>
[B]<iHillsChange>-1</iHillsChange>[/B]
<iPeakChange>0</iPeakChange>
<iLakeChange>1</iLakeChange>
<iCityChange>0</iCityChange>
<iPopulationChangeOffset>0</iPopulationChangeOffset>
<iPopulationChangeDivisor>0</iPopulationChangeDivisor>
<iMinCity>2</iMinCity>
<iTradeModifier>0</iTradeModifier>
<iGoldenAgeYield>0</iGoldenAgeYield>
<iGoldenAgeYieldThreshold>0</iGoldenAgeYieldThreshold>
<iAIWeightPercent>100</iAIWeightPercent>
<ColorType>COLOR_YIELD_FOOD</ColorType>
<SymbolPaths>
<SymbolPath>Art/Interface/Symbols/Food/Food01.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Food/Food02.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Food/Food03.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Food/Food04.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Food/Food05.nif</SymbolPath>
</SymbolPaths>
</YieldInfo>
<YieldInfo>
<Type>YIELD_PRODUCTION</Type>
<Description>TXT_KEY_YIELD_PRODUCTION</Description>
[B] <iHillsChange>1</iHillsChange>[/B]
<iPeakChange>0</iPeakChange>
<iLakeChange>0</iLakeChange>
<iCityChange>0</iCityChange>
<iPopulationChangeOffset>0</iPopulationChangeOffset>
<iPopulationChangeDivisor>0</iPopulationChangeDivisor>
<iMinCity>1</iMinCity>
<iTradeModifier>0</iTradeModifier>
<iGoldenAgeYield>1</iGoldenAgeYield>
<iGoldenAgeYieldThreshold>1</iGoldenAgeYieldThreshold>
<iAIWeightPercent>110</iAIWeightPercent>
<ColorType>COLOR_YIELD_PRODUCTION</ColorType>
<SymbolPaths>
<SymbolPath>Art/Interface/Symbols/Production/Production01.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Production/Production02.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Production/Production03.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Production/Production04.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Production/Production05.nif</SymbolPath>
</SymbolPaths>
</YieldInfo>
<YieldInfo>
<Type>YIELD_COMMERCE</Type>
<Description>TXT_KEY_YIELD_COMMERCE</Description>
<iHillsChange>0</iHillsChange>
<iPeakChange>0</iPeakChange>
<iLakeChange>0</iLakeChange>
<iCityChange>0</iCityChange>
<iPopulationChangeOffset>0</iPopulationChangeOffset>
<iPopulationChangeDivisor>0</iPopulationChangeDivisor>
<iMinCity>1</iMinCity>
<iTradeModifier>100</iTradeModifier>
<iGoldenAgeYield>1</iGoldenAgeYield>
<iGoldenAgeYieldThreshold>1</iGoldenAgeYieldThreshold>
<iAIWeightPercent>80</iAIWeightPercent>
<ColorType>COLOR_YIELD_COMMERCE</ColorType>
<SymbolPaths>
<SymbolPath>Art/Interface/Symbols/Commerce/Commerce01.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Commerce/Commerce02.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Commerce/Commerce03.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Commerce/Commerce04.nif</SymbolPath>
<SymbolPath>Art/Interface/Symbols/Commerce/Commerce05.nif</SymbolPath>
</SymbolPaths>
</YieldInfo>
</YieldInfos>
</Civ4YieldInfos>
Not really. There are Python overrides for many of the things the AI do. What they choose to tech, build, train, etc. Sure it's not many groundbreaking things you can do to change the AI but you can do a lot, like how they move around certain units. But I do agree with you, it's better, and faster if done in SDK, and there are so much more you can do.Plus, if you want to touch the AI, you NEED to be in the DLL.
def changeOwner(self, pUnit, iNewOwner):
pType = gc.getUnitInfo(pUnit.getUnitType()).getType()
pPlot = pUnit.plot()
pPlayer = gc.getPlayer(iNewOwner)
pNewUnit = pPlayer.initUnit(gc.getInfoTypeForString(pType),pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
pNewUnit.convert(pUnit)
return pNewUnit
barbPlayer = gc.getBARBARIAN_PLAYER()
pChanged = self.changeOwner(caster, barbPlayer)
I think your issue is probably that you are creating a unit in the same tile as a visible defender. Since the Barbarian and the other unit are at war with each other, red flags fly up during CvUnit::setXY() because it detects an enemy which CAN defend in the tile.
if (pLoopUnit != NULL)
{
if (isEnemy(pLoopUnit->getTeam(), pNewPlot) || pLoopUnit->isEnemy(getTeam()))
{
if (!pLoopUnit->canCoexistWithEnemyUnit(getTeam()))
{
if (NO_UNITCLASS == pLoopUnit->getUnitInfo().getUnitCaptureClassType() && pLoopUnit->canDefend(pNewPlot))
{
//FfH: Modified by Kael 12/30/2008
// pLoopUnit->jumpToNearestValidPlot(); // can kill unit
if (!isInvisible(pLoopUnit->getTeam(), false))
{
pLoopUnit->jumpToNearestValidPlot(); // can kill unit
}
//FfH: End Modify
}
else
{
//FfH Hidden Nationality: Modified by Kael 08/27/2007
// if (!m_pUnitInfo->isHiddenNationality() && !pLoopUnit->getUnitInfo().isHiddenNationality())
if (!isHiddenNationality() && !pLoopUnit->isHiddenNationality())
//FfH: End Modify
{
GET_TEAM(pLoopUnit->getTeam()).changeWarWeariness(getTeam(), *pNewPlot, GC.getDefineINT("WW_UNIT_CAPTURED"));
GET_TEAM(getTeam()).changeWarWeariness(pLoopUnit->getTeam(), *pNewPlot, GC.getDefineINT("WW_CAPTURED_UNIT"));
GET_TEAM(getTeam()).AI_changeWarSuccess(pLoopUnit->getTeam(), GC.getDefineINT("WAR_SUCCESS_UNIT_CAPTURING"));
}
//FfH: Modified by Kael 12/30/2207
// if (!isNoCapture())
// {
// pLoopUnit->setCapturingPlayer(getOwnerINLINE());
// }
if (!isNoCapture() || GC.getUnitInfo((UnitTypes)pLoopUnit->getUnitType()).getEquipmentPromotion() != NO_PROMOTION)
{
if (!pLoopUnit->isHiddenNationality())
{
pLoopUnit->setCapturingPlayer(getOwnerINLINE());
}
}
//FfH: End Modify
pLoopUnit->kill(false, getOwnerINLINE());
Well, the function in setXY should move them aside, that is true. Kael added these bits, so I would suspect one of them is your issue, but both seem fairly harmless:
Code:if (pLoopUnit != NULL) { if (isEnemy(pLoopUnit->getTeam(), pNewPlot) || pLoopUnit->isEnemy(getTeam())) { if (!pLoopUnit->canCoexistWithEnemyUnit(getTeam())) { if (NO_UNITCLASS == pLoopUnit->getUnitInfo().getUnitCaptureClassType() && pLoopUnit->canDefend(pNewPlot)) { //FfH: Modified by Kael 12/30/2008 // pLoopUnit->jumpToNearestValidPlot(); // can kill unit if (!isInvisible(pLoopUnit->getTeam(), false)) { pLoopUnit->jumpToNearestValidPlot(); // can kill unit } //FfH: End Modify } else { //FfH Hidden Nationality: Modified by Kael 08/27/2007 // if (!m_pUnitInfo->isHiddenNationality() && !pLoopUnit->getUnitInfo().isHiddenNationality()) if (!isHiddenNationality() && !pLoopUnit->isHiddenNationality()) //FfH: End Modify { GET_TEAM(pLoopUnit->getTeam()).changeWarWeariness(getTeam(), *pNewPlot, GC.getDefineINT("WW_UNIT_CAPTURED")); GET_TEAM(getTeam()).changeWarWeariness(pLoopUnit->getTeam(), *pNewPlot, GC.getDefineINT("WW_CAPTURED_UNIT")); GET_TEAM(getTeam()).AI_changeWarSuccess(pLoopUnit->getTeam(), GC.getDefineINT("WAR_SUCCESS_UNIT_CAPTURING")); } //FfH: Modified by Kael 12/30/2207 // if (!isNoCapture()) // { // pLoopUnit->setCapturingPlayer(getOwnerINLINE()); // } if (!isNoCapture() || GC.getUnitInfo((UnitTypes)pLoopUnit->getUnitType()).getEquipmentPromotion() != NO_PROMOTION) { if (!pLoopUnit->isHiddenNationality()) { pLoopUnit->setCapturingPlayer(getOwnerINLINE()); } } //FfH: End Modify pLoopUnit->kill(false, getOwnerINLINE());
def spellExploreLair(caster):
pPlot = caster.plot()
pOwner = gc.getPlayer(gc.getBARBARIAN_PLAYER())
sType = gc.getInfoTypeForString('UNIT_WARRIOR')
unitMonster = pOwner.initUnit(sType, pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.DIRECTION_SOUTH)
Traceback (most recent call last):
File "CvSpellInterface", line 22, in cast
File "<string>", line 0, in ?
File "CvSpellInterface", line 1166, in spellExploreLair
RuntimeError: unidentifiable C++ exception