Skip to content

Objects & Modules

Andreas-W edited this page Oct 13, 2025 · 22 revisions

Object Improvements

WeaponSet

Added new parameter to an object's WeaponSet definition

  • WeaponReloadSharedAcrossSets = No - If a unit switched between weaponset, it's reload time and ammo count (in percent) will be kept. For instance Migs will not reload in air when they get BlackNapalm.

AutoChooseSources

Added new types for AutoChooseSources

  • SYNC_TO_PRIMARY - This weapon slot cannot fire on its own, but will be fired whenever PRIMARY is fired.
  • SYNC_TO_SECONDARY - This weapon slot cannot fire on its own, but will be fired whenever SECONDARY is fired.
  • SYNC_TO_TERTIARY - This weapon slot cannot fire on its own, but will be fired whenever TERTIARY is fired.

Syncs a weapon slot to another. The weapon slot cannot be used except when it's parent weapon is fired. This ignores all conditions and checks of the synced weapon.

Example:

Weapon = PRIMARY MainWeapon
Weapon = SECONDARY SyncedWeapon
AutoChooseSources = SECONDARY SYNC_TO_PRIMARY

In this example, the secondary weapon SyncedWeapon will not be used on its own. Whenever the unit attacks with its primary MainWeapon, the secondary weapon will be fired as well. This can be used for Aircraft to reliably fire multiple weapons on each attack.

AmmoPips style

Added options to customize Ammo Pips, e.g. for Aircraft with a very large clip size.

