Entity* AISystem::FilterNearestUnit(Entity* selectedUnit, set<Entity*> units) { Pathfinder* pathfinder = engine->GetContext()->GetPathfinder(); Entity* nearest = nullptr; int pathSize; int shortestPathSize = INT_MAX; for (Entity* unit : units) { UnitComponent* uc = dynamic_cast<UnitComponent*>(unit->GetComponent(Component::UNIT)); vector<Grid> path = pathfinder->FindPurePath(selectedUnit, unit); pathSize = static_cast<int>(path.size()); if (pathSize > 0 && ( pathSize < shortestPathSize || (pathSize == shortestPathSize && uc->type == Entity::HQ) // if path sizes are equal, favor HQ ) ) { shortestPathSize = pathSize; nearest = unit; } } return nearest; }
bool AISystem::MoveUnitTowardsEnemy(Entity* selectedUnit, Entity* enemy) { World* world = engine->GetContext()->GetWorld(); Pathfinder* pathfinder = engine->GetContext()->GetPathfinder(); vector<Grid> path = pathfinder->FindPurePath(selectedUnit, enemy); if (path.size() > 0) { UnitComponent* uc = dynamic_cast<UnitComponent*>(selectedUnit->GetComponent(Component::UNIT)); PositionComponent* upc = dynamic_cast<PositionComponent*>(selectedUnit->GetComponent(Component::POSITION)); Grid lastStep = *(path.end() - 1); SelectTarget(Graphics::Instance().ToPx(lastStep)); for (unsigned int i = 0; i <= uc->range_max; i++) { // last step is enemy unit so selectedUnit should not move there // unit should not move closer to enemy then is necessary to attack it path.pop_back(); if (path.size() == 1) { // path should not disappear entirely break; } } engine->GetContext()->SetGameState(Context::PL_MOVE); selectedUnit->Add(new AnimationComponent(path, upc->pos)); engine->UpdateEntity(selectedUnit); return true; } else { return false; } }