rnd-20060402-2-src
[rocksndiamonds.git] / src / game_em / synchro_1.c
1 /* first part of synchro.
2  *
3  * game logic for players.
4  *
5  * large switch statement for tiles the player interacts with.
6  */
7
8 #include "main_em.h"
9
10
11 #if 0
12 extern int centered_player_nr;
13 #endif
14
15 #define USE_CHANGED_ACID_STUFF          1
16
17 extern boolean checkIfAllPlayersFitToScreen();
18
19 static void check_player(struct PLAYER *);
20 static void kill_player(struct PLAYER *);
21 static boolean player_digfield(struct PLAYER *, int, int);
22 static boolean player_killed(struct PLAYER *);
23
24 void synchro_1(void)
25 {
26 #if 1
27
28   int start_check_nr;
29   int i;
30
31   game_em.any_player_moving = FALSE;
32
33   /* must test for death and actually kill separately */
34
35   for (i = 0; i < MAX_PLAYERS; i++)
36   {
37     boolean ply_kill = player_killed(&ply[i]);
38
39     if (ply[i].alive && ply_kill)
40       kill_player(&ply[i]);
41   }
42
43 #else
44
45   /* must test for death and actually kill separately */
46   boolean ply1_kill = player_killed(&ply1);
47   boolean ply2_kill = player_killed(&ply2);
48
49   if (ply1.alive && ply1_kill)
50     kill_player(&ply1);
51   if (ply2.alive && ply2_kill)
52     kill_player(&ply2);
53
54 #endif
55
56 #if 0
57   ply1.alive = 1; /* debugging */
58 #endif
59
60 #if 1
61
62   for (i = 0; i < MAX_PLAYERS; i++)
63   {
64     ply[i].oldx = ply[i].x;
65     ply[i].oldy = ply[i].y;
66     ply[i].anim = SPR_still;
67   }
68
69   start_check_nr = (RandomEM & 128 ? 0 : 1) * 2 + (RandomEM & 256 ? 0 : 1);
70
71   for (i = 0; i < MAX_PLAYERS; i++)
72   {
73     int check_nr = (start_check_nr + i) % MAX_PLAYERS;
74
75     if (ply[check_nr].alive)
76       check_player(&ply[check_nr]);
77   }
78
79   for (i = 0; i < MAX_PLAYERS; i++)
80   {
81     if (!ply[i].alive)
82       continue;
83
84     if (Cave[ply[i].oldy][ply[i].oldx] == Zplayer)
85     {
86       Cave[ply[i].oldy][ply[i].oldx] = Xblank;
87       Next[ply[i].oldy][ply[i].oldx] = Xblank;
88     }
89
90     if (Cave[ply[i].y][ply[i].x] == Xblank)
91     {
92       Cave[ply[i].y][ply[i].x] = Zplayer;
93       Next[ply[i].y][ply[i].x] = Zplayer;
94     }
95   }
96
97 #else
98
99   ply1.oldx = ply1.x;
100   ply1.oldy = ply1.y;
101   ply1.anim = SPR_still;
102   ply2.oldx = ply2.x;
103   ply2.oldy = ply2.y;
104   ply2.anim = SPR_still;
105
106   if (RandomEM & 256)
107   {
108     if (ply1.alive) check_player(&ply1);
109     if (ply2.alive) check_player(&ply2);
110   }
111   else
112   {
113     if (ply2.alive) check_player(&ply2);
114     if (ply1.alive) check_player(&ply1);
115   }
116
117   if (ply1.alive)
118   {
119     if (Cave[ply1.oldy][ply1.oldx] == Zplayer)
120     {
121       Cave[ply1.oldy][ply1.oldx] = Xblank;
122       Next[ply1.oldy][ply1.oldx] = Xblank;
123     }
124
125     if (Cave[ply1.y][ply1.x] == Xblank)
126     {
127       Cave[ply1.y][ply1.x] = Zplayer;
128       Next[ply1.y][ply1.x] = Zplayer;
129     }
130   }
131
132   if (ply2.alive)
133   {
134     if (Cave[ply2.oldy][ply2.oldx] == Zplayer)
135     {
136       Cave[ply2.oldy][ply2.oldx] = Xblank;
137       Next[ply2.oldy][ply2.oldx] = Xblank;
138     }
139
140     if (Cave[ply2.y][ply2.x] == Xblank)
141     {
142       Cave[ply2.y][ply2.x] = Zplayer;
143       Next[ply2.y][ply2.x] = Zplayer;
144     }
145   }
146
147 #endif
148 }
149
150 static boolean player_killed(struct PLAYER *ply)
151 {
152   int x = ply->x;
153   int y = ply->y;
154
155 #if 0
156   printf("::: %d: %d, %d\n", ply->num, x, y);
157 #endif
158
159   if (!ply->alive)
160     return FALSE;
161
162 #if 1
163   if (lev.killed_out_of_time && setup.time_limit)
164     return TRUE;
165 #else
166   if (lev.time_initial > 0 && lev.time == 0 && setup.time_limit)
167     return TRUE;
168 #endif
169
170   switch(Cave[y-1][x])
171   {
172     case Xbug_n:
173     case Xbug_e:
174     case Xbug_s:
175     case Xbug_w:
176     case Xbug_gon:
177     case Xbug_goe:
178     case Xbug_gos:
179     case Xbug_gow:
180     case Xtank_n:
181     case Xtank_e:
182     case Xtank_s:
183     case Xtank_w:
184     case Xtank_gon:
185     case Xtank_goe:
186     case Xtank_gos:
187     case Xtank_gow:
188       return TRUE;
189   }
190
191   switch(Cave[y][x+1])
192   {
193     case Xbug_n:
194     case Xbug_e:
195     case Xbug_s:
196     case Xbug_w:
197     case Xbug_gon:
198     case Xbug_goe:
199     case Xbug_gos:
200     case Xbug_gow:
201     case Xtank_n:
202     case Xtank_e:
203     case Xtank_s:
204     case Xtank_w:
205     case Xtank_gon:
206     case Xtank_goe:
207     case Xtank_gos:
208     case Xtank_gow:
209       return TRUE;
210   }
211
212   switch(Cave[y+1][x])
213   {
214     case Xbug_n:
215     case Xbug_e:
216     case Xbug_s:
217     case Xbug_w:
218     case Xbug_gon:
219     case Xbug_goe:
220     case Xbug_gos:
221     case Xbug_gow:
222     case Xtank_n:
223     case Xtank_e:
224     case Xtank_s:
225     case Xtank_w:
226     case Xtank_gon:
227     case Xtank_goe:
228     case Xtank_gos:
229     case Xtank_gow:
230       return TRUE;
231   }
232
233   switch(Cave[y][x-1])
234   {
235     case Xbug_n:
236     case Xbug_e:
237     case Xbug_s:
238     case Xbug_w:
239     case Xbug_gon:
240     case Xbug_goe:
241     case Xbug_gos:
242     case Xbug_gow:
243     case Xtank_n:
244     case Xtank_e:
245     case Xtank_s:
246     case Xtank_w:
247     case Xtank_gon:
248     case Xtank_goe:
249     case Xtank_gos:
250     case Xtank_gow:
251       return TRUE;
252   }
253
254   switch(Cave[y][x])
255   {
256     case Xblank:
257     case Yacid_splash_eB:
258     case Yacid_splash_wB:
259     case Zplayer:
260     case Xdynamite_1:
261     case Xdynamite_2:
262     case Xdynamite_3:
263     case Xdynamite_4:
264 #if 1
265     case Xfake_acid_1:
266     case Xfake_acid_2:
267     case Xfake_acid_3:
268     case Xfake_acid_4:
269     case Xfake_acid_5:
270     case Xfake_acid_6:
271     case Xfake_acid_7:
272     case Xfake_acid_8:
273 #endif
274       return FALSE;
275   }
276
277   return TRUE;
278 }
279
280 static void kill_player(struct PLAYER *ply)
281 {
282   int x = ply->x;
283   int y = ply->y;
284
285   ply->alive = 0;
286
287   switch(Cave[y-1][x])
288   {
289     case Xbug_n:
290     case Xbug_e:
291     case Xbug_s:
292     case Xbug_w:
293     case Xbug_gon:
294     case Xbug_goe:
295     case Xbug_gos:
296     case Xbug_gow:
297       Cave[y-1][x] = Xboom_bug;
298 #if 0
299       play_element_sound(x, y, SAMPLE_boom, Zplayer);
300 #endif
301       break;
302
303     case Xtank_n:
304     case Xtank_e:
305     case Xtank_s:
306     case Xtank_w:
307     case Xtank_gon:
308     case Xtank_goe:
309     case Xtank_gos:
310     case Xtank_gow:
311       Cave[y-1][x] = Xboom_bomb;
312 #if 0
313       play_element_sound(x, y, SAMPLE_boom, Zplayer);
314 #endif
315       break;
316   }
317
318   switch(Cave[y][x+1])
319   {
320     case Xbug_n:
321     case Xbug_e:
322     case Xbug_s:
323     case Xbug_w:
324     case Xbug_gon:
325     case Xbug_goe:
326     case Xbug_gos:
327     case Xbug_gow:
328       Cave[y][x+1] = Xboom_bug;
329 #if 0
330       play_element_sound(x, y, SAMPLE_boom, Zplayer);
331 #endif
332       break;
333
334     case Xtank_n:
335     case Xtank_e:
336     case Xtank_s:
337     case Xtank_w:
338     case Xtank_gon:
339     case Xtank_goe:
340     case Xtank_gos:
341     case Xtank_gow:
342       Cave[y][x+1] = Xboom_bomb;
343 #if 0
344       play_element_sound(x, y, SAMPLE_boom, Zplayer);
345 #endif
346       break;
347   }
348
349   switch(Cave[y+1][x])
350   {
351     case Xbug_n:
352     case Xbug_e:
353     case Xbug_s:
354     case Xbug_w:
355     case Xbug_gon:
356     case Xbug_goe:
357     case Xbug_gos:
358     case Xbug_gow:
359       Cave[y+1][x] = Xboom_bug;
360 #if 0
361       play_element_sound(x, y, SAMPLE_boom, Zplayer);
362 #endif
363       break;
364
365     case Xtank_n:
366     case Xtank_e:
367     case Xtank_s:
368     case Xtank_w:
369     case Xtank_gon:
370     case Xtank_goe:
371     case Xtank_gos:
372     case Xtank_gow:
373       Cave[y+1][x] = Xboom_bomb;
374 #if 0
375       play_element_sound(x, y, SAMPLE_boom, Zplayer);
376 #endif
377       break;
378   }
379
380   switch(Cave[y][x-1])
381   {
382     case Xbug_n:
383     case Xbug_e:
384     case Xbug_s:
385     case Xbug_w:
386     case Xbug_gon:
387     case Xbug_goe:
388     case Xbug_gos:
389     case Xbug_gow:
390       Cave[y][x-1] = Xboom_bug;
391 #if 0
392       play_element_sound(x, y, SAMPLE_boom, Zplayer);
393 #endif
394       break;
395
396     case Xtank_n:
397     case Xtank_e:
398     case Xtank_s:
399     case Xtank_w:
400     case Xtank_gon:
401     case Xtank_goe:
402     case Xtank_gos:
403     case Xtank_gow:
404       Cave[y][x-1] = Xboom_bomb;
405 #if 0
406       play_element_sound(x, y, SAMPLE_boom, Zplayer);
407 #endif
408       break;
409   }
410
411   switch(Cave[y][x])
412   {
413     case Xexit_1:
414     case Xexit_2:
415     case Xexit_3:
416       play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
417       break;
418
419     default:
420       play_element_sound(x, y, SAMPLE_die, Zplayer);
421       break;
422   }
423
424   switch(Cave[y][x])
425   {
426 #if USE_CHANGED_ACID_STUFF
427     case Xacid_1:
428     case Xacid_2:
429     case Xacid_3:
430     case Xacid_4:
431     case Xacid_5:
432     case Xacid_6:
433     case Xacid_7:
434     case Xacid_8:
435       break;
436 #endif
437
438     default:
439       Cave[y][x] = Xboom_1;
440       Boom[y][x] = Xblank;
441       break;
442   }
443 }
444
445 static void check_player(struct PLAYER *ply)
446 {
447   int oldx = ply->x;
448   int oldy = ply->y;
449   int x = oldx;
450   int y = oldy;
451   int anim = 0;
452   int dx = 0, dy = 0;
453
454   game_em.last_player_direction[ply->num] = MV_NONE;
455
456 #if 0
457   printf("::: up == %d, down == %d, left == %d, right == %d, fire == %d [spin == %d, stick == %d]\n",
458          ply->joy_n, ply->joy_s, ply->joy_w, ply->joy_e, ply->joy_fire,
459          ply->joy_spin, ply->joy_stick);
460 #endif
461
462 #if 1
463   if (ply->joy_w)               /* west */
464   {
465     x--;
466     dx = -1;
467     anim = 3;
468   }
469   else if (ply->joy_e)          /* east */
470   {
471     x++;
472     dx = 1;
473     anim = 1;
474   }
475
476   if (ply->joy_n)               /* north */
477   {
478     y--;
479     dy = -1;
480     anim = 0;
481   }
482   else if (ply->joy_s)          /* south */
483   {
484     y++;
485     dy = 1;
486     anim = 2;
487   }
488
489 #else
490
491   if ((ply->joy_spin = !ply->joy_spin))
492   {
493     if (ply->joy_n)             /* north */
494     {
495       y--;
496       dy = -1;
497       anim = 0;
498     }
499     else if (ply->joy_e)        /* east */
500     {
501       x++;
502       dx = 1;
503       anim = 1;
504     }
505     else if (ply->joy_s)        /* south */
506     {
507       y++;
508       dy = 1;
509       anim = 2;
510     }
511     else if (ply->joy_w)        /* west */
512     {
513       x--;
514       dx = -1;
515       anim = 3;
516     }
517   }
518   else
519   {
520     if (ply->joy_w)             /* west */
521     {
522       x--;
523       dx = -1;
524       anim = 3;
525     }
526     else if (ply->joy_s)        /* south */
527     {
528       y++;
529       dy = 1;
530       anim = 2;
531     }
532     else if (ply->joy_e)        /* east */
533     {
534       x++;
535       dx = 1;
536       anim = 1;
537     }
538     else if (ply->joy_n)        /* north */
539     {
540       y--;
541       dy = -1;
542       anim = 0;
543     }
544   }
545 #endif
546
547   if (dx || dy)
548   {
549     int oldx = ply->x;
550     int oldy = ply->y;
551     int x = oldx + dx;
552     int y = oldy + dy;
553     boolean players_visible_before_move;
554     boolean players_visible_after_move;
555     boolean can_move;
556
557     players_visible_before_move = checkIfAllPlayersFitToScreen();
558
559     ply->x = x;
560     ply->y = y;
561
562     players_visible_after_move = checkIfAllPlayersFitToScreen();
563
564     /*
565       player is allowed to move only in the following cases:
566       - it is not needed to display all players (not focussed to all players)
567       - all players are (still or again) visible after the move
568       - some players were already outside visible screen area before the move
569     */
570     can_move = (game.centered_player_nr != -1 ||
571                 players_visible_after_move ||
572                 !players_visible_before_move);
573
574     ply->x = oldx;
575     ply->y = oldy;
576
577     if (!can_move)
578     {
579       ply->joy_n = ply->joy_e = ply->joy_s = ply->joy_w = 0;
580
581       return;
582     }
583   }
584
585   if (dx == 0 && dy == 0)
586   {
587     ply->joy_stick = 0;
588
589     if (ply->joy_drop)
590     {
591       if (++ply->dynamite_cnt == 5 && ply->dynamite)
592       {
593         Cave[y][x] = Xdynamite_1;
594         play_element_sound(x, y, SAMPLE_dynamite, Xdynamite_1);
595         ply->dynamite--;
596       }
597     }
598     else
599     {
600       ply->dynamite_cnt = 0;
601     }
602
603     RandomEM += 7;      /* be a bit more random if the player doesn't move */
604
605     return;
606   }
607
608   ply->joy_stick = 1;
609   ply->joy_n = ply->joy_e = ply->joy_s = ply->joy_w = 0;
610   ply->dynamite_cnt = 0;        /* reset dynamite timer if we move */
611   ply->joy_spin = !ply->joy_spin;
612
613   if (ply->joy_snap == 0)               /* player wants to move */
614   {
615     boolean moved = FALSE;
616
617     if (ply->last_move_dir & MV_HORIZONTAL)
618     {
619       if (!(moved = player_digfield(ply, 0, dy)))
620         moved = player_digfield(ply, dx, 0);
621     }
622     else
623     {
624       if (!(moved = player_digfield(ply, dx, 0)))
625         moved = player_digfield(ply, 0, dy);
626     }
627
628     if (moved)
629     {
630       if (oldx != ply->x)
631         ply->last_move_dir = (dx < 0 ? MV_LEFT : MV_RIGHT);
632       else if (oldy != ply->y)
633         ply->last_move_dir = (dy < 0 ? MV_UP : MV_DOWN);
634
635       game_em.any_player_moving = TRUE;
636       game_em.last_moving_player = ply->num;
637       game_em.last_player_direction[ply->num] = ply->last_move_dir;
638     }
639   }
640   else                                  /* player wants to snap */
641   {
642     player_digfield(ply, dx, dy);
643   }
644 }
645
646 static boolean player_digfield(struct PLAYER *ply, int dx, int dy)
647 {
648   int anim = (dx < 0 ? 3 : dx > 0 ? 1 : dy < 0 ? 0 : dy > 0 ? 2 : 2);
649   int oldx = ply->x;
650   int oldy = ply->y;
651   int x = oldx + dx;
652   int y = oldy + dy;
653   boolean result = TRUE;
654
655   if (!dx && !dy)                       /* no direction specified */
656     return FALSE;
657
658   if (dx && dy && ply->joy_snap)        /* more than one direction specified */
659     return FALSE;
660
661   if (ply->joy_snap == 0)               /* player wants to move */
662   {
663     int element = Cave[y][x];
664
665     switch(Cave[y][x])
666     {
667       /* fire is released */
668       case Xblank:
669       case Yacid_splash_eB:
670       case Yacid_splash_wB:
671         Cave[y][x] = Zplayer;
672         Next[y][x] = Zplayer;
673 #if 1
674       case Xfake_acid_1:
675       case Xfake_acid_2:
676       case Xfake_acid_3:
677       case Xfake_acid_4:
678       case Xfake_acid_5:
679       case Xfake_acid_6:
680       case Xfake_acid_7:
681       case Xfake_acid_8:
682 #endif
683         play_element_sound(x, y, SAMPLE_blank, Xblank);
684         ply->anim = SPR_walk + anim;
685         ply->x = x;
686         ply->y = y;
687         break;
688
689 #if USE_CHANGED_ACID_STUFF
690       case Xacid_1:
691       case Xacid_2:
692       case Xacid_3:
693       case Xacid_4:
694       case Xacid_5:
695       case Xacid_6:
696       case Xacid_7:
697       case Xacid_8:
698         if (Cave[y-1][x+1] == Xblank)
699           Cave[y-1][x+1] = Yacid_splash_eB;
700         if (Cave[y-1][x-1] == Xblank)
701           Cave[y-1][x-1] = Yacid_splash_wB;
702         play_element_sound(x, y, SAMPLE_acid, Xacid_1);
703 #endif
704
705       case Xboom_android:
706       case Xboom_1:
707       case Xbug_n:
708       case Xbug_e:
709       case Xbug_s:
710       case Xbug_w:
711       case Xbug_gon:
712       case Xbug_goe:
713       case Xbug_gos:
714       case Xbug_gow:
715       case Xtank_n:
716       case Xtank_e:
717       case Xtank_s:
718       case Xtank_w:
719       case Xtank_gon:
720       case Xtank_goe:
721       case Xtank_gos:
722       case Xtank_gow:
723
724 #if !USE_CHANGED_ACID_STUFF
725       case Xacid_1:
726       case Xacid_2:
727       case Xacid_3:
728       case Xacid_4:
729       case Xacid_5:
730       case Xacid_6:
731       case Xacid_7:
732       case Xacid_8:
733 #endif
734         ply->anim = SPR_walk + anim;
735         ply->x = x;
736         ply->y = y;
737         break;
738
739       case Xgrass:
740         Cave[y][x] = (dy ? (dy < 0 ? Ygrass_nB : Ygrass_sB) :
741                       (dx > 0 ? Ygrass_eB : Ygrass_wB));
742         Next[y][x] = Zplayer;
743         play_element_sound(x, y, SAMPLE_dirt, Xgrass);
744         ply->anim = SPR_walk + anim;
745         ply->x = x;
746         ply->y = y;
747         break;
748
749       case Xdirt:
750         Cave[y][x] = (dy ? (dy < 0 ? Ydirt_nB : Ydirt_sB) :
751                       (dx > 0 ? Ydirt_eB : Ydirt_wB));
752         Next[y][x] = Zplayer;
753         play_element_sound(x, y, SAMPLE_dirt, Xdirt);
754         ply->anim = SPR_walk + anim;
755         ply->x = x;
756         ply->y = y;
757         break;
758
759       case Xdiamond:
760       case Xdiamond_pause:
761         Cave[y][x] = Ydiamond_eat;
762         Next[y][x] = Zplayer;
763         play_element_sound(x, y, SAMPLE_collect, element);
764         lev.score += lev.diamond_score;
765         lev.required = lev.required < 3 ? 0 : lev.required - 3;
766         ply->anim = SPR_walk + anim;
767         ply->x = x;
768         ply->y = y;
769         break;
770
771       case Xemerald:
772       case Xemerald_pause:
773         Cave[y][x] = Yemerald_eat;
774         Next[y][x] = Zplayer;
775         play_element_sound(x, y, SAMPLE_collect, element);
776         lev.score += lev.emerald_score;
777         lev.required = lev.required < 1 ? 0 : lev.required - 1;
778         ply->anim = SPR_walk + anim;
779         ply->x = x;
780         ply->y = y;
781         break;
782
783       case Xdynamite:
784         Cave[y][x] = Ydynamite_eat;
785         Next[y][x] = Zplayer;
786         play_element_sound(x, y, SAMPLE_collect, element);
787         lev.score += lev.dynamite_score;
788         ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
789         ply->anim = SPR_walk + anim;
790         ply->x = x;
791         ply->y = y;
792         break;
793
794       case Xkey_1:
795         ply->keys |= 0x01;
796         Cave[y][x] = Ykey_1_eat;
797         goto key_walk;
798
799       case Xkey_2:
800         ply->keys |= 0x02;
801         Cave[y][x] = Ykey_2_eat;
802         goto key_walk;
803
804       case Xkey_3:
805         ply->keys |= 0x04;
806         Cave[y][x] = Ykey_3_eat;
807         goto key_walk;
808
809       case Xkey_4:
810         ply->keys |= 0x08;
811         Cave[y][x] = Ykey_4_eat;
812         goto key_walk;
813
814       case Xkey_5:
815         ply->keys |= 0x10;
816         Cave[y][x] = Ykey_5_eat;
817         goto key_walk;
818
819       case Xkey_6:
820         ply->keys |= 0x20;
821         Cave[y][x] = Ykey_6_eat;
822         goto key_walk;
823
824       case Xkey_7:
825         ply->keys |= 0x40;
826         Cave[y][x] = Ykey_7_eat;
827         goto key_walk;
828
829       case Xkey_8:
830         ply->keys |= 0x80;
831         Cave[y][x] = Ykey_8_eat;
832         goto key_walk;
833
834       key_walk:
835
836         Next[y][x] = Zplayer;
837         play_element_sound(x, y, SAMPLE_collect, element);
838         lev.score += lev.key_score;
839         ply->anim = SPR_walk + anim;
840         ply->x = x;
841         ply->y = y;
842         break;
843
844       case Xlenses:
845         Cave[y][x] = Ylenses_eat;
846         Next[y][x] = Zplayer;
847         play_element_sound(x, y, SAMPLE_collect, element);
848         lev.score += lev.lenses_score;
849         lev.lenses_cnt = lev.lenses_time;
850         ply->anim = SPR_walk + anim;
851         ply->x = x;
852         ply->y = y;
853         break;
854
855       case Xmagnify:
856         Cave[y][x] = Ymagnify_eat;
857         Next[y][x] = Zplayer;
858         play_element_sound(x, y, SAMPLE_collect, element);
859         lev.score += lev.magnify_score;
860         lev.magnify_cnt = lev.magnify_time;
861         ply->anim = SPR_walk + anim;
862         ply->x = x;
863         ply->y = y;
864         break;
865
866       case Xstone:
867         if (dy)
868           break;
869
870         switch(Cave[y][x+dx])
871         {
872           case Xacid_1:
873           case Xacid_2:
874           case Xacid_3:
875           case Xacid_4:
876           case Xacid_5:
877           case Xacid_6:
878           case Xacid_7:
879           case Xacid_8:
880             if (Cave[y-1][x+dx+1] == Xblank)
881               Cave[y-1][x+dx+1] = Yacid_splash_eB;
882             if (Cave[y-1][x+dx-1] == Xblank)
883               Cave[y-1][x+dx-1] = Yacid_splash_wB;
884             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
885             goto stone_walk;
886
887           case Xblank:
888           case Yacid_splash_eB:
889           case Yacid_splash_wB:
890             Cave[y][x+dx] = dx > 0 ? Ystone_e : Ystone_w;
891             Next[y][x+dx] = Xstone_pause;
892
893           stone_walk:
894
895             Cave[y][x] = dx > 0 ? Ystone_eB : Ystone_wB;
896             Next[y][x] = Zplayer;
897             play_element_sound(x, y, SAMPLE_roll, Xstone);
898             ply->x = x;
899         }
900
901         ply->anim = SPR_push + anim;
902         break;
903
904       case Xbomb:
905         if (dy)
906           break;
907
908         switch(Cave[y][x+dx])
909         {
910           case Xacid_1:
911           case Xacid_2:
912           case Xacid_3:
913           case Xacid_4:
914           case Xacid_5:
915           case Xacid_6:
916           case Xacid_7:
917           case Xacid_8:
918             if (Cave[y-1][x+dx+1] == Xblank)
919               Cave[y-1][x+dx+1] = Yacid_splash_eB;
920             if (Cave[y-1][x+dx-1] == Xblank)
921               Cave[y-1][x+dx-1] = Yacid_splash_wB;
922             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
923             goto bomb_walk;
924
925           case Xblank:
926           case Yacid_splash_eB:
927           case Yacid_splash_wB:
928             Cave[y][x+dx] = dx > 0 ? Ybomb_e : Ybomb_w;
929             Next[y][x+dx] = Xbomb_pause;
930
931           bomb_walk:
932
933             Cave[y][x] = dx > 0 ? Ybomb_eB : Ybomb_wB;
934             Next[y][x] = Zplayer;
935             play_element_sound(x, y, SAMPLE_roll, Xbomb);
936             ply->x = x;
937         }
938
939         ply->anim = SPR_push + anim;
940         break;
941
942       case Xnut:
943         if (dy)
944           break;
945
946         switch(Cave[y][x+dx])
947         {
948           case Xacid_1:
949           case Xacid_2:
950           case Xacid_3:
951           case Xacid_4:
952           case Xacid_5:
953           case Xacid_6:
954           case Xacid_7:
955           case Xacid_8:
956             if (Cave[y-1][x+dx+1] == Xblank)
957               Cave[y-1][x+dx+1] = Yacid_splash_eB;
958             if (Cave[y-1][x+dx-1] == Xblank)
959               Cave[y-1][x+dx-1] = Yacid_splash_wB;
960             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
961             goto nut_walk;
962
963           case Xblank:
964           case Yacid_splash_eB:
965           case Yacid_splash_wB:
966             Cave[y][x+dx] = dx > 0 ? Ynut_e : Ynut_w;
967             Next[y][x+dx] = Xnut_pause;
968
969           nut_walk:
970
971             Cave[y][x] = dx > 0 ? Ynut_eB : Ynut_wB;
972             Next[y][x] = Zplayer;
973             play_element_sound(x, y, SAMPLE_roll, Xnut);
974             ply->x = x;
975         }
976
977         ply->anim = SPR_push + anim;
978         break;
979
980       case Xspring:
981         if (dy)
982           break;
983
984         switch(Cave[y][x+dx])
985         {
986           case Xalien:
987           case Xalien_pause:
988             Cave[y][x] = dx > 0 ? Yspring_kill_eB : Yspring_kill_wB;
989             Cave[y][x+dx] = dx > 0 ? Yspring_kill_e : Yspring_kill_w;
990             Next[y][x] = Zplayer;
991             Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
992             play_element_sound(x, y, SAMPLE_slurp, Xalien);
993             lev.score += lev.slurp_score;
994             ply->x = x;
995             break;
996
997           case Xacid_1:
998           case Xacid_2:
999           case Xacid_3:
1000           case Xacid_4:
1001           case Xacid_5:
1002           case Xacid_6:
1003           case Xacid_7:
1004           case Xacid_8:
1005             if (Cave[y-1][x+dx+1] == Xblank)
1006               Cave[y-1][x+dx+1] = Yacid_splash_eB;
1007             if (Cave[y-1][x+dx-1] == Xblank)
1008               Cave[y-1][x+dx-1] = Yacid_splash_wB;
1009             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
1010             goto spring_walk;
1011
1012           case Xblank:
1013           case Yacid_splash_eB:
1014           case Yacid_splash_wB:
1015             Cave[y][x+dx] = dx > 0 ? Yspring_e : Yspring_w;
1016             Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
1017
1018           spring_walk:
1019             Cave[y][x] = dx > 0 ? Yspring_eB : Yspring_wB;
1020             Next[y][x] = Zplayer;
1021             play_element_sound(x, y, SAMPLE_roll, Xspring);
1022             ply->x = x;
1023         }
1024
1025         ply->anim = SPR_push + anim;
1026         break;
1027
1028       case Xspring_pause:
1029       case Xstone_pause:
1030       case Xbomb_pause:
1031       case Xnut_pause:
1032       case Xsand_stonein_1:
1033       case Xsand_stonein_2:
1034       case Xsand_stonein_3:
1035       case Xsand_stonein_4:
1036         if (dy)
1037           break;
1038
1039         ply->anim = SPR_push + anim;
1040         break;
1041
1042       case Xballoon:
1043         switch(Cave[y+dy][x+dx])
1044         {
1045           case Xacid_1:
1046           case Xacid_2:
1047           case Xacid_3:
1048           case Xacid_4:
1049           case Xacid_5:
1050           case Xacid_6:
1051           case Xacid_7:
1052           case Xacid_8:
1053             if (Cave[y+dy-1][x+dx+1] == Xblank)
1054               Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
1055             if (Cave[y+dy-1][x+dx-1] == Xblank)
1056               Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
1057             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
1058             goto balloon_walk;
1059
1060           case Xblank:
1061           case Yacid_splash_eB:
1062           case Yacid_splash_wB:
1063             Cave[y+dy][x+dx] = (dy ? (dy < 0 ? Yballoon_n : Yballoon_s) :
1064                                 (dx > 0 ? Yballoon_e : Yballoon_w));
1065             Next[y+dy][x+dx] = Xballoon;
1066
1067           balloon_walk:
1068             Cave[y][x] = (dy ? (dy < 0 ? Yballoon_nB : Yballoon_sB) :
1069                           (dx > 0 ? Yballoon_eB : Yballoon_wB));
1070             Next[y][x] = Zplayer;
1071             play_element_sound(x, y, SAMPLE_push, Xballoon);
1072             ply->x = x;
1073             ply->y = y;
1074         }
1075
1076         ply->anim = SPR_push + anim;
1077         break;
1078
1079       case Xandroid:
1080       case Xandroid_1_n:
1081       case Xandroid_2_n:
1082       case Xandroid_1_e:
1083       case Xandroid_2_e:
1084       case Xandroid_1_s:
1085       case Xandroid_2_s:
1086       case Xandroid_1_w:
1087       case Xandroid_2_w:
1088         switch(Cave[y+dy][x+dx])
1089         {
1090           case Xacid_1:
1091           case Xacid_2:
1092           case Xacid_3:
1093           case Xacid_4:
1094           case Xacid_5:
1095           case Xacid_6:
1096           case Xacid_7:
1097           case Xacid_8:
1098             if (Cave[y+dy-1][x+dx+1] == Xblank)
1099               Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
1100             if (Cave[y+dy-1][x+dx-1] == Xblank)
1101               Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
1102             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
1103             goto android_walk;
1104
1105           case Xblank:
1106           case Yacid_splash_eB:
1107           case Yacid_splash_wB:
1108             Cave[y+dy][x+dx] = (dy ? (dy < 0 ? Yandroid_n : Yandroid_s) :
1109                                 (dx > 0 ? Yandroid_e : Yandroid_w));
1110             Next[y+dy][x+dx] = (dy ? (dy < 0 ? Xandroid_2_n : Xandroid_2_s) :
1111                                 (dx > 0 ? Xandroid_2_e : Xandroid_2_w));
1112
1113           android_walk:
1114             Cave[y][x] = (dy ? (dy < 0 ? Yandroid_nB : Yandroid_sB) :
1115                           (dx > 0 ? Yandroid_eB : Yandroid_wB));
1116             Next[y][x] = Zplayer;
1117             play_element_sound(x, y, SAMPLE_push, Xandroid);
1118             ply->x = x;
1119             ply->y = y;
1120         }
1121
1122         ply->anim = SPR_push + anim;
1123         break;
1124
1125       case Xdoor_1:
1126       case Xfake_door_1:
1127         if (ply->keys & 0x01)
1128           goto door_walk;
1129         else
1130           break;
1131
1132       case Xdoor_2:
1133       case Xfake_door_2:
1134         if (ply->keys & 0x02)
1135           goto door_walk;
1136         else
1137           break;
1138
1139       case Xdoor_3:
1140       case Xfake_door_3:
1141         if (ply->keys & 0x04)
1142           goto door_walk;
1143         else
1144           break;
1145
1146       case Xdoor_4:
1147       case Xfake_door_4:
1148         if (ply->keys & 0x08)
1149           goto door_walk;
1150         else
1151           break;
1152
1153       case Xdoor_5:
1154       case Xfake_door_5:
1155         if (ply->keys & 0x10)
1156           goto door_walk;
1157         else
1158           break;
1159
1160       case Xdoor_6:
1161       case Xfake_door_6:
1162         if (ply->keys & 0x20)
1163           goto door_walk;
1164         else
1165           break;
1166
1167       case Xdoor_7:
1168       case Xfake_door_7:
1169         if (ply->keys & 0x40)
1170           goto door_walk;
1171         else
1172           break;
1173
1174       case Xdoor_8:
1175       case Xfake_door_8:
1176         if (ply->keys & 0x80)
1177           goto door_walk;
1178         else
1179           break;
1180
1181       door_walk:
1182         if (!tab_blank[Cave[y+dy][x+dx]])
1183           break;
1184
1185         Cave[y+dy][x+dx] = Zplayer;
1186         Next[y+dy][x+dx] = Zplayer;
1187         play_element_sound(x, y, SAMPLE_door, element);
1188         ply->anim = SPR_walk + anim;
1189         ply->x = x + dx;
1190         ply->y = y + dy;
1191         break;
1192
1193       case Xwheel:
1194         play_element_sound(x, y, SAMPLE_press, element);
1195         lev.wheel_cnt = lev.wheel_time;
1196         lev.wheel_x = x;
1197         lev.wheel_y = y;
1198         break;
1199
1200       case Xwind_n:
1201         lev.wind_direction = 0;
1202         goto wind_walk;
1203
1204       case Xwind_e:
1205         lev.wind_direction = 1;
1206         goto wind_walk;
1207
1208       case Xwind_s:
1209         lev.wind_direction = 2;
1210         goto wind_walk;
1211
1212       case Xwind_w:
1213         lev.wind_direction = 3;
1214         goto wind_walk;
1215
1216       case Xwind_nesw:
1217         lev.wind_direction = dy ? (dy < 0 ? 0 : 2) : (dx > 0 ? 1 : 3);
1218         goto wind_walk;
1219
1220       wind_walk:
1221         play_element_sound(x, y, SAMPLE_press, element);
1222         lev.wind_cnt = lev.wind_time;
1223         break;
1224
1225       case Xwind_stop:
1226         play_element_sound(x, y, SAMPLE_press, element);
1227         lev.wind_cnt = 0;
1228         break;
1229
1230       case Xswitch:
1231         play_element_sound(x, y, SAMPLE_press, element);
1232         lev.ball_cnt = lev.ball_time;
1233         lev.ball_state = !lev.ball_state;
1234         break;
1235
1236       case Xplant:
1237         Cave[y][x] = Yplant;
1238         Next[y][x] = Xplant;
1239         play_element_sound(x, y, SAMPLE_blank, Xplant);
1240         ply->anim = SPR_walk + anim;
1241         ply->x = x;
1242         ply->y = y;
1243         break;
1244
1245       case Xexit_1:
1246       case Xexit_2:
1247       case Xexit_3:
1248         play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
1249
1250         lev.home--;
1251
1252 #if 0
1253         /* !!! CHECK SCORE CALCULATION !!! */
1254         if (lev.home == 0 && lev.time_initial > 0)      /* game won */
1255           lev.score += lev.time * lev.exit_score / 100;
1256 #endif
1257
1258         ply->anim = SPR_walk + anim;
1259         ply->x = x;
1260         ply->y = y;
1261
1262         break;
1263     }
1264
1265     if (ply->x == oldx && ply->y == oldy)       /* no movement */
1266       result = FALSE;
1267   }
1268   else                                  /* player wants to snap */
1269   {
1270     int element = Cave[y][x];
1271
1272     switch(Cave[y][x])
1273     {
1274       /* fire is pressed */
1275
1276       case Xgrass:
1277         Cave[y][x] = Ygrass_eat;
1278         Next[y][x] = Xblank;
1279         play_element_sound(x, y, SAMPLE_dirt, element);
1280         ply->anim = SPR_spray + anim;
1281         break;
1282
1283       case Xdirt:
1284         Cave[y][x] = Ydirt_eat;
1285         Next[y][x] = Xblank;
1286         play_element_sound(x, y, SAMPLE_dirt, element);
1287         ply->anim = SPR_spray + anim;
1288         break;
1289
1290       case Xdiamond:
1291       case Xdiamond_pause:
1292         Cave[y][x] = Ydiamond_eat;
1293         Next[y][x] = Xblank;
1294         play_element_sound(x, y, SAMPLE_collect, element);
1295         lev.score += lev.diamond_score;
1296         lev.required = lev.required < 3 ? 0 : lev.required - 3;
1297         ply->anim = SPR_walk + anim;
1298         break;
1299
1300       case Xemerald:
1301       case Xemerald_pause:
1302         Cave[y][x] = Yemerald_eat;
1303         Next[y][x] = Xblank;
1304         play_element_sound(x, y, SAMPLE_collect, element);
1305         lev.score += lev.emerald_score;
1306         lev.required = lev.required < 1 ? 0 : lev.required - 1;
1307         ply->anim = SPR_walk + anim;
1308         break;
1309
1310       case Xdynamite:
1311         Cave[y][x] = Ydynamite_eat;
1312         Next[y][x] = Xblank;
1313         play_element_sound(x, y, SAMPLE_collect, element);
1314         lev.score += lev.dynamite_score;
1315         ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
1316         ply->anim = SPR_walk + anim;
1317         break;
1318
1319       case Xkey_1:
1320         ply->keys |= 0x01;
1321         Cave[y][x] = Ykey_1_eat;
1322         goto key_shoot;
1323
1324       case Xkey_2:
1325         ply->keys |= 0x02;
1326         Cave[y][x] = Ykey_2_eat;
1327         goto key_shoot;
1328
1329       case Xkey_3:
1330         ply->keys |= 0x04;
1331         Cave[y][x] = Ykey_3_eat;
1332         goto key_shoot;
1333
1334       case Xkey_4:
1335         ply->keys |= 0x08;
1336         Cave[y][x] = Ykey_4_eat;
1337         goto key_shoot;
1338
1339       case Xkey_5:
1340         ply->keys |= 0x10;
1341         Cave[y][x] = Ykey_5_eat;
1342         goto key_shoot;
1343
1344       case Xkey_6:
1345         ply->keys |= 0x20;
1346         Cave[y][x] = Ykey_6_eat;
1347         goto key_shoot;
1348
1349       case Xkey_7:
1350         ply->keys |= 0x40;
1351         Cave[y][x] = Ykey_7_eat;
1352         goto key_shoot;
1353
1354       case Xkey_8:
1355         ply->keys |= 0x80;
1356         Cave[y][x] = Ykey_8_eat;
1357         goto key_shoot;
1358
1359       key_shoot:
1360         Next[y][x] = Xblank;
1361         play_element_sound(x, y, SAMPLE_collect, element);
1362         lev.score += lev.key_score;
1363         ply->anim = SPR_walk + anim;
1364         break;
1365
1366       case Xlenses:
1367         Cave[y][x] = Ylenses_eat;
1368         Next[y][x] = Xblank;
1369         play_element_sound(x, y, SAMPLE_collect, element);
1370         lev.score += lev.lenses_score;
1371         lev.lenses_cnt = lev.lenses_time;
1372         ply->anim = SPR_walk + anim;
1373         break;
1374
1375       case Xmagnify:
1376         Cave[y][x] = Ymagnify_eat;
1377         Next[y][x] = Xblank;
1378         play_element_sound(x, y, SAMPLE_collect, element);
1379         lev.score += lev.magnify_score;
1380         lev.magnify_cnt = lev.magnify_time;
1381         ply->anim = SPR_walk + anim;
1382         break;
1383
1384       default:
1385         result = FALSE;
1386     }
1387   }
1388
1389   return result;
1390 }