rnd-20020914-1-src
[rocksndiamonds.git] / src / game.c
index aa2d2464e3cd92a48f7c08c1d98907940098a525..a5620a017b0852734cf7f4998af10fabf0c098a9 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Rocks'n'Diamonds -- McDuffin Strikes Back!               *
 *----------------------------------------------------------*
-* (c) 1995-2001 Artsoft Entertainment                      *
+* (c) 1995-2002 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
 #define DX_TIME                        (DX + XX_TIME)
 #define DY_TIME                        (DY + YY_TIME)
 
+/* values for initial player move delay (initial delay counter value) */
+#define INITIAL_MOVE_DELAY_OFF -1
+#define INITIAL_MOVE_DELAY_ON  0
+
 /* values for player movement speed (which is in fact a delay value) */
 #define MOVE_DELAY_NORMAL_SPEED        8
 #define MOVE_DELAY_HIGH_SPEED  4
@@ -102,6 +106,7 @@ static void KillHeroUnlessProtected(int, int);
 
 void PlaySoundLevel(int, int, int);
 void PlaySoundLevelAction(int, int, int);
+void PlaySoundLevelElementAction(int, int, int, int);
 
 static void MapGameButtons();
 static void HandleGameButtons(struct GadgetInfo *);
@@ -111,12 +116,15 @@ static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS];
 #define SND_ACTION_UNKNOWN             0
 #define SND_ACTION_WAITING             1
 #define SND_ACTION_MOVING              2
-#define SND_ACTION_COLLECTING          3
-#define SND_ACTION_IMPACT              4
-#define SND_ACTION_PUSHING             5
-#define SND_ACTION_ACTIVATING          6
+#define SND_ACTION_DIGGING             3
+#define SND_ACTION_COLLECTING          4
+#define SND_ACTION_PASSING             5
+#define SND_ACTION_IMPACT              6
+#define SND_ACTION_PUSHING             7
+#define SND_ACTION_ACTIVATING          8
+#define SND_ACTION_BURNING             9
 
-#define NUM_SND_ACTIONS                        7
+#define NUM_SND_ACTIONS                        10
 
 static struct
 {
@@ -129,20 +137,23 @@ static struct
   { ".waiting",                SND_ACTION_WAITING,     TRUE },
   { ".moving",         SND_ACTION_MOVING,      TRUE }, /* continuos moving */
   { ".running",                SND_ACTION_UNKNOWN,     TRUE },
-  { ".burning",                SND_ACTION_UNKNOWN,     TRUE },
+  { ".burning",                SND_ACTION_BURNING,     TRUE },
   { ".growing",                SND_ACTION_UNKNOWN,     TRUE },
   { ".attacking",      SND_ACTION_UNKNOWN,     TRUE },
+  { ".activated",      SND_ACTION_UNKNOWN,     TRUE },
 
   /* other (non-loop) sound actions are optional */
   { ".stepping",       SND_ACTION_MOVING,      FALSE }, /* discrete moving */
+  { ".digging",                SND_ACTION_DIGGING,     FALSE },
   { ".collecting",     SND_ACTION_COLLECTING,  FALSE },
+  { ".passing",                SND_ACTION_PASSING,     FALSE },
   { ".impact",         SND_ACTION_IMPACT,      FALSE },
   { ".pushing",                SND_ACTION_PUSHING,     FALSE },
   { ".activating",     SND_ACTION_ACTIVATING,  FALSE },
   { NULL,              0,                      0 },
 };
 static int element_action_sound[NUM_LEVEL_ELEMENTS][NUM_SND_ACTIONS];
-static boolean is_loop_sound[NUM_SOUND_EFFECTS];
+static boolean is_loop_sound[NUM_SOUND_FILES];
 
 #define IS_LOOP_SOUND(x)       (is_loop_sound[x])
 
@@ -485,9 +496,18 @@ void DrawGameDoorValues()
           int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
 }
 
-void InitGameEngine()
+
+/*
+  =============================================================================
+  InitGameSound()
+  -----------------------------------------------------------------------------
+  initialize sound effect lookup table for element actions
+  =============================================================================
+*/
+
+void InitGameSound()
 {
-  static int sound_effect_properties[NUM_SOUND_EFFECTS];
+  int sound_effect_properties[NUM_SOUND_FILES];
   int i, j;
 
 #if 0
@@ -498,22 +518,21 @@ void InitGameEngine()
     for (j=0; j<NUM_LEVEL_ELEMENTS; j++)
       element_action_sound[j][i] = -1;
 
-  for (i=0; i<NUM_SOUND_EFFECTS; i++)
+  for (i=0; i<NUM_SOUND_FILES; i++)
   {
-    int len_effect_text = strlen(sound_effects[i].text);
+    int len_effect_text = strlen(sound_files[i].token);
 
     sound_effect_properties[i] = SND_ACTION_UNKNOWN;
     is_loop_sound[i] = FALSE;
 
     /* determine all loop sounds and identify certain sound classes */
 
-    j = 0;
-    while (sound_action_properties[j].text)
+    for (j=0; sound_action_properties[j].text; j++)
     {
       int len_action_text = strlen(sound_action_properties[j].text);
 
       if (len_action_text < len_effect_text &&
-         strcmp(&sound_effects[i].text[len_effect_text - len_action_text],
+         strcmp(&sound_files[i].token[len_effect_text - len_action_text],
                 sound_action_properties[j].text) == 0)
       {
        sound_effect_properties[i] = sound_action_properties[j].value;
@@ -521,8 +540,6 @@ void InitGameEngine()
        if (sound_action_properties[j].is_loop)
          is_loop_sound[i] = TRUE;
       }
-
-      j++;
     }
 
     /* associate elements and some selected sound actions */
@@ -533,9 +550,10 @@ void InitGameEngine()
       {
        int len_class_text = strlen(element_info[j].sound_class_name);
 
-       if (len_class_text < len_effect_text &&
-           strncmp(sound_effects[i].text,
-                   element_info[j].sound_class_name, len_class_text) == 0)
+       if (len_class_text + 1 < len_effect_text &&
+           strncmp(sound_files[i].token,
+                   element_info[j].sound_class_name, len_class_text) == 0 &&
+           sound_files[i].token[len_class_text] == '.')
        {
          int sound_action_value = sound_effect_properties[i];
 
@@ -552,8 +570,8 @@ void InitGameEngine()
 #if 0
   /* TEST ONLY */
   {
-    int element = EL_ROBOT;
-    int sound_action = SND_ACTION_COLLECTING;
+    int element = EL_ERDREICH;
+    int sound_action = SND_ACTION_DIGGING;
     int j = 0;
 
     while (sound_action_properties[j].text)
@@ -568,12 +586,87 @@ void InitGameEngine()
 #endif
 }
 
+
+/*
+  =============================================================================
+  InitGameEngine()
+  -----------------------------------------------------------------------------
+  initialize game engine due to level / tape version number
+  =============================================================================
+*/
+
+static void InitGameEngine()
+{
+  int i;
+
+  game.engine_version = (tape.playing ? tape.engine_version :
+                        level.game_version);
+
+#if 0
+    printf("level %d: level version == %06d\n", level_nr, level.game_version);
+    printf("          tape version == %06d [%s] [file: %06d]\n",
+          tape.engine_version, (tape.playing ? "PLAYING" : "RECORDING"),
+          tape.file_version);
+    printf("       => game.engine_version == %06d\n", game.engine_version);
+#endif
+
+  /* dynamically adjust player properties according to game engine version */
+  game.initial_move_delay =
+    (game.engine_version <= VERSION_IDENT(2,0,1) ? INITIAL_MOVE_DELAY_ON :
+     INITIAL_MOVE_DELAY_OFF);
+
+  /* dynamically adjust player properties according to level information */
+  game.initial_move_delay_value =
+    (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+
+  /* dynamically adjust element properties according to game engine version */
+  {
+    static int ep_em_slippery_wall[] =
+    {
+      EL_BETON,
+      EL_MAUERWERK,
+      EL_MAUER_LEBT,
+      EL_MAUER_X,
+      EL_MAUER_Y,
+      EL_MAUER_XY
+    };
+    static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
+
+    for (i=0; i<ep_em_slippery_wall_num; i++)
+    {
+      if (level.em_slippery_gems)      /* special EM style gems behaviour */
+       Elementeigenschaften2[ep_em_slippery_wall[i]] |=
+         EP_BIT_EM_SLIPPERY_WALL;
+      else
+       Elementeigenschaften2[ep_em_slippery_wall[i]] &=
+         ~EP_BIT_EM_SLIPPERY_WALL;
+    }
+
+    /* "EL_MAUERND" was not slippery for EM gems in version 2.0.1 */
+    if (level.em_slippery_gems && game.engine_version > VERSION_IDENT(2,0,1))
+      Elementeigenschaften2[EL_MAUERND] |=  EP_BIT_EM_SLIPPERY_WALL;
+    else
+      Elementeigenschaften2[EL_MAUERND] &= ~EP_BIT_EM_SLIPPERY_WALL;
+  }
+}
+
+
+/*
+  =============================================================================
+  InitGame()
+  -----------------------------------------------------------------------------
+  initialize and start new game
+  =============================================================================
+*/
+
 void InitGame()
 {
-  int i, j, x, y;
   boolean emulate_bd = TRUE;   /* unless non-BOULDERDASH elements found */
   boolean emulate_sb = TRUE;   /* unless non-SOKOBAN     elements found */
   boolean emulate_sp = TRUE;   /* unless non-SUPAPLEX    elements found */
+  int i, j, x, y;
+
+  InitGameEngine();
 
 #if DEBUG
 #if USE_NEW_AMOEBA_CODE
@@ -629,9 +722,8 @@ void InitGame()
     player->last_move_dir = MV_NO_MOVING;
     player->is_moving = FALSE;
 
-    player->move_delay = -1;   /* no initial move delay */
-    player->move_delay_value =
-      (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+    player->move_delay       = game.initial_move_delay;
+    player->move_delay_value = game.initial_move_delay_value;
 
     player->push_delay = 0;
     player->push_delay_value = 5;
@@ -722,6 +814,10 @@ void InitGame()
     }
   }
 
+  game.emulation = (emulate_bd ? EMU_BOULDERDASH :
+                   emulate_sb ? EMU_SOKOBAN :
+                   emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
+
   /* correct non-moving belts to start moving left */
   for (i=0; i<4; i++)
     if (game.belt_dir[i] == MV_NO_MOVING)
@@ -821,49 +917,6 @@ void InitGame()
     }
   }
 
-  game.version = (tape.playing ? tape.game_version : level.game_version);
-  game.emulation = (emulate_bd ? EMU_BOULDERDASH :
-                   emulate_sb ? EMU_SOKOBAN :
-                   emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
-
-  /* dynamically adjust element properties according to game engine version */
-  {
-    static int ep_em_slippery_wall[] =
-    {
-      EL_BETON,
-      EL_MAUERWERK,
-      EL_MAUER_LEBT,
-      EL_MAUER_X,
-      EL_MAUER_Y,
-      EL_MAUER_XY
-    };
-#if 1
-    static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
-#else
-    static int ep_em_slippery_wall_num =
-      sizeof(ep_em_slippery_wall) / sizeof(int);
-#endif
-
-    /*
-    printf("level %d: game.version == %06d\n", level_nr, level.game_version);
-    printf("         file_version == %06d\n", level.file_version);
-    */
-
-    for (i=0; i<ep_em_slippery_wall_num; i++)
-    {
-#if 1
-      if (level.em_slippery_gems)      /* special EM style gems behaviour */
-#else
-      if (game.version >= GAME_VERSION_2_0)
-#endif
-       Elementeigenschaften2[ep_em_slippery_wall[i]] |=
-         EP_BIT_EM_SLIPPERY_WALL;
-      else
-       Elementeigenschaften2[ep_em_slippery_wall[i]] &=
-         ~EP_BIT_EM_SLIPPERY_WALL;
-    }
-  }
-
   if (BorderElement == EL_LEERRAUM)
   {
     SBX_Left = 0;
@@ -1428,17 +1481,8 @@ void CheckDynamite(int x, int y)
     MovDelay[x][y]--;
     if (MovDelay[x][y])
     {
-#if 0
-      if (!(MovDelay[x][y] % 12))
-#else
       if (!(MovDelay[x][y] % 6))
-#endif
-      {
-       if (Feld[x][y] == EL_DYNAMITE_ACTIVE)
-         PlaySoundLevel(x, y, SND_DYNAMITE_BURNING);
-       else
-         PlaySoundLevel(x, y, SND_DYNABOMB_BURNING);
-      }
+       PlaySoundLevelAction(x, y, SND_ACTION_BURNING);
 
       if (IS_ACTIVE_BOMB(Feld[x][y]))
       {
@@ -2164,65 +2208,7 @@ void Impact(int x, int y)
 
   /* play sound of object that hits the ground */
   if (lastline || object_hit)
-  {
-    int sound;
-
-    switch (element)
-    {
-      case EL_EDELSTEIN_BD:
-        sound = SND_BD_DIAMOND_IMPACT;
-       break;
-      case EL_EDELSTEIN:
-      case EL_EDELSTEIN_GELB:
-      case EL_EDELSTEIN_ROT:
-      case EL_EDELSTEIN_LILA:
-        sound = SND_EMERALD_IMPACT;
-       break;
-      case EL_DIAMANT:
-        sound = SND_DIAMOND_IMPACT;
-       break;
-      case EL_PEARL:
-        sound = SND_PEARL_IMPACT;
-       break;
-      case EL_CRYSTAL:
-        sound = SND_CRYSTAL_IMPACT;
-       break;
-      case EL_SP_INFOTRON:
-        sound = SND_SP_INFOTRON_IMPACT;
-       break;
-      case EL_KOKOSNUSS:
-       sound = SND_NUT_IMPACT;
-       break;
-      case EL_BD_ROCK:
-       sound = SND_BD_ROCK_IMPACT;
-       break;
-      case EL_FELSBROCKEN:
-       sound = SND_ROCK_IMPACT;
-       break;
-      case EL_SP_ZONK:
-       sound = SND_SP_ZONK_IMPACT;
-       break;
-      case EL_ZEIT_VOLL:
-       sound = SND_TIME_ORB_FULL_IMPACT;
-       break;
-      case EL_ZEIT_LEER:
-       sound = SND_TIME_ORB_EMPTY_IMPACT;
-       break;
-      case EL_SPRING:
-       sound = SND_SPRING_IMPACT;
-       break;
-      default:
-       sound = -1;
-        break;
-    }
-
-#if 1
-    PlaySoundLevelAction(x, y, SND_ACTION_IMPACT);
-#else
-    if (sound >= 0)
-      PlaySoundLevel(x, y, sound);
-#endif
-  }
+    PlaySoundLevelElementAction(x, y, element, SND_ACTION_IMPACT);
 }
 
 void TurnRound(int x, int y)
@@ -3150,7 +3136,11 @@ void StartMoving(int x, int y)
       else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
        DrawGraphicAnimation(x, y, el2gfx(element), 2, 4, ANIM_NORMAL);
       else if (element == EL_SONDE)
+#if 0
        DrawGraphicAnimation(x, y, GFX_SONDE_START, 8, 2, ANIM_NORMAL);
+#else
+       DrawNewGraphicAnimation(x, y, IMG_SATELLITE_MOVING);
+#endif
       else if (element == EL_SP_ELECTRON)
        DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_NORMAL);
 
@@ -3504,9 +3494,9 @@ void AmoebeWaechst(int x, int y)
     if (DelayReached(&sound_delay, sound_delay_value))
     {
       if (Store[x][y] == EL_AMOEBE_BD)
-       PlaySoundLevel(x, y, SND_BD_AMOEBA_GROWING);
+       PlaySoundLevel(x, y, SND_BD_AMOEBA_CREATING);
       else
-       PlaySoundLevel(x, y, SND_AMOEBA_GROWING);
+       PlaySoundLevel(x, y, SND_AMOEBA_CREATING);
       sound_delay_value = 30;
     }
   }
@@ -3771,8 +3761,8 @@ void Life(int ax, int ay)
   }
 
   if (changed)
-    PlaySoundLevel(ax, ay, element == EL_LIFE ? SND_GAMEOFLIFE_GROWING :
-                  SND_BIOMAZE_GROWING);
+    PlaySoundLevel(ax, ay, element == EL_LIFE ? SND_GAMEOFLIFE_CREATING :
+                  SND_BIOMAZE_CREATING);
 }
 
 void RobotWheel(int x, int y)
@@ -3950,7 +3940,7 @@ void AusgangstuerOeffnen(int x, int y)
 
 void AusgangstuerBlinken(int x, int y)
 {
-  DrawGraphicAnimation(x, y, GFX_AUSGANG_AUF, 4, 4, ANIM_OSCILLATE);
+  DrawGraphicAnimation(x, y, GFX_AUSGANG_AUF, 4, 4, ANIM_PINGPONG);
 }
 
 void OpenSwitchgate(int x, int y)
@@ -4227,6 +4217,7 @@ void MauerAbleger(int ax, int ay)
        DrawGraphic(SCREENX(ax-1), SCREENY(ay), GFX_MAUER_LEFT);
       new_wall = TRUE;
     }
+
     if (rechts_frei)
     {
       Feld[ax+1][ay] = EL_MAUERND;
@@ -4806,14 +4797,18 @@ void GameActions()
     else if (element == EL_SHIELD_PASSIVE)
     {
       DrawGraphicAnimation(x, y, GFX_SHIELD_PASSIVE, 6, 4, ANIM_NORMAL);
+#if 0
       if (!(FrameCounter % 4))
        PlaySoundLevel(x, y, SND_SHIELD_PASSIVE_ACTIVATED);
+#endif
     }
     else if (element == EL_SHIELD_ACTIVE)
     {
       DrawGraphicAnimation(x, y, GFX_SHIELD_ACTIVE, 6, 4, ANIM_NORMAL);
+#if 0
       if (!(FrameCounter % 4))
        PlaySoundLevel(x, y, SND_SHIELD_ACTIVE_ACTIVATED);
+#endif
     }
 
     if (game.magic_wall_active)
@@ -4977,6 +4972,19 @@ void GameActions()
       CloseAllOpenTimegates();
   }
 
+  for (i=0; i<MAX_PLAYERS; i++)
+  {
+    struct PlayerInfo *player = &stored_player[i];
+
+    if (SHIELD_ON(player))
+    {
+      if (player->shield_active_time_left)
+       PlaySoundLevel(player->jx, player->jy, SND_SHIELD_ACTIVE_ACTIVATED);
+      else if (player->shield_passive_time_left)
+       PlaySoundLevel(player->jx, player->jy, SND_SHIELD_PASSIVE_ACTIVATED);
+    }
+  }
+
   if (TimeFrames >= (1000 / GameFrameDelay))
   {
     TimeFrames = 0;
@@ -4984,12 +4992,14 @@ void GameActions()
 
     for (i=0; i<MAX_PLAYERS; i++)
     {
-      if (SHIELD_ON(&stored_player[i]))
+      struct PlayerInfo *player = &stored_player[i];
+
+      if (SHIELD_ON(player))
       {
-       stored_player[i].shield_passive_time_left--;
+       player->shield_passive_time_left--;
 
-       if (stored_player[i].shield_active_time_left > 0)
-         stored_player[i].shield_active_time_left--;
+       if (player->shield_active_time_left > 0)
+         player->shield_active_time_left--;
       }
     }
 
@@ -5210,7 +5220,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
     return FALSE;
 #else
   if (!FrameReached(&player->move_delay, player->move_delay_value) &&
-      !(tape.playing && tape.game_version < GAME_VERSION_2_0))
+      !(tape.playing && tape.file_version < FILE_VERSION_2_0))
     return FALSE;
 #endif
 
@@ -5802,19 +5812,7 @@ int DigField(struct PlayerInfo *player,
     case EL_SP_BASE:
     case EL_SP_BUG:
       RemoveField(x, y);
-
-      if (element == EL_LEERRAUM)
-       PlaySoundLevel(x, y, SND_EMPTY_SPACE_DIGGING);
-      else if (element == EL_ERDREICH)
-       PlaySoundLevel(x, y, SND_SAND_DIGGING);
-      else if (element == EL_SAND_INVISIBLE)
-       PlaySoundLevel(x, y, SND_SAND_INVISIBLE_DIGGING);
-      else if (element == EL_TRAP_INACTIVE)
-       PlaySoundLevel(x, y, SND_TRAP_INACTIVE_DIGGING);
-      else if (element == EL_SP_BASE)
-       PlaySoundLevel(x, y, SND_SP_BASE_DIGGING);
-      else if (element == EL_SP_BUG)
-       PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_DIGGING);
+      PlaySoundLevelElementAction(x, y, element, SND_ACTION_DIGGING);
       break;
 
     case EL_EDELSTEIN:
@@ -5836,19 +5834,7 @@ int DigField(struct PlayerInfo *player,
       DrawText(DX_EMERALDS, DY_EMERALDS,
               int2str(local_player->gems_still_needed, 3),
               FS_SMALL, FC_YELLOW);
-
-      if (element == EL_EDELSTEIN_BD)
-       PlaySoundLevel(x, y, SND_BD_DIAMOND_COLLECTING);
-      else if (element == EL_DIAMANT)
-       PlaySoundLevel(x, y, SND_DIAMOND_COLLECTING);
-      else if (element == EL_SP_INFOTRON)
-       PlaySoundLevel(x, y, SND_SP_INFOTRON_COLLECTING);
-      else if (element == EL_PEARL)
-       PlaySoundLevel(x, y, SND_PEARL_COLLECTING);
-      else if (element == EL_CRYSTAL)
-       PlaySoundLevel(x, y, SND_CRYSTAL_COLLECTING);
-      else     /* EL_EDELSTEIN style element */
-       PlaySoundLevel(x, y, SND_EMERALD_COLLECTING);
+      PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
       break;
 
     case EL_SPEED_PILL:
@@ -5893,10 +5879,7 @@ int DigField(struct PlayerInfo *player,
       DrawText(DX_DYNAMITE, DY_DYNAMITE,
               int2str(local_player->dynamite, 3),
               FS_SMALL, FC_YELLOW);
-      if (element == EL_SP_DISK_RED)
-       PlaySoundLevel(x, y, SND_SP_DISK_RED_COLLECTING);
-      else
-       PlaySoundLevel(x, y, SND_DYNAMITE_COLLECTING);
+      PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
       break;
 
     case EL_DYNABOMB_NR:
@@ -6101,7 +6084,7 @@ int DigField(struct PlayerInfo *player,
        return MF_NO_ACTION;
 #else
       if (!FrameReached(&player->push_delay, player->push_delay_value) &&
-         !(tape.playing && tape.game_version < GAME_VERSION_2_0) &&
+         !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
          element != EL_SPRING)
        return MF_NO_ACTION;
 #endif
@@ -6126,24 +6109,7 @@ int DigField(struct PlayerInfo *player,
       player->push_delay_value = (element == EL_SPRING ? 0 : 2 + RND(8));
 
       DrawLevelField(x+dx, y+dy);
-      if (element == EL_FELSBROCKEN)
-       PlaySoundLevel(x+dx, y+dy, SND_ROCK_PUSHING);
-      else if (element == EL_BD_ROCK)
-       PlaySoundLevel(x+dx, y+dy, SND_BD_ROCK_PUSHING);
-      else if (element == EL_BOMBE)
-       PlaySoundLevel(x+dx, y+dy, SND_BOMB_PUSHING);
-      else if (element == EL_DX_SUPABOMB)
-       PlaySoundLevel(x+dx, y+dy, SND_DX_BOMB_PUSHING);
-      else if (element == EL_KOKOSNUSS)
-       PlaySoundLevel(x+dx, y+dy, SND_NUT_PUSHING);
-      else if (element == EL_ZEIT_LEER)
-       PlaySoundLevel(x+dx, y+dy, SND_TIME_ORB_EMPTY_PUSHING);
-      else if (element == EL_SP_ZONK)
-       PlaySoundLevel(x+dx, y+dy, SND_SP_ZONK_PUSHING);
-      else if (element == EL_SP_DISK_ORANGE)
-       PlaySoundLevel(x+dx, y+dy, SND_SP_DISK_ORANGE_PUSHING);
-      else if (element == EL_SPRING)
-       PlaySoundLevel(x+dx, y+dy, SND_SPRING_PUSHING);
+      PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
       break;
 
     case EL_PFORTE1:
@@ -6176,7 +6142,6 @@ int DigField(struct PlayerInfo *player,
       DOUBLE_PLAYER_SPEED(player);
 
       PlaySoundLevel(x, y, SND_GATE_PASSING);
-
       break;
 
     case EL_EM_GATE_1X:
@@ -6193,7 +6158,6 @@ int DigField(struct PlayerInfo *player,
       DOUBLE_PLAYER_SPEED(player);
 
       PlaySoundLevel(x, y, SND_GATE_PASSING);
-
       break;
 
     case EL_SWITCHGATE_OPEN:
@@ -6205,11 +6169,7 @@ int DigField(struct PlayerInfo *player,
       player->programmed_action = move_direction;
       DOUBLE_PLAYER_SPEED(player);
 
-      if (element == EL_SWITCHGATE_OPEN)
-       PlaySoundLevel(x, y, SND_SWITCHGATE_PASSING);
-      else
-       PlaySoundLevel(x, y, SND_TIMEGATE_PASSING);
-
+      PlaySoundLevelElementAction(x, y, element, SND_ACTION_PASSING);
       break;
 
     case EL_SP_PORT1_LEFT:
@@ -6366,7 +6326,7 @@ int DigField(struct PlayerInfo *player,
        return MF_NO_ACTION;
 #else
       if (!FrameReached(&player->push_delay, player->push_delay_value) &&
-         !(tape.playing && tape.game_version < GAME_VERSION_2_0) &&
+         !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
          element != EL_BALLOON)
        return MF_NO_ACTION;
 #endif
@@ -6403,18 +6363,13 @@ int DigField(struct PlayerInfo *player,
       {
        RemoveField(x, y);
        Feld[x+dx][y+dy] = element;
+       PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
       }
 
       player->push_delay_value = (element == EL_BALLOON ? 0 : 2);
 
       DrawLevelField(x, y);
       DrawLevelField(x+dx, y+dy);
-      if (element == EL_SONDE)
-       PlaySoundLevel(x+dx, y+dy, SND_SATELLITE_PUSHING);
-      else if (element == EL_SP_DISK_YELLOW)
-       PlaySoundLevel(x+dx, y+dy, SND_SP_DISK_YELLOW_PUSHING);
-      else if (element == EL_BALLOON)
-       PlaySoundLevel(x+dx, y+dy, SND_BALLOON_PUSHING);
 
       if (IS_SB_ELEMENT(element) &&
          local_player->sokobanfields_still_needed == 0 &&
@@ -6528,8 +6483,8 @@ boolean PlaceBomb(struct PlayerInfo *player)
 
 void PlaySoundLevel(int x, int y, int nr)
 {
-  static int loop_sound_frame[NUM_SOUND_EFFECTS];
-  static int loop_sound_volume[NUM_SOUND_EFFECTS];
+  static int loop_sound_frame[NUM_SOUND_FILES];
+  static int loop_sound_volume[NUM_SOUND_FILES];
   int sx = SCREENX(x), sy = SCREENY(y);
   int volume, stereo_position;
   int max_distance = 8;
@@ -6575,86 +6530,15 @@ void PlaySoundLevel(int x, int y, int nr)
 
 void PlaySoundLevelAction(int x, int y, int sound_action)
 {
-  int element = Feld[x][y];
+  PlaySoundLevelElementAction(x, y, Feld[x][y], sound_action);
+}
+
+void PlaySoundLevelElementAction(int x, int y, int element, int sound_action)
+{
   int sound_effect = element_action_sound[element][sound_action];
 
-#if 1
   if (sound_effect != -1)
     PlaySoundLevel(x, y, sound_effect);
-#else
-  if (sound_action == SND_ACTION_MOVING)
-  {
-    if (element == EL_KAEFER)
-      PlaySoundLevel(x, y, SND_BUG_MOVING);
-    else if (element == EL_FLIEGER)
-      PlaySoundLevel(x, y, SND_SPACESHIP_MOVING);
-    else if (element == EL_BUTTERFLY)
-      PlaySoundLevel(x, y, SND_BD_BUTTERFLY_MOVING);
-    else if (element == EL_FIREFLY)
-      PlaySoundLevel(x, y, SND_BD_FIREFLY_MOVING);
-    else if (element == EL_SP_SNIKSNAK)
-      PlaySoundLevel(x, y, SND_SP_SNIKSNAK_MOVING);
-    else if (element == EL_SP_ELECTRON)
-      PlaySoundLevel(x, y, SND_SP_ELECTRON_MOVING);
-    else if (element == EL_MAMPFER)
-      PlaySoundLevel(x, y, SND_YAMYAM_MOVING);
-    else if (element == EL_MAMPFER2)
-      PlaySoundLevel(x, y, SND_DARK_YAMYAM_MOVING);
-    else if (element == EL_BALLOON)
-      PlaySoundLevel(x, y, SND_BALLOON_MOVING);
-    else if (element == EL_SPRING_MOVING)
-      PlaySoundLevel(x, y, SND_SPRING_MOVING);
-    else if (element == EL_MOLE)
-      PlaySoundLevel(x, y, SND_MOLE_MOVING);
-    else if (element == EL_SONDE)
-      PlaySoundLevel(x, y, SND_SATELLITE_MOVING);
-    else if (element == EL_PACMAN)
-      PlaySoundLevel(x, y, SND_PACMAN_MOVING);
-    else if (element == EL_PINGUIN)
-      PlaySoundLevel(x, y, SND_PENGUIN_MOVING);
-    else if (element == EL_SCHWEIN)
-      PlaySoundLevel(x, y, SND_PIG_MOVING);
-    else if (element == EL_DRACHE)
-      PlaySoundLevel(x, y, SND_DRAGON_MOVING);
-    else if (element == EL_ROBOT)
-      PlaySoundLevel(x, y, SND_ROBOT_STEPPING);
-  }
-  else if (sound_action == SND_ACTION_WAITING)
-  {
-    if (element == EL_KAEFER)
-      PlaySoundLevel(x, y, SND_BUG_WAITING);
-    else if (element == EL_FLIEGER)
-      PlaySoundLevel(x, y, SND_SPACESHIP_WAITING);
-    else if (element == EL_BUTTERFLY)
-      PlaySoundLevel(x, y, SND_BD_BUTTERFLY_WAITING);
-    else if (element == EL_FIREFLY)
-      PlaySoundLevel(x, y, SND_BD_FIREFLY_WAITING);
-    else if (element == EL_SP_SNIKSNAK)
-      PlaySoundLevel(x, y, SND_SP_SNIKSNAK_WAITING);
-    else if (element == EL_SP_ELECTRON)
-      PlaySoundLevel(x, y, SND_SP_ELECTRON_WAITING);
-    else if (element == EL_MAMPFER)
-      PlaySoundLevel(x, y, SND_YAMYAM_WAITING);
-    else if (element == EL_MAMPFER2)
-      PlaySoundLevel(x, y, SND_DARK_YAMYAM_WAITING);
-    else if (element == EL_BALLOON)
-      PlaySoundLevel(x, y, SND_BALLOON_WAITING);
-    else if (element == EL_MOLE)
-      PlaySoundLevel(x, y, SND_MOLE_WAITING);
-    else if (element == EL_SONDE)
-      PlaySoundLevel(x, y, SND_SATELLITE_WAITING);
-    else if (element == EL_PACMAN)
-      PlaySoundLevel(x, y, SND_PACMAN_WAITING);
-    else if (element == EL_PINGUIN)
-      PlaySoundLevel(x, y, SND_PENGUIN_WAITING);
-    else if (element == EL_SCHWEIN)
-      PlaySoundLevel(x, y, SND_PIG_WAITING);
-    else if (element == EL_DRACHE)
-      PlaySoundLevel(x, y, SND_DRAGON_WAITING);
-    else if (element == EL_ROBOT)
-      PlaySoundLevel(x, y, SND_ROBOT_WAITING);
-  }
-#endif
 }
 
 void RaiseScore(int value)