rnd-20051216-2-src
authorHolger Schemel <info@artsoft.org>
Fri, 16 Dec 2005 22:31:40 +0000 (23:31 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:49:55 +0000 (10:49 +0200)
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/main.c
src/main.h
src/tools.c

index d1c14d04f419372df4e90a705e57a38a211637ed..8f47ee3c9059a0b164f251f4f24f252e9c946f37 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2005-12-16 05:03]"
+#define COMPILE_DATE_STRING "[2005-12-16 23:27]"
index 8341f92467b21749cfc69ea5b74fcfaaf19a5c57..a36f0696ce037e01e7645378bf9bba37e8928956 100644 (file)
 #define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 45)
 #define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 46)
 #define GADGET_ID_CUSTOM_GEMCOUNT_UP   (GADGET_ID_COUNTER_FIRST + 47)
-#define GADGET_ID_PUSH_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 48)
-#define GADGET_ID_PUSH_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 49)
-#define GADGET_ID_PUSH_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 50)
-#define GADGET_ID_PUSH_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 51)
-#define GADGET_ID_PUSH_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 52)
-#define GADGET_ID_PUSH_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 53)
-#define GADGET_ID_DROP_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 54)
-#define GADGET_ID_DROP_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 55)
-#define GADGET_ID_DROP_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 56)
-#define GADGET_ID_DROP_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 57)
-#define GADGET_ID_DROP_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 58)
-#define GADGET_ID_DROP_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 59)
-#define GADGET_ID_MOVE_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 60)
-#define GADGET_ID_MOVE_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 61)
-#define GADGET_ID_MOVE_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 62)
-#define GADGET_ID_MOVE_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 63)
-#define GADGET_ID_MOVE_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 64)
-#define GADGET_ID_MOVE_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 65)
-#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 66)
-#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 67)
-#define GADGET_ID_EXPLOSION_DELAY_UP   (GADGET_ID_COUNTER_FIRST + 68)
-#define GADGET_ID_IGNITION_DELAY_DOWN  (GADGET_ID_COUNTER_FIRST + 69)
-#define GADGET_ID_IGNITION_DELAY_TEXT  (GADGET_ID_COUNTER_FIRST + 70)
-#define GADGET_ID_IGNITION_DELAY_UP    (GADGET_ID_COUNTER_FIRST + 71)
-#define GADGET_ID_CHANGE_DELAY_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 72)
-#define GADGET_ID_CHANGE_DELAY_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 73)
-#define GADGET_ID_CHANGE_DELAY_FIX_UP  (GADGET_ID_COUNTER_FIRST + 74)
-#define GADGET_ID_CHANGE_DELAY_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 75)
-#define GADGET_ID_CHANGE_DELAY_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 76)
-#define GADGET_ID_CHANGE_DELAY_RND_UP  (GADGET_ID_COUNTER_FIRST + 77)
-#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 78)
-#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 79)
-#define GADGET_ID_CHANGE_CONT_RND_UP   (GADGET_ID_COUNTER_FIRST + 80)
-#define GADGET_ID_GROUP_CONTENT_DOWN   (GADGET_ID_COUNTER_FIRST + 81)
-#define GADGET_ID_GROUP_CONTENT_TEXT   (GADGET_ID_COUNTER_FIRST + 82)
-#define GADGET_ID_GROUP_CONTENT_UP     (GADGET_ID_COUNTER_FIRST + 83)
+#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 48)
+#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 49)
+#define GADGET_ID_CUSTOM_VALUE_FIX_UP  (GADGET_ID_COUNTER_FIRST + 50)
+#define GADGET_ID_CUSTOM_VALUE_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 51)
+#define GADGET_ID_CUSTOM_VALUE_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 52)
+#define GADGET_ID_CUSTOM_VALUE_RND_UP  (GADGET_ID_COUNTER_FIRST + 53)
+#define GADGET_ID_PUSH_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 54)
+#define GADGET_ID_PUSH_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 55)
+#define GADGET_ID_PUSH_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 56)
+#define GADGET_ID_PUSH_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 57)
+#define GADGET_ID_PUSH_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 58)
+#define GADGET_ID_PUSH_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 59)
+#define GADGET_ID_DROP_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 60)
+#define GADGET_ID_DROP_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 61)
+#define GADGET_ID_DROP_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 62)
+#define GADGET_ID_DROP_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 63)
+#define GADGET_ID_DROP_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 64)
+#define GADGET_ID_DROP_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 65)
+#define GADGET_ID_MOVE_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 66)
+#define GADGET_ID_MOVE_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 67)
+#define GADGET_ID_MOVE_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 68)
+#define GADGET_ID_MOVE_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 69)
+#define GADGET_ID_MOVE_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 70)
+#define GADGET_ID_MOVE_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 71)
+#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 72)
+#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 73)
+#define GADGET_ID_EXPLOSION_DELAY_UP   (GADGET_ID_COUNTER_FIRST + 74)
+#define GADGET_ID_IGNITION_DELAY_DOWN  (GADGET_ID_COUNTER_FIRST + 75)
+#define GADGET_ID_IGNITION_DELAY_TEXT  (GADGET_ID_COUNTER_FIRST + 76)
+#define GADGET_ID_IGNITION_DELAY_UP    (GADGET_ID_COUNTER_FIRST + 77)
+#define GADGET_ID_CHANGE_DELAY_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 78)
+#define GADGET_ID_CHANGE_DELAY_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 79)
+#define GADGET_ID_CHANGE_DELAY_FIX_UP  (GADGET_ID_COUNTER_FIRST + 80)
+#define GADGET_ID_CHANGE_DELAY_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 81)
+#define GADGET_ID_CHANGE_DELAY_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 82)
+#define GADGET_ID_CHANGE_DELAY_RND_UP  (GADGET_ID_COUNTER_FIRST + 83)
+#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 84)
+#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 85)
+#define GADGET_ID_CHANGE_CONT_RND_UP   (GADGET_ID_COUNTER_FIRST + 86)
+#define GADGET_ID_GROUP_CONTENT_DOWN   (GADGET_ID_COUNTER_FIRST + 87)
+#define GADGET_ID_GROUP_CONTENT_TEXT   (GADGET_ID_COUNTER_FIRST + 88)
+#define GADGET_ID_GROUP_CONTENT_UP     (GADGET_ID_COUNTER_FIRST + 89)
 
 /* drawing area identifiers */
-#define GADGET_ID_DRAWING_AREA_FIRST   (GADGET_ID_COUNTER_FIRST + 84)
+#define GADGET_ID_DRAWING_AREA_FIRST   (GADGET_ID_COUNTER_FIRST + 90)
 
 #define GADGET_ID_DRAWING_LEVEL                (GADGET_ID_DRAWING_AREA_FIRST + 0)
 #define GADGET_ID_YAMYAM_CONTENT_0     (GADGET_ID_DRAWING_AREA_FIRST + 1)
 #define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 26)
 #define GADGET_ID_CUSTOM_ACCESSIBLE    (GADGET_ID_CHECKBUTTON_FIRST + 27)
 #define GADGET_ID_CUSTOM_GRAV_REACHABLE        (GADGET_ID_CHECKBUTTON_FIRST + 28)
-#define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 29)
-#define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 30)
-#define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 31)
-#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 32)
-#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 33)
-#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 34)
-#define GADGET_ID_CHANGE_USE_RANDOM    (GADGET_ID_CHECKBUTTON_FIRST + 35)
-#define GADGET_ID_CHANGE_HAS_ACTION    (GADGET_ID_CHECKBUTTON_FIRST + 36)
-#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 37)
-#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 38)
-#define GADGET_ID_CHANGE_BY_OTHER_ACT  (GADGET_ID_CHECKBUTTON_FIRST + 39)
+#define GADGET_ID_CUSTOM_USE_LAST_VALUE        (GADGET_ID_CHECKBUTTON_FIRST + 29)
+#define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 30)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 31)
+#define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 32)
+#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 33)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 34)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_CHANGE_USE_RANDOM    (GADGET_ID_CHECKBUTTON_FIRST + 36)
+#define GADGET_ID_CHANGE_HAS_ACTION    (GADGET_ID_CHECKBUTTON_FIRST + 37)
+#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 38)
+#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 39)
+#define GADGET_ID_CHANGE_BY_OTHER_ACT  (GADGET_ID_CHECKBUTTON_FIRST + 40)
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 40)
+#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 41)
 #define GADGET_ID_ELEMENTLIST_LAST     (GADGET_ID_ELEMENTLIST_FIRST +  \
                                        ED_NUM_ELEMENTLIST_BUTTONS - 1)
 
 #define ED_COUNTER_ID_ENVELOPE_YSIZE   13
 #define ED_COUNTER_ID_CUSTOM_SCORE     14
 #define ED_COUNTER_ID_CUSTOM_GEMCOUNT  15
-#define ED_COUNTER_ID_PUSH_DELAY_FIX   16
-#define ED_COUNTER_ID_PUSH_DELAY_RND   17
-#define ED_COUNTER_ID_DROP_DELAY_FIX   18
-#define ED_COUNTER_ID_DROP_DELAY_RND   19
-#define ED_COUNTER_ID_MOVE_DELAY_FIX   20
-#define ED_COUNTER_ID_MOVE_DELAY_RND   21
-#define ED_COUNTER_ID_EXPLOSION_DELAY  22
-#define ED_COUNTER_ID_IGNITION_DELAY   23
-#define ED_COUNTER_ID_GROUP_CONTENT    24
-#define ED_COUNTER_ID_CHANGE_DELAY_FIX 25
-#define ED_COUNTER_ID_CHANGE_DELAY_RND 26
-#define ED_COUNTER_ID_CHANGE_CONT_RND  27
-
-#define ED_NUM_COUNTERBUTTONS          28
+#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 16
+#define ED_COUNTER_ID_CUSTOM_VALUE_RND 17
+#define ED_COUNTER_ID_PUSH_DELAY_FIX   18
+#define ED_COUNTER_ID_PUSH_DELAY_RND   19
+#define ED_COUNTER_ID_DROP_DELAY_FIX   20
+#define ED_COUNTER_ID_DROP_DELAY_RND   21
+#define ED_COUNTER_ID_MOVE_DELAY_FIX   22
+#define ED_COUNTER_ID_MOVE_DELAY_RND   23
+#define ED_COUNTER_ID_EXPLOSION_DELAY  24
+#define ED_COUNTER_ID_IGNITION_DELAY   25
+#define ED_COUNTER_ID_GROUP_CONTENT    26
+#define ED_COUNTER_ID_CHANGE_DELAY_FIX 27
+#define ED_COUNTER_ID_CHANGE_DELAY_RND 28
+#define ED_COUNTER_ID_CHANGE_CONT_RND  29
+
+#define ED_NUM_COUNTERBUTTONS          30
 
 #define ED_COUNTER_ID_LEVEL_FIRST      ED_COUNTER_ID_LEVEL_XSIZE
 #define ED_COUNTER_ID_LEVEL_LAST       ED_COUNTER_ID_LEVEL_RANDOM
 #define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE  15
 #define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE    16
 #define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE        17
-#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT        18
-#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE        19
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      20
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      21
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     22
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      23
-#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY                24
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE   25
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE  26
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 27
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT        28
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    29
-#define ED_CHECKBUTTON_ID_CHANGE_DELAY         30
-#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 31
-#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT  32
-#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 33
-#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   34
-#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 35
-#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM    36
-#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION    37
-
-#define ED_NUM_CHECKBUTTONS                    38
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE        18
+#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT        19
+#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE        20
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      21
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      22
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     23
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      24
+#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY                25
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE   26
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE  27
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 28
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT        29
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    30
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY         31
+#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 32
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT  33
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 34
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   35
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 36
+#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM    37
+#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION    38
+
+#define ED_NUM_CHECKBUTTONS                    39
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_INITIAL_GRAVITY
 #define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
@@ -1083,7 +1093,7 @@ static struct
     GADGET_ID_CUSTOM_SCORE_DOWN,       GADGET_ID_CUSTOM_SCORE_UP,
     GADGET_ID_CUSTOM_SCORE_TEXT,       GADGET_ID_NONE,
     &custom_element.collect_score_initial,
-    NULL,                              "score", " "
+    NULL,                              "CE score", " "
   },
   {
     -1,                                        ED_ELEMENT_SETTINGS_YPOS(6),
@@ -1091,7 +1101,23 @@ static struct
     GADGET_ID_CUSTOM_GEMCOUNT_DOWN,    GADGET_ID_CUSTOM_GEMCOUNT_UP,
     GADGET_ID_CUSTOM_GEMCOUNT_TEXT,    GADGET_ID_CUSTOM_SCORE_UP,
     &custom_element.collect_count_initial,
-    NULL,                              "count", NULL
+    NULL,                              "CE count", NULL
+  },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(12),
+    0,                                 9999,
+    GADGET_ID_CUSTOM_VALUE_FIX_DOWN,   GADGET_ID_CUSTOM_VALUE_FIX_UP,
+    GADGET_ID_CUSTOM_VALUE_FIX_TEXT,   GADGET_ID_NONE,
+    &custom_element.ce_value_fixed_initial,
+    NULL,                              "CE value", NULL
+  },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(12),
+    0,                                 9999,
+    GADGET_ID_CUSTOM_VALUE_RND_DOWN,   GADGET_ID_CUSTOM_VALUE_RND_UP,
+    GADGET_ID_CUSTOM_VALUE_RND_TEXT,   GADGET_ID_CUSTOM_VALUE_FIX_UP,
+    &custom_element.ce_value_random_initial,
+    NULL,                              "+random", NULL
   },
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(7),
@@ -1180,7 +1206,7 @@ static struct
     GADGET_ID_CHANGE_DELAY_FIX_DOWN,   GADGET_ID_CHANGE_DELAY_FIX_UP,
     GADGET_ID_CHANGE_DELAY_FIX_TEXT,   GADGET_ID_NONE,
     &custom_element_change.delay_fixed,
-    NULL,                              "delay", NULL,
+    NULL,                              "CE delay", NULL,
   },
   {
     -1,                                        ED_ELEMENT_SETTINGS_YPOS(2),
@@ -1460,7 +1486,7 @@ static struct ValueTextInfo options_change_direct_action[] =
 #endif
   { CE_IMPACT,                 "impact (on something)"         },
   { CE_SMASHED,                        "smashed (from above)"          },
-  { CE_COUNT_AT_ZERO,          "CE count at zero"              },
+  { CE_VALUE_GETS_ZERO,                "CE value gets 0"               },
 
   { -1,                                NULL                            }
 };
@@ -1481,7 +1507,7 @@ static struct ValueTextInfo options_change_other_action[] =
   { CE_SWITCH_OF_X,            "switch of"                     },
   { CE_CHANGE_OF_X,            "change by page of"             },
   { CE_EXPLOSION_OF_X,         "explosion of"                  },
-  { CE_COUNT_AT_ZERO_OF_X,     "CE count at zero of"           },
+  { CE_VALUE_GETS_ZERO_OF_X,   "CE value gets 0 of"            },
 
   { -1,                                NULL                            }
 };
@@ -1569,15 +1595,15 @@ static struct ValueTextInfo options_action_type[] =
   { CA_RESTART_LEVEL,          "restart level"                 },
   { CA_SHOW_ENVELOPE,          "show envelope"                 },
   { CA_ADD_KEY,                        "add key"                       },
-  { CA_DEL_KEY,                        "remove key"                    },
-  { CA_SET_GEMS,               "set gems"                      },
-  { CA_SET_TIME,               "set time"                      },
-  { CA_SET_SCORE,              "set score"                     },
-  { CA_SET_CE_SCORE,           "set CE score"                  },
-  { CA_SET_CE_COUNT,           "set CE count"                  },
+  { CA_REMOVE_KEY,             "remove key"                    },
   { CA_SET_PLAYER_SPEED,       "set player speed"              },
   { CA_SET_PLAYER_GRAVITY,     "set gravity"                   },
   { CA_SET_WIND_DIRECTION,     "set wind dir."                 },
+  { CA_SET_LEVEL_GEMS,         "set needed gems"               },
+  { CA_SET_LEVEL_TIME,         "set level time"                },
+  { CA_SET_LEVEL_SCORE,                "set level score"               },
+  { CA_SET_CE_SCORE,           "set CE score"                  },
+  { CA_SET_CE_VALUE,           "set CE value"                  },
 #if 0
   { CA_SET_DYNABOMB_NUMBER,    "set bomb number"               },
   { CA_SET_DYNABOMB_SIZE,      "set bomb size"                 },
@@ -1651,19 +1677,21 @@ static struct ValueTextInfo options_action_arg_number[] =
   { CA_ARG_UNDEFINED,          " "                             },
   { CA_ARG_NUMBER_RESET,       "reset"                         },
   { CA_ARG_UNDEFINED,          " "                             },
-  { CA_ARG_NUMBER_CE_SCORE,    "CE score"                      },
-  { CA_ARG_NUMBER_CE_COUNT,    "CE count"                      },
   { CA_ARG_NUMBER_CE_DELAY,    "CE delay"                      },
+  { CA_ARG_NUMBER_CE_SCORE,    "CE score"                      },
+  { CA_ARG_NUMBER_CE_VALUE,    "CE value"                      },
+  { CA_ARG_UNDEFINED,          " "                             },
+  { CA_ARG_ELEMENT_HEADLINE,   "[CE value"                     },
+  { CA_ARG_ELEMENT_HEADLINE,   " of"                           },
+  { CA_ARG_ELEMENT_HEADLINE,   " element]"                     },
+  { CA_ARG_ELEMENT_TARGET,     "target"                        },
+  { CA_ARG_ELEMENT_TRIGGER,    "trigger"                       },
 
   { -1,                                NULL                            }
 };
 
-static struct ValueTextInfo options_action_arg_element[] =
+static struct ValueTextInfo options_action_arg_key[] =
 {
-  { CA_ARG_ELEMENT_HEADLINE,   "[element]"                     },
-  { CA_ARG_ELEMENT_TARGET,     "target"                        },
-  { CA_ARG_ELEMENT_TRIGGER,    "trigger"                       },
-  { CA_ARG_UNDEFINED,          " "                             },
   { CA_ARG_NUMBER_HEADLINE,    "[number]"                      },
   { CA_ARG_1,                  "1"                             },
   { CA_ARG_2,                  "2"                             },
@@ -1673,6 +1701,25 @@ static struct ValueTextInfo options_action_arg_element[] =
   { CA_ARG_6,                  "6"                             },
   { CA_ARG_7,                  "7"                             },
   { CA_ARG_8,                  "8"                             },
+  { CA_ARG_UNDEFINED,          " "                             },
+  { CA_ARG_ELEMENT_HEADLINE,   "[element]"                     },
+  { CA_ARG_ELEMENT_TARGET,     "target"                        },
+  { CA_ARG_ELEMENT_TRIGGER,    "trigger"                       },
+
+  { -1,                                NULL                            }
+};
+
+static struct ValueTextInfo options_action_arg_envelope[] =
+{
+  { CA_ARG_NUMBER_HEADLINE,    "[number]"                      },
+  { CA_ARG_1,                  "1"                             },
+  { CA_ARG_2,                  "2"                             },
+  { CA_ARG_3,                  "3"                             },
+  { CA_ARG_4,                  "4"                             },
+  { CA_ARG_UNDEFINED,          " "                             },
+  { CA_ARG_ELEMENT_HEADLINE,   "[element]"                     },
+  { CA_ARG_ELEMENT_TARGET,     "target"                        },
+  { CA_ARG_ELEMENT_TRIGGER,    "trigger"                       },
 
   { -1,                                NULL                            }
 };
@@ -1754,15 +1801,15 @@ action_arg_options[] =
   { CA_EXIT_PLAYER,            0,      options_action_arg_player,      },
   { CA_KILL_PLAYER,            0,      options_action_arg_player,      },
   { CA_RESTART_LEVEL,          0,      options_action_arg_none,        },
-  { CA_SHOW_ENVELOPE,          0,      options_action_arg_element,     },
-  { CA_ADD_KEY,                        0,      options_action_arg_element,     },
-  { CA_DEL_KEY,                        0,      options_action_arg_element,     },
+  { CA_SHOW_ENVELOPE,          0,      options_action_arg_envelope,    },
+  { CA_ADD_KEY,                        0,      options_action_arg_key,         },
+  { CA_REMOVE_KEY,             0,      options_action_arg_key,         },
   { CA_SET_PLAYER_SPEED,       1,      options_action_arg_speed,       },
-  { CA_SET_GEMS,               2,      options_action_arg_number,      },
-  { CA_SET_TIME,               2,      options_action_arg_number,      },
-  { CA_SET_SCORE,              2,      options_action_arg_number,      },
+  { CA_SET_LEVEL_GEMS,         2,      options_action_arg_number,      },
+  { CA_SET_LEVEL_TIME,         2,      options_action_arg_number,      },
+  { CA_SET_LEVEL_SCORE,                2,      options_action_arg_number,      },
   { CA_SET_CE_SCORE,           2,      options_action_arg_number,      },
-  { CA_SET_CE_COUNT,           2,      options_action_arg_number,      },
+  { CA_SET_CE_VALUE,           2,      options_action_arg_number,      },
   { CA_SET_PLAYER_GRAVITY,     1,      options_action_arg_gravity,     },
   { CA_SET_WIND_DIRECTION,     1,      options_action_arg_direction,   },
 
@@ -2376,6 +2423,12 @@ static struct
     &custom_element_properties[EP_GRAVITY_REACHABLE],
     NULL, "reachable despite gravity", "player can walk/dig despite gravity"
   },
+  {
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(13),
+    GADGET_ID_CUSTOM_USE_LAST_VALUE,   GADGET_ID_NONE,
+    &custom_element.use_last_ce_value,
+    NULL, "use last CE value after change", "use last CE value after change"
+  },
   {
     ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(5),
     GADGET_ID_CUSTOM_WALK_TO_OBJECT,   GADGET_ID_NONE,
@@ -5420,7 +5473,11 @@ static void MapCounterButtons(int id)
   int yoffset_above = MINI_TILEX + ED_GADGET_DISTANCE;
   int yoffset = ED_BORDER_SIZE;
   int x_left = gi_down->x - xoffset_left;
+#if 1
+  int x_right; /* set after gadget position was modified */
+#else
   int x_right = gi_up->x + gi_up->width + xoffset_right;
+#endif
   int y_above = gi_down->y - yoffset_above;
   int x = gi_down->x;
   int y;       /* set after gadget position was modified */
@@ -5429,6 +5486,9 @@ static void MapCounterButtons(int id)
   ModifyEditorCounterLimits(id, counterbutton_info[id].min_value,
                            counterbutton_info[id].max_value);
 
+  /* right text position might have changed after setting position above */
+  x_right = gi_up->x + gi_up->width + xoffset_right;
+
   ModifyEditorCounterValue(id, *counterbutton_info[id].value);
 
   /* set position for "value[1,2,3,4]" counter gadgets (score in most cases) */
@@ -5440,6 +5500,7 @@ static void MapCounterButtons(int id)
     ModifyGadget(gi_up,   GDI_Y, SY + counterbutton_info[id].y, GDI_END);
   }
 
+  /* vertical position might have changed after setting position above */
   y = gi_up->y + yoffset;
 
   if (counterbutton_info[id].text_above)
@@ -5862,6 +5923,30 @@ static int setSelectboxValue(int selectbox_id, int new_value)
   return new_index_value;
 }
 
+static void setSelectboxSpecialActionOptions()
+{
+  int i;
+
+  /* change action mode and arg selectbox according to action type selectbox */
+  for (i = 0; action_arg_options[i].value != -1; i++)
+  {
+    if (action_arg_options[i].value == custom_element_change.action_type)
+    {
+      int mode = action_arg_options[i].mode;
+
+      ModifyEditorSelectboxOptions(ED_SELECTBOX_ID_ACTION_MODE,
+                                  action_arg_modes[mode]);
+      ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_MODE,
+                                custom_element_change.action_mode);
+
+      ModifyEditorSelectboxOptions(ED_SELECTBOX_ID_ACTION_ARG,
+                                  action_arg_options[i].options);
+      ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_ARG,
+                                custom_element_change.action_arg);
+    }
+  }
+}
+
 static void copy_custom_element_settings(int element_from, int element_to)
 {
   struct ElementInfo *ei_from = &element_info[element_from];
@@ -5886,6 +5971,10 @@ static void copy_custom_element_settings(int element_from, int element_to)
   ei_to->collect_score_initial = ei_from->collect_score_initial;
   ei_to->collect_count_initial = ei_from->collect_count_initial;
 
+  ei_to->ce_value_fixed_initial = ei_from->ce_value_fixed_initial;
+  ei_to->ce_value_random_initial = ei_from->ce_value_random_initial;
+  ei_to->use_last_ce_value = ei_from->use_last_ce_value;
+
   ei_to->push_delay_fixed = ei_from->push_delay_fixed;
   ei_to->push_delay_random = ei_from->push_delay_random;
   ei_to->drop_delay_fixed = ei_from->drop_delay_fixed;
@@ -6066,6 +6155,9 @@ static void CopyCustomElementPropertiesToEditor(int element)
   custom_element = element_info[element];
   custom_element_change = *element_info[element].change;
 
+  /* needed to initially set selectbox options for special action options */
+  setSelectboxSpecialActionOptions();
+
   /* needed to initially set selectbox value variables to reliable defaults */
   for (i = 0; i < ED_NUM_SELECTBOX; i++)
     setSelectboxValue(i, *selectbox_info[i].value);
@@ -6148,7 +6240,7 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_BLOCKED) ? CE_BLOCKED :
      HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
      HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
-     HAS_CHANGE_EVENT(element, CE_COUNT_AT_ZERO) ? CE_COUNT_AT_ZERO :
+     HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO) ? CE_VALUE_GETS_ZERO :
      custom_element_change.direct_action);
 
   /* set "change by other element action" selectbox help value */
@@ -6167,7 +6259,7 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_SWITCH_OF_X) ? CE_SWITCH_OF_X :
      HAS_CHANGE_EVENT(element, CE_CHANGE_OF_X) ? CE_CHANGE_OF_X :
      HAS_CHANGE_EVENT(element, CE_EXPLOSION_OF_X) ? CE_EXPLOSION_OF_X :
-     HAS_CHANGE_EVENT(element, CE_COUNT_AT_ZERO_OF_X) ? CE_COUNT_AT_ZERO_OF_X :
+     HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X :
      custom_element_change.other_action);
 }
 
@@ -6282,7 +6374,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_BLOCKED] = FALSE;
   custom_element_change_events[CE_IMPACT] = FALSE;
   custom_element_change_events[CE_SMASHED] = FALSE;
-  custom_element_change_events[CE_COUNT_AT_ZERO] = FALSE;
+  custom_element_change_events[CE_VALUE_GETS_ZERO] = FALSE;
   custom_element_change_events[custom_element_change.direct_action] =
     custom_element_change_events[CE_BY_DIRECT_ACTION];
 
@@ -6301,7 +6393,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_SWITCH_OF_X] = FALSE;
   custom_element_change_events[CE_CHANGE_OF_X] = FALSE;
   custom_element_change_events[CE_EXPLOSION_OF_X] = FALSE;
-  custom_element_change_events[CE_COUNT_AT_ZERO_OF_X] = FALSE;
+  custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE;
   custom_element_change_events[custom_element_change.other_action] =
     custom_element_change_events[CE_BY_OTHER_ACTION];
 
@@ -6519,6 +6611,16 @@ static void ModifyEditorCounterLimits(int counter_id, int min, int max)
   struct GadgetInfo *gi = level_editor_gadget[gadget_id];
 
   ModifyGadget(gi, GDI_NUMBER_MIN, min, GDI_NUMBER_MAX, max, GDI_END);
+
+  if (counter_id >= ED_COUNTER_ID_ELEMENT_VALUE1 &&
+      counter_id <= ED_COUNTER_ID_ELEMENT_VALUE4)
+  {
+    int gadget_id_up = counterbutton_info[counter_id].gadget_id_up;
+    struct GadgetInfo *gi_up = level_editor_gadget[gadget_id_up];
+
+    ModifyGadget(gi, GDI_TEXT_SIZE, (max < 10 ? 1 : 3), GDI_END);
+    ModifyGadget(gi_up, GDI_X, gi->x + gi->width + ED_GADGET_DISTANCE,GDI_END);
+  }
 }
 
 static void ModifyEditorSelectboxValue(int selectbox_id, int new_value)
@@ -7394,23 +7496,8 @@ static void DrawPropertiesChange()
 {
   int i;
 
-  for (i = 0; action_arg_options[i].value != -1; i++)
-  {
-    if (action_arg_options[i].value == custom_element_change.action_type)
-    {
-      int mode = action_arg_options[i].mode;
-
-      ModifyEditorSelectboxOptions(ED_SELECTBOX_ID_ACTION_MODE,
-                                  action_arg_modes[mode]);
-      ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_MODE,
-                                custom_element_change.action_mode);
-
-      ModifyEditorSelectboxOptions(ED_SELECTBOX_ID_ACTION_ARG,
-                                  action_arg_options[i].options);
-      ModifyEditorSelectboxValue(ED_SELECTBOX_ID_ACTION_ARG,
-                                custom_element_change.action_arg);
-    }
-  }
+  /* needed to initially set selectbox options for special action options */
+  setSelectboxSpecialActionOptions();
 
   /* draw stickybutton gadget */
   MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
