Ir para conteúdo
  • Cadastre-se

Normal Impedir que o Console leia a versão dos items.otb.


Posts Recomendados

Bom galera,desculpe se estiver na seção errada.Oque desejo e já tentei é ; impedir que o console leia a versão dos meus itens.otb,sendo assim irei poder colocar items 8.6 em um otserver 8.0 por exemplo.

Espero que possam me ajudar,desde já obrigado!

PS : Conhecimento minimo sobre programação,mas dei uma pesquisada e encontrei algo relacionado ao que desejo neste topico

 

Porém estou utilizando uma distro antiga,então é bem diferente deste topico acima.

 

//////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
//////////////////////////////////////////////////////////////////////
// Represents an item
//////////////////////////////////////////////////////////////////////
// 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include "item.h"
#include "container.h"
#include "configmanager.h"
#include "depot.h"
#include "teleport.h"
#include "trashholder.h"
#include "mailbox.h"
#include "house.h"
#include "game.h"
#include "luascript.h"
#include "actions.h"
#include "combat.h"
#include "weapons.h"
#include "beds.h"
#include <iostream>
#include <sstream>
#include <iomanip>

extern Game g_game;
extern Weapons* g_weapons;
extern ConfigManager g_config;

Items Item::items;

Item* Item::CreateItem(const uint16_t _type, uint16_t _count /*= 0*/)
{
    Item* newItem = NULL;

    const ItemType& it = Item::items[_type];

    if(it.group == ITEM_GROUP_DEPRECATED){
#ifdef __DEBUG__
        std::cout << "Error: [Item::CreateItem] Item id " << it.id << " has been declared deprecated."  << std::endl;
#endif
        return NULL;
    }

    if(it.stackable && !_count){
        _count = 1;
    }

    if(it.id != 0){
        if(it.isDepot()){
            newItem = new Depot(_type);
        }
        else if(it.isContainer()){
            newItem = new Container(_type);
        }
        else if(it.isTeleport()){
            newItem = new Teleport(_type);
        }
        else if(it.isMagicField()){
            newItem = new MagicField(_type);
        }
        else if(it.isDoor()){
            newItem = new Door(_type);
        }
        else if(it.isTrashHolder()){
            newItem = new TrashHolder(_type, it.magicEffect);
        }
        else if(it.isMailbox()){
            newItem = new Mailbox(_type);
        }
        else if(it.isBed()){
            newItem = new BedItem(_type);
        }
        else{
            newItem = new Item(_type, _count);
        }

        newItem->useThing2();
    }
    return newItem;
}

Item* Item::CreateItem(PropStream& propStream)
{
    uint16_t _id;
    if(!propStream.GET_UINT16(_id)){
        return NULL;
    }

    return Item::CreateItem(_id, 0);
}


bool Item::loadItem(xmlNodePtr node, Container* parent)
{
    if(xmlStrcmp(node->name, (const xmlChar*)"item") == 0){
        int32_t intValue;
        std::string strValue;
        Item* item = NULL;

        if(readXMLInteger(node, "id", intValue)){
            item = Item::CreateItem(intValue);
        }

        if(!item){
            return false;
        }

        //optional
        if(readXMLInteger(node, "subtype", intValue)){
            item->setSubType(intValue);
        }

        if(readXMLInteger(node, "actionid", intValue)){
            item->setActionId(intValue);
        }

        if(readXMLString(node, "text", strValue)){
            item->setText(strValue);
        }

        if(item->getContainer()){
            loadContainer(node, item->getContainer());
        }

        if(parent){
            parent->addItem(item);
        }

        return true;
    }

    return false;
}

bool Item::loadContainer(xmlNodePtr parentNode, Container* parent)
{
    xmlNodePtr node = parentNode->children;
    while(node){
        if(node->type != XML_ELEMENT_NODE){
            node = node->next;
            continue;
        }

        if(xmlStrcmp(node->name, (const xmlChar*)"item") == 0){
            if(!loadItem(node, parent)){
                return false;
            }
        }

        node = node->next;
    }

    return true;
}

Item::Item(const uint16_t _type, uint16_t _count /*= 0*/) :
    ItemAttributes()
{
    id = _type;

    const ItemType& it = items[id];

    setItemCount(1);

    if(it.isFluidContainer() || it.isSplash()){
        setFluidType(_count);
    }
    else if(it.stackable){
        if(_count != 0){
            setItemCount(_count);
        }
        else if(it.charges != 0){
            setItemCount(it.charges);
        }
    }
    else if(it.charges != 0){
        //if count is higher than 1, override default charges
        if(_count > 1){
            setCharges(_count);
        }
        else{
            setCharges(it.charges);
        }
    }

    setDefaultDuration();
}

Item::Item(const Item &i) :
    Thing(), ItemAttributes()
{
    //std::cout << "Item copy constructor " << this << std::endl;
    id = i.id;
    count = i.count;

    m_attributes = i.m_attributes;
    if(i.m_firstAttr){
        m_firstAttr = new Attribute(*i.m_firstAttr);
    }
}

Item* Item::clone() const
{
    Item* _item = Item::CreateItem(id, count);
    _item->m_attributes = m_attributes;
    if(m_firstAttr){
        _item->m_firstAttr = new Attribute(*m_firstAttr);
    }

    return _item;
}

void Item::copyAttributes(Item* item)
{
    m_attributes = item->m_attributes;
    if(item->m_firstAttr){
        m_firstAttr = new Attribute(*item->m_firstAttr);
    }

    removeAttribute(ATTR_ITEM_DECAYING);
    removeAttribute(ATTR_ITEM_DURATION);
}

Item::~Item()
{
    //std::cout << "Item destructor " << this << std::endl;
}

void Item::setDefaultSubtype()
{
    const ItemType& it = items[id];

    setItemCount(1);
    if(it.charges != 0){
        if(it.stackable){
            setItemCount(it.charges);
        }
        else{
            setCharges(it.charges);
        }
    }
}

void Item::onRemoved()
{
    ScriptEnviroment::removeTempItem(this);

    if(getUniqueId() != 0){
        ScriptEnviroment::removeUniqueThing(this);
    }
}

void Item::setID(uint16_t newid)
{
    const ItemType& prevIt = Item::items[id];
    id = newid;

    const ItemType& it = Item::items[newid];
    uint32_t newDuration = it.decayTime * 1000;

    if(newDuration == 0 && !it.stopTime && it.decayTo == -1){
        removeAttribute(ATTR_ITEM_DECAYING);
        removeAttribute(ATTR_ITEM_DURATION);
    }

    if(newDuration > 0 && (!prevIt.stopTime || !hasAttribute(ATTR_ITEM_DURATION)) ){
        setDecaying(DECAYING_FALSE);
        setDuration(newDuration);
    }
}

bool Item::hasSubType() const
{
    const ItemType& it = items[id];
    return it.hasSubType();
}

uint16_t Item::getSubType() const
{
    const ItemType& it = items[getID()];

    if(it.isFluidContainer() || it.isSplash()){
        return getFluidType();
    }
    else if(it.stackable){
        return getItemCount();
    }
    else if(it.charges != 0){
        return getCharges();
    }

    return getItemCount();
}

Player* Item::getHoldingPlayer()
{
    Cylinder* p = getParent();
    while(p){
        if(p->getCreature())
            // Must be a player, creatures are not cylinders
            return p->getCreature()->getPlayer();
        p = p->getParent();
    }
    return NULL;
}

const Player* Item::getHoldingPlayer() const
{
    return const_cast<Item*>(this)->getHoldingPlayer();
}

