Jump to content

návod Scydovy YSI návody | #9 | y_stringhash, y_unique, y_remote, y_vehicledata [***]


Scydo

Recommended Posts

YSI_Coding\y_stringhash + YSI_Coding\y_unique + YSI_Coding\y_remote + YSI_Game\y_vehicledata
*****

Ahoj. Jsem tu opět a mám pár dalších docela zajímavých objevů ze YSI, o které se s váma musím podělit.

YSI_Coding\y_stringhash

#include <YSI_Coding\y_stringhash>

hašování, přesněji hašovací funkce jsou funkce, které převedou pomocí matematické operace data do jednoduššího číselného údaje - více.
y_stringhash pracuje velmi podobně. Vezme řetězec údajů a hodí do do číselné podobny, která se pak snadněji podmínkuje. K čemu to je dobré?
Určitě známe všichni switch. Jestliže ne, více v návodě od @vEnd:

A jak všichni víme, jediné údaje, které se dají přepnout jsou obyčejné hodnoty, které se lze porovnávat jako jsou int, float či boolean. A porovnávat řetězec? Například, když si chceme udělat příkaz /drazba, kde bude mít v příkaze možnost napsat jestliže bude dražit auto, dům nebo zbraň? Ani náhodou. Jediná možnost je pomocí funkce strcmp(), ale to není zrovna ideální. Tak přichází y_stringhash s možností i přepnout řetězec a to pomocí funkce YHash():

switch (YHash(mujStr, .podminka = boolean)) {
	case _H<dum>: {
		// Sample code
	}
	case _H<auto>: {
		// Sample code
	}
	case _H<zbran>: {
		// Sample code		
	}
  • YHash = Jméno funkce.
  • mujStr = řetězec, který se hašuje,
  • .podmínka = přesnějí argumenty funkce (jsou hned 4, později vysvětlím),
  • _H = iterátor pro každý hašnutý údaj, ze slova Hash,
  • <dum>, <auto>, <zbran> = hašnuté údaje, nepřidávat uvozovky!

Ale pozor. YHash má zapnuté(true) case-sensitive, takže ahoj a Ahoj, aHoj apod nebude to samé. Jestliže chceme zahrnout i to, musíme ho vypnout(false) a používat jiný iterátor a to _I (od slova Insensitive):

#include <YSI_Visual\y_commands>
YCMD:event(playerid, o[], help) {
	switch (YHash(o, .sensitive = false)) {
		case _I<tunning>: {
			// Sample code
		}
		case _I<derby>: {
			// Sample code
		}
		case _I<dm>: {
			// Sample code		
		}
		/* 
			Zajímavost, vyhodí error, že už je definovaný:
		*/
		case _I<DM>: {
			// Sample code		
		}	

Co se týče podmínek, přesněji argumentů u YHash, tak jsou následujicí:
Jestliže chceme hašovat packnutý řetězec:

switch (YHash(mujStr, .sensitive = false, .pack = true))

A nebo jestliže chceme hašovat jen určitou délku(max length) řetězce:

switch (YHash(mujStr, .sensitive = false, .len = 5))

A teď pozor dvě a to dávejte si pozor jestliže se vám některý hašnutý údaj neopakuje(i když stejně, jestliže máte vypnuté case-sensitive tak vám to vyhodí chybu).
Y_Less také říká, že se může, i když velmi nepravděpodobně, stát, že i když jste si jistý na 100 % že nemáte žádný stejný údaj dvakrát a stejně vám to vyhodí chybu o shodnosti, tak stačí změnit 3. argument funkce type. Více o tom, jak to funguje a jak se obě používají - zde.

YSI_Coding\y_unique

#include <YSI_Coding\y_unique>

Často se nemusí ani nahrávat. Ve velké většině se nahraje automaticky spolu se y_hooks.
y_unique není nic více než jen hromada maker, které přidávají ke funkcím číslo jako jejich "id" a tak umožní používat stejnou funkci vícekrát. Nejčastějí se takové věci hodí do include.
Největší a nejužitečnější ukázka použití je právě y_hooks, protože nejen, že můžeme hookovat stejné funkce ale také můžeme je hookovat vícekrát:

#include <YSI_Coding\y_hooks>

hook OnPlayerConnect(playerid) {
	// Sample Code #1
}

hook OnPlayerConnect@2(playerid) {
	// Sample Code #2
}

hook OnPlayerConnect@3(playerid) {
	// Sample Code #3
}

Největší "id", které se dá použít je 999. Takže jich je určitě dost.
YSI_Coding\y_remote

#include <YSI_Coding\y_remote>

y_remote je prakticky jen vylepšené CallLocalFunction() a CallRemoteFunction(), nicméně, umožní dostávat chyby ještě před kompilací(například jestliže volaná fce nemá návratovou hodnotu a využívá se tak).
Má hned několik keywords. Jedno z nich je vytvoření samotné funkce pomocí remotefunc:

remotefunc LjmenoFunkce() {

}


// V jiném scriptu:
remotefunc RjmenoFunkce() {

} 

Dalším je voláním localfunc pro lokální a broadcastfunc pro mimo:

public OnPlayerConnect(playerid) {
	// Zavolá pouze v aktuálním scriptu:
	localfunc LjmenoFunkce();
	// Zavolá ve všech scriptech zároveň:
	broadcastfunc RjmenoFunkce();
	return 1;
}

Pokud jde o argumenty, tak:

localfunc LjmenoFunkce(cislo, Float:fcislo, string:rezezec[]) {
	pritnf("Cislo: %i, FCislo: %2.f Str %s", cislo, fcislo, retezec);
}

hook OnPlayerConnect@2(playerid) {
	localfunc LjmenoFunkce(11, 43.3, "ahojjoha");
	return 1;
}

A jak jsem již psal, jedna z výhod y_remote je, že může vracet i určité chyby, například právě s chybou návratové hodnoty:

#include <YSI_Core\y_utils>
remotefunc void:prosteBla(cislo) {
	printf("Cislo = %i", cislo);
}

public OnPlayerConnect(playerid) {
	new mojecislo = localfunc prosteBla(10);
	return 1;
}

// Vyhodí chybu, prosteBla nemá návratovou hodnotu

A ještě jedna věc. Jestliže máme deklarovanou funkci v jiném kódě v jiném scriptu, je potřeba u volání funkce s řetězcem přidat i délku(alespoň podle knihovny).
YSI_Game\y_vehicledata

#include <YSI_Game\y_vehicledata>

Tak jo. Tohle bude zajímavější.
Většina z nás si musela vždycky deklarovat jména modelů a nebo půl hodiny hledat id daného modelu pro náš FS. Teď ale díky y_vehicledata, které má prakticky všechny, není třeba. Funkce y_vehicledata mají tři hlavní kategorie:

  • Vehicle_ = Funkce berou a používají vehicleid, které vrací například CreateVehicle(),
  • Model_ = Funkce berou a používají modeild, které vrací právě GetVehicleModel(),
  • VMI_ = aka "Vehicle Internal Model" a mají vlastní speciální hodnotu a je specifické pro tenhle include. A k tomu používají i vlastní tag VMI:. Rozdíl oproti modelům je, že je vždy validní, můžou se použít jako index pro foreach a také mají právě tag, díky kterému se můžou odlišit.

Všechny tři kategorie si stojí i za jménem funkcí, takže například Vehicle_IsPolice(), Model_IsPolice() i VMI_IsPolice() je vše stejně definované.
Nyní funkce:

Vehicle_GetCategory(vehicleid);

Navrátí ID kategorie vozidla, které můžete vidět na wiki - odkaz.
Kdyžtak jména kategorií:

CATEGORY_UNKNOWN
CATEGORY_AIRPLANE
CATEGORY_HELICOPTER
CATEGORY_BIKE
CATEGORY_CONVERTIBLE
CATEGORY_INDUSTRIAL
CATEGORY_LOWRIDER
CATEGORY_OFFROAD   // Verze 1
CATEGORY_OFF_ROAD  // Verze 2
CATEGORY_PUBLIC
CATEGORY_SALOON
CATEGORY_SPORT
CATEGORY_STATIONWAGON  // Verze 1
CATEGORY_STATION_WAGON // Verze 2
CATEGORY_BOAT
CATEGORY_TRAILER
CATEGORY_UNIQUE
CATEGORY_RC

A teď pokud jde o funkce pro podmínky, tak těch je hned několik. A jsou právě kategorizované dle modelu daného vozidla:
(Poznámka: za jménoFce dosadit jednu ze tří kategorií, co chcete použít a to Model, Vehicle nebo VMI).

Vehicle_IsValid(vehicleid); // Jednoduše zjistí jestliže je vozidlo validní.
jménoFce_IsCar(vehicleid); 
jménoFce_IsTruck(vehicleid);
jménoFce_IsVan(vehicleid);
jménoFce_IsFire(vehicleid);
jménoFce_IsPolice(vehicleid);
jménoFce_IsFBI(vehicleid);
jménoFce_IsSWAT(vehicleid);
jménoFce_IsMilitary(vehicleid);
jménoFce_IsWeaponised(vehicleid); //Jakékoliv vozidlo, které může cokoliv "střílet" (započítává se i voda)
jménoFce_IsHelicopter(vehicleid); 
jménoFce_IsBoat(vehicleid);
jménoFce_IsPlane(vehicleid);
jménoFce_IsBike(vehicleid);
jménoFce_IsAmbulance(vehicleid);
jménoFce_IsTaxi(vehicleid);
jménoFce_IsOnWater(vehicleid) - //Vozidla, která nejsou ve CATEGORY_BOAT, ale mohou na vodu.
jménoFce_IsCoastguard(vehicleid); 
jménoFce_IsTrain(vehicleid); // I včetně vagónů.
jménoFce_IsLS(vehicleid); // Specificky pro policie ze LS.
jménoFce_IsSF(vehicleid); // 
jménoFce_IsLV(vehicleid); // 
jménoFce_IsTank(vehicleid);
jménoFce_IsFlowerpot(vehicleid);
jménoFce_IsTransport(vehicleid);
jménoFce_GetName(vehicleid); // Navrátí jméno modelu v packed řetězci.

Použití, určité jasné:

YCMD:stop(playerid, params[], help) {
	if (help)
		return SendClientMessage(playerid, X11_GREEN, "Zastavit hráče pro kontrolu");
	if (!IsPlayerInAnyVehicle(playerid)) 
		return SendClientMessage(playerid, X11_RED, "Nejsi ve vozidle");
	if (!Vehicle_IsCar(GetPlayerVehicleID(playerid)) || !Vehicle_IsPolice(GetPlayerVehicleID(playerid))) 
  		return SendClientMessage(playerid, X11_RED, "Nejsi v policejním autě");
		// Sample code
    }
	return 1;
}

A jaký je rozdíl mezi VMI a Model_/Vehicle_?
Jak jsem již psal, je to jaká si vlastní forma y_vehicledata, a mají všechny 3 body: vlastí tag, vždy validní a použití jako index.

new
	VIM:VIM_VehicleID = Vehicle_GetVIM(GetPlayerVehicleID(playerid));

new
	VIM:VIM_modelID = Model_ToVIM(GetPlayerVehicleID(playerid));

if (!VIM_IsPolice(VIM_modelID)) return ...;

Hlavní topic - odkaz

Gratuluju, dostali jste se na konec 🥳🥳🥳🥳.

Edited by Scydo
Oprava.
  • Děkuji (+1) 1
  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

Vďaka, doteraz som sa s y_vehicledata nestretol a ušetrí to kopec práce. 

 

Menší detail:

před 28minutami, Scydo said:

if (Vehicle_IsCar(GetPlayerVehicleID(playerid) && !Vehicle_IsPolice(GetPlayerVehicleID(playerid))) return SendClientMessage(playerid, X11_RED, "Nejsi v policejním vozidle");

Myslím, že takto by som mohol zastaviť hráča z akéhokoľvek (aj nepolicajného) vozidla, pre ktoré Vehicle_IsCar vráti false.

Edited by DuFF
  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

před 7minutami, DuFF said:

Myslím, že takto by som mohol zastaviť hráča z akéhokoľvek (aj nepolicajného) vozidla, pre ktoré Vehicle_IsCar vráti false.

Jo, menší překlep. Původně tam mělo být něco jiného ale pořádně jsem to nepromazal :v: Díky, opraveno.

před 7minutami, DuFF said:

Vďaka, doteraz som sa s y_vehicledata nestretol a ušetrí to kopec práce.

To rozhodně. Ja na něj narazil už od verze 4, kterou ale neměl pořádně vysvětlenou a původně to byla jen právě kopa proměnných a sem tam nějaká funkce, a tehdy právě bylo spíše lepší si udělat tu obří proměnnou se jmény modelů no :d

Edited by Scydo
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...