La Bibliothèque de Neverwinter Nights
Aide et informations diverses sur Neverwinter Nights ainsi que D&D3.
La date/heure actuelle est 08/06/2024 21:26:18


  Page 1 sur 1 ¤

Voir le sujet précédent ¤ Voir le sujet suivant 
Auteur Message
Elanam Alarune
Novice
Inscrit le: 25 Juil 2004
Messages: 19
Localisation: Dans les Bas Fonds de Kemper, là où les korrigans dansent la gigue
Répondre en citant
Posté le : 24/01/2005 17:11:52 Sujet du message : Baguette d'entropie (effets aléatoires)

Bonjour tout le monde !
J'aurais aimé faire une baguette magique d'entropie qui lance des sorts aléatoirement.
Malheureusement, mon script ne marche pas mais je ne sais pas pourquoi. Je prend la baguette en question et l'utilise contre quelqu'un mais rien ne se passe. Pouvez-vous m'aider ?

Voici le script qui est mis dans le OnActiveItem du module

NWScript :
//baguette d'entropie
//a placer dans OnActiveItem du module

void main()
{
object oBag = GetItemActivated ();
object oPC = GetFirstPC ();
object oTarget = GetAttemptedSpellTarget ();
int nTruc;

int e1=SPELL_CONE_OF_COLD;
int e2=SPELL_CONFUSION;
int e3=SPELL_PROTECTION__FROM_CHAOS;
int e4=SPELL_POISON;
int e5=SPELL_SLEEP;

  if (oBag == GetObjectByTag("bagentr"))
  {

  nTruc=Random(4)+1;


  switch (nTruc)
  {
  case 1 :
    ActionCastSpellAtObject (e1, oTarget);
    break;
  case 2:
    ActionCastSpellAtObject (e2, oTarget);
    break;
  case 3:
    ActionCastSpellAtObject (e3, oTarget);
    break;
  case 4 :
    ActionCastSpellAtObject (e4, oTarget);
    break;
  case 5 :
    ActionCastSpellAtObject (e5, oTarget);
  }
}
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.



Voila. Si jamis quelqu'un a une idée, merci d'avance.
_________________
Nous sommes des héros, Bouh ! Les rodeurs et les hamsters, partout, content nos exploits !
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Athanagorn
Acolyte
Inscrit le: 12 Déc 2004
Messages: 38
Répondre en citant
Posté le : 24/01/2005 17:31:33 Sujet du message :

Ton oTarget, ce doit être la cible de la baguette, pas la cible du sort... Je m'explique, parceque j'ai pas l'impression d'être clair.

Dans ta ligne object oTarget = GetAttemptedSpellTarget(); le sort n'est pas encore lancé, donc il n'y a pas de cible. GetAttemptedSpellTarget() doit être utilisé seulement pen,dant les combats.
Utilise plutôt object oTarget = GetItemActivatedTarget(); pour déterminer la cible de l'activation d'un item.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Elanam Alarune
Novice
Inscrit le: 25 Juil 2004
Messages: 19
Localisation: Dans les Bas Fonds de Kemper, là où les korrigans dansent la gigue
Répondre en citant
Posté le : 24/01/2005 20:24:07 Sujet du message :

Merci Athanagorn

En effet j'avais cru comprendre ça de la fonction mais je n'avais pas trouvé mieux. Merci donc de ta solution (apparement j'avais pas assez cherché Razz) Je vais la tester tout de suite.
_________________
Nous sommes des héros, Bouh ! Les rodeurs et les hamsters, partout, content nos exploits !
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Elanam Alarune
Novice
Inscrit le: 25 Juil 2004
Messages: 19
Localisation: Dans les Bas Fonds de Kemper, là où les korrigans dansent la gigue
Répondre en citant
Posté le : 25/01/2005 12:55:31 Sujet du message :

Re-bonjour

J' ai essayé avec la dite fonction mais ça ne marche toujours pas. J'ai aussi testé de lancer les sorts avec ActionCastSpellAtLocation sur GetLocation(oTarget) maisrien non plus de ce coté. Je ne vois vraiment pas ce qui déconne.

Si quelqu'un a une idée, il est le bienvenu
_________________
Nous sommes des héros, Bouh ! Les rodeurs et les hamsters, partout, content nos exploits !
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Athanagorn
Acolyte
Inscrit le: 12 Déc 2004
Messages: 38
Répondre en citant
Posté le : 25/01/2005 15:13:20 Sujet du message :

Ta ligne if (oBag == GetObjectByTag("bagentr")) est probablement fausse.

Ici, tu compares deux objets ( celui retourné par GetItemActivated() et celui retourné par GetObjectByTag("bagentr") ). Ce que tu veux, c'est probablement comparer le tag de l'objet oBag avec "bagentr". La condition est donc:
if (GetTag(oBag) == "bagentr")

Ta condition initiale ne marchera que s'il y a un et un seul item de tag "bagentr" dans le module.
On ne va quand même pas revenir sur le fonctionnement de GetObjectByTag... Et puis si, tiens.

A propos du fonctionnement du serveur (hypothèses, je n'ai pas accès au code source. Mais ce sont des solutions probables)
Le programme fonctionne apparemment avec un ensemble de listes (chaînées) répertoriant les objets contenus dans le module. Quand un objet est ajouté au module, il est inclus dans les listes auxquelles il affère.
Quand un objet entre dans une zone, il est ajouté dans la liste des objets inclus dans la zone.
Quand un objet sort d'une zone, il est retiré de la liste des objets inclus dans la zone.
Si une créature est crée, elle va être ajoutée à la liste des objets de type créature.
Si une créature est détruite, elle va être supprimée de la liste des objets de type créature.
De même pour tous les types d'objets possibles et imaginables. Chaque objet ayant un inventaire possède aussi probablement une liste des objets de l'inventaire, etc.

Il est probable que ces listes sont de type « ajout en tête de liste, retrait n'importe où », car c'est la solution la plus simple (en terme d'implémentation), mais elles pourraient tout aussi bien être des tables de bases de données (mais je maîtrise pas vraiment ces dernières, et l'absence de DB dans la version initiale de NWN laisse à penser que c'est un ajout ultérieur).

Donc, quand un objet est ajouté dans une liste, il prends l'index 0 dans cette liste. Les autres objets de la liste voient leurs index augmentés de 1.

Lors de l'appel à GetObjectByTag(sTag, nNth), le programme va parcourir ces listes pour essayer de trouver un objet correspondant aux critères demandés, à savoir le nNth objet de tag sTag dans les listes. Il va parcourir ces listes dans un ordre précis qui est indiqué dans nwnlexicon : D'abord les objets de la zone (area), puis si l'objet n'est pas trouvé dans la zone, les listes d'objets de type :
OBJECT_TYPE_STORE (128)
OBJECT_TYPE_PLACEABLE (64)
OBJECT_TYPE_WAYPOINT (32)
OBJECT_TYPE_AREA_OF_EFFECT (16)
OBJECT_TYPE_DOOR (Cool
OBJECT_TYPE_TRIGGER (4)
OBJECT_TYPE_ITEM (2)
OBJECT_TYPE_CREATURE (1)

Dans le cas ou tu veux obtenir un objet particulier mais de tag non unique, il est donc très difficile de connaître le numéro d'ordre de l'objet, et donc d'être sûr de l'obtenir par GetObjectByTag.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Elanam Alarune
Novice
Inscrit le: 25 Juil 2004
Messages: 19
Localisation: Dans les Bas Fonds de Kemper, là où les korrigans dansent la gigue
Répondre en citant
Posté le : 25/01/2005 17:09:29 Sujet du message :

Ok, je crois avoir a peu près compris.
Je te remercie pour ton aide et vais essayer cela tout de suite.
_________________
Nous sommes des héros, Bouh ! Les rodeurs et les hamsters, partout, content nos exploits !
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
lendraste
Grand Maître Chanteur du Conseil
Inscrit le: 20 Fév 2003
Messages: 1403
Localisation: Quelque part ailleurs
Répondre en citant
Posté le : 25/01/2005 17:11:34 Sujet du message :


Elanam Alarune a écrit :
Bonjour tout le monde !
J'aurais aimé faire une baguette magique d'entropie qui lance des sorts aléatoirement.
Malheureusement, mon script ne marche pas mais je ne sais pas pourquoi. Je prend la baguette en question et l'utilise contre quelqu'un mais rien ne se passe. Pouvez-vous m'aider ?

Voila. Si jamis quelqu'un a une idée, merci d'avance.
Une et même plusieurs idées. Car il y a un nombre de points importants à considérer outre ceux soulevés par Athanagorn. Le problème du test du tag n'était pas le seul encore en lice. Il y a celui du ActionCastSpellAtObject.

Dans un premier temps il faut savoir que toute fonction de type ActionTruc (truc représentant un nombre assez important de possibilités offertes par NWN Script) ne peut s'exécuter que dans une queue d'action.

Aaah ! La queue d'action ! Le système le plus impitoyablement méconnu ou incompris de NWN Script et pourtant l'un des plus puissants. Mais je m'égare...

Le script dont il est question ici est déclenché par un évènement du module, OnActivateItem. Or, toute fonction ActionTruc s'exécute par défaut en s'ajoutant à la queue d'action de l'objet qui a lancé le script. Et là, l'objet qui a lancé le script est... (suspens)... le MODULE... N'y a-t-il pas une certaine incohérence à faire en sorte que "le module lance un sort" ? Si le module avait une quelconque représentation physique virtuelle dans l'univers visuel de NWN, ça aurait du sens, mais le module est une entité abstraite, un objet générique et globale qui représente le module en cours d'exécution sur le serveur et rien de plus. Donc un module ne peut pas lancer un sort. Par ailleurs, tu as de la chance que ton script n'ait pas fait planté NWN car jusqu'à la 1.64 (à vérifier), le fait d'affecter une action à la queue d'action du module faisait planter le jeu (à moins que je confonde avec la queue d'action des zones, mais en tout état de cause, c'est aussi inutile que dangereux).

Donc, la première chose à déduire est que le ActionCastSpellAtObject doit être affecté à une autre queue d'action. Mais laquelle ? Et comment ?
Laquelle ? C'est facile de répondre. Celui qui active l'objet devrait être le "lanceur" du sort. Donc le personnage donné par GetItemActivator().
Comment ? Il existe une fonction qui permet d'affecter à un autre objet l'exécution de n'importe quelle fonction de NWN Script, la fonction AssignCommand.

Mais il y a un autre problème encore présent, cette fois dans le paramètrage des ActionCastSpellAtObject. Car, cette action déclenche l'action de lancer un sort, c'est-à-dire de l'incanter et d'en déclencher les effets comme si le personnage était mage. Mais si le personnage n'a pas la capacité de lancer le sort, l'action ne déclenchera aucun processus. Et s'il l'a, c'est en fait l'un de ses propres sorts que le personnage lancera et non comme s'il s'agissait d'un pouvoir issu de la baguette. Ce double problème se résoud en utilisant tous les paramètres de la fonction.
Un exemple d'appel pourrait être :
NWScript :Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Le troisième paramètre concerne les effets de metamagie associé au sort. La valeur que j'ai mise n'en met aucun.
Le quatrième paramètre et l'un de ceux qui nous intéresse. C'est celui qui permet de demander à la fonction de lancer le sort même si le personnage "lanceur" ne le maîtrise pas ou ne le possède pas en mémoire.
Le cinquième est peut-être débuggé, mais ma version du lexicon m'indiquait que ce n'était pas le cas. Il faudra peut-être le considérer car c'est le niveau de lanceur de sort auquel le sort est lancé. En gardant la valeur par défaut (0), il prendra le niveau du personnage, mais il est dit dans le lexicon que préciser la valeur ne change rien. De ce fait, les sorts lancés voit leur puissance calculée en fonction du niveau du personnage ce qui n'est pas forcément intéressant.
Le sixième paramètre risque de changer le comportement du sort, mais il n'existe pas de valeur "nulle" et comme nous avons besoin du paramètre suivant, nous nous devons de spécifier celui-ci.
Le septième paramètre permet de lancer un sort "instantanné", c'est-à-dire sans incantation, ce qui n'est pas mal compte tenu du fait que le sort est sensé être issu de la baguette, il serait louche que le personnage se mette à incanter par la suite.


Il reste toutefois un problème potentiel lié à ce mode d'utilisation (à croire qu'il n'y a que des problèmes à faire ça Smile ). Le fait d'affecter une action sur la queue d'action est soumis à une règle qui ne peut être transgressée :

axiome de base a écrit :

Toute action ajoutée à une queue d'action est ajoutée à la fin de la queue d'action.
Ca signifie que, entre le moment où le personnage active l'objet (qui n'est pas une action instantannée) et le moment où le script va ajouter l'action de lancement du sort sur le personnage, il se peut que quelques actions se soient imiscée. C'est assez facile à faire en fait. Il suffit, par exemple, d'enchainer des actions de lancement de sort. Un coup la baguette est utilisée, et les sorts qui sont lancé ensuite sont placé dans la queue d'action en attendant de pouvoir s'exécuter. Et bien le problème est alors le suivant, lors de l'exécution du script lié à l'activation de la baguette, l'action créé peut se retrouvée placée après d'autres actions que le joueur a préparé. Patatra... Ben oui, le lancement effectif du sort entropique va se retrouvé différé du fait de cette accumulation d'action.

Il existe un moyen sûr, mais pas propre, de pallier ce problème. Avant d'insérer notre action, on s'assure que la queue d'action est vide en la vidant (ClearAllActions). Ce n'est pas propre, car le joueur qui a préparé plein d'action à suivre tellement il est rapide avec son clavier et sa souris, va voir sa liste purement et simplement annulée pour que l'effet de la baguette se produise bien au moment de l'utilisation de celle-ci.

Ainsi en combinant le AssignCommand et ces informations (ainsi que les remarques précédentes) le script devrait ressembler à ça (je me suis permis d'optimiser un peu pour éviter les répétitions de commandes) :

NWScript :
//baguette d'entropie
//a placer dans OnActivateItem du module

void main()
{
  object oBag = GetItemActivated();
  object oCaster = GetItemActivator();
  object oTarget = GetItemActivatedTarget();
  int nTruc;
  int nSpell;

  int e1=SPELL_CONE_OF_COLD;
  int e2=SPELL_CONFUSION;
  int e3=SPELL_PROTECTION__FROM_CHAOS;
  int e4=SPELL_POISON;
  int e5=SPELL_SLEEP;

  if (GetTag(oBag) == "bagentr")
  {
    nTruc=Random(5)+1;
    switch (nTruc)
    {
      case 1 : nSpell = e1; break;
      case 2 : nSpell = e2; break;
      case 3 : nSpell = e3; break;
      case 4 : nSpell = e4; break;
      case 5 : nSpell = e5; break;
    }
    AssignCommand(oCaster, ClearAllActions(TRUE));
    AssignCommand(oCaster, ActionCastSpellAtObject(nSpell, oTarget, METAMAGIC_NONE, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE));
  }
}
Note : le code affiché ci-dessus n'est pas rendu tel qu'il devrait l'être réellement, en particulier des sauts de lignes sont automatiquement insérés pour éviter de casser la mise en page. En le copiant/collant, vous résoudrez ce problème.


Petite précision : je n'ai pas testé du tout ce script. Il se peut que quelque chose d'autre m'ait échappé. Par ailleurs, compte tenu du désagrément causé par le ClearAllActions, il serait peut-être intéressant de chercher une autre solution.
_________________
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 Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Numéro ICQ Ignorer l'utilisateur
 
Athanagorn
Acolyte
Inscrit le: 12 Déc 2004
Messages: 38
Répondre en citant
Posté le : 25/01/2005 19:13:08 Sujet du message :


lendraste a écrit :
Par ailleurs, compte tenu du désagrément causé par le ClearAllActions, il serait peut-être intéressant de chercher une autre solution.
Solution 1: Si l'item a une queue d'action (à vérifier, possiblement avec GetCommandable() ?), ajouter l'action à sa queue d'action.
Solution 2: Créer un placeable invisible, et lui affecter l'action de lancer le sort.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
lendraste
Grand Maître Chanteur du Conseil
Inscrit le: 20 Fév 2003
Messages: 1403
Localisation: Quelque part ailleurs
Répondre en citant
Posté le : 25/01/2005 19:25:37 Sujet du message :


Athanagorn a écrit :
Solution 1: Si l'item a une queue d'action (à vérifier, possiblement avec GetCommandable() ?), ajouter l'action à sa queue d'action.
C'est rigoureusement impossible. Un item d'inventaire n'a pas de queue d'action. De plus un item d'inventaire ne peut pas exécuter de script du tout.


Citation :
Solution 2: Créer un placeable invisible, et lui affecter l'action de lancer le sort.
Un placeable n'a pas la capacité de lancer des sorts. J'ignore donc si une ActionCastSpell peut marcher sur lui. Si toutefois ça marche, ce n'est pas la solution idéale. Avec un PNJ invisible, on saurait sûr de pouvoir le faire, mais c'est assez lourd.

Je n'ai pas eu le temps de réfléchir à la question, mais je pense qu'il existe un moyen de déclencher un effet de sort comme s'il était lancé sans pour autant être contraint d'user du principe évoqué ci-dessus. A l'occasion, je verrai si ça me parle. Comme ça, la solution ne me vient pas.
_________________
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 Voir le profil de l'utilisateur Envoyer un message privé MSN Messenger Numéro ICQ Ignorer l'utilisateur
 
Athanagorn
Acolyte
Inscrit le: 12 Déc 2004
Messages: 38
Répondre en citant
Posté le : 25/01/2005 23:25:34 Sujet du message :


Citation :

Citation :
Solution 2: Créer un placeable invisible, et lui affecter l'action de lancer le sort.
Un placeable n'a pas la capacité de lancer des sorts. J'ignore donc si une ActionCastSpell peut marcher sur lui. Si toutefois ça marche, ce n'est pas la solution idéale. Avec un PNJ invisible, on saurait sûr de pouvoir le faire, mais c'est assez lourd.
L'exemple dans le nwnlexicon pour ActionCastSpellAtObject est dans le OnUsed d'un placeable, et le lancement du sort est bien réalisé par le placeable (OBJECT_SELF), et non pas par l'utlisateur, donc ça devrait être bon. Mais je n'ai pas le temps de tester, en ce moment.


Citation :

Je n'ai pas eu le temps de réfléchir à la question, mais je pense qu'il existe un moyen de déclencher un effet de sort comme s'il était lancé sans pour autant être contraint d'user du principe évoqué ci-dessus. A l'occasion, je verrai si ça me parle. Comme ça, la solution ne me vient pas.
On peux appliquer directement les effets des sorts à l'aide de la fonction ApplyEffectToObject() et de la série des foncions Effect*(), mais certains sorts ont plusieurs effets, et GetEffectSpellId() retournera -1 au lieu d'une valeur correspondant au sort lancé.
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Elanam Alarune
Novice
Inscrit le: 25 Juil 2004
Messages: 19
Localisation: Dans les Bas Fonds de Kemper, là où les korrigans dansent la gigue
Répondre en citant
Posté le : 27/01/2005 14:57:37 Sujet du message :

Je vous remercie tous les deux pour vos aides précieuses. Je n'ai pas encore eu le temps de tester mais j'avais déjà essayé à utiliser la queue d'action et je n'avais pas vu de différences. Toutefois, il est possible que j'ai fait une erreur quelque part aussi je m'en vais de ce pas essayer le script de Lendraste.
_________________
Nous sommes des héros, Bouh ! Les rodeurs et les hamsters, partout, content nos exploits !
 
Revenir en haut Voir le profil de l'utilisateur Envoyer un message privé Ignorer l'utilisateur
 
Montrer les messages depuis :
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


Sauter vers:
FAQ | Rechercher | Liste des Membres | Groupes d'utilisateurs | S'enregistrer | Profil | Se connecter pour vérifier ses messages privés | Connexion
Powered by phpBB 2.* [m] © 2001, 2002 phpBB Group
Theme rewritten in beautiful XHTML code by Baldurien.
Thème "La Bibliothèque de Neverwinter" crée par Kruger
Traduction par : phpBB-fr.com
Page generated in 36.744ms