Skip to content

Commit

Permalink
Let speedometer show score in battles & Delete the 10 player limit in…
Browse files Browse the repository at this point in the history
… arenas (#5193)

* Let speedometer show score in battles (Fix #5084 & #3832)

* Use red-green fade for ffa

* Fix networking bugs
  • Loading branch information
CodingJellyfish authored Oct 28, 2024
1 parent e079089 commit a90c9e8
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 37 deletions.
40 changes: 40 additions & 0 deletions src/modes/free_for_all.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,46 @@ void FreeForAll::getKartsDisplayInfo(
}
} // getKartsDisplayInfo

//-----------------------------------------------------------------------------
std::pair<int, video::SColor> FreeForAll::getSpeedometerDigit(
const AbstractKart *kart) const
{
if (kart->isEliminated()) // m_scores[id] is INT_MIN
{
return std::make_pair(0, video::SColor(255, 128, 128, 128));
}

int id = kart->getWorldKartId();

// Fade from green to red
std::vector<int> sorted_scores;
for (int i = 0; i < m_scores.size(); i++)
{
if (!getKart(i)->isEliminated())
{
sorted_scores.push_back(m_scores[i]);
}
}
std::sort(sorted_scores.begin(), sorted_scores.end(), std::greater<int>());

if (sorted_scores.size() == 1)
{
int s = sorted_scores[id];
video::SColor color = video::SColor(255, s <= 0 ? 255 : 0, s >= 0 ? 255 : 0, 0);
return std::make_pair(s, color);
}

int rank = std::lower_bound(
sorted_scores.begin(), sorted_scores.end(),
m_scores[id], std::greater<int>()) - sorted_scores.begin();

float value = (float)rank / (sorted_scores.size() - 1);
int r = std::min(int(value * 510), 255);
int g = std::min(int((1.0 - value) * 510), 255);

return std::make_pair(m_scores[id], video::SColor(255, r, g, 0));
} // getSpeedometerDigit

// ----------------------------------------------------------------------------
void FreeForAll::terminateRace()
{
Expand Down
5 changes: 5 additions & 0 deletions src/modes/free_for_all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class FreeForAll : public WorldWithRank
// ------------------------------------------------------------------------
virtual bool raceHasLaps() OVERRIDE { return false; }
// ------------------------------------------------------------------------
virtual bool shouldDrawSpeedometerDigit() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual std::pair<int, video::SColor>
getSpeedometerDigit(const AbstractKart *kart) const OVERRIDE;
// ------------------------------------------------------------------------
virtual const std::string& getIdent() const OVERRIDE;
// ------------------------------------------------------------------------
virtual bool kartHit(int kart_id, int hitter = -1) OVERRIDE;
Expand Down
24 changes: 24 additions & 0 deletions src/modes/three_strikes_battle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,30 @@ void ThreeStrikesBattle::getKartsDisplayInfo(
}
} // getKartsDisplayInfo

//-----------------------------------------------------------------------------
std::pair<int, video::SColor> ThreeStrikesBattle::getSpeedometerDigit(
const AbstractKart *kart) const
{
video::SColor color = video::SColor(255, 255, 255, 255);
int id = kart->getWorldKartId();
switch(m_kart_info[id].m_lives)
{
case 3:
color = video::SColor(255, 0, 255, 0);
break;
case 2:
color = video::SColor(255, 255, 229, 0);
break;
case 1:
color = video::SColor(255, 255, 0, 0);
break;
case 0:
color = video::SColor(255, 128, 128, 128);
break;
}
return std::make_pair(m_kart_info[id].m_lives, color);
} // getSpeedometerDigit

//-----------------------------------------------------------------------------
void ThreeStrikesBattle::enterRaceOverState()
{
Expand Down
5 changes: 5 additions & 0 deletions src/modes/three_strikes_battle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class ThreeStrikesBattle : public WorldWithRank
// ------------------------------------------------------------------------
virtual bool raceHasLaps() OVERRIDE { return false; }
// ------------------------------------------------------------------------
virtual bool shouldDrawSpeedometerDigit() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual std::pair<int, video::SColor>
getSpeedometerDigit(const AbstractKart *kart) const OVERRIDE;
// ------------------------------------------------------------------------
virtual const std::string& getIdent() const OVERRIDE;
// ------------------------------------------------------------------------
virtual bool kartHit(int kart_id, int hitter = -1) OVERRIDE;
Expand Down
7 changes: 7 additions & 0 deletions src/modes/world.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,13 @@ class World : public WorldStatus
virtual bool shouldDrawTimer() const
{ return isActiveRacePhase() && getClockMode() != CLOCK_NONE; }
// ------------------------------------------------------------------------
/** \return whether this world should draw the digit on the center of speedometer */
virtual bool shouldDrawSpeedometerDigit() const { return false; }
// ------------------------------------------------------------------------
/** \return a pair consists of the digit and the color of the digit */
virtual std::pair<int, video::SColor> getSpeedometerDigit(const AbstractKart *kart) const
{ return std::make_pair(0, video::SColor(255, 255, 255, 255)); }
// ------------------------------------------------------------------------
/** \return whether this world can generate/have highscores */
bool useHighScores() const { return m_use_highscores; }
// ------------------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions src/modes/world_with_rank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ AbstractKart* WorldWithRank::getKartAtPosition(unsigned int p) const
return m_karts[m_position_index[p-1]].get();
} // getKartAtPosition

//-----------------------------------------------------------------------------
std::pair<int, video::SColor> WorldWithRank::getSpeedometerDigit(const AbstractKart *kart) const
{
return std::make_pair(kart->getPosition(), video::SColor(255, 255, 255, 255));
} // getSpeedometerDigit

//-----------------------------------------------------------------------------
/** This function must be called before starting to set all kart positions
* again. It's mainly used to add some debug support, i.e. detect if the
Expand Down
5 changes: 4 additions & 1 deletion src/modes/world_with_rank.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ class WorldWithRank : public World
virtual void init() OVERRIDE;
virtual void reset(bool restart=false) OVERRIDE;

bool displayRank() const { return m_display_rank; }
virtual bool shouldDrawSpeedometerDigit() const OVERRIDE
{ return m_display_rank; }
virtual std::pair<int, video::SColor>
getSpeedometerDigit(const AbstractKart *kart) const OVERRIDE;

void beginSetKartPositions();
bool setKartPosition(unsigned int kart_id,
Expand Down
60 changes: 33 additions & 27 deletions src/states_screens/race_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,10 @@ RaceGUI::~RaceGUI()
void RaceGUI::init()
{
RaceGUIBase::init();
// Technically we only need getNumLocalPlayers, but using the
// global kart id to find the data for a specific kart.
int n = RaceManager::get()->getNumberOfKarts();

m_animation_states.resize(n);
m_rank_animation_duration.resize(n);
m_last_ranks.resize(n);
m_animation_states.clear();
m_animation_duration.clear();
m_last_digit.clear();
} // init

//-----------------------------------------------------------------------------
Expand All @@ -164,11 +161,10 @@ void RaceGUI::init()
void RaceGUI::reset()
{
RaceGUIBase::reset();
for(unsigned int i=0; i<RaceManager::get()->getNumberOfKarts(); i++)
{
m_animation_states[i] = AS_NONE;
m_last_ranks[i] = i+1;
}

m_animation_states.clear();
m_animation_duration.clear();
m_last_digit.clear();
} // reset

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -908,49 +904,59 @@ void RaceGUI::drawRank(const AbstractKart *kart,
float min_ratio, int meter_width,
int meter_height, float dt)
{
static video::SColor color = video::SColor(255, 255, 255, 255);

// Draw rank
WorldWithRank *world = dynamic_cast<WorldWithRank*>(World::getWorld());
if (!world || !world->displayRank())
World *world = World::getWorld();
if (!world || !world->shouldDrawSpeedometerDigit())
return;

std::pair<int, video::SColor> digit_data = world->getSpeedometerDigit(kart);

int number = digit_data.first;
video::SColor color = digit_data.second;

int id = kart->getWorldKartId();

if (m_animation_states.find(id) == m_animation_states.end())
{
m_animation_duration[id] = 0.0f;
m_animation_states[id] = AS_NONE;
m_last_digit[id] = number;
}

if (m_animation_states[id] == AS_NONE)
{
if (m_last_ranks[id] != kart->getPosition())
if (m_last_digit[id] != number)
{
m_rank_animation_duration[id] = 0.0f;
m_animation_duration[id] = 0.0f;
m_animation_states[id] = AS_SMALLER;
}
}
else
{
m_rank_animation_duration[id] += dt;
m_animation_duration[id] += dt;
}

float scale = 1.0f;
int rank = kart->getPosition();
int shown_number = number;
const float DURATION = 0.4f;
const float MIN_SHRINK = 0.3f;
if (m_animation_states[id] == AS_SMALLER)
{
scale = 1.0f - m_rank_animation_duration[id]/ DURATION;
rank = m_last_ranks[id];
scale = 1.0f - m_animation_duration[id]/ DURATION;
shown_number = m_last_digit[id];
if (scale < MIN_SHRINK)
{
m_animation_states[id] = AS_BIGGER;
m_rank_animation_duration[id] = 0.0f;
m_animation_duration[id] = 0.0f;
// Store the new rank
m_last_ranks[id] = kart->getPosition();
m_last_digit[id] = number;
scale = MIN_SHRINK;
}
}
else if (m_animation_states[id] == AS_BIGGER)
{
scale = m_rank_animation_duration[id] / DURATION + MIN_SHRINK;
rank = m_last_ranks[id];
scale = m_animation_duration[id] / DURATION + MIN_SHRINK;
shown_number = m_last_digit[id];
if (scale > 1.0f)
{
m_animation_states[id] = AS_NONE;
Expand All @@ -960,15 +966,15 @@ void RaceGUI::drawRank(const AbstractKart *kart,
}
else
{
m_last_ranks[id] = kart->getPosition();
m_last_digit[id] = number;
}

gui::ScalableFont* font = GUIEngine::getHighresDigitFont();

int font_height = font->getDimension(L"X").Height;
font->setScale((float)meter_height / font_height * 0.4f * scale);
std::ostringstream oss;
oss << rank; // the current font has no . :( << ".";
oss << shown_number; // the current font has no . :( << ".";

core::recti pos;
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
Expand Down
11 changes: 6 additions & 5 deletions src/states_screens/race_gui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef HEADER_RACE_GUI_HPP
#define HEADER_RACE_GUI_HPP

#include <map>
#include <string>
#include <vector>

Expand Down Expand Up @@ -107,13 +108,13 @@ class RaceGUI : public RaceGUIBase
/** Animation state: none, getting smaller (old value),
* getting bigger (new number). */
enum AnimationState {AS_NONE, AS_SMALLER, AS_BIGGER};
std::vector<AnimationState> m_animation_states;
std::map<int, AnimationState> m_animation_states;

/** How long the rank animation has been shown. */
std::vector<float> m_rank_animation_duration;
/** How long the speedometer digit animation has been shown for this number. */
std::map<int, float> m_animation_duration;

/** Stores the previous rank for each kart. Used for the rank animation. */
std::vector<int> m_last_ranks;
/** Stores the previous digit on the center of the speedometer for each number. */
std::map<int, int> m_last_digit;

bool m_is_tutorial;

Expand Down
4 changes: 0 additions & 4 deletions src/tracks/track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,10 +657,6 @@ void Track::loadTrackInfo()
// Currently only max eight players in soccer mode
m_max_arena_players = 8;
}
// Max 10 players supported in arena
if (m_max_arena_players > 10)
m_max_arena_players = 10;

} // loadTrackInfo

//-----------------------------------------------------------------------------
Expand Down

0 comments on commit a90c9e8

Please sign in to comment.