-- This Lua Script is for Romancing SaGa 2 on lsnes. -- version 2. -- set colours, added RNG and SP Graph. -- Wagnus Prism Light (0x01, 0x09, 0x0B, 0x14, 0x22, 0x25, 0x27, 0x34, 0x3B, 0x40, 0x4E, 0x54, 0x55, 0x65, 0x6A, 0x93, 0x94, 0xAC, 0xBC, 0xBD, 0xBE, 0xCB, 0xE0, 0xE2, 0xE3, 0xE6, 0xE7) --[[ -- I don't know how to translate below six lines. --memory.usememorydomain("CARTROM") -- BizHawk --~ rng = {} --~ for i = 0, 0xFF do --~ rng[i+1] = memory.readbyte(0xC2EF04+i) --rng[i] = i-1 (rng[0] = 1, ... , rng[256] = 255) -- 0x02EF04-0x02F003 --~ end ]] -- instead the above, rng = {234, 101, 90, 123, 244, 71, 14, 170, 71, 159, 57, 155, 90, 227, 177, 132, 141, 238, 114, 128, 84, 52, 51, 24, 121, 169, 210, 228, 35, 25, 34, 97, 9, 215, 93, 202, 3, 40, 220, 43, 94, 179, 201, 232, 39, 102, 102, 248, 80, 158, 48, 13, 100, 242, 235, 220, 46, 132, 231, 103, 7, 35, 122, 191, 174, 48, 147, 206, 96, 142, 226, 152, 145, 12, 97, 236, 252, 137, 209, 20, 115, 216, 245, 222, 144, 145, 147, 43, 77, 80, 10, 68, 142, 40, 10, 45, 166, 182, 185, 191, 241, 30, 209, 51, 246, 96, 0, 229, 59, 208, 152, 12, 182, 37, 102, 28, 20, 210, 34, 17, 34, 66, 223, 104, 46, 137, 124, 236, 168, 176, 88, 177, 200, 184, 104, 86, 17, 228, 113, 111, 236, 124, 108, 52, 72, 133, 239, 70, 85, 181, 155, 182, 228, 141, 90, 156, 8, 229, 9, 223, 215, 223, 68, 148, 33, 122, 240, 248, 205, 74, 204, 127, 74, 8, 11, 249, 192, 122, 78, 60, 102, 244, 144, 226, 58, 96, 56, 6, 105, 150, 115, 3, 67, 1, 30, 52, 226, 188, 193, 174, 135, 188, 246, 106, 182, 43, 188, 231, 165, 254, 135, 183, 134, 134, 157, 118, 177, 100, 130, 165, 204, 49, 10, 110, 101, 205, 83, 56, 163, 147, 188, 39, 131, 227, 31, 94, 193, 89, 215, 37, 103, 137, 238, 205, 32, 30, 106, 238, 71, 191, 143, 88, 86, 135, 41, 86,} rngCol = {} for i = 0, 0xFF do residue20 = rng[i+1] % 0x20 residue40 = rng[i+1] % 0x40 if residue40 == 0 then -- rare drop rngCol[i+1] = "blue" elseif residue20 == 0 then -- normal drop rngCol[i+1] = "lightgreen" elseif rng[i+1] < 0x1F then -- waza 7 rngCol[i+1] = "pink" elseif rng[i+1] < 0x32 then -- waza same level rngCol[i+1] = "yellow" else rngCol[i+1] = "white" end end --memory.usememorydomain("WRAM") -- BizHawk sel = 0 valueSP = {} ipg0 = 0 ipg1 = 0 msg1 = 0 msg0 = 0 btlOn = 1 lastStart = 0 lastEnd = 0 on_paint = function() gui.right_gap(600); -- for supporting scrolling text messages and inputting battle commands. If you'd like to use it, uncomment below five lines, please. --~ msg1 = memory.readbyte(0x7E1F01) --~ if msg1 == 0 and msg0 ~= 0 then --~ print("msg ", movie.framecount()) --~ end --~ msg0 = msg1 local Xpos local Ypos Xpos = memory.readbyte(0x7E1342) Ypos = memory.readbyte(0x7E13D6) gui.text(970, 0, string.format("(%X,%X)", Xpos, Ypos)) local EP local totalBattle local battle local safe local safe2 = {} local Hiraga EP = memory.readbyte(0x7EF693) totalBattle = memory.readword(0x7EF8AE) battle = memory.readbyte(0x7EF694) safe = memory.readbyte(0x7EF7A2) + 0x100 * memory.readbyte(0x7EF7A3) + 0x10000 * memory.readbyte(0x7EF7A4) safe2[1] = math.floor(safe/1000000) safe2[2] = math.floor((safe-(safe2[1]*1000000))/1000) safe2[3] = safe - (safe2[1]*1000000)-(safe2[2]*1000) Hiraga = memory.readbyte(0x7EF697) if safe2[1] ~= 0 then gui.text(970, 12, string.format("%3d,%03d,%03d", safe2[1], safe2[2], safe2[3])) elseif safe2[2] ~= 0 then gui.text(970, 12, string.format("%3d,%03d", safe2[2], safe2[3])) else gui.text(970, 12, string.format("%3d", safe2[3])) end gui.text(970, 24, string.format("EP %d", EP)) gui.text(970, 36, string.format("%d/%d", battle, totalBattle)) gui.text(970, 48, string.format("%dsei", Hiraga)) local jump local battle16 = battle % 0x10 if EP >= battle16 then if battle < 0x30 then jump = battle16 + 0x30 else jump = battle end --~ gui.text(512, 50, string.format("jump%d", jump)) --~ gui.text(512, 62, string.format("tBtl%d->%d", totalBattle, totalBattle + math.floor(jump/4))) --~ gui.text(512, 74, string.format("%dsei->%dsei", Hiraga, Hiraga + math.floor((jump/0x20) + (1/2)))) end local gameMode gameMode = memory.readbyte(0x7FAFC7) --~ gui.text(512, 0, sel) selectKey = memory.readbyte(0x7E0D12) if gameMode == 1 and selectKey == 0x20 then ipg1 = 1 else ipg1 = 0 end if gameMode == 1 and ipg1 == 1 and ipg0 == 0 then sel = sel + 1 end ipg0 = ipg1 local comSelect = memory.readbyte(0x7E0D1A) local numParty = memory.readbyte(0x7EF618) if gameMode ~= 1 then --~ if comSelect < 0 or comSelect >= numParty then for j = 0, 0xF do for i = 0, 0xF do gui.text(545+i*26, 5, string.format("%2X", i), "gray") gui.text(545+i*26, 27+j*20, string.format("%2X", rng[1+i+0x10*j]), rngCol[1+i+0x10*j]) gui.text(520, 27+j*20, string.format("%2X", 0x10*j), "gray") end end --~ end end local currentRNG = memory.readbyte(0x7E0D1F) gui.rectangle(545-2+(currentRNG-16*math.floor(currentRNG/16))*26, 27+20*math.floor(currentRNG/16), 26, 20, 1, "yellow") n = 2 a = 3 b = 2 gui.rectangle(752, 448-100, n-1, 100, 1, "lightgreen", "lightgreen") if gameMode ~= 1 then --~ if comSelect < 0 or comSelect >= numParty then gui.rectangle(750, 448-a*math.floor(rng[currentRNG+1]/8), 2*n, a*math.floor(rng[currentRNG+1]/8), 1, "black", rngCol[currentRNG+1]) for i=0, 106/n do local k = (currentRNG+i+1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(754+i*2*n, 448-a*math.floor(rng[k]/8), 2*n, a*math.floor(rng[k]/8), 1, "black", rngCol[k]) end for j=0, 118/n do local k = (currentRNG-j-1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(746-j*2*n, 448-a*math.floor(rng[k]/8), 2*n, a*math.floor(rng[k]/8), 1, "black", rngCol[k]) end gui.text(753, 448-100, string.format("%2X->%2X", currentRNG, rng[currentRNG+1]), "lightgreen") --~ end end local EV = memory.readbyte(0x7E0D80) -- current effect value gui.text(970, 329, string.format("EV %d", EV)) local currentRNG = memory.readbyte(0x7E0D1F) gui.text(970, 341, string.format("RNG %2X->%2X", currentRNG, rng[currentRNG+1]), "yellow") local preRNG = (currentRNG-1) % 0x100 gui.text(970, 353, string.format(" %2X->%2X", preRNG, rng[preRNG+1]), "gray") defP = {} for i = 1, 5 do defP[i] = {} for j = 1, 8 do --~ defP[i][j] = memory.readbyte(0x7EF055 + 0x100*(i-1) + j-1) -- joined order defP[i][j] = memory.readbyte(0x7EAA55 + 0x100*(i-1) + j-1) -- order in battles end end if gameMode == 1 then local x = 965 local y = 90 local gap = 12 gui.text(x, y, "srd") gui.text(x, y+gap, "axe") gui.text(x, y+gap*2, "spr") gui.text(x, y+gap*3, "arw") gui.text(x, y+gap*4, "heat") gui.text(x, y+gap*5, "cold") gui.text(x, y+gap*6, "elec") gui.text(x, y+gap*7, "sprt") for i = 1, 5 do for j = 1, 8 do gui.text(x+12+24*i, y+gap*(j-1), defP[i][j]) end end end agility = {} SP = {} SPCol = {} HP = {} nonbtlHP = {} for i = 1, 5 do agility[i] = memory.readbyte(0x7EAA65+0x0100*(i-1)) HP[i] = memory.readword(0x7EAA0E + 0x100*(i-1)) nonbtlHP[i] = memory.readword(0x7EF010 + 0x100*(i-1)) end -- for checking the first characters' HP, especially Bear(3rd). If you'd like to use it, uncomment below three lines, please. --~ for i = 1, 5 do --~ gui.text(1080, 0+12*(i-1), HP[i]) --~ end eHP = {} eMHP = {} eAgi = {} eEXP = {} eWaza={} monsID = {} local monNum monNum = memory.readbyte(0x7E0D22) --for i=1, monNum do for i=1, 6 do eHP[i] = memory.readword(0x7EA00E+0x100*(i-1)) eMHP[i] = memory.readbyte(0x7EA010+0x100*(i-1)) eAgi[i] = memory.readbyte(0x7EA065 + 0x100*(i-1)) eWaza[i] = memory.readbyte(0x7EA018 + 0x100*(i-1)) monsID[i] = memory.readword(0x7E1203 + 0x5*(i)) end if monNum > 6 then monNum = 6 end local gameMode gameMode = memory.readbyte(0x7FAFC7) if gameMode == 1 then gui.text(970, 245, "HP") gui.text(1010, 245, "Agi") gui.text(1040, 245, "WLvl") for i=1, monNum do gui.text(970, 260+12*(i-1), string.format("%2d", eHP[i])) gui.text(1015, 260+12*(i-1), string.format("%d", eAgi[i])) gui.text(1035, 260+12*(i-1), string.format("%2d", eWaza[i])) end end for i = 1, 5 do SP[i] = {} SPCol[i] = {} for j = 0, 0xFF do SP[i][j+1] = (agility[i])*2 + (rng[1+(j)] % ((agility[i])*2)) + 1 if (SP[i][j+1] > math.floor( agility[i] * (7/2)) ) then SPCol[i][j+1] = "aqua" elseif (SP[i][j+1] < math.floor( agility[i] * 5/2) ) then SPCol[i][j+1] = "pink" else SPCol[i][j+1] = "white" end end end local comSelect = memory.readbyte(0x7E0D1A) local numParty = memory.readbyte(0x7EF618) if gameMode == 1 then if comSelect >= 0 and comSelect < numParty then for j = 0, 0xF do for i = 0, 0xF do gui.text(545+i*26, 5, string.format("%2X", i), "gray") if sel % 2 == 0 then gui.text(545+i*26, 27+j*20, string.format("%2d", SP[comSelect+1][1+i+0x10*j]), SPCol[comSelect+1][1+i+0x10*j]) else gui.text(545+i*26, 27+j*20, string.format("%2X", rng[1+i+0x10*j]), rngCol[1+i+0x10*j]) end gui.text(520, 27+j*20, string.format("%2X", 0x10*j), "gray") end end local currentRNG = memory.readbyte(0x7E0D1F) gui.rectangle(545-2+(currentRNG-16*math.floor(currentRNG/16))*26, 27+20*math.floor(currentRNG/16), 26, 20, 1, "yellow") else for j = 0, 0xF do for i = 0, 0xF do gui.text(545+i*26, 5, string.format("%2X", i), "gray") gui.text(545+i*26, 27+j*20, string.format("%2X", rng[1+i+0x10*j]), rngCol[1+i+0x10*j]) gui.text(520, 27+j*20, string.format("%2X", 0x10*j), "gray") end end end end gotSP = {} local comSelect = memory.readbyte(0x7E0D1A) for i = 1, comSelect do gotSP[i] = memory.readbyte(0x7E0DD7 + (i-1)) if gotSP[i] ~= 0 then valueSP[i] = gotSP[i] end end local numParty = memory.readbyte(0x7EF618) local gameMode gameMode = memory.readbyte(0x7FAFC7) if gameMode == 1 then if countSP ~= numParty then if comSelect >= 0 and comSelect < numParty+1 then for i = 1, comSelect do if valueSP[i] ~= 0 then gui.text(970, 380+(i-1)*12, string.format(" %3d", valueSP[i])) end end end end end local gameMode = memory.readbyte(0x7FAFC7) local t = movie.framecount() if btlOn ~= gameMode and gameMode ~= 1 then lastEnd = t btlTime = lastEnd - lastStart print(string.format("btlEnd %d, btlTime %d", t, btlTime)) end if btlOn ~= gameMode and gameMode ~= 0 then lastStart = t print(string.format("btlStart %d", t)) end btlOn = gameMode local numParty local comSelect = memory.readbyte(0x7E0D1A) local currentRNG = memory.readbyte(0x7E0D1F) local numParty = memory.readbyte(0x7EF618) if numParty < 6 then if comSelect >=0 and comSelect < numParty then gui.text(970, 365, string.format("SP %2X->%2d", currentRNG, SP[comSelect+1][currentRNG+1]), SPCol[comSelect+1][currentRNG+1]) end end if gameMode == 1 then if comSelect >= 0 and comSelect < numParty then if sel % 2 == 0 then if currentRNG == 0xFF then currentRNG = 0 end gui.rectangle(750, 448-b*math.floor(SP[comSelect+1][currentRNG+1]/a), 2*n, b*math.floor(SP[comSelect+1][currentRNG+1]/a), 1, "black", SPCol[comSelect+1][currentRNG+1]) local currentRNG = memory.readbyte(0x7E0D1F) for i=0, 106/n do k = (currentRNG+i+1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(754+i*2*n, 448-b*math.floor(SP[comSelect+1][k]/a), 2*n, b*math.floor(SP[comSelect+1][k]/a), 1, "black", SPCol[comSelect+1][k]) end for j=0, 118/n do k = (currentRNG-j-1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(746-j*2*n, 448-b*math.floor(SP[comSelect+1][k]/a), 2*n, b*math.floor(SP[comSelect+1][k]/a), 1, "black", SPCol[comSelect+1][k]) end local comSelect = memory.readbyte(0x7E0D1A) numParty = memory.readbyte(0x7EF618) if comSelect >= 0 and comSelect < numParty then if currentRNG == 0xFF then currentRNG = 0 end end gui.text(753, 448-100,string.format("%2X->%2d", currentRNG, SP[comSelect+1][currentRNG+1]), "lightgreen") else gui.rectangle(750, 448-a*math.floor(rng[currentRNG+1]/8), 2*n, a*math.floor(rng[currentRNG+1]/8), 1, "black", rngCol[currentRNG+1]) for i=0, 106/n do local k = (currentRNG+i+1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(754+i*2*n, 448-a*math.floor(rng[k]/8), 2*n, a*math.floor(rng[k]/8), 1, "black", rngCol[k]) end for j=0, 118/n do local k = (currentRNG-j-1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(746-j*2*n, 448-a*math.floor(rng[k]/8), 2*n, a*math.floor(rng[k]/8), 1, "black", rngCol[k]) end gui.text(753, 448-100, string.format("%2X->%2X", currentRNG, rng[currentRNG+1]), "lightgreen") end else gui.rectangle(750, 448-a*math.floor(rng[currentRNG+1]/8), 2*n, a*math.floor(rng[currentRNG+1]/8), 1, "black", rngCol[currentRNG+1]) for i=0, 106/n do local k = (currentRNG+i+1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(754+i*2*n, 448-a*math.floor(rng[k]/8), 2*n, a*math.floor(rng[k]/8), 1, "black", rngCol[k]) end for j=0, 118/n do local k = (currentRNG-j-1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(746-j*2*n, 448-a*math.floor(rng[k]/8), 2*n, a*math.floor(rng[k]/8), 1, "black", rngCol[k]) end gui.text(753, 448-100, string.format("%2X->%2X", currentRNG, rng[currentRNG+1]), "lightgreen") end end --[[ local comSelect = memory.readbyte(0x7E0D1A) local numParty = memory.readbyte(0x7EF618) local agilityTest = 20 local SPTest = {} local SPTestCol = {} local rngMod = {} local rngModCol = {} agilityTest = 20 print(agilityTest) for j = 0, 0xFF do SPTest[j+1] = (agilityTest)*2 + (rng[1+(j)] % (agilityTest*2)) + 1 if (SPTest[j+1] > math.floor( agilityTest * (7/2)) ) then SPTestCol[j+1] = "aqua" elseif (SPTest[j+1] < math.floor( agilityTest * 5/2) ) then SPTestCol[j+1] = "pink" else SPTestCol[j+1] = "white" end rngMod[j+1] = rng[1+(j)] % 4 -- change values if rngMod[j+1] == 0 then rngModCol[j+1] = "red" else rngModCol[j+1] = "white" end end for j = 0, 0xF do for i = 0, 0xF do gui.text(545+i*26, 5, string.format("%2X", i), "gray") --~ gui.text(545+i*26, 27+j*20, string.format("%2d", SPTest[1+i+0x10*j]), SPTestCol[1+i+0x10*j]) --~ gui.text(545+i*26, 27+j*20, string.format("%2d", rngMod[1+i+0x10*j]), rngCol[1+i+0x10*j]) gui.text(545+i*26, 27+j*20, string.format("%2d", rngMod[1+i+0x10*j]), rngModCol[1+i+0x10*j]) gui.text(520, 27+j*20, string.format("%2X", 0x10*j), "gray") end end local currentRNG = memory.readbyte(0x7E0D1F) gui.rectangle(545-2+(currentRNG-16*math.floor(currentRNG/16))*26, 27+20*math.floor(currentRNG/16), 26, 20, 1, "yellow") ]] --[[ gui.rectangle(750, 448-b*math.floor(SPTest[currentRNG+1]/a), 2*n, b*math.floor(SPTest[currentRNG+1]/a), 1, "black", SPTestCol[currentRNG+1]) for i=0, 106/n do local k = (currentRNG+i+1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(754+i*2*n, 448-b*math.floor(SPTest[k]/a), 2*n, b*math.floor(SPTest[k]/a), 1, "black", SPTestCol[k]) end for j=0, 118/n do local k = (currentRNG-j-1+1) % 0x100 if k == 0 then k = 0x100 end gui.rectangle(746-j*2*n, 448-b*math.floor(SPTest[k]/a), 2*n, b*math.floor(SPTest[k]/a), 1, "black", SPTestCol[k]) end gui.text(753, 448-100, string.format("%2X->%2d", currentRNG, SPTest[currentRNG+1]), "lightgreen") ]] --[[ d = 25 --~ gui.rectangle(750, 448-d*math.floor(rngMod[currentRNG+1]), 2*n, d*math.floor(rngMod[currentRNG+1]), 1, "black", rngCol[currentRNG+1]) gui.rectangle(750, 448-d*math.floor(rngMod[currentRNG+1]), 2*n, d*math.floor(rngMod[currentRNG+1]), 1, "black", rngModCol[currentRNG+1]) for i=0, 106/n do local k = (currentRNG+i+1+1) % 0x100 if k == 0 then k = 0x100 end --~ gui.rectangle(754+i*2*n, 448-d*math.floor(rngMod[k]), 2*n, d*math.floor(rngMod[k]), 1, "black", rngCol[k]) gui.rectangle(754+i*2*n, 448-d*math.floor(rngMod[k]), 2*n, d*math.floor(rngMod[k]), 1, "black", rngModCol[k]) end for j=0, 118/n do local k = (currentRNG-j-1+1) % 0x100 if k == 0 then k = 0x100 end --~ gui.rectangle(746-j*2*n, 448-d*math.floor(rngMod[k]), 2*n, d*math.floor(rngMod[k]), 1, "black", rngCol[k]) gui.rectangle(746-j*2*n, 448-d*math.floor(rngMod[k]), 2*n, d*math.floor(rngMod[k]), 1, "black", rngModCol[k]) end gui.text(753, 448-100, string.format("%2X->%2X", currentRNG, rngMod[currentRNG+1]), "lightgreen") ]] end