@@ -8656,6 +8743,7 @@ static void HandleTextAreaGadgets(struct GadgetInfo *gi)
 static void HandleSelectboxGadgets(struct GadgetInfo *gi)
 {
   int type_id = gi->custom_type_id;
+  int value_old = *selectbox_info[type_id].value;
   int value_new = selectbox_info[type_id].options[gi->selectbox.index].value;
 
   *selectbox_info[type_id].value = value_new;
@@ -8673,7 +8761,16 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi)
           (type_id == ED_SELECTBOX_ID_GROUP_CHOICE_MODE))
   {
     if (type_id == ED_SELECTBOX_ID_ACTION_TYPE)
+    {
+      /* when changing action type, reset action mode and action arg */
+      if (value_old != value_new)
+      {
+       custom_element_change.action_mode = -1;
+       custom_element_change.action_arg = -1;
+      }
+
       DrawPropertiesChange();
+    }
 
     CopyElementPropertiesToGame(properties_element);
 
index 121fdf133424bb1bcfb6720e5bc8a65b1a699b36..7ab17f2c5ed4d3d38050f74305db6936f2c2b98c 100644 (file)
@@ -42,7 +42,7 @@
 
 #define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x))
 #define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE)
-#define LEVEL_CHUNK_CUS4_SIZE(x) (48 + 48 + (x) * 48)
+#define LEVEL_CHUNK_CUS4_SIZE(x) (96 + (x) * 48)
 
 /* file identifier strings */
 #define LEVEL_COOKIE_TMPL      "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x"
@@ -450,79 +450,82 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     int element = i;
+    struct ElementInfo *ei = &element_info[element];
 
     /* never initialize clipboard elements after the very first time */
     if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized)
       continue;
 
-    setElementChangePages(&element_info[element], 1);
-    setElementChangeInfoToDefaults(element_info[element].change);
+    setElementChangePages(ei, 1);
+    setElementChangeInfoToDefaults(ei->change);
 
     if (IS_CUSTOM_ELEMENT(element) ||
        IS_GROUP_ELEMENT(element) ||
        IS_INTERNAL_ELEMENT(element))
     {
       for (j = 0; j < MAX_ELEMENT_NAME_LEN + 1; j++)
-       element_info[element].description[j] = '\0';
+       ei->description[j] = '\0';
 
-      if (element_info[element].custom_description != NULL)
-       strncpy(element_info[element].description,
-               element_info[element].custom_description,MAX_ELEMENT_NAME_LEN);
+      if (ei->custom_description != NULL)
+       strncpy(ei->description, ei->custom_description,MAX_ELEMENT_NAME_LEN);
       else
-       strcpy(element_info[element].description,
-              element_info[element].editor_description);
+       strcpy(ei->description, ei->editor_description);
 
-      element_info[element].use_gfx_element = FALSE;
-      element_info[element].gfx_element = EL_EMPTY_SPACE;
+      ei->use_gfx_element = FALSE;
+      ei->gfx_element = EL_EMPTY_SPACE;
 
-      element_info[element].modified_settings = FALSE;
+      ei->modified_settings = FALSE;
     }
 
     if (IS_CUSTOM_ELEMENT(element) ||
        IS_INTERNAL_ELEMENT(element))
     {
-      element_info[element].access_direction = MV_ALL_DIRECTIONS;
+      ei->access_direction = MV_ALL_DIRECTIONS;
 
-      element_info[element].collect_score_initial = 10;        /* special default */
-      element_info[element].collect_count_initial = 1; /* special default */
+      ei->collect_score_initial = 10;  /* special default */
+      ei->collect_count_initial = 1;   /* special default */
 
-      element_info[element].push_delay_fixed = -1;     /* initialize later */
-      element_info[element].push_delay_random = -1;    /* initialize later */
-      element_info[element].drop_delay_fixed = 0;
-      element_info[element].drop_delay_random = 0;
-      element_info[element].move_delay_fixed = 0;
-      element_info[element].move_delay_random = 0;
+      ei->ce_value_fixed_initial = 0;
+      ei->ce_value_random_initial = 0;
+      ei->use_last_ce_value = FALSE;
 
-      element_info[element].move_pattern = MV_ALL_DIRECTIONS;
-      element_info[element].move_direction_initial = MV_START_AUTOMATIC;
-      element_info[element].move_stepsize = TILEX / 8;
+      ei->push_delay_fixed = -1;       /* initialize later */
+      ei->push_delay_random = -1;      /* initialize later */
+      ei->drop_delay_fixed = 0;
+      ei->drop_delay_random = 0;
+      ei->move_delay_fixed = 0;
+      ei->move_delay_random = 0;
 
-      element_info[element].move_enter_element = EL_EMPTY_SPACE;
-      element_info[element].move_leave_element = EL_EMPTY_SPACE;
-      element_info[element].move_leave_type = LEAVE_TYPE_UNLIMITED;
+      ei->move_pattern = MV_ALL_DIRECTIONS;
+      ei->move_direction_initial = MV_START_AUTOMATIC;
+      ei->move_stepsize = TILEX / 8;
 
-      element_info[element].slippery_type = SLIPPERY_ANY_RANDOM;
+      ei->move_enter_element = EL_EMPTY_SPACE;
+      ei->move_leave_element = EL_EMPTY_SPACE;
+      ei->move_leave_type = LEAVE_TYPE_UNLIMITED;
 
-      element_info[element].explosion_type = EXPLODES_3X3;
-      element_info[element].explosion_delay = 16;
-      element_info[element].ignition_delay = 8;
+      ei->slippery_type = SLIPPERY_ANY_RANDOM;
+
+      ei->explosion_type = EXPLODES_3X3;
+      ei->explosion_delay = 16;
+      ei->ignition_delay = 8;
 
       for (x = 0; x < 3; x++)
        for (y = 0; y < 3; y++)
-         element_info[element].content.e[x][y] = EL_EMPTY_SPACE;
+         ei->content.e[x][y] = EL_EMPTY_SPACE;
 
-      element_info[element].access_type = 0;
-      element_info[element].access_layer = 0;
-      element_info[element].access_protected = 0;
-      element_info[element].walk_to_action = 0;
-      element_info[element].smash_targets = 0;
-      element_info[element].deadliness = 0;
+      ei->access_type = 0;
+      ei->access_layer = 0;
+      ei->access_protected = 0;
+      ei->walk_to_action = 0;
+      ei->smash_targets = 0;
+      ei->deadliness = 0;
 
-      element_info[element].can_explode_by_fire = FALSE;
-      element_info[element].can_explode_smashed = FALSE;
-      element_info[element].can_explode_impact = FALSE;
+      ei->can_explode_by_fire = FALSE;
+      ei->can_explode_smashed = FALSE;
+      ei->can_explode_impact = FALSE;
 
-      element_info[element].current_change_page = 0;
+      ei->current_change_page = 0;
 
       /* start with no properties at all */
       for (j = 0; j < NUM_EP_BITFIELDS; j++)
@@ -535,18 +538,21 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
     if (IS_GROUP_ELEMENT(element) ||
        IS_INTERNAL_ELEMENT(element))
     {
+      struct ElementGroupInfo *group;
+
       /* initialize memory for list of elements in group */
-      if (element_info[element].group == NULL)
-       element_info[element].group =
-         checked_malloc(sizeof(struct ElementGroupInfo));
+      if (ei->group == NULL)
+       ei->group = checked_malloc(sizeof(struct ElementGroupInfo));
+
+      group = ei->group;
 
       for (j = 0; j < MAX_ELEMENTS_IN_GROUP; j++)
-       element_info[element].group->element[j] = EL_EMPTY_SPACE;
+       group->element[j] = EL_EMPTY_SPACE;
 
       /* default: only one element in group */
-      element_info[element].group->num_elements = 1;
+      group->num_elements = 1;
 
-      element_info[element].group->choice_mode = ANIM_RANDOM;
+      group->choice_mode = ANIM_RANDOM;
     }
   }
 
@@ -1231,6 +1237,7 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
   for (i = 0; i < num_changed_custom_elements; i++)
   {
     int element = getFile16BitBE(file);
+    struct ElementInfo *ei = &element_info[element];
     unsigned long event_bits;
 
     if (!IS_CUSTOM_ELEMENT(element))
@@ -1241,70 +1248,66 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
     }
 
     for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++)
-      element_info[element].description[j] = getFile8Bit(file);
-    element_info[element].description[MAX_ELEMENT_NAME_LEN] = 0;
+      ei->description[j] = getFile8Bit(file);
+    ei->description[MAX_ELEMENT_NAME_LEN] = 0;
 
     Properties[element][EP_BITFIELD_BASE] = getFile32BitBE(file);
 
     /* some free bytes for future properties and padding */
     ReadUnusedBytesFromFile(file, 7);
 
-    element_info[element].use_gfx_element = getFile8Bit(file);
-    element_info[element].gfx_element =
-      getMappedElement(getFile16BitBE(file));
+    ei->use_gfx_element = getFile8Bit(file);
+    ei->gfx_element = getMappedElement(getFile16BitBE(file));
 
-    element_info[element].collect_score_initial = getFile8Bit(file);
-    element_info[element].collect_count_initial = getFile8Bit(file);
+    ei->collect_score_initial = getFile8Bit(file);
+    ei->collect_count_initial = getFile8Bit(file);
 
-    element_info[element].push_delay_fixed = getFile16BitBE(file);
-    element_info[element].push_delay_random = getFile16BitBE(file);
-    element_info[element].move_delay_fixed = getFile16BitBE(file);
-    element_info[element].move_delay_random = getFile16BitBE(file);
+    ei->push_delay_fixed = getFile16BitBE(file);
+    ei->push_delay_random = getFile16BitBE(file);
+    ei->move_delay_fixed = getFile16BitBE(file);
+    ei->move_delay_random = getFile16BitBE(file);
 
