pull icegun into default. it has a few issues, but, pretty close. that way more people will play with it.
--- a/hedgewars/GSHandlers.inc Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/GSHandlers.inc Tue Feb 26 20:39:18 2013 -0500
@@ -1783,7 +1783,7 @@
Gear^.Y := Gear^.Y + Gear^.dY;
if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then
- SetAllHHToActive;
+ SetAllHHToActive(false);
if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
begin
@@ -2382,7 +2382,9 @@
repeat
CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
- until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0);
+ until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and
+ (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and
+ (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
AmmoMenuInvalidated:= true;
@@ -5044,7 +5046,138 @@
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);
+ var
+ iter:PGear;
+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] and $FF = 0) then
+ iter^.Hedgehog^.Effects[heFrozen]:= 0;
+ iter:= iter^.NextGear
+ end
+*)
+ end;
+end;
+
+
+function isLandscapeEdge(weight:Longint):boolean;
+begin
+ result := (weight < 8) and (weight >= 2);
+end;
+
+function isLandscape(weight:Longint):boolean;
+begin
+ result := weight < 2;
+end;
+
+function isEmptySpace(weight:Longint):boolean;
+begin
+ result := not isLandscape(weight) and not isLandscapeEdge(weight);
+end;
+
+
+function getPixelWeight(x, y:Longint): Longint;
+var
+ i, j:Longint;
+begin
+ result := 0;
+ for i := x - 1 to x + 1 do
+ for j := y - 1 to y + 1 do
+ begin
+ if (i < 0) or
+ (i > LAND_WIDTH - 1) or
+ (j < 0) or
+ (j > LAND_HEIGHT -1) or
+ ((Land[j, i] and $FF00) = 0) then
+ begin
+ result := result + 1;
+ end;
+ end;
+end;
+
+
+procedure drawIcePixel(x, y:Longint);
+var
+ iceSurface: PSDL_Surface;
+ icePixels: PLongwordArray;
+ pictureX, pictureY: LongInt;
+ w, c: LongWord;
+begin
+ if Land[y, x] and lfIce <> 0 then exit;
+// So. 3 parameters here. Ice colour, Ice opacity, and a bias on the greyscaled pixel towards lightness
+ iceSurface:= SpritesData[sprIceTexture].Surface;
+ pictureX := x mod iceSurface^.w;
+ pictureY := y mod iceSurface^.h;
+ icePixels := iceSurface^.pixels;
+ w:= LandPixels[y, x];
+ w:= round(((w shr RShift and $FF) * RGB_LUMINANCE_RED +
+ (w shr BShift and $FF) * RGB_LUMINANCE_GREEN +
+ (w shr GShift and $FF) * RGB_LUMINANCE_BLUE));
+ if w < 128 then w:= w+128;
+ if w > 255 then w:= 255;
+ w:= (w shl RShift) or (w shl BShift) or (w shl GShift) or (LandPixels[y,x] and AMask);
+ //LandPixels[y, x]:= w;
+ LandPixels[y, x]:= addBgColor(w, IceColor);
+ LandPixels[y, x]:= addBgColor(LandPixels[y, x], icePixels^[iceSurface^.w * (y mod iceSurface^.h) + (x mod iceSurface^.w)]);
+
+ Land[y, x] := Land[y, x] or lfIce;
+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 groundFreezingTime:Longint = 1000;
var
HHGear: PGear;
ndX, ndY: hwFloat;
@@ -5052,7 +5185,7 @@
hogs: PGearArrayS;
begin
HHGear := Gear^.Hedgehog^.Gear;
- if (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
+ if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
begin
DeleteGear(Gear);
AfterAttack;
@@ -5060,16 +5193,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);
@@ -5079,65 +5205,76 @@
((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(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);
+ hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
if hogs.size > 0 then
for i:= 0 to hogs.size - 1 do
if hogs.ar^[i] <> HHGear then
- begin
- //if Gear^.Hedgehog^.Effects[heFrozen]:= 0;
- end;
+ if GameTicks mod 5 = 0 then
+ begin
+ hogs.ar^[i]^.Active:= true;
+ if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
+ hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
+ else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
+ hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 100000
+ 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;
- if (gX > max(LAND_WIDTH,4096)*2) or
+ 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;
--- a/hedgewars/uGears.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uGears.pas Tue Feb 26 20:39:18 2013 -0500
@@ -46,7 +46,8 @@
procedure ProcessGears;
procedure EndTurnCleanup;
procedure SetAllToActive;
-procedure SetAllHHToActive;
+procedure SetAllHHToActive; inline;
+procedure SetAllHHToActive(Ice: boolean);
procedure DrawGears;
procedure FreeGearsList;
procedure AddMiscGears;
@@ -562,7 +563,12 @@
end
end;
-procedure SetAllHHToActive;
+procedure SetAllHHToActive; inline;
+begin
+SetAllHHToActive(true)
+end;
+
+procedure SetAllHHToActive(Ice: boolean);
var t: PGear;
begin
AllInactive:= false;
@@ -570,12 +576,14 @@
while t <> nil do
begin
if (t^.Kind = gtHedgehog) or (t^.Kind = gtExplosives) then
- t^.Active:= true;
+ begin
+ if (t^.Kind = gtHedgehog) and Ice then CheckIce(t);
+ t^.Active:= true
+ end;
t:= t^.NextGear
end
end;
-
procedure DrawGears;
var Gear: PGear;
x, y: LongInt;
@@ -766,6 +774,8 @@
begin
dec(i);
Gear:= t^.ar[i];
+ if (Ammo^.Kind = gtFlame) and (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
+ Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
tmpDmg:= ModifyDamage(Damage, Gear);
if (Gear^.State and gstNoDamage) = 0 then
begin
@@ -780,6 +790,7 @@
if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
Gear^.FlightTime:= 1;
+
case Gear^.Kind of
gtHedgehog,
gtMine,
--- a/hedgewars/uGearsHedgehog.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uGearsHedgehog.pas Tue Feb 26 20:39:18 2013 -0500
@@ -29,6 +29,7 @@
procedure HedgehogChAngle(HHGear: PGear);
procedure PickUp(HH, Gear: PGear);
procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
+procedure CheckIce(Gear: PGear); inline;
implementation
uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
@@ -377,7 +378,10 @@
end;
//amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
- amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
+ amIceGun: begin
+ newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
+ newGear^.radius := 8;
+ end;
end;
if altUse and (newGear <> nil) then
begin
@@ -778,7 +782,7 @@
if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) then
MakeHedgehogsStep(Gear);
- SetAllHHToActive;
+ SetAllHHToActive(false);
AddGearCI(Gear)
end
end;
@@ -1196,7 +1200,7 @@
if Gear^.Timer = 0 then
begin
Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
- Gear^.Active:= false;
+ if Gear^.Hedgehog^.Effects[heFrozen] = 0 then Gear^.Active:= false;
AddGearCI(Gear);
exit
end
@@ -1206,40 +1210,24 @@
AllInactive:= false
end;
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehog(Gear: PGear);
+procedure CheckIce(Gear: PGear); inline;
(*
var x,y,tx,ty: LongInt;
tdX, tdY, slope: hwFloat;
land: Word; *)
var slope: hwFloat;
begin
-CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
-if (Gear^.Message and gmDestroy) <> 0 then
- begin
- DeleteGear(Gear);
- exit
- end;
-
-if (Gear^.State and gstHHDriven) = 0 then
- doStepHedgehogFree(Gear)
-else
- begin
- with Gear^.Hedgehog^ do
- if Team^.hasGone then
- TeamGoneEffect(Team^)
- else
- doStepHedgehogDriven(Gear)
- end;
-if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
-and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
-and (not Gear^.dY.isNegative) and (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0)
-and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
- begin
- slope:= CalcSlopeBelowGear(Gear);
- Gear^.dX:=Gear^.dX+slope*_0_07;
- if slope.QWordValue <> 0 then
- Gear^.State:= Gear^.State or gstMoving;
+ if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
+ and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
+ and (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
+ begin
+ slope:= CalcSlopeBelowGear(Gear);
+ if slope.QWordValue > 730144440 then // ignore mild slopes
+ begin
+ Gear^.dX:=Gear^.dX+slope*cGravity*_256;
+ Gear^.State:= Gear^.State or gstMoving
+ end
+ end;
(*
x:= hwRound(Gear^.X);
y:= hwRound(Gear^.Y);
@@ -1254,7 +1242,35 @@
AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
- end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehog(Gear: PGear);
+begin
+CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
+if (Gear^.Message and gmDestroy) <> 0 then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+if GameTicks mod 100 = 0 then CheckIce(Gear);
+if Gear^.Hedgehog^.Effects[heFrozen] > 0 then
+ begin
+ if Gear^.Hedgehog^.Effects[heFrozen] > 256 then
+ dec(Gear^.Hedgehog^.Effects[heFrozen])
+ else if GameTicks mod 10 = 0 then
+ dec(Gear^.Hedgehog^.Effects[heFrozen])
+ end;
+if (Gear^.State and gstHHDriven) = 0 then
+ doStepHedgehogFree(Gear)
+else
+ begin
+ with Gear^.Hedgehog^ do
+ if Team^.hasGone then
+ TeamGoneEffect(Team^)
+ else
+ doStepHedgehogDriven(Gear)
+ end;
end;
end.
--- a/hedgewars/uGearsRender.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uGearsRender.pas Tue Feb 26 20:39:18 2013 -0500
@@ -211,6 +211,8 @@
defaultPos, HatVisible: boolean;
HH: PHedgehog;
CurWeapon: PAmmo;
+ iceOffset:Longint;
+ r:TSDL_Rect;
begin
HH:= Gear^.Hedgehog;
if HH^.Unplaced then
@@ -239,6 +241,29 @@
defaultPos:= true;
HatVisible:= false;
+ if HH^.Effects[heFrozen] > 0 then
+ if HH^.Effects[heFrozen] < 256 then
+ begin
+ DrawHedgehog(sx, sy,
+ sign,
+ 0,
+ 0,
+ 0);
+ defaultPos:= false;
+ HatVisible:= true
+ end
+ else
+ begin
+ DrawHedgehog(sx, sy,
+ sign,
+ 2,
+ 4,
+ 0);
+ defaultPos:= false;
+ HatVisible:= false;
+ exit
+ end;
+
if HH^.Effects[hePoisoned] <> 0 then
begin
@@ -247,6 +272,7 @@
Tint($FF, $FF, $FF, $FF)
end;
+
if ((Gear^.State and gstWinner) <> 0) and
((CurAmmoGear = nil) or (CurAmmoGear^.Kind <> gtPickHammer)) then
begin
@@ -538,7 +564,7 @@
DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
end;
gtIceGun:
- begin DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
+ begin DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
if CurAmmoGear^.Tex <> nil then
DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
end;
@@ -669,7 +695,7 @@
amBee: DrawSpriteRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
amFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
amLandGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
- amIceGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
+ amIceGun: DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
amResurrector: DrawCircle(ox, oy, 98, 4, $F5, $DB, $35, $AA); // I'd rather not like to hardcode 100 here
end;
@@ -917,6 +943,23 @@
Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - ((RealTicks div 2 + Gear^.uid * 491) mod 1500) / 750))));
DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0);
end;
+
+ if HH^.Effects[heFrozen] = HH^.Effects[heFrozen] and $FF then
+ begin
+ /// Tint($00, $FF, $40, $40); (HH^.Effects[heFrozen] and $FF)
+ iceOffset:= trunc(HH^.Effects[heFrozen] / 256 * 64);
+ Tint($FF, $FF, $FF, $FF);
+ r.x := 128;
+ r.y := 128 - iceOffset;
+ r.w := 64;
+ r.h := iceOffset;
+ //DrawTextureFromRect(sx-32, sy-iceoffset+32, @r, SpritesData[sprFrozenHog].texture);
+ DrawTextureFromRectDir(sx-16+sign*2, sy+48-iceoffset, r.w, r.h, @r, HHTexture, sign);
+
+ Tint($FF, $FF, $FF, $FF);
+ end;
+
+
if cVampiric and
(CurrentHedgehog^.Gear <> nil) and
(CurrentHedgehog^.Gear = Gear) then
--- a/hedgewars/uGearsUtils.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uGearsUtils.pas Tue Feb 26 20:39:18 2013 -0500
@@ -182,6 +182,7 @@
i:= _1;
if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then
i:= _1_5;
+if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Effects[heFrozen] > 0) then i:=i*_0_2;
if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then
ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5)
else
--- a/hedgewars/uLandGraphics.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uLandGraphics.pas Tue Feb 26 20:39:18 2013 -0500
@@ -36,6 +36,7 @@
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 FillRoundInLandWithIce(X, Y, Radius: LongInt);
procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean);
function LandBackPixel(x, y: LongInt): LongWord;
procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
@@ -158,6 +159,8 @@
end
end;
+
+
procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
var dx, dy, d: LongInt;
begin
@@ -243,6 +246,130 @@
end;
+
+function isLandscapeEdge(weight:Longint):boolean;
+begin
+ result := (weight < 8) and (weight >= 2);
+end;
+
+function isLandscape(weight:Longint):boolean;
+begin
+ result := weight < 2;
+end;
+
+function isEmptySpace(weight:Longint):boolean;
+begin
+ result := not isLandscape(weight) and not isLandscapeEdge(weight);
+end;
+
+function getPixelWeight(x, y:Longint): Longint;
+var
+ i, j:Longint;
+begin
+ result := 0;
+ for i := x - 1 to x + 1 do
+ for j := y - 1 to y + 1 do
+ begin
+ if (i < 0) or
+ (i > LAND_WIDTH - 1) or
+ (j < 0) or
+ (j > LAND_HEIGHT -1) or
+ ((Land[j, i] and $FF00) = 0) then
+ begin
+ result := result + 1;
+ end;
+ end;
+end;
+
+procedure drawIcePixel(y, x:Longint);
+var
+ iceSurface: PSDL_Surface;
+ icePixels: PLongwordArray;
+ pictureX, pictureY: LongInt;
+ w, c: LongWord;
+ weight: Longint;
+begin
+ weight := getPixelWeight(x, y);
+ if isLandscape(weight) then
+ begin
+ // So. 3 parameters here. Ice colour, Ice opacity, and a bias on the greyscaled pixel towards lightness
+ iceSurface:= SpritesData[sprIceTexture].Surface;
+ pictureX := x mod iceSurface^.w;
+ pictureY := y mod iceSurface^.h;
+ icePixels := iceSurface^.pixels;
+ w:= LandPixels[y, x];
+ w:= round(((w shr RShift and $FF) * RGB_LUMINANCE_RED +
+ (w shr BShift and $FF) * RGB_LUMINANCE_GREEN +
+ (w shr GShift and $FF) * RGB_LUMINANCE_BLUE));
+ if w < 128 then w:= w+128;
+ if w > 255 then w:= 255;
+ w:= (w shl RShift) or (w shl BShift) or (w shl GShift) or (LandPixels[y,x] and AMask);
+ //LandPixels[y, x]:= w;
+ LandPixels[y, x]:= addBgColor(w, IceColor);
+ LandPixels[y, x]:= addBgColor(LandPixels[y, x], icePixels^[iceSurface^.w * (y mod iceSurface^.h) + (x mod iceSurface^.w)]);
+ Land[y, x] := land[y, x] or lfIce;
+ end
+ else if (isLandscapeEdge(weight)) then
+ begin
+ LandPixels[y, x] := $FFB2AF8A;
+ if Land[y, x] > 255 then Land[y, x] := Land[y, x] or lfIce;
+ end;
+
+end;
+
+function getIncrementInquarter(dx, dy, quarter: Longint): Longint;
+const directionX : array [0..3] of Longint = (0, 0, 1, -1);
+const directionY : array [0..3] of Longint = (1, -1, 0, 0);
+begin
+ getIncrementInquarter := directionX[quarter] * dx + directionY[quarter] * dy;
+end;
+
+function getIncrementInquarter2(dx, dy, quarter: Longint): Longint;
+const directionY : array [0..3] of Longint = (0, 0, 1, 1);
+const directionX : array [0..3] of Longint = (1, 1, 0, 0);
+begin
+ getIncrementInquarter2 := directionX[quarter] * dx + directionY[quarter] * dy;
+end;
+
+procedure FillLandCircleLinesIce(x, y, dx, dy: LongInt);
+var q, i, t: LongInt;
+begin
+for q := 0 to 3 do
+ begin
+ t:= y + getIncrementInquarter(dx, dy, q);
+ if (t and LAND_HEIGHT_MASK) = 0 then
+ for i:= Max(x - getIncrementInquarter2(dx, dy, q), 0) to Min(x + getIncrementInquarter2(dx, dy, q), LAND_WIDTH - 1) do
+ if (Land[t, i] and (lfIndestructible or lfIce) = 0) and (not disableLandBack or (Land[t, i] > 255)) then
+ if (cReducedQuality and rqBlurryLand) = 0 then
+ drawIcePixel(t, i)
+ else
+ drawIcePixel(t div 2, i div 2) ;
+ end;
+end;
+
+procedure FillRoundInLandWithIce(X, Y, Radius: LongInt);
+var dx, dy, d: LongInt;
+begin
+dx:= 0;
+dy:= Radius;
+d:= 3 - 2 * Radius;
+ while (dx < dy) do
+ begin
+ FillLandCircleLinesIce(x, y, dx, dy);
+ 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
+ FillLandCircleLinesIce(x, y, dx, dy);
+end;
+
+
function FillLandCircleLinesBG(x, y, dx, dy: LongInt): Longword;
var i, t, by, bx: LongInt;
cnt: Longword;
@@ -350,7 +477,7 @@
else
LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
- Land[t, i]:= Land[t, i] or lfDamaged;
+ Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
//Despeckle(i, t);
LandDirty[t div 32, i div 32]:= 1;
end;
@@ -364,7 +491,7 @@
LandPixels[t, i]:= ExplosionBorderColor
else
LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
- Land[t, i]:= Land[t, i] or lfDamaged;
+ Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
//Despeckle(i, t);
LandDirty[t div 32, i div 32]:= 1;
end;
@@ -379,7 +506,7 @@
else
LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
- Land[t, i]:= Land[t, i] or lfDamaged;
+ Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
//Despeckle(i, t);
LandDirty[t div 32, i div 32]:= 1;
end;
@@ -394,7 +521,7 @@
else
LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
- Land[t, i]:= Land[t, i] or lfDamaged;
+ Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
//Despeckle(i, y - dy);
LandDirty[t div 32, i div 32]:= 1;
end;
@@ -525,7 +652,7 @@
else
LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor;
- Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+ Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
LandDirty[ty div 32, tx div 32]:= 1;
end;
inc(y, dY)
@@ -567,6 +694,7 @@
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] and not lfIce;
if despeckle then
begin
Land[ty, tx]:= Land[ty, tx] or lfDamaged;
@@ -595,7 +723,7 @@
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;
+ Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
if despeckle then
LandDirty[ty div 32, tx div 32]:= 1;
if (cReducedQuality and rqBlurryLand) = 0 then
@@ -638,7 +766,7 @@
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;
+ Land[ty, tx]:=( Land[ty, tx] or lfDamaged) and not lfIce;
if despeckle then
LandDirty[ty div 32, tx div 32]:= 1;
if (cReducedQuality and rqBlurryLand) = 0 then
@@ -664,7 +792,7 @@
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;
+ Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
if despeckle then
LandDirty[ty div 32, tx div 32]:= 1;
if (cReducedQuality and rqBlurryLand) = 0 then
--- a/hedgewars/uRender.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uRender.pas Tue Feb 26 20:39:18 2013 -0500
@@ -26,15 +26,16 @@
procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt);
procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
-procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
+procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
procedure DrawTexture (X, Y: LongInt; Texture: PTexture); inline;
procedure DrawTexture (X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
-procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
-procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
procedure DrawTextureCentered (X, Top: LongInt; Source: PTexture);
procedure DrawTextureF (Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
@@ -63,19 +64,23 @@
var LastTint: LongWord = 0;
-procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
+procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
begin
r.y:= r.y + Height * Position;
r.h:= Height;
DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture)
end;
-procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
begin
-DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
+DrawTextureFromRectDir(X, Y, r^.w, r^.h, r, SourceTexture, 1)
+end;
+procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+begin
+DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1)
end;
-procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
var rr: TSDL_Rect;
_l, _r, _t, _b: real;
VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
@@ -101,14 +106,28 @@
glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
-VertexBuffer[0].X:= X;
-VertexBuffer[0].Y:= Y;
-VertexBuffer[1].X:= rr.w + X;
-VertexBuffer[1].Y:= Y;
-VertexBuffer[2].X:= rr.w + X;
-VertexBuffer[2].Y:= rr.h + Y;
-VertexBuffer[3].X:= X;
-VertexBuffer[3].Y:= rr.h + Y;
+if Dir < 0 then
+ begin
+ VertexBuffer[0].X:= X + rr.w/2;
+ VertexBuffer[0].Y:= Y;
+ VertexBuffer[1].X:= X - rr.w/2;
+ VertexBuffer[1].Y:= Y;
+ VertexBuffer[2].X:= X - rr.w/2;
+ VertexBuffer[2].Y:= rr.h + Y;
+ VertexBuffer[3].X:= X + rr.w/2;
+ VertexBuffer[3].Y:= rr.h + Y;
+ end
+else
+ begin
+ VertexBuffer[0].X:= X;
+ VertexBuffer[0].Y:= Y;
+ VertexBuffer[1].X:= rr.w + X;
+ VertexBuffer[1].Y:= Y;
+ VertexBuffer[2].X:= rr.w + X;
+ VertexBuffer[2].Y:= rr.h + Y;
+ VertexBuffer[3].X:= X;
+ VertexBuffer[3].Y:= rr.h + Y;
+ end;
TextureBuffer[0].X:= _l;
TextureBuffer[0].Y:= _t;
--- a/hedgewars/uTeams.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uTeams.pas Tue Feb 26 20:39:18 2013 -0500
@@ -188,11 +188,11 @@
PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
repeat
CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
- until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
+ until ((Hedgehogs[CurrHedgehog].Gear <> nil) and (Hedgehogs[CurrHedgehog].Effects[heFrozen] = 0)) or (CurrHedgehog = PrevHH)
end
until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0));
end
-until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
+until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] = 0);
SwitchCurrentHedgehog(@(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]));
{$IFDEF USE_TOUCH_INTERFACE}
--- a/hedgewars/uTypes.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uTypes.pas Tue Feb 26 20:39:18 2013 -0500
@@ -86,7 +86,7 @@
sprHandResurrector, sprCross, sprAirDrill, sprNapalmBomb,
sprBulletHit, sprSnowball, sprHandSnowball, sprSnow,
sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis,
- sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar
+ sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, sprFrozenHog
);
// Gears that interact with other Gears and/or Land
@@ -259,6 +259,8 @@
SoundChannel: LongInt;
PortalCounter: LongWord; // Hopefully temporary, but avoids infinite portal loops in a guaranteed fashion.
AIHints: LongWord; // hints for ai. haha ^^^^^^ temporary, sure
+ IceTime: Longint; //time of ice beam with object some interaction temporary
+ IceState: Longint; //state of ice gun temporary
LastDamage: PHedgehog;
end;
TPGearArray = array of PGear;
--- a/hedgewars/uVariables.pas Mon Feb 25 11:37:48 2013 +0400
+++ b/hedgewars/uVariables.pas Tue Feb 26 20:39:18 2013 -0500
@@ -115,6 +115,7 @@
// originally typed consts
ExplosionBorderColor: LongWord;
+ IceColor : LongWord;
WaterOpacity: byte;
SDWaterOpacity: byte;
GrayScale: Boolean;
@@ -654,16 +655,18 @@
Width: 3; Height: 17; imageWidth: 3; imageHeight: 17; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprSlider
(FileName: 'botlevels'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
Width: 22; Height: 15; imageWidth: 22; imageHeight: 15; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprBotlevels
- (* (FileName: 'amKnife'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
- Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandKnife*)
(FileName: 'amCleaver'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: false),// sprHandKnife
- (*(FileName: 'knife'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
- Width: 29; Height: 14; imageWidth: 64; imageHeight: 64; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprKnife*)
(FileName: 'cleaver'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
Width: 64; Height: 64; imageWidth: 64; imageHeight: 128; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprKnife
(FileName: 'star'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
- Width: 12; Height: 12; imageWidth: 12; imageHeight: 12; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprStar
+ Width: 12; Height: 12; imageWidth: 12; imageHeight: 12; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprStar
+ (FileName: 'icetexture'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+ Width: 128; Height: 128; imageWidth: 128; imageHeight: 128; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: true), // sprIceTexture
+ (FileName: 'amIceGun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+ Width: 32; Height: 32; imageWidth: 32; imageHeight: 32; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprIceGun
+ (FileName: 'amFrozenHog'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+ Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprFrozenHog
);
const
@@ -2407,6 +2410,7 @@
SDWaterOpacity:= $80;
SDTint:= $80;
ExplosionBorderColor:= $FF808080;
+ IceColor:= ($44 shl RShift) or ($97 shl GShift) or ($A9 shl BShift) or ($A0 shl AShift);
WaterOpacity:= $80;
cDrownSpeed.QWordValue := 257698038; // 0.06
Binary file share/hedgewars/Data/Graphics/Hedgehog.png has changed
Binary file share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png has changed
Binary file share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png has changed
Binary file share/hedgewars/Data/Graphics/icetexture.png has changed