3729 end; |
3729 end; |
3730 |
3730 |
3731 procedure doStepPortal(Gear: PGear); |
3731 procedure doStepPortal(Gear: PGear); |
3732 var |
3732 var |
3733 iterator, conPortal: PGear; |
3733 iterator, conPortal: PGear; |
3734 s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed: hwFloat; |
3734 s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed, |
3735 o_x,o_y,r_x,r_y,rr_x,rr_y: LongInt; |
3735 resetx, resety, resetdx, resetdy: hwFloat; |
3736 hasdxy, isbullet, iscake: Boolean; |
3736 sx, sy, rh, resetr: LongInt; |
|
3737 hasdxy, isbullet, iscake, isCollision: Boolean; |
3737 begin |
3738 begin |
3738 doPortalColorSwitch(); |
3739 doPortalColorSwitch(); |
3739 |
3740 |
3740 // destroy portal if ground it was attached too is gone |
3741 // destroy portal if ground it was attached too is gone |
3741 if ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) = 0) |
3742 if ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) = 0) |
3801 if (iterator^.X < Gear^.X - r) |
3802 if (iterator^.X < Gear^.X - r) |
3802 or (iterator^.X > Gear^.X + r) |
3803 or (iterator^.X > Gear^.X + r) |
3803 or (iterator^.Y < Gear^.Y - r) |
3804 or (iterator^.Y < Gear^.Y - r) |
3804 or (iterator^.Y > Gear^.Y + r) then |
3805 or (iterator^.Y > Gear^.Y + r) then |
3805 continue; |
3806 continue; |
3806 (* |
|
3807 Square check causes fail on many innocent cases. the 3/4s and 1.5 fudge factors... help. |
|
3808 Might still need to remove this section |
|
3809 *) |
|
3810 //Will if fit through? |
|
3811 //set r to be portal distance |
|
3812 r := Int2hwFloat(Gear^.Radius * 3 div 4); |
|
3813 o_x := hwRound(conPortal^.X + (conPortal^.dX*_1_5)); |
|
3814 o_y := hwRound(conPortal^.Y + (conPortal^.dY*_1_5)); |
|
3815 //r := Int2hwFloat(Gear^.Radius +1); |
|
3816 |
|
3817 //o_x := hwRound(conPortal^.X + conPortal^.dX); |
|
3818 //o_y := hwRound(conPortal^.Y + conPortal^.dY); |
|
3819 r_x := hwRound(conPortal^.X+r*conPortal^.dX); |
|
3820 r_y := hwRound(conPortal^.Y+r*conPortal^.dY); |
|
3821 rr_x := hwRound(conPortal^.X+r*conPortal^.dX*2); |
|
3822 rr_y := hwRound(conPortal^.Y+r*conPortal^.dY*2); |
|
3823 |
|
3824 //check outer edge |
|
3825 if (((rr_y and LAND_HEIGHT_MASK) <> 0) or ((rr_x and LAND_WIDTH_MASK) <> 0)) then |
|
3826 begin |
|
3827 if hasBorder then continue; |
|
3828 end |
|
3829 else |
|
3830 if ((Land[rr_y,rr_x] and $FF00) <> 0) then |
|
3831 continue; |
|
3832 //check middle bound |
|
3833 if (((r_y and LAND_HEIGHT_MASK) <> 0) or ((r_x and LAND_WIDTH_MASK) <> 0)) then |
|
3834 begin |
|
3835 if hasBorder then continue; |
|
3836 end |
|
3837 else |
|
3838 if ((Land[r_y, r_x] and $FF00) <> 0) then |
|
3839 continue; |
|
3840 //check inner bound |
|
3841 if (((o_y and LAND_HEIGHT_MASK) <> 0) or ((o_x and LAND_WIDTH_MASK) <> 0)) then |
|
3842 begin |
|
3843 if hasBorder then continue; |
|
3844 end |
|
3845 else |
|
3846 if ((Land[o_y, o_x] and $FF00) <> 0) then |
|
3847 continue; |
|
3848 //check left bound |
|
3849 if (((rr_y and LAND_HEIGHT_MASK) <> 0) or ((o_x and LAND_WIDTH_MASK) <> 0)) then |
|
3850 begin |
|
3851 if hasBorder then continue; |
|
3852 end |
|
3853 else |
|
3854 if ((Land[rr_y, o_x] and $FF00) <> 0) then |
|
3855 continue; |
|
3856 //Check Right Bound |
|
3857 if (((o_y and LAND_HEIGHT_MASK) <> 0) or ((rr_x and LAND_WIDTH_MASK) <> 0)) then |
|
3858 begin |
|
3859 if hasBorder then continue; |
|
3860 end |
|
3861 else |
|
3862 if ((Land[o_y, rr_x] and $FF00) <> 0) then |
|
3863 continue; |
|
3864 |
|
3865 //Okay reset r in case something uses it |
|
3866 r := Int2hwFloat(iterator^.Radius+Gear^.Radius); |
|
3867 |
3807 |
3868 hasdxy := (((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)) |
3808 hasdxy := (((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)) |
3869 or ((iterator^.State or gstMoving) = 0)); |
3809 or ((iterator^.State or gstMoving) = 0)); |
3870 |
3810 |
3871 // in case the object is not moving, let's asume it's falling towards the portal |
3811 // in case the object is not moving, let's asume it's falling towards the portal |
3927 continue; |
3867 continue; |
3928 |
3868 |
3929 // |
3869 // |
3930 // gears that make it till here will definately be ported |
3870 // gears that make it till here will definately be ported |
3931 // |
3871 // |
|
3872 // (but old position/movement vector might be restored in case there's |
|
3873 // not enough space on the other side) |
|
3874 // |
|
3875 |
|
3876 resetr := iterator^.Radius; |
|
3877 resetx := iterator^.X; |
|
3878 resety := iterator^.Y; |
|
3879 resetdx := iterator^.dX; |
|
3880 resetdy := iterator^.dY; |
3932 |
3881 |
3933 // create a normal of the portal vector, but ... |
3882 // create a normal of the portal vector, but ... |
3934 nx := Gear^.dY; |
3883 nx := Gear^.dY; |
3935 ny := Gear^.dX; |
3884 ny := Gear^.dX; |
3936 // ... decide where the top is based on the hog's direction when firing the portal |
3885 // ... decide where the top is based on the hog's direction when firing the portal |
3946 if not iscake and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative) |
3895 if not iscake and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative) |
3947 and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) |
3896 and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) |
3948 and (iterator^.PortalCounter > 0) then |
3897 and (iterator^.PortalCounter > 0) then |
3949 continue; |
3898 continue; |
3950 |
3899 |
3951 // Until loops are reliably broken |
|
3952 inc(iterator^.PortalCounter); |
|
3953 |
|
3954 // calc gear speed along to the vector and the normal vector of the portal |
3900 // calc gear speed along to the vector and the normal vector of the portal |
3955 if hasdxy then |
3901 if hasdxy then |
3956 begin |
3902 begin |
3957 pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY); |
3903 pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY); |
3958 nspeed:= (nx * iterator^.dX + ny * iterator^.dY); |
3904 nspeed:= (nx * iterator^.dX + ny * iterator^.dY); |
4008 if not hasdxy and not (conPortal^.dY.isNegative) then |
3954 if not hasdxy and not (conPortal^.dY.isNegative) then |
4009 begin |
3955 begin |
4010 iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y)) |
3956 iterator^.dY:= iterator^.dY + hwAbs(cGravity * (iterator^.Y - conPortal^.Y)) |
4011 end; |
3957 end; |
4012 |
3958 |
|
3959 // see if the space on the exit side actually is enough |
|
3960 |
|
3961 if not (isBullet or isCake) then |
|
3962 begin |
|
3963 // TestCollisionXwithXYShift requires a hwFloat for xShift |
|
3964 ox.QWordValue := _1.QWordValue; |
|
3965 ox.isNegative := not iterator^.dX.isNegative; |
|
3966 |
|
3967 sx := hwSign(iterator^.dX); |
|
3968 sy := hwSign(iterator^.dY); |
|
3969 |
|
3970 if iterator^.Radius > 1 then |
|
3971 iterator^.Radius := iterator^.Radius - 1; |
|
3972 |
|
3973 // check front |
|
3974 isCollision := TestCollisionYwithGear(iterator, sy) |
|
3975 or TestCollisionXwithGear(iterator, sx); |
|
3976 |
|
3977 if not isCollision then |
|
3978 begin |
|
3979 // check center area (with half the radius so that the |
|
3980 // the square check won't check more pixels than we want to) |
|
3981 iterator^.Radius := 1 + resetr div 2; |
|
3982 rh := resetr div 4; |
|
3983 isCollision := TestCollisionYwithXYShift(iterator, 0, -sy * rh, sy) |
|
3984 or TestCollisionXwithXYShift(iterator, ox * rh, 0, sx); |
|
3985 end; |
|
3986 |
|
3987 iterator^.Radius := resetr; |
|
3988 |
|
3989 if isCollision then |
|
3990 begin |
|
3991 // collision! oh crap! go back! |
|
3992 iterator^.X := resetx; |
|
3993 iterator^.Y := resety; |
|
3994 iterator^.dX := resetdx; |
|
3995 iterator^.dY := resetdy; |
|
3996 continue; |
|
3997 end; |
|
3998 end; |
|
3999 |
|
4000 // |
|
4001 // You're now officially portaled! |
|
4002 // |
|
4003 |
|
4004 // Until loops are reliably broken |
|
4005 inc(iterator^.PortalCounter); |
|
4006 |
4013 if not isbullet and (iterator^.Kind <> gtFlake) then |
4007 if not isbullet and (iterator^.Kind <> gtFlake) then |
4014 FollowGear := iterator; |
4008 FollowGear := iterator; |
4015 //AddFileLog('portal''d'); |
4009 |
4016 |
|
4017 { |
|
4018 s := _0_2 + _0_008 * Gear^.Health; |
|
4019 iterator^.dX := s * iterator^.dX; |
|
4020 iterator^.dY := s * iterator^.dY; |
|
4021 } |
|
4022 // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. |
4010 // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. |
4023 iterator:= GearsList; |
4011 iterator:= GearsList; |
4024 while iterator <> nil do |
4012 while iterator <> nil do |
4025 begin |
4013 begin |
4026 if iterator^.Kind <> gtPortal then |
4014 if iterator^.Kind <> gtPortal then |
4033 end; |
4021 end; |
4034 iterator:= iterator^.NextGear |
4022 iterator:= iterator^.NextGear |
4035 end; |
4023 end; |
4036 |
4024 |
4037 if Gear^.Health > 1 then dec(Gear^.Health); |
4025 if Gear^.Health > 1 then dec(Gear^.Health); |
4038 |
|
4039 { // breaks (some) loops |
|
4040 if Distance(iterator^.dX, iterator^.dY) > _0_96 then |
|
4041 begin |
|
4042 iterator^.dX := iterator^.dX + signAs(cGravity * getRandom(1000),iterator^.dX); |
|
4043 iterator^.dY := iterator^.dY + signAs(cGravity * getRandom(1000),iterator^.dY); |
|
4044 s := _0_96 / Distance(iterator^.dX, iterator^.dY); |
|
4045 iterator^.dX := s * iterator^.dX; |
|
4046 iterator^.dY := s * iterator^.dX; |
|
4047 end; |
|
4048 } |
|
4049 end; |
4026 end; |
4050 end; |
4027 end; |
4051 |
4028 |
4052 procedure doStepMovingPortal_real(Gear: PGear); |
4029 procedure doStepMovingPortal_real(Gear: PGear); |
4053 var |
4030 var |