diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 923e48b1..b76b47a1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,6 @@ variables: build: stage: build only: - - develop + - develop@log-gtav/reallife-gamemode script: - "dotnet build -c ServerBuild" diff --git a/Client/Gui/Inventory/inventory.js b/Client/Gui/Inventory/inventory.js new file mode 100644 index 00000000..4bb54c9b --- /dev/null +++ b/Client/Gui/Inventory/inventory.js @@ -0,0 +1,332 @@ +var show = false; +var trading = false; +const { x: screenX, y: screenY } = mp.game.graphics.getScreenActiveResolution(0, 0); +let rxC = 0.5; +let ryC = 0.5; +let rWidth = 0.4; +let sX = (screenX * 0.1 / 1000); +let sY = (screenY * 0.1 / 1000); +let eX = sX - 0.1; +let eY = sY - 0.1; +let sizeMul = 0.08; +let yMul = 1.8; + +var inventoryWeight; +var items = [[]]; + +var grid = []; +grid[0] = [0.3375, 0.305] +grid[1] = [0.4195, 0.305] +grid[2] = [0.5015, 0.305] +grid[3] = [0.5835, 0.305] +grid[4] = [0.6655, 0.305] +grid[5] = [0.3375, 0.455] +grid[6] = [0.4195, 0.455] +grid[7] = [0.5015, 0.455] +grid[8] = [0.5835, 0.455] +grid[9] = [0.6655, 0.455] +grid[10] = [0.3375, 0.605] +grid[11] = [0.4195, 0.605] +grid[12] = [0.5015, 0.605] +grid[13] = [0.5835, 0.605] +grid[14] = [0.6655, 0.605] +grid[15] = [0.3375, 0.755] +grid[16] = [0.4195, 0.755] +grid[17] = [0.5015, 0.755] +grid[18] = [0.5835, 0.755] +grid[19] = [0.6655, 0.755] + +var mouseLDown = false; +var mouseRDown = false; +var hoverItem; +var dragItem = null; +var oldDragSlot; +var actFreeSlot; +var bufferItem = []; +var stackToItem; + +mp.events.add("showInventory", (invWeight, itemArr) => { + if (show === false) { + mp.gui.chat.activate(false); + mp.gui.cursor.show(true, true); + inventoryWeight = invWeight; + items = itemArr; + show = true; + mp.game.graphics.requestStreamedTextureDict("itemimages", true); + } else { + mp.events.callRemote('saveInventory', JSON.stringify(items)); + mp.gui.chat.activate(true); + mp.gui.cursor.show(false, false); + show = false; + mp.game.graphics.setStreamedTextureDictAsNoLongerNeeded("itemimages"); + } +}); + +mp.events.add("addItem", (item) => { + items.push(item); +}); + +mp.events.add("render", () => { + if (show === true) { + var pos = mp.gui.cursor.position; + + mp.game.graphics.set2dLayer(1); + //INVENTARHINTERGRUND + mp.game.graphics.drawRect(rxC, ryC, 0.45, 0.7, 255, 255, 255, 200); + + mp.game.graphics.set2dLayer(2); + //INVENTARÜBERSCHRIFT + mp.game.graphics.drawText("Inventar ~g~(" + inventoryWeight + "/40000g)", [rxC, ryC - (rWidth / 1.20)], { + font: 7, + color: [112, 128, 144, 254], + scale: [0.7, 0.7], + outline: true, + }); + + //SLOTS [RECHTECKE] [SLOTZAHLEN] + var tempSlot; + for (var slots = 0; slots < grid.length; slots++) { + mp.game.graphics.drawRect(grid[slots][0], grid[slots][1], sizeMul, sizeMul * yMul, 112, 128, 144, 254); + mp.game.graphics.drawText(tempSlot = slots + 1, [grid[slots][0] - (sizeMul / 2) + 0.006, grid[slots][1] - (sizeMul / 2 * yMul)], { + font: 7, + color: [255, 69, 0, 254], + scale: [0.3, 0.3], + outline: true, + }); + } + + mp.game.graphics.set2dLayer(3); + //SPRITES + ITEMANZAHL + for (var currentItem = 0; currentItem < items.length; currentItem++) { + if (items[currentItem][4] !== "-1") { + mp.game.graphics.drawSprite("itemimages", items[currentItem][0].toLowerCase(), grid[parseInt(items[currentItem][4] - 1)][0], grid[parseInt(items[currentItem][4] - 1)][1], rWidth / 8, rWidth / 5, 0, 255, 255, 255, 255); + mp.game.graphics.drawText("(~y~" + items[currentItem][3] + "~s~)", [grid[parseInt(items[currentItem][4] - 1)][0] + (sizeMul / 2) - 0.008, grid[parseInt(items[currentItem][4] - 1)][1] + 0.05], { + font: 0, + color: [255, 255, 255, 255], + scale: [0.25, 0.25], + outline: true, + }); + } + } + + mp.game.graphics.set2dLayer(4); + //WENN MAUS ÜBER ITEM + if (isMouseOverItem(pos[0], pos[1]) && dragItem === null) { + mp.game.graphics.drawRect(pos[0] / screenX, pos[1] / screenY + 0.055, 0.14, 0.08, 0, 0, 0, 220); + + var hoverItemP = [items[hoverItem][0], items[hoverItem][1], items[hoverItem][2], items[hoverItem][3]]; + + //NAME + mp.game.graphics.drawText("~g~" + hoverItemP[0], [pos[0] / screenX, pos[1] / screenY + 0.02], { + font: 4, + color: [255, 255, 255, 255], + scale: [0.4, 0.4], + outline: true, + }); + + //BESCHREIBUNG + mp.game.graphics.drawText(hoverItemP[1], [pos[0] / screenX, pos[1] / screenY + 0.04], { + font: 4, + color: [255, 255, 255, 255], + scale: [0.35, 0.35], + outline: true, + }); + + //EINZELGEWICHT + mp.game.graphics.drawText("~y~" + hoverItemP[2] + "g~s~ * " + hoverItemP[3] + "~s~ = ~y~" + hoverItemP[2] * hoverItemP[3] + "g", [pos[0] / screenX, pos[1] / screenY + 0.06], { + font: 4, + color: [255, 255, 255, 255], + scale: [0.35, 0.35], + outline: true, + }); + } + + //WENN MOUSE DOWN + if (mouseLDown && dragItem !== null || mouseRDown && dragItem !== null) { + if (isMouseOverFreeSlot(pos[0], pos[1]) || isItemOverSameItem(pos[0], pos[1])) { + mp.game.graphics.drawSprite("itemimages", items[dragItem][0].toLowerCase(), pos[0] / screenX, pos[1] / screenY, rWidth / 8, rWidth / 5, 0, 100, 255, 100, 255); + } else { + mp.game.graphics.drawSprite("itemimages", items[dragItem][0].toLowerCase(), pos[0] / screenX, pos[1] / screenY, rWidth / 8, rWidth / 5, 0, 255, 100, 100, 255); + } + + } + } +}); + +function isMouseOverItem(cX, cY) { + + if (dragItem === null) { + + var x = cX / screenX; + var y = cY / screenY; + var a; + var b; + var c; + + for (var s = 0; s < 20; s++) { + a = grid[s][0] - x; + b = grid[s][1] - y; + c = Math.sqrt(a * a + b * b); + + var invSlot = (s + 1); + + if (c < sizeMul / 2) { + for (i = 0; i < items.length; i++) { + if (parseInt(items[i][4]) === invSlot) { + hoverItem = i; + return true; + } + } + } + } + } +} + +function isMouseOverFreeSlot(cX2, cY2) { + + var x = cX2 / screenX; + var y = cY2 / screenY; + var a; + var b; + var c; + + var isItemOnSlot = 0; + + for (var s = 0; s < 20; s++) { + a = grid[s][0] - x; + b = grid[s][1] - y; + c = Math.sqrt(a * a + b * b); + + var invSlot = (s + 1); + + if (c < sizeMul / 2) { + for (i = 0; i < items.length; i++) { + if (parseInt(items[i][4]) === invSlot) { + isItemOnSlot++; + } + } + if (isItemOnSlot === 0) { + actFreeSlot = s + 1; + return true; + } + } + } +} + +function isItemOverSameItem(cX2, cY2) { + + if (dragItem !== null) { + + var x = cX2 / screenX; + var y = cY2 / screenY; + var a; + var b; + var c; + + for (var s = 0; s < 20; s++) { + a = grid[s][0] - x; + b = grid[s][1] - y; + c = Math.sqrt(a * a + b * b); + + var invSlot = (s + 1); + + if (c < sizeMul / 2) { + for (i = 0; i < items.length; i++) { + if (items[dragItem][0] === items[i][0] && parseInt(items[i][4]) === invSlot && items[hoverItem][4] !== items[i][4]) { + stackToItem = i; + return true; + } + } + } + } + } +} + +mp.events.add('click', (x, y, upOrDown, leftOrRight, relativeX, relativeY, worldPosition, hitEntity) => { + + var cX = x / screenX; + var cY = y / screenY; + + if (show) { + //LINKE MAUSTASTE + //RUNTER + if (upOrDown === "down" && leftOrRight === "left" && mouseLDown === false && mouseRDown === false) { + + mouseLDown = true; + + if (isMouseOverItem(x, y) && dragItem === null) { + dragItem = hoverItem; + oldDragSlot = items[dragItem][4]; + items[dragItem][4] = "-1"; + } + } + + //HOCH + if (upOrDown === "up" && leftOrRight === "left" && mouseLDown === true) { + + mouseLDown = false; + + if (dragItem !== null) { + if (isMouseOverFreeSlot(x, y)) { + items[dragItem][4] = actFreeSlot; + oldDragSlot = null; + dragItem = null; + hoverItem = null; + } else if (isItemOverSameItem(x, y)) { + var newAmount = parseInt(items[stackToItem][3]) + parseInt(items[dragItem][3]); + items[stackToItem][3] = newAmount.toString(); + items[dragItem][4] = "-1"; + dragItem = null; + hoverItem = null; + } else { + items[dragItem][4] = oldDragSlot; + dragItem = null; + hoverItem = null; + } + } + } + + //RECHTE MAUSTASTE + //RUNTER + if (upOrDown === "down" && leftOrRight === "right" && mouseLDown === false && mouseRDown === false) { + + mouseRDown = true; + + if (isMouseOverItem(x, y) && dragItem === null) { + dragItem = hoverItem; + oldDragSlot = items[hoverItem][4]; + bufferItem = [items[hoverItem][0], items[hoverItem][1], items[hoverItem][2], items[hoverItem][3], items[hoverItem][4], items[hoverItem][5]]; + items[hoverItem][3]--; + } + } + + //HOCH + if (upOrDown === "up" && leftOrRight === "right" && mouseRDown === true) { + + mouseRDown = false; + + if (dragItem !== null) { + if (isMouseOverFreeSlot(x, y)) { + + items.push([items[dragItem][0], items[dragItem][1], items[dragItem][2], "1", actFreeSlot.toString(), "-1"]); + if (items[hoverItem][3] === 0) { + items[hoverItem][4] = "-1"; + } + dragItem = null; + hoverItem = null; + } else if (isItemOverSameItem(x, y)) { + items[stackToItem][3]++; + items[hoverItem][4] = "-1"; + bufferItem = null; + dragItem = null; + hoverItem = null; + } else { + items[hoverItem][3]++; + bufferItem = null; + dragItem = null; + hoverItem = null; + } + } + } + } +}); \ No newline at end of file diff --git a/Client/Player/keys.js b/Client/Player/keys.js index 61d7134e..91ec623b 100644 --- a/Client/Player/keys.js +++ b/Client/Player/keys.js @@ -7,6 +7,7 @@ //https://docs.microsoft.com/de-de/windows/desktop/inputdev/virtual-key-codes var chat = false; +var showInventory = false; var showGui = true; const player = mp.players.local; @@ -43,11 +44,18 @@ mp.keys.bind(0x45, false, function () { }); -//I //Spielerliste +//I //Inventar mp.keys.bind(0x49, false, function () { if (!chat) { - mp.events.callRemote("keyPress:I"); - //mp.events.call("showPlayerlist"); + mp.events.callRemote("keyPress:I"); + } +}); + +//J //Spielerliste +mp.keys.bind(0x4A, false, function () { + if (!chat) { + mp.events.callRemote("keyPress:J"); + //mp.events.call("showPlayerlist"); } }); diff --git a/Client/dlcpacks/itemimages/dlc.rpf b/Client/dlcpacks/itemimages/dlc.rpf new file mode 100644 index 00000000..d05c6a2a --- /dev/null +++ b/Client/dlcpacks/itemimages/dlc.rpf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcf279344c11eb9eac1801e56e6fa11172e577ff415363338c5f38d2d1152b31 +size 33792 diff --git a/Client/index.js b/Client/index.js index cc734b4f..9d437a43 100644 --- a/Client/index.js +++ b/Client/index.js @@ -21,6 +21,7 @@ require('./Gui/deathscreen.js'); require('./Gui/infobox.js'); require('./Gui/nametags.js'); require('./Gui/playerlist.js'); +require('./Gui/Inventory/inventory.js'); require('./Login/main.js'); diff --git a/Main.cs b/Main.cs index 210519ef..3f03b549 100644 --- a/Main.cs +++ b/Main.cs @@ -35,6 +35,11 @@ namespace reallife_gamemode NAPI.Server.SetAutoRespawnAfterDeath(false); NAPI.Data.SetWorldData("playerCreatorDimension", 0); + + InventoryManager.LoadItems(); + TuningManager.AddTuningGarage(new Vector3(-341, -134, 38.5)); + TuningManager.AddTuningGarage(new Vector3(732, -1088, 21)); + TuningManager.AddTuningGarage(new Vector3(-1155, -2006, 12)); TuningManager.AddTuningGarage(new Vector3(-341, -134, 38.5)); // Downtown LS TuningManager.AddTuningGarage(new Vector3(732, -1088, 21)); // LS Intersection TuningManager.AddTuningGarage(new Vector3(-1155, -2006, 12)); // LS Airport @@ -47,6 +52,7 @@ namespace reallife_gamemode FactionHelper.CheckFactionBankAccounts(); BusinessManager.LoadBusinesses(); + TempBlip tempBlip = new TempBlip() { Color = 1, diff --git a/Model/DatabaseContext.cs b/Model/DatabaseContext.cs index 3d393416..467accd5 100644 --- a/Model/DatabaseContext.cs +++ b/Model/DatabaseContext.cs @@ -57,6 +57,9 @@ namespace reallife_gamemode.Model public DbSet UserBankAccounts { get; set; } + //Inventar + public DbSet UserItems { get; set; } + //Faction public DbSet Factions { get; set; } public DbSet FactionBankAccounts { get; set; } diff --git a/Server/Commands/Admin.cs b/Server/Commands/Admin.cs index 6e5905ca..1fdf724d 100644 --- a/Server/Commands/Admin.cs +++ b/Server/Commands/Admin.cs @@ -14,6 +14,8 @@ using reallife_gamemode.Server.Extensions; using reallife_gamemode.Server.Services; using reallife_gamemode.Server.Util; using reallife_gamemode.Server.Managers; +using reallife_gamemode.Server.Inventory.Items; +using reallife_gamemode.Server.Inventory.Interfaces; using reallife_gamemode.Server.Saves; using reallife_gamemode.Server.Business; using System.Text.RegularExpressions; @@ -28,6 +30,74 @@ namespace reallife_gamemode.Server.Commands { public class Admin : Script { + [Command("eat", "~m~Benutzung: ~s~/eat [Item]")] + public void CmdAdminEat(Client player, string item) + { + if (!player.GetUser()?.IsAdmin(AdminLevel.SUPPORTER) ?? true) + { + ChatService.NotAuthorized(player); + return; + } + + IItem iItem = InventoryManager.GetItemByName(item); + + if(iItem == null) + { + player.SendChatMessage("Dieses Essen existiert nicht."); + return; + } + + List itemList = player.GetUser().GetItems(); + UserItem eatItem = itemList.FirstOrDefault(i => i.ItemId == iItem.Id); + + if(eatItem == null) + { + player.SendChatMessage("Du hast dieses Item nicht"); + return; + } + + if(iItem is IUsableItem usableItemObj) + { + usableItemObj.Use(eatItem, player); + } + } + [Command("myitems")] + public void CmdAdminMyItems(Client player) + { + if (!player.GetUser()?.IsAdmin(AdminLevel.SUPPORTER) ?? true) + { + ChatService.NotAuthorized(player); + return; + } + + List itemList = player.GetUser().GetItems(); + + foreach (var item in itemList) + { + IItem iitem = InventoryManager.GetItemById(item.ItemId); + player.SendChatMessage("Item: ~g~" + item.Amount + " " + iitem.Name); + } + } + + [Command("giveitem", "~m~Benutzung: ~s~/giveitem [Target] [Item ID] [Anzahl]")] + public void CmdAdminGiveItem(Client player, string targetname, int itemId, int amount) + { + if (!player.GetUser()?.IsAdmin(AdminLevel.SUPPORTER) ?? true) + { + ChatService.NotAuthorized(player); + return; + } + + Client target = ClientService.GetClientByNameOrId(targetname); + if (target == null || !target.IsLoggedIn()) + { + ChatService.PlayerNotFound(player); + return; + } + + UserItem item = new UserItem() { ItemId = itemId, UserId = target.GetUser().Id, Amount = amount}; + InventoryManager.AddItemToInventory(target, item); + } #region Support [Command("o", "~m~Benutzung: ~s~/o [Nachricht]", GreedyArg = true)] diff --git a/Server/Entities/User.cs b/Server/Entities/User.cs index a19a9857..64b7b576 100644 --- a/Server/Entities/User.cs +++ b/Server/Entities/User.cs @@ -3,6 +3,7 @@ using reallife_gamemode.Model; using reallife_gamemode.Server.Extensions; using reallife_gamemode.Server.Util; using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; @@ -131,6 +132,13 @@ namespace reallife_gamemode.Server.Entities } } + public List GetItems() + { + using(var dbContext = new DatabaseContext()) + { + return dbContext.UserItems.ToList().FindAll(u => u.UserId == this.Id); + } + } public bool IsAdmin(AdminLevel level) => AdminLevel >= level; public IBankAccount GetBankAccount(DatabaseContext databaseContext = null) diff --git a/Server/Entities/UserItem.cs b/Server/Entities/UserItem.cs new file mode 100644 index 00000000..4a80faed --- /dev/null +++ b/Server/Entities/UserItem.cs @@ -0,0 +1,34 @@ +using GTANetworkAPI; +using reallife_gamemode.Model; +using reallife_gamemode.Server.Util; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; + +/** +* @overview Life of German Reallife - Entities UserItem (UserItem.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Entities +{ + public class UserItem + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; set; } + + public int ItemId { get; set; } + + [ForeignKey("User")] + public int UserId { get; set; } + public User User { get; set; } + + public int Amount { get; set; } + public int Slot { get; set; } + } +} \ No newline at end of file diff --git a/Server/Events/Key.cs b/Server/Events/Key.cs index c96507ea..9d881657 100644 --- a/Server/Events/Key.cs +++ b/Server/Events/Key.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json; using reallife_gamemode.Model; using reallife_gamemode.Server.Entities; using reallife_gamemode.Server.Extensions; +using reallife_gamemode.Server.Inventory.Interfaces; using reallife_gamemode.Server.Managers; using reallife_gamemode.Server.Saves; using reallife_gamemode.Server.Services; @@ -24,7 +25,8 @@ namespace reallife_gamemode.Server.Events [RemoteEvent("keyPress:NUM2")] public void KeyPressNUM2(Client player) { - if(player.GetData("editmode") == true && player.GetUser().IsAdmin(AdminLevel.HEADADMIN) == true) + if (!player.IsLoggedIn()) return; + if (player.GetData("editmode") == true && player.GetUser().IsAdmin(AdminLevel.HEADADMIN) == true) { TempBlip tempBlip = NAPI.Data.GetWorldData("blipTemplate"); SaveManager.OnSaveBlipData(player, tempBlip.Sprite.ToString(), tempBlip.Name, tempBlip.Scale.ToString(), tempBlip.Color.ToString(), @@ -35,6 +37,7 @@ namespace reallife_gamemode.Server.Events [RemoteEvent("keyPress:E")] public void KeyPressE(Client player) { + if (!player.IsLoggedIn()) return; var user = player.GetUser(); if (user?.FactionId != null) { @@ -107,6 +110,13 @@ namespace reallife_gamemode.Server.Events [RemoteEvent("keyPress:I")] public void KeyPressI(Client player) { + if (!player.IsLoggedIn()) return; + InventoryManager.GetUserItems(player); + } + [RemoteEvent("keyPress:J")] + public void KeyPressJ(Client player) + { + if (!player.IsLoggedIn()) return; List players = NAPI.Pools.GetAllPlayers(); List ListPlayers = new List(); @@ -122,10 +132,11 @@ namespace reallife_gamemode.Server.Events ListPlayers.Add(lPlayer); } player.TriggerEvent("fetchPlayerList", JsonConvert.SerializeObject(ListPlayers)); - } + } [RemoteEvent("keyPress:K")] public void KeyPressK(Client player) { + if (!player.IsLoggedIn()) return; var user = player.GetUser(); if (user?.FactionId != null) { @@ -178,11 +189,13 @@ namespace reallife_gamemode.Server.Events [RemoteEvent("keyPress:L")] public void KeyPressL(Client player) { + if (!player.IsLoggedIn()) return; DoorManager.ChangeDoorState(player); } [RemoteEvent("keyPress:N")] public void KeyPressN(Client player) { + if (!player.IsLoggedIn()) return; if (player.IsInVehicle && player.VehicleSeat == -1) { Vehicle v = player.Vehicle; @@ -192,6 +205,7 @@ namespace reallife_gamemode.Server.Events [RemoteEvent("keyPress:X")] public void KeyPressX(Client player) { + if (!player.IsLoggedIn()) return; if (player.IsInVehicle) { player.Seatbelt = !player.Seatbelt; diff --git a/Server/Events/Login.cs b/Server/Events/Login.cs index 7d9b5f0e..5f165c59 100644 --- a/Server/Events/Login.cs +++ b/Server/Events/Login.cs @@ -56,34 +56,9 @@ namespace reallife_gamemode.Server.Events var userBankAccount = loginUser.UserBankAccounts.SingleOrDefault(u => u.UserId == user.Id); userBankAccount.Balance = userBankAccount.Balance; - if (user.Dead == true) - { - if (user.IsAdmin(AdminLevel.ADMIN) == true) - { - player.TriggerEvent("startDeathTimer", true); - } - else - { - player.TriggerEvent("startDeathTimer", false); - } - - player.SetData("isDead", true); - } - else - { - player.SetData("isDead", false); - } - if (user.Dead == true) - { - //player.TriggerEvent("startDeathTimer"); - //player.SetData("isDead", true); - //TODO: Deathlog entfernen - player.Health = 0; - } - else - { - player.SetData("isDead", false); - } + var userItems = loginUser.UserItems.ToList().FindAll(u => u.UserId == user.Id); + player.SetData("items", userItems); + if (user.CharacterId == null) { var currentPlayerCreatorDimension = (uint) NAPI.Data.GetWorldData("playerCreatorDimension"); @@ -100,6 +75,24 @@ namespace reallife_gamemode.Server.Events NAPI.Player.SpawnPlayer(player, new Vector3(user.PositionX, user.PositionY, user.PositionZ), 0); player.TriggerEvent("draw", player.Name, player.Handle.Value); } + if (user.Dead == true) + { + if (user.IsAdmin(AdminLevel.ADMIN) == true) + { + player.TriggerEvent("startDeathTimer", true); + player.Health = 0; + } + else + { + player.TriggerEvent("startDeathTimer", false); + player.Health = 0; + } + player.SetData("isDead", true); + } + else + { + player.SetData("isDead", false); + } } } } diff --git a/Server/Inventory/Interfaces/IDroppableItem.cs b/Server/Inventory/Interfaces/IDroppableItem.cs new file mode 100644 index 00000000..b854ec5a --- /dev/null +++ b/Server/Inventory/Interfaces/IDroppableItem.cs @@ -0,0 +1,18 @@ +using GTANetworkAPI; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Interfaces DroppableItem (IDroppableItem.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Interfaces +{ + public interface IDroppableItem + { + void Drop(Client player); + } +} diff --git a/Server/Inventory/Interfaces/IItem.cs b/Server/Inventory/Interfaces/IItem.cs new file mode 100644 index 00000000..10222cc2 --- /dev/null +++ b/Server/Inventory/Interfaces/IItem.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Interfaces Item (IItem.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Interfaces +{ + public interface IItem + { + int Id { get; } + string Name { get; } + string Description { get; } + int Gewicht { get; } + string Einheit { get; } + } +} diff --git a/Server/Inventory/Interfaces/IUsableItem.cs b/Server/Inventory/Interfaces/IUsableItem.cs new file mode 100644 index 00000000..d89d5293 --- /dev/null +++ b/Server/Inventory/Interfaces/IUsableItem.cs @@ -0,0 +1,19 @@ +using GTANetworkAPI; +using reallife_gamemode.Server.Entities; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Interfaces UsableItem (IUsableItem.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Interfaces +{ + public interface IUsableItem + { + void Use(UserItem uItem, Client player); + } +} diff --git a/Server/Inventory/Items/Cheeseburger.cs b/Server/Inventory/Items/Cheeseburger.cs new file mode 100644 index 00000000..d311b348 --- /dev/null +++ b/Server/Inventory/Items/Cheeseburger.cs @@ -0,0 +1,23 @@ +using reallife_gamemode.Server.Inventory.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Items Cheeseburger (Cheeseburger.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Items +{ + public class Cheeseburger : FoodItem, IItem + { + public int Id => 2; + public string Name => "Cheeseburger"; + public string Description => "Wie der Hamburger, nur mit Käse."; + public int Gewicht => 320; + public string Einheit => "g"; + public override int HpAmount => 20; + } +} diff --git a/Server/Inventory/Items/Chickenburger.cs b/Server/Inventory/Items/Chickenburger.cs new file mode 100644 index 00000000..7e51af38 --- /dev/null +++ b/Server/Inventory/Items/Chickenburger.cs @@ -0,0 +1,23 @@ +using reallife_gamemode.Server.Inventory.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Items Chickenburger (Chickenburger.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Items +{ + public class Chickenburger : FoodItem, IItem + { + public int Id => 3; + public string Name => "Chickenburger"; + public string Description => "Hühnchenburger"; + public int Gewicht => 330; + public string Einheit => "g"; + public override int HpAmount => 25; + } +} diff --git a/Server/Inventory/Items/FoodItem.cs b/Server/Inventory/Items/FoodItem.cs new file mode 100644 index 00000000..699ef857 --- /dev/null +++ b/Server/Inventory/Items/FoodItem.cs @@ -0,0 +1,23 @@ +using GTANetworkAPI; +using reallife_gamemode.Server.Entities; +using reallife_gamemode.Server.Extensions; +using reallife_gamemode.Server.Inventory.Interfaces; +using reallife_gamemode.Server.Managers; +using System; +using System.Collections.Generic; +using System.Text; + +namespace reallife_gamemode.Server.Inventory.Items +{ + public abstract class FoodItem : IUsableItem + { + public abstract int HpAmount { get; } + + public void Use(UserItem uItem, Client player) + { + player.Health += HpAmount; + player.SendChatMessage("Du hast einen ~y~" + InventoryManager.GetItemById(uItem.ItemId).Name + " ~s~gegessen."); + InventoryManager.RemoveUserItem(player.GetUser(), uItem); + } + } +} diff --git a/Server/Inventory/Items/Hamburger.cs b/Server/Inventory/Items/Hamburger.cs new file mode 100644 index 00000000..be39522b --- /dev/null +++ b/Server/Inventory/Items/Hamburger.cs @@ -0,0 +1,23 @@ +using reallife_gamemode.Server.Inventory.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Items Hamburger (Hamburger.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Items +{ + public class Hamburger : FoodItem, IItem + { + public int Id => 1; + public string Name => "Hamburger"; + public string Description => "Ein leckerer Hamburger."; + public int Gewicht => 300; + public string Einheit => "g"; + public override int HpAmount => 20; + } +} diff --git a/Server/Inventory/Items/Holz.cs b/Server/Inventory/Items/Holz.cs new file mode 100644 index 00000000..947969ad --- /dev/null +++ b/Server/Inventory/Items/Holz.cs @@ -0,0 +1,23 @@ +using reallife_gamemode.Server.Inventory.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Items Hamburger (Hamburger.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Items +{ + public class Holz : FoodItem, IItem + { + public int Id => 4; + public string Name => "Holz"; + public string Description => "Ich und mein Holz."; + public int Gewicht => 1000; + public string Einheit => "g"; + public override int HpAmount => 20; + } +} diff --git a/Server/Inventory/Items/Kraftstoff.cs b/Server/Inventory/Items/Kraftstoff.cs new file mode 100644 index 00000000..7b67b72f --- /dev/null +++ b/Server/Inventory/Items/Kraftstoff.cs @@ -0,0 +1,23 @@ +using reallife_gamemode.Server.Inventory.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +/** +* @overview Life of German Reallife - Inventory Items Hamburger (Hamburger.cs) +* @author VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Inventory.Items +{ + public class Kraftstoff : FoodItem, IItem + { + public int Id => 5; + public string Name => "Kraftstoff"; + public string Description => "Der Stoff gibt dir Kraft."; + public int Gewicht => 1000; + public string Einheit => "g"; + public override int HpAmount => 20; + } +} diff --git a/Server/Managers/InventoryManager.cs b/Server/Managers/InventoryManager.cs new file mode 100644 index 00000000..1d60fa4f --- /dev/null +++ b/Server/Managers/InventoryManager.cs @@ -0,0 +1,173 @@ +using GTANetworkAPI; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using reallife_gamemode.Model; +using reallife_gamemode.Server.Commands; +using reallife_gamemode.Server.Entities; +using reallife_gamemode.Server.Extensions; +using reallife_gamemode.Server.Inventory.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; + +/** +* @overview Life of German Reallife - Managers InventoryManager (InventoryManager.cs) +* @author hydrant, VegaZ +* @copyright (c) 2008 - 2018 Life of German +*/ + +namespace reallife_gamemode.Server.Managers +{ + public class InventoryManager : Script + { + public static List itemList; + + public static void LoadItems() + { + itemList = new List(); + + Type[] allTypes = Assembly.GetExecutingAssembly().GetTypes(); + foreach (Type item in allTypes) + { + if (item.GetInterfaces().Contains((typeof(IItem)))) + { + NAPI.Util.ConsoleOutput($"Loading Item {item.Name}"); + if (Activator.CreateInstance(item) is IItem o) + { + if (GetItemById(o.Id) != null) + { + throw new InvalidOperationException($"Double ItemID found: {o.Id} | {o.Name}"); + } + itemList.Add(o); + } + } + } + } + + public static IItem GetItemById(int id) + { + return itemList.Find(i => i.Id == id); + } + + public static IItem GetItemByName(string name) + { + return itemList.Find(i => i.Name.ToLower() == name.ToLower()); + } + + public static void RemoveUserItem(Entities.User user, UserItem item) + { + using (var dbContext = new DatabaseContext()) + { + var userItem = dbContext.UserItems.FirstOrDefault(i => i.Id == item.Id); + + userItem.Amount--; + + dbContext.SaveChanges(); + + if (userItem.Amount == 0) + { + dbContext.Remove(userItem); + dbContext.SaveChanges(); + } + } + } + + public static void GetUserItems(Client player) + { + var user = player.GetUser(); + var inventoryWeight = 0; + + using (var context = new DatabaseContext()) + { + List userItems = context.UserItems.ToList().FindAll(i => i.UserId == user.Id); + string[][] items = new string[userItems.Count][]; + foreach (var item in userItems) + { + IItem iItem = GetItemById(item.ItemId); + var currentItemWeight = iItem.Gewicht * item.Amount; + inventoryWeight += currentItemWeight; + + items[userItems.IndexOf(item)] = new string[6]; + items[userItems.IndexOf(item)][0] = iItem.Name; + items[userItems.IndexOf(item)][1] = iItem.Description; + items[userItems.IndexOf(item)][2] = iItem.Gewicht.ToString(); + items[userItems.IndexOf(item)][3] = item.Amount.ToString(); + items[userItems.IndexOf(item)][4] = item.Slot.ToString(); + items[userItems.IndexOf(item)][5] = item.Id.ToString(); + } + player.TriggerEvent("showInventory", inventoryWeight, items); + } + } + + [RemoteEvent("saveInventory")] + public void SavePlayerInventory(Client player, string itemArray) + { + + var user = player.GetUser(); + var items = JsonConvert.DeserializeObject(itemArray); + + //player.SendChatMessage(items); + + using (var context = new DatabaseContext()) + { + for (var i = 0; i < items.Length; i++) + { + UserItem cItem = new UserItem + { + Amount = int.Parse(items[i][3]), + ItemId = GetItemByName(items[i][0]).Id, + UserId = user.Id, + Slot = int.Parse(items[i][4]), + }; + + if (int.Parse(items[i][5]) == -1) + { + context.UserItems.Add(cItem); + } + else if (cItem.Slot == -1) + { + UserItem fItem = context.UserItems.FirstOrDefault(j => j.Id == int.Parse(items[i][5])); + context.UserItems.Remove(fItem); + } + else + { + UserItem fItem = context.UserItems.FirstOrDefault(j => j.Id == int.Parse(items[i][5])); + fItem.Amount = cItem.Amount; + fItem.Slot = cItem.Slot; + } + } + context.SaveChanges(); + } + } + + public static void AddItemToInventory(Client player, UserItem item) + { + var user = player.GetUser(); + using (var context = new DatabaseContext()) + { + + + List allItemsByUser = context.UserItems.ToList().FindAll(i => i.UserId == user.Id); + var slotArr = Enumerable.Range(1, 20).ToList(); + allItemsByUser.ForEach(allItem => + { + if (slotArr.Contains(allItem.Slot)) slotArr.Remove(allItem.Slot); + }); + + int newSlot = slotArr.Min(); + + item.Slot = newSlot; + context.UserItems.Add(item); + context.SaveChanges(); + + IItem iItem = GetItemById(item.ItemId); + + string[] newItem = new string[] { iItem.Name, iItem.Description, iItem.Gewicht.ToString(), item.Amount.ToString(), newSlot.ToString(), item.Id.ToString()}; + + player.TriggerEvent("addItem", newItem); + } + } + } +} diff --git a/reallife-gamemode.csproj b/reallife-gamemode.csproj index c1c40cc7..4d431f2e 100644 --- a/reallife-gamemode.csproj +++ b/reallife-gamemode.csproj @@ -6,6 +6,14 @@ true true + + + + + + Always + +