IT/Introduzione allo scripting: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
mNo edit summary
 
(30 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<!-- Tradotto da Shadd in data 23 Gennaio 2008.
{{IT/MainP}}
Ancora incompleto. -->
[[Category:100%]]
[[Category:IT/Concetti di scripting]]
[[Category:IT/Guide e tutorial]]
Le ''Resources'' (Risorse) sono la parte principale di MTA. Essenzialmente, una risorsa è una cartella o un archivio zip che contiene una serie di files ed un file ''meta'' che contiene informazioni su come il server deve gestire la risorsa e cosa contengono i suoi componenti. Una risorsa può essere vista come uno dei programmi che girano su un sistema operativo: può essere avviata e fermata, e più risorse possono essere eseguite contemporaneamente.
Le ''Resources'' (Risorse) sono la parte principale di MTA. Essenzialmente, una risorsa è una cartella o un archivio zip che contiene una serie di files ed un file ''meta'' che contiene informazioni su come il server deve gestire la risorsa e cosa contengono i suoi componenti. Una risorsa può essere vista come uno dei programmi che girano su un sistema operativo: può essere avviata e fermata, e più risorse possono essere eseguite contemporaneamente.


Line 40: Line 42:


====A proposito dei command handlers====
====A proposito dei command handlers====
Il primo argomento della funzione [[addCommandHandler]] è il nome del comando che il giocatore dovrà eseguire, il secondo argomento è invece la funzione che il comando attiverà, nell'esempio sopra ''createVehicleForPlayer''.
Il primo argomento della funzione [[IT/addCommandHandler|addCommandHandler]] è il nome del comando che il giocatore dovrà eseguire, il secondo argomento è invece la funzione che il comando attiverà, nell'esempio sopra ''createVehicleForPlayer''.


Se hai già un'esperienza di base nello scripting o nella programmazione, saprai già che una funzione si chiama nel seguente modo:
Se hai già un'esperienza di base nello scripting o nella programmazione, saprai già che una funzione si chiama nel seguente modo:
Line 47: Line 49:
</syntaxhighlight>
</syntaxhighlight>


Abbiamo infatti chiamato la funzione [[addCommandHandler]] in questo modo, e dato che anche ''createVehicleForPlayer'' è una funzione, può essere anche lei chiamat in tale modo. Ma stiamo invece utilizzando un command handler, che la chiama in modo simile internamente ad MTA.
Abbiamo infatti chiamato la funzione [[IT/addCommandHandler|addCommandHandler]] in questo modo, e dato che anche ''createVehicleForPlayer'' è una funzione, può essere anche lei chiamata in tale modo. Ma stiamo invece utilizzando un command handler, che la chiama in modo simile internamente ad MTA.


Ad esempio: qualcuno durante il gioco scrive "createvehicle 468" nella console per spawnare una Sanchez, il command handler chiama la funzione createVehicleForPlayer, come se avessimo avuto questa riga di codice nello script:
Ad esempio: se qualcuno durante il gioco scrivesse "createvehicle 468" nella console per spawnare una Sanchez, il command handler chiamerebbe la funzione createVehicleForPlayer, come se avessimo avuto questa riga di codice nello script:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
createVehicleForPlayer(thePlayer,"createvehicle","468") -- thePlayer è l'identificatore del giocatore che ha chiamato la funzione
createVehicleForPlayer(thePlayer,"createvehicle","468") -- thePlayer è l'identificatore del giocatore che ha chiamato la funzione
</syntaxhighlight>
</syntaxhighlight>
Come possiamo vedere, contiene diversi argomenti: il giocatore che ha chiamato il comando, il comando che ha chiamato e tutto ciò che ha scritto dopo di esso, in questo caso "468" come id per il veicolo da spawnare, una Sanchez. I primi due parametri sono gli stessi in tutti i command handlers, come puoi vedere nella pagina [[addEventHandler]]. Per questo, devi per forza definire almeno questi due parametri prima che MTA possa riconoscerne altri aggiuntivi(ad esempio, in questo caso, l'ID del veicolo).
Come possiamo vedere, contiene diversi argomenti: il giocatore che ha chiamato il comando, il comando che ha chiamato e tutto ciò che ha scritto dopo di esso, in questo caso "468" come ID per il veicolo da spawnare, una Sanchez. I primi due parametri sono gli stessi in tutti i command handlers, come puoi vedere nella pagina [[IT/addEventHandler|addEventHandler]]. Per questo, devi per forza definire almeno questi due parametri prima che MTA possa riconoscerne altri aggiuntivi(ad esempio, in questo caso, l'ID del veicolo).


''Nota: Puoi creare un command handler solo DOPO aver creato la funzione che l'handler chiemerà, altrimenti MTA non troverà la funzione e non potrà quindi eseguirla.''
''Nota: Puoi creare un command handler solo DOPO aver creato la funzione che l'handler chiamerà, altrimenti MTA non troverà la funzione e non potrà quindi eseguirla.''


====Writing the function====
====Programmare la funzione====
In order to fill the function we created, we need to think about what we have to do:
Prima di creare la funzione che utilizzeremo per il comando, dobbiamo pensare a cosa abbiamo in mente di fare:
* Get the players position, so we know where to spawn the vehicle (we want it to appear right beside the player)
* Memorizzare la posizione del giocatore, in modo da sapere dove far spawnare il veicolo (vogliamo che gli appaia vicino);
* Calculate the position we want to spawn the vehicle at (we don't want it to appear in the player)
* Calcolare la posizione in cui far spawnare il veicolo (non vogliamo che appaia ''addosso'' al giocatore);
* Spawn the vehicle
* Spawnare il veicolo;
* Check if it has been spawned successfully, or output a message
* Controllare se l'operazione ha avuto successo, altrimenti inviare un messaggio di errore.


In order to achieve our goals, we have to use several functions. To find function we need to use, we should visit the [[Scripting Functions|Server Functions List]]. First we need a function to get the players position. Since players are Elements, we first jump to the '''Element functions''' where we find the [[getElementPosition]] function. By clicking on the function name in the list, you get to the function description. There we can see the syntax, what it returns and usually an example. The syntax shows us what arguments we can or have to submit.
Per raggiungere i nostri obiettivi dovremo usare molte funzioni. Per capire quali funzioni usare, andiamo alla [[IT/Funzioni Server-side|Lista funzioni Server-side]]. Innanzitutto ci serve una funzione per ottenere la posizione del giocatore. Dato che i giocatori sono conteggiati come ''Elements''(Elementi), andiamo alla sezione '''Funzioni sugli elementi''' dove troveremo la funzione [[IT/getElementPosition|getElementPosition]]. Cliccando il nome della funzione nella lista raggiungeremo la pagina sui dettagli, dove potremo vedere la sintassi, un esempio di uso e il valore che la funzione ritorna. La sintassi ci mostra quali parametri possiamo o dobbiamo inserire nella funzione.


For [[getElementPosition]], the syntax is:
Per la funzione [[IT/getElementPosition|getElementPosition]], la sintassi è:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
float, float, float getElementPosition ( element theElement )
float, float, float getElementPosition ( element theElement )
</syntaxhighlight>
</syntaxhighlight>


The three ''float'' in front of the function name are the return type. In this case it means the function returns three floating point numbers. Within the parentheses, you can see what arguments you have to submit. In this case only the element whose position you want to get, which is the player in our example.
I tre ''float'' prima del nome della funzione sono i tipi di valore che essa ritorna, in questo caso tre numeri decimali. Dentro le parentesi possiamo invece vedere gli elementi che la funzione accetta, in questo caso solo l'elemento del quale vogliamo conoscere la posizione.


<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function createVehicleForPlayer(thePlayer, command, vehicleModel)
function createVehicleForPlayer(thePlayer, command, vehicleModel)
-- get the position and put it in the x,y,z variables
-- Ottiene le coordinate del giocatore e le memorizza nelle variabili x,y,z.
-- (local means, the variables only exist in the current scope, in this case, the function)
-- (local indica che le variabili esisteranno solo all'interno dello ''scope'' corrente, in questo caso, la funzione)
local x,y,z = getElementPosition(thePlayer)
local x,y,z = getElementPosition(thePlayer)
end
end
</syntaxhighlight>
</syntaxhighlight>


Next we want to ensure that the vehicle won't spawn directly in the player, so we add a few units to the ''x'' variable, which will make it spawn east from the player.
Ora, vogliamo assicurarci che il veicolo non compaia direttamente sopra o nel giocatore, aggiungeremo quindi qualche unità alla variabile ''x'', in modo da farlo comparire un pò più ad est del giocatore.


<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function createVehicleForPlayer(thePlayer, command, vehicleModel)
function createVehicleForPlayer(thePlayer, command, vehicleModel)
local x,y,z = getElementPosition(thePlayer) -- get the position of the player
local x,y,z = getElementPosition(thePlayer) -- otteniamo la posizione del giocatore
x = x + 5 -- add 5 units to the x position
x = x + 5 -- aggiungiamo 5 unità alla variabile x
end
end
</syntaxhighlight>
</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.
Ora abbiamo bisogno di un'altra funzione, che ci permetta di spawnare il veicolo. Cerchiamola nuovamente nella [[IT/Funzioni Server-side|Lista funzioni Server-side]], questa volta tra le '''Funzioni per veicoli''', dove sceglieremo [[IT/createVehicle|createVehicle]]. Nella sintassi di questa funzione abbiamo solo un valore di ritorno (più comune rispetto alle funzioni che ritornano più di un valore), cioé un elemento veicolo che indica il veicolo che abbiamo appena creato con la funzione stessa. Inoltre, vediamo che alcuni elementi si trovano tra parentesi quadre, ad indicare che essi sono opzionali.


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.
Abbiamo già tutti gli elementi che ci servono per chiamare [[IT/createVehicle|createVehicle]] nella nostra funzione: le coordinate che abbiamo memorizzato nelle variabili ''x,y,z'' e l'ID del veicolo che vogliamo chiamare, ottenuto tramite il comando ("createvehicle 468") ed a cui possiamo accedere tramite la variabile locale ''vehicleModel''


<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function createVehicleForPlayer(thePlayer, command, vehicleModel)
function createVehicleForPlayer(thePlayer, command, vehicleModel)
local x,y,z = getElementPosition(thePlayer) -- get the position of the player
local x,y,z = getElementPosition(thePlayer) -- otteniamo la posizione del giocatore
x = x + 5 -- add 5 units to the x position
x = x + 5 -- aggiungiamo 5 unità alla variabile x
-- create the vehicle and store the returned vehicle element in the ''createdVehicle'' variable
-- creiamo il veicolo e lo memorizziamo nella variabile ''createdVehicle''
local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
end
end
</syntaxhighlight>
</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.
Ovviamente questo codice otrebbe essere migliorato in molti modi, ma per il momento ci limiteremo ad aggiungere un controllo per verificare che il veicolo sia stato creato correttamente. Come possiamo leggere nella pagina [[IT/createVehicle|createVehicle]] sotto '''Valori di ritorno''', la funzione restituisce ''false'' quando non riesce a creare il veicolo. Controlleremo quindi il valore della variabile ''createVehicle''.


Now we have our complete script:
Ecco il nostro script completo:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function createVehicleForPlayer(thePlayer, command, vehicleModel)
function createVehicleForPlayer(thePlayer, command, vehicleModel)
local x,y,z = getElementPosition(thePlayer) -- get the position of the player
local x,y,z = getElementPosition(thePlayer) -- otteniamo la posizione del giocatore
x = x + 5 -- add 5 units to the x position
x = x + 5 -- aggiungiamo 5 unità alla variabile x
local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
-- check if the return value was ''false''
-- controlliamo se la funzione ha restituito valore "false"
if (createdVehicle == false) then
if (createdVehicle == false) then
-- if so, output a message to the chatbox, but only to this player.
-- se si, inviamo un messaggio nella chat, ma solo al giocatore che ha chiamato il comando.
outputChatBox("Failed to create vehicle.",thePlayer)
outputChatBox("Fallimento nella creazione del veicolo.",thePlayer)
end
end
end
end
Line 120: Line 122:
</syntaxhighlight>
</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.
Come possiamo vedere, abbiamo inserito una nuova funzione: [[IT/outputChatBox|outputChatBox]]. Adesso dovresti essere in grado di navigare tra le funzioni e documentarti su di esse da te.


==What you need to know==
==Cosa c'è da sapere==
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.
Abbiamo già letto qualcosa sulle ''resources'', sui command handlers e sulle funzioni nel primo paragrafo, ma c'è ancora molto da imparare. Questa sezione ti darà qualche delucidazione su alcuni altri elementi del LUA, e dove possibile ti verranno linkate le pagine sugli argomenti in questione.
===Clientside and Serverside scripts===
===Scripts client-side e scripts server-side===
You may have already noticed these or similiar terms (Server/Client) somwhere 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.
Avrai probabilmente già sentito i termini Server e Client da qualche parte in questa wiki, soprattutto parlando delle funzioni. MTA non supporta solo funzioni o comandi (come quello visto sopra) che funzionano su server, ma anche scripts che vengono eseguiti dal client di MTA. Il motivo di ciò è che alcune funzioni che MTA fornisce (come l'interfaccia grafica, la ''GUI'' - Graphical User Interface) possono essere eseguite solo dal client.


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:
La maggior parte degli scripts che creerai (gamemodes, e mappe) saranno probabilmente server-side, come quello che abbiamo creato nella sezione precedente. Se però ti imbatterai in qualcosa che non funzionerà sul server, dovrai ricorrere agli script client-side. Per creare uno script client-side devi creare un nuovo file .lua (ad esempio ''client.lua''), come per quelli server-side e specificarlo nel ''meta.xml'', in questo modo:
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<script src="client.lua" type="client" />
<script src="client.lua" type="client" />
</syntaxhighlight>
</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]].
L'attributo ''type'' di default è impostato sempre a ''server'', quindi avrai bisogno di specificarlo solo per gli script client-side. Quando fai ciò, lo script viene scaricato nel PC del client quando esso si connette al server. Per saperne di più vedi la [[IT/Funzioni Client-side|Lista funzioni Client-side]].


===More complex resources===
===Script più complessi===
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:
La sezione precedente spiegava in breve come aggiungere script client-side alla ''Resource'', ma si può fare molto di più. Come è spiegato a inizio pagina, con le ''resource'' si può fare praticamente tutto. Il loro scopo dipende semplicemente da ciò che fanno. Prendiamo alcune ''resource'' d'esempio, esaminando i file che contengono, il ''meta.xml'' e cosa dovrebbero fare:


====First example - A utility script====
====Primo esempio - Un ''utility'' script====
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
/admin_commands
/comandi_admin
/meta.xml
/meta.xml
/commands.lua
/comandi.lua
/client.lua
/client.lua
</syntaxhighlight>
</syntaxhighlight>
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<meta>
<meta>
<info author="Someguy" description="admin commands" />
<info author="Qualcuno" description="Comandi admin" />
<script src="commands.lua" />
<script src="comandi.lua" />
<script src="client.lua" type="client" />
<script src="client.lua" type="client" />
</meta>
</meta>
</syntaxhighlight>
</syntaxhighlight>


* The ''commands.lua'' provides some admin commands, like banning a player, muting or something else that can be used to admin the server
* ''comandi.lua'' contiene dei comandi che un admin potrà usare nel suo server per bannare i players, mutarli, o qualsiasi altra cosa
* The ''client.lua'' provides a GUI to be able to perform the mentioned actions easily
* ''client.lua'' contiene una finestra GUI per rendere tutto più gradevole alla vista e, soprattutto, agevole


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.
Questo script di esempio potrebbe restare sempre attivo (magari anche auto-avviato allo ''startup'' del server) perchè è utile durante ogni fase di gioco e non interferisce con la gamemode, a meno che un admin decida di togliere alcune azioni, ovviamente.


====Second example - A gamemode====
====Secondo esempio - Una gamemode====
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
/counterstrike
/counterstrike
Line 165: Line 167:
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<meta>
<meta>
<info author="Someguy" description="Counterstrike remake" type="gamemode" />
<info author="Qualcuno" description="Counterstrike remake" type="gamemode" />
<script src="counterstrike.lua" />
<script src="counterstrike.lua" />
<script src="buymenu.lua" type="client" />
<script src="buymenu.lua" type="client" />
Line 171: Line 173:
</syntaxhighlight>
</syntaxhighlight>


* The ''counterstrike.lua'' contains similiar to the following features:
* ''counterstrike.lua'' contiene ''features'' simili a queste:
** Let players choose their team and spawn them
** Far scegliere ai players il loro team e spawnarli
** Provide them with weapons, targets and instructions (maybe read from a Map, see below)
** Dargli delle armi, e assegnarli degli obiettivi, magari con una mappa (vedi sotto)
** Define the game's rules, e.g. when does the round end, what happens when a player dies
** Definire le regole del gioco, per esempio quando finisce un round o cosa succede quando un player muore
** .. and maybe some more
** .. e magari qualcos'altro
* The ''buymenu.lua'' is a clientside script and creates a menu to buy weapons
* ''buymenu.lua'' è uno script client-side e crea un menu GUI per comprare le armi


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.
Questo esempio può essere chiamato ''gamemode'' perchè non solo interferisce con il gioco, ma ne detta anche le regole. L'attributo ''type'' indica che questo esempio funzionerà con il [[IT/Map manager|Map manager]], un'altra ''resource'' ancora creata dal QA team per gestire le gamemode e le mappe a loro associate. È fortemente raccomandato basare la gamemode sulle tecniche che il Map Manager fornisce.


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.
Ciò significa anche che la gamemode probabilmente non girerà senza una mappa. Le gamemode, infatti, dovrebbero essere più generiche possibile. Un esempio per una mappa si può trovare qui sotto.


====Third example - A Map====
====Terzo esempio - Una mappa====
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
/cs-airport
/cs-airport
Line 191: Line 193:
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<meta>
<meta>
<info author="Someguy" description="Counterstrike airport map" type="map" gamemodes="counterstrike" />
<info author="Qualcuno" description="Counterstrike airport map" type="map" gamemodes="counterstrike" />
<map src="airport.map" />
<map src="airport.map" />
<script src="airport.lua" />
<script src="airport.lua" />
Line 197: Line 199:
</syntaxhighlight>
</syntaxhighlight>


* The ''airport.map'' in a XML file that provides information about the map to the gamemode, these may include:
* ''airport.map'' è un file XML che fornisce alla mode informazioni sulla mappa, come:
** Where the players should spawn, with what weapons, what teams there are
** I punti di spawn dei players, le loro armi, i team
** What the targets are
** Gli obiettivi
** Weather, World Time, Timelimit
** Il tempo atmosferico, l'ora del giorno, il limite di tempo
** Provide vehicles
** I veicoli e gli oggetti
* The ''airport.lua'' might contain map-specific features, that may include:
* ''airport.lua'' potrebbe contenere alcune ''feature'' specifiche di una mappa:
** Opening some door/make something explode when something specific happens
** Aprire una porta/fare qualcosa di speciale quando accade un evento particolare
** Create or move some custom objects, or manipulate objects that are created through the .map file
** Creare e muovere oggetti personalizzati, o manipolare gli oggetti creati con il file .map
** .. anything else map-specific you can think of
** .. qualunque altra cosa specifica di una mappa


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.
Come potete vedere, l'attributo ''type'' è diventato 'map', per avvertire il [[IT/Map manager|Map manager]] che questa ''resource'' è una mappa, mentre l'attributo ''gamemodes'' imposta le gamemode compatibili con questa mappa, in questo caso la gamemode dell'esempio precedente.
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.
Ciò che potrebbe sembrare strano è uno script LUA in una mappa. Ovviamente non sempre serve, ma offre a chi crea una mappa la possibilità di creare un vero e proprio mondo con le regole imposte dalla gamemode.


The ''airport.map'' file might look similiar to this:
Il file ''airport.map'' potrebbe somigliare a questo:
<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<map mode="deathmatch" version="1.0">
<map mode="deathmatch" version="1.0">
Line 227: Line 229:
</syntaxhighlight>
</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.
Quando una gamemode con una mappa compatibile è avviata, la ''resource'' della mappa viene automaticamente avviata dal mapmanager, che permette alla gamemode di ''leggere'' le informazioni che contiene. Quando la mappa cambia, la ''resource'' della mappa precedente viene fermata automaticamente e viene avviata quella successiva.


===Events===
===Eventi===
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]].
Gli eventi sono il mezzo con cui MTA comunica agli script ciò che sta accadendo nel gioco. Per esempio, quando un player muore, viene chiamato l'evento [[IT/onPlayerWasted|onPlayerWasted]]. Per eseguire qualsiasi azione quando un player muore, devi imparare a creare degli ''event handlers'', com'è spiegato nel [[#Scrivere uno script|primo capitolo]].


This example will output a message with the name of the player who died:
Questo esempio scriverà nella chatbox il nome del player che è morto:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function playerDied(totalAmmo, killer, killerWeapon, bodypart)
function playerDied(totalAmmo, killer, killerWeapon, bodypart)
outputChatBox(getClientName(source).." died!")
outputChatBox(getPlayerName(source).." è morto!")
end
end
addEventHandler("onPlayerWasted",getRootElement(),playerDied)
addEventHandler("onPlayerWasted",getRootElement(),playerDied)
</syntaxhighlight>
</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.
Al posto di mostrare quali argomenti servono, la pagina di documentazione per gli eventi mostra quali parametri sono passati alla funzione a cui un evento è ''legato'' (come playerDied nell'esempio di prima), come fa un [[#A proposito dei command handlers|command handler]], solo che è diverso da evento a evento. Un altro punto importante è la variabile ''source'', che si trova nelle funzioni chiamate da un ''event handler''. Non ha bisogno di essere aggiunto nella lista di parametri della funzione, ma esiste lo stesso. Ha valori differenti da evento a evento, per gli eventi che riguardano un player (come nell'esempio di sopra) di solito è l'elemento ''player''.


==Where to go from here==
==Cosa fare dopo==
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.
Ora dovresti essere pratico con le basi dello scripting per MTA e anche un po' con la documentazione. La [[IT/Pagina principale|Pagina principale]] ti fornisce link a informazioni, tutorial e riferimenti che permettono di scoprire più a fondo gli argomenti che vuoi imparare.


[[ru:Scripting Introduction]]
[[ru:Scripting Introduction]]
[[en:Scripting Introduction]]
[[en:Scripting Introduction]]

Latest revision as of 12:30, 27 August 2009

« Torna alla Pagina principale italiana .

Le Resources (Risorse) sono la parte principale di MTA. Essenzialmente, una risorsa è una cartella o un archivio zip che contiene una serie di files ed un file meta che contiene informazioni su come il server deve gestire la risorsa e cosa contengono i suoi componenti. Una risorsa può essere vista come uno dei programmi che girano su un sistema operativo: può essere avviata e fermata, e più risorse possono essere eseguite contemporaneamente.

Tutto ciò che ha a che fare con lo scripting avviene nelle risorse, ciò che una risorsa fà dipende da se si tratta di una gamemode, una mappa o qualsiasi altra cosa.

Creare un semplice script

Innanzitutto, mettiamo caso volessimo creare uno script per aggiungere un comando 'createvehicle' che i giocatori possano usare per far spawnare un veicolo alla loro attuale posizione.

Preparazione

Come detto sopra, una risorsa è una cartella o un archivio zip, quindi prima di tutto dovremo creare una cartella. Il nome della cartella è il nome della risorsa, che viene usato per avviarla o fermarla o come riferimento negli script. Nel nostro esempio la chiameremo commands.

Ciò di cui qualsiasi risorsa ha bisogno è il file meta.xml. Nel nostro caso, vogliamo creare uno script che fornisca determinati comandi ad un giocatore, dobbiamo quindi dire al server di caricare il nostro script, che chiameremo script.lua.

Ecco il contenuto del nostro file meta.xml:

<meta>
     <info author="TuoNome" description="Alcuni semplici comandi" />
     <script src="script.lua" />
</meta>

Creiamo ora il file che conterrà il nostro script: script.lua, nella stessa cartella di meta.xml. Adesso abbiamo i seguenti files:

/commands/meta.xml
/commands/script.lua

Scrivere uno script

Iniziamo a scrivere il contenuto del file script.lua. Come sopra, vogliamo creare un comando per spawnare un veicolo nella posizione di chi esegue il comando stesso. Prima di tutto dobbiamo creare una funzione che possa essere eseguita all'esecuzione dello script, ed un command handler che dica al gioco di eseguire la nostra funzione quando il nostro comando viene chiamato.

-- Creiamo la funzione per spawnare un nuovo veicolo, con gli argomenti "thePlayer", "command" e "vehicle"
function createVehicleForPlayer(thePlayer, command, vehicle)
   -- Qui metteremo le funzioni per creare il veicolo, ottenere la posizione del giocatore eccetera
end

-- Creiamo quindi il "command handler"
addCommandHandler("createvehicle", createVehicleForPlayer)

Nota: Negli esempi di script i nomi delle funzioni sono dei link che portano alla relativa pagina per informazioni sulla funzione stessa.

A proposito dei command handlers

Il primo argomento della funzione addCommandHandler è il nome del comando che il giocatore dovrà eseguire, il secondo argomento è invece la funzione che il comando attiverà, nell'esempio sopra createVehicleForPlayer.

Se hai già un'esperienza di base nello scripting o nella programmazione, saprai già che una funzione si chiama nel seguente modo:

nomeFunzione(argomento1, argomento2, argomento3, ...)

Abbiamo infatti chiamato la funzione addCommandHandler in questo modo, e dato che anche createVehicleForPlayer è una funzione, può essere anche lei chiamata in tale modo. Ma stiamo invece utilizzando un command handler, che la chiama in modo simile internamente ad MTA.

Ad esempio: se qualcuno durante il gioco scrivesse "createvehicle 468" nella console per spawnare una Sanchez, il command handler chiamerebbe la funzione createVehicleForPlayer, come se avessimo avuto questa riga di codice nello script:

createVehicleForPlayer(thePlayer,"createvehicle","468") -- thePlayer è l'identificatore del giocatore che ha chiamato la funzione

Come possiamo vedere, contiene diversi argomenti: il giocatore che ha chiamato il comando, il comando che ha chiamato e tutto ciò che ha scritto dopo di esso, in questo caso "468" come ID per il veicolo da spawnare, una Sanchez. I primi due parametri sono gli stessi in tutti i command handlers, come puoi vedere nella pagina addEventHandler. Per questo, devi per forza definire almeno questi due parametri prima che MTA possa riconoscerne altri aggiuntivi(ad esempio, in questo caso, l'ID del veicolo).

Nota: Puoi creare un command handler solo DOPO aver creato la funzione che l'handler chiamerà, altrimenti MTA non troverà la funzione e non potrà quindi eseguirla.

Programmare la funzione

Prima di creare la funzione che utilizzeremo per il comando, dobbiamo pensare a cosa abbiamo in mente di fare:

  • Memorizzare la posizione del giocatore, in modo da sapere dove far spawnare il veicolo (vogliamo che gli appaia vicino);
  • Calcolare la posizione in cui far spawnare il veicolo (non vogliamo che appaia addosso al giocatore);
  • Spawnare il veicolo;
  • Controllare se l'operazione ha avuto successo, altrimenti inviare un messaggio di errore.

Per raggiungere i nostri obiettivi dovremo usare molte funzioni. Per capire quali funzioni usare, andiamo alla Lista funzioni Server-side. Innanzitutto ci serve una funzione per ottenere la posizione del giocatore. Dato che i giocatori sono conteggiati come Elements(Elementi), andiamo alla sezione Funzioni sugli elementi dove troveremo la funzione getElementPosition. Cliccando il nome della funzione nella lista raggiungeremo la pagina sui dettagli, dove potremo vedere la sintassi, un esempio di uso e il valore che la funzione ritorna. La sintassi ci mostra quali parametri possiamo o dobbiamo inserire nella funzione.

Per la funzione getElementPosition, la sintassi è:

float, float, float getElementPosition ( element theElement )

I tre float prima del nome della funzione sono i tipi di valore che essa ritorna, in questo caso tre numeri decimali. Dentro le parentesi possiamo invece vedere gli elementi che la funzione accetta, in questo caso solo l'elemento del quale vogliamo conoscere la posizione.

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	-- Ottiene le coordinate del giocatore e le memorizza nelle variabili x,y,z.
	-- (local indica che le variabili esisteranno solo all'interno dello ''scope'' corrente, in questo caso, la funzione)
	local x,y,z = getElementPosition(thePlayer)
end

Ora, vogliamo assicurarci che il veicolo non compaia direttamente sopra o nel giocatore, aggiungeremo quindi qualche unità alla variabile x, in modo da farlo comparire un pò più ad est del giocatore.

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- otteniamo la posizione del giocatore
	x = x + 5 -- aggiungiamo 5 unità alla variabile x
end

Ora abbiamo bisogno di un'altra funzione, che ci permetta di spawnare il veicolo. Cerchiamola nuovamente nella Lista funzioni Server-side, questa volta tra le Funzioni per veicoli, dove sceglieremo createVehicle. Nella sintassi di questa funzione abbiamo solo un valore di ritorno (più comune rispetto alle funzioni che ritornano più di un valore), cioé un elemento veicolo che indica il veicolo che abbiamo appena creato con la funzione stessa. Inoltre, vediamo che alcuni elementi si trovano tra parentesi quadre, ad indicare che essi sono opzionali.

Abbiamo già tutti gli elementi che ci servono per chiamare createVehicle nella nostra funzione: le coordinate che abbiamo memorizzato nelle variabili x,y,z e l'ID del veicolo che vogliamo chiamare, ottenuto tramite il comando ("createvehicle 468") ed a cui possiamo accedere tramite la variabile locale vehicleModel

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- otteniamo la posizione del giocatore
	x = x + 5 -- aggiungiamo 5 unità alla variabile x
	-- creiamo il veicolo e lo memorizziamo nella variabile ''createdVehicle''
	local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
end

Ovviamente questo codice otrebbe essere migliorato in molti modi, ma per il momento ci limiteremo ad aggiungere un controllo per verificare che il veicolo sia stato creato correttamente. Come possiamo leggere nella pagina createVehicle sotto Valori di ritorno, la funzione restituisce false quando non riesce a creare il veicolo. Controlleremo quindi il valore della variabile createVehicle.

Ecco il nostro script completo:

function createVehicleForPlayer(thePlayer, command, vehicleModel)
	local x,y,z = getElementPosition(thePlayer) -- otteniamo la posizione del giocatore
	x = x + 5 -- aggiungiamo 5 unità alla variabile x
	local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z)
	-- controlliamo se la funzione ha restituito valore "false"
	if (createdVehicle == false) then
		-- se si, inviamo un messaggio nella chat, ma solo al giocatore che ha chiamato il comando.
		outputChatBox("Fallimento nella creazione del veicolo.",thePlayer)
	end
end
addCommandHandler("createvehicle", createVehicleForPlayer)

Come possiamo vedere, abbiamo inserito una nuova funzione: outputChatBox. Adesso dovresti essere in grado di navigare tra le funzioni e documentarti su di esse da te.

Cosa c'è da sapere

Abbiamo già letto qualcosa sulle resources, sui command handlers e sulle funzioni nel primo paragrafo, ma c'è ancora molto da imparare. Questa sezione ti darà qualche delucidazione su alcuni altri elementi del LUA, e dove possibile ti verranno linkate le pagine sugli argomenti in questione.

Scripts client-side e scripts server-side

Avrai probabilmente già sentito i termini Server e Client da qualche parte in questa wiki, soprattutto parlando delle funzioni. MTA non supporta solo funzioni o comandi (come quello visto sopra) che funzionano su server, ma anche scripts che vengono eseguiti dal client di MTA. Il motivo di ciò è che alcune funzioni che MTA fornisce (come l'interfaccia grafica, la GUI - Graphical User Interface) possono essere eseguite solo dal client.

La maggior parte degli scripts che creerai (gamemodes, e mappe) saranno probabilmente server-side, come quello che abbiamo creato nella sezione precedente. Se però ti imbatterai in qualcosa che non funzionerà sul server, dovrai ricorrere agli script client-side. Per creare uno script client-side devi creare un nuovo file .lua (ad esempio client.lua), come per quelli server-side e specificarlo nel meta.xml, in questo modo:

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

L'attributo type di default è impostato sempre a server, quindi avrai bisogno di specificarlo solo per gli script client-side. Quando fai ciò, lo script viene scaricato nel PC del client quando esso si connette al server. Per saperne di più vedi la Lista funzioni Client-side.

Script più complessi

La sezione precedente spiegava in breve come aggiungere script client-side alla Resource, ma si può fare molto di più. Come è spiegato a inizio pagina, con le resource si può fare praticamente tutto. Il loro scopo dipende semplicemente da ciò che fanno. Prendiamo alcune resource d'esempio, esaminando i file che contengono, il meta.xml e cosa dovrebbero fare:

Primo esempio - Un utility script

/comandi_admin
	/meta.xml
	/comandi.lua
	/client.lua
<meta>
	<info author="Qualcuno" description="Comandi admin" />
	<script src="comandi.lua" />
	<script src="client.lua" type="client" />
</meta>
  • comandi.lua contiene dei comandi che un admin potrà usare nel suo server per bannare i players, mutarli, o qualsiasi altra cosa
  • client.lua contiene una finestra GUI per rendere tutto più gradevole alla vista e, soprattutto, agevole

Questo script di esempio potrebbe restare sempre attivo (magari anche auto-avviato allo startup del server) perchè è utile durante ogni fase di gioco e non interferisce con la gamemode, a meno che un admin decida di togliere alcune azioni, ovviamente.

Secondo esempio - Una gamemode

/counterstrike
	/meta.xml
	/counterstrike.lua
	/buymenu.lua
<meta>
	<info author="Qualcuno" description="Counterstrike remake" type="gamemode" />
	<script src="counterstrike.lua" />
	<script src="buymenu.lua" type="client" />
</meta>
  • counterstrike.lua contiene features simili a queste:
    • Far scegliere ai players il loro team e spawnarli
    • Dargli delle armi, e assegnarli degli obiettivi, magari con una mappa (vedi sotto)
    • Definire le regole del gioco, per esempio quando finisce un round o cosa succede quando un player muore
    • .. e magari qualcos'altro
  • buymenu.lua è uno script client-side e crea un menu GUI per comprare le armi

Questo esempio può essere chiamato gamemode perchè non solo interferisce con il gioco, ma ne detta anche le regole. L'attributo type indica che questo esempio funzionerà con il Map manager, un'altra resource ancora creata dal QA team per gestire le gamemode e le mappe a loro associate. È fortemente raccomandato basare la gamemode sulle tecniche che il Map Manager fornisce.

Ciò significa anche che la gamemode probabilmente non girerà senza una mappa. Le gamemode, infatti, dovrebbero essere più generiche possibile. Un esempio per una mappa si può trovare qui sotto.

Terzo esempio - Una mappa

/cs-airport
	/meta.xml
	/airport.map
	/airport.lua
<meta>
	<info author="Qualcuno" description="Counterstrike airport map" type="map" gamemodes="counterstrike" />
	<map src="airport.map" />
	<script src="airport.lua" />
</meta>
  • airport.map è un file XML che fornisce alla mode informazioni sulla mappa, come:
    • I punti di spawn dei players, le loro armi, i team
    • Gli obiettivi
    • Il tempo atmosferico, l'ora del giorno, il limite di tempo
    • I veicoli e gli oggetti
  • airport.lua potrebbe contenere alcune feature specifiche di una mappa:
    • Aprire una porta/fare qualcosa di speciale quando accade un evento particolare
    • Creare e muovere oggetti personalizzati, o manipolare gli oggetti creati con il file .map
    • .. qualunque altra cosa specifica di una mappa

Come potete vedere, l'attributo type è diventato 'map', per avvertire il Map manager che questa resource è una mappa, mentre l'attributo gamemodes imposta le gamemode compatibili con questa mappa, in questo caso la gamemode dell'esempio precedente. Ciò che potrebbe sembrare strano è uno script LUA in una mappa. Ovviamente non sempre serve, ma offre a chi crea una mappa la possibilità di creare un vero e proprio mondo con le regole imposte dalla gamemode.

Il file airport.map potrebbe somigliare a questo:

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

Quando una gamemode con una mappa compatibile è avviata, la resource della mappa viene automaticamente avviata dal mapmanager, che permette alla gamemode di leggere le informazioni che contiene. Quando la mappa cambia, la resource della mappa precedente viene fermata automaticamente e viene avviata quella successiva.

Eventi

Gli eventi sono il mezzo con cui MTA comunica agli script ciò che sta accadendo nel gioco. Per esempio, quando un player muore, viene chiamato l'evento onPlayerWasted. Per eseguire qualsiasi azione quando un player muore, devi imparare a creare degli event handlers, com'è spiegato nel primo capitolo.

Questo esempio scriverà nella chatbox il nome del player che è morto:

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

Al posto di mostrare quali argomenti servono, la pagina di documentazione per gli eventi mostra quali parametri sono passati alla funzione a cui un evento è legato (come playerDied nell'esempio di prima), come fa un command handler, solo che è diverso da evento a evento. Un altro punto importante è la variabile source, che si trova nelle funzioni chiamate da un event handler. Non ha bisogno di essere aggiunto nella lista di parametri della funzione, ma esiste lo stesso. Ha valori differenti da evento a evento, per gli eventi che riguardano un player (come nell'esempio di sopra) di solito è l'elemento player.

Cosa fare dopo

Ora dovresti essere pratico con le basi dello scripting per MTA e anche un po' con la documentazione. La Pagina principale ti fornisce link a informazioni, tutorial e riferimenti che permettono di scoprire più a fondo gli argomenti che vuoi imparare.