--- a/hedgewars/GSHandlers.inc Thu Feb 28 19:59:42 2013 +0100
+++ b/hedgewars/GSHandlers.inc Thu Feb 28 23:28:01 2013 +0200
@@ -616,6 +616,7 @@
else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
begin
lf:= Land[yy, xx] and (lfObject or lfBasic or lfIndestructible);
+ if lf = 0 then lf:= lfObject;
// If there's room below keep falling
if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
begin
@@ -5091,29 +5092,17 @@
end;
end;
-procedure DrawIce(x, y: Longint);
- const iceRadius :Longint = 32;
-var
- i, j: Longint;
- weight: Longint;
- landRect : TSDL_RECT;
-begin
- FillRoundInLandWithIce(x, y, iceRadius);
- SetAllHHToActive;
- landRect.x := min(max(x - iceRadius, 0), LAND_WIDTH - 1);
- landRect.y := min(max(y - iceRadius, 0), LAND_HEIGHT - 1);
- landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
- landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
- UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
-end;
-
procedure doStepIceGun(Gear: PGear);
const iceWaitCollision:Longint = 0;
const iceCollideWithGround:Longint = 1;
const iceWaitNextTarget:Longint = 2;
const iceCollideWithHog:Longint = 4;
+const iceCollideWithWater:Longint = 5;
+const waterFreezingTime:Longint = 500;
const groundFreezingTime:Longint = 1000;
+const iceRadius = 32;
+const iceHeight = 40;
var
HHGear: PGear;
ndX, ndY: hwFloat;
@@ -5160,24 +5149,40 @@
CheckCollisionWithLand(Gear);
if (State and gstCollision) <> 0 then
begin
- if IceState = iceWaitCollision then
+ if IceState = iceWaitCollision then
begin
- IceState := iceCollideWithGround;
- IceTime := GameTicks;
+ IceState := iceCollideWithGround;
+ IceTime := GameTicks;
+ end
+ end
+ else if (target.y >= cWaterLine) then
+ begin
+ if IceState = iceWaitCollision then
+ begin
+ IceState := iceCollideWithWater;
+ IceTime := GameTicks;
+ end;
end;
- end;
if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
- begin
+ begin
X:= HHGear^.X;
Y:= HHGear^.Y
- end;
+ end;
if (IceState = iceCollideWithGround) and ((GameTicks - IceTime) > groundFreezingTime) then
- begin
- DrawIce(Target.X, Target.Y);
+ begin
+ FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
+ SetAllHHToActive;
IceState := iceWaitNextTarget;
- end;
+ end;
+
+ if (IceState = iceCollideWithWater) and ((GameTicks - IceTime) > groundFreezingTime) then
+ begin
+ DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
+ SetAllHHToActive;
+ IceState := iceWaitNextTarget;
+ end;
// freeze nearby hogs
hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
--- a/hedgewars/uLandGraphics.pas Thu Feb 28 19:59:42 2013 +0100
+++ b/hedgewars/uLandGraphics.pas Thu Feb 28 23:28:01 2013 +0200
@@ -42,7 +42,7 @@
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);
-
+procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean;
implementation
@@ -263,8 +263,13 @@
if (i < 0) or
(i > LAND_WIDTH - 1) or
(j < 0) or
- (j > LAND_HEIGHT -1) or
- ((Land[j, i] and $FF00) = 0) then
+ (j > LAND_HEIGHT -1) then
+ begin
+ result := 0;
+ exit;
+ end;
+
+ if ((Land[j, i] and $FF00) = 0) and ((Land[j, i] and lfIce) = 0) then
begin
result := result + 1;
end;
@@ -328,7 +333,6 @@
end;
if isLandscapeEdge(getPixelWeight(i, t)) then
begin
- if Land[t, i] > 255 then Land[t, i] := Land[t, i] or lfIce and not lfDamaged;
if (LandPixels[py, px] and AMask < 255) and (LandPixels[py, px] and AMask > 0) then
LandPixels[py, px] := (IceEdgeColor and not AMask) or (LandPixels[py, px] and AMask)
else if (LandPixels[py, px] and AMask < 255) or (Land[t, i] > 255) then
@@ -336,36 +340,67 @@
end
else if Land[t, i] > 255 then
begin
- Land[t, i] := Land[t, i] or lfIce and not lfDamaged;
drawIcePixel(py, px)
- end
- end
+ end;
+ if Land[t, i] > 255 then Land[t, i] := Land[t, i] or lfIce and not lfDamaged;
+ end;
end
end;
procedure FillRoundInLandWithIce(X, Y, Radius: LongInt);
var dx, dy, d: LongInt;
+ landRect: TSDL_Rect;
begin
dx:= 0;
dy:= Radius;
d:= 3 - 2 * Radius;
- while (dx < dy) do
+while (dx < dy) do
+ begin
+ FillLandCircleLinesIce(x, y, dx, dy);
+ if (d < 0) then
+ d:= d + 4 * dx + 6
+ else
begin
- FillLandCircleLinesIce(x, y, dx, dy);
- if (d < 0) then
- d:= d + 4 * dx + 6
- else
+ d:= d + 4 * (dx - dy) + 10;
+ dec(dy)
+ end;
+ inc(dx)
+ end;
+if (dx = dy) then
+ FillLandCircleLinesIce(x, y, dx, dy);
+landRect.x := min(max(x - Radius, 0), LAND_WIDTH - 1);
+landRect.y := min(max(y - Radius, 0), LAND_HEIGHT - 1);
+landRect.w := min(2*Radius, LAND_WIDTH - landRect.x - 1);
+landRect.h := min(2*Radius, LAND_HEIGHT - landRect.y - 1);
+UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
+end;
+
+
+procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
+var
+ i, j: integer;
+ landRect: TSDL_Rect;
+begin
+for i := min(max(x - iceRadius, 0), LAND_WIDTH - 1) to min(max(x + iceRadius, 0), LAND_WIDTH - 1) do
+ begin
+ for j := min(max(y, 0), LAND_HEIGHT - 1) to min(max(y + iceHeight, 0), LAND_HEIGHT - 1) do
+ begin
+ if land[j, i] = 0 then
begin
- d:= d + 4 * (dx - dy) + 10;
- dec(dy)
+ land[j, i] := lfIce;
+ drawIcePixel(j, i);
end;
- inc(dx)
- end;
- if (dx = dy) then
- FillLandCircleLinesIce(x, y, dx, dy);
+ end;
+ end;
+landRect.x := min(max(x - iceRadius, 0), LAND_WIDTH - 1);
+landRect.y := min(max(y, 0), LAND_HEIGHT - 1);
+landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
+landRect.h := min(iceHeight, LAND_HEIGHT - landRect.y - 1);
+UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
end;
+
function FillLandCircleLinesBG(x, y, dx, dy: LongInt): Longword;
var i, t, by, bx: LongInt;
cnt: Longword;