rnd-20040301-1-src
authorHolger Schemel <info@artsoft.org>
Mon, 1 Mar 2004 08:37:58 +0000 (09:37 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:46:05 +0000 (10:46 +0200)
* use unlimited number of droppable elements when "count" set to zero
* added option to use step limit instead of time limit for level
* added player and change page as trigger for custom element change

ChangeLog
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/init.c
src/main.c
src/main.h

index 71f243a96328d3d460775765a251c4353c363f6f..2061b83c1699f865278534af85eae4084afe41e4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-02-28
+       * use unlimited number of droppable elements when "count" set to zero
+       * added option to use step limit instead of time limit for level
+
+2004-02-27
+       * added player and change page as trigger for custom element change
+
 2004-02-24
        * fixed bug with exploding amoeba (explosion 3x3 instead of 1x1)
 
index 1fc08875f52a09a5c8c5da935e5ad96b04ab5058..8c2c13bbf96b7c5b507fde45b76c9615e8c3ffca 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-02-28 01:51]"
+#define COMPILE_DATE_STRING "[2004-03-01 02:26]"
index 8f921bc60137ace0fedb008facc034830120926b..5a567832af99981e765126f20de38453970183b6 100644 (file)
 /* selectbox identifiers */
 #define GADGET_ID_SELECTBOX_FIRST      (GADGET_ID_TEXT_AREA_FIRST + 1)
 
-#define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 0)
-#define GADGET_ID_CUSTOM_CONSISTENCY   (GADGET_ID_SELECTBOX_FIRST + 1)
-#define GADGET_ID_CUSTOM_DEADLINESS    (GADGET_ID_SELECTBOX_FIRST + 2)
-#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 3)
-#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 4)
-#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 5)
-#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 6)
-#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 7)
-#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 8)
-#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 9)
-#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 10)
-#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 11)
-#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 12)
-#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 13)
-#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 14)
-#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 15)
-#define GADGET_ID_CHANGE_SIDE          (GADGET_ID_SELECTBOX_FIRST + 16)
-#define GADGET_ID_CHANGE_PLAYER                (GADGET_ID_SELECTBOX_FIRST + 17)
-#define GADGET_ID_CHANGE_PAGE          (GADGET_ID_SELECTBOX_FIRST + 18)
-#define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 19)
-#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 20)
-#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 21)
+#define GADGET_ID_TIME_OR_STEPS                (GADGET_ID_SELECTBOX_FIRST + 0)
+#define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 1)
+#define GADGET_ID_CUSTOM_CONSISTENCY   (GADGET_ID_SELECTBOX_FIRST + 2)
+#define GADGET_ID_CUSTOM_DEADLINESS    (GADGET_ID_SELECTBOX_FIRST + 3)
+#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 4)
+#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 5)
+#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 6)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 7)
+#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 8)
+#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 9)
+#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 10)
+#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 11)
+#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 16)
+#define GADGET_ID_CHANGE_SIDE          (GADGET_ID_SELECTBOX_FIRST + 17)
+#define GADGET_ID_CHANGE_PLAYER                (GADGET_ID_SELECTBOX_FIRST + 18)
+#define GADGET_ID_CHANGE_PAGE          (GADGET_ID_SELECTBOX_FIRST + 19)
+#define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 20)
+#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 21)
+#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 22)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 22)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 23)
 
 #define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 0)
 #define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 1)
 #define ED_TEXTAREA_ID_LEVEL_LAST      ED_TEXTAREA_ID_ENVELOPE
 
 /* values for selectbox gadgets */
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE     0
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER    1
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED        2
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION        3
-#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  4
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    5
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  6
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   7
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 8
-#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   9
-#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   10
-#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      11
-#define ED_SELECTBOX_ID_CUSTOM_CONSISTENCY     12
-#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      13
-#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   14
-#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    15
-#define ED_SELECTBOX_ID_CHANGE_SIDE            16
-#define ED_SELECTBOX_ID_CHANGE_PLAYER          17
-#define ED_SELECTBOX_ID_CHANGE_PAGE            18
-#define ED_SELECTBOX_ID_CHANGE_POWER           19
-#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     20
-#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      21
-
-#define ED_NUM_SELECTBOX                       22
+#define ED_SELECTBOX_ID_TIME_OR_STEPS          0
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE     1
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER    2
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED        3
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION        4
+#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  5
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    6
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  7
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   8
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 9
+#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   10
+#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   11
+#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      12
+#define ED_SELECTBOX_ID_CUSTOM_CONSISTENCY     13
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      14
+#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   15
+#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    16
+#define ED_SELECTBOX_ID_CHANGE_SIDE            17
+#define ED_SELECTBOX_ID_CHANGE_PLAYER          18
+#define ED_SELECTBOX_ID_CHANGE_PAGE            19
+#define ED_SELECTBOX_ID_CHANGE_POWER           20
+#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     21
+#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      22
+
+#define ED_NUM_SELECTBOX                       23
+
+#define ED_SELECTBOX_ID_LEVEL_FIRST    ED_SELECTBOX_ID_TIME_OR_STEPS
+#define ED_SELECTBOX_ID_LEVEL_LAST     ED_SELECTBOX_ID_TIME_OR_STEPS
 
 #define ED_SELECTBOX_ID_CUSTOM1_FIRST  ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
 #define ED_SELECTBOX_ID_CUSTOM1_LAST   ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE
@@ -913,7 +918,7 @@ static struct
     GADGET_ID_LEVEL_GEMSLIMIT_DOWN,    GADGET_ID_LEVEL_GEMSLIMIT_UP,
     GADGET_ID_LEVEL_GEMSLIMIT_TEXT,    GADGET_ID_NONE,
     &level.gems_needed,
-    "number of emeralds to collect:",  NULL, NULL
+    "number of gems to collect:",      NULL, NULL
   },
   {
     ED_SETTINGS_XPOS(0),               ED_COUNTER_YPOS(4),
@@ -921,7 +926,7 @@ static struct
     GADGET_ID_LEVEL_TIMELIMIT_DOWN,    GADGET_ID_LEVEL_TIMELIMIT_UP,
     GADGET_ID_LEVEL_TIMELIMIT_TEXT,    GADGET_ID_NONE,
     &level.time,
-    "time available to solve level:",  NULL, "(0 => no time limit)"
+    "time or step limit to solve level:", NULL, NULL
   },
   {
     ED_SETTINGS_XPOS(0),               ED_COUNTER_YPOS(5),
@@ -929,7 +934,7 @@ static struct
     GADGET_ID_LEVEL_TIMESCORE_DOWN,    GADGET_ID_LEVEL_TIMESCORE_UP,
     GADGET_ID_LEVEL_TIMESCORE_TEXT,    GADGET_ID_NONE,
     &level.score[SC_TIME_BONUS],
-    "score for each 10 seconds left:", NULL, NULL
+    "score for each 10 sec/steps left:", NULL, NULL
   },
   {
     ED_SETTINGS_XPOS(0),               ED_COUNTER2_YPOS(8),
@@ -1134,6 +1139,14 @@ static struct
   }
 };
 
+static struct ValueTextInfo options_time_or_steps[] =
+{
+  { 0,                         "seconds"                       },
+  { 1,                         "steps"                         },
+
+  { -1,                                NULL                            }
+};
+
 static struct ValueTextInfo options_access_type[] =
 {
   { EP_WALKABLE,               "walkable"                      },
@@ -1440,6 +1453,17 @@ static struct
   char *text_left, *text_right, *infotext;
 } selectbox_info[ED_NUM_SELECTBOX] =
 {
+  /* ---------- level and editor settings ---------------------------------- */
+
+  {
+    -1,                                        ED_COUNTER_YPOS(4),
+    GADGET_ID_TIME_OR_STEPS,           GADGET_ID_LEVEL_TIMELIMIT_UP,
+    -1,
+    options_time_or_steps,
+    &level.use_step_counter,
+    NULL, "(0 => no limit)",           "time or step limit"
+  },
+
   /* ---------- element settings: configure 1 (custom elements) ----------- */
 
   {
@@ -5769,7 +5793,7 @@ static void CopyClassicElementPropertiesToEditor(int element)
 
     if (bit_nr > -1)
       custom_element_properties[EP_CAN_MOVE_INTO_ACID] =
-       ((level.can_move_into_acid & (1 << bit_nr)) != 0);
+       ((level.can_move_into_acid_bits & (1 << bit_nr)) != 0);
   }
 #endif
 }
