hedgewars/uCollisions.pas
branchwebgl
changeset 9521 8054d9d775fd
parent 9248 3e8558dc285a
parent 9305 8e5140875ab5
child 9950 2759212a27de
equal deleted inserted replaced
9282:92af50454cf2 9521:8054d9d775fd
    31         end;
    31         end;
    32 
    32 
    33 procedure initModule;
    33 procedure initModule;
    34 procedure freeModule;
    34 procedure freeModule;
    35 
    35 
    36 procedure AddGearCI(Gear: PGear);
    36 procedure AddCI(Gear: PGear);
    37 procedure DeleteCI(Gear: PGear);
    37 procedure DeleteCI(Gear: PGear);
    38 
    38 
    39 function  CheckGearsCollision(Gear: PGear): PGearArray;
    39 function  CheckGearsCollision(Gear: PGear): PGearArray;
    40 
    40 
    41 function  TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean;
    41 function  TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean;
    70 const MAXRECTSINDEX = 1023;
    70 const MAXRECTSINDEX = 1023;
    71 var Count: Longword;
    71 var Count: Longword;
    72     cinfos: array[0..MAXRECTSINDEX] of TCollisionEntry;
    72     cinfos: array[0..MAXRECTSINDEX] of TCollisionEntry;
    73     ga: TGearArray;
    73     ga: TGearArray;
    74 
    74 
    75 procedure AddGearCI(Gear: PGear);
    75 procedure AddCI(Gear: PGear);
    76 var t: PGear;
    76 var t: PGear;
    77 begin
    77 begin
    78 if Gear^.CollisionIndex >= 0 then
    78 if Gear^.CollisionIndex >= 0 then
    79     exit;
    79     exit;
    80 TryDo(Count <= MAXRECTSINDEX, 'Collision rects array overflow', true);
    80 TryDo(Count <= MAXRECTSINDEX, 'Collision rects array overflow', true);
    81 with cinfos[Count] do
    81 with cinfos[Count] do
    82     begin
    82     begin
    83     X:= hwRound(Gear^.X);
    83     X:= hwRound(Gear^.X);
    84     Y:= hwRound(Gear^.Y);
    84     Y:= hwRound(Gear^.Y);
    85     Radius:= Gear^.Radius;
    85     Radius:= Gear^.Radius;
    86     ChangeRoundInLand(X, Y, Radius - 1, true, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen <> 0)));
    86     ChangeRoundInLand(X, Y, Radius - 1, true, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen = 0)));
    87     cGear:= Gear
    87     cGear:= Gear
    88     end;
    88     end;
    89 Gear^.CollisionIndex:= Count;
    89 Gear^.CollisionIndex:= Count;
    90 inc(Count);
    90 inc(Count);
    91 // mines are the easiest way to overflow collision
    91 // mines are the easiest way to overflow collision
   102 procedure DeleteCI(Gear: PGear);
   102 procedure DeleteCI(Gear: PGear);
   103 begin
   103 begin
   104 if Gear^.CollisionIndex >= 0 then
   104 if Gear^.CollisionIndex >= 0 then
   105     begin
   105     begin
   106     with cinfos[Gear^.CollisionIndex] do
   106     with cinfos[Gear^.CollisionIndex] do
   107         ChangeRoundInLand(X, Y, Radius - 1, false, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen <> 0)));
   107         ChangeRoundInLand(X, Y, Radius - 1, false, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen = 0)));
   108     cinfos[Gear^.CollisionIndex]:= cinfos[Pred(Count)];
   108     cinfos[Gear^.CollisionIndex]:= cinfos[Pred(Count)];
   109     cinfos[Gear^.CollisionIndex].cGear^.CollisionIndex:= Gear^.CollisionIndex;
   109     cinfos[Gear^.CollisionIndex].cGear^.CollisionIndex:= Gear^.CollisionIndex;
   110     Gear^.CollisionIndex:= -1;
   110     Gear^.CollisionIndex:= -1;
   111     dec(Count)
   111     dec(Count)
   112     end;
   112     end;
   235     mx:= hwRound(Gear^.X);
   235     mx:= hwRound(Gear^.X);
   236     my:= hwRound(Gear^.Y);
   236     my:= hwRound(Gear^.Y);
   237 
   237 
   238     for i:= 0 to Pred(Count) do
   238     for i:= 0 to Pred(Count) do
   239         with cinfos[i] do
   239         with cinfos[i] do
   240             if (Gear <> cGear) and (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2))
   240             if  (Gear <> cGear) and 
   241             and ((mx > x) xor (Dir > 0)) and
   241                 ((mx > x) xor (Dir > 0)) and
   242                 (
   242                 (
   243                   ((cGear^.Kind in [gtHedgehog, gtMine, gtKnife]) and ((Gear^.State and gstNotKickable) = 0)) or
   243                   ((cGear^.Kind in [gtHedgehog, gtMine, gtKnife]) and ((Gear^.State and gstNotKickable) = 0)) or
   244                 // only apply X kick if the barrel is knocked over
   244                 // only apply X kick if the barrel is knocked over
   245                 ((cGear^.Kind = gtExplosives) and ((cGear^.State and gsttmpflag) <> 0))) then
   245                   ((cGear^.Kind = gtExplosives) and ((cGear^.State and gsttmpflag) <> 0))
       
   246                 ) and
       
   247                 (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2)) then
   246                     begin
   248                     begin
   247                     with cGear^ do
   249                     with cGear^ do
   248                         begin
   250                         begin
   249                         dX:= Gear^.dX;
   251                         dX:= Gear^.dX;
   250                         dY:= Gear^.dY * _0_5;
   252                         dY:= Gear^.dY * _0_5;
   298     my:= hwRound(Gear^.Y);
   300     my:= hwRound(Gear^.Y);
   299     myr:= my+Gear^.Radius;
   301     myr:= my+Gear^.Radius;
   300 
   302 
   301     for i:= 0 to Pred(Count) do
   303     for i:= 0 to Pred(Count) do
   302         with cinfos[i] do
   304         with cinfos[i] do
   303             if (Gear <> cGear) and (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2))
   305             if (Gear <> cGear) and
   304             and ((myr > y) xor (Dir > 0)) and
   306                ((myr > y) xor (Dir > 0)) and
   305                 (
   307                (Gear^.State and gstNotKickable = 0) and
   306                  (cGear^.Kind in [gtHedgehog, gtMine, gtKnife, gtExplosives]) and 
   308                (cGear^.Kind in [gtHedgehog, gtMine, gtKnife, gtExplosives]) and 
   307                  ((Gear^.State and gstNotKickable) = 0)) then
   309                (sqr(mx - x) + sqr(my - y) <= sqr(Radius + Gear^.Radius + 2)) then
   308                     begin
   310                     begin
   309                     with cGear^ do
   311                     with cGear^ do
   310                         begin
   312                         begin
   311                         if (Kind <> gtExplosives) or ((State and gsttmpflag) <> 0) then
   313                         if (Kind <> gtExplosives) or ((State and gsttmpflag) <> 0) then
   312                             dX:= Gear^.dX * _0_5;
   314                             dX:= Gear^.dX * _0_5;