/** Initializes the soccer world. It sets up the data structure
 *  to keep track of points etc. for each kart.
 */
void SoccerWorld::init()
{
    m_kart_team_map.clear();
    m_kart_position_map.clear();
    WorldWithRank::init();
    m_display_rank = false;
    m_goal_timer = 0.0f;
    m_ball_hitter = -1;
    m_ball = NULL;
    m_ball_body = NULL;
    m_goal_target = race_manager->getMaxGoal();
    m_goal_sound = SFXManager::get()->createSoundSource("goal_scored");

    TrackObjectManager* tom = getTrack()->getTrackObjectManager();
    assert(tom);
    PtrVector<TrackObject>& objects = tom->getObjects();
    for (unsigned int i = 0; i < objects.size(); i++)
    {
        TrackObject* obj = objects.get(i);
        if(!obj->isSoccerBall())
            continue;
        m_ball = obj;
        m_ball_body = m_ball->getPhysicalObject()->getBody();
        // Handle one ball only
        break;
    }
    if (!m_ball)
        Log::fatal("SoccerWorld","Ball is missing in soccer field, abort.");

    m_bgd.init(m_ball->getPhysicalObject()->getRadius());

}   // init
/**
 * Checks the soccer balls to see if they crossed the line and trigger the goal accordingly.
 */
void CheckGoal::update(float dt)
{
    World *world = World::getWorld();
    assert(world);

    Track* track = world->getTrack();
    assert(track);

    TrackObjectManager* tom = track->getTrackObjectManager();
    assert(tom);

    PtrVector<TrackObject>&   objects = tom->getObjects();
    unsigned int ball_index = 0;
    for(int i=0; i<objects.size(); i++)
    {
        TrackObject* obj = objects.get(i);
        if(!obj->isSoccerBall())
            continue;

        const Vec3 &xyz = obj->getPresentation<TrackObjectPresentationMesh>()->getNode()->getPosition();
        if(isTriggered(m_previous_position[ball_index], xyz, ball_index))
        {
            if(UserConfigParams::m_check_debug)
                printf("CHECK: Goal check structure %d triggered for object %s.\n",
                       m_index, obj->getPresentation<TrackObjectPresentationMesh>()->getNode()->getDebugName());
            trigger(ball_index);
        }
        m_previous_position[ball_index] = xyz;
        ball_index++;
    }
}
Beispiel #3
0
/** Called when a soccer game is restarted.
 */
void SoccerWorld::reset()
{
    WorldWithRank::reset();
    if(race_manager->hasTimeTarget())
    {
        WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN, race_manager->getTimeTarget());
        m_count_down_reached_zero = false;
    }
    else WorldStatus::setClockMode(CLOCK_CHRONO);

    m_can_score_points = true;
    m_red_goal = 0;
    m_blue_goal = 0;
    m_red_scorers.clear();
    m_red_score_times.clear();
    m_blue_scorers.clear();
    m_blue_score_times.clear();
    m_ball_hitter = -1;
    m_ball = NULL;
    m_red_defender = -1;
    m_blue_defender = -1;
    m_ball_invalid_timer = 0.0f;

    TrackObjectManager* tom = getTrack()->getTrackObjectManager();
    assert(tom);
    PtrVector<TrackObject>& objects = tom->getObjects();
    for (unsigned int i = 0; i < objects.size(); i++)
    {
        TrackObject* obj = objects.get(i);
        if(!obj->isSoccerBall())
            continue;
        m_ball = obj;
        // Handle one ball only
        break;
    }
    if (!m_ball)
        Log::fatal("SoccerWorld","Ball is missing in soccer field, abort.");

    if (m_goal_sound != NULL &&
        m_goal_sound->getStatus() == SFXBase::SFX_PLAYING)
    {
        m_goal_sound->stop();
    }

    initKartList();
    resetAllPosition();
    resetBall();

}   // reset
Beispiel #4
0
/** Called when a battle is restarted.
 */
void SoccerWorld::reset()
{
    WorldWithRank::reset();
    if(race_manager->hasTimeTarget())
    {
        WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN, race_manager->getTimeTarget());
        countDownReachedZero = false;
    }
    else WorldStatus::setClockMode(CLOCK_CHRONO);

    m_can_score_points = true;
    memset(m_team_goals, 0, sizeof(m_team_goals));

    // Reset original positions for the soccer balls
    TrackObjectManager* tom = getTrack()->getTrackObjectManager();
    assert(tom);
    m_redScorers.clear();
    m_redScoreTimes.clear();
    m_blueScorers.clear();
    m_blueScoreTimes.clear();
    m_lastKartToHitBall = -1;
    PtrVector<TrackObject>& objects = tom->getObjects();
    for(unsigned int i=0; i<objects.size(); i++)
    {
        TrackObject* obj = objects.get(i);
        if(!obj->isSoccerBall())
            continue;

        obj->reset();
        obj->getPhysicalObject()->reset();
    }

    if (m_goal_sound != NULL &&
        m_goal_sound->getStatus() == SFXBase::SFX_PLAYING)
    {
        m_goal_sound->stop();
    }

    initKartList();
}   // reset
Beispiel #5
0
//-----------------------------------------------------------------------------
void SoccerWorld::onCheckGoalTriggered(bool first_goal)
{
    if (isRaceOver())
        return;

    if (m_can_score_points)
    {
        m_team_goals[first_goal ? 0 : 1]++;

        World *world = World::getWorld();
        world->setPhase(WorldStatus::GOAL_PHASE);
        m_goal_sound->play();
        if(m_lastKartToHitBall != -1)
        {
            if(first_goal)
            {
                m_redScorers.push_back(m_lastKartToHitBall);
                if(race_manager->hasTimeTarget())
                    m_redScoreTimes.push_back(race_manager->getTimeTarget() - world->getTime());
                else
                    m_redScoreTimes.push_back(world->getTime());
            }
            else
            {
                m_blueScorers.push_back(m_lastKartToHitBall);
                if(race_manager->hasTimeTarget())
                    m_blueScoreTimes.push_back(race_manager->getTimeTarget() - world->getTime());
                else
                    m_blueScoreTimes.push_back(world->getTime());
            }
        }
    }

    // Reset original positions for the soccer balls
    TrackObjectManager* tom = getTrack()->getTrackObjectManager();
    assert(tom);

    PtrVector<TrackObject>& objects = tom->getObjects();
    for(unsigned int i=0; i<objects.size(); i++)
    {
        TrackObject* obj = objects.get(i);
        if(!obj->isSoccerBall())
            continue;

        obj->reset();
        obj->getPhysicalObject()->reset();
    }

    //Resetting the ball triggers the goal check line one more time.
    //This ensures that only one goal is counted, and the second is ignored.
    m_can_score_points = !m_can_score_points;

    //for(int i=0 ; i < getNumKarts() ; i++

    /*if(World::getWorld()->getTrack()->isAutoRescueEnabled() &&
        !getKartAnimation() && fabs(getRoll())>60*DEGREE_TO_RAD &&
                              fabs(getSpeed())<3.0f                )
    {
        new RescueAnimation(this, true);
    }*/

    // TODO: rescue the karts
}   // onCheckGoalTriggered