void Item::setSubType(uint16_t n)
{
    const ItemType& it = items[id];

    if(it.isFluidContainer() || it.isSplash()){
        setFluidType(n);
    }
    else if(it.stackable){
        setItemCount(n);
    }
    else if(it.charges != 0){
        setCharges(n);
    }
    else{
        setItemCount(n);
    }
}

Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream& propStream)
{
    switch(attr){
        case ATTR_COUNT:
        {
            uint8_t _count = 0;
            if(!propStream.GET_UINT8(_count)){
                return ATTR_READ_ERROR;
            }

            setSubType(_count);
            break;
        }

        case ATTR_ACTION_ID:
        {
            uint16_t _actionid = 0;
            if(!propStream.GET_UINT16(_actionid)){
                return ATTR_READ_ERROR;
            }

            setActionId(_actionid);
            break;
        }

        case ATTR_UNIQUE_ID:
        {
            uint16_t _uniqueid;
            if(!propStream.GET_UINT16(_uniqueid)){
                return ATTR_READ_ERROR;
            }

            setUniqueId(_uniqueid);
            break;
        }

        case ATTR_TEXT:
        {
            std::string _text;
            if(!propStream.GET_STRING(_text)){
                return ATTR_READ_ERROR;
            }

            setText(_text);
            break;
        }

        case ATTR_WRITTENBY:
        {
            std::string _writer;
            if(!propStream.GET_STRING(_writer)){
                return ATTR_READ_ERROR;
            }

            setWriter(_writer);
            break;
        }

        case ATTR_DESC:
        {
            std::string _text;
            if(!propStream.GET_STRING(_text)){
                return ATTR_READ_ERROR;
            }

            setSpecialDescription(_text);
            break;
        }

        case ATTR_RUNE_CHARGES:
        {
            uint8_t _charges = 1;
            if(!propStream.GET_UINT8(_charges)){
                return ATTR_READ_ERROR;
            }

            setSubType(_charges);
            break;
        }

        case ATTR_CHARGES:
        {
            uint16_t _charges = 1;
            if(!propStream.GET_UINT16(_charges)){
                return ATTR_READ_ERROR;
            }

            setSubType(_charges);
            break;
        }

        case ATTR_DURATION:
        {
            uint32_t duration = 0;
            if(!propStream.GET_UINT32(duration)){
                return ATTR_READ_ERROR;
            }

            if(((int32_t)duration) < 0){
                duration = 0;
            }
            setDuration(duration);
            break;
        }

        case ATTR_DECAYING_STATE:
        {
            uint8_t state = 0;
            if(!propStream.GET_UINT8(state)){
                return ATTR_READ_ERROR;
            }

            if(state != DECAYING_FALSE){
                setDecaying(DECAYING_PENDING);
            }
            break;
        }

        //these should be handled through derived classes
        //If these are called then something has changed in the items.xml since the map was saved
        //just read the values

        //Depot class
        case ATTR_DEPOT_ID:
        {
            uint16_t _depotId;
            if(!propStream.GET_UINT16(_depotId)){
                return ATTR_READ_ERROR;
            }

            return ATTR_READ_CONTINUE;
        }

        //Door class
        case ATTR_HOUSEDOORID:
        {
            uint8_t _doorId;
            if(!propStream.GET_UINT8(_doorId)){
                return ATTR_READ_ERROR;
            }

            return ATTR_READ_CONTINUE;
        }

        //Bed class
        case ATTR_SLEEPERGUID:
        {
            uint32_t _guid;
            if(!propStream.GET_UINT32(_guid)){
                return ATTR_READ_ERROR;
            }

            return ATTR_READ_CONTINUE;
        }

        case ATTR_SLEEPSTART:
        {
            uint32_t sleep_start;
            if(!propStream.GET_UINT32(sleep_start)){
                return ATTR_READ_ERROR;
            }

            return ATTR_READ_CONTINUE;
        }

        //Teleport class
        case ATTR_TELE_DEST:
        {
            TeleportDest tele_dest;
            if(        !propStream.GET_UINT16(tele_dest._x) ||
                    !propStream.GET_UINT16(tele_dest._y) ||
                    !propStream.GET_UINT8(tele_dest._z))
            {
                return ATTR_READ_ERROR;
            }

            return ATTR_READ_CONTINUE;
        }

        //Container class
        case ATTR_CONTAINER_ITEMS:
        {
            uint32_t count;
            if(!propStream.GET_UINT32(count)){
                return ATTR_READ_ERROR;
            }

            //We cant continue parse attributes since there is
            //container data after this attribute.
            return ATTR_READ_ERROR;
        }

        default:
            return ATTR_READ_ERROR;
        break;
    }

    return ATTR_READ_CONTINUE;
}

bool Item::unserializeAttr(PropStream& propStream)
{
    uint8_t attr_type;
    while(propStream.GET_UINT8(attr_type) && attr_type != 0){
        Attr_ReadValue ret = readAttr((AttrTypes_t)attr_type, propStream);
        if(ret == ATTR_READ_ERROR){
            return false;
            break;
        }
        else if(ret == ATTR_READ_END){
            return true;
        }
    }

    return true;
}

