rnd-20051217-2-src
authorHolger Schemel <info@artsoft.org>
Sat, 17 Dec 2005 03:07:38 +0000 (04:07 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:49:57 +0000 (10:49 +0200)
* added new player option "block snap field" (enabled by default) to
  make it possible to show a snapping animation like in Emerald Mine

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

index d2718887203c13fc34e053b314a6082056d8a4b5..6859bdeee2a52edc2256d1c7cea88769510ef408 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2005-12-17
+       * added new player option "block snap field" (enabled by default) to
+         make it possible to show a snapping animation like in Emerald Mine
+
 2005-12-16
        * added dynamic checkboxes to custom element action settings in editor
        * added "CE value" counter for custom elements (instead of "CE count")
index 9ecbf26b9358e383609d2963d842a6479d5114a6..103dd7d4573cfde155b03180d89457233ffbc0ee 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2005-12-17 00:15]"
+#define COMPILE_DATE_STRING "[2005-12-17 04:05]"
index d4e44e8c0ab3e53b5d743a2fe467137a77bd241e..14c5c353e25f0264942702fe97e112104b389ef0 100644 (file)
 #define GADGET_ID_USE_TIME_ORB_BUG     (GADGET_ID_CHECKBUTTON_FIRST + 7)
 #define GADGET_ID_GROW_INTO_DIGGABLE   (GADGET_ID_CHECKBUTTON_FIRST + 8)
 #define GADGET_ID_DOUBLE_SPEED         (GADGET_ID_CHECKBUTTON_FIRST + 9)
-#define GADGET_ID_BLOCK_LAST_FIELD     (GADGET_ID_CHECKBUTTON_FIRST + 10)
-#define GADGET_ID_SP_BLOCK_LAST_FIELD  (GADGET_ID_CHECKBUTTON_FIRST + 11)
-#define GADGET_ID_INSTANT_RELOCATION   (GADGET_ID_CHECKBUTTON_FIRST + 12)
-#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 13)
-#define GADGET_ID_CAN_FALL_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 14)
-#define GADGET_ID_CAN_MOVE_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 15)
-#define GADGET_ID_DONT_COLLIDE_WITH    (GADGET_ID_CHECKBUTTON_FIRST + 16)
-#define GADGET_ID_CUSTOM_INDESTRUCTIBLE        (GADGET_ID_CHECKBUTTON_FIRST + 17)
-#define GADGET_ID_CUSTOM_CAN_EXPLODE   (GADGET_ID_CHECKBUTTON_FIRST + 18)
-#define GADGET_ID_CUSTOM_EXPLODE_FIRE  (GADGET_ID_CHECKBUTTON_FIRST + 19)
-#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 20)
-#define GADGET_ID_CUSTOM_EXPLODE_IMPACT        (GADGET_ID_CHECKBUTTON_FIRST + 21)
-#define GADGET_ID_CUSTOM_WALK_TO_OBJECT        (GADGET_ID_CHECKBUTTON_FIRST + 22)
-#define GADGET_ID_CUSTOM_DEADLY                (GADGET_ID_CHECKBUTTON_FIRST + 23)
-#define GADGET_ID_CUSTOM_CAN_MOVE      (GADGET_ID_CHECKBUTTON_FIRST + 24)
-#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 25)
-#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 26)
-#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 27)
-#define GADGET_ID_CUSTOM_ACCESSIBLE    (GADGET_ID_CHECKBUTTON_FIRST + 28)
-#define GADGET_ID_CUSTOM_GRAV_REACHABLE        (GADGET_ID_CHECKBUTTON_FIRST + 29)
-#define GADGET_ID_CUSTOM_USE_LAST_VALUE        (GADGET_ID_CHECKBUTTON_FIRST + 30)
-#define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 31)
-#define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 32)
-#define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 33)
-#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 34)
-#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 35)
-#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 36)
-#define GADGET_ID_CHANGE_USE_RANDOM    (GADGET_ID_CHECKBUTTON_FIRST + 37)
-#define GADGET_ID_CHANGE_HAS_ACTION    (GADGET_ID_CHECKBUTTON_FIRST + 38)
-#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 39)
-#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 40)
-#define GADGET_ID_CHANGE_BY_OTHER_ACT  (GADGET_ID_CHECKBUTTON_FIRST + 41)
+#define GADGET_ID_BLOCK_SNAP_FIELD     (GADGET_ID_CHECKBUTTON_FIRST + 10)
+#define GADGET_ID_BLOCK_LAST_FIELD     (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_SP_BLOCK_LAST_FIELD  (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_INSTANT_RELOCATION   (GADGET_ID_CHECKBUTTON_FIRST + 13)
+#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 14)
+#define GADGET_ID_CAN_FALL_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 15)
+#define GADGET_ID_CAN_MOVE_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 16)
+#define GADGET_ID_DONT_COLLIDE_WITH    (GADGET_ID_CHECKBUTTON_FIRST + 17)
+#define GADGET_ID_CUSTOM_INDESTRUCTIBLE        (GADGET_ID_CHECKBUTTON_FIRST + 18)
+#define GADGET_ID_CUSTOM_CAN_EXPLODE   (GADGET_ID_CHECKBUTTON_FIRST + 19)
+#define GADGET_ID_CUSTOM_EXPLODE_FIRE  (GADGET_ID_CHECKBUTTON_FIRST + 20)
+#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 21)
+#define GADGET_ID_CUSTOM_EXPLODE_IMPACT        (GADGET_ID_CHECKBUTTON_FIRST + 22)
+#define GADGET_ID_CUSTOM_WALK_TO_OBJECT        (GADGET_ID_CHECKBUTTON_FIRST + 23)
+#define GADGET_ID_CUSTOM_DEADLY                (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CUSTOM_CAN_MOVE      (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 26)
+#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 27)
+#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 28)
+#define GADGET_ID_CUSTOM_ACCESSIBLE    (GADGET_ID_CHECKBUTTON_FIRST + 29)
+#define GADGET_ID_CUSTOM_GRAV_REACHABLE        (GADGET_ID_CHECKBUTTON_FIRST + 30)
+#define GADGET_ID_CUSTOM_USE_LAST_VALUE        (GADGET_ID_CHECKBUTTON_FIRST + 31)
+#define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 32)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 33)
+#define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 34)
+#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 36)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 37)
+#define GADGET_ID_CHANGE_USE_RANDOM    (GADGET_ID_CHECKBUTTON_FIRST + 38)
+#define GADGET_ID_CHANGE_HAS_ACTION    (GADGET_ID_CHECKBUTTON_FIRST + 39)
+#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 40)
+#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 41)
+#define GADGET_ID_CHANGE_BY_OTHER_ACT  (GADGET_ID_CHECKBUTTON_FIRST + 42)
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 42)
+#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 43)
 #define GADGET_ID_ELEMENTLIST_LAST     (GADGET_ID_ELEMENTLIST_FIRST +  \
                                        ED_NUM_ELEMENTLIST_BUTTONS - 1)
 
 #define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG     5
 #define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE   6
 #define ED_CHECKBUTTON_ID_DOUBLE_SPEED         7
