commit newest tfs branch only for compare

This commit is contained in:
ErikasKontenis
2020-01-02 19:39:21 +02:00
parent 0b0624a20b
commit 1f7dcd7347
160 changed files with 24900 additions and 10996 deletions

View File

@@ -1,6 +1,6 @@
/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
* The Forgotten Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 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
@@ -23,7 +23,12 @@
#include "cylinder.h"
#include "thing.h"
#include "items.h"
#include "luascript.h"
#include "tools.h"
#include <typeinfo>
#include <boost/variant.hpp>
#include <boost/lexical_cast.hpp>
#include <deque>
class Creature;
@@ -31,8 +36,8 @@ class Player;
class Container;
class Depot;
class Teleport;
class TrashHolder;
class Mailbox;
class DepotLocker;
class Door;
class MagicField;
class BedItem;
@@ -50,7 +55,6 @@ enum ITEMPROPERTY {
CONST_PROP_IMMOVABLENOFIELDBLOCKPATH,
CONST_PROP_NOFIELDBLOCKPATH,
CONST_PROP_SUPPORTHANGABLE,
CONST_PROP_UNLAY,
};
enum TradeEvents_t {
@@ -69,7 +73,7 @@ enum AttrTypes_t {
//ATTR_EXT_FILE = 2,
ATTR_TILE_FLAGS = 3,
ATTR_ACTION_ID = 4,
ATTR_MOVEMENT_ID = 5,
ATTR_UNIQUE_ID = 5,
ATTR_TEXT = 6,
ATTR_DESC = 7,
ATTR_TELE_DEST = 8,
@@ -87,22 +91,19 @@ enum AttrTypes_t {
ATTR_SLEEPERGUID = 20,
ATTR_SLEEPSTART = 21,
ATTR_CHARGES = 22,
ATTR_KEYNUMBER = 23,
ATTR_KEYHOLENUMBER = 24,
ATTR_DOORQUESTNUMBER = 25,
ATTR_DOORQUESTVALUE = 26,
ATTR_DOORLEVEL = 27,
ATTR_CHESTQUESTNUMBER = 28,
// add non-OTBM attributes after here
ATTR_CONTAINER_ITEMS = 29,
ATTR_NAME = 30,
ATTR_ARTICLE = 31,
ATTR_PLURALNAME = 32,
ATTR_WEIGHT = 33,
ATTR_ATTACK = 34,
ATTR_DEFENSE = 35,
ATTR_ARMOR = 36,
ATTR_SHOOTRANGE = 37,
ATTR_CONTAINER_ITEMS = 23,
ATTR_NAME = 24,
ATTR_ARTICLE = 25,
ATTR_PLURALNAME = 26,
ATTR_WEIGHT = 27,
ATTR_ATTACK = 28,
ATTR_DEFENSE = 29,
ATTR_EXTRADEFENSE = 30,
ATTR_ARMOR = 31,
ATTR_HITCHANCE = 32,
ATTR_SHOOTRANGE = 33,
ATTR_CUSTOM_ATTRIBUTES = 34,
ATTR_DECAYTO = 35
};
enum Attr_ReadValue {
@@ -160,53 +161,11 @@ class ItemAttributes
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_ACTIONID));
}
void setMovementID(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_MOVEMENTID, n);
void setUniqueId(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_UNIQUEID, n);
}
uint16_t getMovementId() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_MOVEMENTID));
}
void setKeyNumber(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_KEYNUMBER, n);
}
uint16_t getKeyNumber() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_KEYNUMBER));
}
void setKeyHoleNumber(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_KEYHOLENUMBER, n);
}
uint16_t getKeyHoleNumber() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_KEYHOLENUMBER));
}
void setDoorQuestNumber(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_DOORQUESTNUMBER, n);
}
uint16_t getDoorQuestNumber() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_DOORQUESTNUMBER));
}
void setDoorQuestValue(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_DOORQUESTVALUE, n);
}
uint16_t getDoorQuestValue() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_DOORQUESTVALUE));
}
void setDoorLevel(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_DOORLEVEL, n);
}
uint16_t getDoorLevel() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_DOORLEVEL));
}
void setChestQuestNumber(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_CHESTQUESTNUMBER, n);
}
uint16_t getChestQuestNumber() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_CHESTQUESTNUMBER));
uint16_t getUniqueId() const {
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_UNIQUEID));
}
void setCharges(uint16_t n) {
@@ -230,6 +189,13 @@ class ItemAttributes
return getIntAttr(ITEM_ATTRIBUTE_OWNER);
}
void setCorpseOwner(uint32_t corpseOwner) {
setIntAttr(ITEM_ATTRIBUTE_CORPSEOWNER, corpseOwner);
}
uint32_t getCorpseOwner() const {
return getIntAttr(ITEM_ATTRIBUTE_CORPSEOWNER);
}
void setDuration(int32_t time) {
setIntAttr(ITEM_ATTRIBUTE_DURATION, time);
}
@@ -247,19 +213,149 @@ class ItemAttributes
return static_cast<ItemDecayState_t>(getIntAttr(ITEM_ATTRIBUTE_DECAYSTATE));
}
protected:
inline bool hasAttribute(itemAttrTypes type) const {
struct CustomAttribute
{
typedef boost::variant<boost::blank, std::string, int64_t, double, bool> VariantAttribute;
VariantAttribute value;
CustomAttribute() : value(boost::blank()) {}
template<typename T>
explicit CustomAttribute(const T& v) : value(v) {}
template<typename T>
void set(const T& v) {
value = v;
}
template<typename T>
const T& get();
struct PushLuaVisitor : public boost::static_visitor<> {
lua_State* L;
explicit PushLuaVisitor(lua_State* L) : boost::static_visitor<>(), L(L) {}
void operator()(const boost::blank&) const {
lua_pushnil(L);
}
void operator()(const std::string& v) const {
LuaScriptInterface::pushString(L, v);
}
void operator()(bool v) const {
LuaScriptInterface::pushBoolean(L, v);
}
void operator()(const int64_t& v) const {
lua_pushnumber(L, v);
}
void operator()(const double& v) const {
lua_pushnumber(L, v);
}
};
void pushToLua(lua_State* L) const {
boost::apply_visitor(PushLuaVisitor(L), value);
}
struct SerializeVisitor : public boost::static_visitor<> {
PropWriteStream& propWriteStream;
explicit SerializeVisitor(PropWriteStream& propWriteStream) : boost::static_visitor<>(), propWriteStream(propWriteStream) {}
void operator()(const boost::blank&) const {
}
void operator()(const std::string& v) const {
propWriteStream.writeString(v);
}
template<typename T>
void operator()(const T& v) const {
propWriteStream.write<T>(v);
}
};
void serialize(PropWriteStream& propWriteStream) const {
propWriteStream.write<uint8_t>(static_cast<uint8_t>(value.which()));
boost::apply_visitor(SerializeVisitor(propWriteStream), value);
}
bool unserialize(PropStream& propStream) {
// This is hard coded so it's not general, depends on the position of the variants.
uint8_t pos;
if (!propStream.read<uint8_t>(pos)) {
return false;
}
switch (pos) {
case 1: { // std::string
std::string tmp;
if (!propStream.readString(tmp)) {
return false;
}
value = tmp;
break;
}
case 2: { // int64_t
int64_t tmp;
if (!propStream.read<int64_t>(tmp)) {
return false;
}
value = tmp;
break;
}
case 3: { // double
double tmp;
if (!propStream.read<double>(tmp)) {
return false;
}
value = tmp;
break;
}
case 4: { // bool
bool tmp;
if (!propStream.read<bool>(tmp)) {
return false;
}
value = tmp;
break;
}
default: {
value = boost::blank();
return false;
}
}
return true;
}
};
private:
bool hasAttribute(itemAttrTypes type) const {
return (type & attributeBits) != 0;
}
void removeAttribute(itemAttrTypes type);
static std::string emptyString;
static int64_t emptyInt;
static double emptyDouble;
static bool emptyBool;
typedef std::unordered_map<std::string, CustomAttribute> CustomAttributeMap;
struct Attribute
{
union {
int64_t integer;
std::string* string;
CustomAttributeMap* custom;
} value;
itemAttrTypes type;
@@ -272,6 +368,8 @@ class ItemAttributes
value.integer = i.value.integer;
} else if (ItemAttributes::isStrAttrType(type)) {
value.string = new std::string(*i.value.string);
} else if (ItemAttributes::isCustomAttrType(type)) {
value.custom = new CustomAttributeMap(*i.value.custom);
} else {
memset(&value, 0, sizeof(value));
}
@@ -283,6 +381,8 @@ class ItemAttributes
~Attribute() {
if (ItemAttributes::isStrAttrType(type)) {
delete value.string;
} else if (ItemAttributes::isCustomAttrType(type)) {
delete value.custom;
}
}
Attribute& operator=(Attribute other) {
@@ -293,6 +393,8 @@ class ItemAttributes
if (this != &other) {
if (ItemAttributes::isStrAttrType(type)) {
delete value.string;
} else if (ItemAttributes::isCustomAttrType(type)) {
delete value.custom;
}
value = other.value;
@@ -323,12 +425,94 @@ class ItemAttributes
const Attribute* getExistingAttr(itemAttrTypes type) const;
Attribute& getAttr(itemAttrTypes type);
public:
inline static bool isIntAttrType(itemAttrTypes type) {
return (type & 0xFFFFE13) != 0;
CustomAttributeMap* getCustomAttributeMap() {
if (!hasAttribute(ITEM_ATTRIBUTE_CUSTOM)) {
return nullptr;
}
return getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom;
}
inline static bool isStrAttrType(itemAttrTypes type) {
return (type & 0x1EC) != 0;
template<typename R>
void setCustomAttribute(int64_t key, R value) {
std::string tmp = boost::lexical_cast<std::string>(key);
setCustomAttribute(tmp, value);
}
void setCustomAttribute(int64_t key, CustomAttribute& value) {
std::string tmp = boost::lexical_cast<std::string>(key);
setCustomAttribute(tmp, value);
}
template<typename R>
void setCustomAttribute(std::string& key, R value) {
toLowerCaseString(key);
if (hasAttribute(ITEM_ATTRIBUTE_CUSTOM)) {
removeCustomAttribute(key);
} else {
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom = new CustomAttributeMap();
}
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom->emplace(key, value);
}
void setCustomAttribute(std::string& key, CustomAttribute& value) {
toLowerCaseString(key);
if (hasAttribute(ITEM_ATTRIBUTE_CUSTOM)) {
removeCustomAttribute(key);
} else {
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom = new CustomAttributeMap();
}
getAttr(ITEM_ATTRIBUTE_CUSTOM).value.custom->insert(std::make_pair(std::move(key), std::move(value)));
}
const CustomAttribute* getCustomAttribute(int64_t key) {
std::string tmp = boost::lexical_cast<std::string>(key);
return getCustomAttribute(tmp);
}
const CustomAttribute* getCustomAttribute(const std::string& key) {
if (const CustomAttributeMap* customAttrMap = getCustomAttributeMap()) {
auto it = customAttrMap->find(asLowerCaseString(key));
if (it != customAttrMap->end()) {
return &(it->second);
}
}
return nullptr;
}
bool removeCustomAttribute(int64_t key) {
std::string tmp = boost::lexical_cast<std::string>(key);
return removeCustomAttribute(tmp);
}
bool removeCustomAttribute(const std::string& key) {
if (CustomAttributeMap* customAttrMap = getCustomAttributeMap()) {
auto it = customAttrMap->find(asLowerCaseString(key));
if (it != customAttrMap->end()) {
customAttrMap->erase(it);
return true;
}
}
return false;
}
const static uint32_t intAttributeTypes = ITEM_ATTRIBUTE_ACTIONID | ITEM_ATTRIBUTE_UNIQUEID | ITEM_ATTRIBUTE_DATE
| ITEM_ATTRIBUTE_WEIGHT | ITEM_ATTRIBUTE_ATTACK | ITEM_ATTRIBUTE_DEFENSE | ITEM_ATTRIBUTE_EXTRADEFENSE
| ITEM_ATTRIBUTE_ARMOR | ITEM_ATTRIBUTE_HITCHANCE | ITEM_ATTRIBUTE_SHOOTRANGE | ITEM_ATTRIBUTE_OWNER
| ITEM_ATTRIBUTE_DURATION | ITEM_ATTRIBUTE_DECAYSTATE | ITEM_ATTRIBUTE_CORPSEOWNER | ITEM_ATTRIBUTE_CHARGES
| ITEM_ATTRIBUTE_FLUIDTYPE | ITEM_ATTRIBUTE_DOORID | ITEM_ATTRIBUTE_DECAYTO;
const static uint32_t stringAttributeTypes = ITEM_ATTRIBUTE_DESCRIPTION | ITEM_ATTRIBUTE_TEXT | ITEM_ATTRIBUTE_WRITER
| ITEM_ATTRIBUTE_NAME | ITEM_ATTRIBUTE_ARTICLE | ITEM_ATTRIBUTE_PLURALNAME;
public:
static bool isIntAttrType(itemAttrTypes type) {
return (type & intAttributeTypes) == type;
}
static bool isStrAttrType(itemAttrTypes type) {
return (type & stringAttributeTypes) == type;
}
inline static bool isCustomAttrType(itemAttrTypes type) {
return (type & ITEM_ATTRIBUTE_CUSTOM) == type;
}
const std::forward_list<Attribute>& getList() const {
@@ -359,10 +543,10 @@ class Item : virtual public Thing
bool equals(const Item* otherItem) const;
Item* getItem() final {
Item* getItem() override final {
return this;
}
const Item* getItem() const final {
const Item* getItem() const override final {
return this;
}
virtual Teleport* getTeleport() {
@@ -371,18 +555,18 @@ class Item : virtual public Thing
virtual const Teleport* getTeleport() const {
return nullptr;
}
virtual TrashHolder* getTrashHolder() {
return nullptr;
}
virtual const TrashHolder* getTrashHolder() const {
return nullptr;
}
virtual Mailbox* getMailbox() {
return nullptr;
}
virtual const Mailbox* getMailbox() const {
return nullptr;
}
virtual DepotLocker* getDepotLocker() {
return nullptr;
}
virtual const DepotLocker* getDepotLocker() const {
return nullptr;
}
virtual Door* getDoor() {
return nullptr;
}
@@ -437,6 +621,31 @@ class Item : virtual public Thing
return attributes->hasAttribute(type);
}
template<typename R>
void setCustomAttribute(std::string& key, R value) {
getAttributes()->setCustomAttribute(key, value);
}
void setCustomAttribute(std::string& key, ItemAttributes::CustomAttribute& value) {
getAttributes()->setCustomAttribute(key, value);
}
const ItemAttributes::CustomAttribute* getCustomAttribute(int64_t key) {
return getAttributes()->getCustomAttribute(key);
}
const ItemAttributes::CustomAttribute* getCustomAttribute(const std::string& key) {
return getAttributes()->getCustomAttribute(key);
}
bool removeCustomAttribute(int64_t key) {
return getAttributes()->removeCustomAttribute(key);
}
bool removeCustomAttribute(const std::string& key) {
return getAttributes()->removeCustomAttribute(key);
}
void setSpecialDescription(const std::string& desc) {
setStrAttr(ITEM_ATTRIBUTE_DESCRIPTION, desc);
}
@@ -475,6 +684,10 @@ class Item : virtual public Thing
}
void setActionId(uint16_t n) {
if (n < 100) {
n = 100;
}
setIntAttr(ITEM_ATTRIBUTE_ACTIONID, n);
}
uint16_t getActionId() const {
@@ -484,14 +697,11 @@ class Item : virtual public Thing
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_ACTIONID));
}
void setMovementID(uint16_t n) {
setIntAttr(ITEM_ATTRIBUTE_MOVEMENTID, n);
}
uint16_t getMovementId() const {
uint16_t getUniqueId() const {
if (!attributes) {
return 0;
}
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_MOVEMENTID));
return static_cast<uint16_t>(getIntAttr(ITEM_ATTRIBUTE_UNIQUEID));
}
void setCharges(uint16_t n) {
@@ -557,42 +767,49 @@ class Item : virtual public Thing
return static_cast<ItemDecayState_t>(getIntAttr(ITEM_ATTRIBUTE_DECAYSTATE));
}
void setDecayTo(int32_t decayTo) {
setIntAttr(ITEM_ATTRIBUTE_DECAYTO, decayTo);
}
int32_t getDecayTo() const {
if (hasAttribute(ITEM_ATTRIBUTE_DECAYTO)) {
return getIntAttr(ITEM_ATTRIBUTE_DECAYTO);
}
return items[id].decayTo;
}
static std::string getDescription(const ItemType& it, int32_t lookDistance, const Item* item = nullptr, int32_t subType = -1, bool addArticle = true);
static std::string getNameDescription(const ItemType& it, const Item* item = nullptr, int32_t subType = -1, bool addArticle = true);
static std::string getWeightDescription(const ItemType& it, uint32_t weight, uint32_t count = 1);
std::string getDescription(int32_t lookDistance) const final;
std::string getDescription(int32_t lookDistance) const override final;
std::string getNameDescription() const;
std::string getWeightDescription() const;
//serialization
virtual Attr_ReadValue readAttr(AttrTypes_t attr, PropStream& propStream);
bool unserializeAttr(PropStream& propStream);
virtual bool unserializeItemNode(FileLoader& f, NODE node, PropStream& propStream);
virtual bool unserializeItemNode(OTB::Loader&, const OTB::Node&, PropStream& propStream);
virtual void serializeAttr(PropWriteStream& propWriteStream) const;
bool isPushable() const final {
bool isPushable() const override final {
return isMoveable();
}
int32_t getThrowRange() const final {
int32_t getThrowRange() const override final {
return (isPickupable() ? 15 : 2);
}
uint16_t getID() const {
return id;
}
uint16_t getClientID() const {
return items[id].clientId;
}
void setID(uint16_t newid);
// Returns the player that is holding this item in his inventory
Player* getHoldingPlayer() const;
CombatType_t getDamageType() const {
return items[id].damageType;
}
CombatType_t getCombatType() const {
return items[id].combatType;
}
WeaponType_t getWeaponType() const {
return items[id].weaponType;
}
@@ -605,28 +822,7 @@ class Item : virtual public Thing
}
return items[id].shootRange;
}
uint8_t getMissileType() const {
return items[id].shootType;
}
uint8_t getFragility() const {
return items[id].fragility;
}
int32_t getAttackStrength() const {
return items[id].attackStrength;
}
int32_t getAttackVariation() const {
return items[id].attackVariation;
}
int32_t getManaConsumption() const {
return items[id].manaConsumption;
}
uint32_t getMinimumLevel() const {
return items[id].minReqLevel;
}
int32_t getWeaponSpecialEffect() const {
return items[id].weaponSpecialEffect;
}
virtual uint32_t getWeight() const;
uint32_t getBaseWeight() const {
if (hasAttribute(ITEM_ATTRIBUTE_WEIGHT)) {
@@ -652,15 +848,24 @@ class Item : virtual public Thing
}
return items[id].defense;
}
int32_t getExtraDefense() const {
if (hasAttribute(ITEM_ATTRIBUTE_EXTRADEFENSE)) {
return getIntAttr(ITEM_ATTRIBUTE_EXTRADEFENSE);
}
return items[id].extraDefense;
}
int32_t getSlotPosition() const {
return items[id].slotPosition;
}
uint16_t getDisguiseId() const {
return items[id].disguiseId;
int8_t getHitChance() const {
if (hasAttribute(ITEM_ATTRIBUTE_HITCHANCE)) {
return getIntAttr(ITEM_ATTRIBUTE_HITCHANCE);
}
return items[id].hitChance;
}
uint32_t getWorth() const;
void getLight(LightInfo& lightInfo) const;
LightInfo getLightInfo() const;
bool hasProperty(ITEMPROPERTY prop) const;
bool isBlocking() const {
@@ -678,15 +883,15 @@ class Item : virtual public Thing
bool isMagicField() const {
return items[id].isMagicField();
}
bool isSplash() const {
return items[id].isSplash();
}
bool isMoveable() const {
return items[id].moveable;
}
bool isPickupable() const {
return items[id].pickupable;
}
bool isUseable() const {
return items[id].useable;
}
bool isHangable() const {
return items[id].isHangable;
}
@@ -694,33 +899,10 @@ class Item : virtual public Thing
const ItemType& it = items[id];
return it.rotatable && it.rotateTo;
}
bool isDisguised() const {
return items[id].disguise;
}
bool isChangeUse() const {
return items[id].changeUse;
}
bool isChestQuest() const {
return items[id].isChest();
}
bool hasCollisionEvent() const {
return items[id].collisionEvent;
}
bool hasSeparationEvent() const {
return items[id].separationEvent;
}
bool hasUseEvent() const {
return items[id].useEvent;
}
bool hasMultiUseEvent() const {
return items[id].multiUseEvent;
}
bool canDistUse() const {
return items[id].distUse;
}
bool isRune() const {
return items[id].isRune();
bool hasWalkStack() const {
return items[id].walkStack;
}
const std::string& getName() const {
if (hasAttribute(ITEM_ATTRIBUTE_NAME)) {
return getStrAttr(ITEM_ATTRIBUTE_NAME);
@@ -748,12 +930,20 @@ class Item : virtual public Thing
count = n;
}
static uint32_t countByType(const Item* i, int32_t subType);
static uint32_t countByType(const Item* i, int32_t subType) {
if (subType == -1 || subType == i->getSubType()) {
return i->getItemCount();
}
return 0;
}
void setDefaultSubtype();
uint16_t getSubType() const;
void setSubType(uint16_t n);
void setUniqueId(uint16_t n);
void setDefaultDuration() {
uint32_t duration = getDefaultDuration();
if (duration != 0) {
@@ -776,13 +966,18 @@ class Item : virtual public Thing
virtual void startDecaying();
bool isLoadedFromMap() const {
return loadedFromMap;
}
void setLoadedFromMap(bool value) {
loadedFromMap = value;
}
bool isCleanable() const {
return !loadedFromMap && canRemove() && isPickupable() && !hasAttribute(ITEM_ATTRIBUTE_ACTIONID);
return !loadedFromMap && canRemove() && isPickupable() && !hasAttribute(ITEM_ATTRIBUTE_UNIQUEID) && !hasAttribute(ITEM_ATTRIBUTE_ACTIONID);
}
bool hasMarketAttributes() const;
std::unique_ptr<ItemAttributes>& getAttributes() {
if (!attributes) {
attributes.reset(new ItemAttributes());
@@ -799,29 +994,32 @@ class Item : virtual public Thing
}
}
Cylinder* getParent() const {
Cylinder* getParent() const override {
return parent;
}
void setParent(Cylinder* cylinder) {
void setParent(Cylinder* cylinder) override {
parent = cylinder;
}
Cylinder* getTopParent();
const Cylinder* getTopParent() const;
Tile* getTile();
const Tile* getTile() const;
bool isRemoved() const {
Tile* getTile() override;
const Tile* getTile() const override;
bool isRemoved() const override {
return !parent || parent->isRemoved();
}
protected:
Cylinder* parent = nullptr;
uint16_t id; // the same id as in ItemType
private:
std::string getWeightDescription(uint32_t weight) const;
Cylinder* parent = nullptr;
std::unique_ptr<ItemAttributes> attributes;
uint32_t referenceCounter = 0;
uint16_t id; // the same id as in ItemType
uint8_t count = 1; // number of stacked items
bool loadedFromMap = false;
@@ -829,16 +1027,7 @@ class Item : virtual public Thing
//Don't add variables here, use the ItemAttribute class.
};
typedef std::list<Item*> ItemList;
typedef std::deque<Item*> ItemDeque;
inline uint32_t Item::countByType(const Item* i, int32_t subType)
{
if (subType == -1 || subType == i->getSubType()) {
return i->getItemCount();
}
return 0;
}
using ItemList = std::list<Item*>;
using ItemDeque = std::deque<Item*>;
#endif