Daily Archives: 2011/11/04

世界地图外部生成机制

根据上一篇所讲. 现在我们如何在外部生成一张地图.
一.
首先GetMapInfo.
从worldmapareadbc 获得
ID 以及mapName
GetNumberOfDetailTiles() 获取大地图的tile数量? 游戏内能直接获取, 游戏外部如何获取?
二.
从worldmapoverlay.dbc
同上面的ID, 获得当前地图overlays数量
以及他的材质名称, 高度 宽度 坐标位置.

地图 1002 * 668 ?
布局
256 256 256 256
256 256 256 256
256 256 256 256
特殊变量

WORLDMAP_POI_TEXTURE_WIDTH = 256;
WORLDMAP_COSMIC_ID = -1;
WORLDMAP_WORLD_ID = 0;
WORLDMAP_OUTLAND_ID = 3;
WORLDMAP_MAELSTROM_ID = 5;
MAELSTROM_ZONES_ID = { TheMaelstrom = 737, Deepholm = 640, Kezan = 605, TheLostIsles = 544 };

https://github.com/tekkub/wow-ui-source/blob/4.2.2/FrameXML/WorldMapFrame.lua

— Setup the overlays
local textureCount = 0;
for i=1, GetNumMapOverlays() do
local textureName, textureWidth, textureHeight, offsetX, offsetY = GetMapOverlayInfo(i);
if ( textureName and textureName ~= “” ) then
local numTexturesWide = ceil(textureWidth/256);
local numTexturesTall = ceil(textureHeight/256);
local neededTextures = textureCount + (numTexturesWide * numTexturesTall);
if ( neededTextures > NUM_WORLDMAP_OVERLAYS ) then
for j=NUM_WORLDMAP_OVERLAYS+1, neededTextures do
WorldMapDetailFrame:CreateTexture(“WorldMapOverlay”..j, “ARTWORK”);
end
NUM_WORLDMAP_OVERLAYS = neededTextures;
end
local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight;
for j=1, numTexturesTall do
if ( j < numTexturesTall ) then texturePixelHeight = 256; textureFileHeight = 256; else texturePixelHeight = mod(textureHeight, 256); if ( texturePixelHeight == 0 ) then texturePixelHeight = 256; end textureFileHeight = 16; while(textureFileHeight < texturePixelHeight) do textureFileHeight = textureFileHeight * 2; end end for k=1, numTexturesWide do textureCount = textureCount + 1; local texture = _G["WorldMapOverlay"..textureCount]; if ( k < numTexturesWide ) then texturePixelWidth = 256; textureFileWidth = 256; else texturePixelWidth = mod(textureWidth, 256); if ( texturePixelWidth == 0 ) then texturePixelWidth = 256; end textureFileWidth = 16; while(textureFileWidth < texturePixelWidth) do textureFileWidth = textureFileWidth * 2; end end texture:SetWidth(texturePixelWidth); texture:SetHeight(texturePixelHeight); texture:SetTexCoord(0, texturePixelWidth/textureFileWidth, 0, texturePixelHeight/textureFileHeight); texture:SetPoint("TOPLEFT", offsetX + (256 * (k-1)), -(offsetY + (256 * (j - 1)))); texture:SetTexture(textureName..(((j - 1) * numTexturesWide) + k)); texture:Show(); end end end end for i=textureCount+1, NUM_WORLDMAP_OVERLAYS do _G["WorldMapOverlay"..i]:Hide(); end [/lua]

WoW世界地图分析

一.
在游戏中
mapFileName, textureHeight, textureWidth = GetMapInfo() 获取地图信息
然后获取到地图所在的图片路径
pathPrefix = “Interface\\WorldMap\\”..mapFileName..”\\”

例如荒芜之地
Badlands, 667, 768
二.
获取覆盖层数量
numOverlays = GetNumMapOverlays()


获取覆盖层信息
local texName, texWidth, texHeight, offsetX, offsetY = GetMapOverlayInfo(1-numOverlays)


拼接算法:

for texName, texID in pairs(overlayMap) do
local textureName = pathPrefix .. texName
local textureWidth, textureHeight, offsetX, offsetY = mod(texID, 2^10), mod(floor(texID / 2^10), 2^10), mod(floor(texID / 2^20), 2^10), floor(texID / 2^30)

local numTexturesWide = ceil(textureWidth / 256)
local numTexturesTall = ceil(textureHeight / 256)
local neededTextures = textureCount + (numTexturesWide * numTexturesTall)
if neededTextures > numOv then
for j = numOv + 1, neededTextures do
local texture = frame:CreateTexture(format(frameName, j), “ARTWORK”)
tinsert(textureCache, texture)
end
numOv = neededTextures
end
local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight
for j = 1, numTexturesTall do
if j < numTexturesTall then texturePixelHeight = 256 textureFileHeight = 256 else texturePixelHeight = mod(textureHeight, 256) if texturePixelHeight == 0 then texturePixelHeight = 256 end textureFileHeight = 16 while textureFileHeight < texturePixelHeight do textureFileHeight = textureFileHeight * 2 end end for k = 1, numTexturesWide do textureCount = textureCount + 1 local texture = textureCache[textureCount] if k < numTexturesWide then texturePixelWidth = 256 textureFileWidth = 256 else texturePixelWidth = mod(textureWidth, 256) if texturePixelWidth == 0 then texturePixelWidth = 256 end textureFileWidth = 16 while textureFileWidth < texturePixelWidth do textureFileWidth = textureFileWidth * 2 end end texture:SetWidth(texturePixelWidth*scale) texture:SetHeight(texturePixelHeight*scale) texture:SetTexCoord(0, texturePixelWidth / textureFileWidth, 0, texturePixelHeight / textureFileHeight) texture:ClearAllPoints() texture:SetPoint("TOPLEFT", (offsetX + (256 * (k-1))) * scale, -(offsetY + (256 * (j - 1))) * scale) texture:SetTexture(format(textureName.."%d", ((j - 1) * numTexturesWide) + k))if discoveredOverlays[texName] then texture:SetVertexColor(1, 1, 1) texture:SetAlpha(1 - (alphaMod or 0)) texture:SetDrawLayer("ARTWORK") else texture:SetVertexColor(r, g, b) texture:SetAlpha(a * ( 1 - (alphaMod or 0))) texture:SetDrawLayer("BORDER") if db.debug then DEFAULT_CHAT_FRAME:AddMessage(format("|cff33ff99Mapster|r: Subzone: %s in zone: %s", texName, mapFileName)) end endtexture:Show() end end end [/lua]