Jump to content

návod Scydovy YSI návody | #10 | YSI_Players\y_text 📄 + y_languages 📚 [**]


Scydo

Recommended Posts

YSI_Players\y_text 📄 + YSI_Players\y_languages 📚
*****

Upozornění:

Spoiler

y_text i y_languages jsou celkem komplexní includy a skoro nikdy nefungovaly pořádně. Uživatelé velmi často hlásili různé chyby, nebo že jsou nefunkční. A to se týká jak verze YSI4.x tak i té nové YSI5.x.
Sám jsem to zkoušel, prošel desítky řešení bug issuses, i vyzkoušel jak 4.x tak 5.x a celé to zkoušel několik dní a i když se mi povedlo vyřešit přes sto varování, tak nakonec se mi nezobrazují ve hře. Takže, jestliže to chcete vyzkoušet, je to na vás, vám to třeba půjde(jsou samozřejmě i případy, kterým to šlo).

YSI_Players\y_text 📄

#include <YSI_Players\y_text>

Takže, nejdříve y_text. Je založena podobně jako, když si uděláme makra zpráv, které se například opakuji a nechceme je neustále psat:

#define ERROR_MSG_ALEVEL "[ ! ] {FFFFFF}Nemáš dostatečné oprávnění !"

	// Simple code
	if (var[playerid] == false) return SendClientMessage(playerid, 0xFF000000, ERROR_MSG_ALEVEL);
	// Simple code

Což je dobré. Můžeme kdykoliv zprávu změnit a nemusíme přepisovat stovky zpráv kdybychom chtěli cokoliv měnit. Nicméně problém je, že taková akce vyžaduje, aby se celý kód znovu kompiloval. A do toho přichází y_text. Díky kterému nejen, že můžeme měnit zprávu, ale můžeme jí změnit aniž by jsme museli znovu kompilovat kód.

Teď někdo zkušenější by si asi řekl: ,,Nojo, ale pokud chceš mít upravitelné zprávy a nemuset stále kompilovat, tak si je jednoduše uložíš a pak načteš. Tak co bylo na tom tak speciální?". A odpověď zní ano. Je to prakticky načítání řetězců. Zkusíme si takový menší hloupější příklad:

Spoiler

#define MAX_STRING_LEN (144)

enum ENUM_MSGS {
	MSG_HELLO[MAX_STRING_LEN + 1],
	MSG_BYE[MAX_STRING_LEN + 1],
	MSG_ALEVEL[MAX_STRING_LEN + 1]
}

new Messages[ENUM_MSGS];

#include <dof2>
public OnGameModeInit() {
	if (DOF2_FileExists("zpravy.txt")) {
		format(DOF2_GetString("zpravy.txt", "MSG_HELLO"), MAX_STRING_LEN, Messages[MSG_HELLO]);
		format(DOF2_GetString("zpravy.txt", "MSG_BYE"), MAX_STRING_LEN, Messages[MSG_BYE]);
		format(DOF2_GetString("zpravy.txt", "MSG_ALEVEL"), MAX_STRING_LEN, Messages[MSG_ALEVEL]);

	}
	return 1;
}

public OnPlayerConnect(playerid) {
	SendClientMessage(playerid, 0x00FF0000, Messages[MSG_HELLO]);
	return 1;
}

public OnPlayerDisconnect(playerid, reason) {
	SendClientMessage(playerid, 0x00FF0000, Messages[MSG_BYE]);	
	return 1;
}

#include <i-zcmd>
CMD:hp(playerid, params[]) {
	// Simple code
	if (AdminLevel[playerid] < LEVEL_MODERATOR) return SendClientMessage(playerid, 0xFF000000, Messages[MSG_ALEVEL]);
	// Simple code
}

 

Může to být o trochu lepší ale prozatím pracujme s tímhle.
Zatím to není tak hrozné, ale při více zprávách už začne být trochu problém(a navíc si na každou zprávu deklarovat proměnnou? Bruh).
Teď zkusíme to samé se y_text:

loadtext soubor[sekce];

public OnPlayerConnect(playerid) {
	Text_Send(playerid, $MSG_WELCOME);
	return 1;
}

public OnPlayerDisconnect(playerid, reason) {
	Text_Send(playerid, $MSG_BYE);	
	return 1;
}

YCMD:hp(playerid, o[], help) {
	// Simple code
	if (AdminLevel[playerid] < LEVEL_MODERATOR) return Text_Send(playerid, $ERROR_MSG_ALEVEL);
	// Simple code
}

A to je všechno :d.
Takže, jak si někteří všimli máme tu dvě zajímavosti a to funkce loadtext a Text_Send().
Funkce loadtext slouží právě na načtení údajů z našeho soubor.txt a přesněji všechen text pod tagem [sekce]. Jméno souboru i sekce jsou jedno jaké, klidně i server_text_benzinka.txt, ale jsou důležité tři body:

  • Koncovka souboru se musí shodovat se zkratkou ve Langs_Add(o tom později), protože z toho pak načítá i text, dle toho v jakém jazyce se má zobrazit a jaký hráč má nastavený,
  • Musíme přidat tag sekce textů, které má následně načíst,
  • Adresa daného souboru aby byla ve scriptfiles/YSI/tu

Takže příklad, vytvoříme si soubor Czech.CZ ve scriptfiles/YSI/ a v něm budou tři zprávy:

[cze]
MSG_HELLO = Ahoj, vítej na serveru.
MSG_BYE = Sbohem. Zase se někdy zastav.
MSG_ERROR = Někde nastala chyba!

Nyní v kódě si tenhle text načteme pomocí:

loadtext Czech[cze];

A můžeme začít používat kdekoliv pomocí funkce Text_Send(). Nesmíme ale zapomenout na znaménko $, které odkazuje právě na danou zprávu v souboru:

Text_Send(playerid, $MSG_HELLO);
Text_Send(playerid, $MSG_BYE);
Text_Send(playerid, $MSG_ERROR);

Ale tady zábava nekončí, protože Text_Send() je velmi chytrá funkce a nejen, že to může poslat hráčovi, ale také i všem hráčům v dané skupině:

new Group:gVips;

Text_Send(gVips, $MSG_VIP_EVENT);

Nebo i všem co mají nějakou naší proměnnou. Nicméně pokud to je naše proměnná a nic ze YSI, tak musíme před proměnnou přidat znak @ a všem, kdo mají tuto proměnnou true se odešle zpráva(nelze udělat pro všechny co mají false :( ):

new bool:bIsVip[MAX_PLAYER];

Text_Send(@ bIsVip, $MSG_VIP_EVENT);

Můžeme i odeslat formátovanou zprávu se specifikátory! Stačí si jen ten specifikátor přidat do našeho souboru:

[cze]
MSG_HELLO = Ahoj %q, tvoje ID je %i.
MSG_BYE = Sbohem %s(ID:%i).
public OnPlayerConnect(playerid) {
  	// Specifikátor %q je nick hráče a potřebuje jedno playerid
  	// aby to jméno zjistil, pak druhé je jeho id samozřejmě.
	Text_Send(playerid, $MSG_HELLO, playerid, playerid);
	return 1;
}

Specifkátory do souboru jsou:

  • %c - Character
  • %b - Boolean
  • %f - Float
  • %s - String
  • %q - Nick hráče, které zjistí z jeho ID
  • %g - Zobrazení nekonečna
  • %d + %i - Čísla
  • %l - Slovně boolean, cokoliv větší než 0 se zobrazí jako true, a 0 se zobrazí jako false.
  • %n - Příkaz, aka jak se zobrazí příkaz ve hře (kdyby uživatel chtěl změnit jejich jméno).
[cze]
MSG_HELP = Tento příkaz neexistuje, zkus se podívat do %n.
Text_Send(playerid, $MSG_HELP, YCMD:help);

Můžeme měnit i barvu naší zprávy. Ideální je na to použít naše y_colors, protože obsahují 4000 barev, tak na co si hledat vlastní?
Jsou dvě možnost jak přidávat barvy do zpráv, lepší a horší. Horší je pomocí #jméno ale ten není zavřený, takže může sežrat i kus ze slova, například #GOLDenter by zobrazilo pouze ter, protože # sežral -en pro barvu GOLDEN, takže lepší je používat ve {jméno}:

[cze]
MSG_CMD_HELP = {RED}[ ! ] {SNOW}Tento příkaz neexistuje, zkus {RED}/help

Lze použít i "X11" barvy, a postup je úplně stejný: RED -> X11_RED.
Nicméně, je tu přecijen pár limitů. Jeden z nich je, že zpráva nemůže být delší než 128(je možné, že se to už zvětšilo, nikde o tom nic není). Takže, jestliže chceme delší text, tak můžeme použít další "specifikátor"(ono je to spíše identifikátor) a to _číslo, příklad _3, _2, _1...:

[cze]
MSG_DLOUHY_1 = Tohle bude moc dlouhý text, takže si radši na to něco dáme. "_2" "_3"
MSG_DLOUHY_2 = Například budu tady psát náhodná slova takže něco jako slovosled
MSG_DLOUHY_3 = to vůbec nebude existovat, protože heh to tak určitě.
MSG_DLOUHE4 = Tohle už tam patřit nebude, protože nějáký vůl zapomněl přidat podtržítko před slovo DLOUHE.
Text_Send(playerid, $MSG_DLOUHY);

Teď, když víme jak na dlouhé texty, můžeme odeslat i dialog takhle? Ale samozřejmě, i na to má y_text funkce a hned na všechny styly dialogů:

Text_MessageBox(...);
Text_InputBox(...);
Text_ListBox(...);
Text_PasswordBox(...);
// Jestliže ale i tak chceme vlastní tak:
Text_DialogBox(playerid, DIALOG_STYLE_TABLIST_HEADERS, ...);

Příklad použití:

[czech]
DIALOG_NABOJE_TITLE = Dům a náboje
DIALOG_NABOJE = Napiš, kolik chceš schovat %s nábojů do domu číslo %i:
DIALOG_CANCEL = Zrušit
DIALOG_ACCEPT = Potvrdit
inline OnHouseWeaponAdd(...) {
	// Simple code
}
Text_InputBox(playerid, using inline OnHouseWeaponAdd, $DIALOG_NABOJE_TITLE, $DIALOG_NABOJE, $DIALOG_ACCEPT, $DIALOG_CANCEL, GetPlayerWeaponName(playerid), GetHouseIDbyPlayer(playerid));

YSI_Players\y_languages 📚

A teď přichází ten důvod, proč je důležitá i koncovka souboru. Jestliže budeme používát y_text(nebo cokoliv, co ho obsahuje), tak nejen, že to vyhodí varování o nevyužití funkce Langs_Add a nejen, že stejné varování vyhodí i do konzole serveru ale také se nenahrají pořádně naše texty, protože ať chceme nebo ne, y_text se nahrajou spolu s y_languages a jakmile y_languages zaznamená, že není žádný jazyk, hodí se jako #NO_LANGUAGE (-1) a nic nenačte ani nenajde. Jestliže chceme ale jen používat vymoženost y_text a ukládat si naše zprávy do souboru, tak není problém. Stačí ten jazyk deklarovat, nastavit hráči a to je všechno. Nicméně, knihovna přináší pár zajímavých pomůcek pro servery co mají více jazyků.
První co, tak si deklarujeme náš nový jazyk a jako vždy(a stejně jako y_groups) i on má vlastní tag:

// Soubor czech.CZ:
[all]
HELLO = Dobrý den.

//Soubor french.FR:
[all]
HELLO = Bonjour

//Soubor germany.DE:
[all]
HELLO = Guten Tag.
// Můžeme i více nahrání:
loadtext czech[all], french[all], germany[all];

Všimněte si, že všechny 3 soubory mají stejný keyword HELLO. A jak teda pak zobrazit hráči tu správou zprávu? To přece podle toho jaký má nastavený jazyk! Tak pojďme si je vytvořit:
Stejně jako y_groups i jazyky si musíme definovat:
Mají dva argumenty a to 2 písmena(zkratka+koncovka souboru odkud se ten text jazyka nahrává) a jak se ten jazyk bude zobrazovat. Oboje samozřejmě lze zobrazit pak následně ve hře:

public OnGameModeInit() {
	lCzech = Langs_AddLanguage("CZ", "Čeština");
	lFrench = Langs_AddLanguage("DE", "Deutsche");
	lGermany = Langs_AddLanguage("FR", "Français");	
	return 1;
}

Nyní ten jazyk samozřejmě musíme hráči nastavit. Můžeme buď jakmile se nastaví a nebo například v dialogu:

	new 
		string[27];
	format(string, sizeof string, "%s\n%s\n%s", Langs_GetName(lCzech), Langs_GetName(lFrench), Langs_GetName(lGermany));

	inline OnChangeLanguage(pid, ...) {
		// Sample code
		switch (listitem) {
			case 0: Langs_SetPlayerLanguage(pid, lCzech);
			case 1: Langs_SetPlayerLanguage(pid, lFrench);
			case 2: Langs_SetPlayerLanguage(pid, lGermany);
		}
		// Sample code
		return 1;
	}

	Dialog_Show(playerid, using inline OnChangeLanguage, DIALOG_STYLE_LIST, "Nastavení", string, "Potvrdit", "Zavřít");

A teď, protože máme už jazyky načtené, máme je vytvořené i nastavené, tak můžeme hráčům posílat zprávy podle toho, jaký mají nastavený jazyk, například:

YCMD:hello(playerid, o[], help) {
	return Text_Send(playerid, $HELLO), 1;
}

A to je všechno. Jak jsem již psal, y_languages si zjistí jazyk hráče podle toho jaký má nastavený. Pak dle toho vleze do správného souboru, vemze zprávu a zobrazí.

Další věc, co se může hodit, tak zobrazení i zkratky jazyka:

public OnPlayerText(playerid, text[]) {
	// Simple code
	if (...) {
		va_SendClientMessageToAll(X11_SNOW, "[%s] %s(%i): %s", Langs_GetCode(Langs_GetPlayerLanguage(playerid)), ReturnPlayerName(playerid), playerid, text);
		return 0;
	}
	// Simple code
	return 1;
}

Výsledek:
[CZ] Scydo(ID:0): Ahoj, jak se vede?
 

__________________________________________________________
Gratuluji, dostali jste se až na konec
🥳🥳🥳
Hlavní topic - odkaz

Edited by Scydo
pár oprav #2
  • Paráda! (+1) 1
  • Děkuji (+1) 1
  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...