ManaPlus
itemxmlutils.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2014-2019 The ManaPlus Developers
4  * Copyright (C) 2019-2021 Andrei Karas
5  *
6  * This file is part of The ManaPlus Client.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "utils/itemxmlutils.h"
23 
24 #include "utils/checkutils.h"
25 #include "utils/foreach.h"
26 #include "utils/stringutils.h"
28 
30 
31 #include "debug.h"
32 
33 static void convertSignedValue(std::string &outStr,
34  const std::string &srcStr)
35 {
36  if (!srcStr.empty() && srcStr[0] != '-')
37  outStr = std::string("+").append(srcStr);
38  else
39  outStr = srcStr;
40 }
41 
42 static bool readField(ItemFieldInfos::const_iterator it,
43  XmlNodeConstPtr node,
44  std::string &combined)
45 {
46  const std::string fieldName = (*it).first;
47  const ItemFieldType *const field = (*it).second;
48 
49  std::string value = XML::getProperty(node,
50  fieldName.c_str(),
51  "");
52  if (value.empty())
53  return false;
54 
55  StringVect tokens;
56  splitToStringVector(tokens,
57  value,
58  '-');
59  if (tokens.size() > 1)
60  {
61  std::string value1;
62  std::string value2;
63  if (field->sign)
64  {
65  convertSignedValue(value1, tokens[0]);
66  convertSignedValue(value2, tokens[1]);
67  }
68  else
69  {
70  value1 = tokens[0];
71  value2 = tokens[1];
72  }
73  value = strprintf("%s - %s",
74  value1.c_str(),
75  value2.c_str());
76  }
77  else
78  {
79  if (field->sign)
80  convertSignedValue(value, value);
81  }
82  const std::string format = translator->getStr(field->description);
83  combined = strprintf(format.c_str(),
84  value.c_str());
85  return true;
86 }
87 
88 void readItemStatsString(std::string &effect,
89  XmlNodeConstPtr node,
90  const ItemFieldInfos &fields)
91 {
92  if (translator == nullptr)
93  {
94  reportAlways("called readItemStatsString without translator")
95  return;
96  }
97 
98  FOR_EACH (ItemFieldInfos::const_iterator, it, fields)
99  {
100  std::string field;
101  if (!readField(it, node, field))
102  continue;
103  if (!effect.empty())
104  effect.append(" / ");
105  effect.append(field);
106  }
107 }
108 
109 void readItemStatsVector(STD_VECTOR<std::string> &effect,
110  XmlNodeConstPtr node,
111  const ItemFieldInfos &fields)
112 {
113  if (translator == nullptr)
114  {
115  reportAlways("called readItemStatsVector without translator")
116  return;
117  }
118 
119  FOR_EACH (ItemFieldInfos::const_iterator, it, fields)
120  {
121  std::string field;
122  if (!readField(it, node, field))
123  continue;
124  effect.push_back(field);
125  }
126 }
#define reportAlways(...)
Definition: checkutils.h:253
const std::string getStr(const std::string &str)
Definition: podict.cpp:45
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
std::map< std::string, ItemFieldType * > ItemFieldInfos
void readItemStatsVector(std::vector< std::string > &effect, const xmlNodePtr node, const ItemFieldInfos &fields)
static bool readField(ItemFieldInfos::const_iterator it, const xmlNodePtr node, std::string &combined)
void readItemStatsString(std::string &effect, const xmlNodePtr node, const ItemFieldInfos &fields)
static void convertSignedValue(std::string &outStr, const std::string &srcStr)
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:174
PoDict * translator
Definition: podict.cpp:28
std::string strprintf(const char *const format,...)
void splitToStringVector(StringVect &tokens, const std::string &text, const char separator)
std::vector< std::string > StringVect
Definition: stringvector.h:29
const bool sign
Definition: itemfieldtype.h:43
const std::string description
Definition: itemfieldtype.h:42