float Team::_getBestSpotOfReceiving(Player* receiver, float passing_force, Ogre::Vector3& target) { float best_score = -1; Ogre::Vector3 ball_pos = mBall->getPosition(); Ogre::Vector3 to_reciver = Vector3To2(receiver->getPosition() - ball_pos); float dist_to_receiver = to_reciver.length(); float length = receiver->getMaxSpeed() * mBall->getTimeToCoverDistance(dist_to_receiver, passing_force) * 0.8; float theta = asin(length / dist_to_receiver); int try_pass_times = 4; for (int i = 0; i <= try_pass_times; ++i) { Ogre::Radian angle(-theta + i * (2 * theta / try_pass_times)); Ogre::Quaternion rotation = GetRotationThroughHeading(to_reciver) * Ogre::Quaternion(angle, Ogre::Vector3(0, 1, 0)); Ogre::Vector3 aim_target = ball_pos + rotation * Ogre::Vector3(0, 0, dist_to_receiver); if (isSafeGoingThroughAllOpponents(ball_pos, aim_target, passing_force)) { float score = _getScoreOfPosition(aim_target); if (score > best_score) { best_score = score; target = aim_target; } } } return best_score; }
void Team::requestPass(Player* player, double delay_time /* = 0 */) { // With a possibility to execute if (WithPossibility(Prm.RequestPassPosibility)) { if (isSafeGoingThroughAllOpponents( getControllingPlayer()->getPosition(), player->getPosition(), Prm.PlayerMaxPassingForce) ) { MessageDispatcher::get().dispatchMessage( 0, player, getControllingPlayer(), MSG_REQUEST_PASS, player); } } }
bool Team::canShoot(const Ogre::Vector3& from, Ogre::Vector3& proper_target, float shooting_force) { Goal* goal = getOpponent()->getGoal(); float dist_to_goal = Vector3To2(from).distance(goal->getCenter()); // If too far from goal, it may be not a good chance to shoot if (dist_to_goal > Prm.PlayerShootingRange) { return false; } // If shooting angle is too narrow, drop it float theta = fabs(from.x - goal->getCenter().x) / dist_to_goal; if (asin(theta) < PI / 6) { return false; } int tot = Prm.PlayerShootingTryNum; Ogre::Vector3 left_to_right = goal->getRightPost() - goal->getLeftPost(); while (tot--) { Ogre::Vector3 target = goal->getLeftPost() + left_to_right * dt::Random::get(0.f, 1.f); // If safe to shot // or with some possibility if (isSafeGoingThroughAllOpponents(mBall->getPosition(), target, shooting_force) || WithPossibility(0.05)) { proper_target = target; return true; } } return false; }
void Team::requestPass(Player* player, double delay_time /* = 0 */) { // With a possibility to execute if (WithPossibility(Prm.RequestPassPosibility)) { float dot = mControllingPlayer->getHeading().dotProduct( (player->getPosition() - mControllingPlayer->getPosition()).normalisedCopy()); // Not behind the controlling player if (dot > -0.1 && isSafeGoingThroughAllOpponents( getControllingPlayer()->getPosition(), player->getPosition(), Prm.PlayerMaxPassingForce) ) { MessageDispatcher::get().dispatchMessage( 0, player, getControllingPlayer(), MSG_REQUEST_PASS, player); } } }