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 :
//::///////////////////////////////////////////////
//:: 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 oKiller, int 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(sMonine, oKiller, TRUE);
fXP = fCR * nBonusXPTueur;
}
else
{
int nMaxHP = GetLocalInt(OBJECT_SELF, "TotalLeech");
int nLeech = GetLocalInt(oKiller, sLeech);
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(oKiller, nXP);
}
//Fonction d'xp des autres PJ faisant partie du groupe du PJ ayant acheve le monstre
void XPParty(object oKiller, object oArea, int nBonusXPGroupe)
{
int nMembres = 0;
object oMembreGroupe = GetFirstFactionMember(oKiller, TRUE);
while (GetIsObjectValid(oMembreGroupe) == TRUE)
{
object oAreaGroupe = GetArea(oMembreGroupe);
if(oArea == oAreaGroupe)
{
nMembres = nMembres + 1;
}
oMembreGroupe = GetNextFactionMember(oKiller, TRUE);
}
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(oMembreGroupe, sLeech);
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(oMembreGroupe, nXP);
}
oMembreGroupe = GetNextFactionMember(oKiller, TRUE);
}
}
//Fonction d'xp des autres PJ ayant touche le monstre
void XPBinote(object oArea, int 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(oLeecheur, sLeech);
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(oLeecheur, nXP);
DeleteLocalInt(oLeecheur, sLeech);
}
oLeecheur = GetNextPC();
}
}
}
//Tableau de Chasse du Joueur
int GetKillBoard(object oKiller, string sNom)
{
int nKills = GetLocalInt(oKiller, sNom);
nKills += 1;
SetLocalInt(oKiller, sNom, nKills);
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(oKiller, sNom);
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(oKiller, nBonusXPTueur);
//XP (mettez bien l'echelle d'xp sur 0 dans les proprietes du module)
XPBinote(oArea, nBaseXP);
//Bonus XP Groupe, Mettez // devant la ligne si vous ne voulez pas utiliser cette option.
XPParty(oKiller, oArea, nBonusXPGroupe);
}
//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_SELF, EventUserDefined(1007));
}
}
et le ondeath :
//::///////////////////////////////////////////////
//:: 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(oDamager, sLeech);
int nTotBless = GetLocalInt(OBJECT_SELF, "TotalLeech");
int nLeech = nDamage + nBlessure;
int nTotalLeech = nDamage + nTotBless;
SetLocalInt(oDamager, sLeech, nLeech);
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_SELF, EventUserDefined(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 ^^; )