HU/Bevezetés a scriptelésbe: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 53: Line 53:


Következőnek egy parancsot fogunk létrehozni, amivel képesek leszünk egy kocsit létrehozni a helyzetünkön. Lehet, hogy kiszeretnéd ezt hagyni, és a haladó scriptelést szeretnéd megismerni a [[Map Manager | Map Manager]], használatával, ami ezt az oktatást folytatja. Egy másik ág a [[Bevezetés a GUI scriptelésbe]], ami megmutatja hogy hogyan hozunk létre Grafikus Felhasználói Felületet MTAn belül.
Következőnek egy parancsot fogunk létrehozni, amivel képesek leszünk egy kocsit létrehozni a helyzetünkön. Lehet, hogy kiszeretnéd ezt hagyni, és a haladó scriptelést szeretnéd megismerni a [[Map Manager | Map Manager]], használatával, ami ezt az oktatást folytatja. Egy másik ág a [[Bevezetés a GUI scriptelésbe]], ami megmutatja hogy hogyan hozunk létre Grafikus Felhasználói Felületet MTAn belül.
==Egy egyszerű parancs létrehozása==
Menjünk vissza a ''script.lua'' fájl tartalmához. Ahogy említettük feljebb, egy parancsot akarunk szolgáltatni, amivel egy kocsit lehet létrehozni a jelenlegi helyzeteden. Először, létre kell hoznunk egy funkciót, amit megakarunk hívni és egy parancskezelőt, ami létrehozza a parancsot, amit a játékos betud írni a konzolba.
<syntaxhighlight lang="lua">
-- A funckió létrehozása, ezekkel az argumentumokkal: thePlayer, command, vehicleModel
function jarmuLetrehozasaJatekosnak(thePlayer, command, vehicleModel)
  -- A jármű létrehozása és még pár dolog
