rnd-20030701-1-src
authorHolger Schemel <info@artsoft.org>
Tue, 1 Jul 2003 00:11:21 +0000 (02:11 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:42:27 +0000 (10:42 +0200)
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/main.h

index aca25e248d123ee436fc787a1a92bcd53e4e81ad..4f9a05d3d238a7a65e2a9c6b31c56188799c2c97 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-06-29 17:38]"
+#define COMPILE_DATE_STRING "[2003-07-01 01:49]"
index d4b4102a86ed28a7f9ab7b498065a9f49f4a980f..702fed4de857467554d1befc8ef071d7e7f142c3 100644 (file)
 #define ED_AREA_ELEM_CONTENT5_XPOS     (30 * MINI_TILEX + MINI_TILEX / 2)
 #define ED_AREA_ELEM_CONTENT5_YPOS     (ED_SETTINGS_YPOS(7) + \
                                         ED_GADGET_DISTANCE)
+/* extended custom change target */
+#define ED_AREA_ELEM_CONTENT6_XPOS     (29 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT6_YPOS     (ED_SETTINGS_YPOS(10) + \
+                                        ED_GADGET_DISTANCE - MINI_TILEY)
 
 /* values for random placement background drawing area */
 #define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX)
 #define GADGET_ID_LEVEL_RANDOM_DOWN    (GADGET_ID_COUNTER_FIRST + 9)
 #define GADGET_ID_LEVEL_RANDOM_TEXT    (GADGET_ID_COUNTER_FIRST + 10)
 #define GADGET_ID_LEVEL_RANDOM_UP      (GADGET_ID_COUNTER_FIRST + 11)
-#define GADGET_ID_LEVEL_COLLECT_DOWN   (GADGET_ID_COUNTER_FIRST + 12)
-#define GADGET_ID_LEVEL_COLLECT_TEXT   (GADGET_ID_COUNTER_FIRST + 13)
-#define GADGET_ID_LEVEL_COLLECT_UP     (GADGET_ID_COUNTER_FIRST + 14)
+#define GADGET_ID_LEVEL_GEMSLIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 12)
+#define GADGET_ID_LEVEL_GEMSLIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 13)
+#define GADGET_ID_LEVEL_GEMSLIMIT_UP   (GADGET_ID_COUNTER_FIRST + 14)
 #define GADGET_ID_LEVEL_TIMELIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 15)
 #define GADGET_ID_LEVEL_TIMELIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 16)
 #define GADGET_ID_LEVEL_TIMELIMIT_UP   (GADGET_ID_COUNTER_FIRST + 17)
 #define GADGET_ID_ELEMENT_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 24)
 #define GADGET_ID_ELEMENT_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 25)
 #define GADGET_ID_ELEMENT_CONTENT_UP   (GADGET_ID_COUNTER_FIRST + 26)
-#define GADGET_ID_COLLECT_SCORE_DOWN   (GADGET_ID_COUNTER_FIRST + 27)
-#define GADGET_ID_COLLECT_SCORE_TEXT   (GADGET_ID_COUNTER_FIRST + 28)
-#define GADGET_ID_COLLECT_SCORE_UP     (GADGET_ID_COUNTER_FIRST + 29)
-#define GADGET_ID_COLLECT_GEMCOUNT_DOWN        (GADGET_ID_COUNTER_FIRST + 30)
-#define GADGET_ID_COLLECT_GEMCOUNT_TEXT        (GADGET_ID_COUNTER_FIRST + 31)
-#define GADGET_ID_COLLECT_GEMCOUNT_UP  (GADGET_ID_COUNTER_FIRST + 32)
+#define GADGET_ID_CUSTOM_SCORE_DOWN    (GADGET_ID_COUNTER_FIRST + 27)
+#define GADGET_ID_CUSTOM_SCORE_TEXT    (GADGET_ID_COUNTER_FIRST + 28)
+#define GADGET_ID_CUSTOM_SCORE_UP      (GADGET_ID_COUNTER_FIRST + 29)
+#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 30)
+#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 31)
+#define GADGET_ID_CUSTOM_GEMCOUNT_UP   (GADGET_ID_COUNTER_FIRST + 32)
 #define GADGET_ID_PUSH_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 33)
 #define GADGET_ID_PUSH_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 34)
 #define GADGET_ID_PUSH_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 35)
 #define GADGET_ID_CUSTOM_GRAPHIC       (GADGET_ID_DRAWING_AREA_FIRST + 10)
 #define GADGET_ID_CUSTOM_CONTENT       (GADGET_ID_DRAWING_AREA_FIRST + 11)
 #define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 12)
-#define GADGET_ID_CUSTOM_CHANGE_TRIGGER        (GADGET_ID_DRAWING_AREA_FIRST + 13)
-#define GADGET_ID_RANDOM_BACKGROUND    (GADGET_ID_DRAWING_AREA_FIRST + 14)
+#define GADGET_ID_CUSTOM_CHANGE_CONTENT        (GADGET_ID_DRAWING_AREA_FIRST + 13)
+#define GADGET_ID_CUSTOM_CHANGE_TRIGGER        (GADGET_ID_DRAWING_AREA_FIRST + 14)
+#define GADGET_ID_RANDOM_BACKGROUND    (GADGET_ID_DRAWING_AREA_FIRST + 15)
 
 /* text input identifiers */
-#define GADGET_ID_TEXT_INPUT_FIRST     (GADGET_ID_DRAWING_AREA_FIRST + 15)
+#define GADGET_ID_TEXT_INPUT_FIRST     (GADGET_ID_DRAWING_AREA_FIRST + 16)
 
 #define GADGET_ID_LEVEL_NAME           (GADGET_ID_TEXT_INPUT_FIRST + 0)
 #define GADGET_ID_LEVEL_AUTHOR         (GADGET_ID_TEXT_INPUT_FIRST + 1)
 #define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 10)
 #define GADGET_ID_CHANGE_IMPACT_ACTION (GADGET_ID_SELECTBOX_FIRST + 11)
 #define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 13)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 14)
 
 #define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 0)
 #define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 1)
 #define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 18)
 #define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 19)
 #define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 20)
-#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 21)
-#define GADGET_ID_CHANGE_BY_PLAYER     (GADGET_ID_CHECKBUTTON_FIRST + 22)
-#define GADGET_ID_CHANGE_IMPACT_SMASHED        (GADGET_ID_CHECKBUTTON_FIRST + 23)
-#define GADGET_ID_CHANGE_BY_OTHER      (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 21)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 22)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 23)
+#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CHANGE_BY_PLAYER     (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_CHANGE_IMPACT_SMASHED        (GADGET_ID_CHECKBUTTON_FIRST + 26)
+#define GADGET_ID_CHANGE_BY_OTHER      (GADGET_ID_CHECKBUTTON_FIRST + 27)
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 28)
 #define GADGET_ID_ELEMENTLIST_LAST     (GADGET_ID_ELEMENTLIST_FIRST +  \
                                        ED_NUM_ELEMENTLIST_BUTTONS - 1)
 
 #define ED_COUNTER_ID_SELECT_LEVEL     0
 #define ED_COUNTER_ID_LEVEL_XSIZE      1
 #define ED_COUNTER_ID_LEVEL_YSIZE      2
-#define ED_COUNTER_ID_LEVEL_COLLECT    3
+#define ED_COUNTER_ID_LEVEL_GEMSLIMIT  3
 #define ED_COUNTER_ID_LEVEL_TIMELIMIT  4
 #define ED_COUNTER_ID_LEVEL_TIMESCORE  5
 #define ED_COUNTER_ID_LEVEL_RANDOM     6
 #define ED_COUNTER_ID_ELEMENT_SCORE    7
 #define ED_COUNTER_ID_ELEMENT_CONTENT  8
-#define ED_COUNTER_ID_COLLECT_SCORE    9
-#define ED_COUNTER_ID_COLLECT_GEMCOUNT 10
+#define ED_COUNTER_ID_CUSTOM_SCORE     9
+#define ED_COUNTER_ID_CUSTOM_GEMCOUNT  10
 #define ED_COUNTER_ID_PUSH_DELAY_FIX   11
 #define ED_COUNTER_ID_PUSH_DELAY_RND   12
 #define ED_COUNTER_ID_MOVE_DELAY_FIX   13
 #define ED_COUNTER_ID_LEVEL_FIRST      ED_COUNTER_ID_LEVEL_XSIZE
 #define ED_COUNTER_ID_LEVEL_LAST       ED_COUNTER_ID_LEVEL_RANDOM
 
-#define ED_COUNTER_ID_CUSTOM_FIRST     ED_COUNTER_ID_COLLECT_SCORE
+#define ED_COUNTER_ID_CUSTOM_FIRST     ED_COUNTER_ID_CUSTOM_SCORE
 #define ED_COUNTER_ID_CUSTOM_LAST      ED_COUNTER_ID_MOVE_DELAY_RND
 
 #define ED_COUNTER_ID_CHANGE_FIRST     ED_COUNTER_ID_CHANGE_DELAY_FIX
 #define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION   10
 #define ED_SELECTBOX_ID_CHANGE_IMPACT_ACTION   11
 #define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    12
+#define ED_SELECTBOX_ID_CHANGE_POWER           13
 
-#define ED_NUM_SELECTBOX                       13
+#define ED_NUM_SELECTBOX                       14
 
 #define ED_SELECTBOX_ID_CUSTOM_FIRST   ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION
 #define ED_SELECTBOX_ID_CUSTOM_LAST    ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER
 
 #define ED_SELECTBOX_ID_CHANGE_FIRST   ED_SELECTBOX_ID_CHANGE_TIME_UNITS
-#define ED_SELECTBOX_ID_CHANGE_LAST    ED_SELECTBOX_ID_CHANGE_OTHER_ACTION
+#define ED_SELECTBOX_ID_CHANGE_LAST    ED_SELECTBOX_ID_CHANGE_POWER
 
 /* values for textbutton gadgets */
 #define ED_TEXTBUTTON_ID_PROPERTIES_INFO       0
 #define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC   16
 #define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE  17
 #define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    18
-#define ED_CHECKBUTTON_ID_CHANGE_DELAY         19
-#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER     20
-#define ED_CHECKBUTTON_ID_CHANGE_IMPACT_SMASHED        21
-#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER      22
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   19
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 20
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 21
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY         22
+#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER     23
+#define ED_CHECKBUTTON_ID_CHANGE_IMPACT_SMASHED        24
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER      25
 
-#define ED_NUM_CHECKBUTTONS                    23
+#define ED_NUM_CHECKBUTTONS                    26
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_DOUBLE_SPEED
 #define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
@@ -711,8 +724,8 @@ static struct
   {
     ED_SETTINGS_XPOS(0),               ED_COUNTER_YPOS(3),
     0,                                 999,
-    GADGET_ID_LEVEL_COLLECT_DOWN,      GADGET_ID_LEVEL_COLLECT_UP,
-    GADGET_ID_LEVEL_COLLECT_TEXT,
+    GADGET_ID_LEVEL_GEMSLIMIT_DOWN,    GADGET_ID_LEVEL_GEMSLIMIT_UP,
+    GADGET_ID_LEVEL_GEMSLIMIT_TEXT,
     &level.gems_needed,
     "number of emeralds to collect",   NULL, NULL
   },
@@ -765,17 +778,17 @@ static struct
   {
     ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(3),
     MIN_SCORE,                         MAX_SCORE,
-    GADGET_ID_COLLECT_SCORE_DOWN,      GADGET_ID_COLLECT_SCORE_UP,
-    GADGET_ID_COLLECT_SCORE_TEXT,
-    &custom_element.collect_score,
+    GADGET_ID_CUSTOM_SCORE_DOWN,       GADGET_ID_CUSTOM_SCORE_UP,
+    GADGET_ID_CUSTOM_SCORE_TEXT,
+    &custom_element.score,
     NULL,                              "collect score", NULL
   },
   {
     ED_SETTINGS_XPOS(13) + 10,         ED_SETTINGS_YPOS(3),
     MIN_GEM_COUNT,                     MAX_GEM_COUNT,
-    GADGET_ID_COLLECT_GEMCOUNT_DOWN,   GADGET_ID_COLLECT_GEMCOUNT_UP,
-    GADGET_ID_COLLECT_GEMCOUNT_TEXT,
-    &custom_element.collect_gem_count,
+    GADGET_ID_CUSTOM_GEMCOUNT_DOWN,    GADGET_ID_CUSTOM_GEMCOUNT_UP,
+    GADGET_ID_CUSTOM_GEMCOUNT_TEXT,
+    &custom_element.gem_count,
     NULL,                              "gems", NULL
   },
   {
@@ -856,6 +869,23 @@ static struct
   }
 };
 
+static struct ValueTextInfo options_access_type[] =
+{
+  { EP_WALKABLE,               "walk"                          },
+  { EP_PASSABLE,               "pass"                          },
+  { -1,                                NULL                            }
+};
+static int value_access_type = 0;
+
+static struct ValueTextInfo options_access_layer[] =
+{
+  { EP_ACCESSIBLE_OVER,                "over"                          },
+  { EP_ACCESSIBLE_INSIDE,      "inside"                        },
+  { EP_ACCESSIBLE_UNDER,       "under"                         },
+  { -1,                                NULL                            }
+};
+static int value_access_layer = 0;
+
 static struct ValueTextInfo options_walk_to_action[] =
 {
   { EP_DIGGABLE,               "diggable"                      },
@@ -903,23 +933,6 @@ static struct ValueTextInfo options_move_stepsize[] =
   { -1,                                NULL                            }
 };
 
-static struct ValueTextInfo options_consistency[] =
-{
-  { EP_CAN_EXPLODE,            "can explode"                   },
-  { EP_INDESTRUCTIBLE,         "indestructible"                },
-  { -1,                                NULL                            }
-};
-static int value_consistency = 0;
-
-static struct ValueTextInfo options_deadliness[] =
-{
-  { EP_DONT_RUN_INTO,          "running into"                  },
-  { EP_DONT_COLLIDE_WITH,      "colliding with"                },
-  { EP_DONT_TOUCH,             "touching"                      },
-  { -1,                                NULL                            }
-};
-static int value_deadliness = 0;
-
 static struct ValueTextInfo options_smash_targets[] =
 {
   { EP_CAN_SMASH_PLAYER,       "player"                        },
@@ -929,22 +942,22 @@ static struct ValueTextInfo options_smash_targets[] =
 };
 static int value_smash_targets = 0;
 
-static struct ValueTextInfo options_access_type[] =
+static struct ValueTextInfo options_deadliness[] =
 {
-  { EP_WALKABLE,               "walk"                          },
-  { EP_PASSABLE,               "pass"                          },
+  { EP_DONT_RUN_INTO,          "running into"                  },
+  { EP_DONT_COLLIDE_WITH,      "colliding with"                },
+  { EP_DONT_TOUCH,             "touching"                      },
   { -1,                                NULL                            }
 };
-static int value_access_type = 0;
+static int value_deadliness = 0;
 
-static struct ValueTextInfo options_access_layer[] =
+static struct ValueTextInfo options_consistency[] =
 {
-  { EP_ACCESSIBLE_OVER,                "over"                          },
-  { EP_ACCESSIBLE_INSIDE,      "inside"                        },
-  { EP_ACCESSIBLE_UNDER,       "under"                         },
+  { EP_CAN_EXPLODE,            "can explode"                   },
+  { EP_INDESTRUCTIBLE,         "indestructible"                },
   { -1,                                NULL                            }
 };
-static int value_access_layer = 0;
+static int value_consistency = 0;
 
 static struct ValueTextInfo options_time_units[] =
 {
@@ -980,6 +993,14 @@ static struct ValueTextInfo options_change_other_action[] =
 };
 static int value_change_other_action = 0;
 
+static struct ValueTextInfo options_change_power[] =
+{
+  { CP_NON_DESTRUCTIVE,                "non-destructive"               },
+  { CP_HALF_DESTRUCTIVE,       "half-destructive"              },
+  { CP_FULL_DESTRUCTIVE,       "full-destructive"              },
+  { -1,                                NULL                            }
+};
+
 static struct
 {
   int x, y;
@@ -1099,6 +1120,14 @@ static struct
     &value_change_other_action,
     NULL, "other element:", "type of other element action"
   },
+  {
+    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(10),
+    GADGET_ID_CHANGE_POWER,
+    -1,
+    options_change_power,
+    &custom_element.change.power,
+    "power:", NULL, "power of extended change"
+  },
 };
 
 static struct
@@ -1390,6 +1419,24 @@ static struct
     &custom_element_change_events[CE_BY_OTHER],
     NULL,                              "element changes by other element"
   },
+  {
+    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(8),
+    GADGET_ID_CHANGE_USE_EXPLOSION,
+    &custom_element.change.explode,
+    "explode instead of change",       "element explodes instead of change"
+  },
+  {
+    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(9),
+    GADGET_ID_CHANGE_USE_CONTENT,
+    &custom_element.change.use_content,
+    "use extended change target:",     "element changes to more elements"
+  },
+  {
+    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(11),
+    GADGET_ID_CHANGE_ONLY_COMPLETE,
+    &custom_element.change.only_complete,
+    "only use complete change",                "only use complete extended content"
+  },
   {
     ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(12),
     GADGET_ID_CUSTOM_USE_TEMPLATE,
@@ -2806,7 +2853,7 @@ static void CreateDrawingAreas()
 
   level_editor_gadget[id] = gi;
 
-  /* ... one areas for custom element explosion content ... */
+  /* ... one area for custom element explosion content ... */
   id = GADGET_ID_CUSTOM_CONTENT;
   gi = CreateGadget(GDI_CUSTOM_ID, id,
                    GDI_CUSTOM_TYPE_ID, i,
@@ -2845,6 +2892,26 @@ static void CreateDrawingAreas()
 
   level_editor_gadget[id] = gi;
 
+  /* ... one area for extended custom element change target content ... */
+  id = GADGET_ID_CUSTOM_CHANGE_CONTENT;
+  gi = CreateGadget(GDI_CUSTOM_ID, id,
+                   GDI_CUSTOM_TYPE_ID, i,
+                   GDI_X, SX + ED_AREA_ELEM_CONTENT6_XPOS,
+                   GDI_Y, SX + ED_AREA_ELEM_CONTENT6_YPOS,
+                   GDI_WIDTH, 3 * MINI_TILEX,
+                   GDI_HEIGHT, 3 * MINI_TILEY,
+                   GDI_TYPE, GD_TYPE_DRAWING_AREA,
+                   GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
+                   GDI_EVENT_MASK, event_mask,
+                   GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
+                   GDI_CALLBACK_ACTION, HandleDrawingAreas,
+                   GDI_END);
+
+  if (gi == NULL)
+    Error(ERR_EXIT, "cannot create gadget");
+
+  level_editor_gadget[id] = gi;
+
   /* ... one for each custom element change trigger element ... */
   id = GADGET_ID_CUSTOM_CHANGE_TRIGGER;
   gi = CreateGadget(GDI_CUSTOM_ID, id,
@@ -4110,11 +4177,36 @@ static void DrawCustomChangeTargetArea()
 
   DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE);
   DrawMiniGraphicExt(drawto, gi->x, gi->y,
-                    el2edimg(custom_element.change.successor));
+                    el2edimg(custom_element.change.target_element));
 
   MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_TARGET);
 }
 
+static void DrawCustomChangeContentArea()
+{
+  struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_CONTENT];
+  int area_sx = SX + ED_AREA_ELEM_CONTENT6_XPOS;
+  int area_sy = SY + ED_AREA_ELEM_CONTENT6_YPOS;
+  int x, y;
+
+  if (!IS_CUSTOM_ELEMENT(properties_element))
+  {
+    /* this should never happen */
+    Error(ERR_WARN, "element %d is no custom element", properties_element);
+
+    return;
+  }
+
+  DrawElementBorder(area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE);
+
+  for (y=0; y<3; y++)
+    for (x=0; x<3; x++)
+      DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX,gi->y + y * MINI_TILEY,
+                        el2edimg(custom_element.change.content[x][y]));
+
+  MapDrawingArea(GADGET_ID_CUSTOM_CHANGE_CONTENT);
+}
+
 static void DrawCustomChangeTriggerArea()
 {
   struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TRIGGER];
@@ -4700,6 +4792,7 @@ static void DrawPropertiesAdvanced()
   /* draw drawing area gadgets */
   DrawCustomGraphicElementArea();
   DrawCustomChangeTargetArea();
+  DrawCustomChangeContentArea();
   DrawCustomChangeTriggerArea();
 }
 
@@ -5548,7 +5641,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
        }
        else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
        {
-         custom_element.change.successor = new_element;
+         custom_element.change.target_element = new_element;
+         element_info[properties_element] = custom_element;
+       }
+       else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+       {
+         custom_element.change.content[sx][sy] = new_element;
          element_info[properties_element] = custom_element;
        }
        else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
@@ -5667,7 +5765,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
       else if (id == GADGET_ID_CUSTOM_CONTENT)
        PickDrawingElement(button, custom_element.content[sx][sy]);
       else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
-       PickDrawingElement(button, custom_element.change.successor);
+       PickDrawingElement(button, custom_element.change.target_element);
+      else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+       PickDrawingElement(button, custom_element.change.content[sx][sy]);
       else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
        PickDrawingElement(button, custom_element.change.trigger);
       else if (id == GADGET_ID_RANDOM_BACKGROUND)
@@ -6399,30 +6499,33 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
   else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT)
   {
     if (id == GADGET_ID_AMOEBA_CONTENT)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(level.amoeba_content));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(level.amoeba_content));
     else if (id == GADGET_ID_CUSTOM_GRAPHIC)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(custom_element.use_gfx_element));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(custom_element.gfx_element));
     else if (id == GADGET_ID_CUSTOM_CONTENT)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(custom_element.content[sx][sy]));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(custom_element.content[sx][sy]));
     else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(custom_element.change.successor));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(custom_element.change.target_element));
+    else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(custom_element.change.content[sx][sy]));
     else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(custom_element.change.trigger));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(custom_element.change.trigger));
     else if (id == GADGET_ID_RANDOM_BACKGROUND)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(random_placement_background_element));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(random_placement_background_element));
     else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
             id <= GADGET_ID_ELEMENT_CONTENT_7)
     {
       int i = id - GADGET_ID_ELEMENT_CONTENT_0;
 
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
-               "%s", getElementInfoText(level.yamyam_content[i][sx][sy]));
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+               getElementInfoText(level.yamyam_content[i][sx][sy]));
     }
   }
   else
@@ -6439,6 +6542,9 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
     else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
       DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
                "New element after change");
+    else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+               "New extended elements after change");
     else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
       DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
                "Other element triggering change");
index 19f536d9f2498e18bdbe9ca11b36211757fb37ba..16260cc793f2e5a2a740d28b154a5bb5fa7a5b80 100644 (file)
@@ -99,9 +99,14 @@ static void setLevelInfoToDefaults()
   {
     int element = EL_CUSTOM_START + i;
 
+    element_info[element].use_template = FALSE;
+
     element_info[element].use_gfx_element = FALSE;
     element_info[element].gfx_element = EL_EMPTY_SPACE;
 
+    element_info[element].score = 0;
+    element_info[element].gem_count = 0;
+
     element_info[element].push_delay_fixed = 2;                /* special default */
     element_info[element].push_delay_random = 8;       /* special default */
     element_info[element].move_delay_fixed = 0;
@@ -116,9 +121,24 @@ static void setLevelInfoToDefaults()
        element_info[element].content[x][y] = EL_EMPTY_SPACE;
 
     element_info[element].change.events = CE_BITMASK_DEFAULT;
+
     element_info[element].change.delay_fixed = 0;
     element_info[element].change.delay_random = 0;
-    element_info[element].change.successor = EL_EMPTY_SPACE;
+    element_info[element].change.delay_frames = -1;    /* use default */
+
+    element_info[element].change.trigger = EL_EMPTY_SPACE;
+
+    element_info[element].change.target_element = EL_EMPTY_SPACE;
+
+    element_info[element].change.use_content = FALSE;
+    element_info[element].change.only_complete = FALSE;
+    element_info[element].change.power = CP_NON_DESTRUCTIVE;
+
+    element_info[element].change.explode = FALSE;
+
+    for(x=0; x<3; x++)
+      for(y=0; y<3; y++)
+       element_info[element].change.content[x][y] = EL_EMPTY_SPACE;
 
     /* start with no properties at all */
     for (j=0; j < NUM_EP_BITFIELDS; j++)
@@ -385,10 +405,10 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level)
   for (i=0; i < num_changed_custom_elements; i++)
   {
     int element = getFile16BitBE(file);
-    int custom_element_successor = getFile16BitBE(file);
+    int custom_target_element = getFile16BitBE(file);
 
     if (IS_CUSTOM_ELEMENT(element))
-      element_info[element].change.successor = custom_element_successor;
+      element_info[element].change.target_element = custom_target_element;
     else
       Error(ERR_WARN, "invalid custom element number %d", element);
   }
@@ -778,12 +798,12 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level,
   {
     int element = EL_CUSTOM_START + i;
 
-    if (element_info[element].change.successor != EL_EMPTY_SPACE)
+    if (element_info[element].change.target_element != EL_EMPTY_SPACE)
     {
       if (check < num_changed_custom_elements)
       {
        putFile16BitBE(file, element);
-       putFile16BitBE(file, element_info[element].change.successor);
+       putFile16BitBE(file, element_info[element].change.target_element);
       }
 
       check++;
@@ -791,7 +811,7 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level,
   }
 
   if (check != num_changed_custom_elements)    /* should not happen */
-    Error(ERR_WARN, "inconsistent number of custom element successors");
+    Error(ERR_WARN, "inconsistent number of custom target elements");
 }
 
 void SaveLevel(int level_nr)
@@ -843,7 +863,7 @@ void SaveLevel(int level_nr)
 
   /* check for non-standard custom elements and calculate "CUS2" chunk size */
   for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
-    if (element_info[EL_CUSTOM_START + i].change.successor != EL_EMPTY_SPACE)
+    if (element_info[EL_CUSTOM_START + i].change.target_element != EL_EMPTY)
       num_changed_custom_elements2++;
 
   putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
index b51a18739ef7ed2f4dd3092b061f9b3c5c9e0d2b..436d82bac1ee39858512ef0d67b900faa67c2c51 100644 (file)
@@ -165,7 +165,7 @@ static void KillHeroUnlessProtected(int, int);
 
 static void CheckTriggeredElementChange(int, int);
 static void CheckPlayerElementChange(int, int, int, int);
-static void ChangeElementDoIt(int, int, int);
+static void ChangeElementNow(int, int, int);
 
 static void PlaySoundLevel(int, int, int);
 static void PlaySoundLevelNearest(int, int, int);
@@ -202,8 +202,8 @@ static void RunTimegateWheel(int x, int y);
 
 struct ChangingElementInfo
 {
-  int base_element;
-  int next_element;
+  int element;
+  int target_element;
   int change_delay;
   void (*pre_change_function)(int x, int y);
   void (*change_function)(int x, int y);
@@ -375,7 +375,7 @@ struct
   int element;
   int gem_count;
 }
-collect_gem_count_list[] =
+gem_count_list[] =
 {
   { EL_EMERALD,                1 },
   { EL_BD_DIAMOND,     1 },
@@ -390,10 +390,10 @@ collect_gem_count_list[] =
   { EL_UNDEFINED,      0 },
 };
 
-static struct ChangingElementInfo changing_element[MAX_NUM_ELEMENTS];
+static boolean changing_element[MAX_NUM_ELEMENTS];
 static unsigned long trigger_events[MAX_NUM_ELEMENTS];
 
-#define IS_AUTO_CHANGING(e)  (changing_element[e].base_element != EL_UNDEFINED)
+#define IS_AUTO_CHANGING(e)    (changing_element[e])
 #define IS_JUST_CHANGING(x, y) (ChangeDelay[x][y] != 0)
 #define IS_CHANGING(x, y)      (IS_AUTO_CHANGING(Feld[x][y]) || \
                                 IS_JUST_CHANGING(x, y))
@@ -742,42 +742,75 @@ static void InitGameEngine()
   /* initialize changing elements information */
   for (i=0; i<MAX_NUM_ELEMENTS; i++)
   {
+#if 1
+    element_info[i].change.pre_change_function = NULL;
+    element_info[i].change.change_function = NULL;
+    element_info[i].change.post_change_function = NULL;
+
+    if (!IS_CUSTOM_ELEMENT(i))
+    {
+      element_info[i].change.target_element = EL_EMPTY_SPACE;
+      element_info[i].change.delay_fixed = 0;
+      element_info[i].change.delay_random = 0;
+      element_info[i].change.delay_frames = 1;
+    }
+
+    changing_element[i] = FALSE;
+#else
     changing_element[i].base_element = EL_UNDEFINED;
     changing_element[i].next_element = EL_UNDEFINED;
     changing_element[i].change_delay = -1;
     changing_element[i].pre_change_function = NULL;
     changing_element[i].change_function = NULL;
     changing_element[i].post_change_function = NULL;
+#endif
   }
 
   /* add changing elements from pre-defined list */
-  for (i=0; changing_element_list[i].base_element != EL_UNDEFINED; i++)
+  for (i=0; changing_element_list[i].element != EL_UNDEFINED; i++)
   {
+    int element = changing_element_list[i].element;
     struct ChangingElementInfo *ce = &changing_element_list[i];
-    int element = ce->base_element;
+    struct ElementChangeInfo *change = &element_info[element].change;
+
+#if 1
+    change->target_element       = ce->target_element;
+    change->delay_fixed          = ce->change_delay;
+    change->pre_change_function  = ce->pre_change_function;
+    change->change_function      = ce->change_function;
+    change->post_change_function = ce->post_change_function;
 
+    changing_element[element] = TRUE;
+#else
     changing_element[element].base_element         = ce->base_element;
     changing_element[element].next_element         = ce->next_element;
     changing_element[element].change_delay         = ce->change_delay;
     changing_element[element].pre_change_function  = ce->pre_change_function;
     changing_element[element].change_function      = ce->change_function;
     changing_element[element].post_change_function = ce->post_change_function;
+#endif
   }
 
   /* add changing elements from custom element configuration */
   for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
+#if 0
     struct ElementChangeInfo *change = &element_info[element].change;
+#endif
 
     /* only add custom elements that change after fixed/random frame delay */
     if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, CE_DELAY))
       continue;
 
+#if 1
+    changing_element[element] = TRUE;
+#else
     changing_element[element].base_element = element;
-    changing_element[element].next_element = change->successor;
+    changing_element[element].next_element = change->target_element;
     changing_element[element].change_delay = (change->delay_fixed *
                                              change->delay_frames);
+#endif
   }
 
   /* ---------- initialize trigger events ---------------------------------- */
@@ -818,12 +851,12 @@ static void InitGameEngine()
   /* initialize gem count values for each element */
   for (i=0; i<MAX_NUM_ELEMENTS; i++)
     if (!IS_CUSTOM_ELEMENT(i))
-      element_info[i].collect_gem_count = 0;
+      element_info[i].gem_count = 0;
 
   /* add gem count values for all elements from pre-defined list */
-  for (i=0; collect_gem_count_list[i].element != EL_UNDEFINED; i++)
-    element_info[collect_gem_count_list[i].element].collect_gem_count =
-      collect_gem_count_list[i].gem_count;
+  for (i=0; gem_count_list[i].element != EL_UNDEFINED; i++)
+    element_info[gem_count_list[i].element].gem_count =
+      gem_count_list[i].gem_count;
 }
 
 
@@ -2535,7 +2568,7 @@ void Impact(int x, int y)
   {
     PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
 
-    ChangeElementDoIt(x, y, element_info[element].change.successor);
+    ChangeElementNow(x, y, element);
 
     return;
   }
@@ -2666,7 +2699,7 @@ void Impact(int x, int y)
        else if (CAN_CHANGE(smashed) &&
                 HAS_CHANGE_EVENT(smashed, CE_SMASHED))
        {
-         ChangeElementDoIt(x, y + 1, element_info[smashed].change.successor);
+         ChangeElementNow(x, y + 1, smashed);
        }
       }
     }
@@ -5003,12 +5036,16 @@ static void ChangeActiveTrap(int x, int y)
     DrawLevelFieldCrumbledSand(x, y);
 }
 
-static void ChangeElementDoIt(int x, int y, int element_new)
+static void ChangeElementNowExt(int x, int y, int target_element)
 {
-  CheckTriggeredElementChange(Feld[x][y], CE_OTHER_CHANGING);
+  if (IS_PLAYER(x, y) && !IS_ACCESSIBLE(target_element))
+  {
+    Bang(x, y);
+    return;
+  }
 
   RemoveField(x, y);
-  Feld[x][y] = element_new;
+  Feld[x][y] = target_element;
 
   ResetGfxAnimation(x, y);
   ResetRandomAnimationValue(x, y);
@@ -5049,12 +5086,99 @@ static void ChangeElementDoIt(int x, int y, int element_new)
   }
 }
 
+static void ChangeElementNow(int x, int y, int element)
+{
+  struct ElementChangeInfo *change = &element_info[element].change;
+
+  CheckTriggeredElementChange(Feld[x][y], CE_OTHER_CHANGING);
+
+  if (change->explode)
+  {
+    Bang(x, y);
+    return;
+  }
+
+  if (change->use_content)
+  {
+    boolean complete_change = TRUE;
+    boolean can_change[3][3];
+    int xx, yy;
+
+    for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++)
+    {
+      boolean half_destructible;
+      int ex = x + xx - 1;
+      int ey = y + yy - 1;
+      int e;
+
+      can_change[xx][yy] = TRUE;
+
+      if (ex == x && ey == y)  /* do not check changing element itself */
+       continue;
+
+      if (change->content[xx][yy] == EL_EMPTY_SPACE)
+      {
+       can_change[xx][yy] = FALSE;     /* do not change empty borders */
+
+       continue;
+      }
+
+      if (!IN_LEV_FIELD(ex, ey))
+      {
+       can_change[xx][yy] = FALSE;
+       complete_change = FALSE;
+
+       continue;
+      }
+
+      e = Feld[ex][ey];
+
+      half_destructible = (IS_FREE(ex, ey) || IS_DIGGABLE(e));
+
+      if ((change->power <= CP_NON_DESTRUCTIVE  && !IS_FREE(ex, ey)) ||
+         (change->power <= CP_HALF_DESTRUCTIVE && !half_destructible) ||
+         (change->power <= CP_FULL_DESTRUCTIVE && IS_INDESTRUCTIBLE(e)))
+      {
+       can_change[xx][yy] = FALSE;
+       complete_change = FALSE;
+      }
+    }
+
+    if (!change->only_complete || complete_change)
+    {
+      for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++)
+      {
+       int ex = x + xx - 1;
+       int ey = y + yy - 1;
+
+       if (can_change[xx][yy])
+       {
+         ChangeElementNowExt(ex, ey, change->content[xx][yy]);
+
+         /* for symmetry reasons, stop newly created border elements */
+         if (ex != x || ey != y)
+           Stop[ex][ey] = TRUE;
+       }
+      }
+
+      return;
+    }
+  }
+
+  ChangeElementNowExt(x, y, change->target_element);
+}
+
 static void ChangeElement(int x, int y)
 {
   int element = Feld[x][y];
+  struct ElementChangeInfo *change = &element_info[element].change;
 
   if (ChangeDelay[x][y] == 0)          /* initialize element change */
   {
+#if 1
+    ChangeDelay[x][y] = (    change->delay_fixed  * change->delay_frames +
+                        RND(change->delay_random * change->delay_frames)) + 1;
+#else
     ChangeDelay[x][y] = changing_element[element].change_delay + 1;
 
     if (IS_CUSTOM_ELEMENT(element) && HAS_CHANGE_EVENT(element, CE_DELAY))
@@ -5064,12 +5188,18 @@ static void ChangeElement(int x, int y)
 
       ChangeDelay[x][y] += RND(max_random_delay * delay_frames);
     }
+#endif
 
     ResetGfxAnimation(x, y);
     ResetRandomAnimationValue(x, y);
 
+#if 1
+    if (change->pre_change_function)
+      change->pre_change_function(x, y);
+#else
     if (changing_element[element].pre_change_function)
       changing_element[element].pre_change_function(x, y);
+#endif
   }
 
   ChangeDelay[x][y]--;
@@ -5081,12 +5211,19 @@ static void ChangeElement(int x, int y)
     if (IS_ANIMATED(graphic))
       DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
 
+#if 1
+    if (change->change_function)
+      change->change_function(x, y);
+#else
     if (changing_element[element].change_function)
       changing_element[element].change_function(x, y);
+#endif
   }
   else                                 /* finish element change */
   {
+#if 0
     int next_element = changing_element[element].next_element;
+#endif
 
     if (IS_MOVING(x, y))               /* never change a running system ;-) */
     {
@@ -5095,13 +5232,20 @@ static void ChangeElement(int x, int y)
       return;
     }
 
+#if 1
+    ChangeElementNow(x, y, element);
+
+    if (change->post_change_function)
+      change->post_change_function(x, y);
+#else
     if (next_element != EL_UNDEFINED)
-      ChangeElementDoIt(x, y, next_element);
+      ChangeElementNow(x, y, next_element);
     else
-      ChangeElementDoIt(x, y, element_info[element].change.successor);
+      ChangeElementNow(x, y, element_info[element].change.target_element);
 
     if (changing_element[element].post_change_function)
       changing_element[element].post_change_function(x, y);
+#endif
   }
 }
 
@@ -5135,12 +5279,8 @@ static void CheckPlayerElementChange(int x, int y, int element,
   if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, trigger_event))
     return;
 
-#if 1
   ChangeDelay[x][y] = 1;
   ChangeElement(x, y);
-#else
-  ChangeElementDoIt(x, y, element_info[element].change.successor);
-#endif
 }
 
 static void PlayerActions(struct PlayerInfo *player, byte player_action)
@@ -6904,10 +7044,10 @@ int DigField(struct PlayerInfo *player,
                             el2edimg(EL_KEY_1 + key_nr));
          redraw_mask |= REDRAW_DOOR_1;
        }
-       else if (element_info[element].collect_gem_count > 0)
+       else if (element_info[element].gem_count > 0)
        {
          local_player->gems_still_needed -=
-           element_info[element].collect_gem_count;
+           element_info[element].gem_count;
          if (local_player->gems_still_needed < 0)
            local_player->gems_still_needed = 0;
 
@@ -7326,7 +7466,7 @@ void RaiseScoreElement(int element)
       RaiseScore(level.score[SC_KEY]);
       break;
     default:
-      RaiseScore(element_info[element].collect_score);
+      RaiseScore(element_info[element].score);
       break;
   }
 }
index 4a3cee3ce7a65efa4231dcbfc304046aae732110..1108cbf76d19aa265912e6e10eb17313e9f81b10 100644 (file)
 #define EP_PUSHABLE            24
 
 /* values for special configurable properties (depending on level settings) */
-#define EP_EM_SLIPPERY_WALL    25
+#define EP_EM_SLIPPERY_WALL    32
 
 /* values for special graphics properties (no effect on game engine) */
-#define EP_CAN_BE_CRUMBLED     26
+#define EP_CAN_BE_CRUMBLED     33
 
 /* values for pre-defined properties */
-#define EP_PLAYER              27
-#define EP_CAN_PASS_MAGIC_WALL 28
-#define EP_SWITCHABLE          29
-#define EP_BD_ELEMENT          30
-#define EP_SP_ELEMENT          31
-#define EP_SB_ELEMENT          32
-#define EP_GEM                 33
-#define EP_FOOD_DARK_YAMYAM    34
-#define EP_FOOD_PENGUIN                35
-#define EP_FOOD_PIG            36
-#define EP_HISTORIC_WALL       37
-#define EP_HISTORIC_SOLID      38
-#define EP_CLASSIC_ENEMY       39
-#define EP_BELT                        40
-#define EP_BELT_ACTIVE         41
-#define EP_BELT_SWITCH         42
-#define EP_TUBE                        43
-#define EP_KEYGATE             44
-#define EP_AMOEBOID            45
-#define EP_AMOEBALIVE          46
-#define EP_HAS_CONTENT         47
-#define EP_ACTIVE_BOMB         48
-#define EP_INACTIVE            49
+#define EP_PLAYER              34
+#define EP_CAN_PASS_MAGIC_WALL 35
+#define EP_SWITCHABLE          36
+#define EP_BD_ELEMENT          37
+#define EP_SP_ELEMENT          38
+#define EP_SB_ELEMENT          39
+#define EP_GEM                 40
+#define EP_FOOD_DARK_YAMYAM    41
+#define EP_FOOD_PENGUIN                42
+#define EP_FOOD_PIG            43
+#define EP_HISTORIC_WALL       44
+#define EP_HISTORIC_SOLID      45
+#define EP_CLASSIC_ENEMY       46
+#define EP_BELT                        47
+#define EP_BELT_ACTIVE         48
+#define EP_BELT_SWITCH         49
+#define EP_TUBE                        50
+#define EP_KEYGATE             51
+#define EP_AMOEBOID            52
+#define EP_AMOEBALIVE          53
+#define EP_HAS_CONTENT         54
+#define EP_ACTIVE_BOMB         55
+#define EP_INACTIVE            56
 
 /* values for derived properties (determined from properties above) */
-#define EP_ACCESSIBLE_OVER     50
-#define EP_ACCESSIBLE_INSIDE   51
-#define EP_ACCESSIBLE_UNDER    52
-#define EP_WALKABLE            53
-#define EP_PASSABLE            54
-#define EP_ACCESSIBLE          55
-#define EP_SNAPPABLE           56
-#define EP_WALL                        57
-#define EP_SOLID_FOR_PUSHING   58
-#define EP_DRAGONFIRE_PROOF    59
-#define EP_EXPLOSION_PROOF     60
-#define EP_CAN_SMASH           61
-#define EP_CAN_EXPLODE         62
+#define EP_ACCESSIBLE_OVER     57
+#define EP_ACCESSIBLE_INSIDE   58
+#define EP_ACCESSIBLE_UNDER    59
+#define EP_WALKABLE            60
+#define EP_PASSABLE            61
+#define EP_ACCESSIBLE          62
+#define EP_SNAPPABLE           63
+#define EP_WALL                        64
+#define EP_SOLID_FOR_PUSHING   65
+#define EP_DRAGONFIRE_PROOF    66
+#define EP_EXPLOSION_PROOF     67
+#define EP_CAN_SMASH           68
+#define EP_CAN_EXPLODE         69
 
 /* values for internal purpose only (level editor) */
-#define EP_EXPLODE_RESULT      63
-#define EP_WALK_TO_OBJECT      64
-#define EP_DEADLY              65
+#define EP_EXPLODE_RESULT      70
+#define EP_WALK_TO_OBJECT      71
+#define EP_DEADLY              72
 
-#define NUM_ELEMENT_PROPERTIES 66
+#define NUM_ELEMENT_PROPERTIES 73
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
                                  (CH_EVENT_VAR(e) |=  CH_EVENT_BIT(c)) : \
                                  (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
 
+/* values for change power for custom elements */
+#define CP_NON_DESTRUCTIVE     0
+#define CP_HALF_DESTRUCTIVE    1
+#define CP_FULL_DESTRUCTIVE    2
+
 
 /* macros for configurable properties */
 #define IS_DIGGABLE(e)         HAS_PROPERTY(e, EP_DIGGABLE)
@@ -1172,7 +1177,20 @@ struct ElementChangeInfo
 
   short trigger;               /* custom element triggering change */
 
-  short successor;             /* new custom element after change */
+  short target_element;                /* target element after change */
+
+  int content[3][3];           /* new elements after extended change */
+  boolean use_content;         /* use extended change content */
+  boolean only_complete;       /* only use complete content */
+  int power;                   /* power of extended change */
+
+  boolean explode;             /* explode instead of change */
+
+  /* functions that are called before, while and after the change of an
+     element -- currently only used for non-custom elements */
+  void (*pre_change_function)(int x, int y);
+  void (*change_function)(int x, int y);
+  void (*post_change_function)(int x, int y);
 };
 
 struct ElementInfo
@@ -1201,8 +1219,8 @@ struct ElementInfo
   boolean use_gfx_element;
   short gfx_element;           /* optional custom graphic element */
 
-  int collect_score;           /* score value for collecting */
-  int collect_gem_count;       /* gem count value for collecting */
+  int score;                   /* score value for collecting */
+  int gem_count;               /* gem count value for collecting */
 
   int push_delay_fixed;                /* constant frame delay for pushing */
   int push_delay_random;       /* additional random frame delay for pushing */