JeuxOnLineForumsPlusCréer un compte
Forum jeux-vidéo>Neverwinter Nights
Maskado
Les forums JOL > Forum jeux-vidéo > Neverwinter Nights > NWN - Maskado > [Script] Emulation de l'évènement OnHeartBeat avec moins de charge CPU RSS
   
Fil fermé
Partager Outils Rechercher
Avatar de ¤ TynriL ¤
¤ TynriL ¤
Bagnard
 
Avatar de ¤ TynriL ¤
 

[Script] Emulation de l'évènement OnHeartBeat avec moins de charge CPU

Script initialement proposé par Azrael07 !
Citation:
Comme promis dans un coin paumé du forum je vais donné un script pour "emuler" un OnHeartBeat, qui sera activé uniquement si un joueur est dans l'area.
C je pense bcp moins lourd que le OnHeartBeat.

Bon finis les blabla voici le fameux code :

Dans le OnModuleLoad rajoutez la ligne suivante
Code PHP:
SetLocalInt(GetObjectByTag("TAGAREA"),"iPlayerInAreaTAGAREA",0);
//Ca correspond a une variable qui donne le nombre de joueur actuelement dans l'area conserné. 
Puis dans le OnPlayerEnter de l'area
Code PHP:
//OnHeartBeat emulator
//Created by Azrael
//File for OnEnter of area

int iPlayerInArea;//Nombre de joueurs dans l'area
void main()
{
iPlayerInArea GetLocalInt(OBJECT_SELF"iPlayerInAreaTAGAREA");//On recupere l'integer qui sauvegarde le nombre de joueurs dans l'area
iPlayerInArea++;//On incremente la valeur
SetLocalInt(OBJECT_SELF,"iPlayerInAreaTAGAREA"iPlayerInArea);//Et on l'archive de nouveau
if (iPlayerInArea == 1)//Si c'est le premier joueur qui arrive
{
ExecuteScript("NOMDUSCRIPT",OBJECT_SELF);//On active le script qui definira l'action
}


Dans le OnExit meme chose :
Code PHP:
//OnHeartBeat emulator
//Created by Azrael
//File for OnExit of area

int iPlayerInArea;//Nombre de joueurs dans l'area
void main()
{
iPlayerInArea GetLocalInt(OBJECT_SELF"iPlayerInAreaTAGAREA");//On recupere l'integer qui sauvegarde le nombre de joueurs dans l'area
iPlayerInArea--;//On reduit la valeur
SetLocalInt(OBJECT_SELF,"iPlayerInAreaTAGAREA"iPlayerInArea);//Et on l'archive de nouveau

Maintenant voici le gros paquet, c'est un script independant appelé par ExecuteScript("NOMDUSCRIPT",OBJECT_SELF), mais vous devriez donner un autre nom pasque NOMDUSCRIPT c pas terrible -lol-
Code PHP:
//OnHeartBeat emulator
//Created by Azrael
//New script called by OnEnter of area

//Le nombre de joueurs dans l'area, indispensable pour pouvoir tout arreter si y'en a plus
int iPlayerInArea GetLocalInt(OBJECT_SELF,"iPlayerInAreaTAGAREA");
int iSecond;//Pour retenir la seconde (voir + loin)
int iNextAction GetTimeSecond();//La prochaine action realisee

void main()
{
while(
iPlayerInArea 0)//S'il n'y a plus de joueurs la boucle se termine
{
//On retient la seconde actuelle pour :
// 1.Ne pas surcharger en appelant tjrs le temp par la fct
// 2.Etre sur qu'on ne change pas de secondes entre deux lignes de codes (tres peu probable mais possible)
iSecond GetTimeSecond();
//Si il y a eut 6 secondes depuis la derniere action...
if (iNextAction >= iSecond)
{
//...On reinitialise la variable du temp pour la prochaines action

//En revenant a zero si le temp a depasse 54(prochaine action dans 6s : 54+6 = 60, c a dire hors de l'echelle des secondes

if (iSecond >= 54)
{
iNextAction iSecond 54;
}
else
{
iNextAction GetTimeSecond() + 6;
}

//Ici on a reproduit un OnHeartBeat qui ne se produit que si des joueurs sont dans l'area.
//Vous pouvez donc mettre ici votre code comme normal
//Si vous faites un ExecuteScript vous pouvez meme cibler un autre objet
}
//On update le nombre de joueurs present dans l'area
iPlayerInArea GetLocalInt(OBJECT_SELF,"iPlayerInAreaTAGAREA");
}

Alors l'interet d'appeler un nouveau script au niveau du OnEnter, c d'une part pasque je trouve que c plus propre, bon c vrai qu'on s'en fous que ca soit sale du temp que ca marche...
D'autre part je ne suis pas sur que l'on puisse appeler deux fois le meme script en meme temp.

A oui je viens de penser a un bug : si jamais un joueur meurt dans l'arene?
Il faudrait rajouter dans le OnPlayerDeath du module un code du style "Si le player est dans l'arène, alors virer un player dans iPlayerInAreaTAGAREA.

Bon maintenant la question qui tue : a quoi ca sert puisqu'on a deja le OnHeartBeat
En fait, le serveur n'aura a calculer l'action que si un joueur est dans l'area, contrairement au OnHeartBeat.

Le problème c que g pas pu le tester car jusqu'a la fin des vacances je suis sur un pII 350, alors si Aurora peut passer, neverwinter c meme pas la peine
Je vais ouvrir un post sur le forum pour commenter le script, comme Uther a demander, y'en a qui on dut oublier, de pas commenter les scripts dirrectement sur cette page...

N'hesitez pas à me donner toutes propositions/améliorations, coup de geule, enfin je sais pas moi.

Et puis si y'a qlq qui veux bien le tester pour etre bien sur que ca marche...
Lien direct vers le message - Vieux
Avatar de eMRaistlin
eMRaistlin
Alpha & Oméga
 
Avatar de eMRaistlin
 
Apres des tests preliminaire, il semble que si un joueur meurt et quitte l'area, ca declenche le OnExit. (pour info)
Lien direct vers le message - Vieux
Avatar de ¤ TynriL ¤
¤ TynriL ¤
Bagnard
 
Avatar de ¤ TynriL ¤
 
Pas certain pour les déco/reco par contre... Enfin, c'est bricolable en faisant un SignalEvent sur le ClientEnter/ClientExit, mais c'est chiant.
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
Bon j'en ai marre de voir ce script en tête des liste de script alors qu'il ne marche pas, alors je le corrige, maintenant que j'ai la sagesse et l'experience de mon coté (ralala les erreures de jeunesse ^_^)

Code PHP:
//OnHeartBeat emulator
//Created by Azrael
//File for OnEnter of area

void OnHeartBeat();

void main()
{
    
int nPlayerInArea GetLocalInt(OBJECT_SELF"nbrPC");//On recupere l'integer qui sauvegarde le nombre de joueurs dans l'area
    
nPlayerInArea++;//On incremente la valeur
    
if (nPlayerInArea == 1DelayCommand(6.0fOnHeartBeat());//On active le script qui definira l'action

    
SetLocalInt(OBJECT_SELF,"nbrPC"nPlayerInArea);//Et on l'archive de nouveau
}

void OnHeartBeat()
{
    if(!
GetLocalInt(OBJECT_SELF"nbrPC")) return;

    
//code....

    
DelayCommand(6.0fOnHeartBeat());//On active le script qui definira l'action

OnExit :

Code PHP:
//OnHeartBeat emulator
//Created by Azrael
//File for OnExit of area

void main()
{
    
int nPlayerInArea GetLocalInt(OBJECT_SELF"nbrPC");//On recupere l'integer qui sauvegarde le nombre de joueurs dans l'area

    
nPlayerInArea--;//On reduit la valeur
    
SetLocalInt(OBJECT_SELF,"nbrPC"nPlayerInArea);//Et on l'archive de nouveau

Voila, ca devrait mieux marcher....

qu'est ce que je scriptais mal a l'époque ^^

EDIT : vi par contre y'a le problème des decos/recos que j'ai pas corrigé... tampis
Lien direct vers le message - Vieux
Avatar de Jedaï
Jedaï
Alpha & Oméga
 
Avatar de Jedaï
 
Les décos/recos y devrait pas y avoir de problème.

Par contre, vu comme c'est écrit je ne suis pas sûr de l'opportunité d'utiliser ce script : Il faut absolument que tu entoure ton code dans un bloc, sinon ça va être l'enfer : DelayCommand() copie toutes les variables "vivantes" dans le script au moment de son appel....
C'est une fonction qui n'est absolument pas optimisé de ce point de vue...

Donc faut l'utiliser prudemment, je te conseille plutôt :
Code PHP:
void OnHeartBeat()

{

    if( 
GetLocalInt(OBJECT_SELF"nbrPC") ) 
    {
        
//code
    
}
    else return;

    
DelayCommand(6.0fOnHeartBeat());//On active le script qui definira l'action


Ca évitera que tu perdes du temps CPU plutôt que d'en gagner....
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
euh.... je n'ai pas très bien compris la...

si DelayCommand copie de toutes facon toutes les variables, en quoi cela nous avancerais de le mettre entre crochets ?

Je ne comprend pas bien en quoi au final cela diffère...
Lien direct vers le message - Vieux
Sire Pom-pom
Roi
 
La portée des variables déclarées dans un bloque est limitée au bloque. Le DelayCommand étant hors des crochets il n'est pas dans la portée de ces variables et donc elles ne seront pas copiées. Enfin j'espère:
normalement, pour
Code PHP:

      
int  i;
}
i=0
Le compilateur doit dire erreur dans la déclaration de variable ("variable declared without type").
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
Ben j'ignorais completement ca

Alors la o_o on en apprend vraiment tout les jours...

Bien merci pour cet éclairssissement, c'est vraiment bon à savoir
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Pas satisfaisant
Je ne trouve pas cela satisfaisant du tout moi. Certes cette pseudo-parade permet de palier à une utilisation des hearbeats qui exécutent du code toutes les 6s mais coté jouabilité ...

Dans le cas ou le respawn des monstres se fait via des hearbeats ...

Cela revient à dire que le pj se fait tout les monstres de la zone et doit se faire des aller et retour de cette zone vers une autre pour pouvoir espérer revoir un jour ses monstres chéris?
Non ce n'est guère apréciable qu'en dîtes vous? Et le fait des faire respawn les monstres via un delaycommand est encore des plus néfaste pour un server presistant car nwn ou ses objets ont une capacité maximale de stockage pour les delaycommand.
Moi je me vois mal avec mes 300 zones et mes pjs se frittants masse monstres mettre des delay ...

A noté qu'au début je le faisais et ... bof bof. Donc ne pas utiliser les hearbeat ... d'accord je veux bien mais dans ce cas faire en sorte que cela ne repose pas sur un pj ... Pourquoi pas n'allouer une sorte de pnjs invisible et invincible qui s'occupe de faire çà? Genre ce pnj pourrait passerait d'une zone à une autre en marchant et c'est lui qui déclencherai les heartbeat.
Lien direct vers le message - Vieux
Avatar de eMRaistlin
eMRaistlin
Alpha & Oméga
 
Avatar de eMRaistlin
 
Euh...


A priori, c'est pour emuler des OnHeartBeat generic, pas forcement des respawn...


Personnelement, les respawns, je les gere sur le OnDeath des creatures... et je pense pas etre le seul
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
Euh.... je crois rêver ????

Est ce que j'ai seulement insinué qu'il faut remplacer TOUT les onheartbeat du module par ce shéma ?

J'espère bien que celui qui va programmer un respawn de monde persistant ne va pas s'en aller utiliser un truc substitutif et absolument pas adapté pour ce genre de situation.

Entre le respawn des créatures et des evenements régulier appliqués a des zones en particulier, il y a une grande différence...

Ce système est très pratique (bien que je ne l'utiliserais moi même pas sous cette forme la) pour faire des animation dans une zone, qui sont totalement inutiles si aucun joueur n'est dans la zone, comme par exemple des dialoges entre des pnj par des "SpeakString"

De plus, ce n'est pas la seule méthode, mais celle ci a l'avantage d'être utilisable par un simple copier/coller. Après, puisque tu semble si sur de tes compétences, libre à toi d'utliser n'importe quel système.


Pour finir, je dirais qu'il ne me viendrais plus à l'idée en se moment de proposer de tels scripts, mais étant donné que celui ci éétait en première place dans les scripts proposés dans le post persistant, je me suis dis qu'il serait au moins bon que je propose quelque chose qui marche.
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Je n'ai jamais dis le contraire bien entendu voyons. Mais tu avoueras tout de même que ce n'etait pas explicite tout de même.

Et oui ce système peut être pratique mais certainement pas dans l'utilisation de tous les heartbeat comme il a été mentionné au debut de cette rubrique, c'est contre çà que je dis "pas terrible".

Et puis tu dis :

Citation:
puisque tu semble si sur de tes compétences, libre à toi d'utliser n'importe quel système.
- Bon certes je possède des compétences en la manière de par mes études qui d'ailleurs sont loin d'être finies. Mais je me base bien plus sur les constats effectués aux fils des mois d'existance de mon serveur. Le simple fait de passer d'un système de respawn dit classique avec des delaycommand à un système de respawn statique permet déjà de gagner pas mal de mémoire.
Car même si l'on voit le mnémonic "delaycommand", pour ceux qui ont pu voir les quelques morceux des sources de nwn ... delaycommand n'est ni plus ni moin qu'un hearbeat géré directement par le module lui-même, tout comme les encounters.
- Mais mais mais, tout dépend aussi de la taille du monde, des zones, et surtout a n'en point douter du nombre de pnj/monstre dans la zone. Car dans certain cas le delaycommand est bien plus pratique, genre moins de 150 zones de respawn.

Je dis çà car coté lag j'ai tout tenté pour alléger au maximun les codes qui s'excécutent. Maintenant si vous voulez tester de part vous-même passer d'un respawn de type delaycommand à un respawn via heartbeat je suis convainqu que vous y verrai un changement notable, si toute fois votre module fait beaucoup de calcul. Parce que le miens en fait en permance du à de nombreux scripts bah c'est comme çà on m'appèle pas le scripteur fou pour rien mdr.

Ceci dis je ne critique pas hein? Je donne juste un conseil afin d'aider les autres car moi on ne m'a pas aider de ce coté là j'ai du apprendre sur le tas. A vous de prendre en considération ma remarque ou pas, après c'est selon le bon vouloir de chacun.
Lien direct vers le message - Vieux
Avatar de Iridian
Iridian
Roi
 
Avatar de Iridian
 
Citation:
Provient du message de Hidwulf
Le simple fait de passer d'un système de respawn dit classique avec des delaycommand à un système de respawn statique permet déjà de gagner pas mal de mémoire.
*intéressé* et qu'appel tu un "système de respawn statique" ?
J'utilise personnellement des DelayCommand et ca fonctionne très bien, mais s'il est possible d'obtenir les mêmes résultats avec moins de calculs, c'est toujours intéressant ...
Lien direct vers le message - Vieux
Avatar de Hidwulf
Hidwulf
Roi
 
Avatar de Hidwulf
 
Bah lol, déjà le delaycommand n'étant pas une action tu fait faire le spawn du monstre par qui par quoi?
Lien direct vers le message - Vieux
Avatar de 'Az
'Az [P.H.]
Alpha & Oméga
 
Avatar de 'Az
 
Citation:
Car même si l'on voit le mnémonic "delaycommand", pour ceux qui ont pu voir les quelques morceux des sources de nwn ...
Et bien je ne fais pas parti de ces rares élus, mais de toutes facon je me doute bien qu'un DelayCommand fonctionne au départ comme un OnHeartBeat, c'est de toutes facon des fonction appellées en fonction du temp, et je n'ai jamais dit qu'un "DelayCommand(6.0f" soit plus rapide qu'un OnHeartBeat.

Simplement, ce script n'est effectué qu'a la condition que des joueurs se trouvent dans la zone, d'où l'interet, DANS CERTAINS CAS, par rapport à un OnHeartBeat qui est appelé toutes les 6s qu'il y ai des joueurs présents dans la zone ou non.
Lien direct vers le message - Vieux
Fil fermé
Les forums JOL > Forum jeux-vidéo > Neverwinter Nights > NWN - Maskado > [Script] Emulation de l'évènement OnHeartBeat avec moins de charge CPU
   

Outils Rechercher
Rechercher:

Recherche avancée

Les vidéos de Neverwinter Nights RSS
  • Aucune vidéo pour le moment...
Thème visuel : Fuseau horaire GMT +1. Il est actuellement 17h10.
   

© JeuxOnLine, le site des MMO, MMORPG et MOBA. Tous droits réservés. - Conditions générales d'utilisation - Conditions d'utilisation des forums - Traitement des données personnelles - ! Signaler un contenu illicite