From 3a3963bf8d00a6adbad6ec275e9deee79ea13e98 Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 19 Jan 2016 16:21:58 +0800 Subject: [PATCH] Make STK soccer mode more like real match 1. Short win animation is shown in a kart if it scored correctly 2. Possible to identify own goal in result gui Also player name is shown instead of kart name in result gui for all modes. --- src/karts/kart.cpp | 2 +- src/modes/soccer_world.cpp | 82 ++++++++++++++++++++------ src/modes/soccer_world.hpp | 26 ++++++-- src/physics/physics.cpp | 4 +- src/states_screens/race_result_gui.cpp | 77 ++++++++++++++++++++---- 5 files changed, 153 insertions(+), 38 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 9223e7a3a..941b0f4e2 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -932,7 +932,7 @@ void Kart::setRaceResult() else Log::warn("Kart", "Unknown game mode given."); -} // setKartResult +} // setRaceResult //----------------------------------------------------------------------------- /** Called when an item is collected. It will either adjust the collected diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 315516479..f6d99ee02 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -73,8 +73,8 @@ void SoccerWorld::init() m_kart_team_map.clear(); WorldWithRank::init(); m_display_rank = false; - m_goal_timer = 0.f; - m_last_kart_to_hit_ball = -1; + m_goal_timer = 0.0f; + m_ball_hitter = -1; m_goal_target = race_manager->getMaxGoal(); m_goal_sound = SFXManager::get()->createSoundSource("goal_scored"); @@ -93,6 +93,8 @@ void SoccerWorld::reset() } else WorldStatus::setClockMode(CLOCK_CHRONO); + m_animation_timer = 0.0f; + m_animation_showing_kart = -1; m_can_score_points = true; m_red_goal = 0; m_blue_goal = 0; @@ -104,7 +106,7 @@ void SoccerWorld::reset() m_red_score_times.clear(); m_blue_scorers.clear(); m_blue_score_times.clear(); - m_last_kart_to_hit_ball = -1; + m_ball_hitter = -1; PtrVector& objects = tom->getObjects(); for(unsigned int i=0; i 3.0f) { world->setPhase(WorldStatus::RACE_PHASE); - m_goal_timer = 0; + m_goal_timer = 0.0f; + } + } + + if (!(isRaceOver() || isStartPhase()) && m_animation_showing_kart != -1) + { + m_animation_timer += dt; + if (m_animation_timer > 6.0f) + { + m_karts[m_animation_showing_kart] + ->getKartModel()->setAnimation(KartModel::AF_BEGIN); + m_animation_timer = 0.0f; + m_animation_showing_kart = -1; } } } // update @@ -176,23 +190,40 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) World *world = World::getWorld(); world->setPhase(WorldStatus::GOAL_PHASE); m_goal_sound->play(); - if(m_last_kart_to_hit_ball != -1) + if (m_ball_hitter != -1) { - if(first_goal) + m_animation_showing_kart = m_ball_hitter; + ScorerData sd; + sd.m_id = m_ball_hitter; + sd.m_correct_goal = isCorrectGoal(m_ball_hitter, first_goal); + + if (sd.m_correct_goal) + { + m_karts[m_ball_hitter]->getKartModel() + ->setAnimation(KartModel::AF_WIN_START); + } + + if (first_goal) { // Notice: true first_goal means it's blue goal being shoot, // so red team can score - m_red_scorers.push_back(m_last_kart_to_hit_ball); + m_red_scorers.push_back(sd); if(race_manager->hasTimeTarget()) - m_red_score_times.push_back(race_manager->getTimeTarget() - world->getTime()); + { + m_red_score_times.push_back(race_manager + ->getTimeTarget() - world->getTime()); + } else m_red_score_times.push_back(world->getTime()); } else { - m_blue_scorers.push_back(m_last_kart_to_hit_ball); - if(race_manager->hasTimeTarget()) - m_blue_score_times.push_back(race_manager->getTimeTarget() - world->getTime()); + m_blue_scorers.push_back(sd); + if (race_manager->hasTimeTarget()) + { + m_blue_score_times.push_back(race_manager + ->getTimeTarget() - world->getTime()); + } else m_blue_score_times.push_back(world->getTime()); } @@ -222,12 +253,12 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) //----------------------------------------------------------------------------- /** Sets the last kart that hit the ball, to be able to -* identify the scorer later. -*/ -void SoccerWorld::setLastKartTohitBall(unsigned int kart_id) + * identify the scorer later. + */ +void SoccerWorld::setBallHitter(unsigned int kart_id) { - m_last_kart_to_hit_ball = kart_id; -} // setLastKartTohitBall + m_ball_hitter = kart_id; +} // setBallHitter //----------------------------------------------------------------------------- /** The soccer game is over if time up or either team wins. @@ -261,7 +292,7 @@ void SoccerWorld::terminateRace() //----------------------------------------------------------------------------- /** Called when the match time ends. -*/ + */ void SoccerWorld::countdownReachedZero() { m_count_down_reached_zero = true; @@ -495,3 +526,20 @@ SoccerTeam SoccerWorld::getKartTeam(unsigned int kart_id) const return SOCCER_TEAM_BLUE; } // getKartTeam + +//----------------------------------------------------------------------------- +bool SoccerWorld::isCorrectGoal(unsigned int kart_id, bool first_goal) const +{ + SoccerTeam team = getKartTeam(kart_id); + if (first_goal) + { + if (team == SOCCER_TEAM_RED) + return true; + } + else if (!first_goal) + { + if (team == SOCCER_TEAM_BLUE) + return true; + } + return false; +} // isCorrectGoal diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index 3cb2df32b..ba1a6cc6f 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -36,6 +36,16 @@ class Controller; */ class SoccerWorld : public WorldWithRank { +public: + class ScorerData + { + public: + /** World ID of kart which scores. */ + unsigned int m_id; + /** Whether this goal is socred correctly (identify for own goal). */ + bool m_correct_goal; + }; // ScorerData + protected: virtual AbstractKart *createKart(const std::string &kart_ident, int index, int local_player_id, int global_player_id, @@ -54,14 +64,18 @@ private: /** Timer for displaying goal text*/ float m_goal_timer; - int m_last_kart_to_hit_ball; + int m_ball_hitter; + + /** Timer for win/lose animation showing after each goal*/ + float m_animation_timer; + int m_animation_showing_kart; /** Goals data of each team scored */ int m_red_goal; int m_blue_goal; - std::vector m_red_scorers; + std::vector m_red_scorers; std::vector m_red_score_times; - std::vector m_blue_scorers; + std::vector m_blue_scorers; std::vector m_blue_score_times; std::map m_kart_team_map; @@ -110,7 +124,7 @@ public: // ------------------------------------------------------------------------ void onCheckGoalTriggered(bool first_goal); // ------------------------------------------------------------------------ - void setLastKartTohitBall(unsigned int kart_id); + void setBallHitter(unsigned int kart_id); // ------------------------------------------------------------------------ /** Get the soccer result of kart in soccer world (including AIs) */ bool getKartSoccerResult(unsigned int kart_id) const; @@ -121,7 +135,7 @@ public: const int getScore(SoccerTeam team) const { return (team == SOCCER_TEAM_BLUE ? m_blue_goal : m_red_goal); } // ------------------------------------------------------------------------ - const std::vector& getScorers(SoccerTeam team) const + const std::vector& getScorers(SoccerTeam team) const { return (team == SOCCER_TEAM_BLUE ? m_blue_scorers : m_red_scorers); } // ------------------------------------------------------------------------ const std::vector& getScoreTimes(SoccerTeam team) const @@ -143,6 +157,8 @@ public: { return (team == SOCCER_TEAM_BLUE ? m_blue_goal_node : m_red_goal_node); } + // ------------------------------------------------------------------------ + bool isCorrectGoal(unsigned int kart_id, bool first_goal) const; }; // SoccerWorld diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 216d74998..9fee77617 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -226,7 +226,7 @@ void Physics::update(float dt) race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) { SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld(); - soccerWorld->setLastKartTohitBall(kartId); + soccerWorld->setBallHitter(kartId); } continue; } @@ -288,7 +288,7 @@ void Physics::update(float dt) { int kartId = p->getUserPointer(0)->getPointerFlyable()->getOwnerId(); SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld(); - soccerWorld->setLastKartTohitBall(kartId); + soccerWorld->setBallHitter(kartId); } } diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 8c7dc415a..416030f0b 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -475,7 +475,16 @@ void RaceResultGUI::determineTableLayout() // Save a pointer to the current row_info entry RowInfo *ri = &(m_all_row_infos[position-first_position]); ri->m_is_player_kart = kart->getController()->isLocalPlayerController(); - ri->m_kart_name = translations->fribidize(kart->getName()); + + // Identify Human player, if so display real name other than kart name + const int rm_id = kart->getWorldKartId() - + (race_manager->getNumberOfKarts() - race_manager->getNumPlayers()); + + if (rm_id >= 0) + ri->m_kart_name = race_manager->getKartInfo(rm_id).getPlayerName(); + else + ri->m_kart_name = translations->fribidize(kart->getName()); + ri->m_player = ri->m_is_player_kart ? kart->getController()->getPlayer() : NULL; @@ -842,7 +851,15 @@ void RaceResultGUI::determineGPLayout() RowInfo *ri = &(m_all_row_infos[rank]); ri->m_kart_icon = kart->getKartProperties()->getIconMaterial()->getTexture(); - ri->m_kart_name = translations->fribidize(kart->getName()); + + const int rm_id = kart_id - + (race_manager->getNumberOfKarts() - race_manager->getNumPlayers()); + + if (rm_id >= 0) + ri->m_kart_name = race_manager->getKartInfo(rm_id).getPlayerName(); + else + ri->m_kart_name = translations->fribidize(kart->getName()); + ri->m_is_player_kart = kart->getController()->isLocalPlayerController(); ri->m_player = ri->m_is_player_kart ? kart->getController()->getPlayer() : NULL; @@ -1052,16 +1069,32 @@ void RaceResultGUI::displaySoccerResults() //The red scorers: current_y += rect.Height/2 + rect.Height/4; font = GUIEngine::getSmallFont(); - std::vector scorers = sw->getScorers(SOCCER_TEAM_RED); + std::vector scorers = sw->getScorers(SOCCER_TEAM_RED); std::vector score_times = sw->getScoreTimes(SOCCER_TEAM_RED); irr::video::ITexture* scorer_icon; int prev_y = current_y; for(unsigned int i=0; igetKart(scorers.at(i))-> - getKartProperties()->getName(); - result_text.append(" "); + const bool own_goal = !(scorers.at(i).m_correct_goal); + + const int kart_id = scorers.at(i).m_id; + const int rm_id = kart_id - + (race_manager->getNumberOfKarts() - race_manager->getNumPlayers()); + + if (rm_id >= 0) + result_text = race_manager->getKartInfo(rm_id).getPlayerName(); + else + result_text = sw->getKart(kart_id)-> + getKartProperties()->getName(); + + if (own_goal) + { + result_text.append(" "); + result_text.append( _("(Own Goal)") ); + } + + result_text.append(" "); result_text.append(StringUtils::timeToString(score_times.at(i)).c_str()); rect = m_font->getDimension(result_text.c_str()); @@ -1073,8 +1106,9 @@ void RaceResultGUI::displaySoccerResults() if(current_y > height) break; pos = core::rect(current_x,current_y,current_x,current_y); - font->draw(result_text,pos, color, true, false); - scorer_icon = sw->getKart(scorers.at(i)) + font->draw(result_text, pos, (own_goal ? + video::SColor(255, 255, 0, 0) : color), true, false); + scorer_icon = sw->getKart(scorers.at(i).m_id) ->getKartProperties()->getIconMaterial()->getTexture(); source_rect = core::recti(core::vector2di(0,0), scorer_icon->getSize()); irr::u32 offset_x = GUIEngine::getFont()->getDimension(result_text.c_str()).Width/2; @@ -1090,9 +1124,25 @@ void RaceResultGUI::displaySoccerResults() score_times = sw->getScoreTimes(SOCCER_TEAM_BLUE); for(unsigned int i=0; igetKart(scorers.at(i))-> - getKartProperties()->getName(); - result_text.append(" "); + const bool own_goal = !(scorers.at(i).m_correct_goal); + + const int kart_id = scorers.at(i).m_id; + const int rm_id = kart_id - + (race_manager->getNumberOfKarts() - race_manager->getNumPlayers()); + + if (rm_id >= 0) + result_text = race_manager->getKartInfo(rm_id).getPlayerName(); + else + result_text = sw->getKart(kart_id)-> + getKartProperties()->getName(); + + if (own_goal) + { + result_text.append(" "); + result_text.append( _("(Own Goal)") ); + } + + result_text.append(" "); result_text.append(StringUtils::timeToString(score_times.at(i)).c_str()); rect = m_font->getDimension(result_text.c_str()); @@ -1104,8 +1154,9 @@ void RaceResultGUI::displaySoccerResults() if(current_y > height) break; pos = core::rect(current_x,current_y,current_x,current_y); - font->draw(result_text,pos, color, true, false); - scorer_icon = sw->getKart(scorers.at(i))-> + font->draw(result_text,pos, (own_goal ? + video::SColor(255, 255, 0, 0) : color), true, false); + scorer_icon = sw->getKart(scorers.at(i).m_id)-> getKartProperties()->getIconMaterial()->getTexture(); source_rect = core::recti(core::vector2di(0,0), scorer_icon->getSize()); irr::u32 offset_x = GUIEngine::getFont()->getDimension(result_text.c_str()).Width/2;