Wstęp do pisania skryptów: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
(IDE list update, grammar improvement.)
m (Added language references and changed article a little bit)
 
Line 1: Line 1:
Zasoby są kluczową częścią MTA. Najprościej rzecz ujmując, zasób to folder lub plik .zip, który zawiera zbiór plików, oraz dodatkowo plik meta, który opisuje serwerowi jak zasób powinien być ładowany i jakie pliki zawiera. Zasób w MTA, w przełożeniu na bardziej znane środowisko systemu operacyjnego, odpowiada programowi lub usłudze (sys. Windows), działającego pod jego kontrolą - mogą być uruchamiane i zatrzymywane, przy czym wiele z nich może działać jednocześnie (multitasking).
Zasoby są kluczową częścią MTA. Najprościej rzecz ujmując, zasób to folder lub plik .zip, który zawiera zbiór plików, oraz dodatkowo plik meta, który opisuje serwerowi jak zasób powinien być ładowany i jakie pliki zawiera. Zasób w MTA, w przełożeniu na bardziej znane środowisko systemu operacyjnego, odpowiada programowi lub usłudze działającego pod jego kontrolą - mogą być uruchamiane i zatrzymywane, przy czym wiele z nich może działać jednocześnie (multitasking).


Wszystko, co dzieje się wokół skryptów, dzieje się w zasobach, które to definiują, czy jest to gamemode, mapa, czy też cokolwiek innego. MTA jest dostępne do pobrania z wieloma zasobami, których to można opcjonalnie użyć w swoich gamemodach, np. takimi jak maplimits (zatrzymuje graczy w określonych granicach na mapie), deathpickups (tworzy pickupy z brońmi), czy też admin (panel administratora).
Wszystko, co dzieje się wokół skryptów, dzieje się w zasobach, które to definiują, czy jest to gamemode, mapa, czy też cokolwiek innego. MTA jest dostępne do pobrania z wieloma zasobami, których to można opcjonalnie użyć w swoich gamemodach, np. takimi jak maplimits (zatrzymuje graczy w określonych granicach na mapie), weaponpickups (tworzy pickupy z brońmi), czy też admin panel (panel administratora).


{{PL/Tip|Pierwszym krokiem na drodze pisania skryptów w Lua powinno być używanie odpowiedniego edytora skryptów. Ułatwi to znacznie pisanie skryptów. Polecamy [https://code.visualstudio.com/download Visual Studio Code].}}
{{PL/Tip|Pierwszym krokiem na drodze pisania skryptów w Lua powinno być używanie odpowiedniego edytora skryptów. Ułatwi to znacznie pisanie skryptów. Polecamy [https://code.visualstudio.com/download Visual Studio Code].}}
Line 28: Line 28:
</meta>
</meta>
</syntaxhighlight>
</syntaxhighlight>
W znaczniku ''<info />'' znajduje się pole "type", które wskazuje na typ zasobu (może być to: gamemode, zwykły include lub mapa, która zostanie objaśniona w dalszej części). Gamemode to właśnie to, czego potrzebujesz, aby utworzyć działający serwer.
W znaczniku ''<info />'' znajduje się pole "type", które wskazuje na typ zasobu (może być to: gamemode, zwykły include lub mapa, która zostanie objaśniona w dalszej części). Gamemode to właśnie to, czego potrzebujesz, aby utworzyć działający serwer. Znacznik ten jest jedynie dla informacji i nie jest potrzebny by jakikolwiek skrypt działał, aczkolwiek ułatwi to potem identyfikowanie zasobów.


Znacznik ''<script />'' wskazuje na pliki skryptów (.lua), które znajdują się w zasobie, większość z nich utworzysz samodzielnie później.
Znacznik ''<script />'' wskazuje na pliki skryptów (.lua), które znajdują się w zasobie, większość z nich utworzysz samodzielnie później.
Line 35: Line 35:
Możesz teraz skopiować i wkleić poniższy kod do pliku script.lua:
Możesz teraz skopiować i wkleić poniższy kod do pliku script.lua:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
local x = 1959.55
local y = -1714.46
local z = 15
function joinHandler()
function joinHandler()
local x = 1959.55
local y = -1714.46
local z = 15
spawnPlayer(source, x, y, z)
spawnPlayer(source, x, y, z)
fadeCamera(source, true)
fadeCamera(source, true)
setCameraTarget(source, source)
setCameraTarget(source, source)
outputChatBox("Witaj na moim serwerze!", source)
outputChatBox('Witaj na moim serwerze!', source)
end
end
addEventHandler("onPlayerJoin", getRootElement(), joinHandler)
addEventHandler('onPlayerJoin', root, joinHandler)
</syntaxhighlight>
</syntaxhighlight>
Skrypt ten zespawnuję cię w powyższych koordynatach (x, y, z), kiedy tylko dołączysz do gry. Zauważ, że funkcja ''fadeCamera'' musi zostać tutaj użyta, inaczej ekran byłby cały czas czarny. Także, w wydaniach MTA po DP2, musisz ustawić cel kamery (inaczej gracz zobaczy tylko niebo).
Skrypt ten odrodzi cię w powyższych koordynatach (x, y, z), kiedy tylko dołączysz do gry. Zauważ, że funkcja ''fadeCamera'' musi zostać tutaj użyta, inaczej ekran byłby cały czas czarny. Musisz również ustawić cel kamery (inaczej gracz zobaczy tylko niebo).


Zmienna '''source''' wskazuje, kto wywołał event (zdarzenie). Gdy gracz dołączy, kiedy kod jest wykonywany, zmiennej tej używa się, aby zobaczyć, kto dołączył. Dzięki niej, zespawnuję docelowego gracza, zamiast każdego, lub losowej osoby.
Zmienna '''source''' wskazuje, kto wywołał event (zdarzenie). Gdy gracz dołączy, kiedy kod jest wykonywany, zmiennej tej używa się, aby zobaczyć, kto dołączył. Dzięki niej, odrodzi docelowego gracza, zamiast każdego, lub losowej osoby.


Jeżeli bliżej przyjrzymy się funkcji [[addEventHandler]], możemy zauważyć 3 rzeczy: zdarzenie 'onPlayerJoin', który wskazuje, kiedy event jest wywoływany; getRootElement(), które pokazuje kto/co może go wywołać (getRootElement() to wszystko/każdy), oraz joinHandler, które wskazuje na funkcję, która ma być wywołana po tym, kiedy event się zaczął. Wszelakie inne detale zostaną wyjaśnione w dalszej części. Teraz można już uruchomić serwer, oraz wytestować skrypt!
Jeżeli bliżej przyjrzymy się funkcji [[addEventHandler]], możemy zauważyć 3 rzeczy: zdarzenie '''onPlayerJoin''', który wskazuje, kiedy event jest wywoływany; zmienna '''root''', które pokazuje kto/co może go wywołać (root oznacza "najwyższego rodzica" w hierarchii), oraz '''joinHandler''', które wskazuje na funkcję, która ma być wywołana po tym, kiedy event się zaczął. Wszelakie inne detale zostaną wyjaśnione w dalszej części. Teraz można już uruchomić serwer, oraz wytestować skrypt!


===Uruchamianie skryptu===
===Uruchamianie skryptu===
Żeby wystartować serwer pod kontrolą systemu Windows, po prostu uruchom plik wykonywalny w katalogu twojego serwera MTA. Na początku wyświetlą się dane twojego serwera. Zanotuj numer portu, którego będziesz potem potrzebował, przy dołączaniu do gry. Następnie serwer załaduje wszystkie zasoby (załaduje, ale nie uruchomi), które znajdują się w katalogu /resources/, i finalnie, stanie się dostępny dla graczy ("ready to accept connections!").
Żeby wystartować serwer pod kontrolą systemu Windows, po prostu uruchom plik wykonywalny w katalogu twojego serwera MTA. Na początku wyświetlą się dane twojego serwera. Zanotuj numer portu, którego będziesz potem potrzebował, przy dołączaniu do gry. Następnie serwer załaduje wszystkie zasoby (załaduje, ale nie uruchomi), które znajdują się w katalogu /resources/, i finalnie, stanie się dostępny dla graczy ("ready to accept connections!").


Zanim podłączysz się do serwera, musisz wpierw uruchomić gamemode. To logiczne, po to, aby można było mieć na "czymś" grać. Wpisz "gamemode myserver", oraz wciśnij Enter. Serwer uruchomi twój świeżo utworzony gamemode, a także wyświetli tutaj listę wszystkich błędów/ostrzeżeń. Wreszcie, możesz uruchomić klienta MTA, wybrać opcję "Quick Connect" i używając swojego adresu IP, oraz portu (który zdobyliśmy wcześniej) połączyć się. Jeżeli wszystko pójdzie dobrze, za kilka chwil twoja postać będzie wędrowała po ulicach Los Santos.
Zanim podłączysz się do serwera, musisz wpierw uruchomić swój zasób. To logiczne, po to, aby można było mieć na "czymś" grać. Wpisz "start myserver", oraz wciśnij Enter. Serwer uruchomi twój świeżo utworzony gamemode, a także wyświetli tutaj listę wszystkich błędów/ostrzeżeń. Wreszcie, możesz uruchomić klienta MTA, wybrać opcję "Quick Connect" i używając swojego adresu IP, oraz portu (który zdobyliśmy wcześniej) połączyć się. Jeżeli wszystko pójdzie dobrze, za kilka chwil twoja postać będzie wędrowała po ulicach Los Santos.


Następnie, utworzymy prostą komendę do wcześniejszego skryptu, którą gracze będą mogli używać, aby przywoływać sobie pojazdy, blisko ich pozycji. Możesz pominąć tą część, i przejść do bardziej zaawansowanego skryptowania z [[Map_manager|Map Managerem]], które kontynuuje ten samouczek. Inną drogą jest przejście do samouczka [[Introduction_to_Scripting_the_GUI|Wstęp do pisania skryptów z GUI]], gdzie wyjaśnione jest, jak interfejs graficzny jest rysowany oraz oskryptowany w MTA.
Następnie, utworzymy prostą komendę do wcześniejszego skryptu, którą gracze będą mogli używać, aby przywoływać sobie pojazdy, blisko ich pozycji. Możesz pominąć tą część, i przejść do bardziej zaawansowanego skryptowania z [[Map_manager|Map Managerem]], który kontynuuje ten samouczek. Inną drogą jest przejście do samouczka [[Introduction_to_Scripting_the_GUI|Wstęp do pisania skryptów z GUI]], gdzie wyjaśnione jest, jak interfejs graficzny jest rysowany oraz oskryptowany w MTA.


==Tworzymy prostą komendę==
==Tworzymy prostą komendę==
Wróćmy więc do zawartości pliku ''script.lua''. Jak zostało wspomniane wyżej, stworzymy komendę, po której wywołaniu obok bieżącej pozycji gracza pojawi się wybrany pojazd. Po pierwsze, musimy utworzyć funkcję, którą będziemy wzywali wywołaniem komendy, oraz tzw. ''command handler'', który tworzy i powoduje, że komenda może być wprowadzona przez gracza w konsoli.
Wróćmy więc do zawartości pliku ''script.lua''. Jak zostało wspomniane wyżej, stworzymy komendę, po której wywołaniu obok bieżącej pozycji gracza pojawi się wybrany pojazd. Po pierwsze, musimy utworzyć funkcję, którą będziemy wzywali wywołaniem komendy, oraz tzw. ''command handlera'', który tworzy i sprawia, że komenda może być wprowadzona przez gracza w konsoli.


<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
Line 69: Line 70:


-- tworzymy command handler
-- tworzymy command handler
addCommandHandler("stworzpojazd", createVehicleForPlayer)
addCommandHandler('stworzpojazd', createVehicleForPlayer)
</syntaxhighlight>
</syntaxhighlight>
''Notka: kliknięcie nazwy funkcji powoduje przejście do strony z informacjami na jej temat.''
''Notka: kliknięcie nazwy funkcji powoduje przejście do strony z informacjami na jej temat.''
Line 78: Line 79:
Jeżeli masz już doświadczenie w programowaniu, zapewne wiesz, jak wygląda typowa postać funkcji:
Jeżeli masz już doświadczenie w programowaniu, zapewne wiesz, jak wygląda typowa postać funkcji:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
nazwaFunkcji(argument1, argument2, argument3, ..)
nazwaFunkcji(argument1, argument2, argument3, ...)
</syntaxhighlight>
 
<syntaxhighlight lang="lua">
nazwaFunkcji(thePlayer, commandName, argument3, ...)
nazwaFunkcji(thePlayer, commandName, argument3, ..)
</syntaxhighlight>
</syntaxhighlight>
Jeżeli bliżej przypatrzymy się powyższemu przykładowi, zobaczymy, że argumentem1 jest thePlayer, a argumentem2 jest commandName. thePlayer jest po prostu zmienną oznaczającą kto wprowadził komendę, więc jakkolwiek byś jej nie nazwał, będzie zawierała gracza, który aktywował komendę. commandName jest komendą, którą gracz wprowadził. Także, jeżeli gracz wpisałby np. "/alarm", ten argument zawierałby wartość typu string "alarm". Argument3 jest czymś dodatkowym, co tylko wpisze gracz za komendą, będzie to później omawiane. Nigdy nie zapomnij, że pierwsze 2 argumenty są obowiązkowe, lecz możesz je nazwać dowolnie.
Jeżeli bliżej przypatrzymy się powyższemu przykładowi, zobaczymy, że argumentem1 jest thePlayer, a argumentem2 jest commandName. thePlayer jest po prostu zmienną oznaczającą kto wprowadził komendę, więc jakkolwiek byś jej nie nazwał, będzie zawierała gracza, który aktywował komendę. commandName jest komendą, którą gracz wprowadził. Także, jeżeli gracz wpisałby np. "/alarm", ten argument zawierałby wartość typu string (tekst) "alarm". Argument3 jest czymś dodatkowym, co tylko wpisze gracz za komendą, będzie to później omawiane. Nigdy nie zapomnij, że pierwsze 2 argumenty są obowiązkowe, lecz możesz je nazwać dowolnie.


Dlatego też najpierw wywołaliśmy funkcję, do której [[addCommandHandler]] się odwołuje, a potem dopiero dodaliśmy command handler. W innym przypadku komenda nie zostałaby poprawnie przypisana do funkcji. Zalecany jest taki porządek.
Dlatego też najpierw stworzyliśmy funkcję, do której [[addCommandHandler]] się odwołuje, a potem dopiero dodaliśmy command handler. W innym przypadku komenda nie zostałaby poprawnie przypisana do funkcji. Zalecany jest taki porządek.


Dla przykładu: ktoś wpisze w konsoli "/stworzpojazd 468", aby stworzyć obok siebie Sancheza, command handler wywoła funkcję createVehicleForPlayer, która będzie wyglądała tak, kiedy argumenty zostaną do niej przekazane:
Dla przykładu: ktoś wpisze w konsoli "/stworzpojazd 468", aby stworzyć obok siebie Sancheza, command handler wywoła funkcję createVehicleForPlayer, która będzie wyglądała tak, kiedy argumenty zostaną do niej przekazane:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
createVehicleForPlayer(thePlayer,"stworzpojazd","468") -- thePlayer to zmienna typu element (gracz), która wskazuje na tego gracza, który wprowadził komendę
-- thePlayer to zmienna typu element (gracz), która wskazuje na tego gracza, który wprowadził komendę
createVehicleForPlayer(thePlayer,'stworzpojazd',468)
</syntaxhighlight>
</syntaxhighlight>
Jak możemy zobaczyć, dostarczane jest kilka parametrów: gracza, który wywołał komendę, treść komendy, oraz wartość, która została wprowadzona po niej, w tym przypadku "486" (ID Sancheza). Pierwsze dwa parametry będą takie same we wszystkich command handlerach, można to doczytać na stronie funkcji [[addCommandHandler]]. W wyniku tego, zawsze będziesz musiał definiować przynajmniej dwa pierwsze argumenty, aby potem dodać ich dowolną ilość (dla przykładu, jakieś wartości, które funkcja ma przetwarzać)
Jak możemy zobaczyć, dostarczane jest kilka parametrów: gracz, który wywołał komendę, treść komendy, oraz wartość, która została wprowadzona po niej, w tym przypadku "'''486'''" (ID Sancheza). Pierwsze dwa parametry będą takie same we wszystkich command handlerach, można to doczytać na stronie funkcji [[addCommandHandler]]. W wyniku tego, zawsze będziesz musiał definiować przynajmniej dwa pierwsze argumenty, aby potem dodać ich dowolną ilość (dla przykładu, jakieś wartości, które funkcja ma przetwarzać)


<!--
''Przypomnienie: Musisz zawsze dodawać command handler PO funkcji, którą definiowałeś. Porządek wykonania ma znaczenie, inaczej command handler jej nie znajdzie.''
''Przypomnienie: Musisz zawsze dodawać command handler PO funkcji, którą definiowałeś. Porządek wykonania ma znaczenie, inaczej command handler jej nie znajdzie.''
Tylko jeżeli funkcja jest lokalna. W przeciwnym wypadku kolejność nie ma znaczenia.
-->


====Piszemy funkcję====
====Piszemy funkcję====
Line 102: Line 106:
* Sprawdzić, czy się udało, w innym wypadku wypisać komunikat
* Sprawdzić, czy się udało, w innym wypadku wypisać komunikat


Aby dokonać tego celu, będziemy potrzebować kilku funkcji. Aby znaleźć funkcje, których będziemy potrzebować, powinniśmy odwiedzić [[Scripting Functions|Server Functions List]]. Po pierwsze, potrzebujemy funkcji, która pobierze i zwróci pozycję gracza. Odkąd gracze są Elementami, przejdziemy najpierw do '''Element functions''', gdzie znajdziemy funkcję [[getElementPosition]]. Klikając nazwę funkcji na liście, pokaże się jej opis. Możemy tam zobaczyć jej składnię, co zwraca, oraz przykłady użycia. Składnia pokazuje nam, jakich argumentów trzeba użyć:
Aby dokonać tego celu, będziemy potrzebować kilku funkcji. Aby znaleźć funkcje, których będziemy potrzebować, powinniśmy odwiedzić [[Scripting Functions|Listę funkcji serwerowych]]. Po pierwsze, potrzebujemy funkcji, która pobierze i zwróci pozycję gracza. Odkąd gracze są Elementami, przejdziemy najpierw do '''Element functions''', gdzie znajdziemy funkcję [[getElementPosition]]. Klikając nazwę funkcji na liście, pokaże się jej opis. Możemy tam zobaczyć jej składnię, co zwraca, oraz przykłady użycia. Składnia pokazuje nam, jakich argumentów trzeba użyć:


Dla [[getElementPosition]], składnia wygląda tak:
Dla [[getElementPosition]], składnia wygląda tak:
Line 140: Line 144:
end
end
</syntaxhighlight>
</syntaxhighlight>
<!--
'''Zobacz także:'''
* [[PL/OOP|OOP]]
* [[Advanced Topics]]
* [[Script_security|Script security]]
-->
[[ar:مقدمه_في_البرمجه]]
[[en:Scripting Introduction]]
[[es:Introducción a la Programación]]
[[hu:Bevezetés a scriptelésbe]]
[[it:Introduzione allo scripting]]
[[nl:Scripting_introductie]]
[[pt-br:Introdução ao Scripting]]
[[ru:Scripting Introduction]]
[[zh-cn:脚本编写介绍]]
[[Category:Tutorials]]

Latest revision as of 10:57, 29 May 2022

Zasoby są kluczową częścią MTA. Najprościej rzecz ujmując, zasób to folder lub plik .zip, który zawiera zbiór plików, oraz dodatkowo plik meta, który opisuje serwerowi jak zasób powinien być ładowany i jakie pliki zawiera. Zasób w MTA, w przełożeniu na bardziej znane środowisko systemu operacyjnego, odpowiada programowi lub usłudze działającego pod jego kontrolą - mogą być uruchamiane i zatrzymywane, przy czym wiele z nich może działać jednocześnie (multitasking).

Wszystko, co dzieje się wokół skryptów, dzieje się w zasobach, które to definiują, czy jest to gamemode, mapa, czy też cokolwiek innego. MTA jest dostępne do pobrania z wieloma zasobami, których to można opcjonalnie użyć w swoich gamemodach, np. takimi jak maplimits (zatrzymuje graczy w określonych granicach na mapie), weaponpickups (tworzy pickupy z brońmi), czy też admin panel (panel administratora).


[[{{{image}}}|link=|]] Wskazówka: Pierwszym krokiem na drodze pisania skryptów w Lua powinno być używanie odpowiedniego edytora skryptów. Ułatwi to znacznie pisanie skryptów. Polecamy Visual Studio Code.

Tworzymy działający skrypt

Najpierw nauczymy się, krok po kroku, jak stworzyć podstawowy, prosty skrypt, który pozwoli graczowi chodzić po mieście Los Santos.

Ale gdzie zacząć?

Spójrzmy na strukturę skryptów. Wejdź do swojego folderu serwera MTA (MTA Server), a następnie w poniższą ścieżkę:

       /MTA Server/mods/deathmatch/resources/

Powinieneś zobaczyć dużo plików .zip, które są przykładowymi skryptami, dostarczanymi wraz z MTA. Każdy plik jest "zasobem", oraz mogą być rozpakowane i załadowane przez serwer, kiedy jest uruchamiany. Aby stworzyć swój własny zasób, po prostu utwórz folder z preferowaną nazwą. Do celów tego samouczka, użyjemy nazwy "myserver".

Powinieneś być teraz w tym katalogu:

       /MTA Server/mods/deathmatch/resources/myserver/

Identyfikujemy swój zasób

Aby serwer wiedział, co znajduje się w zasobie, plik meta.xml musi zostać stworzony, aby wylistować wszystkie pliki zasobu serwerowi. Musi on znajdować się w głównym katalogu naszego zasobu (w tym przypadku, "myserver"). Tak więc, stwórz plik tekstowy i nazwij go "meta.xml", oraz otwórz go do edycji.

Wpisz do pliku meta.xml ponizszy kod:

<meta>
     <info author="TwojNick" version="0.1" type="gamemode" name="My Server" description="Moj pierwszy serwer MTA" />
     <script src="script.lua" type="server" />
</meta>

W znaczniku <info /> znajduje się pole "type", które wskazuje na typ zasobu (może być to: gamemode, zwykły include lub mapa, która zostanie objaśniona w dalszej części). Gamemode to właśnie to, czego potrzebujesz, aby utworzyć działający serwer. Znacznik ten jest jedynie dla informacji i nie jest potrzebny by jakikolwiek skrypt działał, aczkolwiek ułatwi to potem identyfikowanie zasobów.

Znacznik <script /> wskazuje na pliki skryptów (.lua), które znajdują się w zasobie, większość z nich utworzysz samodzielnie później.

Piszemy prosty skrypt

Zauważ, że w znaczniku <script /> plik skryptu .lua umieściliśmy w bieżącym katalogu (gdybyśmy chcieli inaczej, zawsze jest taka możliwości, działa to dokładnie tak, jak w HTML'u). Teraz utwórzmy ten plik. Możesz teraz skopiować i wkleić poniższy kod do pliku script.lua:

local x = 1959.55
local y = -1714.46
local z = 15

function joinHandler()
	spawnPlayer(source, x, y, z)
	fadeCamera(source, true)
	setCameraTarget(source, source)
	outputChatBox('Witaj na moim serwerze!', source)
end
addEventHandler('onPlayerJoin', root, joinHandler)

Skrypt ten odrodzi cię w powyższych koordynatach (x, y, z), kiedy tylko dołączysz do gry. Zauważ, że funkcja fadeCamera musi zostać tutaj użyta, inaczej ekran byłby cały czas czarny. Musisz również ustawić cel kamery (inaczej gracz zobaczy tylko niebo).

Zmienna source wskazuje, kto wywołał event (zdarzenie). Gdy gracz dołączy, kiedy kod jest wykonywany, zmiennej tej używa się, aby zobaczyć, kto dołączył. Dzięki niej, odrodzi docelowego gracza, zamiast każdego, lub losowej osoby.

Jeżeli bliżej przyjrzymy się funkcji addEventHandler, możemy zauważyć 3 rzeczy: zdarzenie onPlayerJoin, który wskazuje, kiedy event jest wywoływany; zmienna root, które pokazuje kto/co może go wywołać (root oznacza "najwyższego rodzica" w hierarchii), oraz joinHandler, które wskazuje na funkcję, która ma być wywołana po tym, kiedy event się zaczął. Wszelakie inne detale zostaną wyjaśnione w dalszej części. Teraz można już uruchomić serwer, oraz wytestować skrypt!

Uruchamianie skryptu

Żeby wystartować serwer pod kontrolą systemu Windows, po prostu uruchom plik wykonywalny w katalogu twojego serwera MTA. Na początku wyświetlą się dane twojego serwera. Zanotuj numer portu, którego będziesz potem potrzebował, przy dołączaniu do gry. Następnie serwer załaduje wszystkie zasoby (załaduje, ale nie uruchomi), które znajdują się w katalogu /resources/, i finalnie, stanie się dostępny dla graczy ("ready to accept connections!").

Zanim podłączysz się do serwera, musisz wpierw uruchomić swój zasób. To logiczne, po to, aby można było mieć na "czymś" grać. Wpisz "start myserver", oraz wciśnij Enter. Serwer uruchomi twój świeżo utworzony gamemode, a także wyświetli tutaj listę wszystkich błędów/ostrzeżeń. Wreszcie, możesz uruchomić klienta MTA, wybrać opcję "Quick Connect" i używając swojego adresu IP, oraz portu (który zdobyliśmy wcześniej) połączyć się. Jeżeli wszystko pójdzie dobrze, za kilka chwil twoja postać będzie wędrowała po ulicach Los Santos.

Następnie, utworzymy prostą komendę do wcześniejszego skryptu, którą gracze będą mogli używać, aby przywoływać sobie pojazdy, blisko ich pozycji. Możesz pominąć tą część, i przejść do bardziej zaawansowanego skryptowania z Map Managerem, który kontynuuje ten samouczek. Inną drogą jest przejście do samouczka Wstęp do pisania skryptów z GUI, gdzie wyjaśnione jest, jak interfejs graficzny jest rysowany oraz oskryptowany w MTA.

Tworzymy prostą komendę

Wróćmy więc do zawartości pliku script.lua. Jak zostało wspomniane wyżej, stworzymy komendę, po której wywołaniu obok bieżącej pozycji gracza pojawi się wybrany pojazd. Po pierwsze, musimy utworzyć funkcję, którą będziemy wzywali wywołaniem komendy, oraz tzw. command handlera, który tworzy i sprawia, że komenda może być wprowadzona przez gracza w konsoli.

-- tworzymy funkcję, którą będzie wzywał command handler, z argumentami thePlayer (gracz), command (komenda), vehicleModel (model pojazdu)
function createVehicleForPlayer(thePlayer, command, vehicleModel)
   -- Tutaj stworzymy i zespawnujemy pojazd
end

-- tworzymy command handler
addCommandHandler('stworzpojazd', createVehicleForPlayer)

Notka: kliknięcie nazwy funkcji powoduje przejście do strony z informacjami na jej temat.

O command handlerach

Pierwszym argumentem funkcji addCommandHandler jest nazwa komendy, którą gracz może wprowadzić, drugim argumentem jest nazwa funkcji, którą chcielibyśmy wywołać, w tym przypadku createVehicleForPlayer.

Jeżeli masz już doświadczenie w programowaniu, zapewne wiesz, jak wygląda typowa postać funkcji:

nazwaFunkcji(argument1, argument2, argument3, ...)

nazwaFunkcji(thePlayer, commandName, argument3, ...)

Jeżeli bliżej przypatrzymy się powyższemu przykładowi, zobaczymy, że argumentem1 jest thePlayer, a argumentem2 jest commandName. thePlayer jest po prostu zmienną oznaczającą kto wprowadził komendę, więc jakkolwiek byś jej nie nazwał, będzie zawierała gracza, który aktywował komendę. commandName jest komendą, którą gracz wprowadził. Także, jeżeli gracz wpisałby np. "/alarm", ten argument zawierałby wartość typu string (tekst) "alarm". Argument3 jest czymś dodatkowym, co tylko wpisze gracz za komendą, będzie to później omawiane. Nigdy nie zapomnij, że pierwsze 2 argumenty są obowiązkowe, lecz możesz je nazwać dowolnie.

Dlatego też najpierw stworzyliśmy funkcję, do której addCommandHandler się odwołuje, a potem dopiero dodaliśmy command handler. W innym przypadku komenda nie zostałaby poprawnie przypisana do funkcji. Zalecany jest taki porządek.

Dla przykładu: ktoś wpisze w konsoli "/stworzpojazd 468", aby stworzyć obok siebie Sancheza, command handler wywoła funkcję createVehicleForPlayer, która będzie wyglądała tak, kiedy argumenty zostaną do niej przekazane:

-- thePlayer to zmienna typu element (gracz), która wskazuje na tego gracza, który wprowadził komendę
createVehicleForPlayer(thePlayer,'stworzpojazd',468)

Jak możemy zobaczyć, dostarczane jest kilka parametrów: gracz, który wywołał komendę, treść komendy, oraz wartość, która została wprowadzona po niej, w tym przypadku "486" (ID Sancheza). Pierwsze dwa parametry będą takie same we wszystkich command handlerach, można to doczytać na stronie funkcji addCommandHandler. W wyniku tego, zawsze będziesz musiał definiować przynajmniej dwa pierwsze argumenty, aby potem dodać ich dowolną ilość (dla przykładu, jakieś wartości, które funkcja ma przetwarzać)


Piszemy funkcję

Aby prawidłowo "zapełnić" naszą funkcję, powinniśmy pomyśleć o rzeczach, które ma zrobić:

  • Pobrać pozycję gracza, skąd będziemy wiedzieli, gdzie respawnować pojazd (chcemy, aby pojawił się po lewej stronie)
  • Obliczyć dokładną pozycję spawnu auta (nie chcemy, aby spadło na gracza)
  • Zespawnować podany pojazd
  • Sprawdzić, czy się udało, w innym wypadku wypisać komunikat

Aby dokonać tego celu, będziemy potrzebować kilku funkcji. Aby znaleźć funkcje, których będziemy potrzebować, powinniśmy odwiedzić Listę funkcji serwerowych. Po pierwsze, potrzebujemy funkcji, która pobierze i zwróci pozycję gracza. Odkąd gracze są Elementami, przejdziemy najpierw do Element functions, gdzie znajdziemy funkcję getElementPosition. Klikając nazwę funkcji na liście, pokaże się jej opis. Możemy tam zobaczyć jej składnię, co zwraca, oraz przykłady użycia. Składnia pokazuje nam, jakich argumentów trzeba użyć:

Dla getElementPosition, składnia wygląda tak:

float, float, float getElementPosition ( element theElement )

Trzy zmienne typu float na początku oznaczają wartości, które funkcja zwraca. W tym wypadku są to 3 wartości typu zmiennoprzecinkowego (floating point) (x, y i z). W nawiasach możesz dostrzec argumenty, które musisz dostarczyć funkcji, aby została prawidłowo wykonana. W tym przypadku będzie to jedynie element (gracz), którego pozycję chcesz znać.

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	-- pobierz pozycję i zapisz ją w zmiennych x,y,z
	-- (local znaczy, że zmienna będzie istniała tylko w obrębie tej funkcji, przeciwieństwo globalnej zmiennej)
	local x,y,z = getElementPosition(thePlayer)
end

Następnie chcemy mieć pewność, że pojazd nie zespawnuje się przygniatając gracza, toteż dodamy kilka jednostek do zmiennej x, aby go przesunąć na wschód:

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- pobierz pozycję gracza
	x = x + 5 -- dodaj 5 jednostek do pozycji
end

Teraz potrzebujemy następnej, innej funkcji, która będzie spawnować podane auto. Raz jeszcze poszukamy jej w Server Functions List, tym razem powinna być w kategorii Vehicle functions, gdzie wybierzemy właściwą: createVehicle. W składnie tej funkcji mamy tylko jedną rzecz, którą zwraca (jest to często spotykane), element typu vehicle, który wskazuje na spawnowany pojazd. Także, możemy zauważyć argumenty objęte nawiasem kwadratowym, które są opcjonalne.

Mamy już wszystkie argumenty, których potrzebujemy dla createVehicle w naszej funkcji: Pozycję, którą obliczyliśmy w zmiennych x,y,z, oraz model pojazdu, który dostarczymy przez komendę ("stworzpojazd 486"), oraz możliwość dostępu do funkcji przez zmienną vehicleModel (model pojazdu)

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- pobierz pozycję gracza
	x = x + 5 -- dodaj 5 jednostek do pozycji
	-- Stwórz pojazd i przechowaj element typu vehicle w zmiennej ''createdVehicle''
	local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
end