JeuxOnLineForumsPlusConnectés : 440 (sites) | 755 (forums)Créer un compte
Forum jeux-vidéo>Neverwinter Nights
Maskado
Répondre
Partager Outils Rechercher
Avatar de Nek
Nek
Alpha & Oméga
 
Avatar de Nek
 

OnPlayerDying

Cette nuit insomnie, alors pour passer mon temps, j'ai concocté un petit script à mettre dans le OnPlayerDying du module:

Le truc classique, le personnage arrivé à 0pv tombe inconscient et perd 1pv par round avec des chances de se stabiliser.
A la différence des règles D&D3e, un jet de vigueur est autorisé à chaque round pour donner plus de chance au personnage de se stabiliser; et le bonus de constitution intervient également dans la récupération des points de vie lorsque le personnage est stabilisé.
Et bien entendu, s'il a -10pv ou moins, il meurt.

Code PHP:
void dying(object oDyingeffect eSaigner)
{
    
int nPv GetCurrentHitPoints(oDying);
    if(
nPv <= -10)
    {
     
effect eMort EffectDeath(FALSEFALSE);
     
SpeakString("Vous etes mort.");
     
PlayVoiceChat(VOICE_CHAT_DEATHoDying);
     
ApplyEffectToObject(DURATION_TYPE_INSTANTeMortoDying);
     return;
    }
    if (
oDying != OBJECT_INVALID && nPv && nPv > -10)
    {
     
effect eAntiDmg EffectDamageImmunityDecrease(DAMAGE_TYPE_MAGICAL100);
     
ApplyEffectToObject(DURATION_TYPE_TEMPORARYeAntiDmgoDying1.0);
     
ApplyEffectToObject(DURATION_TYPE_INSTANTeSaigneroDying);
     
SendMessageToPC(oDying"Vous sombrez dans l'inconscience.");
     
PlayVoiceChat(VOICE_CHAT_NEARDEATHoDying);
     
int nStvig FortitudeSave(oDying15);
     
int nChanceStab;
     switch(
nStvig)
     {
      case 
0:
           
nChanceStab d10(1);
           break;
      case 
1:
           
nChanceStab d6(1);
           break;
      default:
           
nChanceStab d10(1);
           break;
     }
     if(
nChanceStab <= 1)
     {
      
int nBonusCon GetAbilityModifier(ABILITY_CONSTITUTIONoDying);
      
int nStabilise = (nBonusCon 1);
      
SendMessageToPC(oDying"Vous etes stabilise.");
      
effect eStabilise EffectHeal(nStabilise);
     }
     else
     {
      
DelayCommand(6.0dying(oDyingeSaigner));
     }
    }
}

void main()
{
    
object oDying GetLastPlayerDying();
    
effect eSaigner EffectDamage(1);
    
PlayVoiceChat(VOICE_CHAT_HEALMEoDying);
    
DelayCommand(6.0dying(oDyingeSaigner));

//Petite question: je ne sais pas si le fait d'appliquer un EffectDamage par défaut (DAMAGE_TYPE_MAGICAL donc), prend en compte les résistances ou immunités du personnage à ce type de dégats. Dans le doute, j'ai donc ajouté une ligne qui diminue pendant 1 seconde les résistances à ce type de dégats de 100%.
Maintenant on pourra me dire que pendant cette seconde, un personnage serait vulnérable aux dégats magiques venant d'une autre source, et que ce serait injuste, etc....
Lien direct vers le message - Vieux
Avatar de Jedaï
Jedaï
Alpha & Oméga
 
Avatar de Jedaï
 
Pour répondre à ta question, oui, les résistances sont prises en compte, mais une meilleure solution serait d'appliquer des dommages de type divin : DAMAGE_TYPE_DIVINE.
Lien direct vers le message - Vieux
Nonolevil
Roi
 
il est bien chouette ce script surtout que je cherchais a en faire un (mais je suis pas doué faut dire).
Par contre pour les dommages/guérison je comprend pas pourquoi on utilise pas ça:
EffectHitPointChangeWhenDying();
Ca peut être positif ou négatif et ça évite les problème de résistances diverses, alors pourquoi? ça marche pas, c'est buggé?
Lien direct vers le message - Vieux
Avatar de Nek
Nek
Alpha & Oméga
 
Avatar de Nek
 
Oui tout juste. Le problème est que j'ai adapté mon ancien script de mort qui datait de la 1.21, et à l'époque cette fonction n'existait pas.

Voici la version corrigée (et un rien améliorée)

Code PHP:
/Nombre de PV perdus par round (1.0 1/round0.5 1/2rndetc)
float fAgonie 1.0;
//Nombre de PV gagnes par round en etant stabilise
float fRecup 1.0;
//DC du Jet de Vigueur permettant de se stabiliser
int nDCFort 15;

void dying(object oDyingeffect eSaigner)
{
    
int nPv GetCurrentHitPoints(oDying);
    if(
nPv <= -10)
    {
     
effect eMort EffectDeath(FALSEFALSE);
     
SpeakString("Vous etes mort.");
     
PlayVoiceChat(VOICE_CHAT_DEATHoDying);
     
ApplyEffectToObject(DURATION_TYPE_INSTANTeMortoDying);
     return;
    }
    if (
oDying != OBJECT_INVALID && nPv && nPv > -10)
    {
     
ApplyEffectToObject(DURATION_TYPE_INSTANTeSaigneroDying);
     
SendMessageToPC(oDying"Vous sombrez dans l'inconscience.");
     
PlayVoiceChat(VOICE_CHAT_NEARDEATHoDying);
     
int nStvig FortitudeSave(oDyingnDCFort);
     
int nChanceStab;
     switch(
nStvig)
     {
      case 
0:
           
nChanceStab d10(1);
           break;
      case 
1:
           
nChanceStab d6(1);
           break;
      default:
           
nChanceStab d10(1);
           break;
     }
     if(
nChanceStab <= 1)
     {
      
int nBonusCon GetAbilityModifier(ABILITY_CONSTITUTIONoDying);
      
float fBonusCon IntToFloat(nBonusCon);
      
float fStabilise = (fBonusCon fRecup);
      
SendMessageToPC(oDying"Vous etes stabilise.");
      
effect eStabilise EffectHitPointChangeWhenDying(fStabilise);
     }
     else
     {
      
DelayCommand(6.0dying(oDyingeSaigner));
     }
    }
}

void main()
{
    
object oDying GetLastPlayerDying();
    
effect eSaigner EffectHitPointChangeWhenDying(fAgonie);
    
PlayVoiceChat(VOICE_CHAT_HEALMEoDying);
    
DelayCommand(6.0dying(oDyingeSaigner));

Lien direct vers le message - Vieux
Nonolevil
Roi
 
Il est super ce script par contre si je peuxme permettre d'abuser, j'aimerais qu'on m'explique (pour ma culture personnelle) c'est quoi le switch et le case avec tous ces paramète, ca marche comment a quoi ca sert.
Je vois pasbien la.

Merci.
Lien direct vers le message - Vieux
Avatar de Jedaï
Jedaï
Alpha & Oméga
 
Avatar de Jedaï
 
Y avais eu une grosse discussion sur le switch case avec le détail technique de ton implémentation en assembleur, mais j'arrive pas à la retrouver, je te redirige donc vers ce topic, qui je pense répondra à la plupart de tes questions :
http://forums.jeuxonline.info/showth...hreadid=151909

Très joli script en passant Delphinea, surtout la deuxième version.
Lien direct vers le message - Vieux
Nonolevil
Roi
 
Bon merci je vois a quoi correspond le switch/case maintenant, donc autre question a quoi sert ce test ici?
Je ne comprend pas bien a quoi correspond la ligne:
int nStvig = FortitudeSave(oDying, nDCFort);
a quoi elle sert?
pourquoi le résultat ne peut être que 0 ou 1 ?
et surtout pourquoi 2 nChanceStab différents?

(en fait je pense avoir une idée mais j'en suis pas bien sur)
Voila encore beaucoup de questions pour un script qui je le redit est un bien beau script.
Lien direct vers le message - Vieux
Avatar de Jedaï
Jedaï
Alpha & Oméga
 
Avatar de Jedaï
 
FortitudeSave( oDying, nDC ) fait effectuer un jet de vigueur (d20 + vigueur) à oDying contre nDC (si c'est au-dessus ou égal c'est bon), ce jet est donc soit réussi, soit raté.
S'il est réussi, on tire un d6, sinon on tire un d10, si le résultat de ce nouveau jet est 1, le mourant se rétablit.
Autrement dit, si le jet de vigueur est réussi, le mourant a une chance sur six de se rétablir, sinon il a une chance sur dix.
(Ceci à chaque round)
Lien direct vers le message - Vieux
Avatar de Nek
Nek
Alpha & Oméga
 
Avatar de Nek
 
Je n'aurais pas pu expliquer mieux que Jedaï

Le fait est que l'entier retourné par la fonction "FortitudeSave" est de type booléen (donc vrai ou faux, 0 ou 1), il ne peut pas avoir d'autre résultat, voilà pourquoi il n'y a que ces 2 possibilités là dans le "case".

Maintenant tu vas me dire: "Oui, mais il y a "default" aussi."
Cette option reprend tous les résultats qui ne sont pas énoncés plus haut dans le case (donc qui ne sont ni 0, ni 1).
Etant donné qu'avec la fonction utilisée il ne peut en être autrement, ce cas est inutile me diras-tu.
En fait les scripteurs sont tous des paranoïaques, et ils mettent toujours des tests superflus, on ne sait jamais qu'une valeur imprévue viendrait s'incruster et que le résultat soit autre
C'est surtout par sécurité, comme lorsque dans un script OnClientEnter on met un ligne du genre (incomplet n'essayez pas de compiler ):
Code PHP:
if(!GetIsPC(oPC())
 return; 
En théorie ce script ne peut se déclencher que lorsqu'un joueur est entre sur le serveur, mais bon on ne sait jamais ce qui pourrait entrer par inadvertance

En bref, mieux vaut une petite ligne de sécurité supplémentaire qui ne mange pas de pain, que de se retrouver avec une belle erreur en jaune dans la fenêtre de dialogues du jeu
Lien direct vers le message - Vieux
Avatar de eMRaistlin
eMRaistlin
Alpha & Oméga
 
Avatar de eMRaistlin
 
s'pa encore en persistant, ca ?.
Lien direct vers le message - Vieux
Nonolevil
Roi
 
merci pour toutes ces explications, en fait c'était surtout le default qui m'embrouillais un peu . Doncil me suffit aussi de canger les dés si je veux donner pus ou moind de chance au PJ de se rétablir, c'est bien cool ca, il est vraiment fort ce script .
Lien direct vers le message - Vieux
Nonolevil
Roi
 
heuuu, je viens a l'instant de tester et qand je me stabilise, je regagne des points de vie mais je reste allongé comme mort, ca le fait chez d'autres? il manque quelque chose ?
enfin bon voila je monte a +2 points de vie je suis marqué comme agonisant mais je reste mort je vois pas ce qu'il peut y avoir.
Lien direct vers le message - Vieux
Avatar de gaeriel/nekresh
gaeriel/nekresh
Empereur
 
Avatar de gaeriel/nekresh
 
Et si l'on possède un anneau de régénération +1, on se retrouve dans une boucle infernale qui fait que l'on perd à chaque tour un point de vie tout en en regagnant et, sans se stabiliser, on y reste un certain moment. Je ne sais pas comment on peut faire pour empêcher cela sans pénaliser la personne qui possède un tel anneau.
Lien direct vers le message - Vieux
Avatar de Nek
Nek
Alpha & Oméga
 
Avatar de Nek
 
Plusieurs choses ne tournent pas rond avec la fonction "EffectHitPointChangeWhenDying" en effet, j'ai effectué quelques tests également.

Tout d'abord mettre une valeur négative à fAgonie, sinon tu gagnes des PV au lieu d'en perdre (Là c'est ma faute, je l'avais laissé en positif dans l'exemple donné ici)

Ensuite, avec le script tel qu'il est là, on ne perd pas 1 point par round, mais 1 point CUMULATIF par round. (1 au premier, 2 au 2e, 3 au 3e, etc). Autant dire qu'on meurt vite

Je n'ai pas trouvé de trace de cette fonction dans les scripts Bioware (mis à part son énoncé dans nwscript fatalement), donc difficile de savoir ce qu'il fait réellement.

Lors de la stabilisation, c'est normal que ça ne marche pas, vu que la valeur positive te fait passer au-dessus de zéro et que le script n'est pas capable d'interpéter ce résultat (quand je parlais des tests paranos, en voilà l'exemple le plus flagrant d'utilisation )

Donc, en résumé, la fonction "EffectHitPointChangeWhenDying" est un raccourci fait par Bioware qui NE DOIT PAS être mis dans une boucle, car la valeur est cumulative à chaque appel de la fonction.
Pour ce script, le seul effet valable est le EffectDamage et le EffectHeal.

Donc voici le script final (testé et il fonctionne):

Code PHP:
//Nombre de PV perdus par round
int nAgonie 1;
//Nombre de PV gagnes par round en etant stabilise
int nRecup 1;
//Delai en secondes entre la perte de PV (6.0 = 1 round)
float fDelai 6.0;
//DC du Jet de Vigueur permettant de se stabiliser
int nDCFort 15;
//% de chance d'etre stabilise (entre 1 et 6; 6=100%)
int nStab 1;

void dying(object oDyingeffect eSaigner)
{
    
int nPv GetCurrentHitPoints(oDying);
    if(
nPv <= -10)
    {
     
effect eMort EffectDeath(FALSEFALSE);
     
SpeakString("Vous etes mort.");
     
PlayVoiceChat(VOICE_CHAT_DEATHoDying);
     
ApplyEffectToObject(DURATION_TYPE_INSTANTeMortoDying);
     return;
    }
    if (
oDying != OBJECT_INVALID && nPv 0)
    {
     
SpeakString("Vous sortez de l'inconscience.");
     
PlayVoiceChat(VOICE_CHAT_LAUGHoDying);
     
ClearAllActions();
     return;
    }
    if (
oDying != OBJECT_INVALID && nPv <= && nPv > -10)
    {
     
effect eAntiDmg EffectDamageImmunityDecrease(DAMAGE_TYPE_MAGICAL100);
     
ApplyEffectToObject(DURATION_TYPE_TEMPORARYeAntiDmgoDying0.5);
     
ApplyEffectToObject(DURATION_TYPE_INSTANTeSaigneroDying);
     
SendMessageToPC(oDying"Vous sombrez dans l'inconscience.");
     
PlayVoiceChat(VOICE_CHAT_NEARDEATHoDying);
     
int nStvig FortitudeSave(oDyingnDCFort);
     
int nChanceStab;
     switch(
nStvig)
     {
      case 
0:
           
nChanceStab d10(1);
           break;
      case 
1:
           
nChanceStab d6(1);
           break;
      default:
           
nChanceStab d10(1);
           break;
     }
     if(
nChanceStab <= nStab)
     {
      
int nBonusCon GetAbilityModifier(ABILITY_CONSTITUTIONoDying);
      
int nStabilise = (nBonusCon nRecup);
      
SendMessageToPC(oDying"Vous etes stabilise.");
      
effect eStabilise EffectHeal(nStabilise);
     }
     
DelayCommand(fDelaidying(oDyingeSaigner));
    }
}

void main()
{
    
object oDying GetLastPlayerDying();
    
effect eSaigner EffectDamage(nAgonie);
    
PlayVoiceChat(VOICE_CHAT_HEALMEoDying);
    
DelayCommand(fDelaidying(oDyingeSaigner));

PS: Pour l'anneau de regénération, cela ne pose pas de problème pour le script. L'anneau va justement permettre au personnage de ne jamais mourir (sauf s'il prend un coup en étant par terre évidemment) et d'attendre que la stabilisation s'enclenche grace au jet de sauvegarde et au % de chance d'être stabilisé.
Et lorsque la stabilisation sera lancée, il va récupérer ses PV jusqu'à se retrouver en positif, et se relever.
Lien direct vers le message - Vieux
Avatar de Nek
Nek
Alpha & Oméga
 
Avatar de Nek
 
A propos de la fonction "EffectHitPointChangeWhenDying" j'ai fait une recherche sur les forums de Bioware, et dans la FAQ j'ai trouvé ceci:

Citation:
Some Things To Be Aware Of

- EffectHitPointChangeWhenDying doesn't work (will be fixed in next patch)
La FAQ date de juillet dernier, mais ça n'a pas été modifié depuis....

La source:
FAQ Scripts Bioware
Lien direct vers le message - Vieux
Répondre
Les forums JOL > Forum jeux-vidéo > Neverwinter Nights > NWN - Maskado > OnPlayerDying
   

Outils Rechercher
Rechercher:

Recherche avancée

Les vidéos de Neverwinter Nights RSS
  • Aucune vidéo pour le moment...
Thème visuel : Fuseau horaire GMT +1. Il est actuellement 09h16.
   

© JeuxOnLine, le site des MMO, MMORPG et MOBA. Tous droits réservés. - Conditions générales d'utilisation - Conditions d'utilisation des forums - Traitement des données personnelles - ! Signaler un contenu illicite