• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[GUIDE] [OTCV8] [TIBIA 13 MINIMAP LOADER] Easy load minimap from tibiamaps.io or gunzodus

mar173

Member
Joined
Aug 14, 2016
Messages
34
Reaction score
18
This method is a bit slow, minimap load time ~5sec.

1. copy minimap directory to otcv8 directory
  • example minimap path: "Ezodus 13.20/minimap"
  • example minimap path: "minimap-with-markers/minimap"

2. Add LoadTibia13Minimap function to otcv8/modules/game_minimap/minimap.lua:
Lua:
function LoadTibia13Minimap()
  g_minimap.clean()
  --[[
  local function list_files(directory)
    local files = {}
    local cmd
    if g_app.getOs() == 'windows' then
      cmd = 'dir "' .. directory .. '" /b'
    else
      cmd = 'ls "' .. directory .. '"'
    end
    local handle = io.popen(cmd)
    if handle then
      for file in handle:lines() do
        table.insert(files, file)
      end
      handle:close()
    else
      print("Error: Unable to execute command.")
    end
    return files
  end
  -- Specify the directory you want to list files from
  local directory = "minimap"
  -- Get the list of files in the directory
  local files = list_files(directory)
  ]]
  local files = {}
  if g_resources.directoryExists('/minimap') then
    files = g_resources.listDirectoryFiles("/minimap", false, true)
  end
  -- Loop through the files
  for _, file in ipairs(files) do
    if not file:lower():find('waypointcost') then
      local fileNoExt = file:sub(1, -5)
      local pos = fileNoExt:split("_")
      if #pos >= 3 then
        local x = tonumber(pos[#pos - 2])
        local y = tonumber(pos[#pos - 1])
        local z = tonumber(pos[#pos])
        if x and y and z then
          g_minimap.loadImage('/minimap/' .. file, { x = x, y = y, z = z }, 1.0)
        end
      end
    end
  end
end

3. Use LoadTibia13Minimap in the loadMap function in otcv8/modules/game_minimap/minimap.lua:
Lua:
function loadMap()
  local clientVersion = g_game.getClientVersion()

  g_minimap.clean()
  loaded = false

  local minimapFile = '/minimap.otmm'
  local dataMinimapFile = '/data' .. minimapFile
  local versionedMinimapFile = '/minimap' .. clientVersion .. '.otmm'
  if g_resources.fileExists(dataMinimapFile) then
    loaded = g_minimap.loadOtmm(dataMinimapFile)
  end
  if not loaded and g_resources.fileExists(versionedMinimapFile) then
    loaded = g_minimap.loadOtmm(versionedMinimapFile)
  end
  if not loaded and g_resources.fileExists(minimapFile) then
    loaded = g_minimap.loadOtmm(minimapFile)
  end
  if not loaded then
    print("Minimap couldn't be loaded, file missing?")
  end

  LoadTibia13Minimap()

  minimapWidget:load()
end

4. Optional. Benefits -> 1. otmm map will save correctly after running LoadTibia13Minimap(). 2. .otmm fast load time (stop using LoadTibia13Minimap after first use)
src/client/minimap.cpp
line 302
add block.justSaw();
compile otcv8

C++:
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
MinimapTile& tile = block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y);
if(!(tile.flags & MinimapTileWasSeen)) {
    tile.color = c;
    tile.flags = flags;
    block.justSaw();//line 302


____________________
Optional. Load Marks - very slow -> otc problem at modules/gamelib/ui/uiminimap.lua -> UIMinimap:addFlag
Lua:
ICONS_BY_ID = {
  [0x00] = "checkmark",
  [0x01] = "?",
  [0x02] = "!",
  [0x03] = "star",
  [0x04] = "crossmark",
  [0x05] = "cross",
  [0x06] = "mouth",
  [0x07] = "spear",
  [0x08] = "sword",
  [0x09] = "flag",
  [0x0A] = "lock",
  [0x0B] = "bag",
  [0x0C] = "skull",
  [0x0D] = "$",
  [0x0E] = "red up",
  [0x0F] = "red down",
  [0x10] = "red right",
  [0x11] = "red left",
  [0x12] = "up",
  [0x13] = "down"
}

function MinimapBytesToCoordinate(x1, x2, x3)
  return x1 + 0x80 * x2 + 0x4000 * x3 - 0x4080
end

function ReadMarkersFromFile(fileName)
  local file = io.open(fileName, "rb")
  local markers = {}

  if not file then
    io.stderr:write("Error opening file: " .. fileName .. "\n")
    return markers
  end

  local fileSize = file:seek("end")
  file:seek("set", 0)
  local buffer = file:read(fileSize)
  file:close()

  local index = 1
  local length = #buffer

  if length == 0 then
    return markers
  end

  while index <= length do
    local marker = {}

    if not (buffer:byte(index) == 0x0A) then
      break
    end
    assert(buffer:byte(index) == 0x0A)
    index = index + 1
    local markerSize = buffer:byte(index)
    index = index + 1
    assert(buffer:byte(index) == 0x0A)
    index = index + 1
    local coordinateSize = buffer:byte(index)
    index = index + 1

    assert(coordinateSize == 0x0A)
    assert(buffer:byte(index) == 0x08)
    index = index + 1

    local x1 = buffer:byte(index)
    index = index + 1
    local x2 = buffer:byte(index)
    index = index + 1
    local x3 = buffer:byte(index)
    index = index + 1
    marker.x = MinimapBytesToCoordinate(x1, x2, x3)

    assert(buffer:byte(index) == 0x10)
    index = index + 1

    local y1 = buffer:byte(index)
    index = index + 1
    local y2 = buffer:byte(index)
    index = index + 1
    local y3 = buffer:byte(index)
    index = index + 1
    marker.y = MinimapBytesToCoordinate(y1, y2, y3)

    assert(buffer:byte(index) == 0x18)
    index = index + 1
    marker.z = buffer:byte(index)
    index = index + 1
    assert(buffer:byte(index) == 0x10)
    index = index + 1

    local imageID = buffer:byte(index)
    index = index + 1
    marker.iconID = imageID
    marker.iconName = ICONS_BY_ID[imageID]

    assert(buffer:byte(index) == 0x1A)
    index = index + 1

    local descriptionLength = buffer:byte(index)
    index = index + 1
    local descriptionBuffer = buffer:sub(index, index + descriptionLength - 1)
    index = index + descriptionLength
    marker.description = descriptionBuffer

    while index <= length and buffer:byte(index) ~= 0x0A do
      index = index + 1
    end

    markers[#markers + 1] = marker
  end

  return markers
end

function AddRealTibiaFlags(inputFileName)
  local markers = ReadMarkersFromFile(inputFileName)
  local function posToStr(pos) return pos.x .. ',' .. pos.y .. ',' .. pos.z end
  local seen = {}
  local settings = g_settings.getNode('Minimap')
  if settings then
    if not settings.flags then
      settings.flags = {}
    end
    if settings.flags then
      for _, flag in pairs(settings.flags) do
        seen[posToStr(flag.position)] = true
      end
      for _, marker in ipairs(markers) do
        if not seen[marker.x .. ',' .. marker.y .. ',' .. marker.z] then
          table.insert(settings.flags,
            { icon = marker.iconID, description = marker.description, position = { x = marker.x, y = marker.y, z = marker.z } })
        end
      end
    end
  end
  g_settings.setNode('Minimap', settings)
  g_settings.save()
end

function LoadTibia13Minimap()
  g_minimap.clean()
  local files = {}
  if g_resources.directoryExists('/minimap') then
    files = g_resources.listDirectoryFiles("/minimap", false, true)
  end
  -- Loop through the files
  for _, file in ipairs(files) do
    local fileLower = file:lower()
    if fileLower:find(".bin") then
      --load markers
      AddRealTibiaFlags('minimap/' .. file)
    elseif not fileLower:find('waypointcost') then
      local fileNoExt = file:sub(1, -5)
      local pos = fileNoExt:split("_")
      if #pos >= 3 then
        local x = tonumber(pos[#pos - 2])
        local y = tonumber(pos[#pos - 1])
        local z = tonumber(pos[#pos])
        if x and y and z then
          g_minimap.loadImage('/minimap/' .. file, { x = x, y = y, z = z }, 1.0)
        end
      end
    end
  end
end
 
Last edited:
Thanks for explaining how to add the map! I did it and now I have the map.
Could you please explain a bit further the step 4? about compiling? I don't get it fully :/
 
Back
Top