/** 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++; } }
/** Update the world and the track. * \param dt Time step size. */ void ThreeStrikesBattle::update(float dt) { WorldWithRank::update(dt); WorldWithRank::updateTrack(dt); core::vector3df tire_offset; std::string tire; float scale = 0.5f; float radius = 0.5f; PhysicalObject::bodyTypes tire_model; // insert blown away tire(s) now if was requested while (m_insert_tire > 0) { if(m_insert_tire == 1) { tire_offset = core::vector3df(0.0f, 0.0f, 0.0f); tire = file_manager->getModelFile("tire.b3d"); scale = 0.5f; radius = 0.5f; tire_model = PhysicalObject::MP_CYLINDER_Y; } else { scale = 1.0f; tire_model = PhysicalObject::MP_CYLINDER_X; radius = m_tire_radius[m_insert_tire-2]; tire_offset = m_tire_offsets[m_insert_tire-2]; if (m_insert_tire == 2) tire = m_tire_dir+"/wheel-rear-left.b3d"; else if(m_insert_tire == 3) tire = m_tire_dir+"/wheel-front-left.b3d"; else if(m_insert_tire == 4) tire = m_tire_dir+"/wheel-front-right.b3d"; else if(m_insert_tire == 5) tire = m_tire_dir+"/wheel-rear-right.b3d"; } TrackObjectManager* tom = m_track->getTrackObjectManager(); PhysicalObject* obj = tom->insertObject(tire, tire_model, 15 /* mass */, radius /* radius */, core::vector3df(800.0f,0,m_tire_rotation / M_PI * 180 + 180) , m_tire_position + tire_offset, core::vector3df(scale,scale,scale) /* scale */); // FIXME: orient the force relative to kart orientation obj->getBody()->applyCentralForce(btVector3(60.0f, 0.0f, 0.0f)); m_insert_tire--; if(m_insert_tire == 1) m_insert_tire = 0; m_tires.push_back(obj); } } // update
/** General update function called once per frame. * \param dt Time step size. */ void OverWorld::update(float dt) { // Skip annoying waiting without a purpose // Make sure to do all things that would normally happen in the // update() method of the base classes. if (getPhase() < GO_PHASE) { setPhase(RACE_PHASE); // Normally done in WorldStatus::update(), during phase SET_PHASE, // so we have to start music 'manually', since we skip all phases. World::getWorld()->getTrack()->startMusic(); if (music_manager->getCurrentMusic() != NULL && UserConfigParams::m_music) music_manager->getCurrentMusic()->startMusic(); m_karts[0]->startEngineSFX(); } WorldWithRank::update(dt); WorldWithRank::updateTrack(dt); const unsigned int kart_amount = m_karts.size(); // isn't it cool, on the overworld nitro is free! for(unsigned int n=0; n<kart_amount; n++) { m_karts[n]->setEnergy(100.0f); } TrackObjectManager* tom = getTrack()->getTrackObjectManager(); PtrVector<TrackObject>& objects = tom->getObjects(); for(unsigned int i=0; i<objects.size(); i++) { TrackObject* obj = objects.get(i); if(!obj->isGarage()) continue; float m_distance = obj->getDistance(); Vec3 m_garage_pos = obj->getPosition(); Vec3 m_kart_pos = getKart(0)->getXYZ(); if ((m_garage_pos-m_kart_pos).length_2d() > m_distance) { obj->reset(); } } if (m_return_to_garage) { m_return_to_garage = false; delayedSelfDestruct(); race_manager->exitRace(false); KartSelectionScreen* s = OfflineKartSelectionScreen::getInstance(); s->setMultiplayer(false); s->setFromOverworld(true); StateManager::get()->resetAndGoToScreen(s); } } // update
void GrandPrixWin::setKarts(const std::string idents_arg[3]) { TrackObjectManager* tobjman = Track::getCurrentTrack()->getTrackObjectManager(); // reorder in "podium order" (i.e. second player to the left, first player // in the middle, last at the right) std::string idents[3]; idents[0] = idents_arg[1]; idents[1] = idents_arg[0]; idents[2] = idents_arg[2]; for (int i = 0; i < 3; i++) { const KartProperties* kp = kart_properties_manager->getKart(idents[i]); if (kp == NULL) continue; KartModel* kart_model = kp->getKartModelCopy(KRT_DEFAULT); m_all_kart_models.push_back(kart_model); scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false); m_kart_x[i] = KARTS_X + i*KARTS_DELTA_X; m_kart_y[i] = INITIAL_Y + KARTS_DELTA_Y; m_kart_z[i] = KARTS_INITIAL_Z; m_kart_rotation[i] = 0.0f; core::vector3df kart_pos(m_kart_x[i], m_kart_y[i], m_kart_z[i]); core::vector3df kart_rot(0, 0, 0); core::vector3df kart_scale(1.0f, 1.0f, 1.0f); //FIXME: it's not ideal that both the track object and the presentation // know the initial coordinates of the object TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode(kart_pos, kart_rot, kart_scale, kart_main_node); TrackObject* tobj = new TrackObject(kart_pos, kart_rot, kart_scale, "ghost", presentation, false /* isDynamic */, NULL /* physics settings */); tobjman->insertObject(tobj); m_kart_node[i] = tobj; } TrackObject* currObj; PtrVector<TrackObject>& objects = tobjman->getObjects(); for_in(currObj, objects) { TrackObjectPresentationMesh* meshPresentation = currObj->getPresentation<TrackObjectPresentationMesh>(); if (meshPresentation != NULL) { if (meshPresentation->getModelFile() == "gpwin_podium1.b3d") m_podium_steps[0] = currObj; else if (meshPresentation->getModelFile() == "gpwin_podium2.b3d") m_podium_steps[1] = currObj; else if (meshPresentation->getModelFile() == "gpwin_podium3.b3d") m_podium_steps[2] = currObj; } }
void GrandPrixLose::setKarts(std::vector<std::string> ident_arg) { TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager(); assert(ident_arg.size() > 0); if ((int)ident_arg.size() > MAX_KART_COUNT) { ident_arg.resize(MAX_KART_COUNT); } // (there is at least one kart so kart node 0 is sure to be set) m_kart_node[1] = NULL; m_kart_node[2] = NULL; m_kart_node[3] = NULL; m_kart_x = KART_START_X; m_kart_y = KART_Y; m_kart_z = KART_Z; const int count = ident_arg.size(); for (int n=0; n<count; n++) { const KartProperties* kart = kart_properties_manager->getKart(ident_arg[n]); if (kart != NULL) { KartModel* kart_model = kart->getKartModelCopy(); m_all_kart_models.push_back(kart_model); scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false); core::vector3df kart_pos(m_kart_x + n*DISTANCE_BETWEEN_KARTS, m_kart_y, m_kart_z); core::vector3df kart_rot(0, 90.0f, 0); core::vector3df kart_scale(KART_SCALE, KART_SCALE, KART_SCALE); //FIXME: it's not ideal that both the track object and the presentation know the initial coordinates of the object TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode( kart_main_node, kart_pos, kart_rot, kart_scale); TrackObject* tobj = new TrackObject(kart_pos, kart_rot, kart_scale, "ghost", presentation, false /* isDynamic */, NULL /* physics settings */); tobjman->insertObject(tobj); m_kart_node[n] = tobj; } else { Log::warn("GrandPrixLose", "Could not find a kart named '%s'.", ident_arg[n].c_str()); m_kart_node[n] = NULL; } // if kart != NULL } } // setKarts
/** 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
/** 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
//----------------------------------------------------------------------------- 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
void GrandPrixWin::setKarts(const std::string idents_arg[3]) { TrackObjectManager* tobjman = Track::getCurrentTrack()->getTrackObjectManager(); // reorder in "podium order" (i.e. second player to the left, first player // in the middle, last at the right) std::string idents[3]; idents[0] = idents_arg[1]; idents[1] = idents_arg[0]; idents[2] = idents_arg[2]; for (int i = 0; i < 3; i++) { const KartProperties* kp = kart_properties_manager->getKart(idents[i]); if (kp == NULL) continue; KartModel* kart_model = kp->getKartModelCopy(); m_all_kart_models.push_back(kart_model); scene::ISceneNode* kart_main_node = kart_model->attachModel(true, false); LODNode* lnode = dynamic_cast<LODNode*>(kart_main_node); if (lnode) { // Lod node has to be animated auto* a_node = static_cast<scene::IAnimatedMeshSceneNode*> (lnode->getAllNodes()[0]); const unsigned start_frame = kart_model->getFrame(KartModel::AF_WIN_LOOP_START) > -1 ? kart_model->getFrame(KartModel::AF_WIN_LOOP_START) : kart_model->getFrame(KartModel::AF_WIN_START) > -1 ? kart_model->getFrame(KartModel::AF_WIN_START) : kart_model->getFrame(KartModel::AF_STRAIGHT); const unsigned end_frame = kart_model->getFrame(KartModel::AF_WIN_END) > -1 ? kart_model->getFrame(KartModel::AF_WIN_END) : kart_model->getFrame(KartModel::AF_STRAIGHT); a_node->setLoopMode(true); a_node->setFrameLoop(start_frame, end_frame); } m_kart_x[i] = KARTS_INITIAL_X[i]; m_kart_y[i] = KARTS_INITIAL_Y[i]; m_kart_z[i] = KARTS_INITIAL_Z[i]; m_kart_rotation[i] = KARTS_AND_PODIUMS_INITIAL_ROTATION[i]; core::vector3df kart_pos(m_kart_x[i], m_kart_y[i], m_kart_z[i]); core::vector3df kart_rot(0, 0, 0); core::vector3df kart_scale(1.0f, 1.0f, 1.0f); //FIXME: it's not ideal that both the track object and the presentation // know the initial coordinates of the object TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode(kart_pos, kart_rot, kart_scale, kart_main_node); TrackObject* tobj = new TrackObject(kart_pos, kart_rot, kart_scale, "ghost", presentation, false /* isDynamic */, NULL /* physics settings */); tobjman->insertObject(tobj); m_kart_node[i] = tobj; } TrackObject* currObj; PtrVector<TrackObject>& objects = tobjman->getObjects(); for_in(currObj, objects) { TrackObjectPresentationMesh* meshPresentation = currObj->getPresentation<TrackObjectPresentationMesh>(); if (meshPresentation != NULL) { if (meshPresentation->getModelFile() == "gpwin_podium1.spm") m_podium_steps[0] = currObj; else if (meshPresentation->getModelFile() == "gpwin_podium2.spm") m_podium_steps[1] = currObj; else if (meshPresentation->getModelFile() == "gpwin_podium3.spm") m_podium_steps[2] = currObj; } }