Category Archives: 魔兽插件

新版wow解析库

对wow的数据分析已经有很长很长一段时间了. 其数据结构上大致能比较了解. 但是解析工具一直不如心愿. 当wow版本的升级, 很多数据变得多样化起来. 比如

  1. 一条数据中包含了一个子数据集(表现出来的形式是动态栏位).
  2. 有些数据栏位共享一个字节.

等等情况.

根据多年经验, 我对解析工作做了一个初步的改进.

Field

Field 栏位. 每个栏位我都建立了一个class. 用于表达此栏位的状态, 类型以及结构.

所有的栏位都是继承抽象类 AField.

abstract class AField {
    //unpack读取type, 比如Byte=> "b", int32=> "i"
    public $char;
    //读取长度
    public $size;
    //$name 字段名
    //$dynamic 如果位动态栏位,动态key
    //$group 所属父组
    //$primary_key 是否是主键?
    public function __construct($name = "", $dynamic=0, $group = null, $primary_key = false) {
	$this->name = $name;
	$this->dyn = $dynamic;
	$this->group = $group;
	$this->primary_key = $primary_key;
    }
    
    //重新命名栏位名称
    public function rename($name) {
	$this->name = $name;
	return $this;
    }
    
    //magic方法, 获取栏位名称
    public function __tostring(){
	return "[" . get_class($this).": ". $this->name . "]";
    }
}

AField中包含了栏位名称, 动态key, 动态组名, 主键?
接着创建一些基础栏位, 比如ByteField, UnsignedByteField, IntegerField, UnsignedIntegerField, StringField
再继承基础栏位, 延伸出一些特别栏位: IDField, UnknownField

Row

既然栏位已经写完了. 那么这个时候就要将栏目组成一条数组. 那就是Row.
为了能明确的表述该Row的性质, 我为此创建了DBRow. 其中包含了structures(Field集合), 每个栏位的数值.

DB

完成两个基础Field, Row之后. 这个时候就要组成一个抽象的DB.
这个DB是DBC(DB2), WDB的父类. 它包含了文件, 数据结构, 数据导入导出, 数据的读取地址库, 数据的header.
而它的子类就是实现父类这些方法.

结束

从上看来, 现在解析数据更加快捷方便. 同时能应对文章刚开始说的各种情况.

世界地图外部生成机制

根据上一篇所讲. 现在我们如何在外部生成一张地图.
一.
首先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]

How to show all partyframes in the SecureTemplates

The partyHeader only show one partyframe by the default. If you wanna show all partyframes, you add the code blew:

header:SetAttribute("startingIndex", -num)

Note: If you will debug the partyframes and show these partyframes, you set the attribute of “startingIndex” that it must be negative number !. if you set it positive number, u will cant see anything.

Protected: WSUF Tags API List

This content is password protected. To view it please enter your password below: