Beginner's corner

Top  Previous  Next

Exploding barrels

These barrels are lethal; they will explode when they are hit by bullets, rockets, etc; more than that, they will explode if another barrel has exploded nearby. Can you imagine what you can do at a fuel deposit by firing a single bullet? Don't get to close too one of these barrels because the enemies can shoot them too.

You can have as many barrels as you want; place their models in your level and attach them the barrel action:

action barrel
{
   my._DAMAGE = 300;
   my._SIGNAL = 0;
   my.enable_scan = on; 
   my.enable_shoot = on;
   my.enable_detect = on;
   my.event = barrel_explodes;
}

I'm using some template stuff here; _DAMAGE looks much better than skill16, isn't it? Next line, my._SIGNAL = 0; tells the enemy that the barrel is not the player, so it shouldn't attack the barrel :). The barrel is sensitive to scan_entity and bullets, can detect entities and if its event is triggered it will run the barrel_explodes function:

function barrel_explodes()
{
   if ((event_type == event_scan && indicator == _EXPLODE) 
   || (event_type == event_shoot && indicator == _GUNFIRE))
   {
       waitt (3);
       range = my._DAMAGE * 2;
       damage = my._DAMAGE;
       temp.pan = 360;
       temp.tilt = 180;
       temp.z = range;
       indicator = _EXPLODE;
       scan_entity (my.x, temp);
       morph (barrel_sprite, me);
       while (my.frame < 7)
       {
           my.frame += 3 * time;
           wait (1);
       }
       actor_explode();
   }
}

If the barrel is hit by a rocket (or a grenade, etc) or by a bullet, we waitt(3) to avoid the dangerous instruction warning and to get a nice delay, useful for chained explosions. We prepare for a full area scan (pan = 360, tilt = 180, distance = 600 quants) and we set indicator to _EXPLODE - this way we tell the others that this isn't a friendly scan (to open doors or similar).

I have defined a barrel explosion sprite (it's the explo+7 sprite that comes with the templates but I have changed its name) and we replace barrel.mdl with barrel_sprite using morph. The explosion sprite plays its animation frames and then it explodes using the predefined actor_explode() action in the templates.

Footstep

If you've ever wanted to change the sound of player's steps depending on the surface he walks onto, this piece of code is all you need. I have used two types of surface in my example (grass and stone) but you can add as many surface types as you want.

First of all, we need to get rid of the default foot step sound. Open camera.wdl in your template folder, find this line:

play_sound(thud,30);

and comment it by placing // in front of it. Include footstep.wdl in your main game file and call texture_scan in function main.

function texture_scan()
{
   while (player == null) {wait (1);}
   while (1)
   {
       vec_set(temp, player.x);
       temp.z -= 100;
       trace_mode = ignore_me + ignore_passable + ignore_models + ignore_sprites + scan_texture;
       trace (player.x, temp);
       if (str_cmpi ("grass1", tex_name))
       {
            texture_sound(grass);
       }
       else
       {
             texture_sound(stone);
       }
       step_length += 1 + 2 * key_shift;
       waitt (4);
   }
}

We wait for the player to be created and then we start tracing four times a second (that's what waitt (4) does). We trace between player's position and a position located 100 quants below the player. After trace, tex_name holds the name of the floor texture. We compare the floor texture name with "grass" and we call function texture_sound(grass) or texture_sound(stone) depending on the type of surface.

Function texture_sound is called four times a second, but we don't want to have four steps a second unles our player is running like Gabriela Szabo (never heard of her? never mind...). We are using the step_length variable for that; we are adding 1 to its initial value (zero) every second or 3 if shift is pressed, four times a second.

Let's take a look at:

function texture_sound(sound_type)
{
   vec_set (player_pos1, player.pos);
   wait (2);
   vec_set (player_pos2, player.pos);
   if (player_pos1 != player_pos2)
   {
       if ((sound_type == grass) && (step_length % 6 == 0))
       {
           play_sound (grass_snd, 60);
       }
       if ((sound_type == stone) && (step_length % 6 == 0))
       {
           play_sound (stone_snd, 50);
       }
       if (step_length >= 6) {step_length = 0;}
   }
}

First of all, we need to know if the player is moving. I didn't want to modify the templates so I have decided to use a simple method, storing player's position in player_pos1 and again player's position in player_pos2 two frames later. If these values are equal, the player is standing still but if player_pos1 != player_pos2, the player is moving and we need to play the step sounds.

If the player steps onto grass and step_length % 6 = 0 (this means that step_length = 0, 6, 12, ...) we play the grass_snd sound. The same thing happens when the floor is made of stone. What's with this step_length % 6 thing? You remember that function texture_sound is called four times a second, but we don't need four step sounds a second. I chose 6 because it is divided by 1 (step_length += 1 when shift isn't pressed) and 3 (step_length += 3 when shift is pressed). You can use step_length % 3 to double the number of steps if you want to. With step_length % 6, you will hear a step sound every 6 / 4 = 1.5 seconds.

When step_length is bigger than 6, it will be set to 0; this way we make sure that we hear the step sounds even if step_length is 4 and we constantly add 3 to it (step_length % 6 = 0 could never happen).