-#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD     8
-#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD  9
-#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION   10
-#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 11
-#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID   12
-#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID   13
-#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH    14
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC   15
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE  16
-#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE    17
-#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE        18
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE        19
-#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT        20
-#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE        21
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      22
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      23
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     24
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      25
-#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY                26
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE   27
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE  28
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 29
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT        30
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    31
-#define ED_CHECKBUTTON_ID_CHANGE_DELAY         32
-#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 33
-#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT  34
-#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 35
-#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   36
-#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 37
-#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM    38
-#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION    39
-
-#define ED_NUM_CHECKBUTTONS                    40
+#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD     8
+#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD     9
+#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD  10
+#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION   11
+#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 12
+#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID   13
+#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID   14
+#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH    15
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC   16
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE  17
+#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE    18
+#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE        19
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE        20
+#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT        21
+#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE        22
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      23
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      24
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     25
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      26
+#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY                27
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE   28
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE  29
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 30
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT        31
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    32
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY         33
+#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 34
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT  35
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 36
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   37
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 38
+#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM    39
+#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION    40
+
+#define ED_NUM_CHECKBUTTONS                    41
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_INITIAL_GRAVITY
 #define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
@@ -2350,6 +2352,13 @@ static struct
     NULL,
     "double speed movement",           "set initial movement speed of player"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(5),
+    GADGET_ID_BLOCK_SNAP_FIELD,                GADGET_ID_NONE,
+    &level.block_snap_field,
+    NULL,
+    "block snap field when snapping",  "use snapping delay to show animation"
+  },
   {
     ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(1),
     GADGET_ID_BLOCK_LAST_FIELD,                GADGET_ID_NONE,
@@ -7347,6 +7356,7 @@ static void DrawPropertiesConfig()
     MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ?
                         ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD :
                         ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD);
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION);
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE);
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DOUBLE_SPEED);
index 4cf2a857ea8246c32f98c681ecbfb40866c14498..0482ba8d65b1b6bcc33b59936a115d92b71f5d1b 100644 (file)
@@ -389,6 +389,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
   level->can_pass_to_walkable = FALSE;
   level->grow_into_diggable = TRUE;
 
+  level->block_snap_field = TRUE;
+
   level->block_last_field = FALSE;     /* EM does not block by default */
   level->sp_block_last_field = TRUE;   /* SP blocks the last field */
 
@@ -2783,77 +2785,10 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
   if (leveldir_current == NULL)                /* only when dumping level */
     return;
 
-#if 0
-  printf("::: sort_priority: %d\n", leveldir_current->sort_priority);
-#endif
-
-  /* determine correct game engine version of current level */
-  if (!leveldir_current->latest_engine)
+  if (leveldir_current->latest_engine)
   {
-    /* For all levels which are not forced to use the latest game engine
-       version (normally user contributed, private and undefined levels),
-       use the version of the game engine the levels were created for.
-
-       Since 2.0.1, the game engine version is now directly stored
-       in the level file (chunk "VERS"), so there is no need anymore
-       to set the game version from the file version (except for old,
-       pre-2.0 levels, where the game version is still taken from the
-       file format version used to store the level -- see above). */
-
-    /* player was faster than enemies in 1.0.0 and before */
-    if (level->file_version == FILE_VERSION_1_0)
-      level->double_speed = TRUE;
-
-    /* default behaviour for EM style gems was "slippery" only in 2.0.1 */
-    if (level->game_version == VERSION_IDENT(2,0,1,0))
-      level->em_slippery_gems = TRUE;
-
-    /* springs could be pushed over pits before (pre-release version) 2.2.0 */
-    if (level->game_version < VERSION_IDENT(2,2,0,0))
-      level->use_spring_bug = TRUE;
-
-    /* time orb caused limited time in endless time levels before 3.1.2 */
-    if (level->game_version < VERSION_IDENT(3,1,2,0))
-      level->use_time_orb_bug = TRUE;
-
-    /* only few elements were able to actively move into acid before 3.1.0 */
-    /* trigger settings did not exist before 3.1.0; set to default "any" */
-    if (level->game_version < VERSION_IDENT(3,1,0,0))
-    {
-      int i, j;
-
-      /* correct "can move into acid" settings (all zero in old levels) */
-
-      level->can_move_into_acid_bits = 0; /* nothing can move into acid */
-      level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */
-
-      setMoveIntoAcidProperty(level, EL_ROBOT,     TRUE);
-      setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE);
-      setMoveIntoAcidProperty(level, EL_PENGUIN,   TRUE);
-      setMoveIntoAcidProperty(level, EL_BALLOON,   TRUE);
+    /* ---------- use latest game engine ----------------------------------- */
 
-      for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
-       SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE);
-
-      /* correct trigger settings (stored as zero == "none" in old levels) */
-
-      for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
-      {
-       int element = EL_CUSTOM_START + i;
-       struct ElementInfo *ei = &element_info[element];
-
-       for (j = 0; j < ei->num_change_pages; j++)
-       {
-         struct ElementChangeInfo *change = &ei->change_page[j];
-
-         change->trigger_player = CH_PLAYER_ANY;
-         change->trigger_page = CH_PAGE_ANY;
-       }
-      }
-    }
-  }
-  else         /* always use the latest game engine version */
-  {
     /* For all levels which are forced to use the latest game engine version
        (normally all but user contributed, private and undefined levels), set
        the game engine version to the actual version; this allows for actual
@@ -2873,6 +2808,76 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
 
     if (level->file_version < FILE_VERSION_2_0)
       level->em_slippery_gems = TRUE;
+
+    return;
+  }
+
+  /* ---------- use game engine the level was created with ----------------- */
+
+  /* For all levels which are not forced to use the latest game engine
+     version (normally user contributed, private and undefined levels),
+     use the version of the game engine the levels were created for.
+
+     Since 2.0.1, the game engine version is now directly stored
+     in the level file (chunk "VERS"), so there is no need anymore
+     to set the game version from the file version (except for old,
+     pre-2.0 levels, where the game version is still taken from the
+     file format version used to store the level -- see above). */
+
+  /* player was faster than enemies in 1.0.0 and before */
+  if (level->file_version == FILE_VERSION_1_0)
+    level->double_speed = TRUE;
+
+  /* default behaviour for EM style gems was "slippery" only in 2.0.1 */
+  if (level->game_version == VERSION_IDENT(2,0,1,0))
+    level->em_slippery_gems = TRUE;
+
+  /* springs could be pushed over pits before (pre-release version) 2.2.0 */
+  if (level->game_version < VERSION_IDENT(2,2,0,0))
+    level->use_spring_bug = TRUE;
+
+  /* time orb caused limited time in endless time levels before 3.1.2 */
+  if (level->game_version < VERSION_IDENT(3,1,2,0))
+    level->use_time_orb_bug = TRUE;
+
+  /* default behaviour for snapping was "no snap delay" before 3.1.2 */
+  if (level->game_version < VERSION_IDENT(3,1,2,0))
+    level->block_snap_field = FALSE;
+
+  /* only few elements were able to actively move into acid before 3.1.0 */
+  /* trigger settings did not exist before 3.1.0; set to default "any" */
+  if (level->game_version < VERSION_IDENT(3,1,0,0))
+  {
+    int i, j;
+
+    /* correct "can move into acid" settings (all zero in old levels) */
+
+    level->can_move_into_acid_bits = 0; /* nothing can move into acid */
+    level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */
+
+    setMoveIntoAcidProperty(level, EL_ROBOT,     TRUE);
+    setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE);
+    setMoveIntoAcidProperty(level, EL_PENGUIN,   TRUE);
+    setMoveIntoAcidProperty(level, EL_BALLOON,   TRUE);
+
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+      SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE);
+
+    /* correct trigger settings (stored as zero == "none" in old levels) */
+
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+    {
+      int element = EL_CUSTOM_START + i;
+      struct ElementInfo *ei = &element_info[element];
+
+      for (j = 0; j < ei->num_change_pages; j++)
+      {
+       struct ElementChangeInfo *change = &ei->change_page[j];
+
+       change->trigger_player = CH_PLAYER_ANY;
+       change->trigger_page = CH_PAGE_ANY;
+      }
+    }
   }
 }
 
index ae9c3bd2f977282c47cb48e3244f626f749c295a..cc4dace14930446668c0b72ac43f2750b9f19be2 100644 (file)
@@ -33,6 +33,7 @@
 #define USE_NEW_ALL_SLIPPERY           (USE_NEW_STUFF          * 1)
 #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)
 
 /* for DigField() */
 #define DF_NO_PUSH             0
@@ -7930,6 +7931,18 @@ void GameActions()
        RemoveField(x, y);
     }
 
+#if USE_NEW_SNAP_DELAY
+    if (Feld[x][y] == EL_ELEMENT_SNAPPING)
+    {
+      MovDelay[x][y]--;
+      if (MovDelay[x][y] <= 0)
+      {
+       RemoveField(x, y);
+       DrawLevelField(x, y);
+      }
+    }
+#endif
+
 #if DEBUG
     if (ChangePage[x][y] != -1 && ChangeDelay[x][y] != 1)
     {
@@ -8084,6 +8097,14 @@ void GameActions()
       CheckForDragon(x, y);
     else if (element == EL_EXPLOSION)
       ;        /* drawing of correct explosion animation is handled separately */
+    else if (element == EL_ELEMENT_SNAPPING)
+    {
+#if 1
+      graphic = el_act_dir2img(GfxElement[x][y], GfxAction[x][y],GfxDir[x][y]);
+
+      DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+#endif
+    }
     else if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y))
       DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
 
@@ -9483,6 +9504,27 @@ void RemovePlayer(struct PlayerInfo *player)
   ExitY = ZY = jy;
 }
 
+#if USE_NEW_SNAP_DELAY
+static void setFieldForSnapping(int x, int y, int element, int direction)
+{
+  struct ElementInfo *ei = &element_info[element];
+  int direction_bit = MV_DIR_BIT(direction);
+  int graphic_snapping = ei->direction_graphic[ACTION_SNAPPING][direction_bit];
+  int action = (graphic_snapping != IMG_EMPTY_SPACE ? ACTION_SNAPPING :
+               IS_DIGGABLE(element) ? ACTION_DIGGING : ACTION_COLLECTING);
+
+  Feld[x][y] = EL_ELEMENT_SNAPPING;
+  MovDelay[x][y] = MOVE_DELAY_NORMAL_SPEED + 1 - 1;
+
+  ResetGfxAnimation(x, y);
+
+  GfxElement[x][y] = element;
+  GfxAction[x][y] = action;
+  GfxDir[x][y] = direction;
+  GfxFrame[x][y] = -1;
+}
+#endif
+
 /*
   =============================================================================
   checkDiagonalPushing()
@@ -9707,7 +9749,14 @@ int DigField(struct PlayerInfo *player,
                                        player->index_bit, dig_side);
 
     if (mode == DF_SNAP)
+    {
       TestIfElementTouchesCustomElement(x, y); /* for empty space */
+
+#if USE_NEW_SNAP_DELAY
+      if (level.block_snap_field)
+       setFieldForSnapping(x, y, element, move_direction);
+#endif
+    }
   }
   else if (IS_COLLECTIBLE(element))
   {
@@ -9797,7 +9846,14 @@ int DigField(struct PlayerInfo *player,
                                          player->index_bit, dig_side);
 
     if (mode == DF_SNAP)
+    {
       TestIfElementTouchesCustomElement(x, y); /* for empty space */
+
+#if USE_NEW_SNAP_DELAY
+      if (level.block_snap_field)
+       setFieldForSnapping(x, y, element, move_direction);
+#endif
+    }
   }
   else if (IS_PUSHABLE(element))
   {
index fbe001f882c98dd2a3b02fb29ba883dd145eb9dc..b7f19e0def3beaf09257ce571a18186776e3f18b 100644 (file)
@@ -3968,6 +3968,11 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "-",
     "-"
   },
+  {
+    "element.snapping",
+    "-",
+    "-"
+  },
 
   /* ----------------------------------------------------------------------- */
   /* dummy elements (never used as game elements, only used as graphics)     */
index 59b935f5113f9245bd42598f273c23b3f2b95fd3..a81463570ac250930fc57a2581903142c80a6032 100644 (file)
 #define EL_QUICKSAND_FILLING           (EL_FIRST_RUNTIME_UNREAL + 15)
 #define EL_MAGIC_WALL_FILLING          (EL_FIRST_RUNTIME_UNREAL + 16)
 #define EL_BD_MAGIC_WALL_FILLING       (EL_FIRST_RUNTIME_UNREAL + 17)
+#define EL_ELEMENT_SNAPPING            (EL_FIRST_RUNTIME_UNREAL + 18)
 
 /* dummy elements (never used as game elements, only used as graphics) */
-#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 18)
+#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 19)
 
 #define EL_STEELWALL_TOPLEFT           (EL_FIRST_DUMMY + 0)
 #define EL_STEELWALL_TOPRIGHT          (EL_FIRST_DUMMY + 1)
@@ -1804,6 +1805,7 @@ struct LevelInfo
   boolean can_pass_to_walkable;        /* player can pass to empty or walkable tile */
   boolean grow_into_diggable;  /* amoeba can grow into anything diggable */
 
+  boolean block_snap_field;    /* snapping blocks field to show animation */
   boolean block_last_field;    /* player blocks previous field while moving */
   boolean sp_block_last_field; /* player blocks previous field while moving */
 
index e630cd18f7654c51546de9d6de66d5f33fdac2b1..a2797839332a92db3510b692b4ddb87f35dae408 100644 (file)
@@ -976,6 +976,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
          IS_MOVING(xx, yy))
        continue;
 
+#if 1
+      if (Feld[xx][yy] == EL_ELEMENT_SNAPPING)
+       continue;
+#endif
+
       element = TILE_GFX_ELEMENT(xx, yy);
 
       if (!GFX_CRUMBLED(element))
@@ -988,7 +993,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
        continue;
 #endif
 
+#if 1
+      graphic = el_act2crm(element, ACTION_DEFAULT);
+#else
       graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT);
+#endif
       crumbled_border_size = graphic_info[graphic].border_size;
 
       getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
@@ -1023,7 +1032,20 @@ void DrawLevelFieldCrumbledSand(int x, int y)
   if (!IN_LEV_FIELD(x, y))
     return;
 
+#if 1
+  if (Feld[x][y] == EL_ELEMENT_SNAPPING &&
+      GFX_CRUMBLED(GfxElement[x][y]))
+  {
+    DrawLevelFieldCrumbledSandDigging(x, y, GfxDir[x][y], GfxFrame[x][y]);
+    return;
+  }
+#endif
+
+#if 1
+  graphic = el_act2crm(TILE_GFX_ELEMENT(x, y), ACTION_DEFAULT);
+#else
   graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT);
+#endif
 
   DrawLevelFieldCrumbledSandExt(x, y, graphic, 0);
 }
@@ -1698,8 +1720,13 @@ inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
 
   DrawGraphicAnimation(sx, sy, graphic);
 
+#if 1
+  if (GFX_CRUMBLED(TILE_GFX_ELEMENT(x, y)))
+    DrawLevelFieldCrumbledSand(x, y);
+#else
   if (GFX_CRUMBLED(Feld[x][y]))
     DrawLevelFieldCrumbledSand(x, y);
+#endif
 }
 
 void DrawLevelElementAnimationIfNeeded(int x, int y, int element)