How do I add a promotion?

I'm pretty sure there aren't "special" unit classes for withdrawal and collateral damage. I've had it working on all sorts of different unit classes.

Thinking about it - this may be a fix to a bug I posted about 1.52. This bug allowed you to get promotions for units which couldn't do collateral damage due to data in the unitInfos.xml, but could still get the promotion (hence making the promotion useless, without telling you in-game). The destroyer, for example, cannot do collateral damage, but is a naval unit, so can get the barrage promotion.

I think you want to change <iCollateralDamageLimit> and <iCollateralDamageMaxUnits> on units you want to be able to do collateral damage. The <iCollateralDamageChange> just changes <iCollateralDamage>, and the max units remains at 0, so it doesn't do anything.

No idea about withdrawal. Can't see any similar tags for that, but I might be missing something.
 
I added the collateral damage back into the Army promotions, went into Civ4UnitInfos.xml and set <iCollateralDamageLimit> to I, left <iCollateralDamageMaxUnits> at 0 for the Warrior unit. I tested in-game by using the World-Builder to give myself all techs and that warrior 400XP. This time, the Army promotions did not show as being available.

Additonally, wouldn't TheGreatApple's Method - if it did work - mean that the unit in question could gain a collateral damage promotion, but that that promotion wouldn't actually cause collateral damage (since the Max Units it can damage is set to 0)?
 
I think you probably have to set the max units to be greater than 0, otherwise it wouldn't be able to do any collateral damange and the game wouldn't allow you to get it. Seems it should allow you to get promotions if they don't just change the collateral damage though.

This is all speculation BTW. I might take a look at the SDK to see if I can find anything.
 
I went through the same problem back in December with my Bushido promotions. Some units could get them and others coudn't. Eventually I figured out what you all have now realized: if a unit doesn't have a trait it can't get a promotion that increases that trait.

I created a workaround for it with a Python file. Here is the relevant listing of my Promotions.py
The solution is to start with a promotion that you don't want the unit to have, but which it can get, and replace it with hte promotion you actually want it to have. In my example I replace combat X with Bushido X for Japan. If you want your units to be able to get the combat promotions you can always create a Dummy promotion to use as your replacement one.

Roger Bacon

Code:
def onUnitPromoted(self, argsList):
		'Unit Promoted'
		pUnit, iPromotion = argsList
		iPlayer = pUnit.getOwner()
		pPlayer = gc.getPlayer(iPlayer)
		combat1 = gc.getInfoTypeForString("PROMOTION_COMBAT1")
		combat2 = gc.getInfoTypeForString("PROMOTION_COMBAT2")
		combat3 = gc.getInfoTypeForString("PROMOTION_COMBAT3")
		combat4 = gc.getInfoTypeForString("PROMOTION_COMBAT4")
		combat5 = gc.getInfoTypeForString("PROMOTION_COMBAT5")
		combat6 = gc.getInfoTypeForString("PROMOTION_COMBAT6")
		bushido1 = gc.getInfoTypeForString("PROMOTION_BUSHIDO1")
		bushido2 = gc.getInfoTypeForString("PROMOTION_BUSHIDO2")
		bushido3 = gc.getInfoTypeForString("PROMOTION_BUSHIDO3")
		bushido4 = gc.getInfoTypeForString("PROMOTION_BUSHIDO4")
		bushido5 = gc.getInfoTypeForString("PROMOTION_BUSHIDO5")
		bushido6 = gc.getInfoTypeForString("PROMOTION_BUSHIDO6")
		if (pPlayer.getCivilizationDescriptionKey() != "TXT_KEY_CIV_JAPAN_DESC"):
			return
		if (iPromotion == combat1 and pUnit.isHasPromotion(bushido6)):
			return
		elif (iPromotion == combat1 and pUnit.isHasPromotion(bushido5)):
			pUnit.setHasPromotion(bushido6, true)
			pUnit.setHasPromotion(combat1, false)
			return
		elif (iPromotion == combat1 and pUnit.isHasPromotion(bushido4)):
			pUnit.setHasPromotion(bushido5, true)
			pUnit.setHasPromotion(combat1, false)
			return
		elif (iPromotion == combat1 and pUnit.isHasPromotion(bushido3)):
			pUnit.setHasPromotion(bushido4, true)
			pUnit.setHasPromotion(combat1, false)
			return
		elif (iPromotion == combat1 and pUnit.isHasPromotion(bushido2)):
			pUnit.setHasPromotion(bushido3, true)
			pUnit.setHasPromotion(combat1, false)
			return
		elif (iPromotion == combat1 and pUnit.isHasPromotion(bushido1)):
			pUnit.setHasPromotion(bushido2, true)
			pUnit.setHasPromotion(combat1, false)
			return
		elif (iPromotion == combat1):
			pUnit.setHasPromotion(bushido1, true)
			pUnit.setHasPromotion(combat1, false)
 
The code that controls this, by the way, is in CVGameCoreUtils.cpp in the function isPromotionValid.

Roger Bacon

Code:
bool isPromotionValid(PromotionTypes ePromotion, UnitTypes eUnit)
{
	if (GC.getUnitInfo(eUnit).getUnitCombatType() == NO_UNITCOMBAT)
	{
		return false;
	}

	if (!(GC.getPromotionInfo(ePromotion).getUnitCombat(GC.getUnitInfo(eUnit).getUnitCombatType())))
	{
		return false;
	}

	if (GC.getUnitInfo(eUnit).isOnlyDefensive())
	{
		if ((GC.getPromotionInfo(ePromotion).getCityAttackPercent() != 0) ||
			  (GC.getPromotionInfo(ePromotion).getWithdrawalChange() != 0) ||
			  (GC.getPromotionInfo(ePromotion).getCollateralDamageChange() != 0) ||
			  (GC.getPromotionInfo(ePromotion).isBlitz()) ||
			  (GC.getPromotionInfo(ePromotion).isAmphib()) ||
			  (GC.getPromotionInfo(ePromotion).isRiver()))
		{
			return false;
		}
	}

	if (GC.getUnitInfo(eUnit).isIgnoreTerrainCost())
	{
		if (GC.getPromotionInfo(ePromotion).getMoveDiscountChange() != 0)
		{
			return false;
		}
	}

	if (GC.getUnitInfo(eUnit).getMoves() == 1)
	{
		if (GC.getPromotionInfo(ePromotion).isBlitz())
		{
			return false;
		}
	}

	if ((GC.getUnitInfo(eUnit).getCollateralDamageLimit() == 0) || (GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() == 0))
	{
		if (GC.getPromotionInfo(ePromotion).getCollateralDamageChange() != 0)
		{
			return false;
		}
	}

	return true;
}
 
Back
Top Bottom