diff --git a/ReallifeGamemode.Client/Tuning/main.ts b/ReallifeGamemode.Client/Tuning/main.ts index 9da9b31b..c825708f 100644 --- a/ReallifeGamemode.Client/Tuning/main.ts +++ b/ReallifeGamemode.Client/Tuning/main.ts @@ -26,7 +26,7 @@ export default function tuning(globalData: IGlobalData) { const carModSlotName = [ { Slot: 0, Name: "Spoiler", Price: 1000 }, - { Slot: 1, Name: "Frontstoßstange", Price: 1500}, + { Slot: 1, Name: "Frontstoßstange", Price: 1500 }, { Slot: 2, Name: "Heckstoßstange", Price: 1500 }, { Slot: 3, Name: "Seitenschweller", Price: 1500 }, { Slot: 4, Name: "Auspuff", Price: 500 }, @@ -36,12 +36,12 @@ export default function tuning(globalData: IGlobalData) { { Slot: 8, Name: "Extra 1", Price: 2000 }, { Slot: 9, Name: "Extra 2", Price: 2000 }, { Slot: 10, Name: "Dach", Price: 1500 }, - { Slot: 11, Name: "Motor", Price: 50000 }, - { Slot: 12, Name: "Bremsen", Price: 30000 }, - { Slot: 13, Name: "Getriebe", Price: 15000 }, + { Slot: 11, Name: "Motor", BasePercentage: 20, PriceIncreasePerLevel: 7.5 }, + { Slot: 12, Name: "Bremsen", BasePercentage: 5, PriceIncreasePerLevel: 2.5 }, + { Slot: 13, Name: "Getriebe", BasePercentage: 10, PriceIncreasePerLevel: 2.5 }, { Slot: 14, Name: "Hupe", Price: 500 }, { Slot: 15, Name: "Federung", Price: 2000 }, - { Slot: 18, Name: "Turbo", Price: 40000 }, + { Slot: 18, Name: "Turbo", BasePercentage: 45, PriceIncreasePerLevel: 0 }, { Slot: 22, Name: "Licht", Price: 500 }, { Slot: 23, Name: "Reifen", Price: 1000 }, { Slot: -1, Name: "Lackierung", Price: 1000 }, @@ -165,7 +165,7 @@ export default function tuning(globalData: IGlobalData) { var currentActiveModItem = new Array(); var currentSelectedItem: VehicleModMenuItem = null; - mp.events.add("showTuningMenu", (noMoney) => { + mp.events.add("showTuningMenu", (noMoney, basePrice) => { mp.events.call("hideTuningInfo", false); mp.gui.chat.show(false); @@ -226,9 +226,6 @@ export default function tuning(globalData: IGlobalData) { } } - var price = noMoney? 0 : getModSlotPrice(modType); - - if (mod === null) { mod = localVehicle.getMod(modType); } @@ -248,6 +245,7 @@ export default function tuning(globalData: IGlobalData) { currentMod[modType] = mod; for (var x = -1; x < modNum; x++) { + var price = noMoney ? 0 : getModSlotPrice(modType, basePrice, x); var modText = ""; if (x === -1) { modText = "Serie"; @@ -265,7 +263,7 @@ export default function tuning(globalData: IGlobalData) { modMenu.CurrentSelection = x; } else { - item.SetRightLabel("$"+ moneyformat(price)); + item.SetRightLabel("$" + moneyformat(price)); } } @@ -304,7 +302,7 @@ export default function tuning(globalData: IGlobalData) { }); }); - + mainMenu.ItemSelect.on((item: NativeUI.UIMenuItem, index: number) => { if (item === repairItem) { @@ -315,7 +313,9 @@ export default function tuning(globalData: IGlobalData) { mainMenu.Visible = true; mainMenu.MenuClose.on(() => { - localVehicle.setLights(0); + if (localVehicle && mp.vehicles.exists(localVehicle)) { + localVehicle.setLights(0); + } globalData.InTuning = false; globalData.InMenu = false; mp.events.call("hideTuningInfo", false); @@ -456,8 +456,21 @@ export default function tuning(globalData: IGlobalData) { return realModName; } - function getModSlotPrice(modType: number): number { - return carModSlotName.filter(x => x.Slot == modType)[0].Price; + function getModSlotPrice(modType: number, basePrice: number, modIndex?: number): number { + if (modIndex === -1) { + return 0; + } + + let price = 0; + let priceInfo = carModSlotName.filter(x => x.Slot == modType)[0]; + + if (priceInfo.BasePercentage) { + price = ((priceInfo.BasePercentage + priceInfo.PriceIncreasePerLevel * modIndex) / 100) * basePrice; + } else { + price = priceInfo.Price; + } + + return price; } function setHeadlightsColor(vehicle, index) { diff --git a/ReallifeGamemode.Server/Managers/TuningManager.cs b/ReallifeGamemode.Server/Managers/TuningManager.cs index 9a4d9cc9..3799c5eb 100644 --- a/ReallifeGamemode.Server/Managers/TuningManager.cs +++ b/ReallifeGamemode.Server/Managers/TuningManager.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; @@ -35,7 +36,7 @@ namespace ReallifeGamemode.Server.Managers colShape.OnEntityEnterColShape += (cs, c) => { using var dbContext = new DatabaseContext(); - if (c.IsInVehicle && c.VehicleSeat == 0) + if (c.IsInVehicle && c.VehicleSeat == 0 && IsPlayerAllowedToTuneVehicle(c, c.Vehicle, dbContext)) { c.TriggerEvent("showTuningInfo"); } @@ -43,12 +44,42 @@ namespace ReallifeGamemode.Server.Managers colShape.OnEntityExitColShape += (cs, c) => { - c.TriggerEvent("hideTuningInfo", true); + if(c.IsInVehicle) + { + c.TriggerEvent("hideTuningInfo", true); + } }; tuningGarages.Add(colShape); } + private static bool IsPlayerAllowedToTuneVehicle(Player c, Vehicle vehicle, DatabaseContext dbContext) + { + User user = c.GetUser(); + if(user == null) + { + return false; + } + + ServerVehicle serverVehicle = vehicle.GetServerVehicle(dbContext); + if(serverVehicle == null) + { + return false; + } + + if(serverVehicle is UserVehicle userVehicle && userVehicle.UserId == user.Id) + { + return true; + } + + if(serverVehicle is FactionVehicle factionVehicle && factionVehicle.GetOwners().Contains(user.FactionId ?? 0)) + { + return true; + } + + return false; + } + public static void ApplyTuningToServerVehicle(ServerVehicle sVeh) { Vehicle veh = VehicleManager.GetVehicleFromServerVehicle(sVeh); @@ -81,7 +112,33 @@ namespace ReallifeGamemode.Server.Managers { if (!player.IsInVehicle) return; - player.TriggerEvent("showTuningMenu"); + player.TriggerEvent("showTuningMenu", false, GetVehicleBasePrice(player.Vehicle)); + } + + private int GetVehicleBasePrice(Vehicle vehicle) + { + if(vehicle == null) + { + return 0; + } + + ServerVehicle serverVehicle = vehicle.GetServerVehicle(); + if(serverVehicle == null) + { + return 0; + } + + if(serverVehicle is UserVehicle userVehicle) + { + return userVehicle.Price ?? 0; + } + + if(serverVehicle is FactionVehicle factionVehicle) + { + return factionVehicle.BuyPrice; + } + + return 0; } [RemoteEvent("repairVehicle")]