use hardcoded value instead of sizeof(tmap_info), since size depends on whether edito...
[btb/d2x.git] / main / powerup.c
1 /* $Id: powerup.c,v 1.8 2004-08-28 23:17:45 schaffner 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  */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <conf.h>
24 #endif
25
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "fix.h"
31 #include "vecmat.h"
32 #include "gr.h"
33 #include "3d.h"
34 #include "mono.h"
35 #include "error.h"
36
37 #include "inferno.h"
38 #include "object.h"
39 #include "game.h"
40 #include "key.h"
41
42 #include "fireball.h"
43 #include "powerup.h"
44 #include "gauges.h"
45
46 #include "sounds.h"
47 #include "player.h"
48
49 #include "wall.h"
50 #include "text.h"
51 #include "weapon.h"
52 #include "laser.h"
53 #include "scores.h"
54 #include "multi.h"
55 #include "lighting.h"
56 #include "controls.h"
57 #include "kconfig.h"
58
59 #include "newdemo.h"
60 #include "escort.h"
61
62 #ifdef EDITOR
63 #include "gr.h" //      for powerup outline drawing
64 #include "editor/editor.h"
65 #endif
66
67 int N_powerup_types = 0;
68 powerup_type_info Powerup_info[MAX_POWERUP_TYPES];
69
70 //process this powerup for this frame
71 void do_powerup_frame(object *obj)
72 {
73         fix fudge;
74         vclip_info *vci = &obj->rtype.vclip_info;
75         vclip *vc = &Vclip[vci->vclip_num];
76
77         fudge = (FrameTime * ((obj-Objects)&3)) >> 4;
78         
79         vci->frametime -= FrameTime+fudge;
80         
81         while (vci->frametime < 0 ) {
82
83                 vci->frametime += vc->frame_time;
84                 
85                 if ((obj-Objects)&1)
86                         vci->framenum--;
87                 else
88                         vci->framenum++;
89
90                 if (vci->framenum >= vc->num_frames)
91                         vci->framenum=0;
92
93                 if (vci->framenum < 0)
94                         vci->framenum = vc->num_frames-1;
95         }
96
97         if (obj->lifeleft <= 0) {
98                 object_create_explosion(obj->segnum, &obj->pos, F1_0*7/2, VCLIP_POWERUP_DISAPPEARANCE );
99
100                 if ( Vclip[VCLIP_POWERUP_DISAPPEARANCE].sound_num > -1 )
101                         digi_link_sound_to_object( Vclip[VCLIP_POWERUP_DISAPPEARANCE].sound_num, obj-Objects, 0, F1_0);
102         }
103 }
104
105 #ifdef EDITOR
106 extern fix blob_vertices[];
107
108 //      blob_vertices has 3 vertices in it, 4th must be computed
109 void draw_blob_outline(void)
110 {
111         fix     v3x, v3y;
112
113         v3x = blob_vertices[4] - blob_vertices[2] + blob_vertices[0];
114         v3y = blob_vertices[5] - blob_vertices[3] + blob_vertices[1];
115
116         gr_setcolor(BM_XRGB(63, 63, 63));
117
118         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]) ));
119
120         gr_line(blob_vertices[0], blob_vertices[1], blob_vertices[2], blob_vertices[3]);
121         gr_line(blob_vertices[2], blob_vertices[3], blob_vertices[4], blob_vertices[5]);
122         gr_line(blob_vertices[4], blob_vertices[5], v3x, v3y);
123
124         gr_line(v3x, v3y, blob_vertices[0], blob_vertices[1]);
125 }
126 #endif
127
128 void draw_powerup(object *obj)
129 {
130         #ifdef EDITOR
131         blob_vertices[0] = 0x80000;
132         #endif
133
134         draw_object_blob(obj, Vclip[obj->rtype.vclip_info.vclip_num].frames[obj->rtype.vclip_info.framenum] );
135
136         #ifdef EDITOR
137         if ((Function_mode == FMODE_EDITOR) && (Cur_object_index == obj-Objects))
138                 if (blob_vertices[0] != 0x80000)
139                         draw_blob_outline();
140         #endif
141
142 }
143
144 //void mprintf_powerup_info(void)
145 //{
146 //      int             i;
147 //mprintf((0, "Powerup: %s\n", text));
148 //for (i=0; i<5; i++) {
149 //      char    has_text[12];
150 //
151 //      if (Players[Player_num].primary_weapon_flags & (1 << i))
152 //              strcpy(has_text,"PRESENT");
153 //      else
154 //              strcpy(has_text,"NOPE   ");
155 //      has_text[8] = 0;
156 //
157 //      mprintf((0, "Weapon %i = %s, ammo = %6i, name = %s\n", i, has_text, Players[Player_num].primary_ammo[i], Primary_weapon_names[i]));
158 //}
159 //
160 //for (i=0; i<5; i++) {
161 //      char    has_text[12];
162 //
163 //      if (Players[Player_num].secondary_weapon_flags & (1 << i))
164 //              strcpy(has_text,"PRESENT");
165 //      else
166 //              strcpy(has_text,"NOPE   ");
167 //
168 //      mprintf((0, "Weapon %i = %s, ammo = %6i, name = %s\n", i, has_text, Players[Player_num].secondary_ammo[i], Secondary_weapon_names[i]));
169 //}
170 //}
171
172 void powerup_basic(int redadd, int greenadd, int blueadd, int score, char *format, ...)
173 {
174         char            text[120];
175         va_list args;
176
177         va_start(args, format );
178         vsprintf(text, format, args);
179         va_end(args);
180
181         PALETTE_FLASH_ADD(redadd,greenadd,blueadd);
182
183         HUD_init_message(text);
184
185         //mprintf_powerup_info();
186
187         add_points_to_score(score);
188
189 }
190
191 //#ifndef RELEASE
192 //      Give the megawow powerup!
193 void do_megawow_powerup(int quantity)
194 {
195         int i;
196
197         powerup_basic(30, 0, 30, 1, "MEGA-WOWIE-ZOWIE!");
198         Players[Player_num].primary_weapon_flags = 0xffff ^ HAS_FLAG(SUPER_LASER_INDEX);                //no super laser
199         Players[Player_num].secondary_weapon_flags = 0xffff;
200
201         for (i=0; i<MAX_PRIMARY_WEAPONS; i++)
202                 Players[Player_num].primary_ammo[i] = VULCAN_AMMO_MAX;
203
204         for (i=0; i<3; i++)
205                 Players[Player_num].secondary_ammo[i] = quantity;
206
207         for (i=3; i<MAX_SECONDARY_WEAPONS; i++)
208                 Players[Player_num].secondary_ammo[i] = quantity/5;
209
210         if (Newdemo_state == ND_STATE_RECORDING)
211                 newdemo_record_laser_level(Players[Player_num].laser_level, MAX_LASER_LEVEL);
212
213         Players[Player_num].energy = F1_0*200;
214         Players[Player_num].shields = F1_0*200;
215         Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
216         Players[Player_num].laser_level = MAX_SUPER_LASER_LEVEL;
217
218         if (Game_mode & GM_HOARD)
219                 Players[Player_num].secondary_ammo[PROXIMITY_INDEX] = 12;
220
221
222         update_laser_weapon_info();
223
224 }
225 //#endif
226
227 int pick_up_energy(void)
228 {
229         int     used=0;
230
231         if (Players[Player_num].energy < MAX_ENERGY) {
232                 fix boost;
233                 boost = 3*F1_0 + 3*F1_0*(NDL - Difficulty_level);
234                 if (Difficulty_level == 0)
235                         boost += boost/2;
236                 Players[Player_num].energy += boost;
237                 if (Players[Player_num].energy > MAX_ENERGY)
238                         Players[Player_num].energy = MAX_ENERGY;
239                 powerup_basic(15,15,7, ENERGY_SCORE, "%s %s %d",TXT_ENERGY,TXT_BOOSTED_TO,f2ir(Players[Player_num].energy));
240                 used=1;
241         } else
242                 HUD_init_message(TXT_MAXED_OUT,TXT_ENERGY);
243
244         return used;
245 }
246
247 int pick_up_vulcan_ammo(void)
248 {
249         int     used=0,max;
250
251         int     pwsave = Primary_weapon;                // Ugh, save selected primary weapon around the picking up of the ammo.  I apologize for this code.  Matthew A. Toschlog
252         if (pick_up_ammo(CLASS_PRIMARY, VULCAN_INDEX, VULCAN_AMMO_AMOUNT)) {
253                 powerup_basic(7, 14, 21, VULCAN_AMMO_SCORE, "%s!", TXT_VULCAN_AMMO);
254                 used = 1;
255         } else {
256                 max = Primary_ammo_max[VULCAN_INDEX];
257                 if (Players[Player_num].flags & PLAYER_FLAGS_AMMO_RACK)
258                         max *= 2;
259                 HUD_init_message("%s %d %s!",TXT_ALREADY_HAVE,f2i((unsigned) VULCAN_AMMO_SCALE * (unsigned) max),TXT_VULCAN_ROUNDS);
260                 used = 0;
261         }
262         Primary_weapon = pwsave;
263
264         return used;
265 }
266
267 extern void invalidate_escort_goal(void);
268 extern char GetKeyValue(char);
269 extern void check_to_use_primary(int);
270 extern void multi_send_got_flag (char);
271
272 int Headlight_active_default=1; //is headlight on when picked up?
273 extern int PlayerMessage;
274
275 //      returns true if powerup consumed
276 int do_powerup(object *obj)
277 {
278         int used=0;
279         int special_used=0;             //for when hitting vulcan cannon gets vulcan ammo
280         char temp_string[50];
281         int id=obj->id;
282
283         if ((Player_is_dead) || (ConsoleObject->type == OBJ_GHOST) || (Players[Player_num].shields < 0))
284                 return 0;
285
286         if (obj->ctype.powerup_info.creation_time > GameTime)           //gametime wrapped!
287                 obj->ctype.powerup_info.creation_time = 0;                              //allow player to pick up
288
289         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))
290                 return 0;               //not enough time elapsed
291
292         PlayerMessage=0;        //      Prevent messages from going to HUD if -PlayerMessages switch is set
293
294         switch (obj->id) {
295                 case POW_EXTRA_LIFE:
296                         Players[Player_num].lives++;
297                         powerup_basic(15, 15, 15, 0, TXT_EXTRA_LIFE);
298                         used=1;
299                         break;
300                 case POW_ENERGY:
301                         used = pick_up_energy();
302                         break;
303                 case POW_SHIELD_BOOST:
304                         if (Players[Player_num].shields < MAX_SHIELDS) {
305                                 fix boost = 3*F1_0 + 3*F1_0*(NDL - Difficulty_level);
306                                 if (Difficulty_level == 0)
307                                         boost += boost/2;
308                                 Players[Player_num].shields += boost;
309                                 if (Players[Player_num].shields > MAX_SHIELDS)
310                                         Players[Player_num].shields = MAX_SHIELDS;
311                                 powerup_basic(0, 0, 15, SHIELD_SCORE, "%s %s %d",TXT_SHIELD,TXT_BOOSTED_TO,f2ir(Players[Player_num].shields));
312                                 used=1;
313                         } else
314                                 HUD_init_message(TXT_MAXED_OUT,TXT_SHIELD);
315                         break;
316                 case POW_LASER:
317                         if (Players[Player_num].laser_level >= MAX_LASER_LEVEL) {
318                                 //Players[Player_num].laser_level = MAX_LASER_LEVEL;
319                                 HUD_init_message(TXT_MAXED_OUT,TXT_LASER);
320                         } else {
321                                 if (Newdemo_state == ND_STATE_RECORDING)
322                                         newdemo_record_laser_level(Players[Player_num].laser_level, Players[Player_num].laser_level + 1);
323                                 Players[Player_num].laser_level++;
324                                 powerup_basic(10, 0, 10, LASER_SCORE, "%s %s %d",TXT_LASER,TXT_BOOSTED_TO, Players[Player_num].laser_level+1);
325                                 update_laser_weapon_info();
326                                 pick_up_primary (LASER_INDEX);
327                                 used=1;
328                         }
329                         if (!used && !(Game_mode & GM_MULTI) )
330                                 used = pick_up_energy();
331                         break;
332                 case POW_MISSILE_1:
333                         used=pick_up_secondary(CONCUSSION_INDEX,1);
334                         break;
335                 case POW_MISSILE_4:
336                         used=pick_up_secondary(CONCUSSION_INDEX,4);
337                         break;
338
339                 case POW_KEY_BLUE:
340                         if (Players[Player_num].flags & PLAYER_FLAGS_BLUE_KEY)
341                                 break;
342 #ifdef NETWORK
343                         multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
344 #endif
345                         digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
346                         Players[Player_num].flags |= PLAYER_FLAGS_BLUE_KEY;
347                         powerup_basic(0, 0, 15, KEY_SCORE, "%s %s",TXT_BLUE,TXT_ACCESS_GRANTED);
348                         if (Game_mode & GM_MULTI)
349                                 used=0;
350                         else
351                                 used=1;
352                         invalidate_escort_goal();
353                         break;
354                 case POW_KEY_RED:
355                         if (Players[Player_num].flags & PLAYER_FLAGS_RED_KEY)
356                                 break;
357 #ifdef NETWORK
358                         multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
359 #endif
360                         digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
361                         Players[Player_num].flags |= PLAYER_FLAGS_RED_KEY;
362                         powerup_basic(15, 0, 0, KEY_SCORE, "%s %s",TXT_RED,TXT_ACCESS_GRANTED);
363                         if (Game_mode & GM_MULTI)
364                                 used=0;
365                         else
366                                 used=1;
367                         invalidate_escort_goal();
368                         break;
369                 case POW_KEY_GOLD:
370                         if (Players[Player_num].flags & PLAYER_FLAGS_GOLD_KEY)
371                                 break;
372 #ifdef NETWORK
373                         multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
374 #endif
375                         digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
376                         Players[Player_num].flags |= PLAYER_FLAGS_GOLD_KEY;
377                         powerup_basic(15, 15, 7, KEY_SCORE, "%s %s",TXT_YELLOW,TXT_ACCESS_GRANTED);
378                         if (Game_mode & GM_MULTI)
379                                 used=0;
380                         else
381                                 used=1;
382                         invalidate_escort_goal();
383                         break;
384                 case POW_QUAD_FIRE:
385                         if (!(Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS)) {
386                                 Players[Player_num].flags |= PLAYER_FLAGS_QUAD_LASERS;
387                                 powerup_basic(15, 15, 7, QUAD_FIRE_SCORE, "%s!",TXT_QUAD_LASERS);
388                                 update_laser_weapon_info();
389                                 used=1;
390                         } else
391                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,TXT_QUAD_LASERS);
392                         if (!used && !(Game_mode & GM_MULTI) )
393                                 used = pick_up_energy();
394                         break;
395
396                 case    POW_VULCAN_WEAPON:
397                 case    POW_GAUSS_WEAPON: {
398                         int ammo = obj->ctype.powerup_info.count;
399
400                         used = pick_up_primary((obj->id==POW_VULCAN_WEAPON)?VULCAN_INDEX:GAUSS_INDEX);
401
402                         //didn't get the weapon (because we already have it), but
403                         //maybe snag some of the ammo.  if single-player, grab all the ammo
404                         //and remove the powerup.  If multi-player take ammo in excess of
405                         //the amount in a powerup, and leave the rest.
406                         if (! used)
407                                 if ((Game_mode & GM_MULTI) )
408                                         ammo -= VULCAN_AMMO_AMOUNT;     //don't let take all ammo
409
410                         if (ammo > 0) {
411                                 int ammo_used;
412                                 ammo_used = pick_up_ammo(CLASS_PRIMARY, VULCAN_INDEX, ammo);
413                                 obj->ctype.powerup_info.count -= ammo_used;
414                                 if (!used && ammo_used) {
415                                         powerup_basic(7, 14, 21, VULCAN_AMMO_SCORE, "%s!", TXT_VULCAN_AMMO);
416                                         special_used = 1;
417                                         id = POW_VULCAN_AMMO;           //set new id for making sound at end of this function
418                                         if (obj->ctype.powerup_info.count == 0)
419                                                 used = 1;               //say used if all ammo taken
420                                 }
421                         }
422
423                         break;
424                 }
425
426                 case    POW_SPREADFIRE_WEAPON:
427                         used = pick_up_primary(SPREADFIRE_INDEX);
428                         if (!used && !(Game_mode & GM_MULTI) )
429                                 used = pick_up_energy();
430                         break;
431                 case    POW_PLASMA_WEAPON:
432                         used = pick_up_primary(PLASMA_INDEX);
433                         if (!used && !(Game_mode & GM_MULTI) )
434                                 used = pick_up_energy();
435                         break;
436                 case    POW_FUSION_WEAPON:
437                         used = pick_up_primary(FUSION_INDEX);
438                         if (!used && !(Game_mode & GM_MULTI) )
439                                 used = pick_up_energy();
440                         break;
441
442                 case    POW_HELIX_WEAPON:
443                         used = pick_up_primary(HELIX_INDEX);
444                         if (!used && !(Game_mode & GM_MULTI) )
445                                 used = pick_up_energy();
446                         break;
447
448                 case    POW_PHOENIX_WEAPON:
449                         used = pick_up_primary(PHOENIX_INDEX);
450                         if (!used && !(Game_mode & GM_MULTI) )
451                                 used = pick_up_energy();
452                         break;
453
454                 case    POW_OMEGA_WEAPON:
455                         used = pick_up_primary(OMEGA_INDEX);
456                         if (used)
457                                 Omega_charge = obj->ctype.powerup_info.count;
458                         if (!used && !(Game_mode & GM_MULTI) )
459                                 used = pick_up_energy();
460                         break;
461
462                 case    POW_PROXIMITY_WEAPON:
463                         used=pick_up_secondary(PROXIMITY_INDEX,4);
464                         break;
465                 case    POW_SMARTBOMB_WEAPON:
466                         used=pick_up_secondary(SMART_INDEX,1);
467                         break;
468                 case    POW_MEGA_WEAPON:
469                         used=pick_up_secondary(MEGA_INDEX,1);
470                         break;
471                 case    POW_SMISSILE1_1:
472                         used=pick_up_secondary(SMISSILE1_INDEX,1);
473                         break;
474                 case    POW_SMISSILE1_4:
475                         used=pick_up_secondary(SMISSILE1_INDEX,4);
476                         break;
477                 case    POW_GUIDED_MISSILE_1:
478                         used=pick_up_secondary(GUIDED_INDEX,1);
479                         break;
480                 case    POW_GUIDED_MISSILE_4:
481                         used=pick_up_secondary(GUIDED_INDEX,4);
482                         break;
483                 case    POW_SMART_MINE:
484                         used=pick_up_secondary(SMART_MINE_INDEX,4);
485                         break;
486                 case    POW_MERCURY_MISSILE_1:
487                         used=pick_up_secondary(SMISSILE4_INDEX,1);
488                         break;
489                 case    POW_MERCURY_MISSILE_4:
490                         used=pick_up_secondary(SMISSILE4_INDEX,4);
491                         break;
492                 case    POW_EARTHSHAKER_MISSILE:
493                         used=pick_up_secondary(SMISSILE5_INDEX,1);
494                         break;
495                 case    POW_VULCAN_AMMO:
496                         used = pick_up_vulcan_ammo();
497                         break;
498                 case    POW_HOMING_AMMO_1:
499                         used=pick_up_secondary(HOMING_INDEX,1);
500                         break;
501                 case    POW_HOMING_AMMO_4:
502                         used=pick_up_secondary(HOMING_INDEX,4);
503                         break;
504                 case    POW_CLOAK:
505                         if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) {
506                                 HUD_init_message("%s %s!",TXT_ALREADY_ARE,TXT_CLOAKED);
507                                 break;
508                         } else {
509                                 Players[Player_num].cloak_time = GameTime;      //      Not! changed by awareness events (like player fires laser).
510                                 Players[Player_num].flags |= PLAYER_FLAGS_CLOAKED;
511                                 ai_do_cloak_stuff();
512                                 #ifdef NETWORK
513                                 if (Game_mode & GM_MULTI)
514                                         multi_send_cloak();
515                                 #endif
516                                 powerup_basic(-10,-10,-10, CLOAK_SCORE, "%s!",TXT_CLOAKING_DEVICE);
517                                 used = 1;
518                                 break;
519                         }
520                 case    POW_INVULNERABILITY:
521                         if (Players[Player_num].flags & PLAYER_FLAGS_INVULNERABLE) {
522                                 HUD_init_message("%s %s!",TXT_ALREADY_ARE,TXT_INVULNERABLE);
523                                 break;
524                         } else {
525                                 Players[Player_num].invulnerable_time = GameTime;
526                                 Players[Player_num].flags |= PLAYER_FLAGS_INVULNERABLE;
527                                 powerup_basic(7, 14, 21, INVULNERABILITY_SCORE, "%s!",TXT_INVULNERABILITY);
528                                 used = 1;
529                                 break;
530                         }
531         #ifndef RELEASE
532                 case    POW_MEGAWOW:
533                         do_megawow_powerup(50);
534                         used = 1;
535                         break;
536         #endif
537
538                 case POW_FULL_MAP:
539                         if (Players[Player_num].flags & PLAYER_FLAGS_MAP_ALL) {
540                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the FULL MAP");
541                                 if (!(Game_mode & GM_MULTI) )
542                                         used = pick_up_energy();
543                         } else {
544                                 Players[Player_num].flags |= PLAYER_FLAGS_MAP_ALL;
545                                 powerup_basic(15, 0, 15, 0, "FULL MAP!");
546                                 used=1;
547                         }
548                         break;
549
550                 case POW_CONVERTER:
551                         if (Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) {
552                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Converter");
553                                 if (!(Game_mode & GM_MULTI) )
554                                         used = pick_up_energy();
555                         } else {
556                                 Players[Player_num].flags |= PLAYER_FLAGS_CONVERTER;
557 // DPH: anyone know what the hell this is supposed to do? it's always true =)
558 /*                              if ((GetKeyValue(54))<255)
559                                  {*/
560                                         sprintf (temp_string,"Energy->Shield converter! (Press %c to use)",key_to_ascii(GetKeyValue(54)));
561                                 powerup_basic(15, 0, 15, 0, temp_string);
562 /*                               }
563                            else
564                                 powerup_basic(15, 0, 15, 0, "Energy -> shield converter!"); */
565
566
567                                 used=1;
568                         }
569                         break;
570
571                 case POW_SUPER_LASER:
572                         if (Players[Player_num].laser_level >= MAX_SUPER_LASER_LEVEL) {
573                                 Players[Player_num].laser_level = MAX_SUPER_LASER_LEVEL;
574                                 HUD_init_message("SUPER LASER MAXED OUT!");
575                         } else {
576                                 int old_level=Players[Player_num].laser_level;
577
578                                 if (Players[Player_num].laser_level <= MAX_LASER_LEVEL)
579                                         Players[Player_num].laser_level = MAX_LASER_LEVEL;
580                                 Players[Player_num].laser_level++;
581                                 if (Newdemo_state == ND_STATE_RECORDING)
582                                         newdemo_record_laser_level(old_level, Players[Player_num].laser_level);
583                                 powerup_basic(10, 0, 10, LASER_SCORE, "Super Boost to Laser level %d",Players[Player_num].laser_level+1);
584                                 update_laser_weapon_info();
585                                 if (Primary_weapon!=LASER_INDEX)
586                               check_to_use_primary (SUPER_LASER_INDEX);
587                                 used=1;
588                         }
589                         if (!used && !(Game_mode & GM_MULTI) )
590                                 used = pick_up_energy();
591                         break;
592
593                 case POW_AMMO_RACK:
594                         if (Players[Player_num].flags & PLAYER_FLAGS_AMMO_RACK) {
595                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Ammo rack");
596                                 if (!(Game_mode & GM_MULTI) )
597                                         used = pick_up_energy();
598                         }
599                         else {
600                                 Players[Player_num].flags |= PLAYER_FLAGS_AMMO_RACK;
601 #ifdef NETWORK
602                                 multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
603 #endif
604                                 digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
605                                 powerup_basic(15, 0, 15, 0, "AMMO RACK!");
606                                 used=1;
607                         }
608                         break;
609
610                 case POW_AFTERBURNER:
611                         if (Players[Player_num].flags & PLAYER_FLAGS_AFTERBURNER) {
612                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Afterburner");
613                                 if (!(Game_mode & GM_MULTI) )
614                                         used = pick_up_energy();
615                         }
616                         else {
617                                 Players[Player_num].flags |= PLAYER_FLAGS_AFTERBURNER;
618 #ifdef NETWORK
619                                 multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
620 #endif
621                                 digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
622                                 powerup_basic(15, 15, 15, 0, "AFTERBURNER!");
623                                 Afterburner_charge = f1_0;
624                                 used=1;
625                         }
626                         break;
627
628                 case POW_HEADLIGHT:
629                         if (Players[Player_num].flags & PLAYER_FLAGS_HEADLIGHT) {
630                                 HUD_init_message("%s %s!",TXT_ALREADY_HAVE,"the Headlight boost");
631                                 if (!(Game_mode & GM_MULTI) )
632                                         used = pick_up_energy();
633                         }
634                         else {
635                                 char msg[100];
636                                 Players[Player_num].flags |= PLAYER_FLAGS_HEADLIGHT;
637 #ifdef NETWORK
638                                 multi_send_play_sound(Powerup_info[obj->id].hit_sound, F1_0);
639 #endif
640                                 digi_play_sample( Powerup_info[obj->id].hit_sound, F1_0 );
641                                 sprintf(msg,"HEADLIGHT BOOST! (Headlight is %s)",Headlight_active_default?"ON":"OFF");
642                                 powerup_basic(15, 0, 15, 0, msg );
643                                 if (Headlight_active_default)
644                                         Players[Player_num].flags |= PLAYER_FLAGS_HEADLIGHT_ON;
645                                 used=1;
646 #ifdef NETWORK
647                            if (Game_mode & GM_MULTI)
648                                         multi_send_flags (Player_num);
649 #endif
650                         }
651                         break;
652
653 #ifdef NETWORK
654                 case POW_FLAG_BLUE:
655                         if (Game_mode & GM_CAPTURE)                     
656                                 if (get_team(Player_num) == TEAM_RED) {
657                                         powerup_basic(15, 0, 15, 0, "BLUE FLAG!");
658                                         Players[Player_num].flags |= PLAYER_FLAGS_FLAG;
659                                         used=1;
660                                         multi_send_got_flag (Player_num);
661                                 }
662                    break;
663
664                 case POW_HOARD_ORB:
665                         if (Game_mode & GM_HOARD)                       
666                                 if (Players[Player_num].secondary_ammo[PROXIMITY_INDEX]<12) {
667                                         powerup_basic(15, 0, 15, 0, "Orb!!!");
668                                         Players[Player_num].secondary_ammo[PROXIMITY_INDEX]++;
669                                         Players[Player_num].flags |= PLAYER_FLAGS_FLAG;
670                                         used=1;
671                                         multi_send_got_orb (Player_num);
672                                 }
673                   break;        
674
675                 case POW_FLAG_RED:
676                         if (Game_mode & GM_CAPTURE)                     
677                                 if (get_team(Player_num) == TEAM_BLUE) {
678                                         powerup_basic(15, 0, 15, 0, "RED FLAG!");
679                                         Players[Player_num].flags |= PLAYER_FLAGS_FLAG;
680                                         used=1;
681                                         multi_send_got_flag (Player_num);
682                                 }
683                    break;
684 #endif
685
686 //              case POW_HOARD_ORB:
687
688
689                 default:
690                         break;
691                 }
692
693 //always say used, until physics problem (getting stuck on unused powerup)
694 //is solved.  Note also the break statements above that are commented out
695 //!!    used=1;
696
697         if ((used || special_used) && Powerup_info[id].hit_sound  > -1 ) {
698                 #ifdef NETWORK
699                 if (Game_mode & GM_MULTI) // Added by Rob, take this out if it turns out to be not good for net games!
700                         multi_send_play_sound(Powerup_info[id].hit_sound, F1_0);
701                 #endif
702                 digi_play_sample( Powerup_info[id].hit_sound, F1_0 );
703                 detect_escort_goal_accomplished(obj-Objects);
704         }
705
706         PlayerMessage=1;
707
708         return used;
709
710 }
711
712 #ifndef FAST_FILE_IO
713 /*
714  * reads n powerup_type_info structs from a CFILE
715  */
716 extern int powerup_type_info_read_n(powerup_type_info *pti, int n, CFILE *fp)
717 {
718         int i;
719
720         for (i = 0; i < n; i++) {
721                 pti[i].vclip_num = cfile_read_int(fp);
722                 pti[i].hit_sound = cfile_read_int(fp);
723                 pti[i].size = cfile_read_fix(fp);
724                 pti[i].light = cfile_read_fix(fp);
725         }
726         return i;
727 }
728 #endif