Scydo 397 Odesláno: 21. Červen, 2016 Share Odesláno: 21. Červen, 2016 MULTISAVE V JEDNOM SOUBORU ***** Na tenhle návod mě přivedl Ewwe s jeho problémem ohledně ukládání domů a vozidel... Kdo neví o co jde, tak Ewwe se snažil ukládat ve 2 souborech domy a vozidla. Akorát problém nastal v tom, že se načítaly domy ale nikoliv vozidla.Existuje takový trik jak se vyhnout tomuhle celému složitému ukládání... stačí pak načítat jediný soubor bez nutnosti formátovat cestu, a to za pomocí iterate a tagů v y_ini. Jelikož tag je v souborech nic více než jen poznámka, jde toho šikovně využití a nemusíme se bát, že se nám budou blbě načítat údaje, když jich tam budeme mít moc(jak mi někdo tvrdil, že se mu to děje). A naštěstí i poznámka lze zjistit, takže jak jsem říkal, jde to velice široce využít.Ukážeme si, jak vytvořit ukládání do takové formy: [House0] HouseName = "Dum c: 1" HouseOwner = "Mesto" HouseLock = false Vehicle0model = 560 Vehicle1model = 560 Vehicle2model = 560 HouseX = nějaké_float_číslo HouseY = nějaké_float_číslo HouseZ = nějaké_float_číslo [House1] HouseName = "Dum c: 2" HouseOwner = "Mesto" HouseLock = false Vehicle0model = 560 Vehicle1model = 560 Vehicle2model = 560 HouseX = nějaké_float_číslo HouseY = nějaké_float_číslo HouseZ = nějaké_float_číslo [House2] HouseName = "Dum c: 3" HouseOwner = "Mesto" HouseLock = false Vehicle0model = 560 Vehicle1model = 560 Vehicle2model = 560 HouseX = nějaké_float_číslo HouseY = nějaké_float_číslo HouseZ = nějaké_float_číslo [House3] HouseName = "Dum c: 4" HouseOwner = "Mesto" HouseLock = false Vehicle0model = 560 Vehicle1model = 560 Vehicle2model = 560 HouseX = nějaké_float_číslo HouseY = nějaké_float_číslo HouseZ = nějaké_float_číslo A furt je to v jednom souboru. Nemusíme načítat extra hodnoty, nemusíme nějak složitě zjišťovat cestu, stačí jenom povolit načítání tagů a to je vše. Začneme deklarováním proměnných. Budeme je potřebovat, abychom věděli, do čeho načtené údaje dát: #include <YSI_Data\y_iterate> #include <YSI_Storage\y_ini> enum eHouseInfo { HouseName[MAX_HOUSE_NAME + 1], HouseName[MAX_PLAYER_NAME + 1], bool: HouseLock, HouseVeh0, HouseVeh1, HouseVeh2, Float: HouseXPos, Float: HouseYPos, Float: HouseZPos } new HouseInfo[MAX_HOUSES][eHouseInfo]; A následně i iterátor, do kterého budeme přidávat id domů, které se budou načítat:new Iterator: House<MAX_HOUSES>; Teď, nejlepší na přidávání domů je si udělat fci. Vyhnu se detailům jako textlabel, některé podmínky... To si tam může pak přidat každý individuálně:stock AddHouse(const sHouseName[MAX_HOUSE_NAME+1], const sHouseOwner[], Float:fhX, Float:fhY, Float:fhZ, bool:bLock, ...) { Jelikož používáme iterate, nemusíme zjišťovat počet vytvořených domů... můžeme to jednoduše rovnou přes to zjistit, a to počtem přiřazených hodnot: if (Iter_Count(House) == MAX_HOUSES) A tady přichází ta novinka. Nemusíme přidávat nějaké housecount, nemusíme zjišťovat jestli je volno... můžeme na to využít fci, která nám zjistí nejbližší volné "id domu".new House_ID = Iter_Free(House); A nyni stačí jen přiřadit hodnoty(nesmíme samozřejmě zapomenout přiřadit do iterátoru i samotné id) HouseInfo[House_ID][HouseName] = sHouseName; HouseInfo[House_ID][HouseName] = sHouseOwner; HouseInfo[House_ID][HouseLock] = bLock; HouseInfo[House_ID][HouseXPos] = fhX; HouseInfo[House_ID][HouseYPos] = fhY; HouseInfo[House_ID][HouseZPos] = fhZ; new INI: Soubor = INI_Open("Houses.txt"); INI_SetTag(Soubor, sprintf("House%i", House_ID)); INI_WriteString(Soubor, "HouseName", HouseInfo[House_ID][HouseName]); INI_WriteString(Soubor, "HouseOwner", HouseInfo[House_ID][HouseName]); INI_WriteBool(Soubor, "HouseX", HouseInfo[House_ID][HouseLock]); INI_WriteFloat(Soubor, "HouseX", HouseInfo[House_ID][HouseXPos]); INI_WriteFloat(Soubor, "HouseY", HouseInfo[House_ID][HouseYPos]); INI_WriteFloat(Soubor, "HouseZ", HouseInfo[House_ID][HouseZPos]); INI_Close(Soubor); Iter_Add(House, House_ID); return (true); } Takže ano, prakticky normální ukládání. A teď k načítání... to bude to zajímavější. Protože pracujeme s tagem a v tagu je jen slovo House a číslo, tak právě z toho musíme vytáhnout čistě jenom to číslo. Což pro zběhlejší to není takový problém, ale i pro ty další vám ukážu jak na to. Nejdříve si extrahujeme do stringu sString jen to dané číslo:forward NahratData(tag[], name[], value[]); /* Všimněte si argumentu tag[] */ public NahratData(tag[], name[], value[]) { new sString[14]; strmid(sString, tag, 5, strlen(tag)); Nadále to číslo konvertujeme jako číslo: new House_ID = strval(sString); To je všechno... a už jenom načteme: INI_String("HouseName", HouseInfo[House_ID][HouseName]); INI_String("HouseOwner", HouseInfo[House_ID][HouseName]); INI_Bool("HouseX", HouseInfo[House_ID][HouseLock]); INI_Float("HouseX", HouseInfo[House_ID][HouseXPos]); INI_Float("HouseY", HouseInfo[House_ID][HouseYPos]); Iter_Add(House, House_ID); /* UPOZORNĚNÍ! Fce nesmí být na konci. jelikož jeho spec. návratová hodnota může ukončit celé načítání! */ INI_Float("HouseZ", HouseInfo[House_ID][HouseZPos]); return (false); } A nakonec ten samotný soubor načteme. Jak jsem již říkal: cestu nějak nemusíme formátovat, a nepotřebujeme extra hodnoty, stačí jenom načíst, a povolit načítání tagů:public OnGameModeInit() { INI_ParseFile("Houses.txt", "NahratData", .bPassTag = true); return (true); } Doporučuji pak vyčistit po ukončení scriptu(gamemodu) iterátor:Iter_Clear(House); A aby to nebylo málo, tak za pomocí iterátorů můžeme i zjistit, zda to dané id u kterého stojí hráč patří k domům:if (Iter_Contain(House, House_ID)) return (true); ODKAZYDoporučuji používat sprintf. Velice užitečná věcička: http://forum.sa-mp.com/showpost 612Kdyby někdo nepochopil, jak se s tím pracuje... tak jsem tuhle vychytávku používal hodně často, například u přidávání adminů do /admins pastebin.com/qZV5evSzPODĚKOVÁNÍxhunterx za radu s tímto trikem. 1 Link to comment Share on other sites More sharing options...
Administrátor Ewwe 434 Odesláno: 21. Červen, 2016 Administrátor Share Odesláno: 21. Červen, 2016 No a přesně takhle jsem to já neměl ani nechtěl Link to comment Share on other sites More sharing options...
Scydo 397 Odesláno: 21. Červen, 2016 Author Share Odesláno: 21. Červen, 2016 No a přesně takhle jsem to já neměl ani nechtěl Ano viděl jsem. Ty pracuješ stylem "proč to dělat jednoduše, když to jde udělat složitěji... a tak sem i to i víc líbí" Link to comment Share on other sites More sharing options...
Administrátor Ewwe 434 Odesláno: 21. Červen, 2016 Administrátor Share Odesláno: 21. Červen, 2016 Mě přijde že když budeš mít v jednou souboru 1000 domů a každej bude mít pod sebou 10 udajů + tag tak tak velkej soubor uz nemusi ani precist... Link to comment Share on other sites More sharing options...
Scydo 397 Odesláno: 21. Červen, 2016 Author Share Odesláno: 21. Červen, 2016 Mě přijde že když budeš mít v jednou souboru 1000 domů a každej bude mít pod sebou 10 udajů + tag tak tak velkej soubor uz nemusi ani precist... Tak nemusí to číst zase celý soubor. Můžeš pod jedním tagem jeden (nebo klidně i všechny) údaj/e vymazat, a s podmínkou, pokud je prázdný celé načítání přeskočit. (btw, viděl jsem server kde bylo max 300+- domů. 1000 by se snad už museli brát i jako dům ty pytle odpadků před tím domem v Groove s. ). Link to comment Share on other sites More sharing options...
Om3n 78 Odesláno: 21. Červen, 2016 Share Odesláno: 21. Červen, 2016 Tak nemusí to číst zase celý soubor. Můžeš pod jedním tagem jeden (nebo klidně i všechny) údaj/e vymazat, a s podmínkou, pokud je prázdný celé načítání přeskočit. (btw, viděl jsem server kde bylo max 300+- domů. 1000 by se snad už museli brát i jako dům ty pytle odpadků před tím domem v Groove s. ). Co sem zkoušel, tak jenom v San Fierru se dá vytvořit cca 600 domů, když počítam fakt jenom místa který nevypadaj jako obchod, ale jako vchod do domu. 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