ManaPlus
npcdb.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2008-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "resources/db/npcdb.h"
24 
25 #include "configuration.h"
26 
27 #include "resources/beingcommon.h"
28 #include "resources/beinginfo.h"
29 
30 #include "resources/db/unitsdb.h"
31 
33 
34 #include "utils/cast.h"
35 #include "utils/checkutils.h"
36 #include "utils/dtor.h"
37 #include "utils/gettext.h"
38 
39 #include "debug.h"
40 
41 namespace
42 {
44  bool mLoaded = false;
45 } // namespace
46 
48 {
49  if (mLoaded)
50  unload();
51 
52  logger->log1("Initializing NPC database...");
53 
56  loadXmlDir("npcsPatchDir", loadXmlFile)
57 
58  mLoaded = true;
59 }
60 
61 void NPCDB::loadXmlFile(const std::string &fileName,
62  const SkipError skipError)
63 {
64  XML::Document doc(fileName, UseVirtFs_true, skipError);
65  XmlNodeConstPtrConst rootNode = doc.rootNode();
66 
67  if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "npcs"))
68  {
69  logger->log("NPC Database: Error while loading %s!",
70  paths.getStringValue("npcsFile").c_str());
71  mLoaded = true;
72  return;
73  }
74 
75  // iterate <npc>s
76  for_each_xml_child_node(npcNode, rootNode)
77  {
78  if (xmlNameEqual(npcNode, "include"))
79  {
80  const std::string name = XML::getProperty(npcNode, "name", "");
81  if (!name.empty())
82  loadXmlFile(name, skipError);
83  continue;
84  }
85 
86  if (!xmlNameEqual(npcNode, "npc"))
87  continue;
88 
90  npcNode, "id", 0), BeingTypeId);
91  BeingInfo *currentInfo = nullptr;
92  if (id == BeingTypeId_zero)
93  {
94  reportAlways("NPC Database: NPC with missing ID in %s!",
95  paths.getStringValue("npcsFile").c_str())
96  continue;
97  }
98  else if (mNPCInfos.find(id) != mNPCInfos.end())
99  {
100  logger->log("NpcDB: Redefinition of npc ID %d", toInt(id, int));
101  currentInfo = mNPCInfos[id];
102  }
103  if (currentInfo == nullptr)
104  currentInfo = new BeingInfo;
105 
106  currentInfo->setTargetSelection(XML::getBoolProperty(npcNode,
107  "targetSelection", true));
108 
109  BeingCommon::readBasicAttributes(currentInfo, npcNode, "talk");
110  BeingCommon::readWalkingAttributes(currentInfo, npcNode, 0);
111 
112  currentInfo->setDeadSortOffsetY(XML::getProperty(npcNode,
113  "deadSortOffsetY", 31));
114 
115  currentInfo->setAvatarId(fromInt(XML::getProperty(
116  npcNode, "avatar", 0), BeingTypeId));
117 
118  currentInfo->setAllowDelete(XML::getBoolProperty(npcNode,
119  "allowDelete", true));
120 
121  currentInfo->setAllowEquipment(XML::getBoolProperty(npcNode,
122  "allowEquipment", false));
123 
124  const std::string currency = XML::getProperty(npcNode,
125  "currency", "default");
126  if (UnitsDb::existsCurrency(currency) == false)
127  {
128  reportAlways("Not found currency '%s' for npc %d",
129  currency.c_str(),
130  CAST_S32(id))
131  }
132  currentInfo->setCurrency(currency);
133 
134  SpriteDisplay display;
135  for_each_xml_child_node(spriteNode, npcNode)
136  {
137  if (xmlNameEqual(spriteNode, "sprite"))
138  {
139  if (!XmlHaveChildContent(spriteNode))
140  continue;
141 
142  SpriteReference *const currentSprite = new SpriteReference;
143  currentSprite->sprite = XmlChildContent(spriteNode);
144  currentSprite->variant =
145  XML::getProperty(spriteNode, "variant", 0);
146  display.sprites.push_back(currentSprite);
147  }
148  else if (xmlNameEqual(spriteNode, "particlefx"))
149  {
150  if (!XmlHaveChildContent(spriteNode))
151  continue;
152 
153  display.particles.push_back(XmlChildContent(spriteNode));
154  }
155  else if (xmlNameEqual(spriteNode, "menu"))
156  {
157  std::string name = XML::langProperty(spriteNode, "name", "");
158  std::string command = XML::getProperty(spriteNode,
159  "command", "");
160  currentInfo->addMenu(name, command);
161  }
162  }
163 
164  currentInfo->setDisplay(display);
165  if (currentInfo->getMenu().empty())
166  {
167  // TRANSLATORS: npc context menu item
168  currentInfo->addMenu(_("Talk"), "talk 'NAME'");
169  // TRANSLATORS: npc context menu item
170  currentInfo->addMenu(_("Buy"), "buy 'NAME'");
171  // TRANSLATORS: npc context menu item
172  currentInfo->addMenu(_("Sell"), "sell 'NAME'");
173  }
174  mNPCInfos[id] = currentInfo;
175  }
176 }
177 
179 {
180  logger->log1("Unloading NPC database...");
182  mNPCInfos.clear();
183 
184  mLoaded = false;
185 }
186 
188 {
189  const BeingInfoIterator i = mNPCInfos.find(id);
190 
191  if (i == mNPCInfos.end())
192  {
193  reportAlways("NPCDB: Warning, unknown NPC ID %d requested",
194  toInt(id, int))
195  return BeingInfo::unknown;
196  }
197  return i->second;
198 }
199 
201 {
202  const BeingInfo *const info = get(id);
203  if (info == nullptr)
204  return BeingTypeId_zero;
205  return info->getAvatarId();
206 }
SkipError
bool SkipError
Definition: skiperror.h:29
UnitsDb::existsCurrency
bool existsCurrency(const std::string &name)
Definition: unitsdb.cpp:356
BeingInfos
std::map< BeingTypeId, BeingInfo * > BeingInfos
Definition: beinginfo.h:408
BeingInfo::setDisplay
void setDisplay(const SpriteDisplay &display)
Definition: beinginfo.cpp:126
reportAlways
#define reportAlways(...)
Definition: checkutils.h:252
anonymous_namespace{npcdb.cpp}::mNPCInfos
BeingInfos mNPCInfos
Definition: npcdb.cpp:43
cast.h
SkipError_true
const bool SkipError_true
Definition: skiperror.h:29
BeingInfo
Definition: beinginfo.h:52
unitsdb.h
Net::unload
void unload()
Definition: net.cpp:179
SpriteDisplay::sprites
std::vector< SpriteReference * > sprites
Definition: spritedisplay.h:46
BeingTypeId
int BeingTypeId
Definition: beingtypeid.h:29
anonymous_namespace{npcdb.cpp}::mLoaded
bool mLoaded
Definition: npcdb.cpp:44
paths
Configuration paths
Definition: configuration.cpp:55
AttributesEnum::get
AttributesT get(const std::string &key)
Definition: attributesstrings.cpp:32
SkipError_false
const bool SkipError_false
Definition: skiperror.h:29
NPCDB::getAvatarFor
BeingTypeId getAvatarFor(const BeingTypeId id)
Definition: npcdb.cpp:200
npcdb.h
BeingInfo::setCurrency
void setCurrency(const std::string &name)
Definition: beinginfo.h:352
XML::Document
Definition: libxml.h:52
toInt
#define toInt(val, name)
Definition: intdefines.h:46
XML::getProperty
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:173
BeingInfo::setAllowEquipment
void setAllowEquipment(const bool b)
Definition: beinginfo.h:323
logger
Logger * logger
Definition: logger.cpp:88
NPCDB::unload
void unload()
Definition: npcdb.cpp:178
Actions::info
bool info(InputEvent &event)
Definition: commands.cpp:56
NPCDB::loadXmlFile
void loadXmlFile(const std::string &fileName, const SkipError skipError)
Definition: npcdb.cpp:61
fileName
std::string fileName
Definition: testmain.cpp:38
SpriteReference
Definition: spritereference.h:30
XML::getBoolProperty
bool getBoolProperty(const xmlNodePtr node, const char *const name, const bool def)
Definition: libxml.cpp:268
NPCDB::get
BeingInfo * get(const BeingTypeId id)
Definition: npcdb.cpp:187
loadXmlDir
#define loadXmlDir(name, function)
Definition: beingcommon.h:38
checkutils.h
BeingInfo::setTargetSelection
void setTargetSelection(const bool n)
Definition: beinginfo.h:179
BeingTypeId_zero
const BeingTypeId BeingTypeId_zero
Definition: beingtypeid.h:29
beingcommon.h
gettext.h
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
Configuration::getStringValue
std::string getStringValue(const std::string &key) const
Definition: configuration.cpp:487
BeingInfo::getMenu
const std::vector< BeingMenuItem > & getMenu() const A_CONST
Definition: beinginfo.cpp:258
spritereference.h
SpriteDisplay
Definition: spritedisplay.h:32
XML::langProperty
std::string langProperty(const xmlNodePtr node, const char *const name, const std::string &def)
Definition: libxml.cpp:257
BeingCommon::readBasicAttributes
void readBasicAttributes(BeingInfo *const info, xmlNode *const node, const std::string &hoverCursor)
Definition: beingcommon.cpp:36
Logger::log1
void log1(const char *const log_text)
Definition: logger.cpp:237
SpriteDisplay::particles
StringVect particles
Definition: spritedisplay.h:47
delete_all
void delete_all(Container &c)
Definition: dtor.h:55
NPCDB::load
void load()
Definition: npcdb.cpp:47
BeingInfo::setDeadSortOffsetY
void setDeadSortOffsetY(const int n)
Definition: beinginfo.h:194
beinginfo.h
configuration.h
SpriteReference::variant
int variant
Definition: spritereference.h:48
BeingInfo::setAllowDelete
void setAllowDelete(const bool b)
Definition: beinginfo.h:317
BeingInfoIterator
BeingInfos::iterator BeingInfoIterator
Definition: beinginfo.h:409
fromInt
#define fromInt(val, name)
Definition: intdefines.h:45
BeingInfo::addMenu
void addMenu(const std::string &name, const std::string &command)
Definition: beinginfo.cpp:253
XML::Document::rootNode
xmlNodePtr rootNode()
Definition: libxml.cpp:168
CAST_S32
#define CAST_S32
Definition: cast.h:29
BeingCommon::readWalkingAttributes
void readWalkingAttributes(BeingInfo *const info, xmlNode *const node, const int moreBlockFlags)
Definition: beingcommon.cpp:59
dtor.h
BeingInfo::unknown
static BeingInfo * unknown
Definition: beinginfo.h:55
for_each_xml_child_node
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:160
SpriteReference::sprite
std::string sprite
Definition: spritereference.h:47
_
#define _(s)
Definition: gettext.h:34
BeingInfo::setAvatarId
void setAvatarId(const BeingTypeId id)
Definition: beinginfo.h:200
Logger::log
void log(const char *const log_text,...)
Definition: logger.cpp:268
debug.h