Merge pull request 'Fix bobber collision, ender pearl crash' (#4806) from fix-bobber into master

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4806
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
This commit is contained in:
the-real-herowl 2025-01-05 18:39:34 +01:00
commit ae5353b070
5 changed files with 44 additions and 53 deletions

View file

@ -35,8 +35,7 @@ local fish = function(itemstack, player, pointed_thing)
local pos = player:get_pos() local pos = player:get_pos()
local objs = minetest.get_objects_inside_radius(pos, 125) local objs = minetest.get_objects_inside_radius(pos, 125)
local num = 0 local ent
local ent = nil
local noent = true local noent = true
local durability = FISHING_ROD_DURABILITY local durability = FISHING_ROD_DURABILITY
@ -53,9 +52,7 @@ local fish = function(itemstack, player, pointed_thing)
if (player:get_player_name() == ent.player) then if (player:get_player_name() == ent.player) then
noent = false noent = false
if ent._dive == true then if ent._dive == true then
local itemname
local items local items
local itemcount = 1
local pr = PseudoRandom(os.time() * math.random(1, 100)) local pr = PseudoRandom(os.time() * math.random(1, 100))
local r = pr:next(1, 100) local r = pr:next(1, 100)
local fish_values = {85, 84.8, 84.7, 84.5} local fish_values = {85, 84.8, 84.7, 84.5}
@ -173,15 +170,13 @@ local fish = function(itemstack, player, pointed_thing)
end end
end end
--Check for flying bobber. --Check for flying bobber.
local player_name = player:get_player_name()
for n = 1, #objs do for n = 1, #objs do
ent = objs[n]:get_luaentity() ent = objs[n]:get_luaentity()
if ent then if ent and ent._owner == player_name and ent.objtype=="fishing" then
if ent._thrower and ent.objtype=="fishing" then noent = false
if player:get_player_name() == ent._thrower then mcl_util.remove_entity(ent)
noent = false break
break
end
end
end end
end end
--If no bobber or flying_bobber exists then throw bobber. --If no bobber or flying_bobber exists then throw bobber.
@ -313,17 +308,19 @@ bobber_ENTITY.on_step = bobber_on_step
core.register_entity("mcl_fishing:bobber_entity", bobber_ENTITY) core.register_entity("mcl_fishing:bobber_entity", bobber_ENTITY)
vl_projectile.register("mcl_fishing:flying_bobber_entity", { vl_projectile.register("mcl_fishing:flying_bobber_entity", {
physical = false, physical = true,
collide_with_objects = false,
timer=0, timer=0,
textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture. textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture.
visual_size = {x=0.5, y=0.5}, visual_size = {x=0.5, y=0.5},
collisionbox = {0,0,0,0,0,0}, collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1},
pointable = false, pointable = false,
get_staticdata = mcl_throwing.get_staticdata, get_staticdata = mcl_throwing.get_staticdata,
on_activate = mcl_throwing.on_activate, on_activate = mcl_throwing.on_activate,
_vl_projectile = { _vl_projectile = {
survive_collision = true,
behaviors = { behaviors = {
vl_projectile.collides_with_solids, vl_projectile.collides_with_solids,
}, },
@ -331,8 +328,6 @@ vl_projectile.register("mcl_fishing:flying_bobber_entity", {
on_collide_with_solid = function(self, pos, node) on_collide_with_solid = function(self, pos, node)
local player = self._owner local player = self._owner
mcl_util.remove_entity(self)
-- Make sure the player field is valid for when we create the floating bobber -- Make sure the player field is valid for when we create the floating bobber
if not player then return end if not player then return end
@ -343,12 +338,16 @@ vl_projectile.register("mcl_fishing:flying_bobber_entity", {
local ent = core.add_entity(pos, "mcl_fishing:bobber_entity"):get_luaentity() local ent = core.add_entity(pos, "mcl_fishing:bobber_entity"):get_luaentity()
ent.player = player ent.player = player
ent.child = true ent.child = true
mcl_util.remove_entity(self)
else
local obj = self.object
obj:set_velocity(vector.zero())
obj:set_acceleration(vector.zero())
end end
end end
}, },
_lastpos={}, _lastpos={},
_thrower = nil,
objtype="fishing", objtype="fishing",
}) })
@ -357,14 +356,12 @@ mcl_throwing.register_throwable_object("mcl_fishing:flying_bobber", "mcl_fishing
-- If player leaves area, remove bobber. -- If player leaves area, remove bobber.
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) local objs = minetest.get_objects_inside_radius(player:get_pos(), 250)
local ent = nil
local noent = true
for n = 1, #objs do for n = 1, #objs do
ent = objs[n]:get_luaentity() local ent = objs[n]:get_luaentity()
if ent then if ent then
if ent.player and ent.objtype=="fishing" then if ent.player and ent.objtype=="fishing" then
ent.object:remove() ent.object:remove()
elseif ent._thrower and ent.objtype=="fishing" then elseif ent._owner and ent.objtype=="fishing" then
ent.object:remove() ent.object:remove()
end end
end end
@ -374,16 +371,13 @@ end)
-- If player dies, remove bobber. -- If player dies, remove bobber.
minetest.register_on_dieplayer(function(player) minetest.register_on_dieplayer(function(player)
local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) local objs = minetest.get_objects_inside_radius(player:get_pos(), 250)
local num = 0
local ent = nil
local noent = true
for n = 1, #objs do for n = 1, #objs do
ent = objs[n]:get_luaentity() local ent = objs[n]:get_luaentity()
if ent then if ent then
if ent.player and ent.objtype=="fishing" then if ent.player and ent.objtype=="fishing" then
ent.object:remove() ent.object:remove()
elseif ent._thrower and ent.objtype=="fishing" then elseif ent._owner and ent.objtype=="fishing" then
ent.object:remove() ent.object:remove()
end end
end end
@ -518,10 +512,8 @@ minetest.register_craftitem("mcl_fishing:pufferfish_raw", {
minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, user, pointed_thing) minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, user, pointed_thing)
if itemstack:get_name() == "mcl_fishing:pufferfish_raw" then if itemstack:get_name() == "mcl_fishing:pufferfish_raw" then
mcl_potions.give_effect_by_level("poison", user, 3, 60) mcl_potions.give_effect_by_level("poison", user, 3, 60)
mcl_potions.give_effect_by_level("nausea", user, 2, 20) mcl_potions.give_effect_by_level("nausea", user, 2, 20)
end end
end ) end )

View file

@ -32,11 +32,11 @@ local function egg_spawn_chicks(pos)
end end
vl_projectile.register("mcl_throwing:egg_entity",{ vl_projectile.register("mcl_throwing:egg_entity",{
physical = false, physical = true,
timer=0, timer=0,
textures = {"mcl_throwing_egg.png"}, textures = {"mcl_throwing_egg.png"},
visual_size = {x=0.45, y=0.45}, visual_size = {x=0.45, y=0.45},
collisionbox = {0,0,0,0,0,0}, collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1},
pointable = false, pointable = false,
get_staticdata = mcl_throwing.get_staticdata, get_staticdata = mcl_throwing.get_staticdata,

View file

@ -31,7 +31,7 @@ function on_collide(self, pos, node)
end end
-- Make sure we have a reference to the player -- Make sure we have a reference to the player
local player = self._thrower and core.get_player_by_name(self._thrower) local player = self._owner and core.get_player_by_name(self._owner)
if not player then return end if not player then return end
-- Teleport and hurt player -- Teleport and hurt player
@ -101,11 +101,11 @@ end
-- Ender pearl entity -- Ender pearl entity
vl_projectile.register("mcl_throwing:ender_pearl_entity",{ vl_projectile.register("mcl_throwing:ender_pearl_entity",{
physical = false, physical = true,
timer=0, timer=0,
textures = {"mcl_throwing_ender_pearl.png"}, textures = {"mcl_throwing_ender_pearl.png"},
visual_size = {x=0.9, y=0.9}, visual_size = {x=0.9, y=0.9},
collisionbox = {0,0,0,0,0,0}, collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1},
pointable = false, pointable = false,
get_staticdata = mcl_throwing.get_staticdata, get_staticdata = mcl_throwing.get_staticdata,
@ -113,7 +113,6 @@ vl_projectile.register("mcl_throwing:ender_pearl_entity",{
on_step = vl_projectile.update_projectile, on_step = vl_projectile.update_projectile,
_lastpos={}, _lastpos={},
_thrower = nil, -- Player ObjectRef of the player who threw the ender pearl
_vl_projectile = { _vl_projectile = {
behaviors = { behaviors = {
vl_projectile.collides_with_solids, vl_projectile.collides_with_solids,

View file

@ -40,11 +40,11 @@ local function snowball_particles(pos, vel)
}) })
end end
vl_projectile.register("mcl_throwing:snowball_entity", { vl_projectile.register("mcl_throwing:snowball_entity", {
physical = false, physical = true,
timer=0, timer=0,
textures = {"mcl_throwing_snowball.png"}, textures = {"mcl_throwing_snowball.png"},
visual_size = {x=0.5, y=0.5}, visual_size = {x=0.5, y=0.5},
collisionbox = {0,0,0,0,0,0}, collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1},
pointable = false, pointable = false,
get_staticdata = mcl_throwing.get_staticdata, get_staticdata = mcl_throwing.get_staticdata,

View file

@ -359,24 +359,24 @@ function mod.collides_with_solids(self, dtime, entity_def, projectile_def)
local node_def = core.registered_nodes[node.name] local node_def = core.registered_nodes[node.name]
local collides_with = projectile_def.collides_with local collides_with = projectile_def.collides_with
if entity_def.physical then if not collides_with or not mcl_util.match_node_to_filter(node.name, collides_with) then
-- Projectile has stopped in one axis, so it probably hit something. if entity_def.physical then
-- This detection is a bit clunky, but sadly, MT does not offer a direct collision detection for us. :-( -- Projectile has stopped in one axis, so it probably hit something.
local vel = self.object:get_velocity() -- This detection is a bit clunky, but sadly, MT does not offer a direct collision detection for us. :-(
if not self._last_velocity then local vel = self.object:get_velocity()
self._last_velocity = vel if not self._last_velocity then
return self._last_velocity = vel
end return
end
local delta_v = (vel - self._last_velocity) local delta_v = (vel - self._last_velocity)
local vel_length = vector.length(vel) local vel_length = vector.length(vel)
if vel_length > 1 then delta_v = delta_v / vel_length end if vel_length > 1 then delta_v = delta_v / vel_length end
self._last_velocity = vel self._last_velocity = vel
if math.abs(delta_v.x) <= 0.1 and math.abs(delta_v.z) <= 0.1 and math.abs(delta_v.y) <= 0.2 then if math.abs(delta_v.x) <= 0.1 and math.abs(delta_v.z) <= 0.1 and math.abs(delta_v.y) <= 0.2 then
return return
end end
else elseif node_def and not node_def.walkable then
if node_def and not node_def.walkable and (not collides_with or not mcl_util.match_node_to_filter(node.name, collides_with)) then
return return
end end
end end
@ -430,7 +430,7 @@ function mod.collides_with_solids(self, dtime, entity_def, projectile_def)
if hook then hook(self, self._stuckin, snode, sdef) end if hook then hook(self, self._stuckin, snode, sdef) end
end end
-- Call entity collied hook -- Call entity collided hook
local hook = projectile_def.on_collide_with_solid local hook = projectile_def.on_collide_with_solid
if hook then hook(self, pos, node, node_def) end if hook then hook(self, pos, node, node_def) end