Ankama modifié la manière de se déplacer selon l'orientation

A

Anonymous

Invité
#1
Bonjour,

Je suis toujours en train de coder mon bot et je viens de remarquer que la manière de se déplacer (avec GameMapMovementRequestMessage et GameMapMovementConfirmMessage) a changé...
En effet, les cellId qu'envoie le client officiel ne sont plus toujours les mêmes pour une même case. Cela varie en fonction de l'orientation que doit prendre le personnage pour se déplacer :
  • Si le personnage doit s'orienter vers la droite pour bouger, alors l'ID de la case est normal (par exemple avec la case 0, l'ID reste 0)
  • Si le personnage doit s'orienter vers le bas pour bouger, alors l'ID de la case vaut ID_de_base + 8192 (par exemple l'ID de la case 0 devient 8192, l'ID de la case 28 vaut 8220)
  • Si le personnage doit s'orienter dans le sens droite-bas (en biais quoi), alors l'ID de la case vaut ID_de_base + 4096 (par exemple l'ID de la case 0 devient 4096, l'ID de la case 14 vaut 4110)

D'après mes observations qui, je pense, ne sont pas erronées.
Bien sûr il n'y a pas toutes les possibilités (il y a 8 orientations possibles).

Si on n'adapte pas les cellId, on reçoit un beau ConsoleMessage (ProtocolId = 75) :
(content = Chemin [499, 500] : Impossible de passer par la cellule 500 ; type = 2)
Bien sûr le message change en fonction d'où on veut se déplacer...


Avez-vous constaté la même chose ?
Quelle méthode vous semble la meilleure pour se déplacer (en gros comment détecter dans quel sens va devoir aller le personnage) ? J'ai bien pensé à essayer toutes les solutions possibles mais ça fait un peu bourrin (mais bon ça fonctionne quand même).
 
A

Anonymous

Invité
#2
Re: la société du jeu D. modifié la manière de se déplacer s

Ca toujours été comme ca, on envoie les cellules compressés avec l'orientation. J'ai toujours fait ca mais apparemment que d'autres personnes envoyaient juste le cell id et ca fonctionnait. J'imagine qu'ils ont seulement ajouté une vérification sur le serveur.

Bref, il suffit de compresser l'orientation et le cell id dans un même short:

Code:
 (short)(((int)Orientation & 7) << 12 | CellId & 4095);
 
A

Anonymous

Invité
#3
Re: la société du jeu D. modifié la manière de se déplacer s

Déjà, merci de ta réponse et de ton bout de code malgré sa complexité :p ! J'ai eu le temps de tester et ça fonctionne. Je décortiquerai ça demain parce qu'à cette heure ci, après une semaine de cours, j'ai pas les neurones prêts à faire des opérations sur des bits :geek: .

Par contre, autre chose qui a apparemment changé (à moins que ça ait toujours été comme ça) : le nombre de keyMouvements à envoyer pour un déplacement. En effet, à chaque fois que le personnage change de direction, il faut envoyer la keyMouvement qui correspond à la case du changement. Autant dire que c'est assez casse tête...
Pour l'instant, j'ai trouvé une parade :
  • J'attends le message d'erreur de ConsoleMessage, celui-ci m'indique toutes les cases à suivre pour arriver à mon but (je supprime tout ce qui est à l'extérieur des crochets, ceux-ci compris, et je récupère les cellId en splittant avec la virgule)
  • Je fais un int.Parse(cellIdString)
  • Pour finir j'envoie la liste de cellId que j'ai obtenue à une fonction qui fait tous les mouvements pour arriver au but

Je vous poste le code plus tard si vous voulez, là, je vais me coucher :arrow: .

Encore merci mikedotnet !
 
A

Anonymous

Invité
#4
Re: la société du jeu D. modifié la manière de se déplacer s

Je trouves que tu te compliques beaucoup la vie. Je te conseilles de ne pas utiliser cette façon de faire. Voici la marche à suivre:

Pour chaque cell dans ton path il faut calculer l'orientation par raport à la cell suivante.
La dernière cell garde l'orientation de la cell présédante.

Ensuite il faut prendre la première cell et l'ajouter à une liste différente. Il faut alors regarder les cells une par une sans les ajouter à cette deuxième liste. À chaque changement d'orientation, on ajoute cette cellule à la deuxième liste.

Par exemple si tu as le chemin suivant:

cell1(haut) cell2(haut) cell3(haut) cell4(droite) cell5(droite) cell6(haut) cell7(haut)

Tu prends chanque première cell qui change d'orientation ce qui donne au final le path à envoyer au serveur:

cell1(haut) cell4(droite) cell6(haut)

Finalement, il manque seulement à compresser les cell id`s de la deuxième liste avec les orientations et les envoyer.

p.s. C'est comme ca depuis toujours :)
 
A

Anonymous

Invité
#5
Re: la société du jeu D. modifié la manière de se déplacer s

Seul petit problème...
En fait, je viens de m'apercevoir que ConsoleMessage ne donnait pas le chemin à suivre :shock: ... Il donne des cellIds mais je ne sais pas à quoi elles correspondent...

Donc déjà, comment je trouve mon chemin ? Path finding ?
 
A

Anonymous

Invité
#6
Re: la société du jeu D. modifié la manière de se déplacer s

Tu trouve ton chemin comme avant avec un pathfinding. Il faut seulement modifier les cell id`s avant de les envoyer.
 
A

Anonymous

Invité
#7
Re: la société du jeu D. modifié la manière de se déplacer s

Ok, ça marche, merci.
Je vous tiens au courant le weekend ou la semaine prochaine parce que je vais avoir une semaine pas mal chargée, je n'aurai pas le temps de coder.
 
A

Anonymous

Invité
#8
Re: la société du jeu D. modifié la manière de se déplacer s

Me revoilà :) !

J'ai codé un petit bout de l'algo "PathFinder" un petit peu chaque soir et il est maintenant complet. Je me suis aidé de Traduction : article sur le pathfinding A*.

Après, j'ai fais comme tu as dis, je n'ai gardé que les 1ères cellules de chaque orientation, par exemple, pour aller de la cellId 66 à 501 en 6;-23 (As*rub) :
Code:
66 [None] = (11 ; 5)
94 [Bottom] = (11 ; 7)
122 [Bottom] = (11 ; 9)
150 [Bottom] = (11 ; 11)
178 [Bottom] = (11 ; 13)
206 [Bottom] = (11 ; 15)
234 [Bottom] = (11 ; 17)
262 [Bottom] = (11 ; 19)
290 [Bottom] = (11 ; 21)
318 [Bottom] = (11 ; 23)
346 [Bottom] = (11 ; 25)
374 [Bottom] = (11 ; 27)
402 [Bottom] = (11 ; 29)
430 [Bottom] = (11 ; 31)
458 [Bottom] = (11 ; 33)
486 [Bottom] = (11 ; 35)
487 [Right] = (12 ; 35)
501 [RightBottom] = (12 ; 36)
Ça donne :
Code:
66 // -> 66 (cellule de départ)
8286 // -> 94 + 8192 (bas)
487 // -> 487 + 0 (droite)
501 // -> 501 + 0 (on garde l'orientation de la cellId précédente, comme tu m'as dis)
Mais... Je reçois un beau GameMapNoMovementMessage et le personnage ne bouge pas.

Il y'a quelque chose que je n'ai pas saisis ou ça a changé ?
 
A

Anonymous

Invité
#9
Re: la société du jeu D. modifié la manière de se déplacer s

Je comprends pas trop ton resultat. D'apres ton path tu devrais compresser:

66 (bas)

486 (right)

487 (right bottom)

501 (right bottom)

TU met 487 car ca change d'orientation par raport avec la cellule suivante et tu dois recopier 501 avec la meme orientation pour definir la cellule de fin.
66 prend egalement l'orientation.

J'ai l'impression que tu calcules les orientations décalés d'une case.

De plus, tu ne semble pas appliqué la formule que je t'ai fourni pour la compression
Code:
 (short)(((int)Orientation & 7) << 12 | CellId & 4095);
Voici mon code qui génère les orientations

Code:
        public List<Dofusator.Data.Game.Positions.PathPoint> CleanPath(List<Point> path)
        {
            List<Dofusator.Data.Game.Positions.PathPoint> tempPath = new List<Dofusator.Data.Game.Positions.PathPoint>();
            foreach (Point p in path)
                tempPath.Add(new Dofusator.Data.Game.Positions.PathPoint(p, Dofusator.Data.Game.Orientation.Down));

            for (int i = 0; i < tempPath.Count - 1; i++)
            {
                tempPath[i].SetOrientation(tempPath[i + 1].Position);
            }

            tempPath[tempPath.Count - 1].Orientation = tempPath[tempPath.Count - 2].Orientation;

            if(tempPath.Count == 2)
                return tempPath;

            List<Dofusator.Data.Game.Positions.PathPoint> pathToRemove = new List<Dofusator.Data.Game.Positions.PathPoint>();
            for (int i = 1; i < tempPath.Count - 1; i++)
            {
                if (tempPath[i].Orientation == tempPath[i - 1].Orientation)
                    pathToRemove.Add(tempPath[i]);
            }

            tempPath.RemoveAll(n => pathToRemove.Contains(n));

            return tempPath;
        }
 

bouh2

Membre Actif
Inscrit
12 Septembre 2008
Messages
184
Reactions
21
#10
Re: la société du jeu D. modifié la manière de se déplacer s

Si on utilise (short)(((int)Orientation & 7) << 12 | CellId & 4095) c'est pour encoder sur un short (2 octets = 16 bits) l'orientation sur les 4 premiers bits (le << 12 décale l'orientation de 12 bits sur la gauche, et le & 7 impose une valeur inf ou égale à 7) et la cellule est encodé sur les 12 bits restant. & 4095 (= 0000 1111 1111 1111) impose une valeur inférieur à 4095.

Donc si tu as une orientation sud est (3 = 0011) et une cellule d'id 200 (200 = 0000 1100 1000) les valeurs seront encodé sur un short de la manière suivante :

0011 0000 1100 1000

Regarde des explications sur les opérateurs de bits pour plus d'information sur l'usage de << & et |
 
A

Anonymous

Invité
#11
Re: la société du jeu D. modifié la manière de se déplacer s

mikedotnet a dit:
Je comprends pas trop ton resultat. D'apres ton path tu devrais compresser:

66 (bas)

486 (right)

487 (right bottom)

501 (right bottom)

TU met 487 car ca change d'orientation par raport avec la cellule suivante et tu dois recopier 501 avec la meme orientation pour definir la cellule de fin.
66 prend egalement l'orientation.

J'ai l'impression que tu calcules les orientations décalés d'une case.

De plus, tu ne semble pas appliqué la formule que je t'ai fourni pour la compression
Code:
 (short)(((int)Orientation & 7) << 12 | CellId & 4095);
Voici mon code qui génère les orientations

Code:
        public List<D..Data.Game.Positions.PathPoint> CleanPath(List<Point> path)
        {
            List<D..Data.Game.Positions.PathPoint> tempPath = new List<D..Data.Game.Positions.PathPoint>();
            foreach (Point p in path)
                tempPath.Add(new D..Data.Game.Positions.PathPoint(p, D..Data.Game.Orientation.Down));

            for (int i = 0; i < tempPath.Count - 1; i++)
            {
                tempPath[i].SetOrientation(tempPath[i + 1].Position);
            }

            tempPath[tempPath.Count - 1].Orientation = tempPath[tempPath.Count - 2].Orientation;

            if(tempPath.Count == 2)
                return tempPath;

            List<D..Data.Game.Positions.PathPoint> pathToRemove = new List<D..Data.Game.Positions.PathPoint>();
            for (int i = 1; i < tempPath.Count - 1; i++)
            {
                if (tempPath[i].Orientation == tempPath[i - 1].Orientation)
                    pathToRemove.Add(tempPath[i]);
            }

            tempPath.RemoveAll(n => pathToRemove.Contains(n));

            return tempPath;
        }
Ahh !
En fait avec ton précédent message, j'avais très mal compris ce qu'il fallait faire (je m'étais basé sur ton exemple mais je l'avais interprété d'une autre manière que toi).
Maintenant c'est bon :) .

Pour ce qui est de la ligne :
Code:
(short)(((int)Orientation & 7) << 12 | CellId & 4095);
En fait si je comprends bien, c'est une manière "super-optimisée" de compresser la cellId avec l'orientation (à la place d'un tas de if et de faire "manuellement" cellId + orientation) ?


bouh2 a dit:
Si on utilise (short)(((int)Orientation & 7) << 12 | CellId & 4095) c'est pour encoder sur un short (2 octets = 16 bits) l'orientation sur les 4 premiers bits (le << 12 décale l'orientation de 12 bits sur la gauche, et le & 7 impose une valeur inf ou égale à 7) et la cellule est encodé sur les 12 bits restant. & 4095 (= 0000 1111 1111 1111) impose une valeur inférieur à 4095.

Donc si tu as une orientation sud est (3 = 0011) et une cellule d'id 200 (200 = 0000 1100 1000) les valeurs seront encodé sur un short de la manière suivante :

0011 0000 1100 1000

Regarde des explications sur les opérateurs de bits pour plus d'information sur l'usage de << & et |
Très bonne explication, merci d'avoir pris le temps de l'écrire, ça m'a beaucoup éclairé :) .
Aussi, j'ai lu Programmation C Sharp - Les opérateurs de manipulation des bits et j'ai fais quelques petites "manipulations", maintenant je suis un peu plus à l'aise.


J'ai tout modifié et maintenant le personnage bouge sans broncher :p !

Merci à vous deux !
 
Haut Bas