Aded vehicle sync system (engines now have to be tuned on /off with N key)
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
var chat = false;
|
||||
var showGui = true;
|
||||
|
||||
const player = mp.players.local;
|
||||
|
||||
//ENTER
|
||||
mp.keys.bind(0x0D, false, function () {
|
||||
if (chat === true) {
|
||||
@@ -66,6 +68,8 @@ mp.keys.bind(0x4C, false, function () {
|
||||
//N //Motor Starten
|
||||
mp.keys.bind(0x4E, false, function () {
|
||||
if (!chat) {
|
||||
if (!player.vehicle) return;
|
||||
if (player.vehicle.getSpeed() > 5) return;
|
||||
mp.events.callRemote("keyPress:N");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,6 +29,8 @@ require('./Player/keys.js');
|
||||
require('./Player/quit.js');
|
||||
require('./Player/freecam.js');
|
||||
|
||||
require('./vehiclesync/vehiclesync.js');
|
||||
|
||||
require('./Save/main.js');
|
||||
|
||||
require('./Speedometer/index.js');
|
||||
|
||||
532
Client/vehiclesync/vehiclesync.js
Normal file
532
Client/vehiclesync/vehiclesync.js
Normal file
@@ -0,0 +1,532 @@
|
||||
//Disapproved by the entire planet
|
||||
//You don't need to worry about anything here
|
||||
|
||||
mp.events.add("VehStream_SetEngineStatus", (veh, status) => {
|
||||
if (veh !== undefined) {
|
||||
if (veh.isSeatFree(-1)) //Turns engine on instantly if no driver, otherwise it will not turn on
|
||||
{
|
||||
veh.setEngineOn(status, true, false);
|
||||
veh.setUndriveable(true);
|
||||
}
|
||||
else {
|
||||
veh.setEngineOn(status, false, true);
|
||||
veh.setUndriveable(!status);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetLockStatus", (veh, status) => {
|
||||
if (veh !== undefined) {
|
||||
if (status)
|
||||
veh.setDoorsLocked(2);
|
||||
else
|
||||
veh.setDoorsLocked(1);
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_PlayerEnterVehicleAttempt", (entity, seat) => {
|
||||
if (typeof entity.getVariable("VehicleSyncData") !== 'undefined') {
|
||||
var toggle = entity.getVariable("VehicleSyncData");
|
||||
entity.setEngineOn(toggle.Engine, false, true);
|
||||
entity.setUndriveable(!toggle.Engine);
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_PlayerExitVehicleAttempt", (entity) => {
|
||||
if (entity !== undefined) {
|
||||
if (typeof entity.getVariable("VehicleSyncData") !== 'undefined') {
|
||||
var toggle = entity.getVariable("VehicleSyncData");
|
||||
entity.setEngineOn(toggle.Engine, true, false);
|
||||
entity.setUndriveable(!toggle.Engine);
|
||||
}
|
||||
|
||||
var level = entity.getDirtLevel();
|
||||
mp.events.callRemote("VehStream_SetDirtLevel", entity, level);
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_PlayerExitVehicle", (entity) => {
|
||||
setTimeout(() => {
|
||||
var Status = [];
|
||||
let y = 0;
|
||||
for (y = 0; y < 8; y++) {
|
||||
if (entity.isDoorDamaged(y)) {
|
||||
Status.push(2);
|
||||
}
|
||||
else if (entity.getDoorAngleRatio(y) > 0.15) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
mp.events.callRemote("VehStream_SetDoorData", entity, Status[0], Status[1], Status[2], Status[3], Status[4], Status[5], Status[6], Status[7]);
|
||||
|
||||
Status = [];
|
||||
if (entity.isWindowIntact(0)) {
|
||||
if (entity.getBoneIndexByName("window_rf") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
if (entity.isWindowIntact(1)) {
|
||||
if (entity.getBoneIndexByName("window_lf") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
if (entity.isWindowIntact(2)) {
|
||||
if (entity.getBoneIndexByName("window_rr") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
if (entity.isWindowIntact(3)) {
|
||||
if (entity.getBoneIndexByName("window_lr") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
mp.events.callRemote("VehStream_SetWindowData", entity, Status[0], Status[1], Status[2], Status[3]);
|
||||
|
||||
Status = [];
|
||||
if (!entity.isTyreBurst(0, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(0, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(1, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(1, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(2, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(2, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(3, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(3, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(4, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(4, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(5, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(5, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(6, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(6, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(7, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(7, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(45, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(45, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
if (!entity.isTyreBurst(47, false)) {
|
||||
Status.push(0);
|
||||
}
|
||||
else if (entity.isTyreBurst(47, false)) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
|
||||
mp.events.callRemote("VehStream_SetWheelData", entity, Status[0], Status[1], Status[2], Status[3], Status[4], Status[5], Status[6], Status[7], Status[8], Status[9]);
|
||||
}, 2500);
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_PlayerEnterVehicleAttempt", (entity, seat) => {
|
||||
setTimeout(() => {
|
||||
var Status = [];
|
||||
let y = 0;
|
||||
for (y = 0; y < 8; y++) {
|
||||
if (entity.isDoorDamaged(y)) {
|
||||
Status.push(2);
|
||||
}
|
||||
else if (entity.getDoorAngleRatio(y) > 0.15) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
//mp.events.callRemote("VehStream_SetDoorData", entity, Status[0], Status[1], Status[2], Status[3], Status[4], Status[5], Status[6], Status[7]);
|
||||
|
||||
Status = [];
|
||||
if (entity.isWindowIntact(0)) {
|
||||
if (entity.getBoneIndexByName("window_rf") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
if (entity.isWindowIntact(1)) {
|
||||
if (entity.getBoneIndexByName("window_lf") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
if (entity.isWindowIntact(2)) {
|
||||
if (entity.getBoneIndexByName("window_rr") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
if (entity.isWindowIntact(3)) {
|
||||
if (entity.getBoneIndexByName("window_lr") === -1) {
|
||||
Status.push(1);
|
||||
}
|
||||
else {
|
||||
Status.push(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Status.push(2);
|
||||
}
|
||||
mp.events.callRemote("VehStream_SetWindowData", entity, Status[0], Status[1], Status[2], Status[3]);
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleDirtLevel", (entity, dirt) => {
|
||||
if (entity !== undefined) {
|
||||
entity.setDirtLevel(dirt);
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleDoorStatus_Single", (veh, door, state) => {
|
||||
if (veh !== undefined) {
|
||||
if (state === 0) {
|
||||
veh.setDoorShut(door, false);
|
||||
}
|
||||
else if (state === 1) {
|
||||
veh.setDoorOpen(door, false, false);
|
||||
}
|
||||
else {
|
||||
veh.setDoorBroken(door, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleDoorStatus", (...args) => {
|
||||
if (args[0] !== undefined) {
|
||||
let y = 0;
|
||||
for (y = 1; y < args.length; y++) {
|
||||
if (args[y] === 0) {
|
||||
args[0].setDoorShut(y - 1, false);
|
||||
}
|
||||
else if (args[y] === 1) {
|
||||
args[0].setDoorOpen(y - 1, false, false);
|
||||
}
|
||||
else {
|
||||
args[0].setDoorBroken(y - 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleWindowStatus_Single", (veh, windw, state) => {
|
||||
if (veh !== undefined) {
|
||||
if (state === 1) {
|
||||
veh.rollDownWindow(windw);
|
||||
}
|
||||
else if (state === 0) {
|
||||
veh.fixWindow(windw);
|
||||
veh.rollUpWindow(windw);
|
||||
}
|
||||
else {
|
||||
veh.smashWindow(windw);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleWindowStatus", (...args) => {
|
||||
if (args[0] !== undefined) {
|
||||
let y = 0;
|
||||
for (y = 1; y < 4; y++) {
|
||||
if (args[y] === 1) {
|
||||
args[0].rollDownWindow(y - 1);
|
||||
}
|
||||
else if (args[y] === 0) {
|
||||
args[0].fixWindow(y - 1);
|
||||
args[0].rollUpWindow(y - 1);
|
||||
}
|
||||
else {
|
||||
args[0].smashWindow(y - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleWheelStatus_Single", (veh, wheel, state) => {
|
||||
if (veh !== undefined) {
|
||||
if (wheel === 9) {
|
||||
if (state === 1) {
|
||||
veh.setTyreBurst(45, false, 1000);
|
||||
}
|
||||
else if (state === 0) {
|
||||
veh.setTyreFixed(45);
|
||||
}
|
||||
else {
|
||||
veh.setTyreBurst(45, true, 1000);
|
||||
}
|
||||
}
|
||||
else if (wheel === 10) {
|
||||
if (state === 1) {
|
||||
veh.setTyreBurst(47, false, 1000);
|
||||
}
|
||||
else if (state === 0) {
|
||||
veh.setTyreFixed(47);
|
||||
}
|
||||
else {
|
||||
veh.setTyreBurst(47, true, 1000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (state === 1) {
|
||||
veh.setTyreBurst(wheel, false, 1000);
|
||||
}
|
||||
else if (state === 0) {
|
||||
veh.setTyreFixed(wheel);
|
||||
}
|
||||
else {
|
||||
veh.setTyreBurst(wheel, true, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mp.events.add("VehStream_SetVehicleWheelStatus", (...args) => {
|
||||
if (args[0] !== undefined) {
|
||||
let y = 0;
|
||||
for (y = 1; y < args.length; y++) {
|
||||
if (y === 9) {
|
||||
if (args[y] === 1) {
|
||||
args[0].setTyreBurst(45, false, 1000);
|
||||
}
|
||||
else if (args[y] === 0) {
|
||||
args[0].setTyreFixed(45);
|
||||
}
|
||||
else {
|
||||
args[0].setTyreBurst(45, true, 1000);
|
||||
}
|
||||
}
|
||||
else if (y === 10) {
|
||||
if (args[y] === 1) {
|
||||
args[0].setTyreBurst(47, false, 1000);
|
||||
}
|
||||
else if (args[y] === 0) {
|
||||
args[0].setTyreFixed(47);
|
||||
}
|
||||
else {
|
||||
args[0].setTyreBurst(47, true, 1000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (args[y] === 1) {
|
||||
args[0].setTyreBurst(y - 1, false, 1000);
|
||||
}
|
||||
else if (args[y] === 0) {
|
||||
args[0].setTyreFixed(y - 1);
|
||||
}
|
||||
else {
|
||||
args[0].setTyreBurst(y - 1, true, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Sync data on stream in
|
||||
mp.events.add("entityStreamIn", (entity) => {
|
||||
if (entity.type === "vehicle") {
|
||||
let typeor = typeof entity.getVariable('VehicleSyncData');
|
||||
let actualData = entity.getVariable('VehicleSyncData');
|
||||
|
||||
//Needed to stop vehicles from freaking out
|
||||
mp.game.streaming.requestCollisionAtCoord(entity.position.x, entity.position.y, entity.position.z);
|
||||
//mp.game.invoke('0x199640F55E0F7596', entity.position.x, entity.position.y, entity.position.z);
|
||||
entity.setLoadCollisionFlag(true);
|
||||
entity.trackVisibility();
|
||||
|
||||
if (typeor !== 'undefined' && entity.isSeatFree(-1)) //Only if there is no driver
|
||||
{
|
||||
entity.position = actualData.Position;
|
||||
entity.rotation = actualData.Rotation;
|
||||
}
|
||||
|
||||
//Set doors unbreakable for a moment
|
||||
let x = 0;
|
||||
for (x = 0; x < 8; x++) {
|
||||
entity.setDoorBreakable(x, false);
|
||||
}
|
||||
|
||||
//Do it anyway
|
||||
entity.setUndriveable(true);
|
||||
|
||||
if (typeor !== 'undefined') {
|
||||
entity.setEngineOn(actualData.Engine, true, false);
|
||||
entity.setUndriveable(true);
|
||||
|
||||
if (actualData.Locked)
|
||||
entity.setDoorsLocked(2);
|
||||
else
|
||||
entity.setDoorsLocked(1);
|
||||
|
||||
entity.setDirtLevel(actualData.Dirt);
|
||||
|
||||
for (x = 0; x < 8; x++) {
|
||||
if (actualData.Door[x] === 1)
|
||||
entity.setDoorOpen(x, false, false);
|
||||
else if (actualData.Door[x] === 0)
|
||||
entity.setDoorShut(x, true);
|
||||
else
|
||||
entity.setDoorBroken(x, true);
|
||||
}
|
||||
|
||||
for (x = 0; x < 4; x++) {
|
||||
if (actualData.Window[x] === 0) {
|
||||
entity.fixWindow(x);
|
||||
}
|
||||
else if (actualData.Window[x] === 1) {
|
||||
entity.rollDownWindow(x);
|
||||
}
|
||||
else {
|
||||
entity.smashWindow(x);
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < 8; x++) {
|
||||
if (actualData.Wheel[x] === 0) {
|
||||
entity.setTyreFixed(x);
|
||||
}
|
||||
else if (actualData.Wheel[x] === 1) {
|
||||
entity.setTyreBurst(x, false, 0);
|
||||
}
|
||||
else {
|
||||
entity.setTyreBurst(x, true, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
//For trailer mid wheels
|
||||
if (actualData.Wheel[8] === 0) {
|
||||
entity.setTyreFixed(45);
|
||||
}
|
||||
else if (actualData.Wheel[8] === 1) {
|
||||
entity.setTyreBurst(45, false, 0);
|
||||
}
|
||||
else {
|
||||
entity.setTyreBurst(45, true, 1000);
|
||||
}
|
||||
|
||||
if (actualData.Wheel[9] === 0) {
|
||||
entity.setTyreFixed(47);
|
||||
}
|
||||
else if (actualData.Wheel[9] === 1) {
|
||||
entity.setTyreBurst(47, false, 0);
|
||||
}
|
||||
else {
|
||||
entity.setTyreBurst(47, true, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
//Make doors breakable again
|
||||
setTimeout(() => {
|
||||
for (x = 0; x < 8; x++) {
|
||||
entity.setDoorBreakable(x, true);
|
||||
}
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
@@ -784,6 +784,14 @@ namespace reallife_gamemode.Server.Commands
|
||||
|
||||
|
||||
#region ALevel3
|
||||
Vehicle testV;
|
||||
|
||||
[Command]
|
||||
public void Testveh(Client player)
|
||||
{
|
||||
player.SendChatMessage(VehicleStreaming.GetEngineState(player.Vehicle).ToString());
|
||||
}
|
||||
|
||||
[Command("veh", "~m~Benutzung: ~s~/veh [Fahrzeug] (Farbe 1) (Farbe 2)")]
|
||||
public void CmdAdminVeh(Client player, string hash, int color1 = 111, int color2 = 111)
|
||||
{
|
||||
@@ -808,7 +816,9 @@ namespace reallife_gamemode.Server.Commands
|
||||
return;
|
||||
}
|
||||
|
||||
Vehicle v = NAPI.Vehicle.CreateVehicle(uHash, player.Position, player.Rotation.Z, color1, color2);
|
||||
Vehicle v = testV = NAPI.Vehicle.CreateVehicle(uHash, player.Position, player.Rotation.Z, color1, color2, engine: false);
|
||||
VehicleStreaming.SetEngineState(v, true);
|
||||
VehicleStreaming.SetLockStatus(v, false);
|
||||
player.SetIntoVehicle(v.Handle, -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using GTANetworkAPI;
|
||||
using reallife_gamemode.Model;
|
||||
using reallife_gamemode.Server.Extensions;
|
||||
using reallife_gamemode.Server.Managers;
|
||||
using reallife_gamemode.Server.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
@@ -34,6 +36,8 @@ namespace reallife_gamemode.Server.Entities
|
||||
{
|
||||
if (currentVeh != null) VehicleManager.DeleteVehicle(currentVeh);
|
||||
Vehicle veh = NAPI.Vehicle.CreateVehicle(this.Model, this.Position, this.Heading, this.PrimaryColor, this.SecondaryColor, this.NumberPlate, locked: this.Locked, engine: false);
|
||||
VehicleStreaming.SetEngineState(veh, false);
|
||||
VehicleStreaming.SetLockStatus(veh, false);
|
||||
VehicleManager.AddVehicle(this, veh);
|
||||
|
||||
string numberplate = $"{this.Id}";
|
||||
|
||||
@@ -112,10 +112,12 @@ namespace reallife_gamemode.Server.Events
|
||||
|
||||
foreach(Client listPlayer in players)
|
||||
{
|
||||
var lPlayer = new ListPlayer();
|
||||
lPlayer.Id = listPlayer.Handle.Value;
|
||||
lPlayer.Name = listPlayer.Name;
|
||||
lPlayer.Ping = listPlayer.Ping;
|
||||
var lPlayer = new ListPlayer
|
||||
{
|
||||
Id = listPlayer.Handle.Value,
|
||||
Name = listPlayer.Name,
|
||||
Ping = listPlayer.Ping
|
||||
};
|
||||
|
||||
ListPlayers.Add(lPlayer);
|
||||
}
|
||||
@@ -183,7 +185,8 @@ namespace reallife_gamemode.Server.Events
|
||||
{
|
||||
if (player.IsInVehicle && player.VehicleSeat == -1)
|
||||
{
|
||||
player.Vehicle.EngineStatus = !player.Vehicle.EngineStatus;
|
||||
Vehicle v = player.Vehicle;
|
||||
VehicleStreaming.SetEngineState(v, !VehicleStreaming.GetEngineState(v));
|
||||
}
|
||||
}
|
||||
[RemoteEvent("keyPress:X")]
|
||||
|
||||
444
Server/Util/VehicleSync.cs
Normal file
444
Server/Util/VehicleSync.cs
Normal file
@@ -0,0 +1,444 @@
|
||||
using GTANetworkAPI;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
//Disapproved by god himself
|
||||
|
||||
//Just use the API functions, you have nothing else to worry about
|
||||
|
||||
//Things to note
|
||||
//More things like vehicle mods will be added in the next version
|
||||
|
||||
/* API FUNCTIONS:
|
||||
public static void SetVehicleWindowState(Vehicle veh, WindowID window, WindowState state)
|
||||
public static WindowState GetVehicleWindowState(Vehicle veh, WindowID window)
|
||||
public static void SetVehicleWheelState(Vehicle veh, WheelID wheel, WheelState state)
|
||||
public static WheelState GetVehicleWheelState(Vehicle veh, WheelID wheel)
|
||||
public static void SetVehicleDirt(Vehicle veh, float dirt)
|
||||
public static float GetVehicleDirt(Vehicle veh)
|
||||
public static void SetDoorState(Vehicle veh, DoorID door, DoorState state)
|
||||
public static DoorState GetDoorState(Vehicle veh, DoorID door)
|
||||
public static void SetEngineState(Vehicle veh, bool status)
|
||||
public static bool GetEngineState(Vehicle veh)
|
||||
public static void SetLockStatus(Vehicle veh, bool status)
|
||||
public static bool GetLockState(Vehicle veh)
|
||||
*/
|
||||
|
||||
namespace reallife_gamemode.Server.Util
|
||||
{
|
||||
//Enums for ease of use
|
||||
public enum WindowID
|
||||
{
|
||||
WindowFrontRight,
|
||||
WindowFrontLeft,
|
||||
WindowRearRight,
|
||||
WindowRearLeft
|
||||
}
|
||||
|
||||
public enum WindowState
|
||||
{
|
||||
WindowFixed,
|
||||
WindowDown,
|
||||
WindowBroken
|
||||
}
|
||||
|
||||
public enum DoorID
|
||||
{
|
||||
DoorFrontLeft,
|
||||
DoorFrontRight,
|
||||
DoorRearLeft,
|
||||
DoorRearRight,
|
||||
DoorHood,
|
||||
DoorTrunk
|
||||
}
|
||||
|
||||
public enum DoorState
|
||||
{
|
||||
DoorClosed,
|
||||
DoorOpen,
|
||||
DoorBroken,
|
||||
}
|
||||
|
||||
public enum WheelID
|
||||
{
|
||||
Wheel0,
|
||||
Wheel1,
|
||||
Wheel2,
|
||||
Wheel3,
|
||||
Wheel4,
|
||||
Wheel5,
|
||||
Wheel6,
|
||||
Wheel7,
|
||||
Wheel8,
|
||||
Wheel9
|
||||
}
|
||||
|
||||
public enum WheelState
|
||||
{
|
||||
WheelFixed,
|
||||
WheelBurst,
|
||||
WheelOnRim,
|
||||
}
|
||||
|
||||
public class VehicleStreaming : Script
|
||||
{
|
||||
//This is the data object which will be synced to vehicles
|
||||
public class VehicleSyncData
|
||||
{
|
||||
//Used to bypass some streaming bugs
|
||||
public Vector3 Position { get; set; } = new Vector3();
|
||||
public Vector3 Rotation { get; set; } = new Vector3();
|
||||
|
||||
//Basics
|
||||
public float Dirt { get; set; } = 0.0f;
|
||||
public bool Locked { get; set; } = true;
|
||||
public bool Engine { get; set; } = false;
|
||||
|
||||
//(Not synced)
|
||||
public float BodyHealth { get; set; } = 1000.0f;
|
||||
public float EngineHealth { get; set; } = 1000.0f;
|
||||
|
||||
//Doors 0-7 (0 = closed, 1 = open, 2 = broken) (This uses enums so don't worry about it)
|
||||
public int[] Door { get; set; } = new int[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
//Windows (0 = up, 1 = down, 2 = smashed) (This uses enums so don't worry about it)
|
||||
public int[] Window { get; set; } = new int[4] { 0, 0, 0, 0 };
|
||||
|
||||
//Wheels 0-7, 45/47 (0 = fixed, 1 = flat, 2 = missing) (This uses enums so don't worry about it)
|
||||
public int[] Wheel { get; set; } = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
//API functions for people to use
|
||||
public static void SetVehicleWindowState(Vehicle veh, WindowID window, WindowState state)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData)) //If data doesn't exist create a new one. This is the process for all API functions
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Window[(int)window] = (int)state;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleWindowStatus_Single", veh.Handle, (int)window, (int)state);
|
||||
}
|
||||
|
||||
public static WindowState GetVehicleWindowState(Vehicle veh, WindowID window)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
{
|
||||
data = new VehicleSyncData();
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
}
|
||||
return (WindowState)data.Window[(int)window];
|
||||
}
|
||||
|
||||
public static void SetVehicleWheelState(Vehicle veh, WheelID wheel, WheelState state)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Wheel[(int)wheel] = (int)state;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleWheelStatus_Single", veh.Handle, (int)wheel, (int)state);
|
||||
}
|
||||
|
||||
public static WheelState GetVehicleWheelState(Vehicle veh, WheelID wheel)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
{
|
||||
data = new VehicleSyncData();
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
}
|
||||
return (WheelState)data.Wheel[(int)wheel];
|
||||
}
|
||||
|
||||
public static void SetVehicleDirt(Vehicle veh, float dirt)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Dirt = dirt;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleDirtLevel", veh.Handle, dirt);
|
||||
}
|
||||
|
||||
public static float GetVehicleDirt(Vehicle veh)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
{
|
||||
data = new VehicleSyncData();
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
}
|
||||
return data.Dirt;
|
||||
}
|
||||
|
||||
public static void SetDoorState(Vehicle veh, DoorID door, DoorState state)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Door[(int)door] = (int)state;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleDoorStatus_Single", veh, (int)door, (int)state);
|
||||
}
|
||||
|
||||
public static DoorState GetDoorState(Vehicle veh, DoorID door)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
{
|
||||
data = new VehicleSyncData();
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
}
|
||||
return (DoorState)data.Door[(int)door];
|
||||
}
|
||||
|
||||
public static void SetEngineState(Vehicle veh, bool status)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Engine = status;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetEngineStatus", veh, status);
|
||||
}
|
||||
|
||||
public static bool GetEngineState(Vehicle veh)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
{
|
||||
data = new VehicleSyncData();
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
}
|
||||
return data.Engine;
|
||||
}
|
||||
|
||||
public static void SetLockStatus(Vehicle veh, bool status)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Locked = status;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetLockStatus", veh, status);
|
||||
}
|
||||
|
||||
public static bool GetLockState(Vehicle veh)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
{
|
||||
data = new VehicleSyncData();
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
}
|
||||
return data.Locked;
|
||||
}
|
||||
|
||||
//Used internally only but publicly available in case any of you need it
|
||||
public static VehicleSyncData GetVehicleSyncData(Vehicle veh)
|
||||
{
|
||||
if (veh != null)
|
||||
{
|
||||
if (NAPI.Entity.DoesEntityExist(veh))
|
||||
{
|
||||
if (NAPI.Data.HasEntitySharedData(veh.Handle, "VehicleSyncData"))
|
||||
{
|
||||
//API converts class objects to JObject so we have to change it back
|
||||
JObject obj = NAPI.Data.GetEntitySharedData(veh.Handle, "VehicleSyncData");
|
||||
return obj.ToObject<VehicleSyncData>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default(VehicleSyncData); //null
|
||||
}
|
||||
|
||||
//Used internally only but publicly available in case any of you need it
|
||||
public static bool UpdateVehicleSyncData(Vehicle veh, VehicleSyncData data)
|
||||
{
|
||||
if (veh != null)
|
||||
{
|
||||
if (NAPI.Entity.DoesEntityExist(veh))
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
data.Position = veh.Position;
|
||||
data.Rotation = veh.Rotation;
|
||||
NAPI.Data.SetEntitySharedData(veh, "VehicleSyncData", data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Called from the client to sync dirt level
|
||||
[RemoteEvent("VehStream_SetDirtLevel")]
|
||||
public void VehStreamSetDirtLevel(Client player, Vehicle veh, float dirt)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Dirt = dirt;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
|
||||
//Re-distribute the goods
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleDirtLevel", veh.Handle, dirt);
|
||||
}
|
||||
|
||||
//Called from the client to sync door data
|
||||
[RemoteEvent("VehStream_SetDoorData")]
|
||||
public void VehStreamSetDoorData(Client player, Vehicle veh, int door1state, int door2state, int door3state, int door4state, int door5state, int door6state, int door7state, int door8state)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Door[0] = door1state;
|
||||
data.Door[1] = door2state;
|
||||
data.Door[2] = door3state;
|
||||
data.Door[3] = door4state;
|
||||
data.Door[4] = door5state;
|
||||
data.Door[5] = door6state;
|
||||
data.Door[6] = door7state;
|
||||
data.Door[7] = door8state;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
|
||||
//Re-distribute the goods
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleDoorStatus", veh.Handle, door1state, door2state, door3state, door4state, door5state, door6state, door7state, door8state);
|
||||
}
|
||||
|
||||
//Called from the client to sync window data
|
||||
[RemoteEvent("VehStream_SetWindowData")]
|
||||
public void VehStreamSetWindowData(Client player, Vehicle veh, int window1state, int window2state, int window3state, int window4state)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Window[0] = window1state;
|
||||
data.Window[1] = window2state;
|
||||
data.Window[2] = window3state;
|
||||
data.Window[3] = window4state;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
|
||||
//Re-distribute the goods
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleWindowStatus", veh.Handle, window1state, window2state, window3state, window4state);
|
||||
}
|
||||
|
||||
//Called from the client to sync wheel data
|
||||
[RemoteEvent("VehStream_SetWheelData")]
|
||||
public void VehStreamSetWheelData(Client player, Vehicle veh, int wheel1state, int wheel2state, int wheel3state, int wheel4state, int wheel5state, int wheel6state, int wheel7state, int wheel8state, int wheel9state, int wheel10state)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Wheel[0] = wheel1state;
|
||||
data.Wheel[1] = wheel2state;
|
||||
data.Wheel[2] = wheel3state;
|
||||
data.Wheel[3] = wheel4state;
|
||||
data.Wheel[4] = wheel5state;
|
||||
data.Wheel[5] = wheel6state;
|
||||
data.Wheel[6] = wheel7state;
|
||||
data.Wheel[7] = wheel8state;
|
||||
data.Wheel[8] = wheel9state;
|
||||
data.Wheel[9] = wheel10state;
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
|
||||
//Re-distribute the goods
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleWheelStatus", veh.Handle, wheel1state, wheel2state, wheel3state, wheel4state, wheel5state, wheel6state, wheel7state, wheel8state, wheel9state, wheel10state);
|
||||
}
|
||||
|
||||
//Other events
|
||||
[ServerEvent(Event.PlayerEnterVehicleAttempt)]
|
||||
public void VehStreamEnterAttempt(Client player, Vehicle veh, sbyte seat)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEvent(player, "VehStream_PlayerEnterVehicleAttempt", veh, seat);
|
||||
}
|
||||
|
||||
[ServerEvent(Event.PlayerExitVehicleAttempt)]
|
||||
public void VehStreamExitAttempt(Client player, Vehicle veh)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Position = veh.Position;
|
||||
data.Rotation = veh.Rotation;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEvent(player, "VehStream_PlayerExitVehicleAttempt", veh);
|
||||
}
|
||||
|
||||
[ServerEvent(Event.PlayerExitVehicle)]
|
||||
public void VehStreamExit(Client player, Vehicle veh)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Position = veh.Position;
|
||||
data.Rotation = veh.Rotation;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEvent(player, "VehStream_PlayerExitVehicle", veh);
|
||||
}
|
||||
|
||||
[ServerEvent(Event.PlayerEnterVehicle)]
|
||||
public void VehStreamEnter(Client player, Vehicle veh, sbyte seat)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
NAPI.ClientEvent.TriggerClientEvent(player, "VehStream_PlayerEnterVehicle", veh, seat);
|
||||
}
|
||||
|
||||
[ServerEvent(Event.VehicleDamage)]
|
||||
public void VehDamage(Vehicle veh, float bodyHealthLoss, float engineHealthLoss)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.BodyHealth -= bodyHealthLoss;
|
||||
data.EngineHealth -= engineHealthLoss;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
|
||||
if (NAPI.Vehicle.GetVehicleDriver(veh) != default(Client)) //Doesn't work?
|
||||
NAPI.ClientEvent.TriggerClientEvent(NAPI.Vehicle.GetVehicleDriver(veh), "VehStream_PlayerExitVehicleAttempt", veh);
|
||||
}
|
||||
|
||||
[ServerEvent(Event.VehicleDoorBreak)]
|
||||
public void VehDoorBreak(Vehicle veh, int index)
|
||||
{
|
||||
VehicleSyncData data = GetVehicleSyncData(veh);
|
||||
if (data == default(VehicleSyncData))
|
||||
data = new VehicleSyncData();
|
||||
|
||||
data.Door[index] = 2;
|
||||
|
||||
UpdateVehicleSyncData(veh, data);
|
||||
|
||||
NAPI.ClientEvent.TriggerClientEventInDimension(veh.Dimension, "VehStream_SetVehicleDoorStatus", veh.Handle, data.Door[0], data.Door[1], data.Door[2], data.Door[3], data.Door[4], data.Door[5], data.Door[6], data.Door[7]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user