SHARE
TWEET

Untitled

a guest Mar 25th, 2019 82 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --basic settings
  2. local item_drop_settings                 = {} --settings table
  3. item_drop_settings.age                   = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
  4. item_drop_settings.radius_magnet         = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect!
  5. item_drop_settings.radius_collect        = 0.2 --radius of collection
  6. item_drop_settings.player_collect_height = 1.0 --added to their pos y value
  7. item_drop_settings.collection_safety     = false --do this to prevent items from flying away on laggy servers
  8. item_drop_settings.random_item_velocity  = true --this sets random item velocity if velocity is 0
  9. item_drop_settings.drop_single_item      = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack
  10. -- drop_single_item is disabled by default because it is annoying to throw away items from the intentory screen
  11.  
  12. item_drop_settings.magnet_time           = 0.75 -- how many seconds an item follows the player before giving up
  13.  
  14. local get_gravity = function()
  15.     return tonumber(minetest.settings:get("movement_gravity")) or 9.81
  16. end
  17.  
  18. local check_pickup_achievements = function(object, player)
  19.     local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
  20.     if minetest.get_item_group(itemname, "tree") ~= 0 then
  21.         awards.unlock(player:get_player_name(), "mcl:mineWood")
  22.     elseif itemname == "mcl_mobitems:blaze_rod" then
  23.         awards.unlock(player:get_player_name(), "mcl:blazeRod")
  24.     elseif itemname == "mcl_mobitems:leather" then
  25.         awards.unlock(player:get_player_name(), "mcl:killCow")
  26.     elseif itemname == "mcl_core:diamond" then
  27.         awards.unlock(player:get_player_name(), "mcl:diamonds")
  28.     end
  29. end
  30.  
  31. local enable_physics = function(object, luaentity, ignore_check)
  32.     if luaentity.physical_state == false or ignore_check == true then
  33.         luaentity.physical_state = true
  34.         object:set_properties({
  35.             physical = true
  36.         })
  37.         object:set_velocity({x=0,y=0,z=0})
  38.         object:set_acceleration({x=0,y=-get_gravity(),z=0})
  39.     end
  40. end
  41.  
  42. local disable_physics = function(object, luaentity, ignore_check, reset_movement)
  43.     if luaentity.physical_state == true or ignore_check == true then
  44.         luaentity.physical_state = false
  45.         object:set_properties({
  46.             physical = false
  47.         })
  48.         if reset_movement ~= false then
  49.             object:set_velocity({x=0,y=0,z=0})
  50.             object:set_acceleration({x=0,y=0,z=0})
  51.         end
  52.     end
  53. end
  54.  
  55. minetest.register_globalstep(function(dtime)
  56.     for _,player in ipairs(minetest.get_connected_players()) do
  57.         if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
  58.             local pos = player:get_pos()
  59.             local inv = player:get_inventory()
  60.             local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
  61.  
  62.             --magnet and collection
  63.             for _,object in ipairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.radius_magnet)) do
  64.                 if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
  65.                     object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
  66.                     local collected = false
  67.                     if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
  68.  
  69.                         -- Collection
  70.                         if vector.distance(checkpos, object:get_pos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then
  71.                             -- Ignore if itemstring is not set yet
  72.                             if object:get_luaentity().itemstring ~= "" then
  73.                                 inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
  74.                                 minetest.sound_play("item_drop_pickup", {
  75.                                     pos = pos,
  76.                                     max_hear_distance = 16,
  77.                                     gain = 1.0,
  78.                                 })
  79.                                 check_pickup_achievements(object, player)
  80.  
  81.  
  82.                                 -- Destroy entity
  83.                                 -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately.
  84.                                 object:get_luaentity()._removed = true
  85.                                 object:remove()
  86.                                 collected = true
  87.                             end
  88.  
  89.                         -- Magnet
  90.                         else
  91.                             --move this to the front so players can see animation before collection
  92.                             if not collected then
  93.                                 if object:get_luaentity()._magnet_timer > 1 then
  94.                                     object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time
  95.                                     object:get_luaentity()._magnet_active = false
  96.                                 elseif object:get_luaentity()._magnet_timer < 0 then
  97.                                     object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
  98.                                 end
  99.                             end
  100.  
  101.                             object:get_luaentity()._magnet_active = true
  102.                             object:get_luaentity()._collector_timer = 0
  103.  
  104.                             -- Move object to player
  105.                             disable_physics(object, object:get_luaentity())
  106.                            
  107.                             object:move_to(checkpos)
  108.  
  109.                             --fix eternally falling items
  110.                             minetest.after(0, function(object)
  111.                                 local lua = object:get_luaentity()
  112.                                 if lua then
  113.                                     object:set_acceleration({x=0, y=0, z=0})
  114.                                 end
  115.                             end, object)
  116.  
  117.  
  118.                             --this is a safety to prevent items flying away on laggy servers
  119.                             if item_drop_settings.collection_safety == true then
  120.                                 if object:get_luaentity().init ~= true then
  121.                                     object:get_luaentity().init = true
  122.                                     minetest.after(1, function(args)
  123.                                         local playername = args[1]
  124.                                         local player = minetest.get_player_by_name(playername)
  125.                                         local object = args[2]
  126.                                         local lua = object:get_luaentity()
  127.                                         if player == nil or not player:is_player() or object == nil or lua == nil or lua.itemstring == nil then
  128.                                             return
  129.                                         end
  130.                                         if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
  131.                                             inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
  132.                                             if not object:get_luaentity()._removed then
  133.                                                 minetest.sound_play("item_drop_pickup", {
  134.                                                     pos = pos,
  135.                                                     max_hear_distance = 16,
  136.                                                     gain = 1.0,
  137.                                                 })
  138.                                             end
  139.                                             check_pickup_achievements(object, player)
  140.                                             object:get_luaentity()._removed = true
  141.                                             object:remove()
  142.                                         else
  143.                                             enable_physics(object, object:get_luaentity())
  144.                                         end
  145.                                     end, {player:get_player_name(), object})
  146.                                 end
  147.                             end
  148.                         end
  149.                     end
  150.  
  151.                 end
  152.             end
  153.  
  154.         end
  155.     end
  156. end)
  157.  
  158. local minigroups = { "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" }
  159. local basegroups = { "pickaxey", "axey", "shovely" }
  160. local materials = { "wood", "gold", "stone", "iron", "diamond" }
  161.  
  162. -- Checks if the given node would drop its useful drop if dug by a tool
  163. -- with the given tool capabilities. Returns true if it will yield its useful
  164. -- drop, false otherwise.
  165. local check_can_drop = function(node_name, tool_capabilities)
  166.     local handy = minetest.get_item_group(node_name, "handy")
  167.     local dig_immediate = minetest.get_item_group(node_name, "dig_immediate")
  168.     if handy == 1 or dig_immediate == 2 or dig_immediate == 3 then
  169.         return true
  170.     else
  171.         local toolgroupcaps
  172.         if tool_capabilities then
  173.             toolgroupcaps = tool_capabilities.groupcaps
  174.         else
  175.             return false
  176.         end
  177.  
  178.         -- Compare node groups with tool capabilities
  179.         for m=1, #minigroups do
  180.             local minigroup = minigroups[m]
  181.             local g = minetest.get_item_group(node_name, minigroup)
  182.             if g ~= 0 then
  183.                 local plus = minigroup .. "_dig"
  184.                 if toolgroupcaps[plus] then
  185.                     return true
  186.                 end
  187.             end
  188.         end
  189.         for b=1, #basegroups do
  190.             local basegroup = basegroups[b]
  191.             local g = minetest.get_item_group(node_name, basegroup)
  192.             if g ~= 0 then
  193.                 for m=g, #materials do
  194.                     local plus = basegroup .. "_dig_"..materials[m]
  195.                     if toolgroupcaps[plus] then
  196.                         return true
  197.                     end
  198.                 end
  199.             end
  200.         end
  201.  
  202.         return false
  203.     end
  204. end
  205.  
  206. function minetest.handle_node_drops(pos, drops, digger)
  207.     -- NOTE: This function override allows digger to be nil.
  208.     -- This means there is no digger. This is a special case which allows this function to be called
  209.     -- by hand. Creative Mode is intentionally ignored in this case.
  210.  
  211.     local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true)
  212.     if (digger ~= nil and minetest.settings:get_bool("creative_mode")) or doTileDrops == false then
  213.         return
  214.     end
  215.  
  216.     -- Check if node will yield its useful drop by the digger's tool
  217.     local dug_node = minetest.get_node(pos)
  218.     local toolcaps
  219.     if digger ~= nil then
  220.         local tool = digger:get_wielded_item()
  221.         toolcaps = tool:get_tool_capabilities()
  222.  
  223.         if not check_can_drop(dug_node.name, toolcaps) then
  224.             return
  225.         end
  226.     end
  227.  
  228.     --[[ Special node drops when dug by shears by reading _mcl_shears_drop
  229.     from the node definition.
  230.     Definition of _mcl_shears_drop:
  231.     * true: Drop itself when dug by shears
  232.     * table: Drop every itemstring in this table when dub by shears
  233.     ]]
  234.     local nodedef = minetest.registered_nodes[dug_node.name]
  235.     if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then
  236.         if nodedef._mcl_shears_drop == true then
  237.             drops = { dug_node.name }
  238.         else
  239.             drops = nodedef._mcl_shears_drop
  240.         end
  241.     end
  242.  
  243.     for _,item in ipairs(drops) do
  244.         local count
  245.         if type(item) == "string" then
  246.             count = ItemStack(item):get_count()
  247.         else
  248.             count = item:get_count()
  249.         end
  250.         local drop_item = ItemStack(item)
  251.         drop_item:set_count(1)
  252.         for i=1,count do
  253.             local obj = core.add_item(pos, drop_item)
  254.             if obj ~= nil then
  255.                 local x = math.random(1, 5)
  256.                 if math.random(1,2) == 1 then
  257.                     x = -x
  258.                 end
  259.                 local z = math.random(1, 5)
  260.                 if math.random(1,2) == 1 then
  261.                     z = -z
  262.                 end
  263.                 obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z})
  264.             end
  265.         end
  266.     end
  267. end
  268.  
  269. -- Drop single items by default
  270. function minetest.item_drop(itemstack, dropper, pos)
  271.     if dropper and dropper:is_player() then
  272.         local v = dropper:get_look_dir()
  273.         local p = {x=pos.x, y=pos.y+1.2, z=pos.z}
  274.         local cs = itemstack:get_count()
  275.         if dropper:get_player_control().sneak then
  276.             cs = 1
  277.         end
  278.         local item = itemstack:take_item(cs)
  279.         local obj = core.add_item(p, item)
  280.         if obj then
  281.             v.x = v.x*4
  282.             v.y = v.y*4 + 2
  283.             v.z = v.z*4
  284.             obj:set_velocity(v)
  285.             -- Force collection delay
  286.             obj:get_luaentity()._insta_collect = false
  287.             return itemstack
  288.         end
  289.     end
  290. end
  291.  
  292. --modify builtin:item
  293.  
  294. local time_to_live = tonumber(minetest.settings:get("item_entity_ttl"))
  295. if not time_to_live then
  296.     time_to_live = 300
  297. end
  298.  
  299. core.register_entity(":__builtin:item", {
  300.     initial_properties = {
  301.         hp_max = 1,
  302.         physical = true,
  303.         collide_with_objects = false,
  304.         collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3},
  305.         pointable = false,
  306.         visual = "wielditem",
  307.         visual_size = {x = 0.4, y = 0.4},
  308.         textures = {""},
  309.         spritediv = {x = 1, y = 1},
  310.         initial_sprite_basepos = {x = 0, y = 0},
  311.         is_visible = false,
  312.         infotext = "",
  313.     },
  314.  
  315.     -- Itemstring of dropped item. The empty string is used when the item is not yet initialized yet.
  316.     -- The itemstring MUST be set immediately to a non-empty string after creating the entity.
  317.     -- The hand is NOT permitted as dropped item. ;-)
  318.     -- Item entities will be deleted if they still have an empty itemstring on their first on_step tick.
  319.     itemstring = '',
  320.  
  321.     -- If true, item will fall
  322.     physical_state = true,
  323.  
  324.     -- If item entity is currently flowing in water
  325.     _flowing = false,
  326.  
  327.     -- Number of seconds this item entity has existed so far
  328.     age = 0,
  329.  
  330.     set_item = function(self, itemstring)
  331.         self.itemstring = itemstring
  332.         if self.itemstring == "" then
  333.             -- item not yet known
  334.             return
  335.         end
  336.         local stack = ItemStack(itemstring)
  337.         local count = stack:get_count()
  338.         local max_count = stack:get_stack_max()
  339.         if count > max_count then
  340.             count = max_count
  341.             self.itemstring = stack:get_name().." "..max_count
  342.         end
  343.         local s = 0.2 + 0.1 * (count / max_count)
  344.         local c = s
  345.         local itemtable = stack:to_table()
  346.         local itemname = nil
  347.         local description = ""
  348.         if itemtable then
  349.             itemname = stack:to_table().name
  350.         end
  351.         local item_texture = nil
  352.         local item_type = ""
  353.         if core.registered_items[itemname] then
  354.             item_texture = core.registered_items[itemname].inventory_image
  355.             item_type = core.registered_items[itemname].type
  356.             description = core.registered_items[itemname].description
  357.         end
  358.         local prop = {
  359.             is_visible = true,
  360.             visual = "wielditem",
  361.             textures = {itemname},
  362.             visual_size = {x = s, y = s},
  363.             collisionbox = {-c, -c, -c, c, c, c},
  364.             automatic_rotate = math.pi * 0.5,
  365.             infotext = description,
  366.         }
  367.         self.object:set_properties(prop)
  368.         if item_drop_settings.random_item_velocity == true then
  369.             minetest.after(0, function(self)
  370.                 if not self or not self.object or not self.object:get_luaentity() then
  371.                     return
  372.                 end
  373.                 local vel = self.object:get_velocity()
  374.                 if vel and vel.x == 0 and vel.z == 0 then
  375.                     local x = math.random(1, 5)
  376.                     if math.random(1,2) == 1 then
  377.                         x = -x
  378.                     end
  379.                     local z = math.random(1, 5)
  380.                     if math.random(1,2) == 1 then
  381.                         z = -z
  382.                     end
  383.                     local y = math.random(2,4)
  384.                     self.object:set_velocity({x=1/x, y=y, z=1/z})
  385.                 end
  386.             end, self)
  387.         end
  388.  
  389.     end,
  390.  
  391.     get_staticdata = function(self)
  392.         return core.serialize({
  393.             itemstring = self.itemstring,
  394.             always_collect = self.always_collect,
  395.             age = self.age,
  396.             _insta_collect = self._insta_collect,
  397.             _flowing = self._flowing,
  398.             _removed = self._removed,
  399.         })
  400.     end,
  401.  
  402.     on_activate = function(self, staticdata, dtime_s)
  403.         if string.sub(staticdata, 1, string.len("return")) == "return" then
  404.             local data = core.deserialize(staticdata)
  405.             if data and type(data) == "table" then
  406.                 self.itemstring = data.itemstring
  407.                 self.always_collect = data.always_collect
  408.                 if data.age then
  409.                     self.age = data.age + dtime_s
  410.                 else
  411.                     self.age = dtime_s
  412.                 end
  413.                 --remember collection data
  414.                 -- If true, can collect item without delay
  415.                 self._insta_collect = data._insta_collect
  416.                 self._flowing = data._flowing
  417.                 self._removed = data._removed
  418.             end
  419.         else
  420.             self.itemstring = staticdata
  421.         end
  422.         if self._removed then
  423.             self._removed = true
  424.             self.object:remove()
  425.             return
  426.         end
  427.         if self._insta_collect == nil then
  428.             -- Intentionally default, since delayed collection is rare
  429.             self._insta_collect = true
  430.         end
  431.         if self._flowing == nil then
  432.             self._flowing = false
  433.         end
  434.         self._magnet_timer = 0
  435.         self._magnet_active = false
  436.         -- How long ago the last possible collector was detected. nil = none in this session
  437.         self._collector_timer = nil
  438.         -- Used to apply additional force
  439.         self._force = nil
  440.         self._forcestart = nil
  441.         self._forcetimer = 0
  442.  
  443.         self.object:set_armor_groups({immortal = 1})
  444.         self.object:set_velocity({x = 0, y = 2, z = 0})
  445.         self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0})
  446.         self:set_item(self.itemstring)
  447.     end,
  448.  
  449.     try_merge_with = function(self, own_stack, object, entity)
  450.         if self.age == entity.age or entity._removed then
  451.             -- Can not merge with itself and remove entity
  452.             return false
  453.         end
  454.  
  455.         local stack = ItemStack(entity.itemstring)
  456.         local name = stack:get_name()
  457.         if own_stack:get_name() ~= name or
  458.                 own_stack:get_meta() ~= stack:get_meta() or
  459.                 own_stack:get_wear() ~= stack:get_wear() or
  460.                 own_stack:get_free_space() == 0 then
  461.             -- Can not merge different or full stack
  462.             return false
  463.         end
  464.  
  465.         local count = own_stack:get_count()
  466.         local total_count = stack:get_count() + count
  467.         local max_count = stack:get_stack_max()
  468.  
  469.         if total_count > max_count then
  470.             return false
  471.         end
  472.         -- Merge the remote stack into this one
  473.  
  474.         local pos = object:get_pos()
  475.         pos.y = pos.y + ((total_count - count) / max_count) * 0.15
  476.         self.object:move_to(pos)
  477.  
  478.         self.age = 0 -- Handle as new entity
  479.         own_stack:set_count(total_count)
  480.         self:set_item(own_stack:to_string())
  481.  
  482.         entity._removed = true
  483.         object:remove()
  484.         return true
  485.     end,
  486.  
  487.     on_step = function(self, dtime)
  488.         if self._removed then
  489.             return
  490.         end
  491.         self.age = self.age + dtime
  492.         if self._collector_timer ~= nil then
  493.             self._collector_timer = self._collector_timer + dtime
  494.         end
  495.         if time_to_live > 0 and self.age > time_to_live then
  496.             self._removed = true
  497.             self.object:remove()
  498.             return
  499.         end
  500.         -- Delete corrupted item entities. The itemstring MUST be non-empty on its first step,
  501.         -- otherwise there might have some data corruption.
  502.         if self.itemstring == "" then
  503.             minetest.log("warning", "Item entity with empty itemstring found at "..minetest.pos_to_string(self.object:get_pos()).. "! Deleting it now.")
  504.             self._removed = true
  505.             self.object:remove()
  506.         end
  507.  
  508.         local p = self.object:get_pos()
  509.         local node = core.get_node_or_nil(p)
  510.         local in_unloaded = (node == nil)
  511.  
  512.         -- If no collector was found for a long enough time, declare the magnet as disabled
  513.         if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then
  514.             self._magnet_active = false
  515.             enable_physics(self.object, self)
  516.             return
  517.         end
  518.         if in_unloaded then
  519.             -- Don't infinetly fall into unloaded map
  520.             disable_physics(self.object, self)
  521.             return
  522.         end
  523.  
  524.         -- Destroy item in lava, fire or special nodes
  525.         local nn = node.name
  526.         local def = minetest.registered_nodes[nn]
  527.         local lg = minetest.get_item_group(nn, "lava")
  528.         local fg = minetest.get_item_group(nn, "fire")
  529.         local dg = minetest.get_item_group(nn, "destroys_items")
  530.         if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then
  531.             if dg ~= 2 then
  532.                 minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5})
  533.             end
  534.             self._removed = true
  535.             self.object:remove()
  536.             return
  537.         end
  538.  
  539.         -- Push item out when stuck inside solid opaque node
  540.         if def and def.walkable and def.groups and def.groups.opaque == 1 then
  541.             local shootdir
  542.             local cx = p.x % 1
  543.             local cz = p.z % 1
  544.             local order = {}
  545.  
  546.             -- First prepare the order in which the 4 sides are to be checked.
  547.             -- 1st: closest
  548.             -- 2nd: other direction
  549.             -- 3rd and 4th: other axis
  550.             local cxcz = function(o, cw, one, zero)
  551.                 if cw > 0 then
  552.                     table.insert(o, { [one]=1, y=0, [zero]=0 })
  553.                     table.insert(o, { [one]=-1, y=0, [zero]=0 })
  554.                 else
  555.                     table.insert(o, { [one]=-1, y=0, [zero]=0 })
  556.                     table.insert(o, { [one]=1, y=0, [zero]=0 })
  557.                 end
  558.                 return o
  559.             end
  560.             if math.abs(cx) > math.abs(cz) then
  561.                 order = cxcz(order, cx, "x", "z")
  562.                 order = cxcz(order, cz, "z", "x")
  563.             else
  564.                 order = cxcz(order, cz, "z", "x")
  565.                 order = cxcz(order, cx, "x", "z")
  566.             end
  567.  
  568.             -- Check which one of the 4 sides is free
  569.             for o=1, #order do
  570.                 local nn = minetest.get_node(vector.add(p, order[o])).name
  571.                 local def = minetest.registered_nodes[nn]
  572.                 if def and def.walkable == false and nn ~= "ignore" then
  573.                     shootdir = order[o]
  574.                     break
  575.                 end
  576.             end
  577.             -- If none of the 4 sides is free, shoot upwards
  578.             if shootdir == nil then
  579.                 shootdir = { x=0, y=1, z=0 }
  580.                 local nn = minetest.get_node(vector.add(p, shootdir)).name
  581.                 if nn == "ignore" then
  582.                     -- Do not push into ignore
  583.                     return
  584.                 end
  585.             end
  586.  
  587.             -- Set new item moving speed accordingly
  588.             local newv = vector.multiply(shootdir, 3)
  589.             self.object:set_acceleration({x = 0, y = 0, z = 0})
  590.             self.object:set_velocity(newv)
  591.  
  592.             disable_physics(self.object, self, false, false)
  593.  
  594.             if shootdir.y == 0 then
  595.                 self._force = newv
  596.                 p.x = math.floor(p.x)
  597.                 p.y = math.floor(p.y)
  598.                 p.z = math.floor(p.z)
  599.                 self._forcestart = p
  600.                 self._forcetimer = 1
  601.             end
  602.             return
  603.         end
  604.  
  605.         -- This code is run after the entity got a push from above “push away” code.
  606.         -- It is responsible for making sure the entity is entirely outside the solid node
  607.         -- (with its full collision box), not just its center.
  608.         if self._forcetimer > 0 then
  609.             local cbox = self.object:get_properties().collisionbox
  610.             local ok = false
  611.             if self._force.x > 0 and (p.x > (self._forcestart.x + 0.5 + (cbox[4] - cbox[1])/2)) then ok = true
  612.             elseif self._force.x < 0 and (p.x < (self._forcestart.x + 0.5 - (cbox[4] - cbox[1])/2)) then ok = true
  613.             elseif self._force.z > 0 and (p.z > (self._forcestart.z + 0.5 + (cbox[6] - cbox[3])/2)) then ok = true
  614.             elseif self._force.z < 0 and (p.z < (self._forcestart.z + 0.5 - (cbox[6] - cbox[3])/2)) then ok = true end
  615.             -- Item was successfully forced out. No more pushing
  616.             if ok then
  617.                 self._forcetimer = -1
  618.                 self._force = nil
  619.                 enable_physics(self.object, self)
  620.             else
  621.                 self._forcetimer = self._forcetimer - dtime
  622.             end
  623.             return
  624.         elseif self._force then
  625.             self._force = nil
  626.             enable_physics(self.object, self)
  627.             return
  628.         end
  629.  
  630.         -- Move item around on flowing liquids
  631.         if def and def.liquidtype == "flowing" then
  632.  
  633.             --[[ Get flowing direction (function call from flowlib), if there's a liquid.
  634.             NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
  635.             Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]]
  636.             local vec = flowlib.quick_flow(p, node)
  637.             -- Just to make sure we don't manipulate the speed for no reason
  638.             if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
  639.                 -- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
  640.                 local f = 1.39
  641.                 -- Set new item moving speed into the direciton of the liquid
  642.                 local newv = vector.multiply(vec, f)
  643.                 self.object:set_acceleration({x = 0, y = 0, z = 0})
  644.                 self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
  645.  
  646.                 self.physical_state = true
  647.                 self._flowing = true
  648.                 self.object:set_properties({
  649.                     physical = true
  650.                 })
  651.                 return
  652.             end
  653.         elseif self._flowing == true then
  654.             -- Disable flowing physics if not on/in flowing liquid
  655.             self._flowing = false
  656.             enable_physics(self.object, self, true)
  657.             return
  658.         end
  659.  
  660.         -- If node is not registered or node is walkably solid and resting on nodebox
  661.         local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
  662.         local v = self.object:get_velocity()
  663.  
  664.         if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then
  665.             if self.physical_state then
  666.                 local own_stack = ItemStack(self.object:get_luaentity().itemstring)
  667.                 -- Merge with close entities of the same item
  668.                 for _, object in ipairs(core.get_objects_inside_radius(p, 0.8)) do
  669.                     local obj = object:get_luaentity()
  670.                     if obj and obj.name == "__builtin:item"
  671.                             and obj.physical_state == false then
  672.                         if self:try_merge_with(own_stack, object, obj) then
  673.                             return
  674.                         end
  675.                     end
  676.                 end
  677.                 disable_physics(self.object, self)
  678.             end
  679.         else
  680.             if self._magnet_active == false then
  681.                 enable_physics(self.object, self)
  682.             end
  683.         end
  684.     end,
  685.  
  686.     -- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching
  687. })
  688.  
  689. if minetest.settings:get_bool("log_mods") then
  690.     minetest.log("action", "mcl_item_entity loaded")
  691. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top