Les fichiers dit "includes" (pour Inclusion, hé, l'aut' !) sont des bibliothèques de fonctions. On y trouve ni fonction main(), ni fonction StartingConditional(), mais uniquement des fonctions personnelles.
Les includes ne peuvent pas êtres compilés indépendamment d'un autre script, il suffit donc de les sauvegarder. Ils peuvent avoir plusieurs fonctions.
Il y a un truc chiant dans les scripts de Bioware, c'est les noms de fonctions de 12km. Par exemple :
GetNearestObjectByTag(string sTag, int nCount);
C'est joli, mais quand on l'utilise 28x par script, c'est un peu chiant a réécrire. Alors on peut définir un alias, c'est à dire une copie exacte de la fonction, avec un nom plus court :
object GNOT(string sTag, int nCount) {
return GetNearestObjectByTag(sTag, nCount);
}
Déjà 'achement moins long !
Les alias peuvent aussi servir pour des fonctions "nouvelles mais pas vraiment". En gros, simplifier une fonction en fonction (haha) de l'usage qu'on en fait. Exemple : Spawner un PNJ. Ca revient à faire un appel sur CreateObject(OBJECT_TYPE_CREATURE, gnagna, etc). C'est long, et c'est pas utile. On déclare un alias !
void SpawnNPC(string sTemplate, float fX = 0.0, float fY = 0.0, float fZ = 0.0, float fFacing = 0.0, int bFade = FALSE) {
CreateObject(OBJECT_TYPE_CREATURE,sTemplate,Location(GetArea(OBJECT_SELF), Vector(fX,fY,fZ), fFacing),bFade);
}
Et hop, pour faire apparaitre un PNJ en X=8, Y=5, on a plus qu'a faire
SpawnNPC("MonPNJ",8.0f,5.0f);
Super simple !
On peut également définir des fonctions qui n'existent pas, mais qu'on utilise souvent. Par exemple :
int CountItemsOnObject(object oContainer, string sItemTag) {
int nReturn = 0;
if(GetIsObjectValid(oContainer) && sItemTag != "") {
object oScan = GetFirstItemInInventory(oContainer);
while(GetIsObjectValid(oScan)) {
if(GetTag(oScan) == sItemTag) nReturn += GetNumStackedItems(oScan);
}
}
return nReturn;
}
C'est utile !
Tout ça c'est très bien, me direz-vous, mais pourquoi pas bêtement coller la fonction au début de tous mes scripts ? C'est simple. Pour organiser, centraliser, optimiser ! Imaginez que vous faites une série de 125 scripts pour une quête de 20h de jeu. Dans tous ses scripts, vous mettez vos fonctions. Viens le moment de l'essai, et Ô torpeur, il y a un bug dans une de vos fonctions !! Vous voilà bon pour quelques heures de copier/coller en plus de la correction du bug. Si vous aviez centralisé vos fonctions dans un include, il suffisait de le modifier, de recompiler le module, et le tour était joué...
Une petite astuce en prime : Comment faire apparaitre sa fonction dans la liste, à droite ? Il faut la déclarer avant. En gros, il suffit de copier la première liste de la fonction, et d'y changer l'accolade ouvrante par un point-virgule. Les déclarations de fonctions se font généralement tout au début du script. Vous pouvez également ajouter un commentaire qui apparaitra dans l'aide en bas de l'éditeur de script, il suffit de le mettre au dessus de votre déclaration de fonction. Exemple :
// Tynclude : Nombre d'objets d'un certain tag
// oContainer -> Contenant dans lequel chercher
// sTag -> Tag de l'objet a compter
int CountItemsOnObject(object oContainer, string sItemTag);
Et maintenant, j'ai mon fichier include, comment je l'utilise ? Simplement ajouter une ligne tout au début de votre script, avant toutes les fonctions :
#include "LeNomDeMonScript"
Ce dont il faut se gaffer :
- Les includes recursifs
J'inclut un include dans mon include, et dans l'include que j'inclus, j'inclus mon include. Moyen d'éviter : ne pas mettre d'include dans un include.
- La recompilation
Je change mon include, mais ça ne corrige pas mon bug. Moyen d'éviter : Recompiler le module (Créer > Module) à chaque modification d'un include.
Enjoy!