// Get all neighbouring directions RoadTile::Directions RoadTile::getNeighbouringDirections() { Directions dir; for (Tile* t : getNeighbours()) { dir.insert(Tile::calculateDirection(getTilePosition(), t->getTilePosition())); } return dir; }
bool Route::Path::Find(s32 to, int limit) { const int pathfinding = hero->GetLevelSkill(Skill::Secondary::PATHFINDING); const s32 from = hero->GetIndex(); s32 cur = from; s32 alt = 0; s32 tmp = 0; std::map<s32, cell_t> list; std::map<s32, cell_t>::iterator it1 = list.begin(); std::map<s32, cell_t>::iterator it2 = list.end(); list[cur].cost_g = 0; list[cur].cost_t = 0; list[cur].parent = -1; list[cur].open = 0; const Directions directions = Direction::All(); clear(); while(cur != to) { LocalEvent::Get().HandleEvents(false); for(Directions::const_iterator it = directions.begin(); it != directions.end(); ++it) { if(Maps::isValidDirection(cur, *it)) { tmp = Maps::GetDirectionIndex(cur, *it); if(list[tmp].open) { const u32 costg = GetPenaltyFromTo(cur, tmp, *it, pathfinding); // new if(-1 == list[tmp].parent) { if((list[cur].passbl & *it) || PassableFromToTile(*hero, cur, tmp, *it, to)) { list[cur].passbl |= *it; list[tmp].direct = *it; list[tmp].cost_g = costg; list[tmp].parent = cur; list[tmp].open = 1; list[tmp].cost_d = 50 * Maps::GetApproximateDistance(tmp, to); list[tmp].cost_t = list[cur].cost_t + costg; } } // check alt else { if(list[tmp].cost_t > list[cur].cost_t + costg && ((list[cur].passbl & *it) || PassableFromToTile(*hero, cur, tmp, *it, to))) { list[cur].passbl |= *it; list[tmp].direct = *it; list[tmp].parent = cur; list[tmp].cost_g = costg; list[tmp].cost_t = list[cur].cost_t + costg; } } } } } list[cur].open = 0; it1 = list.begin(); alt = -1; tmp = MAXU16; DEBUG(DBG_OTHER, DBG_TRACE, "route, from: " << cur); // find minimal cost for(; it1 != it2; ++it1) if((*it1).second.open) { const cell_t & cell2 = (*it1).second; #ifdef WITH_DEBUG if(IS_DEBUG(DBG_OTHER, DBG_TRACE) && cell2.cost_g != MAXU16) { int direct = Direction::Get(cur, (*it1).first); if(Direction::UNKNOWN != direct) { VERBOSE("\t\tdirect: " << Direction::String(direct) << ", index: " << (*it1).first << ", cost g: " << cell2.cost_g << ", cost t: " << cell2.cost_t << ", cost d: " << cell2.cost_d); } } #endif if(cell2.cost_t + cell2.cost_d < tmp) { tmp = cell2.cost_t + cell2.cost_d; alt = (*it1).first; } } // not found, and exception if(MAXU16 == tmp || -1 == alt) break; #ifdef WITH_DEBUG else DEBUG(DBG_OTHER, DBG_TRACE, "select: " << alt); #endif cur = alt; if(0 < limit && GetCurrentLength(list, cur) > limit) break; } // save path if(cur == to) { while(cur != from) { push_front(Route::Step(list[cur].parent, list[cur].direct, list[cur].cost_g)); cur = list[cur].parent; } } else { DEBUG(DBG_OTHER, DBG_TRACE, "not found" << ", from:" << from << ", to: " << to); } return !empty(); }
// Update texture and texture direction void RoadTile::updateTile() { Directions dir = getNeighbouringDirections(); int size = dir.size(); // Find which directions exist bool east, west, south, north = false; east = (std::find(dir.begin(), dir.end(), Tile::EAST) != dir.end()); south = (std::find(dir.begin(), dir.end(), Tile::SOUTH) != dir.end()); west = (std::find(dir.begin(), dir.end(), Tile::WEST) != dir.end()); north = (std::find(dir.begin(), dir.end(), Tile::NORTH) != dir.end()); // Rotating if (size == 2) { // Strait if ((east && west) || (south && north)) { mSprite.setTexture(mTextureManager->getRoad_strait()); if (south || north) mSprite.setRotation(90.0f); else mSprite.setRotation(0.0f); } // Turn else { mSprite.setTexture(mTextureManager->getRoad_turn()); if (west && north) mSprite.setRotation(90.0f); else if (north && east) mSprite.setRotation(180.0f); else if (east && south) mSprite.setRotation(270.0f); else mSprite.setRotation(0.0f); } } // Three-way else if (size == 3) { mSprite.setTexture(mTextureManager->getRoad_threeWay()); if (north && west && south) mSprite.setRotation(90.0f); else if (east && north && west) mSprite.setRotation(180.0f); else if (south && east && north) mSprite.setRotation(270.0f); else mSprite.setRotation(0.0f); } // Four-way else if (size == 4) { mSprite.setTexture(mTextureManager->getRoad_fourWay()); } // Dead end else { mSprite.setTexture(mTextureManager->getRoad_blank()); mSprite.setRotation(0.0f); } }