]> icculus.org git repositories - btb/d2x.git/blob - main/powerup.c
document -gl_refresh (d1x r1.20)
[btb/d2x.git] / main / powerup.c
1 /* $Id: powerup.c,v 1.7 2003-10-10 09:36:35 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Code for powerup objects.
18  *
19  * Old Log:
20  * Revision 1.2  1995/10/31  10:18:55  allender
21  * shareware stuff
22  *
23  * Revision 1.1  1995/05/16  15:30:16  allender
24  * Initial revision
25  *
26  * Revision 2.2  1995/03/24  13:50:36  john
27  * Added mega-wowie zowie to release.
28  *
29  * Revision 2.1  1995/03/21  14:38:39  john
30  * Ifdef'd out the NETWORK code.
31  *
32  * Revision 2.0  1995/02/27  11:27:15  john
33  * New version 2.0, which has no anonymous unions, builds with
34  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
35  *
36  * Revision 1.94  1995/02/22  13:46:03  allender
37  * remove anonymous unions from object structure
38  *
39  * Revision 1.93  1995/02/06  15:52:51  mike
40  * add mini megawow powerup for giving reasonable weapons.
41  *
42  * Revision 1.92  1995/01/23  22:49:59  mike
43  * drop energy instead of primary weapon if you have primary weapon
44  * (drop nothing if want to drop vulcan ammo and you are maxed out)
45  * if you have primary weapon and primary weapon there, get energy instead.
46  *
47  * Revision 1.91  1995/01/19  09:42:22  allender
48  * record laser levels for demos
49  *
50  * Revision 1.90  1994/12/31  12:28:01  rob
51  * Added sound for coop key grabs.
52  *
53  * Revision 1.89  1994/12/19  19:55:17  rob
54  * Fixing key semantics for coop game.
55  *
56  * Revision 1.88  1994/12/07  12:55:21  mike
57  * tweak vulcan amounts.
58  *
59  * Revision 1.87  1994/12/06  13:55:36  matt
60  * Made shield & energy powerup messages round to match HUD message
61  *
62  * Revision 1.86  1994/12/03  19:03:57  matt
63  * Fixed vulcan ammo HUD message
64  *
65  * Revision 1.85  1994/11/29  11:35:41  rob
66  * Added sound casting for grabbing powerups.
67  *
68  * Revision 1.84  1994/11/28  11:26:38  matt
69  * Cleaned up hud message printing for picking up weapons
70  *
71  * Revision 1.83  1994/11/27  23:14:01  matt
72  * Made changes for new mprintf calling convention
73  *
74  * Revision 1.82  1994/11/21  16:02:51  mike
75  * comment out unused powerups.
76  *
77  * Revision 1.81  1994/11/20  18:25:47  john
78  * Fixed some #ifndef RELEASE inconsistancies.
79  *
80  * Revision 1.80  1994/11/19  23:54:13  mike
81  * limit megawowiezowie to shareware powerups if in shareware version.
82  *
83  * Revision 1.79  1994/11/14  16:06:16  yuan
84  * Made cloak and invulnerability only picked up once.
85  *
86  * Revision 1.78  1994/11/07  17:41:06  mike
87  * messages for when you're fully stocked with missiles.
88  *
89  * Revision 1.77  1994/10/28  14:42:50  john
90  * Added sound volumes to all sound calls.
91  *
92  * Revision 1.76  1994/10/26  15:55:23  yuan
93  * Made vulcan cannon give 100 ammo if it has less than that.
94  *
95  * Revision 1.75  1994/10/26  15:54:57  yuan
96  * *** empty log message ***
97  *
98  * Revision 1.74  1994/10/25  14:31:25  allender
99  * Fixed bug where getting cloak powerup while cloaked resulted in
100  * player being cloaked forever.
101  *
102  * Revision 1.73  1994/10/25  10:51:21  matt
103  * Vulcan cannon powerups now contain ammo count
104  *
105  * Revision 1.72  1994/10/21  20:41:32  mike
106  * Fix silly backwards (- instead of +) bug in invulnerability powerup.
107  *
108  * Revision 1.71  1994/10/20  09:49:23  mike
109  * Fix up powerups in some way.
110  *
111  * Revision 1.70  1994/10/19  11:16:25  mike
112  * Limit amount of each type of ammo player can hold.
113  *
114  * Revision 1.69  1994/10/17  14:12:11  matt
115  * Added sound for powerup disappearance effect
116  *
117  * Revision 1.68  1994/10/17  14:07:04  mike
118  * Make shields and energy max out at 200.
119  *
120  * Revision 1.67  1994/10/16  12:43:37  mike
121  * Don't allow you to pick up a primary weapon, or invulnerability, you already have.
122  * Make cloak time additive.
123  *
124  * Revision 1.66  1994/10/15  19:05:30  mike
125  * Define constants for vulcan ammo amounts.
126  *
127  * Revision 1.65  1994/10/14  15:57:28  mike
128  * When you pick up a laser boost or quad_laser powerup, update weapon display.
129  *
130  * Revision 1.64  1994/10/13  10:57:51  adam
131  * fiddled with powerup disappearance
132  *
133  * Revision 1.63  1994/10/12  13:07:33  mike
134  * Make powerup play vclip when it goes away.
135  *
136  * Revision 1.62  1994/10/12  08:04:42  mike
137  * Make proximity powerup worth 4 bombs.
138  *
139  * Revision 1.61  1994/10/08  23:37:33  matt
140  * Don't pick up weapons you already have; also fixed auto_select bug
141  * for seconary weapons
142  *
143  * Revision 1.60  1994/10/08  15:41:00  mike
144  * Diminish palette effect due to powerups.
145  *
146  * Revision 1.59  1994/10/07  23:37:45  matt
147  * Made weapons select when pick up better one
148  *
149  * Revision 1.58  1994/10/07  22:09:20  rob
150  * Added network hook for grabbing the cloaking device.
151  *
152  */
153
154
155 #ifdef HAVE_CONFIG_H
156 #include <conf.h>
157 #endif
158
159 #include <stdarg.h>
160 #include <stdio.h>
161 #include <string.h>
162
163 #include "fix.h"
164 #include "vecmat.h"
165 #include "gr.h"
166 #include "3d.h"
167 #include "mono.h"
168 #include "error.h"
169
170 #include "inferno.h"
171 #include "object.h"
172 #include "game.h"
173 #include "key.h"
174
175 #include "fireball.h"
176 #include "powerup.h"
177 #include "gauges.h"
178
179 #include "sounds.h"
180 #include "player.h"
181
182 #include "wall.h"
183 #include "text.h"
184 #include "weapon.h"
185 #include "laser.h"
186 #include "scores.h"
187 #include "multi.h"
188 #include "lighting.h"
189 #include "controls.h"
190 #include "kconfig.h"
191
192 #include "newdemo.h"
193 #include "escort.h"
194
195 #ifdef EDITOR
196 #include "gr.h" //      for powerup outline drawing
197 #include "editor/editor.h"
198 #endif
199
200 int N_powerup_types = 0;
201 powerup_type_info Powerup_info[MAX_POWERUP_TYPES];
202
203 //process this powerup for this frame
204 void do_powerup_frame(object *obj)
205 {
206         fix fudge;
207         vclip_info *vci = &obj->rtype.vclip_info;
208         vclip *vc = &Vclip[vci->vclip_num];
209
210         fudge = (FrameTime * ((obj-Objects)&3)) >> 4;
211         
212         vci->frametime -= FrameTime+fudge;
213         
214         while (vci->frametime < 0 ) {
215
216                 vci->frametime += vc->frame_time;
217                 
218                 if ((obj-Objects)&1)
219                         vci->framenum--;
220                 else
221                         vci->framenum++;
222
223                 if (vci->framenum >= vc->num_frames)
224                         vci->framenum=0;
225
226                 if (vci->framenum < 0)
227                         vci->framenum = vc->num_frames-1;
228         }
229
230         if (obj->lifeleft <= 0) {
231                 object_create_explosion(obj->segnum, &obj->pos, F1_0*7/2, VCLIP_POWERUP_DISAPPEARANCE );
232
233                 if ( Vclip[VCLIP_POWERUP_DISAPPEARANCE].sound_num > -1 )
234                         digi_link_sound_to_object( Vclip[VCLIP_POWERUP_DISAPPEARANCE].sound_num, obj-Objects, 0, F1_0);
235         }
236 }
237
238 #ifdef EDITOR
239 extern fix blob_vertices[];
240
241 //      blob_vertices has 3 vertices in it, 4th must be computed
242 void draw_blob_outline(void)
243 {
244         fix     v3x, v3y;
245
246         v3x = blob_vertices[4] - blob_vertices[2] + blob_vertices[0];
247         v3y = blob_vertices[5] - blob_vertices[3] + blob_vertices[1];
248
249         gr_setcolor(BM_XRGB(63, 63, 63));
250
251         mprintf((0, "[%7.3f %7.3f]  [%7.3f %7.3f]  [%7.3f %7.3f]\n", f2fl(blob_vertices[0]), f2fl(blob_vertices[1]), f2fl(blob_vertices[2]), f2fl(blob_vertices[3]), f2fl(blob_vertices[4]), f2fl(blob_vertices[5]) ));
252
253         gr_line(blob_vertices[0], blob_vertices[1], blob_vertices[2], blob_vertices[3]);
254         gr_line(blob_vertices[2], blob_vertices[3], blob_vertices[4], blob_vertices[5]);
255         gr_line(blob_vertices[4], blob_vertices[5], v3x, v3y);
256
257         gr_line(v3x, v3y, blob_vertices[0], blob_vertices[1]);
258 }
259 #endif
260
261 void draw_powerup(object *obj)
262 {
263         #ifdef EDITOR
264         blob_vertices[0] = 0x80000;
265         #endif
266
267         draw_object_blob(obj, Vclip[obj->rtype.vclip_info.vclip_num].frames[obj->rtype.vclip_info.framenum] );
268
269         #ifdef EDITOR
270         if ((Function_mode == FMODE_EDITOR) && (Cur_object_index == obj-Objects))
271                 if (blob_vertices[0] != 0x80000)
272                         draw_blob_outline();
273         #endif
274
275 }
276
277 //void mprintf_powerup_info(void)
278 //{
279 //      int             i;
280 //mprintf((0, "Powerup: %s\n", text));
281 //for (i=0; i<5; i++) {
282 //      char    has_text[12];
283 //
284 //      if (Players[Player_num].primary_weapon_flags & (1 << i))
285 //              strcpy(has_text,"PRESENT");
286 //      else
287 //              strcpy(has_text,"NOPE   ");
288 //      has_text[8] = 0;
289 //
290 //      mprintf((0, "Weapon %i = %s, ammo = %6i, name = %s\n", i, has_text, Players[Player_num].primary_ammo[i], Primary_weapon_names[i]));
291 //}
292 //
293 //for (i=0; i<5; i++) {
294 //      char    has_text[12];
295 //
296 //      if (Players[Player_num].secondary_weapon_flags & (1 << i))
297 //              strcpy(has_text,"PRESENT");
298 //      else
299 //              strcpy(has_text,"NOPE   ");
300 //
301 //      mprintf((0, "Weapon %i = %s, ammo = %6i, name = %s\n", i, has_text, Players[Player_num].secondary_ammo[i], Secondary_weapon_names[i]));
302 //}
303 //}
304
305 void powerup_basic(int redadd, int greenadd, int blueadd, int score, char *format, ...)
306 {
307         char            text[120];
308         va_list args;
309
310         va_start(args, format );
311         vsprintf(text, format, args);
312         va_end(args);
313
314         PALETTE_FLASH_ADD(redadd,greenadd,blueadd);
315
316         HUD_init_message(text);
317
318         //mprintf_powerup_info();
319
320         add_points_to_score(score);
321
322 }
323
324 //#ifndef RELEASE
325 //      Give the megawow powerup!
326 void do_megawow_powerup(int quantity)
327 {
328         int i;
329
330         powerup_basic(30, 0, 30, 1, "MEGA-WOWIE-ZOWIE!");
331         Players[Player_num].primary_weapon_flags = 0xffff ^ HAS_FLAG(SUPER_LASER_INDEX);                //no super laser
332         Players[Player_num].secondary_weapon_flags = 0xffff;
333
334         for (i=0; i<MAX_PRIMARY_WEAPONS; i++)
335                 Players[Player_num].primary_ammo[i] = VULCAN_AMMO_MAX;
336
337         for (i=0; i<3; i++)
338                 Players[Player_num].secondary_ammo[i] = quantity;
339
340         for (i=3; i<MAX_SECONDARY_WEAPONS; i++)
341                 Players[Player_num].secondary_ammo[i] = quantity/5;
342
343         if (Newdemo_state == ND_STATE_RECORDING)
344                 newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
345
346         Players[Player_num].energy = F1_0*200;
347         Players[Player_num].shields = F1_0*200;
348         Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
349         Players[Player_num].laser_level = MAX_SUPER_LASER_LEVEL;
350
351         if (Game_mode & GM_HOARD)
352                 Players[Player_num].secondary_ammo[PROXIMITY_INDEX] = 12;
353
354
355         update_laser_weapon_info();
356
357 }
358 //#endif
359
360 int pick_up_energy(void)
361 {
362         int     used=0;
363
364         if (Players[Player_num].energy < MAX_ENERGY) {
365                 fix boost;
366                 boost = 3*F1_0 + 3*F1_0*(NDL - Difficulty_level);
367                 if (Difficulty_level == 0)
368                         boost += boost/2;
369                 Players[Player_num].energy += boost;
370                 if (Players[Player_num].energy > MAX_ENERGY)
371                         Players[Player_num].energy = MAX_ENERGY;
372                 powerup_basic(15,15,7, ENERGY_SCORE, "%s %s %d",TXT_ENERGY,TXT_BOOSTED_TO,f2ir(Players[Player_num].energy));
373                 used=1;
374         } else
375                 HUD_init_message(TXT_MAXED_OUT,TXT_ENERGY);
376
377         return used;
378 }
379
380 int pick_up_vulcan_ammo(void)
381 {
382         int     used=0,max;
383
384         int     pwsave = Primary_weapon;                // Ugh, save selected primary weapon around the picking up of the ammo.  I apologize for this code.  Matthew A. Toschlog
385         if (pick_up_ammo(CLASS_PRIMARY, VULCAN_INDEX, VULCAN_AMMO_AMOUNT)) {
386                 powerup_basic(7, 14, 21, VULCAN_AMMO_SCORE, "%s!", TXT_VULCAN_AMMO);
387                 used = 1;
388         } else {
389                 max = Primary_ammo_max[VULCAN_INDEX];
390                 if (Players[Player_num].flags & PLAYER_FLAGS_AMMO_RACK)
391                         max *= 2;
392                 HUD_init_message("%s %d %s!",TXT_ALREADY_HAVE,f2i((unsigned) VULCAN_AMMO_SCALE * (unsigned) max),TXT_VULCAN_ROUNDS);
393                 used = 0;
394         }
395         Primary_weapon = pwsave;
396
397         return used;
398 }
399
400 extern void invalidate_escort_goal(void);
401 extern char GetKeyValue(char);
402 extern void check_to_use_primary(int);
403 extern void multi_send_got_flag (char);
404
405 int Headlight_active_default=1; //is headlight on when picked up?
406 extern int PlayerMessage;
407
408 //      returns true if powerup consumed
409 int do_powerup(object *obj)
410 {
411         int used=0;
412         int special_used=0;             //for when hitting vulcan cannon gets vulcan ammo
413         char temp_string[50];
414         int id=obj->id;
415
416         if ((Player_is_dead) || (ConsoleObject->type == OBJ_GHOST) || (Players[Player_num].shields < 0))
417                 return 0;
418
419         if (obj->ctype.powerup_info.creation_time > GameTime)           //gametime wrapped!
420                 obj->ctype.powerup_info.creation_time = 0;                              //allow player to pick up
421
422         if ((obj->ctype.powerup_info.flags & PF_SPAT_BY_PLAYER) && obj->ctype.powerup_info.creation_time>0 && GameTime<obj->ctype.powerup_info.creation_time+i2f(2))
423                 return 0;               //not enough time elapsed
424
425         PlayerMessage=0;        //      Prevent messages from going to HUD if -PlayerMessages switch is set
426
427         switch (obj->id) {
428                 case POW_EXTRA_LIFE:
429                         Players[Player_num].lives++;
430                         powerup_basic(15, 15, 15, 0, TXT_EXTRA_LIFE);
431                         used=1;
432                         break;
433                 case POW_ENERGY:
434                         used = pick_up_energy();
435                         break;
436                 case POW_SHIELD_BOOST:
437                         if (Players[Player_num].shields < MAX_SHIELDS) {
438                                 fix boost = 3*F1_0 + 3*F1_0*(NDL - Difficulty_level);
439                                 if (Difficulty_level == 0)
440                                         boost += boost/2;
441                                 Players[Player_num].shields += boost;
442                                 if (Players[Player_num].shields > MAX_SHIELDS)
443                                         Players[Player_num].shields = MAX_SHIELDS;
444                                 powerup_basic(0, 0, 15, SHIELD_SCORE, "%s %s %d",TXT_SHIELD,TXT_BOOSTED_TO,f2ir(Players[Player_num].shields));
445                                 used=1;
446                         } else
447                                 HUD_init_message(TXT_MAXED_OUT,TXT_SHIELD);
448                         break;
449                 case POW_LASER:
450                         if (Players[Player_num].laser_level >= MAX_LASER_LEVEL) {
451                                 //Players[Player_num].laser_level = MAX_LASER_LEVEL;
452                                 HUD_init_message(TXT_MAXED_OUT,TXT_LASER);
453                         } else {
454                                 if (Newdemo_state == ND_STATE_RECORDING)
455                                         newdemo_record_laser_level(Players[Player_num].laser_level, Players[Player_num].laser_level + 1);
456                                 Players[Player_num].laser_level++;
457                                 powerup_basic(10, 0, 10, LASER_SCORE, "%s %s %d",TXT_LASER,TXT_BOOSTED_TO, Players[Player_num].laser_level+1);
458                                 update_laser_weapon_info();
459                                 pick_up_primary (LASER_INDEX);
460                                 used=1;
461                         }
462                         if (!used && !(Game_mode & GM_MULTI) )
463                                 used = pick_up_energy();
464                         break;
465                 case POW_MISSILE_1:
466                         used=pick_up_secondary(CONCUSSION_INDEX,1);
467                         break;
468                 case POW_MISSILE_4:
469                         used=pick_up_secondary(CONCUSSION_INDEX,4);
470                         break;
471
472                 case POW_KEY_BLUE:
473                         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY)
474                                 break;
475 #ifdef NETWORK
476                         multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
477 #endif
478                         digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
479                         Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY;
480                         powerup_basic(0, 0, 15, KEY_SCORE, "%s %s",TXT_BLUE,TXT_ACCESS_GRANTED);
481                         if (Game_mode & GM_MULTI)
482                                 used=0;
483                         else
484                                 used=1;
485                         invalidate_escort_goal();
486                         break;
487                 case POW_KEY_RED:
488                         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY)
489                                 break;
490 #ifdef NETWORK
491                         multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
492 #endif
493                         digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
494                         Players[Player_num].flags |= PLAYER_FLAGS_RED_KEY;
495                         powerup_basic(15, 0, 0, KEY_SCORE, "%s %s",TXT_RED,TXT_ACCESS_GRANTED);
496                         if (Game_mode & GM_MULTI)
497                                 used=0;
498                         else
499                                 used=1;
500                         invalidate_escort_goal();
501                         break;
502                 case POW_KEY_GOLD:
503                         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY)
504                                 break;
505 #ifdef NETWORK
506                         multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
507 #endif
508                         digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
509                         Players[Player_num].flags |= PLAYER_FLAGS_GOLD_KEY;
510                         powerup_basic(15, 15, 7, KEY_SCORE, "%s %s",TXT_YELLOW,TXT_ACCESS_GRANTED);
511                         if (Game_mode & GM_MULTI)
512                                 used=0;
513                         else
514                                 used=1;
515                         invalidate_escort_goal();
516                         break;
517                 case POW_QUAD_FIRE:
518                         if (!(Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS)) {
519                                 Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
520                                 powerup_basic(15, 15, 7, QUAD_FIRE_SCORE, "%s!",TXT_QUAD_LASERS);
521                                 update_laser_weapon_info();
522                                 used=1;
523                         } else
524                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,TXT_QUAD_LASERS);
525                         if (!used && !(Game_mode & GM_MULTI) )
526                                 used = pick_up_energy();
527                         break;
528
529                 case    POW_VULCAN_WEAPON:
530                 case    POW_GAUSS_WEAPON: {
531                         int ammo = obj->ctype.powerup_info.count;
532
533                         used = pick_up_primary((obj->id==POW_VULCAN_WEAPON)?VULCAN_INDEX:GAUSS_INDEX);
534
535                         //didn't get the weapon (because we already have it), but
536                         //maybe snag some of the ammo.  if single-player, grab all the ammo
537                         //and remove the powerup.  If multi-player take ammo in excess of
538                         //the amount in a powerup, and leave the rest.
539                         if (! used)
540                                 if ((Game_mode & GM_MULTI) )
541                                         ammo -= VULCAN_AMMO_AMOUNT;     //don't let take all ammo
542
543                         if (ammo > 0) {
544                                 int ammo_used;
545                                 ammo_used = pick_up_ammo(CLASS_PRIMARY, VULCAN_INDEX, ammo);
546                                 obj->ctype.powerup_info.count -= ammo_used;
547                                 if (!used && ammo_used) {
548                                         powerup_basic(7, 14, 21, VULCAN_AMMO_SCORE, "%s!", TXT_VULCAN_AMMO);
549                                         special_used = 1;
550                                         id = POW_VULCAN_AMMO;           //set new id for making sound at end of this function
551                                         if (obj->ctype.powerup_info.count == 0)
552                                                 used = 1;               //say used if all ammo taken
553                                 }
554                         }
555
556                         break;
557                 }
558
559                 case    POW_SPREADFIRE_WEAPON:
560                         used = pick_up_primary(SPREADFIRE_INDEX);
561                         if (!used && !(Game_mode & GM_MULTI) )
562                                 used = pick_up_energy();
563                         break;
564                 case    POW_PLASMA_WEAPON:
565                         used = pick_up_primary(PLASMA_INDEX);
566                         if (!used && !(Game_mode & GM_MULTI) )
567                                 used = pick_up_energy();
568                         break;
569                 case    POW_FUSION_WEAPON:
570                         used = pick_up_primary(FUSION_INDEX);
571                         if (!used && !(Game_mode & GM_MULTI) )
572                                 used = pick_up_energy();
573                         break;
574
575                 case    POW_HELIX_WEAPON:
576                         used = pick_up_primary(HELIX_INDEX);
577                         if (!used && !(Game_mode & GM_MULTI) )
578                                 used = pick_up_energy();
579                         break;
580
581                 case    POW_PHOENIX_WEAPON:
582                         used = pick_up_primary(PHOENIX_INDEX);
583                         if (!used && !(Game_mode & GM_MULTI) )
584                                 used = pick_up_energy();
585                         break;
586
587                 case    POW_OMEGA_WEAPON:
588                         used = pick_up_primary(OMEGA_INDEX);
589                         if (used)
590                                 Omega_charge = obj->ctype.powerup_info.count;
591                         if (!used && !(Game_mode & GM_MULTI) )
592                                 used = pick_up_energy();
593                         break;
594
595                 case    POW_PROXIMITY_WEAPON:
596                         used=pick_up_secondary(PROXIMITY_INDEX,4);
597                         break;
598                 case    POW_SMARTBOMB_WEAPON:
599                         used=pick_up_secondary(SMART_INDEX,1);
600                         break;
601                 case    POW_MEGA_WEAPON:
602                         used=pick_up_secondary(MEGA_INDEX,1);
603                         break;
604                 case    POW_SMISSILE1_1:
605                         used=pick_up_secondary(SMISSILE1_INDEX,1);
606                         break;
607                 case    POW_SMISSILE1_4:
608                         used=pick_up_secondary(SMISSILE1_INDEX,4);
609                         break;
610                 case    POW_GUIDED_MISSILE_1:
611                         used=pick_up_secondary(GUIDED_INDEX,1);
612                         break;
613                 case    POW_GUIDED_MISSILE_4:
614                         used=pick_up_secondary(GUIDED_INDEX,4);
615                         break;
616                 case    POW_SMART_MINE:
617                         used=pick_up_secondary(SMART_MINE_INDEX,4);
618                         break;
619                 case    POW_MERCURY_MISSILE_1:
620                         used=pick_up_secondary(SMISSILE4_INDEX,1);
621                         break;
622                 case    POW_MERCURY_MISSILE_4:
623                         used=pick_up_secondary(SMISSILE4_INDEX,4);
624                         break;
625                 case    POW_EARTHSHAKER_MISSILE:
626                         used=pick_up_secondary(SMISSILE5_INDEX,1);
627                         break;
628                 case    POW_VULCAN_AMMO:
629                         used = pick_up_vulcan_ammo();
630                         break;
631                 case    POW_HOMING_AMMO_1:
632                         used=pick_up_secondary(HOMING_INDEX,1);
633                         break;
634                 case    POW_HOMING_AMMO_4:
635                         used=pick_up_secondary(HOMING_INDEX,4);
636                         break;
637                 case    POW_CLOAK:
638                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
639                                 HUD_init_message("%s %s!",TXT_ALREADY_ARE,TXT_CLOAKED);
640                                 break;
641                         } else {
642                                 Players[Player_num].cloak_time = GameTime;      //      Not! changed by awareness events (like player fires laser).
643                                 Players[Player_num].flags |= PLAYER_FLAGS_CLOAKED;
644                                 ai_do_cloak_stuff();
645                                 #ifdef NETWORK
646                                 if (Game_mode & GM_MULTI)
647                                         multi_send_cloak();
648                                 #endif
649                                 powerup_basic(-10,-10,-10, CLOAK_SCORE, "%s!",TXT_CLOAKING_DEVICE);
650                                 used = 1;
651                                 break;
652                         }
653                 case    POW_INVULNERABILITY:
654                         if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
655                                 HUD_init_message("%s %s!",TXT_ALREADY_ARE,TXT_INVULNERABLE);
656                                 break;
657                         } else {
658                                 Players[Player_num].invulnerable_time = GameTime;
659                                 Players[Player_num].flags |= PLAYER_FLAGS_INVULNERABLE;
660                                 powerup_basic(7, 14, 21, INVULNERABILITY_SCORE, "%s!",TXT_INVULNERABILITY);
661                                 used = 1;
662                                 break;
663                         }
664         #ifndef RELEASE
665                 case    POW_MEGAWOW:
666                         do_megawow_powerup(50);
667                         used = 1;
668                         break;
669         #endif
670
671                 case POW_FULL_MAP:
672                         if (Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL) {
673                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the FULL MAP");
674                                 if (!(Game_mode & GM_MULTI) )
675                                         used = pick_up_energy();
676                         } else {
677                                 Players[Player_num].flags |= PLAYER_FLAGS_MAP_ALL;
678                                 powerup_basic(15, 0, 15, 0, "FULL MAP!");
679                                 used=1;
680                         }
681                         break;
682
683                 case POW_CONVERTER:
684                         if (Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) {
685                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Converter");
686                                 if (!(Game_mode & GM_MULTI) )
687                                         used = pick_up_energy();
688                         } else {
689                                 Players[Player_num].flags |= PLAYER_FLAGS_CONVERTER;
690 // DPH: anyone know what the hell this is supposed to do? it's always true =)
691 /*                              if ((GetKeyValue(54))<255)
692                                  {*/
693                                         sprintf (temp_string,"Energy->Shield converter! (Press %c to use)",key_to_ascii(GetKeyValue(54)));
694                                 powerup_basic(15, 0, 15, 0, temp_string);
695 /*                               }
696                            else
697                                 powerup_basic(15, 0, 15, 0, "Energy -> shield converter!"); */
698
699
700                                 used=1;
701                         }
702                         break;
703
704                 case POW_SUPER_LASER:
705                         if (Players[Player_num].laser_level >= MAX_SUPER_LASER_LEVEL) {
706                                 Players[Player_num].laser_level = MAX_SUPER_LASER_LEVEL;
707                                 HUD_init_message("SUPER LASER MAXED OUT!");
708                         } else {
709                                 int old_level=Players[Player_num].laser_level;
710
711                                 if (Players[Player_num].laser_level <= MAX_LASER_LEVEL)
712                                         Players[Player_num].laser_level = MAX_LASER_LEVEL;
713                                 Players[Player_num].laser_level++;
714                                 if (Newdemo_state == ND_STATE_RECORDING)
715                                         newdemo_record_laser_level(old_level, Players[Player_num].laser_level);
716                                 powerup_basic(10, 0, 10, LASER_SCORE, "Super Boost to Laser level %d",Players[Player_num].laser_level+1);
717                                 update_laser_weapon_info();
718                                 if (Primary_weapon!=LASER_INDEX)
719                               check_to_use_primary (SUPER_LASER_INDEX);
720                                 used=1;
721                         }
722                         if (!used && !(Game_mode & GM_MULTI) )
723                                 used = pick_up_energy();
724                         break;
725
726                 case POW_AMMO_RACK:
727                         if (Players[Player_num].flags & PLAYER_FLAGS_AMMO_RACK) {
728                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Ammo rack");
729                                 if (!(Game_mode & GM_MULTI) )
730                                         used = pick_up_energy();
731                         }
732                         else {
733                                 Players[Player_num].flags |= PLAYER_FLAGS_AMMO_RACK;
734 #ifdef NETWORK
735                                 multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
736 #endif
737                                 digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
738                                 powerup_basic(15, 0, 15, 0, "AMMO RACK!");
739                                 used=1;
740                         }
741                         break;
742
743                 case POW_AFTERBURNER:
744                         if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER) {
745                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Afterburner");
746                                 if (!(Game_mode & GM_MULTI) )
747                                         used = pick_up_energy();
748                         }
749                         else {
750                                 Players[Player_num].flags |= PLAYER_FLAGS_AFTERBURNER;
751 #ifdef NETWORK
752                                 multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
753 #endif
754                                 digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
755                                 powerup_basic(15, 15, 15, 0, "AFTERBURNER!");
756                                 Afterburner_charge = f1_0;
757                                 used=1;
758                         }
759                         break;
760
761                 case POW_HEADLIGHT:
762                         if (Players[Player_num].flags & PLAYER_FLAGS_HEADLIGHT) {
763                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Headlight boost");
764                                 if (!(Game_mode & GM_MULTI) )
765                                         used = pick_up_energy();
766                         }
767                         else {
768                                 char msg[100];
769                                 Players[Player_num].flags |= PLAYER_FLAGS_HEADLIGHT;
770 #ifdef NETWORK
771                                 multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
772 #endif
773                                 digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
774                                 sprintf(msg,"HEADLIGHT BOOST! (Headlight is %s)",Headlight_active_default?"ON":"OFF");
775                                 powerup_basic(15, 0, 15, 0, msg );
776                                 if (Headlight_active_default)
777                                         Players[Player_num].flags |= PLAYER_FLAGS_HEADLIGHT_ON;
778                                 used=1;
779 #ifdef NETWORK
780                            if (Game_mode & GM_MULTI)
781                                         multi_send_flags (Player_num);
782 #endif
783                         }
784                         break;
785
786 #ifdef NETWORK
787                 case POW_FLAG_BLUE:
788                         if (Game_mode & GM_CAPTURE)                     
789                                 if (get_team(Player_num) == TEAM_RED) {
790                                         powerup_basic(15, 0, 15, 0, "BLUE FLAG!");
791                                         Players[Player_num].flags |= PLAYER_FLAGS_FLAG;
792                                         used=1;
793                                         multi_send_got_flag (Player_num);
794                                 }
795                    break;
796
797                 case POW_HOARD_ORB:
798                         if (Game_mode & GM_HOARD)                       
799                                 if (Players[Player_num].secondary_ammo[PROXIMITY_INDEX]<12) {
800                                         powerup_basic(15, 0, 15, 0, "Orb!!!");
801                                         Players[Player_num].secondary_ammo[PROXIMITY_INDEX]++;
802                                         Players[Player_num].flags |= PLAYER_FLAGS_FLAG;
803                                         used=1;
804                                         multi_send_got_orb (Player_num);
805                                 }
806                   break;        
807
808                 case POW_FLAG_RED:
809                         if (Game_mode & GM_CAPTURE)                     
810                                 if (get_team(Player_num) == TEAM_BLUE) {
811                                         powerup_basic(15, 0, 15, 0, "RED FLAG!");
812                                         Players[Player_num].flags |= PLAYER_FLAGS_FLAG;
813                                         used=1;
814                                         multi_send_got_flag (Player_num);
815                                 }
816                    break;
817 #endif
818
819 //              case POW_HOARD_ORB:
820
821
822                 default:
823                         break;
824                 }
825
826 //always say used, until physics problem (getting stuck on unused powerup)
827 //is solved.  Note also the break statements above that are commented out
828 //!!    used=1;
829
830         if ((used || special_used) && Powerup_info[id].hit_sound  > -1 ) {
831                 #ifdef NETWORK
832                 if (Game_mode & GM_MULTI) // Added by Rob, take this out if it turns out to be not good for net games!
833                         multi_send_play_sound(Powerup_info[id].hit_sound, F1_0);
834                 #endif
835                 digi_play_sample( Powerup_info[id].hit_sound, F1_0 );
836                 detect_escort_goal_accomplished(obj-Objects);
837         }
838
839         PlayerMessage=1;
840
841         return used;
842
843 }
844
845 #ifndef FAST_FILE_IO
846 /*
847  * reads n powerup_type_info structs from a CFILE
848  */
849 extern int powerup_type_info_read_n(powerup_type_info *pti, int n, CFILE *fp)
850 {
851         int i;
852
853         for (i = 0; i < n; i++) {
854                 pti[i].vclip_num = cfile_read_int(fp);
855                 pti[i].hit_sound = cfile_read_int(fp);
856                 pti[i].size = cfile_read_fix(fp);
857                 pti[i].light = cfile_read_fix(fp);
858         }
859         return i;
860 }
861 #endif