Creating new weapons

From ZDoom Wiki

Jump to: navigation, search

While making a custom weapon in ZDoom is a bit tricky, this guide should help you get on your way.

Contents

DECORATE Code

A basic weapon in the decorate lump would look like this:

  Actor UberShotgun : SuperShotgun 20024
  {
     Weapon.SelectionOrder 350
     Inventory.PickupSound "misc/usgpickup" 
     Weapon.AmmoGive 12 
     Weapon.AmmoUse 4 
     AttackSound "weapons/ubersgf" 
     States 
     { 
     Spawn: 
        USGP A -1 
        Loop
     Ready: 
        USHG A 1 A_WeaponReady 
        Loop 
     Deselect: 
        USHG A 1 A_Lower 
        Loop 
     Select: 
        USHG A 1 A_Raise 
        Loop 
     Fire: 
        USHG A 3
        USHG A 0 A_FireBullets (13.4, 9.2, 50, 10, "BulletPuff")
        USHG A 7 A_GunFlash
        USHG B 7
        USHG C 7 A_CheckReload
        USHG D 7 A_OpenShotgun2
        USHG E 7
        USHG F 7 A_LoadShotgun2
        USHG G 6
        USHG H 6 A_CloseShotgun2
        USHG A 5 A_ReFire
        Goto Ready 
     Flash: 
        USGF A 6 A_FireBullets(10,10,15,30,0,1) 
        Stop 
     } 
  }

Now that big chunk of code describes the functions and states of a shotgun. Let's analyse this code.

Defining an Actor

The format for this line is: ACTOR <ActorName> [: <inheriting actor>] [<DoomEd Number>] [replaces <replaces>] So our actor is going to be named "UberShotgun", it will inherit all the properties of the super shotgun ("SuperShotgun"), and it's DoomEd Number will be 20024.

Note: In order to make a weapon, the actor always has to inherit from Weapon or another actor that does inherit from Weapon, such as SuperShotgun.

The brackets ("{ }") define the start and end of the code block. All the information pertaining to this actor MUST be within these brackets.

Actor Properties

Next there are various weapon properties, such as the ammo type the weapon uses, and how much it uses with each shot.

There are other properties you can set here, but they are not all required for every weapon. This weapon inherits all of its missing properties from the original shotgun. Like the pickup message, if we wanted to define a custom pickup message, then we could put in a line of code that looks like this.

Also, notice how I didn't define an ammo type. Because of inheriting that, I didn't have to do it. Inheriting makes it a somewhat shorter process by taking out the un-needed pieces of code that need to be written.

Read all about these various properties you can set for weapons on the Weapon and Inventory pages.

Actor States

The next chunk in the code defines the Actor states of the weapon. These tell ZDoom what is going on and what to do at certain frames. This removes the previous limitations of DeHacked or Whacked where you couldn't add in more frames, but could only replace the current ones. With this method, you are able to make brand new sequences, to brand new weapons.

Within a state there is a certain form to be observed.

Note: These functions are not frames, and will not be counted as part of any jump function or a Goto command with an offset.

Let's analyse the states of our UberShotgun.

Spawn State

First off is the spawn state: Code:

  Spawn: 
        USGP A -1 
        Loop 

Spawn is the state the weapon will be in when it is spawned as a pickup. This state definition is very simple. The shotgun lying on the ground will display the sprite USGPA until it's picked up by the player.

Ready State

Next in these series of states is the READY state: Code:

   Ready: 
        USHG A 1 A_WeaponReady 
        Loop 

This state will be entered when the weapon has been selected. The action A_WeaponReady tells ZDoom that the weapon is ready, ie. it can fire, or be deselected. The sprite, USHGA, is the image of the shotgun when it's not doing anything.

Select/Deselect States

The next two states are entered when the player selects, or deselects the weapon. Look at the format of the SELECT and DESELECT states: Code:

  Deselect: 
        USHG A 1 A_Lower 
        Loop 
     Select: 
        USHG A 1 A_Raise 
        Loop 

By default, when a weapon is selected, its sprite is drawn off the screen. The action A_Raise moves the sprite up, and by looping the state, the weapon will be moved until its sprite is at the correct vertical position, at which point the game will goto the Ready state.

Fire State

The Fire state is the state that's entered when the player presses the fire button. The firing sequence looks like this: Code:

  Fire: 
        USHG A 3
        USHG A 0 A_FireBullets (13.4, 9.2, 50, 10, "BulletPuff")
        USHG A 7 A_GunFlash
        USHG B 7
        USHG C 7 A_CheckReload
        USHG D 7 A_OpenShotgun2
        USHG E 7
        USHG F 7 A_LoadShotgun2
        USHG G 6
        USHG H 6 A_CloseShotgun2
        USHG A 5 A_ReFire
        Goto Ready

The first frame shows us the same sprite we saw in the ready state, this will mean that firing is not instant (although it's pretty close). The next frame last 0 tics, this means that frame and the one after it will be executed at the same time. If you ever need two or more actions to happen at the same time, you can use a frame with 0 duration.

The first of these frames uses A_FireBullets, this is what actually shoots the gun. The second frame uses A_GunFlash. What this means is that the Flash state will be executed and run in tandem with the Fire state from that point onward.

A_CheckReload will check if the player still has enough ammo to fire another shot (4 shells in this case), and if they don't, it will switch their weapon to the highest priority available (remember Weapon.SelectionOrder). This makes sense, because if the player had no ammo left, we wouldn't want them to see the 'reloading' sprites that are coming up next.

The rest of the frames would show the 'reloading' sequence of the shotgun. The 3 Open/Load/Close Shotgun2 actions play the sounds of the shotgun reloading.

The last frame of the sequence has A_ReFire. This will check if the player still has the fire button held down, and if they do it will jump to the Hold state. If no Hold state exists, it will jump to the Fire state instead.

The hold state may not seem useful at first, but consider if the weapon you were making was a laser cannon. When you first press the fire button, the cannon needs to charge up, and then it shoots the actual laser beam. But you wouldn't want it to shoot the laser for 6 tics and then go back to the charging sequence. Instead you would create a hold state that is exactly like the Fire state but without the charging sequence.

Finally, at the end of the sequence, we go back to the Ready state so the player can fire again, or switch to another weapon.

Flash State

The last state in our weapon is the Flash state. Code:

  Flash: 
        USGF A 6 bright
        Stop

As stated above, this state runs at the same time as the Fire state, because of when we called A_GunFlash. The first and only frame of this state has the sprite USGFA, which is an image of the muzzle flash. It also has the 'bright' keyword, this means the sprite will be drawn at full brightness, regardless of the light level of the sector. Having a flash state is not mandatory. Although there are some creative uses for the flash state; you could have 2 different firing sounds or gun flash sprites, and with a combination of A_Jump, A_PlaySoundEx, and the different sprites, you could randomize the firing sound and the muzzle flash that the player sees. At the end of the sequence we have a Stop command. We don't need to go back to Ready, because the Fire sequence is running underneath the Flash one, and when the Fire sequence is completed, it will return to the Ready state.

Conclusion

Hopefully you now have a better idea of how to use DECORATE to create a custom weapon. Remember, the best way to learn is by doing, so go try it for yourself!

Personal tools
Namespaces
Variants
Actions
Navigation
ACS
DECORATE
ZDoom mods
Toolbox