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
 

BliBs_Pl - zdjęcie

BliBs_Pl

Rejestracja: 21.04.2011
Aktualnie: Nieaktywny
Poza forum Ostatnio: 19.12.2011 13:42
-----

#262677 Screen Menu

Napisane przez R3X w 25.06.2011 12:44

Screen Menu
v0.4.2

Biblioteka zamknięta w pliku .amxx do tworzenia kołowych menu. Można je spotkać w nowoczesnych grach jak Crisis czy Prototype, więc może się przydać też w CSie. Wybieranie opcji jest całkiem wygodne i spokojnie może zastąpić kilka bindów.

Maksymalna ilość opcji została na stałe zablokowana na wartość 8. API biblioteki jest zgodne z Nowym stylem menu Zobacz opis, z tym , że funkcje zaczynają się smenu_* zamiast menu_*

Przykładowe menu z załącznika ScreenMenu_Test.sma wygląda tak
Dołączona grafika

Wszelkie uwagi i propozycje są mile widziane.


Wymagane pliki:
dhudmessage.inc

Kilka wskazówek:
smenu_create("nazwa", "mcbScreenMenu", "mcbScreenMenuOver");

pierwsza funkcja jest wywoływana po zamknięciu menu i przekazuje informacje na jakiej opcji gracz zatrzymał się ostatnio
druga funkcja jest wywoływana po każdej zmianie aktywnej opcji, nie koniecznie musimy łapać to zdarzenie i można spokojnie pominąć ten parametr

poprawne użycie menu wymaga sekwencji smenu_display ... smenu_exit, w przykładowym kodzie naciśnięcie klawisza E pokazuje menu, a puszczenie E wyłącza menu; moment wyjścia jest traktowany jak wybór opcji, gracz wybiera to co go interesuje przez puszczenie klawisza

to samo możemy zrobić za pomocą komendy aktywnej


register_clcmd("+menu", "wlaczMenu");
register_clcmd("-menu", "wylaczMenu");

bind f +menu


w wlaczMenu robimy display w wylaczMenu exit, wtedy gdy gracz puszcza klawisz F plugin dostaje info o wybranej opcji

smenu_setprop umożliwia konfigurację menu, w następnych wersjach będzie tego więcej, obecnie mamy:
#define SMPROP_SHOW_DESCRIPTION 1 /* Czy pokazywac opis po najechaniu na opcje, param1=number */
#define SMPROP_NORMAL_COLOR 	2 /* Kolor normalny, param1=number[3] */
#define SMPROP_OVER_COLOR 	3 /* Kolor po najechaniu na opcje, param1=number[3] */
#define SMPROP_DISABLED_COLOR 	4 /* Kolor wylaczonej opcji, param1=number[3] */
#define SMPROP_TITLE_COLOR 	5 /* Kolor tytulu, param1=number[3] {0, 0, 0} ukrywa tytul*/
#define SMPROP_PREFIX 		6 /* Prefiks opcji, param1=string[8], domyslnie takie C z kropka*/
czyli można włączyć/wyłączyć pokazywanie podpowiedzi i pokolorować napisy po swojemu


Aktualizacja:
0.4.2
- wywalony spam na chacie
0.4.1
- kursor już nie wariuje
0.4
- wyeliminowano 2 bugi: smenu_display nie działał w callbacku oraz get_info nie pobierało info tylko 2 razy nazwę
0.3
- dodano dynamiczną wersję menu (bez stałego punktu widzenia)

0.2
- dwa nowe pola set_prop
#define SMPROP_TITLE_COLOR 	5 /* Kolor tytulu, param1=number[3] {0, 0, 0} ukrywa tytul*/
#define SMPROP_PREFIX 		6 /* Prefiks opcji, param1=string[8], domyslnie takie C z kropka*/
- wyświetlany tytuł menu
- nowe przykładowe pliki
- możliwość dostosowania położenia menu (komenda +smenu)

0.1
- pierwsza publikacja

Załączone pliki


  • +
  • -
  • 41


#253612 Portal Gun

Napisane przez DarkGL w 27.05.2011 22:34

Dołączona grafika
Pomysł rzucił abes i tak to jakos po trochu powstawało udostepniam poniewaz nie mam czasu sie tym zajmowac
kod nie jest idealny ale wydaje mi sie ze jest ok
plugin przenosi do cs'a portal gun'a znanego z gier Portal i Portal 2
podziękowania dla R3X

Dołączona grafika
give_portal <nick>

Dołączona grafika
// 1 or 2 difrent sprites 0 off this
portal_sprite 1

// 1 - no fall damage 0 - normal (no fall damage for person who have portal gun)
portal_fall_damage 1

// speed of portal bullet
portal_bullet_speed 1500

//how much money you must have to buy portal with /portal command in say negative number off this
portal_cost -1

//portal gun for free on spawn ? 1 - yes 0 -no
portal_spawn 0
po pierwszym uruchomieniu utworzy sie plik
portal.cfg w folderze configs

Dołączona grafika
Te video jest z aktualnymi modelami, reszta jest ze starymi
Aby wyświetlić w większej rozdzielczości, obejrzyj na YouTube.com (kliknij na tytuł)
http://www.youtube.com/watch?v=Y4pa3NMcEBU&hd=1

http://www.youtube.com/watch?v=1rXkDpvuHoY
http://www.youtube.com/watch?v=W6qolwCB5WA
http://www.youtube.com/watch?v=-wiDfqz0Dps

Dołączona grafika
w sma znajdziemy cos takiego
#define SOUNDS
#define SPRITES
//#define TEST
//#define TRACE_HULL
jesli dodamy // przed #define SOUNDS wylaczmy uzywanie dzwiekow przez plugin
przed sprites to wylaczmy sprites
usuwajac TEST spowodujemy dodanie funkcji ktorych uzywalem do testowania
TRACE_HULL przy takiej konfiguracji plugin sprawdza czy miejsce jest wolne za pomoca mojej funkcji jesli to odkomentujemy bedzie uzywac TRACE_HULLA lepiej mojej uzywac : P

#define MAX 32
tu podajemy ilosc slotow
(mniej pamięci zżera plugin)

Dołączona grafika
/portal w say'u

Dołączona grafika
Załączony plik  portal.sma   24,98 KB  4467 Ilość pobrań
  portal.amxx
Załączony plik  portal.amxx   29,09 KB  1440 Ilość pobrań

Załączony plik  portal.rar   2,74 MB  6825 Ilość pobrań

  • +
  • -
  • 60


#269435 Call of duty: Sprint effect (Klawisz shift)

Napisane przez diablix w 13.07.2011 18:06

Sprint - szybki bieg
by diablix

Wiele ludzi poszukiwało tego pluginu, więc jedziemy:)

Dołączona grafika

Naciskając klawisz SHIFT a właściwie przytrzymując poprostu biegniemy jednak jest limit.
Po zużyciu energii (wskaźnik czerwony) musimy czekać aż się "zregenerujemy" :)
W czasie biegu broń zmienia się na nóż i wszelkie akcje (atak, kucanie) zostają zablokowane.

Dołączona grafika

Dołączona grafika

Zamieszczam prezentację

http://www.youtube.com/watch?v=i8N7QAMLoyw

Dołączona grafika

  • Fakemeta

Dołączona grafika

W najbliższym czasie zostanie ukazana wersja DarkGL'a i zostanie ona podpięta w tym temacie :)

Załączone pliki


  • +
  • -
  • 23


#246556 Experience Mod v1.15 by funfel

Napisane przez mierzwi w 06.05.2011 19:17

Expierience Mod v1.15 by funfel
Witam, chciałbym wam przedstawić swoją małą pracę, którą robiłem na zamówienie, lecz w ostatniej chwili klient się rozmyślił, dlatego daję wam go do użytku publicznego. Plugin jest bardzo miły w obsłudze, przyjazne menu, brak !ColorChat'a!, dużo umiejętności, po prostu - cudo na HnS'y Dołączona grafika Teraz mogę się założyć ze w będzie ten expmod by xxx - normalne ;d


Dołączona grafika
Expierience Mod to tak zwany ExpMod, bardzo przydatny na serwery typu HideNSeek and Blocks (EasyBlocks, Medium, Hard).
Plugin posiada 21 umiejętności, 9 osiągnięć oraz sklep. Umiejętności możemy kupic od danego poziomu oraz kosztuje to nas 1 punkt, a punkty dostajemy za zdobyty poziom. W sklepie dodatki kupujemy za monety, które dostajemy za zabójstwo/przeżycie rundy/wygranie rundy. Za osiągnięcie danego osiągnięcia dostajemy nagrodę w postaci monet. AutoBindy to głowne menu pod V oraz użycie skilli pod H, umiejętności można samemu zbindować wchodząc w menu danej umiejętności (przycisk: Zbinduj np. niewidzialność i wpisujesz klawisz).

Spis umiejętności (czas, ilość lub moc zależy od punktów dodanych w daną umiejętność):
Zycie na start - dostajemy na start dodatkowe zycie;
Armor na start - dostajemy na start dodatkowy armor;
Odrodzenie - po śmierci mamy szanse na odrodzenie się;
Super knajf - zadajemy większe obrażenia nożem;
Soldzer - Dostajemy mniejsze obrażenia zadawane przez headsplash;
Niewidzialnosc - Możemy użyć niewidzialności na kilka sekund;
Tytan - Po użyciu jesteś odporny na headsplash przez kilka sekund;
Kamienne ciało - Masz szanse na uniknięcie ciosu;
Ninja[Tylko CT] - Cicho chodzisz przez kilka sekund;
Trutka - Otrówasz wroga na kilka sekund;
Dodatkowe doswiadczenie - Dostajesz dodatkowe doświadczenie przy zabiciu/przeżyciu rundy/końcu rundy;
Szansa na pistolet - Masz szansę aby wygrać pistolet na początku rundy;
Szansa na awp - Masz szansę aby wygrać awp na początku rundy;
Szansa na granat wybuchowy - Masz szansę aby wygrać granat wybuchowy;
Szansa na 2 granat zamrażający[Tylko T] - Masz szansę aby wygrać 2 granat zamrażający na początku rundy;
Regeneracja życia - Dostajesz co kilka sekund trochę życia;
Ruletka - Masz szansę aby wygrać coś w ruletce (doświadczenie, +/- życie, śmierć itp.);
Apteczka - Leczy nam w ciągu sekundy daną ilość życia;
Rozprysk[Tylko VIP] - Oślepia graczy w danym zasięgu (skill skopiowany z perka_by_peyote - nie obrazisz się?);
Supcio hejdz - Dotykając kogoś granatem wybuchowym zadajesz dużo obrażeń (na zasadzie rzucasz granat, trafisz nim w kogoś to on otrzymuje obrażenia, padnie to frag dla cb.);
Odepchnięcie - Odpycha graczy w danym zasięgu;

(ustawienia takie jak: od jakiego poziomu, moc, obrażenia, czas, zasięg można zmienić w bardzo prosty sposób, informacje w Inne Informacje)


Opis osiągnięć:
Frager: Zabij daną ilość osób;
Staly gracz: Połącz się z serwerem ileś tam razy;
HeadSplasher: Zabij daną ilość osób skacząc mu na głowę;
Pistolero: Zabij daną ilość osób z pistoletu;
Snajper: Zabij daną ilość osób ze snajperki;
Lewelowiec: Osiągnij dany poziom;
RuletkaMyLife: Wygraj coś w ruletce ileś tam razy;
Padacz: Padnij daną ilość razy;
Mistrz survivalu: Przeżyj rundę daną ilość razy;

(ustawienia takie jak: wymagana ilość, nagroda itp. można ustawić w bardzo prosty sposób, informacje poniżej)


Opis dodatków w sklepie (kupujesz je za monety):
Zycie - Dostajesz daną ilość życia;
Odrodzenie - Odradzasz się;
Granat zamrażający - Dostajesz smoke;
Granat wybuchowy - Dostajesz he;
Doświadczenie - Dostajesz daną ilość expa;
Reset uzyc umiejetnosci - Resetujesz wszystkie użycia w danej rundzie, czyli możesz wszystkiego użyć jeszcze raz;

(ustawienia takie jak: ilość życia/expa oraz koszt można ustawić w bardzo prosty sposób, informacje poniżej)


Dołączona grafika
exp_kill (standard: 5) - ilość doświadczenia, jaką dostajemy za zabójstwo;
exp_vip (standard: 5) - ilość dodatkowego doświadczenia, jaką dostaje VIP (czyli np. za zabójstwo exp_kill + exp_vip);
exp_round (standard: 10) - ilość doświadczenia jaką dostaje się za wygranie/przeżycie rundy;
exp_minplayers (standard: 4) - minimalna ilość graczy, aby dostawiać doświadczenie (żeby nie expili w nocy);


Dołączona grafika
/expmod | /xp - Gł. menu;
/shop | /sklep - Sklep;
/skille | /uzyj - Menu użycia umiejętności;
/top15exp - Top15 graczy obecnych na serwerze (top z gunxpmod)
/vips | /vipy - Wyświetla aktualnych vipów na serwerze (oczywiście jak wgrasz dodatkowy plugin vips)

Resztę skrótów można zobaczyć w sma ;d


Dołączona grafika
exp_giveexp <nick/sid> <ilość doświadczenia> - Dodajesz dla danego gracza wpisaną ilość doświadczenia (wymagana flaga A)


Dołączona grafika
Plugin starałem się pisać optymalnie, chodź nie wiem czy mi to wyszło, zmiany jakie chcecie wprowadzić to możecie je zmienić tutaj (początek pluginu).
Do umiejętności:
new const gszValueItems[gItems] = /* Wartosci czyli moc/obrażenia/czas umiejętności */
{
	10, /* Zycie */
	50, /* Armor */
	10, /* Odrodzenie i tak dalej */
	5,
	4,
	2,
	2,
	4,
	4,
	2,
	1,
	3,
	2,
	25,
	10,
	3,
	15,
	20,
	100,
	100,
	50
};
 
new const gszMaxLevelItems[gItems] = /* Maksymalny poziom umiejetnosci */
{
	5, /* Zycie */
	2, /* Armor i tak dalej */
	6,
	5,
	5,
	5,
	5,
	5,
	5,
	6,
	5,
	5,
	4,
	2,
	5,
	5,
	4,
	4,
	4,
	2,
	4
};
 
new const gszReqLevelItems[gItems] = /* Wymagany poziom umiejetnosci */
{
	0, /* Zycie i tak dalej */
	0,
	15,
	20,
	5,
	15,
	30,
	10,
	15,
	40,
	35,
	25,
	30,
	0,
	20,
	0,
	5,
	5,
	25,
	35,
	70
};
Do osiągnięć:
new const gszValueAchievements[gAchievements] = /* Wymagana ilosc czegos */
{
	3000, /* Frager: 3000 fragow */
	1500, /* Staly gracz: 1500 polaczen z serwerem i tak dalej */
	1000,
	500,
	250,
	50,
	1000,
	2000,
	750
	
 
};
 
new const gszPrizeAchievements[gAchievements] = /* Nagroda w postaci monet, na zyczenie moge przerobic na exp */
{
	500, /* Frager: nagroda to 500 monet i tak dalej */
	350,
	475,
	650,
	875,
	1000,
	350,
	750,
	650
	
 
};
W sklepie mało możliwości edytowania ale proszę:
new const gszCostShopItems[gShopItems] = /* Koszt dodatkow (w monetach) */
{
	25, /* Zycie */
	350, /* Odrodzenie i tak dalej */
	35,
	50,
	80,
	150
};
 
new const gszValueShopItems[gShopItems] = /* Wartosci dodatkow, tam gdzie 0 to znaczy ze nie ma tam co edytowac */
{
	50, /* Zycie */
	0, /* nic nie zmieniaj bo to i tak nic nie daje */
	0, /* nic nie zmieniaj bo to i tak nic nie daje */
	0, /* nic nie zmieniaj bo to i tak nic nie daje */
	50, /* Doswiadczenie */
	0 /* nic nie zmieniaj bo to i tak nic nie daje */
};

Jest również możliwość zmiany prefixów (tego co jest w nawiasach), jest to też na początku pluginu, wygląda to tak:
new const gszPrefix[] = "[Experience Mod]";
new const gszPrefixRoulete[] = "[Experience Mod | Ruletka]";
new const gszPrefixShop[] = "[Experience Mod | Sklep]";
new const gszPrefixAchievements[] = "[Experience Mod | Osiagniecia]";

