Skocz do zawartości

Nowy szablon forum

mygo.pl

Stworzyliśmy dla Was nowy wygląd forum. Z pewnością znajdziesz rzeczy, które wg Ciebie mogą zostać zmienione - wspomnij o tym w specjalnym wątku.

Czytaj więcej

Jak założyć własną sieć

serwerów CS

Zastanawiasz się nad prowadzeniem własnej sieci serwerów? Przeczytaj podstawowe informacje, na które należy zwrócić uwagę, przy takim projekcie.

Czytaj więcej

Tworzymy spis sieci

dodaj swoją

Dodaj sieć do której należysz, pozwoli to na promocję i budowę ogólnopolskiej bazy sieci CS.

Czytaj więcej

Jak dodać obsługę wielu języków do pluginu? (Tłumaczenie pluginu przez phrases.txt)


SUPER TIMOR
 Udostępnij

Rekomendowane odpowiedzi

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 ? 

 

2a.png


brand-logo.png

Z kodem rabatowym "TIMOR" zyskasz 10% rabatu na wszystkie usługi przez pierwszy miesiąc!

Odnośnik do komentarza
Udostępnij na innych stronach

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ę
 Udostępnij

×
×
  • Dodaj nową pozycję...