Beginner's corner

Top  Previous  Next

Cheat codes

This time I'm going to show you how to add cheat codes to your game. I have implemented cheats for health and armor but you can add as many cheats as you want.

First of all we define a few strings; if you take a look at the definitions below you will see that we have an empty string, a string that will store the user input, another one that will display "Unknown command" if we type something that isn't recognized and two strings that contain the cheat codes for health and armor.

string empty_str = "                   ";
string cheat_str = "                   ";
string unknown_str = "Unknown command";
string health_str = "gimmehealth";
string armor_str = "gimmearmor";

We define two texts; one of them will be used for the cheats and the other one for the "Unknown command" message.

text cheats_txt
{
   pos_x = 0;
   pos_y = 0;
   layer = 20;
   font = standard_font;
   string = cheat_str;
}

text unknown_txt
{
   pos_x = 0;
   pos_y = 0;
   layer = 20;
   font = standard_font;
   string = unknown_str;
}

The function below is called in main so it will be executed at game start:

function init_cheats()
{
   player._health = 30;
   while (1)
   {
       if (key_alt + key_p == 2)
       {
           cheats_txt.visible = on;
           str_cpy (cheat_str, empty_str);
           inkey cheat_str;
           if ((player != null) && (str_cmpi (cheat_str, health_str) == 1))
           {
               player._health = 100;
           }
          if ((player != null) && (str_cmpi (cheat_str, armor_str) == 1))
          {
              player._armor = 100;
          }
          if (str_cmpi (cheat_str, health_str) + str_cmpi (cheat_str, armor_str) == 0)
         {
             unknown_txt.pos_x = screen_size.x / 2;
             unknown_txt.pos_y = screen_size.y / 2;
             unknown_txt.visible = on;
             beep;
             waitt (32);
             unknown_txt.visible = off;
         }
        cheats_txt.visible = off;
     }
    wait (1);
  }
}

We are setting player's health to 30 because we want to see it recovering :) when we type "gimmehealth". The cheats (passwords, if you like) can be typed in if we press Alt + P. If this happens, we show cheats_txt, we clear previous inputs and we show the cursor; as soon as we type Enter, the input is stored in cheat_str.

If the player exists (it could be removed from the level) and cheat_str = health_str, the player will get 100 health points; if cheat_str = armor_str the player will get 100 armor points. I am using str_cmpi which compares the strings without case sensitivity so GimmEHeAltH will work ok.

If we type something wrong (or we don't know the cheat codes) unknown_txt is placed near the middle of the screen and made visible for two seconds, then cheats_txt will also disappear. You can add as many cheats as you want by simply adding their strings and checking:

if ((player != null) && (str_cmpi (cheat_str, yourcheat_str) == 1))
{
   your_cheat_here;
}

Intelligent rain

We love particles, don't we? They look cool and they're so fast! The bad news is that they can't collide with anything - that's why they're so fast. What happens if you want to have rain or snow only outside the house? You could use several particle generators (and small ranges) carefully placed around the house or you could use the intelligent rain code presented below.

The idea is pretty simple: we don't use particles, but sprites and we check to see if they are penetrating something solid. If this is true, the drops stop. Let's take a look at the action that generates the rain drops:

define area_x skill1;
define area_y skill2;
define speed skill3;
define number_of_drops skill4;

action rain_maker
{
  rain_ptr = me;
  my.invisible = on;
  my.passable = on;
  if (my.skill1 + my.skill2 + my.skill3 + my.skill4 == 0) 
  {
      my.area_x = 1000;
      my.area_y = 1000; 
      my.speed = 20; 
      my.number_of_drops = 300; 
  }
  while (my.skill5 < my.number_of_drops)
  {
      temp.x = my.x + my.area_x / 2 - random(my.area_x);
      temp.y = my.y + my.area_y / 2 - random(my.area_y);
      temp.z = my.z;
      ent_create(rain_pcx, temp, create_drops);
      my.skill5 += 1;
      wait (1);
   }
}

You can attach the rain_maker action to any entity because it will be made invisible and passable. I have set some decent names for skills1..4: the raining area on x and y (related to the rain_maker entity), the drop speed and the number of rain drops. If we forget to set these skills in Wed, their sum is zero so the code switches to defaults: 1000 quants on x and y, speed = 20 and 300 rain drops.

Temp stores a random position in a rectangular area set by area_x and area_y; a new drop sprite will be created at this position. Skill5 is increased with every drop so the while loop will continue to run until all the drops are created. The function that runs for every drop is:

function create_drops()
{
   my.scale_x /= 2;
   my.transparent = on;
   my.passable = on;
   my.flare = on;
   while (1)
   {
       my.z -= (random(rain_ptr.speed) + rain_ptr.speed) * time;
       if (content(my.x) == content_solid)
       {
           my.z = rain_ptr.z;
       }
       wait (1);
   }
}

You can use any sprite but it can't have a width below one pixel. I think that a pixel is a little too thick when you are close to the drop so the first line halves the width of the sprite. The drop is transparent, passable and has its flare flag set. The sprite moves in a while (1) loop by changing its z. I'm using a random value so different drops have slightly different speeds.

If the drop hits a brush (a ceiling, etc) its content will be content_solid; the drop will be moved up (we won't be able to notice anything) and we will let it fall again. This way we don't have to create all the drops again and again and we will get a frame rate increase.

Make sure that you don't use thousands of sprites for your rain drops and don't forget to increase the nexus as you add more particles. If you plan to use 400 rain drops your nexus needs to be at least 50.

If some of your drops penetrate the ceiling (this happens with some of the drops in the office level) you can make the ceiling thicker, the drops smaller or you could decrease the drop speed.