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 cb1d0d9290
commit 5185c043bb
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
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)
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._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
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)
local vel = self.object:get_velocity():length()
self.object:set_velocity(dir * vel)
self._puncher = puncher
self._owner = mcl_util.get_entity_id(puncher)
end,
automatic_face_movement_dir = def.rotate
and (def.rotate - (math.pi / 180)) or false,

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

@ -43,7 +43,7 @@ local arrow_entity = {
_fire_damage_resistant = true,
_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,
@ -163,10 +163,6 @@ local arrow_entity = {
out[field] = self["_"..field]
end
if self._owner then
out._owner = self._owner:get_player_name()
end
return minetest.serialize(out)
end,
on_activate = function(self, staticdata, dtime_s)
@ -183,11 +179,9 @@ local arrow_entity = {
self["_"..field] = data[field]
end
local vl_projectile_data = {}
if data._owner then
vl_projectile_data.owner = minetest.get_player_by_name(data._owner)
if not self._vl_projectile then
self._vl_projetile = {}
end
self._vl_projectile = vl_projectile_data
if data.shootername then
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" },
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
self._remove = true
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]
if not def then return end
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.child = true
end

@ -51,7 +51,7 @@ vl_projectile.register("mcl_throwing:egg_entity",{
vl_projectile.collides_with_entities,
},
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
end

@ -125,7 +125,7 @@ vl_projectile.register("mcl_throwing:ender_pearl_entity",{
"group:plant", "group:mushroom",
},
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
end

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

@ -55,7 +55,7 @@ vl_projectile.register("mcl_throwing:snowball_entity", {
vl_projectile.collides_with_entities,
},
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
end

@ -80,8 +80,8 @@ function mod.update_projectile(self, dtime)
-- Update entity timer and remove expired projectiles
self.timer = (self.timer or 0) + dtime
local maximum_flight_time = entity_vl_projectile.maximum_time
if self.timer > maximum_flight_time then
local maximum_flight_time = entity_vl_projectile.maximum_time or 300
if (self.timer or 0) > maximum_flight_time then
self.removed = true
self.object:remove()
return
@ -591,7 +591,11 @@ function mod.create(entity_id, options)
-- Update projectile parameters
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._vl_projectile = {
extra = options.extra,