Questions from the forum

Top  Previous  Next

Q: I am having trouble converting the enemy code in workshop 32 from C-script to lite-C. Can you help?

A: There you go:

 

STRING* bullet_mdl = "bullet.mdl";

 

function fire_bullets(); // creates the bullets

function remove_bullets(); // removes the bullets after they've hit something

function got_shot();

function move_enemy_bullets();

 

#define idle 1

#define attacking 2

#define dead 3

#define status skill1

#define health skill10

 

function fire_bullets()

{

       proc_kill(4); // don't allow more than 1 instance of this function to run

       while (mouse_left) {wait (1);} // wait until the player releases the mouse button

       ent_create (bullet_mdl, camera.x, move_bullets); // create the bullet at camera's position and attach it the "move_bullets" function

}

 

function remove_bullets() // this function runs when the bullet collides with something

{

       wait (1); // wait a frame to be sure (don't trigger engine warnings)

       ent_remove (my); // and then remove the bullet

}

 

action my_enemy() // attach this action to your enemies

{

       while (!player) {wait (1);}

       var idle_percentage = 0;

       var run_percentage = 0;

       var death_percentage = 0;

       VECTOR content_right; // tracks the content in front of the player

       VECTOR content_left; // tracks the content in front of the player

       VECTOR temp;

       set (my, POLYGON); // use accurate collision detection

       my.health = 100;

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); // the enemy is sensitive to impact with player's bullets

       my.event = got_shot; // and runs this function when it is hit

       my.status = idle; // that's the same thing with my.skill1 = 1; (really!)

       while (my.status != dead) // this loop will run for as long as my.skill1 isn't equal to 3

       {

               if (my.status == idle) // hanging around?

               {

                       ent_animate(my, "stand", idle_percentage, ANM_CYCLE); // play the "stand" aka idle animation

                       idle_percentage += 3 * time_step; // "3" controls the animation speed

                       if (vec_dist (player.x, my.x) < 1000) // the player has come too close?

                       {

                               // scanned in the direction of the pan angle and detected the player?

                               if ((c_scan(my.x, my.pan, vector(120, 60, 1000), IGNORE_ME) > 0) && (you == player))

                               {

                                       my.status = attacking; // then attack the player even if it hasn't fired at the enemy yet

                               }

                       }

               }

               if (my.status == attacking) // shooting at the player?

               {

                       // the road is clear? then rotate the enemy towards the player

                       if (c_content (content_right.x, 0) + c_content (content_left.x, 0) == 2)

                       {

                               vec_set(temp, player.x);

                               vec_sub(temp,my.x);

                               vec_to_angle(my.pan, temp); // turn the enemy towards the player

                       }

                       if (vec_dist (player.x, my.x) > 500)

                       {

                               vec_set(content_right, vector(50, -20, -15));

                               vec_rotate(content_right, my.pan);

                               vec_add(content_right.x, my.x);

                               if (c_content (content_right.x, 0) != 1) // this area isn't clear?

                               {

                                       my.pan += 5 * time_step; // then rotate the enemy, allowing it to avoid the obstacle

                               }

                               vec_set(content_left, vector(50, 20, -15));

                               vec_rotate(content_left, my.pan);

                               vec_add(content_left.x, my.x);

                               if (c_content (content_left.x, 0) != 1) // this area isn't clear?

                               {

                                       my.pan -= 5 * time_step; // then rotate the enemy, allowing it to avoid the obstacle

                               }

                               c_move (my, vector(10 * time_step, 0, 0), nullvector, GLIDE);

                               ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation

                               run_percentage += 6 * time_step; // "6" controls the animation speed

                       }

                       else

                       {

                               ent_animate(my, "alert", 100, NULL); // use the last frame from the "alert" animation here

                       }

                       if ((total_frames % 80) == 1) // fire a bullet each second

                       {

                               vec_for_vertex (temp, my, 8);

                               // create the bullet at enemy's position and attach it the "move_enemy_bullets" function

                               ent_create (bullet_mdl, temp, move_enemy_bullets);

                       }

                       if (vec_dist (player.x, my.x) > 1500) // the player has moved far away from the enemy?

                       {

                               my.status = idle; // then switch to "idle"

                       }

               }

               wait (1);

       }

       while (death_percentage < 100) // the loop runs until the "death" animation percentage reaches 100%        

       {

               ent_animate(my, "deatha", death_percentage, NULL); // play the "die" animation only once

               death_percentage += 3 * time_step; // "3" controls the animation speed

               wait (1);

       }

       set (my, PASSABLE); // allow the player to pass through the corpse now

}

 

