Berzerk, orage et tournée de whisky.

Répondre
Partager Rechercher
Non, il ne s'agit pas là du titre d'un nouveau film, mais de trois problèmes que je souhaiterais exposer aux plus sagaces d'entre vous.

- le premier concerne l'éventuelle possibilité de faire rentrer un personnage non joueur en rage barbare. Dans les constantes NWScript, j'ai bien découvert un "SPELLABILITY_BARBARIAN_RAGE" mais je ne vois pas comment on peut l'appliquer au personnage ; ApplyEffect, en tout cas, ne fonctionne pas.

- le second sera très court : connaissez-vous un effet visuel qui puisse rendre l'écran tout à fait blanc pendant un très cours laps de temps, un peu comme l'éclair des conditions météorologiques du jeu.

- le troisième est beaucoup plus complexe, j'avoue avoir longtemps travaillé dessus sans trouver de solution. Bref exposé de la situation : dans un bar, cinq clients se promènent aléatoirement, avec chacun un Tag bien défini. A un instant donné, tournée générale ! Chacun s'arrête, et le serveur fait le tour pour donner à chacun une bouteille. Mais, comme c'est un serveur très intelligent, il suit bien sûr le chemin le plus court, allant d'abord au client le plus proche, puis au plus proche de celui-ci, et cetera...

Et là, groBe Katastrophe !
- GetNearestCreature fait osciller le serveur entre les deux premiers clients.
- si l'on ajoute une condition sur la possession de la bouteille, le serveur ne servira pas deux fois le même mais il s'arrêtera après le deuxième client.
- essayer de régler cela avec les tags nous ramènera au problème de départ : le serveur risque d'avoir une trajectoire tout à fait irréaliste, la position des clients étant totalement aléatoire.

Bref, je suis tout à fait désemparé. L'un d'entre vous aurait-il une solution à ce problème ?
__________________
Où qu'est la bonne Pauline ? A la gare, à Passy...
-1 Essaye avec un CastSpell : la rage du barbare est gérée comme un sort.
(sinon, fais un ExecuteScript(oPC,"nw_s2_barbrage") ^^

-2 : Non, et je crois pas que ca fasse partie des VFX selectionnables

-3 : Comme reyan : fais voir ton script ^^
Désolé pour mon absence, j'ai eu des problèmes professionnels et d'ordinateur. le script, c'était :

Code PHP:

void main()
{

int i 0;
for(;
i<=6;i++)
{
object oAyf=GetObjectByTag("Ayf");//c'est  le  serveur
object oClient=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oAyf,1);
if (
GetIsObjectValid(GetItemPossessedBy(oClient,"NW_IT_MPOTION022")))//l'alcool  que  j'ai choisi de  leur donner
{//rien  ne  se  passe
}
else{
AssignCommand(oAyf,ActionMoveToObject(oClient));
CreateItemOnObject("NW_IT_MPOTION022");}


}

Il compile bien, mais le problème est qu'après le premier client servi, le plus client est celui que le serveur vient tout juste de servir, et donc il a l'objet dans l'inventaire, et donc le script ne s'exécute plus.
Ho mais c'est pas des conditions pour débugger ça
Alors voyons ce que ça donne quand c'est un peu arrangé :

Code PHP:

void main()
{
    
int i;
    for(;
i<=6;i++)
    {
        
object oAyf=GetObjectByTag("Ayf");                                                  //c'est  le  serveur
        
object oClient=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oAyf,1);

        if(!
GetIsObjectValid(GetItemPossessedBy(oClient,"NW_IT_MPOTION022")))             //l'alcool  que  j'ai choisi de  leur donner
        
{                                                                        //( je me suis permis de clarifier un peu ton test, )
            
AssignCommand(oAyf,ActionMoveToObject(oClient));                      //( parcequ'un if(a){rien}else{...} ça donne aussi : if(!a){...} )
            
CreateItemOnObject("NW_IT_MPOTION022");
        }
}

Alors après un premier examen, je dirais que l'utilisation d'un CreateItemOnObject (dont un paramètre manque d'ailleurs) ici n'est pas forcément idéal.
En fait, le problème c'est que les potions sont crées instantanément sur les clients, et non quand le serveur vient les voir.
D'après moi le mieux serait d'utiliser ActionGiveItem afin que l'action de donner l'alcool se mette à la suite de la chaine d'action du serveur.
Par contre je sais pas si il faut que le serveur possède l'objet pour le donner (bon ok comme ça ça a l'air stupide ), et si oui ça risque de compliquer les choses pas mal.
Et puis c'est pas sûr que ça résolve le problème

Taern, qui parle alors qu'il devrait p'tet pas
Ya ya ya, this script peut pas marcher (oui je suis en train de réviser mon anglais, oui y a encore des progrès à faire... ).

En fait c'est l'algorithme lui-même qui est faussé : il n'y a pas de DelayCommand() donc tous les GetNearest() tombent sur les mêmes objets...

Je te propose plutôt ceci (attention c'est un algorithme généraliste, sans doute optimisable) :

Code PHP:

// © Jedaï

void main()
{
    
int nNumber 2;
    
object oAyf=GetObjectByTag("Ayf");
    
object oClient GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oAyf,1);
    
object oBouteille;
    
    while ( 
GetIsObjectValid(oClient))
    {
        
oBouteille CreateItemOnObject("NW_IT_MPOTION022"oAyf);
        
AssignCommand(oAyfActionMoveToObject(oClient));
        
AssignCommand(oAyfActionGiveItem(oBouteilleoClient));
        
oClient GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oAyfnNumber++);
    }

Valà
Optimisable ouais mais pas de beaucoup

Code PHP:

// © Taern (inspiré par Jedaï ^^)

void main()
{
    
int nNumber;
    
object oAyf GetObjectByTag("Ayf");
    
object oClient;
    
object oBouteille;    
    do
    {
        
oClient GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oAyfnNumber++);
        
oBouteille CreateItemOnObject("NW_IT_MPOTION022"oAyf);
        
AssignCommand(oAyfActionMoveToObject(oClient));
        
AssignCommand(oAyfActionGiveItem(oBouteilleoClient));
    }
    while (
oClient != OBJECT_INVALID)

Ben en fait Jedaï appellait 2 fois la fonction GetNearestCreature, alors que c'était pas nécessaire

Et par la même occasion, on a plus besoin d'assigner 2 à nNumber, mais ça je te le concède c'est du pur pinaillement

Par contre y'a peut être un moyen de faire un scan plus précis avec les paramètres de GetNearestCreature ...
C'est bien d'essayer d'optimiser ça mais à vrai dire... Désolé mais c'est pas génial, pour plusieurs raisons :
_ indépendante de ta volonté : le do{}while() marche bizarrement avec le compilateur de Bioware (mauvais dépilage parfois...), il est plus prudent de ne pas l'utiliser
_ plus inquiétante : je suppose que nNumber est initialisé par défaut à 0 (à propos : c'est vraiment pas propre de ne pas l'initialiser !!), ce qui fait que ton premier GetNearest() rapportera le 0ème plus proche (car l'incrémentation est postfixe), or le décompte commence à 1 normalement. Je ne sais pas ce que rapporte GetNearest() avec 0 comme nNth mais j'éviterais une telle construction qui risque de m'interrompre la boucle à la première itération.

De plus je n'appelais pas 2 fois la fonction GetNearest(), mais exactement 1 fois de plus que le nombre de client dans la zone, ce que fait également ton code (en fait 2 fois de plus s'il marche vraiment). Je dirais donc que ton code n'est pas plus optimisé, il l'est sans doute moins....
Arf j'ai encore parlé trop vite

Pour le GetNearest, effectivement il est appelé autant de fois dans les deux cas, autant pour moi (mais bon il est écrit qu'une seule fois hein )

A propos du do-while, ben là tu m'apprend quelque chose parceque je n'ai jamais eu de problème avec ce type de boucle. Enfin bon disons que dans la théorie ça marche

Enfin, même chose pour l'incrémentation du nNumber : j'ai écris ça en supposant évidemment que l'incrémentation se faisait avant l'appel de fonction.
Et d'ailleurs le contraire m'étonnerait, vu que l'opération "++" est une opération comme les autres, n'est ce pas ?
Or si j'écris : if(a+1 == 1), l'opération "+" se fait ici de manière évidente avant le test.
Logiquement, on pourrait penser que : if(a++ == 1) revient exactement au même (mis à part que la valeur de a est modifiée dans ce cas), non ?

Bref, merci de m'éclairer ma lanterne
En fait je n'ai jamais essayé la version préfixée dans le NWScript mais il est certain qu'il se comporte comme je te l'ai dit car en C il existe en fait deux versions de cet opérateur d'incrémentation (et de l'opérateur de décrémentation correspondant) : la version préfixe et la version postfixe, notée respectivement :
Code PHP:

++variable
et
Code PHP:

variable++; 

La différence tient au "moment où est fait l'incrémentation, avant ou après qu'on renvoie la valeur, prenons un exemple :
Code PHP:

int a 10;
int b a++; 
Après ceci, a vaudra 11 mais b vaudra 10.

Code PHP:

int a 10;
int b = ++a
Après cette opération là, b et a vaudront tout deux 11.

Je pense donc que le comportement est identique en NWScript, bien que je n'ai pas fait de test, j'ai suffisamment utilisé cet opérateur pour penser qu'il se comporte bien ainsi.
Mhennnn.... mais c'est hyper chouette ça... Mheenn

Jedaï, puit de connaissance, grand gourou du C, disponible en exclusivité sur Maskado,... et en plus il mord pô


Concernant l'éclair, ya pô photo, faut créer un nouveau VFX repris sur l'original. Vu que ce dernier est un effet qui s'applique de manière personnelle sur son PJ (on est seul à pouvoir le voir, les autres PJ ont le leur), je ne saurais dire de quel façon le VFX créé devrait être appliqué dans la zone ni même quelle taille il devrait faire...
Répondre

Connectés sur ce fil

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