Jump to content
  • Announcements

    • Majesty

      Seja bem vindo a seção Downloads!   04/25/2019

      Seja bem vindo a seção Downloads! 
      Aqui, você pode encontrar diversos downloads sobre OTServ. Se tiver dúvidas e/ou problemas sobre algum conteúdo, primeiro, você deve utilizar a ferramenta de busca e explorar o fórum. Se você não encontrou o que precisa, considere criar um tópico na seção de Suporte:
      https://forums.otserv.com.br/index.php?/forums/forum/402-suporte-dúvidas-bugs-erros/ Considere também ler o grande guia do usuário com dúvidas, que possui várias recomendações e dicas de como tirar dúvidas.

      Obrigado e boa sorte!
Sign in to follow this  
Capaverde

Função saveMap, salva em um novo .otbm

Recommended Posts

Capaverde

Nome: Função saveMap
Autor: Capaverde
Versão Testada: The Forgotten Server - Version 0.2rc9 (Mystic Spirit)

Função que salva o estado do seu mapa num novo .otbm, útil para servidores com sistemas de construção.
Instruções para como instalar abaixo.

bit32 = bit
print = debugPrint

--SPECIAL CHARACTERS
NODE_START = 0xfe
NODE_END = 0xff
ESCAPE_CHAR = 0xfd

--OTBM NODE TYPES
OTBM_ROOTV1 = 1
OTBM_MAP_DATA = 2
OTBM_ITEM_DEF = 3
OTBM_TILE_AREA = 4
OTBM_TILE = 5
OTBM_ITEM = 6
OTBM_TILE_SQUARE = 7
OTBM_TILE_REF = 8
OTBM_SPAWNS = 9
OTBM_SPAWN_AREA = 10
OTBM_MONSTER = 11
OTBM_TOWNS = 12
OTBM_TOWN = 13
OTBM_HOUSETILE = 14

--OTBM ATTR TYPES
OTBM_ATTR_DESCRIPTION = 1
OTBM_ATTR_EXT_FILE = 2
OTBM_ATTR_TILE_FLAGS = 3
OTBM_ATTR_ACTION_ID = 4
OTBM_ATTR_UNIQUE_ID = 5
OTBM_ATTR_TEXT = 6
OTBM_ATTR_DESC = 7
OTBM_ATTR_TELE_DEST = 8
OTBM_ATTR_ITEM = 9
OTBM_ATTR_DEPOT_ID = 10
OTBM_ATTR_EXT_SPAWN_FILE = 11
OTBM_ATTR_RUNE_CHARGES = 12
OTBM_ATTR_EXT_HOUSE_FILE = 13
OTBM_ATTR_HOUSEDOORID = 14
OTBM_ATTR_COUNT = 15
OTBM_ATTR_DURATION = 16
OTBM_ATTR_DECAYING_STATE = 17
OTBM_ATTR_WRITTENDATE = 18
OTBM_ATTR_WRITTENBY = 19
OTBM_ATTR_SLEEPERGUID = 20
OTBM_ATTR_SLEEPSTART = 21
OTBM_ATTR_CHARGES = 22

function lchar(i) s="" while i>0 do s=s..string.char(i%256) i=math.floor(i/256) end return s end

function format(s,size)
    local len = #s
    for x=1,size/8-len do
        s=s.."\0"
    end
    return s
end

function writeData(f,data,size,unescape)
    local thestr
    if type(data) == "string" then
        thestr = format(data,size)
    elseif type(data) == "number" then
        thestr = format(lchar(data),size)
    elseif type(data) == "table" then
        for k,v in pairs(data) do
            print(k,v)
        end
        return
    else
        print(data)
        return
    end
    for x=1,size/8 do
        local c = thestr:sub(x,x)
        --print(#thestr,size,string.byte(c))
        --if c == string.char(0x0D) then error("daonde") end
        if unescape and (c==string.char(NODE_START) or c==string.char(NODE_END) or c==string.char(ESCAPE_CHAR)) then
            f:write(string.char(ESCAPE_CHAR))
        end
        f:write(c)
    end
end

function addU8(f,data)
    writeData(f,data,8,true)
end

function addByte(f,data)
    writeData(f,data,8,false)
end

function addU16(f,data)
    writeData(f,data,16,true)
end

function addU32(f,data)
    writeData(f,data,32,false)
end

function addString(f,data)
    if #data > 0xffff then
        return false
    end
    addU16(f,#data)
    writeData(f,data,#data*8,false)
end

function startNode(f,c) --c is a char
    writeData(f,NODE_START,8,false)
    writeData(f,c,8,true)
end

function endNode(f)
writeData(f,NODE_END,8,false)
end

WIDTH = 128 --put here the dimensions of your map
HEIGHT = 128 --
ITEMDWMAJORVERSION = 2
ITEMDWMINORVERSION = 8

function saveMap(name) --e.g. "map.otbm"
    local minv = math.huge
    local maxv = 0
    print("saveMap start")
    f = io.open(name,"wb")
    addU32(f,0); --version
    startNode(f,0)
    addU32(f,0); --version again 
    addU16(f,WIDTH)
    addU16(f,HEIGHT)
    addU32(f,ITEMDWMAJORVERSION)
    addU32(f,ITEMDWMINORVERSION)

    startNode(f,OTBM_MAP_DATA)
    --addByte(f,OTBM_ATTR_DESCRIPTION)
    --addString(f,"Created with saveMap script, a translation of Remere's")
    local first = true
    local l_x=-1
    local l_y=-1
    local l_Z=-1
    for z=0,7 do
        for xi=0,WIDTH-1,256 do
            for yi=0,HEIGHT-1,256 do
                for x=xi,math.min(xi+256-1,WIDTH-1) do
                    for y=yi,math.min(yi+256-1,HEIGHT-1) do
                        if x<l_x or x>=l_x+256 or y<l_y or y>=l_y+256 or z~=l_z then
                            if not first then
                                endNode(f)
                            end
                            first = false
                            --start new node
                            startNode(f,OTBM_TILE_AREA)
                            l_x=bit32.band(x,0xff00)
                            l_y=bit32.band(y,0xff00)
                            l_z=z
                            addU16(f,l_x)
                            addU16(f,l_y)
                            addU8(f,l_z)
                        end
                        startNode(f,OTBM_TILE)
                        addU8(f,bit32.band(x,0xff))
                        addU8(f,bit32.band(y,0xff))

                        for stackpos=0,10 do
                            local pos = {x=x,y=y,z=z,stackpos=stackpos}
                            local thing = getTileThingByPos(pos)
                                if (thing.itemid==0 and stackpos==0) then --no tile, so we can skip it
                                    break
                                end
                                if thing.itemid > 0 and stackpos ~= 253 then --TODO: save item counts, save containers
                                    addByte(f,OTBM_ATTR_ITEM)
                                    addU16(f,thing.itemid)
                                end
                        end
                        endNode(f)
                    end
                end
            end
        end
    end

    if not first then
        endNode(f)
    end

    endNode(f)
    endNode(f)
    f:close()
    print(minv,maxv)
end

Pra instalar é só colocar o código acima no global.lua, e daí chamar saveMap("map.otbm") onde você quiser, numa talkaction ou npc.
Aviso: Pode lagar um pouco, dependendo do tamanho do seu mapa. Edited by Elwyn
cabeçalho

Share this post


Link to post
Skyen Hasus

Aprovado!

Edited by Skyen Hasus

Share this post


Link to post
Eventide

Muito interessante, mas eu fiquei mais curioso pra saber qual servidor tem sistema de construção... Será possível fazer um survival tipo minecraft/terraria no Tibia? Seria interessante...

Share this post


Link to post
Anderkrox

Gostaria de usar este código, porém está com problemas do fórum!

Share this post


Link to post
Elwyn

 

 

 

bit32 = bit
print = debugPrint

--SPECIAL CHARACTERS
NODE_START = 0xfe
NODE_END = 0xff
ESCAPE_CHAR = 0xfd

--OTBM NODE TYPES
OTBM_ROOTV1 = 1
OTBM_MAP_DATA = 2
OTBM_ITEM_DEF = 3
OTBM_TILE_AREA = 4
OTBM_TILE = 5
OTBM_ITEM = 6
OTBM_TILE_SQUARE = 7
OTBM_TILE_REF = 8
OTBM_SPAWNS = 9
OTBM_SPAWN_AREA = 10
OTBM_MONSTER = 11
OTBM_TOWNS = 12
OTBM_TOWN = 13
OTBM_HOUSETILE = 14

--OTBM ATTR TYPES
OTBM_ATTR_DESCRIPTION = 1
OTBM_ATTR_EXT_FILE = 2
OTBM_ATTR_TILE_FLAGS = 3
OTBM_ATTR_ACTION_ID = 4
OTBM_ATTR_UNIQUE_ID = 5
OTBM_ATTR_TEXT = 6
OTBM_ATTR_DESC = 7
OTBM_ATTR_TELE_DEST = 8
OTBM_ATTR_ITEM = 9
OTBM_ATTR_DEPOT_ID = 10
OTBM_ATTR_EXT_SPAWN_FILE = 11
OTBM_ATTR_RUNE_CHARGES = 12
OTBM_ATTR_EXT_HOUSE_FILE = 13
OTBM_ATTR_HOUSEDOORID = 14
OTBM_ATTR_COUNT = 15
OTBM_ATTR_DURATION = 16
OTBM_ATTR_DECAYING_STATE = 17
OTBM_ATTR_WRITTENDATE = 18
OTBM_ATTR_WRITTENBY = 19
OTBM_ATTR_SLEEPERGUID = 20
OTBM_ATTR_SLEEPSTART = 21
OTBM_ATTR_CHARGES = 22

function lchar(i) s="" while i>0 do s=s..string.char(i%256) i=math.floor(i/256) end return s end

function format(s,size)
    local len = #s
    for x=1,size/8-len do
        s=s.."\0"
    end
    return s
end

function writeData(f,data,size,unescape)
    local thestr
    if type(data) == "string" then
        thestr = format(data,size)
    elseif type(data) == "number" then
        thestr = format(lchar(data),size)
    elseif type(data) == "table" then
        for k,v in pairs(data) do
            print(k,v)
        end
        return
    else
        print(data)
        return
    end
    for x=1,size/8 do
        local c = thestr:sub(x,x)
        --print(#thestr,size,string.byte(c))
        --if c == string.char(0x0D) then error("daonde") end
        if unescape and (c==string.char(NODE_START) or c==string.char(NODE_END) or c==string.char(ESCAPE_CHAR)) then
            f:write(string.char(ESCAPE_CHAR))
        end
        f:write(c)
    end
end

function addU8(f,data)
    writeData(f,data,8,true)
end

function addByte(f,data)
    writeData(f,data,8,false)
end

function addU16(f,data)
    writeData(f,data,16,true)
end

function addU32(f,data)
    writeData(f,data,32,false)
end

function addString(f,data)
    if #data > 0xffff then
        return false
    end
    addU16(f,#data)
    writeData(f,data,#data*8,false)
end

function startNode(f,c) --c is a char
    writeData(f,NODE_START,8,false)
    writeData(f,c,8,true)
end

function endNode(f)
writeData(f,NODE_END,8,false)
end

WIDTH = 128 --put here the dimensions of your map
HEIGHT = 128 --
ITEMDWMAJORVERSION = 2
ITEMDWMINORVERSION = 8

function saveMap(name) --e.g. "map.otbm"
    local minv = math.huge
    local maxv = 0
    print("saveMap start")
    f = io.open(name,"wb")
    addU32(f,0); --version
    startNode(f,0)
    addU32(f,0); --version again 
    addU16(f,WIDTH)
    addU16(f,HEIGHT)
    addU32(f,ITEMDWMAJORVERSION)
    addU32(f,ITEMDWMINORVERSION)

    startNode(f,OTBM_MAP_DATA)
    --addByte(f,OTBM_ATTR_DESCRIPTION)
    --addString(f,"Created with saveMap script, a translation of Remere's")
    local first = true
    local l_x=-1
    local l_y=-1
    local l_Z=-1
    for z=0,7 do
        for xi=0,WIDTH-1,256 do
            for yi=0,HEIGHT-1,256 do
                for x=xi,math.min(xi+256-1,WIDTH-1) do
                    for y=yi,math.min(yi+256-1,HEIGHT-1) do
                        if x<l_x or x>=l_x+256 or y<l_y or y>=l_y+256 or z~=l_z then
                            if not first then
                                endNode(f)
                            end
                            first = false
                            --start new node
                            startNode(f,OTBM_TILE_AREA)
                            l_x=bit32.band(x,0xff00)
                            l_y=bit32.band(y,0xff00)
                            l_z=z
                            addU16(f,l_x)
                            addU16(f,l_y)
                            addU8(f,l_z)
                        end
                        startNode(f,OTBM_TILE)
                        addU8(f,bit32.band(x,0xff))
                        addU8(f,bit32.band(y,0xff))

                        for stackpos=0,10 do
                            local pos = {x=x,y=y,z=z,stackpos=stackpos}
                            local thing = getTileThingByPos(pos)
                                if (thing.itemid==0 and stackpos==0) then --no tile, so we can skip it
                                    break
                                end
                                if thing.itemid > 0 and stackpos ~= 253 then --TODO: save item counts, save containers
                                    addByte(f,OTBM_ATTR_ITEM)
                                    addU16(f,thing.itemid)
                                end
                        end
                        endNode(f)
                    end
                end
            end
        end
    end

    if not first then
        endNode(f)
    end

    endNode(f)
    endNode(f)
    f:close()
    print(minv,maxv)
end

 

 

Share this post


Link to post
Guest
This topic is now closed to further replies.
Sign in to follow this  
  • Recently Browsing   0 members

    No registered users viewing this page.

×