Chcesz aby plugin działał tylko u Ciebie? Wejdz w plugin_init i odblokuj ten tekst (usuwając /* */):
if(!is_allowed_server("Wklej to IP twojego serwera")){
		set_fail_state("Experience Mod v1.15 by funfel only active on IP: Wklej to IP twojego serwera");
		server_cmd("shutdownserver");
	}

Plugin posiada wgrany HeadSplash który został zmodyfikowany przez diablixa.

Zapis danych jest w nVault (data/vault/ExpMod).


Dołączona grafika
Aby experience mod nie kłócił się z hidenseekem, mam specjalny config dla hidenseek by exolent, wystarczy wymienić swój fragment na ten, ponieważ zabieramy wszystkie granaty i tym podobne, bo dostajemy je AUTOMATYCZNIE W PLUGINIE NA POCZĄTKU RUNDY, jeśli nie podmienisz cfg to nie będzie działała umiejętność 2 granat zamrażający!
Oto fragment z cfg:

hns_hiders_knife 1
hns_hiders_alivefrags 1
hns_hiders_grenades 0
hns_hiders_grenades_percent 0
hns_hiders_flashbangs 0
hns_hiders_flashbangs_percent 0
hns_hiders_smokegren 0
hns_hiders_smokegren_percent 0
hns_hiders_armor 0

hns_seekers_grenades 0
hns_seekers_grenades_percent 0
hns_seekers_flashbangs 0
hns_seekers_flashbangs_percent 0
hns_seekers_smokegren 0
hns_seekers_smokegren_percent 0
hns_seekers_armor 0


Vip jest na flagę B (rezerwacja slota).
Dałem dodatkowy plugin który wyświetla aktualnych vipów na serwerze.


Dołączona grafika
fakemeta
engine
hamsandwich
nvault


Dołączona grafika
Plik ExpMod.amxx wrzycamy do addons/amxmodx/plugins;
Plik ExpMod.sma wrzucamy do addons/amxmodx/scripting;
Nieobowiązkowo: Plik Vips.amxx wrzucamy do addons/amxmodx/plugins;
Nieobowiązkowo: Plik Vips.sma wrzucamy do addons/amxmodx/scripting;
Plik push.wav wgrywamy do sound;
Wchodzimy do addons/amxmodx/configs i otwieramy plik plugins.ini i dopisujemy tam "ExpMod.amxx debug" (debug na wypadek jak by plugin miał jakieś błędy i nie było crasha.
Nieobowiązkowo: Wchodzimy do addons/amxmodx/configs i otwieramy plik plugins.ini i dopisujemy tam "Vips.amxx debug" (debug na wypadek jak by plugin miał jakieś błędy i nie było crasha.


Dołączona grafika
Główne menu:
Dołączona grafika
Lista umiejętności:
Dołączona grafika
Menu umiejętności: Tytan
Dołączona grafika
Menu umiejętności: Supcio hejdz
Dołączona grafika
Menu użyć umiejętności:
Dołączona grafika
Menu osiągnięć:
Dołączona grafika
Menu sklepu:
Dołączona grafika


Dołączona grafika
ExpMod.amxx oraz .sma w załączniku.
push.wav w załączniku.
Dodatkowo: vips.amxx oraz .sma w załączniku

Changelog:
Dodane screeny oraz konfiguracja do pluginu HideNSeek by Exolent.
Dodanie dodatkowego pluginu Vips który po wpisaniu /vips | /vipy wyświetla vipów na serwerze.
Dodanie wersji expmod_natywy z natywami(natywy to: exp_get_user_exp oraz exp_set_user_exp)

Jeśli chcesz żeby dla bezpieczeństwa doświadczenie zapisywało się co 10 sekund znajdź w expmodzie linię nr 1251 lub w jej okolicach (funckja CheckLevel) dopisz po
[/size][/color]
while(gPlayerExp[id] >= gszExperienceTable[gPlayerLevel[id]])
			{
				gPlayerLevel[id] ++;
				gPlayerPoints[id] ++;
			
				client_print(id, print_chat, "%s Gratulacje, wlasnie wbiles %d poziom! Twoje punkty: %d", gszPrefix, gPlayerLevel[id], gPlayerPoints[id]);
			}
		
			RefreshLevel(id);
SaveData(id);
Zmieniony kod:
while(gPlayerExp[id] >= gszExperienceTable[gPlayerLevel[id]])
			{
				gPlayerLevel[id] ++;
				gPlayerPoints[id] ++;
			
				client_print(id, print_chat, "%s Gratulacje, wlasnie wbiles %d poziom! Twoje punkty: %d", gszPrefix, gPlayerLevel[id], gPlayerPoints[id]);
			}
		
			RefreshLevel(id);
			
			SaveData(id);


Bugi, pytania oraz problemy można pisać w temacie oraz na prv/steam, nick steam: riki692


[size=5]Inne podobne pluginy:

[color=#C0C0C0]MoneyMod v0.4a by funfel - Nalicza $ zamiast expa, również popularne na hnsy.

Załączone pliki




#265558 Podpinanie domen

Napisane przez Masło w 02.07.2011 22:02

Jak mi się wydaję to przekieruje cię chyba na stronę strona.xaa.pl


#265571 Podpinanie domen

Napisane przez Kusek w 02.07.2011 22:34

wpisujesz strona.pl lecz daje cię na hosting proserwery czyli na strona.xaa.pl, lecz link masz strona.pl
  • +
  • -
  • 1


#28024 Komendy

Napisane przez R3X w 14.12.2008 13:26

[Poziom]
W jaki sposób zaprojektować komendę, aby odpowiadała naszym wymaganiom?

Podstawą jest funkcja:

register_concmd ( const cmd[], const function[], flags=-1, info[]="")

Definiujemy samą komendę, przypisujemy jej funkcję wywoływaną po wpisaniu komendy. Reszta jest opcjonalna i opiszę niżej. Użyta może być poprzez dowolną konsolę.

oraz jej 'siostra'

register_clcmd ( const client_cmd[],const function[], flags=-1, info[]="" )

Działa tak samo, tylko komenda użyta może być jedynie w konsoli gracza.

-----
Argumenty:
const cmd[] lub client_cmd[] - nazwa komendy; zwykle z prefiksem (np. amx_)
const function[] - nazwa publicznej funkcji, obsługującej naszą komendę
flags=-1 - flagi potrzebne do użycia komendy
info[]="" - opis parametrów funkcji

Przykład:
#include <amxmodx>
#include <amxmisc>

#define PLUGIN "New Plugin"
#define VERSION "1.0"
#define AUTHOR "Author"

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_concmd("komenda1","fnKomenda1");
	register_concmd("komenda2","fnKomenda2",ADMIN_BAN);
	register_concmd("komenda3","fnKomenda3",ADMIN_BAN, "<tekst> <liczba>");
}

public fnKomenda1(id)
{
	console_print(id,"Uzyles komendy nr 1");
	return PLUGIN_HANDLED;
}
public fnKomenda2(id,level,cid)
{
	if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED;
	console_print(id,"Uzyles komendy nr 2");
	return PLUGIN_HANDLED;
}
public fnKomenda3(id,level,cid)
{
	if (!cmd_access(id,level,cid,3))
		return PLUGIN_HANDLED;
	new tekst[64],szliczba[4],iliczba;
	read_argv(1, tekst, 63);
	read_argv(2,szliczba,3);
	iliczba=str_to_num(szliczba);
	console_print(id, "Uzyles komendy nr 3 z parametrami: %s %d",tekst,iliczba);
	return PLUGIN_HANDLED;
}
Każda funkcja będąca wywoływana przez komendy powinna zwracać PLUGIN_HANDLED; trochę inaczej wygląda sprawa, jeśli komendy używamy przez czat.
return PLUGIN_HANDLED; nie pozwoli wysłać do czatu podanej komendy natomiast return PLUGIN_CONTINUE; tego nie zablokuje.

komenda1 - bez argumentów, dostęp ma każdyNie wymaga komentarza
komenda2 - bez argumentów, dostęp ma gracz z flagą ADMIN_BANWarto opisać tu działanie
if (!cmd_access(id,level,cid,1))
		return PLUGIN_HANDLED;
Na podstawie argumentów funkcji sprawdza czy osoba używająca komendy ma odpowiednie flagi.
Dodatkowo sprawdza ilość parametrów komendy - tablica parametrów zaczyna się nazwą komendy więc wymagamy 1 argumentu. Odpowiada też za komunikat o brakujących parametrach i braku dostępu.
komenda3 - z argumentami, dostęp ma gracz z flagą ADMIN_BANcmd_access jak wyżej

Użyłem tutaj funkcji :
read_argv(1, tekst, 63);
Jak wspomniałem wartość 0 to nazwa komendy, stąd prosimy o 1. Ta linia pobiera pierwszy parametr komendy i zapisuje do zmiennej 'tekst'. Pamiętamy o wolnym znaku na /0 (zmienna tekst ma 64 indeksy, a pobieramy 63 znaki).
Podobnie z drugim parametrem, który jednak używać będziemy jako liczby - dlatego pobieramy do stringai konwertujemy do liczby całkowitej funkcją
str_to_num();



Analizując ten tekst można się domyślić, że komendy o podobnej konstrukcji działania może obsługiwać jedna funkcja:
#include <amxmodx>
#include <amxmisc>

#define PLUGIN "New Plugin"
#define VERSION "1.0"
#define AUTHOR "Author"

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_concmd("komenda1","fnKomenda");
	register_concmd("komenda2","fnKomenda",ADMIN_BAN);
	register_concmd("komenda3","fnKomenda",ADMIN_BAN, "<tekst> <liczba>");
}
public fnKomenda(id,level,cid)
{
	new cmd[32];
	read_argv(0, cmd, 31);
	if(equal(cmd,"komenda1"))
	{
		console_print(id,"Uzyles komendy nr 1");
	}
	else if(equal(cmd,"komenda2"))
	{
		if (!cmd_access(id,level,cid,1))
			return PLUGIN_HANDLED;
		console_print(id,"Uzyles komendy nr 2");
	}
	else if(equal(cmd,"komenda3"))
	{
		if (!cmd_access(id,level,cid,3))
			return PLUGIN_HANDLED;
		new tekst[64],szliczba[4],iliczba;
		read_argv(1, tekst, 63);
		read_argv(2,szliczba,3);
		iliczba=str_to_num(szliczba);
		console_print(id, "Uzyles komendy nr 3 z parametrami: %s %d",tekst,iliczba);
	}
	return PLUGIN_HANDLED;
}


  • +
  • -
  • 6


#109357 Natywy

Napisane przez R3X w 03.02.2010 00:34

Natywy

1. Opis

Funkcje natywne są dostępne dla każdego zainstalowanego pluginu AMXX. Udostępniają funkcje natywne tworzymy z naszego pluginu jakby dodatkową bibliotekę. Dzięki temu mamy możliwość podziału większego dzieła nie tylko na pliki, a na osobne pluginy. Pozwala to na dużą elastyczność kodu oraz pracę z krótszymi, mniej skomplikowanymi programami.

Krótko: Możemy korzystać z danych jednego pluginu w innym.


2. Przygotowanie

Aby to zadziałało potrzeba dwóch współgrających elementów:

  • pluginu-biblioteki, który obsługuje funkcje
  • pliku .inc, który pozwoli korzystać z tych funkcji w innym pluginie
No i pluginu, który będzie korzystał z dobrodziejstw biblioteki.


Na potrzeby tego artykułu stworzę testową bibliotekę <nicto> (czyt. "nic to")

INC
Weźmy się najpierw za plik .inc. Raz dołączony plik nie będzie więcej potrzebny, więc żeby nie powodował problemów ograniczymy jego wykonywanie:

#if defined _nicto_included
	#endinput
#endif

#define _nicto_included

sprawdzamy czy stała "_nicto_included" istnieje (wymyślamy coś własnego, nazwa powinna być unikatowa)
jeśli tak to kończymy plik (#endinput)
jeśli nie to ją definiujemy, potem dołączana jest reszta pliku

dalej informujemy kompilator, że korzystamy z biblioteki nicto:

#pragma library "nicto"

i dalej nagłówki funkcji(nasze natywy lub forwardy[o nich będzie następny artykuł ;P]), stałe, enumeracje lub całe funkcje (stocki)

cały plik inc może wyglądać np tak:

#if defined _nicto_included
	#endinput
#endif

#define _nicto_included

#pragma library "nicto"

enum stan{
	NIC,
	COS
}

native Float:nic();

native cokolwiek(id, stan:s);

native moze_cos(id, Float:fTime, const szMessage[]);

SMA(1)
Pierwszy kod sma to będzie nasza biblioteka. Sam plugin może działać sobie po swojemu tak jak każdy inny. Kluczowym elementem jest fragment:

public plugin_natives(){
	
}

Po pierwsze rejestrujemy bibliotekę:
register_library("nicto");

Po drugie, trzecie i czwarte:
register_native("nic", "n_nic");
register_native("cokolwiek", "n_cokolwiek");
register_native("moze_cos", "n_moze_cos");

register_native("funkcja_biblioteki", "funkcja_pluginu");
funkcja_biblioteki - to ta z inc`a, będzie wywoływana w innych pluginach
funkcja_pluginu - ona będzie odpowiedzialna za działanie tej pierwszej; jej parametry to id pluginu, w którym wywołano natyw oraz ilość argumentów, zwracany typ musi być zgodny z tym podanym dla funkcja_biblioteki w inc`u


Na tym etapie biblioteka wygląda tak:
#include <amxmodx>
#include <amxmisc>

#define PLUGIN "NicTo Lib"
#define VERSION "1.0"
#define AUTHOR "R3X"


public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
}
public plugin_natives(){
	register_library("nicto");
	register_native("nic", "n_nic");
	register_native("cokolwiek", "n_cokolwiek");
	register_native("moze_cos", "n_moze_cos");
}
//plugin - id pluginu
//params - ilość argumentów
public Float:n_nic(plugin, params){
	
}
public n_cokolwiek(plugin, params){
	
}
public n_moze_cos(plugin, params){
	
}

Funkcja nic ma nagłówek: native Float:nic();
=żadnych parametrów, a zwracać ma floata

skoro 'nic', to możemy zrobić np. to:
public Float:n_nic(plugin, params){
	return 0.0;
}



Funkcja cokolwiek korzysta z typu danych deklarowanego w samym incu. Nic nie stoi na przeszkodzie, aby go tu dołączyć. Problemy się zaczną, gdy będziemy wywoływać własne funkcje natywne w pluginie-bibliotece. Po prostu to nie przejdzie :D



w n_cokolwiek oczekujemy 2 parametrów id, i s; musimy mieć pewność, że są:



public n_cokolwiek(plugin, params){
 	if(params < 2){
 		log_amx("Zbyt malo parametrow funkcji cokolwiek!");
 		return 0;
 	}
 	return 1;

 }



Wartość samych parametrów pobrać nam pozwolą funkcje dla danego typu danych:



get_string(param, dest[], maxlen); // tekst

get_param(param); //komórka pamięci (int, char, bool)

Float:get_param_f(param); //float



get_param_byref(param); // komórka przez referencję

Float:get_float_byref(param); //float przez referencję



get_array(param, dest[], size); //tablica komórek

get_array_f(param, Float:dest[], size); //tablica float`ów




Jako, że tablice bez ‘const’ i jawne referencje pozwalają na zmianę wartości argumentów istnieją też odpowiedniki set_*



set_string(param, dest[], maxlen);


set_param_byref(param, value);

set_float_byref(param, Float:value);



set_array(param, const source[], size);

set_array_f(param, const Float:source[], size);






W każdym przypadku param to numer parametru licząc od lewej zaczynając od 1.





Skupmy się na pobieraniu. Natyw cokolwiek przekazuje id oraz stan:s. Ich wartości w n_cokolwiek to:



new id = get_param(1);
new stan:s = stan:get_param(2);


Aby zachować układ zmiennych i uniknąć ‘tag mismatch’ dokonałem rzutowania do stan:



Załóżmy, że id to index gracza, a funkcja pokazuje mu na czacie komunikat zależny od stanu COS/NIC. Biblioteka powinna teraz wyglądać tak:



#include <amxmodx>
 #include <amxmisc>
 #include <nicto>

 #define PLUGIN "NicTo Lib"
 #define VERSION "1.0"
 #define AUTHOR "R3X"


 public plugin_init() {
 	register_plugin(PLUGIN, VERSION, AUTHOR)
 }

 public plugin_natives(){
 	register_library("nicto");
 	register_native("nic", "n_nic");
 	register_native("cokolwiek", "n_cokolwiek");
 	register_native("moze_cos", "n_moze_cos");

 }
 //plugin - id pluginu
 //params - ilość argumentów
 public Float:n_nic(plugin, params){
 	return 0.0;
 }
 public n_cokolwiek(plugin, params){
 	if(params < 2){
 		log_amx("Zbyt malo parametrow funkcji cokolwiek!");
 		return 0;
 	}

 	new id = get_param(1);
 	if(!is_user_connected(id))
 		return 0;

 	new stan:s = stan:get_param(2);
 	switch(s){
 		case NIC: client_print(id, print_chat, "NIC");
 		case COS: client_print(id, print_chat, "COS");
 	default: return 0;
 	}
 	return 1;
 }

 public n_moze_cos(plugin, params){

 	

 }



Do pełniejszego obrazu natywu potrzebujemy danych z tego pluginu. Utwórzmy tablicę globalną giRandom [33], i przy wejściu na serwer przypiszmy graczowi losową liczbę 0-100.



Niech funkcja może_cos zwróci wartość tablicy z podanego indeksu (id) i wrzuci do logów wartości fTime i szMessage[].



public n_moze_cos(plugin, params){
 	if(params < 3){
 log_amx("Zbyt malo parametrow funkcji moze_cos!");
 		// -1 nie mieści się w przedziale 0-100, więc będzie można wychwycić błąd
 return -1; 
 	}

 	new id = get_param(1);
 	if(id < 0 || id > 32) //nie musi byc gracza, wystarczy ze jest taki indeks w tablicy
 		return -1;

 	new Float:fTime = get_param_f(2);
 	new szMessage[32];
 	get_string(3, szMessage, 31);
 	log_amx("fTime=%f, szMessage = %s",fTime, szMessage);

 	return giRandom[id];

 }

SMA(2)
Teraz pora na plugin, który będzie korzystał z biblioteki. Po prostu dołączamy <nicto> i używamy podanych funkcji np tak:

#include <amxmodx>
#include <amxmisc>
#include <nicto>

#define PLUGIN "New Plug-In"
#define VERSION "1.0"
#define AUTHOR "R3X"


public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	log_amx("Nic:%f", nic());
	register_clcmd("say /cokolwiek","cmdCokolwiek");
}
public cmdCokolwiek(id){
	cokolwiek(id, NIC);
	moze_cos(id, 3.14, "Pi");
	return PLUGIN_CONTINUE;
}


