Here is my lua script for MMZ2
It works for both
U ver and
J ver, tested on
VBA-RR v23.6
Language: lua
local box = {
width = 15,
height = 3,
};
local enemies = {
-- 0x3004F34,
-- 0x3004FF8,
-- 0x30050BC,
-- 0x3005180,
0x03005244,
0x03005308,
0x03005490,
0x030053CC,
0x03005554,
0x03005618,
0x030056DC,
0x030057A0,
0x03005864,
0x03005928,
-- 0x30059EC,
-- 0x3005AB0,
};
local lastDash = 255;
print("MMZ2 - Memory viewer script for VBA, created by zhangsongcui");
function drawCharge(pos, val, y, text)
if val < 5 then
return false;
end
local maxVal = 120;
-- TODO: maxVal = 90;
local var = math.min(maxVal, val);
gui.box(
pos.X - box.width,
pos.Y - box.height + y,
pos.X + box.width,
pos.Y + box.height + y,
nil, "black");
gui.box(
pos.X - box.width,
pos.Y - box.height + y,
pos.X - box.width * (1 - var / maxVal * 2),
pos.Y + box.height + y,
var < maxVal / 3 and "white" or (var < maxVal and "green" or "yellow"), "clear");
gui.text(pos.X - box.width - 17, pos.Y - box.height + y, text);
gui.text(pos.X + box.width + 3, pos.Y - box.height + y, val);
return true;
end
function drawRemain(pos, val, y, maxVal, text)
if val <= 0 or val > maxVal then
return false;
end
gui.box(
pos.X - box.width,
pos.Y - box.height + y,
pos.X + box.width,
pos.Y + box.height + y,
nil, "black");
gui.box(
pos.X - box.width,
pos.Y - box.height + y,
pos.X - box.width * (1 - val / maxVal * 2),
pos.Y + box.height + y,
"white", "clear");
gui.text(pos.X - box.width - 17, pos.Y - box.height + y, text);
gui.text(pos.X + box.width + 3, pos.Y - box.height + y, val);
return true;
end
gui.register(function()
gui.opacity(.8);
local rng = memory.readlong(0x0202E188);
if rng == 0 then
return; -- 游戏还没开始
end
-- 90 290 850
-- 210
gui.text(2, 10, string.format(" RNG: 0x%08X", rng));
gui.text(82, 152, "Ingame Time: " .. memory.readlong(0x0202EBF8));
local isPlaying = memory.readword(0x0202FB78) ~= 0x03C0; -- 主角血条下面的 Z 字
if not isPlaying then
lastDash = 255;
return;
end
local camera = {
X = memory.readlongsigned(0x0202ED48),
Y = memory.readlongsigned(0x0202ED4C),
};
local hero = {
X = (memory.readlongsigned(0x02037D44) - camera.X) / 0x0100 + 120,
Y = (memory.readlongsigned(0x02037D48) - camera.Y) / 0x0100 + 80,
SpeedX = memory.readlongsigned(0x02037D4C),
SpeedY = memory.readlongsigned(0x02037D50),
HP = memory.readbyte(0x02037D94),
Invisible = memory.readbyte(0x02037D84),
Charge1 = memory.readbyte(0x02037E78),
Charge2 = memory.readbyte(0x02037E79),
Dash = memory.readbyte(0x02037E74),
};
if hero.HP <= 0 then
return;
end
for i, enemy in pairs(enemies) do
local hp = memory.readbyte(enemy);
if hp > 0 then
local x = (memory.readlong(enemy - 0x50) - camera.X) / 0x0100 + 120;
local y = (memory.readlong(enemy - 0x4C) - camera.Y) / 0x0100 + 80;
gui.text(x, y, hp);
end
end
-- gui.text(2, 18, string.format("WpnUse: [%d, %d, %d, %d]", memory.readword(0x0202EC0C), memory.readword(0x0202EC0E), memory.readword(0x0202EC10), memory.readword(0x0202EC12)));
gui.text(2, 18, string.format("WpnExp: [%d, %d, %d, %d]", memory.readword(0x02037F0A), memory.readword(0x02037F0C), memory.readword(0x02037F0E), memory.readword(0x02037F10)));
gui.text(2, 26, string.format(" Speed: (%+.1f, %+.1f)", hero.SpeedX / 0x100, hero.SpeedY / 0x100));
if hero.Dash == _G.lastDash then
hero.Dash = 255;
else
_G.lastDash = hero.Dash;
end
local dy = 4;
local offsety = 7;
if drawCharge(hero, hero.Charge1, dy, 'Crg1') then dy = dy + offsety end;
if drawCharge(hero, hero.Charge2, dy, 'Crg2') then dy = dy + offsety end;
if drawRemain(hero, hero.Invisible, dy, 90, 'Invi') then dy = dy + offsety end;
if drawRemain(hero, hero.Dash, dy, 27, 'Dash') then dy = dy + offsety end;
gui.text(hero.HP > 9 and 7 or 8, 35, hero.HP, "red");
local boss = {
X = (memory.readlongsigned(0x0203BBA4) - camera.X) / 0x0100 + 120,
Y = (memory.readlongsigned(0x0203BBA8) - camera.Y) / 0x0100 + 80,
HP = memory.readword(0x0203BBF4),
Invisible = memory.readbyte(0x0203BBE4),
InvisibleLevel = memory.readbyte(0x0203BBE6),
};
if boss.HP > 0 then
if memory.readword(0x0202FBB0) ~= 0x03C0 then -- 指定右侧 Boss 血条下的 Ω 图标显示
-- Boss 战
gui.text(boss.HP > 9 and 226 or 228, 4, boss.HP, "red", "black");
else
-- 中 Boss 战
gui.text(boss.HP > 9 and boss.X - 3 or boss.X - 1, boss.Y - 5, boss.HP, "red", "black");
end
drawRemain(boss, boss.Invisible, 5, 90, "Invi");
if (boss.Invisible > 0) then
gui.text(boss.X - box.width - 17, boss.Y + 9, "Invi Level: " .. boss.InvisibleLevel);
end
end
local bossAnother = { -- 电狼、钳子兄弟的数值
X = (memory.readlongsigned(0x0203BAC0) - camera.X) / 0x0100 + 120,
Y = (memory.readlongsigned(0x0203BAC4) - camera.Y) / 0x0100 + 80,
HP = memory.readword(0x0203BB10),
Invisible = memory.readbyte(0x0203BB00),
InvisibleLevel = memory.readbyte(0x0203BB02),
};
if bossAnother.HP > 0 then
if boss.HP == 0 then -- 这个是本尊
gui.text(bossAnother.HP > 9 and 226 or 228, 4, bossAnother.HP, "red", "black");
end
drawRemain(bossAnother, bossAnother.Invisible, 5, 90, "Invi");
if (bossAnother.Invisible > 0) then
gui.text(bossAnother.X - box.width - 17, bossAnother.Y + 9, "Invi Level: " .. bossAnother.InvisibleLevel);
end
end
end)
EDIT: Fix "<0>" by disabling HTML in this post o_o