home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / weapon.c < prev    next >
Text File  |  1998-06-08  |  19KB  |  587 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/main/rcs/weapon.c $
  15.  * $Revision: 2.1 $
  16.  * $Author: john $
  17.  * $Date: 1995/03/21 14:38:43 $
  18.  * 
  19.  * Functions for weapons...
  20.  * 
  21.  * $Log: weapon.c $
  22.  * Revision 2.1  1995/03/21  14:38:43  john
  23.  * Ifdef'd out the NETWORK code.
  24.  * 
  25.  * Revision 2.0  1995/02/27  11:27:25  john
  26.  * New version 2.0, which has no anonymous unions, builds with
  27.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  28.  * 
  29.  * Revision 1.54  1995/02/15  15:21:48  mike
  30.  * make smart missile select if mega missiles used up.
  31.  * 
  32.  * 
  33.  * Revision 1.53  1995/02/12  02:12:30  john
  34.  * Fixed bug with state restore making weapon beeps.
  35.  * 
  36.  * Revision 1.52  1995/02/09  20:42:15  mike
  37.  * change weapon autoselect, always autoselect smart, mega.
  38.  * 
  39.  * Revision 1.51  1995/02/07  20:44:26  mike
  40.  * autoselect mega, smart when you pick them up.
  41.  * 
  42.  * Revision 1.50  1995/02/07  13:32:25  rob
  43.  * Added include of multi.h
  44.  * 
  45.  * Revision 1.49  1995/02/07  13:21:33  yuan
  46.  * Fixed 2nd typo
  47.  * 
  48.  * Revision 1.48  1995/02/07  13:16:39  yuan
  49.  * Fixed typo.
  50.  * 
  51.  * Revision 1.47  1995/02/07  12:53:12  rob
  52.  * Added network sound prop. to weapon switch.
  53.  * 
  54.  * Revision 1.46  1995/02/06  15:53:17  mike
  55.  * don't autoselect smart or mega missile when you pick it up.
  56.  * 
  57.  * Revision 1.45  1995/02/02  21:43:34  mike
  58.  * make autoselection better.
  59.  * 
  60.  * Revision 1.44  1995/02/02  16:27:21  mike
  61.  * make concussion missiles trade up.
  62.  * 
  63.  * Revision 1.43  1995/02/01  23:34:57  adam
  64.  * messed with weapon change sounds
  65.  * 
  66.  * Revision 1.42  1995/02/01  17:12:47  mike
  67.  * Make smart missile, mega missile not auto-select.
  68.  * 
  69.  * Revision 1.41  1995/02/01  15:50:54  mike
  70.  * fix bogus weapon selection sound code.
  71.  * 
  72.  * Revision 1.40  1995/01/31  16:16:31  mike
  73.  * Separate smart blobs for robot and player.
  74.  * 
  75.  * Revision 1.39  1995/01/30  21:12:11  mike
  76.  * Use new weapon selection sounds, different for primary and secondary.
  77.  * 
  78.  * Revision 1.38  1995/01/29  13:46:52  mike
  79.  * Don't auto-select fusion cannon when you run out of energy.
  80.  * 
  81.  * Revision 1.37  1995/01/20  11:11:13  allender
  82.  * record weapon changes again.  (John somehow lost my 1.35 changes).
  83.  * 
  84.  * Revision 1.36  1995/01/19  17:00:46  john
  85.  * Made save game work between levels.
  86.  * 
  87.  * Revision 1.34  1995/01/09  17:03:48  mike
  88.  * fix autoselection of weapons.
  89.  * 
  90.  * Revision 1.33  1995/01/05  15:46:31  john
  91.  * Made weapons not rearm when starting a saved game.
  92.  * 
  93.  * Revision 1.32  1995/01/03  12:34:23  mike
  94.  * autoselect next lower weapon if run out of smart or mega missile.
  95.  * 
  96.  * Revision 1.31  1994/12/12  21:39:37  matt
  97.  * Changed vulcan ammo: 10K max, 5K w/weapon, 1250 per powerup
  98.  * 
  99.  * Revision 1.30  1994/12/09  19:55:04  matt
  100.  * Added weapon name in "not available in shareware" message
  101.  * 
  102.  * Revision 1.29  1994/12/06  13:50:24  adam
  103.  * added shareware msg. when choosing 4 top weapons
  104.  * 
  105.  * Revision 1.28  1994/12/02  22:07:13  mike
  106.  * if you gots 19 concussion missiles and you runs over 4, say you picks up 1, not 4, we do the math, see?
  107.  * 
  108.  * Revision 1.27  1994/12/02  20:06:24  matt
  109.  * Made vulcan ammo print at approx 25 times actual
  110.  * 
  111.  * Revision 1.26  1994/12/02  15:05:03  matt
  112.  * Fixed bogus weapon constants and arrays
  113.  * 
  114.  * Revision 1.25  1994/12/02  10:50:34  yuan
  115.  * Localization
  116.  * 
  117.  * Revision 1.24  1994/11/29  15:48:28  matt
  118.  * selecting weapon now makes sound
  119.  * 
  120.  * Revision 1.23  1994/11/28  11:26:58  matt
  121.  * Cleaned up hud message printing for picking up weapons
  122.  * 
  123.  * Revision 1.22  1994/11/27  23:13:39  matt
  124.  * Made changes for new mprintf calling convention
  125.  * 
  126.  * Revision 1.21  1994/11/12  16:38:34  mike
  127.  * clean up default ammo stuff.
  128.  * 
  129.  * Revision 1.20  1994/11/07  17:41:18  mike
  130.  * messages for when you try to fire a weapon you don't have or don't have ammo for.
  131.  * 
  132.  * Revision 1.19  1994/10/21  20:40:05  mike
  133.  * fix double vulcan ammo.
  134.  * 
  135.  * Revision 1.18  1994/10/20  09:49:05  mike
  136.  * kill messages no one liked...*sniff* *sniff*
  137.  * 
  138.  * Revision 1.17  1994/10/19  11:17:07  mike
  139.  * Limit amount of player ammo.
  140.  * 
  141.  * Revision 1.16  1994/10/12  08:04:18  mike
  142.  * Fix proximity/homing confusion.
  143.  * 
  144.  * Revision 1.15  1994/10/11  18:27:58  matt
  145.  * Changed auto selection of secondary weapons
  146.  * 
  147.  * Revision 1.14  1994/10/08  23:37:54  matt
  148.  * Don't pick up weapons you already have; also fixed auto_select bug
  149.  * for seconary weapons
  150.  * 
  151.  * Revision 1.13  1994/10/08  14:55:47  matt
  152.  * Fixed bug that selected vulcan cannon when picked up ammo, even though
  153.  * you didn't have the weapon.
  154.  * 
  155.  * Revision 1.12  1994/10/08  12:50:32  matt
  156.  * Fixed bug that let you select weapons you don't have
  157.  * 
  158.  * Revision 1.11  1994/10/07  23:37:56  matt
  159.  * Made weapons select when pick up better one
  160.  * 
  161.  * Revision 1.10  1994/10/07  16:02:08  matt
  162.  * Fixed problem with weapon auto-select
  163.  * 
  164.  * Revision 1.9  1994/10/05  17:00:20  matt
  165.  * Made player_has_weapon() public and moved constants to header file
  166.  * 
  167.  * Revision 1.8  1994/09/26  11:27:13  mike
  168.  * Fix auto selection of weapon when you run out of ammo.
  169.  * 
  170.  * Revision 1.7  1994/09/13  16:40:45  mike
  171.  * Add rearm delay and missile firing delay.
  172.  * 
  173.  * Revision 1.6  1994/09/13  14:43:12  matt
  174.  * Added cockpit weapon displays
  175.  * 
  176.  * Revision 1.5  1994/09/03  15:23:06  mike
  177.  * Auto select next weaker weapon when one runs out, clean up code.
  178.  * 
  179.  * Revision 1.4  1994/09/02  16:38:19  mike
  180.  * Eliminate a pile of arrays, associate weapon data with Weapon_info.
  181.  * 
  182.  * Revision 1.3  1994/09/02  11:57:10  mike
  183.  * Add a bunch of stuff, I forget what.
  184.  * 
  185.  * Revision 1.2  1994/06/03  16:26:32  john
  186.  * Initial version.
  187.  * 
  188.  * Revision 1.1  1994/06/03  14:40:43  john
  189.  * Initial revision
  190.  * 
  191.  * 
  192.  */
  193.  
  194.  
  195. #pragma off (unreferenced)
  196. static char rcsid[] = "$Id: weapon.c 2.1 1995/03/21 14:38:43 john Exp $";
  197. #pragma on (unreferenced)
  198.  
  199. #include "game.h"
  200. #include "weapon.h"
  201. #include "mono.h"
  202. #include "player.h"
  203. #include "gauges.h"
  204. #include "error.h"
  205. #include "sounds.h"
  206. #include "text.h"
  207. #include "powerup.h"
  208. #include "newdemo.h"
  209. #include "multi.h"
  210.  
  211. //    Note, only Vulcan cannon requires ammo.
  212. //ubyte    Default_primary_ammo_level[MAX_PRIMARY_WEAPONS] = {255, 0, 255, 255, 255};
  213. //ubyte    Default_secondary_ammo_level[MAX_SECONDARY_WEAPONS] = {3, 0, 0, 0, 0};
  214.  
  215. //    Convert primary weapons to indices in Weapon_info array.
  216. ubyte Primary_weapon_to_weapon_info[MAX_PRIMARY_WEAPONS] = {0, 11, 12, 13, 14};
  217. ubyte Secondary_weapon_to_weapon_info[MAX_SECONDARY_WEAPONS] = {8, 15, 16, 17, 18};
  218.  
  219. int Primary_ammo_max[MAX_PRIMARY_WEAPONS] = {0, VULCAN_AMMO_MAX, 0, 0, 0};
  220. ubyte Secondary_ammo_max[MAX_SECONDARY_WEAPONS] = {20, 10, 10, 5, 5};
  221.  
  222. weapon_info Weapon_info[MAX_WEAPON_TYPES];
  223. int    N_weapon_types=0;
  224. byte    Primary_weapon, Secondary_weapon;
  225.  
  226. //char    *Primary_weapon_names[MAX_PRIMARY_WEAPONS] = {
  227. //    "Laser Cannon",
  228. //    "Vulcan Cannon",
  229. //    "Spreadfire Cannon",
  230. //    "Plasma Cannon",
  231. //    "Fusion Cannon"
  232. //};
  233.  
  234. //char    *Secondary_weapon_names[MAX_SECONDARY_WEAPONS] = {
  235. //    "Concussion Missile",
  236. //    "Homing Missile",
  237. //    "Proximity Bomb",
  238. //    "Smart Missile",
  239. //    "Mega Missile"
  240. //};
  241.  
  242. //char    *Primary_weapon_names_short[MAX_PRIMARY_WEAPONS] = {
  243. //    "Laser",
  244. //    "Vulcan",
  245. //    "Spread",
  246. //    "Plasma",
  247. //    "Fusion"
  248. //};
  249.  
  250. //char    *Secondary_weapon_names_short[MAX_SECONDARY_WEAPONS] = {
  251. //    "Concsn\nMissile",
  252. //    "Homing\nMissile",
  253. //    "Proxim.\nBomb",
  254. //    "Smart\nMissile",
  255. //    "Mega\nMissile"
  256. //};
  257.  
  258. //    ------------------------------------------------------------------------------------
  259. //    Return:
  260. // Bits set:
  261. //        HAS_WEAPON_FLAG
  262. //        HAS_ENERGY_FLAG
  263. //        HAS_AMMO_FLAG    
  264. // See weapon.h for bit values
  265. int player_has_weapon(int weapon_num, int secondary_flag)
  266. {
  267.     int    return_value = 0;
  268.     int    weapon_index;
  269.  
  270.     //    Hack! If energy goes negative, you can't fire a weapon that doesn't require energy.
  271.     //    But energy should not go negative (but it does), so find out why it does!
  272.     if (Players[Player_num].energy < 0)
  273.         Players[Player_num].energy = 0;
  274.  
  275.     if (!secondary_flag) {
  276.         weapon_index = Primary_weapon_to_weapon_info[weapon_num];
  277.  
  278.         if (Players[Player_num].primary_weapon_flags & (1 << weapon_num))
  279.             return_value |= HAS_WEAPON_FLAG;
  280.  
  281.         if (Weapon_info[weapon_index].ammo_usage <= Players[Player_num].primary_ammo[weapon_num])
  282.             return_value |= HAS_AMMO_FLAG;
  283.  
  284.         if (Weapon_info[weapon_index].energy_usage <= Players[Player_num].energy)
  285.             return_value |= HAS_ENERGY_FLAG;
  286.  
  287.     } else {
  288.         weapon_index = Secondary_weapon_to_weapon_info[weapon_num];
  289.  
  290.         if (Players[Player_num].secondary_weapon_flags & (1 << weapon_num))
  291.             return_value |= HAS_WEAPON_FLAG;
  292.  
  293.         if (Weapon_info[weapon_index].ammo_usage <= Players[Player_num].secondary_ammo[weapon_num])
  294.             return_value |= HAS_AMMO_FLAG;
  295.  
  296.         if (Weapon_info[weapon_index].energy_usage <= Players[Player_num].energy)
  297.             return_value |= HAS_ENERGY_FLAG;
  298.     }
  299.  
  300.  
  301.     return return_value;
  302. }
  303.  
  304. //    ------------------------------------------------------------------------------------
  305. //if message flag set, print message saying selected
  306. select_weapon(int weapon_num, int secondary_flag, int print_message, int wait_for_rearm)
  307. {
  308.     char    *weapon_name;
  309.  
  310. #ifndef SHAREWARE
  311.     if (Newdemo_state==ND_STATE_RECORDING )
  312.         newdemo_record_player_weapon(secondary_flag, weapon_num);
  313. #endif
  314.  
  315.     if (!secondary_flag) {
  316.         if (Primary_weapon != weapon_num) {
  317.             if (wait_for_rearm) digi_play_sample_once( SOUND_GOOD_SELECTION_PRIMARY, F1_0 );
  318.             #ifdef NETWORK
  319.             if (Game_mode & GM_MULTI)    {
  320.                 if (wait_for_rearm) multi_send_play_sound(SOUND_GOOD_SELECTION_PRIMARY, F1_0);
  321.             }
  322.             #endif
  323.             if (wait_for_rearm)
  324.                 Next_laser_fire_time = GameTime + REARM_TIME;
  325.             else
  326.                 Next_laser_fire_time = 0;
  327.             Global_laser_firing_count = 0;
  328.         } else     {
  329.             if (wait_for_rearm) digi_play_sample( SOUND_ALREADY_SELECTED, F1_0 );
  330.         }
  331.         Primary_weapon = weapon_num;
  332.         weapon_name = PRIMARY_WEAPON_NAMES(weapon_num);
  333.     } else {
  334.  
  335.         if (Secondary_weapon != weapon_num) {
  336.             if (wait_for_rearm) digi_play_sample_once( SOUND_GOOD_SELECTION_SECONDARY, F1_0 );
  337.             #ifdef NETWORK
  338.             if (Game_mode & GM_MULTI)    {
  339.                 if (wait_for_rearm) multi_send_play_sound(SOUND_GOOD_SELECTION_PRIMARY, F1_0);
  340.             }
  341.             #endif
  342.             if (wait_for_rearm)
  343.                 Next_missile_fire_time = GameTime + REARM_TIME;
  344.             else
  345.                 Next_missile_fire_time = 0;
  346.             Global_missile_firing_count = 0;
  347.         } else    {
  348.             if (wait_for_rearm) digi_play_sample_once( SOUND_ALREADY_SELECTED, F1_0 );
  349.         }
  350.         Secondary_weapon = weapon_num;
  351.         weapon_name = SECONDARY_WEAPON_NAMES(weapon_num);
  352.     }
  353.  
  354.     if (print_message)
  355.         HUD_init_message("%s %s", weapon_name, TXT_SELECTED);
  356.  
  357. }
  358.  
  359. //    ------------------------------------------------------------------------------------
  360. //    Select a weapon, primary or secondary.
  361. void do_weapon_select(int weapon_num, int secondary_flag)
  362. {
  363.     int    weapon_status = player_has_weapon(weapon_num, secondary_flag);
  364.     char    *weapon_name;
  365.  
  366.  
  367.     #ifdef SHAREWARE    // do special hud msg. for picking registered weapon in shareware version.
  368.     if (weapon_num >= NUM_SHAREWARE_WEAPONS) {
  369.         weapon_name = secondary_flag?SECONDARY_WEAPON_NAMES(weapon_num):PRIMARY_WEAPON_NAMES(weapon_num);
  370.         HUD_init_message("%s %s!", weapon_name,TXT_NOT_IN_SHAREWARE);
  371.         digi_play_sample( SOUND_BAD_SELECTION, F1_0 );
  372.         return;
  373.     }
  374.     #endif
  375.  
  376.     if (!secondary_flag) {
  377.         weapon_name = PRIMARY_WEAPON_NAMES(weapon_num);
  378.         if ((weapon_status & HAS_WEAPON_FLAG) == 0) {
  379.             HUD_init_message("%s %s!", TXT_DONT_HAVE, weapon_name);
  380.             digi_play_sample( SOUND_BAD_SELECTION, F1_0 );
  381.             return;
  382.         }
  383.         else if ((weapon_status & HAS_AMMO_FLAG) == 0) {
  384.             HUD_init_message("%s %s!", TXT_DONT_HAVE_AMMO, weapon_name);
  385.             digi_play_sample( SOUND_BAD_SELECTION, F1_0 );
  386.             return;
  387.         }
  388.     }
  389.     else {
  390.         weapon_name = SECONDARY_WEAPON_NAMES(weapon_num);
  391.         if (weapon_status != HAS_ALL) {
  392.             HUD_init_message("%s %s%s",TXT_HAVE_NO, weapon_name, TXT_SX);
  393.             digi_play_sample( SOUND_BAD_SELECTION, F1_0 );
  394.             return;
  395.         }
  396.     }
  397.  
  398.     select_weapon(weapon_num, secondary_flag, 1, 1);
  399. }
  400.  
  401. //    ----------------------------------------------------------------------------------------
  402. //    Automatically select next best weapon if unable to fire current weapon.
  403. // Weapon type: 0==primary, 1==secondary
  404. void auto_select_weapon(int weapon_type)
  405. {
  406.     int    r;
  407.  
  408.     if (weapon_type==0) {
  409.         r = player_has_weapon(Primary_weapon, 0);
  410.         if (r != HAS_ALL) {
  411.             int    cur_weapon;
  412.             int    try_again = 1;
  413.     
  414.             cur_weapon = Primary_weapon;
  415.     
  416.             while (try_again) {
  417.                 cur_weapon--;
  418.                 if (cur_weapon < 0)
  419.                     cur_weapon = MAX_PRIMARY_WEAPONS-1;
  420.     
  421.                 //    Hack alert!  Because the fusion uses 0 energy at the end (it's got the weird chargeup)
  422.                 //    it looks like it takes 0 to fire, but it doesn't, so never auto-select.
  423.                 if (cur_weapon == FUSION_INDEX)
  424.                     continue;
  425.  
  426.                 if (cur_weapon == Primary_weapon) {
  427.                     HUD_init_message(TXT_NO_PRIMARY);
  428.                     try_again = 0;                // Tried all weapons!
  429.                     select_weapon(0, 0, 0, 1);
  430.                 } else if (player_has_weapon(cur_weapon, 0) == HAS_ALL) {
  431.                     select_weapon(cur_weapon, 0, 1, 1 );
  432.                     try_again = 0;
  433.                 }
  434.             }
  435.         }
  436.  
  437.     } else {
  438.  
  439.         Assert(weapon_type==1);
  440.  
  441.         if (Secondary_weapon != PROXIMITY_INDEX) {
  442.             if (!(player_has_weapon(Secondary_weapon, 1) == HAS_ALL)) {
  443.                 if (Secondary_weapon > SMART_INDEX)
  444.                     if (player_has_weapon(SMART_INDEX, 1) == HAS_ALL) {
  445.                         select_weapon(SMART_INDEX, 1, 1, 1);
  446.                         goto weapon_selected;
  447.                     }
  448.                 if (player_has_weapon(HOMING_INDEX, 1) == HAS_ALL)
  449.                     select_weapon(HOMING_INDEX, 1, 1, 1);
  450.                 else if (player_has_weapon(CONCUSSION_INDEX, 1) == HAS_ALL)
  451.                     select_weapon(CONCUSSION_INDEX, 1, 1, 1);
  452. weapon_selected: ;
  453.             }
  454.         }
  455.     }
  456.  
  457. }
  458.  
  459. #ifndef RELEASE
  460.  
  461. //    ----------------------------------------------------------------------------------------
  462. //    Show player which weapons he has, how much ammo...
  463. //    Looks like a debug screen now because it writes to mono screen, but that will change...
  464. void show_weapon_status(void)
  465. {
  466.     int    i;
  467.  
  468.     for (i=0; i<MAX_PRIMARY_WEAPONS; i++) {
  469.         if (Players[Player_num].primary_weapon_flags & (1 << i))
  470.             mprintf((0, "HAVE"));
  471.         else
  472.             mprintf((0, "    "));
  473.  
  474.         mprintf((0, "  Weapon: %20s, charges: %4i\n", PRIMARY_WEAPON_NAMES(i), Players[Player_num].primary_ammo[i]));
  475.     }
  476.  
  477.     mprintf((0, "\n"));
  478.     for (i=0; i<MAX_SECONDARY_WEAPONS; i++) {
  479.         if (Players[Player_num].secondary_weapon_flags & (1 << i))
  480.             mprintf((0, "HAVE"));
  481.         else
  482.             mprintf((0, "    "));
  483.  
  484.         mprintf((0, "  Weapon: %20s, charges: %4i\n", SECONDARY_WEAPON_NAMES(i), Players[Player_num].secondary_ammo[i]));
  485.     }
  486.  
  487.     mprintf((0, "\n"));
  488.     mprintf((0, "\n"));
  489.  
  490. }
  491.  
  492. #endif
  493.  
  494. //    ---------------------------------------------------------------------
  495. //called when one of these weapons is picked up
  496. //when you pick up a secondary, you always get the weapon & ammo for it
  497. //    Returns true if powerup picked up, else returns false.
  498. int pick_up_secondary(int weapon_index,int count)
  499. {
  500.     int    num_picked_up;
  501.  
  502.     if (Players[Player_num].secondary_ammo[weapon_index] >= Secondary_ammo_max[weapon_index]) {
  503.         HUD_init_message("%s %i %ss!", TXT_ALREADY_HAVE, Players[Player_num].secondary_ammo[weapon_index],SECONDARY_WEAPON_NAMES(weapon_index));
  504.         return 0;
  505.     }
  506.  
  507.     Players[Player_num].secondary_weapon_flags |= (1<<weapon_index);
  508.     Players[Player_num].secondary_ammo[weapon_index] += count;
  509.  
  510.     num_picked_up = count;
  511.     if (Players[Player_num].secondary_ammo[weapon_index] > Secondary_ammo_max[weapon_index]) {
  512.         num_picked_up = count - (Players[Player_num].secondary_ammo[weapon_index] - Secondary_ammo_max[weapon_index]);
  513.         Players[Player_num].secondary_ammo[weapon_index] = Secondary_ammo_max[weapon_index];
  514.     }
  515.  
  516.     //if you pick up a homing, and you're currently using concussion,
  517.     //and you had no homings before, then upgrade
  518.     if ((Secondary_weapon<weapon_index) && (weapon_index != PROXIMITY_INDEX)) //  && (Players[Player_num].secondary_ammo[weapon_index] == count))
  519.         select_weapon(weapon_index,1, 0, 1);
  520.  
  521.     //if you pick up a concussion, and you've got homing (or smart or mega) selected but are out,
  522.     //then select concussion
  523.     if ((weapon_index != PROXIMITY_INDEX) && (Players[Player_num].secondary_ammo[Secondary_weapon] == 0))
  524.         select_weapon(weapon_index,1, 0, 1);
  525.  
  526.     //note: flash for all but concussion was 7,14,21
  527.     if (count>1) {
  528.         PALETTE_FLASH_ADD(15,15,15);
  529.         HUD_init_message("%d %s%s",num_picked_up,SECONDARY_WEAPON_NAMES(weapon_index), TXT_SX);
  530.     }
  531.     else {
  532.         PALETTE_FLASH_ADD(10,10,10);
  533.         HUD_init_message("%s!",SECONDARY_WEAPON_NAMES(weapon_index));
  534.     }
  535.  
  536.     return 1;
  537. }
  538.  
  539. //called when a primary weapon is picked up
  540. //returns true if actually picked up
  541. int pick_up_primary(int weapon_index)
  542. {
  543.     ubyte old_flags = Players[Player_num].primary_weapon_flags;
  544.     ubyte flag = 1<<weapon_index;
  545.  
  546.     if (Players[Player_num].primary_weapon_flags & flag) {        //already have
  547.         HUD_init_message("%s %s!", TXT_ALREADY_HAVE_THE, PRIMARY_WEAPON_NAMES(weapon_index));
  548.         return 0;
  549.     }
  550.  
  551.     Players[Player_num].primary_weapon_flags |= flag;
  552.  
  553.     if (!(old_flags & flag) && weapon_index>Primary_weapon)
  554.         select_weapon(weapon_index,0,0,1);
  555.  
  556.     PALETTE_FLASH_ADD(7,14,21);
  557.     HUD_init_message("%s!",PRIMARY_WEAPON_NAMES(weapon_index));
  558.  
  559.     return 1;
  560. }
  561.  
  562. //called when ammo (for the vulcan cannon) is picked up
  563. //    Return true if ammo picked up, else return false.
  564. int pick_up_ammo(int class_flag,int weapon_index,int ammo_count)
  565. {
  566.     int old_ammo=class_flag;        //kill warning
  567.  
  568.     Assert(class_flag==CLASS_PRIMARY && weapon_index==VULCAN_INDEX);
  569.  
  570.     if (Players[Player_num].primary_ammo[weapon_index] == Primary_ammo_max[weapon_index])
  571.         return 0;
  572.  
  573.     old_ammo = Players[Player_num].primary_ammo[weapon_index];
  574.  
  575.     Players[Player_num].primary_ammo[weapon_index] += ammo_count;
  576.  
  577.     if (Players[Player_num].primary_ammo[weapon_index] > Primary_ammo_max[weapon_index])
  578.         Players[Player_num].primary_ammo[weapon_index] = Primary_ammo_max[weapon_index];
  579.  
  580.     if (Players[Player_num].primary_weapon_flags&(1<<weapon_index) && weapon_index>Primary_weapon && old_ammo==0)
  581.         select_weapon(weapon_index,0,0,1);
  582.  
  583.     return 1;
  584. }
  585.  
  586. 
  587.