diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index fa5e94dc2..e1a5bea5f 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -49,6 +49,7 @@ using namespace irr; #include "modes/linear_world.hpp" #include "modes/world.hpp" #include "modes/soccer_world.hpp" +#include "network/protocols/client_lobby.hpp" #include "race/race_manager.hpp" #include "states_screens/race_gui_multitouch.hpp" #include "tracks/track.hpp" @@ -569,19 +570,25 @@ void RaceGUI::drawGlobalMiniMap() lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.2f))); draw2DImage(m_blue_flag, bp, bs, NULL, NULL, true); } - + + AbstractKart* target_kart = NULL; + Camera* cam = Camera::getActiveCamera(); + auto cl = LobbyProtocol::get(); + bool is_nw_spectate = cl && cl->isSpectator(); + // For network spectator highlight + if (race_manager->getNumLocalPlayers() == 1 && cam && is_nw_spectate) + target_kart = cam->getKart(); + // Move AI/remote players to the beginning, so that local players icons // are drawn above them World::KartList karts = world->getKarts(); - std::sort(karts.begin(), karts.end(), [] - (const std::shared_ptr& a, - const std::shared_ptr& b)->bool + std::partition(karts.begin(), karts.end(), [target_kart, is_nw_spectate] + (const std::shared_ptr& k)->bool { - bool aIsLocalPlayer = a->getController()->isLocalPlayerController(); - bool bIsLocalPlayer = b->getController()->isLocalPlayerController(); - - // strictly greater than, so return false if equal - return !aIsLocalPlayer && aIsLocalPlayer != bIsLocalPlayer; + if (is_nw_spectate) + return k.get() != target_kart; + else + return !k->getController()->isLocalPlayerController(); }); for (unsigned int i = 0; i < karts.size(); i++) @@ -589,7 +596,7 @@ void RaceGUI::drawGlobalMiniMap() const AbstractKart *kart = karts[i].get(); const SpareTireAI* sta = dynamic_cast(kart->getController()); - + // don't draw eliminated kart if (kart->isEliminated() && !(sta && sta->isMoving())) continue; @@ -605,9 +612,11 @@ void RaceGUI::drawGlobalMiniMap() { continue; } + bool is_local = is_nw_spectate ? kart == target_kart : + kart->getController()->isLocalPlayerController(); // int marker_height = m_marker->getSize().Height; core::rect source(core::position2di(0, 0), icon->getSize()); - int marker_half_size = (kart->getController()->isLocalPlayerController() + int marker_half_size = (is_local ? m_minimap_player_size : m_minimap_ai_size )>>1; core::rect position(m_map_left+(int)(draw_at.getX()-marker_half_size), @@ -618,8 +627,7 @@ void RaceGUI::drawGlobalMiniMap() bool has_teams = (ctf_world || soccer_world); // Highlight the player icons with some backgorund image. - if ((has_teams || kart->getController()->isLocalPlayerController()) && - m_icons_frame != NULL) + if ((has_teams || is_local) && m_icons_frame != NULL) { video::SColor color = kart->getKartProperties()->getColor(); diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index 8144b96db..413284aae 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -43,6 +43,7 @@ #include "modes/capture_the_flag.hpp" #include "modes/linear_world.hpp" #include "modes/world.hpp" +#include "network/protocols/client_lobby.hpp" #include "network/network_config.hpp" #include "states_screens/race_gui_multitouch.hpp" #include "tracks/track.hpp" @@ -894,10 +895,19 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) font->setBlackBorder(false); } - int w = kart->getController() - ->isLocalPlayerController() ? ICON_PLAYER_WIDTH - : ICON_WIDTH; - drawPlayerIcon(kart, x, y, w); + + AbstractKart* target_kart = NULL; + Camera* cam = Camera::getActiveCamera(); + auto cl = LobbyProtocol::get(); + bool is_nw_spectate = cl && cl->isSpectator(); + // For network spectator highlight + if (race_manager->getNumLocalPlayers() == 1 && cam && is_nw_spectate) + target_kart = cam->getKart(); + bool is_local = is_nw_spectate ? kart == target_kart : + kart->getController()->isLocalPlayerController(); + + int w = is_local ? ICON_PLAYER_WIDTH : ICON_WIDTH; + drawPlayerIcon(kart, x, y, w, is_local); } //next position #endif } // drawGlobalPlayerIcons @@ -906,7 +916,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) /** Draw one player icon * Takes care of icon looking different due to plumber, squashing, ... */ -void RaceGUIBase::drawPlayerIcon(AbstractKart *kart, int x, int y, int w) +void RaceGUIBase::drawPlayerIcon(AbstractKart *kart, int x, int y, int w, + bool is_local) { #ifndef SERVER_ONLY video::ITexture *icon = @@ -943,8 +954,7 @@ void RaceGUIBase::drawPlayerIcon(AbstractKart *kart, int x, int y, int w) const core::rect pos(x, y, x+w, y+w); //to bring to light the player's icon: add a background - if (kart->getController()->isLocalPlayerController() && - m_icons_frame != NULL) + if (is_local && m_icons_frame != NULL) { video::SColor colors[4]; for (unsigned int i=0;i<4;i++) diff --git a/src/states_screens/race_gui_base.hpp b/src/states_screens/race_gui_base.hpp index af75150e6..6708099e3 100644 --- a/src/states_screens/race_gui_base.hpp +++ b/src/states_screens/race_gui_base.hpp @@ -249,7 +249,8 @@ public: virtual void clearAllMessages() { m_messages.clear(); } void drawGlobalPlayerIcons(int bottom_margin); - void drawPlayerIcon(AbstractKart *kart, int x, int y, int w); + void drawPlayerIcon(AbstractKart *kart, int x, int y, int w, + bool is_local); virtual void drawEnergyMeter(int x, int y, const AbstractKart *kart, const core::recti &viewport,