FR/Introduction Programmation: Difference between revisions
m (From google trad to real french) |
|||
Line 262: | Line 262: | ||
===Événements=== | ===Événements=== | ||
MTA utilise les événements pour signaler aux scripts que des choses s'est passé dans le jeu. Par exemple quand un joueur meurt, l'évènement [[onPlayerWasted]] est déclenché. Pour exécuter n'importe quelle action quand un joueur meurt, votre script doit donner le nom de sa fonction à exécuter lorsque cet événement est déclenché par MTA grâce à la fonction [[addEventHandler]]. C'est très similaire à la fonction qui permet de déclencher une fonction via une commande. | |||
Cet exemple | Cet exemple produira un message avec le nom du joueur qui est mort : | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
function playerDied(totalAmmo, killer, killerWeapon, bodypart) | function playerDied(totalAmmo, killer, killerWeapon, bodypart) | ||
outputChatBox(getPlayerName(source).." died!") | outputChatBox(getPlayerName(source).." died!") | ||
end | end | ||
addEventHandler("onPlayerWasted",getRootElement(),playerDied) | addEventHandler("onPlayerWasted", getRootElement(), playerDied) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Au lieu de | Au lieu de lister les arguments qui sont nécessaires, la page de documentation pour un événement indique quels paramètres sont passés à la fonction que vous attachez à cet événement. Un autre point important est la variable "source", qui existe dans les fonction d'évènement. Il ne doit pas être ajoutés à la liste des paramètres de la fonction, mais elle existe quand même à l'intérieur de votre fonction. Cette variable a une valeur différente d'un événement à l'autre, pour les événements de joueurs (comme dans l'exemple au-dessus) c'est le joueur responsable de son déclenchement. Comme autre exemple, vous pouvez jeter un coup d'œil au script qui permet de faire apparaître le joueur dans la première section pour avoir une idée de comment utiliser cette variable "source". | ||
==Où aller d'ici== | ==Où aller d'ici== |
Revision as of 22:19, 7 August 2016
Les ressources sont les parties clées de MTA. Une ressource est un dossier ou un .zip qui contient plusieurs fichiers, ainsi qu'une meta qui dit au serveur comment la resource doit-elle être chargée. Une ressource peut être comparée comme un programme qu'on peut lancer ou arrêter, il est possible de lancer plusieurs ressources en même temps.
Tout ce qui a un rapport avec la programmation se passe dans les ressources, se que fait la ressource, définie si c'est un gamemode, une map or quelquechose d'autre. MTA s'installe avec des resources que vous pouvez facultativement utiliser dans vos gamemodes, comme la ressource "maplimits" pour garder les joueurs dans une certaine zone ou encore "deathpickups" pour créer des pickups pour ramasser une arme.
La première chose à faire avant de pouvoir programmer en lua, c'est de se procurer un editeur de texte qui supporte le lua. Il vous sera beaucoups plus facile que de le faire avec le bloc-note de Windows. Nous vous recommendons donc Notepad++ ou LuaEdit. Il y a aussi un logiciel non officiel MTA Script Editor ( malheureusement l'auteur ne travail plus dessus ) que vous pouvez tester.
Créer un script qui fonctionne
Nous allons voir tout d'abord comment créer un simple script étapes par étapes qui permetra aux joueurs de se deplacer dans la ville. Dans ce tutoriel, on utilisera notepadd++.
Où sont tous les scripts ?
Laissez moi d'abord vous présenter comment s'oranise une ressource. Allez dans votre dossier MTA San et et suivez le chemin suivant:
/serveur/mods/deathmatch/resources/
Vous y verez de nombreux fichier avec l'extension .zip, se sont des ressources avec à l'intérieur des exemples de scripts . Toutes les ressources chargées sont dézippé par le serveur afin de pouvoir les exécuter ( les .zip ne sont pas obligatiores, vous pouvez aussi laissez votre ressource en tant que dossier ). Pour créer votre propre ressource, créez simplement un nouveau dossier et nommez le comme vous voulez ( Ne pas utiliser d'espace, utilisez plutôt un _ ) . Nommez le "myserveur" pour ce tutoriel.
Maintenant entrez dans votre dossier. Le chemain devrait donc être
/serveur/mods/deathmatch/resources/myserveur/
Identifier votre ressource
Pour que le serveur puisse savoir ce que contient votre ressource, un fichier meta.xml doit être créé afin d'établir une liste du contenu du dossier. Cette 'meta.xml' doit être à la racine de votre ressource ( et non pas dans un autre sous-dossier ), donc dans le dossier "myserveur" dans notre cas. Donc ouvrez notepadd++, créer un nouveau fichier (Ctrl+N), puis faite "Enregistrez sous ..." (Ctrl+Alt+S), dans "Nom:" vous écrivez "meta" et dans "Type:", sélectionnez "*.xml" ( avant-dernier de la liste ), sauvegardez le dans votre dossier "myserveur".
Maintenant, ecrivez le code suivant dans votre meta.xml:
<meta> <info author="Votre Nom" type="gamemode" name="Mon serveur" description="Mon premier serveur MTA" /> <script src="script.lua" /> </meta>
Dans la balise <info />, il y a le champ "type" qui indique si la ressource est un gamemode ou une map, on y reviendra plus tard. Un gamemode est ce dont vous avez besoin pour que votre serveur est une base.
La balise <script /> indique les scripts qui sont dans la ressource, que l'on va maintenant créer.
Créer un script simple
Notez que dans la balise <script />, le fichier .lua n'est pas dans un autre sous-dossier. Donc on va créer notre script.lua au même endroit que notre meta.xml ( Reproduisez la même opération mais "Nom:" écrivez 'script' et pour "Type:" choisissez 'Lua(*.lua)' ) puis copier-coller le code suivant:
function joinHandler() local x = 1959.55 local y = -1714.46 local z = 10 spawnPlayer(source, x, y, z) fadeCamera(source, true) setCameraTarget(source, source) outputChatBox("Bienvenue sur mon serveur", source) end addEventHandler("onPlayerJoin", getRootElement(), joinHandler)
Ce script va fous faire apparître aux coordonnées (x, y, z) spécifié dans le code, lorsque vous connecterez au serveur. La fonction fadeCamera sinon l'écran restera noir. Vous devez aussi dire à la camera de suivre le joueur grâce à la fonction 'setCameraTarget' (sinon il vera une mer bleu).
La variable source indique qui 'déclenche' la fonction. Le fonction se 'déclenche' lorsqu'un joueur rejoind le serveur, vous utiliserez cette variable pour voir qui à rejoind le serveur. Donc lorsque un joueur( "la source" ) rejoindra notre serveur, on le fera apparaître aux coordonnées indiquées .
Focalisons-nous sur addEventHandler, vous pouvez voir 3 choses: 'onPlayerJoin', qui indique quand éxécuter la fonction X. getRootElement(), qui indique qui/quoi peut être déclencher la fonction (getRootElement() veut dire toutes les choses et tous les joueurs). Et enfin la fonction X à éxecuter ( ici joinHandler ). Pour les autres details, nous verrons plus tard dans d'autres exemples mais tout d'abord testons notre premier gamemode!
Lancer le gamemode
Pour lancer le serveur, lancer simplement le 'MTA Server.exe' qui se trouve dans votre dossier 'MTA San et\server'. Une liste d'info concernant le serveur apparaîtra en premier; notez le port du serveur ( 22003 par défaut ), vous en aurez besoin pour rejoindre le serveur. Après, le serveur charge toutes les ressources du dossier 'resource', et enfin "ready to accept connections!"
Avant de pouvoir vous connecter, vous devez lancer votre gamemode. Tapez "start myserver" et appuyer sur Entrer. Le serveur va alors lancer le gamemode que nous avons créé, et nous affichera aussi les erreurs s'il y en a. Maintenant, vous pouvez lancer MTA, cliquez sur "Quick Connect" et ecrivez ceci: Dans Host: le1er champ: 127.0.0.1 ou localhost ( cela signifie que vous vous connectez au serveur du pc actuel ) et le 2ème champ: le port ( ici 22003 ) et cliquez sur 'Connect'. Si tout se passe bien, après quelques secondes, vous devriez apparaître et pouvoir allez où vous voulez.
Ensuite nous allons créer une commande que les joueurs pourront utiliser pour faire apparître une voiture à coté d'eux.
Créer une commande
Revenons à l'intérieur de notre script.lua. Tout d'abord, nous devons créer une fonction qu'on pourra appeler/éxécuter grâce à notre commande et la fonction 'addCommandHandler' afin de créer la commande que les joueurs pourront taper dans le chat( T ) ou la console( F8 ).
-- On crée la fonction qui sera appelée par notre commande avec les arguments: thePlayer, command, vehicleModel function createVehicleForPlayer(thePlayer, commandName, vehicleModel) -- Ici on crée le véhicule end -- on crée la commande et on l'attache à notre fonction addCommandHandler("createVehicle", createVehicleForPlayer)
Note: Grâce au wiki, vous pouvez cliquer sur le nom des fonctions et cela vous redirigera sur la documentation de cette fonction.
A propos du addCommandHandler
Le premier argument du addCommandHandler est le nom de la commande the player will be able to enter, le second le nom de la fonction à appeler, dans notre cas, createVehicleForPlayer.
Si vous avez déjà de l'expérience dans le codage, vous savez qu'un fonction s'appelle comme ceci:
nomDeLaFonction(argument1, argument2, argument3, ..)
Si l'on regarde bien l'exemple ci-dessus, nous pouvons voir que l'argument1 est thePlayer and argument2 le commandName. thePlayer est celui qui à tapé la commande et commandName contient le nom de la commande qu'il à tapé. Donc si un joueur tape "/greet", cet argument va contenir "greet". Argument3 c'est ce que le joueur à tapé en plus de la commande, vous allez apprendre ceci dans le tutoriel. N'oubliez jamais que les deux premiers arguments sont les arguments standards, mais vous pouvez les renommé si vous voulez, seul l'ordre est important.
Par exemple: Un joueur tape "createVehicle 468" pour faire aparaître une Sanchez, la fonction addCommandHandler va appeller notre fonction createVehicleForPlayer, comme ceci:
createVehicleForPlayer(thePlayer,"createVehicle","468") -- thePlayer est l'élement joueur qui a tapé la commande
Comme nous pouvons le voir, ll fournit plusieurs paramètres: le joueur qui a tapé la commande, la commande qu'il a tapé, et n'importe quelle texte qu'il a mis après, dans notre cas, "468" comme id de la Sanchez. Les deux premiers paramètres sont les même pour tous les addCommandHandler qu'on peut retrouver sur la page du addEventHandler. Vous devez toujours définir au moins ces deux paramètres pour utiliser les arguments après eux (par exemple pour traiter le texte qui a été entré après la commande, comme dans notre exemple le modèle du véhicule).
Note: Vous devez créer la commande APRES la fonction que vous allez utiliser pour cette commande, sinon il ne trouvera pas la fonction.
Ecrire la fonction
Pour remplir notre fonction d'instructions, nous devons d'abord pensez à ce que nous devons faire:
- Récupérer la position du joueur, donc on connaitra la position où faire apparaître le véhicule (on veut le faire apparaître à droite du joueur)
- Calculer la position où faire apparître le véhicule (nous ne voulons pas que le véhicule apparaisse dans le joueur)
- Faire apparître les véhicule
- Vérifier si le véhicule a bien apparus, ou aficher un message d'erreur.
Pour ça, nous devons utiliser plusieurs fonctions. Pour trouver la fonction que nous devons utiliser, il faut aller faire un tour dans la La liste des fonctions serveur. D'abord nous avons besoin d'une fonction pour obtenir la position du joueur. Puisque les joueurs sont des éléments, nous devons allez dans la rubrique Element functions où l'on pourra trouver la fonction getElementPosition. En cliquant sur le nom de la fonction, le wiki va vous afficher sa description. On peut y voir la syntaxe, qu'est-ce que la fonction retourne. La syntaxe nous montre les argument qu'on peut ou qu'on doit envoyer.
Pour getElementPosition, la syntaxe est:
float, float, float getElementPosition ( element theElement )
Les trois float devant le nom de la fonction est le type de variable que la fonction nous retourne. Dans notre cas, la fonction retourne trois nombres à virgule(x, y et z). Dans les parenthèses, on peut voir les arguments que l'on doit envoyer, dans notre cas, l'element dont on veut récupérer la position, le joueur dans notre exemple.
function createVehicleForPlayer(thePlayer, command, vehicleModel) -- on récupère la position x,y,z dans des variables locales -- une variable locale n'existe que dans le "périmètre" actuel. Ici, les variable x, y et z sont des variables locales qui se détruiront à la fin de la fonction. local x,y,z = getElementPosition(thePlayer) end
Ensuite, il faut s'assurer que le véhicule n'apparaît pas directement dans le joueur, donc on ajoute quelques unités à la variable x, qui le fera apparaître plus à l'est par rapport au joueur.
function createVehicleForPlayer(thePlayer, command, vehicleModel) local x,y,z = getElementPosition(thePlayer) -- On prent la position du joueur qui a tapé la commande x = x + 5 -- on ajoute 5 unité sur l'axes des x end
Maintenant nous avons besoin d'une autre fonction, celle qui va faire apparaître le véhicule. Nous allons la cherché encore une fois dans la liste des fonctions serveur, mais cette fois, comme nous parlons d'un véhicule, nous devons donc aller dans la catégorieVehicle functions, où l'on va trouver la fonction createVehicle. Dans la syntaxe, nous pouvons voir que cette fonction ne retourne qu'une seule variable, le véhicule ( de type élément ) que nous venons de créer. Nous pouvons aussi voir qu'il y a des arguments entre crochets [], cela veut dire que ce sont des arguments optionels.
Nous avons déjà tous les arguments pour la fonction createVehicle dans notre fonction: La position que nous avons juste calculée dans les variables "x, y, z" et l'id du véhicule que nous avons fourni par la commande ("/createVehicle 468") et qui est stocké dans la variable vehicleModel.
function createVehicleForPlayer(thePlayer, command, vehicleModel) local x,y,z = getElementPosition(thePlayer) -- récupere la position du joueur dans les variables x, y et z x = x + 5 -- rajoute 5 unités sur x -- on crée le véhicule et on enregistre l'élément de type "vehicle" dans la variable ''createdVehicle'' local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z) end
Avec cette variable, on pourrait faire pas mal de choses sympa, mais ici nous allons juste vérifier si le véhicule à bien été créé ou non. Sur le wiki de la fonction createVehicle, il y a la partie nomée Returns, la fonction va retourner false si la voiture n'a pas été créé. Ducoups, on va regarder la valeur de la variable createdVehicle.
Voilà notre code complet:
function createVehicleForPlayer(thePlayer, command, vehicleModel) local x,y,z = getElementPosition(thePlayer) -- On prent la position du joueur qui a tapé la commande x = x + 5 -- on ajoute 5 unités à x local createdVehicle = createVehicle(tonumber(vehicleModel),x,y,z) -- on crée le véhicule demandé par le joueur et on récupère ce que nous retourne la fonction dans la variable createdVehicle -- On vérifie si la valeur retournée est égal à ''false'' ( ce qui signifie que ça n'a pas marché ) if (createdVehicle == false) then -- si c'est le cas, on affiche un message d'erreur dans la chatbox mais seulement pour le joueur. outputChatBox("Erreur lors de la création du véhicule.",thePlayer) end end addCommandHandler("createVehicle", createVehicleForPlayer)
Comme vous pouvez le voir, nous avons utilisé une nouvelle fonction: outputChatBox. Vous devriez maintenant pouvoir regarder la description de cette fonction par vous même.
Ce que vous devez savoir
Vous avez déjà lu quelques informations sur les ressources, les commandes et trouvez des fonctions dans le wiki, mais il y a encore beaucoup à apprendre. Cette section vous donnera une vue d'ensemble plutôt courte sur certaines de ces choses, tout en regardant les pages du wiki si possible.
Les scripts client et serveur
Vous pouvez avoir déjà remarqué ces termes (serveur/client) quelque part sur ce wiki, le plus souvent pour les fonctions. MTA ne supporte pas seulement les scripts exécuté par le serveur et des commandes (comme celle qu'on vien de faire) ou d'autres fonctions, mais aussi les scripts éxécuté par le client MTA, ceux des joueurs qui se connecte au serveur. La raison est que certaines fonctions de MTA doit être du coté client comme par exemple le GUI - Graphical User Interface - ( Pour tout ce qui est fenêtres, boutons, etc ), d'autres devraient être du côté client parce qu'ils fonctionnent mieux mais d'autres sont mieux pensées pour être du côté serveur ou ne fonctionne tout simplement pas du côté client.
La plupart de vos scripts (gamemodes, maps) seront surement du côté serveur, comme celui que nous avons fait tout à l'heure. Si vous vous heurtez à quelque chose qui ne peut pas être résolu du côté serveur, vous devrez probablement le faire côté client. Pour un script client, vous devriez créer un script ordinaire (par exemple appelé client.lua) et spécifié dans la meta.xml, comme ceci:
<script src="client.lua" type="client" />
L'attribut type est par defaut 'server', donc nous avons juste besoin de spécifier que c'est un script client. Lorsque vous faites ceci, le fichier va être télecharger par le joueur sur son ordinateur lorsqu'il se connecte au serveur. Plus d'infos: Client side scripts.
Ressources plus complexes
La section précédente nous a montré brièvement comment ajouter des scripts clients à la ressource. Penchons nous maintenant sur la meta.xml et ce qu'elle fait.
Premier example - Un script utile
/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>
- Le "commands.lua" fournit quelques commandes d'admin, comme le fait d'interdire un joueur, en banissant ou quelque chose d'autre ce qui peut être utilisé par l'admin du serveur
- Le "client.lua" fournit un GUI pour être capable d'exécuter les actions mentionnées facilement
Cet exemple de script doit tourner tout le temps (peut être même démarré en même temps que le serveur) car ces commandes d'admin peuvent être appelé à n'importe quelle moment.
Second example - Un gamemode
/counterstrike /meta.xml /counterstrike.lua /buymenu.lua
<meta> <info author="Quelqu'un" description="Counterstrike remake" type="gamemode" /> <script src="counterstrike.lua" /> <script src="buymenu.lua" type="client" /> </meta>
- Le "counterstrike.lua" contient des caractéristiques semblables aux dispositifs suivants :
- Laisser les joueurs choisirent leur équipe et les faire apparaître
- Leur fournir des armes, des cibles et des instructions (peut-être lues d'une carte, voir ci-dessous)
- Définir les règles du jeu, par exemple. La partie se finie, ce qui se produit quand un joueur meurt
- .. et peut-être encore plus
- Le "buymenu.lua" est un script du côté client et crée un menu pour acheter des armes
Cet exemple peut s'appeler un gamemode, il modifie le gameplay, mais définit réellement les règles de celui-ci. Le "type" attribut indique que cet exemple fonctionne avec Map Manager, encore une autre ressource qui a été écrite par l'équipe de MTA pour contrôler des gamemodes et le chargement de cartes. On recommande fortement que vous basiez vos gamemodes sur les techniques qu'il fournit.
Ceci signifie également que ce gamemode ne fonctionnera probablement pas sans carte. Les gamemodes devront toujours être aussi génériques que possible. Un exemple de gamemode utilisant une carte est énoncé dans le prochain exemple.
Troisième exemple - Une carte
/cs-airport /meta.xml /airport.map /airport.lua
<meta> <info author="Quelqu'un" description="Counterstrike airport map" type="map" gamemodes="counterstrike" /> <map src="airport.map" /> <script src="airport.lua" /> </meta>
- Le "airport.map" dans le fichier XML fournit des informations au sujet de la carte au gamemode, ceului-ci peut inclure :
- Là où les joueurs devraient apparaitre, avec quelles armes, avec quelle équipe
- Ce qui sont les cibles
- Temps, heure du monde, Limite de temps
- Fournir les véhicules
- Le airport.lua peut contenir des actions relatifs a la map comme:
- Ouvrir une certaine porte ou faire éxploser quelque chose quand une autre chose de spécifique se produit
- Créer ou déplacer quelques objets faits sur commande, ou manoeuvrez les objets qui sont créés dans le fichier .map
- .. toutes autre choses relatifs aux ojets du .map
Comme vous pouvez le voir, l'attribut "type" a été changé en 'map', pour dire au Map Manager que cette ressource est une carte, tandis que l'attribut "gamemodes" indique pour quels gamemodes cette carte est valide, dans ce cas-ci le gamemode de l'exemple de tout à l'heure. Ce qui peut venir comme une surprise est qu'il y a aussi un script dans la ressource de carte. Évidemment ce n'est pas nécessaire dans une carte, mais ouvre une large gamme de possibilités pour les créateurs de cartes.
Le "airport.map" pourrait être semblable à ceci :
<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>
Quand un gamemode est commencé avec une carte, les ressources de carte est automatiquement démaré par le mapmanager et les renseignements qu'il contient peut être lu par le gamemode. Quand la carte change, la ressource de carte actuelle est arrêtée et la ressource de carte suivante est commencée. Pour une explication plus détaillée et des exemples pour savoit comment les ressources de cartes sont utilisées dans le script principal, visitez s'il vous plaît la page Writing Gamemodes.
Événements
MTA utilise les événements pour signaler aux scripts que des choses s'est passé dans le jeu. Par exemple quand un joueur meurt, l'évènement onPlayerWasted est déclenché. Pour exécuter n'importe quelle action quand un joueur meurt, votre script doit donner le nom de sa fonction à exécuter lorsque cet événement est déclenché par MTA grâce à la fonction addEventHandler. C'est très similaire à la fonction qui permet de déclencher une fonction via une commande.
Cet exemple produira un message avec le nom du joueur qui est mort :
function playerDied(totalAmmo, killer, killerWeapon, bodypart) outputChatBox(getPlayerName(source).." died!") end addEventHandler("onPlayerWasted", getRootElement(), playerDied)
Au lieu de lister les arguments qui sont nécessaires, la page de documentation pour un événement indique quels paramètres sont passés à la fonction que vous attachez à cet événement. Un autre point important est la variable "source", qui existe dans les fonction d'évènement. Il ne doit pas être ajoutés à la liste des paramètres de la fonction, mais elle existe quand même à l'intérieur de votre fonction. Cette variable a une valeur différente d'un événement à l'autre, pour les événements de joueurs (comme dans l'exemple au-dessus) c'est le joueur responsable de son déclenchement. Comme autre exemple, vous pouvez jeter un coup d'œil au script qui permet de faire apparaître le joueur dans la première section pour avoir une idée de comment utiliser cette variable "source".
Où aller d'ici
Vous devriez maintenant être familiers avec les aspects les plus fondamentaux de MTA scripting et aussi un peu avec la documentation. Le Main_Page vous fournit des liens vers plus de renseignements, Classes de travaux dirigés et Références qui permettent un coup d'oeil plus profond dans les thèmes dont vous désirez apprendre.
D'ici nous recommandons de lire le debugging la classe de travaux dirigés. De bonnes adresses déboguantes sont une nécessité absolue quand vous faites des scripts.