end
-- A parancskezelő létrehozása
addCommandHandler("jarmuletrehozas", jarmuLetrehozasaJatekosnak)
</syntaxhighlight>
''Megjegyzés: A funckió nevek megnyomhatóak a példákban, és a wikin elhelyezkedő funkció leírására dobnak.''
====A parancskezelőkről====
Az első argumentuma az [[addCommandHandler]] funckiónak a parancs neve, amit a játékos betud majd írni, a második argumentuma amit ez megfog hívni, az esetünkben a ''jarmuLetrehozasaJatekosnak''.
Ha már van némi tudásod a scriptelésben, akkor tudni fogod, hogy így hívjuk meg a funckiókat:
<syntaxhighlight lang="lua">
funckioNeve(argumentum1, argumentum2, argumentum3, ..)
</syntaxhighlight>
<syntaxhighlight lang="lua">
funkcioNeve(thePlayer, parancsNeve, argumentum3, ..)
</syntaxhighlight>
Ha egy közelebbről megnézzük az alsó példát felettünk láthatjuk, hogy az argumentum1 a thePlayer és az argumentum2 a commandName. thePlayer simán az az egy, aki beírta a parancsot, szóval, akárminek nevezed el, ez a változó fogja tartalmazni a játékost, aki aktiválta a parancsot. A commandName simán a parancs, amit beírtak. Szóval ha beírták a "/üdvözlet", parancsot akkor ez az argumentum  tartalmazza az "üdvözlet" szöveget. Az argumentum3 az plusz dolog, amit a játékos beírt. Erről egy kicsit később fogsz tanulni az oktatásban. Soha ne felejtsd el, hogy az első kettő argumentum standard, de akárminek elnevezheted.
Mi már meghívtuk az [[addCommandHandler]] funckiót ilyen módon, és mióta a ''jarmuLetrehozasaJatekosnak'' is egy ilyen funckió, ezért ilyen módon meghívható ő is. De e helyett mi egy parancskezelőt használunk, ami hasonló módon hívja meg.
Például: Valaki beírja a "jarmuletrehozas 468" parancsot a játék konzoljába, hogy lehívjon egy Sanchezt, a parancskezelő meghívja a  "jarmuLetrehozasaJatekosnak" funkciót, az olyan '''mintha''' ezt a sort raktuk volna a scriptbe:
<syntaxhighlight lang="lua">
jarmuLetrehozasaJatekosnak(thePlayer,"jarmuletrehozas","468") -- A thePlayer a játékos, aki beírta a parancsot
</syntaxhighlight>
Ahogy láthatjuk, ez pár paramétert szolgáltat: A játékost, aki beírta a parancsot, a parancsot, amit beírt és minden más szöveget, amit utána beírt, ebben a példában a "468" ami a Sanchez IDje a játékban. Az első kettő paraméter mindig ugyan az a parancskezelőknél, amit elolvashatsz az [[addEventHandler]] oldalnál. Ez miatt, mindig minimum kettő paramétert kell meghatározni, hogy akármi mást tudsz utána használni (például, ahhoz, hogy egy szöveget beolvassunk a parancs beírása után, a mi példánkban a jármű model IDje).
''Megjegyzés: Minden esetben a funckió létrehozása UTÁN kell definiálni a parancskezelőt, különben nem fogja megtalálni. A meghívások sorrendje számít.''
====A funckió megírása====
Ahhoz, hogy feltöltsük azt a funkciót, amit írtunk, először gondolkoznunk kell, hogy mit is akarunk csinálni:
* Lekérni a játékos pozícióját, hogy megtudjuk, hogy hova is rakjuk le a kocsit (azt akarjuk, hogy pontosan a játékosnál jelenjen meg).
* Számítsuk ki a pozíciót, ahova létrehozzuk a járművet (nem akarjuk, hogy a játékosban jelenjen meg).
* Hozzuk létre a járművet.
* Nézzük meg, hogy létre lett hova, vagy írjunk ki egy hibát.
Ahhoz, hogy elérjük a célunkat, szükséges lesz pár funkcióra. Ahhoz, hogy megtaláljuk a funkciókat, amikez használnunk kell, látogassunk el a [[Scripting Functions|Szerver Scriptelési Funckiók]]hoz. Először is, le kell kérnünk a játékos pozícióját. Mivel a játékosok elementek, először az '''Element funkcióhoz''' lépünk, ahol megtaláljuk a [[getElementPosition]] funckiót. A funkció nevére kattintással a listában, eljutsz a funkció leírásához. Itt láthatjuk a szintaxist, mit ad vissza, és általában egy példát. A szintaxis mutatja meg, hogy milyen argumentumokat lehet, vagy kell beírnunk.
A [[getElementPosition]] funckióhoz a szintaxis:
<syntaxhighlight lang="lua">
float, float, float getElementPosition ( element azElement )
</syntaxhighlight>
A három ''float'' a visszaadási érték típusa. Ebben az esetben a funkció három lebegőpontos szám. (x, y és z) A zárójelekben láthatod, hogy milyen argumentumokat kell beírnod. Ebben az esetben csak az elementet, akinek leakarod kérni a pozícióját, ami a játékos a példánkban.
<syntaxhighlight lang="lua">
function jarmuLetrehozasaJatekosnak(thePlayer, command, vehicleModel)
-- Kérjük le a koordinátát és rakjuk be az x, y, z változókban
-- (A local azt jelenti, hgy a változó csak a jelenlegi területben létezik, ebben az esetben a funckió)
local x, y, z = getElementPosition(thePlayer)
end
</syntaxhighlight>
Következőnek  to biztosítani akarjuk, hogy a jármű nem lesz létrehozva pontosan a játékosban szóval hozzáadunk pár egységet az ''x'' változóhoz, ami azt fogja eredményezni, hogy a játékostól keletre lesz létrehozva.
<syntaxhighlight lang="lua">
function jarmuLetrehozasaJatekosnak(thePlayer, command, vehicleModel)
local x, y, z = getElementPosition(thePlayer) -- A játékos pozíciójának lekérése
x = x + 5 -- 5 egység hozzáadása az "x" változóhoz
end
</syntaxhighlight>
Now we need another function, one to spawn a vehicle. We once again search for it on the [[Scripting Functions|Server Functions List]], this time - since we are talking about vehicles - in the '''Vehicle functions''' section, where we will choose [[createVehicle]]. In this function's syntax, we only have one return type (which is more common), a vehicle element that points to the vehicle we just created. Also, we see that some arguments are enclosed within [ ] which means that those are optional.
We already have all arguments we need for [[createVehicle]] in our function: The position we just calculated in the ''x,y,z'' variables and the model id that we provided through the command ("createvehicle 468") and can access in the function as ''vehicleModel'' variable.
<syntaxhighlight lang="lua">
function createVehicleForPlayer(thePlayer, command, vehicleModel)
local x,y,z = getElementPosition(thePlayer) -- get the position of the player
x = x + 5 -- add 5 units to the x position
-- create the vehicle and store the returned vehicle element in the ''createdVehicle'' variable
local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
end
</syntaxhighlight>
Of course this code can be improved in many ways, but at least we want to add a check whether the vehicle was created successfully or not. As we can read on the [[createVehicle]] page under '''Returns''', the function returns ''false'' when it was unable to create the vehicle. Thus, we check the value of the ''createVehicle'' variable.
Now we have our complete script:
<syntaxhighlight lang="lua">
function createVehicleForPlayer(thePlayer, command, vehicleModel)
local x,y,z = getElementPosition(thePlayer) -- get the position of the player
x = x + 5 -- add 5 units to the x position
local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
-- check if the return value was ''false''
if (createdVehicle == false) then
-- if so, output a message to the chatbox, but only to this player.
outputChatBox("Failed to create vehicle.",thePlayer)
end
end
addCommandHandler("createvehicle", createVehicleForPlayer)
</syntaxhighlight>
As you can see, we introduced another function with [[outputChatBox]]. By now, you should be able to explore the function's documentation page yourself. For more advanced scripting, please check out the [[Map manager|Map Manager]].
==What you need to know==
You already read some things about resources, command handlers and finding functions in the documentation in the first paragraph, but there is much more to learn. This section will give you a rather short overview over some of these things, while linking to related pages if possible.
===Clientside and Serverside scripts===
You may have already noticed these or similiar terms (Server/Client) somewhere on this wiki, mostly in conjunction with functions. MTA not only supports scripts that run on the server and provide commands (like the one we wrote above) or other features, but also scripts that run on the MTA client the players use to connect to the server. The reason for this is, that some features MTA provides have to be clientside (like a GUI - Graphical User Interface), others should be because they work better and still others are better off to be serverside or just don't work clientside.
Most scripts you will make (gamemodes, maps) will probably be serverside, like the one we wrote in the first section. If you run into something that can't be solved serverside, you will probably have to make it clientside. For a clientside script for example, you would create a ordinary script file (for example called ''client.lua'') and specify it in the meta.xml, like this:
<syntaxhighlight lang="xml">
<script src="client.lua" type="client" />
</syntaxhighlight>
The ''type'' attribute defaults to 'server', so you only need to specify it for clientside scripts. When you do this, the clientside script will be downloaded to the player's computer once he connects to the server. Read more about [[Client side scripts]].
===More complex resources===
The previous section showed briefly how to add clientside scripts to the resource, but there is also much more possible. As mentioned at the very top of this page, resources can be pretty much everything. Their purpose is defined by what they do. Let's have some theoretical resources, by looking at the files it contains, the ''meta.xml'' and what they might do:
====First example - A utility script====
<syntaxhighlight lang="xml">
/admin_commands
/meta.xml
/commands.lua
/client.lua
</syntaxhighlight>
<syntaxhighlight lang="xml">
<meta>
<info author="Someguy" description="admin commands" />
<script src="commands.lua" />
<script src="client.lua" type="client" />
</meta>
</syntaxhighlight>
* The ''commands.lua'' provides some admin commands, like banning a player, muting or something else that can be used to admin the server
* The ''client.lua'' provides a GUI to be able to perform the mentioned actions easily
This example might be running all the time (maybe even auto-started when the server starts) as it's useful during the whole gaming experience and also wont interfere with the gameplay, unless an admin decides to take some action of course.
====Second example - A gamemode====
<syntaxhighlight lang="xml">
/counterstrike
/meta.xml
/counterstrike.lua
/buymenu.lua
</syntaxhighlight>
<syntaxhighlight lang="xml">
<meta>
<info author="Someguy" description="Counterstrike remake" type="gamemode" />
<script src="counterstrike.lua" />
<script src="buymenu.lua" type="client" />
</meta>
</syntaxhighlight>
* The ''counterstrike.lua'' contains similiar to the following features:
** Let players choose their team and spawn them
** Provide them with weapons, targets and instructions (maybe read from a Map, see below)
** Define the game's rules, e.g. when does the round end, what happens when a player dies
** .. and maybe some more
* The ''buymenu.lua'' is a clientside script and creates a menu to buy weapons
This example can be called a gamemode, since it not only intereferes with the gameplay, but actually defines the rules of it. The ''type'' attribute indicates that this example works with the [[Map manager]], yet another resource that was written by the QA Team to manage gamemodes and map loading. It is highly recommended that you base your gamemodes on the techniques it provides.
This also means that the gamemode probably won't run without a map. Gamemodes should always be as generic as possible. An example for a map is stated in the next example.
====Third example - A Map====
<syntaxhighlight lang="xml">
/cs-airport
/meta.xml
/airport.map
/airport.lua
</syntaxhighlight>
<syntaxhighlight lang="xml">
<meta>
<info author="Someguy" description="Counterstrike airport map" type="map" gamemodes="counterstrike" />
<map src="airport.map" />
<script src="airport.lua" />
</meta>
</syntaxhighlight>
* The ''airport.map'' in a XML file that provides information about the map to the gamemode, these may include:
** Where the players should spawn, with what weapons, what teams there are
** What the targets are
** Weather, World Time, Timelimit
** Provide vehicles
* The ''airport.lua'' might contain map-specific features, that may include:
** Opening some door/make something explode when something specific happens
** Create or move some custom objects, or manipulate objects that are created through the .map file
** .. anything else map-specific you can think of
As you can see, the ''type'' attribute changed to 'map', telling the [[Map manager]] that this resource is a map, while the ''gamemodes'' attribute tells it for which gamemodes this map is valid, in this case the gamemode from the above example.
What may come as a surprise is that there is also a script in the Map resource. Of course this is not necessarily needed in a map, but opens a wide range of possibilities for map makers to create their own world within the rules of the gamemode they create it for.
The ''airport.map'' file might look similiar to this:
<syntaxhighlight lang="xml">
<map mode="deathmatch" version="1.0">
<terrorists>
<spawnpoint posX="2332.23" posY="-12232.33" posZ="4.42223" skins="23-40" />
</terrorists>
<counterterrorists>
<spawnpoint posX="2334.23443" posY="-12300.233" posZ="10.2344" skins="40-50" />
</counterterrorists>
<bomb posX="23342.23" posY="" posZ="" />
<vehicle posX="" posY="" posZ="" model="602" />
<vehicle posX="" posY="" posZ="" model="603" />
</map>
</syntaxhighlight>
When a gamemode is started with a map, the map resources is automatically started by the mapmanager and the information it contains can be read by the gamemode resource. When the map changes, the current map resource is stopped and the next map resource is started. For a more in-depth explanation and examples of how map resources are utilized in the main script, please visit the [[Writing Gamemodes]] page.
===Events===
[[Event|Events]] are the way MTA tells scripts about things that happen. For example when a player dies, the [[onPlayerWasted]] event is triggered. In order to perform any actions when a player dies, you have to prepare yourself similiar to adding a command handler, as shown in [[#Writing_the_script|the first chapter]].
This example will output a message with the name of the player who died:
<syntaxhighlight lang="lua">
function playerDied(totalAmmo, killer, killerWeapon, bodypart)
outputChatBox(getPlayerName(source).." died!")
end
addEventHandler("onPlayerWasted",getRootElement(),playerDied)
</syntaxhighlight>
Instead of showing what arguments are needed, the documentation page for Events shows what parameters are passed to the handler function, similiar to the way a [[#About_command_handlers|command handler]] does, just that it is different from event to event. Another important point is the ''source'' variable, that exists in handler functions. It doesn't have to be added to the parameter list of the function, but it still exists. It has a different value from event to event, for player events (as in the example above) it is the player element. As another example, you can take a look at the basic spawning player script in the first section to get an idea how ''source'' is used.
==Where to go from here==
You should now be familiar with the most basic aspects of MTA scripting and also a bit with the documentation. The [[Main Page]] provides you with links to more information, Tutorials and References that allow a deeper look into the topics you desire to learn about.
{{note|From here we recommend reading the [[debugging]] tutorial. Good debugging skills are an absolute necessity when you are making scripts. We also recommend you to use the [[predefined variables list]] to help you with certain tasks and make scripting easier and faster.}}
'''See also:'''
* [[OOP_Introduction|OOP Scripting Introduction]]
* [[Advanced Topics]]
* [[Script_security|Script security]]
* [[Scripting Introduction Urdu]]
[[es:Introducción a la Programación]]
[[it:Introduzione allo scripting]]
[[nl:Scripting_introductie]]
[[pt-br:Introdução ao Scripting]]
[[ru:Scripting Introduction]]
[[ar:مقدمه_في_البرمجه]]
[[zh-cn:脚本编写介绍]]
[[Category:Tutorials]]

Revision as of 19:28, 26 January 2016

A resourcezek egy nagy része az MTAnak. A resource lényegében egy mappa vagy egy zip ami tartalmazza a fájlokat, plusz egy meta fájlt, ami leírja a szervernek, hogy a resource hogyan legyen betöltve, és milyen fájlokat tartalmaz. A resource részben egyező egy programhoz, ami az operációs rendszerünkön fut - lelehet állítani, és ellehet indítani, és egyszerre több resource is futhat.

Minden ami a scripteléssel foglalkozik, a resourcekben történik, amit a resource tesz határozza meg, hogy az egy játéktípus, egy map vagy bármi más. Az MTA tartalmaz scripteket, amiket opcionálisan fel is használhatsz, mint pl egy map korlátozás, hogy csak a játszható térben lehess vagy vagy deathpickupok, amivel létrehozhatunk fegyver felvételi pontokat.

[[{{{image}}}|link=|]] Tip: Az első lépés, ahhoz, hogy elkezdj scriptelni, hogy használj egy LUA szerkesztőt. Ez megkönnyíti a scriptelést. Ajánljuk a Sublime Text, a Notepad++ vagy a LuaEdit programot. Van egy nem hivatalos MTA Script Szerkesztő (fejlesztési státuszban, de nem tudok arról, hogy még fejlesztik) amit kipróbálhatsz.

Egy működő script készítés

Először megfogunk tanulni egy olyan alap script készítését, ami által a karakterünk képes a városban sétálni lépésről lépésre.

Hol találjuk meg a scripteket?

Először is tekintsük meg a script fájlok szerkezetét. Menj az MTA szerver mappájába és kövesd a következő az útvonalat: server/mods/deathmatch/resources/

Itt találni fogsz egy csomó .zip fájlt, amik az általános tömörített scriptek, amit az MTA szolgáltat. Minden fájl egy "resource", az összes kilesz csomagolva és ellesz indítva, a szerver által, amikor az elindul. Ahhoz, hogy létrehozzuk a saját resourceunkat csak szimplán létre kell hoznunk egy általunk kedvelt névvel ellátott mappát. Mi most az "enszerverem" mappa nevet fogjuk használni az oktatáshoz.

Most ebben a könyvtárban kell lenned:

server/mods/deathmatch/resources/enszerverem

A resourceok azonosítása

Ahhoz, hogy a szerver tudja, hogy mi van a resourceban, szükségünk lesz egy meta.xml fájlra a tartalmazott fájlokkal. Ennek a resource főkönyvtárában kell elhelyezkednie, ami az "enszerverem" az esetünkben. Szóval hozz létre egy szöveges dokumentumot, majd nevezd át "meta.xml"-re, és nyisd meg notepaddal.

Írd be a következő kódot a meta.xml fájlba.

<meta>
      <info author = "A neved" type = "gamemode" name = "A szerverem" description = "Az első MTA szerverem"/>
      <script src = "script.lua"/>
</meta>

Az <info/> címkében láthatsz egy "type" mezőt ami eldönti, hogy ez a resource egy játéktípus, és nem egy map, vagy egy script, ami később lesz elmagyarázva. A játéktípus kell nekünk, hogy egy önálló szervert tudjunk létrehozni.

A <script/> címke dönti el azokat a script fájlokat, amit a resource tartalmaz. Ezeket fogjunk elkészíteni következőnek.

Egy egyszerű script létrehozása

Ne feledd, hogy a <script/> címkében a .lua nincs egy másik könyvtárban. Ez miatt ugyan ott fogjuk létrehozni, mint ahol a meta.xml-t. Most már betudod másolni a következő kódot a script.lua fájlodba.

local spawnX, spawnY, spawnZ = 1959,55, -1714,46, 10
function csatlakozasKezelo()
	spawnPlayer(source, spawnX, spawnY, spawnZ)
	fadeCamera(source, true)
	setCameraTarget(source, source)
	outputChatBox ("Üdvözöllek a szerveremen.", source)
end
addEventHandler ("onPlayerJoin", getRootElement (), csatlakozasKezelo)

A script lespawnol minket a koordinátára ( x, y, z ), amit feljebb adtunk meg, amikor csatlakozunk a játékhoz. Ne feledjük, hogy a fadeCamera funkció szükséges, vagy különben fekete lesz a képernyő. Szintúgy, a DP2 kiadása után be kell állítanunk a kamera célját (különben minden játékos a kék eget fogja látni.)

A source változó jelenti, hogy ki hívta meg az eseményt. Mivel egy játékos csatlakozott, amikor a kódunk meglett hívva, ezért ezt a változót használjuk, hogy megnézzük, hogy ki csatlakozott. Ez miatt nem fog mindenkit lespawnolni, vagy egy véletlenszerű játékost.

Ha egy közelebbi pillantást vetünk az addEventHandler-re, akkor láthatunk 3 dolgot: "onPlayerJoin", ami azt jelzi, hogy mikor legyen meghívva. getRootElement(), ami azt jelzi, hogy ki/mi által lehet meghívva. (A getRootElement() mindent/mindenkit jelent.) És joinHandler, ami azt jelzi, hogy melyik funckió legyen lefuttatva, az esemény meghívása után. Egyéb részletek hamarosan le lesznek írva egy másik példában, most indítsuk el a szerverünket, és próbáljuk ki!

A script futtatása

Ahhoz, hogy a szervert elindítsuk, egyszerűen indítsuk el az "MTA Server" fájlt a server/ mappában. Egy lista fog kijönni először, a szerver adataival; jegyezd meg a port számát, ami a kapcsolódáshoz lesz szükséges. Ezután a szerver betölti a resourceokat a server/mods/deathmatch/resources/ mappából, és ezután "kész a csatlakozásokra".

Mielőtt kapcsolódnál a szerverre, el kell indítani a játékmódunkat. Írd be a "start enszerverem", parancsot, és nyomj entert. A szerver elindítja a játékmódot, amit létrehoztál, ettől a ponttól kezdve a hibákat és a figyelmeztetéseket is írni fogja. Most már elindíthatod az MTA klienst, majd a "Qyors Csatlakozás" gombbal csatlakozhatsz is az előbb látott IP-vel és porttal. Ha minden jól megy, pár másodperc múlva a karaktered megjelenik, és Los Santos utcáin járkál.

Következőnek egy parancsot fogunk létrehozni, amivel képesek leszünk egy kocsit létrehozni a helyzetünkön. Lehet, hogy kiszeretnéd ezt hagyni, és a haladó scriptelést szeretnéd megismerni a Map Manager, használatával, ami ezt az oktatást folytatja. Egy másik ág a Bevezetés a GUI scriptelésbe, ami megmutatja hogy hogyan hozunk létre Grafikus Felhasználói Felületet MTAn belül.

Egy egyszerű parancs létrehozása

Menjünk vissza a script.lua fájl tartalmához. Ahogy említettük feljebb, egy parancsot akarunk szolgáltatni, amivel egy kocsit lehet létrehozni a jelenlegi helyzeteden. Először, létre kell hoznunk egy funkciót, amit megakarunk hívni és egy parancskezelőt, ami létrehozza a parancsot, amit a játékos betud írni a konzolba.

-- A funckió létrehozása, ezekkel az argumentumokkal: thePlayer, command, vehicleModel
function jarmuLetrehozasaJatekosnak(thePlayer, command, vehicleModel)
   -- A jármű létrehozása és még pár dolog
end

-- A parancskezelő létrehozása
addCommandHandler("jarmuletrehozas", jarmuLetrehozasaJatekosnak)

Megjegyzés: A funckió nevek megnyomhatóak a példákban, és a wikin elhelyezkedő funkció leírására dobnak.

A parancskezelőkről

Az első argumentuma az addCommandHandler funckiónak a parancs neve, amit a játékos betud majd írni, a második argumentuma amit ez megfog hívni, az esetünkben a jarmuLetrehozasaJatekosnak.

Ha már van némi tudásod a scriptelésben, akkor tudni fogod, hogy így hívjuk meg a funckiókat:

funckioNeve(argumentum1, argumentum2, argumentum3, ..)
funkcioNeve(thePlayer, parancsNeve, argumentum3, ..)

Ha egy közelebbről megnézzük az alsó példát felettünk láthatjuk, hogy az argumentum1 a thePlayer és az argumentum2 a commandName. thePlayer simán az az egy, aki beírta a parancsot, szóval, akárminek nevezed el, ez a változó fogja tartalmazni a játékost, aki aktiválta a parancsot. A commandName simán a parancs, amit beírtak. Szóval ha beírták a "/üdvözlet", parancsot akkor ez az argumentum tartalmazza az "üdvözlet" szöveget. Az argumentum3 az plusz dolog, amit a játékos beírt. Erről egy kicsit később fogsz tanulni az oktatásban. Soha ne felejtsd el, hogy az első kettő argumentum standard, de akárminek elnevezheted.

Mi már meghívtuk az addCommandHandler funckiót ilyen módon, és mióta a jarmuLetrehozasaJatekosnak is egy ilyen funckió, ezért ilyen módon meghívható ő is. De e helyett mi egy parancskezelőt használunk, ami hasonló módon hívja meg.

Például: Valaki beírja a "jarmuletrehozas 468" parancsot a játék konzoljába, hogy lehívjon egy Sanchezt, a parancskezelő meghívja a "jarmuLetrehozasaJatekosnak" funkciót, az olyan mintha ezt a sort raktuk volna a scriptbe:

jarmuLetrehozasaJatekosnak(thePlayer,"jarmuletrehozas","468") -- A thePlayer a játékos, aki beírta a parancsot

Ahogy láthatjuk, ez pár paramétert szolgáltat: A játékost, aki beírta a parancsot, a parancsot, amit beírt és minden más szöveget, amit utána beírt, ebben a példában a "468" ami a Sanchez IDje a játékban. Az első kettő paraméter mindig ugyan az a parancskezelőknél, amit elolvashatsz az addEventHandler oldalnál. Ez miatt, mindig minimum kettő paramétert kell meghatározni, hogy akármi mást tudsz utána használni (például, ahhoz, hogy egy szöveget beolvassunk a parancs beírása után, a mi példánkban a jármű model IDje).

Megjegyzés: Minden esetben a funckió létrehozása UTÁN kell definiálni a parancskezelőt, különben nem fogja megtalálni. A meghívások sorrendje számít.

A funckió megírása

Ahhoz, hogy feltöltsük azt a funkciót, amit írtunk, először gondolkoznunk kell, hogy mit is akarunk csinálni:

  • Lekérni a játékos pozícióját, hogy megtudjuk, hogy hova is rakjuk le a kocsit (azt akarjuk, hogy pontosan a játékosnál jelenjen meg).
  • Számítsuk ki a pozíciót, ahova létrehozzuk a járművet (nem akarjuk, hogy a játékosban jelenjen meg).
  • Hozzuk létre a járművet.
  • Nézzük meg, hogy létre lett hova, vagy írjunk ki egy hibát.

Ahhoz, hogy elérjük a célunkat, szükséges lesz pár funkcióra. Ahhoz, hogy megtaláljuk a funkciókat, amikez használnunk kell, látogassunk el a Szerver Scriptelési Funckiókhoz. Először is, le kell kérnünk a játékos pozícióját. Mivel a játékosok elementek, először az Element funkcióhoz lépünk, ahol megtaláljuk a getElementPosition funckiót. A funkció nevére kattintással a listában, eljutsz a funkció leírásához. Itt láthatjuk a szintaxist, mit ad vissza, és általában egy példát. A szintaxis mutatja meg, hogy milyen argumentumokat lehet, vagy kell beírnunk.

A getElementPosition funckióhoz a szintaxis:

float, float, float getElementPosition ( element azElement )

A három float a visszaadási érték típusa. Ebben az esetben a funkció három lebegőpontos szám. (x, y és z) A zárójelekben láthatod, hogy milyen argumentumokat kell beírnod. Ebben az esetben csak az elementet, akinek leakarod kérni a pozícióját, ami a játékos a példánkban.

function jarmuLetrehozasaJatekosnak(thePlayer, command, vehicleModel)
	-- Kérjük le a koordinátát és rakjuk be az x, y, z változókban
	-- (A local azt jelenti, hgy a változó csak a jelenlegi területben létezik, ebben az esetben a funckió)
	local x, y, z = getElementPosition(thePlayer)
end

Következőnek to biztosítani akarjuk, hogy a jármű nem lesz létrehozva pontosan a játékosban szóval hozzáadunk pár egységet az x változóhoz, ami azt fogja eredményezni, hogy a játékostól keletre lesz létrehozva.

function jarmuLetrehozasaJatekosnak(thePlayer, command, vehicleModel)
	local x, y, z = getElementPosition(thePlayer) -- A játékos pozíciójának lekérése
	x = x + 5 -- 5 egység hozzáadása az "x" változóhoz
end

Now we need another function, one to spawn a vehicle. We once again search for it on the Server Functions List, this time - since we are talking about vehicles - in the Vehicle functions section, where we will choose createVehicle. In this function's syntax, we only have one return type (which is more common), a vehicle element that points to the vehicle we just created. Also, we see that some arguments are enclosed within [ ] which means that those are optional.

We already have all arguments we need for createVehicle in our function: The position we just calculated in the x,y,z variables and the model id that we provided through the command ("createvehicle 468") and can access in the function as vehicleModel variable.

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- get the position of the player
	x = x + 5 -- add 5 units to the x position
	-- create the vehicle and store the returned vehicle element in the ''createdVehicle'' variable
	local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
end

Of course this code can be improved in many ways, but at least we want to add a check whether the vehicle was created successfully or not. As we can read on the createVehicle page under Returns, the function returns false when it was unable to create the vehicle. Thus, we check the value of the createVehicle variable.

Now we have our complete script:

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- get the position of the player
	x = x + 5 -- add 5 units to the x position
	local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
	-- check if the return value was ''false''
	if (createdVehicle == false) then
		-- if so, output a message to the chatbox, but only to this player.
		outputChatBox("Failed to create vehicle.",thePlayer)
	end
end
addCommandHandler("createvehicle", createVehicleForPlayer)

As you can see, we introduced another function with outputChatBox. By now, you should be able to explore the function's documentation page yourself. For more advanced scripting, please check out the Map Manager.

What you need to know

You already read some things about resources, command handlers and finding functions in the documentation in the first paragraph, but there is much more to learn. This section will give you a rather short overview over some of these things, while linking to related pages if possible.

Clientside and Serverside scripts

You may have already noticed these or similiar terms (Server/Client) somewhere on this wiki, mostly in conjunction with functions. MTA not only supports scripts that run on the server and provide commands (like the one we wrote above) or other features, but also scripts that run on the MTA client the players use to connect to the server. The reason for this is, that some features MTA provides have to be clientside (like a GUI - Graphical User Interface), others should be because they work better and still others are better off to be serverside or just don't work clientside.

Most scripts you will make (gamemodes, maps) will probably be serverside, like the one we wrote in the first section. If you run into something that can't be solved serverside, you will probably have to make it clientside. For a clientside script for example, you would create a ordinary script file (for example called client.lua) and specify it in the meta.xml, like this:

<script src="client.lua" type="client" />

The type attribute defaults to 'server', so you only need to specify it for clientside scripts. When you do this, the clientside script will be downloaded to the player's computer once he connects to the server. Read more about Client side scripts.

More complex resources

The previous section showed briefly how to add clientside scripts to the resource, but there is also much more possible. As mentioned at the very top of this page, resources can be pretty much everything. Their purpose is defined by what they do. Let's have some theoretical resources, by looking at the files it contains, the meta.xml and what they might do:

First example - A utility script

/admin_commands
	/meta.xml
	/commands.lua
	/client.lua
<meta>
	<info author="Someguy" description="admin commands" />
	<script src="commands.lua" />
	<script src="client.lua" type="client" />
</meta>
  • The commands.lua provides some admin commands, like banning a player, muting or something else that can be used to admin the server
  • The client.lua provides a GUI to be able to perform the mentioned actions easily

This example might be running all the time (maybe even auto-started when the server starts) as it's useful during the whole gaming experience and also wont interfere with the gameplay, unless an admin decides to take some action of course.

Second example - A gamemode

/counterstrike
	/meta.xml
	/counterstrike.lua
	/buymenu.lua
<meta>
	<info author="Someguy" description="Counterstrike remake" type="gamemode" />
	<script src="counterstrike.lua" />
	<script src="buymenu.lua" type="client" />
</meta>
  • The counterstrike.lua contains similiar to the following features:
    • Let players choose their team and spawn them
    • Provide them with weapons, targets and instructions (maybe read from a Map, see below)
    • Define the game's rules, e.g. when does the round end, what happens when a player dies
    • .. and maybe some more
  • The buymenu.lua is a clientside script and creates a menu to buy weapons

This example can be called a gamemode, since it not only intereferes with the gameplay, but actually defines the rules of it. The type attribute indicates that this example works with the Map manager, yet another resource that was written by the QA Team to manage gamemodes and map loading. It is highly recommended that you base your gamemodes on the techniques it provides.

This also means that the gamemode probably won't run without a map. Gamemodes should always be as generic as possible. An example for a map is stated in the next example.

Third example - A Map

/cs-airport
	/meta.xml
	/airport.map
	/airport.lua
<meta>
	<info author="Someguy" description="Counterstrike airport map" type="map" gamemodes="counterstrike" />
	<map src="airport.map" />
	<script src="airport.lua" />
</meta>
  • The airport.map in a XML file that provides information about the map to the gamemode, these may include:
    • Where the players should spawn, with what weapons, what teams there are
    • What the targets are
    • Weather, World Time, Timelimit
    • Provide vehicles
  • The airport.lua might contain map-specific features, that may include:
    • Opening some door/make something explode when something specific happens
    • Create or move some custom objects, or manipulate objects that are created through the .map file
    • .. anything else map-specific you can think of

As you can see, the type attribute changed to 'map', telling the Map manager that this resource is a map, while the gamemodes attribute tells it for which gamemodes this map is valid, in this case the gamemode from the above example. What may come as a surprise is that there is also a script in the Map resource. Of course this is not necessarily needed in a map, but opens a wide range of possibilities for map makers to create their own world within the rules of the gamemode they create it for.

The airport.map file might look similiar to this:

<map mode="deathmatch" version="1.0">
	<terrorists>
		<spawnpoint posX="2332.23" posY="-12232.33" posZ="4.42223" skins="23-40" />
	</terrorists>
	<counterterrorists>
		<spawnpoint posX="2334.23443" posY="-12300.233" posZ="10.2344" skins="40-50" />
	</counterterrorists>

	<bomb posX="23342.23" posY="" posZ="" />
	
	<vehicle posX="" posY="" posZ="" model="602" />	
	<vehicle posX="" posY="" posZ="" model="603" />	
</map>

When a gamemode is started with a map, the map resources is automatically started by the mapmanager and the information it contains can be read by the gamemode resource. When the map changes, the current map resource is stopped and the next map resource is started. For a more in-depth explanation and examples of how map resources are utilized in the main script, please visit the Writing Gamemodes page.

Events

Events are the way MTA tells scripts about things that happen. For example when a player dies, the onPlayerWasted event is triggered. In order to perform any actions when a player dies, you have to prepare yourself similiar to adding a command handler, as shown in the first chapter.

This example will output a message with the name of the player who died:

function playerDied(totalAmmo, killer, killerWeapon, bodypart)
	outputChatBox(getPlayerName(source).." died!")
end
addEventHandler("onPlayerWasted",getRootElement(),playerDied)

Instead of showing what arguments are needed, the documentation page for Events shows what parameters are passed to the handler function, similiar to the way a command handler does, just that it is different from event to event. Another important point is the source variable, that exists in handler functions. It doesn't have to be added to the parameter list of the function, but it still exists. It has a different value from event to event, for player events (as in the example above) it is the player element. As another example, you can take a look at the basic spawning player script in the first section to get an idea how source is used.

Where to go from here

You should now be familiar with the most basic aspects of MTA scripting and also a bit with the documentation. The Main Page provides you with links to more information, Tutorials and References that allow a deeper look into the topics you desire to learn about.

[[{{{image}}}|link=|]] Note: From here we recommend reading the debugging tutorial. Good debugging skills are an absolute necessity when you are making scripts. We also recommend you to use the predefined variables list to help you with certain tasks and make scripting easier and faster.

See also: