Mumin
Jan 17, 2006, 01:40 PM
(Code based on Kael's "Fall from Heaven" mod. Thanks Kael!)
Rather than fighting themselves, siege units can now create a barrage if they have at least one move left
and are on land. The barrage works like a non-interceptable aircraft which will remain for the turn only
and may be used to bombard the enemy.
Pros (in my opinion):
Siege cannot kill units outright or capture cities.
Siege won't get killed when bombarding.
Feels much more like actual artillery.
Cons:
The AI won't use air units far away from cities. (Why??)
The attack explosion often appears over another tile than the one attacked.
Siege may fire and then move. (The AI will otherwise not be able to move its siege units at all.)
Bombardment is now a two-step process, making it a little more awkward.
Siege may not gain levels.
The following files (place in CustomAssets or Assets for your mod) are needed:
python/CvEventManager.py
xml/art/CIV4ArtDefines_Unit.xml
xml/units/CIV4UnitClassInfos.xml
xml/units/CIV4UnitInfos.xml
xml/units/CIV4PromotionInfos.xml
First make a barrage unit:
Add in xml/units/CIV4UnitClassInfos.xml:
<UnitClassInfo>
<Type>UNITCLASS_CATAPULT_BARRAGE</Type>
<Description>Catapult Barrage</Description>
<iMaxGlobalInstances>-1</iMaxGlobalInstances>
<iMaxTeamInstances>-1</iMaxTeamInstances>
<iMaxPlayerInstances>-1</iMaxPlayerInstances>
<DefaultUnit>UNIT_CATAPULT_BARRAGE</DefaultUnit>
</UnitClassInfo>
Add in xml/units/CIV4UnitInfos.xml:
<UnitInfo>
<Class>UNITCLASS_CATAPULT_BARRAGE</Class>
<Type>UNIT_CATAPULT_BARRAGE</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
<Combat>NONE</Combat>
<Domain>DOMAIN_AIR</Domain>
<DefaultUnitAI>UNITAI_ATTACK_AIR</DefaultUnitAI>
<Invisible>NONE</Invisible>
<SeeInvisible>NONE</SeeInvisible>
<Description>Catapult Barrage</Description>
<Civilopedia/>
<Strategy/>
<Advisor>ADVISOR_MILITARY</Advisor>
<bAnimal>0</bAnimal>
<bFood>0</bFood>
<bNoBadGoodies>0</bNoBadGoodies>
<bOnlyDefensive>0</bOnlyDefensive>
<bNoCapture>0</bNoCapture>
<bRivalTerritory>0</bRivalTerritory>
<bMilitaryHappiness>0</bMilitaryHappiness>
<bMilitarySupport>0</bMilitarySupport>
<bMilitaryProduction>1</bMilitaryProduction>
<bPillage>0</bPillage>
<bSabotage>0</bSabotage>
<bDestroy>0</bDestroy>
<bStealPlans>0</bStealPlans>
<bInvestigate>0</bInvestigate>
<bCounterSpy>0</bCounterSpy>
<bFound>0</bFound>
<bGoldenAge>0</bGoldenAge>
<bInvisible>0</bInvisible>
<bFirstStrikeImmune>0</bFirstStrikeImmune>
<bNoDefensiveBonus>0</bNoDefensiveBonus>
<bIgnoreBuildingDefense>0</bIgnoreBuildingDefense>
<bCanMoveImpassable>0</bCanMoveImpassable>
<bFlatMovementCost>0</bFlatMovementCost>
<bIgnoreTerrainCost>0</bIgnoreTerrainCost>
<bNukeImmune>0</bNukeImmune>
<bPrereqBonuses>0</bPrereqBonuses>
<bPrereqReligion>0</bPrereqReligion>
<bMechanized>1</bMechanized>
<UnitClassUpgrades/>
<UnitAIs>
<UnitAI>
<UnitAIType>UNITAI_ATTACK_AIR</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
</UnitAIs>
<NotUnitAIs/>
<Builds/>
<ReligionSpreads/>
<GreatPeoples/>
<Buildings/>
<ForceBuildings/>
<HolyCity>NONE</HolyCity>
<ReligionType>NONE</ReligionType>
<StateReligion>NONE</StateReligion>
<PrereqReligion>NONE</PrereqReligion>
<PrereqBuilding>NONE</PrereqBuilding>
<PrereqTech>NONE</PrereqTech>
<TechTypes/>
<BonusType>NONE</BonusType>
<PrereqBonuses/>
<ProductionTraits/>
<Flavors/>
<iAIWeight>0</iAIWeight>
<iCost>-1</iCost>
<iHurryCostModifier>0</iHurryCostModifier>
<iMinAreaSize>-1</iMinAreaSize>
<iMoves>1</iMoves>
<iAirRange>1</iAirRange>
<iNukeRange>-1</iNukeRange>
<iWorkRate>0</iWorkRate>
<iBaseDiscover>0</iBaseDiscover>
<iDiscoverMultiplier>0</iDiscoverMultiplier>
<iBaseHurry>0</iBaseHurry>
<iHurryMultiplier>0</iHurryMultiplier>
<iBaseTrade>0</iBaseTrade>
<iTradeMultiplier>0</iTradeMultiplier>
<iGreatWorkCulture>0</iGreatWorkCulture>
<TerrainImpassables/>
<FeatureImpassables/>
<iCombat>0</iCombat>
<iAirCombat>2</iAirCombat>
<iAirCombatLimit>50</iAirCombatLimit>
<iXPValueAttack>0</iXPValueAttack>
<iXPValueDefense>0</iXPValueDefense>
<iFirstStrikes>0</iFirstStrikes>
<iChanceFirstStrikes>0</iChanceFirstStrikes>
<iInterceptionProbability>0</iInterceptionProbability>
<iEvasionProbability>100</iEvasionProbability>
<iWithdrawalProb>0</iWithdrawalProb>
<iCollateralDamage>100</iCollateralDamage>
<iCollateralDamageLimit>50</iCollateralDamageLimit>
<iCollateralDamageMaxUnits>6</iCollateralDamageMaxUnits>
<iCityAttack>100</iCityAttack>
<iCityDefense>0</iCityDefense>
<iAnimalCombat>0</iAnimalCombat>
<iHillsDefense>0</iHillsDefense>
<TerrainNatives/>
<FeatureNatives/>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitClassAttackMods/>
<UnitClassDefenseMods/>
<UnitCombatMods/>
<DomainMods/>
<BonusProductionModifiers/>
<iBombRate>10</iBombRate>
<iBombardRate>0</iBombardRate>
<SpecialCargo>NONE</SpecialCargo>
<DomainCargo>NONE</DomainCargo>
<iCargo>0</iCargo>
<iConscription>0</iConscription>
<iCultureGarrison>0</iCultureGarrison>
<iExtraCost>0</iExtraCost>
<iAsset>0</iAsset>
<iPower>0</iPower>
<UnitMeshGroups>
<iGroupSize>1</iGroupSize>
<fMaxSpeed>10.0</fMaxSpeed>
<iMeleeWaveSize>1</iMeleeWaveSize>
<iRangedWaveSize>1</iRangedWaveSize>
<UnitMeshGroup>
<iRequired>2</iRequired>
<EarlyArtDefineTag>ART_DEF_UNIT_CATAPULT_BARRAGE</EarlyArtDefineTag>
</UnitMeshGroup>
</UnitMeshGroups>
<Button>Art/Interface/Buttons/Units/Catapult.dds</Button>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<FreePromotions/>
</UnitInfo>
And define appropriate art in xml/art/CIV4ArtDefines_Unit.xml:
<UnitArtInfo>
<Type>ART_DEF_UNIT_CATAPULT_BARRAGE</Type>
<fScale>0.02</fScale>
<fInterfaceScale>0.68</fInterfaceScale>
<NIF>Art/Units/ICBM/ICBM.nif</NIF>
<KFM>Art/Units/ICBM/ICBM.kfm</KFM>
<ShadowDef>
<ShadowNIF>Art/Units/01_UnitShadows/UnitShadow.nif</ShadowNIF>
<ShadowAttachNode>BIP Pelvis</ShadowAttachNode>
<fShadowScale>0.01</fShadowScale>
</ShadowDef>
<fBattleDistance>0</fBattleDistance>
<fRangedDeathTime>0.31</fRangedDeathTime>
<bSmoothMove>1</bSmoothMove>
<bActAsRanged>0</bActAsRanged>
<TrainSound>AS2D_UNIT_BUILD_UNIT</TrainSound>
<AudioRunSounds>
<AudioRunTypeLoop/>
<AudioRunTypeEnd/>
</AudioRunSounds>
<SelectionSound>AS3D_UN_ICBM_SELECT</SelectionSound>
<ActionSound>AS3D_UN_ICBM_SELECT</ActionSound>
</UnitArtInfo>
Go to xml/units/CIV4PromotionInfos.xml and remove UNITCOMBAT_SIEGE from all promotions. Then add the following
promotions:
<PromotionInfo>
<Type>PROMOTION_FIRE</Type>
<Description>Fire</Description>
<Sound>NONE</Sound>
<PromotionPrereqOr1>NONE</PromotionPrereqOr1>
<PromotionPrereqOr2>NONE</PromotionPrereqOr2>
<TechPrereq>NONE</TechPrereq>
<bBlitz>0</bBlitz>
<bAmphib>0</bAmphib>
<bRiver>0</bRiver>
<bEnemyRoute>0</bEnemyRoute>
<bAlwaysHeal>0</bAlwaysHeal>
<bHillsDoubleMove>0</bHillsDoubleMove>
<bImmuneToFirstStrikes>0</bImmuneToFirstStrikes>
<iVisibilityChange>0</iVisibilityChange>
<iMovesChange>0</iMovesChange>
<iMoveDiscountChange>0</iMoveDiscountChange>
<iWithdrawalChange>0</iWithdrawalChange>
<iCollateralDamageChange>0</iCollateralDamageChange>
<iBombardRateChange>0</iBombardRateChange>
<iFirstStrikesChange>0</iFirstStrikesChange>
<iChanceFirstStrikesChange>0</iChanceFirstStrikesChange>
<iEnemyHealChange>0</iEnemyHealChange>
<iNeutralHealChange>0</iNeutralHealChange>
<iFriendlyHealChange>0</iFriendlyHealChange>
<iSameTileHealChange>0</iSameTileHealChange>
<iAdjacentTileHealChange>0</iAdjacentTileHealChange>
<iCombatPercent>100</iCombatPercent>
<iCityAttack>0</iCityAttack>
<iCityDefense>0</iCityDefense>
<iHillsDefense>0</iHillsDefense>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitCombatMods/>
<DomainMods/>
<TerrainDoubleMoves/>
<FeatureDoubleMoves/>
<UnitCombats>
<UnitCombat>
<UnitCombatType>UNITCOMBAT_SIEGE</UnitCombatType>
<bUnitCombat>1</bUnitCombat>
</UnitCombat>
</UnitCombats>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<Button>Art/Interface/Buttons/promotions/accuracy.dds</Button>
</PromotionInfo>
<PromotionInfo>
<Type>PROMOTION_ORDNANCE</Type>
<Description>Ordnance</Description>
<Sound>AS2D_IF_LEVELUP</Sound>
<PromotionPrereqOr1>NONE</PromotionPrereqOr1>
<PromotionPrereqOr2>NONE</PromotionPrereqOr2>
<TechPrereq>NONE</TechPrereq>
<bBlitz>0</bBlitz>
<bAmphib>0</bAmphib>
<bRiver>0</bRiver>
<bEnemyRoute>0</bEnemyRoute>
<bAlwaysHeal>0</bAlwaysHeal>
<bHillsDoubleMove>0</bHillsDoubleMove>
<bImmuneToFirstStrikes>0</bImmuneToFirstStrikes>
<iVisibilityChange>0</iVisibilityChange>
<iMovesChange>0</iMovesChange>
<iMoveDiscountChange>0</iMoveDiscountChange>
<iWithdrawalChange>0</iWithdrawalChange>
<iCollateralDamageChange>0</iCollateralDamageChange>
<iBombardRateChange>0</iBombardRateChange>
<iFirstStrikesChange>0</iFirstStrikesChange>
<iChanceFirstStrikesChange>0</iChanceFirstStrikesChange>
<iEnemyHealChange>0</iEnemyHealChange>
<iNeutralHealChange>0</iNeutralHealChange>
<iFriendlyHealChange>0</iFriendlyHealChange>
<iSameTileHealChange>0</iSameTileHealChange>
<iAdjacentTileHealChange>0</iAdjacentTileHealChange>
<iCombatPercent>0</iCombatPercent>
<iCityAttack>0</iCityAttack>
<iCityDefense>0</iCityDefense>
<iHillsDefense>0</iHillsDefense>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitCombatMods/>
<DomainMods/>
<TerrainDoubleMoves/>
<FeatureDoubleMoves/>
<UnitCombats/>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<Button>Art/Interface/Buttons/Promotions/accuracy.dds</Button>
</PromotionInfo>
Now for some Python Code in python/CvEventManager.py:
Find:
def onUnitCreated(self, argsList):
'Unit Completed'
unit = argsList[0]
player = PyPlayer(unit.getOwner())
if (not self.__LOG_UNITBUILD):
return
And replace it with: (Will provide 10 and lvl 3 to new siege units)
def onUnitCreated(self, argsList):
'Unit Completed'
unit = argsList[0]
player = PyPlayer(unit.getOwner())
if unit.getUnitCombatType() == gc.getInfoTypeForString("UNITCOMBAT_SIEGE"):
unit.setLevel(3)
unit.setExperience(10,10)
if (not self.__LOG_UNITBUILD):
return
Then find:
def onUnitPromoted(self, argsList):
'Unit Promoted'
pUnit, iPromotion = argsList
player = PyPlayer(pUnit.getOwner())
if (not self.__LOG_UNITPROMOTED):
return
CvUtil.pyPrint('Unit Promotion Event: %s - %s' %(player.getCivilizationName(), pUnit.getName(),))
And replace with: (Creates a barrage by using the Fire promotion.)
def onUnitPromoted(self, argsList):
'Modded: Unit Promoted'
pUnit, iPromotion = argsList
player = pUnit.getOwner()
pPlayer = gc.getPlayer(player)
iX = pUnit.getX()
iY = pUnit.getY()
if pUnit.isHasPromotion(gc.getInfoTypeForString('PROM OTION_FIRE')) and (pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_CATAPULT')) :
if (pUnit.movesLeft() == 60) and (not pUnit.area().isWater()):
newUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_CAT APULT_ROCKS'), pUnit.getX(), pUnit.getY(), UnitAITypes.NO_UNITAI)
newUnit.setHasPromotion(gc.getInfoTypeForString('P ROMOTION_ORDNANCE'), True)
pUnit.setHasPromotion(gc.getInfoTypeForString('PRO MOTION_FIRE'), False)
pUnit.setLevel(3)
pUnit.setExperience(10, -1)
if (not self.__LOG_UNITPROMOTED):
return
Then find:
def onEndPlayerTurn(self, argsList):
'Called at the end of a players turn'
iGameTurn, iPlayer = argsList
if (gc.getGame().getElapsedGameTurns() == 1):
if (gc.getPlayer(iPlayer).isHuman()):
if (gc.getPlayer(iPlayer).canRevolution(0)):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTT ONPOPUP_CHANGECIVIC)
popupInfo.addPopup(iPlayer)
CvAdvisorUtils.resetAdvisorNags()
CvAdvisorUtils.endTurnFeats(iPlayer)
And replace with: (Will remove barrage on end turn.)
def onEndPlayerTurn(self, argsList):
'Called at the end of a players turn'
iGameTurn, iPlayer = argsList
pPlayer = gc.getPlayer(iPlayer)
for i in range(pPlayer.getNumUnits(), 0, -1):
pUnit = pPlayer.getUnit(i)
if pUnit.isHasPromotion(gc.getInfoTypeForString('PROM OTION_ORDNANCE')):
pUnit.kill(False,0)
if (gc.getGame().getElapsedGameTurns() == 1):
if (gc.getPlayer(iPlayer).isHuman()):
if (gc.getPlayer(iPlayer).canRevolution(0)):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTT ONPOPUP_CHANGECIVIC)
popupInfo.addPopup(iPlayer)
CvAdvisorUtils.resetAdvisorNags()
CvAdvisorUtils.endTurnFeats(iPlayer)
Finally, remove the ability of your siege to fight itself. E.g. like this in xml/units/CIV4UnitInfos.xml:
<UnitInfo>
<Class>UNITCLASS_CATAPULT</Class>
<Type>UNIT_CATAPULT</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
<Combat>UNITCOMBAT_SIEGE</Combat>
<Domain>DOMAIN_LAND</Domain>
<DefaultUnitAI>UNITAI_ATTACK_CITY</DefaultUnitAI>
<Invisible>NONE</Invisible>
<SeeInvisible>NONE</SeeInvisible>
<Description>TXT_KEY_UNIT_CATAPULT</Description>
<Civilopedia>TXT_KEY_UNIT_CATAPULT_PEDIA</Civilopedia>
<Strategy>TXT_KEY_UNIT_CATAPULT_STRATEGY</Strategy>
<Advisor>ADVISOR_MILITARY</Advisor>
<bAnimal>0</bAnimal>
<bFood>0</bFood>
<bNoBadGoodies>0</bNoBadGoodies>
<bOnlyDefensive>1</bOnlyDefensive>
<bNoCapture>1</bNoCapture>
<bRivalTerritory>0</bRivalTerritory>
<bMilitaryHappiness>1</bMilitaryHappiness>
<bMilitarySupport>1</bMilitarySupport>
<bMilitaryProduction>1</bMilitaryProduction>
<bPillage>0</bPillage>
<bSabotage>0</bSabotage>
<bDestroy>0</bDestroy>
<bStealPlans>0</bStealPlans>
<bInvestigate>0</bInvestigate>
<bCounterSpy>0</bCounterSpy>
<bFound>0</bFound>
<bGoldenAge>0</bGoldenAge>
<bInvisible>0</bInvisible>
<bFirstStrikeImmune>0</bFirstStrikeImmune>
<bNoDefensiveBonus>1</bNoDefensiveBonus>
<bIgnoreBuildingDefense>0</bIgnoreBuildingDefense>
<bCanMoveImpassable>0</bCanMoveImpassable>
<bFlatMovementCost>0</bFlatMovementCost>
<bIgnoreTerrainCost>0</bIgnoreTerrainCost>
<bNukeImmune>0</bNukeImmune>
<bPrereqBonuses>0</bPrereqBonuses>
<bPrereqReligion>0</bPrereqReligion>
<bMechanized>1</bMechanized>
<UnitClassUpgrades>
<UnitClassUpgrade>
<UnitClassUpgradeType>UNITCLASS_CANNON</UnitClassUpgradeType>
<bUnitClassUpgrade>1</bUnitClassUpgrade>
</UnitClassUpgrade>
</UnitClassUpgrades>
<UnitAIs>
<UnitAI>
<UnitAIType>UNITAI_ATTACK_CITY</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
<UnitAI>
<UnitAIType>UNITAI_COLLATERAL</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
</UnitAIs>
<NotUnitAIs/>
<Builds/>
<ReligionSpreads/>
<GreatPeoples/>
<Buildings/>
<ForceBuildings/>
<HolyCity>NONE</HolyCity>
<ReligionType>NONE</ReligionType>
<StateReligion>NONE</StateReligion>
<PrereqReligion>NONE</PrereqReligion>
<PrereqBuilding>NONE</PrereqBuilding>
<PrereqTech>TECH_MATHEMATICS</PrereqTech>
<TechTypes/>
<BonusType>NONE</BonusType>
<PrereqBonuses/>
<ProductionTraits/>
<Flavors/>
<iAIWeight>0</iAIWeight>
<iCost>40</iCost>
<iHurryCostModifier>0</iHurryCostModifier>
<iMinAreaSize>-1</iMinAreaSize>
<iMoves>1</iMoves>
<iAirRange>0</iAirRange>
<iNukeRange>-1</iNukeRange>
<iWorkRate>0</iWorkRate>
<iBaseDiscover>0</iBaseDiscover>
<iDiscoverMultiplier>0</iDiscoverMultiplier>
<iBaseHurry>0</iBaseHurry>
<iHurryMultiplier>0</iHurryMultiplier>
<iBaseTrade>0</iBaseTrade>
<iTradeMultiplier>0</iTradeMultiplier>
<iGreatWorkCulture>0</iGreatWorkCulture>
<TerrainImpassables/>
<FeatureImpassables/>
<iCombat>2</iCombat>
<iAirCombat>0</iAirCombat>
<iAirCombatLimit>0</iAirCombatLimit>
<iXPValueAttack>4</iXPValueAttack>
<iXPValueDefense>2</iXPValueDefense>
<iFirstStrikes>0</iFirstStrikes>
<iChanceFirstStrikes>0</iChanceFirstStrikes>
<iInterceptionProbability>0</iInterceptionProbability>
<iEvasionProbability>0</iEvasionProbability>
<iWithdrawalProb>0</iWithdrawalProb>
<iCollateralDamage>0</iCollateralDamage>
<iCollateralDamageLimit>0</iCollateralDamageLimit>
<iCollateralDamageMaxUnits>0</iCollateralDamageMaxUnits>
<iCityAttack>0</iCityAttack>
<iCityDefense>0</iCityDefense>
<iAnimalCombat>0</iAnimalCombat>
<iHillsDefense>0</iHillsDefense>
<TerrainNatives/>
<FeatureNatives/>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitClassAttackMods/>
<UnitClassDefenseMods/>
<UnitCombatMods/>
<DomainMods/>
<BonusProductionModifiers/>
<iBombRate>0</iBombRate>
<iBombardRate>0</iBombardRate>
<SpecialCargo>NONE</SpecialCargo>
<DomainCargo>NONE</DomainCargo>
<iCargo>0</iCargo>
<iConscription>0</iConscription>
<iCultureGarrison>4</iCultureGarrison>
<iExtraCost>0</iExtraCost>
<iAsset>2</iAsset>
<iPower>3</iPower>
<UnitMeshGroups>
<iGroupSize>2</iGroupSize>
<fMaxSpeed>1.25</fMaxSpeed>
<iMeleeWaveSize>2</iMeleeWaveSize>
<iRangedWaveSize>2</iRangedWaveSize>
<UnitMeshGroup>
<iRequired>2</iRequired>
<EarlyArtDefineTag>ART_DEF_UNIT_CATAPULT</EarlyArtDefineTag>
</UnitMeshGroup>
</UnitMeshGroups>
<Button>,Art/Interface/Buttons/Units/Catapult.dds,Art/Interface/Buttons/Unit_Resource_Atlas.dds,7,8</Button>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<FreePromotions/>
</UnitInfo>
Test and, if you like it, implement for the rest of the siege units.
I think that was all (Phew! I hope I got it all right! :crazyeye: ). Thoughts?
Rather than fighting themselves, siege units can now create a barrage if they have at least one move left
and are on land. The barrage works like a non-interceptable aircraft which will remain for the turn only
and may be used to bombard the enemy.
Pros (in my opinion):
Siege cannot kill units outright or capture cities.
Siege won't get killed when bombarding.
Feels much more like actual artillery.
Cons:
The AI won't use air units far away from cities. (Why??)
The attack explosion often appears over another tile than the one attacked.
Siege may fire and then move. (The AI will otherwise not be able to move its siege units at all.)
Bombardment is now a two-step process, making it a little more awkward.
Siege may not gain levels.
The following files (place in CustomAssets or Assets for your mod) are needed:
python/CvEventManager.py
xml/art/CIV4ArtDefines_Unit.xml
xml/units/CIV4UnitClassInfos.xml
xml/units/CIV4UnitInfos.xml
xml/units/CIV4PromotionInfos.xml
First make a barrage unit:
Add in xml/units/CIV4UnitClassInfos.xml:
<UnitClassInfo>
<Type>UNITCLASS_CATAPULT_BARRAGE</Type>
<Description>Catapult Barrage</Description>
<iMaxGlobalInstances>-1</iMaxGlobalInstances>
<iMaxTeamInstances>-1</iMaxTeamInstances>
<iMaxPlayerInstances>-1</iMaxPlayerInstances>
<DefaultUnit>UNIT_CATAPULT_BARRAGE</DefaultUnit>
</UnitClassInfo>
Add in xml/units/CIV4UnitInfos.xml:
<UnitInfo>
<Class>UNITCLASS_CATAPULT_BARRAGE</Class>
<Type>UNIT_CATAPULT_BARRAGE</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
<Combat>NONE</Combat>
<Domain>DOMAIN_AIR</Domain>
<DefaultUnitAI>UNITAI_ATTACK_AIR</DefaultUnitAI>
<Invisible>NONE</Invisible>
<SeeInvisible>NONE</SeeInvisible>
<Description>Catapult Barrage</Description>
<Civilopedia/>
<Strategy/>
<Advisor>ADVISOR_MILITARY</Advisor>
<bAnimal>0</bAnimal>
<bFood>0</bFood>
<bNoBadGoodies>0</bNoBadGoodies>
<bOnlyDefensive>0</bOnlyDefensive>
<bNoCapture>0</bNoCapture>
<bRivalTerritory>0</bRivalTerritory>
<bMilitaryHappiness>0</bMilitaryHappiness>
<bMilitarySupport>0</bMilitarySupport>
<bMilitaryProduction>1</bMilitaryProduction>
<bPillage>0</bPillage>
<bSabotage>0</bSabotage>
<bDestroy>0</bDestroy>
<bStealPlans>0</bStealPlans>
<bInvestigate>0</bInvestigate>
<bCounterSpy>0</bCounterSpy>
<bFound>0</bFound>
<bGoldenAge>0</bGoldenAge>
<bInvisible>0</bInvisible>
<bFirstStrikeImmune>0</bFirstStrikeImmune>
<bNoDefensiveBonus>0</bNoDefensiveBonus>
<bIgnoreBuildingDefense>0</bIgnoreBuildingDefense>
<bCanMoveImpassable>0</bCanMoveImpassable>
<bFlatMovementCost>0</bFlatMovementCost>
<bIgnoreTerrainCost>0</bIgnoreTerrainCost>
<bNukeImmune>0</bNukeImmune>
<bPrereqBonuses>0</bPrereqBonuses>
<bPrereqReligion>0</bPrereqReligion>
<bMechanized>1</bMechanized>
<UnitClassUpgrades/>
<UnitAIs>
<UnitAI>
<UnitAIType>UNITAI_ATTACK_AIR</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
</UnitAIs>
<NotUnitAIs/>
<Builds/>
<ReligionSpreads/>
<GreatPeoples/>
<Buildings/>
<ForceBuildings/>
<HolyCity>NONE</HolyCity>
<ReligionType>NONE</ReligionType>
<StateReligion>NONE</StateReligion>
<PrereqReligion>NONE</PrereqReligion>
<PrereqBuilding>NONE</PrereqBuilding>
<PrereqTech>NONE</PrereqTech>
<TechTypes/>
<BonusType>NONE</BonusType>
<PrereqBonuses/>
<ProductionTraits/>
<Flavors/>
<iAIWeight>0</iAIWeight>
<iCost>-1</iCost>
<iHurryCostModifier>0</iHurryCostModifier>
<iMinAreaSize>-1</iMinAreaSize>
<iMoves>1</iMoves>
<iAirRange>1</iAirRange>
<iNukeRange>-1</iNukeRange>
<iWorkRate>0</iWorkRate>
<iBaseDiscover>0</iBaseDiscover>
<iDiscoverMultiplier>0</iDiscoverMultiplier>
<iBaseHurry>0</iBaseHurry>
<iHurryMultiplier>0</iHurryMultiplier>
<iBaseTrade>0</iBaseTrade>
<iTradeMultiplier>0</iTradeMultiplier>
<iGreatWorkCulture>0</iGreatWorkCulture>
<TerrainImpassables/>
<FeatureImpassables/>
<iCombat>0</iCombat>
<iAirCombat>2</iAirCombat>
<iAirCombatLimit>50</iAirCombatLimit>
<iXPValueAttack>0</iXPValueAttack>
<iXPValueDefense>0</iXPValueDefense>
<iFirstStrikes>0</iFirstStrikes>
<iChanceFirstStrikes>0</iChanceFirstStrikes>
<iInterceptionProbability>0</iInterceptionProbability>
<iEvasionProbability>100</iEvasionProbability>
<iWithdrawalProb>0</iWithdrawalProb>
<iCollateralDamage>100</iCollateralDamage>
<iCollateralDamageLimit>50</iCollateralDamageLimit>
<iCollateralDamageMaxUnits>6</iCollateralDamageMaxUnits>
<iCityAttack>100</iCityAttack>
<iCityDefense>0</iCityDefense>
<iAnimalCombat>0</iAnimalCombat>
<iHillsDefense>0</iHillsDefense>
<TerrainNatives/>
<FeatureNatives/>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitClassAttackMods/>
<UnitClassDefenseMods/>
<UnitCombatMods/>
<DomainMods/>
<BonusProductionModifiers/>
<iBombRate>10</iBombRate>
<iBombardRate>0</iBombardRate>
<SpecialCargo>NONE</SpecialCargo>
<DomainCargo>NONE</DomainCargo>
<iCargo>0</iCargo>
<iConscription>0</iConscription>
<iCultureGarrison>0</iCultureGarrison>
<iExtraCost>0</iExtraCost>
<iAsset>0</iAsset>
<iPower>0</iPower>
<UnitMeshGroups>
<iGroupSize>1</iGroupSize>
<fMaxSpeed>10.0</fMaxSpeed>
<iMeleeWaveSize>1</iMeleeWaveSize>
<iRangedWaveSize>1</iRangedWaveSize>
<UnitMeshGroup>
<iRequired>2</iRequired>
<EarlyArtDefineTag>ART_DEF_UNIT_CATAPULT_BARRAGE</EarlyArtDefineTag>
</UnitMeshGroup>
</UnitMeshGroups>
<Button>Art/Interface/Buttons/Units/Catapult.dds</Button>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<FreePromotions/>
</UnitInfo>
And define appropriate art in xml/art/CIV4ArtDefines_Unit.xml:
<UnitArtInfo>
<Type>ART_DEF_UNIT_CATAPULT_BARRAGE</Type>
<fScale>0.02</fScale>
<fInterfaceScale>0.68</fInterfaceScale>
<NIF>Art/Units/ICBM/ICBM.nif</NIF>
<KFM>Art/Units/ICBM/ICBM.kfm</KFM>
<ShadowDef>
<ShadowNIF>Art/Units/01_UnitShadows/UnitShadow.nif</ShadowNIF>
<ShadowAttachNode>BIP Pelvis</ShadowAttachNode>
<fShadowScale>0.01</fShadowScale>
</ShadowDef>
<fBattleDistance>0</fBattleDistance>
<fRangedDeathTime>0.31</fRangedDeathTime>
<bSmoothMove>1</bSmoothMove>
<bActAsRanged>0</bActAsRanged>
<TrainSound>AS2D_UNIT_BUILD_UNIT</TrainSound>
<AudioRunSounds>
<AudioRunTypeLoop/>
<AudioRunTypeEnd/>
</AudioRunSounds>
<SelectionSound>AS3D_UN_ICBM_SELECT</SelectionSound>
<ActionSound>AS3D_UN_ICBM_SELECT</ActionSound>
</UnitArtInfo>
Go to xml/units/CIV4PromotionInfos.xml and remove UNITCOMBAT_SIEGE from all promotions. Then add the following
promotions:
<PromotionInfo>
<Type>PROMOTION_FIRE</Type>
<Description>Fire</Description>
<Sound>NONE</Sound>
<PromotionPrereqOr1>NONE</PromotionPrereqOr1>
<PromotionPrereqOr2>NONE</PromotionPrereqOr2>
<TechPrereq>NONE</TechPrereq>
<bBlitz>0</bBlitz>
<bAmphib>0</bAmphib>
<bRiver>0</bRiver>
<bEnemyRoute>0</bEnemyRoute>
<bAlwaysHeal>0</bAlwaysHeal>
<bHillsDoubleMove>0</bHillsDoubleMove>
<bImmuneToFirstStrikes>0</bImmuneToFirstStrikes>
<iVisibilityChange>0</iVisibilityChange>
<iMovesChange>0</iMovesChange>
<iMoveDiscountChange>0</iMoveDiscountChange>
<iWithdrawalChange>0</iWithdrawalChange>
<iCollateralDamageChange>0</iCollateralDamageChange>
<iBombardRateChange>0</iBombardRateChange>
<iFirstStrikesChange>0</iFirstStrikesChange>
<iChanceFirstStrikesChange>0</iChanceFirstStrikesChange>
<iEnemyHealChange>0</iEnemyHealChange>
<iNeutralHealChange>0</iNeutralHealChange>
<iFriendlyHealChange>0</iFriendlyHealChange>
<iSameTileHealChange>0</iSameTileHealChange>
<iAdjacentTileHealChange>0</iAdjacentTileHealChange>
<iCombatPercent>100</iCombatPercent>
<iCityAttack>0</iCityAttack>
<iCityDefense>0</iCityDefense>
<iHillsDefense>0</iHillsDefense>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitCombatMods/>
<DomainMods/>
<TerrainDoubleMoves/>
<FeatureDoubleMoves/>
<UnitCombats>
<UnitCombat>
<UnitCombatType>UNITCOMBAT_SIEGE</UnitCombatType>
<bUnitCombat>1</bUnitCombat>
</UnitCombat>
</UnitCombats>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<Button>Art/Interface/Buttons/promotions/accuracy.dds</Button>
</PromotionInfo>
<PromotionInfo>
<Type>PROMOTION_ORDNANCE</Type>
<Description>Ordnance</Description>
<Sound>AS2D_IF_LEVELUP</Sound>
<PromotionPrereqOr1>NONE</PromotionPrereqOr1>
<PromotionPrereqOr2>NONE</PromotionPrereqOr2>
<TechPrereq>NONE</TechPrereq>
<bBlitz>0</bBlitz>
<bAmphib>0</bAmphib>
<bRiver>0</bRiver>
<bEnemyRoute>0</bEnemyRoute>
<bAlwaysHeal>0</bAlwaysHeal>
<bHillsDoubleMove>0</bHillsDoubleMove>
<bImmuneToFirstStrikes>0</bImmuneToFirstStrikes>
<iVisibilityChange>0</iVisibilityChange>
<iMovesChange>0</iMovesChange>
<iMoveDiscountChange>0</iMoveDiscountChange>
<iWithdrawalChange>0</iWithdrawalChange>
<iCollateralDamageChange>0</iCollateralDamageChange>
<iBombardRateChange>0</iBombardRateChange>
<iFirstStrikesChange>0</iFirstStrikesChange>
<iChanceFirstStrikesChange>0</iChanceFirstStrikesChange>
<iEnemyHealChange>0</iEnemyHealChange>
<iNeutralHealChange>0</iNeutralHealChange>
<iFriendlyHealChange>0</iFriendlyHealChange>
<iSameTileHealChange>0</iSameTileHealChange>
<iAdjacentTileHealChange>0</iAdjacentTileHealChange>
<iCombatPercent>0</iCombatPercent>
<iCityAttack>0</iCityAttack>
<iCityDefense>0</iCityDefense>
<iHillsDefense>0</iHillsDefense>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitCombatMods/>
<DomainMods/>
<TerrainDoubleMoves/>
<FeatureDoubleMoves/>
<UnitCombats/>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<Button>Art/Interface/Buttons/Promotions/accuracy.dds</Button>
</PromotionInfo>
Now for some Python Code in python/CvEventManager.py:
Find:
def onUnitCreated(self, argsList):
'Unit Completed'
unit = argsList[0]
player = PyPlayer(unit.getOwner())
if (not self.__LOG_UNITBUILD):
return
And replace it with: (Will provide 10 and lvl 3 to new siege units)
def onUnitCreated(self, argsList):
'Unit Completed'
unit = argsList[0]
player = PyPlayer(unit.getOwner())
if unit.getUnitCombatType() == gc.getInfoTypeForString("UNITCOMBAT_SIEGE"):
unit.setLevel(3)
unit.setExperience(10,10)
if (not self.__LOG_UNITBUILD):
return
Then find:
def onUnitPromoted(self, argsList):
'Unit Promoted'
pUnit, iPromotion = argsList
player = PyPlayer(pUnit.getOwner())
if (not self.__LOG_UNITPROMOTED):
return
CvUtil.pyPrint('Unit Promotion Event: %s - %s' %(player.getCivilizationName(), pUnit.getName(),))
And replace with: (Creates a barrage by using the Fire promotion.)
def onUnitPromoted(self, argsList):
'Modded: Unit Promoted'
pUnit, iPromotion = argsList
player = pUnit.getOwner()
pPlayer = gc.getPlayer(player)
iX = pUnit.getX()
iY = pUnit.getY()
if pUnit.isHasPromotion(gc.getInfoTypeForString('PROM OTION_FIRE')) and (pUnit.getUnitType() == gc.getInfoTypeForString('UNIT_CATAPULT')) :
if (pUnit.movesLeft() == 60) and (not pUnit.area().isWater()):
newUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_CAT APULT_ROCKS'), pUnit.getX(), pUnit.getY(), UnitAITypes.NO_UNITAI)
newUnit.setHasPromotion(gc.getInfoTypeForString('P ROMOTION_ORDNANCE'), True)
pUnit.setHasPromotion(gc.getInfoTypeForString('PRO MOTION_FIRE'), False)
pUnit.setLevel(3)
pUnit.setExperience(10, -1)
if (not self.__LOG_UNITPROMOTED):
return
Then find:
def onEndPlayerTurn(self, argsList):
'Called at the end of a players turn'
iGameTurn, iPlayer = argsList
if (gc.getGame().getElapsedGameTurns() == 1):
if (gc.getPlayer(iPlayer).isHuman()):
if (gc.getPlayer(iPlayer).canRevolution(0)):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTT ONPOPUP_CHANGECIVIC)
popupInfo.addPopup(iPlayer)
CvAdvisorUtils.resetAdvisorNags()
CvAdvisorUtils.endTurnFeats(iPlayer)
And replace with: (Will remove barrage on end turn.)
def onEndPlayerTurn(self, argsList):
'Called at the end of a players turn'
iGameTurn, iPlayer = argsList
pPlayer = gc.getPlayer(iPlayer)
for i in range(pPlayer.getNumUnits(), 0, -1):
pUnit = pPlayer.getUnit(i)
if pUnit.isHasPromotion(gc.getInfoTypeForString('PROM OTION_ORDNANCE')):
pUnit.kill(False,0)
if (gc.getGame().getElapsedGameTurns() == 1):
if (gc.getPlayer(iPlayer).isHuman()):
if (gc.getPlayer(iPlayer).canRevolution(0)):
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTT ONPOPUP_CHANGECIVIC)
popupInfo.addPopup(iPlayer)
CvAdvisorUtils.resetAdvisorNags()
CvAdvisorUtils.endTurnFeats(iPlayer)
Finally, remove the ability of your siege to fight itself. E.g. like this in xml/units/CIV4UnitInfos.xml:
<UnitInfo>
<Class>UNITCLASS_CATAPULT</Class>
<Type>UNIT_CATAPULT</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
<Combat>UNITCOMBAT_SIEGE</Combat>
<Domain>DOMAIN_LAND</Domain>
<DefaultUnitAI>UNITAI_ATTACK_CITY</DefaultUnitAI>
<Invisible>NONE</Invisible>
<SeeInvisible>NONE</SeeInvisible>
<Description>TXT_KEY_UNIT_CATAPULT</Description>
<Civilopedia>TXT_KEY_UNIT_CATAPULT_PEDIA</Civilopedia>
<Strategy>TXT_KEY_UNIT_CATAPULT_STRATEGY</Strategy>
<Advisor>ADVISOR_MILITARY</Advisor>
<bAnimal>0</bAnimal>
<bFood>0</bFood>
<bNoBadGoodies>0</bNoBadGoodies>
<bOnlyDefensive>1</bOnlyDefensive>
<bNoCapture>1</bNoCapture>
<bRivalTerritory>0</bRivalTerritory>
<bMilitaryHappiness>1</bMilitaryHappiness>
<bMilitarySupport>1</bMilitarySupport>
<bMilitaryProduction>1</bMilitaryProduction>
<bPillage>0</bPillage>
<bSabotage>0</bSabotage>
<bDestroy>0</bDestroy>
<bStealPlans>0</bStealPlans>
<bInvestigate>0</bInvestigate>
<bCounterSpy>0</bCounterSpy>
<bFound>0</bFound>
<bGoldenAge>0</bGoldenAge>
<bInvisible>0</bInvisible>
<bFirstStrikeImmune>0</bFirstStrikeImmune>
<bNoDefensiveBonus>1</bNoDefensiveBonus>
<bIgnoreBuildingDefense>0</bIgnoreBuildingDefense>
<bCanMoveImpassable>0</bCanMoveImpassable>
<bFlatMovementCost>0</bFlatMovementCost>
<bIgnoreTerrainCost>0</bIgnoreTerrainCost>
<bNukeImmune>0</bNukeImmune>
<bPrereqBonuses>0</bPrereqBonuses>
<bPrereqReligion>0</bPrereqReligion>
<bMechanized>1</bMechanized>
<UnitClassUpgrades>
<UnitClassUpgrade>
<UnitClassUpgradeType>UNITCLASS_CANNON</UnitClassUpgradeType>
<bUnitClassUpgrade>1</bUnitClassUpgrade>
</UnitClassUpgrade>
</UnitClassUpgrades>
<UnitAIs>
<UnitAI>
<UnitAIType>UNITAI_ATTACK_CITY</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
<UnitAI>
<UnitAIType>UNITAI_COLLATERAL</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
</UnitAIs>
<NotUnitAIs/>
<Builds/>
<ReligionSpreads/>
<GreatPeoples/>
<Buildings/>
<ForceBuildings/>
<HolyCity>NONE</HolyCity>
<ReligionType>NONE</ReligionType>
<StateReligion>NONE</StateReligion>
<PrereqReligion>NONE</PrereqReligion>
<PrereqBuilding>NONE</PrereqBuilding>
<PrereqTech>TECH_MATHEMATICS</PrereqTech>
<TechTypes/>
<BonusType>NONE</BonusType>
<PrereqBonuses/>
<ProductionTraits/>
<Flavors/>
<iAIWeight>0</iAIWeight>
<iCost>40</iCost>
<iHurryCostModifier>0</iHurryCostModifier>
<iMinAreaSize>-1</iMinAreaSize>
<iMoves>1</iMoves>
<iAirRange>0</iAirRange>
<iNukeRange>-1</iNukeRange>
<iWorkRate>0</iWorkRate>
<iBaseDiscover>0</iBaseDiscover>
<iDiscoverMultiplier>0</iDiscoverMultiplier>
<iBaseHurry>0</iBaseHurry>
<iHurryMultiplier>0</iHurryMultiplier>
<iBaseTrade>0</iBaseTrade>
<iTradeMultiplier>0</iTradeMultiplier>
<iGreatWorkCulture>0</iGreatWorkCulture>
<TerrainImpassables/>
<FeatureImpassables/>
<iCombat>2</iCombat>
<iAirCombat>0</iAirCombat>
<iAirCombatLimit>0</iAirCombatLimit>
<iXPValueAttack>4</iXPValueAttack>
<iXPValueDefense>2</iXPValueDefense>
<iFirstStrikes>0</iFirstStrikes>
<iChanceFirstStrikes>0</iChanceFirstStrikes>
<iInterceptionProbability>0</iInterceptionProbability>
<iEvasionProbability>0</iEvasionProbability>
<iWithdrawalProb>0</iWithdrawalProb>
<iCollateralDamage>0</iCollateralDamage>
<iCollateralDamageLimit>0</iCollateralDamageLimit>
<iCollateralDamageMaxUnits>0</iCollateralDamageMaxUnits>
<iCityAttack>0</iCityAttack>
<iCityDefense>0</iCityDefense>
<iAnimalCombat>0</iAnimalCombat>
<iHillsDefense>0</iHillsDefense>
<TerrainNatives/>
<FeatureNatives/>
<TerrainDefenses/>
<FeatureDefenses/>
<UnitClassAttackMods/>
<UnitClassDefenseMods/>
<UnitCombatMods/>
<DomainMods/>
<BonusProductionModifiers/>
<iBombRate>0</iBombRate>
<iBombardRate>0</iBombardRate>
<SpecialCargo>NONE</SpecialCargo>
<DomainCargo>NONE</DomainCargo>
<iCargo>0</iCargo>
<iConscription>0</iConscription>
<iCultureGarrison>4</iCultureGarrison>
<iExtraCost>0</iExtraCost>
<iAsset>2</iAsset>
<iPower>3</iPower>
<UnitMeshGroups>
<iGroupSize>2</iGroupSize>
<fMaxSpeed>1.25</fMaxSpeed>
<iMeleeWaveSize>2</iMeleeWaveSize>
<iRangedWaveSize>2</iRangedWaveSize>
<UnitMeshGroup>
<iRequired>2</iRequired>
<EarlyArtDefineTag>ART_DEF_UNIT_CATAPULT</EarlyArtDefineTag>
</UnitMeshGroup>
</UnitMeshGroups>
<Button>,Art/Interface/Buttons/Units/Catapult.dds,Art/Interface/Buttons/Unit_Resource_Atlas.dds,7,8</Button>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<FreePromotions/>
</UnitInfo>
Test and, if you like it, implement for the rest of the siege units.
I think that was all (Phew! I hope I got it all right! :crazyeye: ). Thoughts?