savory_and_loadory.lua 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. local storage = minetest.get_mod_storage()
  2. local data = {}
  3. --register a table, the content of which is stored
  4. dwarf_characters.intramodcom.register_for_storage = function(key, tab)
  5. --registering non-tables would make it so they would be copies, not
  6. --references making them immutable by the user program
  7. assert(type(tab) == "table",
  8. "Cannot register non-table values to be handled by storage")
  9. --this function gets called after load time so data may contain something
  10. --loaded from mod storage
  11. if data[key]
  12. then
  13. --tab is no longer needed since it's replaced by a loaded table
  14. tab = data[key]
  15. else
  16. data[key] = tab
  17. end
  18. --return whatever table gets stored.
  19. --It's a reference so the data it contains is both visible
  20. --and mutable by the functions here and the user program
  21. return tab
  22. end
  23. --for turning dead people inventories into something that minetest.serialize can handle
  24. --we use a function that returns this so the table can get garbage collected when it's no longer needed
  25. local function deuserdatafy_itemstacks(tab)
  26. local newtab = {}
  27. for i, v in pairs(tab)
  28. do
  29. local tv = type(v)
  30. if tv == "userdata" and v.to_string --if itemstack or AreaStore. If AreaStore propably weird things happen.
  31. then
  32. newtab[i] = {value = v:to_string(), was_userdata = true}
  33. elseif tv == "table"
  34. then
  35. newtab[i] = deuserdatafy_itemstacks(v)
  36. else
  37. --sadly no error message will be displayed if an
  38. --assertion fails on shutdown
  39. assert(tv == "number" or tv == "boolean" or tv == "nil" or tv == "string")
  40. newtab[i] = v
  41. end
  42. end
  43. return newtab
  44. end
  45. local function reuserdatafy_itemstacks(tab)
  46. local newtab = {}
  47. for i, v in pairs(tab)
  48. do
  49. if type(v) == "table"
  50. then
  51. if v.was_userdata --if itemstack
  52. then
  53. newtab[i] = ItemStack(v.value)
  54. else
  55. newtab[i] = reuserdatafy_itemstacks(v)
  56. end
  57. else
  58. newtab[i] = v
  59. end
  60. end
  61. return newtab
  62. end
  63. local function save()
  64. --turn userdata into tables so they can be serialized
  65. --we assume that all userdata in there are ItemStacks
  66. data = deuserdatafy_itemstacks(data)
  67. --convert data from table form to string
  68. local data = minetest.serialize(data)
  69. storage:set_string("data", data)
  70. end
  71. minetest.register_on_shutdown(save)
  72. local function load()
  73. local loaddata = storage:get_string("data")
  74. if loaddata ~= ""
  75. then
  76. --convert back to table
  77. data = minetest.deserialize(loaddata)
  78. --restore ItemStacks
  79. data = reuserdatafy_itemstacks(data)
  80. end
  81. end
  82. load()