Replace _puncher with _owner, rework projectile code to make _owner a string, copy mcl_util.gen_uuid() from minecart branch, add mcl_util.get_entity_id(), fix crash

This commit is contained in:
teknomunk 2024-10-24 06:39:37 -05:00
parent ec6f28c2d1
commit 8f8d27d7e0
10 changed files with 45 additions and 24 deletions

@ -706,3 +706,26 @@ function mcl_util.trace_nodes(pos, dir, allowed_nodes, limit)
return nil, limit, nil return nil, limit, nil
end end
function mcl_util.gen_uuid()
-- Generate a random 128-bit ID that can be assumed to be unique
-- To have a 1% chance of a collision, there would have to be 1.6x10^76 IDs generated
-- https://en.wikipedia.org/wiki/Birthday_problem#Probability_table
local u = {}
for i = 1,16 do
u[#u + 1] = string.format("%02X",math.random(1,255))
end
return table.concat(u)
end
function mcl_util.get_entity_id(entity)
if entity:is_player() then
return entity:get_player_name()
else
local le = entity:get_luaentity()
local id = le._uuid
if not id then
id = mcl_util.gen_uuid()
le._uuid = id
end
return id
end
end

@ -414,7 +414,7 @@ function mcl_mobs.register_arrow(name, def)
allow_punching = function(self, entity_def, projectile_def, object) allow_punching = function(self, entity_def, projectile_def, object)
if def.allow_punching and not def.allow_punching(self, entity_def, projectile_def, object) then return false end if def.allow_punching and not def.allow_punching(self, entity_def, projectile_def, object) then return false end
if self.timer > 2 then return true end if self.timer > 2 then return true end
if self._owner and object == self._owner.object then return false end if self._owner and mcl_util.get_entity_id(object) == self._owner then return false end
return true return true
end, end,
@ -460,7 +460,7 @@ function mcl_mobs.register_arrow(name, def)
on_punch = def.on_punch or function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) on_punch = def.on_punch or function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
local vel = self.object:get_velocity():length() local vel = self.object:get_velocity():length()
self.object:set_velocity(dir * vel) self.object:set_velocity(dir * vel)
self._puncher = puncher self._owner = mcl_util.get_entity_id(puncher)
end, end,
automatic_face_movement_dir = def.rotate automatic_face_movement_dir = def.rotate
and (def.rotate - (math.pi / 180)) or false, and (def.rotate - (math.pi / 180)) or false,

@ -133,8 +133,8 @@ mcl_mobs.register_arrow("mobs_mc:fireball", {
}, nil) }, nil)
mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1, true) mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1, true)
local ent = mob:get_luaentity() local ent = mob:get_luaentity()
if (not ent or ent.health <= 0) and self._puncher and name == "mobs_mc:ghast" then if (not ent or ent.health <= 0) and self._owner and minetest.get_player_by_name(self._owner) and name == "mobs_mc:ghast" then
awards.unlock(self._puncher:get_player_name(), "mcl:fireball_redir_serv") awards.unlock(self._owner, "mcl:fireball_redir_serv")
end end
end, end,

@ -43,7 +43,7 @@ local arrow_entity = {
_fire_damage_resistant = true, _fire_damage_resistant = true,
_save_fields = { _save_fields = {
"last_pos", "startpos", "damage", "is_critical", "stuck", "stuckin", "stuckin_player", "time_in_air", "last_pos", "startpos", "damage", "is_critical", "stuck", "stuckin", "stuckin_player", "time_in_air", "vl_projectile",
}, },
_startpos=nil, _startpos=nil,
@ -163,10 +163,6 @@ local arrow_entity = {
out[field] = self["_"..field] out[field] = self["_"..field]
end end
if self._owner then
out._owner = self._owner:get_player_name()
end
return minetest.serialize(out) return minetest.serialize(out)
end, end,
on_activate = function(self, staticdata, dtime_s) on_activate = function(self, staticdata, dtime_s)
@ -183,11 +179,9 @@ local arrow_entity = {
self["_"..field] = data[field] self["_"..field] = data[field]
end end
local vl_projectile_data = {} if not self._vl_projectile then
if data._owner then self._vl_projetile = {}
vl_projectile_data.owner = minetest.get_player_by_name(data._owner)
end end
self._vl_projectile = vl_projectile_data
if data.shootername then if data.shootername then
local shooter = minetest.get_player_by_name(data.shootername) local shooter = minetest.get_player_by_name(data.shootername)

@ -329,19 +329,19 @@ vl_projectile.register("mcl_fishing:flying_bobber_entity", {
}, },
collides_with = { "group:liquid" }, collides_with = { "group:liquid" },
on_collide_with_solid = function(self, pos, node) on_collide_with_solid = function(self, pos, node)
if not self._last_pos then return end
local last_pos = self._last_pos
local player = self._owner local player = self._owner
self._remove = true self._remove = true
self.object:remove() self.object:remove()
-- Make sure the player field is valid for when we create the floating bobber
if not player then return end
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if not def then return end if not def then return end
if def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source" then if def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source" then
local ent = minetest.add_entity(last_pos, "mcl_fishing:bobber_entity"):get_luaentity() local ent = minetest.add_entity(pos, "mcl_fishing:bobber_entity"):get_luaentity()
ent.player = player ent.player = player
ent.child = true ent.child = true
end end

@ -51,7 +51,7 @@ vl_projectile.register("mcl_throwing:egg_entity",{
vl_projectile.collides_with_entities, vl_projectile.collides_with_entities,
}, },
allow_punching = function(self, _, _, object) allow_punching = function(self, _, _, object)
if self._owner == object:get_player_name() then if self._owner == mcl_util.get_entity_id(object) then
return self.timer > 1 return self.timer > 1
end end

@ -125,7 +125,7 @@ vl_projectile.register("mcl_throwing:ender_pearl_entity",{
"group:plant", "group:mushroom", "group:plant", "group:mushroom",
}, },
allow_punching = function(self, _, _, object) allow_punching = function(self, _, _, object)
if self._owner == object:get_player_name() then if self._owner == mcl_util.get_entity_id(object) then
return self.timer > 1 return self.timer > 1
end end

@ -23,7 +23,7 @@ function mcl_throwing.throw(throw_item, pos, dir, velocity, thrower)
local itemstring = ItemStack(throw_item):get_name() local itemstring = ItemStack(throw_item):get_name()
local obj = vl_projectile.create(entity_mapping[itemstring], { local obj = vl_projectile.create(entity_mapping[itemstring], {
pos = pos, pos = pos,
owner = thrower, owner_id = thrower,
dir = dir, dir = dir,
velocity = velocity, velocity = velocity,
drag = 3, drag = 3,

@ -55,7 +55,7 @@ vl_projectile.register("mcl_throwing:snowball_entity", {
vl_projectile.collides_with_entities, vl_projectile.collides_with_entities,
}, },
allow_punching = function(self, _, _, object) allow_punching = function(self, _, _, object)
if self._owner == object:get_player_name() then if self._owner == mcl_util.get_entity_id(object) then
return self.timer > 1 return self.timer > 1
end end

@ -80,8 +80,8 @@ function mod.update_projectile(self, dtime)
-- Update entity timer and remove expired projectiles -- Update entity timer and remove expired projectiles
self.timer = (self.timer or 0) + dtime self.timer = (self.timer or 0) + dtime
local maximum_flight_time = entity_vl_projectile.maximum_time local maximum_flight_time = entity_vl_projectile.maximum_time or 300
if self.timer > maximum_flight_time then if (self.timer or 0) > maximum_flight_time then
self.removed = true self.removed = true
self.object:remove() self.object:remove()
return return
@ -591,7 +591,11 @@ function mod.create(entity_id, options)
-- Update projectile parameters -- Update projectile parameters
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()
luaentity._owner = options.owner if options.owner_id then
luaentity._owner = options.owner_id
else
luaentity._owner = mcl_util.get_entity_id(options.owner)
end
luaentity._starting_velocity = obj:get_velocity() luaentity._starting_velocity = obj:get_velocity()
luaentity._vl_projectile = { luaentity._vl_projectile = {
extra = options.extra, extra = options.extra,