change how pickip up works: use two raytraces per step
This allows you to make faster sweeping motions and miss less items.
This commit is contained in:
parent
e70e4c5320
commit
3c1e01fe2d
83
init.lua
83
init.lua
@ -97,17 +97,41 @@ end
|
||||
|
||||
-- TODO recheck if player leaving the server is not crashing it
|
||||
|
||||
local function try_to_pickup(player, pointed_thing)
|
||||
-- TODO check if we can pick up more item
|
||||
-- TODO if can't pick up any more items, then maybe move the item entity a bit?
|
||||
local item = pointed_thing.ref:get_luaentity()
|
||||
if item and item.on_punch then -- TODO probaly don't need this check
|
||||
minetest.sound_play("dvornik_pickup", {
|
||||
to_player = player:get_player_name()
|
||||
--pos = player:get_pos(),
|
||||
--max_hear_distance = 10
|
||||
})
|
||||
minetest.add_particle({
|
||||
pos = pointed_thing.ref:get_pos(),
|
||||
expirationtime = 1,
|
||||
size = 1,
|
||||
texture = "tnt_smoke.png" -- TODO
|
||||
})
|
||||
item:on_punch(player)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local RANGE = 3.0
|
||||
--local RADIUS = 1.0
|
||||
local function trace_and_pickup(player)
|
||||
local p_eye_pos = player_get_eye_pos(player)
|
||||
local prev_point = active_veniks[player]
|
||||
local to = vector.add(p_eye_pos, vector.multiply(player:get_look_dir(), RANGE))
|
||||
local ray = minetest.raycast(
|
||||
p_eye_pos,
|
||||
to,
|
||||
true, -- point to objects
|
||||
false) -- point to liquids
|
||||
-- First trace: find what player is looking at
|
||||
local pointed_thing = ray:next()
|
||||
local current_point = nil
|
||||
while pointed_thing do
|
||||
if DEBUG and pointed_thing.type ~= "nothing" and not (pointed_thing.type == "object" and pointed_thing.ref == player) then
|
||||
local point = pointed_thing.intersection_point
|
||||
@ -119,31 +143,51 @@ local function trace_and_pickup(player)
|
||||
-- for _, obj in pairs(minetest.get_objects_inside_radius(point, RADIUS)) do
|
||||
-- obj:remove()
|
||||
-- end
|
||||
local item = pointed_thing.ref:get_luaentity()
|
||||
-- TODO check if we can pick up more item
|
||||
-- TODO if can't pick up any more items, then maybe move the item entity a bit?
|
||||
if item.on_punch then -- TODO probaly don't need this check
|
||||
minetest.sound_play("dvornik_pickup", {
|
||||
to_player = player:get_player_name()
|
||||
--pos = player:get_pos(),
|
||||
--max_hear_distance = 10
|
||||
})
|
||||
minetest.add_particle({
|
||||
pos = pointed_thing.ref:get_pos(),
|
||||
expirationtime = 1,
|
||||
size = 1,
|
||||
texture = "tnt_smoke.png" -- TODO
|
||||
|
||||
})
|
||||
item:on_punch(player)
|
||||
end
|
||||
|
||||
-- Player is looking at an item: use the item position
|
||||
current_point = pointed_thing.ref:get_pos()
|
||||
break
|
||||
end
|
||||
elseif pointed_thing.type == "node" then
|
||||
-- move intersection point a little bit away from the block
|
||||
local HEIGHT = 0.2
|
||||
-- Player is looking at a block: move a little bit away from it
|
||||
current_point = vector.multiply(
|
||||
vector.add(pointed_thing.intersection_point,
|
||||
pointed_thing.intersection_normal),
|
||||
HEIGHT)
|
||||
break
|
||||
end
|
||||
pointed_thing = ray:next()
|
||||
end
|
||||
|
||||
-- Second trace: trace from old previous position to current
|
||||
if not prev_point then
|
||||
prev_point = p_eye_pos
|
||||
end
|
||||
-- TODO maybe limit the distance between prev/current points?
|
||||
if prev_point and prev_point.x and current_point and current_point.x then
|
||||
local ray = minetest.raycast(prev_point,
|
||||
current_point,
|
||||
true,
|
||||
false)
|
||||
local pointed_thing = ray:next()
|
||||
while pointed_thing do
|
||||
if pointed_thing.type == "object" then
|
||||
if pointed_thing.ref ~= player then
|
||||
-- Just pick up everything that was between
|
||||
-- previous and current points
|
||||
try_to_pickup(player, pointed_thing)
|
||||
end
|
||||
end
|
||||
pointed_thing = ray:next()
|
||||
end
|
||||
end
|
||||
-- store the point for next timestep
|
||||
active_veniks[player] = current_point
|
||||
end
|
||||
|
||||
local timer = 0
|
||||
|
||||
minetest.register_globalstep(function(_dtime)
|
||||
for player, _ in pairs(active_veniks) do
|
||||
trace_and_pickup(player)
|
||||
@ -151,6 +195,7 @@ minetest.register_globalstep(function(_dtime)
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player, timed_out)
|
||||
deactivate_venik(player)
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user