La difficulté majeure, c'est le fait que les mapIds de transition de zone soient faussés.
Lorsqu'on souhaite prévoir le déplacement d'une map x à une map y qui se trouvent dans deux zone différentes,
on se retrouve avec des mapIds invalides dans les mapData, ce qui rend difficile la prévision du déplacement,
puisqu'on doit être capable de déterminer si une map permet l'accès à une certaines direction (north, south, west, east) depuis un emplacement de joueur (pour ne pas se bloquer dans les murs d'astrub par exemple).
Pour remédier à ça, j'avais fait un truc comme ça:
MapData = MapsManager.GetMapFromId((int)MapId);
WorldMap currentPosition = null;
if (finder.Path.Count > 2)
currentPosition = finder.Path[finder.Path.Count - 2];
if (MapData == null && currentPosition != null)
{
MapData = MapsManager.GetMapFromCoord(RealCoordinates.X, RealCoordinates.Y, currentPosition.CoordinatesData.worldMap);
if (MapData == null)
{
Console.WriteLine("Map inexistante : " + map.RealCoordinates.ToString());
return;
}
MapId = (uint)MapData.Id;
}
MapData = MapsManager.GetMapFromId((int)MapId);
WorldMap currentPosition = null;
if (finder.Path.Count > 2)
currentPosition = finder.Path[finder.Path.Count - 2];
if (MapData == null && currentPosition != null)
{
MapData = MapsManager.GetMapFromCoord(RealCoordinates.X, RealCoordinates.Y, currentPosition.CoordinatesData.worldMap);
if (MapData == null)
{
Console.WriteLine("Map inexistante : " + map.RealCoordinates.ToString());
return;
}
MapId = (uint)MapData.Id;
}
Si on trouve pas la map via sa mapId, on la recherche via ses coordonnées dans les mapData.
Si on ne trouve toujours rien, je récupère la map ayant le niveau le plus haut (map extérieur) dans les D2O et ayant l'area & la subArea correspondantes.
Attention c'est à adapter, si vous êtes dans des mines, des maisons ou des ateliers etc ça ne fonctionne pas.
Et en cadeau c'était mon CanChangeMap:
public static int CanChangeMap(uint mapId, uint startCell, Map map, MovementDirectionEnum direction)
{
int neighbourId = -1;
int check = -1;
bool special = false;
if (map == null)
return -1;
switch (direction)
{
case MovementDirectionEnum.North:
neighbourId = map.TopNeighbourId;
check = 64;
break;
case MovementDirectionEnum.South:
neighbourId = map.BottomNeighbourId;
check = 4;
break;
case MovementDirectionEnum.East:
neighbourId = map.RightNeighbourId;
check = 1;
break;
case MovementDirectionEnum.West:
neighbourId = map.LeftNeighbourId;
check = 16;
break;
}
if ((check != -1) && (neighbourId >= 0))
{
List<int> possibleCells = new List<int>();
// Possible Basic Cells
for (int i = 0; i <= map.Cells.Count - 1; i++)
if (((map.Cells.MapChangeData & check) != 0 && ((map.Cells.Mov))))
possibleCells.Add(i);
if (possibleCells.Count == 0)
{
// Possible Special Cells
special = true;
for (int i = 0; i <= map.Cells.Count - 1; i++)
{
if (map.Cells.Mov)
{
bool possible = false;
switch (direction)
{
case MovementDirectionEnum.North:
if (map.Cells.TopArrow == true)
possible = true;
break;
case MovementDirectionEnum.South:
if (map.Cells.BottomArrow == true)
possible = true;
break;
case MovementDirectionEnum.East:
if (map.Cells.LeftArrow == true)
possible = true;
break;
case MovementDirectionEnum.West:
if (map.Cells.RightArrow == true)
possible = true;
break;
}
if (possible == true)
possibleCells.Add(i);
}
}
}
if (possibleCells.Count == 0)
return -1;
int cell = possibleCells[RandomCell(0, possibleCells.Count - 1)];
Pathfinder finder = new Pathfinder();
finder.SetMap(map, null, true);
List<CellWithOrientation> path = finder.GetPath((short)startCell, (short)cell);
if (path != null)
{
return cell;
}
}
return -1;
}
Ya le gamePathinder ici aussi : https://github.com/BlueDream145/Pathfinder-2.0