Skocz do zawartości
(◕‿◕)

Od Zera do PawnMastera

Rekomendowane odpowiedzi

Hej, zbliżają się wakacje, stary Od Zera do PawnMaster nie doznał swojego końca, gdyż było tam za dużo błędów składniowych, miejscami sam nie potrafiłem czegoś zrobić więc wklejałem z innych poradników, na szczęście są osoby które i tak na nim skorzystały. Jako iż mamy blisko wakacje, postanowiłem co tydzień dawać od nowa "Od Zera do PawnMastera", przejrzałem błędy które tam popełniłem i pragnę was poinformować, że w tej odnowionej wersji nie będzie na nich miejsca, ponadto pragnę was poinformować, że teraz każdy może pisać "Od Zera do PawnMastera", gdy skończę opisywać PAWN i technologie MySQL/SQLite zostanie w końcu kilka rzeczy nie omówionych, może jakaś biblioteczka nie opisana przez mnie? Może jakiś plugin? Kto wie, osoby zainteresowane po ukończeniu pisaniu przez mnie (czyli wydania ostatniej części) mogą napisać do mnie na PW, pisząc na jaki temat chcą napisać, a potem wstawiają go tutaj. Tak więc wszystkie poradniki będą zamieszczane tutaj, zabrania się ich kopiowania bez zgody autora danej części.
 
Taki tekst oznacza nowy poddział

Taki oznacza nową część poradnika

 

Cytaty, czyli źródła z innych stron
Różnej maści kody
 

Od Zera do PawnMastera - Podstawy podstaw

Nie przedłużając ani chwili dłużej, pobierzemy PAWNO, ale zanim to zrobimy musimy powiedzieć, co to, tak naprawdę jest. Zakładam z góry, że nikt z was nigdy nie miał styczności z programowaniem, więc nie ma bladego pojęcia co to IDE. Większość z was powiedziałaby, że PAWNO to edytor skryptów do SA-MP'a, ale czy edytor skryptów to nie jest też edytor tekstu? Jakby tak się zastanowić to tak jest, IDE to środowisko programisty, czyli edytor kodu wzbogacony o różne duperele, na przykład o kolorowanie składni. Dużo nowych pojęć na początek, bo co to składnia? Składnia to... póki co zostańmy przy tym, że składnia to tekst. Można by powiedzieć, że IDE to może być notatnik, ale jakoś dziwnie pisze się skrypty do gry w notatniku prawda? I czegoś mu brak, otóż IDE, czyli edytor kodu, musi coś z tym kodem zrobić, przetworzyć go tak, żeby komputer go zrozumiał i wyświetlił to co chcemy, a jak to się dzieje, że zwykły edytor tekstu może czynić takie cuda? Ba, nie może, pomaga mu w tym kompilator, w PAWNO zwie się on PawnCC, jest taki plik w folderze z naszym IDE, z rozszerzeniem (dla Windowsa) DLL. Czyli Ty, jako programista-amator piszesz tekst, czyli kod, wciskasz F5, uruchamia się kompilator i kompiluje twój kod, czyli przetwarza tekst na język zrozumiały dla komputera i tak powstaje nasz plik z rozszerzeniem AMX, taki plik możemy śmiało wpakować do odpowiedniego folderu i cieszyć się grą. Proste, prawda? Niestety rzeczywistość jest ponura, bowiem kompilator zawsze gdy coś zepsujemy "wrzuca swoje trzy grosze" i wyrzuca nam przykre informacje o tym, że popełniliśmy w tej linijce i tej, taki i taki błąd. Druga przykra informacja, kompilator czasem się pomyli z numerami linijek gdzie coś sknociliśmy i wprowadza nas w błąd, dlatego nie należy szukać błędu w linijkach gdzie nam mówi kompilator, a kilka linijek wyżej, niżej.
 
Skoro już wiemy co to IDE, co robi dla nas kompilator, co to kompilacja możemy pobrać twoje (może) pierwsze IDE i cieszyć się tymi wszystkimi kontrolerkami, które w rzeczywistości nam się nie przydają :)
 
Wiele osób uważa, że Notepad++ odpowiednio skonfigurowany jest lepszy od PAWNO, nie podważam ich zdania, może mają nawet trochę racji, ponieważ PAWNO jest stare i w tym czasie wyszło dużo innych IDE które też przetworzą nasz kod do pliku AMX, ja jednak zostaję przy starym PAWNO.
 
Ciągle pisze o tym PAWNO, a nawet nie powiedziałem skąd je wyczarować, prawda? Wystarczy pobrać paczkę z serwerem ze strony SA-MP'a http://www.sa-mp.com/download.php mamy tam paczkę z serwerem dla Linuxa jak i dla Windowsa. Pobierz, wypakuj i twoja przygoda się zaczyna
 
Struktura
Gdy wypakowałeś paczkę z serwerem zapewne zauważyłeś kilka folderów i plików, a mianowicie filterscripts, gamemodes, include, npcmodes, pawno, plugins, scriptfiles, announce, samp-license, samp-npc, samp-server, server, server-readme. Ja omówię najważniejsze
 
Nas głównie interesuje folder pawno, jednak, żebyś wiedział co zrobić ze swoim plikiem AMX musisz skonfigurować swój serwer, a żeby to uczynić warto poznać strukturę folderów, żeby wiedzieć co z tym plikiem uczynić.
 
Zaczniemy od filterscripts, do tego folderu należy wrzucać wszystkie skrypty tzw. FS'y
 
Drugim folderem jest gamemodes, wrzucamy do niego wszystkie mapy tzw. GM'y
 
Potem mamy folder include, jest on tym samym czym folder include w Pawno, tyle, że zawiera biblioteki dla serwera, ale w głębi duszy nie potrzebujemy go, zostawiamy go z tym czym jest
 
W npcmodes wrzucamy skrypty botów, będzie o tym poddział gdy zajmiemy się poznawaniem funkcji botów
 
Folder pawno zawiera nasze IDE i biblioteki do niego w folderze include
 
Plugins to nic innego jak pluginy z których musi korzystać nasz serwer, aby odpalić naszego FS'a/GM'a
 
Potem mamy scriptfiles, na tym folderze operujemy, gdy np chcemy stworzyć nowy plik, wszystkie czynności które wykona nasz FS/GM wpływające na komputer, tj. mam tu namyśli takie jak zapisanie pliku (bo głównie tylko to się robi :D), jest on taką "bazą danych" w folderze, dla naszego FS'a/GM'a
 
Potem mamy samp-npc, dzięki temu plikowi włączamy naszych NPC, czyli botów, ale najpierw trzeba jakiegoś zrobić ;)
 
samp-server uruchamia nasz serwer na podstawie konfiguracji server.cfg
 
Otóż, wspomniałem o konfiguracji serwera, może od tego zaczniemy? Otwórz plik server.cfg, twoim oczom ukaże się coś takiego
 

echo Executing Server Config...
lanmode 0
rcon_password changeme
maxplayers 50
port 7777
hostname SA-MP 0.3 Server
gamemode0 grandlarc 1
filterscripts gl_actions gl_realtime gl_property gl_mapicon ls_mall ls_elevator attachments skinchanger vspawner
announce 0
query 1
chatlogging 0
weburl www.sa-mp.com
onfoot_rate 40
incar_rate 40
weapon_rate 40
stream_distance 300.0
stream_rate 1000
maxnpc 0
logtimeformat [%H:%M:%S]
Pełno opcji, omówię te, które powinny się interesować
Zaczniemy od lanmode, 0 - LAN wyłączony, 1 - włączony, tj. czy chcemy aby nasz serwer działał tylko w sieci LAN
 
Potem mamy rcon_password, jest to hasło RCON do administratora RCON, logujemy się do niego hasłem podanym tutaj, komendą /rcon login hasło, proszę nie zmieniaj go na razie, uczynimy to zaraz
 
maxplayers to ilość slotów, my ustawimy Sobie 100
 
port to port, dla przykładu gdy mamy adres ip 127.0.0.1:7777 to "7777" to port, a 127.0.0.1 to adres ip serwera
 
hostname to nazwa naszego serwera, nazwijmy swój serwer "Mój pierwszy serwer"
 
gamemode tutaj wpiszemy nazwę swojego GMa, zostańmy przy grandlarc, a co to ta jedynka? To czas po którym GM ma się zmienić, skoro jednak jest jeden GM, zostajemy przy 1
 
filterscripts to FS'y które ładujemy na serwer, usuńmy wszystkie
 
weburl to link do naszej strony www
 
stream_rate, stream_distance, incar_rate, weapon_rate, onfoot_rate, nie interesuje nas, służą one do określania czasu po jakim ma dojść do zaktualizowania paru dupereli, odsyłam do >> http://wiki.sa-mp.com/wiki/Server.cfg
 
maxnpc maksymalna ilość NPC na serwerze
 
logtimeformat to format czasu w konsoli serwera
 
Zapisujemy swój plik i włączamy serwer, a tu... Nic się nie dzieje!
 
Otwórzmy teraz nowy plik, który pojawił się po włączeniu serwera, mianowicie server_log
 
W pliku server_log zapisują się logi z naszego serwera, po jego wyłączeniu, możemy z niego sporo wyciągnąć, my jednak dowiemy się, dlaczego nasz serwer nie działa

 
----------
Loaded log file: "server_log.txt".
----------
 
SA-MP Dedicated Server
----------------------
v0.3z, ©2005-2014 SA-MP Team
 
[11:42:31] filterscripts = ""  (string)
[11:42:31] plugins = ""  (string)
[11:42:31] Error: Your password must be changed from the default password, please change it.
 
Widzimy w jakiej wersji nasz serwer będzie działał, jest to "0.3z" i jakie skrypty zostały wczytane (w naszym przypadku, żaden), jakie pluginy zostały wczytane (u nas żaden) i błąd. Informuje nas, że nie zmieniliśmy hasła RCON, otwórz znów plik server.cfg i zmień swoje hasło RCON, ja ustawiam Sobie na "haslo"
 
Ciach, w konsoli pojawia się trochę nowego tekstu

[11:45:35] Loaded 3 vehicles from: vehicles/trains.txt
[11:45:35] Loaded 3 vehicles from: vehicles/pilots.txt
[11:45:35] Loaded 15 vehicles from: vehicles/lv_law.txt
[11:45:35] Loaded 39 vehicles from: vehicles/lv_airport.txt
[11:45:35] Loaded 255 vehicles from: vehicles/lv_gen.txt
[11:45:35] Loaded 38 vehicles from: vehicles/sf_law.txt
[11:45:35] Loaded 35 vehicles from: vehicles/sf_airport.txt
[11:45:36] Loaded 353 vehicles from: vehicles/sf_gen.txt
[11:45:36] Loaded 24 vehicles from: vehicles/ls_law.txt
[11:45:36] Loaded 37 vehicles from: vehicles/ls_airport.txt
[11:45:36] Loaded 98 vehicles from: vehicles/ls_gen_inner.txt
[11:45:36] Loaded 389 vehicles from: vehicles/ls_gen_outer.txt
[11:45:36] Loaded 71 vehicles from: vehicles/whetstone.txt
[11:45:36] Loaded 168 vehicles from: vehicles/bone.txt
[11:45:36] Loaded 61 vehicles from: vehicles/flint.txt
[11:45:36] Loaded 96 vehicles from: vehicles/tierra.txt
[11:45:36] Loaded 96 vehicles from: vehicles/red_county.txt
[11:45:36] Total vehicles from files: 1781
[11:45:36] 
---------------------------------------
[11:45:36] Running Grand Larceny - by the SA-MP team
 
[11:45:36] ---------------------------------------
 
[11:45:36] Number of vehicle models: 173
 
Każde takie

Loaded [...] vehicles from: vehicle/[...]
Informuje nas ile pojazdów zostało załadowanych i gdzie, ale skąd są one wczytywane? A no z scriptfiles, jak mówiłem, jest to taka "baza danych" w folderze. Przyjrzyjmy się temu bliżej, otwórz folder scriptfiles, a następnie vehicles. Twoim oczom ukaże się parę plików, otwórzmy "trains". Zauważysz różne cyferki, są to różne dane dot. pojawiania pojazdów, akurat w "trains" pojawiamy pociągi, po znaku ";" mamy komentarz "LV passenger", programiści zostawili nam informacje, pociąg pojawi się w LV.
 
Serwer
Ostatnią rzeczą jaką dziś zrobimy jest sprawdzenie czy wszystko działa, odpal swój serwer, plik od SA-MP'a, "Add Server" i wpisz "localhost"
 

Dla dociekliwych "Co to localhost", odsyłam do wiki

 
Dołącz teraz do gry
 
Trafisz do "wybieralki", gdzie możesz wybrać miejsce spawnu, a potem wybierzesz skin i pojawisz się w mieście które wybrałeś
Możesz teraz spojrzeć na konsolę, ujrzysz tam informacje o tym, że gracz z takim i takim adresem IP dołączył do gry
 
Zaloguj się teraz na administratora RCON, czyli głównego administratora, logujesz się przy pomocy komendy

 

/rcon login hasło z pliku server.cfg
U mnie jest to

/rcon login haslo
 
Moje gratulacje, masz właśnie administratora RCON, co prawda, dla bezpieczeństwa nie używa się już administratora RCON z komendy /rcon login, ale to Twój domowy, pierwszy serwer, więc nie masz o co się martwić :)
 
W konsoli ujrzysz informację, że gracz o takim ID, takim nickiem zalogował się na RCON'a
 
Mowa, że RCON to główny administrator, ale kim byłby główny administrator bez żadnych możliwości?
 
Użyj teraz /rcon cmdlist, twoim oczom ukaże się długa lista komend, przescrolluj na początek listy
 
Nie zagłębiam się w tą listę, ponieważ i tak nikt z tych komend nie korzysta, robi się na to własne komendy, które tak na prawdę robią to samo, jeżeli bardzo interesuję Cię cała lista, odsyłam >> http://wiki.sa-mp.com/wiki/Advanced_Server_Controls
My do nich wrócimy, gdy będziemy musieli (a będziemy)
 
No cóż, zostaje mi tylko, pozdrowić i życzyć powodzenia, jak wspominałem co tydzień jeden poradnik
 
 
 
 
 
Edytowane przez __root__

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ja w tym poradniku nic nie widzę o programowaniu w pawn tylko o uruchomieniu serwera.

 

Racja ale zauważ że jeżeli ktoś chce się nauczyć programować przydałoby się by wiedział jak potem ten skrypt uruchomić :) tak więc chyba to jest taki wstęp do programowania i dobrze że coś tak obszernego powstało. Ode mnie autor dostaje lajka za to, że chciało mu się opisać w tak obszerny i dokładny sposób podstawy stawiania serwera. Gratuluję!

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Uczepiliście się go jak rzep psiego ogona...

Chłopak chcę pomóc osobom, które chcą się czegoś nauczyć.

W tym przypadku jak dobrze skonfigurować serwer (dobrze, że od tego zaczął, bo coraz częściej spotykam się z osobami, które tego nie potrafią dobrze zrobić). Do hejtowania każdy jest pierwszy, a do roboty to nie ma komu.

 

@topic :
Nic dodać, nic ująć ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Mam wrażenie że moda pisania tutorialów "Od Zera do PawnMastera" wywodzi się od forum SA:MP'a, gdzie takie poradniki zaczynają się i w sumie kończą na tym jak skonfigurować swój serwer.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Mam wrażenie że moda pisania tutorialów "Od Zera do PawnMastera" wywodzi się od forum SA:MP'a, gdzie takie poradniki zaczynają się i w sumie kończą na tym jak skonfigurować swój serwer.

Tyle że niestety to nie jest forum SAMPa a Pawno.pl.

 

Druga sprawa, dobra robota. Nie każdy wie jak od razu uruchomić serwer, początkującym się przyda. Like!

 

 

 

Chociaż formatowanie tekstu byś mógł tak "dodać" / zmienić. Bo tyle odstępów nawaliłeś...

Edytowane przez Wojtek020699

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Od Zera do PawnMastera - Programujmy!

Dzisiejszą część poradnika pragnę poświęcić podstawą programowania :)
Otwórz Pawno, wybierz z menu "File", "New"
 
Parę zasad, czyli podstawy
Twoim oczom ukaże się kod, ponad 300 linijek, to jest tak zwany "new" czyli to od czego pisze się GM'y pisane od niczego :D
Jeżeli jesteś uważny, zauważysz często powtarzane się słówko "public" i od wyjaśnienia czym ten "public" jest, zaczniemy
Public nazywamy często też callbackiem, w dalszej części poradnika będę używał określenia callback, ponieważ łatwiej odmienić go przez przypadki i osoby
 
Callback jest to wydarzenie, np gdy gracz wchodzi na serwer dochodzi do wydarzenia "OnPlayerConnect", kod który umieścimy w tym callbacku zostanie wykonany gdy gracz wejdzie na serwer. No dobrze, ale jak taki kod umieścić? My przyjmujemy, że piszemy FS'a, standardem jest, że każdy FS powinien mieć definicję "FILTERSCRIPT", zwyczajnie, jest ona zakomentowana, więc znajdź linijkę 
//#define FILTERSCRIPT
 
I podmień ją na
#define FILTERSCRIPT
Z pewnością dowiesz się co właśnie uczyniłeś, ale na razie, nie przejmuj się tym
 
Teraz gdy mamy naszą linijkę informującą, że piszemy skrypt, możemy przejść do wydarzenia "OnFilterScriptInit"
 
Ów wydarzenie wykonuje swój kod gdy skrypt jest ładowany, z pewnością u Ciebie wygląda to tak
public OnFilterScriptInit()
{
print("\n--------------------------------------");
print(" Blank Filterscript by your name here");
print("--------------------------------------\n");
return 1;
}
 
Co ten kod oznacza? Linijka po linijce
public OnFilterScriptInit()
Słówko "public" mówi, że jest to wydarzenie, a "OnFilterScriptInit" to nazwa wydarzenia, w nawiasach mamy zmienne jakie ów wydarzenie daje nam samo z Siebie, nam jednak nie daje żadnego, dlatego widzimy "()"
 
Potem mamy klamrę otwierającą, informuje ona, że od niej, aż do klamry zamykającej znajduje się kod, w tym przypadku, że ten kod należy, w tym przypadku do wydarzenia "OnFilterScriptInit"
 
No dobrze, ale między klamrami mamy
print("\n--------------------------------------");
print(" Blank Filterscript by your name here");
print("--------------------------------------\n");
return 1;
 
To jest właśnie kod, widzimy tu funkcję "print", jako iż zależy mi, aby każdy umiał posługiwać się dokumentacją, zajrzyj http://wiki.sa-mp.com/wiki/Category:Scripting_Functions i znajdź funkcję "print". Mamy opis funkcji 

 

Prints a string to the server console (not in-game chat) and logs (server_log.txt).

 

Na polski, funkcja wypisuje w konsoli napis który jej podamy i zapisuje go w logach server_log.txt
 
