From 62ce61d98008253e8c38b5d2a5e578f919a2462a Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 4 Jan 2019 14:01:31 +0800 Subject: [PATCH] Add save and restore complete state for soccer world --- src/modes/soccer_world.cpp | 137 +++++++++++++++++++------ src/modes/soccer_world.hpp | 25 ++--- src/states_screens/race_result_gui.cpp | 64 ++++++------ 3 files changed, 150 insertions(+), 76 deletions(-) diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 0b7aa0e89..24cd8a2cd 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -143,9 +143,7 @@ void SoccerWorld::reset(bool restart) m_count_down_reached_zero = false; m_red_scorers.clear(); - m_red_score_times.clear(); m_blue_scorers.clear(); - m_blue_score_times.clear(); m_ball_hitter = -1; m_red_kdm.clear(); m_blue_kdm.clear(); @@ -277,9 +275,11 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) m_goal_frame.push_back(m_frame_count - elapsed_frame); } - ScorerData sd; + ScorerData sd = {}; sd.m_id = m_ball_hitter; sd.m_correct_goal = isCorrectGoal(m_ball_hitter, first_goal); + sd.m_kart = getKart(m_ball_hitter)->getIdent(); + sd.m_player = getKart(m_ball_hitter)->getController()->getName(); if (sd.m_correct_goal) { @@ -293,30 +293,27 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) ->setAnimation(KartModel::AF_LOSE_START, true/* play_non_loop*/); } - float score_time = 0.0f; if (first_goal) { + if (race_manager->hasTimeTarget()) + { + sd.m_time = race_manager->getTimeTarget() - getTime(); + } + else + sd.m_time = getTime(); // Notice: true first_goal means it's blue goal being shoot, // so red team can score m_red_scorers.push_back(sd); - if (race_manager->hasTimeTarget()) - { - score_time = race_manager->getTimeTarget() - getTime(); - } - else - score_time = getTime(); - m_red_score_times.push_back(score_time); } else { - m_blue_scorers.push_back(sd); if (race_manager->hasTimeTarget()) { - score_time = race_manager->getTimeTarget() - getTime(); + sd.m_time = race_manager->getTimeTarget() - getTime(); } else - score_time = getTime(); - m_blue_score_times.push_back(score_time); + sd.m_time = getTime(); + m_blue_scorers.push_back(sd); } if (NetworkConfig::get()->isNetworking() && NetworkConfig::get()->isServer()) @@ -325,9 +322,11 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) p.setSynchronous(true); p.addUInt8(GameEventsProtocol::GE_PLAYER_GOAL) .addUInt8((uint8_t)sd.m_id).addUInt8(sd.m_correct_goal) - .addUInt8(first_goal).addFloat(score_time) + .addUInt8(first_goal).addFloat(sd.m_time) .addTime(World::getWorld()->getTicksSinceStart() + - stk_config->time2Ticks(3.0f)); + stk_config->time2Ticks(3.0f)) + .encodeString(sd.m_kart) + .encodeString(sd.m_player); STKHost::get()->sendPacketToAllPeers(&p, true); } } @@ -346,6 +345,9 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal) //----------------------------------------------------------------------------- void SoccerWorld::handleResetBallFromServer(const NetworkString& ns) { + // Ignore in live join + if (isStartPhase()) + return; int ticks_now = World::getWorld()->getTicksSinceStart(); int ticks_back_to_own_goal = ns.getTime(); if (ticks_now >= ticks_back_to_own_goal) @@ -363,11 +365,38 @@ void SoccerWorld::handleResetBallFromServer(const NetworkString& ns) //----------------------------------------------------------------------------- void SoccerWorld::handlePlayerGoalFromServer(const NetworkString& ns) { - ScorerData sd; + ScorerData sd = {}; sd.m_id = ns.getUInt8(); sd.m_correct_goal = ns.getUInt8() == 1; bool first_goal = ns.getUInt8() == 1; - float score_time = ns.getFloat(); + sd.m_time = ns.getFloat(); + int ticks_now = World::getWorld()->getTicksSinceStart(); + int ticks_back_to_own_goal = ns.getTime(); + try + { + ns.decodeString(&sd.m_kart); + ns.decodeStringW(&sd.m_player); + } + catch (std::exception &e) + { + sd.m_kart = getKart(sd.m_id)->getIdent(); + sd.m_player = getKart(sd.m_id)->getController()->getName(); + (void)e; + } + + if (first_goal) + { + m_red_scorers.push_back(sd); + } + else + { + m_blue_scorers.push_back(sd); + } + + // Ignore in live join + if (isStartPhase()) + return; + if (sd.m_correct_goal) { m_karts[sd.m_id]->getKartModel() @@ -379,19 +408,6 @@ void SoccerWorld::handlePlayerGoalFromServer(const NetworkString& ns) ->setAnimation(KartModel::AF_LOSE_START, true/* play_non_loop*/); } - if (first_goal) - { - m_red_scorers.push_back(sd); - m_red_score_times.push_back(score_time); - } - else - { - m_blue_scorers.push_back(sd); - m_blue_score_times.push_back(score_time); - } - int ticks_now = World::getWorld()->getTicksSinceStart(); - int ticks_back_to_own_goal = ns.getTime(); - if (ticks_now >= ticks_back_to_own_goal) { Log::warn("SoccerWorld", "Server ticks %d is too close to client ticks " @@ -751,3 +767,60 @@ void SoccerWorld::enterRaceOverState() } } // enterRaceOverState + +// ---------------------------------------------------------------------------- +void SoccerWorld::saveCompleteState(BareNetworkString* bns) +{ + const unsigned red_scorers = m_red_scorers.size(); + bns->addUInt32(red_scorers); + for (unsigned i = 0; i < red_scorers; i++) + { + bns->addUInt8((uint8_t)m_red_scorers[i].m_id) + .addUInt8(m_red_scorers[i].m_correct_goal) + .addFloat(m_red_scorers[i].m_time) + .encodeString(m_red_scorers[i].m_kart) + .encodeString(m_red_scorers[i].m_player); + } + + const unsigned blue_scorers = m_blue_scorers.size(); + bns->addUInt32(blue_scorers); + for (unsigned i = 0; i < blue_scorers; i++) + { + bns->addUInt8((uint8_t)m_blue_scorers[i].m_id) + .addUInt8(m_blue_scorers[i].m_correct_goal) + .addFloat(m_blue_scorers[i].m_time) + .encodeString(m_blue_scorers[i].m_kart) + .encodeString(m_blue_scorers[i].m_player); + } +} // saveCompleteState + +// ---------------------------------------------------------------------------- +void SoccerWorld::restoreCompleteState(const BareNetworkString& b) +{ + m_red_scorers.clear(); + m_blue_scorers.clear(); + + const unsigned red_size = b.getUInt32(); + for (unsigned i = 0; i < red_size; i++) + { + ScorerData sd; + sd.m_id = b.getUInt8(); + sd.m_correct_goal = b.getUInt8() == 1; + sd.m_time = b.getFloat(); + b.decodeString(&sd.m_kart); + b.decodeStringW(&sd.m_player); + m_red_scorers.push_back(sd); + } + + const unsigned blue_size = b.getUInt32(); + for (unsigned i = 0; i < blue_size; i++) + { + ScorerData sd; + sd.m_id = b.getUInt8(); + sd.m_correct_goal = b.getUInt8() == 1; + sd.m_time = b.getFloat(); + b.decodeString(&sd.m_kart); + b.decodeStringW(&sd.m_player); + m_blue_scorers.push_back(sd); + } +} // restoreCompleteState diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index dead188bb..8ae78afd2 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -41,13 +41,18 @@ class TrackSector; class SoccerWorld : public WorldWithRank { public: - class ScorerData + struct ScorerData { - public: /** World ID of kart which scores. */ - unsigned int m_id; + unsigned int m_id; /** Whether this goal is socred correctly (identify for own goal). */ - bool m_correct_goal; + bool m_correct_goal; + /** Time goal. */ + float m_time; + /** Kart ident which scores. */ + std::string m_kart; + /** Player name which scores. */ + core::stringw m_player; }; // ScorerData private: @@ -274,9 +279,7 @@ private: /** Goals data of each team scored */ std::vector m_red_scorers; - std::vector m_red_score_times; std::vector m_blue_scorers; - std::vector m_blue_score_times; /** Data generated from navmesh */ TrackSector* m_ball_track_sector; @@ -347,12 +350,6 @@ public: const std::vector& getScorers(KartTeam team) const { return (team == KART_TEAM_BLUE ? m_blue_scorers : m_red_scorers); } // ------------------------------------------------------------------------ - const std::vector& getScoreTimes(KartTeam team) const - { - return (team == KART_TEAM_BLUE ? - m_blue_score_times : m_red_score_times); - } - // ------------------------------------------------------------------------ int getBallNode() const; // ------------------------------------------------------------------------ const Vec3& getBallPosition() const @@ -417,6 +414,10 @@ public: } return progress; } + // ------------------------------------------------------------------------ + virtual void saveCompleteState(BareNetworkString* bns) OVERRIDE; + // ------------------------------------------------------------------------ + virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; }; // SoccerWorld diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 30a0f7dee..0790e09ef 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -1286,16 +1286,12 @@ void RaceResultGUI::displayCTFResults() current_y += rect.Height / 2 + rect.Height / 4; font = GUIEngine::getSmallFont(); std::vector scorers = sw->getScorers(KART_TEAM_RED); + + // Maximum 10 scorers displayed in result screen while (scorers.size() > 10) { scorers.erase(scorers.begin()); } - std::vector score_times = sw->getScoreTimes(KART_TEAM_RED); - while (score_times.size() > 10) - { - score_times.erase(score_times.begin()); - } - irr::video::ITexture* scorer_icon; int prev_y = current_y; @@ -1303,8 +1299,7 @@ void RaceResultGUI::displayCTFResults() { const bool own_goal = !(scorers.at(i).m_correct_goal); - const int kart_id = scorers.at(i).m_id; - result_text = sw->getKart(kart_id)->getController()->getName(); + result_text = scorers.at(i).m_player; if (own_goal) { @@ -1314,7 +1309,7 @@ void RaceResultGUI::displayCTFResults() } result_text.append(" "); - result_text.append(StringUtils::timeToString(score_times.at(i)).c_str()); + result_text.append(StringUtils::timeToString(scorers.at(i).m_time).c_str()); rect = font->getDimension(result_text.c_str()); if (height - prev_y < ((short)scorers.size() + 1)*(short)rect.Height) @@ -1327,34 +1322,35 @@ void RaceResultGUI::displayCTFResults() pos = core::rect(current_x, current_y, current_x, current_y); 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 = (irr::u32)(font->getDimension(result_text.c_str()).Width / 1.5f); - dest_rect = core::recti(current_x - offset_x - 30, current_y, current_x - offset_x, current_y + 30); - draw2DImage(scorer_icon, dest_rect, source_rect, - NULL, NULL, true); + irr::video::ITexture* scorer_icon = NULL; + const KartProperties* kp = kart_properties_manager->getKart(scorers.at(i).m_kart); + if (kp) + scorer_icon = kp->getIconMaterial()->getTexture(); + if (scorer_icon) + { + source_rect = core::recti(core::vector2di(0, 0), scorer_icon->getSize()); + irr::u32 offset_x = (irr::u32)(font->getDimension(result_text.c_str()).Width / 1.5f); + core::recti r = core::recti(current_x - offset_x - 30, current_y, current_x - offset_x, current_y + 30); + draw2DImage(scorer_icon, r, source_rect, + NULL, NULL, true); + } } //The blue scorers: current_y = prev_y; current_x += UserConfigParams::m_width / 2 - red_icon->getSize().Width / 2; scorers = sw->getScorers(KART_TEAM_BLUE); + while (scorers.size() > 10) { scorers.erase(scorers.begin()); } - score_times = sw->getScoreTimes(KART_TEAM_BLUE); - while (score_times.size() > 10) - { - score_times.erase(score_times.begin()); - } + for (unsigned int i = 0; i < scorers.size(); i++) { const bool own_goal = !(scorers.at(i).m_correct_goal); - const int kart_id = scorers.at(i).m_id; - result_text = sw->getKart(kart_id)->getController()->getName(); + result_text = scorers.at(i).m_player; if (own_goal) { @@ -1363,7 +1359,7 @@ void RaceResultGUI::displayCTFResults() } result_text.append(" "); - result_text.append(StringUtils::timeToString(score_times.at(i)).c_str()); + result_text.append(StringUtils::timeToString(scorers.at(i).m_time).c_str()); rect = font->getDimension(result_text.c_str()); if (height - prev_y < ((short)scorers.size() + 1)*(short)rect.Height) @@ -1376,14 +1372,18 @@ void RaceResultGUI::displayCTFResults() pos = core::rect(current_x, current_y, current_x, current_y); 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 = (irr::u32)(font->getDimension(result_text.c_str()).Width / 1.5f); - - dest_rect = core::recti(current_x - offset_x - 30, current_y, current_x - offset_x, current_y + 30); - draw2DImage(scorer_icon, dest_rect, source_rect, - NULL, NULL, true); + irr::video::ITexture* scorer_icon = NULL; + const KartProperties* kp = kart_properties_manager->getKart(scorers.at(i).m_kart); + if (kp) + scorer_icon = kp->getIconMaterial()->getTexture(); + if (scorer_icon) + { + source_rect = core::recti(core::vector2di(0, 0), scorer_icon->getSize()); + irr::u32 offset_x = (irr::u32)(font->getDimension(result_text.c_str()).Width / 1.5f); + core::recti r = core::recti(current_x - offset_x - 30, current_y, current_x - offset_x, current_y + 30); + draw2DImage(scorer_icon, r, source_rect, + NULL, NULL, true); + } } #endif }