Worms 4 Tweaking
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Worms 4 Tweaking

Le tweaking ou comment créer ses armes au delà de l'usine d'armes
 
AccueilPortailRechercherDernières imagesS'enregistrerConnexion

 

 [Débuter en Lua] Les fonctions et les données

Aller en bas 
2 participants
AuteurMessage
WormsS
Membre
WormsS


Nombre de messages : 555
Age : 26
Localisation : data/scripts
Date d'inscription : 28/06/2009

[Débuter en Lua] Les fonctions et les données Empty
MessageSujet: [Débuter en Lua] Les fonctions et les données   [Débuter en Lua] Les fonctions et les données EmptyLun 09 Nov 2015, 09:09

Bonjour à tous ! Very Happy

Je ne peux que me réjouir de cette récente réorganisation du forum. Ayant beaucoup trafiqué les scripts Lua ces deux dernières années, j'ai appris au fil du temps à comprendre et à coder aisément ce langage. Je compte donc vous faire une petite série de tutoriels sur ce que je sais du Lua (tant qu'à connaître, mieux vaut partager).

C'est compliqué de parler Lua sur ce forum. Il n'y a que très peu de personnes qui s'y sont intéressé de près finalement: ce cher _Kilburn et C++ Tomato aux débuts du forum, et bien sûr EasyTwk. Et puis y'a moi, mais que bieeeen plus tard ! Le Lua ça a toujours été considéré dans l'inconscient collectif du forum comme quelque chose qu'il est difficile de manipuler, mais ouvrant d'énormes possibilités. Bref, mon but dans cette prochaine série de tutoriels (car je ne compte pas me contenter de simplement celui-là) ça va être de faire découvrir le lua à ceux qui souhaitent se pencher dessus. (Du moins, le lua de Worms 4, car en soi c'est un vrai langage de programmation, moi je ne vous apprendrai que les choses utiles à savoir en lua dans le contexte de W4.)
Bref, comme peu de personnes ont de connaissances dessus, je n'ai pas d'autre choix que de faire un prélude sur les bases à avoir avant de parler lua sérieusement. Du coup je vais expliquer ce que sont les fonctions et les données.


Quelques bases

Avant toute chose, vous devez savoir un peu comment marche le lua dans W4. Au lancement d'une partie, le jeu va charger plusieurs fichiers:

  • La map sur laquelle vous jouez.
  • Le fichier databank correspondant à la map.
  • Le fichier Lua correspondant à la partie. Pour tout ce qui est partie rapide ou deathmatch classique, c'est le mode dit "Standard VS", qui correspond à stdvs.lua. Pour tout ce qui est des missions un joueur, c'est le fichier lua correspondant au nom anglais de la mission (par ex: SneakyBridgeThieves.lua qui correspond à la mission Voleurs de ponts.)
  • Les bibliothèques de fonctions correspondantes. Le fichier lib_help.lua est toujours chargé, et pour le mode Standard VS, la libraire stdlib.lua est chargée également. Dans ces bibliothèques se trouvent des fonctions que l'on peut appeler à un moment précis du jeu ; on reverra ça plus tard.


I - Les fonctions

De manière générale, le fichier lua est là pour décrire le déroulement de la partie. Vous aurez remarqué que chaque mission diffère dans son objectif et son déroulement: tout est dans le fichier lua correspondant. Par exemple, dans certaines missions vous devez tuer tous les ennemis pour gagner ; dans d'autres vous devrez récupérer un objet, ce genre de choses. C'est aussi dans le fichier lua qu'on va dire au jeu ce qu'il doit se passer lors d'un "événement" précis: lorsqu'un worm meurt, lorsque le tour se termine, commence, etc.
Tous ces événements sont régis par des fonctions. Une fonction en programmation, c'est juste une séquence d'instructions que l'on appelle à un moment donné. Ben dans le cas de W4, lorsque l'un de ces événements se produit (la mort d'un worm etc), le jeu appelle automatiquement la fonction qui y correspond. Ces fonctions on les retrouve un peu dans tous les fichiers lua.

On retrouve des fonctions appelées dans quasiment tous les fichiers, comme function Initialise(), qui est appelée au commencement de la partie. Si vous avez suivi ce que j'ai dit précédemment, cela paraît logique qu'elle soit dans tous les fichiers, et que les instructions de la fonction diffèrent en fonction du fichier. En effet, à chaque mission / mode de jeu l'initialisation de la partie sera différent (pas le même nombre de worms, de caisses sur le terrain etc).
On retrouve d'autres fonctions comme function Crate_Collected() qui comme son nom l'indique se fait appeler lorsque le worm ramasse une caisse.
Et comme on peut changer la liste des instructions qui se trouvent dans la fonction, on peut un peu faire ce que l'on veut à l'arrivée d'un événement précis: c'est là-dessus que sont basés la plupart des mods Lua existants (faire telle ou telle chose lorsque le worm meurt, lorsque le tour commence etc). Je ferai une annexe sur les fonctions utiles.

II - Les données

2.1. Définition

Un autre point à connaître avant de rentrer dans le lard, c'est les données. (traduction relative, ça correspond à l'anglais data. En programmation on peut aussi appeler ça une variable scalaire.)
Les données, c'est TOUT ce qu'il y a dans les fichiers XML de data/Tweak. On retrouve 51 fichiers de données différents (oui oui, les WeapTwk, PartTwk et autres dans le genre). Dans ces fichiers sont stockées des données. C'est la première chose que l'on voit lorsque l'on ouvre l'un de ces fichiers: au début du fichier, je ne vous apprend rien, on retrouve une liste exhaustive de chaque donnée que contient le fichier concerné. Par exemple, dans WeapTwk.xml, on retrouve la liste de tous les kWeapon[arme] au début.

Une chose qu'il faut bien comprendre, c'est que les données sont interactives. Cela veut dire que leur valeur peut évoluer en temps réel en fonction de l'évolution de la partie. Par exemple, au lancement d'une partie, le jeu regardera le style de partie associé ; dans un style de partie on peut paramétrer le temps d'explosion d'une mine. Ce sont deux données correspondant au temps minimum et maximum: "Mine.MinFuse" et "Mine.MaxFuse". Et bien ces données auront une valeur modifiée au début de la partie en fonction de ce que vous avez mis pour le style de partie.
Une donnée ça peut être de plusieurs types comme résumé dans ce tableau:


Type de donnéeÉcriture en XML ExempleÉcriture de l'exemple
EntierIntResources ou UintResourcesLe nombre de tir de la corde ninja est forcément un nombre entier (pas de virgule)<IntResources href='Ninja.NumShots'/>
Flottant (nombre à virgule)FloatResources Le coefficient de propulsion d'un worm lorsqu'un baril explose<FloatResources href='OilDrum.ImpulseMagnitude'/>
Chaîne de caractèreStringResources Tout ce qui est textuel: Le nom de l'arme d'équipe par ex<StringResources href='FactoryWeaponName'/>
VecteurVectorResources La direction choisie pour lancer une attaque aérienne<VectorResources href='Bomber.Direction'/>
CouleurColorResources La couleur du worm malade<ColorResources href='Sick.Colour'/>
ConteneurContainerResources N'importe quelle arme, particule, etc.. Ex: Le Bazooka<ContainerResources href='kWeaponBazooka'/>

Le type conteneur est un peu spécial: ce n'est pas une donnée "simple". Une donnée simple, y'a juste une proprété dedans, c'est sa valeur: un entier, un vecteur, etc. Dans les conteneurs, on a plusieurs propriétés, représentées par des balises. Chacune de ces balises a une valeur spéciale. Et ce n'est pas encore tout, car une propriété de conteneur peut être elle-même un autre conteneur ! C'est le cas des vêtements dans WormsAttachments.xml, où chaque "position" du vêtement est une propriété du conteneur principal, et ces positions sont elles-mêmes des conteneurs contenant leurs propres propriétés (position, taille, rotation).
Bref, les conteneurs, c'est ce que l'on manipule sans le savoir dès que l'on apprend à tweaker. On apprend que dans le conteneur kWeaponDynamite, si on s'amuse à changer la valeur de la propriété <Size>, on se retrouve avec une dynamite plus grande: c'est tout bête !


Mais après cette vaste parenthèse, revenons-en au Lua !
Avec le Lua, on a la possibilité, au moment où l'on veut, de connaître la valeur d'une donnée simple ou la valeur d'une propriété particulière d'une donnée "conteneur", et de les modifier !

2.2. Connaître et éditer une valeur - donnée simple

Pour connaître la valeur d'une donnée simple, c'est vraiment ... simple: on définit une variable qui prend la valeur de la donnée spécifiée. En lua, cela s'écrit comme ceci:
Code:
local NomDeLaVariable = GetData("NomDeLaDonnée")
À noter: pour définir une variable, théoriquement on utilise local. Mais les développeurs de Team 17 n'ont pas l'air de l'utiliser tout le temps, et en effet le jeu accepte que l'on définisse directement la variable sans local.
Notez également la syntaxe: le = signifie "prend la valeur", le GetData() est une fonction qui va chercher la valeur de la donnée: on met des parenthèses et comme le nom de la donnée est une chaîne de caractères, on met des guillemets. En Lua, les points-virgules à la fin des instructions ne sont pas obligatoires. Ils ne sont jamais utilisés dans les scripts de W4.

Concrètement, si je veux connaître par exemple la quantité d'eau qui monte lors de l'inondation, je le coderai tout simplement ainsi:
Code:
local Amount = GetData("Flood.Delta")
Car Flood.Delta est la donnée s'y référent. Le jeu renverra la valeur de cette quantité, soit 43 par défaut.

Vous allez me dire, oui mais ça sert à rien, cette quantité c'est une valeur fixe, autant mettre local Amount = 43 non ?  Suspect
Vous n'avez pas tort. Mais rappelez-vous que certaines données sont interactives et peuvent donc avoir une valeur différente en fonction des circonstances.


Pour éditer la valeur d'une donnée simple, c'est tout aussi bête. Une fonction préexistante permet de le faire, c'est SetData().
En considérant que vous voulez affecter à la donnée "NomDeLaDonnée" la nouvelle valeur "valeur", cela se code ainsi:
Code:
SetData("NomDeLaDonnée", valeur)

Par exemple, pour modifier la quantité d'eau montante lors de l'inondation, j'utilise le SetData() sur la donnée Flood.Delta:
Code:
SetData("Flood.Delta", 60)
Comme la valeur de base est 43, j'aurai une inondation un peu plus forte.
Encore mieux: si je veux par exemple doubler la quantité d'eau de l'inondation, je peux combiner habilement le SetData() et le GetData() ! Si vous avez suivi, cela donnera ceci:
Code:
SetData("Flood.Delta", 2*GetData("Flood.Delta"))
(la petite étoile c'est le "fois").

2.3. Connaître et éditer une valeur - donnée "conteneur"

Pour les conteneurs, c'est un peu différent: c'est pour ça qu'on traite les cas séparément. D'un côté ça paraît logique: Rappelez-vous des conteneurs: dedans on a plein de propriétés. Si on veut une propriété spéciale, on ne peut pas utiliser le GetData() qui renvoie juste la propriété <Value> de la donnée.
Donc en lua, on a une fonction qui permet d'ouvrir un conteneur et de visualiser ses propriétés ; tout cela sans les modifier: c'est le QueryContainer(). On définit une variable muette (ici "data") qui prend cette valeur, puis pour associer une propriété (ici "prop") particulière à une autre variable (ici "val") on utilise la syntaxe NomDeLaVariableDuQueryContainer*POINT*Propriété. C'est plus compréhensible en lisant le code:
Code:
local data = QueryContainer("NomDuConteneur")
local val = data.prop

Petit exercice ! Je veux recueillir dans une variable (appelons-la Taille) la valeur de la propriété <Size> de la donnée-conteneur "kWeaponDynamite". La variable muette de la dynamite s'appelera dyn. À vos codes !
J'espère que vous avez tous trouvé !
Solution:


L'édition maintenant ! Pour éditer la valeur d'une propriété d'une donnée de type conteneur, ça ressemble beaucoup au QueryContainer(): c'est la fonction EditContainer().
Pour utiliser cette fonction, on utilise deux variables muettes: une qui prend pour valeur le conteneur entier, comme pour le QueryContainer(), et une variable de "fermeture" dont on se préoccupe que peu ; elle est juste là pour prévenir quand est-ce qu'on arrête de modifier le conteneur.
Cela donne:
Code:
local fermeture, data = EditContainer("NomDuConteneur")
    data.prop1 = val1
    data.prop2 = val2
    ...
CloseContainer(fermeture)
Notez bien: on définit les variables muettes dans cet ordre, séparées par une virgule. Ici l'ordre entre la propriété et sa valeur est inversé par rapport au QueryContainer(), et c'est normal si on y réfléchit. Comme le = veut dire "prend la valeur", ici ce n'est plus une variable qui prend la valeur d'une propriété, mais la propriété qui prend la valeur qu'on veut.
Notez de même la fonction CloseContainer() dans laquelle on met la variable muette de fermeture définie au début. Elle a pour effet d'arrêter l'édition du conteneur. Ne jamais l'oublier.
Exemple: Pour changer le Scale et Radius de la Dynamite en 3 et 15, cela me donnera ceci:
Code:
local lock, dyn = EditContainer("kWeaponDynamite")
    dyn.Scale = 3
    dyn.Radius = 15
CloseContainer(lock)


III - Exercice

Allez allez, tous en rang, sortez vos PC. Aujourd'hui j'aimerai que vous codiez le petit exercice suivant. Au lancement d'une partie en mode "Standard VS", vous allez faire en sorte que la corde Ninja possède une infinité de coups, qu'elle soit trois fois plus longue que sa distance max de base, et que lorsqu'on la tient dans les mains la particule "WXP_AnchorsHigh" apparaisse.
C'est parti !

Quelques indications tout de même:
Le nombre de coups de la corde Ninja est une donnée entière: "Ninja.NumShots".
L'infini est représenté par la valeur -1.
La distance max de la corde Ninja est une donnée flottante: "Ninja.MaxLength".
La propriété faisant qu'une particule apparaisse lors de la sélection de l'arme est la propriété <HoldParticleFX> présente dans tous les conteneurs d'armes et d'outils.
Le conteneur de la corde Ninja est "kUtilityNinjaRope".

Allez, codez !
Vous avez encore un peu de mal ? Indices: on veut que cela se passe "Au lancement d'une partie en mode Standard VS". Rappelez-vous quelle fonction est appelée au lancement, et quel fichier lua correspond au Standard VS.
Utilisez tout ce que vous avez appris dans ce tuto.


J'espère que vous avez joué le jeu ! Voici la solution:
Solution:


Bref, et voici pour ce tutoriel sur les fonctions et les données ! Je rajouterai prochainement une annexe sur des fonctions et données existantes très utiles à modifier: par exemple, chaque worm en jeu a une donnée-conteneur associée, on peut donc la modifier en plein jeu pour jouer avec sa vie, ses attributs, etc... Vous verrez, on a plein de possibilités ! Wink

Moi je vous dis à une prochaine !
Revenir en haut Aller en bas
Easytwk
Graphiste du Forum
Easytwk


Nombre de messages : 924
Age : 30
Localisation : Zoll
Date d'inscription : 31/10/2007

[Débuter en Lua] Les fonctions et les données Empty
MessageSujet: Re: [Débuter en Lua] Les fonctions et les données   [Débuter en Lua] Les fonctions et les données EmptyLun 09 Nov 2015, 13:13

Eh bien, ça c'est un bon tutoriel ! Et complet avec ça ! Wink
Franchement bravo et merci pour le forum Very Happy

A propos, vu que tu abordes le sujet des attributs, as-tu trouvé le moyen de les éditer dynamiquement ? Il y a longtemps on en avait parlé avec _Kilburn et il me semble que lui non plus n'avait pas trouvé le moyens d'éditer les vecteurs ou les couleurs (ou tout ce qui s'édite par attribut) via le Lua.
Revenir en haut Aller en bas
http://soundcloud.com/Shlyglypotassin
WormsS
Membre
WormsS


Nombre de messages : 555
Age : 26
Localisation : data/scripts
Date d'inscription : 28/06/2009

[Débuter en Lua] Les fonctions et les données Empty
MessageSujet: Re: [Débuter en Lua] Les fonctions et les données   [Débuter en Lua] Les fonctions et les données EmptyLun 09 Nov 2015, 16:22

Merci Smile

Ah, ces fameux attributs ! J'en ai chié pour essayer de les modifier... J'ai tout essayé.
Mais le problème principal, je pense, vient du fait que le jeu "convertisse" tous les attributs en chaîne de caractères au démarrage de la partie ; je m'explique. Si j'ai un vecteur de coordonnées (1, 1, 1) et que je veux afficher sa valeur, le jeu m'affiche de mémoire: "(x=1.000000, y=1.000000, z=1.000000)". Et si je m'amuse à renvoyer le type de cette variable, le jeu me renvoie "string". J'en déduis qu'il "convertit" les vecteurs en chaîne de caractères et les rend par conséquent inutilisables. Parce que le Lua possède un type "vector" il me semble, mais le jeu ne l'utilise pas...
Je ne dis pas qu'il n'y a aucun moyen, mais je n'ai trouvé nulle part. Je suis également tombé sur un vieil article de _Kilburn sur Dream17 où il demandait de l'aide à ce propos, personne ne semblait savoir.
Revenir en haut Aller en bas
Contenu sponsorisé





[Débuter en Lua] Les fonctions et les données Empty
MessageSujet: Re: [Débuter en Lua] Les fonctions et les données   [Débuter en Lua] Les fonctions et les données Empty

Revenir en haut Aller en bas
 
[Débuter en Lua] Les fonctions et les données
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» [Débuter en Lua] Le Wormpot

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Worms 4 Tweaking :: Tutoriels et ressources :: Tutoriels :: Scripting-
Sauter vers: