Adding basic gui for per-player difficulties

This commit is contained in:
Flakebi 2014-07-23 15:18:40 +02:00
parent a77778b1cd
commit 0195d95bad
8 changed files with 140 additions and 34 deletions

View File

@ -76,7 +76,7 @@
time for skidmarks to fade out. -->
<skid-marks max-number="100" fadeout-time="60"/>
<!-- Defines when the upright constraint should be acctive, it's
<!-- Defines when the upright constraint should be active, it's
disabled when the kart is more than this value from the track. -->
<near-ground distance="2"/>
@ -149,7 +149,7 @@
<!-- Camera: Distance between kart and camera.
forward-up-angle: Angle between camera and plane of kart (pitch)
when the camera is pointing forward
backward-up-angke: Angle between camera and plane of kart (pitch)
backward-up-angle: Angle between camera and plane of kart (pitch)
when the camera is pointing backwards. This is usually
larger than the forward-up-angle, since the kart itself
otherwise obstricts too much of the view. -->
@ -334,6 +334,16 @@
skidding-threshold="2.0"
/>
</ai>
<!-- The per-player difficulties in multiplayer games.
These values are multiplied with the current values of a car. (except ai) -->
<difficulties>
<easiest power="4.0" max-speed="4.0" ai="-2"/>
<easier power="2.0" max-speed="2.0" ai="-1"/>
<normal power="1.0" max-speed="1.0" ai="0"/>
<harder power="0.5" max-speed="0.5" ai="+1"/>
<hardest power="0.25" max-speed="0.25" ai="+2"/>
</difficulties>
<!-- Suspension related values. stiffness: kart's suspension stiffness.
rest: Length of suspension when at rest.

View File

@ -43,9 +43,6 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
{
m_player_id = player_id;
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
area.getWidth(), area.getHeight() );
const std::string default_kart = UserConfigParams::m_default_kart;
const KartProperties* props =
kart_properties_manager->getKart(default_kart);
@ -76,19 +73,16 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
}
const int offset = (m_h - (SKILL_COUNT*m_skill_bar_h)) / 2;
for (int i = 0; i < SKILL_COUNT; ++i)
{
irr::core::recti skillArea(m_skill_bar_x, m_skill_bar_y + offset*i,
m_skill_bar_x + m_skill_bar_w,
m_skill_bar_y + m_skill_bar_h + offset*i);
irr::core::recti skillArea(0, 0, 1, 1);
SkillLevelWidget* skill_bar = NULL;
skill_bar = new SkillLevelWidget(skillArea, m_player_id, multiplayer, display_text);
skill_bar = new SkillLevelWidget(skillArea, m_player_id, multiplayer, display_text);
m_skills.push_back(skill_bar);
m_children.push_back(skill_bar);
m_skills.push_back(skill_bar);
m_children.push_back(skill_bar);
}
m_skills[SKILL_MASS]->setValue((int)(props->getMass()/5));
@ -103,6 +97,8 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
m_skills[SKILL_POWER]->setLabel("POWER");
m_skills[SKILL_POWER]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_power", m_player_id);
move(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
area.getWidth(), area.getHeight());
} // KartStatsWidget
// -----------------------------------------------------------------------------
@ -118,11 +114,14 @@ void KartStatsWidget::move(int x, int y, int w, int h)
{
Widget::move(x,y,w,h);
setSize(m_x, m_y, m_w, m_h);
int offset = (m_h - (SKILL_COUNT*m_skill_bar_h)) / 2;
int margin = m_h / SKILL_COUNT - m_skill_bar_h / 2;
if (margin > m_skill_bar_h)
margin = m_skill_bar_h;
int offset = (m_h - (SKILL_COUNT * margin)) / 2;
for (int i = 0; i < SKILL_COUNT; ++i)
{
m_skills[i]->move(m_skill_bar_x,
m_y + offset + m_skill_bar_h*i,
m_y + offset + margin * i,
m_skill_bar_w,
m_skill_bar_h);
}

View File

@ -33,9 +33,16 @@ using namespace irr;
ProgressBarWidget::ProgressBarWidget(bool show_label) : Widget(WTYPE_PROGRESS)
{
m_value = 0;
m_target_value = 0;
m_previous_value = 0;
m_show_label = show_label;
}
ProgressBarWidget::~ProgressBarWidget()
{
GUIEngine::needsUpdate.remove(this);
}
// -----------------------------------------------------------------------------
void ProgressBarWidget::add()
@ -47,17 +54,52 @@ void ProgressBarWidget::add()
m_id = m_element->getID();
m_element->setTabStop(false);
m_element->setTabGroup(false);
/* Copied from model_view_widget.cpp
FIXME: remove this unclean thing, I think irrlicht provides this feature:
virtual void IGUIElement::OnPostRender (u32 timeMs)
\brief animate the element and its children.
*/
GUIEngine::needsUpdate.push_back(this);
}
// -----------------------------------------------------------------------------
void ProgressBarWidget::setValue(int value)
{
m_value = value;
m_target_value = value;
m_previous_value = value;
if (m_show_label)
{
setLabel(std::string(StringUtils::toString(value) + "%").c_str());
}
// -----------------------------------------------------------------------------
void ProgressBarWidget::moveValue(int value)
{
m_previous_value = m_value;
m_target_value = value;
if (m_show_label)
setLabel(std::string(StringUtils::toString(value) + "%").c_str());
}
// -----------------------------------------------------------------------------
void ProgressBarWidget::update(float delta)
{
if (m_target_value != m_value)
{
// Compute current progress in the animation
float cur = (static_cast<float>(m_value) - m_previous_value) / (m_target_value - m_previous_value);
// Animation time: 1.0 seconds
cur += delta * 10;
if (cur > 1)
cur = 1;
m_value = m_previous_value + cur * (m_target_value - m_previous_value);
}
}
// -----------------------------------------------------------------------------
void ProgressBarWidget::setLabel(irr::core::stringw label)

View File

@ -37,31 +37,39 @@ namespace GUIEngine
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getWidthNeededAroundLabel() const { return 35; }
/** When inferring widget size from its label length, this method will be called to
* if/how much space must be added to the raw label's size for the widget to be large enough */
virtual int getHeightNeededAroundLabel() const { return 4; }
/** Change the label on the widget */
void setLabel(const irr::core::stringw label);
int m_value;
bool m_show_label;
/** Values for animation */
int m_target_value;
int m_previous_value;
public:
LEAK_CHECK()
ProgressBarWidget(bool show_label = true);
virtual ~ProgressBarWidget() {}
virtual ~ProgressBarWidget();
/** Change the value of the widget, it must be a percent. */
void setValue(int value);
/** Change the value of the widget smooth, it must be a percent. */
void moveValue(int value);
virtual void update(float delta);
void add();
/** Get the current value of the widget. */
int getValue() {return m_value; };
};
}

View File

@ -148,7 +148,7 @@ void SkillLevelWidget::setSize(const int x, const int y, const int w, const int
void SkillLevelWidget::setValue(const int value)
{
m_bar->setValue(value);
m_bar->moveValue(value);
}
// -----------------------------------------------------------------------------

View File

@ -234,6 +234,13 @@ public:
DIFFICULTY_LAST = DIFFICULTY_BEST,
DIFFICULTY_COUNT};
/** Game difficulty. */
enum PerPlayerDifficulty { PLAYER_DIFFICULTY_EASIEST,
PLAYER_DIFFICULTY_EASY,
PLAYER_DIFFICULTY_NORMAL,
PLAYER_DIFFICULTY_HARD,
PLAYER_DIFFICULTY_HARDEST };
/** Different kart types: A local player, a player connected via network,
* an AI kart, the leader kart (currently not used), a ghost kart. */
enum KartType { KT_PLAYER, KT_NETWORK_PLAYER, KT_AI, KT_LEADER,
@ -523,6 +530,21 @@ public:
return "";
} // getDifficultyAsString
// ------------------------------------------------------------------------
/** Returns the specified difficulty as a string. */
std::string getPerPlayerDifficultyAsString(PerPlayerDifficulty diff) const
{
switch(diff)
{
case RaceManager::PLAYER_DIFFICULTY_EASIEST: return "easiest"; break;
case RaceManager::PLAYER_DIFFICULTY_EASY: return "easy"; break;
case RaceManager::PLAYER_DIFFICULTY_NORMAL: return "normal"; break;
case RaceManager::PLAYER_DIFFICULTY_HARD: return "hard"; break;
case RaceManager::PLAYER_DIFFICULTY_HARDEST: return "hardest"; break;
default: assert(false);
}
return "";
} // getPerPlayerDifficultyAsString
// ------------------------------------------------------------------------
const std::string& getTrackName() const { return m_tracks[m_track_number];}
// ------------------------------------------------------------------------
const GrandPrixData& getGrandPrix() const { return m_grand_prix; }

View File

@ -234,7 +234,7 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
// ---- KartStatsWidget
m_kart_stats = NULL;
// area for the stats widget
// area for the stats widget
core::recti statsArea;
if (!parent->m_multiplayer)
{
@ -256,6 +256,10 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
m_kart_stats->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_stats", m_player_id);
m_children.push_back(m_kart_stats);
m_difficulty = new GUIEngine::SpinnerWidget();
//TODO set difficulty to normal
m_children.push_back(m_difficulty);
if (parent->m_multiplayer && associated_player)
{
if (associated_player->getDevice()->getType() == DT_KEYBOARD)
@ -287,11 +291,15 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] =
StringUtils::toString(player_amount-1);
m_player_ident_spinner->m_properties[PROP_WRAP_AROUND] = "true";
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_EASIEST);
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_HARDEST);
}
else
{
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] = "0";
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_NORMAL);
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_NORMAL);
}
//m_player_ident_spinner->m_event_handler = this;
@ -494,6 +502,7 @@ void PlayerKartWidget::add()
m_player_ident_spinner->add();
m_player_ident_spinner->getIrrlichtElement()->setTabStop(false);
m_player_ident_spinner->setListener(this);
m_difficulty->add();
m_kart_stats->add();
m_model_view->add();
m_kart_name->add();
@ -501,6 +510,7 @@ void PlayerKartWidget::add()
m_model_view->update(0);
m_player_ident_spinner->clearLabels();
m_difficulty->clearLabels();
irr::core::stringw name; // name of the player
if (m_associated_player)
@ -514,16 +524,23 @@ void PlayerKartWidget::add()
for (int n=0; n<player_amount; n++)
{
core::stringw name = PlayerManager::get()->getPlayer(n)->getName();
m_player_ident_spinner->addLabel( translations->fribidize(name) );
m_player_ident_spinner->addLabel(translations->fribidize(name));
}
// select the right player profile in the spinner
m_player_ident_spinner->setValue(name);
m_difficulty->addLabel(_("Easiest"));
m_difficulty->addLabel(_("Easy"));
m_difficulty->addLabel(_("Normal"));
m_difficulty->addLabel(_("Hard"));
m_difficulty->addLabel(_("Hardest"));
}
else
{
m_player_ident_spinner->addLabel(name);
m_player_ident_spinner->setVisible(false);
m_difficulty->addLabel(_("Normal"));
m_difficulty->setVisible(false);
}
assert(m_player_ident_spinner->getStringValue() == name);
@ -693,6 +710,8 @@ void PlayerKartWidget::onUpdate(float delta)
{
m_kart_stats->move(m_x, m_y + m_h/2,
m_w, m_h/2);
m_difficulty->move(m_difficulty_x, m_difficulty_y,
m_difficulty_w, m_difficulty_h);
}
@ -771,6 +790,8 @@ void PlayerKartWidget::setSize(const int x, const int y, const int w, const int
player_id_w = w;
player_id_h = GUIEngine::getFontHeight();
m_difficulty_h = GUIEngine::getFontHeight();
player_name_h = 40;
player_name_w = std::min(400, w);
@ -796,25 +817,23 @@ void PlayerKartWidget::setSize(const int x, const int y, const int w, const int
if (m_parent_screen->m_multiplayer)
{
const int modelMaxHeight = (h - kart_name_h - player_name_h
- player_id_h)/2;
- player_id_h - m_difficulty_h)/2;
const int modelMaxWidth = w;
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
model_x = x + w/2 - (int)(bestSize/2);
model_y = y + player_name_h + player_id_h;
model_w = (int)(bestSize);
model_w = bestSize;
model_h = bestSize;
m_kart_stats_w = model_w;
m_kart_stats_h = model_h;
m_kart_stats_x = x + w/2 - (int)(bestSize/2);
m_kart_stats_y = model_y + model_h;
m_kart_stats_y = model_y + model_h + m_difficulty_h;
}
else
{
const int modelMaxHeight = h - kart_name_h - player_name_h
- player_id_h;
- player_id_h - m_difficulty_h;
const int modelMaxWidth = w;
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
const int modelY = y + player_name_h + player_id_h;
@ -831,6 +850,10 @@ void PlayerKartWidget::setSize(const int x, const int y, const int w, const int
kart_name_x = x;
kart_name_y = y + h - kart_name_h;
m_difficulty_w = w * 2 / 3;
m_difficulty_x = x + (w - m_difficulty_w) / 2;
m_difficulty_y = model_y + model_h;
} // setSize
// -------------------------------------------------------------------------

View File

@ -243,6 +243,7 @@ class PlayerKartWidget : public GUIEngine::Widget,
int model_x, model_y, model_w, model_h;
int kart_name_x, kart_name_y, kart_name_w, kart_name_h;
int m_kart_stats_x, m_kart_stats_y, m_kart_stats_w, m_kart_stats_h;
int m_difficulty_x, m_difficulty_y, m_difficulty_w, m_difficulty_h;
/** A reserved ID for this widget if any, -1 otherwise. (If no ID is
* reserved, widget will not be in the regular tabbing order */
@ -274,6 +275,7 @@ public:
/** Sub-widgets created by this widget */
PlayerNameSpinner* m_player_ident_spinner;
GUIEngine::SpinnerWidget* m_difficulty;
GUIEngine::KartStatsWidget* m_kart_stats;
GUIEngine::ModelViewWidget* m_model_view;
GUIEngine::LabelWidget* m_kart_name;