Popular Post Scydo 397 Odesláno: 18. Duben, 2017 Popular Post Share Odesláno: 18. Duben, 2017 (upraveno) EASY BANKSYSTEM Takových návodů tu je tuna, proč přidávat další? Předtím, než tohle někdo z uživatelů napíše, rád bych řekl, že takové návody jsou roky staré, nefunkční a nebo naprosto prasácky zpracované.Než přistoupíme k návodu, tak bych chtěl zmínit pár bodů, které v tomto návodě nebudu vysvětlovat do podrobností(až ke konci k tomu budu mít pár poznámek): Vizuální zpracování dialogů - To si může každý uživatel udělat idividuálně(v tom případě si proto si hlídejte délky v řetězcích !), Větší počet bankomatů - Chci se spíše zaměřit na ukázku, jak jednodušše na takový systém. Samozřejmě, lze i snadno aplikovat na více bankomatů, Ukládání a načítání množství peněz v bance - Kromě toho, že každý používá jiný include na ukládání a načítání, tak opravdu nemám v úmyslu ukazovat, jak ukládat jednu proměnnou. ZAČÍNÁMESamozřejmě, nahrajeme si základní include a_samp.#include <a_samp>Budeme potřebovat nějakou proměnnou, kam se bude vpisovat počet peněz v bance:new Banka[MAX_PLAYERS];Jelikož víme, že určitě nebudeme zadávat záporná čísla, a přes fci strval může projít záporné znaménko, tak pro jistotu si přidáme fci, aby zjišťovat čistě jen a pouze čísla:stock OnlyNumbers(input[]) { new i; while (i != strlen(input)) if (input[i] <= '9' && input[i] >= '0') i++; else return false; return true; }Nakonec, by bylo dobré si pojmenovat nějak id dialogů, aby si to pak každý mohl individiálně upravit. Můžeme zvolit buď preprocesorovou cestu a nebo přes výčet hodnot. My použijeme výčet hodnot a začneme například hodnotou 6666:enum { DIALOG_BANKA = 6666, DIALOG_BANKA_VLOZIT, DIALOG_BANKA_VYBRAT } Pro lajky Výčer hodnot(enum), přiřadí první proměnné ve výčtu(DIALOG_BANKA) hodnotu a řadově pak přidává o 1 další(pokud není uvedeno jinak), takže výsledná hodnota poslední promněnné ve výčtu(DIALOG_BANKA_VYBRAT) bude 6668, protože DIALOG_BANKA začíná hodnotou 6666 a další DIALOG_BANKA_VLOZIT má hodnotu 6667.Ovšem, lze i použít tradičně preprocesory: #define DIALOG_BANKA (6666) #define DIALOG_BANKA_VLOZIT (6667) #define DIALOG_BANKA_VYBRAT (6668) OTEVŘENÍ DIALOGU BANKYTady jsem raději zvolil způsob přes příkaz. Proč? Jelikož, sice je jednoduché přes pickup, ale takhle má alespoň člověk jistotu, že se otevře pouze jednou a u bankomatu. Začneme podmínkou, zda je u daných pozic(jednoho z) bankomatu: public OnPlayerCommandText(...) { if (!strcmp("/banka", cmdtext, true)) { if (IsPlayerInRangeOfPoint(playerid, 1.0, Banka_x, Banka_y, Banka_z)) {Pozice daného bankomatu si pak může každý uživatel přidat jaké chce.Pokračujeme přidáním akce, zda je na daných souřadnicích a to, že se mu ukáže dialog, v opačném případě vrátí zprávu s informací, že neni u bankomatu(na dané pozici): ShowPlayerDialog(playerid, DIALOG_BANKA, DIALOG_STYLE_LIST, "Banka", "Vložit peníze\nVybrat peníze\nStav konta", "Vybrat", "Zavrit"); }else return SendClientMessage(playerid, -1, "Nejsi u bankomatu");Samozřejmě, nesmíme zapomenout správně uzavřít všechny bloky a správné návratové hodnoty.BANKA A LISTY V DIALOGUZačneme zavoláním samotného callbacku pro dialogy a jako první si přepneme dialogid, kvůli rychlosti(i když skoro nepatrné):public OnDialogResponse(...) { switch(dialogid) {A abychom pak neměli problém s bloky, přidáme si všechny 3 podmínky na všechny dialogy rovnou a všem přidáme podmínku, pokud hráč stiskl druhé tlačítko(Zavřít), tak se "nic" nestane a dialog "se zavře". Dále přiřadíme správném návratové hodnoty, a i samotnému callbacku: case DIALOG_BANKA: { if (!response) return true; /* code */ return true; } case DIALOG_BANKA_VLOZIT: { if (!response) return true; /* code */ return true; } case DIALOG_BANKA_VYBRAT: { if (!response) return true; /* code */ return true; }Začneme hlavním dialogem a to DIALOG_BANKA. Ten bude nejsnadnější. Začneme opět přepnutím, a tentokrát listitemu, a oběma dialogům(vložit a vybrat), protože oba budou typu "input", tak je ukážeme hráči a přiřadíme jim jejich dialogid: case DIALOG_BANKA: { if (!response) return true; switch(listitem) { case 0: ShowPlayerDialog(playerid, DIALOG_BANKA_VLOZIT, DIALOG_STYLE_INPUT, "Banka", "Napište částku, kterou chcete vložit", "Potvrdit", "Zavrit"); case 1: ShowPlayerDialog(playerid, DIALOG_BANKA_VYBRAT, DIALOG_STYLE_INPUT, "Banka", "Napište částku, kterou chcete vybrat", "Potvrdit", "Zavrit");A poslední listitem bude spíše informační, tak si tam rovnou formátujeme množství peněz v bance a ukážeme to v dialogu hráči: case 2: { new s_vBance[43]; format(s_vBance, sizeof s_vBance, "Na kontě máš momentálně %i$", Banka[playerid]); ShowPlayerDialog(playerid, DIALOG_BANKA, DIALOG_STYLE_MSGBOX, "Banka", s_vBance, "Zavrit", ""); } } return true; }Další dialog bude případ, kdy vkládá peníze(DIALOG_BANKA_VLOZIT). Začneme základní podmínkou a na to použijeme naší fci, zda hráč píše pouze čísla. Pokud ne, vrátí mu to zprávu: if (!OnlyNumbers(inputtext)) return SendClientMessage(playerid, -1, "Můžete vepsat pouze čísla !");Pak samozřejmě, aby nemohl neustále vkládat 0$: if (strval(inputtext) == 0) return SendClientMessage(playerid, -1, "Nelze vložit 0$ !");A nakonec, zda počet peněz které vkládá není větší, než u sebe skutečně má: if (GetPlayerMoney(playerid) < strval(inputtext)) return SendClientMessage(playerid, -1, "Nemáte takový obnos peněz !");Pak už jen 2 operace. První, přiřadíme k naší proměnné Banka hodnotu, kterou již má a k ní přičteme počet peněz, které hráč vkládá, a druhá, odečteme hráči daný počet peněz: Banka[playerid] = Banka[playerid] + strval(inputtext); GivePlayerMoney(playerid, -strval(inputtext)); return true; }A posledním dialogem bude případ, kdy peníze vybírá(DIALOG_BANKA_VYBRAT). Opět, začneme základní podmínkou a na to použijeme naší fci, zda hráč píše pouze čísla. Pokud ne, vrátí mu zprávu: if (!OnlyNumbers(inputtext)) return SendClientMessage(playerid, -1, "Můžete vepsat pouze čísla !");Opět, aby nemohl neustále vybírat 0$: if (strval(inputtext) == 0) return SendClientMessage(playerid, -1, "Nelze vybrat 0$ !");Nakonec podmínku, zda peníze, které vybírá nejsou větší, než které v bance ve skutečni jsou: if (Banka[playerid] < strval(inputtext)) return SendClientMessage(playerid, -1, "Nemáte v bankce tolik peněz !");A na úplny konec už jen prohodíme obě operace, a to způsobem, že první, přiřadíme k naší proměnné Banka hodnotu, kterou již má a odečteme počet peněz, které hráč vybírá, a druhá, přičteme hráči daný počet peněz: Banka[playerid] = Banka[playerid] - strval(inputtext); GivePlayerMoney(playerid, strval(inputtext)); return true; } JAK NA VÍCE BANKOMATŮ?To je prosté. Buď si(například) zjistit všechny pozice a pak je v příkaze všechny kontrolovat: if (!strcmp("/banka", cmdtext, true)) { if ( IsPlayerInRangeOfPoint(playerid, 1.0, xxx, yyy, zzz) || IsPlayerInRangeOfPoint(playerid, 1.0, xxx, yyy, zzz) || IsPlayerInRangeOfPoint(playerid, 1.0, xxx, yyy, zzz) || IsPlayerInRangeOfPoint(playerid, 1.0, xxx, yyy, zzz) || IsPlayerInRangeOfPoint(playerid, 1.0, xxx, yyy, zzz) || IsPlayerInRangeOfPoint(playerid, 1.0, xxx, yyy, zzz) ) { ShowPlayerDialog(playerid, ...Nebo, skoro stejným způsobem: Deklarovat si pole s výčtem hodnot x-ové pozice, y-ové pozice a z-ové pozice a pak v cyklu je všechny zjistit najednou(něco na způsob): enum __enum{ Float: XPos, Float: YPos, Float: Zpos} new Float:PoziceBank[MAX_BANKOMATU][__enum] = { {230.0, 110.3, 10.2}, {231.0, 111.3, 11.2}, {232.0, 112.3, 12.2}, {233.0, 113.3, 13.2}, {234.0, 114.3, 14.2}, {235.0, 115.3, 15.2}, {236.0, 116.3, 16.2}, {237.0, 117.3, 17.2}, {238.0, 118.3, 18.2}, {239.0, 119.3, 19.2}, {2310.0, 1110.3, 110.2} }; for(new i; i < MAX_BANKOMATU; i++) { if (IsPlayerInRangeOfPoint(playerid, 1.0, PoziceBank[i][0], PoziceBank[i][1], PoziceBank[i][2])) return ShowPlayerDialog(playerid, ... } Je tu několik návodů, kde by se hodilo už udělat novější a vylepšenější variantu. Pokud budou dobré ohlasy, udělám další návody.PS: snad jsou všechny kódy správně. Testoval jsem a bylo funkční(až na úplně poslední, to jsem netestoval), pokud přecijen bude někde nějaká chyba, napište mi SZ, ať tu není zbytečně spam.PSS: Ano, jde to udělat ještě lépe, ale já jsem to chtěl zpracovat jednoduchou a snadně-pochopitelnou cestou.Děkuji. Edited 20. Duben, 2017 by Ernst Remer 1 8 Link to comment Share on other sites More sharing options...
Rawy 18 Odesláno: 18. Duben, 2017 Share Odesláno: 18. Duben, 2017 Pro začátečníky dobrý. Rep+ Link to comment Share on other sites More sharing options...
DarkDragon_CZE69 17 Odesláno: 18. Duben, 2017 Share Odesláno: 18. Duben, 2017 Hezky rozepsané, popsané. Link to comment Share on other sites More sharing options...
Administrátor Ewwe 434 Odesláno: 19. Duben, 2017 Administrátor Share Odesláno: 19. Duben, 2017 Není zbytečné u té funkce OnlyNumbers kontrolovat každý znak jeslti ej číslo ? Není jednodužší rovnou zkontrolovat jestli je to celé číslo ? Link to comment Share on other sites More sharing options...
Globální moderátor HighPrint 177 Odesláno: 19. Duben, 2017 Globální moderátor Share Odesláno: 19. Duben, 2017 Ewwe má pravdu, ale z hlediska estetiky pro uživatele to bude hezčí. Přeci jenom když zadá čistě text a napíše se mu "Nelze vybrat 0$," tak to není vůbec ono. Jinak je tam redundantní kód if (!response) return true; return true; Tohle by mohlo jít mimo toho switche Možná by bylo ještě fajn ošetřit přetečení hodnotou 2^32-1 Link to comment Share on other sites More sharing options...
Administrátor Ewwe 434 Odesláno: 19. Duben, 2017 Administrátor Share Odesláno: 19. Duben, 2017 Ewwe má pravdu, ale z hlediska estetiky pro uživatele to bude hezčí. Přeci jenom když zadá čistě text a napíše se mu "Nelze vybrat 0$," tak to není vůbec ono. Jak to myslíš ? Link to comment Share on other sites More sharing options...
Globální moderátor HighPrint 177 Odesláno: 19. Duben, 2017 Globální moderátor Share Odesláno: 19. Duben, 2017 Říkals jestli není jednodušší zkontrolovat jestli je to číslo strval("asdasdgdg") ==> 0 strval("123sdfdsf") ==> 123 strval("asdas456564") ==> 0 Z 2/3 případů vrací 0, ve tvém případě by se uživateli vypsalo "Nelze vybrat/vložit 0$", což není úplně hezký Link to comment Share on other sites More sharing options...
Scydo 397 Odesláno: 19. Duben, 2017 Author Share Odesláno: 19. Duben, 2017 (upraveno) To bych mohl, to je pravda. Jsem fci přidal hlavně kvůli záporu, aby se pak nemuselo všude zjišťovat menší nebo rovno ale rovnou fakticky pouze kladná čísla. //edited, upraven topic. Edited 19. Duben, 2017 by Ernst Remer Link to comment Share on other sites More sharing options...
Hlavní moderátor vEnd 279 Odesláno: 20. Duben, 2017 Hlavní moderátor Share Odesláno: 20. Duben, 2017 Jak to myslíš ? Být to PHP, mohlo by strval vracet false a použil bys jednoduše operátor ===, tady to holt vrací nulu jak pro strval("0"), tak pro strval("asdf"). Zas ale nemůžu chtít zázraky od jazyka, který datové typy nerozeznává (o tagech Float, bool apod. nemluvme). Jinak návod je v pohodě. Aktuální návody pro tento a podobné systémy tu momentálně nejsou (alespoň co vím), takže se to hodí. Ty z roků 2008 a 2010 už akorát přidělávají práci helperům, kteří pak musí opravovat zastaralé kódy. 1 Link to comment Share on other sites More sharing options...
rEf 53 Odesláno: 20. Duben, 2017 Share Odesláno: 20. Duben, 2017 (upraveno) Krása! Edited 20. Duben, 2017 by rEf Link to comment Share on other sites More sharing options...
DuFF 85 Odesláno: 29. Srpen, 2020 Share Odesláno: 29. Srpen, 2020 (upraveno) Ospravedlňujem sa za otváranie starého topicu, ale všimol som dosť podstatný bug. Nie je ošetrený výber (ani vklad) zápornej čiastky. Funkcia OnlyNumbers mi síce zabráni napísať do dialogu priamo zápornú hodnotu, ale myslím, že mi nič nebráni docieliť zápornú hodnotu pomocou overflowu. Napríklad tak, že by som do dialogu na výber peňazí napísal sumu 2147483649 (2^31 + 1). Funkcia OnlyNumbers ma nezastaví, pretože každý znak v reťazci "2147483649" je platná číslica. strval("2147483649") vracia hodnotu -2147483647. if (GetPlayerMoney(playerid) < strval(inputtext)) ma nezastaví, pretože budem mať pri sebe viac $ ako -2147483647. Riadok GivePlayerMoney(playerid, -strval(inputtext)); nakoniec spôsobí, že mi server vyplatí 2147483647 $ aj napriek tomu, že som v banke nemusel mať uložené vôbec nič. Edited 29. Srpen, 2020 by DuFF 1 Link to comment Share on other sites More sharing options...
Scydo 397 Odesláno: 29. Srpen, 2020 Author Share Odesláno: 29. Srpen, 2020 (upraveno) před 28 minutami, DuFF said: Ospravedlňujem sa za otváranie starého topicu, ale všimol som dosť podstatný bug. Nie je ošetrený výber (ani vklad) zápornej čiastky...(více) To je sice dobrá přípomínka ale tohle je (k tomu ještě 3 roky starý) tutoriál a ne publikovaný FS. Návod je plně zaměřený na tvorbu Banky, to znamená na vklad, výběr a manipulace. Tvoje připomínka už spadá do kategorie optimalizace. Mimochodem, všimni si poslední věty: On 18. 4. 2017 at 21:37, Scydo said: PSS: Ano, jde to udělat ještě lépe, ale já jsem to chtěl zpracovat jednoduchou a snadně-pochopitelnou cestou. Tím myslím, že tohle je jedna z možností, jak zpracovat Banky, ne celý FS. Edited 29. Srpen, 2020 by Scydo Link to comment Share on other sites More sharing options...
Majitel ffredyk 172 Odesláno: 30. Srpen, 2020 Majitel Share Odesláno: 30. Srpen, 2020 před 15 hodinami, Scydo said: To je sice dobrá přípomínka ale tohle je (k tomu ještě 3 roky starý) tutoriál a ne publikovaný FS. Návod je plně zaměřený na tvorbu Banky, to znamená na vklad, výběr a manipulace. Tvoje připomínka už spadá do kategorie optimalizace. Mimochodem, všimni si poslední věty: Tím myslím, že tohle je jedna z možností, jak zpracovat Banky, ne celý FS. Náhodou je to velmi dobrá připomínka, kterou je potřeba brát v potaz nejen v těchto typech systémů. Overflow je vážná bezpečnostní díra, se kterou by se mělo počítat od základu 1 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