Bonjour à tous chèrs confrères,
je me suis mis aux mods et à l'élaboration de ma première quête. Je me suis mis à m'interesser au scripting. J'ai lu dans un des posts que la meilleur méthode consistait à ''décortiquer'' les scripts pour en comprendre leur fonctionnement.
En cherchant, j'ai pu voir quelques exemples, pour certains bien fournis. Au final, j'ai du mal à m'y prendre pour déceler les raisons de la présence de certaines lignes, leurs applications et fonctionnalités.
Bref, vous connaissez des tutoriels pour analyser les scripts ? Même en anglais.
Je sais que de nombreux topics ici, traitent du scripting et que le forum du Ck en parle très bien. Mais j'arrive pas à assimiler le tout et à faire les liens entre les différents tutoriels. J'ai peu être loupé un truc ?
Apprendre à ''décortiquer'' les scripts
Re: Apprendre à ''décortiquer'' les scripts
Selon ce que tu as déjà vu / connu en programmation, ça peut paraître très obscur, même avec les bons tutos (en partculier avec les scripts vanilla, dont une bonne partie sont conçus pour être utilisés de différentes façons par différents objets, et au final ne sont utilisé que d'une seule façon par un seul objet, donnant l'impression que 60% du script est inutile).
Le plus simple est de poster les extraits que tu as besoin d'analyser ici avec les questions, et qu'on le décortique "ensemble". Ca servira peut-être aussi à d'éventuels futurs lecteurs.
Le plus simple est de poster les extraits que tu as besoin d'analyser ici avec les questions, et qu'on le décortique "ensemble". Ca servira peut-être aussi à d'éventuels futurs lecteurs.
Faites un feu à un homme, il aura chaud un jour.
Mettez le feu à un homme, il aura chaud jusqu'à la fin de sa vie.
Terry Pratchett
Mettez le feu à un homme, il aura chaud jusqu'à la fin de sa vie.
Terry Pratchett
Re: Apprendre à ''décortiquer'' les scripts
Salut Kesta, c'est vraiment sympa de ta part 
Je commence avec un petit script.
Une fois un compagnon mort :
1)Si j'ai bien compris, ce qui se trouve après "extends", ici "Reference Alias", désigne ce à quoi le script est attaché.
2)Si j'ai toujours bien compris, la deuxième ligne est composée dans l'ordre : Du nom du script (DialogueFollowerScript), du type de script (Property), du nom de la quête auquel ce script est attaché (DialogueFollower) et "Auto" est un terme générique.
3)A quoi correspond "Event" ? On l'utilise uniquement lors d'un événement ?
4)"OnDeath" est une fonction ?
5) Dans "Actor akKiller", que signifie "akKiller" ?
6) L'avant dernière ligne, à quoi correspond-elle ?
7) "EndEvent" Obligatoire pour dire au script de bien se terminer ?
De plus, j'ai quelques questions supplémentaires :
-Créer un script et l'ajouter à une quête ou un personnage n'est pas la même chose que de créer un fragment directement ?
-D'où viennent les propriétés dans les scripts ? Elles apparaissent à la compilation ou sont-elles crées au préalable ?
-Si admettons, je veux prendres des Septims au player pour acheter un animal, faut-il passer par un script ou un fragment ? avec un Game.GetPlayer par exemple ?
Malgré toutes ces questions, j'ai pu créer quelques événements sympa mais bon, il y a tellement de possibilités et tellement de choses qui, comme tu le dis, semblent pas utilisées.

Je commence avec un petit script.
Une fois un compagnon mort :
Code : Tout sélectionner
ScriptName FollowerDeathScript extends ReferenceAlias
DialogueFollowerScript Property DialogueFollower Auto
Event OnDeath(Actor akKiller)
DialogueFollower.DismissFollower()
EndEvent
2)Si j'ai toujours bien compris, la deuxième ligne est composée dans l'ordre : Du nom du script (DialogueFollowerScript), du type de script (Property), du nom de la quête auquel ce script est attaché (DialogueFollower) et "Auto" est un terme générique.
3)A quoi correspond "Event" ? On l'utilise uniquement lors d'un événement ?
4)"OnDeath" est une fonction ?
5) Dans "Actor akKiller", que signifie "akKiller" ?
6) L'avant dernière ligne, à quoi correspond-elle ?
7) "EndEvent" Obligatoire pour dire au script de bien se terminer ?
De plus, j'ai quelques questions supplémentaires :
-Créer un script et l'ajouter à une quête ou un personnage n'est pas la même chose que de créer un fragment directement ?
-D'où viennent les propriétés dans les scripts ? Elles apparaissent à la compilation ou sont-elles crées au préalable ?
-Si admettons, je veux prendres des Septims au player pour acheter un animal, faut-il passer par un script ou un fragment ? avec un Game.GetPlayer par exemple ?
Malgré toutes ces questions, j'ai pu créer quelques événements sympa mais bon, il y a tellement de possibilités et tellement de choses qui, comme tu le dis, semblent pas utilisées.
Re: Apprendre à ''décortiquer'' les scripts
Okay, on va y aller calmement. Pas de panique, il y a un petit résumé en 8 lignes à la fin :
Scriptname : Mot-clé par lequel on déclare un script. Avec Papyrus, ce doit toujours être le premier mot de la première ligne.
NomDuScript : Le nom de ton script. Tu peux mettre "ce que tu veux", à l'exception de noms déjà pris (que ce soit par les scripts de base, ou par des scripts de mods). D'où l'intérêt d'utiliser des nom explicites quoiqu'un peu à rallonge, et de préférence avec un préfix propre à ton mod pour prévenir toute incompatibilité. Le nom doit être exactement le même que celui du fichier .psc dans lequel est écris ton code.
Extends : Un autre mot clé, qui va indique que ton script a un "type parent". Tu peux considérer que les scripts que tu écrira auront toujours un type parent (techniquement, il est possible d'en créer de nouveau via SKSE, ou de faire des librairies qui n'ont pas besoin de parents, mais on en reparlera plus tard). Le "type parent" de ton script, C'est un concept de base en programmation objet (on parle d'héritage), que papyrus pousse à l'extrême. Un script qui "hérite" d'un autre (qui l'extend en terme papyrus) a les mêmes définitions de fonctions / variables / propriétés / events / states que son parent. Pour des scripts simples ou de base, tu peux raisonner comme si tu avais fais un copié-collé du type de base dans ton script, et que tu commençais simplement à travailler à partir de là.
TypeParent : Le nom du type parent en question. Il DOIT exister au préalable. En général, tous les scripts extends l'un des type de base du jeu, (Tree, Key, ObjectReference, ...) qui eux même extends le type Form. (Au passage, si tu regarde dans Form.psc, tu remarquera que ce dernier est un type standard défini dans le code du jeu, il n'extends aucun autre type).
Typiquement, dans Form est défini la fonction GetFormID(), qui te permet de récupérer le FormID de l'objet (la "Form" en terme de modding) auquel ce script est attaché. Si tu attache un qui extend le type Actor à un actor, tu pourra quand même appeler GetFormID() depuis ce script (Puisque le script Actor extends ObjectReference, qui lui même extends Form, dans lequel est défini ce fameux GetFormID() ).
L'héritage des script (qu'est-ce qui extend quoi) déjà défini par le jeu de base et SKSE est présenté ici : http://www.creationkit.com/index.php?ti ... pt_Objects
En général, on attache un script qui extends un Type à un objet correspondant à ce type (Un script qui extends Quest sera donc attaché à une Quest, ou à sa version "instanciée" (Le plus souvent, on attache des script qui extends ObjectReference à des objets qui sont en fait des activateurs, fournitures, potions, ... Chaque instance de cet objet agira comme si tu avait ajouté le script qui extends ObjectReference à cette instance directement.)
Cette ligne défini une "Property". Il s'agit d'une variable avec des propriétés spéciales pour papyrus.
Une variable peut être un objet complexe (comme ici, un objet de type DialogueFollowerScript qui lui même extends le type de base Quest qui lui même extends le type Form), un objet de base (comme une Form. En général les types correspondant à des éléments du jeu tel que les Quest sont également considéré comme des objets de base, bien qu'ils extends Form), ou un simple type élémentaire comme un chaine de caractère (String) un nombre entier (Int) ou décimal (Float).
On la défini simplement comme ceci :
L'intérêt d'une variable, c'est qu'elle est utilisable pour toutes tes fonctions, et se conserve.
On va s'éloigner un peu du script d'exemple à partir de maintenant pour construire notre exemple à nous à la place, ce sera plus simple pour éviter les quelques subtilités qu'il contient :
Tu as la première ligne : On défini un nouveau type ActorQuiRajeunit qui hérite du type Actor, et donc par conséquent du type ObjectReference et du type Form.
La seconde défini une variable, et l'initialise à 65 (Ce n'est pas obligatoire, on pourrait l'initialiser autrement, mais on en reparle plus tard).
On a pas encore parlé des fonctions, mais le concept est simple à comprendre : Des bouts de codes pré-écris, qui peuvent être "appelées" par ce script ou par d'autres pour faire effectuer les actions définies dans le bout de code.
Ici, Rajeunir() enlève 1 à notre variable Age, et VoirAge() affiche un message dans le coin en haut à gauche de l'écran avec le nom de notre Actor et son age.
On va ignorer le "Debug.Notification()" pour le moment (ou surtout, le pourquoi il marche), considérons juste que c'est une fonction du jeu qui permet d'afficher le texte entre parenthèses : (GetDisplayName() + " a " + Age)
On utilise ici la fonction GetName() (c'est une fonction SKSE) membre du script Form, qui permet d'obtenir le nom de l'objet auquel le script est attaché (donc ici, le nom de notre PNJ vieillissant), et un peu de bricolage pour avoir une phrase en français.
La point important, c'est qu'on ré-utilise la variable Age. Elle vaut combien ? Eh bien soit 65 si on a jamais appelé la fonction Vieillir, ou alors 65 moins le nombre de fois où la fonction Rajeunir() a été appelée. La variable Age permet donc de garder en mémoire l'age de notre PNJ.
Evidemment, la question qui titille pour l'instant c'est "Mais comment on les appelles ces fonctions ?". On en reparle avec les Events plus tard. Revenons à notre property :
Une auto property (qui est défini en rajoutant le mot-clé "Property" entre le type de la variable et son nom, et en ajoutant le mot-clé "Auto" à la fin), c'est comme une variable, sauf qu'elle :
- Est visible par les autres scripts,
- Peut-être associée à un objet existant via le CK.
Pour voir l'intérêt, il faut voir comment les script peuvent effectuer des actions, sur eux-mêmes ou sur d'autres scripts, et donc s’intéresser aux events.
Les events correspondent à des événements qui se passent en jeu, et sont les moments ou tu veux que ton script effectue une action. On va prendre l'exemple le plus classique : Un Activator, un objet que le joueur peut activer en pressant sur E, et donc le seul but est d'exécuter un portion de script correspondante :
Bon, on extends ObjectReference au lieu d'Activator. Pourquoi ? Parce qu'un objet placé dans le monde est toujours un ObjectReference. Les Objectreference sont ce avec quoi le joueur peut interagir. Petite subtilité, passons.
Bref, avec ce script attaché à notre Activator, et notre activator placé dans le monde, chaque fois que le player va l'activer en pressant sur E, le bout de code dans le bloc OnActivate va tourner. Ici on y fait rien (j'ai mis un commentaire). On va ignorer la partie entre parentheses pour le moment, j'y reviendrai.
Pour le moment, on a un activateur qui ne sert à rien, et un script qui a une fonction pour faire rajeunir un actor et une autre pour voir son age.
Revenons un peu en arrière pour reparler des properties : on va utiliser une property pour pouvoir agir sur notre actor avec notre activator :
Et voilà. Maintenant, à chaque fois que le joueur (ou n'importe quel PNJ du jeu) activera l'activator placé dans le monde, le PNJ référencé rajeunira...
La question est : Mais QUEL PNJ ?
C'est ce que tu va définir en associant ta property à un actor via le CK. C'est pour celà qu'on a mis une property, et non pas juste une variable, que l'on aurait juste écrite :
Sans les mots clés Property et Auto.
Pour faire le lien: Choisis un des PNJs, et ajoute lui le script ActorQuiRajeunit.
Une fois que c'est fait, tu vas dans les properties de ton activator, et là tu lie la property "UnPNJTropVieux" au PNJ en question. Tadaaa !
Pour le moment, on fait rajeunir un PNJ associé au choix, mais bon... ce serait quand même plus logique que ce soit le PNJ qui active notre Machine pour vieux qui rajeunisse non ? C'est possible... à condition que le PNJ en question aie le script ActorQuiRajeunit attaché à lui même.
Admettons que ce soit le cas. Dans ce cas, on va pouvoir utiliser la fameuse partie entre parentheses après OnActivate : Il s'agit d'arguments qui correspondent à l'event reçu. Chaque fois que notre activator est activé, il "sait" qui l'a activé grace à l'argument akActionRef.
On pourrait donc essayer ceci :
Tu remarques qu'on s'est finalement débarrassé de la property, et qu'à la place, on utilise l'argument akActionRef (qui agit comme une variable temporaire).
Sauf que... cet exemple ne compilera pas. En effet, akActionRef est un ObjectReference, en revanche la fonction Vieillir() n'existe que pour les ActorQuiRajeunit... et tous les ObjectReference ne sont pas des ActorQuiRajeunit !
On utilise un cast pour essayer de transformer un type en un autre :
Ici, on essaye de transformer notre ObjectReference en ActorQuiRajeunit. Si notre ObjectReference était bien un actor auquel on avait attaché notre script ActorQuiRajeunit, tout va bien. Si non... BOUM. Non, je plaisante, mais ça ne marchera pas, est tu aura une erreur dans le log papyrus te disant "Impossible d'appeler la fonction Vieillir() sur un null object". Parce que comme le cast aura échoué, (akActionRef As ActorQuiRajeunit) un considéré comme un objet "null" qui n'existe pas. C'est un peu hors sujet, mais en général on évite ce problème de cette façon :
Pour savoir ce qu'elle fait exactement, il faut aller dans le script DialogueFollowerScript, et regarder ce que fait la fonction DismissFollower()
Il y aurait encore des tonnes de points à préciser sur ce que je viens d'écrire, mais j'espère que ça répond à tes questions pour le moment.
Petit résumé :
Ecrire un script, c'est définir un nouveau "type", le plus souvent qui hérite d'un type plus basique.
Ces scripts peuvent être attachées à des objets via le CK.
Les scripts reçoivent des Events, pré-définis en fonction du/des types hérités, qui sont des événements en jeu "reçu" par l'objet auquel ils sont rattachés.
Les events sont les seuls moments auquel le script effectue du travail.
En plus de correspondre à l'action, les events ont souvent des informations additionnelles appelés arguments, utiles dans le contexte de cette action.
Les fonctions sont des portions de codes pré-écris que l'on peut utiliser dans d'autres fonctions ou dans des events. Elles sont propres au types dans lequel elles sont définies.
Les scripts peuvent interagir entre eux via des Properties : Script A peut agir sur Script B si il a une property référençant un objet auquel Script B est attaché.
Le lien entre une property définie dans un script et un véritable objet est fait via l'interface du CK.
Les interactions qu'un script peut avoir avec un autre script passent toujours par des "fonctions" (de façon explicite ou de façon un peu cachée).
La première ligne d'un script est toujours construite de cette manière :1)Si j'ai bien compris, ce qui se trouve après "extends", ici "Reference Alias", désigne ce à quoi le script est attaché.
Code : Tout sélectionner
ScriptName NomDuScript extends TypeParent
NomDuScript : Le nom de ton script. Tu peux mettre "ce que tu veux", à l'exception de noms déjà pris (que ce soit par les scripts de base, ou par des scripts de mods). D'où l'intérêt d'utiliser des nom explicites quoiqu'un peu à rallonge, et de préférence avec un préfix propre à ton mod pour prévenir toute incompatibilité. Le nom doit être exactement le même que celui du fichier .psc dans lequel est écris ton code.
Extends : Un autre mot clé, qui va indique que ton script a un "type parent". Tu peux considérer que les scripts que tu écrira auront toujours un type parent (techniquement, il est possible d'en créer de nouveau via SKSE, ou de faire des librairies qui n'ont pas besoin de parents, mais on en reparlera plus tard). Le "type parent" de ton script, C'est un concept de base en programmation objet (on parle d'héritage), que papyrus pousse à l'extrême. Un script qui "hérite" d'un autre (qui l'extend en terme papyrus) a les mêmes définitions de fonctions / variables / propriétés / events / states que son parent. Pour des scripts simples ou de base, tu peux raisonner comme si tu avais fais un copié-collé du type de base dans ton script, et que tu commençais simplement à travailler à partir de là.
TypeParent : Le nom du type parent en question. Il DOIT exister au préalable. En général, tous les scripts extends l'un des type de base du jeu, (Tree, Key, ObjectReference, ...) qui eux même extends le type Form. (Au passage, si tu regarde dans Form.psc, tu remarquera que ce dernier est un type standard défini dans le code du jeu, il n'extends aucun autre type).
Typiquement, dans Form est défini la fonction GetFormID(), qui te permet de récupérer le FormID de l'objet (la "Form" en terme de modding) auquel ce script est attaché. Si tu attache un qui extend le type Actor à un actor, tu pourra quand même appeler GetFormID() depuis ce script (Puisque le script Actor extends ObjectReference, qui lui même extends Form, dans lequel est défini ce fameux GetFormID() ).
L'héritage des script (qu'est-ce qui extend quoi) déjà défini par le jeu de base et SKSE est présenté ici : http://www.creationkit.com/index.php?ti ... pt_Objects
En général, on attache un script qui extends un Type à un objet correspondant à ce type (Un script qui extends Quest sera donc attaché à une Quest, ou à sa version "instanciée" (Le plus souvent, on attache des script qui extends ObjectReference à des objets qui sont en fait des activateurs, fournitures, potions, ... Chaque instance de cet objet agira comme si tu avait ajouté le script qui extends ObjectReference à cette instance directement.)
Pas exactement. En relisant, j'ai même envie de dire : Pas du tout2)Si j'ai toujours bien compris, la deuxième ligne est composée dans l'ordre : Du nom du script (DialogueFollowerScript), du type de script (Property), du nom de la quête auquel ce script est attaché (DialogueFollower) et "Auto" est un terme générique.

Cette ligne défini une "Property". Il s'agit d'une variable avec des propriétés spéciales pour papyrus.
Une variable peut être un objet complexe (comme ici, un objet de type DialogueFollowerScript qui lui même extends le type de base Quest qui lui même extends le type Form), un objet de base (comme une Form. En général les types correspondant à des éléments du jeu tel que les Quest sont également considéré comme des objets de base, bien qu'ils extends Form), ou un simple type élémentaire comme un chaine de caractère (String) un nombre entier (Int) ou décimal (Float).
On la défini simplement comme ceci :
Code : Tout sélectionner
Int Age
On va s'éloigner un peu du script d'exemple à partir de maintenant pour construire notre exemple à nous à la place, ce sera plus simple pour éviter les quelques subtilités qu'il contient :
Code : Tout sélectionner
Scriptname ActorQuiRajeunit Extends Actor
Int Age = 65
Function Rajeunir()
Age = Age - 1
EndFunction
Function VoirAge()
Debug.Notification(GetName() + " a " + Age)
EndFunction
La seconde défini une variable, et l'initialise à 65 (Ce n'est pas obligatoire, on pourrait l'initialiser autrement, mais on en reparle plus tard).
On a pas encore parlé des fonctions, mais le concept est simple à comprendre : Des bouts de codes pré-écris, qui peuvent être "appelées" par ce script ou par d'autres pour faire effectuer les actions définies dans le bout de code.
Ici, Rajeunir() enlève 1 à notre variable Age, et VoirAge() affiche un message dans le coin en haut à gauche de l'écran avec le nom de notre Actor et son age.
On va ignorer le "Debug.Notification()" pour le moment (ou surtout, le pourquoi il marche), considérons juste que c'est une fonction du jeu qui permet d'afficher le texte entre parenthèses : (GetDisplayName() + " a " + Age)
On utilise ici la fonction GetName() (c'est une fonction SKSE) membre du script Form, qui permet d'obtenir le nom de l'objet auquel le script est attaché (donc ici, le nom de notre PNJ vieillissant), et un peu de bricolage pour avoir une phrase en français.
La point important, c'est qu'on ré-utilise la variable Age. Elle vaut combien ? Eh bien soit 65 si on a jamais appelé la fonction Vieillir, ou alors 65 moins le nombre de fois où la fonction Rajeunir() a été appelée. La variable Age permet donc de garder en mémoire l'age de notre PNJ.
Evidemment, la question qui titille pour l'instant c'est "Mais comment on les appelles ces fonctions ?". On en reparle avec les Events plus tard. Revenons à notre property :
Une auto property (qui est défini en rajoutant le mot-clé "Property" entre le type de la variable et son nom, et en ajoutant le mot-clé "Auto" à la fin), c'est comme une variable, sauf qu'elle :
- Est visible par les autres scripts,
- Peut-être associée à un objet existant via le CK.
Pour voir l'intérêt, il faut voir comment les script peuvent effectuer des actions, sur eux-mêmes ou sur d'autres scripts, et donc s’intéresser aux events.
Les events, c'est ce qui fait marcher ton code. Quand est-ce qu'est appelée un fonction ? Ce n'est pas au pif, mais lors d'events.3)A quoi correspond "Event" ? On l'utilise uniquement lors d'un événement ?
Les events correspondent à des événements qui se passent en jeu, et sont les moments ou tu veux que ton script effectue une action. On va prendre l'exemple le plus classique : Un Activator, un objet que le joueur peut activer en pressant sur E, et donc le seul but est d'exécuter un portion de script correspondante :
Code : Tout sélectionner
ScriptName MachinePourVieux Extends ObjectReference
Event OnActivate(ObjectReference akActionRef)
;ici il va se passer des trucs
EndEvent
Non, c'est un event. Il est pré-défini par le type de base qu'extend ton script (Impossible de définir de nouveaux events, il sont intimement liés au système du jeu), et est "reçu" par ton l'objet auquel est attaché ton script, qui va exécuter le bout de code correspondant. OnDeath va tourner à chaque fois que l'acteur auquel est attaché ton script meurt. (Bon, "à chaque fois" c'est relatif dans ce cas...). La liste des events reçu par quel type de script est disponible dans le lien que j'ai filé plus tôt, en cliquant sur un des types.4)"OnDeath" est une fonction ?
Bref, avec ce script attaché à notre Activator, et notre activator placé dans le monde, chaque fois que le player va l'activer en pressant sur E, le bout de code dans le bloc OnActivate va tourner. Ici on y fait rien (j'ai mis un commentaire). On va ignorer la partie entre parentheses pour le moment, j'y reviendrai.
Pour le moment, on a un activateur qui ne sert à rien, et un script qui a une fonction pour faire rajeunir un actor et une autre pour voir son age.
Revenons un peu en arrière pour reparler des properties : on va utiliser une property pour pouvoir agir sur notre actor avec notre activator :
Code : Tout sélectionner
ScriptName MachinePourVieux Extends ObjectReference
ActorQuiRajeunit Property UnPNJTropVieux Auto
Event OnActivate(ObjectReference akActionRef)
UnPNJTropVieux.Rajeunir()
EndEvent
La question est : Mais QUEL PNJ ?
C'est ce que tu va définir en associant ta property à un actor via le CK. C'est pour celà qu'on a mis une property, et non pas juste une variable, que l'on aurait juste écrite :
Code : Tout sélectionner
ActorQuiRajeunit UnPNJTropVieux
Pour faire le lien: Choisis un des PNJs, et ajoute lui le script ActorQuiRajeunit.
Une fois que c'est fait, tu vas dans les properties de ton activator, et là tu lie la property "UnPNJTropVieux" au PNJ en question. Tadaaa !
C'est bien évidemment l'acteur qui a tué ton PNJ. On va reprendre notre exemple pour expliquer l'intérêt :5) Dans "Actor akKiller", que signifie "akKiller" ?
Pour le moment, on fait rajeunir un PNJ associé au choix, mais bon... ce serait quand même plus logique que ce soit le PNJ qui active notre Machine pour vieux qui rajeunisse non ? C'est possible... à condition que le PNJ en question aie le script ActorQuiRajeunit attaché à lui même.
Admettons que ce soit le cas. Dans ce cas, on va pouvoir utiliser la fameuse partie entre parentheses après OnActivate : Il s'agit d'arguments qui correspondent à l'event reçu. Chaque fois que notre activator est activé, il "sait" qui l'a activé grace à l'argument akActionRef.
On pourrait donc essayer ceci :
Code : Tout sélectionner
ScriptName MachinePourVieux Extends ObjectReference
Event OnActivate(ObjectReference akActionRef)
akActionRef.Rajeunir()
EndEvent
Sauf que... cet exemple ne compilera pas. En effet, akActionRef est un ObjectReference, en revanche la fonction Vieillir() n'existe que pour les ActorQuiRajeunit... et tous les ObjectReference ne sont pas des ActorQuiRajeunit !
On utilise un cast pour essayer de transformer un type en un autre :
Code : Tout sélectionner
ScriptName MachinePourVieux Extends ObjectReference
Event OnActivate(ObjectReference akActionRef)
(akActionRef as ActorQuiRajeunit).Rajeunir()
EndEvent
Code : Tout sélectionner
ScriptName MachinePourVieux Extends ObjectReference
Event OnActivate(ObjectReference akActionRef)
ActorQuiRajeunit futurJeune = (akActionRef as ActorQuiRajeunit)
If futurJeune != null
futurJeune .Rajeunir()
EndIf
EndEvent
Elle correspond à l'action effectuée par le script lors de l'event OnDeath. C'est l'équivalent de notre (akActionRef as ActorQuiRajeunit).Rajeunir()6) L'avant dernière ligne, à quoi correspond-elle ?
Pour savoir ce qu'elle fait exactement, il faut aller dans le script DialogueFollowerScript, et regarder ce que fait la fonction DismissFollower()
Pas pour le script, mais pour l'event. Ce mot clé défini la fin du bloc d'event précédent (dans ce cas, l'event OnDeath. Dans notre exemple, l'event OnActivate). C'est important car tu peux avoir plusieurs events dans un seul script (différents ! Tu ne peux pas avoir deux OnDeath ou OnActivate, à moins d'utiliser des states, ce qui est un poil plus avancé).7) "EndEvent" Obligatoire pour dire au script de bien se terminer ?
Il y aurait encore des tonnes de points à préciser sur ce que je viens d'écrire, mais j'espère que ça répond à tes questions pour le moment.
Petit résumé :
Ecrire un script, c'est définir un nouveau "type", le plus souvent qui hérite d'un type plus basique.
Ces scripts peuvent être attachées à des objets via le CK.
Les scripts reçoivent des Events, pré-définis en fonction du/des types hérités, qui sont des événements en jeu "reçu" par l'objet auquel ils sont rattachés.
Les events sont les seuls moments auquel le script effectue du travail.
En plus de correspondre à l'action, les events ont souvent des informations additionnelles appelés arguments, utiles dans le contexte de cette action.
Les fonctions sont des portions de codes pré-écris que l'on peut utiliser dans d'autres fonctions ou dans des events. Elles sont propres au types dans lequel elles sont définies.
Les scripts peuvent interagir entre eux via des Properties : Script A peut agir sur Script B si il a une property référençant un objet auquel Script B est attaché.
Le lien entre une property définie dans un script et un véritable objet est fait via l'interface du CK.
Les interactions qu'un script peut avoir avec un autre script passent toujours par des "fonctions" (de façon explicite ou de façon un peu cachée).
Faites un feu à un homme, il aura chaud un jour.
Mettez le feu à un homme, il aura chaud jusqu'à la fin de sa vie.
Terry Pratchett
Mettez le feu à un homme, il aura chaud jusqu'à la fin de sa vie.
Terry Pratchett
Re: Apprendre à ''décortiquer'' les scripts
Tout simplement bravo ! Merci. Je pense que ça va servir à tous ceux qui souhaitent s'y mettre. Je connaissais certains trucs via le forum du Ck mais c'est vraiment difficile de tout assimiler. Là, tu nous donnes les bases avec logique et calme et clarté. Mérite probablement d'être épinglé vue le travail que tu as apporté. Merci encore Kesta. Je vais tenter d'assimiler tout ça et de créer quelques scripts pour m’entraîner. Si tu as une suggestion pour la suite je t'en prie mais bon, on verra plus tard, déjà là, il y a de quoi faire. 
