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