Make arrow stuck when they hit solid node (WIP)

This commit is contained in:
Wuzzy 2018-05-08 00:38:00 +02:00
parent fb8c5300cd
commit 47d067d9ec

View File

@ -1,3 +1,6 @@
-- Time in seconds after which a stuck arrow is deleted
local ARROW_TIMEOUT = 60
local mod_mcl_hunger = minetest.get_modpath("mcl_hunger") local mod_mcl_hunger = minetest.get_modpath("mcl_hunger")
local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements")
@ -43,6 +46,7 @@ minetest.register_node("mcl_bows:arrow_box", {
groups = {not_in_creative_inventory=1}, groups = {not_in_creative_inventory=1},
}) })
-- FIXME: Restore arrow state properly on re-loading
local THROWING_ARROW_ENTITY={ local THROWING_ARROW_ENTITY={
physical = false, physical = false,
visual = "wielditem", visual = "wielditem",
@ -53,6 +57,8 @@ local THROWING_ARROW_ENTITY={
_lastpos={}, _lastpos={},
_startpos=nil, _startpos=nil,
_damage=1, -- Damage on impact _damage=1, -- Damage on impact
_stuck=false, -- Whether arrow is stuck
_stucktimer=nil,-- Amount of time (in seconds) the arrow has been stuck so far
_shooter=nil, -- ObjectRef of player or mob who shot it _shooter=nil, -- ObjectRef of player or mob who shot it
} }
@ -60,8 +66,36 @@ THROWING_ARROW_ENTITY.on_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if self._stuck then
self._stucktimer = self._stucktimer + dtime
if self._stucktimer > ARROW_TIMEOUT then
self.object:remove()
return
end
local objects = minetest.get_objects_inside_radius(pos, 2)
for _,obj in ipairs(objects) do
if obj:is_player() then
if not minetest.settings:get_bool("creative_mode") then
-- Pickup arrow if player is nearby
if obj:get_inventory():room_for_item("main", "mcl_bows:arrow") then
obj:get_inventory():add_item("main", "mcl_bows:arrow")
minetest.sound_play("item_drop_pickup", {
pos = pos,
max_hear_distance = 16,
gain = 1.0,
})
self.object:remove()
return
end
else
self.object:remove()
return
end
end
end
-- Check for object collision. Done every tick (hopefully this is not too stressing) -- Check for object collision. Done every tick (hopefully this is not too stressing)
do else
local objs = minetest.get_objects_inside_radius(pos, 2) local objs = minetest.get_objects_inside_radius(pos, 2)
local closest_object local closest_object
local closest_distance local closest_distance
@ -128,13 +162,14 @@ THROWING_ARROW_ENTITY.on_step = function(self, dtime)
end end
-- Check for node collision -- Check for node collision
if self._lastpos.x~=nil then if self._lastpos.x~=nil and not self._stuck then
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if (def and def.walkable) or not def then if (def and def.walkable) or not def then
if not minetest.settings:get_bool("creative_mode") then -- Arrow is stuck and no longer moves
minetest.add_item(self._lastpos, 'mcl_bows:arrow') self._stuck = true
end self._stucktimer = 0
self.object:remove() self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration({x=0, y=0, z=0})
elseif (def and def.liquidtype ~= "none") then elseif (def and def.liquidtype ~= "none") then
-- Slow down arrow in liquids -- Slow down arrow in liquids
local v = def.liquid_viscosity local v = def.liquid_viscosity