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