Un garde qui detecte les pickpocket (PJ/PNJ)

Répondre
Partager Rechercher
Voici le premier jet d'un script permettant a un garde de détecter les pickpocket.
Pour l'exemple, il s'agit d'un chien de garde.

Le script fonctionne très bien mais j'aimerai avoir vos avis pour quelques points (voir les commentaires)

Code PHP:

void main()
{
    
object oItem GetModuleItemAcquired();

    
float fDistanceMax 10.0//distance maximale de perception d'un vol
    
if (GetStolenFlag(oItem))
    {
        
object oVoleur GetItemPossessor(oItem);
        
object oGarde GetNearestObjectByTag("chiendegarde",oVoleur);
        if (
GetIsObjectValid(oGarde))
        {
            
float fDistance GetDistanceBetween(oGarde,oVoleur);
            
AssignCommand(oGarde,SpeakString("distance ="+FloatToString(fDistance),TALKVOLUME_TALK));
            if ((
fDistance<fDistanceMax) && (fDistance>0.0))
            {
                
//il y a un garde a distance de perception, voyons s'il a remarque quelque chose
                //je ne sais pas si search est le meilleur choix pour le garde, mais c'est tous ce que j'ai trouve d'interressant
                
if(GetSkillRank(SKILL_SEARCH,oGarde)+d20()>GetSkillRank(SKILL_PICK_POCKET,oVoleur)+d20())
                {
                    
//le garde a repere le vol
                    
if (GetIsPC(oVoleur)){SendMessageToPC(oVoleur,"Le garde vous a vu voller");}
                    
SetIsTemporaryEnemy(oVoleur,oGarde);
                    
AssignCommand(oGarde,ActionAttack(oVoleur));
                }
            }
        }

        
//Ici un CopyObject serai mieu, si il ne conserve pas le flag "stolen"
        //Dans le doute je garde le CreateItemOnObject
        
CreateItemOnObject(GetTag(oItem),GetItemPossessor(oItem));
        
DestroyObject(oItem);
    }

Donc les points qui m'intéressent :
CopyObject ou CreateItemOnObject ? (pour retirer le Flag "Stolen")
Y a t-il plus logique que la compétence shearch pour détecter un vol ?
Existe il une fonction permettant d'opposer 2 caracts (ca m'étonnerai car j'ai bien cherché, mais j'ai pu passer a coté) ?
Autre chose ?

Merci d'avance
Bien si tu veux opposer dextérité à sagesse, c'est facile, mais c'est pas une fonction, tu peux créer un script qui fait ça, qui se déclenche quand tu fais ExecuteScript.
Si tu veux opposer dextérité à Détection (plus logique que fouille), c'est plus compliqué, tu devras choisir les rapports qui l'emportent, etc.
Si tu veux opposer deux capacités, c'est facile, je me demande même si il y a pas une fonction, mais j'en sais rien parce que je ne l'utilise jamais

Je ne comprends pas la question pour le FlagStolen, sorry

Vlà. C'est pas génial mais c'est tout ce que j'ai.
J'aurai voulu opposer détection et pick-pocket, mais je n'ai pas trouvé détection .... (sans doute une grosse lacune en anglais)

Pour le FlagStolen, en c'est simple, prenons un exemple :

PJVoleur est un voleur, PNJGarde est un garde, PJAmi est un ami du voleur, PJPassant est un autre PJ.

PJVoleur vole un anneau a PJPassant :
L'anneau est marqué comme volé, et donc si PNJGarde est dans le coin et réussi son jet de dès, il s'attaquera a PJVoleur.

Imaginons que PNJGarde soit loin au moment du vol.

Quelques jours plus tard, PJVoleur rencontre PJAmi et lui donne l'anneau :
L'evenement "onAcquireItem" se déclenche, et manque de bol PNJGarde est dans le coin. Si celui ci réussi son jet de dès, il détecte le vol (ba oui l'objet est toujours flaggé comme volé !) et s'attaque a PJAmi.

Donc il me faut me débarrasser du flag "Stolen".
Helas, s'il existe une fonction GetStolenFlag(), il n'y a pas de SetStolenFlag() !

La question est donc :
-qui a t-il de mieux pour enlever ce flag, un CopyObject ou un CreateItemOnObject ?
Le flag stolen risque de poser des problèmes pour ceux qui utilisent l'ATS de Mojo car pour éviter les ventes aux marchands, les objets sont noté comme volé.
Le pauvre artisant risque de ce voir traiter de voleur (même si c'est pas toujours faux) et poursuivi par un garde .
Je sais pas si la constante INVENTORY_DISTURB_TYPE_STOLEN peut être utile dans ton cas?

Jaha Effect
Citation :
Provient du message de Jaha Effect
Le flag stolen risque de poser des problèmes pour ceux qui utilisent l'ATS de Mojo car pour éviter les ventes aux marchands, les objets sont noté comme volé.
Le pauvre artisant risque de ce voir traiter de voleur (même si c'est pas toujours faux) et poursuivi par un garde .
Je sais pas si la constante INVENTORY_DISTURB_TYPE_STOLEN peut être utile dans ton cas?

Jaha Effect
Je ne pense pas, elle serait utile si je pouvais accéder au script InventoryDisturb des joueurs, mais las, ce n'est pas le cas.

Sinon je n'avais pas pensé à l'ATS, mais si je ne me trompe les objets sont crée directement dans l'inventaire. Donc le gain d'un objet ne déclenche par le 'onUnaquireItem'. Je vais donc voir s'il est possible de déclencher le script sur cet évènement plutôt que sur le 'onAcquireItem'.
Tu récupères sur une int... C'est tout ! Maintenant si l'objet est volé au voleur ça ne sert à rien, car le garde ne dira rien... Or tu veux que l'objet puisse être volé à un voleur, n'est-ce pas ?

Solution 2:
Détection si oItem est volé, pas si il est donné, c'est à dire si LastAction(oAcquirer==Steal) (si ça existe pas, dis moi le). Je vais faire des recherches....
Citation :
Provient du message de Ange Musicien
Tu récupères sur une int... C'est tout ! Maintenant si l'objet est volé au voleur ça ne sert à rien, car le garde ne dira rien... Or tu veux que l'objet puisse être volé à un voleur, n'est-ce pas ?

Solution 2:
Détection si oItem est volé, pas si il est donné, c'est à dire si LastAction(oAcquirer==Steal) (si ça existe pas, dis moi le). Je vais faire des recherches....
Ce type de truc existe, c'est même par la que j'avais commencé. Helas, malgré tous mes efforts, la dernière action renvoyé était toujours invalide ...

Sinon je ne comprend pas trop ton premier paragraphe ...
Si l'objet est volé au voleur, son flag "stolen" repasse a "vrai" et le garde se jette sur le voleur du voleur, pas de problèmes. (enfin en théorie, je n'ai pas testé ca, mais je ne vois pas pourquoi le moteur ne ferai pas son travail, car on est d'accord, c'est le moteur de jeu qui fixe le flag "stolen" a vrai)
Voleur1 vole à passant variable est à 0
variable passe à 1
Voleur2 vole à voleur1 variable est à 1... pas bien...

Donc il faut que la variable passe automatiquement à 0 en cas de vol uniquement. Dans ce cas seulement le garde s'en aperçoit, si int = 0 et si la dernière action est un vol...
Citation :
Provient du message de Ange Musicien
Voleur1 vole à passant variable est à 0
variable passe à 1
Voleur2 vole à voleur1 variable est à 1... pas bien...

Donc il faut que la variable passe automatiquement à 0 en cas de vol uniquement. Dans ce cas seulement le garde s'en aperçoit, si int = 0 et si la dernière action est un vol...
Tout a fait, sauf que je n'arrive pas a exploiter la fonction qui renvoie la dernière action.
C'est pour ca que je recrée l'objet, ca remet le flag à 0
Ce n'est pas que je sois particulièrement butté (quoique) mais je ne peu pas utiliser un entier pour ca, car je ne sais pas détecter le vol. Je suis donc obligé d'utiliser la fonction GetFlagStolen() (ou un truc comme ca).

Quand je fait "int aTest=GetCurrentAction(oTest);" aTest n'est jamais égal à ACTION_PICKPOCKET mais a toujours la meme valeur (32xxx, je suppose la valeur "action incorrecte").

(désolé, j'ai un peu du mal a exposer le problème de façon claire et complète)
Ca y est ! Je fais les tests et si ça ne marche pas, j'éditerais. Tu as fait trois grosses erreurs :
- Surtout ne pas rendre d'objet au PC, il le trouvera sur la carcasse du Voleur, en mode dé-volé. Sinon il l'a en double ...
- Créer un objet nécessite un BluePrint, et pas un Tag. Donc utilise GetResRef(oItem) si tu veux créer.
- GetStolenFlag est une variable, il me semble alors qu'il aurait fallu mettre : if(GetStolenFlag(oItem) == TRUE).

Mon script est très différent du tien...
Code PHP:

////////////////////////////////////////////////////
// "Un garde qui detecte le vol" By Ange Musicien //
////////////////////////////////////////////////////

void main()
{
object oSelf OBJECT_SELF;
while(
GetIsObjectValid(oSelf))
//Demande le reperage si le garde est valide
//Créé un mode "repérage" actif en permanence
 
{
 
location lSelf GetLocation(oSelf);
 
object oVoleur GetFirstObjectInShape(SHAPE_SPHERE,10.0,lSelf,FALSE,OBJECT_TYPE_CREATURE);
 while(
GetIsObjectValid(oVoleur))
  {
  
int nAction GetCurrentAction(oVoleur);
  if(
nAction == ACTION_PICKPOCKET)
  
// Uniquement si l'action courrante est le vol
   
{
   
int nDetection GetSkillRank(SKILL_SPOT,oSelf);
   
int nVol GetSkillRank(SKILL_PICK_POCKET,oVoleur);
   if(
nVol+d20(1)<nDetection+d20(1))
   
// Uniquement si le voleur est vu.
    
{
    
ActionSpeakString("Au voleur !!!");
    
SetIsTemporaryEnemy(oVoleur,oSelf,FALSE);
    
ActionAttack(oVoleur,FALSE);
    
//Attaque le voleur
    
int nTestmort GetIsDead(oVoleur);
    
// Verifie que le voleur est mort
    
while(nTestmort==TRUE)
     {
     
object oVole GetFirstItemInInventory(oVoleur);
     
int nTestvole GetStolenFlag(oVole);
     
//Recherche les objets voles
     
if(nTestvole == TRUE)
      {
      
string sResRef GetResRef(oVole);
      
DestroyObject(oVole,0.0);
      
CreateItemOnObject(sResRef,oVoleur,1);
      
// Les remplaces pour qu'il ne soient pas affiches
      // comme voles.
      
}
     }
    }
   }
  }
 }

Hop là, je vais voir si ça marche...

EDIT // J'inclue une phrase de type : "Voleur !!!"
Ne l'utilise pas tout de suite, il faut que j'apporte des modifs...
- Déjà je vais faire en sorte que ça marche lol.
- Ensuite je compte installer des fonctions qui modifient le jet selon la distance du pickpocket (plus il est près et plus le garde à de bonus en détection ).

Mon problème principal est que je ne sais pas où le mettre : dans le OnSpawn ? Dans le OnUserDefined / OnHeartBeat (auquel cas il ferait la détec deux fois par seconde) ? Ou encore dans le OnPercieve ? Quelqu'un peut m'aider ?
Sinon le script est compilé, j'édite la dernière mise à jour qui est détaché de tout On_.
Citation :
Provient du message de Ange Musicien
Ne l'utilise pas tout de suite, il faut que j'apporte des modifs...
- Déjà je vais faire en sorte que ça marche lol.
- Ensuite je compte installer des fonctions qui modifient le jet selon la distance du pickpocket (plus il est près et plus le garde à de bonus en détection ).

Mon problème principal est que je ne sais pas où le mettre : dans le OnSpawn ? Dans le OnUserDefined / OnHeartBeat (auquel cas il ferait la détec deux fois par seconde) ? Ou encore dans le OnPercieve ? Quelqu'un peut m'aider ?
Sinon le script est compilé, j'édite la dernière mise à jour qui est détaché de tout On_.
Hum ... mais euh tu sais *cherche les mots* il marche très bien mon script ... je demandais juste conseil pour l'optimisation ...
Pour info il se place dans le OnAcquireItem (ca me parait logique vu la première ligne du script)
Voui, jusqu'à la restitution de l'objet... Il me paraît difficile de créer un item avec un Tag, non ? En plus, je ne comprends pas pourquoi tu rends l'objet, il faut le mettre sur le cadavre du joueur (PC ou NPC, c'est l'intérêt ).
C'est pour ça que j'en refais un autre. Ton optimisation avait pour but de résoudre certains problèmes, dont le FLagStolen, non ? Il faut donc restructurer complètement, et mettre le flg stolen après la détection du voleur, sinon ... Ton garde sautera sur n'importe quel objet volé, gros problème sur ATS par exemple, et non négligeable. Ou alors tu intègres une variable mais je n'y crois pas trop, il vaut mieux supprimer l'objet et en recréer un neuf...

De plus, le OnAcquire item ne sert à rien : quand il acquière l'item, il l'a déjà volé. En voilà un neuf, qui me semble plus pratique. A toi de voir.

C'est dans le but de résoudre tes problèmes, donc si tu ne veux pas d'aide, dis le, j'ai un script sur les éclairs, un autre sur les marchands et un troisième sur le journal à faire... *snif*

Code PHP:

////////////////////////////////////////////////////
// "Un garde qui detecte le vol" By Ange Musicien //
////////////////////////////////////////////////////
void main()
{
object oSelf OBJECT_SELF;
location lSelf GetLocation(oSelf);
object oVoleur GetFirstObjectInShape(SHAPE_SPHERE,10.0,lSelf,FALSE,OBJECT_TYPE_CREATURE);
while(
GetIsObjectValid(oVoleur))
//Demande le reperage si le garde est valide
 
{
 
int nAction GetCurrentAction(oVoleur);
 if(
nAction == ACTION_PICKPOCKET)
 
// Uniquement si l'action courrante est le vol
  
{
  
int nDetection GetSkillRank(SKILL_SPOT,oSelf);
  
int nVol GetSkillRank(SKILL_PICK_POCKET,oVoleur);
  if(
nVol+d20(1)<nDetection+d20(1))
  
// Uniquement si le voleur est vu.
   
{
   
ActionSpeakString("Au voleur !");
   
SetIsTemporaryEnemy(oVoleur,oSelf,FALSE);
   
ActionAttack(oVoleur,FALSE);
   
//Attaque le voleur
   
int nTestmort GetIsDead(oVoleur);
   
// Verifie que le voleur est mort
   
if(nTestmort==TRUE)
    {
    
object oVole GetFirstItemInInventory(oVoleur);
    
int nTestvole GetStolenFlag(oVole);
    
//Recherche les objets voles
    
while(nTestvole == TRUE && GetIsObjectValid(oVole))
     {
     
string sResRef GetResRef(oVole);
     
location lVoleur GetLocation(oVoleur);
     
DestroyObject(oVole,0.0);
     
CreateObject(OBJECT_TYPE_ITEM,sResRef,lVoleur,FALSE);
     
// Les remplaces pour qu'il ne soient pas affiches
     // comme voles.
     
}
    }
   }
  }
 }

On peut le mettre dans le OnHeartBeat, en le répétant 12 fois par HeartBeat(ce qui demande d'enlever les boucles), ou dans le OnSpawn (ce quiserait plus logique).
pour le sresref/tag, ca apporteras rien à la discut, mais bon..;
c'est possible que le premier script marche, dans la mesure ou beaucoup d'objets standard de bioware ont un TAG et un ResRef identique, les deux fonction renvoyant juste des string, et le create meant tout en misnuscule (me semble) ... mais ca marcheras pas toujours ...
ensuite, le probleme du GetResref
c'est que ca marche que sur les objets présents dans la palette ... donc ayant un resref.
ca pose pas trop de probleme sur un serveur vault tt locké de partt, mais sur des modules plus ouverts ... , les CreateObject(GetResref(oTruc) ... marcheras pas ...
et comme on vole pas que des trucs qui viennent de la palette ...
fin bon, sur un serveur local vault (c ca le nom ?) no pb, mais autrement ...
tiens d'ailleurs, tant que j'y suis, quelqu'un sait si un GetResref marche toujours sur un objet créé par copyobject ?
normalement si il vient de la palette c'est bon, j'imagine mais ... sait'on jamais ... si ca marchait pas, ba ca serais franchement pas top comme qui dirait ... tout objet créé par cette fonction dans un autre script ferait mal à ton script de vol ... fin je suis défaitiste surement, c'est tout
Citation :
Provient du message de Ange Musicien
Voui, jusqu'à la restitution de l'objet... Il me paraît difficile de créer un item avec un Tag, non ? En plus, je ne comprends pas pourquoi tu rends l'objet, il faut le mettre sur le cadavre du joueur (PC ou NPC, c'est l'intérêt ).
C'est pour ça que j'en refais un autre. Ton optimisation avait pour but de résoudre certains problèmes, dont le FLagStolen, non ? Il faut donc restructurer complètement, et mettre le flg stolen après la détection du voleur, sinon ... Ton garde sautera sur n'importe quel objet volé, gros problème sur ATS par exemple, et non négligeable. Ou alors tu intègres une variable mais je n'y crois pas trop, il vaut mieux supprimer l'objet et en recréer un neuf...
Oulalalalala, je me rend compte qu'on ne s'est pas compris du tout !!!
Le but du script n'est pas d'empêcher le vol, mais de mettre le PJ devant ses responsabilités (cad, devant la garde ).
Je m'explique :
-tu vol, si tu te fait prendre, tu as la garde sur le dos.

Citation :
Provient du message de Ange Musicien
De plus, le OnAcquire item ne sert à rien : quand il acquière l'item, il l'a déjà volé. En voilà un neuf, qui me semble plus pratique. A toi de voir.
[/i]
Le but n'était pas de lui donner l'objet, puisqu'il l'a déjà, mais de supprimer l'ancien pour lui en donner un nouveau. Afin d'effacer la marque "stolen".

Citation :
Provient du message de Ange Musicien
C'est dans le but de résoudre tes problèmes, donc si tu ne veux pas d'aide, dis le, j'ai un script sur les éclairs, un autre sur les marchands et un troisième sur le journal à faire... *snif*
[/i]
Si je ne voulais pas d'aide, je ne posterai pas ici Merci a toi pour le temps passé, j'apprécie beaucoup.
D'ailleur je vais utiliser ton script, je ferai juste les modification pour qu'il fonctionne dans le OnPerception.

En espérant que la partie qui récupère l'action en cours fonctionne avec toi, car je n'ai pas réussi a le faire moi
Code PHP:

//::///////////////////////////////////////////////
//:: Bloquer_Les_Vols
//:: Copyright (c)
//:://////////////////////////////////////////////
//:: Created By: Ange Musicien
//:: Modified By: Hidwulf
//:: Created On: 22/03/2003
//:://////////////////////////////////////////////
/*
    -> script a mettre dans un hearbeat de garde
    - Je me suis permis de paufiner un poil tout ça.
    - En toute theorie ce script empeche le vol si
    le garde lie a ce script le remarque ...
    En fait il surprend le voleur qui en perd sa
    concentration et du meme coup son pigeon.
    - A noter qu'on pourrait aussi faire un check
    afin de savoir si le voleur n'a pas un sort
    d'invisibilite sur lui ... Et puis il faudrait
    dans ce cas faire un check sur le garde pour
    savoir si lui il voit l'invisible (enfin c'est peut-être
    géré par la compétence spot mais je suis pas
    certain à voir).
    [..]
*/

int EstVisible (object oObject )
{
    
effect eEffect GetFirstEffectoObject );
    while ( 
GetIsEffectValideEffect ) )
    {
        if( 
GetEffectTypeeEffect ) == EFFECT_TYPE_BLINDNESS )
        {
            return 
1;
        }
        
eEffect GetNextEffectoObject );
    }
    return -
1;
}

int VoitInsivible object oObject )
{
    
effect eEffect GetFirstEffectoObject );
    while ( 
GetIsEffectValideEffect ) )
    {
        if( 
GetEffectTypeeEffect ) == EFFECT_TYPE_SEEINVISIBLE )
        {
            return 
1;
        }
        
eEffect GetNextEffectoObject );
    }
    return -
1;
}

void ScruterLesPassants object MoiLeGarde )
{
    
location lSelf GetLocation(MoiLeGarde);
    
object oVoleur GetFirstObjectInShape(SHAPE_SPHERE,10.0,lSelf,OBJECT_TYPE_CREATURE);
    
/* Boucle representant le balaillage du regard du garde sur les passants ... */
    
while (GetIsObjectValid(oVoleur))
    {
        
/* Ben oui les Dm volent quand y veulent chez moi ! Ahahahahah ...
           Et si ce n'est pas un joueur on ne fait rien du tout hihi
           vois bien des pnjs qui s'amuseraient a voler les joueurs pas vous ?
           Bon c'est sadique je sais */
        
if ( !GetIsPC(oVoleur) || GetIsDM(oVoleur) )
            return;
        
int nAction GetCurrentAction(oVoleur);
        if(
nAction == ACTION_PICKPOCKET)
        {
            if ( 
EstVisible(oVoleur) && VoitInsivible(MoiLeGarde) )
            {
                
int nDetection GetSkillRank(SKILL_SPOT,MoiLeGarde);
                
int nVol GetSkillRank(SKILL_PICK_POCKET,oVoleur);
                
/* test afin de savoir si le voleur est vu par le garde ... */
                
if( nVol+d20(1)<nDetection+d20(1) )
                {
                    
/* L'empeche de voler enfin j'espere ... */
                    
AssignCommand(oVoleur,ClearAllActions(TRUE));
                    
/* TRUE pour arreter toutes les actions mais vraiment toutes */
                    
ActionSpeakString("Au voleur !!");
                    
SetIsTemporaryEnemy(oVoleur,MoiLeGarde,FALSE);
                    
ActionAttack(oVoleur,FALSE);
                    
/* il ne s'occupe que d'un voleur a la fois pauvre garde ... */
                    
return;
                }
                else
                {
                    
/* Ben elle est bien garde la ville avec des gardes qui ne voient pas à plus d'un mètre ! Bande de poivrots !!!
                       Et si on le faisait boire un coup a ce moment la non ? */
                    
AssignCommand(MoiLeGarde,
                    
ActionDoCommand(ActionPlayAnimation(ANIMATION_FIREFORGET_DRINK)));
                }
            }
            else
            {
                
/* Bon le garde n'a rien vu mais il tend la tete un peu parce qu'il a discerner une ombre ... */
                
AssignCommand(MoiLeGarde,
                
ActionDoCommand(ActionPlayAnimation(ANIMATION_LOOPING_LOOK_FAR)));
            }
        }
        else 
/* Regarde les autres personnes près de lui ... */
        
{
            
/* Il a vu quelqu'un mais ce n'est pas un voleur alors il salut cette personne apres tout il est payé pour ca non?? */
            
AssignCommand(MoiLeGarde,
                
ActionDoCommand(ActionPlayAnimation(ANIMATION_FIREFORGET_SALUTE)));
            
GetNextObjectInShape(SHAPE_SPHERE,10.0,lSelf,OBJECT_TYPE_CREATURE);
        }
    }
}

void main()
{
    
ScruterLesPassants(OBJECT_SELF);

A voir si çà marche ... surtout l'histoire du clearallactions. Perso je ne peut pas gérer le flag vole car pas mal de mes items le porte. Je parle bien entendu des items ats de base mais aussi ceux que j'ai ajouté pour ats (+3224 et c'est pas fini), de même pour certains drops faisant ainsi baiser leurs valeurs.
Si quelqu'un veut bien tester comme çà je pourrais savoir si cela fonctionne

@+
T'as vu ce qu'à marqué Iridian ?
Il ne veut pas que le PC soit empêché de vol...
Cela dit nous avons ici tout un lot de possibilités différentes qu'on devrait regrouper dans un ensemble. Avec la possibilité d'envoyer le joueur en prison.

//

A Iridian : Je l'ai aussi modifié pour le mettre dans le OnPerception. Si tu veux je te rajoute une fonction qui varie la perception selon la distance... Pas très dur, tu peux le faire avec des Between facilement.
----> Ton erreur pour le CurrentAction et que quand il a l'objet il a déjà volé, il n'est pas en train de le faire... Il faut donc que le garde détecte en permanence (ou deux fois par secondes, ça évitera de surcharger) les actions en cours...
----> J'avais compris mais tu ne tiens pas en compte le fait que le voleur peut rater ou pas (enfin si, dans ton script le problème ne se posait pas...)

Oualà. Dis moi si ça marche...
Ah oui, je sais mais bon le fait de reprendre un objet avec le flag volé erf quoi. Nan j'ai juste fait une ch'tite version qui n'est pas loin de ce qu'il voulait avoir puisqu'il suffit d'enlever le clearallactions )
Répondre

Connectés sur ce fil

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