
aom_item_entity.LISTEN("on_step", function(self, dtime, moveresult, ...)
    return aom_item_entity.SIGNAL("on_magnet", self, dtime)
end)

aom_item_entity.LISTEN("on_magnet", function(self, dtime)
    if self._picking_up_by then
        local player = self._picking_up_by
        local pos = self.object:get_pos()
        local target = aom_item_entity.get_eyepos(player, -1)
        local dist = vector.distance(vector.new(pos.x, target.y, pos.z), target)

        if dist < 0.1 then
            local inv = player:get_inventory()
            local stack = ItemStack(self.itemstring)
            stack:set_count(1)
            if inv:room_for_item("main", stack) then
                minetest.sound_play("aom_pickup_item", {
                    gain = 0.3 + math.random() * 0.1,
                    to_player = player:get_player_name(),
                    pitch = 0.8 + math.random() * 0.2
                })
                return aom_item_entity.SIGNAL("pickup_item", self, player, false)
            else
                self._picking_up_by = nil
                self:enable_physics()
                self.object:set_velocity(vector.new(0,0,0))
            end
        elseif dist < aom_item_entity.get(player, "item_pickup_max_dist", 2.5) then
            local dir = vector.direction(pos, target)
            dir.y = dir.y + (0.05)
            local vel = vector.multiply(dir, aom_item_entity.settings.magnet_speed)

            local lvel = self.object:get_velocity()
            lvel = vector.multiply(lvel, -0.07)
            vel = vector.add(lvel, vel)

            self.object:set_velocity(vel)
        elseif self._picking_up_by and (dist > aom_item_entity.get(player, "item_pickup_max_dist", 2.5) + 0.3) then
            self:enable_physics()
            self._picking_up_by = nil
        end
    end
end)

aom_item_entity.LISTEN("set_magnet", function(self, player)
    self._picking_up_by = player
    self:disable_physics()

    local dir = vector.direction(self.object:get_pos(), player:get_pos())
    local vel = vector.multiply(dir, 2)

    self.object:set_velocity(vel)
end)

local pl = {}
-- check if player can pickup this item
function aom_item_entity.process_item_ent(self, player)
    if self._picking_up_by then return end
    if self.age < aom_item_entity.settings.grace_period then return end

    local inv = player:get_inventory()
    local stack = ItemStack(self.itemstring)
    stack:set_count(1)
    if not inv:room_for_item("main", stack) then return end
    if not aom_item_entity.player_can_pickup(self, player) then return end
    aom_item_entity.SIGNAL("set_magnet", self, player)
end
-- actually loop through each player to make them pick up items
aom_item_entity.on_globalstep = function(dtime)
    for i, player in pairs(minetest.get_connected_players()) do
        if not pl[player] then pl[player] = {t=1} end
        if pl[player].t > 0 then
            pl[player].t = pl[player].t - dtime
        else repeat
            pl[player].t = 0.5 + math.random()*0.1
            if player:get_meta():get_string("dead") == "true" then break end

            local pos = aom_item_entity.get_eyepos(player, -1)
            local objects = minetest.get_objects_inside_radius(pos, aom_item_entity.get(player, "item_pickup_max_dist", 2.5))
            for k, obj in pairs(objects) do
                local ent = obj:get_luaentity()
                if ent and ent.name == "__builtin:item" then
                    aom_item_entity.process_item_ent(ent, player)
                end
            end
        until true end
    end
end
minetest.register_globalstep(aom_item_entity.on_globalstep)