@@ -5945,10 +5969,10 @@ static void CopyClassicElementPropertiesToGame(int element)
 
     if (bit_nr > -1)
     {
-      level.can_move_into_acid &= ~(1 << bit_nr);
+      level.can_move_into_acid_bits &= ~(1 << bit_nr);
 
       if (custom_element_properties[EP_CAN_MOVE_INTO_ACID])
-       level.can_move_into_acid |= (1 << bit_nr);
+       level.can_move_into_acid_bits |= (1 << bit_nr);
     }
   }
 #endif
@@ -6258,6 +6282,10 @@ static void DrawLevelInfoWindow()
   for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++)
     MapCounterButtons(i);
 
+  /* draw selectbox gadgets */
+  for (i = ED_SELECTBOX_ID_LEVEL_FIRST; i <= ED_SELECTBOX_ID_LEVEL_LAST; i++)
+    MapSelectboxGadget(i);
+
   /* draw checkbutton gadgets */
   for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i <= ED_CHECKBUTTON_ID_LEVEL_LAST; i++)
     MapCheckbuttonGadget(i);
index 5fd205cb42d859ed0cd4049a23777ef235354329..8e6ec1bb99c58cae3cca6f98f50d4bf1c7b1cefb 100644 (file)
@@ -29,7 +29,7 @@
 #define CHUNK_SIZE_NONE                -1      /* do not write chunk size    */
 #define FILE_VERS_CHUNK_SIZE   8       /* size of file version chunk */
 #define LEVEL_HEADER_SIZE      80      /* size of level file header  */
-#define LEVEL_HEADER_UNUSED    8       /* unused level header bytes  */
+#define LEVEL_HEADER_UNUSED    7       /* unused level header bytes  */
 #define LEVEL_CHUNK_CNT2_SIZE  160     /* size of level CNT2 chunk   */
 #define LEVEL_CHUNK_CNT2_UNUSED        11      /* unused CNT2 chunk bytes    */
 #define LEVEL_CHUNK_CNT3_HEADER        16      /* size of level CNT3 header  */
@@ -162,7 +162,9 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
 
   level->use_spring_bug = FALSE;
 
-  level->can_move_into_acid = ~0;      /* everything can move into acid */
+  level->can_move_into_acid_bits = ~0; /* everything can move into acid */
+
+  level->use_step_counter = FALSE;
 
   level->use_custom_template = FALSE;
 
@@ -655,7 +657,9 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level)
 
   level->use_spring_bug                = (getFile8Bit(file) == 1 ? TRUE : FALSE);
 
-  level->can_move_into_acid    = getFile16BitBE(file);
+  level->can_move_into_acid_bits = getFile16BitBE(file);
+
+  level->use_step_counter      = (getFile8Bit(file) == 1 ? TRUE : FALSE);
 
   ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED);
 
@@ -2057,7 +2061,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     {
       int i, j;
 
-      level->can_move_into_acid = 0;   /* nothing can move into acid */
+      level->can_move_into_acid_bits = 0; /* nothing can move into acid */
 
       setMoveIntoAcidProperty(level, EL_ROBOT,     TRUE);
       setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE);
@@ -2367,7 +2371,9 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level)
 
   putFile8Bit(file, (level->use_spring_bug ? 1 : 0));
 
-  putFile16BitBE(file, level->can_move_into_acid);
+  putFile16BitBE(file, level->can_move_into_acid_bits);
+
+  putFile8Bit(file, (level->use_step_counter ? 1 : 0));
 
   WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED);
 }
@@ -2908,6 +2914,7 @@ void DumpLevel(struct LevelInfo *level)
   printf("Player blocks last field:    %s\n", (level->block_last_field ? "yes" : "no"));
   printf("SP player blocks last field: %s\n", (level->sp_block_last_field ? "yes" : "no"));
   printf("use spring bug: %s\n", (level->use_spring_bug ? "yes" : "no"));
+  printf("use step counter: %s\n", (level->use_step_counter ? "yes" : "no"));
 
   printf_line("-", 79);
 }
index 7ff1a5e48146453f1cab477ddfdd45d8e54e7b38..bffde89cb0b6f69f790264f74a299cfeab42de01 100644 (file)
@@ -241,6 +241,7 @@ int DigField(struct PlayerInfo *, int, int, int, int, int, int, int);
 static void InitBeltMovement(void);
 static void CloseAllOpenTimegates(void);
 static void CheckGravityMovement(struct PlayerInfo *);
+static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *);
 static void KillHeroUnlessEnemyProtected(int, int);
 static void KillHeroUnlessExplosionProtected(int, int);
 
@@ -1471,6 +1472,7 @@ void InitGame()
     player->shield_normal_time_left = 0;
     player->shield_deadly_time_left = 0;
 
+    player->inventory_infinite_element = EL_UNDEFINED;
     player->inventory_size = 0;
 
     DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
@@ -1494,6 +1496,7 @@ void InitGame()
   TimeFrames = 0;
   TimePlayed = 0;
   TimeLeft = level.time;
+  TapeTime = 0;
 
   ScreenMovDir = MV_NO_MOVING;
   ScreenMovPos = 0;
@@ -7177,6 +7180,10 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action)
     printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter);
 #endif
 
+#if 0
+    /* !!! TEST !!! */
+    CheckGravityMovement(player);
+#endif
     if (button1)
       snapped = SnapField(player, dx, dy);
     else
@@ -7214,7 +7221,7 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action)
 
     DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
     SnapField(player, 0, 0);
-    CheckGravityMovement(player);
+    CheckGravityMovementWhenNotMoving(player);
 
     if (player->MovPos == 0)
       SetPlayerWaiting(player, TRUE);
@@ -7295,7 +7302,7 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action)
 
     DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
     SnapField(player, 0, 0);
-    CheckGravityMovement(player);
+    CheckGravityMovementWhenNotMoving(player);
 
     if (player->MovPos == 0)
       InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
