Pattern, veut dire motif en anglais. Leur utilisation est liée à la capacité de crier/parler/murmurer des joueurs et PNJ, il s'agit de motifs de phrase (des expressions régulières super light) que l’on peut mettre en place sur un PNJ. A chaque fois qu'il entendra une phrase correspondant à ce motif, son OnConversation sera lancé, et l’on pourra récupérer l’identifiant du motif entendu (fixé par le script).
Les deux fonctions suivantes seront généralement appelées dans l’OnSpawn du PNJ sensé écouter, quoiqu’elles puissent être utilisées partout ailleurs:
1)
SetListening( oObject, TRUE): pour activer l'écoute par le PNJ (ne fait rien par soi-même: il faut ensuite définir ce qu'il doit écouter)
SetListening(oObject, FALSE) annulera l’appel ci-dessus.
2)
SetListenPattern(oPNJ, sPattern , nIdentifiantDuMotif ): pour que le PNJ recherche un motif particulier(sPattern). Il faut appeler cette fonction pour chaque motif que l'on veut établir.
Les possibilités (symboles servant de briques élémentaires) pour construire la chaîne de caractère qui sert de pattern sont les suivantes :
De Noël (Bioware):
**
s’unifiera avec zéro, un, ou plusieurs caractères (wildcard).
*w
un ou plusieurs espaces
*n
un ou plusieurs chiffres
*p
un ou plusieurs signes de ponctuations.
Note : d’après mes tests il faut entendre par là les points d'intérogation,d'exclamation, et le point final, la virgule ou le point virgule ou l’apostrophe par exemple ne sont pas reconnus. Cela peut donc servir de marqueur de fin de phrase.
*a
une ou plusieurs lettres alphabétiques.
|
est ou
( et )
permettent de construire des bloques.
Exemples :
"**" :
toute phrase prononcée sera reconnue. La chaîne vide ,"", est un cas particulier que bioware s’est réservé.
"a*a"
reconnaîtra tout mot commençant par a, à l’exception de "a" lui-même. Il doit en effet y avoir au moins deux lettres : le a initial et une autre pour *a, qui ne peut pas s’unifier avec la chaîne vide. s’il y a un chiffre ou un espace l’expression ne sera pas reconnue.
"pattern 24"
reconnaîtra "pattern 24" et c’est tout. Attention aux espaces ils comptent! "pattern 24 " ne sera pas reconnu.
"bien(tôt|venue)"
reconnaîtra "bientôt" et "bienvenue"
"**(bonjour|pas)***n"
reconnaîtra entre autre : "bonjour, diablo21", "non! pas diablo 2" mais pas "non! pas diablo" (il faut au moins un chiffre à la fin du fait de " *n ").
3)
GetListenPatternNumber() Cette fonction (ainsi que les deux autre qui suivent) s'utilise dans le OnConversation:
C’est a mon avis le seul slot fiable pour cela, en effet c’est le seul qui garantisse de tout capturer. Sur le OnHeartbeat par exemple, ce que dirait le joueur pourrait être perdu dans le bruit de fond (les phrases prononcées par les PNJs).
Cet événement est aussi lancé en cas de clic sur le PNJ par un joueur (si le curseur est l'icone de conversation). Dans ce cas, GetListenPatternNumber() renvoie -1. Ceci est, à mon avis, lié au cas particulier de "".
GetListenPatternNumber(): Renvoie le numéro du pattern (fixé par l'appel correspondant de SetListenPattern) auquel la phrase entendue s'est unifiée.
Exemple :
Dans le OnSpawn :
SetListenPattern(OBJECT SELF,"bonjour monde",11);
Dans le OnConversation :
int nMatch = GetListenPatternNumber();
Si "bonjour monde" est prononcé à côté du PNJ concerné son OnConversation sera lancé. Et dans le script nMatch prendra la valeur 11.
Une remarque, il est tout à fait possible qu'une phrase puisse s'unifier avec plusieurs patterns, dans ce cas, c'est la pattern qui a été crée en premier qui sera prise en compte, les autres seront simplement ignorées et le OnConversation ne sera lancé qu'une seule fois.
ex:
SetListenPattern(OBJECT SELF,"foo",10);
SetListenPattern(OBJECT SELF,"foo**",11);
Le PNJ entend "foo".
Le OnConversation est lancé une seule fois et GetListenPatternNumber() renverra 10.
Un peu plus compliqué: quand des wildcards (**), ou des *a,*n,*p, ou *w, sont présents dans un pattern, la chaîne de caractère que le PNJ reconnaîtra va être "découpée en morceaux":
4)GetMatchedSubstringCount() renvoie le nombre de morceaux.
5)GetMatchedSubstring(i) renvoie les morceaux en questions (indicés de 0 à GetMatchedSubstringCount() - 1)
un exemple d’application, cette fonction renvoie l’intégralité de la chaîne entendue, quel que soit le pattern utilisé pour la capturer :
string GetStringHeard()
{
int i;
string sString ="";
for(i=0; i < GetMatchedSubstringsCount();i++)
{
sString += GetMatchedSubstring(i);
}
return sString;
}
pattern: "**foo**bar**"
phrase entendue: "le meilleur poste au foot c'est à côté du bar"
Passons sur la phrase en question (je sais pas pourquoi, foo et bar ça réveille mon côté beauf) donc le "but du jeu" c'est de faire correspondre le motif et la phrase entendue, ici, étant donné qu'il y a des ** partout les seules contraintes sont de trouver un "foo" et un "bar" (dans cet ordre de gauche à droite) dans la phrase. On voit que notre phrase est découpée en morceaux:
pattern ** foo ** bar **
chaîne de caractère le meilleur poste au foo t c'est à côté du bar
GetMatchedSubstringsCount() renverrait donc... 5, le fait que la dernière soit "" ne change rien .
GetMatchedSubstring(0) == "le meilleur poste au "
GetMatchedSubstring(1) == "foo"
GetMatchedSubstring(2) == "t c'est à côté du "
GetMatchedSubstring(3) == "bar"
GetMatchedSubstring(4) == ""
L'exemple que j'ai choisi est un peu particulier car l'unification se fait de façon unique, ce n'est généralement pas le cas, hors BIOWARE n'a pas donné, autant que je sache, l'algo d'unification.
D’après mes tests l’unification se fait en maximisant les " morceaux " les plus à droite.
Attention, tout en maximisant, il faut quand même qu’il y ai unification, les mots ou bouts de mots constituent donc des barrières infranchissables.
Pour prendre l’exemple du lexicon un peu modifié pour les besoins de la cause:
SetListenPattern(OBJECT SELF, "**foo**bar****", 500);
Supposons que le PNJ entende "foofoofoobarbarbar":
GetMatchedSubstring(0) renvoie "".
GetMatchedSubstring(1) renvoie "foo".
GetMatchedSubstring(2) renvoie "foofoo".
GetMatchedSubstring(3) renvoie "bar".
GetMatchedSubString(4) renvoie "".
GetMatchedSubstring(5) renvoie "barbar".
Avec:
SetListenPattern(OBJECT SELF, "*afoo*abar*a*a", 500);
On obtient:
GetMatchedSubstring(0) renvoie "foo".
GetMatchedSubstring(1) renvoie "foo".
GetMatchedSubstring(2) renvoie "foo".
GetMatchedSubstring(3) renvoie "bar".
GetMatchedSubString(4) renvoie "b".
GetMatchedSubstring(5) renvoie "arbar".
Tout le "foo" est passé sur le 0 car il n’y a aucun autre moyen d’avoir un foo complet (ce qui est exigé) sur le 1.
5)
TestStringAgainstPattern(sPattern, sChaineATester)
Permet comme son nom l’indique de tester une chaîne de caractères sur un Pattern, renvoyant TRUE si ils peuvent être unifiés, FALSE sinon.
EDIT: bordel j'ai modifié mon message, et au coup d'après j'ai remis la vielle version, je ne vais pas y arriver comme ça
re: la mise en page j'abandonne
a