Voir le sujet précédent ¤
Voir le sujet suivant
|
Auteur |
Message |
Sith Vicious
Grand Sage du Conseil
Inscrit le: 19 Oct 2005
Messages: 693
|
Posté le : 05/04/2006 18:09:19 Sujet du message : [système] Vidage de zone / eboueur
Je me suis décidé à faire mon propre système de vidange, apparement il marche, simplement je me rend pas bien compte s'il est mieux ou moins bien que les autres.
Il est basé sur des créatures "éboueurs" qui tournent dans les zones.
Le principe :
- a la sortie d'une zone (joueur) j'enregistre la zone sur la créature, dans une liste.
- sur le heartbeat de la créature :
*si il y a des joueurs dans la zone, ou si elle est seule mais qu'il n'y a rien a nettoyer elle va dans la suivante dans sa liste
*sinon, elle attend (10 heartbeat ~ 1 minute, modifiable) puis elle commence le nettoyage. Pour éviter le lag, elle en fait pas beaucoup à chaque HB (présentement elle vide 5 loot, ou détruit 5 items ou tue 5 créatures de rencontres)
*Une fois qu'il n'y a plus rien a nettoyer, elle saute dans la zone suivante dans sa liste.
J'ai prévu une liste de 30 zones max (modifiable) après quoi ça appelle une autre créature en renfort. Comme ça chaque bête a sa liste de zone et elles ne devraient pas etres débordées, ni se croiser.
Les scripts :
OnExit de chaque 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 :void main() { object oExit = GetExitingObject(); if (! GetIsPC( oExit)) return; if (! GetLocalInt( OBJECT_SELF, "NETTOYAGE_OK")) { object oMod = GetModule(); object oEboueur = GetLocalObject( oMod, "EBOUEUR"); object oTemp = GetFirstObjectInArea( OBJECT_SELF); location lLoc = GetLocation( oTemp); if (! GetIsObjectValid( oTemp)) { lLoc = Location( OBJECT_SELF, Vector( 10.0, 10.0, 0.0), 0.0); } if ( oEboueur == OBJECT_INVALID) { oEboueur = CreateObject( OBJECT_TYPE_CREATURE, "sv_crea_eboueur", lLoc, FALSE, "SV_EBOUEUR_1"); } SetLocalLocation( oEboueur, "TEMP_LOCATION", lLoc); SignalEvent( oEboueur, EventUserDefined( 16258)); SetLocalInt( OBJECT_SELF, "NETTOYAGE_OK", TRUE); } } 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.
(c'est possible de rajouter ça dans le OnEnter si vous avez pas de OnExit générique, juste changer la définition de oExit)
Ajouter une créature dans la palette (resref "sv_crea_eboueur" ou changer la ref dans les scripts)
Mettre comme scripts (et ceux la uniquement, vider les autres) :
OnUserDefined
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 :const int NB_MAX_ZONES_A_NETTOYER = 30; void main() { int nEvent = GetUserDefinedEventNumber(); if ( nEvent == 16258) { int nCount = GetLocalInt( OBJECT_SELF, "NB_LOCATIONS"); if (! nCount) SetLocalInt( OBJECT_SELF, "MA_ZONE_EN_COURS", 1); location lLoc = GetLocalLocation( OBJECT_SELF, "TEMP_LOCATION"); SetLocalLocation( OBJECT_SELF, "NETTOYAGE_"+ IntToString(++ nCount), lLoc); DeleteLocalLocation( OBJECT_SELF, "TEMP_LOCATION"); SetLocalInt( OBJECT_SELF, "NB_LOCATIONS", nCount); if ( nCount >= NB_MAX_ZONES_A_NETTOYER) { string sNumero = IntToString( StringToInt( GetStringRight( GetTag( OBJECT_SELF), 1 ) )+ 1); CreateObject( OBJECT_TYPE_CREATURE, "sv_crea_eboueur", lLoc, FALSE, "SV_EBOUEUR_"+ sNumero); } } } 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.
OnSpawn
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.
OnHeartBeat
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() { int nCount = GetLocalInt( OBJECT_SELF, "NB_LOCATIONS"); if (! nCount) return; int nCurrent = GetLocalInt( OBJECT_SELF, "MA_ZONE_EN_COURS"); if ( GetAILevel() != AI_LEVEL_VERY_LOW) { DeleteLocalInt( OBJECT_SELF, "MES_BATTEMENTS"); if ( nCount== 1) return; nCurrent = ( nCurrent == nCount) ? 1 : nCurrent+ 1; SetLocalInt( OBJECT_SELF, "MA_ZONE_EN_COURS", nCurrent); location lCible = GetLocalLocation( OBJECT_SELF, "NETTOYAGE_"+ IntToString( nCurrent)); JumpToLocation( lCible); return; } int nHB = GetLocalInt( OBJECT_SELF, "MES_BATTEMENTS"); if (! nHB) { if (! GetIsObjectValid( GetNearestObjectByTag( "BodyBag")) && ! GetIsObjectValid( GetNearestObject( OBJECT_TYPE_ITEM)) && ! GetIsObjectValid( GetNearestObject( OBJECT_TYPE_CREATURE)) ) { if ( nCount== 1) return; nCurrent = ( nCurrent == nCount) ? 1 : nCurrent+ 1; SetLocalInt( OBJECT_SELF, "MA_ZONE_EN_COURS", nCurrent); location lCible = GetLocalLocation( OBJECT_SELF, "NETTOYAGE_"+ IntToString( nCurrent)); JumpToLocation( lCible); return; } } SetLocalInt( OBJECT_SELF, "MES_BATTEMENTS",++ nHB); if ( nHB >= 10) { object oBodyBag = GetNearestObjectByTag( "BodyBag"); object oTemp; int i, j = 1; while ( GetIsObjectValid( oBodyBag) && j< 6) { oTemp = GetFirstItemInInventory( oBodyBag); while ( oTemp != OBJECT_INVALID) { DestroyObject( oTemp, 0.5* j); oTemp = GetNextItemInInventory( oBodyBag); } oBodyBag = GetNearestObjectByTag( "BodyBag", OBJECT_SELF,++ j); } if ( j > 5) return; object oItem = GetNearestObject( OBJECT_TYPE_ITEM); while ( GetIsObjectValid( oItem) && j< 6) { DestroyObject( oItem); oItem = GetNearestObject( OBJECT_TYPE_ITEM, OBJECT_SELF,++ i); j++; } if ( j > 5) return; oItem = GetNearestObject( OBJECT_TYPE_CREATURE); i = 1; while ( GetIsObjectValid( oItem) && j< 6) { if ( GetIsEncounterCreature( oItem)) DestroyObject( oItem); oItem = GetNearestObject( OBJECT_TYPE_CREATURE, OBJECT_SELF,++ i); j++; } if ( j== 1) { DeleteLocalInt( OBJECT_SELF, "MES_BATTEMENTS"); if ( nCount== 1) return; nCurrent = ( nCurrent == nCount) ? 1 : nCurrent+ 1; SetLocalInt( OBJECT_SELF, "MA_ZONE_EN_COURS", nCurrent); location lCible = GetLocalLocation( OBJECT_SELF, "NETTOYAGE_"+ IntToString( nCurrent)); JumpToLocation( lCible); 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.
Donc voila, je l'ai essayé il marche, mais j'ai pas de gros module avec plein des joueurs à disposition, donc si ça interesse quelqu'un d'essayer ce système (qui a l'avantage de pas être trop compliqué à mettre en place) j'aimerai savoir si il est valable en conitions réelles et s'il bouffe pas trop en ressources.
|
|
Revenir en haut |
|
|
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
Posté le : 06/04/2006 09:38:05 Sujet du message :
Mon commentaire : très intéressant
les améliorations à faire
- ton code sur le OnExit, mémorise plutôt l'emplacement de l'éboueur en objet local sur le module lui-même, tu économiseras une boucle sur tous les objets de la zone
- désactive le OnPerception de l'éboueur et met une faction neutre envers tout le monde, sinon en 6-10 secondes entre deux HB, il peut lui prendre l'envie d'aller attaquer des monstres.
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 06/04/2006 11:00:06 Sujet du message :
Je fais ça pour toi Sith, car tu m'a beaucoup aidé. C'est loin d'être le même système mais tu en fais ce que tu veux.
Dans les événements de la zone:
OnEnter:
NWScript :void main() { if( GetIsPC( GetEnteringObject()) == TRUE) { if( GetLocalInt( OBJECT_SELF, "PCs_In_Area") == 0) { SignalEvent( OBJECT_SELF, EventUserDefined( 3002)); SetLocalInt( OBJECT_SELF, "PCs_In_Area", 1); SetLocalString( OBJECT_SELF, "PC Tracker Ran", "False"); DelayCommand( 45.0f, SignalEvent( OBJECT_SELF, EventUserDefined( 3001))); DelayCommand( 45.0f, SignalEvent( OBJECT_SELF, EventUserDefined( 2998))); } else { int nOld = GetLocalInt( OBJECT_SELF, "PCs_In_Area"); int nNew = ( nOld + 1); SetLocalInt( OBJECT_SELF, "PCs_In_Area", nNew); } } } 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.
Dans le onExit:
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.
Et dans le OnUserdefined: (((PARTIE 1)))
NWScript :void main() { int nUser= GetUserDefinedEventNumber(); switch( nUser) { case 2998: { if( GetLocalInt( OBJECT_SELF, "PCs_In_Area")>= 1) { int nWeather = GetWeather( OBJECT_SELF); switch( nWeather) { case WEATHER_CLEAR: { SetSkyBox( SKYBOX_GRASS_CLEAR); break; } case WEATHER_RAIN: { SetSkyBox( SKYBOX_GRASS_STORM); break; } case WEATHER_SNOW: { SetSkyBox( SKYBOX_ICY); break; } } DelayCommand( 180.0f, SignalEvent( OBJECT_SELF, EventUserDefined( 2998))); } break; } case 2999: { SetLocalInt( OBJECT_SELF, "PCs_Found", 0); object oPC = GetFirstObjectInArea(); while( GetIsObjectValid( oPC)) { if( GetIsPC( oPC) == TRUE) { SetLocalInt( OBJECT_SELF, "PCs_Found", GetLocalInt( OBJECT_SELF, "PCs_Found")+ 1); } oPC = GetNextObjectInArea(); } if( GetLocalInt( OBJECT_SELF, "PCs_Found") != GetLocalInt( OBJECT_SELF, "PCs_In_Area")) { SetLocalInt( OBJECT_SELF, "PCs_In_Area", GetLocalInt( OBJECT_SELF, "PCs_Found")); } if( GetLocalInt( OBJECT_SELF, "PCs_Found") == 0) { SignalEvent( OBJECT_SELF, EventUserDefined( 3000)); SetLocalString( OBJECT_SELF, "PC Tracker Ran", "False"); } else { DelayCommand( 300.0f, SignalEvent( OBJECT_SELF, EventUserDefined( 2999))); } break; } case 3000: { object oArea = GetArea( OBJECT_SELF); object oChk = GetFirstObjectInArea( oArea); while( GetIsObjectValid( oChk) && ( GetLocalInt( OBJECT_SELF, "PCs_In_Area") == 0)) { int nChk = GetObjectType( oChk); switch( nChk) { case OBJECT_TYPE_CREATURE: { SetImmortal( oChk, FALSE); SetPlotFlag( oChk, FALSE); DelayCommand( 0.1f, DestroyObject( oChk)); break; }
/* warning: 5 unclosed block {} */ 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.
*******************************************************************************************
(((PARTIE2)))
NWScript :} /* suspect block end found !*/
oChk = GetNextObjectInArea( oArea); } /* suspect block end found !*/
object oObject = GetFirstObjectInArea( GetArea( OBJECT_SELF)); while( GetIsObjectValid( oObject) && ( GetLocalInt( OBJECT_SELF, "PCs_In_Area") == 0)) { if ( GetObjectType( oObject) == OBJECT_TYPE_ENCOUNTER) { SetEncounterActive( TRUE, oObject); } oObject= GetNextObjectInArea(); } break; } /* suspect block end found !*/
case 3001: { if( GetLocalString( OBJECT_SELF, "PC Tracker Ran") == "False") { SetLocalString( OBJECT_SELF, "PC Tracker Ran", "True"); SignalEvent( OBJECT_SELF, EventUserDefined( 2999)); } else { return; } break; } case 3002: { object oSP = GetFirstObjectInArea(); string nOSPTag = ""; while( GetIsObjectValid( oSP)) { if( GetTag( oSP) == nOSPTag) { oSP = GetNextObjectInArea(); } else { if(( GetObjectType( oSP) == OBJECT_TYPE_WAYPOINT) || ( GetObjectType( oSP) == OBJECT_TYPE_STORE)) { if( GetStringUpperCase( GetStringLeft( GetName( oSP), 5)) == "SPWN_") { string nresref = GetStringRight( GetName( oSP), GetStringLength( GetName( oSP))- 5); if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 3)) == "WP_") { string sSPTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 3); string sNPCTag = GetStringLeft( sSPTag, GetStringLength( sSPTag)- 3); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); } if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 5)) == "POST_") { string sNPCTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 5); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); } if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 4)) == "SIT_") { string sNPCTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 4); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); DelayCommand( 0.5f, AssignCommand( GetObjectByTag( sNPCTag), ActionSit( GetNearestObjectByTag( "Chair")))); } if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 4)) == "MER_") { string sNPCTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 4); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); if( GetStoreGold( oSP) <= 1000) { SetStoreGold( oSP, 100000); } } if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 6)) == "NIGHT_") { if(( GetTimeHour() >= 18) || ( GetTimeHour() <= 6)) { string sNPCTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 6); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); } } if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 4)) == "DAY_") { if(( GetTimeHour() <= 18) && ( GetTimeHour() >= 6)) { string sNPCTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 4); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); } } if( GetStringUpperCase( GetStringLeft( GetTag( oSP), 5)) == "NORM_") { string sNPCTag = GetStringRight( GetTag( oSP), GetStringLength( GetTag( oSP))- 5); CreateObject( OBJECT_TYPE_CREATURE, GetStringRight( GetStringLowerCase( GetName( oSP)), GetStringLength( GetName( oSP))- 5), GetLocation( oSP), FALSE, sNPCTag); } } } nOSPTag = GetTag( oSP); oSP = GetNextObjectInArea(); } } break; } break; } /* suspect block end found !*/
} /* suspect block end found !*/
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'imagination est plus importante que le savoir. (Albert Einstein)
Dernière édition par AZAZEL11 le 20/04/2006 16:46:44; édité 7 fois
|
|
Revenir en haut |
|
|
Sith Vicious
Grand Sage du Conseil
Inscrit le: 19 Oct 2005
Messages: 693
|
Posté le : 06/04/2006 11:42:21 Sujet du message :
>Lylver : J'ai pas compris ta remarque sur le OnExit. Je fais pas de boucle, je prends juste le premier objet pour tenter d'avoir une position accessible pour le nettoyeur, histoire que le moteur n'ait pas à recalculer une position valide quand il arrive dans la zone. Si il n'y a pas d'objet je le jette un peu au hasard, de toute façon c'est pas si grave, l'important c'est juste qu'il soit dans la zone. Enfin je t'ai peut-être mal compris.
-Pour le OnPerception : ben il en a pas, l'éboueur a juste les 3 scripts de mon post, les autres il en a pas besoin, et effectivement ça lui ferait faire que des bétises. Par contre effectivement, le mettre amical envers tout le monde c'est une bonne idée, ça évitera le cas de ces stupides attaques d'opportunités (que même un monstre sans scripts lance à tout bout de champ, ça m'énerve). Ou lui coller un effet "sanctuaire" en plus au spawn pourquoi pas.
>Azazel : ben justement, le principe c'était de changer la logique des systèmes comme celui là. Surtout d'éviter le comptage des PJ, et d'éviter de faire plein d'opérations inutiles sur les objets des zones. Avec un système comme celui que tu présente, déjà il y a le risque d'erreurs en comptage des joueurs (ie dans ton OnExit, tu attends 2 secondes avant de passer la variable des joueurs à 0, si un ou plusieurs joueurs entrent pendant ce temps, ils ne seront pas pris en compte). Et à chaque fois qu'une zone va se trouver vide, tu boucle sur tous ses objets, qui sont la plupart du temps pas visés par le nettoyage (des triggers, des WP, des meubles pour la deco etc.).
J'ai tenté d'innover en me servant du comptage automatique des PJ en fonction native Bioware via l'IA des monstres, et limiter au maximum les boucles inutiles. Considérant qu'il vallait mieux que le nettoyage aille lentement mais surement, plutot que d'avoir des opérations dans tous les sens. Et d'avoir du lag si par exemple un joueur a vider 300 objets inutiles au sol.
Je suis pas convaincu que mon système soit vraiment plus léger, ça demande à être vérifié et surement amélioré, mais je crois quand même qu'il peut apporter une nouvelle façon d'envisager ces systèmes de nettoyage.
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 06/04/2006 16:55:29 Sujet du message :
ok d'ak. Mais pour les objets je les ai mis actifs seulement ici car je les ai désactivés sur mon module (seules les créatures sont visées). Avec ce trio de script, tous les pnjs du module, tous sans exception sont en spawn (via WP). Alors pour les intéressés d'économie de ressources, voilà une solution. _________________ L'imagination est plus importante que le savoir. (Albert Einstein)
|
|
Revenir en haut |
|
|
zogzog59
Grand Chevalier
Inscrit le: 16 Jan 2005
Messages: 123
|
Posté le : 08/04/2006 12:49:36 Sujet du message :
zog zog ....
salut azazel11, j'ai une question a propos de ton set de script ?!
tu dis que ce set de script permet d'économiser des ressources déja c'est un bon point ca ^^ !
tu dis ensuite, que les pnj spawn via un WP ? Donc il faut assigner un wp à chaques pnj créés sur la zone utilisant se set de script ?? _________________ Les vaux module rp
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 18/04/2006 01:02:11 Sujet du message :
c'est exactement ça.
1-tu places les 3 scripts dans les événements de la zone
2-tu places un WayPoint sur la map
3-tu le nomme (sans fautes) avec (SPWN_)au début et avec le resref de la créature (blueprint) ex: SPWN_creature001
4-Donner le tag de ce meme waypoint commencant soit par (SIT_)pour que le pnj s'assoit sur la chaise la plus proche, (WP_) pour le faire marcher mais il faut PLUSIEURS WP attention aux tags ici!!!, (POST_) pour que le pnj aille un *poste de garde* , (NIGHT_)/(DAY_) pour que le pnj spawn le jour ou la nuit, (MER_) pour les marchands et (NORM_) pour *normal* , et a la fin tu fini le tag afin qu'il soit UNIQUE!!! ex: SIT_clown01
donc il faut nommer le WP et lui donner un tag pour que le script s'exécute
(le script cherche des waypoints nommés (et non le tag)commencant par SPWN_ , le tag sert a définir la fonction que fera le pnj, le nom du WP sert juste à le faire spawner.
Bref, si tu as des questions dis moi le! _________________ L'imagination est plus importante que le savoir. (Albert Einstein)
|
|
Revenir en haut |
|
|
P.Patoche
Chevalier
Inscrit le: 14 Avr 2006
Messages: 70
Localisation: France 77 |
Posté le : 20/04/2006 10:04:47 Sujet du message :
Bonjour a toutes et a tous, voila j'ai un petit souci le Scripts "Area Onuserdefined" de AZAZEL11 me marque une erreur est t'il possible de m'aider ? ligne 233
d'avance merci bien a vous.
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 20/04/2006 16:45:49 Sujet du message :
|
|
Revenir en haut |
|
|
P.Patoche
Chevalier
Inscrit le: 14 Avr 2006
Messages: 70
Localisation: France 77 |
Posté le : 20/04/2006 18:08:45 Sujet du message :
Je te remerci bien pour ta reponce si rapide je test et je te dit.
:(bon voila, plus d'erreur et apres essais les monstres et leur drop disparaise bien mais les drops dejat au sol reste et si tu pose une item au sol elle ne disparais pas non plus, suis bien triste *sniff* et comme je ne sais pas trop faire les scripts je suis obliger de m'en remettre a vous.
d'avance merci pour votre aide.
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 21/04/2006 00:31:58 Sujet du message :
c'est voulu, je l'ai moi meme désactiver. Il suffit juste d'enlever les // à chaque ligne concernant les OBJECTS a case 3000 (remettre actif la fonction des objets)
relis le script, tu verras ou il y a toute une section (en vert) , suffit d'effacer les //, c'était encore plus économique a mon sens de désactiver cette section car il y très peu d'objet trainant sur le sol...alos le script fait une boucle pour rien, mais si tu y tiens, tu sais maintenant quoi faire pour réactiver cette section.^^ Au pire si tu veux, j'ai un script de poubelle magique, (efface tout item à la fermeture d'un tonneau exemple)
vala _________________ L'imagination est plus importante que le savoir. (Albert Einstein)
|
|
Revenir en haut |
|
|
P.Patoche
Chevalier
Inscrit le: 14 Avr 2006
Messages: 70
Localisation: France 77 |
Posté le : 21/04/2006 09:47:55 Sujet du message :
Bon ok et un grand merci a toi pour ton aide et ton temp passer pour m'aider, sa marche tres bien, et je veus bien ton system de poubelle stp *deprime vue la qualité des scripts,et se dit qu'il est incapable d'en faire des comme ca*.
|
|
Revenir en haut |
|
|
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
Posté le : 21/04/2006 16:10:22 Sujet du message :
En réponse à la question de Sith plus : effectivement il n'y a pas de boucles, j'ai mal vu.
----
J'ai refait complétement l'éboueur du TNB2 (un peu moins de 400 zones)
il marche au poil maintenant.
Vous le trouverez là-bas (version éludée des scripts pour garder l'essentiel):
http://nwvault.ign.com/View.php?view=scripts.Detail&id=2998
Je n'utilise pas de créatures comme le fait Sith Vicious. Le principe est de déclencher une surveillance de la zone via les évênements OnEnterArea et OnExitArea.
J'ai rencontré un bug sur le OnExitArea lorsqu'il s'agit d'une déconnexion de PJs et c'est pour cela que je ne suis pas revenu sur ce post plus tôt.
Donc maintenant le coeur du système se trouve sur le heart-beat du module. J'ai longtemps hésité mais les tests de consommation CPU sont bons et j'ai économisé plusieurs fonctions que j'avais dispersées sur plusieurs scripts en une seule gestion des zones actives.
Le côté "optimal" de la chose c'est que cette liste des zones est maintenant à géométrie variable :
- elle ne comprend que ce qu'il y a besoin de gérer
- on peut débogger son évolution en mode console grâce à "## dm_dumpmodulelocals"
- elle se compacte automatiquement lorsqu'un zone est vide de joueurs (en même temps que le passage du nettoyeur !)
- j'ai trouvé un système assez futé pour éviter le risque de "too many instructions" : on envoie un signal personnalisé (SignalEvent comme dans le système custom au-dessus). Le nettoyeur n'a donc aucun risque de se bloquer et cela réparti la charge CPU .. tout simplement en faisant confiance au moteur temps réel de nwn : il se débrouille pour gérer les priorités des "SignalEvent" tout en conservant l'ordre dans lequel ils ont été envoyés (je n'étais pas sûr de ce fait mais les examens des logs me satisfont)
Le système combine le nettoyeur et la fonction de centralisation des heart-beats de zones.
De façon annexe vous trouverez aussi un système de Spawn Statique déja connu mais à ma sauce pour intégrer le nettoyage des créatures.
Je vous mets à la suite le coeur du système : le script de heart-beat voyez en téléchargement pour le reste. (J'ai anglicisé pour avoir un retour de nos américains favoris : large public)
NWScript :#include "ly_lib_area"void CompactHole( int m, int j); void PassivateArea( int m, int j); void DoAreaScript( int m, int j); int UnchainPassive( int m, int j); void main() { object oMod = GetModule(); object oArea ; int nBZone = GetLocalInt( oMod, "N_FHB_AREA"); string sMesg; int n; int i = 0; for( n= 1 ; n <= nBZone ; n++ ){ oArea = GetLocalObject( oMod, "FHB_AREA"+ IntToString( n)); if( GetLocalInt( oMod, "FHB_ACTIF"+ IntToString( n)) ){ if( NbPlayerorDMInArea( oArea) == 0 ){ PassivateArea( n, i); } else { DoAreaScript( n, i); } if( i != 0 ){ CompactHole( n, i); } } else { if( UnchainPassive( n, i) == 1 ){ i++; } else { if( i != 0 ){ CompactHole( n, i); } } } } if( i != 0 ){ SetLocalInt( oMod, "N_FHB_AREA", nBZone - i) ; sMesg = "Hooked Zone Count : "+ IntToString( nBZone - i); WriteTimestampedLogEntry( sMesg); } } void CompactHole( int m, int j) { object oMod = GetModule(); object oArea = GetLocalObject( oMod, "FHB_AREA"+ IntToString( m)) ; SetLocalObject( oMod, "FHB_AREA"+ IntToString( m- j), oArea); if( GetLocalInt( oMod, "FHB_ACTIF"+ IntToString( m)) ){ SetLocalInt( oMod, "FHB_ACTIF"+ IntToString( m- j), TRUE); } else { DeleteLocalInt( oMod, "FHB_ACTIF"+ IntToString( m- j)) ; } DeleteLocalInt( oMod, "FHB_ACTIF"+ IntToString( m)) ; SetLocalInt( oArea, "FHB_LIDX", m- j); DeleteLocalObject( oMod, "FHB_AREA"+ IntToString( m)) ; } void PassivateArea( int m, int j) { object oMod = GetModule(); object oArea = GetLocalObject( oMod, "FHB_AREA"+ IntToString( m)) ; DeleteLocalInt( oMod, "FHB_ACTIF"+ IntToString( m)) ; DeleteLocalInt( oArea, "FHB_ACTIF") ; string sMesg = "Hooked Zone : "+ GetTag( oArea)+ "-"+ GetName( oArea)+ " passivated"; WriteTimestampedLogEntry( sMesg); DeleteLocalInt( oArea, "PC_HERE") ; } void DoAreaScript( int m, int j) { object oMod = GetModule(); object oArea = GetLocalObject( oMod, "FHB_AREA"+ IntToString( m)) ; SetLocalInt( oMod, "FHB_ACTIF"+ IntToString( m), TRUE); SetLocalInt( oArea, "FHB_COUNT", 20); string sScript = GetLocalString( oArea, "FHB_SCRIPT"); if( sScript != "" ){ SetLocalObject( oMod, "AREA_FOR_SC"+ IntToString( m), oArea); SignalEvent( oMod, EventUserDefined( 1000+ m)); } } int UnchainPassive( int m, int j) { object oMod = GetModule(); object oArea = GetLocalObject( oMod, "FHB_AREA"+ IntToString( m)) ; int k= 0; int nHB = GetLocalInt( oArea, "FHB_COUNT") - 1; if( nHB > 0 ){ SetLocalInt( oArea, "FHB_COUNT", nHB); } else { DeleteLocalObject( oMod, "FHB_AREA"+ IntToString( m)); DeleteLocalInt( oArea, "FHB_LIDX"); k= 1 ; SetLocalObject( oMod, "AREA_FOR_SC"+ IntToString( m), oArea); SignalEvent( oMod, EventUserDefined( 2000+ m)); } return k; } 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 petit effet de bord qui m'a donné des sueurs froides : au démarrage du module toutes les zones ou des PNJs sont posés viennent "s'arrimer" (hook) dans la liste.
Je vous précise que j'en profite pour repasser toutes ces zones en spawn statique
Enfin bref, sueurs froides donc : 97 zones hookées au démarrage...
mais quasiment rien en temps CPU pour la gestion et retour à 0 zones hookées au bout de 2 minutes : mission accomplie !
Je pense que le système peut gérer des modules à plus de 100 joueurs présents ( : en les mettant 1 par zone)
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 21/04/2006 18:14:08 Sujet du message :
POUBELLEvoila le script a mettre dans le OnUsed d'un contenant (barrique, caisse, etc...)
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. _________________ L'imagination est plus importante que le savoir. (Albert Einstein)
|
|
Revenir en haut |
|
|
Sith Vicious
Grand Sage du Conseil
Inscrit le: 19 Oct 2005
Messages: 693
|
Posté le : 21/04/2006 18:44:40 Sujet du message :
Le SetIsDestroyable sert à rien, c'est uniquement pour les créatures pour que leur corps disparaisse pas.
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 21/04/2006 19:30:03 Sujet du message :
|
|
Revenir en haut |
|
|
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
|
Posté le : 25/04/2006 11:49:10 Sujet du message :
Une qui fait joli (animation)
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.
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.
|
|
Revenir en haut |
|
|
AZAZEL11
Seigneur
Inscrit le: 08 Fév 2006
Messages: 156
|
Posté le : 16/12/2006 05:37:38 Sujet du message :
RÉSOLU' PROBLÈME VENANT D'AILLEURS
le bien, le mal...l'un ne va pas sans l'autre..j'avais un système impect mais voila depuis un temps il me lâche quelques fois..
j'ai un ennui qui me dépasse a vrai dire.
explications:
VOIR MON POST PLUS HAUT POUR LES SCRIPTS(MA PREMIÈRE RÉPONSE^^)
problème: ==> intermitent
sur le module depuis un certain temps (il a grossit depuis) mes pnjs *despawn* une seconde après que lorsque nous sommes en MD et qu'on *dépossède* un pnj ou quand on les *possèdent* . À savoir si nwn ne *perdrait* pas le fil pendant cette seconde(possède/dépossède) et qui considèrerait la zone comme vide même si ce n'est pas le cas...
Ou bien si c'est parce que nous avons 2 scripts différents (un pour les zones intérieures/extérieures) mais avec les même chiffre pour les signalevents. Ça je ne sais pas si ça cause problème.
enfin avant d'entrer dans les détails plus approfondis, il n'y aurait pas une âme charitable qui pourrait me donner son avis sur la question à savoir le POURQUOI mes pnjs *despawn* de facon non-désirée? _________________ L'imagination est plus importante que le savoir. (Albert Einstein)
|
|
Revenir en haut |
|
|
|