using System; using System.Linq; using CitizenFX.Core; using CitizenFX.Core.Native; using CitizenFX.Core.UI; using Nexd.ESX.Client; using TaxiJob.Client.Extensions; namespace TaxiJob.Client.Handler { public static class JobHandler { private static bool _vehicleSpawned; private static Vehicle _vehicle; private static Blip _vehicleBlip; private static Blip _taskBlip; private static int _lastJob; private static bool _inJob; private static bool _isNpcJob; private static bool _arrived; private static bool _lookStarted; private static Ped _npc; private static int _nextSpeech; public static void OnTick() { HandleVehicleSpawner(); HandleVehicleDeleter(); HandleVehicleBlip(); HandleNpcJob(); HandleJob(); if (!_inJob && _vehicleSpawned && _vehicleBlip == null && Game.GameTime - _lastJob >= TaxiJob.Config.TimeToNpcJob) { StartNpcJob(); } if (Game.PlayerPed.IsDead && _inJob) StopJob(); } private static async void HandleVehicleSpawner() { if (_vehicleSpawned || Game.PlayerPed.IsInVehicle()) return; var dist = World.GetDistance(Game.PlayerPed.Position, TaxiJob.Config.VehicleSpawner.Position); if (dist >= TaxiJob.Config.DrawDistance) return; TaxiJob.Config.VehicleSpawner.Render(); if (dist <= TaxiJob.Config.VehicleSpawner.Size.X) { Screen.DisplayHelpTextThisFrame("Drücke ~INPUT_CONTEXT~ um das Taxi aus der Garage zu holen"); if (Game.IsControlJustReleased(0, Control.Context)) { if (!ESX.Game.IsSpawnPointClear(TaxiJob.Config.VehicleSpawnPoint.ToVector3(), 5.0)) { Notify.Error("Ein Fahrzeug blockiert den Spawnpunkt!"); return; } _vehicle = await TaxiJob.SpawnVehicle(API.GetHashKey(TaxiJob.Config.VehicleModel), TaxiJob.Config.VehicleSpawnPoint); _vehicle.SetNumberPlateText(await TaxiJob.GeneratePlate()); BaseScript.TriggerEvent("craftix:refuelVehicle", _vehicle.Handle); Game.PlayerPed.SetIntoVehicle(_vehicle, VehicleSeat.Driver); _lastJob = Game.GameTime; _vehicleSpawned = true; } } } private static void HandleVehicleDeleter() { if (_vehicleSpawned) { if (!_vehicle.Exists() || _vehicle.IsDead) { _vehicleBlip?.Delete(); StopJob(); _vehicleSpawned = false; _vehicleBlip = null; _vehicle = null; return; } } if (!_vehicleSpawned || !Game.PlayerPed.IsInVehicle(_vehicle)) return; World.DrawMarker(MarkerType.HorizontalCircleSkinny, TaxiJob.Config.VehicleDeleter, Vector3.Zero, Vector3.Zero, new Vector3(3.7f, 3.7f, 0.2f), TaxiJob.Config.VehicleSpawner.Color); var dist = World.GetDistance(Game.PlayerPed.Position, TaxiJob.Config.VehicleDeleter); if (dist >= 4.0f) return; Screen.DisplayHelpTextThisFrame("Drücke ~INPUT_CONTEXT~ um das Auto in die Garage zu stellen"); if (Game.IsControlJustReleased(0, Control.Context)) { _vehicle?.Delete(); _vehicleBlip?.Delete(); StopJob(); _vehicleSpawned = false; _vehicleBlip = null; _vehicle = null; } } private static void HandleVehicleBlip() { if (!_vehicleSpawned) return; var inVehicle = Game.PlayerPed.IsInVehicle(_vehicle); if (inVehicle && _vehicleBlip != null) { _lastJob = Game.GameTime; _vehicleBlip?.Delete(); _vehicleBlip = null; } else if (!inVehicle && _vehicleBlip == null) { _vehicleBlip = new Blip(API.AddBlipForEntity(Game.PlayerPed.LastVehicle.Handle)); _vehicleBlip.Sprite = (BlipSprite)198; _vehicleBlip.Color = BlipColor.Yellow; _vehicleBlip.Name = "Dienstwagen"; API.SetBlipDisplay(_vehicleBlip.Handle, 4); } } private static void HandleJob() { if (!_inJob || _isNpcJob) return; if (!_arrived) { if (!Game.PlayerPed.IsInVehicle()) return; var dist = World.GetDistance(Game.PlayerPed.Position, _taskBlip.Position); if (dist <= 30.0 && Game.PlayerPed.CurrentVehicle.Speed <= 1) { _taskBlip.Delete(); _taskBlip = null; _arrived = true; } } } private static void HandleNpcJob() { if (!_inJob || !_isNpcJob) return; if (!_arrived) { if (!Game.PlayerPed.IsInVehicle()) return; var dist = World.GetDistance(Game.PlayerPed.Position, _npc.Position); if (!_lookStarted && dist <= 50.0 && dist > 30.0) { _npc.Task.LookAt(Game.PlayerPed, int.MaxValue); _lookStarted = true; } if (dist <= 30.0 && Game.PlayerPed.CurrentVehicle.Speed <= 1) { _npc.Task.ClearAllImmediately(); _npc.Task.EnterVehicleOnFreeSeat(Game.PlayerPed.CurrentVehicle, VehicleSeat.RightRear); _npc.PlayAmbientSpeech("GENERIC_HI"); _taskBlip.Delete(); _taskBlip = null; _arrived = true; var random = new Random(); _nextSpeech = Game.GameTime + (random.Next(5000) + 20000); } } if (_arrived && _taskBlip == null && _npc.IsInVehicle()) { var playerPos = Game.PlayerPed.Position; var target = TaxiJob.Config.Positions .Where(pos => World.GetDistance(playerPos, pos) >= 500.0f) .Random(); _taskBlip = new Blip(API.AddBlipForCoord(target.X, target.Y, target.Z)); _taskBlip.Name = "Ziel"; _taskBlip.ShowRoute = true; Notify.Info("Zielposition wurde im Navi eingegeben."); } if (_arrived && _taskBlip != null) { if (!Game.PlayerPed.IsInVehicle()) return; var dist = World.GetDistance(Game.PlayerPed.Position, _taskBlip.Position); if (_nextSpeech <= Game.GameTime) { var random = new Random(); _nextSpeech = Game.GameTime + (random.Next(5000) + 20000); _npc.PlayAmbientSpeech("GENERIC_HOWS_IT_GOING"); } if (dist <= 30.0 && Game.PlayerPed.CurrentVehicle.Speed <= 1) { _inJob = false; _npc.Task.LeaveVehicle(_npc.CurrentVehicle, true); _npc.PlayAmbientSpeech("GENERIC_THANKS"); _npc.MarkAsNoLongerNeeded(); _npc = null; StopJob(); Notify.Success("Auftrag beendet!"); } } } private static async void StartNpcJob() { Notify.Info("Neuer Auftrag!"); StopJob(); var target = TaxiJob.Config.Positions.Random(); _taskBlip = new Blip(API.AddBlipForCoord(target.X, target.Y, target.Z)); _taskBlip.Name = "Kunde"; _taskBlip.ShowRoute = true; var model = new Model(TaxiJob.Config.Npcs.Random()); await model.Load(); _npc = await World.CreatePed(model, target); _npc.AsMissionEntry(); _npc.Task.ClearAllImmediately(); _npc.LootAtStreet(); _npc.SetBlockingOfNonTemporaryEvents(true); _npc.IsInvincible = true; _npc.Task.StandStill(int.MaxValue); _isNpcJob = true; _inJob = true; } private static void StopJob() { _taskBlip?.Delete(); _taskBlip = null; _npc?.Task.ClearAllImmediately(); _npc?.MarkAsNoLongerNeeded(); _npc = null; _inJob = false; _isNpcJob = false; _arrived = false; _lookStarted = false; _lastJob = Game.GameTime; } } }