Creating new projectiles (ZScript)

From ZDoom Wiki
Jump to navigation Jump to search

Projectiles are actors that can be fired by the player weapons with A_FireProjectile, or by monsters with A_SpawnProjectile or A_CustomComboAttack. Projectiles have speed and can move at constant velocity until they hit another actor, after which they'll deal damage to it.

Properties, states and sounds

There's only a few things to observe:

  • Use the Projectile property to set all the necessary flags to make an actor into a projectile.
  • Projectiles need their Speed property defined, otherwise they won't be able to move.
  • Projectiles also need Damage (or, for more compelx functionality, Damage Function) in order to be able to deal damage.
  • Set proper Height and Radius.
  • Define a looping Spawn state sequence and a terminating Death sequence. The Spawn sequence is shown while the projectile is moving and the Death sequence is the explosion animation.

Projectiles can also use different death states depending on what they hit:

  • If the projectile hits an actor that is shootable but cannot bleed (which can be caused by the actor having NOBLOOD, NODAMAGE or INVULNERABLE flags), it will use its Crash state, if present. If there is no Crash state, it'll go to Death as usual.
  • If the projectile hits an actor that can bleed, it will use the XDeath state. If there is no XDeath state, the normal Death state will be used.
  • If the projectile hits a wall, floor, or a non-SHOOTABLE actor, the Death state will be used as normal.

Normally, projectiles define two sounds:

  • The SeeSound is the sound the projectile plays when its fired. It's not obligatory, since you can prefer to play the sound from the Weapon instead.
  • The DeathSound will be played when the projectile explodes.

Examples

This shows a simple projectile:

class BlueShot02 : Actor
{
  Default
  {
    Projectile;
    Height 8;
    Radius 6;
    Damage 5;
    Speed 10;
    RenderStyle 'Add';
    SeeSound "misc/shot";
    DeathSound "misc/shotx";
  }
  States
  {
  Spawn:
    WS16 AB 4 bright;
    loop;
  Death:
    WS16 CDE 6 bright;
    stop;
  }
}


To create a homing missile you have to add the SEEKERMISSILE flag and call one of the seeking functions in the Spawn sequence:

actor BlueShotSeeking : Actor
{
  Default
  {
    Projectile;
    +SEEKERMISSILE
    Height 8;
    Radius 6;
    Damage 5;
    Speed 10;
    RenderStyle 'Add';
    SeeSound "misc/shot";
    DeathSound "misc/shotx";
  }
  States
  {
  Spawn:
    WS16 A 4 bright A_Tracer2;
    loop;
  Death:
    WS16 CDE 6 bright;
    stop;
  }
}

You can also do more complex things with Action functions, for example spawning a trail behind the projectile or doing some special effect while exploding. This is a projectile that is doing some BFG-like effect with a different sprite. This projectile also has a limited life span. It automatically explodes after a few seconds because the Spawn state is not looped:

class DevastatorBall : Actor
{
  Default
  {
    Projectile;
    Radius 13;
    Height 8;
    Speed 25;
    Damage 200;
    RenderStyle 'Add';
    Alpha 0.8;
    DeathSound "weapons/bfgx";
  }
  States
  {
  Spawn:
    DVS1 A 100 bright;
    TNT1 A 0 ExplodeMissile;
  Death:
    DVE1 AB 8 bright;
    DVE1 C 8 bright A_BFGSpray ("DevastatorExtra");
    DVE1 DEF 8 bright;
    stop;
  }
}

Projectiles can also be subjected to gravity. To do this, you will need to remove the NOGRAVITY flag, which is automatically set by the Projectile property. After that you can also make your projectile bouncing by using bouncing flags or the BounceType property (but not both).

This is an example of a simple bouncing projectile that looks like Imp's fireball but explodes and uses sounds from a Rocket:

class SimpleGrenade : Actor
{
  Default
  {
    Radius 11;
    Height 8;
    Speed 25;
    Damage 20;
    Projectile;
    -NOGRAVITY
    SeeSound "weapons/rocklf";
    DeathSound "weapons/rocklx";
    Obituary "$OB_MPROCKET";
    +ROCKETTRAIL
    +BOUNCEONWALLS
    +BOUNCEONFLOORS
    +BOUNCEONCEILINGS
    +BOUNCEAUTOOFF
    Gravity 0.5;
    WallBounceFactor 0.5;
    BounceFactor 0.75;
  }
  States
  {
  Spawn:
    BAL1 A 1 bright;
    loop;
  Death:
    MISL B 8 Bright A_Explode;
    MISL C 6 Bright;
    MISL D 4 Bright;
    Stop;
  }
}

Virtual functions

There are several virtual functions that are relevant for projectiles and can be used to add custom behavior to them. Check the following pages: