From 98db053ae7fa09a8b209dca95e4e65d00320cc0b Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Thu, 30 Jun 2016 15:08:36 +0300
Subject: Move extended stats from status window into stats.xml too.

Also add reports about failed stats loading.
---
 src/gui/windows/statuswindow.cpp   | 16 +++++++++---
 src/gui/windows/statuswindow.h     |  2 +-
 src/net/eathena/generalhandler.cpp | 35 +------------------------
 src/net/tmwa/generalhandler.cpp    | 31 +---------------------
 src/resources/db/statdb.cpp        | 53 +++++++++++++++++++++++++++++++++++---
 src/resources/db/statdb.h          |  6 +++--
 6 files changed, 69 insertions(+), 74 deletions(-)

diff --git a/src/gui/windows/statuswindow.cpp b/src/gui/windows/statuswindow.cpp
index f4ca38195..60aab8ca3 100644
--- a/src/gui/windows/statuswindow.cpp
+++ b/src/gui/windows/statuswindow.cpp
@@ -230,10 +230,12 @@ StatusWindow::StatusWindow() :
     updateLevelLabel();
 }
 
-void StatusWindow::addBasicAttributes()
+void StatusWindow::addAttributes()
 {
-    const std::vector<BasicStat> &stats = StatDb::getExtraStats();
-    FOR_EACH (std::vector<BasicStat>::const_iterator, it, stats)
+    clearAttributes();
+
+    const std::vector<BasicStat> &basicStats = StatDb::getBasicStats();
+    FOR_EACH (std::vector<BasicStat>::const_iterator, it, basicStats)
     {
         const BasicStat &stat = *it;
         addAttribute(stat.attr,
@@ -241,6 +243,14 @@ void StatusWindow::addBasicAttributes()
             stat.tag,
             Modifiable_true);
     }
+
+    const std::vector<BasicStat> &extendedStats = StatDb::getExtendedStats();
+    FOR_EACH (std::vector<BasicStat>::const_iterator, it, extendedStats)
+    {
+        const BasicStat &stat = *it;
+        addAttribute(stat.attr,
+            stat.name);
+    }
 }
 
 void StatusWindow::updateLevelLabel()
diff --git a/src/gui/windows/statuswindow.h b/src/gui/windows/statuswindow.h
index a11ea62b4..539c23a39 100644
--- a/src/gui/windows/statuswindow.h
+++ b/src/gui/windows/statuswindow.h
@@ -99,7 +99,7 @@ class StatusWindow final : public Window,
 
         void updateLevelLabel();
 
-        void addBasicAttributes();
+        void addAttributes();
 
     private:
         static std::string translateLetter(const char *const letters);
diff --git a/src/net/eathena/generalhandler.cpp b/src/net/eathena/generalhandler.cpp
index 029b7123a..1a0353dfa 100644
--- a/src/net/eathena/generalhandler.cpp
+++ b/src/net/eathena/generalhandler.cpp
@@ -197,40 +197,7 @@ void GeneralHandler::gameStarted() const
     if (!statusWindow)
         return;
 
-    // protection against double addition attributes.
-    statusWindow->clearAttributes();
-
-    statusWindow->addBasicAttributes();
-
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATK, _("Attack"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::DEF, _("Defense"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::MATK, _("M.Attack"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::MDEF, _("M.Defense"));
-    // TRANSLATORS: player stat
-    // xgettext:no-c-format
-    statusWindow->addAttribute(Attributes::HIT, _("% Accuracy"));
-    // TRANSLATORS: player stat
-    // xgettext:no-c-format
-    statusWindow->addAttribute(Attributes::FLEE, _("% Evade"));
-    // TRANSLATORS: player stat
-    // xgettext:no-c-format
-    statusWindow->addAttribute(Attributes::CRIT, _("% Critical"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATTACK_DELAY, _("Attack Delay"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::WALK_SPEED, _("Walk Delay"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATTACK_RANGE, _("Attack Range"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATTACK_SPEED, _("Damage per sec."));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::KARMA, _("Karma"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::MANNER, _("Manner"));
+    statusWindow->addAttributes();
 }
 
 void GeneralHandler::gameEnded() const
diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp
index f7515de02..a48f05cec 100644
--- a/src/net/tmwa/generalhandler.cpp
+++ b/src/net/tmwa/generalhandler.cpp
@@ -208,36 +208,7 @@ void GeneralHandler::gameStarted() const
     if (!statusWindow)
         return;
 
-    // protection against double addition attributes.
-    statusWindow->clearAttributes();
-
-    statusWindow->addBasicAttributes();
-
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATK, _("Attack"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::DEF, _("Defense"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::MATK, _("M.Attack"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::MDEF, _("M.Defense"));
-    // TRANSLATORS: player stat
-    // xgettext:no-c-format
-    statusWindow->addAttribute(Attributes::HIT, _("% Accuracy"));
-    // TRANSLATORS: player stat
-    // xgettext:no-c-format
-    statusWindow->addAttribute(Attributes::FLEE, _("% Evade"));
-    // TRANSLATORS: player stat
-    // xgettext:no-c-format
-    statusWindow->addAttribute(Attributes::CRIT, _("% Critical"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATTACK_DELAY, _("Attack Delay"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::WALK_SPEED, _("Walk Delay"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATTACK_RANGE, _("Attack Range"));
-    // TRANSLATORS: player stat
-    statusWindow->addAttribute(Attributes::ATTACK_SPEED, _("Damage per sec."));
+    statusWindow->addAttributes();
 }
 
 void GeneralHandler::gameEnded() const
diff --git a/src/resources/db/statdb.cpp b/src/resources/db/statdb.cpp
index e079d323a..ae48485bd 100644
--- a/src/resources/db/statdb.cpp
+++ b/src/resources/db/statdb.cpp
@@ -37,9 +37,10 @@ namespace
 {
     bool mLoaded = false;
     static std::vector<BasicStat> mBasicStats;
+    static std::vector<BasicStat> mExtendedStats;
 }  // namespace
 
-void StatDb::addBasicStats()
+void StatDb::addDefaultStats()
 {
     mBasicStats.push_back(BasicStat(Attributes::STR,
         "str",
@@ -67,11 +68,16 @@ void StatDb::addBasicStats()
         _("Luck")));
 }
 
-const std::vector<BasicStat> &StatDb::getExtraStats()
+const std::vector<BasicStat> &StatDb::getBasicStats()
 {
     return mBasicStats;
 }
 
+const std::vector<BasicStat> &StatDb::getExtendedStats()
+{
+    return mExtendedStats;
+}
+
 void StatDb::load()
 {
     if (mLoaded)
@@ -92,11 +98,15 @@ static void loadBasicStats(const XmlNodePtr rootNode)
     {
         if (xmlNameEqual(node, "stat"))
         {
+            const std::string name = XML::getProperty(node, "name", "");
             const int id = XML::getProperty(node, "id", 0);
             if (id <= 0 || id >= maxAttr)
+            {
+                reportAlways("Wrong id for basic stat with name %s",
+                    name.c_str());
                 continue;
+            }
             const std::string tag = XML::getProperty(node, "tag", "");
-            const std::string name = XML::getProperty(node, "name", "");
             mBasicStats.push_back(BasicStat(static_cast<AttributesT>(id),
                 tag,
                 name));
@@ -104,6 +114,28 @@ static void loadBasicStats(const XmlNodePtr rootNode)
     }
 }
 
+static void loadExtendedStats(const XmlNodePtr rootNode)
+{
+    const int maxAttr = static_cast<int>(Attributes::MAX_ATTRIBUTE);
+    for_each_xml_child_node(node, rootNode)
+    {
+        if (xmlNameEqual(node, "stat"))
+        {
+            const std::string name = XML::getProperty(node, "name", "");
+            const int id = XML::getProperty(node, "id", 0);
+            if (id <= 0 || id >= maxAttr)
+            {
+                reportAlways("Wrong id for extended stat with name %s",
+                    name.c_str());
+                continue;
+            }
+            mExtendedStats.push_back(BasicStat(static_cast<AttributesT>(id),
+                std::string(),
+                name));
+        }
+    }
+}
+
 void StatDb::loadXmlFile(const std::string &fileName,
                          const SkipError skipError)
 {
@@ -117,7 +149,7 @@ void StatDb::loadXmlFile(const std::string &fileName,
         logger->log("StatDb: Error while loading %s!",
             fileName.c_str());
         if (skipError == SkipError_false)
-            addBasicStats();
+            addDefaultStats();
         return;
     }
 
@@ -134,6 +166,19 @@ void StatDb::loadXmlFile(const std::string &fileName,
         {
             loadBasicStats(node);
         }
+        else if (xmlNameEqual(node, "extended"))
+        {
+            loadExtendedStats(node);
+        }
+    }
+    if (skipError == SkipError_false)
+    {
+        if (mBasicStats.empty() &&
+            mExtendedStats.empty())
+        {
+            reportAlways("StatDb: no stats found");
+            addDefaultStats();
+        }
     }
 }
 
diff --git a/src/resources/db/statdb.h b/src/resources/db/statdb.h
index 5a5d3920a..d9aaf1568 100644
--- a/src/resources/db/statdb.h
+++ b/src/resources/db/statdb.h
@@ -39,9 +39,11 @@ namespace StatDb
     void loadXmlFile(const std::string &fileName,
                      const SkipError skipError);
 
-    void addBasicStats();
+    void addDefaultStats();
 
-    const std::vector<BasicStat> &getExtraStats();
+    const std::vector<BasicStat> &getBasicStats();
+
+    const std::vector<BasicStat> &getExtendedStats();
 }  // namespace StatDb
 
 #endif  // RESOURCES_DB_STATDB_H
-- 
cgit v1.2.3-70-g09d2