Skip to content

Instantly share code, notes, and snippets.

@cezarguimaraes
Last active November 2, 2019 00:25
Show Gist options
  • Save cezarguimaraes/262fd9b39c8070312f17 to your computer and use it in GitHub Desktop.
Save cezarguimaraes/262fd9b39c8070312f17 to your computer and use it in GitHub Desktop.
Parse tibia dat files
local vstruct = require 'vstruct'
function Items(path)
local buffer = io.open(path, 'rb')
local signature = vstruct.readvals('u4', buffer)
local itemCount, creatureCount, effectCount, distanceCount = vstruct.readvals('4 * u2', buffer)
local items = {}
for id = 100, itemCount + creatureCount do
local item = {id = id, onTopPriority = 5, movable = true}
items[id] = item
local optByte = vstruct.readvals('u1', buffer)
while optByte ~= 0xFF do
if optByte == 0x00 then
item.groundSpeed = vstruct.readvals('u2', buffer)
item.onTopPriority = 0
item.group = 'ground'
elseif optByte == 0x01 then
item.alwaysOnTop = true
item.onTopPriority = 1
elseif optByte == 0x02 then
item.alwaysOnTop = true
item.onTopPriority = 2
elseif optByte == 0x03 then
item.alwaysOnTop = true
item.onTopPriority = 3
elseif optByte == 0x04 then
item.group = 'container'
elseif optByte == 0x05 then
item.stackable = true
elseif optByte == 0x07 then
item.useWith = true
elseif optByte == 0x08 or optByte == 0x09 then
item.readable = true
item.writable = optByte == 0x08
item.maxLength = vstruct.readvals('u2', buffer)
elseif optByte == 0x0A then
item.group = 'fluid container'
elseif optByte == 0x0B then
item.group = 'splash'
elseif optByte == 0x0C then
item.blocksObjects = true
elseif optByte == 0x0D then
item.movable = false
elseif optByte == 0x0E then
item.blocksProjectiles = true
elseif optByte == 0x0F then
item.blocksPathfinder = true
elseif optByte == 0x10 then
item.noMovementAnimation = true
elseif optByte == 0x11 then
item.pickupable = true
elseif optByte == 0x12 then
item.hangable = true
elseif optByte == 0x13 then
item.horizontal = true
elseif optByte == 0x14 then
item.vertical = true
elseif optByte == 0x15 then
item.rotatable = true
elseif optByte == 0x16 then
item.lightLevel, item.lightColor = vstruct.readvals('u2 u2', buffer)
elseif optByte == 0x19 then
buffer:seek('cur', 4)
elseif optByte == 0x1A then
item.hasHeight = true
buffer:seek('cur', 2)
elseif optByte == 0x1D then
item.minimapColor = vstruct.readvals('u2', buffer)
elseif optByte == 0x1E then
local opt = vstruct.readvals('u2', buffer)
if opt == 1112 then
item.readable = true
end
elseif optByte == 0x1F then
item.walkStack = true
elseif optByte == 0x20 then
item.lookThrough = true
elseif optByte == 0x21 then
buffer:seek('cur', 2)
elseif optByte == 0x22 then
local info = vstruct.read('category:u2 wareId:u2 showAs:u2 name:c2 profession:u2 level:u2', buffer)
for k, v in pairs(info) do
item[k] = v
end
elseif optByte == 0x23 then
buffer:seek('cur', 2)
end
optByte = vstruct.readvals('u1', buffer)
end
local isOutfit = (id > itemCount) and vstruct.readvals('u1', buffer) or 1
for j = 1, isOutfit do
local frameGroup = id > itemCount and vstruct.readvals('u1', buffer) or 0
local width, height = vstruct.readvals('u1 u1', buffer)
if width > 1 or height > 1 then
buffer:seek('cur', 1)
end
local frames, xdiv, ydiv, zdiv, animLength = vstruct.readvals('5 * u1', buffer)
item.animation = animLength > 1
if item.animation then
buffer:seek('cur', 6 + animLength * 8)
--[[for i = 1, animLength do
buffer:seek('cur', 8)
end]]
end
local numSprites = width * height * frames * xdiv * ydiv * zdiv * animLength
buffer:seek('cur', 4 * numSprites)
--[[for i = 1, numSprites do
buffer:seek('cur', 4)
end]]
end
end
buffer:close()
return items
end
return Items
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment