Jump to content

HighPrint

Globální moderátor
  • Příspěvků

    1335
  • Registrován

  • Aktivní

  • Vítězných dnů

    30

Everything posted by HighPrint

  1. Quiter mel pravdu, GetPlayerPoolSize vraci nejvyssi ID a v pripade ze se odpoji nejvyssi hrac (pripadne vic hracu s nejvyssimi ID) algoritmus nemusi a ani nebude spravne fungovat. Nejvhodnejsi variantou je to co uvedl vEnd s upravenym limitem – sizeof(racecar), ten nam zabezpeci ze projede cele pole Ovsem ted je potreba jeste zajistit pripad prepisovani vozidel – tedy pripad, kdy se pripoji do zavodu hrac s ID 5, vytvori se pro neho vozidlo racecar[5] = id_vozidla1 a odpoji se. Pripoji se novy hrac, ktery bude mit ID 5, prihlasi se do zavodu a prepise se jiz existujici promenna racecar[5] = id_vozidla2. Takze jeste osetrit v Disconnectu pokud je v zavodu. V tomhle mel zas pravdu Ernest. V podstate tady mel kazdej kus pravdy, ale dost zalezi na tom jak ten zavod mas implementovany. Shrnu ti pripady at to mas jednotnejsi a jak si to udelas (jak se ti to bude hodit) je na tobe. Predpokladam, ze vytvareni vozidel uz mas spravne: Pripad 1) Zavod skonci, je potreba smazat vozidla for(new i; i < sizeof(racecar); i++) // spustíme cyklus pro vsechny vozidla { if(racecar[i] == 0) continue; // ak sa racecar pre daného hráča rovná 0, preskočíme na ďalšie ID DestroyVehicle(racecar[i]); // zničíme vozidlo s ID, ktoré je uložené v racecar[i] racecar[i] = 0; // racecar nastavíme na 0 } Pripad 2) Hrac poskodil vozidlo do takoveho stavu, ze se znici public OnVehicleDeath(vehicleid, killerid) { // vehicleid - vozidlo, ktere bylo zniceno // killerid - id hrace, ktery ho "znicil", resp oznamil zniceni vozidla. Vetsinou se jedna o nejblizsiho hrace tedy ridic nebo pasazer. /* Hezky popis je na wiki http://wiki.sa-mp.com/wiki/OnVehicleDeath, kde je vypis pri zavolani tohoto callbacku. Muzes si vyzkouset koho hlasi jako killerid pri niceni */ if(racecar[killerid]){ // pokud racecar neni nulove, ekvivalentni s racecar[killerid] != 0 DestroyVehicle(racecar[killerid]); racecar[killerid] = 0; } return 1; } Pripad 3) Hrac vystoupi ze zavodniho vozidla (pripad, ktery mas osetreny ty a neni az tak uplne zly, rozhodne to neni blbost. Akorat ti ho upravim) public OnPlayerStateChange(playerid, newstate, oldstate) { if(oldstate == PLAYER_STATE_DRIVER && newstate == PLAYER_STATE_ONFOOT) { if(racecar[playerid]) { DestroyVehicle(racecar[playerid]); racecar[playerid] = 0; } } } return 1; } Ovsem jedna se jen o kostru niceni vozidel. Do nich si ovsem jeste vloz svoje veci okolo zavodu jako jestli zavod zacal / skoncil. Vyhodit hrace z vozidla aby ho to nebuglo pri zniceni, zpravy o diskvalifikaci apod.
  2. https://askubuntu.com/questions/263996/fixing-the-nvidia-graphics-screen-flicker-issue Vyzkoušej pak něco odtud, docela dost lidi ma podobne problemy
  3. co mas za grafickou kartu? Vyzkousel si virtualbox?
  4. Nerad ti kazím naději, hošánku, ale je to naprostej shit Logo jak z MS Word word artu, ikonky blbě pozicované, nehodí se tam. Banner je hnusně rozšířen. Linky v menu nejsou pořádně ani zarovnané A to jsou teprve jen věci co opravdu bijou do očí.
  5. Problém bude v podmínkách... Co jsou zač ty proměnné?
  6. Musíš si někam externě uložit první string
  7. Ří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ý
  8. 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
  9. Lze to ještě zjednodušit na for(new i = 0; i < 8; i ++) // 9 - 1 kvůli nulovému znaku Random_text[i] = 65 + random(52); Text: if(!Random_text[0]) { strcmp... Random_text[0] = 0; } A uživatel potom upravuje jen svoji délku v cyklu fajnšmekr by si všiml, že se jedná o znaky ASCII, tak by využil jiného "datového" typu
  10. 1) Procházíš úplně všechny property včetně nevytvořených. Na začátku než se vše zinicializuje je player pos na pozici 0,0,0, proto se zřejmě zobrazuje při připojení Fix: procházet jen existující Hint: var propertyid 2) Ten print je na první pohled, že se váže k dini_Exist Fix: Tabovat a předělat uzávorkování 3) Co je tohle za prasárnu? for(new p=0; p GetPlayerMoney(playerid)) { Tohle nemohlo projít bez erroru Also IsPlayerInSphere bych nahradil IsPlayerInRangeOfPoint
  11. pauto = CreateVehicle(560,x+2,y+2,z,310,3,3,-1); DestroyVehicle(pauto); Co udělá tohle?
  12. Jsem nezajímavej člověk, dělá mi radost, když na mě někdo kouká jak si ho honím
  13. Diky moc, cenim si odpovedi a beru tvoje pripominky na vedomi. Jenom bych chtel dodat par komentaru k pripominkam. Snazil jsem se spise popsat princip oop a kvuli tomu se pak michaly ruzne syntaxe 1) jasne byl to jen priklad abych ukazal, ze trida muze bejt clenskou metodou jine tridy, nechtel jsem pouzit nic co by okolo toho nebylo nezbytne 2) dobra poznamka, v tu chvili me to nenapadlo, ale zase... snazil jsem se to brat co nejvic objektivne, takze initializer list nema treba zminovana java. A dale protoze se za tim skryva zajimavejsich veci at uz z praktickeho hlediska tak i teoretickeho 3) jo, tuto informaci bych mohl pripsat, co se tyce ty chyby tak jsem si ji vedom. Michal jsem blbe jazyky, tak se za to omlouvam, kazdopadne diky za bystre oko 4) pripisu informaci, az budu dostupnej na pc. Diky! 5) o tom jsem nikdy neslysel, mel jsem za to, ze destruktor je vzdy zaruceny. Mohl bys mi vic popsat proc se na nej nelze spolehnout? 6) pripisu jako poznamku pro c++ 7) jsem si toho vedom, muj pokus o navod volit metodu "baby-steps" a postupne rozsirovat pojmy, proto jsem nechtel zatezovat na zacatku ctenare
  14. Dávat tak mocnej nástroj uživatelům
  15. https://strawpoll.com/5828515 Zabanovat Tanga
  16. Mód se podle mě nikdy neuchytí už jenom z důvodu, že když si jdu zahrát MP, tak očekávám interakci s více hráči. Rozhodně ne SP mise, které si mimochodem můžu také zahrát kdykoliv v lepé provedené verzi (tedy samotné SP). Uvítal bych spíše něco jako APB reloaded nebo aspoň SP mise s tím, že danou misi můžou začít jen ve 2 nebo více hráčích. Např k přerozdělování rolí při nějaké misi. Akorát se ty mise pak musejí šíleným způsobem vymakat, aby hráče to vůbec bavilo //edit: pardon, až teď jsem si přečetl závěr...
  17. http://forum.sa-mp.com/forumdisplay.php?f=71 Jsou tam daleko lepší hratelnější GM než na CZ/SK scéně. Also špatná sekce...
  18. Poslal jsem ti odkaz na dokumentaci funkce, kterou dáváš do podmínky. Máš nejmenší ponětí co ta funkce dělá? Máš tam i znázorněný příklad jak vypadá využití té funkce: Ofík: PutPlayerInVehicle(playerid, vehicleid, 0); Tvoje: PutPlayerInVehicle(playerid) Vidíš v čem je aspoň rozdíl? Nebudu ti opravovat podmínku dokud se nad tím nezamyslíš...
  19. http://wiki.sa-mp.com/wiki/Function:PutPlayerInVehicle oprav si tu funkci a zkus možná pochopit co dělá.
  20. Zbytek kódu si mám vycucat? Prosím o doplnění
  21. Úvod do OOP #1 Obsah: Úvod Pojmy Závěr 1. Úvod Jenom bych chtěl předem říci, že téma popisuji s nadsázkou, proto pokud objevíte nějakou blbost/nedostatek, tak mi to okomentujte a opravím/přidám. Co vlastně OOP je? Jedná se o Objektově-orientované programování a je jedním z nejvyužívanějších programovacích paradigmat1. Těch paradigmat je spoustu, určitě jste zaslechli o procedurální2, logické3 nebo funkcionální4 a další a další. Než si uvedeme nějaké základní pojmy, bylo by fajn si říct jaké jsou vlastně výhody OOP. Hlavní výhodou OOP je snažší údržba, rychlejší vývoj aplikace (z hlediska týmového), méně chybovost a rychlá orientace. Nevýhody – koncept třídy (vysvětlíme si později pojem) jedné osoby nemusí být sympatické té druhé. Většinou se proto dává důraz na to, že třídy se snaží být co nejvíce nezávislé nezasahujíc do něčeho co nemá zasahovat/co nemá v popisu práce. Dále chybou je zneužívání OOP, vytváření různých tříd na vše možné, co člověka napadne a špatně využití zapouzdření. Prakticky třídy vyžadují ohromnou dokumentaci a přípravu. 1 jednají se o styl, koncept a principy programování 2 nebo také imperativní – hlavní charakteristikou je výpočet pomocí posloupností příkazů a určuje přesný postup, např. C, PHP atd. Dělí se ještě do dalších podskupin, ale ty řešit nebudeme. 3 vyhodnocování matematickou logikou, např. prolog 4 matematické funkce a jejich výpočetní vyhodnocování – lambda kalkul, lisp, Zpravidla se jednají o rekurentní výpočty. 1. Pojmy Třída (class) je abstrakce entity, popisuje datový typ. Udává nám jaké vlastnosti (členy) bude mít objekt (také jako instance třídy případně proměnné). Mezi vlastnostmi se zařazují členské proměnné (atributy, položky, attributes) a interface také jako členské funkce (metody, methods). Třídy se mohou i libovolně skládat resp. objekt třídy x je členskou proměnnou třídy y. Na následujícím příkladu si všechny tyto pojmy ukážeme a vysvětlíme. Příklady se pokusím vždy co nejvíce předvádět objektivně (jelikož deklarace tříd apod se liší v závislosti v jakém jazyku programujete), pro upřesnění se budu spíše držet syntaxe C++ (nejsou avšak korektní). Uvedený příklad budu postupem času rozšiřovat dle nových pojmů co si zavedeme. Na OOP samozřejmě také existují spoustu prog. konvencí, ačkoliv v téhle kapitole se jich držet nebudeme kvůli znázornění základních pojmů Př. Zvolme třídu Web. Jeho atributy bude návštěvnost, url a majitel webu, který je objektem třídy Osoba. Obsahuje jen jednu členskou metodu IncreaseTraffic a to na inkrementaci návštěvnosti. Třída Osoba obsahuje jméno, věk a víceméně pohlaví. class Osoba { /* Member variables */ string name; int age; bool gender; } class Web { /* Member methods */ IncreaseTraffic(); /* Member variables */ int traffic; string url; Osoba owner; } /* V závislosti na jazyk, ve kterém programujeme může definice členských metod být jinačí. Pro přehlednost vždy definici funkce budu dávat vně tříd */ IncreaseTraffic() { ++traffic; } /* Deklarace objektu pak vypadá:*/ Web pawnocz = new Web(); /* alokace objektu Webu s názvem pawnocz */ pawnocz.url = "pawno.cz"; /* k jednotlivým atributům/metodám se přistupuje pomocí tečkové notace případně šipkové (např. v PHP). Zde nastavujeme atribut */ pawnocz.owner.name = "chytrak" /* nastavování členských proměnných objektu owner (patriot Print) */ pawnocz.IncreaseTraffic(); /* voláme funkci IT(); k pawnocz Konstruktory a destruktory. Co to je? Konstruktor se deklaruje jako metoda a volá se vždy při vytvoření objektu1. Tzn když jsme deklarovali objekt pawnocz, zavolal se konstruktor. Ten ale nemáme deklarovaný ani definovaný, proto si zpravidla kompilátor vygeneruje sám2. Obecně o konstruktorech je toho hrozně moc informací, ale v základní verzi si uvedeme jen inicializační bez parametrů a s parametrama. Destruktor se naopak volá při zaniknutí objektu. Dobré zmínit je, že konstruktor nelze explicitně volat na existující objekt. 1 poctivému čtenáři může v tuhle chvíli dojít, že při vytvoření objektu pawnocz se také a dokonce jako první zavolal konstruktor Osoba 2 pro zajímavost, C++ dokáže vytvořit inicializační konstruktor na vynulování proměnné. v Javě naopak vytvoří prázdný konstruktor. Více informací o C++ konstruktoru – http://en.cppreference.com/w/cpp/language/initialization Pojďme rozšířit náš příklad. Destruktor a konstruktor se deklaruje v závislosti na jazyku (např v PHP __construct, __destruct). Pro zpřehlednění si smažeme třídu Osobu a změníme majiteli datový typ. class Web { /* Constructor & destructor */ Web(); /* konstruktor MUSÍ mít stejný název jako třída a NEMÁ návratovou hodnotu */ ~Web(); /* pro destruktor platí to co u konstruktoru, akorát před názvem je '~' */ IncreaseTraffic(); int traffic; string url; string owner; } Web() { traffic = 50; } /* inicializační konstruktor bez parametru */ IncreaseTraffic() { ++traffic; } Web pawnocz = new Web(); /* při alokaci webu je nyní traffic rovna 50 */ pawnocz.url = "pawno.cz"; pawnocz.owner = "chytrak" pawnocz.IncreaseTraffic(); První větším pojmem, které se setkáme při OOP je zapouzdření (anglicky encapsulation). Jak jsem již trochu nastínil nějaké settery a gettery. Jedná se vlastně o viditelnost neboli přístup k členům třídy. Dělíme do tří skupin – public, private, protected. Public znamená, že je přístupná komukoli v programu. Private je přístupná POUZE a JEN POUZE v dané třídě (neplést si to s objekty). K protected dojdeme později, jelikož ještě neznáme pojem dědění. Pojďme si zase rozšířit náš příklad. V našem příkladu použiji C++ encapsulation, jelikož mi přijde takové hezčí na uvedení. Pro poznámku, třída v C++ je implicitně privátní, zpřístupníme informace tím, že viditelnost označíme jinak. Víc na příkladech class Web { public: /* veřejná viditelnost – implicitně (tedy defaultně) je private a nepíše se tam. */ Web(); /* konstruktor a destruktor musí být vždy PUBLIC */ ~Web(); IncreaseTraffic(); /* v Javě se nedělí na viditelnost jako v C++, ale označuje klíčovým slovem public/private/protected před metodou případně u proměnných. Viz public IncreaseTraffict(); */ string owner; private: /* privátní */ int traffic; /* v Javě private int traffic */ string url; } Web() { traffic = 50; } /* inicializační konstruktor bez parametru */ IncreaseTraffic() { ++traffic; } Web pawnocz = new Web(); pawnocz.url = "pawno.cz"; /* CHYBA, proměnná url se nachází v private sekci */ pawnocz.IncreaseTraffic(); /* VALIDNÍ KROK, metoda se nachází v public sekci */ pawnocz.owner = "chytrak"; /* VALIDNÍ KROK, proměnná owner je v public sekci */ Jak zpřístupnit privátním informacím ostatním? Tím že pro členskou proměnnou si vytvoříme getter a setter. Setter a getter zní možná sofistikovaně, ale není to nic jiného než obyčejná metoda na čtení případně zapisování. Teď ale přichází kámen úrazu – a to zbytečně vytváření setterů a getterů. Vytvoříme-li setter a getter pro privátní proměnnou, rovnou ji můžeme nechat zviditelnit celou. Proto je tady potřeba pořádně promyslet zda-li vůbec potřebujeme settery a gettery. Samozřejmě pokud máme proměnnou, kterou nechceme aby nám někdo cizí měnil obsah, postačí nám pouze getter pro čtení informací. Občas nechceme vůbec aby nám někdo četl informace, v tu chvíli nepotřebujeme ani jednu z metod. int getTraffic() { return traffic; } string getUrl(string u) { return url; } void setOwner(string o) { owner = o; } Pojďme si ještě zmínit klíčové kouzelné slovo this. Jedná se o proměnnou (většinou reference) na danou instanci nad kterou pracujeme. Používá se pro upřesnění s jakým objektem pracujeme, např pro rozlišování proměnné instance od parametru. Občas se hodí i předávat danou instanci dál v metod. Zároveň si rozšíříme příklad o konstruktoru s parametrem. class Web { public: Web(int traffic, string url, string owner); /* rozšířili jsme konstruktor o tři parametry */ ~Web(); IncreaseTraffic(); int getTraffic(); string getUrl(); setOwner(string owner); private: string url; int traffic; string owner; /* jenom drobná změna, owner jsme přesunuli mezi private */ } Web(int traffic, string url, string owner) { /*Vtip je v tom, že náš parametr se jmenuje stejně jako naše členská proměnná, tak jak to vyřešit? Můžeme přistoupit k proměnné slůvkem this->traffic = traffic; Pro zamezení tohoto konfliktu osobně třeba používám prefix "m_" --> tedy přejmenovat to na m_Traffic = traffic; */ this->traffic = traffic; /* v c++ se jedná o pointer, v javě reference. v PHP $this->traffic; */ this->owner = owner; this->url = url; } IncreaseTraffic() { ++traffic; } int getTraffic() { return traffic; } string getUrl() { return url; } void setOwner(string owner) { this->owner = owner; } Web pawnocz = new Web(50,"pawno.cz","chytrak"); /* voila, závorka není nic jiného než konstruktor. Lze vytvořit i lokální objekty Web pawnocz(50,"pawno.cz");, const Web pawno(50,"pawno.cz");...*/ print pawnocz.getUrl() + " má " + pawnocz.getTraffic() + " návštěvnost."; /* pawno.cz má 50 návštěvnost */ pawnocz.IncreaseTraffic(); pawnocz.setOwner("Lukáš Valenta"); /* už se nám nelíbilo, že je chytrak majitelem webu. */ Metody i proměnné můžou být static. Co to pro nás znamená? Co se týče metod, tak jsou podobné běžným funkcím, nemají implicitní instanci ani implicitní členské proměnné, ani this nejsou k dispozici. Jediné plus je mají přístup k třídním proměnným a volat třídní metody. Statické třídní proměnné jsou sdíleny instancemi třídy, a jsou dodržována standartními pravidly zapouzdření. Statické metody ani proměnné nás ale teď nezajímá. Zbývá nám ještě projasnit si tři základní pojmy – protected, polymorfismus a dědičnost Dědičnost slouží k vytvoření nových datových typ na základě něčeho čeho už máme. Proč jsem si nechal encapsulation protected až teď? Protected je víceméně private plus navíc to, že se věci pod touto viditelností dědí do ostatních podtříd. Pro znázornění využijeme třídu Osoba, kterou jsem si hezky nadeklaroval na začátku a rozšíříme ji o metodu pozdrav. Na tento příklad později navážeme polymorfismus. Vysvětlíme si příklad, chceme třídu Cech a Nemec a ty budou dědit Osoba, která se bude chovat jako abstraktní třída1. Každý vždy bude mít navíc členskou proměnnou a každý umí jen svůj jazyk. 1 abstraktní třída je třída, která nemá svoji implementaci a chová se jen čistě jako rozhraní pro třídy, které ho budou dědit. Na abstraktní třídy nelze vytvořit instance. Abstraktní třídy jsou užitečné, pokud víme, že všechny zděděné třídy jsou schopny provést implementaci abstraktních metod class Osoba { public: Osoba(); ~Osoba(); void pozdrav() = 0; /* = 0; znamená, že označujeme pozdrav() za abstraktní metodu v c++. V Javě a PHP je označení klíčovým slůvkem "abstract" před "class" */ protected: string name; int age; bool gender; } /* v Javě class Cech extends Osoba, v PHP tuším taky */ /* v C++ lze využít klíčové slovo public/private nebo vůbec nic. V případě public znamená, že ponechává vidtelnost zděděných věcí. Private je, že zděděné věci nemají viditelnost mimo této třídy a zakazuje polymorfismus */ class Cech : public Osoba { public: Cech(); ~Cech(); string getFavouriteBeer(); private: string favouriteBeer; } class Nemec: public Osoba { public: Nemec(); ~Nemec(); bool hasMustache(); private: bool mustache; } Polymorfismus umožňuje pracovat a používat jednotné rozhraní pro více (podobných) typů objektů. Podstatou polymorfismu je, zajistit přehlednost, jednoduchost jednotně pracovat se třídy velmi podobné, avšak trochu se lišící. Dokonce jsme si připravili rozhraní (viz výše Osoba) a poděděné třídy. Naším cílem je zajistit volání z databáze Osob1 takovým způsobem, aby každá osoba své národnosti volal svůj pozdrav2. 1 přeskočíme-li řeči o dynamických a statických vazeb, tabulce virtuálních metod neboli VMT (c++), zjišťování instance (java) 2 abychom nemuseli složitě zjišťovat jakou instancí jaké třídy, ale stačí volat a nechat na běhu programu ať si zvolí metodu sám. // Kód v C++ Osoba ** arr = new Osoba*[20]; for ( int i = 0; i < 20; i ++){ if(rand % 2 == 0) arr[i] = new Cech; else arr[i] = new Nemec; } for( int i = 0; i < 20; i ++) arr[i]->pozdrav(); // Guten tag / Ahoj v závislosti na random for( int i = 0; i < 20; i ++) delete arr[i]; // nesmíme zapomenout na uvolňování :-) 2. Závěr Tak došli jsme úspěšně ke konci. V dnešní kapitolě jste si doufám odnesli nějaké základy o OOP a jeho základní pojmy (zapouzdření, polymorfismus, dědění,...). Pokud máte v něčem nejasno, neváhejte a zeptejte se. Polymorfismus jsem trochu odbil, takže se za to omlouvám, ale snad jsem Vám nastínil trochu tý černé magie okolo ní. Pokud byste si přáli o ní něco více vědět, tak editnu trochu příklad a rozšířím ji. Pokud jsem něco uvedl špatně, prosím napište mi to. Pokud jsem na něco zapomněl, také mi to napište. Každopádně se s Vámi loučím a snad jsem někoho zaujal vyzkoušet si OOP.
  22. z logu nelze vyčíst nic, nemuvě o tom, že nevíme o jaký problém se jedná
  23. Rozdíl mezi ostatníma je, že ty se pawn neučíš. Nesnažíš se ani pochopit kód/errory nýbrž chceš po lidech aby ti ho opravili. Snaha musí být oboustranná jinak od těch "lepších" lidí nečekej pomoc. Ode mě rozhodně ne.
  24. A přesto spoušíš martinatoorův prison mód, který mimochodem je do každičkého detailu okopírované
×
×
  • Create New...