# HG changeset patch # User unc0rr # Date 1179169134 0 # Node ID 69e06d710d46cd783ce3d8ce3035119f347d1551 # Parent efc640bb60d02dfc035f5a4b62e200cc5f947cd9 Moving hedgehog could get another hedgehog moving forward diff -r efc640bb60d0 -r 69e06d710d46 hedgewars/GSHandlers.inc --- 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); diff -r efc640bb60d0 -r 69e06d710d46 hedgewars/HHHandlers.inc --- 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; diff -r efc640bb60d0 -r 69e06d710d46 hedgewars/uCollisions.pas --- 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; diff -r efc640bb60d0 -r 69e06d710d46 hedgewars/uFloat.pas --- 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);