User File #638535951794312029

Upload All User Files

#638535951794312029 - [DQ9] Chest Timer Lua Script

DQ9ChestTimer.lua
39 downloads
Uploaded 6/10/2024 5:46 AM by TKG (see all 6)
Hit L + R to toggle the chest timer view on/off. Hit Start to start/reset the stopwatch.
index = {
   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 13, 13},

   {14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 4, 4, 4, 4, 4, 4, 4, 4, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 25, 25, 26, 26},

   {27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 36, 36, 37, 37},

   {38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 46, 47, 48},

   {38, 38, 38, 38, 38, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 52, 53, 54, 55, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61},

   {38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 65, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 69, 70, 71, 72, 73, 74},

   {38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 79, 79, 80, 80, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90},

   {91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104},

   {91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 108, 108, 108, 108, 109, 110, 111, 112, 113, 114, 115},

   {91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 118, 118, 118, 118, 118, 118, 118, 118, 95, 95, 95, 95, 95, 108, 108, 108, 108, 108, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130}
}

items = {
   "Medicinal herb", "Evac-u-bell", "Magic water", "H0ly water", "Gleeban gr0at", "Antid0tal herb", "0aken club", "M00nw0rt bulb", "Chimaera wing", "125G",

   "P0p s0cks", "Str0ng medicine", "Silver bracelets", "Bunny tail", "R0yal s0il", "Lava lump", "Angel bell", "Silver platter", "Fisticup", "Superi0r medicine",

   "Str0ng antid0te", "268G", "R0ckb0mb shard", "Ir0n nails", "G0ld ring", "G0ld bracer", "Ir0n mask", "Cannib0x", "T0ad 0il", "Mini medal",

   "450G", "Ir0n 0re", "Slime shield", "C0rundum", "Resurr0ck", "Gleeban guinea", "Strength ring", "Agility ring", "Mimic", "Manky mud",

   "Nectar", "670G", "S0rcerer's st0ne", "Flintst0ne", "Mirr0rst0ne", "Fuddle b0w", "Gl0mb0ler0", "Saint's ashes", "Malicite", "Panacea",

   "Hephaestus' flame", "Muscle belt", "Maid 0utfit", "Thug b00ts", "Thug's mug", "Maid's m0p", "T0ughie tr0users", "Finessence", "Aggressence", "Danger0us bustier",

   "Br0uhaha b00mstick", "Narspici0us", "Mystifying mixture", "Astral plume", "Densinium", "Ri0t0us wristbands", "Fingerless gl0ves", "Mythril 0re", "Veteran's gl0ves", "0h-n0 b0w",

   "Blessed b00ts", "Skull ring", "Hela's hammer", "Hades' helm", "Dem0n whip", "Lucida shard", "Sage's elixir", "880G", "Perfect panacea", "Depressing sh0es",

   "Unhappy hat", "Veteran's arm0ur", "Spellspadrilles", "Veteran's b00ts", "C0mbat b00ts", "She-mage sh0es", "Trinity tights", "Ruin0us shield", "Divine dress", "Skull helm", 

   "Matad0r's gl0ves", "Pand0ra's b0x", "Enchanted st0ne", "1500G", "Gleeban g0ld piece", "G0ld bar", "Her0 spear", "Pruning knife", "Wyrmwand", "Wizardly whip",
   
   "Beast claws", "Attribeauty", "Heavy hatchet", "Megat0n hammer", "Pentarang", "Ethereal st0ne", "3000G", "Reckless necklace", "0richalcum", "MS sw0rd",

   "MS spear", "MS shield", "MS arm0ur", "MS helm", "MS gauntlets", "MS s0llerets", "Reset st0ne", "Sainted s0ma", "Yggdrasil leaf", "Stardust sw0rd",

   "P0ker", "Deft dagger", "Bright staff", "Gringham whip", "Kn0ck0ut r0d", "Drag0nl0rd claws", "Critical fan", "Bad axe", "Gr0undbreaker", "Mete0rang", "Angel's b0w"
}

multiplierA = {
   1103515245,
   3265436265,
   2155723957,
   3993403153,
   3953215549,
   3554433017,
   2603963141,
   3487424289,
   268046093,
   4011613833,
   1524104789,
   3358797873,
   2371908317,
   2298363417
}

incrementC = {
   12345,
   3554416254,
   2802067423,
   3596950572,
   229283573,
   3256818826,
   1051550459,
   3441282840,
   2941955441,
   551188310,
   2951033815,
   1772930244,
   2518396845,
   639546082
}

crMod = {2,2,3,4,4,5,5,6,6,5,10,7}
crAdd = {1,1,1,1,2,2,3,3,4,5,1,4}
crLabel = {"I","H","G","F","E","D","C","B","A","S"}

local buttonCount = 0
local triggerCount = 0
local frameCount = 0
local startToggle = false
local LRToggle = false

local function dq9_rand(seed, a, c)
   local hi = bit.rshift(seed, 16)
	local lo = bit.band(seed, 65535) * a + c
	local cr = bit.rshift(lo, 16)
	lo = bit.band(lo, 65535)
	hi = bit.band((hi * a + cr), 65535)
   seed = bit.bor(bit.lshift(hi, 16), lo)
   return bit.band(hi, 32767)
end

local function getChestRank(mapSeed, floor, MR, chestCount, chestOrder)
   local seed = mapSeed + floor
   local position = chestCount * 2 + chestOrder
   local output = dq9_rand(seed, multiplierA[position], incrementC[position])
   if MR == 0 or MR > 12 then
      return 1
   else
      return math.floor((output-1) * crMod[MR] / 32767 + crAdd[MR])
   end
end

local function chestTimer(mapSeed, floor, sec, chestOrder, chestRank)
   local seed = mapSeed + floor + sec - 5
   local rand = dq9_rand(seed, multiplierA[chestOrder], incrementC[chestOrder])
   local rand99
   if rand == 0 then rand99 = 0
   else rand99 = math.floor((rand - 1) * 100 / 32767)
   end
   if chestRank == nil then
      return 0
   else
      return string.upper(items[(index[chestRank][rand99+1])+1])
   end
end

local function seconds(counter)
   return math.floor(counter / 60)
end

local function stopwatch(counter)
   local sec = seconds(counter)
   local ms = string.format("%02d", math.floor((counter % 60) / 60 * 100))
   if sec < 100 then
       return string.format("%03d.%s", sec, ms)
   else
       return string.format("%d.%s", sec, ms)
   end
end

local function drawChestItem(x, y, text)
   gui.text(x, y, text)
end

local function drawChestCount(x, y, count, rank)
   gui.text(x, y, string.format("%d (%s)", count, rank))
end

local function drawChestItems(mapSeed, floor, sec, chestCount, cr1, cr2, cr3)
   for y = 1, 14 do
       local yOffset = y * 12 - 180
       gui.line(0, yOffset, 256, yOffset, "#444444")
       gui.text(0, yOffset + 3, sec + y - 1)

       if chestCount >= 1 then
         gui.box(19, yOffset, 256, yOffset + 12, "black", "#444444")
         drawChestCount(53, -177, 1, crLabel[cr1])
         drawChestItem(21, yOffset + 3, chestTimer(mapSeed, floor, sec + y - 1, 1, cr1))
       end

       if chestCount >= 2 then
         gui.box(98, yOffset, 256, yOffset + 12, "black", "#444444")
         drawChestCount(132, -177, 2, crLabel[cr2])
         drawChestItem(100, yOffset + 3, chestTimer(mapSeed, floor, sec + y - 1, 2, cr2))
         gui.line(98, 0, 98, -180, "#444444")
       end

       if chestCount == 3 then
         gui.box(177, yOffset, 256, yOffset + 12, "black", "#444444")
         drawChestCount(211, -177, 3, crLabel[cr3])
         drawChestItem(179, yOffset + 3, chestTimer(mapSeed, floor, sec + y - 1, 3, cr3))
         gui.line(177, 0, 177, -180, "#444444")
       end
   end
end

local function updateToggle(input, toggle, count)
   if input == 0 then
       count = count + 1
       if count == 1 then
           toggle = not toggle
       end
   else
       count = 0
   end
   return toggle, count
end

local function main()

   local mapSeed = memory.readword(0x020FD828)
   local floor = memory.readbyte(0x020FD7AA)
   local chestCount = memory.readbyte(0x020FDA2C)
   local SMR = memory.readbyte(0x020FD82E)
   local MR = bit.rshift(floor-1, 2) + SMR

   local cr1 = getChestRank(mapSeed, floor, MR, chestCount, 1)
   local cr2 = getChestRank(mapSeed, floor, MR, chestCount, 2)
   local cr3 = getChestRank(mapSeed, floor, MR, chestCount, 3)

   local buttonInput = bit.band(memory.readbyte(0x04000130), 0x8)
   startToggle, buttonCount = updateToggle(buttonInput, startToggle, buttonCount)

   if startToggle then
      frameCount = frameCount + 1
   else
      frameCount = 0
   end

   local triggerInput = bit.band(memory.readbyte(0x04000131),0xF)
   LRToggle, triggerCount = updateToggle(triggerInput, LRToggle, triggerCount)

   if LRToggle then

      gui.box(0,0,256,-192,"black")
      gui.line(0, -180, 256, -180, "#444444")
      gui.line(19, 0, 19, -180, "#444444")
      gui.text(110, -190, stopwatch(frameCount), "white")
      gui.text(6, -177, "#")
      sec = seconds(frameCount)
      drawChestItems(mapSeed, floor, sec, chestCount, cr1, cr2, cr3)

   end
end

gui.register(main)