Files
reallife-gamemode/ReallifeGamemode.Server/Managers/JobManager.cs
2020-03-01 17:39:54 +01:00

310 lines
9.5 KiB
C#

using GTANetworkAPI;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Job;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Server.Util;
using ReallifeGamemode.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace ReallifeGamemode.Server.Managers
{
public class JobManager : Script
{
private static List<JobBase> _jobs = new List<JobBase>();
public static void LoadJobs()
{
IEnumerable<Type> jobTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(JobBase)) && !t.IsAbstract);
foreach (var type in jobTypes)
{
var instance = Activator.CreateInstance(type) as JobBase;
if (GetJob(instance.Id) != null)
{
throw new InvalidOperationException($"Double Job ID found: {instance.Id} | {instance.Name}");
}
_jobs.Add(instance);
NAPI.Util.ConsoleOutput($"Loading job {instance.Name}");
}
NAPI.Util.ConsoleOutput($"Loaded {_jobs.Count} jobs");
}
public static JobBase GetJob(int id) => _jobs.Where(j => j.Id == id).FirstOrDefault();
public static T GetJob<T>() where T : JobBase
{
return _jobs.Where(j => j.GetType() == typeof(T)).FirstOrDefault() as T;
}
public static List<JobBase> GetJobs() => _jobs.OrderBy(j => j.Id).ToList();
[RemoteEvent("CLIENT:JobCenter_CancelJob")]
public void CancelJobEvent(Player player)
{
using (var dbContext = new DatabaseContext())
{
User u = player.GetUser(dbContext);
if (u == null) return;
if (u.JobId == null)
{
ChatService.ErrorMessage(player, "Du hast momentan keinen Job, den du kündigen könntest.");
return;
}
u.JobId = null;
ChatService.SendMessage(player, "~y~[JOBCENTER]~s~ Du hast deinen Job erfolgreich gekündigt.");
dbContext.SaveChanges();
}
}
[RemoteEvent("CLIENT:JobCenter_AcceptJob")]
public void AcceptJobEvent(Player player, int jobId)
{
using (var dbContext = new DatabaseContext())
{
User u = player.GetUser(dbContext);
if (u == null) return;
if (u.JobId != null)
{
ChatService.ErrorMessage(player, "Du musst deinen alten Job kündigen, bevor du einen neuen ausüben kannst");
return;
}
JobBase job = JobManager.GetJob(jobId);
if (job == null)
{
ChatService.ErrorMessage(player, "Bei der Job-Annahme ist ein Fehler aufgetretet: Dieser Job wurde nicht gefunden");
return;
}
ChatService.SendMessage(player, $"~y~[JOBCENTER]~s~ Du hast erfolgreich deinen neuen Job: ~o~{job.Name}~s~ angenommen.");
u.JobId = jobId;
dbContext.SaveChanges();
}
}
[RemoteEvent("CLIENT:JobManager_ShowJobMenu")]
public void ShowJobMenuEvent(Player player)
{
User u = player.GetUser();
if (u.JobId == null) return;
JobBase job = GetJob(u.JobId.Value);
dynamic data = null;
if (job.Id == 1 && job.GetUsersInJob().Contains(player))
{
var taxiCalls = JobManager.GetJob<TaxiDriverJob>().TaxiContracts;
if (!taxiCalls.Any(t => t.Driver?.Handle == player.Handle)) // Spieler in keiner aktiven Fahrt
{
data = new
{
job.Id,
Status = 0,
JobData = new
{
TaxiCalls = taxiCalls
.Where(t => t.Driver == null)
.Select(t => new
{
t.Name,
Distance = Math.Round(t.Position.DistanceTo(player.Position), 0)
})
.OrderBy(t => t.Distance)
}
};
}
else // Spieler in aktiver Fahrt
{
data = new
{
job.Id,
Status = 1,
JobData = new
{
taxiCalls.Where(t => t.Driver.Handle == player.Handle).First().Name
}
};
}
}
var json = JsonConvert.SerializeObject(data);
player.TriggerEvent("SERVER:Job_ShowJobMenu", job.Name, json);
}
[RemoteEvent("CLIENT:Job_StartJob")]
public void StartJobEvent(Player player)
{
User u = player.GetUser();
if (u.JobId == null) return;
JobBase job = GetJob(u.JobId.Value);
if (job.GetUsersInJob().Contains(player))
{
ChatService.ErrorMessage(player, "Du bist schon in deinem Job aktiv");
return;
}
if (job.NeedVehicleToStart && !job.GetJobVehicles().Any(v => v.GetVehicle().Handle.Value == player.Vehicle?.Handle.Value))
{
ChatService.ErrorMessage(player, "Zum Start dieses Jobs musst du in einem Jobfahrzeug sein");
return;
}
job.StartJob(player);
}
[RemoteEvent("CLIENT:Job_StopJob")]
public void StopJob(Player player)
{
User u = player.GetUser();
if (u.JobId == null) return;
JobBase job = GetJob(u.JobId.Value);
if (!job.GetUsersInJob().Contains(player))
{
ChatService.ErrorMessage(player, "Du führst deinen Job momentan nicht aus");
return;
}
if (job.NeedVehicleToStart && player.Vehicle != null)
{
VehicleStreaming.SetEngineState(player.Vehicle, false);
}
job.StopJob(player);
}
[ServerEvent(Event.PlayerExitVehicle)]
public void JobManagerPlayerExitVehicle(Player player, Vehicle veh)
{
User u = player.GetUser();
if (u.JobId == null) return;
JobBase job = GetJob(u.JobId.Value);
if (job.GetUsersInJob().Contains(player) && job.NeedVehicleToStart)
{
job.StopJob(player);
return;
}
}
[ServerEvent(Event.PlayerEnterVehicle)]
public void JobManagerPlayerEnterVehicle(Player player, Vehicle veh, sbyte seat)
{
if (seat == 0) return;
ServerVehicle sVeh = veh.GetServerVehicle();
if (sVeh == null) return;
if (sVeh is JobVehicle jV && jV.JobId == 1) // Spieler steigt in Taxi ein
{
var taxiJob = JobManager.GetJob<TaxiDriverJob>();
Player driver = veh.GetDriver();
if (!driver.HasData("DriverPrice")) return;
int taxiPrice = driver.GetData<int>("DriverPrice");
float km = 0;
if (!driver.HasData("FareKm")) { driver.SetData<float>("FareKm", km); }
km = driver.GetData<float>("FareKm");
if (driver.HasData("Passager")) return;
driver.SetData<int>("Passager", player.GetUser().Id);
driver.SetData<bool>("hasPassager", true);
player.TriggerEvent("CLIENT:startCustomerFare", taxiPrice, km);
var taxiContracts = taxiJob.TaxiContracts.Where(t => t.Name == player.Name);
if (taxiContracts.Count() == 0) return;
var contract = taxiContracts.First();
taxiJob.TaxiContracts.Remove(contract);
if (driver != null && contract.Driver != null && contract.Driver.Handle != veh.GetDriver().Handle)
{
ChatService.SendMessage(contract.Driver, $"!{{02FCFF}}{player.Name} ist in ein Taxi eingestiegen, der Auftrag wurde beendet.");
ChatService.SendMessage(player, $"!{{02FCFF}}Du bist in ein Taxi eingestiegen, der Auftrag wurde beendet.");
}
}
}
[ServerEvent(Event.PlayerExitVehicle)]
public void JobManagerPlayerEnterVehicle(Player player, Vehicle veh)
{
ServerVehicle sVeh = veh.GetServerVehicle();
if (sVeh == null) return;
if (sVeh is JobVehicle jV && jV.JobId == 1) // Spieler steigt in Taxi aus
{
var taxiJob = JobManager.GetJob<TaxiDriverJob>();
if (veh.Occupants.Count == 0) return;
Player driver = veh.GetDriver();
if (driver == null) return;
if (player.GetUser().Id != driver.GetData<int>("Passager")) { player.TriggerEvent("CLIENT:cancelFare"); return; }
player.TriggerEvent("CLIENT:cancelFareCustomer");
driver.ResetData("Passager");
driver.ResetData("hasPassager");
foreach(Player occupant in veh.Occupants)
{
if (occupant == driver) continue;
occupant.WarpOutOfVehicle();
}
}
}
[RemoteEvent("CLIENT:JobManager_TaxiJob_AcceptCall")]
public void TaxiJobAcceptCall(Player player, string name)
{
var taxiJob = JobManager.GetJob<TaxiDriverJob>();
if (!taxiJob.TaxiContracts.Any(t => t.Name == name))
{
ChatService.ErrorMessage(player, "Dieser Spieler hat kein Taxi gerufen oder der Auftrag ist nicht mehr aktuell");
return;
}
var job = taxiJob.TaxiContracts.Where(t => t.Name == name).First();
var target = PlayerService.GetPlayerByNameOrId(name);
if (target == null)
{
taxiJob.TaxiContracts.Remove(job);
ChatService.ErrorMessage(player, "Dieser Spieler ist nicht mehr online");
return;
}
job.Driver = player;
player.TriggerEvent("SERVER:Util_setWaypoint", target.Position.X, target.Position.Y);
player.SetData<bool>("hasPassager", true);
ChatService.SendMessage(target, $"!{{02FCFF}}Dein Auftrag wurde von {player.Name} angenommen. Warte an deiner aktuellen Position.");
ChatService.SendMessage(target, $"!{{02FCFF}}Für die Anfahrt fallen zusätzlich Kosten auf.");
ChatService.SendMessage(player, $"!{{02FCFF}}Du hast den Auftrag von {name} angenommen. Hole ihn nun ab.");
}
}
}