Questions from the forum (COPY)

Top  Previous  Next

Q: How can I make an entity that can be picked up appear near the player, in an area that can range from -1000 to +1000 quants around the player on the x and y axis and at z = 0?

A: Here's an example:

 

VECTOR ammo_coords;

 

SOUND gotammo_wav = "gotammo.wav";

 

function ammo_code()

{

       set (my, PASSABLE);

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

       while (vec_dist (player.x, my.x) > 100)

       {

               my.pan += 3 * time_step;

               wait (1);

       }

       wait (-1);

       ent_remove (my);

}

 

function ammo_pack() // attach this action to your ammo pack models

{

       ammo_coords.x = player.x - 1000 + random(2000);

       ammo_coords.y = player.y - 1000 + random(2000);

       ammo_coords.z = 0;

       ent_create("ammo.mdl", ammo_coords, ammo_code);

}

 

function ammo_startup()

{

       // generate an ammo pack each time the player presses the p key

       on_p = ammo_pack;        

}

 

 

Q: How can I create a drawbridge? In the game, when the player clicks a switch, the drawbridge should be lowered.

A: Create your drawbridge as a wmb entity. Use another entity (wmb, model, etc) for the switch and the code below.

 

BMAP* pointer_tga = "pointer.tga";

 

ENTITY* bridge; // entity pointer to the drawbridge entity

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

function click_event()

{

       if (event_type == EVENT_CLICK)

       {

               while (bridge.tilt > 0)

               {

                       bridge.tilt -= 5 * time_step; // 5 = bridge lowering speed

                       wait (1);

               }

       }

}

 

 

// attach this action to your switch entity

action my_switch()

{

       my.emask |= ENABLE_CLICK;

       my.event = click_event;

}

 

// attach this action to your drawbridge entity

action drawbridge()

{

       bridge = me; // I'm the drawbridge

}

 

 

Q: How do I set up the path patrolling direction in Wed?

A: Select your path (1). Then, choose "Vertex Move" (2). Right click the desired edge (3). Choose the desired direction (4). All the steps are detailed in the image below.

 

aum116_faq1

 

 

 

Q: I have a dragon model, and I am trying to create a fireball entity breathe out of its mouth and move toward the player.

A: Here's a piece of code that does the job.

 

BMAP* fire_tga = "fire.tga";

 

STRING* fireball_mdl = "fireball.mdl";

 

VECTOR fireball_coords, temp;

 

SOUND* fireball_wav = "fireball.wav";

SOUND* destroyed_wav = "destroyed.wav";

 

function shoot_fireball();

function remove_fireball();

function fade_fire(PARTICLE *p);

function fire_effect(PARTICLE *p);

 

function shoot_fireball()

{

       VECTOR fireball_speed, temp;

       my.emask |= (ENABLE_ENTITY | ENABLE_BLOCK);

       my.event = remove_fireball;

       my.pan = you.pan;

       my.tilt = you.tilt;

       vec_set(fireball_speed.x, nullvector);

       fireball_speed.x = 50 * time_step;

       while (1)

       {

               effect(fire_effect, 10, my.x, nullvector);               

               c_move (my, fireball_speed.x, nullvector, IGNORE_FLAG2 | IGNORE_PASSABLE);

               wait (1);

       }

}

 

function remove_fireball()

{

       wait (1);

       my.event = NULL;

       ent_playsound (my, destroyed_wav, 1000); // play the explosion sound

       set (my, INVISIBLE); // hide the fireball, keep ent_playsound playing

       wait (-1.5); // wait for 1.5 seconds

       ent_remove(me); // now remove it

}

 

function fade_fire(PARTICLE *p)

{

       p.alpha -= 4 * time_step; // fade out the fire particles

       if (p.alpha < 0)

               p.lifespan = 0;

}

 

function fire_effect(PARTICLE *p)

{

       set (my, PASSABLE);

       p->vel_x = 1 - random(2);

       p->vel_y = 1 - random(2);

       p->vel_z = 3 - random(6);

       p.alpha = 20 + random(50);

       p.bmap = fire_tga;

       p.size = 10 + random(5); // gives the size of the flame particles

       p.flags |= (BRIGHT | MOVE);

       p.event = fade_fire;

}

 

action my_dragon() // attach this action to your dragon model

{         

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

       while (1) // rotates towards the player at all times

       {

               vec_set(temp, player.x);

               vec_sub(temp, my.x);

               vec_to_angle(my.pan, temp);

               my.tilt = 0;

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

               {

                       if (total_frames % 255 == 1) // play with 255

                       {

                               vec_set(fireball_coords.x, vector(50, -7, 14)); // play with these values

                               vec_rotate(fireball_coords.x, my.pan);

                               vec_add(fireball_coords.x, my.x);

                               ent_create (fireball_mdl, fireball_coords, shoot_fireball);

                               snd_play (fireball_wav, 50, 0);

                       }        

               }

               wait (1);

       }

}

 

 

