--- 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);