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 16:38:26


  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
Silverwave
Ecuyer
Inscrit le: 21 Mai 2003
Messages: 69
Répondre en citant
Posté le : 27/01/2004 07:20:35 Sujet du message : OnHeartBeat de plus de 6 secondes?

Normalement un OnHearBeat déclenche les commandes dans ce script à tous les 6 secondes... mais si je veux que le heartbeat ne soit délenché qu'à tous les 30 secondes, par exemple, que dois-je faire?

J'ai essayer de mettre un DelayCommand mais le problème c'est que le script ne se délenche, en effet, pas avant 30 secondes mais à partir de ces 30 premières secondes, il se déclenche ensuite normalement, soit à tous les 6 secondes.

Quelqu'un connait un moyen de le faire déclencher véritablement à tous les 30 sec?
_________________
~ J'suis rendu un écuye ! Yé ! ~

Laughing:
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
lendraste
Grand Maître Chanteur du Conseil
Inscrit le: 20 Fév 2003
Messages: 1403
Localisation: Quelque part ailleurs
Répondre en citant
Posté le : 27/01/2004 08:24:32 Sujet du message :

Un solution consiste à faire en sorte de ne tenir compte du OnHeartBeat que tout les 5 déclenchements. En d'autres termes, tu n'empêcheras pas de se déclencher toutes les 6 secondes, mais à chacun de ces déclenchements tu peux compter. Quand tu est arrivé à 5 ( 5 x 6 = 30 secondes), tu remets le compteur à zéro et tu exécutes ce que tu avais prévus. Voici le squelette de la solution à placer sur un OnHeartBeat:
NWScript :

void main()
{
  int nCount=GetLocalInt(OBJECT_SELF, "OHB_COUNT");
  if (nCount<5)
  {
    nCount++; // On ajoute 1
    SetLocalInt(OBJECT_SELF, "OHB_COUNT", nCount); // On sauve la nouvelle valeur
  }
  else
  {
   
    SetLocalInt(OBJECT_SELF, "OHB_COUNT", 0);

   
  }
}
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.


Attention toutefois à ne pas généraliser ce processus. Sur un OnHeartBeat, OK, sur 100 ça ne le fait pas. S'il s'agit d'une utilisation marginale, tu peux te servir de cette solution. Si tu as besoin de faire accomplir quelque chose à toutes les créatures de ton module toutes les 30 secondes, le OnHeartBeat n'est pas forcément la meilleure solution.
_________________
Lendraste de Loreval
Qui cherche la Vérité cherche celui qui la détient, car elle n'existe pas à l'état naturel.
La cité des mensonges - 1
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Numéro ICQ Ignorer l'utilisateur
 
Silverwave
Ecuyer
Inscrit le: 21 Mai 2003
Messages: 69
Répondre en citant
Posté le : 27/01/2004 16:53:29 Sujet du message :

Évidemment, la réponde était simple ! Et ça marche très bien.
Merci pour le tuyau Smile
_________________
~ J'suis rendu un écuye ! Yé ! ~

Laughing:
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
Répondre en citant
Posté le : 15/04/2005 17:18:09 Sujet du message : Heart-Beat limité

Pour des raisons d'économie de temps de calcul, on entend régulièrement : limiter les heart-beat dans les modules.
Je soumets à votre lecture quelques scripts de heart-beat

Tout d'abord, un heart-beat global, conditionné à la présence des joueurs dans une zone

NWScript :
//:: //////////////////
//:: Lylver 2005-04-12
//:: module Heart-Beat : put on OnModuleHeartBeat of the module
//:: Optimizing by hooking fonction
//:: and passivation
//:: //////////////////

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

void main()
{
  object oMod = GetModule() ;
  object oArea ;
  int nHB = GetLocalInt(oMod,"N_FHB_AREA"), n ;
  for( n=1 ; n <= nHB ; n++ ){
      if( GetLocalInt(oMod,"FHB_ACTIF"+IntToString(n)) ){ // fast check, one call + test
        oArea = GetLocalObject(oMod,"FHB_AREA"+IntToString(n)) ;
        if( CheckPJInArea(oArea) == 0 ){
            SetLocalInt(oMod,"FHB_ACTIF"+IntToString(n),FALSE) ; // passivation
            WriteTimestampedLogEntry("Hooked Zone : "+GetTag(oArea)+"-"+GetName(oArea)+" passivated");
        } else {
            ExecuteScript(GetLocalString(oArea,"FHB_SCRIPT"),oArea) ;
            // SendMessageToAllDMs("Hook ed Zone : "+GetTag(oArea)+"-&q uot;+GetName(oArea)+" doing its Heart-Beat");
            WriteTimestampedLogEntry("Hooked Zone : "+GetTag(oArea)+"-"+GetName(oArea)+" doing its Heart-Beat");
        }
      }
  }
}
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 aussi la façon d'activer le heart-beat ou le réactiver lorsque qu'une créature entre dans la zone.

NWScript :
//:: //////////////////
//:: Lylver 2005-04-12
//:: module Heart-Beat : put on OnEnter of Area(s)
//:: attach to HB when PC enter area
//:: Optimizing by hooking fonction
//:: and passivation when no PC
//:: //////////////////

void main()
{
  object oSelf = OBJECT_SELF ;
  object oMod = GetModule() ;
  int nHB = GetLocalInt(oMod,"N_FHB_AREA"), n, nHooked=FALSE ;
  for( n=1 ; n <= nHB ; n++ ){
      if( GetLocalObject(oMod,"FHB_AREA"+IntToString(n)) == oSelf ){
        nHooked = TRUE ;
        if( GetLocalInt(oMod,"FHB_ACTIF"+IntToString(n))== FALSE ){ // passive ?
            SetLocalInt(oMod,"FHB_ACTIF"+IntToString(n),TRUE) ; // hooked, reactivated
            SendMessageToAllDMs("Hooked Zone : "+GetTag(oSelf)+"-"+GetName(oSelf)+" reactivated to Heart-Beat");
            WriteTimestampedLogEntry("Hooked Zone : "+GetTag(oSelf)+"-"+GetName(oSelf)+" reactivated to Heart-Beat");
        }
        break ;
      }
  }
  if( nHooked == FALSE ){ // Hooking the Area to the HB
      nHB++ ;
      SetLocalInt(oMod,"N_FHB_AREA",nHB) ;
      SetLocalObject(oMod,"FHB_AREA"+IntToString(nHB),oSelf);
      SetLocalInt(oMod,"FHB_ACTIF"+IntToString(nHB),TRUE) ; // hooked, activated
      SetLocalString(oSelf,"FHB_SCRIPT","script_hb_de_la_zone") ;
      ExecuteScript("script_hb_de_la_zone", oSelf); // optionnel, si vous pouvez attendre le prochain HB, enlevez cette ligne
      SendMessageToAllDMs("Hooking Zone : "+GetTag(oSelf)+"-"+GetName(oSelf)+" to Heart-Beat");
      WriteTimestampedLogEntry("Hooking Zone : "+GetTag(oSelf)+"-"+GetName(oSelf)+" to Heart-Beat");
  }
  ExecuteScript("script_onenter_area",oSelf);
}
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.


Explication et divers effets constatés.
Faire tourner un script de heart-beat sur la fonction OnModuleHeartBeat doit donc être codé avec précaution pour éviter d'alourdir les temps d'éxécution.
Ce modèle (à parfaire) centralise une liste des zones ayant un évênement de heart-beat à faire fonctionner et lance ces évênements lorsque certaines conditions sont requises.
Il n'y a que peu de raisons de laisser des évênements se produire dans une zone au rythme de 6-10 secondes en l'absence de joueurs :
lorsque une créature pénètre dans la zone, le deuxième script placé sur le OnEnter de la zone vient signaler au Heart-Beat global de prendre en charge sur le timer du module un script particulier à répeter.
lorsque les joueurs ont disparus de la zone, le script maître "passive" la zone et suspens les exécutions futures.
Effet de bord : si vous placer des créatures dans une zone, le heart-beat se déclenchera une fois pour cette zone au lancement du module, puis il sera passivé.

Performance constatée au bout de 12 heures environ avec le profiler nwnx2 :

Citation :
sow_mod_hb 454 msec 5889 calls * // script maître
sow_z0303_enter 1 msec 2 calls // script d'activation
q1foot_ent_rumcv 0 msec 2 calls // script hb (z0303)
sow_zb103_enter 37 msec 12 calls // scripts d'activation
sow_on_hb_zb103 2349 msec 804 calls // script hb lourd d'une zone moyennement fréquentée
sow_zdfog_enter 5 msec 1 calls // scripts d'activation
sow_desert_fog 0 msec 1 calls // scripts hb
Je vous laisse évaluer le temps dépensé si tout le monde était sur le HB de sa zone.
Veillez à enlever les écritures dans les fichiers de logs une fois que vous avez fini de valider.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
Répondre en citant
Posté le : 24/05/2005 13:52:20 Sujet du message : mise à jour

NWScript :
// * returns true if there is no player in the area
// * has to be ran from an object
// source bioware 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 partant d'une zone vide
    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
}
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.


fonction beaucoup plus rapide que CheckPJInArea() pour tester la présence de quelqu'un de connecté dans la zone et ne risquant pas l'erreur "TOO MANY INSTRUCTIONS"
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé 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 51.842ms