Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

[ROZWIĄZANE] Dużo zmiennych, dużo modeli, menu wyboru - jak skrócić?Z 18 zmiennych w 2-3.


  • Zamknięty Temat jest zamknięty
12 odpowiedzi w tym temacie

#1 oeN.

    Wszechwidzący

  • Użytkownik

Reputacja: 95
Zaawansowany

  • Postów:294
  • Lokalizacja:Dom
Offline

Napisano 30.05.2015 07:51

Witam,

 

Znowu przychodzę z problemem odnośnie wielu zmiennych które mnie zaczynają irytować. Szybki opis:

Posiadam plugin który w bazie zapisuje graczowi jakie posiada modele, aktualnie struktura tabeli wygląda mniej więcej tak:

Nick | skin1 | skin2 | skin3 | skin4 | skin5 [...] skin12

I już jest lipa bo serwer odczuwa jak ma nagle to wszystko zapisywać.

Druga sprawa to zmienne...

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];

No jest lipa, prawda? Czym bardziej że mam zamiar dodawać ich więcej a boję się że w końcu będzie się źle działo i crash na crashu.

I teraz tak, można by to jakoś skrócić bez problemu gdyby nie jedna rzecz, menu w którym wybieramy jaki model chcemy używać i wybrany model się zapisuje do zmiennej aby go używać aż się nie zmieni, tutaj ok, mam do tego jedną zmienną ale żeby wybrać model najpierw trzeba go mieć, więc używam 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;
	
	else if(item == 4 && !g_PlayerSkin4[id])
		return ITEM_DISABLED;
	
	else if(item == 5 && !g_PlayerSkin5[id])
		return ITEM_DISABLED;
	
	else if(item == 6 && !g_PlayerSkin6[id])
		return ITEM_DISABLED;
	
	else if(item == 7 && !g_PlayerSkin7[id])
		return ITEM_DISABLED;
	
	else if(item == 8 && !g_PlayerSkin8[id])
		return ITEM_DISABLED;
	
	else if(item == 9 && !g_PlayerSkin9[id])
		return ITEM_DISABLED;
		
	else if(item == 10 && !g_PlayerSkin10[id])
		return ITEM_DISABLED;
		
	else if(item == 11 && !g_PlayerSkin11[id])
		return ITEM_DISABLED;
		
	else if(item == 12 && !g_PlayerSkin12[id])
		return ITEM_DISABLED;
	
	return ITEM_ENABLED;

No i właśnie, co z tym zrobić? Ktoś coś podpowie?


  • +
  • -
  • 0

#2 Rivit

    Godlike

  • Support Team

Reputacja: 1 319
Godlike

  • Postów:4 380
Offline

Napisano 31.05.2015 09:41

Suma bitowa


Popatrz jak w stockowym cod mod są przechowywane bronie gracza, minusem jest tylko to że ograniczenie jest do 32 lub 31
  • +
  • -
  • 1

#3 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 555
Godlike

  • Postów:11 980
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 31.05.2015 14:24

Suma bitowa i tablice dyynamiczne


  • +
  • -
  • 0

#4 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 31.05.2015 15:20

Tu nawet nie trzeba sumy bitowej czy tablic dynamicznych, po prostu zapisuj do jakiejś zmiennej jakąś wartość na podstawie której będziesz komuś dawał określony model.
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#5 wiwi249

    Wszechobecny

  • Użytkownik

Reputacja: 150
Profesjonalista

  • Postów:440
  • GG:
  • Imię:Wiktor
  • Lokalizacja:Tarnobrzeg
Offline

Napisano 31.05.2015 15:20

g_PlayerSkin[33][12]

Ale wtedy musialbys liczyc skiny od 0 albo od 1 i ustawić rozmiar drugiego indeksu na 13.

I wtedy ten callback można zrobić pętlą.


  • +
  • -
  • 1

Wykonuję strony internetowe, zlecenia AMXX i HLDS - w tym pisanie pluginów, ogarnianie serwerów, edycja i tworzenie modeli.

Potrzebujesz czegoś? Pisz!

 

"śpieszmy się pisać posty, tak szybko banują..." ~ sebul


#6 oeN.

    Wszechwidzący

  • Autor tematu
  • Użytkownik

Reputacja: 95
Zaawansowany

  • Postów:294
  • Lokalizacja:Dom
Offline

Napisano 31.05.2015 15:31

