SUPER TIMOR Opublikowano Listopad 29, 2019 o 22:34 Udostępnij Opublikowano Listopad 29, 2019 o 22:34 Jak umieścić tłumaczenie w pluginie, jak doprowadzić do tego, by plugin wczytał nam plik z tłumaczeniem, który mu przygotujemy? Jak zakodować różne komunikaty, z różnymi zmiennymi? Całość omówimy na przykładzie pluginu, który losuje dwie osoby na mapkę i daje im flagę "a". Spoiler #include <sourcemod> #pragma newdecls required #define PREFIX "\x02★Darmowy VIP★\x01" // prefix, który będzie wyświetlany przed wiadomościami tekstowymi - \x01 i \x02 odpowiadają za kolory int iVipID[2]; // tablica, w której będziemy przechowywać dwa indeksy graczy, którym należy się VIP int iVIPSID[2]; // tablica, w której będziemy przechowywać SID tych dwóch graczy bool rozdano_vip = false; // zmienna typu boolean, która będzie służyła do określenia, czy losowanie na danej mapie już nastąpiło public Plugin myinfo = { name = "freeVIP", author = "SUPER TIMOR", description = "Darmowy vip dla 2 osób na mapę", version = "1.0.0", url = "http://steamcommunity.com/id/bonkwszlaufrocku" }; public void OnMapStart() // łapiemy funkcję wywoływaną przy zmianie mapy { CreateTimer(20.0, VIP1, TIMER_FLAG_NO_MAPCHANGE); // odpalamy timer, który za 20 sekund wywoła funkcję VIP1. Flaga TIMER_FLAG_NO_MAPCHANGE służy do zatrzymania timera, w przypadku gdyby mapa została zmieniona (np przez admina, który przez przypadek załadował inną mapę, niż chciał) rozdano_vip = false; // nie rozdaliśmy jeszcze VIP'ów, więc ustawiamy zmienną na fałsz for (int i = 0; i < 2; i++) // pętla, w której każdej "szufladce" tablicy nadamy wartość 0, czyli po prostu resetujemy ID klientów z darmowymi VIP'ami { iVipID[i] = 0; // o właśnie tutaj to robimy iVIPSID[i] = 0; // yeah } } public void OnClientPutInServer(int client) // gdy gracz wejdzie na serwer.. { if(!IsValidClient(client) || !rozdano_vip) // i nie rozdano VIP'a, lub gracz jest nieprawidłowy (patrz stock na samym dole) return; // no to cofamy dziada, nie możemy pozwolić sobie na dalszy przebieg funkcji for (int i = 0; i < 2; i++) // ale jeśli sytuacja wygląda inaczej - gracz jest prawidłowy, a VIP'y już są rozdane { if(iVIPSID[i] == GetSteamAccountID(client)) // sprawdzamy, czy SID któregoś z darmowych VIPów pokrywa się z ID klienta, który wchodzi na serwer AddUserFlags(client, Admin_Reservation); // i dodaję mu flagę "a" jeśli tak - flagi są rozpisane tutaj : https://sm.alliedmods.net/new-api/admin/AdminFlag } } public Action VIP1(Handle timer, any client) // funkcja, którą odpalaliśmy timerem na początku mapy, pamiętasz? :) { if(rozdano_vip) // jeśli jakimś cudem rozdano już VIP'y, a funkcja się odpaliła return Plugin_Stop; // no to basta dziadu int gracze = GetAllPlayers(); // ale jeśli nie, to używając stocka poniżej pobieramy ilość graczy bez VIP'a na serwerze if(gracze < 2) // jeśli jest ich mniej niż 2 { if(!rozdano_vip) // i jeśli nadal nie rozdano VIP'ów { PrintToChatAll("%s Losowanie 2 darmowych VIP'ów nie może się teraz odbyć. Próba zostanie ponowiona za 20 sekund!", PREFIX); // powiadamiamy CreateTimer(20.0, VIP1, TIMER_FLAG_NO_MAPCHANGE); // i odpalamy timer ponownie :) return Plugin_Continue; // pomijamy poniższe linijki, żeby przypadkiem nikomu VIP'a nie rozdać! } } iVipID[0] = GetRandomPlayer(); // jeśli kod wyżej nie przeszedł, czyli graczy jest wystarczająco, stockiem łapimy osobę bez VIP'a i zapisujemy jej ID w pierwszej szufladce naszej tablicy iVipID[1] = GetRandomPlayer(); // tutaj łapiemy do drugiej szufladki drugą osobę while(iVipID[0] == iVipID[1]) // no, a co jeśli plugin wylosował jedną i tę samą osobę? pętla warunkowa! jeśli ID gracza z szufladki nr 1 jest takie samo jak z szufladki nr 2, to pobieramy do drugiej szufladki kolejny raz. Tak długo, aż uda nam się pobrać inną osobę iVipID[1] = GetRandomPlayer(); // no i tu właśnie dzieją się te czary iVIPSID[0] = GetSteamAccountID(iVipID[0]); // zapisujemy SID graczy iVIPSID[1] = GetSteamAccountID(iVipID[1]); // zapisujemy SID graczy PrintToChatAll("%s Gratulacje! VIP'ami na tej mapie zostali : %N oraz %N!", PREFIX, iVipID[0], iVipID[1]); // oznajmiamy powodzenie rozdano_vip = true; // vipy rozdane, więc zmienną ustawiamy na prawdę return Plugin_Continue; // użyliśmy wcześniej, więc musimy użyć teraz. funkcja musi zwracać jakąś wartość } stock int GetRandomPlayer() // stock, dzięki któremu wcześniej pobraliśmy ID osoby nominowanej do zostania VIP'em :P { int clients[MAXPLAYERS + 1]; int clientCount; for (int i = 1; i <= MaxClients; i++) { if (IsClientInGame(i) && IsValidClient(i) && !ma_vip(i) && !IsFakeClient(i)) clients[clientCount++] = i; } if(clientCount < 2) return -1; return (clientCount == 0) ? -1 : clients[GetRandomInt(0, clientCount - 1)]; } stock int GetAllPlayers() // stock, dzięki któremu pobraliśmy wszystkich graczy bez VIP na serwerze { int gracze = 0; for(int i = 0; i <= MaxClients; i++) { if(!IsValidClient(i) || !IsClientInGame(i) || IsFakeClient(i)) continue; if(ma_vip(i)) continue; gracze ++; } return gracze; } stock bool ma_vip(int client) // stock, dzięki któremu sprawdzamy, czy gracz o podanym ID ma VIP'a (w tym wypadku jest to flaga a - ADMFLAG_RESERVATION { if(GetUserFlagBits(client) & ADMFLAG_RESERVATION) return true; return false; } stock bool IsValidClient(int client) // stock, dzięki któremu sprawdzamy, czy gracz jest prawidłowy { if (client > 0 && client <= MAXPLAYERS && IsClientConnected(client)) return true; return false; } No i OK. Zacznijmy od początku. 1. Poinformuj plugin o pliku z tłumaczeniem. W tym celu w funkcji startupu pluginu (OnPluginStart) należy załadować translacje. Użyjemy do tego funkcji LoadTranslations. W naszym przypadku będzie to wyglądało w ten sposób : public void OnPluginStart() { LoadTranslations("free-vip.phrases"); } 2. Napisz funkcję wyświetlającą tekst pobierany z pliku *.phrases.txt Pierwszym i jednocześnie dość istotnym krokiem w tym miejscu będzie zdanie sobie sprawy, że istnieją dwie możliwości zaimplementowania tłumaczenia w kodzie. %t - użyjemy, gdy wyświetlany tekst będzie bezpośrednio do gracza, przykładowo przez funkcję PrintToChat. %T - tego dziada użyjemy, gdy funkcja nie będzie bezpośrednio kierowana do gracza, a do serwera, zatem PrintToServer, LogMessage czy Format zawierający tłumaczenie musi być napisany w tej formie. Ważnym jest, żeby zaznaczyć w kodzie, jakiego języka mamy użyć do translacji. LANG_SERVER - funkcja użyje języka serwera. client(indeks klienta) - w wypadku, gdybyśmy używali przykładowo funkcji Format w celu podstawienia stringa do nazwy menu, funkcja użyje języka klienta. W naszym przykładzie skupimy się na funkcji PrintToChatAll, bo występuje ona dwa razy, i jako jedyna wyświetla tekst. Cytat PrintToChatAll("%s Gratulacje! VIP'ami na tej mapie zostali : %N oraz %N!", PREFIX, iVipID[0], iVipID[1]); PrintToChatAll("%s Losowanie 2 darmowych VIP'ów nie może się teraz odbyć. Próba zostanie ponowiona za 20 sekund!", PREFIX); Jak widać, pierwsza funkcja najpierw wyświetli zdefiniowany na początku pluginu prefiks, potem tekst i dwie zmienne. %N odpowiada za nazwę klienta, którego ID podaliśmy w argumentach za prefiksem. Druga funkcja wyświetli tylko prefiks i tekst. Jako, że prefiks jest zdefiniowany i jest stały, pominiemy go w tłumaczeniu. Cytat PrintToChatAll("%s %t", PREFIX, "Gratulacje", iVipID[0], iVipID[1]); PrintToChatAll("%s %t", PREFIX, "Losowanie odroczone"); 3. Stwórz plik z tłumaczeniem Na tym etapie zajmiemy się stworzeniem pliku tekstowego, którego nazwa będzie odpowiadała tej, którą zaznaczyliśmy w naszym pluginie na jego początku. Zatem - tworzymy plik free-vip.phrases.txt, a w nim: "Phrases" // koniecznie. Zawsze ta linijka musi się tak nazywać :) { "Gratulacje" // odniesienie do nazwy tłumaczonego wyrażenia w kodzie { "#format" "{1:N},{2:N}" //ustalamy w odpowiedniej kolejności typy zmiennych, które implementujemy w argumentach funkcji wyświetlającej tekst "en" "Congratz! This map VIP players are: {1} and {2}!" //tłumaczenie dla języka angielskiego "pl" "Gratulacje! VIP'ami na tej mapie zostali: {1} oraz {2}!" //tłumaczenie dla języka polskiego } "Losowanie odroczone" { //tutaj nie trzeba nic formatować, bo nie mamy żadnych zmiennych, więc przechodzimy od razu do tłumaczeń "en" "The draw of 2 free VIPs will be denied. The attempt will be renewed in 20 seconds!" //tłumaczenie dla języka angielskiego "pl" "Losowanie 2 darmowych VIP'ów nie może się teraz odbyć. Próba zostanie ponowiona za 20 sekund!" //tłumaczenie dla języka polskiego } } Plik należy umieścić w folderze addons/sourcemod/translations/ Inne typy zmiennych w "#format" : {1:d},{2:x},{3:f},{4:s},{5:c},{6:t} d lub i : wyświetli liczbę, cyfrę x : wyświetli zmienną w systemie szesnastkowym f : wyświetli zmienną typu float s : wyświetli zmienną typu string c : wyświetli jeden znak (UTF-8) t : służy do załączania kolejnej translacji Zezwalam na kopiowanie tego poradnika w dowolne miejsca internetu, niech niesie pomoc komu tam trzeba ? Fajnie by było, gdyby tak udostępniony poradnik został odpowiednio opisany kto jest autorem, oraz skąd pochodzi ? 3 Podziękuj! Z kodem rabatowym "TIMOR" zyskasz 10% rabatu na wszystkie usługi przez pierwszy miesiąc! Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się