rnd-20060318-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   game_em.last_player_direction[ply->num] = MV_NONE;
456
457 #if 0
458   printf("::: up == %d, down == %d, left == %d, right == %d, fire == %d [spin == %d, stick == %d]\n",
459          ply->joy_n, ply->joy_s, ply->joy_w, ply->joy_e, ply->joy_fire,
460          ply->joy_spin, ply->joy_stick);
461 #endif
462
463 #if 1
464   if (ply->joy_w)               /* west */
465   {
466     x--;
467     dx = -1;
468     anim = 3;
469   }
470   else if (ply->joy_e)          /* east */
471   {
472     x++;
473     dx = 1;
474     anim = 1;
475   }
476
477   if (ply->joy_n)               /* north */
478   {
479     y--;
480     dy = -1;
481     anim = 0;
482   }
483   else if (ply->joy_s)          /* south */
484   {
485     y++;
486     dy = 1;
487     anim = 2;
488   }
489
490 #else
491
492   if ((ply->joy_spin = !ply->joy_spin))
493   {
494     if (ply->joy_n)             /* north */
495     {
496       y--;
497       dy = -1;
498       anim = 0;
499     }
500     else if (ply->joy_e)        /* east */
501     {
502       x++;
503       dx = 1;
504       anim = 1;
505     }
506     else if (ply->joy_s)        /* south */
507     {
508       y++;
509       dy = 1;
510       anim = 2;
511     }
512     else if (ply->joy_w)        /* west */
513     {
514       x--;
515       dx = -1;
516       anim = 3;
517     }
518   }
519   else
520   {
521     if (ply->joy_w)             /* west */
522     {
523       x--;
524       dx = -1;
525       anim = 3;
526     }
527     else if (ply->joy_s)        /* south */
528     {
529       y++;
530       dy = 1;
531       anim = 2;
532     }
533     else if (ply->joy_e)        /* east */
534     {
535       x++;
536       dx = 1;
537       anim = 1;
538     }
539     else if (ply->joy_n)        /* north */
540     {
541       y--;
542       dy = -1;
543       anim = 0;
544     }
545   }
546 #endif
547
548   if (dx || dy)
549   {
550     int oldx = ply->x;
551     int oldy = ply->y;
552     int x = oldx + dx;
553     int y = oldy + dy;
554     boolean can_move = TRUE;
555
556     ply->x = x;
557     ply->y = y;
558
559     can_move = (game.centered_player_nr != -1 ||
560                 checkIfAllPlayersFitToScreen());
561
562     ply->x = oldx;
563     ply->y = oldy;
564
565     if (!can_move)
566     {
567       ply->joy_n = ply->joy_e = ply->joy_s = ply->joy_w = 0;
568
569       return;
570     }
571   }
572
573   if (dx == 0 && dy == 0)
574   {
575     ply->joy_stick = 0;
576
577     if (ply->joy_drop)
578     {
579       if (++ply->dynamite_cnt == 5 && ply->dynamite)
580       {
581         Cave[y][x] = Xdynamite_1;
582         play_element_sound(x, y, SAMPLE_dynamite, Xdynamite_1);
583         ply->dynamite--;
584       }
585     }
586     else
587     {
588       ply->dynamite_cnt = 0;
589     }
590
591     RandomEM += 7;      /* be a bit more random if the player doesn't move */
592
593     return;
594   }
595
596   ply->joy_stick = 1;
597   ply->joy_n = ply->joy_e = ply->joy_s = ply->joy_w = 0;
598   ply->dynamite_cnt = 0;        /* reset dynamite timer if we move */
599   ply->joy_spin = !ply->joy_spin;
600
601   if (ply->joy_snap == 0)               /* player wants to move */
602   {
603     boolean moved = FALSE;
604
605     if (ply->last_move_dir & MV_HORIZONTAL)
606     {
607       if (!(moved = player_digfield(ply, 0, dy)))
608         moved = player_digfield(ply, dx, 0);
609     }
610     else
611     {
612       if (!(moved = player_digfield(ply, dx, 0)))
613         moved = player_digfield(ply, 0, dy);
614     }
615
616     if (moved)
617     {
618       if (oldx != ply->x)
619         ply->last_move_dir = (dx < 0 ? MV_LEFT : MV_RIGHT);
620       else if (oldy != ply->y)
621         ply->last_move_dir = (dy < 0 ? MV_UP : MV_DOWN);
622
623       game_em.any_player_moving = TRUE;
624       game_em.last_moving_player = ply->num;
625       game_em.last_player_direction[ply->num] = ply->last_move_dir;
626     }
627   }
628   else                                  /* player wants to snap */
629   {
630     player_digfield(ply, dx, dy);
631   }
632 }
633
634 static boolean player_digfield(struct PLAYER *ply, int dx, int dy)
635 {
636   int anim = (dx < 0 ? 3 : dx > 0 ? 1 : dy < 0 ? 0 : dy > 0 ? 2 : 2);
637   int oldx = ply->x;
638   int oldy = ply->y;
639   int x = oldx + dx;
640   int y = oldy + dy;
641   boolean result = TRUE;
642
643   if (!dx && !dy)                       /* no direction specified */
644     return FALSE;
645
646   if (dx && dy && ply->joy_snap)        /* more than one direction specified */
647     return FALSE;
648
649   if (ply->joy_snap == 0)               /* player wants to move */
650   {
651     int element = Cave[y][x];
652
653     switch(Cave[y][x])
654     {
655       /* fire is released */
656       case Xblank:
657       case Yacid_splash_eB:
658       case Yacid_splash_wB:
659         Cave[y][x] = Zplayer;
660         Next[y][x] = Zplayer;
661 #if 1
662       case Xfake_acid_1:
663       case Xfake_acid_2:
664       case Xfake_acid_3:
665       case Xfake_acid_4:
666       case Xfake_acid_5:
667       case Xfake_acid_6:
668       case Xfake_acid_7:
669       case Xfake_acid_8:
670 #endif
671         play_element_sound(x, y, SAMPLE_blank, Xblank);
672         ply->anim = SPR_walk + anim;
673         ply->x = x;
674         ply->y = y;
675         break;
676
677 #if 1
678       case Xacid_1:
679       case Xacid_2:
680       case Xacid_3:
681       case Xacid_4:
682       case Xacid_5:
683       case Xacid_6:
684       case Xacid_7:
685       case Xacid_8:
686 #endif
687         if (Cave[y-1][x+1] == Xblank)
688           Cave[y-1][x+1] = Yacid_splash_eB;
689         if (Cave[y-1][x-1] == Xblank)
690           Cave[y-1][x-1] = Yacid_splash_wB;
691         play_element_sound(x, y, SAMPLE_acid, Xacid_1);
692
693       case Xboom_android:
694       case Xboom_1:
695       case Xbug_n:
696       case Xbug_e:
697       case Xbug_s:
698       case Xbug_w:
699       case Xbug_gon:
700       case Xbug_goe:
701       case Xbug_gos:
702       case Xbug_gow:
703       case Xtank_n:
704       case Xtank_e:
705       case Xtank_s:
706       case Xtank_w:
707       case Xtank_gon:
708       case Xtank_goe:
709       case Xtank_gos:
710       case Xtank_gow:
711 #if 0
712       case Xacid_1:
713       case Xacid_2:
714       case Xacid_3:
715       case Xacid_4:
716       case Xacid_5:
717       case Xacid_6:
718       case Xacid_7:
719       case Xacid_8:
720 #endif
721         ply->anim = SPR_walk + anim;
722         ply->x = x;
723         ply->y = y;
724         break;
725
726       case Xgrass:
727         Cave[y][x] = (dy ? (dy < 0 ? Ygrass_nB : Ygrass_sB) :
728                       (dx > 0 ? Ygrass_eB : Ygrass_wB));
729         Next[y][x] = Zplayer;
730         play_element_sound(x, y, SAMPLE_dirt, Xgrass);
731         ply->anim = SPR_walk + anim;
732         ply->x = x;
733         ply->y = y;
734         break;
735
736       case Xdirt:
737         Cave[y][x] = (dy ? (dy < 0 ? Ydirt_nB : Ydirt_sB) :
738                       (dx > 0 ? Ydirt_eB : Ydirt_wB));
739         Next[y][x] = Zplayer;
740         play_element_sound(x, y, SAMPLE_dirt, Xdirt);
741         ply->anim = SPR_walk + anim;
742         ply->x = x;
743         ply->y = y;
744         break;
745
746       case Xdiamond:
747       case Xdiamond_pause:
748         Cave[y][x] = Ydiamond_eat;
749         Next[y][x] = Zplayer;
750         play_element_sound(x, y, SAMPLE_collect, element);
751         lev.score += lev.diamond_score;
752         lev.required = lev.required < 3 ? 0 : lev.required - 3;
753         ply->anim = SPR_walk + anim;
754         ply->x = x;
755         ply->y = y;
756         break;
757
758       case Xemerald:
759       case Xemerald_pause:
760         Cave[y][x] = Yemerald_eat;
761         Next[y][x] = Zplayer;
762         play_element_sound(x, y, SAMPLE_collect, element);
763         lev.score += lev.emerald_score;
764         lev.required = lev.required < 1 ? 0 : lev.required - 1;
765         ply->anim = SPR_walk + anim;
766         ply->x = x;
767         ply->y = y;
768         break;
769
770       case Xdynamite:
771         Cave[y][x] = Ydynamite_eat;
772         Next[y][x] = Zplayer;
773         play_element_sound(x, y, SAMPLE_collect, element);
774         lev.score += lev.dynamite_score;
775         ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
776         ply->anim = SPR_walk + anim;
777         ply->x = x;
778         ply->y = y;
779         break;
780
781       case Xkey_1:
782         ply->keys |= 0x01;
783         Cave[y][x] = Ykey_1_eat;
784         goto key_walk;
785
786       case Xkey_2:
787         ply->keys |= 0x02;
788         Cave[y][x] = Ykey_2_eat;
789         goto key_walk;
790
791       case Xkey_3:
792         ply->keys |= 0x04;
793         Cave[y][x] = Ykey_3_eat;
794         goto key_walk;
795
796       case Xkey_4:
797         ply->keys |= 0x08;
798         Cave[y][x] = Ykey_4_eat;
799         goto key_walk;
800
801       case Xkey_5:
802         ply->keys |= 0x10;
803         Cave[y][x] = Ykey_5_eat;
804         goto key_walk;
805
806       case Xkey_6:
807         ply->keys |= 0x20;
808         Cave[y][x] = Ykey_6_eat;
809         goto key_walk;
810
811       case Xkey_7:
812         ply->keys |= 0x40;
813         Cave[y][x] = Ykey_7_eat;
814         goto key_walk;
815
816       case Xkey_8:
817         ply->keys |= 0x80;
818         Cave[y][x] = Ykey_8_eat;
819         goto key_walk;
820
821       key_walk:
822
823         Next[y][x] = Zplayer;
824         play_element_sound(x, y, SAMPLE_collect, element);
825         lev.score += lev.key_score;
826         ply->anim = SPR_walk + anim;
827         ply->x = x;
828         ply->y = y;
829         break;
830
831       case Xlenses:
832         Cave[y][x] = Ylenses_eat;
833         Next[y][x] = Zplayer;
834         play_element_sound(x, y, SAMPLE_collect, element);
835         lev.score += lev.lenses_score;
836         lev.lenses_cnt = lev.lenses_time;
837         ply->anim = SPR_walk + anim;
838         ply->x = x;
839         ply->y = y;
840         break;
841
842       case Xmagnify:
843         Cave[y][x] = Ymagnify_eat;
844         Next[y][x] = Zplayer;
845         play_element_sound(x, y, SAMPLE_collect, element);
846         lev.score += lev.magnify_score;
847         lev.magnify_cnt = lev.magnify_time;
848         ply->anim = SPR_walk + anim;
849         ply->x = x;
850         ply->y = y;
851         break;
852
853       case Xstone:
854         if (dy)
855           break;
856
857         switch(Cave[y][x+dx])
858         {
859           case Xacid_1:
860           case Xacid_2:
861           case Xacid_3:
862           case Xacid_4:
863           case Xacid_5:
864           case Xacid_6:
865           case Xacid_7:
866           case Xacid_8:
867             if (Cave[y-1][x+dx+1] == Xblank)
868               Cave[y-1][x+dx+1] = Yacid_splash_eB;
869             if (Cave[y-1][x+dx-1] == Xblank)
870               Cave[y-1][x+dx-1] = Yacid_splash_wB;
871             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
872             goto stone_walk;
873
874           case Xblank:
875           case Yacid_splash_eB:
876           case Yacid_splash_wB:
877             Cave[y][x+dx] = dx > 0 ? Ystone_e : Ystone_w;
878             Next[y][x+dx] = Xstone_pause;
879
880           stone_walk:
881
882             Cave[y][x] = dx > 0 ? Ystone_eB : Ystone_wB;
883             Next[y][x] = Zplayer;
884             play_element_sound(x, y, SAMPLE_roll, Xstone);
885             ply->x = x;
886         }
887
888         ply->anim = SPR_push + anim;
889         break;
890
891       case Xbomb:
892         if (dy)
893           break;
894
895         switch(Cave[y][x+dx])
896         {
897           case Xacid_1:
898           case Xacid_2:
899           case Xacid_3:
900           case Xacid_4:
901           case Xacid_5:
902           case Xacid_6:
903           case Xacid_7:
904           case Xacid_8:
905             if (Cave[y-1][x+dx+1] == Xblank)
906               Cave[y-1][x+dx+1] = Yacid_splash_eB;
907             if (Cave[y-1][x+dx-1] == Xblank)
908               Cave[y-1][x+dx-1] = Yacid_splash_wB;
909             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
910             goto bomb_walk;
911
912           case Xblank:
913           case Yacid_splash_eB:
914           case Yacid_splash_wB:
915             Cave[y][x+dx] = dx > 0 ? Ybomb_e : Ybomb_w;
916             Next[y][x+dx] = Xbomb_pause;
917
918           bomb_walk:
919
920             Cave[y][x] = dx > 0 ? Ybomb_eB : Ybomb_wB;
921             Next[y][x] = Zplayer;
922             play_element_sound(x, y, SAMPLE_roll, Xbomb);
923             ply->x = x;
924         }
925
926         ply->anim = SPR_push + anim;
927         break;
928
929       case Xnut:
930         if (dy)
931           break;
932
933         switch(Cave[y][x+dx])
934         {
935           case Xacid_1:
936           case Xacid_2:
937           case Xacid_3:
938           case Xacid_4:
939           case Xacid_5:
940           case Xacid_6:
941           case Xacid_7:
942           case Xacid_8:
943             if (Cave[y-1][x+dx+1] == Xblank)
944               Cave[y-1][x+dx+1] = Yacid_splash_eB;
945             if (Cave[y-1][x+dx-1] == Xblank)
946               Cave[y-1][x+dx-1] = Yacid_splash_wB;
947             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
948             goto nut_walk;
949
950           case Xblank:
951           case Yacid_splash_eB:
952           case Yacid_splash_wB:
953             Cave[y][x+dx] = dx > 0 ? Ynut_e : Ynut_w;
954             Next[y][x+dx] = Xnut_pause;
955
956           nut_walk:
957
958             Cave[y][x] = dx > 0 ? Ynut_eB : Ynut_wB;
959             Next[y][x] = Zplayer;
960             play_element_sound(x, y, SAMPLE_roll, Xnut);
961             ply->x = x;
962         }
963
964         ply->anim = SPR_push + anim;
965         break;
966
967       case Xspring:
968         if (dy)
969           break;
970
971         switch(Cave[y][x+dx])
972         {
973           case Xalien:
974           case Xalien_pause:
975             Cave[y][x] = dx > 0 ? Yspring_kill_eB : Yspring_kill_wB;
976             Cave[y][x+dx] = dx > 0 ? Yspring_kill_e : Yspring_kill_w;
977             Next[y][x] = Zplayer;
978             Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
979             play_element_sound(x, y, SAMPLE_slurp, Xalien);
980             lev.score += lev.slurp_score;
981             ply->x = x;
982             break;
983
984           case Xacid_1:
985           case Xacid_2:
986           case Xacid_3:
987           case Xacid_4:
988           case Xacid_5:
989           case Xacid_6:
990           case Xacid_7:
991           case Xacid_8:
992             if (Cave[y-1][x+dx+1] == Xblank)
993               Cave[y-1][x+dx+1] = Yacid_splash_eB;
994             if (Cave[y-1][x+dx-1] == Xblank)
995               Cave[y-1][x+dx-1] = Yacid_splash_wB;
996             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
997             goto spring_walk;
998
999           case Xblank:
1000           case Yacid_splash_eB:
1001           case Yacid_splash_wB:
1002             Cave[y][x+dx] = dx > 0 ? Yspring_e : Yspring_w;
1003             Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
1004
1005           spring_walk:
1006             Cave[y][x] = dx > 0 ? Yspring_eB : Yspring_wB;
1007             Next[y][x] = Zplayer;
1008             play_element_sound(x, y, SAMPLE_roll, Xspring);
1009             ply->x = x;
1010         }
1011
1012         ply->anim = SPR_push + anim;
1013         break;
1014
1015       case Xspring_pause:
1016       case Xstone_pause:
1017       case Xbomb_pause:
1018       case Xnut_pause:
1019       case Xsand_stonein_1:
1020       case Xsand_stonein_2:
1021       case Xsand_stonein_3:
1022       case Xsand_stonein_4:
1023         if (dy)
1024           break;
1025
1026         ply->anim = SPR_push + anim;
1027         break;
1028
1029       case Xballoon:
1030         switch(Cave[y+dy][x+dx])
1031         {
1032           case Xacid_1:
1033           case Xacid_2:
1034           case Xacid_3:
1035           case Xacid_4:
1036           case Xacid_5:
1037           case Xacid_6:
1038           case Xacid_7:
1039           case Xacid_8:
1040             if (Cave[y+dy-1][x+dx+1] == Xblank)
1041               Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
1042             if (Cave[y+dy-1][x+dx-1] == Xblank)
1043               Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
1044             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
1045             goto balloon_walk;
1046
1047           case Xblank:
1048           case Yacid_splash_eB:
1049           case Yacid_splash_wB:
1050             Cave[y+dy][x+dx] = (dy ? (dy < 0 ? Yballoon_n : Yballoon_s) :
1051                                 (dx > 0 ? Yballoon_e : Yballoon_w));
1052             Next[y+dy][x+dx] = Xballoon;
1053
1054           balloon_walk:
1055             Cave[y][x] = (dy ? (dy < 0 ? Yballoon_nB : Yballoon_sB) :
1056                           (dx > 0 ? Yballoon_eB : Yballoon_wB));
1057             Next[y][x] = Zplayer;
1058             play_element_sound(x, y, SAMPLE_push, Xballoon);
1059             ply->x = x;
1060             ply->y = y;
1061         }
1062
1063         ply->anim = SPR_push + anim;
1064         break;
1065
1066       case Xandroid:
1067       case Xandroid_1_n:
1068       case Xandroid_2_n:
1069       case Xandroid_1_e:
1070       case Xandroid_2_e:
1071       case Xandroid_1_s:
1072       case Xandroid_2_s:
1073       case Xandroid_1_w:
1074       case Xandroid_2_w:
1075         switch(Cave[y+dy][x+dx])
1076         {
1077           case Xacid_1:
1078           case Xacid_2:
1079           case Xacid_3:
1080           case Xacid_4:
1081           case Xacid_5:
1082           case Xacid_6:
1083           case Xacid_7:
1084           case Xacid_8:
1085             if (Cave[y+dy-1][x+dx+1] == Xblank)
1086               Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
1087             if (Cave[y+dy-1][x+dx-1] == Xblank)
1088               Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
1089             play_element_sound(x, y, SAMPLE_acid, Xacid_1);
1090             goto android_walk;
1091
1092           case Xblank:
1093           case Yacid_splash_eB:
1094           case Yacid_splash_wB:
1095             Cave[y+dy][x+dx] = (dy ? (dy < 0 ? Yandroid_n : Yandroid_s) :
1096                                 (dx > 0 ? Yandroid_e : Yandroid_w));
1097             Next[y+dy][x+dx] = (dy ? (dy < 0 ? Xandroid_2_n : Xandroid_2_s) :
1098                                 (dx > 0 ? Xandroid_2_e : Xandroid_2_w));
1099
1100           android_walk:
1101             Cave[y][x] = (dy ? (dy < 0 ? Yandroid_nB : Yandroid_sB) :
1102                           (dx > 0 ? Yandroid_eB : Yandroid_wB));
1103             Next[y][x] = Zplayer;
1104             play_element_sound(x, y, SAMPLE_push, Xandroid);
1105             ply->x = x;
1106             ply->y = y;
1107         }
1108
1109         ply->anim = SPR_push + anim;
1110         break;
1111
1112       case Xdoor_1:
1113       case Xfake_door_1:
1114         if (ply->keys & 0x01)
1115           goto door_walk;
1116         else
1117           break;
1118
1119       case Xdoor_2:
1120       case Xfake_door_2:
1121         if (ply->keys & 0x02)
1122           goto door_walk;
1123         else
1124           break;
1125
1126       case Xdoor_3:
1127       case Xfake_door_3:
1128         if (ply->keys & 0x04)
1129           goto door_walk;
1130         else
1131           break;
1132
1133       case Xdoor_4:
1134       case Xfake_door_4:
1135         if (ply->keys & 0x08)
1136           goto door_walk;
1137         else
1138           break;
1139
1140       case Xdoor_5:
1141       case Xfake_door_5:
1142         if (ply->keys & 0x10)
1143           goto door_walk;
1144         else
1145           break;
1146
1147       case Xdoor_6:
1148       case Xfake_door_6:
1149         if (ply->keys & 0x20)
1150           goto door_walk;
1151         else
1152           break;
1153
1154       case Xdoor_7:
1155       case Xfake_door_7:
1156         if (ply->keys & 0x40)
1157           goto door_walk;
1158         else
1159           break;
1160
1161       case Xdoor_8:
1162       case Xfake_door_8:
1163         if (ply->keys & 0x80)
1164           goto door_walk;
1165         else
1166           break;
1167
1168       door_walk:
1169         if (!tab_blank[Cave[y+dy][x+dx]])
1170           break;
1171
1172         Cave[y+dy][x+dx] = Zplayer;
1173         Next[y+dy][x+dx] = Zplayer;
1174         play_element_sound(x, y, SAMPLE_door, element);
1175         ply->anim = SPR_walk + anim;
1176         ply->x = x + dx;
1177         ply->y = y + dy;
1178         break;
1179
1180       case Xwheel:
1181         play_element_sound(x, y, SAMPLE_press, element);
1182         lev.wheel_cnt = lev.wheel_time;
1183         lev.wheel_x = x;
1184         lev.wheel_y = y;
1185         break;
1186
1187       case Xwind_n:
1188         lev.wind_direction = 0;
1189         goto wind_walk;
1190
1191       case Xwind_e:
1192         lev.wind_direction = 1;
1193         goto wind_walk;
1194
1195       case Xwind_s:
1196         lev.wind_direction = 2;
1197         goto wind_walk;
1198
1199       case Xwind_w:
1200         lev.wind_direction = 3;
1201         goto wind_walk;
1202
1203       case Xwind_nesw:
1204         lev.wind_direction = dy ? (dy < 0 ? 0 : 2) : (dx > 0 ? 1 : 3);
1205         goto wind_walk;
1206
1207       wind_walk:
1208         play_element_sound(x, y, SAMPLE_press, element);
1209         lev.wind_cnt = lev.wind_time;
1210         break;
1211
1212       case Xwind_stop:
1213         play_element_sound(x, y, SAMPLE_press, element);
1214         lev.wind_cnt = 0;
1215         break;
1216
1217       case Xswitch:
1218         play_element_sound(x, y, SAMPLE_press, element);
1219         lev.ball_cnt = lev.ball_time;
1220         lev.ball_state = !lev.ball_state;
1221         break;
1222
1223       case Xplant:
1224         Cave[y][x] = Yplant;
1225         Next[y][x] = Xplant;
1226         play_element_sound(x, y, SAMPLE_blank, Xplant);
1227         ply->anim = SPR_walk + anim;
1228         ply->x = x;
1229         ply->y = y;
1230         break;
1231
1232       case Xexit_1:
1233       case Xexit_2:
1234       case Xexit_3:
1235         play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
1236
1237         lev.home--;
1238
1239 #if 0
1240         /* !!! CHECK SCORE CALCULATION !!! */
1241         if (lev.home == 0 && lev.time_initial > 0)      /* game won */
1242           lev.score += lev.time * lev.exit_score / 100;
1243 #endif
1244
1245         ply->anim = SPR_walk + anim;
1246         ply->x = x;
1247         ply->y = y;
1248
1249         break;
1250     }
1251
1252     if (ply->x == oldx && ply->y == oldy)       /* no movement */
1253       result = FALSE;
1254   }
1255   else                                  /* player wants to snap */
1256   {
1257     int element = Cave[y][x];
1258
1259     switch(Cave[y][x])
1260     {
1261       /* fire is pressed */
1262
1263       case Xgrass:
1264         Cave[y][x] = Ygrass_eat;
1265         Next[y][x] = Xblank;
1266         play_element_sound(x, y, SAMPLE_dirt, element);
1267         ply->anim = SPR_spray + anim;
1268         break;
1269
1270       case Xdirt:
1271         Cave[y][x] = Ydirt_eat;
1272         Next[y][x] = Xblank;
1273         play_element_sound(x, y, SAMPLE_dirt, element);
1274         ply->anim = SPR_spray + anim;
1275         break;
1276
1277       case Xdiamond:
1278       case Xdiamond_pause:
1279         Cave[y][x] = Ydiamond_eat;
1280         Next[y][x] = Xblank;
1281         play_element_sound(x, y, SAMPLE_collect, element);
1282         lev.score += lev.diamond_score;
1283         lev.required = lev.required < 3 ? 0 : lev.required - 3;
1284         ply->anim = SPR_walk + anim;
1285         break;
1286
1287       case Xemerald:
1288       case Xemerald_pause:
1289         Cave[y][x] = Yemerald_eat;
1290         Next[y][x] = Xblank;
1291         play_element_sound(x, y, SAMPLE_collect, element);
1292         lev.score += lev.emerald_score;
1293         lev.required = lev.required < 1 ? 0 : lev.required - 1;
1294         ply->anim = SPR_walk + anim;
1295         break;
1296
1297       case Xdynamite:
1298         Cave[y][x] = Ydynamite_eat;
1299         Next[y][x] = Xblank;
1300         play_element_sound(x, y, SAMPLE_collect, element);
1301         lev.score += lev.dynamite_score;
1302         ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
1303         ply->anim = SPR_walk + anim;
1304         break;
1305
1306       case Xkey_1:
1307         ply->keys |= 0x01;
1308         Cave[y][x] = Ykey_1_eat;
1309         goto key_shoot;
1310
1311       case Xkey_2:
1312         ply->keys |= 0x02;
1313         Cave[y][x] = Ykey_2_eat;
1314         goto key_shoot;
1315
1316       case Xkey_3:
1317         ply->keys |= 0x04;
1318         Cave[y][x] = Ykey_3_eat;
1319         goto key_shoot;
1320
1321       case Xkey_4:
1322         ply->keys |= 0x08;
1323         Cave[y][x] = Ykey_4_eat;
1324         goto key_shoot;
1325
1326       case Xkey_5:
1327         ply->keys |= 0x10;
1328         Cave[y][x] = Ykey_5_eat;
1329         goto key_shoot;
1330
1331       case Xkey_6:
1332         ply->keys |= 0x20;
1333         Cave[y][x] = Ykey_6_eat;
1334         goto key_shoot;
1335
1336       case Xkey_7:
1337         ply->keys |= 0x40;
1338         Cave[y][x] = Ykey_7_eat;
1339         goto key_shoot;
1340
1341       case Xkey_8:
1342         ply->keys |= 0x80;
1343         Cave[y][x] = Ykey_8_eat;
1344         goto key_shoot;
1345
1346       key_shoot:
1347         Next[y][x] = Xblank;
1348         play_element_sound(x, y, SAMPLE_collect, element);
1349         lev.score += lev.key_score;
1350         ply->anim = SPR_walk + anim;
1351         break;
1352
1353       case Xlenses:
1354         Cave[y][x] = Ylenses_eat;
1355         Next[y][x] = Xblank;
1356         play_element_sound(x, y, SAMPLE_collect, element);
1357         lev.score += lev.lenses_score;
1358         lev.lenses_cnt = lev.lenses_time;
1359         ply->anim = SPR_walk + anim;
1360         break;
1361
1362       case Xmagnify:
1363         Cave[y][x] = Ymagnify_eat;
1364         Next[y][x] = Xblank;
1365         play_element_sound(x, y, SAMPLE_collect, element);
1366         lev.score += lev.magnify_score;
1367         lev.magnify_cnt = lev.magnify_time;
1368         ply->anim = SPR_walk + anim;
1369         break;
1370
1371       default:
1372         result = FALSE;
1373     }
1374   }
1375
1376   return result;
1377 }