lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
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 :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 :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 :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 :#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") ; if ( oArea != OBJECT_INVALID) { sArea = GetTag( oArea) ; 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"); } if( bEmptyArea ){ nBodyBag = CleanBodyBag( oArea) ; nPNJ = CleanPNJ( oArea) ; nItemLost = CleanItem( oArea) ; } else { DeleteLocalInt( oMod, "CLEANQ" + sArea) ; DeleteLocalObject( oMod, "CLEANQ") ; DelayCommand( 6.0, SignalEvent( OBJECT_SELF, EventUserDefined( 300))) ; return ; } if( ( nBodyBag >= 0) && ( nPNJ >= 0) && ( nItemLost >= 0) ){ DeleteLocalInt( oMod, "CLEANQ" + sArea) ; DeleteLocalObject( oMod, "CLEANQ") ; DelayCommand( 6.0, SignalEvent( OBJECT_SELF, EventUserDefined( 300))) ; return ; } else { SetLocalInt( oMod, "CLEANQ" + sArea, 29 + GetLocalInt( oMod, "CLEANQ" + sArea)) ; } } else { oArea = GetLocalObject( oMod, "CLEANR") ; if ( oArea != OBJECT_INVALID) { sArea = GetTag( oArea) ; SetLocalObject( oMod, "CLEANQ", oArea) ; SetLocalInt( oMod, "CLEANQ" + sArea, CleanP) ; DeleteLocalInt( oMod, "CLEANR" + sArea) ; DeleteLocalObject( oMod, "CLEANR") ; } else { sArea = "" ; if( CleanP > 0 ){ SetLocalInt( oMod, "CLEANQ", CleanP) ; DeleteLocalInt( oMod, "CLEANP") ; } } } float fDelay = 180.0 - 6.0 * IntToFloat(( 1+ GetLocalInt( oMod, "CLEANQ"+ sArea))) ; if ( fDelay < 6.1) fDelay = 6.1 ; 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 :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 :#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 ){ if( GetLocalObject( oMod, "CLEANQ") == OBJECT_SELF ){ DeleteLocalInt( oMod, "CLEANR" + sArea) ; if( GetLocalObject( oMod, "CLEANR") == OBJECT_SELF ){ DeleteLocalObject( oMod, "CLEANR") ; } WriteTimestampedLogEntry( "Warning : GC OnExitLoop : "+ sArea+ " GC here : cancelling outnumbered request") ; } else { DeleteLocalInt( oMod, "CLEANQ" + sArea) ; WriteTimestampedLogEntry( "Warning : GC OnExitLoop : "+ sArea+ " found area counter without object, resetting.") ; } return ; } if( CleanR < 0 ){ DeleteLocalInt( oMod, "CLEANR" + sArea) ; if( GetLocalObject( oMod, "CLEANR") == OBJECT_SELF ){ DeleteLocalObject( oMod, "CLEANR") ; } CleanR = 0 ; } if( CleanR == 0 ){ if( NoPlayerInArea( OBJECT_SELF) ){ if( GetLocalInt( OBJECT_SELF, "PC_HERE") == 1) DeleteLocalInt( OBJECT_SELF, "PC_HERE") ; } else { WriteTimestampedLogEntry( "Warning : GC OnExitLoop : PJ here, no hooking") ; return ; } } if( CleanR > 0 ){ if( NoPlayerInArea( OBJECT_SELF) ){ if( GetLocalInt( OBJECT_SELF, "PC_HERE") == 1) DeleteLocalInt( OBJECT_SELF, "PC_HERE") ; } else { DeleteLocalInt( oMod, "CLEANR" + sArea) ; if( GetLocalObject( oMod, "CLEANR") == OBJECT_SELF ){ DeleteLocalObject( oMod, "CLEANR") ; } WriteTimestampedLogEntry( "Warning : GC OnExitLoop Stop Other Hooking") ; return ; } } if( CleanR > 300 ) WriteTimestampedLogEntry( "Warning : GC OnExitLoop Slow Hooking") ; if( ( GetLocalObject( oMod, "CLEANR") == OBJECT_INVALID) && ( CleanR >= CleanP) ){ SetLocalObject( oMod, "CLEANR", OBJECT_SELF) ; WriteTimestampedLogEntry( "Warning : GC OnExitLoop "+ sArea+ " Hooking") ; return ; } if( GetLocalObject( oMod, "CLEANR") == OBJECT_SELF ){ WriteTimestampedLogEntry( "Warning : GC OnExitLoop "+ sArea+ " already hooked") ; return ; } SetLocalInt( oMod, "CLEANR" + sArea,++ CleanR) ; if( CleanR > CleanP ) SetLocalInt( oMod, "CLEANP", CleanR) ; WriteTimestampedLogEntry( "Warning : GC OnExitLoop "+ sArea+ " nb "+ IntToString( CleanR)+ " Hooking failed : recheck in 6 secondes") ; DelayCommand( 6.0, ExecuteScript( "ly_onexit_loop", OBJECT_SELF)) ; } 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 :#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 { 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 ){ DeleteLocalObject( oMod, "CLEANQ") ; DeleteLocalInt( oMod, "CLEANQ" + sArea) ; } if( GetLocalObject( oMod, "CLEANR") == OBJECT_SELF ){ DeleteLocalObject( oMod, "CLEANR") ; SetLocalInt( oMod, "CLEANR" + sArea,- 1) ; } 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
|