+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);
+}
+