Compare commits

...

10 Commits

Author SHA1 Message Date
Alayan
fc969982da Merge with latest master 2018-10-05 17:55:02 +02:00
Alayan
3e6d7afb14 Move rank indicator to the top-right and adda rank icon 2018-09-30 20:55:04 +02:00
Alayan
87725b4415 Make alert indicator more discrete, restrict kart icon display 2018-09-30 17:00:46 +02:00
Alayan
61df9c4b35 Don't show an alert when the player uses an offensive powerup 2018-09-29 16:41:43 +02:00
Alayan
7b62947e08 Add an alert icon when a dangerous projectile is nerby 2018-09-29 16:28:34 +02:00
Alayan
dcec81c7d5 Add an alert icon when another kart is nearby 2018-09-29 15:42:50 +02:00
Alayan
799f6d98c1 Optimize new icons 2018-09-29 14:26:43 +02:00
Alayan
fa98a30543 Icons for danger warnings 2018-09-29 14:22:51 +02:00
Alayan
7386465931 Remove outdated comment 2018-09-26 18:57:36 +02:00
Alayan
f5abd2c798 Move the rank indicator to the top-left and clarify it 2018-09-26 18:57:13 +02:00
9 changed files with 209 additions and 26 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -225,6 +225,9 @@ public:
/** Returns the type of flyable. */
PowerupManager::PowerupType getType() const {return m_type;}
// ------------------------------------------------------------------------
/** Returns the owner's kart */
AbstractKart *getOwner() const { return m_owner;}
// ------------------------------------------------------------------------
/** Returns the owner's kart */
AbstractKart *getOwner() const { return m_owner;}

View File

