diff -r bde641cf53c8 -r e350500c4edb hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Thu Apr 04 14:37:19 2013 +0200 +++ b/hedgewars/GSHandlers.inc Tue Jun 04 22:28:12 2013 +0200 @@ -1,6 +1,6 @@ (* * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2012 Andrey Korotaev + * Copyright (c) 2004-2013 Andrey Korotaev * * 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 @@ -197,6 +197,7 @@ tdY := Gear^.dY; + // might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips) if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048)) or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then @@ -429,14 +430,13 @@ CalcRotationDirAngle(Gear); // let's add some smoke depending on speed - s:= max(32,152 - hwRound(Distance(Gear^.dX,Gear^.dY)*120))+random(10); + s:= max(32,152 - round((abs(hwFloat2FLoat(Gear^.dX))+abs(hwFloat2Float(Gear^.dY)))*120))+random(10); if (GameTicks mod s) = 0 then begin // adjust angle to match the texture if Gear^.dX.isNegative then - i:= 130 - else - i:= 50; + i:= 130 + else i:= 50; smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke); if smoke <> nil then @@ -504,7 +504,11 @@ or (Gear^.Kind = gtBall) then CalcRotationDirAngle(Gear) else if (GameTicks and $1F) = 0 then - AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) + begin + if hwRound(Gear^.Y) > cWaterLine then + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) + else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) + end end; //////////////////////////////////////////////////////////////////////////////// @@ -521,24 +525,31 @@ exit end; if (GameTicks and $3F) = 0 then - AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); + begin + if hwRound(Gear^.Y) > cWaterLine then + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) + else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) + end end; //////////////////////////////////////////////////////////////////////////////// procedure doStepSnowball(Gear: PGear); var kick, i: LongInt; particle: PVisualGear; + gdX, gdY: hwFloat; begin AllInactive := false; if (GameFlags and gfMoreWind) = 0 then Gear^.dX := Gear^.dX + cWindSpeed; + gdX := Gear^.dX; + gdY := Gear^.dY; doStepFallingGear(Gear); CalcRotationDirAngle(Gear); if (Gear^.State and gstCollision) <> 0 then begin - kick:= hwRound((hwAbs(Gear^.dX)+hwAbs(Gear^.dY)) * _20); - Gear^.dY.isNegative:= (not Gear^.dY.isNegative); - Gear^.dX.isNegative:= (not Gear^.dX.isNegative); + kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20); + Gear^.dX:= gdX; + Gear^.dY:= gdY; AmmoShove(Gear, 0, kick); for i:= 15 + kick div 10 downto 0 do begin @@ -1418,7 +1429,9 @@ //////////////////////////////////////////////////////////////////////////////// procedure doStepMine(Gear: PGear); var vg: PVisualGear; + dxdy: hwFloat; begin + if Gear^.Health = 0 then dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY); if (Gear^.State and gstMoving) <> 0 then begin DeleteCI(Gear); @@ -1436,14 +1449,8 @@ doStepFallingGear(Gear); if (Gear^.Health = 0) then begin - if (not Gear^.dY.isNegative) and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then - inc(Gear^.Damage, hwRound(Gear^.dY * _70)) - else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then - inc(Gear^.Damage, hwRound(Gear^.dX * _70)) - else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then - inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) - else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then - inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); + if (dxdy > _0_4) and (Gear^.State and gstCollision <> 0) then + inc(Gear^.Damage, hwRound(dxdy * _50)); if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then begin @@ -1577,46 +1584,38 @@ /////////////////////////////////////////////////////////////////////////////// -(* -TODO -Increase damage as barrel smokes? -Try tweaking friction some more -*) procedure doStepRollingBarrel(Gear: PGear); var i: LongInt; particle: PVisualGear; + dxdy: hwFloat; begin if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then SetLittle(Gear^.dY); Gear^.State := Gear^.State or gstAnimation; + if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen; if ((Gear^.dX.QWordValue <> 0) or (Gear^.dY.QWordValue <> 0)) then begin DeleteCI(Gear); AllInactive := false; - if (not Gear^.dY.isNegative) and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then + dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY); + doStepFallingGear(Gear); + if (Gear^.State and gstCollision <> 0) and(dxdy > _0_4) then begin - Gear^.State := Gear^.State or gsttmpFlag; - inc(Gear^.Damage, hwRound(Gear^.dY * _70)); - for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do + if (TestCollisionYwithGear(Gear, 1) <> 0) then begin - particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust); - if particle <> nil then - particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) - end - end - else if (not Gear^.dX.isNegative) and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then - inc(Gear^.Damage, hwRound(Gear^.dX * _70)) - - else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then - inc(Gear^.Damage, hwRound(Gear^.dY * -_70)) - - else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then - inc(Gear^.Damage, hwRound(Gear^.dX * -_70)); - - doStepFallingGear(Gear); + Gear^.State := Gear^.State or gsttmpFlag; + for i:= min(12, hwRound(dxdy*_10)) downto 0 do + begin + particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust); + if particle <> nil then + particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480) + end + end; + inc(Gear^.Damage, hwRound(dxdy * _50)) + end; CalcRotationDirAngle(Gear); //CheckGearDrowning(Gear) end @@ -1655,23 +1654,19 @@ dec(Gear^.Health, Gear^.Damage); Gear^.Damage := 0; if Gear^.Health <= 0 then - Gear^.doStep := @doStepCase; - // Hand off to doStepCase for the explosion - + doStepCase(Gear); end; procedure doStepCase(Gear: PGear); var i, x, y: LongInt; k: TGearType; - exBoom: boolean; dX, dY: HWFloat; hog: PHedgehog; sparkles: PVisualGear; gi: PGear; begin k := Gear^.Kind; - exBoom := false; if (Gear^.Message and gmDestroy) > 0 then begin @@ -1684,22 +1679,54 @@ Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump)); exit end; + if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen; + + if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then + begin + x := hwRound(Gear^.X); + y := hwRound(Gear^.Y); + hog:= Gear^.Hedgehog; + + DeleteGear(Gear); + // <-- delete gear! + + if k = gtCase then + begin + doMakeExplosion(x, y, 25, hog, EXPLAutoSound); + for i:= 0 to 63 do + AddGear(x, y, gtFlame, 0, _0, _0, 0); + end + else if k = gtExplosives then + begin + doMakeExplosion(x, y, 75, hog, EXPLAutoSound); + for i:= 0 to 31 do + begin + dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1); + dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1); + AddGear(x, y, gtFlame, 0, dX, dY, 0); + AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); + end + end; + exit + end; if k = gtExplosives then begin //if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation; if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then + begin Gear^.doStep := @doStepRollingBarrel; - - if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then + exit; + end + else Gear^.dX:= _0; + + if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then if (cBarrelHealth div Gear^.Health) > 2 then AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke) - else - AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); + else + AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite); dec(Gear^.Health, Gear^.Damage); Gear^.Damage := 0; - if Gear^.Health <= 0 then - exBoom := true; end else begin @@ -1751,34 +1778,6 @@ end end; - if (Gear^.Damage > 0) or exBoom then - begin - x := hwRound(Gear^.X); - y := hwRound(Gear^.Y); - hog:= Gear^.Hedgehog; - - DeleteGear(Gear); - // <-- delete gear! - - if k = gtCase then - begin - doMakeExplosion(x, y, 25, hog, EXPLAutoSound); - for i:= 0 to 63 do - AddGear(x, y, gtFlame, 0, _0, _0, 0); - end - else if k = gtExplosives then - begin - doMakeExplosion(x, y, 75, hog, EXPLAutoSound); - for i:= 0 to 31 do - begin - dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1); - dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1); - AddGear(x, y, gtFlame, 0, dX, dY, 0); - AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0); - end - end; - exit - end; if (Gear^.dY.QWordValue <> 0) or (TestCollisionYwithGear(Gear, 1) = 0) then @@ -2432,25 +2431,24 @@ var dX, dY, gdX, gdY: hwFloat; i: LongInt; - dxn, dyn: boolean; begin AllInactive := false; - dxn := Gear^.dX.isNegative; - dyn := Gear^.dY.isNegative; + gdX := Gear^.dX; + gdY := Gear^.dY; doStepFallingGear(Gear); if (Gear^.State and gstCollision) <> 0 then begin - gdX := Gear^.dX; - gdY := Gear^.dY; doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound); - - gdX.isNegative := not dxn; - gdY.isNegative := not dyn; + gdX.isNegative := not gdX.isNegative; + gdY.isNegative := not gdY.isNegative; + gdX:= gdX*_0_2; + gdY:= gdY*_0_2; + for i:= 0 to 4 do begin - dX := gdX + (GetRandomf - _0_5) * _0_03; - dY := gdY + (GetRandomf - _0_5) * _0_03; + dX := gdX + rndSign(GetRandomf) * _0_03; + dY := gdY + rndSign(GetRandomf) * _0_03; AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25); end; @@ -2459,7 +2457,11 @@ end; if (GameTicks and $3F) = 0 then - AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) + begin + if hwRound(Gear^.Y) > cWaterLine then + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) + else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) + end end; //////////////////////////////////////////////////////////////////////////////// @@ -2767,7 +2769,6 @@ procedure doStepSeductionWork(Gear: PGear); var i: LongInt; hogs: PGearArrayS; - len: Integer; begin AllInactive := false; hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius); @@ -2960,7 +2961,11 @@ doStepFallingGear(Gear); if (GameTicks and $3F) = 0 then - AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace); + begin + if hwRound(Gear^.Y) > cWaterLine then + AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble) + else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace) + end; if ((Gear^.State and gstCollision) <> 0) then begin @@ -3210,10 +3215,11 @@ move:= _0_02; fuel:= 5; end;*) - - if Gear^.Health > 0 then - begin - if (HHGear^.Message and gmUp) <> 0 then + if HHGear^.Message and gmPrecise <> 0 then + HedgehogChAngle(HHGear) + else if Gear^.Health > 0 then + begin + if HHGear^.Message and gmUp <> 0 then begin if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then begin @@ -3280,10 +3286,12 @@ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall) end; - if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then + if (HHGear^.Message and (gmAttack or gmUp or gmLeft or gmRight) <> 0) and + (HHGear^.Message and gmPrecise = 0) then Gear^.State := Gear^.State and (not gsttmpFlag); - HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight)); + if HHGear^.Message and gmPrecise = 0 then + HHGear^.Message := HHGear^.Message and (not (gmUp or gmLeft or gmRight)); HHGear^.State := HHGear^.State or gstMoving; Gear^.X := HHGear^.X; @@ -3300,7 +3308,7 @@ if // (Gear^.Health = 0) (HHGear^.Damage <> 0) //or CheckGearDrowning(HHGear) - or (cWaterLine + 512 < hwRound(HHGear^.Y)) + or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y)) or (TurnTimeLeft = 0) // allow brief ground touches - to be fair on this, might need another counter or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0)) @@ -3701,7 +3709,11 @@ // wow! good candidate there, let's see if the distance and direction is okay! if hasdxy then begin - s := r / Distance(iterator^.dX, iterator^.dY); + s := Distance(iterator^.dX, iterator^.dY); + // if the resulting distance is 0 skip this gear + if s.QWordValue = 0 then + continue; + s := r / s; ox:= iterator^.X + s * iterator^.dX; oy:= iterator^.Y + s * iterator^.dY; end @@ -4650,7 +4662,6 @@ resgear: PGear; hh: PHedgehog; i: LongInt; - len: Integer; begin if (TurnTimeLeft > 0) then dec(TurnTimeLeft); @@ -4743,7 +4754,6 @@ graves: PGearArrayS; hh: PHedgehog; i: LongInt; - len: Integer; begin AllInactive := false; graves := GearsNear(Gear^.X, Gear^.Y, gtGrave, Gear^.Radius); @@ -5093,7 +5103,18 @@ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) + '%', cWhiteColor, fntSmall) end; - if GameTicks mod 10 = 0 then dec(Gear^.Health); + if Gear^.Message and (gmUp or gmDown) <> 0 then + begin + StopSoundChan(Gear^.SoundChannel); + Gear^.SoundChannel:= -1; + if GameTicks mod 40 = 0 then dec(Gear^.Health) + end + else + begin + if Gear^.SoundChannel = -1 then + Gear^.SoundChannel := LoopSound(sndIceBeam); + if GameTicks mod 10 = 0 then dec(Gear^.Health) + end end; @@ -5110,17 +5131,6 @@ 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; @@ -5135,21 +5145,22 @@ const iceRadius = 32; const iceHeight = 40; var - HHGear: PGear; + HHGear, iter: PGear; landRect: TSDL_Rect; ndX, ndY: hwFloat; - i, t, gX, gY: LongInt; + i, j, t, gX, gY: LongInt; hogs: PGearArrayS; - len: Integer; + vg: PVisualGear; begin HHGear := Gear^.Hedgehog^.Gear; - if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then - begin + if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) or (HHGear^.dX.QWordValue > 4294967) then + begin + StopSoundChan(Gear^.SoundChannel); DeleteGear(Gear); AfterAttack; exit - end - else if Gear^.Message and (gmUp or gmDown) = 0 then updateFuel(Gear); + end; + updateFuel(Gear); with Gear^ do begin @@ -5173,7 +5184,7 @@ if Target.X <> NoPointX then begin - CheckCollisionWithLand(Gear); + CheckCollision(Gear); if (State and gstCollision) <> 0 then begin if Timer = iceWaitCollision then @@ -5205,6 +5216,49 @@ 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); + + // Freeze nearby mines/explosives/cases too + iter := GearsList; + while iter <> nil do + begin + if (iter^.State and gstFrozen = 0) and + ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and + (abs(iter^.X.Round-target.x)+abs(iter^.Y.Round-target.y)+2<2*iceRadius) and (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y)) nil then + begin + i:= random(100) + 155; + vg^.Tint:= i shl 24 or i shl 16 or $FF shl 8 or Longword(random(200) + 55); + vg^.Angle:= random(360); + vg^.dx:= 0.001 * random(80); + vg^.dy:= 0.001 * random(80) + end + end; + PlaySound(sndHogFreeze); + iter^.State:= iter^.State or gstFrozen; + if iter^.Kind = gtMine then // dud mine block + begin + vg:= AddVisualGear(hwRound(iter^.X) - 4 + Random(8), hwRound(iter^.Y) - 4 - Random(4), vgtSmoke); + if vg <> nil then + vg^.Scale:= 0.5; + PlaySound(sndVaporize); + iter^.Health := 0; + iter^.Damage := 0; + iter^.State := iter^.State and (not gstAttacking) + end + else if iter^.Kind = gtCase then + begin + DeleteCI(iter); + AddGearCI(iter) + end + else // gtExplosives + iter^.Health:= iter^.Health + cBarrelHealth + end; + iter:= iter^.NextGear + end; // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius); SetAllHHToActive(true); @@ -5213,10 +5267,26 @@ if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then begin + PlaySound(sndHogFreeze); DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight); SetAllHHToActive(true); Timer := iceWaitCollision; end; +(* + Any ideas for something that would look good here? + if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then + begin + vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1); + if vg <> nil then + begin + i:= random(100) + 155; + vg^.Tint:= IceColor or $FF; + vg^.Angle:= random(360); + vg^.dx:= 0.001 * random(80); + vg^.dy:= 0.001 * random(80) + end + end; +*) // freeze nearby hogs hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2); @@ -5229,7 +5299,10 @@ 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]:= 200000;//cHedgehogTurnTime + cReadyDelay + begin + hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 200000-1;//cHedgehogTurnTime + cReadyDelay + PlaySound(sndHogFreeze); + end; end; inc(Pos) end @@ -5242,14 +5315,16 @@ X:= HHGear^.X; Y:= HHGear^.Y end; - {if (gX > max(LAND_WIDTH,4096)*2) or + 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 - X:= HHGear^.X; - Y:= HHGear^.Y - end} + begin + //X:= HHGear^.X; + //Y:= HHGear^.Y + Target.X:= gX; + Target.Y:= gY; + end end end; end;