hedgewars/GSHandlers.inc
changeset 3974 91ac041ecb20
parent 3971 5c82ee165ed5
child 3985 57121975b64b
equal deleted inserted replaced
3973:0d1a420531ef 3974:91ac041ecb20
  1091 end;
  1091 end;
  1092 
  1092 
  1093 procedure doStepRopeWork(Gear: PGear);
  1093 procedure doStepRopeWork(Gear: PGear);
  1094 var 
  1094 var 
  1095     HHGear: PGear;
  1095     HHGear: PGear;
  1096     len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat;
  1096     len, tx, ty, nx, ny, rDxDy, ropeDx, ropeDy, mdX, mdY: hwFloat;
  1097     lx, ly: LongInt;
  1097     lx, ly: LongInt;
  1098     haveCollision,
  1098     haveCollision,
  1099     haveDivided: boolean;
  1099     haveDivided: boolean;
  1100 
  1100 
  1101 procedure DeleteMe;
  1101 procedure DeleteMe;
  1123 begin
  1123 begin
  1124     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  1124     HHGear := PHedgehog(Gear^.Hedgehog)^.Gear;
  1125 
  1125 
  1126     if ((HHGear^.State and gstHHDriven) = 0)
  1126     if ((HHGear^.State and gstHHDriven) = 0)
  1127        or (CheckGearDrowning(HHGear)) then
  1127        or (CheckGearDrowning(HHGear)) then
  1128     begin
  1128         begin
  1129         PlaySound(sndRopeRelease);
  1129         PlaySound(sndRopeRelease);
  1130         DeleteMe;
  1130         DeleteMe;
  1131         exit
  1131         exit
  1132     end;
  1132         end;
  1133 
  1133 
  1134     if (Gear^.Message and gmLeft  <> 0) then HHGear^.dX := HHGear^.dX - _0_0002
  1134     if (Gear^.Message and gmLeft  <> 0) then HHGear^.dX := HHGear^.dX - _0_0002
  1135     else
  1135     else
  1136         if (Gear^.Message and gmRight <> 0) then HHGear^.dX := HHGear^.dX + _0_0002;
  1136         if (Gear^.Message and gmRight <> 0) then HHGear^.dX := HHGear^.dX + _0_0002;
  1137 
  1137 
  1181     nx := Gear^.X + mdX * len;
  1181     nx := Gear^.X + mdX * len;
  1182     ny := Gear^.Y + mdY * len;
  1182     ny := Gear^.Y + mdY * len;
  1183     tx := mdX * _0_3; // should be the same as increase step
  1183     tx := mdX * _0_3; // should be the same as increase step
  1184     ty := mdY * _0_3;
  1184     ty := mdY * _0_3;
  1185 
  1185 
       
  1186     rDxDy.isNegative:= true;
  1186     while len > _3 do
  1187     while len > _3 do
  1187     begin
  1188         begin
  1188         lx := hwRound(nx);
  1189         lx := hwRound(nx);
  1189         ly := hwRound(ny);
  1190         ly := hwRound(ny);
  1190         if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0
  1191         if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] <> 0) then
  1191            ) then
  1192             begin
  1192         begin
  1193             if rDxDy.isNegative then rDxDy := _1 / Distance(ropeDx, ropeDy);
  1193             ny := _1 / Distance(ropeDx, ropeDy);
       
  1194             // old rope pos
  1194             // old rope pos
  1195             nx := ropeDx * ny;
  1195             nx := ropeDx * rDxDy;
  1196             ny := ropeDy * ny;
  1196             ny := ropeDy * rDxDy;
  1197 
  1197 
  1198             with RopePoints.ar[RopePoints.Count] do
  1198             with RopePoints.ar[RopePoints.Count] do
  1199             begin
  1199                 begin
  1200                 X := Gear^.X;
  1200                 X := Gear^.X;
  1201                 Y := Gear^.Y;
  1201                 Y := Gear^.Y;
  1202                 if RopePoints.Count = 0 then RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX);
  1202                 if RopePoints.Count = 0 then RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX);
  1203                 b := (nx * HHGear^.dY) > (ny * HHGear^.dX);
  1203                 b := (nx * HHGear^.dY) > (ny * HHGear^.dX);
  1204                 dLen := len
  1204                 dLen := len
  1205             end;
  1205                 end;
  1206             with RopePoints.rounded[RopePoints.Count] do
  1206             with RopePoints.rounded[RopePoints.Count] do
  1207             begin
  1207                 begin
  1208                 X := hwRound(Gear^.X);
  1208                 X := hwRound(Gear^.X);
  1209                 Y := hwRound(Gear^.Y);
  1209                 Y := hwRound(Gear^.Y);
  1210             end;
  1210                 end;
  1211 
  1211 
  1212             Gear^.X := Gear^.X + nx * len;
  1212             Gear^.X := Gear^.X + nx * len;
  1213             Gear^.Y := Gear^.Y + ny * len;
  1213             Gear^.Y := Gear^.Y + ny * len;
  1214             inc(RopePoints.Count);
  1214             inc(RopePoints.Count);
  1215             TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true);
  1215             TryDo(RopePoints.Count <= MAXROPEPOINTS, 'Rope points overflow', true);
  1216             Gear^.Elasticity := Gear^.Elasticity - len;
  1216             Gear^.Elasticity := Gear^.Elasticity - len;
  1217             Gear^.Friction := Gear^.Friction - len;
  1217             Gear^.Friction := Gear^.Friction - len;
  1218             haveDivided := true;
  1218             haveDivided := true;
  1219             break
  1219             break
  1220         end;
  1220             end;
  1221         nx := nx - tx;
  1221         nx := nx - tx;
  1222         ny := ny - ty;
  1222         ny := ny - ty;
       
  1223         lx := hwRound(nx);
       
  1224         ly := hwRound(ny);
  1223         // len := len - _0_3 // should be the same as increase step
  1225         // len := len - _0_3 // should be the same as increase step
  1224         len.QWordValue := len.QWordValue - _0_3.QWordValue;
  1226         len.QWordValue := len.QWordValue - _0_3.QWordValue;
  1225     end;
  1227         end;
  1226 
  1228 
  1227     if not haveDivided then
  1229     if not haveDivided then
  1228         if RopePoints.Count > 0 then // check whether the last dividing point could be removed
  1230         if RopePoints.Count > 0 then // check whether the last dividing point could be removed
  1229         begin
  1231             begin
  1230             tx := RopePoints.ar[Pred(RopePoints.Count)].X;
  1232             tx := RopePoints.ar[Pred(RopePoints.Count)].X;
  1231             ty := RopePoints.ar[Pred(RopePoints.Count)].Y;
  1233             ty := RopePoints.ar[Pred(RopePoints.Count)].Y;
  1232             mdX := tx - Gear^.X;
  1234             mdX := tx - Gear^.X;
  1233             mdY := ty - Gear^.Y;
  1235             mdY := ty - Gear^.Y;
  1234             if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X
  1236             if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X) * mdY) then
  1235                ) * mdY) then
  1237                 begin
  1236             begin
       
  1237                 dec(RopePoints.Count);
  1238                 dec(RopePoints.Count);
  1238                 Gear^.X := RopePoints.ar[RopePoints.Count].X;
  1239                 Gear^.X := RopePoints.ar[RopePoints.Count].X;
  1239                 Gear^.Y := RopePoints.ar[RopePoints.Count].Y;
  1240                 Gear^.Y := RopePoints.ar[RopePoints.Count].Y;
  1240                 Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen;
  1241                 Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen;
  1241                 Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen;
  1242                 Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen;
  1245                 mdX := mdX * len;
  1246                 mdX := mdX * len;
  1246                 mdY := mdY * len;
  1247                 mdY := mdY * len;
  1247 
  1248 
  1248                 HHGear^.X := Gear^.X - mdX * Gear^.Elasticity;
  1249                 HHGear^.X := Gear^.X - mdX * Gear^.Elasticity;
  1249                 HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity;
  1250                 HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity;
  1250             end
  1251                 end
  1251         end;
  1252             end;
  1252 
  1253 
  1253     haveCollision := false;
  1254     haveCollision := false;
  1254     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1255     if TestCollisionXwithGear(HHGear, hwSign(HHGear^.dX)) then
  1255     begin
  1256         begin
  1256         HHGear^.dX := -_0_6 * HHGear^.dX;
  1257         HHGear^.dX := -_0_6 * HHGear^.dX;
  1257         haveCollision := true
  1258         haveCollision := true
  1258     end;
  1259         end;
  1259     if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then
  1260     if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) then
  1260     begin
  1261         begin
  1261         HHGear^.dY := -_0_6 * HHGear^.dY;
  1262         HHGear^.dY := -_0_6 * HHGear^.dY;
  1262         haveCollision := true
  1263         haveCollision := true
  1263     end;
  1264         end;
  1264 
  1265 
  1265     if haveCollision
  1266     if haveCollision
  1266        and (Gear^.Message and (gmLeft or gmRight) <> 0)
  1267        and (Gear^.Message and (gmLeft or gmRight) <> 0)
  1267        and (Gear^.Message and (gmUp or gmDown) <> 0) then
  1268        and (Gear^.Message and (gmUp or gmDown) <> 0) then
  1268     begin
  1269         begin
  1269         HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
  1270         HHGear^.dX := SignAs(hwAbs(HHGear^.dX) + _0_2, HHGear^.dX);
  1270         HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
  1271         HHGear^.dY := SignAs(hwAbs(HHGear^.dY) + _0_2, HHGear^.dY)
  1271     end;
  1272         end;
  1272 
  1273 
  1273     len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY);
  1274     len := hwSqr(HHGear^.dX) + hwSqr(HHGear^.dY);
  1274     if len > _0_64 then
  1275     if len > _0_64 then
  1275     begin
  1276         begin
  1276         len := _0_8 / hwSqrt(len);
  1277         len := _0_8 / hwSqrt(len);
  1277         HHGear^.dX := HHGear^.dX * len;
  1278         HHGear^.dX := HHGear^.dX * len;
  1278         HHGear^.dY := HHGear^.dY * len;
  1279         HHGear^.dY := HHGear^.dY * len;
  1279     end;
  1280         end;
  1280 
  1281 
  1281 
  1282 
  1282     if (Gear^.Message and gmAttack) <> 0 then
  1283     if (Gear^.Message and gmAttack) <> 0 then
  1283         if (Gear^.State and gsttmpFlag) <> 0 then
  1284         if (Gear^.State and gsttmpFlag) <> 0 then
  1284             with PHedgehog(Gear^.Hedgehog)^ do
  1285             with PHedgehog(Gear^.Hedgehog)^ do
  1285             begin
  1286                 begin
  1286                 PlaySound(sndRopeRelease);
  1287                 PlaySound(sndRopeRelease);
  1287                 if CurAmmoType <> amParachute then
  1288                 if CurAmmoType <> amParachute then
  1288                     WaitCollision
  1289                     WaitCollision
  1289                 else
  1290                 else
  1290                     DeleteMe
  1291                     DeleteMe
  1291             end
  1292                 end
  1292     else
  1293     else
  1293     else
  1294     else
  1294         if (Gear^.State and gsttmpFlag) = 0 then
  1295         if (Gear^.State and gsttmpFlag) = 0 then
  1295             Gear^.State := Gear^.State or gsttmpFlag;
  1296             Gear^.State := Gear^.State or gsttmpFlag;
  1296 end;
  1297 end;