@@ -7395,11 +7402,29 @@ void GameActions()
   {
     int actual_player_action = stored_player[i].effective_action;
 
+#if 1
+    /* OLD: overwrite programmed action with tape action (BAD!!!) */
     if (stored_player[i].programmed_action)
       actual_player_action = stored_player[i].programmed_action;
+#endif
 
     if (recorded_player_action)
+    {
+#if 0
+      if (stored_player[i].programmed_action &&
+         stored_player[i].programmed_action != recorded_player_action[i])
+       printf("::: %d <-> %d\n",
+              stored_player[i].programmed_action, recorded_player_action[i]);
+#endif
+
       actual_player_action = recorded_player_action[i];
+    }
+
+#if 0
+    /* NEW: overwrite tape action with programmed action */
+    if (stored_player[i].programmed_action)
+      actual_player_action = stored_player[i].programmed_action;
+#endif
 
     tape_action[i] = PlayerActions(&stored_player[i], actual_player_action);
 
@@ -7833,39 +7858,44 @@ void GameActions()
   if (TimeFrames >= FRAMES_PER_SECOND)
   {
     TimeFrames = 0;
-    TimePlayed++;
+    TapeTime++;
 
-    for (i = 0; i < MAX_PLAYERS; i++)
+    if (!level.use_step_counter)
     {
-      struct PlayerInfo *player = &stored_player[i];
+      TimePlayed++;
 
-      if (SHIELD_ON(player))
+      for (i = 0; i < MAX_PLAYERS; i++)
       {
-       player->shield_normal_time_left--;
+       struct PlayerInfo *player = &stored_player[i];
 
-       if (player->shield_deadly_time_left > 0)
-         player->shield_deadly_time_left--;
-      }
-    }
+       if (SHIELD_ON(player))
+       {
+         player->shield_normal_time_left--;
 
-    if (tape.recording || tape.playing)
-      DrawVideoDisplay(VIDEO_STATE_TIME_ON, TimePlayed);
+         if (player->shield_deadly_time_left > 0)
+           player->shield_deadly_time_left--;
+       }
+      }
 
-    if (TimeLeft > 0)
-    {
-      TimeLeft--;
+      if (TimeLeft > 0)
+      {
+       TimeLeft--;
 
-      if (TimeLeft <= 10 && setup.time_limit)
-       PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
+       if (TimeLeft <= 10 && setup.time_limit)
+         PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
 
-      DrawGameValue_Time(TimeLeft);
+       DrawGameValue_Time(TimeLeft);
 
-      if (!TimeLeft && setup.time_limit)
-       for (i = 0; i < MAX_PLAYERS; i++)
-         KillHero(&stored_player[i]);
+       if (!TimeLeft && setup.time_limit)
+         for (i = 0; i < MAX_PLAYERS; i++)
+           KillHero(&stored_player[i]);
+      }
+      else if (level.time == 0 && !AllPlayersGone) /* level w/o time limit */
+       DrawGameValue_Time(TimePlayed);
     }
-    else if (level.time == 0 && !AllPlayersGone) /* level without time limit */
-      DrawGameValue_Time(TimePlayed);
+
+    if (tape.recording || tape.playing)
+      DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
   }
 
   DrawAllPlayers();
@@ -8067,6 +8097,27 @@ static void CheckGravityMovement(struct PlayerInfo *player)
   }
 }
 
+static void CheckGravityMovementWhenNotMoving(struct PlayerInfo *player)
+{
+#if 1
+  return CheckGravityMovement(player);
+#endif
+
+  if (game.gravity && !player->programmed_action)
+  {
+    int jx = player->jx, jy = player->jy;
+    boolean field_under_player_is_free =
+      (IN_LEV_FIELD(jx, jy + 1) && IS_FREE(jx, jy + 1));
+    boolean player_is_standing_on_valid_field =
+      (IS_WALKABLE_INSIDE(Feld[jx][jy]) ||
+       (IS_WALKABLE(Feld[jx][jy]) &&
+       !(element_info[Feld[jx][jy]].access_direction & MV_DOWN)));
+
+    if (field_under_player_is_free && !player_is_standing_on_valid_field)
+      player->programmed_action = MV_DOWN;
+  }
+}
+
 /*
   MovePlayerOneStep()
   -----------------------------------------------------------------------------
@@ -8214,9 +8265,16 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy)
       !tape.playing)
     return FALSE;
 #else
+
+#if 1
+  if (!FrameReached(&player->move_delay, player->move_delay_value))
+    return FALSE;
+#else
   if (!FrameReached(&player->move_delay, player->move_delay_value) &&
       !(tape.playing && tape.file_version < FILE_VERSION_2_0))
     return FALSE;
+#endif
+
 #endif
 
   /* remove the last programmed player action */
