[Résolu] Script de l'établi (Workbench) : base de la programmation

Vous trouverez ici les tutoriels et l'entraide sur les outils et techniques de modding spécifiques à Fallout 3.
Exceteraviking
Traducteur aspirant
Traducteur aspirant
Messages : 64

Script de l'établi (Workbench) : base de la programmation

Message par Exceteraviking »

Salut à vous.

Je recherche un moddeur qui connaisse les subtilité de la scriptologie de F3.

Je cherche à changer un script existant, et après reflexion à en créer un second de zéro en m'inspirant du 1er. Mais je m'y perds dans les opérateurs, les références, les commandes etc.

J'ai une idée claire de ce que j'aimerais obtenir comme comportement.

Par exemple et pour parler du script en question : Il s'agit de mon MOD préféré Workbench Crafting Expansion. J'aimerais que le script que j'ai déja modifié et qui fonctionne parfaitement s'applique à tous les établis du jeu (comme ça doit surement être le cas pour le script original de F3) SAUF à celui de la maison du joueur.
Pour ce dernier, j'aimerais que l'établi ne recherche pas les pièces détachées disponibles UNIQUEMENT dans l'inventaire du joueur MAIS AUSSI dans un container que j'ai placé pour l'occasion. Jusque là, ça roule.
Ca se corse lorsque le script passe à l'étape de retrait des dites pièces qui ont été utilisées pour fabriquer un objet. Si vous suivez toujours, dans le script, il est dit que:
¤Si telle et telle pièces sont présentes en nombre suffisant dans l'inventaire du joueur , alors
¤fabriquer l'objet et ensuite
¤afficher un message de réussite et ensuite
¤retirer les pièces strictement nécessaires de l'inventaire du joueur.

J'aimerais connaitre la méthode pour scripter (à l'aide des opérateur je pense) plutôt celà:
¤Si telle et telle pièces sont présentes en nombre suffisant dans l'inventaire du joueur ET/OU dans le container , alors
¤fabriquer l'objet et ensuite
¤afficher un message de réussite et ensuite
¤retirer les pièces strictement nécessaires de l'inventaire du joueur ET/OU du container.

C'est facile à dire là comme ça. A coder même, mais lorsque viens le moment de faire les comptes des pièces à retirer. Je patine.
Comment scripter cette dernière étape si le joueur n'as qu'une partie des pièces?
Je pense à des munitions par exemple.
Admettons que j'ai besoin de 5 clous de rails, que j'en ai 3 sur moi, et 3 dans le container. Le début, c'est OK:

if ( player.GetItemCount + MegatonToolbox.GetItemCount AmmoRailwaySpikes > 4 )

Comment scripter pour qu'il en soit retirées 3 au joueur et les deux restantes du container ou inversement?

======================================================

Second soucis, et ça je pense que ça ira tout seul, je présume déja de la méthode, comment dire à l'établi de megaton qu'il obéisse à ce script unique étoffé et uniquement lui? Ca ne pose pas de problème que cet établi ne soit accessible qu'après achat chez Moira? Ca ne va pas faire beugguer le jeu cet attachement à un nouveau script?

=======================================================

Et enfin, je me suis aperçu qu'il y avait une limite à la quantité de caractère que pouvait contenir un script. M3dhi sur Falout3Nuclear m'as donc conseillé de le scinder en deux, et de finir le premier par un lancement du second. Est il possible d'attacher deux script à cet établi ou d'émettre une condition uniquement pour cet établi (pour que le second ne se lance que pour lui) dans le script qui est utilisé par tous les établis du jeu? C'est pas fouillon de faire ça?


Je sais que mon post est très long et je ne sais pas si je me suis bien fait comprendre.
Dans l'ordre des priorités, j'aimerais vraiment connaitre la formule magique. Pour la suite, je pense que je peux trouver ça par moi même. :D Vous me verrez débarquer si ce n'est pas le cas :lol:
Pardonnez aussi mon ignorance s'il vous plait, je ne suis pas programmeur, peut être un matheu mais ça va pas plus loin que les additions pendant les commissions du lundi. J'évolue dans d'autre sphère que les sciences appliquées, je n'ai donc plus l'habitude :| .
morghoth a écrit :Recherche testeurs pour mods traduits.PM s.v.p. :)
Sherman
Confrère
Messages : 131

Re: Aide de moddeur pour scripter

Message par Sherman »

Hello !!

Je me penche sur la première partie de ton problème. Chercher une partie des objets dans l'inventaire du joueur et une autre dans les containers.

Pour cela, ce que je te propose, c'est tout simplement de compter les items disponibles dans tous les containers à tester (joueur compris).

Prenons l'exemple des clous.

3 Clous sur le Joueur
10 Clous dans un coffre
5 Clous requis pour la réparation

Var1 //Stockera le nombre de clous sur le joueur
Var2 //Stockera le nombre de clous dans le coffre
Var3 //Nombre de clous requis. Fixé à 5.
Var4 //Variable pour le calcul

Il suffit ensuite que lorsque ta réparation commence :
1) Le script compte les clous :
avec .GetItemCount, qui renvoie le nombre d'un objet sur la cible.
tu stockes la valeur dans une variable (une par container)
Var1 -> 3
Var2 -> 10
2) Tu additionnes les variables pour savoir si les clous sont en nombre suffisant
If Var1+Var2 >= Var3
3) Si oui,
là il va falloir que tu fasses quelques calculs sur tes variables pour retirer le bon nombre de clous au bon endroit. On utilisera des comparaisons.
if Var1 >= Var3
player.RemoveItem ... Var3
else if Var1<Var3
set Var4 to Var3-Var1
player.RemoveItem ... Var1
coffre.RemoveItem ... Var4

Note : il faut bien sûr que le block 3) soit contenu dans le block 2) (le block 3 ne doit s'executer que si le nombre total de clous est suffisant)
Et voilà, normalement le script aura retiré tous les clous du joueur, plus ceux nécessaires dans le coffre.

Pour ta deuxième question, que seul l'établi de Mégaton obéisse à ce script, rien de plus simple.
Et ça ne pose bien sûr aucun problème que cet établi soit achetable chez Moira.
Si l'établi de la maison est sur la même base que les autres du jeu, tu crées une autre ID pour faire un deuxième établi, sur lequel tu places ton script. Ce deuxième établi ne sera placé en jeu que dans la maison de Megaton au lieu de celui de base.
Il te reste ensuite à faire les modifs d'usage pour que ce soit celui vendu par Moira.
(La même REF editeur devrait suffire si le système d'achat de meubles est le même que celui d'Oblivion).
Avatar du membre
apdji
Légende de la Confrérie
Légende de la Confrérie
Messages : 9868
Contact :

Re: Aide de moddeur pour scripter

Message par apdji »

Je ne suis pas encore passé sur f3n aujourd'hui, mais à mon avis, je pense que suuk pourrait certainement éclairer ta lanterne ;)
Image

"Pas de coercition ... un peu d'éducation ..." Moorelf
Exceteraviking
Traducteur aspirant
Traducteur aspirant
Messages : 64

Re: Aide de moddeur pour scripter

Message par Exceteraviking »

Ouhaaaa :shock: C'est trop balèze.
Merçi beaucoup Sherman. Ce que je cherchais, c'était bien ça :

if Var1 >= Var3
player.RemoveItem ... Var3
else if Var1<Var3
set Var4 to Var3-Var1
player.RemoveItem ... Var1
coffre.RemoveItem ... Var4

Et il va falloir que j'étudie les variables + en profondeur... J'aurais pourtant aimé éviter de les utiliser. Parce que des variables, il va y en avoir des tonnes avec toutes les pièçes détachées.
C'est peut être pas plus mal finalement... Ce sera plus aisé de rajouter des recettes de fabrication par la suite.

Si quelqu'un à des infos sur la limite de taille des scripts.... :| C'est de ça dont tu parles apdji ?

Merçi encore, c'est tout à fait ce dont j'avais besoin comme réponse. :idea: :D
morghoth a écrit :Recherche testeurs pour mods traduits.PM s.v.p. :)
Sherman
Confrère
Messages : 131

Re: Aide de moddeur pour scripter

Message par Sherman »

De rien !

Par contre, tu ne pourras pas éviter d'utiliser des variables. C'est indispensable en programmation.
Il n'y a donc pas à hésiter ! ;)

Et puis, ne crains pas d'en utiliser un certain nombre (j'ai écrit des scripts pour Obli avec une cinquantaine de variables, facile !). Sachant que tu peux les réutiliser.

Comme un joueur ne va pas réparer en même temps un fusil et une armure (il est obligé de faire l'un puis l'autre), tu n'auras besoin que d'un nombre de variables correspondant au nombre maximum d'items utilisés par une réparation.

Exemple :
Fusil : 4 items,
Pistolet : 3 items,
Armure : 5 items,
Casque : 2 items,
...

=> Tu as besoin de de 5 variables, *2 pour joueur + coffre, +5 pour le soustraction

soit 15 variables.

On doit pouvoir réduire encore ce nombre en réutilisant certaines au moment du décompte.

Attention, n'oublies pas que tant que le script n'est pas relancé, les valeurs des variables restent en mémoire. Il faudra donc que tu réinitialises les variables à la fin de chaque réparation.

N'hésite pas si tu as d'autres questions !
Avatar du membre
apdji
Légende de la Confrérie
Légende de la Confrérie
Messages : 9868
Contact :

Re: Aide de moddeur pour scripter

Message par apdji »

Pour la taille des scripts à mon avis y a pas de vraies limites, ne serait ce que par l'utilisation du FOSE, mais il me semble que le système est un peu différent que les scripts de base.

En fait, je te parlais de Suuk, car en terme de scripts, je ne m'y suis pas penché sur le sujet, ce qui fait que je n'ai que survolé ton topic et je t'ai renvoyé vers lui car je sais qu'il est calé et qu'il réponds, aide facilement pour les scripts sur le forum de f3n ;)
Image

"Pas de coercition ... un peu d'éducation ..." Moorelf
Exceteraviking
Traducteur aspirant
Traducteur aspirant
Messages : 64

Re: Aide de moddeur pour scripter

Message par Exceteraviking »

J'suis à fond d'dans ...

Voilà à quoi ça ressemble pour un seul objet.
Il y a des lignes en trop mais elle concerne d'autre bloc qui n'apparaissent pas (et pas encore écrite mais le schéma restera le même)

SCRIPT

J'ai uploader sur mon FTP parce que les tabulations ne passe ni dans un spoil, ni dans le corps du post... :?:

Je ne sais pas bien manier les else et elseif, ni mettre les end là où il faudrait certainement les mettre...
Je ne connais que la commande : Set varX to -1 pour réinitialiser les variables, est ce bien ça?
Et les "return" sont là parce qu'il était présent dans le script sur lequel je me suis basé, et après ma première modification qui s'exécute parfaitement. Je les ai utilisé "intuitivement". Je ne saisi pas bien leur rôle.

J'ai choisi de mettre une variable par pièçe détachée dans un soucis de clarté dans ma tête. C'est trop compliqué pour moi actuellement d'énoncer des variables génériques et des les modifier au cas par cas (selon le bloc en cours d'execution). Je ferais ça après, pour dégrossir le script. Je pense que je serais plus à l'aise alors.

Sinon, il n'existe pas un programme avec GUI pour fabriquer des script? :lol: Ce serait qd même plus pratique pour les néophyte (un peu comme le Flash qui a les préférence des infographistes).
Modifié en dernier par Exceteraviking le 23 mai 2009, 18:49, modifié 1 fois.
morghoth a écrit :Recherche testeurs pour mods traduits.PM s.v.p. :)
Sherman
Confrère
Messages : 131

Re: Aide de moddeur pour scripter

Message par Sherman »

Réinitialiser les variables, c'est seulement les remettre à un valeur par défaut qui n'interfère pas avec ton code.

(En programmation, quand on déclare une variable, elle a alors une valeur aléatoire, celle stockée dans la case mémoire correspondant à son adresse. Pour éviter les mauvaises surprises, on initialise donc la variable, en fixant sa valeur à 0 par exemple).

Dans le GECK, une variable créée par un script est forcément initialisée à 0 (il me semble) donc, pour la rénitialiser, il te suffit de faire :

Code : Tout sélectionner

set Var to 0
Ca marche aussi avec ton

Code : Tout sélectionner

set Var to -1
MAIS, il est bien de prendre l'habitude de partir de zéro, car quand tu crées une variable que tu incrémentes (par exemple un compteur de morts en globale)

Code : Tout sélectionner

Set Var to Var+1
si tu avais réinitialisé ta variable entre deux utilisations à -1, ton compte sera faux.

Deuxième remarque : mets des commentaires !! C'est indispensable à la bonne compréhension de ton code, et ça t'aidera pour l'évolution de ton code.

Ha, oui, le rôle des return...
En C, toute fonction appelée retourne une valeur. On écrit "return 0" la plupart du temps, pour qu'il n'y ait pas de choses laissées au hasard dans le code. Ou "return Var" pour obtenir le résultat du calcul sur une variable.
Mais si on n'utilise pas le nombre renvoyé par la fonction (elle ne peut en renvoyer qu'un seul) parce qu'on a créé une fonction qui renverra plusieurs arguments (en travaillant sur des pointeurs par exemple) alors on peut laisser seulement "return" et la valeur renvoyée sera aléatoire.

Ici, le return doit surement retourner une valeur. Mais laquelle et à qui ? Ca, je ne peux pas le dire. J'aurais tendance à croire qu'il n'est pas indispensable, vu que tu as trois fois le même bloc de code dont seulement un seul qui a un "return".

Pour les blocs if/elseif/else/endif...
If : SI
ElseIF : Sinon SI
Else : Sinon
EndIF : Fin du bloc
Voilà un exemple d'utilisation :

Code : Tout sélectionner

if Var1 + Var2 >= Var3
....... if Var1 == 5
............. instruction1
....... elseif Var1 == 6 && Var 2 < 4
............ instruction2
....... elseif Var 2 > 4
........... instruction3
....... else
.......... instructionGénérique
....... endif
endif
Le SI ouvre le test logique. Les SINONSI sont d'autres SI à l'intérieur du bloc. Ils permettent de tester plusieurs conditions pour un même bloc. (Offrent des choix)
Attention, les SINONSI ne s'exécutent que si la valeur False est renvoyée par les conditions d'au dessus ! Autrement dit, dans le bloc de l'exemple, UNE SEULE des instructions s'exécutera.
Lorsque le code s'exécute, on parcourt le bloc, et la première condition vérifiée entraîne la sortie.
Le SINON sert à ce qu'il y ait un choix par défaut, pour que le script ait toujours quelque chose à faire.

Bonne continuation !

Edit : désolé, j'avais oublié un endif dans l'exemple... :oops:
Exceteraviking
Traducteur aspirant
Traducteur aspirant
Messages : 64

Re: Aide de moddeur pour scripter

Message par Exceteraviking »

OK. Je comprends. Ca m'avait semblé étrange qu'il initialise ses variables à -1.
J'avais lu cette page du geckwiki pour trafiquer le script de base. C'est là que j'avais entendu parler des RETURN et des set to -1.
► Afficher le texte
Je crois comprendre que ça na s'applique qu'au bouton d'un "Menu Level" ou un truc comme ça. Ce return sert à revenir plus haut dans le script, à la boite de message qui s'affiche quand un choix ne lance rien du tout in game (comme le bouton "Annuler"/"Aucun"/"Retour").

Pour mes variables donc, comme elles concernent l'énumérations d'items d'inventaire, je dois les réinitialiser à 0 ou même ne pas les réinitialiser du tout puisque je les remplis à chaque fois au début de chaque bloc... Non?
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Pour les commentaires, oui, je suis désolé, j'avais bien compris que c'était nécessaires, j'étais dans le speed, à fond d'dans, et j'avais encore en tête la limite de longueur des script dans le GECK. J'ai fait le radin niveau taille, copié, collé, posté, uploadé dès que j'ai eu terminé la première partie. J'aurais dû mettre un peu plus en forme. Ce sera fait quand j'aurais terminé le 1er jet :D.
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
OK.
Je voyais le elseif comme une sorte et "et si pas...ceci celà", j'étais pas loin.
Attention, les SINONSI ne s'exécutent que si la valeur False est renvoyée par les conditions d'au dessus !
. Ca c'est ce dont je n'était pas sûr.
Il vaux mieux donc que dans mon script, je mettre des if les uns à la suite afin que tout se vérifie pour permettre de renvoyer la valeur True:

Code : Tout sélectionner

if Var1 + Var2 >= Var3
....... if Var1 == 5
............. instruction1
....... if Var1 == 6 && Var 2 < 4
............ instruction2
....... if Var 2 > 4
........... instruction3
....... endif
elseif  blablabla
else  blaaaa
endif
Si je comprends bien, dans un bloc, il doit y avoir cet ordre:
If
(Elseif -> facultatif et/ou autant que l'on en a besoin)
else (au minimum dans ce que j'appellerais le bloc maitre)
Endif

J'crois que j'ai saisi. Pour mon malheur, j'suis du genre à piger un truc neuf rapidement, et un certain temps après, ne plus rien y comprendre, pour enfin, recomprendre la chose pour l'éternité. Si y a des psy dans la salle... ;) :siffle:
Je crois que que j'ai définitivement compris. ^^ :mrgreen:


Je vais poster l'intégralité du 1er jet de mon script quand je l'aurais rempli. Tu pourras contrôler si tu veux. Ce sera grâce à toi que je l'aurais fait en tout cas. Merçi beaucoup.
Et ensuite, j'irais chercher sur F3N de l'aide pour un autre problème le concernant comme l'a conseillé le troll ( ;) ).
morghoth a écrit :Recherche testeurs pour mods traduits.PM s.v.p. :)
Sherman
Confrère
Messages : 131

Re: Aide de moddeur pour scripter

Message par Sherman »

Ok, je comprends mieux l'utilité du RETURN et du set à -1

En fait, c'est un cas particulier là, qui s'applique aux menus des fenêtres pop-up des activators.
Quand tu choisis des boutons, tu peux en effet fixer ta variable à 1, 2, 3, etc... pour faire la différence entre les options; et réserver une valeur spéciale, par exemple -1 pour le choix sortir/annuler

(La structure correspondante en C est le switch)

Si la ligne contenant le return s'exécute, le script se termine.
Pour mes variables donc, comme elles concernent l'énumérations d'items d'inventaire, je dois les réinitialiser à 0 ou même ne pas les réinitialiser du tout puisque je les remplis à chaque fois au début de chaque bloc... Non?
Exact.
Remplir les variables avec une nouvelle valeur (par exemple celle renvoyée par le GetItemCount) c'est déjà les réinitialiser.
Alors effectivement, tu peux ne pas avoir besoin de les réinitialiser.

Il faut savoir que dans Fallout, toute variable non déclarée en globale est automatiquement réinitialisée lorsque le script est relancé.

Dans ton cas, si le joueur veut pouvoir faire plusieurs réparations de suite, sans quitter l'établi, tu n'auras pas besoin de réinitialiser les variables si tu places leur affectation au bon endroit dans ton script (avant les tests, dans le bon block...) C'est au cas par cas, et c'est à toi de bien comprendre ton script pour savoir ce que tu as besoin de faire ou non !
Et puis, si tu hésites, tu postes ton code et je regarderais avec plaisir !
Il vaux mieux donc que dans mon script, je mettre des if les uns à la suite afin que tout se vérifie pour permettre de renvoyer la valeur True:
Si tu mets des IF les uns à la suite des autres, ils seront indépendants, et tu auras autant de TRUE renvoyés que de blocks IF.
Et donc autant d'instructions qui s'exécuteront que de blocs où le IF est vérifié.
Si tu veux tester plusieurs choses pour une seule instruction, utilise les AND et OR.
► Afficher le texte

Code : Tout sélectionner

if Var1 + Var2 >= Var3
....... if Var1 == 5
............. instruction1
....... if Var1 == 6 && Var 2 < 4
............ instruction2
....... if Var 2 > 4
........... instruction3
....... endif                          <=== (1)
elseif  blablabla
else  blaaaa
endif
Sans oublier les endif. Ou tu les places tous en (1) et dans ce cas tu imbriques tes tests, ou chacun après son instruction. Mais ça je suppose que tu le sais et que c'est juste un petit oubli.
Si je comprends bien, dans un bloc, il doit y avoir cet ordre:
If
(Elseif -> facultatif et/ou autant que l'on en a besoin)
else (au minimum dans ce que j'appellerais le bloc maitre)
Endif
Exactement.
Les possibilités offertes par cette structure de test sont quand même assez importantes.
Quant au ELSE, tout dépend de la longueur du script et de son type.
Pour un script de quête par exemple, qui tourne tout le temps, le mieux c'est de mettre un IF au début :

Code : Tout sélectionner

SI GetStage QUESTMachin >= xx
........ tout un tas d'instrcutions
SINON
........ quitter le script // évite que le jeu soit trop chargé de script non utilisés.
Quand la quête sera terminée, le moddeur aura pris le soin d'arreter le script de quête grace à la commande stopQuest

On voit dans cette exemple pourquoi le ELSE est "obligatoire" dans ce que tu appellerais un bloc maître.
Mais pour un script sur un activateur, qui ne ralentit donc pas le jeu, ce n'est pas forcément indispensable.
pour un autre problème le concernant
Pour ton autre problème, n'hésite pas à me demander, si je peux t'aider, je le ferais.

Concernant la longueur max des scripts, je pense que le plus judicieux c'est de faire :
- un script maître sur l'établi
- un script distinct par objet à réparer
C'est l'architecture la plus judicieuse à mon avis. Ton script maître ne sert qu'à appeler le bon script d'objet lorsque tu choisis tel ou tel option dans le menu de réparation.
Ca permettra en plus de le faire évoluer très facilement, en rajoutant seulement des options pour d'éventuels nouveaux scripts.
De plus, tu pourras contrôler chaque script individuellement en cas de problème.
Hors-sujet
PS : J'espère t'aider à progresser dans le vaste domaine du script, mais je ne suis pas spécialiste. En fait, je programme "professionnellement" on va dire dans le cadre de mes études, et j'applique ce que je sais sur le GECK (et le TESCS) mais j'ai un peu de mal avec ces programmes dans le sens où c'est complètement différent de la programmation "libre". Dans ces programmes, on doit appeler des fonctions déjà existantes très spécifiques et très limitées, et il faut toutes les connaître pour avoir un réel sentiment de liberté.
J'ai plus l'habitude de créer moi-même mes fonctions, gérer mes entrées/sorties, la mémoire à allouer,...
Donc je fais avec les fonctions que je connais sur le GECK, mais je peux t'aider à mieux comprendre le principe de la programmation et je peux t'apprendre une partie de ce que je sais qui te servira.
Il te suffira ensuite d'aller chercher dans le catalogue des fonctions celles qui correspondent à tes besoins. Tu pourras alors faire tout ce que tu veux !

http://fose.silverlock.org/Fallout3Comm ... t_Commands
Répondre

Retourner vers « Modder Fallout 3 »