Q: How can I create an on-screen keyboard with keys that can be clicked using the left mouse button?

A: Use panel buttons for your keyboard, or simply verify the (x,y) coordinates of each key and trigger an event when certain conditions are met. Here's a code snippet that tracks the WSAD keys using the keyboard bitmap below.

 

keyboard

 

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);

       }

}

 

PANEL* keyboard_pan =

{

       bmap = "keyboard.png";

       pos_x = 0;

       pos_y = 0;

       flags = SHOW;

       on_click = check_coords;

}

 

function check_coords()

{

       if ((mouse_pos.y > 95) && (mouse_pos.y < 127)) // the cursor is placed on the 3rd row of keys (Tab, Q, W, E, R, etc)

       {

               if ((mouse_pos.x > 118) && (mouse_pos.x < 146)) // the cursor is placed on the W key

               {

                       printf ("Key W has been pressed!");

               }

       }

       if ((mouse_pos.y > 140) && (mouse_pos.y < 168)) // the cursor is placed on the 4th row of keys (Caps Lock, A, S, D, etc)

       {

               if ((mouse_pos.x > 88) && (mouse_pos.x < 115)) // the cursor is placed on the A key

               {

                       printf ("Key A has been pressed!");

               }

               if ((mouse_pos.x > 130) && (mouse_pos.x < 158)) // the cursor is placed on the S key

               {

                       printf ("Key S has been pressed!");

               }

               if ((mouse_pos.x > 173) && (mouse_pos.x < 200)) // the cursor is placed on the D key

               {

                       printf ("Key D has been pressed!");

               }

       }

}

 

 

Q: Does anyone have the code for a combo animation?

A: Here's a snippet:

 

// Use the "A" and "S" keys to run the kick_left and kick_right animations

// Press "A" quickly, and then "S" to run the death animation

action my_ninja()

{

       var combo_running = 0;

       var anim_factor;

       while (1)

       {

               if (key_a) // kick left

               {

                       anim_factor = 0;

                       while (anim_factor < 97)

                       {

                               // the player has pressed the "S" key right after pressing the "A" key?

                               if ((anim_factor < 15) && (key_d)) // play with 15, it gives the combo trigger sensitivity

                               {

                                       combo_running = 1;

                                       break; // get out of this loop and let's run the combo animation

                               }

                               else // the normal kick_left animation is continued (no combos this time)

                               {

                                       anim_factor += 5 * time_step;

                                       ent_animate(my, "kick_left", anim_factor, ANM_CYCLE);

                               }

                               wait (1);

                       }

                       if (combo_running == 1)

                       {

                               anim_factor = 0;

                               while (anim_factor < 97)

                               {

                                       anim_factor += 1 * time_step;

                                       ent_animate(my, "death", anim_factor, ANM_CYCLE);

                               }

                               combo_running = 0;

                       }

               }

               else

               {

                       if (key_d)

                       {

                               anim_factor = 0;

                               while (anim_factor < 97)

                               {

                                       anim_factor += 5 * time_step;

                                       ent_animate(my, "kick_right", anim_factor, ANM_CYCLE);

                                       wait (1);

                               }

                       }

               }                        

               wait (1);

       }

}

 

 

Q: I want to make a flying rocket that is generated from a fixed launcher every five seconds and hits a wall in front of it, exploding on impact.
A: Here's an example.

 

BMAP* fire_tga = "fire.tga";

 

STRING* rocket_mdl = "rocket.mdl";

 

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

 

VECTOR rocket_coords, temp;

 

SOUND* rocket_wav = "rocket.wav";

SOUND* destroyed_wav = "destroyed.wav";

 

function shoot_rocket();

function remove_rocket();

function fade_fire(PARTICLE *p);

function fire_effect(PARTICLE *p);

 

function shoot_rocket()

{

       VECTOR rocket_speed, temp;

       my.emask |= (ENABLE_ENTITY | ENABLE_BLOCK);

       my.event = remove_rocket;

       my.pan = you.pan;

       my.tilt = you.tilt;

       vec_set(rocket_speed.x, nullvector);

       rocket_speed.x = 50 * time_step;

       while (1)

       {

               effect(fire_effect, 10, my.x, nullvector);               

               c_move (my, rocket_speed.x, nullvector, IGNORE_FLAG2 | IGNORE_PASSABLE);

               wait (1);

       }

}

 

function explosion_sprite()

{

       set (my, PASSABLE | BRIGHT | TRANSLUCENT);

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

       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 += 0.5 * 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);

}

 

function remove_rocket()

{

       wait (1);

       my.event = NULL;

       ent_playsound (my, destroyed_wav, 1000); // play the explosion sound

       set (my, INVISIBLE); // hide the rocket, keep ent_playsound playing

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

       wait (-1); // wait for 1 second

       ent_remove(me); // now remove it

}

 

function fade_fire(PARTICLE *p)

{

       p.alpha -= 4 * time_step; // fade out the fire particles

       if (p.alpha < 0)

               p.lifespan = 0;

}

 

function fire_effect(PARTICLE *p)

{

       set (my, PASSABLE);

       p->vel_x = 1 - random(2);

       p->vel_y = 1 - random(2);

       p->vel_z = 3 - random(6);

       p.alpha = 20 + random(50);

       p.bmap = fire_tga;

       p.size = 10 + random(5); // gives the size of the flame particles

       p.flags |= (BRIGHT | MOVE);

       p.event = fade_fire;

}

 

action cannon() // attach this action to your cannon

{         

       while (1)

       {

               // generate the rocket 50 quants in front of the player

               vec_set(rocket_coords.x, vector(50, 0, 0)); // play with these values

               vec_rotate(rocket_coords.x, my.pan);

               vec_add(rocket_coords.x, my.x);

               ent_create (rocket_mdl, rocket_coords, shoot_rocket);

               snd_play (rocket_wav, 50, 0);

               wait(-5);

               wait (1);

       }

}

 

 

Q: I am trying to create a panel with a button. When the button is clicked, it should display an image inside the panel's frame. The image should disappear when you click it.

A: There you go:

 

BMAP* pointer_tga = "pointer.tga";

 

BMAP* pictureon_pcx = "pictureon.pcx";

BMAP* pictureoff_pcx = "pictureoff.pcx";

 

function show_photo();

function hide_photo();

 

PANEL* frame_pan = // that's your photo frame panel

{

       bmap = "frame.pcx";

       layer = 15;

       button(20, 20, pictureon_pcx, pictureoff_pcx, pictureon_pcx, show_photo, NULL, NULL);

       flags = SHOW;

}

 

PANEL* photo_pan = // that's your photo panel

{

       bmap = "photo.pcx";

       layer = 20; // has a higher layer value in comparison with the frame panel

       on_click = hide_photo;

}

 

function show_photo()

{

       set(photo_pan, SHOW);

}

 

function hide_photo()

{

       reset(photo_pan, SHOW);

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}

 

 

Q: How can I make my NPC open a door? I have a hard time trying to make it do that.

A: Use c_scan to open the door when the NPC approaches it; here's an example.

 

var door_scanned = 0;

 

action my_npc() // attach this action to the NPC entity

{

       var anim_percentage;

       while (1)

       {

               // use your own movement code here

               c_move (my, vector(3 * time_step, 0, 0), nullvector, GLIDE); // "3" controls the walking speed

               my.pan += 2 * time_step; // this line makes the entity walk in a circle, 2 sets the radius

               ent_animate(my, "walk", anim_percentage, ANM_CYCLE);

               anim_percentage += 4 * time_step; // "4" controls the "walk" animation speed

               wait (1);

       }

}

 

action my_door()

{

       VECTOR temp[3];

       while (1)

       {

               // scan for the NPC every 20 frames

               // the NPC will be detected if it comes closer than 200 quants to the door

               c_scan(my.x, my.pan, vector(360, 90, 200), IGNORE_ME | SCAN_ENTS); // play with 200

            if (you) // an entity has been detected?

               {

                       while (my.z < 200) // 200 sets the height of the opened door

                       {

                               my.z += 3 * time_step;

                               wait (1);

                       }

               }

               else

               {

                       while (my.z > 0)

                       {

                               my.z -= 8 * time_step;

                               wait (1);                        

                       }

               }

               wait (20);

       }

}

 

 

Q: The player clicks the "create new character" button and you have to enter its name, which is then saved to a file on the hard drive. How do I do that?

A: Here's exactly what you need:

 

BMAP* pictureon_pcx = "pictureon.pcx";

BMAP* pictureoff_pcx = "pictureoff.pcx";

 

BMAP* pointer_tga = "pointer.tga";

 

STRING* name_str = "#30"; // store up to 30 characters

 

function input_player();

 

PANEL* player_pan =

{

       bmap = "main.pcx";

       layer = 15;

       button(20, 20, pictureon_pcx, pictureoff_pcx, pictureon_pcx, input_player, NULL, NULL);

       flags = SHOW;

}

 

TEXT* player_name_txt =

{

       pos_x = 10;

       pos_y = 50;

       string(name_str);

       flags = SHOW;

}

 

function input_player()

{

       var filehandle;

       str_cpy (name_str, "Input Player's Name, Please!");

       wait (-3);

       str_cpy(name_str, "                           "); // reset the input string

       inkey(name_str); // now let's input the name

       filehandle = file_open_write("player.txt"); // opens / overwrites the existing player.txt file (if any)

       file_str_write(filehandle, name_str); // write player's name

       file_close(filehandle);

}

 

function mouse_startup()

       mouse_mode = 2;

       mouse_map = pointer_tga;

       while (1)

       

               vec_set(mouse_pos, mouse_cursor);

               wait(1);

       }

}