rnd-20030627-1-src
authorHolger Schemel <info@artsoft.org>
Fri, 27 Jun 2003 21:19:15 +0000 (23:19 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:42:20 +0000 (10:42 +0200)
src/conftime.h
src/game.c
src/init.c
src/main.c
src/main.h
src/tools.c

index 5fa300177619032a7a816206756a26743ad79815..2438837ce278df00359b656f5a4936092e57295f 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-06-23 23:45]"
+#define COMPILE_DATE_STRING "[2003-06-27 20:39]"
index d0f7751bbbca9183bf1fed4ec03edb5008671678..f29054575911e49267634b141081c3caba569368 100644 (file)
@@ -750,6 +750,33 @@ static void InitGameEngine()
     if (HAS_CHANGE_EVENT(i, CE_BY_OTHER))
       trigger_events[element_info[i].change.trigger] |=
        element_info[i].change.events;
+
+  /* set push delay value for all non-custom elements */
+  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  {
+    if (!IS_CUSTOM_ELEMENT(i))
+    {
+      if (i == EL_SPRING ||
+         i == EL_BALLOON)
+      {
+       element_info[i].push_delay_fixed = 0;
+       element_info[i].push_delay_random = 0;
+      }
+      else if (i == EL_SOKOBAN_OBJECT ||
+              i == EL_SOKOBAN_FIELD_FULL ||
+              i == EL_SATELLITE ||
+              i == EL_SP_DISK_YELLOW)
+      {
+       element_info[i].push_delay_fixed = 2;
+       element_info[i].push_delay_random = 0;
+      }
+      else
+      {
+       element_info[i].push_delay_fixed = 2;
+       element_info[i].push_delay_random = 8;
+      }
+    }
+  }
 }
 
 
@@ -907,6 +934,7 @@ void InitGame()
       AmoebaNr[x][y] = 0;
       JustStopped[x][y] = 0;
       Stop[x][y] = FALSE;
+      Pushed[x][y] = FALSE;
       ExplodePhase[x][y] = 0;
       ExplodeField[x][y] = EX_NO_EXPLOSION;
 
@@ -1601,6 +1629,7 @@ static void RemoveField(int x, int y)
   MovDir[x][y] = 0;
   MovDelay[x][y] = 0;
   ChangeDelay[x][y] = 0;
+  Pushed[x][y] = FALSE;
 }
 
 void RemoveMovingField(int x, int y)
@@ -3315,8 +3344,14 @@ void StartMoving(int x, int y)
 #endif
     }
 #if 1
+#if 1
+    else if (game.engine_version < RELEASE_IDENT(2,2,0,7) &&
+            CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED &&
+            JustStopped[x][y] && !Pushed[x][y + 1])
+#else
     else if (CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED &&
             JustStopped[x][y])
+#endif
     {
       /*
       printf("::: %d\n", MovDir[x][y]);
@@ -3828,7 +3863,11 @@ void ContinueMoving(int x, int y)
   MovPos[x][y] += step;
 
 #if 1
+#if 1
+  if (Pushed[x][y])    /* special case: moving object pushed by player */
+#else
   if (pushing)         /* special case: moving object pushed by player */
+#endif
 #if 1
     MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos));
 #else
@@ -3922,6 +3961,16 @@ void ContinueMoving(int x, int y)
       Feld[x][y] = get_next_element(element);
       element = Feld[newx][newy] = Store[x][y];
     }
+    else if (element == EL_SOKOBAN_OBJECT)
+    {
+      if (Back[x][y])
+       Feld[x][y] = Back[x][y];
+
+      if (Back[newx][newy])
+       Feld[newx][newy] = EL_SOKOBAN_FIELD_FULL;
+
+      Back[x][y] = Back[newx][newy] = 0;
+    }
     else if (Store[x][y] == EL_ACID)
     {
       element = Feld[newx][newy] = EL_ACID;
@@ -3939,6 +3988,8 @@ void ContinueMoving(int x, int y)
     GfxAction[newx][newy] = GfxAction[x][y];   /* keep action one frame */
     GfxRandom[newx][newy] = GfxRandom[x][y];   /* keep same random value */
 
+    Pushed[x][y] = Pushed[newx][newy] = FALSE;
+
     ResetGfxAnimation(x, y);   /* reset animation values for old field */
 
 #if 1
@@ -3946,15 +3997,17 @@ void ContinueMoving(int x, int y)
     if (!CAN_MOVE(element))
       MovDir[newx][newy] = 0;
 #else
-    /*
+
+#if 0
     if (CAN_FALL(element) && MovDir[newx][newy] == MV_DOWN)
       MovDir[newx][newy] = 0;
-    */
-
+#else
     if (!CAN_MOVE(element) ||
        (element == EL_SPRING && MovDir[newx][newy] == MV_DOWN))
       MovDir[newx][newy] = 0;
 #endif
+
+#endif
 #endif
 
     DrawLevelField(x, y);
@@ -6766,6 +6819,8 @@ int DigField(struct PlayerInfo *player,
       return MF_ACTION;
       break;
 
+#if 0
+
       /* the following elements cannot be pushed by "snapping" */
     case EL_ROCK:
     case EL_BOMB:
@@ -6863,6 +6918,8 @@ int DigField(struct PlayerInfo *player,
 
       break;
 
+#endif
+
     case EL_GATE_1:
     case EL_GATE_2:
     case EL_GATE_3:
@@ -7047,6 +7104,8 @@ int DigField(struct PlayerInfo *player,
       return MF_ACTION;
       break;
 
+#if 0
+
 #if 0
     case EL_SOKOBAN_FIELD_EMPTY:
       break;
@@ -7086,6 +7145,44 @@ int DigField(struct PlayerInfo *player,
 
       if (IS_SB_ELEMENT(element))
       {
+#if 1
+       if (element == EL_SOKOBAN_FIELD_FULL)
+       {
+         Back[x][y] = EL_SOKOBAN_FIELD_EMPTY;
+         local_player->sokobanfields_still_needed++;
+       }
+
+       if (Feld[x + dx][y + dy] == EL_SOKOBAN_FIELD_EMPTY)
+       {
+         Back[x + dx][y + dy] = EL_SOKOBAN_FIELD_EMPTY;
+         local_player->sokobanfields_still_needed--;
+       }
+
+       Feld[x][y] = EL_SOKOBAN_OBJECT;
+
+       if (Back[x][y] == Back[x + dx][y + dy])
+         PlaySoundLevelAction(x, y, ACTION_PUSHING);
+       else if (Back[x][y] != 0)
+         PlaySoundLevelElementAction(x, y, EL_SOKOBAN_FIELD_FULL,
+                                     ACTION_EMPTYING);
+       else
+         PlaySoundLevelElementAction(x + dx, y + dy, EL_SOKOBAN_FIELD_EMPTY,
+                                     ACTION_FILLING);
+
+       InitMovingField(x, y, (dx < 0 ? MV_LEFT :
+                              dx > 0 ? MV_RIGHT :
+                              dy < 0 ? MV_UP : MV_DOWN));
+       MovPos[x][y] = (dx != 0 ? dx : dy);
+
+#if 0
+       printf("::: %s -> %s [%s -> %s]\n",
+              element_info[Feld[x][y]].token_name,
+              element_info[Feld[x + dx][y + dy]].token_name,
+              element_info[Back[x][y]].token_name,
+              element_info[Back[x + dx][y + dy]].token_name);
+#endif
+
+#else
        if (element == EL_SOKOBAN_FIELD_FULL)
        {
          Feld[x][y] = EL_SOKOBAN_FIELD_EMPTY;
@@ -7127,11 +7224,19 @@ int DigField(struct PlayerInfo *player,
            PlaySoundLevel(x, y, SND_SOKOBAN_OBJECT_PUSHING);
 #endif
        }
+#endif
       }
       else
       {
+#if 1
+       InitMovingField(x, y, (dx < 0 ? MV_LEFT :
+                              dx > 0 ? MV_RIGHT :
+                              dy < 0 ? MV_UP : MV_DOWN));
+       MovPos[x][y] = (dx != 0 ? dx : dy);
+#else
        RemoveField(x, y);
-       Feld[x+dx][y+dy] = element;
+       Feld[x + dx][y + dy] = element;
+#endif
        PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
       }
 
@@ -7152,6 +7257,8 @@ int DigField(struct PlayerInfo *player,
 
       break;
 
+#endif
+
     case EL_PENGUIN:
     case EL_PIG:
     case EL_DRAGON:
@@ -7199,13 +7306,17 @@ int DigField(struct PlayerInfo *player,
       }
       else if (IS_PUSHABLE(element))
       {
-       if (mode == DF_SNAP)
+       if (mode == DF_SNAP && element != EL_BD_ROCK)
          return MF_NO_ACTION;
 
        if (CAN_FALL(element) && dy)
          return MF_NO_ACTION;
 
-       if (CAN_FALL(element) && IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1))
+       if (CAN_FALL(element) && IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1) &&
+           !(element == EL_SPRING && use_spring_bug))
+         return MF_NO_ACTION;
+
+       if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING)
          return MF_NO_ACTION;
 
        if (!player->Pushing &&
@@ -7214,7 +7325,10 @@ int DigField(struct PlayerInfo *player,
 
        player->Pushing = TRUE;
 
-       if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
+       if (!(IN_LEV_FIELD(x + dx, y + dy) &&
+             (IS_FREE(x + dx, y + dy) ||
+              (Feld[x + dx][y + dy] == EL_SOKOBAN_FIELD_EMPTY &&
+               IS_SB_ELEMENT(element)))))
          return MF_NO_ACTION;
 
        if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
@@ -7224,35 +7338,60 @@ int DigField(struct PlayerInfo *player,
          player->push_delay = FrameCounter;
 
        if (!FrameReached(&player->push_delay, player->push_delay_value) &&
-           !(tape.playing && tape.file_version < FILE_VERSION_2_0))
+           !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
+           element != EL_SPRING && element != EL_BALLOON)
          return MF_NO_ACTION;
 
-#if 1
-       InitMovingField(x, y, (dx < 0 ? MV_LEFT :
-                              dx > 0 ? MV_RIGHT :
-                              dy < 0 ? MV_UP : MV_DOWN));
-       MovPos[x][y] = (dx != 0 ? dx : dy);
-#else
-       RemoveField(x, y);
-       Feld[x + dx][y + dy] = element;
-#endif
+       if (IS_SB_ELEMENT(element))
+       {
+         if (element == EL_SOKOBAN_FIELD_FULL)
+         {
+           Back[x][y] = EL_SOKOBAN_FIELD_EMPTY;
+           local_player->sokobanfields_still_needed++;
+         }
+
+         if (Feld[x + dx][y + dy] == EL_SOKOBAN_FIELD_EMPTY)
+         {
+           Back[x + dx][y + dy] = EL_SOKOBAN_FIELD_EMPTY;
+           local_player->sokobanfields_still_needed--;
+         }
+
+         Feld[x][y] = EL_SOKOBAN_OBJECT;
+
+         if (Back[x][y] == Back[x + dx][y + dy])
+           PlaySoundLevelAction(x, y, ACTION_PUSHING);
+         else if (Back[x][y] != 0)
+           PlaySoundLevelElementAction(x, y, EL_SOKOBAN_FIELD_FULL,
+                                       ACTION_EMPTYING);
+         else
+           PlaySoundLevelElementAction(x + dx, y + dy, EL_SOKOBAN_FIELD_EMPTY,
+                                       ACTION_FILLING);
+
+         if (local_player->sokobanfields_still_needed == 0 &&
+             game.emulation == EMU_SOKOBAN)
+         {
+           player->LevelSolved = player->GameOver = TRUE;
+           PlaySoundLevel(x, y, SND_GAME_SOKOBAN_SOLVING);
+         }
+       }
+       else
+         PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
+
+       InitMovingField(x, y, move_direction);
+
+       if (mode == DF_SNAP)
+         ContinueMoving(x, y);
+       else
+         MovPos[x][y] = (dx != 0 ? dx : dy);
+
+       Pushed[x][y] = TRUE;
+       Pushed[x + dx][y + dy] = TRUE;
 
-#if 1
        if (game.engine_version < RELEASE_IDENT(2,2,0,7))
          player->push_delay_value = GET_NEW_PUSH_DELAY(element);
-#else
-       player->push_delay_value = 2 + RND(8);
-#endif
-
-       DrawLevelField(x + dx, y + dy);
-       PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
 
        CheckTriggeredElementChange(element, CE_OTHER_PUSHING);
-#if 1
        CheckPlayerElementChange(x, y, element, CE_PUSHED_BY_PLAYER);
-#else
-       CheckPlayerElementChange(x + dx, y + dy, element, CE_PUSHED_BY_PLAYER);
-#endif
 
        break;
       }
index 6d32cd3b46158d149470e58a04e890ffd37a147e..dfd97f5ef2df5dca82cb92c99c2de7ae27158fd4 100644 (file)
@@ -2243,7 +2243,9 @@ void InitElementPropertiesStatic()
     EL_DYNABOMB_INCREASE_NUMBER,
     EL_DYNABOMB_INCREASE_SIZE,
     EL_DYNABOMB_INCREASE_POWER,
+#if 0
     EL_SOKOBAN_OBJECT,
+#endif
     EL_SOKOBAN_FIELD_EMPTY,
     EL_SOKOBAN_FIELD_FULL,
     EL_WALL_EMERALD_RED,
@@ -2273,7 +2275,9 @@ void InitElementPropertiesStatic()
     EL_SP_PORT_VERTICAL,
     EL_SP_PORT_ANY,
     EL_SP_DISK_RED,
+#if 0
     EL_SP_DISK_YELLOW,
+#endif
     EL_SP_CHIP_SINGLE,
     EL_SP_CHIP_LEFT,
     EL_SP_CHIP_RIGHT,
index c721a4cd734808cc3cdf4b6fbb8f1a8269fc26a8..48a0f60ab60a05e0649bf3f070e948b65dc12cf0 100644 (file)
@@ -50,6 +50,7 @@ short                 Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 boolean                        Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+boolean                        Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  AmoebaCnt[MAX_NUM_AMOEBA];
index 4385aa55db7d6f3f858355c8473ebb05697eae74..bff222702bd410775906be20866b5fdd563b353b 100644 (file)
@@ -1305,6 +1305,7 @@ extern short                      Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern boolean                 Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern boolean                 Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   AmoebaCnt[MAX_NUM_AMOEBA];
index 761aa4a88580bced42c7eb77704e92fe722f5870..974765111a020583fdfddb12566c784b84a37c0a 100644 (file)
@@ -600,6 +600,9 @@ void DrawPlayer(struct PlayerInfo *player)
 
     if (player->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
     {
+#if 1
+      DrawLevelElement(next_jx, next_jy, EL_EMPTY);
+#else
       if (player->GfxPos)
       {
        if (Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL)
@@ -609,6 +612,7 @@ void DrawPlayer(struct PlayerInfo *player)
       }
       else
        DrawLevelField(next_jx, next_jy);
+#endif
     }
   }
 
@@ -700,11 +704,20 @@ void DrawPlayer(struct PlayerInfo *player)
   {
     int px = SCREENX(next_jx), py = SCREENY(next_jy);
 
+    if (Back[next_jx][next_jy])
+      DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+
+#if 1
+    if ((sxx || syy) && element == EL_SOKOBAN_OBJECT)
+      DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
+                                NO_CUTTING);
+#else
     if ((sxx || syy) &&
        (element == EL_SOKOBAN_FIELD_EMPTY ||
         Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL))
       DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
                                 NO_CUTTING);
+#endif
     else
     {
 #if 1