TEMPLATE: unit automatically gives its killer a promotion

Bad Player

Deity
Joined
Oct 31, 2005
Messages
3,534
Location
(Bris)Vegas!
A simple script to make the killer of a unit receive a promotion. In this case (which is easily modified by changing the red text to whatever unit and promotion you want), the unit which kills a BadPlayerDemon will receive the Demon Slaying promotion.

1) Add to the file CIV4GameText_FFH2.xml:
Code:
    <TEXT>
        <Tag>[COLOR="Red"]TXT_KEY_UNIT_BAD_PLAYER_DEMON[/COLOR]</Tag>
        <English>[COLOR="red"]Bad Player Demon[/COLOR]</English>
        <French>[COLOR="red"]Bad Player Demon[/COLOR]</French>
        <German>[COLOR="red"]Bad Player Demon[/COLOR]</German>
        <Italian>[COLOR="red"]Bad Player Demon[/COLOR]</Italian>
        <Spanish>[COLOR="red"]Bad Player Demon[/COLOR]</Spanish>
    </TEXT>
    <TEXT>
        <Tag>[COLOR="red"]TXT_KEY_UNIT_BAD_PLAYER_DEMON_PEDIA[/COLOR]</Tag>
        <English>[COLOR="red"]BP's test unit.  It should give the unit which kills it the demon slaying promotion.  It is using the Champion unit for everything except the name and the promotion given upon death.[/COLOR]</English>
        <French>Most of the Lanun army is conscripted to serve as deckhands at one time or another. Those that show aptitude at sea are trained to be boarding parties, fearless (after enough grog) and deadly (at least on sea) these sea monkeys are ever eager to swing to an enemy vessel and dispatch the crew, claiming the prize for themselves.</French>
        <German>Die meisten aus der Lanun Armee sind verpflichtet mindestens einmal als Matrosen zu dienen. Diejenigen, die eine Eignung fürs Meer zeigen, werden ausgebildet um Entermannschafften zu werden. Furchtlos (nach genug Grog) und tödlich (wenigstesns auf See) sind diese Seeaffen immer begierig darauf sich hinüber zu einem feindlichen Schiff zu schwingen, um Mannschafften zu erledigen und die Schätze für sich in Besitz zu nehmen.</German>
        <Italian>Most of the Lanun army is conscripted to serve as deckhands at one time or another. Those that show aptitude at sea are trained to be boarding parties, fearless (after enough grog) and deadly (at least on sea) these sea monkeys are ever eager to swing to an enemy vessel and dispatch the crew, claiming the prize for themselves.</Italian>
        <Spanish>Most of the Lanun army is conscripted to serve as deckhands at one time or another. Those that show aptitude at sea are trained to be boarding parties, fearless (after enough grog) and deadly (at least on sea) these sea monkeys are ever eager to swing to an enemy vessel and dispatch the crew, claiming the prize for themselves.</Spanish>
    </TEXT>
    <TEXT>
        <Tag>[COLOR="red"]TXT_KEY_UNIT_BAD_PLAYER_DEMON_STRATEGY[/COLOR]</Tag>
        <English>[COLOR="red"]BP's test unit.  It should give the unit which kills it the demon slaying promotion.  It is using the Champion unit for everything except the name and the promotion given upon death.[/COLOR]</English>
        <French>Although capable fighters on their own, Boarding parties are also able to attack naval units. And if they win, the naval unit comes under their control. They require a harbor to train and gain strength from metal resources as with other melee units.</French>
        <German>Obwohl sie alleine schon fähige Kämpfer sind, können Entermannschaften auch Wassereinheiten angreifen. Und falls sie gewinnen, gerät die Wassereinheit unter ihre Kontrolle. Sie benötigen einen Hafen um ausgebildet zu werden und gewinnen, wie andere Nahkampfeinheiten auch, durch Metallressourcen an Stärke.</German>
        <Italian>Although capable fighters on their own, Boarding parties are also able to attack naval units. And if they win, the naval unit comes under their control. They require a harbor to train and gain strength from metal resources as with other melee units.</Italian>
        <Spanish>Although capable fighters on their own, Boarding parties are also able to attack naval units. And if they win, the naval unit comes under their control. They require a harbor to train and gain strength from metal resources as with other melee units.</Spanish>
    </TEXT>

