hedgewars/uCollisions.pas
changeset 6123 0cb751caf0ac
parent 6081 537bbd5c1a62
child 6124 bee90df26109
equal deleted inserted replaced
6122:58ecb4fb743d 6123:0cb751caf0ac
   385 TestRectancleForObstacle:= false
   385 TestRectancleForObstacle:= false
   386 end;
   386 end;
   387 
   387 
   388 function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean;
   388 function CalcSlopeTangent(Gear: PGear; collisionX, collisionY: LongInt; var outDeltaX, outDeltaY: LongInt; TestWord: LongWord): boolean;
   389 var ldx, ldy, rdx, rdy: LongInt;
   389 var ldx, ldy, rdx, rdy: LongInt;
   390     i, j, mx, my, li, ri, jfr, jto, tmpo : ShortInt;
   390     i, j, k, mx, my, li, ri, jfr, jto, tmpo : ShortInt;
   391     tmpx, tmpy: LongWord;
   391     tmpx, tmpy: LongWord;
   392     dx, dy, s: hwFloat;
   392     dx, dy, s: hwFloat;
   393     offset: Array[0..7,0..1] of ShortInt;
   393     offset: Array[0..7,0..1] of ShortInt;
       
   394     isColl: Boolean;
   394 
   395 
   395 begin
   396 begin
   396     dx:= Gear^.dX;
   397     dx:= Gear^.dX;
   397     dy:= Gear^.dY;
   398     dy:= Gear^.dY;
   398 
   399 
   416     for i:= 0 to 7 do
   417     for i:= 0 to 7 do
   417         begin
   418         begin
   418         offset[i,0]:= mx;
   419         offset[i,0]:= mx;
   419         offset[i,1]:= my;
   420         offset[i,1]:= my;
   420 
   421 
   421         tmpx:= collisionX + mx;
   422         // multiplicator k tries to skip small pixels/gaps when possible
   422         tmpy:= collisionY + my;
   423         for k:= 4 downto 1 do
   423 
   424             begin
   424         if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then
   425             tmpx:= collisionX + k * mx;
   425             if (Land[tmpy,tmpx] > TestWord) then
   426             tmpy:= collisionY + k * my;
   426                 begin
   427 
   427                 // remember the index belonging to the first and last collision (if in 1st half)
   428             if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then
   428                 if (i <> 0) then
   429                 if (Land[tmpy,tmpx] > TestWord) then
   429                     begin
   430                     begin
   430                     if (ri = -1) then
   431                     // remember the index belonging to the first and last collision (if in 1st half)
   431                         ri:= i
   432                     if (i <> 0) then
   432                     else
   433                         begin
   433                         li:= i;
   434                         if (ri = -1) then
       
   435                             ri:= i
       
   436                         else
       
   437                             li:= i;
       
   438                         end;
   434                     end;
   439                     end;
   435                 end;
   440             end;
   436 
   441 
   437         if i = 7 then break;
   442         if i = 7 then break;
   438 
   443 
   439         // prepare offset for next check (clockwise)
   444         // prepare offset for next check (clockwise)
   440         if (mx = -1) and (my <> -1) then my:= my - 1
   445         if (mx = -1) and (my <> -1) then my:= my - 1
   455         // using mx,my as temporary value buffer here
   460         // using mx,my as temporary value buffer here
   456 
   461 
   457         jfr:= 8+li+1;
   462         jfr:= 8+li+1;
   458         jto:= 8+li-1;
   463         jto:= 8+li-1;
   459 
   464 
       
   465         isColl:= false;
   460         for j:= jfr downto jto do
   466         for j:= jfr downto jto do
   461             begin
   467             begin
   462             tmpo:= j mod 8;
   468             tmpo:= j mod 8;
   463             tmpx:= ldx + offset[tmpo,0];
   469             // multiplicator k tries to skip small pixels/gaps when possible
   464             tmpy:= ldy + offset[tmpo,1];
   470             for k:= 3 downto 1 do
   465             if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0)
   471                 begin
   466                 and (Land[tmpy,tmpx] > TestWord) then
   472                 tmpx:= ldx + k * offset[tmpo,0];
   467                     begin
   473                 tmpy:= ldy + k * offset[tmpo,1];
   468                     ldx:= tmpx;
   474                 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0)
   469                     ldy:= tmpy;
   475                     and (Land[tmpy,tmpx] > TestWord) then
   470                     break;
   476                         begin
   471                     end;
   477                         ldx:= tmpx;
       
   478                         ldy:= tmpy;
       
   479                         isColl:= true;
       
   480                         break;
       
   481                         end;
       
   482                 end;
       
   483             if isColl then break;
   472             end;
   484             end;
   473 
   485 
   474         jfr:= 8+ri-1;
   486         jfr:= 8+ri-1;
   475         jto:= 8+ri+1;
   487         jto:= 8+ri+1;
   476 
   488 
       
   489         isColl:= false;
   477         for j:= jfr to jto do
   490         for j:= jfr to jto do
   478             begin
   491             begin
   479             tmpo:= j mod 8;
   492             tmpo:= j mod 8;
   480             tmpx:= rdx + offset[tmpo,0];
   493             for k:= 3 downto 1 do
   481             tmpy:= rdy + offset[tmpo,1];
   494                 begin
   482             if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0)
   495                 tmpx:= rdx + k * offset[tmpo,0];
   483                 and (Land[tmpy,tmpx] > TestWord) then
   496                 tmpy:= rdy + k * offset[tmpo,1];
   484                     begin
   497                 if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK)  = 0)
   485                     rdx:= tmpx;
   498                     and (Land[tmpy,tmpx] > TestWord) then
   486                     rdy:= tmpy;
   499                         begin
   487                     break;
   500                         rdx:= tmpx;
   488                     end;
   501                         rdy:= tmpy;
       
   502                         isColl:= true;
       
   503                         break;
       
   504                         end;
       
   505                 end;
       
   506             if isColl then break;
   489             end;
   507             end;
   490         end;
   508         end;
   491 
   509 
   492     ldx:= rdx - ldx;
   510     ldx:= rdx - ldx;
   493     ldy:= rdy - ldy;
   511     ldy:= rdy - ldy;