void cMonster::TickPathFinding() { const int PosX = POSX_TOINT; const int PosY = POSY_TOINT; const int PosZ = POSZ_TOINT; m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z); std::vector<Vector3d> m_PotentialCoordinates; m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ)); static const struct // Define which directions to try to move to { int x, z; } gCrossCoords[] = { { 1, 0}, {-1, 0}, { 0, 1}, { 0,-1}, } ; if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */) { // Too low/high, can't really do anything FinishPathFinding(); return; } for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) { continue; } BLOCKTYPE BlockAtY = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); int LowestY = FindFirstNonAirBlockPosition(gCrossCoords[i].x + PosX, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtLowestY = m_World->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ); if ( (!cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!IsBlockLava(BlockAtLowestY)) && (BlockAtLowestY != E_BLOCK_CACTUS) && (PosY - LowestY < FALL_DAMAGE_HEIGHT) ) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ)); } else if ( (cBlockInfo::IsSolid(BlockAtY)) && (BlockAtY != E_BLOCK_CACTUS) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!cBlockInfo::IsSolid(BlockAtYPP)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE) ) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } } if (!m_PotentialCoordinates.empty()) { Vector3f ShortestCoords = m_PotentialCoordinates.front(); for (std::vector<Vector3d>::const_iterator itr = m_PotentialCoordinates.begin(); itr != m_PotentialCoordinates.end(); ++itr) { Vector3f Distance = m_FinalDestination - ShortestCoords; Vector3f Distance2 = m_FinalDestination - *itr; if (Distance.SqrLength() > Distance2.SqrLength()) { ShortestCoords = *itr; } } m_Destination = ShortestCoords; m_Destination.z += 0.5f; m_Destination.x += 0.5f; } else { FinishPathFinding(); } }
void cMonster::TickPathFinding() { int PosX = (int)floor(GetPosX()); int PosY = (int)floor(GetPosY()); int PosZ = (int)floor(GetPosZ()); m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z); std::vector<Vector3d> m_PotentialCoordinates; m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ)); static const struct // Define which directions to try to move to { int x, z; } gCrossCoords[] = { { 1, 0}, {-1, 0}, { 0, 1}, { 0,-1}, } ; for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { if ((gCrossCoords[i].x + PosX == PosX) && (gCrossCoords[i].z + PosZ == PosZ)) { continue; } if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) { continue; } BLOCKTYPE BlockAtY = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYM = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY - 1, gCrossCoords[i].z + PosZ); if ((!g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ)); } else if ((g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!g_BlockIsSolid[BlockAtYPP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } } if (!m_PotentialCoordinates.empty()) { Vector3f ShortestCoords = m_PotentialCoordinates.front(); for (std::vector<Vector3d>::const_iterator itr = m_PotentialCoordinates.begin(); itr != m_PotentialCoordinates.end(); ++itr) { Vector3f Distance = m_FinalDestination - ShortestCoords; Vector3f Distance2 = m_FinalDestination - *itr; if (Distance.SqrLength() > Distance2.SqrLength()) { ShortestCoords = *itr; } } m_Destination = ShortestCoords; m_Destination.z += 0.5f; m_Destination.x += 0.5f; } else { FinishPathFinding(); } }