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