bool Item::unserializeItemNode(FileLoader& f, NODE node, PropStream& propStream)
{
    return unserializeAttr(propStream);
}

bool Item::serializeAttr(PropWriteStream& propWriteStream) const
{
    if(isStackable() || isFluidContainer() || isSplash()){
        uint8_t _count = getSubType();
        propWriteStream.ADD_UINT8(ATTR_COUNT);
        propWriteStream.ADD_UINT8(_count);
    }

    if(hasCharges()){
        uint16_t _count = getCharges();
        propWriteStream.ADD_UINT8(ATTR_CHARGES);
        propWriteStream.ADD_UINT16(_count);
    }

    if(!isNotMoveable() /*moveable*/){
        uint16_t _actionId = getActionId();
        if(_actionId){
            propWriteStream.ADD_UINT8(ATTR_ACTION_ID);
            propWriteStream.ADD_UINT16(_actionId);
        }
    }

    const std::string& _text = getText();
    if(_text.length() > 0){
        propWriteStream.ADD_UINT8(ATTR_TEXT);
        propWriteStream.ADD_STRING(_text);
    }

    const std::string& _writer = getWriter();
    if(_writer.length() > 0){
        propWriteStream.ADD_UINT8(ATTR_WRITTENBY);
        propWriteStream.ADD_STRING(_writer);
    }

    const std::string& _specialDesc = getSpecialDescription();
    if(_specialDesc.length() > 0){
        propWriteStream.ADD_UINT8(ATTR_DESC);
        propWriteStream.ADD_STRING(_specialDesc);
    }

    if(hasAttribute(ATTR_ITEM_DURATION)){
        uint32_t duration = getDuration();
        propWriteStream.ADD_UINT8(ATTR_DURATION);
        propWriteStream.ADD_UINT32(duration);
    }

    uint32_t decayState = getDecaying();
    if(decayState == DECAYING_TRUE || decayState == DECAYING_PENDING){
        propWriteStream.ADD_UINT8(ATTR_DECAYING_STATE);
        propWriteStream.ADD_UINT8(decayState);
    }

    return true;
}

bool Item::hasProperty(enum ITEMPROPERTY prop) const
{
    const ItemType& it = items[id];

    switch(prop){
        case BLOCKSOLID:
            if(it.blockSolid)
                return true;
            break;

        case MOVEABLE:
            if(it.moveable && getUniqueId() == 0)
                return true;
            break;

        case HASHEIGHT:
            if(it.hasHeight)
                return true;
            break;

        case BLOCKPROJECTILE:
            if(it.blockProjectile)
                return true;
            break;

        case BLOCKPATH:
            if(it.blockPathFind)
                return true;
            break;

        case ISVERTICAL:
            if(it.isVertical)
                return true;
            break;

        case ISHORIZONTAL:
            if(it.isHorizontal)
                return true;
            break;

        case IMMOVABLEBLOCKSOLID:
            if(it.blockSolid && (!it.moveable || getUniqueId() != 0))
                return true;
            break;

        case IMMOVABLEBLOCKPATH:
            if(it.blockPathFind && (!it.moveable || getUniqueId() != 0))
                return true;
            break;

        case SUPPORTHANGABLE:
            if(it.isHorizontal || it.isVertical)
                return true;
            break;

        case IMMOVABLENOFIELDBLOCKPATH:
            if(!it.isMagicField() && it.blockPathFind && (!it.moveable || getUniqueId() != 0))
                return true;
            break;

        case NOFIELDBLOCKPATH:
            if(!it.isMagicField() && it.blockPathFind)
                return true;
            break;

        default:
            return false;
    }
    return false;
}

double Item::getWeight() const
{
    if(isStackable()){
        return items[id].weight * std::max((int32_t)1, (int32_t)getItemCount());
    }

    return items[id].weight;
}

std::string Item::getLongName(const ItemType& it, int32_t lookDistance,
    const Item* item /*= NULL*/, int32_t subType /*= -1*/, bool addArticle /*= true*/)
{
    std::ostringstream s;

    if(item){
        subType = item->getSubType();
    }

    if(it.name.length()){
        if(it.stackable && subType > 1){
            if(it.showCount){
                s << subType << " ";
            }

            s << it.pluralName;
        }
        else{
            if(addArticle && !it.article.empty()){
                s << it.article << " ";
            }
            s << it.name;
        }
    }
    else{
        s << "an item of type " << it.id << ", please report it to gamemaster";
    }

    return s.str();
}

