OnPlayerDying

Répondre
Partager Rechercher
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....
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.
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é?
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));

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.
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 :
https://forums.jeuxonline.info/showthread.php?t=151909

Très joli script en passant Delphinea, surtout la deuxième version.
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.
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)
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
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 .
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.
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.
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.
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
Il me semblait vraiment que cette commande avait été débuggée dans un patch il y a un petit moment, mais après moultes recherches, ben j'ai rien pu retrouver.

Enfin bon, un test ne devrait prendre plus de 5 minutes, mais malheureusement je suis atteint d'une très grave maladie : la glandouillose

Si une âme charitable pouvait s'en charger
Je l'ai testé, et cette fonction renvoit un résultat cumulatif.

Tu peux l'utiliser dans ton script sans problème, mais alors tu ne pourras rien faire intervenir d'autre.

Par exemple:

Code PHP:

void main()
{
 
object oDying GetLastPlayerDying();
 
effect eSaigner EffectHitPointChangeWhenDying(-1.0);
 
ApplyEffectToObject(DURATION_TYPE_PERMANENTeSaigneroDying);

Ton perso va perdre 1 PV par round (6 secondes) et l'effet sera annulé si il reçoit un soin.
La seule chose que tu peux configurer, c'est le nombre de PV perdus (-0.2 voudrait dire 1PV toutes les 30 secondes par exemple).
Le reste, tu ne peux rien faire, à moins de pouvoir modifier la fonction elle-même, mais je ne sais pas où elle se trouve, et si même on peut la modifier....
Merchi bien

En clair ça peut convenir lorsqu'on veut un script de mort simpliste, mais pour un script un peu plus complexe c'est pas plus compliqué de se charger de la baisse de points de vie soi-même.

Par contre je crois que ce genre de fonction est codé en dur dans l'exécutable, donc je doute que tu puisse modifier quoique ce soit
Les fonctions modifiables de Bioware sont celles qui se trouvent dans les fichiers d'include, par exemple nw_i0_generic.
Oui j'ai eu beau cherché, celle là ne figurait dans aucun script nw_ , donc aucune chance de savoir réellement ce qu'elle fait (et de la modifier ce qui est bien dommage )
En effet il manque une ligne (que j'ai corrigé sur mon module test mais pas ici, désolé de l'oubli)

Sous la ligne:
Code PHP:

effect eStabilise EffectHeal(nStabilise); 

Ajouter la ligne:
Code PHP:

ApplyEffectToObject(DURATION_TYPE_INSTANTeStabiliseoDying); 


PS: Je compte bien mettre tous mes scripts dans un "package" installable lorsque j'aurais terminé. Si vous avez la patience d'attendre début juin, vous pourrez bénéficier du système complet de règles testé et corrigé (car ce n'est jamais que des scripts de test pour le moment).
Le script marche très bien, mais il si ton personnage n'a pas été soigné alors qu'il s'est stabilisé, c'est du à ceci:
Si sa constitution a été décrue, et que son "bonus" de constitution soit égal ou inférieur à -2.
Le nombre de PV soigné est alors négatif, vu qu'il résulte de la somme de deux variables: nRecup et nBonusCon.

Exemple:

-Ton perso a 12 de constitution
-Il se prend un critique d'une araignée et rate son jet de vigueur contre le poison
-Sa constitution passe à 6, son "Bonus" de Constitution est donc un malus: -2
-Lorsqu'il se stabilise, le script le "soigne" de 1 - 2 = -1
Répondre

Connectés sur ce fil

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