2) Add to the file CIV4UnitInfos.xml (N.B. This is a champion unit, just use whatever other unit you prefer from the same file as a base):
Code:
       <UnitInfo>
            <Class>UNITCLASS_CHAMPION</Class>
            <Type>[COLOR="red"]UNIT_BAD_PLAYER_DEMON[/COLOR]</Type>
            <UniqueNames>
            </UniqueNames>
            <Special>NONE</Special>
            <Capture>NONE</Capture>
            <Combat>UNITCOMBAT_MELEE</Combat>
            <Domain>DOMAIN_LAND</Domain>
            <DefaultUnitAI>UNITAI_ATTACK</DefaultUnitAI>
            <Invisible>NONE</Invisible>
            <SeeInvisible>NONE</SeeInvisible>
            <Description>[COLOR="red"]TXT_KEY_UNIT_BAD_PLAYER_DEMON[/COLOR]</Description>
            <Civilopedia>TXT_KEY_UNIT_PLACEHOLDER_PEDIA</Civilopedia>
            <Strategy>[COLOR="red"]TXT_KEY_UNIT_BAD_PLAYER_DEMON_STRATEGY[/COLOR]</Strategy>
            <Advisor>ADVISOR_MILITARY</Advisor>
            <bAnimal>0</bAnimal>
            <bFood>0</bFood>
            <bNoBadGoodies>0</bNoBadGoodies>
            <bOnlyDefensive>0</bOnlyDefensive>
            <bNoCapture>0</bNoCapture>
            <bQuickCombat>0</bQuickCombat>
            <bRivalTerritory>0</bRivalTerritory>
            <bMilitaryHappiness>1</bMilitaryHappiness>
            <bMilitarySupport>1</bMilitarySupport>
            <bMilitaryProduction>1</bMilitaryProduction>
            <bPillage>1</bPillage>
            <bSpy>0</bSpy>
            <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>
            <bCanMoveAllTerrain>0</bCanMoveAllTerrain>
            <bFlatMovementCost>0</bFlatMovementCost>
            <bIgnoreTerrainCost>0</bIgnoreTerrainCost>
            <bNukeImmune>0</bNukeImmune>
            <bPrereqBonuses>0</bPrereqBonuses>
            <bPrereqReligion>0</bPrereqReligion>
            <bMechanized>0</bMechanized>
            <bSuicide>0</bSuicide>
            <bHiddenNationality>0</bHiddenNationality>
            <bAlwaysHostile>0</bAlwaysHostile>
            <UnitClassUpgrades>
                <UnitClassUpgrade>
                    <UnitClassUpgradeType>UNITCLASS_IMMORTAL</UnitClassUpgradeType>
                    <bUnitClassUpgrade>1</bUnitClassUpgrade>
                </UnitClassUpgrade>
                <UnitClassUpgrade>
                    <UnitClassUpgradeType>UNITCLASS_BERSERKER</UnitClassUpgradeType>
                    <bUnitClassUpgrade>1</bUnitClassUpgrade>
                </UnitClassUpgrade>
                <UnitClassUpgrade>
                    <UnitClassUpgradeType>UNITCLASS_PHALANX</UnitClassUpgradeType>
                    <bUnitClassUpgrade>1</bUnitClassUpgrade>
                </UnitClassUpgrade>
                <UnitClassUpgrade>
                    <UnitClassUpgradeType>UNITCLASS_PALADIN</UnitClassUpgradeType>
                    <bUnitClassUpgrade>1</bUnitClassUpgrade>
                </UnitClassUpgrade>
                <UnitClassUpgrade>
                    <UnitClassUpgradeType>UNITCLASS_EIDOLON</UnitClassUpgradeType>
                    <bUnitClassUpgrade>1</bUnitClassUpgrade>
                </UnitClassUpgrade>
                <UnitClassUpgrade>
                    <UnitClassUpgradeType>UNITCLASS_KNIGHT</UnitClassUpgradeType>
                    <bUnitClassUpgrade>1</bUnitClassUpgrade>
                </UnitClassUpgrade>
            </UnitClassUpgrades>
            <UnitClassTargets>
            </UnitClassTargets>
            <UnitCombatTargets>
            </UnitCombatTargets>
            <UnitClassDefenders>
            </UnitClassDefenders>
            <UnitCombatDefenders>
            </UnitCombatDefenders>
            <FlankingStrikes>
            </FlankingStrikes>
            <UnitAIs>
                <UnitAI>
                    <UnitAIType>UNITAI_ATTACK</UnitAIType>
                    <bUnitAI>1</bUnitAI>
                </UnitAI>
                <UnitAI>
                    <UnitAIType>UNITAI_ATTACK_CITY</UnitAIType>
                    <bUnitAI>1</bUnitAI>
                </UnitAI>
                <UnitAI>
                    <UnitAIType>UNITAI_COUNTER</UnitAIType>
                    <bUnitAI>1</bUnitAI>
                </UnitAI>
                <UnitAI>
                    <UnitAIType>UNITAI_CITY_COUNTER</UnitAIType>
                    <bUnitAI>1</bUnitAI>
                </UnitAI>
            </UnitAIs>
            <NotUnitAIs>
            </NotUnitAIs>
            <Builds>
            </Builds>
            <ReligionSpreads>
            </ReligionSpreads>
            <CorporationSpreads>
            </CorporationSpreads>
            <GreatPeoples>
            </GreatPeoples>
            <Buildings>
            </Buildings>
            <ForceBuildings>
            </ForceBuildings>
            <HolyCity>NONE</HolyCity>
            <ReligionType>NONE</ReligionType>
            <StateReligion>NONE</StateReligion>
            <PrereqReligion>NONE</PrereqReligion>
            <PrereqCorporation>NONE</PrereqCorporation>
            <PrereqBuilding>NONE</PrereqBuilding>
            <PrereqTech>TECH_IRON_WORKING</PrereqTech>
            <TechTypes>
            </TechTypes>
            <BonusType>NONE</BonusType>
            <PrereqBonuses>
            </PrereqBonuses>
            <ProductionTraits>
            </ProductionTraits>
            <Flavors>
            </Flavors>
            <iAIWeight>0</iAIWeight>
            <iCost>120</iCost>
            <iHurryCostModifier>0</iHurryCostModifier>
            <iAdvancedStartCost>100</iAdvancedStartCost>
            <iAdvancedStartCostIncrease>0</iAdvancedStartCostIncrease>
            <iMinAreaSize>-1</iMinAreaSize>
            <iMoves>1</iMoves>
            <bNoRevealMap>0</bNoRevealMap>
            <iAirRange>0</iAirRange>
            <iAirUnitCap>0</iAirUnitCap>
            <iDropRange>0</iDropRange>
            <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>
            <iEspionagePoints>0</iEspionagePoints>
            <TerrainImpassables>
            </TerrainImpassables>
            <FeatureImpassables>
            </FeatureImpassables>
            <TerrainPassableTechs>
            </TerrainPassableTechs>
            <FeaturePassableTechs>
            </FeaturePassableTechs>
            <iCombat>6</iCombat>
            <iCombatLimit>100</iCombatLimit>
            <iAirCombat>0</iAirCombat>
            <iAirCombatLimit>0</iAirCombatLimit>
            <iXPValueAttack>8</iXPValueAttack>
            <iXPValueDefense>4</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>
            <iHillsAttack>0</iHillsAttack>
            <iHillsDefense>0</iHillsDefense>
            <TerrainNatives>
            </TerrainNatives>
            <FeatureNatives>
            </FeatureNatives>
            <TerrainAttacks>
            </TerrainAttacks>
            <TerrainDefenses>
            </TerrainDefenses>
            <FeatureAttacks>
            </FeatureAttacks>
            <FeatureDefenses>
            </FeatureDefenses>
            <UnitClassAttackMods>
            </UnitClassAttackMods>
            <UnitClassDefenseMods>
            </UnitClassDefenseMods>
            <UnitCombatMods>
                <UnitCombatMod>
                    <UnitCombatType>UNITCOMBAT_MELEE</UnitCombatType>
                    <iUnitCombatMod>25</iUnitCombatMod>
                </UnitCombatMod>
            </UnitCombatMods>
            <UnitCombatCollateralImmunes>
            </UnitCombatCollateralImmunes>
            <DomainMods>
            </DomainMods>
            <BonusProductionModifiers>
            </BonusProductionModifiers>
            <iBombRate>0</iBombRate>
            <iBombardRate>0</iBombardRate>
            <SpecialCargo>NONE</SpecialCargo>
            <DomainCargo>NONE</DomainCargo>
            <iCargo>0</iCargo>
            <iConscription>3</iConscription>
            <iCultureGarrison>6</iCultureGarrison>
            <iExtraCost>0</iExtraCost>
            <iAsset>9</iAsset>
            <iPower>18</iPower>
            <UnitMeshGroups>
            <iGroupSize>3</iGroupSize>
            <fMaxSpeed>1.75</fMaxSpeed>
            <fPadTime>1</fPadTime>
            <iMeleeWaveSize>3</iMeleeWaveSize>
            <iRangedWaveSize>0</iRangedWaveSize>
                <UnitMeshGroup>
                    <iRequired>3</iRequired>
                    <EarlyArtDefineTag>ART_DEF_UNIT_CHAMPION</EarlyArtDefineTag>
                </UnitMeshGroup>
            </UnitMeshGroups>
            <FormationType>FORMATION_TYPE_DEFAULT</FormationType>
            <HotKey></HotKey>
            <bAltDown>0</bAltDown>
            <bShiftDown>0</bShiftDown>
            <bCtrlDown>0</bCtrlDown>
            <bGraphicalOnly>0</bGraphicalOnly>
            <iHotKeyPriority>0</iHotKeyPriority>
            <FreePromotions>
            </FreePromotions>
            <LeaderPromotion>NONE</LeaderPromotion>
            <iLeaderExperience>0</iLeaderExperience>
            <bNeverObsolete>1</bNeverObsolete>
            <iCombatDefense>6</iCombatDefense>
            <iTier>3</iTier>
            <iWeaponTier>3</iWeaponTier>
            <PrereqBuildingClass>BUILDINGCLASS_TRAINING_YARD</PrereqBuildingClass>
[COLOR="red"]<PythonPostCombatLost>postCombatBadPlayerDemon(pCaster,pOpponent)</PythonPostCombatLost>[/COLOR]
        </UnitInfo>

3) Add to the file CvSpellInterface.py:
Code:
def postCombat[COLOR="red"]BadPlayerDemon[/COLOR](pCaster, pOpponent):
	pOpponent.setHasPromotion(gc.getInfoTypeForString('[COLOR="red"]PROMOTION_DEMON_SLAYING[/COLOR]'), True)



I hope even complete beginners could just change a few words and make a different unit receive a different promotion.
 
3) Add to the file CvSpellInterface.py:
Code:
def postCombat[COLOR="red"]BadPlayerDemon[/COLOR](pCaster, pOpponent):
	pOpponent.setHasPromotion(gc.getInfoTypeForString('[COLOR="red"]PROMOTION_DEMON_SLAYING[/COLOR]'), True)

Don't you need an if statement in your function to check if the killed unit is the UNIT_BAD_PLAYER_DEMON?
Code:
	if pCaster.getUnitType() == gc.getInfoTypeForString('[COLOR="red"]UNIT_BAD_PLAYER_DEMON[/COLOR]'):
		pOpponent.setHasPromotion(gc.getInfoTypeForString('[COLOR="red"]PROMOTION_DEMON_SLAYING[/COLOR]'), True)

Alternative if statements might look at the promotions the killed unit/surviving unit had.

I'd put the python code in onUnitKilled, either modularly as in RifE or else in CvEventManager.
 
I don't know much about python (I'm trying to learn) but I tested this in a 1 v 1 situation and it works. I'll test it in a stack vs stack situation now. EDIT: Tested it in a stack situation and it works (see attached post-combat pictures to show that only the aquebus which attacked the bad player demon received the demon slaying promotion).



A lot of my code is based off Hyborem's section (the postCombatHyborem) and the mimic (promotion section).
 
Very nice code and and very easy to follow. Thank you!

3) Add to the file CvSpellInterface.py:
Code:
def postCombat[COLOR="red"]BadPlayerDemon[/COLOR](pCaster, pOpponent):
	pOpponent.setHasPromotion(gc.getInfoTypeForString('[COLOR="red"]PROMOTION_DEMON_SLAYING[/COLOR]'), True)

I don 't know Python myself so how would I add a 50%-chance condition into the above snippet like:

if random(100) >50 then ... [call setHasPromotion]
 
Top Bottom