ManaPlus
npcdialogdb.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2011-2019 The ManaPlus Developers
4  *
5  * This file is part of The ManaPlus Client.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
22 
23 #include "configuration.h"
24 
25 #include "resources/beingcommon.h"
27 
28 #include "utils/checkutils.h"
29 #include "utils/dtor.h"
30 
31 #include "debug.h"
32 
33 namespace
34 {
35  bool mLoaded = false;
37 } // namespace
38 
40 {
41  if (mLoaded)
42  unload();
43 
44  logger->log1("Loading npc dialog database...");
45  loadXmlFile(paths.getStringValue("npcDialogsFile"), SkipError_false);
46  loadXmlFile(paths.getStringValue("npcDialogsPatchFile"), SkipError_true);
47  loadXmlDir("npcDialogsPatchDir", loadXmlFile)
48 
49  mLoaded = true;
50 }
51 
52 static void loadNpcDialogMenu(NpcDialogInfo *const dialog,
53  XmlNodeConstPtrConst node)
54 {
55  for_each_xml_child_node(childNode, node)
56  {
57  if (!xmlTypeEqual(childNode, XML_ELEMENT_NODE))
58  continue;
59 
60  if (xmlNameEqual(childNode, "button"))
61  {
62  const std::string name = XML::getProperty(childNode, "name", "");
63  const std::string value = XML::getProperty(childNode, "value", "");
64  if (value.empty())
65  continue;
66 
67  NpcButtonInfo *const button = new NpcButtonInfo;
68  button->x = XML::getIntProperty(
69  childNode, "x", 0, 0, 10000);
70  button->y = XML::getIntProperty(
71  childNode, "y", 0, 0, 10000);
72  button->name = name;
73  button->value = value;
74  button->image = XML::getProperty(childNode, "image", "");
75  if (button->name.empty() && button->image.empty())
76  {
77  reportAlways("Error: npc button without name or image")
78  delete button;
79  continue;
80  }
82  childNode, "imageWidth", 16, 1, 1000);
84  childNode, "imageHeight", 16, 1, 1000);
85  dialog->menu.buttons.push_back(button);
86  }
87  else if (xmlNameEqual(childNode, "image"))
88  {
89  const std::string image = XML::getProperty(childNode, "image", "");
90  if (image.empty())
91  {
92  reportAlways("Error: no image attribute found in image tag.")
93  continue;
94  }
95  NpcImageInfo *const imageInfo = new NpcImageInfo;
96  imageInfo->name = image;
97  imageInfo->x = XML::getIntProperty(
98  childNode, "x", 0, 0, 10000);
99  imageInfo->y = XML::getIntProperty(
100  childNode, "y", 0, 0, 10000);
101  dialog->menu.images.push_back(imageInfo);
102  }
103  else if (xmlNameEqual(childNode, "text"))
104  {
105  const std::string text = XML::getProperty(childNode, "text", "");
106  if (text.empty())
107  {
108  reportAlways("Error: no text attribute found in text tag.")
109  continue;
110  }
111  NpcTextInfo *const textInfo = new NpcTextInfo;
112  textInfo->text = text;
113  textInfo->x = XML::getIntProperty(
114  childNode, "x", 0, 0, 10000);
115  textInfo->y = XML::getIntProperty(
116  childNode, "y", 0, 0, 10000);
117  textInfo->width = XML::getIntProperty(
118  childNode, "width", 20, 10, 10000);
119  textInfo->height = XML::getIntProperty(
120  childNode, "height", 20, 10, 10000);
121  dialog->menu.texts.push_back(textInfo);
122  }
123  }
124 }
125 
126 static void loadNpcDialogInventory(NpcDialogInfo *const dialog,
127  XmlNodePtrConst node)
128 {
129  dialog->inventory.cell = XML::getProperty(node, "cell", "");
131  node, "columns", 10000, 1, 10000);
132 }
133 
134 static void loadNpcDialog(NpcDialogInfo *const dialog,
135  XmlNodeConstPtrConst node)
136 {
137  for_each_xml_child_node(childNode, node)
138  {
139  if (xmlNameEqual(childNode, "menu"))
140  {
141  loadNpcDialogMenu(dialog, childNode);
142  }
143  else if (xmlNameEqual(childNode, "inventory"))
144  {
145  loadNpcDialogInventory(dialog, childNode);
146  }
147  }
148 }
149 
150 void NpcDialogDB::loadXmlFile(const std::string &fileName,
151  const SkipError skipError)
152 {
153  XML::Document *const doc = new XML::Document(fileName,
155  skipError);
156 
157  XmlNodeConstPtrConst root = doc->rootNode();
158  if (root == nullptr)
159  {
160  delete doc;
161  return;
162  }
163 
164  for_each_xml_child_node(node, root)
165  {
166  if (xmlNameEqual(node, "dialog"))
167  {
168  const std::string name = XML::getProperty(node, "name", "");
169  if (name.empty())
170  continue;
171 
172  deleteDialog(name);
173  NpcDialogInfo *const dialog = new NpcDialogInfo;
174  dialog->name = name;
175  dialog->hideText = XML::getBoolProperty(
176  node, "hideText", false);
177  mDialogs[name] = dialog;
178  loadNpcDialog(dialog, node);
179  }
180  else if (xmlNameEqual(node, "include"))
181  {
182  const std::string name = XML::getProperty(node, "name", "");
183  if (!name.empty())
184  loadXmlFile(name, skipError);
185  continue;
186  }
187  }
188 
189  delete doc;
190 }
191 
192 void NpcDialogDB::deleteDialog(const std::string &name)
193 {
194  const DialogsIter it = mDialogs.find(name);
195  if (it == mDialogs.end())
196  return;
197 
198  NpcDialogInfo *dialog = (*it).second;
199  delete_all(dialog->menu.buttons);
200  delete_all(dialog->menu.images);
201  delete_all(dialog->menu.texts);
202  mDialogs.erase(it);
203  delete dialog;
204 }
205 
207 {
208  logger->log1("Unloading npc dialog database...");
209 
211  {
212  NpcDialogInfo *dialog = (*it).second;
213  delete_all(dialog->menu.buttons);
214  delete_all(dialog->menu.images);
215  delete_all(dialog->menu.texts);
216  delete dialog;
217  }
218  mDialogs.clear();
219 
220  mLoaded = false;
221 }
222 
223 NpcDialogInfo *NpcDialogDB::getDialog(const std::string &name)
224 {
225  const DialogsIter it = mDialogs.find(name);
226  if (it == mDialogs.end())
227  return nullptr;
228  return (*it).second;
229 }
NpcDialogDB::unload
void unload()
Definition: npcdialogdb.cpp:206
SkipError
bool SkipError
Definition: skiperror.h:29
NpcDialogMenuInfo::texts
std::vector< NpcTextInfo * > texts
Definition: npcdialogmenuinfo.h:45
reportAlways
#define reportAlways(...)
Definition: checkutils.h:252
NpcDialogDB::deleteDialog
void deleteDialog(const std::string &name)
Definition: npcdialogdb.cpp:192
NpcTextInfo::width
int width
Definition: npctextinfo.h:44
SkipError_true
const bool SkipError_true
Definition: skiperror.h:29
NpcDialogInfo::menu
NpcDialogMenuInfo menu
Definition: npcdialoginfo.h:41
NpcImageInfo
Definition: npcimageinfo.h:28
NpcDialogDB::loadXmlFile
void loadXmlFile(const std::string &fileName, const SkipError skipError)
Definition: npcdialogdb.cpp:150
NpcDialogInfo::hideText
bool hideText
Definition: npcdialoginfo.h:44
NpcButtonInfo
Definition: npcbuttoninfo.h:28
NpcButtonInfo::value
std::string value
Definition: npcbuttoninfo.h:44
Net::unload
void unload()
Definition: net.cpp:179
NpcButtonInfo::x
int x
Definition: npcbuttoninfo.h:46
NpcTextInfo
Definition: npctextinfo.h:28
NpcButtonInfo::imageWidth
int imageWidth
Definition: npcbuttoninfo.h:48
NpcDialogInfo::name
std::string name
Definition: npcdialoginfo.h:43
paths
Configuration paths
Definition: configuration.cpp:55
NpcButtonInfo::image
std::string image
Definition: npcbuttoninfo.h:45
NpcImageInfo::x
int x
Definition: npcimageinfo.h:40
SkipError_false
const bool SkipError_false
Definition: skiperror.h:29
NpcDialogDB::load
void load()
Definition: npcdialogdb.cpp:39
anonymous_namespace{npcdialogdb.cpp}::mLoaded
bool mLoaded
Definition: npcdialogdb.cpp:35
loadNpcDialogInventory
static void loadNpcDialogInventory(NpcDialogInfo *const dialog, xmlNode *const node)
Definition: npcdialogdb.cpp:126
XML::Document
Definition: libxml.h:52
NpcButtonInfo::y
int y
Definition: npcbuttoninfo.h:47
NpcImageInfo::y
int y
Definition: npcimageinfo.h:41
XML::getIntProperty
int getIntProperty(const xmlNodePtr node, const char *const name, int def, const int min, const int max)
Definition: libxml.cpp:189
XML::getProperty
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:173
logger
Logger * logger
Definition: logger.cpp:88
NpcDialogDB::DialogsIter
Dialogs::iterator DialogsIter
Definition: npcdialogdb.h:56
fileName
std::string fileName
Definition: testmain.cpp:38
XML::getBoolProperty
bool getBoolProperty(const xmlNodePtr node, const char *const name, const bool def)
Definition: libxml.cpp:268
loadXmlDir
#define loadXmlDir(name, function)
Definition: beingcommon.h:38
NpcImageInfo::name
std::string name
Definition: npcimageinfo.h:39
checkutils.h
NpcTextInfo::y
int y
Definition: npctextinfo.h:43
beingcommon.h
NpcInventoryInfo::cell
std::string cell
Definition: npcinventoryinfo.h:38
NpcInventoryInfo::columns
int columns
Definition: npcinventoryinfo.h:39
NpcButtonInfo::name
std::string name
Definition: npcbuttoninfo.h:43
loadXmlFile
static void loadXmlFile(const std::string &file, const std::string &name, BadgesInfos &arr, const SkipError skipError)
Definition: badgesdb.cpp:42
UseVirtFs_true
const bool UseVirtFs_true
Definition: usevirtfs.h:29
NpcDialogInfo
Definition: npcdialoginfo.h:29
Configuration::getStringValue
std::string getStringValue(const std::string &key) const
Definition: configuration.cpp:487
NpcDialogInfo::inventory
NpcInventoryInfo inventory
Definition: npcdialoginfo.h:42
loadNpcDialog
static void loadNpcDialog(NpcDialogInfo *const dialog, const xmlNode *const node)
Definition: npcdialogdb.cpp:134
anonymous_namespace{npcdialogdb.cpp}::mDialogs
NpcDialogDB::Dialogs mDialogs
Definition: npcdialogdb.cpp:36
Logger::log1
void log1(const char *const log_text)
Definition: logger.cpp:237
NpcTextInfo::height
int height
Definition: npctextinfo.h:45
NpcButtonInfo::imageHeight
int imageHeight
Definition: npcbuttoninfo.h:49
delete_all
void delete_all(Container &c)
Definition: dtor.h:55
NpcDialogDB::getDialog
NpcDialogInfo * getDialog(const std::string &name)
Definition: npcdialogdb.cpp:223
NpcTextInfo::x
int x
Definition: npctextinfo.h:42
NpcDialogMenuInfo::images
std::vector< NpcImageInfo * > images
Definition: npcdialogmenuinfo.h:44
NpcDialogMenuInfo::buttons
std::vector< NpcButtonInfo * > buttons
Definition: npcdialogmenuinfo.h:43
configuration.h
XML::Document::rootNode
xmlNodePtr rootNode()
Definition: libxml.cpp:168
loadNpcDialogMenu
static void loadNpcDialogMenu(NpcDialogInfo *const dialog, const xmlNode *const node)
Definition: npcdialogdb.cpp:52
NpcTextInfo::text
std::string text
Definition: npctextinfo.h:41
npcdialogdb.h
NpcDialogDB::Dialogs
std::map< std::string, NpcDialogInfo * > Dialogs
Definition: npcdialogdb.h:55
dtor.h
for_each_xml_child_node
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:160
npcdialoginfo.h
FOR_EACH
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
debug.h