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