diff --git a/src/karts/abstract_kart.hpp b/src/karts/abstract_kart.hpp index 8857889fa..c0cba1cfe 100644 --- a/src/karts/abstract_kart.hpp +++ b/src/karts/abstract_kart.hpp @@ -447,6 +447,9 @@ public: /** Counter which is used for displaying wrong way message after a delay */ virtual float getWrongwayCounter() = 0; virtual void setWrongwayCounter(float counter) = 0; + // ------------------------------------------------------------------------ + /** Returns whether this kart wins or loses. */ + virtual bool getRaceResult() const = 0; }; // AbstractKart diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index dc3713ad0..7f23f6f7b 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -113,6 +113,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id, m_race_position = position; m_collected_energy = 0; m_finished_race = false; + m_race_result = false; m_finish_time = 0.0f; m_bubblegum_time = 0.0f; m_bubblegum_torque = 0.0f; @@ -836,70 +837,46 @@ void Kart::finishedRace(float time) m_kart_model->finishedRace(); race_manager->kartFinishedRace(this, time); - if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE || - race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL) + if ((race_manager->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER) + && m_controller->isPlayerController()) { - // in modes that support it, start end animation - setController(new EndController(this, m_controller->getPlayer(), - m_controller)); - if (m_controller->isPlayerController()) // if player is on this computer - { - PlayerProfile *player = PlayerManager::getCurrentPlayer(); - const ChallengeStatus *challenge = player->getCurrentChallengeStatus(); - // In case of a GP challenge don't make the end animation depend - // on if the challenge is fulfilled - if(challenge && !challenge->getData()->isGrandPrix()) - { - if(challenge->getData()->isChallengeFulfilled()) - m_kart_model->setAnimation(KartModel::AF_WIN_START); - else - m_kart_model->setAnimation(KartModel::AF_LOSE_START); - - } - else if(m_race_position<=0.5f*race_manager->getNumberOfKarts() || - m_race_position==1) - m_kart_model->setAnimation(KartModel::AF_WIN_START); - else - m_kart_model->setAnimation(KartModel::AF_LOSE_START); - - RaceGUIBase* m = World::getWorld()->getRaceGUI(); - if(m) - { - m->addMessage((getPosition() == 1 ? _("You won the race!") : _("You finished the race!")) , - this, 2.0f); - } - } - } - else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER) - { - // start end animation - setController(new EndController(this, m_controller->getPlayer(), - m_controller)); - if(m_race_position<=2) - m_kart_model->setAnimation(KartModel::AF_WIN_START); - else if(m_race_position>=0.7f*race_manager->getNumberOfKarts()) - m_kart_model->setAnimation(KartModel::AF_LOSE_START); - RaceGUIBase* m = World::getWorld()->getRaceGUI(); - if(m) + if (m) { - if (getPosition() == 2) + if (race_manager-> + getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER && + getPosition() == 2) m->addMessage(_("You won the race!"), this, 2.0f); + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL) + { + m->addMessage((getPosition() == 1 ? + _("You won the race!") : _("You finished the race!")) , + this, 2.0f); + } } } - else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES || - race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) - { - setController(new EndController(this, m_controller->getPlayer(), - m_controller)); - } - else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_EASTER_EGG) - { - m_kart_model->setAnimation(KartModel::AF_WIN_START); - setController(new EndController(this, m_controller->getPlayer(), - m_controller)); - } + if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_EASTER_EGG) + { + // Save for music handling in race result gui + m_race_result = race_manager->getKartResult(this); + setController(new EndController(this, m_controller->getPlayer(), + m_controller)); + + // Skip animation if this kart is eliminated + if (m_eliminated) return; + + m_kart_model->setAnimation(m_race_result ? + KartModel::AF_WIN_START : KartModel::AF_LOSE_START); + } } // finishedRace //----------------------------------------------------------------------------- diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 8e53a7ac4..539041de9 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -109,6 +109,9 @@ private: /** Offset of the graphical kart chassis from the physical chassis. */ float m_graphical_y_offset; + /** True if the kart wins, false otherwise. */ + bool m_race_result; + /** True if the kart is eliminated. */ bool m_eliminated; @@ -438,6 +441,9 @@ public: float getWrongwayCounter() { return m_wrongway_counter; } // ------------------------------------------------------------------------ void setWrongwayCounter(float counter) { m_wrongway_counter = counter; } + // ------------------------------------------------------------------------ + /** Returns whether this kart wins or loses. */ + virtual bool getRaceResult() const { return m_race_result; } }; // Kart diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index beafc2b33..8fb23351a 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -174,6 +174,8 @@ void ThreeStrikesBattle::kartHit(const unsigned int kart_id) // check if kart is 'dead' if (m_kart_info[kart_id].m_lives < 1) { + if (getCurrentNumPlayers()) + eliminateKart(kart_id, /*notify_of_elimination*/ true); m_karts[kart_id]->finishedRace(WorldStatus::getTime()); scene::ISceneNode** wheels = m_karts[kart_id]->getKartModel() ->getWheelNodes(); @@ -181,8 +183,6 @@ void ThreeStrikesBattle::kartHit(const unsigned int kart_id) if(wheels[1]) wheels[1]->setVisible(false); if(wheels[2]) wheels[2]->setVisible(false); if(wheels[3]) wheels[3]->setVisible(false); - if (getCurrentNumPlayers()) - eliminateKart(kart_id, /*notify_of_elimination*/ true); // Find a camera of the kart with the most lives ("leader"), and // attach all cameras for this kart to the leader. int max_lives = 0; diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index 7abaac61e..13f9f8440 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -21,6 +21,7 @@ #include #include +#include "challenges/challenge_status.hpp" #include "challenges/unlock_manager.hpp" #include "config/player_manager.hpp" #include "config/saved_grand_prix.hpp" @@ -889,4 +890,59 @@ void RaceManager::setupPlayerKartInfo() computeRandomKartList(); } // setupPlayerKartInfo +//----------------------------------------------------------------------------- +bool RaceManager::getKartResult(AbstractKart* kart) const +{ + if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL) + { + // TODO NetworkController? + if (kart->getController()->isPlayerController()) + { + PlayerProfile *player = PlayerManager::getCurrentPlayer(); + const ChallengeStatus *challenge = player->getCurrentChallengeStatus(); + // In case of a GP challenge don't make the end animation depend + // on if the challenge is fulfilled + if (challenge && !challenge->getData()->isGrandPrix()) + { + if (challenge->getData()->isChallengeFulfilled()) + return true; + else + return false; + } + else if (kart->getPosition() <= 0.5f*race_manager->getNumberOfKarts() || + kart->getPosition() == 1) + return true; + else + return false; + } + else + { + if (kart->getPosition() <= 0.5f*race_manager->getNumberOfKarts() || + kart->getPosition() == 1) + return true; + else + return false; + } + } + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES) + { + // the kart wins if it isn't eliminated + return !kart->isEliminated(); + } + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) + { + // TODO complete together with soccer ai! + return true; + } + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_EASTER_EGG) + { + // Easter egg mode only has one player, so always win + return true; + } + + return true; // Fallback +} // getKartResult + /* EOF */ diff --git a/src/race/race_manager.hpp b/src/race/race_manager.hpp index 062e5cd50..990c0cb61 100644 --- a/src/race/race_manager.hpp +++ b/src/race/race_manager.hpp @@ -774,6 +774,8 @@ public: { return m_kart_last_position_on_overworld; } + // ------------------------------------------------------------------------ + bool getKartResult(AbstractKart* kart) const; }; // RaceManager diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 78d6e2be4..defee6c44 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -63,10 +63,6 @@ DEFINE_SCREEN_SINGLETON( RaceResultGUI ); RaceResultGUI::RaceResultGUI() : Screen("race_result.stkgui", /*pause race*/ false) { - std::string path = file_manager->getAsset(FileManager::MUSIC, - "race_summary.music"); - m_race_over_music = music_manager->getMusicInformation(path); - } // RaceResultGUI //----------------------------------------------------------------------------- @@ -88,6 +84,21 @@ void RaceResultGUI::init() music_manager->stopMusic(); m_finish_sound = SFXManager::get()->quickSound("race_finish"); + + bool human_win = true; + unsigned int num_karts = race_manager->getNumberOfKarts(); + for (unsigned int kart_id = 0; kart_id < num_karts; kart_id++) + { + const AbstractKart *kart = World::getWorld()->getKart(kart_id); + if (kart->getController()->isPlayerController()) + human_win = human_win && kart->getRaceResult(); + } + + std::string path = (human_win ? //TODO proper win / lose music + file_manager->getAsset(FileManager::MUSIC, "Boom_boom_boom.music") : + file_manager->getAsset(FileManager::MUSIC, "race_summary.music")); + m_race_over_music = music_manager->getMusicInformation(path); + if (!m_finish_sound) { // If there is no finish sound (because sfx are disabled), start