Jump to content

návod [YSI] Multisave v jednom souboru [**] #5


Scydo

Recommended Posts

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);
ODKAZY

Doporučuji používat sprintf. Velice užitečná věcička: http://forum.sa-mp.com/showpost 612
Kdyby 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/qZV5evSz


PODĚKOVÁNÍ

xhunterx za radu s tímto trikem.
  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

No a přesně takhle jsem to já neměl ani nechtěl :d

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í" :d

Link to comment
Share on other sites

  • Administrátor

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

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. :d).

Link to comment
Share on other sites

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. :d).

 

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

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...