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