From 1ade00462dda1d860136c21ac69f67d54b7aaa6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=9C=E8=8C=82=E6=A3=AE?=
<35170687+dumaosen@users.noreply.github.com>
Date: Wed, 18 Dec 2019 09:23:06 +0800
Subject: [PATCH] Simple tips manager (#4146)
---
data/skins/coal/stkskin.xml | 3 +
data/skins/forest/stkskin.xml | 3 +
data/skins/ocean/stkskin.xml | 3 +
data/skins/peach/stkskin.xml | 3 +
data/skins/ruby/stkskin.xml | 3 +
data/tips.xml | 21 ++++++
src/guiengine/engine.cpp | 24 +++++--
src/guiengine/engine.hpp | 2 +-
src/main.cpp | 7 +-
src/states_screens/race_result_gui.cpp | 5 ++
src/tips/tips_manager.cpp | 90 ++++++++++++++++++++++++++
src/tips/tips_manager.hpp | 75 +++++++++++++++++++++
12 files changed, 233 insertions(+), 6 deletions(-)
create mode 100644 data/tips.xml
create mode 100644 src/tips/tips_manager.cpp
create mode 100644 src/tips/tips_manager.hpp
diff --git a/data/skins/coal/stkskin.xml b/data/skins/coal/stkskin.xml
index e39217320..78e111290 100644
--- a/data/skins/coal/stkskin.xml
+++ b/data/skins/coal/stkskin.xml
@@ -292,6 +292,9 @@ when the border that intersect at this corner are enabled.
+
+
+
diff --git a/data/skins/forest/stkskin.xml b/data/skins/forest/stkskin.xml
index f30ef7665..c1f3b06d8 100644
--- a/data/skins/forest/stkskin.xml
+++ b/data/skins/forest/stkskin.xml
@@ -292,6 +292,9 @@ when the border that intersect at this corner are enabled.
+
+
+
diff --git a/data/skins/ocean/stkskin.xml b/data/skins/ocean/stkskin.xml
index b14180968..b77eace9e 100644
--- a/data/skins/ocean/stkskin.xml
+++ b/data/skins/ocean/stkskin.xml
@@ -291,6 +291,9 @@ when the border that intersect at this corner are enabled.
+
+
+
diff --git a/data/skins/peach/stkskin.xml b/data/skins/peach/stkskin.xml
index 987706460..42531968c 100644
--- a/data/skins/peach/stkskin.xml
+++ b/data/skins/peach/stkskin.xml
@@ -309,6 +309,9 @@ all types of ttf.
+
+
+
diff --git a/data/skins/ruby/stkskin.xml b/data/skins/ruby/stkskin.xml
index 04bb8955e..5bd9d815d 100644
--- a/data/skins/ruby/stkskin.xml
+++ b/data/skins/ruby/stkskin.xml
@@ -290,6 +290,9 @@ when the border that intersect at this corner are enabled.
+
+
+
diff --git a/data/tips.xml b/data/tips.xml
new file mode 100644
index 000000000..48945e9ab
--- /dev/null
+++ b/data/tips.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp
index d9122d83d..64f66e5d6 100644
--- a/src/guiengine/engine.cpp
+++ b/src/guiengine/engine.cpp
@@ -684,6 +684,7 @@ namespace GUIEngine
#include "modes/cutscene_world.hpp"
#include "modes/world.hpp"
#include "states_screens/race_gui_base.hpp"
+#include "tips/tips_manager.hpp"
#include "utils/debug.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@@ -1357,10 +1358,14 @@ namespace GUIEngine
// -----------------------------------------------------------------------
std::vector g_loading_icons;
+ core::stringw g_tips_string;
- void renderLoading(bool clearIcons, bool launching)
+ void renderLoading(bool clearIcons, bool launching, bool update_tips)
{
#ifndef SERVER_ONLY
+ if(update_tips)
+ g_tips_string = _("Tip: ") + TipsManager::get()->getTip("general");
+
if (clearIcons) g_loading_icons.clear();
g_skin->drawBgImage();
@@ -1382,6 +1387,10 @@ namespace GUIEngine
const int screen_w = frame_size.Width;
const int screen_h = frame_size.Height;
+ // used in drawing tips
+ const int text_height = getFontHeight() * 1.2f;
+ const int y_from = screen_h - text_height * 0.3f;
+
const core::rect< s32 > dest_area =
core::rect< s32 >(screen_w/2 - stretched_size/2,
screen_h/2 - stretched_size/2,
@@ -1404,11 +1413,18 @@ namespace GUIEngine
SColor(255,255,255,255),
true/* center h */, false /* center v */ );
+ // Draw a tip during loading
+ core::rect tipRect(core::position2d(0, y_from - text_height),
+ core::dimension2d(screen_w, text_height));
+ GL32_draw2DRectangle(Skin::getColor("tips_background::neutral"), tipRect);
+ Private::g_font->draw(g_tips_string.c_str(), tipRect, Skin::getColor("brighttext::neutral"),
+ true /* hcenter */, true /* vcenter */);
+
const int icon_count = (int)g_loading_icons.size();
- const int icon_size = (int)(std::min(screen_w, screen_h) / 10.0f);
+ const int icon_size = (int)(std::min(screen_w, screen_h) / 12.0f);
const int ICON_MARGIN = 6;
int x = ICON_MARGIN;
- int y = screen_h - icon_size - ICON_MARGIN;
+ int y = y_from - icon_size - ICON_MARGIN - text_height * 1.2f;
for (int n=0; ngetVideoDriver()
->beginScene(true, true, video::SColor(255,100,101,140));
- renderLoading(false, true);
+ renderLoading(false, true, false);
g_device->getVideoDriver()->endScene();
}
else
diff --git a/src/guiengine/engine.hpp b/src/guiengine/engine.hpp
index e765965c1..9ac009cf7 100644
--- a/src/guiengine/engine.hpp
+++ b/src/guiengine/engine.hpp
@@ -232,7 +232,7 @@ namespace GUIEngine
void render(float dt, bool is_loading = false);
/** \brief renders a "loading" screen */
- void renderLoading(bool clearIcons = true, bool launching = false);
+ void renderLoading(bool clearIcons = true, bool launching = false, bool update_tips = true);
/** \brief to spice up a bit the loading icon : add icons to the loading screen */
void addLoadingIcon(irr::video::ITexture* icon);
diff --git a/src/main.cpp b/src/main.cpp
index a682ced37..d5512851b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -197,6 +197,7 @@
#include "guiengine/engine.hpp"
#include "guiengine/event_handler.hpp"
#include "guiengine/dialog_queue.hpp"
+#include "guiengine/message_queue.hpp"
#include "input/device_manager.hpp"
#include "input/input_manager.hpp"
#include "input/keyboard_device.hpp"
@@ -243,6 +244,7 @@
#include "states_screens/options/user_screen.hpp"
#include "states_screens/dialogs/init_android_dialog.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
+#include "tips/tips_manager.hpp"
#include "tracks/arena_graph.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
@@ -1792,7 +1794,7 @@ void initRest()
GUIEngine::init(device, driver, StateManager::get());
- GUIEngine::renderLoading(true, true);
+ GUIEngine::renderLoading(true, true, false);
input_manager = new InputManager();
// Get into menu mode initially.
input_manager->setMode(InputManager::MENU);
@@ -2025,6 +2027,9 @@ int main(int argc, char *argv[])
// ServerConfig will use stk_config for server version testing
stk_config->load(file_manager->getAsset("stk_config.xml"));
bool no_graphics = !CommandLine::has("--graphical-server");
+
+ TipsManager::create();
+
// Load current server config first, if any option is specified than
// override it later
// Disable sound if found server-config or wan/lan server name
diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp
index 68e3d943b..2b92ce562 100644
--- a/src/states_screens/race_result_gui.cpp
+++ b/src/states_screens/race_result_gui.cpp
@@ -60,10 +60,12 @@
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/online/networking_lobby.hpp"
#include "states_screens/race_setup_screen.hpp"
+#include "tips/tips_manager.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
+
#include
/** Constructor, initialises internal data structures.
@@ -141,6 +143,9 @@ void RaceResultGUI::init()
m_start_track = 0;
m_end_track = (int)tracks.size();
}
+
+ core::stringw tips_string = _("Tip: ") + TipsManager::get()->getTip("race");
+ MessageQueue::add(MessageQueue::MT_GENERIC, tips_string);
} // init
//-----------------------------------------------------------------------------
diff --git a/src/tips/tips_manager.cpp b/src/tips/tips_manager.cpp
new file mode 100644
index 000000000..514497980
--- /dev/null
+++ b/src/tips/tips_manager.cpp
@@ -0,0 +1,90 @@
+//
+// SuperTuxKart - a fun racing game with go-kart
+// Copyright (C) 2019 dumaosen
+//
+// 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 "tips/tips_manager.hpp"
+
+#include "io/file_manager.hpp"
+#include "utils/log.hpp"
+#include "utils/random_generator.hpp"
+#include "utils/string_utils.hpp"
+#include "utils/translation.hpp"
+
+TipsManager* TipsManager::m_tips_manager = NULL;
+
+// ----------------------------------------------------------------------------
+/** Constructor, which reads data/tips.xml and stores the information
+ * in objects.
+ */
+TipsManager::TipsManager()
+{
+ const std::string file_name = file_manager->getAsset("tips.xml");
+ const XMLNode *root = file_manager->createXMLTree(file_name);
+ unsigned int num_nodes = root->getNumNodes();
+
+ for(unsigned int i = 0; i < num_nodes; i++)
+ {
+ const XMLNode *node = root->getNode(i);
+ addTipSet(node);
+ }
+
+ if(num_nodes != m_all_tip_sets.size())
+ Log::error("TipsManager",
+ "Multiple tipsets with the same id!");
+
+ delete root;
+} // TipsManager
+
+// ----------------------------------------------------------------------------
+TipsManager::~TipsManager()
+{
+ m_all_tip_sets.clear();
+} // ~TipsManager
+
+// ----------------------------------------------------------------------------
+void TipsManager::addTipSet(const XMLNode *input)
+{
+ std::string id;
+
+ if(!input->get("id", &id))
+ Log::error("TipSet",
+ "Undefined id for tipset.");
+
+ for(unsigned int n = 0; n < input->getNumNodes(); n++)
+ {
+ const XMLNode *node = input->getNode(n);
+ if (node->getName() != "tip")
+ continue; // ignore incorrect node
+
+ std::string text;
+ if(!node->get("text", &text))
+ continue; // missing text, ignore node
+
+ // Gettext is used here
+ m_all_tip_sets[id].push_back(_(text.c_str()));
+ }
+ if(m_all_tip_sets[id].size() != input->getNumNodes())
+ Log::error("TipSet",
+ "Incorrect tips for the entries of tipset \"%s\".", id.c_str());
+}
+
+// ----------------------------------------------------------------------------
+irr::core::stringw TipsManager::getTip(std::string id)
+{
+ RandomGenerator randgen;
+ return m_all_tip_sets[id][randgen.get(m_all_tip_sets[id].size())];
+} // getTipSet
diff --git a/src/tips/tips_manager.hpp b/src/tips/tips_manager.hpp
new file mode 100644
index 000000000..da53943af
--- /dev/null
+++ b/src/tips/tips_manager.hpp
@@ -0,0 +1,75 @@
+//
+// SuperTuxKart - a fun racing game with go-kart
+// Copyright (C) 2019 dumaosen
+//
+// 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_TIPS_MANAGER_HPP
+#define HEADER_TIPS_MANAGER_HPP
+
+#include "io/xml_node.hpp"
+
+#include
+#include
+#include
+#include