From 511434a923821d9de80eaed9183b8b3e1306385d Mon Sep 17 00:00:00 2001 From: teknomunk <teknomunk@protonmail.com> Date: Mon, 6 Jan 2025 07:29:53 -0600 Subject: [PATCH] Replace compute_hash with a string.format(), move spawn_names into logging block, remove argument aliasing in get_spawn_list(), add SpawnState type annotation --- mods/ENTITIES/mcl_mobs/spawning.lua | 72 ++++++++++++++++++----------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index a1d406960..8be11552f 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -277,8 +277,6 @@ function mcl_mobs:spawn_setup(def) local chance = def.chance or 1000 local aoc = def.aoc or aoc_range - local - -- chance/spawn number override in minetest.conf for registered mob local numbers = minetest.settings:get(name) if numbers then @@ -495,10 +493,10 @@ local function is_farm_animal(n) end local function get_water_spawn(p) - local nn = minetest.find_nodes_in_area(vector.offset(p,-2,-1,-2),vector.offset(p,2,-15,2),{"group:water"}) - if nn and #nn > 0 then - return nn[math_random(#nn)] - end + local nn = minetest.find_nodes_in_area(vector.offset(p,-2,-1,-2),vector.offset(p,2,-15,2),{"group:water"}) + if nn and #nn > 0 then + return nn[math_random(#nn)] + end end --- helper to check a single node p @@ -687,6 +685,22 @@ function mcl_mobs.spawn(pos,id) return obj end +---@class mcl_mobs.SpawnState +---@field cap_space_hostile integer +---@field cap_space_passive integer +---@field spawn_hostile boolean +---@field spawn_passive boolean +---@field is_ground boolean +---@field is_grass boolean +---@field is_water boolean +---@field biome string +---@field dimension string +---@field light integer +---@field serialized string + +---@param pos vector.Vector +---@param parent_state mcl_mobs.SpawnState? +---@return mcl_mobs.SpawnState?, core.Node? local function build_state_for_position(pos, parent_state) -- Get spawning parameters for this location local biome_name = get_biome_name(pos) @@ -768,6 +782,14 @@ local function build_state_for_position(pos, parent_state) end end + -- Convert state into a format that can be used as a hash table key + state.serialized = string.format("%s:%s:d:%d:%s:%s:%s:%s:%s:%d", + state.biome, state.dimension, + state.cap_space_hostile, state.cap_space_passive, + state.spawn_hostile, state.spawn_passive, + state.is_ground, state.is_grass, state.is_water, + state.light + ) return state,node end @@ -983,24 +1005,16 @@ if mobs_spawn then end local spawn_lists = {} - local function get_spawn_list(pos, cap_space_hostile, cap_space_non_hostile) - local spawn_hostile = false - local spawn_passive = false - + local function get_spawn_list(pos, hostile_limit, passive_limit) -- Check capacity - local mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("spawn_class", pos) - local cap_space_hostile = mob_cap_space(pos, "hostile", mob_counts_close, mob_counts_wide, cap_space_hostile, cap_space_non_hostile ) - if cap_space_hostile > 0 then - spawn_hostile = true - end - local cap_space_passive = mob_cap_space(pos, "passive", mob_counts_close, mob_counts_wide, cap_space_hostile, cap_space_non_hostile ) - if cap_space_passive > 0 then - if math_random(100) < peaceful_percentage_spawned then - spawn_passive = true - end - end + local mob_counts_close, mob_counts_wide = count_mobs_all("spawn_class", pos) + local cap_space_hostile = mob_cap_space(pos, "hostile", mob_counts_close, mob_counts_wide, hostile_limit, passive_limit ) + local spawn_hostile = cap_space_hostile > 0 - -- Merge light level chcekss with cap checks + local cap_space_passive = mob_cap_space(pos, "passive", mob_counts_close, mob_counts_wide, hostile_limit, passive_limit ) + local spawn_passive = cap_space_passive > 0 and math_random(100) < peaceful_percentage_spawned + + -- Merge light level checks with cap checks local state, node = build_state_for_position(pos) if not state then return end state.spawn_hostile = spawn_hostile and state.spawn_hostile @@ -1010,7 +1024,7 @@ if mobs_spawn then if not state.spawn_hostile and not state.spawn_passive then return end -- Check the cache to see if we have already built a spawn list for this state - local state_hash = compute_hash(state) -- from mcl_enchanting + local state_hash = state.serialized local spawn_list = spawn_lists[state_hash] state.cap_space_hostile = cap_space_hostile state.cap_space_passive = cap_space_passive @@ -1020,16 +1034,21 @@ if mobs_spawn then -- Build a spawn list for this state spawn_list = {} - local spawn_names = {} for _,def in pairs(spawn_dictionary) do if initial_spawn_check(state, node, def) then spawn_list[#spawn_list + 1] = def - spawn_names[#spawn_names + 1] = def.name end end if logging then - minetest.log(dump({ + local spawn_names = {} + for _,def in pairs(spawn_dictionary) do + if initial_spawn_check(state, node, def) then + spawn_names[#spawn_names + 1] = def.name + end + end + + core.log(dump({ pos = pos, node = node, state = state, @@ -1093,7 +1112,6 @@ if mobs_spawn then --everything is correct, spawn mob local spawn_in_group = mob_def_ent.spawn_in_group or 4 - local spawned if spawn_in_group then local group_min = mob_def_ent.spawn_in_group_min or 1 if not group_min then group_min = 1 end