-    element_info[element].move_pattern = getFile16BitBE(file);
-    element_info[element].move_direction_initial = getFile8Bit(file);
-    element_info[element].move_stepsize = getFile8Bit(file);
+    ei->move_pattern = getFile16BitBE(file);
+    ei->move_direction_initial = getFile8Bit(file);
+    ei->move_stepsize = getFile8Bit(file);
 
     for (y = 0; y < 3; y++)
       for (x = 0; x < 3; x++)
-       element_info[element].content.e[x][y] =
-         getMappedElement(getFile16BitBE(file));
+       ei->content.e[x][y] = getMappedElement(getFile16BitBE(file));
 
     event_bits = getFile32BitBE(file);
     for (j = 0; j < NUM_CHANGE_EVENTS; j++)
       if (event_bits & (1 << j))
-       element_info[element].change->has_event[j] = TRUE;
+       ei->change->has_event[j] = TRUE;
 
-    element_info[element].change->target_element =
-      getMappedElement(getFile16BitBE(file));
+    ei->change->target_element = getMappedElement(getFile16BitBE(file));
 
-    element_info[element].change->delay_fixed = getFile16BitBE(file);
-    element_info[element].change->delay_random = getFile16BitBE(file);
-    element_info[element].change->delay_frames = getFile16BitBE(file);
+    ei->change->delay_fixed = getFile16BitBE(file);
+    ei->change->delay_random = getFile16BitBE(file);
+    ei->change->delay_frames = getFile16BitBE(file);
 
-    element_info[element].change->trigger_element =
-      getMappedElement(getFile16BitBE(file));
+    ei->change->trigger_element = getMappedElement(getFile16BitBE(file));
 
-    element_info[element].change->explode = getFile8Bit(file);
-    element_info[element].change->use_target_content = getFile8Bit(file);
-    element_info[element].change->only_if_complete = getFile8Bit(file);
-    element_info[element].change->use_random_replace = getFile8Bit(file);
+    ei->change->explode = getFile8Bit(file);
+    ei->change->use_target_content = getFile8Bit(file);
+    ei->change->only_if_complete = getFile8Bit(file);
+    ei->change->use_random_replace = getFile8Bit(file);
 
-    element_info[element].change->random_percentage = getFile8Bit(file);
-    element_info[element].change->replace_when = getFile8Bit(file);
+    ei->change->random_percentage = getFile8Bit(file);
+    ei->change->replace_when = getFile8Bit(file);
 
     for (y = 0; y < 3; y++)
       for (x = 0; x < 3; x++)
-       element_info[element].change->target_content.e[x][y] =
+       ei->change->target_content.e[x][y] =
          getMappedElement(getFile16BitBE(file));
 
-    element_info[element].slippery_type = getFile8Bit(file);
+    ei->slippery_type = getFile8Bit(file);
 
     /* some free bytes for future properties and padding */
     ReadUnusedBytesFromFile(file, LEVEL_CPART_CUS3_UNUSED);
 
     /* mark that this custom element has been modified */
-    element_info[element].modified_settings = TRUE;
+    ei->modified_settings = TRUE;
   }
 
   return chunk_size;
@@ -1317,6 +1320,8 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   int element;
   int i, j, x, y;
 
+  /* ---------- custom element base property values (96 bytes) ------------- */
+
   element = getFile16BitBE(file);
 
   if (!IS_CUSTOM_ELEMENT(element))
@@ -1338,17 +1343,16 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
 
   ei->num_change_pages = getFile8Bit(file);
 
-  /* some free bytes for future base property values and padding */
-  ReadUnusedBytesFromFile(file, 5);
-
   chunk_size_expected = LEVEL_CHUNK_CUS4_SIZE(ei->num_change_pages);
   if (chunk_size_expected != chunk_size)
   {
-    ReadUnusedBytesFromFile(file, chunk_size - 48);
+    ReadUnusedBytesFromFile(file, chunk_size - 43);
     return chunk_size_expected;
   }
 
-  /* read custom property values */
+  ei->ce_value_fixed_initial = getFile16BitBE(file);
+  ei->ce_value_random_initial = getFile16BitBE(file);
+  ei->use_last_ce_value = getFile8Bit(file);
 
   ei->use_gfx_element = getFile8Bit(file);
   ei->gfx_element = getMappedElement(getFile16BitBE(file));
@@ -1390,7 +1394,7 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   /* some free bytes for future custom property values and padding */
   ReadUnusedBytesFromFile(file, 1);
 
-  /* read change property values */
+  /* ---------- change page property values (48 bytes) --------------------- */
 
   setElementChangePages(ei, ei->num_change_pages);
 
@@ -2876,7 +2880,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
       int element = EL_CUSTOM_START + i;
 
       /* order of checking and copying events to be mapped is important */
-      for (j = CE_BY_OTHER_ACTION; j >= CE_COUNT_AT_ZERO; j--)
+      for (j = CE_BY_OTHER_ACTION; j >= CE_VALUE_GETS_ZERO; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 2))
        {
@@ -3290,63 +3294,64 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
   for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
+    struct ElementInfo *ei = &element_info[element];
 
-    if (element_info[element].modified_settings)
+    if (ei->modified_settings)
     {
       if (check < num_changed_custom_elements)
       {
        putFile16BitBE(file, element);
 
        for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++)
-         putFile8Bit(file, element_info[element].description[j]);
+         putFile8Bit(file, ei->description[j]);
 
        putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
 
        /* some free bytes for future properties and padding */
        WriteUnusedBytesToFile(file, 7);
 
-       putFile8Bit(file, element_info[element].use_gfx_element);
-       putFile16BitBE(file, element_info[element].gfx_element);
+       putFile8Bit(file, ei->use_gfx_element);
+       putFile16BitBE(file, ei->gfx_element);
 
-       putFile8Bit(file, element_info[element].collect_score_initial);
-       putFile8Bit(file, element_info[element].collect_count_initial);
+       putFile8Bit(file, ei->collect_score_initial);
+       putFile8Bit(file, ei->collect_count_initial);
 
-       putFile16BitBE(file, element_info[element].push_delay_fixed);
-       putFile16BitBE(file, element_info[element].push_delay_random);
-       putFile16BitBE(file, element_info[element].move_delay_fixed);
-       putFile16BitBE(file, element_info[element].move_delay_random);
+       putFile16BitBE(file, ei->push_delay_fixed);
+       putFile16BitBE(file, ei->push_delay_random);
+       putFile16BitBE(file, ei->move_delay_fixed);
+       putFile16BitBE(file, ei->move_delay_random);
 
-       putFile16BitBE(file, element_info[element].move_pattern);
-       putFile8Bit(file, element_info[element].move_direction_initial);
-       putFile8Bit(file, element_info[element].move_stepsize);
+       putFile16BitBE(file, ei->move_pattern);
+       putFile8Bit(file, ei->move_direction_initial);
+       putFile8Bit(file, ei->move_stepsize);
 
        for (y = 0; y < 3; y++)
          for (x = 0; x < 3; x++)
-           putFile16BitBE(file, element_info[element].content.e[x][y]);
+           putFile16BitBE(file, ei->content.e[x][y]);
 
-       putFile32BitBE(file, element_info[element].change->events);
+       putFile32BitBE(file, ei->change->events);
 
-       putFile16BitBE(file, element_info[element].change->target_element);
+       putFile16BitBE(file, ei->change->target_element);
 
-       putFile16BitBE(file, element_info[element].change->delay_fixed);
-       putFile16BitBE(file, element_info[element].change->delay_random);
-       putFile16BitBE(file, element_info[element].change->delay_frames);
+       putFile16BitBE(file, ei->change->delay_fixed);
+       putFile16BitBE(file, ei->change->delay_random);
+       putFile16BitBE(file, ei->change->delay_frames);
 
-       putFile16BitBE(file, element_info[element].change->trigger_element);
+       putFile16BitBE(file, ei->change->trigger_element);
 
-       putFile8Bit(file, element_info[element].change->explode);
-       putFile8Bit(file, element_info[element].change->use_target_content);
-       putFile8Bit(file, element_info[element].change->only_if_complete);
-       putFile8Bit(file, element_info[element].change->use_random_replace);
+       putFile8Bit(file, ei->change->explode);
+       putFile8Bit(file, ei->change->use_target_content);
+       putFile8Bit(file, ei->change->only_if_complete);
+       putFile8Bit(file, ei->change->use_random_replace);
 
-       putFile8Bit(file, element_info[element].change->random_percentage);
-       putFile8Bit(file, element_info[element].change->replace_when);
+       putFile8Bit(file, ei->change->random_percentage);
+       putFile8Bit(file, ei->change->replace_when);
 
        for (y = 0; y < 3; y++)
          for (x = 0; x < 3; x++)
-           putFile16BitBE(file,element_info[element].change->content.e[x][y]);
+           putFile16BitBE(file, ei->change->content.e[x][y]);
 
-       putFile8Bit(file, element_info[element].slippery_type);
+       putFile8Bit(file, ei->slippery_type);
 
        /* some free bytes for future properties and padding */
        WriteUnusedBytesToFile(file, LEVEL_CPART_CUS3_UNUSED);
@@ -3366,6 +3371,8 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   struct ElementInfo *ei = &element_info[element];
   int i, j, x, y;
 
+  /* ---------- custom element base property values (96 bytes) ------------- */
+
   putFile16BitBE(file, element);
 
   for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
@@ -3376,10 +3383,9 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 
   putFile8Bit(file, ei->num_change_pages);
 
-  /* some free bytes for future base property values and padding */
-  WriteUnusedBytesToFile(file, 5);
-
-  /* write custom property values */
+  putFile16BitBE(file, ei->ce_value_fixed_initial);
+  putFile16BitBE(file, ei->ce_value_random_initial);
+  putFile8Bit(file, ei->use_last_ce_value);
 
   putFile8Bit(file, ei->use_gfx_element);
   putFile16BitBE(file, ei->gfx_element);
@@ -3421,7 +3427,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   /* some free bytes for future custom property values and padding */
   WriteUnusedBytesToFile(file, 1);
 
-  /* write change property values */
+  /* ---------- change page property values (48 bytes) --------------------- */
 
   for (i = 0; i < ei->num_change_pages; i++)
   {
index 07585bb6404e1d8709026d50ed3716d40a47ec7c..440016b024f5770cc63b49452494bc1408e1a881 100644 (file)
@@ -28,7 +28,7 @@
 #define USE_NEW_STUFF                  (                         1)
 
 #define USE_NEW_SP_SLIPPERY            (USE_NEW_STUFF          * 1)
-#define USE_NEW_COLLECT_COUNT          (USE_NEW_STUFF          * 1)
+#define USE_NEW_CUSTOM_VALUE           (USE_NEW_STUFF          * 1)
 #define USE_NEW_PLAYER_ANIM            (USE_NEW_STUFF          * 1)
 #define USE_NEW_ALL_SLIPPERY           (USE_NEW_STUFF          * 1)
 #define USE_NEW_PLAYER_SPEED           (USE_NEW_STUFF          * 1)
                                 RND(element_info[e].move_delay_random))
 #define GET_MAX_MOVE_DELAY(e)  (   (element_info[e].move_delay_fixed) + \
                                    (element_info[e].move_delay_random))
+#define GET_NEW_CUSTOM_VALUE(e)        (   (element_info[e].ce_value_fixed_initial) +\
+                                RND(element_info[e].ce_value_random_initial))
 #define GET_CHANGE_DELAY(c)    (   ((c)->delay_fixed  * (c)->delay_frames) + \
                                 RND((c)->delay_random * (c)->delay_frames))
 
