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

Panneau de contrôle

Recherche | Retour aux forums

JOL Archives

[script]Areas transitions intelligentes

Par Azrael07 le 6/12/2002 à 21:58:01 (#2728061)

Areas transitions intelligentes

Ce script permet de récupérer la position d'une créature utilisant une area transition pour la restaurer dans l'area ciblée, ce qui permet l'utilisation d'areas transitions sur de très grandes surfaces, et sans surcharger l'area cible de waypoints.

Si ce script s'avère être très pratique, son utilisation n'est pas simple. Je vais m'efforcer de l'expliquer de la facon la plus claire possible

1. La création de l'area transition :

Il faut prendre un déclancheur générique et tracer la zone de transition, de préférence à l'extrémité de la zone, et en respectant la condition suivante :

Le trigger ne doit pas dépacer les diagonales des côtés de l'area correspondantes au trigger. Bon comme c'est vraiment pas claire, je vais donner un exemple en image :

http://azrael07.free.fr/nwn/areatransition_oui.jpghttp://azrael07.free.fr/nwn/areatransition_non.jpg

Notez bien que si cette condition n'est pas respecté, le joueur risque de se retrouver à une position de la zone cible incorecte.

Evitez de faire des areas transitions trop larges, elles ne doivent en AUCUNS CAS dépasser 2 unités en largeurs (on peut voir les coordonnés en bas a gauche de la fenetre d'aurora). En revanche, la longeur ne pose aucun problème, l'area transition peut donc faire la totalité d'un bord de zone, a condition que la condition des diagonales soit respectée.

2. L'affectation des scripts :

Le script suivant peut être placé à deux endroits différents selon le résultat voulu. Si on le met sur le OnUse du trigger, il se comportera comme une area transition standard, le joueur se déplacera si celui ci utilise, donc click sur le trigger. Le script est également adapté au OnEnter, qui permetra au joueur de ce déplacer directement en entrant dans le trigger, ce qui évite l'infame curseur bleu propre a l'area transition, et fait peut etre un peu plus réaliste. Personnelement c'est comme ca que je l'utilise.


//::///////////////////////////////////////////////
//:: Areas Transitions
//:: 4a_tr_en_trans
//:: Copyright (c) 2003 Module 4e age
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Créé par : Azrael07
//:: Créé le : 06/12/2002
//:://////////////////////////////////////////////

void DoActionChangeArea(object oCreature, object oAreaTransition = OBJECT_SELF)
{
//On recuere la position et l'orientation de la creature qui change d'area
object oArea = GetArea(oCreature);

vector vPlayerPosition = GetPosition(oCreature);
float fOrientation = GetFacing(oCreature);

//Comme ce script va s'appliquer a une quasi totalite de mon module, je ne
//vais pas le modifier pour chaques areatransition, donc tout les localsobject serons initialises dans le OnModuleLoad
object oNewArea = GetLocalObject(oAreaTransition, "TrgAr");

//Les tailles des deux areas sont utilises pout le calcul de la nouvelle position
float fSizeX = IntToFloat(GetLocalInt(oArea, "SzX")) * 10.0f;
float fSizeY = IntToFloat(GetLocalInt(oArea, "SzY")) * 10.0f;

float fNewSizeX = IntToFloat(GetLocalInt(oNewArea, "SzX")) * 10.0f;
float fNewSizeY = IntToFloat(GetLocalInt(oNewArea, "SzY")) * 10.0f;

float fAdapt = fSizeX / fSizeY;

float fFactor = GetLocalFloat( oAreaTransition, "Fact");
if (fFactor == 0.0f) fFactor = 1.0f;

float fStartingPoint = GetLocalFloat( oAreaTransition, "StrPnt") * 10.0f;

float fNewPosition;
vector vNewPosition;
//Calcul de la nouvelle position en fonction de la direction a laquelle pointe le trigger
if( vPlayerPosition.x > vPlayerPosition.y * fAdapt && fSizeX - vPlayerPosition.x >= vPlayerPosition.y * fAdapt)
{
if (fStartingPoint > 0.0f) fNewPosition = vPlayerPosition.x * fFactor + fStartingPoint;
else fNewPosition = ( vPlayerPosition.x + fStartingPoint ) * fFactor;

vNewPosition = Vector( fNewPosition, fNewSizeY - 2.0f , vPlayerPosition.z);
}
else if( vPlayerPosition.x > vPlayerPosition.y * fAdapt && fSizeX - vPlayerPosition.x 0.0f) fNewPosition = vPlayerPosition.y * fFactor + fStartingPoint;
else fNewPosition = ( vPlayerPosition.y + fStartingPoint ) * fFactor;

vNewPosition = Vector( 2.0f, fNewPosition, vPlayerPosition.z);
}
else if( vPlayerPosition.x = fSizeY - vPlayerPosition.y * fAdapt)
{
if (fStartingPoint > 0.0f) fNewPosition = vPlayerPosition.x * fFactor + fStartingPoint;
else fNewPosition = ( vPlayerPosition.x + fStartingPoint ) * fFactor;

vNewPosition = Vector( fNewPosition, 2.0f, vPlayerPosition.z);
}
else if( vPlayerPosition.x < vPlayerPosition.y * fAdapt && vPlayerPosition.x 0.0f) fNewPosition = vPlayerPosition.y * fFactor + fStartingPoint;
else fNewPosition = ( vPlayerPosition.y + fStartingPoint ) * fFactor;

vNewPosition = Vector( fNewSizeX - 2.0f, fNewPosition, vPlayerPosition.z);
}

PrintVector(vPlayerPosition, TRUE);

//on met tout ca dans une location
location lNewLocation = Location(oNewArea, vNewPosition, fOrientation);

//et on le jump
AssignCommand(oCreature, ClearAllActions());
AssignCommand(oCreature, ActionJumpToLocation(lNewLocation));
}

void main()
{
//On prend les references indispensables
object oCreature = GetEnteringObject();

//On verifie si le joueur n'est pas deja dans une area transition avant de
//l'envoyer autre part
int nIsInAreaTransition = GetLocalInt(oCreature, "InArTr");
if (!nIsInAreaTransition)
{
object oAreaTransition = GetLocalObject(OBJECT_SELF, "ArTrAssoc");
if(!GetIsObjectValid(oAreaTransition)) oAreaTransition = OBJECT_SELF;
//On appelle la fonction
DoActionChangeArea(oCreature, oAreaTransition);
}
SetLocalInt(oCreature, "InArTr", nIsInAreaTransition + 1);
}


puis le script suivant doit être mis dans le OnExit du trigger :


//::///////////////////////////////////////////////
//:: Areas Transitions Intelligentes
//:: 4a_tr_ex_trans
//:: Copyright (c) 2003 Module 4e age
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Créé par : Azrael07
//:: Créé le : 04/12/2002
//:://////////////////////////////////////////////

void main()
{
object oCreature = GetExitingObject();
int bIsInAreaTransition = GetLocalInt(oCreature, "InArTr");

bIsInAreaTransition--;
ERROR("bIsInAr = " + IntToString(bIsInAreaTransition));
if(bIsInAreaTransition)
SetLocalInt(oCreature, "InArTr", bIsInAreaTransition);
else
//On detruit la variable plutot que l'initialiser a FALSE pour liberer des
//ressources
DeleteLocalInt(oCreature, "InArTr");
}


Bon jusqu'a présent, rien de bien compliqué, a part du copier/coller.

3.La configuration de l'area transition :

voila la ca se complique, il va faloir initialiser des variables dans le OnLoad du module :

Pour chaques zone source et[:B] cible, le script suivant devras être rentré :

SetLocalFloat(GetObjectByTag("TAG_DE_LA_ZONE"), "SzX", TailleXDeLaZone);
SetLocalFloat(GetObjectByTag("TAG_DE_LA_ZONE"), "SzY", TailleYDeLaZone);


la TailleDeLaZone correspond à ces dimentions, c'est à dire au nombre de carreaux multiplié par 10.
donc un petit exemple, une zone de tag "Zone1" de dimentions 16*32 donnera :

SetLocalFloat(GetObjectByTag("Zone1"), "SzX", 160.0f);
SetLocalFloat(GetObjectByTag("Zone1"), "SzY", 320.0f);

Puis il faudra entrer les valeurs suivants pour chaques areas transition :


SetLocalObject(GetObjectByTag("TAG_DU_TRIGGER"), "TrgAr", GetObjectByTag("TAG_DE_LA_ZONE_CIBLE"));
//SetLocalFloat(GetObjectByTag("TAG_DU_TRIGGER"), "Fact", fFacteur);
//SetLocalFloat(GetObjectByTag("TAG_DU_TRIGGER"), "StrPnt", fStartingPoint);


la première donnée tombe sous le sens, les deux autres beaucoup moins. Dans un premier temp, il faut savoir qu'elles sont optionnelles. Si elles ne sont pas initialisés, Fact prendra pour valeur par default 1.0f et StrPn prendra 0.0f

fFactor représente le facteur multiplicateur des coordonnés de la première zone a la seconde, et cela permet la gestion de déplacement vers des zones de taille différentes.
le mieux pour comprendre est un exemple : on veut aller d'une area de 8*8 à une area de 16*16, sachant que les deux areas doivent avoir une area transition de toute la longeur de la zone. Il suffit de mettre 2.0f en fFactor, et un joueur quittant la zone en un point de coordonnée 3.0f se retrouvera à un point de coordonnée 6.0f. La meme situation inversée donnera un facteur multiplicateur de 1/2, ainsi il quiterai un point par exemple de 15.0f pour arriver à un point de 7.5f

fStartingPoint ajoute sa valeur au nouvelles coordonnés du joueur. ex : Un joueur quitte une area de 8*8 a l'est pour arriver a une area de 16*16. Toute la partie sud de cette dernière ne doit pas être accessible par la première area (mais par une autre par exemple). On va donc mettre 8.0f en fStartingPoint. De ce fait, un joueur quittant la première area en un point 6.0f arrivera a un point 14.0f. Le déplacement de la seconde zone vers la première aura fStartingPoint = -8.0f.


Voila je pense que j'ai dut vous expliquer en gros les possibilités du script (enfin si vous avez compris pasque je dois pas être très clair). Il est possible, et meme probable que je rajoute encore quelques possibilités au script, je mettrais ce post a jour si c'est le cas.

Le script est grossièrement testé, mais je n'ai pas testé toutes les possibilités. Si vous voyez des bugs, signalez le moi ;)

EDIT : Mise a jour

Par Azrael07 le 12/2/2003 à 22:18:19 (#3226058)

petite mise a jour qui corrige un gros bug (la sortie par l'est d'une zone envoyais le joueur a l'angle ou qu'il se trouve)

Vala j'ai pas trouvé d'autres bugs, mais si y'en a je tiendrais ce post a jour ;)

Par Cheni Poussière le 13/2/2003 à 22:12:43 (#3233540)

:aide:
Si j'ai tout compris, ça sert à faire passer un joueur (ou autre chose) d'une area à l'autre en respectant sa position (s'il sort par le sud de la zone, il rentre au sud de la zone suivante), sans qu'il n'y ait forcément besoin de cliquer sur le trigger, c'est bien ça ?

Par Azrael07 le 13/2/2003 à 22:49:54 (#3233735)

et bien pour être exact, ben c'est exactement ca ;)


sans qu'il n'y ait forcément besoin de cliquer sur le trigger,


Ca tu peux faire comme tu veux, il suffit de mettre ton script dans le OnClick plutot que le OnEnter si tu veux le faire en clickant dessus plutot qu'en entrand dedans, a toi de voir selon tes envies

Par Cheni Poussière le 13/2/2003 à 23:04:45 (#3233808)

Le code me paraît énorme (bien plus joli que tout ce que je peux faire, cela dit ;) ) , mais l'idée est originale et intelligente.

Par Azrael07 le 13/2/2003 à 23:21:46 (#3233897)

Le code me paraît énorme


vi mais c'est pas un problème, suffit juste de le recopier bètement et de suivre (si c'est possible vu comme je sais pas écrire) le petit tut qui suit ;)

Par Cheni Poussière le 13/2/2003 à 23:26:50 (#3233934)

Oh, je ne disais pas que c'était dur à installer :D . Simplement, c'est un gros boulot.

Par mobidique le 14/2/2003 à 15:28:38 (#3238041)

Provient du message de Cheni Poussière
Si j'ai tout compris [...] (s'il sort par le sud de la zone, il rentre au sud de la zone suivante)Pil poil :D Meuh nan ... S'il sort par le sud d'une zone il va rentrer par le nord dans l'autre :rolleyes: Mais je ne pense pas que le script gère cela alors si en allant au sud tu veux faire rentrer tes joueurs par le sud après tout ...

Par Delphinea le 14/2/2003 à 16:28:29 (#3238504)

On trouve ça aussi sur nwvault:

smart edge transfer

JOL Archives 1.0.1
@ JOL / JeuxOnLine