La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
La date/heure actuelle est 23/11/2024 18:25:39

GC

  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
Répondre en citant
Posté le : 25/05/2005 10:43:52 Sujet du message : GC

Bonjour à tous, je viens soumettre à votre sagacité un système de nettoyage ou "éboueur" basé sur le concept de Garbage Collector, il est assez consistant à mettre en place, mais me donne satisfaction depuis 9 mois sur le module sur lequel notre équipe travaille.
Je tiens à remercier quelques autres concepteurs desquels je me suis inspiré pour les fonctions : en particulier, je suis parti du module du bouchon lyonnais. Egalement, je tiens à citer mon collègue de bureau, expert JVM, absolument pas joueur, pour l'excellente explication du concept.

Tout d'abord, une bibliothèque de fonctions :

Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :
NWScript :
//:: Lylver 2005-01-12
//:: Include File for Area Cleaning
//:: inspire du bouchon lyonnais
//:: ly_lib_area.nss

int CheckPJInArea(object oArea) {
  object oObject = GetFirstObjectInArea(oArea) ;
  int nCount = 0 ;
  while (GetIsObjectValid(oObject)) {
      if (GetIsPC(oObject)) {
      nCount++ ;
      break ;
      }
      oObject = GetNextObjectInArea(oArea) ;
  }
  return nCount ;
}

// * returns true if there is no player in the area
// * has to be ran from an object
// source xp2 module modifie
int NoPlayerInArea(object oArea) {
    object oFirst = GetFirstObjectInArea(oArea) ;
    if( GetIsPC(oFirst) || GetIsDM(oFirst) || GetIsDMPossessed(oFirst) ) return FALSE ;
    // pour le cas ou le seul objet est un PC
    if( !GetIsObjectValid(oFirst) ){
      SendMessageToAllDMs("Erreur : no valid object for GetFirstObjectInArea") ;
      return TRUE;
    }
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oFirst);
    return !GetIsObjectValid(oPC); // * no player in area
}

int CleanBodyBag(object oArea, int nMax = 50) {
  int nCost = 0 ;
  object oItem ;
  object oBag = GetFirstObjectInArea(oArea) ;
  while (GetIsObjectValid(oBag)) {
      if( (GetObjectType(oBag) == OBJECT_TYPE_PLACEABLE) && (GetTag(oBag) == "BodyBag") ){
        nCost++ ; // incremente le nombre des objets effectivement traites
        oItem = GetFirstItemInInventory(oBag) ;
        while (oItem != OBJECT_INVALID) {
            nCost++ ;
            DestroyObject(oItem) ;
            oItem = GetNextItemInInventory(oBag) ;
        }
        // DestroyObject(oBag,0.1) ; pas besoin : le moteur le fait, mais ou passent les BodyBags ?
      }
      oBag = GetNextObjectInArea(oArea) ;
      if (nCost > nMax) { nCost = -1 * nCost ; break ;}
  }
  return nCost ;
}

int CleanPNJ(object oArea, int nMax = 50) {
  object oPnj = GetFirstObjectInArea(oArea) ;
  int nCost = 0 ;
  while (GetIsObjectValid(oPnj)) {
      if( GetIsEncounterCreature(oPnj) ){
        nCost++ ;
        DestroyObject(oPnj) ;
      }
      oPnj = GetNextObjectInArea(oArea) ;
      if (nCost > nMax) { nCost = -1 * nCost ; break ;}
  }
  return nCost ;
}

int CleanItem(object oArea, int nMax = 50) {
  object oItem = GetFirstObjectInArea(oArea) ;
  object oLostItem = GetObjectByTag("CHEST_LOST_ITEM") ;
  int nCost = 0, bChest = GetIsObjectValid(oLostItem) ;
  while (GetIsObjectValid(oItem)) {
      if( GetObjectType(oItem) == OBJECT_TYPE_ITEM ){
        nCost++ ;
        if( bChest ) CopyItem(oItem,oLostItem) ;
        DestroyObject(oItem) ;
      }
      oItem = GetNextObjectInArea(oArea) ;
      if (nCost > nMax) { nCost = -1 * nCost ; break ;}
  }
  return nCost ;
}

// void main() {}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.



Le script suivant est à adapter/inclure sur le OnModuleLoad

Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :
NWScript :
void main()
{

// begin add-on Lylver 2005-05-21
SignalEvent(OBJECT_SELF, EventUserDefined(300));

// end add-Lylver
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Le script suivant est à adapter/inclure sur le OnUserDefined du module

Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :
NWScript :
/*
    Incorporate this code into Module::OnUserDefined
*/

// Update : lylver 07/04/2004
// Nom : ly_mod_userdef
//:: Update Lylver 2005-01-12
//:: Garbage Collector
//:: + Fix du switch incorrect

void main() {
switch (GetUserDefinedEventNumber()) {

case 300:{
  ExecuteScript("ly_mod_area_gc",OBJECT_SELF) ;
  break ;
  }
} /* switch */

}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.



Maintenant le script principal

Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :
NWScript :
//:: Lylver 2005-04-28
//:: ly_mod_area_gc.nss
//:: nouvelle fonction de test PJ dans zone
//:: GC main non affecte
//:Confused///////////////////////// //////////
//:: Lylver 2005-03-08
//:: Copie des items perdus (abandonne)
//:: dans le coffre des objets trouves
//:Confused///////////////////////// //////////
//:: Lylver 2005-01-12
//:: Module Garbage Collector

#include "ly_lib_area"

void main() {
  object oMod = GetModule() ;
  int nBodyBag=0,nPNJ=0,nItemLost=0,bEmptyArea ;
  int CleanP = GetLocalInt(oMod,"CLEANP") ;
  string sArea = "" ;
  object oArea = GetLocalObject(oMod,"CLEANQ") ;
  // SendMessageToAllDMs("GC : Hello ! I'm Here !") ;
  if (oArea != OBJECT_INVALID) { // j'ai une zone a traiter
      sArea = GetTag(oArea) ; // un run de nettoyage courant
      /* code */
      SendMessageToAllDMs("GC : operating on Area : " + GetName(oArea)) ;
      WriteTimestampedLogEntry("GC : operating on Area : " + GetName(oArea)) ;
      bEmptyArea = NoPlayerInArea(oArea) ;
      if( GetLocalInt(OBJECT_SELF,"PC_HERE") == 1 ){
        SendMessageToAllDMs("Warning GC : PC_HERE est a etat 1");
        WriteTimestampedLogEntry("Warning GC : PC_HERE est a etat 1");
      }
        // default cleaning : 50 items in one pass, return negative for 2nd check later
        // CleanBodyBag(object oArea, int nMax = 50)
      if( bEmptyArea ){ // si la zone est effectivement vide on nettoie
        nBodyBag = CleanBodyBag(oArea) ;
        nPNJ = CleanPNJ(oArea) ;
        nItemLost = CleanItem(oArea) ;
      } else { // mais si quelqu'un est la, on abandonne et on purge la queue
        DeleteLocalInt(oMod,"CLEANQ" + sArea) ;
        DeleteLocalObject(oMod,"CLEANQ") ;
        DelayCommand(6.0,SignalEvent(OBJECT_SELF, EventUserDefined(300))) ; // pas trop vite
        return ; // exit et recommence
      }
      // test si c'est fini (pas de code retour negatif
      if( (nBodyBag >= 0) && (nPNJ >= 0) && (nItemLost >=0) ){ // oui on prend la requete suivante
        DeleteLocalInt(oMod,"CLEANQ" + sArea) ;
        DeleteLocalObject(oMod,"CLEANQ") ;
        DelayCommand(6.0,SignalEvent(OBJECT_SELF, EventUserDefined(300))) ; // qu'on examine
        return ; // exit et recommence
      } else { // on termine rapidement
        SetLocalInt(oMod,"CLEANQ" + sArea, 29 + GetLocalInt(oMod,"CLEANQ" + sArea)) ; // passage + rapide
      }
  } else { // pas de zone en cours, alors on examine les requetes
      oArea = GetLocalObject(oMod,"CLEANR") ;
      if (oArea != OBJECT_INVALID) { // trouve qq chose a faire
        // SendMessageToAllDMs("GC : switching to Area : " + GetName(oArea)) ;
        sArea = GetTag(oArea) ; // gere la file d'attente
        SetLocalObject(oMod,"CLEANQ",oArea) ; // passe en clean courant
        SetLocalInt(oMod,"CLEANQ" + sArea, CleanP) ; // delai suivant
        // dependant de la plus longue des autres attentes en cours
        DeleteLocalInt(oMod,"CLEANR" + sArea) ;// libere le semaphore
        DeleteLocalObject(oMod,"CLEANR") ;
      } else { // meme si pas prise, il peut y avoir une demande de plus faible priorite
      // en boucle, on en tient compte en retestant plus vite apres reset priorite
        sArea = "" ;
        if( CleanP > 0 ){
            SetLocalInt(oMod,"CLEANQ", CleanP) ; // delai suivant
            DeleteLocalInt(oMod,"CLEANP") ; // reset priorite globale
        }
      }
      // else SendMessageToAllDMs("GC : Nothing to Do") ;
  }
  // on ne nettoie pas immediatement mais en fonction de la priorite de la requete
  // pour conserver une latence avant destruction des monstres 174s mini + 6s du a la purge
  float fDelay = 180.0 - 6.0 * IntToFloat((1+GetLocalInt(oMod,"CLEANQ"+sArea))) ; // 180 secondes maxi
  if (fDelay < 6.1) fDelay = 6.1 ; // pas trop vite pour la sortie de boucle des OnExit
  DelayCommand(fDelay, SignalEvent(OBJECT_SELF, EventUserDefined(300)));
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.



L'activation du nettoyage par l'évênement OnExit d'une zone

Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :

NWScript :
//:: Lylver 2005-04-28
//:: ly_onexit_area.nss
//:: nouvelle fonction de test PJ dans zone
//:: Lylver 2005-01-15
//:: OnExit Area
//:: GC
//:: Lylver 2005-02-07
//:: update

void main() {
  object oPC = GetExitingObject() ;
  string sArea = GetTag(OBJECT_SELF) ;
  int bInteractive = GetIsPC(oPC) || GetIsDM(oPC) || GetIsDMPossessed(oPC) ;
  if( bInteractive ){ ExecuteScript("ly_onexit_loop",OBJECT_SELF); } // sous-fonction pour le GC
  else { // traitement des PNJs qui sortent de leur zone a la poursuite des PJs ou

  // par ceux qui patrouillent hors de vue des joueurs : duree de vie 180 secondes
      if( GetIsEncounterCreature(oPC) && !GetIsObjectValid(GetMaster(oPC)) ){
      /* if( NoPlayerInArea(OBJECT_SELF) ){
            SetLocalInt(oPC,"DESTROY& quot;,180) ; // au cas ou la difference serait necessaire
        } else {
            SetLocalInt(oPC,"DESTROY& quot;,180) ;
        }      */

        SetLocalInt(oPC,"DESTROY",180) ;
        WriteTimestampedLogEntry("Zone "+sArea+" OnExit : "+GetName(oPC)+" marked for destroy") ;
      }
      return ;
  }
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Un script spécifique que j'ai détaché (j'ai parfois d'autres fonctions sur le OnExit)

Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :
NWScript :
//:: Lylver 2005-04-28
//:: ly_onexit_loop.nss
//:: nouvelle fonction de test PJ dans zone
//:: Lylver 2005-01-15
//:: OnExit Area
//:: Activation du GC : boucle d'attachement
#include "ly_lib_area"
void main()
{
  object oMod = GetModule() ;
  string sArea = GetTag(OBJECT_SELF) ;
  int nPJ;
  int CleanQ = GetLocalInt(oMod,"CLEANQ" + sArea) ;
  int CleanR = GetLocalInt(oMod,"CLEANR" + sArea) ;
  int CleanP = GetLocalInt(oMod,"CLEANP") ;
  if( CleanQ > 0 ){ // GC should be here
      if( GetLocalObject(oMod,"CLEANQ") == OBJECT_SELF ){ // GC ici : suppression de demande surnumeraire
        DeleteLocalInt(oMod,"CLEANR" + sArea) ; // reset a neutre
        if( GetLocalObject(oMod,"CLEANR") == OBJECT_SELF ){
            DeleteLocalObject(oMod,"CLEANR") ; // free GC [espere operation atomique]
        }
        WriteTimestampedLogEntry("Warning : GC OnExitLoop : "+sArea+" GC here : cancelling outnumbered request") ;
      } else { // cas d'erreur
        DeleteLocalInt(oMod,"CLEANQ" + sArea) ;
        WriteTimestampedLogEntry("Warning : GC OnExitLoop : "+sArea+" found area counter without object, resetting.") ;
      }
      return ; // GC is busy on our zone or repaired mismatch
  }
  if( CleanR < 0 ){ // traite l'annulation demandee
      DeleteLocalInt(oMod,"CLEANR" + sArea) ; // reset a neutre
      if( GetLocalObject(oMod,"CLEANR") == OBJECT_SELF ){
        DeleteLocalObject(oMod,"CLEANR") ; // free GC [espere operation atomique]
      }
      // SendMessageToPC(GetExitingObje ct(), "OnExit : GC called but ordered stop : " + sArea) ;
      CleanR = 0 ; // poursuit, test PJ plus loin
  }
  if( CleanR == 0 ){ // etat standard
//      nPJ = CheckPJInArea(OBJECT_SELF) ; fonction NoPlayerInArea 5* plus rapide
      if( NoPlayerInArea(OBJECT_SELF) ){ // controle
        // raz variable de statut
        if( GetLocalInt(OBJECT_SELF,"PC_HERE") == 1) DeleteLocalInt(OBJECT_SELF,"PC_HERE") ;
//        if( nPJ &gt; 0 ) WriteTimestampedLogEntry(" ;Erreur : GC OnExitLoop Resultat CheckPJ et NoPlayer different");
      } else {
        WriteTimestampedLogEntry("Warning : GC OnExitLoop : PJ here, no hooking") ;
        return ; // pas de hooking : il y a du monde
      }
  }
  if( CleanR > 0 ){ // je suis deja passe ou alors un deuxieme PJ vient de sortir
      if( NoPlayerInArea(OBJECT_SELF) ){ // controle
        // raz variable de statut
        if( GetLocalInt(OBJECT_SELF,"PC_HERE") == 1) DeleteLocalInt(OBJECT_SELF,"PC_HERE") ;
      } else { // stop ! : quelqu'un est la, pas besoin de nettoyer
        DeleteLocalInt(oMod,"CLEANR" + sArea) ; // reset a neutre
        if( GetLocalObject(oMod,"CLEANR") == OBJECT_SELF ){
            DeleteLocalObject(oMod,"CLEANR") ; // free GC [espere operation atomique]
        }
        WriteTimestampedLogEntry("Warning : GC OnExitLoop Stop Other Hooking") ;
        return ; // stop other running hooking : il y a du monde
      }
  }
  // Warning : overload
  if( CleanR > 300 ) WriteTimestampedLogEntry("Warning : GC OnExitLoop Slow Hooking") ;
  // hooking, ajout de prioritisation
  if( (GetLocalObject(oMod,"CLEANR") == OBJECT_INVALID) && (CleanR >= CleanP) ){ // semaphore vide
      SetLocalObject(oMod,"CLEANR",OBJECT_SELF) ; // signal GC [espere operation atomique]
      WriteTimestampedLogEntry("Warning : GC OnExitLoop "+sArea+" Hooking") ;
      return ; // yes I'm hooked !
  }
  if( GetLocalObject(oMod,"CLEANR") == OBJECT_SELF ){ // semaphore pris par moi-meme
      WriteTimestampedLogEntry("Warning : GC OnExitLoop "+sArea+" already hooked") ;
      return ; // yes I've been hooked !
  }
  // semaphore pas libre, increment compteur : accelere GC
  SetLocalInt(oMod,"CLEANR" + sArea,++CleanR) ;
  if( CleanR > CleanP ) SetLocalInt(oMod,"CLEANP",CleanR) ; // monte la priorite a soi-meme
  // pour prendre une option
  WriteTimestampedLogEntry("Warning : GC OnExitLoop "+sArea+" nb "+IntToString(CleanR)+" Hooking failed : recheck in 6 secondes") ;
  // SendMessageToAllDMs("OnEx it : GC called : " + sArea + IntToString(CleanR)) ;
  DelayCommand(6.0,ExecuteScript("ly_onexit_loop",OBJECT_SELF)) ; // recheck in 6 seconds
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Et enfin un deuxième script pour la zone à mettre sur le OnEnter
Ce message est un spoiler, et risque de vous informer de choses que vous auriez dû apprendre par vous même (fin d'un jeu, film, etc). À vos risques et périls (ludiques), vous pouvez le voir en cliquant sur cet avertissement.
Spoiler :
NWScript :
//:: Lylver 2005-04-28
//:: ly_onenter_area.nss
//:: nouvelle fonction de test PJ dans zone
//:: Lylver 2005-01-12
//:: Signal to Garbage Collector that PC are here
//:: Put OnEnter of Area

#include "ly_lib_area"
void main() {
  object oPC = GetEnteringObject() ;
  string sArea = GetTag(OBJECT_SELF) ;
  int bInteractive = GetIsPC(oPC) || GetIsDM(oPC) || GetIsDMPossessed(oPC) ;
  if( bInteractive ){
      WriteTimestampedLogEntry("Zone "+sArea+" OnEnter : "+GetName(oPC)) ;
  } else { // traitement des PNJs qui sortent de leur zone a la poursuite des PJs ou
  // par ceux qui patrouillent hors de vue des joueurs : duree de vie 180 secondes
      int nDestroy = GetLocalInt(oPC,"DESTROY") ;
      if( nDestroy != 0 ){
        if( NoPlayerInArea(OBJECT_SELF) ){
            DestroyObject(oPC,IntToFloat(nDestroy)) ;
            WriteTimestampedLogEntry("Zone "+sArea+" OnEnter, no PJs : "+GetName(oPC)+" will be destroyed") ;
        }
      }
      return ;
  }
  object oMod = GetModule() ;
  if( bInteractive ){
      if( GetLocalObject(oMod,"CLEANQ") == OBJECT_SELF ){ // check GC is in Area
        // SendMessageToAllDMs("OnEn ter : GC operating : Ordering Stop : " + sArea) ;
        // SendMessageToPC(GetEnteringObj ect(), "OnEnter : GC operating : Ordering Stop : " + sArea) ;
        DeleteLocalObject(oMod,"CLEANQ") ; // stop GC on Area
        DeleteLocalInt(oMod,"CLEANQ" + sArea) ; // counter also
      }
      if( GetLocalObject(oMod,"CLEANR") == OBJECT_SELF ){ // check GC called for Area
        // SendMessageToAllDMs("OnEn ter : GC called : cancelling " + sArea) ;
        // SendMessageToPC(GetEnteringObj ect(), "OnEnter : GC called : cancelling " + sArea) ;
        DeleteLocalObject(oMod,"CLEANR") ; // cancel GC call for Area
        SetLocalInt(oMod,"CLEANR" + sArea,-1) ; // demande d'arret
        // Note : -1 to reset zone counter done by ly_onexit_area, stoping hook-loop also
      }
      // variable de statut pour usage futur
      if( GetLocalInt(OBJECT_SELF,"PC_HERE") == 0) SetLocalInt(OBJECT_SELF,"PC_HERE",1) ;
  }
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Si vous avez eu le courage de lire jusqu'ici voici le mode d'emploi
- créer ces scripts dans votre module : ly_lib_area, ly_mod_area_gc, ly_onenter_area, ly_onexit_area et ly_onexit_loop
- adapter/éventuellement créer des scripts pour les évênements OnModuleLoad/OnUserDefined du Module
- ajouter les scripts ly_onenter_area et ly_onexit_area sur les évênements OnEnter/Onexit des zones dont vous voulez gérer le nettoyage

Note : j'autorise les monstres à se déplacer entre plusieurs zones, GC gère ceux-ci.

Pour ceux qui veulent tester : j'ai repris ces scripts et éludé quelques lignes qui ajoute des fonctions autres, pour rester dans le cadre du nettoyeur. Ce système a été longuement vérifié (logs et nwnx2 pour les performances) mais il peut subsister quelques bugs/morceaux de code inutile, je suis preneur des remarques
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Flumby
Chevalier
Inscrit le: 01 Juin 2006
Messages: 71
Répondre en citant
Posté le : 12/10/2006 15:38:36 Sujet du message :

en utilisant la fonction rechercher, je suis tomber sur ce nettoyeur de zone.

Je n'arrive pas a comprendre comment le faire tourner, il m'a l'air pourtant bien sympathique.

Pour un besoin ponctuel, j'ai tenté d'installer le tout sur un module vierge de tout autre script, sans nwnx ou FF et ca refuse de marcher.

J'ai pourtant bien suivi toutes les recommandations.


Citation :
Si vous avez eu le courage de lire jusqu'ici voici le mode d'emploi
- créer ces scripts dans votre module : ly_lib_area, ly_mod_area_gc, ly_onenter_area, ly_onexit_area et ly_onexit_loop
- adapter/éventuellement créer des scripts pour les évênements OnModuleLoad/OnUserDefined du Module
- ajouter les scripts ly_onenter_area et ly_onexit_area sur les évênements OnEnter/Onexit des zones dont vous voulez gérer le nettoyage
Pour vérifier si ca marchait, j'ai décoter tous les commentaires de message PC ou DM.

J'ai donc créé 2 zones, dont les différents événement sont indiqués. Je me connecte MD ou joueur, je place quelque PNJ et autres créatures. Je change de zone, attend quelque quarts d'heures. Et la rien ne se passe...

Faut il nécessairement un FF ou nwnx pour le faire tourner ? Ai je loupé une étape ?
_________________
Premier DM a avoir inauguré la chute d'auberge sur Joueur rebel

Preuve Smile => http:
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Flumby
Chevalier
Inscrit le: 01 Juin 2006
Messages: 71
Répondre en citant
Posté le : 13/10/2006 15:40:46 Sujet du message :

Bon bah j'ai résolu mon probleme.
_________________
Premier DM a avoir inauguré la chute d'auberge sur Joueur rebel

Preuve Smile => http:
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Anthraxcite
Légende vivante
Inscrit le: 12 Juin 2004
Messages: 372
Localisation: Belgique
Répondre en citant
Posté le : 13/10/2006 17:49:31 Sujet du message :

Pour la première fonction :
NWScript :
int CheckPJInArea(object oArea) {
  object oObject = GetFirstObjectInArea(oArea) ;
  int nCount = 0 ;
  while (GetIsObjectValid(oObject)) {
      if (GetIsPC(oObject)) {
      nCount++ ;
      break ;
      }
      oObject = GetNextObjectInArea(oArea) ;
  }
  return nCount ;
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.

Ce ne serait pas plus économique de boucler sur la liste des joueurs plutôt? Surtout pour les zones à grand nombre d'objets...
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur MSN Messenger Ignorer l'utilisateur
 
Montrer les messages depuis :
Page 1 sur 1 ¤


Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Sauter vers:
FAQ | Rechercher | Liste des Membres | Groupes d'utilisateurs | S'enregistrer | Profil | Se connecter pour vérifier ses messages privés | Connexion
Powered by phpBB 2.* [m] © 2001, 2002 phpBB Group
Theme rewritten in beautiful XHTML code by Baldurien.
Thème "La Bibliothèque de Neverwinter" crée par Kruger
Traduction par : phpBB-fr.com
Page generated in 113.848ms