using System; using CitizenFX.Core; using CitizenFX.Core.Native; using CitizenFX.Core.UI; using TaxiJob.Client.Extensions; namespace TaxiJob.Client.Handler { public static class NpcTaxiHandler { public static bool IsCustomer; private static Vehicle _taxi; private static Blip _blip; private static Ped _driver; private static bool _arrived; private static bool _hasDestination; private static Vector3 _destination; private static bool _atDestination; private static int _lastUpdate; private static Vector3 _lastPosition; private static bool _pause; public static async void StartNpcJob() { if (IsCustomer) return; await BaseScript.Delay(5000); Notify.Info("Ein Taxi ist auf dem Weg zu ihnen!"); var spawn = GetDistantSpawn(700); // Spawn Taxi var model = (Model)VehicleHash.Taxi; await model.Load(); _taxi = await World.CreateVehicle(model, spawn.ToVector3(), spawn.W); _taxi.Mods.LicensePlate = await TaxiJob.GeneratePlate(); _taxi.AsMissionEntry(); TaxiJob.SetFuel(_taxi, 100.0f); // Blip _blip = new Blip(API.AddBlipForEntity(_taxi.Handle)); _blip.Sprite = (BlipSprite)198; _blip.Color = BlipColor.Yellow; _blip.Name = "Taxi"; // Driver model = new Model(-573920724); await model.Load(); _driver = await World.CreatePed(model, spawn.ToVector3()); _driver.SetIntoVehicle(_taxi, VehicleSeat.Driver); _driver.CanBeTargetted = false; _driver.AsMissionEntry(); // Drive to Player _driver.Task.DriveTo(_taxi, World.GetNextPositionOnStreet(Game.PlayerPed.Position), 10f, 20f, 262975); Taximeter.Reset(); _lastPosition = _taxi.Position; Taximeter.Pause(false); _arrived = false; _pause = false; IsCustomer = true; } public static void OnTick() { if (!_driver.IsInVehicle(_taxi)) { TaxiJob.SetFuel(_taxi, 0.0f); IsCustomer = false; _blip?.Delete(); _blip = null; Taximeter.Reset(); } if (!_arrived && Game.PlayerPed.IsInVehicle(_taxi)) { _arrived = true; _atDestination = false; _hasDestination = false; _driver.PlayAmbientSpeech("GENERIC_HI"); _blip?.Delete(); _blip = null; Taximeter.SetVisible(true); } if (_arrived && !_hasDestination && World.WaypointPosition != Vector3.Zero) { _hasDestination = true; _destination = World.GetNextPositionOnStreet(World.WaypointPosition); _driver.Task.DriveTo(_taxi, _destination, 10f, 20f, 262975); } if (_hasDestination && !_atDestination && World.GetDistance(_taxi.Position, _destination) <= 10.5f && !Game.PlayerPed.IsInVehicle(_taxi)) { _atDestination = true; var price = (int)Math.Round(Convert.ToSingle(Taximeter.Attributes.CurrentFare) + 0.5f); BaseScript.TriggerServerEvent("taxijob:server:bill", price, Game.Player.ServerId); Taximeter.Reset(); } if (_atDestination && World.GetDistance(_taxi.Position, Game.PlayerPed.Position) >= 5) { _taxi.MarkAsNoLongerNeeded(); _driver.MarkAsNoLongerNeeded(); _hasDestination = false; _destination = Vector3.Zero; _atDestination = false; _taxi = null; _driver = null; IsCustomer = false; } var current = Game.GameTime; if (current - _lastUpdate >= 2000) { _lastUpdate = current; Taximeter.CalculatePrice(_lastPosition, _taxi.Position); _lastPosition = _taxi.Position; } if (!(_hasDestination && !_atDestination)) return; Screen.DisplayHelpTextThisFrame("Drücke ~INPUT_VEH_SHUFFLE~ um die Fahrt " + (_pause ? "fortzusetzen" : "zu pausieren")); if (Game.IsControlJustReleased(0, Control.VehicleShuffle)) { if (_pause) { if (World.WaypointPosition != Vector3.Zero) _destination = World.GetNextPositionOnStreet(World.WaypointPosition); _driver?.Task.DriveTo(_taxi, _destination, 10f, 20f, 262975); } else { _driver?.Task.DriveTo(_taxi, _taxi.Position + (_taxi.ForwardVector * 20f), 10f, 5f, 262975); } _pause = !_pause; } if (!Game.PlayerPed.IsInVehicle(_taxi)) { _atDestination = true; var price = (int)Math.Round(Convert.ToSingle(Taximeter.Attributes.CurrentFare) + 0.5f); BaseScript.TriggerServerEvent("taxijob:server:bill", price, Game.Player.ServerId); Taximeter.Reset(); } } private static Vector4 GetDistantSpawn(int distance) { Vector3 player = Game.PlayerPed.Position; Vector3 location = Vector3.Zero; float heading = 0f; int unused = 0; API.GetNthClosestVehicleNodeWithHeading(player.X, player.Y, player.Z, distance, ref location, ref heading, ref unused, 9, 3.0f, 2.5f); return new Vector4(location, heading); } } }