[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Форум » Уроки SourceMod (SourcePawn) Скриптинга » События в SourcePawn (http://forum.sn-project.ru/viewtopic.php?f=75&t=1973)
События в SourcePawn
rootДата: Воскресенье, 03.02.2013, 10:44 | Сообщение # 1
Генералиссимус
Группа: Администраторы
Сообщений: 561
Статус: Offline
События в SourcePawn

События - сообщения, используемые сервером для передачи сообщений и данных

Введение
События описаны в .res файлах мода в папке resource. "Стандартные" события находятся в hl2/resource/gameevents.res и hl2/resource/serverevents.res. Мод может расширить эти события с помощью расширений.
Для примера посмотрим на player_death из hl2/resource/gameevents.res:

Код
"player_death"
{
     "userid"   "short"      // user ID убитого              
     "attacker"   "short"       // user ID убийцы
}

Counter-Strike:Source расширяет это описание в cstrike/resource/modevents.res:
Код
"player_death"
{
     "userid"   "short"      // user ID убитого              
     "attacker"   "short"       // user ID убийцы
     "weapon"   "string"    // название оружие, которым убил убийца   
     "headshot"   "bool"      // сигнал попадания в голову
}
Обратите внимание, что событие состоит в следующем формате:

Код
"name"
{
     "key1"   "valueType1"
     "key2"   "valueType2"
     ...
}

Посылка сообщений
Послать сообщения очень просто. Например мы хотим послать сообщение смерти используя событие player_death описанное выше. Для Counter-Strike:Source, это будет иметь вид:

Код
SendDeathMessage(attacker, victim, const String:weapon[], bool:headshot)
{
     new Handle:event = CreateEvent("player_death")
     if (event == INVALID_HANDLE)
     {
        return
     }
     
     SetEventInt(event, "userid", GetClientUserId(victim))
     SetEventInt(event, "attacker", GetClientUserId(attacker))
     SetEventString(event, "weapon", weapon)
     SetEventBool(event, "headshot", headshot)
     FireEvent(event)
}
Примечания:
Вы не должны вызывать CloseHandle(), FireEvent() сделает это за вас.Даже если "userid" и "attacker" являются shorts, мы отсылаем их в качестве ints. Термин "short" используется только для того, чтобы сказать движку сколько байт числа необходимо для отправки.Событие может и не создастся; это происходит если событие не существует или никто не перехватывает его. Поэтому вы должны убедиться, что вызовCreateEvent возвращает правильный Handle.Большинство событий используют userids вместо индекса.По умолчанию, FireEvent() посылает сообщения к клиенту. Это можно отключить установив dontBroadcast в true.
Перехват событий
Существует три режима перехвата событий:
Pre - Перехват события до выполнения.Post - Перехват события после выполнения.Post_NoCopy - Перехват события, но не сохраняется любая информация об этом событии (специальная оптимизация).
Перехват событий обычно делается для одной из этих целей. Для того, чтоб понять какой режим использовать, смотрите ниже список целей:
Блокировка события (предотвращение выполнения)
Всегда PreИзменение события (изменение параметров)
Всегда PreВыполнить после события (сделать что-то после того как событие произошло)
Pre если ваши действия должны произойти перед выполнением событияPost если ваши действия должны произойти после выполнением событияPostNoCopy если подходит Post и требуется только имя событияБлокировка событий
Блокировку событий сделать очень просто. Например мы хотим заблокировать событие смерти если смерть произошла от попадания в голову:
Код
public OnPluginStart()
{
     HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre)
}
     
public Action:Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
     if (GetEventBool(event, "headshot"))
     {
        return Plugin_Handled
     }
     return Plugin_Continue
}

Изменение событий
Изменить событий тоже очень просто -- события могут быть изменены в режиме перед выполнением события. Например мы хотим убрать попадание в голову со всех событий:
Код
public OnPluginStart()
{
     HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre)
}
     
public Action:Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
     SetEventBool(event, "headshot", false)
     return Plugin_Continue
}

Post Перехват событий
По умолчанию используется перехват после события и как правило наиболее используемый. Например мы хотим послать сообщение всем игрокам, которые умерли:
Код
public OnPluginStart()
{
     HookEvent("player_death", Event_PlayerDeath)
}
     
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
     decl String:weapon[64]
     new victimId = GetEventInt(event, "userid")
     new attackerId = GetEventInt(event, "attacker")
     new bool:headshot = GetEventBool(event, "headshot")
     GetEventString(event, "weapon", weapon, sizeof(weapon))
     
     decl String:name[64]
     new victim = GetClientOfUserId(victimId)
     new attacker = GetClientOfUserId(attackerId)
     GetClientName(attacker, name, sizeof(name))
     
     PrintToConsole(victim,
        "You were killed by \"%s\" (weapon \"%s\") (headshot \"%d\")",
        name,
        weapon,
        headshot)
}
Это будет писать игроку в консоли кто его убил, с каким оружием и было ли попадание в голову.
Обратите внимание, что возвращение значений с перехвата после события игнорируется, поэтому тег Action не нужен.

PostNoCopy Перехват событий
Наконец есть перехваты где требуется только имя события. PostNoCopy специальная оптимизация для этого. При переходе от Pre к Post, SourceMod должен дублировать событие и все значения. PostNoCopy предотвращает это.
Например мы хотим найти когда происходят определенные события.
Код
public OnPluginStart()
{
     HookEvent("game_newmap", GameEvents, EventHookMode_PostNoCopy)
     HookEvent("game_start", GameEvents, EventHookMode_PostNoCopy)
     HookEvent("game_end", GameEvents, EventHookMode_PostNoCopy)
     HookEvent("game_message", GameEvents, EventHookMode_PostNoCopy)
}

public GameEvents(Handle:event, const String:name[], bool:dontBroadcast)
{
     PrintToServer("Event has been fired (event \"%s\") (nobcast \"%d\")", name, dontBroadcast)
}


Обратите внимание, что как и обычный Post перехват, он не требует возврата значений. Однако, параметр event для PostNoCopy всегда должен быть равным INVALID_HANDLE. Таким образом параметр name должен использоваться вместо GetEventName.

Оригинал
 
ReespawnДата: Суббота, 31.08.2013, 02:15 | Сообщение # 2
Рядовой
Группа: Пользователи
Сообщений: 2
Статус: Offline
что то я не понял для чего это? может мне кто нибудь подробно объяснит а то я как то новичок по созданию сервера CS Source sh_ok
 
BeatMaker_R1KO_Дата: Суббота, 31.08.2013, 16:03 | Сообщение # 3
Сержант
Группа: Пользователи
Сообщений: 20
Статус: Offline
Цитата (Reespawn)
что то я не понял для чего это? может мне кто нибудь подробно объяснит а то я как то новичок по созданию сервера CS Source
Это для написание плагинов. Можешь пользоватся готовыми и не заморачиватся.
 
Гость_Дата: Среда, 14.10.2015, 03:47 | Сообщение # 4
Рядовой
Группа: Пользователи
Сообщений: 1
Статус: Offline
cool
 
Форум » Форум » Уроки SourceMod (SourcePawn) Скриптинга » События в SourcePawn (http://forum.sn-project.ru/viewtopic.php?f=75&t=1973)
  • Страница 1 из 1
  • 1
Поиск: