Race UI improvements (#3465)

* Add a flag icon next to the lap counter

* Fix flag icon scaling across resolutions

* Add an option controlling minimap display

* Allow to display all the karts in the icon list if the minimap is hidden/on the right

* Remove useless scaling

* Fix minimap issues in splitscreen

* Align the spinners in the UI options

* Check for touch settings instead of a compile-time Android check

* Fix server-only compilation

* Make UI options checkboxes have the same size than checkboxes elsewhere

* Add translation cues for minimap options

* Don't look up icon paths every frame
This commit is contained in:
Alayan-stk-2 2018-09-24 03:15:51 +02:00 committed by auriamg
parent 0c3691cf18
commit 1c6890f77e
8 changed files with 149 additions and 51 deletions

View File

@ -44,6 +44,8 @@ options_language.png by Alayan, based on http://www.languageicon.org/, released
blue_flag.png, heart.png and red_flag.png by Benau, released under CC-BY-SA 4
lap_flag.png, modified by Alayan, original by Alina Oleynik from The Noun Project, under CC-BY 3.0
====
Glass Skin by Auria, under CC-BY-SA 3+

BIN
data/gui/icons/lap_flag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -30,14 +30,26 @@
<!-- ************ SKIN CHOICE ************ -->
<div layout="horizontal-row" width="100%" height="fit">
<label I18N="In the ui settings" text="Skin" align="center"/>
<label proportion="1" I18N="In the ui settings" text="Skin" align="center"/>
<spacer width="2%" height="20"/>
<spinner id="skinchoice" width="30%"/>
<div layout="horizontal-row" proportion="5" height="100%">
<spinner id="skinchoice" width="60%"/>
</div>
</div>
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<label proportion="1" I18N="In the ui settings" text="Minimap" align="center"/>
<spacer width="2%" height="20"/>
<div layout="horizontal-row" proportion="5" height="100%">
<spinner id="minimap" width="60%"/>
</div>
</div>
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="showfps"/>
<spacer width="1%" height="100%" />
<label height="100%" I18N="In the ui settings" text="Display FPS" word_wrap="true"/>
@ -45,7 +57,7 @@
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="split_screen_horizontally"/>
<spacer width="1%" height="100%" />
<label height="100%" I18N="In the ui settings" text="Multiplayer splits screen horizontally" word_wrap="true"/>
@ -53,7 +65,7 @@
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="perPlayerDifficulty"/>
<spacer width="1%" height="100%" />
<label height="100%" I18N="In the ui settings" text="Enable per-player handicaps" word_wrap="true"/>
@ -61,7 +73,7 @@
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="enable-internet"/>
<spacer width="1%" height="100%" />
<label height="100%" I18N="In the ui settings" text="Connect to the Internet" word_wrap="true"/>
@ -69,7 +81,7 @@
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="enable-hw-report"/>
<spacer width="1%" height="100%" />
<label height="100%" id="label-hw-report" I18N="In the ui settings"
@ -78,7 +90,7 @@
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="show-login"/>
<spacer width="1%" height="100%" />
<label height="100%" I18N="In the ui settings" text="Always show login screen" word_wrap="true"/>
@ -86,7 +98,7 @@
<spacer width="5" height="2%"/>
<div layout="horizontal-row" width="100%" height="6%">
<div layout="horizontal-row" width="100%" height="fit">
<checkbox id="enable-lobby-chat"/>
<spacer width="1%" height="100%" />
<label height="100%" id="label-lobby-chat" I18N="In the ui settings" text="Enable chatting in networking lobby" word_wrap="true"/>

View File

@ -903,6 +903,10 @@ namespace UserConfigParams
PARAM_DEFAULT( StringUserConfigParam("Peach.stkskin", "skin_file",
"Name of the skin to use") );
PARAM_PREFIX IntUserConfigParam m_minimap_display
PARAM_DEFAULT(IntUserConfigParam(0, "minimap_display",
"Minimap: 0 bottom-left, 1 middle-right, 2 hidden"));
// ---- Handicap
PARAM_PREFIX GroupUserConfigParam m_handicap
PARAM_DEFAULT( GroupUserConfigParam("Handicap",

View File

@ -108,6 +108,23 @@ void OptionsScreenUI::loadedFromFile()
skinSelector->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(skin_count-1);
// Setup the minimap options spinner
GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
assert( minimap_options != NULL );
minimap_options->m_properties[PROP_WRAP_AROUND] = "true";
minimap_options->clearLabels();
//I18N: In the UI options, minimap position in the race UI
minimap_options->addLabel( core::stringw(_("In the bottom-left")));
//I18N: In the UI options, minimap position in the race UI
minimap_options->addLabel( core::stringw(_("On the right side")));
//I18N: In the UI options, minimap position in the race UI
minimap_options->addLabel( core::stringw(_("Hidden")));
minimap_options->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
if (UserConfigParams::m_multitouch_enabled &&
UserConfigParams::m_multitouch_mode != 0)
minimap_options->m_properties[GUIEngine::PROP_MIN_VALUE] = "1";
minimap_options->m_properties[GUIEngine::PROP_MAX_VALUE] = "2";
} // loadedFromFile
// -----------------------------------------------------------------------------
@ -123,6 +140,17 @@ void OptionsScreenUI::init()
GUIEngine::SpinnerWidget* skinSelector = getWidget<GUIEngine::SpinnerWidget>("skinchoice");
assert( skinSelector != NULL );
GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
assert( minimap_options != NULL );
if (UserConfigParams::m_multitouch_enabled &&
UserConfigParams::m_multitouch_mode != 0 &&
UserConfigParams::m_minimap_display == 0)
{
UserConfigParams::m_minimap_display = 1;
}
minimap_options->setValue(UserConfigParams::m_minimap_display);
// ---- video modes
CheckBoxWidget* splitscreen_method = getWidget<CheckBoxWidget>("split_screen_horizontally");
assert(splitscreen_method != NULL);
@ -235,6 +263,12 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
GUIEngine::reloadSkin();
irr_driver->setMaxTextureSize();
}
else if (name == "minimap")
{
GUIEngine::SpinnerWidget* minimap_options = getWidget<GUIEngine::SpinnerWidget>("minimap");
assert( minimap_options != NULL );
UserConfigParams::m_minimap_display = minimap_options->getValue();
}
else if (name == "split_screen_horizontally")
{
CheckBoxWidget* split_screen_horizontally = getWidget<CheckBoxWidget>("split_screen_horizontally");

View File

@ -140,8 +140,20 @@ RaceGUI::RaceGUI()
m_minimap_player_size = (int)( stk_config->m_minimap_player_icon * scaling);
m_map_width = (int)(map_size * scaling);
m_map_height = (int)(map_size * scaling);
m_map_left = (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
if(UserConfigParams::m_minimap_display == 1 && /*map on the right side*/
race_manager->getNumLocalPlayers() == 1)
{
m_map_left = (int)(irr_driver->getActualScreenSize().Width -
m_map_width - 10.0f*scaling);
m_map_bottom = (int)(3*irr_driver->getActualScreenSize().Height/4 -
m_map_height);
}
else // default, map in the bottom-left corner
{
m_map_left = (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
}
// Minimap is also rendered bigger via OpenGL, so find power-of-two again
const int map_texture = 2 << ((int) ceil(1.0 + log(128.0 * scaling)));
@ -152,7 +164,9 @@ RaceGUI::RaceGUI()
// special case : when 3 players play, use available 4th space for such things
if (race_manager->getIfEmptyScreenSpaceExists())
{
m_map_left = irr_driver->getActualScreenSize().Width - m_map_width;
m_map_left = irr_driver->getActualScreenSize().Width -
m_map_width - (int)( 10.0f * scaling);
m_map_bottom = (int)( 10.0f * scaling);
}
else if (m_multitouch_gui != NULL)
{
@ -170,6 +184,15 @@ RaceGUI::RaceGUI()
m_speed_bar_icon = material_manager->getMaterial("speedfore.png");
m_speed_bar_icon->getTexture(false,false);
//createMarkerTexture();
// Load icon textures for later reuse
m_lap_flag = irr_driver->getTexture(FileManager::GUI_ICON, "lap_flag.png");
m_red_team = irr_driver->getTexture(FileManager::GUI_ICON, "soccer_ball_red.png");
m_blue_team = irr_driver->getTexture(FileManager::GUI_ICON, "soccer_ball_blue.png");
m_red_flag = irr_driver->getTexture(FileManager::GUI_ICON, "red_flag.png");
m_blue_flag = irr_driver->getTexture(FileManager::GUI_ICON, "blue_flag.png");
m_soccer_ball = irr_driver->getTexture(FileManager::GUI_ICON, "soccer_ball_normal.png");
m_heart_icon = irr_driver->getTexture(FileManager::GUI_ICON, "heart.png");
} // RaceGUI
//-----------------------------------------------------------------------------
@ -262,7 +285,15 @@ void RaceGUI::renderGlobal(float dt)
}
}
if (!m_is_tutorial) drawGlobalPlayerIcons(m_map_height);
if (!m_is_tutorial)
{
if(UserConfigParams::m_minimap_display == 0 || /*map in the bottom-left*/
(UserConfigParams::m_minimap_display == 1 &&
race_manager->getNumLocalPlayers() >= 2))
drawGlobalPlayerIcons(m_map_height + m_map_bottom);
else // map hidden or on the right side
drawGlobalPlayerIcons(0);
}
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
drawScores();
#endif
@ -324,11 +355,7 @@ void RaceGUI::drawScores()
static video::SColor color = video::SColor(255,255,255,255);
//Draw two teams score
irr::video::ITexture *red_team = irr_driver->getTexture(FileManager::GUI_ICON,
"soccer_ball_red.png");
irr::video::ITexture *blue_team = irr_driver->getTexture(FileManager::GUI_ICON,
"soccer_ball_blue.png");
irr::video::ITexture *team_icon = red_team;
irr::video::ITexture *team_icon = m_red_team;
for(unsigned int i=0; i<2; i++)
{
@ -347,7 +374,7 @@ void RaceGUI::drawScores()
if (i == 1)
{
team_icon = blue_team;
team_icon = m_blue_team;
}
core::rect<s32> indicator_pos(offset_x, offset_y,
offset_x + (int)(m_minimap_player_size*2),
@ -498,6 +525,10 @@ void RaceGUI::drawLiveDifference()
void RaceGUI::drawGlobalMiniMap()
{
#ifndef SERVER_ONLY
//TODO : exception for some game modes ? Another option "Hidden in race, shown in battle ?"
if(UserConfigParams::m_minimap_display == 2 /*map hidden*/)
return;
// draw a map when arena has a navigation mesh.
Track *track = Track::getCurrentTrack();
if ( (track->isArena() || track->isSoccer()) && !(track->hasNavMesh()) )
@ -517,48 +548,45 @@ void RaceGUI::drawGlobalMiniMap()
if (ctf)
{
Vec3 draw_at;
video::ITexture* icon =
irr_driver->getTexture(FileManager::GUI_ICON, "red_flag.png");
if (!ctf->isRedFlagInBase())
{
track->mapPoint2MiniMap(Track::getCurrentTrack()->getRedFlag().getOrigin(),
&draw_at);
core::rect<s32> rs(core::position2di(0, 0), icon->getSize());
core::rect<s32> rs(core::position2di(0, 0), m_red_flag->getSize());
core::rect<s32> rp(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.2f)),
m_map_left+(int)(draw_at.getX()+(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.2f)));
draw2DImage(icon, rp, rs, NULL, NULL, true, true);
draw2DImage(m_red_flag, rp, rs, NULL, NULL, true, true);
}
track->mapPoint2MiniMap(ctf->getRedFlag(), &draw_at);
core::rect<s32> rs(core::position2di(0, 0), icon->getSize());
core::rect<s32> rs(core::position2di(0, 0), m_red_flag->getSize());
core::rect<s32> rp(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.2f)),
m_map_left+(int)(draw_at.getX()+(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.2f)));
draw2DImage(icon, rp, rs, NULL, NULL, true);
draw2DImage(m_red_flag, rp, rs, NULL, NULL, true);
icon = irr_driver->getTexture(FileManager::GUI_ICON, "blue_flag.png");
if (!ctf->isBlueFlagInBase())
{
track->mapPoint2MiniMap(Track::getCurrentTrack()->getBlueFlag().getOrigin(),
&draw_at);
core::rect<s32> rs(core::position2di(0, 0), icon->getSize());
core::rect<s32> rs(core::position2di(0, 0), m_blue_flag->getSize());
core::rect<s32> rp(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.2f)),
m_map_left+(int)(draw_at.getX()+(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.2f)));
draw2DImage(icon, rp, rs, NULL, NULL, true, true);
draw2DImage(m_blue_flag, rp, rs, NULL, NULL, true, true);
}
track->mapPoint2MiniMap(ctf->getBlueFlag(), &draw_at);
core::rect<s32> bs(core::position2di(0, 0), icon->getSize());
core::rect<s32> bs(core::position2di(0, 0), m_blue_flag->getSize());
core::rect<s32> bp(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.2f)),
m_map_left+(int)(draw_at.getX()+(m_minimap_player_size/1.4f)),
lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.2f)));
draw2DImage(icon, bp, bs, NULL, NULL, true);
draw2DImage(m_blue_flag, bp, bs, NULL, NULL, true);
}
for(unsigned int i=0; i<world->getNumKarts(); i++)
@ -572,8 +600,7 @@ void RaceGUI::drawGlobalMiniMap()
Vec3 draw_at;
track->mapPoint2MiniMap(xyz, &draw_at);
video::ITexture* icon = sta ?
irr_driver->getTexture(FileManager::GUI_ICON, "heart.png") :
video::ITexture* icon = sta ? m_heart_icon :
kart->getKartProperties()->getMinimapIcon();
if (icon == NULL)
{
@ -613,16 +640,13 @@ void RaceGUI::drawGlobalMiniMap()
{
Vec3 draw_at;
track->mapPoint2MiniMap(sw->getBallPosition(), &draw_at);
video::ITexture* icon =
irr_driver->getTexture(FileManager::GUI_ICON, "soccer_ball_normal.png");
core::rect<s32> source(core::position2di(0, 0), icon->getSize());
core::rect<s32> source(core::position2di(0, 0), m_soccer_ball->getSize());
core::rect<s32> position(m_map_left+(int)(draw_at.getX()-(m_minimap_player_size/2.5f)),
lower_y -(int)(draw_at.getY()+(m_minimap_player_size/2.5f)),
m_map_left+(int)(draw_at.getX()+(m_minimap_player_size/2.5f)),
lower_y -(int)(draw_at.getY()-(m_minimap_player_size/2.5f)));
draw2DImage(icon, position, source, NULL, NULL, true);
draw2DImage(m_soccer_ball, position, source, NULL, NULL, true);
}
#endif
} // drawGlobalMiniMap
@ -1102,14 +1126,15 @@ unsigned int RaceGUI::computeVerticesForMeter(core::vector2df position[], float
} //computeVerticesForMeter
//-----------------------------------------------------------------------------
/** Displays the rank and the lap of the kart.
/** Displays the lap of the kart.
* \param info Info object c
*/
void RaceGUI::drawLap(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
{
// Don't display laps or ranks if the kart has already finished the race.
#ifndef SERVER_ONLY
// Don't display laps if the kart has already finished the race.
if (kart->hasFinishedRace()) return;
World *world = World::getWorld();
@ -1158,13 +1183,29 @@ void RaceGUI::drawLap(const AbstractKart* kart,
// don't display 'lap 0/..' at the start of a race
if (lap < 0 ) return;
// Display lap flag
int icon_width = irr_driver->getActualScreenSize().Height/19;
core::rect<s32> indicator_pos(viewport.LowerRightCorner.X - (icon_width+10),
pos.UpperLeftCorner.Y,
viewport.LowerRightCorner.X - 10,
pos.UpperLeftCorner.Y + icon_width);
core::rect<s32> source_rect(core::position2d<s32>(0,0),
m_lap_flag->getSize());
draw2DImage(m_lap_flag,indicator_pos,source_rect,
NULL,NULL,true);
pos.UpperLeftCorner.X -= icon_width;
pos.LowerRightCorner.X -= icon_width;
static video::SColor color = video::SColor(255, 255, 255, 255);
std::ostringstream out;
out << lap + 1 << "/" << race_manager->getNumLaps();
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
font->setScale(scaling.Y < 1.0f ? 0.5f: 1.0f);
font->draw(out.str().c_str(), pos, color);
font->setScale(1.0f);
#endif
} // drawLap

View File

@ -91,6 +91,16 @@ private:
/** Height of the digit font. */
int m_font_height;
/** Icon textures (stored as variables to not look up
their location on every frame) */
irr::video::ITexture *m_lap_flag;
irr::video::ITexture *m_red_team;
irr::video::ITexture *m_blue_team;
irr::video::ITexture *m_red_flag;
irr::video::ITexture *m_blue_flag;
irr::video::ITexture *m_soccer_ball;
irr::video::ITexture *m_heart_icon;
/** Animation state: none, getting smaller (old value),
* getting bigger (new number). */
enum AnimationState {AS_NONE, AS_SMALLER, AS_BIGGER};

View File

@ -697,10 +697,11 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
const unsigned int num_karts = race_manager->getNumberOfKarts() - sta;
// -2 because that's the spacing further on
int ICON_PLAYER_WIDTH = y_space / num_karts - 2;
int ICON_PLAYER_WIDTH = y_space / (num_karts) - 2;
int icon_width_max = (int)(50*(irr_driver->getActualScreenSize().Width/800.0f));
int icon_width_min = (int)(35*(irr_driver->getActualScreenSize().Height/600.0f));
int icon_width_max = (int)(60*(irr_driver->getActualScreenSize().Width/1024.0f));
int icon_width_min = (int)(35*((irr_driver->getActualScreenSize().Height - (y_base+10))/720.0f));
if (icon_width_min < 35) icon_width_min = 35;
if (icon_width_min > icon_width_max)
{
int icon_width_tmp = icon_width_max;
@ -712,14 +713,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
if (ICON_PLAYER_WIDTH > icon_width_max) ICON_PLAYER_WIDTH = icon_width_max;
if (ICON_PLAYER_WIDTH < icon_width_min) ICON_PLAYER_WIDTH = icon_width_min;
// TODO: Is this absolute treshold necessary?
if(irr_driver->getActualScreenSize().Height<600)
{
ICON_PLAYER_WIDTH = 35;
}
// Icon width for the AI karts
int ICON_WIDTH = ICON_PLAYER_WIDTH * 4 / 5;
int ICON_WIDTH = ICON_PLAYER_WIDTH * 5 / 6;
WorldWithRank* world = dynamic_cast<WorldWithRank*>(World::getWorld());
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());