OTx
Member
- Joined
- Aug 3, 2012
- Messages
- 126
- Reaction score
- 10
Hello everyone!
I am working on a school project that involves some mechanisms in Tibia. I wanted to know more about pathfinding that Tibia is using. I looked through the source code of Crying Damson 0.3.6pl and found some Astar code in map.cpp and map.h.
map.cpp
So what I want is to implement this on Java, the language that I am working with right now.
I have already started and got a working piece in my own project but the only problem is that the nodes that I am putting out on my own map, they are not working as great as it does in Tibia. By the way, my project is using astar pathfinding with a navigation mesh, thus navigation mesh with polygons instead of single tiles.
So my question is how Tibia is putting out nodes itself, you know when someone is mapping on RME-mapeditor and every node is connected to each other automaticly.
Thansk in advance if you have any clue!
I am working on a school project that involves some mechanisms in Tibia. I wanted to know more about pathfinding that Tibia is using. I looked through the source code of Crying Damson 0.3.6pl and found some Astar code in map.cpp and map.h.
map.cpp
Code:
//*********** AStarNodes *************
AStarNodes::AStarNodes()
{
curNode = 0;
openNodes.reset();
}
AStarNode* AStarNodes::createOpenNode()
{
if(curNode >= MAX_NODES)
return NULL;
uint32_t retNode = curNode;
curNode++;
openNodes[retNode] = 1;
return &nodes[retNode];
}
AStarNode* AStarNodes::getBestNode()
{
if(!curNode)
return NULL;
int32_t bestNodeF = 100000;
uint32_t bestNode = 0;
bool found = false;
for(uint32_t i = 0; i < curNode; i++)
{
if(nodes[i].f < bestNodeF && openNodes[i] == 1)
{
found = true;
bestNodeF = nodes[i].f;
bestNode = i;
}
}
if(found)
return &nodes[bestNode];
return NULL;
}
void AStarNodes::closeNode(AStarNode* node)
{
uint32_t pos = GET_NODE_INDEX(node);
if(pos < MAX_NODES)
{
openNodes[pos] = 0;
return;
}
assert(pos >= MAX_NODES);
std::cout << "AStarNodes. trying to close node out of range" << std::endl;
return;
}
void AStarNodes::openNode(AStarNode* node)
{
uint32_t pos = GET_NODE_INDEX(node);
if(pos < MAX_NODES)
{
openNodes[pos] = 1;
return;
}
assert(pos >= MAX_NODES);
std::cout << "AStarNodes. trying to open node out of range" << std::endl;
return;
}
uint32_t AStarNodes::countClosedNodes()
{
uint32_t counter = 0;
for(uint32_t i = 0; i < curNode; i++)
{
if(!openNodes[i])
counter++;
}
return counter;
}
uint32_t AStarNodes::countOpenNodes()
{
uint32_t counter = 0;
for(uint32_t i = 0; i < curNode; i++)
{
if(openNodes[i] == 1)
counter++;
}
return counter;
}
bool AStarNodes::isInList(uint16_t x, uint16_t y)
{
for(uint32_t i = 0; i < curNode; i++)
{
if(nodes[i].x == x && nodes[i].y == y)
return true;
}
return false;
}
AStarNode* AStarNodes::getNodeInList(uint16_t x, uint16_t y)
{
for(uint32_t i = 0; i < curNode; i++)
{
if(nodes[i].x == x && nodes[i].y == y)
return &nodes[i];
}
return NULL;
}
int32_t AStarNodes::getMapWalkCost(const Creature* creature, AStarNode* node,
const Tile* neighbourTile, const Position& neighbourPos)
{
if(std::abs(node->x - neighbourPos.x) == std::abs(node->y - neighbourPos.y)) //diagonal movement extra cost
return MAP_DIAGONALWALKCOST;
return MAP_NORMALWALKCOST;
}
int32_t AStarNodes::getTileWalkCost(const Creature* creature, const Tile* tile)
{
int32_t cost = 0;
if(tile->getTopVisibleCreature(creature)) //destroy creature cost
cost += MAP_NORMALWALKCOST * 3;
if(const MagicField* field = tile->getFieldItem())
{
if(!creature->isImmune(field->getCombatType()))
cost += MAP_NORMALWALKCOST * 3;
}
return cost;
}
int32_t AStarNodes::getEstimatedDistance(uint16_t x, uint16_t y, uint16_t xGoal, uint16_t yGoal)
{
int32_t diagonal = std::min(std::abs(x - xGoal), std::abs(y - yGoal));
return (MAP_DIAGONALWALKCOST * diagonal) + (MAP_NORMALWALKCOST * ((std::abs(
x - xGoal) + std::abs(y - yGoal)) - (2 * diagonal)));
}
So what I want is to implement this on Java, the language that I am working with right now.
I have already started and got a working piece in my own project but the only problem is that the nodes that I am putting out on my own map, they are not working as great as it does in Tibia. By the way, my project is using astar pathfinding with a navigation mesh, thus navigation mesh with polygons instead of single tiles.
So my question is how Tibia is putting out nodes itself, you know when someone is mapping on RME-mapeditor and every node is connected to each other automaticly.
Thansk in advance if you have any clue!
Last edited: