diff --git a/Client/DoorManager/doormanager.js b/Client/DoorManager/doormanager.js index b411b8ca..9123a22d 100644 --- a/Client/DoorManager/doormanager.js +++ b/Client/DoorManager/doormanager.js @@ -2,4 +2,4 @@ locked === 1 ? locked = true : locked = false; mp.game.object.doorControl(doorHash, x, y, z, locked, p5, p6, p7); -}); \ No newline at end of file +}); diff --git a/Client/Gui/interiors.js b/Client/Gui/interiors.js new file mode 100644 index 00000000..1eedd52f --- /dev/null +++ b/Client/Gui/interiors.js @@ -0,0 +1,31 @@ +var keyBound = false; +var interiorId = -1; +var enterExit = undefined; + +mp.events.add('InteriorManager_ClearHelpText', () => { + mp.game.ui.clearHelp(true); + + enterExit = undefined; + + if (keyBound) { + mp.keys.unbind(0x45, false, keyPressHandler); + keyBound = false; + } +}); + +mp.events.add('InteriorManager_ShowHelpText', (interior, intId, entEx) => { + mp.game.ui.setTextComponentFormat('STRING'); + mp.game.ui.addTextComponentSubstringPlayerName('Drücke ~INPUT_CONTEXT~, um ~b~' + interior + ' ~s~zu ' + (entEx === 0 ? 'betreten' : 'verlassen')); + mp.game.ui.displayHelpTextFromStringLabel(0, true, true, -1); + + interiorId = intId; + enterExit = entEx; + + mp.keys.bind(0x45, false, keyPressHandler); + keyBound = true; +}); + +function keyPressHandler() { + if (globalData.InChat) return; + mp.events.callRemote('InteriorManager_UseTeleport', interiorId, enterExit); +} \ No newline at end of file diff --git a/Client/Gui/vehiclemenu/main.js b/Client/Gui/vehiclemenu/main.js index bfd0b09f..2538d5f9 100644 --- a/Client/Gui/vehiclemenu/main.js +++ b/Client/Gui/vehiclemenu/main.js @@ -1,5 +1,17 @@ let menuBrowser = null; +const NativeUI = require('nativeui'); +const Menu = NativeUI.Menu; +const UIMenuItem = NativeUI.UIMenuItem; +const UIMenuListItem = NativeUI.UIMenuListItem; +const UIMenuCheckboxItem = NativeUI.UIMenuCheckboxItem; +const UIMenuSliderItem = NativeUI.UIMenuSliderItem; +const BadgeStyle = NativeUI.BadgeStyle; +const Point = NativeUI.Point; +const ItemsCollection = NativeUI.ItemsCollection; +const Color = NativeUI.Color; +const ListItem = NativeUI.ListItem; + mp.events.add('ToggleVehicleMenu', () => { if (menuBrowser !== null) { menuBrowser.destroy(); @@ -24,15 +36,68 @@ mp.events.add('doAction', (action) => { case 8: // Motor mp.events.callRemote("VehicleMenu_ToggleEngine"); break; - case 5: + case 5: // Auf -/ Abschließen mp.events.callRemote("VehicleMenu_LockCar"); break; - case 3: + case 3: // Türen showDoorsMenu(); break; } }); function showDoorsMenu() { + mp.gui.chat.show(false); + var doorMenu = new Menu("Türen", "Türen verwalten", new Point(50, 50)); + + doorMenu.AddItem(new UIMenuListItem("Tür", "Welche Tür darf's sein?", new ItemsCollection([ + " Fahrertür", + " Beifahrertür", + "Hinten links", + "Hinten rechts", + "Motorhaube", + "Kofferraum" + ]))); + + doorMenu.AddItem(new UIMenuItem("Alle öffnen", "Öffnet alle Türen")); + doorMenu.AddItem(new UIMenuItem("Alle schließen", "Schließt alle Türen")); + + doorMenu.ItemSelect.on((item, index) => { + if (index === 0) { + var doorId = -1; + switch (item.SelectedItem.DisplayText) { + case " Fahrertür": + doorId = 0; + break; + case " Beifahrertür": + doorId = 1; + break; + case "Hinten links": + doorId = 2; + break; + case "Hinten rechts": + doorId = 3; + break; + case "Motorhaube": + doorId = 4; + break; + case "Kofferraum": + doorId = 5; + break; + } + if (doorId !== -1) { + mp.events.callRemote("VehicleMenu_ToggleSingleDoor", doorId); + } + } else if (index === 1) { + mp.events.callRemote("VehicleMenu_OpenAllDoors"); + } else if (index === 2) { + mp.events.callRemote("VehicleMenu_CloseAllDoors"); + } + }); + + doorMenu.MenuClose.on(() => { + mp.gui.chat.show(true); + }); + + doorMenu.Open(); } \ No newline at end of file diff --git a/Client/Player/keys.js b/Client/Player/keys.js index 04974e77..61b94641 100644 --- a/Client/Player/keys.js +++ b/Client/Player/keys.js @@ -17,6 +17,7 @@ const player = mp.players.local; mp.keys.bind(0x0D, false, function () { if (chat === true) { chat = false; + globalData.InChat = false; } }); @@ -102,6 +103,7 @@ mp.keys.bind(0x4E, false, function () { mp.keys.bind(0x54, false, function () { if (chat === false && showInv === false) { chat = true; + globalData.InChat = true; } }); diff --git a/Client/index.js b/Client/index.js index e33be7fa..f94dcb48 100644 --- a/Client/index.js +++ b/Client/index.js @@ -7,7 +7,8 @@ let globalData = { InTuning: false, HideGui: false, - PlayerInteraction: false + PlayerInteraction: false, + InChat: false }; mp.game.gameplay.enableMpDlcMaps(true); @@ -30,6 +31,7 @@ require('./Gui/nametags.js'); require('./Gui/playerlist.js'); require('./Gui/Inventory/inventory.js'); require('./Gui/vehiclemenu/main.js'); +require('./Gui/interiors.js'); require('./Interaction/interaction.js'); @@ -47,4 +49,5 @@ require('./Tuning/main.js'); require('./Tuning/sync.js'); require('./Tuning/sirensilence.js'); -require('./vehiclesync/vehiclesync.js'); \ No newline at end of file +require('./vehiclesync/vehiclesync.js'); +require('./vehiclesync/smoothtrottle.js'); \ No newline at end of file diff --git a/Client/vehiclesync/smoothtrottle.js b/Client/vehiclesync/smoothtrottle.js new file mode 100644 index 00000000..fb087413 --- /dev/null +++ b/Client/vehiclesync/smoothtrottle.js @@ -0,0 +1,137 @@ +//This script will make vehicles have smoother acceleration. +//To disable the script call an event and set "GlobalDisable" to true. +//To disable individual sections, set "DisableAntiReverse" or "DisableSmoothThrottle" to true. + +//This script includes an anti-reverse brake system with automatic brake lights. + +//When you brake, while holding brake you will come to a complete stop and won't reverse until you +//release the brake button and press it again. + +mp.events.add("SmoothThrottle_PlayerEnterVehicle", (entity, seat) => +{ + BrakeSystem = true; +}); + +mp.events.add("SmoothThrottle_PlayerExitVehicle", (entity) => +{ + BrakeSystem = false; +}); + +mp.events.add("SmoothThrottle_SetSmoothThrottle", (turnedOn) => +{ + DisableSmoothThrottle = !turnedOn; +}); + +mp.events.add("SmoothThrottle_SetAntiReverse", (turnedOn) => +{ + DisableAntiReverse = !turnedOn; +}); + +mp.events.add("SmoothThrottle_SetGlobal", (turnedOn) => +{ + GlobalDisable = !turnedOn; +}); + +let GlobalDisable = false; +let DisableAntiReverse = false; +let DisableSmoothThrottle = false; + +let BrakeSystem = false; +let vehicleStopped = false; +let vehicleStoppedOnOwn = false; +let constantStart = 0.25; //starts at 0.25 and increases to 1 +let constantStep = 0.135; //You can change this for a faster throttle response (Will cause more skidding) + +let deltaAmount = constantStart; +let prevTime = mp.game.invoke('0x9CD27B0045628463'); +let diffToggle = false; + +mp.events.add("render", () => +{ + if(GlobalDisable) + return; + + if(BrakeSystem) + { + if(mp.players.local.vehicle !== null) + { + if(!mp.players.local.vehicle.isSeatFree(-1)) //only do this if the vehicle has a driver (doesn't have to be the player who is rendering this) + { + //Optimize function calls to variables (probably doesn't make a difference) + let vehClass = mp.players.local.vehicle.getClass(); + let isControl71Pressed = mp.game.controls.isControlPressed(0, 71); //accelerate + let isControl72Pressed = mp.game.controls.isControlPressed(0, 72); //brake + let isControl76Pressed = mp.game.controls.isControlPressed(0, 76); //handbrake + let speed = mp.players.local.vehicle.getSpeed(); + + //Only do it to car classes + if(!DisableSmoothThrottle && ((vehClass >= 0 && vehClass <= 12) || vehClass === 18 || vehClass === 19 || vehClass === 20)) + { + if(isControl71Pressed || isControl72Pressed) + { + if(isControl76Pressed) + { + deltaAmount = 1.0; //If people are buffering their throttle up + } + + mp.players.local.vehicle.setEngineTorqueMultiplier(deltaAmount); + + //Calculate tick time and step every 250ms + if (mp.game.invoke('0x9CD27B0045628463') - prevTime > 250) + { + prevTime = mp.game.invoke('0x9CD27B0045628463'); + deltaAmount += constantStep * speed; //Curve + if(deltaAmount > 1.0) + { + deltaAmount = 1.0; + } + } + } + else + { + deltaAmount = constantStart; //Reset when they let go of throttle + //mp.game.controls.setControlNormal(0, 71, amount); + } + } + + //THIS IS THE BRAKE LIGHT SYSTEM WITH ANTI-REVERSE + if(DisableAntiReverse) + return; + + if(speed < 1) + { + vehicleStopped = true; + } + else + { + vehicleStopped = false; + vehicleStoppedOnOwn = false; + diffToggle = false; + } + + if((!isControl72Pressed && mp.game.controls.isControlEnabled(0, 72)) && !isControl76Pressed && vehicleStopped) + { + vehicleStoppedOnOwn = true; + mp.players.local.vehicle.setBrakeLights(true); + } + + if(vehicleStopped && !vehicleStoppedOnOwn && !mp.players.local.vehicle.isInBurnout() && !diffToggle) + { + mp.players.local.vehicle.setBrakeLights(true); + mp.game.controls.disableControlAction(0, 72, true); + } + + if((isControl71Pressed && !isControl72Pressed) || isControl76Pressed) + { + mp.players.local.vehicle.setBrakeLights(false); + } + + if(mp.game.controls.isDisabledControlJustReleased(0, 72) && vehicleStopped) + { + mp.game.controls.enableControlAction(0, 72, true); + diffToggle = true; + } + } + } + } +}); \ No newline at end of file diff --git a/Main.cs b/Main.cs index ff5c3174..38198a41 100644 --- a/Main.cs +++ b/Main.cs @@ -48,9 +48,10 @@ namespace reallife_gamemode DatabaseHelper.InitDatabaseFirstTime(); - InteriorManager.LoadInteriors(); FactionHelper.CheckFactionBankAccounts(); BusinessManager.LoadBusinesses(); + InteriorManager.LoadInteriors(); + DoorManager.LoadDoors(); TempBlip tempBlip = new TempBlip() diff --git a/Server/Commands/Admin.cs b/Server/Commands/Admin.cs index 274ba4f5..5adc264b 100644 --- a/Server/Commands/Admin.cs +++ b/Server/Commands/Admin.cs @@ -2111,7 +2111,7 @@ namespace reallife_gamemode.Server.Commands player.TriggerEvent("showTuningMenu"); } - [Command("interior", "~m~Benutzung: ~s~/interior [Add / Remove / SetEnterPosition / SetExitPosition] [Name]")] + [Command("interior", "~m~Benutzung: ~s~/interior [Add / Remove / SetEnterPosition / SetExitPosition] [Name / ID]")] public void CmdAdminInterior(Client player, string option1, string option2) { if (!player.GetUser()?.IsAdmin(AdminLevel.HEADADMIN) ?? true) @@ -2131,11 +2131,6 @@ namespace reallife_gamemode.Server.Commands switch(option1) { case "add": - if(InteriorManager.GetInteriorByName(option2) != null) - { - player.SendChatMessage("~r~[FEHLER]~s~ Dieses Interior existiert schon."); - return; - } using(var dbContext = new DatabaseContext()) { Interior interiorAdd = new Interior @@ -2150,23 +2145,18 @@ namespace reallife_gamemode.Server.Commands case "remove": using (var dbContext = new DatabaseContext()) { - Interior interiorRemove = InteriorManager.GetInteriorByName(option2, dbContext); + if(!int.TryParse(option2, out int intId)) + { + player.SendChatMessage("~r~[FEHLER]~s~ Es muss eine Nummer angegeben werden."); + return; + } + Interior interiorRemove = InteriorManager.GetInteriorById(intId, dbContext); if(interiorRemove == null) { player.SendChatMessage("~r~[FEHLER]~s~ Dieses Interior existiert nicht."); return; } - TextLabel enT = InteriorManager.GetInteriorEnterTextLabel(interiorRemove); - TextLabel exT = InteriorManager.GetInteriorExitTextLabel(interiorRemove); - Marker enM = InteriorManager.GetInteriorEnterMarker(interiorRemove); - Marker exM = InteriorManager.GetInteriorExitMarkers(interiorRemove); - - if (enT != null) enT.Delete(); - if (exT != null) exT.Delete(); - if (enM != null) enM.Delete(); - if (exM != null) exM.Delete(); - InteriorManager.DeleteInterior(interiorRemove); dbContext.Interiors.Remove(interiorRemove); @@ -2177,7 +2167,12 @@ namespace reallife_gamemode.Server.Commands case "setenterposition": using (var dbContext = new DatabaseContext()) { - Interior interior = InteriorManager.GetInteriorByName(option2, dbContext); + if (!int.TryParse(option2, out int intIdEnter)) + { + player.SendChatMessage("~r~[FEHLER]~s~ Es muss eine Nummer angegeben werden."); + return; + } + Interior interior = InteriorManager.GetInteriorById(intIdEnter, dbContext); if (interior == null) { player.SendChatMessage("~r~[FEHLER]~s~ Dieses Interior existiert nicht."); @@ -2185,14 +2180,21 @@ namespace reallife_gamemode.Server.Commands } interior.EnterPosition = player.Position; dbContext.SaveChanges(); + InteriorManager.DeleteInterior(interior); + InteriorManager.LoadInterior(interior); + player.SendChatMessage("~b~[ADMIN]~s~ Die Eingangs-Position vom Interior ~y~" + interior.Name + "~s~ wurde gesetzt."); InteriorManager.LoadInteriors(); } - player.SendChatMessage("~b~[ADMIN]~s~ Die Eingangs-Position vom Interior ~y~" + option2 + "~s~ wurde gesetzt."); break; case "setexitposition": using (var dbContext = new DatabaseContext()) { - Interior interior = InteriorManager.GetInteriorByName(option2, dbContext); + if (!int.TryParse(option2, out int intIdExit)) + { + player.SendChatMessage("~r~[FEHLER]~s~ Es muss eine Nummer angegeben werden."); + return; + } + Interior interior = InteriorManager.GetInteriorById(intIdExit, dbContext); if (interior == null) { player.SendChatMessage("~r~[FEHLER]~s~ Dieses Interior existiert nicht."); @@ -2200,13 +2202,28 @@ namespace reallife_gamemode.Server.Commands } interior.ExitPosition = player.Position; dbContext.SaveChanges(); + InteriorManager.DeleteInterior(interior); + InteriorManager.LoadInterior(interior); + player.SendChatMessage("~b~[ADMIN]~s~ Die Eingangs-Position vom Interior ~y~" + interior.Name + "~s~ wurde gesetzt."); InteriorManager.LoadInteriors(); } - player.SendChatMessage("~b~[ADMIN]~s~ Die Ausgangs-Position vom Interior ~y~" + option2 + "~s~ wurde gesetzt."); break; } } + [Command("reloaddoors", "~m~Benutzung: ~s~/reloaddoors")] + public void CmdAdminReloaddoors(Client player) + { + if (!player.GetUser()?.IsAdmin(AdminLevel.HEADADMIN) ?? true) + { + ChatService.NotAuthorized(player); + return; + } + + DoorManager.ReloadDoors(); + player.SendChatMessage("~b~[ADMIN]~s~ Die Türen wurden erfolgreich neugeladen."); + } + #endregion #region ALevel1338 @@ -2297,45 +2314,6 @@ namespace reallife_gamemode.Server.Commands /* ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ - //TEST COMMAND - [Command("own")] - public void CmdAdminOwn(Client player) - { - if (!player.GetUser()?.IsAdmin(AdminLevel.ADMIN) ?? true) - { - ChatService.NotAuthorized(player); - return; - } - - if (player.IsInVehicle) - { - Vehicle playerVehicle = player.Vehicle; - int playerSeat = player.VehicleSeat; - using (var saveVehicle = new DatabaseContext()) - { - var dataSet = new UserVehicle - { - UserId = player.GetUser().Id, - Model = (VehicleHash)playerVehicle.Model, - PositionX = playerVehicle.Position.X, - PositionY = playerVehicle.Position.Y, - PositionZ = playerVehicle.Position.Z, - Heading = playerVehicle.Heading, - NumberPlate = playerVehicle.NumberPlate, - PrimaryColor = playerVehicle.PrimaryColor, - SecondaryColor = playerVehicle.SecondaryColor, - Locked = playerVehicle.Locked, - Active = true - }; - saveVehicle.UserVehicles.Add(dataSet); - saveVehicle.SaveChanges(); - - player.SetIntoVehicle(dataSet.Spawn(playerVehicle), -1); - } - } - else player.SendChatMessage("~m~Du sitzt in keinem Fahrzeug!"); - } - //TEST COMMAND [Command("myvehicles")] public void CmdAdminMyVehicles(Client player) @@ -2383,37 +2361,6 @@ namespace reallife_gamemode.Server.Commands } } - //TODO Ausführen bei Tastendruck wenn in Fahrzeug. - [Command("buyv")] - public void BuyShopVehicle(Client player) - { - if (!player.GetUser()?.IsAdmin(AdminLevel.ADMIN) ?? true) - { - ChatService.NotAuthorized(player); - return; - } - - if (player.IsInVehicle) - { - if (player.Vehicle.HasData("shopVehicleId")) - { - int shopVehicleId = player.Vehicle.GetData("shopVehicleId"); - using (var getShopVehicle = new DatabaseContext()) - { - ShopVehicle sVehicle = getShopVehicle.ShopVehicles.FirstOrDefault(u => u.Id == shopVehicleId); - Entities.Faction receiverUser = getShopVehicle.Factions.FirstOrDefault(u => u.Name == "LSPD"); - BankManager.TransferMoney(player.GetUser(), receiverUser, sVehicle.Price, "Fahrzeug gekauft: " + NAPI.Vehicle.GetVehicleDisplayName(sVehicle.Model)); - //TODO Anpassen - Vehicle boughtVehicle = NAPI.Vehicle.CreateVehicle(sVehicle.Model, new Vector3(sVehicle.PositionX, sVehicle.PositionY + 10, sVehicle.PositionZ + 0.5), sVehicle.Heading, - sVehicle.PrimaryColor, sVehicle.SecondaryColor, "LoG", 255, false, true, 0); - player.SetIntoVehicle(boughtVehicle, 0); - //TODO fügt das Fahrzeug als Userfahrzeug hinzu - CmdAdminOwn(player); - } - } - } - } - [Command("saveall")] public void SaveAll(Client player) { diff --git a/Server/Entities/Door.cs b/Server/Entities/Door.cs index 87dd5a66..3e87810a 100644 --- a/Server/Entities/Door.cs +++ b/Server/Entities/Door.cs @@ -1,8 +1,8 @@ -using System; +using GTANetworkAPI; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Numerics; using System.Text; /** @@ -25,7 +25,10 @@ namespace reallife_gamemode.Server.Entities public float Y { get; set; } public float Z { get; set; } public float Radius { get; set; } - + + [NotMapped] + public Vector3 Position => new Vector3(X, Y, Z); + [ForeignKey("FactionId")] public int? FactionId { get; set; } public Faction Faction { get; set; } diff --git a/Server/Events/VehicleMenu.cs b/Server/Events/VehicleMenu.cs index f86705a0..f3cb47d6 100644 --- a/Server/Events/VehicleMenu.cs +++ b/Server/Events/VehicleMenu.cs @@ -88,5 +88,42 @@ namespace reallife_gamemode.Server.Events player.SendNotification(msg); } } + + [RemoteEvent("VehicleMenu_ToggleSingleDoor")] + public void VehicleMenuToggleSingleDoorEvent(Client player, int door) + { + if (!player.IsInVehicle) return; + Vehicle veh = player.Vehicle; + + DoorID doorId = (DoorID)door; + + DoorState state = VehicleStreaming.GetDoorState(veh, doorId); + + VehicleStreaming.SetDoorState(veh, doorId, state == DoorState.DoorOpen ? DoorState.DoorClosed : DoorState.DoorOpen); + } + + [RemoteEvent("VehicleMenu_OpenAllDoors")] + public void VehicleMenuOpenAllDoorsEvent(Client player) + { + if (!player.IsInVehicle) return; + Vehicle veh = player.Vehicle; + + foreach (DoorID doorId in Enum.GetValues(typeof(DoorID))) + { + VehicleStreaming.SetDoorState(veh, doorId, DoorState.DoorOpen); + } + } + + [RemoteEvent("VehicleMenu_CloseAllDoors")] + public void VehicleMenuCloseAllDoorsEvent(Client player) + { + if (!player.IsInVehicle) return; + Vehicle veh = player.Vehicle; + + foreach (DoorID doorId in Enum.GetValues(typeof(DoorID))) + { + VehicleStreaming.SetDoorState(veh, doorId, DoorState.DoorClosed); + } + } } } diff --git a/Server/Managers/DoorManager.cs b/Server/Managers/DoorManager.cs index 4fe0f3fb..db147c91 100644 --- a/Server/Managers/DoorManager.cs +++ b/Server/Managers/DoorManager.cs @@ -17,18 +17,38 @@ namespace reallife_gamemode.Server.Managers { public class DoorManager : Script { + private static Dictionary _doorColShapes = new Dictionary(); + + public static void LoadDoors() + { + using (var dbContext = new DatabaseContext()) + { + foreach(Door door in dbContext.Doors) + { + _doorColShapes[door.Id] = NAPI.ColShape.CreateSphereColShape(door.Position, 30f); + } + } + } + + public static void ReloadDoors() + { + foreach(var doorPair in _doorColShapes) + { + doorPair.Value.Entity().Delete(); + } + _doorColShapes.Clear(); + LoadDoors(); + } + public static void ChangeDoorState(Client player) { - List NearDoors = new List(); var user = player.GetUser(); - using (var saveDoor = new DatabaseContext()) + using (var dbContext = new DatabaseContext()) { - NearDoors = saveDoor.Doors.ToList().FindAll(d => new Vector3(d.X, d.Y, d.Z).DistanceTo(player.Position) <= d.Radius); + IQueryable NearDoors = dbContext.Doors.Where(d => d.Position.DistanceTo(player.Position) <= d.Radius); foreach (Door d in NearDoors) { - Door currentDoor = saveDoor.Doors.FirstOrDefault(c => c.Id == d.Id); - if(!user.IsAdmin(AdminLevel.ADMIN) && (d.FactionId != user.FactionId || d.FactionId == null)) { string lockState = "~r~Du hast kein Recht diese T\u00fcr " + (d.Locked == true ? "auf" : "ab") + "zuschlie\u00dfen!"; @@ -36,15 +56,30 @@ namespace reallife_gamemode.Server.Managers continue; } - currentDoor.Locked = !currentDoor.Locked; + d.Locked = !d.Locked; string notStr = d.Name + " " + (d.Locked == false ? "~g~auf" : "~r~ab") + "geschlossen"; player.SendNotification(notStr, true); - NAPI.Pools.GetAllPlayers().ForEach(p => p.TriggerEvent("changeDoorState", d.Model, d.X, d.Y, d.Z, (currentDoor.Locked ? 1 : 0), 0.0f, 0.0f, 0.0f)); + NAPI.Pools.GetAllPlayers().ForEach(p => p.TriggerEvent("changeDoorState", d.Model, d.X, d.Y, d.Z, (d.Locked ? 1 : 0), 0.0f, 0.0f, 0.0f)); + } + dbContext.SaveChanges(); + } + } + + [ServerEvent(Event.PlayerEnterColshape)] + public void DoorManagerPlayerEnterColShapeEvent(ColShape colShape, Client player) + { + if(_doorColShapes.ContainsValue(colShape.Handle)) + { + int doorId = _doorColShapes.Where(d => d.Value.Value == colShape.Handle.Value).FirstOrDefault().Key; + + using(var dbContext = new DatabaseContext()) + { + Door door = dbContext.Doors.Where(d => d.Id == doorId).First(); + player.TriggerEvent("changeDoorState", door.Model, door.X, door.Y, door.Z, (door.Locked ? 1 : 0), 0.0f, 0.0f, 0.0f); } - saveDoor.SaveChanges(); } } } diff --git a/Server/Managers/InteriorManager.cs b/Server/Managers/InteriorManager.cs index b6443009..acc902ef 100644 --- a/Server/Managers/InteriorManager.cs +++ b/Server/Managers/InteriorManager.cs @@ -8,12 +8,14 @@ using System.Text; namespace reallife_gamemode.Server.Managers { - public class InteriorManager + public class InteriorManager : Script { public static Dictionary _interiorEnterTextLabels = new Dictionary(); public static Dictionary _interiorExitTextLabels = new Dictionary(); public static Dictionary _interiorEnterMarkers = new Dictionary(); public static Dictionary _interiorExitMarkers = new Dictionary(); + public static Dictionary _interiorEnterColShapes = new Dictionary(); + public static Dictionary _interiorExitColShapes = new Dictionary(); public static Interior GetInteriorByName(string name, DatabaseContext dbContext = null) { @@ -30,50 +32,116 @@ namespace reallife_gamemode.Server.Managers } } + public static Interior GetInteriorById(int id, DatabaseContext dbContext = null) + { + if (dbContext == null) + { + using (dbContext = new DatabaseContext()) + { + return dbContext.Interiors.Where(i => i.Id == id).FirstOrDefault(); + } + } + else + { + return dbContext.Interiors.Where(i => i.Id == id).FirstOrDefault(); + } + } + public static void LoadInteriors() { using (var dbContext = new DatabaseContext()) { foreach (Interior interior in dbContext.Interiors) { - TextLabel enT = GetInteriorEnterTextLabel(interior); - TextLabel exT = GetInteriorExitTextLabel(interior); - Marker enM = GetInteriorEnterMarker(interior); - Marker exM = GetInteriorExitMarkers(interior); - - if (enT != null) enT.Delete(); - if (exT != null) exT.Delete(); - if (enM != null) enM.Delete(); - if (exM != null) exM.Delete(); - if (interior.EnterPosition != null) - { - NAPI.Util.ConsoleOutput("enterposition not null"); - _interiorEnterTextLabels[interior.Id] = NAPI.TextLabel.CreateTextLabel("~y~" + interior.Name + "\n~s~Eingang", interior.EnterPosition, 10f, 1f, 0, new Color(255, 255, 255)); - _interiorEnterMarkers[interior.Id] = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, interior.EnterPosition.Subtract(new Vector3(0, 0, 1.5)), new Vector3(), new Vector3(), 1.0f, new Color(255, 255, 255)); - } - - if(interior.ExitPosition != null) - { - NAPI.Util.ConsoleOutput("exitposition not null"); - _interiorExitTextLabels[interior.Id] = NAPI.TextLabel.CreateTextLabel("~y~" + interior.Name + "\n~s~Ausgang", interior.ExitPosition, 10f, 1f, 0, new Color(255, 255, 255)); - _interiorExitMarkers[interior.Id] = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, interior.ExitPosition.Subtract(new Vector3(0, 0, 1.5)), new Vector3(), new Vector3(), 1.0f, new Color(255, 255, 255)); - } + LoadInterior(interior); } - dbContext.SaveChanges(); + } + } + + public static void LoadInterior(Interior interior) + { + if (interior.EnterPosition != null) + { + _interiorEnterTextLabels[interior.Id] = NAPI.TextLabel.CreateTextLabel("~y~" + interior.Name + "\n~s~Eingang", interior.EnterPosition, 10f, 1f, 0, new Color(255, 255, 255)); + _interiorEnterMarkers[interior.Id] = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, interior.EnterPosition.Subtract(new Vector3(0, 0, 1.7)), new Vector3(), new Vector3(), 2.0f, new Color(255, 255, 255, 100)); + _interiorEnterColShapes[interior.Id] = NAPI.ColShape.CreateSphereColShape(interior.EnterPosition, 1.5f); + } + + if (interior.ExitPosition != null) + { + _interiorExitTextLabels[interior.Id] = NAPI.TextLabel.CreateTextLabel("~y~" + interior.Name + "\n~s~Ausgang", interior.ExitPosition, 10f, 1f, 0, new Color(255, 255, 255)); + _interiorExitMarkers[interior.Id] = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, interior.ExitPosition.Subtract(new Vector3(0, 0, 1.7)), new Vector3(), new Vector3(), 1.6f, new Color(255, 255, 255, 100)); + _interiorExitColShapes[interior.Id] = NAPI.ColShape.CreateSphereColShape(interior.ExitPosition, 1.3f); } } public static void DeleteInterior(Interior interior) { + TextLabel enT = GetInteriorEnterTextLabel(interior); + TextLabel exT = GetInteriorExitTextLabel(interior); + Marker enM = GetInteriorEnterMarker(interior); + Marker exM = GetInteriorExitMarkers(interior); + ColShape enC = GetInteriorEnterColShape(interior); + ColShape exC = GetInteriorExitColShape(interior); + + if (enT != null) enT.Delete(); + if (exT != null) exT.Delete(); + if (enM != null) enM.Delete(); + if (exM != null) exM.Delete(); + if (enC != null) enC.Delete(); + if (exC != null) exC.Delete(); + _interiorEnterTextLabels.Remove(interior.Id); _interiorExitTextLabels.Remove(interior.Id); _interiorEnterMarkers.Remove(interior.Id); _interiorExitMarkers.Remove(interior.Id); + _interiorEnterColShapes.Remove(interior.Id); + _interiorExitColShapes.Remove(interior.Id); } public static TextLabel GetInteriorEnterTextLabel(Interior interior) => NAPI.Pools.GetAllTextLabels().Find(t => t.Handle.Value == _interiorEnterTextLabels.FirstOrDefault(x => x.Key == interior.Id).Value.Value); public static TextLabel GetInteriorExitTextLabel(Interior interior) => NAPI.Pools.GetAllTextLabels().Find(t => t.Handle.Value == _interiorExitTextLabels.FirstOrDefault(x => x.Key == interior.Id).Value.Value); + public static Marker GetInteriorEnterMarker(Interior interior) => NAPI.Pools.GetAllMarkers().Find(t => t.Handle.Value == _interiorEnterMarkers.FirstOrDefault(x => x.Key == interior.Id).Value.Value); public static Marker GetInteriorExitMarkers(Interior interior) => NAPI.Pools.GetAllMarkers().Find(t => t.Handle.Value == _interiorExitMarkers.FirstOrDefault(x => x.Key == interior.Id).Value.Value); + + public static ColShape GetInteriorEnterColShape(Interior interior) => NAPI.Pools.GetAllColShapes().Find(t => t.Handle.Value == _interiorEnterColShapes.FirstOrDefault(x => x.Key == interior.Id).Value.Value); + public static ColShape GetInteriorExitColShape(Interior interior) => NAPI.Pools.GetAllColShapes().Find(t => t.Handle.Value == _interiorExitColShapes.FirstOrDefault(x => x.Key == interior.Id).Value.Value); + + public static int GetInteriorIdFromEnterColShape(NetHandle handle) => _interiorEnterColShapes.FirstOrDefault(c => c.Value.Value == handle.Value).Key; + public static int GetInteriorIdFromExitColShape(NetHandle handle) => _interiorExitColShapes.FirstOrDefault(c => c.Value.Value == handle.Value).Key; + + [ServerEvent(Event.PlayerEnterColshape)] + public void InteriorManagerPlayerEnterColshapeEvent(ColShape colShape, Client player) + { + int enterId = GetInteriorIdFromEnterColShape(colShape); + int exitId = GetInteriorIdFromExitColShape(colShape); + if(enterId != 0) + { + Interior interior = GetInteriorById(enterId); + player.TriggerEvent("InteriorManager_ShowHelpText", interior.Name, interior.Id, 0); + } + else if(exitId != 0) + { + Interior interior = GetInteriorById(exitId); + player.TriggerEvent("InteriorManager_ShowHelpText", interior.Name, interior.Id, 1); + } + } + + [ServerEvent(Event.PlayerExitColshape)] + public void InteriorManagerPlayerExitColshapeEvent(ColShape colShape, Client player) + { + if(GetInteriorIdFromEnterColShape(colShape) != 0 || GetInteriorIdFromExitColShape(colShape) != 0) + { + player.TriggerEvent("InteriorManager_ClearHelpText"); + } + } + + [RemoteEvent("InteriorManager_UseTeleport")] + public void InteriorManagerUseTeleportEvent(Client player, int id, int enterExit) + { + Interior interior = GetInteriorById(id); + player.Position = enterExit == 0 ? interior.ExitPosition : interior.EnterPosition; + } } } diff --git a/Server/Util/SmoothThrottle.cs b/Server/Util/SmoothThrottle.cs new file mode 100644 index 00000000..d55775a7 --- /dev/null +++ b/Server/Util/SmoothThrottle.cs @@ -0,0 +1,40 @@ +using GTANetworkAPI; + +namespace reallife_gamemode.Server.Util +{ + public class SmoothThrottleAntiReverse : Script + { + [ServerEvent(Event.PlayerExitVehicle)] + public void SmoothThrottleExitEvent(Client player, Vehicle veh) + { + NAPI.ClientEvent.TriggerClientEvent(player, "SmoothThrottle_PlayerExitVehicle", veh); + } + + [ServerEvent(Event.PlayerEnterVehicle)] + public void SmoothThrottleEnterEvent(Client player, Vehicle veh, sbyte seat) + { + NAPI.ClientEvent.TriggerClientEvent(player, "SmoothThrottle_PlayerEnterVehicle", veh, seat); + } + + //You can call these to change settings on player if you want. + //Note that these are toggles, you only need to call them once. + + //This disables/enables the smooth throttle + public static void SetSmoothThrottle(Client player, bool turnedOn) + { + NAPI.ClientEvent.TriggerClientEvent(player, "SmoothThrottle_SetSmoothThrottle", turnedOn); + } + + //This disables/enables anti reverse + public static void SetAntiReverse(Client player, bool turnedOn) + { + NAPI.ClientEvent.TriggerClientEvent(player, "SmoothThrottle_SetAntiReverse", turnedOn); + } + + //This disables/enables both + public static void SetSmoothThrottleAntiReverse(Client player, bool turnedOn) + { + NAPI.ClientEvent.TriggerClientEvent(player, "SmoothThrottle_SetGlobal", turnedOn); + } + } +} \ No newline at end of file