function got_shot()

{

       if (you.skill30 != 1) {return;} // didn't collide with a bullet? Then nothing should happen

       my.health -= 35;

       if (my.health <= 0) // dead?

       {

               my.status = dead; // stop the loop from "action my_enemy"

               my.event = NULL; // the enemy is dead, so it should stop reacting to other bullets from now on

               return; // end this function here

       }

       else // got shot but not (yet) dead?

       {

               my.status = attacking; // same thing with my.skill1 = 2

       }

}

 

function move_enemy_bullets()

{

       VECTOR bullet_speed; // this var will store the speed of the bullet

       my.skill30 = 1; // I'm a bullet

       // the bullet is sensitive to impact with other entities and to impact with level blocks

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY | ENABLE_BLOCK);

       my.event = remove_bullets; // when it collides with something, its event function (remove_bullets) will run

       my.pan = you.pan; // the bullet has the same pan

       my.tilt = you.tilt; // and tilt with the enemy

       bullet_speed.x = 50 * time_step; // adjust the speed of the bullet here

       bullet_speed.y = 0; // the bullet doesn't move sideways

       bullet_speed.z = 0; // or up / down on the z axis

       // the loop will run for as long as the bullet exists (it isn't "null")

       while (my)

       {

               // move the bullet ignoring its creator (the enemy)

               c_move (my, bullet_speed, nullvector, IGNORE_YOU);

               wait (1);

       }

}

 

 

Q: I've made a game that runs at 1024 x 768 pixels but when I've tried it on a wide screen monitor (1440 x 900 pixels) I noticed that the image doesn't look sharp.Is there any way to restore the sharpness of the images, regardless of the resolution of the screen?

A: The best method is to run the game at the same resolution with your display; here's a tiny snippet that does that automatically.

 

function main()

{

       video_set(sys_metrics(0), sys_metrics(1), 32, 1); // detect and use the best screen resolution

       level_load (test_wmb);

       // put the rest of your code here

}

 

 

Q: I know that in C-script you could determine the width or height of characters in a particular font using the .char_x and .char_y properties. I cant find them in the lite-C manual though; has this been dropped from the language? What is the lite-C way of determining the height of a character for a font?

A: The width and height of the fonts is calculated automatically in lite-C; nevertheless, if you'd like to know the width and height of a character from a bitmapped font you can use the following piece of code.

 

var char_width, char_height;

 

BMAP* ethnocentric18_tga = "ethnocentric18.tga";

 

FONT* arial_font = "Arial#20b";

 

function check_font(BMAP* font_bitmap) // checks bitmapped fonts with up to 4 rows of characters

{

       if (bmap_width(font_bitmap) % 11 == 0) // the image width is divisible by 11? Then it's a single row font!

       {

               char_width = bmap_width / 11;

               char_height = bmap_height;                                

       }

       else // we've got a font that consists of 4 rows, each one of them having 32 characters here

       {

               char_width = bmap_width(font_bitmap) / 32;

               char_height = bmap_height(font_bitmap) / 4;

       }

}

 

PANEL* font_pan =

{        

       pos_x = 0;

       pos_y = 0;

       layer = 15;

       digits(10, 5, "Font character width: %.0f", arial_font, 1, char_width);

       digits(10, 25, "Font character height: %.0f", arial_font, 1, char_height);

       flags = SHOW;

}

 

function test_fonts_startup()

{

       wait (-5); // wait until the level is loaded

       check_font(ethnocentric18_tga); // use your own font(s) here

}

 

 

Q: I need an enemy that comes towards the player until it is 100 quants away from him, and then maintains that distance. Even the player runs toward it, the enemy should retreat in order to keep those 100 quants between it and the player.

A: Use the following snippet as a base for your code.

 

#define idle 1

#define following 2

#define dead 3

#define status skill1

 

action my_enemy() // attach this action to your enemies

{

       while (!player) {wait (1);}

       var idle_percentage = 0;

       var run_percentage = 0;

       VECTOR temp;

       set (my, POLYGON); // use accurate collision detection

       my.status = idle; // that's the same thing with my.skill1 = 1; (really!)

       vec_set (temp.x, my.x); // trace 10,000 quants below the player

       temp.z -= 10000;

       my.z -= c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 20; // play with 20

       while (my.status != dead) // this loop will run for as long as my.skill1 isn't equal to 3

       {

               vec_set (temp.x, my.x); // trace 10,000 quants below the player

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 20; // play with 20

               if (my.status == idle) // hanging around?

               {

                       ent_animate(my, "stand", idle_percentage, ANM_CYCLE); // play the "stand" aka idle animation

                       idle_percentage += 3 * time_step; // "3" controls the animation speed

                       if (vec_dist (player.x, my.x) < 1000) // the player has come too close?

                       {

                               // scanned in the direction of the pan angle and detected the player?

                               if ((c_scan(my.x, my.pan, vector(120, 60, 1000), IGNORE_ME) > 0) && (you == player))

                               {

                                       my.status = following; // then attack the player even if it hasn't fired at the enemy yet

                               }

                       }

               }

               if (my.status == following) // shooting at the player?

               {

                       vec_set(temp, player.x);

                       vec_sub(temp,my.x);

                       vec_to_angle(my.pan, temp); // turn the enemy towards the player

                       if (vec_dist (player.x, my.x) > 100) // the distance between player and enemy is bigger than 100 quants?

                       {

                               c_move (my, vector(10 * time_step, 0, temp.z), nullvector, GLIDE); // move towards the player

                               ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation

                               run_percentage += 6 * time_step; // "6" controls the animation speed, using normal animation

                       }

                       if (vec_dist (player.x, my.x) < 90) // the distance between player and enemy is smaller than 90 quants?

                       {

                               c_move (my, vector(-10 * time_step, 0, temp.z), nullvector, GLIDE); // move away from the player

                               ent_animate(my, "run", run_percentage, ANM_CYCLE); // play the "run" animation

                               run_percentage -= 6 * time_step; // "6" controls the animation speed, using a reversed animation

                       }

                       if (vec_dist (player.x, my.x) > 500) // the player has moved far away from the enemy?

                       {

                               my.status = idle; // then switch to "idle"

                       }

               }

               wait (1);

       }

       set (my, PASSABLE); // allow the player to pass through the corpse now

}

 

 

Q: How can I make a circle on the ground around an entity?

A: The easiest method is to use a passable tga sprite.

 

STRING* circle_tga = "circle.tga";

 

function adjust_circle()

{

       set (my, PASSABLE);

       my.tilt = 90;

       while (1)

       {

               vec_set (my.x, you.x);

               my.z = you.min_z + 35; // place the circle 35 quants above the entity's min_z value, play with 35

               wait (1);

       }

}

 

action my_entity() // moves the entity in a circle

{

       var anim_percentage = 0;

       ent_create(circle_tga, my.x, adjust_circle);

       while (1)

       {

               anim_percentage += 3 * time_step; // 3 = "walk" animation speed

            ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "walk" animation

               c_move (my, vector(5 * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);

               my.pan += 2 * time_step; // 2 sets the radius of the circle

               wait (1);

       }

}

 

aum88_faq1

 

 

Q: I am programming my weapons and I would like to know how to animate them correctly. If I keep the left mouse button pressed, the gun should animate correctly and only shoot one bullet per second. Can you help?

A: Here's the code for an animated weapon that fires a bullet per second.

 

var front_offset = 30; // animates player's weapon while it is firing by moving it backwards

var init_offset = 30; // stores front_offset's value

 

ENTITY* weapon1;

 

STRING* bullet_mdl = "bullet.mdl";

 

SOUND* bullet_wav = "bullet.wav";

 

function fire_bullets();

function move_bullets();

function remove_bullets();

 

action players_weapon() // place your weapon model in the level and attach it this action

{

       weapon1 = my; // I'm weapon1

       VECTOR player1_pos; // stores the initial position of the player

       VECTOR player2_pos; // stores the position of the player after a frame

       VECTOR weapon_offset;

       var weapon_height;

       set (my, PASSABLE); // the weapon model is passable

       while (!player) {wait (1);} // wait until the player is created

       while (vec_dist (player.x, my.x) > 50) {wait (1);} // wait until the player comes close to pick up the weapon

       my.roll = 0;

       while (1)

       {

               vec_set (player1_pos.x, player.x); // store the initial player position

               // place the weapon 30 quants in front, 18 quants to the right and 20 quants below camera's origin

               vec_set (weapon_offset.x, vector (front_offset, -18, -20));

               if (vec_dist (player1_pos.x, player2_pos.x) != 0) // the player has moved during the last frame?

               {

                       weapon_height += 30 * time_step; // then offset weapon_height (30 = weapon waving speed)

                       weapon_offset.z += 0.3 * sin(weapon_height); // (0.3 = weapon waving amplitude)

               }

               // rotate weapon_offset according to the camera angles

               vec_rotate (weapon_offset.x, vector (camera.pan, camera.tilt, 0));

               vec_add (weapon_offset.x, camera.x); // add the camera position to weapon_offset

               vec_set (my.x, weapon_offset.x); // set weapon's coords to weapon_offset

               my.pan = camera.pan; // use the same camera angles for the weapon

               my.tilt = camera.tilt;

               vec_set (player2_pos.x, player.x); // store the new player coordinates after 1 frame

               wait (1);

       }

}

 

function weapon_startup()

{

       on_mouse_left = fire_bullets; // call function fire_bullets() when the left mouse button is pressed

}

 

function fire_bullets() // includes the code that animates the weapon as well

{

       var temp_seconds = 0;

       VECTOR temp;

       proc_kill(4); // don't allow more than 1 copy of this function to run

       while (mouse_left) // this loop runs for as long as the left mouse button is pressed

       {

               front_offset -= 1; // move the weapon backwards a bit

               vec_for_vertex (temp.x, weapon1, 29); // get the coordinates for the bullets' origin

                // create the bullet at camera's position and attach it the "move_bullets" function

               ent_create (bullet_mdl, temp.x, move_bullets);

               temp_seconds = 0;

               snd_play (bullet_wav, 100, 0); // play the bullet sound at a volume of 100

               while (temp_seconds < 0.5)

               {

                       temp_seconds += time_step / 16; // adds 0.5 to temp_seconds in 0.5 seconds)

                       front_offset -= 0.1; // restore the position of the weapon

                       wait (1);

               }

               while (front_offset < init_offset)

               {

                       front_offset += 0.1; // restore the position of the weapon

                       wait (1);

               }

               front_offset = init_offset;

       }

}

 

function move_bullets()

{

       VECTOR bullet_speed; // stores the speed of the bullet

       my.skill30 = 1; // I'm a bullet

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY | ENABLE_BLOCK);

       my.event = remove_bullets; // when it collides with something, its event function (remove_bullets) will run

       my.pan = camera.pan; // the bullet has the same pan

       my.tilt = camera.tilt; // and tilt with the camera

       bullet_speed.x = 200 * time_step; // adjust the speed of the bullet here

       bullet_speed.y = 0; // the bullet doesn't move sideways

       bullet_speed.z = 0; // then don't allow the gravity to have its ways with the bullet

       while (my) // this loop will run for as long as the bullet exists (it isn't "null")

       {

               // move the bullet ignoring the passable entities and store the result in distance_covered

               c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE);

               wait (1);

       }

}

 

function remove_bullets() // this function runs when the bullet collides with something

{

       wait (1); // wait a frame to be sure (don't trigger engine warnings)

       ent_remove (my); // and then remove the bullet

}

 

 

Q: Does anyone knows how to put a muzzle effect in front of an animated weapon model?

A: There you go:

 

ENTITY* weapon1;

 

STRING* bullet_mdl = "bullet.mdl";

STRING* muzzle_tga = "muzzle.tga";

STRING* explosion_pcx = "explosion+5.pcx"; // explosion sprite

 

