rnd-20030923-1-src
authorHolger Schemel <info@artsoft.org>
Mon, 22 Sep 2003 23:53:16 +0000 (01:53 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:43:53 +0000 (10:43 +0200)
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/main.h

index 5ba3a714fd8a1589a5bca3a7c4b44d395ce98d3b..65d91c0e3eb3b0817010bc014a6ab0f3b208bf1c 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-09-21 22:10]"
+#define COMPILE_DATE_STRING "[2003-09-23 01:50]"
index f55a3de1e5472a302e9e56cd5b6a44672f3f3e28..fe8df680b12f57ab0b83c4163b6cd70100a21efe 100644 (file)
                                         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(9) + \
+#define ED_AREA_ELEM_CONTENT6_YPOS     (ED_SETTINGS_YPOS(10) + \
                                         ED_GADGET_DISTANCE - MINI_TILEY)
 
 /* values for random placement background drawing area */
 #define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 10)
 #define GADGET_ID_CHANGE_DIRECT_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)
-#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_CHANGE_SIDES         (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 15)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 16)
 
 #define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 0)
 #define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 1)
 #define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      10
 #define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   11
 #define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    12
-#define ED_SELECTBOX_ID_CHANGE_POWER           13
-#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     14
+#define ED_SELECTBOX_ID_CHANGE_SIDES           13
+#define ED_SELECTBOX_ID_CHANGE_POWER           14
+#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     15
 
-#define ED_NUM_SELECTBOX                       15
+#define ED_NUM_SELECTBOX                       16
 
 #define ED_SELECTBOX_ID_CUSTOM_FIRST   ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
 #define ED_SELECTBOX_ID_CUSTOM_LAST    ED_SELECTBOX_ID_CUSTOM_CONSISTENCY
@@ -940,7 +942,7 @@ static struct
     NULL,                              "+random", NULL
   },
   {
-    ED_SETTINGS_XPOS(3),               ED_SETTINGS_YPOS(11),
+    ED_SETTINGS_XPOS(3),               ED_SETTINGS_YPOS(12),
     0,                                 100,
     GADGET_ID_CHANGE_CONT_RND_DOWN,    GADGET_ID_CHANGE_CONT_RND_UP,
     GADGET_ID_CHANGE_CONT_RND_TEXT,    GADGET_ID_NONE,
@@ -1109,6 +1111,8 @@ static struct ValueTextInfo options_change_direct_action[] =
   { CE_TOUCHED_BY_PLAYER,      "touched by player"             },
   { CE_PRESSED_BY_PLAYER,      "pressed by player"             },
   { CE_PUSHED_BY_PLAYER,       "pushed by player"              },
+  { CE_ENTERED_BY_PLAYER,      "entered by player"             },
+  { CE_LEFT_BY_PLAYER,         "left by player"                },
   { CE_DROPPED_BY_PLAYER,      "dropped by player"             },
   { CE_COLLISION,              "collision"                     },
   { CE_IMPACT,                 "impact"                        },
@@ -1121,19 +1125,29 @@ static struct ValueTextInfo options_change_other_action[] =
   { CE_OTHER_GETS_TOUCHED,     "player touches"                },
   { CE_OTHER_GETS_PRESSED,     "player presses"                },
   { CE_OTHER_GETS_PUSHED,      "player pushes"                 },
+  { CE_OTHER_GETS_ENTERED,     "player enters"                 },
+  { CE_OTHER_GETS_LEFT,                "player leaves"                 },
   { CE_OTHER_GETS_DIGGED,      "player digs"                   },
   { CE_OTHER_GETS_COLLECTED,   "player collects"               },
   { CE_OTHER_GETS_DROPPED,     "player drops"                  },
-  { CE_TOUCHING_ANY_SIDE_OF,   "touching"                      },
-  { CE_TOUCHING_LEFT_OF,       "touching left of"              },
-  { CE_TOUCHING_RIGHT_OF,      "touching right of"             },
-  { CE_TOUCHING_TOP_OF,                "touching top of"               },
-  { CE_TOUCHING_BOTTOM_OF,     "touching bottom of"            },
+  { CE_OTHER_IS_TOUCHING,      "touching ..."                  },
   { CE_OTHER_IS_CHANGING,      "change of"                     },
   { CE_OTHER_IS_EXPLODING,     "explosion of"                  },
   { -1,                                NULL                            }
 };
 
+static struct ValueTextInfo options_change_sides[] =
+{
+  { CH_SIDE_LEFT,              "left side"                     },
+  { CH_SIDE_RIGHT,             "right side"                    },
+  { CH_SIDE_TOP,               "top side"                      },
+  { CH_SIDE_BOTTOM,            "bottom side"                   },
+  { CH_SIDE_LEFT_RIGHT,                "left/right side"               },
+  { CH_SIDE_TOP_BOTTOM,                "top/bottom side"               },
+  { CH_SIDE_ANY,               "all sides"                     },
+  { -1,                                NULL                            }
+};
+
 static struct ValueTextInfo options_change_power[] =
 {
   { CP_NON_DESTRUCTIVE,                "empty"                         },
@@ -1269,7 +1283,15 @@ static struct
     NULL, "element:",                  "type of other element action"
   },
   {
-    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(9),
+    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(7),
+    GADGET_ID_CHANGE_SIDES,            GADGET_ID_NONE,
+    -1,
+    options_change_sides,
+    &custom_element_change.sides,
+    "... at", NULL,                    "element side that causes change"
+  },
+  {
+    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(10),
     GADGET_ID_CHANGE_POWER,            GADGET_ID_NONE,
     -1,
     options_change_power,
@@ -1277,7 +1299,7 @@ static struct
     "replace when", NULL,              "which elements can be replaced"
   },
   {
-    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(13),
+    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(14),
     GADGET_ID_SELECT_CHANGE_PAGE,      GADGET_ID_NONE,
     3,
     options_change_page,
@@ -1315,19 +1337,19 @@ static struct
     NULL, NULL,                                "Advanced element configuration"
   },
   {
-    -1,                                        ED_SETTINGS_YPOS(12),
+    -1,                                        ED_SETTINGS_YPOS(13),
     GADGET_ID_SAVE_AS_TEMPLATE,                GADGET_ID_CUSTOM_USE_TEMPLATE,
     -1,                                        "Save as template",
     " ", NULL,                         "Save current settings as new template"
   },
   {
-    -1,                                        ED_SETTINGS_YPOS(13),
+    -1,                                        ED_SETTINGS_YPOS(14),
     GADGET_ID_ADD_CHANGE_PAGE,         GADGET_ID_NEXT_CHANGE_PAGE,
     -1,                                        "New",
     " ", NULL,                         "Add new config page"
   },
   {
-    -1,                                        ED_SETTINGS_YPOS(13),
+    -1,                                        ED_SETTINGS_YPOS(14),
     GADGET_ID_DEL_CHANGE_PAGE,         GADGET_ID_ADD_CHANGE_PAGE,
     -1,                                        "Delete",
     NULL, NULL,                                "Delete current config page"
@@ -1346,14 +1368,14 @@ static struct
 {
   {
     ED_BUTTON_MINUS_XPOS,              ED_BUTTON_COUNT_YPOS,
-    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(13),
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(14),
     ED_BUTTON_COUNT_XSIZE,             ED_BUTTON_COUNT_YSIZE,
     GADGET_ID_PREV_CHANGE_PAGE,                GADGET_ID_NONE,
     NULL, NULL,                                "select previous config page"
   },
   {
     ED_BUTTON_PLUS_XPOS,               ED_BUTTON_COUNT_YPOS,
-    -1,                                        ED_SETTINGS_YPOS(13),
+    -1,                                        ED_SETTINGS_YPOS(14),
     ED_BUTTON_COUNT_XSIZE,             ED_BUTTON_COUNT_YSIZE,
     GADGET_ID_NEXT_CHANGE_PAGE,                GADGET_ID_SELECT_CHANGE_PAGE,
     NULL, "config page",               "select next config page"
@@ -1619,31 +1641,31 @@ static struct
     NULL, NULL,                                "element changes by other element"
   },
   {
-    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(7),
+    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(8),
     GADGET_ID_CHANGE_USE_EXPLOSION,    GADGET_ID_NONE,
     &custom_element_change.explode,
     NULL, "explode instead of change", "element explodes instead of change"
   },
   {
-    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(8),
+    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(9),
     GADGET_ID_CHANGE_USE_CONTENT,      GADGET_ID_NONE,
     &custom_element_change.use_content,
     NULL, "use extended change target:","element changes to more elements"
   },
   {
-    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(10),
+    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(11),
     GADGET_ID_CHANGE_ONLY_COMPLETE,    GADGET_ID_NONE,
     &custom_element_change.only_complete,
     NULL, "only use complete change",  "only use complete extended content"
   },
   {
-    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(11),
+    ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(12),
     GADGET_ID_CHANGE_USE_RANDOM,       GADGET_ID_NONE,
     &custom_element_change.use_random_change,
     NULL, NULL,                                "use random value for new content"
   },
   {
-    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(12),
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(13),
     GADGET_ID_CUSTOM_USE_TEMPLATE,     GADGET_ID_NONE,
     &level.use_custom_template,
     NULL, "use template",              "use template for custom properties"
@@ -4531,6 +4553,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
     (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER :
+     HAS_CHANGE_EVENT(element, CE_ENTERED_BY_PLAYER) ? CE_ENTERED_BY_PLAYER :
+     HAS_CHANGE_EVENT(element, CE_LEFT_BY_PLAYER) ? CE_LEFT_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_DROPPED_BY_PLAYER) ? CE_DROPPED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION :
      HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
@@ -4539,18 +4563,15 @@ static void CopyCustomElementPropertiesToEditor(int element)
 
   /* set "change by other element action" selectbox help value */
   custom_element_change.other_action =
-    (
-     HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED :
+    (HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PRESSED) ? CE_OTHER_GETS_PRESSED :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PUSHED) ? CE_OTHER_GETS_PUSHED :
+     HAS_CHANGE_EVENT(element, CE_OTHER_GETS_ENTERED) ? CE_OTHER_GETS_ENTERED :
+     HAS_CHANGE_EVENT(element, CE_OTHER_GETS_LEFT) ? CE_OTHER_GETS_LEFT :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DIGGED) ? CE_OTHER_GETS_DIGGED :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DROPPED) ? CE_OTHER_GETS_DROPPED :
-     HAS_CHANGE_EVENT(element, CE_TOUCHING_ANY_SIDE_OF) ? CE_TOUCHING_ANY_SIDE_OF :
-     HAS_CHANGE_EVENT(element, CE_TOUCHING_LEFT_OF) ? CE_TOUCHING_LEFT_OF :
-     HAS_CHANGE_EVENT(element, CE_TOUCHING_RIGHT_OF) ? CE_TOUCHING_RIGHT_OF :
-     HAS_CHANGE_EVENT(element, CE_TOUCHING_TOP_OF) ? CE_TOUCHING_TOP_OF :
-     HAS_CHANGE_EVENT(element, CE_TOUCHING_BOTTOM_OF) ? CE_TOUCHING_BOTTOM_OF :
+     HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING :
      custom_element_change.other_action);
@@ -4648,6 +4669,8 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_PUSHED_BY_PLAYER] = FALSE;
+  custom_element_change_events[CE_ENTERED_BY_PLAYER] = FALSE;
+  custom_element_change_events[CE_LEFT_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_DROPPED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_COLLISION] = FALSE;
   custom_element_change_events[CE_IMPACT] = FALSE;
@@ -4656,19 +4679,17 @@ static void CopyCustomElementPropertiesToGame(int element)
     custom_element_change_events[CE_BY_DIRECT_ACTION];
 
   /* set other element action change event from checkbox and selectbox */
-  custom_element_change_events[CE_TOUCHING_ANY_SIDE_OF] = FALSE;
-  custom_element_change_events[CE_TOUCHING_LEFT_OF] = FALSE;
-  custom_element_change_events[CE_TOUCHING_RIGHT_OF] = FALSE;
-  custom_element_change_events[CE_TOUCHING_TOP_OF] = FALSE;
-  custom_element_change_events[CE_TOUCHING_BOTTOM_OF] = FALSE;
-  custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
-  custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_TOUCHED] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_PRESSED] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_PUSHED] = FALSE;
+  custom_element_change_events[CE_OTHER_GETS_ENTERED] = FALSE;
+  custom_element_change_events[CE_OTHER_GETS_LEFT] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_DIGGED] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_DROPPED] = FALSE;
+  custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE;
+  custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
+  custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
   custom_element_change_events[custom_element_change.other_action] =
     custom_element_change_events[CE_BY_OTHER_ACTION];
 
index 79ad7e3ce49bd624be09e2652e7c50be532e1a88..64c1c632c95181be0514c5d5db37e07201ac634a 100644 (file)
@@ -74,6 +74,8 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
   change->can_change = FALSE;
 
   change->events = CE_BITMASK_DEFAULT;
+  change->sides = CH_SIDE_ANY;
+
   change->target_element = EL_EMPTY_SPACE;
 
   change->delay_fixed = 0;
index 312ac26426fdaebb246735eb1708679c204db785..05325ad7ce0fbce0d4fc53dc836f084596552e29 100644 (file)
@@ -169,7 +169,9 @@ static void KillHeroUnlessProtected(int, int);
 static void TestIfPlayerTouchesCustomElement(int, int);
 static void TestIfElementTouchesCustomElement(int, int);
 
+static boolean CheckTriggeredElementSideChange(int, int, int, int, int);
 static boolean CheckTriggeredElementChange(int, int, int, int);
+static boolean CheckElementSideChange(int, int, int, int, int, int);
 static boolean CheckElementChange(int, int, int, int);
 
 static void PlaySoundLevel(int, int, int);
@@ -821,33 +823,6 @@ static void InitGameEngine()
     ei->change_events |= CH_EVENT_BIT(CE_DELAY);
   }
 
-  /* set summarized change event CE_TOUCHING_ANY_SIDE_OF */
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
-  {
-    struct ElementInfo *ei = &element_info[EL_CUSTOM_START + i];
-
-    for (j=0; j < ei->num_change_pages; j++)
-    {
-      if (!ei->change_page[j].can_change)
-       continue;
-
-      /* check for change event of touching other element on some side */
-      if (ei->change_page[j].events & (CH_EVENT_BIT(CE_TOUCHING_ANY_SIDE_OF |
-                                                   CE_TOUCHING_LEFT_OF |
-                                                   CE_TOUCHING_RIGHT_OF |
-                                                   CE_TOUCHING_TOP_OF |
-                                                   CE_TOUCHING_BOTTOM_OF)))
-       ei->change_page[j].events |= CH_EVENT_BIT(CE_TOUCHING_SOME_SIDE);
-
-      /* add change event for each side when event exists for any side */
-      if (ei->change_page[j].events & CH_EVENT_BIT(CE_TOUCHING_ANY_SIDE_OF))
-       ei->change_page[j].events |= (CH_EVENT_BIT(CE_TOUCHING_LEFT_OF) |
-                                     CH_EVENT_BIT(CE_TOUCHING_RIGHT_OF) |
-                                     CH_EVENT_BIT(CE_TOUCHING_TOP_OF) |
-                                     CH_EVENT_BIT(CE_TOUCHING_BOTTOM_OF));
-    }
-  }
-
 #if 1
   /* add change events from custom element configuration */
   for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -5611,25 +5586,20 @@ static void ChangeElement(int x, int y, int page)
   }
 }
 
-static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
-                                          int trigger_event)
+static boolean CheckTriggeredElementSideChange(int lx, int ly,
+                                              int trigger_element,
+                                              int trigger_side,
+                                              int trigger_event)
 {
   int i, j, x, y;
 
   if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event)))
     return FALSE;
 
-#if 0
-  /* prevent this function from running into a loop */
-  if (trigger_event == CE_OTHER_IS_CHANGING)
-    Changed[lx][ly] = TRUE;
-#endif
-
   for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
-#if 1
     boolean change_element = FALSE;
     int page;
 
@@ -5639,8 +5609,10 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
 
     for (j=0; j < element_info[element].num_change_pages; j++)
     {
-      if (element_info[element].change_page[j].trigger_element ==
-         trigger_element)
+      struct ElementChangeInfo *change = &element_info[element].change_page[j];
+
+      if (change->sides & trigger_side &&
+         change->trigger_element == trigger_element)
       {
        change_element = TRUE;
        page = j;
@@ -5652,20 +5624,10 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
     if (!change_element)
       continue;
 
-#else
-    if (!CAN_CHANGE(element) ||
-       !HAS_ANY_CHANGE_EVENT(element, trigger_event) ||
-       element_info[element].change->trigger_element != trigger_element)
-      continue;
-#endif
-
     for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
     {
-      if (x == lx && y == ly)  /* do not change trigger element itself */
-       continue;
-
 #if 0
-      if (Changed[x][y])       /* do not change already changed elements */
+      if (x == lx && y == ly)  /* do not change trigger element itself */
        continue;
 #endif
 
@@ -5674,31 +5636,37 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
        ChangeDelay[x][y] = 1;
        ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
        ChangeElement(x, y, page);
-
-#if 0
-       Changed[x][y] = TRUE;   /* prevent element from being changed again */
-#endif
       }
     }
   }
 
-#if 0
-  /* reset change prevention array */
-  for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
-    Changed[x][y] = FALSE;
-#endif
-
   return TRUE;
 }
 
-static boolean CheckElementChangeExt(int x, int y, int element,
-                                    int trigger_event, int page)
+static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
+                                          int trigger_event)
+{
+  return CheckTriggeredElementSideChange(lx, ly, trigger_element, CH_SIDE_ANY,
+                                        trigger_event);
+}
+
+static boolean CheckElementSideChange(int x, int y, int element, int side,
+                                     int trigger_event, int page)
 {
   if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event))
     return FALSE;
 
   if (Feld[x][y] == EL_BLOCKED)
+  {
     Blocked2Moving(x, y, &x, &y);
+    element = Feld[x][y];
+  }
+
+  if (page < 0)
+    page = element_info[element].event_page_num[trigger_event];
+
+  if (!(element_info[element].change_page[page].sides & side))
+    return FALSE;
 
   ChangeDelay[x][y] = 1;
   ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
@@ -5709,9 +5677,7 @@ static boolean CheckElementChangeExt(int x, int y, int element,
 
 static boolean CheckElementChange(int x, int y, int element, int trigger_event)
 {
-  int page = element_info[element].event_page_num[trigger_event];
-
-  return CheckElementChangeExt(x, y, element, trigger_event, page);
+  return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1);
 }
 
 static void PlayerActions(struct PlayerInfo *player, byte player_action)
@@ -6435,8 +6401,22 @@ static void CheckGravityMovement(struct PlayerInfo *player)
 boolean MoveFigureOneStep(struct PlayerInfo *player,
                          int dx, int dy, int real_dx, int real_dy)
 {
+  static int change_sides[4][2] =
+  {
+    /* enter side        leave side */
+    { CH_SIDE_RIGHT,   CH_SIDE_LEFT    },      /* moving left  */
+    { CH_SIDE_LEFT,    CH_SIDE_RIGHT   },      /* moving right */
+    { CH_SIDE_BOTTOM,  CH_SIDE_TOP     },      /* moving up    */
+    { CH_SIDE_TOP,     CH_SIDE_BOTTOM  }       /* moving down  */
+  };
+  int move_direction = (dx == -1 ? MV_LEFT :
+                       dx == +1 ? MV_RIGHT :
+                       dy == -1 ? MV_UP :
+                       dy == +1 ? MV_DOWN : MV_NO_MOVING);
+  int enter_side = change_sides[MV_DIR_BIT(move_direction)][0];
+  int leave_side = change_sides[MV_DIR_BIT(move_direction)][1];
   int jx = player->jx, jy = player->jy;
-  int new_jx = jx+dx, new_jy = jy+dy;
+  int new_jx = jx + dx, new_jy = jy + dy;
   int element;
   int can_move;
 
@@ -6488,15 +6468,33 @@ boolean MoveFigureOneStep(struct PlayerInfo *player,
   StorePlayer[jx][jy] = 0;
   player->last_jx = jx;
   player->last_jy = jy;
-  jx = player->jx = new_jx;
-  jy = player->jy = new_jy;
-  StorePlayer[jx][jy] = player->element_nr;
+  player->jx = new_jx;
+  player->jy = new_jy;
+  StorePlayer[new_jx][new_jy] = player->element_nr;
 
   player->MovPos =
     (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value);
 
   ScrollFigure(player, SCROLL_INIT);
 
+#if 1
+  if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
+  {
+    CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+                                   CE_OTHER_GETS_LEFT);
+    CheckElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+                          CE_LEFT_BY_PLAYER, -1);
+  }
+
+  if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy]))
+  {
+    CheckTriggeredElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy],
+                                   enter_side, CE_OTHER_GETS_ENTERED);
+    CheckElementSideChange(new_jx, new_jy, Feld[new_jx][new_jy], enter_side,
+                          CE_ENTERED_BY_PLAYER, -1);
+  }
+#endif
+
   return MF_MOVING;
 }
 
@@ -6835,16 +6833,16 @@ void TestIfElementTouchesCustomElement(int x, int y)
     { +1, 0 },
     { 0, +1 }
   };
-  static int touching_side[4][2] =
+  static int change_sides[4][2] =
   {
-    { CE_TOUCHING_TOP_OF,      CE_TOUCHING_BOTTOM_OF   },
-    { CE_TOUCHING_LEFT_OF,     CE_TOUCHING_RIGHT_OF    },
-    { CE_TOUCHING_RIGHT_OF,    CE_TOUCHING_LEFT_OF     },
-    { CE_TOUCHING_BOTTOM_OF,   CE_TOUCHING_TOP_OF      }
+    /* center side       border side */
+    { CH_SIDE_TOP,     CH_SIDE_BOTTOM  },      /* check top    */
+    { CH_SIDE_LEFT,    CH_SIDE_RIGHT   },      /* check left   */
+    { CH_SIDE_RIGHT,   CH_SIDE_LEFT    },      /* check right  */
+    { CH_SIDE_BOTTOM,  CH_SIDE_TOP     }       /* check bottom */
   };
   boolean change_center_element = FALSE;
   int center_element_change_page = 0;
-  int center_element_change_event = 0;
   int center_element = Feld[x][y];
   int i, j;
 
@@ -6859,8 +6857,8 @@ void TestIfElementTouchesCustomElement(int x, int y)
   {
     int xx = x + xy[i][0];
     int yy = y + xy[i][1];
-    int change_event_center = touching_side[i][0];
-    int change_event_border = touching_side[i][1];
+    int center_side = change_sides[i][0];
+    int border_side = change_sides[i][1];
     int border_element;
 
     if (!IN_LEV_FIELD(xx, yy))
@@ -6870,7 +6868,7 @@ void TestIfElementTouchesCustomElement(int x, int y)
 
     /* check for change of center element (but change it only once) */
     if (IS_CUSTOM_ELEMENT(center_element) &&
-       HAS_ANY_CHANGE_EVENT(center_element, change_event_border) &&
+       HAS_ANY_CHANGE_EVENT(center_element, CE_OTHER_IS_TOUCHING) &&
        !change_center_element)
     {
       for (j=0; j < element_info[center_element].num_change_pages; j++)
@@ -6878,12 +6876,12 @@ void TestIfElementTouchesCustomElement(int x, int y)
        struct ElementChangeInfo *change =
          &element_info[center_element].change_page[j];
 
-       if (change->events & CH_EVENT_BIT(change_event_border) &&
+       if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) &&
+           change->sides & border_side &&
            change->trigger_element == border_element)
        {
          change_center_element = TRUE;
          center_element_change_page = j;
-         center_element_change_event = change_event_border;
 
          break;
        }
@@ -6892,17 +6890,19 @@ void TestIfElementTouchesCustomElement(int x, int y)
 
     /* check for change of border element */
     if (IS_CUSTOM_ELEMENT(border_element) &&
-       HAS_ANY_CHANGE_EVENT(border_element, change_event_center))
+       HAS_ANY_CHANGE_EVENT(border_element, CE_OTHER_IS_TOUCHING))
     {
       for (j=0; j < element_info[border_element].num_change_pages; j++)
       {
        struct ElementChangeInfo *change =
          &element_info[border_element].change_page[j];
 
-       if (change->events & CH_EVENT_BIT(change_event_center) &&
+       if (change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) &&
+           change->sides & center_side &&
            change->trigger_element == center_element)
        {
-         CheckElementChangeExt(xx,yy, border_element, change_event_center, j);
+         CheckElementSideChange(xx, yy, border_element, CH_SIDE_ANY,
+                                CE_OTHER_IS_TOUCHING, j);
          break;
        }
       }
@@ -6910,8 +6910,8 @@ void TestIfElementTouchesCustomElement(int x, int y)
   }
 
   if (change_center_element)
-    CheckElementChangeExt(x, y, center_element, center_element_change_event,
-                         center_element_change_page);
+    CheckElementSideChange(x, y, center_element, CH_SIDE_ANY,
+                          CE_OTHER_IS_TOUCHING, center_element_change_page);
 
 #if 0
   check_changing = FALSE;
