Система телепортации в Pawn

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

8

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

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

Структура данных телепортов

Код:
enum TeleportInfo
{
    tName[32],
    Float:tX,
    Float:tY,
    Float:tZ,
    Float:tAngle,
    tInterior,
    tCategory,
    tPrice
}

new TeleportData[100][TeleportInfo];
new TotalTeleports = 0;

Создание телепорта

Код:
CreateTeleport(name[], Float:x, Float:y, Float:z, Float:angle, interior, category, price)
{
    if(TotalTeleports >= sizeof(TeleportData))
    {
        return -1;
    }
    
    strcpy(TeleportData[TotalTeleports][tName], name, 32);
    TeleportData[TotalTeleports][tX] = x;
    TeleportData[TotalTeleports][tY] = y;
    TeleportData[TotalTeleports][tZ] = z;
    TeleportData[TotalTeleports][tAngle] = angle;
    TeleportData[TotalTeleports][tInterior] = interior;
    TeleportData[TotalTeleports][tCategory] = category;
    TeleportData[TotalTeleports][tPrice] = price;
    
    TotalTeleports++;
    return TotalTeleports - 1;
}

Инициализация телепортов

Код:
public OnGameModeInit()
{
    // Города
    CreateTeleport("Лос Сантос", 1958.3783, 1343.1572, 15.3746, 90.0, 0, 0, 0);
    CreateTeleport("Сан Фиерро", -1982.1798, 885.4023, 45.2109, 180.0, 0, 0, 0);
    CreateTeleport("Лас Вентурас", 2233.8069, 1283.0005, 10.8203, 270.0, 0, 0, 0);
    
    // Бизнесы
    CreateTeleport("24/7", -25.8845, -185.8689, 1003.5469, 0.0, 17, 1, 100);
    CreateTeleport("Бар", 493.3909, -22.7228, 1000.6797, 0.0, 11, 1, 100);
    CreateTeleport("Клуб", 493.3909, -22.7228, 1000.6797, 0.0, 17, 1, 100);
    
    // Больницы
    CreateTeleport("Больница LS", 1172.0151, -1323.2229, 15.4030, 0.0, 0, 2, 0);
    CreateTeleport("Больница SF", -2655.5251, 639.5264, 14.4531, 0.0, 0, 2, 0);
    
    // Полиция
    CreateTeleport("Полиция LS", 1544.6033, -1675.2142, 13.5578, 90.0, 0, 3, 0);
    CreateTeleport("Полиция SF", -1605.0154, 716.8611, 150.0547, 0.0, 0, 3, 0);
    
    return 1;
}

Команда телепортации

Код:
CMD:tp(playerid, params[])
{
    new teleportid;
    if(sscanf(params, "d", teleportid))
    {
        ShowTeleportMenu(playerid);
        return 1;
    }
    
    if(teleportid < 0 || teleportid >= TotalTeleports)
    {
        SendClientMessage(playerid, -1, "Неверный ID телепорта");
        return 1;
    }
    
    if(TeleportData[teleportid][tPrice] > 0)
    {
        if(GetPlayerMoney(playerid) < TeleportData[teleportid][tPrice])
        {
            new string[128];
            format(string, sizeof(string), "Недостаточно денег. Нужно: $%d", TeleportData[teleportid][tPrice]);
            SendClientMessage(playerid, -1, string);
            return 1;
        }
        
        GivePlayerMoney(playerid, -TeleportData[teleportid][tPrice]);
    }
    
    SetPlayerPos(playerid, TeleportData[teleportid][tX], TeleportData[teleportid][tY], TeleportData[teleportid][tZ]);
    SetPlayerFacingAngle(playerid, TeleportData[teleportid][tAngle]);
    SetPlayerInterior(playerid, TeleportData[teleportid][tInterior]);
    
    new string[128];
    format(string, sizeof(string), "Вы телепортировались в: %s", TeleportData[teleportid][tName]);
    SendClientMessage(playerid, -1, string);
    
    return 1;
}

Меню телепортов по категориям

