Files
reallife-gamemode/ReallifeGamemode.Server/Managers/VehicleManager.cs
2021-05-20 18:11:47 +02:00

1338 lines
34 KiB
C#

using GTANetworkAPI;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Log;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Server.Util;
using ReallifeGamemode.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
namespace ReallifeGamemode.Server.Managers
{
public class VehicleManager : Script
{
public static Dictionary<Vehicle, Dictionary<string, DateTime>> lastDriversInVehicle = new Dictionary<Vehicle, Dictionary<string, DateTime>>();
private static readonly List<string> _enabledMods = new List<string>()
{
"ninef",
"ninef2",
"blista",
"asea",
"asea2",
"boattrailer",
"bus",
"armytanker",
"armytrailer",
"armytrailer2",
"freighttrailer",
"coach",
"airbus",
"asterope",
"airtug",
"ambulance",
"barracks",
"barracks2",
"baller",
"baller2",
"bjxl",
"banshee",
"benson",
"bfinjection",
"biff",
"blazer",
"blazer2",
"blazer3",
"bison",
"bison2",
"bison3",
"boxville",
"boxville2",
"boxville3",
"bobcatxl",
"bodhi2",
"buccaneer",
"buffalo",
"buffalo2",
"bulldozer",
"bullet",
"blimp",
"burrito",
"burrito2",
"burrito3",
"burrito4",
"burrito5",
"cavalcade",
"cavalcade2",
"policet",
"gburrito",
"cablecar",
"caddy",
"caddy2",
"camper",
"carbonizzare",
"cheetah",
"comet2",
"cogcabrio",
"coquette",
"cutter",
"gresley",
"dilettante",
"dilettante2",
"dune",
"dune2",
"hotknife",
"dloader",
"dubsta",
"dubsta2",
"dump",
"rubble",
"docktug",
"dominator",
"emperor",
"emperor2",
"emperor3",
"entityxf",
"exemplar",
"elegy2",
"f620",
"fbi",
"fbi2",
"felon",
"felon2",
"feltzer2",
"firetruk",
"flatbed",
"forklift",
"fq2",
"fusilade",
"fugitive",
"futo",
"granger",
"gauntlet",
"habanero",
"hauler",
"handler",
"infernus",
"ingot",
"intruder",
"issi2",
"Jackal",
"journey",
"jb700",
"khamelion",
"landstalker",
"lguard",
"manana",
"mesa",
"mesa2",
"mesa3",
"crusader",
"minivan",
"mixer",
"mixer2",
"monroe",
"mower",
"mule",
"mule2",
"oracle",
"oracle2",
"packer",
"patriot",
"pbus",
"penumbra",
"peyote",
"phantom",
"phoenix",
"picador",
"pounder",
"police",
"police4",
"police2",
"police3",
"policeold1",
"policeold2",
"pony",
"pony2",
"prairie",
"pranger",
"premier",
"primo",
"proptrailer",
"rancherxl",
"rancherxl2",
"rapidgt",
"rapidgt2",
"radi",
"ratloader",
"rebel",
"regina",
"rebel2",
"rentalbus",
"ruiner",
"rumpo",
"rumpo2",
"rhino",
"riot",
"ripley",
"rocoto",
"romero",
"sabregt",
"sadler",
"sadler2",
"sandking",
"sandking2",
"schafter2",
"schwarzer",
"scrap",
"seminole",
"sentinel",
"sentinel2",
"zion",
"zion2",
"serrano",
"sheriff",
"sheriff2",
"speedo",
"speedo2",
"stanier",
"stinger",
"stingergt",
"stockade",
"stockade3",
"stratum",
"sultan",
"superd",
"surano",
"surfer",
"surfer2",
"surge",
"taco",
"tailgater",
"taxi",
"trash",
"tractor",
"tractor2",
"tractor3",
"graintrailer",
"baletrailer",
"tiptruck",
"tiptruck2",
"tornado",
"tornado2",
"tornado3",
"tornado4",
"tourbus",
"towtruck",
"towtruck2",
"utillitruck",
"utillitruck2",
"utillitruck3",
"voodoo2",
"washington",
"stretch",
"youga",
"ztype",
"sanchez",
"sanchez2",
"scorcher",
"tribike",
"tribike2",
"tribike3",
"fixter",
"cruiser",
"BMX",
"policeb",
"akuma",
"carbonrs",
"bagger",
"bati",
"bati2",
"ruffian",
"daemon",
"double",
"pcj",
"vader",
"vigero",
"faggio2",
"hexer",
"annihilator",
"buzzard",
"buzzard2",
"cargobob",
"cargobob2",
"cargobob3",
"skylift",
"polmav",
"maverick",
"nemesis",
"frogger",
"frogger2",
"cuban800",
"duster",
"stunt",
"mammatus",
"jet",
"shamal",
"luxor",
"titan",
"lazer",
"cargoplane",
"squalo",
"marquis",
"dinghy",
"dinghy2",
"jetmax",
"predator",
"tropic",
"seashark",
"seashark2",
"submersible",
"freightcar",
"freight",
"freightcont1",
"freightcont2",
"freightgrain",
"tankercar",
"metrotrain",
"docktrailer",
"trailers",
"trailers2",
"trailers3",
"tvtrailer",
"raketrailer",
"tanker",
"trailerlogs",
"tr2",
"tr3",
"tr4",
"trflat",
"trailersmall",
"velum",
"adder",
"voltic",
"vacca",
"suntrap",
"submersible2",
"dukes",
"dukes2",
"buffalo3",
"dominator2",
"dodo",
"marshall",
"blimp2",
"gauntlet2",
"stalion",
"stalion2",
"blista2",
"blista3",
"bifta",
"speeder",
"kalahari",
"paradise",
"btype",
"jester",
"turismor",
"alpha",
"vestra",
"zentorno",
"massacro",
"huntley",
"thrust",
"rhapsody",
"warrener",
"blade",
"glendale",
"panto",
"dubsta3",
"pigalle",
"monster",
"sovereign",
"innovation",
"hakuchou",
"furoregt",
"miljet",
"besra",
"coquette2",
"swift",
"jester2",
"massacro2",
"ratloader2",
"slamvan",
"mule3",
"velum2",
"tanker2",
"casco",
"boxville4",
"hydra",
"insurgent",
"insurgent2",
"gburrito2",
"technical",
"dinghy3",
"savage",
"enduro",
"guardian",
"lectro",
"kuruma",
"kuruma2",
"trash2",
"barracks3",
"valkyrie",
"slamvan2",
"swift2",
"luxor2",
"feltzer3",
"osiris",
"virgo",
"windsor",
"coquette3",
"vindicator",
"t20",
"brawler",
"toro",
"chino",
"faction",
"faction2",
"moonbeam",
"moonbeam2",
"primo2",
"chino2",
"buccaneer2",
"voodoo",
"Lurcher",
"btype2",
"verlierer2",
"nightshade",
"mamba",
"limo2",
"schafter3",
"schafter4",
"schafter5",
"schafter6",
"cog55",
"cog552",
"cognoscenti",
"cognoscenti2",
"baller3",
"baller4",
"baller5",
"baller6",
"toro2",
"seashark3",
"dinghy4",
"tropic2",
"speeder2",
"cargobob4",
"supervolito",
"supervolito2",
"valkyrie2",
"tampa",
"sultanrs",
"banshee2",
"btype3",
"faction3",
"minivan2",
"sabregt2",
"slamvan3",
"tornado5",
"virgo2",
"virgo3",
"nimbus",
"xls",
"xls2",
"seven70",
"fmj",
"bestiagts",
"pfister811",
"brickade",
"rumpo3",
"volatus",
"prototipo",
"reaper",
"tug",
"windsor2",
"lynx",
"gargoyle",
"tyrus",
"sheava",
"omnis",
"le7b",
"contender",
"trophytruck",
"trophytruck2",
"rallytruck",
"cliffhanger",
"bf400",
"tropos",
"brioso",
"tampa2",
"tornado6",
"faggio3",
"faggio",
"raptor",
"vortex",
"avarus",
"sanctus",
"youga2",
"hakuchou2",
"nightblade",
"chimera",
"esskey",
"wolfsbane",
"zombiea",
"zombieb",
"defiler",
"daemon2",
"ratbike",
"shotaro",
"manchez",
"blazer4",
"elegy",
"tempesta",
"italigtb",
"italigtb2",
"nero",
"nero2",
"specter",
"specter2",
"diablous",
"diablous2",
"blazer5",
"ruiner2",
"dune4",
"dune5",
"phantom2",
"voltic2",
"penetrator",
"boxville5",
"wastelander",
"technical2",
"fcr",
"fcr2",
"comet3",
"ruiner3",
"turismo2",
"infernus2",
"gp1",
"ruston",
"trailers4",
"xa21",
"caddy3",
"vagner",
"phantom3",
"nightshark",
"cheetah2",
"torero",
"hauler2",
"trailerlarge",
"technical3",
"insurgent3",
"apc",
"tampa3",
"dune3",
"trailersmall2",
"halftrack",
"ardent",
"oppressor",
"vigilante",
"bombushka",
"alphaz1",
"seabreeze",
"tula",
"havok",
"hunter",
"microlight",
"rogue",
"pyro",
"howard",
"mogul",
"starling",
"nokota",
"molotok",
"rapidgt3",
"retinue",
"cyclone",
"visione",
"z190",
"viseris",
"comet5",
"raiden",
"riata",
"sc1",
"autarch",
"savestra",
"gt500",
"comet4",
"neon",
"sentinel3",
"khanjali",
"barrage",
"volatol",
"akula",
"deluxo",
"stromberg",
"chernobog",
"riot2",
"avenger",
"avenger2",
"thruster",
"yosemite",
"hermes",
"hustler",
"streiter",
"revolter",
"pariah",
"kamacho",
"entity2",
"cheburek",
"jester3",
"caracara",
"hotring",
"seasparrow",
"flashgt",
"ellie",
"michelli",
"fagaloa",
"dominator3",
"tyrant",
"tezeract",
"gb200",
"issi3",
"taipan",
"blimp3",
"mule4",
"pounder2",
"speedo4",
"pbus2",
"patriot2",
"swinger",
"terbyte",
"oppressor2",
"strikeforce",
"menacer",
"scramjet",
"freecrawler",
"stafford",
"bruiser",
"bruiser2",
"bruiser3",
"brutus",
"brutus2",
"brutus3",
"cerberus",
"cerberus2",
"cerberus3",
"clique",
"deathbike",
"deathbike2",
"deathbike3",
"deveste",
"deviant",
"dominator4",
"dominator5",
"dominator6",
"impaler",
"impaler2",
"impaler3",
"impaler4",
"imperator",
"imperator2",
"imperator3",
"issi4",
"issi5",
"issi6",
"italigto",
"monster3",
"monster4",
"monster5",
"rcbandito",
"scarab",
"scarab2",
"scarab3",
"schlagen",
"slamvan4",
"slamvan5",
"slamvan6",
"toros",
"tulip",
"vamos",
"zr380",
"zr3802",
"zr3803",
"streiter2", //Mod
"caracara2",
"drafter",
"dynasty",
"emerus",
"gauntlet3",
"gauntlet4",
"hellion",
"issi7",
"jugular",
"krieger",
"locust",
"nebula",
"neo",
"novak",
"paragon",
"paragon2",
"peyote2",
"rrocket",
"s80",
"thrax",
"zorrusso",
"zion3",
"polbullet", //Mod
"polbullet2", //Mod
"sherbullet", //Mod
"hwaybullet", //Mod
"zhaba",
"yosemite2",
"vstr",
"vagrant",
"sultan2",
"sugoi",
"stryder",
"retinue2",
"rebla",
"outlaw",
"minitank",
"komoda",
"kanjo",
"jb7002",
"imorgon",
"furia",
"formula2",
"formula",
"everon",
"asbo",
"openwheel1",
"openwheel2",
"tigon",
"landstalker2",
"penumbra2",
"club",
"coquette4",
"seminole2",
"dukes3",
"manana2",
"peyote3",
"gauntlet5",
"yosemite3",
"youga3",
"glendale2",
"alkonost",
"annihilator2",
"avisa",
"brioso2",
"dinghy5",
"italirsx",
"kosatka",
"longfin",
"manchez2",
"patrolboat",
"seasparrow2",
"seasparrow3",
"slamtruck",
"squaddie",
"toreador",
"verus",
"vetir",
"veto",
"veto2",
"weevil",
"winky",
"polamggtr", //mod
"newsfrog", //mod
"fibn",//mod
"fibg",//mod
"fibd",//mod
"fibs",//mod
"fibc",//mod
"fibn2",//mod
"fibx",//mod
"fibg2",//mod
"fibd2",//mod
"fibj",//mod
"fibn3",//mod
"fibr",//mod
};
private static readonly List<string> _restrictedVehicles = new List<string>()
{
"dinghy5",
"kosatka",
"cerberus",
"cerberus2",
"cerberus3",
"firetruk",
"issi4",
"issi5",
"issi6",
"jb700",
"jb7002",
"riot2",
"akula",
"annihilator",
"buzzard",
"havok",
"hunter",
"savage",
"seasparrow",
"valkyrie",
"valkyrie2",
"annihilator2",
"seasparrow2",
"seasparrow3",
"apc",
"barrage",
"chernobog",
"halftrack",
"khanjali",
"minitank",
"rhino",
"scarab",
"scarab2",
"scarab3",
"thruster",
"trailersmall2",
"oppressor",
"oppressor2",
"deathbike",
"deathbike2",
"deathbike3",
"dominator4",
"dominator5",
"dominator6",
"slamvan4",
"slamvan5",
"slamvan6",
"imperator3",
"imperator",
"imperator2",
"impaler2",
"impaler3",
"impaler4",
"tampa3",
"bruiser",
"bruiser2",
"bruiser3",
"brutus",
"brutus2",
"brutus3",
"caracara",
"dune3",
"insurgent",
"insurgent3",
"monster3",
"monster4",
"monster5",
"menacer",
"nightshark",
"fibn2",
"rcbandito",
"minitank",
"technical",
"technical2",
"technical3",
"avenger",
"avenger2",
"bombushka",
"hydra",
"lazer",
"microlight",
"mogul",
"molotok",
"nokota",
"pyro",
"rogue",
"strikeforce",
"seabreeze",
"starling",
"tula",
"volatol",
"alkonost",
"limo2",
"zr380",
"zr3802",
"zr3803",
"ardent",
"deluxo",
"stromberg",
"toreador",
"comet4",
"scramjet",
"vigilante",
"voltic2",
"freight",
"freightcar",
"freightcont1",
"freightcont2",
"freightgrain",
"metrotrain",
"tankercar",
"trailerlarge",
"boxville5",
"mule4",
"speedo4",
"pounder2"
};
public VehicleManager ()
{
#region add_VehicleRespawnPoints
VehicleRespawnPoints.Add(pos1);
VehicleRespawnPoints.Add(pos2);
VehicleRespawnPoints.Add(pos3);
VehicleRespawnPoints.Add(pos4);
VehicleRespawnPoints.Add(pos5);
VehicleRespawnPoints.Add(pos6);
VehicleRespawnPoints.Add(pos7);
VehicleRespawnPoints.Add(pos8);
VehicleRespawnPoints.Add(pos9);
VehicleRespawnPoints.Add(pos10);
VehicleRespawnPoints.Add(pos11);
VehicleRespawnPoints.Add(pos12);
VehicleRespawnPoints.Add(pos13);
VehicleRespawnPoints.Add(pos14);
VehicleRespawnPoints.Add(pos15);
VehicleRespawnPoints.Add(pos16);
VehicleRespawnPoints.Add(pos17);
VehicleRespawnPoints.Add(pos18);
VehicleRespawnPoints.Add(pos19);
VehicleRespawnPoints.Add(pos20);
#endregion add_VehicleRespawnPoints
}
private static readonly Dictionary<int, ushort> _serverVehicles = new Dictionary<int, ushort>();
private static readonly Dictionary<NetHandle, Vector3> lastPositions = new Dictionary<NetHandle, Vector3>();
private static DateTime lastSave = DateTime.UtcNow;
private static ILogger<VehicleManager> logger = LogManager.GetLogger<VehicleManager>();
public static void CheckEnabledMods()
{
foreach (var name in _enabledMods)
{
if (_enabledMods.Where(x => x == name).Count() != 1)
{
NAPI.Util.ConsoleOutput($"{name} double");
}
}
}
public static bool IsVehicleRestricted(string name) => _restrictedVehicles.Contains(name.ToLower());
public static void VehicleTimerTick()
{
NAPI.Task.Run(() =>
{
NAPI.Pools.GetAllVehicles().ForEach(v =>
{
if (v.Handle.Value == 0 || v.Handle == default)
{
return;
}
Vector3 lastPosition = v.Position;
if (lastPositions.ContainsKey(v.Handle)) lastPosition = lastPositions[v.Handle];
lastPositions[v.Handle] = v.Position;
double distanceDriven;
try
{
distanceDriven = v.HasSharedData("drivenDistance") ? (double)v.GetSharedData<dynamic>("drivenDistance") : 0D;
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
{
distanceDriven = 0;
}
double distance = lastPosition.DistanceTo(v.Position) / 1000.0;
if (distance > 0.2)
{
lastPositions[v.Handle] = v.Position;
return;
}
distanceDriven += distance;
v.SetSharedData("drivenDistance", (float)distanceDriven);
});
if (DateTime.UtcNow.Subtract(lastSave).Seconds >= 30)
{
lastSave = DateTime.UtcNow;
// save to db
using (var dbContext = new DatabaseContext())
{
foreach (var key in lastPositions.Keys.ToList())
{
Vehicle v = key.Entity<Vehicle>();
if (v == null) continue;
if (!v.HasSharedData("drivenDistance")) continue;
ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(v, dbContext);
if (sVeh == null) continue;
sVeh.DistanceDriven = (float)v.GetSharedData<dynamic>("drivenDistance");
}
dbContext.SaveChanges();
}
}
});
}
public static void AddVehicle(ServerVehicle serverVehicle, Vehicle vehicle)
{
if (_serverVehicles.ContainsKey(serverVehicle.Id))
{
var spawnedHandle = _serverVehicles.Where(s => s.Key == serverVehicle.Id).First().Value;
logger.LogCritical("Server Vehicle {Id} already has a spawned vehicle with handle {spawnedHandle}", serverVehicle.Id, spawnedHandle);
new NetHandle(_serverVehicles[serverVehicle.Id], EntityType.Vehicle).Entity<Vehicle>().Delete();
}
if (_serverVehicles.ContainsValue(vehicle.Handle.Value))
{
var dbId = _serverVehicles.Where(v => v.Value == vehicle.Handle.Value).First().Key;
var dbIdHandle = vehicle.Handle.Value;
logger.LogCritical("Vehicle handle {handle} already belongs to server vehicle {dbIdHandle}", dbIdHandle, dbId);
return;
}
var id = serverVehicle.Id;
var handle = vehicle.Handle.Value;
logger.LogInformation("Mapping server vehicle id {id} to vehicle {handle}", id, handle);
_serverVehicles[serverVehicle.Id] = vehicle.Handle.Value;
}
internal static void DeleteVehicle(Vehicle veh)
{
ServerVehicle sVeh;
if ((sVeh = GetServerVehicleFromVehicle(veh)) != null)
{
var id = sVeh.Id;
var handle = veh.Handle.Value;
logger.LogInformation("Deleting server vehicle {id} mapping to spawned veh {handle}", id, handle);
_serverVehicles.Remove(sVeh.Id);
}
veh?.Delete();
}
public static Vehicle GetVehicleFromHandle(ushort handle)
{
return NAPI.Pools.GetAllVehicles().Find(v => v.Handle.Value == handle);
}
public static Vehicle GetVehicleFromId(int id)
{
using (var dbcontext = new DatabaseContext())
{
ServerVehicle sVeh = dbcontext.ServerVehicles.Where(sV => sV.Id == id).FirstOrDefault();
return GetVehicleFromServerVehicle(sVeh);
}
}
public static Vehicle GetVehicleFromServerVehicle(ServerVehicle serverVehicle)
{
if (serverVehicle == null)
{
return null;
}
if (!_serverVehicles.ContainsKey(serverVehicle.Id))
{
return null;
}
return GetVehicleFromHandle(_serverVehicles[serverVehicle.Id]);
}
public static ServerVehicle GetServerVehicleFromVehicle(Vehicle veh, DatabaseContext dbContext = null)
{
if (veh == null)
{
return null;
}
dbContext = dbContext ?? new DatabaseContext();
foreach (KeyValuePair<int, ushort> pair in _serverVehicles)
{
if (pair.Value == veh.Handle.Value)
{
return dbContext.ServerVehicles.Find(pair.Key);
}
}
return null;
}
public static bool IsValidHash(uint hash)
{
foreach (VehicleHash vh in Enum.GetValues(typeof(VehicleHash)))
{
if ((uint)vh == hash) return true;
}
foreach (string mod in _enabledMods)
{
if (NAPI.Util.GetHashKey(mod) == hash) return true;
}
return false;
}
[ServerEvent(Event.VehicleDeath)]
public static void VehicleManagerVehicleDeath(Vehicle vehicle)
{
/*
String rentCarOwner = Rentcar.mapPlayerRentcarBill.FirstOrDefault(x => x.Value.Item1 == vehicle).Key;
ChatService.Broadcast("a:" + "");
if (rentCarOwner != null)
{
Player target = PlayerService.GetPlayerByNameOrId(rentCarOwner);
Rentcar.cancelRent(target);
}
*/
ServerVehicle serverVehicle = GetServerVehicleFromVehicle(vehicle);
if (serverVehicle == null)
{
vehicle.Delete();
return;
}
InventoryManager.RemoveAllItemsfromVehicleInventory(vehicle);
CheckVehicleDeath(vehicle.Id);
}
public static void CheckVehicleDeath(int id)
{
using (var dbContext = new DatabaseContext())
{
Vehicle vehicle = NAPI.Pools.GetAllVehicles().Find(v => v.Id == id);
ServerVehicle sV = vehicle.GetServerVehicle(dbContext);
if (sV is UserVehicle)
{
foreach (VehicleRespawnPoint point in VehicleRespawnPoints)
{
if (NAPI.Pools.GetAllVehicles().Any(v => v.Position.DistanceTo(point.Position) < 1))
{
ChatService.Broadcast("Fahrzeug zu nah");
}
else
{
sV.PositionX = point.Position.X;
sV.PositionY = point.Position.Y;
sV.PositionZ = point.Position.Z;
sV.Heading = point.Heading;
dbContext.SaveChanges();
break;
}
}
vehicle.Delete();
Vehicle newVeh = sV.Spawn(vehicle);
newVeh.Repair();
}
if (sV is FactionVehicle || sV is GroupVehicle)
{
vehicle.Delete();
Vehicle newVeh = sV.Spawn(vehicle);
newVeh.Repair();
}
}
}
[RemoteEvent("CLIENT:setMarkerBehindVehicle")]
public void setVectorBehindVehicle(Player player, int id, string jsonX, string jsonY, string jsonZ)
{
Vehicle vehicle = NAPI.Pools.GetAllVehicles().Find(v => v.Id == id);
Vector3 vector3 = new Vector3(Convert.ToSingle((double)JsonConvert.DeserializeObject(jsonX)), Convert.ToSingle((double)JsonConvert.DeserializeObject(jsonY)), Convert.ToSingle((double)JsonConvert.DeserializeObject(jsonZ)));
vehicle.AddMarkerBehind(vector3);
}
#region spawnpositions-vehicleInWater
public static List<VehicleRespawnPoint> VehicleRespawnPoints = new List<VehicleRespawnPoint> ();
VehicleRespawnPoint pos1 = new VehicleRespawnPoint()
{
Position = new Vector3(-307.84, -909.04, 31.07),
Heading = 167.46f
};
VehicleRespawnPoint pos2 = new VehicleRespawnPoint()
{
Position = new Vector3(-311.52, -908.40, 31.07),
Heading = 170.40f
};
VehicleRespawnPoint pos3 = new VehicleRespawnPoint()
{
Position = new Vector3(-315.18, -907.68, 31.07),
Heading = 167.17f
};
VehicleRespawnPoint pos4 = new VehicleRespawnPoint()
{
Position = new Vector3(-319.09, -906.68, 31.07),
Heading = 168.41f
};
VehicleRespawnPoint pos5 = new VehicleRespawnPoint()
{
Position = new Vector3(-322.48, -905.95, 31.07),
Heading = 169.00f
};
VehicleRespawnPoint pos6 = new VehicleRespawnPoint()
{
Position = new Vector3(-322.48, -905.95, 31.07),
Heading = 169.00f
};
VehicleRespawnPoint pos7 = new VehicleRespawnPoint()
{
Position = new Vector3(-325.95, -905.17, 31.07),
Heading = 168.26f
};
VehicleRespawnPoint pos8 = new VehicleRespawnPoint()
{
Position = new Vector3(-329.77, -904.33, 31.07),
Heading = 168.17f
};
VehicleRespawnPoint pos9 = new VehicleRespawnPoint()
{
Position = new Vector3(-333.31, -903.61, 31.07),
Heading = 169.17f
};
VehicleRespawnPoint pos10 = new VehicleRespawnPoint()
{
Position = new Vector3(-336.86, -902.80, 31.07),
Heading = 167.65f
};
VehicleRespawnPoint pos11 = new VehicleRespawnPoint()
{
Position = new Vector3(-340.41, -902.12, 31.07),
Heading = 162.65f
};
VehicleRespawnPoint pos12 = new VehicleRespawnPoint()
{
Position = new Vector3(-360.96, -893.13, 31.07),
Heading = -88.49f
};
VehicleRespawnPoint pos13 = new VehicleRespawnPoint()
{
Position = new Vector3(-360.80, -896.62, 31.07),
Heading = -88.13f
};
VehicleRespawnPoint pos14 = new VehicleRespawnPoint()
{
Position = new Vector3(-359.50, -944.78, 31.08),
Heading = -89.30f
};
VehicleRespawnPoint pos15 = new VehicleRespawnPoint()
{
Position = new Vector3(-361.17, -948.58, 31.08),
Heading = -85.58f
};
VehicleRespawnPoint pos16 = new VehicleRespawnPoint()
{
Position = new Vector3(-361.00, -952.27, 31.08),
Heading = -89.86f
};
VehicleRespawnPoint pos17 = new VehicleRespawnPoint()
{
Position = new Vector3(-360.99, -955.92, 31.08),
Heading = -87.21f
};
VehicleRespawnPoint pos18 = new VehicleRespawnPoint()
{
Position = new Vector3(-350.26, -972.01, 31.08),
Heading = -18.13f
};
VehicleRespawnPoint pos19 = new VehicleRespawnPoint()
{
Position = new Vector3(-346.58, -973.31, 31.08),
Heading = -19.79f
};
VehicleRespawnPoint pos20 = new VehicleRespawnPoint()
{
Position = new Vector3(-343.31, -974.59, 31.08),
Heading = -20.22f
};
/*
private readonly IReadOnlyCollection<Vector3> vector3s = new List<Vector3>
{
new Vector3(-343.31, -974.59, 31.08), //Heading -20.22
new Vector3(-339.67, -975.69, 31.08), //Heading -16.76
new Vector3(-336.38, -976.95, 31.08), //Heading -19.30
new Vector3(-332.50, -978.28, 31.08), //Heading -18.82
new Vector3(-329.48, -979.39, 31.08), //Heading -26.22
new Vector3(-325.96, -980.70, 31.08), //Heading -19.74
new Vector3(-360.85, -900.53, 31.07), //Heading -88.64
new Vector3(-360.71, -904.02, 31.07), //Heading -88.04
new Vector3(-360.56, -907.78, 31.07), //Heading -88.41
new Vector3(-360.41, -911.79, 31.08), //Heading -86.13
new Vector3(-360.30, -915.26, 31.08), //Heading -134.60
new Vector3(-360.12, -919.21, 31.08), //Heading -82.35
new Vector3(-360.03, -922.63, 31.08), //Heading -89.27
new Vector3(-359.78, -926.58, 31.08), //Heading -84.04
new Vector3(-359.73, -929.89, 31.08), //Heading -88.67
new Vector3(-359.66, -933.50, 31.08), //Heading -88.67
new Vector3(-359.54, -937.61, 31.08), //Heading -86.68
new Vector3(-359.48, -941.17, 31.08), //Heading -90.07
new Vector3(-336.84, -952.54, 31.08), //Heading 68.74
new Vector3(-355.55, -949.08, 31.08), //Heading 71.85
new Vector3(-334.47, -945.95, 31.08), //Heading 70.89
new Vector3(-333.11, -942.11, 31.08), //Heading 70.18
new Vector3(-331.90, -938.98, 31.08), //Heading 68.07
new Vector3(-330.65, -935.58, 31.08), //Heading 70.98
new Vector3(-329.24, -931.58, 31.08), //Heading 73.91
new Vector3(-328.12, -928.44, 31.08), //Heading 69.17
new Vector3(-326.67, -924.60, 31.08), //Heading 46.89
new Vector3(-322.36, -982.02, 31.08), //Heading -21.25059
new Vector3(-318.92, -983.19, 31.08), //Heading -20.580233
new Vector3(-315.42, -984.40, 31.08), //Heading -21.508415
new Vector3(-311.97, 985.60, 31.080), //Heading -20.866705
new Vector3(-308.43, -986.83, 31.08), //Heading -21.050055
new Vector3(-305.03, -988.07, 31.08), //Heading -21.021408
new Vector3(-301.48, -989.31, 31.08), //Heading -22.333475
new Vector3(-298.04, -990.48, 31.08), //Heading -26.02332
new Vector3(-342.30, -921.35, 31.0), //Heading-109.20534
new Vector3(-343.37, -925.01, 31.08), //Heading -111.86385
new Vector3(-344.68, -928.18, 31.08), //Heading -109.97883
new Vector3(-345.78, -931.86, 31.08), //Heading -110.89556
}.AsReadOnly();
*/
#endregion spawnpositions-vehicleInWater
[RemoteEvent("CheckWater")]
public static void CheckWater(Player player, int id)
{
CheckVehicleDeath(id);
}
}
}
public class VehicleRespawnPoint
{
public Vector3 Position { get; set; }
public float Heading { get; set; }
}