/** * Tibia GIMUD Server - a free and open-source MMORPG server emulator * Copyright (C) 2019 Sabrehaven and Mark Samman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef FS_HOUSE_H_EB9732E7771A438F9CD0EFA8CB4C58C4 #define FS_HOUSE_H_EB9732E7771A438F9CD0EFA8CB4C58C4 #include #include "container.h" #include "housetile.h" #include "position.h" class House; class BedItem; class Player; class AccessList { public: void parseList(const std::string& list); void addPlayer(const std::string& name); void addGuild(const std::string& name); bool isInList(const Player* player); void getList(std::string& list) const; private: std::string list; std::unordered_set playerList; std::unordered_set guildList; // TODO: include ranks bool allowEveryone = false; }; class Door final : public Item { public: explicit Door(uint16_t type); // non-copyable Door(const Door&) = delete; Door& operator=(const Door&) = delete; Door* getDoor() final { return this; } const Door* getDoor() const final { return this; } House* getHouse() { return house; } //serialization Attr_ReadValue readAttr(AttrTypes_t attr, PropStream& propStream) final; void serializeAttr(PropWriteStream&) const final {} void setDoorId(uint32_t doorId) { setIntAttr(ITEM_ATTRIBUTE_DOORID, doorId); } uint32_t getDoorId() const { return getIntAttr(ITEM_ATTRIBUTE_DOORID); } bool canUse(const Player* player); void setAccessList(const std::string& textlist); bool getAccessList(std::string& list) const; void onRemoved() final; protected: void setHouse(House* house); private: House* house = nullptr; std::unique_ptr accessList; friend class House; }; enum AccessList_t { GUEST_LIST = 0x100, SUBOWNER_LIST = 0x101, }; enum AccessHouseLevel_t { HOUSE_NOT_INVITED = 0, HOUSE_GUEST = 1, HOUSE_SUBOWNER = 2, HOUSE_OWNER = 3, }; typedef std::list HouseTileList; typedef std::list HouseBedItemList; class HouseTransferItem final : public Item { public: static HouseTransferItem* createHouseTransferItem(House* house); explicit HouseTransferItem(House* house) : Item(0), house(house) {} void onTradeEvent(TradeEvents_t event, Player* owner) final; bool canTransform() const final { return false; } protected: House* house; }; class House { public: explicit House(uint32_t houseId); void addTile(HouseTile* tile); void updateDoorDescription() const; bool canEditAccessList(uint32_t listId, const Player* player); // listId special values: // GUEST_LIST guest list // SUBOWNER_LIST subowner list void setAccessList(uint32_t listId, const std::string& textlist); bool getAccessList(uint32_t listId, std::string& list) const; bool isInvited(const Player* player); AccessHouseLevel_t getHouseAccessLevel(const Player* player); bool kickPlayer(Player* player, Player* target); void setEntryPos(Position pos) { posEntry = pos; } const Position& getEntryPosition() const { return posEntry; } void setName(std::string houseName) { this->houseName = houseName; } const std::string& getName() const { return houseName; } void setOwner(uint32_t guid, bool updateDatabase = true, Player* player = nullptr); uint32_t getOwner() const { return owner; } void setPaidUntil(time_t paid) { paidUntil = paid; } time_t getPaidUntil() const { return paidUntil; } void setRent(uint32_t rent) { this->rent = rent; } uint32_t getRent() const { return rent; } void setPayRentWarnings(uint32_t warnings) { rentWarnings = warnings; } uint32_t getPayRentWarnings() const { return rentWarnings; } void setTownId(uint32_t townId) { this->townId = townId; } uint32_t getTownId() const { return townId; } uint32_t getId() const { return id; } void addDoor(Door* door); void removeDoor(Door* door); Door* getDoorByNumber(uint32_t doorId) const; Door* getDoorByPosition(const Position& pos); HouseTransferItem* getTransferItem(); void resetTransferItem(); bool executeTransfer(HouseTransferItem* item, Player* player); const HouseTileList& getTiles() const { return houseTiles; } const std::set& getDoors() const { return doorSet; } void addBed(BedItem* bed); const HouseBedItemList& getBeds() const { return bedsList; } uint32_t getBedCount() { return static_cast(std::ceil(bedsList.size() / 2.)); //each bed takes 2 sqms of space, ceil is just for bad maps } private: bool transferToDepot() const; bool transferToDepot(Player* player) const; AccessList guestList; AccessList subOwnerList; Container transfer_container{ITEM_LOCKER1}; HouseTileList houseTiles; std::set doorSet; HouseBedItemList bedsList; std::string houseName; std::string ownerName; HouseTransferItem* transferItem = nullptr; time_t paidUntil = 0; uint32_t id; uint32_t owner = 0; uint32_t rentWarnings = 0; uint32_t rent = 0; uint32_t townId = 0; Position posEntry = {}; bool isLoaded = false; }; typedef std::map HouseMap; enum RentPeriod_t { RENTPERIOD_DAILY, RENTPERIOD_WEEKLY, RENTPERIOD_MONTHLY, RENTPERIOD_YEARLY, RENTPERIOD_NEVER, }; class Houses { public: Houses() = default; ~Houses() { for (const auto& it : houseMap) { delete it.second; } } // non-copyable Houses(const Houses&) = delete; Houses& operator=(const Houses&) = delete; House* addHouse(uint32_t id) { auto it = houseMap.find(id); if (it != houseMap.end()) { return it->second; } House* house = new House(id); houseMap[id] = house; return house; } House* getHouse(uint32_t houseId) { auto it = houseMap.find(houseId); if (it == houseMap.end()) { return nullptr; } return it->second; } House* getHouseByPlayerId(uint32_t playerId); bool loadHousesXML(const std::string& filename); void payHouses(RentPeriod_t rentPeriod) const; const HouseMap& getHouses() const { return houseMap; } private: HouseMap houseMap; }; #endif