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