MVER = { { name = "signature", typ = T_STRING, length = 4, cond = { { cond = COND_EQ, value = ("MVER"):reverse() } } }, { name = "length", typ = T_UINT32, cond = { { cond = COND_EQ, value = 4 } } }, { name = "version", typ = T_UINT32, cond = { { cond = COND_EQ, value = 17 } } }, } MOHD = { { name = "signature", typ = T_STRING, length = 4, cond = { { cond = COND_EQ, value = ("MOHD"):reverse() } } }, { name = "length", typ = T_UINT32, cond = { { cond = COND_EQ, value = 64 } } }, { name = "nTextures", typ = T_UINT32 }, { name = "nGroups", typ = T_UINT32 }, { name = "nPortals", typ = T_UINT32 }, { name = "nLights", typ = T_UINT32 }, { name = "nDoodadNames", typ = T_UINT32 }, { name = "nDoodadDefs", typ = T_UINT32 }, { name = "nDoodadSets", typ = T_UINT32 }, { name = "ambColor", typ = T_UINT32 }, { name = "wmoID", typ = T_UINT32 }, { name = "bbcorner1_1", typ = T_FLOAT }, { name = "bbcorner1_2", typ = T_FLOAT }, { name = "bbcorner1_3", typ = T_FLOAT }, { name = "bbcorner2_1", typ = T_FLOAT }, { name = "bbcorner2_2", typ = T_FLOAT }, { name = "bbcorner2_3", typ = T_FLOAT }, { name = "unk", typ = T_UINT32 }, } MOGP = { { name = "gName", typ = T_UINT32 }, { name = "gNameDesc", typ = T_UINT32 }, { name = "flags", typ = T_UINT32 }, { name = "bbcorner1_1", typ = T_FLOAT }, { name = "bbcorner1_2", typ = T_FLOAT }, { name = "bbcorner1_3", typ = T_FLOAT }, { name = "bbcorner2_1", typ = T_FLOAT }, { name = "bbcorner2_2", typ = T_FLOAT }, { name = "bbcorner2_3", typ = T_FLOAT }, { name = "moprIndex", typ = T_UINT16 }, { name = "nItems", typ = T_UINT16 }, { name = "nBatchesA", typ = T_UINT16 }, { name = "nBatchesB", typ = T_UINT16 }, { name = "nBatchesC", typ = T_UINT32 }, { name = "fog1", typ = T_UINT8 }, { name = "fog2", typ = T_UINT8 }, { name = "fog3", typ = T_UINT8 }, { name = "fog4", typ = T_UINT8 }, { name = "unk", typ = T_UINT32 }, { name = "groupID", typ = T_UINT32 }, { name = "unk2", typ = T_UINT32 }, { name = "unk3", typ = T_UINT32 }, } MOGI = { { name = "flags", typ = T_UINT32 }, { name = "bbcorner1_1", typ = T_FLOAT }, { name = "bbcorner1_2", typ = T_FLOAT }, { name = "bbcorner1_3", typ = T_FLOAT }, { name = "bbcorner2_1", typ = T_FLOAT }, { name = "bbcorner2_2", typ = T_FLOAT }, { name = "bbcorner2_3", typ = T_FLOAT }, { name = "nameOffset", typ = T_INT32 }, } MLIQ = { { name = "xverts", typ = T_UINT32 }, { name = "yverts", typ = T_UINT32 }, { name = "xtiles", typ = T_UINT32 }, { name = "ytiles", typ = T_UINT32 }, { name = "coord_1", typ = T_FLOAT }, { name = "coord_2", typ = T_FLOAT }, { name = "coord_3", typ = T_FLOAT }, { name = "matID", typ = T_UINT16 }, } local function check_chunk_head(fin, head) if read_string(fin, 4):reverse() ~= head then error("Was expecting " .. head .. " chunk now") end end local md5translate = nil function init_wmo_reader(fin) if not md5translate then md5translate = "" if fin == nil then fin = mpqHandle "textures/Minimap/md5translate.trs" end while not fin:isclosed() do md5translate = md5translate .. fin:read() .. "\n" end end end local function parse_mogi(map, points) if not md5translate then init_wmo_reader() end local i, x, y, tex, mapping mapping = {} for i, x, y, tex in md5translate:gmatch('\\' .. map .. "_(%d%d%d)_(%d%d)_(%d%d)%.blp\t(%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x)%.blp") do i = tonumber(i) x = tonumber(x) y = tonumber(y) if points[i] then -- and tex ~= "c7182036289831c2dce4a7200377e6f4" then local x_, y_, z_ = points[i][1] + x * 256, points[i][2] + y * 256, points[i][3] local good = true --[[ if v.ignore then if v.ignore.z then for k in pairs(v.ignore.z) do if k <= z_ and z_ < k + 0.000001 then good = false break end end end if good and v.ignore.x then for k in pairs(v.ignore.x) do if k <= x_ and x_ < k + 0.000001 then good = false break end end end if good and v.ignore.y then for k in pairs(v.ignore.y) do if k <= y_ and y_ < k + 0.000001 then good = false break end end end if good and v.ignore.tex then if v.ignore.tex[tex] then good = false end end end ]]-- if good then table.insert(mapping, { tex = tex, x = x_, y = y_, z = z_ }) end end end return mapping end function wmo_reader(fin, map) -- local mver, mohd, motx, tx_names, momt, motxes, mogn, global_names, mogis local s, i, l mver = read_structure(fin, MVER) mohd = read_structure(fin, MOHD) bbox = { { x = mohd.bbcorner1_1 * 2, y = mohd.bbcorner1_2 * 2, z = mohd.bbcorner1_3 * 2 }, { x = mohd.bbcorner2_1 * 2, y = mohd.bbcorner2_2 * 2, z = mohd.bbcorner2_3 * 2 }, } check_chunk_head(fin, "MOTX") l = fin:readU32() b = Buffer() tx_names = {} b:copyfrom(fin, l) while not b:isclosed() do s = read_string(b) if s ~= "" then table.insert(tx_names, s) end end check_chunk_head(fin, "MOMT") l = fin:readU32() fin:seek(l, SEEK_CUR) -- skip MOMT part check_chunk_head(fin, "MOGN") l = fin:readU32() b = Buffer() global_names = {} b:copyfrom(fin, l) while not b:isclosed() do s = read_string(b) if s ~= "" then table.insert(global_names, s) end end check_chunk_head(fin, "MOGI") l = fin:readU32() if l ~= mohd.nGroups * struct_sizeof(MOGI) then error "MOGI chunk size inconsistant" end mogis = {} local points = {} for i = 1, mohd.nGroups do local cur_mogi cur_mogi = read_structure(fin, MOGI) table.insert(mogis, cur_mogi) points[i] = { cur_mogi.bbcorner1_1 * 2, cur_mogi.bbcorner1_2 * 2, cur_mogi.bbcorner1_3 * 2 } end mapping = parse_mogi(map, points) --[[ check_chunk_head(fin, "MOSB") l = fin:readU32() fin:seek(l, SEEK_CUR) -- skip MOSB part check_chunk_head(fin, "MOPV") l = fin:readU32() fin:seek(l, SEEK_CUR) -- skip MOPV part check_chunk_head(fin, "MOPT") l = fin:readU32() fin:seek(l, SEEK_CUR) -- skip MOPT part check_chunk_head(fin, "MORP") -- etc... we are only interested in the MOGI chunk anyway. ]]-- return { bbox = bbox, mapping = mapping } end