예제 #1
0
void ThingTypeManager::loadOtb(const std::string& file)
{
    FileStreamPtr fin = g_resources.openFile(file);

    uint signature = fin->getU32();
    if(signature != 0)
        stdext::throw_exception("invalid otb file");

    BinaryTreePtr root = fin->getBinaryTree();

    signature = root->getU32();
    if(signature != 0)
        stdext::throw_exception("invalid otb file");

    root->getU32(); // flags

    m_otbMajorVersion = root->getU32();
    m_otbMinorVersion = root->getU32();
    root->getU32(); // build number
    root->skip(128); // description

    m_itemTypes.resize(root->getChildren().size(), m_nullItemType);
    for(const BinaryTreePtr& node : root->getChildren()) {
        ItemTypePtr itemType(new ItemType);
        itemType->unserialize(node);
        addItemType(itemType);
    }

    m_otbLoaded = true;
}
예제 #2
0
void ThingTypeManager::parseItemType(uint16 serverId, TiXmlElement* elem)
{
    ItemTypePtr itemType = nullptr;

    bool s;
    int d;

    if(g_game.getProtocolVersion() < 960) {
        s = serverId > 20000 && serverId < 20100;
        d = 20000;
    } else {
        s = serverId > 30000 && serverId < 30100;
        d = 30000;
    }

    if(s) {
        serverId -= d;
        itemType = ItemTypePtr(new ItemType);
        itemType->setServerId(serverId);
        addItemType(itemType);
    } else
        itemType = getItemType(serverId);

    itemType->setName(elem->Attribute("name"));
    for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
        std::string key = attrib->Attribute("key");
        if(key.empty())
            continue;

        stdext::tolower(key);
        if(key == "description")
            itemType->setDesc(attrib->Attribute("value"));
        else if(key == "weapontype")
            itemType->setCategory(ItemCategoryWeapon);
        else if(key == "ammotype")
            itemType->setCategory(ItemCategoryAmmunition);
        else if(key == "armor")
            itemType->setCategory(ItemCategoryArmor);
        else if(key == "charges")
            itemType->setCategory(ItemCategoryCharges);
        else if(key == "type") {
            std::string value = attrib->Attribute("value");
            stdext::tolower(value);

            if(value == "key")
                itemType->setCategory(ItemCategoryKey);
            else if(value == "magicfield")
                itemType->setCategory(ItemCategoryMagicField);
            else if(value == "teleport")
                itemType->setCategory(ItemCategoryTeleport);
            else if(value == "door")
                itemType->setCategory(ItemCategoryDoor);
        }
    }
}
예제 #3
0
void ThingTypeManager::loadOtb(const std::string& file)
{
    try {
        FileStreamPtr fin = g_resources.openFile(file);

        uint signature = fin->getU32();
        if(signature != 0)
            stdext::throw_exception("invalid otb file");

        BinaryTreePtr root = fin->getBinaryTree();
        root->skip(1); // otb first byte is always 0

        signature = root->getU32();
        if(signature != 0)
            stdext::throw_exception("invalid otb file");

        uint8 rootAttr = root->getU8();
        if(rootAttr == 0x01) { // OTB_ROOT_ATTR_VERSION
            uint16 size = root->getU16();
            if(size != 4 + 4 + 4 + 128)
                stdext::throw_exception("invalid otb root attr version size");

            m_otbMajorVersion = root->getU32();
            m_otbMinorVersion = root->getU32();
            root->skip(4); // buildNumber
            root->skip(128); // description
        }

        m_reverseItemTypes.clear();
        m_itemTypes.resize(root->getChildren().size() + 1, m_nullItemType);
        m_reverseItemTypes.resize(root->getChildren().size() + 1, m_nullItemType);

        for(const BinaryTreePtr& node : root->getChildren()) {
            ItemTypePtr itemType(new ItemType);
            itemType->unserialize(node);
            addItemType(itemType);

            uint16 clientId = itemType->getClientId();
            if(unlikely(clientId >= m_reverseItemTypes.size()))
                m_reverseItemTypes.resize(clientId + 1);
            m_reverseItemTypes[clientId] = itemType;
        }

        m_otbLoaded = true;
        g_lua.callGlobalField("g_things", "onLoadOtb", file);
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to load '%s' (OTB file): %s", file, e.what()));
    }
}
예제 #4
0
void ThingTypeManager::loadOtb(const std::string& file)
{
    try {
        FileStreamPtr fin = g_resources.openFile(file);

        uint signature = fin->getU32();
        if(signature != 0)
            stdext::throw_exception("invalid otb file");

        BinaryTreePtr root = fin->getBinaryTree();

        signature = root->getU32();
        if(signature != 0)
            stdext::throw_exception("invalid otb file");

        root->skip(4);

        m_otbMajorVersion = root->getU32();
        m_otbMinorVersion = root->getU32();
        root->skip(4);
        root->skip(128); // description

        m_reverseItemTypes.clear();
        m_itemTypes.resize(root->getChildren().size() + 1, m_nullItemType);
        m_reverseItemTypes.resize(root->getChildren().size() + 1, m_nullItemType);

        for(const BinaryTreePtr& node : root->getChildren()) {
            ItemTypePtr itemType(new ItemType);
            itemType->unserialize(node);
            addItemType(itemType);

            uint16 clientId = itemType->getClientId();
            if(unlikely(clientId >= m_reverseItemTypes.size()))
                m_reverseItemTypes.resize(clientId + 1);
            m_reverseItemTypes[clientId] = itemType;
        }

        m_otbLoaded = true;
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to load '%s' (OTB file): %s", file, e.what()));
    }
}
예제 #5
0
void ThingTypeManager::parseItemType(uint16 id, TiXmlElement* elem)
{
    uint16 serverId = id;
    if(serverId > 20000 && id < 20100) {
        serverId -= 20000;

        ItemTypePtr newType(new ItemType);
        newType->setServerId(serverId);
        addItemType(newType);
    }

    ItemTypePtr itemType = getItemType(serverId);
    itemType->setName(elem->Attribute("name"));
    for(TiXmlElement* attrib = elem->FirstChildElement(); attrib; attrib = attrib->NextSiblingElement()) {
        if(attrib->ValueStr() != "attribute")
            break;

        if(attrib->Attribute("key") == "description") {
            itemType->setDesc(attrib->Attribute("value"));
            break;
        }
    }
}
예제 #6
0
void ThingTypeManager::loadXml(const std::string& file)
{
    /// Read XML
    TiXmlDocument doc;
    doc.Parse(g_resources.loadFile(file).c_str());
    if(doc.Error())
        stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));

    TiXmlElement* root = doc.FirstChildElement();
    if(!root || root->ValueTStr() != "items")
        stdext::throw_exception("invalid root tag name");

    for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
        if(element->ValueTStr() != "item")
            continue;

        uint16 id = element->readType<uint16>("id");
        if(id > 20000 && id < 20100) {
            id -= 20000;
            ItemTypePtr newType(new ItemType);
            newType->setServerId(id);
            addItemType(newType);
        }

        if(id != 0)
            parseItemType(id, element);
        else {
            uint16 fromId = element->readType<uint16>("fromid"), toId = element->readType<uint16>("toid");
            for(uint16 i = fromId; i < toId; ++i)
                parseItemType(i, element);
        }
    }

    doc.Clear();
    m_xmlLoaded = true;
    g_logger.debug("items.xml read successfully.");
}