+ {
+ /* !!! fix side (direction) orientation here and elsewhere !!! */
+ CheckElementSideChange(newx, newy, Feld[newx][newy],
+ direction, CE_COLLISION_ACTIVE, -1);
+
+ if (IN_LEV_FIELD(nextx, nexty))
+ {
+ static int opposite_directions[] =
+ {
+ MV_RIGHT,
+ MV_LEFT,
+ MV_DOWN,
+ MV_UP
+ };
+ int move_dir_bit = MV_DIR_BIT(direction);
+ int opposite_direction = opposite_directions[move_dir_bit];
+ int hitting_side = direction;
+ int touched_side = opposite_direction;
+ int hitting_element = Feld[newx][newy];
+ int touched_element = MovingOrBlocked2Element(nextx, nexty);
+ boolean object_hit = (!IS_MOVING(nextx, nexty) ||
+ MovDir[nextx][nexty] != direction ||
+ ABS(MovPos[nextx][nexty]) <= TILEY / 2);
+
+ if (object_hit)
+ {
+ int i;
+
+ CheckElementSideChange(nextx, nexty, Feld[nextx][nexty],
+ opposite_direction, CE_COLLISION_PASSIVE, -1);
+
+ if (IS_CUSTOM_ELEMENT(hitting_element) &&
+ HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_COLL_ACTIVE))
+ {
+ for (i = 0; i < element_info[hitting_element].num_change_pages; i++)
+ {
+ struct ElementChangeInfo *change =
+ &element_info[hitting_element].change_page[i];
+
+ if (change->can_change &&
+ change->events & CH_EVENT_BIT(CE_OTHER_IS_COLL_ACTIVE) &&
+ change->sides & touched_side &&
+ change->trigger_element == touched_element)
+ {
+ CheckElementSideChange(newx, newy, hitting_element,
+ CH_SIDE_ANY, CE_OTHER_IS_COLL_ACTIVE, i);
+ break;
+ }
+ }
+ }
+
+ if (IS_CUSTOM_ELEMENT(touched_element) &&
+ HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_IS_COLL_PASSIVE))
+ {
+ for (i = 0; i < element_info[touched_element].num_change_pages; i++)
+ {
+ struct ElementChangeInfo *change =
+ &element_info[touched_element].change_page[i];
+
+ if (change->can_change &&
+ change->events & CH_EVENT_BIT(CE_OTHER_IS_COLL_PASSIVE) &&
+ change->sides & hitting_side &&
+ change->trigger_element == hitting_element)
+ {
+ CheckElementSideChange(nextx, nexty, touched_element,
+ CH_SIDE_ANY, CE_OTHER_IS_COLL_PASSIVE, i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }