hedgewars/uGearsHandlersRope.pas
branchui-scaling
changeset 15283 c4fd2813b127
parent 14653 4aec7d17ef7d
child 15900 128ace913837
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
    48     tX:= HHGear^.X;
    48     tX:= HHGear^.X;
    49     if WorldWrap(HHGear) and (WorldEdge = weWrap) and
    49     if WorldWrap(HHGear) and (WorldEdge = weWrap) and
    50        ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0))  then
    50        ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0))  then
    51         begin
    51         begin
    52         HHGear^.X:= tX;
    52         HHGear^.X:= tX;
    53         HHGear^.dX.isNegative:= hwRound(tX) > LongInt(leftX) + HHGear^.Radius * 2
    53         HHGear^.dX.isNegative:= hwRound(tX) > leftX + HHGear^.Radius * 2
    54         end;
    54         end;
    55 
    55 
    56     if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then
    56     if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then
    57         begin
    57         begin
    58         DeleteGear(Gear);
    58         DeleteGear(Gear);
    64     if ((HHGear^.State and gstHHDriven) = 0)
    64     if ((HHGear^.State and gstHHDriven) = 0)
    65     or (CheckGearDrowning(HHGear))
    65     or (CheckGearDrowning(HHGear))
    66     or (TestCollisionYwithGear(HHGear, 1) <> 0) then
    66     or (TestCollisionYwithGear(HHGear, 1) <> 0) then
    67         begin
    67         begin
    68         DeleteGear(Gear);
    68         DeleteGear(Gear);
    69         if (TestCollisionYwithGear(HHGear, 1) <> 0) and (GetAmmoEntry(HHGear^.Hedgehog^, amRope)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
    69         if (TestCollisionYwithGear(HHGear, 1) <> 0) and (GetAmmoEntry(HHGear^.Hedgehog^, amRope)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) and (HHGear^.Hedgehog^.MultiShootAttacks = 0) then
    70             HHGear^.Hedgehog^.CurAmmoType:= amRope;
    70             HHGear^.Hedgehog^.CurAmmoType:= amRope;
    71         isCursorVisible := false;
    71         isCursorVisible := false;
    72         ApplyAmmoChanges(HHGear^.Hedgehog^);
    72         ApplyAmmoChanges(HHGear^.Hedgehog^);
    73         exit
    73         exit
    74         end;
    74         end;
   158        ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0))  then
   158        ((TestCollisionXwithGear(HHGear, 1) <> 0) or (TestCollisionXwithGear(HHGear, -1) <> 0))  then
   159         begin
   159         begin
   160         PlaySound(sndRopeRelease);
   160         PlaySound(sndRopeRelease);
   161         RopeDeleteMe(Gear, HHGear);
   161         RopeDeleteMe(Gear, HHGear);
   162         HHGear^.X:= tX;
   162         HHGear^.X:= tX;
   163         HHGear^.dX.isNegative:= hwRound(tX) > LongInt(leftX) + HHGear^.Radius * 2;
   163         HHGear^.dX.isNegative:= hwRound(tX) > leftX + HHGear^.Radius * 2;
   164         exit
   164         exit
   165         end;
   165         end;
   166 
   166 
   167     tX:= HHGear^.X;
   167     tX:= HHGear^.X;
   168     HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shl 2;
   168     HHGear^.dX.QWordValue:= HHGear^.dX.QWordValue shl 2;
   212     tx := HHGear^.X;
   212     tx := HHGear^.X;
   213     ty := HHGear^.Y;
   213     ty := HHGear^.Y;
   214 
   214 
   215     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
   215     if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
   216         if not ((TestCollisionXwithXYShift(HHGear, _2*hwSign(ropeDx), 0, hwSign(ropeDx), true) <> 0)
   216         if not ((TestCollisionXwithXYShift(HHGear, _2*hwSign(ropeDx), 0, hwSign(ropeDx), true) <> 0)
   217         or ((ropeDy.QWordValue <> 0) and (TestCollisionYwithXYShift(HHGear, 0, 1*hwSign(ropeDy), hwSign(ropeDy)) <> 0))) then
   217         or ((ropeDy.QWordValue <> 0) and (TestCollisionYwithXYShift(HHGear, 0, hwSign(ropeDy), hwSign(ropeDy)) <> 0))) then
   218             Gear^.Elasticity := Gear^.Elasticity + _1_2;
   218             Gear^.Elasticity := Gear^.Elasticity + _1_2;
   219 
   219 
   220     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
   220     if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
   221         if not ((TestCollisionXwithXYShift(HHGear, -_2*hwSign(ropeDx), 0, -hwSign(ropeDx), true) <> 0)
   221         if not ((TestCollisionXwithXYShift(HHGear, -_2*hwSign(ropeDx), 0, -hwSign(ropeDx), true) <> 0)
   222         or ((ropeDy.QWordValue <> 0) and (TestCollisionYwithXYShift(HHGear, 0, 1*-hwSign(ropeDy), -hwSign(ropeDy)) <> 0))) then
   222         or ((ropeDy.QWordValue <> 0) and (TestCollisionYwithXYShift(HHGear, 0, -hwSign(ropeDy), -hwSign(ropeDy)) <> 0))) then
   223             Gear^.Elasticity := Gear^.Elasticity - _1_2;
   223             Gear^.Elasticity := Gear^.Elasticity - _1_2;
   224 
   224 
   225     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
   225     HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
   226     HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity;
   226     HHGear^.Y := Gear^.Y + mdY * Gear^.Elasticity;
   227 
   227 
   228     HHGear^.dX := HHGear^.X - tx;
   228     HHGear^.dX := HHGear^.X - tx;
   229     HHGear^.dY := HHGear^.Y - ty;
   229     HHGear^.dY := HHGear^.Y - ty;
   230     ////
       
   231 
       
   232 
   230 
   233     haveDivided := false;
   231     haveDivided := false;
   234     // check whether rope needs dividing
   232     // check whether rope needs dividing
   235 
   233 
   236     len := Gear^.Elasticity - _5;
   234     len := Gear^.Elasticity - _5;
   417 procedure RopeRemoveFromAmmo(Gear, HHGear: PGear);
   415 procedure RopeRemoveFromAmmo(Gear, HHGear: PGear);
   418 begin
   416 begin
   419     if (Gear^.State and gstAttacked) = 0 then
   417     if (Gear^.State and gstAttacked) = 0 then
   420         begin
   418         begin
   421         OnUsedAmmo(HHGear^.Hedgehog^);
   419         OnUsedAmmo(HHGear^.Hedgehog^);
   422         Gear^.State := Gear^.State or gstAttacked
   420         Gear^.State := Gear^.State or gstAttacked;
   423         end;
   421         ApplyAmmoChanges(HHGear^.Hedgehog^);
   424     ApplyAmmoChanges(HHGear^.Hedgehog^)
   422         end;
   425 end;
   423 end;
   426 
   424 
   427 procedure doStepRopeAttach(Gear: PGear);
   425 procedure doStepRopeAttach(Gear: PGear);
   428 var
   426 var
   429     HHGear: PGear;
   427     HHGear: PGear;
   430     tx, ty, tt: hwFloat;
   428     tx, ty, tt: hwFloat;
   431 begin
   429 begin
   432     
       
   433     Gear^.X := Gear^.X - Gear^.dX;
   430     Gear^.X := Gear^.X - Gear^.dX;
   434     Gear^.Y := Gear^.Y - Gear^.dY;
   431     Gear^.Y := Gear^.Y - Gear^.dY;
   435     Gear^.Elasticity := Gear^.Elasticity + _1;
   432     Gear^.Elasticity := Gear^.Elasticity + _1;
   436 
   433 
   437     HHGear := Gear^.Hedgehog^.Gear;
   434     HHGear := Gear^.Hedgehog^.Gear;
   449        ((WorldEdge = weBounce) and ((hwRound(Gear^.X) <= LeftX) or (hwRound(Gear^.X) >= RightX))) then
   446        ((WorldEdge = weBounce) and ((hwRound(Gear^.X) <= LeftX) or (hwRound(Gear^.X) >= RightX))) then
   450         begin
   447         begin
   451         HHGear^.State := HHGear^.State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   448         HHGear^.State := HHGear^.State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   452         HHGear^.Message := HHGear^.Message and (not gmAttack);
   449         HHGear^.Message := HHGear^.Message and (not gmAttack);
   453         DeleteGear(Gear);
   450         DeleteGear(Gear);
   454         if (GetAmmoEntry(HHGear^.Hedgehog^, amRope)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   451         if (GetAmmoEntry(HHGear^.Hedgehog^, amRope)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) and (HHGear^.Hedgehog^.MultiShootAttacks = 0) then
   455             HHGear^.Hedgehog^.CurAmmoType:= amRope;
   452             HHGear^.Hedgehog^.CurAmmoType:= amRope;
   456         isCursorVisible := false;
   453         isCursorVisible := false;
   457         ApplyAmmoChanges(HHGear^.Hedgehog^);
   454         ApplyAmmoChanges(HHGear^.Hedgehog^);
   458         exit()
   455         exit()
   459         end;
   456         end;
   464         begin
   461         begin
   465         doStepHedgehogMoving(HHGear);
   462         doStepHedgehogMoving(HHGear);
   466         Gear^.X := Gear^.X + HHGear^.dX;
   463         Gear^.X := Gear^.X + HHGear^.dX;
   467         Gear^.Y := Gear^.Y + HHGear^.dY;
   464         Gear^.Y := Gear^.Y + HHGear^.dY;
   468 
   465 
       
   466         // hedgehog can teleport up to 5 pixels upwards when sliding,
       
   467         // so we have to give up the maintained rope length
       
   468         // after doStepHedgehogMoving() call and recalculate
       
   469         // it based on the gear and current hedgehog positions
       
   470         Gear^.Elasticity:= int2hwFloat(hwRound(Distance(Gear^.X - HHGear^.X, Gear^.Y - HHGear^.Y) + _0_001));
   469 
   471 
   470         tt := Gear^.Elasticity;
   472         tt := Gear^.Elasticity;
   471         tx := _0;
   473         tx := _0;
   472         ty := _0;
   474         ty := _0;
   473         while tt > _20 do
   475         while tt > _20 do
   476                 begin
   478                 begin
   477                 Gear^.X := Gear^.X + tx;
   479                 Gear^.X := Gear^.X + tx;
   478                 Gear^.Y := Gear^.Y + ty;
   480                 Gear^.Y := Gear^.Y + ty;
   479                 Gear^.Elasticity := tt;
   481                 Gear^.Elasticity := tt;
   480                 Gear^.doStep := @doStepRopeWork;
   482                 Gear^.doStep := @doStepRopeWork;
       
   483 
   481                 PlaySound(sndRopeAttach);
   484                 PlaySound(sndRopeAttach);
   482                 with HHGear^ do
   485                 with HHGear^ do
   483                     begin
   486                     begin
   484                     State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   487                     State := State and (not (gstAttacking or gstHHJumping or gstHHHJump));
   485                     Message := Message and (not gmAttack)
   488                     Message := Message and (not gmAttack)
   486                     end;
   489                     end;
   487 
   490 
   488                 RopeRemoveFromAmmo(Gear, HHGear);
   491                 RopeRemoveFromAmmo(Gear, HHGear);
   489 
       
   490                 tt := _0;
       
   491                 exit
   492                 exit
   492                 end;
   493                 end;
   493             tx := tx + Gear^.dX + Gear^.dX;
   494             tx := tx + Gear^.dX + Gear^.dX;
   494             ty := ty + Gear^.dY + Gear^.dY;
   495             ty := ty + Gear^.dY + Gear^.dY;
   495             tt := tt - _2;
   496             tt := tt - _2;
   496             end;
   497             end;
   497         end;
   498         end;
   498 
   499 
   499     if Gear^.Elasticity < _20 then Gear^.CollisionMask:= lfLandMask
   500     if Gear^.Elasticity < _20 then Gear^.CollisionMask:= lfLandMask
   500     else Gear^.CollisionMask:= lfNotCurrentMask; //lfNotObjMask or lfNotHHObjMask;
   501     else Gear^.CollisionMask:= lfNotCurHogCrate; //lfNotObjMask or lfNotHHObjMask;
   501     CheckCollision(Gear);
   502     CheckCollision(Gear);
   502 
   503 
   503     if (Gear^.State and gstCollision) <> 0 then
   504     if (Gear^.State and gstCollision) <> 0 then
   504         if Gear^.Elasticity < _10 then
   505         if Gear^.Elasticity < _10 then
   505             Gear^.Elasticity := _10000
   506             Gear^.Elasticity := _10000
   527                 begin
   528                 begin
   528                 State := State and (not gstAttacking);
   529                 State := State and (not gstAttacking);
   529                 Message := Message and (not gmAttack)
   530                 Message := Message and (not gmAttack)
   530                 end;
   531                 end;
   531         DeleteGear(Gear);
   532         DeleteGear(Gear);
   532         if (GetAmmoEntry(HHGear^.Hedgehog^, amRope)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
   533         if (GetAmmoEntry(HHGear^.Hedgehog^, amRope)^.Count >= 1) and ((Ammoz[HHGear^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) and (HHGear^.Hedgehog^.MultiShootAttacks = 0) then
   533             HHGear^.Hedgehog^.CurAmmoType:= amRope;
   534             HHGear^.Hedgehog^.CurAmmoType:= amRope;
   534         isCursorVisible := false;
   535         isCursorVisible := false;
   535         ApplyAmmoChanges(HHGear^.Hedgehog^);
   536         ApplyAmmoChanges(HHGear^.Hedgehog^);
   536         exit;
   537         exit;
   537         end;
   538         end;