Witam was w moim pierwszym poradniku . Temat ten będzie spolszczeniem, natomiast link do oryginału (w języku angielskim) zamieszczę na dole .
Funkcja "HookEvent"
-------------------------------------------------------------------------------------------------------------------------------------------------------
Na samym wstępie opiszę wam funkcję, którą będziemy używać do wyłapywania wydarzeń .
native HookEvent(const String:name[], EventHook:callback, EventHookMode:mode=EventHookMode_Post);
Parametry:
1. Pierwszy paramter jest to nazwa wydarzenia (Lista eventów do poszczególnych gier na silniku Source).
2. Drugi natomiast jest to nazwa wywołanej funkcji.
3. Opcjonalny tryb hook'a (o tym niżej ).
Hookowanie wydarzeń
-------------------------------------------------------------------------------------------------------------------------------------------------------
Kiedy wyłapujemy jakieś wydarzenie, mamy do wyboru trzy "tryby":
- Pre - Wyłapuje wydarzenie zanim zostanie zwolnione1.
- Post - Wyłapuje wydarzenie zaraz po tym jak zostanie zwolnione.
- Post_NoCopy - Wyłapuje wydarzenie, ale nie zapisuje o nim żadnych informacji.
Hookowanie wydarzeń używamy w jednym z następujących celów. Aby zorientować się, który tryb użyć, zobacz listę poniżej:
- Blokowanie wydarzenia (Zapobieganie jego zwolnieniu)
- Zawsze Pre
- Zmienianie wydarzenia (dokładniej jego paramterów )
- Zawsze Pre
- Działania w wydarzeniu (działania przed/pro zakończeniu wydarzenia)2
- Pre jeśli twoje działanie musi mieć miejsce (lul, nie jestem tutaj pewien w tłumaczeniu ) akcją silnika.
- Post jeśli twoje działanie musi mieć miejsce po akcji silnika.
- PostNoCopy jeśli twoje działanie jest Post i wymaga tylko nazwy wydarzenia.
UWAGA! Nigdy nie potrzebuje unhook'owania eventu, kiedy plugin przestanie z niego korzystać. Zrobi się to samoczynnie.
Blokowanie wydarzeń
-------------------------------------------------------------------------------------------------------------------------------------------------------
Blokowanie wydarzeń jest prostsze, niż myślisz ! Powiedzmy, że chcesz zablokować śmierć poprzez strzał w głowę.
public OnPluginStart() { HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre) //Rejestrujemy śmierć wraz z trybem "Pre" } public Action:Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) { if(GetEventBool(event, "Headshot")) //Nasz if zostanie wywołany, jeśli śmierć jest wywołana strzałem w głowe { return Plugin_Handled //Zwracamy Plugin_Handled, które blokuje funkcje } return Plugin_Continue //Jeśli if się nie spełni przechodzimy dalej zwracając Plugin_Continue }
Zmienianie wydarzenia
-------------------------------------------------------------------------------------------------------------------------------------------------------
Zmienianie wydarzenia również jest proste. Wydarzenia modyfikujemy w hook'u "pre". Na przykład, ustalmy, że chcemy usunąć headshot'a ze wszystkich eventów.
public OnPluginStart() { HookEvent("player_death", Event_PlayerDeath, EventHookMode_Pre) //Wyłapujemy event } public Action:Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) { SetEventBool(event, "headshot", false) //Ustawiamy zmienną typu logicznego (o ile dobrze pamiętam, tak to się nazywało xd) headshot na false, czyli blokujemy możliwość zabicia strzałem w głowę. return Plugin_Changed }
Upewnij się, że zwracasz Plugin_Changed zamiast Plugin_Continue, kiedy modyfikujemy event lub jego parametry.
Hook "post"
-------------------------------------------------------------------------------------------------------------------------------------------------------
Hooki z parametem post są domyślne i będą zwykle najczęściej używane. Na przykład, ustalmy, że chcemy "wydrukować" wiadomość do każdego gracza, że zginął:
public OnPluginStart() { HookEvent("player_death", Event_PlayerDeath) //Rejestrujemy event } public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) { decl String:weapon[64] //Deklarujemy zmienną typu string new victimId = GetEventInt(event, "userid") //Tworzymy zmienną victimID oraz przypisujemy jej pobieranie id ofiary new attackerId = GetEventInt(event, "attacker")//Tworzymy zmienną attackerID oraz przypisujemy jej pobieranie id zabójcy new bool:headshot = GetEventBool(event, "headshot") //Tworzymy zmienną typu logicznego oraz przypisujemy za zadanie pobieranie informacji o zabiciu z głowy GetEventString(event, "weapon", weapon, sizeof(weapon)) //Pobieramy nazwę broni krótko mówiąc :D decl String:name[64] //Deklarujemy zmienną typu string new victim = GetClientOfUserId(victimId) //Z tego co wyczytałem to funkcja getclientofuserid tłumaczy id user'a na prawdziwy index gracza. W tym przypadku otrzymamy id ofiary new attacker = GetClientOfUserId(attackerId) //To co wyżej, z tym, że otrzymamy id zabójcy GetClientName(attacker, name, sizeof(name)) //Pobieramy nick zabójcy PrintToConsole(victim, "You were killed by \"%s\" (weapon \"%s\") (headshot \"%d\")", name, weapon, headshot) //Tego już nie będę objaśniał. Jeśli znajdę czas znajdzie się to, w którymś z moich przyszłych poradników ^^. }
Uwaga! Zwracaną wartością dla hooków post jest ignore, więc tag "Action" nie jest wymagany.
Hook "PostNoCopy"
-------------------------------------------------------------------------------------------------------------------------------------------------------
Na końcu, istnieją pewne hook'i, którym potrzebna jest tylko nazwa wydarzenia. PostNoCopy jest specjalnie zoptymalizowany do tego zadania. Podczas przechodzenia z Pre do Post, SourceMod musi powielać wydarzenie i jego wszystkie pary klucz/wartość. PostNoCopy zapobiega tej sekwencji.
Powiedzmy, że chcemy wiedzieć kiedy pewna sekwencja wydarzeń jest wywoływana.
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) }
Należy pamiętam, że normalnie Hook'i Post nie wymaga wartości. Jednakże, parametr event zawsze powinien być równy INVALID_HANDLE. Zatem parametr name musi być stosowany zamiast GetEventName.
UWAGA! Mogą pojawić się w pewnych momentach błędy w tłumaczeniu lub inne drobne błędy. Może to wynikać z mojego lekkiego niedouczenia oraz dziur spowodowanych ch*jowym systemem nauki w szkołach. Krytyka mile widziana (bez przesady ). Za wszystkie błędy bardzo przepraszam :<.
Oryginał: www.wiki.alliedmods.net/Events_(SourceMod_Scripting)
1O co chodzi z tym zwolnione . W oryginale było fired, czyli zwolnione. Nie mogłem znaleźć jakiejś sensownej alternatywy, więc tłumacze to w sensie, że silnik przetrzymuje wydarzenie, a następnie je zwalnia .
2Nie jestem pewien tego tłumaczenia.