Система инвентаря в Pawn: управление предметами

Активный
Статус
Сообщения
516
Лайки
32

8

месяц на сайте

Инвентарь позволяет игрокам хранить и использовать предметы. Разберем создание системы.

Структура данных инвентаря
Код:
enum ItemInfo
{
    iName[32],
    iType,
    iValue,
    iWeight
}

enum PlayerItem
{
    pItemID,
    pQuantity
}

new ItemData[100][ItemInfo];
new TotalItems = 0;
new PlayerInventory[MAX_PLAYERS][50][PlayerItem];
new PlayerInventorySize[MAX_PLAYERS];

Создание предмета
Код:
CreateItem(name[], type, value, weight)
{
    if(TotalItems >= sizeof(ItemData))
    {
        return -1;
    }
    
    strcpy(ItemData[TotalItems][iName], name, 32);
    ItemData[TotalItems][iType] = type;
    ItemData[TotalItems][iValue] = value;
    ItemData[TotalItems][iWeight] = weight;
    
    TotalItems++;
    return TotalItems - 1;
}

Добавление предмета в инвентарь
Код:
AddItemToInventory(playerid, itemid, quantity)
{
    if(itemid >= TotalItems)
    {
        return 0;
    }
    
    if(PlayerInventorySize[playerid] >= sizeof(PlayerInventory[]))
    {
        SendClientMessage(playerid, -1, "Инвентарь переполнен");
        return 0;
    }
    
    // Поиск существующего предмета
    for(new i = 0; i < PlayerInventorySize[playerid]; i++)
    {
        if(PlayerInventory[playerid][i][pItemID] == itemid)
        {
            PlayerInventory[playerid][i][pQuantity] += quantity;
            return 1;
        }
    }
    
    // Добавление нового предмета
    PlayerInventory[playerid][PlayerInventorySize[playerid]][pItemID] = itemid;
    PlayerInventory[playerid][PlayerInventorySize[playerid]][pQuantity] = quantity;
    PlayerInventorySize[playerid]++;
    
    return 1;
}

Удаление предмета из инвентаря
Код:
RemoveItemFromInventory(playerid, itemid, quantity)
{
    for(new i = 0; i < PlayerInventorySize[playerid]; i++)
    {
        if(PlayerInventory[playerid][i][pItemID] == itemid)
        {
            if(PlayerInventory[playerid][i][pQuantity] >= quantity)
            {
                PlayerInventory[playerid][i][pQuantity] -= quantity;
                
                if(PlayerInventory[playerid][i][pQuantity] <= 0)
                {
                    // Удаление предмета
                    for(new j = i; j < PlayerInventorySize[playerid] - 1; j++)
                    {
                        PlayerInventory[playerid][j] = PlayerInventory[playerid][j + 1];
                    }
                    PlayerInventorySize[playerid]--;
                }
                
                return 1;
            }
            else
            {
                SendClientMessage(playerid, -1, "Недостаточно предметов");
                return 0;
            }
        }
    }
    
    SendClientMessage(playerid, -1, "Предмет не найден в инвентаре");
    return 0;
}

Показ инвентаря
Код:
ShowInventory(playerid)
{
    if(PlayerInventorySize[playerid] == 0)
    {
        SendClientMessage(playerid, -1, "Инвентарь пуст");
        return 0;
    }
    
    new string[512] = "";
    for(new i = 0; i < PlayerInventorySize[playerid]; i++)
    {
        new itemid = PlayerInventory[playerid][i][pItemID];
        new quantity = PlayerInventory[playerid][i][pQuantity];
        format(string, sizeof(string), "%s%s x%d\n", 
            string, ItemData[itemid][iName], quantity);
    }
    
    ShowPlayerDialog(playerid, DIALOG_INVENTORY, DIALOG_STYLE_LIST, "Инвентарь", string, "Использовать", "Закрыть");
    return 1;
}

Использование предметов
Код:
UseItem(playerid, itemid)
{
    switch(ItemData[itemid][iType])
    {
        case ITEM_TYPE_HEAL:
        {
            new Float:health;
            GetPlayerHealth(playerid, health);
            if(health < 100.0)
            {
                SetPlayerHealth(playerid, 100.0);
                RemoveItemFromInventory(playerid, itemid, 1);
                SendClientMessage(playerid, -1, "Здоровье восстановлено");
            }
            else
            {
                SendClientMessage(playerid, -1, "У вас полное здоровье");
            }
        }
        case ITEM_TYPE_WEAPON:
        {
            new weaponid = ItemData[itemid][iValue];
            GivePlayerWeapon(playerid, weaponid, 100);
            RemoveItemFromInventory(playerid, itemid, 1);
            SendClientMessage(playerid, -1, "Оружие выдано");
        }
        case ITEM_TYPE_FOOD:
        {
            // Восстановление голода
            RemoveItemFromInventory(playerid, itemid, 1);
            SendClientMessage(playerid, -1, "Вы поели");
        }
    }
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_INVENTORY)
    {
        if(response)
        {
            new itemid = PlayerInventory[playerid][listitem][pItemID];
            UseItem(playerid, itemid);
        }
    }
    return 1;
}

Команды
Код:
CMD:inventory(playerid, params[])
{
    ShowInventory(playerid);
    return 1;
}

CMD:giveitem(playerid, params[])
{
    if(PlayerInfo[playerid][pAdmin] < 1)
    {
        return 1;
    }
    
    new targetid, itemid, quantity;
    if(sscanf(params, "uii", targetid, itemid, quantity))
    {
        SendClientMessage(playerid, -1, "Использование: /giveitem [id] [itemid] [количество]");
        return 1;
    }
    
    if(AddItemToInventory(targetid, itemid, quantity))
    {
        SendClientMessage(targetid, -1, "Вы получили предмет");
    }
    return 1;
}

Важные моменты:
- Ограничивайте размер инвентаря
- Реализуйте систему веса
- Сохраняйте данные инвентаря
- Предоставляйте удобный интерфейс

Система инвентаря добавляет глубину геймплею!
 

1 человек читают эту тему (Всего: 1, Пользователей: 0, Гостей: 1)

Сверху