rnd-20050314-1-src
[rocksndiamonds.git] / src / game_em / synchro_1.c
index 695d52f378875387336beb665f990a8df5fb4836..c5b2c456b4910ed38eae9452f42b29d4f17d1edb 100644 (file)
@@ -8,22 +8,24 @@
 #include "tile.h"
 #include "level.h"
 #include "sample.h"
+#include "display.h"
 
 
-static void player(struct PLAYER *);
-static int test(struct PLAYER *);
-static void die(struct PLAYER *);
+static void check_player(struct PLAYER *);
+static void kill_player(struct PLAYER *);
+static boolean player_digfield(struct PLAYER *, int, int);
+static boolean player_killed(struct PLAYER *);
 
 void synchro_1(void)
 {
  /* must test for death and actually kill separately */
-  char ply1_kill = test(&ply1);
-  char ply2_kill = test(&ply2);
+  boolean ply1_kill = player_killed(&ply1);
+  boolean ply2_kill = player_killed(&ply2);
 
   if (ply1.alive && ply1_kill)
-    die(&ply1);
+    kill_player(&ply1);
   if (ply2.alive && ply2_kill)
-    die(&ply2);
+    kill_player(&ply2);
 
 #if 0
   ply1.alive = 1; /* debugging */
@@ -38,13 +40,13 @@ void synchro_1(void)
 
   if (Random & 256)
   {
-    if (ply1.alive) player(&ply1);
-    if (ply2.alive) player(&ply2);
+    if (ply1.alive) check_player(&ply1);
+    if (ply2.alive) check_player(&ply2);
   }
   else
   {
-    if (ply2.alive) player(&ply2);
-    if (ply1.alive) player(&ply1);
+    if (ply2.alive) check_player(&ply2);
+    if (ply1.alive) check_player(&ply1);
   }
 
   if (ply1.alive)
@@ -78,13 +80,21 @@ void synchro_1(void)
   }
 }
 
-static int test(struct PLAYER *ply)
+static boolean player_killed(struct PLAYER *ply)
 {
   register unsigned int x = ply->x;
   register unsigned int y = ply->y;
 
-  if (lev.time == 0)
-    return(1);
+  if (!ply->alive)
+    return FALSE;
+
+#if 1
+  if (lev.killed_out_of_time && setup.time_limit)
+    return TRUE;
+#else
+  if (lev.time_initial > 0 && lev.time == 0 && setup.time_limit)
+    return TRUE;
+#endif
 
   switch(Cave[y-1][x])
   {
@@ -104,7 +114,7 @@ static int test(struct PLAYER *ply)
     case Xtank_goe:
     case Xtank_gos:
     case Xtank_gow:
-      return(1);
+      return TRUE;
   }
 
   switch(Cave[y][x+1])
@@ -125,7 +135,7 @@ static int test(struct PLAYER *ply)
     case Xtank_goe:
     case Xtank_gos:
     case Xtank_gow:
-      return(1);
+      return TRUE;
   }
 
   switch(Cave[y+1][x])
@@ -146,7 +156,7 @@ static int test(struct PLAYER *ply)
     case Xtank_goe:
     case Xtank_gos:
     case Xtank_gow:
-      return(1);
+      return TRUE;
   }
 
   switch(Cave[y][x-1])
@@ -167,7 +177,7 @@ static int test(struct PLAYER *ply)
     case Xtank_goe:
     case Xtank_gos:
     case Xtank_gow:
-      return(1);
+      return TRUE;
   }
 
   switch(Cave[y][x])
@@ -180,13 +190,23 @@ static int test(struct PLAYER *ply)
     case Xdynamite_2:
     case Xdynamite_3:
     case Xdynamite_4:
-      return(0);
+#if 1
+    case Xfake_acid_1:
+    case Xfake_acid_2:
+    case Xfake_acid_3:
+    case Xfake_acid_4:
+    case Xfake_acid_5:
+    case Xfake_acid_6:
+    case Xfake_acid_7:
+    case Xfake_acid_8:
+#endif
+      return FALSE;
   }
 
-  return(1);
+  return TRUE;
 }
 
