Bonsoir
Voilà quelques petites fonctions de rien du tout qui m'ont bien aidées, donc je me suis dit que ça pourrait aider quelqu'un d'autre.
Elle ont été faites à la base pour prendre aléatoirement un objet sur une zone, sans pour autant refaire le script à chaque changement de zone, sans se soucier du nombre d'objets de même type sur la zone, et sans mettre de variable sur un objet
Exemple : je veux prendre aléatoirement un Waypoint, mais ce waypoint doit avoir une variable X à 4 (pour faire apparaître un créature, un effet spécial, etc).
Problème N°1 : l'utilisation des fonctions
GetFirstObjectInArea et
GetNextObjectInArea fera que l'on tombera toujours sur le même waypoint, ce qui rend l'aléatoire inopérant . Donc il faut compter le nombre de Waypoint dans la zone et appliquer
Random () ensuite avec une boucle on prend aléatoirement le waypoint (boucle de type
while )
Problème N°2 : si l'on a beaucoup de WP sur la zone, et que seul un petit nombre de ces WP n'ont pas la propriété voulue, la recherche aléatoire peut durer une éternité (d'ailleurs rien qu'avec un seul WP qui n'a pas la propriété voulue il y a une chance, même infime, que la fonction renvoie toujours celui si et donc que la boucle continue indéfiniement). Du coup j'ai fait une autre fonction qui crée une boucle décalée dont le décalage sera lui aléatoire. (en gros on a une suite avec des numéros qui se suivent 1,2,3,4,5,6,7,8,9,10, et la boucle décalée scannera les objets N° 4,5,6,7,8,9,10,1,2,3 si elle est décalée de 3)..
Donc on regardera tous les objets, quel qu'ils soient. Et s'il n'existe qu'un seul qui corresponde, on le trouvera parmi une multitude.
// choisi le 1er objet de la zone en excluant un type d'objet
// fait pour compter le nombre d'objet de même type
object ChoiseFirstObject (object oAreaChoiseObject, int iTypeExclude)
{
object oFirstObjectChoise = GetFirstObjectInArea (oAreaChoiseObject);
while (GetObjectType (oFirstObjectChoise) == iTypeExclude)
{
oFirstObjectChoise = GetNextObjectInArea (oAreaChoiseObject);
}
return oFirstObjectChoise;
}
// Compte et renvoie le nombre d'objets de type nType
// nType : OBJECT_TYPE_CREATURE, OBJECT_TYPE_DOOR,
// OBJECT_TYPE_WAYPOINT, OBJECT_TYPE_PLACEABLE, etc..
int ObjectCompteur (object oArea, int nType)
{
object oFirstObject = ChoiseFirstObject(oArea, nType);
int iCompt = 0;
object oObject = GetNearestObject (nType, oFirstObject , iCompt );
while (oObject != OBJECT_INVALID)
{
iCompt ++;
oObject = GetNearestObject (nType, oFirstObject ,iCompt );
}
// je sais pas pourquoi mais il y en a toujours 1 de plus...
// peut etre que le n°0 et le n°1 sont les mêmes
iCompt --;
return iCompt ;
}
// prend une boucle et donne le résultat sur une boucle décalée
// Rajoute iRandomBoucle tout en restant en dessous du max
// sert à se servir d'une fonction aléatoire avec condition
// sans risquer de toujours tomber toujours sur un mauvais objet
int GetBoucle (int iNbBoucle, int iRandomBoucle, int iBoucleMax)
{
int iResult = iRandomBoucle + iNbBoucle ;
if (iResult > iBoucleMax) iResult = iResult - iBoucleMax;
return iResult;
}
donc voilà avec ces fonctions on peut prendre aléatoirement mon Waypoint qui aura une variable int X égale à 4 avec ces lignes, parmi quelques WP qui possèdent cette propriété, même s'il y a 200 WP sur la zone et seulement 2 WP qui ont une variable X à 4.
//oArea est la zone acquise avec GetArea()
object oFirstObject = ChoiseFirstObject (oArea, OBJECT_TYPE_WAYPOINT );
int nRandomBcle = Random (ObjectCompteur (oArea, OBJECT_TYPE_WAYPOINT)+1); // le décalage de la boucle est aléatoire
int nRandomBclCompt = 1;
object oWPSpawn = OBJECT_INVALID;
int iVar;
while ((oWPSpawn == OBJECT_INVALID)||(iVar != 4)
{
oWPSpawn = GetNearestObject (OBJECT_TYPE_WAYPOINT, oFirstObject,GetBoucle (nRandomBclCompt, nRandomBcle, iDoorAleat));
iVar= GetLocalInt (oWPSpawn, "X");
nRandomBclCompt ++;
}