Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
СТАРОЕ 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);
Теперь не обязательно создавать массив из одной ячейки, чтобы передать игрока
Тоже стало проще, однако есть 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, которое пришлось бы реализовывать)
Также немного поясняю момент с хуками (это касается всех предыдущих и текущих версий данного плагина):
Все хуки проверяются и удаляются автоматически, в плагин-модуль не нужно помечать модуль/эффект недействительным, а хуки не нужно удалять. Они все снимутся сами