Bienvenue sur JeuxOnLine - MMO, MMORPG et MOBA !
Les sites de JeuxOnLine...
 

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

[bibliothèque]Préprogrammer des chaines d'actions

Par Azrael07 le 25/1/2003 à 21:53:23 (#3100531)

C'est une des bibliothèques dont je me sert pour mon module, et l'une des rares qui est facilement adaptable, alors je la publie(a tant faire ^_^).

Son principe est simple, son utilisation n'est pas trop compliquée, sa réalisation a été carement galère lol

Le but de cette bibliothèque est d'enregistrer une liste d'action (vi ces actions qui ce mettent les unes a la suite des autres), pour ensuite être appliqué à n'importe quel pnj. L'interet, en plus de celui de la préprogramation de la chaine, est que la chaine d'action peut être interompue et reprise sans problèmes.
Immaginez la scène : on donne a un pnj les actions d'aller d'un bout a l'autre du module de facon a ce qu'il emprinte les routes et qu'il passe d'area en area. Le pnj va se retrouver avec une liste d'action en attente impressionnante, mais s'il rencontre un monstre en chemin et est tenu de se defendre, sa liste d'action est complètement perdue et tout est a reprogrammer. Avec les chaines d'actions que permet cette bibliothèque, l'appel d'une seule fonction permetra de tout restaurer, et le pnj reprendra ses actions la ou il les avait arreté.

j'ai grosso modo explquer comment utiliser la bibliothèque dans les commentaires, si une réelle utilisation de cette bibliothèque au sein d'un module interesse quelqu'un, faite moi le savoir je publirais les mises a jour.

Je l'ai testée et elle marche sur toutes les situations que j'ai testé, mais je n'ai pas essayé toutes les fonction ATS, il est possible que certaine bug. Si c'est le cas faite moi le savoir, merci :)

Arf la bibliothèque est trop grosse pour rentrer en entier :/

bon ben je la met sur mon ftp alors ^^

elle est ICI

Par Archamedes_Fr le 25/1/2003 à 21:59:47 (#3100560)

Wow... Que dire... Que tout cela s'avère fort intéressant !

Merci de nous faire partager le résultat de tes sueurs. D'autant qu'effectivement, j'étais confronté au problème que tu décris :D . :merci: :merci:

Par Jaha Effect le 25/1/2003 à 22:53:01 (#3100844)

Bon bha je vais tester ça moi :)
Je sais pas ce que j'ai à torturer les créations de mes camarades en ce moment :)
Surement parce que je les trouvent géniales en tout cas je suis heureux de voir autant de créativité ici ;)

Jaha Effect :D

Par Azrael07 le 26/1/2003 à 15:12:53 (#3103581)

ouaip par contre j'ai pas pu configurer certaines actions. Certaines le seront dans une prochaine version, d'autres ne le seront pas du tout, pour une raison très simple :

Ma bibliothèque retient les actions en utilisant une variable INT pour ce souvenir de son type, et de plusieurs variables pour enregistrer les arguments qu'elle prend. Or, ben y'a des type de variables qui peuvent pas etre enregistrés. La plus évidente est les fonctions bien sur, ce qui supprime définitivement la fonction ActionDoCommand du lot.

Dans le meme genre, on a les fonctions ActionUseTalentAtObject et ActionUseTalentAtLocation, mais qui ne sont pas necessaire, puisqu'on peut largement utiliser a la place ATSUseFeat, ATSUseSkill et ATSCastSpell

voila, tout ca sera mis en place dans une version qui ne devrais pas trop tarder a arriver.

par contre, pour le ActionDoCommand, si quelqu'un a une idée, moi je ne pense pas que ce soit possible...

Par Jaha Effect le 26/1/2003 à 17:48:21 (#3104602)

Tu pourrais nous donner quelques exemples de chaines d'actions avec la manière que tu les scriptes, stp.
Ou peut être un petit mod de demo...

Jaha Effect :D

Par Azrael07 le 26/1/2003 à 18:24:11 (#3104881)

ah ouaip bien sur ^_^' ou avais je la tete

je met ca on line ce soir, avec une version plus complète :)

Par Jaha Effect le 26/1/2003 à 18:55:19 (#3105129)

merci :)

Jaha Effect :D

Par Azrael07 le 26/1/2003 à 22:13:04 (#3106797)

bon voila un petit tutorial pour aller avec la nouvelle version de la bibliothèque.

Je conseille a tout le monde de lire jusqu'au bout le tutorial, vous allez vous rendre compte que cette bibliothèque permet DE TRES NOMBREUSES CHOSES.

la dernière version de la bibliothèque est dispo ICI, /!\ liens différent de celui du haut /!\

L'utilisation d'une chaîne d'action se fait en plusieurs temps :

1) L'initialisation

2) Le lancement

3) La modification / affectation

4) Destruction de la chaîne d'action

pour bien utiliser ce système il faut dans un premier temps en comprendre le fonctionnement général.
Les actions, lors de l'initialisation sont enregistrées dans des variables locales, pour ensuite être réutilisées lors du lancement. Puisque plusieurs chaînes d'actions peuvent être crées, chacune d'entre elle est définie par un numéro (son pointeur) qui permet de la retrouver parmi les autres.
Lors de la création de la première chaîne d'action celle si recevra donc le numéro 1, la deuxième aura le numéro 2, etc.

Chaque actions sera ensuite crées dans cette chaîne, et chacune de ces actions portera elles aussi un numéro identifiant leurs position.(donc idem, la première aura le numéro 1, etc)

Si ce principe de numéro est très facilement gérable quand il y a peu de chaînes et d'action dans ces chaînes, cela devient beaucoup plus compliqué a gérer si il y a beaucoup de chaînes, c'est pourquoi j'ai prévu des fonctions ayant pour but de retrouver ces pointeurs.

Pour initialiser une chaîne, il faut dans un premier temps la créer, on va pour cela utiliser la fonction CreateActionStruct. Cette fonction n'attend pas d'argument, et renvoie le pointeur de la structure nouvellement créée.
ex :

int pActionStruct = CreateActionStruct();


on notera que j'utilise le p plutôt que le n devant la variable car elle désigne un pointeur et non pas une variable int cherchant a donner une valeur numérique simple.
une fois cette structure créée, on va initialiser les actions qui vont être effectuées par cette structure.
Cela se déroule de la même façon que lorsque vous "programmez" un pnj longtemps a l'avance avec une suite de fonction de type Action*, a la différence prêt que les fonctions utilisées ici utilisent un argument en plus, le pointeur vers la structure.
Les actions a programmer utilisent les mêmes fonction que les actions standard, si ce n'est qu'elle porte le nom de ATS*

plutôt que Action*
ex:
ATSMoveToObject(pActionStruct, oTarget);
ATSAttack(pActionStruct, oTarget);
ATSCloseDoor(pActionStruct, oDoor);


tout comme les fonctions d'action normales, les fonctions d'action pour chaînes d'action utilise des paramètres par défaut
ex:
ATSMoveToObject(pActionStruct, oTarget);

correspond à:
ATSMoveToObject(pActionStruct, oTarget, TRUE);


pour finir, il est conseillé de mettre en lieu sur le pointeur vers la structure, car le perdre signifie perdre la structure elle même.
pour cela, deux solutions : ou bien on l'associe à une variable locale, qui peut porter un nom la représentant
ex: une structure ayant pour but de déplacer une créature d'une area X a une area Y pourra être enregistrée de la façon suivante:
SetLocalInt(oModule, "XversY", pActionStruct);


la deuxième solution consiste a l'associer directement a la créature qui va l'utiliser, alors on peut utiliser la fonction SetActionStruct.
ex:
SetActionStruct(oCreature, pActionStruct);


2)L'exécution :

dans un premier temps si l'exécution ne se fait pas dans le même fichier que l'initialisation(la première peut se faire dans le OnModuleLoad et la deuxième dans un OnUsed par exemple) il faut récupérer le pointeur vers la chaîne, avec un GetLocalInt si vous avez utilisez la première méthode, ou avec un GetActionStruct(oCreature) si vous avez utilisé la seconde

ensuite, deux façon d'exécuter sont possible :

la fonction EnqueueActionStruct place la chaîne d'action désigner à la suite de la file d'attente des actions de la créature

ex:
EnqueueActionStruct(pActionStruct, oCreature);


la seconde exécute la chaîne d'action en vidant les actions de la cible au préalable:

ExecuteActionStruct(pActionStruct, oCreature);


3)Modification / Ré affectation :


Ca y est, votre créature est partie. Vous pouvez maintenant effectuer divers actions sur la chaîne d'action, reprendre une chaîne d'action interrompue, et même affecter une chaîne d'action déjà utilisée a une autre créature.

Si la cible est interrompue dans son action (un combat, une utilisation de ClearAllActions, ect..) une simple réutilisation de la fonction ExecuteActionStruct permettra à la créature de reprendre ses actions la où elles s'étaient arrêtées.

Vous pouvez également modifier une chaîne d'action, remplacer une action par une autre, supprimer une action (mais hélas pas en insérer, il faudrait que je revoie tout le moteur dynamique pour pouvoir insérer cette option, donc n'ayez pas trop d'espoir la dessus, c'est peu probable).

Ajouter une action a la suite :
Les fonctions ATS* peuvent être utilisées bien après la création de la chaîne, et après l'affectation des autres fonctions ATS. Vous pouvez donc ajouter des actions a la suite de la chaîne quand vous le souhaitez.

Agir sur une action :


Pour agir sur une action, la possibilité la plus simple est probablement d'avoir le pointeur de cette action, mais l'obtenir n'est pas forcement évident.
Toute fonction ATS renvoie à son appel un pointeur vers la fonction nouvellement créé, vous pouvez donc enregistrer ce pointeur si l'action créée est susceptible d'être effacée.
ex:
int pMove = ATSMoveToObject(pActionStruct, oTarget);
SetLocalInt(oModule, "Mouvement", pMove);


si vous n'avez pas le pointeur, une fonction permet de le retrouver, mais celle ci est cependant limitée par le type, vous ne pourrez retrouver une action si elle est perdue au milieu d'action de même type.
J'ai représenté tout les types d'actions avec des constantes ACTION_TYPE_*

int pAction = GetFirstActionByType(pActionStruct, ACTION_TYPE_MOVE_TO_OBJECT);


Il faut savoir que cette fonction détruit la première action dans la chaîne, même si cette action a déjà été effectuée par le npc au moment de son exécution. Pour éviter cela, on va dans un premier temps utiliser la fonction GetCurrentActionInStruct qui va renvoyer un pointeur vers l'action qu'effectue actuellement la créature. Puis on va utiliser le troisième argument a la fonction GetFirstActionByType (par default a 1) qui definie le point de départ de la recherche.

ex:
int pCurrentAction = GetCurrentActionInStruct(oCreature);
int pAction = GetFirstActionByType(pActionStruct, ACTION_TYPE_MOVE_TO_OBJECT, pCurrentAction);


Maintenant que le pointeur vers la fonction a été trouvé, on peut y effectuer divers opérations:

Supprimer une action :

RemoveAction(pActionStruct, pAction);


Remplacer une action :

supprimer l'action revient a vider son emplacement, on peut alors mettre dans cet emplacement une autre action, et ainsi la modifier. On va alors utiliser un nouvel argument de la fonction de type ATS, qui lui permet de lui imposer une position de l'action plutôt que la laisser aller se positionner a la fin de la chaîne
ex: l'action pointée par pAction est un mouvement vers l'objet oObject1, on aimerais modifier se mouvement pour l'envoyer vers l'objet oObject2 :
RemoveAction(pActionStruct, pAction);
ATSMoveToObject(pActonStruct, oObject2, FALSE, 1.0f, pAction);


on notera qu'il faut réécrire tout les arguments par défaut précédents, comme le veut les règles du C.

IMPORTANT : les modifications a la chaînes seront transmise a la créature que par un rafraîchissement de cette chaîne d'action.
Pour qu'une modification de la chaîne d'action prenne effet sur une créature il faut donc impérativement rééxécuter la chaîne d'action sur celle-ci -> ExecuteActionStruct

4)La destruction de la chaîne d'action :

Une fois que toutes les opérations ont été effectués et toutes les actions de cette chaîne ont été réalisés, la chaîne peut et doit être détruite pour libérer les ressources qu'elle prend. cela ce fait par la simple fonction DeleteActionStruct
ex:
DeleteActionStruct(pActionStruct);


pour simplifier la destruction de cette chaîne on peut aussi utiliser un argument (par défaut a FALSE) des fonctions ExecuteActionStruct et EnqueueActionStruct, qui détruit automatiquement la chaîne d'action lorsque la créature a effectuée la totalité des actions de cette chaîne.
ex:
EnqueueActionStruct(oTarget, pActionStruct, TRUE);
ExecuteActionStruct(oTarget, pActionStruct, TRUE);


____________________________________________________________________________________

Voila pour l'explication des chaînes d'actions, je pense avoir été a peu près clair.

Vous avez du vous rendre compte de la puissance de cette bibliothèque, qui comble un gros trou laissé dans la gestion des actions des pnjs.

Une version future devrais apporter les quelques actions qui manquent encore a la liste des ATS (si ce n'est ATSDoCommand qui ne verra malheureusement jamais le jour) et permettre l'effacement des actions en même temps que leurs exécutions, utiles pour les chaînes d'action utilisées par une seule créature.

Une grande partie de la bibliothèque à été testé, mais les dernières fonctions créent ne l'on pas été, si ça ne marche pas ou que ça bug, prévenez moi ;)

Merci et bon courage a tous

Par Jaha Effect le 26/1/2003 à 23:15:08 (#3107249)

Tu aurais pas un scripte tout fait qui exploite ta bibliothèque pour compléter le cours, parce que ça reste quand même assez théorique et comme on dit rien ne vaux un bon exemple. :)

Jaha Effect :D

Par Azrael07 le 26/1/2003 à 23:19:44 (#3107291)

oki ben je fais ca demain, surtout pas ce soir je crois que je suis pas en état

Par eMRaistlin le 27/1/2003 à 0:43:35 (#3107845)

Azrael, t'es un boss :D

Merci a toi...

Par Skanzo Sylan le 27/1/2003 à 1:48:49 (#3108083)

Bon, j'ai simplement essayé le "XversY" :)

Le perso va bien à l'endroit quand je lui en donne l'ordre. Mais alors franchement, quand j'imagine les possibilités, c'est véritablement carrément superbement divin! :maboule:

J'vais tester quelques chaines d'actions plus complexe :D

#include "lib_actionstruct"

void main()
{
// declarations
object oWay = GetObjectByTag( "NW_WAYPOINT001");
object oModule = GetModule();

// initialise la chaine
int pActionStruct = CreateActionStruct();
// ajoute une action a la chaine
ATSMoveToObject( pActionStruct, oWay);

// sauvegarde
SetLocalInt( oModule, "XversY", pActionStruct);

}


#include "lib_actionstruct"

void main()
{
//declarations
object oPNJ = GetObjectByTag( "Mashal");
object oModule = GetModule();

// recupere le pointeur
int pActionStruct = GetLocalInt( oModule, "XversY");
// applique la chaine au PNJ qui l'execute aussitot
ExecuteActionStruct( oPNJ, pActionStruct);

}

Par Azrael07 le 27/1/2003 à 21:47:13 (#3114388)

alors j'ai fait une petite mise a jour de la bibliothèque, corrigant quelques bugs plus ou moins gros.

Un gros bug que j'ai (enfin plutot que Skanzo Sylan a) repertorié, c'est l'impossibilité d'utiliser la fonction ATSRest

après avoir passé l'arpem a essayer de chercher d'où sa venais, je me suis rendu compte que le problème vient de chez bioware, il est pas possible d'utiliser ActionRest a la suite d'autres actions.

encore mieux : si on utilise ActionRest sans AssignCommand sur un script qui ne peut pas faire d'action (une conversation dans ce cas la), mega plantage du jeu :/

-> SendBugRapportToBioware

pour la demo, je la mettrais pas ce soir non plus, j'ai pas le temp.
On va dire a la fin de la semaine pour me donner un peu de marge mais se sera surment avant.

Par Skanzo Sylan le 28/1/2003 à 13:01:50 (#3117731)

Bien dommage ce bug, encore une fois merci Bioware :rolleyes:

En attendant que ce bug soit résolu, tu pourrais tout simplement remplacer l'action Rest par l'animation de s'asseoir par terre. Tout juste un simulacre en prenant soin d'avertir l'utilisateur de cette bibliothèque dans les commentaires de cette fonction :)

bon, ba puisque personne fais rien

Par Reyan le 10/2/2003 à 23:18:47 (#3211278)

alors, je ne crois pas avoir vu d'exemple, à part celui de Skanzo Sylan, et comme ca me serait bien util, je me suis lancé dans un essai :rasta: bon, comme je suis une quiche level 2, c'est pas top top, soyez indulgent :D
bon, alors j'ai repris le "moduletest" fait y a qq tps :rolleyes:
et j'ai rajouté une zone, vec un long parcours, 5 portes (PORTE1, PORTE2, ...)
un waypoint au debut : WP_0
un waipoint devant chaque porte : WP_PORTE1, ...
un waypoint à la fin : WP_6
un guide , avec , dans le

onspawn

#include "bi_actionstruct"
#include "NW_I0_GENERIC"
void main()
{
object oWp1 = GetObjectByTag("WP_PORTE1");
object oWp2 = GetObjectByTag("WP_PORTE2");
object oWp3 = GetObjectByTag("WP_PORTE3");
object oWp4 = GetObjectByTag("WP_PORTE4");
object oWp5 = GetObjectByTag("WP_PORTE5");
object oWpfin = GetObjectByTag("WP_FIN");
object oPorte1 = GetObjectByTag("PORTE1");
object oPorte2 = GetObjectByTag("PORTE2");
object oPorte3 = GetObjectByTag("PORTE3");
object oPorte4 = GetObjectByTag("PORTE4");
object oPorte5 = GetObjectByTag("PORTE5");
//initialisation de la struct de guidage ^_^
int pDepart = CreateActionStruct();

ATSMoveToObject(pDepart, oWp1);
SetLocalInt(OBJECT_SELF, "POSITION", 1);
//devrait indiquer la position, mais marche pas, faudrait un ActionDoCommand je suppose T_T
ATSUnlockObject(pDepart, oPorte1);
ATSOpenDoor(pDepart, oPorte1);
ATSMoveToObject(pDepart, oWp2);
SetLocalInt(OBJECT_SELF, "POSITION", 2);
ATSUnlockObject(pDepart, oPorte2);
ATSOpenDoor(pDepart, oPorte2);
ATSMoveToObject(pDepart, oWp3);
SetLocalInt(OBJECT_SELF, "POSITION", 3);
ATSUnlockObject(pDepart, oPorte3);
ATSOpenDoor(pDepart, oPorte3);
ATSMoveToObject(pDepart, oWp4);
SetLocalInt(OBJECT_SELF, "POSITION", 4);
ATSUnlockObject(pDepart, oPorte4);
ATSOpenDoor(pDepart, oPorte4);
ATSMoveToObject(pDepart, oWp5);
SetLocalInt(OBJECT_SELF, "POSITION", 5);
ATSUnlockObject(pDepart, oPorte5);
ATSMoveToObject(pDepart, oWpfin);
SetLocalInt(OBJECT_SELF, "POSITION", 6);
SetLocalInt(OBJECT_SELF, "DEPART", pDepart);


SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001

}




alors "bi_actionstruct" c'est la biblio de azrael, vous l'aviez deviné (j'ai changé de nom sans faire exprès, en fait j'avais la flemme de re tout changer :rolleyes: )

dans le onuserdefined

#include "bi_actionstruct"
void main()
{
// enter desired behaviour here
int nEvent = GetUserDefinedEventNumber();
switch(nEvent)
{
case 1001:
object oLeader = GetFirstPC();
float fLoin = GetDistanceBetween(OBJECT_SELF, oLeader);
int nCherche = GetLocalInt(OBJECT_SELF,"CHERCHE");
int pAttente = GetLocalInt(OBJECT_SELF, "ATTENTE");
//recupere le wp le plus proche
object oNearestwp = GetNearestObject(OBJECT_TYPE_WAYPOINT);
string s = ObjectToString(oNearestwp);
string si = GetStringRight(s, 1);
if((fLoin > 10.0) && (nCherche !=2))
{
//arrete tout
ClearAllActions();
//met en "mode recherche Leader"
SetLocalInt(OBJECT_SELF, "CHERCHE", 2);
int i = StringToInt(si);
i -=1;
//donne a i le valeur du wp precedent, et non le plus proche
string s1 = IntToString(i);
int i2 = i-=1;
string s2= IntToString(i2);
int i3 = i-=2;
string s3= IntToString(i3);
int i4 = i-=3;
string s4= IntToString(i4);
int i5 = i-=4;
string s5= IntToString(i5);
int i6 = i-=5;
string s6= IntToString(i6);
// debut initialisation struct


int pAttente = CreateActionStruct();
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
ATSSpeakString(pAttente, "Mais !!");
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
ATSSpeakString(pAttente, "Eh oh ! Y'a quelqu'un ?");
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD);
ATSSpeakString(pAttente, "Eh ! Ou vous etes passez !");
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_TAUNT);
ATSSpeakString(pAttente,"Je vous avait dis de ne pas vous eloigner !", TALKVOLUME_SHOUT);
//retour en arriere, ca marche pas ...
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s1));
ATSSpeakString(pAttente, "Youhou !!");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s2));
ATSSpeakString(pAttente, "Oh eh !");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s3));
ATSSpeakString(pAttente, "Par ici bon sang !");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s4));
ATSSpeakString(pAttente, "Youhou !!");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s5));
ATSSpeakString(pAttente, "Youhou !!");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s6));
ATSSpeakString(pAttente, "Youhou !!");
//normalement il va retourner jusqu'a ce qu'il trouve "object invalid"
//ds le cas ou il etait pas rendu a la fin
//permet, je pense, de le faire revenir au bout a coups sure

/* essai d'application d'une boucle sur les ATS .. marche pas ... j'essai avec les inPostions ...

while(i > 0)
{
string sPosition = IntToString(i);
ATSMoveToObject(pAttente, GetObjectByTag("WP_PORTE"+sPosition));
ATSSpeakString(pAttente,"Eh oh !");
i -= 1;
};


while(i < iB)
{
string sPosition = IntToString(i);
ATSMoveToObject(pAttente, GetObjectByTag("WP_PORTE"+sPosition));
ATSSpeakString(pAttente,"Mais ou etes vous sapristi !");
i++;
};
*/
//en remplacement de ce qui y a audessus qui marche pas, je fais ca
ATSSpeakString(pAttente, "Venez tout de suite !!", TALKVOLUME_SHOUT);
ATSMoveToObject(pAttente, oLeader);
ATSStartConversation(pAttente, oLeader);

//fin initialisation struct
//lancement
ExecuteActionStruct(OBJECT_SELF, pAttente);

}
if((fLoin < 10.0) && (nCherche ==2))
{
//quand il trouve le leader, il annule la recherche et engeule
//et sort du "mode recherche Leader"
ClearAllActions();
ActionMoveToObject(oLeader);
ActionStartConversation(oLeader);
SetLocalInt(OBJECT_SELF, "CHERCHE", 1);
DeleteActionStruct(pAttente);
}
}
}


j'ai laissé les quelques essai infructueux .. notamment les
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s3));

qui ne marche pas sans doute parce que c'est mal écrit ...

alors ensuite j'ai fait un dialogue pour mon guide, tout bête, avec une ligne qui se déclenche si il est 'en mode recherche Leader"
if(!(GetLocalInt(GetPCSpeaker(), "CHERCHE") == 2))
return FALSE;

et une ligne de départ qui lance la chaine
#include "bi_actionstruct"
void main()
{
int pDepart = GetLocalInt(OBJECT_SELF, "DEPART");
ActionDoCommand(DelayCommand(1.0, ActionSpeakString("Suivez moi ! Et restez pres de moi !")));
ExecuteActionStruct(OBJECT_SELF, pDepart, FALSE);

}


j'ai supprimé les ClearAllActions a la fin du dialogue, et je lance

ce que je voudrais, c'est que mon guide ma balade, ouvre les portes etc. et que qd il s'aperçoit que le joueur leader est loin, il aille le chercher. J'aurais aimé qu'il le fasse en revenant sur ses pas, parce que je ne fais pas confiance au "ActionMoveToObject" qui ont tendance a trimballer le NPC n'importe où ...mais ca marche pas

autre pb, je en sais pas trop pk, le guide revient loin sur ses pas pour récupérer la chaine, je suppose que c'est parce que son action n'était pas finit qu'il repasse a la précédente .. est ce que si on met "TRUE" au dernier argument d'une ATS ca la supprime qd elle est faite ? comme un chaine ?
auquel cas sa règle mon pb (vais aller essayer tt de suite ;)) )
bref, c'est un script que j'ai eu du mal à pondre (oui je suis une quiche :p ) et y a sure ment pleins de trucs qui vont pas le plus mieux possible, alors svp, montrez moi :merci:


:monstre: ca lance même plus en mettant TRUE, y a un truc que j'ai pas du comprendre :rasta:

Par Azrael07 le 10/2/2003 à 23:39:19 (#3211400)

Alors y'a un truc qu'il faut bien comprendre : cette bibliothèque n'est pas encore débuggée, donc il est bien possible que plusieurs trucs merdent :/

Le TRUE après les ATS n'a carrement jamais été testé ^^'
je comptais m'occuper du debuggage général de cette lib un peu plus tard, mais si tu dis en avoir besoin, je vais reprendre ca tout de suite, et en profiter pour regarder un peu ce script.

Donc je m'en occupe demain, ce soir vu l'heure, 'vais peut être aller au dodo, mais en regardant ton script en vitesse il me semble que tu as ressortis l'un des bugs connus de la biblio, je verrais tout ca demain :)

(heu par contre tu vas me faire le plaisir d'arreter de te traiter de super quiche, pasque je trouve vu ton script que c un peu beaucoup faux, alors que je t'y reprenne pas hein :enerve: )

'nuit all

Par Delphinea le 10/2/2003 à 23:42:06 (#3211411)

ATS... cela me fait penser à Ambrosia Tradeskill System de Mojo.....

Les fonctions de ce système commencent également par "ATS". J'espère que ça ne va pas générer de doublons pour les gens voulant utiliser les deux systèmes. Au vu des fonctions utilisées je ne pense pas, mais on ne sait jamais.....

Par Azrael07 le 11/2/2003 à 20:28:01 (#3217099)

pour ton premier code, je sais pas ce qu'il a a voir avec la suite, mais en tout cas il est innutilisable, car tu ne retient pas le pointeur vers la chaine créée, tu doit mettre a la fin un truc du genre :


SetLocalInt(oModule, "Depart", pDepart);


ensuite, dans le deuxième code :


string s = ObjectToString(oNearestwp);
string si = GetStringRight(s, 1);


la je sais pas trop ce que t'as voulu faire, en fait si mes connaissances s'avèrent exactes, ObjectToString renvoie la position de l'object dans la liste chainée des objets, donc fct totalement inutile en réalité, mais je peux me tromper (c'est louche qu'une fonction ne servent a rien O_o)
tu peux me dire ce que tu veux faire par la ?

i -=1;


met plutot :
i--;
c'est plus bô ^_^ (pi très très légèrement plus rapide, un tour d'orloge de moins, autant dire rien ^^)



string s1 = IntToString(i);
int i2 = i-=1;
string s2= IntToString(i2);
int i3 = i-=2;
string s3= IntToString(i3);
int i4 = i-=3;
string s4= IntToString(i4);
int i5 = i-=4;
string s5= IntToString(i5);
int i6 = i-=5;
string s6= IntToString(i6);



ATTENTION : voila ce que produit la ligne suivante, pour i = 1 au départ :
int i2 = i-=1;

on a a la fin i2 = 0, mais.... i = 0
i-=1 baisse la variable i de 1, et la ligne suivante se suffie a elle meme :
i -= 1;

le mieux pour le code ci dessus et de réutiliser ta variable i :

string s1 = IntToString(i);
i--;
string s2= IntToString(i);
i--;
string s3= IntToString(i);
i--;
string s4= IntToString(i);
i--;
string s5= IntToString(i);
i--;
string s6= IntToString(i);


ensuite, pour la définition de tes fonctions ATS apparament pas d'erreurs, sauf que tu dois prendre garde quand

L'argument TRUE d'une fonction ATS sert à supprimer l'action une fois celle ci terminée, ce qui a pour unique utilité de réduire les ressources prisent par la fonction, donc ca n'aideras a rien pour ton truc.

par contre je n'ai pas tout compris dans tes explications : où dans cet exemple ma biblio ne marche elle pas ?
je m'occupe du beta test cette semaine, ce weekend dans le pire des cas, la nouvelle version marchera peut etre mieux :D

Par Reyan le 12/2/2003 à 0:27:24 (#3218618)

pour ton premier code, je sais pas ce qu'il a a voir avec la suite, mais en tout cas il est innutilisable, car tu ne retient pas le pointeur vers la chaine créée, tu doit mettre a la fin un truc du genre :


g mis le même truc, mais sur le NPC ^_^

string s = ObjectToString(oNearestwp);
string si = GetStringRight(s, 1);


la je sais pas trop ce que t'as voulu faire, en fait si mes connaissances s'avèrent exactes, ObjectToString renvoie la position de l'object dans la liste chainée des objets, donc fct totalement inutile en réalité, mais je peux me tromper (c'est louche qu'une fonction ne servent a rien O_o)
tu peux me dire ce que tu veux faire par la ?


en fait, c t une bêtise ^_^ je voulais récupérer le tag du WP le plus proche, prendre la lettre de droite (le chiffre quoi) mais j'étais fatigué :monstre: je pensais que ObjectToString ferait ca, à partir du nom, mais ObjectToString ce transforme un object en un pâté d'hexadecimal ... je me demande a quoi ca peut ressembler ... bref, il suffisait de faire GetTag :rolleyes:

ce qui marchait pas, c t le script en lui même ;)
ce qui va peut être pas avec ta biblio c'est le dernier argument des fonctions ATS, le fameux "TRUE" qui ne donne rien :) et annule tout semble t'il :doute:

Par Reyan le 12/2/2003 à 0:53:53 (#3218753)

bon, alors retest
et c marche tjrs pas :monstre:
j'ai changé ce que tu m'avais fais remarquer :)
et mon NPC revient bien sur ses pas jusqu'a apercevoir le leader, et alors il va le voir et lui parle, mais quand je veux reprendre la chaine d'action, elle reprend "au milieu" pas à la première, mais à la 5 ou 6 eme ... même si il en a fait plusieurs autre après ... c'est bizarre :rasta: si ca vient de l'utilisation, je vois pas où :merci: (je met les scripts corrigé ici, pour que la discussion est un sens :) si c'est pas bien, ba dites ;) )

onspawn

#include "bi_actionstruct"
#include "NW_I0_GENERIC"
void main()
{
object oWp1 = GetObjectByTag("WP_PORTE1");
object oWp2 = GetObjectByTag("WP_PORTE2");
object oWp3 = GetObjectByTag("WP_PORTE3");
object oWp4 = GetObjectByTag("WP_PORTE4");
object oWp5 = GetObjectByTag("WP_PORTE5");
object oWpfin = GetObjectByTag("WP_FIN6");
object oPorte1 = GetObjectByTag("PORTE1");
object oPorte2 = GetObjectByTag("PORTE2");
object oPorte3 = GetObjectByTag("PORTE3");
object oPorte4 = GetObjectByTag("PORTE4");
object oPorte5 = GetObjectByTag("PORTE5");
//initialisation de la struct de guidage ^_^
int pDepart = CreateActionStruct();

ATSMoveToObject(pDepart, oWp1, FALSE,1.0,FALSE);
ATSUnlockObject(pDepart, oPorte1, FALSE);
ATSOpenDoor(pDepart, oPorte1, FALSE);
ATSMoveToObject(pDepart, oWp2, FALSE,1.0,FALSE);
ATSUnlockObject(pDepart, oPorte2, FALSE);
ATSOpenDoor(pDepart, oPorte2, FALSE);
ATSMoveToObject(pDepart, oWp3, FALSE,1.0,FALSE);
ATSUnlockObject(pDepart, oPorte3, FALSE);
ATSOpenDoor(pDepart, oPorte3, FALSE);
ATSMoveToObject(pDepart, oWp4, FALSE,1.0,FALSE);
ATSUnlockObject(pDepart, oPorte4, FALSE);
ATSOpenDoor(pDepart, oPorte4, FALSE);
ATSMoveToObject(pDepart, oWp5, FALSE,1.0,FALSE);
ATSUnlockObject(pDepart, oPorte5, FALSE);
ATSOpenDoor(pDepart, oPorte5, FALSE);
ATSMoveToObject(pDepart, oWpfin, FALSE,1.0,FALSE);
SetLocalInt(OBJECT_SELF, "DEPART", pDepart);


SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001

}



onuserdefined

#include "bi_actionstruct"
#include "replace"
void main()
{
// enter desired behaviour here
int nEvent = GetUserDefinedEventNumber();
if(nEvent == 1001)
{

object oLeader = GetFirstPC();
float fLoin = GetDistanceBetween(OBJECT_SELF, oLeader);
int nCherche = GetLocalInt(OBJECT_SELF,"CHERCHE");
int pAttente = GetLocalInt(OBJECT_SELF, "ATTENTE");
//recupere le wp le plus proche
object oNearestwp = GetNearestObject(OBJECT_TYPE_WAYPOINT);
string s = GetTag(oNearestwp);
string si = GetStringRight(s, 1);
if((fLoin > 10.0) && (nCherche !=2))
{
//arrete tout
ClearAllActions();
//met en "mode recherche Leader"
SetLocalInt(OBJECT_SELF, "CHERCHE", 2);
int i = StringToInt(si);
i --;
//donne a i le valeur du wp precedent, et non le plus proche
string s1 = IntToString(i);
i--;
string s2= IntToString(i);
i--;
string s3= IntToString(i);
i--;
string s4= IntToString(i);
i--;
string s5= IntToString(i);
i--;
string s6= IntToString(i);
// debut initialisation struct


int pAttente = CreateActionStruct();
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_HEAD_TURN_LEFT);
ATSSpeakString(pAttente, "Mais !!");
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_HEAD_TURN_RIGHT);
ATSSpeakString(pAttente, "Eh oh ! Y'a quelqu'un ?");
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD);
ATSSpeakString(pAttente, "Eh ! Ou vous etes passez !");
ATSPlayAnimation(pAttente, ANIMATION_FIREFORGET_TAUNT);
ATSSpeakString(pAttente,"Je vous avait dis de ne pas vous eloigner !", TALKVOLUME_SHOUT);
//retour en arriere
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s1));
ATSSpeakString(pAttente, "Youhou !!");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s2));
ATSSpeakString(pAttente, "Oh eh !");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s3));
ATSSpeakString(pAttente, "Par ici bon sang !");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s4));
ATSSpeakString(pAttente, "Youhou !!");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s5));
ATSSpeakString(pAttente, "Youhou !!");
ATSMoveToObject(pAttente,GetObjectByTag("WP_PORTE"+s6));
ATSSpeakString(pAttente, "Youhou !!");
//normalement il va retourner jusqu'a ce qu'il trouve "object invalid"
//ds le cas ou il etait pas rendu a la fin
//permet, je pense, de le faire revenir au bout a coups sure


//fin initialisation struct
//lancement
ExecuteActionStruct(OBJECT_SELF, pAttente);

}
if((fLoin < 10.0) && (nCherche ==2))
{
//quand il trouve le leader, il annule la recherche et engeule
//et sort du "mode recherche Leader"
ClearAllActions();
ActionMoveToObject(oLeader);
ActionStartConversation(oLeader);
SetLocalInt(OBJECT_SELF, "CHERCHE", 1);
DeleteActionStruct(pAttente);
}
}
}

JOL Archives 1.0.1
@ JOL / JeuxOnLine