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