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