Продвинутые колбэки в Pawn: расширенные возможности

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

8

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

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

OnPlayerUpdate - оптимизация
Код:
new lastUpdate[MAX_PLAYERS];

public OnPlayerUpdate(playerid)
{
    // Обновление каждые 500мс вместо каждого кадра
    if(GetTickCount() - lastUpdate[playerid] > 500)
    {
        UpdatePlayerHUD(playerid);
        lastUpdate[playerid] = GetTickCount();
    }
    return 1;
}

OnPlayerKeyStateChange
Код:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    // Нажатие F (KEY_SECONDARY_ATTACK)
    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]))
            {
                ShowHouseMenu(playerid, i);
                break;
            }
        }
    }
    
    // Нажатие Y (KEY_YES)
    if(newkeys & KEY_YES)
    {
        // Действие
    }
    
    // Нажатие N (KEY_NO)
    if(newkeys & KEY_NO)
    {
        // Действие
    }
    
    return 1;
}

OnPlayerText - фильтрация чата
Код:
public OnPlayerText(playerid, text[])
{
    // Проверка на мат
    if(ContainsBadWords(text))
    {
        SendClientMessage(playerid, -1, "Использование нецензурной лексики запрещено");
        return 0;
    }
    
    // Логирование
    new string[256], name[MAX_PLAYER_NAME];
    GetPlayerName(playerid, name, sizeof(name));
    format(string, sizeof(string), "[ЧАТ] %s: %s", name, text);
    LogMessage(string);
    
    // Форматирование сообщения
    format(string, sizeof(string), "%s говорит: %s", name, text);
    SendClientMessageToAll(GetPlayerColor(playerid), string);
    
    return 0; // отменяем стандартное сообщение
}

OnPlayerDeath - система смерти
Код:
public OnPlayerDeath(playerid, killerid, reason)
{
    // Сохранение данных
    SavePlayerData(playerid);
    
    // Обработка убийства
    if(killerid != INVALID_PLAYER_ID)
    {
        new string[128];
        format(string, sizeof(string), "%s убил %s", GetPlayerName(killerid), GetPlayerName(playerid));
        SendClientMessageToAll(-1, string);
        
        // Награда за убийство
        GivePlayerMoney(killerid, 100);
        PlayerInfo[killerid][pKills]++;
    }
    
    // Штраф за смерть
    GivePlayerMoney(playerid, -50);
    
    // Респавн через 5 секунд
    SetTimerEx("RespawnPlayer", 5000, false, "i", playerid);
    
    return 1;
}

forward RespawnPlayer(playerid);
public RespawnPlayer(playerid)
{
    if(IsPlayerConnected(playerid))
    {
        SpawnPlayer(playerid);
    }
}

OnVehicleSpawn - управление транспортом
Код:
public OnVehicleSpawn(vehicleid)
{
    // Восстановление цвета транспорта
    if(VehicleData[vehicleid][vColor1] != -1)
    {
        ChangeVehicleColor(vehicleid, VehicleData[vehicleid][vColor1], VehicleData[vehicleid][vColor2]);
    }
    
    // Восстановление модификаций
    for(new i = 0; i < 14; i++)
    {
        if(VehicleData[vehicleid][vComponents][i] > 0)
        {
            AddVehicleComponent(vehicleid, VehicleData[vehicleid][vComponents][i]);
        }
    }
    
    return 1;
}

OnPlayerEnterCheckpoint
Код:
public OnPlayerEnterCheckpoint(playerid)
{
    // Определение типа чекпоинта
    switch(PlayerCheckpoint[playerid])
    {
        case CHECKPOINT_RACE_START:
        {
            StartRace(playerid);
        }
        case CHECKPOINT_RACE_FINISH:
        {
            FinishRace(playerid);
        }
        case CHECKPOINT_MISSION:
        {
            CompleteMission(playerid);
        }
    }
    
    DisablePlayerCheckpoint(playerid);
    return 1;
}

OnPlayerStateChange
Код:
public OnPlayerStateChange(playerid, newstate, oldstate)
{
    // Вход в транспорт
    if(newstate == PLAYER_STATE_DRIVER)
    {
        new vehicleid = GetPlayerVehicleID(playerid);
        new string[128];
        format(string, sizeof(string), "Вы сели за руль транспорта %d", GetVehicleModel(vehicleid));
        SendClientMessage(playerid, -1, string);
        
        // Проверка владельца
        if(strlen(VehicleData[vehicleid][vOwner]) > 0)
        {
            if(strcmp(GetPlayerName(playerid), VehicleData[vehicleid][vOwner], true))
            {
                SendClientMessage(playerid, -1, "Этот транспорт принадлежит другому игроку");
            }
        }
    }
    
    // Выход из транспорта
    if(oldstate == PLAYER_STATE_DRIVER)
    {
        SendClientMessage(playerid, -1, "Вы вышли из транспорта");
    }
    
    return 1;
}

Кастомные колбэки
Код:
// Объявление кастомного колбэка
forward OnPlayerLevelUp(playerid, newlevel);
public OnPlayerLevelUp(playerid, newlevel)
{
    new string[128];
    format(string, sizeof(string), "Поздравляем! Вы достигли уровня %d!", newlevel);
    SendClientMessage(playerid, -1, string);
    
    // Награда за уровень
    GivePlayerMoney(playerid, newlevel * 1000);
    
    return 1;
}

// Вызов кастомного колбэка
CheckPlayerLevel(playerid)
{
    new newLevel = CalculateLevel(PlayerInfo[playerid][pExperience]);
    if(newLevel > PlayerInfo[playerid][pLevel])
    {
        PlayerInfo[playerid][pLevel] = newLevel;
        CallLocalFunction("OnPlayerLevelUp", "ii", playerid, newLevel);
    }
}

Важные моменты:
- Оптимизируйте частые колбэки
- Используйте таймеры для тяжелых операций
- Логируйте важные события
- Обрабатывайте все возможные случаи

Правильное использование колбэков создает динамичный сервер!
 

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

Сверху