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