//////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game //////////////////////////////////////////////////////////////////////// // 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 3 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, see . //////////////////////////////////////////////////////////////////////// #ifndef __ITEMS__ #define __ITEMS__ #include "otsystem.h" #include "itemloader.h" #include "const.h" #include "enums.h" #include "position.h" #include #define ITEMS 10500 #define SLOTP_WHEREEVER 0xFFFFFFFF #define SLOTP_HEAD 1 << 0 #define SLOTP_NECKLACE 1 << 1 #define SLOTP_BACKPACK 1 << 2 #define SLOTP_ARMOR 1 << 3 #define SLOTP_RIGHT 1 << 4 #define SLOTP_LEFT 1 << 5 #define SLOTP_LEGS 1 << 6 #define SLOTP_FEET 1 << 7 #define SLOTP_RING 1 << 8 #define SLOTP_AMMO 1 << 9 #define SLOTP_DEPOT 1 << 10 #define SLOTP_TWO_HAND 1 << 11 #define SLOTP_HAND SLOTP_LEFT | SLOTP_RIGHT enum ItemTypes_t { ITEM_TYPE_NONE = 0, ITEM_TYPE_DEPOT, ITEM_TYPE_MAILBOX, ITEM_TYPE_TRASHHOLDER, ITEM_TYPE_CONTAINER, ITEM_TYPE_DOOR, ITEM_TYPE_MAGICFIELD, ITEM_TYPE_TELEPORT, ITEM_TYPE_BED, ITEM_TYPE_KEY, ITEM_TYPE_LAST }; enum FloorChange_t { CHANGE_PRE_FIRST = 0, CHANGE_DOWN = CHANGE_PRE_FIRST, CHANGE_FIRST = 1, CHANGE_NORTH = CHANGE_FIRST, CHANGE_EAST = 2, CHANGE_SOUTH = 3, CHANGE_WEST = 4, CHANGE_FIRST_EX = 5, CHANGE_NORTH_EX = CHANGE_FIRST_EX, CHANGE_EAST_EX = 6, CHANGE_SOUTH_EX = 7, CHANGE_WEST_EX = 8, CHANGE_NONE = 9, CHANGE_LAST = CHANGE_NONE }; struct Abilities { Abilities() { memset(skills, 0, sizeof(skills)); memset(skillsPercent, 0, sizeof(skillsPercent)); memset(stats, 0 , sizeof(stats)); memset(statsPercent, 0, sizeof(statsPercent)); memset(absorbPercent, 0, sizeof(absorbPercent)); elementType = COMBAT_NONE; manaShield = invisible = regeneration = preventLoss = preventDrop = false; speed = healthGain = healthTicks = manaGain = manaTicks = elementDamage = conditionSuppressions = 0; }; bool manaShield, invisible, regeneration, preventLoss, preventDrop; CombatType_t elementType; int16_t elementDamage, absorbPercent[COMBAT_LAST + 1]; int32_t skills[SKILL_LAST + 1], skillsPercent[SKILL_LAST + 1], stats[STAT_LAST + 1], statsPercent[STAT_LAST + 1], speed, healthGain, healthTicks, manaGain, manaTicks, conditionSuppressions; }; class Condition; class ItemType { private: ItemType(const ItemType& it) {} public: ItemType(); virtual ~ItemType(); bool isGroundTile() const {return (group == ITEM_GROUP_GROUND);} bool isContainer() const {return (group == ITEM_GROUP_CONTAINER);} bool isSplash() const {return (group == ITEM_GROUP_SPLASH);} bool isFluidContainer() const {return (group == ITEM_GROUP_FLUID);} bool isDoor() const {return (type == ITEM_TYPE_DOOR);} bool isMagicField() const {return (type == ITEM_TYPE_MAGICFIELD);} bool isTeleport() const {return (type == ITEM_TYPE_TELEPORT);} bool isKey() const {return (type == ITEM_TYPE_KEY);} bool isDepot() const {return (type == ITEM_TYPE_DEPOT);} bool isMailbox() const {return (type == ITEM_TYPE_MAILBOX);} bool isTrashHolder() const {return (type == ITEM_TYPE_TRASHHOLDER);} bool isBed() const {return (type == ITEM_TYPE_BED);} bool isRune() const {return clientCharges;} bool hasSubType() const {return (isFluidContainer() || isSplash() || stackable || charges);} bool stopTime, showCount, clientCharges, stackable, showDuration, showCharges, showAttributes, allowDistRead, canReadText, canWriteText, forceSerialize, isVertical, isHorizontal, isHangable, useable, moveable, pickupable, rotable, replaceable, lookThrough, hasHeight, blockSolid, blockPickupable, blockProjectile, blockPathFind, allowPickupable, alwaysOnTop, floorChange[CHANGE_LAST]; MagicEffectClasses magicEffect; FluidTypes_t fluidSource; WeaponType_t weaponType; Direction bedPartnerDir; AmmoAction_t ammoAction; CombatType_t combatType; RaceType_t corpseType; ShootType_t shootType; Ammo_t ammoType; uint16_t transformToOnUse[2], transformToFree, transformEquipTo, transformDeEquipTo, id, clientId, maxItems, slotPosition, wieldPosition, speed, maxTextLen, writeOnceItemId; int32_t attack, extraAttack, defense, extraDefense, armor, breakChance, hitChance, maxHitChance, runeLevel, runeMagLevel, lightLevel, lightColor, decayTo, rotateTo, alwaysOnTopOrder; uint32_t shootRange, charges, decayTime, attackSpeed, wieldInfo, minReqLevel, minReqMagicLevel, worth, levelDoor; std::string name, pluralName, article, description, runeSpellName, vocationString; Condition* condition; Abilities abilities; itemgroup_t group; ItemTypes_t type; float weight; }; template class Array { public: Array(uint32_t n); virtual ~Array(); A getElement(uint32_t id); const A getElement(uint32_t id) const; void addElement(A a, uint32_t pos); uint32_t size() {return m_size;} private: A* m_data; uint32_t m_size; }; template Array::Array(uint32_t n) { m_data = (A*)malloc(sizeof(A) * n); memset(m_data, 0, sizeof(A) * n); m_size = n; } template Array::~Array() { free(m_data); } template A Array::getElement(uint32_t id) { if(id < m_size) return m_data[id]; return 0; } template const A Array::getElement(uint32_t id) const { if(id < m_size) return m_data[id]; return 0; } template void Array::addElement(A a, uint32_t pos) { #define INCREMENT 5000 if(pos >= m_size) { m_data = (A*)realloc(m_data, sizeof(A) * (pos + INCREMENT)); memset(m_data + m_size, 0, sizeof(A) * (pos + INCREMENT - m_size)); m_size = pos + INCREMENT; } m_data[pos] = a; } struct RandomizationBlock { int32_t fromRange, toRange, chance; }; typedef std::map RandomizationMap; typedef std::map IntegerMap; class Items { public: Items(): m_randomizationChance(50), items(ITEMS) {} virtual ~Items() {clear();} bool reload(); int32_t loadFromOtb(std::string); bool loadFromXml(); void parseItemNode(xmlNodePtr itemNode, uint32_t id); void addItemType(ItemType* iType); ItemType& getItemType(int32_t id); const ItemType& getItemType(int32_t id) const; const ItemType& operator[](int32_t id) const {return getItemType(id);} int32_t getItemIdByName(const std::string& name); const ItemType& getItemIdByClientId(int32_t spriteId) const; uint16_t getRandomizedItem(uint16_t id); uint8_t getRandomizationChance() const {return m_randomizationChance;} RandomizationBlock getRandomization(int16_t id) {return randomizationMap[id];} uint32_t size() {return items.size();} IntegerMap getMoneyMap() {return moneyMap;} const ItemType* getElement(uint32_t id) const {return items.getElement(id);} static uint32_t dwMajorVersion; static uint32_t dwMinorVersion; static uint32_t dwBuildNumber; private: uint8_t m_randomizationChance; void clear(); void parseRandomizationBlock(int32_t id, int32_t fromId, int32_t toId, int32_t chance); Array items; RandomizationMap randomizationMap; IntegerMap moneyMap; IntegerMap reverseItemMap; }; #endif