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