Scydo 397 Odesláno: 14. Leden, 2021 Share Odesláno: 14. Leden, 2021 (upraveno) 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 14. Leden, 2021 by Scydo Oprava. 1 1 Link to comment Share on other sites More sharing options...
Lukasz 336 Odesláno: 14. Leden, 2021 Share Odesláno: 14. Leden, 2021 Super! Zajímavé téma na topic a určitě se bude lidem hodit! 1 Link to comment Share on other sites More sharing options...
DuFF 85 Odesláno: 14. Leden, 2021 Share Odesláno: 14. Leden, 2021 (upraveno) 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 14. Leden, 2021 by DuFF 1 Link to comment Share on other sites More sharing options...
Scydo 397 Odesláno: 14. Leden, 2021 Author Share Odesláno: 14. Leden, 2021 (upraveno) 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 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 Edited 14. Leden, 2021 by Scydo Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now