mannequin.lua 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. local function mannequin_formspec(pos, start)
  2. start = start or 0
  3. local spos = pos.x ..','.. pos.y ..','.. pos.z
  4. local formspec =
  5. 'formspec_version[3]'..
  6. 'size[10.25,7.5]'..
  7. 'listcolors[#00000069;#5a5a5a]'..
  8. 'textarea[.5,.5;9.75,2;;;Show off some articles of clothing.]'..
  9. 'list[detached:creative_trash;main;9,2.5;1,1;]'..
  10. 'image[9,2.5;1,1;creative_trash_icon.png]'..
  11. 'button[.5,6.5;.75,.75;prev;<]'..
  12. 'button[9,6.5;.75,.75;next;>]'..
  13. 'list[nodemeta:'..spos..';clothes;.25,1.25;8,1;]'..
  14. 'list[detached:clothing_list;main;.25,4.0;8,2;'..start..']'..
  15. 'listring[]'..
  16. 'button_exit[4,6.5;2.25,.75;;close]'
  17. return formspec
  18. end
  19. minetest.register_on_player_receive_fields(function(player, formname, fields)
  20. if formname == 'clothing:mannequin' then
  21. local name = player:get_player_name()
  22. local pos = tasks.player_config[name]
  23. local meta = minetest.get_meta(pos)
  24. local start = meta:get_int('start')
  25. if fields.prev then
  26. start = start - 16
  27. start = math.max(start, 0)
  28. meta:set_int('start', start)
  29. minetest.show_formspec(name, 'clothing:mannequin', mannequin_formspec(pos, start))
  30. elseif fields.next then
  31. if start + 16 <= clothing.inv_size then
  32. start = start + 16
  33. end
  34. meta:set_int('start', start)
  35. minetest.show_formspec(name, 'clothing:mannequin', mannequin_formspec(pos, start))
  36. end
  37. end
  38. end)
  39. local function update_entity(pos, pose)
  40. local node = minetest.get_node(pos)
  41. if node.name == 'clothing:mannequin_'..pose then
  42. local clothes = nil
  43. for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
  44. local entity = obj:get_luaentity()
  45. if entity then
  46. if entity.name == 'clothing:mannequin_'..pose..'_entity' then
  47. if clothes then
  48. obj:remove()
  49. else
  50. clothes = obj
  51. end
  52. end
  53. end
  54. end
  55. if not clothes then
  56. clothes = minetest.add_entity(pos, 'clothing:mannequin_'..pose..'_entity')
  57. clothes:set_yaw(math.pi * 2 - node.param2 * math.pi / 2)
  58. end
  59. local meta = minetest.get_meta(pos)
  60. local inv = meta:get_inventory(pos)
  61. local clothing_texture = {}
  62. for i = 1,8 do
  63. local item = inv:get_stack('clothes', i)
  64. local def = item:get_definition() or {}
  65. if def.tex then
  66. clothing_texture[#clothing_texture+1] = def.tex
  67. end
  68. end
  69. local texture = table.concat(clothing_texture, '^')
  70. if texture == '' then
  71. texture = 'blank.png'
  72. end
  73. clothes:set_properties({textures = {texture}})
  74. clothes:set_yaw(math.pi * 2 - node.param2 * math.pi / 2)
  75. else
  76. for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do
  77. obj:remove()
  78. end
  79. end
  80. end
  81. minetest.register_node('clothing:mannequin_standing', {
  82. description = 'Standing Mannequin',
  83. drawtype = 'mesh',
  84. mesh = 'clothing_mannequin_standing.obj',
  85. tiles = {'clothing_mannequin.png'},
  86. use_texture_alpha = 'clip',
  87. paramtype = 'light',
  88. paramtype2 = 'facedir',
  89. groups = {breakable=1},
  90. selection_box = {
  91. type = 'fixed',
  92. fixed = {-.45, -.5, -.125, .45, .75, .125},
  93. },
  94. collision_box = {
  95. type = 'fixed',
  96. fixed = {-.45, -.5, -.125, .45, .75, .125},
  97. },
  98. on_construct = function(pos)
  99. local meta = minetest.get_meta(pos)
  100. local inv = meta:get_inventory()
  101. inv:set_size('clothes', 8)
  102. end,
  103. on_rightclick = function(pos, node, clicker)
  104. local name = clicker:get_player_name()
  105. if not minetest.is_protected(pos, name) or minetest.check_player_privs(name, {server = true}) then
  106. local meta = minetest.get_meta(pos)
  107. meta:set_int('start', 0)
  108. tasks.player_config[name] = pos
  109. minetest.show_formspec(name, 'clothing:mannequin', mannequin_formspec(pos))
  110. end
  111. end,
  112. allow_metadata_inventory_put = function(pos, listname, index, stack)
  113. local def = stack:get_definition() or {}
  114. local groups = def.groups or {}
  115. if groups['clothing'] then
  116. return 1
  117. end
  118. return 0
  119. end,
  120. on_metadata_inventory_put = function(pos)
  121. update_entity(pos, 'standing')
  122. end,
  123. on_metadata_inventory_move = function(pos)
  124. update_entity(pos, 'standing')
  125. end,
  126. on_metadata_inventory_take = function(pos)
  127. update_entity(pos, 'standing')
  128. end,
  129. after_destruct = function(pos)
  130. update_entity(pos, 'standing')
  131. end
  132. })
  133. minetest.register_entity('clothing:mannequin_standing_entity', {
  134. visual = 'mesh',
  135. mesh = 'clothing_mannequin_standing_clothes.obj',
  136. visual_size = {x=10, y=10, z=10.1},
  137. collisionbox = {0},
  138. physical = false,
  139. textures = {'blank.png'},
  140. on_activate = function(self)
  141. local pos = self.object:get_pos()
  142. local name = minetest.get_node(pos).name
  143. if name ~= 'clothing:mannequin_standing' then
  144. self.object:remove()
  145. else
  146. update_entity(pos, 'standing')
  147. end
  148. end
  149. })