Potem mamy

 

Parameters:

string[] The string to print

 

 
Co to znaczy? Są to parametry, czyli argumenty naszej funkcji, ta funkcja ma jeden argument, o nazwie string jest to tekst
 
Na końcu mamy 

 

This function does not return any specific values.

 

Jak samo zdanie wskazuje, funkcja nie zwraca żadnej specyficznej wartości, a o co chodzi z tym zwracaniem? Funkcje mogą zwracać różne wartości, np gdy jakaś funkcja coś pobiera, to najczęściej zwraca pobraną wartość
 
Dobrze, skoro wiemy, co mówi nasza dokumentacja, wróćmy do 
print("\n--------------------------------------");
print(" Blank Filterscript by your name here");
print("--------------------------------------\n");
 
Widzimy tu funkcję "print" która bierze od nas tekst, a gdzie ten tekst podać?
Mamy otwarcie nawiasu "(" potem "\n", po otworzeniu nawiasu mamy cudzysłów ", na końcu drugi, między cudzysłowy dajemy tekst, potem zamykamy nawias i średnik. Jeżeli się przyjrzysz w programowaniu prawie każdą linijkę kończymy średnikiem, póki co znamy już jeden wyjątek, linijkę z nazwą wydarzenia nie kończymy średnikiem.
W skrócie, między nawiasy dajemy parametry dla funkcji, funkcję kończymy średnikiem, jeżeli funkcja potrzebuje od nas tekstu, dajemy go między cudzysłowy. Ostatnią rzeczą którą warto tu omówić jest "\n", gdy użyjemy "\n" w tekście (nie każda funkcja "przetrawi" nasze "\n") zaczyna się nowa linia. Zostało nam 
return 1;
Każde wydarzenie musi zwrócić 1, return zwraca dowolną wartość, jaką mu podamy, a gdy zwraca 1, informuje, że callback wykonał się poprawnie i nie ma błędów. Usuń teraz print'y i wstaw własny tekst :)
 
Zmienne
Skoro wiesz już jakie są zasady programowania, warto omówić zmienne, ale co to jest? Są różne definicje zmiennych, mi najbardziej pasuje, słoiczek, możesz do niego coś włożyć, coś wyjąć, coś dorzucić, coś ująć, coś powiększyć o X razy, coś zmniejszyć o X razy. 
 
A jak je tworzymy? To proste "new" i nazwa słoiczka, np
new zmienna;
Pamiętając, że po praktycznie wszystkich linijkach dajemy średnik
A jak z nazwami? Może się tam znaleźć cyfra, litera, lub znak specjalny, ale nie może się zaczynać od znaków specjalnych i cyfr (wyjątkiem tutaj jest _)
 
Przejdźmy do działania na słoiczkach, dajmy mu wartość 5 (póki co ograniczymy się do liczb całkowitych)
zmienna = 5;
znakiem "=" przypisujemy naszej zmiennej wartość
 
Ale możemy też dać mu wartość od razu po stworzeniu, w tej samej linijce
new zmienna = 5;
Możemy utworzyć kilka zmiennych
new zmienna1;
new zmienna2;
new zmienna3;
I zrobić to w ładniejszy (stylistycznie) sposób, wszystko w jednej linijce 
new zmienna1, zmienna2, zmienna3;
Jak widzisz, kolejne zmienne oddzielamy tylko przecinkami
 
Możemy utworzyć kilka zmiennych i nadać im wartości w tej samej linijce
new zmienna1 = 5, zmienna2 = 3, zmienna3 = 2;
 
Możemy też posłużyć się o ciekawsze kombinacje, otóż, gdy używamy nazwy zmiennej preprocessor wstawia za nazwę jej wartość, więc możemy zrobić np
new zmienna1, zmienna2 = 3, zmienna3 = 2;
zmienna1 = zmienna3;
 
Teraz zmienna1 ma wartość zmienna3 czyli 2
new zmienna1 = zmienna3, zmienna2 = 3, zmienna3 = 2;
Taka kombinacja kończy się wypadkiem 

 

 

error 017: undefined symbol "zmienna3"

 

Dlaczego? Ano tworzysz zmienna1 i dajesz jej wartość zmienna3, ale zmienna3 tworzysz po zmienna1, więc podczas tworzenia zmienna1, zmienna3 nie istnieje, więc kompilator nie może jej znaleźć
Wystarczy zmienić kolejność
new zmienna3 = 2, zmienna2 = 3, zmienna1 = zmienna3;
 
Dalej pominę pokazywanie, że można robić wszystko to w tej samej linijce, ponieważ, najzwyczajniej w świecie można, pominę tworzenie trzech zmiennych, możesz je usunąć, będziemy pracować na zmiennej zmienna, utwórz więc ją i nadaj jej wartość 1000
 
Teraz pora na działania na zmiennych, najprostszym z nich jest dodawanie
zmienna = zmienna + 500;
Po prostu powiększamy zmienną zmienna o 500
 
Odejmowanie
zmienna = zmienna - 500;
Teraz zmniejszamy
 
I się zatrzymajmy, jest ułatwienie dodawania i odejmowania wartości ze zmiennych symbolami += (dodawanie) i -= (odejmowanie)
Czyli
zmienna += 500;
 
To nic innego jak
zmienna = zmienna + 500;
 
A
zmienna -= 500;
 
To
zmienna = zmienna - 500;
 
Teraz mnożenie
zmienna = zmienna * 2;
Mnożymy powiększamy zmienną dwukrotnie, lub, np
 
zmienna *= 20;
Dwudziestokrotnie
 
Dzielimy
zmienna /= 2;
Przez dwa, lub przez
zmienna = zmienna / 10;
dziesięć
 
No i jeszcze jedno, możemy mieć resztę z dzielenia, podczas dzielenia znakiem "/" zostanie ona ucięta, żeby ją zatrzymać użyjemy modulo "%"
zmienna %= 2;
 
Teraz zostało do omówienia, że mamy kilka typów danych

 

 

String - Tekst (np "Jajko")

Integer (Int) - liczba całkowita (np 245)
Float - liczba zmiennoprzecinkowa (np 2.67)
Bool - Prawda/Fałsz (czyli może mieć wartość true, lub false)
Array - Tablica (na to poświęcimy Sobie oddzielny rozdział)
 
 
Jak tworzymy stringa? 
new string[rozmiar];
 
