rnd-20051215-1-src
authorHolger Schemel <info@artsoft.org>
Thu, 15 Dec 2005 00:19:04 +0000 (01:19 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:49:52 +0000 (10:49 +0200)
* added missing configuration settings for the following elements:
  - EL_TIMEGATE_SWITCH (time of open time gate)
  - EL_LIGHT_SWITCH_ACTIVE (time of light switched on)
  - EL_SHIELD_NORMAL (time of shield duration)
  - EL_SHIELD_DEADLY (time of shield duration)
  - EL_EXTRA_TIME (time added to level time)
  - EL_TIME_ORB_FULL (time added to level time)
* added "wind direction" as a movement pattern for custom elements
* added initial wind direction for balloon / custom elements to editor
* added functionality for EL_BALLOON_SWITCH_NONE to R'n'D game engine

13 files changed:
ChangeLog
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/game_em/convert.c
src/init.c
src/libgame/misc.c
src/libgame/system.h
src/libgame/toons.c
src/main.c
src/main.h
src/tools.c

index 7034922c1adf1df56f4b911dd8d157bd92829df3..542dc114718e06e6b3f0b9b81f92d321d2a939a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
+2005-12-15
+       * added missing configuration settings for the following elements:
+         - EL_TIMEGATE_SWITCH          (time of open time gate)
+         - EL_LIGHT_SWITCH_ACTIVE      (time of light switched on)
+         - EL_SHIELD_NORMAL            (time of shield duration)
+         - EL_SHIELD_DEADLY            (time of shield duration)
+         - EL_EXTRA_TIME               (time added to level time)
+         - EL_TIME_ORB_FULL            (time added to level time)
+
+2005-12-14
+       * added "wind direction" as a movement pattern for custom elements
+       * added initial wind direction for balloon / custom elements to editor
+       * added functionality for EL_BALLOON_SWITCH_NONE to R'n'D game engine
+
 2005-12-13
-       * added parameters to editor for "game of life" and "biomaze" elements
+       * added parameters for "game of life" and "biomaze" elements to editor
 
 2005-12-12
        * added level file chunk "CONF" for generic level and element settings
index 51f3c558127625946fb62fcafb7697f38fa162e1..2b2874acfc4ada143be732203e9b2c1c415fff3c 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2005-12-14 02:22]"
+#define COMPILE_DATE_STRING "[2005-12-15 01:12]"
index 020b1ca690c6ee10d31bcbc2f165ff01f3e1a943..79e58746897bf9b2a7030df0e2e8b4db032c44e6 100644 (file)
 
 #define GADGET_ID_TIME_OR_STEPS                (GADGET_ID_SELECTBOX_FIRST + 0)
 #define GADGET_ID_GAME_ENGINE_TYPE     (GADGET_ID_SELECTBOX_FIRST + 1)
-#define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 2)
-#define GADGET_ID_CUSTOM_EXPLOSION_TYPE        (GADGET_ID_SELECTBOX_FIRST + 3)
-#define GADGET_ID_CUSTOM_DEADLINESS    (GADGET_ID_SELECTBOX_FIRST + 4)
-#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 5)
-#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 6)
-#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 7)
-#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 8)
-#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 9)
-#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 10)
-#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 11)
-#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 12)
-#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 13)
-#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 14)
-#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 15)
-#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 16)
-#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 17)
-#define GADGET_ID_CHANGE_SIDE          (GADGET_ID_SELECTBOX_FIRST + 18)
-#define GADGET_ID_CHANGE_PLAYER                (GADGET_ID_SELECTBOX_FIRST + 19)
-#define GADGET_ID_CHANGE_PAGE          (GADGET_ID_SELECTBOX_FIRST + 20)
-#define GADGET_ID_CHANGE_REPLACE_WHEN  (GADGET_ID_SELECTBOX_FIRST + 21)
-#define GADGET_ID_ACTION_TYPE          (GADGET_ID_SELECTBOX_FIRST + 22)
-#define GADGET_ID_ACTION_MODE          (GADGET_ID_SELECTBOX_FIRST + 23)
-#define GADGET_ID_ACTION_ARG           (GADGET_ID_SELECTBOX_FIRST + 24)
-#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 25)
-#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 26)
+#define GADGET_ID_WIND_DIRECTION       (GADGET_ID_SELECTBOX_FIRST + 2)
+#define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 3)
+#define GADGET_ID_CUSTOM_EXPLOSION_TYPE        (GADGET_ID_SELECTBOX_FIRST + 4)
+#define GADGET_ID_CUSTOM_DEADLINESS    (GADGET_ID_SELECTBOX_FIRST + 5)
+#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 6)
+#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 7)
+#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 8)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 9)
+#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 10)
+#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 11)
+#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 16)
+#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 17)
+#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 18)
+#define GADGET_ID_CHANGE_SIDE          (GADGET_ID_SELECTBOX_FIRST + 19)
+#define GADGET_ID_CHANGE_PLAYER                (GADGET_ID_SELECTBOX_FIRST + 20)
+#define GADGET_ID_CHANGE_PAGE          (GADGET_ID_SELECTBOX_FIRST + 21)
+#define GADGET_ID_CHANGE_REPLACE_WHEN  (GADGET_ID_SELECTBOX_FIRST + 22)
+#define GADGET_ID_ACTION_TYPE          (GADGET_ID_SELECTBOX_FIRST + 23)
+#define GADGET_ID_ACTION_MODE          (GADGET_ID_SELECTBOX_FIRST + 24)
+#define GADGET_ID_ACTION_ARG           (GADGET_ID_SELECTBOX_FIRST + 25)
+#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 26)
+#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 27)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 27)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 28)
 
 #define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 0)
 #define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 1)
 /* values for selectbox gadgets */
 #define ED_SELECTBOX_ID_TIME_OR_STEPS          0
 #define ED_SELECTBOX_ID_GAME_ENGINE_TYPE       1
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE     2
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER    3
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED        4
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION        5
-#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  6
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    7
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  8
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   9
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 10
-#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   11
-#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   12
-#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      13
-#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE  14
-#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      15
-#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   16
-#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    17
-#define ED_SELECTBOX_ID_CHANGE_SIDE            18
-#define ED_SELECTBOX_ID_CHANGE_PLAYER          19
-#define ED_SELECTBOX_ID_CHANGE_PAGE            20
-#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN    21
-#define ED_SELECTBOX_ID_ACTION_TYPE            22
-#define ED_SELECTBOX_ID_ACTION_MODE            23
-#define ED_SELECTBOX_ID_ACTION_ARG             24
-#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     25
-#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      26
-
-#define ED_NUM_SELECTBOX                       27
+#define ED_SELECTBOX_ID_WIND_DIRECTION         2
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE     3
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER    4
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED        5
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION        6
+#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  7
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    8
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  9
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   10
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 11
+#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   12
+#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   13
+#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      14
+#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE  15
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      16
+#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   17
+#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    18
+#define ED_SELECTBOX_ID_CHANGE_SIDE            19
+#define ED_SELECTBOX_ID_CHANGE_PLAYER          20
+#define ED_SELECTBOX_ID_CHANGE_PAGE            21
+#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN    22
+#define ED_SELECTBOX_ID_ACTION_TYPE            23
+#define ED_SELECTBOX_ID_ACTION_MODE            24
+#define ED_SELECTBOX_ID_ACTION_ARG             25
+#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     26
+#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      27
+
+#define ED_NUM_SELECTBOX                       28
 
 #define ED_SELECTBOX_ID_LEVEL_FIRST    ED_SELECTBOX_ID_TIME_OR_STEPS
-#define ED_SELECTBOX_ID_LEVEL_LAST     ED_SELECTBOX_ID_GAME_ENGINE_TYPE
+#define ED_SELECTBOX_ID_LEVEL_LAST     ED_SELECTBOX_ID_WIND_DIRECTION
 
 #define ED_SELECTBOX_ID_CUSTOM1_FIRST  ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
 #define ED_SELECTBOX_ID_CUSTOM1_LAST   ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION
@@ -1264,6 +1266,17 @@ static struct ValueTextInfo options_game_engine_type[] =
   { -1,                                NULL                            }
 };
 
+static struct ValueTextInfo options_wind_direction[] =
+{
+  { MV_START_NONE,             "none"                          },
+  { MV_START_LEFT,             "left"                          },
+  { MV_START_RIGHT,            "right"                         },
+  { MV_START_UP,               "up"                            },
+  { MV_START_DOWN,             "down"                          },
+
+  { -1,                                NULL                            }
+};
+
 static struct ValueTextInfo options_access_type[] =
 {
   { EP_WALKABLE,               "walkable"                      },
@@ -1291,7 +1304,7 @@ static struct ValueTextInfo options_access_protected[] =
 
 static struct ValueTextInfo options_access_direction[] =
 {
-  { MV_NO_DIRECTIONS,          "no direction"                  },
+  { MV_NO_DIRECTION          "no direction"                  },
   { MV_LEFT,                   "left"                          },
   { MV_RIGHT,                  "right"                         },
   { MV_UP,                     "up"                            },
@@ -1331,6 +1344,7 @@ static struct ValueTextInfo options_move_pattern[] =
   { MV_HORIZONTAL,             "horizontal"                    },
   { MV_VERTICAL,               "vertical"                      },
   { MV_ALL_DIRECTIONS,         "all directions"                },
+  { MV_WIND_DIRECTION,         "wind direction"                },
   { MV_TOWARDS_PLAYER,         "towards player"                },
   { MV_AWAY_FROM_PLAYER,       "away from player"              },
   { MV_ALONG_LEFT_SIDE,                "along left side"               },
@@ -1669,8 +1683,18 @@ static struct
     &level.game_engine_type,
     "game engine:", NULL,              "game engine"
   },
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(12),
+    GADGET_ID_WIND_DIRECTION,          GADGET_ID_NONE,
+    -1,
+    options_wind_direction,
+    &level.wind_direction_initial,
+    "initial wind direction:", NULL,   "initial wind direction"
+  },
 
-  /* ---------- element settings: configure 1 (custom elements) ----------- */
+  /* ---------- element settings: configure (several elements) ------------- */
+
+  /* ---------- element settings: configure 1 (custom elements) ------------ */
 
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(3),
@@ -1713,7 +1737,7 @@ static struct
     NULL, NULL,                                "diggable/collectible/pushable"
   },
 
-  /* ---------- element settings: configure 2 (custom elements) ----------- */
+  /* ---------- element settings: configure 2 (custom elements) ------------ */
 
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(1),
@@ -2606,7 +2630,7 @@ static int new_element3 = EL_SAND;
 #define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : (button) == 2 ? 5 : 10)
 
 /* forward declaration for internal use */
-static void ModifyEditorCounter(int, int);
+static void ModifyEditorCounterValue(int, int);
 static void ModifyEditorCounterLimits(int, int, int);
 static void ModifyEditorSelectbox(int, int);
 static void ModifyEditorDrawingArea(int, int, int);
@@ -5285,6 +5309,12 @@ static void MapCounterButtons(int id)
   int x = gi_down->x;
   int y;       /* set after gadget position was modified */
 
+  /* counter limits must be changed first to prevent value truncation */
+  ModifyEditorCounterLimits(id, counterbutton_info[id].min_value,
+                           counterbutton_info[id].max_value);
+
+  ModifyEditorCounterValue(id, *counterbutton_info[id].value);
+
   /* set position for "value[1,2,3,4]" counter gadgets (score in most cases) */
   if (id >= ED_COUNTER_ID_ELEMENT_VALUE1 &&
       id <= ED_COUNTER_ID_ELEMENT_VALUE4)
@@ -5305,9 +5335,6 @@ static void MapCounterButtons(int id)
   if (counterbutton_info[id].text_right)
     DrawText(x_right, y, counterbutton_info[id].text_right, FONT_TEXT_1);
 
-  ModifyEditorCounter(id, *counterbutton_info[id].value);
-  ModifyEditorCounterLimits(id, counterbutton_info[id].min_value,
-                           counterbutton_info[id].max_value);
   MapGadget(gi_down);
   MapGadget(gi_text);
   MapGadget(gi_up);
@@ -6358,7 +6385,7 @@ static void AdjustEditorScrollbar(int id)
               GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END);
 }
 
-static void ModifyEditorCounter(int counter_id, int new_value)
+static void ModifyEditorCounterValue(int counter_id, int new_value)
 {
   int *counter_value = counterbutton_info[counter_id].value;
   int gadget_id = counterbutton_info[counter_id].gadget_id_text;
@@ -6880,6 +6907,7 @@ static void DrawPropertiesInfo()
 #define TEXT_GAME_OF_LIFE_2    "Max neighbours to survive"
 #define TEXT_GAME_OF_LIFE_3    "Min neighbours to create"
 #define TEXT_GAME_OF_LIFE_4    "Max neighbours to create"
+#define TEXT_TIME_BONUS                "Extra time to solve level"
 
 static struct
 {
@@ -6952,9 +6980,16 @@ static struct
   { EL_AMOEBA_FULL,    &level.amoeba_speed,            TEXT_AMOEBA_SPEED },
   { EL_BD_AMOEBA,      &level.amoeba_speed,            TEXT_AMOEBA_SPEED },
   { EL_MAGIC_WALL,     &level.time_magic_wall,         TEXT_DURATION   },
+  { EL_BD_MAGIC_WALL,  &level.time_magic_wall,         TEXT_DURATION   },
   { EL_ROBOT_WHEEL,    &level.time_wheel,              TEXT_DURATION   },
 
 #if 1
+  { EL_TIMEGATE_SWITCH,        &level.time_timegate,           TEXT_DURATION   },
+  { EL_LIGHT_SWITCH_ACTIVE, &level.time_light,         TEXT_DURATION   },
+  { EL_SHIELD_NORMAL,  &level.shield_normal_time,      TEXT_DURATION   },
+  { EL_SHIELD_DEADLY,  &level.shield_deadly_time,      TEXT_DURATION   },
+  { EL_EXTRA_TIME,     &level.extra_time,              TEXT_TIME_BONUS },
+  { EL_TIME_ORB_FULL,  &level.time_orb_time,           TEXT_TIME_BONUS },
   { EL_GAME_OF_LIFE,   &level.game_of_life[0],         TEXT_GAME_OF_LIFE_1 },
   { EL_GAME_OF_LIFE,   &level.game_of_life[1],         TEXT_GAME_OF_LIFE_2 },
   { EL_GAME_OF_LIFE,   &level.game_of_life[2],         TEXT_GAME_OF_LIFE_3 },
@@ -7101,6 +7136,11 @@ static void DrawPropertiesConfig()
   if (properties_element == EL_SPRING)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG);
 
+#if 0
+  if (properties_element == EL_BALLOON)
+    MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION);
+#endif
+
   if (CAN_GROW(properties_element))
   {
     checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y =
@@ -8385,7 +8425,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi)
                                  REQ_ASK))
     {
       if (gadget_id == counterbutton_info[counter_id].gadget_id_text)
-       ModifyEditorCounter(counter_id, *counter_value);
+       ModifyEditorCounterValue(counter_id, *counter_value);
 
       return;
     }
