315 lines
6.7 KiB
C++

/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
*
* 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 <set>
#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<uint32_t> playerList;
std::unordered_set<uint32_t> 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> 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<HouseTile*> HouseTileList;
typedef std::list<BedItem*> 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<Door*>& getDoors() const {
return doorSet;
}
void addBed(BedItem* bed);
const HouseBedItemList& getBeds() const {
return bedsList;
}
uint32_t getBedCount() {
return static_cast<uint32_t>(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<Door*> 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<uint32_t, House*> 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