1. Ce site utilise des "témoins de connexion" (cookies) conformes aux textes de l'Union Européenne. Continuer à naviguer sur nos pages vaut acceptation de notre règlement en la matière. En savoir plus.

Que pensez-vous de l'idée du plugin ?

Discussion dans 'La Taverne des Yubos Bavards' démarrée par sokarcreative, 28 Décembre 2012.

  1. sokarcreative

    sokarcreative Music never sleep

    Je ne me trompes pas de section, je vous rassure =).
    Vu que j'ai commencé à coder un peu de tout c'est temps-ci, je me suis dit que j'allais faire enfin un vrai plugin assez fun et je voulais savoir ce que vous en pensiez, donc je n'ai pas spécialement besoin d'aide en terme technique (d'où cette section).

    Description rapide : Un joueur choisit un pouvoir dans le /menu. En fonction du pouvoir choisit, les levels s'accumuleront pas de la même façon, pour certains il faudra 5 kills, d'autres 2 kills pour 1 level, etc. Les secondes que le joueur peut bénéficier avec ce pouvoir dépend d'une part du nombre de level qu'il aura accumuler mais également du nombre de secondes enregistrées par level pour ce pouvoir.

    Une fois que le joueur à activer son pouvoir, les nombres de level du joueur sont reset et les kills sont remis à zero ou aux kills non utilisés lors du lancement du pouvoir (calculé à l'aide du modulo).

    - J'ai créer de multiples Cvars qui permettent une grande liberté au configurateur du plugin.
    - J'ai créer un menu dynamique avec des informations qui changent en fonction de différentes variables et cvars enregistrées.
    - J'ajouterai par la suite d'autres pouvoirs comme le "hook" par exemple.
    - J'ai beaucoup optimisé le code par rapport à l'ancienne version que j'ai montré antérieurement (dans d'autres discussions).
    J'ai pas encore terminé le plugin, je vous rassure :

    Je crois que je vais ajouter des variables enableXXX pour les différents pouvoirs. Ainsi certains pouvoirs ne seront pas utilisable selon certaines configurations.

    Dites moi ce que vous en pensez, si vous avez des petites idées supplémentaires à me donner, des idées funs ou autre :) .


    Le code v[0.1.0]
    Code (C):
    #include <amxmodx>
    #include <cstrike>
    #include <hamsandwich>
    #include <fakemeta>
    #include <engine>
    #include <fun>
    #include <cvar_util>
     
    #define PLUGIN_NAME "Test Powers Menu"
    #define PLUGIN_AUTHOR  "sokarcreative"
    #define PLUGIN_VERSION  "0.1.0"
     
    #define Ham_Player_ResetMaxSpeed Ham_Item_PreFrame
    #define MAX_PLAYERS 32
     
    new HamHook:HookKilled;
    new HamHook:HookResetMaxSpeed;
    new HookSetClientKeyValue;
     
     
    new CvarEnable;
    new Float:CvarMaxSpeed, Float:CvarGravity;
    new Float:CvarMaxSpeedSecPerLvl, Float:CvarInvisibilitySecPerLvl, Float:CvarGodmodeSecPerLvl, Float:CvarGravitySecPerLvl, Float:CvarNoclipSecPerLvl;
    new CvarMaxSpeedKillPerLvl, CvarInvisibilityKillPerLvl, CvarGodmodeKillPerLvl, CvarGravityKillPerLvl, CvarNoclipKillPerLvl;
     
    new const maxspeed = 1;
    new const invisibility = 2;
    new const godmode = 3;
    new const gravity = 4;
    new const noclip = 5;
    new const none = 0;
     
    new g_playerKill[MAX_PLAYERS];
    new g_playerPower[MAX_PLAYERS];
    new g_playerLvl[MAX_PLAYERS];
    new bool:g_playerMaxSpeed[MAX_PLAYERS];
     
    new g_powerName[6][] ={
        "aucun",
        "vitesse amélioré",
        "invisibilité",
        "godmode",
        "gravité",
        "noclip"
    }
    enum _:Information
    {
        PlayerIndex,
        PlayerName[ 32 ],
        Time
    }
     
    new g_hudmsg;
     
    public plugin_init()
    {
        register_plugin( PLUGIN_NAME, PLUGIN_VERSION , PLUGIN_AUTHOR );
     
        DisableHamForward( HookKilled = RegisterHam( Ham_Killed, "player", "fw_OnPlayerKilled", true ));
        DisableHamForward( HookResetMaxSpeed = RegisterHam(Ham_Player_ResetMaxSpeed,"player","fw_resetmaxspeed", true));
        HookSetClientKeyValue = register_forward( FM_SetClientKeyValue, "OnSetClientKeyValue", false );
     
        CvarHookChange( CvarRegister( "tpm_enable", "1" ), "OnCvarEnableChange" );
     
        register_clcmd( "say /menu", "menu" );
        register_clcmd( "say_team /menu", "menu" );
        register_clcmd( "say /lvl", "get_level" );
        register_clcmd( "say_team /lvl", "get_level" );
        register_clcmd( "say /pkill", "get_kill" );
        register_clcmd( "say_team /pkill", "get_kill" );
        register_clcmd( "say /usePower", "usePower" );
        register_clcmd( "say_team /usePower", "usePower" );
        register_clcmd( "say /god", "omg_godmode" );
     
        CvarCache( CvarRegister( "tpm_maxspeed", "3000.0" ), CvarType_Float, CvarMaxSpeed );
        CvarCache( CvarRegister( "tpm_gravity", "0.4" ), CvarType_Float, CvarGravity );
     
        CvarCache( CvarRegister( "tpm_maxspeedSecPerLvl", "5.0" ), CvarType_Float, CvarMaxSpeedSecPerLvl );
        CvarCache( CvarRegister( "tpm_invisibilitySecPerLvl", "1.0" ), CvarType_Float, CvarInvisibilitySecPerLvl );
        CvarCache( CvarRegister( "tpm_godmodeSecPerLvl", "2.0" ), CvarType_Float, CvarGodmodeSecPerLvl );
        CvarCache( CvarRegister( "tpm_gravitySecPerLvl", "2.0" ), CvarType_Float, CvarGravitySecPerLvl );
        CvarCache( CvarRegister( "tpm_noclipSecPerLvl", "5.0" ), CvarType_Float, CvarNoclipSecPerLvl );
     
        CvarCache( CvarRegister( "tpm_maxspeedKillPerLvl", "1" ), CvarType_Int, CvarMaxSpeedKillPerLvl );
        CvarCache( CvarRegister( "tpm_invisibilityKillPerLvl", "2" ), CvarType_Int, CvarInvisibilityKillPerLvl );
        CvarCache( CvarRegister( "tpm_godmodeKillPerLvl", "3" ), CvarType_Int, CvarGodmodeKillPerLvl );
        CvarCache( CvarRegister( "tpm_gravityKillPerLvl", "1" ), CvarType_Int, CvarGravityKillPerLvl );
        CvarCache( CvarRegister( "tpm_noclipKillPerLvl", "4" ), CvarType_Int, CvarNoclipKillPerLvl );
     
        g_hudmsg = CreateHudSyncObj();
     
    }
     
    public omg_godmode( id )
    {
        // Fuck le aim des bots :3
        set_user_godmode(id,1);
        if(get_user_godmode(id))
            client_print( id, print_chat , "godmode 1");
    }
     
    public OnSetClientKeyValue( const client, const infoBuffer[], const key[], const value[] )
    {
        if( value[ 0 ] == '1'  && equal( key, "*bot" ) )
        {
            RegisterHamFromEntity( Ham_Killed, client, "fw_OnPlayerKilled", .Post = true );
            RegisterHamFromEntity( Ham_Player_ResetMaxSpeed, client, "fw_resetmaxspeed", .Post = true );
            unregister_forward( FM_SetClientKeyValue, HookSetClientKeyValue, .post = false );
        }
    }
     
     
    public OnCvarEnableChange( const handleCvar, const oldValue[], const newValue[], const cvarName[] )
    {
        ( CvarEnable = str_to_num( newValue ) ) ? EnableHamForward( HookKilled ) : DisableHamForward( HookKilled );
        ( CvarEnable = str_to_num( newValue ) ) ? EnableHamForward( HookResetMaxSpeed) : DisableHamForward( HookResetMaxSpeed );
    }
     
    public menu( id )
    {
        new menuName[40];
        new powerLvlName[40];
        new Float:time = secPerLvl( g_playerPower[ id ] )*float(g_playerLvl[ id ]);
        format(menuName, charsmax(menuName), "\r Ton pouvoir : [%s]", g_powerName[ g_playerPower[ id ] ]);
        format(powerLvlName, charsmax(powerLvlName), "\wUsePower [temps total : %.0f sec(s)]", time);
        new menu = menu_create( menuName,"menu_handler");
        menu_additem( menu, "\wChanger de pouvoirs", "1", 0);
        menu_additem( menu, "\wLvl", "2", 0);
        menu_additem( menu, "\wKill", "3", 0);
        menu_additem( menu, powerLvlName, "4", 0);
        menu_setprop( menu, MPROP_EXIT, MEXIT_ALL );
        menu_display( id, menu, 0 );
    }
     
    public menuPower( id )
    {
        new maxspeedName[70];
        new invisibilityName[70];
        new godmodeName[70];
        new gravityName[70];
        new noclipName[70];
        format(maxspeedName, charsmax(maxspeedName), "\w %s [%.0f sec(s) par lvl] [1 lvl = %d kill(s)]", g_powerName[ maxspeed ], secPerLvl( maxspeed ), killPerLvl( maxspeed ) );
        format(invisibilityName, charsmax(invisibilityName), "\w %s [%.0f sec(s) par lvl] [1 lvl = %d kill(s)]", g_powerName[ invisibility ], secPerLvl( invisibility ), killPerLvl( invisibility ) );
        format(godmodeName, charsmax(godmodeName), "\w %s [%.0f sec(s) par lvl] [1 lvl = %d kill(s)]", g_powerName[ godmode ], secPerLvl( godmode ), killPerLvl( godmode ) );
        format(gravityName, charsmax(gravityName), "\w %s [%.0f sec(s) par lvl] [1 lvl = %d kill(s)]", g_powerName[ gravity ], secPerLvl( gravity ), killPerLvl( gravity ) );
        format(noclipName, charsmax(noclipName), "\w %s [%.0f sec(s) par lvl] [1 lvl = %d kill(s)]", g_powerName[ noclip ], secPerLvl( noclip ), killPerLvl( noclip ) );
     
        new menuPower = menu_create( "\r Menu des pouvoirs :", "menuPower_handler" );
        menu_additem( menuPower, maxspeedName, "1", 0);
        menu_additem( menuPower, invisibilityName, "2", 0);
        menu_additem( menuPower, godmodeName, "3", 0);
        menu_additem( menuPower, gravityName, "4", 0);
        menu_additem( menuPower, noclipName, "5", 0);
        menu_additem( menuPower, "\wAucun pouvoir", "6", 0);
        menu_setprop( menuPower, MPROP_EXIT, MEXIT_ALL );
        menu_display( id, menuPower, 0 );
    }
     
     
    public client_putinserver(id)
    {
            g_playerPower[ id ] = none;
            g_playerLvl[ id ] = 0;
            g_playerKill[ id ] = 0;
            g_playerMaxSpeed[ id ] = false;
    }
     
    public client_disconnect(id)
    {
            g_playerPower[ id ] = none;
            g_playerLvl[ id ] = 0;
            g_playerKill[ id ] = 0;
            g_playerMaxSpeed[ id ] = false;
    }
     
    public menu_handler( id, menu, item)
    {
        if( item == MENU_EXIT )
        {
            menu_destroy( menu );
            return PLUGIN_HANDLED;
        }
     
        new data[6], iName[64];
        new access, callback;
     
        menu_item_getinfo( menu, item, access, data,5, iName, 63, callback );
        new key = str_to_num( data );
        switch( key )
        {
            case 1:
            {
                menuPower( id );
            }
            case 2:
            {
                get_level( id );
            }
            case 3:
            {
                get_kill( id );
            }
            case 4:
            {
                usePower( id );
            }
        }
        menu_destroy( menu );
        return PLUGIN_HANDLED;
    }
     
    public menuPower_handler( id, menu, item)
    {
        if( item == MENU_EXIT )
        {
            menu_destroy( menu );
            return PLUGIN_HANDLED;
        }
     
        new data[6], iName[64];
        new access, callback;
     
        menu_item_getinfo( menu, item, access, data,5, iName, 63, callback );
        new power = str_to_num( data );
     
        if(power == 6)
            power = 0;
     
        changePower(id, power);
        client_print( id, print_chat , "Nouveau pouvoir : %s", g_powerName[ power ]);
        update_lvl( id );
        client_print( id, print_chat , "/usePower pour utiliser ton pouvoir !");
     
        menu_destroy( menu );
        return PLUGIN_HANDLED;
    }
     
    public changePower(id, power){
        g_playerPower[ id ] = power;
    }
     
    public get_level( id ){
        if(g_playerPower[ id ] != none)
            client_print( id, print_chat , "lvl (%s) : %d", g_powerName[ g_playerPower[ id ] ], g_playerLvl[ id ]);
        else
            client_print( id, print_chat , "Aucun pouvoir ! /menu pour choisir un pouvoir");
    }
     
    public get_kill( id ){
        if(g_playerPower[ id ] != none)
            client_print( id, print_chat , "kill (%s) : %d", g_powerName[ g_playerPower[ id ] ], g_playerKill[ id ]);
        else
            client_print( id, print_chat , "Aucun pouvoir ! /menu pour choisir un pouvoir");
    }
     
    public fw_OnPlayerKilled( victim, attacker, shouldgib ){
        if(CvarEnable == 0)
            return HAM_IGNORED;
        if(task_exists(victim))
            change_task(victim, 0.0 ,0);
        if( get_user_team( attacker ) == get_user_team( victim ) && g_playerLvl[ attacker ] > 0)
        {
            g_playerKill[ attacker ] -= killPerLvl( g_playerPower[ attacker ] );
            update_lvl( attacker );
        }
        else if( attacker != victim )
        {
            g_playerKill[ attacker ]++;
            g_playerKill[ victim ] = 0;
            update_lvl( attacker );
            update_lvl( victim );
        }
        return HAM_HANDLED;
    }
     
    public killPerLvl( power ){
        switch( power ){
            case 1 : return CvarMaxSpeedKillPerLvl;
            case 2 : return CvarInvisibilityKillPerLvl;
            case 3 : return CvarGodmodeKillPerLvl;
            case 4 : return CvarGravityKillPerLvl;
            case 5 : return CvarNoclipKillPerLvl;
        }
        return 0;
    }
     
    Float:secPerLvl( power ){
        switch( power ){
            case 1 : return CvarMaxSpeedSecPerLvl;
            case 2 : return CvarInvisibilitySecPerLvl;
            case 3 : return CvarGodmodeSecPerLvl;
            case 4 : return CvarGravitySecPerLvl;
            case 5 : return CvarNoclipSecPerLvl;
        }
        return 0.0
    }
     
    public update_lvl( id ){
        g_playerLvl[ id ] = g_playerKill[ id ] / killPerLvl( g_playerPower[ id ] );
    }
     
    public usePower( id ){
        if(g_playerPower[ id ] == 0 || g_playerLvl[ id ] == 0 || task_exists(id, 0))
        {
            return PLUGIN_HANDLED;
        }
        g_playerKill[ id ] = g_playerKill[ id ] % killPerLvl( g_playerPower[ id ] );
        set_power( id );
        return PLUGIN_HANDLED;
    }
     
    public set_power( id ){
        new data[ Information ];
        data[ PlayerIndex ] = id ;
        get_user_name( id , data[ PlayerName ] , charsmax( data[ PlayerName ] ) );
        new Float:time = secPerLvl( g_playerPower[ id ] )*float(g_playerLvl[ id ]);
        data[ Time ] = floatround(time);
        switch( g_playerPower[ id ] )
        {
            case 1 :
            {
                set_user_maxspeed(id, CvarMaxSpeed);
                g_playerMaxSpeed[ id ] = true;
            }
            case 2 : set_user_rendering(id, kRenderFxNone, 0,0,0, kRenderTransAdd,5);
            case 3 : set_user_godmode( id, 1 );
            case 4 : set_user_gravity( id, CvarGravity );
            case 5 : set_user_noclip( id, 1 );
        }
        client_print( data[ PlayerIndex ], print_chat , "[%s] commencé", g_powerName[ g_playerPower[ data[ PlayerIndex ] ] ]);
        set_task(time , "unset_power", id, data, sizeof( data ));
        set_task(0.0, "hud_message", id, data, sizeof( data ));
        update_lvl( id );
    }
     
    public unset_power( data[ Information ] ){
        switch( g_playerPower[ data[ PlayerIndex ] ] )
        {
            case 1 :
            {
                set_user_maxspeed(data[ PlayerIndex ], 320.0);
                g_playerMaxSpeed[ data[ PlayerIndex ] ] = false;
            }
            case 2 : set_user_rendering(data[ PlayerIndex ] ,kRenderFxNone,255,255,255, kRenderNormal,16);
            case 3 : set_user_godmode( data[ PlayerIndex ], 0 );
            case 4 : set_user_gravity( data[ PlayerIndex ], 1.0 );
            case 5 : set_user_noclip( data[ PlayerIndex ], 0 );
        }
        client_print( data[ PlayerIndex ], print_chat , "[%s] terminé", g_powerName[ g_playerPower[ data[ PlayerIndex ] ] ]);
    }
     
    public hud_message( data[ Information ] ){
        set_hudmessage(0, 255, 0, 0.01, 0.7, 0, 0.1, 2.0, 0.1, 0.1, -1);
        data[ Time ] -= 1;
        if(data[ Time ] >= 0)
        {
            ShowSyncHudMsg(data[ PlayerIndex ], g_hudmsg, "[%s] reste %d sec(s)", g_powerName[ g_playerPower[ data[ PlayerIndex ] ] ], data[ Time ]);
            set_task(1.0, "hud_message", data[ PlayerIndex ], data, sizeof( data ));
        }
    }
     
    public fw_resetmaxspeed( id ){
        if(g_playerMaxSpeed[ id ])
            set_user_maxspeed(id, CvarMaxSpeed);
        else
            set_user_maxspeed(id, 320.0);
    }
    PS : j'ai pas encore trouvé de nom vraiment adéquat pour le plugin d'où le nom un peu nul. :D 
     

    Pièces jointes:

    Tags:
  2. Arkshine

    Arkshine Le Docteur

    Non, je ne crois pas que tu veuilles entendre notre avis. :ROFLMAO: 
     
  3. micapat

    micapat Nyuu Nyuuu !?

    Ça ressemble un peu au mode Warcraft :unsure:  Enfin : des pouvoirs, des levels, ...
     
  4. sokarcreative

    sokarcreative Music never sleep

    Bah si... :unsure: 

    J'ai pas encore testé ce plugin mais j'irai voir ce qu'il en retourne

    Edit : micapat : Wow ça m'a l'air bien plus poussé et farfelu que ce que je suis en train de faire quand même
     
    Dernière édition: 28 Décembre 2012
  5. ConnorMcLeod

    ConnorMcLeod Modérateur

    Un Nième mod avec les pouvoirs les plus répandus :) 
    Mais pour t'entraîner pourquoi pas.
     
  6. sokarcreative

    sokarcreative Music never sleep

    Oui bien sûr, ça reste malgré tout un entrainement :ROFLMAO: . Faire des pouvoirs personnalisés ça demandera beaucoup de patience et de temps !
    (Au moins ce plugin m'occupe lors de mes pauses car oui j'ai examens dans 10 jours :cry:  )
     
  7. Arkshine

    Arkshine Le Docteur

    L'idée est complètement pourrie. C'est tellement vu, revu, remaché, partout, dans tous les sens, dans la plupart des plugins, que ça devient vraiment "boring as hell". Ca n'a rien d'original, c'est trop simple, c'est sans intérêt. C'est nul en somme. :D 

    Après comme le dis Connor, pour t'entrainer à coder, toute idée est bonne à prendre et ça importe peu ; l'intérêt est surtout que ça te motive toi.
     
  8. sokarcreative

    sokarcreative Music never sleep

    J'apprécie ta franchise et quoiqu'il en soit, ce n'est pas aujourd'hui que je vais vous pondre le plugin de demain mais bon j'essaie de m'accrocher à l'idée que ce sur quoi je m'exerces n'est pas complètement useless. Utiliser les pouvoirs dans les plugins, c'est un classique mais c'est sans doute le meilleur moyen de voir "de manière concrète" si son code est bon. :geek: 

    J'aurais tout de même préféré des commentaires autres que tournant autour de "pouvoirs" en tant que telle.
    J'ai l'impression que votre opinion est affecté par le concept de "pouvoir".
    "pouvoir" ==> "tout le monde en fait" ==> "opinion préconçu : null" ==> CQFD

    Après peut-être que je me trompes et que je suis en manque d'imaginations... :arghh: 

    Bref, j'apprécie beaucoup les critiques car c'est comme ça qu'on avance. ;) 

    PS : c'est pas pour autant qu'il faut m'en mettre pleins la vue :LOL: 
     
  9. Arkshine

    Arkshine Le Docteur

    Non, tu ne comprends pas. Mon avis est surtout basé sur la quantité de codes qu'on voit sur le forum Amxx. Beaucoup sont des mini-plugins qui proposent juste des "pouvoirs" de base, les plus simples et rien d'autres, comme le tien. Ce n'est pas une opinion préconçue, même si je peux comprendre que ce n'est pas agréable de se voir dire que son idée est nulle :p  ; c'est juste un fait, une réalité, ton plugin est ultra-méga-basique et ne proposes rien de concret, d'original. Si tu ne connais pas War3 FT, ou encore SuperHero, je peux comprendre ton étonnement, ce sont des gros mods avec des "pouvoirs" mais en version bien plus poussés, et tu as pleins de mods-like dans ce genre. Ce que je veux dire, c'est que tu débarques, et tu demandes un avis sur un plugin qui ne fait "rien", avec une idée que tu penses "originale" et "cool", mais le souci c'est que tu as un sacré train de retard, ça déjà été exploité de long en large sur de nombreux plugins/mods :ROFLMAO:  ; tu comprendras donc pourquoi on a cette réaction "Arf, encore un plugin avec des pouvoirs..." ; et de plus, tu n'as pas de chance, ceux qui ont répondu sont des codeurs aguerris. Répondre sur ton idée, en tout cas pour nous, c'est juste pas possible, tellement ton code/idée est basique/générique/inintéressant et ça irait plus vite que tu regardes par toi-même ces mods en question. J'espère que tu comprends mieux un peu notre réaction. :) 

    Par contre, on peut critiquer ton code et t'aider à t'améliorer. En fait, je peux te conseiller de ne pas te focaliser trop sur les "idées". Tu es débutant, ce qui explique évidemment que ton code est basique (ce n'est pas une critique négative), mais tant que tu n'auras pas un niveau suffisant pour faire un peu tout ce que tu veux, ne perds pas ton temps à vouloir réinventer la roue. Le plus important, pour le moment, c'est que si tu as une idée qui te motive, utilises-la pour ton apprentissage, mais n'en fait pas non plus un objectif à peaufiner dans tous les sens, ça n'a aucun intérêt. Le but c'est que tu génères du code sur la base d'une idée simple. Une fois que tu as implémenté cette idée simple, et que tu as assimilé le code correspondant, tu passes à autres chose. Une fois que tu seras capable d'apprendre/faire un peu n'importe quoi, tu verras les choses différemment, aura des idées plus poussées, et tu pourras commencer à faire ton premier vrai projet, et à ce moment là, tu pourras demander des avis et tu auras sans aucun doute des retours pertinent.
     
    Dernière édition: 28 Décembre 2012
  10. sokarcreative

    sokarcreative Music never sleep

    C'est vrai que je m’attarde beaucoup sur les petits détails d'un plugin alors que comme tu le dis, je devrais plutôt explorer un peu tous les coins des fonctions, des modules, etc avant de m'embarquer dans un projet sans intérêt (sans contenu).
    Je crois que, NON JE VAIS explorer du code en profondeur dans des plugins complexes pour ma culture pawnienne et pour avancer vraiment !

    Yep ! Comme disait également Connor, je brûles des étapes et par ma propre constatation je suis trop vite satisfait du travail fournit.

    La résolution 2013 (je profites de la nouvelle année :angel:  ) : Recherches, recherches et recherches !

    Merci pour cet épilogue rassurant, motivant et constructif :) 

    Java, HTML, PHP, CSS, SQL, Langage C et bientôt toi "PAWN" ! ahah :mad: 
     
  11. ConnorMcLeod

    ConnorMcLeod Modérateur

    Pense aussi à télécharger HLSDK, c'est une excellente référence, même si c'est pas le code source de cs, y'a plein de choses intéressantes et qui permettent de comprendre le fonctionnement du jeu.
    En + comme tu connais le C ça sera facile à lire pour toi.
     

Partager cette page

Chargement...
Chargement...