fceux/output/luaScripts/vnb.lua

614 lines
17 KiB
Lua

-- Valkyrie no Bouken stuffs
-- This game sucks, don't play it
-- Lovingly based off of 4matsy's SMB code, and then mutilated and mamed as required
-- Xkeeper 2008, September 12th
require("x_functions");
x_requires(4);
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function mapdot(x,y,color)
if (x >= 1 and x <= 254 and y >= 1 and y <= 239) then
gui.drawline(x - 1, y , x + 1, y , color);
gui.drawline(x , y - 1, x , y + 2, color);
end;
end;
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function doexp()
totalexp = vnbnumber(0x00d5, 5);
growth = memory.readbyte(0x0111);
level = memory.readbyte(0x00b9);
nextlv = memory.readbyte(0x00bb);
prevexp = -1;
if level ~= 0 then
if nextlv < 0x14 then
nextexp = exptable[nextlv + 1];
else
prevexp = math.floor(totalexp / 10000) * 10000;
nextexp = math.floor(totalexp / 10000) * 10000 + 10000;
end;
if growth < 3 and prevexp == -1 then
-- prevexp = exptable[leveltable[growth][level] + 1];
end;
expval = {};
expval["level"] = level;
expval["next"] = nextexp - totalexp;
expval["prev"] = prevexp;
expval["pct"] = math.floor((totalexp - prevexp) / (nextexp - prevexp) * 100);
expval["exp"] = totalexp;
if prevexp == -1 then
expval["pct"] = -1;
end;
else
expval = {};
expval["level"] = 0;
expval["next"] = 0;
expval["prev"] = 0;
expval["pct"] = 0;
expval["exp"] = 0;
end;
return expval;
end;
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function vnbnumber(offset, length)
val = 0;
for i = 0, length do
inp = memory.readbyte(offset + (i));
if (inp ~= 0x26) then val = val + inp * (10 ^ i); end;
end;
return val;
end;
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function worldmap()
herox = memory.readbyte(0x0080) + memory.readbyte(0x0081) * 256; -- hero's X position
heroy = memory.readbyte(0x0082) + memory.readbyte(0x0083) * 256; -- hero's current MP
if mapstyle == 1 then
mapx = 8;
mapy = 9;
mapw = 60;
maph = 37;
elseif mapstyle == 2 or mapstyle == 3 then
mapx = 8;
mapy = 34;
mapw = 240;
maph = 147;
else
return nil;
end;
if gamemode == 0x05 or gamemode == 0x01 or gamemode == 0x06 or gamemode == 0x08 then
maphx = math.ceil(herox / 3840 * mapw);
maphy = math.ceil(heroy / 2352 * maph);
-- filledbox(mapx - 1, mapy - 1, mapx + mapw + 1, mapy + maph, "#000000");
box(mapx - 1, mapy - 1, mapx + mapw + 1, mapy + maph, "#ffffff");
if mapstyle == 3 then
for i = 0, 0xFF do
mappx = math.ceil((3840 / 16) * math.fmod(i, 0x10) / 3840 * mapw);
mappy = math.ceil((2352 / 16) * math.floor(i / 0x10) / 2352 * maph);
mappx2 = math.ceil((3840 / 16) * (math.fmod(i, 0x10) + 1) / 3840 * mapw) - 1;
mappy2 = math.ceil((2352 / 16) * (math.floor(i / 0x10) + 1) / 2352 * maph) - 1;
tmp = memory.readbyte(0x81E5 + i) * 2;
filledbox(mapx + mappx, mapy + mappy, mapx + mappx2, mapy + mappy2, string.format("#%02x%02x%02x", tmp, tmp, tmp));
end;
end;
if math.fmod(timer, 60) >= 30 then
color = "#888888";
else
color = "#bbbbbb";
end;
-- line(mapx, mapy + maphy, mapx + mapw, mapy + maphy, "#cccccc");
-- line(mapx + maphx, mapy, mapx + maphx, mapy + maph, "#cccccc");
mapdist = 51;
for i = 1, mappoints do
mappx = math.ceil(mapdots[i]["x"] / 3840 * mapw);
mappy = math.ceil(mapdots[i]["y"] / 2352 * maph);
mapdot(mapx + mappx, mapy + mappy, mapdots[i]["color"]);
if mapdots[i]["name"] then
mapdotdist = math.abs(mapdots[i]["x"] - herox) + math.abs(mapdots[i]["y"] - heroy);
if mapdotdist < mapdist then
mapdist = mapdotdist;
mapdistn = mapdots[i]["name"];
end;
end;
end;
if mapdist <= 50 then
text(90, 17, mapdistn);
end;
filledbox(mapx + maphx - 0, mapy + maphy - 0, mapx + maphx + 0, mapy + maphy + 0, "#ffffff");
box(mapx + maphx - 1, mapy + maphy - 1, mapx + maphx + 1, mapy + maphy + 1, color);
-- text(mapx + 0, mapy + maph + 2, string.format("%04d, %04d", herox, heroy));
end;
end;
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function gameloop()
if gamemode == 0x01 and math.fmod(timer, 60) >= 30 then
text(105, 180, "< DEMO >");
end;
herohp = memory.readbyte(0x00c0) + memory.readbyte(0x00c1) * 256; -- hero's current HP
heromp = memory.readbyte(0x00c2) + memory.readbyte(0x00c3) * 256; -- hero's current MP
heromaxhp = memory.readbyte(0x00c4) + memory.readbyte(0x00c5) * 256; -- hero's maximum HP
heromaxmp = memory.readbyte(0x00c6) + memory.readbyte(0x00c7) * 256; -- hero's maximum MP
money = vnbnumber(0x00d0, 4);
gametime = memory.readbyte(0x0031) * 0x3c + memory.readbyte(0x0030); -- game-time
gamehour = math.floor(gametime / 320);
gameminute = math.floor((gametime - 320 * gamehour) / 320 * 60);
expval = doexp();
worldmap();
filledbox(96, 194, 255, 244, "#000000");
text(191, 8, string.format("Time: %02d:%02d", gamehour, gameminute));
-- text(188, 23, string.format("GameMode: %02x", gamemode));
text( 90, 194, string.format("HP %3d/%3d MP %3d/%3d", herohp, heromaxhp, heromp, heromaxmp));
if expval["next"] > 0 then
text( 90, 218, string.format("Lv.%2d: %6d XP Next %6d", expval["level"], expval["exp"], expval["next"]));
else
text( 90, 218, string.format("Lv.%2d: %6d EXP", expval["level"], expval["exp"]));
end;
text(217, 202, string.format("ATK %2d", memory.readbyte(0x00e7)));
text(217, 210, string.format("$%5d", money));
lifebar(191, 16, 60, 2, gamehour, 24, "#ffffff", "#777777", true);
lifebar(191, 20, 60, 0, gameminute, 60, "#cccccc", "#555555", true);
lifebar( 90, 202, 123, 4, herohp, heromaxhp, "#ffcc00", "#880000", true);
lifebar( 90, 208, 123, 3, heromp, heromaxmp, "#9999ff", "#0000dd", true);
if expval["pct"] ~= -1 then
lifebar( 90, 226, 162, 2, expval["pct"], 100, "#ffffff", "#555555", true);
end;
box(89, 194, 91, 244, "#000000");
line(90, 194, 90, 244, "#000000");
if not enemy then enemy = {} end;
if gamemode == 0x05 or gamemode == 0x01 or gamemode == 0x06 then
for i = 0, 5 do
offset = 0x500 + 0x10 * i;
if not enemy[i] then
enemy[i] = {};
end;
if (memory.readbyte(offset) > 0) then
if not enemy[i]["maxhp"] then enemy[i]["maxhp"] = 0 end;
enemy[i]["t"] = memory.readbyte(offset);
enemy[i]["x"] = memory.readbyte(offset + 5);
enemy[i]["y"] = memory.readbyte(offset + 6);
enemy[i]["hp"] = memory.readbyte(offset + 15);
enemy[i]["maxhp"] = math.max(enemy[i]["maxhp"], enemy[i]["hp"]);
enemy[i]["item"] = memory.readbyte(offset + 10);
if enemy[i]["t"] > 1 then
text(enemy[i]["x"] - 9, enemy[i]["y"] - 16, enemy[i]["hp"] .."/".. enemy[i]["maxhp"]);
lifebar(enemy[i]["x"] - 5, enemy[i]["y"] - 8, 22, 0, enemy[i]["hp"], enemy[i]["maxhp"], "#ffcc00", "#dd0000", false);
else
if (enemy[i]["item"] == 0x1C) then
if enemy[i]["hp"] == 0 then enemy[i]["hp"] = 10 end;
if enemy[i]["hp"] == 9 then enemy[i]["hp"] = 99 end;
text(enemy[i]["x"] - 6 - math.min(math.floor(enemy[i]["hp"] / 10) * 2, 2), enemy[i]["y"] - 8, "$".. enemy[i]["hp"]);
else
box(enemy[i]["x"], enemy[i]["y"], enemy[i]["x"] + 15, enemy[i]["y"] + 15, "#ffffff");
text(enemy[i]["x"] - string.len(itemlist[enemy[i]["item"]]) * 1.75 + 0, enemy[i]["y"] - 8, itemlist[enemy[i]["item"]]);
end;
end;
else
enemy[i] = {};
end;
end;
end;
for i = 0, 7 do
offset = 0x0160 + 0x02 * i;
item = memory.readbyte(offset + 1);
uses = memory.readbyte(offset + 1);
xo = math.fmod(i, 4);
yo = math.floor(i / 4);
if (item > 0 and (uses > 0 and uses < 255)) then
text(xo * 12 + 8, 194 + yo * 16, uses);
end;
end;
--[[-- auto-regenerate HP
if (herohp < heromaxhp) and ((math.fmod(timer, 3) == 0) or true) then
herohp = herohp + 1;
memory.writebyte(0x00c0, math.fmod(herohp, 256));
memory.writebyte(0x00c1, math.floor(herohp / 256));
end;
--]]--
--[[ basically the Big Cheating Section.
if not expbooster then expbooster = 0 end;
expbooster = expbooster + 1;
if expbooster >= 3 and gamemode == 0x06 then
expbooster = 0;
memory.writebyte(0x0d5, memory.readbyte(0x00d5) + 1);
for i = 0,5 do
inp = memory.readbyte(0x00d5 + i);
if (inp == 0x0a) then
memory.writebyte(0x00d5 + (i + 1), memory.readbyte(0x00d5 + (i + 1)) + 1);
memory.writebyte(0x00d5 + i, 0);
elseif (inp == 0x27) then
memory.writebyte(0x00d5 + i, 1);
end;
end;
end;
]]--
end;
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function charaselect()
asign = memory.readbyte(0x0110);
btype = memory.readbyte(0x0111);
-- line( 92, 30, 92, 130, "#ffffff");
filledbox( 13, 48, 96, 64, "#000000"); -- cover JP text
filledbox( 13, 80, 96, 96, "#000000"); -- cover JP text
filledbox( 13, 112, 96, 128, "#000000"); -- cover JP text
filledbox(160, 48, 231, 64, "#000000"); -- cover JP text
text( 74, 24, " Create your character ");
text( 15, 51, "Astrological sign:");
text(158, 51, string.format("%s", asigns[asign]));
text( 41, 83, "Blood type:");
-- text(164, 83, string.format("%s (%X)", btypes[btype], btype));
text( 26, 115, "Clothing color:");
asign2 = math.fmod(asign, 4);
if asign2 == 0 then
shp = 64;
smp = 32;
elseif asign2 == 1 then
shp = 48;
smp = 48;
elseif asign2 == 2 then
shp = 32;
smp = 64;
elseif asign2 == 3 then
shp = 33;
smp = 63;
end;
strength = 10 + math.floor(shp / 32);
text( 8, 135, "Starting HP: ");
text( 8, 143, "Starting MP: ");
text(167, 135, " ".. shp);
text(167, 143, " ".. smp);
lifebar( 68, 136, 100, 4, shp, 64, "#ffcc00", "#880000");
lifebar( 68, 144, 100, 4, smp, 64, "#9999ff", "#0000dd");
text(194, 136, "Strength: ".. strength);
text(194, 146, "Magic:");
if smp >= 60 then
text(204, 162, "Fireball");
end;
if smp >= 40 then
text(204, 154, "Heal");
end;
graphx = 17;
graphy = 160;
text(graphx - 10, graphy + 63, "Lv.");
for i = 1, 12 do
thispointx = i * 15 + graphx;
line(thispointx, graphy, thispointx, graphy + 63, "#000088");
text(thispointx - 4 - (string.len(string.format("%d", i)) - 1) * 3, graphy + 63, string.format("%d", i));
end;
for i = 0, 7 do
lg = i * 3;
thispointy = graphy + 63 - (lg) * 3;
line(graphx + 15, thispointy, graphx + 180, thispointy, "#000088");
if exptable[lg] then
temp = string.format("%d", exptable[lg]);
text(graphx - 17, thispointy - 4, string.format("%5d", exptable[lg]));
end;
end;
line(graphx + 15, graphy , graphx + 15, graphy + 63, "#9999ff");
line(graphx + 15, graphy + 63, graphx + 180, graphy + 63, "#9999ff");
-- filledbox(graphx + 19, graphy + 1, graphx + 73, graphy + 8, "#666666");
text(graphx + 16, graphy - 1, "EXP Growth");
if btype <= 2 then
lastpointx = graphx;
lastpointy = graphy + 180;
for i = 1, 12 do
thispointx = i * 15 + graphx;
thispointy = graphy + 63 - (leveltable[btype][i] * 3);
line(lastpointx, lastpointy, thispointx, thispointy, "#ffffff");
lastpointx = thispointx;
lastpointy = thispointy;
end;
else
-- filledbox(graphx + 75, graphy + 27, graphx + 119, graphy + 35, "#666666");
text(graphx + 74, graphy + 26, " Random ");
end;
line(194, 145, 254, 145, "#000000");
line( 8, 153, 192, 153, "#000000");
end;
-- ************************************************************************************
-- ************************************************************************************
-- ************************************************************************************
function keyintercept()
tmp = memory.readbyte(0x0026);
if AND(tmp, 0x04) == 0x04 then
mapstyle = math.fmod(mapstyle + 1, 3)
end;
-- memory.writebyte(0x0026, AND(tmp, 0xFB));
end;
memory.register(0x0026, keyintercept);
timer = 0;
mapstyle = 1; -- 0 = hidden, 1 = mini, 2 = bigmap
gamemode = 0;
itemlist = {};
itemlist[0x01] = "Lantrn";
itemlist[0x02] = "Lantrn2";
itemlist[0x03] = "Potion";
itemlist[0x04] = "Potion2";
itemlist[0x05] = "Antidt";
itemlist[0x06] = "Antidt2";
itemlist[0x07] = "Key";
itemlist[0x08] = "GoldKey";
itemlist[0x09] = "Ax";
itemlist[0x0a] = "Ax2";
itemlist[0x0b] = "Sword";
itemlist[0x0c] = "Sword2";
itemlist[0x0d] = "PwSword";
itemlist[0x0e] = "PwSword2";
itemlist[0x0f] = "MsSword";
itemlist[0x10] = "SandraSl";
itemlist[0x11] = "Mantle";
itemlist[0x12] = "Mantle2";
itemlist[0x13] = "Helmet";
itemlist[0x14] = "Helmet2";
itemlist[0x15] = "Tent";
itemlist[0x16] = "Tent2";
itemlist[0x17] = "Tiara";
itemlist[0x18] = "Whale";
itemlist[0x19] = "CureAll";
itemlist[0x1a] = "TimeKey";
itemlist[0x1b] = "Ship";
itemlist[0x1c] = "Cash";
exptable = {
0,
20,
50,
90,
150,
230,
350,
510,
750,
1100,
1600,
2200,
3200,
4400,
6400,
9000,
12000,
15000,
20000,
30000,
40000,
50000,
};
leveltable = {};
leveltable[0] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x13, 0x14};
leveltable[1] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x0A, 0x0D, 0x10, 0x13, 0x14, 0x15};
leveltable[2] = { 0x00, 0x03, 0x06, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13};
asigns = {};
asigns[0x00] = "Aries";
asigns[0x01] = "Taurus";
asigns[0x02] = "Gemini";
asigns[0x03] = "Cancer";
asigns[0x04] = "Leo";
asigns[0x05] = "Virgo";
asigns[0x06] = "Libra";
asigns[0x07] = "Scorpio";
asigns[0x08] = "Sagittarius";
asigns[0x09] = "Capricorn";
asigns[0x0A] = "Aquarius";
asigns[0x0B] = "Pisces";
btypes = {};
btypes[0x00] = "A";
btypes[0x01] = "B";
btypes[0x02] = "O";
btypes[0x03] = "AB";
mapdots = {};
mapdots[1] = {x = 996, y = 1888, color = "#4444ff"}; -- house
mapdots[2] = {x = 773, y = 989, color = "#4444ff"}; -- house
mapdots[3] = {x = 266, y = 2263, color = "#00ff00"}; -- warp point
mapdots[4] = {x = 1800, y = 216, color = "#00ff00"}; -- warp point
mapdots[5] = {x = 776, y = 344, color = "#00ff00"}; -- warp point
mapdots[6] = {x = 2055, y = 2008, color = "#00ff00"}; -- warp point
mapdots[7] = {x = 1863, y = 2045, color = "#dd0000", name = "South Pyramid"}; -- s.pyramid
mapdots[8] = {x = 1607, y = 381, color = "#dd0000", name = "North Pyramid"}; -- n.pyramid
mappoints = table.maxn(mapdots);
while (true) do
timer = timer +1; -- timer for script events
gamemode = memory.readbyte(0x0029); -- game mode
if gamemode == 0x05 or gamemode == 0x01 or gamemode == 0x06 or gamemode == 0x08 then
gameloop();
elseif gamemode == 0x02 then
charaselect();
else
-- gametime = memory.readbyte(0x0031) * 0x3c + memory.readbyte(0x0030); -- game-time
-- gamehour = math.floor(gametime / 320);
-- gameminute = math.floor((gametime - 320 * gamehour) / 320 * 60);
gametimer1 = memory.readbyte(0x0031);
gametimer2 = memory.readbyte(0x0030);
text(190, 8, string.format("Timer: %02X %02X", gametimer1, gametimer2));
text(189, 23, string.format("GameMode: %02x", gamemode));
lifebar(191, 16, 60, 2, gametimer1, 0x80, "#ffffff", "#777777", true);
lifebar(191, 20, 60, 0, gametimer2, 0x3c, "#cccccc", "#555555", true);
end;
FCEU.frameadvance();
end;