init.lua 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. minetest.register_entity(":__builtin:item", {
  2. initial_properties = {
  3. hp_max = 1,
  4. physical = true,
  5. collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
  6. visual = "sprite",
  7. visual_size = {x=0.5, y=0.5},
  8. textures = {""},
  9. spritediv = {x=1, y=1},
  10. initial_sprite_basepos = {x=0, y=0},
  11. is_visible = false,
  12. timer = 0,
  13. },
  14. itemstring = '',
  15. physical_state = true,
  16. set_item = function(self, itemstring)
  17. self.itemstring = itemstring
  18. local stack = ItemStack(itemstring)
  19. local itemtable = stack:to_table()
  20. local itemname = nil
  21. if itemtable then
  22. itemname = stack:to_table().name
  23. end
  24. local item_texture = nil
  25. local item_type = ""
  26. if minetest.registered_items[itemname] then
  27. item_texture = minetest.registered_items[itemname].inventory_image
  28. item_type = minetest.registered_items[itemname].type
  29. end
  30. prop = {
  31. is_visible = true,
  32. visual = "sprite",
  33. textures = {"unknown_item.png"}
  34. }
  35. if item_texture and item_texture ~= "" then
  36. prop.visual = "sprite"
  37. prop.textures = {item_texture}
  38. prop.visual_size = {x=0.50, y=0.50}
  39. else
  40. prop.visual = "wielditem"
  41. prop.textures = {itemname}
  42. prop.visual_size = {x=0.20, y=0.20}
  43. prop.automatic_rotate = math.pi * 0.25
  44. end
  45. self.object:set_properties(prop)
  46. end,
  47. get_staticdata = function(self)
  48. --return self.itemstring
  49. return minetest.serialize({
  50. itemstring = self.itemstring,
  51. always_collect = self.always_collect,
  52. timer = self.timer,
  53. })
  54. end,
  55. on_activate = function(self, staticdata, dtime_s)
  56. if string.sub(staticdata, 1, string.len("return")) == "return" then
  57. local data = minetest.deserialize(staticdata)
  58. if data and type(data) == "table" then
  59. self.itemstring = data.itemstring
  60. self.always_collect = data.always_collect
  61. self.timer = data.timer
  62. if not self.timer then
  63. self.timer = 0
  64. end
  65. self.timer = self.timer+dtime_s
  66. end
  67. else
  68. self.itemstring = staticdata
  69. end
  70. self.object:set_armor_groups({immortal=1})
  71. self.object:setvelocity({x=0, y=2, z=0})
  72. self.object:setacceleration({x=0, y=-10, z=0})
  73. self:set_item(self.itemstring)
  74. end,
  75. on_step = function(self, dtime)
  76. local time = minetest.setting_get("remove_items")
  77. if not time then
  78. time = 300
  79. end
  80. if not self.timer then
  81. self.timer = 0
  82. end
  83. self.timer = self.timer + dtime
  84. if time ~= 0 and (self.timer > time) then
  85. self.object:remove()
  86. end
  87. local p = self.object:getpos()
  88. local name = minetest.env:get_node(p).name
  89. if name == "default:lava_flowing" or name == "default:lava_source" then
  90. minetest.sound_play("builtin_item_lava", {pos=self.object:getpos()})
  91. self.object:remove()
  92. return
  93. end
  94. if minetest.registered_nodes[name].liquidtype == "flowing" then
  95. get_flowing_dir = function(self)
  96. local pos = self.object:getpos()
  97. local param2 = minetest.env:get_node(pos).param2
  98. for i,d in ipairs({-1, 1, -1, 1}) do
  99. if i<3 then
  100. pos.x = pos.x+d
  101. else
  102. pos.z = pos.z+d
  103. end
  104. local name = minetest.env:get_node(pos).name
  105. local par2 = minetest.env:get_node(pos).param2
  106. if name == "default:water_flowing" and par2 < param2 then
  107. return pos
  108. end
  109. if i<3 then
  110. pos.x = pos.x-d
  111. else
  112. pos.z = pos.z-d
  113. end
  114. end
  115. end
  116. local vec = get_flowing_dir(self)
  117. if vec then
  118. local v = self.object:getvelocity()
  119. if vec and vec.x-p.x > 0 then
  120. self.object:setvelocity({x=0.5,y=v.y,z=0})
  121. elseif vec and vec.x-p.x < 0 then
  122. self.object:setvelocity({x=-0.5,y=v.y,z=0})
  123. elseif vec and vec.z-p.z > 0 then
  124. self.object:setvelocity({x=0,y=v.y,z=0.5})
  125. elseif vec and vec.z-p.z < 0 then
  126. self.object:setvelocity({x=0,y=v.y,z=-0.5})
  127. end
  128. self.object:setacceleration({x=0, y=-10, z=0})
  129. self.physical_state = true
  130. self.object:set_properties({
  131. physical = true
  132. })
  133. return
  134. end
  135. end
  136. p.y = p.y - 0.3
  137. local nn = minetest.env:get_node(p).name
  138. -- If node is not registered or node is walkably solid
  139. if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable then
  140. if self.physical_state then
  141. self.object:setvelocity({x=0,y=0,z=0})
  142. self.object:setacceleration({x=0, y=0, z=0})
  143. self.physical_state = false
  144. self.object:set_properties({
  145. physical = false
  146. })
  147. end
  148. else
  149. if not self.physical_state then
  150. self.object:setvelocity({x=0,y=0,z=0})
  151. self.object:setacceleration({x=0, y=-10, z=0})
  152. self.physical_state = true
  153. self.object:set_properties({
  154. physical = true
  155. })
  156. end
  157. end
  158. end,
  159. on_punch = function(self, hitter)
  160. if self.itemstring ~= '' then
  161. local left = hitter:get_inventory():add_item("main", self.itemstring)
  162. if not left:is_empty() then
  163. self.itemstring = left:to_string()
  164. return
  165. end
  166. end
  167. self.object:remove()
  168. end,
  169. })
  170. if minetest.setting_get("log_mods") then
  171. minetest.log("action", "builtin_item loaded")
  172. end