The demons came and the marines died. Except one. Your are the last defence against these hell-spawned hordes. Prepare for the most intense mutant-laden, blood-splattered action ever! The texture-mapped virtual world is so real, you don't just play DOOM - you live it.

Report article RSS Feed Doom Source Code Tutorial 10

Modding The Monsters In Doom Part 3 - The Pink Demon. In addition to biting flesh, this demon can now shoot fire balls at its enemies.

Posted by Delyon on Oct 18th, 2011
Basic Client Side Coding.

Doom Source Code Tutorial 10
Game: Doom or Doom2
Level: Basic.
Objective: Understand the basics of the Demon's states, attacks and characteristics.
Resources required: VC++ 2008 Express Edition; source code for Doom (tested with Doomsday ver 1.9.0-beta6.9 and chocolate doom).
Introduction:
Most missile slinging monsters in doom like imps, and barons have two modes of attack: the normal missile shooting from a distance and also what is known as mêlée attack (it's a French word, I believe), when their enemy is up close and personal. Today we are going to make changes to the pink demon, one of two monsters in doom that were deprived from any shooting capability ,not even a wimpy pistol! However they made up for that by their fast chasing skills and flesh biting aggression or in the other case being partly invisible. The changes we intend to make in this article are basic but effective and will focus on giving this particular monster the ability to shoot missiles just like everyone else, and why not? But before we go any further, let me point out that the naming convention in doom for this monster and his cousin the imp, just in case you did not know, somehow got mixed up with the trooper and the sergeant. I do not really know how this happened or why but it will not affect our work. I just want the reader to be aware of this weirdness before we start. Let's begin:
Procedure:
1. As always one of the best ways to start a monster mod is to first examine the states and properties of these entities. Here are the 3 attack states for demons in jdoom, notice that SARG_ATK is used and not something like DEMON_ATK as you'd logically expect; look it up in the objects.ded file:

State {
ID = "SARG_ATK1";
Sprite = "SARG";
Frame = 4;
Tics = 8;
Action = "A_FaceTarget";
Next state = "SARG_ATK2";
}

State {
ID = "SARG_ATK2";
Sprite = "SARG";
Frame = 5;
Tics = 8;
Action = "A_FaceTarget";
Next state = "SARG_ATK3";
}

State {
ID = "SARG_ATK3";
Sprite = "SARG";
Frame = 6;
Tics = 8;
Action = "A_SargAttack";
Next state = "SARG_RUN1";
}

2. The attack sequence uses 3 different attack frames of 8 tics each. Let's have a look at the action function that does the actual flesh tearing, A_SargAttack .Find it in p_enemy.c under jdoom:

void C_DECL A_SargAttack(mobj_t *actor)
{
int damage;
if (!actor->target)
return;
A_FaceTarget(actor);
if (checkMeleeRange(actor))
{
damage = ((P_Random() % 10) + 1) * 4;
P_DamageMobj(actor->target, actor, actor, damage, false);
}

3. As you can clearly see, the function checks to see if the enemy is close enough physically for melee attack,if it checks true then it will enter this attack sequence, otherwise it will just continue the normal run/chase state. Have a look inside the braces, you see that the actual damage to the enemy is done directly by the P_DamageMobj function and the rate of damage is higher than that used for the gunshots. The absence of a gun attack or missile attack is very evident.
4. Now we want to make this monster a shooter; we have several choices here; but let's give it the same capability as the imp as it is the best choice for obvious reasons; you really don't want it to shoot rockets or dozens of skulls in confined spaces. The missile function for the imp which we will examine in the next tutorial should look like this, in jdoom:

P_SpawnMissile (MT_TROOPSHOT, actor, actor->target);

5. So all we need to do to make this work is just simply add this function to the attack function of the pink demon. The complete modified function for jdoom should look like this:

void C_DECL A_SargAttack(mobj_t *actor)
{
int damage;
if (!actor->target)
return;
A_FaceTarget(actor);
if (checkMeleeRange(actor))
{
damage = ((P_Random() % 10) + 1) * 4;
P_DamageMobj(actor->target, actor, actor, damage, false);
return;
}
// launch a missile
P_SpawnMissile (MT_TROOPSHOT, actor, actor->target);
}

Notice that we've added return when the melee action was done.This is the modified version for chocolate doom:

void A_SargAttack (mobj_t* actor)
{
int damage;
if (!actor->target)
return;
A_FaceTarget (actor);
if (P_CheckMeleeRange (actor))
{
damage = ((P_Random())+1)*4;
P_DamageMobj (actor->target, actor, actor, damage);
return;
}
// launch a missile
P_SpawnMissile (actor, actor->target, MT_TROOPSHOT);
}

6. Please go ahead , compile and run your mod. You'll be disapppointed because the demons never shoot at the player from a distance. This is because the attack states for all monsters are actually called from inside the A_Chase() action function. Inside this function, a check is made to see if the monster has a missile attack or not, if it does then missiles will be launched , otherwise nothing will happen. In order to make this happen a "missile attack" entry is required in the Thing structure of that particular monster. Lets check that out. Go back to your objects.ded file or your info.c if you are doing it for chocolate doom and take a look:

Thing {
ID = "SERGEANT";
Name = "Demon";
DoomEd number = 3002;
Spawn state = "SARG_STND";
See state = "SARG_RUN1";
Pain state = "SARG_PAIN";
Melee state = "SARG_ATK1";
Missile state = "NULL";
.....................
.....................
}

And for chocolate doom:

{                    // MT_SERGEANT
3002,              // doomednum
S_SARG_STND,  // spawnstate
150,                // spawnhealth
S_SARG_RUN1,  // seestate
sfx_sgtsit,        // seesound
8,                   // reactiontime
sfx_sgtatk,       // attacksound
S_SARG_PAIN,   // painstate
180,                // painchance
sfx_dmpain,     // painsound
S_SARG_ATK1,  // meleestate
0,                   // missilestate
......................
},

7. You see the entries in red in the blocks above, they are either NULL for nothing or 0 as in info.c indicating to the engine that this monster has no missile attack sequence. By the way you may observe that a mêlée attack entry is present. All we need to do now is just add a missile state attack to this structure and we should be done. Let's do it:

For jdoom it needs to look like this:
Thing {
ID = "SERGEANT";
Name = "Demon";
DoomEd number = 3002;
Spawn state = "SARG_STND";
See state = "SARG_RUN1";
Pain state = "SARG_PAIN";
Melee state = "SARG_ATK1";
Missile state = "SARG_ATK1";

8. However, we need to do it in C code in g_game.c . Add this at the usual place in the function void G_InitNew () in jdoom, just before where it says //<-- KLUDGE as shown below (ver 1.9.0beta6.9 only):

//note: you need to navigate your way through a number of arrays this time!
MOBJINFO[MT_SERGEANT].states[SN_MISSILE] = S_SARG_ATK1;
// <-- KLUDGE

But for chocolate doom,it is easier, just edit info.c as follows:

{                        // MT_SERGEANT
3002,                  // doomednum
S_SARG_STND,     // spawnstate
150,                   // spawnhealth
S_SARG_RUN1,     // seestate
sfx_sgtsit,           // seesound
8,                      // reactiontime
sfx_sgtatk,          // attacksound
S_SARG_PAIN,      // painstate
180,                   // painchance
sfx_dmpain,        // painsound
S_SARG_ATK1,     // meleestate
S_SARG_ATK1,     // missilestate

9. Now take a long breath, compile and start a new game. Go to a level where there are a few pink demons and let the fire balls shower you like hell till your flesh is roast beef. Actually this mod still requires some fine tuning as you may get more fire balls than biting. We‘ll try to fix this in a future article when we talk about MISSILE RANGE and MELEE RANGE.
As an exercise, make this demons shoot a volley of missiles in each attack instead of just one shot. You may want to wait till next tutorial to find out how, because we'll help the imp to do just that.
Best of luck.
Adam.

Return to Tutorials page.

Post a Comment
click to sign in

You are not logged in, your comment will be anonymous unless you join the community today (totally free - or sign in with your social account on the right) which we encourage all contributors to do.

2000 characters limit; HTML formatting and smileys are not supported - text only

Icon
Doom
Platforms
Windows, Mac, Linux, DOS, SNES, GBA, PS1, X360, XBOX
Developer & Publisher
id Software
Engine
Doom Engine
Contact
Send Message
Official Page
Idsoftware.com
Release Date
Released Dec 9, 1993
Game Watch
Track this game
Tutorial
Browse
Tutorials
Report Abuse
Report article
Related Games
Doom
Doom Single & Multiplayer First Person Shooter
Related Engines
Doom Engine
Doom Engine GPL Released Dec 10, 1993
Related Groups
id Software
id Software Developer & Publisher