rnd-20030402-1-src
[rocksndiamonds.git] / src / game.c
index fb21d6f62cafab430c342d9c7f88b9ee7473a34f..b6a7697e002a489f2044e0974fc2db401ddf02d6 100644 (file)
@@ -643,9 +643,10 @@ void InitGame()
     player->Pushing = FALSE;
     player->Switching = FALSE;
     player->GfxPos = 0;
-    player->Frame = 0;
-
+    player->GfxDir = MV_NO_MOVING;
     player->GfxAction = ACTION_DEFAULT;
+    player->Frame = 0;
+    player->StepFrame = 0;
 
     player->use_murphy_graphic = FALSE;
     player->use_disk_red_graphic = FALSE;
@@ -657,6 +658,8 @@ void InitGame()
 
     player->is_moving = FALSE;
     player->is_waiting = FALSE;
+    player->is_digging = FALSE;
+    player->is_collecting = FALSE;
 
     player->move_delay       = game.initial_move_delay;
     player->move_delay_value = game.initial_move_delay_value;
@@ -940,7 +943,7 @@ void InitGame()
 
   OpenDoor(DOOR_OPEN_ALL);
 
-  PlaySoundStereo(SND_GAME_STARTING, SOUND_MAX_RIGHT);
+  PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE);
   if (setup.sound_music)
     PlayMusic(level_nr);
 
@@ -1096,18 +1099,18 @@ void GameWon()
 
   local_player->LevelSolved = FALSE;
 
-  PlaySoundStereo(SND_GAME_WINNING, SOUND_MAX_RIGHT);
+  PlaySoundStereo(SND_GAME_WINNING, SOUND_MIDDLE);
 
   if (TimeLeft)
   {
     if (!tape.playing && setup.sound_loops)
-      PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+      PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
                   SND_CTRL_PLAY_LOOP);
 
     while (TimeLeft > 0)
     {
       if (!tape.playing && !setup.sound_loops)
-       PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT);
+       PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
       if (TimeLeft > 0 && !(TimeLeft % 10))
        RaiseScore(level.score[SC_ZEITBONUS]);
       if (TimeLeft > 100 && !(TimeLeft % 10))
@@ -1127,13 +1130,13 @@ void GameWon()
   else if (level.time == 0)            /* level without time limit */
   {
     if (!tape.playing && setup.sound_loops)
-      PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+      PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
                   SND_CTRL_PLAY_LOOP);
 
     while (TimePlayed < 999)
     {
       if (!tape.playing && !setup.sound_loops)
-       PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT);
+       PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
       if (TimePlayed < 999 && !(TimePlayed % 10))
        RaiseScore(level.score[SC_ZEITBONUS]);
       if (TimePlayed < 900 && !(TimePlayed % 10))
@@ -1261,12 +1264,19 @@ int NewHiScore()
   return position;
 }
 
-static void InitPlayerGfxAnimation(struct PlayerInfo *player, int action)
+void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir)
 {
-  if (player->GfxAction != action)
+  if (player->GfxAction != action || player->GfxDir != dir)
   {
+#if 0
+    printf("Player frame reset! (%d => %d, %d => %d)\n",
+          player->GfxAction, action, player->GfxDir, dir);
+#endif
+
     player->GfxAction = action;
+    player->GfxDir = dir;
     player->Frame = 0;
+    player->StepFrame = 0;
   }
 }
 
@@ -1374,6 +1384,7 @@ static int MovingOrBlocked2ElementIfNotLeaving(int x, int y)
 static void RemoveField(int x, int y)
 {
   Feld[x][y] = EL_EMPTY;
+  GfxElement[x][y] = EL_EMPTY;
   MovPos[x][y] = 0;
   MovDir[x][y] = 0;
   MovDelay[x][y] = 0;
@@ -1607,6 +1618,7 @@ void Explode(int ex, int ey, int phase, int mode)
       }
 
       Feld[x][y] = EL_EXPLOSION;
+      GfxElement[x][y] = EL_EMPTY;
       MovDir[x][y] = MovPos[x][y] = 0;
       AmoebaNr[x][y] = 0;
       ExplodePhase[x][y] = 1;
@@ -1678,7 +1690,7 @@ void Explode(int ex, int ey, int phase, int mode)
     int frame = getGraphicAnimationFrame(graphic, phase - delay);
 
     if (phase == delay)
-      DrawCrumbledSand(SCREENX(x), SCREENY(y));
+      DrawLevelFieldCrumbledSand(x, y);
 
     if (IS_PFORTE(Store[x][y]))
     {
@@ -3133,7 +3145,7 @@ void StartMoving(int x, int y)
        Feld[x][y] = EL_EMPTY;
        DrawLevelField(x, y);
 
-       PlaySoundLevel(newx, newy, SND_CLASS_EXIT_PASSING);
+       PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING);
        if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
          DrawGraphicThruMask(SCREENX(newx),SCREENY(newy), el2img(element), 0);
 
@@ -3387,7 +3399,7 @@ void ContinueMoving(int x, int y)
        yy = y + xy[i][1];
 
        if (IN_LEV_FIELD(xx, yy) && Feld[xx][yy] == EL_SAND)
-         DrawLevelField(xx, yy);       /* for "DrawCrumbledSand()" */
+         DrawLevelField(xx, yy);       /* for "crumbled sand" */
       }
     }
 
@@ -4372,7 +4384,7 @@ static void ChangeActiveTrap(int x, int y)
 
   /* if new animation frame was drawn, correct crumbled sand border */
   if (IS_NEW_FRAME(GfxFrame[x][y], graphic))
-    DrawCrumbledSand(SCREENX(x), SCREENY(y));
+    DrawLevelFieldCrumbledSand(x, y);
 }
 
 static void ChangeElement(int x, int y)
@@ -4465,7 +4477,13 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action)
     CheckGravityMovement(player);
 
     if (player->MovPos == 0)
-      InitPlayerGfxAnimation(player, ACTION_DEFAULT);
+    {
+#if 0
+      printf("Trying... Player frame reset\n");
+#endif
+
+      InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
+    }
 
     if (player->MovPos == 0)   /* needed for tape.playing */
       player->is_moving = FALSE;
@@ -4865,7 +4883,7 @@ void GameActions()
       TimeLeft--;
 
       if (TimeLeft <= 10 && setup.time_limit)
-       PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MAX_RIGHT);
+       PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
 
       DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
 
@@ -4898,12 +4916,31 @@ void GameActions()
     redraw_mask |= REDRAW_FPS;
   }
 
+#if 0
+  if (stored_player[0].jx != stored_player[0].last_jx ||
+      stored_player[0].jy != stored_player[0].last_jy)
+    printf("::: %d, %d, %d, %d, %d\n",
+          stored_player[0].MovDir,
+          stored_player[0].MovPos,
+          stored_player[0].GfxPos,
+          stored_player[0].Frame,
+          stored_player[0].StepFrame);
+#endif
+
 #if 1
   FrameCounter++;
   TimeFrames++;
 
   for (i=0; i<MAX_PLAYERS; i++)
-    stored_player[i].Frame++;
+  {
+    int move_frames =
+      MOVE_DELAY_NORMAL_SPEED /  stored_player[i].move_delay_value;
+
+    stored_player[i].Frame += move_frames;
+
+    if (stored_player[i].MovPos != 0)
+      stored_player[i].StepFrame += move_frames;
+  }
 #endif
 }
 
@@ -5200,7 +5237,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
     }
   }
 
-#if 1
+#if 0
 #if 1
   InitPlayerGfxAnimation(player, ACTION_DEFAULT);
 #else
@@ -5209,6 +5246,8 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
 #endif
 #endif
 
+  player->StepFrame = 0;
+
   if (moved & MF_MOVING)
   {
     if (old_jx != jx && old_jy == jy)
@@ -5216,7 +5255,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
     else if (old_jx == jx && old_jy != jy)
       player->MovDir = (old_jy < jy ? MV_DOWN : MV_UP);
 
-    DrawLevelField(jx, jy);    /* for "DrawCrumbledSand()" */
+    DrawLevelField(jx, jy);    /* for "crumbled sand" */
 
     player->last_move_dir = player->MovDir;
     player->is_moving = TRUE;
@@ -5628,7 +5667,11 @@ int DigField(struct PlayerInfo *player,
                        dy == +1 ? MV_DOWN : MV_NO_MOVING);
   int element;
 
-  player->is_digging = FALSE;
+  if (player->MovPos == 0)
+  {
+    player->is_digging = FALSE;
+    player->is_collecting = FALSE;
+  }
 
   if (player->MovPos == 0)
     player->Pushing = FALSE;
@@ -5685,11 +5728,14 @@ int DigField(struct PlayerInfo *player,
     case EL_SP_BASE:
     case EL_SP_BUGGY_BASE:
     case EL_SP_BUGGY_BASE_ACTIVATING:
+      RemoveField(x, y);
 #if 1
-      if (mode != DF_SNAP && element == EL_SAND)
-       GfxElement[x][y] = Feld[x][y];
+      if (mode != DF_SNAP && element != EL_EMPTY)
+      {
+       GfxElement[x][y] = (CAN_BE_CRUMBLED(element) ? EL_SAND : element);
+       player->is_digging = TRUE;
+      }
 #endif
-      RemoveField(x, y);
       PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
       break;
 
@@ -5703,6 +5749,13 @@ int DigField(struct PlayerInfo *player,
     case EL_PEARL:
     case EL_CRYSTAL:
       RemoveField(x, y);
+#if 1
+      if (mode != DF_SNAP)
+      {
+       GfxElement[x][y] = element;
+       player->is_collecting = TRUE;
+      }
+#endif
       local_player->gems_still_needed -= (element == EL_DIAMOND ? 3 :
                                          element == EL_PEARL ? 5 :
                                          element == EL_CRYSTAL ? 8 : 1);
@@ -5732,7 +5785,7 @@ int DigField(struct PlayerInfo *player,
        TimeLeft += 10;
        DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
       }
-      PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MAX_RIGHT);
+      PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MIDDLE);
       break;
 
     case EL_SHIELD_NORMAL:
@@ -6166,7 +6219,7 @@ int DigField(struct PlayerInfo *player,
       TimeLeft += 10;
       DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
       DrawLevelField(x, y);
-      PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MAX_RIGHT);
+      PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MIDDLE);
       return MF_ACTION;
       break;
 
@@ -6332,8 +6385,8 @@ int DigField(struct PlayerInfo *player,
 
   player->push_delay = 0;
 
-  if (Feld[x][y] != element)           /* really digged something */
-    player->is_digging = TRUE;
+  if (Feld[x][y] != element)           /* really digged/collected something */
+    player->is_collecting = !player->is_digging;
 
   return MF_MOVING;
 }
@@ -6355,7 +6408,13 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
       player->Pushing = FALSE;
 
     player->snapped = FALSE;
-    player->is_digging = FALSE;
+
+    if (player->MovPos == 0)
+    {
+      player->is_digging = FALSE;
+      player->is_collecting = FALSE;
+    }
+
     return FALSE;
   }
 
@@ -6372,6 +6431,8 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
 
   player->snapped = TRUE;
   player->is_digging = FALSE;
+  player->is_collecting = FALSE;
+
   DrawLevelField(x, y);
   BackToFront();