Ja wiem jak działają operacje na sumach bitowych, jest to optymalne i w ogóle ale też się ciężko na nich operuje.
No raczej nie...
Czy sprawdzanie czy gracz posiada daną flagę uprawnień jest niewygodne w AMXX? A działa to właśnie na bitach.
Zamiast tego:
new g_PlayerSkin1[33], g_PlayerSkin2[33], g_PlayerSkin3[33], g_PlayerSkin4[33], g_PlayerSkin5[33];
new g_PlayerSkin6[33], g_PlayerSkin7[33], g_PlayerSkin8[33], g_PlayerSkin9[33], g_PlayerSkin10[33];
new g_PlayerSkin11[33], g_PlayerSkin12[33];
umieszczasz to:
new g_PlayerSkins[33];
Zamiast tego:
if(item == 0)
return ITEM_ENABLED;
else if(item == 1 && !g_PlayerSkin1[id])
return ITEM_DISABLED;
else if(item == 2 && !g_PlayerSkin2[id])
return ITEM_DISABLED;
else if(item == 3 && !g_PlayerSkin3[id])
return ITEM_DISABLED;
// ... i tak dalej i tak dalej ...
umieszczasz to:
if (item > 0 && item <= 32 && !g_PlayerSkins[id] & (1<<(item - 1)) {
return ITEM_DISABLED;
return ITEM_ENABLED;
// NIC WIĘCEJ!
Dalej twierdzisz, że jest na tym operować gorzej?
Jak nie lubisz posługiwać się operatorami bitowymi to można sobie odpowiednie aliasy i funkcje do tego utworzyć.
Polecam stworzyć kilka funkcji:
/** 1. sprawdzenie czy gracz posiada model: */
stock user_hasSkin(id, skin) {
return g_PlayerSkins[id] & (1 << skin) == (1 << skin) // porównanie jest dodane po to, by zawsze otrzymywać 1 lub 0, co czasem może mieć znaczenie
}
/** 2. przypisanie graczowi modelu: */
stock user_giveSkin(id, skin) {
g_PlayerSkins[id] |= (1 << skin)
}
/** 3. odebranie graczowi modelu: */
stock user_takeSkin(id, skin) {
g_PlayerSkins[id] &= ~(1 << skin)
}
/** 4. wyczyszczenie graczowi modeli: */
stock user_takeSkin(id, skin) {
g_PlayerSkins[id] = 0;
}
// 2 dodatkowe funkcje, wydają się na pozór mało przydatne ale za chwilę się okaże do czego służą
/** 5. export modeli (do zapisu w nvault, bazie danych itp): */
stock user_writeSkin(id, string[], length) {
num_to_str(g_PlayerSkins[id], string, length);
}
/** 6. import modeli (z bazy danych, nvault itp): */
stock user_readSkin(id, string[]) {
g_PlayerSkins[id] = str_to_num(string);
}
W ten sposób posługujesz się bardzo wygodnymi funkcjami.
Mówią ludzie o limicie do 32 czy tam do 31 itemów. Owszem istnieje taki. Nie jestem pewien czy maksymalnie możemy przechować 32 czy 31 bitów (ostatni bit jest wykorzystywany jako znak liczby i może stanowić problemy, ale nigdy tego w praktyce w AMXX nie sprawdzałem) ale...
new g_PlayerSkins[33][2];
już mamy 62 itemy maksymalnie I tu się wyjaśnia dlaczego stworzyłem 2 dodatkowe funkcje (5 i 6) do eksportu i importu. Wystarczy teraz te 6 funkcji zmodyfikować:
/** 1. sprawdzenie czy gracz posiada model: */
stock user_hasSkin(id, skin) {
return g_PlayerSkins[id][skin/31] & (1 << (skin % 31)) == (1 << (skin % 31)) // porównanie jest dodane po to, by zawsze otrzymywać 1 lub 0, co czasem może mieć znaczenie
}
/** 2. przypisanie graczowi modelu: */
stock user_giveSkin(id, skin) {
g_PlayerSkins[id][skin/31] |= (1 << (skin % 31))
}
/** 3. odebranie graczowi modelu: */
stock user_takeSkin(id, skin) {
g_PlayerSkins[id][skin/31] &= ~(1 << (skin % 31))
}
/** 4. wyczyszczenie graczowi modeli: */
stock user_takeSkin(id, skin) {
for (new i=0; i<2; ++i)
g_PlayerSkins[id][i] = 0;
}
// 2 dodatkowe funkcje, wydają się na pozór mało przydatne ale za chwilę się okaże do czego służą
/** 5. export modeli (do zapisu w nvault, bazie danych itp): */
stock user_writeSkin(id, string[], length) {
new count = 0;
for (new i=0; i<2; ++i) {
count += num_to_str(g_PlayerSkins[id][i], string[count], length);
string[count] = ' ';
}
string[count] = '^0';
}
/** 6. import modeli (z bazy danych, nvault itp): */
stock user_readSkin(id, string[]) {
new count = 0;
new left[16], right[256];
for (new i=0; i<2; ++i) {
strtok(right, left, 15, right, 255)
g_PlayerSkins[id][i] = str_to_num(left);
}
}
W ten sposób nie musisz nic więcej zmieniać w kodzie (no może prócz wielkości tablicy na string do zapisania w nvault).
Pamiętaj tylko, żeby istniejący nvault przekonwertować. Możesz to zrobić w prosty sposób:
1. stwórz oddzielny plugin
2. zainstaluj i użyj w nim nVault Utility
3. wymyśl sobie jakiś specjalny klucz w którym będziesz przechowywał wersję pliku (musi być on unikalny - upewnij się żeby dla żadnego gracza się taki klucz nie zapisał. Dla przykładu użyj na jego początku czegoś, co nigdy nie wystąpi w nicku gracza, adresie IP ani steam ID)
4. odczytaj klucz wcześniej wymyślony, jeśli go nie ma to przyjmij że nvault jest w starej (pierwotnej) wersji. Jeśli jest, odczytaj wartość żeby się dowiedzieć jaką wersję masz.
5. Dokonaj konwersji (jeśli konieczna), lecąc po wszystkich kluczach w nvault (za pomocą Utility) i zmieniając format.
Plugin po udanej konwersji wyłączyć. Na przyszłość jak coś będziesz w pliku zmieniał to masz gotową bazę i zapisaną wersję