Система аренды транспорта в Pawn

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

8

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

Создание системы аренды транспорта с выбором моделей, таймерами аренды, оплатой и автоматическим возвратом.

Структура данных аренды

Код:
enum RentalInfo
{
    rModel,
    rName[32],
    rPrice,
    rTime,
    Float:rX,
    Float:rY,
    Float:rZ,
    Float:rAngle,
    rPickup
}

new RentalData[20][RentalInfo];
new TotalRentals = 0;
new PlayerRentalVehicle[MAX_PLAYERS] = {INVALID_VEHICLE_ID, ...};
new PlayerRentalTime[MAX_PLAYERS];
new PlayerRentalTimer[MAX_PLAYERS];

Создание точки аренды

Код:
CreateRentalPoint(modelid, name[], price, time, Float:x, Float:y, Float:z, Float:angle)
{
    if(TotalRentals >= sizeof(RentalData))
    {
        return -1;
    }
    
    RentalData[TotalRentals][rModel] = modelid;
    strcpy(RentalData[TotalRentals][rName], name, 32);
    RentalData[TotalRentals][rPrice] = price;
    RentalData[TotalRentals][rTime] = time;
    RentalData[TotalRentals][rX] = x;
    RentalData[TotalRentals][rY] = y;
    RentalData[TotalRentals][rZ] = z;
    RentalData[TotalRentals][rAngle] = angle;
    RentalData[TotalRentals][rPickup] = CreatePickup(1239, 1, x, y, z, 0);
    
    new string[128];
    format(string, sizeof(string), "Аренда: %s\nЦена: $%d\nВремя: %d минут\nНажмите F", name, price, time);
    Create3DTextLabel(string, 0x00FF00FF, x, y, z+1.0, 10.0, 0, 0);
    
    TotalRentals++;
    return TotalRentals - 1;
}

Инициализация точек аренды

Код:
public OnGameModeInit()
{
    // Аренда в Лос Сантосе
    CreateRentalPoint(411, "Infernus", 5000, 30, 1754.1234, -1898.5678, 13.5469, 90.0);
    CreateRentalPoint(560, "Sultan", 3000, 30, 1754.1234, -1905.5678, 13.5469, 90.0);
    CreateRentalPoint(429, "Banshee", 4000, 30, 1754.1234, -1912.5678, 13.5469, 90.0);
    CreateRentalPoint(451, "Turismo", 6000, 30, 1754.1234, -1919.5678, 13.5469, 90.0);
    
    // Аренда в Сан Фиерро
    CreateRentalPoint(411, "Infernus", 5000, 30, -1982.1798, 885.4023, 45.2109, 180.0);
    CreateRentalPoint(560, "Sultan", 3000, 30, -1989.1798, 885.4023, 45.2109, 180.0);
    
    // Аренда в Лас Вентурасе
    CreateRentalPoint(429, "Banshee", 4000, 30, 2233.8069, 1283.0005, 10.8203, 270.0);
    CreateRentalPoint(451, "Turismo", 6000, 30, 2240.8069, 1283.0005, 10.8203, 270.0);
    
    return 1;
}

Обработка пикапа аренды

Код:
public OnPlayerPickUpPickup(playerid, pickupid)
{
    for(new i = 0; i < TotalRentals; i++)
    {
        if(pickupid == RentalData[i][rPickup])
        {
            if(PlayerRentalVehicle[playerid] != INVALID_VEHICLE_ID)
            {
                SendClientMessage(playerid, -1, "У вас уже есть арендованный транспорт");
                return 1;
            }
            
            ShowRentalMenu(playerid, i);
            return 1;
        }
    }
    return 1;
}

Меню аренды

Код:
ShowRentalMenu(playerid, rentalid)
{
    new string[256];
    format(string, sizeof(string),
        "Аренда транспорта\n\n\
        Модель: %s\n\
        Цена: $%d\n\
        Время аренды: %d минут\n\n\
        Вы хотите арендовать этот транспорт?",
        RentalData[rentalid][rName],
        RentalData[rentalid][rPrice],
        RentalData[rentalid][rTime]
    );
    
    SetPVarInt(playerid, "RentalID", rentalid);
    ShowPlayerDialog(playerid, DIALOG_RENTAL, DIALOG_STYLE_MSGBOX, "Аренда транспорта", string, "Арендовать", "Отмена");
    return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == DIALOG_RENTAL)
    {
        if(response)
        {
            new rentalid = GetPVarInt(playerid, "RentalID");
            DeletePVar(playerid, "RentalID");
            
            if(GetPlayerMoney(playerid) < RentalData[rentalid][rPrice])
            {
                new string[128];
                format(string, sizeof(string), "Недостаточно денег. Нужно: $%d", RentalData[rentalid][rPrice]);
                SendClientMessage(playerid, -1, string);
                return 1;
            }
            
            GivePlayerMoney(playerid, -RentalData[rentalid][rPrice]);
            
            new Float:x, Float:y, Float:z, Float:angle;
            GetPlayerPos(playerid, x, y, z);
            GetPlayerFacingAngle(playerid, angle);
            
            new vehicleid = CreateVehicle(RentalData[rentalid][rModel], x+3, y, z, angle, 0, 1, -1);
            PutPlayerInVehicle(playerid, vehicleid, 0);
            
            PlayerRentalVehicle[playerid] = vehicleid;
            PlayerRentalTime[playerid] = RentalData[rentalid][rTime] * 60;
            
            new string[128];
            format(string, sizeof(string), "Вы арендовали %s на %d минут", RentalData[rentalid][rName], RentalData[rentalid][rTime]);
            SendClientMessage(playerid, -1, string);
            
            PlayerRentalTimer[playerid] = SetTimerEx("UpdateRentalTime", 60000, true, "i", playerid);
            
            format(string, sizeof(string), "Время аренды: %d минут", RentalData[rentalid][rTime]);
            SendClientMessage(playerid, -1, string);
        }
        return 1;
    }
    return 0;
}

Обновление времени аренды

Код:
forward UpdateRentalTime(playerid);
public UpdateRentalTime(playerid)
{
    if(PlayerRentalVehicle[playerid] == INVALID_VEHICLE_ID)
    {
        KillTimer(PlayerRentalTimer[playerid]);
        return 1;
    }
    
    PlayerRentalTime[playerid]--;
    
    if(PlayerRentalTime[playerid] <= 0)
    {
        new string[128];
        format(string, sizeof(string), "Время аренды истекло. Транспорт будет возвращен через 30 секунд");
        SendClientMessage(playerid, -1, string);
        
        SetTimerEx("ReturnRentalVehicle", 30000, false, "i", playerid);
        KillTimer(PlayerRentalTimer[playerid]);
    }
    else
    {
        new minutes = PlayerRentalTime[playerid] / 60;
        new seconds = PlayerRentalTime[playerid] % 60;
        
        if(minutes == 0 && seconds <= 30)
        {
            new string[128];
            format(string, sizeof(string), "Время аренды истекает через %d секунд", seconds);
            SendClientMessage(playerid, -1, string);
        }
    }
    
    return 1;
}

Возврат транспорта

Код:
forward ReturnRentalVehicle(playerid);
public ReturnRentalVehicle(playerid)
{
    if(PlayerRentalVehicle[playerid] != INVALID_VEHICLE_ID)
    {
        if(IsPlayerInVehicle(playerid, PlayerRentalVehicle[playerid]))
        {
            RemovePlayerFromVehicle(playerid);
        }
        
        DestroyVehicle(PlayerRentalVehicle[playerid]);
        PlayerRentalVehicle[playerid] = INVALID_VEHICLE_ID;
        PlayerRentalTime[playerid] = 0;
        
        SendClientMessage(playerid, -1, "Транспорт возвращен");
    }
    return 1;
}

Команда возврата транспорта

Код:
CMD:returnrental(playerid, params[])
{
    if(PlayerRentalVehicle[playerid] == INVALID_VEHICLE_ID)
    {
        SendClientMessage(playerid, -1, "У вас нет арендованного транспорта");
        return 1;
    }
    
    ReturnRentalVehicle(playerid);
    KillTimer(PlayerRentalTimer[playerid]);
    
    SendClientMessage(playerid, -1, "Вы вернули арендованный транспорт");
    return 1;
}

Проверка при выходе из транспорта

Код:
public OnPlayerExitVehicle(playerid, vehicleid)
{
    if(vehicleid == PlayerRentalVehicle[playerid])
    {
        new string[128];
        format(string, sizeof(string), "Вы вышли из арендованного транспорта. Время аренды: %d минут", PlayerRentalTime[playerid] / 60);
        SendClientMessage(playerid, -1, string);
    }
    return 1;
}

Уничтожение транспорта при отключении

Код:
public OnPlayerDisconnect(playerid, reason)
{
    if(PlayerRentalVehicle[playerid] != INVALID_VEHICLE_ID)
    {
        DestroyVehicle(PlayerRentalVehicle[playerid]);
        KillTimer(PlayerRentalTimer[playerid]);
        PlayerRentalVehicle[playerid] = INVALID_VEHICLE_ID;
    }
    return 1;
}

Список доступных транспортов

Код:
CMD:rentals(playerid, params[])
{
    new string[512] = "Доступные транспорты для аренды:\n\n";
    
    for(new i = 0; i < TotalRentals; i++)
    {
        format(string, sizeof(string), "%s%d. %s - $%d (%d минут)\n",
            string, i+1, RentalData[i][rName], RentalData[i][rPrice], RentalData[i][rTime]);
    }
    
    ShowPlayerDialog(playerid, DIALOG_RENTAL_LIST, DIALOG_STYLE_LIST, "Список аренды", string, "Закрыть", "");
    return 1;
}

Сохранение точек аренды в MySQL

Код:
SaveRentalsToMySQL()
{
    for(new i = 0; i < TotalRentals; i++)
    {
        new query[256];
        format(query, sizeof(query),
            "INSERT INTO rentals (model, name, price, time, x, y, z, angle) VALUES (%d, '%e', %d, %d, %.2f, %.2f, %.2f, %.2f) ON DUPLICATE KEY UPDATE price = %d, time = %d",
            RentalData[i][rModel],
            RentalData[i][rName],
            RentalData[i][rPrice],
            RentalData[i][rTime],
            RentalData[i][rX],
            RentalData[i][rY],
            RentalData[i][rZ],
            RentalData[i][rAngle],
            RentalData[i][rPrice],
            RentalData[i][rTime]
        );
        mysql_query(g_SQL, query);
    }
    return 1;
}

LoadRentalsFromMySQL()
{
    mysql_query(g_SQL, "SELECT * FROM rentals");
    mysql_store_result();
    
    new rows = mysql_num_rows();
    for(new i = 0; i < rows && i < sizeof(RentalData); i++)
    {
        RentalData[i][rModel] = mysql_fetch_int("model");
        mysql_fetch_field_row(RentalData[i][rName], "name");
        RentalData[i][rPrice] = mysql_fetch_int("price");
        RentalData[i][rTime] = mysql_fetch_int("time");
        RentalData[i][rX] = mysql_fetch_float("x");
        RentalData[i][rY] = mysql_fetch_float("y");
        RentalData[i][rZ] = mysql_fetch_float("z");
        RentalData[i][rAngle] = mysql_fetch_float("angle");
        RentalData[i][rPickup] = CreatePickup(1239, 1, RentalData[i][rX], RentalData[i][rY], RentalData[i][rZ], 0);
        
        new string[128];
        format(string, sizeof(string), "Аренда: %s\nЦена: $%d\nВремя: %d минут\nНажмите F",
            RentalData[i][rName], RentalData[i][rPrice], RentalData[i][rTime]);
        Create3DTextLabel(string, 0x00FF00FF, RentalData[i][rX], RentalData[i][rY], RentalData[i][rZ]+1.0, 10.0, 0, 0);
        
        TotalRentals++;
    }
    
    mysql_free_result();
    return 1;
}

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

Код:
CREATE TABLE IF NOT EXISTS rentals (
    id INT AUTO_INCREMENT PRIMARY KEY,
    model INT,
    name VARCHAR(32),
    price INT,
    time INT,
    x FLOAT,
    y FLOAT,
    z FLOAT,
    angle FLOAT
);

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

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

Сверху