Creation d'un menu pour l'atelier des colonies

 
 

Lorsqu'on a crée des objets dans le Creation kit pour l'atelier des colonies, on a deux options, soit on intègre les objets dans les menus originels, soit on crée un menu indépendant.

Si on a peu d'objets à ajouter on peut simplement les intégrer dans les menus existants dans la bonne catégorie, ça peut paraître une bonne idée, mais si on a plusieurs mods qui font de même on arrive vite à des menus sans fin peu pratiques à utiliser. En plus il y a une limite au nombre d'objets dans un menu, ce qui fait que certains vont disparaître.

 
Si on intègre dans les menus d'origine, il ne faut absolument pas modifier les listes de catégories sinon les menu provenant des DLC ou d'autre mods vont disparaitre ou être incomplets.
Tout ce qu'on peut faire c'est utiliser les catégories existantes en utilisant les mots clés (Keywords) originaux. Si on veut créer une nouvelle catégorie en créant un nouveau Keyword, on deva ensuite ajouter ce Keyword dans une liste du type FormList.
Si on ajoute un Keyword dans une Form List d'origine, on risque de perdre tous les Keywords que pourraient ajpouter les DLC ou des mods dans cette même liste. C'est une question d'ordre de chargement, le dernier mod qui modifie la liste prend la main et remplace les autres listes venant du jeu originel, des DLC ou de mods.
 
Pour éviter ce problème de conflits dans les listes, le jeu propose la possibilité de d'ajouter dynamiquement des listes ou des catégories aux listes d'origine, c'est ce que font tous les DLC.
Les bons mods de construction le font également, mais c'est assez rare, il y a une autre option c'est d'utiliser un mod qui gère les menus des mods, mais ça peut causer des problème de compatibilité.
Mieux vaut donc faire son propre menu indépendant et de l'injecter dynamiquement au lancement du jeu.
Pour le faire on va utiliser un petit script et une quête qui sera lancée au démarrage et qui démarrera le script qui ajoutera les menus.
 
La première chose à faire c'est de créer notre menu:
 
On va avoir besoin de Keywords qui définiront les catégories du menu, c'est à dire par exemple; murs, sols, plafonds, meubles etc...
On va avoir besoin aussi d'un autre Keyword qui définira le nom de notre menu et l'icône qui le représentera dans le menu de base.
On va ensuite avoir besoin d'une FormList qui va contenir la liste de nos Keywords.
C'est cette Form List qui sera chargée dynamiquement au démarrage dans la liste des menus.
 
Mais ce n'est pas tout, les objets qu'on peut construire et qui doivent apparaître dans le menu doivent avoir une fonctionalité supplémentaire qui va définir leur échelle et l'angle de vue, c'est ce qu'on appelle un Transform.
Sans ce Transform l'objet n'apparait pas en miniature dans le menu ou si le transform n'est pas adapté, la miniature sera trop petite ou trop grande.
 
Les keywords et leur usage:
 
 
Les Keywords sont utilisés pour créer des liens entre divers éléments dans le Creation Kit.
 
Lorsqu'on a créé un objet dans le Creation Kit, un Static, un Furniture, un Activator par exemple, pour pouvoir ensuite l'intégrer dans le menu de construction d'un atelier de colonie, il faut créer un Constructible Objet et c'est ce Constructible Object qui devra être lié au menu par le moyen d'un Keyword.
Ce keyword a la structure suivante :
 
ID : c'est ID de l'entité Keyword
Type: c'est le genre de Keyword, dans notre cas on a besoin d'un Recipe Filter (filtre de recette)
Display Name: c'est le nom de la catégorie affiché dans le menu.
 
 
 
Dans cette fenêtre on va détailler les champs pour une meilleure compréhension au cas où ça ne serait pas déjà connu.
 
ID : c'est l'ID de l'entité Constructible Object
Workbench Keyword: définit le type d'atelier qui peut construire l'objet
Pickup Sound et Putdown Sound : définissent les bruits joués lorqu'on prend l'objet et qu'on le pose.
Menu Art Objet : c'est l'icône qui sera affichée dans le menu de l'atelier si on veut autre chose que l'objet lui-même
Created Objet : c'est l'objet fabriqué
Recipe Filter : c'est là qu'on va mettre le Keyword de la catégorie du menu ( c'est ce qui nous intéresse ici)
Required Item List: c'est la liste des objets nécessaire pour la construction (si c'est vide l'objet ne peut pas être créé dans le jeu!)
Match Conditions : c'est une liste de conditions à remplir pour pouvoir dfréer l'objet (ce n'est pas obligatoire)
Description: c'est un message qui sera éventuellement affiché à l'écran
 
 
La création du menu :
 
 
Pour notre menu on va avoir besoin d'un Keyword pour chaque catégories, une fois qu'on les aura tous, on va pouvoir créer notre liste du type FormList
 
 
 
Dans cette FormList on a plusieurs champs :
 
ID : l'ID de l'entité FormList
Name : le nom de la liste
 
En dessous on a la liste d'objet, ici on a un exemple d'une liste d'objets statique. Ce genre de liste peut être utlilisée dans un Constructible Object à la place d'un objet seul, ça permet de simplifier le travail si plusieurs objets sont crés avec la même recette. Ca ne veut pas dire qu'on va créer tous les objets en même temps, mais qu'il seront disponibles individuellement dans la le menu. Le jeu utilise très souvent cette simplification car ça évite de créer à chaque fois un Constructible Objet pour toute une série d'objets similaires.
 
 
Ci-dessus une FormList d'un menu, c'est ce qui nous intéresse dans le cas présent.
 
C'est le menu décoration du jeu, on voit qu'il contient des Keywords KYWD et des FormLists FLST. Ceci permet d'intégrer des sous menus pour une meilleure classification.
Le premier Keyword en haut de la liste c'est toujours celui qui va définir le nom affiché du menu, il faut toujours en mettre un et au sommet de la liste.
 
On va pour notre menu après avoir créé une nouvelle FormList, créer ce Keyword qui va définir le nom qu'on verra à l'écran.
Ce sera un Keyword de type Recipe Filter avec dans Display Name le nom de notre menu.
 
Ensuite on peut ajouter la liste des Keyword définissant nos catégories et aussi d'autre listes pour d'éventuels sous-menus.
 
 
Notre menu est alors prêt pour être intégré dans le menu du jeu originel.
C'est à ce moment que la catastrophe peut arriver, si on ajoute notre FormList à celle du jeu originel dans le menu principal par exemple.
Si un DLC ou un Mod a besoin de rajouter une FormList lui aussi, notre mod qui sera chargé après va l'écraser en rendre indisponibles les objets des DLC ou des mods chargés avant.
 
C'est pourquoi on va charger dynamiquement au démarrage grâce à une quête et un script notre menu.
 
 
Chargement Dynamique du menu dans le jeu :
 
 
 
Pour charger le menu dynamiquement il y a un tutoriel avec les fichiers nécessaires sur Nexus à l'adresse :
 
Tutoriel du Nexus
 
J'ai suivit le tutoriel scrupuleusement, mais sans succès, mon menu n'apparaissait jamais, en plus les autres menus des mods disparassaient également.
C'est du au fait que le script principal est en deux partie, la première pour charger le menu et léa deuxième pour l'enlever et nettoyer le menu.
 
Le problème c'est que la deuxième partie ne doit être activée que lorsqu'on utilise une drogue crée dans l'établi de chimie. Il doit y avoir un bug dans le script qui fait que les deux parties se déclenchent l'une après l'autre.
Le menu s'installe puis est immédiatement désinstallé et le nettoyage supprime les autres menus chargés dynamiquement.
Normalement il y a un test pour savoir si le script doit installer ou désinstaller, mais visiblement ça ne mache pas.
 
J'ai modifié le script de chargement en enlevant la deuxième partie et en l'intégrant dans un autre script. Il faut simplement veiller à ce que les paramètres soient bien les mêmes dans les deux.
 
 
Pour commencer l'intégration du menu, on va créer un nouveelle quête dans le Creation Kit.
 
 
Pour ce qu'on va faire créer la quête est très simple, il suffit d'en créer une nouvelle par défaut dans le Creation Kit.
 
Il faut vérifier dans le premier onglet Quest Data que Start Game Enabled et Run Once sont bien cochés.
 
 
Ensuite on va dans le dernier onglet Scripts pour ajouter le script de chargement du menu. Il suffit de cliquer sur le bouton Add pour accéder au dossier Scripts du jeu, il faut mettre un filtre pour retrouver le bon script plus facilement.
Si on n'a pas de script disponible, on peut en créer un d'après la source que vous allez voir plus bas.
Je vais expliquer plus loin comment créer le fichier source et comment le compiler.
 
 
 
Ensuite on va devoir paramétrer notre script pour lui donner les noms de menus, l'identité du menu dans lequel on va ajouter le notre et l'identité de notre menu.
On double clique sur le script pour ouvrir la fenêtre de paramètres.
 
On voit que les paramètres sont divisés en deux groupes, le premier va contenir le ou les menus de base du jeu originel auquel on va ajouter notre menu et en dessous le ou les menus qu'on a créé.
 
Si on prend la première ligne, on voit que le premier paramètre s'appelle WorkshopMenuMain (c'est la variable du script) à droite on a Pick Object et la liste déroulante des objets du jeu (il faut utiliser un filtre pour retrouve le menu sinon c'est l'enfer!!), on va prendre le menu WorkshopMenuMain qui est le menu principal de l'atelier, celui qu'on voit lorsqu'on l'ouvre.
J'ai fait exprès dans le script de nommer cette variable avec le nom du menu pour simplifier le paramètrage en utilisant le bouton Auto-Fill, c'est une astuce pour aller plus vite.
Mais on pourrait très bien prendre un autre menu, le nom de la variable n'a pas d'importance ici, c'est juste pour faciliter le paramètrage.
 
On va faire ensuite la même chose pour notre menu qui ici s'appelle WorkshopMenu01JFV.
 
Voilà on a terminé l'intégration de notre menu dans celui d'origine. Comme vous voyez c'est très simple à faire, il n'y a plus qu'à sauvegarder la quête, le mod et tester.
 
 
Modification du script :
 
 
En cas de besoin on peut rajouter des menus dans le script si on désire placer nos menus dans divers menus d'origine. Pour ce faire, on va devoir modifier la source du script puis le recompiler.
 
On ouvre la source du script avec un clic droit et en choisissant Edit Source.
 
Dans la source on voit en haut deux groupes : VanillaWorkshopMenu et CustomWorkshopMenu, c'est là qu'on va ajouter les variables nécessaires pour d'autres menus
 
FormList Property WorkshopMenuMain auto const
C'est la déclaration de la variable WorkshopMenuMain du menu d'origine. On peut en ajouter d'autres avec la même structure.
 
Ensuite on pass au code lui même qui va détecter le lancement du script et le chargement de la partie.
 
Il y a deux tests, tout simplement parce que la première fois que le jeu démarre avec le mod, la sauvegarde ne contient pas d'info sur celui-ci et la quête. Il faut détecter le démarrage de la quête la première fois pour charger le menu.
 
Event OnQuestInit() va détecter le lancement de la quête et ensuite lancer la fonction install() puis enregistrer l'évènement OnPlayerLoadGame pour plus tard.
 
Event OnPlayerLoadGame(Actor actorref) va par la suite charger le menu par la fonction install().
 
 
Function install() c'est la fonction qui va effectivement charger le menu dans le menu d'origine.
 
WorkshopMenuMain.addForm(WorkshopMenu01JFV) va ajouter notre menu dans le menu de base.
 
 
Une fois qu'on a terminé de modifier la source du script, il faut le compiler
 
 
Si il n'y a pas d'erreur votre script ser recompilé et prêt à servir.
 
 
La source du script d'installation de menus:
 
 
Group VanillaWorkshopMenus
 
  FormList property VanillaWorkshopMenu auto const
 
EndGroup
 
Group CustomWorkshopMenus
 
  FormList property CustomWorkshopMenu auto const
 
EndGroup
 
 
 
Event OnQuestInit()
 
  install()
  RegisterForRemoteEvent(Game.GetPlayer(), "OnPlayerLoadGame")
 
EndEvent
 
 
 
Event Actor.OnPlayerLoadGame(Actor actorref)
 
  install()
 
EndEvent
 
 
 
Function install()
 
  VanillaWorkshopMenu.addForm(CustomWorkshopMenu)
 
EndFunction
 
 
 
 
Désinstallation du menu :
 
 
Si on désinstalle le mod, il ne suffit pas de l'enlever de la liste des mods pour que les menus retrouvent leur aspect d'origine. Le script va laisser des traces dans la sauvegarde et par la suite on peut avoir des bugs dans les menus.
Il faut donc veiller à désinstaller les menu ajoutés avant de désactiver le mod. Pour ce faire on va utiliser une potion magique qui va lancer un script qui va désinstaller les menus.
 
On a besoins de plusieurs choses :
 
Un Magic Effect à créer dans le Creation Kit:

 

Le Magic Effect va lancer le script JFVMenusUnInstaller qui va enlever le menu ajouté et nettoyer le menu d'origine qui a été modifié de toute trace restante.
 
 
Une potion à créer dans le Creation Kit:
 

 

 

Un Constructible Objet pour créer la potion à l'établi de chimie:
 
 
 
Il reste à configurer les paramètres du script de désinstallation dans Magic Effect comme on l'a fait dans la quête utilisée pour l'installation.
 
Lorsqu'on va utiliser la potion, elle va lancer le Magic Effect qui va lancer le script de désinstallation.
 
 
La source du script de désinstallation :
 
 
 
Group VanillaWorkshopMenus
 
  FormList property VanillaWorkshopMenu auto const
 
EndGroup
 
 
Group CustomWorkshopMenus
 
  FormList property CustomWorkshopMenu auto const
 
EndGroup
 
 
bool uninstallCheckRunning = false
 
 
 
Event onEffectStart(Actor akTarget, Actor akCaster)
 
  uninstall_manually()
  checkForUninstall()
 
EndEvent
 
 
 
Function uninstall_manually()
 
  VanillaWorkshopMenu.RemoveAddedForm(CustomWorkshopMenu)
 
EndFunction
 
 
 
Function checkForUninstall()
 
  if (!uninstallCheckRunning)
    uninstallCheckRunning = true
    while (Game.IsPluginInstalled("MyMod.esp"))
      Utility.wait(60)
    endwhile
  removeNoneValues(VanillaWorkshopMenu)
    uninstallCheckRunning = false
  endif
 
EndFunction
 
 
 
Function removeNoneValues(Formlist flst)
   
  Formlist temp = flst
  VanillaWorkshopMenu.revert()
  int i = 0
  while (i < temp.getSize())
    if (temp.getAt(i))
      flst.addForm(temp.getAt(i))
    endif
    i+=1
  endwhile
 
EndFunction