@@ -8394,7 +8434,7 @@ static void HandleCounterButtons(struct GadgetInfo *gi)
   if (gadget_id == counterbutton_info[counter_id].gadget_id_text)
     *counter_value = gi->textinput.number_value;
   else
-    ModifyEditorCounter(counter_id, *counter_value + step);
+    ModifyEditorCounterValue(counter_id, *counter_value + step);
 
   if (counter_id == ED_COUNTER_ID_SELECT_LEVEL)
   {
index 447ebc71cfde81ee1330868e84fa262a4f9623e4..121fdf133424bb1bcfb6720e5bc8a65b1a699b36 100644 (file)
@@ -103,30 +103,113 @@ static struct
   int element;
   int type;
   void *value;
+  int default_value;
 } element_conf[] =
 {
-  /* 1-byte values */
-  { EL_EMC_ANDROID,    CONF_VALUE_INTEGER_1,   &li.android_move_time   },
-  { EL_EMC_ANDROID,    CONF_VALUE_INTEGER_2,   &li.android_clone_time  },
-  { EL_EMC_MAGIC_BALL, CONF_VALUE_INTEGER_1,   &li.ball_time           },
-  { EL_EMC_LENSES,     CONF_VALUE_INTEGER_1,   &li.lenses_score        },
-  { EL_EMC_LENSES,     CONF_VALUE_INTEGER_2,   &li.lenses_time         },
-  { EL_EMC_MAGNIFIER,  CONF_VALUE_INTEGER_1,   &li.magnify_score       },
-  { EL_EMC_MAGNIFIER,  CONF_VALUE_INTEGER_2,   &li.magnify_time        },
-  { EL_ROBOT,          CONF_VALUE_INTEGER_1,   &li.slurp_score         },
-  { EL_GAME_OF_LIFE,   CONF_VALUE_INTEGER_1,   &li.game_of_life[0]     },
-  { EL_GAME_OF_LIFE,   CONF_VALUE_INTEGER_2,   &li.game_of_life[1]     },
-  { EL_GAME_OF_LIFE,   CONF_VALUE_INTEGER_3,   &li.game_of_life[2]     },
-  { EL_GAME_OF_LIFE,   CONF_VALUE_INTEGER_4,   &li.game_of_life[3]     },
-  { EL_BIOMAZE,                CONF_VALUE_INTEGER_1,   &li.biomaze[0]          },
-  { EL_BIOMAZE,                CONF_VALUE_INTEGER_2,   &li.biomaze[1]          },
-  { EL_BIOMAZE,                CONF_VALUE_INTEGER_3,   &li.biomaze[2]          },
-  { EL_BIOMAZE,                CONF_VALUE_INTEGER_4,   &li.biomaze[3]          },
-
-  /* multi-byte values */
-  { EL_EMC_MAGIC_BALL, CONF_VALUE_CONTENT_8,   &li.ball_content        },
-
-  { -1,                        -1,                     NULL                    },
+  /* ---------- 1-byte values ---------------------------------------------- */
+  {
+    EL_EMC_ANDROID,                    CONF_VALUE_INTEGER_1,
+    &li.android_move_time,             10
+  },
+  {
+    EL_EMC_ANDROID,                    CONF_VALUE_INTEGER_2,
+    &li.android_clone_time,            10
+  },
+  {
+    EL_EMC_MAGIC_BALL,                 CONF_VALUE_INTEGER_1,
+    &li.ball_time,                     10
+  },
+  {
+    EL_EMC_LENSES,                     CONF_VALUE_INTEGER_1,
+    &li.lenses_score,                  10
+  },
+  {
+    EL_EMC_LENSES,                     CONF_VALUE_INTEGER_2,
+    &li.lenses_time,                   10
+  },
+  {
+    EL_EMC_MAGNIFIER,                  CONF_VALUE_INTEGER_1,
+    &li.magnify_score,                 10
+  },
+  {
+    EL_EMC_MAGNIFIER,                  CONF_VALUE_INTEGER_2,
+    &li.magnify_time,                  10
+  },
+  {
+    EL_ROBOT,                          CONF_VALUE_INTEGER_1,
+    &li.slurp_score,                   10
+  },
+  {
+    EL_GAME_OF_LIFE,                   CONF_VALUE_INTEGER_1,
+    &li.game_of_life[0],               2
+  },
+  {
+    EL_GAME_OF_LIFE,                   CONF_VALUE_INTEGER_2,
+    &li.game_of_life[1],               3
+  },
+  {
+    EL_GAME_OF_LIFE,                   CONF_VALUE_INTEGER_3,
+    &li.game_of_life[2],               3
+  },
+  {
+    EL_GAME_OF_LIFE,                   CONF_VALUE_INTEGER_4,
+    &li.game_of_life[3],               3
+  },
+  {
+    EL_BIOMAZE,                                CONF_VALUE_INTEGER_1,
+    &li.biomaze[0],                    2
+  },
+  {
+    EL_BIOMAZE,                                CONF_VALUE_INTEGER_2,
+    &li.biomaze[1],                    3
+  },
+  {
+    EL_BIOMAZE,                                CONF_VALUE_INTEGER_3,
+    &li.biomaze[2],                    3
+  },
+  {
+    EL_BIOMAZE,                                CONF_VALUE_INTEGER_4,
+    &li.biomaze[3],                    3
+  },
+  {
+    EL_BALLOON,                                CONF_VALUE_INTEGER_1,
+    &li.wind_direction_initial,                MV_NONE
+  },
+  {
+    EL_TIMEGATE_SWITCH,                        CONF_VALUE_INTEGER_1,
+    &li.time_timegate,                 10
+  },
+  {
+    EL_LIGHT_SWITCH_ACTIVE,            CONF_VALUE_INTEGER_1,
+    &li.time_light,                    10
+  },
+  {
+    EL_SHIELD_NORMAL,                  CONF_VALUE_INTEGER_1,
+    &li.shield_normal_time,            10
+  },
+  {
+    EL_SHIELD_DEADLY,                  CONF_VALUE_INTEGER_1,
+    &li.shield_deadly_time,            10
+  },
+  {
+    EL_EXTRA_TIME,                     CONF_VALUE_INTEGER_1,
+    &li.extra_time,                    10
+  },
+  {
+    EL_TIME_ORB_FULL,                  CONF_VALUE_INTEGER_1,
+    &li.time_orb_time,                 10
+  },
+
+  /* ---------- multi-byte values ------------------------------------------ */
+  {
+    EL_EMC_MAGIC_BALL,                 CONF_VALUE_CONTENT_8,
+    &li.ball_content,                  EL_EMPTY
+  },
+
+  {
+    -1,                                        -1,
+    NULL,                              -1
+  },
 };
 
 static struct
@@ -151,6 +234,40 @@ filetype_id_list[] =
 /* level file functions                                                      */
 /* ========================================================================= */
 
+static void setLevelInfoToDefaultsFromConfigList(struct LevelInfo *level)
+{
+  int i;
+
+  li = *level;         /* copy level information into temporary buffer */
+
+  for (i = 0; element_conf[i].element != -1; i++)
+  {
+    int default_value = element_conf[i].default_value;
+    int type = element_conf[i].type;
+    int bytes = type & CONF_MASK_BYTES;
+
+    if (bytes != CONF_MASK_MULTI_BYTES)
+    {
+      if (CONF_VALUE_BOOLEAN(type))
+       *(boolean *)(element_conf[i].value) = default_value;
+      else
+       *(int *)    (element_conf[i].value) = default_value;
+    }
+    else if (type == CONF_VALUE_CONTENT_8)
+    {
+      struct Content *content = (struct Content *)(element_conf[i].value);
+      int c, x, y;
+
+      for (c = 0; c < MAX_ELEMENT_CONTENTS; c++)
+       for (y = 0; y < 3; y++)
+         for (x = 0; x < 3; x++)
+           content[c].e[x][y] = default_value;
+    }
+  }
+
+  *level = li;         /* copy temporary buffer back to level information */
+}
+
 void setElementChangePages(struct ElementInfo *ei, int change_pages)
 {
   int change_page_size = sizeof(struct ElementChangeInfo);
@@ -216,6 +333,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
   static boolean clipboard_elements_initialized = FALSE;
   int i, j, x, y;
 
+  setLevelInfoToDefaultsFromConfigList(level);
   setLevelInfoToDefaults_EM();
 
   level->native_em_level = &native_em_level;
@@ -243,8 +361,10 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
 
   level->time_magic_wall = 10;
   level->time_wheel = 10;
+#if 0
   level->time_light = 10;
   level->time_timegate = 10;
+#endif
 
   level->amoeba_content = EL_DIAMOND;
 
@@ -275,21 +395,25 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
   level->use_step_counter = FALSE;
 
   /* values for the new EMC elements */
+#if 0
   level->android_move_time = 10;
   level->android_clone_time = 10;
-  level->ball_random = FALSE;
-  level->ball_state_initial = FALSE;
   level->ball_time = 10;
   level->lenses_score = 10;
-  level->magnify_score = 10;
-  level->slurp_score = 10;
   level->lenses_time = 10;
+  level->magnify_score = 10;
   level->magnify_time = 10;
-  level->wind_direction_initial = MV_NO_MOVING;
+  level->slurp_score = 10;
+  level->wind_direction_initial = MV_NONE;
+#endif
+  level->ball_random = FALSE;
+  level->ball_state_initial = FALSE;
+#if 0
   for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
     for (x = 0; x < 3; x++)
       for (y = 0; y < 3; y++)
        level->ball_content[i].e[x][y] = EL_EMPTY;
+#endif
   for (i = 0; i < 16; i++)
     level->android_array[i] = FALSE;
 
@@ -2793,7 +2917,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
       int element = EL_CUSTOM_START + i;
       struct ElementInfo *ei = &element_info[element];
 
-      if (ei->access_direction == MV_NO_DIRECTIONS)
+      if (ei->access_direction == MV_NO_DIRECTION)
        ei->access_direction = MV_ALL_DIRECTIONS;
 
 #if 0
@@ -3373,13 +3497,27 @@ static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element)
     putFile16BitBE(file, group->element[i]);
 }
 
-static int SaveLevel_CONF_Value(FILE *file, int element, int type, int value)
+static int SaveLevel_CONF_Value(FILE *file, int pos)
 {
+  int default_value = element_conf[pos].default_value;
+  int element = element_conf[pos].element;
+  int type = element_conf[pos].type;
   int bytes = type & CONF_MASK_BYTES;
+  void *value_ptr = element_conf[pos].value;
+  int value = (CONF_VALUE_BOOLEAN(type) ? *(boolean *)value_ptr :
+              *(int *)value_ptr);
   int num_bytes = 0;
+  boolean modified = FALSE;
+
+  /* check if any settings have been modified before saving them */
+  if (value != default_value)
+    modified = TRUE;
+
+  if (!modified)               /* do not save unmodified default settings */
+    return 0;
 
   if (bytes == CONF_MASK_MULTI_BYTES)
-    Error(ERR_EXIT, "SaveLevel_CONF_INT: invalid type CONF_MASK_MULTI_BYTES");
+    Error(ERR_EXIT, "SaveLevel_CONF_Value: cannot save multi-byte values");
 
   num_bytes += putFile16BitBE(file, element);
   num_bytes += putFile8Bit(file, type);
@@ -3390,12 +3528,26 @@ static int SaveLevel_CONF_Value(FILE *file, int element, int type, int value)
   return num_bytes;
 }
 
-static int SaveLevel_CONF_Content(FILE *file, int element, int type,
-                                 struct Content *content, int num_contents)
+static int SaveLevel_CONF_Content(FILE *file, int pos, int num_contents)
 {
+  struct Content *content = (struct Content *)(element_conf[pos].value);
+  int default_value = element_conf[pos].default_value;
+  int element = element_conf[pos].element;
+  int type = element_conf[pos].type;
   int num_bytes = 0;
+  boolean modified = FALSE;
   int i, x, y;
 
+  /* check if any settings have been modified before saving them */
+  for (i = 0; i < num_contents; i++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
+       if (content[i].e[x][y] != default_value)
+         modified = TRUE;
+
+  if (!modified)               /* do not save unmodified default settings */
+    return 0;
+
   num_bytes += putFile16BitBE(file, element);
   num_bytes += putFile8Bit(file, type);
   num_bytes += putFile16BitBE(file, num_contents * CONF_CONTENT_NUM_BYTES);
@@ -3417,30 +3569,13 @@ static int SaveLevel_CONF(FILE *file, struct LevelInfo *level)
 
   for (i = 0; element_conf[i].element != -1; i++)
   {
-    int element = element_conf[i].element;
-    int type    = element_conf[i].type;
-    void *value = element_conf[i].value;
+    int type = element_conf[i].type;
     int bytes = type & CONF_MASK_BYTES;
 
-    if (bytes == CONF_MASK_MULTI_BYTES)
-    {
-      if (type == CONF_VALUE_CONTENT_8)
-      {
-       struct Content *content = (struct Content *)value;
-
-       chunk_size += SaveLevel_CONF_Content(file, element, type,
-                                            content, MAX_ELEMENT_CONTENTS);
-      }
-      else
-       Error(ERR_WARN, "cannot save CONF value for element %d", element);
-    }
-    else
-    {
-      int value_int = (CONF_VALUE_BOOLEAN(type) ? *(boolean *)value :
-                      *(int *)value);
-
-      chunk_size += SaveLevel_CONF_Value(file, element, type, value_int);
-    }
+    if (bytes != CONF_MASK_MULTI_BYTES)
+      chunk_size += SaveLevel_CONF_Value(file, i);
+    else if (type == CONF_VALUE_CONTENT_8)
+      chunk_size += SaveLevel_CONF_Content(file, i, MAX_ELEMENT_CONTENTS);
   }
 
   return chunk_size;
@@ -3559,8 +3694,12 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
 
   conf_chunk_size = SaveLevel_CONF(NULL, level);       /* get chunk size */
 
-  putFileChunkBE(file, "CONF", conf_chunk_size);
-  SaveLevel_CONF(file, level);
+  /* check for non-default configuration settings to be saved in CONF chunk */
+  if (conf_chunk_size > 0)
+  {
+    putFileChunkBE(file, "CONF", conf_chunk_size);
+    SaveLevel_CONF(file, level);
+  }
 
   fclose(file);
 
@@ -3738,7 +3877,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
 
     for (j = 0; j < MAX_PLAYERS; j++)
     {
-      tape->pos[i].action[j] = MV_NO_MOVING;
+      tape->pos[i].action[j] = MV_NONE;
 
       if (tape->player_participates[j])
        tape->pos[i].action[j] = getFile8Bit(file);
@@ -3785,7 +3924,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
 
        /* delay part */
        for (j = 0; j < MAX_PLAYERS; j++)
-         tape->pos[i].action[j] = MV_NO_MOVING;
+         tape->pos[i].action[j] = MV_NONE;
        tape->pos[i].delay--;
 
        i++;
index 7f6186c4f58130a519c16626ca5306ae9dc338b8..84de452cf1c42ca76d7f62e876168529a29f4ad0 100644 (file)
@@ -582,7 +582,7 @@ access_direction_list[] =
   { EL_SP_GRAVITY_OFF_PORT_UP,                                      MV_DOWN },
   { EL_SP_GRAVITY_OFF_PORT_DOWN,                            MV_UP           },
 
-  { EL_UNDEFINED,                      MV_NO_MOVING                         }
+  { EL_UNDEFINED,                      MV_NONE                              }
 };
 
 static boolean trigger_events[MAX_NUM_ELEMENTS][NUM_CHANGE_EVENTS];
@@ -657,7 +657,7 @@ static int getBeltDirFromBeltSwitchElement(int element)
   static int belt_move_dir[3] =
   {
     MV_LEFT,
-    MV_NO_MOVING,
+    MV_NONE,
     MV_RIGHT
   };
 
@@ -1498,10 +1498,10 @@ void InitGame()
     player->dynabombs_left = 0;
     player->dynabomb_xl = FALSE;
 
-    player->MovDir = MV_NO_MOVING;
+    player->MovDir = MV_NONE;
     player->MovPos = 0;
     player->GfxPos = 0;
-    player->GfxDir = MV_NO_MOVING;
+    player->GfxDir = MV_NONE;
     player->GfxAction = ACTION_DEFAULT;
     player->Frame = 0;
     player->StepFrame = 0;
@@ -1517,7 +1517,7 @@ void InitGame()
 
     player->step_counter = 0;
 
-    player->last_move_dir = MV_NO_MOVING;
+    player->last_move_dir = MV_NONE;
 
     player->is_waiting = FALSE;
     player->is_moving = FALSE;
@@ -1617,7 +1617,7 @@ void InitGame()
 #if defined(NETWORK_AVALIABLE)
   /* initial null action */
   if (network_playing)
-    SendToServer_MovePlayer(MV_NO_MOVING);
+    SendToServer_MovePlayer(MV_NONE);
 #endif
 
   ZX = ZY = -1;
@@ -1629,7 +1629,7 @@ void InitGame()
   TimeLeft = level.time;
   TapeTime = 0;
 
-  ScreenMovDir = MV_NO_MOVING;
+  ScreenMovDir = MV_NONE;
   ScreenMovPos = 0;
   ScreenGfxPos = 0;
 
@@ -1643,7 +1643,7 @@ void InitGame()
   game.light_time_left = 0;
   game.timegate_time_left = 0;
   game.switchgate_pos = 0;
-  game.balloon_dir = MV_NO_MOVING;
+  game.wind_direction = level.wind_direction_initial;
   game.gravity = level.initial_gravity;
   game.explosions_delayed = TRUE;
 
@@ -1651,7 +1651,7 @@ void InitGame()
 
   for (i = 0; i < NUM_BELTS; i++)
   {
-    game.belt_dir[i] = MV_NO_MOVING;
+    game.belt_dir[i] = MV_NONE;
     game.belt_dir_nr[i] = 3;           /* not moving, next moving left */
   }
 
@@ -1691,7 +1691,7 @@ void InitGame()
       GfxRandom[x][y] = INIT_GFX_RANDOM();
       GfxElement[x][y] = EL_UNDEFINED;
       GfxAction[x][y] = ACTION_DEFAULT;
-      GfxDir[x][y] = MV_NO_MOVING;
+      GfxDir[x][y] = MV_NONE;
     }
   }
 
@@ -1766,7 +1766,7 @@ void InitGame()
 
   /* correct non-moving belts to start moving left */
   for (i = 0; i < NUM_BELTS; i++)
-    if (game.belt_dir[i] == MV_NO_MOVING)
+    if (game.belt_dir[i] == MV_NONE)
       game.belt_dir_nr[i] = 3;         /* not moving, next moving left */
 
   /* check if any connected player was not found in playfield */
@@ -2147,7 +2147,7 @@ void InitMovDir(int x, int y)
 
        if (move_direction_initial == MV_START_PREVIOUS)
        {
-         if (MovDir[x][y] != MV_NO_MOVING)
+         if (MovDir[x][y] != MV_NONE)
            return;
 
          move_direction_initial = MV_START_AUTOMATIC;
@@ -2634,7 +2634,7 @@ static void RemoveField(int x, int y)
 
   GfxElement[x][y] = EL_UNDEFINED;
   GfxAction[x][y] = ACTION_DEFAULT;
-  GfxDir[x][y] = MV_NO_MOVING;
+  GfxDir[x][y] = MV_NONE;
 }
 
 void RemoveMovingField(int x, int y)
@@ -3205,7 +3205,7 @@ void Explode(int ex, int ey, int phase, int mode)
     Back[x][y] = 0;
 
     MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
-    GfxDir[x][y] = MV_NO_MOVING;
+    GfxDir[x][y] = MV_NONE;
     ChangeDelay[x][y] = 0;
     ChangePage[x][y] = -1;
 
@@ -3418,7 +3418,7 @@ static void InitBeltMovement()
 
       for (i = 0; i < NUM_BELTS; i++)
       {
-       if (IS_BELT(element) && game.belt_dir[i] != MV_NO_MOVING)
+       if (IS_BELT(element) && game.belt_dir[i] != MV_NONE)
        {
          int e_belt_nr = getBeltNrFromBeltElement(element);
          int belt_nr = i;
@@ -3461,9 +3461,9 @@ static void ToggleBeltSwitch(int x, int y)
   static int belt_move_dir[4] =
   {
     MV_LEFT,
-    MV_NO_MOVING,
+    MV_NONE,
     MV_RIGHT,
-    MV_NO_MOVING,
+    MV_NONE,
   };
 
   int element = Feld[x][y];
@@ -3509,7 +3509,7 @@ static void ToggleBeltSwitch(int x, int y)
          DrawLevelField(xx, yy);
        }
       }
-      else if (IS_BELT(element) && belt_dir != MV_NO_MOVING)
+      else if (IS_BELT(element) && belt_dir != MV_NONE)
       {
        int e_belt_nr = getBeltNrFromBeltElement(element);
 
@@ -3521,7 +3521,7 @@ static void ToggleBeltSwitch(int x, int y)
          DrawLevelField(xx, yy);
        }
       }
-      else if (IS_BELT_ACTIVE(element) && belt_dir == MV_NO_MOVING)
+      else if (IS_BELT_ACTIVE(element) && belt_dir == MV_NONE)
       {
        int e_belt_nr = getBeltNrFromBeltActiveElement(element);
 
@@ -4174,7 +4174,7 @@ inline static void TurnRoundExt(int x, int y)
   }
   else if (element == EL_BALLOON)
   {
-    MovDir[x][y] = game.balloon_dir;
+    MovDir[x][y] = game.wind_direction;
     MovDelay[x][y] = 0;
   }
   else if (element == EL_SPRING)
@@ -4182,7 +4182,7 @@ inline static void TurnRoundExt(int x, int y)
     if (MovDir[x][y] & MV_HORIZONTAL &&
        (!SPRING_CAN_ENTER_FIELD(element, move_x, move_y) ||
         SPRING_CAN_ENTER_FIELD(element, x, y + 1)))
-      MovDir[x][y] = MV_NO_MOVING;
+      MovDir[x][y] = MV_NONE;
 
     MovDelay[x][y] = 0;
   }
@@ -4251,7 +4251,7 @@ inline static void TurnRoundExt(int x, int y)
       }
     }
 
-    MovDir[x][y] = MV_NO_MOVING;
+    MovDir[x][y] = MV_NONE;
     if (attr_x < x)
       MovDir[x][y] |= (AllPlayersGone ? MV_RIGHT : MV_LEFT);
     else if (attr_x > x)
@@ -4388,6 +4388,11 @@ inline static void TurnRoundExt(int x, int y)
     MovDir[x][y] = move_pattern;
     MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
   }
+  else if (move_pattern & MV_WIND_DIRECTION)
+  {
+    MovDir[x][y] = game.wind_direction;
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+  }
   else if (move_pattern == MV_ALONG_LEFT_SIDE)
   {
     if (CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, left_x, left_y))
@@ -4441,7 +4446,7 @@ inline static void TurnRoundExt(int x, int y)
       }
     }
 
-    MovDir[x][y] = MV_NO_MOVING;
+    MovDir[x][y] = MV_NONE;
     if (attr_x < x)
       MovDir[x][y] |= (move_away ? MV_RIGHT : MV_LEFT);
     else if (attr_x > x)
@@ -4487,7 +4492,7 @@ inline static void TurnRoundExt(int x, int y)
           move_pattern == MV_WHEN_DROPPED)
   {
     if (!CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, move_x, move_y))
-      MovDir[x][y] = MV_NO_MOVING;
+      MovDir[x][y] = MV_NONE;
 
     MovDelay[x][y] = 0;
   }
@@ -4515,7 +4520,7 @@ inline static void TurnRoundExt(int x, int y)
     };
     boolean hunter_mode = (move_pattern == MV_MAZE_HUNTER);
     int move_preference = -1000000;    /* start with very low preference */
-    int new_move_dir = MV_NO_MOVING;
+    int new_move_dir = MV_NONE;
     int start_test = RND(4);
     int i;
 
@@ -4764,7 +4769,7 @@ void StartMoving(int x, int y)
     }
     else if (IS_FREE(x, y + 1) && element == EL_SPRING && level.use_spring_bug)
     {
-      if (MovDir[x][y] == MV_NO_MOVING)
+      if (MovDir[x][y] == MV_NONE)
       {
        InitMovingField(x, y, MV_DOWN);
        started_moving = TRUE;
@@ -4906,7 +4911,7 @@ void StartMoving(int x, int y)
 
   /* not "else if" because of elements that can fall and move (EL_SPRING) */
 #if 0
-  if (CAN_MOVE(element) && !started_moving && MovDir[x][y] != MV_NO_MOVING)
+  if (CAN_MOVE(element) && !started_moving && MovDir[x][y] != MV_NONE)
 #else
   if (CAN_MOVE(element) && !started_moving)
 #endif
@@ -4916,7 +4921,7 @@ void StartMoving(int x, int y)
 
 #if 0
 #if DEBUG
-    if (MovDir[x][y] == MV_NO_MOVING)
+    if (MovDir[x][y] == MV_NONE)
     {
       printf("StartMoving(): %d,%d: element %d ['%s'] not moving\n",
             x, y, element, element_info[element].token_name);
@@ -5103,7 +5108,7 @@ void StartMoving(int x, int y)
        if (DigField(local_player, x, y, newx, newy, 0,0, DF_DIG) == MF_MOVING)
          DrawLevelField(newx, newy);
        else
-         GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING;
+         GfxDir[x][y] = MovDir[x][y] = MV_NONE;
       }
       else if (!IS_FREE(newx, newy))
       {
@@ -6286,7 +6291,7 @@ void MauerWaechst(int x, int y)
 
       Feld[x][y] = Store[x][y];
       Store[x][y] = 0;
-      GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING;
+      GfxDir[x][y] = MovDir[x][y] = MV_NONE;
       DrawLevelField(x, y);
     }
   }
@@ -8387,7 +8392,7 @@ boolean MovePlayerOneStep(struct PlayerInfo *player,
   player->MovDir = (dx < 0 ? MV_LEFT :
                    dx > 0 ? MV_RIGHT :
                    dy < 0 ? MV_UP :
-                   dy > 0 ? MV_DOWN :  MV_NO_MOVING);
+                   dy > 0 ? MV_DOWN :  MV_NONE);
 
   if (!IN_LEV_FIELD(new_jx, new_jy))
     return MF_NO_ACTION;
@@ -8476,7 +8481,7 @@ boolean MovePlayer(struct PlayerInfo *player, int dx, int dy)
   player->move_delay = -1;             /* set to "uninitialized" value */
 
   /* store if player is automatically moved to next field */
-  player->is_auto_moving = (player->programmed_action != MV_NO_MOVING);
+  player->is_auto_moving = (player->programmed_action != MV_NONE);
 
   /* remove the last programmed player action */
   player->programmed_action = 0;
@@ -8849,7 +8854,7 @@ void ScrollScreen(struct PlayerInfo *player, int mode)
     redraw_mask |= REDRAW_FIELD;
   }
   else
-    ScreenMovDir = MV_NO_MOVING;
+    ScreenMovDir = MV_NONE;
 }
 
 void TestIfPlayerTouchesCustomElement(int x, int y)
@@ -9123,7 +9128,7 @@ void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir)
       continue;
 
     test_move_dir =
-      (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NO_MOVING);
+      (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NONE);
 
     test_element = MovingOrBlocked2ElementIfNotLeaving(test_x, test_y);
 
@@ -9197,7 +9202,7 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir)
       continue;
 
     test_move_dir =
-      (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NO_MOVING);
+      (IS_MOVING(test_x, test_y) ? MovDir[test_x][test_y] : MV_NONE);
 
     test_element = Feld[test_x][test_y];
 
@@ -9253,7 +9258,7 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir)
 
 void TestIfPlayerTouchesBadThing(int x, int y)
 {
-  TestIfGoodThingHitsBadThing(x, y, MV_NO_MOVING);
+  TestIfGoodThingHitsBadThing(x, y, MV_NONE);
 }
 
 void TestIfPlayerRunsIntoBadThing(int x, int y, int move_dir)
@@ -9263,7 +9268,7 @@ void TestIfPlayerRunsIntoBadThing(int x, int y, int move_dir)
 
 void TestIfBadThingTouchesPlayer(int x, int y)
 {
-  TestIfBadThingHitsGoodThing(x, y, MV_NO_MOVING);
+  TestIfBadThingHitsGoodThing(x, y, MV_NONE);
 }
 
 void TestIfBadThingRunsIntoPlayer(int x, int y, int move_dir)
@@ -9273,12 +9278,12 @@ void TestIfBadThingRunsIntoPlayer(int x, int y, int move_dir)
 
 void TestIfFriendTouchesBadThing(int x, int y)
 {
-  TestIfGoodThingHitsBadThing(x, y, MV_NO_MOVING);
+  TestIfGoodThingHitsBadThing(x, y, MV_NONE);
 }
 
 void TestIfBadThingTouchesFriend(int x, int y)
 {
-  TestIfBadThingHitsGoodThing(x, y, MV_NO_MOVING);
+  TestIfBadThingHitsGoodThing(x, y, MV_NONE);
 }
 
 void TestIfBadThingTouchesOtherBadThing(int bad_x, int bad_y)
@@ -9430,10 +9435,10 @@ int DigField(struct PlayerInfo *player,
   int jx = oldx, jy = oldy;
   int dx = x - jx, dy = y - jy;
   int nextx = x + dx, nexty = y + dy;
-  int move_direction = (dx == -1 ? MV_LEFT :
+  int move_direction = (dx == -1 ? MV_LEFT  :
                        dx == +1 ? MV_RIGHT :
-                       dy == -1 ? MV_UP :
-                       dy == +1 ? MV_DOWN : MV_NO_MOVING);
+                       dy == -1 ? MV_UP    :
+                       dy == +1 ? MV_DOWN  : MV_NONE);
   int opposite_direction = MV_DIR_OPPOSITE(move_direction);
   int dig_side = MV_DIR_OPPOSITE(move_direction);
   int old_element = Feld[jx][jy];
@@ -9620,14 +9625,14 @@ int DigField(struct PlayerInfo *player,
     }
     else if (element == EL_EXTRA_TIME && level.time > 0)
     {
-      TimeLeft += 10;
+      TimeLeft += level.extra_time;
       DrawGameValue_Time(TimeLeft);
     }
     else if (element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY)
     {
-      player->shield_normal_time_left += 10;
+      player->shield_normal_time_left += level.shield_normal_time;
       if (element == EL_SHIELD_DEADLY)
-       player->shield_deadly_time_left += 10;
+       player->shield_deadly_time_left += level.shield_deadly_time;
     }
     else if (element == EL_DYNAMITE || element == EL_SP_DISK_RED)
     {
@@ -9879,20 +9884,19 @@ int DigField(struct PlayerInfo *player,
     {
       ActivateTimegateSwitch(x, y);
     }
-    else if (element == EL_BALLOON_SWITCH_LEFT ||
+    else if (element == EL_BALLOON_SWITCH_LEFT  ||
             element == EL_BALLOON_SWITCH_RIGHT ||
-            element == EL_BALLOON_SWITCH_UP ||
-            element == EL_BALLOON_SWITCH_DOWN ||
+            element == EL_BALLOON_SWITCH_UP    ||
+            element == EL_BALLOON_SWITCH_DOWN  ||
+            element == EL_BALLOON_SWITCH_NONE  ||
             element == EL_BALLOON_SWITCH_ANY)
     {
-      if (element == EL_BALLOON_SWITCH_ANY)
-       game.balloon_dir = move_direction;
-      else
-       game.balloon_dir = (element == EL_BALLOON_SWITCH_LEFT  ? MV_LEFT :
-                           element == EL_BALLOON_SWITCH_RIGHT ? MV_RIGHT :
-                           element == EL_BALLOON_SWITCH_UP    ? MV_UP :
-                           element == EL_BALLOON_SWITCH_DOWN  ? MV_DOWN :
-                           MV_NO_MOVING);
+      game.wind_direction = (element == EL_BALLOON_SWITCH_LEFT  ? MV_LEFT  :
+                            element == EL_BALLOON_SWITCH_RIGHT ? MV_RIGHT :
+                            element == EL_BALLOON_SWITCH_UP    ? MV_UP    :
+                            element == EL_BALLOON_SWITCH_DOWN  ? MV_DOWN  :
+                            element == EL_BALLOON_SWITCH_NONE  ? MV_NONE  :
+                            move_direction);
     }
     else if (element == EL_LAMP)
     {
@@ -9905,7 +9909,7 @@ int DigField(struct PlayerInfo *player,
     else if (element == EL_TIME_ORB_FULL)
     {
       Feld[x][y] = EL_TIME_ORB_EMPTY;
-      TimeLeft += 10;
+      TimeLeft += level.time_orb_time;
       DrawGameValue_Time(TimeLeft);
 
       ResetGfxAnimation(x, y);
@@ -9957,10 +9961,10 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
 {
   int jx = player->jx, jy = player->jy;
   int x = jx + dx, y = jy + dy;
-  int snap_direction = (dx == -1 ? MV_LEFT :
+  int snap_direction = (dx == -1 ? MV_LEFT  :
                        dx == +1 ? MV_RIGHT :
-                       dy == -1 ? MV_UP :
-                       dy == +1 ? MV_DOWN : MV_NO_MOVING);
+                       dy == -1 ? MV_UP    :
+                       dy == +1 ? MV_DOWN  : MV_NONE);
 
   if (player->MovPos != 0 && game.engine_version >= VERSION_IDENT(2,2,0,0))
     return FALSE;
index 6287eea207642bdf86973d686e789c984bee2f25..e82a3547a84637417d1b45f5fb58d83c2131f522 100644 (file)
@@ -947,7 +947,7 @@ void prepare_em_level(void)
   ply1.anim = 0;
   ply1.oldx = ply1.x = ply1.x_initial;
   ply1.oldy = ply1.y = ply1.y_initial;
-  ply1.last_move_dir = MV_NO_MOVING;
+  ply1.last_move_dir = MV_NONE;
   ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = 0;
   ply1.joy_snap = ply1.joy_drop = 0;
   ply1.joy_stick = ply1.joy_spin = 0;
@@ -960,7 +960,7 @@ void prepare_em_level(void)
   ply2.anim = 0;
   ply2.oldx = ply2.x = ply2.x_initial;
   ply2.oldy = ply2.y = ply2.y_initial;
-  ply2.last_move_dir = MV_NO_MOVING;
+  ply2.last_move_dir = MV_NONE;
   ply2.joy_n = ply2.joy_e = ply2.joy_s = ply2.joy_w = 0;
   ply2.joy_snap = ply1.joy_drop = 0;
   ply2.joy_stick = ply2.joy_spin = 0;
index 73d76eaad433c3f009e2dedfd366699f1af58060..769d98fa411805999d3e75527cb0860c283aa54d 100644 (file)
@@ -2504,6 +2504,7 @@ void InitElementPropertiesStatic()
     EL_BALLOON_SWITCH_UP,
     EL_BALLOON_SWITCH_DOWN,
     EL_BALLOON_SWITCH_ANY,
+    EL_BALLOON_SWITCH_NONE,
     EL_LAMP,
     EL_TIME_ORB_FULL,
     EL_EMC_MAGIC_BALL_SWITCH,
index 39eca58ac7d2cc9d2438d5600e84b9f3521c1072..685311b94918d900c91ac7a493da25a100903b89 100644 (file)
@@ -1748,7 +1748,7 @@ int get_parameter_value(char *value_raw, char *suffix, int type)
     result = (strcmp(value, "left")  == 0 ? MV_LEFT :
              strcmp(value, "right") == 0 ? MV_RIGHT :
              strcmp(value, "up")    == 0 ? MV_UP :
-             strcmp(value, "down")  == 0 ? MV_DOWN : MV_NO_MOVING);
+             strcmp(value, "down")  == 0 ? MV_DOWN : MV_NONE);
   }
   else if (strcmp(suffix, ".anim_mode") == 0)
   {
index 0b210ed01f0584645db71364b390fbfa5700432a..0ccf0a2904bd78c0d2df5ed6f4cc59f12f35676b 100644 (file)
 #define BUTTON_2               5
 
 /* values for move directions and special "button" key bitmasks */
-#define MV_NO_MOVING           0
+#define MV_NONE                        0
 #define MV_LEFT                        (1 << MV_BIT_LEFT)
 #define MV_RIGHT               (1 << MV_BIT_RIGHT)
 #define MV_UP                  (1 << MV_BIT_UP)
 #define MV_VERTICAL            (MV_UP   | MV_DOWN)
 #define MV_ALL_DIRECTIONS      (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
 #define MV_ANY_DIRECTION       (MV_ALL_DIRECTIONS)
-#define MV_NO_DIRECTIONS       (MV_NO_MOVING)
+#define MV_NO_DIRECTION                (MV_NONE)
 
 #define KEY_BUTTON_1           (1 << BUTTON_1)
 #define KEY_BUTTON_2           (1 << BUTTON_2)
 #define MV_DIR_OPPOSITE(x)     ((x) == MV_LEFT  ? MV_RIGHT :           \
                                 (x) == MV_RIGHT ? MV_LEFT  :           \
                                 (x) == MV_UP    ? MV_DOWN  :           \
-                                (x) == MV_DOWN  ? MV_UP    : MV_NO_MOVING)
+                                (x) == MV_DOWN  ? MV_UP    : MV_NONE)
 
 
 /* values for animation mode (frame order and direction) */
index 9f4c1fe49b727e6101605c6bc29ab92085476236..fec3907304fe4dd5a0e687d34b1585bdc3ca44c4 100644 (file)
@@ -88,7 +88,7 @@ static int get_toon_direction(char *direction_string_raw)
                   strcmp(direction_string, "right") == 0 ? MV_RIGHT :
                   strcmp(direction_string, "up")    == 0 ? MV_UP :
                   strcmp(direction_string, "down")  == 0 ? MV_DOWN :
-                  MV_NO_MOVING);
+                  MV_NONE);
 
   free(direction_string);
 
index 105912923086d223012d1597fd65a4d704fcc514..6798042bcdd56eb43448ad2763a3892d14d3fe09 100644 (file)
@@ -77,7 +77,7 @@ int                   scroll_x, scroll_y;
 
 int                    FX = SX, FY = SY;
 int                    ScrollStepSize;
-int                    ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
+int                    ScreenMovDir = MV_NONE, ScreenMovPos = 0;
 int                    ScreenGfxPos = 0;
 int                    BorderElement = EL_STEELWALL;
 int                    GameFrameDelay = GAME_FRAME_DELAY;
@@ -1756,27 +1756,27 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "balloon_switch_left",
     "balloon_switch",
-    "send balloon to the left"
+    "wind switch (left)"
   },
   {
     "balloon_switch_right",
     "balloon_switch",
-    "send balloon to the right"
+    "wind switch (right)"
   },
   {
     "balloon_switch_up",
     "balloon_switch",
-    "send balloon up"
+    "wind switch (up)"
   },
   {
     "balloon_switch_down",
     "balloon_switch",
-    "send balloon down"
+    "wind switch (down)"
   },
   {
     "balloon_switch_any",
     "balloon_switch",
-    "send balloon in pressed direction"
+    "wind switch (any direction)"
   },
   {
     "emc_steelwall_1",
@@ -3456,7 +3456,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "balloon_switch_none",
     "balloon_switch",
-    "stop moving balloon"
+    "wind switch (off)"
   },
   {
     "emc_gate_5",
index 1d5ad46b4fd29679409bdadc9e7344a5f5369856..7805f3496b79e0e167eeb75878a1d9a01f60ad7f 100644 (file)
 #define PLAYER_BITS_TRIGGER    (1 << 4)
 
 /* values for change side for custom elements */
-#define CH_SIDE_NONE           MV_NO_MOVING
+#define CH_SIDE_NONE           MV_NONE
 #define CH_SIDE_LEFT           MV_LEFT
 #define CH_SIDE_RIGHT          MV_RIGHT
 #define CH_SIDE_TOP            MV_UP
 #define MV_BIT_TURNING_LEFT_RIGHT 14
 #define MV_BIT_TURNING_RIGHT_LEFT 15
 #define MV_BIT_TURNING_RANDOM  16
+#define MV_BIT_WIND_DIRECTION  17
 
 /* values for custom move patterns */
 #define MV_TOWARDS_PLAYER      (1 << MV_BIT_TOWARDS_PLAYER)
 #define MV_TURNING_LEFT_RIGHT  (1 << MV_BIT_TURNING_LEFT_RIGHT)
 #define MV_TURNING_RIGHT_LEFT  (1 << MV_BIT_TURNING_RIGHT_LEFT)
 #define MV_TURNING_RANDOM      (1 << MV_BIT_TURNING_RANDOM)
+#define MV_WIND_DIRECTION      (1 << MV_BIT_WIND_DIRECTION)
 
 /* values for initial move direction (bits 0 - 3: basic move directions) */
 #define MV_START_BIT_PREVIOUS  4
 
 /* values for initial move direction */
-#define MV_START_AUTOMATIC     (MV_NO_MOVING)
+#define MV_START_NONE          (MV_NONE)
+#define MV_START_AUTOMATIC     (MV_NONE)
 #define MV_START_LEFT          (MV_LEFT)
 #define MV_START_RIGHT         (MV_RIGHT)
 #define MV_START_UP            (MV_UP)
@@ -1740,6 +1743,12 @@ struct LevelInfo
   int time_light;
   int time_timegate;
 
+  int shield_normal_time;
+  int shield_deadly_time;
+
+  int extra_time;
+  int time_orb_time;
+
   /* values for the new EMC elements */
   int android_move_time;
   int android_clone_time;
@@ -1844,7 +1853,7 @@ struct GameInfo
   int belt_dir[4];
   int belt_dir_nr[4];
   int switchgate_pos;
-  int balloon_dir;
+  int wind_direction;
   boolean gravity;
   boolean explosions_delayed;
   boolean envelope_active;
index aa1767a426c9f4e962b63a08ab06935564906ed2..502f8deac6bf774c7f0fb35986778bd073c7a0cf 100644 (file)
@@ -5386,7 +5386,7 @@ int el_act_dir2img(int element, int action, int direction)
 {
   element = GFX_ELEMENT(element);
 
-  if (direction == MV_NO_MOVING)
+  if (direction == MV_NONE)
     return element_info[element].graphic[action];
 
   direction = MV_DIR_BIT(direction);
@@ -5397,7 +5397,7 @@ int el_act_dir2img(int element, int action, int direction)
 int el_act_dir2img(int element, int action, int direction)
 {
   element = GFX_ELEMENT(element);
-  direction = MV_DIR_BIT(direction);   /* default: MV_NO_MOVING => MV_DOWN */
+  direction = MV_DIR_BIT(direction);   /* default: MV_NONE => MV_DOWN */
 
   /* direction_graphic[][] == graphic[] for undefined direction graphics */
   return element_info[element].direction_graphic[action][direction];
@@ -5409,7 +5409,7 @@ static int el_act_dir2crm(int element, int action, int direction)
 {
   element = GFX_ELEMENT(element);
 
-  if (direction == MV_NO_MOVING)
+  if (direction == MV_NONE)
     return element_info[element].crumbled[action];
 
   direction = MV_DIR_BIT(direction);
@@ -5420,7 +5420,7 @@ static int el_act_dir2crm(int element, int action, int direction)
 static int el_act_dir2crm(int element, int action, int direction)
 {
   element = GFX_ELEMENT(element);
-  direction = MV_DIR_BIT(direction);   /* default: MV_NO_MOVING => MV_DOWN */
+  direction = MV_DIR_BIT(direction);   /* default: MV_NONE => MV_DOWN */
 
   /* direction_graphic[][] == graphic[] for undefined direction graphics */
   return element_info[element].direction_crumbled[action][direction];
@@ -5525,7 +5525,7 @@ void InitGraphicInfo_EM(void)
     object_mapping[i].element_rnd = EL_UNKNOWN;
     object_mapping[i].is_backside = FALSE;
     object_mapping[i].action = ACTION_DEFAULT;
-    object_mapping[i].direction = MV_NO_MOVING;
+    object_mapping[i].direction = MV_NONE;
   }
 
   /* always start with reliable default values */
@@ -5535,7 +5535,7 @@ void InitGraphicInfo_EM(void)
     {
       player_mapping[p][i].element_rnd = EL_UNKNOWN;
       player_mapping[p][i].action = ACTION_DEFAULT;
-      player_mapping[p][i].direction = MV_NO_MOVING;
+      player_mapping[p][i].direction = MV_NONE;
     }
   }
 
@@ -5985,7 +5985,7 @@ void InitGraphicInfo_EM(void)
       {
        int effective_element = element;
        int effective_action = action;
-       int graphic = (direction == MV_NO_MOVING ?
+       int graphic = (direction == MV_NONE ?
                       el_act2img(effective_element, effective_action) :
                       el_act_dir2img(effective_element, effective_action,
                                      direction));