Use a custom dialog to show the details of an achievement's progress

This commit is contained in:
Benau 2018-10-07 11:33:38 +08:00
parent a8b1c54092
commit 38d13adc07
8 changed files with 519 additions and 12 deletions

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="2%" width="100%" height="96%" layout="vertical-row">
<!-- The achievement's name is filled in the header at runtime -->
<header id="title" width="96%" height="10%" text_align="center"
word_wrap="true"/>
<spacer width="20" height="1%" />
<label id="description" width="90%" height="12%" align="center"
text_align="center" word_wrap="true" text=""/>
<spacer width="20" height="1%" />
<box width="96%" height="64%" align="center" layout="vertical-row"
padding="6">
<list id="progress-tree" x="0" y="0" width="100%" height="100%"/>
</box>
<spacer width="20" height="1%" />
<buttonbar id="options" width="90%" height="10%" align="center">
<icon-button id="ok" width="16" height="16"
icon="gui/icons/green_check.png" text="OK"
label_location="bottom"/>
</buttonbar>
<spacer width="20" height="1%" />
</div>
</stkgui>

View File

@ -153,21 +153,47 @@ irr::core::stringw Achievement::getProgressAsString()
* Returning an error code with a number is not full-proof because a sum goal can
* legitimately be negative (a counter can be chosen to count against the
* achievement's fullfilment). */
int Achievement::computeGoalProgress(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference)
int Achievement::computeGoalProgress(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference, bool same_tree)
{
if (progress.children.size() != 1)
if (progress.children.size() >= 2)
{
// This should NOT happen
assert(false);
return 0;
}
// Can happen when showing the progress status of all parts of the goal tree
else if (progress.children.size() == 0)
{
//TODO : find a more automatic way ; clean up repetition
if (progress.type == "race-started-all" ||
progress.type == "race-finished-all" ||
progress.type == "race-won-all" ||
progress.type == "race-finished-reverse-all" ||
progress.type == "race-finished-alone-all" ||
progress.type == "less-laps-all" ||
progress.type == "more-laps-all" ||
progress.type == "twice-laps-all" ||
progress.type == "egg-hunt-started-all" ||
progress.type == "egg-hunt-finished-all")
{
if (same_tree)
{
return PlayerManager::getCurrentAchievementsStatus()
->getNumTracksAboveValue(0, reference.type);
}
// Compare against the target value (in the reference tree) !
// Progress is only shown for the current local accuont, so we can use the current achievements status
return PlayerManager::getCurrentAchievementsStatus()
->getNumTracksAboveValue(reference.value, reference.type);
}
return progress.value;
}
else if (progress.children[0].type == "AND" ||
progress.children[0].type == "AND-AT-ONCE" ||
progress.children[0].type == "OR")
{
return computeGoalProgress(progress.children[0], reference.children[0]);
}
else
{
//TODO : find a more automatic way

View File

@ -44,6 +44,14 @@ private:
/** True if this achievement has been achieved. */
bool m_achieved;
void onCompletion();
bool recursiveSetGoalValue(AchievementInfo::goalTree &tree, const std::string &goal_string, int value,
bool and_or, bool sum_andatonce);
bool recursiveCompletionCheck(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference);
protected:
friend class AchievementProgressDialog;
/** The tree of goals. It is identical to the
* goal tree of the matching AchievementInfo,
* except that the stored values represent the
@ -53,13 +61,8 @@ private:
/** A pointer to the corresponding AchievementInfo instance. */
AchievementInfo *m_achievement_info;
void onCompletion();
bool recursiveSetGoalValue(AchievementInfo::goalTree &tree, const std::string &goal_string, int value,
bool and_or, bool sum_andatonce);
bool recursiveCompletionCheck(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference);
int computeFullfiledGoals(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference);
int computeGoalProgress(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference);
int computeGoalProgress(AchievementInfo::goalTree &progress, AchievementInfo::goalTree &reference, bool same_tree=false);
public:
Achievement(AchievementInfo * info);

View File

@ -149,6 +149,33 @@ void AchievementInfo::copyGoalTree(goalTree &copy, goalTree &model, bool set_val
}
} // copyGoalTree
// ----------------------------------------------------------------------------
/** Returns the goal tree's depth. If an AND/OR/ANT-AT-ONCE contains only
* one element, it is ignored (this is useful because the root is always
* AND ; so for e.g. an OR achievement, we prefer to not display it). */
int AchievementInfo::getRecursiveDepth(goalTree &parent)
{
if (parent.children.size() != 1)
{
int max = 0;
for (unsigned int i=0;i<parent.children.size();i++)
{
int depth = getRecursiveDepth(parent.children[i]);
if (depth > max);
max = depth;
}
return max+1;
}
else if (parent.children[0].type == "AND" ||
parent.children[0].type == "AND-AT-ONCE" ||
parent.children[0].type == "OR")
{
return getRecursiveDepth(parent.children[0]);
}
else
return 1;
} // getRecursiveDepth
// ----------------------------------------------------------------------------
/** Returns a string with the number of goals to fullfil to
* get this achievements.

View File

@ -73,8 +73,10 @@ private:
void parseGoals(const XMLNode * input, goalTree &parent);
int recursiveGoalCount(goalTree &parent);
int recursiveProgressCount(goalTree &parent);
int getRecursiveDepth(goalTree &parent);
protected:
friend class Achievement;
friend class AchievementProgressDialog;
/** The tree storing all goals */
goalTree m_goal_tree;
@ -85,6 +87,7 @@ public:
virtual irr::core::stringw goalString();
virtual irr::core::stringw progressString();
int getDepth() { return getRecursiveDepth(m_goal_tree); }
uint32_t getID() const { return m_id; }
irr::core::stringw getDescription() const { return _(m_description.c_str()); }
irr::core::stringw getName() const { return _LTR(m_name.c_str()); }

View File

@ -0,0 +1,325 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2018 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/dialogs/achievement_progress_dialog.hpp"
#include "achievements/achievement_info.hpp"
#include "config/player_manager.hpp"
#include "guiengine/dialog_queue.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
#include <IGUIEnvironment.h>
using namespace GUIEngine;
using namespace irr;
using namespace irr::gui;
using namespace Online;
// ----------------------------------------------------------------------------
AchievementProgressDialog::AchievementProgressDialog(Achievement *achievement)
: ModalDialog(0.9f,0.9f), m_achievement(achievement),
m_self_destroy(false)
{
loadFromFile("online/achievement_progress_dialog.stkgui");
m_progress_table = getWidget<ListWidget>("progress-tree");
assert(m_progress_table != NULL);
m_depth = m_achievement->getInfo()->getDepth();
m_progress_table->clear();
std::vector<ListWidget::ListCell> row;
for (int i=0;i<m_depth;i++)
{
row.push_back(ListWidget::ListCell
(_C("achievement_info", "Goal"), -1, 2, true));
row.push_back(ListWidget::ListCell
(_C("achievement_info", "Progress"), -1, 1, true));
}
m_progress_table->addItem(StringUtils::toString(0), row);
m_row_counter = 1;
recursiveFillTable(m_achievement->m_progress_goal_tree, m_achievement->m_achievement_info->m_goal_tree, 0);
} // AchievementProgressDialog
// -----------------------------------------------------------------------------
/* Recursively fill the table with the goals */
void AchievementProgressDialog::recursiveFillTable(AchievementInfo::goalTree &progress,
AchievementInfo::goalTree &reference, int depth)
{
if (progress.children.size() != 1)
{
int goal = -1; // Will be filled with goals or progress
int target = -1;
if (progress.type == "AND" ||
progress.type == "AND-AT-ONCE" ||
progress.type == "OR")
{
goal = m_achievement->computeFullfiledGoals(progress, reference);
target = m_achievement->computeFullfiledGoals(reference, reference);
}
else
{
goal = m_achievement->computeGoalProgress(progress, reference);
target = m_achievement->computeGoalProgress(reference, reference, true);
}
std::vector<ListWidget::ListCell> row;
for (int i=0;i<m_depth;i++)
{
//TODO : for sum, indicate if a subgoal counts towards or against it
if (i==depth)
{
std::string temp = StringUtils::toString(goal) + "/" +
StringUtils::toString(target);
core::stringw progress_string(temp.c_str());
core::stringw goal_name = niceGoalName(progress.type);
row.push_back(ListWidget::ListCell
(goal_name, -1, 2, true));
row.push_back(ListWidget::ListCell
(progress_string, -1, 1, true));
}
else
{
row.push_back(ListWidget::ListCell
(" ", -1, 2, true));
row.push_back(ListWidget::ListCell
(" ", -1, 1, true));
}
}
m_progress_table->addItem(StringUtils::toString(m_row_counter), row);
m_row_counter++;
for (unsigned int i=0;i<progress.children.size();i++)
{
recursiveFillTable(progress.children[i],reference.children[i],depth+1);
}
}
// Skip the current node as it has no effect
else
{
return recursiveFillTable(progress.children[0], reference.children[0], depth);
}
} // recursiveFillTable
// -----------------------------------------------------------------------------
core::stringw AchievementProgressDialog::niceGoalName(std::string internal_name)
{
core::stringw nice_name;
// I18N : For achievements, a parent goal linking logically several subgoals
if(internal_name=="AND") nice_name = _("Fulfill all the subogals");
// I18N : For achievements, a parent goal linking logically several subgoals
if(internal_name=="AND-AT-ONCE") nice_name = _("Fulfill all the subgoals at the same time");
// I18N : For achievements, a parent goal linking logically several subgoals
if(internal_name=="OR") nice_name = _("Fulfill at least one subgoal");
// I18N : For achievements, a parent goal linking logically several subgoals
if(internal_name=="SUM") nice_name = _("The sum of the subgoals must reach the indicated value");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="won-races") nice_name = _("Races won");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="won-normal-races") nice_name = _("Normal races won");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="won-tt-races") nice_name = _("Time-trial races won");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="won-ftl-races") nice_name = _("Follow-the-Leader races won");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="cons-won-races") nice_name = _("Consecutive won races");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="cons-won-races-hard") nice_name = _("Consecutive won races in Expert or SuperTux");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="easy-started") nice_name = _("Novice races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="easy-finished") nice_name = _("Novice races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="medium-started") nice_name = _("Intermediate races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="medium-finished") nice_name = _("Intermediate races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="hard-started") nice_name = _("Expert races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="hard-finished") nice_name = _("Expert races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="best-started") nice_name = _("SuperTux races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="best-finished") nice_name = _("SuperTux races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="normal-started") nice_name = _("Normal races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="normal-finished") nice_name = _("Normal races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="tt-started") nice_name = _("Time-trial races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="tt-finished") nice_name = _("Time-trial races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="ftl-started") nice_name = _("Follow-the-Leader races started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="ftl-finished") nice_name = _("Follow-the-Leader races finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="three-strikes-started") nice_name = _("3 Strikes battle started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="three-strikes-finished") nice_name = _("3 Strikes battle finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="soccer-started") nice_name = _("Soccer matches started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="soccer-finished") nice_name = _("Soccer matches finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="egg-hunt-started") nice_name = _("Egg Hunts started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="egg-hunt-finished") nice_name = _("Egg Hunts finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="with-ghost-started") nice_name = _("Races started with a ghost replay");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="with-ghost-finished") nice_name = _("Races finished with a ghost replay");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="ctf-started") nice_name = _("Capture-the-Flag matches started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="ctf-finished") nice_name = _("Capture-the-Flag matches finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="ffa-started") nice_name = _("Free-for-All matches started");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="ffa-finished") nice_name = _("Free-for-All matches finished");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="powerup-used") nice_name = _("Powerups used");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="powerup-used-1race") { nice_name = _("Powerups used"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="bowling-hit") nice_name = _("Bowling ball hits");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="bowling-hit-1race") { nice_name = _("Bowling ball hits"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="swatter-hit") nice_name = _("Swatter hits");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="swatter-hit-1race") { nice_name = _("Swatter hits"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="all-hits") nice_name = _("All hits");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="all-hits-1race") { nice_name = _("All Hits"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="hit-same-kart-1race") { nice_name = _("Hits against the same kart"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="banana") nice_name = _("Bananas collected");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="banana-1race") { nice_name = _("Bananas collected"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="skidding") nice_name = _("Skidding");
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="skidding-1race") { nice_name = _("Skidding"); nice_name += _(" (1 race)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="skidding-1lap") { nice_name = _("Skidding"); nice_name += _(" (1 lap)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-started") { nice_name =_("Races started"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-finished") { nice_name =_("Races finished"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-won") { nice_name =_("Races won"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-finished-reverse") { nice_name =_("Reverse direction races finished"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-finished-alone") { nice_name =_("Races finished alone"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="less-laps") { nice_name =_("Races with less than the default lap number"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="more-laps") { nice_name =_("Races with more than the default lap number"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="twice-laps") { nice_name =_("Races with at least twice as much as the default lap number"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="egg-hunt-started") { nice_name =_("Egg hunts started"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="egg-hunt-finished") { nice_name =_("Egg hunts finished"); nice_name += _(" (maximum on one official track)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-started-all") { nice_name =_("Races started"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-finished-all") { nice_name =_("Races finished"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-won-all") { nice_name =_("Races won"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-finished-reverse-all") { nice_name =_("Reverse direction races finished"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="race-finished-alone-all") { nice_name =_("Races finished alone"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="less-laps-all") { nice_name =_("Races with less than the default lap number"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="more-laps-all") { nice_name =_("Races with more than the default lap number"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="twice-laps-all") { nice_name =_("Races with at least twice as much as the default lap number"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="egg-hunt-started-all") { nice_name =_("Egg hunts started"); nice_name += _(" (official tracks matching the goal)"); }
// I18N : A goal for achievements. If this text is in (), it's a precision added to multiple different goals.
if(internal_name=="egg-hunt-finished-all") { nice_name =_("Egg hunts finished"); nice_name += _(" (official tracks matching the goal)"); }
return nice_name;
} // niceGoalName
// -----------------------------------------------------------------------------
void AchievementProgressDialog::beforeAddingWidgets()
{
m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget != NULL);
m_ok_widget = getWidget<IconButtonWidget>("ok");
assert(m_ok_widget != NULL);
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
} // beforeAddingWidgets
// -----------------------------------------------------------------------------
void AchievementProgressDialog::init()
{
LabelWidget* header = getWidget<LabelWidget>("title");
assert(header != NULL);
core::stringw name = m_achievement->getInfo()->getName();
header->setText(name, true /* expand as needed */);
LabelWidget* description = getWidget<LabelWidget>("description");
assert(description != NULL);
core::stringw description_text = m_achievement->getInfo()->getDescription();
description->setText(description_text, true /* expand as needed */);
} // init
// -----------------------------------------------------------------------------
void AchievementProgressDialog::onUpdate(float dt)
{
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
return;
}
} // onUpdate
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation
AchievementProgressDialog::processEvent(const std::string& source)
{
if (source == m_options_widget->m_properties[PROP_ID])
{
const std::string& selection =
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_ok_widget->m_properties[PROP_ID])
{
m_self_destroy = true;
return GUIEngine::EVENT_BLOCK;
}
}
return GUIEngine::EVENT_LET;
} // processEvent

View File

@ -0,0 +1,81 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2018 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_ACHIEVEMENT_PROGRESS_DIALOG_HPP
#define HEADER_ACHIEVEMENT_PROGRESS_DIALOG_HPP
#include "achievements/achievement.hpp"
#include "guiengine/modaldialog.hpp"
#include "utils/types.hpp"
#include <irrString.h>
#include <vector>
namespace GUIEngine
{
class IconButtonWidget;
class LabelWidget;
class ListWidget;
class RibbonWidget;
}
/**
* \brief Dialog that shows an achievement description and progress
* \ingroup states_screens
*/
class AchievementProgressDialog : public GUIEngine::ModalDialog
{
private:
Achievement *m_achievement;
bool m_self_destroy;
int m_depth;
int m_row_counter;//Used in the recurisve table filling
GUIEngine::ListWidget* m_progress_table;
GUIEngine::RibbonWidget* m_options_widget;
GUIEngine::IconButtonWidget* m_ok_widget;
void recursiveFillTable(AchievementInfo::goalTree &progress,
AchievementInfo::goalTree &reference, int depth);
core::stringw niceGoalName(std::string internal_name);
public:
AchievementProgressDialog(Achievement *achievement);
// ------------------------------------------------------------------------
~AchievementProgressDialog() {}
// ------------------------------------------------------------------------
virtual void beforeAddingWidgets();
// ------------------------------------------------------------------------
virtual void init();
// ------------------------------------------------------------------------
void onEnterPressedInternal() { m_self_destroy = true; }
// ------------------------------------------------------------------------
GUIEngine::EventPropagation processEvent(const std::string& source);
// ------------------------------------------------------------------------
virtual bool onEscapePressed()
{
m_self_destroy = true;
return false;
}
// ------------------------------------------------------------------------
virtual void onUpdate(float dt);
};
#endif

View File

@ -25,7 +25,7 @@
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "online/online_profile.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/dialogs/achievement_progress_dialog.hpp"
#include "states_screens/dialogs/player_rankings_dialog.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "states_screens/state_manager.hpp"
@ -152,8 +152,21 @@ void BaseOnlineProfileAchievements::eventCallback(Widget* widget,
// is no error, show the achievement (it can happen that the
// string is "" if no achievement exists)
if(StringUtils::fromString(achievement, id))
new MessageDialog(AchievementsManager::get()
->getAchievementInfo(id)->getDescription());
{
std::map<uint32_t, Achievement *> & all_achievements =
PlayerManager::getCurrentPlayer()->getAchievementsStatus()
->getAllAchievements();
std::map<uint32_t, Achievement *>::const_iterator it;
for (it = all_achievements.begin(); it != all_achievements.end(); ++it)
{
Achievement *a = it->second;
if (a->getInfo()->getID() == (unsigned int) id)
{
new AchievementProgressDialog(a);
break;
}
}
}
}
if (name == "rankings")
{