Wypocin sadpepe
Daj kod po przeróbkach i zobaczymy czego brakuje
To równanie zostało stworzone przy pomocy kodu LaTeX:
Edytor LaTeX online: CodeCogs.com/latex/eqneditor.php
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.
|
Napisane przez Robiin
w 08.08.2018 22:51
Napisane przez d0naciak
w 28.12.2015 19:20
Opis
Plugin dodaje do gry klany. Każdy klan posiada swojego właściciela i członków - oni zdobywają poziom klanu. Z każdym nowym poziomem dostajemy punkty które możemy przeznaczyć w expa, krytyka bądź bogactwo. Klany posiadają swoje top 15, więcej do sprawdzenia w grze.
Klany przeznaczone są raczej dla Cod'ów z max. poziomem od 101 do 801. Na większych limitach będzie to działać, jednak mnożniki od statystyk mogą zgłupieć.
Maksymalny poziom klanu to 61, a wymagane doświadczenie do zdobycia kolejnego poziomu grupy jest generowane na podstawie tego który obowiązuje w klasach.
say /klany - otwiera menu klanów
Instalacja
Pobierz
cod_klany.sma 36,3 KB 1342 Ilość pobrań
cod_klany.amxx
Otwórz cod_klany.sma
Konfiguruj:
Skompiluj, reszta standardowa
Napisane przez Miczu
w 02.07.2008 15:13
Start mapy
plugin_init() { //code }Powyzsza funkcja jest tylko wywolywana po zmianie mapy (na samym jej poczatku).
Koniec mapy
plugin_end ( ) { //code }Powyzsza funkcja jest wywolywana przy zmianie mapy lub prawidlowym zamknieciu serwera. Prawdopodobnie nie wychwyci crasha.
Nowa Runda
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("HLTV", "Nowa_Runda", "a", "1=0", "2=0") } public Nowa_Runda() { //code }Nowa runda tym sposobem omija pierwsza runde - pierwsza po zmianie mapy.
Poczatek Rundy
#include <amxmodx> #include <amxmisc> public plugin_init() { register_logevent("Poczatek_Rundy", 2, "1=Round_Start") } public Poczatek_Rundy() { //code }
Koniec Rundy
#include <amxmodx> #include <amxmisc> public plugin_init() { register_logevent("Koniec_Rundy", 2, "1=Round_End") } public Koniec_Rundy() { //code }
Damage - obrazenia
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("Damage", "Damage", "b", "2!=0") } public Damage(id) { new vid = read_data(0) // vid == id new damage = read_data(2) new Origins[3] // Wspolrzedne gracza, granatu, obiektu wywolujacego obrazenia Origins[0] = read_data(4) Origins[1] = read_data(5) Origins[2] = read_data(6) new kid = get_user_attacker(id) // Gracz atakujacy //code }
DeathMsg - ktos umarl
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("DeathMsg", "DeathMsg", "a") } public DeathMsg() { new kid = read_data(1) //zabojca new vid = read_data(2) // ofiara new hs = read_data(3) // HeadShot (1 == true) new weapon[64] read_data(4,weapon,63) //krotka nazwa broni (bez weapon_ / CSW_ ) //code }kid i vid sa sobie rowne gdy zabije cie wlasna bron (granat) lub np. admin uzyje slay'a...
CurWeapon - obecna bron
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("CurWeapon","CurWeapon","be", "1=1") } public CurWeapon(id) { new wid = read_data(2) // Id broni new ammo = read_data(3) // liczba naboi w magazynku //code }
Podniesienie broni
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("WeapPickup", "WeapPickup", "b") } public WeapPickup(id) { new wid = read_data(1) // id broni //code }
Podniesienie amunicji
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("AmmoPickup", "AmmoPickup", "b") } public AmmoPickup(id) { new aid = read_data(1) //id amunicji new clip = read_data(2) //ilosc naboi //code }
Amunicja
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("AmmoX", "AmmoX", "b") } public AmmoX(id) { new aid = read_data(1) new clip = read_data(2) client_print(id,print_chat,"id %d aid %d clip %d",id,aid,clip) //code }
Wejscie na server
public client_putinserver(id){ //code }
Polaczenie z serwerem
public client_connect(id) { //code }
Rozlaczenie sie z serwerem
public client_disconnect(id) { //code }
Health - Zycie
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("Health", "Health", "be") } public Health(id) { new health = read_data(1) //code }
Money - zmiana w kasie
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("Money", "Money", "be") } public Money(id) { new Money = read_data(1) //code }
TeamInfo - informacjie o Teamie
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("TeamInfo","team_assign","a") } public team_assign() { new id = read_data(1) new Team[32] read_data(2,Team,31) //UNASSIGNED //TERRORIST //CT //SPECTATOR }
#include <amxmodx> #include <amxmisc> public plugin_init() { register_event("TeamInfo","team_assign","a") } public team_assign() { static old_team[33] new tid new id = read_data(1) new Team[32] read_data(2,Team,31) //UNASSIGNED //TERRORIST //CT //SPECTATOR if(equal(Team,"UNASSIGNED")) tid = 0 else if(equal(Team,"TERRORIST")) tid = 1 else if(equal(Team,"CT")) tid = 2 else if(equal(Team,"SPECTATOR")) tid = 3 if(old_team[id]==tid) return PLUGIN_CONTINUE //jesli druzyna sie nie zmienila to przerywamy event old_team[id] = tid //zapisujemy nowy team /*code //koniec code */ return PLUGIN_CONTINUE // skoro juz uzylismy returna to musimy tez na koniec go dac }
register_logeventnie maja parametru id - a mowiac inaczej jak dodamy parametr id, to bedzie mial wartosc 0
Napisane przez Miczu
w 07.03.2008 15:16
Funkcje poszczegolnych bibliotek:
Dokumentacja AMXX.pl
lub
Funkcje
Lista eventow:
Events
Informacje o broniach z Cs'a:
Nazwy broni i ammo do give_item (+ speed) - AMXX.pl: Support AMX Mod X
lub
Weapons
Web kompilator:
Kompilator - AMXX.pl: Support AMX Mod X
Informacje o stałych pev
Napisane przez DarkGL
w 19.12.2014 12:11
Jest to pierwsza część cyklu tutoriali na temat preprocesora autorstwa Y_Less przetłumaczona na język polski
Źródło http://forum.sa-mp.c...5175#post785175
http://darkgl.amxx.p...cessor-czesc-1/
Sam tutorial dotyczy preprocesora obecnego w wersji pawn'a dla sa:mp jednak wiele rzeczy jest wspólnych , niektóre niestety działają tylko w sa:mp ale postanowiłem zostawić ich opis jaką ciekawostkę. Wszelkie uwagi co do tlumaczenia mile widziane. Podczas tłumaczenia dodawałem / zmieniałem rzeczy od siebie.
Za wszystkie błędy lub nieścisłości przepraszam czasami ciężko było przenieść znaczenie zdań z języka angielskiego na polski.
Zawartość
Część 1 - Obejmuje wprowadzenie do preprocesora oraz kilka ważnych rzeczy przydatnych podczas pisania makr.
Część 2 - Wyjaśnienie dokładnie czego szuka kompilator oraz typowych zastosowań makr.
Część 3 - Opis innych dostępnych dyrektyw (oprócz"#define") oraz spojrzenie na definicje bez wartości podmiany.
Część 4 - Używanie stringów w preprocesorze.
Część 5 - Alternatywy dla preprocesora, wiele symboli i rekurencja.
Część 6 - Problemy z makrami oraz spacje.
Podstawowa podmiana
Na początek proste makra i jeszcze prostsze definicje. Idealny początek do wprowadzenia jak działa preprocesor.
Definicje
Definicja poniżej składa się tylko z tekstu do podmiany i tekstu na który podmieniasz.
#define MAX_PLAYERS 500
Klasyka - definicja określa ilośc graczy na Twoim serwerze.Idealny przykład jak działają definicje. Preprocesor jak sama nazwa wskazuje wykonuje się przed głownym procesem ( kompilatorem ). Kompilator bierze napisany kod i konwertuje go do pliku AMXX, preprocesor generuje napisany kod. Przykład:
printf("%d", MAX_PLAYERS);
Preprocesor podczas wykonywania przekonwertuje ten kod do:
printf("%d", 500);
Jest to kod który zostanie przekazany głownemu kompilatorowi i to ten kod zostanie przekonwertowany do pliku wynikowego ( AMXX ). Jest to po prostu podmiana tekstu. Wszystkie makra są w tej samej formie:
#define <szukany text><spacja/spacje><text podmiany>
Warto zauważyć że spacja jest ważna - pierwsza spacja oznacza koniec stringu który będzie szukany, wszystko za spacją jest traktowane jako string na który preprocesor będzie podmieniał znalezione stringi! W przykładzie wyżej szukany string to "MAX_PLAYERS" a string podmiany to "500".
Makra
Makro to coś w rodzaju funkcji - posiada parametry. Nazwy parametrów zaczynają się od "%0" do "%9" ( "%0" , "%1" , "%2" itp. itd. ) - nie można im nadać własnych nazw. Funkcja zwracająca maksymalną ilośc graczy pomnożoną przez liczbę wyglądała by tak:
MaxPlayersTimesNumber(number) { return MAX_PLAYERS * number; // Pamiętaj że "MAX_PLAYERS" jest definicją więc kompilator skompiluje te wyrażenie jako: // return (500) * number; }
Makro robiące to samo wyglądało by tak:
#define MAX_PLAYERS_TIMES_NUMBER(%0) MAX_PLAYERS * %0
Tym razem szukanym stringiem jest "MAX_PLAYERS_TIMES_NUMBER(%0)" a stringiem podmiany jest "MAX_PLAYERS * %0". "%0" to specjalne wyrażenie - nie oznacza szukaj "%0", oznacza szukaj czegokolwiek pomiędzy dwoma nawiasami . "%0" otrzymują tą samą wartość która była pomiędzy nawiasami w stringu który był podmieniany.
Przykład:
#define MAX_PLAYERS 500 #define MAX_PLAYERS_TIMES_NUMBER(%0) MAX_PLAYERS * %0 printf("%d", MAX_PLAYERS_TIMES_NUMBER(7));
Po wykonaniu preprocesora ( podamiana "%0" na "7" ) otrzymujemy:
#define MAX_PLAYERS 500 printf("%d", MAX_PLAYERS * 7);
"MAX_PLAYERS" jest dodatkowo makrem więc otrzymujemy:
printf("%d", 500 * 7);
Warto zauwayżyć że kompilator jest "inteligentny" - jeśli widzi takie wyrażenie jak to tutaj gdzie nie mamy żadnych zmiennych , wyliczy sobie wartość , więc kod który finalnie dostajemy do kompilacji wygląda tak ( kompilator nie umie formatować stringów ):
printf("%d", 3500);
Można by to też zrobić tak:
#define MAX_PLAYERS 500 #define MAX_PLAYERS_TIMES_NUMBER(%0) MAX_PLAYERS * %0 new value = 7; printf("%d", MAX_PLAYERS_TIMES_NUMBER(value));
Po wykonaniu preprocesora ( podamiana "%0" na "value" ) otrzymujemy:
#define MAX_PLAYERS 500 new value = 7; printf("%d", MAX_PLAYERS * value);
"MAX_PLAYERS" jest makrem więc otrzymujemy:
new value = 7; printf("%d", 500 * value);
Ponieważ te wyrażenie używa zmiennej kompilator nie umie go wyliczyć. Więc jest to finalny kod który zostaje skompilowany.
Dlaczego ?
Więc dlaczego używać makr zamiast funkcji ( lub dlaczego używać funkcji zamiast makr )? Makra podmieniają tekst - więc wszedzie gdzie umieścisz makro tam zostanie dodany twój tekst. Jeśli masz makro w kodzie użyte 100 razy , kod zostanie wygenerowany 100 razy. Z drugiej strony jeśli masz 100 wywołań funkcji w swoim kodzie , kod zostanie dodany tylko raz mimo 100 wywołań. Funkcje są prawdopodbnie bardziej użyteczne jeśli masz dużo kodu - duże bloki kodu występujące 100 razy utworzą bardzo duży plik AMXX ! Makra są raczej używane przy małej ilości kodu - wywołanie funkcji zajmuje pamieć i czas procesora więc jeśli masz mały blok kodu nie opłaca się wywoływać funkcji , ale to nie jest zasadą ! Jeśli użyłbyś funkcji zamiast makra powyżej , skompilowany kod wygląał by tak:
MaxPlayersTimesNumber(number) { return (500) * number; }
Przykład 1:
printf("%d", MaxPlayersTimesNumber(7));
Przykład 2:
new value = 7; printf("%d", MaxPlayersTimesNumber(value));
W obu przypadkach kompilator nie wie jak zoptymalizować kod.
Konwencja
Jedną z rzeczy które mogłeś zauważyć czytając ten poradnik jest nazewnictwo ,funkcja została nazwana "MaxPlayersTimesNumber" to samo makro zostało nazwane "MAX_PLAYERS_TIMES_NUMBER".
To tylko konwencja - funkcje w tym poradnik będą miały nazwy pisane małymi literami oprócz pierwszych znaków wyrazów , makra za to będą miały nazwy pisane wielkimi literami z wyrazami oddzielonymi "_", jest to po to,aby łatwo można było zorientować się czego teraz używamy bez sprawdzania definicji.
Kolejna konwencja to ustawianie stringu podmiany na pozycji 40 ( kiedy to możliwe ) - jest to po to, aby ułatwić czytanie dużej ilości makr np.
#define DEFINITION_1 1 #define MY_DEF 2 #define SOME_OTHER_LONG_NAME_DEFINITION 3 #define A_MACRO(%0) 3 * %0
Zamiast:
#define DEFINITION_1 1 #define MY_DEF 2 #define SOME_OTHER_LONG_NAME_DEFINITION 3 #define A_MACRO(%0) 3 * %0
Żadna z tych konwencji nie jest zasadą, więc masz wolną ręke przy używaniu ich, jeśli chcesz możesz je zignorować. Ale zachęcał bym Cie to posiadania naprawdę dobrych powodów zanim je zignorujesz.
Składnia / Semantyka
Szybkie przypomnienie. "Składnia" jest to wygląd kodu, "Semantyka" oznacza to co ten kod robi . Składnia pętli for to: "for (; ; ) {}", "semantyka" pętli for to: wykonaj się ileś razy na podstawie przekazanych parametrów. Wążna sprawą w następnej sekcji jest składnia i semantyka funkcji "printf". Składnia to: "printf(string[], ...);" - czyli string a następnie dowolna ilość parametrów, zawartość stringu nie wpływa na składnie - "printf("%d", 6, 7);" spełnia zasady składnie, ale 7 nie zostanie wyświetlona ponieważ string określa semantykę funkcji ( co ona naprawdę robi ).Kod się skompiluje ale nie będzie działał poprawnie , i jest to bardzo ważna różnica.
Parametry
Makro może posiadać kilka parametrów:
#define MULTIPLY_TWO_NUMBERS(%0,%1) %0 * %1
W rzeczywistości makro może mieć nawet do 10 parametrów:
#define MULTIPLY_NUMBERS(%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) %0 * %1 * %2 * %3 * %4 * %5 * %6 * %7 * %8 * %9
Niektórzy lubią stawiać spacje po przecinku w liście parametrów np.:
#define MULTIPLY_TWO_NUMBERS(%0, %1) %0 * %1
Czegoś takiego nie można robić w makrach - tak jak było wcześniej powiedziane spacja oznacza koniec stringu do podmiany , więc preprocesor będzie szukał "MULTIPLY_TWO_NUMBERS(%0,", a nie "MULTIPLY_TWO_NUMBERS(%0, %1)" i podmieni to na "%1) %0 * %1".
Teraz kiedy wiesz już czym jest makro i czym są jego parametry możemy skupić się na różnicach parametrów makr i parametrów funkcji.
Po pierwsze - parametry makra i funkcji nie są tym samym i nie powinny być traktowane w ten sam sposób. Parametry funkcji są oddzielane przecinkami, parametry makr są oddzielone czymkolwiek chcesz.
Ten kod nie jest poprawny, podczas wywołania funkcji jest przekazywane za dużo parametrów:
MyFunc(a) { return a; } main() { printf("%d", MyFunc(1, 2)); }
Ten kod jest poprawny:
#define MY_FUNC(%0) %0 main() { printf("%d", MY_FUNC(1, 2)); }
W przykładzie wyżej makro "MY_FUNC" szuka czegoś pomiędzy dwoma nawiasami poprzedzone "MY_FUNC". W tym przykładzie zawartością pomiędzy nawiasami jest "1, 2". Wyrażenie zawiera przecinek ale dla makra nie robi to różnicy. Kod po wykonynaniu preprocesora dla tego makra będzie wyglądał tak:
main() { printf("%d", 1, 2); }
Wygenerowany kod jest w pełni poprawny( oczywiście 2 nie zostanie wyświetlone ).
Jeśli parametry nie są odzielane przecinkami , jak móc używać więcej niż jednego ? Parametry są odzielane czymkolwiek chcesz żeby były odzielane np.:
#define MULTIPLY_TWO_NUMBERS(%0,%1) %0 * %1
Kod wyżej będzie szukał "MULTIPLY_TWO_NUMBERS(" następnie wszystkiego do przecinka , przecinka , wszystkiego do zamykającego nawiasu.
printf("%d", MULTIPLY_TWO_NUMBERS(6, 7));
Kod wyżej zostanie podmieniony przez makro ( spacja tutaj jest dopuszczalna , nie jest dopuszczalna w deklaracji ) i otrzymamy taki kod:
printf("%d", 6 * 7);
Jednak przecinek nie jest zamykajacym nawiasem więc to też jest prawidłowe:
printf("%d", MULTIPLY_TWO_NUMBERS(6, 7, 8));
W tym przypadku parametr "%0" przyjmuje wartość 6 a parametr "%1" przyjmuje wartość "7,8" więc po wygenerowaniu kodu otrzymamy:
printf("%d", 6 * 7, 8);
Nawiasy
Skoro parametry są tak elastyczne jak możemy kontrolować to co generuje nam preprocesor ? Wszystkie makra wyżej były bardzo złe , nie używały nawiasów.
Przykład:
// Without brackets (first). #define MULTIPLY_TWO_A(%0,%1) %0 * %1 // With brackets (second). #define MULTIPLY_TWO_B(%0,%1) ((%0) * (%1)) main() { // Two with first. printf("%d", MULTIPLY_TWO_A(6, 7)); // Two with second. printf("%d", MULTIPLY_TWO_B(6, 7)); // Three with first. printf("%d", MULTIPLY_TWO_A(6, 7, 8)); // Three with second. printf("%d", MULTIPLY_TWO_B(6, 7, 8)); }
Po wygenerowaniu otrzymamy taki kod:
main() { // VALID printf("%d", 6 * 7); // VALID printf("%d", ((6) * (7))); // VALID printf("%d", 6 * 7, 8)); // INVALID! printf("%d", ((6) * (7, 8))); }
Finalny kod pokazuje ważna różnice , po dodaniu nawiasów wygenerowany kod jest błędny ( składnia jest błędna ). Próbujemy mnożyć "6" przez "7,8" - co jest błędne więc użytkownik dostanie błąd przy kompilacji.
Inne użycie nawiasów to ustalanie priorytetów operatorów. Dzięki nawiasom możemy ustalać kolejność wykonywania operatorów np. "4 + 5 * 6" otrzymujemy "34", nie "54". Ponieważ * ma wyższy priorytet niż + więc "4 + 5 * 6" zostaje wykonane do "4 + 30" a potem "34". Jeśli parametry były by wykonywane po kolei "4 + 5 * 6" staje się "9 * 6" a następnie "54".
Przeanalizujmy taki kod
#define ADD_TWO(%0,%1) %0 + %1 main() { printf("%d", ADD_TWO(3, 3) * 7); }
3 + 3 to 6 , 6 * 7 to 42 prawda? Nie! Zobaczmy wygenerowany kod.
main() { printf("%d", 3 + 3 * 7); }
Wiemy co się stanie, mnożenie zostanie wykonane przed dodawaniem więc otrzymamy 24. Całość możemy naprawić dodając nawiasy:
#define ADD_TWO(%0,%1) (%0 + %1)
Kolejny przykład
#define MUL_TWO(%0,%1) (%0 * %1) main() { printf("%d", MUL_TWO(3 + 3, 7)); }
Dodaliśmy nawiasy więc wszystko powinno być ok ? Błąd ! Zobaczmy co wygenerował preprocesor:
main() { printf("%d", (3 + 3 * 7)); }
Obliczenia są w nawiasach, ale znowu mnożenie zostanie wykonane przed dodawaniem. Powinniśmy dodać jeszcze jeden poziom nawiasów dzięki czemu wszystkie operacje będa wykonywane poprawnie:
#define MUL_TWO(%0,%1) ((%0) * (%1))
PAMIĘTAJ: Owijaj makro i parametry makra w nawiasy. Istnieją sytuację kiedy nie trzeba tego robić ale o nich opowiem później.
Makra kilku linijkowe
Makro może mieć kilka linii dzięki użyciu "\". Zasada jest prosta jeśli na końcu linii znajduje się znak \ makro jest kontynuowane w kolejnej linii. Makro nie może być kontynuowane w parametrach i nazwie z tych samych powodów z których nie możemy używać spacji. Uwaga: W tym poradniku znak kontynuacji jest umieszczany na pozycji 80:
#define MUL_TWO(%0,%1) \ ((%0) * (%1))
#define MUL_TWO(%0,%1) \ ( \ (%0) \ * \ (%1) \ )
#define MUL_TWO(%0,%1) \ ( \ ( \ %0 \ ) \ * \ ( \ %1 \ ) \ )
Ostatnia linii makra nie posiada operatora konytnuacji.
Pułapka
Jest jeden bardzo ważny problem podczas używania makr zamiast funkcji:
Wersja funkcyjna:
PrintSquare(var) { printf("%d", var * var); } main() { new var = 2; PrintSquare(var++); printf("%d", var); }
Wynik:
4
3
Wersja z makrami:
#define PRINT_SQUARE(%0) printf("%d", (%0) * (%0)) main() { new var = 2; PRINT_SQUARE(var++); printf("%d", var); }
Możemy otrzymać:
4
4
Lub:
6
4
Ponieważ parametry przekazane do makra są inkrementowane , więc inkrementacja jest dodawana przy generowaniu kodu:
main() { new var = 2; printf("%d", (var++) * (var++)); printf("%d", var); }
W takim przypadku w drugim printf zmienna var będzie zinkrementowana dwa razy - co jest błędne i nie wydarzy sie podczas użycia funkcji.
Kolejność wykonania dla operatora inkrementowania może zostać wykonana na dwa sposoby:
temp1 = var; temp2 = var; var = var + 1; var = var + 1; printf("%d", temp1 * temp2);
Lub:
temp1 = var; var = var + 1; temp2 = var; var = var + 1; printf("%d", temp1 * temp2);
Oba są technicznie prawidłowe - w obu przypadkach inkrementowanie jest wykonane po użyciu zmiennej , problemem jest tylko który sposób wybierze kompilator. Dlatego wynik może być "4" lub "6".
Bądź bardzo uważny podczas używania makr z parametrami które modyfikują zmienne - dlatego nazwy makr są pisane bardzo często z dużych liter aby użytkownik wiedział że jest to makro i był bardzo uważny podczas jego używania.
Napisane przez Asiap
w 03.11.2017 17:46
g_pSpriteWave = engfunc(EngFunc_PrecacheModel, "sprites/shockwave.spr"); stock CreateBeamCylinder(Float:vecOrigin[3], iLife, iWidth, iColor[3]) { message_begin_f(MSG_PVS, SVC_TEMPENTITY, vecOrigin); write_byte(TE_BEAMCYLINDER); write_coord_f(vecOrigin[0]); write_coord_f(vecOrigin[1]); write_coord_f(vecOrigin[2]); write_coord_f(vecOrigin[0]); write_coord_f(vecOrigin[1]); write_coord_f(vecOrigin[2] + 332.0); write_short(g_pSpriteWave); write_byte(0); write_byte(0); write_byte(iLife); write_byte(iWidth); write_byte(0); write_byte(iColor[0]); write_byte(iColor[1]); write_byte(iColor[2]); write_byte(255); write_byte(0); message_end(); }
static Float:vecOrigin[3]; pev(id, pev_origin, vecOrigin); vecOrigin[2] -= pev(id, pev_flags) & FL_DUCKING ? 15.0 : 33.0; CreateBeamCylinder(vecOrigin, 5, 3, { 255, 0, 0 });
Napisane przez Puchate
w 25.10.2015 17:50
Napisane przez GwynBleidD
w 16.04.2015 16:33
a = 10 // przypisze wartość 10 do zmiennej aUmieszczenie czegokolwiek innego po jego lewej stronie poskutkuje pięknym błędem kompilacji.
10 = a // zwróci błąd, nie możemy przecież nic przypisać do 10, nie jest zmienną! 10 = 12 // również zwróci błąd 10 = 10 // to też jest błąd, nie ważne że 10 jest równe 10, to nie jest operator porównaniaCo ciekawe, operator przypisania ZWRACA wartość. Wartością tą jest wartość prawego wyrażenia, dzięki temu możemy takiego operatora użyć kilkukrotnie w 1 instrukcji:
a=b=c=12 // zmiennej c przypisze wartość 12, następnie zrobi to samo dla wartości b oraz a
if ( x = funkcja(y) )Wiele osób pewnie pomyśli, że powyższy kod porówna x z wartością zwróconą przez funkcję. Otóż nie zrobi tego! Przypisze on do zmiennej x wartość zwróconą przez funkcję, a następnie tą samą wartość zwróci. Tak więc jeśli funkcja zwróci true, kod wewnątrz if się wykona, jeśli zwróci false, kod się nie wykona. Nie jest ważne co do tej pory siedziało w zmiennej x, na dodatek zostanie to zastąpione nową wartością!
if (( x = funkcja(y) ))Nie zmieni to działania warunku, ale poinformuje kompilator, że WIEMY co robimy i nie pomyliliśmy się używając = zamiast == w tym miejscu.
10 + 20 // 30 20 - 2 // 18 14 * 3 // 42 12 / 2 // 6 13 / 2 // również 6 ! 13.0 / 2 // 6.5 13 % 2 // 1
~14 // dobrze 14~ // żle, argument musi być po prawej!
a •= 10jest równoznaczne:
a = a • 10Oczywiście operator • w języku pawn nie istnieje, należy go zastąpić dowolnym operatorem arytmetycznym lub bitowym.
i++ // postinkrementacja ++i // preinkrementacja --i // predekrementacja i-- // postdekrementacja
i += 1Postinkrementację można zapisać inaczej tylko jako funkcję:
postinkrementacja(&i) { new j = i; i += 1 return j; }
if (is_user_connected(id) && has_user_jetpack(id))kod wewnątrz funkcji has_user_jetpack NIE ZOSTANIE NIGDY wykonany, jeśli gracz nie jest połączony do serwera!
if (has_user_jetpack(gracz1) || has_user_jetpack(gracz2))sprawdzenie dla drugiego gracza czy posiada jetpack NIGDY SIĘ NIE WYKONA jeśli pierwszy gracz jetpack posiada.
is_user_connected(id)?"gracz jest na serwerze":"gracza nie ma na serwerze"
Napisane przez Droso
w 24.11.2013 21:08
Myślę, że łatwiej będzie Ci to zrozumieć:
Najpierw tworzymy jakby uchwyt i nazwę naszego menu:
new menu = menu_create("Lista Graczy:", "menu_handler");
Następnie przystępujemy to pętli, ty użyłeś do tego jeszcze funkcji get_players, ale ja osobiście jej nie lubię , bo zawiera błędy itd.
Dlatego użyjemy samej pętli
Najpierw zmienne
new maxplayers = get_maxplayers(); // ile osob moze byc maksymalnie na serwerze new name[32] // zmienna przechowujaca nick gracza new data[6] // to bedzie ID gracza, ktore wysylamy w info :)
Teraz pętla:
for(new i=1; i<=maxplayers; i++) // pętla od 1 DO MAKSYMALNEJ LICZBY GRACZY { if(!is_user_connected(i)) continue; // jezeli gracz o danym ID (i) nie jest polaczony to go pomijamy uzwajać "continue" if(is_user_hltv(i) || is_user_bot(i)) continue; // jezeli dane ID to HLTV/BOT - pomijamy! num_to_str(i, data, 5); get_user_name(id, name, 31); // pobieramy nick menu_additem(menu, name, data); // dodajemy do menu gracza. }
Zakończenie menu, czyli wyświetlelnie:
menu_display(id, menu, item);
Teraz funkcja menu_handler
public menu_handler(id, menu, item) { if(item == MENU_EXIT) // jezeli gracz wyszedl z MENU - nic nie robimy :) return; if(!is_user_connected(id)) // jezeli gracz, ktory wybieral cos z menu nie jest polaczony to konczymy interakcje :D return; // zmienne sa wymagane ;( new name[32]; // ta zmienna bedzie przechowywala nick gracza, a inaczej tekst wybranej czesci menu. new callback; // to jest callback na razie Ci nie potrzebny nie zwracaj uwagi new data[6]; // to będzie ID gracza ;) new dostep; // to Ci nie potrzebne; menu_item_getinfo(menu, item, dostep, data, 5, name, 31, callback); // pobieramy dane wybranego/ej itemu/opcji z menu! new id2 = str_to_num(data); if(!is_user_connected(id2)) return; // id2 - to id gracza wybranego z menu :) // name - to jego nick. client_print(id, print_chat, "Wybrales gracza: %s o ID: %d", name, id2); :) }
Proszę.
Nie rozumiesz, pisz - wytłumaczymy w tym temacie.
Napisane przez Rivit
w 19.12.2014 18:32
Napisane przez R3X
w 14.10.2011 18:40
Napisane przez WeBsteR
w 05.07.2015 10:36
Łap coś po mojemu :
#include <amxmodx> #include <hamsandwich> #include <fun> public plugin_init() { register_plugin("Granaty","1.0","Webster"); RegisterHam(Ham_Spawn, "player", "respawn", 1); } public respawn(id) { if(get_user_flags(id) & ADMIN_LEVEL_A) { set_task(10.0,"gift",id) } } public client_authorized(id) { if(get_user_flags(id) & ADMIN_LEVEL_A) { set_task(10.0,"gift",id) } } public gift(id) { for(new id=0;id<33;id++) { if(is_user_alive(id) && get_user_team(id) == 1) { give_item(id,"weapon_flashbang") give_item(id,"weapon_smokegrenade") } } }
Napisane przez skorpius
w 04.07.2015 18:31
Hahaheh to że dałeś Public z nazwą round_start nic ci nie da./* Plugin generated by AMXX-Studio */ #include <amxmodx> #include <fun> #define PLUGIN "New Plug-In" #define VERSION "1.0" #define AUTHOR "klqs" public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR); } public round_start(id){ if(get_user_flags(id) & ADMIN_LEVEL_A){ set_task(10.0, "Granaty", id); } } public Granaty(id){ if(is_user_alive(id) && get_user_team(id) == 1){ give_item(id, "weapon_flashbang"); give_item(id, "weapon_smokegrenade"); } }Mój pierwszy pluginNie testowałem.