diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index 5c53d3512..b250f7909 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -491,6 +491,7 @@ std::set ScalableFont::getPreloadCharacters(const GUIEngine::TTFLoading preload_char.insert((wchar_t)i); //Include basic Latin too, starting from A (char code 65) setlocale(LC_ALL, "en_US.UTF8"); + std::set upper; std::set::iterator it = preload_char.begin(); while (it != preload_char.end()) @@ -498,7 +499,15 @@ std::set ScalableFont::getPreloadCharacters(const GUIEngine::TTFLoading //Only use all capital letter for bold char with latin (<640 of char code). //Remove all characters (>char code 8191) not used by the title if (((iswlower((wchar_t)*it) || !iswalpha((wchar_t)*it)) && *it < 640) || *it > 8191) + { + if (*it < 8192 && iswalpha((wchar_t)*it)) + { + //Make sure we include all upper case letters, + //because the title font shows all characters as capital letters + upper.insert(towupper((wchar_t)*it)); + } it = preload_char.erase(it); + } else ++it; } @@ -507,6 +516,7 @@ std::set ScalableFont::getPreloadCharacters(const GUIEngine::TTFLoading for (u32 i = 32; i < 65; ++i) preload_char.insert((wchar_t)i); //Include basic symbol (from space (char code 32) to @(char code 64)) + preload_char.insert(upper.begin(), upper.end()); preload_char.insert((wchar_t)160); //Non-breaking space //Remove Ordinal indicator (char code 170 and 186) 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..7b7dddf76 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,71 +837,103 @@ 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 || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER) + && m_controller->isPlayerController()) + { + RaceGUIBase* m = World::getWorld()->getRaceGUI(); + if (m) + { + 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); + } + } + } + + 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 + setRaceResult(); + 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 + +//----------------------------------------------------------------------------- +void Kart::setRaceResult() +{ if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_NORMAL_RACE || race_manager->getMinorMode() == RaceManager::MINOR_MODE_TIME_TRIAL) { - // 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 + // TODO NetworkController? + if (this->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 && !challenge->getData()->isGrandPrix()) { - if(challenge->getData()->isChallengeFulfilled()) - m_kart_model->setAnimation(KartModel::AF_WIN_START); + if (challenge->getData()->isChallengeFulfilled()) + m_race_result = true; else - m_kart_model->setAnimation(KartModel::AF_LOSE_START); - + m_race_result = false; } - else if(m_race_position<=0.5f*race_manager->getNumberOfKarts() || - m_race_position==1) - m_kart_model->setAnimation(KartModel::AF_WIN_START); + else if (this->getPosition() <= 0.5f*race_manager->getNumberOfKarts() || + this->getPosition() == 1) + m_race_result = true; 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); - } + m_race_result = false; } - } - 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) + else { - if (getPosition() == 2) - m->addMessage(_("You won the race!"), this, 2.0f); + if (this->getPosition() <= 0.5f*race_manager->getNumberOfKarts() || + this->getPosition() == 1) + m_race_result = true; + else + m_race_result = false; } } - else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES || - race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FOLLOW_LEADER || + race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES) { - setController(new EndController(this, m_controller->getPlayer(), - m_controller)); + // the kart wins if it isn't eliminated + m_race_result = !this->isEliminated(); + } + else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) + { + // TODO complete together with soccer ai! + m_race_result = true; } 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)); + // Easter egg mode only has one player, so always win + m_race_result = true; } + else + Log::warn("Kart", "Unknown game mode given."); -} // finishedRace +} // setKartResult //----------------------------------------------------------------------------- /** Called when an item is collected. It will either adjust the collected diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 8e53a7ac4..955337108 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,12 @@ 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; } + // ------------------------------------------------------------------------ + /** Set this kart race result. */ + void setRaceResult(); }; // 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/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 78d6e2be4..0709e0e4b 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 //----------------------------------------------------------------------------- @@ -87,7 +83,25 @@ void RaceResultGUI::init() getWidget("bottom")->setVisible(false); 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(); + } + + m_finish_sound = SFXManager::get()->quickSound( + human_win ? "gp_end" : "race_finish"); + + //std::string path = (human_win ? Different result music too later + // file_manager->getAsset(FileManager::MUSIC, "race_summary.music") : + // file_manager->getAsset(FileManager::MUSIC, "race_summary.music")); + std::string path = 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