-static void die(struct PLAYER *ply)
+static void kill_player(struct PLAYER *ply)
 {
   register unsigned int x = ply->x;
   register unsigned int y = ply->y;
@@ -204,6 +224,9 @@ static void die(struct PLAYER *ply)
     case Xbug_gos:
     case Xbug_gow:
       Cave[y-1][x] = Xboom_bug;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
 
     case Xtank_n:
@@ -215,6 +238,9 @@ static void die(struct PLAYER *ply)
     case Xtank_gos:
     case Xtank_gow:
       Cave[y-1][x] = Xboom_bomb;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
   }
 
@@ -229,6 +255,9 @@ static void die(struct PLAYER *ply)
     case Xbug_gos:
     case Xbug_gow:
       Cave[y][x+1] = Xboom_bug;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
 
     case Xtank_n:
@@ -240,6 +269,9 @@ static void die(struct PLAYER *ply)
     case Xtank_gos:
     case Xtank_gow:
       Cave[y][x+1] = Xboom_bomb;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
   }
 
@@ -254,6 +286,9 @@ static void die(struct PLAYER *ply)
     case Xbug_gos:
     case Xbug_gow:
       Cave[y+1][x] = Xboom_bug;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
 
     case Xtank_n:
@@ -265,6 +300,9 @@ static void die(struct PLAYER *ply)
     case Xtank_gos:
     case Xtank_gow:
       Cave[y+1][x] = Xboom_bomb;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
   }
 
@@ -279,6 +317,9 @@ static void die(struct PLAYER *ply)
     case Xbug_gos:
     case Xbug_gow:
       Cave[y][x-1] = Xboom_bug;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
 
     case Xtank_n:
@@ -290,6 +331,9 @@ static void die(struct PLAYER *ply)
     case Xtank_gos:
     case Xtank_gow:
       Cave[y][x-1] = Xboom_bomb;
+#if 0
+      play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
       break;
   }
 
@@ -298,98 +342,145 @@ static void die(struct PLAYER *ply)
     case Xexit_1:
     case Xexit_2:
     case Xexit_3:
-      play[SAMPLE_exit] = 1;
+      play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
       break;
 
     default:
-      play[SAMPLE_die] = 1;
+      play_element_sound(x, y, SAMPLE_die, Zplayer);
       break;
   }
 
-  Cave[y][x] = Xboom_1;
-  Boom[y][x] = Xblank;
+  switch(Cave[y][x])
+  {
+#if 1
+    case Xacid_1:
+    case Xacid_2:
+    case Xacid_3:
+    case Xacid_4:
+    case Xacid_5:
+    case Xacid_6:
+    case Xacid_7:
+    case Xacid_8:
+      break;
+#endif
+
+    default:
+      Cave[y][x] = Xboom_1;
+      Boom[y][x] = Xblank;
+      break;
+  }
 }
 
