diff -r 1385ab7219d9 -r b98631bf2066 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Fri Feb 22 11:35:54 2013 +0400 +++ b/hedgewars/GSHandlers.inc Sat Feb 23 19:12:11 2013 +0200 @@ -5042,7 +5042,131 @@ A frozen hog will animate differently. To be decided, but possibly in a similar fashion to a grave when it comes to explosions. The hog might (possibly) not be damaged by explosions. This might make freezing potentially useful for friendlies in a bad position. It might be better to allow damage though. A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again. *) + + +procedure updateFuel(Gear: PGear); +var + t:LongInt; +begin + t:= Gear^.Health div 10; + if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then + begin + Gear^.Damage:= t; + FreeTexture(Gear^.Tex); + Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) + + '%', cWhiteColor, fntSmall) + end; + if GameTicks mod 10 = 0 then dec(Gear^.Health); +end; + + +procedure updateTarget(Gear:PGear; newX, newY:HWFloat); +begin + with Gear^ do + begin + dX:= newX; + dY:= newY; + Pos:= 0; + Target.X:= NoPointX; + LastDamage:= nil; + X:= Hedgehog^.Gear^.X; + Y:= Hedgehog^.Gear^.Y; + (* unfreeze all semifrozen hogs - make this generic hog cleanup + iter := GearsList; + while iter <> nil do + begin + if (iter^.Kind = gtHedgehog) and + (iter^.Hedgehog^.Effects[heFrozen] < 0) then + iter^.Hedgehog^.Effects[heFrozen]:= 0; + iter:= iter^.NextGear + end *) + end; +end; + + +function isLanscapeEdge(weight:Longint):boolean; +begin + result := (weight < 8) and (weight >= 2); +end; + +function isLanscape(weight:Longint):boolean; +begin + result := weight < 2; +end; + +function isEmptySpace(weight:Longint):boolean; +begin + result := not isLanscape(weight) and not isLanscapeEdge(weight); +end; + + +function getPixelWeight(x, y:Longint): Longint; +var + i, j:Longint; +begin + result := 0; + for i := max(x - 1, 0) to min(x + 1, LAND_WIDTH-1) do + begin + for j := max(y - 1, 0) to min(y + 1, LAND_HEIGHT-1) do + begin + if ((Land[j, i] and $FF00) = 0) then + begin + result := result + 1; + end; + end; + end; +end; + + +procedure drawIcePixel(x, y:Longint); +var + iceSurface: PSDL_Surface; + icePixels: PLongwordArray; + pictureX, pictureY: LongInt; +begin + iceSurface:= SpritesData[sprIceTexture].Surface; + pictureX := x mod iceSurface^.w; + pictureY := y mod iceSurface^.h; + icePixels := iceSurface^.pixels; + LandPixels[y, x] := icePixels^[pictureX + pictureY * iceSurface^.w]; + Land[y, x] := land[y, x] or lfIce; +end; + +procedure DrawIce(Gear: PGear; x, y: Longint); + const iceSize :Longint = 35; + const iceHalfSize :Longint = 17; +var + i, j: Longint; + weight: Longint; +begin + + for i := max(x - iceHalfSize, 0) to min(x + iceHalfSize, LAND_WIDTH-1) do + begin + for j := max(y - iceHalfSize, 0) to min(y + iceHalfSize, LAND_HEIGHT-1) do + begin + weight := getPixelWeight(i, j); + if isLanscape(weight) then + begin + drawIcePixel(i, j); + end else + begin + if isLanscapeEdge(weight) then + begin + LandPixels[j, i] := $FFB2AF8A; + end; + end; + end; + end; + UpdateLandTexture(x - iceHalfSize, iceSize, y - iceHalfSize, iceSize, true); +end; + + procedure doStepIceGun(Gear: PGear); +const iceWaitCollision:Longint = 0; +const iceCollideWithGround:Longint = 1; +const iceWaitNextTarget:Longint = 2; +const iceCollideWithHog:Longint = 4; +const groundFreezingTime:Longint = 1000; var HHGear: PGear; ndX, ndY: hwFloat; @@ -5058,16 +5182,9 @@ end else begin - t:= Gear^.Health div 10; - if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then - begin - Gear^.Damage:= t; - FreeTexture(Gear^.Tex); - Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) + - '%', cWhiteColor, fntSmall) - end + updateFuel(Gear); end; - if GameTicks mod 10 = 0 then dec(Gear^.Health); + with Gear^ do begin HedgehogChAngle(HHGear); @@ -5077,65 +5194,73 @@ ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then begin - dX:= ndX; - dY:= ndY; - Pos:= 0; - Target.X:= NoPointX; - LastDamage:= nil; - X:= HHGear^.X; - Y:= HHGear^.Y; -(* unfreeze all semifrozen hogs - make this generic hog cleanup - iter := GearsList; - while iter <> nil do - begin - if (iter^.Kind = gtHedgehog) and - (iter^.Hedgehog^.Effects[heFrozen] < 0) then - iter^.Hedgehog^.Effects[heFrozen]:= 0; - iter:= iter^.NextGear - end *) + updateTarget(Gear, ndX, ndY); + IceState := iceWaitCollision; end else begin X:= X + dX; Y:= Y + dY; gX:= hwRound(X); - gY:= hwRound(Y); - if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y)); + gY:= hwRound(Y); + if Target.X = NoPointX then + begin + t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y)); + end; + if Target.X <> NoPointX then - begin + begin + CheckCollisionWithLand(Gear); + if (State and gstCollision) <> 0 then + begin + if IceState = iceWaitCollision then + begin + IceState := iceCollideWithGround; + IceTime := GameTicks; + 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(Gear, Target.X, Target.Y); + IceState := iceWaitNextTarget; + end; + // freeze nearby hogs - if GameTicks mod 10 = 0 then dec(Gear^.Health); hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius); if hogs.size > 0 then for i:= 0 to hogs.size - 1 do + begin if hogs.ar^[i] <> HHGear then - begin - //if Gear^.Hedgehog^.Effects[heFrozen]:= 0; - end; + begin + //if Gear^.Hedgehog^.Effects[heFrozen]:= 0; + end; + end; inc(Pos) - end + end else if (t > 400) and ((gY > cWaterLine) or (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0)) and (Land[gY, gX] <> 0))) then - begin + begin Target.X:= gX; Target.Y:= gY; X:= HHGear^.X; Y:= HHGear^.Y - end; + end; if (gX > max(LAND_WIDTH,4096)*2) or (gX < -max(LAND_WIDTH,4096)) or (gY < -max(LAND_HEIGHT,4096)) or (gY > max(LAND_HEIGHT,4096)+512) then - begin + begin X:= HHGear^.X; Y:= HHGear^.Y - end + end end end; end;