[Prob] spawn, suppression et respawn des PNJ en fonction des PJ dans la zone.

Répondre
Partager Rechercher
Salut a tous,

J'ai un problème ( ) avec un script qui permet de supprimer les PNJ d'une zone lorsqu'aucun PJ n'est dedans (très pratique pour les "grosse" villes pleine de PNJ lorsque le serveur est une machine peu puissante ^^)

-Voici le principe:
Un PJ entre seul dans la zone, il active une rencontre qui fait spawn les PNJ puis ils rejoignent leurs points de passage. Ensuite ce même PJ (toujours tout seul dans cette zone) quitte la zone, tout les PNJ sont supprimer. (ensuite s'il y retourne, tous les PNJ respawn et ainsi de suite)

Jusqu'ici aucun problème ça fonctionne correctement.

-Voici le problème:
Lorsque le joueur déconnecte dans la zone le script ne réagit pas, il fait comme si le PJ etait encore la donc les PNJ ne sont pas détruit même si un autre PJ arrive puis quitte la zone.

Voici les scripts utiliser*:

Sur le OnEnter de la zone:

Code:
 void main() 
{
object oPlayer=GetEnteringObject();
object oArea=OBJECT_SELF;
if(!GetIsPC(oPlayer)||GetIsDM(oPlayer)){return;}
//Area decouverte,enlever les commentaires:
//ExploreAreaForPlayer(oArea,oPlayer);
//si un premier joueur entre dans la zone, creer PNJ
//sinon,on ne fait rien.
int iNumberOfPLayer=GetLocalInt(OBJECT_SELF,"AREA_PC_COUNT");
//on incremente ça:
SetLocalInt(OBJECT_SELF,"AREA_PC_COUNT",iNumberOfPLayer+1);
//si c'est le premier joueur qui vient d'entre,on indique alors rencontre de se genere
if(iNumberOfPLayer==0)
{
SetLocalInt(OBJECT_SELF,"Zone001",TRUE);
}
else
{
DeleteLocalInt(OBJECT_SELF,"Zone001");
}
}

Sur le OnExit de la zone:

Code:
 void TrashObject(object oObject) 
{
/* search and destroy contents of body bag's, others just destroy */
if (GetObjectType(oObject) == OBJECT_TYPE_PLACEABLE) {
object oItem = GetFirstItemInInventory(oObject);
/* recursively trash all items inside container */
while (GetIsObjectValid(oItem))
{
TrashObject(oItem);
oItem = GetNextItemInInventory(oObject);
}
}
DestroyObject(oObject);
}
void main()
{
object oPlayer = GetExitingObject();
object oArea = OBJECT_SELF;
if(!GetIsPC(oPlayer)||GetIsDM(oPlayer)){ return; }
int iPCCount = GetLocalInt(oArea,"AREA_PC_COUNT") - 1;
SetLocalInt(oArea,"AREA_PC_COUNT",iPCCount);
/* bypass if currently in-progress (blocked) or ClearTrash is disabled */
if (GetLocalInt(OBJECT_SELF, "CT_IN_PROGRESS") != 1)
{
SetLocalInt(OBJECT_SELF, "CT_IN_PROGRESS", 1); /* set a flag to block */
int iItemDestructTime;
int iObjectType;
int iNow = (GetCalendarMonth()*10000) + (GetCalendarDay()*100) + GetTimeHour();
int iAreaDestructTime = iNow + 1; /* destroy items in 'n' game hours from now */
object oItem = GetFirstObjectInArea();
while (GetIsObjectValid(oItem))
{
// Destruction des PNJs generes automatiquement
if(GetIsEncounterCreature(oItem) && (iPCCount==0))
{
DestroyObject(oItem);
oItem = GetNextObjectInArea();
}
else
{
iObjectType = GetObjectType(oItem);
switch (iObjectType) {
case OBJECT_TYPE_PLACEABLE:
/* monster drop containers are tagged placeables */
if (GetTag(oItem) != "BodyBag") {
break; }
/* note: no break here, allow fall-through */
case OBJECT_TYPE_ITEM:
iItemDestructTime = GetLocalInt(oItem, "CT_DESTRUCT_TIME");
if (iItemDestructTime > 0)
{
if (iItemDestructTime <= iNow) {
TrashObject(oItem); /* destruct time has passed, trash the object */
}
/* note: no action if destruct time set but not passed */
} else {
/* no destruct time set, so do it now */
SetLocalInt(oItem, "CT_DESTRUCT_TIME", iAreaDestructTime);
}
}
 
oItem = GetNextObjectInArea();
}
}
SetLocalInt(OBJECT_SELF, "CT_IN_PROGRESS", 0); /* done, release */
}
}

Sur le OnEnter de la rencontre:

Code:
void main()
{
SetEncounterActive(FALSE,OBJECT_SELF);
if(GetLocalInt(GetArea(OBJECT_SELF),"Zone001"))
{
//if(GetIsNight()){SetEncounterSpawnsMax(d4(),OBJECT_SELF;}
SetEncounterActive(TRUE,OBJECT_SELF);
}
}

Donc voila, nous sommes des newbies en ce qui concerne les scripts, on a même quelques difficulté a utiliser Lilac Soul (lol) et je n'ai vraiment aucune idée de comment faire pour que le script prennent en compte la déconnexion.
J'ai lu sur un autre message que lorsque le joueur déconnecte, le module ne lui attribu aucune position donc si je met un script sur le OnClientLeave qui dit qu'une fois déconnecter, le joueur se retrouve ailleurs (une zone prévu a cet effet) est ce que ma ville va se vider des ses PNJ?
Ou alors sur le OnHeartBeat (de la zone) un script qui vérifie toutes les minutes (par exemple) le nombre de PJ dans la zone et si zero la suppression des PNJ?
je propose ça tout en sachant que je dis sûrement deux grosses bêtises .

Voila voila, je vous remercie d'avance pour vos réponses ^^

A bientôt.

*ce sont des morceaux de scripts trouver a droite et a gauche
euh... effectivement je crois me souvenirs que en cas de deco d'un PJ dans ta zone t'es emmerde... c'est clair.

Une solution serait effectivement de verifier sur un OHB le nombre de PJ lorsque ce nombre est passe > 0
Maintenant est-ce qu'il y a un interet a le faire?
va voir ICI .

Voila sinon en terme de script pas grands choses a dire dessus sauf que la fonction Trash est immonde :
Je t'en remet une qui normalement devrait faire la meme chose en consommant 10 fois moins...
Code PHP:

void TrashObject(object oObject
{
/* search and destroy contents of body bag's, others just destroy */
    
if (GetObjectType(oObject) == OBJECT_TYPE_PLACEABLE)
    {
        
object oItem GetFirstItemInInventory(oObject);
        
/* recursively trash all items inside container */
        
while (GetIsObjectValid(oItem))
        {
            
// Cela ne sert a rien! A part consommer un max de ressource 
            //TrashObject(oItem);
            
DestroyObject(oObject); //Ca devrait suffire
            
oItem GetNextItemInInventory(oObject);
        }
    }

    
DestroyObject(oObject);

La tu fais des appels recursifs en moins, et la recursivite est tres gourmande, et en plus des tests en moins sur le type d'objet.
Ok, je te remercie et je vais éplucher l"ici" tout de suite^^
---
Apres avoir lu l'autre sujet je pense que je ne vais pas me servir de ces script ci dessus, je vais essayer de faire le truc pour le OHB mais juste histoire de dire que ca sera fini
Voila, merci encore pour ton aide^^ (je post le dernier code pour le OnHeartBeat dés qu'il sera fait (si j'y arrive) pour ceux qui voudraient utiliser ce systeme)
On pourrait peut-être aussi mettre un p'tit script dans le OnExit du perso :

Code PHP:

  void main()
  {
  
object oArea GetArea(OBJECT_SELF);
  
  
ExecuteScript("nom du script du OnExit"oArea);
  
  } 
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés