Switch per player difficulty to player config
This commit is contained in:
parent
70ad37aeb7
commit
e2089fcea6
@ -10,8 +10,6 @@
|
||||
<placeholder id="playerskarts" width="100%" align="center" proportion="4">
|
||||
<!-- Contents is added programatically -->
|
||||
</placeholder>
|
||||
<placeholder id="perPlayerDifficulty" width="100%" align="center" proportion="0">
|
||||
</placeholder>
|
||||
|
||||
<spacer height="15" width="25"/>
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the user screen" text="Multiplayer Boost/Handicap"/>
|
||||
<gauge id="difficulty" min_value="1" max_value="5" width="300" align="center" />
|
||||
<gauge id="difficulty" min_value="0" max_value="4" width="300" align="center" />
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the user screen" text="Apply Boost/Handicap in singleplayer too"/>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<div width="80%" align="center" layout="vertical-row" height="fit">
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the user screen" text="Multiplayer Boost/Handicap"/>
|
||||
<gauge id="difficulty" min_value="1" max_value="5" width="300" align="center" />
|
||||
<gauge id="difficulty" min_value="0" max_value="4" width="300" align="center" />
|
||||
</div>
|
||||
<div width="100%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="left" I18N="In the user screen" text="Apply Boost/Handicap in singleplayer too"/>
|
||||
|
@ -338,7 +338,9 @@
|
||||
</ai>
|
||||
|
||||
<!-- The per-player difficulties in multiplayer games.
|
||||
These values are multiplied with the current values of a car. -->
|
||||
These values are multiplied with the current values of a car
|
||||
so 1 means that nothing changes.
|
||||
The meaning of the different values is explained below this tag. -->
|
||||
<difficulties>
|
||||
<easiest>
|
||||
<mass value="1.0"/>
|
||||
|
@ -41,6 +41,8 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
|
||||
m_local_name = name;
|
||||
m_is_guest_account = is_guest;
|
||||
m_use_frequency = is_guest ? -1 : 0;
|
||||
m_difficulty = PLAYER_DIFFICULTY_NORMAL;
|
||||
m_singleplayer_difficulty = false;
|
||||
m_unique_id = PlayerManager::get()->getUniqueId();
|
||||
m_saved_session = false;
|
||||
m_saved_token = "";
|
||||
@ -68,6 +70,8 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
|
||||
*/
|
||||
PlayerProfile::PlayerProfile(const XMLNode* node)
|
||||
{
|
||||
m_difficulty = PLAYER_DIFFICULTY_NORMAL;
|
||||
m_singleplayer_difficulty = false;
|
||||
m_saved_session = false;
|
||||
m_saved_token = "";
|
||||
m_saved_user_id = 0;
|
||||
@ -81,6 +85,8 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
|
||||
node->get("name", &m_local_name );
|
||||
node->get("guest", &m_is_guest_account );
|
||||
node->get("use-frequency", &m_use_frequency );
|
||||
node->get("difficulty", (int*) &m_difficulty);
|
||||
node->get("singleplayer-difficulty", &m_singleplayer_difficulty);
|
||||
node->get("unique-id", &m_unique_id );
|
||||
node->get("saved-session", &m_saved_session );
|
||||
node->get("saved-user", &m_saved_user_id );
|
||||
@ -198,7 +204,10 @@ void PlayerProfile::save(UTFWriter &out)
|
||||
<< L"\" guest=\"" << m_is_guest_account
|
||||
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
|
||||
|
||||
out << L" icon-filename=\"" << m_icon_filename <<L"\"\n";
|
||||
out << L" icon-filename=\"" << m_icon_filename << L"\"\n";
|
||||
|
||||
out << L" difficulty=\"" << m_difficulty
|
||||
<< L"\" singleplayer-difficulty=\"" << m_singleplayer_difficulty << L"\"\n";
|
||||
|
||||
out << L" unique-id=\"" << m_unique_id
|
||||
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define HEADER_PLAYER_PROFILE_HPP
|
||||
|
||||
#include "challenges/story_mode_status.hpp"
|
||||
#include "network/remote_kart_info.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/types.hpp"
|
||||
@ -66,6 +67,10 @@ public:
|
||||
private:
|
||||
LEAK_CHECK()
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
#endif
|
||||
|
||||
/** The name of the player (wide string, so it can be in native
|
||||
* language). */
|
||||
core::stringw m_local_name;
|
||||
@ -73,10 +78,6 @@ private:
|
||||
/** True if this account is a guest account. */
|
||||
bool m_is_guest_account;
|
||||
|
||||
#ifdef DEBUG
|
||||
unsigned int m_magic_number;
|
||||
#endif
|
||||
|
||||
/** Counts how often this player was used (always -1 for guests). */
|
||||
int m_use_frequency;
|
||||
|
||||
@ -86,6 +87,13 @@ private:
|
||||
/** Absolute path of the icon file for this player. */
|
||||
std::string m_icon_filename;
|
||||
|
||||
/** The difficulty (boost or handicap) for this player. */
|
||||
PerPlayerDifficulty m_difficulty;
|
||||
|
||||
/** If the per player difficulty should be applied for singleplayer games.
|
||||
Story mode is excluded to prevent cheating. */
|
||||
bool m_singleplayer_difficulty;
|
||||
|
||||
/** True if this user has a saved session. */
|
||||
bool m_saved_session;
|
||||
|
||||
@ -111,8 +119,8 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
PlayerProfile(const core::stringw &name, bool is_guest = false);
|
||||
PlayerProfile(const XMLNode *node);
|
||||
PlayerProfile(const core::stringw &name, bool is_guest = false);
|
||||
PlayerProfile(const XMLNode *node);
|
||||
virtual ~PlayerProfile();
|
||||
void save(UTFWriter &out);
|
||||
void loadRemainingData(const XMLNode *node);
|
||||
@ -159,6 +167,42 @@ public:
|
||||
return m_local_name.c_str();
|
||||
} // getName
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the per player difficulty for this player. */
|
||||
void setDifficulty(const PerPlayerDifficulty difficulty)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(m_magic_number == 0xABCD1234);
|
||||
#endif
|
||||
m_difficulty = difficulty;
|
||||
} // setDifficulty
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the per player difficulty of this player. */
|
||||
PerPlayerDifficulty getDifficulty() const
|
||||
{
|
||||
assert(m_magic_number == 0xABCD1234);
|
||||
return m_difficulty;
|
||||
} // getDifficulty
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the singleplayer difficulty for this player. */
|
||||
void setSingleplayerDifficulty(const bool singleplayer_difficulty)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(m_magic_number == 0xABCD1234);
|
||||
#endif
|
||||
m_singleplayer_difficulty = singleplayer_difficulty;
|
||||
} // setSingleplayerDifficulty
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the per player difficulty of this player. */
|
||||
bool isSingleplayerDifficulty() const
|
||||
{
|
||||
assert(m_magic_number == 0xABCD1234);
|
||||
return m_singleplayer_difficulty;
|
||||
} // getDifficulty
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if this player is a guest account. */
|
||||
bool isGuestAccount() const
|
||||
|
@ -2082,6 +2082,20 @@ void Skin::drawBadgeOn(const Widget* widget, const core::recti& rect)
|
||||
"hourglass.png");
|
||||
doDrawBadge(texture, rect, max_icon_size, true);
|
||||
}
|
||||
if (widget->m_badges & ZIPPER_BADGE)
|
||||
{
|
||||
float max_icon_size = 0.43f;
|
||||
video::ITexture* texture = irr_driver->getTexture(FileManager::MODEL,
|
||||
"zipper_collect.png");
|
||||
doDrawBadge(texture, rect, max_icon_size, false);
|
||||
}
|
||||
if (widget->m_badges & ANCHOR_BADGE)
|
||||
{
|
||||
float max_icon_size = 0.43f;
|
||||
video::ITexture* texture = irr_driver->getTexture(FileManager::MODEL,
|
||||
"anchor-icon.png");
|
||||
doDrawBadge(texture, rect, max_icon_size, false);
|
||||
}
|
||||
} // drawBadgeOn
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -60,19 +60,23 @@ namespace GUIEngine
|
||||
enum BadgeType
|
||||
{
|
||||
/** display a lock on the widget, to mean a certain game feature is locked */
|
||||
LOCKED_BADGE = 1,
|
||||
LOCKED_BADGE = 1,
|
||||
/** display a green check on a widget, useful e.g. to display confirmation */
|
||||
OK_BADGE = 2,
|
||||
OK_BADGE = 1 << 1,
|
||||
/** display a red mark badge on the widget, useful e.g. to warn of an invalid choice */
|
||||
BAD_BADGE = 4,
|
||||
BAD_BADGE = 1 << 2,
|
||||
/** display a trophy badge on the widget, useful e.g. for challenges */
|
||||
TROPHY_BADGE = 8,
|
||||
TROPHY_BADGE = 1 << 3,
|
||||
/** A gamepad icon */
|
||||
GAMEPAD_BADGE = 16,
|
||||
GAMEPAD_BADGE = 1 << 4,
|
||||
/** A keyboard icon */
|
||||
KEYBOARD_BADGE = 32,
|
||||
KEYBOARD_BADGE = 1 << 5,
|
||||
/** An hourglass badge to indicate loading */
|
||||
LOADING_BADGE = 64
|
||||
LOADING_BADGE = 1 << 6,
|
||||
/** A zipper badge to indicate that this player receives a boost */
|
||||
ZIPPER_BADGE = 1 << 7,
|
||||
/** A anchor badge to indicate that this player receives a handicap */
|
||||
ANCHOR_BADGE = 1 << 8
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,7 +53,6 @@ namespace GUIEngine
|
||||
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 */
|
||||
@ -85,7 +84,6 @@ namespace GUIEngine
|
||||
|
||||
/** Sub-widgets created by this widget */
|
||||
PlayerNameSpinner* m_player_ident_spinner;
|
||||
SpinnerWidget* m_difficulty;
|
||||
KartStatsWidget* m_kart_stats;
|
||||
ModelViewWidget* m_model_view;
|
||||
LabelWidget* m_kart_name;
|
||||
|
@ -25,7 +25,7 @@
|
||||
GhostKart::GhostKart(const std::string& ident)
|
||||
: Kart(ident, /*world kart id*/99999,
|
||||
/*position*/-1, btTransform(), stk_config->getPlayerDifficulty(
|
||||
PLAYER_DIFFICULTY_NORMAL)) //TODO Ghost races PerPlayerDifficulty
|
||||
PLAYER_DIFFICULTY_NORMAL))
|
||||
{
|
||||
m_current_transform = 0;
|
||||
m_next_event = 0;
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "utils/log.hpp"
|
||||
|
||||
/**
|
||||
* The constructor initialises all values with default values (mostly 1).
|
||||
* The constructor initialises all values with default values.
|
||||
*/
|
||||
PlayerDifficulty::PlayerDifficulty(const std::string &filename)
|
||||
{
|
||||
|
@ -27,12 +27,10 @@
|
||||
class XMLNode;
|
||||
|
||||
/**
|
||||
* \brief This class stores the properties of a kart.
|
||||
* This includes size, name, identifier, physical properties etc.
|
||||
* It is atm also the base class for STKConfig, which stores the default values
|
||||
* for all physics constants.
|
||||
* Note that KartProperies is copied (when setting the default values from
|
||||
* stk_config.
|
||||
* \brief This class stores values that modify the properties of a kart.
|
||||
* This includes physical properties like speed and the effect of items.
|
||||
* The values stored in this class get multiplied with the current
|
||||
* properties of the kart. If all values here are set to 1, nothing changes.
|
||||
*
|
||||
* \ingroup karts
|
||||
*/
|
||||
@ -161,8 +159,8 @@ private:
|
||||
|
||||
|
||||
public:
|
||||
PlayerDifficulty (const std::string &filename="");
|
||||
~PlayerDifficulty ();
|
||||
PlayerDifficulty (const std::string &filename="");
|
||||
~PlayerDifficulty ();
|
||||
void getAllData (const XMLNode * root);
|
||||
std::string getIdent() const;
|
||||
float getStartupBoost () const;
|
||||
|
@ -307,7 +307,8 @@ void RaceManager::startNew(bool from_overworld)
|
||||
// Create the kart status data structure to keep track of scores, times, ...
|
||||
// ==========================================================================
|
||||
m_kart_status.clear();
|
||||
Log::verbose("RaceManager", "Nb of karts=%u, ai:%lu players:%lu\n", (unsigned int)m_num_karts, m_ai_kart_list.size(), m_player_karts.size());
|
||||
Log::verbose("RaceManager", "Nb of karts=%u, ai:%lu players:%lu\n",
|
||||
(unsigned int) m_num_karts, m_ai_kart_list.size(), m_player_karts.size());
|
||||
|
||||
assert((unsigned int)m_num_karts == m_ai_kart_list.size()+m_player_karts.size());
|
||||
// First add the AI karts (randomly chosen)
|
||||
|
@ -507,6 +507,16 @@ bool KartSelectionScreen::joinPlayer(InputDevice* device, bool first_player)
|
||||
|
||||
newPlayerWidget->add();
|
||||
|
||||
// Add badge for per player difficulty if necessary
|
||||
if (!m_from_overworld && (m_multiplayer || !profile_to_use->isSingleplayerDifficulty()))
|
||||
{
|
||||
PerPlayerDifficulty difficulty = profile_to_use->getDifficulty();
|
||||
if (difficulty < PLAYER_DIFFICULTY_NORMAL)
|
||||
m_kart_widgets[new_player_id].m_model_view->setBadge(ZIPPER_BADGE);
|
||||
else if (difficulty > PLAYER_DIFFICULTY_NORMAL)
|
||||
m_kart_widgets[new_player_id].m_model_view->setBadge(ANCHOR_BADGE);
|
||||
}
|
||||
|
||||
// ---- Divide screen space among all karts
|
||||
const int amount = m_kart_widgets.size();
|
||||
Widget* fullarea = getWidget("playerskarts");
|
||||
@ -1179,6 +1189,10 @@ void KartSelectionScreen::allPlayersDone()
|
||||
// std::cout << "selection=" << selection.c_str() << std::endl;
|
||||
|
||||
race_manager->setLocalKartInfo(n, selected_kart);
|
||||
// Set per player difficulty if needed
|
||||
const PlayerProfile* profile = StateManager::get()->getActivePlayerProfile(n);
|
||||
if (!m_from_overworld && (m_multiplayer || !profile->isSingleplayerDifficulty()))
|
||||
race_manager->setPlayerDifficulty(n, profile->getDifficulty());
|
||||
}
|
||||
|
||||
// ---- Switch to assign mode
|
||||
|
@ -48,7 +48,6 @@ class KartSelectionScreen : public GUIEngine::Screen
|
||||
friend class KartHoverListener;
|
||||
friend class PlayerNameSpinner;
|
||||
friend class FocusDispatcher;
|
||||
friend class FocusDispatcher2;
|
||||
protected:
|
||||
/** Contains the custom widget shown for every player. (ref only since
|
||||
* we're adding them to a Screen, and the Screen will take ownership
|
||||
@ -196,14 +195,6 @@ public:
|
||||
virtual GUIEngine::EventPropagation focused(const int playerID);
|
||||
}; // FocusDispatcher
|
||||
|
||||
class FocusDispatcher2 : public FocusDispatcher
|
||||
{
|
||||
public:
|
||||
FocusDispatcher2(KartSelectionScreen *parent);
|
||||
|
||||
virtual GUIEngine::EventPropagation focused(const int playerID);
|
||||
};
|
||||
|
||||
//!----------------------------------------------------------------------------
|
||||
//! KartHoverListener :
|
||||
class KartHoverListener : public GUIEngine::DynamicRibbonHoverListener
|
||||
|
@ -59,6 +59,17 @@ void BaseUserScreen::loadedFromFile()
|
||||
|
||||
void BaseUserScreen::init()
|
||||
{
|
||||
m_difficulty = getWidget<SpinnerWidget>("difficulty");
|
||||
assert(m_difficulty);
|
||||
m_difficulty->clearLabels();
|
||||
m_difficulty->addLabel(_("Big boost"));
|
||||
m_difficulty->addLabel(_("Boost"));
|
||||
m_difficulty->addLabel(_("Normal"));
|
||||
m_difficulty->addLabel(_("Handicap"));
|
||||
m_difficulty->addLabel(_("Big handicap"));
|
||||
|
||||
m_singleplayer_difficulty = getWidget<CheckBoxWidget>("singleplayer-difficulty");
|
||||
assert(m_singleplayer_difficulty);
|
||||
m_online_cb = getWidget<CheckBoxWidget>("online");
|
||||
assert(m_online_cb);
|
||||
m_username_tb = getWidget<TextBoxWidget >("username");
|
||||
@ -155,23 +166,15 @@ void BaseUserScreen::selectUser(int index)
|
||||
m_players->setSelection(StringUtils::toString(index), PLAYER_ID_GAME_MASTER,
|
||||
/*focusIt*/ true);
|
||||
|
||||
// Last game was not online, so make the offline settings the default
|
||||
// (i.e. unckeck online checkbox, and make entry fields invisible).
|
||||
|
||||
if (!profile->wasOnlineLastTime() || profile->getLastOnlineName() == "")
|
||||
{
|
||||
m_online_cb->setState(false);
|
||||
makeEntryFieldsVisible();
|
||||
return;
|
||||
}
|
||||
|
||||
// Now last use was with online --> Display the saved data
|
||||
m_online_cb->setState(true);
|
||||
// Display the saved data if the user was online last time and change the visibility
|
||||
m_difficulty->setValue(profile->getDifficulty());
|
||||
m_singleplayer_difficulty->setState(profile->isSingleplayerDifficulty());
|
||||
m_online_cb->setState(profile->wasOnlineLastTime() && profile->getLastOnlineName().size() > 0);
|
||||
makeEntryFieldsVisible();
|
||||
m_username_tb->setText(profile->getLastOnlineName());
|
||||
getWidget<CheckBoxWidget>("remember-user")->setState(
|
||||
profile->rememberPassword());
|
||||
if(profile->getLastOnlineName().size()>0)
|
||||
if(profile->getLastOnlineName().size() > 0)
|
||||
m_username_tb->setDeactivated();
|
||||
else
|
||||
m_username_tb->setActivated();
|
||||
@ -353,6 +356,10 @@ void BaseUserScreen::login()
|
||||
PlayerManager::get()->setCurrentPlayer(player);
|
||||
assert(player);
|
||||
|
||||
// Save difficulty
|
||||
player->setDifficulty((PerPlayerDifficulty) m_difficulty->getValue());
|
||||
player->setSingleplayerDifficulty(m_singleplayer_difficulty->getState());
|
||||
|
||||
// If no online login requested, log the player out (if necessary)
|
||||
// and go to the main menu screen (though logout needs to finish first)
|
||||
if(!m_online_cb->getState())
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
@ -64,6 +65,12 @@ private:
|
||||
* display more meaningful sign-out message. */
|
||||
irr::core::stringw m_sign_in_name;
|
||||
|
||||
/** Per player difficulty. */
|
||||
GUIEngine::SpinnerWidget *m_difficulty;
|
||||
|
||||
/** Apply per player difficulty in singleplayer mode. */
|
||||
GUIEngine::CheckBoxWidget *m_singleplayer_difficulty;
|
||||
|
||||
/** Online check box. */
|
||||
GUIEngine::CheckBoxWidget *m_online_cb;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user