1 /*
2 * func.c - function pointers for special extras
3 *
4 * $Id: func.c,v 1.22 2006/03/29 21:46:27 alfie Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will be entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "xblast.h"
25
26 /*
27 * global variables
28 */
29 void (*specialExtraFunc) (BMPlayer *);
30 void (*specialKeyFunc) (BMPlayer *);
31
32 /*
33 * local types
34 */
35 typedef void (*SpecialExtraFunc) (BMPlayer *);
36 typedef void (*SpecialKeyFunc) (BMPlayer *);
37 static char *seVoidName = N_("No Special Extra");
38 static char *skVoidName = N_("No Special Key");
39
40 /*
41 * void functions
42 */
43 void
SpecialExtraVoid(BMPlayer * ps)44 SpecialExtraVoid (BMPlayer * ps)
45 {
46 }
47
48 void
SpecialKeyVoid(BMPlayer * ps)49 SpecialKeyVoid (BMPlayer * ps)
50 {
51 }
52
53 /*
54 * Invincible
55 */
56 static void
SpecialExtraInvincible(BMPlayer * ps)57 SpecialExtraInvincible (BMPlayer * ps)
58 {
59 SND_Play (SND_INVINC, ps->x / (PIXW / MAX_SOUND_POSITION));
60 ps->illtime = 0;
61 ps->illness = ps->health;
62 ps->invincible += EXTRA_INVINCIBLE;
63 } /* SpecialExtraInvincible */
64
65 /*
66 * Kicking
67 */
68 static void
SpecialExtraKick(BMPlayer * ps)69 SpecialExtraKick (BMPlayer * ps)
70 {
71 SND_Play (SND_NEWKICK, ps->x / (PIXW / MAX_SOUND_POSITION));
72 ps->kick = XBTrue;
73 } /* SpecialExtraKick */
74
75 /*
76 * Remote Control
77 */
78 static void
SpecialExtraRC(BMPlayer * ps)79 SpecialExtraRC (BMPlayer * ps)
80 {
81 SND_Play (SND_NEWRC, ps->x / (PIXW / MAX_SOUND_POSITION));
82 ps->remote_control = XBTrue;
83 } /* SpecialExtraRC */
84
85 static void
SpecialKeyRC(BMPlayer * ps)86 SpecialKeyRC (BMPlayer * ps)
87 {
88 if (ps->remote_control > 0) {
89 if (IgnitePlayersBombs (ps)) {
90 SND_Play (SND_SHOOT, ps->x / (PIXW / MAX_SOUND_POSITION));
91 }
92 }
93 } /* SpecialKeyRC */
94
95 /*
96 * bombs choice extra
97 */
98 static void
SpecialExtraChoice(BMPlayer * ps)99 SpecialExtraChoice (BMPlayer * ps)
100 {
101 char tutu[40];
102 if (ps->choice_bomb_type == NUM_BMT) {
103 int i;
104 for (i = ChoiceDefaultBomb; bomb_name_choice[i] == NULL; i = ((i + 1) % NUM_BMT)) ;
105 ps->choice_bomb_type = i;
106 if (ps->local) {
107 sprintf (tutu, "%s : ", p_string[ps->id].name);
108 strcat (tutu, bomb_name_choice[(ps->choice_bomb_type)]);
109 SetMessage (tutu, XBTrue);
110 }
111 }
112 }
113
114 static void
SpecialKeyChoice(BMPlayer * ps)115 SpecialKeyChoice (BMPlayer * ps)
116 {
117
118 if (ps->choice_bomb_type != NUM_BMT) {
119 char tutu[40];
120 int i;
121 i = ps->choice_bomb_type;
122 for (i = ((i + 1) % NUM_BMT); bomb_name_choice[i] == NULL; i = ((i + 1) % NUM_BMT)) ;
123 ps->choice_bomb_type = i;
124 if (ps->local) {
125 sprintf (tutu, "%s : ", p_string[ps->id].name);
126 strcat (tutu, bomb_name_choice[(ps->choice_bomb_type)]);
127 SetMessage (tutu, XBTrue);
128
129 }
130 }
131 }
132
133 /* Written by VVL */
134 static void
SpecialKeyThrough(BMPlayer * ps)135 SpecialKeyThrough (BMPlayer * ps)
136 {
137 if ((ps->throughCount > 0) && (ps->lives > 0)) {
138 if (ps->through) {
139 ps->through = 0;
140 }
141 else {
142 ps->through = EXTRA_THROUGH_TIME;
143 ps->throughCount--;
144 }
145 }
146 }
147
148 /**/
149 /* Walk through bomb Mode */
150 /**/ static void
SpecialExtraThrough(BMPlayer * ps)151 SpecialExtraThrough (BMPlayer * ps)
152 {
153 ps->throughCount += 1;
154 }
155
156 /*
157 * Teleport
158 */
159 static void
SpecialExtraTeleport(BMPlayer * ps)160 SpecialExtraTeleport (BMPlayer * ps)
161 {
162 SND_Play (SND_NEWTELE, ps->x / (PIXW / MAX_SOUND_POSITION));
163 if (ps->teleport == 0) {
164 ps->teleport = 1;
165 }
166 } /* SpecialExtraTeleport */
167
168 static void
SpecialKeyTeleport(BMPlayer * ps)169 SpecialKeyTeleport (BMPlayer * ps)
170 {
171 if (ps->teleport == 1) {
172 ps->teleport = TELEPORT_TIME;
173 }
174 } /* SpecialKeyTeleport */
175
176 /*
177 * Frogger extra (galatius(skywalker))
178 */
179 static void
SpecialExtraFrogger(BMPlayer * ps)180 SpecialExtraFrogger (BMPlayer * ps)
181 {
182 // SND_Play (SND_NEWTELE, ps->x / (PIXW / MAX_SOUND_POSITION));
183
184 ps->frogger++;
185 } /* SpecialExtraFrogger */
186
187 static void
SpecialKeyFrogger(BMPlayer * ps)188 SpecialKeyFrogger (BMPlayer * ps)
189 {
190 if ((ps->lives > 0) && (ps->frogger) && (!ps->dying)) {
191 /* do_bell(); */
192 DoFrog (ps);
193 }
194 } /* SpecialKeyFrogger */
195
196 /*
197 * Daleif Illness (galatius(skywalker))
198 * Note that picking up this extra gets you *rid* of the daleif illness *
199 */
200 static void
SpecialExtraDaleif(BMPlayer * ps)201 SpecialExtraDaleif (BMPlayer * ps)
202 {
203 ps->daleif = 0;
204 } /* SpecialExtraDalif */
205
206 /*
207 * Extra Ignite All
208 */
209 static void
SpecialExtraIgniteAll(BMPlayer * ps)210 SpecialExtraIgniteAll (BMPlayer * ps)
211 {
212 SND_Play (SND_BUTT, ps->x / (PIXW / MAX_SOUND_POSITION));
213 IgniteAllBombs (ps);
214 } /* SpecialExtraIgniteAll */
215
216 static void
SpecialKeySpecialBomb(BMPlayer * ps)217 SpecialKeySpecialBomb (BMPlayer * ps)
218 {
219 DropBomb (ps, BMTspecial);
220 } /* SpecialKeySpecialBomb */
221
222 static void
SpecialExtraSpecialBomb(BMPlayer * ps)223 SpecialExtraSpecialBomb (BMPlayer * ps)
224 {
225 SND_Play (SND_SPBOMB, ps->x / (PIXW / MAX_SOUND_POSITION));
226 ps->special_bombs += 3;
227 } /* SpecialextraSpecialBomb */
228
229 /*
230 * Junkie (Garth again)
231 */
232 void
SpecialExtraJunkie(BMPlayer * ps)233 SpecialExtraJunkie (BMPlayer * ps)
234 {
235 SND_Play (SND_INJ, ps->x / (PIXW / MAX_SOUND_POSITION));
236 ps->junkie = MAX_JUNKIE_TIME;
237 } /* SpecialExtraJunkie */
238
239 /*
240 * Air Pump (Garth Denley)
241 */
242 static void
SpecialExtraAir(BMPlayer * ps)243 SpecialExtraAir (BMPlayer * ps)
244 {
245 SND_Play (SND_NEWPUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
246 ps->air_button = XBTrue;
247 } /* SpecialExtraAir */
248
249 static void
SpecialKeyAir(BMPlayer * ps)250 SpecialKeyAir (BMPlayer * ps)
251 {
252 if ((ps->air_button > 0) && (ps->lives > 0)) {
253 SND_Play (SND_PUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
254 DoAir (ps);
255 }
256 } /* SpecialKeyAir */
257
258 /*
259 * Sucker (Stephan Natschlaeger)
260 */
261 static void
SpecialExtraSuck(BMPlayer * ps)262 SpecialExtraSuck (BMPlayer * ps)
263 {
264 SND_Play (SND_NEWPUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
265 ps->suck_button = XBTrue;
266 } /* SpecialExtraSuck */
267
268 /*
269 * Ghost (Belgium Guys)
270 */
271 void
SpecialExtraGhost(BMPlayer * ps)272 SpecialExtraGhost (BMPlayer * ps)
273 {
274 SND_Play (SND_NEWPUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
275 ps->ghost = EXTRA_GHOST_TIME;
276
277 } /* SpecialExtraGhost */
278
279 static void
SpecialKeySuck(BMPlayer * ps)280 SpecialKeySuck (BMPlayer * ps)
281 {
282 if ((ps->suck_button > 0) && (ps->lives > 0)) {
283 SND_Play (SND_PUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
284 DoSuck (ps);
285 }
286 } /* SpecialKeySuck */
287
288 /*
289 * poison extra
290 */
291 void
SpecialExtraPoison(BMPlayer * ps)292 SpecialExtraPoison (BMPlayer * ps)
293 {
294 if (!ps->invincible) {
295 ps->dying = DEAD_TIME;
296 }
297 } /* SpecialExtraPoison */
298
299 /*
300 * spinner extra (long stunned )
301 */
302 static void
SpecialExtraLongStunned(BMPlayer * ps)303 SpecialExtraLongStunned (BMPlayer * ps)
304 {
305 SND_Play (SND_STUN, ps->x / (PIXW / MAX_SOUND_POSITION));
306 ps->stunned = STUN_TIME * 4;
307 } /* SpecialExtraLongStunned */
308
309 /*
310 * speed extra
311 */
312 static void
SpecialExtraSpeed(BMPlayer * ps)313 SpecialExtraSpeed (BMPlayer * ps)
314 {
315 SND_Play (SND_FAST, ps->x / (PIXW / MAX_SOUND_POSITION));
316 ps->illness = IllRun;
317 ps->health = IllRun;
318 ps->illtime = 0;
319 } /* SpecialExtraSpeed */
320
321 /*
322 * speed extra
323 */
324 static void
SpecialExtraSpeed2(BMPlayer * ps)325 SpecialExtraSpeed2 (BMPlayer * ps)
326 {
327 SND_Play (SND_FAST, ps->x / (PIXW / MAX_SOUND_POSITION));
328 ps->illness = IllRun;
329 ps->health = IllRun;
330 ps->illtime = 0;
331 ps->speed++;
332 } /* SpecialExtraSpeed */
333
334 /*
335 * slow extra
336 */
337 void
SpecialExtraSlow(BMPlayer * ps)338 SpecialExtraSlow (BMPlayer * ps)
339 {
340 SND_Play (SND_SLOW, ps->x / (PIXW / MAX_SOUND_POSITION));
341 ps->illness = IllSlow;
342 ps->health = IllSlow;
343 ps->illtime = 0;
344 } /* SpecialExtraSlow */
345
346 /*
347 * mayhem extra
348 */
349 static void
SpecialExtraMayhem(BMPlayer * ps)350 SpecialExtraMayhem (BMPlayer * ps)
351 {
352 SND_Play (SND_SLAY, ps->x / (PIXW / MAX_SOUND_POSITION));
353 ps->kick = XBTrue;
354 ps->illness = IllRun;
355 ps->health = IllRun;
356 ps->illtime = 0;
357 } /* SpecialExtraMayhem */
358
359 /*
360 * holy grail extra
361 */
362 static void
SpecialExtraHolyGrail(BMPlayer * ps)363 SpecialExtraHolyGrail (BMPlayer * ps)
364 {
365 SND_Play (SND_HOLY, ps->x / (PIXW / MAX_SOUND_POSITION));
366 ps->lives += KillOtherPlayers (ps->team);
367 if (ps->lives > 9) {
368 ps->lives = 9;
369 }
370 ps->invincible = NEW_INVINCIBLE;
371 ps->dying = DEAD_TIME;
372 } /* SpecialExtraHolyGrail */
373
374 /* Added by "Belgium Guys" */
375 /* steal extra */
376 /**/ static void
SpecialExtraSteal(BMPlayer * ps)377 SpecialExtraSteal (BMPlayer * ps)
378 {
379
380 ps->bombs += StealBombsOtherPlayers (ps->team);
381 ps->range += StealRangeOtherPlayers (ps->team);
382 }
383
384 /*
385 * multiple extra
386 */
387 static void
SpecialExtraLife(BMPlayer * ps)388 SpecialExtraLife (BMPlayer * ps)
389 {
390 SND_Play (SND_LIFE, ps->x / (PIXW / MAX_SOUND_POSITION));
391 if (ps->lives < 9) {
392 ps->lives++;
393 }
394 } /* SpecialExtraLife */
395
396 /*
397 * multiple extra
398 */
399 static void
SpecialExtraMultiple(BMPlayer * ps)400 SpecialExtraMultiple (BMPlayer * ps)
401 {
402 switch (GameRandomNumber (11)) {
403 case 0:
404 case 1:
405 SpecialExtraSpeed (ps);
406 break;
407 case 2:
408 case 3:
409 SpecialExtraPoison (ps);
410 break;
411 case 4:
412 case 5:
413 SpecialExtraInvincible (ps);
414 break;
415 case 6:
416 case 7:
417 SpecialExtraLongStunned (ps);
418 break;
419 case 8:
420 case 9:
421 SpecialExtraAir (ps);
422 break;
423 case 10:
424 SpecialExtraLife (ps);
425 break;
426 }
427 } /* SpecialExtraMultiple */
428
429 /*Skywalker epfl */
430
431 /* Written by VVL */
432 /* Electrify */
433 static void
SpecialExtraElectrify(BMPlayer * ps)434 SpecialExtraElectrify (BMPlayer * ps)
435 {
436 ps->electrify = EXTRA_ELECTRIFY_COUNT;
437 }
438
439 static void
SpecialKeyElectrify(BMPlayer * ps)440 SpecialKeyElectrify (BMPlayer * ps)
441 {
442 if ((ps->lives > 0) && (ps->electrify)) {
443 if (ElectrifyOtherPlayers (ps->id)) {
444 /* Success ... another player is hit! :-) */
445 ps->electrify = 0;
446 }
447 else {
448 /* Failure ... just try again! :-( */
449 ps->electrify--;
450 }
451 }
452 }
453
454 static void
SpecialExtraFarter(BMPlayer * ps)455 SpecialExtraFarter (BMPlayer * ps)
456 {
457 ps->farter = 1;
458 }
459
460 static void
SpecialKeyFarter(BMPlayer * ps)461 SpecialKeyFarter (BMPlayer * ps)
462 {
463 if (ps != NULL) {
464 if ((ps->lives > 0) && (ps->farter)) {
465 /* do_bell(); */
466 FartOnOtherPlayers (ps);
467 }
468 }
469 }
470
471 /* Fart on players and bombs (galatius) */
472
473 static void
SpecialExtraBfarter(BMPlayer * ps)474 SpecialExtraBfarter (BMPlayer * ps)
475 {
476 if (ps != NULL) {
477 ps->bfarter = 1;
478 }
479 }
480
481 /* Fart on players and bombs (galatius) */
482 static void
SpecialKeyBfarter(BMPlayer * ps)483 SpecialKeyBfarter (BMPlayer * ps)
484 {
485 if ((ps->lives > 0) && (ps->bfarter) && ps != NULL) {
486 /* do_bell(); */
487 FartOnOtherPlayers (ps);
488 DoAir (ps);
489 }
490 }
491
492 static void
SpecialExtraSwapColor(BMPlayer * ps)493 SpecialExtraSwapColor (BMPlayer * ps)
494 {
495 SwapColorOtherPlayers (ps->team);
496 }
497
498 static void
SpecialExtraSwapPosition(BMPlayer * ps)499 SpecialExtraSwapPosition (BMPlayer * ps)
500 {
501 SwapPositionOtherPlayers (ps->team);
502 }
503
504 /* */
505
506 /*
507 * cloaking device
508 */
509 static void
SpecialExtraCloak(BMPlayer * ps)510 SpecialExtraCloak (BMPlayer * ps)
511 {
512 int w = 1;
513 if (ps->cloaking < 0) {
514 ps->cloaking *= -1;
515 w = -1;
516 }
517 ps->cloaking += 2 * EXTRA_INVINCIBLE;
518 ps->cloaking *= w;
519 SND_Play (SND_NEWCLOAK, ps->x / (PIXW / MAX_SOUND_POSITION));
520 } /* SpecialExtraCloak */
521
522 static void
SpecialKeyCloak(BMPlayer * ps)523 SpecialKeyCloak (BMPlayer * ps)
524 {
525 ps->cloaking *= -1;
526 if (ps->cloaking > 0) {
527 SND_Play (SND_DECLOAK, ps->x / (PIXW / MAX_SOUND_POSITION));
528 }
529 else if (ps->cloaking < 0) {
530 SND_Play (SND_ENCLOAK, ps->x / (PIXW / MAX_SOUND_POSITION));
531 }
532 } /* SpecialKeyCloak */
533
534 /*
535 * pow extra (stun others)
536 */
537 void
SpecialExtraStunOthers(BMPlayer * ps)538 SpecialExtraStunOthers (BMPlayer * ps)
539 {
540 StunOtherPlayers (ps->team, STUN_TIME * 4);
541 }
542
543 /*
544 * morphing extra (player becomes a bomb)
545 */
546 static void
SpecialExtraMorph(BMPlayer * ps)547 SpecialExtraMorph (BMPlayer * ps)
548 {
549 ps->num_morph++;
550 }
551
552 static void
SpecialKeyMorph(BMPlayer * ps)553 SpecialKeyMorph (BMPlayer * ps)
554 {
555 if ((0 < ps->num_morph) && (0 < ps->bombs) && (!ps->morphed)) {
556 #ifdef DEBUG
557 fprintf (stderr, "Player %d morphs", ps->id);
558 #endif
559 ps->morphed = 1;
560 DropBomb (ps, BMTdefault);
561 }
562 } /* SpecialKeyMorph */
563
564 static void
SpecialExtraStop(BMPlayer * ps)565 SpecialExtraStop (BMPlayer * ps)
566 {
567
568 ps->stop = XBTrue;
569 }
570
571 static void
SpecialKeyStop(BMPlayer * ps)572 SpecialKeyStop (BMPlayer * ps)
573 {
574 if (ps->stop > 0) {
575
576 StopPlayersBombs (ps);
577 }
578 }
579
580 /* Written by Amilhastre */
581 static void
SpecialExtraEvilGrail(BMPlayer * ps)582 SpecialExtraEvilGrail (BMPlayer * ps)
583 {
584 ps->evilill = ILLDEATHTIME;
585 }
586
587 /* phantom extra */
588 /* Written by Amilhastre */
589 static void
SpecialExtraPhantom(BMPlayer * ps)590 SpecialExtraPhantom (BMPlayer * ps)
591 {
592 if (!ps->phantom)
593 ps->phantom = 3 * EXTRA_INVISIBLE;
594 else
595 ps->phantom += EXTRA_INVISIBLE;
596 }
597
598 /* revive extra */
599 /* Written by Amilhastre */
600 static void
SpecialExtraRevive(BMPlayer * ps)601 SpecialExtraRevive (BMPlayer * ps)
602 {
603 ps->revive++;
604 }
605
606 /* ** Skywalker **
607 * sniping extra (player moves the bomb)
608 */
609 static void
SpecialExtraSnipe(BMPlayer * ps)610 SpecialExtraSnipe (BMPlayer * ps)
611 {
612 ps->num_snipe++;
613 }
614
615 static void
SpecialKeySnipe(BMPlayer * ps)616 SpecialKeySnipe (BMPlayer * ps)
617 {
618 if ((0 < ps->num_snipe) && (0 < ps->bombs) && (ps->sniping == 0)) {
619
620 ps->sniping = 2;
621 DropBomb (ps, BMTdefault);
622 ps->sniping = 1;
623 }
624 else {
625 if (ps->sniping == 1) {
626 if (IgnitePlayersBombs (ps)) {
627 ps->sniping = 1;
628 ps->d_soll = GoStop;
629 }
630 }
631 }
632
633 } /* SpecialKeySnipe */
634
635 /* EPFL */
636
637 static void
SpecialExtraJump(BMPlayer * ps)638 SpecialExtraJump (BMPlayer * ps)
639 {
640 SND_Play (SND_NEWPUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
641 ps->jump_button += 1;
642 }
643
644 static void
SpecialKeyJump(BMPlayer * ps)645 SpecialKeyJump (BMPlayer * ps)
646 {
647 if ((ps->jump_button > 0) && (ps->lives > 0)) {
648 SND_Play (SND_PUMP, ps->x / (PIXW / MAX_SOUND_POSITION));
649 DoJump (ps);
650 }
651 }
652
653 /* END EPFL */
654
655 /*
656 * conversion tables
657 */
658 /* extra pickup functions */
659 static DBToData extraTable[] = {
660 {"air", (void *)SpecialExtraAir},
661 {"bfarter", (void *)SpecialExtraBfarter}, /* skywalker */
662 {"choicebombtype", (void *)SpecialExtraChoice}, /* skywalker */
663 {"cloak", (void *)SpecialExtraCloak},
664 {"daleif", (void *)SpecialExtraDaleif},
665 {"electrify", (void *)SpecialExtraElectrify},
666 {"evilgrail", (void *)SpecialExtraEvilGrail},
667 {"farter", (void *)SpecialExtraFarter}, /* skywalker */
668 {"frogger", (void *)SpecialExtraFrogger}, /* skywalker */
669 {"ghost", (void *)SpecialExtraGhost}, /* skywalker */
670 {"holyGrail", (void *)SpecialExtraHolyGrail},
671 {"igniteAll", (void *)SpecialExtraIgniteAll},
672 {"invincible", (void *)SpecialExtraInvincible},
673 {"jump", (void *)SpecialExtraJump}, /* skywalker */
674 {"junkie", (void *)SpecialExtraJunkie},
675 {"kick", (void *)SpecialExtraKick},
676 {"life", (void *)SpecialExtraLife},
677 {"longStunned", (void *)SpecialExtraLongStunned},
678 {"mayhem", (void *)SpecialExtraMayhem},
679 {"morph", (void *)SpecialExtraMorph},
680 {"multiple", (void *)SpecialExtraMultiple},
681 {"phantom", (void *)SpecialExtraPhantom},
682 {"poison", (void *)SpecialExtraPoison},
683 {"rc", (void *)SpecialExtraRC},
684 {"revive", (void *)SpecialExtraRevive},
685 {"slow", (void *)SpecialExtraSlow},
686 {"snipe", (void *)SpecialExtraSnipe}, /* skywalker */
687 {"specialBomb", (void *)SpecialExtraSpecialBomb},
688 {"speed", (void *)SpecialExtraSpeed},
689 {"speed2", (void *)SpecialExtraSpeed2},
690 {"steal", (void *)SpecialExtraSteal},
691 {"stop", (void *)SpecialExtraStop},
692 {"stunOthers", (void *)SpecialExtraStunOthers},
693 {"sucker", (void *)SpecialExtraSuck},
694 {"swapcolor", (void *)SpecialExtraSwapColor}, /* skywalker */
695 {"swapposition", (void *)SpecialExtraSwapPosition}, /* skywalker */
696 {"teleport", (void *)SpecialExtraTeleport},
697 {"through", (void *)SpecialExtraThrough},
698 {"void", (void *)SpecialExtraVoid},
699 {NULL, NULL}
700 };
701
702 /* extra key functions */
703 static DBToData keyTable[] = {
704 {"air", (void *)SpecialKeyAir},
705 {"bfarter", (void *)SpecialKeyBfarter},
706 {"choicebombtype", (void *)SpecialKeyChoice}, /* skywalker */
707 {"cloak", (void *)SpecialKeyCloak},
708 {"electrify", (void *)SpecialKeyElectrify},
709 {"farter", (void *)SpecialKeyFarter}, /* skywalker */
710 {"frogger", (void *)SpecialKeyFrogger}, /* skywalker */
711 {"jump", (void *)SpecialKeyJump}, /* skywalker */
712 {"morph", (void *)SpecialKeyMorph},
713 {"rc", (void *)SpecialKeyRC},
714 {"snipe", (void *)SpecialKeySnipe}, /* skywalker */
715 {"specialBomb", (void *)SpecialKeySpecialBomb},
716 {"stop", (void *)SpecialKeyStop},
717 {"sucker", (void *)SpecialKeySuck},
718 {"teleport", (void *)SpecialKeyTeleport},
719 {"through", (void *)SpecialKeyThrough},
720 {"void", (void *)SpecialKeyVoid},
721 {NULL, NULL}
722 };
723
724 /*
725 * parse func section of level data
726 */
727 XBBool
ParseLevelFunc(const DBSection * section,DBSection * warn)728 ParseLevelFunc (const DBSection * section, DBSection * warn)
729 {
730 void *ptr;
731 /* check if section exists */
732 if (NULL == section) {
733 Dbg_Out ("LEVEL: func section is missing!\n");
734 DB_CreateEntryString (warn, atomMissing, "true");
735 return XBFalse;
736 }
737 /* Extra has default */
738 switch (DB_ConvertEntryData (section, atomExtra, &ptr, extraTable)) {
739 case DCR_NoSuchEntry:
740 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomExtra));
741 specialExtraFunc = SpecialExtraVoid;
742 break;
743 case DCR_Failure:
744 Dbg_Out ("LEVEL: warning for %s\n", DB_SectionEntryString (section, atomExtra));
745 specialExtraFunc = SpecialExtraVoid;
746 DB_CreateEntryString (warn, atomExtra, DB_DataToString (extraTable, specialExtraFunc));
747 break;
748 default:
749 assert (ptr != NULL);
750 specialExtraFunc = (SpecialExtraFunc) ptr;
751 break;
752 }
753 /* check for swap extras, buggy for < 2.10.2 */
754 if (!Version_AtLeast (VERSION_JOINT, &Ver_2_10_2)) {
755 if (specialExtraFunc == SpecialExtraSwapColor) {
756 /* add warning and reject level */
757 DB_CreateEntryString (warn, atomExtra, DB_DataToString (extraTable, specialExtraFunc));
758 return XBFalse;
759 }
760 }
761 /* Key has default */
762 switch (DB_ConvertEntryData (section, atomKey, &ptr, keyTable)) {
763 case DCR_NoSuchEntry:
764 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomKey));
765 specialKeyFunc = SpecialKeyVoid;
766 break;
767 case DCR_Failure:
768 Dbg_Out ("LEVEL: warning for %s\n", DB_SectionEntryString (section, atomKey));
769 specialKeyFunc = SpecialKeyVoid;
770 DB_CreateEntryString (warn, atomExtra, DB_DataToString (keyTable, specialKeyFunc));
771 break;
772 default:
773 assert (ptr != NULL);
774 specialKeyFunc = (SpecialKeyFunc) ptr;
775 break;
776 }
777 return XBTrue;
778 }
779
780 /*
781 * config section [FUNC]
782 */
783 void
ConfigLevelFunc(const DBSection * section)784 ConfigLevelFunc (const DBSection * section)
785 {
786 /* set extra info */
787 if (specialExtraFunc == SpecialExtraAir) {
788 AddExtraInfo (N_("Airpump as an extra"));
789 }
790 else if (specialExtraFunc == SpecialExtraBfarter) { /* skywalker */
791 AddExtraInfo (N_("Bfarter as an extra"));
792 }
793 else if (specialExtraFunc == SpecialExtraChoice) { /* skywalker */
794 AddExtraInfo (N_("Choice as an extra"));
795 }
796 else if (specialExtraFunc == SpecialExtraCloak) {
797 AddExtraInfo (N_("Cloak as an extra"));
798 }
799 else if (specialExtraFunc == SpecialExtraDaleif) {
800 AddExtraInfo (N_("Daleif as an extra"));
801 }
802 else if (specialExtraFunc == SpecialExtraElectrify) {
803 AddExtraInfo (N_("Electrify as an extra"));
804 }
805 else if (specialExtraFunc == SpecialExtraFarter) { /* skywalker */
806 AddExtraInfo (N_("Farter as an extra"));
807 }
808 else if (specialExtraFunc == SpecialExtraFrogger) { /* skywalker */
809 AddExtraInfo (N_("Frogger as an extra"));
810 }
811 else if (specialExtraFunc == SpecialExtraGhost) { /* skywalker */
812 AddExtraInfo (N_("Ghost as an extra"));
813 }
814 else if (specialExtraFunc == SpecialExtraHolyGrail) {
815 AddExtraInfo (N_("The Holy Grail as an extra"));
816 }
817 else if (specialExtraFunc == SpecialExtraIgniteAll) {
818 AddExtraInfo (N_("Button as an extra"));
819 }
820 else if (specialExtraFunc == SpecialExtraInvincible) {
821 AddExtraInfo (N_("Invincibility as an extra"));
822 }
823 else if (specialExtraFunc == SpecialExtraJump) {
824 AddExtraInfo (N_("Jump as an extra"));
825 }
826 else if (specialExtraFunc == SpecialExtraJunkie) {
827 AddExtraInfo (N_("Junkie virus as an extra"));
828 }
829 else if (specialExtraFunc == SpecialExtraKick) {
830 AddExtraInfo (N_("Kick as an extra"));
831 }
832 else if (specialExtraFunc == SpecialExtraLife) {
833 AddExtraInfo (N_("Free life as an extra"));
834 }
835 else if (specialExtraFunc == SpecialExtraLongStunned) {
836 AddExtraInfo (N_("Spinner as an extra"));
837 }
838 else if (specialExtraFunc == SpecialExtraMayhem) {
839 AddExtraInfo (N_("Mayhem (Kick & Run) as an extra"));
840 }
841 else if (specialExtraFunc == SpecialExtraMorph) {
842 AddExtraInfo (N_("Morphing as an extra"));
843 }
844 else if (specialExtraFunc == SpecialExtraMultiple) {
845 AddExtraInfo (N_("Random special extra"));
846 }
847 else if (specialExtraFunc == SpecialExtraPhantom) {
848 AddExtraInfo (N_("Phantom as an extra"));
849 }
850 else if (specialExtraFunc == SpecialExtraPoison) {
851 AddExtraInfo (N_("Poison as an extra"));
852 }
853 else if (specialExtraFunc == SpecialExtraRC) {
854 AddExtraInfo (N_("Remote control as an extra"));
855 }
856 else if (specialExtraFunc == SpecialExtraRevive) {
857 AddExtraInfo (N_("Revive control as an extra"));
858 }
859 else if (specialExtraFunc == SpecialExtraSnipe) { /* skywalker */
860 AddExtraInfo (N_("Snipe as an extra"));
861 }
862 else if (specialExtraFunc == SpecialExtraStop) { /* skywalker */
863 AddExtraInfo (N_("Stop as an extra"));
864 }
865 else if (specialExtraFunc == SpecialExtraSuck) { /* skywalker */
866 AddExtraInfo (N_("Sucker as an extra"));
867 }
868 else if (specialExtraFunc == SpecialExtraSwapColor) { /* skywalker */
869 AddExtraInfo (N_("Swapcolor as an extra"));
870 }
871 else if (specialExtraFunc == SpecialExtraSwapPosition) { /* skywalker */
872 AddExtraInfo (N_("Swapposition as an extra"));
873 }
874 else if (specialExtraFunc == SpecialExtraSlow) {
875 AddExtraInfo (N_("Slowdown as an extra"));
876 }
877 else if (specialExtraFunc == SpecialExtraSpeed) {
878 AddExtraInfo (N_("Speed as an extra"));
879 }
880 else if (specialExtraFunc == SpecialExtraSpeed2) {
881 AddExtraInfo (N_("SpeedII as an extra"));
882 }
883 else if (specialExtraFunc == SpecialExtraStop) {
884 AddExtraInfo (N_("Stop as an extra"));
885 }
886 else if (specialExtraFunc == SpecialExtraStunOthers) {
887 AddExtraInfo (N_("Stunner as an extra"));
888 }
889 else if (specialExtraFunc == SpecialExtraTeleport) {
890 AddExtraInfo (N_("Teleporter as an extra"));
891 }
892 else if (specialExtraFunc == SpecialExtraThrough) {
893 AddExtraInfo (N_("Through as an extra"));
894 }
895 } /* ConfigLevelFunc */
896
897 /*
898 *
899 */
900 XBBool
HasSpecialBombs(void)901 HasSpecialBombs (void)
902 {
903 return (specialExtraFunc == SpecialExtraSpecialBomb);
904 } /* HasSpecialBombs */
905
906 /*
907 * return the name of the extra type
908 */
909 const char *
GetExtraNameFunc(void * type)910 GetExtraNameFunc (void *type)
911 {
912 int i;
913 if (type == SpecialExtraVoid)
914 return seVoidName;
915 for (i = 0; extraTable[i].value != NULL; ++i)
916 if (extraTable[i].value == type)
917 return extraTable[i].key;
918 return seVoidName;
919 }
920 const char *
GetExtraNameInt(int type)921 GetExtraNameInt (int type)
922 {
923 int i;
924 for (i = 0; extraTable[i].value != NULL; ++i)
925 if (i == type)
926 return extraTable[i].key;
927 return seVoidName;
928 }
929
930 /*
931 * return the name of the key type
932 */
933 const char *
GetKeyNameFunc(void * type)934 GetKeyNameFunc (void *type)
935 {
936 int i;
937 if (type == SpecialKeyVoid)
938 return skVoidName;
939 for (i = 0; keyTable[i].value != NULL; ++i)
940 if (keyTable[i].value == type)
941 return keyTable[i].key;
942 return skVoidName;
943 }
944 const char *
GetKeyNameInt(int type)945 GetKeyNameInt (int type)
946 {
947 int i;
948 for (i = 0; keyTable[i].value != NULL; ++i)
949 if (i == type)
950 return keyTable[i].key;
951 return skVoidName;
952 }
953
954 /*
955 * return the number of the key type
956 */
957 int
GetNumberOfKeys(void)958 GetNumberOfKeys (void)
959 {
960 int i;
961 for (i = 0; keyTable[i].value != NULL; ++i) ;
962 return i;
963 }
964
965 /*
966 * return the number of the extra type
967 */
968 int
GetNumberOfExtras(void)969 GetNumberOfExtras (void)
970 {
971 int i;
972 for (i = 0; extraTable[i].value != NULL; ++i) ;
973 return i;
974 }
975
976 /*
977 * end of file func.c
978 */
979