rnd-20051231-1-src
authorHolger Schemel <info@artsoft.org>
Sat, 31 Dec 2005 02:35:38 +0000 (03:35 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:50:11 +0000 (10:50 +0200)
12 files changed:
src/conf_gfx.c
src/conftime.h
src/editor.c
src/files.c
src/files.h
src/game.c
src/init.c
src/libgame/misc.c
src/libgame/misc.h
src/libgame/system.h
src/main.c
src/main.h

index 33df19924bfdc6fc0fcfbd105046cdad8eb2cc5d..1c5725b16994842eed61b08473e78f58b9678067 100644 (file)
@@ -4181,13 +4181,13 @@ struct ConfigInfo image_config[] =
   { "editor.element_border_input.xpos",                "0"                     },
   { "editor.element_border_input.ypos",                "0"                     },
 
-  { "editor.cascade_list",                     "RocksFontEM.pcx"       },
-  { "editor.cascade_list.xpos",                        "11"                    },
-  { "editor.cascade_list.ypos",                        "0"                     },
+  { "editor.cascade_list",                     "RocksDoor.pcx"         },
+  { "editor.cascade_list.x",                   "708"                   },
+  { "editor.cascade_list.y",                   "80"                    },
   { "editor.cascade_list.frames",              "1"                     },
-  { "editor.cascade_list.active",              "RocksFontEM.pcx"       },
-  { "editor.cascade_list.active.xpos",         "13"                    },
-  { "editor.cascade_list.active.ypos",         "0"                     },
+  { "editor.cascade_list.active",              "RocksDoor.pcx"         },
+  { "editor.cascade_list.active.x",            "740"                   },
+  { "editor.cascade_list.active.y",            "80"                    },
   { "editor.cascade_list.active.frames",       "1"                     },
 
   { "background.envelope_1",                   "RocksScreen.pcx"       },
index d35627060444606d4057b4c08877446207ff6bd1..6283844b598b8d697b6a051b8c48dc5e976129cd 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2005-12-30 17:05]"
+#define COMPILE_DATE_STRING "[2005-12-31 02:43]"
index e25ece3686be4a78e2e9b1d2b70cde66c87c686b..2f5154c1d3d444f17d8a8f98fea6da3af95bab6d 100644 (file)
@@ -2919,6 +2919,7 @@ static void ModifyEditorSelectboxValue(int, int);
 static void ModifyEditorSelectboxOptions(int, struct ValueTextInfo *);
 static void ModifyEditorDrawingArea(int, int, int);
 static void ModifyEditorElementList();
+static void AdjustElementListScrollbar();
 static void RedrawDrawingElements();
 static void DrawDrawingWindow();
 static void DrawLevelInfoWindow();
