In an attempt to inspire others to do more open TASing, and share knowledge, I'm posting as many scripts and stuff as I can find.
My main battle script for FF8. I liked it a lot.
Download FF8Battle.luaLanguage: lua
BlockAdvance =2;
Items = {"Potion","Potion+","Hi-Potion","Hi-Potion+","X-Potion","Mega-Potion","Phoenix Down","Mega Phoenix","Elixir","Megalixir","Antidote",
"Soft","Eye Drops","Echo Screen","Holy Water","Remedy","Remedy+","Hero-trial","Hero","Holy War-trial","Holy War","Shell Stone","Protect Stone",
"Aura Stone","Death Stone","Holy Stone","Flare Stone","Meteor Stone","Ultima Stone","Gysahl Greens","Phoenix Pinion","Friendship","Tent",
"Pet House","Cottage","G-Potion","G-Hi Potion","G-Mega-Potion","G-Returner","Rename Card","Amnesia Greens","HP-J Scroll","Str-J Scroll",
"Vit-J Scroll","Mag-J Scroll","Spr-J Scroll","Spd-J Scroll","Luck-J Scroll","Aegis Amulet","Elem Atk","Elem Guard","Status Atk","Status Guard",
"Rosetta Stone","Magic Scroll","GF Scroll","Draw Scroll","Item Scroll","Gambler Spirit","Healing Ring","Phoenix Spirit","Med Kit","Bomb Spirit",
"Hungry Cookpot","Mog's Amulet","Steel Pipe","Star Fragment","Energy Crystal","Samantha Soul","Healing Mail","Silver Mail","Gold Armor",
"Diamond Armor","Regen Ring","Giant's Ring","Gaea's Ring","Strength Love","Power Wrist","Hyper Wrist","Turlte Shell","Orihalcon","Adamantine",
"Rune Armlet","Force Armlet","Magic Armlet","Circlet","Hypno Crown","Royal Crown","Jet Engine","Rocket Engine","Moon Curtain","Steel Curtain",
"Glow Curtain","Accelerator","Monk's Code","Knight's Code","Doc's Code","Hundred Needles","Three Stars","Ribbon","Normal Ammo","Shotgun Ammo",
"Dark Ammo","Fire Ammo","Demolition Ammo","Fast Ammo","AP Ammo","Pulse Ammo","M-Stone Piece","Magic Stone","Wizard Stone","Ochu Tentacle",
"Healing Water","Cockatrice Pinion","Zombie Powder","Lightweight","Sharp Spike","Screw","Saw Blade","Mesmerize Blade","Vampire Fang",
"Fury Fragment","Betrayal Sword","Sleep Powder","Life Ring","Dragon Fang","Spider Web","Coral Fragment","Curse Spike","Black Hole","Water Crystal",
"Missile","Mystery Fluid","Running Fire","Inferno Fang","Malboro Tentacles","Whisper","Laser Cannon","Barrier","Power Generator","Dark Matter",
"Bomb Fragment","Red Fang","Arctic Wind","North Wind","Dynamo Stone","Shear Feather","Venom Fang","Steel Orb","Moon Stone","Dino Bone","Windmill",
"Dragon Skin","Fish Fin","Dragon Fin","Silence Powder","Poison Powder","Dead Spirit","Chef's Knife","Cactus Thorn","Shaman Stone","Fuel",
"Girl Next Door","Sorceress' Letter","Chocobo's Tag","Pet Nametag","Solomon Ring","Magical Lamp","HP Up","Str Up","Vit Up","Mag Up","Spr Up",
"Spd Up","Luck Up","LuvLuvG","Weapons Mon 1st","Weapons Mon Mar","Weapons Mon Apr","Weapons Mon May","Weapons Mon Jun","Weapons Mon Jul",
"Weapons Mon Aug","Combat King 001","Combat King 002","Combat King 003","Combat King 004","Combat King 005","Pet Pals Vol.1","Pet Pals Vol.2",
"Pet Pals Vol.3","Pet Pals Vol.4","Pet Pals Vol.5","Pet Pals Vol.6","Occult Fan I","Occult Fan II","Occult Fan III","Occult Fan IV"};
StepVals = {7, 182, 240, 31, 85, 91, 55, 227, 174, 79, 178, 94, 153, 246, 119, 203, 96, 143, 67, 62, 167, 76, 45, 136, 199, 104, 215, 209, 194, 242, 193, 221, 170, 147, 22, 247, 38,
4, 54, 161, 70, 78, 86, 190, 108, 110, 128, 213, 181, 142, 164, 158, 231, 202, 206, 33, 255, 15, 212, 140, 230, 211, 152, 71, 244, 13, 21, 237, 196, 228, 53, 120, 186, 218, 39, 97,
171, 185, 195, 125, 133, 252, 149, 107, 48, 173, 134, 0, 141, 205, 126, 159, 229, 239, 219, 89, 235, 5, 20, 201, 36, 44, 160, 60, 68, 105, 64, 113, 100, 58, 116, 124, 132, 19, 148,
156, 150, 172, 180, 188, 3, 222, 84, 220, 197, 216, 12, 183, 37, 11, 1, 28, 35, 43, 51, 59, 151, 27, 98, 47, 176, 224, 115, 204, 2, 74, 254, 155, 163, 109, 25, 56, 117, 189, 102, 135,
63, 175, 243, 251, 131, 10, 18, 26, 34, 83, 144, 207, 122, 139, 82, 90, 73, 106, 114, 40, 88, 138, 191, 14, 6, 162, 253, 250, 65, 101, 210, 77, 226, 92, 29, 69, 30, 9, 17, 179, 95, 41,
121, 57, 46, 42, 81, 217, 93, 166, 234, 49, 129, 137, 16, 103, 245, 169, 66, 130, 112, 157, 146, 87, 225, 61, 241, 249, 238, 8, 145, 24, 32, 177, 165, 187, 198, 72, 80, 154, 214, 127,
123, 233, 117, 223, 50, 111, 52, 168, 208, 184, 99, 200, 192, 236, 75, 232, 23, 248};
Critical = {99, 6, 240, 35, 248, 229, 168, 1, 193, 174, 127, 72, 123, 177, 220, 9, 34, 109, 125, 238, 157, 88, 213, 85, 36, 57, 122, 223, 142, 84, 108,
27, 192, 11, 208, 67, 216, 154, 71, 93, 33, 2, 23, 75, 219, 17, 175, 112, 205, 77, 52, 73, 114, 145, 45, 98, 151, 89, 69, 247, 110, 70, 170,
10, 163, 200, 49, 146, 56, 250, 212, 230, 203, 243, 222, 107, 187, 241, 28, 60, 214, 173, 178, 169, 221, 87, 66, 149, 12, 121, 37, 31, 188,
231, 172, 91, 131, 40, 118, 242, 24, 218, 135, 161, 97, 111, 190, 90, 94, 81, 239, 176, 201, 21, 116, 137, 189, 209, 162, 117, 215, 153, 133,
76, 79, 210, 191, 74, 32, 8, 86, 160, 80, 58, 103, 38, 65, 51, 183, 186, 251, 48, 207, 124, 132, 44, 50, 233, 29, 22, 130, 120, 164, 128, 101,
95, 14, 39, 185, 25, 195, 167, 182, 0, 59, 252, 136, 225, 198, 147, 254, 139, 217, 184, 19, 105, 47, 100, 18, 55, 253, 119, 226, 181, 4, 224, 26,
140, 143, 180, 204, 249, 96, 235, 41, 227, 144, 165, 104, 61, 129, 115, 63, 171, 126, 179, 15, 206, 196, 53, 148, 150, 134, 113, 211, 42, 228, 159,
156, 236, 78, 20, 245, 234, 64, 166, 246, 3, 152, 197, 7, 244, 43, 194, 62, 232, 155, 54, 83, 46, 141, 13, 82, 16, 102, 30, 237, 138, 68, 158, 5,
255, 92, 199, 106, 202, 99, 6, 240, 35, 248, 229, 168, 1, 193, 174, 127, 72, 123, 177, 220, 9, 34, 109, 125, 238, 157, 88, 213, 85, 36, 57, 122, 223, 142, 84, 108,
27, 192, 11, 208, 67, 216, 154, 71, 93, 33, 2, 23, 75, 219, 17, 175, 112, 205, 77, 52, 73, 114, 145, 45, 98, 151, 89, 69, 247, 110, 70, 170,
10, 163, 200, 49, 146, 56, 250, 212, 230, 203, 243, 222, 107, 187, 241, 28, 60, 214, 173, 178, 169, 221, 87, 66, 149, 12, 121, 37, 31, 188,
231, 172, 91, 131, 40, 118, 242, 24, 218, 135, 161, 97, 111, 190, 90, 94, 81, 239, 176, 201, 21, 116, 137, 189, 209, 162, 117, 215, 153, 133,
76, 79, 210, 191, 74, 32, 8, 86, 160, 80, 58, 103, 38, 65, 51, 183, 186, 251, 48, 207, 124, 132, 44, 50, 233, 29, 22, 130, 120, 164, 128, 101,
95, 14, 39, 185, 25, 195, 167, 182, 0, 59, 252, 136, 225, 198, 147, 254, 139, 217, 184, 19, 105, 47, 100, 18, 55, 253, 119, 226, 181, 4, 224, 26,
140, 143, 180, 204, 249, 96, 235, 41, 227, 144, 165, 104, 61, 129, 115, 63, 171, 126, 179, 15, 206, 196, 53, 148, 150, 134, 113, 211, 42, 228, 159,
156, 236, 78, 20, 245, 234, 64, 166, 246, 3, 152, 197, 7, 244, 43, 194, 62, 232, 155, 54, 83, 46, 141, 13, 82, 16, 102, 30, 237, 138, 68, 158, 5,
255, 92, 199, 106, 202 }
AtkDmg = {-1, 5, 7, 0, 16, 29, 2, 0, 27, 7, 27, 5, 22, 10, 21, 7, 0, 9, 24, 5, 24, 21, 14, 17, 2, 22, 22, 24, 9, 17, 7, 26, 26, 10, 9, 0, 17, 21, 4,
26, -1, 0, 22, 7, 19, 16, 9, 12, 5, 10, 17, 5, 14, 12, 10, 31, 17, 22, 2, 16, 10, 2, 4, 9, 29, 0, 16, 12, 22, 17, 12, 31, 4, 10, 22, 7, 21, 9, 27,
26, 16, 7, 12, 2, 22, 19, -1, 16, 10, 21, 2, 29, 22, -1, 5, 24, 31, 5, 17, 10, 22, 19, 2, 27, 29, 10, 24, 22, 27, 14, 7, 10, 2, 19, 16, 4, 22,
10, 29, 17, 16, 19, 0, 9, 12, 10, 24, 7, 31, 7, 19, 27, 12, 24, 2, 4, 31, 17, 17, 19, 19, 14, 7, 24, -1, 10, 16, 0, 27, 21, 29, 19, 31, 27, 0,
27, 12, 5, 19, 24, 29, 0, 16, -1, 24, 19, 2, 26, -1, 14, 22, 5, 17, 17, 17, 5, 12, 0, 17, 21, 21, 19, 27, 16, 2, 24, 24, 7, 10, 14, 5, 17, 29, 2,
7, 27, 10, -1, 4, 27, 29, 16, 29, 5, 26, 12, 14, 7, 29, 19, 16, 17, 0, 12, 12, 7, 29, 26, 22, 4, 10, 19, 12, 2, 29, 0, 14, 2, 19, 31, 5, 12,
9, 27, 27, 0, 22, 19, 16, 12, 7, 12, 16, 16, 2, 29, 5, 5, 0, 24, 4, 22, 24, 0, 5, 2}
Characters = {"Squall","Zell","Irvine","Quistis","Rinoa","Selphie","Seifer","Edea","Laguna","Kiros","Ward"};
pReady = { 0x83014, 0x83018, 0x83054, 0x830CC, 0x8308C, 0x83090 }
btPressed = { 0, 0, 0, 0, 0, 0 }
RNGBase = 0x000EEBA8;
RNGOffset = 0x000EEBB0;
BATTLE = 0x0000867C;
EnemyATB = 0x000ED3DC;
EHP = 0x000ED3E0;
HP = 0xED170;
MaxHP = 0xED174;
ATB = 0xED16C;
INBATTLE = 0x73651; --80
INBATTLE = 0x00078AA3;
Char = 0xED213;
Stats = {"Lvl","Str","Vit","Mag", "Spr", "Spd", "Lck", "Eva", "Hit"};
Lvl = 0xED214;
Str = 0xED215;
Vit = 0xED216;
Mag = 0xED217;
Spr = 0xED218;
Spd = 0xED219;
Lck = 0xED21A;
Eva = 0xED21B;
Hit = 0xED21C;
Crisis = 0x000ED222;
Card = 0x78D30;
Ix = 0x00078D00;
Selection = 0x0010331C;
Esel = 0x00103338;
Damage = 0x000ED992;
AttackType = 0x00102EA0;
keys = {};
last_keys = {};
X = savestate.create();
Of = 0xD0;
function EStat(Num)
Offset = Of*(Num+3);
gui.text(230,30, memory.readbyte(Char+Offset));
for i = 1,9,1 do
gui.text(250,30+i*10,string.format("%s-%d", Stats[i], memory.readbyte(Char+Offset+i)));
end;
end;
--*****************************************************************************
function press(button)
--*****************************************************************************
-- Checks if a button is pressed.
-- The tables it accesses should be obvious in the next line.
if keys[button] and not last_keys[button] then
return true
end
return false
end
Hold = {};
Hold[1] = false;
Hold[2] = false;
Hold[3] = false;
EHold = false;
PNum = 3;
page = 0;
function RenzokuenTest()
end;
function PDisp(Num)
for i = 1,9,1 do
gui.text(10,30+i*10,string.format("%s-%d", Stats[i], memory.readbyte(Char+Sel*Of+i)));
end;
end;
function Display()
if memory.readbyte(Selection) < 3 then
Sel = memory.readbyte(Selection);
gui.text(1,30,Characters[math.min(memory.readbyte(Char+Sel*Of)+1,11)]);
if (memory.readword(AttackType) == 25452) then
SE = (memory.readbyte(Esel)-112)/32 + 3;
Dmg = math.floor(memory.readbyte(Str+Of*Sel)* memory.readbyte(Str+Of*Sel) / 16 + memory.readbyte(Str+Of*Sel));
Dmg = math.floor(Dmg * (265 - memory.readbyte(Vit+Of*SE))/256);
Dmg = math.floor(Dmg * 20/16);
gui.text(100,20, string.format("Base Damage: %d", Dmg));
gui.text(200,1,"RNG - DMG");
for i = 0,10,1 do
n = 0;
if memory.readbyte(Hit+Sel*Of) < 255 then
RNGx = math.mod(memory.readbyte(RNG)+i+2+page*10,256);
RNGval = AtkDmg[RNGx+1];
DmgR = math.floor(Dmg * (RNGval+1+240) / 256);
RNGx = math.mod(memory.readbyte(RNG)+i+1+page*10,256);
RNGval = Critical[RNGx+1];
if (memory.readbyte(Lck+Of*Sel) >= RNGval) then
DmgR = DmgR*2;
end;
else
RNGx = math.mod(memory.readbyte(RNG)+i+page*10,256);
RNGval = AtkDmg[RNGx+1];
DmgR = math.floor(Dmg * (RNGval+1+240) / 256);
end;
gui.text(200,11+i*10, string.format("%3d - %d",RNGx, DmgR));
end;
else
gui.text(200,1,"RNG - CL");
for i =0,10,1 do
HPMod = math.floor(2500 * memory.readword(HP+Of*Sel) /memory.readword(MaxHP+Of*Sel));
RNGx = math.mod(memory.readbyte(RNG)+i+page*10,256);
RandomMod = Critical[RNGx+1]+160;
LimitLevel =(1600 - HPMod) / RandomMod;
CL = math.max(math.min(LimitLevel-4,4),0);
if CL > 0 then
if Sel == 1 then
RHits = CL + 3;
if Critical[RNGx+1] < 128 then
RHits = RHits + 1;
end;
if Critical[RNGx+2] < (CL * 60 + 1) then
Finisher = "RD";
else
Finisher = "";
end;
RHits2 = CL + 3;
if Critical[RNGx+2] < 128 then
RHits2 = RHits2 + 1;
end;
if Critical[RNGx+3] < (CL * 60 + 1) then
Finisher2 = "RD";
else
Finisher2 = " ";
end;
gui.text(200,11+i*10, string.format("%3d - %d, %dH %2s +1 %dH %s",RNGx+1,CL,RHits, Finisher,RHits2, Finisher2));
else
gui.text(200,11+i*10, string.format("%3d - %d",RNGx+1,CL));
end;
end;
end;
end;
end;
for i = 0,4,1 do
if memory.readbyte(Ix+1+2*i) > 0 then
gui.text(100, 71+i*10, string.format("%d %s",memory.readbyte(Ix+1+2*i),Items[memory.readbyte(Ix+i*2)]));
end;
end;
if (memory.readbyte(Card) < 255) then
gui.text(100, 61,string.format("Card: %d",memory.readbyte(Card)));
end;
if (memory.readbyte(Card+1) < 255) then
gui.text(140, 61,string.format("Card: %d",memory.readbyte(Card+1)));
end;
if (memory.readbyte(Card+2) < 255) then
gui.text(160, 61,string.format("Card: %d",memory.readbyte(Card+2)));
end;
gui.text(100,11,string.format("Damage: %d Target %d", memory.readword(Damage), memory.readbyte(0xED7EC+Of*2)));
for i = 0,EnNum-1,1 do
gui.text(200,172-10*(EnNum-i),string.format("Enemy %d %4d", i+1, memory.readword(EHP+Of*i)));
if EHold then
gui.text(290,172-10*(EnNum-i),"HOLD","Red");
else
gui.text(290,172-10*(EnNum-i),string.format("%4d",memory.readword(EnemyATB+Of*i)));
end;
end;
for i = 0,PNum-1,1 do
if memory.readword(HP+Of*i) > 0 then
gui.text(220,175+15*i,string.format("%d %4d", memory.readbyte(Crisis+Of*i), memory.readword(HP+Of*i)));
if Hold[i+1] then
gui.text(290,175+15*i,"HOLD","Red");
else
gui.text(290,175+15*i,string.format("%4d",memory.readword(ATB+Of*i)));
end;
end;
end;
end;
function comparemouse(x1,y1,x2,y2)
mousepass = false;
if (keys.xmouse >= x1) and (keys.xmouse <= x2) and (keys.ymouse >= y1) and (keys.ymouse <= y2) then
mousepass = true;
end;
end;
while true do
if memory.readbyte(INBATTLE)==0 then
EnNum = 0;
for i = 0,3,1 do
Offset = Of*(i+3);
if memory.readbyte(Char+Offset) < 255 then
EnNum = i+1;
end;
end;
RNG = RNGBase + memory.readbyte(RNGOffset);
gui.text(100,1,string.format("%d RNG: %d, (%d)", memory.readbyte(RNGOffset), memory.readbyte(RNG), Critical[memory.readbyte(RNG)+1]));
--gui.text(100,21,string.format("Advance: %d", BlockAdvance*100));
if EHold then
for i = 0,EnNum-1,1 do
memory.writebyte(EnemyATB+Of*i,0);
end;
end;
for i = 0,PNum-1,1 do
if (Hold[i+1]) then
memory.writebyte(ATB+Of*i,0);
end;
end;
Display();
emu.frameadvance();
keys = input.get();
if (press('K')) then
Enum = 3;
last_keys = keys;
Last_RNG = memory.readbyte(RNG);
savestate.save(X);
stop = false;
i = 0;
EnNum = 4;
while (not stop) do
savestate.load(X);
memory.writebyte(RNG,math.mod((Last_RNG+i),256));
for j=1,BlockAdvance*100,1 do
gui.text(100,1,math.mod(Last_RNG+i,256));
gui.text(130,1,Critical[math.mod(Last_RNG+i,256)+1]);
gui.text(10,51,string.format("TESTING"));
Display();
emu.frameadvance();
keys = input.get();
if press('K') then stop = true; break; end;
last_keys = keys;
end;
i = i+1;
end;
end;
if press('pageup') then
page = page - 1;
end;
if press('pagedown') then
page = page + 1;
end;
if (keys.leftclick) then
for i = 0,EnNum-1,1 do
comparemouse(200,173+15*i, 250, 187+15*i);
if (mousepass) then
EStat(i);
end;
end;
end;
if press('leftclick') then
comparemouse(250,162-10*EnNum,310, 162);
if (mousepass) then
EHold = not EHold;
end;
for i = 0,PNum-1,1 do
comparemouse(250,162+15*i, 310, 177+15*i);
if (mousepass) then
Hold[i+1] = not Hold[i+1];
end;
end;
end;
last_keys = keys;
else
for i = 1,# btPressed do
ready = memory.readbyte(pReady[i])
if ready == 1 then
if btPressed[i] == 0 or btPressed[i] == 10 then
joypad.set(1,{["x"]=true})
btPressed[i] = 1
end
elseif ready == 10 then
if btPressed[i] == 0 or btPressed[i] == 1 then
joypad.set(1,{["x"]=true})
btPressed[i] = 10
end
else
btPressed[i] = 0
end
-- gui.text(40,10+(i*8),btPressed[i] .. " " .. ready)
end
emu.frameadvance();
gui.text(1, 30, 'Dialog Skip');
end;
end;
This is my Step-Detection script - allows you to determine the next battle, and whether or not you should stutter walk. Never got it to work perfect for the next set.
Download StepScript.luaLanguage: lua
StepVals = {7, 182, 240, 31, 85, 91, 55, 227, 174, 79, 178, 94, 153, 246, 119, 203, 96, 143, 67, 62, 167, 76, 45, 136, 199, 104, 215, 209, 194, 242, 193, 221, 170, 147, 22, 247, 38,
4, 54, 161, 70, 78, 86, 190, 108, 110, 128, 213, 181, 142, 164, 158, 231, 202, 206, 33, 255, 15, 212, 140, 230, 211, 152, 71, 244, 13, 21, 237, 196, 228, 53, 120, 186, 218, 39, 97,
171, 185, 195, 125, 133, 252, 149, 107, 48, 173, 134, 0, 141, 205, 126, 159, 229, 239, 219, 89, 235, 5, 20, 201, 36, 44, 160, 60, 68, 105, 64, 113, 100, 58, 116, 124, 132, 19, 148,
156, 150, 172, 180, 188, 3, 222, 84, 220, 197, 216, 12, 183, 37, 11, 1, 28, 35, 43, 51, 59, 151, 27, 98, 47, 176, 224, 115, 204, 2, 74, 254, 155, 163, 109, 25, 56, 117, 189, 102, 135,
63, 175, 243, 251, 131, 10, 18, 26, 34, 83, 144, 207, 122, 139, 82, 90, 73, 106, 114, 40, 88, 138, 191, 14, 6, 162, 253, 250, 65, 101, 210, 77, 226, 92, 29, 69, 30, 9, 17, 179, 95, 41,
121, 57, 46, 42, 81, 217, 93, 166, 234, 49, 129, 137, 16, 103, 245, 169, 66, 130, 112, 157, 146, 87, 225, 61, 241, 249, 238, 8, 145, 24, 32, 177, 165, 187, 198, 72, 80, 154, 214, 127,
123, 233, 117, 223, 50, 111, 52, 168, 208, 184, 99, 200, 192, 236, 75, 232, 23, 248};
Offsync = 0x8005F150;
StepLoc = 0x0005F151;
StepLoc2 = 0x0005F164;
DangerLoc = 0x0005F0FE;
AngeloLoc = 0x00077E9A;
function GetNextEncounter()
Danger = memory.readbyte(DangerLoc);
Step = memory.readbyte(StepLoc);
WalkStep = 0;
while (Danger < StepVals[math.mod(Step,256)+1]) do
WalkStep = WalkStep+1;
Step = Step + 1;
Danger = Danger + 2;
end;
Danger = memory.readbyte(DangerLoc);
Step = memory.readbyte(StepLoc);
RunStep = 0;
while (Danger < StepVals[math.mod(Step,256)+1]) do
RunStep = RunStep+1;
Step = Step + 1;
Danger = Danger + 5;
end;
gui.text(120,1,string.format("Walk: %d Run: %d",WalkStep,RunStep));
gui.text(120,11,string.format("Step: %.2f Danger: %d", memory.readbyte(StepLoc) + memory.readword(StepLoc2)/256, memory.readbyte(DangerLoc)));
gui.text(120,21,string.format("Angelo Steps: %d", memory.readbyte(AngeloLoc)));
end;
while true do
emu.frameadvance();
GetNextEncounter();
end;
[/code]