persistent_player_attributes.lua 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. --[[
  2. Persistent player attributes
  3. ]]
  4. -- change this to inject into other module
  5. local M = thirsty
  6. M.persistent_player_attributes = {}
  7. local PPA = M.persistent_player_attributes
  8. --[[
  9. Helper functions that take care of the conversions *and* the
  10. clamping for us
  11. ]]
  12. local function _count_for_val(value, def)
  13. local count = math.floor((value - def.min) / (def.max - def.min) * 65535)
  14. if count < 0 then count = 0 end
  15. if count > 65535 then count = 65535 end
  16. return count
  17. end
  18. local function _val_for_count(count, def)
  19. local value = count / 65535 * (def.max - def.min) + def.min
  20. if value < def.min then value = def.min end
  21. if value > def.max then value = def.max end
  22. return value
  23. end
  24. -- end helper functions
  25. -- the stash of registered attributes
  26. PPA.defs = {--[[
  27. name = {
  28. name = "mymod_attr1",
  29. min = 0,
  30. max = 10,
  31. default = 5,
  32. },
  33. ]]}
  34. PPA.read_cache = {--[[
  35. player_name = {
  36. attr1 = value1,
  37. attr2 = value2,
  38. },
  39. ]]}
  40. --[[
  41. How to register a new attribute, with named parameters:
  42. PPA.register({ name = "mymod_attr1", min = 0, ... })
  43. ]]
  44. PPA.register = function(def)
  45. PPA.defs[def.name] = {
  46. name = def.name,
  47. min = def.min or 0.0,
  48. max = def.max or 1.0,
  49. default = def.default or def.min or 0.0,
  50. }
  51. end
  52. -- The on_joinplayer handler
  53. PPA.on_joinplayer = function(player)
  54. local inv = player:get_inventory()
  55. local player_name = player:get_player_name()
  56. PPA.read_cache[player_name] = {}
  57. for name, def in pairs(PPA.defs) do
  58. inv:set_size(name, 1)
  59. if inv:is_empty(name) then
  60. -- set default value
  61. inv:set_stack(name, 1, ItemStack({ name = ":", count = _count_for_val(def.default, def) }))
  62. -- cache default value
  63. PPA.read_cache[player_name][name] = def.default
  64. end
  65. end
  66. end
  67. minetest.register_on_joinplayer(PPA.on_joinplayer)
  68. --[[ get an attribute, procedural style:
  69. local attr1 = PPA.get_value(player, "mymod_attr1")
  70. ]]
  71. PPA.get_value = function(player, name)
  72. local player_name = player:get_player_name()
  73. if PPA.read_cache[player_name][name] == nil then
  74. local def = PPA.defs[name]
  75. local inv = player:get_inventory()
  76. local count = inv:get_stack(name, 1):get_count()
  77. PPA.read_cache[player_name][name] = _val_for_count(count, def)
  78. end
  79. return PPA.read_cache[player_name][name]
  80. end
  81. --[[ set an attribute, procedural style:
  82. PPA.set_value(player, "mymod_attr1", attr1)
  83. ]]
  84. PPA.set_value = function(player, name, value)
  85. local def = PPA.defs[name]
  86. local inv = player:get_inventory()
  87. local player_name = player:get_player_name()
  88. if value > def.max then value = def.max end
  89. if value < def.min then value = def.min end
  90. PPA.read_cache[player_name][name] = value
  91. inv:set_stack(name, 1, ItemStack({ name = ":", count = _count_for_val(value, def) }))
  92. end