957 then |
957 then |
958 Gear^.doStep := @doStepShotIdle |
958 Gear^.doStep := @doStepShotIdle |
959 end; |
959 end; |
960 |
960 |
961 //////////////////////////////////////////////////////////////////////////////// |
961 //////////////////////////////////////////////////////////////////////////////// |
|
962 procedure spawnBulletTrail(Bullet: PGear); |
|
963 var oX, oY: hwFloat; |
|
964 VGear: PVisualGear; |
|
965 begin |
|
966 if Bullet^.PortalCounter = 0 then |
|
967 begin |
|
968 ox:= CurrentHedgehog^.Gear^.X + Int2hwFloat(GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle)); |
|
969 oy:= CurrentHedgehog^.Gear^.Y + Int2hwFloat(GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle)); |
|
970 end |
|
971 else |
|
972 begin |
|
973 ox:= Bullet^.Elasticity; |
|
974 oy:= Bullet^.Friction; |
|
975 end; |
|
976 |
|
977 // Bullet trail |
|
978 VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail); |
|
979 if VGear <> nil then |
|
980 begin |
|
981 VGear^.X:= hwFloat2Float(ox); |
|
982 VGear^.Y:= hwFloat2Float(oy); |
|
983 VGear^.dX:= hwFloat2Float(Bullet^.X); |
|
984 VGear^.dY:= hwFloat2Float(Bullet^.Y); |
|
985 |
|
986 // reached edge of land. assume infinite beam. Extend it way out past camera |
|
987 if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0) |
|
988 or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then |
|
989 // only extend if not under water |
|
990 if hwRound(Bullet^.Y) < cWaterLine then |
|
991 begin |
|
992 VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X); |
|
993 VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y); |
|
994 end; |
|
995 |
|
996 VGear^.Timer := 200; |
|
997 end; |
|
998 end; |
|
999 |
962 procedure doStepBulletWork(Gear: PGear); |
1000 procedure doStepBulletWork(Gear: PGear); |
963 var |
1001 var |
964 i, x, y: LongWord; |
1002 i, x, y: LongWord; |
965 oX, oY: hwFloat; |
1003 oX, oY: hwFloat; |
966 VGear: PVisualGear; |
1004 VGear: PVisualGear; |
975 Gear^.Y := Gear^.Y + Gear^.dY; |
1013 Gear^.Y := Gear^.Y + Gear^.dY; |
976 x := hwRound(Gear^.X); |
1014 x := hwRound(Gear^.X); |
977 y := hwRound(Gear^.Y); |
1015 y := hwRound(Gear^.Y); |
978 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
1016 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) |
979 and (Land[y, x] <> 0) then inc(Gear^.Damage); |
1017 and (Land[y, x] <> 0) then inc(Gear^.Damage); |
|
1018 // let's interrupt before a collision to give portals a chance to catch the bullet |
|
1019 if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then |
|
1020 begin |
|
1021 Gear^.Tag := 1; |
|
1022 Gear^.Damage := 0; |
|
1023 Gear^.X := Gear^.X - Gear^.dX; |
|
1024 Gear^.Y := Gear^.Y - Gear^.dY; |
|
1025 CheckGearDrowning(Gear); |
|
1026 break; |
|
1027 end |
|
1028 else |
|
1029 Gear^.Tag := 0; |
|
1030 |
980 if Gear^.Damage > 5 then |
1031 if Gear^.Damage > 5 then |
981 if Gear^.AmmoType = amDEagle then |
1032 if Gear^.AmmoType = amDEagle then |
982 AmmoShove(Gear, 7, 20) |
1033 AmmoShove(Gear, 7, 20) |
983 else |
1034 else |
984 AmmoShove(Gear, Gear^.Timer, 20); |
1035 AmmoShove(Gear, Gear^.Timer, 20); |
1020 begin |
1071 begin |
1021 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY); |
1072 VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY); |
1022 end; |
1073 end; |
1023 end; |
1074 end; |
1024 |
1075 |
1025 if Gear^.PortalCounter = 0 then |
1076 spawnBulletTrail(Gear); |
1026 begin |
|
1027 // Bullet trail |
|
1028 VGear := AddVisualGear( |
|
1029 hwround(CurrentHedgehog^.Gear^.X) + GetLaunchX(CurrentHedgehog^.CurAmmoType, hwSign(CurrentHedgehog^.Gear^.dX), CurrentHedgehog^.Gear^.Angle), |
|
1030 hwround(CurrentHedgehog^.Gear^.Y) + GetLaunchY(CurrentHedgehog^.CurAmmoType, CurrentHedgehog^.Gear^.Angle), |
|
1031 vgtLineTrail |
|
1032 ); |
|
1033 if VGear <> nil then |
|
1034 begin |
|
1035 // http://mantis.freepascal.org/view.php?id=17714 hits again |
|
1036 VGear^.dX := Gear^.X.QWordValue / SignAs(_1,_1).QWordValue; |
|
1037 VGear^.dY := Gear^.Y.QWordValue / SignAs(_1,_1).QWordValue; |
|
1038 |
|
1039 if (Gear^.X.isNegative) then VGear^.dX:= -VGear^.dX; |
|
1040 if (Gear^.Y.isNegative) then VGear^.dY:= -VGear^.dY; |
|
1041 |
|
1042 // reached edge of land. assume infinite beam. Extend it way out past camera |
|
1043 if (hwRound(Gear^.X) and LAND_WIDTH_MASK <> 0) |
|
1044 or (hwRound(Gear^.Y) and LAND_HEIGHT_MASK <> 0) then |
|
1045 // only extend if not under water |
|
1046 if hwRound(Gear^.Y) < cWaterLine then |
|
1047 begin |
|
1048 VGear^.dX := VGear^.dX + LAND_WIDTH * (VGear^.dX - VGear^.X); |
|
1049 VGear^.dY := VGear^.dY + LAND_WIDTH * (VGear^.dY - VGear^.Y); |
|
1050 end; |
|
1051 |
|
1052 VGear^.Timer := 200; |
|
1053 end |
|
1054 end; |
|
1055 Gear^.doStep := @doStepShotIdle |
1077 Gear^.doStep := @doStepShotIdle |
1056 end; |
1078 end; |
1057 end; |
1079 end; |
1058 |
1080 |
1059 procedure doStepDEagleShot(Gear: PGear); |
1081 procedure doStepDEagleShot(Gear: PGear); |
3929 |
3951 |
3930 if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then |
3952 if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius + 1 ) then |
3931 continue; |
3953 continue; |
3932 end; |
3954 end; |
3933 |
3955 |
|
3956 // draw bullet trail |
|
3957 if isbullet then |
|
3958 spawnBulletTrail(iterator); |
|
3959 |
3934 // calc gear offset in portal vector direction |
3960 // calc gear offset in portal vector direction |
3935 ox := (iterator^.X - Gear^.X); |
3961 ox := (iterator^.X - Gear^.X); |
3936 oy := (iterator^.Y - Gear^.Y); |
3962 oy := (iterator^.Y - Gear^.Y); |
3937 poffs:= (Gear^.dX * ox + Gear^.dY * oy); |
3963 poffs:= (Gear^.dX * ox + Gear^.dY * oy); |
3938 |
3964 |
3939 if poffs < _0 then |
3965 if not isBullet and poffs.isNegative then |
|
3966 continue; |
|
3967 |
|
3968 // only port bullets close to the portal |
|
3969 if isBullet and not (hwAbs(poffs) < _3) then |
3940 continue; |
3970 continue; |
3941 |
3971 |
3942 // |
3972 // |
3943 // gears that make it till here will definately be ported |
3973 // gears that make it till here will definately be ported |
3944 // |
3974 // |
3962 ny.isNegative := not ny.isNegative; |
3992 ny.isNegative := not ny.isNegative; |
3963 |
3993 |
3964 // calc gear offset in portal normal vector direction |
3994 // calc gear offset in portal normal vector direction |
3965 noffs:= (nx * ox + ny * oy); |
3995 noffs:= (nx * ox + ny * oy); |
3966 |
3996 |
|
3997 if isBullet and (hwRound(hwAbs(noffs)) >= Gear^.Radius) then |
|
3998 continue; |
|
3999 |
3967 // avoid gravity related loops of not really moving gear |
4000 // avoid gravity related loops of not really moving gear |
3968 if not iscake and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative) |
4001 if not (iscake or isbullet) and (Gear^.dY.isNegative) and (conPortal^.dY.isNegative) |
3969 and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) |
4002 and ((iterator^.dX.QWordValue + iterator^.dY.QWordValue) < _0_08.QWordValue) |
3970 and (iterator^.PortalCounter > 0) then |
4003 and (iterator^.PortalCounter > 0) then |
3971 continue; |
4004 continue; |
3972 |
4005 |
3973 // calc gear speed along to the vector and the normal vector of the portal |
4006 // calc gear speed along to the vector and the normal vector of the portal |
4077 if iscake then iterator^.PortalCounter:= 33 |
4110 if iscake then iterator^.PortalCounter:= 33 |
4078 else inc(iterator^.PortalCounter); |
4111 else inc(iterator^.PortalCounter); |
4079 |
4112 |
4080 if not isbullet and (iterator^.Kind <> gtFlake) then |
4113 if not isbullet and (iterator^.Kind <> gtFlake) then |
4081 FollowGear := iterator; |
4114 FollowGear := iterator; |
|
4115 |
|
4116 // store X/Y values of exit for net bullet trail |
|
4117 if isbullet then |
|
4118 begin |
|
4119 iterator^.Elasticity:= iterator^.X; |
|
4120 iterator^.Friction := iterator^.Y; |
|
4121 end; |
4082 |
4122 |
4083 // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. |
4123 // This jiggles gears, to ensure a portal connection just placed under a gear takes effect. |
4084 iterator:= GearsList; |
4124 iterator:= GearsList; |
4085 while iterator <> nil do |
4125 while iterator <> nil do |
4086 begin |
4126 begin |