@ -38,7 +38,9 @@ using namespace irr;
#include "guiengine/modaldialog.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "items/attachment.hpp"
#include "items/powerup_manager.hpp"
#include "items/projectile_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp"
#include "karts/controller/spare_tire_ai.hpp"
@ -187,12 +189,19 @@ RaceGUI::RaceGUI()
// Load icon textures for later reuse
m_lap_flag = irr_driver->getTexture(FileManager::GUI_ICON, "lap_flag.png");
m_rank_icon = irr_driver->getTexture(FileManager::GUI_ICON, "podium.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");
m_danger[0] = irr_driver->getTexture(FileManager::GUI_ICON, "alert_nodanger.png");
m_danger[1] = irr_driver->getTexture(FileManager::GUI_ICON, "alert_danger.png");
m_danger[2] = irr_driver->getTexture(FileManager::GUI_ICON, "alert_bigdanger.png");
m_projectile[0] = powerup_manager->getIcon(PowerupManager::POWERUP_BOWLING)->getTexture();
m_projectile[1] = powerup_manager->getIcon(PowerupManager::POWERUP_CAKE)->getTexture();
m_projectile[2] = powerup_manager->getIcon(PowerupManager::POWERUP_RUBBERBALL)->getTexture();
} // RaceGUI
//-----------------------------------------------------------------------------
@ -286,11 +295,14 @@ void RaceGUI::renderGlobal(float dt)
}
}
if (!m_is_tutorial)
if (!m_is_tutorial &&
(race_manager->getNumLocalPlayers() == 1 ||
(race_manager->getNumLocalPlayers() == 2 &&
UserConfigParams::split_screen_horizontally == true)))
{
if(UserConfigParams::m_minimap_display == 0 || /*map in the bottom-left*/
(UserConfigParams::m_minimap_display == 1 &&
race_manager->getNumLocalPlayers() >= 2))
race_manager->getNumLocalPlayers() == 2))
drawGlobalPlayerIcons(m_map_height + m_map_bottom);
else // map hidden or on the right side
drawGlobalPlayerIcons(0);
@ -335,7 +347,8 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
if (m_multitouch_gui == NULL)
{
drawPowerupIcons(kart, viewport, scaling);
drawSpeedEnergyRank(kart, viewport, scaling, dt);
drawSpeedEnergy(kart, viewport, scaling, dt);
drawRank(kart, viewport, scaling, dt);
}
if (!m_is_tutorial)
@ -655,7 +668,7 @@ void RaceGUI::drawGlobalMiniMap()
//-----------------------------------------------------------------------------
/** Energy meter that gets filled with nitro. This function is called from
* drawSpeedEnergyRank, which defines the correct position of the energy
* drawSpeedEnergy, which defines the correct position of the energy
* meter.
* \param x X position of the meter.
* \param y Y position of the meter.
@ -773,7 +786,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
} // drawEnergyMeter
//-----------------------------------------------------------------------------
/** Draws the rank of a player.
/** Draws misc. info inside the meters circle.
* \param kart The kart of the player.
* \param offset Offset of top left corner for this display (for splitscreen).
* \param min_ratio Scaling of the screen (for splitscreen).
@ -781,13 +794,15 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
* \param meter_height Height of the meter (inside which the rank is shown).
* \param dt Time step size.
*/
void RaceGUI::drawRank(const AbstractKart *kart,
void RaceGUI::drawMiscInfo(const AbstractKart *kart,
const core::vector2df &offset,
float min_ratio, int meter_width,
int meter_height, float dt)
{
static video::SColor color = video::SColor(255, 255, 255, 255);
// Draw hit or capture limit in network game
if ((race_manager->getMajorMode() == RaceManager::MAJOR_MODE_FREE_FOR_ALL ||
race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG) &&
race_manager->getHitCaptureLimit() != std::numeric_limits<int>::max())
@ -808,6 +823,117 @@ void RaceGUI::drawRank(const AbstractKart *kart,
font->setScale(1.0f);
return;
}
else if (race_manager->isLinearRaceMode())
{
float closest_kart_dist_squared = 99999.9f;
int closest_kart_id = -1;
bool closest_with_bad_attach = false;
World *world = World::getWorld();
for(unsigned int i=0;i<world->getNumKarts();i++)
{
float dist2 = world->getKart(i)->getXYZ().distance2(kart->getXYZ());
if (dist2 > 0 && dist2 < 900.0f &&
(!closest_with_bad_attach || dist2 < closest_kart_dist_squared))
{
if (!closest_with_bad_attach)
{
closest_kart_id = i;
closest_kart_dist_squared = dist2;
}
if (world->getKart(i)->getAttachment()->getType() == Attachment::ATTACH_BOMB ||
world->getKart(i)->getAttachment()->getType() == Attachment::ATTACH_SWATTER)
{
closest_with_bad_attach = true;
closest_kart_id = i;
closest_kart_dist_squared = dist2;
}
}
}
// Plungers are not shown, because they are not very dangerous,
// and in most cases fly too quickly to make an alert useful
int projectile_types[3]; //[2] basket, [1] cakes, [0] bowling
projectile_types[0] = projectile_manager->getNearbyProjectileCount(kart, 15.0f /*alert radius*/,
PowerupManager::POWERUP_BOWLING,
true /* exclude if owned by the kart */);
projectile_types[1] = projectile_manager->getNearbyProjectileCount(kart, 25.0f /*alert radius*/,
PowerupManager::POWERUP_CAKE,
true /* exclude if owned by the kart */);
projectile_types[2] = projectile_manager->getNearbyProjectileCount(kart, 50.0f /*alert radius*/,
PowerupManager::POWERUP_RUBBERBALL,
true /* exclude if owned by the kart */);
int icon_to_use = 2;
int projectile_to_show = -1;
// We show dangerous projectile with priority :
// basket ball > cake > bowling ball > plunger
if (projectile_types[2] >= 1)
projectile_to_show = 2;
else if (projectile_types[1] >= 1)
projectile_to_show = 1;
else if (projectile_types[0] >= 1)
projectile_to_show = 0;
// If no dangerous projectile and another kart close, show it
else if (closest_kart_id >= 0)
{
if (closest_with_bad_attach)
icon_to_use = 2;
else
icon_to_use = 1;
}
else
icon_to_use = 0;
int icon_width = meter_width/2;
int x = int(offset.X + 0.375f*meter_width);
int y = int(offset.Y - 0.235f*meter_height) - icon_width;
core::rect<s32> indicator_pos(x, y, x + icon_width, y + icon_width);
core::rect<s32> source_rect(core::position2d<s32>(0,0),
m_danger[icon_to_use]->getSize());
draw2DImage(m_danger[icon_to_use],indicator_pos,source_rect,
NULL,NULL,true);
x = x+0.1875f*icon_width;
y = y+0.1875f*icon_width;
icon_width = 0.625f*icon_width;
// Draw kart's icon
if (icon_to_use == 2 && projectile_to_show == -1)
{
drawPlayerIcon(world->getKart(closest_kart_id),
x, y, icon_width);
}
// Draw projectile's icon
if (icon_to_use == 2 && projectile_to_show >= 0)
{
core::rect<s32> proj_icon_pos(x, y, x + icon_width, y + icon_width);
core::rect<s32> base_rect(core::position2d<s32>(0,0),
m_projectile[projectile_to_show]->getSize());
draw2DImage(m_projectile[projectile_to_show],proj_icon_pos,base_rect,
NULL,NULL,true);
}
}
} // drawMiscInfo
//-----------------------------------------------------------------------------
/** Draws the rank of a player.
* \param kart The kart of the player.
* \param viewport The viewport to use.
* \param scaling Which scaling to apply to the rank indicator
* \param dt Time step size.
*/
void RaceGUI::drawRank(const AbstractKart *kart, const core::recti &viewport,
const core::vector2df &scaling, float dt)
{
#ifndef SERVER_ONLY
float min_ratio = std::min(scaling.X, scaling.Y);
static video::SColor color = video::SColor(255, 255, 255, 255);
// Draw rank
WorldWithRank *world = dynamic_cast<WorldWithRank*>(World::getWorld());
@ -862,31 +988,81 @@ void RaceGUI::drawRank(const AbstractKart *kart,
m_last_ranks[id] = kart->getPosition();
}
// If the time display in the top right is in this viewport,
// move the rank display down a little bit so that it is
// displayed under the time and laps.
core::recti pos;
pos.UpperLeftCorner.Y = viewport.UpperLeftCorner.Y +
irr_driver->getActualScreenSize().Height*6/100;
if (viewport.UpperLeftCorner.Y == 0 &&
viewport.LowerRightCorner.X == (int)(irr_driver->getActualScreenSize().Width) &&
!race_manager->getIfEmptyScreenSpaceExists())
{
pos.UpperLeftCorner.Y = irr_driver->getActualScreenSize().Height*18/100;
}
pos.LowerRightCorner.Y = viewport.LowerRightCorner.Y+20;
// 1. Draw the rank icon
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_rank_icon->getSize());
draw2DImage(m_rank_icon,indicator_pos,source_rect,
NULL,NULL,true);
// 2. Draw the total number of karts
// Fonts are drawn in the middle of the available area
// So we use the pos to specify the center of the desired area
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
std::ostringstream oss2;
oss2 << "/" << world->getNumKarts();
float offset = font->getDimension(world->getNumKarts() < 10 ? L"/9" : L"/19").Width;
float voffset = font->getDimension(L"9").Height;
font->setScale(min_ratio);
voffset = std::max<float>(voffset,font->getDimension(L"9").Height);
font->setScale(1.0f);
int middle_x = viewport.LowerRightCorner.X - (icon_width+20) - int(offset/2);
int middle_y = pos.UpperLeftCorner.Y + icon_width/2;
pos.LowerRightCorner = core::vector2di(middle_x, middle_y);
pos.UpperLeftCorner = core::vector2di(middle_x, middle_y);
font->draw(oss2.str().c_str(), pos, color, true, true);
// 3. Draw the rank itself
font->setScale(min_ratio * scale);
font->setShadow(video::SColor(255, 128, 0, 0));
std::ostringstream oss;
oss << rank; // the current font has no . :( << ".";
core::recti pos;
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
int(offset.Y - 0.49f*meter_height));
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
int(offset.Y - 0.49f*meter_height));
offset += font->getDimension(rank < 10 ? L"9" : L"19").Width;
middle_x -= (offset/2);
pos.LowerRightCorner = core::vector2di(middle_x, middle_y);
pos.UpperLeftCorner = core::vector2di(middle_x, middle_y);
font->draw(oss.str().c_str(), pos, color, true, true);
font->setScale(1.0f);
#endif
} // drawRank
//-----------------------------------------------------------------------------
/** Draws the speedometer, the display of available nitro, and
* the rank of the kart (inside the speedometer).
/** Draws the speedometer and the display of available nitro.
* \param kart The kart for which to show the data.
* \param viewport The viewport to use.
* \param scaling Which scaling to apply to the speedometer.
* \param dt Time step size.
*/
void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
void RaceGUI::drawSpeedEnergy(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling,
float dt)
@ -916,13 +1092,10 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
meter_texture->getSize());
draw2DImage(meter_texture, meter_pos, meter_texture_coords, NULL,
NULL, true);
// TODO: temporary workaround, shouldn't have to use
// draw2DVertexPrimitiveList to render a simple rectangle
const float speed = kart->getSpeed();
drawRank(kart, offset, min_ratio, meter_width, meter_height, dt);
drawMiscInfo(kart, offset, min_ratio, meter_width, meter_height, dt);
if(speed <=0) return; // Nothing to do if speed is negative.
@ -1007,7 +1180,7 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
drawMeterTexture(m_speed_bar_icon->getTexture(), vertices, count);
#endif
} // drawSpeedEnergyRank
} // drawSpeedEnergy
void RaceGUI::drawMeterTexture(video::ITexture *meter_texture, video::S3DVertex vertices[], unsigned int count)
{

View File

@ -94,12 +94,15 @@ private:
/** Icon textures (stored as variables to not look up
their location on every frame) */
irr::video::ITexture *m_lap_flag;
irr::video::ITexture *m_rank_icon;
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;
irr::video::ITexture *m_danger[3];
irr::video::ITexture *m_projectile[3];
/** Animation state: none, getting smaller (old value),
* getting bigger (new number). */
@ -118,13 +121,16 @@ private:
void drawEnergyMeter (int x, int y, const AbstractKart *kart,
const core::recti &viewport,
const core::vector2df &scaling);
void drawSpeedEnergyRank (const AbstractKart* kart,
void drawSpeedEnergy (const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling, float dt);
void drawLap (const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling);
void drawRank (const AbstractKart *kart,
const core::recti &viewport,
const core::vector2df &scaling, float dt);
void drawMiscInfo (const AbstractKart *kart,
const core::vector2df &offset,
float min_ratio, int meter_width,
int meter_height, float dt);

View File

@ -1139,3 +1139,4 @@ void RaceGUIBase::removeReferee()
}
} // removeReferee