A basic weapon in the decorate lump would look like this:
Code: Select all
ACTOR Doom3Shotgun : Shotgun 20024
{
Weapon.SelectionOrder 350
Inventory.PickupSound "misc/d3pickup"
Weapon.AmmoGive 8
Weapon.AmmoUse 1
AttackSound "weapons/d3shtgnf"
States
{
Spawn:
D3SH A -1
LOOP
Ready:
D3SG A 1 A_WeaponReady
LOOP
Deselect:
D3SG A 1 A_Lower
LOOP
Select:
D3SG A 1 A_Raise
LOOP
Fire:
D3SG A 0 A_JumpIfNoAmmo(1)
D3SG A 6 A_GunFlash
D3SG B 4
D3SG C 4
D3SG D 34
D3SG E 2
D3SG F 2
D3SG G 8
D3SG F 2
D3SG E 2
Goto Ready
Flash:
D3SF A 6 A_FireBullets(10,10,15,30,0,1)
stop
}
}
Lets start by analyzing this piece of code.
(ACTOR Doom3Shotgun : Shotgun 20024)- Describes that this thing is going to be a complex actor, like a monster or a weapon. Instead of a static object or projectile. This line must always come first so that ZDoom knows that it is "compiling" a sort of weapon.
Note: this line must always be in the format (ACTOR [weaponname] : [inheriting weapon or "weapon"] [doomed number])
After that line, there is a single bracket. This bracket marks the start of the code.
Next comes the various weapon stats, like what ammo type, how much ammo this weapon gives oyu when you pick it up, or how much it uses on one shot. Then there is the properties like what sound it should make when firing, or the message you recieve when picking up the weapon.
(Inventory.PickupSound "misc/d3pickup")-Tells ZDoom what sound to play when the item is picked up. [can be defined in the SNDINFO lump]
(Weapon.AmmoGive 8)-Tells ZDoom how much ammo to give when this weapon is picked up. [note, this is not the max of how much ammo it can hold]
(Weapon.AmmoUse 1)-Tells ZDoom how much ammo to use when firing the weapon.
(AttackSound "weapons/d3shtgnf")-Tells ZDoom what sound to play when the weapon is fired. [can also be defined in the SNDINFO lump]
there are other properties you can set there, but they were not required for that weapon, because it is inheriting all of its' missing properties from the original shotgun. Like the pickup message, if I wanted to define a custom pickup message, then I would have to put in a line of code that looks like this.
(Inventory.Pickupmessage "You got the Doom 3 Shotgun!")
(please note that the function 'Weapon.SelectionOrder' prioritizes which weapons the game should switch to if your current weapon runs out of ammo. So if you run out of shells, you would switch to the super shotgun because it's preference is higher than, say, the pistol.
That would go at the top of the script above the pickup sound. Also, notice how I didn't define an ammo type. It was because of inheriting that I didn't have to do it. Inheriting makes it a some what shorter process, by taking out the un-needed peices of code needing to be written.
Anyways... Let's get back to the analysis!
The next chunk in the code, is the most crucial part... The firing sequences!
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.
The states code looks a bit like this:
Code: Select all
States
{
Spawn:
D3SH A -1
LOOP
Ready:
D3SG A 1 A_WeaponReady
LOOP
Deselect:
D3SG A 1 A_Lower
LOOP
Select:
D3SG A 1 A_Raise
LOOP
Fire:
D3SG A 0 A_JumpIfNoAmmo(1)
D3SG A 6 A_GunFlash
D3SG B 4
D3SG C 4
D3SG D 34
D3SG E 2
D3SG F 2
D3SG G 8
D3SG F 2
D3SG E 2
Goto Ready
Flash:
D3SF A 6 A_FireBullets(10,10,15,2,0,1)
stop
}
First off is the spawn state:
Code: Select all
Spawn:
D3SH A -1
LOOP
This (as all other states) has to be in a certain format, which as follows:
Code: Select all
Spawn:
[sprite] [frame] [delay]
LOOP
the FRAME always is the next letter after the SPRITE.
and the DELAY is how long it will take before it gets to the next frame.
[note: DELAY is not in seconds, it goes at its' own pace, so play around with the numbers]
[note 2: for a SPAWN state, always use a DELAY of -1]
Next in these series of states is the READY state:
Code: Select all
Ready:
D3SG A 1 A_WeaponReady
LOOP
The format of this state is similar to the SPAWN state, except for a couple exceptions.
Code: Select all
Ready:
[sprite] [frame] [delay] [action]
LOOP
the ACTION, however is used in every state, except the SPAWN state. the ACTION tells ZDoom what to perform when it gets to this particular frame.
[note: keep in mind that this sprite, is supposed to be the idle state of your weapon! NOT what it will look like when it is on the ground]
[note 2: always keep the action as "A_WeaponReady" so ZDoom doesn't crash!]
The next two states, are basically the exact opposite of each other. Look at the format of the SELECT and DESELECT states:
Code: Select all
Deselect:
D3SG A 1 A_Lower
LOOP
Select:
D3SG A 1 A_Raise
LOOP
The next state, defines what happens when you click the shoot button. It tells ZDoom what to shoot, or what to do at the select frames.
On this weapon, there are a bunch of frames, but only about six of them are actual firing frames. The rest are to give the illusion, that it is "reloading".
The firing sequence looks like this
Code: Select all
Fire:
D3SG A 0 A_JumpIfNoAmmo(1)
D3SG A 6 A_GunFlash
D3SG B 4
D3SG C 4
D3SG D 34
D3SG E 2
D3SG F 2
D3SG G 8
D3SG F 2
D3SG E 2
Goto Ready
A_FireBullets(h-spread, v-spread, number of bullets, damage per bullet, "PuffType", UseNoAmmo,range) - fires certain ammount of bullets with custom damage
A_CustomBulletAttack(h-spread, v-spread, number of bullets, damage per bullet, "PuffType", range) <-- Monsters only
A_RailAttack(damage,x-offset,ammo,"RR GG BB" color of the spiral, "RR GG BB" color of the line.)
Spoiler:
A_JumpIfNoAmmo(number of frames) - it jumps the specified number of frames when you have no ammo.
A_GiveInventory("item name", amount) - gives the player an item
A_ReFire - goes to the HOLD state
A_TakeInventory("item name", amount) - takes an item from the player
A_SpawnItem("item name", distance, zheight, bool useammo [don't use ammo?]) - spawns item infront of user
A_CustomPunch(damage, dontrandomize, UseNoAmmo, pufftype,range) - defines a punching paramter
A_FireCustomMissile(type, angle, UseNoAmmo, xy-offset, spawnheight) - fires a custom missle
A_GunFlash - goes to the FLASH state, playing through the frames and drawing the sprites directly on top of the weapon's firing frames.
A_PlaySound("soundname") - plays the specified sound on the selected frame.
A_Explode - Damages all things within the explosion radius.
A_Gravity - makes the thing subject to falling from the air. (projectiles only)
A_SeekerMissile(angle threshold, angle maxturnangle) - threshold and maxturnangle determine how 'aggressive' the missile will home in on its target. The larger the values the more precise it is. Both angles are specified in degrees and must be in the range [0, 90]. (projectiles only)
A_JumpIfInventory("itemname", amount, frames) - Skips a certain number of frames depending on how much of an inventory item you have, the inventory items can also be weapons or ammo.
these are just some of the states used to define actions. If you have one that I haven't covered, email the function, and the syntax to mastershake2005@verizon.net
The next two states are semi important. The FLASH and HOLD states.
The FLASH state is only used if you want a muzzle flash to be in your weapon. The HOLD state is only if you want your weapon to be able to fire over and over again. [like a machine gun]
The FLASH state looks like this:
Code: Select all
Flash:
[sprite] [frame] [delay] [action]
stop
The HOLD state looks very similar:
Code: Select all
Hold:
[sprite] [frame] [delay] [action]
Goto Ready
HOW-TO MAKE CUSTOM SPRITE TRAILS
This is very simple to do. (I learned it by viewing the DECORATE of Daniel's Weapon mod)
Anyways...
Make your weapon. Then have it fire a custom missile, lets say that the missile is called FreezerMissile... Now the DECORATE for this missile should look similar to this
Code: Select all
projectile FreezeMissile
{
Radius 11
Height 8
Speed 22
Damage 21
PROJECTILE
ExplosionDamage 128
ExplosionRadius 160
SeeSound "weapons/missilefly"
DeathSound "weapons/freezebombexpl"
Obituary "%o was killed by a FreezeMissile."
States
{
Spawn:
FRMS A 0 Bright
FRMS A 2 Bright
Loop
Death:
FRME A 3 Bright A_Explode
FRME B 0
FRME B 0
FRME B 0
FRME B 0
FRME BCDEFGHIJKLMNOPQRS 3 Bright
Stop
}
}
Code: Select all
projectile FreezeMissile
{
Radius 11
Height 8
Speed 22
Damage 21
PROJECTILE
ExplosionDamage 128
ExplosionRadius 160
SeeSound "weapons/missilefly"
DeathSound "weapons/freezebombexpl"
Obituary "%o was killed by a FreezeMissile."
States
{
Spawn:
FRMS A 0 Bright
FRMS A 2 Bright A_CustomMissile("FreezeMissileTrail",0,0,0)
FRMS A 2 Bright A_CustomMissile("FreezeMissileTrail",0,0,0)
FRMS A 2 Bright A_CustomMissile("FreezeMissileTrail",0,0,0)
FRMS A 2 Bright A_CustomMissile("FreezeMissileTrail",0,0,0)
FRMS A 2 Bright A_CustomMissile("FreezeMissileTrail",0,0,0)
Loop
Death:
FRME A 3 Bright A_Explode
FRME B 0
FRME B 0
FRME B 0
FRME B 0
FRME BCDEFGHIJKLMNOPQRS 3 Bright
Stop
}
}
Code: Select all
ACTOR FreezeMissileTrail
{
Radius 4
Height 3
Speed 1
Scale 0.7
+NOGRAVITY
RenderStyle Translucent
Alpha 0.5
States
{
Spawn:
MTRL A 2
MTRL AB 3
MTRL CD 3
MTRL E 4
MTRL F 5
Stop
}
}
"Upgradable Weapons"
Ok... I just sorta figured this out the other day, so here is my explanation of it.
Have you ever wanted a dual weilding weapon, but only if you pick up one of them first? If so then keep reading... There are also other applications with this method, but you would need to screw around with it a bit. So here we go.
First we need our single weild weapon.
So here we have an smg for example
Code: Select all
ACTOR SMG : Weapon
{
Weapon.SelectionOrder 200
Weapon.AmmoGive 12
Weapon.AmmoUse 1
Weapon.Kickback 200
Weapon.AmmoType "Clip"
States
{
Spawn:
Ready:
SMGG A 1 A_WeaponReady
LOOP
Deselect:
SMGG A 1 A_Lower
LOOP
Select:
SMGG A 1 A_Raise
LOOP
Fire:
SMGG A 0 A_JumpIfNoAmmo(3)
SMGG B 1 A_PlaySound("weapons/smgf")
SMGG C 1 A_FireBullets(3,3,1,6,0,1)
SMGG B 1
Goto Ready
}
}
Next you need the dual weild version. It has to be a completely different weapon, try not to inherit from the single wield if possible.
So the dual wield looks like this
Code: Select all
ACTOR DualSMG : Weapon
{
Weapon.SelectionOrder 200
Weapon.AmmoGive 12
Weapon.AmmoUse 1
Weapon.Kickback 200
Weapon.AmmoType "Clip"
States
{
Spawn:
Ready:
SM2G A 1 A_WeaponReady
LOOP
Deselect:
SM2G A 1 A_Lower
LOOP
Select:
SM2G A 1 A_Raise
LOOP
Fire:
SM2G A 0 A_JumpIfNoAmmo(3)
SM2G B 1 A_PlaySound("weapons/smgf")
SM2G C 1 A_FireBullets(6,3,3,6,0,1)
SM2G B 1
Goto Ready
}
}
For the Inventory Item you need it to check and see how many you have of that inventory item. Depending on the amount it will then decide which item to give you (single,dual or ammo) The inventory for this particualr item will look like this
Code: Select all
ACTOR SMGGun : Inventory 1989
{
+AUTOACTIVATE
Inventory.MaxAmount 2
Inventory.PickupSound "misc/w_pkup"
Inventory.PickupMessage "You got the SMG"
States
{
Spawn:
SMCH A -1
LOOP
Pickup:
TNT1 A 0 A_JumpIfInventory("SMG", 1, 4)
TNT1 A 0 A_JumpIfInventory("SMGGun", 2, 6)
TNT1 A 0 A_GiveInventory("SMG", 1)
TNT1 A 0 A_SelectWeapon("SMG")
Stop
TNT1 A 0 A_TakeInventory("SMG", 1)
TNT1 A 0 A_GiveInventory("DualSMG", 1)
TNT1 A 0 A_SelectWeapon("DualSMG")
Stop
TNT1 A 0 A_TakeInventory("SMGGun", 1)
TNT1 A 0 A_GiveInventory("Clip", 12)
Stop
}
}
ALTERNATE FIRE
ok boys and girs today we get our alternate fire. It is basically the same as making normal DECORATE weapons, except with 2 extra states.
These two extra states are
Code: Select all
AltFire:
and
AltHold:
The normal gotos apply. for these its just Goto AltFire and A_ReFire...
Note* A_Refire in the alt section goes to alt hold. Im guessing the same with A_GunFlash.
As you can see, the alternate fire is basically the same as regular, just with a couple new states.
Alerting Monsters when you want
Lets say you want to make a reloading weapon(tutorial coming soon) But you do not want to alert the monsters while reloading. This can be easily achieved with a property flag and a single code pointer. Lets start out with our weapon.
Code: Select all
ACTOR OmegaRifle : PlasmaRifle 20020
{
States
{
Fire:
PLAS A 1
PLAS B 2
PLAS C 2
PLAS D 2 A_FireCustomMissile("PlasmaBall", 0, 1, 0, 0)
PLAS E 2
Goto Ready
AltFire:
PLSR ABCDEFGH 2
Goto Ready
}
}
We achieve this by adding a +NOALERT flag to the weapon. So after that the weapon will look like so
Code: Select all
ACTOR OmegaRifle : PlasmaRifle 20020
{
+NOALERT
States
{
Fire:
PLAS A 1
PLAS B 2
PLAS C 2
PLAS D 2 A_FireCustomMissile("PlasmaBall", 0, 1, 0, 0)
PLAS E 2
Goto Ready
AltFire:
PLSR ABCDEFGH 2
Goto Ready
}
}
Code: Select all
ACTOR Alert
{
Height 1
Radius 1
Speed 255
Damage 0
ExplosionRadius 0
ExplosionDamage 0
PROJECTILE
States
{
Spawn:
TNT1 A 0
TNT1 A 0 A_AlertMonsters
Goto Death
Death:
TNT1 A 0
Stop
}
}
Code: Select all
ACTOR OmegaRifle : PlasmaRifle 20020
{
+NOALERT
States
{
Fire:
PLAS A 1
PLAS B 2
PLAS C 2
PLAS D 0 A_FireCustomMissile("Alert", 0, 0, 0, 0)
PLAS D 2 A_FireCustomMissile("PlasmaBall", 0, 1, 0, 0)
PLAS E 2
Goto Ready
AltFire:
PLSR ABCDEFGH 2
Goto Ready
}
}
* New codepointers
* how to make custom projectile trails
*****EDIT 06/04/05*****
*how to make "upgradable weapons"
*****EDIT 06/23/05*****
*Alternate Fire
*Other crap (I think)
*****EDIT 07/03/05*****
*New Codepointers
*****EDIT 07/24/05*****
*Alerting Monsters
This guide was made to show people the basics of the new DECORATE system in the UNOFFICIAL build of ZDoom. This guide and the test wad was created by Chaos Central Inc. the weapon sprites that are in the test wad were "borrowed" from the demo of Doom 2.5
If you have any questions, please feel free to ask by posting on my forum at http://www.chaoscentral.tk
YOU NEED GRUBBER'S LATEST BUILD FOR UPGRADABLE WEAPONS... LOCATED HERE http://www.aki-izumi.com/biohazard/hosted/grb