# HG changeset patch # User nemo # Date 1361929158 18000 # Node ID c64b758e0412f667ee9304fbf768ba1340a6abf8 # Parent 7445ce865e0408b62bdc67eee7752ecb3da274a3# Parent 3bb505fc707ef4f57af7e88c890744d8ff6f65f7 pull icegun into default. it has a few issues, but, pretty close. that way more people will play with it. diff -r 7445ce865e04 -r c64b758e0412 hedgewars/GSHandlers.inc --- 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; diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uGears.pas --- 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, diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uGearsHedgehog.pas --- 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. diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uGearsRender.pas --- 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 diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uGearsUtils.pas --- 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 diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uLandGraphics.pas --- 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 diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uRender.pas --- 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; diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uTeams.pas --- 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} diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uTypes.pas --- 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; diff -r 7445ce865e04 -r c64b758e0412 hedgewars/uVariables.pas --- 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 diff -r 7445ce865e04 -r c64b758e0412 share/hedgewars/Data/Graphics/Hedgehog.png Binary file share/hedgewars/Data/Graphics/Hedgehog.png has changed diff -r 7445ce865e04 -r c64b758e0412 share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png Binary file share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png has changed diff -r 7445ce865e04 -r c64b758e0412 share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png Binary file share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png has changed diff -r 7445ce865e04 -r c64b758e0412 share/hedgewars/Data/Graphics/icetexture.png Binary file share/hedgewars/Data/Graphics/icetexture.png has changed