@@ -257,15 +259,15 @@ static void TestIfElementSmashesCustomElement(int, int, int);
 
 static void ChangeElement(int, int, int);
 
-static boolean CheckTriggeredElementChangeExt(int, int, int,int,int);
-#define CheckTriggeredElementChange(e, ev)                             \
-       CheckTriggeredElementChangeExt(e, ev, CH_PLAYER_ANY, CH_SIDE_ANY, -1)
-#define CheckTriggeredElementChangeByPlayer(e, ev, p, s)               \
-       CheckTriggeredElementChangeExt(e, ev, p, s, -1)
-#define CheckTriggeredElementChangeBySide(e, ev, s)                    \
-       CheckTriggeredElementChangeExt(e, ev, CH_PLAYER_ANY, s, -1)
-#define CheckTriggeredElementChangeByPage(e, ev, p)                    \
-       CheckTriggeredElementChangeExt(e, ev, CH_PLAYER_ANY, CH_SIDE_ANY, p)
+static boolean CheckTriggeredElementChangeExt(int, int, int, int, int,int,int);
+#define CheckTriggeredElementChange(x, y, e, ev)                       \
+       CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY,CH_SIDE_ANY, -1)
+#define CheckTriggeredElementChangeByPlayer(x, y, e, ev, p, s)         \
+       CheckTriggeredElementChangeExt(x, y, e, ev, p, s, -1)
+#define CheckTriggeredElementChangeBySide(x, y, e, ev, s)              \
+       CheckTriggeredElementChangeExt(x, y, e, ev, CH_PLAYER_ANY, s, -1)
+#define CheckTriggeredElementChangeByPage(x, y, e, ev, p)              \
+       CheckTriggeredElementChangeExt(x,y,e,ev, CH_PLAYER_ANY, CH_SIDE_ANY, p)
 
 static boolean CheckElementChangeExt(int, int, int, int, int, int, int);
 #define CheckElementChange(x, y, e, te, ev)                            \
@@ -917,8 +919,14 @@ static void InitField(int x, int y, boolean init_game)
       break;
   }
 
-#if USE_NEW_COLLECT_COUNT
-  Count[x][y] = element_info[Feld[x][y]].collect_count_initial;
+#if USE_NEW_CUSTOM_VALUE
+
+#if 1
+  CustomValue[x][y] = GET_NEW_CUSTOM_VALUE(Feld[x][y]);
+#else
+  CustomValue[x][y] = element_info[Feld[x][y]].custom_value_initial;
+#endif
+
 #endif
 }
 
@@ -1321,6 +1329,7 @@ static void InitGameEngine()
       ei->change_page[j].actual_trigger_element = EL_EMPTY;
       ei->change_page[j].actual_trigger_player = EL_PLAYER_1;
       ei->change_page[j].actual_trigger_side = CH_SIDE_NONE;
+      ei->change_page[j].actual_trigger_ce_value = 0;
     }
   }
 
@@ -1667,8 +1676,8 @@ void InitGame()
       MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
       ChangeDelay[x][y] = 0;
       ChangePage[x][y] = -1;
-#if USE_NEW_COLLECT_COUNT
-      Count[x][y] = 0;         /* initialized in InitField() */
+#if USE_NEW_CUSTOM_VALUE
+      CustomValue[x][y] = 0;           /* initialized in InitField() */
 #endif
       Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0;
       AmoebaNr[x][y] = 0;
@@ -2535,8 +2544,8 @@ void InitMovingField(int x, int y, int direction)
 
     MovDir[newx][newy] = MovDir[x][y];
 
-#if USE_NEW_COLLECT_COUNT
-    Count[newx][newy] = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+    CustomValue[newx][newy] = CustomValue[x][y];
 #endif
 
     GfxFrame[newx][newy] = GfxFrame[x][y];
@@ -2620,8 +2629,8 @@ static void RemoveField(int x, int y)
   MovDir[x][y] = 0;
   MovDelay[x][y] = 0;
 
-#if USE_NEW_COLLECT_COUNT
-  Count[x][y] = 0;
+#if USE_NEW_CUSTOM_VALUE
+  CustomValue[x][y] = 0;
 #endif
 
   AmoebaNr[x][y] = 0;
@@ -2892,7 +2901,8 @@ void RelocatePlayer(int jx, int jy, int el_player_raw)
                               CE_LEFT_BY_PLAYER,
                               player->index_bit, leave_side);
 
-  CheckTriggeredElementChangeByPlayer(old_element, CE_PLAYER_LEAVES_X,
+  CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
+                                     CE_PLAYER_LEAVES_X,
                                      player->index_bit, leave_side);
 
   Feld[jx][jy] = el_player;
@@ -2914,7 +2924,7 @@ void RelocatePlayer(int jx, int jy, int el_player_raw)
     CheckElementChangeByPlayer(jx, jy, element, CE_ENTERED_BY_PLAYER,
                               player->index_bit, enter_side);
 
-  CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_ENTERS_X,
+  CheckTriggeredElementChangeByPlayer(jx, jy, element, CE_PLAYER_ENTERS_X,
                                      player->index_bit, enter_side);
 }
 
@@ -3210,8 +3220,8 @@ void Explode(int ex, int ey, int phase, int mode)
     ChangeDelay[x][y] = 0;
     ChangePage[x][y] = -1;
 
-#if USE_NEW_COLLECT_COUNT
-    Count[x][y] = 0;
+#if USE_NEW_CUSTOM_VALUE
+    CustomValue[x][y] = 0;
 #endif
 
     InitField_WithBug2(x, y, FALSE);
@@ -3357,7 +3367,7 @@ void Bang(int x, int y)
       break;
   }
 
-  CheckTriggeredElementChange(element, CE_EXPLOSION_OF_X);
+  CheckTriggeredElementChange(x, y, element, CE_EXPLOSION_OF_X);
 }
 
 void SplashAcid(int x, int y)
@@ -3886,7 +3896,7 @@ void Impact(int x, int y)
 
          CheckElementChangeBySide(x, y + 1, smashed, element,
                                   CE_SWITCHED, CH_SIDE_TOP);
-         CheckTriggeredElementChangeBySide(smashed, CE_SWITCH_OF_X,
+         CheckTriggeredElementChangeBySide(x, y + 1, smashed, CE_SWITCH_OF_X,
                                            CH_SIDE_TOP);
        }
       }
@@ -5453,7 +5463,7 @@ void ContinueMoving(int x, int y)
       Feld[x][y] = EL_MAGIC_WALL_DEAD;
     element = Feld[newx][newy] = Store[x][y];
 
-#if USE_NEW_COLLECT_COUNT
+#if USE_NEW_CUSTOM_VALUE
     InitField(newx, newy, FALSE);
 #endif
   }
@@ -5471,7 +5481,7 @@ void ContinueMoving(int x, int y)
       Feld[x][y] = EL_BD_MAGIC_WALL_DEAD;
     element = Feld[newx][newy] = Store[x][y];
 
-#if USE_NEW_COLLECT_COUNT
+#if USE_NEW_CUSTOM_VALUE
     InitField(newx, newy, FALSE);
 #endif
   }
@@ -5506,8 +5516,8 @@ void ContinueMoving(int x, int y)
     Changed[newx][newy]     = Changed[x][y];
     ChangeEvent[newx][newy] = ChangeEvent[x][y];
 
-#if USE_NEW_COLLECT_COUNT
-    Count[newx][newy] = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+    CustomValue[newx][newy] = CustomValue[x][y];
 #endif
   }
 
@@ -5516,8 +5526,8 @@ void ContinueMoving(int x, int y)
   Changed[x][y] = FALSE;
   ChangeEvent[x][y] = -1;
 
-#if USE_NEW_COLLECT_COUNT
-  Count[x][y] = 0;
+#if USE_NEW_CUSTOM_VALUE
+  CustomValue[x][y] = 0;
 #endif
 
   /* copy animation control values to new field */
@@ -5619,7 +5629,7 @@ void ContinueMoving(int x, int y)
 
     CheckElementChangeByPlayer(newx, newy, element, CE_PUSHED_BY_PLAYER,
                               player->index_bit, dig_side);
-    CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PUSHES_X,
+    CheckTriggeredElementChangeByPlayer(newx,newy, element, CE_PLAYER_PUSHES_X,
                                        player->index_bit, dig_side);
   }
 