std::string Item::getLongName() const
{
    const ItemType& it = items[id];
    return getLongName(it, 0, this);
}

std::string Item::getDescription(const ItemType& it, int32_t lookDistance,
    const Item* item /*= NULL*/, int32_t subType /*= -1*/, bool addArticle /*= true*/)
{
    std::stringstream s;

    if (item){
        subType = item->getSubType();
    }

    if (it.name.length()){
        if (it.stackable && item && item->getItemCount() > 1){
            if (it.showCount){
                s << (int)item->getItemCount() << " ";
            }

            s << it.pluralName;
        }
        else{
            if (!it.article.empty()){
                s << it.article << " ";
            }
            s << it.name;
        }
    }
    else{
        s << "an item of type " << it.id;
    }

    if (it.isRune()){
        uint32_t charges = std::max((uint32_t)1, (uint32_t)(item == NULL ? it.charges : item->getCharges()));

        if (it.runeLevel > 0 || it.runeMagLevel > 0){
            if (it.runeLevel > 0){
                s << " for level " << it.runeLevel;
            }
            if (it.runeMagLevel > 0){
                if (it.runeLevel > 0){
                    s << " and";
                }
                s << " for magic level " << it.runeMagLevel;
            }
        }
        s << ". It's an \"" << it.runeSpellName << "\"-spell (" << charges << "x). ";
    }
    else if (it.id == 1227 || it.id == 1229 || it.id == 1245 || it.id == 1247 || it.id == 1259 || it.id == 1261 || it.id == 3540 || it.id == 3549 && item->getActionId() >= 1000) {
        s << " for level " << item->getActionId() - 1000 << ".";
    }
    else if (it.weaponType != WEAPON_NONE){
        if (it.weaponType == WEAPON_DIST && it.amuType != AMMO_NONE){
            if (it.attack != 0){
                s << ", Atk" << std::showpos << it.attack << std::noshowpos;
            }
        }
        else if (it.weaponType != WEAPON_AMMO && it.weaponType != WEAPON_WAND){ // Arrows and Bolts doesn't show atk
            s << " (";
            if (it.attack != 0){
                s << "Atk:" << (int)it.attack;
            }

            if (it.defense != 0 || it.extraDef != 0){
                if (it.attack != 0)
                    s << " ";

                s << "Def:" << (int)it.defense;
            }

            if (it.abilities.stats[STAT_MAGICPOINTS] != 0){
                if (it.attack != 0 || it.defense != 0 || it.extraDef != 0)
                    s << ", ";

                s << "magic level " << std::showpos << (int)it.abilities.stats[STAT_MAGICPOINTS] << std::noshowpos;
            }
            s << ")";
        }
        s << ".";
    }
    else if (it.armor != 0 || it.abilities.absorb.any()){
        if (it.showCharges){
            if (subType > 1){
                s << " that has " << (int32_t)subType << " charges left";
            }
            else{
                s << " that has 1 charge left";
            }
        }

        s << " (Arm:" << it.armor << ").";
    }
    else if (it.isFluidContainer()){
        if (item && item->getFluidType() != 0){
            s << " of " << items[item->getFluidType()].name << ".";
        }
        else{
            s << ". It is empty.";
        }
    }
    else if (it.isSplash()){
        s << " of ";
        if (item && item->getFluidType() != 0){
            s << items[item->getFluidType()].name;
        }
        else{
            s << items[1].name;
        }
    }
    else if (it.isContainer()){
        s << " (Vol:" << (int)it.maxItems << ").";
    }
    else if (it.isKey()){
        if (item){
            s << " (Key:" << (int)item->getActionId() << ").";
        }
        else{
            s << " (Key:" << (int)0 << ").";
        }
    }
    else if (it.allowDistRead){
        s << std::endl;

        if (item && item->getText() != ""){
            if (lookDistance <= 4){
                if (item->getWriter().length()){
                    s << item->getWriter() << " wrote: ";
                }
                else{
                    s << "You read: ";
                }

                s << item->getText();
            }
            else{
                s << "You are too far away to read it.";
            }
        }
        else{
            s << "Nothing is written on it.";
        }
    }
    else if (it.showCharges){
        uint32_t charges = (item == NULL ? it.charges : item->getCharges());
        if (charges > 1){
            s << " that has " << (int)charges << " charges left.";
        }
        else{
            s << " that has 1 charge left.";
        }
    }
    else if (it.showDuration){
        if (item && item->hasAttribute(ATTR_ITEM_DURATION)){
            int32_t duration = item->getDuration() / 1000;
            s << " that has energy for ";

            if (duration >= 120){
                s << duration / 60 << " minutes left.";
            }
            else if (duration > 60){
                s << "1 minute left.";
            }
            else{
                s << " less than a minute left.";
            }
        }
        else{
            s << " that is brand-new.";
        }
    }
    else{
        s << ".";
    }

    if (it.wieldInfo != 0){
        s << std::endl << "It can only be wielded properly by ";
        if (it.wieldInfo & WIELDINFO_PREMIUM){
            s << "premium ";
        }

        if (it.wieldInfo & WIELDINFO_VOCREQ){
            s << it.vocationString;
        }
        else{
            s << "players";
        }

        if (it.wieldInfo & WIELDINFO_LEVEL){
            s << " of level " << (int)it.minReqLevel << " or higher";
        }

        if (it.wieldInfo & WIELDINFO_MAGLV){
            if (it.wieldInfo & WIELDINFO_LEVEL){
                s << " and";
            }
            else{
                s << " of";
            }
            s << " magic level " << (int)it.minReqMagicLevel << " or higher";
        }

        s << ".";
    }

    if (lookDistance <= 1){
        double weight = (item == NULL ? it.weight : item->getWeight());
        if (weight > 0){
            s << std::endl << getWeightDescription(it, weight);
        }
    }

    if (item && item->getSpecialDescription() != ""){
        s << std::endl << item->getSpecialDescription().c_str();
    }
    else if (it.description.length() && lookDistance <= 1){
        s << std::endl << it.description;
    }

    return s.str();
}

std::string Item::getDescription(int32_t lookDistance) const
{
    std::stringstream s;
    const ItemType& it = items[id];

    s << getDescription(it, lookDistance, this);
    return s.str();
}

std::string Item::getXRayDescription() const
{
    std::stringstream ret;

    ret << "ID: " << getID() << std::endl;
    uint16_t actionId = getActionId();
    uint16_t uniqueId = getUniqueId();
    if(actionId > 0)
        ret << "Action ID: " << actionId << std::endl;
    if(uniqueId > 0)
        ret << "Unique ID: " << uniqueId << std::endl;
    #ifdef __DEBUG__
    if (getContainer())
        ret << "There are " << getContainer()->getTotalAmountOfItemsInside() - 1 << " things inside of this." << std::endl;
    #endif
    ret << Thing::getXRayDescription();
    return ret.str();
}

std::string Item::getWeightDescription() const
{
    double weight = getWeight();
    if(weight > 0){
        return getWeightDescription(weight);
    }
    else{
        return "";
    }
}

std::string Item::getWeightDescription(double weight) const
{
    const ItemType& it = Item::items[id];
    return getWeightDescription(it, weight, getItemCount());
}

std::string Item::getWeightDescription(const ItemType& it, double weight, uint32_t count /*= 1*/)
{
    std::stringstream ss;
    if(it.stackable && count > 1){
        ss << "They weigh " << std::fixed << std::setprecision(2) << weight << " oz.";
    }
    else{
        ss << "It weighs " << std::fixed << std::setprecision(2) << weight << " oz.";
    }
    return ss.str();
}


void Item::setUniqueId(uint16_t n)
{
    if(getUniqueId() != 0)
        return;

    ItemAttributes::setUniqueId(n);
    ScriptEnviroment::addUniqueThing(this);
}

bool Item::canDecay()
{
    if(isRemoved()){
        return false;
    }

    if(getUniqueId() != 0){
        return false;
    }

    const ItemType& it = Item::items[id];
    if(it.decayTo == -1 || it.decayTime == 0){
        return false;
    }

    return true;
}

uint32_t Item::getWorth() const
{
    const ItemType& it = Item::items[id];
    return getItemCount() * it.currency;
}

void Item::getLight(LightInfo& lightInfo)
{
    const ItemType& it = items[id];
    lightInfo.color = it.lightColor;
    lightInfo.level = it.lightLevel;
}

std::string ItemAttributes::emptyString("");

const std::string& ItemAttributes::getStrAttr(itemAttrTypes type) const
{
    if(!validateStrAttrType(type))
        return emptyString;

    //this will *NOT* create the attribute if it does not exist
    Attribute* attr = getAttrConst(type);
    if(attr){
        return *(std::string*)attr->value;
    }
    else{
        return emptyString;
    }
}

void ItemAttributes::setStrAttr(itemAttrTypes type, const std::string& value)
{
    if(!validateStrAttrType(type))
        return;

    if(value.length() == 0)
        return;

    //this will create the attribute if it does not exist
    Attribute* attr = getAttr(type);
    if(attr){
        //if has a previous value delete it
        if(attr->value){
            delete (std::string*)attr->value;
        }
        //create the new value as string
        attr->value = (void*)new std::string(value);
    }
}

bool ItemAttributes::hasAttribute(itemAttrTypes type) const
{
    if(!validateIntAttrType(type))
        return false;

    Attribute* attr = getAttrConst(type);
    if(attr){
        return true;
    }

    return false;
}

void ItemAttributes::removeAttribute(itemAttrTypes type)
{
    //check if we have it
    if((type & m_attributes) != 0){
        //go trough the linked list until find it
        Attribute* prevAttr = NULL;
        Attribute* curAttr = m_firstAttr;
        while(curAttr != NULL){
            if(curAttr->type == type){
                //found so remove it from the linked list
                if(prevAttr){
                    prevAttr->next = curAttr->next;
                }
                else{
                    m_firstAttr = curAttr->next;
                }
                //remove it from flags
                m_attributes = m_attributes & ~type;

                //delete string if it is string type
                if(validateStrAttrType(type)){
                    delete (std::string*)curAttr->value;
                }
                //finally delete the attribute and return
                delete curAttr;
                return;
            }

            //advance in the linked list
            prevAttr = curAttr;
            curAttr = curAttr->next;
        }
    }
}

uint32_t ItemAttributes::getIntAttr(itemAttrTypes type) const
{
    if(!validateIntAttrType(type))
        return 0;

    Attribute* attr = getAttrConst(type);
    if(attr){
        return static_cast<uint32_t>(0xFFFFFFFF & reinterpret_cast<ptrdiff_t>(attr->value));
    }
    else{
        return 0;
    }
}

void ItemAttributes::setIntAttr(itemAttrTypes type, int32_t value)
{
    if(!validateIntAttrType(type))
        return;

    Attribute* attr = getAttr(type);
    if(attr){
        attr->value = reinterpret_cast<void*>(static_cast<ptrdiff_t>(value));
    }
}

void ItemAttributes::increaseIntAttr(itemAttrTypes type, int32_t value)
{
    if(!validateIntAttrType(type))
        return;

    Attribute* attr = getAttr(type);
    if(attr){
        attr->value = reinterpret_cast<void*>(static_cast<ptrdiff_t>(static_cast<uint32_t>(0xFFFFFFFF & reinterpret_cast<ptrdiff_t>(attr->value)) + value));
    }
}

bool ItemAttributes::validateIntAttrType(itemAttrTypes type)
{
    //list of numeric type attributes
    switch(type){
    case ATTR_ITEM_ACTIONID:
    case ATTR_ITEM_UNIQUEID:
    case ATTR_ITEM_OWNER:
    case ATTR_ITEM_DURATION:
    case ATTR_ITEM_DECAYING:
    case ATTR_ITEM_CHARGES:
    case ATTR_ITEM_FLUIDTYPE:
    case ATTR_ITEM_DOORID:
        return true;
        break;

    default:
        return false;
        break;
    }
    return false;
}

bool ItemAttributes::validateStrAttrType(itemAttrTypes type)
{
    //list of text type attributes
    switch(type){
    case ATTR_ITEM_DESC:
    case ATTR_ITEM_TEXT:
    case ATTR_ITEM_WRITTENBY:
        return true;
        break;
    default:
        return false;
        break;
    }
    return false;
}

void ItemAttributes::addAttr(Attribute* attr)
{
    //add an attribute to the linked list
    if(m_firstAttr){
        //is not the first, so look for the end of the list
        Attribute* curAttr = m_firstAttr;
        while(curAttr->next){
            curAttr = curAttr->next;
        }
        //and add it at the end
        curAttr->next = attr;
    }
    else{
        //is the first
        m_firstAttr = attr;
    }
    //add it to flags
    m_attributes = m_attributes | attr->type;
}

ItemAttributes::Attribute* ItemAttributes::getAttrConst(itemAttrTypes type) const
{
    //check flags
    if((type & m_attributes) == 0){
        return NULL;
    }
    //it is here, so search it in the linked list
    Attribute* curAttr = m_firstAttr;
    while(curAttr){
        if(curAttr->type == type){
            //found
            return curAttr;
        }
        curAttr = curAttr->next;
    }
    //not found?
    std::cout << "Warning: [ItemAttributes::getAttrConst] (type & m_attributes) != 0 but attribute not found" << std::endl;
    return NULL;
}

ItemAttributes::Attribute* ItemAttributes::getAttr(itemAttrTypes type)
{
    Attribute* curAttr;
    if((type & m_attributes) == 0){
        //if that type was not present add it
        curAttr = new Attribute(type);
        addAttr(curAttr);
        return curAttr;
    }
    else{
        //was present, search and return it
        curAttr = m_firstAttr;
        while(curAttr){
            if(curAttr->type == type){
                return curAttr;
            }
            curAttr = curAttr->next;
        }
    }
    std::cout << "Warning: [ItemAttributes::getAttr] (type & m_attributes) != 0 but attribute not found" << std::endl;
    curAttr = new Attribute(type);
    addAttr(curAttr);
    return curAttr;
}

void ItemAttributes::deleteAttrs(Attribute* attr)
{
    //deletes all attributes recursively
    if(attr){
        //if is string type, delete the allocated string
        if(validateStrAttrType(attr->type)){
            delete (std::string*)attr->value;
        }
        Attribute* next_attr = attr->next;
        attr->next = NULL;
        //delete next while it was not NULL
        if(next_attr){
            deleteAttrs(next_attr);
        }
        delete attr;
    }
}

void Item::__startDecaying()
{
    g_game.startDecay(this);
}

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

  • Conteúdo Similar

    • Por Jaurez
      .
    • Por Cat
      Em alguns casos, o tibia 8.60 comum não abre de jeito nenhum no map editor, mesmo desmarcando check file signatures e configurando o path corretamente.
       
      Este é o client 8.60 adaptado para o Remere's Map Editor. Resolvi postar já que ele foi removido do site oficial do RME. (ficou apenas a versão para linux lá)
      Se estiver tendo problemas para abrir a versão 8.60, tente utilizar este.
                                                                                                                     
      Baixar o Tibia Client 8.60 que funciona no Remere’s Map Editor
      Essa versão do Tibia 8.60 client resolve o erro unsupported client version ou Could not locate tibia.dat and/or tibia.spr, please navigate to your tibia 8.60 installation folder.
       
      Downloads
      https://tibiaking.com/applications/core/interface/file/attachment.php?id=47333

      Scan: https://www.virustotal.com/gui/file/333e172ac49ba2028db9eb5889994509e7d2de28ebccfa428c04e86defbe15cc
       
    • Por danilo belato
      Fala Galera To Com um problema aki 
       
      quero exporta umas sprites de um server para colocar em outro 
       
      eu clico na sprites ai aparece tds a forma delas do lado de la >>
       
      ai eu clico nela e ponho a opiçao de export mais quando salvo a sprite ela n abri 
       
      aparece isso quando tento vê-la 
       
      visualização não disponível ( no formatos png e bitmap)
       
      Agora no formato idc fala que o paint n pode ler 
       
      me ajudem ae...
    • Por Vitor Bicaleto
      Galera to com o script do addon doll aqui, quando eu digito apenas "!addon" ele aparece assim: Digite novamente, algo está errado!"
      quando digito por exemplo: "!addon citizen" ele não funciona e não da nenhum erro
       
      mesma coisa acontece com o mount doll.. 
    • Por Ayron5
      Substitui uma stone no serve, deu tudo certo fora  esse  erro ajudem  Valendo  Rep+  Grato  

      Erro: data/actions/scripts/boost.lua:557: table index is nil
       [Warning - Event::loadScript] Cannot load script (data/actions/scripts/boost.lua)

      Script:
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo