- Further work on new collisions implementation
authorunc0rr
Wed, 09 May 2007 20:32:41 +0000
changeset 511 2b5b9e00419d
parent 510 4e994e1b7abb
child 512 efc640bb60d0
- Further work on new collisions implementation
hedgewars/GSHandlers.inc
hedgewars/HHHandlers.inc
hedgewars/uCollisions.pas
hedgewars/uConsts.pas
hedgewars/uGears.pas
hedgewars/uLandGraphics.pas
--- a/hedgewars/GSHandlers.inc	Mon May 07 21:12:06 2007 +0000
+++ b/hedgewars/GSHandlers.inc	Wed May 09 20:32:41 2007 +0000
@@ -476,13 +476,13 @@
    HHGear^.State:= HHGear^.State or gstAttacking;
 
    inc(BTSteps);
-   if BTSteps = 11 then
+   if BTSteps = 7 then
       begin
       BTSteps:= 0;
-      Gear^.X:= HHGear^.X + Gear^.dX * cHHRadius * 2;
-      Gear^.Y:= HHGear^.Y + Gear^.dY * cHHRadius * 2;
+      Gear^.X:= HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
+      Gear^.Y:= HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
       HHGear^.State:= HHGear^.State or gstNoDamage;
-      AmmoShove(Gear, 3, 14);
+      AmmoShove(Gear, 2, 14);
       HHGear^.State:= HHGear^.State and not gstNoDamage
       end;
 
@@ -821,8 +821,8 @@
    CheckGearDrowning(Gear);
    end;
 
-if (Gear^.CollIndex = High(Longword)) and (Gear^.dY.QWordValue = 0) then AddGearCI(Gear)
-   else if (Gear^.CollIndex < High(Longword)) and (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear);
+if (Gear^.dY.QWordValue = 0) then AddGearCI(Gear)
+   else if (Gear^.dY.QWordValue <> 0) then DeleteCI(Gear)
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/hedgewars/HHHandlers.inc	Mon May 07 21:12:06 2007 +0000
+++ b/hedgewars/HHHandlers.inc	Wed May 09 20:32:41 2007 +0000
@@ -325,8 +325,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 procedure doStepHedgehogFree(Gear: PGear);
+var prevState: Longword;
 begin
-//DeleteCI(Gear);
+prevState:= Gear^.State;
 if not TestCollisionYwithGear(Gear, 1) then
    begin
    if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0;
@@ -373,6 +374,7 @@
 
 if (Gear^.State and gstMoving) <> 0 then
    begin
+   Gear^.State:= Gear^.State and not gstAnimation;
    Gear^.X:= Gear^.X + Gear^.dX;
    Gear^.Y:= Gear^.Y + Gear^.dY;
    if (Gear^.dY > _0) and not TestCollisionYwithGear(Gear, 1) and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
@@ -399,11 +401,20 @@
 
 if (not CheckGearDrowning(Gear)) and
    ((Gear^.State and gstMoving) = 0) then
+   if ((Gear^.State and gstAnimation) = 0) and
+      (prevState <> Gear^.State) then
       begin
-      Gear^.State:= 0;
-      Gear^.Active:= false;
-      AddGearCI(Gear);
-      exit
+      Gear^.State:= gstAnimation;
+      Gear^.Timer:= 150
+      end else
+      begin
+      if Gear^.Timer = 0 then
+         begin
+         Gear^.State:= 0;
+         Gear^.Active:= false;
+         AddGearCI(Gear);
+         exit
+         end else dec(Gear^.Timer)
       end
 end;
 
@@ -416,5 +427,5 @@
    exit
    end;
 if (Gear^.State and gstHHDriven) = 0 then doStepHedgehogFree(Gear)
-                                    else doStepHedgehogDriven(Gear)
+                                     else doStepHedgehogDriven(Gear)
 end;
--- a/hedgewars/uCollisions.pas	Mon May 07 21:12:06 2007 +0000
+++ b/hedgewars/uCollisions.pas	Wed May 09 20:32:41 2007 +0000
@@ -38,7 +38,7 @@
 function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean;
 
 implementation
-uses uMisc, uConsts, uLand, uLandGraphics;
+uses uMisc, uConsts, uLand, uLandGraphics, uConsole;
 
 type TCollisionEntry = record
                        X, Y, Radius: LongInt;
@@ -52,29 +52,29 @@
 
 procedure AddGearCI(Gear: PGear);
 begin
-if Gear^.CollIndex < High(Longword) then exit;
+if Gear^.CollisionIndex >= 0 then exit;
 TryDo(Count <= MAXRECTSINDEX, 'Collision rects array overflow', true);
 with cinfos[Count] do
      begin
      X:= hwRound(Gear^.X);
      Y:= hwRound(Gear^.Y);
      Radius:= Gear^.Radius;
-     ChangeRoundInLand(X, Y, Radius - 1, +1);
+     ChangeRoundInLand(X, Y, Radius - 1, true);
      cGear:= Gear
      end;
-Gear^.CollIndex:= Count;
+Gear^.CollisionIndex:= Count;
 inc(Count)
 end;
 
 procedure DeleteCI(Gear: PGear);
 begin
-if Gear^.CollIndex < Count then
+if Gear^.CollisionIndex >= 0 then
    begin
-   with cinfos[Gear^.CollIndex] do
-        ChangeRoundInLand(X, Y, Radius - 1, -1);
-   cinfos[Gear^.CollIndex]:= cinfos[Pred(Count)];
-   cinfos[Gear^.CollIndex].cGear^.CollIndex:= Gear^.CollIndex;
-   Gear^.CollIndex:= High(Longword);
+   with cinfos[Gear^.CollisionIndex] do
+        ChangeRoundInLand(X, Y, Radius - 1, false);
+   cinfos[Gear^.CollisionIndex]:= cinfos[Pred(Count)];
+   cinfos[Gear^.CollisionIndex].cGear^.CollisionIndex:= Gear^.CollisionIndex;
+   Gear^.CollisionIndex:= -1;
    dec(Count)
    end;
 end;
@@ -93,7 +93,7 @@
 for i:= 0 to Pred(Count) do
    with cinfos[i] do
       if (Gear <> cGear) and
-         (sqrt(sqr(mx - x) + sqr(my - y)) <= Radius + Gear^.Radius) then
+         (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius)) then
              begin
              ga.ar[ga.Count]:= cinfos[i].cGear;
              inc(ga.Count)
--- a/hedgewars/uConsts.pas	Mon May 07 21:12:06 2007 +0000
+++ b/hedgewars/uConsts.pas	Wed May 09 20:32:41 2007 +0000
@@ -126,6 +126,7 @@
       cCurrHHZ = Succ(cHHZ);
 
       cShotgunRadius = 22;
+      cBlowTorchC    = 6;
 
       cKeyMaxIndex = 1023;
 
@@ -148,6 +149,7 @@
       gstHHThinking     = $00000800;
       gstNoDamage       = $00001000;
       gstHHHJump        = $00002000;
+      gstAnimation      = $00004000;
 
       gm_Left   = $00000001;
       gm_Right  = $00000002;
--- a/hedgewars/uGears.pas	Mon May 07 21:12:06 2007 +0000
+++ b/hedgewars/uGears.pas	Wed May 09 20:32:41 2007 +0000
@@ -44,7 +44,7 @@
              Message : Longword;
              Hedgehog: pointer;
              Health, Damage: LongInt;
-             CollIndex: Longword;
+             CollisionIndex: LongInt;
              Tag: LongInt;
              Surf: PSDL_Surface;
              Z: Longword;
@@ -175,7 +175,7 @@
 Result^.dX:= dX;
 Result^.dY:= dY;
 Result^.doStep:= doStepHandlers[Kind];
-Result^.CollIndex:= High(Longword);
+Result^.CollisionIndex:= -1;
 Result^.Timer:= Timer;
 
 if CurrentTeam <> nil then
@@ -277,7 +277,7 @@
                 Result^.Radius:= 10;
                 end;
    gtBlowTorch: begin
-                Result^.Radius:= cHHRadius;
+                Result^.Radius:= cHHRadius + cBlowTorchC;
                 Result^.Timer:= 7500;
                 end;
      end;
@@ -464,7 +464,7 @@
              Surface);
 
 with PHedgehog(Gear^.Hedgehog)^ do
-     if Gear^.State = 0 then
+     if (Gear^.State and not gstAnimation) = 0 then
         begin
         t:= hwRound(Gear^.Y) - cHHRadius - 10 + WorldDy;
         dec(t, HealthTag^.h + 2);
