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