@@ -6560,20 +6570,24 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
 
   int action_arg_number_max =
     (action_type == CA_SET_PLAYER_SPEED ? MOVE_STEPSIZE_MAX :
-     action_type == CA_SET_GEMS ? 999 :
-     action_type == CA_SET_TIME ? 9999 :
-     action_type == CA_SET_SCORE ? 99999 :
+     action_type == CA_SET_LEVEL_GEMS ? 999 :
+     action_type == CA_SET_LEVEL_TIME ? 9999 :
+     action_type == CA_SET_LEVEL_SCORE ? 99999 :
      action_type == CA_SET_CE_SCORE ? 9999 :
-     action_type == CA_SET_CE_COUNT ? 9999 :
+     action_type == CA_SET_CE_VALUE ? 9999 :
      CA_ARG_MAX);
 
   int action_arg_number_reset =
     (action_type == CA_SET_PLAYER_SPEED ? TILEX/game.initial_move_delay_value :
-     action_type == CA_SET_GEMS ? level.gems_needed :
-     action_type == CA_SET_TIME ? level.time :
-     action_type == CA_SET_SCORE ? 0 :
+     action_type == CA_SET_LEVEL_GEMS ? level.gems_needed :
+     action_type == CA_SET_LEVEL_TIME ? level.time :
+     action_type == CA_SET_LEVEL_SCORE ? 0 :
      action_type == CA_SET_CE_SCORE ? 0 :
-     action_type == CA_SET_CE_COUNT ? ei->collect_count_initial :
+#if 1
+     action_type == CA_SET_CE_VALUE ? GET_NEW_CUSTOM_VALUE(element) :
+#else
+     action_type == CA_SET_CE_VALUE ? ei->custom_value_initial :
+#endif
      0);
 
   int action_arg_number =
@@ -6585,20 +6599,22 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
      action_arg == CA_ARG_NUMBER_MAX ? action_arg_number_max :
      action_arg == CA_ARG_NUMBER_RESET ? action_arg_number_reset :
      action_arg == CA_ARG_NUMBER_CE_SCORE ? ei->collect_score :
-#if USE_NEW_COLLECT_COUNT
-     action_arg == CA_ARG_NUMBER_CE_COUNT ? Count[x][y] :
+#if USE_NEW_CUSTOM_VALUE
+     action_arg == CA_ARG_NUMBER_CE_VALUE ? CustomValue[x][y] :
 #else
-     action_arg == CA_ARG_NUMBER_CE_COUNT ? ei->collect_count_initial :
+     action_arg == CA_ARG_NUMBER_CE_VALUE ? ei->custom_value_initial :
 #endif
      action_arg == CA_ARG_NUMBER_CE_DELAY ? GET_CHANGE_DELAY(change) :
+     action_arg == CA_ARG_ELEMENT_TARGET ? GET_NEW_CUSTOM_VALUE(change->target_element) :
+     action_arg == CA_ARG_ELEMENT_TRIGGER ? change->actual_trigger_ce_value :
      -1);
 
   int action_arg_number_old =
-    (action_type == CA_SET_GEMS ? local_player->gems_still_needed :
-     action_type == CA_SET_TIME ? TimeLeft :
-     action_type == CA_SET_SCORE ? local_player->score :
+    (action_type == CA_SET_LEVEL_GEMS ? local_player->gems_still_needed :
+     action_type == CA_SET_LEVEL_TIME ? TimeLeft :
+     action_type == CA_SET_LEVEL_SCORE ? local_player->score :
      action_type == CA_SET_CE_SCORE ? ei->collect_score :
-     action_type == CA_SET_CE_COUNT ? Count[x][y] :
+     action_type == CA_SET_CE_VALUE ? CustomValue[x][y] :
      0);
 
   int action_arg_number_new =
@@ -6691,7 +6707,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
       break;
     }
 
-    case CA_DEL_KEY:
+    case CA_REMOVE_KEY:
     {
       int element = getSpecialActionElement(action_arg_element,
                                            action_arg_number, EL_KEY_1);
@@ -6714,72 +6730,6 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
       break;
     }
 
-    case CA_SET_GEMS:
-    {
-      local_player->gems_still_needed = action_arg_number_new;
-
-      DrawGameValue_Emeralds(local_player->gems_still_needed);
-
-      break;
-    }
-
-    case CA_SET_TIME:
-    {
-      if (level.time > 0)      /* only modify limited time value */
-      {
-       TimeLeft = action_arg_number_new;
-
-       DrawGameValue_Time(TimeLeft);
-
-       if (!TimeLeft && setup.time_limit)
-         for (i = 0; i < MAX_PLAYERS; i++)
-           KillPlayer(&stored_player[i]);
-      }
-
-      break;
-    }
-
-    case CA_SET_SCORE:
-    {
-      local_player->score = action_arg_number_new;
-
-      DrawGameValue_Score(local_player->score);
-
-      break;
-    }
-
-    case CA_SET_CE_SCORE:
-    {
-      ei->collect_score = action_arg_number_new;
-
-      break;
-    }
-
-    case CA_SET_CE_COUNT:
-    {
-#if USE_NEW_COLLECT_COUNT
-      int count_last = Count[x][y];
-
-      Count[x][y] = action_arg_number_new;
-
-#if 0
-      printf("::: Count == %d\n", Count[x][y]);
-#endif
-
-      if (Count[x][y] == 0 && count_last > 0)
-      {
-#if 0
-       printf("::: CE_COUNT_AT_ZERO\n");
-#endif
-
-       CheckElementChange(x, y, element, EL_UNDEFINED, CE_COUNT_AT_ZERO);
-       CheckTriggeredElementChange(element, CE_COUNT_AT_ZERO_OF_X);
-      }
-#endif
-
-      break;
-    }
-
 #if 1
     case CA_SET_PLAYER_SPEED:
     {
@@ -6881,6 +6831,72 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
       break;
     }
 
+    case CA_SET_LEVEL_GEMS:
+    {
+      local_player->gems_still_needed = action_arg_number_new;
+
+      DrawGameValue_Emeralds(local_player->gems_still_needed);
+
+      break;
+    }
+
+    case CA_SET_LEVEL_TIME:
+    {
+      if (level.time > 0)      /* only modify limited time value */
+      {
+       TimeLeft = action_arg_number_new;
+
+       DrawGameValue_Time(TimeLeft);
+
+       if (!TimeLeft && setup.time_limit)
+         for (i = 0; i < MAX_PLAYERS; i++)
+           KillPlayer(&stored_player[i]);
+      }
+
+      break;
+    }
+
+    case CA_SET_LEVEL_SCORE:
+    {
+      local_player->score = action_arg_number_new;
+
+      DrawGameValue_Score(local_player->score);
+
+      break;
+    }
+
+    case CA_SET_CE_SCORE:
+    {
+      ei->collect_score = action_arg_number_new;
+
+      break;
+    }
+
+    case CA_SET_CE_VALUE:
+    {
+#if USE_NEW_CUSTOM_VALUE
+      int last_custom_value = CustomValue[x][y];
+
+      CustomValue[x][y] = action_arg_number_new;
+
+#if 0
+      printf("::: Count == %d\n", CustomValue[x][y]);
+#endif
+
+      if (CustomValue[x][y] == 0 && last_custom_value > 0)
+      {
+#if 0
+       printf("::: CE_VALUE_GETS_ZERO\n");
+#endif
+
+       CheckElementChange(x, y, element, EL_UNDEFINED, CE_VALUE_GETS_ZERO);
+       CheckTriggeredElementChange(x, y, element, CE_VALUE_GETS_ZERO_OF_X);
+      }
+#endif
+
+      break;
+    }
+
 #if 0
     case CA_SET_DYNABOMB_NUMBER:
     {
@@ -6979,6 +6995,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
     change->actual_trigger_element = EL_EMPTY;
     change->actual_trigger_player = EL_PLAYER_1;
     change->actual_trigger_side = CH_SIDE_NONE;
+    change->actual_trigger_ce_value = 0;
   }
 
 #if 1
@@ -7123,7 +7140,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
   }
 
   /* this uses direct change before indirect change */
-  CheckTriggeredElementChangeByPage(old_element, CE_CHANGE_OF_X, page);
+  CheckTriggeredElementChangeByPage(x, y, old_element, CE_CHANGE_OF_X, page);
 
   return TRUE;
 }
@@ -7301,7 +7318,8 @@ static void ChangeElement(int x, int y, int page)
 
 #endif
 
