Иконка ресурса

Ядро плагина Effect Calculator 2.1

Версия Дата выпуска Скачивания Оценка  
2.1 231 5.00 звёзд 1 оценок Скачать
1.0 116 0.00 звёзд 0 оценок Скачать
Обновил описание, теперь по нему можно клепать новые модули под новое API
СТАРОЕ API СЛОМАНО
Модули под версию 1.Х не совместимы с версией 2.Х и наоборот

Написать прослойку возможность есть, названия старых нативов не используются, но если у вас есть силы написать такое API, лучше потратить их на внесение изменений под новое API. Однако если будет слишком много запросов, придется выпустить прослойку между старыми модулями и новым ядром
Изменения в API:
Старый добрый ECalc_Hook превратился в:
C-подобный:
typeset ECalc_HookCallBack    {
    // old
    //function void (any[] data, int size, float &value);
    //function void (any[] data, int size, float &value, const char[] effect);

    // new
    function void (int client, float &value, const char[] effect, any[] data, int size);
    function void (int client, float &value, const char[] effect);
    function void (int client, float &value);
}

/***
 *    ECalc_Hook            Hook calculating effect multiplier
 *
 *    @param    effect        Name of effect
 *    @param    mult_name    Name of multiplier (same multipliers will sum)
 *    @param    func        Hook callback (See ECalc_HookCallBack)
 *    @param    remove        If true, your hook will be removed
 *
 *    @no return
***/
native void ECalc_Hook2(const char[] effect, const char[] mult_name, ECalc_HookCallBack func, bool remove = false);
Изменен принцип определения игрока, больше нет эффектов без владельца.
Теперь в хуке можно узнать, какой именно эффект был вызван
Как это выглядит:
C-подобный:
public void OnLibraryAdded(const char[] name)
{
    if(!strcmp(name, "effectcalc"))
        ECalc_Hook("damage", "base", ModifyDamage)
}

public void ModifyDamage(any[] data, int size, float &value)
{
    if(size < 1)    return;
    int player = data[0];
    if(GetClientTeam(player) == 2)    value += 0.5
}
->
C-подобный:
public void OnLibraryAdded(const char[] name)
{
    if(!strcmp(name, "effectcalc"))
        ECalc_Hook2("damage", "base", ModifyDamage)
}

public void ModifyDamage(int player, float &value)
{
    if(GetClientTeam(player) == 2)    value += 0.5
}
Как видите, изменений немного, но, со стороны разработчика, они качественные
ECalc_Run тоже потерпел изменения:
C-подобный:
/***
 *    ECalc_Run            Calculating effects final multiplier
 *
 *    @param    effect        Effect ID (not name, for faster work)
 *    @param    data        Dynamic array for data
 *    @param    size        Count of values in array
 *
 *    @return    multiplier    Final multiplier of this effect, ready to use
**/
native float ECalc_Run2(int client, const char[] effect, any[] data = NULL_VECTOR, int size = 0);
Теперь не обязательно создавать массив из одной ячейки, чтобы передать игрока
C-подобный:
public void OnLibraryRemoved(const char[] name)
{
    if(!strcmp(name, "effectcalc"))
        effect = -1
}

public void OnLibraryAdded(const char[] name)
{
    if(!strcmp(name, "effectcalc"))
        effect = ECalc_GetEffect("speed")
}

public void EventSpawn(Event event, const char[] name, bool dbc)
{
    int temp[1]
    if(effect == -1)
        return
    int client = GetClientOfUserId(event.GetInt("userid"))
    if(client)
    {
        temp[0] = client
        SetEntDataFloat(client, offs_LaggedMovementValue, ECalc_Run(effect, temp, 1))
    }
}
->
C-подобный:
public void EventSpawn(Event event, const char[] name, bool dbc)
{
    int client = GetClientOfUserId(event.GetInt("userid"))
    if(client)
    {
        SetEntDataFloat(client, offs_LaggedMovementValue, ECalc_Run2(client, "speed"))
    }
}
Тоже стало проще, однако есть 1 нюанс, для этого загляните в следующий спойлер
Добавилось дополнительное API:
C-подобный:
typeset ECalc_HookApplyCallBack    {
    function Action (int client); // return Plugin_Stop on applying
}

/***
 *    ECalc_Hook            Hook calculating effect multiplier
 *
 *    @param    effect        Name of effect
 *    @param    mult_name    Name of multiplier (same multipliers will sum)
 *    @param    func        Hook callback (See ECalc_HookCallBack)
 *    @param    remove        If true, your hook will be removed
 *
 *    @no return
***/
native void ECalc_HookApply(const char[] effect, ECalc_HookApplyCallBack func, bool remove = false);

/***
 *    ECalc_Recalculate    Functions calls to recalculate some effects of player
 *
 *    @param    effect        client
 *    @param    effect        Name of effect
 *
 *    @return                true if effect applied
***/
native bool ECalc_Apply(int client, const char[] effect);
Концепция проста: если модуль резко изменяет баф для эффекта, он не может сообщить, что он это сделал, и что если сейчас вызвать перерасчёт множителя, то он будет другим
Вернее, не мог, до сего момента: ECalc_HookApply и ECalc_Apply представляет концепцию, обратную ECalc_Hook2 и ECalc_Run2, но вызов обратный

Кратко:
C-подобный:
public void OnLibraryAdded(const char[] lib)    {
    if(!strcmp(lib, "effectcalc"))    {
        ECalc_HookApply("speed", ApplyPlayerSpeed)
    }
}

public Action ApplyPlayerSpeed(int client)    {
    SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", ECalc_Run2(client, "speed"));
    return Plugin_Stop
}

// в OnPluginStart HookEvent на спавн игрока
public void EventSpawn(Event event, const char[] name, bool dbc)
{
    int client = GetClientOfUserId(event.GetInt("userid"))
    if(client)    ApplyPlayerSpeed(client);
}
C-подобный:
float g_flValue = 0.0;

public void OnPluginStart()
{
    CreateTimer(5.0, ReRandomSpeed, _, TIMER_REPEAT);
}

public Action ReRandomSpeed(Handle timer)
{
    g_flValue = GetRandomFloat(-0.5,0.5); // изменение скорости игроков от -50% до +50%
    for(int i = 1; i <= MaxClients; ++i)
    {
        if(IsClientInGame(i))    ECalc_Apply(i, "speed");
    }
}

public void OnLibraryAdded(const char[] lib)    {
    if(!strcmp(lib, "effectcalc"))    {
        ECalc_Hook2("speed", "randomizer", HookPlayerSpeed)
    }
}

public void HookPlayerSpeed(int client, float& value)
{
    value += g_flValue;
}
Данная схема изменяет множитель скорости игрока в диапазоне от 0.5 до 1.5 каждые 5 секунд. С прошлым API это было практически невозможно (за исключением другого вспомогательного API, которое пришлось бы реализовывать)

Также немного поясняю момент с хуками (это касается всех предыдущих и текущих версий данного плагина):
Все хуки проверяются и удаляются автоматически, в плагин-модуль не нужно помечать модуль/эффект недействительным, а хуки не нужно удалять. Они все снимутся сами
Сверху Снизу