diff --git a/ReallifeGamemode.Client/Tuning/main.ts b/ReallifeGamemode.Client/Tuning/main.ts index c825708f..66414bb5 100644 --- a/ReallifeGamemode.Client/Tuning/main.ts +++ b/ReallifeGamemode.Client/Tuning/main.ts @@ -22,7 +22,7 @@ export default function tuning(globalData: IGlobalData) { const disableInput = [75, 278, 279, 280, 281, 23, 59, 60, 71, 72, 74]; - const carModTypes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 18, 22, -1, 25, 27, 28, 33, 34, 35, 38, 39, 40, 41, 42, 43, 44, 46, 48, 69]; + const carModTypes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 18, 22, -2, -1, 25, 27, 28, 33, 34, 35, 38, 39, 40, 41, 42, 43, 44, 46, 48, 69]; const carModSlotName = [ { Slot: 0, Name: "Spoiler", Price: 1000 }, @@ -43,7 +43,7 @@ export default function tuning(globalData: IGlobalData) { { Slot: 15, Name: "Federung", Price: 2000 }, { Slot: 18, Name: "Turbo", BasePercentage: 45, PriceIncreasePerLevel: 0 }, { Slot: 22, Name: "Licht", Price: 500 }, - { Slot: 23, Name: "Reifen", Price: 1000 }, + { Slot: -2, Name: "Reifen", Price: 1000 }, { Slot: -1, Name: "Lackierung", Price: 1000 }, { Slot: 25, Name: "Nummernschildhalter", Price: 500 }, { Slot: 27, Name: "Innenausstatung", Price: 500 }, @@ -207,6 +207,12 @@ export default function tuning(globalData: IGlobalData) { mainMenu.BindMenuToItem(colorMenu, colorItem); return; + } else if (modType == -2) { + var wheelsItem = new UIMenuItem("Reifen"); + var wheelsMenu = getWheelsMenu(); + + mainMenu.AddItem(wheelsItem); + mainMenu.BindMenuToItem(wheelsMenu, wheelsItem); } var num = localVehicle.getNumMods(modType); @@ -302,8 +308,6 @@ export default function tuning(globalData: IGlobalData) { }); }); - - mainMenu.ItemSelect.on((item: NativeUI.UIMenuItem, index: number) => { if (item === repairItem) { mp.events.callRemote("repairVehicle"); @@ -493,6 +497,11 @@ export default function tuning(globalData: IGlobalData) { } } + function getWheelsMenu(): NativeUI.Menu { + var wheelsMenu = new NativeUI.Menu("Reifen", "rollin on dem rims", new NativeUI.Point(0, screenRes.y / 3)); + return wheelsMenu; + } + function getColorMenu(): NativeUI.Menu { var currentColors = mp.players.local.vehicle.getColours(0, 0); @@ -591,6 +600,8 @@ export default function tuning(globalData: IGlobalData) { mp.events.callRemote("CLIENT:TuningManager_SetVehicleColor", false, color); } + + class VehicleModMenuItem extends UIMenuItem { public price: number; } diff --git a/ReallifeGamemode.Server/Events/UpdateCharacterWeapon.cs b/ReallifeGamemode.Server/Events/UpdateCharacterWeapon.cs deleted file mode 100644 index ea213d7b..00000000 --- a/ReallifeGamemode.Server/Events/UpdateCharacterWeapon.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Linq; -using GTANetworkAPI; -using ReallifeGamemode.Database.Entities; -using ReallifeGamemode.Database.Models; -using ReallifeGamemode.Server.Extensions; -using ReallifeGamemode.Server.Managers; - -namespace ReallifeGamemode.Server.Events -{ - public class UpdateCharacterWeapon : Script - { - [RemoteEvent("updateWeaponSelection")] - public void UpdateWeaponSelection(Player client, string weaponModel, int slot) - { - if (weaponModel == "Keine") - { - client.RemoveAllWeapons(); - return; - } - - WeaponHash weaponHash = NAPI.Util.WeaponNameToModel(weaponModel); - - if (slot == 1) - { - client.RemoveAllWeapons(); - client.GiveWeapon(weaponHash, 0); - } - if (slot == 2) - { - client.RemoveAllWeapons(); - client.GiveWeapon(weaponHash, 0); - } - if (slot == 3) - { - client.RemoveAllWeapons(); - client.GiveWeapon(weaponHash, 0); - } - if (slot == 4) - { - client.RemoveAllWeapons(); - client.GiveWeapon(weaponHash, 0); - } - if (slot == 5) - { - client.SafeSetArmor(100); - } - } - - [RemoteEvent("cancelWeaponSelection")] - public void CancelWeaponSelection(Player client) - { - client.RemoveAllWeapons(); - } - - [RemoteEvent("saveWeaponSelection")] - public void SaveWeaponSelection(Player client, string primaryModel, string secondaryModel, string meleeModel, string specialModel, string armor) - { - WeaponPoint nearestWeapon = PositionManager.WeaponPoints.Find(w => w.Position.DistanceTo(client.Position) <= 1.5 && w.FactionId == client.GetUser().FactionId); - - if (nearestWeapon == null) - { - client.SendChatMessage("~y~Du bist nicht mehr an deinem Waffenschrank!"); - return; - } - - client.RemoveAllWeapons(); - if (!uint.TryParse(primaryModel, out uint primary)) - { - if (primaryModel.Contains("mk2") && !primaryModel.Contains("_mk2")) primaryModel = primaryModel.Replace("mk2", "_mk2"); - primary = NAPI.Util.GetHashKey($"weapon_{primaryModel}"); - } - if (!uint.TryParse(secondaryModel, out uint secondary)) - { - if (secondaryModel.Contains("mk2") && !secondaryModel.Contains("_mk2")) secondaryModel = secondaryModel.Replace("mk2", "_mk2"); - secondary = NAPI.Util.GetHashKey($"weapon_{secondaryModel}"); - } - if (!uint.TryParse(meleeModel, out uint melee)) - { - if (meleeModel.Contains("mk2") && !meleeModel.Contains("_mk2")) meleeModel = meleeModel.Replace("mk2", "_mk2"); - melee = NAPI.Util.GetHashKey($"weapon_{meleeModel}"); - } - - client.GiveWeapon((WeaponHash)primary, 500); - client.GiveWeapon((WeaponHash)secondary, 250); - client.GiveWeapon((WeaponHash)melee, 1); - - if (!uint.TryParse(specialModel, out uint special)) - { - if (specialModel.Contains("mk2") && !specialModel.Contains("_mk2")) specialModel = specialModel.Replace("mk2", "_mk2"); - special = NAPI.Util.GetHashKey($"weapon_{specialModel}"); - } - client.GiveWeapon((WeaponHash)special, 30); - - if (armor == "Schutzweste") - { - client.SafeSetArmor(100); - } - - using (var context = new DatabaseContext()) - { - User user = client.GetUser(); - FactionWeapon slot1 = context.FactionWeapons.Where(w => w.FactionId == user.FactionId && w.WeaponModel == primaryModel).FirstOrDefault(); - if (slot1 != null) - slot1.Ammount -= 1; - FactionWeapon slot2 = context.FactionWeapons.Where(w => w.FactionId == user.FactionId && w.WeaponModel == secondaryModel).FirstOrDefault(); - if (slot2 != null) - slot2.Ammount -= 1; - FactionWeapon slot3 = context.FactionWeapons.Where(w => w.FactionId == user.FactionId && w.WeaponModel == meleeModel).FirstOrDefault(); - if (slot3 != null) - slot3.Ammount -= 1; - FactionWeapon slot4 = context.FactionWeapons.Where(w => w.FactionId == user.FactionId && w.WeaponModel == specialModel).FirstOrDefault(); - if (slot4 != null) - slot4.Ammount -= 1; - FactionWeapon slot5 = context.FactionWeapons.Where(w => w.FactionId == user.FactionId && w.WeaponModel == armor).FirstOrDefault(); - if (slot5 != null) - slot5.Ammount -= 1; - context.SaveChanges(); - } - } - - [RemoteEvent("CLIENT:Ammunation_BuyWeapon")] - public void AmmunationBuyWeapoon(Player player, string weaponmodel, int ammo, int price) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - - if (user.Handmoney < price) - { - player.SendNotification("Du hast nicht genügend Geld bei dir"); - return; - } - user.Handmoney -= price; - dbContext.SaveChanges(); - player.GiveWeapon(NAPI.Util.WeaponNameToModel(weaponmodel), ammo); - //client.TriggerEvent("SERVER:SET_HANDMONEY", user.Handmoney); - } - } - } -} diff --git a/ReallifeGamemode.Server/Events/Weapon.cs b/ReallifeGamemode.Server/Events/Weapon.cs new file mode 100644 index 00000000..eb73287e --- /dev/null +++ b/ReallifeGamemode.Server/Events/Weapon.cs @@ -0,0 +1,141 @@ +using System; +using System.Linq; +using GTANetworkAPI; +using Microsoft.Extensions.Logging; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; +using ReallifeGamemode.Server.Extensions; +using ReallifeGamemode.Server.Log; +using ReallifeGamemode.Server.Managers; + +namespace ReallifeGamemode.Server.Events +{ + public class Weapon : Script + { + private ILogger logger = LogManager.GetLogger(); + + private const int SLOT_PRIMARY = 2; + private const int SLOT_SECONDARY = 1; + private const int SLOT_MEELE = 3; + private const int SLOT_SPECIAL = 4; + + + [RemoteEvent("saveWeaponSelection")] + public void SaveWeaponSelection(Player client, string primaryModel, string secondaryModel, string meleeModel, string specialModel, string armor) + { + using var dbContext = new DatabaseContext(); + User user = client.GetUser(dbContext); + + WeaponPoint nearestWeapon = PositionManager.WeaponPoints.Find(w => w.Position.DistanceTo(client.Position) <= 1.5 && w.FactionId == user.FactionId); + + if (nearestWeapon == null) + { + client.SendChatMessage("~y~Du bist nicht mehr an deinem Waffenschrank!"); + return; + } + + if (!string.IsNullOrEmpty(primaryModel)) + { + HandleSlot(user, client, 2, primaryModel, dbContext); + } + + if (!string.IsNullOrEmpty(secondaryModel)) + { + HandleSlot(user, client, 1, secondaryModel, dbContext); + } + + if (!string.IsNullOrEmpty(meleeModel)) + { + HandleSlot(user, client, 3, meleeModel, dbContext); + } + + if (!string.IsNullOrEmpty(specialModel)) + { + HandleSlot(user, client, 4, specialModel, dbContext); + } + + dbContext.SaveChanges(); + + if (armor == "Schutzweste") + { + logger.LogInformation("Player {0} took armor from weaponrack of faction {1}", user.Name, user.FactionId); + client.SafeSetArmor(100); + } + } + + public void HandleSlot(User user, Player player, int slot, string selection, DatabaseContext context) + { + string weapon = GetRealWeaponModelName(selection); + + uint hashKey = NAPI.Util.GetHashKey(weapon); + + if (!Enum.GetValues(typeof(WeaponHash)).Cast().Contains((WeaponHash)hashKey)) + { + logger.LogWarning("Player {0} tried to take invalid weapon {1} from weaponrack of faction {2}", user.Name, selection, user.FactionId); + return; + } + + var slotWeapons = context.FactionWeapons.Where(w => w.FactionId == user.FactionId && w.SlotID == slot).ToList(); + + foreach (var slotWeaponHash in slotWeapons.Select(w => NAPI.Util.GetHashKey(GetRealWeaponModelName(w.WeaponModel)))) + { + player.RemoveWeapon((WeaponHash)slotWeaponHash); + } + + var chosenWeapon = slotWeapons.Where(w => w.WeaponModel == selection).FirstOrDefault(); + if (chosenWeapon == null) + { + logger.LogWarning("Player {0} tried to take not-existing weapon {1} from weaponrack of faction {2}", user.Name, selection, user.FactionId); + return; + } + + int ammo = GetSlotAmmoAmount(slot); + player.GiveWeapon((WeaponHash)hashKey, ammo); + player.SetWeaponAmmo((WeaponHash)hashKey, ammo); + + chosenWeapon.Ammount -= 1; + logger.LogInformation("Player {0} took weapon {1} from weaponrack of faction {2}", user.Name, selection, user.FactionId); + } + + private int GetSlotAmmoAmount(int slot) => slot switch + { + SLOT_PRIMARY => 500, + SLOT_SECONDARY => 250, + SLOT_MEELE => 1, + SLOT_SPECIAL => 20, + _ => 1 + }; + + private string GetRealWeaponModelName(string weapon) + { + string ret = "weapon_" + weapon.ToLower(); + + if (!ret.Contains("_mk2") && ret.Contains("mk2")) + { + ret = ret.Replace("mk2", "_mk2"); + } + + return ret; + } + + [RemoteEvent("CLIENT:Ammunation_BuyWeapon")] + public void AmmunationBuyWeapoon(Player player, string weaponmodel, int ammo, int price) + { + using (var dbContext = new DatabaseContext()) + { + User user = player.GetUser(dbContext); + + if (user.Handmoney < price) + { + player.SendNotification("Du hast nicht genügend Geld bei dir"); + return; + } + logger.LogInformation("Player {0} bought a {1} in ammunation", user.Name, weaponmodel); + user.Handmoney -= price; + dbContext.SaveChanges(); + player.GiveWeapon(NAPI.Util.WeaponNameToModel(weaponmodel), ammo); + //client.TriggerEvent("SERVER:SET_HANDMONEY", user.Handmoney); + } + } + } +} diff --git a/ReallifeGamemode.Server/ReallifeGamemode.Server.csproj b/ReallifeGamemode.Server/ReallifeGamemode.Server.csproj index 80049bd1..0bd45f54 100644 --- a/ReallifeGamemode.Server/ReallifeGamemode.Server.csproj +++ b/ReallifeGamemode.Server/ReallifeGamemode.Server.csproj @@ -42,6 +42,7 @@ +