rnd-19980820
[rocksndiamonds.git] / src / game.c
index dbc5458281c82836719c2db85724588faebd3b11..c75c9dd466177a3bbd8cbab9d79879e9853492e1 100644 (file)
@@ -49,6 +49,7 @@ void GetPlayerConfig()
   joystick_nr = SETUP_2ND_JOYSTICK_ON(player.setup);
   quick_doors = SETUP_QUICK_DOORS_ON(player.setup);
   scroll_delay_on = SETUP_SCROLL_DELAY_ON(player.setup);
+  soft_scrolling_on = SETUP_SOFT_SCROLL_ON(player.setup);
 
   if (joystick_nr != old_joystick_nr)
   {
@@ -74,6 +75,7 @@ void InitGame()
   FrameCounter = 0;
   TimeFrames = 0;
   TimeLeft = level.time;
+  ScreenMovPos = 0;
   PlayerMovDir = MV_NO_MOVING;
   PlayerMovPos = 0;
   PlayerFrame = 0;
@@ -105,8 +107,8 @@ void InitGame()
       case EL_SPIELFIGUR:
       case EL_SPIELER1:
        Feld[x][y] = EL_LEERRAUM;
-       JX = x;
-       JY = y;
+       JX = lastJX = x;
+       JY = lastJY = y;
        break;
       case EL_SPIELER2:
        Feld[x][y] = EL_LEERRAUM;
@@ -1390,6 +1392,15 @@ void StartMoving(int x, int y)
 
   if (CAN_FALL(element) && y<lev_fieldy-1)
   {
+    if (PlayerPushing && PlayerMovPos)
+    {
+      int nextJX = JX + (JX - lastJX);
+      int nextJY = JY + (JY - lastJY);
+
+      if (x == nextJX && y == nextJY)
+       return;
+    }
+
     if (element==EL_MORAST_VOLL)
     {
       if (IS_FREE(x,y+1))
@@ -2713,14 +2724,6 @@ void GameActions()
        }
       }
     }
-
-    /*
-    if (PlayerMovPos)
-      ScrollFigure(0);
-
-    DrawPlayerField();
-    */
-
   }
 
   if (TimeLeft>0 && TimeFrames>=25 && !tape.pausing)
@@ -2740,30 +2743,17 @@ void GameActions()
       KillHero();
   }
 
-  /*
-  if (PlayerMovPos)
-    ScrollFigure(0);
-    */
-
-
-  /*
   DrawPlayerField();
-  */
-
 
   BackToFront();
 }
 
 void ScrollLevel(int dx, int dy)
 {
+  int softscroll_offset = (soft_scrolling_on ? TILEX : 0);
   int x,y;
-  int softscroll_offset = (FX == TILEX ? TILEX : 0);
 
-  if (soft_scrolling_on)
-  {
-    ScreenMovPos = PlayerMovPos;
-    redraw_mask |= REDRAW_FIELD;
-  }
+  ScreenMovPos = PlayerMovPos;
 
   XCopyArea(display,drawto_field,drawto_field,gc,
            FX + TILEX*(dx==-1) - softscroll_offset,
@@ -2791,14 +2781,10 @@ void ScrollLevel(int dx, int dy)
 
 BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy)
 {
-  int oldJX,oldJY, newJX = JX+dx,newJY = JY+dy;
+  int newJX = JX+dx, newJY = JY+dy;
   int element;
   int can_move;
 
-/*
-  int old_move_dir = PlayerMovDir;
-*/
-
   if (PlayerGone || (!dx && !dy))
     return(MF_NO_ACTION);
 
@@ -2806,12 +2792,6 @@ BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy)
                  dx > 0 ? MV_RIGHT :
                  dy < 0 ? MV_UP :
                  dy > 0 ? MV_DOWN :    MV_NO_MOVING);
-/*
-  if (old_move_dir != PlayerMovDir)
-    PlayerFrame = 0;
-  else
-    PlayerFrame = (PlayerFrame + 1) % 4;
-*/
 
   if (!IN_LEV_FIELD(newJX,newJY))
     return(MF_NO_ACTION);
@@ -2839,57 +2819,28 @@ BOOL MoveFigureOneStep(int dx, int dy, int real_dx, int real_dy)
   if (can_move != MF_MOVING)
     return(can_move);
 
-  oldJX = JX;
-  oldJY = JY;
+  lastJX = JX;
+  lastJY = JY;
   JX = newJX;
   JY = newJY;
 
-
-  JX2 = oldJX;
-  JY2 = oldJY;
-
   PlayerMovPos = (dx > 0 || dy > 0 ? -1 : 1) * 3*TILEX/4;
 
   ScrollFigure(-1);
 
-  if (Store[oldJX][oldJY])
-  {
-    DrawGraphic(SCROLLX(oldJX),SCROLLY(oldJY),el2gfx(Store[oldJX][oldJY]));
-    DrawGraphicThruMask(SCROLLX(oldJX),SCROLLY(oldJY),
-                       el2gfx(Feld[oldJX][oldJY]));
-  }
-  else if (Feld[oldJX][oldJY]==EL_DYNAMIT)
-    DrawDynamite(oldJX,oldJY);
-  else
-    DrawLevelField(oldJX,oldJY);
-
   return(MF_MOVING);
 }
 
 BOOL MoveFigure(int dx, int dy)
 {
   static long move_delay = 0;
+  static int last_move_dir = MV_NO_MOVING;
   int moved = MF_NO_ACTION;
   int oldJX = JX, oldJY = JY;
 
   if (PlayerGone || (!dx && !dy))
     return(FALSE);
 
-/*
-  if (!DelayReached(&move_delay,8) && !tape.playing)
-    return(FALSE);
-*/
-
-/*
-  if (!DelayReached(&move_delay,10) && !tape.playing)
-    return(FALSE);
-*/
-
-/*
-  if (!FrameReached(&move_delay,2) && !tape.playing)
-    return(FALSE);
-*/
-
   if (Movemethod == 0)
   {
     if (!DelayReached(&move_delay,Movespeed[0]) && !tape.playing)
@@ -2901,28 +2852,33 @@ BOOL MoveFigure(int dx, int dy)
       return(FALSE);
   }
 
-  if (moved |= MoveFigureOneStep(dx,0, dx,dy))
-    moved |= MoveFigureOneStep(0,dy, dx,dy);
+  if (last_move_dir & (MV_LEFT | MV_RIGHT))
+  {
+    if (!(moved |= MoveFigureOneStep(0,dy, dx,dy)))
+      moved |= MoveFigureOneStep(dx,0, dx,dy);
+  }
   else
   {
-    moved |= MoveFigureOneStep(0,dy, dx,dy);
-    moved |= MoveFigureOneStep(dx,0, dx,dy);
+    if (!(moved |= MoveFigureOneStep(dx,0, dx,dy)))
+      moved |= MoveFigureOneStep(0,dy, dx,dy);
   }
 
+  last_move_dir = MV_NO_MOVING;
+
   if (moved & MF_MOVING)
   {
-    int old_scroll_x=scroll_x, old_scroll_y=scroll_y;
+    int old_scroll_x = scroll_x, old_scroll_y = scroll_y;
     int offset = (scroll_delay_on ? 3 : 0);
 
     if ((scroll_x < JX-MIDPOSX-offset || scroll_x > JX-MIDPOSX+offset) &&
-       JX>=MIDPOSX-1-offset && JX<=lev_fieldx-(MIDPOSX-offset))
+       JX >= MIDPOSX-1-offset && JX <= lev_fieldx-(MIDPOSX-offset))
       scroll_x = JX-MIDPOSX + (scroll_x < JX-MIDPOSX ? -offset : offset);
     if ((scroll_y < JY-MIDPOSY-offset || scroll_y > JY-MIDPOSY+offset) &&
-       JY>=MIDPOSY-1-offset && JY<=lev_fieldy-(MIDPOSY-offset))
+       JY >= MIDPOSY-1-offset && JY <= lev_fieldy-(MIDPOSY-offset))
       scroll_y = JY-MIDPOSY + (scroll_y < JY-MIDPOSY ? -offset : offset);
 
-    if (scroll_x!=old_scroll_x || scroll_y!=old_scroll_y)
-      ScrollLevel(old_scroll_x-scroll_x,old_scroll_y-scroll_y);
+    if (scroll_x != old_scroll_x || scroll_y != old_scroll_y)
+      ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y);
   }
 
   if (!(moved & MF_MOVING) && !PlayerPushing)
@@ -2938,14 +2894,12 @@ BOOL MoveFigure(int dx, int dy)
       PlayerMovDir = (oldJY < JY ? MV_DOWN : MV_UP);
 
     DrawLevelField(JX,JY);     /* für "ErdreichAnbroeckeln()" */
+
+    last_move_dir = PlayerMovDir;
   }
 
   TestIfHeroHitsBadThing();
 
-  /*
-  BackToFront();
-  */
-
   if (PlayerGone)
     RemoveHero();
 
@@ -2955,29 +2909,47 @@ BOOL MoveFigure(int dx, int dy)
 void ScrollFigure(int init)
 {
   static long actual_frame_counter;
-  static int oldX = -1, oldY = -1;
+  static int oldJX = -1, oldJY = -1;
 
   if (init)
   {
-    if (PlayerMovPos && oldX != -1 && oldY != -1)
-    {
-      DrawLevelElement(oldX,oldY, Feld[oldX][oldY]);
-      DrawPlayerField();
-    }
+    if (oldJX != -1 && oldJY != -1)
+      DrawLevelElement(oldJX,oldJY, Feld[oldJX][oldJY]);
+
+    if (Feld[lastJX][lastJY] == EL_LEERRAUM)
+      Feld[lastJX][lastJY] = EL_PLAYER_IS_LEAVING;
+    DrawLevelElement(lastJX,lastJY, Feld[lastJX][lastJY]);
+    DrawPlayerField();
 
-    oldX = JX2;
-    oldY = JY2;
+    oldJX = lastJX;
+    oldJY = lastJY;
     actual_frame_counter = FrameCounter;
 
-    redraw[redraw_x1 + oldX][redraw_y1 + oldY] = 1;
-    redraw_tiles++;
+    if (PlayerPushing)
+    {
+      int nextJX = JX + (JX - lastJX);
+      int nextJY = JY + (JY - lastJY);
 
-    /*
-    DrawLevelElement(oldX,oldY, Feld[oldX][oldY]);
-    */
+      if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
+       DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER);
+      else
+       DrawLevelElement(nextJX,nextJY, EL_LEERRAUM);
+    }
 
     DrawPlayerField();
 
+    if (Store[lastJX][lastJY])
+    {
+      DrawGraphic(SCROLLX(lastJX),SCROLLY(lastJY),
+                 el2gfx(Store[lastJX][lastJY]));
+      DrawGraphicThruMask(SCROLLX(lastJX),SCROLLY(lastJY),
+                         el2gfx(Feld[lastJX][lastJY]));
+    }
+    else if (Feld[lastJX][lastJY]==EL_DYNAMIT)
+      DrawDynamite(lastJX,lastJY);
+    else
+      DrawLevelField(lastJX,lastJY);
+
     return;
   }
   else if (!FrameReached(&actual_frame_counter,1))
@@ -2991,13 +2963,47 @@ void ScrollFigure(int init)
     redraw_mask |= REDRAW_FIELD;
   }
 
-  DrawLevelElement(oldX,oldY, Feld[oldX][oldY]);
+  if (Feld[oldJX][oldJY] == EL_PLAYER_IS_LEAVING)
+    Feld[oldJX][oldJY] = EL_LEERRAUM;
+
+  DrawLevelElement(oldJX,oldJY, Feld[oldJX][oldJY]);
   DrawPlayerField();
 
+
+
+  if (Store[oldJX][oldJY])
+  {
+    DrawGraphic(SCROLLX(oldJX),SCROLLY(oldJY),el2gfx(Store[oldJX][oldJY]));
+    DrawGraphicThruMask(SCROLLX(oldJX),SCROLLY(oldJY),
+                       el2gfx(Feld[oldJX][oldJY]));
+  }
+  else if (Feld[oldJX][oldJY]==EL_DYNAMIT)
+    DrawDynamite(oldJX,oldJY);
+  else
+    DrawLevelField(oldJX,oldJY);
+
+  if (PlayerPushing)
+  {
+    int nextJX = JX + (JX - lastJX);
+    int nextJY = JY + (JY - lastJY);
+
+    if (PlayerMovPos)
+    {
+      if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
+       DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER);
+      else
+       DrawLevelElement(nextJX,nextJY, EL_LEERRAUM);
+    }
+    else
+      DrawLevelElement(nextJX,nextJY, Feld[nextJX][nextJY]);
+  }
+
   if (!PlayerMovPos)
   {
-    JX2 = JX;
-    JY2 = JY;
+    lastJX = JX;
+    lastJY = JY;
+
+    oldJX = oldJY = -1;
   }
 }
 
@@ -3189,7 +3195,8 @@ int DigField(int x, int y, int real_dx, int real_dy, int mode)
   static long push_delay = 0;
   static int push_delay_value = 5;
 
-  PlayerPushing = FALSE;
+  if (!PlayerMovPos)
+    PlayerPushing = FALSE;
 
   if (mode == DF_NO_PUSH)
   {
@@ -3507,7 +3514,7 @@ BOOL PlaceBomb(void)
 {
   int element;
 
-  if (PlayerGone)
+  if (PlayerGone || PlayerMovPos)
     return(FALSE);
 
   element = Feld[JX][JY];