mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2025-04-22 07:15:14 +02:00
Merge pull request 'mcl_mobs spawning cleanup and performance optimization' (#4468) from mcl_mobs_cleanup into master
Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4468 Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
This commit is contained in:
commit
62efc371a1
10 changed files with 728 additions and 588 deletions
|
@ -25,6 +25,7 @@ read_globals = {
|
|||
"indexof",
|
||||
"insert_all",
|
||||
"key_value_swap",
|
||||
"shuffle",
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -4,66 +4,7 @@ local modname = core.get_current_modname()
|
|||
local modpath = core.get_modpath(modname)
|
||||
dofile(modpath.."/roman_numerals.lua")
|
||||
dofile(modpath.."/nodes.lua")
|
||||
|
||||
-- Updates all values in t using values from to*.
|
||||
function table.update(t, ...)
|
||||
for _, to in ipairs {...} do
|
||||
for k, v in pairs(to) do
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Updates nil values in t using values from to*.
|
||||
function table.update_nil(t, ...)
|
||||
for _, to in ipairs {...} do
|
||||
for k, v in pairs(to) do
|
||||
if t[k] == nil then
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
---Works the same as `pairs`, but order returned by keys
|
||||
---
|
||||
---Taken from https://www.lua.org/pil/19.3.html
|
||||
---@generic T: table, K, V, C
|
||||
---@param t T
|
||||
---@param f? fun(a: C, b: C):boolean
|
||||
---@return fun():K, V
|
||||
function table.pairs_by_keys(t, f)
|
||||
local a = {}
|
||||
for n in pairs(t) do table.insert(a, n) end
|
||||
table.sort(a, f)
|
||||
|
||||
local i = 0 -- iterator variable
|
||||
local function iter() -- iterator function
|
||||
i = i + 1
|
||||
if a[i] == nil then
|
||||
return nil
|
||||
else
|
||||
return a[i], t[a[i]]
|
||||
end
|
||||
end
|
||||
return iter
|
||||
end
|
||||
|
||||
-- Removes one element randomly selected from the array section of the table and
|
||||
-- returns it, or nil if there are no elements in the array section of the table
|
||||
function table.remove_random_element(table)
|
||||
local count = #table
|
||||
if count == 0 then return nil end
|
||||
|
||||
local idx = math.random(count)
|
||||
local res = table[idx]
|
||||
table[idx] = table[count]
|
||||
table[count] = nil
|
||||
count = count - 1
|
||||
return res
|
||||
end
|
||||
dofile(modpath.."/table.lua")
|
||||
|
||||
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default", false)
|
||||
local LOG_MODULE = "[MCL2]"
|
||||
|
|
77
mods/CORE/mcl_util/table.lua
Normal file
77
mods/CORE/mcl_util/table.lua
Normal file
|
@ -0,0 +1,77 @@
|
|||
-- Updates all values in t using values from to*.
|
||||
function table.update(t, ...)
|
||||
for _, to in ipairs {...} do
|
||||
for k, v in pairs(to) do
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Updates nil values in t using values from to*.
|
||||
function table.update_nil(t, ...)
|
||||
for _, to in ipairs {...} do
|
||||
for k, v in pairs(to) do
|
||||
if t[k] == nil then
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
---Works the same as `pairs`, but order returned by keys
|
||||
---
|
||||
---Taken from https://www.lua.org/pil/19.3.html
|
||||
---@generic T: table, K, V, C
|
||||
---@param t T
|
||||
---@param f? fun(a: C, b: C):boolean
|
||||
---@return fun():K, V
|
||||
function table.pairs_by_keys(t, f)
|
||||
local a = {}
|
||||
for n in pairs(t) do table.insert(a, n) end
|
||||
table.sort(a, f)
|
||||
|
||||
local i = 0 -- iterator variable
|
||||
local function iter() -- iterator function
|
||||
i = i + 1
|
||||
if a[i] == nil then
|
||||
return nil
|
||||
else
|
||||
return a[i], t[a[i]]
|
||||
end
|
||||
end
|
||||
return iter
|
||||
end
|
||||
|
||||
---@param a table
|
||||
---@param b table
|
||||
---@return table
|
||||
function table.intersect(a, b)
|
||||
local values_map = {}
|
||||
|
||||
for _,v in pairs(a) do values_map[v] = 1 end
|
||||
|
||||
-- Get all the values that are in both tables
|
||||
local result = {}
|
||||
for _,v in pairs(b) do
|
||||
if values_map[v] then
|
||||
result[#result + 1] = v
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Removes one element randomly selected from the array section of the table and
|
||||
-- returns it, or nil if there are no elements in the array section of the table
|
||||
function table.remove_random_element(table)
|
||||
local count = #table
|
||||
if count == 0 then return nil end
|
||||
|
||||
local idx = math.random(count)
|
||||
local res = table[idx]
|
||||
table[idx] = table[count]
|
||||
table[count] = nil
|
||||
count = count - 1
|
||||
return res
|
||||
end
|
|
@ -36,13 +36,13 @@ end
|
|||
-- nil, "void"
|
||||
function mcl_worlds.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
return y - mcl_vars.mg_overworld_min, "overworld", 0
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
return y - mcl_vars.mg_nether_min, "nether", 1
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
return y - mcl_vars.mg_end_min, "end", 2
|
||||
else
|
||||
return nil, "void"
|
||||
return nil, "void", 3
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -50,8 +50,8 @@ local y_to_layer = mcl_worlds.y_to_layer
|
|||
|
||||
-- Takes a pos and returns the dimension it belongs to (same as above)
|
||||
function mcl_worlds.pos_to_dimension(pos)
|
||||
local _, dim = y_to_layer(pos.y)
|
||||
return dim
|
||||
local _, dim, dim_id = y_to_layer(pos.y)
|
||||
return dim, dim_id
|
||||
end
|
||||
|
||||
local pos_to_dimension = mcl_worlds.pos_to_dimension
|
||||
|
|
27
mods/ENTITIES/mcl_mobs/functions.lua
Normal file
27
mods/ENTITIES/mcl_mobs/functions.lua
Normal file
|
@ -0,0 +1,27 @@
|
|||
local default_seethru = {air = true}
|
||||
|
||||
---@param origin vector.Vector
|
||||
---@param target vector.Vector
|
||||
---@param seethru? {[string]: boolean} Set (look-up table) of nodes to treat as seethrough. Defaults to {air: true}
|
||||
---@return boolean True if line-of-sight is blocked, false otherwise
|
||||
function mcl_mobs.check_line_of_sight(origin, target, seethru)
|
||||
seethru = seethru or default_seethru
|
||||
local raycast = core.raycast(origin, target, false, true)
|
||||
|
||||
local los_blocked = false
|
||||
for hitpoint in raycast do
|
||||
if hitpoint.type == "node" then
|
||||
--TODO: type object could block vision, for example minecarts
|
||||
local node = core.get_node(core.get_pointed_thing_position(hitpoint))
|
||||
|
||||
if not seethru[node.name] then
|
||||
local nodef = core.registered_nodes[node.name]
|
||||
if nodef and nodef.walkable then
|
||||
los_blocked = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return not los_blocked
|
||||
end
|
|
@ -18,6 +18,7 @@ local node_ok = function(pos, fallback)
|
|||
return minetest.registered_nodes[fallback]
|
||||
end
|
||||
mcl_mobs.node_ok = node_ok
|
||||
dofile(path .. "/functions.lua")
|
||||
|
||||
--api and helpers
|
||||
-- effects: sounds and particles mostly
|
||||
|
|
|
@ -28,6 +28,7 @@ local vector_zero = vector.zero
|
|||
local vector_copy = vector.copy
|
||||
local vector_offset = vector.offset
|
||||
local vector_distance = vector.distance
|
||||
local raycast_line_of_sight = mcl_mobs.check_line_of_sight
|
||||
|
||||
local registered_fallback_node = minetest.registered_nodes[mcl_mobs.fallback_node]
|
||||
|
||||
|
@ -63,26 +64,6 @@ function mob_class:is_node_waterhazard(nodename)
|
|||
end
|
||||
|
||||
|
||||
local function raycast_line_of_sight(origin, target)
|
||||
local raycast = minetest.raycast(origin, target, false, true)
|
||||
local los_blocked = false
|
||||
for hitpoint in raycast do
|
||||
if hitpoint.type == "node" then
|
||||
--TODO type object could block vision, for example chests
|
||||
local node = minetest.get_node(minetest.get_pointed_thing_position(hitpoint))
|
||||
|
||||
if node.name ~= "air" then
|
||||
local nodef = minetest.registered_nodes[node.name]
|
||||
if nodef and nodef.walkable then
|
||||
los_blocked = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return not los_blocked
|
||||
end
|
||||
|
||||
function mob_class:target_visible(origin)
|
||||
if not origin then return end
|
||||
if not self.attack then return end
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -99,7 +99,19 @@ mcl_mobs.register_mob("mobs_mc:guardian", {
|
|||
view_range = 16,
|
||||
})
|
||||
|
||||
mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10, mobs_mc.water_level)
|
||||
mcl_mobs:spawn_specific(
|
||||
"mobs_mc:guardian", -- name
|
||||
"overworld", -- dimension
|
||||
"water", -- type_of_spawning
|
||||
{}, -- no biomes, only spawn in structures
|
||||
0, -- min_light
|
||||
core.LIGHT_MAX+1, -- max_light
|
||||
30, -- interval
|
||||
25000, -- chance
|
||||
2, -- aoc
|
||||
mcl_vars.mg_overworld_min, -- min_height
|
||||
mobs_mc.water_level - 10 -- max_height
|
||||
)
|
||||
mcl_mobs:non_spawn_specific("mobs_mc:guardian","overworld",0,minetest.LIGHT_MAX+1)
|
||||
-- spawn eggs
|
||||
mcl_mobs.register_egg("mobs_mc:guardian", S("Guardian"), "#5a8272", "#f17d31", 0)
|
||||
|
|
|
@ -112,7 +112,19 @@ mcl_mobs.register_mob("mobs_mc:guardian_elder", {
|
|||
},
|
||||
})
|
||||
|
||||
mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18, mobs_mc.water_level)
|
||||
mcl_mobs:spawn_specific(
|
||||
"mobs_mc:guardian_elder", -- name
|
||||
"overworld", -- dimension
|
||||
"water", -- type_of_spawning
|
||||
{}, -- no biomes, only spawn in structures
|
||||
0, -- min_light
|
||||
core.LIGHT_MAX+1, -- max_light
|
||||
30, -- interval
|
||||
40000, -- chance
|
||||
2, -- aoc
|
||||
mcl_vars.mg_overworld_min, -- min_height
|
||||
mobs_mc.water_level - 18 -- max_height
|
||||
)
|
||||
|
||||
-- spawn eggs
|
||||
mcl_mobs.register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "#ceccba", "#747693", 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue