Merge pull request 'Sculk removed off xp_step and triggered by player and mob death [Performance]' (#3545) from sculk_performance_fix into master

Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3545
Reviewed-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 <mrrar@noreply.git.minetest.land>
This commit is contained in:
ancientmarinerdev 2023-03-17 20:42:23 +00:00
commit d437f45f4a
3 changed files with 67 additions and 36 deletions

View file

@ -2,4 +2,4 @@ name = mcl_mobs
author = PilzAdam author = PilzAdam
description = Adds a mob API for mods to add animals or monsters, etc. description = Adds a mob API for mods to add animals or monsters, etc.
depends = mcl_particles depends = mcl_particles
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience, mcl_sculk

View file

@ -488,9 +488,21 @@ function mob_class:check_for_death(cause, cmi_cause)
self:item_drop(cooked, looting) self:item_drop(cooked, looting)
if ((not self.child) or self.type ~= "animal") and (minetest.get_us_time() - self.xp_timestamp <= math.huge) then if ((not self.child) or self.type ~= "animal") and (minetest.get_us_time() - self.xp_timestamp <= math.huge) then
mcl_experience.throw_xp(self.object:get_pos(), math.random(self.xp_min, self.xp_max)) local pos = self.object:get_pos()
local xp_amount = math.random(self.xp_min, self.xp_max)
if not mcl_sculk.handle_death(pos, xp_amount) then
--minetest.log("Xp not thrown")
if minetest.is_creative_enabled("") ~= true then
mcl_experience.throw_xp(pos, xp_amount)
end
else
--minetest.log("xp thrown")
end
end end
end end
end end
-- execute custom death function -- execute custom death function

View file

@ -1,4 +1,7 @@
local S = minetest.get_translator(minetest.get_current_modname()) local S = minetest.get_translator(minetest.get_current_modname())
mcl_sculk = {}
local mt_sound_play = minetest.sound_play local mt_sound_play = minetest.sound_play
local spread_to = {"mcl_core:stone","mcl_core:dirt","mcl_core:sand","mcl_core:dirt_with_grass","group:grass_block","mcl_core:andesite","mcl_core:diorite","mcl_core:granite","mcl_core:mycelium","group:dirt","mcl_end:end_stone","mcl_nether:netherrack","mcl_blackstone:basalt","mcl_nether:soul_sand","mcl_blackstone:soul_soil","mcl_crimson:warped_nylium","mcl_crimson:crimson_nylium","mcl_core:gravel"} local spread_to = {"mcl_core:stone","mcl_core:dirt","mcl_core:sand","mcl_core:dirt_with_grass","group:grass_block","mcl_core:andesite","mcl_core:diorite","mcl_core:granite","mcl_core:mycelium","group:dirt","mcl_end:end_stone","mcl_nether:netherrack","mcl_blackstone:basalt","mcl_nether:soul_sand","mcl_blackstone:soul_soil","mcl_crimson:warped_nylium","mcl_crimson:crimson_nylium","mcl_core:gravel"}
@ -102,27 +105,26 @@ local function has_nonsculk(pos)
if minetest.get_item_group(minetest.get_node(p).name,"sculk") <= 0 and minetest.get_item_group(minetest.get_node(p).name,"solid") > 0 then return p end if minetest.get_item_group(minetest.get_node(p).name,"sculk") <= 0 and minetest.get_item_group(minetest.get_node(p).name,"solid") > 0 then return p end
end end
end end
local function retrieve_close_spreadable_nodes (p)
local nnn = minetest.find_nodes_in_area(vector.offset(p,-SPREAD_RANGE,-SPREAD_RANGE,-SPREAD_RANGE),vector.offset(p,SPREAD_RANGE,SPREAD_RANGE,SPREAD_RANGE),spread_to)
local nn={}
for _,v in pairs(nnn) do
if has_air(v) then
table.insert(nn,v)
end
end
table.sort(nn,function(a, b)
return vector.distance(p, a) < vector.distance(p, b)
end)
return nn
end
local old_on_step = minetest.registered_entities["mcl_experience:orb"].on_step local function spread_sculk (p, xp_amount)
local c = minetest.find_node_near(p,SPREAD_RANGE,{"mcl_sculk:catalyst"})
minetest.registered_entities["mcl_experience:orb"].on_step = function(self,dtime) if c then
local p = self.object:get_pos() local nn = retrieve_close_spreadable_nodes (p)
local nu = minetest.get_node(vector.offset(p,0,-1,0)) if nn and #nn > 0 then
local ret = old_on_step(self,dtime) if xp_amount > 0 then
if not self._sculkdrop then
local c = minetest.find_node_near(p,SPREAD_RANGE,{"mcl_sculk:catalyst"})
if c then
local nnn = minetest.find_nodes_in_area(vector.offset(p,-SPREAD_RANGE,-SPREAD_RANGE,-SPREAD_RANGE),vector.offset(p,SPREAD_RANGE,SPREAD_RANGE,SPREAD_RANGE),spread_to)
local nn={}
for _,v in pairs(nnn) do
if has_air(v) then
table.insert(nn,v)
end
end
table.sort(nn,function(a, b)
return vector.distance(p, a) < vector.distance(p, b)
end)
if nn and #nn > 0 and self._xp > 0 then
local d = math.random(100) local d = math.random(100)
--[[ --enable to generate shriekers and sensors --[[ --enable to generate shriekers and sensors
if d <= 1 then if d <= 1 then
@ -136,27 +138,44 @@ minetest.registered_entities["mcl_experience:orb"].on_step = function(self,dtime
self.object:remove() self.object:remove()
return ret return ret
else --]] else --]]
local r = math.min(math.random(#nn),self._xp)
for i=1,r do
minetest.set_node(nn[i],{name = "mcl_sculk:sculk" }) local r = math.min(math.random(#nn), xp_amount)
set_node_xp(nn[i],math.floor(self._xp / r)) --minetest.log("r: ".. r)
for i=1,r do
minetest.set_node(nn[i],{name = "mcl_sculk:sculk" })
set_node_xp(nn[i],math.floor(xp_amount / r))
end
for i=1,r do
local p = has_nonsculk(nn[i])
if p and has_air(p) then
minetest.set_node(vector.offset(p,0,1,0),{name = "mcl_sculk:vein", param2 = 1})
end end
for i=1,r do end
local p = has_nonsculk(nn[i]) set_node_xp(nn[1],get_node_xp(nn[1]) + xp_amount % r)
if p and has_air(p) then return true
minetest.set_node(vector.offset(p,0,1,0),{name = "mcl_sculk:vein", param2 = 1}) --self.object:remove()
end
end
set_node_xp(nn[1],get_node_xp(nn[1]) + self._xp % r)
self.object:remove()
return ret
--end --end
end end
end end
end end
return ret
end end
function mcl_sculk.handle_death(pos, xp_amount)
if not pos or not xp_amount then return end
--local nu = minetest.get_node(vector.offset(p,0,-1,0))
return spread_sculk (pos, xp_amount)
end
minetest.register_on_dieplayer(function(player)
if mcl_sculk.handle_death(player:get_pos(), 5) then
--minetest.log("Player is dead. Sculk")
else
--minetest.log("Player is dead. not Sculk")
end
end)
minetest.register_node("mcl_sculk:sculk", { minetest.register_node("mcl_sculk:sculk", {
description = S("Sculk"), description = S("Sculk"),
tiles = { tiles = {