Myślałem właśnie nad sumą bitową ale byłby wtedy problem z zapisem do bazy, tak mi się wydaje.

 

Tu nawet nie trzeba sumy bitowej czy tablic dynamicznych, po prostu zapisuj do jakiejś zmiennej jakąś wartość na podstawie której będziesz komuś dawał określony model.

Właśnie to robię, mam w cholerę zmiennych i każda zmienna to inny model, tylko pomyśleć co by było przy 30 modelach, armageddon.

 

 

g_PlayerSkin[33][12]

Ale wtedy musialbys liczyc skiny od 0 albo od 1 i ustawić rozmiar drugiego indeksu na 13.

I wtedy ten callback można zrobić pętlą.

 

To nie jest taki głupi pomysł i na 99% wygląda na to że się sprawdzi.


  • +
  • -
  • 0

#7 Rivit

    Godlike

  • Support Team

Reputacja: 1 319
Godlike

  • Postów:4 380
Offline

Napisano 31.05.2015 17:57


Myślałem właśnie nad sumą bitową ale byłby wtedy problem z zapisem do bazy, tak mi się wydaje.

 

 

No właśnie nie...

 

1<<x, (gdzie x to jakaś liczba) to nic innego jak zwykła liczba, poczytaj o przesunięciu bitowym, także w zapisie tych skinów będziesz miał tylko jedną wartość, czyli sumę bitową wszystkich skinów.

 

Przetestuj to i zobacz co Ci wypisze na czacie:

#include amxmodx

public plugin_init()
{
   register_plugin("","","")
   register_clcmd("say /bitsuma", "a")
}

public a(id)
{
   client_print(id, 3, "1<<2 to tak naprawdę: %i", 1<<2)
   client_print(id, 3, "1<<12 to tak naprawdę: %i", 1<<12)
   client_print(id, 3, "1<<30 to tak naprawdę: %i", 1<<30)
}

  • +
  • -
  • 0

#8 oeN.

    Wszechwidzący

  • Autor tematu
  • Użytkownik

Reputacja: 95
Zaawansowany

  • Postów:294
  • Lokalizacja:Dom
Offline

Napisano 31.05.2015 18:55

Ja wiem jak działają operacje na sumach bitowych, jest to optymalne i w ogóle ale też się ciężko na nich operuje.


Użytkownik oeN. edytował ten post 31.05.2015 18:56

  • +
  • -
  • 0

#9 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 01.06.2015 12:20


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ę :)


  • +
  • -
  • 2

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#10 Rivit

    Godlike

  • Support Team

Reputacja: 1 319
Godlike

  • Postów:4 380
Offline

Napisano 01.06.2015 15:04

Gwyn, kocham Cię, te stocki wykorzystam do czegoś, jak zbadać jaki jest limit?

I czy zamiast tworzenia bool[33] to mogę właśnie na sumach bitowych? Czy braknie miejsca dla ostatniego
  • +
  • -
  • 0

#11 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 01.06.2015 16:38


Gwyn, kocham Cię, te stocki wykorzystam do czegoś, jak zbadać jaki jest limit?

 

Jaki limit? Limit tego ile możesz przechować bitów w 1 zmiennej? Spróbować przechować i sprawdzić czy wyszło :)

 


I czy zamiast tworzenia bool[33] to mogę właśnie na sumach bitowych? Czy braknie miejsca dla ostatniego

 

Zabraknie...


  • +
  • -
  • 1

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#12 oeN.

    Wszechwidzący

  • Autor tematu
  • Użytkownik

Reputacja: 95
Zaawansowany

  • Postów:294
  • Lokalizacja:Dom
Offline

Napisano 01.06.2015 19:01

Wszystko za wszystkich robisz :D

 

No co mogę powiedzieć, dziękuje Ci bardzo, problem rozwiązany, można zamknąć.


  • +
  • -
  • 0

#13 MAGNET

    SourceLearned ;)

  • Moderator

Reputacja: 661
Wszechmogący

  • Postów:1 535
  • GG:
  • Imię:Olek
  • Lokalizacja:Dalekoo
Offline

Napisano 04.06.2015 21:32

Wiadomość wygenerowana automatycznie


Ten temat został zamknięty przez moderatora.

Powód: Pomoc udzielona

Jeśli się z tym nie zgadzasz, report.png raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.


Z pozdrowieniami,
Zespół AMXX.PL
  • +
  • -
  • 0




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych