SHARE
TWEET

ctmirrors

XT-8147 Apr 26th, 2017 (edited) 54 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- ctmirrors.lua
  2. -- Script designed for DeSmuME
  3. -- Usage: Load the US ROM of Chrono Trigger DS, load your save, run this script, close the Lua window, then save your game
  4. -- You now have the following:
  5. -- Nu Arcana x7
  6. -- Uranian Mirror x1
  7. -- Pontic Mirror x2
  8. -- Promethean Mirror x1
  9. -- Aresian Mirror x2
  10. -- Item Encyclopedia entries for all of the above
  11.  
  12. -- Lua is a terrible language and you should kill yourself if you like it
  13.  
  14. -- If modifying this script for your own purposes, you may find this Google Sheet that I've created (and am still working on) to be useful
  15. -- https://docs.google.com/spreadsheets/d/1x0rUPHkSwbUqhCnvJYKhIgAJEVe2DUS-XyZxj1bwu5Y/pubhtml
  16.  
  17. -- memory address to start looping through, and the maximum number of 4-byte item records that can be there
  18. local start_address = 0x02072ED4
  19. local length = 59
  20.  
  21. -- array representing all items to add, and their item encyclopedia offsets
  22. -- items[i][1] = Item ID
  23. -- items[i][2] = Category ID
  24. -- items[i][3] = quantity (max 0x63, which is 99 in decimal)
  25. -- items[i][4] = value to be used by the code, leave it zero or Unexpected Things(tm) will happen
  26. local items = {
  27.     { 0x2B, 0x30, 0x07, 0 }, -- Nu Arcana x7
  28.     { 0x2C, 0x30, 0x01, 0 }, -- Uranian Mirror x1
  29.     { 0x2D, 0x30, 0x02, 0 }, -- Pontic Mirror x2
  30.     { 0x2E, 0x30, 0x01, 0 }, -- Promethean Mirror x1
  31.     { 0x2F, 0x30, 0x01, 0 }, -- Hadean Mirror x1
  32.     { 0x30, 0x30, 0x02, 0 }  -- Aresian Mirror x2
  33. }
  34.  
  35. -- item encyclopedia modifications to make
  36. -- encyclopedia[i][1] = address
  37. -- encyclopedia[i][2] = bitmask to be bitwise OR'd with the value at that address
  38. local encyclopedia = {
  39.     { 0x0207454A, 0xF8 }, -- Everything except the Aresian Mirror
  40.     { 0x0207454B, 0x01 }  -- Aresian Mirror
  41. }
  42.  
  43. -- Everything below this line is absolutely perfect (except for the fact that it's written in Lua)
  44. -- therefore, if you modify it, you're a bad person.
  45. -- unless you're modifying it to make it be in a different language and somehow still have it work in DeSmuME
  46. -- in which case, you're amazing, share your Lua library that's making that possible with me so I can be free as well
  47.  
  48. -- WHY ARE LUA ARRAYS ONE-BASED
  49. -- WHY
  50. -- anyway, this is just to name my numeric indices so the code is more readable
  51. local item_id = 1
  52. local category_id = 2
  53. local quantity = 3
  54. local inv_slot = 4
  55.  
  56. local address = 1
  57. local bitmask = 2
  58.  
  59. -- also I'm just going to ignore lexical scoping by declaring everything I'm using as high up as possible
  60. -- this is because I come from real, non-toy languages where variables have to be declared at the beginning of the function
  61. -- besides, it ain't particularly clean to be declaring variables in the middle of your code
  62. -- also, Lua doesn't have any kind of "strict mode" and will happily let you use uninitialized variables
  63. local idx
  64. local itemidx = 1
  65. local curraddr
  66. local item
  67.  
  68. -- okay, so.
  69. -- For some stupid reason, emulators are stuck on Lua 5.1
  70. -- this means no bitwise operators, as found in Lua 5.3
  71. -- to "gloss over" this, DeSmuME includes a language extension that adds a 'bit' library
  72. -- instead of, you know, using Lua 5.3
  73. -- yay for shoehorning in functionality that you could get by simply updating Lua?
  74. -- anyway
  75. -- Item encyclopedia entries, go.
  76. -- this is actually the easy part.
  77. for idx, item in ipairs( encyclopedia ) do
  78.     memory.writebyte( item[address], bit.bor( memory.readbyte( item[address] ), item[bitmask] ) )
  79. end
  80. -- See?  Look how easy that was.
  81.  
  82. -- now the hard part, which is actually giving the items to the player
  83. -- look to see if each item already exists
  84. -- if it does, make a note of the address
  85. for idx = 0, length - 1 do
  86.     curraddr = start_address + ( idx * 4 )
  87.     for itemidx, item in ipairs( items ) do
  88.         if memory.readbyte( curraddr     ) == item[item_id] and
  89.            memory.readbyte( curraddr + 1 ) == item[category_id] then
  90.             item[inv_slot] = curraddr
  91.         end
  92.     end
  93. end
  94.  
  95. -- now find an empty inventory slot for any item that the player doesn't already have
  96. itemidx = 1
  97. for idx = 0, length - 1 do -- see?  zero-based arrays are far more intuitive from a programming perspective
  98.     curraddr = start_address + ( idx * 4 ) -- because then math like this (essentially pointer math) Just Works(tm) without a shitty "gotta subtract one" in there
  99.     while itemidx <= #items and items[itemidx][inv_slot] ~= 0 do
  100.         itemidx = itemidx + 1 -- because Lua was designed by geniuses, we can't do itemidx += 1 or itemidx++
  101.     end
  102.     if itemidx > #items then
  103.         break -- exit our search early if we've got addresses for all the items
  104.     end
  105.     if memory.readdword( curraddr ) == 0 then
  106.         items[itemidx][inv_slot] = curraddr -- found an empty inventory slot, store that sucker
  107.     end
  108. end
  109.  
  110. -- now go through and actually do things
  111. for itemidx, item in ipairs( items ) do
  112.     memory.writebyte( item[inv_slot]    , item[item_id] )
  113.     memory.writebyte( item[inv_slot] + 1, item[category_id] )
  114.     memory.writebyte( item[inv_slot] + 2, item[quantity] )
  115.     memory.writebyte( item[inv_slot] + 3, 0x00 ) -- just for sanity's sake (mmm, sake)
  116. end
RAW Paste Data
Challenge yourself this year...
Learn something new in 2017
Top