diff --git a/Client/Business/cardealer.js b/Client/Business/cardealer.js new file mode 100644 index 00000000..48951ec3 --- /dev/null +++ b/Client/Business/cardealer.js @@ -0,0 +1,60 @@ +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; + +const moneyFormat = require("moneyformat"); + +var shopMenu; + +mp.events.add('ShopVehicle_OpenMenu', (businessName, price) => { + var veh = mp.players.local.vehicle; + if (!veh) return; + mp.gui.chat.show(false); + shopMenu = new Menu("Fahrzeugkauf", "Kaufe ein neues Auto", new Point(50, 50)); + + var carItem = new UIMenuItem("Fahrzeugname"); + carItem.SetRightLabel(mp.game.ui.getLabelText(mp.game.vehicle.getDisplayNameFromVehicleModel(veh.model))); + shopMenu.AddItem(carItem); + + var shopItem = new UIMenuItem("Autohaus"); + shopItem.SetRightLabel(businessName); + shopMenu.AddItem(shopItem); + + var priceItem = new UIMenuItem("Preis"); + priceItem.SetRightLabel("~g~$~s~ "+ moneyFormat(price)); + shopMenu.AddItem(priceItem); + + var saveItem = new UIMenuItem("Kaufen"); + saveItem.BackColor = new Color(0, 100, 0); + saveItem.HighlightedBackColor = new Color(0, 150, 0); + shopMenu.AddItem(saveItem); + + var cancelItem = new UIMenuItem("Abbrechen"); + cancelItem.BackColor = new Color(213, 0, 0); + cancelItem.HighlightedBackColor = new Color(229, 57, 53); + shopMenu.AddItem(cancelItem); + + shopMenu.ItemSelect.on((item, index) => { + if (item === cancelItem) { + shopMenu.Close(); + } else if (item === saveItem) { + mp.events.callRemote("VehShop_BuyVehicle"); + shopMenu.Close(); + } + }); + + shopMenu.MenuClose.on(() => { + mp.gui.chat.show(true); + mp.players.local.taskLeaveVehicle(veh.handle, 0); + }); + + shopMenu.Open(); +}); \ No newline at end of file diff --git a/Client/Gui/infobox.js b/Client/Gui/infobox.js index f631969f..55b047da 100644 --- a/Client/Gui/infobox.js +++ b/Client/Gui/infobox.js @@ -68,8 +68,10 @@ mp.events.add("toggleUi", (show) => { // return ('$' + num.toFixed(2).replace('.', ',').replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1.')); //} +const moneyFormat = require("moneyformat"); + mp.events.add("updateMoney", (money) => { - playerMoney = money.toLocaleString("de-DE", { minimumFractionDigits: 0 }); + playerMoney = moneyFormat(money); }); mp.events.add("render", () => { diff --git a/Client/index.js b/Client/index.js index 8fd9f6c1..cf8009db 100644 --- a/Client/index.js +++ b/Client/index.js @@ -43,3 +43,4 @@ require('./Tuning/sync.js'); require('./Tuning/sirensilence.js'); require('./Business/main.js'); +require('./Business/cardealer.js'); diff --git a/Client/moneyformat/index.js b/Client/moneyformat/index.js new file mode 100644 index 00000000..ad58585a --- /dev/null +++ b/Client/moneyformat/index.js @@ -0,0 +1,3 @@ +exports = function (money) { + return money.toLocaleString("de-DE", { minimumFractionDigits: 0 }); +}; \ No newline at end of file diff --git a/Client/vehiclesync/vehiclesync.js b/Client/vehiclesync/vehiclesync.js index 08d50d56..65b99414 100644 --- a/Client/vehiclesync/vehiclesync.js +++ b/Client/vehiclesync/vehiclesync.js @@ -27,6 +27,7 @@ mp.events.add("VehStream_SetLockStatus", (veh, status) => { }); mp.events.add("VehStream_PlayerEnterVehicleAttempt", (entity, seat) => { + entity = mp.vehicles.atRemoteId(entity); if (entity === undefined || entity === null || !entity.isAVehicle()) return; if (typeof entity.getVariable("VehicleSyncData") !== 'undefined') { var toggle = entity.getVariable("VehicleSyncData"); @@ -51,7 +52,7 @@ mp.events.add("VehStream_PlayerExitVehicleAttempt", (entity) => { mp.events.add("VehStream_PlayerExitVehicle", (entity) => { entity = mp.vehicles.atRemoteId(entity); - if (entity === undefined || entity === null/* || !entity.isAVehicle()*/) { + if (entity === undefined || entity === null || !entity.isAVehicle()) { return; } setTimeout(() => { @@ -223,6 +224,7 @@ mp.events.add("VehStream_PlayerExitVehicle", (entity) => { }); mp.events.add("VehStream_PlayerEnterVehicleAttempt", (entity, seat) => { + entity = mp.vehicles.atRemoteId(entity); if (entity === undefined || entity === null || !entity.isAVehicle()) return; setTimeout(() => { var Status = []; diff --git a/Model/DatabaseContext.cs b/Model/DatabaseContext.cs index 467accd5..a88eb177 100644 --- a/Model/DatabaseContext.cs +++ b/Model/DatabaseContext.cs @@ -67,7 +67,6 @@ namespace reallife_gamemode.Model public DbSet FactionVehicles { get; set; } //Shops - public DbSet Shops { get; set; } //Logs //public DbSet BanLogs { get; set; } diff --git a/Server/Business/CarDealerBusinessBase.cs b/Server/Business/CarDealerBusinessBase.cs new file mode 100644 index 00000000..82d0a461 --- /dev/null +++ b/Server/Business/CarDealerBusinessBase.cs @@ -0,0 +1,13 @@ +using GTANetworkAPI; +using System; +using System.Collections.Generic; +using System.Text; + +namespace reallife_gamemode.Server.Business +{ + public abstract class CarDealerBusinessBase : BusinessBase + { + public abstract Vector3 CarSpawnPositon { get; } + public abstract float CarSpawnHeading { get; } + } +} diff --git a/Server/Business/ShopBusiness.cs b/Server/Business/ShopBusiness.cs index 283f33bb..ed9d2ea6 100644 --- a/Server/Business/ShopBusiness.cs +++ b/Server/Business/ShopBusiness.cs @@ -5,7 +5,7 @@ using GTANetworkAPI; namespace reallife_gamemode.Server.Business { - class ShopBusiness : BusinessBase + public class ShopBusiness : BusinessBase { public override int Id => 2; diff --git a/Server/Business/VapidCarDealerBusiness.cs b/Server/Business/VapidCarDealerBusiness.cs new file mode 100644 index 00000000..26666017 --- /dev/null +++ b/Server/Business/VapidCarDealerBusiness.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; + +namespace reallife_gamemode.Server.Business +{ + public class VapidCarDealerBusiness : CarDealerBusinessBase + { + public override int Id => 3; + + public override string Name => "Vapid Autohaus"; + + public override Vector3 Position => new Vector3(-177, -1156, 23); + + public override Vector3 CarSpawnPositon => new Vector3(-222, -1162, 22.5); + + public override float CarSpawnHeading => 356.6f; + + public override void Load() + { + + } + } +} diff --git a/Server/Commands/Admin.cs b/Server/Commands/Admin.cs index 486a7c8b..5160393e 100644 --- a/Server/Commands/Admin.cs +++ b/Server/Commands/Admin.cs @@ -221,9 +221,9 @@ namespace reallife_gamemode.Server.Commands } player.SendChatMessage("~m~__________ ~s~Businesses ~m~__________"); - foreach (Business.BusinessBase b in BusinessManager.Businesses) + foreach (BusinessBase b in BusinessManager.Businesses.OrderBy(b => b.Id)) { - player.SendChatMessage(b.Id.ToString().PadRight(3) + " | " + b.Name); + player.SendChatMessage(b.Id.ToString().PadRight(3) + " | " + b.Name + (b is CarDealerBusinessBase ? " | Autohaus" : "")); } } #endregion @@ -676,7 +676,9 @@ namespace reallife_gamemode.Server.Commands return; } - target.Position = new Vector3(target.Position.X, target.Position.Y, target.Position.Z + wert); + Vector3 oldPos = target.Position; + + target.Position = new Vector3(oldPos.X, oldPos.Y, oldPos.Z + wert); player.SendChatMessage("Du hast " + target.Name + " geslappt. Höhe: " + wert + ""); } @@ -1439,8 +1441,8 @@ namespace reallife_gamemode.Server.Commands } } - [Command("save", "~m~Benutzung: ~s~/save [Typ = ~g~Blip~s~, ~g~Goto (X)~s~, ~r~Marker~s~, ~r~Ped~s~, ~r~Pickup~s~, ~r~TextLabel~s~, ~g~Vehicle~s~, ~g~FVehicle~s~, ~g~SVehicle~s~] (Beschreibung) = (X)")] - public void CmdAdminSave(Client player, string typ, string description = null) + [Command("save", "~m~Benutzung: ~s~/save [Typ = ~g~Blip~s~, ~g~Goto (X)~s~, ~r~Marker~s~, ~r~Ped~s~, ~r~Pickup~s~, ~r~TextLabel~s~, ~g~Vehicle~s~, ~g~FVehicle~s~, ~g~SVehicle (X)~s~] (Beschreibung) = (X)")] + public void CmdAdminSave(Client player, string typ, string option1 = null, string option2 = null) { if (!player.GetUser()?.IsAdmin(AdminLevel.HEADADMIN) ?? true) { @@ -1453,7 +1455,7 @@ namespace reallife_gamemode.Server.Commands player.TriggerEvent("saveBlip"); break; case "goto": - if (description == null) + if (option1 == null) { player.SendChatMessage("Für Goto musst du einen dritten Parameter angeben. Beispiel: Ort des Goto-Punktes."); return; @@ -1462,11 +1464,11 @@ namespace reallife_gamemode.Server.Commands { using (var dbContext = new DatabaseContext()) { - GotoPoint p = dbContext.GotoPoints.FirstOrDefault(x => x.Description == description); + GotoPoint p = dbContext.GotoPoints.FirstOrDefault(x => x.Description == option1); if (p == null) { - SaveManager.SaveGotoPoint(player, description); - player.SendNotification("Goto-Punkt ~g~" + description + "~s~ gespeichert.", true); + SaveManager.SaveGotoPoint(player, option1); + player.SendNotification("Goto-Punkt ~g~" + option1 + "~s~ gespeichert.", true); } else { @@ -1512,12 +1514,38 @@ namespace reallife_gamemode.Server.Commands case "svehicle": if (player.IsInVehicle) { + if(option1 == null || option2 == null) + { + player.SendChatMessage("~m~Benutzung: ~s~/save SVehicle [Carshop Business ID] [Preis]"); + return; + } + + if(!int.TryParse(option1, out int businessId) || !int.TryParse(option2, out int price)) + { + player.SendChatMessage("~m~Benutzung: ~s~/save SVehicle [Carshop Business ID] [Preis]"); + return; + } + + BusinessBase business = BusinessManager.GetBusiness(businessId); + if(business == null) + { + player.SendChatMessage("~r~[FEHLER]~s~ Dieses Business existiert nicht."); + return; + } + + if(!(business is CarDealerBusinessBase)) + { + player.SendChatMessage("~r~[FEHLER]~s~ Dieses Business ist kein Fahrzeug-Business."); + return; + } + Vehicle vehicle = player.Vehicle; int playerSeat = player.VehicleSeat; vehicle = SaveManager.SaveShopVehicleData(vehicle, (VehicleHash)vehicle.Model, vehicle.DisplayName, vehicle.Position, vehicle.Heading, vehicle.NumberPlate, - Convert.ToByte(vehicle.PrimaryColor), Convert.ToByte(vehicle.SecondaryColor)); + Convert.ToByte(vehicle.PrimaryColor), Convert.ToByte(vehicle.SecondaryColor), business, price); player.SendNotification("Shopfahrzeug ~g~" + vehicle.DisplayName + "~s~ gespeichert.", true); - player.SetIntoVehicle(vehicle, playerSeat); + Vector3 oldPos = player.Position; + player.Position = new Vector3(oldPos.X, oldPos.Y, oldPos.Z + 2.5); } else player.SendChatMessage("~m~Du sitzt in keinem Fahrzeug!"); break; diff --git a/Server/Entities/ServerVehicle.cs b/Server/Entities/ServerVehicle.cs index 1b908172..94b4e3c7 100644 --- a/Server/Entities/ServerVehicle.cs +++ b/Server/Entities/ServerVehicle.cs @@ -35,7 +35,13 @@ namespace reallife_gamemode.Server.Entities public Vehicle Spawn(Vehicle currentVeh = null) { 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); + Vector3 position = this.Position; + uint model = (uint)this.Model; + float heading = this.Heading; + int c1 = this.PrimaryColor; + int c2 = this.SecondaryColor; + string np = this.NumberPlate; + Vehicle veh = NAPI.Vehicle.CreateVehicle(Model, position, heading, c1, c2, "", 255, false, false); VehicleStreaming.SetEngineState(veh, false); VehicleStreaming.SetLockStatus(veh, this.Locked); VehicleManager.AddVehicle(this, veh); diff --git a/Server/Entities/Shop.cs b/Server/Entities/Shop.cs deleted file mode 100644 index ce2e94a2..00000000 --- a/Server/Entities/Shop.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using reallife_gamemode.Server.Entities; - -/** -* @overview Life of German Reallife - Entities Shop (Shop.cs) -* @author VegaZ -* @copyright (c) 2008 - 2018 Life of German -*/ - -namespace reallife_gamemode.Server.Entities -{ - public class Shop - { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public string ShopName { get; set; } - public float Balance { get; set; } - - [ForeignKey("ShopCategory")] - public int Category { get; set; } - public ShopCategory ShopCategory { get; set; } - - public int Owner { get; set; } - public bool Active { get; set; } - } -} diff --git a/Server/Entities/ShopCategory.cs b/Server/Entities/ShopCategory.cs deleted file mode 100644 index 3b88eb0a..00000000 --- a/Server/Entities/ShopCategory.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using reallife_gamemode.Server.Entities; - -/** -* @overview Life of German Reallife - Entities ShopCategory (ShopCategory.cs) -* @author VegaZ -* @copyright (c) 2008 - 2018 Life of German -*/ - -namespace reallife_gamemode.Server.Entities -{ - public class ShopCategory - { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get; set; } - public string Category { get; set; } - } -} diff --git a/Server/Entities/ShopVehicles.cs b/Server/Entities/ShopVehicles.cs index 096d34d6..6e4157b0 100644 --- a/Server/Entities/ShopVehicles.cs +++ b/Server/Entities/ShopVehicles.cs @@ -1,4 +1,5 @@ using GTANetworkAPI; +using reallife_gamemode.Server.Business; using reallife_gamemode.Server.Util; using System; using System.Collections.Generic; @@ -19,7 +20,7 @@ namespace reallife_gamemode.Server.Entities { [ForeignKey("Shop")] public int? ShopId { get; set; } - public Shop Shop { get; set; } + public int BusinessId { get; set; } public int Price { get; set; } public override string ToString() diff --git a/Server/Events/Key.cs b/Server/Events/Key.cs index 62a25eb0..172ccfe0 100644 --- a/Server/Events/Key.cs +++ b/Server/Events/Key.cs @@ -204,10 +204,26 @@ namespace reallife_gamemode.Server.Events { Vehicle v = player.Vehicle; bool state = VehicleStreaming.GetEngineState(v); - NAPI.Util.ConsoleOutput("changing engine state: " + state.ToString()); + ServerVehicle sV = v.GetServerVehicle(); + if (sV != null) + { + if (sV is ShopVehicle) + { + VehicleStreaming.SetEngineState(v, false); + return; + } + else if(sV is FactionVehicle fV) + { + if(fV.FactionId != player.GetUser().FactionId && !state) + { + return; + } + } + } VehicleStreaming.SetEngineState(v, !state); } } + [RemoteEvent("keyPress:X")] public void KeyPressX(Client player) { diff --git a/Server/Managers/BusinessManager.cs b/Server/Managers/BusinessManager.cs index 8e1f4a50..6f54ce2e 100644 --- a/Server/Managers/BusinessManager.cs +++ b/Server/Managers/BusinessManager.cs @@ -1,4 +1,5 @@ using GTANetworkAPI; +using reallife_gamemode.Model; using reallife_gamemode.Server.Business; using reallife_gamemode.Server.Entities; using reallife_gamemode.Server.Extensions; @@ -108,5 +109,57 @@ namespace reallife_gamemode.Server.Managers return; } } + + [ServerEvent(Event.PlayerEnterVehicle)] + public void CarDealerBusiness_PlayerEnterVehicle(Client player, Vehicle veh, int seat) + { + ServerVehicle sVeh = veh.GetServerVehicle(); + if (sVeh == null) return; + if(!(sVeh is ShopVehicle)) return; + ShopVehicle shopVehicle = (ShopVehicle)sVeh; + player.TriggerEvent("ShopVehicle_OpenMenu", GetBusiness(shopVehicle.BusinessId).Name, shopVehicle.Price); + } + + [RemoteEvent("VehShop_BuyVehicle")] + public void CarDealerBusiness_BuyVehicle(Client player) + { + ServerVehicle sVeh = player.Vehicle?.GetServerVehicle(); + if (sVeh == null) return; + if (!(sVeh is ShopVehicle)) return; + ShopVehicle shopVehicle = (ShopVehicle)sVeh; + int price = shopVehicle.Price; + CarDealerBusinessBase business = (CarDealerBusinessBase)GetBusiness(shopVehicle.BusinessId); + TransactionResult result = BankManager.TransferMoney(player.GetUser(), business, price, "Auto gekauft"); + if(result == TransactionResult.SENDER_NOT_ENOUGH_MONEY) + { + player.SendNotification("~r~Du hast nicht genug Geld: " + price.ToMoneyString()); + return; + } + + Vector3 spawnPos = business.CarSpawnPositon; + + UserVehicle newVeh = new UserVehicle + { + Heading = business.CarSpawnHeading, + PositionX = spawnPos.X, + PositionY = spawnPos.Y, + PositionZ = spawnPos.Z, + Locked = false, + UserId = player.GetUser().Id, + Model = shopVehicle.Model, + PrimaryColor = 111, + SecondaryColor = 111, + Active = true, + NumberPlate = "" + }; + + using(var dbContext = new DatabaseContext()) + { + dbContext.UserVehicles.Add(newVeh); + dbContext.SaveChanges(); + } + + newVeh.Spawn(); + } } } diff --git a/Server/Managers/LoadManager.cs b/Server/Managers/LoadManager.cs index 002831d4..296554f7 100644 --- a/Server/Managers/LoadManager.cs +++ b/Server/Managers/LoadManager.cs @@ -5,6 +5,7 @@ using GTANetworkAPI; using reallife_gamemode.Model; using reallife_gamemode.Server.Entities; using reallife_gamemode.Server.Extensions; +using reallife_gamemode.Server.Saves; /** * @overview Life of German Reallife - Managers LoadManager (LoadManager.cs) @@ -22,7 +23,7 @@ namespace reallife_gamemode.Server.Managers { using (var loadData = new DatabaseContext()) { - foreach (Saves.SavedBlip b in loadData.Blips) + foreach (SavedBlip b in loadData.Blips) { if(b.Active == true) { diff --git a/Server/Managers/SaveManager.cs b/Server/Managers/SaveManager.cs index eab7c693..7ef4f169 100644 --- a/Server/Managers/SaveManager.cs +++ b/Server/Managers/SaveManager.cs @@ -1,5 +1,6 @@ using GTANetworkAPI; using reallife_gamemode.Model; +using reallife_gamemode.Server.Business; using reallife_gamemode.Server.Entities; using reallife_gamemode.Server.Extensions; using reallife_gamemode.Server.Managers; @@ -9,7 +10,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -namespace reallife_gamemode.Server.Events +namespace reallife_gamemode.Server.Managers { public class SaveManager : Script { @@ -105,7 +106,7 @@ namespace reallife_gamemode.Server.Events } } public static Vehicle SaveShopVehicleData(Vehicle veh, VehicleHash vehicleModel, string vehicleModelName, Vector3 vehiclePosition, float vehicleHeading, - string vehicleNumberPlate, int vehiclePrimaryColor, int vehicleSecondaryColor) + string vehicleNumberPlate, int vehiclePrimaryColor, int vehicleSecondaryColor, BusinessBase business, int price) { using (var saveData = new DatabaseContext()) { @@ -119,7 +120,9 @@ namespace reallife_gamemode.Server.Events NumberPlate = vehicleNumberPlate, PrimaryColor = vehiclePrimaryColor, SecondaryColor = vehicleSecondaryColor, - Active = true + Active = true, + BusinessId = business.Id, + Price = price }; saveData.ShopVehicles.Add(dataSet); saveData.SaveChanges(); diff --git a/Server/Util/VehicleSync.cs b/Server/Util/VehicleSync.cs index dfa431fb..d25c2b0d 100644 --- a/Server/Util/VehicleSync.cs +++ b/Server/Util/VehicleSync.cs @@ -371,7 +371,7 @@ namespace reallife_gamemode.Server.Util data = new VehicleSyncData(); UpdateVehicleSyncData(veh, data); - NAPI.ClientEvent.TriggerClientEvent(player, "VehStream_PlayerEnterVehicleAttempt", veh, seat); + NAPI.ClientEvent.TriggerClientEvent(player, "VehStream_PlayerEnterVehicleAttempt", veh.Handle.Value, seat); } [ServerEvent(Event.PlayerExitVehicleAttempt)]