Код:
ShowTeleportMenu(playerid)
{
    new string[512] = "Выберите категорию:\n\n";
    strcat(string, "1. Города\n");
    strcat(string, "2. Бизнесы\n");
    strcat(string, "3. Больницы\n");
    strcat(string, "4. Полиция\n");
    strcat(string, "5. Дома\n");
    strcat(string, "6. Развлечения\n");
    
    ShowPlayerDialog(playerid, DIALOG_TELEPORT_CATEGORY, DIALOG_STYLE_LIST, "Телепорты", string, "Выбрать", "Отмена");
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_TELEPORT_CATEGORY)
    {
        if(response)
        {
            ShowTeleportList(playerid, listitem);
        }
        return 1;
    }
    
    if(dialogid == DIALOG_TELEPORT_LIST)
    {
        if(response)
        {
            new teleportid = strval(inputtext);
            if(teleportid >= 0 && teleportid < TotalTeleports)
            {
                if(TeleportData[teleportid][tPrice] > 0)
                {
                    if(GetPlayerMoney(playerid) < TeleportData[teleportid][tPrice])
                    {
                        SendClientMessage(playerid, -1, "Недостаточно денег");
                        return 1;
                    }
                    GivePlayerMoney(playerid, -TeleportData[teleportid][tPrice]);
                }
                
                SetPlayerPos(playerid, TeleportData[teleportid][tX], TeleportData[teleportid][tY], TeleportData[teleportid][tZ]);
                SetPlayerFacingAngle(playerid, TeleportData[teleportid][tAngle]);
                SetPlayerInterior(playerid, TeleportData[teleportid][tInterior]);
                
                new string[128];
                format(string, sizeof(string), "Вы телепортировались в: %s", TeleportData[teleportid][tName]);
                SendClientMessage(playerid, -1, string);
            }
        }
        return 1;
    }
    
    return 0;
}

ShowTeleportList(playerid, category)
{
    new string[512], count = 0, list[100];
    
    for(new i = 0; i < TotalTeleports; i++)
    {
        if(TeleportData[i][tCategory] == category)
        {
            format(list, sizeof(list), "%d. %s", i, TeleportData[i][tName]);
            if(TeleportData[i][tPrice] > 0)
            {
                format(list, sizeof(list), "%s ($%d)\n", list, TeleportData[i][tPrice]);
            }
            else
            {
                strcat(list, "\n");
            }
            strcat(string, list);
            count++;
        }
    }
    
    if(count == 0)
    {
        SendClientMessage(playerid, -1, "В этой категории нет телепортов");
        return 1;
    }
    
    ShowPlayerDialog(playerid, DIALOG_TELEPORT_LIST, DIALOG_STYLE_LIST, "Список телепортов", string, "Телепорт", "Назад");
    return 1;
}

Сохранение текущей позиции

Код:
CMD:savetp(playerid, params[])
{
    if(PlayerInfo[playerid][pAdmin] < 1)
    {
        SendClientMessage(playerid, -1, "У вас нет доступа к этой команде");
        return 1;
    }
    
    new name[32];
    if(sscanf(params, "s[32]", name))
    {
        SendClientMessage(playerid, -1, "Использование: /savetp [название]");
        return 1;
    }
    
    new Float:x, Float:y, Float:z, Float:angle;
    GetPlayerPos(playerid, x, y, z);
    GetPlayerFacingAngle(playerid, angle);
    
    new teleportid = CreateTeleport(name, x, y, z, angle, GetPlayerInterior(playerid), 0, 0);
    
    if(teleportid != -1)
    {
        new string[128];
        format(string, sizeof(string), "Телепорт '%s' создан (ID: %d)", name, teleportid);
        SendClientMessage(playerid, -1, string);
    }
    else
    {
        SendClientMessage(playerid, -1, "Достигнут лимит телепортов");
    }
    
    return 1;
}

Телепорт к игроку

Код:
CMD:goto(playerid, params[])
{
    if(PlayerInfo[playerid][pAdmin] < 1)
    {
        SendClientMessage(playerid, -1, "У вас нет доступа к этой команде");
        return 1;
    }
    
    new targetid;
    if(sscanf(params, "u", targetid))
    {
        SendClientMessage(playerid, -1, "Использование: /goto [id игрока]");
        return 1;
    }
    
    if(!IsPlayerConnected(targetid))
    {
        SendClientMessage(playerid, -1, "Игрок не найден");
        return 1;
    }
    
    new Float:x, Float:y, Float:z;
    GetPlayerPos(targetid, x, y, z);
    SetPlayerPos(playerid, x+2, y, z);
    SetPlayerInterior(playerid, GetPlayerInterior(targetid));
    SetPlayerVirtualWorld(playerid, GetPlayerVirtualWorld(targetid));
    
    new string[128], name[MAX_PLAYER_NAME];
    GetPlayerName(targetid, name, sizeof(name));
    format(string, sizeof(string), "Вы телепортировались к игроку %s", name);
    SendClientMessage(playerid, -1, string);
    
    return 1;
}

Телепорт игрока к вам

Код:
CMD:gethere(playerid, params[])
{
    if(PlayerInfo[playerid][pAdmin] < 1)
    {
        SendClientMessage(playerid, -1, "У вас нет доступа к этой команде");
        return 1;
    }
    
    new targetid;
    if(sscanf(params, "u", targetid))
    {
        SendClientMessage(playerid, -1, "Использование: /gethere [id игрока]");
        return 1;
    }
    
    if(!IsPlayerConnected(targetid))
    {
        SendClientMessage(playerid, -1, "Игрок не найден");
        return 1;
    }
    
    new Float:x, Float:y, Float:z;
    GetPlayerPos(playerid, x, y, z);
    SetPlayerPos(targetid, x+2, y, z);
    SetPlayerInterior(targetid, GetPlayerInterior(playerid));
    SetPlayerVirtualWorld(targetid, GetPlayerVirtualWorld(playerid));
    
    new string[128], name[MAX_PLAYER_NAME];
    GetPlayerName(targetid, name, sizeof(name));
    format(string, sizeof(string), "Вы телепортировали игрока %s к себе", name);
    SendClientMessage(playerid, -1, string);
    
    format(string, sizeof(string), "Администратор телепортировал вас");
    SendClientMessage(targetid, -1, string);
    
    return 1;
}

Сохранение телепортов в MySQL

Код:
SaveTeleportsToMySQL()
{
    for(new i = 0; i < TotalTeleports; i++)
    {
        new query[256];
        format(query, sizeof(query),
            "INSERT INTO teleports (name, x, y, z, angle, interior, category, price) VALUES ('%e', %.2f, %.2f, %.2f, %.2f, %d, %d, %d) ON DUPLICATE KEY UPDATE x = %.2f, y = %.2f, z = %.2f",
            TeleportData[i][tName],
            TeleportData[i][tX],
            TeleportData[i][tY],
            TeleportData[i][tZ],
            TeleportData[i][tAngle],
            TeleportData[i][tInterior],
            TeleportData[i][tCategory],
            TeleportData[i][tPrice],
            TeleportData[i][tX],
            TeleportData[i][tY],
            TeleportData[i][tZ]
        );
        mysql_query(g_SQL, query);
    }
    return 1;
}

LoadTeleportsFromMySQL()
{
    mysql_query(g_SQL, "SELECT * FROM teleports");
    mysql_store_result();
    
    new rows = mysql_num_rows();
    for(new i = 0; i < rows && i < sizeof(TeleportData); i++)
    {
        mysql_fetch_row_format(TeleportData[i][tName], "name");
        TeleportData[i][tX] = mysql_fetch_float("x");
        TeleportData[i][tY] = mysql_fetch_float("y");
        TeleportData[i][tZ] = mysql_fetch_float("z");
        TeleportData[i][tAngle] = mysql_fetch_float("angle");
        TeleportData[i][tInterior] = mysql_fetch_int("interior");
        TeleportData[i][tCategory] = mysql_fetch_int("category");
        TeleportData[i][tPrice] = mysql_fetch_int("price");
        TotalTeleports++;
    }
    
    mysql_free_result();
    return 1;
}

Создание таблицы для телепортов

Код:
CREATE TABLE IF NOT EXISTS teleports (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(32) UNIQUE,
    x FLOAT,
    y FLOAT,
    z FLOAT,
    angle FLOAT,
    interior INT DEFAULT 0,
    category INT DEFAULT 0,
    price INT DEFAULT 0
);

Эта система предоставляет полный функционал телепортации с категориями, ценами и сохранением в базе данных.
 

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

Сверху