void PlayerController::enterNearestVehicle() { if (!character->getCurrentVehicle()) { auto world = character->engine; VehicleObject* nearest = nullptr; float d = 10.f; for (auto& p : world->vehiclePool.objects) { auto object = p.second; float vd = glm::length(character->getPosition() - object->getPosition()); if (vd < d) { d = vd; nearest = static_cast<VehicleObject*>(object); } } if (nearest) { setNextActivity(new Activities::EnterVehicle(nearest, 0)); } } }
void PlayerController::exitVehicle() { if (character->getCurrentVehicle()) { setNextActivity(std::make_unique<Activities::ExitVehicle>()); } }
void PlayerController::jump() { if (!character->isInWater() && character->isOnGround()) { setNextActivity(std::make_unique<Activities::Jump>()); } }
void PlayerController::jump() { if (!character->isInWater()) { setNextActivity(new Activities::Jump()); } }
void PlayerController::exitVehicle() { if (character->getCurrentVehicle()) { setNextActivity(new Activities::ExitVehicle()); } }
void DefaultAIController::update(float dt) { switch (currentGoal) { case FollowLeader: { if (!leader) break; if (getCharacter()->getCurrentVehicle()) { if (leader->getCurrentVehicle() != getCharacter()->getCurrentVehicle()) { skipActivity(); setNextActivity(std::make_unique<Activities::ExitVehicle>()); } // else we're already in the right spot. } else { if (leader->getCurrentVehicle()) { setNextActivity(std::make_unique<Activities::EnterVehicle>( leader->getCurrentVehicle(), 1)); } else { glm::vec3 dir = leader->getPosition() - getCharacter()->getPosition(); if (glm::length(dir) > followRadius) { if (glm::distance(gotoPos, leader->getPosition()) > followRadius) { gotoPos = leader->getPosition() + (glm::normalize(-dir) * followRadius * 0.7f); skipActivity(); setNextActivity(std::make_unique<Activities::GoTo>(gotoPos)); } } } } } break; case TrafficWander: { if (targetNode) { auto targetDistance = glm::vec2(character->getPosition() - targetNode->position); if (glm::length(targetDistance) <= 0.1f) { // Assign the next target node auto lastTarget = targetNode; std::random_device rd; std::default_random_engine re(rd()); std::uniform_int_distribution<> d( 0, lastTarget->connections.size() - 1); targetNode = lastTarget->connections.at(d(re)); setNextActivity(std::make_unique<Activities::GoTo>( targetNode->position)); } else if (getCurrentActivity() == nullptr) { setNextActivity(std::make_unique<Activities::GoTo>( targetNode->position)); } } else { // We need to pick an initial node auto& graph = getCharacter()->engine->aigraph; AIGraphNode* node = nullptr; float mindist = std::numeric_limits<float>::max(); for (auto n : graph.nodes) { float d = glm::distance(n->position, getCharacter()->getPosition()); if (d < mindist) { node = n; mindist = d; } } targetNode = node; } } break; default: break; } CharacterController::update(dt); }