diff --git a/src/client/creatures.cpp b/src/client/creatures.cpp index 0a606eac..c2373767 100644 --- a/src/client/creatures.cpp +++ b/src/client/creatures.cpp @@ -83,10 +83,8 @@ void Spawn::load(TiXmlElement* node) } } -void Spawn::save(TiXmlElement*& node) +void Spawn::save(TiXmlElement* node) { - node = new TiXmlElement("spawn"); - const Position& c = getCenterPos(); node->SetAttribute("centerx", c.x); node->SetAttribute("centery", c.y); @@ -260,7 +258,7 @@ void CreatureManager::saveSpawns(const std::string& fileName) doc.LinkEndChild(root); for(auto pair : m_spawns) { - TiXmlElement* elem; + TiXmlElement* elem = new TiXmlElement("spawn"); pair.second->save(elem); root->LinkEndChild(elem); } diff --git a/src/client/creatures.h b/src/client/creatures.h index 16690a76..9b2d7bd4 100644 --- a/src/client/creatures.h +++ b/src/client/creatures.h @@ -61,7 +61,7 @@ public: protected: void load(TiXmlElement* node); - void save(TiXmlElement*& node); + void save(TiXmlElement* node); private: stdext::dynamic_storage m_attribs; diff --git a/src/client/declarations.h b/src/client/declarations.h index 8cd03fc8..b9955501 100644 --- a/src/client/declarations.h +++ b/src/client/declarations.h @@ -77,8 +77,10 @@ typedef stdext::shared_object_ptr SpawnPtr; typedef std::vector ThingList; typedef std::vector ThingTypeList; typedef std::vector ItemTypeList; -typedef std::vector HouseList; -typedef std::vector TownList; +typedef std::list HouseList; +typedef std::list TownList; +typedef std::list ItemList; +typedef std::vector ItemVector; typedef std::unordered_map TileMap; // net diff --git a/src/client/houses.cpp b/src/client/houses.cpp index 93ddc91e..4d67f3b9 100644 --- a/src/client/houses.cpp +++ b/src/client/houses.cpp @@ -28,12 +28,10 @@ HouseManager g_houses; House::House() { - m_nullTile = TilePtr(new Tile(Position())); } House::House(uint32 hId, const std::string &name, const Position &pos) { - m_nullTile = TilePtr(new Tile(Position())); setId(hId); setName(name); if(pos.isValid()) @@ -46,12 +44,27 @@ void House::setTile(const TilePtr& tile) m_tiles.insert(std::make_pair(tile->getPosition(), tile)); } -const TilePtr& House::getTile(const Position& position) +TilePtr House::getTile(const Position& position) { TileMap::const_iterator iter = m_tiles.find(position); if(iter != m_tiles.end()) return iter->second; - return m_nullTile; + return nullptr; +} + +void House::addDoor(const ItemPtr& door) +{ + if (!door) return; + door->setDoorId(m_lastDoorId); + m_doors[m_lastDoorId++] = door; +} + +void House::removeDoorById(uint32 doorId) +{ + if(doorId >= m_lastDoorId) + stdext::throw_exception(stdext::format("Failed to remove door of id %d (would overflow), max id: %d", + doorId, m_lastDoorId)); + m_doors[doorId] = nullptr; } void House::load(const TiXmlElement *elem) @@ -73,10 +86,8 @@ void House::load(const TiXmlElement *elem) setEntry(entryPos); } -void House::save(TiXmlElement*& elem) +void House::save(TiXmlElement* elem) { - elem = new TiXmlElement("house"); - elem->SetAttribute("name", getName()); elem->SetAttribute("houseid", getId()); @@ -93,7 +104,6 @@ void House::save(TiXmlElement*& elem) HouseManager::HouseManager() { - m_nullHouse = HousePtr(new House); } void HouseManager::addHouse(const HousePtr& house) @@ -109,11 +119,17 @@ void HouseManager::removeHouse(uint32 houseId) m_houses.erase(it); } -const HousePtr& HouseManager::getHouse(uint32 houseId) +HousePtr HouseManager::getHouse(uint32 houseId) +{ + auto it = findHouse(houseId); + return it != m_houses.end() ? *it : nullptr; +} + +HousePtr HouseManager::getHouseByName(std::string name) { auto it = std::find_if(m_houses.begin(), m_houses.end(), - [=] (const HousePtr& house) -> bool { return house->getId() == houseId; }); - return it != m_houses.end() ? *it : m_nullHouse; + [=] (const HousePtr& house) -> bool { return house->getName() == name; }); + return it != m_houses.end() ? *it : nullptr; } void HouseManager::load(const std::string& fileName) @@ -152,7 +168,7 @@ void HouseManager::save(const std::string& fileName) doc.LinkEndChild(root); for(auto house : m_houses) { - TiXmlElement *elem; + TiXmlElement *elem = new TiXmlElement("house"); house->save(elem); root->LinkEndChild(elem); } @@ -161,8 +177,18 @@ void HouseManager::save(const std::string& fileName) stdext::throw_exception(stdext::format("failed to save houses XML %s: %s", fileName, doc.ErrorDesc())); } +HouseList HouseManager::filterHouses(uint32 townId) +{ + HouseList ret; + for(const HousePtr& house : m_houses) + if(house->getTownId() == townId) + ret.push_back(house); + return ret; +} + HouseList::iterator HouseManager::findHouse(uint32 houseId) { return std::find_if(m_houses.begin(), m_houses.end(), [=] (const HousePtr& house) -> bool { return house->getId() == houseId; }); } + diff --git a/src/client/houses.h b/src/client/houses.h index 67f03932..2e32c291 100644 --- a/src/client/houses.h +++ b/src/client/houses.h @@ -43,10 +43,10 @@ class House : public LuaObject public: House(); House(uint32 hId, const std::string& name = "", const Position& pos=Position()); - ~House() { m_tiles.clear(); m_nullTile = nullptr; } + ~House() { m_tiles.clear(); } void setTile(const TilePtr& tile); - const TilePtr& getTile(const Position& pos); + TilePtr getTile(const Position& pos); void setName(const std::string& name) { m_attribs.set(HouseAttrName, name); } std::string getName() { return m_attribs.get(HouseAttrName); } @@ -66,14 +66,19 @@ public: void setEntry(const Position& p) { m_attribs.set(HouseAttrEntry, p); } Position getEntry() { return m_attribs.get(HouseAttrEntry); } + void addDoor(const ItemPtr& door); + void removeDoor(const ItemPtr& door) { removeDoorById(door->getDoorId()); } + void removeDoorById(uint32 doorId); + protected: void load(const TiXmlElement* elem); - void save(TiXmlElement*& elem); + void save(TiXmlElement* elem); private: stdext::packed_storage m_attribs; TileMap m_tiles; - TilePtr m_nullTile; + ItemVector m_doors; + uint32 m_lastDoorId; stdext::boolean m_isGuildHall; friend class HouseManager; @@ -85,16 +90,18 @@ public: void addHouse(const HousePtr& house); void removeHouse(uint32 houseId); - HouseList getHouseList() { return m_houses; } - const HousePtr& getHouse(uint32 houseId); - void clear() { m_houses.clear(); m_nullHouse = nullptr; } + HousePtr getHouse(uint32 houseId); + HousePtr getHouseByName(std::string name); void load(const std::string& fileName); void save(const std::string& fileName); + void clear() { m_houses.clear(); } + HouseList getHouseList() { return m_houses; } + HouseList filterHouses(uint32 townId); + private: HouseList m_houses; - HousePtr m_nullHouse; protected: HouseList::iterator findHouse(uint32 houseId); diff --git a/src/client/item.cpp b/src/client/item.cpp index 6570fc5a..7a7e884d 100644 --- a/src/client/item.cpp +++ b/src/client/item.cpp @@ -187,6 +187,10 @@ void Item::serializeItem(const OutputBinaryTreePtr& out) out->addU16(getDepotId()); } + if(isHouseDoor()) { + out->addU8(ATTR_HOUSEDOORID); + out->addU8(getDoorId()); + } uint16 aid = m_attribs.get(ATTR_ACTION_ID); uint16 uid = m_attribs.get(ATTR_UNIQUE_ID); if(aid) { diff --git a/src/client/item.h b/src/client/item.h index 79e01704..12429b2b 100644 --- a/src/client/item.h +++ b/src/client/item.h @@ -97,8 +97,6 @@ public: uint16 getServerId() { return m_serverId; } bool isValid(); - ItemPtr clone(); - void unserializeItem(const BinaryTreePtr& in); void serializeItem(const OutputBinaryTreePtr& out); @@ -111,6 +109,7 @@ public: void setActionId(uint16 actionId) { m_attribs.set(ATTR_ACTION_ID, actionId); } void setUniqueId(uint16 uniqueId) { m_attribs.set(ATTR_UNIQUE_ID, uniqueId); } + bool isHouseDoor() { return m_attribs.has(ATTR_HOUSEDOORID); } bool isDepot() { return m_attribs.has(ATTR_DEPOT_ID); } bool isContainer() { return m_attribs.has(ATTR_CONTAINER_ITEMS); } bool isDoor() { return m_attribs.has(ATTR_HOUSEDOORID); } @@ -118,6 +117,7 @@ public: bool isMoveable(); bool isGround(); + ItemPtr clone(); ItemPtr asItem() { return static_self_cast(); } bool isItem() { return true; } @@ -136,7 +136,7 @@ private: uint16 m_serverId; uint8 m_countOrSubType; stdext::packed_storage m_attribs; - std::vector m_containerItems; + ItemList m_containerItems; }; #pragma pack(pop) diff --git a/src/client/luafunctions.cpp b/src/client/luafunctions.cpp index a18dc6ca..659175b5 100644 --- a/src/client/luafunctions.cpp +++ b/src/client/luafunctions.cpp @@ -70,16 +70,19 @@ void Client::registerLuaFunctions() g_lua.bindSingletonFunction("g_things", "findItemTypeByCategory", &ThingTypeManager::findItemTypeByCategory, &g_things); g_lua.registerSingletonClass("g_houses"); - g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses); - g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses); - g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses); - g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses); - g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses); - g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses); - g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses); + g_lua.bindSingletonFunction("g_houses", "clear", &HouseManager::clear, &g_houses); + g_lua.bindSingletonFunction("g_houses", "load", &HouseManager::load, &g_houses); + g_lua.bindSingletonFunction("g_houses", "save", &HouseManager::save, &g_houses); + g_lua.bindSingletonFunction("g_houses", "getHouse", &HouseManager::getHouse, &g_houses); + g_lua.bindSingletonFunction("g_houses", "getHouseByName", &HouseManager::getHouseByName, &g_houses); + g_lua.bindSingletonFunction("g_houses", "addHouse", &HouseManager::addHouse, &g_houses); + g_lua.bindSingletonFunction("g_houses", "removeHouse", &HouseManager::removeHouse, &g_houses); + g_lua.bindSingletonFunction("g_houses", "getHouseList", &HouseManager::getHouseList, &g_houses); + g_lua.bindSingletonFunction("g_houses", "filterHouses", &HouseManager::filterHouses, &g_houses); g_lua.registerSingletonClass("g_towns"); g_lua.bindSingletonFunction("g_towns", "getTown", &TownManager::getTown, &g_towns); + g_lua.bindSingletonFunction("g_towns", "getTownByName",&TownManager::getTownByName,&g_towns); g_lua.bindSingletonFunction("g_towns", "addTown", &TownManager::addTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "removeTown", &TownManager::removeTown, &g_towns); g_lua.bindSingletonFunction("g_towns", "getTowns", &TownManager::getTowns, &g_towns); @@ -336,6 +339,7 @@ void Client::registerLuaFunctions() g_lua.registerClass(); g_lua.bindClassStaticFunction("create", []{ return HousePtr(new House); }); g_lua.bindClassMemberFunction("setId", &House::setId); + g_lua.bindClassMemberFunction("getId", &House::getId); g_lua.bindClassMemberFunction("setName", &House::setName); g_lua.bindClassMemberFunction("getName", &House::getName); g_lua.bindClassMemberFunction("setTownId", &House::setTownId); @@ -344,6 +348,9 @@ void Client::registerLuaFunctions() g_lua.bindClassMemberFunction("getTile", &House::getTile); g_lua.bindClassMemberFunction("setEntry", &House::setEntry); g_lua.bindClassMemberFunction("getEntry", &House::getEntry); + g_lua.bindClassMemberFunction("addDoor", &House::addDoor); + g_lua.bindClassMemberFunction("removeDoor", &House::removeDoor); + g_lua.bindClassMemberFunction("removeDoorById", &House::removeDoorById); g_lua.bindClassMemberFunction("setSize", &House::setSize); g_lua.bindClassMemberFunction("getSize", &House::getSize); g_lua.bindClassMemberFunction("setRent", &House::setRent); diff --git a/src/client/towns.cpp b/src/client/towns.cpp index 17d1deba..2a78ee41 100644 --- a/src/client/towns.cpp +++ b/src/client/towns.cpp @@ -58,6 +58,15 @@ const TownPtr& TownManager::getTown(uint32 townId) return m_nullTown; } +const TownPtr& TownManager::getTownByName(std::string name) +{ + auto it = std::find_if(m_towns.begin(), m_towns.end(), + [=] (const TownPtr& town) -> bool { return town->getName() == name; } ); + if(it != m_towns.end()) + return *it; + return m_nullTown; +} + TownList::iterator TownManager::findTown(uint32 townId) { return std::find_if(m_towns.begin(), m_towns.end(), diff --git a/src/client/towns.h b/src/client/towns.h index b50e4fa6..0e962381 100644 --- a/src/client/towns.h +++ b/src/client/towns.h @@ -54,6 +54,7 @@ public: void addTown(const TownPtr& town); void removeTown(uint32 townId); const TownPtr& getTown(uint32 townId); + const TownPtr& getTownByName(std::string name); TownList getTowns() { return m_towns; } void clear() { m_towns.clear(); m_nullTown = nullptr; } diff --git a/src/client/uiitem.cpp b/src/client/uiitem.cpp index bd539b9c..50af3fa0 100644 --- a/src/client/uiitem.cpp +++ b/src/client/uiitem.cpp @@ -63,8 +63,8 @@ void UIItem::drawSelf(Fw::DrawPane drawPane) g_painter->setColor(Color(231, 231, 231)); m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight); } - // debug, show item id - //m_font->drawText(stdext::to_string(m_item->getId()), m_rect, Fw::AlignBottomRight); + if(m_showId) + m_font->drawText(stdext::to_string(m_item->getServerId()), m_rect, Fw::AlignBottomRight); } drawBorder(m_rect); @@ -98,5 +98,7 @@ void UIItem::onStyleApply(const std::string& styleName, const OTMLNodePtr& style setItemVisible(node->value()); else if(node->tag() == "virtual") setVirtual(node->value()); + else if(node->tag() == "show-id") + m_showId = node->value(); } } diff --git a/src/client/uiitem.h b/src/client/uiitem.h index 7b454fd2..cb02bd02 100644 --- a/src/client/uiitem.h +++ b/src/client/uiitem.h @@ -54,6 +54,7 @@ protected: ItemPtr m_item; stdext::boolean m_virtual; stdext::boolean m_itemVisible; + stdext::boolean m_showId; }; #endif