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