@@ -8407,7 +8465,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy)
   }
   else
   {
-    CheckGravityMovement(player);
+    CheckGravityMovementWhenNotMoving(player);
 
     /*
     player->last_move_dir = MV_NO_MOVING;
@@ -8526,6 +8584,42 @@ void ScrollPlayer(struct PlayerInfo *player, int mode)
        RemoveHero(player);
     }
 
+    if (level.use_step_counter)
+    {
+      int i;
+
+      TimePlayed++;
+
+      for (i = 0; i < MAX_PLAYERS; i++)
+      {
+       struct PlayerInfo *player = &stored_player[i];
+
+       if (SHIELD_ON(player))
+       {
+         player->shield_normal_time_left--;
+
+         if (player->shield_deadly_time_left > 0)
+           player->shield_deadly_time_left--;
+       }
+      }
+
+      if (TimeLeft > 0)
+      {
+       TimeLeft--;
+
+       if (TimeLeft <= 10 && setup.time_limit)
+         PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
+
+       DrawGameValue_Time(TimeLeft);
+
+       if (!TimeLeft && setup.time_limit)
+         for (i = 0; i < MAX_PLAYERS; i++)
+           KillHero(&stored_player[i]);
+      }
+      else if (level.time == 0 && !AllPlayersGone) /* level w/o time limit */
+       DrawGameValue_Time(TimePlayed);
+    }
+
     if (tape.single_step && tape.recording && !tape.pausing &&
        !player->programmed_action)
       TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
@@ -9562,9 +9656,12 @@ int DigField(struct PlayerInfo *player,
        {
          int i;
 
-         for (i = 0; i < element_info[element].collect_count; i++)
-           if (player->inventory_size < MAX_INVENTORY_SIZE)
-             player->inventory_element[player->inventory_size++] = element;
+         if (element_info[element].collect_count == 0)
+           player->inventory_infinite_element = element;
+         else
+           for (i = 0; i < element_info[element].collect_count; i++)
+             if (player->inventory_size < MAX_INVENTORY_SIZE)
+               player->inventory_element[player->inventory_size++] = element;
 
          DrawGameValue_Dynamite(local_player->inventory_size);
        }
@@ -9945,25 +10042,43 @@ boolean DropElement(struct PlayerInfo *player)
 {
   int jx = player->jx, jy = player->jy;
   int old_element = Feld[jx][jy];
-  int new_element;
+  int new_element = (player->inventory_size > 0 ?
+                    player->inventory_element[player->inventory_size - 1] :
+                    player->inventory_infinite_element != EL_UNDEFINED ?
+                    player->inventory_infinite_element :
+                    player->dynabombs_left > 0 ?
+                    EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr :
+                    EL_UNDEFINED);
 
   /* check if player is active, not moving and ready to drop */
   if (!player->active || player->MovPos || player->drop_delay > 0)
     return FALSE;
 
   /* check if player has anything that can be dropped */
-  if (player->inventory_size == 0 && player->dynabombs_left == 0)
+#if 1
+  if (new_element == EL_UNDEFINED)
+    return FALSE;
+#else
+  if (player->inventory_size == 0 &&
+      player->inventory_infinite_element == EL_UNDEFINED &&
+      player->dynabombs_left == 0)
     return FALSE;
+#endif
 
   /* check if anything can be dropped at the current position */
   if (IS_ACTIVE_BOMB(old_element) || old_element == EL_EXPLOSION)
     return FALSE;
 
   /* collected custom elements can only be dropped on empty fields */
+#if 1
+  if (IS_CUSTOM_ELEMENT(new_element) && old_element != EL_EMPTY)
+    return FALSE;
+#else
   if (player->inventory_size > 0 &&
       IS_CUSTOM_ELEMENT(player->inventory_element[player->inventory_size - 1])
       && old_element != EL_EMPTY)
     return FALSE;
+#endif
 
   if (old_element != EL_EMPTY)
     Back[jx][jy] = old_element;                /* store old element on this field */
@@ -9971,19 +10086,26 @@ boolean DropElement(struct PlayerInfo *player)
   ResetGfxAnimation(jx, jy);
   ResetRandomAnimationValue(jx, jy);
 
-  if (player->inventory_size > 0)
+  if (player->inventory_size > 0 ||
+      player->inventory_infinite_element != EL_UNDEFINED)
   {
-    player->inventory_size--;
-    new_element = player->inventory_element[player->inventory_size];
+    if (player->inventory_size > 0)
+    {
+      player->inventory_size--;
 
-    if (new_element == EL_DYNAMITE)
-      new_element = EL_DYNAMITE_ACTIVE;
-    else if (new_element == EL_SP_DISK_RED)
-      new_element = EL_SP_DISK_RED_ACTIVE;
+#if 0
+      new_element = player->inventory_element[player->inventory_size];
+#endif
 
-    Feld[jx][jy] = new_element;
+      DrawGameValue_Dynamite(local_player->inventory_size);
 
-    DrawGameValue_Dynamite(local_player->inventory_size);
+      if (new_element == EL_DYNAMITE)
+       new_element = EL_DYNAMITE_ACTIVE;
+      else if (new_element == EL_SP_DISK_RED)
+       new_element = EL_SP_DISK_RED_ACTIVE;
+    }
+
+    Feld[jx][jy] = new_element;
 
     if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
       DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
@@ -10006,7 +10128,10 @@ boolean DropElement(struct PlayerInfo *player)
   else         /* player is dropping a dyna bomb */
   {
     player->dynabombs_left--;
+
+#if 0
     new_element = EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr;
+#endif
 
     Feld[jx][jy] = new_element;
 
index ed480b14b4aca78fbb7eb8b797988e0941b57724..a78ee6118bb5241ef391f7eb193ee46af187798c 100644 (file)
@@ -1640,10 +1640,10 @@ void setMoveIntoAcidProperty(struct LevelInfo *level, int element, boolean set)
 
   if (bit_nr > -1)
   {
-    level->can_move_into_acid &= ~(1 << bit_nr);
+    level->can_move_into_acid_bits &= ~(1 << bit_nr);
 
     if (set)
-      level->can_move_into_acid |= (1 << bit_nr);
+      level->can_move_into_acid_bits |= (1 << bit_nr);
   }
 }
 
@@ -1652,7 +1652,7 @@ boolean getMoveIntoAcidProperty(struct LevelInfo *level, int element)
   int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID);
 
   if (bit_nr > -1)
-    return ((level->can_move_into_acid & (1 << bit_nr)) != 0);
+    return ((level->can_move_into_acid_bits & (1 << bit_nr)) != 0);
 
   return FALSE;
 }
index 5729b9314fc98f2d773ba0160354a163def177bb..8dfd8930bb3877f43c026bacebd3026297adeb49 100644 (file)
@@ -90,7 +90,7 @@ int                   ZX, ZY;
 int                    ExitX, ExitY;
 int                    AllPlayersGone;
 
-int                    TimeFrames, TimePlayed, TimeLeft;
+int                    TimeFrames, TimePlayed, TimeLeft, TapeTime;
 
 boolean                        network_player_action_received = FALSE;
 
index 370d28910103f66e59f26e633d23cff59ed1bd4b..e40f4d8858c266354c05ceb91ae1d068da0a492b 100644 (file)
@@ -1372,6 +1372,7 @@ struct PlayerInfo
   int shield_deadly_time_left;
 
   int inventory_element[MAX_INVENTORY_SIZE];
+  int inventory_infinite_element;
   int inventory_size;
 };
 
@@ -1422,7 +1423,7 @@ struct LevelInfo
   int time_light;
   int time_timegate;
 
-  int can_move_into_acid;      /* bits indicate property for element groups */
+  int can_move_into_acid_bits; /* bits indicate property for element groups */
 
   boolean double_speed;
   boolean initial_gravity;
@@ -1431,6 +1432,8 @@ struct LevelInfo
   boolean sp_block_last_field; /* player blocks previous field while moving */
   boolean use_spring_bug;      /* for compatibility with old levels */
 
+  int use_step_counter;                /* count steps instead of seconds for level */
+
   short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
   boolean use_custom_template; /* use custom properties from template file */
@@ -1843,7 +1846,7 @@ extern int                        ZX, ZY;
 extern int                     ExitX, ExitY;
 extern int                     AllPlayersGone;
 
-extern int                     TimeFrames, TimePlayed, TimeLeft;
+extern int                     TimeFrames, TimePlayed, TimeLeft, TapeTime;
 extern boolean                 SiebAktiv;
 extern int                     SiebCount;