hedgewars/uCollisions.pas
changeset 3401 d5d31d16eccc
parent 3236 4ab3917d7d44
child 3407 dcc129c4352e
equal deleted inserted replaced
3400:4003bf74588a 3401:d5d31d16eccc
    46 
    46 
    47 function  TestCollisionY(Gear: PGear; Dir: LongInt): boolean;
    47 function  TestCollisionY(Gear: PGear; Dir: LongInt): boolean;
    48 
    48 
    49 function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean;
    49 function  TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean;
    50 function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean;
    50 function  TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean;
       
    51 
       
    52 function  calcSlopeNormal(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): Boolean;
    51 
    53 
    52 implementation
    54 implementation
    53 uses uMisc, uConsts, uLand, uLandGraphics, uConsole;
    55 uses uMisc, uConsts, uLand, uLandGraphics, uConsole;
    54 
    56 
    55 type TCollisionEntry = record
    57 type TCollisionEntry = record
   310 TestCollisionYwithXYShift:= TestCollisionYwithGear(Gear, Dir);
   312 TestCollisionYwithXYShift:= TestCollisionYwithGear(Gear, Dir);
   311 Gear^.X:= Gear^.X - int2hwFloat(ShiftX);
   313 Gear^.X:= Gear^.X - int2hwFloat(ShiftX);
   312 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY)
   314 Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY)
   313 end;
   315 end;
   314 
   316 
       
   317 
       
   318 function calcSlopeNormal(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): boolean;
       
   319 var sx, sy, ldx, ldy, rdx, rdy: LongInt;
       
   320     i, j, mx, my : ShortInt;
       
   321     tmpx, tmpy: LongWord;
       
   322     dx, dy, rx, ry: hwFloat;
       
   323     leftsteps:  Array[0..4,0..1] of ShortInt;
       
   324     rightsteps: Array[0..4,0..1] of ShortInt;
       
   325 
       
   326 begin
       
   327     dx:= Gear^.dX;
       
   328     dy:= Gear^.dY;
       
   329     
       
   330     if Gear^.AdvBounce > 0 then
       
   331         begin
       
   332         rx:= _0_5 + Int2hwFloat(collisionX) - Gear^.X;
       
   333         ry:= _0_5 + Int2hwFloat(collisionY) - Gear^.Y;
       
   334         end
       
   335     else
       
   336         begin
       
   337         rx:= dx;
       
   338         ry:= dy;
       
   339         end;
       
   340 
       
   341     sx:= hwSign(rx);
       
   342     sy:= hwSign(ry);
       
   343 
       
   344     if rx.QWordValue > ry.QWordValue then
       
   345         begin
       
   346         if (ry/rx).QWordValue < _0_5.QWordValue then sy:= 0;
       
   347         end
       
   348     else
       
   349         begin
       
   350         if (rx/ry).QWordValue < _0_5.QWordValue then sx:= 0;
       
   351         end;
       
   352 
       
   353     mx:= -sx;
       
   354     my:= -sy;
       
   355 
       
   356     for i:= 0 to 4 do
       
   357         begin
       
   358         if (mx = -1) and (my <>  1) then my:= my + 1
       
   359         else if (my = 1) and (mx <> 1) then mx:= mx + 1
       
   360         else if (mx = 1) and (my <> -1) then my:= my - 1
       
   361         else mx:= mx - 1;
       
   362 
       
   363         leftsteps[i,0]:= mx;
       
   364         leftsteps[i,1]:= my;
       
   365         end;
       
   366 
       
   367     mx:= -sx;
       
   368     my:= -sy;
       
   369 
       
   370     for i:= 0 to 4 do
       
   371         begin
       
   372         if (mx = -1) and (my <> -1) then my:= my - 1
       
   373         else if (my = -1) and (mx <> 1) then mx:= mx + 1
       
   374         else if (mx = 1) and (my <> 1) then my:= my + 1
       
   375         else mx:= mx - 1;
       
   376 
       
   377         rightsteps[i,0]:= mx;
       
   378         rightsteps[i,1]:= my;
       
   379         end;
       
   380 
       
   381     ldx:= collisionX;
       
   382     ldy:= collisionY;
       
   383     rdx:= collisionX;
       
   384     rdy:= collisionY;
       
   385 
       
   386     for i:= 0 to 4 do
       
   387         begin
       
   388         tmpx:= collisionX + leftsteps[i,0];
       
   389         tmpy:= collisionY + leftsteps[i,1];
       
   390         if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0) then
       
   391             if (Land[tmpy,tmpx] > TestWord) then
       
   392                 begin
       
   393                 if i <> 0 then
       
   394                     for j:= 0 to 2 do
       
   395                         begin
       
   396                         leftsteps[j,0]:= leftsteps[i+j,0];
       
   397                         leftsteps[j,1]:= leftsteps[i+j,1];
       
   398                         end;
       
   399                 ldx:= tmpx;
       
   400                 ldy:= tmpy;
       
   401                 break;
       
   402                 end;
       
   403         end;
       
   404 
       
   405     for i:= 0 to 4 do
       
   406         begin
       
   407         tmpx:= collisionX + rightsteps[i,0];
       
   408         tmpy:= collisionY + rightsteps[i,1];
       
   409         if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0) then
       
   410             if (Land[tmpy,tmpx] > TestWord) then
       
   411                 begin
       
   412                 if i <> 0 then
       
   413                     for j:= 0 to 2 do
       
   414                         begin
       
   415                         rightsteps[j,0]:= rightsteps[i+j-1,0];
       
   416                         rightsteps[j,1]:= rightsteps[i+j-1,1];
       
   417                         end;
       
   418                 rdx:= tmpx;
       
   419                 rdy:= tmpy;
       
   420                 break;
       
   421                 end;
       
   422         end;
       
   423 
       
   424     // TODO: avoid redundant checks
       
   425     for i:= 0 to 4 do
       
   426         begin
       
   427         for j:= 0 to 2 do
       
   428             begin
       
   429             tmpx:= ldx + leftsteps[j,0];
       
   430             tmpy:= ldy + leftsteps[j,1];
       
   431             if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0) then
       
   432                 if (Land[tmpy,tmpx] > TestWord) then
       
   433                     begin
       
   434                     ldx:= tmpx;
       
   435                     ldy:= tmpy;
       
   436                     break;
       
   437                     end;
       
   438             end;
       
   439         end;
       
   440 
       
   441     for i:= 0 to 4 do
       
   442         begin
       
   443         for j:= 0 to 2 do
       
   444             begin
       
   445             tmpx:= rdx + rightsteps[j,0];
       
   446             tmpy:= rdy + rightsteps[j,1];
       
   447             if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0) then
       
   448                 if (Land[tmpy,tmpx] > TestWord) then
       
   449                     begin
       
   450                     rdx:= tmpx;
       
   451                     rdy:= tmpy;
       
   452                     break;
       
   453                     end;
       
   454             end;
       
   455         end;
       
   456 
       
   457     ldx:= rdx - ldx;
       
   458     ldy:= rdy - ldy;
       
   459 
       
   460     // rotate vector by 90°
       
   461     rdx:= -ldy;
       
   462     ldy:= ldx;
       
   463     ldx:= rdx;
       
   464     
       
   465     if (ldy <> 0) then tmpy := collisionY + ldy div abs(ldy) else tmpy:= collisionY;
       
   466     if (ldx <> 0) then tmpx := collisionX + ldx div abs(ldx) else tmpx:= collisionX;
       
   467     if ((ldx = 0) and (ldy = 0)) then EXIT(false);
       
   468     
       
   469     if ((((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0) 
       
   470         and (Land[tmpy,tmpx] > TestWord)) then
       
   471             begin
       
   472             if (ldy <> 0) then
       
   473                 begin
       
   474                 ldy:= -ldy;
       
   475                 tmpy := collisionY + ldy div abs(ldy);
       
   476                 end;
       
   477             if (ldx <> 0) then
       
   478                 begin
       
   479                 ldx:= -ldx;
       
   480                 tmpx := collisionX + ldx div abs(ldx);
       
   481                 end;
       
   482             
       
   483             if ((((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0) 
       
   484                 and (Land[tmpy,tmpx] > TestWord)) then
       
   485                     EXIT(false);
       
   486             end;
       
   487 
       
   488         
       
   489     if (dx*ldx + dy*ldy).isNegative then
       
   490         begin
       
   491         deltaX:= ldx;
       
   492         deltaY:= ldy;
       
   493         EXIT(true);
       
   494         end;
       
   495 exit(false);
       
   496 end;
       
   497 
   315 procedure initModule;
   498 procedure initModule;
   316 begin
   499 begin
   317     Count:= 0;
   500     Count:= 0;
   318 end;
   501 end;
   319 
   502