Make STK soccer mode more like real match

1. Short win animation is shown in a kart if it scored correctly

2. Possible to identify own goal in result gui

Also player name is shown instead of kart name in result gui for all modes.
This commit is contained in:
Benau 2016-01-19 16:21:58 +08:00
parent 7831ef5ef5
commit 3a3963bf8d
5 changed files with 153 additions and 38 deletions

View File

@ -932,7 +932,7 @@ void Kart::setRaceResult()
else
Log::warn("Kart", "Unknown game mode given.");
} // setKartResult
} // setRaceResult
//-----------------------------------------------------------------------------
/** Called when an item is collected. It will either adjust the collected

View File

@ -73,8 +73,8 @@ void SoccerWorld::init()
m_kart_team_map.clear();
WorldWithRank::init();
m_display_rank = false;
m_goal_timer = 0.f;
m_last_kart_to_hit_ball = -1;
m_goal_timer = 0.0f;
m_ball_hitter = -1;
m_goal_target = race_manager->getMaxGoal();
m_goal_sound = SFXManager::get()->createSoundSource("goal_scored");
@ -93,6 +93,8 @@ void SoccerWorld::reset()
}
else WorldStatus::setClockMode(CLOCK_CHRONO);
m_animation_timer = 0.0f;
m_animation_showing_kart = -1;
m_can_score_points = true;
m_red_goal = 0;
m_blue_goal = 0;
@ -104,7 +106,7 @@ void SoccerWorld::reset()
m_red_score_times.clear();
m_blue_scorers.clear();
m_blue_score_times.clear();
m_last_kart_to_hit_ball = -1;
m_ball_hitter = -1;
PtrVector<TrackObject>& objects = tom->getObjects();
for(unsigned int i=0; i<objects.size(); i++)
{
@ -158,7 +160,19 @@ void SoccerWorld::update(float dt)
if (m_goal_timer > 3.0f)
{
world->setPhase(WorldStatus::RACE_PHASE);
m_goal_timer = 0;
m_goal_timer = 0.0f;
}
}
if (!(isRaceOver() || isStartPhase()) && m_animation_showing_kart != -1)
{
m_animation_timer += dt;
if (m_animation_timer > 6.0f)
{
m_karts[m_animation_showing_kart]
->getKartModel()->setAnimation(KartModel::AF_BEGIN);
m_animation_timer = 0.0f;
m_animation_showing_kart = -1;
}
}
} // update
@ -176,23 +190,40 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal)
World *world = World::getWorld();
world->setPhase(WorldStatus::GOAL_PHASE);
m_goal_sound->play();
if(m_last_kart_to_hit_ball != -1)
if (m_ball_hitter != -1)
{
if(first_goal)
m_animation_showing_kart = m_ball_hitter;
ScorerData sd;
sd.m_id = m_ball_hitter;
sd.m_correct_goal = isCorrectGoal(m_ball_hitter, first_goal);
if (sd.m_correct_goal)
{
m_karts[m_ball_hitter]->getKartModel()
->setAnimation(KartModel::AF_WIN_START);
}
if (first_goal)
{
// Notice: true first_goal means it's blue goal being shoot,
// so red team can score
m_red_scorers.push_back(m_last_kart_to_hit_ball);
m_red_scorers.push_back(sd);
if(race_manager->hasTimeTarget())
m_red_score_times.push_back(race_manager->getTimeTarget() - world->getTime());
{
m_red_score_times.push_back(race_manager
->getTimeTarget() - world->getTime());
}
else
m_red_score_times.push_back(world->getTime());
}
else
{
m_blue_scorers.push_back(m_last_kart_to_hit_ball);
if(race_manager->hasTimeTarget())
m_blue_score_times.push_back(race_manager->getTimeTarget() - world->getTime());
m_blue_scorers.push_back(sd);
if (race_manager->hasTimeTarget())
{
m_blue_score_times.push_back(race_manager
->getTimeTarget() - world->getTime());
}
else
m_blue_score_times.push_back(world->getTime());
}
@ -222,12 +253,12 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal)
//-----------------------------------------------------------------------------
/** Sets the last kart that hit the ball, to be able to
* identify the scorer later.
*/
void SoccerWorld::setLastKartTohitBall(unsigned int kart_id)
* identify the scorer later.
*/
void SoccerWorld::setBallHitter(unsigned int kart_id)
{
m_last_kart_to_hit_ball = kart_id;
} // setLastKartTohitBall
m_ball_hitter = kart_id;
} // setBallHitter
//-----------------------------------------------------------------------------
/** The soccer game is over if time up or either team wins.
@ -261,7 +292,7 @@ void SoccerWorld::terminateRace()
//-----------------------------------------------------------------------------
/** Called when the match time ends.
*/
*/
void SoccerWorld::countdownReachedZero()
{
m_count_down_reached_zero = true;
@ -495,3 +526,20 @@ SoccerTeam SoccerWorld::getKartTeam(unsigned int kart_id) const
return SOCCER_TEAM_BLUE;
} // getKartTeam
//-----------------------------------------------------------------------------
bool SoccerWorld::isCorrectGoal(unsigned int kart_id, bool first_goal) const
{
SoccerTeam team = getKartTeam(kart_id);
if (first_goal)
{
if (team == SOCCER_TEAM_RED)
return true;
}
else if (!first_goal)
{
if (team == SOCCER_TEAM_BLUE)
return true;
}
return false;
} // isCorrectGoal

View File

@ -36,6 +36,16 @@ class Controller;
*/
class SoccerWorld : public WorldWithRank
{
public:
class ScorerData
{
public:
/** World ID of kart which scores. */
unsigned int m_id;
/** Whether this goal is socred correctly (identify for own goal). */
bool m_correct_goal;
}; // ScorerData
protected:
virtual AbstractKart *createKart(const std::string &kart_ident, int index,
int local_player_id, int global_player_id,
@ -54,14 +64,18 @@ private:
/** Timer for displaying goal text*/
float m_goal_timer;
int m_last_kart_to_hit_ball;
int m_ball_hitter;
/** Timer for win/lose animation showing after each goal*/
float m_animation_timer;
int m_animation_showing_kart;
/** Goals data of each team scored */
int m_red_goal;
int m_blue_goal;
std::vector<int> m_red_scorers;
std::vector<ScorerData> m_red_scorers;
std::vector<float> m_red_score_times;
std::vector<int> m_blue_scorers;
std::vector<ScorerData> m_blue_scorers;
std::vector<float> m_blue_score_times;
std::map<int, SoccerTeam> m_kart_team_map;
@ -110,7 +124,7 @@ public:
// ------------------------------------------------------------------------
void onCheckGoalTriggered(bool first_goal);
// ------------------------------------------------------------------------
void setLastKartTohitBall(unsigned int kart_id);
void setBallHitter(unsigned int kart_id);
// ------------------------------------------------------------------------
/** Get the soccer result of kart in soccer world (including AIs) */
bool getKartSoccerResult(unsigned int kart_id) const;
@ -121,7 +135,7 @@ public:
const int getScore(SoccerTeam team) const
{ return (team == SOCCER_TEAM_BLUE ? m_blue_goal : m_red_goal); }
// ------------------------------------------------------------------------
const std::vector<int>& getScorers(SoccerTeam team) const
const std::vector<ScorerData>& getScorers(SoccerTeam team) const
{ return (team == SOCCER_TEAM_BLUE ? m_blue_scorers : m_red_scorers); }
// ------------------------------------------------------------------------
const std::vector<float>& getScoreTimes(SoccerTeam team) const
@ -143,6 +157,8 @@ public:
{
return (team == SOCCER_TEAM_BLUE ? m_blue_goal_node : m_red_goal_node);
}
// ------------------------------------------------------------------------
bool isCorrectGoal(unsigned int kart_id, bool first_goal) const;
}; // SoccerWorld

View File

@ -226,7 +226,7 @@ void Physics::update(float dt)
race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
{
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
soccerWorld->setLastKartTohitBall(kartId);
soccerWorld->setBallHitter(kartId);
}
continue;
}
@ -288,7 +288,7 @@ void Physics::update(float dt)
{
int kartId = p->getUserPointer(0)->getPointerFlyable()->getOwnerId();
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
soccerWorld->setLastKartTohitBall(kartId);
soccerWorld->setBallHitter(kartId);
}
}

View File

@ -475,7 +475,16 @@ void RaceResultGUI::determineTableLayout()
// Save a pointer to the current row_info entry
RowInfo *ri = &(m_all_row_infos[position-first_position]);
ri->m_is_player_kart = kart->getController()->isLocalPlayerController();
ri->m_kart_name = translations->fribidize(kart->getName());
// Identify Human player, if so display real name other than kart name
const int rm_id = kart->getWorldKartId() -
(race_manager->getNumberOfKarts() - race_manager->getNumPlayers());
if (rm_id >= 0)
ri->m_kart_name = race_manager->getKartInfo(rm_id).getPlayerName();
else
ri->m_kart_name = translations->fribidize(kart->getName());
ri->m_player = ri->m_is_player_kart
? kart->getController()->getPlayer() : NULL;
@ -842,7 +851,15 @@ void RaceResultGUI::determineGPLayout()
RowInfo *ri = &(m_all_row_infos[rank]);
ri->m_kart_icon =
kart->getKartProperties()->getIconMaterial()->getTexture();
ri->m_kart_name = translations->fribidize(kart->getName());
const int rm_id = kart_id -
(race_manager->getNumberOfKarts() - race_manager->getNumPlayers());
if (rm_id >= 0)
ri->m_kart_name = race_manager->getKartInfo(rm_id).getPlayerName();
else
ri->m_kart_name = translations->fribidize(kart->getName());
ri->m_is_player_kart = kart->getController()->isLocalPlayerController();
ri->m_player = ri->m_is_player_kart
? kart->getController()->getPlayer() : NULL;
@ -1052,16 +1069,32 @@ void RaceResultGUI::displaySoccerResults()
//The red scorers:
current_y += rect.Height/2 + rect.Height/4;
font = GUIEngine::getSmallFont();
std::vector<int> scorers = sw->getScorers(SOCCER_TEAM_RED);
std::vector<SoccerWorld::ScorerData> scorers = sw->getScorers(SOCCER_TEAM_RED);
std::vector<float> score_times = sw->getScoreTimes(SOCCER_TEAM_RED);
irr::video::ITexture* scorer_icon;
int prev_y = current_y;
for(unsigned int i=0; i<scorers.size(); i++)
{
result_text = sw->getKart(scorers.at(i))->
getKartProperties()->getName();
result_text.append(" ");
const bool own_goal = !(scorers.at(i).m_correct_goal);
const int kart_id = scorers.at(i).m_id;
const int rm_id = kart_id -
(race_manager->getNumberOfKarts() - race_manager->getNumPlayers());
if (rm_id >= 0)
result_text = race_manager->getKartInfo(rm_id).getPlayerName();
else
result_text = sw->getKart(kart_id)->
getKartProperties()->getName();
if (own_goal)
{
result_text.append(" ");
result_text.append( _("(Own Goal)") );
}
result_text.append(" ");
result_text.append(StringUtils::timeToString(score_times.at(i)).c_str());
rect = m_font->getDimension(result_text.c_str());
@ -1073,8 +1106,9 @@ void RaceResultGUI::displaySoccerResults()
if(current_y > height) break;
pos = core::rect<s32>(current_x,current_y,current_x,current_y);
font->draw(result_text,pos, color, true, false);
scorer_icon = sw->getKart(scorers.at(i))
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 = GUIEngine::getFont()->getDimension(result_text.c_str()).Width/2;
@ -1090,9 +1124,25 @@ void RaceResultGUI::displaySoccerResults()
score_times = sw->getScoreTimes(SOCCER_TEAM_BLUE);
for(unsigned int i=0; i<scorers.size(); i++)
{
result_text = sw->getKart(scorers.at(i))->
getKartProperties()->getName();
result_text.append(" ");
const bool own_goal = !(scorers.at(i).m_correct_goal);
const int kart_id = scorers.at(i).m_id;
const int rm_id = kart_id -
(race_manager->getNumberOfKarts() - race_manager->getNumPlayers());
if (rm_id >= 0)
result_text = race_manager->getKartInfo(rm_id).getPlayerName();
else
result_text = sw->getKart(kart_id)->
getKartProperties()->getName();
if (own_goal)
{
result_text.append(" ");
result_text.append( _("(Own Goal)") );
}
result_text.append(" ");
result_text.append(StringUtils::timeToString(score_times.at(i)).c_str());
rect = m_font->getDimension(result_text.c_str());
@ -1104,8 +1154,9 @@ void RaceResultGUI::displaySoccerResults()
if(current_y > height) break;
pos = core::rect<s32>(current_x,current_y,current_x,current_y);
font->draw(result_text,pos, color, true, false);
scorer_icon = sw->getKart(scorers.at(i))->
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 = GUIEngine::getFont()->getDimension(result_text.c_str()).Width/2;