Wolf Planet Forum Index Wolf Planet
We want you here!
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[Tutorial]Extra Ammo Types

 
Post new topic   Reply to topic    Wolf Planet Forum Index -> Coding Alliance
View previous topic :: View next topic  
Author Message
Deathshead
Corporal


Joined: 18 Feb 2005
Posts: 87

PostPosted: Wed Apr 06, 2005 11:32 am    Post subject: [Tutorial]Extra Ammo Types Reply with quote

I have seen countless requests for tutorials for different ammo types, and although BrotherTank and Paal has released one, I think many people are thrown off by the screen dumps and extra code (as in BT's WWW tutorial). Here is my code for Seperate Ammo. It seems a bit unnecessary to do the first part, but I find this makes the code easier to edit. In this tutorial, I present code for pistol, chaingun, and machinegun ammo, and extra code should you want to add more weapons with seperate ammo.

First, open WL_DEF.H and search for 'ammo':

Code:

#define STARTAMMO      8


Change it to look like:

Code:

#define STARTAMMO      8
#define STARTAMMO2      0
#define STARTAMMO3      0
//#define STARTAMMO4      0
//#define STARTAMMO5      0
//#define STARTAMMO6      0


Once again, search for 'ammo'. Your code should look something like:

Code:

typedef   struct
{
   byte         difficulty;
   byte         mapon,oldmap;
   long      oldscore,score,nextextra;
   char         lives;
   int         health;
   byte         count;
   char         ammo:
   char         keys;
   char         guardweapon;
   weapontype      bestweapon,weapon,chosenweapon;

   char         faceframe;
   int         attackframe,attackcount,weaponframe;

   char         episode,secretcount,treasurecount,killcount,
            secrettotal,treasuretotal,killtotal;
   long      TimeCount;
   long      killx,killy;
   boolean      victoryflag;      // set during victory animations
} gametype;


Delete the 'char ammo' line, and underneath the entire structure add:

Code:

//--------------
//
// ammo structure
//
//--------------

typedef struct
{
   char         ammo1;
   char         ammo2;
   char         ammo3;
//   char         ammo4;
//   char         ammo5;
//   char         ammo6;
} ammo_t;


Next, search for 'gamestate'. Your hit should look like:

Code:

extern   gametype   gamestate;


Add the following line underneath:

Code:

extern   ammo_t      ammotype;


Now, go through the WL_****.C files, and change all occurances of gamestate.ammo into ammotype.ammo1.

That might have seemed unnecessary, and if you don't want to do that last bit, just add the ammo variables into the gamestate structure. I did this because it made the code easier to edit.

Now, open WL_MAIN.C and find the NewGame function:

Code:

void NewGame (int difficulty,int episode)
{
   memset (&gamestate,0,sizeof(gamestate));
   gamestate.difficulty = difficulty;
   gamestate.weapon = gamestate.bestweapon = gamestate.chosenweapon = wp_pistol;
   gamestate.health = 100;
   ammotype.ammo1 = STARTAMMO;
   gamestate.lives = 3;
   gamestate.nextextra = EXTRAPOINTS;
   gamestate.episode=episode;
   startgame = true;
}


Add the following lines underneath the ammotype.ammo1 line:

Code:

   ammotype.ammo2 = STARTAMMO2;
   ammotype.ammo3 = STARTAMMO3;
   //ammotype.ammo4 = STARTAMMO4;
   //ammotype.ammo5 = STARTAMMO5;
   //ammotype.ammo6 = STARTAMMO6;


And do the same thing in the Died function. That bit of code decides how much ammo for each weapon at the beginning of the game and after you die.

Now, onto WL_AGENT.C, where all the weapon action occurs. Replace the CheckWeaponChange function with:

Code:

/*==
==== CheckWeaponChange/ChkAtkAmmo
==== Editted by BrotherTank
====
==== Number Keys 1-10 select Weapon.
==== ChkAtkAmmo checks to see if player
==== has any ammo for the weapon, if not,
==== switch to knife.
==*/

// Checks to make sure you have ammo for weapon
// returns "true" if yes and "false" if no
int ChkAtkAmmo (int weapon)
{
   switch (weapon)
   {   
      case wp_knife: return 1;
      case wp_pistol:
           if (ammotype.ammo1 > 0 ) return 1;
      case wp_machinegun:
           if (ammotype.ammo2 > 0 ) return 1;
      case wp_chaingun:
           if (ammotype.ammo3 > 0 ) return 1;
         break;
   }
   return 0;
}

void CheckWeaponChange (void)
{
   int   i,kbuttons[10]={sc_1,sc_2,sc_3,sc_4,sc_5,sc_6,sc_7,sc_8,sc_9,sc_0};

   for (i=0;i<NUMWEAPONS;i++)
      if ((Keyboard[kbuttons[i]]) && (i != gamestate.weapon))
      {
         if (buttonstate[bt_readyknife+i-wp_knife])
         {
             gamestate.weapon = gamestate.chosenweapon = i;
              DrawWeapon ();
              DrawAmmo ();
              return;
          }
      }
}


ChkAtkAmmo checks to see if you have any ammo for a weapon. If yes, it returns true, if no, it returns false. Now, scroll down to the GiveWeapon function. Make it look like:

Code:

/*==
==== GiveWeapon
==== Editted by BrotherTank/Deathshead
====
==== Gives Player a weapon, with 6 ammo for that
==== weapon.
==*/

void GiveWeapon (int weapon)
{
   switch (weapon)
   {
   case wp_pistol:
         GiveAmmo (wp_pistol,6);
      break;
   case wp_machinegun:
      GiveAmmo (wp_machinegun,6);
      break;
   case wp_chaingun:
      GiveAmmo (wp_chaingun,6);
      break;
   }   

   if (gamestate.bestweapon<weapon)
      gamestate.bestweapon = gamestate.weapon = gamestate.chosenweapon = weapon;
   DrawWeapon ();
   DrawAmmo ();
}


You will notice the extra parameters called in GiveAmmo. This will be explained in a second. Now, replace the DrawAmmo routine with this variation:

Code:

/*==
==== DrawAmmo
==== Editted by Deathshead
====
==== This is another variation of the original DrawAmmo
==== routine. For each weapon, the ammo variable becomes
==== the amount of ammo for the weapon. It then displays
==== the ammo onn te statusbar
==*/

void   DrawAmmo (void)
{
   char   ammo;

   switch (gamestate.weapon)
   {
      case wp_knife:
         ammo=0;
         break;
      case wp_pistol:
         ammo = ammotype.ammo1;
         break;
      case wp_machinegun:
         ammo = ammotype.ammo2;
         break;
      case wp_chaingun:
         ammo = ammotype.ammo3;
         break;
   }
   LatchNumber (27,16,3,ammo);
}


This checks what ammo the weapon uses, then displays that amount on the statusbar. Now for the GiveAmmo routine. This is BrotherTanks version, which allows for multiple ammotypes and weapons. Examine it, and you will understand:

Code:

/*==
==== GiveAmmo
==== Editted by BrotherTank/Deathshead
====
==== This variation of GiveAmmo, will give
==== the player ammo for a weapon
==*/

void   GiveAmmo (int weapon,char ammo)
{
     if (!ammotype.ammo1 && !ammotype.ammo2 && !ammotype.ammo3)   // knife was out
     {
    if (!gamestate.attackframe)
    {
      gamestate.weapon = gamestate.chosenweapon;
      DrawWeapon ();
    }
     }
     switch (weapon)
     {
         case wp_pistol:
            ammotype.ammo1 += ammo;
      if (ammotype.ammo1 > 50) ammotype.ammo1 = 50;
      break;
    case wp_machinegun:
      ammotype.ammo2 += ammo;
      if (ammotype.ammo2 > 100) ammotype.ammo2 = 100;
      break;
    case wp_chaingun:
      ammotype.ammo3 += ammo;
      if (ammotype.ammo3 > 200) ammotype.ammo3 = 200;
      break;
     }
     DrawAmmo ();
}


For that function to work though, you have to go back to the top of the file and change:

Code:

void   GiveAmmo (int ammo);


to:

Code:

void   GiveAmmo (int weapon,char ammo);


And do the same thing in WL_DEF.H . Now change all occurances of:

[code]
GiveAmmo (Number);
[code]

to Read:

[code]
GiveAmmo (wp_pistol,Number);
[/code]

Where Number is how much ammo is given. Now go down to the T_Attack function. Look for the following slabs of code and change accordingly:

[code]
case -1:
ob->state = &s_player;
if (!ammotype.ammo1)
{
gamestate.weapon = wp_knife;
DrawWeapon ();
}
else
{
if (gamestate.weapon != gamestate.chosenweapon)
{
gamestate.weapon = gamestate.chosenweapon;
DrawWeapon ();
}
};
gamestate.attackframe = gamestate.weaponframe = 0;
return;
[/code]

to:

[code]
case -1:
ob->state = &s_player;

if (!ChkAtkAmmo (gamestate.weapon) && gamestate.chosenweapon != wp_knife)
{
gamestate.weapon = wp_knife;
for (i=wp_pistol; i<NUMWEAPONS; i++)
{
if (ChkAtkAmmo (i) && gamestate.bestweapon >= i)
{
gamestate.weapon = i;
}
}
DrawWeapon ();
DrawAmmo ();
}
else
{
if (gamestate.weapon != gamestate.chosenweapon)
{
if (ChkAtkAmmo(gamestate.chosenweapon))
gamestate.weapon = gamestate.chosenweapon;
DrawWeapon ();
}
}
gamestate.attackframe = gamestate.weaponframe = 0;
return;
[/code]


[code]
case 4:
if (!ammotype.ammo1)
break;
if (buttonstate[bt_attack])
gamestate.attackframe -= 2;
[/code]

to:

[code]
case 4: // Chaingun - Fall back 2 frames and fire again if button Pressed
if (!ChkAtkAmmo(gamestate.weapon)) break;
if (buttonstate[bt_attack]) gamestate.attackframe -= 2;
[/code]


[code]
case 1:
if (!gamestate.ammo)
{ // can only happen with chain gun
gamestate.attackframe++;
break;
}
GunAttack (ob);
ammotype.ammo1--;
DrawAmmo ();
break;
[/code]

to:

[code]
case 1:
if (!ChkAtkAmmo(wp_chaingun) && gamestate.weapon == wp_chaingun)
{ gamestate.attackframe++; break; }

if (ChkAtkAmmo(gamestate.weapon))
{
GunAttack (ob);

switch (gamestate.weapon)
{
case wp_pistol:
ammotype.ammo1--;
break;
case wp_machinegun:
ammotype.ammo2--;
break;
case wp_chaingun:
ammotype.ammo3--;
break;
}
DrawAmmo ();
break;
}
else
{ return; }
[/code]


[code]
case 3:
if (ammotype.ammo2 && buttonstate[bt_attack])
gamestate.attackframe -= 2;
break;
[/code]

to:

[code]
case 3:
if (ChkAtkAmmo(gamestate.weapon) && buttonstate[bt_attack])
gamestate.attackframe -= 2;
break;
[/code]

That concludes my tutorial. Please tell me if there are problems, as this is almost directly from my source.

If you use this, please include me and BrotherTank in your credits, and send me an email at deathshead.frozenfire@gmail.com , as I would like to see your project!

There you go
-Deathshead
_________________
Myspace
VampireFreaks
Music4Life
Wolfing Time
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Flamer46
Newbie


Joined: 16 Feb 2005
Posts: 25
Location: Italy

PostPosted: Wed Apr 06, 2005 4:04 pm    Post subject: Reply with quote

Why did you add a new struct in WL_DEF.h? It`s a waste of memory. I know that idea has been around for some time but why do it? I did multiple ammo`s for Operation supernatural in a lot easier way.
_________________
Join my forum at
[url]wolfingdays.exoboards.com[/url]
and visit my site at
www.wolfer.co.nr
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Deathshead
Corporal


Joined: 18 Feb 2005
Posts: 87

PostPosted: Thu Apr 07, 2005 9:01 am    Post subject: Reply with quote

Because, looking for 'ammotype' is alot easier for me. It doesn't take up too much, and what I do later saves that memory, and more. Also, I said you can skip that step and just add it in gamestate if you can't be bothered. It's up to you. OK?
_________________
Myspace
VampireFreaks
Music4Life
Wolfing Time
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Wolf Planet Forum Index -> Coding Alliance All times are GMT
Page 1 of 1

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001 phpBB Group

Chronicles phpBB2 theme by Jakob Persson (http://www.eddingschronicles.com). Stone textures by Patty Herford.