void IngameState::handlePlayerInput(const SDL_Event& event) { auto player = game->getPlayer(); switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_SPACE: if( player->getCharacter()->getCurrentVehicle() ) { player->getCharacter()->getCurrentVehicle()->setHandbraking(true); } else { player->jump(); } break; case SDLK_f: if( player->getCharacter()->getCurrentVehicle()) { player->exitVehicle(); } else if (player->isCurrentActivity( Activities::EnterVehicle::ActivityName)) { // Give up entering a vehicle if we're alreadying doing so player->skipActivity(); } else { player->enterNearestVehicle(); } break; case SDLK_LSHIFT: player->setRunning(true); break; default: break; } break; case SDL_KEYUP: switch (event.key.keysym.sym) { case SDLK_LSHIFT: player->setRunning(false); break; default: break; } break; case SDL_MOUSEBUTTONDOWN: switch(event.button.button) { case SDL_BUTTON_LEFT: player->getCharacter()->useItem(true, true); break; default: break; } break; case SDL_MOUSEBUTTONUP: switch(event.button.button) { case SDL_BUTTON_LEFT: player->getCharacter()->useItem(false, true); break; default: break; } break; case SDL_MOUSEWHEEL: player->getCharacter()->cycleInventory(event.wheel.y > 0); break; case SDL_MOUSEMOTION: if (game->hasFocus()) { glm::ivec2 screenSize = getWindow().getSize(); glm::vec2 mouseMove(event.motion.xrel / static_cast<float>(screenSize.x), event.motion.yrel / static_cast<float>(screenSize.y)); autolookTimer = kAutoLookTime; if (!m_invertedY) { mouseMove.y = -mouseMove.y; } m_cameraAngles += glm::vec2(mouseMove.x, mouseMove.y); m_cameraAngles.y = glm::clamp(m_cameraAngles.y, kCameraPitchLimit, glm::pi<float>() - kCameraPitchLimit); } break; default: break; } }
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); }