/** Function to let AI get unstuck. * \param dt Time step size. * \return True if getting stuck is needed to be done. */ bool ArenaAI::gettingUnstuck(const float dt) { if (!m_is_stuck || m_is_uturn) return false; resetAfterStop(); setSteering(0.0f, dt); m_controls->setBrake(true); m_time_since_reversing += dt; if (m_time_since_reversing >= 1.0f) { m_is_stuck = false; m_time_since_reversing = 0.0f; } AIBaseController::update(dt); return true; } // gettingUnstuck
/** Update \ref m_front_transform for ball aiming functions, also make AI stop * after goal. * \param dt Time step size. */ void SoccerAI::update(int ticks) { #ifdef BALL_AIM_DEBUG Vec3 red = m_world->getBallAimPosition(KART_TEAM_RED); Vec3 blue = m_world->getBallAimPosition(KART_TEAM_BLUE); m_red_sphere->setPosition(red.toIrrVector()); m_blue_sphere->setPosition(blue.toIrrVector()); #endif m_force_brake = false; m_chasing_ball = false; m_front_transform.setOrigin(m_kart->getFrontXYZ()); m_front_transform.setBasis(m_kart->getTrans().getBasis()); if (m_world->getPhase() == World::GOAL_PHASE) { resetAfterStop(); m_controls->setBrake(false); m_controls->setAccel(0.0f); AIBaseController::update(ticks); return; } ArenaAI::update(ticks); } // update
/** This is the main entry point for the AI. * It is called once per frame for each AI and determines the behaviour of * the AI, e.g. steering, accelerating/braking, firing. * \param dt Time step size. */ void ArenaAI::update(float dt) { // This is used to enable firing an item backwards. m_controls->setLookBack(false); m_controls->setNitro(false); // Let the function below to reset it later m_controls->setAccel(0.0f); m_controls->setBrake(false); m_mini_skid = false; // Don't do anything if there is currently a kart animations shown. if (m_kart->getKartAnimation()) { resetAfterStop(); return; } if (!isKartOnRoad() && m_kart->isOnGround()) { m_time_since_off_road += dt; } else if (m_time_since_off_road != 0.0f) { m_time_since_off_road = 0.0f; } // If the kart needs to be rescued, do it now (and nothing else) if (m_time_since_off_road > 5.0f && m_kart->isOnGround()) { m_time_since_off_road = 0.0f; new RescueAnimation(m_kart); AIBaseController::update(dt); return; } if (isWaiting()) { AIBaseController::update(dt); return; } checkIfStuck(dt); if (gettingUnstuck(dt)) return; findTarget(); // After found target, convert it to local coordinate, used for skidding or // u-turn if (!m_is_uturn) { m_target_point_lc = m_kart->getTrans().inverse()(m_target_point); doSkiddingTest(); configSteering(); } else { m_target_point_lc = m_kart->getTrans().inverse()(m_reverse_point); } useItems(dt); if (m_kart->getSpeed() > 15.0f && !m_is_uturn && m_turn_radius > 30.0f && !ignorePathFinding()) { // Only use nitro when turn angle is big (180 - angle) m_controls->setNitro(true); } if (m_is_uturn) { resetAfterStop(); doUTurn(dt); } else { configSpeed(); setSteering(m_steering_angle, dt); } AIBaseController::update(dt); } // update