@@ -3636,7 +3637,7 @@ static int num_editor_el_dx_boulderdash = SIZEOF_ARRAY_INT(editor_el_dx_boulderd
 
 static int editor_hl_chars[] =
 {
-  EL_INTERNAL_CASCADE_TEXT_ACTIVE,
+  EL_INTERNAL_CASCADE_CHARS_ACTIVE,
   EL_CHAR('T'),
   EL_CHAR('X'),
   EL_CHAR('T'),
@@ -4218,9 +4219,9 @@ static int num_editor_el_user_defined = 0;
 static int editor_hl_dynamic[] =
 {
   EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE,
-  EL_CHAR('D'),
-  EL_CHAR('Y'),
-  EL_CHAR('N'),
+  EL_CHAR('U'),
+  EL_CHAR('S'),
+  EL_CHAR('E'),
 };
 
 static int *editor_hl_dynamic_ptr = editor_hl_dynamic;
@@ -4244,6 +4245,7 @@ static int num_editor_elements = 0;       /* dynamically determined */
 static struct
 {
   boolean *setup_value;
+  boolean *setup_cascade_value;
 
   int **headline_list;
   int *headline_list_size;
@@ -4257,75 +4259,90 @@ editor_elements_info[] =
 {
   {
     &setup.editor.el_boulderdash,
+    &setup.editor_cascade.el_bd,
     &editor_hl_boulderdash_ptr,                &num_editor_hl_boulderdash,
     &editor_el_boulderdash_ptr,                &num_editor_el_boulderdash
   },
   {
     &setup.editor.el_emerald_mine,
+    &setup.editor_cascade.el_em,
     &editor_hl_emerald_mine_ptr,       &num_editor_hl_emerald_mine,
     &editor_el_emerald_mine_ptr,       &num_editor_el_emerald_mine
   },
   {
     &setup.editor.el_emerald_mine_club,
+    &setup.editor_cascade.el_emc,
     &editor_hl_emerald_mine_club_ptr,  &num_editor_hl_emerald_mine_club,
     &editor_el_emerald_mine_club_ptr,  &num_editor_el_emerald_mine_club
   },
   {
     &setup.editor.el_more,
+    &setup.editor_cascade.el_rnd,
     &editor_hl_more_ptr,               &num_editor_hl_more,
     &editor_el_more_ptr,               &num_editor_el_more
   },
   {
     &setup.editor.el_sokoban,
+    &setup.editor_cascade.el_sb,
     &editor_hl_sokoban_ptr,            &num_editor_hl_sokoban,
     &editor_el_sokoban_ptr,            &num_editor_el_sokoban
   },
   {
     &setup.editor.el_supaplex,
+    &setup.editor_cascade.el_sp,
     &editor_hl_supaplex_ptr,           &num_editor_hl_supaplex,
     &editor_el_supaplex_ptr,           &num_editor_el_supaplex
   },
   {
     &setup.editor.el_diamond_caves,
+    &setup.editor_cascade.el_dc,
     &editor_hl_diamond_caves_ptr,      &num_editor_hl_diamond_caves,
     &editor_el_diamond_caves_ptr,      &num_editor_el_diamond_caves
   },
   {
     &setup.editor.el_dx_boulderdash,
+    &setup.editor_cascade.el_dx,
     &editor_hl_dx_boulderdash_ptr,     &num_editor_hl_dx_boulderdash,
     &editor_el_dx_boulderdash_ptr,     &num_editor_el_dx_boulderdash
   },
   {
     &setup.editor.el_chars,
+    &setup.editor_cascade.el_chars,
     &editor_hl_chars_ptr,              &num_editor_hl_chars,
     &editor_el_chars_ptr,              &num_editor_el_chars
   },
   {
     &setup.editor.el_custom,
+    &setup.editor_cascade.el_ce,
     &editor_hl_custom_ptr,             &num_editor_hl_custom,
     &editor_el_custom_ptr,             &num_editor_el_custom
   },
   {
     &setup.editor.el_custom,
+    &setup.editor_cascade.el_ge,
     &editor_hl_group_ptr,              &num_editor_hl_group,
     &editor_el_group_ptr,              &num_editor_el_group
   },
   {
     &setup.editor.el_user_defined,
+    &setup.editor_cascade.el_user,
     &editor_hl_user_defined_ptr,       &num_editor_hl_user_defined,
     &editor_el_user_defined_ptr,       &num_editor_el_user_defined
   },
   {
     &setup.editor.el_dynamic,
+    &setup.editor_cascade.el_dynamic,
     &editor_hl_dynamic_ptr,            &num_editor_hl_dynamic,
     &editor_el_dynamic_ptr,            &num_editor_el_dynamic,
   },
   {
+    &use_el_empty,
     &use_el_empty,
     &editor_hl_empty_ptr,              &num_editor_hl_empty,
     &editor_el_empty_ptr,              &num_editor_el_empty,
   },
   {
+    NULL,
     NULL,
     NULL,                              NULL,
     NULL,                              NULL
@@ -4438,9 +4455,29 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements)
 
 static void ReinitializeElementList()
 {
+  static boolean initialization_needed = TRUE;
   int pos = 0;
   int i, j;
 
+  if (initialization_needed)
+  {
+    LoadSetup_EditorCascade();         /* load last editor cascade state */
+
+    /* initialize editor cascade element from saved cascade state */
+    for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
+    {
+      int *cascade_element = &(*editor_elements_info[i].headline_list)[0];
+      boolean cascade_value = *editor_elements_info[i].setup_cascade_value;
+
+      if (IS_EDITOR_CASCADE(*cascade_element))
+       *cascade_element =
+         (cascade_value ? EL_CASCADE_ACTIVE(*cascade_element) :
+          EL_CASCADE_INACTIVE(*cascade_element));
+    }
+
+    initialization_needed = FALSE;
+  }
+
   checked_free(editor_elements);
 
   /* reload optional user defined element list for each invocation of editor */
@@ -4539,11 +4576,9 @@ static void ReinitializeElementList()
     }
   }
 
-  /* correct position of element list scrollbar */
-  if (element_shift < 0)
-    element_shift = 0;
-  if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
-    element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
+  /* this function is also called before editor gadgets are initialized */
+  if (level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL] != NULL)
+    AdjustElementListScrollbar();
 }
 
 void PrintEditorElementList()
@@ -4553,10 +4588,25 @@ void PrintEditorElementList()
 
   for (i = 0; editor_elements_info[i].setup_value != stop; i++)
   {
+    int cascade_element = (*editor_elements_info[i].headline_list)[0];
+
+    if (IS_EDITOR_CASCADE(cascade_element))
+    {
+      int cascade_element_show = EL_CASCADE_INACTIVE(cascade_element);
+      char *headline = element_info[cascade_element_show].editor_description;
+
+      printf_line_with_prefix("# ", "-", 77);
+      printf("# %s\n", headline);
+      printf_line_with_prefix("# ", "-", 77);
+    }
+
     for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
     {
       int element = (*editor_elements_info[i].headline_list)[j];
 
+      if (IS_EDITOR_CASCADE(element))
+       element = EL_CHAR_MINUS;
+
       printf("# %s\n", element_info[element].token_name);
     }
 
@@ -6821,6 +6871,7 @@ static void AdjustElementListScrollbar()
   struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL];
   int items_max, items_visible, item_position;
 
+  /* correct position of element list scrollbar */
   if (element_shift < 0)
     element_shift = 0;
   if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
@@ -6910,8 +6961,10 @@ static void ModifyEditorElementList()
     int element = editor_elements[element_shift + i];
 
     UnmapGadget(gi);
+
     getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
     ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
+
     MapGadget(gi);
   }
 }
@@ -9504,21 +9557,24 @@ static void HandleControlButtons(struct GadgetInfo *gi)
 
          for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
          {
-           int *cascade_element = *editor_elements_info[i].headline_list;
+           int *cascade_element= &(*editor_elements_info[i].headline_list)[0];
+           boolean *cascade_value=editor_elements_info[i].setup_cascade_value;
 
            if (*cascade_element == new_element)
            {
              *cascade_element = EL_CASCADE_TOGGLE(*cascade_element);
+             *cascade_value = IS_EDITOR_CASCADE_ACTIVE(*cascade_element);
 
+             /* update element selection list */
              ReinitializeElementList();
-#if 0
-             ReinitializeElementListButtons();
-#endif
              ModifyEditorElementList();
-             AdjustElementListScrollbar();
 
+             /* update cascading gadget info text */
              PrintEditorGadgetInfoText(level_editor_gadget[id]);
 
+             /* save current editor cascading state */
+             SaveSetup_EditorCascade();
+
              break;
            }
          }
index 1d29930366fd64f8d6375501991b2c30112e0678..4647c4ef3ca5ccfbfcac6d3014c1b651a77d324f 100644 (file)
@@ -4504,6 +4504,24 @@ void SaveScore(int nr)
 
 #define NUM_EDITOR_SETUP_TOKENS                        13
 
+/* editor cascade setup */
+#define SETUP_TOKEN_EDITOR_CASCADE_BD          0
+#define SETUP_TOKEN_EDITOR_CASCADE_EM          1
+#define SETUP_TOKEN_EDITOR_CASCADE_EMC         2
+#define SETUP_TOKEN_EDITOR_CASCADE_RND         3
+#define SETUP_TOKEN_EDITOR_CASCADE_SB          4
+#define SETUP_TOKEN_EDITOR_CASCADE_SP          5
+#define SETUP_TOKEN_EDITOR_CASCADE_DC          6
+#define SETUP_TOKEN_EDITOR_CASCADE_DX          7
+#define SETUP_TOKEN_EDITOR_CASCADE_TEXT                8
+#define SETUP_TOKEN_EDITOR_CASCADE_CE          9
+#define SETUP_TOKEN_EDITOR_CASCADE_GE          10
+#define SETUP_TOKEN_EDITOR_CASCADE_USER                11
+#define SETUP_TOKEN_EDITOR_CASCADE_GENERIC     12
+#define SETUP_TOKEN_EDITOR_CASCADE_DYNAMIC     13
+
+#define NUM_EDITOR_CASCADE_SETUP_TOKENS                14
+
 /* shortcut setup */
 #define SETUP_TOKEN_SHORTCUT_SAVE_GAME         0
 #define SETUP_TOKEN_SHORTCUT_LOAD_GAME         1
@@ -4545,6 +4563,7 @@ void SaveScore(int nr)
 
 static struct SetupInfo si;
 static struct SetupEditorInfo sei;
+static struct SetupEditorCascadeInfo seci;
 static struct SetupShortcutInfo ssi;
 static struct SetupInputInfo sii;
 static struct SetupSystemInfo syi;
@@ -4594,6 +4613,24 @@ static struct TokenInfo editor_setup_tokens[] =
   { TYPE_SWITCH, &sei.el_dynamic,      "editor.el_dynamic"             },
 };
 
+static struct TokenInfo editor_cascade_setup_tokens[] =
+{
+  { TYPE_SWITCH, &seci.el_bd,          "editor.cascade.el_bd"          },
+  { TYPE_SWITCH, &seci.el_em,          "editor.cascade.el_em"          },
+  { TYPE_SWITCH, &seci.el_emc,         "editor.cascade.el_emc"         },
+  { TYPE_SWITCH, &seci.el_rnd,         "editor.cascade.el_rnd"         },
+  { TYPE_SWITCH, &seci.el_sb,          "editor.cascade.el_sb"          },
+  { TYPE_SWITCH, &seci.el_sp,          "editor.cascade.el_sp"          },
+  { TYPE_SWITCH, &seci.el_dc,          "editor.cascade.el_dc"          },
+  { TYPE_SWITCH, &seci.el_dx,          "editor.cascade.el_dx"          },
+  { TYPE_SWITCH, &seci.el_chars,       "editor.cascade.el_chars"       },
+  { TYPE_SWITCH, &seci.el_ce,          "editor.cascade.el_ce"          },
+  { TYPE_SWITCH, &seci.el_ge,          "editor.cascade.el_ge"          },
+  { TYPE_SWITCH, &seci.el_user,                "editor.cascade.el_user"        },
+  { TYPE_SWITCH, &seci.el_generic,     "editor.cascade.el_generic"     },
+  { TYPE_SWITCH, &seci.el_dynamic,     "editor.cascade.el_dynamic"     },
+};
+
 static struct TokenInfo shortcut_setup_tokens[] =
 {
   { TYPE_KEY_X11, &ssi.save_game,      "shortcut.save_game"            },
@@ -4724,6 +4761,25 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->options.verbose = FALSE;
 }
 
+static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si)
+{
+  si->editor_cascade.el_bd     = TRUE;
+  si->editor_cascade.el_em     = TRUE;
+  si->editor_cascade.el_emc    = TRUE;
+  si->editor_cascade.el_rnd    = TRUE;
+  si->editor_cascade.el_sb     = TRUE;
+  si->editor_cascade.el_sp     = TRUE;
+  si->editor_cascade.el_dc     = TRUE;
+  si->editor_cascade.el_dx     = TRUE;
+
+  si->editor_cascade.el_chars  = FALSE;
+  si->editor_cascade.el_ce     = FALSE;
+  si->editor_cascade.el_ge     = FALSE;
+  si->editor_cascade.el_user   = FALSE;
+  si->editor_cascade.el_generic        = FALSE;
+  si->editor_cascade.el_dynamic        = FALSE;
+}
+
 static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
 {
   int i, pnr;
@@ -4786,6 +4842,22 @@ static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
   setup.options = soi;
 }
 
+static void decodeSetupFileHash_EditorCascade(SetupFileHash *setup_file_hash)
+{
+  int i;
+
+  if (!setup_file_hash)
+    return;
+
+  /* editor cascade setup */
+  seci = setup.editor_cascade;
+  for (i = 0; i < NUM_EDITOR_CASCADE_SETUP_TOKENS; i++)
+    setSetupInfo(editor_cascade_setup_tokens, i,
+                getHashEntry(setup_file_hash,
+                             editor_cascade_setup_tokens[i].text));
+  setup.editor_cascade = seci;
+}
+
 void LoadSetup()
 {
   char *filename = getSetupFilename();
@@ -4816,6 +4888,27 @@ void LoadSetup()
     Error(ERR_WARN, "using default setup values");
 }
 
+void LoadSetup_EditorCascade()
+{
+  char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME);
+  SetupFileHash *setup_file_hash = NULL;
+
+  /* always start with reliable default values */
+  setSetupInfoToDefaults_EditorCascade(&setup);
+
+  setup_file_hash = loadSetupFileHash(filename);
+
+  if (setup_file_hash)
+  {
+    checkSetupFileHashIdentifier(setup_file_hash, getCookie("SETUP"));
+    decodeSetupFileHash_EditorCascade(setup_file_hash);
+
+    freeSetupFileHash(setup_file_hash);
+  }
+
+  free(filename);
+}
+
 void SaveSetup()
 {
   char *filename = getSetupFilename();
@@ -4888,6 +4981,37 @@ void SaveSetup()
   SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
+void SaveSetup_EditorCascade()
+{
+  char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME);
+  FILE *file;
+  int i;
+
+  InitUserDataDirectory();
+
+  if (!(file = fopen(filename, MODE_WRITE)))
+  {
+    Error(ERR_WARN, "cannot write editor cascade state file '%s'", filename);
+    free(filename);
+    return;
+  }
+
+  fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
+                                              getCookie("SETUP")));
+  fprintf(file, "\n");
+
+  seci = setup.editor_cascade;
+  fprintf(file, "\n");
+  for (i = 0; i < NUM_EDITOR_SETUP_TOKENS; i++)
+    fprintf(file, "%s\n", getSetupLine(editor_cascade_setup_tokens, "", i));
+
+  fclose(file);
+
+  SetFilePermissions(filename, PERMS_PRIVATE);
+
+  free(filename);
+}
+
 void LoadCustomElementDescriptions()
 {
   char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
index 9a0cf0ff04b476086d101b065db3ffcc7d830de0..ead1f24f2b0abe7d0bf3371e6b33a33b900c9953 100644 (file)
@@ -54,6 +54,9 @@ void SaveScore(int);
 void LoadSetup();
 void SaveSetup();
 
+void LoadSetup_EditorCascade();
+void SaveSetup_EditorCascade();
+
 void LoadCustomElementDescriptions();
 void LoadSpecialMenuDesignSettings();
 void LoadUserDefinedEditorElementList(int **, int *);
index 4d67b93151c841f642ef47749dda96984093b649..3eff842eb44ece2ed7c4c5efd98b0db1f0c1fc88 100644 (file)
@@ -34,6 +34,7 @@
 #define USE_NEW_PLAYER_SPEED           (USE_NEW_STUFF          * 1)
 #define USE_NEW_DELAYED_ACTION         (USE_NEW_STUFF          * 1)
 #define USE_NEW_SNAP_DELAY             (USE_NEW_STUFF          * 1)
+#define USE_ONLY_ONE_CHANGE_PER_FRAME  (USE_NEW_STUFF          * 0)
 
 /* for DigField() */
 #define DF_NO_PUSH             0
@@ -1209,6 +1210,38 @@ static void InitGameEngine()
   game.use_block_last_field_bug =
     (game.engine_version < VERSION_IDENT(3,1,1,0));
 
+  /*
+    Summary of bugfix/change:
+    Changed behaviour of CE changes with multiple changes per single frame.
+
+    Fixed/changed in version:
+    3.2.0-6
+
+    Description:
+    Before 3.2.0-6, only one single CE change was allowed in each engine frame.
+    This resulted in race conditions where CEs seem to behave strange in some
+    situations (where triggered CE changes were just skipped because there was
+    already a CE change on that tile in the playfield in that engine frame).
+    Since 3.2.0-6, this was changed to allow up to MAX_NUM_CHANGES_PER_FRAME.
+    (The number of changes per frame must be limited in any case, because else
+    it is easily possible to define CE changes that would result in an infinite
+    loop, causing the whole game to freeze. The MAX_NUM_CHANGES_PER_FRAME value
+    should be set large enough so that it would only be reached in cases where
+    the corresponding CE change conditions run into a loop. Therefore, it seems
+    to be reasonable to set MAX_NUM_CHANGES_PER_FRAME to the same value as the
+    maximal number of change pages for custom elements.)
+
+    Affected levels/tapes:
+    Probably many.
+  */
+
+#if USE_ONLY_ONE_CHANGE_PER_FRAME
+  game.max_num_changes_per_frame = 1;
+#else
+  game.max_num_changes_per_frame =
+    (game.engine_version < VERSION_IDENT(3,2,0,6) ? 1 : 32);
+#endif
+
   /* ---------------------------------------------------------------------- */
 
   /* dynamically adjust element properties according to game engine version */
@@ -1706,7 +1739,7 @@ void InitGame()
       Stop[x][y] = FALSE;
       Pushed[x][y] = FALSE;
 
-      Changed[x][y] = FALSE;
+      Changed[x][y] = 0;
       ChangeEvent[x][y] = -1;
 
       ExplodePhase[x][y] = 0;
@@ -5675,7 +5708,7 @@ void ContinueMoving(int x, int y)
 
   ChangeDelay[x][y] = 0;
   ChangePage[x][y] = -1;
-  Changed[x][y] = FALSE;
+  Changed[x][y] = 0;
   ChangeEvent[x][y] = -1;
 
 #if USE_NEW_CUSTOM_VALUE
@@ -7118,11 +7151,7 @@ static void ChangeElementNowExt(struct ElementChangeInfo *change,
   if (ELEM_IS_PLAYER(target_element))
     RelocatePlayer(x, y, target_element);
 
-#if 1
-  Changed[x][y] = TRUE;                /* ignore all further changes in this frame */
-#else
-  Changed[x][y] |= ChangeEvent[x][y];  /* ignore same changes in this frame */
-#endif
+  Changed[x][y]++;             /* count number of changes in the same frame */
 
   TestIfBadThingTouchesPlayer(x, y);
   TestIfPlayerTouchesCustomElement(x, y);
@@ -7148,21 +7177,11 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
     change->actual_trigger_ce_value = 0;
   }
 
-#if 1
-  /* do not change any elements that have already changed in this frame */
-  if (Changed[x][y])
+  /* do not change elements more than a specified maximum number of changes */
+  if (Changed[x][y] >= game.max_num_changes_per_frame)
     return FALSE;
-#else
-  /* do not change already changed elements with same change event */
-  if (Changed[x][y] & ChangeEvent[x][y])
-    return FALSE;
-#endif
 
-#if 1
-  Changed[x][y] = TRUE;                /* ignore all further changes in this frame */
-#else
-  Changed[x][y] |= ChangeEvent[x][y];  /* ignore same changes in this frame */
-#endif
+  Changed[x][y]++;             /* count number of changes in the same frame */
 
   if (change->explode)
   {
@@ -8044,7 +8063,7 @@ void GameActions()
 
   for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
   {
-    Changed[x][y] = FALSE;
+    Changed[x][y] = 0;
     ChangeEvent[x][y] = -1;
 
     /* this must be handled before main playfield loop */
@@ -8652,8 +8671,19 @@ boolean MovePlayerOneStep(struct PlayerInfo *player,
 
   if (player->cannot_move)
   {
+#if 1
+    if (player->MovPos == 0)
+    {
+      player->is_moving = FALSE;
+      player->is_digging = FALSE;
+      player->is_collecting = FALSE;
+      player->is_snapping = FALSE;
+      player->is_pushing = FALSE;
+    }
+#else
     DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
     SnapField(player, 0, 0);
+#endif
 
     return MF_NO_ACTION;
   }
@@ -10468,7 +10498,7 @@ boolean DropElement(struct PlayerInfo *player)
     PlayLevelSoundAction(dropx, dropy, ACTION_DROPPING);
 
     /* needed if previous element just changed to "empty" in the last frame */
-    Changed[dropx][dropy] = FALSE;             /* allow another change */
+    Changed[dropx][dropy] = 0;         /* allow at least one more change */
 
     CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER,
                               player->index_bit, drop_side);
@@ -10508,7 +10538,7 @@ boolean DropElement(struct PlayerInfo *player)
     nextx = dropx + GET_DX_FROM_DIR(move_direction);
     nexty = dropy + GET_DY_FROM_DIR(move_direction);
 
-    Changed[dropx][dropy] = FALSE;             /* allow another change */
+    Changed[dropx][dropy] = 0;         /* allow at least one more change */
     CheckCollision[dropx][dropy] = 2;
   }
 
index b89412c4bb16016490c8d6d4a7fd4dc171a31849..b4b78259e4db2b48151bad954c48574df729b3c2 100644 (file)
@@ -109,6 +109,14 @@ inline void InitElementSmallImagesScaledUp(int graphic)
 
 void InitElementSmallImages()
 {
+  static int special_graphics[] =
+  {
+    IMG_EDITOR_ELEMENT_BORDER,
+    IMG_EDITOR_ELEMENT_BORDER_INPUT,
+    IMG_EDITOR_CASCADE_LIST,
+    IMG_EDITOR_CASCADE_LIST_ACTIVE,
+    -1
+  };
   struct PropertyMapping *property_mapping = getImageListPropertyMapping();
   int num_property_mappings = getImageListPropertyMappingSize();
   int i;
@@ -124,6 +132,10 @@ void InitElementSmallImages()
   /* initialize images from dynamic configuration (may be elements or other) */
   for (i = 0; i < num_property_mappings; i++)
     InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+
+  /* initialize special images from above list (non-element images) */
+  for (i = 0; special_graphics[i] > -1; i++)
+    InitElementSmallImagesScaledUp(special_graphics[i]);
 }
 
 #if 1
@@ -3371,7 +3383,7 @@ void InitElementPropertiesStatic()
     EL_INTERNAL_CASCADE_SP_ACTIVE,
     EL_INTERNAL_CASCADE_DC_ACTIVE,
     EL_INTERNAL_CASCADE_DX_ACTIVE,
-    EL_INTERNAL_CASCADE_TEXT_ACTIVE,
+    EL_INTERNAL_CASCADE_CHARS_ACTIVE,
     EL_INTERNAL_CASCADE_CE_ACTIVE,
     EL_INTERNAL_CASCADE_GE_ACTIVE,
     EL_INTERNAL_CASCADE_USER_ACTIVE,
@@ -3390,7 +3402,7 @@ void InitElementPropertiesStatic()
     EL_INTERNAL_CASCADE_SP,
     EL_INTERNAL_CASCADE_DC,
     EL_INTERNAL_CASCADE_DX,
-    EL_INTERNAL_CASCADE_TEXT,
+    EL_INTERNAL_CASCADE_CHARS,
     EL_INTERNAL_CASCADE_CE,
     EL_INTERNAL_CASCADE_GE,
     EL_INTERNAL_CASCADE_USER,
@@ -3859,6 +3871,10 @@ void Execute_Command(char *command)
     printf("# (The entries below are default and therefore commented out.)\n");
     printf("\n");
 
+    /* this is needed to be able to check element list for cascade elements */
+    InitElementPropertiesStatic();
+    InitElementPropertiesEngine(GAME_VERSION_ACTUAL);
+
     PrintEditorElementList();
 
     exit(0);
index 685311b94918d900c91ac7a493da25a100903b89..f0a282f16a12e2611ab84c9e8b796fd0b84961fd 100644 (file)
@@ -52,6 +52,12 @@ void printf_line(char *line_string, int line_length)
   fprintf_line(stdout, line_string, line_length);
 }
 
+void printf_line_with_prefix(char *prefix, char *line_string, int line_length)
+{
+  fprintf(stdout, "%s", prefix);
+  fprintf_line(stdout, line_string, line_length);
+}
+
 
 /* int2str() returns a number converted to a string;
    the used memory is static, but will be overwritten by later calls,
index caa57ea3d3bb799f995b094bc41da99bbb9739dc..c69d5f5c2f01c24b41cb49593d52fb6b0d4bc8e1 100644 (file)
@@ -69,6 +69,7 @@
 
 void fprintf_line(FILE *, char *, int);
 void printf_line(char *, int);
+void printf_line_with_prefix(char *, char *, int);
 char *int2str(int, int);
 char *i_to_a(unsigned int);
 int log_2(unsigned int);
index c8b7d4d346d54d0567fda692d8bc27303d6a1968..32f4ee6a36b916f1b5b78a587ca8fa5ac2dfbb3f 100644 (file)
 #define SETUP_FILENAME         "setup.conf"
 #define LEVELSETUP_FILENAME    "levelsetup.conf"
 #define EDITORSETUP_FILENAME   "editorsetup.conf"
+#define EDITORCASCADE_FILENAME "editorcascade.conf"
 #define HELPANIM_FILENAME      "helpanim.conf"
 #define HELPTEXT_FILENAME      "helptext.conf"
 #define LEVELINFO_FILENAME     "levelinfo.conf"
 #define SETUP_FILENAME         "setup.cnf"
 #define LEVELSETUP_FILENAME    "lvlsetup.cnf"
 #define EDITORSETUP_FILENAME   "edsetup.cnf"
+#define EDITORCASCADE_FILENAME "edcascad.conf"
 #define HELPANIM_FILENAME      "helpanim.cnf"
 #define HELPTEXT_FILENAME      "helptext.cnf"
 #define LEVELINFO_FILENAME     "lvlinfo.cnf"
@@ -592,6 +594,24 @@ struct SetupEditorInfo
   boolean el_headlines;
 };
 
+struct SetupEditorCascadeInfo
+{
+  boolean el_bd;
+  boolean el_em;
+  boolean el_emc;
+  boolean el_rnd;
+  boolean el_sb;
+  boolean el_sp;
+  boolean el_dc;
+  boolean el_dx;
+  boolean el_chars;
+  boolean el_ce;
+  boolean el_ge;
+  boolean el_user;
+  boolean el_generic;
+  boolean el_dynamic;
+};
+
 struct SetupShortcutInfo
 {
   Key save_game;
@@ -636,6 +656,7 @@ struct SetupInfo
   boolean override_level_music;
 
   struct SetupEditorInfo editor;
+  struct SetupEditorCascadeInfo editor_cascade;
   struct SetupShortcutInfo shortcut;
   struct SetupInputInfo input[MAX_PLAYERS];
   struct SetupSystemInfo system;
index 50f262eba227cd1b4d88c495a4dfd6549b667d5e..99538b9d4a9b5455c494a2e29dcbf5c037a0ed7e 100644 (file)
@@ -50,7 +50,7 @@ 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];
-boolean                        Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short                  Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
@@ -4275,12 +4275,12 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "hide DX Boulderdash elements"
   },
   {
-    "internal_cascade_text",
+    "internal_cascade_chars",
     "internal",
     "show text elements"
   },
   {
-    "internal_cascade_text.active",
+    "internal_cascade_chars.active",
     "internal",
     "hide text elements"
   },
@@ -4327,12 +4327,12 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "internal_cascade_dynamic",
     "internal",
-    "show elements from this level"
+    "show elements used in this level"
   },
   {
     "internal_cascade_dynamic.active",
     "internal",
-    "hide elements from this level"
+    "hide elements used in this level"
   },
 
   /* keyword to stop parser: "ELEMENT_INFO_END" <-- do not change! */
index 5331d94a2126f4b30e0dc6e3209ec1ed8b98b23a..736d1c73dad3f1ab4eced01ae79b0a6e33c30b6c 100644 (file)
 #define EL_INTERNAL_CLIPBOARD_GROUP    (EL_FIRST_INTERNAL + 2)
 #define EL_INTERNAL_DUMMY              (EL_FIRST_INTERNAL + 3)
 
-#define EL_INTERNAL_CASCADE_BD         (EL_FIRST_INTERNAL + 4)
-#define EL_INTERNAL_CASCADE_BD_ACTIVE  (EL_FIRST_INTERNAL + 5)
-#define EL_INTERNAL_CASCADE_EM         (EL_FIRST_INTERNAL + 6)
-#define EL_INTERNAL_CASCADE_EM_ACTIVE  (EL_FIRST_INTERNAL + 7)
-#define EL_INTERNAL_CASCADE_EMC                (EL_FIRST_INTERNAL + 8)
-#define EL_INTERNAL_CASCADE_EMC_ACTIVE (EL_FIRST_INTERNAL + 9)
-#define EL_INTERNAL_CASCADE_RND                (EL_FIRST_INTERNAL + 10)
-#define EL_INTERNAL_CASCADE_RND_ACTIVE (EL_FIRST_INTERNAL + 11)
-#define EL_INTERNAL_CASCADE_SB         (EL_FIRST_INTERNAL + 12)
-#define EL_INTERNAL_CASCADE_SB_ACTIVE  (EL_FIRST_INTERNAL + 13)
-#define EL_INTERNAL_CASCADE_SP         (EL_FIRST_INTERNAL + 14)
-#define EL_INTERNAL_CASCADE_SP_ACTIVE  (EL_FIRST_INTERNAL + 15)
-#define EL_INTERNAL_CASCADE_DC         (EL_FIRST_INTERNAL + 16)
-#define EL_INTERNAL_CASCADE_DC_ACTIVE  (EL_FIRST_INTERNAL + 17)
-#define EL_INTERNAL_CASCADE_DX         (EL_FIRST_INTERNAL + 18)
-#define EL_INTERNAL_CASCADE_DX_ACTIVE  (EL_FIRST_INTERNAL + 19)
-#define EL_INTERNAL_CASCADE_TEXT       (EL_FIRST_INTERNAL + 20)
-#define EL_INTERNAL_CASCADE_TEXT_ACTIVE        (EL_FIRST_INTERNAL + 21)
-#define EL_INTERNAL_CASCADE_CE         (EL_FIRST_INTERNAL + 22)
-#define EL_INTERNAL_CASCADE_CE_ACTIVE  (EL_FIRST_INTERNAL + 23)
-#define EL_INTERNAL_CASCADE_GE         (EL_FIRST_INTERNAL + 24)
-#define EL_INTERNAL_CASCADE_GE_ACTIVE  (EL_FIRST_INTERNAL + 25)
-#define EL_INTERNAL_CASCADE_USER       (EL_FIRST_INTERNAL + 26)
-#define EL_INTERNAL_CASCADE_USER_ACTIVE        (EL_FIRST_INTERNAL + 27)
-#define EL_INTERNAL_CASCADE_GENERIC       (EL_FIRST_INTERNAL + 28)
-#define EL_INTERNAL_CASCADE_GENERIC_ACTIVE (EL_FIRST_INTERNAL + 29)
-#define EL_INTERNAL_CASCADE_DYNAMIC       (EL_FIRST_INTERNAL + 30)
-#define EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE (EL_FIRST_INTERNAL + 31)
+#define EL_INTERNAL_CASCADE_BD                 (EL_FIRST_INTERNAL + 4)
+#define EL_INTERNAL_CASCADE_BD_ACTIVE          (EL_FIRST_INTERNAL + 5)
+#define EL_INTERNAL_CASCADE_EM                 (EL_FIRST_INTERNAL + 6)
+#define EL_INTERNAL_CASCADE_EM_ACTIVE          (EL_FIRST_INTERNAL + 7)
+#define EL_INTERNAL_CASCADE_EMC                        (EL_FIRST_INTERNAL + 8)
+#define EL_INTERNAL_CASCADE_EMC_ACTIVE         (EL_FIRST_INTERNAL + 9)
+#define EL_INTERNAL_CASCADE_RND                        (EL_FIRST_INTERNAL + 10)
+#define EL_INTERNAL_CASCADE_RND_ACTIVE         (EL_FIRST_INTERNAL + 11)
+#define EL_INTERNAL_CASCADE_SB                 (EL_FIRST_INTERNAL + 12)
+#define EL_INTERNAL_CASCADE_SB_ACTIVE          (EL_FIRST_INTERNAL + 13)
+#define EL_INTERNAL_CASCADE_SP                 (EL_FIRST_INTERNAL + 14)
+#define EL_INTERNAL_CASCADE_SP_ACTIVE          (EL_FIRST_INTERNAL + 15)
+#define EL_INTERNAL_CASCADE_DC                 (EL_FIRST_INTERNAL + 16)
+#define EL_INTERNAL_CASCADE_DC_ACTIVE          (EL_FIRST_INTERNAL + 17)
+#define EL_INTERNAL_CASCADE_DX                 (EL_FIRST_INTERNAL + 18)
+#define EL_INTERNAL_CASCADE_DX_ACTIVE          (EL_FIRST_INTERNAL + 19)
+#define EL_INTERNAL_CASCADE_CHARS              (EL_FIRST_INTERNAL + 20)
+#define EL_INTERNAL_CASCADE_CHARS_ACTIVE       (EL_FIRST_INTERNAL + 21)
+#define EL_INTERNAL_CASCADE_CE                 (EL_FIRST_INTERNAL + 22)
+#define EL_INTERNAL_CASCADE_CE_ACTIVE          (EL_FIRST_INTERNAL + 23)
+#define EL_INTERNAL_CASCADE_GE                 (EL_FIRST_INTERNAL + 24)
+#define EL_INTERNAL_CASCADE_GE_ACTIVE          (EL_FIRST_INTERNAL + 25)
+#define EL_INTERNAL_CASCADE_USER               (EL_FIRST_INTERNAL + 26)
+#define EL_INTERNAL_CASCADE_USER_ACTIVE                (EL_FIRST_INTERNAL + 27)
+#define EL_INTERNAL_CASCADE_GENERIC            (EL_FIRST_INTERNAL + 28)
+#define EL_INTERNAL_CASCADE_GENERIC_ACTIVE     (EL_FIRST_INTERNAL + 29)
+#define EL_INTERNAL_CASCADE_DYNAMIC            (EL_FIRST_INTERNAL + 30)
+#define EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE     (EL_FIRST_INTERNAL + 31)
 
 #define EL_INTERNAL_CLIPBOARD_START    (EL_FIRST_INTERNAL + 0)
 #define EL_INTERNAL_CLIPBOARD_END      (EL_FIRST_INTERNAL + 2)
@@ -1986,6 +1986,7 @@ struct GameInfo
   /* (for the latest engine version, these flags should always be "FALSE") */
   boolean use_change_when_pushing_bug;
   boolean use_block_last_field_bug;
+  boolean max_num_changes_per_frame;
 
   /* variable within running game */
   int yamyam_content_nr;
@@ -2362,7 +2363,7 @@ 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 boolean                 Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short                   Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];