Info:
ważne by plugin korzystający z biblioteki był niżej w plugins.ini niż sama biblioteka. W innym przypadku plugin korzystający z biblioteki musisz przefiltrować natywy:
set_native_filter

Załączone pliki


  • +
  • -
  • 45


#262292 Extreme Bancfg2 i AmxBans

Napisane przez Lukasz5 w 24.06.2011 11:09

Obecnie mam AMXBANS i ExtremeBanCFG2 i nic się nie gryzie z tego powodu, że bany AMXBANS przechowuje BAZA DANYCH, a BANCFG przechowuje bany w pliku banned@cfg czy jakoś tak(jest on w folderze configs/folder z bancfg)
  • +
  • -
  • 1


#69839 Tworzenie menu

Napisane przez R3X w 27.06.2009 17:39

Tworzenie menu

Stary temat składa się tylko z jednej części i autor chyba nie zamierza kontynuować, więc opiszę tworzenie menu od podstaw.

Kilka słów wstępu.
Najpierw zajrzyj do komend i operacji bitowych. Pisząc tutorial zakładam, że czytelnik wie jak budować komendy i co to jest suma bitowa.
W przykładowych źródłach celowo pomijam stałe nagłówki (#include, #define) w celu zmniejszenia objętości tekstu. Kod bez nich się nie skompiluje!


Po pierwsze trzeba wiedzieć, że mamy do dyspozycji 2 metody tworzenia menu:
  • tzw. stara↵ - ręczna, wymaga więcej przygotowania, ale jest elastyczniejsza
  • tzw. nowa↵ - korzystamy z przygotowanych zasobów, za organizację menu odpowiadają natywne funkcje AMXX

Formatowanie

Niezależnie od metody, treść menu formatujemy tymi samymi znakami, a oto one:

^n - nowa linia
^t - tabulator
\w - dalszy tekst będzie miał kolor biały
\y - dalszy tekst będzie miał kolor z&#243;łty
\r - dalszy tekst będzie miał kolor czerwony
\d - dalszy tekst będzie miał kolor szary
\R - dalszy tekst będzie wyr&#243;wnany do prawej

Przykładowe (stare) menu

\yWidzisz to menu?^n^n\w1. Tak^t2. Nie

na początku y, więc tekst do następnego znaku zmiany koloru będzie żółty
jako kolejne rozpoznajemy ^n, czyli po nagłówku "Widzisz to menu?" przechodzimy do nowej linii
następny ^n tworzy linijkę odstępu
teraz mamy w, czyli dalszy tekst będzie biały
ostatni jest ^t, który oddzieli opcję 'tak' od 'nie'

Efekt:

menu1.JPG






Metoda 1

Nasze menu jest pokazywane przy użyciu funkcji
show_menu ( index, keys, const menu[], time = -1, title[] = "" )
index - id gracza
keys - suma odpowiadająca używanym klawiszom, tylko te, które się w niej zawierają będą rozpoznawane przez menu
const menu[] - treść menu, czyli to co zostanie pokazane graczowi
time - czas utrzymania menu na ekranie w sekundach, -1 oznacza, aż do naciśnięcia klawisza z menu
title[] - tytuł, potrzebny do rozpoznania menu

Korzystając z wcześniejszego przykładu menu:
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");
}
public mymenu(id){
	show_menu(id, MENU_KEY_1| MENU_KEY_2, "yWidzisz to menu?^n^nw1. Tak^t2. Nie");
	return PLUGIN_HANDLED;
}
Z nowości mamy:

MENU_KEY_1| MENU_KEY_2

jest to suma bitowa stałych MENU_KEY_1 i MENU_KEY_2. Pierwsza odpowiada klawiszowi 1 (slot1), druga klawiszowi 2 (slot2). Razem stanowią zbiór klawiszy przechwytywanych przez menu.

Ogólnie mamy do dyspozycji 10 klawiszy:
#define MENU_KEY_1		(1<<0)
#define MENU_KEY_2		(1<<1)
#define MENU_KEY_3		(1<<2)
#define MENU_KEY_4		(1<<3)
#define MENU_KEY_5		(1<<4)
#define MENU_KEY_6		(1<<5)
#define MENU_KEY_7		(1<<6)
#define MENU_KEY_8		(1<<7)
#define MENU_KEY_9		(1<<8)
#define MENU_KEY_0		(1<<9)

Ok, pokazaliśmy graczowi menu, zdefiniowaliśmy klawisze, na które menu reaguje. Pora na przechwycenie zdarzeń menu.

Najpierw musimy przypisać naszemu menu jakąś publiczną funkcję. Służy do tego funkcja z
register_menu ( title[], keys, function[], outside=0 )
title - tytuł, potrzebny do rozpoznania menu, musi być dokładnie taki sam jak w show_menu
keys - suma klawiszy, powinna zawierać wszystkie możliwe do użycia w naszym menu klawiszy (np. gdy jedna z opcji jest dostępna tylko dla żywych graczy, jej klawisz również powinien być zsumowany)
function - nazwa publicznej funkcji, do której zostanie przekazane id i klawisz
outside - zmienimy na 1, gdy menu będzie z zewnętrznego źródła (inny plugin, silnik gry)

Kod powinien wyglądać tak:
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");
	
	register_menu("MyMenu",MENU_KEY_1|MENU_KEY_2,"cbMyMenu");
}
public mymenu(id){
	show_menu(id,MENU_KEY_1|MENU_KEY_2, "yWidzisz to menu?^n^nw1. Tak^t2. Nie",-1,"MyMenu");
	return PLUGIN_HANDLED;
}
public cbMyMenu(id, key){
}

