La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
FAQ
Rechercher
Liste des Membres
Groupes d'utilisateurs
S'enregistrer Se connecter pour vérifier ses messages privés Connexion
S'enregistrer Se connecter pour vérifier ses messages privés Connexion
La date/heure actuelle est 23/11/2024 22:24:41
La Bibliothèque de Neverwinter Nights Index du Forum »
La Bibliothèque Binaire du NWScript - Neverwinter Nights
Voir le sujet précédent ¤ Voir le sujet suivant | |
---|---|
Auteur | Message |
Nordehialen Acolyte Messages: 37 |
Posté le : 28/01/2003 13:20:40 Sujet du message : Script pour conditionnement du repos ajout d'un argument
JEDAI a dit :
Pour Conditionner le repos en fontion d'un objet et d'un lieux.... Dans auberge : besoin clef .... a la belle étoile : besoin kit de survie Citation : Bon alors je pense que le script suivant devrait régler ton problème :
Merci encore ca fonction tres bien.
NwScript: Code : void main()
{ object oPC = GetLastPCRested(); string sArea = GetTag(GetArea(oPC)); if (sArea == "Tag De L'Auberge1") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé1"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else if (sArea == "Tag De L'Auberge2") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé2"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else if (sArea == "Tag De L'Auberge3") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé3"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag du kit"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à la belle étoile sans sac de couchage !"); } } } Par ailleurs si ça t'intéresse d'avoir un système plus cohérent et un script plus simple, va voir ce post [http] Maintenat Je voudrati conditionner mon kit ou le script ci dessus pour que Quand tu t'es reposé une fois, tu preds un kit de survie... La deuxieme fois que tu te repose tu en perd encore un .... et ainsi desuite... Comment puis-je faire????? Merci d'avance... _________________ Une drow loyale bonne, difficile à croire et pourtant... |
Revenir en haut | |
Jedaï Chevalier Messages: 89 Localisation: Le Havre, ville pourrie |
C'est assez simple :
Code : void main() { object oPC = GetLastPCRested(); string sArea = GetTag(GetArea(oPC)); if (sArea == "Tag De L'Auberge1") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé1"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else if (sArea == "Tag De L'Auberge2") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé2"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else if (sArea == "Tag De L'Auberge3") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé3"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else { object oKit = GetItemPossessedBy(oPC, "Tag du kit"); if( ! GetIsObjectValid(oKit)) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à la belle étoile sans sac de couchage !"); } else DestroyObject(oKit); } } (Ce script ne marchera pas si tes kits sont empilables) |
Revenir en haut | |
Aania Acolyte Messages: 23 |
Je up ce vieux post pour une question bête.
Pourquoi les messages style "Vous ne pouvez pas dormir à la belle étoile sans sac de couchage !" apparait deux fois quand on presse la touche R pour dormir in-game? Y'a moyen de faire quelque chose contre ça? Meeeeeeerciiiii! |
Revenir en haut | |
lendraste Grand Maître Chanteur du Conseil Messages: 1403 Localisation: Quelque part ailleurs |
Aania a écrit : Je up ce vieux post pour une question bête.
Parce que ce script, qui a été placé sur l'évènement OnPlayerRest se déclenche deux fois. Il se déclenche lorsque le joueur déclenche le sommeil en appuyant sur R, mais dans ce cas, on teste si je joueur a le droit de dormir, et si ce n'est pas le cas, on annule immédiatement le mode repos. En faisant cela on redéclenche l'évènement OnPlayerRest qui se déclenche aussi bien lorsque l'on commence à se reposer que lorsque le repos est interrompu (qu'il soit arrivé à la fin, que je joueur y ait mis fin ou qu'un script y mette fin).
Pourquoi les messages style "Vous ne pouvez pas dormir à la belle étoile sans sac de couchage !" apparait deux fois quand on presse la touche R pour dormir in-game? Citation : Y'a moyen de faire quelque chose contre ça? Bien sûr. Il suffit de tester la raison du déclenchement du OnPlayerRest. La fonction GetLastRestEventType va renvoyer une valeur entière qui correspond au 4 modes possibles de déclenchement de l'évènement :
Extrait du Lexicon a écrit :
REST_EVENTTYPE_REST_FINISHED Rest event completed successfully. This is the normal constant sent after a rest. REST_EVENTTYPE_REST_INVALID Rest event last attempted was invalid due to closeness to hostile creatures, attempt was right after a combat, or another invalidating type of occurance happened to stop PC from resting. REST_EVENTTYPE_REST_STARTED Indicates that a rest event has been started for the specific PC. Voilà ce que ça donne : Code : void main() { object oPC = GetLastPCRested(); int nEventType=GetLastRestEventType(); string sArea = GetTag(GetArea(oPC)); if (nEventType==REST_EVENTTYPE_REST_STARTED) { if (sArea == "Tag De L'Auberge1") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé1"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else if (sArea == "Tag De L'Auberge2") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé2"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else if (sArea == "Tag De L'Auberge3") { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag de la clé3"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à l'auberge sans payer votre chambre !"); } } else { if( ! GetIsObjectValid(GetItemPossessedBy(oPC, "Tag du kit"))) { AssignCommand(oPC, ClearAllActions()); SendMessageToPC(oPC, "Vous ne pouvez pas dormir à la belle étoile sans sac de couchage !"); } } } } _________________ Lendraste de Loreval Qui cherche la Vérité cherche celui qui la détient, car elle n'existe pas à l'état naturel. La cité des mensonges - 1 |
Revenir en haut | |
Aania Acolyte Messages: 23 |
Mmm, Lendraste... Comment dire? Ben t'es balaise...
Bon j'ai bien avancé mais y'a encore un truc qui me chagrine. Dans ce script sur le OnPlayerRest, j'ai inclus un effet de blindness sur le PJ pendant qu'il dort : Code : if (nEventType==REST_EVENTTYPE_REST_STARTED) { ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectBlindness(), oPC); } Je retire bien sur cet effet quand le PJ a fini de dormir : Code : if(nEventType == REST_EVENTTYPE_REST_FINISHED){ RemoveEffect(oPC, EffectBlindness()); } Par contre, j'ai fait ça pour enlever l'effet en cas d'annulation du repos par le PJ fausse manip ou autres : Code : if(nEventType == REST_EVENTTYPE_REST_CANCELLED){ RemoveEffect(oPC, EffectBlindness()); } Mais ça marche pas, l'effet reste quand on se déplace pendant le repos par ex. Je me demande si j'ai pas interet à faire un setcommandable(False) pendant le repos mais j'ai peur qu'en cas d'attaque contre le PJ, il puisse pls rien faire! Any idea, script Master? |
Revenir en haut | |
lendraste Grand Maître Chanteur du Conseil Messages: 1403 Localisation: Quelque part ailleurs |
Aania a écrit : Mmm, Lendraste... Comment dire? Ben t'es balaise... Merci. Mais je me suis beaucoup entraîné
Citation : Code : if(nEventType == REST_EVENTTYPE_REST_CANCELLED){ RemoveEffect(oPC, EffectBlindness()); } Mais ça marche pas, l'effet reste quand on se déplace pendant le repos par ex. Je me demande si j'ai pas interet à faire un setcommandable(False) pendant le repos mais j'ai peur qu'en cas d'attaque contre le PJ, il puisse pls rien faire! Lorsque tu invoques une fonction comme EffectBlindness, tu créé un effet virtuel. Celui-ci n'a de conséquence sur l'environnement que si tu l'appliques à un objet (inerte ou non) ou à une position (cf. ApplyEffectOnObject et ApplyEffectAtLocation). A partir de ce moment, cet effet à une existence propre. Tu comprendras, en lisant cette définition, que faire un RemoveEffect sur quelque chose de virtuel n'a aucun "effet" (mauvais jeu de mot ). Pour supprimer un effet, il faut donc que celui-ci existe, et surtout, il faut pouvoir en trouver la référence. Or, il existe un jeu de commande qui s'appelle GetFirstEffect, GetNextEffect et GetIsEffectValid qui permettent justement de retrouver les effets appliqué sur un objet. La technique de base est la suivante : Code : //oPC contient une référence à un objet Personnage-Joueur comportant un certain nombre d'effet effect eEff=GetFirstEffect(); //Récupère le premier effet appliqué sur l'objet while (GetIsEffectValid(eEff)) //Tant qu'on trouve un effet valide { //faire des trucs avec eEff // ..... eEff=GetNextEffect(); //chercher l'effet suivant } Cette boucle permet de parcourir les effets appliqué sur un objet, sur un personnage-joueur en l'occurrence. Tu me diras sans doute que c'est idiot de parcourir tous les effets alors qu'un seul d'entre eux doit être supprimé, mais NWN ne nous laisse pas le choix, c'est le seul moyen et il comporte de nombreux défaut : Chaque effet trouvé possède des caractéristiques qui permettent de l'identifier. En l'occurence on peut retrouver le type de l'effet (GetEffectType), le sous-type de l'effet (GetEffectSubType), la durée de l'effet (GetEffectDurationType), le créateur de l'effet (GetEffectCreator) et le sort qui a créé l'effet quand c'est un sort qui l'a créé (GetEffectSpellId), mais c'est tout. Rien ne distingue un EffectBlindness tel que tu l'appliques sur le PJ d'un EffectBlindness créé par un sort, ou généré par un objet autrement que par ces caractéristiques. C'est un problème récurent pour un scripteur que de savoir exactement quel effet il doit supprimer lorsque plusieurs effet du même type se combinent sur un objet. Je te laisserai explorer toute la dimension du problème par toi-même. Il se trouve que dans le cas qui nous occupe, on peut se contenter de la solution la plus simple qui consiste à supprimer tous les effets Blindness. Et dans ce cas, on procède ainsi : Code : //oPC contient une référence à un objet Personnage-Joueur comportant un certain nombre d'effet effect eEff=GetFirstEffect(); //Récupère le premier effet appliqué sur l'objet while (GetIsEffectValid(eEff)) //Tant qu'on trouve un effet valide { if (GetEffectType(eEff)==EFFECT_TYPE_BLINDNESS) // On teste s'il s'agit d'un effet de type Blindness { //C'est le cas, on le le supprime RemoveEffect(oPC, eEff); } eEff=GetNextEffect(); //chercher l'effet suivant } Bon courage pour la suite. _________________ Lendraste de Loreval Qui cherche la Vérité cherche celui qui la détient, car elle n'existe pas à l'état naturel. La cité des mensonges - 1 |
Revenir en haut | |
Aania Acolyte Messages: 23 |
Re Lenfaste,
Merci pour tes réponses toujours très détaillées. J'ai quand même un petit souci à comprendre ta solution. Pourquoi mon : Code : RemoveEffect(oPC, EffectBlindness()); marche sur le REST_EVENTTYPE_REST_FINISHED et pas sur le REST_EVENTTYPE_REST_CANCELLED.
J'ai bien compris le fond du problème que tu évoques mais j'ai un peu du mal à comprendre pourquoi ça marche si bien dans le cas ou le sommeil se termine normalement et pas du tout, en cas d'annulation. [EDIT] Ah ben ouais! chuis conne! Quand le PJ a fini son repos, les effets genre Blindness s'annulent automatiquement! Donc mon RemoveEffect sur le REST_EVENTTYPE_REST_FINISHED, il marche pas non plus! J'ai été bluffé là! [/EDIT] Je vais en tout cas, tester ta boucle de suite... Merci encore. |
Revenir en haut | |
lendraste Grand Maître Chanteur du Conseil Messages: 1403 Localisation: Quelque part ailleurs |
Aania a écrit : J'ai bien compris le fond du problème que tu évoques mais j'ai un peu du mal à comprendre pourquoi ça marche si bien dans le cas ou le sommeil se termine normalement et pas du tout, en cas d'annulation. Je n'avais pas trop remarqué cette interrogation en fait. Excuses-moi. Le moteur du jeu exécute certaines actions indépendamment du script. En l'occurence certaines catégories d'effets sont annulés par un début et une fin de repos. C'est le cas de EffectPolymorph, par exemple, qui ne survit pas à l'action de la touche "R" du clavier. Honnêtement je ne connais pas tous les effets affectés par le moteur de jeu de la sorte mais il est possible que EffectBlindness en fasse parti. Pour s'en assurer, tu n'as qu'à supprimer le code concernant le "réveil" normal et regarder si l'effet disparaît quand même, on aura ainsi l'assurance que le "réveil" normal d'un PJ supprime ce type d'effet._________________ Lendraste de Loreval Qui cherche la Vérité cherche celui qui la détient, car elle n'existe pas à l'état naturel. La cité des mensonges - 1 |
Revenir en haut | |
Aania Acolyte Messages: 23 |
Ben voilà, encore une fois, t'as tout bon... Je venais d'éditer mon message après t'avoir devancé pour faire ce test!
Bon ben pour infos, ca marche bien maintenant avec ta boucle sur les effets actifs sur le PJ. Merci merci... |
Revenir en haut | |
nunch Grand Sage du Conseil Messages: 966 Localisation: Dans la gueule du Lyon |
Landraste, est-ce que quand tu boucles sur tous les effets sur un PJ, ceux-ci sont-ils renvoyés dans l'ordre dans lequel ils sont apparus ?
Si c'est le cas, il suffirait juste de dissiper le dernier effet de type Blindness, non ? * Question un poil innoncente * |
Revenir en haut | |
lendraste Grand Maître Chanteur du Conseil Messages: 1403 Localisation: Quelque part ailleurs |
nunch a écrit : Landraste, est-ce que quand tu boucles sur tous les effets sur un PJ, ceux-ci sont-ils renvoyés dans l'ordre dans lequel ils sont apparus ?
Je n'ai pas la réponse à cette question. Et non, je n'ai pas réponse à tout
Si c'est le cas, il suffirait juste de dissiper le dernier effet de type Blindness, non ? * Question un poil innoncente * Je n'ai jamais cherché à savoir si les effets étaient parcourus dans l'ordre où ils ont été affecté. Je serai tenté de dire oui (en faisant référence à mes connaissances théoriques sur les listes linéaires chainées), mais je pense qu'il faut faire le test pour s'en assurer. _________________ Lendraste de Loreval Qui cherche la Vérité cherche celui qui la détient, car elle n'existe pas à l'état naturel. La cité des mensonges - 1 |
Revenir en haut | |
nunch Grand Sage du Conseil Messages: 966 Localisation: Dans la gueule du Lyon |
Dans ce cas j'essairai de vérifier ça ce soir et je tiens au courant.
|
Revenir en haut | |
nunch Grand Sage du Conseil Messages: 966 Localisation: Dans la gueule du Lyon |
J'ai fait un petit script qui applique aléatoire un vingtaine d'effet à un PJ, un même effet pouvant être appliqué plusieurs fois.
Lorsque les effets sont parcourus avec GetFirstEffect() et GetNextEffect(), ils ne sont pas restitués dans l'ordre. Par contre ils ont tendance à être regroupés par type, même si ce n'est pas toujours vrai. Voilà le script utilisé, placé sur un OnEnter() d'un déclencheur: Code : void AfficherTypeEffet(effect eEffet,object oPC) { switch(GetEffectType(eEffet)) { case EFFECT_TYPE_ABILITY_DECREASE: SendMessageToPC(oPC,"EFFECT_TYPE_ABILITY_DECREASE"); break; case EFFECT_TYPE_AC_DECREASE: SendMessageToPC(oPC,"EFFECT_TYPE_AC_DECREASE"); break; case EFFECT_TYPE_ATTACK_DECREASE: SendMessageToPC(oPC,"EFFECT_TYPE_ATTACK_DECREASE"); break; case EFFECT_TYPE_BLINDNESS: SendMessageToPC(oPC,"EFFECT_TYPE_BLINDNESS"); break; case EFFECT_TYPE_CHARMED: SendMessageToPC(oPC,"EFFECT_TYPE_CHARMED"); break; case EFFECT_TYPE_CONCEALMENT: SendMessageToPC(oPC,"EFFECT_TYPE_CONCEALMENT"); break; case EFFECT_TYPE_CONFUSED: SendMessageToPC(oPC,"EFFECT_TYPE_CURSE"); break; case EFFECT_TYPE_CURSE: SendMessageToPC(oPC,"EFFECT_TYPE_CURSE"); break; case EFFECT_TYPE_DARKNESS: SendMessageToPC(oPC,"EFFECT_TYPE_DARKNESS"); break; case EFFECT_TYPE_DEAF: SendMessageToPC(oPC,"EFFECT_TYPE_DEAF"); break; case EFFECT_TYPE_DISEASE: SendMessageToPC(oPC,"EFFECT_TYPE_DISEASE"); break; case EFFECT_TYPE_DOMINATED: SendMessageToPC(oPC,"EFFECT_TYPE_DOMINATED"); break; case EFFECT_TYPE_ENTANGLE: SendMessageToPC(oPC,"EFFECT_TYPE_ENTANGLE"); break; case EFFECT_TYPE_ETHEREAL: SendMessageToPC(oPC,"EFFECT_TYPE_ETHEREAL"); break; case EFFECT_TYPE_FRIGHTENED: SendMessageToPC(oPC,"EFFECT_TYPE_FRIGHTENED"); break; case EFFECT_TYPE_HASTE: SendMessageToPC(oPC,"EFFECT_TYPE_HASTE"); break; case EFFECT_TYPE_INVISIBILITY: SendMessageToPC(oPC,"EFFECT_TYPE_INVISIBILITY"); break; case EFFECT_TYPE_ULTRAVISION: SendMessageToPC(oPC,"EFFECT_TYPE_ULTRAVISION"); break; case EFFECT_TYPE_SANCTUARY: SendMessageToPC(oPC,"EFFECT_TYPE_SANCTUARY"); break; case EFFECT_TYPE_SILENCE: SendMessageToPC(oPC,"EFFECT_TYPE_SILENCE"); break; } } void main() { object oPC = GetEnteringObject(); int ii=0; while(ii<20) { effect eEffet; switch(d20()) { case 0: eEffet = EffectAbilityDecrease(ABILITY_CHARISMA,1); break; case 1: eEffet = EffectACDecrease(1); break; case 2: eEffet = EffectAttackDecrease(1); break; case 3: eEffet = EffectBlindness(); break; case 4: eEffet = EffectCharmed(); break; case 5: eEffet = EffectConcealment(90); break; case 6: eEffet = EffectConfused(); break; case 7: eEffet = EffectCurse(); break; case 8: eEffet = EffectDarkness(); break; case 9: eEffet = EffectDeaf(); break; case 10: eEffet = EffectDisease(DISEASE_SHAKES); break; case 11: eEffet = EffectDominated(); break; case 12: eEffet = EffectEntangle(); break; case 13: eEffet = EffectEthereal(); break; case 14: eEffet = EffectFrightened(); break; case 15: eEffet = EffectHaste(); break; case 16: eEffet = EffectInvisibility(INVISIBILITY_TYPE_NORMAL); break; case 17: eEffet = EffectUltravision(); break; case 18: eEffet = EffectSanctuary(20); break; case 19: eEffet = EffectSilence(); break; } AfficherTypeEffet(eEffet,oPC); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eEffet,oPC,60.0); ii++; } SendMessageToPC(oPC,"==================================="); effect eEffet = GetFirstEffect(oPC); while(GetIsEffectValid(eEffet)==TRUE) { AfficherTypeEffet(eEffet,oPC); eEffet = GetNextEffect(oPC); } SendMessageToPC(oPC,"==================================="); } |
Revenir en haut | |
lendraste Grand Maître Chanteur du Conseil Messages: 1403 Localisation: Quelque part ailleurs |
nunch a écrit : J'ai fait un petit script qui applique aléatoire un vingtaine d'effet à un PJ, un même effet pouvant être appliqué plusieurs fois.
Merci pour ce test
Lorsque les effets sont parcourus avec GetFirstEffect() et GetNextEffect(), ils ne sont pas restitués dans l'ordre. Par contre ils ont tendance à être regroupés par type, même si ce n'est pas toujours vrai. Donc nous pouvons en conclure que la liste des effets est aussi bordelique que celle des joueurs (GetFirstPC(), GetNextPC()) ou celles des inventaires (GetFirstItemInInventory(), GetNextItemInInventory() )... L'identifiant miracle d'un Effect n'est donc pas pour demain _________________ Lendraste de Loreval Qui cherche la Vérité cherche celui qui la détient, car elle n'existe pas à l'état naturel. La cité des mensonges - 1 |
Revenir en haut | |
La Bibliothèque de Neverwinter Nights Index du Forum »
La Bibliothèque Binaire du NWScript - Neverwinter Nights
Page 1 sur 1 ¤
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum