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

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

8

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

Дома позволяют игрокам иметь собственность. Разберем создание полноценной системы домов.

Структура данных дома
Код:
enum HouseInfo
{
    Float:hX,
    Float:hY,
    Float:hZ,
    Float:hInteriorX,
    Float:hInteriorY,
    Float:hInteriorZ,
    hInterior,
    hPrice,
    hOwner[MAX_PLAYER_NAME],
    hLocked,
    hWeapons[10],
    hAmmo[10],
    Text3D:hLabel,
    hPickup
}

new HouseData[100][HouseInfo];
new TotalHouses = 0;

Создание дома
Код:
CreateHouse(Float:x, Float:y, Float:z, Float:ix, Float:iy, Float:iz, interior, price)
{
    if(TotalHouses >= sizeof(HouseData))
    {
        return -1;
    }
    
    new string[128];
    if(strlen(HouseData[TotalHouses][hOwner]) == 0)
    {
        format(string, sizeof(string), "Дом на продажу\nЦена: $%d\nНажмите F", price);
    }
    else
    {
        format(string, sizeof(string), "Дом\nВладелец: %s\nНажмите F", HouseData[TotalHouses][hOwner]);
    }
    
    HouseData[TotalHouses][hX] = x;
    HouseData[TotalHouses][hY] = y;
    HouseData[TotalHouses][hZ] = z;
    HouseData[TotalHouses][hInteriorX] = ix;
    HouseData[TotalHouses][hInteriorY] = iy;
    HouseData[TotalHouses][hInteriorZ] = iz;
    HouseData[TotalHouses][hInterior] = interior;
    HouseData[TotalHouses][hPrice] = price;
    HouseData[TotalHouses][hLabel] = Create3DTextLabel(string, 0xFFFFFFFF, x, y, z + 1.0, 20.0, 0, 0);
    HouseData[TotalHouses][hPickup] = CreatePickup(1273, 1, x, y, z, 0);
    HouseData[TotalHouses][hLocked] = 0;
    
    TotalHouses++;
    return TotalHouses - 1;
}

Вход в дом
Код:
EnterHouse(playerid, houseid)
{
    if(HouseData[houseid][hLocked] && strcmp(GetPlayerName(playerid), HouseData[houseid][hOwner], true))
    {
        SendClientMessage(playerid, -1, "Дом заблокирован");
        return 0;
    }
    
    SetPlayerPos(playerid, HouseData[houseid][hInteriorX], HouseData[houseid][hInteriorY], HouseData[houseid][hInteriorZ]);
    SetPlayerInterior(playerid, HouseData[houseid][hInterior]);
    SetPlayerVirtualWorld(playerid, houseid + 1);
    
    PlayerInHouse[playerid] = houseid;
    
    SendClientMessage(playerid, -1, "Вы вошли в дом");
    return 1;
}

ExitHouse(playerid)
{
    if(PlayerInHouse[playerid] == -1)
    {
        return 0;
    }
    
    new houseid = PlayerInHouse[playerid];
    SetPlayerPos(playerid, HouseData[houseid][hX], HouseData[houseid][hY], HouseData[houseid][hZ]);
    SetPlayerInterior(playerid, 0);
    SetPlayerVirtualWorld(playerid, 0);
    
    PlayerInHouse[playerid] = -1;
    
    SendClientMessage(playerid, -1, "Вы вышли из дома");
    return 1;
}

Покупка дома
Код:
BuyHouse(playerid, houseid)
{
    if(houseid >= TotalHouses)
    {
        SendClientMessage(playerid, -1, "Неверный ID дома");
        return 0;
    }
    
    if(strlen(HouseData[houseid][hOwner]) > 0)
    {
        SendClientMessage(playerid, -1, "Дом уже имеет владельца");
        return 0;
    }
    
    if(GetPlayerMoney(playerid) < HouseData[houseid][hPrice])
    {
        SendClientMessage(playerid, -1, "Недостаточно денег");
        return 0;
    }
    
    GetPlayerName(playerid, HouseData[houseid][hOwner], MAX_PLAYER_NAME);
    GivePlayerMoney(playerid, -HouseData[houseid][hPrice]);
    
    UpdateHouseLabel(houseid);
    
    new string[128];
    format(string, sizeof(string), "Вы купили дом за $%d", HouseData[houseid][hPrice]);
    SendClientMessage(playerid, -1, string);
    
    return 1;
}

UpdateHouseLabel(houseid)
{
    new string[128];
    if(strlen(HouseData[houseid][hOwner]) == 0)
    {
        format(string, sizeof(string), "Дом на продажу\nЦена: $%d\nНажмите F", HouseData[houseid][hPrice]);
        Update3DTextLabelText(HouseData[houseid][hLabel], 0xFFFFFFFF, string);
    }
    else
    {
        format(string, sizeof(string), "Дом\nВладелец: %s\nНажмите F", HouseData[houseid][hOwner]);
        Update3DTextLabelText(HouseData[houseid][hLabel], 0x00FF00FF, string);
    }
}

Взаимодействие с домом
Код:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if(newkeys & KEY_SECONDARY_ATTACK)
    {
        for(new i = 0; i < TotalHouses; i++)
        {
            if(IsPlayerInRangeOfPoint(playerid, 3.0, HouseData[i][hX], HouseData[i][hY], HouseData[i][hZ]))
            {
                if(GetPlayerInterior(playerid) == 0)
                {
                    // Снаружи дома
                    if(strlen(HouseData[i][hOwner]) == 0)
                    {
                        ShowPlayerDialog(playerid, DIALOG_BUY_HOUSE, DIALOG_STYLE_MSGBOX, "Покупка дома", 
                            "Купить этот дом?", "Купить", "Отмена");
                        PlayerHouseID[playerid] = i;
                    }
                    else
                    {
                        EnterHouse(playerid, i);
                    }
                }
                else
                {
                    // Внутри дома
                    if(PlayerInHouse[playerid] == i)
                    {
                        ExitHouse(playerid);
                    }
                }
                break;
            }
        }
    }
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_BUY_HOUSE)
    {
        if(response)
        {
            BuyHouse(playerid, PlayerHouseID[playerid]);
        }
    }
    return 1;
}

