private async void WorldAddRope(int Ply, int FB, int Veh) { if (PP.Handle != Ply) { List <Vehicle> vehicles = new List <Vehicle>(World.GetAllVehicles()); Vehicle _fb = vehicles.Find(x => x.Handle == FB); Vehicle _veh = vehicles.Find(x => x.Handle == Veh); if (_fb.Position.DistanceTo(PP.Position) <= 50f) { Rope rope = World.AddRope((RopeType)6, _fb.WinchDummyPos(), Vector3.Zero, _fb.WinchDummyPos().DistanceTo(_veh.GetRopeHook()), 0.1f, false); rope.AttachEntities(_fb, _fb.WinchDummyPos(), LV, _veh.GetRopeHook(), _fb.WinchDummyPos().DistanceTo(_veh.GetRopeHook())); rope.ActivatePhysics(); do { rope.StartWinding(); await Delay(5); } while (!(rope.Length <= 1.8f)); rope.StopWinding(); rope.DetachEntity(_fb); rope.DetachEntity(_veh); rope.Delete(); } } }
public void TestDelete(string text, int start, int end) { Rope rope = new Rope(text); rope.Delete(start, end); string beginning = text.Substring(0, start); string temp = text.Substring(start); string other = temp.Substring(end - start); string expected = beginning + other; Assert.Equal(expected, rope.Report()); }
public void Delete() { if (Exists()) { rope.Delete(); } if (isEntity2AMapPosition && Util.IsProp(entity2)) { Util.DeleteEntity(entity2); } Reset(); }
// Tests various functionality of ropes static void RopeTests() { Console.WriteLine(new string('-', 100)); Console.WriteLine("Testing Rope Functionality"); // Constructor for long string Rope rope = new Rope("aaaaabbbbbcccccdddddeeeeefffffggggghhhhhiiiiijjjjjkkkkklllllmmmmmnnnnnooooopppppqqqqqrrrrrssssstttttuuuuuvvvvvwwwwwxxxxxyyyyyzzzzz"); Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // Concatenation normal case Rope rope2 = Rope.Concatenate(new Rope("abcdefghijklmnopqrstuvwxyz"), new Rope("zyxwvutsrqponmlkjihgfedcba")); Console.Write("Rope Value: "); rope2.Print(); Console.WriteLine("Rope Structure: "); rope2.PrintStructure(); Console.WriteLine(new string('-', 100)); // Concatenation 2 small ropes Rope rope3 = Rope.Concatenate(new Rope("12345"), new Rope("54321")); Console.Write("Rope Value: "); rope3.Print(); Console.WriteLine("Rope Structure: "); rope3.PrintStructure(); Console.WriteLine(new string('-', 100)); // Concatenation, rope with small right child + small rope Rope rope4 = Rope.Concatenate(new Rope("123456789012345"), new Rope("abcd")); Console.Write("Rope Value: "); rope4.Print(); Console.WriteLine("Rope Structure: "); rope4.PrintStructure(); Console.WriteLine(new string('-', 100)); Console.Write("Rope Value: "); rope.Print(); // Substring overlapping nodes Console.WriteLine("\nSubstring [23,47]: " + rope.Substring(23, 47)); // substring single node Console.WriteLine("Substring [23,25]: " + rope.Substring(23, 25)); // substring single char Console.WriteLine("Substring [99,99]: " + rope.Substring(99, 99)); // substring index 0 bound Console.WriteLine("Substring [0,32]: " + rope.Substring(0, 32)); // substring max index bound Console.WriteLine("Substring [0,32]: " + rope.Substring(102, 129)); // substring index < 0 Console.WriteLine("Substring [-1,10]: " + (rope.Substring(-1, 10) == null ? "No substring found" : "Substring found")); // substring > max Console.WriteLine("Substring [50,150]: " + (rope.Substring(50, 150) == null ? "No substring found" : "Substring found")); // start index > end index Console.WriteLine("Substring [20,10]: " + (rope.Substring(20, 10) == null ? "No substring found" : "Substring found")); // ChatAt index within range Console.WriteLine("\nChar at index 25: " + rope.CharAt(25)); // ChatAt index 0 Console.WriteLine("Char at index 25: " + rope.CharAt(0)); // ChatAt max index Console.WriteLine("Char at index 25: " + rope.CharAt(129)); // ChatAt index < 0 Console.WriteLine("Char at index 25: " + (rope.CharAt(130) == '\0' ? "No char found" : "char found")); // ChatAt index > max Console.WriteLine("Char at index 25: " + (rope.CharAt(-1) == '\0' ? "No char found" : "char found")); // Find string accross multiple nodes Console.WriteLine("\nFind string \"dddee\" index: " + rope.Find("dddee")); // Find string in single node Console.WriteLine("Find string \"dddee\" index: " + rope.Find("ggghh")); // find string not in rope Console.WriteLine("Find string \"dddee\" index: " + rope.Find("xxxxxx")); // find empty string Console.WriteLine("Find string \"dddee\" index: " + rope.Find("")); // find string exceeding rope capacity Console.WriteLine("Find string \"dddee\" index: " + rope.Find(new string('a', 200))); // Splitting rope at end node Console.WriteLine(new string('-', 100)); Console.WriteLine("Splitting rope at index 69"); Rope rope5 = rope.Split(69); Console.Write("Left Split Rope Value: "); rope.Print(); Console.WriteLine("Left Split Rope Structure: "); rope.PrintStructure(); Console.Write("Right Split Rope Value: "); rope5.Print(); Console.WriteLine("Right Split Rope Structure: "); rope5.PrintStructure(); // splitting rope mid node Console.WriteLine(new string('-', 100)); Console.WriteLine("Splitting rope at index 48"); rope5 = rope.Split(48); Console.Write("Left Split Rope Value: "); rope.Print(); Console.WriteLine("Left Split Rope Structure: "); rope.PrintStructure(); Console.Write("Right Split Rope Value: "); rope5.Print(); Console.WriteLine("Right Split Rope Structure: "); rope5.PrintStructure(); // splitting rope at end of rope Console.WriteLine(new string('-', 100)); Console.WriteLine("Splitting rope at index 48"); rope5 = rope.Split(48); Console.Write("Left Split Rope Value: "); rope.Print(); Console.WriteLine("Left Split Rope Structure: "); rope.PrintStructure(); Console.Write("Right Split Rope Value: "); rope5.Print(); Console.WriteLine("Right Split Rope Structure: "); rope5.PrintStructure(); // splitting rope at start of rope (index - 1) Console.WriteLine(new string('-', 100)); Console.WriteLine("Splitting rope at index -1"); rope5 = rope.Split(-1); Console.Write("Left Split Rope Value: "); rope.Print(); Console.WriteLine("Left Split Rope Structure: "); rope.PrintStructure(); Console.Write("Right Split Rope Value: "); rope5.Print(); Console.WriteLine("Right Split Rope Structure: "); rope5.PrintStructure(); rope = rope5; // splitting rope at index > rope length Console.WriteLine(new string('-', 100)); Console.WriteLine("Splitting rope at index 100"); rope5 = rope.Split(100); Console.Write("Left Split Rope Value: "); rope.Print(); Console.WriteLine("Left Split Rope Structure: "); rope.PrintStructure(); Console.WriteLine("Right Split Rope Value: " + (rope5 == null ? "null" : " not null")); // splitting rope at index < start Console.WriteLine(new string('-', 100)); Console.WriteLine("Splitting rope at index -10"); rope5 = rope.Split(-10); Console.Write("Left Split Rope Value: "); rope.Print(); Console.WriteLine("Left Split Rope Structure: "); rope.PrintStructure(); Console.WriteLine("Right Split Rope Value: " + (rope5 == null ? "null" : " not null")); Console.WriteLine(new string('-', 100)); rope = new Rope("aaaaabbbbbcccccdddddeeeeefffffggggghhhhhiiiiijjjjjkkkkklllllmmmmmnnnnnooooopppppqqqqqrrrrrssssstttttuuuuuvvvvvwwwwwxxxxxyyyyyzzzzz"); Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); // deleting from center of rope crossing multiple nodes Console.WriteLine(new string('-', 100)); if (rope.Delete(30, 65)) { Console.WriteLine("Deleted substring [30,65]"); } else { Console.WriteLine("Failed to delete substring [30,65]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // deleting single character if (rope.Delete(90, 90)) { Console.WriteLine("Deleted substring [90,90]"); } else { Console.WriteLine("Failed to delete substring [90,90]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // deleting from middle of string if (rope.Delete(50, 68)) { Console.WriteLine("Deleted substring [50,68]"); } else { Console.WriteLine("Failed to delete substring [50,68]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // deleting from end of string if (rope.Delete(48, 73)) { Console.WriteLine("Deleted substring [48,73]"); } else { Console.WriteLine("Failed to delete substring [48,73]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // deleting from start of string if (rope.Delete(0, 15)) { Console.WriteLine("Deleted substring [0,15]"); } else { Console.WriteLine("Failed to delete substring [0,15]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // deleting with second bound exceding string size if (rope.Delete(25, 100)) { Console.WriteLine("Deleted substring [25,100]"); } else { Console.WriteLine("Failed to delete substring [25,100]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine(new string('-', 100)); // deleting with first bound exceding string size if (rope.Delete(-10, 10)) { Console.WriteLine("Deleted substring [-10,10]"); } else { Console.WriteLine("Failed to delete substring [-10,10]"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine(new string('-', 100)); // inserting at center of rope if (rope.Insert("ABCDEFGHIJKLMNO", 11)) { Console.WriteLine("Inserted \"ABCDEFGHIJKLMNO\" at index 11"); } else { Console.WriteLine("Failed to insert at index 11"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // inserting samll string inside other string if (rope.Insert("QRS", 28)) { Console.WriteLine("Inserted \"QRS\" at index 28"); } else { Console.WriteLine("Failed to insert at index 28"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // inserting at start of rope if (rope.Insert("TUVW", 0)) { Console.WriteLine("Inserted \"TUVM\" at index 0"); } else { Console.WriteLine("Failed to insert at index 0"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // inserting at end of rope if (rope.Insert("XYZ", 54)) { Console.WriteLine("Inserted \"XYZ\" at index 54"); } else { Console.WriteLine("Failed to insert at index 54"); } Console.Write("Rope Value: "); rope.Print(); Console.WriteLine("Rope Structure: "); rope.PrintStructure(); Console.WriteLine(new string('-', 100)); // inserting before start of rope if (rope.Insert("AAAAA", -10)) { Console.WriteLine("Inserted \"AAAA\" at index -10"); } else { Console.WriteLine("Failed to insert at index -10"); } Console.Write("Rope Value: "); rope.Print(); // inserting after end of rope if (rope.Insert("ZZZZZ", 100)) { Console.WriteLine("Inserted \"ABCDEFGHIJKLMNO\" at index 100"); } else { Console.WriteLine("Failed to insert at index 100"); } Console.Write("Rope Value: "); rope.Print(); /* * Console.WriteLine(rope.CharAt(89)); * Console.WriteLine(rope.Substring(20, 55)); * Console.WriteLine(rope.Find("aaaaabbbbbbb")); * //Rope split = rope.Split(25); * rope.Insert("123456789012345", 0); * rope.PrintStructure(); * rope.Delete(0, 170); * rope.PrintStructure(); * rope.Print(); * rope.Insert("123456789012345", 0); * rope.PrintStructure(); * //split.PrintStructure(); */ }
public async Task OnTick() { await Task.FromResult(0); try { PP.LastFlatbed(PP.Position.GetNearestFlatbed()); if (PP.CurrentVehicle == LF) { Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); if (!LF.IsControlOutside()) { if (manualControl) { if (Game.IsControlPressed(0, liftKey)) { LF.DropBedManually(true); } if (Game.IsControlPressed(0, lowerKey)) { LF.DropBedManually(false); } } else { if (Game.IsControlJustPressed(0, hookKey)) { await LF.DropBed(); } } } FreezeEntityPosition(LF.Handle, false); LF.IsPersistent = false; if (LF.CurrentTowingVehicle().Handle != 0 && PP.IsInVehicle(LF)) { if (Game.IsControlPressed(2, Control.VehicleAccelerate)) { ApplyForceToEntity(Game.Player.LastVehicle.Handle, 3, 0F, -0.04F, 0F, 0F, 0F, 0F, 0, true, true, true, true, true); } if (Game.IsControlPressed(2, Control.VehicleBrake)) { ApplyForceToEntity(Game.Player.LastVehicle.Handle, 3, 0F, 0.04F, 0F, 0F, 0F, 0F, 0, true, true, true, true, true); } } } else { LF.IsPersistent = true; } if (PP.IsInVehicle()) { if (PP.CurrentVehicle.IsOnAllWheels) { if (DecorGetFloat(PP.CurrentVehicle.Handle, gHeightDecor) == 0f) { DecorSetFloat(PP.CurrentVehicle.Handle, gHeightDecor, PP.CurrentVehicle.HeightAboveGround); } } if (PP.CurrentVehicle.IsThisFlatbed3() && !LFList.Contains(PP.CurrentVehicle)) { LFList.Add(PP.CurrentVehicle); } } if (LF.Exists()) { if (!PP.IsInVehicle(LF) && LF.IsControlOutside() && (PP.Position.DistanceTo(LF.ControlDummyPos()) <= 2f | PP.Position.DistanceTo(LF.ControlDummy2Pos()) <= 2f)) { if (manualControl) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HELP", "Press {0} to lift/lower the bed."), $"{liftKey.GetButtonIcon()} {lowerKey.GetButtonIcon()}")); if (Game.IsControlPressed(0, liftKey)) { LF.DropBedManually(true); } if (Game.IsControlPressed(0, lowerKey)) { LF.DropBedManually(false); } } else { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HELP", "Press {0} to lift/lower the bed."), hookKey.GetButtonIcon())); if (Game.IsControlJustPressed(0, hookKey)) { await LF.DropBed(); } } } if (!DecorGetBool(LF.Handle, helpDecor) && LV.IsThisFlatbed3()) { if (manualControl) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HELP", "Press {0} to lift/lower the bed."), $"{liftKey.GetButtonIcon()} {lowerKey.GetButtonIcon()}")); } else { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HELP", "Press {0} to lift/lower the bed."), hookKey.GetButtonIcon())); } DecorSetBool(LF.Handle, helpDecor, true); } if (marker) { LF.DrawMarkerTick(); } if (LF.IsFlatbedDropped()) { LF.TurnOnIndicators(); } else { LF.TurnOffIndicators(); } if (LF.CurrentTowingVehicle().Handle != 0) { if (!LF.CurrentTowingVehicle().IsAttachedTo(LF)) { LF.CurrentTowingVehicle(null); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, 0); } } if (DoesEntityExist(GetEntityAttachedTo(LF.Handle)) && LF.CurrentTowingVehicle().Handle == 0) { LF.CurrentTowingVehicle(GetEntityAttachedTo(LF.Handle)); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, GetEntityAttachedTo(LF.Handle)); } if (PP.IsInVehicle()) //Player is in vehicle { //Detach towing vehicle if player is inside towing vehicle if (PP.CurrentVehicle == LF.CurrentTowingVehicle()) { if (LV.IsVehicleFacingFlatbed(LF)) { await LF.CurrentTowingVehicle().DetachToFix(false); } else { await LF.CurrentTowingVehicle().DetachToFix(true); } LF.CurrentTowingVehicle().IsPersistent = false; LF.CurrentTowingVehicle(null); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, 0); } //Load vehicle while player is pressing hookkey on bed if (LV.IsAlive && LV.Position.DistanceTo(LF.AttachDummyPos()) <= 2f) { if (!LV.IsThisFlatbed3() && LF.CurrentTowingVehicle().Handle == 0 && AC.Contains(LV.ClassType)) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HOOK", "Press {0} to load {1}."), hookKey.GetButtonIcon(), PP.CurrentVehicle.LocalizedName)); if (Game.IsControlJustPressed(0, hookKey)) { LF.CurrentTowingVehicle(PP.CurrentVehicle); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, PP.CurrentVehicle.Handle); PP.CurrentVehicle.IsEngineRunning = false; PP.CurrentVehicle.IsPersistent = true; if (PP.CurrentVehicle == LF.CurrentTowingVehicle()) { PP.Task.LeaveVehicle(LF.CurrentTowingVehicle(), true); } await Delay(3000); if (LV.IsVehicleFacingFlatbed(LF)) { LV.AttachToFix(LF, LF.AttachDummyIndex(), LV.AttachCoords(), Vector3.Zero); } else { LV.AttachToFix(LF, LF.AttachDummyIndex(), LV.AttachCoords(), new Vector3(0f, 0f, 180f)); } } } } //Load vehicle while player is pressing hookkey on attach marker if (LF.AttachPosition().IsAnyVehicleNearAttachPosition(2f)) { if (!LV.IsThisFlatbed3() && LF.CurrentTowingVehicle().Handle == 0 && LF.IsFlatbedDropped() && AC.Contains(LV.ClassType)) { if (LV.Model != LF.Model) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HOOK", "Press {0} to load {1}."), hookKey.GetButtonIcon(), LV.LocalizedName)); if (Game.IsControlJustPressed(0, hookKey)) { LF.CurrentTowingVehicle(LV); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, LV.Handle); LV.IsPersistent = true; if (DecorGetFloat(LF.CurrentTowingVehicle().Handle, gHeightDecor) == 0f && LV.IsOnAllWheels) { DecorSetFloat(LF.CurrentTowingVehicle().Handle, gHeightDecor, LF.CurrentTowingVehicle().HeightAboveGround); } FreezeEntityPosition(LF.Handle, true); if (PP.CurrentVehicle == LV) { PP.Task.LeaveVehicle(); } if (LV.IsVehicleFacingFlatbed(LF)) { do { PP.Task.GoTo(LV.GetRopeHook()); await Delay(100); } while (!(PP.Position.DistanceTo(LV.GetRopeHook()) <= 1.5f)); } else { do { PP.Task.GoTo(LV.GetRopeHookRear()); await Delay(100); } while (!(PP.Position.DistanceTo(LV.GetRopeHookRear()) <= 1.5f)); } PP.Task.ClearAll(); //Vehicle heading is almost same as Flatbed if (LV.IsVehicleFacingFlatbed(LF)) { TriggerServerEvent("flatbed:AddRope", PP.Handle, LF.Handle, LV.Handle); ES = false; Rope rope = World.AddRope((RopeType)6, LF.WinchDummyPos(), Vector3.Zero, LF.WinchDummyPos().DistanceTo(LV.GetRopeHook()), 0.1f, false); rope.AttachEntities(LF, LF.WinchDummyPos(), LV, LV.GetRopeHook(), LF.WinchDummyPos().DistanceTo(LV.GetRopeHook())); rope.ActivatePhysics(); do { if (ES == true) { ES = false; rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(LV); rope.Delete(); return; } if (!LV.IsAnyPedBlockingVehicle(LF)) { rope.StartWinding(); Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); } await Delay(5); } while (!(rope.Length <= 1.9f)); rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(LV); rope.Delete(); FreezeEntityPosition(LF.Handle, false); LV.AttachToFix(LF, LF.AttachDummyIndex(), LV.AttachCoords(), Vector3.Zero); } //Vehicle heading is the opposite of Flatbed else { TriggerServerEvent("flatbed:AddRope", PP.Handle, LF.Handle, LV.Handle); ES = false; Rope rope = World.AddRope((RopeType)6, LF.WinchDummyPos(), Vector3.Zero, LF.WinchDummyPos().DistanceTo(LV.GetRopeHookRear()), 0.1f, false); rope.AttachEntities(LF, LF.WinchDummyPos(), LV, LV.GetRopeHookRear(), LF.WinchDummyPos().DistanceTo(LV.GetRopeHookRear())); rope.ActivatePhysics(); do { if (ES == true) { ES = false; rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(LV); rope.Delete(); return; } if (!LV.IsAnyPedBlockingVehicle(LF)) { rope.StartWinding(); Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); } await Delay(5); } while (!(rope.Length <= 1.9f)); rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(LV); rope.Delete(); FreezeEntityPosition(LF.Handle, false); LV.AttachToFix(LF, LF.AttachDummyIndex(), LV.AttachCoords(), Vector3.Zero); } } } } } } else //Player is not in vehicle { //Unload vehicle while flatbed is lowered if (LF.IsFlatbedDropped() && PP.Position.DistanceTo(LF.AttachDummyPos()) <= 3f) { if (World.GetDistance(LF.CurrentTowingVehicle().Position, PP.Position) <= 3f) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_UNHOOK", "Press {0} to unload {1}."), hookKey.GetButtonIcon(), LF.CurrentTowingVehicle().LocalizedName)); if (Game.IsControlJustPressed(0, hookKey)) { Vehicle towVeh = LF.CurrentTowingVehicle(); FreezeEntityPosition(LF.Handle, true); towVeh.SteeringScale = 0f; if (towVeh.IsVehicleFacingFlatbed(LF)) { await towVeh.DetachToFix(false); } else { await towVeh.DetachToFix(true); } await Delay(1000); if (towVeh.IsDriveable2()) { PP.Task.EnterVehicle(towVeh, VehicleSeat.Driver, 5000, 1f); do { Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); await Delay(5); } while (!(towVeh.Position.DistanceTo(LF.AttachPosition()) <= 2f)); } else { do { if (towVeh.IsVehicleFacingFlatbed(LF)) { towVeh.PushVehicleBack(); } else { towVeh.PushVehicleForward(); } Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); await Delay(5); } while (!(towVeh.Position.DistanceTo(LF.AttachPosition()) <= 2f)); } FreezeEntityPosition(LF.Handle, false); towVeh.IsPersistent = false; LF.CurrentTowingVehicle(null); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, 0); } } } if (LF.CurrentTowingVehicle().Handle == 0 && LF.IsFlatbedDropped() && LF.AttachPosition().IsAnyVehicleNearAttachPosition(2f)) { Vehicle thatVehicle = PP.Position.WorldGetClosestVehicle(); //Vehicle heading is almost same as Flatbed if (thatVehicle.Model != LF.Model && AC.Contains(thatVehicle.ClassType) && PP.Position.DistanceTo(thatVehicle.GetRopeHook()) <= 1.5f) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HOOK", "Press {0} to load {1}."), hookKey.GetButtonIcon(), thatVehicle.LocalizedName)); if (Game.IsControlJustPressed(0, hookKey)) { LF.CurrentTowingVehicle(thatVehicle); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, thatVehicle.Handle); thatVehicle.IsPersistent = true; if (thatVehicle.IsOnAllWheels) { if (DecorGetFloat(thatVehicle.Handle, gHeightDecor) == 0f) { DecorSetFloat(thatVehicle.Handle, gHeightDecor, thatVehicle.HeightAboveGround); } } FreezeEntityPosition(LF.Handle, true); TriggerServerEvent("flatbed:AddRope", PP.Handle, LF.Handle, LV.Handle); ES = false; Rope rope = World.AddRope((RopeType)6, LF.WinchDummyPos(), Vector3.Zero, LF.WinchDummyPos().DistanceTo(thatVehicle.GetRopeHook()), 0.1f, false); rope.AttachEntities(LF, LF.WinchDummyPos(), thatVehicle, thatVehicle.GetRopeHook(), LF.WinchDummyPos().DistanceTo(thatVehicle.GetRopeHook())); rope.ActivatePhysics(); do { if (ES == true) { ES = false; rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(thatVehicle); rope.Delete(); return; } if (!thatVehicle.IsAnyPedBlockingVehicle(LF)) { rope.StartWinding(); Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); } await Delay(5); } while (!(rope.Length <= 1.9f)); rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(thatVehicle); rope.Delete(); FreezeEntityPosition(LF.Handle, false); thatVehicle.AttachToFix(LF, LF.GetBoneIndex("misc_a"), thatVehicle.AttachCoords(), Vector3.Zero); } } //Vehicle heading is the opposite of Flatbed if (thatVehicle.Model != LF.Model && AC.Contains(thatVehicle.ClassType) && PP.Position.DistanceTo(thatVehicle.GetRopeHookRear()) <= 1.5f) { DisplayHelpTextThisFrame(String.Format(GetLangEntry("INM_FB_HOOK", "Press {0} to load {1}."), hookKey.GetButtonIcon(), thatVehicle.LocalizedName)); if (Game.IsControlJustPressed(0, hookKey)) { LF.CurrentTowingVehicle(thatVehicle); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, thatVehicle.Handle); thatVehicle.IsPersistent = true; if (thatVehicle.IsOnAllWheels) { if (DecorGetFloat(thatVehicle.Handle, gHeightDecor) == 0f) { DecorSetFloat(thatVehicle.Handle, gHeightDecor, thatVehicle.HeightAboveGround); } } FreezeEntityPosition(LF.Handle, true); TriggerServerEvent("flatbed:AddRope", PP.Handle, LF.Handle, LV.Handle); ES = false; Rope rope = World.AddRope((RopeType)6, LF.WinchDummyPos(), Vector3.Zero, LF.WinchDummyPos().DistanceTo(thatVehicle.GetRopeHookRear()), 0.1f, false); rope.AttachEntities(LF, LF.WinchDummyPos(), thatVehicle, thatVehicle.GetRopeHookRear(), LF.WinchDummyPos().DistanceTo(thatVehicle.GetRopeHookRear())); rope.ActivatePhysics(); do { if (ES == true) { ES = false; rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(thatVehicle); rope.Delete(); return; } if (!thatVehicle.IsAnyPedBlockingVehicle(LF)) { rope.StartWinding(); Game.DisableControlThisFrame(0, Control.VehicleMoveUpDown); } await Delay(5); } while (!(rope.Length <= 1.9f)); rope.StopWinding(); rope.DetachEntity(LF); rope.DetachEntity(thatVehicle); rope.Delete(); FreezeEntityPosition(LF.Handle, false); thatVehicle.AttachToFix(LF, LF.GetBoneIndex("misc_a"), thatVehicle.AttachCoords(), new Vector3(0f, 0f, 180f)); } } } } if (World.GetDistance(LF.CurrentTowingVehicle().Position, LF.Position) >= 20f) { LF.CurrentTowingVehicle().IsPersistent = false; LF.CurrentTowingVehicle(null); TriggerServerEvent("flatbed:SetTowingVehicle", PP.Handle, LF.Handle, 0); } } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}{ex.StackTrace}"); } }