Make the data table different for each arrow

I found myself discovering, while re-reading this code (and judging it not so readable, despite myself being its author), that data table of each arrow was in fact a single reference shared between all entities corresponding to an arrow of the same type.
I'm really sorry about this and the catastrophes it may have caused (e.g., it made it easy to duplicate an item using a drop arrow by throwing a random item, and then throwing the item to duplicate before the first arrow hit the ground: both arrows would then produce the stack that was thrown last). I hope no player discovered this on a server that used this mod.

(Also, I don't really see the point of the make_arrow_def function anymore, so I removed it. I wrote this too long ago to remember why I would write such code.)
This commit is contained in:
upsilon 2020-02-16 18:20:37 +01:00
parent 1449f49af7
commit b9c78c92b2
No known key found for this signature in database
GPG Key ID: A80DAE1F266E1C3C
1 changed files with 6 additions and 9 deletions

View File

@ -43,10 +43,14 @@ local function shoot_arrow(itemstack, player, index, throw_itself, new_stack)
local obj = (minetest.registered_items[itemstack:get_name()].spawn_arrow_entity or throwing.spawn_arrow_entity)(pos, arrow, player)
local luaentity = obj:get_luaentity()
-- Set custom data in the entity
luaentity.player = player:get_player_name()
if not luaentity.item then
luaentity.item = arrow
end
luaentity.data = {}
luaentity.timer = 0
if luaentity.on_throw then
if luaentity:on_throw(pos, player, arrow_stack, index, luaentity.data) == false then
@ -203,14 +207,6 @@ local function arrow_step(self, dtime)
self.last_pos = pos -- Used by the build arrow
end
function throwing.make_arrow_def(def)
def.timer = 0
def.player = ""
def.on_step = arrow_step
def.data = {}
return def
end
--[[
on_hit(pos, last_pos, node, object, hitter)
Either node or object is nil, depending whether the arrow collided with an object (luaentity or player) or with a node.
@ -276,7 +272,7 @@ function throwing.register_arrow(name, def)
}
minetest.register_node(registration_name, def)
minetest.register_entity(registration_name.."_entity", throwing.make_arrow_def{
minetest.register_entity(registration_name.."_entity", {
physical = false,
visual = "wielditem",
visual_size = {x = 0.125, y = 0.125},
@ -289,6 +285,7 @@ function throwing.register_arrow(name, def)
allow_protected = def.allow_protected,
target = def.target,
on_hit_fails = def.on_hit_fails,
on_step = arrow_step,
item = name,
})
end