-static void player(struct PLAYER *ply)
+static void check_player(struct PLAYER *ply)
 {
-  register unsigned int x = ply->x;
-  register unsigned int y = ply->y;
-  unsigned int anim = 0;       /* initialized to make compilers happy */
+  unsigned int oldx = ply->x;
+  unsigned int oldy = ply->y;
+  register unsigned int x = oldx;
+  register unsigned int y = oldy;
+  unsigned int anim = 0;
   int dx = 0, dy = 0;
 
+#if 0
+  printf("::: up == %d, down == %d, left == %d, right == %d, fire == %d [spin == %d, stick == %d]\n",
+        ply->joy_n, ply->joy_s, ply->joy_w, ply->joy_e, ply->joy_fire,
+        ply->joy_spin, ply->joy_stick);
+#endif
+
+#if 1
+  if (ply->joy_w)              /* west */
+  {
+    x--;
+    dx = -1;
+    anim = 3;
+  }
+  else if (ply->joy_e)         /* east */
+  {
+    x++;
+    dx = 1;
+    anim = 1;
+  }
+
+  if (ply->joy_n)              /* north */
+  {
+    y--;
+    dy = -1;
+    anim = 0;
+  }
+  else if (ply->joy_s)         /* south */
+  {
+    y++;
+    dy = 1;
+    anim = 2;
+  }
+
+#else
+
   if ((ply->joy_spin = !ply->joy_spin))
   {
-    if (ply->joy_n)
+    if (ply->joy_n)            /* north */
     {
       y--;
       dy = -1;
       anim = 0;
-      /* north */
     }
-    else if (ply->joy_e)
+    else if (ply->joy_e)       /* east */
     {
       x++;
       dx = 1;
       anim = 1;
-      /* east */
     }
-    else if (ply->joy_s)
+    else if (ply->joy_s)       /* south */
     {
       y++;
       dy = 1;
       anim = 2;
-      /* south */
     }
-    else if (ply->joy_w)
+    else if (ply->joy_w)       /* west */
     {
       x--;
       dx = -1;
       anim = 3;
-      /* west */
     }
   }
   else
   {
-    if (ply->joy_w)
+    if (ply->joy_w)            /* west */
     {
       x--;
       dx = -1;
       anim = 3;
-      /* west */
     }
-    else if (ply->joy_s)
+    else if (ply->joy_s)       /* south */
     {
       y++;
       dy = 1;
       anim = 2;
-      /* south */
     }
-    else if (ply->joy_e)
+    else if (ply->joy_e)       /* east */
     {
       x++;
       dx = 1;
       anim = 1;
-      /* east */
     }
-    else if (ply->joy_n)
+    else if (ply->joy_n)       /* north */
     {
       y--;
       dy = -1;
       anim = 0;
-      /* north */
     }
   }
+#endif
 
   if (dx == 0 && dy == 0)
   {
     ply->joy_stick = 0;
 
-    if (ply->joy_fire)
+    if (ply->joy_drop)
     {
       if (++ply->dynamite_cnt == 5 && ply->dynamite)
       {
        Cave[y][x] = Xdynamite_1;
-       play[SAMPLE_dynamite] = 1;
+       play_element_sound(x, y, SAMPLE_dynamite, Xdynamite_1);
        ply->dynamite--;
       }
     }
@@ -398,7 +489,7 @@ static void player(struct PLAYER *ply)
       ply->dynamite_cnt = 0;
     }
 
-    Random += 7; /* bit more random if we dont move */
+    Random += 7;       /* be a bit more random if the player doesn't move */
 
     return;
   }
@@ -406,9 +497,56 @@ static void player(struct PLAYER *ply)
   ply->joy_stick = 1;
   ply->joy_n = ply->joy_e = ply->joy_s = ply->joy_w = 0;
   ply->dynamite_cnt = 0; /* reset dynamite timer if we move */