SOUND* bullet_wav = "bullet.wav";

 

function fire_bullets();

function move_bullets();

function remove_bullets();

function display_muzzle();

function explosion_sprite();

 

action players_weapon() // place your weapon model in the level and attach it this action

{

       VECTOR weapon_offset;

       weapon1 = my; // I'm weapon1

       set (my, PASSABLE); // the weapon model is passable

       while (!player) {wait (1);} // wait until the player is created

       while (1)

       {

               // place the weapon 30 quants in front, 18 quants to the right and 20 quants below camera's origin

               vec_set (weapon_offset.x, vector (30, -18, -20));

               // rotate weapon_offset according to the camera angles

               vec_rotate (weapon_offset.x, vector (camera.pan, camera.tilt, 0));

               vec_add (weapon_offset.x, camera.x); // add the camera position to weapon_offset

               vec_set (my.x, weapon_offset.x); // set weapon's coords to weapon_offset

               my.pan = camera.pan; // use the same camera angles for the weapon

               my.tilt = camera.tilt;

               wait (1);

       }

}

 

function weapon_startup()

{

       on_mouse_left = fire_bullets; // call function fire_bullets() when the left mouse button is pressed

}

 

function fire_bullets() // includes the code that animates the weapon as well

{

       VECTOR temp;

       proc_kill(4); // don't allow more than 1 copy of this function to run

       while (mouse_left) // this loop runs for as long as the left mouse button is pressed

       {

               vec_for_vertex (temp.x, weapon1, 29); // get the coordinates for the bullets' origin

                // create the bullet at camera's position and attach it the "move_bullets" function

               ent_create (bullet_mdl, temp.x, move_bullets);

               ent_create (muzzle_tga, temp.x, display_muzzle); // create the gun muzzle

               snd_play (bullet_wav, 100, 0); // play the bullet sound at a volume of 100

               wait (-0.1); // fire 10 bullets per second

       }

}

 

function move_bullets()

{

       VECTOR bullet_speed; // stores the speed of the bullet

       my.skill30 = 1; // I'm a bullet

       my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY | ENABLE_BLOCK);

       my.event = remove_bullets; // when it collides with something, its event function (remove_bullets) will run

       my.pan = camera.pan; // the bullet has the same pan

       my.tilt = camera.tilt; // and tilt with the camera

       bullet_speed.x = 200 * time_step; // adjust the speed of the bullet here

       bullet_speed.y = 0; // the bullet doesn't move sideways

       bullet_speed.z = 0; // then don't allow the gravity to have its ways with the bullet

       while (my) // this loop will run for as long as the bullet exists (it isn't "null")

       {

               // move the bullet ignoring the passable entities and store the result in distance_covered

               c_move (my, bullet_speed, nullvector, IGNORE_PASSABLE);

               wait (1);

       }

}

 

function remove_bullets() // this function runs when the bullet collides with something

{

       wait (1); // wait a frame to be sure (don't trigger engine warnings)

       ent_create (explosion_pcx, my.x, explosion_sprite); // create the explosion sprite

       set (my, INVISIBLE | PASSABLE);

       wait (-2); // wait until the explosion_sprite() function is over

       ent_remove (my); // and then remove the bullet

}

 

function display_muzzle()

{

       set (my, PASSABLE | BRIGHT);

       my.roll = 0.01;

       my.ambient = 100; // and this line makes it even brighter

       my.pan = weapon1.pan; // has the same pan and tilt

       my.tilt = weapon1.tilt; // with the weapon

       my.roll = random(360); // and a random roll angle (looks nicer)

       my.scale_x = 0.3; // we scale it down

       my.scale_y = my.scale_x; // on all the axis

       my.scale_z = my.scale_z; // this would only be needed for a 3D (model-based) muzzle

       weapon1.ambient = 100; // highlight the weapon (makes it look more realistic)

       wait (2); // show the muzzle sprite for 2 frames

       weapon1.ambient = 0; // restore the normal weapon ambient value

       ent_remove (my); // and then remove it

}

 

function explosion_sprite()

{

       set (my, PASSABLE | BRIGHT | TRANSLUCENT);

       my.scale_x = 0.15; // we scale it down to 0.15

       my.scale_y = my.scale_x; // on both axis

       my.ambient = 100; // and we give it an ambient of 100

       my.roll = random(360); // we set a random roll angle

       my.alpha = 100; // but we set it to be completely opaque for now

       while (my.frame < 5) // go through all the animation frames

       {

               my.frame += 2 * time_step; // animation speed

               wait (1);

       }

       while (my.alpha > 0) // now fade the last frame quickly

       {

               my.alpha -= 50 * time_step; // 50 = fading speed

               wait (1);

       }

       ent_remove (my);

}

 

aum88_faq2

 

 

Q: I know how to use the ent_animate command, but I don't know how to set up the animation scenes in Med. My model has 101 animation frames; how do I set them up in order to use them with ent_animate?

A: Here's a step by step explanation.

 

1) Open your model in Med and click the "Animate" button at the bottom of the screen.

 

aum88_faq3

 

2) Examine the animation frames carefully; decide what are the frames that will be used for the first scene ("walk" for my model). Click the "Play Setup" button in the lower left corner, and then check if you've got them right or not by seeing how the animation looks when it runs in a loop.

 

aum88_faq4

 

3) Time to change the frame names; select Edit -> Manage Frames.

 

aum88_faq5

 

4) Select the desired (walk) frames in the "Frames" window, and then click the "Rename Frames" button. I chose to name the walking frames for my model... "walk", what else?

 

aum88_faq6

 

5) Repeat the process for the rest of your animations. You will end up having "walk", "stand", etc animation frames that can be used with ent_animate.

 

 

Q: Is it possible to change the texture of a block in a certain area of my level?

A: The easiest method is to save your block as a wmb entity and then replace it with another one that has the desired texture using ent_morph.

 

BMAP* pointer_tga = "pointer.tga";

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function replace_block()

{

       ent_morph(me, "newblock.wmb"); // replaces the old block with the new one; newblock.wmb must exist!

       my.event = NULL; // don't react to mouse clicks from now on

}

 

action special_block() // attach this action to your wmb block

{

       // the block will be replaced when the player clicks it using the left mouse button

       // you can replace the block when it is shot, etc.

       my.emask |= ENABLE_CLICK;

       my.event = replace_block;

}

 

 

Q: When I move the player with its face close to a wall (a BSP block) I'd like to check the wall texture and if its name is "steel", I'd like the player to turn its back against the wall automatically. How can I do that?

A: Use this snippet.

 

action players_code() // attach this action to your player

{

       var movement_speed = 20; // movement speed

       VECTOR temp, players_sensor;

       set (my, INVISIBLE); // 1st person player

       player = my; // I'm the player

       while (1)

       {

               my.pan -= 7 * mouse_force.x * time_step;

               camera.x = my.x;

               camera.y = my.y;

               camera.z = my.z + 50 + 1.1 * sin(my.skill44); // play with 50 and 1.1

               camera.pan = my.pan;

               camera.tilt = player.tilt;

               vec_set (temp.x, my.x); // trace 10,000 quants below the player

               temp.z -= 10000;

               temp.z = -c_trace (my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - 2; // play with 2

               temp.x = movement_speed * (key_w - key_s) * time_step;

               temp.y = movement_speed * (key_a - key_d) * 0.6 * time_step;

               c_move (my, temp.x, nullvector, IGNORE_PASSABLE | GLIDE);

 

               // place the sensor at x = 50, y = 0, z = 0 in relation to the origin of the player model

               vec_set (players_sensor.x, vector(50, 0, 0));

               vec_rotate (players_sensor.x, my.pan);

               vec_add (players_sensor.x, my.x);

 

               if (c_trace (my.x, players_sensor.x, IGNORE_ME | IGNORE_PASSABLE | SCAN_TEXTURE) > 0) // something was hit?

               {

                       if (str_cmpi(tex_name, "steel") == 1) // detected the steel texture?

                               vec_to_angle(my.pan, normal); // then rotate the player according to the normal of the surface!

               }

               wait (1);

       }

}

 

TEXT* message_txt =

{

       pos_x = 200;

       pos_y = 20;

       string(tex_name);

       flags = SHOW;

}