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