Modding: C&C Generals: Creating a New General's Power

C&C Generals ModdingThe Step-by-Step Guide to Creating a New General's Power by Cloning an Existing One
Learning by Example: Giving the Chinese Artillery Barrage General's Power to the GLA
By CommieDog

This tutorial assumes that you already know how to access the INI files within INI.big (INIZH.big for Zero Hour), extract them to the proper location, and know how to edit them. People who cannot handle these tasks would be better served looking at a beginner's tutorial and getting some basic modding experience before jumping headfirst into a more difficult task such as this.

As you might have guessed by the title, this tutorial is about adding a new General's Power to a side. I prefer to use the cloning method (copying existing code and changing whatever is necessary in the copy) as opposed to typing new code from scratch as it greatly reduces the likelihood of a typo interfering. For the purposes of this tutorial, I will use the example of cloning China's Artillery Barrage power and giving it to the GLA. You'll probably want to clone another General's Power at some point, but the principle is the same. So, without any further disclaimers, here is the step-by-step guide:

  1. Clone all Artillery Barrage Sciences (3 of them in this case) in Science.ini. Be sure to give each Science a new name (a common mistake when cloning code) and change the PrerequisiteScience= values so that SCIENCE_GLA is present instead of SCIENCE_CHINA for the first level and that levels 2 and 3 refer to the new Sciences 1 level beneath them, or else your new Artillery Barrage clone will be inaccessable.

    Science SCIENCE_GLAArtilleryBarrage1
      PrerequisiteSciences = SCIENCE_GLA SCIENCE_Rank3
      SciencePurchasePointCost = 1
      IsGrantable = Yes
      DisplayName = SCIENCE:ChinaArtilleryBarrage
      Description = CONTROLBAR:ToolTipChinaScienceArtilleryBarrage
    End
    
    Science SCIENCE_GLAArtilleryBarrage2
      PrerequisiteSciences = SCIENCE_GLAArtilleryBarrage1 SCIENCE_Rank3
      SciencePurchasePointCost = 1
      IsGrantable = Yes
      DisplayName = SCIENCE:ChinaArtilleryBarrage2
      Description = CONTROLBAR:ToolTipChinaScienceArtilleryBarrage
    End
    
    Science SCIENCE_GLAArtilleryBarrage3
      PrerequisiteSciences = SCIENCE_GLAArtilleryBarrage2 SCIENCE_Rank3
      SciencePurchasePointCost = 1
      IsGrantable = Yes
      DisplayName = SCIENCE:ChinaArtilleryBarrage3
      Description = CONTROLBAR:ToolTipChinaScienceArtilleryBarrage
    End
  2. Clone the Artillery Barrage SpecialPower in SpecialPower.ini. Change the RequiredScience= value to refer to the level 1 version of your cloned Sciences. In addition, you will need to change the Enum= value to something used by a SpecialPower that was cut from Generals or ZH at some point. The Napalm Strike is a good example of this, so I'm going to copy SPECIAL_NAPALM_STRIKE from it for my new Artillery Barrage. If you are modding normal Generals, then the AcademyClassify= line will not exist. No not panic, as this was new code added for Zero Hour.
    ;-----------------------------------------------------------------------------
    SpecialPower SuperweaponGLAArtilleryBarrage
      Enum                = SPECIAL_NAPALM_STRIKE
      ReloadTime          = 300000   ; in milliseconds. min is 2x door/open close time!
      RequiredScience     = SCIENCE_GLAArtilleryBarrage1
      InitiateSound       = FireArtilleryCannonSound
      PublicTimer         = No
      SharedSyncedTimer   = Yes
      ViewObjectDuration  = 30000
      ViewObjectRange     = 250
      RadiusCursorRadius  = 125
      ShortcutPower       = Yes     ;Capable of being fired by the side-bar shortcut.
      AcademyClassify     = ACT_SUPERPOWER ;Considered a powerful special power that a player could fire. Not for simpler unit based powers.
    End
  3. Clone all Artillery Barrage OCL's (ObjectCreationLists) from ObjectCreationList.ini. (Again, there are 3 of them in this case). Fortunately, no change is required beyond a simple name edit.
    ;-----------------------------------------------------------------------------
    ;-----------------------------------------------------------------------------
    ObjectCreationList SUPERWEAPON_GLAArtilleryBarrage1
      DeliverPayload
        Transport                       = ChinaArtilleryCannon
        FormationSize                   = 12
        FormationSpacing                = 1.0
        StartAtPreferredHeight          = Yes
        StartAtMaxSpeed                 = Yes
        MaxAttempts                     = 1                   ;max attempts
        DeliveryDistance                = 250                 ;distance from target allowed to start/stop dropping.
        WeaponErrorRadius               = 100                 ; how bad the artillerist is
        DelayDeliveryMax                = 3000                ; his delayed reaction to "Fire!"
        VisibleItemsDroppedPerInterval  = 1                   ;Drops two bombs at a time
        VisibleDropBoneBaseName         = RootTransform       ;The bombs are created and dropped at this bone base
        VisibleSubObjectBaseName        = Bomb                ;The bombs are visible until dropped.
        VisibleNumBones                 = 1                   ;Number of bones.
        VisiblePayloadTemplateName      = ChinaArtilleryBarrageShell  ;Created when payload is dropped.
        VisiblePayloadWeaponTemplate    = ArtilleryBarrageDamageWeapon
        InheritTransportVelocity        = Yes                 ;The bombs will start at transport velocity.
        ExitPitchRate                   = 30                  ;The bomb will pitch down.
        SelfDestructObject              = Yes                 ; so the delivery vehicle goes away 'POP!'
        DeliveryDecalRadius = 125
        DeliveryDecal
          Texture           = SCCArtilleryBarrage_China
          Style             = SHADOW_ALPHA_DECAL
          OpacityMin        = 25%
          OpacityMax        = 50%
          OpacityThrobTime  = 500
          Color             = R:255 G:156 B:0 A:255
          OnlyVisibleToOwningPlayer = Yes
        End
      End
    End
    
    
    ;-----------------------------------------------------------------------------
    ;-----------------------------------------------------------------------------
    ObjectCreationList SUPERWEAPON_GLAArtilleryBarrage2
      DeliverPayload
        Transport                       = ChinaArtilleryCannon
        FormationSize                   = 24
        FormationSpacing                = 1.0
        StartAtPreferredHeight          = Yes
        StartAtMaxSpeed                 = Yes
        MaxAttempts                     = 1                   ;max attempts
        DeliveryDistance                = 250                 ;distance from target allowed to start/stop dropping.
        WeaponErrorRadius               = 100                 ; how bad the artillerist is
        DelayDeliveryMax                = 3000                ; his delayed reaction to "Fire!"
        VisibleItemsDroppedPerInterval  = 1                   ;Drops two bombs at a time
        VisibleDropBoneBaseName         = RootTransform       ;The bombs are created and dropped at this bone base
        VisibleSubObjectBaseName        = Bomb                ;The bombs are visible until dropped.
        VisibleNumBones                 = 1                   ;Number of bones.
        VisiblePayloadTemplateName      = ChinaArtilleryBarrageShell  ;Created when payload is dropped.
        VisiblePayloadWeaponTemplate    = ArtilleryBarrageDamageWeapon
        InheritTransportVelocity        = Yes                 ;The bombs will start at transport velocity.
        ExitPitchRate                   = 30                  ;The bomb will pitch down.
        SelfDestructObject              = Yes                 ; so the delivery vehicle goes away 'POP!'
        DeliveryDecalRadius = 125
        DeliveryDecal
          Texture           = SCCArtilleryBarrage_China
          Style             = SHADOW_ALPHA_DECAL
          OpacityMin        = 25%
          OpacityMax        = 50%
          OpacityThrobTime  = 500
          Color             = R:255 G:156 B:0 A:255
          OnlyVisibleToOwningPlayer = Yes
        End
      End
    End
    
    
    ;-----------------------------------------------------------------------------
    ;-----------------------------------------------------------------------------
    ObjectCreationList SUPERWEAPON_GLAArtilleryBarrage3
      DeliverPayload
        Transport                       = ChinaArtilleryCannon
        FormationSize                   = 36
        FormationSpacing                = 1.0
        StartAtPreferredHeight          = Yes
        StartAtMaxSpeed                 = Yes
        MaxAttempts                     = 1                  ;max attempts
        DeliveryDistance                = 250                 ;distance from target allowed to start/stop dropping.
        WeaponErrorRadius               = 100                 ; how bad the artillerist is
        DelayDeliveryMax                = 3000                ; his delayed reaction to "Fire!"
        VisibleItemsDroppedPerInterval  = 1                   ;Drops two bombs at a time
        VisibleDropBoneBaseName         = RootTransform       ;The bombs are created and dropped at this bone base
        VisibleSubObjectBaseName        = Bomb                ;The bombs are visible until dropped.
        VisibleNumBones                 = 1                   ;Number of bones.
        VisiblePayloadTemplateName      = ChinaArtilleryBarrageShell  ;Created when payload is dropped.
        VisiblePayloadWeaponTemplate    = ArtilleryBarrageDamageWeapon
        InheritTransportVelocity        = Yes                 ;The bombs will start at transport velocity.
        ExitPitchRate                   = 30                  ;The bomb will pitch down.
        SelfDestructObject              = Yes                 ; so the delivery vehicle goes away 'POP!'
        DeliveryDecalRadius = 125
        DeliveryDecal
          Texture           = SCCArtilleryBarrage_China
          Style             = SHADOW_ALPHA_DECAL
          OpacityMin        = 25%
          OpacityMax        = 50%
          OpacityThrobTime  = 500
          Color             = R:255 G:156 B:0 A:255
          OnlyVisibleToOwningPlayer = Yes
        End
      End
    End
  4. Now you'll need to clone a total of 5 CommandButtons in CommandButton.ini: 3 for you to purchase your new Artillery Barrage and 2 to fire it. (Notice a pattern here?) As before, substitute your new code name wherever there is a reference to the original Artillery Barrage.
    CommandButton Command_PurchaseScienceGLAArtilleryBarrage1
      Command           = PURCHASE_SCIENCE
      Science           = SCIENCE_GLAArtilleryBarrage1
      ButtonImage       = SSBarrage
      ButtonBorderType  = UPGRADE ; Identifier for the User as to what kind of button this is
    End
    
    CommandButton Command_PurchaseScienceGLAArtilleryBarrage2
      Command           = PURCHASE_SCIENCE
      Science           = SCIENCE_GLAArtilleryBarrage2
      ButtonImage       = SSBarrage2
      ButtonBorderType  = UPGRADE ; Identifier for the User as to what kind of button this is
    End
    
    CommandButton Command_PurchaseScienceGLAArtilleryBarrage3
      Command           = PURCHASE_SCIENCE
      Science           = SCIENCE_GLAArtilleryBarrage3
      ButtonImage       = SSBarrage3
      ButtonBorderType  = UPGRADE ; Identifier for the User as to what kind of button this is
    End
    
    
    CommandButton Command_GLAArtilleryBarrage
      Command           = SPECIAL_POWER
      SpecialPower      = SuperweaponGLAArtilleryBarrage
      Options           = NEED_SPECIAL_POWER_SCIENCE NEED_TARGET_POS CONTEXTMODE_COMMAND
      Science           = SCIENCE_GLAArtilleryBarrage1 SCIENCE_GLAArtilleryBarrage2 SCIENCE_GLAArtilleryBarrage3
      TextLabel         = CONTROLBAR:ArtilleryBarrage
      ButtonImage       = SSBarrage
      ButtonBorderType  = ACTION ; Identifier for the User as to what kind of button this is
      DescriptLabel     = CONTROLBAR:TooltipFireArtilleryBarrage
      RadiusCursorType  = ARTILLERYBARRAGE
      InvalidCursorName     = GenericInvalid
    End
    
    
    CommandButton Command_GLAArtilleryBarrageFromShortcut
      Command           = SPECIAL_POWER_FROM_SHORTCUT
      SpecialPower      = SuperweaponGLAArtilleryBarrage
      Options           = NEED_SPECIAL_POWER_SCIENCE NEED_TARGET_POS CONTEXTMODE_COMMAND
      Science           = SCIENCE_GLAArtilleryBarrage1 SCIENCE_GLAArtilleryBarrage2 SCIENCE_GLAArtilleryBarrage3
      TextLabel         = CONTROLBAR:NoHotKeyArtilleryBarrage
      ButtonImage       = SSBarrage
      DescriptLabel     = CONTROLBAR:TooltipFireArtilleryBarrage
      RadiusCursorType  = ARTILLERYBARRAGE
      InvalidCursorName     = GenericInvalid
    End
  5. With everything ready, now you can set up your shiny new CommandButtons to appear ingame by adding their names in the appropriate places in CommandSet.ini.

    First off comes the new purchasing buttons. They belong in SCIENCE_GLA_CommandSetRank3, and I recommend placing them in slots 13, 14, and 15.

    CommandSet SCIENCE_GLA_CommandSetRank3
      1 = Command_PurchaseScienceHijacker
      4 = Command_PurchaseScienceRebelAmbush1
      5 = Command_PurchaseScienceRebelAmbush2
      6 = Command_PurchaseScienceRebelAmbush3
      7 = Command_PurchaseScienceCashBounty1
      8 = Command_PurchaseScienceCashBounty2
      9 = Command_PurchaseScienceCashBounty3
      10 = Command_PurchaseScienceEmergencyRepair1
      11 = Command_PurchaseScienceEmergencyRepair2
      12 = Command_PurchaseScienceEmergencyRepair3
      13 = Command_PurchaseScienceGLAArtilleryBarrage1
      14 = Command_PurchaseScienceGLAArtilleryBarrage2
      15 = Command_PurchaseScienceGLAArtilleryBarrage3
    END

    Next is the sidebar shortcut button, which goes in SpecialPowerShortcutGLA.

    CommandSet SpecialPowerShortcutGLA
      1 = Command_AmbushFromShortcut
      2 = Command_EmergencyRepairFromShortcut
      3 = Command_AnthraxBombFromShortcut
      4 = Command_ScudStormFromShortcut
      5 = Command_RadarVanScanFromShortcut
      6 = Command_SneakAttackFromShortcut
      7 = Command_GPSScramblerFromShortcut
      8 = Command_GLAArtilleryBarrageFromShortcut
    END

    Finally, you should add the normal firing CommandButton the the GLA Command Center's CommandSet.

    CommandSet GLACommandCenterCommandSet
      1  = Command_ConstructGLAWorker
      4  = Command_GPSScrambler
      5  = Command_Ambush
      6  = Command_EmergencyRepair
      7  = Command_AnthraxBomb
      8  = Command_SneakAttack
      9  = Command_GLAArtilleryBarrage
      13 = Command_SetRallyPoint
      14 = Command_Sell
    End

    Remember that all 3 CommandSets already exist and should not be created anew. Note that in normal Generals, the number of CommandSet slots is more restricted, so you may need to make some sacrifices in order to fit in your new Artillery Strike.

  6. Now you'll need to edit the GLA Command Center itself so that it can support the new Artillery Barrage. Copying code that already works is the best way to do this, so search for "Object ChinaCommandCenter" in \Object\FactionBuilding.ini and then search for "ModuleTag_17". Copy the associated block of code (all 7 line's worth, the entire module) and then search for "Object GLACommandCenter". Scroll down to the end of that Object's code and paste your copied code slightly above the unindented "End" statement. Give your new module a name, because the fun part is about to begin. The module you just copied had several references to the original Artillery Barrage code, and you'll need to update all of them in order to have the new Artillery Barrage work properly ingame.

    Object GLACommandCenter
      ...
    
      Behavior           = OCLSpecialPower ModuleTag_GLAArtilleryBarrage
        SpecialPowerTemplate = SuperweaponGLAArtilleryBarrage
        UpgradeOCL           = SCIENCE_GLAArtilleryBarrage3 SUPERWEAPON_GLAArtilleryBarrage3
        UpgradeOCL           = SCIENCE_GLAArtilleryBarrage2 SUPERWEAPON_GLAArtilleryBarrage2
        OCL                  = SUPERWEAPON_GLAArtilleryBarrage1
        CreateLocation       = CREATE_AT_EDGE_FARTHEST_FROM_TARGET
      End
    
      ...
    End
  7. Test your new Artillery Strike ingame. Note that this guide will only give the new Artillery Strike to the default GLA faction. If you are modding ZH and want any of the GLA generals to have this new ability as well, then you must repeat Steps 5 and 6 for each General.

While this guide goes through a few steps that are not technically necessary, I recommend cloning General's Powers in this way in order to prevent the two powers from having dependencies that could interfere with each other. This way, the new Artillery Barrage is independent of the old one and can be adjusted accordingly. (Want to change the timer or the rank prerequisites for your new General's Power? Go ahead!). You'll also be well on your way to creating a new unique General's Power, but that involves additional steps and will be covered in another tutorial.

Have fun! And remember: you must use these modding powers only for good, not for evil.