Увидел что одному форумчанину нужна помощь и он не представляет за что браться и как создать инвентарь, я сам с таким когда то столкнулся и решил написать тему по созданию простого инвентаря, сам мучался когда то, но умнее этого пока в голову не пришло...
За помощь в создание инвентаря очень благодарен Coveragt, спасибо тебе друг)
Отдельное спасибо Mip & Pesok, тоже многому меня научили и подсказали, реально классные пацаны)
p.s
Это не бестпрактис, за достойную критику ставлю лайк
А за ошибки в орфографии будьте добры не писать
Сразу вставляю видеоролик чтоб не тратить ваше время, кому не интересен данный результат
И так открываем среду разработки, у меня это Rider но роли не играет, надеюсь у вас все настроено
Создаем в Server side проекте, директорию Inventory, внутри нее создаем директорию Items, это будут наши предметы
Начнем с абстрактного класса Item, создаем его и добавляем нужные нам поля
Прежде чем создать даже элементарный бургер, нам понадобится еще пару классов)
Класс Util статический, для получения инвентаря игрока, в следующем фрагменте будет использоваться, они взаимосвязаны, поэтому без разницы что первое будете читать, Util.cs || Inventory.cs
Теперь инвентарь, управление, здесь у нас будет лут игрока и лут который на всем сервере
Inventory.cs
Думаю понятно
Не отходя от кассы давайте создадим бургер, люблю зингеры)
И так новая директория в директории Inventory будет называться Food
Внутри создаем класс Burger который реализует : Item
Подобнее проворачиваем с колой) кудаж бургер без колы
Теперь нам нужно будет проициализировать инвентарь игрока, чтоб он имелся и можно было взаимодействовать, в любой cs файл который наследуется от Script на стороне сервера, мы добавим
Ну и остался последний штрих, тк мы не юзаем фронт, то все будет через Command , новый файл LootManager : Script , сразу наследуемся от Script
За помощь в создание инвентаря очень благодарен Coveragt, спасибо тебе друг)
Отдельное спасибо Mip & Pesok, тоже многому меня научили и подсказали, реально классные пацаны)
p.s
Это не бестпрактис, за достойную критику ставлю лайк
А за ошибки в орфографии будьте добры не писать
Сразу вставляю видеоролик чтоб не тратить ваше время, кому не интересен данный результат
И так открываем среду разработки, у меня это Rider но роли не играет, надеюсь у вас все настроено
Создаем в Server side проекте, директорию Inventory, внутри нее создаем директорию Items, это будут наши предметы
Начнем с абстрактного класса Item, создаем его и добавляем нужные нам поля
C#:
using GTANetworkAPI;
namespace RageMP.Server.Inventory
{
public abstract class Item
{
public abstract string IconName { get; set; } // имя иконки которая будет отображаться на фронте
public abstract string Description { get; set; } // описание для фронта
public abstract string Name { get; set; } // имя нашего предмета
public abstract int Size { get; set; } // размер предмета, сколько он будет занимать слотов, если у вас будет грид сетка, я думаю вам нужно будет 2 переменные, сайз по вертикали и сайз по горизонтали
public abstract int Amount { get; set; } // чтобы в будущем стакать предметы
public abstract uint SpawnObjectHash { get; set; } // хеш объекта который будет спавниться на земле
public abstract void Use(Player player, int indexRemove); // действие, если это гамбургер то здесь запускается анимация, добавляются какие либо игроку свойства, например сытость +15, все увидете позже, ну и естественно удаление предмета или выдача физического оружия если это оружие
}
}
Класс Util статический, для получения инвентаря игрока, в следующем фрагменте будет использоваться, они взаимосвязаны, поэтому без разницы что первое будете читать, Util.cs || Inventory.cs
C#:
public static class Util
{
//получение инвентаря игрока
public static Inventory GetPlayerInventory(Player player)
{
return player.GetData<Inventory>(nameof(Inventory));
}
//из объекта гта5 который на полу лежит, физический, достать Item
public static Item GetObjectItem(Object obj)
{
return obj.GetData<Item>(nameof(Item));
}
//в радиусе найти ближайшие объекты
public static List<Object> GetObjectsInRadiusOfPosition(double radius, Vector3 position, uint dim)
{
return NAPI.Pools.GetAllObjects().Where(p => p.Dimension == dim).Where(FilterByRadius).ToList();
bool FilterByRadius(Object customObject)
{
if (customObject != null)
{
return Math.Pow(position.X - customObject.Position.X, 2.0) +
Math.Pow(position.Y - customObject.Position.Y, 2.0) +
Math.Pow(position.Z - customObject.Position.Z, 2.0) < Math.Pow(radius, 2.0);
}
return false;
}
}
}
Теперь инвентарь, управление, здесь у нас будет лут игрока и лут который на всем сервере
Inventory.cs
C#:
public class Inventory
{
public List<Item> Items { get; set; } = new List<Item>(); // player inventory
public static List<Item> LootServer = new List<Item>(); // server inventory
//Когда игрок забирает с пола, мы удаляем из коллекции, по индексу
public static void RemoveLootObject(int index)
{
LootServer.RemoveAt(index);
}
//Когда игрок выкидывает на пол то заспавнить объект + положить внутрь листа нашего
public static Object SpawnLootObject(Vector3 position, Item item, uint dim = 0)
{
LootServer.Add(item);
var obj = NAPI.Object.CreateObject(item.SpawnObjectHash, position + new Vector3(0f, 0f, -0.90f),
new Vector3(90f, 90f, 90f),
255, 0);
obj.SetData(nameof(Item), item);
obj.SetData("dataNameItem", NAPI.TextLabel.CreateTextLabel(item.Name,
position + new Vector3(0f, 0f, -0.55f), 2.0f, 0.1f, 4,
new Color(255, 255, 255), true, 0));
obj.GetData<TextLabel>("dataNameItem").Text = item.Name;
return obj;
}
// находим объекты в радиусе 1.5 метра, получаем инвентарь игрока, проверки индекса, можете их удалить и свои проверки, я кста вообще здесь минимум делал проверок во всем коде, что не есть хорошо но у вас свои ручки и напишите решение
public void pickItem(Player player, int index)
{
var objects = Util.GetObjectsInRadiusOfPosition(1.5, player.Position, player.Dimension);
var Items = Util.GetPlayerInventory(player).Items;
if (index >= 0 && index < objects.Count && objects.ElementAt(index) != null)
{
var obj = objects.ElementAt(index);
if (obj == null || obj.IsNull || !obj.Exists) // жоская проверка на null XD
{
Console.Write("Object is null");
return;
}
var item = Util.GetObjectItem(obj);
Items.Add(item);
RemoveLootObject(index);
obj.GetData<GTANetworkAPI.TextLabel>("dataNameItem").Text = "";
obj.Delete();
updateIndexItems();
}
}
public void spawnItem(Player player, int index)
{
Item item = null;
switch (index)
{
case 1:
item = new Burger();
break;
case 2:
item = new Cola();
break;
default:
player.SendNotification("~r~Предмет не найден с данным индексом!");
return;
}
SpawnLootObject(player.Position, item);
}
//выкидываем на пол + спавним объект, у себя удаляем а в лист сервера добавляем
public void dropItem(Player player, int index)
{
var Items = Util.GetPlayerInventory(player).Items;
RageMP.Server.Inventory.Inventory.SpawnLootObject(player.Position, Items[index]);
Items.RemoveAt(index);
updateIndexItems();
}
public void checkMyInventory(Player player)
{
var inventory = Util.GetPlayerInventory(player);
int i = 0;
player.SendChatMessage("--------------------");
foreach (var item in inventory.Items)
{
player.SendChatMessage($"~g~Your: {item.Name} [{i++}]");
}
player.SendChatMessage("--------------------");
}
public void updateIndexItems()
{
Items = Items.Where(x => x != null).ToList(); // иногда индекс сбивается и по 0 уже ничего нет, начинается с 1, такой вот костыль
}
}
|
Не отходя от кассы давайте создадим бургер, люблю зингеры)
И так новая директория в директории Inventory будет называться Food
Внутри создаем класс Burger который реализует : Item
C#:
public class Burger : Item
{
public override string IconName { get; set; } = "Burger.png";
public override string Description { get; set; } = "Увеличивает сытость на 15%";
public override string Name { get; set; } = "Большой бургер";
public override int Size { get; set; } = 1;
public override int Amount { get; set; } = 1; // Текущее кол-во бургеров, чтоб стакать
public override uint SpawnObjectHash { get; set; } = 2240524752;
public override void Use(Player player, int indexRemove)
{
player.PlayAnimation("mp_player_inteat@burger", "mp_player_int_eat_burger", 49);
var inven = Util.GetPlayerInventory(player);
if (inven.Items[indexRemove] != null && indexRemove >= 0 && inven.Items.Count > indexRemove)
{
if (inven.Items[indexRemove].Name.Length > 0)
{
inven.Items.RemoveAt(indexRemove);
}
}
NAPI.Task.Run(() =>
{
if (player.GetData<int>("eatIcon") + 15 > 100)
{
player.SetData("eatIcon", 100);
} else {
player.SetData("eatIcon", player.GetData<int>("eatIcon") + 15);
}
player.SendNotification("~g~Сыт на " + player.GetData<int>("eatIcon") + "%");
player.StopAnimation();
},1500);
}
}
C#:
public class Cola : Item
{
public override string IconName { get; set; } = "cola.png";
public override string Description { get; set; } = "Увеличивает водный баланс на 15%";
public override string Name { get; set; } = "Cola 0.33";
public override int Size { get; set; } = 1;
public override int Amount { get; set; } = 1;
public override uint SpawnObjectHash { get; set; } = 1020618269;
public override void Use(Player player, int indexRemove)
{
player.PlayAnimation("mp_player_intdrink", "loop_bottle", 49);
var inven = Util.GetPlayerInventory(player);
if (inven.Items[indexRemove] != null && indexRemove >= 0 && inven.Items.Count > indexRemove)
{
if (inven.Items[indexRemove].Name.Length > 0)
{
inven.Items.RemoveAt(indexRemove);
}
}
NAPI.Task.Run(() =>
{
if (player.GetData<int>("waterIcon") + 25 >= 100)
{
player.SetData("waterIcon", 100);
} else {
player.SetData("waterIcon", player.GetData<int>("waterIcon") + 25);
}
player.SendNotification("~g~Водный баланс " + player.GetData<int>("waterIcon") + "%");
player.StopAnimation();
},1500);
}
}
C#:
[ServerEvent(Event.PlayerSpawn)]
public void OnPlayerSpawn(Player player)
{
Inventory inventory = new Inventory();
inventory.Items.Add(new Burger());
player.SetData(nameof(Inventory), inventory);
player.SetData("eatIcon", 10);
player.SetData("waterIcon", 9);
}
C#:
public class LootManager : Script
{
[Command("drop")]
public void dropItem(Player player, int index)
{
RageMP.Server.Inventory.Inventory inventory = new RageMP.Server.Inventory.Inventory();
inventory.dropItem(player, index);
}
[Command("pick")]
public void pickItem(Player player, int index)
{
RageMP.Server.Inventory.Inventory inventory = new RageMP.Server.Inventory.Inventory();
inventory.pickItem(player, index);
}
[Command("spawn")]
public void spawnItem(Player player, int index)
{
RageMP.Server.Inventory.Inventory inventory = new RageMP.Server.Inventory.Inventory();
inventory.spawnItem(player, index);
}
// посмотреть что вокруг имеется
[Command("check")]
public void checkItems(Player player)
{
var objects = Util.GetObjectsInRadiusOfPosition(1.5, player.Position, player.Dimension);
int i = 0;
player.SendChatMessage("--------------------");
foreach (var obj in objects)
{
var item = Util.GetObjectItem(obj);
player.SendChatMessage($"~b~Around: {item.Name} [{i++}]");
}
player.SendChatMessage("--------------------");
}
[Command("myinv")]
public void checkMyInventory(Player player)
{
RageMP.Server.Inventory.Inventory inventory = new RageMP.Server.Inventory.Inventory();
inventory.checkMyInventory(player);
}
[Command("use")]
public void useItem(Player player, int index)
{
var inventory = Util.GetPlayerInventory(player);
inventory.Items[index].Use(player, index);
inventory.updateIndexItems();
}
}