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