Added new message system to show achievements in race (and not as a

dialog later). Work in progress ... it doesn't look particulary nice yet ;)
This commit is contained in:
hiker 2014-06-23 09:13:44 +10:00
parent 8004e9d42c
commit 6231e618d8
9 changed files with 243 additions and 14 deletions

View File

@ -68,6 +68,14 @@ when the border that intersect at this corner are enabled.
<!-- Stateless -->
<element type="background" image="ocean/background.jpg" />
<element type="achievement-message" image="ocean/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="friend-message" image="ocean/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="button" state="neutral" image="ocean/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>

View File

@ -68,6 +68,14 @@ when the border that intersect at this corner are enabled.
<!-- Stateless -->
<element type="background" image="peach/background.jpg" />
<element type="achievement-message" image="peach/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="friend-message" image="peach/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>
<element type="button" state="neutral" image="peach/glassbutton.png"
left_border="13" right_border="13" top_border="13" bottom_border="13"
preserve_h_aspect_ratios="true" hborder_out_portion="0" vborder_out_portion="0"/>

View File

@ -21,7 +21,7 @@
#include "achievements/achievement.hpp"
#include "achievements/achievement_info.hpp"
#include "guiengine/dialog_queue.hpp"
#include "guiengine/message_queue.hpp"
#include "io/utf_writer.hpp"
#include "config/player_manager.hpp"
#include "states_screens/dialogs/notification_dialog.hpp"
@ -202,8 +202,7 @@ void Achievement::check()
//show achievement
core::stringw s = StringUtils::insertValues(_("Completed achievement \"%s\"."),
m_achievement_info->getTitle());
GUIEngine::DialogQueue::get()->pushDialog(
new NotificationDialog(NotificationDialog::T_Achievements, s));
MessageQueue::add(MessageQueue::MT_ACHIEVEMENT, s);
// Sends a confirmation to the server that an achievement has been
// completed, if a user is signed in.

View File

@ -662,6 +662,7 @@ namespace GUIEngine
#include "io/file_manager.hpp"
#include "guiengine/event_handler.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/message_queue.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/skin.hpp"
@ -1189,6 +1190,8 @@ namespace GUIEngine
// further render)
g_env->drawAll();
MessageQueue::update(elapsed_time);
// ---- some menus may need updating
if (gamestate != GAME)
{

161
src/guiengine/message_queue.cpp Executable file
View File

@ -0,0 +1,161 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// 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.
/**
\page addons Addons
*/
#include "guiengine/message_queue.hpp"
#include "config/user_config.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/skin.hpp"
#include "IGUIElement.h"
using namespace GUIEngine;
namespace MessageQueue
{
/** A small helper class to store and sort messages to be displayed. */
class Message
{
private:
/** The type of the message. */
MessageQueue::MessageType m_message_type;
/** The message. */
core::stringw m_message;
public:
Message(MessageQueue::MessageType mt, const core::stringw &message)
{
m_message_type = mt;
m_message = message;
} // Message
// --------------------------------------------------------------------
bool operator<(const Message &rhs) const
{
return m_message_type < rhs.m_message_type;
} // operator()
// --------------------------------------------------------------------
/** Returns the message. */
const core::stringw & getMessage() const { return m_message; }
// --------------------------------------------------------------------
MessageQueue::MessageType getMessageType() const { return m_message_type; }
}; // class Message
// ============================================================================
/** A function class to compare messages, required for priority_queue. */
class CompareMessages
{
public:
bool operator() (const Message *a, const Message *b) const
{
return a->getMessageType() < b->getMessageType();
} // operator ()
}; // operator()
// ============================================================================
/** List of all messages. */
std::priority_queue<Message*, std::vector<Message*>,
CompareMessages> g_all_messages;
/** How long the current message has been displayed. */
float g_current_display_time = -1.0f;
/** How long the current message should be displaed. */
float g_max_display_time = -1.0f;
/** The label widget used to show the current message. */
SkinWidgetContainer *g_container = NULL;
core::recti g_area;
// ============================================================================
void createLabel(const Message *message)
{
if(!g_container)
g_container = new SkinWidgetContainer();
gui::ScalableFont *font = GUIEngine::getFont();
core::dimension2du dim = font->getDimension(message->getMessage().c_str());
g_current_display_time = 0.0f;
// Maybe make this time dependent on message length as well?
g_max_display_time = 5.0f;
int x = (UserConfigParams::m_width - dim.Width) / 2;
int y = UserConfigParams::m_height - int(1.5f*dim.Height);
g_area = irr::core::recti(x, y, x+dim.Width, y+dim.Height);
} // createLabel
// ----------------------------------------------------------------------------
/** Adds a message to the message queue.
* \param mt The MessageType of the message.
* \param message The actual message.
*/
void MessageQueue::add(MessageType mt, const core::stringw &message)
{
Message *m = new Message(mt, message);
if(g_all_messages.size()==0)
{
createLabel(m);
}
g_all_messages.push(m);
} // add
// ----------------------------------------------------------------------------
/** Update function called from the GUIEngine to handle displaying of the
* messages. It will make sure that each message is shown for a certain
* amount of time, before it is discarded and the next message (if any)
* is displayed.
* \param dt Time step size.
*/
void MessageQueue::update(float dt)
{
if(g_all_messages.size()==0) return;
g_current_display_time += dt;
if(g_current_display_time > g_max_display_time)
{
Message *last= g_all_messages.top();
g_all_messages.pop();
delete last;
if(g_all_messages.size()==0)
{
return;
}
createLabel(g_all_messages.top());
}
Message *current = g_all_messages.top();
std::string type = current->getMessageType() == MT_ACHIEVEMENT
? "achievement-message"
: "friend-message";
GUIEngine::getSkin()->drawMessage(g_container, g_area, type);
gui::ScalableFont *font = GUIEngine::getFont();
video::SColor color(255, 0, 0, 0);
font->draw(current->getMessage(), g_area, color, true, true);
} // update
} // namespace GUIEngine
// ----------------------------------------------------------------------------

View File

@ -0,0 +1,41 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// 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_MESSAGE_QUEUE_HPP
#define HEADER_MESSAGE_QUEUE_HPP
#include "guiengine/widgets/label_widget.hpp"
#include "irrString.h"
#include <queue>
#include <vector>
using namespace irr;
namespace MessageQueue
{
/** The various message type which can be shown (which might use a
* different look. */
enum MessageType {MT_ACHIEVEMENT, MT_FRIEND};
void add(MessageType mt, const core::stringw &message);
void update(float dt);
}; // namespace GUIEngine
#endif

View File

@ -373,6 +373,20 @@ void Skin::drawBgImage()
irr_driver->getVideoDriver()->enableMaterial2D(false);
} // drawBgImage
// ----------------------------------------------------------------------------
/** Draws a background box for an in-game notification message. Example would
* be an achievement, or friends comming online.
* \param w The SkinWidgetContainer for the outline.
* \param dest The destination rectangle to use.
* \param type The type of the message (achievement or friend).
*/
void Skin::drawMessage(SkinWidgetContainer* w, const core::recti &dest,
const std::string &type)
{
drawBoxFromStretchableTexture(w, dest,
SkinConfig::m_render_params[type+"::neutral"]);
} // drawMessage
// ----------------------------------------------------------------------------
void Skin::drawBoxFromStretchableTexture(SkinWidgetContainer* w,
const core::recti &dest,

View File

@ -394,7 +394,7 @@ namespace GUIEngine
virtual const wchar_t*
getDefaultText(gui::EGUI_DEFAULT_TEXT text) const;
virtual gui::IGUIFont* getFont(gui::EGUI_DEFAULT_FONT which=
gui::EGDF_DEFAULT) const ;
gui::EGDF_DEFAULT) const;
virtual u32 getIcon (gui::EGUI_DEFAULT_ICON icon) const ;
virtual s32 getSize (gui::EGUI_DEFAULT_SIZE size) const ;
virtual gui::IGUISpriteBank * getSpriteBank () const ;
@ -409,6 +409,8 @@ namespace GUIEngine
virtual void setSpriteBank (gui::IGUISpriteBank *bank);
void drawTooltips();
void drawMessage(SkinWidgetContainer* w, const core::recti &dest,
const std::string &type);
video::ITexture* getImage(const char* name);

View File

@ -22,7 +22,7 @@
#include "achievements/achievements_manager.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "guiengine/dialog_queue.hpp"
#include "guiengine/message_queue.hpp"
#include "guiengine/screen.hpp"
#include "online/online_profile.hpp"
#include "online/profile_manager.hpp"
@ -379,11 +379,7 @@ namespace Online
message = _("%d friends are now online.",
to_notify.size());
}
NotificationDialog *dia =
new NotificationDialog(NotificationDialog::T_Friends,
message);
GUIEngine::DialogQueue::get()->pushDialog(dia, false);
OnlineProfileFriends::getInstance()->refreshFriendsList();
MessageQueue::add(MessageQueue::MT_FRIEND, message);
}
else if(went_offline)
{
@ -422,10 +418,7 @@ namespace Online
{
message = _("You have a new friend request!");
}
NotificationDialog *dia =
new NotificationDialog(NotificationDialog::T_Friends,
message);
GUIEngine::DialogQueue::get()->pushDialog(dia, false);
MessageQueue::add(MessageQueue::MT_FRIEND, message);
OnlineProfileFriends::getInstance()->refreshFriendsList();
}
}