--- a/hedgewars/uLandGraphics.pas	Mon May 07 21:12:06 2007 +0000
+++ b/hedgewars/uLandGraphics.pas	Wed May 09 20:32:41 2007 +0000
@@ -30,7 +30,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 ChangeRoundInLand(X, Y, Radius: LongInt; Delta: LongInt);
+procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
 
 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): boolean;
 
@@ -50,17 +50,34 @@
    for i:= max(x - dy, 0) to min(x + dy, 2047) do Land[y - dx, i]:= Value;
 end;
 
-procedure ChangeCircleLines(x, y, dx, dy: LongInt; Delta: LongInt);
+procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean);
 var i: LongInt;
 begin
-if ((y + dy) and $FFFFFC00) = 0 then
-   for i:= max(x - dx, 0) to min(x + dx, 2047) do inc(Land[y + dy, i], Delta);
-if ((y - dy) and $FFFFFC00) = 0 then
-   for i:= max(x - dx, 0) to min(x + dx, 2047) do inc(Land[y - dy, i], Delta);
-if ((y + dx) and $FFFFFC00) = 0 then
-   for i:= max(x - dy, 0) to min(x + dy, 2047) do inc(Land[y + dx, i], Delta);
-if ((y - dx) and $FFFFFC00) = 0 then
-   for i:= max(x - dy, 0) to min(x + dy, 2047) do inc(Land[y - dx, i], Delta);
+if not doSet then
+   begin
+   if ((y + dy) and $FFFFFC00) = 0 then
+      for i:= max(x - dx, 0) to min(x + dx, 2047) do
+          if (Land[y + dy, i] > 0) then dec(Land[y + dy, i]);
+   if ((y - dy) and $FFFFFC00) = 0 then
+      for i:= max(x - dx, 0) to min(x + dx, 2047) do
+          if (Land[y - dy, i] > 0) then dec(Land[y - dy, i]);
+   if ((y + dx) and $FFFFFC00) = 0 then
+      for i:= max(x - dy, 0) to min(x + dy, 2047) do
+          if (Land[y + dx, i] > 0) then dec(Land[y + dx, i]);
+   if ((y - dx) and $FFFFFC00) = 0 then
+      for i:= max(x - dy, 0) to min(x + dy, 2047) do
+          if (Land[y - dx, i] > 0) then dec(Land[y - dx, i]);
+   end else
+   begin
+   if ((y + dy) and $FFFFFC00) = 0 then
+      for i:= max(x - dx, 0) to min(x + dx, 2047) do inc(Land[y + dy, i]);
+   if ((y - dy) and $FFFFFC00) = 0 then
+      for i:= max(x - dx, 0) to min(x + dx, 2047) do inc(Land[y - dy, i]);
+   if ((y + dx) and $FFFFFC00) = 0 then
+      for i:= max(x - dy, 0) to min(x + dy, 2047) do inc(Land[y + dx, i]);
+   if ((y - dx) and $FFFFFC00) = 0 then
+      for i:= max(x - dy, 0) to min(x + dy, 2047) do inc(Land[y - dx, i]);
+   end
 end;
 
 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
@@ -83,7 +100,7 @@
   if (dx = dy) then FillCircleLines(x, y, dx, dy, Value);
 end;
 
-procedure ChangeRoundInLand(X, Y, Radius: LongInt; Delta: LongInt);
+procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
 var dx, dy, d: LongInt;
 begin
   dx:= 0;
@@ -91,7 +108,7 @@
   d:= 3 - 2 * Radius;
   while (dx < dy) do
      begin
-     ChangeCircleLines(x, y, dx, dy, Delta);
+     ChangeCircleLines(x, y, dx, dy, doSet);
      if (d < 0)
      then d:= d + 4 * dx + 6
      else begin
@@ -100,7 +117,7 @@
           end;
      inc(dx)
      end;
-  if (dx = dy) then ChangeCircleLines(x, y, dx, dy, Delta);
+  if (dx = dy) then ChangeCircleLines(x, y, dx, dy, doSet)
 end;
 
 procedure ClearLandPixel(y, x: LongInt);
@@ -277,6 +294,7 @@
         tx:= hwRound(X);
         ty:= hwRound(Y);
         if ((ty and $FFFFFC00) = 0) and ((tx and $FFFFF800) = 0) then
+         if Land[ty, tx] = COLOR_LAND then
            begin
            Land[ty, tx]:= 0;
            ClearLandPixel(ty, tx);