-static boolean CheckTriggeredElementChangeExt(int trigger_element,
+static boolean CheckTriggeredElementChangeExt(int x, int y,
+                                             int trigger_element,
                                              int trigger_event,
                                              int trigger_player,
                                              int trigger_side,
@@ -7338,6 +7356,7 @@ static boolean CheckTriggeredElementChangeExt(int trigger_element,
        change->actual_trigger_element = trigger_element;
        change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player);
        change->actual_trigger_side = trigger_side;
+       change->actual_trigger_ce_value = CustomValue[x][y];
 
        if ((change->can_change && !change_done) || change->has_action)
        {
@@ -7424,6 +7443,7 @@ static boolean CheckElementChangeExt(int x, int y,
       change->actual_trigger_element = trigger_element;
       change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player);
       change->actual_trigger_side = trigger_side;
+      change->actual_trigger_ce_value = CustomValue[x][y];
 
       if (change->can_change && !change_done)
       {
@@ -8820,14 +8840,16 @@ void ScrollPlayer(struct PlayerInfo *player, int mode)
                                   CE_LEFT_BY_PLAYER,
                                   player->index_bit, leave_side);
 
-      CheckTriggeredElementChangeByPlayer(old_element, CE_PLAYER_LEAVES_X,
+      CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
+                                         CE_PLAYER_LEAVES_X,
                                          player->index_bit, leave_side);
 
       if (IS_CUSTOM_ELEMENT(new_element))
        CheckElementChangeByPlayer(jx, jy, new_element, CE_ENTERED_BY_PLAYER,
                                   player->index_bit, enter_side);
 
-      CheckTriggeredElementChangeByPlayer(new_element, CE_PLAYER_ENTERS_X,
+      CheckTriggeredElementChangeByPlayer(jx, jy, new_element,
+                                         CE_PLAYER_ENTERS_X,
                                          player->index_bit, enter_side);
     }
 
@@ -8955,7 +8977,8 @@ void TestIfPlayerTouchesCustomElement(int x, int y)
 
       CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
                                 player->index_bit, border_side);
-      CheckTriggeredElementChangeByPlayer(border_element, CE_PLAYER_TOUCHES_X,
+      CheckTriggeredElementChangeByPlayer(xx, yy, border_element,
+                                         CE_PLAYER_TOUCHES_X,
                                          player->index_bit, border_side);
     }
     else if (IS_PLAYER(xx, yy))
@@ -8970,7 +8993,8 @@ void TestIfPlayerTouchesCustomElement(int x, int y)
 
       CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
                                 player->index_bit, center_side);
-      CheckTriggeredElementChangeByPlayer(center_element, CE_PLAYER_TOUCHES_X,
+      CheckTriggeredElementChangeByPlayer(x, y, center_element,
+                                         CE_PLAYER_TOUCHES_X,
                                          player->index_bit, center_side);
       break;
     }
@@ -9528,18 +9552,24 @@ int DigField(struct PlayerInfo *player,
     return MF_NO_ACTION;       /* field has no opening in this direction */
 
   element = Feld[x][y];
-#if USE_NEW_COLLECT_COUNT
-  collect_count = Count[x][y];
+#if USE_NEW_CUSTOM_VALUE
+
+#if 1
+  collect_count = element_info[element].collect_count_initial;
+#else
+  collect_count = CustomValue[x][y];
+#endif
+
 #else
   collect_count = element_info[element].collect_count_initial;
 #endif
 
 #if 0
   if (element != EL_BLOCKED &&
-      Count[x][y] != element_info[element].collect_count_initial)
+      CustomValue[x][y] != element_info[element].collect_count_initial)
     printf("::: %d: %d != %d\n",
           element,
-          Count[x][y],
+          CustomValue[x][y],
           element_info[element].collect_count_initial);
 #endif
 
@@ -9648,7 +9678,7 @@ int DigField(struct PlayerInfo *player,
 
     PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
 
-    CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_DIGS_X,
+    CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X,
                                        player->index_bit, dig_side);
 
     if (mode == DF_SNAP)
@@ -9738,7 +9768,7 @@ int DigField(struct PlayerInfo *player,
     PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING);
 
     if (is_player)
-      CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_COLLECTS_X,
+      CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_COLLECTS_X,
                                          player->index_bit, dig_side);
 
     if (mode == DF_SNAP)
@@ -9871,7 +9901,7 @@ int DigField(struct PlayerInfo *player,
     {
       CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
                                 player->index_bit, dig_side);
-      CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PUSHES_X,
+      CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X,
                                          player->index_bit, dig_side);
     }
   }
@@ -9879,7 +9909,7 @@ int DigField(struct PlayerInfo *player,
   {
     if (PLAYER_SWITCHING(player, x, y))
     {
-      CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PRESSES_X,
+      CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
                                          player->index_bit, dig_side);
 
       return MF_ACTION;
@@ -9961,10 +9991,10 @@ int DigField(struct PlayerInfo *player,
       DrawLevelField(x, y);
     }
 
-    CheckTriggeredElementChangeByPlayer(element, CE_SWITCH_OF_X,
+    CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X,
                                        player->index_bit, dig_side);
 
-    CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PRESSES_X,
+    CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
                                        player->index_bit, dig_side);
 
     return MF_ACTION;
@@ -9979,13 +10009,13 @@ int DigField(struct PlayerInfo *player,
 
       CheckElementChangeByPlayer(x, y, element, CE_SWITCHED,
                                 player->index_bit, dig_side);
-      CheckTriggeredElementChangeByPlayer(element, CE_SWITCH_OF_X,
+      CheckTriggeredElementChangeByPlayer(x, y, element, CE_SWITCH_OF_X,
                                          player->index_bit, dig_side);
     }
 
     CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER,
                               player->index_bit, dig_side);
-    CheckTriggeredElementChangeByPlayer(element, CE_PLAYER_PRESSES_X,
+    CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
                                        player->index_bit, dig_side);
 
     return MF_NO_ACTION;
@@ -10154,7 +10184,8 @@ boolean DropElement(struct PlayerInfo *player)
 
     CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER,
                               player->index_bit, drop_side);
-    CheckTriggeredElementChangeByPlayer(new_element, CE_PLAYER_DROPS_X,
+    CheckTriggeredElementChangeByPlayer(dropx, dropy, new_element,
+                                       CE_PLAYER_DROPS_X,
                                        player->index_bit, drop_side);
 
     TestIfElementTouchesCustomElement(dropx, dropy);
index 6798042bcdd56eb43448ad2763a3892d14d3fe09..fbe001f882c98dd2a3b02fb29ba883dd145eb9dc 100644 (file)
@@ -43,7 +43,7 @@ short                 MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  ChangePage[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short                  Count[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short                  CustomValue[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
index d7bbde09ff305eb172cf629d22d7f221c431ef6b..e4b4f0d85f3207930b485ba2bea509aa0ca75c15 100644 (file)
 #define CE_PLAYER_PUSHES_X             13
 #define CE_PLAYER_COLLECTS_X           14
 #define CE_PLAYER_DROPS_X              15
-#define CE_COUNT_AT_ZERO               16
-#define CE_COUNT_AT_ZERO_OF_X          17
+#define CE_VALUE_GETS_ZERO             16
+#define CE_VALUE_GETS_ZERO_OF_X                17
 #define CE_BY_OTHER_ACTION             18
 #define CE_BY_DIRECT_ACTION            19
 #define CE_PLAYER_DIGS_X               20
 #define CA_RESTART_LEVEL               3
 #define CA_SHOW_ENVELOPE               4
 #define CA_ADD_KEY                     5
-#define CA_DEL_KEY                     6
-#define CA_SET_GEMS                    7
-#define CA_SET_TIME                    8
-#define CA_SET_SCORE                   9
-#define CA_SET_CE_SCORE                        10
-#define CA_SET_CE_COUNT                        11
-#define CA_SET_PLAYER_SPEED            12
-#define CA_SET_PLAYER_GRAVITY          13
-#define CA_SET_WIND_DIRECTION          14
+#define CA_REMOVE_KEY                  6
+#define CA_SET_PLAYER_SPEED            7
+#define CA_SET_PLAYER_GRAVITY          8
+#define CA_SET_WIND_DIRECTION          9
+#define CA_SET_LEVEL_GEMS              10
+#define CA_SET_LEVEL_TIME              11
+#define CA_SET_LEVEL_SCORE             12
+#define CA_SET_CE_SCORE                        13
+#define CA_SET_CE_VALUE                        14
 #if 0
 #define CA_SET_DYNABOMB_NUMBER         15
 #define CA_SET_DYNABOMB_SIZE           16
 #define CA_ARG_NUMBER_MAX              (CA_ARG_NUMBER + 1)
 #define CA_ARG_NUMBER_RESET            (CA_ARG_NUMBER + 2)
 #define CA_ARG_NUMBER_CE_SCORE         (CA_ARG_NUMBER + 3)
-#define CA_ARG_NUMBER_CE_COUNT         (CA_ARG_NUMBER + 4)
+#define CA_ARG_NUMBER_CE_VALUE         (CA_ARG_NUMBER + 4)
 #define CA_ARG_NUMBER_CE_DELAY         (CA_ARG_NUMBER + 5)
 #define CA_ARG_NUMBER_HEADLINE         (CA_ARG_NUMBER + 999)
 #define CA_ARG_ELEMENT                 12000
@@ -1953,8 +1953,9 @@ struct ElementChangeInfo
   void (*post_change_function)(int x, int y);
 
   short actual_trigger_element;        /* element that actually triggered change */
-  int actual_trigger_side;     /* el.side that actually triggered change */
+  int actual_trigger_side;     /* element side that triggered the change */
   int actual_trigger_player;   /* player which actually triggered change */
+  int actual_trigger_ce_value; /* CE value of element that triggered change */
 
   boolean can_change_or_has_action;    /* can_change | has_action */
 
@@ -2025,6 +2026,10 @@ struct ElementInfo
   int collect_score_initial;   /* initial score value for collecting */
   int collect_count_initial;   /* initial count value for collecting */
 
+  int ce_value_fixed_initial;  /* initial value for custom variable (fix) */
+  int ce_value_random_initial; /* initial value for custom variable (rnd) */
+  boolean use_last_ce_value;   /* use value from element before change */
+
   int push_delay_fixed;                /* constant delay before pushing */
   int push_delay_random;       /* additional random delay before pushing */
   int drop_delay_fixed;                /* constant delay after dropping */
@@ -2229,7 +2234,7 @@ extern short                      MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ChangePage[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short                   Count[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short                   CustomValue[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
index 502f8deac6bf774c7f0fb35986778bd073c7a0cf..e630cd18f7654c51546de9d6de66d5f33fdac2b1 100644 (file)
@@ -85,7 +85,7 @@ void DumpTile(int x, int y)
   printf("  MovDir:      %d\n", MovDir[x][y]);
   printf("  MovDelay:    %d\n", MovDelay[x][y]);
   printf("  ChangeDelay: %d\n", ChangeDelay[x][y]);
-  printf("  Count:       %d\n", Count[x][y]);
+  printf("  CustomValue: %d\n", CustomValue[x][y]);
   printf("  GfxElement:  %d\n", GfxElement[x][y]);
   printf("  GfxAction:   %d\n", GfxAction[x][y]);
   printf("  GfxFrame:    %d\n", GfxFrame[x][y]);