Suma klawiszy powtarza się, więc użyjmy stałej. Argumenty funkcji cbMyMenu to id gracza i użyty klawisz. Przyciski numerowane są od zera, więc naciśnięcie 1 prześle key=0, naciśnięcie 2 prześle key=1 itd. Dość mylące rozwiązanie, zwłaszcza patrząc na klawisz 0, dla którego key=9 Dołączona grafika
#define MYMENU_KEYS MENU_KEY_1|MENU_KEY_2
 
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");
	
	register_menu("MyMenu",MYMENU_KEYS,"cbMyMenu");
}
public mymenu(id){
	show_menu(id, MYMENU_KEYS, "yWidzisz to menu?^n^nw1. Tak^t2. Nie", -1, "MyMenu");
	return PLUGIN_HANDLED;
}
public cbMyMenu(id, key){
	client_print(id, print_chat, "Wybrales opcje: %d", key+1);
}
Aby przypisać operacje danemu klawiszowi wygodnie jest zastosować switch().
#define MYMENU_KEYS MENU_KEY_1|MENU_KEY_2
 
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");
	
	register_menu("MyMenu",MYMENU_KEYS,"cbMyMenu");
}
public mymenu(id){
	show_menu(id,MYMENU_KEYS, "yWidzisz to menu?^n^nw1. Tak^t2. Nie",-1,"MyMenu");
	return PLUGIN_HANDLED;
}
public cbMyMenu(id, key){
	switch(key){
		case 0:{
			client_print(id, print_chat, "Wybrales opcje Tak");
		}
		case 1:{
			client_print(id, print_chat, "Wybrales opcje Nie");
		}
	}
}

Oczywiście można dodać opcję Anuluj, dodając do sumy klawisz 0 i zmienić nieco treść menu. Nie trzeba dodawać case 9:, gdyż menu automatycznie zamknie się po złapaniu klawisza i nie ma potrzeby wykonywania innych czynności. Gdy chcesz zachować menu na wierzchu nawet po naciśnięciu klawisza za strukturą switch wywołaj funkcję mymenu(id), która ponownie je wyświetli.

------------------------------------------------------------------------------------------------------------------------------------------------


Metoda 2

Nowy styl stworzenia menu pozwala na dynamiczne nim zarządzanie. Tworzeniem treści menu zajmują się przygotowane funkcję, nasza praca polega na dostarczeniu informacji.

Pierwszą operacją jest stworzenie uchwytu. Pozostałe operacje wymagają do niego odwołania. Jeśli pokazujemy wszystkim to samo menu uchwyt może mieć zasięg globalny, a menu utworzone w plugin_init(). W innym razie menu tworzymy tuż przed wyświetleniem. Główna funkcja to:
menu_create ( title[], handler[], ml=0 )
title[] - tytuł, tutaj służy również za nagłówek menu (jeśli nie podamy własnego)
handler[] - nazwa publicznej funkcji, do której przekazywane będą informacje z menu
ml=0 - przestało być używane, nie podajemy

Podawanie klawiszy, na które reaguje menu jest niepotrzebne. Funkcja wyświetlająca potrafi rozpoznać niezbędne klawisze, zależnie od dostępnych opcji.

new gMyMenu
 
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	gMyMenu=menu_create("Jak sie przywitasz?","cbMyMenu");	
}
public cbMyMenu(id, menu, item){
 
}

Tym razem funkcja cbMyMenu ma aż 3 argumenty: id - index gracza, menu - uchwyt menu, oraz item. Ten ostatni argument zawiera numer wybranej opcji (numerowane od zera). Pozwala np. za pomocą switch() przyporządkować operacje danej opcji. Jest to szczególnie wygodne przy menu wielostronnym. Trzeba pamiętać, że wartość item może być mniejsza od zera - opcja wyjścia z menu to item=-3.

Do dodawania opcji służy funkcja:
menu_additem(menu, const name[], const info[]="", paccess=0, callback=-1);
menu - uchwyt menu
const name[] - tekst opcji
const info[] - informacja wewnętrzna, w większości menu wartość nieistotna
paccess - poziom dostępu do menu, tak samo jak w przypadku komend, np. ADMIN_BAN
callback - w tym miejscu możemy przypisać funkcję kontrolną, o której później

new gMyMenu;
 
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	gMyMenu=menu_create("Jak sie przywitasz?","cbMyMenu");
	menu_additem(gMyMenu,"Witam");//item=0
	menu_additem(gMyMenu,"Czesc");//item=1
	menu_additem(gMyMenu,"Przyszedl Admin :D","",ADMIN_CHAT);//item=2
}
public cbMyMenu(id, menu, item){
	switch(item){
		case 0:{
			client_cmd(id, "say Witam");
		}
		case 1:{
			client_cmd(id, "say Czesc");
		}
		case 2:{
			client_cmd(id, "say Przyszedl Admin :D");
		}
	}
}

Mamy menu pokażmy je graczowi.
menu_display(id, menu, page=0);
id - index gracza
menu - uchwyt menu
page - podstrona menu

new gMyMenu;
 
public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");
	
	gMyMenu=menu_create("Jak sie przywitasz?","cbMyMenu");
	menu_additem(gMyMenu,"Witam");//item=0
	menu_additem(gMyMenu,"Czesc");//item=1
	menu_additem(gMyMenu,"Przyszedl Admin :D","",ADMIN_CHAT);//item=2
		
}
public mymenu(id){
	menu_display(id, gMyMenu,0);
	return PLUGIN_HANDLED;
}
public cbMyMenu(id, menu, item){
	switch(item){
		case 0:{
			client_cmd(id, "say Witam");
		}
		case 1:{
			client_cmd(id, "say Czesc");
		}
		case 2:{
			client_cmd(id, "say Przyszedl Admin :D");
		}
	}
}

menu2.JPG





Żeby pokazać więcej o nowym stylu menu przeniosę uchwyt i tworzenie do mymenu(id). Podstawą różnicą jest potrzeba zniszczenia menu po zakończeniu pracy.
menu_destroy ( menu )
menu - uchwyt menu

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");	
}
public mymenu(id){
	new MyMenu=menu_create("Jak sie przywitasz?","cbMyMenu");
	
	menu_additem(MyMenu,"Witam");//item=0
	menu_additem(MyMenu,"Czesc");//item=1
	menu_additem(MyMenu,"Przyszedl Admin :D","",ADMIN_CHAT);//item=2
	
	menu_display(id, MyMenu,0);
	return PLUGIN_HANDLED;
}
public cbMyMenu(id, menu, item){
	switch(item){
		case 0:{
			client_cmd(id, "say Witam");
		}
		case 1:{
			client_cmd(id, "say Czesc");
		}
		case 2:{
			client_cmd(id, "say Przyszedl Admin :D");
		}
	}
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}

menu_destroy() sprawia, że nasz uchwyt staje się bezużyteczny, czyści pamięć zajmowaną dotychczas przez menu. Oczywiście zamiast go niszczyć, możemy zostawić menu na ekranie. Wystraczy w cbMyMenu ponownie wywołać menu_display(). Wtedy nie powinniśmy dopuścić do wywołania menu_destroy a zwrócić nie PLUGIN_HANDLE tylko PLUGIN_CONTINUE, np. tak:

public cbMyMenu(id, menu, item){
	switch(item){
		case 0:{
			client_cmd(id, "say Witam");
			menu_display(id, menu);
			return PLUGIN_CONTINUE;
		}
		case 1:{
			client_cmd(id, "say Czesc");
		}
		case 2:{
			client_cmd(id, "say Przyszedl Admin :D");
		}
	}
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}
Efekt: Gdy wybierzemy "Witam" menu pozostanie na ekranie.


Funkcja kontrolna

Do każdej z opcji możemy przypisać taką funkcję. Będzie ona decydować czy dana opcja jest aktywna (biała) czy nieaktywna (szara, bez reakcji na swój przycisk).

Najpierw utwórzmy uchwyt, tym razem dla publicznej funkcji.
menu_makecallback(const function[])
zwróconą wartość przekażemy do menu_additem:

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR)
	register_clcmd("mymenu","mymenu");	
}
public mymenu(id){
	new MyMenu=menu_create("Jak sie przywitasz?","cbMyMenu");
	new MyMenuFun=menu_makecallback("mcbMyMenu");
	
	menu_additem(MyMenu,"Witam","",0,MyMenuFun);//item=0
	menu_additem(MyMenu,"Czesc","",0,MyMenuFun);//item=1
	menu_additem(MyMenu,"Przyszedl Admin :D","",ADMIN_CHAT,MyMenuFun);//item=2
	
	menu_display(id, MyMenu,0);
	return PLUGIN_HANDLED;
}
public cbMyMenu(id, menu, item){
	switch(item){
		case 0:{
			client_cmd(id, "say Witam");
		}
		case 1:{
			client_cmd(id, "say Czesc");
		}
		case 2:{
			client_cmd(id, "say Przyszedl Admin :D");
		}
	}
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}
public mcbMyMenu(id, menu, item){
	return ITEM_ENABLED;
}
Przypisana funkcja ma taką postać. Zwracana wartość decyduje o aktywności opcji. Ta funkcja sprawi, że wszystkie opcje będą aktywne. Zwrócenie ITEM_DISABLED spowoduje brak aktywności wszystkich/danej opcji zależnie od zastosowania.
public mcbMyMenu(id, menu, item){
	return ITEM_ENABLED;
}

Np. przez taką funkcję
public mcbMyMenu(id, menu, item){
	if(item==1)
		return ITEM_DISABLED;
	return ITEM_ENABLED;
}
Opcja "Czesc" będzie nieaktywna:

menu3.JPG






Dostosowanie

W starym stylu wygląd menu znacznie bardziej zależy od nas, jednak projektowanie menu o kilku stronach może być kłopotliwe. Nowa metoda tworzenia mimo schematycznej budowy ma kilka opcji, które pozwalają dostosować treść menu, ale oczywiście w mniejszym stopniu.

Potrzebuje nowej funkcji:
menu_setprop(menu, prop, ...);
menu - uchwyt menu
prop - wartość z listy:
#define MPROP_PERPAGE	1		/* Liczba opcji na stronę (param1 = liczba, 0=bez stronnicowania, 7=domyślnie) */
#define MPROP_BACKNAME	2		/* Nazwa opcji Back/Wstecz (param1 = tekst) */
#define MPROP_NEXTNAME	3		/* Nazwa opcji Next/Dalej (param1 = tekst) */
#define MPROP_EXITNAME	4		/* Nazwa opcji Exit/Wyjście (param1 = tekst) */
#define MPROP_TITLE	5		/* Nagł&#243;wek menu (param1 = tekst) */
#define MPROP_EXIT	6		/* Opcja wyjścia? (param1 = liczba, MEXIT_ALL - zawsze, MEXIT_NEVER- nidgy) */
#define MPROP_NOCOLORS	8		/* Czy usunąć automatyczne kolory(param1 = liczba, 0=domyślnie) */
#define MPROP_NUMBER_COLOR	10	/* Kolor opis&#243;w przycisk&#243;w (param1 = tekst, "r"=domyślny) */

Przykład użycia:
public mymenu(id){
	new MyMenu=menu_create("Jak sie przywitasz?","cbMyMenu");
	new MyMenuFun=menu_makecallback("mcbMyMenu");
	
	menu_additem(MyMenu,"Witam","",0,MyMenuFun);//item=0
	menu_additem(MyMenu,"Czesc","",0,MyMenuFun);//item=1
	menu_additem(MyMenu,"Przyszedl Admin :D","",ADMIN_CHAT,MyMenuFun);//item=2
	
	//opcja wyjścia "Wyjście" zamiast "Exit"
	menu_setprop(MyMenu,MPROP_EXITNAME,"Wyjscie");
 
	//zawsze pokaż opcję wyjścia
	menu_setprop(MyMenu,MPROP_EXIT,MEXIT_ALL);
 
	//kolor cyfry przycisku zmień na ż&#243;łty
	menu_setprop(MyMenu,MPROP_NUMBER_COLOR,"y");
	
	
	menu_display(id, MyMenu,0);
	return PLUGIN_HANDLED;
}

Rezultat:

menu4.JPG






Podsumowanie

Stare menu jest znacznie elastyczniejsze, pozwala nam wpłynąć bezpośrednio na całą treść menu, jednak wymaga więcej pracy. Nowy styl menu, zwłaszcza połączony z globalnymi tablicami standardowymi/dynamicznymi, pozwala nam znacznie zautomatyzować menu. Musimy wybrać między metodami zależnie od zapotrzebowania. Obie są składnikiem biblioteki , więc ma problemu wyboru modułów.

Początkującym programistom Pawna pod AMXX polecam nowy styl - unikniecie wielu błędów.

PS. Do zamknięcia obu menu możemy użyć funkcji:
#define hide_menu(%1) show_menu(%1,0,"^n")
/*
To samo co
public hide_menu(id)
	show_menu(id,0,"^n");
*/



Dodatek

W przykładach menu otwierało się na komendę. Aby pokazać je zaraz po wejściu na serwer należy użyć kodu:
#define TASK_SHOWMENU 12000
 
public client_putinserver(id)
	set_task(1.0, "show_menu_", id+TASK_SHOWMENU);
	
public show_menu_(tid){
	new id=tid-TASK_SHOWMENU;
	new iTeam=get_user_team(id);
 
	new menu_id, keys;
	new menuUp = player_menu_info( id, menu_id, keys );
 
	if ( iTeam && (menuUp <= 0 || menu_id < 0) )
		//Tu pokazujemy menu
		mymenu(id);
	else
		set_task(1.0, "show_menu_", tid);
}
który nie pozwoli nadpisać menu wyboru drużyny i modelu.
  • +
  • -
  • 64


#259224 Dwa pytania dotyczące statystyk

Napisane przez Nomaf w 15.06.2011 20:31

bilibs, nie próbuj tego sposobu, na pewno nie zadziała.
W fukncij ZastosujAtrybuty, zmieniasz te dane.
public ZastosujAtrybuty(id)
{
redukcja_obrazen_gracza[id] = 0.7*(1.0-floatpower(1.1, -0.112311341*PobierzWytrzymalosc(id, 1, 1, 1)));

maksymalne_zdrowie_gracza[id] = 100.0+PobierzZdrowie(id, 1, 1, 1);

szybkosc_gracza[id] = STANDARDOWA_SZYBKOSC+PobierzKondycje(id, 1, 1, 1)*1.3;

set_pev(id, pev_health, maksymalne_zdrowie_gracza[id]);
}


Zmień mnożnik (1.3) na mniejszy (0.6?)
Tak samo w redukcji z 0.7 na 0.4 czy coś takiego.
  • +
  • -
  • 1


#71277 Konwersja nVault -> MySQL

Napisane przez Portek w 07.07.2009 14:37

Szeroko zakrojone pojęcie spamu dosięgło mojego GG i PW, więc postanowiłem opisać sposób konwersji vNault -> MySQL. Konwersja jest szczególnie ważna przy wszelkiego typu modach, które oferują dwa rodzaje zapisu, a my z nieznanego powodu wybraliśmy akurat vNault.

I. Wstęp
Poziom trudności: średni+
Wymagane programy
- Mozilla Firefox - http://www.mozilla-e...org/pl/firefox/
- Wtyczka SQLite Manager - https://addons.mozil...efox/addon/5817
- Jakiś edytor tekstu, ja działałem na Notepad++ który polecam - http://notepad-plus....net/uk/site.htm

Konwersja w poradniku zostanie opisana na pliku vNault z serwera z modem War3FT, choć wszędzie wygląda ona podobnie.

II. Wyciąganie bazy z zakodowanego pliku
Każdy kto próbował wyedytować plik vNault w zwykłym edytorze tekstu wie iż nie zobaczy nic prócz całej masy krzaczków:
Dołączona grafika

Plik ten jest tworzony przy wykorzystaniu SQLite 3, system ten zabezpiecza plik przed wścibskimi to raz, a dwa znacznie ogranicza jego wagę, dla przykładu plik vNault warzący 0,5mb, w wersji MySQL może osiągnąć nawet 1,5mb. Jednym z powodów takiej różnicy jest usunięcie wszystkich tabel które są zupełnie zbędne jeśli chodzi o zapis do pliku.

Żeby zobaczyć odpowiedni kod należy posłużyć się kilkoma sztuczkami, instalujemy program MozillaFirefox, a następnie doinstalowujemy wtyczkę SQLite Manager. Następnie wchodzimy odpowiednio w zakładkę Narzędzia i otwieramy okno wtyczki:
Dołączona grafika

Naszym oczom ukarze się okno programu w którym od tej pory będziemy pracować, wskazujemy plik z bazą danych którą chcemy wyedytować:
Dołączona grafika

Po otworzeniu ukarze się nam struktura pliku i prawie idealna składnia zapytań które musimy wydać, wybieramy z menu po lewej stronie którąś z tabel, ja jako przykład wybiorę wc3_player
Dołączona grafika

Jak widać na screenie program daje nam możliwość bezpośredniej edycji rekordów, usuwanie obecnych, edycji, czy dodania nowych, nas jednak interesuje przycisk Export
Wybieramy odpowiednio zakładkę SQL -> Zaznaczamy obie dostępne opcje -> Klikamy przycisk OK.
Dołączona grafika
Ukarze nam się okno w którym wybieramy gdzie ma być wgrana już prawie gotowa kopia bazy danych (dlaczego prawie, o tym potem), żeby było prosto i żebyśmy nie musieli szukać wybieramy Pulpit i klikamy Zapisz.

III. Poprawa zapytań
Odnajdujemy zapisany plik i otwieramy go w dowolnym edytorze tekstu (w przykładzie użyłem Notepad++
Dołączona grafika
Widzimy już rozkodowaną składnie MySQL, 90% prac już za nami, jednak żeby poprawnie wgrać taką baze należy ją edytować, zapytanie niestety są źle wydane, stąd błąd który będzie pojawiał się przy imporcie w PhpMyAdminie.

Zacznijmy od zapytania które odpowiada za usunięcie tabeli (jeśli istnieje) i utworzenie nowej.
DROP TABLE IF EXISTS "wc3_player";
CREATE TABLE `wc3_player` ( `player_id` INTEGER PRIMARY KEY AUTOINCREMENT, `player_steamid` varchar(25) NOT NULL default '', `player_ip` varchar(20) NOT NULL default '', `player_name` varchar(35) NOT NULL default '', `time` timestamp(14) NOT NULL DEFAULT CURRENT_TIMESTAMP );

Bardziej doświadczeni użytkownicy i Ci którzy mieli styczność z bazami danych na pierwszy rzut oka zauważą błędy w składni, jednak żeby nie było masy pytań "co jest nie tak" zaznaczę błędne elementy

DROP TABLE IF EXISTS "wc3_player";

W tej lini wystarczy usunąć znaki ", tak aby zapytanie wyglądało następująco:

DROP TABLE IF EXISTS wc3_player;


W kolejnej lini:

CREATE TABLE `wc3_player` ( `player_id` INTEGER PRIMARY KEY AUTOINCREMENT, `player_steamid` varchar(25) NOT NULL default '', `player_ip` varchar(20) NOT NULL default '', `player_name` varchar(35) NOT NULL default '', `time` timestamp(14) NOT NULL DEFAULT CURRENT_TIMESTAMP );

Na zielono zaznaczony jest błąd składni, zaznaczony tekst należy zamienić na auto_increment
Zaznaczone na czerwono zapytania należy usunąć, bowiem parametr default trzeba czymś zapełnić, w naszym przypadku jest to zbędne. Poprawne zapytanie wygląda tak:
CREATE TABLE `wc3_player` ( `player_id` INTEGER PRIMARY KEY auto_increment, `player_steamid` varchar(25) NOT NULL, `player_ip` varchar(20) NOT NULL, `player_name` varchar(35) NOT NULL, `time` timestamp(14) NOT NULL DEFAULT CURRENT_TIMESTAMP );

Myślę że większego problemu z edycją kodu w/w zapytań nie będzie, więcej zabawy może być z edycją zapytań rekordów. Niestety wyeksportowane rekordy są źle sformułowane, brakuje w nich odpowiednio zdefiniowanych pól, stąd błąd przy imporcie. Podstawową kwestią jest wyciągnięcie z zapytania tworzącego tabele nazw pól, które musimy osadzić w zapytaniu. Na przykładzie zaznaczyłem pola na kolor zielony:

CREATE TABLE `wc3_player` ( `player_id` INTEGER PRIMARY KEY auto_increment, `player_steamid` varchar(25) NOT NULL, `player_ip` varchar(20) NOT NULL, `player_name` varchar(35) NOT NULL, `time` timestamp(14) NOT NULL DEFAULT CURRENT_TIMESTAMP );


Skoro mamy już nazwy tabel zajmijmy się edycja rekordów, świeżo rozkodowana baza wygląda mniej więcej tak:
INSERT INTO "wc3_player" VALUES(1,'','','Portek',07.07.2009);
Brakuje w niej tak jak pisałem wcześniej zdefiniowanych pól do których maja być dodane dane, poprawiamy więc odpowiednio kod:

INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`)VALUES(1,'','','Portek',07.07.2009);

Na pierwszy rzut oka widać co zostało dodane, "wc3_player" zostało zamienione na 'wc3_player', oraz dodane zostały nazwy pól (UWAGA! Ważne żeby nazwy pól były podawane między znakami 'a', oraz było w dokładnie takiej samej kolejności jak w zapytanie tworzącym tabele!).
Nie pozostało nam nic innego jak edycja wszystkich zapytań, ręczna edycja wszystkiego mija się z celem, komu chciało by się to wszystko wstawiać, posłużymy się więc opcją "Zamień". Edytujemy odpowiednio pierwszą linijkę, zaznaczamy stary kod który musimy zamienić, naciskamy klawisze CTRL+H, w pierwszym polu powinien pojawić się stary kod, następnie klikamy na pole poniżej, oraz zaznaczamy wyedytowaną i poprawna już część kodu, ukarze się ona w polu poniżej. Nie pozostaje już nic innego jak kliknąć przycisk Zamień wszystkie
Dołączona grafika

Wyedytowany cały kod, który można poprawnie i bez problemów importować do bazy danych wygląda tak:
DROP TABLE IF EXISTS wc3_player;
CREATE TABLE `wc3_player` ( `player_id` INTEGER PRIMARY KEY auto_increment, `player_steamid` varchar(25) NOT NULL, `player_ip` varchar(20) NOT NULL, `player_name` varchar(35) NOT NULL, `time` timestamp(14) NOT NULL DEFAULT CURRENT_TIMESTAMP );
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`)VALUES(1,'','','Portek',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(2,'','','Portek2',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(3,'','','Portek3',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(4,'','','Portek4',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(5,'','','Portek5',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(6,'','','Portek6',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(7,'','','Portek7',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(8,'','','Portek8',07.07.2009);
INSERT INTO `wc3_player` (`player_id` ,`player_steamid` ,`player_ip` ,`player_name` ,`time`) VALUES(9,'','','Portek9',07.07.2009);

Poradnik uważam za skończony, nie należy on do łatwiejszych bo i cała operacja nie jest łatwa. Wymagana jest znajomość struktury baz danych, zapytań SQL. W razie problemów proszę o kontakt w tym temacie lub poprzez Prywatną Wiadomość, będę pomagał :-)

Poradnik wykonany dla www.amxx.pl
Copyright � 2009 Portek. Kopiowanie zabronione.

Mówi o tym USTAWA ART.16
  • +
  • -
  • 22


#256504 Problem przy kompilacji kilku klas.

Napisane przez V3ko w 06.06.2011 18:19

Poprawione ^^ Sory ze kolejny post, ale on mógłby nie zauważyć.

Załączone pliki


  • +
  • -
  • 1


#256462 Problem przy kompilacji kilku klas.

Napisane przez V3ko w 06.06.2011 17:15

Łapaj.

Załączone pliki


  • +
  • -
  • 1


#256230 /premium w MotD

Napisane przez Leihto w 05.06.2011 17:26

<!DOCTYPE html 
	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
	<meta name="Description" content="Tu wpisz opis zawartości strony" />
	<meta name="Keywords" content="Tu wpisz wyrazy kluczowe rozdzielone przecinkami" />
	<title>Konta premium</title>
</head>
<body bgcolor="black"><font color="red">
<center><img src="cstrike/kontapremium.jpg" alt="Konta Premium" /></center><br>
Na naszym serwerze sa 4 rodzaje kont premium:<br>
- Bronze Premium (Sms: 7.38 zl , Przelew: 4 zl) : Tank , Profesjonalista<br>
- Silver Premium (Sms: 11.07 zl , Przelew: 5.50 zl) : Marynarz , Artylerzysta<br>
- Gold Premium (Sms: 23.37 zl , Przelew: 11.50  zl) : Kapitan , Killer<br>
- Diamond Premium (Sms: 30.75 zl , Przelew: 15 zl) : Cheater , Zawodowy Kucacz<br>
</font></body>
</html>

Mniej wiecej tak ;) Musisz pamietac aby ze kazda nowa linijke zaczynasz znacznikiem <br>
Co do zgodnosci z html :D Nie wiem :D Ale wiem tyle ze to dziala :P

P.S. Na serwerach nie wolno trzymac obrazkow :)
  • +
  • -
  • 1