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
 

klqs99 - zdjęcie

klqs99

Rejestracja: 03.07.2015
Aktualnie: Nieaktywny
Poza forum Ostatnio: 09.03.2021 13:26
-----

#751668 Public_paint_splat Pb Mod

Napisane przez Robiin w 08.08.2018 22:51

Wypocin sadpepe

 

Daj kod po przeróbkach i zobaczymy czego brakuje


  • +
  • -
  • 2


#717013 Klany

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 

Załączony plik  cod_klany.sma   36,3 KB  1342 Ilość pobrań
  cod_klany.amxx

Otwórz cod_klany.sma

Konfiguruj:

#define LIMIT_CZLONKOW 15 //Ile maksymalnie czlonkow moze wystepowac w klanie
#define WYMAGANY_POZIOM 15 //Jaki poziom jest wymagany aby moc zalozyc klan
#define WYMAGANA_ILOSC_MONET 500 //Ile trzeba monet do zalozenia klanu
//Zakomentuj aby wylaczyc udzial monet w klanach
 

Skompiluj, reszta standardowa :)


  • +
  • -
  • 12


#9646 Eventy

Napisane przez Miczu w 02.07.2008 15:13

Postaram sie przedstawic najwazniesze eventy do cs'a, wraz z codem wystarczajacym do pozniejszego korzystania z niego O:)

Ps. podam tylko sprawdzone metody i nie będę przytaczal jakie sa bledne metody (szczegolnie nowa runda jest pare metod w tym 1 bledna, czesto stosowana).

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.
#mozliwe problemy gdy w tym evencie np: operacje na graczu typu danie broni(potwierdzone)...

Poczatek Rundy


Poczatek rudny to jak sie freeze skonczy - mozna sie ruszac ;-)
#include <amxmodx>
#include <amxmisc>
 
public plugin_init() {
	register_logevent("Poczatek_Rundy", 2, "1=Round_Start")  
}
 
public Poczatek_Rundy()
{
	//code
}

Koniec Rundy


Przeciwnik zabity/Bomba wybuchla/Bomba zostala rozbrojona/zakladnicy uwolnieni/minol czas rudny
#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...

kid == 0 gdy np. spadniesz z wysokiej wysokosci...

CurWeapon - obecna bron



Wykrywa zmiane broni - takze gdy sie sawnujesz dostajesz nowa bron i funkcja tez jest wywolana.

#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
}

Noz, granaty itp. maja ammo = -1

Info-bronie

Z testow wynika, ze w/w event jest tez wywolywany po wystrzeleniu naboju (ammo sie zmienia) lub po przeladowaniu.

Podniesienie broni



Podniesie broni a takze kupienie. Na starcie rundy sie uruchomi gdy dostajemy noz i pistolet (2 razy). Jest wywolywany takze gdy kupimy cos, ale nie bedziemy mieli tego w rekach (np. granat).

#include <amxmodx>
#include <amxmisc>
 
public plugin_init() {
	register_event("WeapPickup", "WeapPickup", "b")
}
 
public WeapPickup(id)
{
	new wid = read_data(1) // id broni
 
	//code
}

Nie liczy podniesienia Shilda oraz kupienia defa, noktowizora czy kamizelki Dołączona grafika

Podniesienie amunicji



Jak kupujemy amunicje to clip daje nam wartosc ile nam przybylo. Jesli podniesiemy M4A1 co ma 24 w broni i 90 w zapasie to clip bedzie mial wartosc 90, a nie 114. Jak drop'niemy i podniesiemy wlasna bron to event nie zostanie wywolany.

#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



Aktualny stan amunicji w 'zapasie'. Jak kupujemy ammo to clip ma laczna wartosc naboi w magazynku. Jak podniesiemy po kims bron np. AK 25 i 90 w zapasie to clip wynosi 90.

Na poczatku rundy wszystkie typy naboi za wyjatkiem tych do ktorych mamy bron sa zerowane. Jak kupujemy granaty to clip ma wartosc rowna ilosci danego typu np. flash max 2...
#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


Juz widzisz mape ;-)
public client_putinserver(id){
	//code
}

Polaczenie z serwerem


Czyli gdy np. w konsoli napiszesz connect IP:PORT
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



Ogolny wyglad eventu:
#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
}

Ale trzeba sie tu pilnowac! Z moich badan wynika ze event jest wywolywany za kazdym spawnem i dodatkowo przy wyborze z menu teamu.

Jesli chcemy wykrywac autentyczna zmiane druzyny musimy zastosowac taki zabieg (chyba najoptymalniej i do tego czysto):
#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
}

=================================================

Eventy wywolane przez:
register_logevent
nie maja parametru id - a mowiac inaczej jak dodamy parametr id, to bedzie mial wartosc 0

=================================================

Flagi do eventow:

"a" - Global Event - wysylany do all graczy (mozliwy jest brak mozliwosci podpiecia id do eventu np. DeathMsg)
"b" - Event sent to a single target - do konkretnego gracza (zwiazany z pojedynczym graczem - demage)
"c" - Send only once when repeated to other players - tylko raz gdy jest powtarzany u innych graczy.
"d" - Only if sent to a dead player - tylko u martwych graczy
"e" - Only if sent to an alive player - tylko u zywych graczy ( przed wersja 1.80 jest bug, wiec i tak wypada sprawdzac is_user_alive(id) )


PS. Jak będę mial czas to dodam wiecej O:)
PS2. Jak cos nie dziala to dajcie znac, bo nie wszystko mialem czas sprawdzic przed daniem na forum.

PS3. Jestem autorem tego poradnika i wolno tylko kopiowac za moja zgoda... Nie [you] nie mozesz kopiowac!
  • +
  • -
  • 60


#2093 Potrzebne do Scriptingu

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

 

http://amxx.pl/pevresearch


  • +
  • -
  • 8


#675787 PAWN Pre-Processor Część 1

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.


  • +
  • -
  • 12


#743785 Beam - czerwony okrąg wokół entity

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 });

  • +
  • -
  • 1


#713773 Blokowanie komendy status

Napisane przez Puchate w 25.10.2015 17:50

Nie da się pluginem.

 

https://forums.allie...441&postcount=2


  • +
  • -
  • 1


#697629 Operatory w PAWNie

Napisane przez GwynBleidD w 16.04.2015 16:33

Już kilka artykułów o tym istnieje, jednak żadnen nie opisuje tego dokładniej. Istnieje również ładny artykuł na wikibooks, będący częścią książki o języku C (C/Operatory - Wikibooks, biblioteka wolnych podręczników) jednak opisuje on niektóre kwestie dość zawile i jest o języku C, a w PAWNie jest kilka drobnych różnic (m.in w rzutowaniu itp)
 
Wstęp
 
Ogólnie operatory możemy podzielić na 3 kategorie: dwuargumentowe, jednoargumentowe i jeszcze jeden, samotny w swojej grupie operator wyrażenia warunkowego ( ? : ) który posiada 3 argumenty.
 
Operatory dwuargumentowe przyjmują 2 argumenty, rozdzielone właśnie tym operatorem. Argumenty nazywamy odpowiednio lewym i prawym.
 
Operatory jednoargumentowe przyjmują tylko jeden argument, który powinien być określony z lewej lub z prawej strony operatora (w zależności od operatora i jego użycia).
 
Operator przypisania
 
Operator przypisania, czyli operator = służy do umieszczenia wartości znajdującej się z prawej strony w zmiennej po lewej stronie. Po prawej może znajdować się dowolne wyrażenie, po lewej musi znajdować się zmienna.
 
a = 10  // przypisze wartość 10 do zmiennej a
Umieszczenie 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ównania
Co 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
 
