My lua script for MMZ 1, tested U ver on VBA-RR 23.6.
It's strange that Zero's X speed is always positive, but here it is.
Language: lua
local box = {
width = 15,
height = 3,
};
local enemies = {
-- 0x0300420C,
-- 0x030042D8,
0x030043A4,
0x03004470,
0x0300453C,
0x03004608,
0x030046D4,
0x030047A0,
0x0300486C,
0x03004938,
0x03004A04,
0x03004AD0,
-- 0x03004B9C,
-- 0x03004B9C,
-- 0x03004D2C,
-- 0x03004EBC,
-- 0x0300504C,
-- 0x03005114,
0x030051DC,
0x030052A4,
0x0300536C,
0x03005434,
0x030054FC,
0x030055C4,
0x0300568C,
0x03005754,
0x0300581C,
0x030058E4,
-- 0x030059AC,
-- 0x03005B3C,
};
local lastDash = 255;
print("MMZ1 - 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(0x02022890);
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(0x0202A5D8));
local isPlaying = memory.readword(0x0202396C) ~= 0x03C0; -- 主角血条下面的 Z 字
if not isPlaying then
lastDash = 255;
return;
end
local camera = {
X = memory.readlongsigned(0x02022C74),
Y = memory.readlongsigned(0x02022C78),
};
local hero = {
X = (memory.readlongsigned(0x0202B5EC) - camera.X) / 0x0100 + 120,
Y = (memory.readlongsigned(0x0202B5F0) - camera.Y) / 0x0100 + 80,
SpeedX = memory.readlongsigned(0x0202B5F4),
SpeedY = memory.readlongsigned(0x0202B5F8),
HP = memory.readbyte(0x0202B62C),
Crystal = memory.readword(0x0202B79E),
Invisible = memory.readbyte(0x0202B634),
Charge1 = memory.readbyte(0x0202B6C2),
Charge2 = memory.readbyte(0x0202B6C3),
Dash = memory.readbyte(0x0202B6B8),
Abtn = memory.readbyte(0x0202B6C5),
Invisible2 = memory.readbyte(0x0202B6C6),
};
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 + 0x0C) - camera.X) / 0x0100 + 120;
local y = (memory.readlong(enemy + 0x10) - camera.Y) / 0x0100 + 80;
gui.text(x, y, hp);
end
end
-- gui.text(2, 18, string.format("WpnUse: [%d, %d, %d, %d]", memory.readword(0x02022B3C), memory.readword(0x02022B3E), memory.readword(0x02022B40), memory.readword(0x02022B42)));
gui.text(2, 18, string.format("WpnExp: [%d, %d, %d, %d]", memory.readwordsigned(0x0202B72C), memory.readwordsigned(0x0202B72E), memory.readwordsigned(0x0202B730), memory.readwordsigned(0x0202B732)));
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(0x0202CBFC) - camera.X) / 0x0100 + 120,
Y = (memory.readlongsigned(0x0202CC00) - camera.Y) / 0x0100 + 80,
HP = memory.readword(0x0202CC3C),
Invisible = memory.readbyte(0x0202CC44),
};
if boss.HP > 0 then
if memory.readword(0x020239A4) ~= 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");
end
local bossAnother = { -- 大象的数值
X = (memory.readlongsigned(0x0202CB6C) - camera.X) / 0x0100 + 120,
Y = (memory.readlongsigned(0x0202CB70) - camera.Y) / 0x0100 + 80,
HP = memory.readword(0x0202CB54),
Invisible = memory.readbyte(0x0202CB5C),
};
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");
end
end)
EDIT: Fix elephant's HP