Хранение оружия в доме
Код:
StoreWeaponInHouse(playerid, houseid)
{
    if(strcmp(GetPlayerName(playerid), HouseData[houseid][hOwner], true))
    {
        SendClientMessage(playerid, -1, "Вы не владелец этого дома");
        return 0;
    }
    
    new weapon = GetPlayerWeapon(playerid);
    if(weapon == 0)
    {
        SendClientMessage(playerid, -1, "У вас нет оружия");
        return 0;
    }
    
    new ammo = GetPlayerAmmo(playerid);
    
    // Поиск свободного слота
    for(new i = 0; i < 10; i++)
    {
        if(HouseData[houseid][hWeapons][i] == 0)
        {
            HouseData[houseid][hWeapons][i] = weapon;
            HouseData[houseid][hAmmo][i] = ammo;
            RemovePlayerWeapon(playerid, weapon);
            
            SendClientMessage(playerid, -1, "Оружие сохранено в доме");
            return 1;
        }
    }
    
    SendClientMessage(playerid, -1, "В доме нет места для оружия");
    return 0;
}

TakeWeaponFromHouse(playerid, houseid)
{
    if(strcmp(GetPlayerName(playerid), HouseData[houseid][hOwner], true))
    {
        SendClientMessage(playerid, -1, "Вы не владелец этого дома");
        return 0;
    }
    
    // Показ меню оружия
    new string[256] = "";
    for(new i = 0; i < 10; i++)
    {
        if(HouseData[houseid][hWeapons][i] > 0)
        {
            format(string, sizeof(string), "%sОружие %d (Патроны: %d)\n", 
                string, HouseData[houseid][hWeapons][i], HouseData[houseid][hAmmo][i]);
        }
    }
    
    if(strlen(string) > 0)
    {
        ShowPlayerDialog(playerid, DIALOG_HOUSE_WEAPONS, DIALOG_STYLE_LIST, "Оружие в доме", string, "Взять", "Отмена");
        PlayerHouseID[playerid] = houseid;
    }
    else
    {
        SendClientMessage(playerid, -1, "В доме нет оружия");
    }
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_HOUSE_WEAPONS)
    {
        if(response)
        {
            new houseid = PlayerHouseID[playerid];
            new weapon = HouseData[houseid][hWeapons][listitem];
            new ammo = HouseData[houseid][hAmmo][listitem];
            
            GivePlayerWeapon(playerid, weapon, ammo);
            
            HouseData[houseid][hWeapons][listitem] = 0;
            HouseData[houseid][hAmmo][listitem] = 0;
            
            SendClientMessage(playerid, -1, "Оружие взято из дома");
        }
    }
    return 1;
}

Команды
Код:
CMD:myhouse(playerid, params[])
{
    new count = 0;
    for(new i = 0; i < TotalHouses; i++)
    {
        if(!strcmp(GetPlayerName(playerid), HouseData[i][hOwner], true))
        {
            count++;
            new string[128];
            format(string, sizeof(string), "Дом %d: Цена $%d", i, HouseData[i][hPrice]);
            SendClientMessage(playerid, -1, string);
        }
    }
    
    if(count == 0)
    {
        SendClientMessage(playerid, -1, "У вас нет домов");
    }
    return 1;
}

CMD:lockhouse(playerid, params[])
{
    for(new i = 0; i < TotalHouses; i++)
    {
        if(!strcmp(GetPlayerName(playerid), HouseData[i][hOwner], true))
        {
            if(IsPlayerInRangeOfPoint(playerid, 5.0, HouseData[i][hX], HouseData[i][hY], HouseData[i][hZ]))
            {
                HouseData[i][hLocked] = !HouseData[i][hLocked];
                SendClientMessage(playerid, -1, HouseData[i][hLocked] ? "Дом заблокирован" : "Дом разблокирован");
                return 1;
            }
        }
    }
    
    SendClientMessage(playerid, -1, "Вы не находитесь рядом со своим домом");
    return 1;
}

CMD:sellhouse(playerid, params[])
{
    for(new i = 0; i < TotalHouses; i++)
    {
        if(!strcmp(GetPlayerName(playerid), HouseData[i][hOwner], true))
        {
            if(IsPlayerInRangeOfPoint(playerid, 5.0, HouseData[i][hX], HouseData[i][hY], HouseData[i][hZ]))
            {
                GivePlayerMoney(playerid, HouseData[i][hPrice] / 2);
                
                HouseData[i][hOwner][0] = '\0';
                HouseData[i][hLocked] = 0;
                
                UpdateHouseLabel(i);
                
                SendClientMessage(playerid, -1, "Дом продан");
                return 1;
            }
        }
    }
    
    SendClientMessage(playerid, -1, "Вы не находитесь рядом со своим домом");
    return 1;
}

Важные моменты:
- Используйте виртуальные миры для изоляции домов
- Сохраняйте данные домов в базе данных
- Реализуйте систему хранения предметов
- Предоставляйте удобные команды управления

Дома создают систему собственности на сервере!
 

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

Сверху