hedgewars/uLandGraphics.pas
branchhedgeroid
changeset 7855 ddcdedd3330b
parent 7509 76e3a3fc17cd
child 8026 4a4f21070479
child 8579 d18bc19d780a
--- a/hedgewars/uLandGraphics.pas	Thu Nov 24 13:44:30 2011 +0100
+++ b/hedgewars/uLandGraphics.pas	Sun Oct 28 13:28:23 2012 +0100
@@ -1,6 +1,6 @@
 (*
  * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2011 Andrey Korotaev <unC0Rr@gmail.com>
+ * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,10 +22,10 @@
 interface
 uses uFloat, uConsts, uTypes;
 
-type PRangeArray = ^TRangeArray;
-     TRangeArray = array[0..31] of record
+type TRangeArray = array[0..31] of record
                                    Left, Right: LongInt;
                                    end;
+     PRangeArray = ^TRangeArray;
 
 function  addBgColor(OldColor, NewColor: LongWord): LongWord;
 function  SweepDirty: boolean;
@@ -36,8 +36,11 @@
 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte);
 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt);
 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
-procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
+procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean);
 function  LandBackPixel(x, y: LongInt): LongWord;
+procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
+procedure DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword);
+procedure DumpLandToLog(x, y, r: LongInt);
 
 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean;
 
@@ -56,7 +59,7 @@
         begin
         addBgColor:= NewColor;
         exit
-        end; 
+        end;
     // Get colors
     oRed   := (OldColor shr RShift);
     oGreen := (OldColor shr GShift);
@@ -69,7 +72,7 @@
     // Mix colors
     nRed   := min(255,((nRed*nAlpha) div 255) + ((oRed*oAlpha*byte(255-nAlpha)) div 65025));
     nGreen := min(255,((nGreen*nAlpha) div 255) + ((oGreen*oAlpha*byte(255-nAlpha)) div 65025));
-    nBlue  := min(255,((nBlue*nAlpha) div 255) + ((oBlue*oAlpha*byte(255-nAlpha)) div 65025)); 
+    nBlue  := min(255,((nBlue*nAlpha) div 255) + ((oBlue*oAlpha*byte(255-nAlpha)) div 65025));
     nAlpha := min(255, oAlpha + nAlpha);
 
     addBgColor := (nAlpha shl AShift) or (nRed shl RShift) or (nGreen shl GShift) or (nBlue shl BShift);
@@ -83,7 +86,7 @@
         if (Land[y + dy, i] and lfIndestructible) = 0 then
             Land[y + dy, i]:= Value;
 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
         if (Land[y - dy, i] and lfIndestructible) = 0 then
             Land[y - dy, i]:= Value;
 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
@@ -96,82 +99,107 @@
             Land[y - dx, i]:= Value;
 end;
 
-procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean);
+procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet, isCurrent: boolean);
 var i: LongInt;
 begin
 if not doSet then
-   begin
-   if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-          if (Land[y + dy, i] > 0) and (Land[y + dy, i] < 256) then dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data
-   if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-          if (Land[y - dy, i] > 0) and (Land[y - dy, i] < 256) then dec(Land[y - dy, i]);
-   if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-          if (Land[y + dx, i] > 0) and (Land[y + dx, i] < 256) then dec(Land[y + dx, i]);
-   if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-          if (Land[y - dx, i] > 0) and (Land[y - dx, i] < 256) then dec(Land[y - dx, i]);
-   end else
-   begin
-   if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-          if (Land[y + dy, i] < 256) then
-              inc(Land[y + dy, i]);
-   if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-          if (Land[y - dy, i] < 256) then
-              inc(Land[y - dy, i]);
-   if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-          if (Land[y + dx, i] < 256) then
-              inc(Land[y + dx, i]);
-   if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
-      for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-          if (Land[y - dx, i] < 256) then
-              inc(Land[y - dx, i]);
-   end
+    begin
+    if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y + dy, i]:= Land[y + dy, i] and $FF7F
+            else if Land[y + dy, i] and $007F > 0 then
+                Land[y + dy, i]:= (Land[y + dy, i] and $FF80) or ((Land[y + dy, i] and $7F) - 1);
+    if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y - dy, i]:= Land[y - dy, i] and $FF7F
+            else if Land[y - dy, i] and $007F > 0 then
+                Land[y - dy, i]:= (Land[y - dy, i] and $FF80) or ((Land[y - dy, i] and $7F) - 1);
+    if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y + dx, i]:= Land[y + dx, i] and $FF7F
+            else if Land[y + dx, i] and $007F > 0 then
+                Land[y + dx, i]:= (Land[y + dx, i] and $FF80) or ((Land[y + dx, i] and $7F) - 1);
+    if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y - dx, i]:= Land[y - dx, i] and $FF7F
+            else if Land[y - dx, i] and $007F > 0 then
+                Land[y - dx, i]:= (Land[y - dx, i] and $FF80) or ((Land[y - dx, i] and $7F) - 1)
+    end
+else
+    begin
+    if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y + dy, i]:= Land[y + dy, i] or $80
+            else if Land[y + dy, i] and $007F < 127 then
+                Land[y + dy, i]:= (Land[y + dy, i] and $FF80) or ((Land[y + dy, i] and $7F) + 1);
+    if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y - dy, i]:= Land[y - dy, i] or $80
+            else if Land[y - dy, i] and $007F < 127 then
+                Land[y - dy, i]:= (Land[y - dy, i] and $FF80) or ((Land[y - dy, i] and $7F) + 1);
+    if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y + dx, i]:= Land[y + dx, i] or $80
+            else if Land[y + dx, i] and $007F < 127 then
+                Land[y + dx, i]:= (Land[y + dx, i] and $FF80) or ((Land[y + dx, i] and $7F) + 1);
+    if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
+        for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+            if isCurrent then
+                Land[y - dx, i]:= Land[y - dx, i] or $80
+            else if Land[y - dx, i] and $007F < 127 then
+                Land[y - dx, i]:= (Land[y - dx, i] and $FF80) or ((Land[y - dx, i] and $7F) + 1)
+    end
 end;
 
 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
 var dx, dy, d: LongInt;
 begin
-  dx:= 0;
-  dy:= Radius;
-  d:= 3 - 2 * Radius;
-  while (dx < dy) do
-     begin
-     FillCircleLines(x, y, dx, dy, Value);
-     if (d < 0)
-     then d:= d + 4 * dx + 6
-     else begin
-          d:= d + 4 * (dx - dy) + 10;
-          dec(dy)
-          end;
-     inc(dx)
-     end;
-  if (dx = dy) then FillCircleLines(x, y, dx, dy, Value);
+dx:= 0;
+dy:= Radius;
+d:= 3 - 2 * Radius;
+while (dx < dy) do
+    begin
+    FillCircleLines(x, y, dx, dy, Value);
+    if (d < 0) then
+        d:= d + 4 * dx + 6
+    else
+        begin
+        d:= d + 4 * (dx - dy) + 10;
+        dec(dy)
+        end;
+    inc(dx)
+    end;
+if (dx = dy) then
+    FillCircleLines(x, y, dx, dy, Value);
 end;
 
-procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
+procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean);
 var dx, dy, d: LongInt;
 begin
-  dx:= 0;
-  dy:= Radius;
-  d:= 3 - 2 * Radius;
-  while (dx < dy) do
-     begin
-     ChangeCircleLines(x, y, dx, dy, doSet);
-     if (d < 0)
-     then d:= d + 4 * dx + 6
-     else begin
-          d:= d + 4 * (dx - dy) + 10;
-          dec(dy)
-          end;
-     inc(dx)
-     end;
-  if (dx = dy) then ChangeCircleLines(x, y, dx, dy, doSet)
+dx:= 0;
+dy:= Radius;
+d:= 3 - 2 * Radius;
+while (dx < dy) do
+    begin
+    ChangeCircleLines(x, y, dx, dy, doSet, isCurrent);
+    if (d < 0) then
+        d:= d + 4 * dx + 6
+    else
+        begin
+        d:= d + 4 * (dx - dy) + 10;
+        dec(dy)
+        end;
+    inc(dx)
+    end;
+if (dx = dy) then
+    ChangeCircleLines(x, y, dx, dy, doSet, isCurrent)
 end;
 
 procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
@@ -222,90 +250,90 @@
 cnt:= 0;
 t:= y + dy;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-       if (Land[t, i] and lfIndestructible) = 0 then
-           begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-               begin
-               by:= t; bx:= i;
-               end
-           else
-               begin
-               by:= t div 2; bx:= i div 2;
-               end;
-           if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not disableLandBack then
-               begin
-               inc(cnt);
-               LandPixels[by, bx]:= LandBackPixel(i, t)
-               end
-           else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
-               LandPixels[by, bx]:= 0
-           end;
+    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+        if (Land[t, i] and lfIndestructible) = 0 then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                begin
+                by:= t; bx:= i;
+                end
+            else
+                begin
+                by:= t div 2; bx:= i div 2;
+                end;
+            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
+                begin
+                inc(cnt);
+                LandPixels[by, bx]:= LandBackPixel(i, t)
+                end
+            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
+                LandPixels[by, bx]:= 0
+            end;
 
 t:= y - dy;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-       if (Land[t, i] and lfIndestructible) = 0 then
-           begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-               begin
-               by:= t; bx:= i;
-               end
-           else
-               begin
-               by:= t div 2; bx:= i div 2;
-               end;
-           if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not disableLandBack then
-               begin
-               inc(cnt);
-               LandPixels[by, bx]:= LandBackPixel(i, t)
-               end
-           else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
-               LandPixels[by, bx]:= 0
-           end;
+    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+        if (Land[t, i] and lfIndestructible) = 0 then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                begin
+                by:= t; bx:= i;
+                end
+            else
+                begin
+                by:= t div 2; bx:= i div 2;
+                end;
+            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
+                begin
+                inc(cnt);
+                LandPixels[by, bx]:= LandBackPixel(i, t)
+                end
+            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
+                LandPixels[by, bx]:= 0
+            end;
 
 t:= y + dx;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-       if (Land[t, i] and lfIndestructible) = 0 then
-           begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-               begin
-               by:= t; bx:= i;
-               end
-           else
-               begin
-               by:= t div 2; bx:= i div 2;
-               end;
-           if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not disableLandBack then
-               begin
-               inc(cnt);
-               LandPixels[by, bx]:= LandBackPixel(i, t)
-               end
-           else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
-               LandPixels[by, bx]:= 0
-           end;
+    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+        if (Land[t, i] and lfIndestructible) = 0 then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                begin
+                by:= t; bx:= i;
+                end
+            else
+                begin
+                by:= t div 2; bx:= i div 2;
+                end;
+            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
+                begin
+                inc(cnt);
+                LandPixels[by, bx]:= LandBackPixel(i, t)
+                end
+            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
+                LandPixels[by, bx]:= 0
+            end;
 t:= y - dx;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-       if (Land[t, i] and lfIndestructible) = 0 then
-           begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-               begin
-               by:= t; bx:= i;
-               end
-           else
-               begin
-               by:= t div 2; bx:= i div 2;
-               end;
-           if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not disableLandBack then
-               begin
-               inc(cnt);
-               LandPixels[by, bx]:= LandBackPixel(i, t)
-               end
-           else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
-               LandPixels[by, bx]:= 0
-           end;
+    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+        if (Land[t, i] and lfIndestructible) = 0 then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                begin
+                by:= t; bx:= i;
+                end
+            else
+                begin
+                by:= t div 2; bx:= i div 2;
+                end;
+            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
+                begin
+                inc(cnt);
+                LandPixels[by, bx]:= LandBackPixel(i, t)
+                end
+            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
+                LandPixels[by, bx]:= 0
+            end;
 FillLandCircleLinesBG:= cnt;
 end;
 
@@ -314,62 +342,62 @@
 begin
 t:= y + dy;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-       if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
-          begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-            LandPixels[t, i]:= cExplosionBorderColor
-          else
-            LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
+    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                LandPixels[t, i]:= ExplosionBorderColor
+            else
+                LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
 
-          Land[t, i]:= Land[t, i] or lfDamaged;
-          //Despeckle(i, t);
-          LandDirty[t div 32, i div 32]:= 1;
-          end;
+            Land[t, i]:= Land[t, i] or lfDamaged;
+            //Despeckle(i, t);
+            LandDirty[t div 32, i div 32]:= 1;
+            end;
 
 t:= y - dy;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
-       if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
-          begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-              LandPixels[t, i]:= cExplosionBorderColor
+    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
+        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                LandPixels[t, i]:= ExplosionBorderColor
             else
-              LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
-          Land[t, i]:= Land[t, i] or lfDamaged;
-          //Despeckle(i, t);
-          LandDirty[t div 32, i div 32]:= 1;
-          end;
+                LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
+            Land[t, i]:= Land[t, i] or lfDamaged;
+            //Despeckle(i, t);
+            LandDirty[t div 32, i div 32]:= 1;
+            end;
 
 t:= y + dx;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-       if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
-           begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-           LandPixels[t, i]:= cExplosionBorderColor
+    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                LandPixels[t, i]:= ExplosionBorderColor
             else
-           LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
+               LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
 
-           Land[t, i]:= Land[t, i] or lfDamaged;
-           //Despeckle(i, t);
-           LandDirty[t div 32, i div 32]:= 1;
-           end;
+            Land[t, i]:= Land[t, i] or lfDamaged;
+            //Despeckle(i, t);
+            LandDirty[t div 32, i div 32]:= 1;
+            end;
 
 t:= y - dx;
 if (t and LAND_HEIGHT_MASK) = 0 then
-   for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
-       if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
-          begin
-           if (cReducedQuality and rqBlurryLand) = 0 then
-          LandPixels[t, i]:= cExplosionBorderColor
+    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
+        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
+            begin
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                LandPixels[t, i]:= ExplosionBorderColor
             else
-          LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
+                LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
 
-          Land[t, i]:= Land[t, i] or lfDamaged;
-          //Despeckle(i, y - dy);
-          LandDirty[t div 32, i div 32]:= 1;
-          end;
+            Land[t, i]:= Land[t, i] or lfDamaged;
+            //Despeckle(i, y - dy);
+            LandDirty[t div 32, i div 32]:= 1;
+            end;
 end;
 
 function DrawExplosion(X, Y, Radius: LongInt): Longword;
@@ -387,15 +415,17 @@
     while (dx < dy) do
         begin
         inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
-        if (d < 0)
-        then d:= d + 4 * dx + 6
-        else begin
+        if (d < 0) then
+            d:= d + 4 * dx + 6
+        else
+            begin
             d:= d + 4 * (dx - dy) + 10;
             dec(dy)
             end;
         inc(dx)
         end;
-    if (dx = dy) then inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
+    if (dx = dy) then
+        inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
     end;
 
 // draw a hole in land
@@ -408,15 +438,17 @@
     while (dx < dy) do
         begin
         FillLandCircleLines0(x, y, dx, dy);
-        if (d < 0)
-        then d:= d + 4 * dx + 6
-        else begin
+        if (d < 0) then
+            d:= d + 4 * dx + 6
+        else
+            begin
             d:= d + 4 * (dx - dy) + 10;
             dec(dy)
             end;
         inc(dx)
         end;
-    if (dx = dy) then FillLandCircleLines0(x, y, dx, dy);
+    if (dx = dy) then
+        FillLandCircleLines0(x, y, dx, dy);
     end;
 
   // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function
@@ -431,22 +463,24 @@
     while (dx < dy) do
         begin
         FillLandCircleLinesEBC(x, y, dx, dy);
-        if (d < 0)
-        then d:= d + 4 * dx + 6
-        else begin
+        if (d < 0) then
+            d:= d + 4 * dx + 6
+        else
+            begin
             d:= d + 4 * (dx - dy) + 10;
             dec(dy)
             end;
         inc(dx)
         end;
-    if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy);
+    if (dx = dy) then
+        FillLandCircleLinesEBC(x, y, dx, dy);
     end;
 
 tx:= Max(X - Radius - 1, 0);
 dx:= Min(X + Radius + 1, LAND_WIDTH) - tx;
 ty:= Max(Y - Radius - 1, 0);
 dy:= Min(Y + Radius + 1, LAND_HEIGHT) - ty;
-UpdateLandTexture(tx, dx, ty, dy);
+UpdateLandTexture(tx, dx, ty, dy, false);
 DrawExplosion:= cnt
 end;
 
@@ -468,9 +502,9 @@
                     begin
                     by:= ty div 2; bx:= tx div 2;
                     end;
-                if ((Land[ty, tx] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not disableLandBack then
+                if ((Land[ty, tx] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
                     LandPixels[by, bx]:= LandBackPixel(tx, ty)
-                else if ((Land[ty, tx] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
+                else if ((Land[ty, tx] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
                     LandPixels[by, bx]:= 0
                 end
             end;
@@ -486,10 +520,10 @@
         for tx:= Max(0, ar^[i].Left - Radius) to Min(LAND_WIDTH, ar^[i].Right + Radius) do
             if ((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0) then
                 begin
-                    if (cReducedQuality and rqBlurryLand) = 0 then
-                        LandPixels[ty, tx]:= cExplosionBorderColor
-                    else
-                        LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor;
+                 if (cReducedQuality and rqBlurryLand) = 0 then
+                    LandPixels[ty, tx]:= ExplosionBorderColor
+                else
+                    LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor;
 
                 Land[ty, tx]:= Land[ty, tx] or lfDamaged;
                 LandDirty[ty div 32, tx div 32]:= 1;
@@ -498,7 +532,7 @@
     end;
 
 
-UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT)
+UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false)
 end;
 
 //
@@ -529,19 +563,19 @@
     Y:= Y + dY;
     tx:= hwRound(X);
     ty:= hwRound(Y);
-    if ((ty and LAND_HEIGHT_MASK) = 0) and
-       ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and lfBasic) <> 0) or
-       ((Land[ty, tx] and lfObject) <> 0)) then
+    if ((ty and LAND_HEIGHT_MASK) = 0)
+    and ((tx and LAND_WIDTH_MASK) = 0)
+    and (((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        if despeckle then 
+        if despeckle then
             begin
             Land[ty, tx]:= Land[ty, tx] or lfDamaged;
             LandDirty[ty div 32, tx div 32]:= 1
             end;
         if (cReducedQuality and rqBlurryLand) = 0 then
-            LandPixels[ty, tx]:= cExplosionBorderColor
-        else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+            LandPixels[ty, tx]:= ExplosionBorderColor
+        else
+            LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
         end
     end;
     nx:= nx - dY;
@@ -553,23 +587,23 @@
     X:= nx - dX8;
     Y:= ny - dY8;
     for t:= 0 to 7 do
-    begin
-    X:= X + dX;
-    Y:= Y + dY;
-    tx:= hwRound(X);
-    ty:= hwRound(Y);
-    if ((ty and LAND_HEIGHT_MASK) = 0) and
-       ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and lfBasic) <> 0) or
-       ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
-        if despeckle then LandDirty[ty div 32, tx div 32]:= 1;
-        if (cReducedQuality and rqBlurryLand) = 0 then
-            LandPixels[ty, tx]:= cExplosionBorderColor
-        else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
-        end
-    end;
+        X:= X + dX;
+        Y:= Y + dY;
+        tx:= hwRound(X);
+        ty:= hwRound(Y);
+        if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
+        or ((Land[ty, tx] and lfObject) <> 0)) then
+            begin
+            Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+            if despeckle then
+                LandDirty[ty div 32, tx div 32]:= 1;
+            if (cReducedQuality and rqBlurryLand) = 0 then
+                LandPixels[ty, tx]:= ExplosionBorderColor
+            else
+                LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
+            end
+        end;
     X:= nx;
     Y:= ny;
     for t:= 0 to ticks do
@@ -588,7 +622,7 @@
                 begin
                 by:= ty div 2; bx:= tx div 2;
                 end;
-            if ((Land[ty, tx] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and not disableLandBack then
+            if ((Land[ty, tx] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
                 LandPixels[by, bx]:= LandBackPixel(tx, ty)
             else if ((Land[ty, tx] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
                 LandPixels[by, bx]:= 0;
@@ -601,18 +635,18 @@
     Y:= Y + dY;
     tx:= hwRound(X);
     ty:= hwRound(Y);
-    if ((ty and LAND_HEIGHT_MASK) = 0) and
-       ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and lfBasic) <> 0) or
-       ((Land[ty, tx] and lfObject) <> 0)) then
+    if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
+    or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
-        if despeckle then LandDirty[ty div 32, tx div 32]:= 1;
+        if despeckle then
+            LandDirty[ty div 32, tx div 32]:= 1;
         if (cReducedQuality and rqBlurryLand) = 0 then
-            LandPixels[ty, tx]:= cExplosionBorderColor
-        else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+            LandPixels[ty, tx]:= ExplosionBorderColor
+        else
+            LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
         end
-    end;
+        end;
     nx:= nx - dY;
     ny:= ny + dX;
     end;
@@ -627,16 +661,16 @@
     Y:= Y + dY;
     tx:= hwRound(X);
     ty:= hwRound(Y);
-    if ((ty and LAND_HEIGHT_MASK) = 0) and
-       ((tx and LAND_WIDTH_MASK) = 0) and
-       (((Land[ty, tx] and lfBasic) <> 0) or
-       ((Land[ty, tx] and lfObject) <> 0)) then
+    if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
+    or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
-        if despeckle then LandDirty[ty div 32, tx div 32]:= 1;
+        if despeckle then
+            LandDirty[ty div 32, tx div 32]:= 1;
         if (cReducedQuality and rqBlurryLand) = 0 then
-            LandPixels[ty, tx]:= cExplosionBorderColor
-        else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+            LandPixels[ty, tx]:= ExplosionBorderColor
+        else
+            LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
         end
     end;
     nx:= nx - dY;
@@ -648,7 +682,7 @@
 ddx:= Min(stX + HalfWidth * 2 + 4 + abs(hwRound(dX * ticks)), LAND_WIDTH) - tx;
 ddy:= Min(stY + HalfWidth * 2 + 4 + abs(hwRound(dY * ticks)), LAND_HEIGHT) - ty;
 
-UpdateLandTexture(tx, ddx, ty, ddy)
+UpdateLandTexture(tx, ddx, ty, ddy, false)
 end;
 
 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean;
@@ -656,6 +690,7 @@
     p: PByteArray;
     Image: PSDL_Surface;
 begin
+TryPlaceOnLand:= false;
 numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height;
 
 TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true);
@@ -666,205 +701,220 @@
 col:= Frame div numFramesFirstCol;
 
 if SDL_MustLock(Image) then
-   SDLTry(SDL_LockSurface(Image) >= 0, true);
+    SDLTry(SDL_LockSurface(Image) >= 0, true);
 
 bpp:= Image^.format^.BytesPerPixel;
 TryDo(bpp = 4, 'It should be 32 bpp sprite', true);
 // Check that sprite fits free space
 p:= @(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]);
 case bpp of
-     4: for y:= 0 to Pred(h) do
-            begin
-            for x:= 0 to Pred(w) do
-                if PLongword(@(p^[x * 4]))^ <> 0 then
-                   if ((cpY + y) <= Longint(topY)) or
-                      ((cpY + y) >= LAND_HEIGHT) or
-                      ((cpX + x) <= Longint(leftX)) or
-                      ((cpX + x) >= Longint(rightX)) or
-                      (Land[cpY + y, cpX + x] <> 0) then
-                      begin
-                      if SDL_MustLock(Image) then
-                         SDL_UnlockSurface(Image);
-                      exit(false)
-                      end;
-            p:= @(p^[Image^.pitch]);
-            end;
-     end;
+    4: for y:= 0 to Pred(h) do
+        begin
+        for x:= 0 to Pred(w) do
+            if (PLongword(@(p^[x * 4]))^) <> 0 then
+                if ((cpY + y) <= Longint(topY)) or ((cpY + y) >= LAND_HEIGHT) or
+                   ((cpX + x) <= Longint(leftX)) or ((cpX + x) >= Longint(rightX)) or (Land[cpY + y, cpX + x] <> 0) then
+                    begin
+                        if SDL_MustLock(Image) then
+                            SDL_UnlockSurface(Image);
+                        exit;
+                    end;
+        p:= @(p^[Image^.pitch]);
+        end;
+    end;
 
 TryPlaceOnLand:= true;
 if not doPlace then
-   begin
-   if SDL_MustLock(Image) then
-      SDL_UnlockSurface(Image);
-   exit
-   end;
+    begin
+    if SDL_MustLock(Image) then
+        SDL_UnlockSurface(Image);
+    exit
+    end;
 
 // Checked, now place
 p:= @(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]);
 case bpp of
-     4: for y:= 0 to Pred(h) do
-            begin
-            for x:= 0 to Pred(w) do
-                if PLongword(@(p^[x * 4]))^ <> 0 then
+    4: for y:= 0 to Pred(h) do
+        begin
+        for x:= 0 to Pred(w) do
+            if (PLongword(@(p^[x * 4]))^) <> 0 then
                    begin
-                   if (cReducedQuality and rqBlurryLand) = 0 then
-                       begin
-                       gX:= cpX + x;
-                       gY:= cpY + y;
-                       end
-                   else
-                       begin
-                       gX:= (cpX + x) div 2;
-                       gY:= (cpY + y) div 2;
-                       end;
-                   if indestructible then
-                       Land[cpY + y, cpX + x]:= lfIndestructible
-                   else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then  // This test assumes lfBasic and lfObject differ only graphically
-                       Land[cpY + y, cpX + x]:= lfBasic
-                   else
-                       Land[cpY + y, cpX + x]:= lfObject;
-                   // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun
-                   if (Theme = 'Snow') or (Theme = 'Christmas') then Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or lfIce;
-                   LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
-                   end;
-            p:= @(p^[Image^.pitch]);
-            end;
-     end;
+                if (cReducedQuality and rqBlurryLand) = 0 then
+                    begin
+                    gX:= cpX + x;
+                    gY:= cpY + y;
+                    end
+                else
+                     begin
+                     gX:= (cpX + x) div 2;
+                     gY:= (cpY + y) div 2;
+                    end;
+                if indestructible then
+                    Land[cpY + y, cpX + x]:= lfIndestructible
+                else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then  // This test assumes lfBasic and lfObject differ only graphically
+                    Land[cpY + y, cpX + x]:= lfBasic
+                else
+                    Land[cpY + y, cpX + x]:= lfObject;
+                // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun
+                if (Theme = 'Snow') or (Theme = 'Christmas') then
+                    Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or lfIce;
+                    LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
+                end;
+        p:= @(p^[Image^.pitch]);
+        end;
+    end;
 if SDL_MustLock(Image) then
-   SDL_UnlockSurface(Image);
+    SDL_UnlockSurface(Image);
 
 x:= Max(cpX, leftX);
 w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
 y:= Max(cpY, topY);
 h:= Min(cpY + Image^.h, LAND_HEIGHT) - y;
-UpdateLandTexture(x, w, y, h)
+UpdateLandTexture(x, w, y, h, true)
 end;
 
 function Despeckle(X, Y: LongInt): boolean;
 var nx, ny, i, j, c, xx, yy: LongInt;
     pixelsweep: boolean;
 begin
-if (cReducedQuality and rqBlurryLand) = 0 then
-   begin
-   xx:= X;
-   yy:= Y;
-   end
-else
-   begin
-   xx:= X div 2;
-   yy:= Y div 2;
-   end;
-pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
-if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
+    Despeckle:= true;
+
+    if (cReducedQuality and rqBlurryLand) = 0 then
+    begin
+        xx:= X;
+        yy:= Y;
+    end
+    else
+    begin
+        xx:= X div 2;
+        yy:= Y div 2;
+    end;
+
+    pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
+    if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
     begin
-    c:= 0;
-    for i:= -1 to 1 do
-        for j:= -1 to 1 do
-            if (i <> 0) or (j <> 0) then
+        c:= 0;
+        for i:= -1 to 1 do
+            for j:= -1 to 1 do
+                if (i <> 0) or (j <> 0) then
                 begin
-                ny:= Y + i;
-                nx:= X + j;
-                if ((ny and LAND_HEIGHT_MASK) = 0) and ((nx and LAND_WIDTH_MASK) = 0) then
+                    ny:= Y + i;
+                    nx:= X + j;
+                    if ((ny and LAND_HEIGHT_MASK) = 0) and ((nx and LAND_WIDTH_MASK) = 0) then
                     begin
-                    if pixelsweep then
+                        if pixelsweep then
                         begin
-                        if ((cReducedQuality and rqBlurryLand) <> 0) then
+                            if ((cReducedQuality and rqBlurryLand) <> 0) then
                             begin
-                            nx:= nx div 2;
-                            ny:= ny div 2
+                                nx:= nx div 2;
+                                ny:= ny div 2
                             end;
-                        if LandPixels[ny, nx] <> 0 then inc(c);
+                            if LandPixels[ny, nx] <> 0 then
+                                inc(c);
                         end
-                    else if Land[ny, nx] > 255 then inc(c);
+                    else if Land[ny, nx] > 255 then
+                        inc(c);
                     end
                 end;
 
-    if c < 4 then // 0-3 neighbours
+        if c < 4 then // 0-3 neighbours
         begin
-        if ((Land[Y, X] and lfBasic) <> 0) and not disableLandBack then
-            LandPixels[yy, xx]:= LandBackPixel(X, Y)
-        else
-            LandPixels[yy, xx]:= 0;
+            if ((Land[Y, X] and lfBasic) <> 0) and (not disableLandBack) then
+                LandPixels[yy, xx]:= LandBackPixel(X, Y)
+            else
+                LandPixels[yy, xx]:= 0;
 
-        Land[Y, X]:= 0;
-        if not pixelsweep then exit(true);
+            if not pixelsweep then
+            begin
+                Land[Y, X]:= 0;
+                exit
+            end
         end;
     end;
-Despeckle:= false
+    Despeckle:= false
 end;
 
 procedure Smooth(X, Y: LongInt);
 begin
 // a bit of AA for explosions
-if (Land[Y, X] = 0) and (Y > LongInt(topY) + 1) and 
-   (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
+if (Land[Y, X] = 0) and (Y > LongInt(topY) + 1) and
+    (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
     begin
-    if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0)) or
-       (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
+    if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0))
+    or (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
         begin
         if (cReducedQuality and rqBlurryLand) = 0 then
             begin
-            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and not AMask) or (128 shl AShift)
+            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then
+                LandPixels[y,x]:= (ExplosionBorderColor and (not AMask)) or (128 shl AShift)
             else
                 LandPixels[y,x]:=
-                                (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
-                                (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
-                                (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
+                                (((((LandPixels[y,x] and RMask shr RShift) div 2)+((ExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
+                                (((((LandPixels[y,x] and GMask shr GShift) div 2)+((ExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
+                                (((((LandPixels[y,x] and BMask shr BShift) div 2)+((ExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
             end;
-        if (Land[y, x-1] = lfObject) then Land[y,x]:= lfObject
-        else if (Land[y, x+1] = lfObject) then Land[y,x]:= lfObject
-        else Land[y,x]:= lfBasic;
+        if (Land[y, x-1] = lfObject) then
+            Land[y,x]:= lfObject
+        else if (Land[y, x+1] = lfObject) then
+            Land[y,x]:= lfObject
+        else
+            Land[y,x]:= lfBasic;
         end
-    else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
-            (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
-            (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
-            (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
-            (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
-            (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
-            (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0)) or
-            (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
+    else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
+    or (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
+    or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
+    or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
+    or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
+    or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
+    or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))
+    or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
         begin
         if (cReducedQuality and rqBlurryLand) = 0 then
             begin
-            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and not AMask) or (64 shl AShift)
+            if ((LandPixels[y,x] and AMask) shr AShift) < 10 then
+                LandPixels[y,x]:= (ExplosionBorderColor and (not AMask)) or (64 shl AShift)
             else
                 LandPixels[y,x]:=
-                                (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
-                                (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
-                                (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
+                                (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((ExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
+                                (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((ExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
+                                (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((ExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
             end;
-        if (Land[y, x-1] = lfObject) then Land[y, x]:= lfObject
-        else if (Land[y, x+1] = lfObject) then Land[y, x]:= lfObject
-        else if (Land[y+1, x] = lfObject) then Land[y, x]:= lfObject
-        else if (Land[y-1, x] = lfObject) then Land[y, x]:= lfObject
+        if (Land[y, x-1] = lfObject) then
+            Land[y, x]:= lfObject
+        else if (Land[y, x+1] = lfObject) then
+            Land[y, x]:= lfObject
+        else if (Land[y+1, x] = lfObject) then
+            Land[y, x]:= lfObject
+        else if (Land[y-1, x] = lfObject) then
+        Land[y, x]:= lfObject
         else Land[y,x]:= lfBasic
         end
     end
-else if ((cReducedQuality and rqBlurryLand) = 0) and (LandPixels[Y, X] and AMask = 255) and
-    ((Land[Y, X] and (lfDamaged or lfBasic) = lfBasic) or (Land[Y, X] and (lfDamaged or lfBasic) = lfBasic)) and 
-    (Y > LongInt(topY) + 1) and (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
+else if ((cReducedQuality and rqBlurryLand) = 0) and (LandPixels[Y, X] and AMask = 255)
+and ((Land[Y, X] and (lfDamaged or lfBasic) = lfBasic) or (Land[Y, X] and (lfDamaged or lfBasic) = lfBasic))
+and (Y > LongInt(topY) + 1) and (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
     begin
-    if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0)) or
-       (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
+    if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0))
+    or (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
         begin
         LandPixels[y,x]:=
-                        (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
-                        (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
-                        (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
+                        (((((LandPixels[y,x] and RMask shr RShift) div 2)+((ExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
+                        (((((LandPixels[y,x] and GMask shr GShift) div 2)+((ExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
+                        (((((LandPixels[y,x] and BMask shr BShift) div 2)+((ExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
         end
-    else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
-            (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
-            (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
-            (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
-            (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
-            (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
-            (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0)) or
-            (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
+    else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
+    or (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
+    or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
+    or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
+    or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
+    or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
+    or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))
+    or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
         begin
         LandPixels[y,x]:=
-                        (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
-                        (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
-                        (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
+                        (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((ExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
+                        (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((ExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
+                        (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((ExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
         end
     end
 end;
@@ -921,7 +971,8 @@
                                     end
                                 end;
                     end;
-                if updateBlock then UpdateLandTexture(tx, 32, ty, 32);
+                if updateBlock then
+                    UpdateLandTexture(tx, 32, ty, 32, false);
                 LandDirty[y, x]:= 2;
                 end;
             end;
@@ -947,19 +998,204 @@
 // Return true if outside of land or not the value tested, used right now for some X/Y movement that does not use normal hedgehog movement in GSHandlers.inc
 function CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean; inline;
 begin
-     CheckLandValue:= ((X and LAND_WIDTH_MASK <> 0) or (Y and LAND_HEIGHT_MASK <> 0)) or ((Land[Y, X] and LandFlag) = 0)
+    CheckLandValue:= ((X and LAND_WIDTH_MASK <> 0) or (Y and LAND_HEIGHT_MASK <> 0)) or ((Land[Y, X] and LandFlag) = 0)
 end;
 
 function LandBackPixel(x, y: LongInt): LongWord; inline;
 var p: PLongWordArray;
 begin
-    if LandBackSurface = nil then LandBackPixel:= 0
+    if LandBackSurface = nil then
+        LandBackPixel:= 0
     else
-    begin
+        begin
         p:= LandBackSurface^.pixels;
         LandBackPixel:= p^[LandBackSurface^.w * (y mod LandBackSurface^.h) + (x mod LandBackSurface^.w)];// or $FF000000;
+        end
+end;
+
+
+procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
+var
+  eX, eY, dX, dY: LongInt;
+  i, sX, sY, x, y, d: LongInt;
+begin
+eX:= 0;
+eY:= 0;
+dX:= X2 - X1;
+dY:= Y2 - Y1;
+
+if (dX > 0) then
+    sX:= 1
+else
+    if (dX < 0) then
+        begin
+        sX:= -1;
+        dX:= -dX
+        end
+    else
+        sX:= dX;
+
+if (dY > 0) then
+    sY:= 1
+else
+    if (dY < 0) then
+        begin
+        sY:= -1;
+        dY:= -dY
+        end
+    else
+        sY:= dY;
+
+if (dX > dY) then
+    d:= dX
+else
+    d:= dY;
+
+x:= X1;
+y:= Y1;
+
+for i:= 0 to d do
+    begin
+    inc(eX, dX);
+    inc(eY, dY);
+    if (eX > d) then
+        begin
+        dec(eX, d);
+        inc(x, sX);
+        end;
+    if (eY > d) then
+        begin
+        dec(eY, d);
+        inc(y, sY);
+        end;
+
+    if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
+        Land[y, x]:= Color;
     end
 end;
 
+procedure DrawDots(x, y, xx, yy: Longint; Color: Longword); inline;
+begin
+    if (((x + xx) and LAND_WIDTH_MASK) = 0) and (((y + yy) and LAND_HEIGHT_MASK) = 0) then Land[y + yy, x + xx]:= Color;
+    if (((x + xx) and LAND_WIDTH_MASK) = 0) and (((y - yy) and LAND_HEIGHT_MASK) = 0) then Land[y - yy, x + xx]:= Color;
+    if (((x - xx) and LAND_WIDTH_MASK) = 0) and (((y + yy) and LAND_HEIGHT_MASK) = 0) then Land[y + yy, x - xx]:= Color;
+    if (((x - xx) and LAND_WIDTH_MASK) = 0) and (((y - yy) and LAND_HEIGHT_MASK) = 0) then Land[y - yy, x - xx]:= Color;
+    if (((x + yy) and LAND_WIDTH_MASK) = 0) and (((y + xx) and LAND_HEIGHT_MASK) = 0) then Land[y + xx, x + yy]:= Color;
+    if (((x + yy) and LAND_WIDTH_MASK) = 0) and (((y - xx) and LAND_HEIGHT_MASK) = 0) then Land[y - xx, x + yy]:= Color;
+    if (((x - yy) and LAND_WIDTH_MASK) = 0) and (((y + xx) and LAND_HEIGHT_MASK) = 0) then Land[y + xx, x - yy]:= Color;
+    if (((x - yy) and LAND_WIDTH_MASK) = 0) and (((y - xx) and LAND_HEIGHT_MASK) = 0) then Land[y - xx, x - yy]:= Color;
+end;
+
+procedure DrawLines(X1, Y1, X2, Y2, XX, YY: LongInt; color: Longword);
+var
+  eX, eY, dX, dY: LongInt;
+  i, sX, sY, x, y, d: LongInt;
+  f: boolean;
+begin
+    eX:= 0;
+    eY:= 0;
+    dX:= X2 - X1;
+    dY:= Y2 - Y1;
+
+    if (dX > 0) then
+        sX:= 1
+    else
+        if (dX < 0) then
+            begin
+            sX:= -1;
+            dX:= -dX
+            end
+        else
+            sX:= dX;
+
+    if (dY > 0) then
+        sY:= 1
+    else
+        if (dY < 0) then
+            begin
+            sY:= -1;
+            dY:= -dY
+            end
+        else
+            sY:= dY;
+
+    if (dX > dY) then
+        d:= dX
+    else
+        d:= dY;
+
+    x:= X1;
+    y:= Y1;
+
+    for i:= 0 to d do
+        begin
+        inc(eX, dX);
+        inc(eY, dY);
+
+        f:= eX > d;
+        if f then
+            begin
+            dec(eX, d);
+            inc(x, sX);
+            DrawDots(x, y, xx, yy, color)
+            end;
+        if (eY > d) then
+            begin
+            dec(eY, d);
+            inc(y, sY);
+            f:= true;
+            DrawDots(x, y, xx, yy, color)
+            end;
+
+        if not f then
+            DrawDots(x, y, xx, yy, color)
+        end
+end;
+
+procedure DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword);
+var dx, dy, d: LongInt;
+begin
+    dx:= 0;
+    dy:= Radius;
+    d:= 3 - 2 * Radius;
+    while (dx < dy) do
+        begin
+        DrawLines(x1, y1, x2, y2, dx, dy, color);
+        if (d < 0) then
+            d:= d + 4 * dx + 6
+        else
+            begin
+            d:= d + 4 * (dx - dy) + 10;
+            dec(dy)
+            end;
+        inc(dx)
+        end;
+    if (dx = dy) then
+        DrawLines(x1, y1, x2, y2, dx, dy, color);
+end;
+
+
+procedure DumpLandToLog(x, y, r: LongInt);
+var xx, yy, dx: LongInt;
+    s: shortstring;
+begin
+    s[0]:= char(r * 2 + 1);
+    for yy:= y - r to y + r do
+        begin
+        for dx:= 0 to r*2 do
+            begin
+            xx:= dx - r + x;
+            if (xx = x) and (yy = y) then
+                s[dx + 1]:= 'X'
+            else if Land[yy, xx] > 255 then
+                s[dx + 1]:= 'O'
+            else if Land[yy, xx] > 0 then
+                s[dx + 1]:= '*'
+            else
+                s[dx + 1]:= '.'
+            end;
+        AddFileLog('Land dump: ' + s);
+        end;
+end;
 
 end.