Dzięki temu możemy użyć takiego operatora w warunku if:
 
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ą!
 
Bystre oko zauważy, że kompilator AMXX zwróci nam warning przy kompilacji tej linii. Aby kompilator uciszyć, wystarczy objąć warunek dodatkowymi nawiasami:
 
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.
 
Operatory arytmetyczne
 
Operatory arytmetyczne wykonują proste działania arytmetyczne i zwracają ich wynik. Wszystkie operatory arytmetyczne są dwuargumentowe i zaliczamy do nich +, -, *, / oraz %. Wykonują one po kolei: dodawanie, odejmowanie, mnożenie, dzielenie (zwrócenie wyniku z dzielenia), dzielenie (zwrócenie reszty z dzielenia). Przykłady:
 
 
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
 
Dodatkowemu wyjaśnieniu podlegają operatory dzielenia. Pierwszy z nich dokona dzielenia całkowitego (tj zaokrągli wynik z dzielenia do jedności w dół) jeśli po jego obu stronach znajdą się liczby typu całkowitego. Dokona jednak dokładnego dzielenia, gdy choć z jednej strony znajdzie się liczba zmiennoprzecinkowa. Drugi z operatorów dokona zawsze dzielenia całkowitego i zwróci jego resztę.
 
Operatory znaku liczby
 
Są to operatory - i + dla których podany został tylko 1 argument, po prawej stronie. Skutkiem jest zachowanie (dla +) lub zmiana na przeciwny (dla -) znak liczby. Wyobrazić sobie można to tak, jakby po lewej stronie wirtualnie stało zawsze 0 ;)
 
Operatory te można rozróżnić tylko, gdy po lewej stronie nie znajduje się nic, znajduje się inny operator lub znajduje się nawias.
 
Operatory bitowe
 
Istnieje 7 operatorów bitowych, jeden jednoargumentowy i sześć dwuargumentoych.
 
Operatorem jednoargumentowym jest ~ czyli negacja bitowa. Przyjmuje on argument po swojej PRAWEJ stronie:
 
~14 // dobrze
14~ // żle, argument musi być po prawej!
 
Operator zwraca negację bitową podanego argumentu.
 
Operatorami dwuargumentowymi są operatory &, |, ^, <<, >> oraz >>>. Trzy pierwsze z nich dla podanych argumentów zwracają odpowiednio ich koniunkcję bitową (iloczyn bitowy), ich alternatywę bitową (suma bitowa) oraz ich alternatywę rozłączną (bitową różnicę symetryczną, XOR).
 
Pozostałe trzy dokonują przesunięcia bitowego. Argument po lewej stronie jest liczbą przesuwaną, a argument po prawej oznacza o ile bitów argument po lewej zostanie przesunięty. << dokonuje przesunięcia w lewo, >> w prawo arytmetycznie, a >>> w prawo logicznie.
 
Więcej o operatorach bitowych tutaj: Operacje bitowe
 
Operatory skróconego przypisania
 
Operator skróconego przypisania jest niczym innym, jak połączeniem operatora arytmetycznego lub bitowego z operatorem przypisania. Dla operatora •:
 
a •= 10
jest równoznaczne:
 
a = a • 10
Oczywiście operator • w języku pawn nie istnieje, należy go zastąpić dowolnym operatorem arytmetycznym lub bitowym.
 
Inaczej mówiąc: operator ten wykona działanie na argumencie lewym i prawym tak jakby to miało miejsce przy zwykłym operatorze arytmetycznym lub bitowym, jednak wynik tego działania zapisze również w lewym argumencie.
 
Oznacza to, że tak jak dla operatora przypisania, zwraca on wartość przypisywaną oraz wymaga by po jego lewej stronie znajdowała się zmienna.
 
Inkrementacja i dekrementacja
 
Są to operatory ++ oraz --, są operatorami jednoargumentowymi i występują w 2ch odmianach: post i pre. Postinkrementacja i postdekrementacja następują, gdy argument zostanie podany z lewej strony. Preinkrementacja i predekrementacja gdy zostanie podany z prawej strony. Przykłady:
 
 
i++ // postinkrementacja
++i // preinkrementacja
--i // predekrementacja
i-- // postdekrementacja
 
Operatory te zwiększają (inkrementacja) lub zmniejszają (dekrementacja) wartość liczby o 1. Jako, że zapisują one wynik w zmiennej podanej jako argument, przyjmują za argument WYŁĄCZNIE zmienne. Nie mogą być to liczby ani inne wyrażenia. Post od pre różni się zwracaną wartością. Postinkrementacja zwraca wartość przed wykonaniem działania, preinkrementacja wartość po wykonaniu działania. Preinkrementacja jest bezpośrednim odpowiednikiem zapisu:
 
i += 1
Postinkrementację można zapisać inaczej tylko jako funkcję:
 
postinkrementacja(&i) {
    new j = i;
    i += 1
    return j;
}
 
Operatory logiczne
 
Zanim o samych operatorach, trochę o samych stanach logicznych. W języku pawn istnieją 2 stany logiczne: prawda i fałsz, które są swoimi wzajemnymi przeciwieństwami. Fałszem jest wszystko o wartości zero, prawdą wszystko o wartości różnej od zera! To oznacza, że prawdą jest nie tylko 1, ale też 2, 10, 2000 a nawet liczby ujemne czyli -300 lub -1!
W związku z tym, że wartości dla prawdy jest de facto nieskończenie wiele (właściwie to skończenie, ale i tak mnóstwo), przyjęło się że każdy operator logiczny będzie zwracał 1 jako prawdę logiczną. Zważmy jednak na to, że nadal może on przyjąć dowolną wartość i jeśli jest ona różna od zera, potraktuje ją jako prawdę !!!
 
Operatorami logicznymi są: !, ==, !=, <, >, <=, >=, && oraz ||.
 
Pierwszy z nich, czyli ! jest operatorem jednoargumentowym i przyjmuje argument, tak jak operator negacji bitowej, po swojej prawej stronie. Zwraca on logiczne przeciwieństwo danego wyrażenia. Czyli jeśli jako argument dostanie prawdę, zwróci fałsz, jeśli fałsz to zwróci prawdę.
 
Reszta z nich przyjmuje 2 argumenty i możemy je podzielić na 2 kategorie: operatory porównania i operatory and i or.
 
Operatory porównania po prostu porównują 2 wartości ze sobą i zwracają prawdę lub fałsz jeśli ich wewnętrzny warunek został spełniony.
== sprawdzi czy wartości są równe
!= sprawdzi czy wartości są różne
> sprawdzi czy wartość po lewej jest większa od wartości po prawej
< sprawdzi czy wartość po lewej jest mniejsza od wartości po prawej
>= sprawdzi czy wartość po lewej jest większa lub równa wartości po prawej
<= sprawdzi czy wartość po lewej jest mniejsza lub równa wartości po prawej
 
Operator && jest to operator AND, sprawdza on czy zarówno po lewej jak i po prawej znajduje się prawda logiczna. Jest dość specyficznym operatorem, ponieważ najpierw sprawdzi (i jednocześnie wykona odpowiednie działania) czy po prawej jest prawda, a dopiero później po lewej. Jeśli po prawej znajdzie się fałsz, wszystko po jego lewej stronie NIE ZOSTANIE wykonane!
 
Oznacza to, że:
 
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!
 
Operator || jest operatorem OR, sprawdza on czy po lewej lub po prawej znajduje się prawda logiczna. On również zachowuje się specyficznie, gdyż nie wykona nigdy kodu po jego prawej jeśli po lewej znajduje się prawda.
 
Oznacza to, że:
 
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.
 
Operator wyrażenia warunkowego
 
Operator ten przyjmuje 3 argumenty, pierwszy z nich wstawiamy przed znakiem zapytania, drugi pomiędzy znakiem zapytania, a dwukropkiem, a trzeci z nich za dwukropkiem.
 
Działanie operatora jest dość proste, jeśli 1 argument jest prawdą, zwróci on 2 argument, jeśli fałszem, zwróci 3 argument. Przykład:
 
 
is_user_connected(id)?"gracz jest na serwerze":"gracza nie ma na serwerze"
 
Nawiasy
 
Prócz tych wszystkich operatorów występują również nawiasy. Pierwszy z nich, czyli nawias okrągły () może służyć do 2ch rzeczy: może grupować (jak w matematyce) odpowiednie wyrażenia, zmieniając ich kolejność wykonywania oraz może być składnikiem definicji lub wywołania funkcji.
 
Drugi z nich, nawias kwadratowy [] służy do definiowania tablicy lub do wywoływania konkretnego elementu tej tablicy.
 
Priorytety i kolejność obliczeń
 
Każdy z operatorów posiada pewien priorytet, który determinuje kolejność w jakiej operatory zostaną wywołane jeśli znajdują się w 1 instrukcji. Dodatkowo każdy z operatorów posiada kierunek łączności, który determinuje w jakiej kolejności zostaną wykonane działania dla operatorów o tym samym priorytecie.
 
Priorytety od najwyższego do najniższego:
  • Nawiasy
  • wybór elementu tablicy, wywołanie funkcji, postinkrementacja, postdekrementacja 
  • !, ~, + i - (jako znak liczby), preinkrementacja, predekrementacja
  • *, /, %
  • + i - (jako operatory arytmetyczne)
  • <<, >>, >>>
  • <, <=, >, >=
  • == !=
  • &
  • ^
  • |
  • &&
  • ||
  • ?: (operator wyrażenia warunkowego)
  • wszystkie operatory przypisania
Większość operatorów posiada łączność lewostronną. Wyjątkiem są operatory priorytetów 3, 14 i 15 które posiadają łączność prawostronną.
  • +
  • -
  • 13


#588187 [ROZWIĄZANE] Jak stworzyc menu z listą graczy?

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ę :D, 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.

 


  • +
  • -
  • 5


#675889 Call of Duty: MW Mod [UPDATE]

Napisane przez Rivit w 19.12.2014 18:32

Paczke mozna wgrac jak ktos ma serwer na pukawce więc nwm poco to jest skoro nic tu nowego :>

 

 

:facepalm2: :facepalm2: :facepalm2: :facepalm2: :facepalm2: :facepalm2: :facepalm2: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm: :facepalm:

 

 

Nie pomyślałeś, że tamta paczka pochodzi stąd?


  • +
  • -
  • 5


#307752 Generator klas COD Mod

Napisane przez R3X w 14.10.2011 18:40

Przygotowaliśmy dla Was Generator klas (link również w menu Dodatki AMXX)

Wypełnij formularz i pobierz własną klasę do nowego Cod moda. Oprócz wyboru broni i statystyk klasy możliwe jest też dołączanie różnych dodatków. Na razie jest ich kilka, niedługo będą kolejne.

Mam nadzieję, że się przyda :)
  • +
  • -
  • 98


#705110 [Prośba]Napisanie prostego pluginu na dodawanie itemów po czasie.

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")
        }
    }
}


  • +
  • -
  • 2


#704995 [Prośba]Napisanie prostego pluginu na dodawanie itemów po czasie.

Napisane przez skorpius w 04.07.2015 18:31

/* 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 plugin :P Nie testowałem.
Hahaheh to że dałeś Public z nazwą round_start nic ci nie da.

Nie dodałeś event;U który by uchwycić runde. Moim zdaniem JEŚLI zadziała to tak samo jak te wyżej tzn wejście na serwer, w co wątpię gdyż nie na tu plugin_init
  • +
  • -
  • 1