Add the required GUI code for CTF

This commit is contained in:
Benau 2018-08-17 12:54:38 +08:00
parent acce57cf31
commit 9905ebe09d
9 changed files with 355 additions and 45 deletions

View File

@ -1034,6 +1034,11 @@ void Kart::setRaceResult()
FreeForAll* ffa = dynamic_cast<FreeForAll*>(World::getWorld());
m_race_result = ffa->getKartAtPosition(1) == this;
}
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
{
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
m_race_result = ctf->getKartCTFResult(getWorldKartId());
}
else if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
{
SoccerWorld* sw = dynamic_cast<SoccerWorld*>(World::getWorld());

View File

@ -60,8 +60,6 @@ CaptureTheFlag::~CaptureTheFlag()
void CaptureTheFlag::init()
{
FreeForAll::init();
const btTransform& red_pos = Track::getCurrentTrack()->getRedFlag();
const btTransform& blue_pos = Track::getCurrentTrack()->getBlueFlag();
#ifndef SERVER_ONLY
m_red_flag_node = irr_driver->addAnimatedMesh(m_red_flag_mesh, "red_flag");
@ -69,14 +67,51 @@ void CaptureTheFlag::init()
"blue_flag");
assert(m_red_flag_node);
assert(m_blue_flag_node);
m_red_flag_node->setPosition(Vec3(red_pos.getOrigin()).toIrrVector());
Vec3 hpr;
hpr.setHPR(red_pos.getRotation());
m_red_flag_node->setRotation(hpr.toIrrHPR());
m_blue_flag_node->setPosition(Vec3(blue_pos.getOrigin()).toIrrVector());
hpr.setHPR(blue_pos.getRotation());
m_blue_flag_node->setRotation(hpr.toIrrHPR());
#endif
} // init
//-----------------------------------------------------------------------------
void CaptureTheFlag::reset()
{
FreeForAll::reset();
m_red_trans = Track::getCurrentTrack()->getRedFlag();
m_blue_trans = Track::getCurrentTrack()->getBlueFlag();
m_red_scores = m_blue_scores = 0;
m_red_holder = m_blue_holder = -1;
#ifndef SERVER_ONLY
m_red_flag_node->setPosition(
Vec3(m_red_trans.getOrigin()).toIrrVector());
Vec3 hpr;
hpr.setHPR(m_red_trans.getRotation());
m_red_flag_node->setRotation(hpr.toIrrHPR());
m_blue_flag_node->setPosition(
Vec3(m_blue_trans.getOrigin()).toIrrVector());
hpr.setHPR(m_blue_trans.getRotation());
m_blue_flag_node->setRotation(hpr.toIrrHPR());
#endif
} // reset
//-----------------------------------------------------------------------------
void CaptureTheFlag::update(int ticks)
{
FreeForAll::update(ticks);
} // update
// ----------------------------------------------------------------------------
video::SColor CaptureTheFlag::getColor(unsigned int kart_id) const
{
return getKartTeam(kart_id) == KART_TEAM_RED ?
video::SColor(255, 255, 0, 0) : video::SColor(255, 0, 0, 255);
} // getColor
// ----------------------------------------------------------------------------
bool CaptureTheFlag::isRaceOver()
{
if (NetworkConfig::get()->isServer() &&
(m_red_scores >= race_manager->getHitCaptureLimit() ||
m_blue_scores >= race_manager->getHitCaptureLimit()))
return true;
return FreeForAll::isRaceOver();
} // isRaceOver

View File

@ -42,6 +42,13 @@ private:
irr::scene::IAnimatedMesh* m_blue_flag_mesh;
int m_red_scores, m_blue_scores, m_red_holder, m_blue_holder;
btTransform m_red_trans, m_blue_trans;
// ------------------------------------------------------------------------
virtual video::SColor getColor(unsigned int kart_id) const OVERRIDE;
public:
// ------------------------------------------------------------------------
CaptureTheFlag();
@ -50,8 +57,40 @@ public:
// ------------------------------------------------------------------------
virtual void init() OVERRIDE;
// ------------------------------------------------------------------------
virtual void reset() OVERRIDE;
// ------------------------------------------------------------------------
virtual void update(int ticks) OVERRIDE;
// ------------------------------------------------------------------------
virtual bool hasTeam() const OVERRIDE { return true; }
// ------------------------------------------------------------------------
bool getKartCTFResult(unsigned int kart_id) const
{
if (m_red_scores == m_blue_scores)
return true;
bool red_win = m_red_scores > m_blue_scores;
KartTeam team = getKartTeam(kart_id);
if ((red_win && team == KART_TEAM_RED) ||
(!red_win && team == KART_TEAM_BLUE))
return true;
else
return false;
}
// ------------------------------------------------------------------------
int getRedScore() const { return m_red_scores; }
// ------------------------------------------------------------------------
int getBlueScore() const { return m_blue_scores; }
// ------------------------------------------------------------------------
int getRedHolder() const { return m_red_holder; }
// ------------------------------------------------------------------------
int getBlueHolder() const { return m_blue_holder; }
// ------------------------------------------------------------------------
const Vec3& getRedFlag() const { return (Vec3&)m_red_trans.getOrigin(); }
// ------------------------------------------------------------------------
const Vec3& getBlueFlag() const { return (Vec3&)m_blue_trans.getOrigin(); }
// ------------------------------------------------------------------------
virtual bool isRaceOver() OVERRIDE;
}; // CaptureTheFlag

View File

@ -172,6 +172,7 @@ void FreeForAll::getKartsDisplayInfo(
RaceGUIBase::KartIconDisplayInfo& rank_info = (*info)[i];
rank_info.lap = -1;
rank_info.m_outlined_font = true;
rank_info.m_color = getColor(i);
rank_info.m_text = m_karts[i]->getController()->getName() + L" (" +
StringUtils::toWString(m_scores[i]) + L")";
}
@ -187,3 +188,9 @@ void FreeForAll::terminateRace()
} // i<kart_amount
WorldWithRank::terminateRace();
} // terminateRace
// ----------------------------------------------------------------------------
video::SColor FreeForAll::getColor(unsigned int kart_id) const
{
return GUIEngine::getSkin()->getColor("font::normal");
} // getColor

View File

@ -31,6 +31,10 @@ private:
bool m_count_down_reached_zero;
std::vector<int> m_scores;
// ------------------------------------------------------------------------
virtual video::SColor getColor(unsigned int kart_id) const;
public:
// ------------------------------------------------------------------------
FreeForAll();
@ -61,7 +65,6 @@ public:
void setKartScoreFromServer(NetworkString& ns);
// ------------------------------------------------------------------------
int getKartScore(int kart_id) const { return m_scores.at(kart_id); }
}; // FreeForAll

View File

@ -38,14 +38,13 @@ using namespace irr;
#include "guiengine/modaldialog.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "items/attachment.hpp"
#include "items/attachment_manager.hpp"
#include "items/powerup_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp"
#include "karts/controller/spare_tire_ai.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "modes/capture_the_flag.hpp"
#include "modes/follow_the_leader.hpp"
#include "modes/linear_world.hpp"
#include "modes/world.hpp"
@ -266,7 +265,8 @@ void RaceGUI::renderGlobal(float dt)
}
if (!m_is_tutorial) drawGlobalPlayerIcons(m_map_height);
if(Track::getCurrentTrack()->isSoccer()) drawScores();
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
drawScores();
#endif
} // renderGlobal
@ -514,6 +514,35 @@ void RaceGUI::drawGlobalMiniMap()
track->drawMiniMap(dest);
World *world = World::getWorld();
CaptureTheFlag *ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
if (ctf)
{
Vec3 draw_at;
track->mapPoint2MiniMap(ctf->getRedFlag(), &draw_at);
video::ITexture* icon =
irr_driver->getTexture(FileManager::GUI, "red_flag.png");
core::rect<s32> rs(core::position2di(0, 0), icon->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);
track->mapPoint2MiniMap(ctf->getBlueFlag(), &draw_at);
icon = irr_driver->getTexture(FileManager::GUI, "blue_flag.png");
core::rect<s32> bs(core::position2di(0, 0), icon->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);
}
for(unsigned int i=0; i<world->getNumKarts(); i++)
{
const AbstractKart *kart = world->getKart(i);
@ -1066,11 +1095,6 @@ void RaceGUI::drawLap(const AbstractKart* kart,
if (kart->hasFinishedRace()) return;
World *world = World::getWorld();
if (!world->raceHasLaps()) return;
const int lap = world->getFinishedLapsOfKart(kart->getWorldKartId());
// don't display 'lap 0/..' at the start of a race
if (lap < 0 ) return;
core::recti pos;
@ -1090,6 +1114,32 @@ void RaceGUI::drawLap(const AbstractKart* kart,
- m_lap_width - 10;
pos.LowerRightCorner.X = viewport.LowerRightCorner.X;
// Draw CTF scores with red score - blue score
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
if (ctf)
{
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
font->setScale(scaling.Y < 1.0f ? 0.5f: 1.0f);
core::stringw text = StringUtils::toWString(ctf->getRedScore());
font->draw(text, pos, video::SColor(255, 255, 0, 0));
core::dimension2du d = font->getDimension(text.c_str());
pos += core::position2di(d.Width, 0);
text = L"-";
font->draw(text, pos, video::SColor(255, 255, 255, 255));
d = font->getDimension(text.c_str());
pos += core::position2di(d.Width, 0);
text = StringUtils::toWString(ctf->getBlueScore());
font->draw(text, pos, video::SColor(255, 0, 0, 255));
font->setScale(1.0f);
return;
}
if (!world->raceHasLaps()) return;
const int lap = world->getFinishedLapsOfKart(kart->getWorldKartId());
// don't display 'lap 0/..' at the start of a race
if (lap < 0 ) return;
static video::SColor color = video::SColor(255, 255, 255, 255);
std::ostringstream out;
out << lap + 1 << "/" << race_manager->getNumLaps();

View File

@ -40,6 +40,7 @@
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "karts/rescue_animation.hpp"
#include "modes/capture_the_flag.hpp"
#include "modes/linear_world.hpp"
#include "modes/world.hpp"
#include "states_screens/race_gui_multitouch.hpp"
@ -722,7 +723,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
// Icon width for the AI karts
int ICON_WIDTH = ICON_PLAYER_WIDTH * 4 / 5;
WorldWithRank *world = (WorldWithRank*)(World::getWorld());
WorldWithRank* world = dynamic_cast<WorldWithRank*>(World::getWorld());
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
//initialize m_previous_icons_position
if(m_previous_icons_position.size()==0)
@ -852,8 +854,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
if (info.m_outlined_font)
{
GUIEngine::getOutlineFont()->draw(info.m_text, pos,
GUIEngine::getSkin()->getColor("font::normal"), false,
false, NULL, true/*ignore RTL*/);
info.m_color, false, false, NULL, true/*ignore RTL*/);
}
else
{
@ -877,6 +878,32 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
int w = kart->getController()
->isLocalPlayerController() ? ICON_PLAYER_WIDTH
: ICON_WIDTH;
// CTF
if (ctf)
{
if (ctf->getRedHolder() == (int)kart_id)
{
video::ITexture* red =
irr_driver->getTexture(FileManager::GUI, "red_flag.png");
const core::rect<s32> rect(core::position2d<s32>(0, 0),
red->getSize());
const core::rect<s32> pos1
(x - 20, y - 10, x + w - 20, y + w - 30);
draw2DImage(red, pos1, rect, NULL, NULL, true);
}
else if (ctf->getBlueHolder() == (int)kart_id)
{
video::ITexture* blue =
irr_driver->getTexture(FileManager::GUI, "blue_flag.png");
const core::rect<s32> rect(core::position2d<s32>(0, 0),
blue->getSize());
const core::rect<s32> pos1
(x - 20, y - 10, x + w - 20, y + w - 30);
draw2DImage(blue, pos1, rect, NULL, NULL, true);
}
}
const core::rect<s32> pos(x, y, x+w, y+w);
//to bring to light the player's icon: add a background

View File

@ -42,7 +42,7 @@
#include "karts/kart_properties_manager.hpp"
#include "modes/cutscene_world.hpp"
#include "modes/demo_world.hpp"
#include "modes/free_for_all.hpp"
#include "modes/capture_the_flag.hpp"
#include "modes/overworld.hpp"
#include "modes/soccer_world.hpp"
#include "network/network_config.hpp"
@ -474,6 +474,158 @@ void RaceResultGUI::backToLobby()
NetworkingLobby::getInstance()->addMoreServerInfo(L"--------------------");
} // backToLobby
//-----------------------------------------------------------------------------
void RaceResultGUI::displayCTFResults()
{
#ifndef SERVER_ONLY
//Draw win text
core::stringw result_text;
video::SColor color = video::SColor(255, 255, 255, 255);
video::SColor red_color = video::SColor(255, 255, 0, 0);
gui::IGUIFont* font = GUIEngine::getTitleFont();
int current_x = UserConfigParams::m_width / 2;
RowInfo *ri = &(m_all_row_infos[0]);
int current_y = (int)ri->m_y_pos;
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>(World::getWorld());
const int red_score = ctf->getRedScore();
const int blue_score = ctf->getBlueScore();
GUIEngine::Widget *table_area = getWidget("result-table");
int height = table_area->m_h + table_area->m_y;
if (red_score > blue_score)
result_text = _("Red Team Wins");
else if (blue_score > red_score)
result_text = _("Blue Team Wins");
else
result_text = _("It's a draw");
core::rect<s32> pos(current_x, current_y, current_x, current_y);
font->draw(result_text.c_str(), pos, color, true, true);
core::dimension2du rect = font->getDimension(result_text.c_str());
//Draw team scores:
current_y += rect.Height;
current_x /= 2;
irr::video::ITexture* red_icon = irr_driver->getTexture(FileManager::GUI,
"red_flag.png");
irr::video::ITexture* blue_icon = irr_driver->getTexture(FileManager::GUI,
"blue_flag.png");
core::recti source_rect(core::vector2di(0, 0), red_icon->getSize());
core::recti dest_rect(current_x, current_y,
current_x + red_icon->getSize().Width / 2,
current_y + red_icon->getSize().Height / 2);
draw2DImage(red_icon, dest_rect, source_rect,
NULL, NULL, true);
current_x += UserConfigParams::m_width / 2 - red_icon->getSize().Width / 2;
dest_rect = core::recti(current_x, current_y,
current_x + red_icon->getSize().Width / 2,
current_y + red_icon->getSize().Height / 2);
draw2DImage(blue_icon, dest_rect, source_rect,
NULL, NULL, true);
result_text = StringUtils::toWString(blue_score);
rect = font->getDimension(result_text.c_str());
current_x += red_icon->getSize().Width / 4;
current_y += red_icon->getSize().Height / 2 + rect.Height / 4;
pos = core::rect<s32>(current_x, current_y, current_x, current_y);
font->draw(result_text.c_str(), pos, color, true, false);
current_x -= UserConfigParams::m_width / 2 - red_icon->getSize().Width / 2;
result_text = StringUtils::toWString(red_score);
pos = core::rect<s32>(current_x, current_y, current_x, current_y);
font->draw(result_text.c_str(), pos, color, true, false);
int center_x = UserConfigParams::m_width / 2;
pos = core::rect<s32>(center_x, current_y, center_x, current_y);
font->draw("-", pos, color, true, false);
// The red team player scores:
current_y += rect.Height / 2 + rect.Height / 4;
font = GUIEngine::getSmallFont();
irr::video::ITexture* kart_icon;
int prev_y = current_y;
const unsigned num_karts = ctf->getNumKarts();
for (unsigned int i = 0; i < num_karts; i++)
{
AbstractKart* kart = ctf->getKartAtPosition(i + 1);
unsigned kart_id = kart->getWorldKartId();
if (ctf->getKartTeam(kart_id) != KART_TEAM_RED)
continue;
result_text = kart->getController()->getName();
result_text.append(" ");
if (kart->isEliminated())
{
result_text.append(_("Eliminated"));
}
else
{
result_text.append(
StringUtils::toWString(ctf->getKartScore(kart_id)));
}
rect = font->getDimension(result_text.c_str());
current_y += rect.Height;
if (current_y > height) break;
pos = core::rect<s32>(current_x, current_y, current_x, current_y);
font->draw(result_text, pos,
kart->getController()->isLocalPlayerController() ?
red_color : color, true, false);
kart_icon = kart->getKartProperties()->getIconMaterial()->getTexture();
source_rect = core::recti(core::vector2di(0, 0), kart_icon->getSize());
irr::u32 offset_x =
(irr::u32)(font->getDimension(result_text.c_str()).Width / 1.5f);
dest_rect = core::recti(current_x - offset_x - 30, current_y,
current_x - offset_x, current_y + 30);
draw2DImage(kart_icon, dest_rect, source_rect, NULL, NULL, true);
}
// The blue team player scores:
current_y = prev_y;
current_x += UserConfigParams::m_width / 2 - red_icon->getSize().Width / 2;
for (unsigned int i = 0; i < num_karts; i++)
{
AbstractKart* kart = ctf->getKartAtPosition(i + 1);
unsigned kart_id = kart->getWorldKartId();
if (ctf->getKartTeam(kart_id) != KART_TEAM_BLUE)
continue;
result_text = kart->getController()->getName();
result_text.append(" ");
if (kart->isEliminated())
{
result_text.append(_("Eliminated"));
}
else
{
result_text.append(
StringUtils::toWString(ctf->getKartScore(kart_id)));
}
rect = font->getDimension(result_text.c_str());
current_y += rect.Height;
if (current_y > height) break;
pos = core::rect<s32>(current_x, current_y, current_x, current_y);
font->draw(result_text, pos,
kart->getController()->isLocalPlayerController() ?
red_color : color, true, false);
kart_icon = kart->getKartProperties()->getIconMaterial()->getTexture();
source_rect = core::recti(core::vector2di(0, 0), kart_icon->getSize());
irr::u32 offset_x = (irr::u32)
(font->getDimension(result_text.c_str()).Width / 1.5f);
dest_rect = core::recti(current_x - offset_x - 30, current_y,
current_x - offset_x, current_y + 30);
draw2DImage(kart_icon, dest_rect, source_rect, NULL, NULL, true);
}
#endif
}
//-----------------------------------------------------------------------------
void RaceResultGUI::onConfirm()
{
@ -714,8 +866,6 @@ void RaceResultGUI::backToLobby()
void RaceResultGUI::renderGlobal(float dt)
{
#ifndef SERVER_ONLY
bool isSoccerWorld = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
m_timer += dt;
assert(World::getWorld()->getPhase() == WorldStatus::RESULT_DISPLAY_PHASE);
unsigned int num_karts = (unsigned int)m_all_row_infos.size();
@ -821,7 +971,16 @@ void RaceResultGUI::backToLobby()
// Second phase: update X and Y positions for the various animations
// =================================================================
float v = 0.9f*UserConfigParams::m_width / m_time_single_scroll;
if (!isSoccerWorld)
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
{
displaySoccerResults();
}
else if (race_manager->getMajorMode() ==
RaceManager::MAJOR_MODE_CAPTURE_THE_FLAG)
{
displayCTFResults();
}
else
{
for (unsigned int i = 0; i < m_all_row_infos.size(); i++)
{
@ -876,8 +1035,6 @@ void RaceResultGUI::backToLobby()
displayOneEntry((unsigned int)x, (unsigned int)y, i, true);
} // for i
}
else
displaySoccerResults();
// Display highscores
if (race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX ||
@ -1135,14 +1292,7 @@ void RaceResultGUI::backToLobby()
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();
result_text = sw->getKart(kart_id)->getController()->getName();
if (own_goal)
{
@ -1192,14 +1342,7 @@ void RaceResultGUI::backToLobby()
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();
result_text = sw->getKart(kart_id)->getController()->getName();
if (own_goal)
{

View File

@ -192,6 +192,7 @@ private:
void displayGPProgress();
void cleanupGPProgress();
void displayPostRaceInfo();
void displayCTFResults();
void displaySoccerResults();
void displayScreenShots();