1 /*
2 * file player.c - ingame player mangment
3 *
4 * $Id: player.c,v 1.48 2006/06/13 11:11:27 fzago 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 * local constants
28 */
29 #define BOMB_STEP 2
30 #define STEP_HORI BASE_X
31 #define STEP_VERT BASE_Y
32
33 #define MAX_RANGE 10
34 #define ILLTIME 256
35 #define ILL_X (4*BASE_X)
36 #define ILL_Y (5*BASE_Y)
37
38 #define JUNKIE_ILL_TIME (ILLTIME)
39 #define JUNKIE_STUN_TIME 12
40 #define JUNKIE_TIME_1 360
41 #define JUNKIE_TIME_2 210
42 #define JUNKIE_TIME_3 60 /* Speed */
43
44 #define NUM_TELE_TRIES 25
45
46 /*
47 * init flags for extras
48 * LF_ level start flag
49 * RF_ revive flag
50 * IF_ both of the above
51 */
52 #define IF_None 0
53 /* kick extra */
54 #define LF_Kick (1<<29)
55 #define RF_Kick (1<<30)
56 #define IF_Kick (RF_Kick|LF_Kick)
57 /* remote control */
58 #define LF_RC 1
59 #define RF_RC 2
60 //#define IF_RC 3
61 /* teleporter */
62 #define LF_Teleport 4
63 #define RF_Teleport 5
64 //#define IF_Teleport 6
65 /* airpump */
66 #define LF_Airpump 7
67 #define RF_Airpump 8
68 //#define IF_Airpump 9
69 /* cloak extra */
70 #define LF_Cloak 10
71 #define RF_Cloak 11
72 //#define IF_Cloak 12
73 /* morph extra */
74 #define LF_Morph 13
75 #define RF_Morph 14
76 //#define IF_Morph 15
77 /** Skywalker **/
78 #define LF_Snipe 16
79 #define RF_Snipe 17
80 //#define IF_Snipe 18
81 #define LF_Frogger 19
82 #define RF_Frogger 20
83 //#define IF_Frogger 21
84 #define LF_Fart 22
85 #define RF_Fart 23
86 //#define IF_Fart 24
87 #define LF_Bfart 25
88 #define RF_Bfart 26
89 //#define IF_Bfart 27
90 #define LF_Choice 28
91 #define RF_Choice 29
92 //#define IF_Choice 30
93 #define LF_Stop 31
94 #define RF_Stop 32
95 //#define IF_Stop 33
96 #define LF_Phantom 34
97 #define RF_Phantom 35
98 //#define IF_Phantom 36
99 #define LF_Electrify 37
100 #define RF_Electrify 38
101 //#define IF_Electrify 39
102
103 #define LF_Daleif 40
104 #define RF_Daleif 41
105 //#define IF_Daleif 42
106 #define LF_Suck 43
107 #define RF_Suck 44
108 //#define IF_Suck 45
109
110 /* revive extra */
111 #define LF_Revive 46
112 #define RF_Revive 47
113 //#define IF_Revive (RF_Revive|LF_Revive)
114 #define LF_Jump 48
115 #define RF_Jump 49
116 //#define IF_Revive (RF_Revive|LF_Revive)
117
118 #define LF_Reverse2 50
119 #define RF_Reverse2 51
120 #define LF_Through 52
121 #define RF_Through 53
122 /** **/
123 #define NUM_IF 12
124
125 /*
126 * global variables
127 */
128 BMPlayer player_stat[2 * MAX_PLAYER];
129 PlayerStrings p_string[2 * MAX_PLAYER];
130
131 /*
132 * extern variables
133 */
134 extern void (*special_extra_function) (void);
135
136 /*
137 * local variables - retrieved from level data
138 */
139 static int minRange;
140 static int minBombs;
141 static int recLives;
142 static int specialBombs;
143 static int reviveHealth;
144 static int initHealth;
145 static unsigned initFlags;
146 static unsigned revFlags;
147 static BMPosition pos0[MAX_PLAYER];
148 static int pos0Shuffle[MAX_PLAYER];
149 static int pos0Cnt;
150 static int playersAllowed;
151
152 /*
153 * local variables - defined by game data
154 */
155 static XBBool randomPlayerPos;
156 static XBBool ifRecLives;
157 static int maxLives;
158 static int numPlayer;
159
160 /*
161 * local variables - for final setup
162 */
163 static BMPosition pos[MAX_PLAYER];
164 static unsigned iniplayerflags;
165 static unsigned revplayerflags;
166
167 #if 0
168 static int game_mode;
169 #endif
170
171 /* conversion tables */
172 static DBToInt healthTable[] = {
173 {"bomb", (int)IllBomb},
174 {"empty", (int)IllEmpty},
175 {"healthy", (int)Healthy},
176 {"invisible", (int)IllInvisible},
177 {"malfunction", (int)IllMalfunction},
178 {"mini", (int)IllMini},
179 {"reverse", (int)IllReverse},
180 {"reverse2", (int)IllReverse2},
181 {"run", (int)IllRun},
182 {"slow", (int)IllSlow},
183 {"teleport", (int)IllTeleport},
184 {NULL, -1},
185 };
186 static DBToInt initFlagsTable[] = {
187 {"airpump", LF_Airpump},
188 {"bfarter", LF_Bfart},
189 {"choicebombtype", LF_Choice}, /* skywalker */
190 {"cloak", LF_Cloak},
191 {"daleif", LF_Daleif},
192 {"electrify", LF_Electrify},
193 {"farter", LF_Fart}, /* skywalker */
194 {"frogger", LF_Frogger}, /* skywalker */
195 {"jump", LF_Jump}, /* skywalker */
196 {"kick", LF_Kick},
197 {"morph", LF_Morph},
198 {"none", 0},
199 {"phantom", LF_Phantom},
200 {"rc", LF_RC},
201 {"revive", LF_Revive},
202 {"snipe", LF_Snipe}, /** Skywalker **/
203 {"stop", LF_Stop},
204 {"sucker", LF_Suck},
205 {"teleport", LF_Teleport},
206 {"through", LF_Through},
207 {NULL, -1},
208 };
209 static DBToInt reviveFlagsTable[] = {
210 {"airpump", RF_Airpump},
211 {"bfarter", RF_Bfart},
212 {"choicebombtype", RF_Choice}, /* skywalker */
213 {"cloak", RF_Cloak},
214 {"daleif", RF_Daleif},
215 {"electrify", RF_Electrify},
216 {"farter", RF_Fart}, /* skywalker */
217 {"frogger", RF_Frogger}, /* skywalker */
218 {"jump", RF_Jump}, /* skywalker */
219 {"kick", RF_Kick},
220 {"morph", RF_Morph},
221 {"none", 0},
222 {"phantom", RF_Phantom},
223 {"rc", RF_RC},
224 {"revive", RF_Revive},
225 {"snipe", RF_Snipe}, /** Skywalker **/
226 {"stop", RF_Stop},
227 {"sucker", RF_Suck},
228 {"teleport", RF_Teleport},
229 {"through", RF_Through},
230 {NULL, -1},
231 };
232
233 /* info text data */
234 static const char *permHealthInfo[MAX_ILL] = {
235 NULL,
236 N_("Permanent random bombing"),
237 N_("Permanent slowdown"),
238 N_("Permanent running"),
239 N_("Permanent mini bombs"),
240 N_("No bomb while healthy"),
241 N_("Permanent invisibility"),
242 N_("Permanent malfunctions"),
243 N_("Permanent reverse controls"),
244 N_("Permanent reverse(2) controls"),
245 N_("Permanent random teleporting"),
246 };
247 static const char *initHealthInfo[MAX_ILL] = {
248 NULL,
249 N_("Initial random bombing"),
250 N_("Initial slowdown"),
251 N_("Initial running"),
252 N_("Initial mini bombs"),
253 N_("No bomb while healthy"),
254 N_("Initial invisibility"),
255 N_("Initial malfunctions"),
256 N_("Initial reverse controls"),
257 N_("Initial reverse(2) controls"),
258 N_("Initial random teleporting"),
259 };
260 static const char *reviveHealthInfo[MAX_ILL] = {
261 NULL,
262 N_("Revived with random bombing"),
263 N_("Revived with slowdown"),
264 N_("Revived with running"),
265 N_("Revived with mini bombs"),
266 N_("Revived with bombs while healthy"),
267 N_("Revived with invisibility"),
268 N_("Revived with malfunctions"),
269 N_("Revived with reverse controls"),
270 N_("Revived with reverse(2) controls"),
271 N_("Revived with random teleporting"),
272 };
273
274 /*
275 * parse player section in level data
276 */
277 XBBool
ParseLevelPlayers(const DBSection * section,unsigned gameMode,DBSection * warn)278 ParseLevelPlayers (const DBSection * section, unsigned gameMode, DBSection * warn)
279 {
280 int i, k;
281 /* check existence of section */
282 if (NULL == section) {
283 Dbg_Out ("LEVEL: player section is missing!\n");
284 DB_CreateEntryString (warn, atomMissing, "true");
285 return XBFalse;
286 }
287 /* Bombs entry is required */
288 if (!DB_GetEntryInt (section, atomBombs, &minBombs)) {
289 Dbg_Out ("LEVEL: critical failure, %s\n", DB_SectionEntryString (section, atomBombs));
290 DB_CreateEntryString (warn, atomBombs, "missing!");
291 return XBFalse;
292 }
293 /* Range entry is required */
294 if (!DB_GetEntryInt (section, atomRange, &minRange)) {
295 Dbg_Out ("LEVEL: critical failure, %s\n", DB_SectionEntryString (section, atomRange));
296 DB_CreateEntryString (warn, atomRange, "missing!");
297 return XBFalse;
298 }
299 /* RecLives has default */
300 if (!DB_GetEntryInt (section, atomRecLives, &recLives)) {
301 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomRecLives));
302 recLives = 0;
303 }
304 /* SpecialBombs has default */
305 if (!DB_GetEntryInt (section, atomSpecialBombs, &specialBombs)) {
306 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomSpecialBombs));
307 specialBombs = 0;
308 }
309 /* ReviveVirus has default */
310 switch (DB_ConvertEntryInt (section, atomReviveVirus, (int *)&reviveHealth, healthTable)) {
311 case DCR_NoSuchEntry:
312 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomReviveVirus));
313 reviveHealth = Healthy;
314 break;
315 case DCR_Failure:
316 Dbg_Out ("LEVEL: warning for %s\n", DB_SectionEntryString (section, atomReviveVirus));
317 reviveHealth = Healthy;
318 DB_CreateEntryString (warn, atomReviveVirus, DB_IntToString (healthTable, reviveHealth));
319 break;
320 default:
321 break;
322 }
323 /* InitVirus has default */
324 switch (DB_ConvertEntryInt (section, atomInitVirus, (int *)&initHealth, healthTable)) {
325 case DCR_NoSuchEntry:
326 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomInitVirus));
327 initHealth = Healthy;
328 break;
329 case DCR_Failure:
330 Dbg_Out ("LEVEL: warning %s\n", DB_SectionEntryString (section, atomInitVirus));
331 initHealth = Healthy;
332 DB_CreateEntryString (warn, atomInitVirus, DB_IntToString (healthTable, initHealth));
333 break;
334 default:
335 break;
336 }
337 /* InitExtra has default */
338 switch (DB_ConvertEntryFlags (section, atomInitExtra, &initFlags, initFlagsTable)) {
339 case DCR_NoSuchEntry:
340 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomInitExtra));
341 initFlags = 0;
342 break;
343 case DCR_Failure:
344 Dbg_Out ("LEVEL: warning for %s\n", DB_SectionEntryString (section, atomInitExtra));
345 initFlags = 0;
346 DB_CreateEntryString (warn, atomInitExtra, DB_IntToString (initFlagsTable, initFlags));
347 break;
348 default:
349 break;
350 }
351 /* ReviveExtra has default */
352 switch (DB_ConvertEntryFlags (section, atomReviveExtra, &revFlags, reviveFlagsTable)) {
353 case DCR_NoSuchEntry:
354 Dbg_Level ("default for %s\n", DB_SectionEntryString (section, atomReviveExtra));
355 revFlags = 0;
356 break;
357 case DCR_Failure:
358 Dbg_Out ("LEVEL: warning for %s\n", DB_SectionEntryString (section, atomReviveExtra));
359 revFlags = 0;
360 DB_CreateEntryString (warn, atomReviveExtra, DB_IntToString (reviveFlagsTable, revFlags));
361 break;
362 default:
363 break;
364 }
365 /* retrieve all player positions, count them */
366 k = 0;
367 for (i = 0; i < MAX_PLAYER; i++) {
368 if (DB_GetEntryPos (section, atomArrayPos0[k + 1], pos0 + k)) {
369 if ((pos0[k].x > 0) && (pos0[k].y > 0) &&
370 (pos0[k].x <= MAZE_W) && (pos0[k].y <= MAZE_H)) {
371 pos0Shuffle[k] = k;
372 k++;
373 }
374 }
375 }
376 pos0Cnt = k;
377 /* check if there are player positions */
378 if (pos0Cnt == 0) {
379 Dbg_Out ("LEVEL: critical failure, no player positions found!\n");
380 DB_CreateEntryString (warn, atomArrayPos0[0], "missing!");
381 return XBFalse;
382 }
383 Dbg_Level ("%u player positions found\n", pos0Cnt);
384 /* retrieve number of allowed players from gameMode */
385 k = 0;
386 for (i = 5; (i > 0) && (k == 0); i--) {
387 if ((gameMode & (1 << i)) != 0) {
388 k = i + 1;
389 }
390 }
391 playersAllowed = k;
392 /* check if players are allowed at all */
393 if (playersAllowed == 0) {
394 Dbg_Out ("LEVEL: critical failure, no players allowed!\n");
395 return XBFalse;
396 }
397 Dbg_Level ("%u players allowed\n", playersAllowed);
398 return XBTrue;
399 } /* ParseLevelPlayers */
400
401 /*
402 * configure players for game
403 */
404 void
ConfigLevelPlayers(const DBSection * section,XBBool allowRandomPos,unsigned gameMode)405 ConfigLevelPlayers (const DBSection * section, XBBool allowRandomPos, unsigned gameMode)
406 {
407 BMPlayer *ps;
408 int i, j, k, m;
409 int pl[MAX_PLAYER];
410 int numActive;
411 const char *s;
412
413 assert (section != NULL);
414 revplayerflags = 0;
415 iniplayerflags = 0;
416
417 /* min of allowed players and defined positions */
418 k = MIN (pos0Cnt, playersAllowed);
419 assert (k > 0);
420 /* determine number of active players and shuffle list */
421 numActive = 0;
422 for (i = 0; i < numPlayer; i++) {
423 if (!player_stat[i].in_active) {
424 pl[numActive] = i;
425 numActive++;
426 }
427 }
428 Dbg_Level ("%u of %u players are active, %u defined positions - assigning positions...\n",
429 numActive, numPlayer, pos0Cnt);
430 /* shuffle active players */
431 for (i = numActive - 1; i > 0; i--) {
432 j = GameRandomNumber (i + 1);
433 j = (j >= 0) ? j : 0;
434 j = (j >= i + 1) ? i : j;
435 m = pl[j];
436 pl[j] = pl[i];
437 pl[i] = m;
438 }
439 /* shuffle retrieved positions */
440 for (i = k - 1; i > 0; i--) {
441 j = GameRandomNumber (i + 1);
442 j = (j >= 0) ? j : 0;
443 j = (j >= i + 1) ? i : j;
444 m = pos0Shuffle[j];
445 pos0Shuffle[j] = pos0Shuffle[i];
446 pos0Shuffle[i] = m;
447 }
448 /* setup shuffled player positions */
449 for (i = 0; i < numActive; i++) {
450 if (i < k) {
451 pos[pl[i]] = pos0[pos0Shuffle[i]];
452 Dbg_Level ("active player %i on defined position %i (%i, %i)\n",
453 pl[i], pos0Shuffle[i], pos[pl[i]].x, pos[pl[i]].y);
454 }
455 else {
456 j = GameRandomNumber (k);
457 j = (j >= 0) ? j : 0;
458 j = (j >= k) ? k - 1 : j;
459 pos[pl[i]] = pos0[j];
460 Dbg_Level ("active player %i on random position %i (%i, %i)\n",
461 pl[i], j, pos[pl[i]].x, pos[pl[i]].y);
462
463 }
464 }
465 /* store positions in player stats */
466 j = 0;
467 for (i = 0; i < numPlayer; i++) {
468 ps = player_stat + i;
469 if (ps->in_active) {
470 ps->x = 0;
471 ps->y = i * BLOCK_HEIGHT;
472 SetSpriteMode (ps->sprite, SPM_UNMAPPED);
473 }
474 else {
475 ps->x = pos[i].x * BLOCK_WIDTH;
476 ps->y = (pos[i].y - 1) * BLOCK_HEIGHT;
477
478 j++;
479 }
480 }
481 /* setup other player attributes */
482 for (i = 0; i < numPlayer; i++) {
483 ps = player_stat + i;
484 /* Added by VVL (Chat) 12/11/99 : Begin */
485 ps->chatmode = 0;
486 ps->chatstring[0] = '\0';
487 ps->chatlen = 0;
488 /* Added by VVL (Chat) 12/11/99 : End */
489 ps->iniextra_flags = initFlags;
490 ps->revextra_flags = revFlags;
491 iniplayerflags = (ps->iniextra_flags & ((0xffffff) >> 2));
492 revplayerflags = (ps->revextra_flags & ((0xffffff) >> 2));
493 ps->kick = (LF_Kick & ps->iniextra_flags) ? XBTrue : XBFalse;
494 ps->invincible = NEW_INVINCIBLE;
495 ps->illness = initHealth;
496 ps->health = initHealth;
497 ps->illtime = 0;
498 ps->junkie = 0;
499 ps->ghost = 0;
500 ps->dying = 0;
501 ps->stunned = 0;
502 if (ifRecLives && recLives) {
503 ps->lives = ps->in_active ? 0 : recLives;
504 }
505 else {
506 ps->lives = ps->in_active ? 0 : maxLives;
507 }
508 ps->range = minRange;
509 ps->bombs = minBombs;
510 ps->special_bombs = specialBombs;
511 ps->jump_button = (LF_Jump == iniplayerflags) ? XBTrue : XBFalse;
512 ps->remote_control = (LF_RC == iniplayerflags) ? XBTrue : XBFalse;
513 ps->teleport = (LF_Teleport == iniplayerflags) ? XBTrue : XBFalse;
514 ps->air_button = (LF_Airpump == iniplayerflags) ? XBTrue : XBFalse;
515 ps->cloaking = (LF_Cloak == iniplayerflags) ? -GAME_TIME : 0;
516 ps->stop = (LF_Stop == iniplayerflags) ? XBTrue : XBFalse;
517 ps->phantom = (LF_Phantom == iniplayerflags) ? GAME_TIME : XBFalse;
518 ps->electrify = (LF_Electrify == iniplayerflags) ? EXTRA_ELECTRIFY_COUNT : XBFalse;
519 ps->revive = (LF_Revive == iniplayerflags) ? XBTrue : XBFalse;
520 ps->suck_button = (LF_Suck == iniplayerflags) ? XBTrue : XBFalse;
521 ps->num_extras =
522 (LF_Snipe == iniplayerflags) ? 1000 : ((LF_Morph == iniplayerflags) ? 1000 : 0);
523 ps->speed = 0;
524 ps->daleif = (LF_Daleif == iniplayerflags) ? XBTrue : XBFalse; /* Daleif illness (galatius) */
525 ps->farted = (LF_Fart == iniplayerflags) ? XBTrue : XBFalse; /* Fart counter (galatius) */
526 ps->bfarter = (LF_Bfart == iniplayerflags) ? XBTrue : XBFalse; /* Fart counter (galatius) */
527 ps->num_snipe = (LF_Snipe == iniplayerflags) ? 1000 : 0;
528 ps->num_morph = (LF_Morph == iniplayerflags) ? 1000 : 0;
529 ps->daleifing = 0;
530 ps->abort = ABORT_NONE;
531 ps->d_ist = GoStop;
532 ps->d_soll = GoStop;
533 ps->d_look = GoDown;
534 ps->morphed = XBFalse;
535 /* Written by VVL */
536 ps->through = (LF_Through == iniplayerflags) ? XBTrue : XBFalse;
537 ps->throughCount = ps->through ? 255 : 0;
538 ps->evilill = 0;
539 /** Skywalker **/
540 ps->sniping = 0;
541 ps->frogger = (LF_Frogger == iniplayerflags) ? XBTrue : XBFalse;
542 /** **/
543 if (LF_Choice == iniplayerflags) {
544 char tutu[40];
545 int h;
546 for (h = ChoiceDefaultBomb; bomb_name_choice[h] == NULL; h = ((h + 1) % NUM_BMT)) ;
547
548 ps->choice_bomb_type = h;
549 if (ps->local) {
550 sprintf (tutu, "%s : ", p_string[ps->id].name);
551 strcat (tutu, bomb_name_choice[(ps->choice_bomb_type)]);
552 SetMessage (tutu, XBTrue);
553 }
554 }
555 else {
556 ps->choice_bomb_type = NUM_BMT;
557 /* fprintf(stderr," bomb typ1 %i\n", ps->choice_bomb_type); */
558 }
559 }
560 /* set text for info screen */
561 switch (minBombs) {
562 case 0:
563 AddPlayerInfo (N_("No bomb"));
564 break;
565 case 1:
566 AddPlayerInfo (N_("1 bomb"));
567 break;
568 default:
569 /* TRANSLATORS: %d > 1 (multiple bombs only) */
570 AddPlayerInfo (N_("%d bombs"), minBombs);
571 break;
572 }
573 switch (minRange) {
574 case 0:
575 AddPlayerInfo (N_("No initial range"));
576 break;
577 case 1:
578 AddPlayerInfo (N_("Only mini bombs"));
579 break;
580 default:
581 AddPlayerInfo (N_("Initial range %d"), minRange);
582 break;
583 }
584 if (initHealth == reviveHealth) {
585 if (NULL != (s = permHealthInfo[initHealth])) {
586 AddPlayerInfo (s);
587 }
588 }
589 else {
590 if (NULL != (s = initHealthInfo[initHealth])) {
591 AddPlayerInfo (s);
592 }
593 if (NULL != (s = reviveHealthInfo[reviveHealth])) {
594 AddPlayerInfo (s);
595 }
596 }
597 if (iniplayerflags == LF_Daleif) {
598 if (revplayerflags == RF_Daleif) {
599 AddPlayerInfo (N_("Daleif as default"));
600 }
601 else {
602 AddPlayerInfo (N_("Initial Daleif"));
603 }
604 }
605 else if ((revplayerflags == RF_Daleif)) {
606 AddPlayerInfo (N_("Revived with Daleif"));
607 }
608 if (iniplayerflags == LF_RC) {
609 if (revplayerflags == RF_RC) {
610 AddPlayerInfo (N_("Remote control as default"));
611 }
612 else {
613 AddPlayerInfo (N_("Initial remote control"));
614 }
615 }
616 else if ((revplayerflags == RF_RC)) {
617 AddPlayerInfo (N_("Revived with remote control"));
618 }
619 if (iniplayerflags == LF_Jump) {
620 if (revplayerflags == RF_Jump) {
621 AddPlayerInfo (N_("Jump as default"));
622 }
623 else {
624 AddPlayerInfo (N_("Initial Jump"));
625 }
626 }
627 else if ((revplayerflags == RF_Jump)) {
628 AddPlayerInfo (N_("Revived with Jump"));
629 }
630 if (iniplayerflags == LF_Airpump) {
631 if (revplayerflags == RF_Airpump) {
632 AddPlayerInfo (N_("Airpump as default"));
633 }
634 else {
635 AddPlayerInfo (N_("Initial airpump"));
636 }
637 }
638 else if (revplayerflags == RF_Airpump) {
639 AddPlayerInfo (N_("Revived with airpump"));
640 }
641 if (iniplayerflags == LF_Cloak) {
642 if (revplayerflags == RF_Cloak) {
643 AddPlayerInfo (N_("Cloak as default"));
644 }
645 else {
646 AddPlayerInfo (N_("Initial cloak"));
647 }
648 }
649 else if (revplayerflags == RF_Cloak) {
650 AddPlayerInfo (N_("Revived with cloak"));
651 }
652 if (iniplayerflags & LF_Kick) {
653 if (revplayerflags == RF_Kick) {
654 AddPlayerInfo (N_("Initial kick"));
655 }
656 else {
657 AddPlayerInfo (N_("Initial kick"));
658 }
659 }
660 else if (revplayerflags == RF_Kick) {
661 AddPlayerInfo (N_("Revived with kick"));
662 }
663 if (iniplayerflags == LF_Morph) {
664 if (revplayerflags == RF_Morph) {
665 AddPlayerInfo (N_("Morphing as default"));
666 }
667 else {
668 AddPlayerInfo (N_("Initial morphing"));
669 }
670 }
671 else if (revplayerflags == RF_Morph) {
672 AddPlayerInfo (N_("Revived with morphing"));
673 }
674 if (iniplayerflags == LF_Through) {
675 if (revplayerflags == RF_Through) {
676 AddPlayerInfo (N_("Throughing as default"));
677 }
678 else {
679 AddPlayerInfo (N_("Initial throughing"));
680 }
681 }
682 else if (revplayerflags == RF_Through) {
683 AddPlayerInfo (N_("Revived with throughing"));
684 }
685
686 if (iniplayerflags == LF_Suck) {
687 if (revplayerflags == RF_Suck) {
688 AddPlayerInfo (N_("Sucker as default"));
689 }
690 else {
691 AddPlayerInfo (N_("Initial sucker"));
692 }
693 }
694 else if (revplayerflags == RF_Suck) {
695 AddPlayerInfo (N_("Revived with sucker"));
696 }
697 /* that's all folks */
698 } /* ConfigLevelPlayers */
699
700 /*
701 * Create Welcome messages for players at start of level
702 */
703 void
WelcomePlayers(void)704 WelcomePlayers (void)
705 {
706 int i, j, num;
707 const char *list[MAX_PLAYER];
708 const char *swap;
709
710 /* get messages */
711 for (i = 0, num = 0; i < numPlayer; i++) {
712 if (NULL != p_string[i].welcome && !player_stat[i].in_active) {
713 list[num++] = p_string[i].welcome;
714 }
715 }
716 /* shuffle them */
717 for (i = 0; i < num; i++) {
718 j = OtherRandomNumber (num);
719 swap = list[i];
720 list[i] = list[j];
721 list[j] = swap;
722 }
723 /* show them */
724 for (i = 0; i < num; i++) {
725 SetMessage (list[i], XBFalse);
726 }
727 } /* WelcomePlayers */
728
729 /*
730 *
731 */
732 int
NumSpecialBombs(void)733 NumSpecialBombs (void)
734 {
735 return specialBombs;
736 } /* NumSpecialBombs */
737
738 /*
739 * set player stat to default values
740 */
741 static void
InitPlayerStat(BMPlayer * ps,int player,int ctrl,XBPlayerTeam team,int PID,XBBool local)742 InitPlayerStat (BMPlayer * ps, int player, int ctrl, XBPlayerTeam team, int PID, XBBool local) // XBCC
743 {
744 /* set default values */
745 ps->victories = 0;
746 ps->PID = PID; // XBCC
747 ps->id = player;
748 ps->disp = local ? SPM_MAPPED : SPM_UNMAPPED;
749 ps->local = local;
750 ps->sprite = CreatePlayerSprite (ps->id, 0, 0, 0, SPM_UNMAPPED);
751 Dbg_Out (" sprite player %i %i", ((ps->sprite)->player).player, ps->id);
752 ((ps->sprite)->player).player = ps->id;
753 Dbg_Out (" new sprite player %i %i\n", ((ps->sprite)->player).player, ps->id);
754 ps->in_active = XBFalse;
755 /* evaluate team mode */
756 if (team == XBPT_None) {
757 ps->team = ps->id;
758 }
759 else {
760 ps->team = team - XBPT_None - 1;
761 }
762 } /* InitPlayerStat */
763
764 /*
765 * set all messages for given player
766 */
767 static void
InitPlayerMessages(PlayerStrings * str,const CFGPlayer * cfgPlayer)768 InitPlayerMessages (PlayerStrings * str, const CFGPlayer * cfgPlayer)
769 {
770 char tmp[128];
771
772 /* player name */
773 str->name = DupString (cfgPlayer->name);
774 assert (NULL != str->name);
775 str->tag = DupString (cfgPlayer->name);
776 assert (NULL != str->tag);
777 /* pause string */
778 sprintf (tmp, "Game paused by %s", str->name);
779 str->pause = DupString (tmp);
780 assert (NULL != str->pause);
781 /* win a level */
782 if (NULL != cfgPlayer->messages.msgWinLevel) {
783 str->winlevel = DupString (cfgPlayer->messages.msgWinLevel);
784 }
785 else {
786 sprintf (tmp, _("%s wins"), str->name);
787 str->winlevel = DupString (tmp);
788 }
789 assert (NULL != str->winlevel);
790 /* win the game */
791 if (NULL != cfgPlayer->messages.msgWinGame) {
792 str->wingame = DupString (cfgPlayer->messages.msgWinGame);
793 }
794 else {
795 str->wingame = DupString (N_("CONGRATULATIONS!"));
796 }
797 assert (NULL != str->wingame);
798 /* request abort */
799 sprintf (tmp, "Abort requested by %s", str->tag);
800 str->abort = DupString (tmp);
801 assert (NULL != str->abort);
802 /* cancel abort */
803 sprintf (tmp, "%s cancels abort", str->tag);
804 str->abortcancel = DupString (tmp);
805 assert (str->abortcancel != NULL);
806 /* loosing a life */
807 if (NULL != cfgPlayer->messages.msgLoseLife) {
808 str->loselife = DupString (cfgPlayer->messages.msgLoseLife);
809 }
810 else {
811 str->loselife = NULL;
812 }
813 /* loosing a level */
814 if (NULL != cfgPlayer->messages.msgLoseLevel) {
815 str->loselevel = DupString (cfgPlayer->messages.msgLoseLevel);
816 }
817 else {
818 str->loselevel = NULL;
819 }
820 /* gloating */
821 if (NULL != cfgPlayer->messages.msgGloat) {
822 str->gloat = DupString (cfgPlayer->messages.msgGloat);
823 }
824 else {
825 str->gloat = NULL;
826 }
827 /* laola */
828 if (NULL != cfgPlayer->messages.msgLaola) {
829 str->laola = DupString (cfgPlayer->messages.msgLaola);
830 }
831 else {
832 str->laola = NULL;
833 }
834 /* looser */
835 if (NULL != cfgPlayer->messages.msgLoser) {
836 str->loser = DupString (cfgPlayer->messages.msgLoser);
837 }
838 else {
839 str->loser = NULL;
840 }
841 /* welcome to the game */
842 if (NULL != cfgPlayer->messages.msgWelcome) {
843 str->welcome = DupString (cfgPlayer->messages.msgWelcome);
844 }
845 else {
846 str->welcome = NULL;
847 }
848 } /* InitPlayerMessages */
849
850 /*
851 *
852 */
853 void
InitPlayers(XBPlayerHost host,const CFGGame * cfgGame,const CFGPlayer * cfgPlayer)854 InitPlayers (XBPlayerHost host, const CFGGame * cfgGame, const CFGPlayer * cfgPlayer)
855 {
856 int i, j, cnt;
857 XBBool local;
858 BMPlayer *ps;
859
860 assert (NULL != cfgGame);
861 assert (NULL != cfgPlayer);
862
863 /* global settings */
864 numPlayer = cfgGame->players.num;
865 maxLives = cfgGame->setup.numLives;
866 ifRecLives = cfgGame->setup.ifRecLives;
867 randomPlayerPos = cfgGame->setup.randomPlayers;
868 cnt = 0;
869 /* player settings */
870 for (ps = player_stat, i = 0; i < cfgGame->players.num; ps++, i++) {
871 assert (ATOM_INVALID != cfgGame->players.player[i]);
872 local = (host == cfgGame->players.host[i]);
873 if (local) {
874 ps->localDisplay = cnt;
875 cnt++;
876 ps->bot = cfgGame->setup.bot;
877 }
878 else {
879 ps->localDisplay = -1;
880 ps->bot = XBFalse;
881 if (XBPT_None != cfgGame->players.team[i]) {
882 for (j = 0; j < cfgGame->players.num; j++) {
883
884 if (i != j && host == cfgGame->players.host[j]) {
885 local = local || (cfgGame->players.team[i] == cfgGame->players.team[j]);
886 }
887 }
888 }
889 }
890 ps->away = XBTrue;
891 InitPlayerStat (player_stat + i, i, i, cfgGame->players.team[i], (cfgPlayer + i)->id.PID, local); // XBCC
892 InitPlayerMessages (p_string + i, cfgPlayer + i);
893 }
894 } /* InitPlayers */
895
896 /*
897 *
898 */
899 void
FinishPlayers(void)900 FinishPlayers (void)
901 {
902 int i;
903 PlayerStrings *str;
904
905 for (i = 0; i < numPlayer; i++) {
906 str = p_string + i;
907 if (NULL != str->name) {
908 free (str->name);
909 }
910 if (NULL != str->tag) {
911 free (str->tag);
912 }
913 if (NULL != str->pause) {
914 free (str->pause);
915 }
916 if (NULL != str->winlevel) {
917 free (str->winlevel);
918 }
919 if (NULL != str->wingame) {
920 free (str->wingame);
921 }
922 if (NULL != str->loselife) {
923 free (str->loselife);
924 }
925 if (NULL != str->loselevel) {
926 free (str->loselevel);
927 }
928 if (NULL != str->gloat) {
929 free (str->gloat);
930 }
931 if (NULL != str->laola) {
932 free (str->laola);
933 }
934 if (NULL != str->loser) {
935 free (str->loser);
936 }
937 if (NULL != str->welcome) {
938 free (str->welcome);
939 }
940 if (NULL != str->abort) {
941 free (str->abort);
942 }
943 if (NULL != str->abortcancel) {
944 free (str->abortcancel);
945 }
946 }
947 numPlayer = 0;
948 } /* FinishPlayers */
949
950 /*
951 *
952 */
953 void
DeletePlayerSprites(void)954 DeletePlayerSprites (void)
955 {
956 int player;
957
958 for (player = 0; player < numPlayer; player++) {
959 DeleteSprite (player_stat[player].sprite);
960 }
961 } /* DeletePlayerSprites */
962
963 /*
964 *
965 */
966 void
DropBomb(BMPlayer * ps,int type)967 DropBomb (BMPlayer * ps, int type)
968 {
969 if ((ps->bombs != 0) && (ps->sniping != 1) && /* skywalker / koen */
970 (ps->illness != IllEmpty) &&
971 (ps->morphed < 2) &&
972 (type == BMTdefault || ps->special_bombs > 0 || ps->choice_bomb_type != NUM_BMT)) {
973 if (ps->lives > 0) {
974 if (ps->choice_bomb_type != NUM_BMT)
975 type = ps->choice_bomb_type;
976 if (NewPlayerBomb (ps, type)) {
977 SND_Play (SND_DROP, ps->x / (PIXW / MAX_SOUND_POSITION));
978 ps->bombs--;
979 if (ps->morphed) {
980 ps->morphed = 2;
981 ps->num_morph--;
982 }
983 /** Skywalker **/
984 if (ps->sniping) {
985 ps->num_snipe--;
986 }
987 /** **/
988 if (type != BMTdefault && ps->choice_bomb_type == NUM_BMT) {
989 ps->special_bombs--;
990 }
991 }
992 else {
993 if (ps->morphed) {
994 ps->morphed = 0;
995 }
996 }
997 }
998 }
999 } /* DropBomb */
1000
1001 /*
1002 *
1003 */
1004 static void
WalkStop(BMPlayer * ps,int flag,int mazex,int mazey)1005 WalkStop (BMPlayer * ps, int flag, int mazex, int mazey)
1006 {
1007 if (ps->illness != IllReverse) {
1008 if (ps->illness == IllReverse2) {
1009 switch (ps->d_look) {
1010 case GoDown:
1011 SetSpriteAnime (ps->sprite, SpriteStopLeft);
1012 break;
1013 case GoUp:
1014 SetSpriteAnime (ps->sprite, SpriteStopRight);
1015 break;
1016 case GoLeft:
1017 SetSpriteAnime (ps->sprite, SpriteStopDown);
1018 break;
1019 case GoRight:
1020 SetSpriteAnime (ps->sprite, SpriteStopUp);
1021 break;
1022 default:
1023 break;
1024 }
1025 }
1026 else {
1027 switch (ps->d_look) {
1028 case GoDown:
1029 SetSpriteAnime (ps->sprite, SpriteStopDown);
1030 break;
1031 case GoUp:
1032 SetSpriteAnime (ps->sprite, SpriteStopUp);
1033 break;
1034 case GoLeft:
1035 SetSpriteAnime (ps->sprite, SpriteStopLeft);
1036 break;
1037 case GoRight:
1038 SetSpriteAnime (ps->sprite, SpriteStopRight);
1039 break;
1040 default:
1041 break;
1042 }
1043 }
1044 }
1045 else {
1046 switch (ps->d_look) {
1047 case GoDown:
1048 SetSpriteAnime (ps->sprite, SpriteStopUp);
1049 break;
1050 case GoUp:
1051 SetSpriteAnime (ps->sprite, SpriteStopDown);
1052 break;
1053 case GoLeft:
1054 SetSpriteAnime (ps->sprite, SpriteStopRight);
1055 break;
1056 case GoRight:
1057 SetSpriteAnime (ps->sprite, SpriteStopLeft);
1058 break;
1059 default:
1060 break;
1061 }
1062 }
1063 } /* WalkStop */
1064
1065 /*
1066 *
1067 */
1068 static void
WalkUp(BMPlayer * ps,int flag,int mazex,int mazey)1069 WalkUp (BMPlayer * ps, int flag, int mazex, int mazey)
1070 {
1071 if (!(flag && CheckMazeGhost (ps->ghost, mazex, mazey - 1))
1072 ||
1073 (!((ps->phantom) ? CheckMazePhantomWall (mazex, mazey - 1) : CheckMaze (mazex, mazey - 1))
1074 && (mazey > 1))) {
1075 ps->y -= STEP_VERT;
1076 if (ps->y < 0)
1077 ps->y = PIXH - BLOCK_HEIGHT * 2; // 02-05-2002
1078 mazey = ps->y / BLOCK_HEIGHT + 1;
1079 if (ps->illness != IllReverse) {
1080 if (ps->illness == IllReverse2) {
1081 SetSpriteAnime (ps->sprite, SpriteWalkLeft0 + ((ps->y / STEP_VERT) % 4));
1082 }
1083 else {
1084 SetSpriteAnime (ps->sprite, SpriteWalkUp0 + ((ps->y / STEP_VERT) % 4));
1085 }
1086 }
1087 else {
1088 SetSpriteAnime (ps->sprite, SpriteWalkDown0 + ((ps->y / STEP_VERT) % 4));
1089 }
1090 }
1091 else {
1092 ps->d_ist = GoStop;
1093 if (ps->illness != IllReverse) {
1094 if (ps->illness == IllReverse2) {
1095 SetSpriteAnime (ps->sprite, SpriteStopLeft);
1096 }
1097 else {
1098 SetSpriteAnime (ps->sprite, SpriteStopUp);
1099 }
1100 }
1101 else {
1102 SetSpriteAnime (ps->sprite, SpriteStopDown);
1103 }
1104 }
1105
1106 /* try a kick */
1107 if (CheckBomb (mazex, mazey)
1108 && ((ps->y % BLOCK_HEIGHT) == (STEP_VERT * BOMB_STEP) && (!ps->through)) && (!ps->through)) {
1109 if (ps->kick) {
1110 SND_Play (SND_KICK, ps->x / (PIXW / MAX_SOUND_POSITION));
1111 /* added by Galatius */
1112 switch (ps->daleif & GameRandomNumber (2)) {
1113 case 0:
1114 MoveBomb (mazex, mazey, GoUp);
1115 break;
1116 case 1:
1117 ps->daleifing = DALEIF_TIME;
1118 MoveBomb (mazex, mazey, GoDown);
1119 break;
1120 } /* end added by Galatius */
1121 ps->d_soll = GoStop;
1122 }
1123 ps->y += STEP_VERT;
1124 ps->y = (ps->y + PIXH) % PIXH;
1125 }
1126 // if(oldy!=ps->y)SND_Play (SND_STEP4, ps->x / (PIXW / MAX_SOUND_POSITION));
1127 } /* WalkUp */
1128
1129 /*
1130 * local function walk_left
1131 */
1132 static void
WalkLeft(BMPlayer * ps,int flag,int mazex,int mazey)1133 WalkLeft (BMPlayer * ps, int flag, int mazex, int mazey)
1134 {
1135 if (!(flag && CheckMazeGhost (ps->ghost, mazex - 1, mazey)) ||
1136 (!((ps->phantom) ? CheckMazePhantomWall (mazex - 1, mazey) : CheckMaze (mazex - 1, mazey))
1137 && (mazex > 1))) {
1138 ps->x -= STEP_HORI;
1139 if (ps->x < 0)
1140 ps->x = PIXW; // 02-05-2002
1141 mazex = ps->x / BLOCK_WIDTH;
1142 if (ps->illness != IllReverse) {
1143 if (ps->illness == IllReverse2) {
1144 SetSpriteAnime (ps->sprite, SpriteWalkDown0 + ((ps->x / STEP_VERT) % 4));
1145 }
1146 else {
1147 SetSpriteAnime (ps->sprite, SpriteWalkLeft0 + ((ps->x / STEP_HORI) % 4));
1148 }
1149 }
1150 else {
1151 SetSpriteAnime (ps->sprite, SpriteWalkRight0 + ((ps->x / STEP_HORI) % 4));
1152 }
1153 }
1154 else {
1155 ps->d_ist = GoStop;
1156 if (ps->illness != IllReverse) {
1157 if (ps->illness == IllReverse2) {
1158 SetSpriteAnime (ps->sprite, SpriteStopDown);
1159 }
1160 else {
1161 SetSpriteAnime (ps->sprite, SpriteStopLeft);
1162 }
1163 }
1164 else {
1165 SetSpriteAnime (ps->sprite, SpriteStopRight);
1166 }
1167 }
1168
1169 /* try a kick */
1170 if (CheckBomb (mazex, mazey)
1171 && ((ps->x % BLOCK_WIDTH) == (STEP_HORI * BOMB_STEP)) && (!ps->through)) {
1172 if (ps->kick) {
1173 SND_Play (SND_KICK, ps->x / (PIXW / MAX_SOUND_POSITION));
1174 /* added by Galatius */
1175 switch (ps->daleif & GameRandomNumber (2)) {
1176 case 0:
1177
1178 MoveBomb (mazex, mazey, GoLeft);
1179 break;
1180 case 1:
1181 ps->daleifing = DALEIF_TIME;
1182 MoveBomb (mazex, mazey, GoRight);
1183
1184 break;
1185 default:
1186 break;
1187
1188 }
1189 ps->d_soll = GoStop;
1190 /* end added by Galatius */
1191 }
1192 ps->x += STEP_HORI;
1193 }
1194 // if(oldx!=ps->x)SND_Play (SND_STEP1, ps->x / (PIXW / MAX_SOUND_POSITION));
1195 } /* WalkLeft */
1196
1197 /*
1198 *
1199 */
1200 static void
WalkDown(BMPlayer * ps,int flag,int mazex,int mazey)1201 WalkDown (BMPlayer * ps, int flag, int mazex, int mazey)
1202 {
1203 if (!(flag && CheckMazeGhost (ps->ghost, mazex, mazey + 1)) ||
1204 (!((ps->phantom) ? CheckMazePhantomWall (mazex, mazey + 1) : CheckMaze (mazex, mazey + 1))
1205 && (mazey < (MAZE_H - 2)))) {
1206 ps->y += STEP_VERT;
1207 if (ps->y >= (PIXH - BLOCK_HEIGHT * 2))
1208 ps->y = 0; // 02-05-2002
1209
1210 mazey = ps->y / BLOCK_HEIGHT + 1;
1211 if (ps->illness != IllReverse) {
1212 if (ps->illness == IllReverse2) {
1213 SetSpriteAnime (ps->sprite, SpriteWalkRight0 + ((ps->y / STEP_VERT) % 4));
1214 }
1215 else {
1216 SetSpriteAnime (ps->sprite, SpriteWalkDown0 + ((ps->y / STEP_VERT) % 4));
1217 }
1218 }
1219 else {
1220 SetSpriteAnime (ps->sprite, SpriteWalkUp0 + ((ps->y / STEP_VERT) % 4));
1221 }
1222 }
1223 else {
1224 ps->d_ist = GoStop;
1225 if (ps->illness != IllReverse) {
1226 if (ps->illness == IllReverse2) {
1227 SetSpriteAnime (ps->sprite, SpriteStopRight);
1228 }
1229 else {
1230 SetSpriteAnime (ps->sprite, SpriteStopDown);
1231 }
1232 }
1233 else {
1234 SetSpriteAnime (ps->sprite, SpriteStopUp);
1235 }
1236 }
1237
1238 /* try a kick */
1239 if (CheckBomb (mazex, mazey + 1)
1240 && ((ps->y % BLOCK_HEIGHT) == (BLOCK_HEIGHT - STEP_VERT * BOMB_STEP))
1241 && (!ps->through)
1242 ) {
1243 if (ps->kick) {
1244 SND_Play (SND_KICK, ps->x / (PIXW / MAX_SOUND_POSITION));
1245 /* added by Galatius */
1246 switch (ps->daleif & GameRandomNumber (2)) {
1247 case 0:
1248 MoveBomb (mazex, mazey + 1, GoDown);
1249 break;
1250 case 1:
1251 ps->daleifing = DALEIF_TIME;
1252 MoveBomb (mazex, mazey + 1, GoUp);
1253 break;
1254 }
1255 /* end added by Galatius */
1256 ps->d_soll = GoStop;
1257 }
1258 ps->y -= STEP_VERT;
1259 }
1260 //if(oldy!=ps->y) SND_Play (SND_STEP2, ps->x / (PIXW / MAX_SOUND_POSITION));
1261 } /* WalkDown */
1262
1263 /*
1264 *
1265 */
1266 static void
WalkRight(BMPlayer * ps,int flag,int mazex,int mazey)1267 WalkRight (BMPlayer * ps, int flag, int mazex, int mazey)
1268 {
1269 if (!(flag && CheckMazeGhost (ps->ghost, mazex + 1, mazey)) ||
1270 (!((ps->phantom) ? CheckMazePhantomWall (mazex + 1, mazey) : CheckMaze (mazex + 1, mazey))
1271 && (mazex < (MAZE_W - 2)))) {
1272 ps->x += STEP_HORI;
1273 if (ps->x >= PIXW - BLOCK_WIDTH)
1274 ps->x = 0; // 02-05-2002
1275 mazex = ps->x / BLOCK_WIDTH;
1276 if (ps->illness != IllReverse) {
1277 if (ps->illness == IllReverse2) {
1278 SetSpriteAnime (ps->sprite, SpriteWalkUp0 + ((ps->x / STEP_VERT) % 4));
1279 }
1280 else {
1281 SetSpriteAnime (ps->sprite, SpriteWalkRight0 + ((ps->x / STEP_HORI) % 4));
1282 }
1283 }
1284 else {
1285 SetSpriteAnime (ps->sprite, SpriteWalkLeft0 + ((ps->x / STEP_HORI) % 4));
1286 }
1287 }
1288 else {
1289 ps->d_ist = GoStop;
1290 if (ps->illness != IllReverse) {
1291 if (ps->illness == IllReverse2) {
1292 SetSpriteAnime (ps->sprite, SpriteStopUp);
1293 }
1294 else {
1295 SetSpriteAnime (ps->sprite, SpriteStopRight);
1296 }
1297 }
1298 else {
1299 SetSpriteAnime (ps->sprite, SpriteStopLeft);
1300 }
1301 }
1302
1303 /* try kick */
1304 if (CheckBomb (mazex + 1, mazey)
1305 && ((ps->x % BLOCK_WIDTH) == (BLOCK_WIDTH - STEP_HORI * BOMB_STEP))
1306 && (!ps->through)) {
1307 if (ps->kick) {
1308 SND_Play (SND_KICK, ps->x / (PIXW / MAX_SOUND_POSITION));
1309 /* added by Galatius */
1310 switch (ps->daleif & GameRandomNumber (2)) {
1311 case 0:
1312 MoveBomb (mazex + 1, mazey, GoRight);
1313 break;
1314 case 1:
1315 ps->daleifing = DALEIF_TIME;
1316 MoveBomb (mazex + 1, mazey, GoLeft);
1317 break;
1318 }
1319 /* end added by Galatius */
1320 ps->d_soll = GoStop;
1321 }
1322 ps->x -= STEP_HORI;
1323 }
1324 // if(oldx!=ps->x)SND_Play (SND_STEP3, ps->x / (PIXW / MAX_SOUND_POSITION));
1325 } /* WalkRight */
1326
1327 /*
1328 * try to teleport player
1329 */
1330 static XBBool
TeleportPlayer(BMPlayer * ps,int mazeX,int mazeY)1331 TeleportPlayer (BMPlayer * ps, int mazeX, int mazeY)
1332 {
1333 int newMazeX, newMazeY;
1334 int i, j, n;
1335 int fs[MAZE_W * MAZE_H];
1336
1337 n = 0;
1338 for (i = 0; i < MAZE_W; i++) {
1339 for (j = 0; j < MAZE_H; j++) {
1340 if (!CheckMaze (i, j)) {
1341 fs[n] = i + j * MAZE_W;
1342 n++;
1343 }
1344 }
1345 }
1346
1347 if (n > 0) {
1348 i = fs[GameRandomNumber (n)];
1349 newMazeX = i % MAZE_W;
1350 newMazeY = i / MAZE_W;
1351 if (((ps->
1352 phantom) ? (!CheckMazePhantomWall (newMazeX, newMazeY)) : (!CheckMaze (newMazeX,
1353 newMazeY)))
1354 && ((mazeX != newMazeX) || (mazeY != newMazeY))) {
1355 SND_Play (SND_TELE1, ps->x / (PIXW / MAX_SOUND_POSITION));
1356 ps->x = newMazeX * BLOCK_WIDTH;
1357 ps->y = (newMazeY - 1) * BLOCK_HEIGHT;
1358 ps->d_soll = GoStop;
1359 ps->d_look = GoDown;
1360 SND_Play (SND_TELE2, ps->x / (PIXW / MAX_SOUND_POSITION));
1361 return XBTrue;
1362 }
1363 }
1364
1365 return XBFalse;
1366 } /* TeleportPlayer */
1367
1368 /*
1369 * local function do_walk
1370 */
1371 static void
DoWalk(BMPlayer * ps,int gameTime)1372 DoWalk (BMPlayer * ps, int gameTime)
1373 {
1374 XBBool flag;
1375 int mazeX, mazeY;
1376 int i;
1377 int xalt, yalt;
1378 int spm_mode;
1379
1380 xalt = ps->x;
1381 yalt = ps->y;
1382
1383 if (ps->illness != IllSlow || 0 == gameTime % 2) {
1384 for (i = 0; i <= (ps->illness == IllRun) * ((ps->speed == 0) ? 1 : ps->speed); i++) {
1385 flag = XBFalse;
1386 mazeX = ps->x / BLOCK_WIDTH;
1387 mazeY = ps->y / BLOCK_HEIGHT + 1;
1388
1389 if (0 == (ps->x % BLOCK_WIDTH) && 0 == (ps->y % BLOCK_HEIGHT)) {
1390 flag = XBTrue;
1391 /* check if player has deliberately teleported */
1392 if (ps->teleport == TELEPORT_TIME) {
1393 if (TeleportPlayer (ps, mazeX, mazeY)) {
1394 ps->teleport--;
1395 }
1396 }
1397 /* change direction if needed */
1398 ps->d_ist = ps->d_soll;
1399 if (ps->d_ist != GoStop) {
1400 ps->d_look = ps->d_ist;
1401 }
1402 }
1403 /* random teleporting */
1404 if ((ps->illness == IllTeleport) && (0 == GameRandomNumber (32))) {
1405 TeleportPlayer (ps, mazeX, mazeY);
1406 ps->d_ist = GoStop;
1407 ps->d_soll = GoStop;
1408 }
1409 /* let the player walk */
1410 if (ps->sniping != 1) { /* skywalker / koen */
1411 switch (ps->d_ist) {
1412 case GoStop:
1413 WalkStop (ps, flag, mazeX, mazeY);
1414 break;
1415 case GoLeft:
1416 WalkLeft (ps, flag, mazeX, mazeY);
1417 break;
1418 case GoRight:
1419 WalkRight (ps, flag, mazeX, mazeY);
1420 break;
1421 case GoDown:
1422 WalkDown (ps, flag, mazeX, mazeY);
1423 break;
1424 case GoUp:
1425 WalkUp (ps, flag, mazeX, mazeY);
1426 break;
1427 default:
1428 break;
1429 }
1430 }
1431 MoveSprite (ps->sprite, ps->x, ps->y);
1432
1433 /* insert get _extra here */
1434 if ((ps->x % BLOCK_WIDTH == 0) && (ps->y % BLOCK_HEIGHT == 0)) {
1435 switch (GetExtra (ps->invincible, ps->x / BLOCK_WIDTH, ps->y / BLOCK_HEIGHT + 1)) {
1436 case BTBomb:
1437 SND_Play (SND_NEWBOMB, ps->x / (PIXW / MAX_SOUND_POSITION));
1438 ps->bombs++;
1439 break;
1440 case BTRange:
1441 SND_Play (SND_MOREFIRE, ps->x / (PIXW / MAX_SOUND_POSITION));
1442 if (ps->range < MAX_RANGE) {
1443 ps->range++;
1444 }
1445 break;
1446 case BTSick:
1447 ps->illtime = ILLTIME;
1448 ps->illness = GameRandomNumber (MAX_ILL) + 1;
1449 if (ps->illness == IllInvisible) {
1450 SND_Play (SND_INVIS, ps->x / (PIXW / MAX_SOUND_POSITION));
1451 }
1452 else {
1453 SND_Play (SND_BAD, ps->x / (PIXW / MAX_SOUND_POSITION));
1454 }
1455 if (ps->illness == IllReverse) {
1456 switch (ps->d_ist) {
1457 case GoDown:
1458 ps->d_ist = GoUp;
1459 break;
1460 case GoUp:
1461 ps->d_ist = GoDown;
1462 break;
1463 case GoLeft:
1464 ps->d_ist = GoRight;
1465 break;
1466 case GoRight:
1467 ps->d_ist = GoLeft;
1468 break;
1469 default:
1470 break;
1471 }
1472 }
1473 if (ps->illness == IllReverse2) {
1474 switch (ps->d_ist) {
1475 case GoDown:
1476 ps->d_ist = GoLeft;
1477 break;
1478 case GoUp:
1479 ps->d_ist = GoRight;
1480 break;
1481 case GoLeft:
1482 ps->d_ist = GoUp;
1483 break;
1484 case GoRight:
1485 ps->d_ist = GoDown;
1486 break;
1487 default:
1488 break;
1489 }
1490 }
1491 break;
1492
1493 case BTSpecial:
1494 ps->num_extras++;
1495 (*specialExtraFunc) (ps);
1496 break;
1497 }
1498 }
1499 }
1500 } /*decrement phantom time */
1501 /* Written by Amilhastre */
1502 if (ps->phantom > 0) {
1503 ps->phantom--;
1504 }
1505 /* Added by "Belgium Guys" */
1506 if (ps->through) {
1507 ps->through--;
1508 }
1509 if (ps->ghost) {
1510 ps->ghost--;
1511 /* Written by VVL */
1512 if ((ps->ghost == 0) && (ps->lives > 0)) {
1513 if (CheckMaze ((ps->x / BLOCK_WIDTH), (ps->y / BLOCK_HEIGHT) + 1)) {
1514 ps->lives = 1;
1515 ps->dying = DEAD_TIME;
1516 }
1517 }
1518 }
1519 /* Skywalker */
1520 if (ps->laola) {
1521 static BMSpriteAnimation laola_animation[6] = {
1522 SpriteWinner3, SpriteWinner2, SpriteWinner,
1523 SpriteWinner, SpriteWinner2,
1524 SpriteWinner3
1525 };
1526 SetSpriteAnime (ps->sprite, laola_animation[ps->laola - 1]);
1527 ps->laola--;
1528 }
1529 else {
1530 if (ps->looser) {
1531 static BMSpriteAnimation looser_animation[10] = {
1532 SpriteLooser, SpriteLooser, SpriteLooser1, SpriteLooser1, SpriteLooser,
1533 SpriteLooser, SpriteLooser, SpriteLooser2, SpriteLooser2, SpriteLooser,
1534 };
1535 SetSpriteAnime (ps->sprite, looser_animation[ps->looser - 1]);
1536 ps->looser--;
1537 }
1538 }
1539 /* */
1540 // 02-05-2002, reinco BUG fixed
1541 if (ps->invincible > 0) {
1542 ps->invincible--;
1543 }
1544 else if (ps->teleport > 1) {
1545 ps->teleport--;
1546 }
1547
1548 /* draw player if not totally invisible or morphed */
1549 if (ps->in_active) {
1550 spm_mode = SPM_UNMAPPED;
1551 }
1552 else if (ps->illness != IllInvisible) {
1553 /* set default mode */
1554 spm_mode = SPM_MAPPED;
1555 /* first check for cloak */
1556 if (ps->cloaking < 0) {
1557 ps->cloaking++;
1558 if (ps->cloaking & 0x01) {
1559 spm_mode = ps->disp;
1560 }
1561 else {
1562 spm_mode = SPM_UNMAPPED;
1563 }
1564 }
1565 /* Added by "Belgium Guys" *//* blinking if gost_time < 64 */
1566 if ((ps->ghost < 64) && (ps->ghost)) {
1567 if (ps->ghost & 0x01) {
1568 spm_mode |= SPM_MASKED;
1569 }
1570 }
1571
1572 /* blinking if invincible */
1573 if (ps->invincible > 0) {
1574 if (ps->invincible & 0x01) {
1575 spm_mode |= SPM_MASKED;
1576 }
1577 /* or slower blinking if arrived from teleport */
1578 }
1579 else if (ps->teleport > 1) {
1580 if ((ps->teleport >> 1) & 0x01) {
1581 spm_mode |= SPM_MASKED;
1582 }
1583 }
1584 }
1585 else {
1586 spm_mode = SPM_UNMAPPED;
1587 }
1588 SetSpriteMode (ps->sprite, spm_mode);
1589
1590 /* is player still sick? */
1591 if (ps->illness != ps->health) {
1592 /* decrement illness timer */
1593 if ((ps->illtime--) == 0) {
1594 /* heal if time is over */
1595 ps->illness = ps->health;
1596 }
1597 }
1598
1599 /* drop random bombs if needed */
1600 if ((ps->x % BLOCK_WIDTH == 0) && (ps->y % BLOCK_HEIGHT == 0)) {
1601 if (ps->illness == IllBomb) {
1602 if (GameRandomNumber (4) != 0) {
1603 if (ps->choice_bomb_type != NUM_BMT)
1604 DropBomb (ps, ps->choice_bomb_type);
1605 else
1606 DropBomb (ps, BMTdefault);
1607
1608 }
1609 }
1610 }
1611 } /* DoWalk */
1612
1613 /*
1614 *
1615 */
1616 static void
DoMorph(BMPlayer * ps)1617 DoMorph (BMPlayer * ps)
1618 {
1619 SetSpriteAnime (ps->sprite, SpriteMorphed);
1620 SetSpriteMode (ps->sprite, (ps->morphed == 2) ? SPM_MAPPED : SPM_UNMAPPED);
1621 if (ps->d_soll != GoStop) {
1622 MoveBomb (ps->x / BLOCK_WIDTH, ps->y / BLOCK_HEIGHT + 1, ps->d_soll);
1623 ps->d_soll = GoStop;
1624 }
1625 } /* DoMorph */
1626
1627 /*
1628 *
1629 */
1630 void
DoJunkie(void)1631 DoJunkie (void)
1632 {
1633 BMPlayer *ps1;
1634
1635 /* Junkie countdown */
1636 for (ps1 = player_stat; ps1 < player_stat + numPlayer; ps1++) {
1637 if ((ps1->lives) && (ps1->junkie)) {
1638 /* Junkie sickness */
1639 switch (--(ps1->junkie)) {
1640 case JUNKIE_TIME_1:
1641 case JUNKIE_TIME_2:
1642 /* Give a random illness */
1643 ps1->illtime = JUNKIE_ILL_TIME;
1644 ps1->illness = GameRandomNumber (MAX_ILL) + 1;
1645 break;
1646
1647 case JUNKIE_TIME_3:
1648 /* Stun player and give speed */
1649 ps1->stunned += JUNKIE_STUN_TIME;
1650 ps1->illtime = JUNKIE_ILL_TIME;
1651 ps1->illness = IllRun;
1652 break;
1653
1654 case 0:
1655 /* Too long! Take a hit. */
1656 ps1->dying = DEAD_TIME;
1657 ps1->junkie = MAX_JUNKIE_TIME;
1658 break;
1659 }
1660 }
1661 }
1662 } /* DoJunkie */
1663
1664 /**/
1665 /* public function Electrify_other_players */
1666 /**/ int
ElectrifyOtherPlayers(int nplayer)1667 ElectrifyOtherPlayers (int nplayer)
1668 {
1669 int player;
1670 int count = 0;
1671
1672 for (player = 0; player < numPlayer; player++) {
1673 if (nplayer != player) {
1674 if (player_stat[player].lives) {
1675 if ((ABS (player_stat[player].x - player_stat[nplayer].x) < (BLOCK_WIDTH * 3 / 4))
1676 && (ABS (player_stat[player].y - player_stat[nplayer].y) <
1677 (BLOCK_HEIGHT * 3 / 4))) {
1678 player_stat[player].dying = DEAD_TIME;
1679 player_stat[player].electrify = 0;
1680 count++;
1681 }
1682 }
1683 }
1684 }
1685 return (count > 0);
1686 }
1687
1688 /*
1689 *
1690 */
1691 void
InfectOtherPlayers(int * active_player)1692 InfectOtherPlayers (int *active_player)
1693 {
1694 BMPlayer *ps1, *ps2;
1695 BMPlayer *ptr;
1696 int i, team_alive, equipe;
1697
1698 for (ps1 = player_stat; ps1 < player_stat + numPlayer; ps1++) {
1699 for (ps2 = ps1 + 1; ps2 < player_stat + numPlayer; ps2++) {
1700 if ((ABS (ps1->x - ps2->x) < ILL_X)
1701 && (ABS (ps1->y - ps2->y) < ILL_Y)) {
1702 if (ps1->lives && ps2->lives) {
1703 /* infection with "evil grail" virus */
1704
1705 if (ps1->evilill && (!ps2->invincible)) {
1706 ps1->illtime = ps1->evilill = 0;
1707 ps1->illness = ps1->health = IllRun;
1708 ps1->kick = XBTrue;
1709 ps1->invincible += BONUSEVIL;
1710 ps1->phantom += BONUSEVIL;
1711 if (ps1->cloaking > 0)
1712 ps1->cloaking = -(ps1->cloaking + BONUSEVIL);
1713 else
1714 ps1->cloaking -= BONUSEVIL;
1715 ps1->revive += 1;
1716 ps2->evilill = ILLDEATHTIME;
1717
1718 }
1719 else if (ps2->evilill && (!ps1->invincible)) {
1720 ps2->illtime = ps2->evilill = 0;
1721 ps2->illness = ps2->health = IllRun;
1722 ps2->kick = XBTrue;
1723 ps2->invincible += BONUSEVIL;
1724 ps2->phantom += BONUSEVIL;
1725 if (ps2->cloaking > 0)
1726 ps2->cloaking = -(ps2->cloaking + BONUSEVIL);
1727 else
1728 ps2->cloaking -= BONUSEVIL;
1729 ps2->revive += 1;
1730 ps1->evilill = ILLDEATHTIME;
1731 }
1732 /* infection with "normal" viruses */
1733 if (ps1->illness != ps2->illness) {
1734 if ((!ps2->invincible) && (ps1->illtime > ps2->illtime)) {
1735 ps2->illness = ps1->illness;
1736 ps2->illtime = ILLTIME;
1737 }
1738 else if ((!ps1->invincible) && (ps2->illtime > ps1->illtime)) {
1739 ps1->illness = ps2->illness;
1740 ps1->illtime = ILLTIME;
1741 }
1742 }
1743 /* infection with junkie virus */
1744 if (((ps2->junkie) && (!ps1->invincible)) || (ps1->junkie)) {
1745 ps1->junkie = MAX_JUNKIE_TIME;
1746 }
1747 if (((ps1->junkie) && (!ps2->invincible)) || (ps2->junkie)) {
1748 ps2->junkie = MAX_JUNKIE_TIME;
1749 }
1750 }
1751 else {
1752 if ((ps2->lives) && (ps1->revive)) {
1753 equipe = -1;
1754 team_alive = XBFalse;
1755 for (i = 0, ptr = player_stat; i < numPlayer; i++, ptr++) {
1756 if (ptr->team == ps1->team) {
1757 team_alive |= (ptr->lives != 0);
1758 equipe++;
1759 }
1760 }
1761
1762 if (!team_alive)
1763 (*active_player)++;
1764 ps1->lives = 1;
1765 ps1->revive--;
1766 }
1767
1768 if ((ps1->lives) && (ps2->revive)) {
1769 equipe = -1;
1770 team_alive = XBFalse;
1771 for (i = 0, ptr = player_stat; i < numPlayer; i++, ptr++) {
1772 if (ptr->team == ps2->team) {
1773 team_alive |= (ptr->lives != 0);
1774 equipe++;
1775 }
1776 }
1777
1778 if (!team_alive)
1779 (*active_player)++;
1780 ps2->lives = 1;
1781 ps2->revive--;
1782
1783 }
1784 }
1785 }
1786 }
1787 }
1788 } /* InfectOtherPlayers */
1789
1790 /*
1791 *
1792 */
1793 static void
HaveAGloat(int player)1794 HaveAGloat (int player)
1795 {
1796 int g, gloatpl, gloatpltt;
1797
1798 gloatpl = -1;
1799 for (g = 0; g < 6; g++) {
1800 gloatpltt = OtherRandomNumber (numPlayer);
1801 if (gloatpltt != player && player_stat[gloatpltt].lives > 0) {
1802 gloatpl = gloatpltt;
1803 break;
1804 }
1805 }
1806 if (gloatpl > -1) {
1807 SetMessage (p_string[gloatpl].gloat, XBFalse);
1808 }
1809 } /* HaveAGloat */
1810
1811 void
SetMsgLaola(int player)1812 SetMsgLaola (int player)
1813 {
1814 SetMessage (p_string[player].laola, XBFalse);
1815
1816 }
1817
1818 void
SetMsgLoser(int player)1819 SetMsgLoser (int player)
1820 {
1821 SetMessage (p_string[player].loser, XBFalse);
1822
1823 }
1824
1825 /* Added by Fouf on 09/02/99 22:46:25 *//* Added by "Belgium Guys" */ /**/
1826 /* local function kill_player_at_ghost */
1827 /**/ void
KillPlayerAtGhost(int block,int x,int y)1828 KillPlayerAtGhost (int block, int x, int y)
1829 {
1830 BMPlayer *ps;
1831 int player;
1832
1833 for (player = 0; player < numPlayer; player++) {
1834 ps = player_stat + player;
1835 if (!ps->ghost || block == BTVoid) {
1836 if (ps->lives > 0) {
1837 if ((ps->x < (x + 1) * BLOCK_WIDTH)
1838 && (ps->x > (x - 1) * BLOCK_WIDTH)
1839 && (ps->y < (y) * BLOCK_HEIGHT)
1840 && (ps->y > (y - 2) * BLOCK_HEIGHT)) {
1841 ps->lives = 1;
1842 ps->dying = DEAD_TIME;
1843 }
1844 }
1845 }
1846 }
1847 }
1848
1849 /*
1850 *
1851 */
1852 void
KillPlayerAt(int x,int y)1853 KillPlayerAt (int x, int y)
1854 {
1855 BMPlayer *ps;
1856 int player;
1857
1858 for (player = 0; player < numPlayer; player++) {
1859 ps = player_stat + player;
1860 /* Added by "Belgium Guys" */
1861 if (!ps->ghost) {
1862 if (ps->lives > 0) {
1863 if ((ps->x < (x + 1) * BLOCK_WIDTH)
1864 && (ps->x > (x - 1) * BLOCK_WIDTH)
1865 && (ps->y < (y) * BLOCK_HEIGHT)
1866 && (ps->y > (y - 2) * BLOCK_HEIGHT)) {
1867 ps->lives = 1;
1868 ps->dying = DEAD_TIME;
1869 }
1870 }
1871 }
1872 }
1873 } /* KillPlayerAt */
1874
1875 /*
1876 *
1877 */
1878 int
KillOtherPlayers(int team)1879 KillOtherPlayers (int team)
1880 {
1881 int count = 0;
1882 int player;
1883
1884 for (player = 0; player < numPlayer; player++) {
1885 if ((player_stat[player].team != team)
1886 && (player_stat[player].lives > 0)) {
1887 player_stat[player].dying = DEAD_TIME;
1888 count++;
1889 }
1890 }
1891
1892 return count;
1893 } /* KillOtherPlayers */
1894
1895 /*
1896 *
1897 */
1898 int
StunOtherPlayers(int team,int time)1899 StunOtherPlayers (int team, int time)
1900 {
1901 int count = 0;
1902 int player;
1903
1904 for (player = 0; player < numPlayer; player++) {
1905 if ((player_stat[player].team != team)
1906 && (!player_stat[player].invincible > 0)) {
1907 SND_Play (SND_STUN, player_stat[player].x / (PIXW / MAX_SOUND_POSITION));
1908 player_stat[player].stunned = time;
1909 count++;
1910 }
1911 }
1912 return count;
1913 } /* StunOtherPlayers */
1914
1915 /*Skywalker */
1916
1917 /**/
1918 /* public function fart_on_other_players (galatius) */
1919 /**/ int
FartOnOtherPlayers(BMPlayer * ps)1920 FartOnOtherPlayers (BMPlayer * ps)
1921 {
1922 BMPlayer *ps1;
1923 int ex, ey;
1924 int count = 0;
1925
1926 /* do_bell(); */
1927 if (ps->stunned || ps->smelly) {
1928 return (count > 0);
1929 }
1930 ps->smelly = SMELLY_TIME;
1931
1932 for (ps1 = player_stat; ps1 < player_stat + numPlayer; ps1++) {
1933 if ((ps1->lives == 0) || (ps1->invincible) ||
1934 ((ps->x == ps1->x) && (ps->y == ps1->y)) ||
1935 (ABS (ps1->x - ps->x) >= (BLOCK_WIDTH * 2)) ||
1936 (ABS (ps1->y - ps->y) >= (BLOCK_HEIGHT * 2))) {
1937 continue;
1938 } /* Now ps will fart ps1 */
1939
1940 ps1->farted = 20; /* Fart counter */
1941
1942 ex = (ps1->x - ps->x) * BLOCK_HEIGHT;
1943 ey = (ps1->y - ps->y) * BLOCK_WIDTH;
1944
1945 switch (ps1->d_ist) {
1946 case GoStop:
1947 if (ABS (ex) >= ABS (ey)) {
1948 ps1->d_soll = (ex < 0 ? GoLeft : GoRight);
1949 }
1950 else {
1951 ps1->d_soll = (ey < 0 ? GoUp : GoDown);
1952 }
1953 break;
1954 case GoRight:
1955 case GoLeft:
1956 ps1->d_soll = (ex < 0 ? GoLeft : GoRight);
1957 break;
1958 case GoUp:
1959 case GoDown:
1960 ps1->d_soll = (ey < 0 ? GoUp : GoDown);
1961 break;
1962 default:
1963 break;
1964 }
1965
1966 ps1->illness = IllRun;
1967 ps1->illtime = 20;
1968 ps1->stunned = 20;
1969
1970 count++;
1971 }
1972 return (count > 0);
1973 }
1974
1975 /**/
1976 /* public function Swap_color_other_players */
1977 /**/ void
SwapColorOtherPlayers(int team)1978 SwapColorOtherPlayers (int team)
1979 {
1980 int count = 0;
1981 int D[MAX_PLAYER];
1982 int RR;
1983 int player;
1984
1985 if (numPlayer == 2) {
1986 RR = ((player_stat[0].sprite)->player).player;
1987 ((player_stat[0].sprite)->player).player = ((player_stat[1].sprite)->player).player;
1988 ((player_stat[1].sprite)->player).player = RR;
1989 MarkMazeSprite (player_stat[0].sprite);
1990 MarkMazeSprite (player_stat[1].sprite);
1991 }
1992 else {
1993
1994 for (player = 0; player < numPlayer; player++) {
1995 if (((player_stat[player].team) != team) && player_stat[player].lives) {
1996 D[count] = player;
1997 count++;
1998 }
1999 }
2000
2001 if (count > 2) {
2002 RR = ((player_stat[D[0]].sprite)->player).player;
2003 for (player = 0; player < count - 1; player++) {
2004 ((player_stat[D[player]].sprite)->player).player =
2005 ((player_stat[D[player + 1]].sprite)->player).player;
2006 MarkMazeSprite (player_stat[D[player]].sprite);
2007 }
2008 ((player_stat[D[count - 1]].sprite)->player).player = RR;
2009 MarkMazeSprite (player_stat[D[count - 1]].sprite);
2010 }
2011 else {
2012 if (count == 2) {
2013 RR = ((player_stat[D[0]].sprite)->player).player;
2014 ((player_stat[D[0]].sprite)->player).player =
2015 ((player_stat[D[1]].sprite)->player).player;
2016 ((player_stat[D[1]].sprite)->player).player = RR;
2017 MarkMazeSprite ((player_stat[D[0]].sprite));
2018 MarkMazeSprite ((player_stat[D[1]].sprite));
2019 }
2020 }
2021 }
2022 }
2023
2024 #if unused
2025 /**/
2026 /* public function Swap_color_other_players2 */
2027 /**/ void
SwapColorOtherPlayers2(int team)2028 SwapColorOtherPlayers2 (int team)
2029 {
2030 int count = 0;
2031 int D[MAX_PLAYER];
2032 int RR;
2033 int player;
2034 int swapper = 0;
2035
2036 fprintf (stderr, "count %i \n", count);
2037 if (numPlayer == 2) {
2038 RR = ((player_stat[0].sprite)->player).player;
2039 ((player_stat[0].sprite)->player).player = ((player_stat[1].sprite)->player).player;
2040 ((player_stat[1].sprite)->player).player = RR;
2041 MarkMazeSprite (player_stat[0].sprite);
2042 MarkMazeSprite (player_stat[1].sprite);
2043 }
2044 else {
2045
2046 for (player = 0; player < numPlayer; player++) {
2047 if (player_stat[player].lives) {
2048 if (((player_stat[player].team) != team)) {
2049 D[count] = player;
2050 count++;
2051 }
2052 else {
2053 swapper = player;
2054 }
2055 }
2056 }
2057
2058 if (count > 2) {
2059 RR = ((player_stat[D[0]].sprite)->player).player;
2060 for (player = 0; player < count - 1; player++) {
2061 ((player_stat[D[player]].sprite)->player).player =
2062 ((player_stat[D[player + 1]].sprite)->player).player;
2063 MarkMazeSprite (player_stat[D[player]].sprite);
2064 }
2065 ((player_stat[D[count - 1]].sprite)->player).player = RR;
2066 MarkMazeSprite (player_stat[D[count - 1]].sprite);
2067 }
2068 /* 2 or 3 players, count 1 or 2 */
2069 else {
2070 if (count > 0) {
2071 fprintf (stderr, "count %i numPlayer %i\n", count, numPlayer);
2072 if (count == 1)
2073 D[1] = swapper;
2074
2075 RR = ((player_stat[D[0]].sprite)->player).player;
2076 ((player_stat[D[0]].sprite)->player).player =
2077 ((player_stat[D[1]].sprite)->player).player;
2078 ((player_stat[D[1]].sprite)->player).player = RR;
2079 MarkMazeSprite ((player_stat[D[0]].sprite));
2080 MarkMazeSprite ((player_stat[D[1]].sprite));
2081 }
2082
2083 }
2084 }
2085 }
2086 #endif
2087
2088 /*Skywalker */
2089
2090 /**/
2091 /* public function steal_bombs_other_players */
2092 /**/ int
StealBombsOtherPlayers(int team)2093 StealBombsOtherPlayers (int team)
2094 {
2095 int count = 0;
2096 int player;
2097
2098 for (player = 0; player < numPlayer; player++) {
2099 if (player_stat[player].team != team) {
2100 if (player_stat[player].bombs > 0) {
2101 player_stat[player].bombs--;
2102 count++;
2103 }
2104 }
2105 }
2106 return count;
2107 }
2108
2109 /**/
2110 /* public function steal_range_other_players */
2111 /**/ int
StealRangeOtherPlayers(int team)2112 StealRangeOtherPlayers (int team)
2113 {
2114 int count = 0;
2115 int player;
2116 for (player = 0; player < numPlayer; player++) {
2117 if (player_stat[player].team != team) {
2118 if (player_stat[player].range > 1) {
2119 player_stat[player].range--;
2120 count++;
2121 }
2122 }
2123 }
2124 return count;
2125 }
2126
2127 /**/
2128 /* public function Swap_position_other_players */
2129 /**/ void
SwapPositionOtherPlayers(int team)2130 SwapPositionOtherPlayers (int team)
2131 {
2132 int x = 0, y = 0;
2133 int first = -1;
2134 int player;
2135 int count = 0;
2136
2137 for (player = 0; player < numPlayer; player++) {
2138 if ((player_stat[player].team) != team) {
2139 count++;
2140 if (player_stat[player].lives) {
2141 if (first > -1) {
2142 player_stat[first].x = (player_stat[player].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2143 player_stat[first].y = (player_stat[player].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2144 first = player;
2145 }
2146 else {
2147 first = player;
2148 x = (player_stat[player].x / BLOCK_WIDTH) * BLOCK_WIDTH;;
2149 y = (player_stat[player].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;;
2150 }
2151 }
2152 }
2153 }
2154 if (count > 1) {
2155 if (first > -1) {
2156 player_stat[first].x = x;
2157 player_stat[first].y = y;
2158 }
2159 }
2160
2161 if (numPlayer == 2) {
2162 x = (player_stat[0].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2163 y = (player_stat[0].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2164 player_stat[0].x = (player_stat[1].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2165 player_stat[0].y = (player_stat[1].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2166 player_stat[1].x = x;
2167 player_stat[1].y = y;
2168 }
2169 }
2170
2171 #ifdef unused
2172 /**/
2173 /* public function Swap_position_other_players2 */
2174 /**/ void
SwapPositionOtherPlayers2(int team)2175 SwapPositionOtherPlayers2 (int team)
2176 {
2177 int x = 0, y = 0;
2178 int first = -1;
2179 int player, swapper = 0;
2180 int count = 0;
2181
2182 for (player = 0; player < numPlayer; player++) {
2183 if (player_stat[player].lives) {
2184 if ((player_stat[player].team) != team) {
2185 count++;
2186 if (first > -1) {
2187 player_stat[first].x = (player_stat[player].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2188 player_stat[first].y = (player_stat[player].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2189 first = player;
2190 }
2191 else {
2192 first = player;
2193 x = (player_stat[player].x / BLOCK_WIDTH) * BLOCK_WIDTH;;
2194 y = (player_stat[player].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;;
2195 }
2196 }
2197 else {
2198 swapper = player;
2199 }
2200 }
2201 }
2202 if (count > 1) {
2203 if (first > -1) {
2204 player_stat[first].x = x;
2205 player_stat[first].y = y;
2206 }
2207 }
2208 /* count==1 */
2209 else {
2210 if (first > -1) {
2211 player_stat[first].x = (player_stat[swapper].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2212 player_stat[first].y = (player_stat[swapper].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2213 player_stat[swapper].x = x;
2214 player_stat[swapper].y = y;
2215 }
2216 }
2217
2218 if (numPlayer == 2) {
2219 x = (player_stat[0].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2220 y = (player_stat[0].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2221 player_stat[0].x = (player_stat[1].x / BLOCK_WIDTH) * BLOCK_WIDTH;
2222 player_stat[0].y = (player_stat[1].y / BLOCK_HEIGHT) * BLOCK_HEIGHT;
2223 player_stat[1].x = x;
2224 player_stat[1].y = y;
2225 }
2226 }
2227 #endif
2228
2229 /* added by Skywalker */
2230 /**/
2231 /* public function do_frog (galatius) */
2232 /**/ void
DoFrog(BMPlayer * ps)2233 DoFrog (BMPlayer * ps)
2234 {
2235 int ex, ey;
2236 int frogs = ps->frogger;
2237
2238 if (!ps->d_ist == GoStop) {
2239 /* If you are already moving: */
2240 ex = ps->x % BLOCK_WIDTH;
2241 ey = ps->y % BLOCK_HEIGHT;
2242
2243 switch (ps->d_ist) {
2244 case GoDown:
2245 case GoUp:
2246 ps->y -= ey + ((ps->d_ist == GoUp) - 1) * BLOCK_HEIGHT;
2247 break;
2248 case GoRight:
2249 case GoLeft:
2250 ps->x -= ex + ((ps->d_ist == GoLeft) - 1) * BLOCK_WIDTH;
2251 break;
2252 default:
2253 break;
2254 }
2255
2256 frogs--;
2257 }
2258
2259 ex = 0;
2260 ey = 0;
2261 switch (ps->d_look) {
2262 case GoDown:
2263 ey = 1;
2264 break;
2265 case GoUp:
2266 ey = -1;
2267 break;
2268 case GoRight:
2269 ex = 1;
2270 break;
2271 case GoLeft:
2272 ex = -1;
2273 break;
2274 default:
2275 break;
2276 }
2277
2278 ps->x += ex * BLOCK_WIDTH * frogs;
2279 ps->y += ey * BLOCK_HEIGHT * frogs;
2280
2281 ps->x = MAX (0, MIN (14 * BLOCK_WIDTH, ps->x));
2282 ps->y = MAX (-BLOCK_HEIGHT, MIN (11 * BLOCK_HEIGHT, ps->y));
2283
2284 if (CheckMaze (ps->x / BLOCK_WIDTH, ps->y / BLOCK_HEIGHT + 1)) {
2285 MoveSprite (ps->sprite, ps->x, ps->y);
2286 ps->lives = 1;
2287 ps->dying = DEAD_TIME;
2288 }
2289
2290 ps->d_soll = GoStop;
2291
2292 }
2293
2294 /* end added by Skywalker */
2295
2296 /*
2297 *
2298 */
2299 static void
RevivePlayer(BMPlayer * ps,int * active_player)2300 RevivePlayer (BMPlayer * ps, int *active_player)
2301 {
2302 BMPlayer *ptr;
2303 PlayerStrings *st;
2304 int i, team_alive;
2305 int playerflags;
2306
2307 st = p_string + ps->id;
2308
2309 ps->lives--;
2310 /* check if player has lost all lives? */
2311 if (ps->lives == 0) {
2312 SetSpriteMode (ps->sprite, SPM_UNMAPPED);
2313 SND_Play (SND_DEAD, ps->x / (PIXW / MAX_SOUND_POSITION));
2314 team_alive = XBFalse;
2315 for (i = 0, ptr = player_stat; i < numPlayer; i++, ptr++) {
2316 if (ptr->team == ps->team) {
2317 team_alive |= (ptr->lives != 0);
2318 }
2319 }
2320 if (!team_alive) {
2321 (*active_player)--;
2322 }
2323 DistributeExtras (ps->bombs - minBombs, ps->range - minRange, ps->num_extras,
2324 ps->special_bombs);
2325 SetMessage (st->loselevel, XBFalse);
2326 }
2327 else {
2328 SND_Play (SND_OUCH, ps->x / (PIXW / MAX_SOUND_POSITION));
2329 DistributeExtras (0, 0, ps->num_extras, ps->special_bombs);
2330 SetMessage (st->loselife, XBFalse);
2331 }
2332 HaveAGloat (ps->id);
2333 /* reset values */
2334 playerflags = (ps->revextra_flags & ((0xffffff) >> 2));
2335 ps->invincible = NEW_INVINCIBLE;
2336 ps->dying = 0;
2337 ps->stunned = 0;
2338 ps->illness = reviveHealth;
2339 ps->health = reviveHealth;
2340 ps->illtime = 0;
2341 ps->teleport = 0;
2342 ps->cloaking = XBFalse;
2343 ps->morphed = XBFalse;
2344 ps->num_morph = 0;
2345 ps->evilill = 0;
2346 ps->phantom = 0;
2347 ps->through = 0;
2348 ps->throughCount = 0;
2349 ps->farted = (RF_Fart == playerflags) ? XBTrue : XBFalse; /* (galatius) */
2350 ps->smelly = 0; /* (galatius) */
2351 ps->bfarter = (RF_Bfart == playerflags) ? XBTrue : XBFalse; /* (galatius) */
2352 if (!ps->revive)
2353 ps->cloaking = 0;
2354
2355 /* Note that junkie ISN'T reset (not a bug) */
2356 /* very important */
2357 if (ps->remote_control > 0) {
2358 IgnitePlayersBombs (ps);
2359 }
2360 ps->daleifing = 0; /* (galatius) */
2361 ps->daleif = (RF_Daleif == playerflags) ? XBTrue : XBFalse; /* (galatius) */
2362
2363 ps->remote_control = XBFalse;
2364 ps->kick = XBFalse;
2365 ps->air_button = XBFalse;
2366 ps->frogger = (RF_Frogger == playerflags) ? XBTrue : XBFalse; /*Skywalker */
2367 ps->jump_button = (RF_Jump == playerflags) ? XBTrue : XBFalse; /*Skywalker */
2368 ps->evilill = 0;
2369 ps->stop = (RF_Stop == playerflags) ? XBTrue : XBFalse; /*Skywalker */
2370 ps->suck_button = (RF_Suck == playerflags) ? XBTrue : XBFalse; /*Skywalker */
2371 ps->phantom = (RF_Phantom == playerflags) ? GAME_TIME : XBFalse; /*Skywalker */
2372 ps->electrify = (RF_Electrify == playerflags) ? EXTRA_ELECTRIFY_COUNT : XBFalse; /*Skywalker */
2373 /* If special bombs are distributed, then zero the count */
2374 if (DistribSpecial ()) {
2375 ps->special_bombs = 0;
2376 }
2377 /* Reset extra pickup count */
2378 ps->num_extras = 0;
2379 /* reset inital extras */
2380 if (RF_RC == playerflags) {
2381 ps->remote_control = 1;
2382 }
2383 if (RF_Teleport == playerflags) {
2384 ps->teleport = 1;
2385 }
2386
2387 if (RF_Kick & ps->revextra_flags) {
2388 ps->kick = 1;
2389 }
2390 if (RF_Morph == playerflags) {
2391 ps->num_morph = 1000;
2392 }
2393 if (RF_Through == playerflags) {
2394 ps->through = XBTrue;
2395 ps->throughCount = 255;
2396 }
2397 if (RF_Snipe == playerflags) {
2398 ps->num_snipe = 1000;
2399 }
2400 ps->speed = 0;
2401
2402 if (RF_Revive == playerflags) {
2403 ps->revive = 1;
2404 }
2405 ps->choice_bomb_type = NUM_BMT;
2406 if (ps->local)
2407 ResetMessage ();
2408 if (RF_Choice == playerflags) {
2409 int h;
2410 for (h = ChoiceDefaultBomb; bomb_name_choice[h] == NULL; h = ((h + 1) % NUM_BMT)) ;
2411 ps->choice_bomb_type = h;
2412 if (ps->local && ps->lives) {
2413 char tutu[40];
2414 sprintf (tutu, "%s : ", p_string[ps->id].name);
2415 strcat (tutu, bomb_name_choice[(ps->choice_bomb_type)]);
2416 SetMessage (tutu, XBTrue);
2417 }
2418 }
2419 if (RF_Airpump == playerflags) {
2420 ps->air_button = 1;
2421 }
2422 if (RF_Cloak == playerflags) {
2423 ps->cloaking = -GAME_TIME;
2424 }
2425 /* if revived ignite the bombs! */
2426 if (ps->sniping == 1) {
2427 if (IgnitePlayersBombs (ps)) {
2428 ps->sniping = 1;
2429 ps->d_soll = GoStop;
2430 }
2431 }
2432 } /* RevivePlayer */
2433
2434 /*
2435 *
2436 */
2437 static void
DoStunned(BMPlayer * ps)2438 DoStunned (BMPlayer * ps)
2439 {
2440 switch ((ps->d_look + ps->stunned - 1) % 4 + GoStop + 1) {
2441 case GoDown:
2442 SetSpriteAnime (ps->sprite, SpriteStopDown);
2443 break;
2444 case GoUp:
2445 SetSpriteAnime (ps->sprite, SpriteStopUp);
2446 break;
2447 case GoLeft:
2448 SetSpriteAnime (ps->sprite, SpriteStopLeft);
2449 break;
2450 case GoRight:
2451 SetSpriteAnime (ps->sprite, SpriteStopRight);
2452 break;
2453 }
2454
2455 ps->stunned--;
2456 } /* DoStunned */
2457
2458 void
DoEvilIll(void)2459 DoEvilIll (void)
2460 {
2461 BMPlayer *ps1;
2462
2463 /* evil-ill countdown */
2464 for (ps1 = player_stat; ps1 < player_stat + numPlayer; ps1++) {
2465 if ((ps1->lives) && (ps1->evilill)) {
2466 if (ps1->evilill == 1)
2467 /* Too long! Take a hit. */
2468 ps1->dying = DEAD_TIME;
2469 ps1->evilill--;
2470 }
2471 }
2472 }
2473
2474 /*
2475 *
2476 */
2477 static void
DoDie(BMPlayer * ps)2478 DoDie (BMPlayer * ps)
2479 {
2480 if (ps->dying == DEAD_TIME) {
2481 SetSpriteMode (ps->sprite, SPM_MAPPED);
2482 }
2483 ps->dying--;
2484
2485 if (ps->lives > 1) {
2486 switch (ps->d_look) {
2487 case GoLeft:
2488 SetSpriteAnime (ps->sprite, SpriteDamagedLeft);
2489 break;
2490 case GoUp:
2491 SetSpriteAnime (ps->sprite, SpriteDamagedUp);
2492 break;
2493 case GoRight:
2494 SetSpriteAnime (ps->sprite, SpriteDamagedRight);
2495 break;
2496 default:
2497 SetSpriteAnime (ps->sprite, SpriteDamagedDown);
2498 break;
2499 }
2500 }
2501 else {
2502 switch (ps->d_look) {
2503 case GoLeft:
2504 SetSpriteAnime (ps->sprite, SpriteDeadLeft);
2505 break;
2506 case GoUp:
2507 SetSpriteAnime (ps->sprite, SpriteDeadUp);
2508 break;
2509 case GoRight:
2510 SetSpriteAnime (ps->sprite, SpriteDeadRight);
2511 break;
2512 default:
2513 SetSpriteAnime (ps->sprite, SpriteDeadDown);
2514 break;
2515 }
2516 }
2517 } /* DoDie */
2518
2519 /*
2520 *
2521 */
2522 XBBool
CheckPlayerNear(int x,int y)2523 CheckPlayerNear (int x, int y)
2524 {
2525 int player;
2526
2527 for (player = 0; player < numPlayer; player++) {
2528 if ((ABS (x * BLOCK_WIDTH - player_stat[player].x) < BLOCK_WIDTH) &&
2529 (ABS (y * BLOCK_HEIGHT - BLOCK_HEIGHT - player_stat[player].y) < BLOCK_HEIGHT)) {
2530 return XBTrue;
2531 }
2532 }
2533 return XBFalse;
2534 } /* CheckPlayerNear */
2535
2536 /*
2537 *
2538 */
2539 void
DoAllPlayers(int game_time,int * active_player)2540 DoAllPlayers (int game_time, int *active_player)
2541 {
2542 int spm_mode;
2543 int i, p, player;
2544 int plist[MAX_PLAYER]; // SMPF
2545
2546 /* if time is over, kill them all */
2547 if (game_time == (GAME_TIME - DEAD_TIME + 1)) {
2548 for (player = 0; player < numPlayer; player++) {
2549 if (player_stat[player].lives > 0) {
2550 player_stat[player].lives = 1;
2551 player_stat[player].dying = DEAD_TIME;
2552 }
2553 }
2554 }
2555
2556 for (i = 0; i < numPlayer; i++) {
2557 plist[i] = i;
2558 }
2559 for (i = numPlayer - 1; i > 0; i--) {
2560 p = GameRandomNumber (i + 1);
2561 player = plist[p];
2562 plist[p] = plist[i];
2563 plist[i] = player;
2564 }
2565
2566 /* check player status */
2567 for (p = 0; p < numPlayer; p++) {
2568 /* to permute player when drawing and stunning */
2569 /* quick and dirty but hopefully it solves some problems */
2570 player = plist[p];
2571
2572 if (player_stat[player].lives != 0) {
2573
2574 switch (player_stat[player].dying) {
2575 case 0:
2576 /* player is alive and ... */
2577 if (player_stat[player].morphed) {
2578 /* ... or morphed */
2579 DoMorph (player_stat + player);
2580 }
2581 else if (player_stat[player].stunned) {
2582 if (player_stat[player].farted) {
2583 /* (galatius) */
2584 DoWalk (player_stat + player, game_time);
2585 DoStunned (player_stat + player);
2586 player_stat[player].farted--;
2587 }
2588 else {
2589 /* ... and stunned */
2590 DoStunned (player_stat + player);
2591 }
2592 }
2593 else {
2594 /* ... walks around */
2595 DoWalk (player_stat + player, game_time);
2596 }
2597 /* added by Galatius */
2598 if (player_stat[player].smelly) {
2599 player_stat[player].smelly--;
2600 }
2601 if (player_stat[player].daleifing) {
2602 player_stat[player].daleifing--;
2603 }
2604 break;
2605
2606 case 1:
2607 /* try to revive player */
2608 RevivePlayer (player_stat + player, active_player);
2609 break;
2610
2611 default:
2612 /* player is dying */
2613 DoDie (player_stat + player);
2614 break;
2615 }
2616 }
2617 else {
2618 if (player_stat[player].revive) {
2619 if (player_stat[player].cloaking < 0) {
2620 player_stat[player].cloaking++;
2621 if (player_stat[player].cloaking & 0x01) {
2622 spm_mode = player_stat[player].disp;
2623 }
2624 else {
2625 spm_mode = SPM_UNMAPPED;
2626 }
2627 }
2628 else
2629 spm_mode = SPM_MAPPED;
2630 SetSpriteMode (player_stat[player].sprite, spm_mode);
2631 SetSpriteAnime (player_stat[player].sprite, SpriteZombie);
2632
2633 }
2634 }
2635 }
2636 } /* DoAllPlayers */
2637
2638 /*
2639 *
2640 */
2641 void
CheckPlayerHit(void)2642 CheckPlayerHit (void)
2643 {
2644 int player;
2645 int gridx, gridy;
2646
2647 for (player = 0; player < numPlayer; player++) {
2648 gridx = (player_stat[player].x + (BLOCK_WIDTH >> 1)) / BLOCK_WIDTH;
2649 gridy = (player_stat[player].y + (BLOCK_HEIGHT >> 1)) / BLOCK_HEIGHT + 1;
2650 if (0 != player_stat[player].lives &&
2651 0 == player_stat[player].invincible &&
2652 0 == player_stat[player].morphed &&
2653 0 == player_stat[player].dying && CheckExplosion (gridx, gridy)) {
2654 player_stat[player].dying = DEAD_TIME;
2655 }
2656 }
2657 } /* CheckPlayerHit */
2658
2659 /*
2660 * check if local players are away, make them bot, reset away flag
2661 */
2662 void
Player_CheckLocalAway(void)2663 Player_CheckLocalAway (void)
2664 {
2665 BMPlayer *ps;
2666 for (ps = player_stat; ps < player_stat + numPlayer; ps++) {
2667 if (ps->localDisplay >= 0) {
2668 if (ps->away) {
2669 ps->bot = XBTrue;
2670 }
2671 else {
2672 ps->away = XBTrue;
2673 }
2674 }
2675 }
2676 } /* Player_CheckLocalAway */
2677
2678 /*
2679 * check if all local players are bots
2680 */
2681 XBBool
Player_CheckLocalBot(void)2682 Player_CheckLocalBot (void)
2683 {
2684 BMPlayer *ps;
2685 for (ps = player_stat; ps < player_stat + numPlayer; ps++) {
2686 if (ps->localDisplay >= 0 && !ps->bot) {
2687 return XBFalse;
2688 }
2689 }
2690 return XBTrue;
2691 } /* Player_CheckLocalBot */
2692
2693 /*
2694 * determine action for all (local) bots
2695 */
2696 void
Player_BotAction(PlayerAction * pa)2697 Player_BotAction (PlayerAction * pa)
2698 {
2699 BMPlayer *ps;
2700 for (ps = player_stat; ps < player_stat + numPlayer; ps++) {
2701 if (ps->bot && ps->localDisplay >= 0) {
2702 gestionBot (player_stat, pa, ps->id, numPlayer);
2703 }
2704 }
2705 } /* Player_BotAction */
2706
2707 /*
2708 * de/activate bot
2709 */
2710 void
Player_ActivateBot(BMPlayer * ps,XBBool activate)2711 Player_ActivateBot (BMPlayer * ps, XBBool activate)
2712 {
2713 assert (ps != NULL);
2714 ps->away = activate;
2715 if (ps->bot == activate) {
2716 return;
2717 }
2718 ps->bot = activate;
2719 if (activate) {
2720 SetMessage (N_("Bot Activated"), XBFalse);
2721 }
2722 else {
2723 SetMessage (N_("Bot Deactivated"), XBFalse);
2724 }
2725 } /* Player_ActivateBot */
2726
2727 /*
2728 * return if player is local bot
2729 */
2730 XBBool
Player_isLocalBot(BMPlayer * ps)2731 Player_isLocalBot (BMPlayer * ps)
2732 {
2733 assert (ps != NULL);
2734 return (ps->bot && ps->localDisplay >= 0);
2735 } /* Player_isLocalBot */
2736
2737 /*
2738 * end of file player.c
2739 */
2740