Répartition d'XP sur un monstre tué

Répondre
Partager Rechercher
Voici 2 scripts permettant une autre façon de gérer le gain d'expérience lorsqu'une créature est tuée. Voici les ajouts que ces scripts proposent:

- Le PJ ayant achevé le monstre ne sera plus le seul à recevoir l'XP du monstre, mais l'XP sera réparti entre tous les personnages ayant endommagé le monstre, et ce proportionnellement aux dégats infligés.
- L'XP sera également divisé entre les membres d'un même groupe, tout en accordant un bonus proportionnel au nombre de membres dans ce groupe (plus vous serez, plus le bonus sera important).
- L'XP ne sera accordé que si le PJ se trouve dans la même zone que le monstre tué.
- La quantité d'XP gagné selon le CR du monstre peut être réglé en modifiant simplement la donné d'une variable en début de script. (Augmenter la valeur pour gagner plus, diminuer pour gagner moins).
- Les MD sont avertis de la mort d'une créature, de son meurtrier, et de l'endroit de la mort. (Vous pouvez le désactiver)

Voici le premier script, à placer au tout début de la fonction Main du script OnDamaged de la créature (nw_c2_default6 par défaut):
Code PHP:

    object oDamager GetLastDamager();
    
int nDamage GetTotalDamageDealt();
    
string sTag GetTag(OBJECT_SELF);
    
string sLeech "Leech_" sTag;
    
int nBlessure GetLocalInt(oDamagersLeech);
    
int nLeech nDamage nBlessure;
    
SetLocalInt(oDamagersLeechnLeech); 
Voici le second script, à placer dans le OnDeath de la créature (nw_c2_default7 par défaut):
Code PHP:

#include "NW_I0_GENERIC"

//Vous pouvez changer la valeur de nBaseXP selon votre echelle; 100=DMG.
int nBaseXP 100;

//Fonction d'xp du PJ achevant le monstre
void XPBinote(object oPCint nLastDamageint nBaseXP)
{
 
string sTag GetTag(OBJECT_SELF);
 
string sLeech "Leech_" sTag;
 
float fCR GetChallengeRating(OBJECT_SELF);
 
int nMaxHP GetMaxHitPoints(OBJECT_SELF);
 
float fMaxHP IntToFloat(nMaxHP);
 
int nLeech GetLocalInt(oPCsLeech);
 
nLeech nLeech nLastDamage;
   
float fLeech IntToFloat(nLeech);
   
float fDmg fLeech fMaxHP;
   
float fXP = (fCR fDmg)* nBaseXP;
   
int nXP FloatToInt(fXP);
   
SendMessageToPC(oPC"Vous gagnez " IntToString(nXP) + " points d'experience.");
   
GiveXPToCreature(oPCnXP);
   
DeleteLocalInt(oPCsLeech);
}

//Fonction d'xp des autres PJ faisant partie du groupe du PJ ayant acheve le monstre
void XPPartyBinote(object oKillerobject oAreaint nBaseXP)
{
    
int nMembres 0;
    
object oMembreGroupe GetFirstFactionMember(oKillerTRUE);
    while (
GetIsObjectValid(oMembreGroupe) == TRUE)
    {
     
object oAreaGroupe GetArea(oMembreGroupe);
     if(
oArea == oAreaGroupe)
     {
      
nMembres nMembres 1;
     }
     
oMembreGroupe GetNextFactionMember(oKillerTRUE);
    }
    
float fCR GetChallengeRating(OBJECT_SELF);
    
float fCompteur IntToFloat(nMembres);
    
//Bonus d'xp accorde aux PJ jouant en groupe.
    //Si vous ne voulez pas favoriser cela, mettez cette ligne:
    //float fMultiplier = 1.0;
    
float fMultiplier = (1.0 + ((0.1 fCompteur) - 0.1));
    
float fXP = ((fCR fMultiplier) / fCompteur);
    
string sTag GetTag(OBJECT_SELF);
    
string sLeech "Leech_" sTag;
    
int nMaxHP GetMaxHitPoints(OBJECT_SELF);
    
float fMaxHP IntToFloat(nMaxHP);
    while (
GetIsObjectValid(oMembreGroupe) == TRUE)
    {
     
object oAreaGroupe GetArea(oMembreGroupe);
     if(
GetIsPC(oMembreGroupe) == TRUE && oArea == oAreaGroupe && GetCurrentHitPoints(oMembreGroupe) > 0)
     {
      
int nLeech GetLocalInt(oMembreGroupesLeech);
      
float fLeech IntToFloat(nLeech);
      
float fDmg fLeech fMaxHP;
      
float fXPReel = (fXP fDmg)* nBaseXP;
      
int nXP FloatToInt(fXPReel);
      
SendMessageToPC(oMembreGroupe"Vous gagnez " IntToString(nXP) + " points d'experience.");
      
GiveXPToCreature(oMembreGroupenXP);
      
DeleteLocalInt(oMembreGroupesLeech);
     }
     
oMembreGroupe GetNextFactionMember(oKillerTRUE);
    }
}

//Fonction d'xp des autres PJ ayant touche le monstre
void XPLeechBinote(object oAreaint nBaseXP)
{
    
object oLeecheur GetFirstPC();
    
float fCR GetChallengeRating(OBJECT_SELF);
    
string sTag GetTag(OBJECT_SELF);
    
string sLeech "Leech_" sTag;
    
int nMaxHP GetMaxHitPoints(OBJECT_SELF);
    
float fMaxHP IntToFloat(nMaxHP);
    while (
GetIsObjectValid(oLeecheur) == TRUE)
    {
     
object oAreaLeech GetArea(oLeecheur);
     if(
GetIsPC(oLeecheur) == TRUE && oArea == oAreaLeech && GetCurrentHitPoints(oLeecheur) > 0)
     {
      
int nLeech GetLocalInt(oLeecheursLeech);
      
float fLeech IntToFloat(nLeech);
      
float fDmg fLeech fMaxHP;
      
float fXPReel = (fCR fDmg)* nBaseXP;
      
int nXP FloatToInt(fXPReel);
      
SendMessageToPC(oLeecheur"Vous gagnez " IntToString(nXP) + " points d'experience.");
      
GiveXPToCreature(oLeecheurnXP);
      
DeleteLocalInt(oLeecheursLeech);
     }
     
oLeecheur GetNextPC();
    }
}

void main()
{
    
int nClass GetLevelByClass(CLASS_TYPE_COMMONER);
    
int nAlign GetAlignmentGoodEvil(OBJECT_SELF);
    
int nCoupMortel GetTotalDamageDealt();
    
object oKiller GetLastKiller();
    
object oArea GetArea(OBJECT_SELF);
    
string sArea GetTag(oArea);
    
string sNom GetName(OBJECT_SELF);
    
string sKiller GetName(oKiller);
    if(
nClass && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
    {
        
AdjustAlignment(oKillerALIGNMENT_EVIL5);
    }
    
//Message d'avertissement aux MDs. Mettez // devant la ligne si vous ne voulez pas avoir cette option.
    
SendMessageToAllDMs(sNom " vient d'etre tue par " sKiller " dans " sArea);
    if(
GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
        
SignalEvent(OBJECT_SELFEventUserDefined(1007));
    }
    
XPBinote(oKillernCoupMortelnBaseXP);
    
XPPartyBinote(oKilleroAreanBaseXP);
    
XPLeechBinote(oAreanBaseXP);

J'ai cependant plusieurs interrogations que je n'ai pas encore résolu:
- Si le personnage frappe plusieurs monstres possédant le même TAG, il va y avoir une soupe dans les variables Leech à mon avis.
- Si le monstre est soigné et que le "leech" dépasse le total maximum des PV du monstre, le gain d'xp sera erroné.
une idée en l'air comme ça serait d'associer à chaque monstre une clé incrémentée à chaque spawn de monstre et donc normalement unique pour chaque.
Un entier stockée au niveau du module ou dans chaque zone (ca dépend comment tu définis ta clé, si c'est juste un entier ou la concaténation du nom de la zone, du type de la créature et de l'entier ...).

Pour les soins, faudrait récupérer le total des dégâts fait et après faire des pourcentages de dégats ... non ?
Pour les PV je viens de le dire dans ton autre post, j'avais pas vu celui-la. Effectivement il va falloir que tu additionnes tous les degats faits aux monstres, sinon tu risques de retrouver des gens tapant des trolls en etant semi-afk.

Pour le problème de tag, effectivement ca va poser des problèmes dès lors qu'il y aura plusieurs monstres du meme type. Essaye de stocker ca sur le monstre, mais je suis pas sur que tu pourras le récupérer dans le OnDeath...
Au pire tu peux tjs rajouter un nombre aleatoire dans le nom de ton LocalInt, et vérifier s'il n'existe pas déjà un LocalInt portant ce nom.
En prenant ma douche j'ai pensé à quelques trucs:

- Mon script tel qu'il est là donne 3x des XP au PJ qui a tué le monstre. (Il est PJ, il est membre de son propre groupe, il est le meurtrier). Le script peut très bien rester comme cela, si on considère que faire partie d'un groupe et qu'achever le monstre apporte un bonus.
Afin de rendre le code flexible, il suffit alors de déclarer 3 nBaseXP au début du script: un pour le meurtrier, un pour le groupe, un pour les joueurs ayant touché le monstre. Avec une valeur +/- haute selon l'importance qu'on veut accorder à ces xp, et avec la mention: "Vous gagnez xxx XP de bonus de groupe." par exemple.

- Remplacer nMaxHP par nTotalLeech, ce qui devrait résoudre le problème de "soins" du monstre et du nombre de leech dépassant les MaxHP du monstre. nTotalLeech serait égal à la somme des nLeech de tous les PJ du module sur le TAG du monstre tué.

-Pour le TAG je pense avoir trouvé, on ajoute la Location de mort du monstre au TAG, comme ça, sur de ne pas avoir 2 fois le même.

Je vais modifier mon code avec ces petites idées, dites moi ce que vous en pensez, et merci pour vos remarques.
Citation :
Provient du message de puchiko
et il se passe quoi si le PC tueur n'est pas membre d'un groupe alors que les PC d'un autre groupe ont contribué à tuer le monstre ?
Ils sont traités a part, ca pose pas de problème ca.

Delphinéa, ton coup de la location, bof, vu que tu commences a stocker avant la mort du monstre, je suis pas sur que ca soit très efficace, je pencherai plutot pour ajouter un nombre aleatoire au nom du localInt, avec un ptit test pour vérifier que ca existe pas déjà.
Oui en effet, le coup de la location c'est très bof, vu que entre chaque coup reçu, le monstre risque de bouger pas mal

Je pense que je vais adopter ton idée Zunder, merci
Mise à jour du script
***Mise à jour des scripts***

- Problème de TAG identique entre les monstres résolu.
J'ai résolu ça en m'inspirant de l'idée de Zunder, de la façon suivante:
Dans le OnDamaged, lorsque le monstre se prend le premier coup depuis son respawn, un "tag générique" lui est attribué et est ensuite sauvegardé sur le monstre (LocalString). De cette façon, il est aisément récupérable à n'importe quel endroit d'un des deux scripts. Le tag générique se voit attribué une valeur aléatoire entre 0 et 65534, ce qui est largement suffisant.
- Problème d'XP multiple résolu.
Maintenant le script OnDeath comporte 3 variables configurables en début de script, permettant de régler le % d'xp supplémentaire accordé.
- Problème du Max de PV résolu.
Remplacement du "GetMaxHitPoints" par une variable stockée sur le monstre, reprenant les dégats totaux qu'il a reçu.

***Ajouts***

- Fonction Tableau de Chasse, permettant de comptabiliser le nombre de créatures tuées par chaque joueur et de l'afficher à chaque fois que le PJ achève une créature.

- Fonction Réputation de Faction, permettant à chaque PJ tuant une créature, de voir ses relations avec la faction de la créature se déteriorer, voir carrément devenir hostile si la créature tuée était le leader de la faction (voir un membre puissant).
Vous pouvez régler la pénalité de réputation en début de script, via la variable "nReput".

//Voici le premier script, à placer au tout début de la fonction Main du script OnDamaged de la créature (nw_c2_default6 par défaut):

Code PHP:

    object oDamager GetLastDamager();
    
int nDamage GetTotalDamageDealt();
    
int nCoup GetLocalInt(OBJECT_SELF"Coup");
    
string sLeech;
    if (
nCoup == 0)
    {
     
string sTag GetTag(OBJECT_SELF);
     
int nID Random(65534);
     
string sID IntToString(nID);
     
sLeech "Leech_" sTag sID;
    }
    else
    {
     
sLeech GetLocalString(OBJECT_SELF"TagLeech");
    }
    
SetLocalString(OBJECT_SELF"TagLeech"sLeech);
    
int nBlessure GetLocalInt(oDamagersLeech);
    
int nTotBless GetLocalInt(OBJECT_SELF"TotalLeech");
    
int nLeech nDamage nBlessure;
    
int nTotalLeech nDamage nTotBless;
    
SetLocalInt(oDamagersLeechnLeech);
    
SetLocalInt(OBJECT_SELF"TotalLeech"nTotalLeech);
    
int nFCoup nCoup 1;
    
SetLocalInt(OBJECT_SELF"Coup"nFCoup); 
//Voici le second script, à placer dans le OnDeath de la créature (nw_c2_default7 par défaut):

Code PHP:

#include "NW_I0_GENERIC"

//Vous pouvez changer la valeur de nBaseXP selon votre echelle; 100=DMG.
int nBaseXP 100;
int nBonusXPGroupe 25;
int nBonusXPTueur 5;
//Changement de la Reputation de base lors d'un meurtre
int nReput = -5;

//Ne changez rien ci-dessus, sauf si vous savez ce que vous faites ;)

//Fonction d'xp du PJ achevant le monstre
void XPBinote(object oKillerint nBonusXPTueur)
{
 
float fCR GetChallengeRating(OBJECT_SELF);
 
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
 
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
 
int nLeech GetLocalInt(oKillersLeech);
 if(
sLeech == "")
 {
  
nMaxHP GetMaxHitPoints(OBJECT_SELF);
  
nLeech nMaxHP;
 }
  
float fMaxHP IntToFloat(nMaxHP);
  
float fLeech IntToFloat(nLeech);
  
float fDmg fLeech fMaxHP;
  
float fXP = (fCR fDmg)* nBonusXPTueur;
  
int nXP FloatToInt(fXP);
  
SendMessageToPC(oKiller"Vous gagnez " IntToString(nXP) + " points d'experience de Bonus.");
  
GiveXPToCreature(oKillernXP);
}

//Fonction d'xp des autres PJ faisant partie du groupe du PJ ayant acheve le monstre
void XPPartyBinote(object oKillerobject oAreaint nBonusXPGroupe)
{
     
int nMembres 0;
     
object oMembreGroupe GetFirstFactionMember(oKillerTRUE);
     while (
GetIsObjectValid(oMembreGroupe) == TRUE)
     {
      
object oAreaGroupe GetArea(oMembreGroupe);
      if(
oArea == oAreaGroupe)
      {
       
nMembres nMembres 1;
      }
      
oMembreGroupe GetNextFactionMember(oKillerTRUE);
     }
     
float fCR GetChallengeRating(OBJECT_SELF);
     
float fCompteur IntToFloat(nMembres);
     
//Bonus d'xp accorde aux PJ jouant en groupe.
     //Si vous ne voulez pas favoriser cela, mettez cette ligne:
     //float fMultiplier = 1.0;
     
float fMultiplier = (1.0 + ((0.1 fCompteur) - 0.1));
     
float fXP = ((fCR fMultiplier) / fCompteur);
     
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
     
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
     while (
GetIsObjectValid(oMembreGroupe) == TRUE)
     {
      
object oAreaGroupe GetArea(oMembreGroupe);
      if(
GetIsPC(oMembreGroupe) == TRUE && oArea == oAreaGroupe && GetCurrentHitPoints(oMembreGroupe) > 0)
      {
       
int nLeech GetLocalInt(oMembreGroupesLeech);
       if(
sLeech == "")
       {
        
nMaxHP GetMaxHitPoints(OBJECT_SELF);
        
nLeech nMaxHP;
       }
       
float fMaxHP IntToFloat(nMaxHP);
       
float fLeech IntToFloat(nLeech);
       
float fDmg fLeech fMaxHP;
       
float fXPReel = (fXP fDmg)* nBonusXPGroupe;
       
int nXP FloatToInt(fXPReel);
       
SendMessageToPC(oMembreGroupe"Vous gagnez " IntToString(nXP) + " points d'experience de Bonus de Groupe.");
       
GiveXPToCreature(oMembreGroupenXP);
      }
      
oMembreGroupe GetNextFactionMember(oKillerTRUE);
     }
}

//Fonction d'xp des autres PJ ayant touche le monstre
void XPLeechBinote(object oAreaint nBaseXP)
{
    
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
    if(
sLeech == "")
    {
     return;
    }
    else
    {
     
object oLeecheur GetFirstPC();
     
float fCR GetChallengeRating(OBJECT_SELF);
     
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
     
float fMaxHP IntToFloat(nMaxHP);
     while (
GetIsObjectValid(oLeecheur) == TRUE)
     {
      
object oAreaLeech GetArea(oLeecheur);
      if(
oArea == oAreaLeech && GetCurrentHitPoints(oLeecheur) > 0)
      {
       
int nLeech GetLocalInt(oLeecheursLeech);
       
float fLeech IntToFloat(nLeech);
       
float fDmg fLeech fMaxHP;
       
float fXPReel = (fCR fDmg)* nBaseXP;
       
int nXP FloatToInt(fXPReel);
       
SendMessageToPC(oLeecheur"Vous gagnez " IntToString(nXP) + " points d'experience.");
       
GiveXPToCreature(oLeecheurnXP);
       
DeleteLocalInt(oLeecheursLeech);
      }
      
oLeecheur GetNextPC();
     }
    }
}

//Tableau de Chasse du Joueur
void KillBoard(object oKillerstring sNom)
{
    
int nKills GetLocalInt(oKillersNom);
    
nKills += 1;
    
SetLocalInt(oKillersNomnKills);
    
string sKills IntToString(nKills);
    
SendMessageToPC(oKiller"Vous venez de tuer " sNom "; ceci est votre " sKills "e !");
}

//Ajustement de la Faction lors d'un meurtre
void AdjustFaction (object oKillerint nReput)
{
    
object oLeader GetFactionLeader(OBJECT_SELF);
    
object oGrosBill GetFactionStrongestMember(OBJECT_SELF);
    
string sFaction GetName(oLeader);
    if(
oLeader == OBJECT_SELF)
    {
     
nReput nReput 20;
    }
    else if(
oGrosBill == OBJECT_SELF)
    {
     
nReput nReput 10;
    }
    
AdjustReputation(oKillerOBJECT_SELFnReput);
    
SendMessageToPC(oKiller"Votre reputation vis-a-vis de la faction de " sFaction " s'est deterioree!");
}

void main()
{
    
int nClass GetLevelByClass(CLASS_TYPE_COMMONER);
    
int nAlign GetAlignmentGoodEvil(OBJECT_SELF);
    
object oKiller GetLastKiller();
    
object oArea GetArea(OBJECT_SELF);
    
string sArea GetTag(oArea);
    
string sNom GetName(OBJECT_SELF);
    
string sKiller GetName(oKiller);
    if(
nClass && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
    {
        
AdjustAlignment(oKillerALIGNMENT_EVIL5);
    }
    
//Message d'avertissement aux MDs. Mettez // devant la ligne si vous ne voulez pas avoir cette option.
    
SendMessageToAllDMs(sNom " vient d'etre tue par " sKiller " dans " sArea);
    
//Bonus XP Tueur
    
XPBinote(oKillernBonusXPTueur);
    
//Bonus XP Groupe
    
XPPartyBinote(oKilleroAreanBonusXPGroupe);
    
//XP (mettez bien l'echelle d'xp sur 0 dans les proprietes du module)
    
XPLeechBinote(oAreanBaseXP);
    
//Tableau de Chasse
    
KillBoard(oKillersNom);
    
//Ajustement de la Faction
    
AdjustFaction (oKillernReput);
    
//Effacement des variables locales du monstre
    
DeleteLocalInt(OBJECT_SELF"TotalLeech");
    
DeleteLocalInt(OBJECT_SELF"Coup");
    
DeleteLocalString(OBJECT_SELF"TagLeech");

    if(
GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
        
SignalEvent(OBJECT_SELFEventUserDefined(1007));
    }

J'ai édité les scripts ci-dessus pour des erreurs mathématiques, car je divisais au lieu de multiplier, ce qui faisait qu'on gagnait plus quand on devait gagner moins; j'ai honte

***De plus, en testant tout ça, j'ai remarqué quelques trucs:

- Si vous tuez le monstre en un coup, le script OnDamaged ne se déclenche pas, le OnDeath est directement lancé, ce qui donnait un joli 0 dans la division, et occasionnait une belle erreur
J'ai corrigé cela en vérifiant que si le TagLeech n'a pas été attribué à la créature (donc si elle meurt sans jamais avoir été blessée auparavant), celui qui l'a tué est censé lui avoir fait tous ses PV et donc récolte tout l'xp.

- Les lignes "SendMessageToPC" ne sont pas indispensables pour annoncer le gain d'xp sauf si on veut que le joueur soit averti de la nature du bonus. Car la fonction "GiveXpToCreature" retourne obligatoirement un "SendMessageToPC" au joueur qui reçoit les XP, donc ça fait un peu double emploi.

***Quelques points à améliorer:

- L'xp attribué est fixe selon le CR et ne varie pas selon le niveau du personnage vis à vis du CR (comme c'est censé le faire à D&D). Je vais réaliser une version plus proche de cela mais en gardant les XP de % des dégats faits au monstre ainsi que les XP de groupe. (Bioware se contente de diviser par le nombre de membres du groupe selon le CR Total tout en omettant si ceux-ci ont participé ou sont dans la zone....)

- Vu que ce script est placé dans le OnDeath, il faut absolument que la partie XP ne se déclenche que si le Tueur est un PC, ou alors si le PC a fait le plus gros % de dégats par rapport aux PNJ/Monstres ayant participé, etc....

- Inclure un bonus de rareté d'après le tableau de chasse. Plus le PJ tuera des créatures similaires, moins il gagnera d'xp sur les suivantes. Par contre il aura un bonus s'il s'agit de la première qu'il tue.

- Permettre au PJ/MD de consulter son Tableau de Chasse via un objet.

- Permettre au MD de visualiser les réputations de tel ou tel PJ vis à vis de toutes les factions. (Pour le PJ je ne sais pas encore si je vais le faire, ça me parait un peu trop facile pour lui ce truc )

- Ajouter des phrases d'ambiance pour les combats lorsque le monstre ou le PJ reçoivent des coups. Par exemple, si le PJ fait un "Oneshot", une phrase du genre: "Votre adversaire explose littéralement sous votre coup ravageur, des morceaux s'éparpillant partout aux alentours!"
Dans le même ordre d'idée selon le % de PV enlevé par un coup, des phrases plus ou moins drôles et bien sur des "VOICE"


Enfin voilà, si vous avez des idées n'hésitez pas
Si je veux donner un nombre de point d'expérience définie et non utilisé le pourcentage, quand le Pj tue une créature comment doi je faire en utilisant aussi ce script merveilleux ? Je sai c une question assez basique mais je ssuis pas trop doué pour les script.
__________________
http://soiretoile.chez-alice.fr/Artisans/SignatureAzoun.jpg
Si tu veux que seul le personnage qui donne le coup final reçoive la totalité des xp, tu n'utilises pas ce script, Bioware le fait déjà
Nan pas exactement, je veu que tout ceux qui l'on touché puisse gagné de l'xp mais que le nombre d'xp donné soit choisi par moi seul et non pas en fonction du CR du monstre et de la créature.
En bref que le blaireau vale 1 px par exemple.
Y'a quelque probleme avec ton script :
- un monstre avec peu de px, ne rapportera rien au tueur, car le nombre de px donné ne sera pas divisible.
- un monstre tué avec un sort ou un renvoi des mort vivant ne donne pas de bonus au tueur et ne compte pas comme créature tué dans le tableau de chasse. Seul le message "px gagné.." s'affiche.

Sinon je fais comment le script pour donné des px quand un Pj tu un monstre ?
Que le tueur ne reçoive rien si le monstre est trop faible, c'est un peu normal. Il n'y a aucune expérience à tirer du fait d'être celui qui a achevé le rat qui envahissait la cave de marie la fermière

Si tu veux attribuer un nombre fixe d'xp à un monstre, je ne vois qu'une solution:

Créer une fonction qui renvoit la valeur de fCR en début de mon script, cette fonction vérifiant le TAG de toutes les créatures peuplant ton module (un CASE gigantesque en fait, mais le problème est que le CASE ne compare que les entiers... donc viva la série d'else if, bonjours la galère....) et retournant la valeur fCR appropriée. Exemple:

Code PHP:

float XPFixe(string sTag)
{
 if (
sTag == "NW_BADGER")
 {
   return 
1.0;
 }
 else if (
sTag == "NW_GOBLINA")
 {
   return 
5.0
 
}
 else if (
sTag == "NW_SPIDER")
 {
   return 
15.0
 
}
}
//etc, etc, continue la liste si ça t'amuse :D 
Et à chaque fois qu'on demande la valeur fCR, tu mets cette ligne:

Code PHP:

float fCR XPFixe(GetTag(OBJECT_SELF)); 


Si tu veux mon avis, tu te compliques la vie en voulant faire ça, et surtout à chaque fois que tu vas ajouter une créature à ton module, tu devras ajouter une ligne à la fonction, alors que Bioware te propose un système tout fait

Le plus simple est de modifier le CR de la créature dans l'éditeur de façon à ce que les XP correspondent à ce que tu veux, franchement c'est 1000 fois plus simple et plus pratique.
Je ne comprend pas tout
Ca serai possible de détailé le script employé ?
Et ou on le met exactement
Et dasn ce cas la ou est ce que l'on donne la valeur en px que l'on veut attribuer lors du meurtre de la créature ?
Merci
Excuse moi de t'ennuyer je sais que ta pas mal d boulot Nek, mai si j'inclus les lignes que tu me dit, es ce que cela prendra beaucoup de ressource ?
Sinon, dans cette ligne:
Code PHP:

if (sTag == "NW_BADGER")
 {
   return 
1.0;
 } 
Ou sont inscrit le nombre de px donné au joueur. Et comment je es ce que j'inclus les nouvelle donné ?

Merci
Ce genre de script ne pose pas de problème point de vue "ressources" ne t'en fait pas

Le chiffre représentant les xp est dans ce cas ci: 1.0 (qui veut dire 1 XP )

Si tu veux ajouter un monstre, tu dois avoir 2 données à ta disposition:

- Son TAG
- Les XP que tu veux lui attribuer.

Ensuite tu ajoutes la même ligne que les autres mais en changeant le TAG entre " " par le nouveau, et en changeant le chiffre avec décimale (important) par celui que tu désires.

Par exemple, ajouter une Dracoliche qui comporte le TAG: DRACOLICHE à qui tu veux donner 25000 XP, ça donnerait ceci:

Code PHP:

else if (sTag == "DRACOLICHE")
 {
   return 
25000.0
 


PS: Mais je te déconseille tout de même cette méthode qui est fastidieuse à mettre en place et pas très souple d'emploi.
Utilise plutot mon script complet et donne une valeur entre 1 et 5 à nBaseXP, tu en seras plus content
Mise à jour des scripts
Comme prévu, voici une nouvelle version de ces scripts, comprenant entre autre:

- Bonus de rareté (plus vous tuez le même monstre, moins il vous rapporte).
- Phrases de combat (selon le coup que vous portez, des phrases et des voix d'animations surviennent durant la bataille).
- Meilleure structure du script, réécriture de certaines fonctions.

Code PHP:

//::///////////////////////////////////////////////
//:: Default On Damaged
//:: NW_C2_DEFAULT6
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    If already fighting then ignore, else determine
    combat round
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//:: Modifier By: Binote
//:://////////////////////////////////////////////

#include "NW_I0_GENERIC"

void VoiceFighting(object oDamagerint nDamage)
{
    
float fMaxHP IntToFloat(GetMaxHitPoints(OBJECT_SELF));
    
float fDamage IntToFloat(nDamage);
    
int nAlignBM GetAlignmentGoodEvil(oDamager);
    
float fViolence fDamage/fMaxHP;
    
string sMonine;
    if(
fViolence >= 0.9)
    {
     
sMonine "Votre attaque envoit votre adversaire aux portes de la mort.";
     
PlayVoiceChat(VOICE_CHAT_NEARDEATHOBJECT_SELF);
     if(
nAlignBM == ALIGNMENT_EVIL)
     {
      
PlayVoiceChat(VOICE_CHAT_LAUGHoDamager);
     }
    }
    else if(
fViolence >= 0.8)
    {
     
sMonine "Votre adversaire se demande encore ce qu'il lui est arrive.";
     
PlayVoiceChat(VOICE_CHAT_PAIN3OBJECT_SELF);
    }
    else if(
fViolence >= 0.7)
    {
     
sMonine "Votre adversaire ne peut que constater les degats de votre attaque.";
     
PlayVoiceChat(VOICE_CHAT_PAIN2OBJECT_SELF);
    }
    else if(
fViolence >= 0.6)
    {
     
sMonine "Votre adversaire ne peut contenir la violence de votre attaque.";
     
PlayVoiceChat(VOICE_CHAT_PAIN1OBJECT_SELF);
    }
    else if(
fViolence >= 0.5)
    {
     
sMonine "Votre adversaire a du mal a encaisser la violence de votre attaque.";
     
PlayVoiceChat(VOICE_CHAT_BATTLECRY1OBJECT_SELF);
    }
    else if(
fViolence <= 0.1)
    {
     
sMonine "Votre ridicule petite attaque fait peu d'effet sur votre adversaire.";
     
PlayVoiceChat(VOICE_CHAT_LAUGHOBJECT_SELF);
     
PlayVoiceChat(VOICE_CHAT_WEAPONSUCKSoDamager);
    }
    else
    {
    }
    
FloatingTextStringOnCreature(sMonineoDamagerTRUE);
}

void main()
{
    
object oDamager GetLastDamager();
    
int nDamage GetTotalDamageDealt();
    
int nCoup GetLocalInt(OBJECT_SELF"Coup");
    
string sLeech;
    if (
nCoup == 0)
    {
     
string sTag GetTag(OBJECT_SELF);
     
int nID Random(65534);
     
string sID IntToString(nID);
     
sLeech "Leech_" sTag sID;
    }
    else
    {
     
sLeech GetLocalString(OBJECT_SELF"TagLeech");
    }
    
SetLocalString(OBJECT_SELF"TagLeech"sLeech);
    
int nBlessure GetLocalInt(oDamagersLeech);
    
int nTotBless GetLocalInt(OBJECT_SELF"TotalLeech");
    
int nLeech nDamage nBlessure;
    
int nTotalLeech nDamage nTotBless;
    
SetLocalInt(oDamagersLeechnLeech);
    
SetLocalInt(OBJECT_SELF"TotalLeech"nTotalLeech);
    
int nFCoup nCoup 1;
    
SetLocalInt(OBJECT_SELF"Coup"nFCoup);
    
VoiceFighting(oDamagernDamage);

    if(!
GetFleeToExit())
    {
        if(!
GetSpawnInCondition(NW_FLAG_SET_WARNINGS))
        {
            if(!
GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
            {
                if(
GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
                {
                    
DetermineSpecialBehavior(oDamager);
                }
                else if(
GetIsObjectValid(oDamager))
                {
                    
DetermineCombatRound();
                    if(!
GetIsFighting(OBJECT_SELF))
                    {
                        if(!
GetObjectSeen(oDamager) && GetArea(OBJECT_SELF) == GetArea(oDamager))
                        {
                            
ActionMoveToLocation(GetLocation(oDamager), TRUE);
                            
ActionDoCommand(DetermineCombatRound());
                        }
                    }
                }
            }
            else if (!
GetIsObjectValid(GetAttemptedSpellTarget()))
            {
                
object oTarget GetAttackTarget();
                if(!
GetIsObjectValid(oTarget))
                {
                    
oTarget GetAttemptedAttackTarget();
                }
                
object oAttacker GetLastHostileActor();
                if (
GetIsObjectValid(oAttacker) && oTarget != oAttacker && GetIsEnemy(oAttacker) &&
                   (
GetTotalDamageDealt() > (GetMaxHitPoints(OBJECT_SELF) / 4) ||
                    (
GetHitDice(oAttacker) - 2) > GetHitDice(oTarget) ) )
                {
                    
DetermineCombatRound(oAttacker);
                }
            }
        }
    }
    if(
GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT))
    {
        
SignalEvent(OBJECT_SELFEventUserDefined(1006));
    }

Code PHP:

//::///////////////////////////////////////////////
//:: Default On Death
//:: NW_C2_DEFAULT7
//:://////////////////////////////////////////////

//:://////////////////////////////////////////////
//:: Created By: Binote
//:: Created On: Mai 2003
//:://////////////////////////////////////////////

#include "NW_I0_GENERIC"

//Vous pouvez changer la valeur de nBaseXP selon votre echelle; 100=DMG.
int nBaseXP 100;
//Bonus d'XP a partager entre les membres conscients du groupe se trouvant dans la meme Zone
int nBonusXPGroupe 25;
//Bonus d'XP pour celui qui acheve la creature
int nBonusXPTueur 5;
//Bonus de Rarete: nombre de creatures tuees avant que le Bonus = 0
int nBonusXPRarete 20;

//Changement de la Reputation de base lors d'un meurtre
int nReput = -5;

//Ne changez rien ci-dessus, sauf si vous savez ce que vous faites ;)

//Fonction d'xp du PJ achevant le monstre
void XPTueur(object oKillerint nBonusXPTueur)
{
 
float fCR GetChallengeRating(OBJECT_SELF);
 
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
 
float fXP;
 if(
sLeech == "")
 {
  
string sMonine "Votre attaque est si violente que votre adversaire est litteralement pulverise.";
  
FloatingTextStringOnCreature(sMonineoKillerTRUE);
  
fXP fCR nBonusXPTueur;
 }
 else
 {
  
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
  
int nLeech GetLocalInt(oKillersLeech);
  
float fMaxHP IntToFloat(nMaxHP);
  
float fLeech IntToFloat(nLeech);
  
float fDmg fLeech fMaxHP;
  
fXP = (fCR fDmg)* nBonusXPTueur;
 }
 
int nXP FloatToInt(fXP);
 
SendMessageToPC(oKiller"Vous gagnez " IntToString(nXP) + " points d'experience de Bonus.");
 
GiveXPToCreature(oKillernXP);
}

//Fonction d'xp des autres PJ faisant partie du groupe du PJ ayant acheve le monstre
void XPParty(object oKillerobject oAreaint nBonusXPGroupe)
{
     
int nMembres 0;
     
object oMembreGroupe GetFirstFactionMember(oKillerTRUE);
     while (
GetIsObjectValid(oMembreGroupe) == TRUE)
     {
      
object oAreaGroupe GetArea(oMembreGroupe);
      if(
oArea == oAreaGroupe)
      {
       
nMembres nMembres 1;
      }
      
oMembreGroupe GetNextFactionMember(oKillerTRUE);
     }
     
float fCR GetChallengeRating(OBJECT_SELF);
     
float fCompteur IntToFloat(nMembres);
     
//Bonus d'xp accorde aux PJ jouant en groupe.
     //Si vous ne voulez pas favoriser cela, mettez cette ligne:
     //float fMultiplier = 1.0;
     
float fMultiplier = (1.0 + ((0.1 fCompteur) - 0.1));
     
float fXP = ((fCR fMultiplier) / fCompteur);
     
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
     
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
     while (
GetIsObjectValid(oMembreGroupe) == TRUE)
     {
      
object oAreaGroupe GetArea(oMembreGroupe);
      if(
GetIsPC(oMembreGroupe) == TRUE && oArea == oAreaGroupe && GetCurrentHitPoints(oMembreGroupe) > 0)
      {
       
int nLeech GetLocalInt(oMembreGroupesLeech);
       if(
sLeech == "")
       {
        
nMaxHP GetMaxHitPoints(OBJECT_SELF);
        
nLeech nMaxHP;
       }
       
float fMaxHP IntToFloat(nMaxHP);
       
float fLeech IntToFloat(nLeech);
       
float fDmg fLeech fMaxHP;
       
float fXPReel = (fXP fDmg)* nBonusXPGroupe;
       
int nXP FloatToInt(fXPReel);
       
SendMessageToPC(oMembreGroupe"Vous gagnez " IntToString(nXP) + " points d'experience de Bonus de Groupe.");
       
GiveXPToCreature(oMembreGroupenXP);
      }
      
oMembreGroupe GetNextFactionMember(oKillerTRUE);
     }
}

//Fonction d'xp des autres PJ ayant touche le monstre
void XPBinote(object oAreaint nBaseXPint nXPRarete)
{
    
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
    if(
sLeech == "")
    {
     return;
    }
    else
    {
     
object oLeecheur GetFirstPC();
     
float fCR GetChallengeRating(OBJECT_SELF);
     
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
     
float fMaxHP IntToFloat(nMaxHP);
     while (
GetIsObjectValid(oLeecheur) == TRUE)
     {
      
object oAreaLeech GetArea(oLeecheur);
      if(
oArea == oAreaLeech && GetCurrentHitPoints(oLeecheur) > 0)
      {
       
int nLeech GetLocalInt(oLeecheursLeech);
       
float fLeech IntToFloat(nLeech);
       
float fDmg fLeech fMaxHP;
       
float fXPReel = (fCR fDmg)* nBaseXP;
       
int nXPLeech FloatToInt(fXPReel);
       
int nXP nXPLeech nXPRarete;
       
SendMessageToPC(oLeecheur"Vous gagnez " IntToString(nXP) + " XP, dont " IntToString(nXPRarete) + " XP de Bonus de Rarete.");
       
GiveXPToCreature(oLeecheurnXP);
       
DeleteLocalInt(oLeecheursLeech);
      }
      
oLeecheur GetNextPC();
     }
    }
}

//Tableau de Chasse du Joueur
int GetKillBoard(object oKillerstring sNom)
{
    
int nKills GetLocalInt(oKillersNom);
    
nKills += 1;
    
SetLocalInt(oKillersNomnKills);
    return 
nKills;
}

//Bonus XP de Rarete
int GetXPRarete(int nBonusXPRareteint nKills)
{
    
float fCR GetChallengeRating(OBJECT_SELF);
    
float fBonusXPRarete IntToFloat(nBonusXPRarete);
    
float fKills IntToFloat(nKills);
    
float fXP fCR * (fBonusXPRarete/fKills);
    
int nXP FloatToInt(fXP);
    return 
nXP;
}

//Ajustement de la Faction lors d'un meurtre
void AdjustFaction (object oKillerint nReput)
{
    
object oLeader GetFactionLeader(OBJECT_SELF);
    
object oGrosBill GetFactionStrongestMember(OBJECT_SELF);
    
string sFaction GetName(oLeader);
    if(
oLeader == OBJECT_SELF)
    {
     
nReput nReput 20;
    }
    else if(
oGrosBill == OBJECT_SELF)
    {
     
nReput nReput 10;
    }
    
AdjustReputation(oKillerOBJECT_SELFnReput);
    
SendMessageToPC(oKiller"Votre reputation vis-a-vis de la faction de " sFaction " s'est deterioree!");
}

void main()
{
    
int nClass GetLevelByClass(CLASS_TYPE_COMMONER);
    
int nAlign GetAlignmentGoodEvil(OBJECT_SELF);
    
object oKiller GetLastKiller();
    
object oArea GetArea(OBJECT_SELF);
    
string sArea GetTag(oArea);
    
string sNom GetName(OBJECT_SELF);
    
string sKiller GetName(oKiller);
    if(
nClass && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))
    {
        
AdjustAlignment(oKillerALIGNMENT_EVIL5);
    }
    
//Message d'avertissement aux MDs. Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
    
SendMessageToAllDMs(sNom " vient d'etre tue par " sKiller " dans " sArea);
    if(
GetIsPC(oKiller) == TRUE)
    {
     
//Resultat du Tableau de Chasse
     
int nKillBoard GetKillBoard(oKillersNom);
     
string sKills IntToString(nKillBoard);
     
SendMessageToPC(oKiller"Vous venez de tuer " sNom "; ceci est votre " sKills "e !");
     
//Bonus XP Rarete
     
int nXPRarete GetXPRarete(nBonusXPRaretenKillBoard);
     
//Bonus XP Tueur, Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
     
XPTueur(oKillernBonusXPTueur);
     
//XP (mettez bien l'echelle d'xp sur 0 dans les proprietes du module)
     
XPBinote(oAreanBaseXPnXPRarete);
     
//Bonus XP Groupe, Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
     
XPParty(oKilleroAreanBonusXPGroupe);
    }
     
//Ajustement de la Faction
     
AdjustFaction (oKillernReput);
     
//Effacement des variables locales du monstre
     
DeleteLocalInt(OBJECT_SELF"TotalLeech");
     
DeleteLocalInt(OBJECT_SELF"Coup");
     
DeleteLocalString(OBJECT_SELF"TagLeech");
    if(
GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
    {
        
SignalEvent(OBJECT_SELFEventUserDefined(1007));
    }

Voilà, je voudrais savoir si c'est possible de faire un PNJ qui donne le niveau 2 aux joueurs seulement s'ils sont niveau 1, avec un petit dialogue ?

Merci d'éviter de poster en majuscule à l'avenir.
j'ai trouvé le scrypt est a mettre dans " action " du dialogue du joueur

Code PHP:


void main
()
{
    
// Donne 3001 XP au joueur s'il est lvl 1
    
object joueur GetPCSpeaker();
    
int nXP GetXP(joueur);

    if (
nXP 1001)
    {
        
GiveXPToCreature(joueur3001);
         
    }



voila
Bonjour, j'ai remarqué 2-3 petites choses dans le code ici, je suppose qu'il vaut mieux les rapporter :

- Le ratio d'xp 100 est trop élevé, un chevalier funeste de la campagne solo rapporte avec ce script 1050xp ( 1000xp avec XPBinote, et 50 avec XPTueur )
Pour ma part j'ai mis le ratio nBaseXP = 7, et nBonusXPTueur = 3 (ou deux, je me rapelle plus ), ainsi je touche une xp correcte de tous les monstres. Enfin ça c'est juste minime
- J'ai modifié quelque peu le script pour mon usage, en rajoutant un test d'xp minimale, en effet, certains monstres donnaient 0 points d'xp ( cela vient surement d'un FloatToInt ), pour contrer cela il suffit de rajouter juste avant les lignes concernant legain d'xp du jouer un petit

if(nXP < 20)
{
nXP = 20;
}

ainsi on obtient une xp minimale par monstre, qui me semble tout a fait convenable.

- J'ai eu une erreur de "division par zero" à un moment, je suppose qu'elle provient du moment ou on compte les membres du groupe dans la zone, mais logiquement vu que le pj ayant tué le monstre se trouve dans sa zone, la variable nMembre ( et donc fCompteur ) devraient au minimum valoir 1... (pour info, ceci ce trouve dans la foncopn XPParty ).
Les seules autres divisions sont du genre fDmg = fLeech / fMaxHP; et si j'ai bien compris, fMaxHP contient la valeur des hp maximaux du monstre qui vient de mourir, donc toujours différent de zero.
Enfin bref, ce bug de division par zero n'a pas causé de plantage ni rien, juste un petit message jaune.
Je tiens a préciser que j'ai eu ce message lorsque je ne tuais aucun monstre (je ramassais mes drops ), que tous les membres de mon groupe ont eu ce message, et que j'étais seul dans ma zone.

- Pour terminer, la fonction XPParty n'a pas l'air de fonctionner. En fait, j'ai jamais regardé et calculé exactement l'xp que l'on gagnait hors et en party a la mort d'un monstre via la fiche du personnage, mais je déduis cela du fait que je n'ai jamais eu le message suivant :

SendMessageToPC(oMembreGroupe, "Vous gagnez " + IntToString(nXP) + " points d'experience de Bonus de Groupe.");

J'en conclus donc que la fonction ne donne pas l'xp, vu qu'elle ne s'exécute pas, ou qu'elle plante avant d'afficher ce message.


Pour info, voici le script tel que je l'utilise :
Code PHP:

 //::///////////////////////////////////////////////
     //:: Default On Death
     //:: NW_C2_DEFAULT7
     //:://////////////////////////////////////////////
     
     //:://////////////////////////////////////////////
     //:: Created By: Binote
     //:: Created On: Mai 2003
     //:://////////////////////////////////////////////
     
     #include "NW_I0_GENERIC"
     
     //Vous pouvez changer la valeur de nBaseXP selon votre echelle; 100=DMG.
     
int nBaseXP 7;
     
//Bonus d'XP a partager entre les membres conscients du groupe se trouvant dans la meme Zone
     
int nBonusXPGroupe 25;
     
//Bonus d'XP pour celui qui acheve la creature
     
int nBonusXPTueur 3;
     
//Bonus de Rarete: nombre de creatures tuees avant que le Bonus = 0
     
int nBonusXPRarete 20;
     
     
//Changement de la Reputation de base lors d'un meurtre
     
int nReput = -5;
     
     
//Ne changez rien ci-dessus, sauf si vous savez ce que vous faites ;)
     
     //Fonction d'xp du PJ achevant le monstre
     
void XPTueur(object oKillerint nBonusXPTueur)
     {
     
float fCR GetChallengeRating(OBJECT_SELF);
     
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
     
float fXP;
     if(
sLeech == "")
     {
       
string sMonine "Votre attaque est si violente que votre adversaire est litteralement pulverise.";
       
FloatingTextStringOnCreature(sMonineoKillerTRUE);
       
fXP fCR nBonusXPTueur;
     }
     else
     {
       
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
       
int nLeech GetLocalInt(oKillersLeech);
       
float fMaxHP IntToFloat(nMaxHP);
       
float fLeech IntToFloat(nLeech);
       
float fDmg fLeech fMaxHP;
       
fXP = (fCR fDmg)* nBonusXPTueur;
     }
     
int nXP FloatToInt(fXP);
     if(
nXP 20)
     {
         
nXP 20;
     }
     
SendMessageToPC(oKiller"Vous gagnez " IntToString(nXP) + " points d'experience de Bonus.");
     
GiveXPToCreature(oKillernXP);
     }
     
     
//Fonction d'xp des autres PJ faisant partie du groupe du PJ ayant acheve le monstre
     
void XPParty(object oKillerobject oAreaint nBonusXPGroupe)
     {
          
int nMembres 0;
          
object oMembreGroupe GetFirstFactionMember(oKillerTRUE);
          while (
GetIsObjectValid(oMembreGroupe) == TRUE)
          {
           
object oAreaGroupe GetArea(oMembreGroupe);
           if(
oArea == oAreaGroupe)
           {
            
nMembres nMembres 1;
           }
           
oMembreGroupe GetNextFactionMember(oKillerTRUE);
          }
          
float fCR GetChallengeRating(OBJECT_SELF);
          
float fCompteur IntToFloat(nMembres);
          
//Bonus d'xp accorde aux PJ jouant en groupe.
          //Si vous ne voulez pas favoriser cela, mettez cette ligne:
          
float fMultiplier 1.0;
          
//float fMultiplier = (1.0 + ((0.1 * fCompteur) - 0.1));
          
float fXP = ((fCR fMultiplier) / fCompteur);
          
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
          
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
          while (
GetIsObjectValid(oMembreGroupe) == TRUE)
          {
           
object oAreaGroupe GetArea(oMembreGroupe);
      if(
GetIsPC(oMembreGroupe) == TRUE && oArea == oAreaGroupe && GetCurrentHitPoints(oMembreGroupe) > 0)
           {
            
int nLeech GetLocalInt(oMembreGroupesLeech);
            if(
sLeech == "")
            {
             
nMaxHP GetMaxHitPoints(OBJECT_SELF);
             
nLeech nMaxHP;
            }
            
float fMaxHP IntToFloat(nMaxHP);
            
float fLeech IntToFloat(nLeech);
            
float fDmg fLeech fMaxHP;
            
float fXPReel = (fXP fDmg)* nBonusXPGroupe;
            
int nXP FloatToInt(fXPReel);
      
SendMessageToPC(oMembreGroupe"Vous gagnez " IntToString(nXP) + " points d'experience de Bonus de Groupe.");
            
GiveXPToCreature(oMembreGroupenXP);
           }
           
oMembreGroupe GetNextFactionMember(oKillerTRUE);
          }
     }
     
     
//Fonction d'xp des autres PJ ayant touche le monstre
     
void XPBinote(object oAreaint nBaseXP)
     {
         
string sLeech GetLocalString(OBJECT_SELF"TagLeech");
         if(
sLeech == "")
         {
          return;
         }
         else
         {
          
object oLeecheur GetFirstPC();
          
float fCR GetChallengeRating(OBJECT_SELF);
          
int nMaxHP GetLocalInt(OBJECT_SELF"TotalLeech");
          
float fMaxHP IntToFloat(nMaxHP);
          while (
GetIsObjectValid(oLeecheur) == TRUE)
          {
           
object oAreaLeech GetArea(oLeecheur);
           if(
oArea == oAreaLeech && GetCurrentHitPoints(oLeecheur) > 0)
           {
            
int nLeech GetLocalInt(oLeecheursLeech);
            
float fLeech IntToFloat(nLeech);
            
float fDmg fLeech fMaxHP;
            
float fXPReel = (fCR fDmg)* nBaseXP;
            
int nXPLeech FloatToInt(fXPReel);
            
int nXP nXPLeech;
            if(
nXP 20)
            {
             
nXP 20;
            }
            
SendMessageToPC(oLeecheur"Vous gagnez " IntToString(nXP) + " XP");
            
GiveXPToCreature(oLeecheurnXP);
            
DeleteLocalInt(oLeecheursLeech);
           }
           
oLeecheur GetNextPC();
          }
         }
     }
     
     
//Tableau de Chasse du Joueur
     
int GetKillBoard(object oKillerstring sNom)
     {
         
int nKills GetLocalInt(oKillersNom);
         
nKills += 1;
         
SetLocalInt(oKillersNomnKills);
         return 
nKills;
     }
     
     
     
     
void main()
     {
         
int nClass GetLevelByClass(CLASS_TYPE_COMMONER);
         
int nAlign GetAlignmentGoodEvil(OBJECT_SELF);
         
object oKiller GetLastKiller();
         
object oArea GetArea(OBJECT_SELF);
         
string sArea GetTag(oArea);
         
string sNom GetName(OBJECT_SELF);
         
string sKiller GetName(oKiller);
     
//Message d'avertissement aux MDs. Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
         //SendMessageToAllDMs(sNom + " vient d'etre tue par " + sKiller + " dans " + sArea);
         
if(GetIsPC(oKiller) == TRUE)
         {
          
//Resultat du Tableau de Chasse
          
int nKillBoard GetKillBoard(oKillersNom);
          
string sKills IntToString(nKillBoard);
          
SendMessageToPC(oKiller"Vous venez de tuer " sNom "; ceci est votre " sKills "e !");
          
//Bonus XP Rarete
          //Bonus XP Tueur, Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
          
XPTueur(oKillernBonusXPTueur);
          
//XP (mettez bien l'echelle d'xp sur 0 dans les proprietes du module)
          
XPBinote(oAreanBaseXP);
          
//Bonus XP Groupe, Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
          
XPParty(oKilleroAreanBonusXPGroupe);
         }
          
//Ajustement de la Faction
          //Effacement des variables locales du monstre
          
DeleteLocalInt(OBJECT_SELF"TotalLeech");
          
DeleteLocalInt(OBJECT_SELF"Coup");
          
DeleteLocalString(OBJECT_SELF"TagLeech");
         if(
GetSpawnInCondition(NW_FLAG_DEATH_EVENT))
         {
             
SignalEvent(OBJECT_SELFEventUserDefined(1007));
         }
     } 
et le ondeath :
Code PHP:

//::///////////////////////////////////////////////
     //:: Default On Damaged
     //:: NW_C2_DEFAULT6
     //:: Copyright (c) 2001 Bioware Corp.
     //:://////////////////////////////////////////////
     /*
         If already fighting then ignore, else determine
         combat round
     */
     //:://////////////////////////////////////////////
     //:: Created By: Preston Watamaniuk
     //:: Created On: Oct 16, 2001
     //:: Modifier By: Binote
     //:://////////////////////////////////////////////
     
     #include "NW_I0_GENERIC"
     
     
void main()
     {
         
object oDamager GetLastDamager();
         
int nDamage GetTotalDamageDealt();
         
int nCoup GetLocalInt(OBJECT_SELF"Coup");
         
string sLeech;
         if (
nCoup == 0)
         {
          
string sTag GetTag(OBJECT_SELF);
          
int nID Random(65534);
          
string sID IntToString(nID);
          
sLeech "Leech_" sTag sID;
         }
         else
         {
          
sLeech GetLocalString(OBJECT_SELF"TagLeech");
         }
         
SetLocalString(OBJECT_SELF"TagLeech"sLeech);
         
int nBlessure GetLocalInt(oDamagersLeech);
         
int nTotBless GetLocalInt(OBJECT_SELF"TotalLeech");
         
int nLeech nDamage nBlessure;
         
int nTotalLeech nDamage nTotBless;
         
SetLocalInt(oDamagersLeechnLeech);
         
SetLocalInt(OBJECT_SELF"TotalLeech"nTotalLeech);
         
int nFCoup nCoup 1;
         
SetLocalInt(OBJECT_SELF"Coup"nFCoup);
     
         if(!
GetFleeToExit())
         {
             if(!
GetSpawnInCondition(NW_FLAG_SET_WARNINGS))
             {
          if(!
GetIsObjectValid(GetAttemptedAttackTarget()) && !GetIsObjectValid(GetAttemptedSpellTarget()))
                 {
                     if(
GetBehaviorState(NW_FLAG_BEHAVIOR_SPECIAL))
                     {
                  
DetermineSpecialBehavior(oDamager);
                     }
                 else if(
GetIsObjectValid(oDamager))
                     {
                         
DetermineCombatRound();
                  if(!
GetIsFighting(OBJECT_SELF))
                         {
                      if(!
GetObjectSeen(oDamager) && GetArea(OBJECT_SELF) == GetArea(oDamager))
                      {
                          
ActionMoveToLocation(GetLocation(oDamager), TRUE);
                          
ActionDoCommand(DetermineCombatRound());
                      }
                         }
                     }
                 }
              else if (!
GetIsObjectValid(GetAttemptedSpellTarget()))
                 {
                 
object oTarget GetAttackTarget();
                  if(!
GetIsObjectValid(oTarget))
                     {
                  
oTarget GetAttemptedAttackTarget();
                     }
                     
object oAttacker GetLastHostileActor();
              if (
GetIsObjectValid(oAttacker) && oTarget != oAttacker && GetIsEnemy(oAttacker) &&
                  (
GetTotalDamageDealt() > (GetMaxHitPoints(OBJECT_SELF) / 4) ||
                  (
GetHitDice(oAttacker) - 2) > GetHitDice(oTarget) ) )
                     {
                  
DetermineCombatRound(oAttacker);
                     }
                 }
             }
         }
         if(
GetSpawnInCondition(NW_FLAG_DAMAGED_EVENT))
         {
             
SignalEvent(OBJECT_SELFEventUserDefined(1006));
         }
     } 

ps: le nBonusXPGroupe est toujours a 25 pour les raisons citées plus haut : je ne le vois pas intervenir durant ma partie.
ps2: j'utilise ce script pour un module persistant action
ps3 : je trouve ce script super, car il ne dépend pas du lv du monstre et du pj, et donc même les zones bas lv restent intéressante question xp, cela ne limite donc pas le module a "zone A pour lv Y, zone B pour lv Z,..."
Merci de l'avoir tapé, j'avoue que je n'ai pas encore les connaissance nécéssaires pour écrire un tel script, mais juste pour le comprendre ( et encore ^^; )
Citation :
- Le ratio d'xp 100 est trop élevé...
la valeur 100 correspond au DMG (Guide du Maitre 3e Edition), sur mon module persistant j'utilise cette config:

Code PHP:

//Vous pouvez changer la valeur de nBaseXP selon votre echelle; 100=DMG.
int nBaseXP 15;
//Bonus d'XP a partager entre les membres conscients du groupe se trouvant dans la meme Zone
int nBonusXPGroupe 5;
//Bonus d'XP pour celui qui acheve la creature
int nBonusXPTueur 1;
//Bonus de Rarete: nombre de creatures tuees avant que le Bonus = 0
int nBonusXPRarete 10;
//Changement de la Reputation de base lors d'un meurtre
int nReput = -5
Citation :
- J'ai modifié quelque peu le script pour mon usage, en rajoutant un test d'xp minimale, en effet, certains monstres donnaient 0 points d'xp ( cela vient surement d'un FloatToInt ),
Le système donne 0xp dans les cas suivants:
- Le monstre est tué en un coup (ce qui ne représente pas un "défi" selon moi), dans ce cas seuls les XP bonus (BonusXPTueur) sont attribués.
- Le tueur a un CR au moins 2 fois supérieur à celui du monstre tué, ce qui est également trop "facile".
Ce n'est pas du à une erreur ou un bug, mais simplement à un choix de script.

Citation :
J'ai eu une erreur de "division par zero" à un moment,
C'est parce qu'un MD ou un PNJ/monstre tue un autre PNJ/monstre (Et que donc ça entraine une division par 0).
Place la portion "main" du code dans ce "IF":
Code PHP:

if(GetIsPC(oPC) && !GetIsDM(oPC) && !GetIsDMPossessed(oPC))
{

Depuis le temps j'ai mis à jour ce script qui existe dans une version plus récente. Je le publierai cette semaine si ça vous intéresse.
Citation :
- Le tueur a un CR au moins 2 fois supérieur à celui du monstre tué, ce qui est également trop "facile".
je te comprends entièrement, mais bon le pauvre magicien a qui je pensais en écrivant ça se faisait déchirer par le monstre en question ^^;

Enfin, merci de ton aide ^^

ps: oui la version a jour m'intéresse ^^

ps2 : comment vous faites pour que vos codes soient colorés? ^^;
edit : merci, il me semblais juste que j'avais déjà essayé ^^;
Répondre

Connectés sur ce fil

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