hedgewars/uGearsHandlersRope.pas
changeset 7593 b966e2d833f2
parent 7592 cf67e58313ea
child 7594 5f03595335e6
equal deleted inserted replaced
7592:cf67e58313ea 7593:b966e2d833f2
   102     lx, ly, cd: LongInt;
   102     lx, ly, cd: LongInt;
   103     haveCollision,
   103     haveCollision,
   104     haveDivided: boolean;
   104     haveDivided: boolean;
   105 
   105 
   106 begin
   106 begin
       
   107     if GameTicks mod 8 <> 0 then exit;
       
   108 
   107     HHGear := Gear^.Hedgehog^.Gear;
   109     HHGear := Gear^.Hedgehog^.Gear;
   108 
   110 
   109     if ((HHGear^.State and gstHHDriven) = 0)
   111     if ((HHGear^.State and gstHHDriven) = 0)
   110        or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then
   112        or (CheckGearDrowning(HHGear)) or (Gear^.PortalCounter <> 0) then
   111         begin
   113         begin
   113         RopeDeleteMe(Gear, HHGear);
   115         RopeDeleteMe(Gear, HHGear);
   114         exit
   116         exit
   115         end;
   117         end;
   116 
   118 
   117     if (Gear^.Message and gmLeft  <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then
   119     if (Gear^.Message and gmLeft  <> 0) and (not TestCollisionXwithGear(HHGear, -1)) then
   118         HHGear^.dX := HHGear^.dX - _0_0002;
   120         HHGear^.dX := HHGear^.dX - _0_0128;
   119 
   121 
   120     if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear,  1)) then
   122     if (Gear^.Message and gmRight <> 0) and (not TestCollisionXwithGear(HHGear,  1)) then
   121         HHGear^.dX := HHGear^.dX + _0_0002;
   123         HHGear^.dX := HHGear^.dX + _0_0128;
   122 
   124 
   123     // vector between hedgehog and rope attaching point
   125     // vector between hedgehog and rope attaching point
   124     ropeDx := HHGear^.X - Gear^.X;
   126     ropeDx := HHGear^.X - Gear^.X;
   125     ropeDy := HHGear^.Y - Gear^.Y;
   127     ropeDy := HHGear^.Y - Gear^.Y;
   126 
   128 
   134         else
   136         else
   135             cd:= 1;
   137             cd:= 1;
   136 
   138 
   137         // apply gravity if there is no obstacle
   139         // apply gravity if there is no obstacle
   138         if not TestCollisionXwithGear(HHGear, cd) then
   140         if not TestCollisionXwithGear(HHGear, cd) then
   139             HHGear^.dY := HHGear^.dY + cGravity;
   141             HHGear^.dY := HHGear^.dY + cGravity * 64;
   140 
   142 
   141         if (GameFlags and gfMoreWind) <> 0 then
   143         if (GameFlags and gfMoreWind) <> 0 then
   142             // apply wind if there's no obstacle
   144             // apply wind if there's no obstacle
   143             if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then
   145             if not TestCollisionXwithGear(HHGear, hwSign(cWindSpeed)) then
   144                 HHGear^.dX := HHGear^.dX + cWindSpeed / HHGear^.Density;
   146                 HHGear^.dX := HHGear^.dX + cWindSpeed * 64 / HHGear^.Density;
   145         end;
   147         end;
   146 
   148 
   147     mdX := ropeDx + HHGear^.dX;
   149     mdX := ropeDx + HHGear^.dX;
   148     mdY := ropeDy + HHGear^.dY;
   150     mdY := ropeDy + HHGear^.dY;
   149     len := _1 / Distance(mdX, mdY);
   151     len := _1 / Distance(mdX, mdY);
   160     ty := HHGear^.Y;
   162     ty := HHGear^.Y;
   161 
   163 
   162     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
   164     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
   163         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
   165         if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
   164         or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then
   166         or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then
   165             Gear^.Elasticity := Gear^.Elasticity + _0_3;
   167             Gear^.Elasticity := Gear^.Elasticity + _2_4;
   166 
   168 
   167     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
   169     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
   168         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
   170         if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
   169         or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then
   171         or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then
   170             Gear^.Elasticity := Gear^.Elasticity - _0_3;
   172             Gear^.Elasticity := Gear^.Elasticity - _2_4;
   171 
   173 
   172     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
   174     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
   173     HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity;
   175     HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity;
   174 
   176 
   175     HHGear^.dX := HHGear^.X - tx;
   177     HHGear^.dX := HHGear^.X - tx;
   181     // check whether rope needs dividing
   183     // check whether rope needs dividing
   182 
   184 
   183     len := Gear^.Elasticity - _5;
   185     len := Gear^.Elasticity - _5;
   184     nx := Gear^.X + mdX * len;
   186     nx := Gear^.X + mdX * len;
   185     ny := Gear^.Y + mdY * len;
   187     ny := Gear^.Y + mdY * len;
   186     tx := mdX * _0_3; // should be the same as increase step
   188     tx := mdX * _2_4; // should be the same as increase step
   187     ty := mdY * _0_3;
   189     ty := mdY * _2_4;
   188 
   190 
   189     while len > _3 do
   191     while len > _3 do
   190         begin
   192         begin
   191         lx := hwRound(nx);
   193         lx := hwRound(nx);
   192         ly := hwRound(ny);
   194         ly := hwRound(ny);
   223             break
   225             break
   224             end;
   226             end;
   225         nx := nx - tx;
   227         nx := nx - tx;
   226         ny := ny - ty;
   228         ny := ny - ty;
   227 
   229 
   228         // len := len - _0_3 // should be the same as increase step
   230         // len := len - _2_4 // should be the same as increase step
   229         len.QWordValue := len.QWordValue - _0_3.QWordValue;
   231         len.QWordValue := len.QWordValue - _2_4.QWordValue;
   230         end;
   232         end;
   231 
   233 
   232     if not haveDivided then
   234     if not haveDivided then
   233         if RopePoints.Count > 0 then // check whether the last dividing point could be removed
   235         if RopePoints.Count > 0 then // check whether the last dividing point could be removed
   234             begin
   236             begin
   266         haveCollision := true
   268         haveCollision := true
   267         end;
   269         end;
   268 
   270 
   269     if haveCollision and (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.Message and (gmUp or gmDown) <> 0) then
   271     if haveCollision and (Gear^.Message and (gmLeft or gmRight) <> 0) and (Gear^.Message and (gmUp or gmDown) <> 0) then
   270         begin
   272         begin
   271         HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
   273         HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _1_6, HHGear^.dX);
   272         HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
   274         HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _1_6, HHGear^.dY)
   273         end;
   275         end;
   274 
   276 
   275     len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY);
   277     len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY);
   276     if len > _0_64 then
   278     if len > _49 then
   277         begin
   279         begin
   278         len := _0_8 / hwSqrt(len);
   280         len := _7 / hwSqrt(len);
   279         HHGear^.dX := HHGear^.dX * len;
   281         HHGear^.dX := HHGear^.dX * len;
   280         HHGear^.dY := HHGear^.dY * len;
   282         HHGear^.dY := HHGear^.dY * len;
   281         end;
   283         end;
   282 
   284 
   283     haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0);
   285     haveCollision:= ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)]) <> 0);
   319 
   321 
   320     if not haveCollision then
   322     if not haveCollision then
   321         begin
   323         begin
   322         if (Gear^.State and gsttmpFlag) <> 0 then
   324         if (Gear^.State and gsttmpFlag) <> 0 then
   323             begin
   325             begin
       
   326             HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shr 3;
       
   327             HHGear^.dY.QWordValue:= HHGear^.dY.QWordValue shr 3;
       
   328             
   324             PlaySound(sndRopeRelease);
   329             PlaySound(sndRopeRelease);
   325             if Gear^.Hedgehog^.CurAmmoType <> amParachute then
   330             if Gear^.Hedgehog^.CurAmmoType <> amParachute then
   326                 RopeWaitCollision(Gear, HHGear)
   331                 RopeWaitCollision(Gear, HHGear)
   327             else
   332             else
   328                 RopeDeleteMe(Gear, HHGear)
   333                 RopeDeleteMe(Gear, HHGear)
   392                 Gear^.Elasticity := tt;
   397                 Gear^.Elasticity := tt;
   393                 Gear^.doStep := @doStepRopeWork;
   398                 Gear^.doStep := @doStepRopeWork;
   394                 PlaySound(sndRopeAttach);
   399                 PlaySound(sndRopeAttach);
   395                 with HHGear^ do
   400                 with HHGear^ do
   396                     begin
   401                     begin
       
   402                     dX.QWordValue:= dX.QWordValue shl 3;
       
   403                     dY.QWordValue:= dY.QWordValue shl 3;
   397                     State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   404                     State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   398                     Message := Message and (not gmAttack)
   405                     Message := Message and (not gmAttack)
   399                     end;
   406                     end;
   400 
   407 
   401                 RopeRemoveFromAmmo(Gear, HHGear);
   408                 RopeRemoveFromAmmo(Gear, HHGear);
   418         begin
   425         begin
   419         Gear^.doStep := @doStepRopeWork;
   426         Gear^.doStep := @doStepRopeWork;
   420         PlaySound(sndRopeAttach);
   427         PlaySound(sndRopeAttach);
   421         with HHGear^ do
   428         with HHGear^ do
   422             begin
   429             begin
       
   430             dX.QWordValue:= dX.QWordValue shl 3;
       
   431             dY.QWordValue:= dY.QWordValue shl 3;
   423             State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   432             State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   424             Message := Message and (not gmAttack)
   433             Message := Message and (not gmAttack)
   425             end;
   434             end;
   426 
   435 
   427         RopeRemoveFromAmmo(Gear, HHGear);
   436         RopeRemoveFromAmmo(Gear, HHGear);