From 467e0a4248629076b6d95ba57e0d419efa024bfd Mon Sep 17 00:00:00 2001 From: hydrant Date: Thu, 20 May 2021 11:58:15 +0200 Subject: [PATCH 01/10] Add legal option to items --- .../Inventory/Interfaces/IItem.cs | 2 ++ .../Inventory/Items/BaseItem.cs | 18 ++++++++++++++++++ .../Inventory/Items/Cannabis.cs | 15 +++------------ .../Inventory/Items/ConsumableItem.cs | 16 ++++++++-------- .../Inventory/Items/DropItem.cs | 14 +++++++------- .../Inventory/Items/UseItem.cs | 14 +++++++------- .../Inventory/Items/WeaponDealItem.cs | 14 +++++++------- 7 files changed, 52 insertions(+), 41 deletions(-) create mode 100644 ReallifeGamemode.Server/Inventory/Items/BaseItem.cs diff --git a/ReallifeGamemode.Server/Inventory/Interfaces/IItem.cs b/ReallifeGamemode.Server/Inventory/Interfaces/IItem.cs index dd364314..4605aed4 100644 --- a/ReallifeGamemode.Server/Inventory/Interfaces/IItem.cs +++ b/ReallifeGamemode.Server/Inventory/Interfaces/IItem.cs @@ -14,5 +14,7 @@ namespace ReallifeGamemode.Server.Inventory.Interfaces int Gewicht { get; } string Einheit { get; } int Price { get; } + + bool Legal { get; } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/BaseItem.cs b/ReallifeGamemode.Server/Inventory/Items/BaseItem.cs new file mode 100644 index 00000000..a47fdb82 --- /dev/null +++ b/ReallifeGamemode.Server/Inventory/Items/BaseItem.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ReallifeGamemode.Server.Inventory.Interfaces; + +namespace ReallifeGamemode.Server.Inventory.Items +{ + public abstract class BaseItem : IItem + { + public abstract int Id { get; } + public abstract string Name { get; } + public abstract string Description { get; } + public abstract int Gewicht { get; } + public abstract string Einheit { get; } + public abstract int Price { get; } + public virtual bool Legal => true; + } +} diff --git a/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs b/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs index a0845bd6..bd82e7af 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs @@ -9,13 +9,13 @@ using ReallifeGamemode.Server.Inventory.Interfaces; namespace ReallifeGamemode.Server.Inventory.Items { - public class Cannabis : ConsumableItem + public class Cannabis : DropItem { public override int Id => 108; - public override string Name => "Grünes Gift"; + public override string Name => "Cannabis"; - public override string Description => "puff puff and pass"; + public override string Description => "kein brokkoli"; public override int Gewicht => 2; @@ -24,14 +24,5 @@ namespace ReallifeGamemode.Server.Inventory.Items public override uint Object => 3076948544; public override int Price => 0; - - public override int HpAmount => -5; - - public override float Cooldown => 20000; - - public override void Consume(UserItem uItem) - { - //nothing - } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs b/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs index d5a96232..abfaa298 100644 --- a/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs +++ b/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs @@ -8,17 +8,17 @@ using ReallifeGamemode.Server.Util; namespace ReallifeGamemode.Server.Inventory.Items { - public abstract class ConsumableItem : IUsableItem + public abstract class ConsumableItem : BaseItem, IUsableItem { public abstract int HpAmount { get; } - public abstract int Id { get; } - public abstract string Name { get; } - public abstract string Description { get; } - public abstract int Gewicht { get; } - public abstract string Einheit { get; } - public abstract uint Object { get; } - public abstract int Price { get; } + public override int Id { get; } + public override string Name { get; } + public override string Description { get; } + public override int Gewicht { get; } + public override string Einheit { get; } + public override int Price { get; } public abstract float Cooldown { get; } + public abstract uint Object { get; } public abstract void Consume(UserItem uItem); diff --git a/ReallifeGamemode.Server/Inventory/Items/DropItem.cs b/ReallifeGamemode.Server/Inventory/Items/DropItem.cs index 52bf1fc2..e41f034a 100644 --- a/ReallifeGamemode.Server/Inventory/Items/DropItem.cs +++ b/ReallifeGamemode.Server/Inventory/Items/DropItem.cs @@ -6,15 +6,15 @@ using ReallifeGamemode.Server.Managers; namespace ReallifeGamemode.Server.Inventory.Items { - public abstract class DropItem : IDroppableItem + public abstract class DropItem : BaseItem, IDroppableItem { - public abstract int Id { get; } - public abstract string Name { get; } - public abstract string Description { get; } - public abstract int Gewicht { get; } - public abstract string Einheit { get; } + public override int Id { get; } + public override string Name { get; } + public override string Description { get; } + public override int Gewicht { get; } + public override string Einheit { get; } public abstract uint Object { get; } - public abstract int Price { get; } + public override int Price { get; } public void Drop(UserItem uItem, Player player, int amount) { diff --git a/ReallifeGamemode.Server/Inventory/Items/UseItem.cs b/ReallifeGamemode.Server/Inventory/Items/UseItem.cs index 7da16564..9674fb70 100644 --- a/ReallifeGamemode.Server/Inventory/Items/UseItem.cs +++ b/ReallifeGamemode.Server/Inventory/Items/UseItem.cs @@ -10,15 +10,15 @@ using ReallifeGamemode.Server.Managers; namespace ReallifeGamemode.Server.Inventory.Items { - public abstract class UseItem : IUsableItem + public abstract class UseItem : BaseItem, IUsableItem { - public abstract int Id { get; } - public abstract string Name { get; } - public abstract string Description { get; } - public abstract int Gewicht { get; } - public abstract string Einheit { get; } + public override int Id { get; } + public override string Name { get; } + public override string Description { get; } + public override int Gewicht { get; } + public override string Einheit { get; } + public override int Price { get; } public abstract uint Object { get; } - public abstract int Price { get; } public abstract bool Use(UserItem uItem); diff --git a/ReallifeGamemode.Server/Inventory/Items/WeaponDealItem.cs b/ReallifeGamemode.Server/Inventory/Items/WeaponDealItem.cs index d36904d7..b38a907a 100644 --- a/ReallifeGamemode.Server/Inventory/Items/WeaponDealItem.cs +++ b/ReallifeGamemode.Server/Inventory/Items/WeaponDealItem.cs @@ -6,15 +6,15 @@ using ReallifeGamemode.Server.WeaponDeal; namespace ReallifeGamemode.Server.Inventory.Items { - public abstract class WeaponDealItem : IWeaponDealItem + public abstract class WeaponDealItem : BaseItem, IWeaponDealItem { - public abstract int Id { get; } - public abstract string Name { get; } - public abstract string Description { get; } - public abstract int Gewicht { get; } - public abstract string Einheit { get; } + public override int Id { get; } + public override string Name { get; } + public override string Description { get; } + public override int Gewicht { get; } + public override string Einheit { get; } + public override int Price { get; } public abstract uint Object { get; } - public abstract int Price { get; } public bool noTransfer(Player client, UserItem uItem, FactionVehicle fVeh) { From 34033eb8757f1ded6ff91f778705efaab813e149 Mon Sep 17 00:00:00 2001 From: hydrant Date: Sat, 22 May 2021 14:52:29 +0200 Subject: [PATCH 02/10] Add Hanf items, some inventory mess removed --- .../html/inventory/img/inventory/108.svg | 37 +---------------- .../html/inventory/img/inventory/109.svg | 1 + .../html/inventory/img/inventory/110.svg | 1 + .../Commands/AdminCommands.cs | 21 ++++------ .../Inventory/Interfaces/IUsableItem.cs | 7 +++- .../Inventory/Items/Apfel.cs | 6 +-- .../Inventory/Items/AviateChips.cs | 6 +-- .../Inventory/Items/Baklava.cs | 6 +-- .../Inventory/Items/Bier.cs | 4 +- .../Inventory/Items/CannabisSeeds.cs | 17 ++++++++ .../Inventory/Items/Cheeseburger.cs | 6 +-- .../Inventory/Items/Chips.cs | 6 +-- .../Inventory/Items/Cocain.cs | 6 ++- .../Inventory/Items/ConsumableItem.cs | 17 ++++---- .../Inventory/Items/Joint.cs | 28 +++++++++++++ .../Inventory/Items/Kebab.cs | 6 +-- .../Inventory/Items/Notfallkit.cs | 18 ++++----- .../Inventory/Items/Rubellos.cs | 40 ++++++------------- .../Inventory/Items/UseItem.cs | 4 +- .../Managers/InventoryManager.cs | 24 +++++++---- 20 files changed, 126 insertions(+), 135 deletions(-) create mode 100644 ReallifeGamemode.Client/assets/html/inventory/img/inventory/109.svg create mode 100644 ReallifeGamemode.Client/assets/html/inventory/img/inventory/110.svg create mode 100644 ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs create mode 100644 ReallifeGamemode.Server/Inventory/Items/Joint.cs diff --git a/ReallifeGamemode.Client/assets/html/inventory/img/inventory/108.svg b/ReallifeGamemode.Client/assets/html/inventory/img/inventory/108.svg index 92a41b9c..a8f2824b 100644 --- a/ReallifeGamemode.Client/assets/html/inventory/img/inventory/108.svg +++ b/ReallifeGamemode.Client/assets/html/inventory/img/inventory/108.svg @@ -1,36 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/ReallifeGamemode.Client/assets/html/inventory/img/inventory/109.svg b/ReallifeGamemode.Client/assets/html/inventory/img/inventory/109.svg new file mode 100644 index 00000000..52ae40dd --- /dev/null +++ b/ReallifeGamemode.Client/assets/html/inventory/img/inventory/109.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ReallifeGamemode.Client/assets/html/inventory/img/inventory/110.svg b/ReallifeGamemode.Client/assets/html/inventory/img/inventory/110.svg new file mode 100644 index 00000000..cefab709 --- /dev/null +++ b/ReallifeGamemode.Client/assets/html/inventory/img/inventory/110.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ReallifeGamemode.Server/Commands/AdminCommands.cs b/ReallifeGamemode.Server/Commands/AdminCommands.cs index c1d5f487..3e12ecd9 100644 --- a/ReallifeGamemode.Server/Commands/AdminCommands.cs +++ b/ReallifeGamemode.Server/Commands/AdminCommands.cs @@ -2231,26 +2231,19 @@ namespace ReallifeGamemode.Server.Commands return; } - var invWeight = 0; + var invWeight = InventoryManager.GetUserInventoryWeight(target); - using (var context = new DatabaseContext()) - { - List userItems = context.UserItems.ToList().FindAll(i => i.UserId == target.GetUser().Id); - foreach (var uItem in userItems) - { - invWeight += uItem.Amount * InventoryManager.GetItemById(uItem.ItemId).Gewicht; - } - } + IItem item = InventoryManager.GetItemById(itemId); - if (invWeight + (amount * InventoryManager.GetItemById(itemId).Gewicht) > 40000) + if (invWeight + (amount * item.Gewicht) > InventoryManager.MAX_USER_INVENTORY) { ChatService.SendMessage(player, "~y~" + target.Name + " ~s~hat nicht mehr genug Platz in seinem Inventar."); } else { - UserItem item = new UserItem() { ItemId = itemId, UserId = target.GetUser().Id, Amount = amount }; - InventoryManager.AddItemToInventory(target, item.ItemId, item.Amount); - ChatService.SendMessage(player, "~b~[ADMIN]~s~ Du hast " + target.Name + " ~g~" + amount + "~s~ mal das Item gegeben."); + UserItem userItem = new UserItem() { ItemId = itemId, UserId = target.GetUser().Id, Amount = amount }; + InventoryManager.AddItemToInventory(target, userItem.ItemId, userItem.Amount); + ChatService.SendMessage(player, $"~b~[ADMIN]~s~ Du hast ~y~{target.Name}~y~ ~y~{amount}~s~ mal das Item ~y~{item.Name}~s~ gegeben."); } } @@ -2340,7 +2333,7 @@ namespace ReallifeGamemode.Server.Commands } [Command("inventory", "~m~Benutzung: ~s~/inventory [Spieler]")] - public void CmdAdminGiveItem(Player player, string targetname) + public void CmdAdminInventory(Player player, string targetname) { if (!player.GetUser()?.IsAdmin(AdminLevel.HEADADMIN) ?? true) { diff --git a/ReallifeGamemode.Server/Inventory/Interfaces/IUsableItem.cs b/ReallifeGamemode.Server/Inventory/Interfaces/IUsableItem.cs index 67650c24..24539b6c 100644 --- a/ReallifeGamemode.Server/Inventory/Interfaces/IUsableItem.cs +++ b/ReallifeGamemode.Server/Inventory/Interfaces/IUsableItem.cs @@ -1,4 +1,6 @@ -using ReallifeGamemode.Database.Entities; +using GTANetworkAPI; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; /** * @overview Life of German Reallife - Inventory Interfaces UsableItem (IUsableItem.cs) @@ -10,6 +12,7 @@ namespace ReallifeGamemode.Server.Inventory.Interfaces { public interface IUsableItem : IItem, IDroppableItem //marker Interface { - bool Use(UserItem uItem); + bool RemoveWhenUsed { get; } + bool Use(Player player, User user, DatabaseContext databaseContext); } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Apfel.cs b/ReallifeGamemode.Server/Inventory/Items/Apfel.cs index 4b396c17..81fafb8b 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Apfel.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Apfel.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Managers; @@ -20,10 +21,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override int Price => 50; public override float Cooldown => 60000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - int amountToAdd = HpAmount; if (player.Health + amountToAdd > 100) { @@ -32,7 +31,6 @@ namespace ReallifeGamemode.Server.Inventory.Items player.SafeSetHealth(player.Health + amountToAdd); player.SendNotification("Du hast einen ~y~" + Name + " ~s~gegessen.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/AviateChips.cs b/ReallifeGamemode.Server/Inventory/Items/AviateChips.cs index b65f0f86..49b597fb 100644 --- a/ReallifeGamemode.Server/Inventory/Items/AviateChips.cs +++ b/ReallifeGamemode.Server/Inventory/Items/AviateChips.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Managers; @@ -21,10 +22,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override float Cooldown => 60000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - int amountToAdd = HpAmount; if (player.Health + amountToAdd > 100) { @@ -33,7 +32,6 @@ namespace ReallifeGamemode.Server.Inventory.Items player.SafeSetHealth(player.Health + amountToAdd); player.SendNotification("Du hast ~y~" + Name + " ~s~gegessen.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Baklava.cs b/ReallifeGamemode.Server/Inventory/Items/Baklava.cs index e5825cf8..6b07dfdc 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Baklava.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Baklava.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Managers; @@ -21,10 +22,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override float Cooldown => 180000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - int amountToAdd = HpAmount; if (player.Health + amountToAdd > 100) { @@ -33,7 +32,6 @@ namespace ReallifeGamemode.Server.Inventory.Items player.SafeSetHealth(player.Health + amountToAdd); player.SendNotification("Du hast ein ~y~" + Name + " ~s~gegessen.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Bier.cs b/ReallifeGamemode.Server/Inventory/Items/Bier.cs index 99fc67a5..73852580 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Bier.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Bier.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Text; +using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; namespace ReallifeGamemode.Server.Inventory.Items { @@ -18,7 +20,7 @@ namespace ReallifeGamemode.Server.Inventory.Items public override float Cooldown => 1000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { //nothing } diff --git a/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs b/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs new file mode 100644 index 00000000..63f0f0db --- /dev/null +++ b/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReallifeGamemode.Server.Inventory.Items +{ + public class CannabisSeeds : BaseItem + { + public override int Id { get; } = 109; + public override string Name { get; } = "Cannabis Samen"; + public override string Description { get; } = "vierhundertzwanzig lodere es"; + public override int Gewicht { get; } = 10; + public override string Einheit { get; } = "g"; + public override int Price { get; } = 0; + public override bool Legal => false; + } +} diff --git a/ReallifeGamemode.Server/Inventory/Items/Cheeseburger.cs b/ReallifeGamemode.Server/Inventory/Items/Cheeseburger.cs index 225962ba..38f0775c 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Cheeseburger.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Cheeseburger.cs @@ -1,5 +1,6 @@ using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Managers; @@ -23,10 +24,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override int Price => 100; public override float Cooldown => 120000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - int amountToAdd = HpAmount; if (player.Health + amountToAdd > 100) { @@ -35,7 +34,6 @@ namespace ReallifeGamemode.Server.Inventory.Items player.SafeSetHealth(player.Health + amountToAdd); player.SendNotification("Du hast einen ~y~" + Name + " ~s~gegessen.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Chips.cs b/ReallifeGamemode.Server/Inventory/Items/Chips.cs index 3198deb5..a6cb4623 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Chips.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Chips.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Managers; @@ -21,10 +22,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override float Cooldown => 30000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - int amountToAdd = HpAmount; if (player.Health + amountToAdd > 100) { @@ -33,7 +32,6 @@ namespace ReallifeGamemode.Server.Inventory.Items player.SafeSetHealth(player.Health + amountToAdd); player.SendNotification("Du hast ~y~" + Name + " ~s~gegessen.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Cocain.cs b/ReallifeGamemode.Server/Inventory/Items/Cocain.cs index 60e5000c..3137798e 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Cocain.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Cocain.cs @@ -1,4 +1,6 @@ -using ReallifeGamemode.Database.Entities; +using GTANetworkAPI; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; /** * @overview Life of German Reallife - Inventory Items Chickenburger (Chickenburger.cs) @@ -21,7 +23,7 @@ namespace ReallifeGamemode.Server.Inventory.Items public override float Cooldown => 20000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { //nothing } diff --git a/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs b/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs index abfaa298..ea7d5f90 100644 --- a/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs +++ b/ReallifeGamemode.Server/Inventory/Items/ConsumableItem.cs @@ -1,6 +1,7 @@ using System; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Inventory.Interfaces; using ReallifeGamemode.Server.Managers; @@ -8,7 +9,7 @@ using ReallifeGamemode.Server.Util; namespace ReallifeGamemode.Server.Inventory.Items { - public abstract class ConsumableItem : BaseItem, IUsableItem + public abstract class ConsumableItem : UseItem { public abstract int HpAmount { get; } public override int Id { get; } @@ -18,28 +19,28 @@ namespace ReallifeGamemode.Server.Inventory.Items public override string Einheit { get; } public override int Price { get; } public abstract float Cooldown { get; } - public abstract uint Object { get; } + public abstract override uint Object { get; } + public override bool RemoveWhenUsed => true; - public abstract void Consume(UserItem uItem); + public abstract void Consume(Player player, User user, DatabaseContext databaseContext); - public bool Use(UserItem uItem) + public override bool Use(Player player, User user, DatabaseContext databaseContext) { - User user = uItem.GetUser(); if (user.Player == null || !user.Player.IsLoggedIn()) return false; - if (!HasCooldownElapsed(user)) + if (!HasCooldownElapsed(user) && Cooldown > 0) { DateTime time = InventoryManager.itemCooldown[user.Id]; int timeUntillNextUse = (int)(time - DateTime.Now).TotalSeconds; - uItem.GetUser().Player.TriggerEvent("Error", $"Versuche es nach {timeUntillNextUse} Sekunden erneut."); + user.Player.TriggerEvent("Error", $"Versuche es nach {timeUntillNextUse} Sekunden erneut."); return false; } DateTime cooldown = DateTime.Now.AddMilliseconds(Cooldown); InventoryManager.itemCooldown.Add(user.Id, cooldown); - Consume(uItem); + Consume(player, user, databaseContext); return true; } diff --git a/ReallifeGamemode.Server/Inventory/Items/Joint.cs b/ReallifeGamemode.Server/Inventory/Items/Joint.cs new file mode 100644 index 00000000..27bfc0d6 --- /dev/null +++ b/ReallifeGamemode.Server/Inventory/Items/Joint.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; +using ReallifeGamemode.Server.Services; + +namespace ReallifeGamemode.Server.Inventory.Items +{ + public class Joint : UseItem + { + public override int Id { get; } = 110; + public override string Name { get; } = "Joint"; + public override string Description { get; } = "stay high bis zum tod"; + public override int Gewicht { get; } = 20; + public override string Einheit { get; } = "g"; + public override int Price { get; } = 0; + public override uint Object { get; } + public override bool Legal => false; + public override bool RemoveWhenUsed => true; + + public override bool Use(Player player, User user, DatabaseContext databaseContext) + { + return true; + } + } +} diff --git a/ReallifeGamemode.Server/Inventory/Items/Kebab.cs b/ReallifeGamemode.Server/Inventory/Items/Kebab.cs index 508e9c50..eced1333 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Kebab.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Kebab.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Managers; @@ -21,10 +22,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override float Cooldown => 300000; - public override void Consume(UserItem uItem) + public override void Consume(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - int amountToAdd = HpAmount; if (player.Health + amountToAdd > 100) { @@ -33,7 +32,6 @@ namespace ReallifeGamemode.Server.Inventory.Items player.SafeSetHealth(player.Health + amountToAdd); player.SendNotification("Du hast ein ~y~" + Name + " ~s~gegessen.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); } } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs b/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs index b6d19fe3..4a5bfe40 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs @@ -19,17 +19,12 @@ namespace ReallifeGamemode.Server.Inventory.Items public override uint Object => 875075437; public override int Price => 2500; - public override bool Use(UserItem uItem) + public override bool RemoveWhenUsed { get; } = true; + + public override bool Use(Player player, User user, DatabaseContext databaseContext) { - Player player = uItem.GetUser().Player; - - if (uItem.ItemId != 201) - { - return false; - } - Vehicle veh = null; - + var nearestVeh = NAPI.Pools.GetAllVehicles().Where(v => v.Position.DistanceTo(player.Position) <= 5).FirstOrDefault(); veh = nearestVeh; @@ -39,13 +34,13 @@ namespace ReallifeGamemode.Server.Inventory.Items return false; } - if(player.IsInVehicle) + if (player.IsInVehicle) { player.SendNotification("Du musst aus deinem Fahrzeug aussteigen!"); return false; } - if(veh.Controller == null) + if (veh.Controller == null) { player.SendNotification("Du kannst dieses Fahrzeug nicht reparieren, weil Jemand bereits im Fahrzeug sitzt"); return false; @@ -62,6 +57,7 @@ namespace ReallifeGamemode.Server.Inventory.Items Vector3 position = veh.Position; player.SendNotification("Du hast ~g~" + InventoryManager.GetItemById(uItem.ItemId).Name + " ~s~verwendet", false); InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); + InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); ServerVehicle serverVehicle = veh.GetServerVehicle(dbContext); serverVehicle.Spawn(veh).Position = position; Vehicle newVeh = serverVehicle.Spawn(veh); diff --git a/ReallifeGamemode.Server/Inventory/Items/Rubellos.cs b/ReallifeGamemode.Server/Inventory/Items/Rubellos.cs index 4a36ce7f..416252a6 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Rubellos.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Rubellos.cs @@ -19,40 +19,24 @@ namespace ReallifeGamemode.Server.Inventory.Items public override string Einheit => "g"; public override uint Object => 875075437; public override int Price => 500; + public override bool RemoveWhenUsed => true; - public override bool Use(UserItem uItem) - { - Player player = uItem.GetUser().Player; - - if (uItem.ItemId != 200) + public override bool Use(Player player, User user, DatabaseContext databaseContext) { - return false; - } - Random random = new Random(); - int randomNumber = random.Next(1, 4); - if (randomNumber == 1) - { - using (var dbContext = new DatabaseContext()) + Random random = new Random(); + int randomNumber = random.Next(1, 2); + if (randomNumber == 1) { - User winner = player.GetUser(dbContext); - winner.Handmoney += 1000; + user.Handmoney += 1000; //player.TriggerEvent("SERVER:SET_HANDMONEY", winner.Handmoney); - dbContext.SaveChanges(); - } player.SendNotification("Glückwunsch du hast ~g~$~w~1000 gewonnen!"); - } - else - { + } + else + { player.SendNotification("Leider kein Gewinn, viel Glück beim nächsten mal."); + } + player.SendNotification("Du hast ein ~g~" + Name + " ~s~verwendet.", false); + return true; } - player.SendNotification("Du hast ~g~" + InventoryManager.GetItemById(uItem.ItemId).Name + " ~s~verwendet.", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); - return true; } - - -} - - - } diff --git a/ReallifeGamemode.Server/Inventory/Items/UseItem.cs b/ReallifeGamemode.Server/Inventory/Items/UseItem.cs index 9674fb70..59cf30ea 100644 --- a/ReallifeGamemode.Server/Inventory/Items/UseItem.cs +++ b/ReallifeGamemode.Server/Inventory/Items/UseItem.cs @@ -19,8 +19,8 @@ namespace ReallifeGamemode.Server.Inventory.Items public override string Einheit { get; } public override int Price { get; } public abstract uint Object { get; } + public abstract bool RemoveWhenUsed { get; } - public abstract bool Use(UserItem uItem); - + public abstract bool Use(Player player, User user, DatabaseContext databaseContext); } } diff --git a/ReallifeGamemode.Server/Managers/InventoryManager.cs b/ReallifeGamemode.Server/Managers/InventoryManager.cs index 38d5d00d..4658cd12 100644 --- a/ReallifeGamemode.Server/Managers/InventoryManager.cs +++ b/ReallifeGamemode.Server/Managers/InventoryManager.cs @@ -27,7 +27,7 @@ namespace ReallifeGamemode.Server.Managers { public class InventoryManager : Script { - private const int MAX_USER_INVENTORY = 40000; + public const int MAX_USER_INVENTORY = 40000; private static readonly ILogger logger = LogManager.GetLogger(); public static List itemList; @@ -82,7 +82,11 @@ namespace ReallifeGamemode.Server.Managers { player.TriggerEvent("Error", "Du kannst deinen Kofferraum gerade nicht öffnen."); } - Vehicle veh = NAPI.Pools.GetAllVehicles().ToList().Where(v => v.Position.DistanceTo(player.Position) <= 4).FirstOrDefault(); + Vehicle veh = NAPI.Pools.GetAllVehicles() + .ToList() + .Where(v => v.Position.DistanceTo(player.Position) <= 4) + .OrderBy(v => v.Position.DistanceTo(player.Position)) + .FirstOrDefault(); if (veh == null) { player.TriggerEvent("Error", "Kein Fahrzeug in der Nähe!"); @@ -270,7 +274,7 @@ namespace ReallifeGamemode.Server.Managers } } - public static void GetUserItemsAsAdmin(Player player, User user) + public static void GetUserItemsAsAdmin(Player admin, User user) { var inventoryWeight = 0; @@ -292,7 +296,7 @@ namespace ReallifeGamemode.Server.Managers items[userItems.IndexOf(item)][4] = item.Slot.ToString(); items[userItems.IndexOf(item)][5] = item.Id.ToString(); } - player.TriggerEvent("showInventoryToAdmin", user.Name, inventoryWeight, items); + admin.TriggerEvent("showInventoryToAdmin", user.Name, inventoryWeight, items); } } @@ -510,10 +514,10 @@ namespace ReallifeGamemode.Server.Managers int itemId = JsonConvert.DeserializeObject(jsonItemId); string type = JsonConvert.DeserializeObject(jsonType); - User user = player.GetUser(); using (var context = new DatabaseContext()) { + User user = player.GetUser(context); UserItem fItem = context.UserItems.Where(u => u.UserId == user.Id && u.ItemId == itemId).FirstOrDefault(); IItem iItem = GetItemById(fItem.ItemId); @@ -534,8 +538,14 @@ namespace ReallifeGamemode.Server.Managers if (iItem is IUsableItem usableItemObj) { - if (usableItemObj.Use(fItem)) + logger.LogInformation("Player {0} used the item {1} ({2})", player.Name, iItem.Name, iItem.Id); + if (usableItemObj.Use(player, user, context)) { + if (usableItemObj.RemoveWhenUsed) + { + RemoveUserItem(user, fItem, 1); + } + SetBackpackItems(player); player.TriggerEvent("aproveUse", 1, iItem.Name); } @@ -559,6 +569,7 @@ namespace ReallifeGamemode.Server.Managers if (iItem is IDroppableItem usableItemObj2) { + logger.LogInformation("Player {0} dropped the item {1} ({2})", player.Name, iItem.Name, iItem.Id); Vector3 dropPosition = PlayerExtension.GetPositionFromPlayer(player, 0.6f, 0); //new Vector3(player.Position.X, player.Position.Y, player.Position.Z - 0.8f); Random r = new Random(); @@ -617,7 +628,6 @@ namespace ReallifeGamemode.Server.Managers if (GetUserInventoryWeight(client) + shopItem.Gewicht > MAX_USER_INVENTORY) { - return; } From 848353053b12ad113c28f227e327708b0aa6b5b0 Mon Sep 17 00:00:00 2001 From: hydrant Date: Sat, 22 May 2021 19:10:40 +0200 Subject: [PATCH 03/10] addserver function to set inventory show --- ReallifeGamemode.Client/inventory/inventory.ts | 6 +++--- ReallifeGamemode.Server/Events/Key.cs | 2 +- .../Extensions/ClientExtension.cs | 12 ++++++++++++ .../Util/InventoryToggleOption.cs | 11 +++++++++++ 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 ReallifeGamemode.Server/Util/InventoryToggleOption.cs diff --git a/ReallifeGamemode.Client/inventory/inventory.ts b/ReallifeGamemode.Client/inventory/inventory.ts index 1f2a7504..05a90982 100644 --- a/ReallifeGamemode.Client/inventory/inventory.ts +++ b/ReallifeGamemode.Client/inventory/inventory.ts @@ -21,14 +21,14 @@ invBrowser = mp.browsers.new('package://assets/html/inventory/inventory.html'); }); - mp.events.add('inventoryShow', () => { - if (!globalData.InMenu && !loaded) { + mp.events.add('inventoryShow', (force = undefined) => { + if (!globalData.InMenu && !loaded || force === true) { globalData.InMenu = true; mp.gui.cursor.show(true, true); loaded = true; invBrowser.execute(`showInventory()`); - } else if (loaded) { + } else if (loaded || force === true) { globalData.InMenu = false; mp.gui.cursor.show(false, false); loaded = false; diff --git a/ReallifeGamemode.Server/Events/Key.cs b/ReallifeGamemode.Server/Events/Key.cs index 234616eb..b77f8649 100644 --- a/ReallifeGamemode.Server/Events/Key.cs +++ b/ReallifeGamemode.Server/Events/Key.cs @@ -769,7 +769,7 @@ namespace ReallifeGamemode.Server.Events if (!player.IsLoggedIn() || player.GetData("isDead")) return; if (player.GetData("isDead")) return; - player.TriggerEvent("inventoryShow"); + player.ToggleInventory(); InventoryManager.SetBackpackItems(player); } diff --git a/ReallifeGamemode.Server/Extensions/ClientExtension.cs b/ReallifeGamemode.Server/Extensions/ClientExtension.cs index 817d2ee4..2ffa1af2 100644 --- a/ReallifeGamemode.Server/Extensions/ClientExtension.cs +++ b/ReallifeGamemode.Server/Extensions/ClientExtension.cs @@ -477,5 +477,17 @@ namespace ReallifeGamemode.Server.Extensions if (player.GetUser().Wanteds > 0) PositionManager.cuffPoints.Add(player); } + + public static void ToggleInventory(this Player player, InventoryToggleOption option = InventoryToggleOption.TOGGLE) + { + if(option == InventoryToggleOption.TOGGLE) + { + player.TriggerEvent("inventoryShow"); + } + else + { + player.TriggerEvent("inventoryShow", option == InventoryToggleOption.SHOW); + } + } } } diff --git a/ReallifeGamemode.Server/Util/InventoryToggleOption.cs b/ReallifeGamemode.Server/Util/InventoryToggleOption.cs new file mode 100644 index 00000000..863e6210 --- /dev/null +++ b/ReallifeGamemode.Server/Util/InventoryToggleOption.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReallifeGamemode.Server.Util +{ + public enum InventoryToggleOption + { + TOGGLE, SHOW, HIDE + } +} From d72f7216cc8e4b7778f5a80161ad76a83ead423f Mon Sep 17 00:00:00 2001 From: hydrant Date: Sun, 23 May 2021 20:18:30 +0200 Subject: [PATCH 04/10] fix pedmanager --- ReallifeGamemode.Client/Ped/PedCreator.ts | 30 +++++++++++++++---- .../Managers/PedManager.cs | 3 +- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ReallifeGamemode.Client/Ped/PedCreator.ts b/ReallifeGamemode.Client/Ped/PedCreator.ts index 600599be..0048c40b 100644 --- a/ReallifeGamemode.Client/Ped/PedCreator.ts +++ b/ReallifeGamemode.Client/Ped/PedCreator.ts @@ -741,28 +741,48 @@ u_m_y_tattoo_01: 0x94AE2B8C, u_m_y_zombie_01: 0xAC4B4506, } - var CreatedPeds = []; + var CreatedPeds: Array = []; mp.events.add("SERVER:CreateStaticPeds", (jsonVector3s, jsonHeadings, jsonCharHashes, jsonDimension) => { var vector3s = JSON.parse(jsonVector3s); var headings = JSON.parse(jsonHeadings); var charHashes = JSON.parse(jsonCharHashes); + var dimension = JSON.parse(jsonDimension); for (var i = 0; i < vector3s.length; i++) { - let p = mp.peds.new(Number(charHashes[i]), vector3s[i], headings[i], dimension[i]); + var hash = charHashes[i]; + + var tmpHash = getPedHashByName(hash); + if (tmpHash != -1) { + hash = tmpHash; + } + + //mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`); + + let p = mp.peds.new(hash, vector3s[i], headings[i], dimension[i]); p.freezePosition(true); p.setInvincible(true); - p.setCollision(false, false); + //p.setCollision(false, false); CreatedPeds.push(p); } }); mp.events.add('entityStreamIn', (entity: EntityMp) => { CreatedPeds.forEach(function (p) { if (entity == p) { - + p.freezePosition(true); p.setInvincible(true); - p.setCollision(false, false); + //p.setCollision(false, false); } }); }); + + function getPedHashByName(name: string) { + var keys = Object.keys(PedHashes); + var idx = keys.indexOf(name) !== -1; + if (idx) { + return PedHashes[name]; + } + + return -1; + } } \ No newline at end of file diff --git a/ReallifeGamemode.Server/Managers/PedManager.cs b/ReallifeGamemode.Server/Managers/PedManager.cs index 0a176366..0bc860c9 100644 --- a/ReallifeGamemode.Server/Managers/PedManager.cs +++ b/ReallifeGamemode.Server/Managers/PedManager.cs @@ -68,7 +68,8 @@ namespace ReallifeGamemode.Server.Managers { WeponDealPed, DepartmentPed, - PrisonPed + PrisonPed, + } public class PedData From a49fcf09c7ddd597f13ca0c19619e226f9e12363 Mon Sep 17 00:00:00 2001 From: hydrant Date: Mon, 24 May 2021 00:04:55 +0200 Subject: [PATCH 05/10] samen kaufen und hanf -> joint --- ReallifeGamemode.Client/Ped/PedCreator.ts | 1515 +++++++++-------- ReallifeGamemode.Client/drugs/hanf.ts | 67 + ReallifeGamemode.Client/index.ts | 3 + ReallifeGamemode.Client/util/animationSync.ts | 64 +- ReallifeGamemode.Server/BaseScript.cs | 19 + ReallifeGamemode.Server/Events/Key.cs | 14 + .../Inventory/Items/Joint.cs | 4 +- ReallifeGamemode.Server/Main.cs | 1 + .../Managers/HanfManager.cs | 178 ++ .../Managers/InventoryManager.cs | 37 +- ReallifeGamemode.Server/Util/Colors.cs | 12 + 11 files changed, 1126 insertions(+), 788 deletions(-) create mode 100644 ReallifeGamemode.Client/drugs/hanf.ts create mode 100644 ReallifeGamemode.Server/BaseScript.cs create mode 100644 ReallifeGamemode.Server/Managers/HanfManager.cs create mode 100644 ReallifeGamemode.Server/Util/Colors.cs diff --git a/ReallifeGamemode.Client/Ped/PedCreator.ts b/ReallifeGamemode.Client/Ped/PedCreator.ts index 0048c40b..e2559dbd 100644 --- a/ReallifeGamemode.Client/Ped/PedCreator.ts +++ b/ReallifeGamemode.Client/Ped/PedCreator.ts @@ -1,747 +1,751 @@ -export default function PedCreator() { - // Update 04/03/2020, Ped count [739] - var PedHashes = { - a_c_boar: 0xCE5FF074, - a_c_cat_01: 0x573201B8, - a_c_chickenhawk: 0xAAB71F62, - a_c_chimp: 0xA8683715, - a_c_chop: 0x14EC17EA, - a_c_cormorant: 0x56E29962, - a_c_cow: 0xFCFA9E1E, - a_c_coyote: 0x644AC75E, - a_c_crow: 0x18012A9F, - a_c_deer: 0xD86B5A95, - a_c_dolphin: 0x8BBAB455, - a_c_fish: 0x2FD800B7, - a_c_hen: 0x6AF51FAF, - a_c_humpback: 0x471BE4B2, - a_c_husky: 0x4E8F95A2, - a_c_killerwhale: 0x8D8AC8B9, - a_c_mtlion: 0x1250D7BA, - a_c_pig: 0xB11BAB56, - a_c_pigeon: 0x06A20728, - a_c_poodle: 0x431D501C, - a_c_pug: 0x6D362854, - a_c_rabbit_01: 0xDFB55C81, - a_c_rat: 0xC3B52966, - a_c_retriever: 0x349F33E1, - a_c_rhesus: 0xC2D06F53, - a_c_rottweiler: 0x9563221D, - a_c_seagull: 0xD3939DFD, - a_c_sharkhammer: 0x3C831724, - a_c_sharktiger: 0x06C3F072, - a_c_shepherd: 0x431FC24C, - a_c_stingray: 0xA148614D, - a_c_westy: 0xAD7844BB, - a_f_m_beach_01: 0x303638A7, - a_f_m_bevhills_01: 0xBE086EFD, - a_f_m_bevhills_02: 0xA039335F, - a_f_m_bodybuild_01: 0x3BD99114, - a_f_m_business_02: 0x1FC37DBC, - a_f_m_downtown_01: 0x654AD86E, - a_f_m_eastsa_01: 0x9D3DCB7A, - a_f_m_eastsa_02: 0x63C8D891, - a_f_m_fatbla_01: 0xFAB48BCB, - a_f_m_fatcult_01: 0xB5CF80E4, - a_f_m_fatwhite_01: 0x38BAD33B, - a_f_m_ktown_01: 0x52C824DE, - a_f_m_ktown_02: 0x41018151, - a_f_m_prolhost_01: 0x169BD1E1, - a_f_m_salton_01: 0xDE0E0969, - a_f_m_skidrow_01: 0xB097523B, - a_f_m_soucent_01: 0x745855A1, - a_f_m_soucent_02: 0xF322D338, - a_f_m_soucentmc_01: 0xCDE955D2, - a_f_m_tourist_01: 0x505603B9, - a_f_m_tramp_01: 0x48F96F5B, - a_f_m_trampbeac_01: 0x8CA0C266, - a_f_o_genstreet_01: 0x61C81C85, - a_f_o_indian_01: 0xBAD7BB80, - a_f_o_ktown_01: 0x47CF5E96, - a_f_o_salton_01: 0xCCFF7D8A, - a_f_o_soucent_01: 0x3DFA1830, - a_f_o_soucent_02: 0xA56DE716, - a_f_y_beach_01: 0xC79F6928, - a_f_y_bevhills_01: 0x445AC854, - a_f_y_bevhills_02: 0x5C2CF7F8, - a_f_y_bevhills_03: 0x20C8012F, - a_f_y_bevhills_04: 0x36DF2D5D, - a_f_y_business_01: 0x2799EFD8, - a_f_y_business_02: 0x31430342, - a_f_y_business_03: 0xAE86FDB4, - a_f_y_business_04: 0xB7C61032, - a_f_y_eastsa_01: 0xF5B0079D, - a_f_y_eastsa_02: 0x0438A4AE, - a_f_y_eastsa_03: 0x51C03FA4, - a_f_y_epsilon_01: 0x689C2A80, - a_f_y_femaleagent: 0x50610C43, - a_f_y_fitness_01: 0x457C64FB, - a_f_y_fitness_02: 0x13C4818C, - a_f_y_genhot_01: 0x2F4AEC3E, - a_f_y_golfer_01: 0x7DD8FB58, - a_f_y_hiker_01: 0x30830813, - a_f_y_hippie_01: 0x1475B827, - a_f_y_hipster_01: 0x8247D331, - a_f_y_hipster_02: 0x97F5FE8D, - a_f_y_hipster_03: 0xA5BA9A16, - a_f_y_hipster_04: 0x199881DC, - a_f_y_indian_01: 0x092D9CC1, - a_f_y_juggalo_01: 0xDB134533, - a_f_y_runner_01: 0xC7496729, - a_f_y_rurmeth_01: 0x3F789426, - a_f_y_scdressy_01: 0xDB5EC400, - a_f_y_skater_01: 0x695FE666, - a_f_y_soucent_01: 0x2C641D7A, - a_f_y_soucent_02: 0x5A8EF9CF, - a_f_y_soucent_03: 0x87B25415, - a_f_y_tennis_01: 0x550C79C6, - a_f_y_topless_01: 0x9CF26183, - a_f_y_tourist_01: 0x563B8570, - a_f_y_tourist_02: 0x9123FB40, - a_f_y_vinewood_01: 0x19F41F65, - a_f_y_vinewood_02: 0xDAB6A0EB, - a_f_y_vinewood_03: 0x379DDAB8, - a_f_y_vinewood_04: 0xFAE46146, - a_f_y_yoga_01: 0xC41B062E, - a_m_m_acult_01: 0x5442C66B, - a_m_m_afriamer_01: 0xD172497E, - a_m_m_beach_01: 0x403DB4FD, - a_m_m_beach_02: 0x787FA588, - a_m_m_bevhills_01: 0x54DBEE1F, - a_m_m_bevhills_02: 0x3FB5C3D3, - a_m_m_business_01: 0x7E6A64B7, - a_m_m_eastsa_01: 0xF9A6F53F, - a_m_m_eastsa_02: 0x07DD91AC, - a_m_m_farmer_01: 0x94562DD7, - a_m_m_fatlatin_01: 0x61D201B3, - a_m_m_genfat_01: 0x06DD569F, - a_m_m_genfat_02: 0x13AEF042, - a_m_m_golfer_01: 0xA9EB0E42, - a_m_m_hasjew_01: 0x6BD9B68C, - a_m_m_hillbilly_01: 0x6C9B2849, - a_m_m_hillbilly_02: 0x7B0E452F, - a_m_m_indian_01: 0xDDCAAA2C, - a_m_m_ktown_01: 0xD15D7E71, - a_m_m_malibu_01: 0x2FDE6EB7, - a_m_m_mexcntry_01: 0xDD817EAD, - a_m_m_mexlabor_01: 0xB25D16B2, - a_m_m_og_boss_01: 0x681BD012, - a_m_m_paparazzi_01: 0xECCA8C15, - a_m_m_polynesian_01: 0xA9D9B69E, - a_m_m_prolhost_01: 0x9712C38F, - a_m_m_rurmeth_01: 0x3BAD4184, - a_m_m_salton_01: 0x4F2E038A, - a_m_m_salton_02: 0x60F4A717, - a_m_m_salton_03: 0xB28C4A45, - a_m_m_salton_04: 0x964511B7, - a_m_m_skater_01: 0xD9D7588C, - a_m_m_skidrow_01: 0x01EEA6BD, - a_m_m_socenlat_01: 0x0B8D69E3, - a_m_m_soucent_01: 0x6857C9B7, - a_m_m_soucent_02: 0x9F6D37E1, - a_m_m_soucent_03: 0x8BD990BA, - a_m_m_soucent_04: 0xC2FBFEFE, - a_m_m_stlat_02: 0xC2A87702, - a_m_m_tennis_01: 0x546A5344, - a_m_m_tourist_01: 0xC89F0184, - a_m_m_tramp_01: 0x1EC93FD0, - a_m_m_trampbeac_01: 0x53B57EB0, - a_m_m_tranvest_01: 0xE0E69974, - a_m_m_tranvest_02: 0xF70EC5C4, - a_m_o_acult_01: 0x55446010, - a_m_o_acult_02: 0x4BA14CCA, - a_m_o_beach_01: 0x8427D398, - a_m_o_genstreet_01: 0xAD54E7A8, - a_m_o_ktown_01: 0x1536D95A, - a_m_o_salton_01: 0x20208E4D, - a_m_o_soucent_01: 0x2AD8921B, - a_m_o_soucent_02: 0x4086BD77, - a_m_o_soucent_03: 0x0E32D8D0, - a_m_o_tramp_01: 0x174D4245, - a_m_y_acult_01: 0xB564882B, - a_m_y_acult_02: 0x80E59F2E, - a_m_y_beach_01: 0xD1FEB884, - a_m_y_beach_02: 0x23C7DC11, - a_m_y_beach_03: 0xE7A963D9, - a_m_y_beachvesp_01: 0x7E0961B8, - a_m_y_beachvesp_02: 0xCA56FA52, - a_m_y_bevhills_01: 0x76284640, - a_m_y_bevhills_02: 0x668BA707, - a_m_y_breakdance_01: 0x379F9596, - a_m_y_busicas_01: 0x9AD32FE9, - a_m_y_business_01: 0xC99F21C4, - a_m_y_business_02: 0xB3B3F5E6, - a_m_y_business_03: 0xA1435105, - a_m_y_cyclist_01: 0xFDC653C7, - a_m_y_dhill_01: 0xFF3E88AB, - a_m_y_downtown_01: 0x2DADF4AA, - a_m_y_eastsa_01: 0xA4471173, - a_m_y_eastsa_02: 0x168775F6, - a_m_y_epsilon_01: 0x77D41A3E, - a_m_y_epsilon_02: 0xAA82FF9B, - a_m_y_gay_01: 0xD1CCE036, - a_m_y_gay_02: 0xA5720781, - a_m_y_genstreet_01: 0x9877EF71, - a_m_y_genstreet_02: 0x3521A8D2, - a_m_y_golfer_01: 0xD71FE131, - a_m_y_hasjew_01: 0xE16D8F01, - a_m_y_hiker_01: 0x50F73C0C, - a_m_y_hippy_01: 0x7D03E617, - a_m_y_hipster_01: 0x2307A353, - a_m_y_hipster_02: 0x14D506EE, - a_m_y_hipster_03: 0x4E4179C6, - a_m_y_indian_01: 0x2A22FBCE, - a_m_y_jetski_01: 0x2DB7EEF3, - a_m_y_juggalo_01: 0x91CA3E2C, - a_m_y_ktown_01: 0x1AF6542C, - a_m_y_ktown_02: 0x297FF13F, - a_m_y_latino_01: 0x132C1A8E, - a_m_y_methhead_01: 0x696BE0A9, - a_m_y_mexthug_01: 0x3053E555, - a_m_y_motox_01: 0x64FDEA7D, - a_m_y_motox_02: 0x77AC8FDA, - a_m_y_musclbeac_01: 0x4B652906, - a_m_y_musclbeac_02: 0xC923247C, - a_m_y_polynesian_01: 0x8384FC9F, - a_m_y_roadcyc_01: 0xF561A4C6, - a_m_y_runner_01: 0x25305EEE, - a_m_y_runner_02: 0x843D9D0F, - a_m_y_salton_01: 0xD7606C30, - a_m_y_skater_01: 0xC1C46677, - a_m_y_skater_02: 0xAFFAC2E4, - a_m_y_soucent_01: 0xE716BDCB, - a_m_y_soucent_02: 0xACA3C8CA, - a_m_y_soucent_03: 0xC3F0F764, - a_m_y_soucent_04: 0x8A3703F1, - a_m_y_stbla_01: 0xCF92ADE9, - a_m_y_stbla_02: 0x98C7404F, - a_m_y_stlat_01: 0x8674D5FC, - a_m_y_stwhi_01: 0x2418C430, - a_m_y_stwhi_02: 0x36C6E98C, - a_m_y_sunbathe_01: 0xB7292F0C, - a_m_y_surfer_01: 0xEAC2C7EE, - a_m_y_vindouche_01: 0xC19377E7, - a_m_y_vinewood_01: 0x4B64199D, - a_m_y_vinewood_02: 0x5D15BD00, - a_m_y_vinewood_03: 0x1FDF4294, - a_m_y_vinewood_04: 0x31C9E669, - a_m_y_yoga_01: 0xAB0A7155, - cs_amandatownley: 0x95EF18E3, - cs_andreas: 0xE7565327, - cs_ashley: 0x26C3D079, - cs_bankman: 0x9760192E, - cs_barry: 0x69591CF7, - cs_beverly: 0xB46EC356, - cs_brad: 0xEFE5AFE6, - cs_bradcadaver: 0x7228AF60, - cs_carbuyer: 0x8CCE790F, - cs_casey: 0xEA969C40, - cs_chengsr: 0x30DB9D7B, - cs_chrisformage: 0xC1F380E6, - cs_clay: 0xDBCB9834, - cs_dale: 0x0CE81655, - cs_davenorton: 0x8587248C, - cs_debra: 0xECD04FE9, - cs_denise: 0x6F802738, - cs_devin: 0x2F016D02, - cs_dom: 0x4772AF42, - cs_dreyfuss: 0x3C60A153, - cs_drfriedlander: 0xA3A35C2F, - cs_fabien: 0x47035EC1, - cs_fbisuit_01: 0x585C0B52, - cs_floyd: 0x062547E7, - cs_guadalope: 0x0F9513F1, - cs_gurk: 0xC314F727, - cs_hunter: 0x5B44892C, - cs_janet: 0x3034F9E2, - cs_jewelass: 0x4440A804, - cs_jimmyboston: 0x039677BD, - cs_jimmydisanto: 0xB8CC92B4, - cs_joeminuteman: 0xF09D5E29, - cs_johnnyklebitz: 0xFA8AB881, - cs_josef: 0x459762CA, - cs_josh: 0x450EEF9D, - cs_karen_daniels: 0x4BAF381C, - cs_lamardavis: 0x45463A0D, - cs_lazlow: 0x38951A1B, - cs_lestercrest: 0xB594F5C3, - cs_lifeinvad_01: 0x72551375, - cs_magenta: 0x5816C61A, - cs_manuel: 0xFBB374CA, - cs_marnie: 0x574DE134, - cs_martinmadrazo: 0x43595670, - cs_maryann: 0x0998C7AD, - cs_michelle: 0x70AEB9C8, - cs_milton: 0xB76A330F, - cs_molly: 0x45918E44, - cs_movpremf_01: 0x4BBA84D9, - cs_movpremmale: 0x8D67EE7D, - cs_mrk: 0xC3CC9A75, - cs_mrs_thornhill: 0x4F921E6E, - cs_mrsphillips: 0xCBFDA3CF, - cs_natalia: 0x4EFEB1F0, - cs_nervousron: 0x7896DA94, - cs_nigel: 0xE1479C0B, - cs_old_man1a: 0x1EEC7BDC, - cs_old_man2: 0x98F9E770, - cs_omega: 0x8B70B405, - cs_orleans: 0xAD340F5A, - cs_paper: 0x6B38B8F8, - cs_patricia: 0xDF8B1301, - cs_priest: 0x4D6DE57E, - cs_prolsec_02: 0x1E9314A2, - cs_russiandrunk: 0x46521A32, - cs_siemonyetarian: 0xC0937202, - cs_solomon: 0xF6D1E04E, - cs_stevehains: 0xA4E0A1FE, - cs_stretch: 0x893D6805, - cs_tanisha: 0x42FE5370, - cs_taocheng: 0x8864083D, - cs_taostranslator: 0x53536529, - cs_tenniscoach: 0x5C26040A, - cs_terry: 0x3A5201C5, - cs_tom: 0x69E8ABC3, - cs_tomepsilon: 0x8C0FD4E2, - cs_tracydisanto: 0x0609B130, - cs_wade: 0xD266D9D6, - cs_zimbor: 0xEAACAAF0, - csb_abigail: 0x89768941, - csb_agent: 0xD770C9B4, - csb_anita: 0x0703F106, - csb_anton: 0xA5C787B6, - csb_ballasog: 0xABEF0004, - csb_bride: 0x82BF7EA1, - csb_burgerdrug: 0x8CDCC057, - csb_car3guy1: 0x04430687, - csb_car3guy2: 0x1383A508, - csb_chef: 0xA347CA8A, - csb_chef2: 0xAE5BE23A, - csb_chin_goon: 0xA8C22996, - csb_cletus: 0xCAE9E5D5, - csb_cop: 0x9AB35F63, - csb_customer: 0xA44F6F8B, - csb_denise_friend: 0xB58D2529, - csb_fos_rep: 0x1BCC157B, - csb_g: 0xA28E71D7, - csb_groom: 0x7AAB19D2, - csb_grove_str_dlr: 0xE8594E22, - csb_hao: 0xEC9E8F1C, - csb_hugh: 0x6F139B54, - csb_imran: 0xE3420BDB, - csb_jackhowitzer: 0x44BC7BB1, - csb_janitor: 0xC2005A40, - csb_maude: 0xBCC475CB, - csb_money: 0x989DFD9A, - csb_mp_agent14: 0x6DBBFC8B, - csb_mweather: 0x613E626C, - csb_ortega: 0xC0DB04CF, - csb_oscar: 0xF41F399B, - csb_paige: 0x5B1FA0C3, - csb_popov: 0x617D89E2, - csb_porndudes: 0x2F4AFE35, - csb_prologuedriver: 0xF00B49DB, - csb_prolsec: 0x7FA2F024, - csb_ramp_gang: 0xC2800DBE, - csb_ramp_hic: 0x858C94B8, - csb_ramp_hipster: 0x21F58BB4, - csb_ramp_marine: 0x616C97B9, - csb_ramp_mex: 0xF64ED7D0, - csb_rashcosvki: 0x188099A9, - csb_reporter: 0x2E420A24, - csb_roccopelosi: 0xAA64168C, - csb_screen_writer: 0x8BE12CEC, - csb_stripper_01: 0xAEEA76B5, - csb_stripper_02: 0x81441B71, - csb_tonya: 0x6343DD19, - csb_trafficwarden: 0xDE2937F3, - csb_undercover: 0xEF785A6A, - csb_vagspeak: 0x48FF4CA9, - g_f_importexport_01: 0x84A1B11A, - g_f_y_ballas_01: 0x158C439C, - g_f_y_families_01: 0x4E0CE5D3, - g_f_y_lost_01: 0xFD5537DE, - g_f_y_vagos_01: 0x5AA42C21, - g_m_importexport_01: 0xBCA2CCEA, - g_m_m_armboss_01: 0xF1E823A2, - g_m_m_armgoon_01: 0xFDA94268, - g_m_m_armlieut_01: 0xE7714013, - g_m_m_chemwork_01: 0xF6157D8F, - g_m_m_chiboss_01: 0xB9DD0300, - g_m_m_chicold_01: 0x106D9A99, - g_m_m_chigoon_01: 0x7E4F763F, - g_m_m_chigoon_02: 0xFF71F826, - g_m_m_korboss_01: 0x352A026F, - g_m_m_mexboss_01: 0x5761F4AD, - g_m_m_mexboss_02: 0x4914D813, - g_m_y_armgoon_02: 0xC54E878A, - g_m_y_azteca_01: 0x68709618, - g_m_y_ballaeast_01: 0xF42EE883, - g_m_y_ballaorig_01: 0x231AF63F, - g_m_y_ballasout_01: 0x23B88069, - g_m_y_famca_01: 0xE83B93B7, - g_m_y_famdnf_01: 0xDB729238, - g_m_y_famfor_01: 0x84302B09, - g_m_y_korean_01: 0x247502A9, - g_m_y_korean_02: 0x8FEDD989, - g_m_y_korlieut_01: 0x7CCBE17A, - g_m_y_lost_01: 0x4F46D607, - g_m_y_lost_02: 0x3D843282, - g_m_y_lost_03: 0x32B11CDC, - g_m_y_mexgang_01: 0xBDDD5546, - g_m_y_mexgoon_01: 0x26EF3426, - g_m_y_mexgoon_02: 0x31A3498E, - g_m_y_mexgoon_03: 0x964D12DC, - g_m_y_pologoon_01: 0x4F3FBA06, - g_m_y_pologoon_02: 0xA2E86156, - g_m_y_salvaboss_01: 0x905CE0CA, - g_m_y_salvagoon_01: 0x278C8CB7, - g_m_y_salvagoon_02: 0x3273A285, - g_m_y_salvagoon_03: 0x03B8C510, - g_m_y_strpunk_01: 0xFD1C49BB, - g_m_y_strpunk_02: 0x0DA1EAC6, - hc_driver: 0x3B474ADF, - hc_gunman: 0x0B881AEE, - hc_hacker: 0x99BB00F8, - ig_abigail: 0x400AEC41, - ig_agent: 0x246AF208, - ig_amandatownley: 0x6D1E15F7, - ig_andreas: 0x47E4EEA0, - ig_ashley: 0x7EF440DB, - ig_avon: 0xFCE270C2, - ig_ballasog: 0xA70B4A92, - ig_bankman: 0x909D9E7F, - ig_barry: 0x2F8845A3, - ig_benny: 0xC4B715D2, - ig_bestmen: 0x5746CD96, - ig_beverly: 0xBDA21E5C, - ig_brad: 0xBDBB4922, - ig_bride: 0x6162EC47, - ig_car3guy1: 0x84F9E937, - ig_car3guy2: 0x75C34ACA, - ig_casey: 0xE0FA2554, - ig_chef: 0x49EADBF6, - ig_chef2: 0x85889AC3, - ig_chengsr: 0xAAE4EA7B, - ig_chrisformage: 0x286E54A7, - ig_clay: 0x6CCFE08A, - ig_claypain: 0x9D0087A8, - ig_cletus: 0xE6631195, - ig_dale: 0x467415E9, - ig_davenorton: 0x15CD4C33, - ig_denise: 0x820B33BD, - ig_devin: 0x7461A0B0, - ig_dom: 0x9C2DB088, - ig_dreyfuss: 0xDA890932, - ig_drfriedlander: 0xCBFC0DF5, - ig_fabien: 0xD090C350, - ig_fbisuit_01: 0x3AE4A33B, - ig_floyd: 0xB1B196B2, - ig_g: 0x841BA933, - ig_groom: 0xFECE8B85, - ig_hao: 0x65978363, - ig_hunter: 0xCE1324DE, - ig_janet: 0x0D6D9C49, - ig_jay_norris: 0x7A32EE74, - ig_jewelass: 0x0F5D26BB, - ig_jimmyboston: 0xEDA0082D, - ig_jimmydisanto: 0x570462B9, - ig_joeminuteman: 0xBE204C9B, - ig_johnnyklebitz: 0x87CA80AE, - ig_josef: 0xE11A9FB4, - ig_josh: 0x799E9EEE, - ig_karen_daniels: 0xEB51D959, - ig_kerrymcintosh: 0x5B3BD90D, - ig_lamardavis: 0x65B93076, - ig_lazlow: 0xDFE443E5, - ig_lestercrest_2: 0x6E42FD26, - ig_lestercrest: 0x4DA6E849, - ig_lifeinvad_01: 0x5389A93C, - ig_lifeinvad_02: 0x27BD51D4, - ig_magenta: 0xFCDC910A, - ig_malc: 0xF1BCA919, - ig_manuel: 0xFD418E10, - ig_marnie: 0x188232D0, - ig_maryann: 0xA36F9806, - ig_maude: 0x3BE8287E, - ig_michelle: 0xBF9672F4, - ig_milton: 0xCB3059B2, - ig_molly: 0xAF03DDE1, - ig_money: 0x37FACDA6, - ig_mp_agent14: 0xFBF98469, - ig_mrk: 0xEDDCAB6D, - ig_mrs_thornhill: 0x1E04A96B, - ig_mrsphillips: 0x3862EEA8, - ig_natalia: 0xDE17DD3B, - ig_nervousron: 0xBD006AF1, - ig_nigel: 0xC8B7167D, - ig_old_man1a: 0x719D27F4, - ig_old_man2: 0xEF154C47, - ig_omega: 0x60E6A7D8, - ig_oneil: 0x2DC6D3E7, - ig_orleans: 0x61D4C771, - ig_ortega: 0x26A562B7, - ig_paige: 0x154FCF3F, - ig_paper: 0x999B00C6, - ig_patricia: 0xC56E118C, - ig_popov: 0x267630FE, - ig_priest: 0x6437E77D, - ig_prolsec_02: 0x27B3AD75, - ig_ramp_gang: 0xE52E126C, - ig_ramp_hic: 0x45753032, - ig_ramp_hipster: 0xDEEF9F6E, - ig_ramp_mex: 0xE6AC74A4, - ig_rashcosvki: 0x380C4DE6, - ig_roccopelosi: 0xD5BA52FF, - ig_russiandrunk: 0x3D0A5EB1, - ig_screen_writer: 0xFFE63677, - ig_siemonyetarian: 0x4C7B2F05, - ig_solomon: 0x86BDFE26, - ig_stevehains: 0x382121C8, - ig_stretch: 0x36984358, - ig_talina: 0xE793C8E8, - ig_tanisha: 0x0D810489, - ig_taocheng: 0xDC5C5EA5, - ig_taostranslator: 0x7C851464, - ig_tenniscoach: 0xA23B5F57, - ig_terry: 0x67000B94, - ig_tomepsilon: 0xCD777AAA, - ig_tonya: 0xCAC85344, - ig_tracydisanto: 0xDE352A35, - ig_trafficwarden: 0x5719786D, - ig_tylerdix: 0x5265F707, - ig_vagspeak: 0xF9FD068C, - ig_wade: 0x92991B72, - ig_zimbor: 0x0B34D6F5, - mp_f_boatstaff_01: 0x3293B9CE, - mp_f_cardesign_01: 0x242C34A7, - mp_f_chbar_01: 0xC3F6E385, - mp_f_cocaine_01: 0x4B657AF8, - mp_f_counterfeit_01: 0xB788F1F5, - mp_f_deadhooker: 0x73DEA88B, - mp_f_execpa_01: 0x432CA064, - mp_f_execpa_02: 0x5972CCF0, - mp_f_forgery_01: 0x781A3CF8, - mp_f_freemode_01: 0x9C9EFFD8, - mp_f_helistaff_01: 0x19B6FF06, - mp_f_meth_01: 0xD2B27EC1, - mp_f_misty_01: 0xD128FF9D, - mp_f_stripperlite: 0x2970A494, - mp_f_weed_01: 0xB26573A3, - mp_g_m_pros_01: 0x6C9DD7C9, - mp_m_avongoon: 0x9C13CB95, - mp_m_boatstaff_01: 0xC85F0A88, - mp_m_bogdangoon: 0x4D5696F7, - mp_m_claude_01: 0xC0F371B7, - mp_m_cocaine_01: 0x56D38F95, - mp_m_counterfeit_01: 0x9855C974, - mp_m_exarmy_01: 0x45348DBB, - mp_m_execpa_01: 0x3E8417BC, - mp_m_famdd_01: 0x33A464E5, - mp_m_fibsec_01: 0x5CDEF405, - mp_m_forgery_01: 0x613E709B, - mp_m_freemode_01: 0x705E61F2, - mp_m_g_vagfun_01: 0xC4A617BD, - mp_m_marston_01: 0x38430167, - mp_m_meth_01: 0xEDB42F3F, - mp_m_niko_01: 0xEEDACFC9, - mp_m_securoguard_01: 0xDA2C984E, - mp_m_shopkeep_01: 0x18CE57D0, - mp_m_waremech_01: 0xF7A74139, - mp_m_weapexp_01: 0x36EA5B09, - mp_m_weapwork_01: 0x4186506E, - mp_m_weed_01: 0x917ED459, - mp_s_m_armoured_01: 0xCDEF5408, - player_one: 0x9B22DBAF, - player_two: 0x9B810FA2, - player_zero: 0x0D7114C9, - s_f_m_fembarber: 0x163B875B, - s_f_m_maid_01: 0xE093C5C6, - s_f_m_shop_high: 0xAE47E4B0, - s_f_m_sweatshop_01: 0x312B5BC0, - s_f_y_airhostess_01: 0x5D71A46F, - s_f_y_bartender_01: 0x780C01BD, - s_f_y_baywatch_01: 0x4A8E5536, - s_f_y_cop_01: 0x15F8700D, - s_f_y_factory_01: 0x69F46BF3, - s_f_y_hooker_01: 0x028ABF95, - s_f_y_hooker_02: 0x14C3E407, - s_f_y_hooker_03: 0x031640AC, - s_f_y_migrant_01: 0xD55B2BF5, - s_f_y_movprem_01: 0x2300C816, - s_f_y_ranger_01: 0x9FC7F637, - s_f_y_scrubs_01: 0xAB594AB6, - s_f_y_sheriff_01: 0x4161D042, - s_f_y_shop_low: 0xA96E2604, - s_f_y_shop_mid: 0x3EECBA5D, - s_f_y_stripper_01: 0x52580019, - s_f_y_stripper_02: 0x6E0FB794, - s_f_y_stripperlite: 0x5C14EDFA, - s_f_y_sweatshop_01: 0x8502B6B2, - s_m_m_ammucountry: 0x0DE9A30A, - s_m_m_armoured_01: 0x95C76ECD, - s_m_m_armoured_02: 0x63858A4A, - s_m_m_autoshop_01: 0x040EABE3, - s_m_m_autoshop_02: 0xF06B849D, - s_m_m_bouncer_01: 0x9FD4292D, - s_m_m_ccrew_01: 0xC9E5F56B, - s_m_m_chemsec_01: 0x2EFEAFD5, - s_m_m_ciasec_01: 0x625D6958, - s_m_m_cntrybar_01: 0x1A021B83, - s_m_m_dockwork_01: 0x14D7B4E0, - s_m_m_doctor_01: 0xD47303AC, - s_m_m_fiboffice_01: 0xEDBC7546, - s_m_m_fiboffice_02: 0x26F067AD, - s_m_m_fibsec_01: 0x7B8B434B, - s_m_m_gaffer_01: 0xA956BD9E, - s_m_m_gardener_01: 0x49EA5685, - s_m_m_gentransport: 0x1880ED06, - s_m_m_hairdress_01: 0x418DFF92, - s_m_m_highsec_01: 0xF161D212, - s_m_m_highsec_02: 0x2930C1AB, - s_m_m_janitor: 0xA96BD9EC, - s_m_m_lathandy_01: 0x9E80D2CE, - s_m_m_lifeinvad_01: 0xDE0077FD, - s_m_m_linecook: 0xDB9C0997, - s_m_m_lsmetro_01: 0x765AAAE4, - s_m_m_mariachi_01: 0x7EA4FFA6, - s_m_m_marine_01: 0xF2DAA2ED, - s_m_m_marine_02: 0xF0259D83, - s_m_m_migrant_01: 0xED0CE4C6, - s_m_m_movalien_01: 0x64611296, - s_m_m_movprem_01: 0xD85E6D28, - s_m_m_movspace_01: 0xE7B31432, - s_m_m_paramedic_01: 0xB353629E, - s_m_m_pilot_01: 0xE75B4B1C, - s_m_m_pilot_02: 0xF63DE8E1, - s_m_m_postal_01: 0x62599034, - s_m_m_postal_02: 0x7367324F, - s_m_m_prisguard_01: 0x56C96FC6, - s_m_m_scientist_01: 0x4117D39B, - s_m_m_security_01: 0xD768B228, - s_m_m_snowcop_01: 0x1AE8BB58, - s_m_m_strperf_01: 0x795AC7A8, - s_m_m_strpreach_01: 0x1C0077FB, - s_m_m_strvend_01: 0xCE9113A9, - s_m_m_trucker_01: 0x59511A6C, - s_m_m_ups_01: 0x9FC37F22, - s_m_m_ups_02: 0xD0BDE116, - s_m_o_busker_01: 0xAD9EF1BB, - s_m_y_airworker: 0x62018559, - s_m_y_ammucity_01: 0x9E08633D, - s_m_y_armymech_01: 0x62CC28E2, - s_m_y_autopsy_01: 0xB2273D4E, - s_m_y_barman_01: 0xE5A11106, - s_m_y_baywatch_01: 0x0B4A6862, - s_m_y_blackops_01: 0xB3F3EE34, - s_m_y_blackops_02: 0x7A05FA59, - s_m_y_blackops_03: 0x5076A73B, - s_m_y_busboy_01: 0xD8F9CD47, - s_m_y_chef_01: 0x0F977CEB, - s_m_y_clown_01: 0x04498DDE, - s_m_y_construct_01: 0xD7DA9E99, - s_m_y_construct_02: 0xC5FEFADE, - s_m_y_cop_01: 0x5E3DA4A4, - s_m_y_dealer_01: 0xE497BBEF, - s_m_y_devinsec_01: 0x9B557274, - s_m_y_dockwork_01: 0x867639D1, - s_m_y_doorman_01: 0x22911304, - s_m_y_dwservice_01: 0x75D30A91, - s_m_y_dwservice_02: 0xF5908A06, - s_m_y_factory_01: 0x4163A158, - s_m_y_fireman_01: 0xB6B1EDA8, - s_m_y_garbage: 0xEE75A00F, - s_m_y_grip_01: 0x309E7DEA, - s_m_y_hwaycop_01: 0x739B1EF5, - s_m_y_marine_01: 0x65793043, - s_m_y_marine_02: 0x58D696FE, - s_m_y_marine_03: 0x72C0CAD2, - s_m_y_mime: 0x3CDCA742, - s_m_y_pestcont_01: 0x48114518, - s_m_y_pilot_01: 0xAB300C07, - s_m_y_prismuscl_01: 0x5F2113A1, - s_m_y_prisoner_01: 0xB1BB9B59, - s_m_y_ranger_01: 0xEF7135AE, - s_m_y_robber_01: 0xC05E1399, - s_m_y_sheriff_01: 0xB144F9B9, - s_m_y_shop_mask: 0x6E122C06, - s_m_y_strvend_01: 0x927F2323, - s_m_y_swat_01: 0x8D8F1B10, - s_m_y_uscg_01: 0xCA0050E9, - s_m_y_valet_01: 0x3B96F23E, - s_m_y_waiter_01: 0xAD4C724C, - s_m_y_winclean_01: 0x550D8D9D, - s_m_y_xmech_01: 0x441405EC, - s_m_y_xmech_02_mp: 0x69147A0D, - s_m_y_xmech_02: 0xBE20FA04, - u_f_m_corpse_01: 0x2E140314, - u_f_m_drowned_01: 0xD7F37609, - u_f_m_miranda: 0x414FA27B, - u_f_m_promourn_01: 0xA20899E7, - u_f_o_moviestar: 0x35578634, - u_f_o_prolhost_01: 0xC512DD23, - u_f_y_bikerchic: 0xFA389D4F, - u_f_y_comjane: 0xB6AA85CE, - u_f_y_corpse_01: 0x9C70109D, - u_f_y_corpse_02: 0x0D9C72F8, - u_f_y_hotposh_01: 0x969B6DFE, - u_f_y_jewelass_01: 0xF0D4BE2E, - u_f_y_mistress: 0x5DCA2528, - u_f_y_poppymich: 0x23E9A09E, - u_f_y_princess: 0xD2E3A284, - u_f_y_spyactress: 0x5B81D86C, - u_m_m_aldinapoli: 0xF0EC56E2, - u_m_m_bankman: 0xC306D6F5, - u_m_m_bikehire_01: 0x76474545, - u_m_m_doa_01: 0x621E6BFD, - u_m_m_edtoh: 0x2A797197, - u_m_m_fibarchitect: 0x342333D3, - u_m_m_filmdirector: 0x2B6E1BB6, - u_m_m_glenstank_01: 0x45BB1666, - u_m_m_griff_01: 0xC454BCBB, - u_m_m_jesus_01: 0xCE2CB751, - u_m_m_jewelsec_01: 0xACCCBDB6, - u_m_m_jewelthief: 0xE6CC3CDC, - u_m_m_markfost: 0x1C95CB0B, - u_m_m_partytarget: 0x81F74DE7, - u_m_m_prolsec_01: 0x709220C7, - u_m_m_promourn_01: 0xCE96030B, - u_m_m_rivalpap: 0x60D5D6DA, - u_m_m_spyactor: 0xAC0EA5D8, - u_m_m_streetart_01: 0x6C19E962, - u_m_m_willyfist: 0x90769A8F, - u_m_o_filmnoir: 0x2BACC2DB, - u_m_o_finguru_01: 0x46E39E63, - u_m_o_taphillbilly: 0x9A1E5E52, - u_m_o_tramp_01: 0x6A8F1F9B, - u_m_y_abner: 0xF0AC2626, - u_m_y_antonb: 0xCF623A2C, - u_m_y_babyd: 0xDA116E7E, - u_m_y_baygor: 0x5244247D, - u_m_y_burgerdrug_01: 0x8B7D3766, - u_m_y_chip: 0x24604B2B, - u_m_y_corpse_01: 0x94C2A03F, - u_m_y_cyclist_01: 0x2D0EFCEB, - u_m_y_fibmugger_01: 0x85B9C668, - u_m_y_guido_01: 0xC6B49A2F, - u_m_y_gunvend_01: 0xB3229752, - u_m_y_hippie_01: 0xF041880B, - u_m_y_imporage: 0x348065F5, - u_m_y_juggernaut_01: 0x90EF5134, - u_m_y_justin: 0x7DC3908F, - u_m_y_mani: 0xC8BB1E52, - u_m_y_militarybum: 0x4705974A, - u_m_y_paparazzi: 0x5048B328, - u_m_y_party_01: 0x36E70600, - u_m_y_pogo_01: 0xDC59940D, - u_m_y_prisoner_01: 0x7B9B4BC0, - u_m_y_proldriver_01: 0x855E36A3, - u_m_y_rsranger_01: 0x3C438CD2, - u_m_y_sbike: 0x6AF4185D, - u_m_y_staggrm_01: 0x9194CE03, - u_m_y_tattoo_01: 0x94AE2B8C, - u_m_y_zombie_01: 0xAC4B4506, - } - var CreatedPeds: Array = []; +var PedHashes = { + a_c_boar: 0xCE5FF074, + a_c_cat_01: 0x573201B8, + a_c_chickenhawk: 0xAAB71F62, + a_c_chimp: 0xA8683715, + a_c_chop: 0x14EC17EA, + a_c_cormorant: 0x56E29962, + a_c_cow: 0xFCFA9E1E, + a_c_coyote: 0x644AC75E, + a_c_crow: 0x18012A9F, + a_c_deer: 0xD86B5A95, + a_c_dolphin: 0x8BBAB455, + a_c_fish: 0x2FD800B7, + a_c_hen: 0x6AF51FAF, + a_c_humpback: 0x471BE4B2, + a_c_husky: 0x4E8F95A2, + a_c_killerwhale: 0x8D8AC8B9, + a_c_mtlion: 0x1250D7BA, + a_c_pig: 0xB11BAB56, + a_c_pigeon: 0x06A20728, + a_c_poodle: 0x431D501C, + a_c_pug: 0x6D362854, + a_c_rabbit_01: 0xDFB55C81, + a_c_rat: 0xC3B52966, + a_c_retriever: 0x349F33E1, + a_c_rhesus: 0xC2D06F53, + a_c_rottweiler: 0x9563221D, + a_c_seagull: 0xD3939DFD, + a_c_sharkhammer: 0x3C831724, + a_c_sharktiger: 0x06C3F072, + a_c_shepherd: 0x431FC24C, + a_c_stingray: 0xA148614D, + a_c_westy: 0xAD7844BB, + a_f_m_beach_01: 0x303638A7, + a_f_m_bevhills_01: 0xBE086EFD, + a_f_m_bevhills_02: 0xA039335F, + a_f_m_bodybuild_01: 0x3BD99114, + a_f_m_business_02: 0x1FC37DBC, + a_f_m_downtown_01: 0x654AD86E, + a_f_m_eastsa_01: 0x9D3DCB7A, + a_f_m_eastsa_02: 0x63C8D891, + a_f_m_fatbla_01: 0xFAB48BCB, + a_f_m_fatcult_01: 0xB5CF80E4, + a_f_m_fatwhite_01: 0x38BAD33B, + a_f_m_ktown_01: 0x52C824DE, + a_f_m_ktown_02: 0x41018151, + a_f_m_prolhost_01: 0x169BD1E1, + a_f_m_salton_01: 0xDE0E0969, + a_f_m_skidrow_01: 0xB097523B, + a_f_m_soucent_01: 0x745855A1, + a_f_m_soucent_02: 0xF322D338, + a_f_m_soucentmc_01: 0xCDE955D2, + a_f_m_tourist_01: 0x505603B9, + a_f_m_tramp_01: 0x48F96F5B, + a_f_m_trampbeac_01: 0x8CA0C266, + a_f_o_genstreet_01: 0x61C81C85, + a_f_o_indian_01: 0xBAD7BB80, + a_f_o_ktown_01: 0x47CF5E96, + a_f_o_salton_01: 0xCCFF7D8A, + a_f_o_soucent_01: 0x3DFA1830, + a_f_o_soucent_02: 0xA56DE716, + a_f_y_beach_01: 0xC79F6928, + a_f_y_bevhills_01: 0x445AC854, + a_f_y_bevhills_02: 0x5C2CF7F8, + a_f_y_bevhills_03: 0x20C8012F, + a_f_y_bevhills_04: 0x36DF2D5D, + a_f_y_business_01: 0x2799EFD8, + a_f_y_business_02: 0x31430342, + a_f_y_business_03: 0xAE86FDB4, + a_f_y_business_04: 0xB7C61032, + a_f_y_eastsa_01: 0xF5B0079D, + a_f_y_eastsa_02: 0x0438A4AE, + a_f_y_eastsa_03: 0x51C03FA4, + a_f_y_epsilon_01: 0x689C2A80, + a_f_y_femaleagent: 0x50610C43, + a_f_y_fitness_01: 0x457C64FB, + a_f_y_fitness_02: 0x13C4818C, + a_f_y_genhot_01: 0x2F4AEC3E, + a_f_y_golfer_01: 0x7DD8FB58, + a_f_y_hiker_01: 0x30830813, + a_f_y_hippie_01: 0x1475B827, + a_f_y_hipster_01: 0x8247D331, + a_f_y_hipster_02: 0x97F5FE8D, + a_f_y_hipster_03: 0xA5BA9A16, + a_f_y_hipster_04: 0x199881DC, + a_f_y_indian_01: 0x092D9CC1, + a_f_y_juggalo_01: 0xDB134533, + a_f_y_runner_01: 0xC7496729, + a_f_y_rurmeth_01: 0x3F789426, + a_f_y_scdressy_01: 0xDB5EC400, + a_f_y_skater_01: 0x695FE666, + a_f_y_soucent_01: 0x2C641D7A, + a_f_y_soucent_02: 0x5A8EF9CF, + a_f_y_soucent_03: 0x87B25415, + a_f_y_tennis_01: 0x550C79C6, + a_f_y_topless_01: 0x9CF26183, + a_f_y_tourist_01: 0x563B8570, + a_f_y_tourist_02: 0x9123FB40, + a_f_y_vinewood_01: 0x19F41F65, + a_f_y_vinewood_02: 0xDAB6A0EB, + a_f_y_vinewood_03: 0x379DDAB8, + a_f_y_vinewood_04: 0xFAE46146, + a_f_y_yoga_01: 0xC41B062E, + a_m_m_acult_01: 0x5442C66B, + a_m_m_afriamer_01: 0xD172497E, + a_m_m_beach_01: 0x403DB4FD, + a_m_m_beach_02: 0x787FA588, + a_m_m_bevhills_01: 0x54DBEE1F, + a_m_m_bevhills_02: 0x3FB5C3D3, + a_m_m_business_01: 0x7E6A64B7, + a_m_m_eastsa_01: 0xF9A6F53F, + a_m_m_eastsa_02: 0x07DD91AC, + a_m_m_farmer_01: 0x94562DD7, + a_m_m_fatlatin_01: 0x61D201B3, + a_m_m_genfat_01: 0x06DD569F, + a_m_m_genfat_02: 0x13AEF042, + a_m_m_golfer_01: 0xA9EB0E42, + a_m_m_hasjew_01: 0x6BD9B68C, + a_m_m_hillbilly_01: 0x6C9B2849, + a_m_m_hillbilly_02: 0x7B0E452F, + a_m_m_indian_01: 0xDDCAAA2C, + a_m_m_ktown_01: 0xD15D7E71, + a_m_m_malibu_01: 0x2FDE6EB7, + a_m_m_mexcntry_01: 0xDD817EAD, + a_m_m_mexlabor_01: 0xB25D16B2, + a_m_m_og_boss_01: 0x681BD012, + a_m_m_paparazzi_01: 0xECCA8C15, + a_m_m_polynesian_01: 0xA9D9B69E, + a_m_m_prolhost_01: 0x9712C38F, + a_m_m_rurmeth_01: 0x3BAD4184, + a_m_m_salton_01: 0x4F2E038A, + a_m_m_salton_02: 0x60F4A717, + a_m_m_salton_03: 0xB28C4A45, + a_m_m_salton_04: 0x964511B7, + a_m_m_skater_01: 0xD9D7588C, + a_m_m_skidrow_01: 0x01EEA6BD, + a_m_m_socenlat_01: 0x0B8D69E3, + a_m_m_soucent_01: 0x6857C9B7, + a_m_m_soucent_02: 0x9F6D37E1, + a_m_m_soucent_03: 0x8BD990BA, + a_m_m_soucent_04: 0xC2FBFEFE, + a_m_m_stlat_02: 0xC2A87702, + a_m_m_tennis_01: 0x546A5344, + a_m_m_tourist_01: 0xC89F0184, + a_m_m_tramp_01: 0x1EC93FD0, + a_m_m_trampbeac_01: 0x53B57EB0, + a_m_m_tranvest_01: 0xE0E69974, + a_m_m_tranvest_02: 0xF70EC5C4, + a_m_o_acult_01: 0x55446010, + a_m_o_acult_02: 0x4BA14CCA, + a_m_o_beach_01: 0x8427D398, + a_m_o_genstreet_01: 0xAD54E7A8, + a_m_o_ktown_01: 0x1536D95A, + a_m_o_salton_01: 0x20208E4D, + a_m_o_soucent_01: 0x2AD8921B, + a_m_o_soucent_02: 0x4086BD77, + a_m_o_soucent_03: 0x0E32D8D0, + a_m_o_tramp_01: 0x174D4245, + a_m_y_acult_01: 0xB564882B, + a_m_y_acult_02: 0x80E59F2E, + a_m_y_beach_01: 0xD1FEB884, + a_m_y_beach_02: 0x23C7DC11, + a_m_y_beach_03: 0xE7A963D9, + a_m_y_beachvesp_01: 0x7E0961B8, + a_m_y_beachvesp_02: 0xCA56FA52, + a_m_y_bevhills_01: 0x76284640, + a_m_y_bevhills_02: 0x668BA707, + a_m_y_breakdance_01: 0x379F9596, + a_m_y_busicas_01: 0x9AD32FE9, + a_m_y_business_01: 0xC99F21C4, + a_m_y_business_02: 0xB3B3F5E6, + a_m_y_business_03: 0xA1435105, + a_m_y_cyclist_01: 0xFDC653C7, + a_m_y_dhill_01: 0xFF3E88AB, + a_m_y_downtown_01: 0x2DADF4AA, + a_m_y_eastsa_01: 0xA4471173, + a_m_y_eastsa_02: 0x168775F6, + a_m_y_epsilon_01: 0x77D41A3E, + a_m_y_epsilon_02: 0xAA82FF9B, + a_m_y_gay_01: 0xD1CCE036, + a_m_y_gay_02: 0xA5720781, + a_m_y_genstreet_01: 0x9877EF71, + a_m_y_genstreet_02: 0x3521A8D2, + a_m_y_golfer_01: 0xD71FE131, + a_m_y_hasjew_01: 0xE16D8F01, + a_m_y_hiker_01: 0x50F73C0C, + a_m_y_hippy_01: 0x7D03E617, + a_m_y_hipster_01: 0x2307A353, + a_m_y_hipster_02: 0x14D506EE, + a_m_y_hipster_03: 0x4E4179C6, + a_m_y_indian_01: 0x2A22FBCE, + a_m_y_jetski_01: 0x2DB7EEF3, + a_m_y_juggalo_01: 0x91CA3E2C, + a_m_y_ktown_01: 0x1AF6542C, + a_m_y_ktown_02: 0x297FF13F, + a_m_y_latino_01: 0x132C1A8E, + a_m_y_methhead_01: 0x696BE0A9, + a_m_y_mexthug_01: 0x3053E555, + a_m_y_motox_01: 0x64FDEA7D, + a_m_y_motox_02: 0x77AC8FDA, + a_m_y_musclbeac_01: 0x4B652906, + a_m_y_musclbeac_02: 0xC923247C, + a_m_y_polynesian_01: 0x8384FC9F, + a_m_y_roadcyc_01: 0xF561A4C6, + a_m_y_runner_01: 0x25305EEE, + a_m_y_runner_02: 0x843D9D0F, + a_m_y_salton_01: 0xD7606C30, + a_m_y_skater_01: 0xC1C46677, + a_m_y_skater_02: 0xAFFAC2E4, + a_m_y_soucent_01: 0xE716BDCB, + a_m_y_soucent_02: 0xACA3C8CA, + a_m_y_soucent_03: 0xC3F0F764, + a_m_y_soucent_04: 0x8A3703F1, + a_m_y_stbla_01: 0xCF92ADE9, + a_m_y_stbla_02: 0x98C7404F, + a_m_y_stlat_01: 0x8674D5FC, + a_m_y_stwhi_01: 0x2418C430, + a_m_y_stwhi_02: 0x36C6E98C, + a_m_y_sunbathe_01: 0xB7292F0C, + a_m_y_surfer_01: 0xEAC2C7EE, + a_m_y_vindouche_01: 0xC19377E7, + a_m_y_vinewood_01: 0x4B64199D, + a_m_y_vinewood_02: 0x5D15BD00, + a_m_y_vinewood_03: 0x1FDF4294, + a_m_y_vinewood_04: 0x31C9E669, + a_m_y_yoga_01: 0xAB0A7155, + cs_amandatownley: 0x95EF18E3, + cs_andreas: 0xE7565327, + cs_ashley: 0x26C3D079, + cs_bankman: 0x9760192E, + cs_barry: 0x69591CF7, + cs_beverly: 0xB46EC356, + cs_brad: 0xEFE5AFE6, + cs_bradcadaver: 0x7228AF60, + cs_carbuyer: 0x8CCE790F, + cs_casey: 0xEA969C40, + cs_chengsr: 0x30DB9D7B, + cs_chrisformage: 0xC1F380E6, + cs_clay: 0xDBCB9834, + cs_dale: 0x0CE81655, + cs_davenorton: 0x8587248C, + cs_debra: 0xECD04FE9, + cs_denise: 0x6F802738, + cs_devin: 0x2F016D02, + cs_dom: 0x4772AF42, + cs_dreyfuss: 0x3C60A153, + cs_drfriedlander: 0xA3A35C2F, + cs_fabien: 0x47035EC1, + cs_fbisuit_01: 0x585C0B52, + cs_floyd: 0x062547E7, + cs_guadalope: 0x0F9513F1, + cs_gurk: 0xC314F727, + cs_hunter: 0x5B44892C, + cs_janet: 0x3034F9E2, + cs_jewelass: 0x4440A804, + cs_jimmyboston: 0x039677BD, + cs_jimmydisanto: 0xB8CC92B4, + cs_joeminuteman: 0xF09D5E29, + cs_johnnyklebitz: 0xFA8AB881, + cs_josef: 0x459762CA, + cs_josh: 0x450EEF9D, + cs_karen_daniels: 0x4BAF381C, + cs_lamardavis: 0x45463A0D, + cs_lazlow: 0x38951A1B, + cs_lestercrest: 0xB594F5C3, + cs_lifeinvad_01: 0x72551375, + cs_magenta: 0x5816C61A, + cs_manuel: 0xFBB374CA, + cs_marnie: 0x574DE134, + cs_martinmadrazo: 0x43595670, + cs_maryann: 0x0998C7AD, + cs_michelle: 0x70AEB9C8, + cs_milton: 0xB76A330F, + cs_molly: 0x45918E44, + cs_movpremf_01: 0x4BBA84D9, + cs_movpremmale: 0x8D67EE7D, + cs_mrk: 0xC3CC9A75, + cs_mrs_thornhill: 0x4F921E6E, + cs_mrsphillips: 0xCBFDA3CF, + cs_natalia: 0x4EFEB1F0, + cs_nervousron: 0x7896DA94, + cs_nigel: 0xE1479C0B, + cs_old_man1a: 0x1EEC7BDC, + cs_old_man2: 0x98F9E770, + cs_omega: 0x8B70B405, + cs_orleans: 0xAD340F5A, + cs_paper: 0x6B38B8F8, + cs_patricia: 0xDF8B1301, + cs_priest: 0x4D6DE57E, + cs_prolsec_02: 0x1E9314A2, + cs_russiandrunk: 0x46521A32, + cs_siemonyetarian: 0xC0937202, + cs_solomon: 0xF6D1E04E, + cs_stevehains: 0xA4E0A1FE, + cs_stretch: 0x893D6805, + cs_tanisha: 0x42FE5370, + cs_taocheng: 0x8864083D, + cs_taostranslator: 0x53536529, + cs_tenniscoach: 0x5C26040A, + cs_terry: 0x3A5201C5, + cs_tom: 0x69E8ABC3, + cs_tomepsilon: 0x8C0FD4E2, + cs_tracydisanto: 0x0609B130, + cs_wade: 0xD266D9D6, + cs_zimbor: 0xEAACAAF0, + csb_abigail: 0x89768941, + csb_agent: 0xD770C9B4, + csb_anita: 0x0703F106, + csb_anton: 0xA5C787B6, + csb_ballasog: 0xABEF0004, + csb_bride: 0x82BF7EA1, + csb_burgerdrug: 0x8CDCC057, + csb_car3guy1: 0x04430687, + csb_car3guy2: 0x1383A508, + csb_chef: 0xA347CA8A, + csb_chef2: 0xAE5BE23A, + csb_chin_goon: 0xA8C22996, + csb_cletus: 0xCAE9E5D5, + csb_cop: 0x9AB35F63, + csb_customer: 0xA44F6F8B, + csb_denise_friend: 0xB58D2529, + csb_fos_rep: 0x1BCC157B, + csb_g: 0xA28E71D7, + csb_groom: 0x7AAB19D2, + csb_grove_str_dlr: 0xE8594E22, + csb_hao: 0xEC9E8F1C, + csb_hugh: 0x6F139B54, + csb_imran: 0xE3420BDB, + csb_jackhowitzer: 0x44BC7BB1, + csb_janitor: 0xC2005A40, + csb_maude: 0xBCC475CB, + csb_money: 0x989DFD9A, + csb_mp_agent14: 0x6DBBFC8B, + csb_mweather: 0x613E626C, + csb_ortega: 0xC0DB04CF, + csb_oscar: 0xF41F399B, + csb_paige: 0x5B1FA0C3, + csb_popov: 0x617D89E2, + csb_porndudes: 0x2F4AFE35, + csb_prologuedriver: 0xF00B49DB, + csb_prolsec: 0x7FA2F024, + csb_ramp_gang: 0xC2800DBE, + csb_ramp_hic: 0x858C94B8, + csb_ramp_hipster: 0x21F58BB4, + csb_ramp_marine: 0x616C97B9, + csb_ramp_mex: 0xF64ED7D0, + csb_rashcosvki: 0x188099A9, + csb_reporter: 0x2E420A24, + csb_roccopelosi: 0xAA64168C, + csb_screen_writer: 0x8BE12CEC, + csb_stripper_01: 0xAEEA76B5, + csb_stripper_02: 0x81441B71, + csb_tonya: 0x6343DD19, + csb_trafficwarden: 0xDE2937F3, + csb_undercover: 0xEF785A6A, + csb_vagspeak: 0x48FF4CA9, + g_f_importexport_01: 0x84A1B11A, + g_f_y_ballas_01: 0x158C439C, + g_f_y_families_01: 0x4E0CE5D3, + g_f_y_lost_01: 0xFD5537DE, + g_f_y_vagos_01: 0x5AA42C21, + g_m_importexport_01: 0xBCA2CCEA, + g_m_m_armboss_01: 0xF1E823A2, + g_m_m_armgoon_01: 0xFDA94268, + g_m_m_armlieut_01: 0xE7714013, + g_m_m_chemwork_01: 0xF6157D8F, + g_m_m_chiboss_01: 0xB9DD0300, + g_m_m_chicold_01: 0x106D9A99, + g_m_m_chigoon_01: 0x7E4F763F, + g_m_m_chigoon_02: 0xFF71F826, + g_m_m_korboss_01: 0x352A026F, + g_m_m_mexboss_01: 0x5761F4AD, + g_m_m_mexboss_02: 0x4914D813, + g_m_y_armgoon_02: 0xC54E878A, + g_m_y_azteca_01: 0x68709618, + g_m_y_ballaeast_01: 0xF42EE883, + g_m_y_ballaorig_01: 0x231AF63F, + g_m_y_ballasout_01: 0x23B88069, + g_m_y_famca_01: 0xE83B93B7, + g_m_y_famdnf_01: 0xDB729238, + g_m_y_famfor_01: 0x84302B09, + g_m_y_korean_01: 0x247502A9, + g_m_y_korean_02: 0x8FEDD989, + g_m_y_korlieut_01: 0x7CCBE17A, + g_m_y_lost_01: 0x4F46D607, + g_m_y_lost_02: 0x3D843282, + g_m_y_lost_03: 0x32B11CDC, + g_m_y_mexgang_01: 0xBDDD5546, + g_m_y_mexgoon_01: 0x26EF3426, + g_m_y_mexgoon_02: 0x31A3498E, + g_m_y_mexgoon_03: 0x964D12DC, + g_m_y_pologoon_01: 0x4F3FBA06, + g_m_y_pologoon_02: 0xA2E86156, + g_m_y_salvaboss_01: 0x905CE0CA, + g_m_y_salvagoon_01: 0x278C8CB7, + g_m_y_salvagoon_02: 0x3273A285, + g_m_y_salvagoon_03: 0x03B8C510, + g_m_y_strpunk_01: 0xFD1C49BB, + g_m_y_strpunk_02: 0x0DA1EAC6, + hc_driver: 0x3B474ADF, + hc_gunman: 0x0B881AEE, + hc_hacker: 0x99BB00F8, + ig_abigail: 0x400AEC41, + ig_agent: 0x246AF208, + ig_amandatownley: 0x6D1E15F7, + ig_andreas: 0x47E4EEA0, + ig_ashley: 0x7EF440DB, + ig_avon: 0xFCE270C2, + ig_ballasog: 0xA70B4A92, + ig_bankman: 0x909D9E7F, + ig_barry: 0x2F8845A3, + ig_benny: 0xC4B715D2, + ig_bestmen: 0x5746CD96, + ig_beverly: 0xBDA21E5C, + ig_brad: 0xBDBB4922, + ig_bride: 0x6162EC47, + ig_car3guy1: 0x84F9E937, + ig_car3guy2: 0x75C34ACA, + ig_casey: 0xE0FA2554, + ig_chef: 0x49EADBF6, + ig_chef2: 0x85889AC3, + ig_chengsr: 0xAAE4EA7B, + ig_chrisformage: 0x286E54A7, + ig_clay: 0x6CCFE08A, + ig_claypain: 0x9D0087A8, + ig_cletus: 0xE6631195, + ig_dale: 0x467415E9, + ig_davenorton: 0x15CD4C33, + ig_denise: 0x820B33BD, + ig_devin: 0x7461A0B0, + ig_dom: 0x9C2DB088, + ig_dreyfuss: 0xDA890932, + ig_drfriedlander: 0xCBFC0DF5, + ig_fabien: 0xD090C350, + ig_fbisuit_01: 0x3AE4A33B, + ig_floyd: 0xB1B196B2, + ig_g: 0x841BA933, + ig_groom: 0xFECE8B85, + ig_hao: 0x65978363, + ig_hunter: 0xCE1324DE, + ig_janet: 0x0D6D9C49, + ig_jay_norris: 0x7A32EE74, + ig_jewelass: 0x0F5D26BB, + ig_jimmyboston: 0xEDA0082D, + ig_jimmydisanto: 0x570462B9, + ig_joeminuteman: 0xBE204C9B, + ig_johnnyklebitz: 0x87CA80AE, + ig_josef: 0xE11A9FB4, + ig_josh: 0x799E9EEE, + ig_karen_daniels: 0xEB51D959, + ig_kerrymcintosh: 0x5B3BD90D, + ig_lamardavis: 0x65B93076, + ig_lazlow: 0xDFE443E5, + ig_lestercrest_2: 0x6E42FD26, + ig_lestercrest: 0x4DA6E849, + ig_lifeinvad_01: 0x5389A93C, + ig_lifeinvad_02: 0x27BD51D4, + ig_magenta: 0xFCDC910A, + ig_malc: 0xF1BCA919, + ig_manuel: 0xFD418E10, + ig_marnie: 0x188232D0, + ig_maryann: 0xA36F9806, + ig_maude: 0x3BE8287E, + ig_michelle: 0xBF9672F4, + ig_milton: 0xCB3059B2, + ig_molly: 0xAF03DDE1, + ig_money: 0x37FACDA6, + ig_mp_agent14: 0xFBF98469, + ig_mrk: 0xEDDCAB6D, + ig_mrs_thornhill: 0x1E04A96B, + ig_mrsphillips: 0x3862EEA8, + ig_natalia: 0xDE17DD3B, + ig_nervousron: 0xBD006AF1, + ig_nigel: 0xC8B7167D, + ig_old_man1a: 0x719D27F4, + ig_old_man2: 0xEF154C47, + ig_omega: 0x60E6A7D8, + ig_oneil: 0x2DC6D3E7, + ig_orleans: 0x61D4C771, + ig_ortega: 0x26A562B7, + ig_paige: 0x154FCF3F, + ig_paper: 0x999B00C6, + ig_patricia: 0xC56E118C, + ig_popov: 0x267630FE, + ig_priest: 0x6437E77D, + ig_prolsec_02: 0x27B3AD75, + ig_ramp_gang: 0xE52E126C, + ig_ramp_hic: 0x45753032, + ig_ramp_hipster: 0xDEEF9F6E, + ig_ramp_mex: 0xE6AC74A4, + ig_rashcosvki: 0x380C4DE6, + ig_roccopelosi: 0xD5BA52FF, + ig_russiandrunk: 0x3D0A5EB1, + ig_screen_writer: 0xFFE63677, + ig_siemonyetarian: 0x4C7B2F05, + ig_solomon: 0x86BDFE26, + ig_stevehains: 0x382121C8, + ig_stretch: 0x36984358, + ig_talina: 0xE793C8E8, + ig_tanisha: 0x0D810489, + ig_taocheng: 0xDC5C5EA5, + ig_taostranslator: 0x7C851464, + ig_tenniscoach: 0xA23B5F57, + ig_terry: 0x67000B94, + ig_tomepsilon: 0xCD777AAA, + ig_tonya: 0xCAC85344, + ig_tracydisanto: 0xDE352A35, + ig_trafficwarden: 0x5719786D, + ig_tylerdix: 0x5265F707, + ig_vagspeak: 0xF9FD068C, + ig_wade: 0x92991B72, + ig_zimbor: 0x0B34D6F5, + mp_f_boatstaff_01: 0x3293B9CE, + mp_f_cardesign_01: 0x242C34A7, + mp_f_chbar_01: 0xC3F6E385, + mp_f_cocaine_01: 0x4B657AF8, + mp_f_counterfeit_01: 0xB788F1F5, + mp_f_deadhooker: 0x73DEA88B, + mp_f_execpa_01: 0x432CA064, + mp_f_execpa_02: 0x5972CCF0, + mp_f_forgery_01: 0x781A3CF8, + mp_f_freemode_01: 0x9C9EFFD8, + mp_f_helistaff_01: 0x19B6FF06, + mp_f_meth_01: 0xD2B27EC1, + mp_f_misty_01: 0xD128FF9D, + mp_f_stripperlite: 0x2970A494, + mp_f_weed_01: 0xB26573A3, + mp_g_m_pros_01: 0x6C9DD7C9, + mp_m_avongoon: 0x9C13CB95, + mp_m_boatstaff_01: 0xC85F0A88, + mp_m_bogdangoon: 0x4D5696F7, + mp_m_claude_01: 0xC0F371B7, + mp_m_cocaine_01: 0x56D38F95, + mp_m_counterfeit_01: 0x9855C974, + mp_m_exarmy_01: 0x45348DBB, + mp_m_execpa_01: 0x3E8417BC, + mp_m_famdd_01: 0x33A464E5, + mp_m_fibsec_01: 0x5CDEF405, + mp_m_forgery_01: 0x613E709B, + mp_m_freemode_01: 0x705E61F2, + mp_m_g_vagfun_01: 0xC4A617BD, + mp_m_marston_01: 0x38430167, + mp_m_meth_01: 0xEDB42F3F, + mp_m_niko_01: 0xEEDACFC9, + mp_m_securoguard_01: 0xDA2C984E, + mp_m_shopkeep_01: 0x18CE57D0, + mp_m_waremech_01: 0xF7A74139, + mp_m_weapexp_01: 0x36EA5B09, + mp_m_weapwork_01: 0x4186506E, + mp_m_weed_01: 0x917ED459, + mp_s_m_armoured_01: 0xCDEF5408, + player_one: 0x9B22DBAF, + player_two: 0x9B810FA2, + player_zero: 0x0D7114C9, + s_f_m_fembarber: 0x163B875B, + s_f_m_maid_01: 0xE093C5C6, + s_f_m_shop_high: 0xAE47E4B0, + s_f_m_sweatshop_01: 0x312B5BC0, + s_f_y_airhostess_01: 0x5D71A46F, + s_f_y_bartender_01: 0x780C01BD, + s_f_y_baywatch_01: 0x4A8E5536, + s_f_y_cop_01: 0x15F8700D, + s_f_y_factory_01: 0x69F46BF3, + s_f_y_hooker_01: 0x028ABF95, + s_f_y_hooker_02: 0x14C3E407, + s_f_y_hooker_03: 0x031640AC, + s_f_y_migrant_01: 0xD55B2BF5, + s_f_y_movprem_01: 0x2300C816, + s_f_y_ranger_01: 0x9FC7F637, + s_f_y_scrubs_01: 0xAB594AB6, + s_f_y_sheriff_01: 0x4161D042, + s_f_y_shop_low: 0xA96E2604, + s_f_y_shop_mid: 0x3EECBA5D, + s_f_y_stripper_01: 0x52580019, + s_f_y_stripper_02: 0x6E0FB794, + s_f_y_stripperlite: 0x5C14EDFA, + s_f_y_sweatshop_01: 0x8502B6B2, + s_m_m_ammucountry: 0x0DE9A30A, + s_m_m_armoured_01: 0x95C76ECD, + s_m_m_armoured_02: 0x63858A4A, + s_m_m_autoshop_01: 0x040EABE3, + s_m_m_autoshop_02: 0xF06B849D, + s_m_m_bouncer_01: 0x9FD4292D, + s_m_m_ccrew_01: 0xC9E5F56B, + s_m_m_chemsec_01: 0x2EFEAFD5, + s_m_m_ciasec_01: 0x625D6958, + s_m_m_cntrybar_01: 0x1A021B83, + s_m_m_dockwork_01: 0x14D7B4E0, + s_m_m_doctor_01: 0xD47303AC, + s_m_m_fiboffice_01: 0xEDBC7546, + s_m_m_fiboffice_02: 0x26F067AD, + s_m_m_fibsec_01: 0x7B8B434B, + s_m_m_gaffer_01: 0xA956BD9E, + s_m_m_gardener_01: 0x49EA5685, + s_m_m_gentransport: 0x1880ED06, + s_m_m_hairdress_01: 0x418DFF92, + s_m_m_highsec_01: 0xF161D212, + s_m_m_highsec_02: 0x2930C1AB, + s_m_m_janitor: 0xA96BD9EC, + s_m_m_lathandy_01: 0x9E80D2CE, + s_m_m_lifeinvad_01: 0xDE0077FD, + s_m_m_linecook: 0xDB9C0997, + s_m_m_lsmetro_01: 0x765AAAE4, + s_m_m_mariachi_01: 0x7EA4FFA6, + s_m_m_marine_01: 0xF2DAA2ED, + s_m_m_marine_02: 0xF0259D83, + s_m_m_migrant_01: 0xED0CE4C6, + s_m_m_movalien_01: 0x64611296, + s_m_m_movprem_01: 0xD85E6D28, + s_m_m_movspace_01: 0xE7B31432, + s_m_m_paramedic_01: 0xB353629E, + s_m_m_pilot_01: 0xE75B4B1C, + s_m_m_pilot_02: 0xF63DE8E1, + s_m_m_postal_01: 0x62599034, + s_m_m_postal_02: 0x7367324F, + s_m_m_prisguard_01: 0x56C96FC6, + s_m_m_scientist_01: 0x4117D39B, + s_m_m_security_01: 0xD768B228, + s_m_m_snowcop_01: 0x1AE8BB58, + s_m_m_strperf_01: 0x795AC7A8, + s_m_m_strpreach_01: 0x1C0077FB, + s_m_m_strvend_01: 0xCE9113A9, + s_m_m_trucker_01: 0x59511A6C, + s_m_m_ups_01: 0x9FC37F22, + s_m_m_ups_02: 0xD0BDE116, + s_m_o_busker_01: 0xAD9EF1BB, + s_m_y_airworker: 0x62018559, + s_m_y_ammucity_01: 0x9E08633D, + s_m_y_armymech_01: 0x62CC28E2, + s_m_y_autopsy_01: 0xB2273D4E, + s_m_y_barman_01: 0xE5A11106, + s_m_y_baywatch_01: 0x0B4A6862, + s_m_y_blackops_01: 0xB3F3EE34, + s_m_y_blackops_02: 0x7A05FA59, + s_m_y_blackops_03: 0x5076A73B, + s_m_y_busboy_01: 0xD8F9CD47, + s_m_y_chef_01: 0x0F977CEB, + s_m_y_clown_01: 0x04498DDE, + s_m_y_construct_01: 0xD7DA9E99, + s_m_y_construct_02: 0xC5FEFADE, + s_m_y_cop_01: 0x5E3DA4A4, + s_m_y_dealer_01: 0xE497BBEF, + s_m_y_devinsec_01: 0x9B557274, + s_m_y_dockwork_01: 0x867639D1, + s_m_y_doorman_01: 0x22911304, + s_m_y_dwservice_01: 0x75D30A91, + s_m_y_dwservice_02: 0xF5908A06, + s_m_y_factory_01: 0x4163A158, + s_m_y_fireman_01: 0xB6B1EDA8, + s_m_y_garbage: 0xEE75A00F, + s_m_y_grip_01: 0x309E7DEA, + s_m_y_hwaycop_01: 0x739B1EF5, + s_m_y_marine_01: 0x65793043, + s_m_y_marine_02: 0x58D696FE, + s_m_y_marine_03: 0x72C0CAD2, + s_m_y_mime: 0x3CDCA742, + s_m_y_pestcont_01: 0x48114518, + s_m_y_pilot_01: 0xAB300C07, + s_m_y_prismuscl_01: 0x5F2113A1, + s_m_y_prisoner_01: 0xB1BB9B59, + s_m_y_ranger_01: 0xEF7135AE, + s_m_y_robber_01: 0xC05E1399, + s_m_y_sheriff_01: 0xB144F9B9, + s_m_y_shop_mask: 0x6E122C06, + s_m_y_strvend_01: 0x927F2323, + s_m_y_swat_01: 0x8D8F1B10, + s_m_y_uscg_01: 0xCA0050E9, + s_m_y_valet_01: 0x3B96F23E, + s_m_y_waiter_01: 0xAD4C724C, + s_m_y_winclean_01: 0x550D8D9D, + s_m_y_xmech_01: 0x441405EC, + s_m_y_xmech_02_mp: 0x69147A0D, + s_m_y_xmech_02: 0xBE20FA04, + u_f_m_corpse_01: 0x2E140314, + u_f_m_drowned_01: 0xD7F37609, + u_f_m_miranda: 0x414FA27B, + u_f_m_promourn_01: 0xA20899E7, + u_f_o_moviestar: 0x35578634, + u_f_o_prolhost_01: 0xC512DD23, + u_f_y_bikerchic: 0xFA389D4F, + u_f_y_comjane: 0xB6AA85CE, + u_f_y_corpse_01: 0x9C70109D, + u_f_y_corpse_02: 0x0D9C72F8, + u_f_y_hotposh_01: 0x969B6DFE, + u_f_y_jewelass_01: 0xF0D4BE2E, + u_f_y_mistress: 0x5DCA2528, + u_f_y_poppymich: 0x23E9A09E, + u_f_y_princess: 0xD2E3A284, + u_f_y_spyactress: 0x5B81D86C, + u_m_m_aldinapoli: 0xF0EC56E2, + u_m_m_bankman: 0xC306D6F5, + u_m_m_bikehire_01: 0x76474545, + u_m_m_doa_01: 0x621E6BFD, + u_m_m_edtoh: 0x2A797197, + u_m_m_fibarchitect: 0x342333D3, + u_m_m_filmdirector: 0x2B6E1BB6, + u_m_m_glenstank_01: 0x45BB1666, + u_m_m_griff_01: 0xC454BCBB, + u_m_m_jesus_01: 0xCE2CB751, + u_m_m_jewelsec_01: 0xACCCBDB6, + u_m_m_jewelthief: 0xE6CC3CDC, + u_m_m_markfost: 0x1C95CB0B, + u_m_m_partytarget: 0x81F74DE7, + u_m_m_prolsec_01: 0x709220C7, + u_m_m_promourn_01: 0xCE96030B, + u_m_m_rivalpap: 0x60D5D6DA, + u_m_m_spyactor: 0xAC0EA5D8, + u_m_m_streetart_01: 0x6C19E962, + u_m_m_willyfist: 0x90769A8F, + u_m_o_filmnoir: 0x2BACC2DB, + u_m_o_finguru_01: 0x46E39E63, + u_m_o_taphillbilly: 0x9A1E5E52, + u_m_o_tramp_01: 0x6A8F1F9B, + u_m_y_abner: 0xF0AC2626, + u_m_y_antonb: 0xCF623A2C, + u_m_y_babyd: 0xDA116E7E, + u_m_y_baygor: 0x5244247D, + u_m_y_burgerdrug_01: 0x8B7D3766, + u_m_y_chip: 0x24604B2B, + u_m_y_corpse_01: 0x94C2A03F, + u_m_y_cyclist_01: 0x2D0EFCEB, + u_m_y_fibmugger_01: 0x85B9C668, + u_m_y_guido_01: 0xC6B49A2F, + u_m_y_gunvend_01: 0xB3229752, + u_m_y_hippie_01: 0xF041880B, + u_m_y_imporage: 0x348065F5, + u_m_y_juggernaut_01: 0x90EF5134, + u_m_y_justin: 0x7DC3908F, + u_m_y_mani: 0xC8BB1E52, + u_m_y_militarybum: 0x4705974A, + u_m_y_paparazzi: 0x5048B328, + u_m_y_party_01: 0x36E70600, + u_m_y_pogo_01: 0xDC59940D, + u_m_y_prisoner_01: 0x7B9B4BC0, + u_m_y_proldriver_01: 0x855E36A3, + u_m_y_rsranger_01: 0x3C438CD2, + u_m_y_sbike: 0x6AF4185D, + u_m_y_staggrm_01: 0x9194CE03, + u_m_y_tattoo_01: 0x94AE2B8C, + u_m_y_zombie_01: 0xAC4B4506, + hanf_verarbeiter_typ: 0x6C8C08E5, + hanf_verarbeiter_wachmann: 0x7ED5AD78, + hanf_verarbeiter_wachhund: 0x9563221D +}; +var CreatedPeds: Array = []; + +export default function PedCreator() { + mp.events.add("SERVER:CreateStaticPeds", (jsonVector3s, jsonHeadings, jsonCharHashes, jsonDimension) => { var vector3s = JSON.parse(jsonVector3s); var headings = JSON.parse(jsonHeadings); @@ -756,7 +760,7 @@ hash = tmpHash; } - //mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`); + mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`); let p = mp.peds.new(hash, vector3s[i], headings[i], dimension[i]); p.freezePosition(true); @@ -775,14 +779,19 @@ } }); }); +} - function getPedHashByName(name: string) { - var keys = Object.keys(PedHashes); - var idx = keys.indexOf(name) !== -1; - if (idx) { - return PedHashes[name]; - } - - return -1; +function getPedHashByName(name: string) { + var keys = Object.keys(PedHashes); + var idx = keys.indexOf(name) !== -1; + if (idx) { + return PedHashes[name]; } + + return -1; +} + +export function getCreatedPedByName(name: string): PedMp { + var hash = getPedHashByName(name); + return CreatedPeds.filter(p => p.model === hash)[0]; } \ No newline at end of file diff --git a/ReallifeGamemode.Client/drugs/hanf.ts b/ReallifeGamemode.Client/drugs/hanf.ts new file mode 100644 index 00000000..1fb4cdcb --- /dev/null +++ b/ReallifeGamemode.Client/drugs/hanf.ts @@ -0,0 +1,67 @@ +import { Menu, Point, UIMenuSliderItem, UIMenuItem, Color, UIMenuListItem, ItemsCollection } from "../libs/NativeUI"; +import { createMenuItem } from "../util"; +import moneyformat from "../moneyformat"; +import { getAnimFromId } from "../util/animationSync"; +import { getCreatedPedByName } from "../Ped/PedCreator"; + +export default function hanfSystem(globalData: IGlobalData) { + mp.events.add("SERVER:Hanf_BuySeed", price => { + if (globalData.InMenu || globalData.InChat) { + return; + } + + globalData.InMenu = true; + + var menu = new Menu("Samen kaufen", "Kaufe dir Hanfsamen", new Point(50, 50)); + + var seedsToBuy = 0; + + var countItems = [...Array(50).keys()].map(x => x + 1); + + var soloPriceItem = createMenuItem("Einzelpreis", "Preis pro Samen", item => { + item.SetRightLabel("$" + moneyformat(price)); + }); + menu.AddItem(soloPriceItem); + + var countItem = new UIMenuListItem("Anzahl", "Wähle die Anzahl der Samen aus", new ItemsCollection(countItems), 0); + menu.AddItem(countItem); + + var buyItem = new UIMenuItem("Kaufen", "Kaufe die Samen"); + buyItem.BackColor = new Color(0, 100, 0); + buyItem.HighlightedBackColor = new Color(0, 150, 0); + menu.AddItem(buyItem); + + var completePriceItem = new UIMenuItem("Gesamtpreis", "Preis für alle Samen"); + menu.AddItem(completePriceItem); + + menu.ListChange.on((item, index) => { + if (item === countItem) { + seedsToBuy = Number(countItem.SelectedValue); + completePriceItem.SetRightLabel("$" + moneyformat(seedsToBuy * price)); + } + }); + + menu.ItemSelect.on((item, index) => { + if (item === buyItem) { + mp.events.callRemote("CLIENT:Hanf_BuySeeds", seedsToBuy); + menu.Close(); + } + }); + + menu.MenuClose.on(() => { + globalData.InMenu = false; + }); + + menu.Open(); + }); + + mp.events.add("SERVER:Hanf_PlayManufacturerAnim", animId => { + var anim = getAnimFromId(animId); + var npc = getCreatedPedByName("hanf_verarbeiter_typ"); + npc.taskPlayAnim(anim.dict, anim.name, 1, 0, 1000 * 10, 1, 0, !1, !1, !1); + setTimeout(() => { + npc.stopAnim(anim.name, anim.dict, 3); + npc.stopAnimTask(anim.dict, anim.name, 3); + }, 1000 * 10); + }); +} \ No newline at end of file diff --git a/ReallifeGamemode.Client/index.ts b/ReallifeGamemode.Client/index.ts index 763acf17..512ea377 100644 --- a/ReallifeGamemode.Client/index.ts +++ b/ReallifeGamemode.Client/index.ts @@ -295,6 +295,9 @@ rentCar(globalData); import Carwash from './util/carwash'; Carwash(globalData); +import hanfSystem from './drugs/hanf'; +hanfSystem(globalData); + require('./Gui/policedepartment'); require('./Gui/helptext'); require('./admin/spectate'); diff --git a/ReallifeGamemode.Client/util/animationSync.ts b/ReallifeGamemode.Client/util/animationSync.ts index f786b64a..e0842af2 100644 --- a/ReallifeGamemode.Client/util/animationSync.ts +++ b/ReallifeGamemode.Client/util/animationSync.ts @@ -1,5 +1,42 @@ import { debug } from "util"; +const animationSyncData = +{ + animations: [], + + register: function (name, animDict, animName, duration, loop, flag, endless) { + let id = mp.game.joaat(name); + + if (!this.animations.hasOwnProperty(id)) { + this.animations[id] = + { + id: id, + name: name, + animDict: animDict, + animName: animName, + duration: duration, + loop: loop, + flag: flag, + endless: endless + }; + } else { + mp.game.graphics.notify("Animation Sync Error: ~r~Duplicate Entry"); + } + }, + + getAnimFromId: function (name: string): { dict: string, name: string } { + var anim = this.animations[mp.game.joaat(name)]; + return { + dict: anim.animDict, + name: anim.animName + } + } +}; + +export function getAnimFromId(name: string) { + return animationSyncData.getAnimFromId(name); +} + export default function animationSync() { let blockInput = false; let animationBreakTimer; @@ -12,37 +49,13 @@ export default function animationSync() { animationSyncData.register("getUncuff", "mp_arresting", "b_uncuff", 5500, false, 0, false); animationSyncData.register("hup", "mp_am_hold_up", "handsup_base", -1, true, 50, true); animationSyncData.register("carryBox", "anim@heists@box_carry@", "idle", -1, true, 50, true); + animationSyncData.register("manufacturJoint", "anim@mp_snowball", "pickup_snowball", 1000 * 10, false, 1, false); }); const animationBreakMessage = [ { animName: "Cuffed", msg: "Handschellen gebrochen." } ]; - const animationSyncData = - { - animations: [], - - register: function (name, animDict, animName, duration, loop, flag, endless) { - let id = mp.game.joaat(name); - - if (!this.animations.hasOwnProperty(id)) { - this.animations[id] = - { - id: id, - name: name, - animDict: animDict, - animName: animName, - duration: duration, - loop: loop, - flag: flag, - endless: endless - }; - } else { - mp.game.graphics.notify("Animation Sync Error: ~r~Duplicate Entry"); - } - } - }; - /* mp.events.add("entityStreamIn", (entity) => { if (entity.type === "player" && entity.animationData) { @@ -90,6 +103,7 @@ export default function animationSync() { clearTimeout(animationBreakTimer); animationBreakTimer = null; } + if (string == null) { blockInput = false; return; diff --git a/ReallifeGamemode.Server/BaseScript.cs b/ReallifeGamemode.Server/BaseScript.cs new file mode 100644 index 00000000..969ff10c --- /dev/null +++ b/ReallifeGamemode.Server/BaseScript.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; +using Microsoft.Extensions.Logging; +using ReallifeGamemode.Server.Log; + +namespace ReallifeGamemode.Server +{ + public abstract class BaseScript : Script + { + protected readonly ILogger logger; + + public BaseScript() + { + logger = LogManager.GetLogger(this.GetType()); + } + } +} diff --git a/ReallifeGamemode.Server/Events/Key.cs b/ReallifeGamemode.Server/Events/Key.cs index b77f8649..79274414 100644 --- a/ReallifeGamemode.Server/Events/Key.cs +++ b/ReallifeGamemode.Server/Events/Key.cs @@ -243,6 +243,8 @@ namespace ReallifeGamemode.Server.Events AmmunationPoint nearestAmmunationPoint = PositionManager.AmmunationPoints.Find(s => s.Position.DistanceTo(player.Position) <= 1.5); RentcarPoint nearestRentcarPoint = PositionManager.rentcarPoints.Find(s => s.Position.DistanceTo(player.Position) <= 1.5); JailPoint nearestjailPoint = PositionManager.jailPoints.Find(s => s.Position.DistanceTo(player.Position) <= 1.5); + bool isNearCannabisSeedBuyPoint = HanfManager.IsPlayerNearSeedBuyPoint(player); + bool isNearJointManufacturerPoint = HanfManager.IsPlayerNearJointManufacturer(player); if (user?.FactionId != null) { @@ -761,6 +763,18 @@ namespace ReallifeGamemode.Server.Events return; } } + + if (isNearCannabisSeedBuyPoint) + { + player.TriggerEvent("SERVER:Hanf_BuySeed", HanfManager.SEED_PRICE); + return; + } + + if (isNearJointManufacturerPoint) + { + HanfManager.BuildJointsFromCannabis(player); + return; + } } [RemoteEvent("keyPress:I")] diff --git a/ReallifeGamemode.Server/Inventory/Items/Joint.cs b/ReallifeGamemode.Server/Inventory/Items/Joint.cs index 27bfc0d6..97ffc677 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Joint.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Joint.cs @@ -4,7 +4,8 @@ using System.Text; using GTANetworkAPI; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; -using ReallifeGamemode.Server.Services; +using ReallifeGamemode.Server.Extensions; +using ReallifeGamemode.Server.Util; namespace ReallifeGamemode.Server.Inventory.Items { @@ -22,6 +23,7 @@ namespace ReallifeGamemode.Server.Inventory.Items public override bool Use(Player player, User user, DatabaseContext databaseContext) { + player.ToggleInventory(InventoryToggleOption.HIDE); return true; } } diff --git a/ReallifeGamemode.Server/Main.cs b/ReallifeGamemode.Server/Main.cs index 439d20df..d3be0fe4 100644 --- a/ReallifeGamemode.Server/Main.cs +++ b/ReallifeGamemode.Server/Main.cs @@ -147,6 +147,7 @@ namespace ReallifeGamemode.Server PositionManager.LoadPositionManager(); LoadManager.LoadLoadManager(); Rentcar.Setup(); + HanfManager.Load(); World.WeatherSync.Load(); diff --git a/ReallifeGamemode.Server/Managers/HanfManager.cs b/ReallifeGamemode.Server/Managers/HanfManager.cs new file mode 100644 index 00000000..76b7a3a9 --- /dev/null +++ b/ReallifeGamemode.Server/Managers/HanfManager.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Timers; +using GTANetworkAPI; +using Microsoft.Extensions.Logging; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; +using ReallifeGamemode.Server.Extensions; +using ReallifeGamemode.Server.Inventory.Interfaces; +using ReallifeGamemode.Server.Inventory.Items; +using ReallifeGamemode.Server.Services; +using ReallifeGamemode.Server.Util; + +namespace ReallifeGamemode.Server.Managers +{ + public class HanfManager : BaseScript + { + /// + /// Punkte zum Samen kaufen + /// + private readonly static List _seedsBuyPoints = new List(); + + /// + /// Aktueller Samen-Preis + /// + public static int SEED_PRICE = 50; + + /// + /// Wie viele Joints man aus einem Cannabis bekommt + /// + public static int CANNABIS_TO_JOINT_RATIO = 3; + + /// + /// Flag, ob der Verarbeiter aktuell benutzt wird + /// + private static bool _manufacturerCurrentlyUsed = false; + + /// + /// Marihuana -> Joint + /// + private readonly static Vector3 _jointManufacturerPoint = new Vector3(-127.726105, 1921.5142, 197.31104); + + /// + /// Animations-ID des Verarbeitens + /// + private const string _manufacturerAnim = "manufacturJoint"; + + private static Timer _manufacturerDoneTimer = new Timer(TimeSpan.FromSeconds(10).TotalMilliseconds); + + static HanfManager() + { + _manufacturerDoneTimer.Elapsed += ManufacturerDoneTimerCallback; + } + + /// + /// Ladefunktion zum + /// + public static void Load() + { + _seedsBuyPoints.Add(new Vector3(-30.21876, -585.3222, 17.917326)); + _seedsBuyPoints.Add(new Vector3(-680.89386, -634.6783, 25.29923)); + _seedsBuyPoints.Add(new Vector3(-1310.743, -608.9064, 29.382874)); + _seedsBuyPoints.Add(new Vector3(-758.6156, -1595.2686, 6.302392)); + _seedsBuyPoints.Add(new Vector3(-441.0504, 1595.4435, 358.4195)); + + ColShape colShape = null; + + foreach (Vector3 buyPoint in _seedsBuyPoints) + { + colShape = NAPI.ColShape.CreateSphereColShape(buyPoint, 20.0f); + colShape.OnEntityEnterColShape += OnSeedBuyRangeColShapeEnter; + } + } + + private static void OnSeedBuyRangeColShapeEnter(ColShape colShape, Player player) + { + ChatService.SendMessage(player, $"Fremder sagt: Pssst.. Willst paar Samen erwerben?"); + } + + internal static bool IsPlayerNearSeedBuyPoint(Player player) + { + return _seedsBuyPoints.Any(p => player.Position.DistanceTo(p) <= 2.5f); + } + + internal static bool IsPlayerNearJointManufacturer(Player player) + { + return _jointManufacturerPoint.DistanceTo(player.Position) <= 2.5f; + } + + [RemoteEvent("CLIENT:Hanf_BuySeeds")] + public void HanfManagerBuySeeds(Player player, int amount) + { + if (!player.IsLoggedIn()) + { + return; + } + + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + + IItem seedItem = InventoryManager.GetItem(); + var newAmount = seedItem.Gewicht * amount; + + if (!InventoryManager.CanPlayerHoldMoreWeight(player, newAmount)) + { + player.TriggerEvent("~r~So viele Samen passen nicht mehr in deine Hosentasche"); + return; + } + + var price = amount * SEED_PRICE; + + if (user.Handmoney < price) + { + player.SendNotification("~r~Du hast nicht genug Geld dafür"); + return; + } + + logger.LogInformation("Player {0} bought {1} cannabis seeds for {2} dollars (price per seed: {3})", player.Name, amount, price, SEED_PRICE); // <-- WICHTIG LOGS + + user.Handmoney -= price; + dbContext.SaveChanges(); + + InventoryManager.AddItemToInventory(player, seedItem.Id, amount); + + player.SendNotification($"Du hast {amount} Hanfsamen gekauft"); + } + + internal static void BuildJointsFromCannabis(Player player) + { + if(player.HasAnimation(_manufacturerAnim) || _manufacturerCurrentlyUsed) + { + return; + } + + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + var userItems = InventoryManager.GetUserItems(player, dbContext); + + IItem cannabisItem = InventoryManager.GetItem(); + IItem jointItem = InventoryManager.GetItem(); + + var addWeight = jointItem.Gewicht * CANNABIS_TO_JOINT_RATIO - cannabisItem.Gewicht; + + if (!InventoryManager.CanPlayerHoldMoreWeight(player, addWeight)) + { + player.SendNotification("~r~Für die Verarbeitung hast du nicht genug Platz im Rucksack"); + return; + } + + UserItem userCannabisItem = userItems.Where(i => i.ItemId == cannabisItem.Id).FirstOrDefault(); + if (userCannabisItem == null) + { + player.SendNotification("~r~Du hast kein Cannabis dabei"); + return; + } + + _manufacturerCurrentlyUsed = true; + _manufacturerDoneTimer.Start(); + + player.SyncAnimation(_manufacturerAnim); + + InventoryManager.RemoveUserItem(user, userCannabisItem, 1); + InventoryManager.AddItemToInventory(player, jointItem.Id, CANNABIS_TO_JOINT_RATIO); + + player.SendNotification($"Du hast 1 Cannabis in {CANNABIS_TO_JOINT_RATIO} Joints verarbeitet"); + + NAPI.ClientEvent.TriggerClientEventInRange(player.Position, 100.0f, "SERVER:Hanf_PlayManufacturerAnim", _manufacturerAnim); + } + + private static void ManufacturerDoneTimerCallback(object sender, EventArgs args) + { + _manufacturerDoneTimer.Stop(); + _manufacturerCurrentlyUsed = false; + } + } +} diff --git a/ReallifeGamemode.Server/Managers/InventoryManager.cs b/ReallifeGamemode.Server/Managers/InventoryManager.cs index 4658cd12..a5d04b93 100644 --- a/ReallifeGamemode.Server/Managers/InventoryManager.cs +++ b/ReallifeGamemode.Server/Managers/InventoryManager.cs @@ -75,6 +75,11 @@ namespace ReallifeGamemode.Server.Managers player.SetSharedData("backpackItems", JsonConvert.SerializeObject(backpackItems[player].ToArray())); } + internal static IItem GetItem() where T : IItem + { + return itemList.Where(i => i.GetType() == typeof(T)).First(); + } + [RemoteEvent("CLIENT:getVehicleInventory")] public static void SetVehicleItems(Player player) { @@ -134,6 +139,11 @@ namespace ReallifeGamemode.Server.Managers player.SetSharedData("vehicleItems", JsonConvert.SerializeObject(vehicleItems[player].ToArray())); } + public static bool CanPlayerHoldMoreWeight(Player player, int moreWeight) + { + return GetUserInventoryWeight(player) + moreWeight <= MAX_USER_INVENTORY; + } + public static void LoadItems() { itemList = new List(); @@ -179,12 +189,8 @@ namespace ReallifeGamemode.Server.Managers if (userItem.Amount == 0) { dbContext.Remove(userItem); - dbContext.SaveChanges(); } - Player player = user.Player; - List itemList = GetUserItems(player); - if (itemList == null) return; dbContext.SaveChanges(); } } @@ -216,16 +222,29 @@ namespace ReallifeGamemode.Server.Managers return new DatabaseContext().VehicleItems.ToList().FindAll(i => i.GetVehicle().GetVehicle() == vehicle); } - public static List GetUserItems(Player player) + public static List GetUserItems(Player player, DatabaseContext dbContext = null) { - var user = player.GetUser(); - - using (var context = new DatabaseContext()) + if (dbContext == null) { - return context.UserItems.ToList().FindAll(i => i.UserId == user.Id); + using (dbContext = new DatabaseContext()) + { + return GetUserItemsInternal(player, dbContext); + } + } + else + { + return GetUserItemsInternal(player, dbContext); } } + private static List GetUserItemsInternal(Player player, DatabaseContext dbContext) + { + var user = player.GetUser(dbContext); + + return dbContext.UserItems.ToList().FindAll(i => i.UserId == user.Id); + } + + public static int GetUserInventoryWeight(Player player) { var user = player.GetUser(); diff --git a/ReallifeGamemode.Server/Util/Colors.cs b/ReallifeGamemode.Server/Util/Colors.cs new file mode 100644 index 00000000..13271ad9 --- /dev/null +++ b/ReallifeGamemode.Server/Util/Colors.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; + +namespace ReallifeGamemode.Server.Util +{ + public static class Colors + { + public static Color White = new Color(255, 255, 255); + } +} From 3abf2a2d0ef2b4825db043e582739564270a2037 Mon Sep 17 00:00:00 2001 From: hydrant Date: Tue, 25 May 2021 20:10:58 +0200 Subject: [PATCH 06/10] hanf continuation --- ReallifeGamemode.Client/Ped/PedCreator.ts | 2 +- ReallifeGamemode.Client/drugs/hanf.ts | 167 ++ ReallifeGamemode.Client/global.d.ts | 10 +- .../Entities/CannabisPlant.cs | 30 + ...210524202105_AddCannabisPlants.Designer.cs | 2223 +++++++++++++++++ .../20210524202105_AddCannabisPlants.cs | 47 + .../DatabaseContextModelSnapshot.cs | 40 + .../Models/DatabaseContext.cs | 2 + ReallifeGamemode.Server/Events/Connect.cs | 2 + .../Inventory/Items/CannabisSeeds.cs | 20 +- .../Managers/HanfManager.cs | 122 +- .../Managers/InventoryManager.cs | 5 +- ReallifeGamemode.Server/Util/CannabisData.cs | 19 + 13 files changed, 2681 insertions(+), 8 deletions(-) create mode 100644 ReallifeGamemode.Database/Entities/CannabisPlant.cs create mode 100644 ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.Designer.cs create mode 100644 ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.cs create mode 100644 ReallifeGamemode.Server/Util/CannabisData.cs diff --git a/ReallifeGamemode.Client/Ped/PedCreator.ts b/ReallifeGamemode.Client/Ped/PedCreator.ts index e2559dbd..98e14dad 100644 --- a/ReallifeGamemode.Client/Ped/PedCreator.ts +++ b/ReallifeGamemode.Client/Ped/PedCreator.ts @@ -760,7 +760,7 @@ export default function PedCreator() { hash = tmpHash; } - mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`); + //mp.gui.chat.push(`adding ped ${hash} (${charHashes[i]}`); let p = mp.peds.new(hash, vector3s[i], headings[i], dimension[i]); p.freezePosition(true); diff --git a/ReallifeGamemode.Client/drugs/hanf.ts b/ReallifeGamemode.Client/drugs/hanf.ts index 1fb4cdcb..9876f1b5 100644 --- a/ReallifeGamemode.Client/drugs/hanf.ts +++ b/ReallifeGamemode.Client/drugs/hanf.ts @@ -3,8 +3,24 @@ import { createMenuItem } from "../util"; import moneyformat from "../moneyformat"; import { getAnimFromId } from "../util/animationSync"; import { getCreatedPedByName } from "../Ped/PedCreator"; +import KeyBinder from 'ragemp-better-bindings'; + +const hanfPlantObjects = { + stage1: mp.game.joaat('bkr_prop_weed_bud_pruned_01a'), + stage2: mp.game.joaat('bkr_prop_weed_bud_01b'), + stage3: mp.game.joaat('prop_weed_02'), + stage4: mp.game.joaat('prop_weed_01') +}; + +const minimumPlantDistance = 5; export default function hanfSystem(globalData: IGlobalData) { + + let currentPlantingPreviewObject: ObjectMp = null; + let currentPlantingMarkerPreview: MarkerMp = null; + let currentlyPlanting: boolean = false; + let lastPlantingState = true; + mp.events.add("SERVER:Hanf_BuySeed", price => { if (globalData.InMenu || globalData.InChat) { return; @@ -64,4 +80,155 @@ export default function hanfSystem(globalData: IGlobalData) { npc.stopAnimTask(anim.dict, anim.name, 3); }, 1000 * 10); }); + + mp.events.add("SERVER:Hanf_StartPlanting", _ => { + let player = mp.players.local; + currentPlantingPreviewObject = mp.objects.new(hanfPlantObjects.stage1, player.position, { + alpha: 255 + }); + currentPlantingPreviewObject.notifyStreaming = true; + + currentlyPlanting = true; + }); + + mp.events.add(RageEnums.EventKey.RENDER, _ => { + if (!currentlyPlanting) { + return; + } + + var player = mp.players.local; + + var newPlantState = isAbleToPlant(); + + var markerColor: [number, number, number, number] = [0, 255, 0, 255]; + if (!newPlantState) { + markerColor = [255, 0, 0, 255]; + } + + if (currentPlantingMarkerPreview) { + currentPlantingMarkerPreview.destroy(); + } + + var playerPos = player.position; + var objectPos = new mp.Vector3(playerPos.x, playerPos.y, playerPos.z - 1.0); + + currentPlantingMarkerPreview = mp.markers.new(25, objectPos, 0.7, { + color: markerColor, + visible: true, + rotation: new mp.Vector3(1, 0, 0) + }); + }); + + mp.events.add(RageEnums.EventKey.ENTITY_STREAM_IN, entity => { + if (entity === currentPlantingPreviewObject) { + currentPlantingPreviewObject.attachTo(Number(mp.players.local.handle), 0, 0, 0.2, -0.95, 0, 0, 0, true, false, false, false, 0, true); + } + }); + + function isAbleToPlant() { + var player = mp.players.local; + + if (isNearPlant()) { + return false; + } + + if (!isSurfaceAllowed()) { + return false; + } + + if (currentPlantingPreviewObject) { + var objectPos = getPlantPreviewPosition(); + var realZ = mp.game.gameplay.getGroundZFor3dCoord(objectPos.x, objectPos.y, objectPos.z + 1, 0, false); + if (realZ > objectPos.z + 1) { + return false; + } + } + + if (player.isSwimming() || player.isSwimmingUnderWater() || !player.isOnFoot()) { + return false; + } + + return true; + } + + const RAYCAST_POINT_TO_POINT_NATIVE = "0x377906D8A31E5586"; + const GET_RAYCAST_RESULT_NATIVE = "0x65287525D951F6BE"; + + function isSurfaceAllowed() { + const player = mp.players.local; + var position = player.position; + var raycast = mp.game.invoke(RAYCAST_POINT_TO_POINT_NATIVE, position.x, position.y, position.z + 5, position.x, position.y, position.z - 5, -1, undefined, 0); + mp.gui.chat.push("raycast = " + raycast); + var hit: boolean, coord: Vector3Mp, surfaceNormal: Vector3Mp, materialHash: number, entityHit: EntityMp; + var raycastResult = mp.game.invoke(GET_RAYCAST_RESULT_NATIVE, raycast, hit, coord, surfaceNormal, materialHash, entityHit); + + mp.gui.chat.push("result: " + raycastResult + ", hit = " + hit + ", test = " + materialHash); + + return true; + } + + KeyBinder.bind('e', _ => { + if (!currentlyPlanting || globalData.InChat) { + return; + } + + if (!lastPlantingState) { + mp.game.graphics.notify("~r~Hier kann kein Hanf platziert werden"); + return; + } + + currentlyPlanting = false; + + var player = mp.players.local; + + if (currentPlantingPreviewObject) { + currentPlantingPreviewObject.destroy(); + } + + if (currentPlantingMarkerPreview) { + currentPlantingMarkerPreview.destroy(); + } + + var position = getPlantPreviewPosition(); + var realZ = mp.game.gameplay.getGroundZFor3dCoord(position.x, position.y, position.z + 2, 0, false); + + mp.events.callRemote("CLIENT:Hanf_PlantHanf", position.x, position.z, realZ); + }); + + function getPlantPreviewPosition(): Vector3Mp { + return mp.players.local.getOffsetFromInWorldCoords(0, 0.2, -1); + } + + function isNearPlant(): boolean { + var position = getPlantPreviewPosition(); + var nearPlant = false; + + Object.keys(hanfPlantObjects).forEach(k => { + var hash = hanfPlantObjects[k]; + var obj = mp.game.object.getClosestObjectOfType(position.x, position.y, position.z, minimumPlantDistance, hash, false, false, false); + if (obj && obj != currentPlantingPreviewObject.handle) { + nearPlant = true; + } + }); + + return nearPlant; + } + + let currentHanfData: Array = null; + let hanfDataIdToObjectMap: Map = null; + + mp.events.add("SERVER:Hanf_UpdateHanfData", dataJson => { + var data: Array = >JSON.parse(dataJson) + if (currentHanfData == null) { + currentHanfData = data; + } + + var newPlants = data.filter(d => currentHanfData.filter(x => x.id === d.id).length == 0); + var removedPlants = currentHanfData.filter(d => data.filter(x => x.id === d.id).length == 0); + var existingPlants = data.filter(d => currentHanfData.filter(x => x.id === d.id).length == 1); + + mp.gui.chat.push(`new: ${newPlants.length}, removed: ${removedPlants.length}, existing: ${existingPlants.length}`); + + currentHanfData = data; + }); } \ No newline at end of file diff --git a/ReallifeGamemode.Client/global.d.ts b/ReallifeGamemode.Client/global.d.ts index a3a3e4b2..9a836413 100644 --- a/ReallifeGamemode.Client/global.d.ts +++ b/ReallifeGamemode.Client/global.d.ts @@ -22,7 +22,7 @@ declare type AccountData = { nextPayday: number; stateFaction: boolean; playTime: number; - userWarn: number; + userWarn: number; } declare type JobData = { @@ -97,6 +97,14 @@ declare type RentcarProperty = { Price: number; } +declare type CannabisData = { + id: number; + x: number; + y: number; + z: number; + time: Date; +} + declare type PlayerCharacterData = { Gender: boolean; Father: number; diff --git a/ReallifeGamemode.Database/Entities/CannabisPlant.cs b/ReallifeGamemode.Database/Entities/CannabisPlant.cs new file mode 100644 index 00000000..1697942b --- /dev/null +++ b/ReallifeGamemode.Database/Entities/CannabisPlant.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; + +namespace ReallifeGamemode.Database.Entities +{ + public class CannabisPlant + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public long Id { get; set; } + + public DateTime PlantDate { get; set; } + + public float X { get; set; } + + public float Y { get; set; } + + public float Z { get; set; } + + public bool Harvested { get; set; } + + public User PlantedBy { get; set; } + + [ForeignKey(nameof(PlantedBy))] + public int PlantedById { get; set; } + } +} diff --git a/ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.Designer.cs b/ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.Designer.cs new file mode 100644 index 00000000..26238f60 --- /dev/null +++ b/ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.Designer.cs @@ -0,0 +1,2223 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ReallifeGamemode.Database.Models; + +namespace ReallifeGamemode.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20210524202105_AddCannabisPlants")] + partial class AddCannabisPlants + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.3") + .HasAnnotation("PropertyAccessMode", PropertyAccessMode.PreferFieldDuringConstruction) + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ATM", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("Faulty") + .HasColumnType("tinyint(1)"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("ATMs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Ban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Applied") + .HasColumnType("int"); + + b.Property("BannedBy") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Reason") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UntilDateTime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("BusRoutes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusRoutePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BusRouteId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("BusRouteId"); + + b.ToTable("BusRoutesPoints"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusinessBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessId") + .IsUnique(); + + b.ToTable("BusinessBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusinessData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessData"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Harvested") + .HasColumnType("tinyint(1)"); + + b.Property("PlantDate") + .HasColumnType("datetime(6)"); + + b.Property("PlantedById") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("PlantedById"); + + b.ToTable("CannabisPlants"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ageing") + .HasColumnType("tinyint unsigned"); + + b.Property("AgeingOpacity") + .HasColumnType("float"); + + b.Property("BeardColor") + .HasColumnType("tinyint unsigned"); + + b.Property("Blemishes") + .HasColumnType("tinyint unsigned"); + + b.Property("BlemishesOpacity") + .HasColumnType("float"); + + b.Property("Blush") + .HasColumnType("tinyint unsigned"); + + b.Property("BlushColor") + .HasColumnType("tinyint unsigned"); + + b.Property("BlushOpacity") + .HasColumnType("float"); + + b.Property("BrowDepth") + .HasColumnType("float"); + + b.Property("BrowHeight") + .HasColumnType("float"); + + b.Property("CheekDepth") + .HasColumnType("float"); + + b.Property("CheekboneHeight") + .HasColumnType("float"); + + b.Property("CheekboneWidth") + .HasColumnType("float"); + + b.Property("ChestHair") + .HasColumnType("tinyint unsigned"); + + b.Property("ChestHairColor") + .HasColumnType("tinyint unsigned"); + + b.Property("ChestHairOpacity") + .HasColumnType("float"); + + b.Property("ChinDepth") + .HasColumnType("float"); + + b.Property("ChinHeight") + .HasColumnType("float"); + + b.Property("ChinIndent") + .HasColumnType("float"); + + b.Property("ChinWidth") + .HasColumnType("float"); + + b.Property("Complexion") + .HasColumnType("tinyint unsigned"); + + b.Property("ComplexionOpacity") + .HasColumnType("float"); + + b.Property("EyeColor") + .HasColumnType("tinyint unsigned"); + + b.Property("EyeSize") + .HasColumnType("float"); + + b.Property("EyebrowColor") + .HasColumnType("tinyint unsigned"); + + b.Property("Eyebrows") + .HasColumnType("tinyint unsigned"); + + b.Property("EyebrowsOpacity") + .HasColumnType("float"); + + b.Property("FacialHair") + .HasColumnType("tinyint unsigned"); + + b.Property("FacialHairOpacity") + .HasColumnType("float"); + + b.Property("Father") + .HasColumnType("tinyint unsigned"); + + b.Property("Freckles") + .HasColumnType("tinyint unsigned"); + + b.Property("FrecklesOpacity") + .HasColumnType("float"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("Hair") + .HasColumnType("tinyint unsigned"); + + b.Property("HairColor") + .HasColumnType("tinyint unsigned"); + + b.Property("HairHighlightColor") + .HasColumnType("tinyint unsigned"); + + b.Property("JawShape") + .HasColumnType("float"); + + b.Property("JawWidth") + .HasColumnType("float"); + + b.Property("LipThickness") + .HasColumnType("float"); + + b.Property("Lipstick") + .HasColumnType("tinyint unsigned"); + + b.Property("LipstickColor") + .HasColumnType("tinyint unsigned"); + + b.Property("LipstickOpacity") + .HasColumnType("float"); + + b.Property("Makeup") + .HasColumnType("tinyint unsigned"); + + b.Property("MakeupOpacity") + .HasColumnType("float"); + + b.Property("Mother") + .HasColumnType("tinyint unsigned"); + + b.Property("NeckWidth") + .HasColumnType("float"); + + b.Property("NoseBottomHeight") + .HasColumnType("float"); + + b.Property("NoseBridgeDepth") + .HasColumnType("float"); + + b.Property("NoseBroken") + .HasColumnType("float"); + + b.Property("NoseTipHeight") + .HasColumnType("float"); + + b.Property("NoseTipLength") + .HasColumnType("float"); + + b.Property("NoseWidth") + .HasColumnType("float"); + + b.Property("Similarity") + .HasColumnType("float"); + + b.Property("SkinSimilarity") + .HasColumnType("float"); + + b.Property("SunDamage") + .HasColumnType("tinyint unsigned"); + + b.Property("SunDamageOpacity") + .HasColumnType("float"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Characters"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CharacterCloth", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClothId") + .HasColumnType("int"); + + b.Property("Duty") + .HasColumnType("tinyint(1)"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("SlotType") + .HasColumnType("tinyint unsigned"); + + b.Property("Texture") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("CharacterClothes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ClothCombination", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("Top") + .HasColumnType("int"); + + b.Property("Torso") + .HasColumnType("int"); + + b.Property("Undershirt") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ClothCombinations"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Door", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AlwaysOpen") + .HasColumnType("tinyint(1)"); + + b.Property("Category") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Locked") + .HasColumnType("tinyint(1)"); + + b.Property("Model") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Radius") + .HasColumnType("float"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("Doors"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.DutyCloth", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClothId") + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("SlotType") + .HasColumnType("tinyint unsigned"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("DutyClothes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Faction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("GangOwned") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("StateOwned") + .HasColumnType("tinyint(1)"); + + b.Property("WeaponDealTime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BankAccountId"); + + b.ToTable("Factions"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("Bic") + .HasColumnType("varchar(12) CHARACTER SET utf8mb4") + .HasMaxLength(12); + + b.Property("Iban") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("FactionBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("RankName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("FactionRanks"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionWeapon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ammount") + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("SlotID") + .HasColumnType("int"); + + b.Property("WeaponModel") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("FactionWeapons"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GotoPoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Description") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("GotoPoints"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BankAccountId"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GroupBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Balance") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("GroupBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.House", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("CanRentIn") + .HasColumnType("tinyint(1)"); + + b.Property("LastRentSetTime") + .HasColumnType("datetime(6)"); + + b.Property("OwnerId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("RentalFee") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("BankAccountId"); + + b.HasIndex("OwnerId"); + + b.ToTable("Houses"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.HouseBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Balance") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("HouseBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.HouseRental", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("HouseId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("HouseId"); + + b.HasIndex("UserId"); + + b.ToTable("HouseRentals"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Interior", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EnterPositionStr") + .HasColumnName("EnterPosition") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ExitPositionStr") + .HasColumnName("ExitPosition") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("Interiors"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Heading") + .HasColumnType("double"); + + b.Property("X") + .HasColumnType("double"); + + b.Property("Y") + .HasColumnType("double"); + + b.Property("Z") + .HasColumnType("double"); + + b.HasKey("Id"); + + b.ToTable("Locations"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.BankAccountTransactionHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Fee") + .HasColumnType("int"); + + b.Property("MoneySent") + .HasColumnType("int"); + + b.Property("NewReceiverBalance") + .HasColumnType("int"); + + b.Property("NewSenderBalance") + .HasColumnType("int"); + + b.Property("Origin") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Receiver") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("ReceiverBalance") + .HasColumnType("int"); + + b.Property("Sender") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("SenderBalance") + .HasColumnType("int"); + + b.Property("Timestamp") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("BankAccountTransactionLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Text") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Time") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ChatLogs"); + + b.HasDiscriminator("Discriminator").HasValue("ChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.CommandLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Command") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Time") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("CommandLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Death", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CauseOfDeath") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("KillerHeading") + .HasColumnType("float"); + + b.Property("KillerId") + .HasColumnType("int"); + + b.Property("KillerPositionX") + .HasColumnType("float"); + + b.Property("KillerPositionY") + .HasColumnType("float"); + + b.Property("KillerPositionZ") + .HasColumnType("float"); + + b.Property("Timestamp") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.Property("VictimHeading") + .HasColumnType("float"); + + b.Property("VictimId") + .HasColumnType("int"); + + b.Property("VictimPositionX") + .HasColumnType("float"); + + b.Property("VictimPositionY") + .HasColumnType("float"); + + b.Property("VictimPositionZ") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("KillerId"); + + b.HasIndex("VictimId"); + + b.ToTable("DeathLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.LoginLogoutLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("IpAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("LoginLogout") + .HasColumnType("tinyint(1)"); + + b.Property("PlayerId") + .HasColumnType("bigint"); + + b.Property("SocialClubName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Time") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("Username") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("LoginLogoutLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.News", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Caption") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Content") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Timestamp") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("News"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedBlip", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Alpha") + .HasColumnType("tinyint unsigned"); + + b.Property("Color") + .HasColumnType("tinyint unsigned"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("DrawDistance") + .HasColumnType("float"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("Rotation") + .HasColumnType("float"); + + b.Property("Scale") + .HasColumnType("float"); + + b.Property("ShortRange") + .HasColumnType("tinyint(1)"); + + b.Property("Sprite") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.ToTable("Blips"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedMarker", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ColorA") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorB") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorG") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorR") + .HasColumnType("tinyint unsigned"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("DirectionX") + .HasColumnType("float"); + + b.Property("DirectionY") + .HasColumnType("float"); + + b.Property("DirectionZ") + .HasColumnType("float"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("RotationX") + .HasColumnType("float"); + + b.Property("RotationY") + .HasColumnType("float"); + + b.Property("RotationZ") + .HasColumnType("float"); + + b.Property("Scale") + .HasColumnType("float"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("Visible") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Markers"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedPed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("HashModel") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Heading") + .HasColumnType("float"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Peds"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedPickup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("PositionX") + .HasColumnType("float") + .HasMaxLength(128); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("RespawnTime") + .HasColumnType("int"); + + b.Property("RotationX") + .HasColumnType("float"); + + b.Property("RotationY") + .HasColumnType("float"); + + b.Property("RotationZ") + .HasColumnType("float"); + + b.Property("Vehicle") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Pickups"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedTextLabel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ColorA") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorB") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorG") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorR") + .HasColumnType("tinyint unsigned"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("DrawDistance") + .HasColumnType("float"); + + b.Property("Font") + .HasColumnType("tinyint unsigned"); + + b.Property("LOS") + .HasColumnType("tinyint(1)"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("Text") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("TextLabels"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.Property("Variable") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ServerVehicle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("DistanceDriven") + .HasColumnType("float"); + + b.Property("Heading") + .HasColumnType("float"); + + b.Property("Livery") + .HasColumnType("int"); + + b.Property("Locked") + .HasColumnType("tinyint(1)"); + + b.Property("Model") + .HasColumnType("int unsigned"); + + b.Property("NumberPlate") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("PrimaryColor") + .HasColumnType("int"); + + b.Property("SecondaryColor") + .HasColumnType("int"); + + b.Property("TankAmount") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("ServerVehicles"); + + b.HasDiscriminator("Discriminator").HasValue("ServerVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ShopClothe", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Category") + .HasColumnType("int"); + + b.Property("ClotheId") + .HasColumnType("int"); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("TypeId") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("ShopClothes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ShopItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Amount") + .HasColumnType("int"); + + b.Property("ItemId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ShopItems"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.TuningGarage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("TuningGarages"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Turfs", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Color") + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("MaxValue") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Owner") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Range") + .HasColumnType("float"); + + b.Property("Rotation") + .HasColumnType("float"); + + b.Property("Surplus") + .HasColumnType("tinyint(1)"); + + b.Property("Value") + .HasColumnType("int"); + + b.Property("Vector") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Turfs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AdminLevel") + .HasColumnType("int"); + + b.Property("BanId") + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("BusSkill") + .HasColumnType("int"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Dead") + .HasColumnType("tinyint(1)"); + + b.Property("DriverLicenseBike") + .HasColumnType("tinyint(1)"); + + b.Property("DriverLicenseVehicle") + .HasColumnType("tinyint(1)"); + + b.Property("Email") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("FactionLeader") + .HasColumnType("tinyint(1)"); + + b.Property("FactionRankId") + .HasColumnType("int"); + + b.Property("FlyingLicensePlane") + .HasColumnType("tinyint(1)"); + + b.Property("FreeSurgery") + .HasColumnType("tinyint(1)"); + + b.Property("GroupId") + .HasColumnType("int"); + + b.Property("GroupRank") + .HasColumnType("int"); + + b.Property("Handmoney") + .HasColumnType("int"); + + b.Property("HouseId") + .HasColumnType("int"); + + b.Property("JailTime") + .HasColumnType("int"); + + b.Property("JobId") + .HasColumnType("int"); + + b.Property("LogUserId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Password") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("PaydayTimer") + .HasColumnType("int"); + + b.Property("PilotSkill") + .HasColumnType("int"); + + b.Property("PlayedMinutes") + .HasColumnType("int"); + + b.Property("Points") + .HasColumnType("int"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("RegistrationDate") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.Property("SocialClubName") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Wage") + .HasColumnType("int"); + + b.Property("Wanteds") + .HasColumnType("int"); + + b.Property("WeaponLicense") + .HasColumnType("tinyint(1)"); + + b.Property("failpoints") + .HasColumnType("int"); + + b.Property("otheramount") + .HasColumnType("int"); + + b.Property("trashcount") + .HasColumnType("int"); + + b.Property("warn") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BanId"); + + b.HasIndex("BankAccountId"); + + b.HasIndex("BusinessId") + .IsUnique(); + + b.HasIndex("CharacterId"); + + b.HasIndex("FactionId"); + + b.HasIndex("FactionRankId"); + + b.HasIndex("GroupId"); + + b.HasIndex("HouseId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("Bic") + .HasColumnType("varchar(12) CHARACTER SET utf8mb4") + .HasMaxLength(12); + + b.Property("Iban") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("UserBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Amount") + .HasColumnType("int"); + + b.Property("ItemId") + .HasColumnType("int"); + + b.Property("Slot") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserItems"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserWeapon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ammo") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("WeaponId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("WeaponId"); + + b.ToTable("UserWeapons"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Amount") + .HasColumnType("int"); + + b.Property("ItemId") + .HasColumnType("int"); + + b.Property("Slot") + .HasColumnType("int"); + + b.Property("VehicleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("VehicleId"); + + b.ToTable("VehicleItems"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleMod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ModId") + .HasColumnType("int"); + + b.Property("ServerVehicleId") + .HasColumnType("int"); + + b.Property("Slot") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ServerVehicleId", "Slot") + .IsUnique(); + + b.ToTable("VehicleMods"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Weapon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ammo") + .HasColumnType("int"); + + b.Property("AmmunationActive") + .HasColumnType("tinyint(1)"); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("Legal") + .HasColumnType("tinyint(1)"); + + b.Property("Price") + .HasColumnType("float"); + + b.Property("SlotID") + .HasColumnType("int"); + + b.Property("WeaponModel") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Weapons"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.WeaponCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Category") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("WeaponCategories"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Whitelist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("SocialClubName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("WhitelistEntries"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.DepartmentChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("DepartmentChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.FactionChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.HasIndex("FactionId"); + + b.HasDiscriminator().HasValue("FactionChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.GangChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("GangChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.GroupChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.Property("GroupId") + .HasColumnType("int"); + + b.HasIndex("GroupId"); + + b.HasDiscriminator().HasValue("GroupChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.LeaderChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("LeaderChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.LocalChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("LocalChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.NewsChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("NewsChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.OChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("OChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("BuyPrice") + .HasColumnType("int"); + + b.Property("Owners") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.ToTable("FactionVehicles"); + + b.HasDiscriminator().HasValue("FactionVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GroupVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("GroupId") + .HasColumnType("int"); + + b.HasIndex("GroupId"); + + b.HasDiscriminator().HasValue("GroupVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.JobVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("JobId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("JobVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.NoobSpawnVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.HasDiscriminator().HasValue("NoobSpawnVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.NoobVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.HasDiscriminator().HasValue("NoobVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.HasDiscriminator().HasValue("SavedVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.SchoolVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("SchoolId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("SchoolVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ShopVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.ToTable("ShopVehicles"); + + b.HasDiscriminator().HasValue("ShopVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("BusinessId") + .HasColumnName("UserVehicle_BusinessId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnName("UserVehicle_Price") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasIndex("UserId"); + + b.ToTable("UserVehicles"); + + b.HasDiscriminator().HasValue("UserVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Ban", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusRoutePoint", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.BusRoute", "BusRoute") + .WithMany("RoutePoints") + .HasForeignKey("BusRouteId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "PlantedBy") + .WithMany() + .HasForeignKey("PlantedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CharacterCloth", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Door", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.DutyCloth", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Faction", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.FactionBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionRank", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionWeapon", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Group", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.GroupBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.House", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.HouseBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + + b.HasOne("ReallifeGamemode.Database.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.HouseRental", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.House", "House") + .WithMany("Rentals") + .HasForeignKey("HouseId"); + + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.CommandLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Death", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "Killer") + .WithMany() + .HasForeignKey("KillerId"); + + b.HasOne("ReallifeGamemode.Database.Entities.User", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.LoginLogoutLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.News", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.User", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Ban", "Ban") + .WithMany() + .HasForeignKey("BanId"); + + b.HasOne("ReallifeGamemode.Database.Entities.UserBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + + b.HasOne("ReallifeGamemode.Database.Entities.Character", "Character") + .WithMany() + .HasForeignKey("CharacterId"); + + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId"); + + b.HasOne("ReallifeGamemode.Database.Entities.FactionRank", "FactionRank") + .WithMany() + .HasForeignKey("FactionRankId"); + + b.HasOne("ReallifeGamemode.Database.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId"); + + b.HasOne("ReallifeGamemode.Database.Entities.House", "House") + .WithMany() + .HasForeignKey("HouseId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserItem", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserWeapon", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ReallifeGamemode.Database.Entities.Weapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleItem", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.ServerVehicle", "Vehicle") + .WithMany() + .HasForeignKey("VehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleMod", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.ServerVehicle", "Vehicle") + .WithMany() + .HasForeignKey("ServerVehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Weapon", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.WeaponCategory", "WeaponCategory") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.FactionChatLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.GroupChatLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GroupVehicle", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserVehicle", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.cs b/ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.cs new file mode 100644 index 00000000..0663b19c --- /dev/null +++ b/ReallifeGamemode.Database/Migrations/20210524202105_AddCannabisPlants.cs @@ -0,0 +1,47 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ReallifeGamemode.Database.Migrations +{ + public partial class AddCannabisPlants : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CannabisPlants", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + PlantDate = table.Column(nullable: false), + X = table.Column(nullable: false), + Y = table.Column(nullable: false), + Z = table.Column(nullable: false), + Harvested = table.Column(nullable: false), + PlantedById = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CannabisPlants", x => x.Id); + table.ForeignKey( + name: "FK_CannabisPlants_Users_PlantedById", + column: x => x.PlantedById, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_CannabisPlants_PlantedById", + table: "CannabisPlants", + column: "PlantedById"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CannabisPlants"); + } + } +} diff --git a/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs b/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs index 341f3a2d..ceeeb6b5 100644 --- a/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs +++ b/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs @@ -154,6 +154,37 @@ namespace ReallifeGamemode.Database.Migrations b.ToTable("BusinessData"); }); + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Harvested") + .HasColumnType("tinyint(1)"); + + b.Property("PlantDate") + .HasColumnType("datetime(6)"); + + b.Property("PlantedById") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("PlantedById"); + + b.ToTable("CannabisPlants"); + }); + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b => { b.Property("Id") @@ -1931,6 +1962,15 @@ namespace ReallifeGamemode.Database.Migrations .HasForeignKey("BusRouteId"); }); + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "PlantedBy") + .WithMany() + .HasForeignKey("PlantedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b => { b.HasOne("ReallifeGamemode.Database.Entities.User", "User") diff --git a/ReallifeGamemode.Database/Models/DatabaseContext.cs b/ReallifeGamemode.Database/Models/DatabaseContext.cs index 6a8fb10d..20b5e151 100644 --- a/ReallifeGamemode.Database/Models/DatabaseContext.cs +++ b/ReallifeGamemode.Database/Models/DatabaseContext.cs @@ -179,6 +179,8 @@ namespace ReallifeGamemode.Database.Models //Server Variablen public DbSet ServerVariables { get; set; } + + public DbSet CannabisPlants { get; set; } } public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory diff --git a/ReallifeGamemode.Server/Events/Connect.cs b/ReallifeGamemode.Server/Events/Connect.cs index 2f1ce662..1c43f5b7 100644 --- a/ReallifeGamemode.Server/Events/Connect.cs +++ b/ReallifeGamemode.Server/Events/Connect.cs @@ -88,6 +88,8 @@ namespace ReallifeGamemode.Server.Events NAPI.World.RequestIpl("ferris_finale_Anim"); // Riesenrad NAPI.World.RequestIpl("Carwash_with_spinners"); // Carwash + HanfManager.UpdateHanfForPlayer(player); + TimeSpan currentTime = TimeManager.CurrentTime; bool disableLightMode = currentTime > LightModeTimeFrom && currentTime < LightModeTimeTo; diff --git a/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs b/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs index 63f0f0db..f3fa752d 100644 --- a/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs +++ b/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs @@ -1,10 +1,15 @@ using System; using System.Collections.Generic; using System.Text; +using GTANetworkAPI; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Database.Models; +using ReallifeGamemode.Server.Extensions; +using ReallifeGamemode.Server.Managers; namespace ReallifeGamemode.Server.Inventory.Items { - public class CannabisSeeds : BaseItem + public class CannabisSeeds : UseItem { public override int Id { get; } = 109; public override string Name { get; } = "Cannabis Samen"; @@ -13,5 +18,18 @@ namespace ReallifeGamemode.Server.Inventory.Items public override string Einheit { get; } = "g"; public override int Price { get; } = 0; public override bool Legal => false; + + public override uint Object { get; } + public override bool RemoveWhenUsed { get; } = false; + + public override bool Use(Player player, User user, DatabaseContext databaseContext) + { + if(!player.IsInVehicle) + { + HanfManager.StartCannabisPlanting(player); + } + + return true; + } } } diff --git a/ReallifeGamemode.Server/Managers/HanfManager.cs b/ReallifeGamemode.Server/Managers/HanfManager.cs index 76b7a3a9..ff74bfa5 100644 --- a/ReallifeGamemode.Server/Managers/HanfManager.cs +++ b/ReallifeGamemode.Server/Managers/HanfManager.cs @@ -5,6 +5,7 @@ using System.Text; using System.Timers; using GTANetworkAPI; using Microsoft.Extensions.Logging; +using Newtonsoft.Json; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; @@ -47,8 +48,18 @@ namespace ReallifeGamemode.Server.Managers /// private const string _manufacturerAnim = "manufacturJoint"; + /// + /// Data-Key, ob der Spieler grade eine Pflanze anpflanzt + /// + private const string PLAYER_CURRENTLY_PLANTING_DATA_KEY = "isPlantingCannabis"; + + /// + /// Timer der den Status des Verarbeiters zurücksetzt + /// private static Timer _manufacturerDoneTimer = new Timer(TimeSpan.FromSeconds(10).TotalMilliseconds); + private static List _currentCannabisData = new List(); + static HanfManager() { _manufacturerDoneTimer.Elapsed += ManufacturerDoneTimerCallback; @@ -72,11 +83,29 @@ namespace ReallifeGamemode.Server.Managers colShape = NAPI.ColShape.CreateSphereColShape(buyPoint, 20.0f); colShape.OnEntityEnterColShape += OnSeedBuyRangeColShapeEnter; } + + UpdateHanfWorldData(new DatabaseContext()); + + Timer updateHanfDataTimer = new Timer(TimeSpan.FromMinutes(1).TotalMilliseconds); + updateHanfDataTimer.Elapsed += UpdateHanfDataTimer_Elapsed; + updateHanfDataTimer.Start(); + } + + private static void UpdateHanfDataTimer_Elapsed(object sender, ElapsedEventArgs e) + { + using var dbContext = new DatabaseContext(); + UpdateHanfWorldData(dbContext); } private static void OnSeedBuyRangeColShapeEnter(ColShape colShape, Player player) { - ChatService.SendMessage(player, $"Fremder sagt: Pssst.. Willst paar Samen erwerben?"); + var user = player.GetUser(); + if (user.Faction.StateOwned) + { + return; + } + + ChatService.SendMessage(player, $"Fremder sagt: Pssst.. Willst du Samen kaufen?"); } internal static bool IsPlayerNearSeedBuyPoint(Player player) @@ -89,6 +118,95 @@ namespace ReallifeGamemode.Server.Managers return _jointManufacturerPoint.DistanceTo(player.Position) <= 2.5f; } + internal static void StartCannabisPlanting(Player player) + { + player.ToggleInventory(InventoryToggleOption.HIDE); + + if (!player.IsAlive()) + { + return; + } + + var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + if (user.Faction?.StateOwned ?? false) + { + player.SendNotification("~r~Du darfst keine Hanfsamen einfplanzen"); + return; + } + + if (player.HasData(PLAYER_CURRENTLY_PLANTING_DATA_KEY) && player.GetData(PLAYER_CURRENTLY_PLANTING_DATA_KEY)) + { + player.SendNotification("~r~Du pflanzt aktuell schon einen Hanfsamen ein"); + return; + } + + player.SetData(PLAYER_CURRENTLY_PLANTING_DATA_KEY, true); + + player.TriggerEvent("SERVER:Hanf_StartPlanting"); + } + + [RemoteEvent("CLIENT:Hanf_PlantHanf")] + public void HanfManagerPlantHanf(Player player, float x, float y, float z) + { + player.ResetData(PLAYER_CURRENTLY_PLANTING_DATA_KEY); + + IItem cannabisSeedItem = InventoryManager.GetItem(); + UserItem userCannabisSeedsItem = InventoryManager.UserHasThisItem(player, cannabisSeedItem.Id); + if (userCannabisSeedsItem == null) + { + player.SendNotification("~r~Du hast keine Samen mehr"); + return; + } + + logger.LogInformation("Player {0} planted a cannabis plant at x: {1}, y: {2}, z: {3}", player.Name, x, y, z); + + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + + InventoryManager.RemoveUserItem(user, userCannabisSeedsItem, 1); + + CannabisPlant newPlant = new CannabisPlant() + { + X = x, + Y = y, + Z = z, + PlantedBy = user, + PlantDate = DateTime.Now, + }; + + dbContext.CannabisPlants.Add(newPlant); + dbContext.SaveChanges(); + + UpdateHanfWorldData(dbContext); + } + + public static void UpdateHanfWorldData(DatabaseContext dbContext) + { + var activePlants = dbContext.CannabisPlants.Where(p => !p.Harvested).Select(p => new CannabisData() + { + Id = p.Id, + Time = p.PlantDate, + X = p.X, + Y = p.Y, + Z = p.Z + }).ToList(); + + _currentCannabisData = activePlants; + + NAPI.Pools.GetAllPlayers().ForEach(p => + { + UpdateHanfForPlayer(p, activePlants); + }); + } + + public async static void UpdateHanfForPlayer(Player player, List cannabisData = null) + { + cannabisData ??= _currentCannabisData; + var x = await NAPI.Task.WaitForMainThread(); + player.TriggerEvent("SERVER:Hanf_UpdateHanfData", JsonConvert.SerializeObject(cannabisData)); + } + [RemoteEvent("CLIENT:Hanf_BuySeeds")] public void HanfManagerBuySeeds(Player player, int amount) { @@ -129,7 +247,7 @@ namespace ReallifeGamemode.Server.Managers internal static void BuildJointsFromCannabis(Player player) { - if(player.HasAnimation(_manufacturerAnim) || _manufacturerCurrentlyUsed) + if (player.HasAnimation(_manufacturerAnim) || _manufacturerCurrentlyUsed) { return; } diff --git a/ReallifeGamemode.Server/Managers/InventoryManager.cs b/ReallifeGamemode.Server/Managers/InventoryManager.cs index a5d04b93..aaa1b434 100644 --- a/ReallifeGamemode.Server/Managers/InventoryManager.cs +++ b/ReallifeGamemode.Server/Managers/InventoryManager.cs @@ -563,10 +563,9 @@ namespace ReallifeGamemode.Server.Managers if (usableItemObj.RemoveWhenUsed) { RemoveUserItem(user, fItem, 1); + SetBackpackItems(player); + player.TriggerEvent("aproveUse", 1, iItem.Name); } - - SetBackpackItems(player); - player.TriggerEvent("aproveUse", 1, iItem.Name); } } else player.TriggerEvent("Error", "Du kannst dieses Item nicht benutzen."); diff --git a/ReallifeGamemode.Server/Util/CannabisData.cs b/ReallifeGamemode.Server/Util/CannabisData.cs new file mode 100644 index 00000000..ed1180d7 --- /dev/null +++ b/ReallifeGamemode.Server/Util/CannabisData.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReallifeGamemode.Server.Util +{ + public class CannabisData + { + public long Id { get; set; } + + public float X { get; set; } + + public float Y { get; set; } + + public float Z { get; set; } + + public DateTime Time { get; set; } + } +} From 4be3137cc55fac93c2adc9d0197d751d7fbb2728 Mon Sep 17 00:00:00 2001 From: hydrant Date: Wed, 26 May 2021 01:33:31 +0200 Subject: [PATCH 07/10] hanf wachstum --- ReallifeGamemode.Client/drugs/hanf.ts | 170 ++++++++++++++---- ReallifeGamemode.Client/game.ts | 2 +- ReallifeGamemode.Client/global.d.ts | 10 +- .../Commands/AdminCommands.cs | 13 ++ ReallifeGamemode.Server/Events/Connect.cs | 2 - ReallifeGamemode.Server/Events/Login.cs | 2 + ReallifeGamemode.Server/Events/Register.cs | 7 +- .../Managers/HanfManager.cs | 106 ++++++++++- 8 files changed, 271 insertions(+), 41 deletions(-) diff --git a/ReallifeGamemode.Client/drugs/hanf.ts b/ReallifeGamemode.Client/drugs/hanf.ts index 9876f1b5..3dd44235 100644 --- a/ReallifeGamemode.Client/drugs/hanf.ts +++ b/ReallifeGamemode.Client/drugs/hanf.ts @@ -12,7 +12,29 @@ const hanfPlantObjects = { stage4: mp.game.joaat('prop_weed_01') }; -const minimumPlantDistance = 5; +const hanfTimeToObject = [ + { + minutes: 15, + object: hanfPlantObjects.stage1, + }, + { + minutes: 60 * 1, + object: hanfPlantObjects.stage2 + }, + { + minutes: 60 * 3, + object: hanfPlantObjects.stage3 + }, + { + minutes: 60 * 4, + object: hanfPlantObjects.stage4 + } +] + +const minimumPlantDistance = 2; + +const maximumPlantDuration = 6 * 60 * 60 * 1000; // 6 Stunden / 360 Minuten / 21600 Sekunden / 21600000 Millisekunden +const timeToHarvestPlant = 4 * 60 * 60 * 1000; // 4 Stunden export default function hanfSystem(globalData: IGlobalData) { @@ -128,13 +150,13 @@ export default function hanfSystem(globalData: IGlobalData) { function isAbleToPlant() { var player = mp.players.local; - if (isNearPlant()) { + if (isNearPlant(minimumPlantDistance)) { return false; } - if (!isSurfaceAllowed()) { - return false; - } + //if (!isSurfaceAllowed()) { + // return false; + //} if (currentPlantingPreviewObject) { var objectPos = getPlantPreviewPosition(); @@ -144,7 +166,7 @@ export default function hanfSystem(globalData: IGlobalData) { } } - if (player.isSwimming() || player.isSwimmingUnderWater() || !player.isOnFoot()) { + if (player.isSwimming() || player.isSwimmingUnderWater() || !player.isOnFoot() || player.isSprinting() || player.isShooting()) { return false; } @@ -168,7 +190,19 @@ export default function hanfSystem(globalData: IGlobalData) { } KeyBinder.bind('e', _ => { - if (!currentlyPlanting || globalData.InChat) { + if (globalData.InChat) { + return; + } + + if (!currentlyPlanting) { + var nearPlant = isNearPlant(0.5); + + if (!nearPlant) { + return; + } + + mp.events.callRemote("CLIENT:Hanf_HarvestHanf", nearPlant.Id); + return; } @@ -183,52 +217,128 @@ export default function hanfSystem(globalData: IGlobalData) { if (currentPlantingPreviewObject) { currentPlantingPreviewObject.destroy(); + currentPlantingPreviewObject = null; } if (currentPlantingMarkerPreview) { currentPlantingMarkerPreview.destroy(); + currentPlantingMarkerPreview = null; } var position = getPlantPreviewPosition(); var realZ = mp.game.gameplay.getGroundZFor3dCoord(position.x, position.y, position.z + 2, 0, false); - mp.events.callRemote("CLIENT:Hanf_PlantHanf", position.x, position.z, realZ); + mp.events.callRemote("CLIENT:Hanf_PlantHanf", position.x, position.y, realZ); }); function getPlantPreviewPosition(): Vector3Mp { return mp.players.local.getOffsetFromInWorldCoords(0, 0.2, -1); } - function isNearPlant(): boolean { - var position = getPlantPreviewPosition(); - var nearPlant = false; - - Object.keys(hanfPlantObjects).forEach(k => { - var hash = hanfPlantObjects[k]; - var obj = mp.game.object.getClosestObjectOfType(position.x, position.y, position.z, minimumPlantDistance, hash, false, false, false); - if (obj && obj != currentPlantingPreviewObject.handle) { - nearPlant = true; - } - }); - - return nearPlant; + function getPlantText(plant: CannabisData) { + var time = Date.now() - Date.parse(plant.Time); + if (time > maximumPlantDuration) { + return ("~g~Hanf~n~~r~Verrottet"); + } + return (`~g~Hanf~n~Fortschritt: ${getPlantPercentage(plant).toFixed(2)}%`); } - let currentHanfData: Array = null; - let hanfDataIdToObjectMap: Map = null; + function getPlantPercentage(plant: CannabisData) { + var time = Date.now() - Date.parse(plant.Time); + return Math.min((time / timeToHarvestPlant) * 100, 100); + } - mp.events.add("SERVER:Hanf_UpdateHanfData", dataJson => { - var data: Array = >JSON.parse(dataJson) - if (currentHanfData == null) { - currentHanfData = data; + function isNearPlant(distance: number): CannabisData { + var pos = getPlantPreviewPosition(); + var nearPlants = currentHanfData.filter(h => + mp.game.gameplay.getDistanceBetweenCoords(pos.x, pos.y, pos.z, h.X, h.Y, h.Z, true) < distance); + + if (!nearPlants || nearPlants.length == 0) { + return null; } - var newPlants = data.filter(d => currentHanfData.filter(x => x.id === d.id).length == 0); - var removedPlants = currentHanfData.filter(d => data.filter(x => x.id === d.id).length == 0); - var existingPlants = data.filter(d => currentHanfData.filter(x => x.id === d.id).length == 1); + nearPlants = nearPlants.sort((a, b) => + Number(mp.game.gameplay.getDistanceBetweenCoords(pos.x, pos.y, pos.z, a.X, a.Y, a.Z, true) < + mp.game.gameplay.getDistanceBetweenCoords(pos.x, pos.y, pos.z, b.X, b.Y, b.Z, true))); + + return nearPlants[0]; + } + + let currentHanfData: Array = []; + let hanfDataIdToObjectMap: Map = new Map(); + let hanfDataIdToTextLabelMap: Map = new Map(); + + mp.events.add("SERVER:Hanf_UpdateHanfData", dataJson => { + mp.console.logInfo(dataJson); + var data: Array = >JSON.parse(dataJson) + + var newPlants = data.filter(d => currentHanfData.filter(x => x.Id === d.Id).length == 0); + var removedPlants = currentHanfData.filter(d => data.filter(x => x.Id === d.Id).length == 0); + var existingPlants = data.filter(d => currentHanfData.filter(x => x.Id === d.Id).length == 1); mp.gui.chat.push(`new: ${newPlants.length}, removed: ${removedPlants.length}, existing: ${existingPlants.length}`); + newPlants.forEach(plant => { + var model = getPlantModel(plant); + mp.gui.chat.push("new id: " + plant.Id + ", model = " + model); + var object = mp.objects.new(getPlantModel(plant), new mp.Vector3(plant.X, plant.Y, plant.Z)); + hanfDataIdToObjectMap.set(plant.Id, object); + + var textLabel = mp.labels.new(getPlantText(plant), new mp.Vector3(plant.X, plant.Y, plant.Z + 1), { + los: true, + drawDistance: 2 + }); + hanfDataIdToTextLabelMap.set(plant.Id, textLabel); + }); + + removedPlants.forEach(plant => { + //mp.gui.chat.push("removed id: " + plant.Id); + var object = hanfDataIdToObjectMap.get(plant.Id); + hanfDataIdToObjectMap.delete(plant.Id); + object.destroy(); + var textLabel = hanfDataIdToTextLabelMap.get(plant.Id); + textLabel.destroy(); + hanfDataIdToTextLabelMap.delete(plant.Id); + }); + + existingPlants.forEach(plant => { + //mp.gui.chat.push("existing plant: " + plant.Id + ", plant time = " + new Date(plant.Time).toLocaleTimeString() + ", current time = " + new Date().toLocaleTimeString()); + var object = hanfDataIdToObjectMap.get(plant.Id); + var model = getPlantModel(plant); + if (model != object.model) { + //mp.gui.chat.push("existing plant: " + plant.Id + ", changing model to = " + model); + object.destroy(); + var object = mp.objects.new(model, new mp.Vector3(plant.X, plant.Y, plant.Z)); + hanfDataIdToObjectMap.delete(plant.Id); + hanfDataIdToObjectMap.set(plant.Id, object); + } + + var textLabel = hanfDataIdToTextLabelMap.get(plant.Id); + textLabel.text = getPlantText(plant); + }); + currentHanfData = data; }); + + function getPlantModel(plant: CannabisData): number { + var diff = Date.now() - Date.parse(plant.Time); + var model = -1; + + var dbgTxt; + + if (diff <= 30 * 60 * 1000) { // 0 - 30 Minuten + model = hanfPlantObjects.stage1; + dbgTxt = "30 Minuten"; + } else if (diff <= 4 * 60 * 60 * 1000) { // 30 - 240 Minuten / 4 Stunden + model = hanfPlantObjects.stage3; + dbgTxt = "3 Stunden"; + } else { // Ausgewachsen / Ab 4 Stunden + model = hanfPlantObjects.stage4; + dbgTxt = "4 Stunden"; + } + + //mp.gui.chat.push("plant id = " + plant.Id + ", age = " + dbgTxt); + + return model; + } } \ No newline at end of file diff --git a/ReallifeGamemode.Client/game.ts b/ReallifeGamemode.Client/game.ts index c201e07d..bc89c7ed 100644 --- a/ReallifeGamemode.Client/game.ts +++ b/ReallifeGamemode.Client/game.ts @@ -168,5 +168,5 @@ export { EntityType, AccountData, VehicleData, - DoorState + DoorState, } \ No newline at end of file diff --git a/ReallifeGamemode.Client/global.d.ts b/ReallifeGamemode.Client/global.d.ts index 9a836413..d577d1a2 100644 --- a/ReallifeGamemode.Client/global.d.ts +++ b/ReallifeGamemode.Client/global.d.ts @@ -98,11 +98,11 @@ declare type RentcarProperty = { } declare type CannabisData = { - id: number; - x: number; - y: number; - z: number; - time: Date; + Id: number; + X: number; + Y: number; + Z: number; + Time: string; } declare type PlayerCharacterData = { diff --git a/ReallifeGamemode.Server/Commands/AdminCommands.cs b/ReallifeGamemode.Server/Commands/AdminCommands.cs index 3e12ecd9..8230c661 100644 --- a/ReallifeGamemode.Server/Commands/AdminCommands.cs +++ b/ReallifeGamemode.Server/Commands/AdminCommands.cs @@ -3391,6 +3391,19 @@ namespace ReallifeGamemode.Server.Commands ChatService.SendMessage(player, "~b~[ADMIN]~s~ Die Türen wurden erfolgreich neugeladen."); } + [Command("reloadhanf", "~m~Benutzung: ~s~/reloadhanf")] + public void CmdAdminReloadHanf(Player player) + { + if (!player.GetUser().IsAdmin(AdminLevel.HEADADMIN)) + { + ChatService.NotAuthorized(player); + return; + } + + HanfManager.UpdateHanfWorldData(new DatabaseContext()); + ChatService.SendMessage(player, "~b~[ADMIN]~s~ Die Hanfpflanzen wurden erfolgreich neugeladen."); + } + //[Command("house", "~m~Benutzung: ~s~/house [add / remove / price / type / reloadhouses]", GreedyArg = true)] //public void CmdAdminHouse(Player player, string option1 = null, string option2 = null) //{ diff --git a/ReallifeGamemode.Server/Events/Connect.cs b/ReallifeGamemode.Server/Events/Connect.cs index 1c43f5b7..2f1ce662 100644 --- a/ReallifeGamemode.Server/Events/Connect.cs +++ b/ReallifeGamemode.Server/Events/Connect.cs @@ -88,8 +88,6 @@ namespace ReallifeGamemode.Server.Events NAPI.World.RequestIpl("ferris_finale_Anim"); // Riesenrad NAPI.World.RequestIpl("Carwash_with_spinners"); // Carwash - HanfManager.UpdateHanfForPlayer(player); - TimeSpan currentTime = TimeManager.CurrentTime; bool disableLightMode = currentTime > LightModeTimeFrom && currentTime < LightModeTimeTo; diff --git a/ReallifeGamemode.Server/Events/Login.cs b/ReallifeGamemode.Server/Events/Login.cs index 328525b3..a7c1c4d5 100644 --- a/ReallifeGamemode.Server/Events/Login.cs +++ b/ReallifeGamemode.Server/Events/Login.cs @@ -115,6 +115,8 @@ namespace ReallifeGamemode.Server.Events ChatService.BroadcastGroup(msg, user.Group); } + HanfManager.UpdateHanfForPlayer(player); + string message = string.Empty; if (GlobalHelper.CustomJoinMessages.ContainsKey(player.SocialClubName)) diff --git a/ReallifeGamemode.Server/Events/Register.cs b/ReallifeGamemode.Server/Events/Register.cs index c67bd0b8..af1111e7 100644 --- a/ReallifeGamemode.Server/Events/Register.cs +++ b/ReallifeGamemode.Server/Events/Register.cs @@ -7,6 +7,7 @@ using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Util; using System; using ReallifeGamemode.Database.Entities.Logs; +using ReallifeGamemode.Server.Managers; /** * @overview Life of German Reallife - Event Register (Register.cs) @@ -29,7 +30,7 @@ namespace ReallifeGamemode.Server.Events player.TriggerEvent("SERVER:Login_Error", "Das Passwort muss aus mindestens 6 Zeichen bestehen."); return; } - if (dbContext.Users.Where(u => u.SocialClubName == player.SocialClubName).Count()!= 0) + if (dbContext.Users.Where(u => u.SocialClubName == player.SocialClubName).Count() != 0) { player.TriggerEvent("SERVER:Login_Error", "Es ist schon ein Konto mit dieser Socialclub-ID registriert."); return; @@ -79,10 +80,12 @@ namespace ReallifeGamemode.Server.Events currentPlayerCreatorDimension++; NAPI.Data.SetWorldData("playerCreatorDimension", currentPlayerCreatorDimension); player.Dimension = NAPI.Data.GetWorldData("playerCreatorDimension"); - player.TriggerEvent("toggleCreator",false); + player.TriggerEvent("toggleCreator", false); player.SafeTeleport(new Vector3(402.8664, -996.4108, -99.00027)); //player.Position = new Vector3(user.PositionX, user.PositionY, user.PositionZ); + HanfManager.UpdateHanfForPlayer(player); + if (GlobalHelper.CountdownUntil > DateTime.Now) { player.TriggerEvent("countdown", (GlobalHelper.CountdownUntil - DateTime.Now).TotalSeconds, GlobalHelper.CountdownText); diff --git a/ReallifeGamemode.Server/Managers/HanfManager.cs b/ReallifeGamemode.Server/Managers/HanfManager.cs index ff74bfa5..fa1ffd2e 100644 --- a/ReallifeGamemode.Server/Managers/HanfManager.cs +++ b/ReallifeGamemode.Server/Managers/HanfManager.cs @@ -53,11 +53,23 @@ namespace ReallifeGamemode.Server.Managers /// private const string PLAYER_CURRENTLY_PLANTING_DATA_KEY = "isPlantingCannabis"; + /// + /// Ab welcher Zeit Pflanzen verwelken + /// + private static readonly TimeSpan MAX_PLANT_TIME = TimeSpan.FromHours(6); + + private static readonly TimeSpan MIN_PLANT_TIME_TO_HARVEST = TimeSpan.FromHours(4); + /// /// Timer der den Status des Verarbeiters zurücksetzt /// private static Timer _manufacturerDoneTimer = new Timer(TimeSpan.FromSeconds(10).TotalMilliseconds); + /// + /// Zufallsgenerator für weibliche Pflanze und erhaltenes Cannabis + /// + private static Random _random = new Random(); + private static List _currentCannabisData = new List(); static HanfManager() @@ -99,8 +111,13 @@ namespace ReallifeGamemode.Server.Managers private static void OnSeedBuyRangeColShapeEnter(ColShape colShape, Player player) { + if (!player.IsLoggedIn()) + { + return; + } + var user = player.GetUser(); - if (user.Faction.StateOwned) + if (user?.Faction?.StateOwned == true) { return; } @@ -245,6 +262,93 @@ namespace ReallifeGamemode.Server.Managers player.SendNotification($"Du hast {amount} Hanfsamen gekauft"); } + [RemoteEvent("CLIENT:Hanf_HarvestHanf")] + public void HanfManagerHarvestHanf(Player player, long hanfId) + { + if (!player.IsLoggedIn()) + { + return; + } + + using var dbContext = new DatabaseContext(); + + User user = player.GetUser(dbContext); + CannabisPlant plant = dbContext.CannabisPlants.Find(hanfId); + if (plant == null) + { + logger.LogError("Player {0} tried to harvest cannabis plant {1} but it was not found in database", player.Name, hanfId); + } + + if (user.Faction?.StateOwned == true && !(user.FactionId == 3 && player.IsDuty())) + { + player.SendNotification("~r~Du kannst kein Hanf ernten"); + return; + } + + if (plant.Harvested) + { + return; + } + + plant.Harvested = true; + + if (user.FactionId != 3) // Zivi / Gangmember erntet ab + { + bool isPlantRotten = DateTime.Now - plant.PlantDate > MAX_PLANT_TIME; + if (isPlantRotten) + { + player.SendNotification("~r~Die Pflanze ist leider verrottet"); + } + else + { + bool isPlantReadyToHarvest = DateTime.Now - plant.PlantDate > MIN_PLANT_TIME_TO_HARVEST; + if (!isPlantReadyToHarvest) // Wenn die Pflanze noch nicht ausgewachsen ist + { + bool getSeedBack = _random.Next(0, 2) == 1; // 50% Chance + if(getSeedBack) + { + IItem cannabisSeedItem = InventoryManager.GetItem(); + InventoryManager.AddItemToInventory(player, cannabisSeedItem.Id, 1); + player.SendNotification("~g~Du konntest den Samen wieder ausgraben"); + } + else + { + player.SendNotification("~r~Du konntest den Samen leider nicht wieder ausgraben"); + } + } + else + { + bool isFemalePlant = _random.Next(0, 10) + 1 <= 8; // 80% Chance dass es eine weibliche Pflanze ist + if (isFemalePlant) + { + int cannabisAmount = _random.Next(4, 10) + 1; // zwischen 5 und 10g Cannabis + IItem cannabisItem = InventoryManager.GetItem(); + var newWeight = cannabisAmount * cannabisItem.Gewicht; + if (!InventoryManager.CanPlayerHoldMoreWeight(player, newWeight)) + { + int restWeightPlayerCanHold = InventoryManager.MAX_USER_INVENTORY - InventoryManager.GetUserInventoryWeight(player); + cannabisAmount = restWeightPlayerCanHold / cannabisItem.Gewicht; + player.SendNotification("~o~Warnung:~s~ Du hast nicht das komplette Cannabis der Pflanze erhalten, da dein Inventar voll ist"); + } + player.SendNotification("~g~" + cannabisAmount + "g Cannabis geerntet"); + InventoryManager.AddItemToInventory(player, cannabisItem.Id, cannabisAmount); + } + else + { + player.SendNotification("~r~Du hast die falschen Samen eingesät und keinen Ertrag aus dieser Pflanze erhalten"); + } + } + } + } + else // FIB erntet ab + { + + } + + dbContext.SaveChanges(); + UpdateHanfWorldData(dbContext); + } + internal static void BuildJointsFromCannabis(Player player) { if (player.HasAnimation(_manufacturerAnim) || _manufacturerCurrentlyUsed) From 211269d03a526a6f92739511e41120e0fbf07f3a Mon Sep 17 00:00:00 2001 From: hydrant Date: Wed, 26 May 2021 21:01:36 +0200 Subject: [PATCH 08/10] wt bruch micha bekommt keine gitlab rechte mehr --- ReallifeGamemode.Server/Events/EnterVehicle.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ReallifeGamemode.Server/Events/EnterVehicle.cs b/ReallifeGamemode.Server/Events/EnterVehicle.cs index 6702336d..a6e48c1f 100644 --- a/ReallifeGamemode.Server/Events/EnterVehicle.cs +++ b/ReallifeGamemode.Server/Events/EnterVehicle.cs @@ -23,7 +23,7 @@ namespace ReallifeGamemode.Server.Events if (vehicle.HasMarkerBehind()) vehicle.RemoveMarkerBehind(); - if(vehicle != null && !string.IsNullOrEmpty(client.Name)) + if (vehicle != null && !string.IsNullOrEmpty(client.Name)) { if (!VehicleManager.lastDriversInVehicle.ContainsKey(vehicle)) { @@ -39,15 +39,12 @@ namespace ReallifeGamemode.Server.Events if ((vehicle.Class != 16 && vehicle.Class != 15) && u.DriverLicenseVehicle == false) { client.SendNotification("Du besitzt keinen Führerschein!"); - return; } - - if ((vehicle.Class == 16 && u.FlyingLicensePlane == false) || (vehicle.Class == 15 && u.FlyingLicensePlane == false)) //planes = 16 helicopter = 15 + else if ((vehicle.Class == 16 && u.FlyingLicensePlane == false) || (vehicle.Class == 15 && u.FlyingLicensePlane == false)) //planes = 16 helicopter = 15 { client.SendNotification("Du besitzt keinen Flugschein!"); - return; } - + } From 60f55e0eeb0105c048a556b32953b4ab014f80ab Mon Sep 17 00:00:00 2001 From: hydrant Date: Thu, 27 May 2021 21:06:20 +0200 Subject: [PATCH 09/10] hanf vielleicht fertig --- .../Interaction/factioninteraction.ts | 31 +- ReallifeGamemode.Client/drugs/hanf.ts | 133 +- ReallifeGamemode.Client/util/animationSync.ts | 14 +- .../util/attachmentMngr.ts | 7 +- ReallifeGamemode.Database/Entities/User.cs | 4 + ...901_AddUserCannabisSeedBuyData.Designer.cs | 2229 +++++++++++++++++ ...210527144901_AddUserCannabisSeedBuyData.cs | 33 + .../DatabaseContextModelSnapshot.cs | 6 + ReallifeGamemode.Server/BaseScript.cs | 2 +- ReallifeGamemode.Server/Events/Death.cs | 8 + ReallifeGamemode.Server/Events/Disconnect.cs | 8 + ReallifeGamemode.Server/Events/Key.cs | 92 +- ReallifeGamemode.Server/Events/Vehicle.cs | 6 + .../Inventory/Interfaces/IIllegalItem.cs | 11 + .../Inventory/Items/Cannabis.cs | 6 +- .../Inventory/Items/CannabisSeeds.cs | 8 +- .../Inventory/Items/Joint.cs | 29 +- .../Managers/HanfManager.cs | 253 +- .../Managers/InteractionManager.cs | 145 ++ .../Managers/InventoryManager.cs | 27 +- 20 files changed, 2996 insertions(+), 56 deletions(-) create mode 100644 ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.Designer.cs create mode 100644 ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.cs create mode 100644 ReallifeGamemode.Server/Inventory/Interfaces/IIllegalItem.cs diff --git a/ReallifeGamemode.Client/Interaction/factioninteraction.ts b/ReallifeGamemode.Client/Interaction/factioninteraction.ts index 1b75b5ed..506e47a1 100644 --- a/ReallifeGamemode.Client/Interaction/factioninteraction.ts +++ b/ReallifeGamemode.Client/Interaction/factioninteraction.ts @@ -31,7 +31,7 @@ export default function factionInteraction(globalData: IGlobalData) { var ticketName: string; var pointsName: string; - var factionInteractionMenu; + var factionInteractionMenu: NativeUI.Menu; var healTaskMenuMedic; var reviveTaskMenuMedic; var insDate; @@ -42,7 +42,10 @@ export default function factionInteraction(globalData: IGlobalData) { //LSPD let ticketTaskMenuLSPD; let pointsTaskMenuLSPD; - let wantedsMenuLSPD + let wantedsMenuLSPD; + + let friskUserMenuItem: NativeUI.UIMenuItem; + let friskVehicleMenuItem: NativeUI.UIMenuItem; if (userFactionId == 1 || userFactionId == 3) { if (isDuty) { mp.gui.chat.activate(false); @@ -59,6 +62,12 @@ export default function factionInteraction(globalData: IGlobalData) { wantedsMenuLSPD = new UIMenuItem("Verbrecher Liste"); factionInteractionMenu.AddItem(wantedsMenuLSPD); + friskUserMenuItem = new UIMenuItem("Spieler durchsuchen", "Einen Spieler auf illegale Gegenstände durchsuchen."); + factionInteractionMenu.AddItem(friskUserMenuItem); + + friskVehicleMenuItem = new UIMenuItem("Fahrzeug durchsuchen", "Das nächste Fahrzeug auf illegale Gegenstände durchsuchen.") + factionInteractionMenu.AddItem(friskVehicleMenuItem); + /*TaskMenuLSPD = new UIMenuItem(""); TaskMenuLSPD.SetRightLabel(""); factionInteractionMenu.AddItem(TaskMenuLSPD);*/ //weiteres @@ -107,6 +116,20 @@ export default function factionInteraction(globalData: IGlobalData) { globalData.InMenu = false; mp.events.callRemote("CLIENT:wantedlist"); break; + + case friskUserMenuItem: + factionInteractionMenu.Visible = false; + var input = new InputHelper("Welchem Spieler möchtest du Strafpunkte geben (Name / ID)?", globalData); + input.show(); + input.getValue(name => { + mp.events.callRemote("CLIENT:InteractionMenu_LSPD_FriskUser", name); + globalData.InMenu = false; + }); + break; + + case friskVehicleMenuItem: + factionInteractionMenu.Close(); + mp.events.callRemote("CLIENT:InteractionMenu_LSPD_FriskVehicle"); } }); @@ -273,7 +296,7 @@ export default function factionInteraction(globalData: IGlobalData) { mp.gui.chat.activate(true); globalData.InMenu = false; mp.events.callRemote("updateMedicTask", 1, activeTask.Victim, true); - mp.events.call("destroyMedicTaskCheckpoint"); + mp.events.call("destroyMedicTaskCheckpoint"); break; } @@ -357,7 +380,7 @@ export default function factionInteraction(globalData: IGlobalData) { } aTask1.SetRightLabel(mp.game.gameplay.getDistanceBetweenCoords(player.position.x, player.position.y, player.position.z, tasks[i].Position.x, tasks[i].Position.y, tasks[i].Position.z, true).toFixed(2).toString() + " ~g~m"); - healTaskMenuMedic.AddItem(aTask1); + healTaskMenuMedic.AddItem(aTask1); } let backItem1 = new UIMenuItem("Zur\u00fcck", "Zur\u00fcck zur Fraktionsinteraktion."); diff --git a/ReallifeGamemode.Client/drugs/hanf.ts b/ReallifeGamemode.Client/drugs/hanf.ts index 3dd44235..4c5339c1 100644 --- a/ReallifeGamemode.Client/drugs/hanf.ts +++ b/ReallifeGamemode.Client/drugs/hanf.ts @@ -5,7 +5,7 @@ import { getAnimFromId } from "../util/animationSync"; import { getCreatedPedByName } from "../Ped/PedCreator"; import KeyBinder from 'ragemp-better-bindings'; -const hanfPlantObjects = { +export const hanfPlantObjects = { stage1: mp.game.joaat('bkr_prop_weed_bud_pruned_01a'), stage2: mp.game.joaat('bkr_prop_weed_bud_01b'), stage3: mp.game.joaat('prop_weed_02'), @@ -43,7 +43,7 @@ export default function hanfSystem(globalData: IGlobalData) { let currentlyPlanting: boolean = false; let lastPlantingState = true; - mp.events.add("SERVER:Hanf_BuySeed", price => { + mp.events.add("SERVER:Hanf_BuySeed", (maxSeedsToBuy, price) => { if (globalData.InMenu || globalData.InChat) { return; } @@ -54,7 +54,7 @@ export default function hanfSystem(globalData: IGlobalData) { var seedsToBuy = 0; - var countItems = [...Array(50).keys()].map(x => x + 1); + var countItems = [...Array(maxSeedsToBuy).keys()].map(x => x + 1); var soloPriceItem = createMenuItem("Einzelpreis", "Preis pro Samen", item => { item.SetRightLabel("$" + moneyformat(price)); @@ -93,6 +93,56 @@ export default function hanfSystem(globalData: IGlobalData) { menu.Open(); }); + mp.events.add("SERVER:Hanf_SellCannabisMenu", (maxCannabisToSell, price) => { + if (globalData.InMenu || globalData.InChat) { + return; + } + + globalData.InMenu = true; + + var menu = new Menu("Cannabis verkaufen", "Verkaufe dein Cannabis", new Point(50, 50)); + + var cannabisToSell = 0; + + var countItems = [...Array(maxCannabisToSell).keys()].map(x => x + 1); + + var soloPriceItem = createMenuItem("Einzelpreis", "Preis pro Hanfblüte", item => { + item.SetRightLabel("$" + moneyformat(price)); + }); + menu.AddItem(soloPriceItem); + + var countItem = new UIMenuListItem("Anzahl", "Wähle die Anzahl der Blüten aus", new ItemsCollection(countItems), 0); + menu.AddItem(countItem); + + var buyItem = new UIMenuItem("Verkaufen", "Verkaufe dein Cannabis"); + buyItem.BackColor = new Color(0, 100, 0); + buyItem.HighlightedBackColor = new Color(0, 150, 0); + menu.AddItem(buyItem); + + var completePriceItem = new UIMenuItem("Gesamtpreis", "Preis für alle Blüten"); + menu.AddItem(completePriceItem); + + menu.ListChange.on((item, index) => { + if (item === countItem) { + cannabisToSell = Number(countItem.SelectedValue); + completePriceItem.SetRightLabel("$" + moneyformat(cannabisToSell * price)); + } + }); + + menu.ItemSelect.on((item, index) => { + if (item === buyItem) { + mp.events.callRemote("CLIENT:Hanf_SellCannabis", cannabisToSell); + menu.Close(); + } + }); + + menu.MenuClose.on(() => { + globalData.InMenu = false; + }); + + menu.Open(); + }); + mp.events.add("SERVER:Hanf_PlayManufacturerAnim", animId => { var anim = getAnimFromId(animId); var npc = getCreatedPedByName("hanf_verarbeiter_typ"); @@ -154,9 +204,9 @@ export default function hanfSystem(globalData: IGlobalData) { return false; } - //if (!isSurfaceAllowed()) { - // return false; - //} + if (!isSurfaceAllowed()) { + return false; + } if (currentPlantingPreviewObject) { var objectPos = getPlantPreviewPosition(); @@ -177,14 +227,29 @@ export default function hanfSystem(globalData: IGlobalData) { const GET_RAYCAST_RESULT_NATIVE = "0x65287525D951F6BE"; function isSurfaceAllowed() { + return true; const player = mp.players.local; - var position = player.position; - var raycast = mp.game.invoke(RAYCAST_POINT_TO_POINT_NATIVE, position.x, position.y, position.z + 5, position.x, position.y, position.z - 5, -1, undefined, 0); + var position = getPlantPreviewPosition(); + var raycast = mp.game.invoke(RAYCAST_POINT_TO_POINT_NATIVE, position.x, position.y, position.z + 5, position.x, position.y, position.z - 5, 1, 0, 7); mp.gui.chat.push("raycast = " + raycast); - var hit: boolean, coord: Vector3Mp, surfaceNormal: Vector3Mp, materialHash: number, entityHit: EntityMp; - var raycastResult = mp.game.invoke(GET_RAYCAST_RESULT_NATIVE, raycast, hit, coord, surfaceNormal, materialHash, entityHit); + var resultObj = { + hit: [false], + coord: [new mp.Vector3()], + surface: [new mp.Vector3()], + material: [0], + entityHit: [null] + }; - mp.gui.chat.push("result: " + raycastResult + ", hit = " + hit + ", test = " + materialHash); + var raycastResult = -1; + var retries = 10; + + do { + raycastResult = mp.game.invoke(GET_RAYCAST_RESULT_NATIVE, raycast, resultObj.hit, resultObj.coord, resultObj.surface, resultObj.material, resultObj.entityHit); + retries--; + } while (raycastResult != 0 && raycastResult != 2 && retries > 0); + + + mp.gui.chat.push("result: " + raycastResult + ", result = " + JSON.stringify(resultObj)); return true; } @@ -270,17 +335,15 @@ export default function hanfSystem(globalData: IGlobalData) { mp.events.add("SERVER:Hanf_UpdateHanfData", dataJson => { mp.console.logInfo(dataJson); + var data: Array = >JSON.parse(dataJson) var newPlants = data.filter(d => currentHanfData.filter(x => x.Id === d.Id).length == 0); var removedPlants = currentHanfData.filter(d => data.filter(x => x.Id === d.Id).length == 0); var existingPlants = data.filter(d => currentHanfData.filter(x => x.Id === d.Id).length == 1); - mp.gui.chat.push(`new: ${newPlants.length}, removed: ${removedPlants.length}, existing: ${existingPlants.length}`); - newPlants.forEach(plant => { var model = getPlantModel(plant); - mp.gui.chat.push("new id: " + plant.Id + ", model = " + model); var object = mp.objects.new(getPlantModel(plant), new mp.Vector3(plant.X, plant.Y, plant.Z)); hanfDataIdToObjectMap.set(plant.Id, object); @@ -292,7 +355,6 @@ export default function hanfSystem(globalData: IGlobalData) { }); removedPlants.forEach(plant => { - //mp.gui.chat.push("removed id: " + plant.Id); var object = hanfDataIdToObjectMap.get(plant.Id); hanfDataIdToObjectMap.delete(plant.Id); object.destroy(); @@ -302,11 +364,9 @@ export default function hanfSystem(globalData: IGlobalData) { }); existingPlants.forEach(plant => { - //mp.gui.chat.push("existing plant: " + plant.Id + ", plant time = " + new Date(plant.Time).toLocaleTimeString() + ", current time = " + new Date().toLocaleTimeString()); var object = hanfDataIdToObjectMap.get(plant.Id); var model = getPlantModel(plant); if (model != object.model) { - //mp.gui.chat.push("existing plant: " + plant.Id + ", changing model to = " + model); object.destroy(); var object = mp.objects.new(model, new mp.Vector3(plant.X, plant.Y, plant.Z)); hanfDataIdToObjectMap.delete(plant.Id); @@ -341,4 +401,43 @@ export default function hanfSystem(globalData: IGlobalData) { return model; } + + mp.events.addProc("SERVER:Hanf_GetModelToGivePlayer", id => { + var plant = currentHanfData.filter(x => x.Id == id)[0]; + var model = getPlantModel(plant); + if (model == hanfPlantObjects.stage1) { + return 1; + } else if (model == hanfPlantObjects.stage3) { + return 2; + } else if (model == hanfPlantObjects.stage4) { + return 3; + } + }); + + //var rotationTestObject: ObjectMp = null; + //var a1: number, a2: number, a3: number, a4: number, a5: number, a6: number; + //mp.events.add(RageEnums.EventKey.PLAYER_COMMAND, (f) => { + // var args = f.split(' '); + // if (args[0] != "a") { + // return; + // } + + // a1 = parseFloat(args[1] || "0"); + // a2 = parseFloat(args[2] || "0"); + // a3 = parseFloat(args[3] || "0"); + // a4 = parseFloat(args[4] || "0"); + // a5 = parseFloat(args[5] || "0"); + // a6 = parseFloat(args[6] || "0"); + + // mp.gui.chat.push(`a1: ${a1.toFixed(2)}, a2: ${a2.toFixed(2)}, a3: ${a3.toFixed(2)}, a4: ${a4.toFixed(2)}, a5: ${a5.toFixed(2)}, a6: ${a6.toFixed(2)},`) + + // if (rotationTestObject != null) { + // rotationTestObject.attachTo(Number(mp.players.local.handle), mp.players.local.getBoneIndex(57005), a1, a2, a3, a4, a5, a6, true, false, false, false, 0, true); + // return; + // } + + // rotationTestObject = mp.objects.new(mp.game.joaat("prop_cs_trowel"), mp.players.local.position, { + // alpha: 255 + // }); + //}); } \ No newline at end of file diff --git a/ReallifeGamemode.Client/util/animationSync.ts b/ReallifeGamemode.Client/util/animationSync.ts index e0842af2..02f51191 100644 --- a/ReallifeGamemode.Client/util/animationSync.ts +++ b/ReallifeGamemode.Client/util/animationSync.ts @@ -4,7 +4,7 @@ const animationSyncData = { animations: [], - register: function (name, animDict, animName, duration, loop, flag, endless) { + register: function (name, animDict, animName, duration, loop, flag, endless, eventAfter: string = null) { let id = mp.game.joaat(name); if (!this.animations.hasOwnProperty(id)) { @@ -17,7 +17,8 @@ const animationSyncData = duration: duration, loop: loop, flag: flag, - endless: endless + endless: endless, + eventAfter: eventAfter }; } else { mp.game.graphics.notify("Animation Sync Error: ~r~Duplicate Entry"); @@ -50,6 +51,10 @@ export default function animationSync() { animationSyncData.register("hup", "mp_am_hold_up", "handsup_base", -1, true, 50, true); animationSyncData.register("carryBox", "anim@heists@box_carry@", "idle", -1, true, 50, true); animationSyncData.register("manufacturJoint", "anim@mp_snowball", "pickup_snowball", 1000 * 10, false, 1, false); + //animationSyncData.register("harvestPlantEnter", "amb@world_human_gardener_plant@female@enter", "enter_female", 1000 * 3.5, false, 1, false); + animationSyncData.register("harvestPlant", "amb@world_human_gardener_plant@male@base", "base", 1000 * 10, false, 1, false, "Hanf_FinishDiggingAnimation"); + //animationSyncData.register("harvestPlantExit", "amb@world_human_gardener_plant@female@exit", "exit_female", 1000 * 3.5, false, 1, false, "Hanf_FinishDiggingAnimation"); + animationSyncData.register("jointUse", "amb@world_human_smoking_pot@male@base", "base", 1000 * 10, false, 1, false); }); const animationBreakMessage = [ @@ -115,7 +120,7 @@ export default function animationSync() { let animData = animationSyncData.animations[index]; - let { id, name, animDict, animName, duration, loop, flag, endless } = animData; + let { id, name, animDict, animName, duration, loop, flag, endless, eventAfter } = animData; loadAnimDict(animDict, function () { mp.players.exists(entity) && 0 !== entity.handle && entity.taskPlayAnim(animDict, animName, 1, 0, duration, parseInt(flag), 0, !1, !1, !1) @@ -130,6 +135,9 @@ export default function animationSync() { let a = setTimeout(function () { clearTimeout(a); mp.events.callRemote("CLIENT:ClearAnimationData", true); + if (eventAfter) { + mp.events.callRemote("CLIENT:" + eventAfter); + } }, duration); } } diff --git a/ReallifeGamemode.Client/util/attachmentMngr.ts b/ReallifeGamemode.Client/util/attachmentMngr.ts index d46da114..82d32b94 100644 --- a/ReallifeGamemode.Client/util/attachmentMngr.ts +++ b/ReallifeGamemode.Client/util/attachmentMngr.ts @@ -1,4 +1,5 @@ import { IGame, IEntity } from "../game"; +import { hanfPlantObjects } from "../drugs/hanf"; export default function attachmentManager(game: IGame) { mp.events.add("SERVER:LoadAttachments", () => { @@ -9,6 +10,10 @@ export default function attachmentManager(game: IGame) { attachmentMngr.register("weapondeal1", "ex_office_swag_guns02", "chassis_dummy", new mp.Vector3(0, 0.8, 0), new mp.Vector3(0, 0, 0)); attachmentMngr.register("weapondeal2", "w_sg_pumpshotgun", "chassis_dummy", new mp.Vector3(0.4, 1.6, 0.62), new mp.Vector3(90, 0, 180)); attachmentMngr.register("handcuffs", "p_cs_cuffs_02_s", 28422, new mp.Vector3(-0.05, 0, 0), new mp.Vector3(90, 90, 0)); + attachmentMngr.register("shovel", "prop_cs_trowel", 28422, new mp.Vector3(0.1, 0.0, 0.0), new mp.Vector3(120, 70, 0)); + attachmentMngr.register("CannabisPlantInHand1", hanfPlantObjects.stage1, 28422, new mp.Vector3(), new mp.Vector3()); + attachmentMngr.register("CannabisPlantInHand2", hanfPlantObjects.stage3, 28422, new mp.Vector3(), new mp.Vector3()); + attachmentMngr.register("CannabisPlantInHand3", hanfPlantObjects.stage4, 28422, new mp.Vector3(), new mp.Vector3()); }); const attachmentMngr = @@ -140,7 +145,7 @@ export default function attachmentManager(game: IGame) { targetEntity, bone, offset.x, offset.y, offset.z, rotation.x, rotation.y, rotation.z, - false, false, false, false, 2, true + true, false, false, false, 0, true ); } diff --git a/ReallifeGamemode.Database/Entities/User.cs b/ReallifeGamemode.Database/Entities/User.cs index 197224eb..eec30f5b 100644 --- a/ReallifeGamemode.Database/Entities/User.cs +++ b/ReallifeGamemode.Database/Entities/User.cs @@ -129,6 +129,10 @@ namespace ReallifeGamemode.Database.Entities public bool FreeSurgery { get; set; } = true; + public DateTime? LastTimeBoughtCannabisSeeds { get; set; } + + public int CannabisSeedsBoughtToday { get; set; } + [NotMapped] public Player Player { diff --git a/ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.Designer.cs b/ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.Designer.cs new file mode 100644 index 00000000..6f55b056 --- /dev/null +++ b/ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.Designer.cs @@ -0,0 +1,2229 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ReallifeGamemode.Database.Models; + +namespace ReallifeGamemode.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20210527144901_AddUserCannabisSeedBuyData")] + partial class AddUserCannabisSeedBuyData + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.3") + .HasAnnotation("PropertyAccessMode", PropertyAccessMode.PreferFieldDuringConstruction) + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ATM", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("Faulty") + .HasColumnType("tinyint(1)"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("ATMs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Ban", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Applied") + .HasColumnType("int"); + + b.Property("BannedBy") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Reason") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UntilDateTime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Bans"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusRoute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("BusRoutes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusRoutePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BusRouteId") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("BusRouteId"); + + b.ToTable("BusRoutesPoints"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusinessBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BusinessId") + .IsUnique(); + + b.ToTable("BusinessBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusinessData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("BusinessData"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Harvested") + .HasColumnType("tinyint(1)"); + + b.Property("PlantDate") + .HasColumnType("datetime(6)"); + + b.Property("PlantedById") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("PlantedById"); + + b.ToTable("CannabisPlants"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ageing") + .HasColumnType("tinyint unsigned"); + + b.Property("AgeingOpacity") + .HasColumnType("float"); + + b.Property("BeardColor") + .HasColumnType("tinyint unsigned"); + + b.Property("Blemishes") + .HasColumnType("tinyint unsigned"); + + b.Property("BlemishesOpacity") + .HasColumnType("float"); + + b.Property("Blush") + .HasColumnType("tinyint unsigned"); + + b.Property("BlushColor") + .HasColumnType("tinyint unsigned"); + + b.Property("BlushOpacity") + .HasColumnType("float"); + + b.Property("BrowDepth") + .HasColumnType("float"); + + b.Property("BrowHeight") + .HasColumnType("float"); + + b.Property("CheekDepth") + .HasColumnType("float"); + + b.Property("CheekboneHeight") + .HasColumnType("float"); + + b.Property("CheekboneWidth") + .HasColumnType("float"); + + b.Property("ChestHair") + .HasColumnType("tinyint unsigned"); + + b.Property("ChestHairColor") + .HasColumnType("tinyint unsigned"); + + b.Property("ChestHairOpacity") + .HasColumnType("float"); + + b.Property("ChinDepth") + .HasColumnType("float"); + + b.Property("ChinHeight") + .HasColumnType("float"); + + b.Property("ChinIndent") + .HasColumnType("float"); + + b.Property("ChinWidth") + .HasColumnType("float"); + + b.Property("Complexion") + .HasColumnType("tinyint unsigned"); + + b.Property("ComplexionOpacity") + .HasColumnType("float"); + + b.Property("EyeColor") + .HasColumnType("tinyint unsigned"); + + b.Property("EyeSize") + .HasColumnType("float"); + + b.Property("EyebrowColor") + .HasColumnType("tinyint unsigned"); + + b.Property("Eyebrows") + .HasColumnType("tinyint unsigned"); + + b.Property("EyebrowsOpacity") + .HasColumnType("float"); + + b.Property("FacialHair") + .HasColumnType("tinyint unsigned"); + + b.Property("FacialHairOpacity") + .HasColumnType("float"); + + b.Property("Father") + .HasColumnType("tinyint unsigned"); + + b.Property("Freckles") + .HasColumnType("tinyint unsigned"); + + b.Property("FrecklesOpacity") + .HasColumnType("float"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("Hair") + .HasColumnType("tinyint unsigned"); + + b.Property("HairColor") + .HasColumnType("tinyint unsigned"); + + b.Property("HairHighlightColor") + .HasColumnType("tinyint unsigned"); + + b.Property("JawShape") + .HasColumnType("float"); + + b.Property("JawWidth") + .HasColumnType("float"); + + b.Property("LipThickness") + .HasColumnType("float"); + + b.Property("Lipstick") + .HasColumnType("tinyint unsigned"); + + b.Property("LipstickColor") + .HasColumnType("tinyint unsigned"); + + b.Property("LipstickOpacity") + .HasColumnType("float"); + + b.Property("Makeup") + .HasColumnType("tinyint unsigned"); + + b.Property("MakeupOpacity") + .HasColumnType("float"); + + b.Property("Mother") + .HasColumnType("tinyint unsigned"); + + b.Property("NeckWidth") + .HasColumnType("float"); + + b.Property("NoseBottomHeight") + .HasColumnType("float"); + + b.Property("NoseBridgeDepth") + .HasColumnType("float"); + + b.Property("NoseBroken") + .HasColumnType("float"); + + b.Property("NoseTipHeight") + .HasColumnType("float"); + + b.Property("NoseTipLength") + .HasColumnType("float"); + + b.Property("NoseWidth") + .HasColumnType("float"); + + b.Property("Similarity") + .HasColumnType("float"); + + b.Property("SkinSimilarity") + .HasColumnType("float"); + + b.Property("SunDamage") + .HasColumnType("tinyint unsigned"); + + b.Property("SunDamageOpacity") + .HasColumnType("float"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Characters"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CharacterCloth", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClothId") + .HasColumnType("int"); + + b.Property("Duty") + .HasColumnType("tinyint(1)"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("SlotType") + .HasColumnType("tinyint unsigned"); + + b.Property("Texture") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("CharacterClothes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ClothCombination", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("Top") + .HasColumnType("int"); + + b.Property("Torso") + .HasColumnType("int"); + + b.Property("Undershirt") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ClothCombinations"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Door", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AlwaysOpen") + .HasColumnType("tinyint(1)"); + + b.Property("Category") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Locked") + .HasColumnType("tinyint(1)"); + + b.Property("Model") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Radius") + .HasColumnType("float"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("Doors"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.DutyCloth", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClothId") + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("SlotId") + .HasColumnType("int"); + + b.Property("SlotType") + .HasColumnType("tinyint unsigned"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("DutyClothes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Faction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("GangOwned") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("StateOwned") + .HasColumnType("tinyint(1)"); + + b.Property("WeaponDealTime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BankAccountId"); + + b.ToTable("Factions"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("Bic") + .HasColumnType("varchar(12) CHARACTER SET utf8mb4") + .HasMaxLength(12); + + b.Property("Iban") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("FactionBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionRank", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("RankName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("FactionRanks"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionWeapon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ammount") + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("SlotID") + .HasColumnType("int"); + + b.Property("WeaponModel") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("FactionId"); + + b.ToTable("FactionWeapons"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GotoPoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Description") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("GotoPoints"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BankAccountId"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GroupBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Balance") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("GroupBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.House", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("CanRentIn") + .HasColumnType("tinyint(1)"); + + b.Property("LastRentSetTime") + .HasColumnType("datetime(6)"); + + b.Property("OwnerId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("RentalFee") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("BankAccountId"); + + b.HasIndex("OwnerId"); + + b.ToTable("Houses"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.HouseBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Balance") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("HouseBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.HouseRental", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("HouseId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("HouseId"); + + b.HasIndex("UserId"); + + b.ToTable("HouseRentals"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Interior", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EnterPositionStr") + .HasColumnName("EnterPosition") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ExitPositionStr") + .HasColumnName("ExitPosition") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("Interiors"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Heading") + .HasColumnType("double"); + + b.Property("X") + .HasColumnType("double"); + + b.Property("Y") + .HasColumnType("double"); + + b.Property("Z") + .HasColumnType("double"); + + b.HasKey("Id"); + + b.ToTable("Locations"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.BankAccountTransactionHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Fee") + .HasColumnType("int"); + + b.Property("MoneySent") + .HasColumnType("int"); + + b.Property("NewReceiverBalance") + .HasColumnType("int"); + + b.Property("NewSenderBalance") + .HasColumnType("int"); + + b.Property("Origin") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Receiver") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("ReceiverBalance") + .HasColumnType("int"); + + b.Property("Sender") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("SenderBalance") + .HasColumnType("int"); + + b.Property("Timestamp") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("BankAccountTransactionLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Text") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Time") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ChatLogs"); + + b.HasDiscriminator("Discriminator").HasValue("ChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.CommandLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Command") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Time") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("CommandLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Death", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CauseOfDeath") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("KillerHeading") + .HasColumnType("float"); + + b.Property("KillerId") + .HasColumnType("int"); + + b.Property("KillerPositionX") + .HasColumnType("float"); + + b.Property("KillerPositionY") + .HasColumnType("float"); + + b.Property("KillerPositionZ") + .HasColumnType("float"); + + b.Property("Timestamp") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.Property("VictimHeading") + .HasColumnType("float"); + + b.Property("VictimId") + .HasColumnType("int"); + + b.Property("VictimPositionX") + .HasColumnType("float"); + + b.Property("VictimPositionY") + .HasColumnType("float"); + + b.Property("VictimPositionZ") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("KillerId"); + + b.HasIndex("VictimId"); + + b.ToTable("DeathLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.LoginLogoutLogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("IpAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("LoginLogout") + .HasColumnType("tinyint(1)"); + + b.Property("PlayerId") + .HasColumnType("bigint"); + + b.Property("SocialClubName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Time") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("Username") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("LoginLogoutLogs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.News", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Caption") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Content") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Timestamp") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("News"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedBlip", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Alpha") + .HasColumnType("tinyint unsigned"); + + b.Property("Color") + .HasColumnType("tinyint unsigned"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("DrawDistance") + .HasColumnType("float"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("Rotation") + .HasColumnType("float"); + + b.Property("Scale") + .HasColumnType("float"); + + b.Property("ShortRange") + .HasColumnType("tinyint(1)"); + + b.Property("Sprite") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.ToTable("Blips"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedMarker", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ColorA") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorB") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorG") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorR") + .HasColumnType("tinyint unsigned"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("DirectionX") + .HasColumnType("float"); + + b.Property("DirectionY") + .HasColumnType("float"); + + b.Property("DirectionZ") + .HasColumnType("float"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("RotationX") + .HasColumnType("float"); + + b.Property("RotationY") + .HasColumnType("float"); + + b.Property("RotationZ") + .HasColumnType("float"); + + b.Property("Scale") + .HasColumnType("float"); + + b.Property("Type") + .HasColumnType("tinyint unsigned"); + + b.Property("Visible") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Markers"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedPed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("HashModel") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Heading") + .HasColumnType("float"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Peds"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedPickup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("PositionX") + .HasColumnType("float") + .HasMaxLength(128); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("RespawnTime") + .HasColumnType("int"); + + b.Property("RotationX") + .HasColumnType("float"); + + b.Property("RotationY") + .HasColumnType("float"); + + b.Property("RotationZ") + .HasColumnType("float"); + + b.Property("Vehicle") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Pickups"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedTextLabel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ColorA") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorB") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorG") + .HasColumnType("tinyint unsigned"); + + b.Property("ColorR") + .HasColumnType("tinyint unsigned"); + + b.Property("Dimension") + .HasColumnType("tinyint unsigned"); + + b.Property("DrawDistance") + .HasColumnType("float"); + + b.Property("Font") + .HasColumnType("tinyint unsigned"); + + b.Property("LOS") + .HasColumnType("tinyint(1)"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("Text") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("TextLabels"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("int"); + + b.Property("Variable") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ServerVehicle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("DistanceDriven") + .HasColumnType("float"); + + b.Property("Heading") + .HasColumnType("float"); + + b.Property("Livery") + .HasColumnType("int"); + + b.Property("Locked") + .HasColumnType("tinyint(1)"); + + b.Property("Model") + .HasColumnType("int unsigned"); + + b.Property("NumberPlate") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("PrimaryColor") + .HasColumnType("int"); + + b.Property("SecondaryColor") + .HasColumnType("int"); + + b.Property("TankAmount") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("ServerVehicles"); + + b.HasDiscriminator("Discriminator").HasValue("ServerVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ShopClothe", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Category") + .HasColumnType("int"); + + b.Property("ClotheId") + .HasColumnType("int"); + + b.Property("ComponentId") + .HasColumnType("int"); + + b.Property("Gender") + .HasColumnType("tinyint(1)"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("TypeId") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("ShopClothes"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ShopItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Amount") + .HasColumnType("int"); + + b.Property("ItemId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("ShopId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ShopItems"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.TuningGarage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("TuningGarages"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Turfs", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Color") + .HasColumnType("int"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("MaxValue") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Owner") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Range") + .HasColumnType("float"); + + b.Property("Rotation") + .HasColumnType("float"); + + b.Property("Surplus") + .HasColumnType("tinyint(1)"); + + b.Property("Value") + .HasColumnType("int"); + + b.Property("Vector") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Turfs"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AdminLevel") + .HasColumnType("int"); + + b.Property("BanId") + .HasColumnType("int"); + + b.Property("BankAccountId") + .HasColumnType("int"); + + b.Property("BusSkill") + .HasColumnType("int"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.Property("CannabisSeedsBoughtToday") + .HasColumnType("int"); + + b.Property("CharacterId") + .HasColumnType("int"); + + b.Property("Dead") + .HasColumnType("tinyint(1)"); + + b.Property("DriverLicenseBike") + .HasColumnType("tinyint(1)"); + + b.Property("DriverLicenseVehicle") + .HasColumnType("tinyint(1)"); + + b.Property("Email") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("FactionId") + .HasColumnType("int"); + + b.Property("FactionLeader") + .HasColumnType("tinyint(1)"); + + b.Property("FactionRankId") + .HasColumnType("int"); + + b.Property("FlyingLicensePlane") + .HasColumnType("tinyint(1)"); + + b.Property("FreeSurgery") + .HasColumnType("tinyint(1)"); + + b.Property("GroupId") + .HasColumnType("int"); + + b.Property("GroupRank") + .HasColumnType("int"); + + b.Property("Handmoney") + .HasColumnType("int"); + + b.Property("HouseId") + .HasColumnType("int"); + + b.Property("JailTime") + .HasColumnType("int"); + + b.Property("JobId") + .HasColumnType("int"); + + b.Property("LastTimeBoughtCannabisSeeds") + .HasColumnType("datetime(6)"); + + b.Property("LogUserId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Password") + .HasColumnType("varchar(64) CHARACTER SET utf8mb4") + .HasMaxLength(64); + + b.Property("PaydayTimer") + .HasColumnType("int"); + + b.Property("PilotSkill") + .HasColumnType("int"); + + b.Property("PlayedMinutes") + .HasColumnType("int"); + + b.Property("Points") + .HasColumnType("int"); + + b.Property("PositionX") + .HasColumnType("float"); + + b.Property("PositionY") + .HasColumnType("float"); + + b.Property("PositionZ") + .HasColumnType("float"); + + b.Property("RegistrationDate") + .ValueGeneratedOnAdd() + .HasColumnType("datetime(6)"); + + b.Property("SocialClubName") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Wage") + .HasColumnType("int"); + + b.Property("Wanteds") + .HasColumnType("int"); + + b.Property("WeaponLicense") + .HasColumnType("tinyint(1)"); + + b.Property("failpoints") + .HasColumnType("int"); + + b.Property("otheramount") + .HasColumnType("int"); + + b.Property("trashcount") + .HasColumnType("int"); + + b.Property("warn") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BanId"); + + b.HasIndex("BankAccountId"); + + b.HasIndex("BusinessId") + .IsUnique(); + + b.HasIndex("CharacterId"); + + b.HasIndex("FactionId"); + + b.HasIndex("FactionRankId"); + + b.HasIndex("GroupId"); + + b.HasIndex("HouseId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserBankAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Balance") + .HasColumnType("int"); + + b.Property("Bic") + .HasColumnType("varchar(12) CHARACTER SET utf8mb4") + .HasMaxLength(12); + + b.Property("Iban") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("UserBankAccounts"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Amount") + .HasColumnType("int"); + + b.Property("ItemId") + .HasColumnType("int"); + + b.Property("Slot") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserItems"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserWeapon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ammo") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("WeaponId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("WeaponId"); + + b.ToTable("UserWeapons"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Amount") + .HasColumnType("int"); + + b.Property("ItemId") + .HasColumnType("int"); + + b.Property("Slot") + .HasColumnType("int"); + + b.Property("VehicleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("VehicleId"); + + b.ToTable("VehicleItems"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleMod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ModId") + .HasColumnType("int"); + + b.Property("ServerVehicleId") + .HasColumnType("int"); + + b.Property("Slot") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ServerVehicleId", "Slot") + .IsUnique(); + + b.ToTable("VehicleMods"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Weapon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Ammo") + .HasColumnType("int"); + + b.Property("AmmunationActive") + .HasColumnType("tinyint(1)"); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("Legal") + .HasColumnType("tinyint(1)"); + + b.Property("Price") + .HasColumnType("float"); + + b.Property("SlotID") + .HasColumnType("int"); + + b.Property("WeaponModel") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Weapons"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.WeaponCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Category") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("WeaponCategories"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Whitelist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("SocialClubName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.ToTable("WhitelistEntries"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.DepartmentChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("DepartmentChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.FactionChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.Property("FactionId") + .HasColumnType("int"); + + b.HasIndex("FactionId"); + + b.HasDiscriminator().HasValue("FactionChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.GangChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("GangChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.GroupChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.Property("GroupId") + .HasColumnType("int"); + + b.HasIndex("GroupId"); + + b.HasDiscriminator().HasValue("GroupChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.LeaderChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("LeaderChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.LocalChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("LocalChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.NewsChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("NewsChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.OChatLogEntry", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry"); + + b.HasDiscriminator().HasValue("OChatLogEntry"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("BuyPrice") + .HasColumnType("int"); + + b.Property("Owners") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.ToTable("FactionVehicles"); + + b.HasDiscriminator().HasValue("FactionVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GroupVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("GroupId") + .HasColumnType("int"); + + b.HasIndex("GroupId"); + + b.HasDiscriminator().HasValue("GroupVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.JobVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("JobId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("JobVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.NoobSpawnVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.HasDiscriminator().HasValue("NoobSpawnVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.NoobVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.HasDiscriminator().HasValue("NoobVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Saves.SavedVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.HasDiscriminator().HasValue("SavedVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.SchoolVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("SchoolId") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("SchoolVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.ShopVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("BusinessId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnType("int"); + + b.ToTable("ShopVehicles"); + + b.HasDiscriminator().HasValue("ShopVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserVehicle", b => + { + b.HasBaseType("ReallifeGamemode.Database.Entities.ServerVehicle"); + + b.Property("BusinessId") + .HasColumnName("UserVehicle_BusinessId") + .HasColumnType("int"); + + b.Property("Price") + .HasColumnName("UserVehicle_Price") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasIndex("UserId"); + + b.ToTable("UserVehicles"); + + b.HasDiscriminator().HasValue("UserVehicle"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Ban", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.BusRoutePoint", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.BusRoute", "BusRoute") + .WithMany("RoutePoints") + .HasForeignKey("BusRouteId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CannabisPlant", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "PlantedBy") + .WithMany() + .HasForeignKey("PlantedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Character", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.CharacterCloth", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Door", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.DutyCloth", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Faction", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.FactionBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionRank", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.FactionWeapon", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Group", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.GroupBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.House", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.HouseBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + + b.HasOne("ReallifeGamemode.Database.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.HouseRental", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.House", "House") + .WithMany("Rentals") + .HasForeignKey("HouseId"); + + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.ChatLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.CommandLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Death", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "Killer") + .WithMany() + .HasForeignKey("KillerId"); + + b.HasOne("ReallifeGamemode.Database.Entities.User", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.LoginLogoutLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.News", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.User", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Ban", "Ban") + .WithMany() + .HasForeignKey("BanId"); + + b.HasOne("ReallifeGamemode.Database.Entities.UserBankAccount", "BankAccount") + .WithMany() + .HasForeignKey("BankAccountId"); + + b.HasOne("ReallifeGamemode.Database.Entities.Character", "Character") + .WithMany() + .HasForeignKey("CharacterId"); + + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId"); + + b.HasOne("ReallifeGamemode.Database.Entities.FactionRank", "FactionRank") + .WithMany() + .HasForeignKey("FactionRankId"); + + b.HasOne("ReallifeGamemode.Database.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId"); + + b.HasOne("ReallifeGamemode.Database.Entities.House", "House") + .WithMany() + .HasForeignKey("HouseId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserItem", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserWeapon", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ReallifeGamemode.Database.Entities.Weapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleItem", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.ServerVehicle", "Vehicle") + .WithMany() + .HasForeignKey("VehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.VehicleMod", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.ServerVehicle", "Vehicle") + .WithMany() + .HasForeignKey("ServerVehicleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Weapon", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.WeaponCategory", "WeaponCategory") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.FactionChatLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Faction", "Faction") + .WithMany() + .HasForeignKey("FactionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.Logs.Chat.GroupChatLogEntry", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.GroupVehicle", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.Group", "Group") + .WithMany() + .HasForeignKey("GroupId"); + }); + + modelBuilder.Entity("ReallifeGamemode.Database.Entities.UserVehicle", b => + { + b.HasOne("ReallifeGamemode.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.cs b/ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.cs new file mode 100644 index 00000000..bc63b452 --- /dev/null +++ b/ReallifeGamemode.Database/Migrations/20210527144901_AddUserCannabisSeedBuyData.cs @@ -0,0 +1,33 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace ReallifeGamemode.Database.Migrations +{ + public partial class AddUserCannabisSeedBuyData : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CannabisSeedsBoughtToday", + table: "Users", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "LastTimeBoughtCannabisSeeds", + table: "Users", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CannabisSeedsBoughtToday", + table: "Users"); + + migrationBuilder.DropColumn( + name: "LastTimeBoughtCannabisSeeds", + table: "Users"); + } + } +} diff --git a/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs b/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs index ceeeb6b5..ccb4e8cc 100644 --- a/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs +++ b/ReallifeGamemode.Database/Migrations/DatabaseContextModelSnapshot.cs @@ -1456,6 +1456,9 @@ namespace ReallifeGamemode.Database.Migrations b.Property("BusinessId") .HasColumnType("int"); + b.Property("CannabisSeedsBoughtToday") + .HasColumnType("int"); + b.Property("CharacterId") .HasColumnType("int"); @@ -1505,6 +1508,9 @@ namespace ReallifeGamemode.Database.Migrations b.Property("JobId") .HasColumnType("int"); + b.Property("LastTimeBoughtCannabisSeeds") + .HasColumnType("datetime(6)"); + b.Property("LogUserId") .HasColumnType("int"); diff --git a/ReallifeGamemode.Server/BaseScript.cs b/ReallifeGamemode.Server/BaseScript.cs index 969ff10c..d9a27f6a 100644 --- a/ReallifeGamemode.Server/BaseScript.cs +++ b/ReallifeGamemode.Server/BaseScript.cs @@ -9,7 +9,7 @@ namespace ReallifeGamemode.Server { public abstract class BaseScript : Script { - protected readonly ILogger logger; + protected static ILogger logger { get; private set; } public BaseScript() { diff --git a/ReallifeGamemode.Server/Events/Death.cs b/ReallifeGamemode.Server/Events/Death.cs index 4c3a3637..697e2159 100644 --- a/ReallifeGamemode.Server/Events/Death.cs +++ b/ReallifeGamemode.Server/Events/Death.cs @@ -47,6 +47,14 @@ namespace ReallifeGamemode.Server.Events return; } + if(player.HasData("IsCarryingPlant") || player.GetData("IsCarryingPlant")) + { + var currentModel = player.GetData("HoldingCannabisPlant"); + + player.AddAttachment("CannabisPlantInHand" + currentModel, true); + player.ResetData("IsCarryingPlant"); + } + using var dbContext = new DatabaseContext(); User user = player.GetUser(dbContext); diff --git a/ReallifeGamemode.Server/Events/Disconnect.cs b/ReallifeGamemode.Server/Events/Disconnect.cs index ca1ba2ab..b8af1ce7 100644 --- a/ReallifeGamemode.Server/Events/Disconnect.cs +++ b/ReallifeGamemode.Server/Events/Disconnect.cs @@ -41,6 +41,14 @@ namespace ReallifeGamemode.Server.Events return; } + if (player.HasData("IsCarryingPlant") || player.GetData("IsCarryingPlant")) + { + var currentModel = player.GetData("HoldingCannabisPlant"); + + player.AddAttachment("CannabisPlantInHand" + currentModel, true); + player.ResetData("IsCarryingPlant"); + } + var logEntry = new LoginLogoutLogEntry() { LoginLogout = false, diff --git a/ReallifeGamemode.Server/Events/Key.cs b/ReallifeGamemode.Server/Events/Key.cs index 79274414..bf14ab2d 100644 --- a/ReallifeGamemode.Server/Events/Key.cs +++ b/ReallifeGamemode.Server/Events/Key.cs @@ -21,6 +21,8 @@ using ReallifeGamemode.Server.Types; using ReallifeGamemode.Server.Util; using ReallifeGamemode.Server.WeaponDeal; using ReallifeGamemode.Server.Log; +using ReallifeGamemode.Server.Inventory.Items; +using Microsoft.EntityFrameworkCore; using ReallifeGamemode.Server.Wanted; /** @@ -217,9 +219,61 @@ namespace ReallifeGamemode.Server.Events [RemoteEvent("keyPress:E")] public void KeyPressE(Player player) { - if (!player.IsLoggedIn() || player.GetData("isDead") || player.IsInVehicle) return; + if (!player.IsLoggedIn() || player.GetData("isDead")) return; var user = player.GetUser(); + if (player.IsInVehicle + && player.VehicleSeat == 0 + && player.Vehicle.Model == (uint)VehicleHash.Riot + && (user.FactionId == 1 || user.FactionId == 3) + && player.Position.DistanceTo(HanfManager.ASSERVATENKAMMER_POSITION) <= 3 + /*&& player.IsDuty()*/) + { + using var dbContext = new DatabaseContext(); + GTANetworkAPI.Vehicle veh = player.Vehicle; + ServerVehicle serverVehicle = veh.GetServerVehicle(dbContext); + + List items = InventoryManager.GetVehicleItems(veh); + if (items.Count() == 0) + { + player.SendNotification("Der Riot ist leer"); + return; + } + + IIllegalItem cannabisItem = InventoryManager.GetItem(); + IIllegalItem cannabisSeedItem = InventoryManager.GetItem(); + + VehicleItem vehicleCannabisItem = items.Where(i => i.ItemId == cannabisItem.Id).FirstOrDefault(); + VehicleItem vehicleCannabisSeedItem = items.Where(i => i.ItemId == cannabisSeedItem.Id).FirstOrDefault(); + + int cannabisAmount = vehicleCannabisItem?.Amount ?? 0; + int cannabisSeedAmount = vehicleCannabisSeedItem?.Amount ?? 0; + + InventoryManager.RemoveVehicleItem(serverVehicle, vehicleCannabisItem, cannabisAmount, player); + InventoryManager.RemoveVehicleItem(serverVehicle, vehicleCannabisSeedItem, cannabisSeedAmount, player); + + var price = cannabisSeedAmount * cannabisSeedItem.PriceForConfiscation + cannabisAmount * cannabisItem.PriceForConfiscation; + + logger.LogInformation("Player {0} unloaded the riot truck with {1} cannabis and {2} cannabis seed and the faction got {3}", player.Name, cannabisAmount, cannabisSeedAmount, price); + + var factions = dbContext.Factions.Include(f => f.BankAccount).Where(f => f.Id == 1 || f.Id == 3); + foreach (var faction in factions) + { + faction.BankAccount.Balance += price; + } + + player.SendNotification("~g~Der Riot wurde erfolgreich entladen"); + + dbContext.SaveChanges(); + + return; + } + + if (player.IsInVehicle) + { + return; + } + if (player.HasData("nearATM")) { ATMManager.ShowAtmUi(player, player.GetData("nearATM")); @@ -245,6 +299,7 @@ namespace ReallifeGamemode.Server.Events JailPoint nearestjailPoint = PositionManager.jailPoints.Find(s => s.Position.DistanceTo(player.Position) <= 1.5); bool isNearCannabisSeedBuyPoint = HanfManager.IsPlayerNearSeedBuyPoint(player); bool isNearJointManufacturerPoint = HanfManager.IsPlayerNearJointManufacturer(player); + bool isNearCannabisSellPoint = HanfManager.IsPlayerNearCannabisSellPoint(player); if (user?.FactionId != null) { @@ -766,7 +821,7 @@ namespace ReallifeGamemode.Server.Events if (isNearCannabisSeedBuyPoint) { - player.TriggerEvent("SERVER:Hanf_BuySeed", HanfManager.SEED_PRICE); + HanfManager.ShowPlayerBuySeedMenu(player); return; } @@ -775,6 +830,39 @@ namespace ReallifeGamemode.Server.Events HanfManager.BuildJointsFromCannabis(player); return; } + + if (isNearCannabisSellPoint) + { + HanfManager.PlayerSellCannabis(player); + return; + } + + if (player.HasData("IsCarryingPlant") || player.GetData("IsCarryingPlant") && (user.FactionId == 3 || user.FactionId == 1) && player.IsDuty()) + { + using var dbContext = new DatabaseContext(); + FactionVehicle riot = dbContext.FactionVehicles.Where(f => f.Model == VehicleHash.Riot).ToList().Where(f => f.GetOwners().Contains(3)).FirstOrDefault(); + if (riot == null) + { + return; + } + GTANetworkAPI.Vehicle riotVehicle = VehicleManager.GetVehicleFromServerVehicle(riot); + if (riotVehicle.Position.DistanceTo(player.Position) > 3) + { + return; + } + + var currentModel = player.GetData("HoldingCannabisPlant"); + + player.AddAttachment("CannabisPlantInHand" + currentModel, true); + player.ResetData("IsCarryingPlant"); + + var cannabisItem = InventoryManager.GetItem(); + var cannabisSeedsItem = InventoryManager.GetItem(); + int itemIdToGive = currentModel == 3 ? cannabisItem.Id : cannabisSeedsItem.Id; + int amountToGive = currentModel == 3 ? new Random().Next(4, 10) + 1 : 1; + + InventoryManager.AddItemToVehicleInventory(riotVehicle, itemIdToGive, amountToGive); + } } [RemoteEvent("keyPress:I")] diff --git a/ReallifeGamemode.Server/Events/Vehicle.cs b/ReallifeGamemode.Server/Events/Vehicle.cs index ff21e6d8..4be3db76 100644 --- a/ReallifeGamemode.Server/Events/Vehicle.cs +++ b/ReallifeGamemode.Server/Events/Vehicle.cs @@ -1,17 +1,21 @@ 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.Types; using ReallifeGamemode.Server.Util; using ReallifeGamemode.Server.WeaponDeal; +using ReallifeGamemode.Server.Log; namespace ReallifeGamemode.Server.Events { public class Vehicle : Script { + private static readonly ILogger logger = LogManager.GetLogger(); + [RemoteEvent("VehicleMenu_ToggleEngine")] public void VehicleMenuToggleEngineEvent(Player player) { @@ -271,6 +275,8 @@ namespace ReallifeGamemode.Server.Events sV.PositionZ = pos.Z; sV.Heading = v.Heading; + logger.LogInformation("Player {0} parked the car {1} at x:{2}, y:{3}, z:{4}", player.Name, sV.Id, pos.X, pos.Y, pos.Z); + player.SendNotification("~g~Das Fahrzeug wurde geparkt."); diff --git a/ReallifeGamemode.Server/Inventory/Interfaces/IIllegalItem.cs b/ReallifeGamemode.Server/Inventory/Interfaces/IIllegalItem.cs new file mode 100644 index 00000000..caac39a5 --- /dev/null +++ b/ReallifeGamemode.Server/Inventory/Interfaces/IIllegalItem.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReallifeGamemode.Server.Inventory.Interfaces +{ + interface IIllegalItem : IItem + { + int PriceForConfiscation { get; } + } +} diff --git a/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs b/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs index bd82e7af..11f2c7bf 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Cannabis.cs @@ -9,7 +9,7 @@ using ReallifeGamemode.Server.Inventory.Interfaces; namespace ReallifeGamemode.Server.Inventory.Items { - public class Cannabis : DropItem + public class Cannabis : DropItem, IIllegalItem { public override int Id => 108; @@ -24,5 +24,9 @@ namespace ReallifeGamemode.Server.Inventory.Items public override uint Object => 3076948544; public override int Price => 0; + + public override bool Legal => false; + + public int PriceForConfiscation { get; } = 5; } } diff --git a/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs b/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs index f3fa752d..7d3d098a 100644 --- a/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs +++ b/ReallifeGamemode.Server/Inventory/Items/CannabisSeeds.cs @@ -5,11 +5,12 @@ using GTANetworkAPI; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; +using ReallifeGamemode.Server.Inventory.Interfaces; using ReallifeGamemode.Server.Managers; namespace ReallifeGamemode.Server.Inventory.Items { - public class CannabisSeeds : UseItem + public class CannabisSeeds : UseItem, IIllegalItem { public override int Id { get; } = 109; public override string Name { get; } = "Cannabis Samen"; @@ -21,14 +22,15 @@ namespace ReallifeGamemode.Server.Inventory.Items public override uint Object { get; } public override bool RemoveWhenUsed { get; } = false; + public int PriceForConfiscation { get; } = 10; public override bool Use(Player player, User user, DatabaseContext databaseContext) { - if(!player.IsInVehicle) + if (!player.IsInVehicle) { HanfManager.StartCannabisPlanting(player); } - + return true; } } diff --git a/ReallifeGamemode.Server/Inventory/Items/Joint.cs b/ReallifeGamemode.Server/Inventory/Items/Joint.cs index 97ffc677..21ed6a6f 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Joint.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Joint.cs @@ -5,12 +5,16 @@ using GTANetworkAPI; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Extensions; +using ReallifeGamemode.Server.Inventory.Interfaces; using ReallifeGamemode.Server.Util; namespace ReallifeGamemode.Server.Inventory.Items { - public class Joint : UseItem + public class Joint : UseItem, IIllegalItem { + private static Dictionary lastJointUse = new Dictionary(); + private static readonly TimeSpan _jointCooldown = TimeSpan.FromMinutes(10); + public override int Id { get; } = 110; public override string Name { get; } = "Joint"; public override string Description { get; } = "stay high bis zum tod"; @@ -21,10 +25,33 @@ namespace ReallifeGamemode.Server.Inventory.Items public override bool Legal => false; public override bool RemoveWhenUsed => true; + public int PriceForConfiscation { get; } = 25; + public override bool Use(Player player, User user, DatabaseContext databaseContext) { + if (!CanUserUseJoint(user)) + { + player.TriggerEvent("Error", $"Versuche es nach {-1 * (int)((DateTime.Now - lastJointUse[user.Id]) - _jointCooldown).TotalSeconds} Sekunden erneut."); + return false; + } + + player.SyncAnimation("jointUse"); + player.ToggleInventory(InventoryToggleOption.HIDE); + int armorToSet = Math.Min(player.Armor + 25, 100); + player.SafeSetArmor(armorToSet); + lastJointUse[user.Id] = DateTime.Now; return true; } + + private bool CanUserUseJoint(User user) + { + if(!lastJointUse.ContainsKey(user.Id)) + { + return true; + } + + return DateTime.Now - lastJointUse[user.Id] > _jointCooldown; + } } } diff --git a/ReallifeGamemode.Server/Managers/HanfManager.cs b/ReallifeGamemode.Server/Managers/HanfManager.cs index fa1ffd2e..a2916668 100644 --- a/ReallifeGamemode.Server/Managers/HanfManager.cs +++ b/ReallifeGamemode.Server/Managers/HanfManager.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Timers; using GTANetworkAPI; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using ReallifeGamemode.Database.Entities; @@ -12,6 +13,7 @@ using ReallifeGamemode.Server.Extensions; using ReallifeGamemode.Server.Inventory.Interfaces; using ReallifeGamemode.Server.Inventory.Items; using ReallifeGamemode.Server.Services; +using ReallifeGamemode.Server.Types; using ReallifeGamemode.Server.Util; namespace ReallifeGamemode.Server.Managers @@ -23,10 +25,28 @@ namespace ReallifeGamemode.Server.Managers /// private readonly static List _seedsBuyPoints = new List(); + private readonly static List _cannabisSellPoints = new List(); + /// /// Aktueller Samen-Preis /// - public static int SEED_PRICE = 50; + public static int SEED_PRICE = 0; + + private const int SEED_PRICE_MIN = 40; + private const int SEED_PRICE_MAX = 75; + + /// + /// Aktueller Hanf-Verkaufspreis + /// + public static int CANNABIS_PRICE = 0; + + private const int CANNABIS_PRICE_MIN = 50; + private const int CANNABIS_PRICE_MAX = 125; + + /// + /// Wie viele Samen ein Spieler pro Tag maximal kaufen darf + /// + private const int MAX_SEEDS_PER_DAY = 50; /// /// Wie viele Joints man aus einem Cannabis bekommt @@ -72,6 +92,8 @@ namespace ReallifeGamemode.Server.Managers private static List _currentCannabisData = new List(); + public static readonly Vector3 ASSERVATENKAMMER_POSITION = new Vector3(-5.45, -670.03, 32.33); + static HanfManager() { _manufacturerDoneTimer.Elapsed += ManufacturerDoneTimerCallback; @@ -82,6 +104,12 @@ namespace ReallifeGamemode.Server.Managers /// public static void Load() { + var priceRandom = new Random(); + + SEED_PRICE = priceRandom.Next(SEED_PRICE_MIN, SEED_PRICE_MAX + 1); + CANNABIS_PRICE = priceRandom.Next(CANNABIS_PRICE_MIN, CANNABIS_PRICE_MAX + 1); + logger.LogInformation("Generated hanf prices: seed = {0}, cannabis = {1}", SEED_PRICE, CANNABIS_PRICE); + _seedsBuyPoints.Add(new Vector3(-30.21876, -585.3222, 17.917326)); _seedsBuyPoints.Add(new Vector3(-680.89386, -634.6783, 25.29923)); _seedsBuyPoints.Add(new Vector3(-1310.743, -608.9064, 29.382874)); @@ -92,17 +120,58 @@ namespace ReallifeGamemode.Server.Managers foreach (Vector3 buyPoint in _seedsBuyPoints) { - colShape = NAPI.ColShape.CreateSphereColShape(buyPoint, 20.0f); + colShape = NAPI.ColShape.CreateSphereColShape(buyPoint, 10.0f); colShape.OnEntityEnterColShape += OnSeedBuyRangeColShapeEnter; } - UpdateHanfWorldData(new DatabaseContext()); + _cannabisSellPoints.Add(new Vector3(2220.04, 5614.24, 54.72)); + _cannabisSellPoints.Add(new Vector3(201.77, 2442.06, 60.45)); + _cannabisSellPoints.Add(new Vector3(155.87, -3103.26, 7.03)); + + foreach (Vector3 sellPoint in _cannabisSellPoints) + { + colShape = NAPI.ColShape.CreateSphereColShape(sellPoint, 10.0f); + colShape.OnEntityEnterColShape += OnCannabisSellRangeColShapeEnter; + } + + NAPI.Marker.CreateMarker(GTANetworkAPI.MarkerType.VerticalCylinder, ASSERVATENKAMMER_POSITION.Subtract(new Vector3(0, 0, 3.0)), new Vector3(), new Vector3(), 3.0f, Colors.White); + NAPI.TextLabel.CreateTextLabel("Asservatenkammer~n~Drücke ~y~E, um den ~y~Riot~s~ zu entladen", ASSERVATENKAMMER_POSITION, 10.0f, 10.0f, 0, Colors.White); + + using var dbContext = new DatabaseContext(); + HarvestRottenPlants(dbContext); + UpdateHanfWorldData(dbContext); Timer updateHanfDataTimer = new Timer(TimeSpan.FromMinutes(1).TotalMilliseconds); updateHanfDataTimer.Elapsed += UpdateHanfDataTimer_Elapsed; updateHanfDataTimer.Start(); } + private static void OnCannabisSellRangeColShapeEnter(ColShape colShape, Player player) + { + if (!player.IsLoggedIn()) + { + return; + } + + var user = player.GetUser(); + if (user?.Faction?.StateOwned == true) + { + return; + } + + ChatService.SendMessage(player, $"Fremder sagt: Pssst.. Hier kannst du dein Brokkoli loswerden."); + } + + private static void HarvestRottenPlants(DatabaseContext dbContext) + { + var rottenPlants = dbContext.CannabisPlants.Where(p => EF.Functions.DateDiffHour(p.PlantDate, DateTime.Now) > MAX_PLANT_TIME.TotalHours); + foreach (var plant in rottenPlants) + { + plant.Harvested = true; + } + dbContext.SaveChanges(); + } + private static void UpdateHanfDataTimer_Elapsed(object sender, ElapsedEventArgs e) { using var dbContext = new DatabaseContext(); @@ -148,7 +217,7 @@ namespace ReallifeGamemode.Server.Managers var user = player.GetUser(dbContext); if (user.Faction?.StateOwned ?? false) { - player.SendNotification("~r~Du darfst keine Hanfsamen einfplanzen"); + player.SendNotification("~r~Du darfst keine Hanfsamen einpflanzen"); return; } @@ -220,7 +289,7 @@ namespace ReallifeGamemode.Server.Managers public async static void UpdateHanfForPlayer(Player player, List cannabisData = null) { cannabisData ??= _currentCannabisData; - var x = await NAPI.Task.WaitForMainThread(); + await NAPI.Task.WaitForMainThread(); player.TriggerEvent("SERVER:Hanf_UpdateHanfData", JsonConvert.SerializeObject(cannabisData)); } @@ -235,6 +304,12 @@ namespace ReallifeGamemode.Server.Managers using var dbContext = new DatabaseContext(); var user = player.GetUser(dbContext); + if (amount > GetAmountOfCannabisSeedsPlayerCanBuyToday(user)) + { + player.SendNotification("~r~Du kannst heute nicht mehr so viele Samen kaufen"); + return; + } + IItem seedItem = InventoryManager.GetItem(); var newAmount = seedItem.Gewicht * amount; @@ -254,6 +329,16 @@ namespace ReallifeGamemode.Server.Managers logger.LogInformation("Player {0} bought {1} cannabis seeds for {2} dollars (price per seed: {3})", player.Name, amount, price, SEED_PRICE); // <-- WICHTIG LOGS + if (user.LastTimeBoughtCannabisSeeds == null || user.LastTimeBoughtCannabisSeeds.Value.Date != DateTime.Now.Date) + { + user.CannabisSeedsBoughtToday = amount; + } + else + { + user.CannabisSeedsBoughtToday += amount; + } + user.LastTimeBoughtCannabisSeeds = DateTime.Now; + user.Handmoney -= price; dbContext.SaveChanges(); @@ -263,7 +348,7 @@ namespace ReallifeGamemode.Server.Managers } [RemoteEvent("CLIENT:Hanf_HarvestHanf")] - public void HanfManagerHarvestHanf(Player player, long hanfId) + public async void HanfManagerHarvestHanf(Player player, long hanfId) { if (!player.IsLoggedIn()) { @@ -273,15 +358,10 @@ namespace ReallifeGamemode.Server.Managers using var dbContext = new DatabaseContext(); User user = player.GetUser(dbContext); - CannabisPlant plant = dbContext.CannabisPlants.Find(hanfId); + CannabisPlant plant = dbContext.CannabisPlants.Include(p => p.PlantedBy).Where(p => p.Id == hanfId).FirstOrDefault(); if (plant == null) { logger.LogError("Player {0} tried to harvest cannabis plant {1} but it was not found in database", player.Name, hanfId); - } - - if (user.Faction?.StateOwned == true && !(user.FactionId == 3 && player.IsDuty())) - { - player.SendNotification("~r~Du kannst kein Hanf ernten"); return; } @@ -290,10 +370,32 @@ namespace ReallifeGamemode.Server.Managers return; } - plant.Harvested = true; - - if (user.FactionId != 3) // Zivi / Gangmember erntet ab + if (player.IsAdminDuty() && player.IsTSupport() && user.IsAdmin(AdminLevel.ADMIN)) { + player.SendNotification($"Du hast die Hanf-Pflanze von ~y~{plant.PlantedBy.Name}~s~ entfernt"); + plant.Harvested = true; + dbContext.SaveChanges(); + UpdateHanfWorldData(dbContext); + return; + } + + if (user.Faction?.StateOwned == true) + { + if (!((user.FactionId == 1 || user.FactionId == 3) && player.IsDuty())) + { + player.SendNotification("~r~Du kannst kein Hanf ernten"); + return; + } + } + + //player.SyncAnimation(new[] { "harvestPlantEnter", "harvestPlant", "harvestPlantExit" }.ToList()); + //player.SyncAnimation("harvestPlant"); + //player.AddAttachment("shovel", false); + + if (user.FactionId != 3 && user.FactionId != 1) // Zivi / Gangmember erntet ab + { + player.SyncAnimation("harvestPlant"); + plant.Harvested = true; bool isPlantRotten = DateTime.Now - plant.PlantDate > MAX_PLANT_TIME; if (isPlantRotten) { @@ -305,7 +407,7 @@ namespace ReallifeGamemode.Server.Managers if (!isPlantReadyToHarvest) // Wenn die Pflanze noch nicht ausgewachsen ist { bool getSeedBack = _random.Next(0, 2) == 1; // 50% Chance - if(getSeedBack) + if (getSeedBack) { IItem cannabisSeedItem = InventoryManager.GetItem(); InventoryManager.AddItemToInventory(player, cannabisSeedItem.Id, 1); @@ -340,15 +442,32 @@ namespace ReallifeGamemode.Server.Managers } } } - else // FIB erntet ab + else // FIB / LSPD erntet ab { + if (!(player.HasData("IsCarryingPlant") || player.GetData("IsCarryingPlant"))) + { + player.SetData("IsCarryingPlant", true); + player.SendNotification($"Du hast eine Pflanze von ~y~{plant.PlantedBy.Name}~s~ ausgegraben"); + + player.SyncAnimation("harvestPlant"); + plant.Harvested = true; + + var modelToGet = await player.TriggerProcedure("SERVER:Hanf_GetModelToGivePlayer", plant.Id); + player.SetData("HoldingCannabisPlant", modelToGet); + player.AddAttachment("CannabisPlantInHand" + modelToGet, false); + } } dbContext.SaveChanges(); UpdateHanfWorldData(dbContext); } + internal static bool IsPlayerNearCannabisSellPoint(Player player) + { + return _cannabisSellPoints.Any(p => p.DistanceTo(player.Position) <= 3); + } + internal static void BuildJointsFromCannabis(Player player) { if (player.HasAnimation(_manufacturerAnim) || _manufacturerCurrentlyUsed) @@ -396,5 +515,105 @@ namespace ReallifeGamemode.Server.Managers _manufacturerDoneTimer.Stop(); _manufacturerCurrentlyUsed = false; } + + [RemoteEvent("CLIENT:Hanf_FinishDiggingAnimation")] + public void HanfManagerFinishDiggingAnimation(Player player) + { + player.AddAttachment("shovel", true); + } + + private static int GetAmountOfCannabisSeedsPlayerCanBuyToday(User user) + { + if (user.LastTimeBoughtCannabisSeeds == null) + { + return MAX_SEEDS_PER_DAY; + } + + if (user.LastTimeBoughtCannabisSeeds.Value.Date != DateTime.Now.Date) + { + return MAX_SEEDS_PER_DAY; + } + + return MAX_SEEDS_PER_DAY - user.CannabisSeedsBoughtToday; + } + + internal static void ShowPlayerBuySeedMenu(Player player) + { + var user = player.GetUser(); + + if (user.Faction?.StateOwned == true) + { + return; + } + + var seedsUserCanBuy = GetAmountOfCannabisSeedsPlayerCanBuyToday(user); + + if (seedsUserCanBuy == 0) + { + player.SendNotification("~r~Du kannst heute keine Samen mehr kaufen"); + return; + } + + player.TriggerEvent("SERVER:Hanf_BuySeed", seedsUserCanBuy, SEED_PRICE); + } + + internal static void PlayerSellCannabis(Player player) + { + if (!player.IsLoggedIn()) + { + return; + } + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + + if (user.Faction?.StateOwned == true) + { + return; + } + + List items = InventoryManager.GetUserItems(player, dbContext); + + IItem cannabisItem = InventoryManager.GetItem(); + var cannabisAmount = items.Where(i => i.ItemId == cannabisItem.Id).FirstOrDefault()?.Amount ?? 0; + + if (cannabisAmount == 0) + { + player.SendNotification("~r~Du hast kein Cannabis dabei"); + return; + } + + player.TriggerEvent("SERVER:Hanf_SellCannabisMenu", cannabisAmount, CANNABIS_PRICE); + } + + [RemoteEvent("CLIENT:Hanf_SellCannabis")] + public void HanfManagerSellCannabis(Player player, int amount) + { + if (!player.IsLoggedIn()) + { + return; + } + + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + List items = InventoryManager.GetUserItems(player, dbContext); + + IItem cannabisItem = InventoryManager.GetItem(); + var cannabisUserItem = items.Where(i => i.ItemId == cannabisItem.Id).FirstOrDefault(); + var cannabisAmount = cannabisUserItem?.Amount ?? 0; + + if (cannabisAmount < amount) + { + player.SendNotification("~r~Du hast nicht so viel Cannabis dabei"); + return; + } + + var price = amount * CANNABIS_PRICE; + user.Handmoney += price; + InventoryManager.RemoveUserItem(user, cannabisUserItem, amount); + + logger.LogInformation("Player {0} sold {1} cannabis to the server for {2} dollars", player.Name, amount, price); + + player.SendNotification($"Du hast ~g~{amount} Hanfblüten~s~ für ~g~{price.ToMoneyString()}~s~ verkauft"); + } } } diff --git a/ReallifeGamemode.Server/Managers/InteractionManager.cs b/ReallifeGamemode.Server/Managers/InteractionManager.cs index d6d6e0ed..c769b235 100644 --- a/ReallifeGamemode.Server/Managers/InteractionManager.cs +++ b/ReallifeGamemode.Server/Managers/InteractionManager.cs @@ -18,6 +18,7 @@ using ReallifeGamemode.Server.Core.API; using ReallifeGamemode.Server.Factions.Medic; using Microsoft.Extensions.Logging; using ReallifeGamemode.Server.Log; +using ReallifeGamemode.Server.Inventory.Interfaces; /** * @overview Life of German Reallife - Managers Interaction (InteractionManager.cs) @@ -758,6 +759,150 @@ namespace ReallifeGamemode.Server.Managers } } + [RemoteEvent("CLIENT:InteractionMenu_LSPD_FriskUser")] + public void InteractionMenuLspdFriskUser(Player player, string name) + { + if (!player.IsLoggedIn()) + { + return; + } + + Player target = PlayerService.GetPlayerByNameOrId(name); + if (!target.IsLoggedIn()) + { + ChatService.PlayerNotFound(player); + return; + } + + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + + if ((user.FactionId != 1 && user.FactionId != 3) || !player.IsDuty()) + { + return; + } + + if (player.Position.DistanceTo(target.Position) > 5) + { + player.SendNotification("~r~Der Spieler ist nicht in deiner Nähe"); + return; + } + + var targetUser = target.GetUser(dbContext); + + var targetItems = InventoryManager.GetUserItems(target, dbContext); + List illItemsList = new List(); + bool illegalItemsFound = false; + var price = 0; + + foreach (var targetItem in targetItems) + { + IItem item = InventoryManager.GetItemById(targetItem.ItemId); + if (!item.Legal) + { + illItemsList.Add($"{targetItem.Amount}x {item.Name}"); + InventoryManager.RemoveUserItem(targetUser, targetItem, targetItem.Amount); + illegalItemsFound = true; + price += ((IIllegalItem)item).PriceForConfiscation * targetItem.Amount; + logger.LogInformation("Player {0} confiscated the illegal item {1} ({2}, amount: {3}) from player {4}", player.Name, item.Name, item.Id, targetItem.Amount, target.Name); + } + } + + if (!illegalItemsFound) + { + player.SendNotification("~g~Der Spieler hat keine illegalen Gegenstände dabei"); + return; + } + + logger.LogInformation("executive factions got {0} dollars from the confiscation", price); + var factions = dbContext.Factions.Include(f => f.BankAccount).Where(f => f.Id == 1 || f.Id == 3); + foreach (var faction in factions) + { + faction.BankAccount.Balance += price; + } + + dbContext.SaveChanges(); + + string illItemsStr = "~y~" + string.Join("~s~,~y~ ", illItemsList) + "~s~"; + ChatService.SendMessage(player, $"Du hast ~y~{target.Name}~s~ folgende Gegenstände abgenommen: {illItemsStr}"); + ChatService.SendMessage(target, $"~y~{player.Name}~s~ hat die folgende Gegenstände abgenommen: {illItemsStr}"); + + } + + [RemoteEvent("CLIENT:InteractionMenu_LSPD_FriskVehicle")] + public void InteractionMenuLspdFriskVehicle(Player player) + { + if (!player.IsLoggedIn()) + { + return; + } + + using var dbContext = new DatabaseContext(); + var user = player.GetUser(dbContext); + + if ((user.FactionId != 1 && user.FactionId != 3) || !player.IsDuty()) + { + return; + } + + var vehicle = NAPI.Pools.GetAllVehicles().Where(v => v.Position.DistanceTo(player.Position) <= 5).OrderBy(v => v.Position.DistanceTo(player.Position)).FirstOrDefault(); + if (vehicle == null) + { + player.SendNotification("~r~Es befindet sich kein Fahrzeug in deiner Nähe"); + return; + } + + ServerVehicle serverVehicle = vehicle.GetServerVehicle(dbContext); + if (serverVehicle == null) + { + player.SendNotification("~r~Dieses Fahrzeug kann nicht durchsucht werden"); + return; + } + + if (VehicleStreaming.GetLockState(vehicle) || serverVehicle.Locked) + { + player.SendNotification("~r~Dieses Fahrzeug ist abgeschlossen"); + return; + } + + var targetItems = InventoryManager.GetVehicleItems(vehicle); + List illItemsList = new List(); + bool illegalItemsFound = false; + var price = 0; + + foreach (var targetItem in targetItems) + { + IItem item = InventoryManager.GetItemById(targetItem.ItemId); + if (!item.Legal) + { + illItemsList.Add($"{targetItem.Amount}x {item.Name}"); + InventoryManager.RemoveVehicleItem(serverVehicle, targetItem, targetItem.Amount, null); + illegalItemsFound = true; + price += ((IIllegalItem)item).PriceForConfiscation * targetItem.Amount; + logger.LogInformation("Player {0} confiscated the illegal item {1} ({2}, amount: {3}) from vehicle {4}", player.Name, item.Name, item.Id, targetItem.Amount, serverVehicle.Id); + } + } + + if (!illegalItemsFound) + { + player.SendNotification("~g~Im Kofferraum sind keine illegalen Gegenstände"); + return; + } + + logger.LogInformation("executive factions got {0} dollars from the confiscation", price); + + var factions = dbContext.Factions.Include(f => f.BankAccount).Where(f => f.Id == 1 || f.Id == 3); + foreach (var faction in factions) + { + faction.BankAccount.Balance += price; + } + + dbContext.SaveChanges(); + + string illItemsStr = "~y~" + string.Join("~s~,~y~ ", illItemsList) + "~s~"; + ChatService.SendInRange(player.Position, 20, $"{player.Name} hat aus dem Kofferraum folgende Gegenstände beschlagnahmt: {illItemsStr}"); + } + [RemoteEvent("CLIENT:InteractionMenu_Pay")] public void InteractionMenu_Pay(Player player, string jsonNameOrId, string stringAmount) { diff --git a/ReallifeGamemode.Server/Managers/InventoryManager.cs b/ReallifeGamemode.Server/Managers/InventoryManager.cs index aaa1b434..e8cfea56 100644 --- a/ReallifeGamemode.Server/Managers/InventoryManager.cs +++ b/ReallifeGamemode.Server/Managers/InventoryManager.cs @@ -47,7 +47,7 @@ namespace ReallifeGamemode.Server.Managers public int Amount; public int ItemId; public int Weight; - public Vehicle vehicle; + public ushort vehicle; } public static void SetBackpackItems(Player player) @@ -75,9 +75,9 @@ namespace ReallifeGamemode.Server.Managers player.SetSharedData("backpackItems", JsonConvert.SerializeObject(backpackItems[player].ToArray())); } - internal static IItem GetItem() where T : IItem + internal static T GetItem() where T : IItem { - return itemList.Where(i => i.GetType() == typeof(T)).First(); + return (T)itemList.Where(i => i.GetType() == typeof(T)).First(); } [RemoteEvent("CLIENT:getVehicleInventory")] @@ -86,7 +86,9 @@ namespace ReallifeGamemode.Server.Managers if (player.IsInVehicle) { player.TriggerEvent("Error", "Du kannst deinen Kofferraum gerade nicht öffnen."); + return; } + Vehicle veh = NAPI.Pools.GetAllVehicles() .ToList() .Where(v => v.Position.DistanceTo(player.Position) <= 4) @@ -131,7 +133,7 @@ namespace ReallifeGamemode.Server.Managers Amount = i.Amount, ItemId = i.ItemId, Weight = GetVehicleInventoryWeight(veh), - vehicle = veh, + vehicle = veh.Handle.Value, }; vehicleItems[player].Add(newItem); } @@ -197,6 +199,10 @@ namespace ReallifeGamemode.Server.Managers public static void RemoveVehicleItem(ServerVehicle sVeh, VehicleItem item, int amount, Player player) { + if (item == null) + { + return; + } using (var dbContext = new DatabaseContext()) { var vehicleItem = dbContext.VehicleItems.FirstOrDefault(i => i.Id == item.Id); @@ -327,20 +333,29 @@ namespace ReallifeGamemode.Server.Managers using (var context = new DatabaseContext()) { + User user = player.GetUser(context); if (!vehicleItems.ContainsKey(player)) vehicleItems.Add(player, new List()); Vehicle veh = null; if (vehicleItems[player].Count != 0) - veh = vehicleItems[player].FirstOrDefault().vehicle; + veh = new NetHandle(vehicleItems[player].FirstOrDefault().vehicle, EntityType.Vehicle).Entity(); ServerVehicle serverVehicle = VehicleManager.GetServerVehicleFromVehicle(veh, context); - VehicleItem vehItem = context.VehicleItems.Where(v => v.VehicleId == serverVehicle.Id && v.ItemId == itemID).FirstOrDefault(); if (vehItem == null) { player.TriggerEvent("Error", "Transfer nicht möglich."); return; } + if (serverVehicle is FactionVehicle factionVehicle) + { + IItem item = GetItemById(itemID); + if (factionVehicle.Model == VehicleHash.Riot && user.Faction?.StateOwned == true) + { + player.TriggerEvent("Error", "Transfer nicht möglich."); + return; + } + } RemoveVehicleItem(serverVehicle, vehItem, itemAmount, player); SetVehicleItems(player); From 48b4cc22a7564eac38a8bef4160a35d713a104af Mon Sep 17 00:00:00 2001 From: hydrant Date: Thu, 27 May 2021 21:12:44 +0200 Subject: [PATCH 10/10] fix merge --- ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs b/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs index 4a5bfe40..896ee597 100644 --- a/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs +++ b/ReallifeGamemode.Server/Inventory/Items/Notfallkit.cs @@ -46,18 +46,16 @@ namespace ReallifeGamemode.Server.Inventory.Items return false; } - if((VehicleHash)veh.Model == WeaponDealManager.WEAPON_DEAL_GANG_VEHICLE_HASH || (VehicleHash)veh.Model == WeaponDealManager.WEAPON_DEAL_STAATSFRAK_VEHICLE_HASH) + if ((VehicleHash)veh.Model == WeaponDealManager.WEAPON_DEAL_GANG_VEHICLE_HASH || (VehicleHash)veh.Model == WeaponDealManager.WEAPON_DEAL_STAATSFRAK_VEHICLE_HASH) { player.SendNotification("Du kannst den Waffentransporter nicht reparieren!"); - return false; + return false; } using (var dbContext = new DatabaseContext()) { Vector3 position = veh.Position; - player.SendNotification("Du hast ~g~" + InventoryManager.GetItemById(uItem.ItemId).Name + " ~s~verwendet", false); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); - InventoryManager.RemoveUserItem(player.GetUser(), uItem, 1); + player.SendNotification("Du hast ~g~" + Name + " ~s~verwendet", false); ServerVehicle serverVehicle = veh.GetServerVehicle(dbContext); serverVehicle.Spawn(veh).Position = position; Vehicle newVeh = serverVehicle.Spawn(veh);