+  ply->joy_spin = !ply->joy_spin;
+
+  if (ply->joy_snap == 0)              /* player wants to move */
+  {
+    boolean moved = FALSE;
 
-  if (ply->joy_fire == 0)
+    if (ply->last_move_dir & MV_HORIZONTAL)
+    {
+      if (!(moved = player_digfield(ply, 0, dy)))
+       moved = player_digfield(ply, dx, 0);
+    }
+    else
+    {
+      if (!(moved = player_digfield(ply, dx, 0)))
+       moved = player_digfield(ply, 0, dy);
+    }
+
+    if (moved)
+    {
+      if (oldx != ply->x)
+       ply->last_move_dir = (dx < 0 ? MV_LEFT : MV_RIGHT);
+      else if (oldy != ply->y)
+       ply->last_move_dir = (dy < 0 ? MV_UP : MV_DOWN);
+    }
+  }
+  else                                 /* player wants to snap */
   {
+    player_digfield(ply, dx, dy);
+  }
+}
+
+static boolean player_digfield(struct PLAYER *ply, int dx, int dy)
+{
+  int anim = (dx < 0 ? 3 : dx > 0 ? 1 : dy < 0 ? 0 : dy > 0 ? 2 : 2);
+  unsigned int oldx = ply->x;
+  unsigned int oldy = ply->y;
+  register unsigned int x = oldx + dx;
+  register unsigned int y = oldy + dy;
+  boolean result = TRUE;
+
+  if (!dx && !dy)                      /* no direction specified */
+    return FALSE;
+
+  if (dx && dy && ply->joy_snap)       /* more than one direction specified */
+    return FALSE;
+
+  if (ply->joy_snap == 0)              /* player wants to move */
+  {
+    int element = Cave[y][x];
+
     switch(Cave[y][x])
     {
       /* fire is released */
@@ -417,12 +555,38 @@ static void player(struct PLAYER *ply)
       case Yacid_splash_wB:
        Cave[y][x] = Zplayer;
        Next[y][x] = Zplayer;
-       play[SAMPLE_blank] = 1;
+#if 1
+      case Xfake_acid_1:
+      case Xfake_acid_2:
+      case Xfake_acid_3:
+      case Xfake_acid_4:
+      case Xfake_acid_5:
+      case Xfake_acid_6:
+      case Xfake_acid_7:
+      case Xfake_acid_8:
+#endif
+       play_element_sound(x, y, SAMPLE_blank, Xblank);
        ply->anim = SPR_walk + anim;
        ply->x = x;
        ply->y = y;
        break;
 
+#if 1
+      case Xacid_1:
+      case Xacid_2:
+      case Xacid_3:
+      case Xacid_4:
+      case Xacid_5:
+      case Xacid_6:
+      case Xacid_7:
+      case Xacid_8:
+#endif
+       if (Cave[y-1][x+1] == Xblank)
+         Cave[y-1][x+1] = Yacid_splash_eB;
+       if (Cave[y-1][x-1] == Xblank)
+         Cave[y-1][x-1] = Yacid_splash_wB;
+       play_element_sound(x, y, SAMPLE_acid, Xacid_1);
+
       case Xboom_android:
       case Xboom_1:
       case Xbug_n:
@@ -441,6 +605,7 @@ static void player(struct PLAYER *ply)
       case Xtank_goe:
       case Xtank_gos:
       case Xtank_gow:
+#if 0
       case Xacid_1:
       case Xacid_2:
       case Xacid_3:
@@ -449,6 +614,7 @@ static void player(struct PLAYER *ply)
       case Xacid_6:
       case Xacid_7:
       case Xacid_8:
+#endif
        ply->anim = SPR_walk + anim;
        ply->x = x;
        ply->y = y;
@@ -458,7 +624,7 @@ static void player(struct PLAYER *ply)
        Cave[y][x] = (dy ? (dy < 0 ? Ygrass_nB : Ygrass_sB) :
                      (dx > 0 ? Ygrass_eB : Ygrass_wB));
        Next[y][x] = Zplayer;
-       play[SAMPLE_dirt] = 1;
+       play_element_sound(x, y, SAMPLE_dirt, Xgrass);
        ply->anim = SPR_walk + anim;
        ply->x = x;
        ply->y = y;
@@ -468,7 +634,7 @@ static void player(struct PLAYER *ply)
        Cave[y][x] = (dy ? (dy < 0 ? Ydirt_nB : Ydirt_sB) :
                      (dx > 0 ? Ydirt_eB : Ydirt_wB));
        Next[y][x] = Zplayer;
-       play[SAMPLE_dirt] = 1;
+       play_element_sound(x, y, SAMPLE_dirt, Xdirt);
        ply->anim = SPR_walk + anim;
        ply->x = x;
        ply->y = y;
@@ -478,7 +644,7 @@ static void player(struct PLAYER *ply)
       case Xdiamond_pause:
        Cave[y][x] = Ydiamond_eat;
        Next[y][x] = Zplayer;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.diamond_score;
        lev.required = lev.required < 3 ? 0 : lev.required - 3;
        ply->anim = SPR_walk + anim;
@@ -490,7 +656,7 @@ static void player(struct PLAYER *ply)
       case Xemerald_pause:
        Cave[y][x] = Yemerald_eat;
        Next[y][x] = Zplayer;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.emerald_score;
        lev.required = lev.required < 1 ? 0 : lev.required - 1;
        ply->anim = SPR_walk + anim;
@@ -501,7 +667,7 @@ static void player(struct PLAYER *ply)
       case Xdynamite:
        Cave[y][x] = Ydynamite_eat;
        Next[y][x] = Zplayer;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.dynamite_score;
        ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
        ply->anim = SPR_walk + anim;
@@ -511,41 +677,48 @@ static void player(struct PLAYER *ply)
 
       case Xkey_1:
        ply->keys |= 0x01;
+       Cave[y][x] = Ykey_1_eat;
        goto key_walk;
 
       case Xkey_2:
        ply->keys |= 0x02;
+       Cave[y][x] = Ykey_2_eat;
        goto key_walk;
 
       case Xkey_3:
        ply->keys |= 0x04;
+       Cave[y][x] = Ykey_3_eat;
        goto key_walk;
 
       case Xkey_4:
        ply->keys |= 0x08;
+       Cave[y][x] = Ykey_4_eat;
        goto key_walk;
 
       case Xkey_5:
        ply->keys |= 0x10;
+       Cave[y][x] = Ykey_5_eat;
        goto key_walk;
 
       case Xkey_6:
        ply->keys |= 0x20;
+       Cave[y][x] = Ykey_6_eat;
        goto key_walk;
 
       case Xkey_7:
        ply->keys |= 0x40;
+       Cave[y][x] = Ykey_7_eat;
        goto key_walk;
 
       case Xkey_8:
        ply->keys |= 0x80;
+       Cave[y][x] = Ykey_8_eat;
        goto key_walk;
 
       key_walk:
 
-       Cave[y][x] = Yball_eat;
        Next[y][x] = Zplayer;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.key_score;
        ply->anim = SPR_walk + anim;
        ply->x = x;
@@ -553,9 +726,9 @@ static void player(struct PLAYER *ply)
        break;
 
       case Xlenses:
-       Cave[y][x] = Yball_eat;
+       Cave[y][x] = Ylenses_eat;
        Next[y][x] = Zplayer;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.lenses_score;
        lev.lenses_cnt = lev.lenses_time;
        ply->anim = SPR_walk + anim;
@@ -564,9 +737,9 @@ static void player(struct PLAYER *ply)
        break;
 
       case Xmagnify:
-       Cave[y][x] = Yball_eat;
+       Cave[y][x] = Ymagnify_eat;
        Next[y][x] = Zplayer;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.magnify_score;
        lev.magnify_cnt = lev.magnify_time;
        ply->anim = SPR_walk + anim;
@@ -592,7 +765,7 @@ static void player(struct PLAYER *ply)
              Cave[y-1][x+dx+1] = Yacid_splash_eB;
            if (Cave[y-1][x+dx-1] == Xblank)
              Cave[y-1][x+dx-1] = Yacid_splash_wB;
-           play[SAMPLE_acid] = 1;
+           play_element_sound(x, y, SAMPLE_acid, Xacid_1);
            goto stone_walk;
 
           case Xblank:
@@ -605,7 +778,7 @@ static void player(struct PLAYER *ply)
 
            Cave[y][x] = dx > 0 ? Ystone_eB : Ystone_wB;
            Next[y][x] = Zplayer;
-           play[SAMPLE_roll] = 1;
+           play_element_sound(x, y, SAMPLE_roll, Xstone);
            ply->x = x;
        }
 
@@ -630,7 +803,7 @@ static void player(struct PLAYER *ply)
              Cave[y-1][x+dx+1] = Yacid_splash_eB;
            if (Cave[y-1][x+dx-1] == Xblank)
              Cave[y-1][x+dx-1] = Yacid_splash_wB;
-           play[SAMPLE_acid] = 1;
+           play_element_sound(x, y, SAMPLE_acid, Xacid_1);
            goto bomb_walk;
 
          case Xblank:
@@ -643,7 +816,7 @@ static void player(struct PLAYER *ply)
 
            Cave[y][x] = dx > 0 ? Ybomb_eB : Ybomb_wB;
            Next[y][x] = Zplayer;
-           play[SAMPLE_roll] = 1;
+           play_element_sound(x, y, SAMPLE_roll, Xbomb);
            ply->x = x;
        }
 
@@ -668,7 +841,7 @@ static void player(struct PLAYER *ply)
              Cave[y-1][x+dx+1] = Yacid_splash_eB;
            if (Cave[y-1][x+dx-1] == Xblank)
              Cave[y-1][x+dx-1] = Yacid_splash_wB;
-           play[SAMPLE_acid] = 1;
+           play_element_sound(x, y, SAMPLE_acid, Xacid_1);
            goto nut_walk;
 
           case Xblank:
@@ -681,7 +854,7 @@ static void player(struct PLAYER *ply)
 
            Cave[y][x] = dx > 0 ? Ynut_eB : Ynut_wB;
            Next[y][x] = Zplayer;
-           play[SAMPLE_roll] = 1;
+           play_element_sound(x, y, SAMPLE_roll, Xnut);
            ply->x = x;
        }
 
@@ -700,7 +873,7 @@ static void player(struct PLAYER *ply)
            Cave[y][x+dx] = dx > 0 ? Yspring_kill_e : Yspring_kill_w;
            Next[y][x] = Zplayer;
            Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
-           play[SAMPLE_slurp] = 1;
+           play_element_sound(x, y, SAMPLE_slurp, Xalien);
            lev.score += lev.slurp_score;
            ply->x = x;
            break;
@@ -717,7 +890,7 @@ static void player(struct PLAYER *ply)
              Cave[y-1][x+dx+1] = Yacid_splash_eB;
            if (Cave[y-1][x+dx-1] == Xblank)
              Cave[y-1][x+dx-1] = Yacid_splash_wB;
-           play[SAMPLE_acid] = 1;
+           play_element_sound(x, y, SAMPLE_acid, Xacid_1);
            goto spring_walk;
 
           case Xblank:
@@ -729,7 +902,7 @@ static void player(struct PLAYER *ply)
          spring_walk:
            Cave[y][x] = dx > 0 ? Yspring_eB : Yspring_wB;
            Next[y][x] = Zplayer;
-           play[SAMPLE_roll] = 1;
+           play_element_sound(x, y, SAMPLE_roll, Xspring);
            ply->x = x;
        }
 
@@ -765,7 +938,7 @@ static void player(struct PLAYER *ply)
              Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
            if (Cave[y+dy-1][x+dx-1] == Xblank)
              Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
-           play[SAMPLE_acid] = 1;
+           play_element_sound(x, y, SAMPLE_acid, Xacid_1);
            goto balloon_walk;
 
           case Xblank:
@@ -779,7 +952,7 @@ static void player(struct PLAYER *ply)
            Cave[y][x] = (dy ? (dy < 0 ? Yballoon_nB : Yballoon_sB) :
                          (dx > 0 ? Yballoon_eB : Yballoon_wB));
            Next[y][x] = Zplayer;
-           play[SAMPLE_push] = 1;
+           play_element_sound(x, y, SAMPLE_push, Xballoon);
            ply->x = x;
            ply->y = y;
        }
@@ -810,7 +983,7 @@ static void player(struct PLAYER *ply)
              Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
            if (Cave[y+dy-1][x+dx-1] == Xblank)
              Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
-           play[SAMPLE_acid] = 1;
+           play_element_sound(x, y, SAMPLE_acid, Xacid_1);
            goto android_walk;
 
           case Xblank:
@@ -825,7 +998,7 @@ static void player(struct PLAYER *ply)
            Cave[y][x] = (dy ? (dy < 0 ? Yandroid_nB : Yandroid_sB) :
                          (dx > 0 ? Yandroid_eB : Yandroid_wB));
            Next[y][x] = Zplayer;
-           play[SAMPLE_push] = 1;
+           play_element_sound(x, y, SAMPLE_push, Xandroid);
            ply->x = x;
            ply->y = y;
        }
@@ -895,14 +1068,14 @@ static void player(struct PLAYER *ply)
 
        Cave[y+dy][x+dx] = Zplayer;
        Next[y+dy][x+dx] = Zplayer;
-       play[SAMPLE_door] = 1;
+       play_element_sound(x, y, SAMPLE_door, element);
        ply->anim = SPR_walk + anim;
        ply->x = x + dx;
        ply->y = y + dy;
        break;
 
       case Xwheel:
-       play[SAMPLE_press] = 1;
+       play_element_sound(x, y, SAMPLE_press, element);
        lev.wheel_cnt = lev.wheel_time;
        lev.wheel_x = x;
        lev.wheel_y = y;
@@ -929,17 +1102,17 @@ static void player(struct PLAYER *ply)
        goto wind_walk;
 
       wind_walk:
-       play[SAMPLE_press] = 1;
+       play_element_sound(x, y, SAMPLE_press, element);
        lev.wind_cnt = lev.wind_time;
        break;
 
       case Xwind_stop:
-       play[SAMPLE_press] = 1;
+       play_element_sound(x, y, SAMPLE_press, element);
        lev.wind_cnt = 0;
        break;
 
       case Xswitch:
-       play[SAMPLE_press] = 1;
+       play_element_sound(x, y, SAMPLE_press, element);
        lev.ball_cnt = lev.ball_time;
        lev.ball_state = !lev.ball_state;
        break;
@@ -947,7 +1120,7 @@ static void player(struct PLAYER *ply)
       case Xplant:
        Cave[y][x] = Yplant;
        Next[y][x] = Xplant;
-       play[SAMPLE_blank] = 1;
+       play_element_sound(x, y, SAMPLE_blank, Xplant);
        ply->anim = SPR_walk + anim;
        ply->x = x;
        ply->y = y;
@@ -956,26 +1129,45 @@ static void player(struct PLAYER *ply)
       case Xexit_1:
       case Xexit_2:
       case Xexit_3:
-       play[SAMPLE_exit] = 1;
-       if (--lev.home == 0)
+       play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
+
+       lev.home--;
+
+#if 0
+       /* !!! CHECK SCORE CALCULATION !!! */
+       if (lev.home == 0 && lev.time_initial > 0)      /* game won */
          lev.score += lev.time * lev.exit_score / 100;
+#endif
+
        ply->anim = SPR_walk + anim;
        ply->x = x;
        ply->y = y;
+
        break;
     }
+
+    if (ply->x == oldx && ply->y == oldy)      /* no movement */
+      result = FALSE;
   }
-  else
+  else                                 /* player wants to snap */
   {
+    int element = Cave[y][x];
+
     switch(Cave[y][x])
     {
       /* fire is pressed */
 
       case Xgrass:
+       Cave[y][x] = Ygrass_eat;
+       Next[y][x] = Xblank;
+       play_element_sound(x, y, SAMPLE_dirt, element);
+       ply->anim = SPR_spray + anim;
+       break;
+
       case Xdirt:
-       Cave[y][x] = Yball_eat;
+       Cave[y][x] = Ydirt_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_dirt] = 1;
+       play_element_sound(x, y, SAMPLE_dirt, element);
        ply->anim = SPR_spray + anim;
        break;
 
@@ -983,7 +1175,7 @@ static void player(struct PLAYER *ply)
       case Xdiamond_pause:
        Cave[y][x] = Ydiamond_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.diamond_score;
        lev.required = lev.required < 3 ? 0 : lev.required - 3;
        ply->anim = SPR_walk + anim;
@@ -993,7 +1185,7 @@ static void player(struct PLAYER *ply)
       case Xemerald_pause:
        Cave[y][x] = Yemerald_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.emerald_score;
        lev.required = lev.required < 1 ? 0 : lev.required - 1;
        ply->anim = SPR_walk + anim;
@@ -1002,7 +1194,7 @@ static void player(struct PLAYER *ply)
       case Xdynamite:
        Cave[y][x] = Ydynamite_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.dynamite_score;
        ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
        ply->anim = SPR_walk + anim;
@@ -1010,61 +1202,73 @@ static void player(struct PLAYER *ply)
 
       case Xkey_1:
        ply->keys |= 0x01;
+       Cave[y][x] = Ykey_1_eat;
        goto key_shoot;
 
       case Xkey_2:
        ply->keys |= 0x02;
+       Cave[y][x] = Ykey_2_eat;
        goto key_shoot;
 
       case Xkey_3:
        ply->keys |= 0x04;
+       Cave[y][x] = Ykey_3_eat;
        goto key_shoot;
 
       case Xkey_4:
        ply->keys |= 0x08;
+       Cave[y][x] = Ykey_4_eat;
        goto key_shoot;
 
       case Xkey_5:
        ply->keys |= 0x10;
+       Cave[y][x] = Ykey_5_eat;
        goto key_shoot;
 
       case Xkey_6:
        ply->keys |= 0x20;
+       Cave[y][x] = Ykey_6_eat;
        goto key_shoot;
 
       case Xkey_7:
        ply->keys |= 0x40;
+       Cave[y][x] = Ykey_7_eat;
        goto key_shoot;
 
       case Xkey_8:
        ply->keys |= 0x80;
+       Cave[y][x] = Ykey_8_eat;
        goto key_shoot;
 
       key_shoot:
-       Cave[y][x] = Yball_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.key_score;
        ply->anim = SPR_walk + anim;
        break;
 
       case Xlenses:
-       Cave[y][x] = Yball_eat;
+       Cave[y][x] = Ylenses_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.lenses_score;
        lev.lenses_cnt = lev.lenses_time;
        ply->anim = SPR_walk + anim;
        break;
 
       case Xmagnify:
-       Cave[y][x] = Yball_eat;
+       Cave[y][x] = Ymagnify_eat;
        Next[y][x] = Xblank;
-       play[SAMPLE_collect] = 1;
+       play_element_sound(x, y, SAMPLE_collect, element);
        lev.score += lev.magnify_score;
        lev.magnify_cnt = lev.magnify_time;
        ply->anim = SPR_walk + anim;
        break;
+
+      default:
+       result = FALSE;
     }
   }
+
+  return result;
 }