hedgewars/uGearsHandlersMess.pas
branchqmlfrontend
changeset 11071 3851ce4f2061
parent 11070 f9a03078dd4f
child 11152 3ac7f6d43200
equal deleted inserted replaced
11050:9b7c8c5a94e0 11071:3851ce4f2061
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2014 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
  1502         begin
  1502         begin
  1503         Gear^.dY := _0;
  1503         Gear^.dY := _0;
  1504         SetLittle(HHGear^.dX);
  1504         SetLittle(HHGear^.dX);
  1505         HHGear^.dY := _0;
  1505         HHGear^.dY := _0;
  1506         end
  1506         end
       
  1507     else if Gear^.dY.isNegative and (TestCollisionYwithGear(HHGear, -1) <> 0) then
       
  1508         begin
       
  1509         Gear^.dY := cGravity;
       
  1510         HHGear^.dY := cGravity;
       
  1511         end
  1507     else
  1512     else
  1508         begin
  1513         begin
  1509         if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), lfLandMask) then
  1514         if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), lfLandMask) then
  1510             begin
  1515             begin
  1511             Gear^.dY := Gear^.dY + cGravity;
  1516             Gear^.dY := Gear^.dY + cGravity;
  1912                     tY:=Gear^.Y-targ^.Y;
  1917                     tY:=Gear^.Y-targ^.Y;
  1913                     if (tX.Round+tY.Round < Gear^.Karma) and
  1918                     if (tX.Round+tY.Round < Gear^.Karma) and
  1914                        (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Karma)) then
  1919                        (hwRound(hwSqr(tX) + hwSqr(tY)) < sqr(Gear^.Karma)) then
  1915                         begin
  1920                         begin
  1916                         Gear^.Hedgehog:= CurrentHedgehog;
  1921                         Gear^.Hedgehog:= CurrentHedgehog;
       
  1922                         tmpG:= FollowGear;
  1917                         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Karma, Gear^.Hedgehog, EXPLAutoSound);
  1923                         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Karma, Gear^.Hedgehog, EXPLAutoSound);
       
  1924                         FollowGear:= tmpG;
  1918                         DeleteGear(Gear);
  1925                         DeleteGear(Gear);
  1919                         exit
  1926                         exit
  1920                         end
  1927                         end
  1921                     end
  1928                     end
  1922                 else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then
  1929                 else if (Gear^.Angle > 0) and (CheckGearNear(Gear, gtHedgehog, Gear^.Karma, Gear^.Karma) <> nil) then
  1927                     exit
  1934                     exit
  1928                     end;
  1935                     end;
  1929                 Gear^.State:= Gear^.State and (not gstAttacking);
  1936                 Gear^.State:= Gear^.State and (not gstAttacking);
  1930                 Gear^.Timer:= Gear^.WDTimer
  1937                 Gear^.Timer:= Gear^.WDTimer
  1931                 end;
  1938                 end;
  1932             dec(Gear^.Timer);
  1939             if Gear^.Timer > 0 then
       
  1940                 dec(Gear^.Timer);
  1933             end
  1941             end
  1934         end
  1942         end
  1935     else // gsttmpFlag = 0
  1943     else // gsttmpFlag = 0
  1936         if (TurnTimeLeft = 0)
  1944         if (TurnTimeLeft = 0)
  1937         or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
  1945         or ((GameFlags and gfInfAttack <> 0) and (GameTicks > Gear^.FlightTime))
  1951     if land = 0 then land:= TestCollisionYwithGear(Gear,-2);
  1959     if land = 0 then land:= TestCollisionYwithGear(Gear,-2);
  1952     if land = 0 then land:= TestCollisionXwithGear(Gear,-2);
  1960     if land = 0 then land:= TestCollisionXwithGear(Gear,-2);
  1953     if land = 0 then land:= TestCollisionYwithGear(Gear, 2);
  1961     if land = 0 then land:= TestCollisionYwithGear(Gear, 2);
  1954     if (land <> 0) and (land and lfBouncy = 0) then
  1962     if (land <> 0) and (land and lfBouncy = 0) then
  1955         begin
  1963         begin
  1956         if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1964         if ((Gear^.State and gstMoving) <> 0) or (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
  1957             begin
  1965             begin
  1958             PlaySound(sndRopeAttach);
  1966             PlaySound(sndRopeAttach);
  1959             Gear^.dX:= _0;
  1967             Gear^.dX:= _0;
  1960             Gear^.dY:= _0;
  1968             Gear^.dY:= _0;
  1961             Gear^.State:= Gear^.State and (not gstMoving);
  1969             Gear^.State:= Gear^.State and (not gstMoving);
  2759 
  2767 
  2760     LandFlags:= 0;
  2768     LandFlags:= 0;
  2761     if Gear^.AmmoType = amRubber then LandFlags:= lfBouncy
  2769     if Gear^.AmmoType = amRubber then LandFlags:= lfBouncy
  2762     else if cIce then LandFlags:= lfIce;
  2770     else if cIce then LandFlags:= lfIce;
  2763 
  2771 
  2764     distFail:= ((Distance(tx - x, ty - y) > _256) and ((WorldEdge <> weWrap) or
  2772     distFail:= (cBuildMaxDist > 0) and ((hwRound(Distance(tx - x, ty - y)) > cBuildMaxDist) and ((WorldEdge <> weWrap) or
  2765             (
  2773             (
  2766             (Distance(tx - int2hwFloat(rightX+(rx-leftX)), ty - y) > _256) and
  2774             (hwRound(Distance(tx - int2hwFloat(rightX+(rx-leftX)), ty - y)) > cBuildMaxDist) and
  2767             (Distance(tx - int2hwFloat(leftX-(rightX-rx)), ty - y) > _256)
  2775             (hwRound(Distance(tx - int2hwFloat(leftX-(rightX-rx)), ty - y)) > cBuildMaxDist)
  2768             )));
  2776             )));
  2769     if distFail
  2777     if distFail
  2770     or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Width div 2, Gear^.Target.Y - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Height div 2, Ammoz[Gear^.AmmoType].PosSprite, Gear^.State, true, LandFlags)) then
  2778     or (not TryPlaceOnLand(Gear^.Target.X - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Width div 2, Gear^.Target.Y - SpritesData[Ammoz[Gear^.AmmoType].PosSprite].Height div 2, Ammoz[Gear^.AmmoType].PosSprite, Gear^.State, true, LandFlags)) then
  2771         begin
  2779         begin
  2772         PlaySound(sndDenied);
  2780         PlaySound(sndDenied);
  2797 procedure doStepTeleportAfter(Gear: PGear);
  2805 procedure doStepTeleportAfter(Gear: PGear);
  2798 var
  2806 var
  2799     HHGear: PGear;
  2807     HHGear: PGear;
  2800 begin
  2808 begin
  2801     HHGear := Gear^.Hedgehog^.Gear;
  2809     HHGear := Gear^.Hedgehog^.Gear;
  2802     doStepHedgehogMoving(HHGear);
  2810     if HHGear <> nil then doStepHedgehogMoving(HHGear);
  2803     // if not infattack mode wait for hedgehog finish falling to collect cases
  2811     // if not infattack mode wait for hedgehog finish falling to collect cases
  2804     if ((GameFlags and gfInfAttack) <> 0)
  2812     if ((GameFlags and gfInfAttack) <> 0)
       
  2813     or (HHGear = nil)
  2805     or ((HHGear^.State and gstMoving) = 0)
  2814     or ((HHGear^.State and gstMoving) = 0)
  2806     or (Gear^.Hedgehog^.Gear^.Damage > 0)
  2815     or (HHGear^.Damage > 0)
  2807     or ((HHGear^.State and gstDrowning) = 1) then
  2816     or ((HHGear^.State and gstDrowning) = 1) then
  2808         begin
  2817         begin
  2809         DeleteGear(Gear);
  2818         DeleteGear(Gear);
  2810         AfterAttack
  2819         AfterAttack
  2811         end
  2820         end
  2812 end;
  2821 end;
  2813 
  2822 
  2814 procedure doStepTeleportAnim(Gear: PGear);
  2823 procedure doStepTeleportAnim(Gear: PGear);
  2815 begin
  2824 begin
  2816     if (Gear^.Hedgehog^.Gear^.Damage > 0) then
  2825     if (Gear^.Hedgehog^.Gear = nil) or (Gear^.Hedgehog^.Gear^.Damage > 0) then
  2817         begin
  2826         begin
  2818         DeleteGear(Gear);
  2827         DeleteGear(Gear);
  2819         AfterAttack;
  2828         AfterAttack;
  2820         end;
  2829         end;
  2821     inc(Gear^.Timer);
  2830     inc(Gear^.Timer);
  2838     ytol = cHHRadius;
  2847     ytol = cHHRadius;
  2839 begin
  2848 begin
  2840     AllInactive := false;
  2849     AllInactive := false;
  2841 
  2850 
  2842     HHGear := Gear^.Hedgehog^.Gear;
  2851     HHGear := Gear^.Hedgehog^.Gear;
       
  2852     if HHGear = nil then
       
  2853     begin
       
  2854         DeleteGear(Gear);
       
  2855         exit
       
  2856     end; 
  2843 
  2857 
  2844     valid:= false;
  2858     valid:= false;
  2845 
  2859 
  2846     lx:= Gear^.Target.X - SpritesData[sprHHTelepMask].Width  div 2; // left
  2860     lx:= Gear^.Target.X - SpritesData[sprHHTelepMask].Width  div 2; // left
  2847     ty:= Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2; // top
  2861     ty:= Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2; // top
  5196 
  5210 
  5197 ////////////////////////////////////////////////////////////////////////////////
  5211 ////////////////////////////////////////////////////////////////////////////////
  5198 procedure doStepHammer(Gear: PGear);
  5212 procedure doStepHammer(Gear: PGear);
  5199 var HHGear, tmp, tmp2: PGear;
  5213 var HHGear, tmp, tmp2: PGear;
  5200          t: PGearArray;
  5214          t: PGearArray;
  5201          i: LongInt;
  5215  i, dmg, d: LongInt;
  5202 begin
  5216 begin
  5203 HHGear:= Gear^.Hedgehog^.Gear;
  5217 HHGear:= Gear^.Hedgehog^.Gear;
  5204 HHGear^.State:= HHGear^.State or gstNoDamage;
  5218 HHGear^.State:= HHGear^.State or gstNoDamage;
  5205 DeleteCI(HHGear);
  5219 DeleteCI(HHGear);
       
  5220 SetLittle(HHGear^.dY);
       
  5221 HHGear^.dY.IsNegative:= true;
       
  5222 HHGear^.State:= HHGear^.State or gstMoving;
  5206 
  5223 
  5207 t:= CheckGearsCollision(Gear);
  5224 t:= CheckGearsCollision(Gear);
  5208 
  5225 
  5209 for i:= 5 downto 0 do
  5226 for i:= 5 downto 0 do
  5210     AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  5227     AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  5215     dec(i);
  5232     dec(i);
  5216     tmp:= t^.ar[i];
  5233     tmp:= t^.ar[i];
  5217     if (tmp^.State and gstNoDamage) = 0 then
  5234     if (tmp^.State and gstNoDamage) = 0 then
  5218         if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then
  5235         if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then
  5219             begin
  5236             begin
       
  5237             dmg:= 0;
  5220             //tmp^.State:= tmp^.State or gstFlatened;
  5238             //tmp^.State:= tmp^.State or gstFlatened;
  5221             if (tmp^.Kind <> gtHedgehog) or (tmp^.Hedgehog^.Effects[heInvulnerable] = 0) then
  5239             if (tmp^.Kind <> gtHedgehog) or (tmp^.Hedgehog^.Effects[heInvulnerable] = 0) then
  5222                 ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown);
  5240                 begin
  5223             //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
  5241                 // base damage on remaining health
  5224             tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
  5242                 dmg:= (tmp^.Health - tmp^.Damage);
  5225             tmp2^.LinkedGear:= tmp;
  5243                 if dmg > 0 then
  5226             SetAllToActive
  5244                     begin
  5227             end
  5245                     // do 1/2 current hp worth of damage if extra damage is enabled (1/3 damage if not)
  5228         else
  5246                     if cDamageModifier > _1 then
  5229             begin
  5247                         d:= 2
  5230             end
  5248                     else
       
  5249                         d:= 3;
       
  5250                     // always round up
       
  5251                     if dmg mod d > 0 then
       
  5252                         dmg:= dmg div d + 1
       
  5253                     else
       
  5254                         dmg:= dmg div d;
       
  5255 
       
  5256                     ApplyDamage(tmp, CurrentHedgehog, dmg, dsUnknown);
       
  5257                     end;
       
  5258                 end;
       
  5259 
       
  5260             if (tmp^.Kind <> gtHedgehog) or (dmg > 0) or (tmp^.Health > tmp^.Damage) then
       
  5261                 begin
       
  5262                 //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
       
  5263                 tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
       
  5264                 tmp2^.LinkedGear:= tmp;
       
  5265                 SetAllToActive
       
  5266                 end;
       
  5267             end;
  5231     end;
  5268     end;
  5232 
  5269 
  5233 HHGear^.State:= HHGear^.State and (not gstNoDamage);
  5270 HHGear^.State:= HHGear^.State and (not gstNoDamage);
  5234 Gear^.Timer:= 250;
  5271 Gear^.Timer:= 250;
  5235 Gear^.doStep:= @doStepIdle
  5272 Gear^.doStep:= @doStepIdle