hedgewars/GSHandlers.inc
changeset 1504 1603a796f42a
parent 1501 a0e56fdf10cd
child 1505 3a96e93572cb
equal deleted inserted replaced
1503:a40b871d506b 1504:1603a796f42a
   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;