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

Przydatne funkcje + Ciekawostki o nichLogarytm, forwardy, itd.

nie chce mi sie tagowac

  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
1 odpowiedź w tym temacie

#1 BlackPerfum

    Pseudo interakcja??

  • Power User

Reputacja: 459
Wszechobecny

  • Postów:575
  • Lokalizacja:...
Offline

Napisano 04.05.2014 01:09

*
Popularny

Witam dawno tu mnie nie było dlatego na powrót chciał bym wam przekazać w użytek parę ciekawych i uproszczających życie funkcji
 
Dobrze zaczynajmy
 
Pierwszą taką funkcją będzie nikomu nie znane SearchKey. Tak to wygląda:
SearchKey(value,keys)
{
	return floatround(floatlog(float(value & keys),2.0))
}
Taka mała niepozorna funkcja zastępuje całkiem dużo kodu.
 
value - wartość w której szukamy
keys - suma bitowa
 
Co ona robi takiego? Hmm najprościej ujmując szuka w zmiennej value bitów ze zmiennej keys i zwraca nr znalezionego bitu (Standardowy logarytm).
Jest pewna uwaga co do zastosowania, gdyż tylko jeden bit może byc taki sam w obu zmiennych (inaczej zwróci nie pożądane wyniki)
 
Teraz pewnie wiele waszych mózgów przetworzyło taką oto informację: na co mi to?
 
Zarzucę pięknym przykładem:
 
Chcemy sprawdzić jaki gracz ma pistolet (broń drugorzędna),ten w plecaku lub aktualnie wyciągnięty.(zakładamy że gracz ma tylko jeden pistolet)
 
Normalnie większość z was zrobiła by tak:
new SB = 1<<CSW_ELITE | 1<<CSW_FIVESEVEN | 1<<CSW_USP | 1<<CSW_GLOCK18 | 1<<CSW_DEAGLE | 1<<CSW_P228
new weapons[32], numweapons,weapon;
get_user_weapons(id, weapons, numweapons);
	
for(new i=0; i<numweapons; i++)
	if((1<<weapons[i]) & SB)
		weapon = weapons[i];

//Jupii znaleźliśmy nasz pistolet :D
Oczywiście nie biorę pod uwagę gorszych przypadków szukania broni
 
Ja za to zrobił bym to tak:
new SB = 1<<CSW_ELITE | 1<<CSW_FIVESEVEN | 1<<CSW_USP | 1<<CSW_GLOCK18 | 1<<CSW_DEAGLE | 1<<CSW_P228
new weapons,weaponlist[32],num,weapon
weapons = get_user_weapons(id,weaponlist,num)
weapon = SearchKey(weapons,SB)

//I tak oto znaleźliśmy pistolet
Zastrzegam prawa do gnębienia tego przykładu gdyż jest dosyć głupi (nie widać dużej różnicy kodu ani 100% poprawności) bo na połowie aktualnych serwerów można mieć wiele broni na raz (także tego samego typu(typ tzn. pierwszorzędne/drugorzędne/itd))
 
Ale np. gdy mamy info o graczu:
enum {Latam=1,Plywam,Biegam,Chodze,Stoje,NicSieZeMnaNieDzieje,PosiadamC4,Pisze,WidzeHud,WidzeMotd,WidzeSay}
new Player[33]
To gdy chcemy sprawdzić co się z ziomkiem (ale tylko rzeczy między Latam a NicSieZeMnaNieDzieje) dzieje to musimy zrobić tak:
new CoRobiGracz
if(Player[id] & 1<<Latam) CoRobiGracz = Latam               //Ja latam jeee
else if(Player[id] & 1<<Plywam) CoRobiGracz = Plywam        // Plywam :D
else if(Player[id] & 1<<Biegam) CoRobiGracz = Biegam        // A jednak biegam
else if(Player[id] & 1<<Chodze) CoRobiGracz = Chodze        // Spacerek
else if(Player[id] & 1<<Stoje) CoRobiGracz = Stoje          // Zmeczylem sie
else if(Player[id] & 1<<NicSieZeMnaNieDzieje) CoRobiGracz = NicSieZeMnaNieDzieje // Totalny odpoczynek
Pamiętajmy iż może być więcej niż jeden bit aktywny!!!

Podalem 6 możliwości a czasem jest ich 31 no nie fajnie tak wypisywać 31 instrukcji dlatego z pomocą przychodzi nam ta funkcja:
new CoRobiGracz = SearchKey(Player[id],Player[id] & (1<<Latam|1<<Plywam|1<<Biegam|1<<Chodze|1<<Stoje|1<<NicSieZeMnaNieDzieje))

// I tak w oto sposob sie dowiedzielismy co sie dzieje z graczem (pewnie to ostatnie)
Ten przykład tez nie pokazuje prawdziwego potencjału tej funkcji ale co zrobić jak brakuje nam weny.
Różnicę tu akurat widać dużą. Z 6 instrukcji na 0 to jest dużo.
Teraz pytania: dlaczego użyłem:
float
floatlog
floatround
 
A bo nie ma logarytmu pracującego nie na floacie (w amxx'ie)
Jeśli się mylę to proszę o wskazanie mi poprawnego toku myślenia.
 
Jedziemy dalej. Kolejnym całkiem sprytnym trikiem użycia funkcji dostępnych w amxx'ie jest coś takiego:
 
Wycinek z pluginu nr. 1:
public Wywolaj()
{
	new R,X,text[6]
	formatex(text,5,"Zjem")
	X = CreateMultiForward("Tutorial",ET_IGNORE,FP_CELL,FP_STRING);
	ExecuteForward(X, R, X, text);
}

public Tutorial(id,text[])
{
        DestroyForward(id)
        server_print("%s noge tu byl",text)
}
A teraz drugi plugin:
public Tutorial(id,text[])
{
	new PolowaTekstu[10]
	formatex(PolowaTekstu,9,"%s ci",text)
	ExecuteForward(id, R, id, PolowaTekstu);
}
To wcale nie jakies wiekopomne odkrycie ale ciekawe. Wywołanie funkcji Wywolaj sprawi że plugin nr. 1 napisze w konsoli serwera Zjem ci noge tu byl. Prawda że ciekawe rzeczy robi ta funkcja, a najciekawsze jest to że przerzucam sobie po pluginach uchwyt do multi forwardu biggrin.png
 
I to działa o dziwo. Nie wiem czy ze wszystkimi uchwytami z modułu amxmodx tak sie da bo nigdy nie miałem powodów by to sprawdzać biggrin.png
 
Kolejna rzecz to pokazanie wam wszystkim czego nie powinno się robić.
public Menu(id)
{
	new menu = menu_create( "Menu" , "Menu_Zwrot");
	if(is_user_alive(id))	menu_additem(menu,"+ 50Hp")
	else	menu_additem(menu,"Ozyw")
	menu_additem(menu,"Pusta opcja")
	menu_setprop(menu, MPROP_PERPAGE, 1)
	menu_display(id, menu);
} 
Załóżmy że to menu samo się otwiera co 1 min. W pewnym przypadku graczu zostało otworzone te menu kiedy żył ale przez jego głupotę zginą i po śmierci widzi opcje +50Hp i nie kliknie jej (bo według niego ona nic mu nie da)
 
Niestety jako ludzie rozumni nie możemy go za nic winić i co tu zrobić nie każdy zna amxx'a i wie że w hook'u menu jest jeszcze raz sprawdzane czy zyje.
Dlatego trzeba by menu odświeżać ale nam się niee chce. Tyle kodu by gracz widział inną opcję. Za nic!!! Niech się potrudzi i zmieni stronę menu biggrin.png
Moje rozwiązanie biggrin.png (Całkiem głupie, ale przydaje sie gdy nie chcemy marnowac wysyłanych pakietow na durne menu, a czasem menu trzeba by odswiezyc ze 100 razy na 5 sek)
new const NameMenuItem[][] = {"+ 50Hp ","Ozyw"}

public Menu2(id)
{
	new menu = menu_create( "Menu" , "Menu_Zwrot");
	new cb = menu_makecallback("Menu_Callback");
	menu_additem(menu,"Taki tam tekst",_,_,cb)
	menu_additem(menu,"Pusta opcja",_,_,cb)
	menu_setprop(menu, MPROP_PERPAGE, 1)
	menu_display(id, menu);
}

public Menu_Callback(id,menu,item)
{
	static acces,callback,name[100],tryb,data[2]
	menu_item_getinfo(menu,item,acces,data,1,name,99,callback)
	
	switch(item)
        {
		case 0:
		{
			if(is_user_alive(id))	tryb = 0
			else tryb = 1
		}
		case 1:	return ITEM_DISABLED
	}

	if(contain(name, NameMenuItem[tryb]) == -1)
	{
		formatex(name,99,"%s^n^n Aby odswiezyc menu zmien strone",NameMenuItem[tryb])
		menu_item_setname(menu,item,name)
	}
	
	return ITEM_ENABLED
}
Funkcja contain jest tu bardzo ale to bardzo ważna. Dlaczego? A bo zmieniając cały czas w menu nazwy przyciskow nasze cudne menu sie buguje i powoli zjada nam text (nie zawsze do gracza dochodzi opcja multipart ale czemu?? nie mam pojęcia) na szczęście ten bug występuje kiedy menu ma więcej znaków niż 1000 czy 1024 nie mam pojęcia bo nie sprawdzałem dokładnie. Ale grunt że po zmianie strony odświeża + nie trzeba używać jakichś rozległych funkcji
 
Więcej wam nie powiem bo wyjdzie na to że dzisiaj opiszę wam wszystkie znane mi ciekawostki / funkcje (taak mam coś jeszcze w zanadrzu) a ja chcę jeszcze was czymś w przyszłości zaskoczyć biggrin.png

Użytkownik BlackPerfum edytował ten post 17.07.2014 14:53

  • +
  • -
  • 10
Chcesz napisać do mnie na PW to:
Spoiler

Mój tok myślenia jest błędny? Wskaż mi błąd zmienie to!

Aktualnie bije limit 32 graczy (łącze serwery) ale nadal są lagi przy zbyt dużym przesyłu informacji Dołączona grafika
Gra się płynnie do 40~50 graczy potem łącze pada i zamiast biegać ludzie się teleportują Dołączona grafika

#2 GT Team

    Ten lepszy xD

  • Zbanowany

Reputacja: 321
Wszechpomocny

  • Postów:1 435
  • GG:
  • Imię:Tomasz i Grzegorz
  • Lokalizacja:Wojkowice
Offline

Napisano 17.06.2014 19:20

Możesz dodać ciekawostkę, albo taki trik:

 

Niektórzy używając menu, muszą przesłać jakieś dane ID, przez 2 publice ( w których mamy menu ) co zmusza nas do tworzenia nowych zmiennych.

Można to ominąc w łatwy sposób, posłużę się przykładem z tego pluginu:

 
// Mam id, do przeslania
public Menu2(id, IDdoprzeslania)
{
    // i jak  tu je przeslac do handlera, nie tworzac nowej zmiennej ?
    // menu2 wykwolalismy korzystajac ze zmiennej wewnetrznej
    // wykorzystamy data
    // przypuscmy ze IDdoprzeslania jest liczba i ma wartosc 100
    // wiec zaczynamy
 
    new data[5]
    num_to_str(IDdoprzeslania, data, charsmax(data))
    // teraz liczbe 100 mamy w data
    // Nastepnie przeslemy data w ktoryms z item

    new menu = menu_create( "Menu" , "Menu_Zwrot");
    new cb = menu_makecallback("Menu_Callback");
    menu_additem(menu,"Taki tam tekst", data,_,cb)
    menu_additem(menu,"Pusta opcja",_,_,cb)
    menu_setprop(menu, MPROP_PERPAGE, 1)
    menu_display(id, menu);
}
// i w handlerze odbieramy te liczbe
public Menu_Zwrot(id,menu,item)
{
   //pominiemy srpawdzanie czy item tam menu ble ble ble
   // nazwy akurat teraz nie potrzebujemy, tylko data, wiec odwrocimy
   // nasze zmienne ( tzn ich wymiar) by nie tracic na pamieci (xD)
    static acces,callback,name[2],tryb,data[5]
    menu_item_getinfo(menu,item,acces,data,4,name,1,callback)
  // i teraz tak, jezeli potrzebujemy tego data, tylko kiedy wcisniemy 1 
  // (dlatego 1 poniewaz przy tworzeniu dalismy data do pierwszej opcji)
  // to wystarczy nam dac to static i m_i_g w if(item == 0) 
   // a jezeli potrzebujemy to w kazdej sytuacji, bez wzgledu na to, czy
   // jest to item == 0 czy item == 5
   // to zamiast menu_item_getinfo(menu, item ... dajemy 
   // menu_item_getinfo(menu, 0 ...  
   // aby odebrac te nasze 100, po wczesniejszym rozumowaniu 
   // pobieramy to data i zamieniamy na liczbe
   new liczba = str_to_num(data)
   // i o to nie musimy tworzyc zadnych zmiennych zew.
}

 

Mozemy wtedy przeslac z handlera, do dalszej funkcji za pomocą p2p. ( moja definicja, czyli z publica, do publica xD)


Nowa wersja Tower Defense 0.2 Alpha | Inne Mody -> Nowości

 






Również z jednym lub większą ilością słów kluczowych: nie chce mi sie tagowac

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

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