@@ -7247,6 +7247,16 @@ static boolean checkDiagonalPushing(struct PlayerInfo *player,
 int DigField(struct PlayerInfo *player,
             int x, int y, int real_dx, int real_dy, int mode)
 {
+#if 0
+  static int change_sides[4][2] =
+  {
+    /* enter side        leave side */
+    { CH_SIDE_RIGHT,   CH_SIDE_LEFT    },      /* moving left  */
+    { CH_SIDE_LEFT,    CH_SIDE_RIGHT   },      /* moving right */
+    { CH_SIDE_BOTTOM,  CH_SIDE_TOP     },      /* moving up    */
+    { CH_SIDE_TOP,     CH_SIDE_BOTTOM  }       /* moving down  */
+  };
+#endif
   boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
   int jx = player->jx, jy = player->jy;
   int dx = x - jx, dy = y - jy;
@@ -7255,6 +7265,10 @@ int DigField(struct PlayerInfo *player,
                        dx == +1 ? MV_RIGHT :
                        dy == -1 ? MV_UP :
                        dy == +1 ? MV_DOWN : MV_NO_MOVING);
+#if 0
+  int enter_side = change_sides[MV_DIR_BIT(move_direction)][0];
+  int leave_side = change_sides[MV_DIR_BIT(move_direction)][1];
+#endif
   int element;
 
   if (player->MovPos == 0)
@@ -7812,6 +7826,24 @@ int DigField(struct PlayerInfo *player,
   if (Feld[x][y] != element)           /* really digged/collected something */
     player->is_collecting = !player->is_digging;
 
+#if 0
+  if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
+  {
+    CheckTriggeredElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+                                   CE_OTHER_GETS_LEFT);
+    CheckElementSideChange(jx, jy, Feld[jx][jy], leave_side,
+                          CE_LEFT_BY_PLAYER, -1);
+  }
+
+  if (IS_CUSTOM_ELEMENT(Feld[x][y]))
+  {
+    CheckTriggeredElementSideChange(x, y, Feld[x][y], enter_side,
+                                   CE_OTHER_GETS_ENTERED);
+    CheckElementSideChange(x, y, Feld[x][y], enter_side,
+                          CE_ENTERED_BY_PLAYER, -1);
+  }
+#endif
+
   return MF_MOVING;
 }
 
index 1d0375f1a8fdc8f08f1dd799aa998ca35b38693b..bfb43280bfddfa04e48a22d70250057e6e236a28 100644 (file)
 #define CE_COLLISION           5
 #define CE_IMPACT              6
 #define CE_SMASHED             7
-#define CE_TOUCHING_ANY_SIDE_OF        8
+#define CE_OTHER_IS_TOUCHING   8
 #define CE_OTHER_IS_CHANGING   9
 #define CE_OTHER_IS_EXPLODING  10
 #define CE_OTHER_GETS_TOUCHED  11
 #define CE_BY_OTHER_ACTION     18      /* activates other element events */
 #define CE_BY_DIRECT_ACTION    19      /* activates direct element events */
 #define CE_OTHER_GETS_DIGGED   20
-#define CE_TOUCHING_LEFT_OF    21
-#define CE_TOUCHING_RIGHT_OF   22
-#define CE_TOUCHING_TOP_OF     23
-#define CE_TOUCHING_BOTTOM_OF  24
+#define CE_ENTERED_BY_PLAYER   21
+#define CE_LEFT_BY_PLAYER      22
+#define CE_OTHER_GETS_ENTERED  23
+#define CE_OTHER_GETS_LEFT     24
 
 /* values for derived change events (determined from properties above) */
 #define CE_TOUCHING_SOME_SIDE  25      /* summarized left/right/up/down/any */
                                  (CH_EVENT_VAR(e) |=  CH_EVENT_BIT(c)) : \
                                  (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
 
+/* values for change sides for custom elements */
+#define CH_SIDE_LEFT           MV_LEFT
+#define CH_SIDE_RIGHT          MV_RIGHT
+#define CH_SIDE_TOP            MV_UP
+#define CH_SIDE_BOTTOM         MV_DOWN
+#define CH_SIDE_LEFT_RIGHT     MV_HORIZONTAL
+#define CH_SIDE_TOP_BOTTOM     MV_VERTICAL
+#define CH_SIDE_ANY            MV_ANY_DIRECTION
+
 /* values for change power for custom elements */
 #define CP_NON_DESTRUCTIVE     0
 #define CP_HALF_DESTRUCTIVE    1
@@ -1251,7 +1260,8 @@ struct ElementChangeInfo
 {
   boolean can_change;          /* use or ignore this change info */
 
-  unsigned long events;                /* bitfield for change events */
+  unsigned long events;                /* change events */
+  int sides;                   /* change sides */
 
   short target_element;                /* target element after change */