Otclient  14/8/2020
houses.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "map.h"
24 
26 
28 
30 {
31 }
32 
33 House::House(uint32 hId, const std::string &name, const Position &pos)
34 {
35  setId(hId);
36  setName(name);
37  if(pos.isValid())
38  setEntry(pos);
39 }
40 
41 void House::setTile(const TilePtr& tile)
42 {
43  tile->setFlag(TILESTATE_HOUSE);
44  tile->setHouseId(getId());
45  m_tiles.insert(std::make_pair(tile->getPosition(), tile));
46 }
47 
49 {
50  TileMap::const_iterator iter = m_tiles.find(position);
51  if(iter != m_tiles.end())
52  return iter->second;
53  return nullptr;
54 }
55 
56 void House::addDoor(const ItemPtr& door)
57 {
58  if (!door) return;
59  door->setDoorId(m_lastDoorId);
60  m_doors[m_lastDoorId++] = door;
61 }
62 
64 {
65  if(doorId >= m_lastDoorId)
66  stdext::throw_exception(stdext::format("Failed to remove door of id %d (would overflow), max id: %d",
67  doorId, m_lastDoorId));
68  m_doors[doorId] = nullptr;
69 }
70 
71 void House::load(const TiXmlElement *elem)
72 {
73  std::string name = elem->Attribute("name");
74  if(name.empty())
75  name = stdext::format("Unnamed house #%lu", getId());
76 
77  setName(name);
78  setRent(elem->readType<uint32>("rent"));
79  setSize(elem->readType<uint32>("size"));
80  setTownId(elem->readType<uint32>("townid"));
81  m_isGuildHall = elem->readType<bool>("guildhall");
82 
83  Position entryPos;
84  entryPos.x = elem->readType<int>("entryx");
85  entryPos.y = elem->readType<int>("entryy");
86  entryPos.z = elem->readType<int>("entryz");
87  setEntry(entryPos);
88 }
89 
91 {
92  elem->SetAttribute("name", getName());
93  elem->SetAttribute("houseid", getId());
94 
95  Position entry = getEntry();
96  elem->SetAttribute("entryx", entry.x);
97  elem->SetAttribute("entryy", entry.y);
98  elem->SetAttribute("entryz", entry.z);
99 
100  elem->SetAttribute("rent", getRent());
101  elem->SetAttribute("townid", getTownId());
102  elem->SetAttribute("size", getSize());
103  elem->SetAttribute("guildhall", (int)m_isGuildHall);
104 }
105 
107 {
108 }
109 
111 {
112  if(findHouse(house->getId()) == m_houses.end())
113  m_houses.push_back(house);
114 }
115 
117 {
118  auto it = findHouse(houseId);
119  if(it != m_houses.end())
120  m_houses.erase(it);
121 }
122 
124 {
125  auto it = findHouse(houseId);
126  return it != m_houses.end() ? *it : nullptr;
127 }
128 
130 {
131  auto it = std::find_if(m_houses.begin(), m_houses.end(),
132  [=] (const HousePtr& house) -> bool { return house->getName() == name; });
133  return it != m_houses.end() ? *it : nullptr;
134 }
135 
136 void HouseManager::load(const std::string& fileName)
137 {
138  try {
139  TiXmlDocument doc;
140  doc.Parse(g_resources.readFileContents(fileName).c_str());
141  if(doc.Error())
142  stdext::throw_exception(stdext::format("failed to load '%s': %s (House XML)", fileName, doc.ErrorDesc()));
143 
144  TiXmlElement *root = doc.FirstChildElement();
145  if(!root || root->ValueTStr() != "houses")
146  stdext::throw_exception("invalid root tag name");
147 
148  for(TiXmlElement *elem = root->FirstChildElement(); elem; elem = elem->NextSiblingElement()) {
149  if(elem->ValueTStr() != "house")
150  stdext::throw_exception("invalid house tag.");
151 
152  uint32 houseId = elem->readType<uint32>("houseid");
153  HousePtr house = getHouse(houseId);
154  if(!house)
155  house = HousePtr(new House(houseId)), addHouse(house);
156 
157  house->load(elem);
158  }
159  } catch(std::exception& e) {
160  g_logger.error(stdext::format("Failed to load '%s': %s", fileName, e.what()));
161  }
162  sort();
163 }
164 
165 void HouseManager::save(const std::string& fileName)
166 {
167  try {
168  TiXmlDocument doc;
169  doc.SetTabSize(2);
170 
171  TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", "");
172  doc.LinkEndChild(decl);
173 
174  TiXmlElement* root = new TiXmlElement("houses");
175  doc.LinkEndChild(root);
176 
177  for(auto house : m_houses) {
178  TiXmlElement *elem = new TiXmlElement("house");
179  house->save(elem);
180  root->LinkEndChild(elem);
181  }
182 
183  if(!doc.SaveFile("data"+fileName))
184  stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc()));
185  } catch(std::exception& e) {
186  g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
187  }
188 }
189 
191 {
192  HouseList ret;
193  for(const HousePtr& house : m_houses)
194  if(house->getTownId() == townId)
195  ret.push_back(house);
196  return ret;
197 }
198 
199 HouseList::iterator HouseManager::findHouse(uint32 houseId)
200 {
201  return std::find_if(m_houses.begin(), m_houses.end(),
202  [=] (const HousePtr& house) -> bool { return house->getId() == houseId; });
203 }
204 
206 {
207  m_houses.sort([] (const HousePtr& lhs, const HousePtr& rhs) { return lhs->getName() < rhs->getName(); });
208 }
209 
210 /* vim: set ts=4 sw=4 et: */
HouseList
std::list< HousePtr > HouseList
Definition: declarations.h:83
TiXmlNode::NextSiblingElement
const TiXmlElement * NextSiblingElement() const
Definition: tinyxml.cpp:476
HouseManager::findHouse
HouseList::iterator findHouse(uint32 houseId)
Definition: houses.cpp:199
Position::x
int x
Definition: position.h:243
Tile::setHouseId
void setHouseId(uint32 hid)
Definition: tile.h:122
House::getTownId
uint32 getTownId()
Definition: houses.h:58
Position::isValid
bool isValid() const
Definition: position.h:182
uint32
uint32_t uint32
Definition: types.h:35
HouseManager::sort
void sort()
Definition: houses.cpp:205
TiXmlNode::LinkEndChild
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Definition: tinyxml.cpp:186
House::setName
void setName(const std::string &name)
Definition: houses.h:51
TiXmlDocument::ErrorDesc
const char * ErrorDesc() const
Contains a textual (english) description of the error if one occurs.
Definition: tinyxml.h:1380
TiXmlDocument::Parse
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Definition: tinyxmlparser.cpp:708
TiXmlDeclaration
Definition: tinyxml.h:1202
TiXmlNode::ValueTStr
const TIXML_STRING & ValueTStr() const
Definition: tinyxml.h:504
resourcemanager.h
Logger::error
void error(const std::string &what)
Definition: logger.h:54
Tile::getPosition
const Position & getPosition()
Definition: tile.h:87
House::getName
std::string getName()
Definition: houses.h:52
Position::y
int y
Definition: position.h:244
stdext::format
std::string format()
Definition: format.h:82
HouseManager::load
void load(const std::string &fileName)
Definition: houses.cpp:136
Position::z
short z
Definition: position.h:245
TiXmlElement::Attribute
std::string Attribute(const std::string &name) const
Definition: tinyxml.cpp:558
House::addDoor
void addDoor(const ItemPtr &door)
Definition: houses.cpp:56
House::setTownId
void setTownId(uint32 tid)
Definition: houses.h:57
TiXmlDocument::SetTabSize
void SetTabSize(int _tabsize)
Definition: tinyxml.h:1421
g_resources
ResourceManager g_resources
Definition: resourcemanager.cpp:32
HouseManager::getHouse
HousePtr getHouse(uint32 houseId)
Definition: houses.cpp:123
g_logger
Logger g_logger
Definition: logger.cpp:35
House::getRent
uint32 getRent()
Definition: houses.h:64
TiXmlDocument::SaveFile
bool SaveFile() const
Save a file using the current document value. Returns true if successful.
Definition: tinyxml.cpp:763
TiXmlDocument
Definition: tinyxml.h:1310
House::setTile
void setTile(const TilePtr &tile)
Definition: houses.cpp:41
House::setRent
void setRent(uint32 r)
Definition: houses.h:63
Position
Definition: position.h:33
TiXmlNode::FirstChildElement
const TiXmlElement * FirstChildElement() const
Convenience function to get through elements.
Definition: tinyxml.cpp:446
House::save
void save(TiXmlElement *elem)
Definition: houses.cpp:90
HouseManager::addHouse
void addHouse(const HousePtr &house)
Definition: houses.cpp:110
Tile::setFlag
void setFlag(uint32 flag)
Definition: tile.h:117
House::setId
void setId(uint32 hId)
Definition: houses.h:54
HousePtr
stdext::shared_object_ptr< House > HousePtr
Definition: declarations.h:75
TiXmlElement::SetAttribute
void SetAttribute(const std::string &name, const std::string &_value)
Definition: tinyxml.cpp:594
map.h
TILESTATE_HOUSE
@ TILESTATE_HOUSE
Definition: tile.h:44
House::removeDoorById
void removeDoorById(uint32 doorId)
Definition: houses.cpp:63
Item::setDoorId
void setDoorId(uint8 doorId)
Definition: item.h:109
HouseManager::HouseManager
HouseManager()
Definition: houses.cpp:106
HouseManager::getHouseByName
HousePtr getHouseByName(std::string name)
Definition: houses.cpp:129
TiXmlElement::readType
T readType(const std::string &str) const
Definition: tinyxml.h:953
House::getSize
uint32 getSize()
Definition: houses.h:61
stdext::throw_exception
void throw_exception(const std::string &what)
Throws a generic exception.
Definition: exception.h:43
HouseManager::filterHouses
HouseList filterHouses(uint32 townId)
Definition: houses.cpp:190
House::getEntry
Position getEntry()
Definition: houses.h:67
ResourceManager::readFileContents
std::string readFileContents(const std::string &fileName)
Definition: resourcemanager.cpp:185
House
Definition: houses.h:41
House::getTile
TilePtr getTile(const Position &pos)
Definition: houses.cpp:48
House::load
void load(const TiXmlElement *elem)
Definition: houses.cpp:71
House::House
House()
Definition: houses.cpp:29
stdext::shared_object_ptr< Tile >
House::setSize
void setSize(uint32 s)
Definition: houses.h:60
TiXmlElement
Definition: tinyxml.h:943
HouseManager
Definition: houses.h:87
House::setEntry
void setEntry(const Position &p)
Definition: houses.h:66
TiXmlDocument::Error
bool Error() const
Definition: tinyxml.h:1377
House::getId
uint32 getId()
Definition: houses.h:55
HouseManager::removeHouse
void removeHouse(uint32 houseId)
Definition: houses.cpp:116
g_houses
HouseManager g_houses
Definition: houses.cpp:27
HouseManager::save
void save(const std::string &fileName)
Definition: houses.cpp:165