Rondes: Solution!

Répondre
Partager Rechercher
Vous avez surement remarqué que dans Neverwinter Nights, les PNJs a qui vous avez attribué des Waypoints suivent ceux-ci dans cet ordre (en imaginant que vous leur avez donné 4 waypoints):

1 - 2 - 3 - 4 - 3 - 2 - 1, etc...

Mais dans le cas où le PNJ doit faire une ronde, une vraie, "faire un rond", vous le verrez bêtement faire demi-tour une fois arrivé à la case départ.

Il y a donc une solution pour qu'un PNJ voulu suive les numéros de waypoints dans cet ordre:

1 - 2 - 3 - 4 - 1 - 2 - 3 - 4, etc...

La solution se situe en bas du topic.

Merci à Deyonara pour m'avoir grandement aidé à trouver la solution
Il te permet de créer tes évènements personnalisés, ou d'utiliser ceux déjà présents.

Par exemple, tu as une porte verrouillée, et un garde qui surveille cette porte. Si la quelqu'un touche à la porte, le garde réagit. Si quelqu'un l'ouvre, il réagit d'une autre manière.

Le garde sera taggé ici "GARDE_PORTE"

Nous avons donc deux évènements à définir :

- L'évènement "utilisation de la porte" - qui sera numérotée 9001 (j'utilise un nombre élevé, pour éviter tout conflit avec d'autres évènements).

- L'évènement "ouverture de la porte" - qui sera numérotée 9002.

Dans le "OnUsed" de la porte, tu peux ajouter le signalement de l'évènement 9001 à l'intention du garde, à ta convenance. Si par exemple l'utilisateur est en mode furtif ou invisible, le garde ne verra pas que quelqu'un active le "OnUsed", et donc le signalement sera sous condition.
Code PHP:

void main()
{
    
object oUser GetLastUsedBy();
    
object oGarde GetNearestObjectByTag("GARDE_PORTE");

    
// ici je met la condition que le joueur n'est pas en mode furtif
    
if(GetActionMode(oUser)!=ACTION_MODE_STEALTH)
    {
        
SignalEvent(oGarde,9001);
    }

Ensuite, dans le "OnOpened" de la porte, tu ajoutes le signalement de l'évènement 9002 à l'intention du garde. Tu peux également déclarer un signalement différent selon les critères que tu auras définis. Par exemple si le joueur est toujours furtif, le garde réagira à l'évènement 9002, à l'évènement 9003 si le joueur est un nain, 9004 pour le reste, ou encore autant de réactions différentes que tu souhaiteras.
Code PHP:

void main()
{
    
object oOpener GetLastOpener();
    
object oGarde GetNearestObjectByTag();

    
// si le joueur est en furtif
    
if(GetActionMode(oOpener)==ACTION_MODE_STEALTH)
    {
        
SignalEvent(oGarde,9002);
    }

    
// si le joueur est un nain
    
else if(GetRacialType(oOpener)==RACIAL_TYPE_DWARF)
    {
        
SignalEvent(oGarde,9003);
    }

    
// pour le reste
    
else
    {
        
SignalEvent(oGarde,9004);
    }

Maintenant, il faut définir ce qui arrivera au garde quand il recevra le signal en question, et c'est dans le "OnUsedDefined" que ça se passe :
Code PHP:

void main()
{
    
int nEvent GetUserDefinedEventNumber();

    if(
nEvent==9001)
    {
        
// actions correspondantes à effectuer ici
    
}

    else if(
nEvent==9002)
    {
        
// actions correspondantes à effectuer ici
    
}

    else if(
nEvent==9003)
    {
        
// actions correspondantes à effectuer ici
    
}

    else if(
nEvent==9004)
    {
        
// actions correspondantes à effectuer ici
    
}

C'est certain, ce n'est qu'une approche basique de ce qui peut être réalisé avec les évènements personnalisés, mais le principe est là.
Ok, je vois le principe à présent, merci Deyonara!

Par contre... Dans ton cas, tu utilise un evenement (onused) pour activer ton signal event.

Mais... Si je veux par exemple que lorsqu'un PNJ atteint un Waypoint précis (l'evenement donc), il fasse son action?
Comment dois-je faire?
__________________
Nigel,
- Webmaster du site Rpgamers, http://www.rpgamers-fr.com
Tout sur les RPGs console: Soluces, traductions, tests, roms, wallpapers, listing, etc...
- Builder du module Neverwinter Nights "La voix de l'extinction", serveur Rôleplay et monde persistant.
Hum... Oui ca reste assez ennuyeux...

J'explique mon problème plus précisément alors:
J'ai réussi à bidouiller le nouveau système de Waypoint d'HotU de manières à ce que les PNJs fassent une vraie ronde (1, 2, 3, 4, 1, 2, 3, 4) au lieu de faire un aller-retour (1, 2, 3, 4, 3, 2, 1), ce qui est très pratique si un PNJ dessine une ronde.

Par contre... ça devient gênant lorsque son chemin est droit ou doit faire un aller-retour, je suis obligé de rajouter des waypoints.

C'est alors que j'ai vu cette fonction sur NWN lexicon, "SetWayPointTo1", qui me permettrait de garder le fonctionnement de NWN par défaut (le système d'aller-retour en "1, 2, 3, 2, 1" donc) et d'utiliser cette fonction occasionnellement sur les PNJs-ronde

Mais pour ça, il me faut l'évènement qui va bien... Et c'est là mon souci.
__________________
Nigel,
- Webmaster du site Rpgamers, http://www.rpgamers-fr.com
Tout sur les RPGs console: Soluces, traductions, tests, roms, wallpapers, listing, etc...
- Builder du module Neverwinter Nights "La voix de l'extinction", serveur Rôleplay et monde persistant.
Ca ou tu peux mettre une variable sur un PNJ qui doit effectuer une ronde complète.

D'ailleurs si tu peux me fournir ce script de ronde, ça me permettrait également de m'y atteler, je pourrai voir un peu le système de waypoint.

Sinon pour l'idée, il doit bien y avoir un moment où le PNJ décide d'aller au deuxième WP quand il arrive au premier. Essaye de trouver un moment du script où le PNJ change sa route, il y a sûrement un déclencheur par position, je présume.
D'ailleurs tu pourrais même définir une variable "int" sur le dernier WP de ta ronde, et mettre la condition suivante dans le système de ronde :

-> if(GetLocalInt(oWaypoint,"RETURN_TO_01")==TRUE)

Si c'est le cas, le système de ronde complète s'effectue. Sinon, le PNJ tournera les talons pour faire le chemin inverse.
Ouep, d'ailleurs j'ai avancé sur le problème!

Alors pour le script, il s'agit de X0_i0_walkway, gaffe par contre, il est en include sur pas mal de scripts comme nw_i0_generic et quelques nw_default.

Voici la ligne de code que j'ai changé sur le script d'origine:
ligne 297 ou pas loin:

Code PHP:

    // Check to see if this is the first time
    
if (nCurWay == -1)
    {
        
nCurWay GetNearestWalkWayPoint(oCreature);
    }
     else if (
nCurWay == nPoints){
    {
     
SpeakString("ca marche");
     
nCurWay 1;
    } 
Le speakstring est évidemment là pour tester si ça marche hein
Donc, ce script permet d'obliger les PNJs à faire une vraie ronde en 1, 2, 3, 4, 1, 2, 3, 4

Maintenant, je tente de faire en sorte que les PNJs fassent ce type de ronde uniquement s'ils possedent un objet appelé "PNJRonde":

Code PHP:

    // Check to see if this is the first time
    
if (nCurWay == -1)
    {
        
nCurWay GetNearestWalkWayPoint(oCreature);
    }
    else if (
nCurWay == nPoints)
    {
      if (
HasItem(oCreature"PNJRonde"))
      {
       
SpeakString("ca marche");
       
nCurWay 1;
      }
    } 
...J'y travaille encore, ça déconne pour les PNJs ne possedant pas l'objet dans l'inventaire, ils stoppent au lieu de retourner en arrière.
__________________
Nigel,
- Webmaster du site Rpgamers, http://www.rpgamers-fr.com
Tout sur les RPGs console: Soluces, traductions, tests, roms, wallpapers, listing, etc...
- Builder du module Neverwinter Nights "La voix de l'extinction", serveur Rôleplay et monde persistant.
Pas bête pour le coup de l'integer, je tente ça de suite, plutot que l'objet à mettre dans l'inventaire!

Par contre, j'avoue que je seche un peu...
;D
Bon, ben.. Le premier qui trouve laisse un message ;D
tiens, dans la fonction GetNextWaypoint(), tu peux remplacer une partie par ça :
Code PHP:

... ... ...
int bGoingBackwards GetWalkCondition(NW_WALK_FLAG_BACKWARDS,oCreature);
if(
bGoingBackwards)
{
    
nCurWay--;
    if(
nCurWay==0)
    {
        
nCurWay 2;
        
SetWalkCondition(NW_WALK_FLAG_BACKWARDS,FALSE,oCreature);
    }
}
else
{
    
nCurWay++;
    if(
nCurWay>nPoints)
    {
        
////////////////////////////////////////////////////////
        // Si le PNJ a la variable :
        
if(GetLocalInt(oCreature,"RETURN_TO_01")==1)
        {
            
// On remet le compteur à 1
            
nCurWay 1;
        }
        
// sinon...
        
else
        {
            
nCurWay -= 2;
            
SetWalkCondition(NW_WALK_FLAG_BACKWARDS,TRUE,oCreature);
        }
        
////////////////////////////////////////////////////////
    
}
}
... ... ... 
Ca t'obligera à mettre une variable sur tous les gardes qui doivent boucler leur ronde.

Mais, tu peux automatiser la mise en place de la variable sur le PNJ, en rajoutant ces quelques lignes dans cette partie de la fonction WalkWayPoints(). Par contre, il faudra la mettre sur le dernier WP de la boucle :
Code PHP:

... ... ...
object oWay GetNextWalkWayPoint(OBJECT_SELF);
if(
GetIsObjectValid(oWay)==TRUE)
{
    
SetWalkCondition(NW_WALK_FLAG_CONSTANT);
    
// * Feb 7 2003: Moving this from 299 to 321, because I don't see the point
    // * in clearing actions unless I actually have waypoints to walk
    
ClearActions(CLEAR_X0_I0_WALKWAY_WalkWayPoints);

    
////////////////////////////////////////////////////////
    // Si le Waypoint est le dernier d'une boucle
    
if(GetLocalInt(oWay,"RETURN_TO_01")==1)
    {
        
SetLocalInt(OBJECT_SELF,"RETURN_TO_01",1);
    }
    
////////////////////////////////////////////////////////

    //SpeakString("Moving to waypoint: " + GetTag(oWay));
    
ActionMoveToObject(oWay,nRun);
    if(
GetLocalInt(oWay,"X2_L_WAYPOINT_SETFACING")==1)
    {
        
ActionDoCommand(SetFacing(GetFacing(oWay)));
    }
... ... ... 
C'est à tester néanmoins...

[EDIT : Bon... le sujet d'origine de ce post a quand même fait l'objet d'un virage à 90°]

[EDIT : Après tests, l'automatisation ne marche seulement en cas d'activation de la ligne "SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);" dans le "OnSpawn" du PNJ, soit dans le script "nw_c2_default9".]
Yes!!!
Deyonara, t'es une chef!!

Ca marche impec'!
Bon, je n'ai pas testé pour l'automatisation de la variable sur les PJ, mais le systeme de ronde est impécable!!!

Donc, je récapitule pour finaliser ce sujet:

Dans le script "X0_i0_walkway", modifier à la ligne 316 ou pas loin, ceci:

Code PHP:

nCurWay++;
 if (
nCurWay nPoints)
 {
   
//  [A rajouter]
   
if(GetLocalInt(oCreature,"RETURN_TO_01")==1)
      {
      
nCurWay 1;
      }
   
// [/Fin]
   
else
      {
       
nCurWay nCurWay 2
ATTENTION!
Pensez à décommenter le "main" qui se trouve tout en bas du fichier pour pouvoir compiler, puis, recommentez.
Pensez aussi à sauvegarder ces fichiers de script dans votre module: nw_i0_generic (à compiler de la même manière) et la série des nw_c2_default1, 3, 4, 5, 6, 9, b

Et au final, ajouter la variable RETURN_TO_01 à 1 sur le PNJ qui doit faire une ronde de type 1, 2, 3, 1, 2, 3.


[PS: Oui, ça a completement viré de bord ;D, Je change le sujet]
[EDIT: Voilà, j'ai même changé le premier post]
Oui, c'est normal, il faut les nw_c2_default recompilés que je conseille sur le post au dessus et tout est nickel normalement ^^
Remarque j'ai pas testé, mais logiquement, il reprend sa route.
Et pourtant... rien de tout cela, maintenant c'est moi qui ai des problèmes...

Si je le dérange en cliquant de n'importe quelle manière, le PNJ casse sa ronde, et repart pour de stupides allers-retours.

[EDIT : Je crois même que je vais supprimer la notion d'allers retours... c'est une idée américaine stupide]
En fait, c'est ce que je me suis dit au début, mais finalement c'est tout de même utile cette notion de ronde à l'américaine ;D

Sinon, pour ton souci avec le PNJ qui ne continue pas sa ronde, regarde bien le topic-résumé que j'ai fait, il faut que tu aie les scripts que je donne de sauvegardés et re-compilés à tout prix sur ton module...
Et mettre le set de scripts par défaut (les x2_def**)sur ton PNJ ou alors, appeler toi-même les fonctions citées précédemment (les nw_c2***)
Oublie pas non-plus de bien compiler nw_i0_generic, je me fais avoir à chaque fois du fait qu'il n'y a pas de fonction "main"...

Chez moi ça marche, j'ai beau lui lancer une magie, l'attaquer, lui parler, enfin tout ce qu'on peut faire sur lui, il continue sa course au bout de 6 secondes maximum (heartbeat)
__________________
Nigel,
- Webmaster du site Rpgamers, http://www.rpgamers-fr.com
Tout sur les RPGs console: Soluces, traductions, tests, roms, wallpapers, listing, etc...
- Builder du module Neverwinter Nights "La voix de l'extinction", serveur Rôleplay et monde persistant.
C'est magnifique, tout compile, j'ai littéralement supprimé la notion d'allers-retours, donc impossible de revenir sur ses pas...

LE PNJ CONTINUE À FAIRE DES ALLERS-RETOURS !!!

Je n'ai pourtant pas porté préjudice à Bioware, mais l'éditeur m'en veut passionnément.
Mygod!!!


Ca vient forcément d'une compilation qu'il a pas pris, essaie de recompiler dans l'ordre: X0_i0_walkway (le main en bas...) >> nw_i0_generic (le main aussi en bas, scasse-burnes!) >> Puis ces satanés Nw_c2**

Je me suis fait avoir aussi dans l'après-midi, où j'avais dégagé un speakstring qui continuait d'apparaitre quand mayme!! xD
Ca surprend!
Mais le probleme vient d'une compile.

Vérifie quand même que les evenement OnDisturb, OnHeartbeat, OnAttack etc de ton PNJ sont bien munis d'un script qui appele les nw_c2 par le biais des X2_def...
(c'est pas lourdingue du tout! ;D)


...Essaie aussi de rajouter et compiler X0_i0_anims, j'ai un doute.
__________________
Nigel,
- Webmaster du site Rpgamers, http://www.rpgamers-fr.com
Tout sur les RPGs console: Soluces, traductions, tests, roms, wallpapers, listing, etc...
- Builder du module Neverwinter Nights "La voix de l'extinction", serveur Rôleplay et monde persistant.
Je crois que j'ai aussi une solution... je vais réinstaller ce @!&?!$* de Neverwinter Nights...

Je donnerai des nouvelle de ces @!&?!$*s de compilations dès que ça sera fait.

[EDIT : Si ça peut arranger les choses, je m'excuse sincèrement auprès de Bioware pour avoir traité indirectement cette honnête société canadienne d'américains aux idées stupide]
Oui, et rien n'y fait...

Mon organisme étant trop fragile, j'ai préféré la réinstallation à l'avalanche de coups de têtes dans l'écran. Cela aurait été peut-être un bon défoulement, mais aucunement constructif.
Bon... je crois qu'il va falloir que j'envoie des fleurs et une boite de chocolat à Bioware...

Le module ne prend pas la compilation... j'ai beau retourner le script dans tous les sens, le mettre en include dans des programmes de tests pour le faire compiler, puis le mettre en void main() pour le tester, puis me ronger les ongles... mais rien...


[EDIT : Après réception des orties et des croûtes de fromages, Bioware m'a suggéré de repartir d'un nouveau module. Heureusement que je fait des modules de tests d'une zone, ça m'évite la rédaction d'une lettre d'insultes Donc ça marche, mais à quel prix... il est peut être grand temps que ces braves gens pensent à achever cette mise à jour]
Répondre

Connectés sur ce fil

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