La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
La date/heure actuelle est 20/05/2024 06:52:42


  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
ballestolive
Ecuyer
Inscrit le: 15 Nov 2005
Messages: 64
Localisation: A 35 KM Sud de Paris.
Répondre en citant
Posté le : 14/01/2006 21:23:15 Sujet du message : Demande aide script de repos autorisé par plusieurs objets.

Voila j'ai actuellement un script de repos qui autorise le repos si on a un objet "BOUFFE" dans l'inventaire, en plus de quelques autres conditiond. Et je souhaiterai qu'il n'y est pas que cet objet BOUFFE qui autorise le repos mais d'autres items ( créer par le TS ) avec différents tag. Etant un newbie en script je solicite donc la communauté pour sa générosité et sa grande compétence.

D'avance merci. voici le script actuel:

NWScript :
// modification du dodo par nono3

#include "com_constantes"
#include "com_include"
#include "rest_include"

//Confused//////////////////////// /////////////////////
//:: Nom s3_MDL_dodo1
//:: Module Mer de Lune (Lunerousse)
//Confused//////////////////////// ////////////////////

//Confused//////////////////////// ////////////////////
//:: Created By: Jouby
//:: Created On: 2004
//Confused//////////////////////// ////////////////////

void ClearDarkness(object oOwner)//effacer l'effet du noir de l'ecran
{
effect eTemp=GetFirstEffect(oOwner);
effect eEcranNoir = EffectVisualEffect(VFX_DUR_BLACKOUT);
while(GetIsEffectValid(eTemp))
{
if(GetEffectType(eTemp)==GetEffectType(eEcranNoir))
{
RemoveEffect(oOwner, eTemp);
}
eTemp=GetNextEffect(oOwner);
}
}
/////////////////////////// ///////////////////
//Pas de repos sans nourriture//////////////////
//script du Troubadour//////////////////// /////
////////////////////////////// //////////////////
//Mode d'emploi : placer ce script dans le "OnRest" du module"//
//Creer un ou plusieurs objets non stackable portant le tag "BOUFFE"//

//Ce qui suit est une nouvelle fonction, elle n'est pas de moi//
//Elle cherche un item donne dans l'inventaire du PJ//

object CheckInventoryForItem(object oPC, string sItemTag)
{
  object oItem = GetFirstItemInInventory (oPC);
  while (oItem != OBJECT_INVALID)
  {
    if (GetTag(oItem) == sItemTag)
      return oItem;
    oItem = GetNextItemInInventory (oPC);
  }
  return OBJECT_INVALID;
}
//VARIABLE MODIFIABLES
//Le nombres d'heure durant lequelles le joueurs doit attendre


int TIMEBETWEENRESTING=6;
//Le nombre reel de minutes qui correspond a 1 heure dans le jeu
int REALTIMEMINUTES=2;
//FIN DES VARIABLES MODIFIABLES
int CurrentTime();


void main()//fonction principale

{
string sItemTag = "BOUFFE";
object oPC = GetLastPCRested();
object oItemRequis = CheckInventoryForItem(oPC, sItemTag);
object oTarget = oPC;
object oZone5 = GetArea(oPC);
object oPlaceable = GetFirstObjectInArea(oZone5);
string sTag = GetTag(oPlaceable);
string sReposInterdit = "s3_repos_interdi";
string sRepos_Interdit_animation = "A cause d'une animation en cours, le repos est interdit dans la zone pour raison de RP";
int iCurrentTime, iLastRestTime, iTimeSinceRest, iTimeUntilRest;
float fTimePenalty;

switch (GetLastRestEventType())
{
case REST_EVENTTYPE_REST_STARTED:
iCurrentTime = CurrentTime();
iLastRestTime = GetLocalInt(oPC,"REST_HOUR");
iTimeSinceRest = iCurrentTime-iLastRestTime;
SetLocalInt(oPC, "REST_SECOND", GetTimeSecond());
if (iLastRestTime==0 || iTimeSinceRest >= TIMEBETWEENRESTING)
{
SetLocalInt(oPC, "REST_ALLOWED", TRUE);


//Lorsque le joueur click sur "se reposer" le script verifie la presence de l'item "bouffe"//
//S'il n'y en a pas le repos est annule et un message envoye au joueur//
    if (GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED)
      {
      if (GetItemPossessedBy(oPC,"BOUFFE") == OBJECT_INVALID)
        {
        SendMessageToPC (oPC, "Impossible de vous reposer avec cette faim qui vous tenaille...");
        AssignCommand (oPC,ClearAllActions());
        }
//si l'item "bouffe" est present le repos est lance et un seul item de ce type detruit//
        else
        {
        DestroyObject(oItemRequis, 0.0);


while (GetIsObjectValid(oPlaceable))
{
if (sReposInterdit == sTag)
{
SendMessageToPC(oPC,sRepos_Interdit_animation);
AssignCommand(oPC, ClearAllActions());
return;
}
oPlaceable = GetNextObjectInArea(oZone5);
}



if (GetLastRestEventType()== REST_EVENTTYPE_REST_STARTED)
{
PlayVoiceChat(VOICE_CHAT_REST, oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_BLACKOUT), oTarget);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_IMP_SLEEP), oTarget);
}

if (GetLastRestEventType()== REST_EVENTTYPE_REST_CANCELLED)
{
ClearDarkness(oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSlow(), oTarget, 30.0f);
SendMessageToPC(oPC, "Le reveil suite a un repos interrompu est toujours tres difficile");
}

if (GetLastRestEventType()== REST_EVENTTYPE_REST_FINISHED)
{
ClearDarkness(oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSlow(), oTarget, 10.0f);
SendMessageToPC(oPC, "S'arracher des bras de Sylune vous demande encore quelques instants");
}
}
}








}
else
{
SetLocalInt(oPC, "REST_ALLOWED", FALSE);
iTimeUntilRest = (TIMEBETWEENRESTING-iTimeSinceRest);
if (REALTIMEMINUTES == 1)
{
iTimeUntilRest = FloatToInt(HoursToSeconds(iTimeUntilRest)/60);
//Vous pouvez changer le message si le repos n'est pas encore
//autoriser
if (iTimeUntilRest == 1)
{
FloatingTextStringOnCreature("Vous devez attendre " +
"1 heure avant de pouvoir vous reposer", oPC);
}
else
{
FloatingTextStringOnCreature("Vous devez attendre "+
IntToString(iTimeUntilRest)+
" heures avant de pouvoir vous reposer", oPC);
}
}
else
{
if (iTimeUntilRest == 1)
{
FloatingTextStringOnCreature("Vous devez attendre " +
"1 heure avant de pouvoir vous reposer", oPC);
}
else
{
FloatingTextStringOnCreature("Vous devez attendre "+
IntToString(iTimeUntilRest)+
" heures avant de pouvoir vous reposer", oPC);
}
}
//Annuler le repos
AssignCommand(oPC,ClearAllActions());
}
break;
case REST_EVENTTYPE_REST_CANCELLED:
//variable sur le temps de repos
if (GetLocalInt(oPC, "REST_ALLOWED") == TRUE)
{
iCurrentTime = GetTimeSecond();
iLastRestTime = GetLocalInt(oPC, "REST_SECOND");
iTimeSinceRest = iCurrentTime - iLastRestTime;
if (iTimeSinceRest<0) iTimeSinceRest+= 60;
fTimePenalty = TIMEBETWEENRESTING*(iTimeSinceRest/(0.5*GetHitDice(oPC)+10));
SetLocalInt(oPC,"REST_HOUR", CurrentTime()-(TIMEBETWEENRESTING-FloatToInt(fTimePenalty)));
}
break;
case REST_EVENTTYPE_REST_FINISHED:
SetLocalInt(oPC, "REST_HOUR", CurrentTime());
}








}



  int CurrentTime()
{
return GetCalendarYear()*8064 + GetCalendarMonth()*672 + GetCalendarDay()*24 + GetTimeHour();
}
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.


Encore merci Smile
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Ignorer l'utilisateur
 
BenGorre
Légende vivante
Inscrit le: 12 Fév 2004
Messages: 301
Répondre en citant
Posté le : 15/01/2006 09:50:34 Sujet du message :

Bonjour bonjour,

Tu veus qu'on puisse dormire avec "BOUFFE" ET les autres objets? ou avec "BOUFFE" OU les autres?
_________________
La mort n'est rien seul le fait de mourir est terrible
Henry Fielding 1745

Le serveur Filandre a été stoppé pour le moment, je on travail à la conversion vers NWN2.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
ballestolive
Ecuyer
Inscrit le: 15 Nov 2005
Messages: 64
Localisation: A 35 KM Sud de Paris.
Répondre en citant
Posté le : 15/01/2006 15:09:50 Sujet du message :

Je souhaiterai que l'on puisse dormir avec BOUFFE ou d'autres items avec d'autres TAGs.

En fais le TS que l'on utilise donne plusieurs modèle d'item qui peuvent être manger donc je vouais les utiliser.

Merci de votre aide.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Ignorer l'utilisateur
 
Elandil2
Chevalier
Inscrit le: 14 Fév 2005
Messages: 97
Localisation: sur mon ordi loir-et-cher
Répondre en citant
Posté le : 15/01/2006 18:10:38 Sujet du message :

J'ai ce qu'il te faut ...
Si t'es patient je te fait ca Wink
_________________
Rejoignez nous sur notre forum
Aelor, module en construction
Vive Gimli

 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Ignorer l'utilisateur
 
Elandil2
Chevalier
Inscrit le: 14 Fév 2005
Messages: 97
Localisation: sur mon ordi loir-et-cher
Répondre en citant
Posté le : 15/01/2006 18:29:01 Sujet du message :

*Message a supprimer*
_________________
Rejoignez nous sur notre forum
Aelor, module en construction
Vive Gimli

Dernière édition par Elandil2 le 15/01/2006 18:31:01; édité 1 fois
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Ignorer l'utilisateur
 
Elandil2
Chevalier
Inscrit le: 14 Fév 2005
Messages: 97
Localisation: sur mon ordi loir-et-cher
Répondre en citant
Posté le : 15/01/2006 18:29:34 Sujet du message :

Voila, il te suffit tout simplelment de rajouter "repos_" devant le tag d'un obbjet néssessaire a dormir ...

NWScript :
// modification du dodo par nono3
////////////////////////// /////////////////////
//:: Nom s3_MDL_dodo1
//:: Module Mer de Lune (Lunerousse)
////////////////////////// ////////////////////

////////////////////////// ////////////////////
//:: Created By: Jouby
//:: Created On: 2004
////////////////////////// ////////////////////

void ClearDarkness(object oOwner)//effacer l'effet du noir de l'ecran
{
effect eTemp=GetFirstEffect(oOwner);
effect eEcranNoir = EffectVisualEffect(VFX_DUR_BLACKOUT);
while(GetIsEffectValid(eTemp))
{
if(GetEffectType(eTemp)==GetEffectType(eEcranNoir))
{
RemoveEffect(oOwner, eTemp);
}
eTemp=GetNextEffect(oOwner);
}
}
/////////////////////////// ///////////////////
//Pas de repos sans nourriture//////////////////
//script du Troubadour//////////////////// /////
////////////////////////////// //////////////////
//Mode d'emploi : placer ce script dans le "OnRest" du module"//
//Creer un ou plusieurs objets non stackable portant le tag "BOUFFE"//

//Ce qui suit est une nouvelle fonction, elle n'est pas de moi//
//Elle cherche un item donne dans l'inventaire du PJ//

object CheckInventoryForItem(object oPC, string sItemTag)
{
  object oItem = GetFirstItemInInventory (oPC);
  while (oItem != OBJECT_INVALID)
  {
    if (GetStringLeft(GetTag(oItem),6) == sItemTag)
      return oItem;
    oItem = GetNextItemInInventory (oPC);
  }
  return OBJECT_INVALID;
}
//VARIABLE MODIFIABLES
//Le nombres d'heure durant lequelles le joueurs doit attendre


int TIMEBETWEENRESTING=6;
//Le nombre reel de minutes qui correspond a 1 heure dans le jeu
int REALTIMEMINUTES=2;
//FIN DES VARIABLES MODIFIABLES
int CurrentTime();


void main()//fonction principale

{
string sItemTag = "repos_";
object oPC = GetLastPCRested();
object oItemRequis = CheckInventoryForItem(oPC, sItemTag);
object oTarget = oPC;
object oZone5 = GetArea(oPC);
object oPlaceable = GetFirstObjectInArea(oZone5);
string sTag = GetTag(oPlaceable);
string sReposInterdit = "s3_repos_interdi";
string sRepos_Interdit_animation = "A cause d'une animation en cours, le repos est interdit dans la zone pour raison de RP";
int iCurrentTime, iLastRestTime, iTimeSinceRest, iTimeUntilRest;
float fTimePenalty;

switch (GetLastRestEventType())
{
case REST_EVENTTYPE_REST_STARTED:
iCurrentTime = CurrentTime();
iLastRestTime = GetLocalInt(oPC,"REST_HOUR");
iTimeSinceRest = iCurrentTime-iLastRestTime;
SetLocalInt(oPC, "REST_SECOND", GetTimeSecond());
if (iLastRestTime==0 || iTimeSinceRest >= TIMEBETWEENRESTING)
{
SetLocalInt(oPC, "REST_ALLOWED", TRUE);


//Lorsque le joueur click sur "se reposer" le script verifie la presence de l'item "bouffe"//
//S'il n'y en a pas le repos est annule et un message envoye au joueur//
    if (GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED)
      {
      if (GetIsObjectValid(oItemRequis) == FALSE)
        {
        SendMessageToPC (oPC, "Impossible de vous reposer avec cette faim qui vous tenaille...");
        AssignCommand (oPC,ClearAllActions());
        }
//si l'item "bouffe" est present le repos est lance et un seul item de ce type detruit//
        else
        {
        DestroyObject(oItemRequis, 0.0);


while (GetIsObjectValid(oPlaceable))
{
if (sReposInterdit == sTag)
{
SendMessageToPC(oPC,sRepos_Interdit_animation);
AssignCommand(oPC, ClearAllActions());
return;
}
oPlaceable = GetNextObjectInArea(oZone5);
}



if (GetLastRestEventType()== REST_EVENTTYPE_REST_STARTED)
{
PlayVoiceChat(VOICE_CHAT_REST, oPC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_BLACKOUT), oTarget);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_IMP_SLEEP), oTarget);
}

if (GetLastRestEventType()== REST_EVENTTYPE_REST_CANCELLED)
{
ClearDarkness(oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSlow(), oTarget, 30.0f);
SendMessageToPC(oPC, "Le reveil suite a un repos interrompu est toujours tres difficile");
}

if (GetLastRestEventType()== REST_EVENTTYPE_REST_FINISHED)
{
ClearDarkness(oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSlow(), oTarget, 10.0f);
SendMessageToPC(oPC, "S'arracher des bras de Sylune vous demande encore quelques instants");
}
}
}








}
else
{
SetLocalInt(oPC, "REST_ALLOWED", FALSE);
iTimeUntilRest = (TIMEBETWEENRESTING-iTimeSinceRest);
if (REALTIMEMINUTES == 1)
{
iTimeUntilRest = FloatToInt(HoursToSeconds(iTimeUntilRest)/60);
//Vous pouvez changer le message si le repos n'est pas encore
//autoriser
if (iTimeUntilRest == 1)
{
FloatingTextStringOnCreature("Vous devez attendre " +
"1 heure avant de pouvoir vous reposer", oPC);
}
else
{
FloatingTextStringOnCreature("Vous devez attendre "+
IntToString(iTimeUntilRest)+
" heures avant de pouvoir vous reposer", oPC);
}
}
else
{
if (iTimeUntilRest == 1)
{
FloatingTextStringOnCreature("Vous devez attendre " +
"1 heure avant de pouvoir vous reposer", oPC);
}
else
{
FloatingTextStringOnCreature("Vous devez attendre "+
IntToString(iTimeUntilRest)+
" heures avant de pouvoir vous reposer", oPC);
}
}
//Annuler le repos
AssignCommand(oPC,ClearAllActions());
}
break;
case REST_EVENTTYPE_REST_CANCELLED:
//variable sur le temps de repos
if (GetLocalInt(oPC, "REST_ALLOWED") == TRUE)
{
iCurrentTime = GetTimeSecond();
iLastRestTime = GetLocalInt(oPC, "REST_SECOND");
iTimeSinceRest = iCurrentTime - iLastRestTime;
if (iTimeSinceRest<0) iTimeSinceRest+= 60;
fTimePenalty = TIMEBETWEENRESTING*(iTimeSinceRest/(0.5*GetHitDice(oPC)+10));
SetLocalInt(oPC,"REST_HOUR", CurrentTime()-(TIMEBETWEENRESTING-FloatToInt(fTimePenalty)));
}
break;
case REST_EVENTTYPE_REST_FINISHED:
SetLocalInt(oPC, "REST_HOUR", CurrentTime());
}








}



  int CurrentTime()
{
return GetCalendarYear()*8064 + GetCalendarMonth()*672 + GetCalendarDay()*24 + GetTimeHour();
}
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.

_________________
Rejoignez nous sur notre forum
Aelor, module en construction
Vive Gimli

 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Ignorer l'utilisateur
 
ballestolive
Ecuyer
Inscrit le: 15 Nov 2005
Messages: 64
Localisation: A 35 KM Sud de Paris.
Répondre en citant
Posté le : 15/01/2006 18:37:25 Sujet du message :

Je te remercie beaucoup, mais malheureusement ta solution n'est pas envisageable dans mon cas car les objets qui vont permettre de se reposer son créer par mon système de TS ( en fait j'utilise ATS. Et les objet sont spawner dans le corps des animeau que l'on dépecent. Donc il faut respecter le TAG en place des objets donné par le TS. Par de renomage passible DSL.

Tous les objets sont basé sur ce model de tag: "ATS_R_xxxx_N_MEAT" les xxxx sont remplacer par quatre lettre permettant la différentiation de l'animal d'ou viens la viande.

Peux être qu'avec ta modif et ces information, il est possible de faire quelque chose qui colle mieux.

En tout cas merci.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Ignorer l'utilisateur
 
edisnotdead
Grand Chevalier
Inscrit le: 19 Fév 2005
Messages: 132
Répondre en citant
Posté le : 16/01/2006 06:55:23 Sujet du message :

...
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
lylver
Héros
Inscrit le: 08 Avr 2005
Messages: 274
Répondre en citant
Posté le : 16/01/2006 14:13:13 Sujet du message :

Le code du repos d'un module en ligne utilisant
- feu de camp
- tente
- aliments
- délai minimum entre 2 repos

Il tient compte des conditions climatiques et gère un repos partiel, voire maladie
=> variables locales sur les zones optionnelles pour des effets particuliers

On peut désactiver certaines parties.
Note : une initialisation d'une variable horaire doit être faite à l'entrée du personnage joueur dans le jeu.
Au début on le trouve un peu lourdingue, mais comme il n'est pas bloquant...

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 :
//:Confused/
//:: Update Lylver 2005-12-12
//:: evt 550 : regenere les effets du aux custom items apres repos
//:Confused/
//:: Update Lylver 2005-12-11
//:: correction erreur maladie
//:Confused/
//:: Update Lylver 2005-10-15
//:: changement : ameliore critere bRepas
//:: manger = guerison complete
//:: maladie isolee
//:: rayon de la zone de tente augmente 7.0 au lieu de 5.0
//:Confused/
//:: Update Lylver 2005-09-29
//:: variables pour les zones
//:: int REPOS :
//
// 1 - feu requis
// 2 - tente/abri requis
// 3 = 2 & 1 : les deux requis
//:: int MIASME : (positif) malus au jet de vigueur
//:: string REPOS1, message specifique de zone remplacant "Il fait froid"
//:: string REPOS2, message specifique de zone remplacant "Il fait humide"
//:Confused/
//:: Update Lylver 2005-09-17
//:: repos non bloquant => maladie a la place
//:Confused/
//:: Update Lylver 2005-09-16
//:: adaptation TN Bouchon 2
//:Confused/////////////////////////////////////
// Update Lylver 2005-08-01 : mise en fonction de la reputation
// Note : reste encore des pbs de repos intempestif (rares)
//::
// mod_onrest
// by dluan on sep 2003,
// updated Lylver 2004-04-17
// Update Lylver 2004-12-15 pour SoW 3h<>540s
// Update Lylver 2004-12-17 pour SoW materiel de camping.
// remplace x2_mod_def_rest a etudier
// Update Lylver 2005-06-03 : correction repos intempestif
// enlevant les sorts de facon aggressive
//:Confused/////////////////////////////////////
#include "nw_i0_plot"
#include "ly_lib_time"
#include "ly_lib_death"
#include "x0_i0_position"

void main()
{
    object oPC = GetLastPCRested() ;
    object oArea = GetArea(oPC);
    object oMod = GetModule() ;
// code TN Bouchon specifique
  object oFood ;
    if(GetTag(oArea)=="Zone002")
    {
        SendMessageToPC(oPC,LocationToString(GetAheadLocation(oPC)));
        return;
    }
// code TN Bouchon specifique
    int iHostileRange = 30;
    int nDisease = 0 ;
    int bRepas = FALSE ;
    int nCirc = 0 ;
    string sDisease = "";
    // set a stack size
    int i = 10;
    // set an object equal to the provisions on the player. This will be
    // OBJECT_INVALID if the player doesn't have any
    object oProvisions = GetItemPossessedBy(oPC, "PROVISIONS");
    int nSetting = GetLocalInt(oArea, "REPOS");
    int nSetDis = GetLocalInt(oArea, "MIASME");
    string sMessage1 = GetLocalString(oArea, "REPOS1");
    string sMessage2 = GetLocalString(oArea, "REPOS2");
    int  nModif = GetAbilityModifier(ABILITY_CONSTITUTION,oPC); //... corrige 2005-03-28
    int  iCDay = ly_day() ;
    int  iCTime = ly_time() ;
    int  iRestDelay ;
    int  iRestDay ;
    int  iRestSecond ;
/*  int  RESTDELAY = 540 ; // Real Time 3min <=> 1h Game Play
    // Repos toutes les 3 heures  */
    int  RESTDELAY = 120 ; // Real Time 5min <=> 1h Game Play
    // Repos toutes les 2 minutes irl
    int curHP = GetCurrentHitPoints(oPC);
    int maxHP = GetMaxHitPoints(oPC);

    // debut du repos
    if (GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED) {

// code TN Bouchon partie 1/2
        // Aliments pour manger, necessaire avant de se reposer.
        SendMessageToPC(oPC,"Vous essayez de vous reposer....");
        if( HasItem(oPC,"alimentderepos1") &&
            HasItem(oPC,"alimentderepos2") &&
            HasItem(oPC,"alimentderepos3") ){
            WriteTimestampedLogEntry("Repos de "+GetName(oPC));
            bRepas = TRUE ;
        } else {
            SendMessageToPC(oPC,"Vous n'avez pas ce qu'il faut pour vous nourrir avant de vous reposer");
            SendMessageToPC(oPC,"Vous ressentirez la faim à votre réveil");
            if( oProvisions == OBJECT_INVALID ){
              bRepas = FALSE ;
            } else {
              bRepas = TRUE ;
            }
            // AssignCommand(oPC, ClearAllActions());
        }

// code TN Bouchon partie 1/2

        iRestDay = GetLocalInt(oPC, "PC_LastDayRest");
        iRestSecond = GetLocalInt(oPC, "PC_LastRest") ;
        iRestDelay = iCTime - iRestSecond + FloatToInt(HoursToSeconds((iCDay - iRestDay) * 24));
        SetLocalInt(oPC, "PC_HPRest", curHP);
        SetLocalInt(oPC, "PC_CNRest", nModif);
        // si on a des provisions (pass-DM) : Repos Immediat
        if (oProvisions != OBJECT_INVALID) { iRestDelay = RESTDELAY ; DestroyObject(oProvisions) ; } ;
        /* Checking the Resting Delay */
        if (iRestDelay < RESTDELAY)  {
            AssignCommand(oPC, ClearAllActions());
            if (RESTDELAY-iRestDelay <= 60) SendMessageToPC(oPC, "Vous devez attendre moins d'une minute pour vous reposez");
            else SendMessageToPC(oPC, "Vous devez attendre " + IntToString(FloatToInt(IntToFloat((RESTDELAY-iRestDelay))/60)) + " minute(s) avant de vous reposer a nouveau.");
            SetLocalInt(oPC, "PC_WARest", TRUE);
            return;
        }

// code TN Bouchon partie 2/2
        // Aliments pour manger, necessaire avant de se reposer.
        if( bRepas ){
            SendMessageToPC(oPC,"Vous mangez un peu... et faites une sieste réparatrice");
            oFood = GetItemPossessedBy(oPC, "alimentderepos1");
            DestroyObject(oFood);
            oFood = GetItemPossessedBy(oPC, "alimentderepos2");
            DestroyObject(oFood);
            oFood = GetItemPossessedBy(oPC, "alimentderepos3");
            DestroyObject(oFood);
        }
// code TN Bouchon partie 2/2

        /* Blindness Effect */
        effect eBlind = EffectBlindness();
        effect eDeaf = EffectDeaf();
        effect eVis = EffectVisualEffect(VFX_IMP_SLEEP);
        eBlind = ExtraordinaryEffect(eBlind);
        eDeaf =  ExtraordinaryEffect(eDeaf);
          // get nearest creature check proximity hostility etc.
          object oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
          if (iHostileRange == 0 || (iHostileRange != 0 && GetDistanceToObject(oCreature) <= IntToFloat(iHostileRange))) {
          // Initiate Resting, make a Gangus bedroll
              object oRestbedroll = CreateObject (OBJECT_TYPE_PLACEABLE, "sow_bedrolls", GetLocation (oPC), FALSE);
          // Autodestruction c'est mieux.
              SetPlotFlag(oRestbedroll, TRUE) ;
              DestroyObject(oRestbedroll, 120.0) ;
              SetLocalInt(oRestbedroll,"DC_FIND",d20(1));
              SetLocalInt(oRestbedroll,"PJ_RACE",GetRacialType(oPC));
              SetLocalInt(oRestbedroll,"PJ_SEXE",GetGender(oPC));
              SetLocalInt(oRestbedroll,"PJ_POIDS",GetWeight(oPC));
              SetLocalString(oRestbedroll,"PJ_NAME",GetName(oPC));
              // repos complet ?
              if( bRepas ) nCirc = 4 ; else nCirc = 0 ;
              nCirc += 3 ;
              SetLocalInt(oPC, "PC_FullRest", nCirc);  // par defaut
              int iAuSec = TRUE ; // par defaut
              int iAuChaud = TRUE ; // par defaut
              if( nSetting != 0 ){ // exemple desert de jour...
                // mettre a la variable "REPOS"
                // 1 - feu requis
                // 2 - tente/abri requis
                // 3 = 2 & 1 : les deux requis
                switch( nSetting ){
                    case 1: iAuChaud = FALSE ; break ;
                    case 2: iAuSec = FALSE ; break ;
                    case 3: iAuChaud = FALSE ; iAuSec = FALSE ; break ;
                    default: break;
                }
              }
              // preselection des zones hostiles
              // Au Sec ?
              if( (GetWeather(oArea) == WEATHER_RAIN) ||
                  (GetWeather(oArea) == WEATHER_SNOW) ){
                iAuSec = FALSE ;
                object oTente = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
                while (oTente != OBJECT_INVALID) {
                if ((GetTag(oTente)=="SOW_PLC_TENTE") ||
                    (GetTag(oTente)=="SOW_PLC_TENTEB") ){
                    iAuSec = TRUE ; break ; } ;
                    oTente = GetNextObjectInShape(SHAPE_SPHERE, 7.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
                }
              }
              // Au Chaud ?
              if( GetWeather(oArea) == WEATHER_SNOW ){ iAuChaud = FALSE ; }
              if( GetIsAreaNatural(oArea) && GetIsNight() ){ iAuChaud = FALSE ; }
              if( GetIsAreaNatural(oArea) && (GetIsAreaAboveGround(oArea) == AREA_UNDERGROUND) ){
                iAuChaud = FALSE ;
              }
              // Eviter de faire des loops inutiles...
              if( !iAuChaud ){
                object oFeuCamp = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
                while (oFeuCamp != OBJECT_INVALID) {
                    if( (GetTag(oFeuCamp)=="SOW_FEU_CAMP") ||
                      (GetTag(oFeuCamp)=="SOW_FEU_CUIS") ||
                      (GetTag(oFeuCamp)=="SOW_FEU_BROC") ||
                      (GetLevelByClass(CLASS_TYPE_SHADOWDANCER,oPC)>0) ){
                      iAuChaud = TRUE ; break ;
                    }
                    oFeuCamp = GetNextObjectInShape(SHAPE_SPHERE, 5.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
                }
              }
              //
              if( bRepas ) nCirc = 4 ; else nCirc = 0 ;
              if( iAuSec ) nCirc +=2 ;
              if( iAuChaud ) nCirc++ ;
              // nCirc = 4*bRepas + 2*iAuSec + iAuChaud ;
              // SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
              SetLocalInt(oPC, "PC_FullRest", nCirc);
              if( !iAuChaud ){
                if( sMessage1 == "" ) SendMessageToPC(oPC, "Il fait froid") ;
                else SendMessageToPC(oPC, sMessage1) ;
              }
              if( !iAuSec ){
                if( sMessage2 == "" ) SendMessageToPC(oPC, "Il fait humide") ;
                else SendMessageToPC(oPC, sMessage2) ;
              }
              if( !(iAuSec && iAuChaud) ){
                SendMessageToPC(oPC, "Vous dormez mal") ;
              }
              AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, oPC, 26.0));
              AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDeaf, oPC, 26.0));
              AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPC, 26.0));
          }
          else { // Enemy too close for resting
          AssignCommand (oPC, ClearAllActions());
          SendMessageToPC(oPC, "Des monstres sont proches, vous ne pouvez pas vous reposer");
          }
    }
    // Annulation du repos
    if (GetLastRestEventType() == REST_EVENTTYPE_REST_CANCELLED) {
        /* cancel blindness and eventually damage PC */
        DeleteLocalInt(oPC, "PC_CNRest");
        effect eBad = GetFirstEffect(oPC);
        while (GetIsEffectValid(eBad)) {
            if (GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS &&
                GetEffectCreator(eBad) == oPC) {
                RemoveEffect(oPC, eBad);
            }
            eBad = GetNextEffect(oPC);
        }
        /* cancel deaf and eventually damage PC */
        eBad = GetFirstEffect(oPC);
        while (GetIsEffectValid(eBad)) {
            if (GetEffectType(eBad) == EFFECT_TYPE_DEAF &&
                GetEffectCreator(eBad) == oPC) {
                RemoveEffect(oPC, eBad);
            }
            eBad = GetNextEffect(oPC);
        }
        /* cancel effects created by PCs */
        effect eGood = GetFirstEffect(oPC);
        int iPC_No_Wait = !GetLocalInt(oPC, "PC_WARest");
        DeleteLocalInt(oPC, "PC_WARest");            // correction repos intempestif
        while (GetIsEffectValid(eGood) && iPC_No_Wait) {  // enlevant les sorts de facon aggressive
          if (GetIsFriend(oPC, GetEffectCreator(eGood))) {
              RemoveEffect(oPC, eGood);
          }
        eGood = GetNextEffect(oPC);
        }
        iRestDelay = GetLocalInt(oPC, "PC_LastRest");
        if (iCTime < iRestDelay + 5) {
            // don't let players to cheat
            talent tFeat, tSpell;
            int  nIndex, i, nTalentID;
            for (nIndex=1; nIndex<1000; nIndex++) {
                tFeat  = TalentFeat (nIndex);
                tSpell = TalentSpell(nIndex);
                if (GetIsTalentValid(tFeat)) {
                    nTalentID = GetIdFromTalent(tFeat);
                    for (i=1; i<40; i++) {
                        DecrementRemainingFeatUses(oPC, nTalentID);
                        if (!GetHasFeat(nTalentID, oPC))  i = 40;
                    }
                }
                if (GetIsTalentValid(tSpell)) {
                    nTalentID = GetIdFromTalent(tSpell);
                    for (i=1; i<40; i++) {
                        DecrementRemainingSpellUses(oPC, nTalentID);
                        if (!GetHasSpell(nTalentID, oPC))  i = 40;
                    }
                }
            }
            // end cheating section
        }
        curHP = GetLocalInt(oPC, "PC_HPRest");
        maxHP = GetCurrentHitPoints(oPC);
        if (curHP >= maxHP)  return;
        effect eDamage = EffectDamage(maxHP-curHP, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC);
    // regeneration d'effets enleves par le repos
    // Gestion des objets a effets sur le PJ
    // => Les Bracelets d'AC ici
      SetLocalObject(oMod,"PJ_ITEFF",oPC) ;
      DeleteLocalObject(oMod,"OBJ_ITEFF") ; // rend invalide : le sc va chercher tout
      SignalEvent(oMod, EventUserDefined(550)) ;
    //
    }
    // Repos effectif
    if (GetLastRestEventType() == REST_EVENTTYPE_REST_FINISHED) {
        SetLocalInt(oPC, "PC_LastRest", iCTime);
        SetLocalInt(oPC, "PC_LastDayRest", iCDay);
        nModif = GetLocalInt(oPC, "PC_CNRest") + 3*GetHasFeat(FEAT_TOUGHNESS, oPC); // Constitution de debut de repos
        nModif += ( (GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC)>0) ||
                  (GetLevelByClass(CLASS_TYPE_DRUID, oPC)>0) ||
                  (GetLevelByClass(CLASS_TYPE_HARPER, oPC)>0) ||
                  (GetLevelByClass(CLASS_TYPE_RANGER, oPC)>0) ) ? 2 : 0 ;
        // metamorphe forcement druide
        DeleteLocalInt(oPC, "PC_CNRest");
        CleanDeathCard(oPC) ;
        CleanAgoCard(oPC) ;
        /* eventually damage PC */
        curHP = GetLocalInt(oPC, "PC_HPRest");
        maxHP = GetMaxHitPoints(oPC);
        int nLevel  = GetHitDice(oPC);
        int nHeal  = 0;
        if( curHP > maxHP ) curHP = maxHP ;
        int nDamage = maxHP-curHP ;
        // natural heal or damage
        nHeal  += (maxHP * (2 + nModif))/20 ;
        if( nDamage > nHeal) { nDamage = nDamage - nHeal ; nHeal=0; }
        else { nHeal = nHeal - nDamage ; nDamage = 0 ;}
        effect eDamage, eHeal ;
        if( nDamage > 0 ) eDamage = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
        // si on est dans de bonnes conditions : Full repos
        nCirc = GetLocalInt(oPC, "PC_FullRest") ;
        // SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
        if (nCirc >= 4) { // cf bRepas
          nHeal = maxHP-curHP ;
        } else if( nDamage >0 ) DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC));
        if (nHeal > 0) {
          eHeal = EffectHeal(nHeal);
          DelayCommand(1.0,ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC));
        }
        if( nCirc >= 4 ) nCirc -= 4 ; // bRepas gere, on passe a chaud/froid, sec/humide
        // SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
        if( nCirc < 3 ) {
          if (nCirc == 0) nDisease = Random(5) ; else nDisease = 5 + Random(5) ;
          DeleteLocalInt(oPC,"PC_FullRest");
          switch (nDisease) {
              case 0:
                sDisease = "La Croupissure tente de s'insinuer en vous" ;
                break;
              case 1:
                sDisease = "Les miasmes de la Fièvre Gloussante accompagne votre sommeil" ;
                break;
              case 2:
                sDisease = "Une Folie Parasitaire vous guette" ; nDisease = 16 ;
                break;
              case 3:
                sDisease = "Le froid et l'humidité amène la Tremblote du Soldat" ; nDisease = 15 ;
                break;
              case 4:
                sDisease = "Le Mal Rouge agrémente votre réveil" ; nDisease = 7 ;
                break;
              case 5:
                sDisease = "La Bouille-Crâne accompagne votre fin de nuit" ;
                break;
              case 6:
                sDisease = "Les miasmes environnant déclenche des Pustules Effroyables" ; nDisease = 13 ;
                break;
              case 7:
                sDisease = "La Fièvre des Marais est le risque du voyageur";  nDisease = 4 ;
                break;
              case 8:
                sDisease = "Auriez-vous attrapé la Tremblote ?" ;
                break;
              case 9:
                sDisease = "La Mort Vaseuse est une croupissure des plus communes" ;
                break;
              default:
                sDisease = "La Fièvre des Marais est le risque du voyageur";  nDisease = 4 ;
                break;
          }
          effect eBadSleep = EffectDisease(nDisease) ;
          effect eWanderer  = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, 2, SAVING_THROW_TYPE_DISEASE)) ;
          SendMessageToPC(oPC, sDisease);
          if( (GetLevelByClass(CLASS_TYPE_HARPER, oPC) +
              GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC) +
              GetLevelByClass(CLASS_TYPE_RANGER, oPC)) > 0 ) {
              ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWanderer, oPC, 3.0) ;
              }
          if( nSetDis !=0 ){ // malus de zone
              eWanderer  = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, nSetDis, SAVING_THROW_TYPE_DISEASE)) ;
              ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWanderer, oPC, 3.0) ;
          }
          ApplyEffectToObject(DURATION_TYPE_INSTANT, eBadSleep, oPC) ;
        }
//
        SendMessageToPC(oPC, "Vous restaurez "+IntToString(nHeal)+" points de vie.");
    // regeneration d'effets enleves par le repos
    // Gestion des objets a effets sur le PJ
    // => Les Bracelets d'AC ici
      SetLocalObject(oMod,"PJ_ITEFF",oPC) ;
      DeleteLocalObject(oMod,"OBJ_ITEFF") ; // rend invalide : le sc va chercher tout
      SignalEvent(oMod, EventUserDefined(550)) ;
    //
    }
}
Le code a colorer syntaxiquement est trop long (plus de 10240 caractères) et risque de ne pas s'afficher du tout. Vous pouvez le voir en version colorée ici.


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 :

//:: ly_lib_time.nss
int ly_day()
{
    int iCTY = GetCalendarYear() ;
    int iCTM = GetCalendarMonth() ;
    int iCTD = GetCalendarDay() ;
    int iCDay = iCTY*12*28 + iCTM*28 + iCTD ;
    return iCDay ;
}

int ly_time()
{
    // Bug Minutes &amp; Secondes ...
    // 3 minutes/heures =&gt; 1h RP &lt;=&gt; 180 sec IRL
    int iTH = GetTimeHour();
    int iTM = GetTimeMinute();
    int iTS = GetTimeSecond();
    int iCTime = FloatToInt(HoursToSeconds(iTH)) + iTM*60 + iTS ;
    return iCTime ;
}

void ly_grant_rest(object oPC)
{
//
// Init du repos et mort
    SetLocalInt(oPC, "PC_LastRest", ly_time()-540);
    SetLocalInt(oPC, "PC_LastDayRest", ly_day());
    SetLocalInt(oPC, "DyingHP", -1);
    SendMessageToPC(oPC, "Vous pouvez vous reposer pour recuperer." ) ;
}

void ly_anti_deco(object oPC) {
  if (!GetIsDM (oPC)) {
  // don't let players to cheat deco/reco
      talent tFeat, tSpell;
      int nIndex, i, nTalentID;
      for (nIndex=1; nIndex<1000; nIndex++) {
        tFeat = TalentFeat (nIndex);
        tSpell = TalentSpell(nIndex);
        if (GetIsTalentValid(tFeat)) {
            nTalentID = GetIdFromTalent(tFeat);
            for (i=1; i<40; i++) {
              DecrementRemainingFeatUses(oPC, nTalentID);
              if (!GetHasFeat(nTalentID, oPC)) i = 40;
            }
        }
        if (GetIsTalentValid(tSpell)) {
            nTalentID = GetIdFromTalent(tSpell);
            for (i=1; i<40; i++) {
              DecrementRemainingSpellUses(oPC, nTalentID);
              if (!GetHasSpell(nTalentID, oPC)) i = 40;
            }
        }
      }
      SendMessageToPC(oPC, "Sorts et Dons desactives : vous devez vous reposez pour recuperer." ) ;
  // end cheating section
  }
}

// void main() {}
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.


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 :

//:: ly_lib_death.nss

void CleanDeathCard(object oDead) { // wrapper
// Gestion des cartes de mort
  if( GetItemPossessedBy(oDead, "mortNODROP") != OBJECT_INVALID ){
      MustHaveNoItem(oDead,"mortNODROP");
  }
}
// end carte mort

void CleanAgoCard(object oDead) {
// Gestion des cartes d'agonie
  if( GetItemPossessedBy(oDead, "agoNODROP") != OBJECT_INVALID ){
      MustHaveNoItem(oDead,"agoNODROP");
  }
}
// end carte agonie

void GiveDeathCard(object oPC) {
  // donne une carte de mort pour la deco et une variable d'etat
  string sCarte = "mortNODROP", sRef = "mortnodrop" ;
  if( GetItemPossessedBy(oPC, sCarte) == OBJECT_INVALID )
      CreateItemOnObject(sRef, oPC, 1);
}

void GiveAgoCard(object oPC) {
  // donne une carte d'agonie pour la deco et une variable d'etat
  string sCarte = "agoNODROP", sRef = "agonodrop" ;
  if( GetItemPossessedBy(oPC, sCarte) == OBJECT_INVALID )
      CreateItemOnObject(sRef, oPC, 1);
}

int ChkDeathCard(object oPC) {
// Gestion des cartes de mort
  int nCard = 0 ;
  if( GetItemPossessedBy(oPC, "mortNODROP") != OBJECT_INVALID ){
      nCard = MustHaveNoItem(oPC,"mortNODROP");
  }
  if( nCard>0 ) ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectDeath(),oPC);
// end carte mort
  return nCard ;
}

int ChkAgoCard(object oPC) {
// Gestion des cartes d'agonie
  int nCard = 0 ;
  if( GetItemPossessedBy(oPC, "agoNODROP") != OBJECT_INVALID ){
      nCard = MustHaveNoItem(oPC,"agoNODROP");
  }
  if( nCard>0 ){
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectMovementSpeedDecrease(75),oPC,60.0);
  ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAbilityDecrease(ABILITY_CONSTITUTION, 1),oPC);
  }
// end carte agonie
  return nCard ;
}

void ChkAgoSpeed(object oPC) {
// Gestion des cartes d'agonie
  if( GetItemPossessedBy(oPC, "agoNODROP") != OBJECT_INVALID ){
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY,EffectMovementSpeedDecrease(75),oPC,60.0);
  }
// end carte agonie
}

// void main(){}
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.


Edit : *se relit et voit que ce script contient encore des choses pas purgées ... la vache Wheel of Time ca me rajeunit pas*
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Montrer les messages depuis :
Page 1 sur 1 ¤


Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Sauter vers:
FAQ | Rechercher | Liste des Membres | Groupes d'utilisateurs | S'enregistrer | Profil | Se connecter pour vérifier ses messages privés | Connexion
Powered by phpBB 2.* [m] © 2001, 2002 phpBB Group
Theme rewritten in beautiful XHTML code by Baldurien.
Thème "La Bibliothèque de Neverwinter" crée par Kruger
Traduction par : phpBB-fr.com
Page generated in 96.232ms