Moving hedgehog could get another hedgehog moving forward
authorunc0rr
Mon, 14 May 2007 18:58:54 +0000
changeset 513 69e06d710d46
parent 512 efc640bb60d0
child 514 fb8ba88a83c3
Moving hedgehog could get another hedgehog moving forward
hedgewars/GSHandlers.inc
hedgewars/HHHandlers.inc
hedgewars/uCollisions.pas
hedgewars/uFloat.pas
--- a/hedgewars/GSHandlers.inc	Thu May 10 21:19:12 2007 +0000
+++ b/hedgewars/GSHandlers.inc	Mon May 14 18:58:54 2007 +0000
@@ -93,7 +93,6 @@
 
 if (Gear^.State and gstFalling) <> 0 then Gear^.dY:= Gear^.dY + cGravity;
 
-
 Gear^.X:= Gear^.X + Gear^.dX;
 Gear^.Y:= Gear^.Y + Gear^.dY;
 CheckGearDrowning(Gear);
--- a/hedgewars/HHHandlers.inc	Thu May 10 21:19:12 2007 +0000
+++ b/hedgewars/HHHandlers.inc	Mon May 14 18:58:54 2007 +0000
@@ -328,9 +328,9 @@
 var prevState: Longword;
 begin
 prevState:= Gear^.State;
-if not TestCollisionYwithGear(Gear, 1) then
+if not TestCollisionYKick(Gear, 1) then
    begin
-   if (Gear^.dY.isNegative) and TestCollisionYwithGear(Gear, -1) then Gear^.dY:= _0;
+   if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then Gear^.dY:= _0;
    Gear^.State:= Gear^.State or gstFalling or gstMoving;
    Gear^.dY:= Gear^.dY + cGravity
    end else begin
@@ -345,7 +345,7 @@
 if (Gear^.State <> 0) then DeleteCI(Gear);
 
 if (Gear^.State and gstMoving) <> 0 then
-   if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) then
+   if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
       if ((Gear^.State and gstFalling) = 0) then
          if hwAbs(Gear^.dX) > _0_01 then
             if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.dX:= Gear^.dX * _0_96; Gear^.Y:= Gear^.Y - _1 end else
@@ -377,7 +377,9 @@
    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
+   if (not Gear^.dY.isNegative) and
+      (not TestCollisionYKick(Gear, 1)) and
+       TestCollisionYwithXYShift(Gear, 0, 1, 1) then
       begin
       CheckHHDamage(Gear);
       Gear^.dY:= _0;
--- a/hedgewars/uCollisions.pas	Thu May 10 21:19:12 2007 +0000
+++ b/hedgewars/uCollisions.pas	Mon May 14 18:58:54 2007 +0000
@@ -30,10 +30,17 @@
 
 procedure AddGearCI(Gear: PGear);
 procedure DeleteCI(Gear: PGear);
+
 function CheckGearsCollision(Gear: PGear): PGearArray;
+
 function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean;
 function TestCollisionYwithGear(Gear: PGear; Dir: LongInt): boolean;
+
+function TestCollisionXKick(Gear: PGear; Dir: LongInt): boolean;
+function TestCollisionYKick(Gear: PGear; Dir: LongInt): boolean;
+
 function TestCollisionY(Gear: PGear; Dir: LongInt): boolean;
+
 function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean;
 function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean;
 
@@ -143,7 +150,7 @@
            begin
            IntersectGear:= nil;
            TestWord:= 0
-           end else    
+           end else
            TestWord:= COLOR_LAND - 1
    else TestWord:= 0;
 
@@ -163,6 +170,103 @@
 TestCollisionYwithGear:= false
 end;
 
+function TestCollisionXKick(Gear: PGear; Dir: LongInt): boolean;
+var x, y, mx, my, i: LongInt;
+    flag: boolean;
+begin
+flag:= false;
+x:= hwRound(Gear^.X);
+if Dir < 0 then x:= x - Gear^.Radius
+           else x:= x + Gear^.Radius;
+if (x and $FFFFF800) = 0 then
+   begin
+   y:= hwRound(Gear^.Y) - Gear^.Radius + 1;
+   i:= y + Gear^.Radius * 2 - 2;
+   repeat
+     if (y and $FFFFFC00) = 0 then
+           if Land[y, x] = COLOR_LAND then exit(true)
+                                      else flag:= true;
+     inc(y)
+   until (y > i);
+   end;
+TestCollisionXKick:= false;
+
+if flag then
+   begin
+   if Count = 0 then exit;
+   mx:= hwRound(Gear^.X);
+   my:= hwRound(Gear^.Y);
+
+   for i:= 0 to Pred(Count) do
+    with cinfos[i] do
+      if (Gear <> cGear) and
+         (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius)) and
+         ((mx > x) xor (Dir > 0)) then
+             begin
+             Gear^.dX:= Gear^.dX {* _0_6};
+             Gear^.dY:= Gear^.dY {* _0_6};
+             with cinfos[i].cGear^ do
+                  begin
+                  dX:= Gear^.dX {* _1_5};
+                  dY:= Gear^.dY {* _1_5};
+                  State:= State and gstMoving;
+                  Active:= true
+                  end;
+             DeleteCI(cinfos[i].cGear);
+             exit
+             end
+   end
+end;
+
+function TestCollisionYKick(Gear: PGear; Dir: LongInt): boolean;
+var x, y, mx, my, i: LongInt;
+    flag: boolean;
+begin
+flag:= false;
+y:= hwRound(Gear^.Y);
+if Dir < 0 then y:= y - Gear^.Radius
+           else y:= y + Gear^.Radius;
+if (y and $FFFFFC00) = 0 then
+   begin
+   x:= hwRound(Gear^.X) - Gear^.Radius + 1;
+   i:= x + Gear^.Radius * 2 - 2;
+   repeat
+     if (x and $FFFFF800) = 0 then
+        if Land[y, x] > 0 then
+           if Land[y, x] = COLOR_LAND then exit(true)
+                                      else flag:= true;
+     inc(x)
+   until (x > i);
+   end;
+TestCollisionYKick:= false;
+
+if flag then
+   begin
+   if Count = 0 then exit;
+   mx:= hwRound(Gear^.X);
+   my:= hwRound(Gear^.Y);
+
+   for i:= 0 to Pred(Count) do
+    with cinfos[i] do
+      if (Gear <> cGear) and
+         (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius)) and
+         ((my > y) xor (Dir > 0)) then
+             begin
+             Gear^.dX:= Gear^.dX * _0_6;
+             Gear^.dY:= Gear^.dY * _0_6;
+             with cinfos[i].cGear^ do
+                  begin
+                  dX:= Gear^.dX {* _1_5};
+                  dY:= Gear^.dY {* _1_5};
+                  State:= State and gstMoving;
+                  Active:= true
+                  end;
+             DeleteCI(cinfos[i].cGear);
+             exit
+             end
+   end
+end;
+
 function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean;
 begin
 Gear^.X:= Gear^.X + ShiftX;
--- a/hedgewars/uFloat.pas	Thu May 10 21:19:12 2007 +0000
+++ b/hedgewars/uFloat.pas	Mon May 14 18:58:54 2007 +0000
@@ -100,6 +100,7 @@
             _1_9: hwFloat = (isNegative: false; QWordValue:  8160437862);
               _0: hwFloat = (isNegative: false; QWordValue:           0);
               _1: hwFloat = (isNegative: false; QWordValue:  4294967296);
+            _1_5: hwFloat = (isNegative: false; QWordValue:  4294967296 * 3 div 2);
               _2: hwFloat = (isNegative: false; QWordValue:  4294967296 * 2);
               _3: hwFloat = (isNegative: false; QWordValue:  4294967296 * 3);
               _4: hwFloat = (isNegative: false; QWordValue:  4294967296 * 4);