613 //////////////////////////////////////////////////////////////////////////////// |
613 //////////////////////////////////////////////////////////////////////////////// |
614 |
614 |
615 procedure doStepRopeWork(Gear: PGear); |
615 procedure doStepRopeWork(Gear: PGear); |
616 const flCheck: boolean = false; |
616 const flCheck: boolean = false; |
617 var HHGear: PGear; |
617 var HHGear: PGear; |
618 len, cs, cc, tx, ty, nx, ny: hwFloat; |
618 len, cs, cc, tx, ty, nx, ny: hwFloat; |
619 lx, ly: LongInt; |
619 lx, ly: LongInt; |
620 |
620 |
621 procedure DeleteMe; |
621 procedure DeleteMe; |
622 begin |
622 begin |
623 with HHGear^ do |
623 with HHGear^ do |
624 begin |
624 begin |
625 Message:= Message and not gm_Attack; |
625 Message:= Message and not gm_Attack; |
626 State:= State or gstMoving; |
626 State:= State or gstMoving; |
627 end; |
627 end; |
628 DeleteGear(Gear) |
628 DeleteGear(Gear) |
629 end; |
629 end; |
630 |
630 |
631 begin |
631 begin |
632 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
632 HHGear:= PHedgehog(Gear^.Hedgehog)^.Gear; |
633 |
633 |
634 if ((HHGear^.State and gstHHDriven) = 0) |
634 if ((HHGear^.State and gstHHDriven) = 0) |
635 or (CheckGearDrowning(HHGear)) then |
635 or (CheckGearDrowning(HHGear)) then |
636 begin |
636 begin |
637 DeleteMe; |
637 DeleteMe; |
638 exit |
638 exit |
639 end; |
639 end; |
640 |
640 |
641 Gear^.dX:= HHGear^.X - Gear^.X; |
641 Gear^.dX:= HHGear^.X - Gear^.X; |
642 Gear^.dY:= HHGear^.Y - Gear^.Y; |
642 Gear^.dY:= HHGear^.Y - Gear^.Y; |
643 |
643 |
644 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else |
644 if (Gear^.Message and gm_Left <> 0) then HHGear^.dX:= HHGear^.dX - _0_0002 else |
655 nx:= SignAs(cs, HHGear^.dX) * 7; // hedgehog direction normalized with length 7 |
655 nx:= SignAs(cs, HHGear^.dX) * 7; // hedgehog direction normalized with length 7 |
656 ny:= SignAs(cc, HHGear^.dY) * 7; |
656 ny:= SignAs(cc, HHGear^.dY) * 7; |
657 |
657 |
658 flCheck:= not flCheck; |
658 flCheck:= not flCheck; |
659 if flCheck then // check whether rope needs dividing |
659 if flCheck then // check whether rope needs dividing |
660 begin |
660 begin |
661 len:= Gear^.Elasticity - _20; |
661 len:= Gear^.Elasticity - _20; |
662 while len > _5 do |
662 while len > _5 do |
663 begin |
663 begin |
664 tx:= cc*len; |
664 tx:= cc*len; |
665 ty:= cs*len; |
665 ty:= cs*len; |
666 lx:= hwRound(Gear^.X + tx + nx); |
666 lx:= hwRound(Gear^.X + tx + nx); |
667 ly:= hwRound(Gear^.Y + ty + ny); |
667 ly:= hwRound(Gear^.Y + ty + ny); |
668 if ((ly and $FFFFFC00) = 0) and ((lx and $FFFFF800) = 0) and (Land[ly, lx] <> 0) then |
668 if ((ly and $FFFFFC00) = 0) and ((lx and $FFFFF800) = 0) and (Land[ly, lx] <> 0) then |
669 begin |
669 begin |
670 with RopePoints.ar[RopePoints.Count] do |
670 with RopePoints.ar[RopePoints.Count] do |
671 begin |
671 begin |
672 X:= Gear^.X; |
672 X:= Gear^.X; |
673 Y:= Gear^.Y; |
673 Y:= Gear^.Y; |
674 if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX); |
674 if RopePoints.Count = 0 then RopePoints.HookAngle:= DxDy2Angle(Gear^.dY, Gear^.dX); |
675 b:= (cc * HHGear^.dY) > (cs * HHGear^.dX); |
675 b:= (cc * HHGear^.dY) > (cs * HHGear^.dX); |
676 dLen:= len |
676 dLen:= len |
677 end; |
677 end; |
678 Gear^.X:= Gear^.X + tx; |
678 Gear^.X:= Gear^.X + tx; |
679 Gear^.Y:= Gear^.Y + ty; |
679 Gear^.Y:= Gear^.Y + ty; |
680 inc(RopePoints.Count); |
680 inc(RopePoints.Count); |
681 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); |
681 TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true); |
682 Gear^.Elasticity:= Gear^.Elasticity - len; |
682 Gear^.Elasticity:= Gear^.Elasticity - len; |
683 Gear^.Friction:= Gear^.Friction - len; |
683 Gear^.Friction:= Gear^.Friction - len; |
684 break |
684 break |
685 end; |
685 end; |
686 len:= len - _0_5 |
686 len:= len - _0_5 |
687 end; |
687 end; |
688 end else |
688 end else |
689 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
689 if RopePoints.Count > 0 then // check whether the last dividing point could be removed |
690 begin |
690 begin |
691 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
691 tx:= RopePoints.ar[Pred(RopePoints.Count)].X; |
692 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
692 ty:= RopePoints.ar[Pred(RopePoints.Count)].Y; |
693 if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then |
693 if RopePoints.ar[Pred(RopePoints.Count)].b xor ((tx - Gear^.X) * (ty - HHGear^.Y) > (tx - HHGear^.X) * (ty - Gear^.Y)) then |
694 begin |
694 begin |
695 dec(RopePoints.Count); |
695 dec(RopePoints.Count); |
696 Gear^.X:=RopePoints.ar[RopePoints.Count].X; |
696 Gear^.X:=RopePoints.ar[RopePoints.Count].X; |
697 Gear^.Y:=RopePoints.ar[RopePoints.Count].Y; |
697 Gear^.Y:=RopePoints.ar[RopePoints.Count].Y; |
698 Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
698 Gear^.Elasticity:= Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen; |
699 Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen |
699 Gear^.Friction:= Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen |
700 end |
700 end |
701 end; |
701 end; |
702 |
702 |
703 Gear^.dX:= HHGear^.X - Gear^.X; |
703 Gear^.dX:= HHGear^.X - Gear^.X; |
704 Gear^.dY:= HHGear^.Y - Gear^.Y; |
704 Gear^.dY:= HHGear^.Y - Gear^.Y; |
705 |
705 |
706 cs:= Gear^.dY + HHGear^.dY; |
706 cs:= Gear^.dY + HHGear^.dY; |
711 |
711 |
712 HHGear^.dX:= HHGear^.X; |
712 HHGear^.dX:= HHGear^.X; |
713 HHGear^.dY:= HHGear^.Y; |
713 HHGear^.dY:= HHGear^.Y; |
714 |
714 |
715 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
715 if ((Gear^.Message and gm_Down) <> 0) and (Gear^.Elasticity < Gear^.Friction) then |
716 if not (TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
716 if not (TestCollisionXwithGear(HHGear, hwSign(Gear^.dX)) |
717 or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity + _0_3; |
717 or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity + _0_3; |
718 |
718 |
719 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then |
719 if ((Gear^.Message and gm_Up) <> 0) and (Gear^.Elasticity > _30) then |
720 if not (TestCollisionXwithGear(HHGear, -hwSign(Gear^.dX)) |
720 if not (TestCollisionXwithGear(HHGear, -hwSign(Gear^.dX)) |
721 or TestCollisionYwithGear(HHGear, -hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity - _0_3; |
721 or TestCollisionYwithGear(HHGear, -hwSign(Gear^.dY))) then Gear^.Elasticity:= Gear^.Elasticity - _0_3; |
722 |
722 |
723 HHGear^.X:= Gear^.X + cc*Gear^.Elasticity; |
723 HHGear^.X:= Gear^.X + cc*Gear^.Elasticity; |
724 HHGear^.Y:= Gear^.Y + cs*Gear^.Elasticity; |
724 HHGear^.Y:= Gear^.Y + cs*Gear^.Elasticity; |
725 |
725 |
726 HHGear^.dX:= HHGear^.X - HHGear^.dX; |
726 HHGear^.dX:= HHGear^.X - HHGear^.dX; |
727 HHGear^.dY:= HHGear^.Y - HHGear^.dY; |
727 HHGear^.dY:= HHGear^.Y - HHGear^.dY; |
728 |
728 |
729 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
729 if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then |
730 HHGear^.dX:= -_0_6 * HHGear^.dX; |
730 HHGear^.dX:= -_0_6 * HHGear^.dX; |
731 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
731 if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then |
732 HHGear^.dY:= -_0_6 * HHGear^.dY; |
732 HHGear^.dY:= -_0_6 * HHGear^.dY; |
733 |
733 |
734 len:= Distance(HHGear^.dX, HHGear^.dY); |
734 len:= Distance(HHGear^.dX, HHGear^.dY); |
735 if len > _0_8 then |
735 if len > _0_8 then |
736 begin |
736 begin |
737 len:= _0_8 / len; |
737 len:= _0_8 / len; |
738 HHGear^.dX:= HHGear^.dX * len; |
738 HHGear^.dX:= HHGear^.dX * len; |
739 HHGear^.dY:= HHGear^.dY * len; |
739 HHGear^.dY:= HHGear^.dY * len; |
740 end; |
740 end; |
741 |
741 |
742 if (Gear^.Message and gm_Attack) <> 0 then |
742 if (Gear^.Message and gm_Attack) <> 0 then |
743 if (Gear^.State and gsttmpFlag) <> 0 then DeleteMe else |
743 if (Gear^.State and gsttmpFlag) <> 0 then |
744 else if (Gear^.State and gsttmpFlag) = 0 then Gear^.State:= Gear^.State or gsttmpFlag; |
744 DeleteMe |
|
745 else |
|
746 else |
|
747 if (Gear^.State and gsttmpFlag) = 0 then |
|
748 Gear^.State:= Gear^.State or gsttmpFlag; |
745 end; |
749 end; |
746 |
750 |
747 |
751 |
748 procedure doStepRopeAttach(Gear: PGear); |
752 procedure doStepRopeAttach(Gear: PGear); |
749 var HHGear: PGear; |
753 var HHGear: PGear; |