Merge dev into inventory

This commit is contained in:
VegaZ
2018-12-10 21:29:10 +01:00
14 changed files with 1126 additions and 15 deletions

View File

@@ -5,9 +5,12 @@ before_script:
- "../gm_database_password.sh"
- "dotnet restore"
variables:
GIT_STRATEGY: clone
build:
stage: build
only:
- develop
- develop@log-gtav/reallife-gamemode
script:
- "dotnet build -c ServerBuild"

View File

@@ -10,6 +10,8 @@ var chat = false;
var showInventory = false;
var showGui = true;
const player = mp.players.local;
//ENTER
mp.keys.bind(0x0D, false, function () {
if (chat === true) {
@@ -74,6 +76,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");
}
});

View File

@@ -194,7 +194,7 @@ mp.events.add("showTuningMenu", () => {
var menuItem = new UIMenuItem(slotName);
if(localVehicle.getNumMods(modType) !== 0) mainMenu.AddItem(menuItem);
if(localVehicle.getNumMods(modType) !== 0 || modType === 18 || modType === 22) mainMenu.AddItem(menuItem);
}
});
@@ -217,9 +217,15 @@ mp.events.add("showTuningMenu", () => {
}
var currentMod = localVehicle.getMod(modSlot);
var oldToggleValue;
if (modSlot === 18 || modSlot === 22) {
oldToggleValue = localVehicle.isToggleModOn(modSlot);
currentMod = oldToggleValue ? 0 : -1;
}
var currentModItem;
var modNum = localVehicle.getNumMods(modSlot);
if (modSlot === 18 || modSlot === 22) modNum = 1;
modMenu = new Menu(item.Text, "Änderung: " + item.Text, new Point(50, 50));
@@ -230,6 +236,10 @@ mp.events.add("showTuningMenu", () => {
modItem = new UIMenuItem("Serie", "");
} else {
var modName = getModName(localVehicle, modSlot, i);
if (modSlot === 18) modName = "Turbolader";
if (modSlot === 22) modName = "Xenon-Licht";
modItem = new UIMenuItem(modName, "");
}
@@ -251,11 +261,21 @@ mp.events.add("showTuningMenu", () => {
currentModItem = selectedItem;
}
mp.events.callRemote("setVehicleMod", modSlot, index);
if (modSlot === 18 || modSlot === 22) {
oldToggleValue = index === 0 ? false : true;
return;
}
if (index === 0) index = -1;
currentMod = index - 1;
});
modMenu.IndexChange.on((index) => {
if (modSlot === 18 || modSlot === 22) {
localVehicle.toggleMod(modSlot, index === 0 ? false : true);
return;
}
if (index === 0) index = -1;
localVehicle.setMod(modSlot, index - 1);
});
@@ -269,8 +289,6 @@ mp.events.add("showTuningMenu", () => {
localVehicle.setDoorShut(door, false);
}
localVehicle.setMod(modSlot, currentMod);
if (closeMenu) {
closeMenu = false;
return;
@@ -278,6 +296,13 @@ mp.events.add("showTuningMenu", () => {
mainMenu.Visible = true;
modMenu.Visible = false;
if (modSlot === 18 || modSlot === 22) {
oldToggleValue = (oldToggleValue === false) ? 0 : 1;
localVehicle.toggleMod(modSlot, oldToggleValue === 0 ? false : true);
return;
}
localVehicle.setMod(modSlot, currentMod);
});
mainMenu.Visible = false;
@@ -292,7 +317,9 @@ mp.events.add("showTuningMenu", () => {
});
mp.events.add("playerLeaveVehicle", () => {
if (keyBound) {
mp.events.call("hideTuningInfo", true);
}
});
function getSlotName(slot) {

View File

@@ -0,0 +1,15 @@
mp.keys.bind(0x42, true, _ => {
mp.events.callRemote("keyPress:B:toggleSiren");
});
mp.events.add('toggleVehicleSiren', (vehicle, state) => {
vehicle.setSirenSound(state);
});
mp.events.add('entityStreamIn', (entity) => {
if (entity.isAVehicle()) {
var state = entity.getVariable("sirenSound");
if (state === undefined) return;
entity.setSirenSound(state);
}
});

View File

@@ -1,4 +1,18 @@
mp.events.add('entityStreamIn', (entity) => {
mp.gui.chat.push("streamed in:");
mp.gui.chat.push(entity.Model);
if (entity.isAVehicle()) {
var mod18 = entity.getVariable('mod18');
var mod22 = entity.getVariable('mod22');
if (mod18 !== undefined) {
entity.toggleMod(18, mod18);
}
if (mod22 !== undefined) {
entity.toggleMod(22, mod22);
}
}
});
mp.events.add('vehicleToggleMod', (veh, slot, newval) => {
veh.toggleMod(slot, newval);
});

View File

@@ -30,11 +30,14 @@ require('./Player/keys.js');
require('./Player/quit.js');
require('./Player/freecam.js');
require('./vehiclesync/vehiclesync.js');
require('./Save/main.js');
require('./Speedometer/index.js');
require('./Tuning/main.js');
require('./Tuning/sync.js');
require('./Tuning/sirensilence.js');
require('./Business/main.js');

View 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);
}
});

View File

@@ -35,10 +35,17 @@ namespace reallife_gamemode
NAPI.Server.SetAutoRespawnAfterDeath(false);
NAPI.Data.SetWorldData("playerCreatorDimension", 0);
InventoryManager.LoadItems();
TuningManager.AddTuningGarage(new Vector3(-341, -134, 38.5));
TuningManager.AddTuningGarage(new Vector3(732, -1088, 21));
TuningManager.AddTuningGarage(new Vector3(-1155, -2006, 12));
TuningManager.AddTuningGarage(new Vector3(-341, -134, 38.5)); // Downtown LS
TuningManager.AddTuningGarage(new Vector3(732, -1088, 21)); // LS Intersection
TuningManager.AddTuningGarage(new Vector3(-1155, -2006, 12)); // LS Airport
TuningManager.AddTuningGarage(new Vector3(110, 6628, 31)); // Paleto Bay
TuningManager.AddTuningGarage(new Vector3(1175, 2639, 37)); // Route 69
TimeManager.StartTimeManager();
DatabaseHelper.InitDatabaseFirstTime();

View File

@@ -854,6 +854,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)
{
@@ -878,7 +886,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);
}

View File

@@ -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}";

View File

@@ -122,10 +122,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);
}
@@ -196,7 +198,8 @@ namespace reallife_gamemode.Server.Events
if (!player.IsLoggedIn()) return;
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")]

26
Server/Events/Siren.cs Normal file
View File

@@ -0,0 +1,26 @@
using GTANetworkAPI;
using System;
using System.Collections.Generic;
using System.Text;
namespace reallife_gamemode.Server.Events
{
class Siren : Script
{
private Dictionary<NetHandle, bool> _sirenStates = new Dictionary<NetHandle, bool>();
[RemoteEvent("keyPress:B:toggleSiren")]
public void ToggleSirenEvent(Client player)
{
if (!player.IsInVehicle || player.VehicleSeat != -1) return;
Vehicle pV = player.Vehicle;
bool oldValue = _sirenStates.ContainsKey(pV.Handle) ? _sirenStates[pV.Handle] : false;
bool newValue = !oldValue;
_sirenStates[pV.Handle] = newValue;
pV.SetSharedData("sirenSound", newValue);
NAPI.ClientEvent.TriggerClientEventForAll("toggleVehicleSiren", pV, newValue);
}
}
}

View File

@@ -45,10 +45,18 @@ namespace reallife_gamemode.Server.Managers
Vehicle veh = VehicleManager.GetVehicleFromServerVehicle(sVeh);
if (veh == null) return;
using(var dbContext = new DatabaseContext())
veh.SetSharedData("mod18", false);
veh.SetSharedData("mod22", false);
using (var dbContext = new DatabaseContext())
{
foreach(VehicleMod vMod in dbContext.VehicleMods.ToList().FindAll(vM => vM.ServerVehicleId == sVeh.Id))
{
if(vMod.Slot == 18 || vMod.Slot == 22)
{
veh.SetSharedData("mod" + vMod.Slot, true);
}
veh.SetMod(vMod.Slot, vMod.ModId - 1);
}
}
@@ -72,8 +80,19 @@ namespace reallife_gamemode.Server.Managers
[RemoteEvent("setVehicleMod")]
public void SetVehicleMod(Client player, int slot, int index)
{
Vehicle pV = player.Vehicle;
if (index == 0) index--;
player.Vehicle.SetMod(slot, index - 1);
if(slot != 18 && slot != 22)
{
pV.SetMod(slot, index - 1);
}
else
{
bool newVal = index == -1 ? false : true;
pV.SetSharedData("mod" + slot, newVal);
NAPI.ClientEvent.TriggerClientEventForAll("vehicleToggleMod", pV, slot, newVal);
}
ServerVehicle sV = player.Vehicle.GetServerVehicle();
if (sV == null) return;

444
Server/Util/VehicleSync.cs Normal file
View 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]);
}
}
}