OnPerception

Répondre
Partager Rechercher
bonjour,

sur une créature(par défait Hostile), j'ai mis 2 scripts afin de tester si le pj que cette créature vois porte au non un vêtement spécifique.

Si ce pj porte le bon vêtement, la créature doit être amicale.
Si ce pj ne porte pas le bon vêtement, la créature doit l'attaquer.

Voici le script placé dans le OnPercption de la créature:

Code PHP:

void main()
{
object oPJ GetLastPerceived();
object oBJ1 GetObjectByTag("tuniqueparticuliere");
// le PJ porte t'il la tunique ?
if (((GetItemInSlot(INVENTORY_SLOT_CHESToPJ)) == oBJ1))
{
SetIsTemporaryFriend(oPJOBJECT_SELF);
ActionAttack(oPJTRUE);
ExecuteScript("x2_def_percept"OBJECT_SELF);
}
else
{
SetIsTemporaryEnemy(oPJOBJECT_SELF);
ActionAttack(oPJFALSE);
ExecuteScript("x2_def_percept"OBJECT_SELF);
}

le second script est placé sur le OnUserDefine de la créature :

Code PHP:

void main()
{
object oPJ GetLastPerceived();
object oBJ1 GetObjectByTag("tuniqueparticuliere");
int nUser GetUserDefinedEventNumber();
if (
nUser == 1002// OnPerception event
{
// PJ porte t'il la tunique ?
if (((GetItemInSlot(INVENTORY_SLOT_CHESToPJ)) == oBJ1))
{
SetIsTemporaryFriend(oPJOBJECT_SELF);
ActionAttack(oPJTRUE);
}
else
{
SetIsTemporaryEnemy(oPJOBJECT_SELF);
ActionAttack(oPJFALSE);
}
}


Ce qui fonctione correctement :
- le pj est vu, la créature identifie clairement ce qu'il porte. s'il porte pas la bonne tunique elle l'attaque.

Ce qui fonctionne pas:
- dans le cas ou le pj porte la bonne tunique, la créature n'est pas béliqueuse (quelques courts instants) mais elle le devient rapidement.

J'ai essayé en utilisant uniquement les SetIsTemporaryEnemy/Friend. résultat idem.
J'ai essayé en utilisant uniquement les SetIsTemporaryEnemy/Friend et ajoutant une durée. résultat idem.

J'ai essayé en utilisant uniquement les ActionAttack. Résultat idem.

Et cette version, cumul les 2.

Avez vous une idée du pb ?

Merci.

a+
Hello,

merci pour ce lien Bjorn.

Sauf erreur de ma part, si un des pjs porte par ce qu'il faut, la faction de la créature est changée.par conséquence elle devient hostile pour tout le monde. Et même pour celui qui porte les bonnes affaires.

C'est pas tout à fait ce que je souhaitais faire. Moi je voudrais que l'hostilité se manifeste seulement envers le(s) pj(s) qui ne porte pas le bon habit. C'est pourquoi j'utilise le SetIsTemporary...

Quelqu'un aurait il une autre idée ?

Merci.

a+
Désoler je n'avait pas put tester cela en multi ....*part se cacher*

Et si tu allez voir là leçon de script numero 4 ou 5 enfin peu être que cela peu t'aider

[url="https://forums.jeuxonline.info/showthread.php?t=103859[/url]
Fantome, essaie d'augmenter la perception (dans les options avancées) et les compétences de la créatures comme Detection et perception auditive.

c'est surement parce qu'elle te remarque un peu sur le tard
Nigel, la créature me remarque bien : j'ai placé pour mes test quelques phrases de texte afin de voir par ou je passais exactement.

J'ai essayé en jouant sur les factions, sans plus de succès.

Quelqu'un aurait il une solution, je suis à court d'idée là ?

Merci.

a+
Le probleme est bien que la créature devient hostile un peu tard?

C'est qu'elle te perçoit surement trop tard, j'en suis presque convaincu.
Citation :
Le probleme est bien que la créature devient hostile un peu tard?
Non le pb est pas là Nigel.

Le pb est au contraire qu'elle devient hostile alors qu'elle devrait pas. Je te redonne exactement ce qui se passe :
1°) le pj porte le bon vêtement
2°) la créature le voit, et l'identifie comme portant le bon vêtement - statut amical -
3°) la créature devient hostile et attaque le pj.

une idée ?
Pourquoi mets-tu deux fois le même script? Dans le OnPerception et le OnUserDefined?

Aussi, je ne pense pas que le else soit nécéssaire vu que ta créature est par défaut hostile... Mais c'est à vérifier.

Bon, on enleve donc cette partie pour plus de clarté,
Ce qui donne:

Code PHP:

void main() 

object oPJ GetLastPerceived(); 
object oBJ1 GetObjectByTag("tuniqueparticuliere"); 
// le PJ porte t'il la tunique ? 
if (((GetItemInSlot(INVENTORY_SLOT_CHESToPJ)) == oBJ1)) 

SetIsTemporaryFriend(oPJOBJECT_SELF); 
ActionAttack(oPJTRUE); 
ExecuteScript("x2_def_percept"OBJECT_SELF);
}

Si j'ai bien compris, à la suite de ce script, ta créature devient bien amicale si ton PJ porte l'armure spécifique, mais devient hostile quelques temps après.

Pourquoi ajouter "ActionAttack"?
Je vois qu'il est en mode passif, donc que la créature deviendra hostile sans pour autant foncer sur l'adversaire.

Si tu enleve cette ligne: ActionAttack(oPJ, TRUE);
Ca fait quoi?
Ton script est assez bizarre Fantome (ou alors je l'ai pas compris).
Comme le demande Nigel, pourquoi faire deux fois la même chose ?
D'habitude, lorsqu'on doit modifier un script d'IA de créature, on ne remplace pas le script par défaut (ici x2_def_percept), mais on utilise le OnUserDefined.

Ensuite, pourquoi faire ActionAttack dans les deux cas ? Connais-tu la signification exacte du 2e paramètre de la fonction ? Si non, je te renvoie au lexicon.

D'autre part, pas besoin de SetTemporaryEnemy.

Enfin, dernier gros problème : tu compare l'armure portée par le PJ avec un objet dont tu ne connais absolument rien.
Code PHP:

GetItemInSlot(INVENTORY_SLOT_CHESToPJ) == oBJ1 

Quel est cet objet oBJ1 ? le premier objet venu portant le tag "tuniqueparticuliere" ? tu as relativement peu de chances que ce soit le même porté par le PJ.
Il faut au contraire que tu t'intéresse au tag de l'objet porté par le PJ.

Dernière chose, essaie de soigner la présentation. Evite les parenthèses qui servent à rien (2 paires de parenthèses inutiles sur la ligne avec le if), et surtout : indente. Quand tu a un bloc compris entre deux accolades, décale le d'une tabulation (suffit de sélectionner tout le bloc et d'appuyer sur tab).

Bon, je te propose une version de ton script un peu remaniée en rapport à ce que j'ai relevé précédemment :
(à mettre sur le OnUserDefined)
Code PHP:

void main()
{
    
object oPJ GetLastPerceived();
    
object oArmure GetItemInSlot(INVENTORY_SLOT_CHESToPJ);
    
int nUser GetUserDefinedEventNumber();
    if (
nUser == 1002// OnPerception event
    
{
        
// PJ porte t'il la tunique ?
        
if (GetTag(oArmure) == "tuniqueparticuliere")
        {
            
SetIsTemporaryFriend(oPJOBJECT_SELF);
        }
        else
        {
            
ActionAttack(oPJ);
        }
    }

En effet, je ferais comme ça aussi.

Je ne suis pas certain non plus que le else soit vraiment nécessaire encore une fois... Je pense qu'il faut tester avec et sans...
Bonsoir,

merci pour vos réponses.

J'ai testé. Malheureusement ca fonctionne pas. J'ai peux être pas bien procédé :
- 1°) j'ai placé le script de Taern dans le OnUserDefined
- 2°) j'ai remis dans le OnPerception le script par défaut : x2_def_percept

J'ai ajouté des phrases pour voir si je passais bien dans OnUsedDefined. Les phrases ne sont pas apparus.

De votre coté, vous aviez testé ? ca marchait ?

Une autre idée ?

Merci.

a+
Si on le met juste tel que tu dit Nigel, si le pj décide de changer de vetement, la créature s'en rends pas compte.

Avec les idées que vous m'avez évoqué, voici enfin la solution qui fonctionne.

Dans le OnPerception de la créature :
Code PHP:

void main() 

    
object oPJ GetLastPerceived(); 
    
object oArmure GetItemInSlot(INVENTORY_SLOT_CHESToPJ); 

        
// PJ porte t'il la tunique ? 
        
if (GetTag(oArmure) == "tuniqueparticuliere"
        { 
            
SetIsTemporaryFriend(oPJOBJECT_SELF); 
        } 
        else 
        { 
            
SetIsTemporaryEnemy(oPJOBJECT_SELF); 
            
ActionAttack(oPJ); 
        } 
   
ExecuteScript("x2_def_percept"OBJECT_SELF);     

Puis dans le OnUserDefine :
Code PHP:

void main()
{

int nUser GetUserDefinedEventNumber();
    if (
nUser == 1002// OnPerception event
    
{
       
ExecuteScript("XXXXX"OBJECT_SELF); // ici c'est le script du OnPeception
    
}


Merci pour votre aide.

a+
Pour moi tu n'as absolument pas besoin de gerer aux 2 endroits!!!

Soit tu fais ta modif dans le script par defaut du OnPerception, soit tu le geres dans le OnUserDefined.
A savoir qu'en fait c'est 2 evenements differents! l'un est un evenements lance par le moteur (le OnPerception de base) l'autre est un evenement lance par script (En l'occurence ici il est normalement lance a la fin du script par defaut).
Donc une solution que je trouvais propre au depart etait de rien mettre sur les scripts par defaut et de tout gerer sur les OnUserDefined, mais au final ce n'est pas une solution super. Car enfait les script par defaut n'en sont pas reellement mais c'est des scripts specialisés pour les modules fournis par Bio (y a qu'a voir le script de la mort qui fait des tests sur des noms de zones que vous n'aurez jamais dans vos modules ).

Enfin Bref, ici normalement le premier code lance sera celui du OnPerception, et ensuite a la fin il lancera le code de ton userDefined.
Ce qui me fait peur dans ton code, c'est que a priori pour moi tu devrais boucler sur les 2 evenements!!! (vu que le OnPerception a la fin appel le UserDefined et que toi dans le userDefined tu rappels le OnPerception ) Sauf si bien sur tu n'as pas decommenté la bonne ligne dans le OnSpawn et dans ce cas effectivement tu ne boucles pas mais le code de ton userdefined n'est jamais executé.
En fait Garrath si j'en suis arrivé a cette solution c'est parce que j'ai remarqué que le OnPerception semplait se lancer qu'une seule fois : par conséquense si le pj change de vetement devant la créature elle ne prends pas en compte se changement.

Et donc je pensais qu'ensuite le OnUserDefine prenait le relais du OnPerception, ce qui semble effectivement se faire. Mais comme tu l'as justement souligné, effectivement les 2 scripts se renvoient la balle.

Actuellement la solution écrite plus haut fonctionne, c'est surement pas la meilleur mais j'ai pas d'autre idée. Si tu as une autre solution je suis preneur.

Merci.

a+
Ben c logique
Le OnPerception se fait que lorsque qu'un PNJ remarque un PJ. Et en general une seule fois.
En fait pour qu'un PJ soit percu il faut qu'il fasse une action le permettant. Donc soit entre dans le champ de vue du PNJ soit faire du bruit.
Donc si ton PJ change de vetement alors qu'il a deja ete percu par le PNJ, le PNJ ne fera rien.
C pas un evenements de surveillance mais un evenements qui se produit a une modif de champ de perception du PNJ. Un PJ qui entre dans le champ de perception visuel du PNJ declenche l'evenement, si ensuite il reste la, l'evenement ne se redeclenche pas.
(Enfait c pas totalement vrai, au bout d'un certain temps il me semble qu'il se redeclenche quand meme )

Donc la, la solution a mon avis c de declencher toi meme l'evenement.
La pour moi tu as 2 solutions.
1 - Garder ton code sur l'evenement standard (et l'enlever du OnUserDefined) et dans ce cas la, il faut declencher une action grace aux SpeakString("ce que tu veux", TALKVOLUME_SILENT_SHOUT) ou SpeakString(("ce que tu veux", TALKVOLUME_SILENT_TALK) et la je pense que ca devrait declencher le OnPerception (j'en suis sur )
2 - Laisser le code standard sur le OnPErception et code dans le OnUserDEfined uniquement (decommente la ligne qui va bine dans le OnSPawn du PNJ), et a la place de lancer un SpeakString tu lances une boucle sur les PNJ de la zone et tu lances l'evenements qui va bien sur chaque PNJ

Dans les 2 solutions ca veut dire que de toutes façons il faut que tu crees un script pour le OnEquip de ton item ainsi q'ailleurs que pour le desequipement (voir le TagBasedScript pour cela c tres bien ).
Maintenant avantages et inconvenient des 2 methodes :
La 1 er.
avec le TALKVOLUME_SILENT_SHOUT le DM a une trace de l'action sur con canal (c vite chaint )
que cela soit avec le SILENT_SHOUT ou SIlent_TALK il me semble que tous les PNJ de la zone reagissent (a voir si cela t'interresse ou pas )

La 2 nd
Le pb c'est la boucle sur les PNJ qui se trouve autour de toi. En fait il faut faire une boucle sur les creatures les plus proches (tant qu'elles sont dans la zone) et si elles peuvent te voir ou pas (si tu veux pousser le vices au max )
Répondre

Connectés sur ce fil

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