np
new string[256];
256 czyli rozmiar to, to ile znaków zmieści
Tekst dajemy w cudzysłowach np
string = "Cebulka i pomidor";
 
Float? To liczba zmiennoprzecinkowa, oczywiście, działania matematyczne na niej jak na Integer, ale ona w przypadku reszty z dzielenia modulo, nie potrąci jej 
 
new Float:liczba = 0.9;
Słówko, Float, oznacza, jak nazwa wskazuje, że to Float 
 
bool czyli prawda/fałsz, np
new bool:prawda = true;
new bool:falsz = false;
A Array? Zapraszam do kolejnego rozdziału
 
Tablice
Czasem może się zdarzyć, że chcemy zapisać kilka wartości, różnych wartości, możemy się poratować wtedy tablicami i ułatwić Sobie pracę
 
Tablicę tworzymy w następujący sposób
new nazwa[rozmiar];
Czyli tak jak String'a. A jak przypisujemy wartość do tablicy? Podajemy indeks w rozmiarze pola do którego chcemy przypisać daną wartość. Utwórz tablicę o nazwie tablica, o rozmiarze 3.
 
Przykładowe przypisanie wartości to nic innego jak
tablica[2] = 3;
Przypisz do każdego indeksu jakąś wartość
 
Nie wiem, bo jasnowidzem nie jestem, jakie wartości podałeś, ale zgaduję (ręki uciąć Sobie nie dam), że tak wygląda twoje przypisanie
new tablica[3];
tablica[1] = Integer;
tablica[2] = Integer;
tablica[3] = Integer;
Za Integer oczywiście jakaś liczba całkowita.
No i masz... 

 

error 032: array index out of bounds (variable "tablica")
 
Co ten błąd znaczy? Utworzyłeś tablicę o rozmiarze 3, a podałeś w linijce
tablica[3] = 9;
indeks 4, nie będę dalej kręcił, w programowaniu liczymy od zera.
Czyli gdy podajesz indeks 1, to tak na prawdę (licząc jak na programistę przystało) jest to indeks 2, więc indeks 3 to indeks 4, a nasza tablica ma rozmiar 3
 
Jeżeli tak nie miałeś i znałeś tą zasadę, zaoszczędziłeś Sobie czasu
 
Chciałbym zwrócić uwagę, że nadal, na tablicy również możesz dodawać, odejmować, mnożyć, dzielić
Powykonuj teraz parę działań na tablicach, powiększ tablicę o indeksie 0 o tablicę o indeksie 1
Potem tablicę o indeksie 1 zmniejsz o tablicę o indeksie 2
Tablicę o indeksie 2 pomnóż przez tablicę o indeksie 0
A na końcu tablicę o indeksie 0, podziel przez tablicę o indeksie 1
Skorzystaj z najkrótszego możliwego zapisu
 
Gdy skończysz porównajmy cały kod razem z tworzeniem i przypisywaniem wartości 

new tablica[3];
tablica[0] = 3;
tablica[1] = 5;
tablica[2] = 7;
tablica[0] += tablica[1];
tablica[1] -= tablica[2];
tablica[2] *= tablica[0];
tablica[0] /= tablica[1];
Oczywiście, wartości mogą być twoje

 

 
Tablice mogą być różnego typu i tworzymy różne typy jak w przypadku zmiennych
 
Utwórz tablicę o rozmiarze 3 typu Float o nazwie tablica2

new Float:tablica2[3];

I przypisz znów każdemu indeksowi jakąś wartość

new Float:tablica2[3];
tablica2[0] = 2.3;
tablica2[1] = 24.6;
tablica2[2] = 98.99;

Oczywiście, znów możesz wykonywać wszelkie działania matematyczne
 
 
Tablica może być też bool, utwórz taką, nadaj jej rozmiar 3 i jakieś wartości indeksom

tablica3[0] = true;
tablica3[1] = false;
tablica3[2] = false;

 
Do tablicy możemy przypisywać wartości też w prostszy sposób
new tal[10];
tal = {2, 575, 686, 72, 8, 9, 830, 96, 409, 57};
Nadajemy kolejnym indeksom od zera podane wartości
To tak samo jakby
tal[0] = 2;
tal[1] = 575;
tal[2] = 686;
tal[3] = 72;
tal[4] = 8;
tal[5] = 830;
tal[6] = 96;
tal[7] = 409;
tal[8] = 57;
Ale pierwszy zapis jest prostszy i szybszy 
 
Istnieją jeszcze tablice dwu i trzywymiarowe najczęściej spotykamy dwuwymiarowe, w przypadku gdy utworzymy tablicę czterowymiarową, dostaniemy smutne "3 grosze od kompilatora"
 
error 053: exceeding maximum number of dimension

 

Standardowo dojdą do tego jeszcze 3 inne błędy, ale o źródle problemu informuje nas ten błąd
A jak tworzymy te tablice dwuwymiarowe? To proste
new nazwa[rozmiar1][rozmiar2]
Np
new tablicainna[3][3];
A co oznacza, że tablica jest dwuwymiarowa? Mamy po 3 indeksy na "wymiar, czyli np
tablicainna[0][0] = 67;
Przypisujemy do indeksu 0, wymiaru 0 wartość 67
Możemy w ten sposób z 3 indeksów mieć ich 9 (3 indeksy na wymiar, 3 wymiary 3*3 = 9)
Oczywiście i na tych tablicach mamy swoje ulubione działania
Przypisz do wszystkich indeksów jakieś liczby

tablicainna[0][0] = 56;
tablicainna[0][1] = 52;
tablicainna[0][2] = 112;
tablicainna[1][0] = 986;
tablicainna[1][1] = 234;
tablicainna[1][2] = 0;
tablicainna[2][0] = 78;
tablicainna[2][1] = 88;
tablicainna[2][2] = 134;

No dobrze, ale jeszcze nie dawno pokazałem szybszy i wygodniejszy (przynajmniej tak mi się wydaje) sposób na wypisywanie danych do tablicy, czy to znaczy, że w tablicach dwuwymiarowych i trzywymiarowych on nie istnieje? 
Otóż, istnieje
nazwa[wymiar] = { wartości };
 
Np
tablicainna[0] = {4, 5, 5};
 
Do tablic wielowymiarowych możemy również przypisać stringa, np
new stringtab[2][5];
stringtab[0] = "Ala";
stringtab[1] = "Kot";
 
I chyba tu możemy skończyć nasze tablice wielowymiarowe :)
Standardowo może być to Float, Integer, bool lub String
 
Stałe
Były tablice, zmienne, a co ze stałymi?
 
Stałe to również "słoiczki", ale im możemy nadać wartość przy tworzeniu i tyle, nie możemy odejmować, dodawać, mnożyć, dzielić, przypisywać nowych wartości, tworzymy je
const nazwa = wartosc;
 
Może to być float, int lub bool
const stala = 50;
const Float:f = 5.8;
const bool:b = true;
 
Wszystkie funkcje print i printf dawaj na razie w callbacku OnFilterScriptInit(), później odpal tylko swój skrypt
Komentarze
Na koniec zostawiłem najprostsze dwa tematy, pierwszym z nich są komentarze
 
Komentarze to tekst nie interpetowany przez kompilator, po prostu, on pomija komentarze, jest to świetny sposób na schowanie przed kompilatorem tymczasowo jakiś linijek kodu, zaznaczenie Sobie w kodzie jakiś ważnych informacji, czy też po prostu fajne podpisanie swojego kodu 
 
/* "   "       ""             "      "  "  "
"  "       "  "           " "    ""  "  "
""        "    "         "   "  " "  "  "
""       """"""""       "     ""  "  "  "
" "     "        "     "      ""  "  "  "
"  "   "          "   "       ""  "  "  "
"   " "            " "            "  "  """""""
 
*/
Ahh, nie jestem w tym dobry :/
 
Ale dobrze, od początku, mamy dwa typy komentarzy
 
- Jednoliniowe
- Blokowe
 
Komentarze jednoliniowe zaczynają się od "//" i kończą na końcu linijki, a komentarze blokowe zaczynają się od "/*", a kończą na "*/", prawda, że proste?
 
print(/*Komentarz*/"/* Komentarz */ - jednak nie :<"); //Otrzymamy "/* Komentarz */ - jednak nie :<"
W poniższym kodzie komentarz zaczyna się przed tekstem do wysłania, a w tekście do wysłania wstawiłem "/* Komentarz */ - jednak nie :<", ponieważ wszystko między "" jest interpetowane jako tekst, nasz komentarz wstawiony tam nie został potraktowany z należytym mu "szacunkiem" ;)
I tą nowiną żegnamy komentarze
 
Printowanie
To taki bonusik ode mnie. Czasem zdarzy się, że będziesz chciał sprawdzić jaką wartość ma jakaś zmienna lub co zwraca jakaś funkcja podczas gry, z pewnością będiesz kombinował i tak kombinował i kombinował, ale po co? Pragnę przedstawić Ci dwa proste sposoby "debugowania" wybranych funkcji i zmiennych (tak na prawdę printujemy je tylko w konsoli), zaoszczędzisz Sobie dzięki temu czas, ale pamiętaj, że na serwerze produkcyjnym takim debugowniem zaśmiecisz Sobie konsolę
Skoro wiesz czym się zajmiemy, znajdź na wiki funkcję printf, jest to z pewnością prostszy sposób od drugiego
 
Funkcja ta działa jak print, ale pozwala używać formatowania, mamy następujące typy 

 

 

%i/%d = Integer

%s = String
%c = ASCII
%b = Binar
%f = float
%x = hex

 

A jak to działa? Np gdy zmienna jest typu Integer, używamy %d wtedy funkcja wyprintuje nam jej wartość, gdy to string używamy %s, gdy ASCII to %c, gdy float to %f itd.
 
Utwórz teraz zmienną typu Float, Integer, String i jakąś tablicę o 3 indeksach i nadaj im wartości

new integer = 98, string[15] = "Jan Cebulka", Float:f = 67.89, array[3] = {2, 6, 7};

Jak to wygląda w praktyce?
printf("integer = %d\nstring = %s\nFloat = %f\nArray[0] = %d\nArray[1] = %d\nArray[2] = %d", integer, string, f, array[0], array[1], array[2]); 
Co my tu robimy? Tak jak pisałem, za %d wstawiamy wartość Int za %s stringa za %f Float, wartości są przypisywane od lewej strony do prawej
 
Odpal, w konsoli zobaczysz coś mniej więcej takiego 

 

 

[18:16:46] integer = 98

string = Jan Cebulka
Float = 67.889999
Array[0] = 2
Array[1] = 6
Array[2] = 7
 
Widzisz? Wartości twoich zmiennych (ja akurat pokazuję swoich :D)
 
No dobra, ale jest jeszcze drugi sposób, znajdź funkcję format w dokumentacji
Jak ona działa? Pozwala sformatować nasz tekst do stringa, utwórz więc pustego stringa

new string[256];

I teraz zajmiemy się formatowaniem, funkcja bierze od nas stringa do którego chcemy wrzucić sformatowany tekst i jego rozmiar, my użyjemy funkcji sizeof, która pobiera rozmiar stringa za nas, przyjmuje ona jeden argument, mianowicie stringa którego rozmiar ma podać
 
Zanim zaczniemy, utwórz zmienną i nadaj jej wartość 259, jest to symbol z tablicy ASCII
Spróbuj sam użyć funkcji format

format(string, sizeof(string), "Format:\nASCII = %c", ascii);

 
Potem już tylko
print(string);
I naszym oczom ukaże się serduszko
Edytowane przez __root__

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Nie czytałem całości bo nie wiedzę takiej potrzeby :P ale na sam początek rzuciło mi się w oczy "OnPlayerJoin" :) popraw to xD

 

Za poradnik oczywiście like!

Edytowane przez lnferno

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Od Zera do PawnMastera - Składnia i preprocessor

 
Dziś zajmiemy się składnią PAWN i preprocessorem, standardowo każdego printa i printf wstawimy w OnFilterScriptInit() i sprawdzamy czy działa
 
Instrukcja warunkowa - if
Z pewnością nie raz będziesz potrzebował sprawdzić czy jakaś zmienna ma jakąś tam wartość, dlatego właśnie mamy if (pl. jeśli), jego użycie jest proste i wygodne
 
if(warunek) 
{ 
//kod
} 
 
 
A co za warunek? Poniżej wstawiam listę znaków których możemy dodać do warunku
 
 

wartośćA == wartośćB Kod wykona się gdy wartośćA będzie równa wartośćB
wartośćA > wartośćB Kod wykona się gdy wartośćA będzie większa od wartośćB
wartośćA < wartośćB Kod wykona się gdy wartośćA będzie mniejsza od wartośćB
wartośćA != wartośćB Kod wykona się gdy wartośćA będzie inna niż wartośćB
wartośćA >= wartośćB Kod wykona się gdy wartośćA będzie większa lub równa wartośćB
wartośćA <= wartośćB Kod wykona się gdy wartośćA będzie mniejsza lub równa wartośćB

 

 
 
Utwórz dwie zmienne wartoscA i wartoscB nadaj im jakieś wartości Integer
Teraz utworzymy if'a
 
if(wartoscA  == wartoscB) 
{ 
print("if wykonał się"); 
} 
 
Jeśli twoje zmienne miały takie same wartości, otrzymasz informację w konsoli "if wykonał się"
 
if(wartoscA > wartoscB) 
{ 
print("if wykonał się"); 
} 
 
Jeśli wartoscA była większa od wartoscB if wykona się
 
if(wartoscA < wartoscB) 
{ 
print("if wykonał się"); 
} 
 
Jeśli wartoscA była mniejsza od wartoscB if wykona się
 
Zrób teraz sam, analogicznie warunki wykorzystując symbolę != >= i <=


1.
if(wartoscA >= wartoscB) 
{     
print("if wykonał się"); 
} 
2.
if(wartoscA <= wartoscB) 
{ 
print("if wykonał się"); 
} 
3.
if(wartoscA  != wartoscB) 
{ 
print("if wykonał się"); 
} 
 


Utwórz teraz trzy zmienne string o wartości "Kot", bool o wartości true i Float o wartości 34.56
 
Porównaj zmienną string do tekstu "Ala ma kota", bool'a do wartości true, a Float'a do wartości 78.98
 
W przypadku porównania string'a do tekstu "Ala ma kota" otrzymamy błąd
 
 

error 033: array must be indexed (variable "str")

 

 
Ponieważ dwa stringi (tekst to też string) nie porównuje się w ten sposób, mamy do tego funckję strcmp
Znajdź ją na wiki, jak widzisz, ma ona 4 argumenty, dwa wymagane, pierwszy argument to string do porównania, drugi to drugi string do porównania, trzeci to wartość bool, czy wielkość liter ma znaczenie, czwarty to rozmiar stringa do porównania, my wykorzystamy trzy argumenty, funkcja zwraca fałsz (0/false) gdy dwa stringi są takie same
 
if(strcmp(str, "Ala ma Kota", true) == 0) 
{ 
print("Kot = Kot;"); 
} 
 
Po odpaleniu takiego kodu nie dostaniemy, nic (mam na myśli print'a), chyba że zmienna str, ma wartość "Ala ma Kota"
Trzeci argument jak i czwarty jest opcjonalny, nie musimy ich podawać, trzeci przyjmuje wartość false, więc jeślichcemy aby "kot" nie był tym samym co "Kot" nie musimy podawać trzeciego argumentu :)
Wróćmy jednak do
 
if(strcmp(str, "Ala ma Kota", true) == 0) 
{ 
print("Kot = Kot;"); 
} 
 
Użyliśmy tu "==" aby sprawdzić czy funkcja zwraca fałsz (inaczej zero lub false)
Jest na to łatwiejszy sposób, przed funkcją wystarczy wstawić operatora "!" wtedy wykona if gdy funkcja zwróci fałsz, a my pominiemy "== 0"
 
if(!strcmp(str, "Ala ma Kota", true)) { print("Kot = Kot;"); } 
 
I to chyba na tyle, a gdy chcemy sprawdzić czy funkcja zwraca prawdę, usuń po prostu operatora "!"
 
Prawdopodobnie porównałeś bool'a w ten sposób
 
if(b == true) 
{ 
print("b = true;"); 
} 
Tu również możesz zrobić jak w przypadku funkcji
 
if(b) 
{ 
print("b = true;"); 
} 
 
A porównywanie float'a to nic innego niż 
 
if(f == 78.98) 
{ 
print("f = 78.98;");
} 
 
 
else i else if
else wykonuje się gdy warunek if'a nie zostanie spełniony, wróćmy do
 
if(f == 78.98) 
{ 
print("f = 78.98"); 
} 
 
else w tym przypadku to nic innego niż
 
if(f == 78.98) 
{ 
print("f = 78.98"); 
} 
else 
{ 
printf("f = %d", f); 
} 
 
 
A else if? Wykona się gdy warunek if'a nie zostanie spełniony, ale jego warunek zostanie
 
if(f == 78.98) 
{ 
print("f = 78.98"); 
} 
else if(f == 34.56) 
{ 
print("f = 34.56"); 
} 
else 
{ 
printf("Hmmm nie wiem :C, może tak?\nf = %f", f); 
}
 
Teraz dostaniemy "f = 34.56", możesz zamienić wartość f na 1.98, w konsoli dostaniesz

[15:22:17] Hmmm nie wiem :C, może tak?
f = 1.980000

 

 
Wychodzi to trochę po za temat else if'a, ale mamy problem, a jak go rozwiązać? Otóż gdy dajemy %d, %f, %i, możemy swoją wartość zaokrąglić, potraktować ciut inaczej. W przypadku %f możemy określić do ilu miejsc po przecinku chcemy aby nasza wartość była pokazywana, wystarczy, że po % damy np 0.2, wtedy nasza liczba będzie ucięta do dwóch miejsc po przecinku, możemy też otrzymać taki format
 

f = 01.980000

 
Dodając zamiast 0.2 po prostu 2, wtedy 1 zostanie pokazane w formacie dwóch liczb
 
Pętla warunkowa for
Czym jest pętla? Pętla powtarza jakiś kod, np pętla for powtarza jakiś kod dopóki jej warunek nie zostanie spełniony
 
for(wartość początkowa; warunek kończący; edytujemy wartość początkową)
{ 
//kod 
} 
 
W "wartość początkowa" możemy utworzyć nową zmienną lub użyć już istniejącą, Ty utwórz zmienną i i nadaj jej wartość 0, potem warunek który musi się spełnić, żeby pętla się skończyła, a na końcu coś czym będziemy zmieniać swoją zmienną, my chcemy odliczać do dziesięciu więc powiększymy ją o 1 co każde wykonanie kodu, powiększanie lub zmniejszanie zmiennych o 1 było częste, więc powstał sposób "zmienna++" i "zmienna--" możemy tak powiększać lub zmniejszać zmienną o 1


Nasza pętla :)
 
for(new i = 0; i < 10; i++) 
{ 
printf("Wielkie odliczanie: %d", i); 
} 
 

w
Aczkolwiek, nasza pętla wykona się 9 razy, wystarczy zmienić warunek, na "gdy 10 będzie większe lub równe i"
 

i <= 10
 
Pętla może też być nieskończona, ponieważ nie musimy podawać nic, wystarczy dać ;;
 
new i; 
for(; 
{ 
i++; 
printf("Wielkie odliczanie: %d", i); 
} 
 
Nasza pętla będzie teraz wykonywać się w nieskończoność, wielkie odliczanie będzie bez końca
Ułatwimy jednak Sobie życie i nasza "nieskończona pętla" skończy się na 9, z pomocą przychodzi nam "break", gdy go użyjemy pętla zakończy się


new i; 
for(; 
{ 
i++; 
if(i == 10) 
{ 
break; 
} 
printf("Wielkie odliczanie: %d", i); 
} 


Możemy też przeskoczyć np liczbę 10, wstawiając continue


 
new i; 
for(; 
{ 
i++; 
if(i == 10) 
{ 
continue; 
} 
printf("Wielkie odliczanie: %d", i); 
}
 


Teraz po 9 będzie liczba 11. Ale dobrze już koniec z zamulaniem komputera, 
 
Raczej odliczanie, to np od 10 do 0, prawda? Zmień kod tak, żeby odliczało od 10 do 0 ;)


 
 for(new i = 10; i >= 0; i--) 
{    
printf("Wielkie odliczanie: %d", i); 
}


 
Pętla while
Kolejną pętlą jaką poznamy jest pętla while, różni się trochę od for 
 
Pętla while otrzymuje po prostu kod który ma wykonywać dopóki jej warunek  kest spełniony, niestety tu nie możemy utworzyć w warunku zmiennej, musimy to zrobić przed pętlą
 

while(warunek) 
{    
//kod 
}
 
 
Np
 new i = 0;
while(i <= 98) 
{    
i++;    
printf("%d", i); 
}
Pętla ta wykonuje swój kod dopóki warunek zostanie spełniony 
Warto tu jeszcze dodać, że pętla ta gdy ma spełniony warunek, to nie zatrzyma się, dokończy okrążenie i dopiero się skończy. Ale my znamy "break" i "continue" wystarczy więc dodać 
if(i == 98)
{   
break;
}
 
I gotowe, pętla skończy się na 98!
 
Chciałbym jeszcze wyjść na chwilę po za temat pętli while i powiedzieć coś o warunków składających się z kilku warunków :D

A || B - Warunek A lub B jest prawdziwy
A && B - Warunek A i B jest prawdziwy

 
Np
new i = 0;
new bool:a = true; 
while(i <= 98 || a) 
{    
i++;    
printf("%d", i);   
if(i == 23)   
{     
a = false;   
}    
}
Teraz nasza pętla zatrzyma się za 23 razem
 
Pętla do...while
Powoli zbliżamy się do końca :)
Teraz trochę o pętli do...while ów pętla wykona się zawsze przynajmniej raz, a kończy się gdy jej warunek jest fałszywy
do
{
//kod
}
while(warunek);
np
new i = 3;
do
{   
printf("i = %d", i);   
i--;
}
while(i > 0);
Krótko i na temat, kod wykona się 3 razy, mamy swoje odliczanie :)
 
Enum
Enum to typ wyliczeniowy, dajemy go za callbackami
enum enum_
{
a = 0,
b = 1,
c = 2
};
Teraz tak jakbyś utworzył trzy zmienne typu int, a, b i c, każda z nich ma swoją wartość liczbową, a jest równe 0, b równe 1, a c równe 2, proste, prawda?
Możesz przypisać tego enuma pod zmienną podając go jako rozmiar
ab[enum_];
A potem użycie
ab[a];
Upewnijmy się, że a jest równe 0, b jest równe 1, a c jest równe 2
printf("ab[a] = %d\nab[b] = %d\nab[c] = %d", ab[a], ab[b], ab[c]);
Jak widzisz, szybkim sposobem utworzyłeś trzy zmienne, możesz tworzyć tak też zmienne typu Float, String, bool
enum enum_
{a,
Float:b,
c[40],
bool:d
};
Proste, prawda?
 
Preprocessor i dyrektywy
Mówiłem, że kompilator nie czyta twój kod tak jak Ty go podasz, najpierw preprocessor robi swoje, to on wstawia za zmienne ich wartości, kompilator taki kod
new i = 3;
print(i);
Otrzymuje w sposób
print(3);
I to jest rola preprocessora
Lub
new a[25] = "Mleko";
/* O tą linijkę chodzi*/ printf("%s', a);
Dostaje
printf("%s', "Mleko");
I tyle dobrze wiedzieć.
 
Mamy jeszcze dyrektywy preprocessora, trochę ich jest, ale są one proste więc tylko chwilę o nich porozmawiamy
 
#define pozwala definiować coś, coś jak stałe, nie można tego zmieniać, ani się tym w żaden sposób dodawać, odejmować, dzielić itd.
#define A 6
//A w kodzie
printf("%d", A);
Oczywiście może też być np string czy Float
#define S "Mleczko CIF"
#define F 56.87 
/*-------A POTEM---------*/
printf("%s", S);
printf("%f", F);
Zauważ, że po dyrektywach nie ma średnika, nie ma też przecinków czy nawiasów
 
#assert
assert działa jak if, tyle, że jeśli warunek assert się nie spełni, od razu wywali nam błąd
#define X 98
#assert X == 9
Dostaniemy
 
 

fatal error 110: assertion failed: 98 == 9
 Compilation aborted.Pawn compiler 3.2.3664

 

 
 
Mamy też #if #else i #elseif no i #error do naszych własnych błędów
#define K 78
#if K == 87
#error ":c"
#endif
Dostaniemy
 

fatal error 111: user error: ":c"

 

Inne użycie
#define K 874
#if K == 87
#error ":c"
#elseif K > 777
#error "K > 777"
#endif
#include to kolejna dyrektywa, pozwala nam na dołączanie bibliotek i ich funkcji z "include" w twoim folderze z Pawno
Podstawową biblioteką jest a_samp, należy ją dodawać przed wszystkimi innymi
#include <a_samp>
Mamy też np ZCMD, sscanf itd. Ale o tym niebawem
I chyba tyle, jeśli chodzi o ten materiał, ufff! Edytowane przez __root__

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×