Added a new parameter for object definitions:

  • AmmoPipsStyle = DEFAULT - (Change the unit's display style for ammo pips to one of these:)
    • DEFAULT - default ZH style; 1 yellow pip symbol for each shot.
    • PERCENTAGE_BAR - display a yellow bar similar to the health bar, showing the ammo count in percent.
    • SINGLE - default ZH pip visuals, but only show a single symbol regardless of clip size. Ammo count is displayed via fading yellow color.

Note: This parameter might be moved to individual weapons in the future, to allow displaying ammo pips for multiple weapon slots at once.

Object Modules

AIUpdateInterface (And all other AIUpdate types)

New experimental parameter:

  • PreferredAttackAngle = <angle> [MIRRORED] - (mirrored keyword is optional) When a unit turns to attack, it will attempt to turn to this angle. If mirrored is enable it can also use the same angle +180°. Possibly useful for battleship setups with multiple turrets. Only works for locomotors that can turn in place (minTurnSpeed = 0) Note: this is NOT needed for limited turret angles (See below). Units will follow the actual turret angles when trying to attack.

Turret

New paramters for Turret or AltTurret entries

  • MinTurretAngle = 0 - Minimum angle the turret is allowed to turn
  • MaxTurretAngle = 0 - Maximum angle the turret is allowed to turn Notes:
  • for backwards facing configurations, MaxTurretAngle can be > MinTurretAngle; Currently this is not working 100% reliably
  • Remove the angle limit lines to use unlimited angle. A value of 0 will use 0 as limit.
  • If the turret cannot turn to the front (e.g. side mounted gun on a helicopter), the unit will attempt to turn to the turret's firing arc
    • this feature only works for locomotors that can turn in place (minTurnSpeed = 0)

WeaponSetUpgrade

Added new parameters for WeaponSetUpgrade

  • WeaponSetFlag = <WeaponSetFlag> - define which Weaponset to enable (default = PLAYER_UPGRADE)
  • WeaponSetFlagsToClear = <WeaponSetFlag1> <WeaponSetFlag2> .. - define which Weaponsets to disable
  • NeedsParkedAircraft = No - Units with JetAIUpdate need to be parked in hangar to research this upgrade

Notes: WeaponSetFlagsToClear can be used to switch between WeaponSets using multiple upgrades. example:

  Behavior = WeaponSetUpgrade ModuleTag_04a
    WeaponSetFlag = PLAYER_UPGRADE
    WeaponSetFlagsToClear = PLAYER_UPGRADE2 PLAYER_UPGRADE3
    TriggeredBy = Upgrade_GLAWorkerFakeCommandSet
    RemovesUpgrades = Upgrade_GLAWorkerRealCommandSet Upgrade_GLAWorkerFakeCommandSet Test_Upgrade_DummyToggle
  End
  
  Behavior = WeaponSetUpgrade ModuleTag_04b
    WeaponSetFlag = PLAYER_UPGRADE2
    WeaponSetFlagsToClear = PLAYER_UPGRADE PLAYER_UPGRADE3
    TriggeredBy = Upgrade_GLAWorkerRealCommandSet
    RemovesUpgrades = Upgrade_GLAWorkerRealCommandSet Upgrade_GLAWorkerFakeCommandSet Test_Upgrade_DummyToggle
  End
  
  Behavior = WeaponSetUpgrade ModuleTag_04c
    WeaponSetFlag = PLAYER_UPGRADE3
    WeaponSetFlagsToClear = PLAYER_UPGRADE PLAYER_UPGRADE2
    TriggeredBy = Test_Upgrade_DummyToggle
    RemovesUpgrades = Upgrade_GLAWorkerRealCommandSet Upgrade_GLAWorkerFakeCommandSet Test_Upgrade_DummyToggle
  End

You can combine this with NeedsParkedAircraft to allow Jets to switch their ammo type when parked using multiple object upgrades.

ArmorUpgrade

Added new parameters for ArmorUpgrade

  • ArmorSetFlag = <ArmorSetFlag> - define which Armorset to enable (default = PLAYER_UPGRADE)
  • ArmorSetFlagsToClear = <ArmorSetFlag1> <ArmorSetFlag2> .. - define which ArmorSets to disable

Notes: ArmorSetFlagsToClear can be used to switch between ArmorSets using multiple upgrades (see WeaponSetUpgrade).

LocomotorSetUpgrade

Added new parameters for LocomotorSetUpgrade

  • EnableUpgrade = No - (if 'Yes' (default), locomotor is switched to SET_NORMAL_UPGRADED; if 'No' locomotor is switched back to SET_NORMAL)
  • ExplicitLocomotorType = SET_SUPERSONIC - Optional; explicitly switch to the defined locomotor set (This is not persistant, unlike EnableUpgrade)

Notes: EnableUpgrade only allows for a single locomotor upgrade, but it can be toggled on/off with multiple upgrades. With ExplicitLocomotorType, Locomotor sets can be set freely, but they will not persist if the unit changes its locomotor through other means (e.g. Aircraft taking off, or combat bike switching rider)

MaxHealthUpgrade

Added new parameter for MaxHealthUpgrade

  • MultiplyMaxHealth = 1.0 - (multiplier on the unit's current HP; default = 1.0 -> no change.)

Notes:

  • It is recommended to change all health upgrades to multiplicative as they will not be affected by other HP changes like veterancy, and can be freely stacked (and even reversed).
  • You can still use AddMaxHealth for additive boni, and could even combine it with MultiplyMaxHealth. The formula is NewHP = (CurrentHP * MultiplyMaxHealth) + AddMaxHealth.

ArmorDamageScalarUpdate (New)

This module was designed for a temporary armor buff ability. The module will apply a damage/armor scale value to every unit in the area for the given amount of time. In addition, various visual effects can be added.

example:

Behavior = ArmorDamageScalarUpdate ModuleTag_01
    AllowedAffectKindOf = VEHICLE STRUCTURE  ; (required; any object matching *any* of these KindOfs is a valid target)
    ForbiddenAffectKindOf = INFANTRY  ; (optional; any object matching *any* of these KindOfs is an invalid target)
    AffectsTargets = ALLIES NEUTRALS  ; (required; any combination of ALLIES, NEUTRALS, ENEMIES)
    AffectAirborne = Yes   ; (default = Yes; Should this affect units currently in the air) 
    BonusDuration = 10000     ; (required; How long effect lasts, in ms)
    BonusRange = 100     ; (required; Radius of the effect)
    ArmorDamageScalar = 0.9;   ; (default = 1.0; damage scalar to apply; 1.0 = no effect; 0.5 = takes half damage; 2.0 = takes double damage; min = 0.01)
    EffectParticleSystem = <entry from particlesystem.ini>  ; (optional; apply particlesystem to affected objects. SystemLifeTime is scaled automatically. If VolumeType = BOX, the size will be changed to the object's geometry.)
    OverrideDamageFX = <entry from damageFX.ini> ; (optional; change the object's DamageFX to this entry over the duration)
    ScaleParticleSystem = Yes  ; (default = No; If enabled, the particle system's spawn rate will be adjusted for the object's size)
    ApplyColorTint = Yes  ; (default = No; Apply a dark red color tint to the objects for the duration)
End

Notes:

  • This module is designed to be put on a dummy object marker, like for EmergencyRepair or Frenzy.
  • To correctly track the objects over the duration, the marker object needs to stay alive for the duration. Lifetime is tracked in the module itself. You do not need to add a lifetimeupdate as well. If the object is killed earlier, the effect will be removed from all units.
  • The effect is applied once at the beginning. Objects leaving or entering the radius later will not get the effect.
  • The module can be used to apply a damage increase to enemy units (i.e. lower their armor)

CostModiferUpgrade

New Parameters added. Example:

Behavior = CostModiferUpgrade ModuleTag_123
  TriggeredBy = Upgrade_CostReduction  ; entry from upgrade.ini
  EffectKindOf = VEHICLE  ; Units with this KindOf will be affected
  Percentage = -20%  ; amount that cost will be reduced
  IsOneShotUpgrade = No  ; (NEW) Is this a one time global upgrade, or should it be removed when the object dies or changes owner?
  BonusStacksWith = DIFFERENT_VALUE  ; (NEW) Stacking behavior when multiple bonus sources exist
End

** BonusStacksWith types **

  • DIFFERENT_VALUE - Default behavior: Does not stack with other bonus with the same value. Does stack with bonus with different value.
  • OTHER_TYPE - Does stack with bonus from other type of unit with the same value. Does not stack with bonus from the same type of unit. I.e. Multiple OilRefineries would not stack, but a Refinery would stack with an IndustrialPlant if it had the same value.
  • SAME_TYPE - Bonus from multiple sources of the same type will stack. I.e. Owning multiple Refineries grants additional bonus.

Notes:

  • Bonus stacking is additive, not multiplicative

ProductionTimeModiferUpgrade (New)

This works just like CostModiferUpgrade (Oil Refinery) to apply a global production time reduction for the given KindOf example:

Behavior = ProductionTimeModifierUpgrade ModuleTag_123
  TriggeredBy = Upgrade_CostReduction  ; entry from upgrade.ini
  EffectKindOf = VEHICLE  ; Units with this KindOf will be affected
  Percentage = -20%  ; amount that build time will be reduced
  IsOneShotUpgrade = No  ; Is this a one time global upgrade, or should it be removed when the object dies or changes owner?
  BonusStacksWith = DIFFERENT_VALUE  ; Stacking behavior when multiple bonus sources exist
End

ExperienceScalarUpgrade

Added parameter to make module active by default (useful for negativ scalars):

  • StartsActive = False

Added new parameter to modify XP value of a unit (i.e. XP that is gained for the enemy when the unit is killed)

  • AddXPValueScalar = 0.0 - Additive modifier for XP value scalar. I.e.: XPValueNew = XPValueOld * (1.0 + AddXPValueScalar).

Laser Improvements

LaserUpdate

New parameters are added to allow the laser to grow/shrink or fade in/out

  • BeamFadeInDuration = 0 - (time in ms. Alpha scalar is linear interpolated from 0 to 1 over the given time at the start.)
  • BeamFadeOutDuration = 0 - (time in ms. Alpha scalar is linear interpolated from 1 to 0 at the end of the beam's lifetime. Requires LifetimeUpdate)
  • BeamGrowDuration = 0 - (time in ms. Beam width is linear interpolated from 0 to 1 over the given time at the start.)
  • BeamShrinkDuration = 0 - (time in ms. Beam width is linear interpolated from 1 to 0 at the end of the beam's lifetime. Requires LifetimeUpdate)
  • UseMultiLaserDraw = No - (This flag is needed, if a Laser object has multiple LaserDraw modules, to correctly update all of them)
  • UseHouseColoredParticles = No - (Apply house colored tint to the laser's muzzle and target particle systems)

W3DLaserDraw

Added parameters to specify grid animation. Currently only a 1xn grid is allowed (i.e. multiple columns) to work together with scrollRate.

  • TextureGridTotalColumns = 1 - (total number of columns in the texture)
  • TextureGridColumns = 1 - (actual number of columns used for the animation)
  • UseHouseColorOuter = No - (apply house color to the laser's outer color)
  • UseHouseColorOuter = No - (apply house color to the laser's inner color)

Note: Usually both TextureGridColumns and TextureGridTotalColumns numbers would be the same. But having separate numbers allows to use an odd number of frames and still keep proper DDS texture sizes. E.g. you have a texture width of 512, with 8 frames of 64. But you only want 7 frames, so you can set TextureGridTotalColumns=8 and TextureGridColumns=7.

MissileAIUpdate

Added new parameters to MissileAIUpdate module:

  • RandomPathOffset = 0.0 - distance in meters. Missile projectils will spread out randomly to fly a random arc pattern for more interesting visuals.

  • ZCorrectionFactor = 2.0 - Missiles attacking air units will have their direction shifted upwards by this factor. (2.0 is vZH default)

  • ApplyLauncherBonus = No - Any extra weapon that is fired from the projectile (On death, fireweaponupdate, etc.) will inherit the shooter's weapon bonus values

Notes:

  • ZCorrectionFactor is what causes AA missiles in vZH to be never aligned to the launcher. For units with actual fire pitch (e.g. Patriot), it is recommended to set this value to 0. For units that cannot pitch (e.g. Missile Defender) a value between 1 and 2 is recommended.

DumbProjectileBehavior

New parameters:

  • ApplyLauncherBonus = No - Any extra weapon that is fired from the projectile (On death, fireweaponupdate, etc.) will inherit the shooter's weapon bonus values

FreeFallProjectileBehavior

New type of projectile module that mimics the behavior of Bombs dropped by genpowers. Projectiles will move based on physics, making it suitable for carpet bomb or strafing run aircraft weapons. On collision, the weapon's damage and detonation effects are applied.

Example:

Behavior = FreeFallProjectileBehavior ModuleTag_009
   MaxLifespan = 10000  ; Maximum lifetime of the object
   TumbleRandomly = No  ; Adds random rotation, same as for DumbProjectileBehavior
   CourseCorrectionScalar = 1.0   ; guide the bomb towards the intended target. 1=no homing, 0=snapto; 0.99=smooth, 0.95=too-fast
   UseWeaponSpeed = No   ; apply additional speed from the unit's weapon
   ExitPitchRate = 0 ; Angle tilt per second to apply (respects centerOfMassOffset in the projectile's physics)
   ApplyLauncherBonus = Yes  ; Apply weapon bonus from launcher for any secondary weapon effects
   DetonateOnGround = Yes   ; Will the projectile detonate when hitting the ground or live on (to bounce or rest on ground)?
   DetonateOnCollide = Yes    ; Same as above, when hitting another object (See Weapon for collission settings)
   GarrisonHitKillRequiredKindOf = <Kindof list>  ; Same as MissileAI/DumbProjectile
   GarrisonHitKillForbiddenKindOf= <Kindof list>  ; Same as MissileAI/DumbProjectile
   GarrisonHitKillCount = 0  ; Same as MissileAI/DumbProjectile
   GarrisonHitKillFX = <FXList>  ; Same as MissileAI/DumbProjectile
End

Notes:

  • This module's behavior depends a lot on the projectile's physics settings, such as mass, friction, etc. It takes some finetuning to get the exact behavior you want.
  • For basic carpet bombing, you can copy the settings from existing genpowers.

ScatterShotUpdate (New)

New module intended for weapon projectiles, to allow scattering in mid air and fire multiple shots to targets within range.

Parameters:

  • Weapon = - (The weapon to be fired at targets.)
  • NumShots = - (default = 0; number of shots to fire)
  • TargetSearchRadius = - (default = 0; range around the weapon's target location or object that we look for targets)
  • TargetMinRadius = - (default = 0; minimum range targets need to be away from the original target)
  • MaxShotsPerTarget = - (default = 0; How many shots to fire at each target. 0 = randomly attack ground only; 1 = attack each target once; >1 when each target was attacked once, start from the beginning)
  • PreferSimilarTargets = - (default = No; Choose air or ground targets similar to the main target object. I.e. if we attack an air unit, all targets will be picked from air units first)
  • PreferNearestTargets = - (default = No; Prefer targets closest to the original target; Otherwise choose randomly)
  • NoTargetsScatterRadius = - (default = 0; If not targets were found/picked, use this random scatter radius to attack the ground)
  • NoTargetsScatterMinRadius = - (default = 0; Minimum scatter radius when no target is found)
  • NoTargetsScatterMaxAngle = - (default = 0; Acceptable aim delta angle for scatter targets)
  • AttackGroundWhenNoTargets = - (default = yes; If Yes, when we run out of targets, fire randomly at the ground; If No, do not fire.)
  • AvoidOriginalTargetObject = - (default = no; If Yes, we never try to hit the original target of the attack)
  • AvoidPreviousTargetWhenChain = - (default = no; When the attack was fired from another ScatterShot module, avoid that modules original target)
  • TriggerDistanceToTarget = - (default = 0; How close the projectile needs to be to the target to trigger the scatter shot.)
  • TriggerLifetime = - (default = 0; How long after the projectile was created to trigger the scatter shot. 0 = no limit.)
  • TriggerOnImpact = - (default = No; Trigger scatter shot on projectile impact.)
  • TriggerInstantly = - (default = No; Trigger scatter shot instantly after the projectile was created)
  • StayAliveAfterTrigger = - (default = No; The original weapon's projectile will stay alive after the scatter shot was triggered.)
  • TriggeredDeathType = - (default = NORMAL; The death type to use for the projectile object when the scatter shot is triggered.)
  • ScatterFX = - (default = None; entry from FXList.ini to play when scatter shot is triggered.)

Notes:

  • The weapon used for the scatter shot needs to have a clip size large enough to fire all shots.
  • When picking targets for the scatter shots, they need to be viable targets for the weapon's damage type.
  • When the original weapon targets an object, that original target will always be picked to fire a scatter weapon at.
  • This module can be used on non-projectile objects as well (using lifetime or instant triggers), e.g. to create an object that fires at multiple units in range simultaneously

Examples:

  Behavior = ScatterShotUpdate ModuleTag_Scatter
    Weapon = TomahawkMissileScatterWeapon    ; simple guided rocket weapon
    NumShots = 5
    TargetSearchRadius = 120.0    ; Pick targets in 120 range
    NoTargetsScatterRadius = 60.0   ; If no targets, scatter randomly in 60 radius
    MaxShotsPerTarget = 1       ; Fire at each targets once. If we have more than 5 targets, hit the ground randomly
    TriggerDistanceToTarget = 150.0   ; Trigger at this distance to target
  End

Contain Modules

Added new features for all contain modules. WeaponBonus types that are passed to passengers can now be configured.

  • PassengerWeaponBonusList = <BONUS1> <BONUS2> - (provide a list of WeaponBonus types that will be applied to the contained objects)

Default values:

  • GarrisonContain: GARRISONED
  • TransportContain: CONTAINED

Setting PassengerWeaponBonusList = None will override the default value.

Note: HelixContain grants GARRISONED to its passengers in vanilla ZH. This is changed to CONTAINED. To restore vanilla behaviour you will need to manually set the bonus here.

StickyBombUpdate#

Added new parameters to customize the 2D anim visuals:

  • Animation2DBase = <entry from Animation2D.ini> - 2D anim for background bomb visuals (default = BombRemote)
  • Animation2DTimed = <entry from Animation2D.ini> 2D anim for foreground/timer visuals; This is used when the bomb object has a LifeTimeUpdate (default = BombTimed)
  • ShowTimer = Yes - Flag to disable Animation2DTimed for timed bombs - Only use base animation.

Note: Setting Animation2DBase or Timed to "None" will hide them.

CrateCollide

Added new parameters for all CrateCollide modules:

  • AllowNeutralPlayer = No - Crate can be picked up by the neutral player
  • AllowPickAboveTerrain = No - Crate can be picked up when it is above ground.

StickyBombCrateCollide

CrateCollide module to apply sticky bombs to objects. Can be used with pickup crates or projectiles.

Example:

Behavior = StickyBombCrateCollide ModuleTag_419
   NeedsTarget = No ; Needs an intended target object (e.g. from a projectile) cannot be picked up by regular collission
   StickyBombObject = <Object with StickyBombUpdate>  ; The object to create
   AllowMultiCollide = No ; If used as a crate, can the effect be applied to multiple objects at once?
   ShowInfiltrationEvent = No  ; If enabled, shows a radar event for the target player
   ChanceToTriggerPercent = 100%; Chance to create the StickyBombObject.
End

Example to use on a Missile or DumbProjectile to apply a sticksBomb to the target:

Behavior = StickyBombCrateCollide ModuleTag_419
  RequiredKindOf = STRUCTURE
  ForbiddenKindOf = VEHICLE INFANTRY
  BuildingPickup = Yes
  ExecuteFX = FX_SniperDroneTargetTracerPingFX
  AllowNeutralPlayer = Yes
  AllowPickAboveTerrain = Yes
  NeedsTarget = Yes
  StickyBombObject = Lazr_SniperDroneTargetTracerStickyBomb
End

; Needs separate modules for Building/Unit collissions
Behavior = StickyBombCrateCollide ModuleTag_420
  ;RequiredKindOf = VEHICLE INFANTRY
  ForbiddenKindOf = STRUCTURE
  BuildingPickup = No
  ExecuteFX = FX_SniperDroneTargetTracerPingFX
  AllowNeutralPlayer = Yes
  AllowPickAboveTerrain = Yes
  NeedsTarget = Yes
  StickyBombObject = Lazr_SniperDroneTargetTracerStickyBomb
End

AdvancedCollide (New)

A collide module with more versatile parameters

  • CollideWeapon = <weapon entry> - Weapon to fire on collide
  • OCL = <OCL entry> - OCL to create on collide
  • FX = <FXList entry> - FX to create on collide
  • FireOnce = No - trigger once or for every collission
  • CollideWithGround = No - trigger collision when hitting the ground
  • CollideWithObjects = Yes - trigger collission when hitting objects.
  • RequiredStatus = <status entry> - required status for this object
  • ForbiddenStatus = <status entry> - forbidden status for this object
  • TargetRequiredStatus = <status entry> - required status for the object we collide with
  • TargetForbiddenStatus = <status entry> - forbidden status for the object we collide with
  • RequiredKindOf = <KindOf entry> - required KindOf for the object we collide with
  • ForbiddenKindOf = <KindOf entry> - forbidden KindOf for the object we collide with
  • ChanceToTriggerPercent = 100% - Chance to trigger effects on collide
  • RollOnceForTrigger = No - Roll for trigger chance every time we collide, or only the first time (and then keep the result)

Note: This module allows to trigger effects when objects collides with the ground, e.g. when a projectile misses it's target.

LifeTimeUpdate

Add new parameter: *ShowProgressBar = No Enables progress bar above unit health to visualize lifetime. Requires SHOW_PROGRESS_BAR KindOf.

RadiusDecalBehavior (New)

New module to create a radius decal that follows a unit. Can be triggered via upgrade.

Example:

Behavior = RadiusDecalBehavior ModuleTag_decal1
    TriggeredBy = <Upgrade entry>  ; Optional
    ; < All other basic upgrade entries (ConflictsWith, RemovesUpgrades, FXListUpgrade, RequiresAllTriggers) >
    StartsActive = No  ; Set to yes, to enable initially
    Radius = 100.0 ; (radius in meters)
    RadiusDecal   ; Decal Template, Same parameters as DeliveryDecal in OCL ini
      Texture           = SCCFuelAirBomb_USA   ; Texture name
      Style             = SHADOW_ALPHA_DECAL   ; SHADOW_DECAL, SHADOW_ALPHA_DECAL or SHADOW_ADDITIVE_DECAL
      OpacityMin        = 25%    ; default = 100%, Opacity will move between min and max
      OpacityMax        = 50%    ; default = 100%
      OpacityThrobTime  = 500    ; default = 1000
      Color             = R:255 G:0 B:0 A:255 
      OnlyVisibleToOwningPlayer = Yes     ; Disable to make the decal visible to all players
      End
  End

Note: This module reacts to the upgrade being removed (by a different upgrade). This means you can make the decal toggle on/off.

ParkingPlaceBehavior

Added new features and parameters to ParkingPlaceBehavior (Airfield)

  • ParkedUnitsDamageScalar = 1.0 - scalar for damage taken applied to all parked aircraft (0.9 = only take 90% of damage)
  • ParkedUnitsDamageScalarUpgraded = 1.0 - same as above, after upgrade
  • DamageScalarUpgradedTriggeredBy = <upgrade name> - upgrade to trigger the upgraded scalar value
  • RequiredKindOf = <KindOf list> - if set, only aircraft that has these KindOfs is allowed to dock here
  • ForbiddenKindOf = <KindOf list> - if set, aircraft that has these KindOfs is not allowed to dock here.

Notes:

  • ParkedUnitsDamageScalar can be used to apply an upgrade that grants damage protection to parked aircraft
  • Required/Forbidden KindOf can be used to allow only specific kinds of aircraft to land (i.e. to use different sizes, or differ between VTOL/Regular jets)

UnitProductionBonusUpgrade (New)

This upgrade module allows to set a cost and/or build time modifier for individual types of units. This affects the whole player and not just individual factories.

Parameters:

  • <All common upgrade params; e.g. TriggeredBy>
  • CostModifierPercentage = 0 - Percentage amount that the unit's costs are modified
  • BuildTimeModifierPercentage = 0 - Percentage amount that the unit's build time is modified
  • UnitTemplateName = <Name of an Object> - The unit to apply this bonus to. (multiple lines are allowed)

Example

Behavior = UnitProductionBonusUpgrade ModuleTag_01
  TriggeredBy = Upgrade_CostReduction   ; The upgrade trigger
  CostModifierPercentage = -40%    ; Cost is reduced by 40%
  BuildTimeModifierPercentage = -80%    ; Build time is reduced by 80%
  UnitTemplateName = Tank_ChinaInfantryRedguard    ; The units this bonus applies to
  UnitTemplateName = Tank_ChinaTankBattleMaster
End

Notes

  • This upgrade is currently not removable, i.e. it will not work like the CostModifierUpgrade module for Tech OilRefinery. It's only suitable as a global upgrade for now

StealthUpgrade

Added new parameters

  • EnableStealth = Yes - If set to No, this will disable the object's stealth instead of enabling it. Can be used for a toggleable upgrade.

  • OverrideStealthForbiddenConditions = <StealthForbiddenConditionFlags> - Override StealthForbiddenConditions in StealthUpdate for this unit.

Note: if OverrideStealthForbiddenConditions is set, EnableStealth is ignored as there is no reason to use both functionalities at the same time.

BattlePlanBonusBehavior (New)

New module that can be used to customize the effects of BattlePlans for individual units. This module needs to go to the unit that receives the battle plan bonus effects, not the StrategyCenter.

Parameters:

Behavior = BattlePlanBonusBehavior ModuleTag_BPB
  ; Generic Upgrade parameters:  
  TriggeredBy = <Upgrade entry>
  ; ---
  StartsActive = No  ; Active immediately or requires upgrade?
  OverrideGlobalBonus = No  ; Enable to skip default BattlePlan bonus effects (i.e. values from BattlePlanUpdate, or WeaponBonus effects) for this unit
  ShouldParalyzeOnPlanChange = Yes  ; Should this unit be paralyzed/disabled while switching battle plans?
  ; -- Bonus entries -- Valid <BATTLE_PLAN_NAME> are BOMBARDMENT, SEARCH_AND_DESTROY and HOLD_THE_LINE
  WeaponSet = <BATTLE_PLAN_NAME> <WEAPON_SET_FLAG>  ; Set this weaponset flag while this battleplan is active
  ArmorSet = <BATTLE_PLAN_NAME> <WEAPON_SET_FLAG>  ; Set this armorset flag while this battleplan is active
  WeaponBonus = <BATTLE_PLAN_NAME> <WEAPON_BONUS_NAME>  ; Grant this weaponbonus while this battleplan is active
  ArmorDamageScalar = <BATTLE_PLAN_NAME> 1.0   ; Set damage reduction while this battleplan is active
  SightRangeScalar = <BATTLE_PLAN_NAME> 1.0  ; Set a sight range bonus while this battleplan is active
  StatusToSet = <BATTLE_PLAN_NAME> <STATUS_TYPE>   ; Set this status when enabling this battle plan. Clear it on battle plan removal
  StatusToClear = <BATTLE_PLAN_NAME> <STATUS_TYPE>  ; Clear this status when enabling this battle plan. Set it on battle plan removal
End

Examples

Example 1 - Give extra effects to Battle plans

Behavior = BattlePlanBonusBehavior ModuleTag_BP1
  TriggeredBy = Upgrade_BattlePlanBonusExample
  OverrideGlobalBonus = No
  ShouldParalyzeOnPlanChange = Yes
  WeaponSet = BOMBARDMENT PLAYER_UPGRADE
  WeaponBonus = SEARCH_AND_DESTROY FRENZY_THREE
  StatusToClear = HOLD_THE_LINE CAN_STEALTH
  ArmorDamageScalar = HOLD_THE_LINE 0.9
End

This unit gains the regular battlePlan bonus effects with additional effects:

  • With BOMBARDMENT we switch to the upgraded WeaponSet
  • With SEARCH_AND_DESTROY we gain an extra weapon bonus
  • With HoldTheLine we gain additional damage reduction, but lose the ability to stealth.

Example 2 - Allow units to gain battle plans

Behavior = BattlePlanBonusBehavior ModuleTag_BP0
  StartsActive = Yes
  OverrideGlobalBonus = Yes
  ConflictsWith = Upgrade_GrantBattlePlans
  ShouldParalyzeOnPlanChange = No
End
  
Behavior = BattlePlanBonusBehavior ModuleTag_BP1
  TriggeredBy = Upgrade_GrantBattlePlans
  OverrideGlobalBonus = No
  ShouldParalyzeOnPlanChange = Yes
End

This adds no additional effects, but makes the unit skip default BattlePlan effects (and paralyze) initially, and applies them only after the upgrade. Note: For this to work, the unit needs to be inlcuded in the BattlePlan's valid KindOfs, even though the intention is to not give them the battlePlan effects by default.

WeaponBonusUpdate

Added Parameters:

  • AffectsTargets = [ALLIES/ENEMIES/NEUTRALS] ; Allows applying a bonus to enemies
  • AffectsAirborne = Yes ; allow/disallow the bonus be applied to currently airborne units
  • TintStatusType = [TINT_STATUS type] ; which color tint to apply

DelayedUpgradeBehavior (New)

Applies or Removes Upgrade(s) after a set time. Initially triggered by an upgrade. This can be used to make temporary upgrades.

Example:

Behavior = DelayedUpgradeBehavior ModuleTag_DelUp
  TriggeredBy = <Upgrade entry>   ; Initial Trigger
  ; additional generic Upgrade params (ConflictsWith, RemovesUpgrades, FXListUpgrade, RequiresAllTriggers)
  UpgradesToTrigger = <Upgrade1, Upgrade2, ...>   ; Upgrades that will be triggered after the delay
  UpgradesToRemove = <Upgrade1, Upgrade2, ...>    ; Upgrades that will be removed after the delay
  TriggerAfterTime = <time in msec>    ; Time delay
End

UpgradeSpecialPower (New)

Trigger an upgrade via a special power. This can be used to (e.g. in combination with DelayedUpgradeBehavior) to create a temporary upgrade with a cooldown.

Example:

Behavior = UpgradeSpecialPower ModuleTag_SpecUp01
  SpecialPowerTemplate = <SpecialPower Entry>
  ; Other params from SpecialPower module (UpdateModuleStartsAttack, StartsPaused, InitiateSound, ScriptedSpecialPowerOnly)
  UpgradeToGrant = <Upgrade Entry>
End

OCLSpecialPower

Added new parameter: *SelectCreatedObject = No The (first) created object will be automatically selected by the player

TeleporterAIUpdate (New - EXPERIMENTAL)

** Warning: This module is experimental, i.e. it is not fully tested and might undergo revisions**

AIUpdate module designed to work like a Chrono Legionnaire in RA2. I.e. The unit teleports instead of moving normally, and needs to recharge depending on the distance it teleported. ** Note: Currently this module is only working properly for infantry units. It currently does not work properly for vehicles and it is not certain it ever will.**

Example:

Behavior = TeleporterAIUpdate ModuleTag_123
   TeleportStartFX = [FXList entry] ; FX to play at the unit's previous position when it teleports
   TeleportTargetFX = [FXList entry] ; FX to play at the unit's target position when it teleports
   TeleportRecoverEndFX = [FXList entry] ; FX to play on the unit, when it has finished recovering
   MinDistanceForTeleport = 20.0  ; distance in which the unit moves normally instead of teleporting
   DisabledDurationPerDistance = 10.0 ; How long the unit will need to recover, linear to the distance (in MS per distance). Recommended values = 5-10. 
   TeleportRecoverSoundAmbient = [AudioEvent entry] ; Ambient sound played on the unit while it recovers from a teleport.
   TeleportRecoverOpacityStart = 10%  ; Unit maximum transparency when it starts to recover.
   TeleportRecoverOpacityEnd = 80%  ; Unit minimum transparency when it has finished recovering.
   TeleportRecoverTint = TELEPORT_RECOVER  ; Color tint status to apply while recovering
   [entries from AIUpdate]
End

When a unit is recovering from a teleport, the conditionstate TELEPORT_RECOVER is set. Note: In most cases, the unit will also be MOVING after a teleport, so it's recommended to define both states.

ChronoDeathBehavior (New)

Death Module for "Chrono" death. This makes the unit fade out and shrink.

Example:

Behavior = ChronoDeathBehavior ModuleTag_ChronoDeath
  DeathTypes = NONE +CHRONO  ; Death types to use
  ; Additional DieModule params (VeterancyLevels, ExemptStatus, RequiredStatus)
  StartFX = <FXList entry> ; FX to play at the start
  EndFX = <FXList entry> ; FX to play at the end
  ; Note: The following params are meant to be used (instead of StartFX/EndFX) when used in Default/Object.ini:
  StartFXInfantry = <FXList entry> ; played if the object is INFANTRY
  StartFXVehicle = <FXList entry> ; VEHICLE
  StartFXStructure = <FXList entry>  ; STRUCTURE
  EndFXInfantry = <FXList entry> ; played if the object is INFANTRY
  EndFXVehicle = <FXList entry> ; VEHICLE
  EndFXStructure = <FXList entry>  ; STRUCTURE

  OCL = <OCL entry> ; OCL to create at the start
  OCLDynamicGeometryScaleFactor = 0.0;  Used in combination with DynamicGeometryClientUpdate. If this is set, the created object will be scaled to the parent object's radius. The value here should be set to the model's default size (e.g. a value of 10.0 corresponds to a sphere with radius 10.0)

  StartScale = 1.0  ; Unit scale at the start
  EndScale = 0.1    ; Unit scale at the end
  StartOpacity = 25%  ; Opacity at the start
  EndOpacity = 0%    ; Opacity at the end
  DestructionDelay = 500   ; Duration of the sequence in ms
End

DynamicGeometryClientUpdate (New)

Client module for simple animations on a drawable's opacity and scale. Can be useful for effects like EMP bubbles.

Example:

ClientUpdate = DynamicGeometryClientUpdate ModuleTag_02
  Opacity = INITIAL 0.0      ; value when object is created
  Opacity = MIDPOINT 1.0     ; value at midpoint duration
  Opacity = FINAL 0.0        ; value at end of duration
  Scale = INITIAL 0.0
  Scale = MIDPOINT 1.0
  Scale = FINAL 0.0
  Interpolation = SMOOTH   ; How values in between are interpolated - SMOOTH (sinus curve) or LINEAR
  TotalDuration = 666   ; in ms
  MidpointDuration = 200    ; in ms
End

ResetSpecialPowerTimerWhileAliveUpdate (New)

Update Module to reset a player global (shared synch timer) superweapon while a unit is alive, this allows super unit deploys to start the cooldown when the unit is dead

Example:

  Behavior = ResetSpecialPowerTimerWhileAliveUpdate ModuleTag_x
    SpecialPowerTemplate = Tank_SuperweaponUniqueUnit  ; a superweapon template with shared synch timer ( like genpowers)
  End

W3DModelDraw

Added parameters (To the main Draw module block, not the individual ConditionStates):

  • IgnoreAnimationSpeedScaling = No - ignore animation scaling (e.g. for PreAttackDelay) for a draw module. Useful for having Looping animations (e.g. rotor blades or flags) along with a pre_attack anim in another draw module.

  • IgnoreRotation = No - This model will always stay aligned to the world (i.e. Z up), ignoring rotation via movement. Do not use this on modules with Firebones or Turrets.

  • OnlyVisibleToOwningPlayer = No - This model will only be visible to the owning player. Do not use it on modules with Firebones or Turrets.

Energy Shields

Added a Body and Behavior module for rechargable energy shields. This adds another health bar on top and absorbs damage until it's depleted.

ShieldBody

This Body is required for shields to work.

Body = ShieldBody ModuleTag_ES1
  ;<ActiveBody paramters>
  StartsActive = No  ; Enable Shields by default; Otherwise an upgrade is required (defined in EnergyShieldBehavior)
  ShieldMaxHealth = 100  ; Health points of the shield (only needed if ShieldMaxHealthPercent is not set)
  ShieldMaxHealthPercent = 30%  ; Health points relative to MaxHealth (overrides ShieldMaxHealth)
  ShieldArmorSetFlag = PLAYER_UPGRADE  ; (Optional) ArmorSetFlag to use while the shield is up
  ShieldPassThroughDamageTypes = <Damage Types> ; List of damage types that will go through the shield and damage the Health. NONE +X, ALL -Y notation.
  DefaultShieldPassThroughDamageTypes = <Damage Types> ; This has the same functionalty as above, but is predefined with all utility damage types that should always be passed through. This should not be defined in most cases, but can be overriden
End

NOTE: DefaultShieldPassThroughDamageTypes default values: NONE +STATUS +DEPLOY +UNRESISTABLE +HEALING +PENALTY +DISARM +HAZARD_CLEANUP +TOPPLING +SUBDUAL_UNRESISTABLE +CHRONO_UNRESISTABLE

EnergyShieldBehavior

The second required module for shield logic

Behavior = EnergyShieldBehavior ModuleTag_ES2
    StartsActive = No  ; Enabled by default (no upgrade required)
    TriggeredBy = <Upgrade Name>
    ShieldRechargeDelay = 5000  ; Time (ms) of no damage taken, until shield starts recharging.
    ShieldRechargeRate = 100  ; Delay (ms) between shield recharge ticks
    ShieldRechargeAmount = 0  ; How much shield to recharge per tick (Absolute. Use only one)
    ShieldRechargeAmountPercent = 2%  ; How much shield to recharge per tick (Percentage. Use only one)
    ShieldHealthBarColor = R:128 G:255 B:255 A:255  ; RGBA color for the shield health bar
    ShieldHealthBarBackgroundColor = R:0 G:0 B:0 A:255  ; RGBA color for the shield health bar outline
    ShowHealthBarBackgroundWhenEmpty = No   ; Show empty frame when shield is depleted
    ShowHealthBarWhenUnselected = No ; Show shield health bar when the unit is not selected or mousover
    ShieldModelCondition = <ConditionStateName>  ; Optional: Conditionstate to set when shield is active
    ShieldSubObjectName = <SubObjName> ; Optional: Model subobject to show when the shield is active
    ShieldHitModelCondition = <ConditionStateName> ; Optional: Conditionstate to set when shield was hit
    ShieldHitSubObjectName = <SubObjName> ; Optional: Model subobject to show when the shield was hit
    ShieldHitConditionDuration = 500  ; Optional: How long to show conditionstate when shield was hit
    ShieldDownFX = <FXList> ; Optional: FX to play when shield is depleted
    ShieldUpFX = <FXList> ; Optional: FX to play when a depleted shield starts recharging
End

** Note: for the shield health bar to work, the KindOf "SHOW_PROGRESS_BAR" is required on the object**

** Note2: When using both ShieldHitModelCondition and ShieldModelCondition parameters: When the shield is hit, both conditionstates are active at the same time. So a setup like this is required:

Draw = W3DModelDraw ModuleTag_ES0
  ; Inactive Shield
  DefaultConditionState
    Model = None
  End
		
  ; Active Energy Shield
  ConditionState = USER_1
    Model = ShieldActive
  End
	
  ; Energy Shield Hit
  ConditionState = USER_1 USER_2
    Model = ShieldHit
  End
End

MultiAddOnContain (New)

New contain module to replicate MARV turret functionality from Kane's Wrath: The object (Can be used on a structure or vehicle) has a container for multiple infantry units. Each contained infantry, will spawn a portable structure on the unit, that will move and attack along with it. Each type of infantry has it's own portable structure defined. Only units defined in the list can enter. There is no limit on how many addOns can be defined.

Example:

Behavior = MultiAddOnContain ModuleTag_123
  ; Params from TransportContain:  
  Slots = 4
  EnterSound = GarrisonEnter
  ExitSound = GarrisonExit
  ImmuneToClearBuildingAttacks = Yes
  DamagePercentToUnits = 100%
  IsEnclosingContainer = No
  ; New Params
  PayloadTemplateName = <Name of Infantry object to be contained by default> ; can have multiple PayloadTemplateName entries
  AddOnBoneName = STATION  ;Name of bone to place the addOns (uses numbering from 00-99 for available slots)
  AddOnEntry = <Name of contained Infantry object 1> <Name of Portable Structure object 1>
  AddOnEntry = <Name of contained Infantry object 2> <Name of Portable Structure object 2>
  AddOnEntry = <Name of contained Infantry object 3> <Name of Portable Structure object 3>
  ...
  EmptySlotSubObjectName = COVER_EMPTY   ;Name of any subobject (numbered) that should be visible when a slot is empty
  OccupiedSlotSubObjectName = COVER_OCCUPIED   ;Name of any subobject (numbered) that should be visible when a slot is filled (hide this in art code by default)
End

Container Draw Module Requirements

Like with OverlordContain, the container object needs to have one of

  • W3DOverlordTankDraw
  • W3DOverlordTruckDraw
  • W3DOverlordAircraftDraw - Note: Contary to the name, this is the default module to use (e.g for Structures) when no extra behavior is required

A new parameter was added to these modules that needs to be set when used with MultiAddOnContain:

  • HasMultiAddOns = Yes

AddOn Draw Module Requirements

Like with Overlord addOns, the contained portable structure object needs to have W3DDependencyModelDraw

AttachToBoneInContainer should now be set to the same numbered bone used for AddOnBoneName in MultiAddonContain. E.g. "STATION" if using STATION01-XX

Misc Improvements

ObjectExtend

Allows to use inheritence in the parser. ObjectExtend is similar to ObjectReskin but inherit all modules and allow modifications. The parent object must be defined before the ObjectExtend.

Syntax: ObjectExtend NewObject ObjectToInheritFrom

Use RemoveModule ModuleTag_xx to remove a module inherited from the parent.
WeaponSet and ArmorSet are inherited, but if you define another one in the child, the inherited sets are removed.
If the parent has multiple WeaponSets all will be removed from the child if the child defines one.

Examples:

ObjectExtend ZExtendedTank Chem_GLAVehicleRadarVan  
  ; *** ART Parameters ***  
  SelectPortrait = SNHacker2_L ;define other icons  
  ButtonImage = SNHacker2  
    
  RemoveModule ModuleTag_01 ; Remove the parent's draw  
  
  Draw = W3DTankDraw ModuleTag_1337 ; add a new draw  
    OkToChangeModelColor = Yes  
    DefaultConditionState  
      Model = NVInferno  
      Turret = Turret  
      TurretPitch = TurretEL01  
      WeaponFireFXBone = PRIMARY Muzzle  
      WeaponRecoilBone = PRIMARY Barrel  
      WeaponLaunchBone = PRIMARY Muzzle  
      HideSubObject = PARTSUP TurretEl02  
      ShowSubObject = TurretEL01 TURRETPARTS  
    End  
    ConditionState = RUBBLE REALLYDAMAGED  
      Model = NVInferno_D  
    End  
    TrackMarks = EXTnkTrack.tga  
    TreadAnimationRate = 2.0  
  End  
  Draw = W3DModelDraw ModuleTag_0123 ; add a second draw (tree on top)  
    DefaultConditionState  
      Model = PTOak01  
    End  
  End  
  Prerequisites ; change the prerequisites  
    Object = Tank_ChinaCommandCenter TEST_MODE  
  End  
  WeaponSet ; define new weaponset, all parent inherited weapons are cleared  
    Conditions = None  
    Weapon = PRIMARY Tank_InfernoCannonGun  
  End  
  RemoveModule ModuleTag_Stealth ; Remove the stealth update inherited from the parent  
End  
ObjectExtend ZExtendedTank2 ZExtendedTank  ; inherit again
  RemoveModule ModuleTag_0123  ; remove the tree draw
  WeaponSet  ; replaces all weaponset
    Conditions = None  
    Weapon = PRIMARY MarauderTankGun  
  End  
  ArmorSet  ; replaces all armor sets
    Conditions = None  
    Armor = TruckArmorExtended  
    DamageFX = TankDamageFX  
  End  
End  

Clone this wiki locally