From 429984937cbf05e7c263968c3249d700a419048f Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 07:10:25 +0400 Subject: [PATCH 01/15] Fix several minor mob issues --- mods/ENTITIES/extra_mobs/fox.lua | 60 +- mods/ENTITIES/extra_mobs/strider.lua | 44 +- .../api/mob_functions/environment.lua | 20 - .../mcl_mobs/api/mob_functions/set_up.lua | 22 +- mods/ENTITIES/mcl_mobs/api/spawning.lua | 885 +++++++----------- mods/ENTITIES/mobs_mc/zombie.lua | 333 +++---- mods/MAPGEN/mcl_villages/init.lua | 3 +- 7 files changed, 516 insertions(+), 851 deletions(-) diff --git a/mods/ENTITIES/extra_mobs/fox.lua b/mods/ENTITIES/extra_mobs/fox.lua index 7df04b554..10f9ca898 100644 --- a/mods/ENTITIES/extra_mobs/fox.lua +++ b/mods/ENTITIES/extra_mobs/fox.lua @@ -18,12 +18,7 @@ local S = minetest.get_translator("extra_mobs") --################### fox --################### -local followitem = "" -if minetest.get_modpath("mc_sweet_berry") then - followitem = "mc_sweet_berry:sweet_berry" -else - followitem = nil -end +local followitem = "mcl_farming:sweet_berry" local fox = { type = "monster", @@ -123,35 +118,30 @@ local fox = { mobs:register_mob("extra_mobs:fox", fox) -- spawning -mobs:spawn_specific( -"extra_mobs:fox", -"overworld", -"ground", -{ -"FlowerForest", -"Swampland", -"Taiga", -"ExtremeHills", -"BirchForest", -"MegaSpruceTaiga", -"MegaTaiga", -"ExtremeHills+", -"Forest", -"Plains", -"ColdTaiga", -"SunflowerPlains", -"RoofedForest", -"MesaPlateauFM_grasstop", -"ExtremeHillsM", -"BirchForestM", -}, -0, -minetest.LIGHT_MAX+1, -30, -6000, -3, -mobs_mc.spawn_height.water, -mobs_mc.spawn_height.overworld_max) +mobs:spawn_setup({ + name = "extra_mobs:fox", + biomes = { + "FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "ColdTaiga", + "SunflowerPlains", + "RoofedForest", + "MesaPlateauFM_grasstop", + "ExtremeHillsM", + "BirchForestM", + }, + interval = 30, + chance = 6000, + min_height = mobs_mc.spawn_height.water, +}) --mobs:spawn_specific("extra_mobs:fox", "overworld", "ground", 0, minetest.LIGHT_MAX+1, 30, 6000, 3, 0, 500) --[[ diff --git a/mods/ENTITIES/extra_mobs/strider.lua b/mods/ENTITIES/extra_mobs/strider.lua index d6c854207..bc86379cd 100644 --- a/mods/ENTITIES/extra_mobs/strider.lua +++ b/mods/ENTITIES/extra_mobs/strider.lua @@ -213,20 +213,36 @@ baby_strider.child = 1 mobs:register_mob("extra_mobs:baby_strider", baby_strider) -- Regular spawning in the Nether -mobs:spawn_specific( -"extra_mobs:strider", -"nether", -"lava", -{ -"Nether" -}, -0, -minetest.LIGHT_MAX+1, -30, -6000, -3, -mobs_mc.spawn_height.nether_min, -mobs_mc.spawn_height.nether_max) + +mobs:spawn_setup({ + name = "extra_mobs:strider", + type_of_spawning = "lava", + dimension = "nether", + biomes = { + "Nether" + }, + min_height = mcl_mapgen.nether.min, + max_height = mcl_mapgen.nether.max, + chance = 2000, + check_position = function(pos) + return minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}).name:find("lava") + end +}) + +mobs:spawn_setup({ + name = "extra_mobs:baby_strider", + type_of_spawning = "lava", + dimension = "nether", + biomes = { + "Nether" + }, + min_height = mcl_mapgen.nether.min, + max_height = mcl_mapgen.nether.max, + chance = 100, + check_position = function(pos) + return minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}).name:find("lava") + end +}) -- spawn eggs mobs:register_egg("extra_mobs:strider", S("Strider"), "extra_mobs_spawn_icon_strider.png", 0) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua index c7fb073b0..22013e35e 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua @@ -211,26 +211,6 @@ mobs.teleport = function(self, target) end end ---a function used for despawning mobs -mobs.check_for_player_within_area = function(self, radius) - local pos1 = self.object:get_pos() - if not pos1 then return end - --get players in radius - for _,player in pairs(minetest_get_connected_players()) do - if player and player:get_hp() > 0 then - local pos2 = player:get_pos() - local distance = vector_distance(pos1,pos2) - if distance < radius then - --found a player - return true - end - end - end - --did not find a player - return false -end - - --a simple helper function for mobs following mobs.get_2d_distance = function(pos1,pos2) pos1.y = 0 diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua index b9cf2f669..a0467f4d2 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua @@ -5,9 +5,27 @@ local minetest_settings = minetest.settings -- CMI support check local use_cmi = minetest.global_exists("cmi") +local vector_distance = vector.distance +local minetest_get_connected_players = minetest.get_connected_players +local math_random = math.random + mobs.can_despawn = function(self) - return (not self.tamed and not self.bred and not self.nametag and - not mobs.check_for_player_within_area(self, 64)); + if self.tamed or self.bred or self.nametag then return false end + local mob_pos = self.object:get_pos() + if not mob_pos then return true end + local distance = 999 + for _, player in pairs(minetest_get_connected_players()) do + if player and player:get_hp() > 0 then + local player_pos = player:get_pos() + local new_distance = vector_distance(player_pos, mob_pos) + if new_distance < distance then + distance = new_distance + if distance < 33 then return false end + if distance < 128 and math_random(1, 200) == 19 then return true end + end + end + end + return true end -- get entity staticdata diff --git a/mods/ENTITIES/mcl_mobs/api/spawning.lua b/mods/ENTITIES/mcl_mobs/api/spawning.lua index bf07ca94d..2fcc83baf 100644 --- a/mods/ENTITIES/mcl_mobs/api/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/api/spawning.lua @@ -6,11 +6,14 @@ local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air local get_biome_name = minetest.get_biome_name local get_objects_inside_radius = minetest.get_objects_inside_radius local get_connected_players = minetest.get_connected_players - +local minetest_get_perlin = minetest.get_perlin local math_random = math.random local math_floor = math.floor ---local max = math.max +local math_ceil = math.ceil +local math_cos = math.cos +local math_sin = math.sin +local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end --local vector_distance = vector.distance local vector_new = vector.new @@ -22,151 +25,171 @@ local table_remove = table.remove local pairs = pairs -- range for mob count -local aoc_range = 48 +local aoc_range = 32 --do mobs spawn? local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false ---[[ -THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs +local noise_params = { + offset = 0, + scale = 3, + spread = { + x = 301, + y = 50, + z = 304, + }, + seed = 100, + octaves = 3, + persistence = 0.5, +} -underground: -"FlowerForest_underground", -"JungleEdge_underground",local spawning_position = spawning_position_list[math.random(1,#spawning_position_list)] -"ColdTaiga_underground", -"IcePlains_underground", -"IcePlainsSpikes_underground", -"MegaTaiga_underground", -"Taiga_underground", -"ExtremeHills+_underground", -"JungleM_underground", -"ExtremeHillsM_underground", -"JungleEdgeM_underground", +-- THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs +-- Also used for missing parameter +-- Please update the list when adding new biomes! -ocean: -"RoofedForest_ocean", -"JungleEdgeM_ocean", -"BirchForestM_ocean", -"BirchForest_ocean", -"IcePlains_deep_ocean", -"Jungle_deep_ocean", -"Savanna_ocean", -"MesaPlateauF_ocean", -"ExtremeHillsM_deep_ocean", -"Savanna_deep_ocean", -"SunflowerPlains_ocean", -"Swampland_deep_ocean", -"Swampland_ocean", -"MegaSpruceTaiga_deep_ocean", -"ExtremeHillsM_ocean", -"JungleEdgeM_deep_ocean", -"SunflowerPlains_deep_ocean", -"BirchForest_deep_ocean", -"IcePlainsSpikes_ocean", -"Mesa_ocean", -"StoneBeach_ocean", -"Plains_deep_ocean", -"JungleEdge_deep_ocean", -"SavannaM_deep_ocean", -"Desert_deep_ocean", -"Mesa_deep_ocean", -"ColdTaiga_deep_ocean", -"Plains_ocean", -"MesaPlateauFM_ocean", -"Forest_deep_ocean", -"JungleM_deep_ocean", -"FlowerForest_deep_ocean", -"MushroomIsland_ocean", -"MegaTaiga_ocean", -"StoneBeach_deep_ocean", -"IcePlainsSpikes_deep_ocean", -"ColdTaiga_ocean", -"SavannaM_ocean", -"MesaPlateauF_deep_ocean", -"MesaBryce_deep_ocean", -"ExtremeHills+_deep_ocean", -"ExtremeHills_ocean", -"MushroomIsland_deep_ocean", -"Forest_ocean", -"MegaTaiga_deep_ocean", -"JungleEdge_ocean", -"MesaBryce_ocean", -"MegaSpruceTaiga_ocean", -"ExtremeHills+_ocean", -"Jungle_ocean", -"RoofedForest_deep_ocean", -"IcePlains_ocean", -"FlowerForest_ocean", -"ExtremeHills_deep_ocean", -"MesaPlateauFM_deep_ocean", -"Desert_ocean", -"Taiga_ocean", -"BirchForestM_deep_ocean", -"Taiga_deep_ocean", -"JungleM_ocean", +local list_of_all_biomes = { -water or beach? -"MesaPlateauFM_sandlevel", -"MesaPlateauF_sandlevel", -"MesaBryce_sandlevel", -"Mesa_sandlevel", + -- underground: -beach: -"FlowerForest_beach", -"Forest_beach", -"StoneBeach", -"ColdTaiga_beach_water", -"Taiga_beach", -"Savanna_beach", -"Plains_beach", -"ExtremeHills_beach", -"ColdTaiga_beach", -"Swampland_shore", -"MushroomIslandShore", -"JungleM_shore", -"Jungle_shore", + "FlowerForest_underground", + "JungleEdge_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", -dimension biome: -"Nether", -"End", + -- ocean: -Overworld regular: -"Mesa", -"FlowerForest", -"Swampland", -"Taiga", -"ExtremeHills", -"Jungle", -"Savanna", -"BirchForest", -"MegaSpruceTaiga", -"MegaTaiga", -"ExtremeHills+", -"Forest", -"Plains", -"Desert", -"ColdTaiga", -"MushroomIsland", -"IcePlainsSpikes", -"SunflowerPlains", -"IcePlains", -"RoofedForest", -"ExtremeHills+_snowtop", -"MesaPlateauFM_grasstop", -"JungleEdgeM", -"ExtremeHillsM", -"JungleM", -"BirchForestM", -"MesaPlateauF", -"MesaPlateauFM", -"MesaPlateauF_grasstop", -"MesaBryce", -"JungleEdge", -"SavannaM", -]]-- + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean", + -- water or beach? + "MesaPlateauFM_sandlevel", + "MesaPlateauF_sandlevel", + "MesaBryce_sandlevel", + "Mesa_sandlevel", + + -- beach: + + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore", + + -- dimension biome: + + "Nether", + "End", + + -- Overworld regular: + + "Mesa", + "FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "Jungle", + "Savanna", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "Desert", + "ColdTaiga", + "MushroomIsland", + "IcePlainsSpikes", + "SunflowerPlains", + "IcePlains", + "RoofedForest", + "ExtremeHills+_snowtop", + "MesaPlateauFM_grasstop", + "JungleEdgeM", + "ExtremeHillsM", + "JungleM", + "BirchForestM", + "MesaPlateauF", + "MesaPlateauFM", + "MesaPlateauF_grasstop", + "MesaBryce", + "JungleEdge", + "SavannaM", +} -- count how many mobs are in an area local function count_mobs(pos) @@ -216,11 +239,74 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? --this is where all of the spawning information is kept local spawn_dictionary = {} +local summary_chance = 0 + +function mobs:spawn_setup(def) + if not mobs_spawn then return end + + if not def then + minetest.log("warning", "Empty mob spawn setup definition") + return + end + + local name = def.name + if not name then + minetest.log("warning", "Missing mob name") + return + end + + local dimension = def.dimension or "overworld" + local type_of_spawning = def.type_of_spawning or "ground" + local biomes = def.biomes or list_of_all_biomes + local min_light = def.min_light or 0 + local max_light = def.max_light or (minetest.LIGHT_MAX + 1) + local chance = def.chance or 1000 + local aoc = def.aoc or aoc_range + local min_height = def.min_height or mcl_mapgen.overworld.min + local max_height = def.max_height or mcl_mapgen.overworld.max + local day_toggle = def.day_toggle + local on_spawn = def.on_spawn + local check_position = def.check_position + + -- chance/spawn number override in minetest.conf for registered mob + local numbers = minetest.settings:get(name) + if numbers then + numbers = numbers:split(",") + chance = tonumber(numbers[1]) or chance + aoc = tonumber(numbers[2]) or aoc + if chance == 0 then + minetest.log("warning", string.format("[mobs] %s has spawning disabled", name)) + return + end + minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) + end + + if chance < 1 then + chance = 1 + minetest.log("warning", "Chance shouldn't be less than 1 (mob name: " .. name ..")") + end + + spawn_dictionary[#spawn_dictionary + 1] = { + name = name, + dimension = dimension, + type_of_spawning = type_of_spawning, + biomes = biomes, + min_light = min_light, + max_light = max_light, + chance = chance, + aoc = aoc, + min_height = min_height, + max_height = max_height, + day_toggle = day_toggle, + check_position = check_position, + on_spawn = on_spawn, + } + summary_chance = summary_chance + chance + minetest.log("warning", minetest.serialize(spawn_dictionary)) +end function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) - --print(dump(biomes)) - -- Do mobs spawn at all? if not mobs_spawn then return @@ -239,179 +325,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh return end - minetest.log("action", - string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) - end - - --[[ - local function spawn_action(pos, node, active_object_count, active_object_count_wider, name) - - local orig_pos = table.copy(pos) - -- is mob actually registered? - if not mobs.spawning_mobs[name] - or not minetest.registered_entities[name] then - minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!") - return - end - - -- additional custom checks for spawning mob - if mobs:spawn_abm_check(pos, node, name) == true then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!") - return - end - - -- count nearby mobs in same spawn class - local entdef = minetest.registered_entities[name] - local spawn_class = entdef and entdef.spawn_class - if not spawn_class then - if entdef.type == "monster" then - spawn_class = "hostile" - else - spawn_class = "passive" - end - end - local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class] - -- do not spawn if too many of same mob in area - if active_object_count_wider >= max_per_block -- large-range mob cap - or (not in_class_cap) -- spawn class mob cap - or count_mobs(pos, name) >= aoc then -- per-mob mob cap - -- too many entities - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!") - return - end - - -- if toggle set to nil then ignore day/night check - if day_toggle then - - local tod = (minetest.get_timeofday() or 0) * 24000 - - if tod > 4500 and tod < 19500 then - -- daylight, but mob wants night - if day_toggle == false then - -- mob needs night - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!") - return - end - else - -- night time but mob wants day - if day_toggle == true then - -- mob needs day - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!") - return - end - end - end - - -- spawn above node - pos.y = pos.y + 1 - - -- only spawn away from player - local objs = minetest.get_objects_inside_radius(pos, 24) - - for n = 1, #objs do - - if objs[n]:is_player() then - -- player too close - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!") - return - end - end - - -- mobs cannot spawn in protected areas when enabled - if not spawn_protected - and minetest.is_protected(pos, "") then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!") - return - end - - -- are we spawning within height limits? - if pos.y > max_height - or pos.y < min_height then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!") - return - end - - -- are light levels ok? - local light = minetest.get_node_light(pos) - if not light - or light > max_light - or light < min_light then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!") - return - end - - -- do we have enough space to spawn mob? - local ent = minetest.registered_entities[name] - local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1])) - local min_x, max_x - if width_x % 2 == 0 then - max_x = math.floor(width_x/2) - min_x = -(max_x-1) - else - max_x = math.floor(width_x/2) - min_x = -max_x - end - - local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3])) - local min_z, max_z - if width_z % 2 == 0 then - max_z = math.floor(width_z/2) - min_z = -(max_z-1) - else - max_z = math.floor(width_z/2) - min_z = -max_z - end - - local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1) - - for y = 0, max_y do - for x = min_x, max_x do - for z = min_z, max_z do - local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z} - if minetest.registered_nodes[node_ok(pos2).name].walkable == true then - -- inside block - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!") - if ent.spawn_small_alternative and (not minetest.registered_nodes[node_ok(pos).name].walkable) then - minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative) - spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative) - end - return - end - end - end - end - - -- tweak X/Y/Z spawn pos - if width_x % 2 == 0 then - pos.x = pos.x + 0.5 - end - if width_z % 2 == 0 then - pos.z = pos.z + 0.5 - end - pos.y = pos.y - 0.5 - - local mob = minetest.add_entity(pos, name) - minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos)) - - if on_spawn then - - local ent = mob:get_luaentity() - - on_spawn(ent, pos) - end - end - - local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider) - spawn_action(pos, node, active_object_count, active_object_count_wider, name) - end - ]]-- - - local entdef = minetest.registered_entities[name] - local spawn_class - if entdef.type == "monster" then - spawn_class = "hostile" - else - spawn_class = "passive" + minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) end --load information into the spawn dictionary @@ -423,107 +337,34 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh spawn_dictionary[key]["biomes"] = biomes spawn_dictionary[key]["min_light"] = min_light spawn_dictionary[key]["max_light"] = max_light - spawn_dictionary[key]["interval"] = interval spawn_dictionary[key]["chance"] = chance spawn_dictionary[key]["aoc"] = aoc spawn_dictionary[key]["min_height"] = min_height spawn_dictionary[key]["max_height"] = max_height spawn_dictionary[key]["day_toggle"] = day_toggle - --spawn_dictionary[key]["on_spawn"] = spawn_abm_action - spawn_dictionary[key]["spawn_class"] = spawn_class - --[[ - minetest.register_abm({ - label = name .. " spawning", - nodenames = nodes, - neighbors = neighbors, - interval = interval, - chance = floor(max(1, chance * mobs_spawn_chance)), - catch_up = false, - action = spawn_abm_action, - }) - ]]-- + summary_chance = summary_chance + chance end --- compatibility with older mob registration --- we're going to forget about this for now -j4i ---[[ -function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) - - mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, - chance, active_object_count, -31000, max_height, day_toggle) +local two_pi = 2 * math.pi +local function get_next_mob_spawn_pos(pos) + local distance = math_random(25, 32) + local angle = math_random() * two_pi + return { + x = math_round(pos.x + distance * math_cos(angle)), + y = pos.y, + z = math_round(pos.z + distance * math_sin(angle)) + } end -]]-- - - ---Don't disable this yet-j4i --- MarkBu's spawn function - -function mobs:spawn(def) - --does nothing for now - --[[ - local name = def.name - local nodes = def.nodes or {"group:soil", "group:stone"} - local neighbors = def.neighbors or {"air"} - local min_light = def.min_light or 0 - local max_light = def.max_light or 15 - local interval = def.interval or 30 - local chance = def.chance or 5000 - local active_object_count = def.active_object_count or 1 - local min_height = def.min_height or -31000 - local max_height = def.max_height or 31000 - local day_toggle = def.day_toggle - local on_spawn = def.on_spawn - - mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) - ]]-- -end - - - -local axis ---inner and outer part of square donut radius -local inner = 15 -local outer = 64 -local int = {-1,1} - -local function position_calculation(pos) - - pos = vector_floor(pos) - - --this is used to determine the axis buffer from the player - axis = math_random(0,1) - - --cast towards the direction - if axis == 0 then --x - pos.x = pos.x + math_random(inner,outer)*int[math_random(1,2)] - pos.z = pos.z + math_random(-outer,outer) - else --z - pos.z = pos.z + math_random(inner,outer)*int[math_random(1,2)] - pos.x = pos.x + math_random(-outer,outer) - end - return pos -end - ---[[ -local decypher_limits_dictionary = { - ["overworld"] = {mcl_vars.mg_overworld_min,mcl_vars.mg_overworld_max}, - ["nether"] = {mcl_vars.mg_nether_min, mcl_vars.mg_nether_max}, - ["end"] = {mcl_vars.mg_end_min, mcl_vars.mg_end_max} -} -]]-- local function decypher_limits(posy) - --local min_max_table = decypher_limits_dictionary[dimension] - --return min_max_table[1],min_max_table[2] posy = math_floor(posy) return posy - 32, posy + 32 end --a simple helper function for mob_spawn local function biome_check(biome_list, biome_goal) - for _,data in ipairs(biome_list) do + for _, data in pairs(biome_list) do if data == biome_goal then return true end @@ -533,176 +374,102 @@ local function biome_check(biome_list, biome_goal) end ---todo mob limiting ---MAIN LOOP - if mobs_spawn then + + local perlin_noise + + local function spawn_a_mob(pos, dimension, y_min, y_max) + local dimension = dimension or mcl_worlds.pos_to_dimension(pos) + local goal_pos = get_next_mob_spawn_pos(pos) + local spawning_position_list = find_nodes_in_area_under_air( + {x = goal_pos.x, y = y_min, z = goal_pos.z}, + {x = goal_pos.x, y = y_max, z = goal_pos.z}, + {"group:solid", "group:water", "group:lava"} + ) + if #spawning_position_list <= 0 then return end + local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)] + + --hard code mob limit in area to 7 for now + if count_mobs(spawning_position) >= 7 then return end + + local gotten_node = get_node(spawning_position).name + local gotten_biome = minetest.get_biome_data(spawning_position) + if not gotten_node or not gotten_biome then return end + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + + --add this so mobs don't spawn inside nodes + spawning_position.y = spawning_position.y + 1 + + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(spawning_position) + + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 + local is_ground = not (is_water or is_lava) + if not is_ground then + spawning_position.y = spawning_position.y - 1 + end + + local mob_def + + --create a disconnected clone of the spawn dictionary + --prevents memory leak + local mob_library_worker_table = table_copy(spawn_dictionary) + + --grab mob that fits into the spawning location + --randomly grab a mob, don't exclude any possibilities + perlin_noise = perlin_noise or minetest_get_perlin(noise_params) + local noise = perlin_noise:get_3d(spawning_position) + local current_summary_chance = summary_chance + while #mob_library_worker_table > 0 do + local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1 + local mob_index = 1 + local mob_chance = mob_library_worker_table[mob_index].chance + local step_chance = mob_chance + while step_chance < mob_chance_offset do + mob_index = mob_index + 1 + mob_chance = mob_library_worker_table[mob_index].chance + step_chance = step_chance + mob_chance + end + local mob_def = mob_library_worker_table[mob_index] + if mob_def + and spawning_position.y >= mob_def.min_height + and spawning_position.y <= mob_def.max_height + and mob_def.dimension == dimension + and biome_check(mob_def.biomes, gotten_biome) + and gotten_light >= mob_def.min_light + and gotten_light <= mob_def.max_light + and (is_ground or mob_def.type_of_spawning ~= "ground") + and (mob_def.check_position and mob_def.check_position(spawning_position) or true) + then + --everything is correct, spawn mob + local object = minetest.add_entity(spawning_position, mob_def.name) + if object then + return mob_def.on_spawn and mob_def.on_spawn(object, pos) + end + end + current_summary_chance = current_summary_chance - mob_chance + table_remove(mob_library_worker_table, mob_index) + end + end + + + --MAIN LOOP + local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime - if timer >= 10 then - timer = 0 - for _,player in pairs(get_connected_players()) do - -- after this line each "break" means "continue" - local do_mob_spawning = true - repeat - --don't need to get these variables more than once - --they happen in a single server step - - local player_pos = player:get_pos() - local dimension = mcl_worlds.pos_to_dimension(player_pos) - - if dimension == "void" or dimension == "default" then - break -- ignore void and unloaded area - end - - local min, max = decypher_limits(player_pos.y) - - for i = 1, math_random(1,4) do - -- after this line each "break" means "continue" - local do_mob_algorithm = true - repeat - - local goal_pos = position_calculation(player_pos) - - local spawning_position_list = find_nodes_in_area_under_air(vector_new(goal_pos.x,min,goal_pos.z), vector_new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) - - --couldn't find node - if #spawning_position_list <= 0 then - break - end - - local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] - - --Prevent strange behavior --- this is commented out: /too close to player --fixed with inner circle - if not spawning_position then -- or vector_distance(player_pos, spawning_position) < 15 - break - end - - --hard code mob limit in area to 5 for now - if count_mobs(spawning_position) >= 5 then - break - end - - local gotten_node = get_node(spawning_position).name - - if not gotten_node or gotten_node == "air" then --skip air nodes - break - end - - local gotten_biome = minetest.get_biome_data(spawning_position) - - if not gotten_biome then - break --skip if in unloaded area - end - - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - - --add this so mobs don't spawn inside nodes - spawning_position.y = spawning_position.y + 1 - - --only need to poll for node light if everything else worked - local gotten_light = get_node_light(spawning_position) - - local is_water = get_item_group(gotten_node, "water") ~= 0 - local is_lava = get_item_group(gotten_node, "lava") ~= 0 - - local mob_def = nil - - --create a disconnected clone of the spawn dictionary - --prevents memory leak - local mob_library_worker_table = table_copy(spawn_dictionary) - - --grab mob that fits into the spawning location - --randomly grab a mob, don't exclude any possibilities - local repeat_mob_search = true - repeat - - --do not infinite loop - if #mob_library_worker_table <= 0 then - --print("breaking infinite loop") - break - end - - local skip = false - - --use this for removing table elements of mobs that do not match - local temp_index = math_random(1,#mob_library_worker_table) - - local temp_def = mob_library_worker_table[temp_index] - - --skip if something ridiculous happens (nil mob def) - --something truly horrible has happened if skip gets - --activated at this point - if not temp_def then - skip = true - end - - if not skip and (spawning_position.y < temp_def.min_height or spawning_position.y > temp_def.max_height) then - skip = true - end - - --skip if not correct dimension - if not skip and (temp_def.dimension ~= dimension) then - skip = true - end - - --skip if not in correct biome - if not skip and (not biome_check(temp_def.biomes, gotten_biome)) then - skip = true - end - - --don't spawn if not in light limits - if not skip and (gotten_light < temp_def.min_light or gotten_light > temp_def.max_light) then - skip = true - end - - --skip if not in correct spawning type - if not skip and (temp_def.type_of_spawning == "ground" and is_water) then - skip = true - end - - if not skip and (temp_def.type_of_spawning == "ground" and is_lava) then - skip = true - end - - --found a mob, exit out of loop - if not skip then - --minetest.log("warning", "found mob:"..temp_def.name) - --print("found mob:"..temp_def.name) - mob_def = table_copy(temp_def) - break - else - --minetest.log("warning", "deleting temp index "..temp_index) - --print("deleting temp index") - table_remove(mob_library_worker_table, temp_index) - end - - until repeat_mob_search == false --this is needed to sort through mobs randomly - - - --catch if went through all mobs and something went horribly wrong - --could not find a valid mob to spawn that fits the environment - if not mob_def then - break - end - - --adjust the position for water and lava mobs - if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then - spawning_position.y = spawning_position.y - 1 - end - - --print("spawning: " .. mob_def.name) - - --everything is correct, spawn mob - minetest.add_entity(spawning_position, mob_def.name) - - break - until do_mob_algorithm == false --this is a safety catch - end - - break - until do_mob_spawning == false --this is a performance catch + if timer < 10 then return end + timer = 0 + for _, player in pairs(get_connected_players()) do + local pos = player:get_pos() + local dimension = mcl_worlds.pos_to_dimension(pos) + -- ignore void and unloaded area + if dimension ~= "void" and dimension ~= "default" then + local y_min, y_max = decypher_limits(pos.y) + for i = 1, math_random(1, 4) do + spawn_a_mob(pos, dimension, y_min, y_max) + end end end end) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index e1247d8bd..3eb0122a7 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -9,6 +9,95 @@ local S = minetest.get_translator(minetest.get_current_modname()) --################### ZOMBIE --################### +local husk_biomes = { + "Desert", + "SavannaM", + "Savanna", + "Savanna_beach", +} + +local zombie_biomes = { + "FlowerForest_underground", + "JungleEdge_underground", + "StoneBeach_underground", + "MesaBryce_underground", + "Mesa_underground", + "RoofedForest_underground", + "Jungle_underground", + "Swampland_underground", + "MushroomIsland_underground", + "BirchForest_underground", + "Plains_underground", + "MesaPlateauF_underground", + "ExtremeHills_underground", + "MegaSpruceTaiga_underground", + "BirchForestM_underground", + "SavannaM_underground", + "MesaPlateauFM_underground", + "Desert_underground", + "Savanna_underground", + "Forest_underground", + "SunflowerPlains_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", + "Mesa", + "FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "Jungle", + "Savanna", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "Desert", + "ColdTaiga", + "MushroomIsland", + "IcePlainsSpikes", + "SunflowerPlains", + "IcePlains", + "RoofedForest", + "ExtremeHills+_snowtop", + "MesaPlateauFM_grasstop", + "JungleEdgeM", + "ExtremeHillsM", + "JungleM", + "BirchForestM", + "MesaPlateauF", + "MesaPlateauFM", + "MesaPlateauF_grasstop", + "MesaBryce", + "JungleEdge", + "SavannaM", + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore", + "MesaPlateauFM_sandlevel", + "MesaPlateauF_sandlevel", + "MesaBryce_sandlevel", + "Mesa_sandlevel", +} + local drops_common = { {name = mobs_mc.items.rotten_flesh, chance = 1, @@ -166,230 +255,36 @@ baby_husk.child = 1 mobs:register_mob("mobs_mc:baby_husk", baby_husk) - -- Spawning -mobs:spawn_specific( -"mobs_mc:zombie", -"overworld", -"ground", -{ -"FlowerForest_underground", -"JungleEdge_underground", -"StoneBeach_underground", -"MesaBryce_underground", -"Mesa_underground", -"RoofedForest_underground", -"Jungle_underground", -"Swampland_underground", -"MushroomIsland_underground", -"BirchForest_underground", -"Plains_underground", -"MesaPlateauF_underground", -"ExtremeHills_underground", -"MegaSpruceTaiga_underground", -"BirchForestM_underground", -"SavannaM_underground", -"MesaPlateauFM_underground", -"Desert_underground", -"Savanna_underground", -"Forest_underground", -"SunflowerPlains_underground", -"ColdTaiga_underground", -"IcePlains_underground", -"IcePlainsSpikes_underground", -"MegaTaiga_underground", -"Taiga_underground", -"ExtremeHills+_underground", -"JungleM_underground", -"ExtremeHillsM_underground", -"JungleEdgeM_underground", -"Mesa", -"FlowerForest", -"Swampland", -"Taiga", -"ExtremeHills", -"Jungle", -"Savanna", -"BirchForest", -"MegaSpruceTaiga", -"MegaTaiga", -"ExtremeHills+", -"Forest", -"Plains", -"Desert", -"ColdTaiga", -"MushroomIsland", -"IcePlainsSpikes", -"SunflowerPlains", -"IcePlains", -"RoofedForest", -"ExtremeHills+_snowtop", -"MesaPlateauFM_grasstop", -"JungleEdgeM", -"ExtremeHillsM", -"JungleM", -"BirchForestM", -"MesaPlateauF", -"MesaPlateauFM", -"MesaPlateauF_grasstop", -"MesaBryce", -"JungleEdge", -"SavannaM", -"FlowerForest_beach", -"Forest_beach", -"StoneBeach", -"ColdTaiga_beach_water", -"Taiga_beach", -"Savanna_beach", -"Plains_beach", -"ExtremeHills_beach", -"ColdTaiga_beach", -"Swampland_shore", -"MushroomIslandShore", -"JungleM_shore", -"Jungle_shore", -"MesaPlateauFM_sandlevel", -"MesaPlateauF_sandlevel", -"MesaBryce_sandlevel", -"Mesa_sandlevel", -}, -0, -7, -30, -6000, -4, -mobs_mc.spawn_height.overworld_min, -mobs_mc.spawn_height.overworld_max) +mobs:spawn_setup({ + name = "mobs_mc:zombie", + biomes = zombie_biomes, + max_light = 7, + chance = 2000, +}) + -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific( -"mobs_mc:baby_zombie", -"overworld", -"ground", -{ -"FlowerForest_underground", -"JungleEdge_underground", -"StoneBeach_underground", -"MesaBryce_underground", -"Mesa_underground", -"RoofedForest_underground", -"Jungle_underground", -"Swampland_underground", -"MushroomIsland_underground", -"BirchForest_underground", -"Plains_underground", -"MesaPlateauF_underground", -"ExtremeHills_underground", -"MegaSpruceTaiga_underground", -"BirchForestM_underground", -"SavannaM_underground", -"MesaPlateauFM_underground", -"Desert_underground", -"Savanna_underground", -"Forest_underground", -"SunflowerPlains_underground", -"ColdTaiga_underground", -"IcePlains_underground", -"IcePlainsSpikes_underground", -"MegaTaiga_underground", -"Taiga_underground", -"ExtremeHills+_underground", -"JungleM_underground", -"ExtremeHillsM_underground", -"JungleEdgeM_underground", -"Mesa", -"FlowerForest", -"Swampland", -"Taiga", -"ExtremeHills", -"Jungle", -"Savanna", -"BirchForest", -"MegaSpruceTaiga", -"MegaTaiga", -"ExtremeHills+", -"Forest", -"Plains", -"Desert", -"ColdTaiga", -"MushroomIsland", -"IcePlainsSpikes", -"SunflowerPlains", -"IcePlains", -"RoofedForest", -"ExtremeHills+_snowtop", -"MesaPlateauFM_grasstop", -"JungleEdgeM", -"ExtremeHillsM", -"JungleM", -"BirchForestM", -"MesaPlateauF", -"MesaPlateauFM", -"MesaPlateauF_grasstop", -"MesaBryce", -"JungleEdge", -"SavannaM", -"FlowerForest_beach", -"Forest_beach", -"StoneBeach", -"ColdTaiga_beach_water", -"Taiga_beach", -"Savanna_beach", -"Plains_beach", -"ExtremeHills_beach", -"ColdTaiga_beach", -"Swampland_shore", -"MushroomIslandShore", -"JungleM_shore", -"Jungle_shore", -"MesaPlateauFM_sandlevel", -"MesaPlateauF_sandlevel", -"MesaBryce_sandlevel", -"Mesa_sandlevel", -}, -0, -7, -30, -60000, -4, -mobs_mc.spawn_height.overworld_min, -mobs_mc.spawn_height.overworld_max) +mobs:spawn_setup({ + name = "mobs_mc:baby_zombie", + biomes = zombie_biomes, + max_lignt = 7, + chance = 100, +}) +mobs:spawn_setup({ + name = "mobs_mc:husk", + biomes = husk_biomes, + max_light = 7, + chance = 2000, +}) -mobs:spawn_specific( -"mobs_mc:husk", -"overworld", -"ground", -{ -"Desert", -"SavannaM", -"Savanna", -"Savanna_beach", -}, -0, -7, -30, -6500, -4, -mobs_mc.spawn_height.overworld_min, -mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific( -"mobs_mc:baby_husk", -"overworld", -"ground", -{ -"Desert", -"SavannaM", -"Savanna", -"Savanna_beach", -}, -0, -7, -30, -65000, -4, -mobs_mc.spawn_height.overworld_min, -mobs_mc.spawn_height.overworld_max) +mobs:spawn_setup({ + name = "mobs_mc:baby_husk", + biomes = husk_biomes, + max_light = 7, + chance = 100, +}) -- Spawn eggs mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index e837ab027..37052a9b6 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -436,8 +436,7 @@ local function build_a_village(minp, maxp, pr, placer) end -- Disable natural generation in singlenode. -if mg_name ~= "singlenode" then - local mg_name = minetest.get_mapgen_setting("mg_name") +if not mcl_mapgen.singlenode then local scan_last_node = mcl_mapgen.LAST_BLOCK * mcl_mapgen.BS - 1 local scan_offset = mcl_mapgen.BS mcl_mapgen.register_mapgen(function(minp, maxp, chunkseed) From 60693b2d01e1d2a2aad3542302a5582fc51d380a Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 07:25:02 +0400 Subject: [PATCH 02/15] #249 Switch whirlpools/bubble columns directly --- mods/ITEMS/mcl_core/nodes_liquid.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 75314cf9f..47913be71 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -388,6 +388,12 @@ end ["mcl_core:whirlpool_source"] = -BUBBLE_COLUMN_SPEED, ["mcl_core:bubble_column_source"] = BUBBLE_COLUMN_SPEED, } + local bubble_source_fast_switch_from_to = { + ["mcl_nether:soul_sand"] = "mcl_core:bubble_column_source", + ["mcl_core:bubble_column_source"] = "mcl_core:bubble_column_source", + ["mcl_nether:magma"] = "mcl_core:whirlpool_source", + ["mcl_core:whirlpool_source"] = "mcl_core:whirlpool_source", + } minetest.register_abm({ label = "Process bubble columns and whirlpools", nodenames = {"mcl_core:whirlpool_source", "mcl_core:bubble_column_source"}, @@ -399,7 +405,7 @@ end local check = nether_node_to_check[name] local below = minetest.get_node({x = x, y = y - 1, z = z}).name if below ~= name and below ~= check then - minetest.swap_node(pos, {name = "mcl_core:water_source"}) + minetest.swap_node(pos, {name = bubble_source_fast_switch_from_to[below] or "mcl_core:water_source"}) return end local upper_pos = {x = x, y = y + 1, z = z} From 7ad310a848bfbfb78f62735502e6f8f2b13d113d Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 07:34:54 +0400 Subject: [PATCH 03/15] #249 Reduce client-side player speed smoothly in bubbles --- mods/PLAYER/mcl_playerplus/init.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index bdd2748b7..825bd0c3b 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -2,7 +2,6 @@ mcl_playerplus = { elytra = {}, } -local player_velocity_old = {x=0, y=0, z=0} local get_connected_players = minetest.get_connected_players local dir_to_yaw = minetest.dir_to_yaw local get_item_group = minetest.get_item_group @@ -336,9 +335,6 @@ minetest.register_globalstep(function(dtime) set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) end - player_velocity_old = player:get_velocity() or player:get_player_velocity() - - -- controls right and left arms pitch when shooting a bow or blocking if mcl_shields.is_blocking(player) == 2 then set_bone_position_conditional(player, "Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0)) @@ -466,6 +462,7 @@ minetest.register_globalstep(function(dtime) local bubble_column_head = node_head == "mcl_core:bubble_column_source" fly_pos.y = player_pos_for_bubble_columns[name].y + (bubble_column_head and time or time/10) player:set_pos(fly_pos) + player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) player_pos_for_bubble_columns[name] = fly_pos end else @@ -479,6 +476,7 @@ minetest.register_globalstep(function(dtime) if stands_on == "mcl_nether:magma" then fly_pos.y = math.floor(fly_pos.y) + (control.sneak and 0.51 or 0.5) player:set_pos(fly_pos) + player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) player_pos_for_bubble_columns[name] = fly_pos else fly_pos.y = player_pos_for_bubble_columns[name].y - (whirlpool_head and time/2 or time/5) @@ -486,9 +484,11 @@ minetest.register_globalstep(function(dtime) if will_stand_on == "mcl_nether:magma" then fly_pos.y = math.floor(fly_pos.y) + (control.sneak and 0.51 or 0.5) player:set_pos(fly_pos) + player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) player_pos_for_bubble_columns[name] = fly_pos elseif will_stand_on == "mcl_core:whirlpool_source" then player:set_pos(fly_pos) + player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) player_pos_for_bubble_columns[name] = fly_pos else player_pos_for_bubble_columns[name] = nil From 21f7738b4db922af48ea6947164d919bc1c2379c Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 08:34:12 +0400 Subject: [PATCH 04/15] Fix mob despawn --- mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua | 12 ++++++++---- mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index cbbda43d5..ab91a0542 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -902,10 +902,14 @@ function mobs.mob_step(self, dtime) object = self.object, max_hear_distance = 5 }, true) - self.object:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self.lava_damage} - }, nil) +--[[ if not mcl_burning.is_burning(self.object) then + mcl_burning.set_on_fire(self.object, 1.1) + else +]] self.object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self.lava_damage} + }, nil) +-- end self.lava_counter = 0 self.health = self.health - lava_damage self:teleport() diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua index a0467f4d2..454794dda 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua @@ -21,7 +21,7 @@ mobs.can_despawn = function(self) if new_distance < distance then distance = new_distance if distance < 33 then return false end - if distance < 128 and math_random(1, 200) == 19 then return true end + if distance < 128 and math_random(1, 42) ~= 11 then return false end end end end From c5b9313428d75289b6cca6b7002b38192dbc0aef Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 16:45:24 +0400 Subject: [PATCH 05/15] Make silverfishes attack --- mods/ENTITIES/mobs_mc/silverfish.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index ac3991ad1..44b804fe0 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -2,6 +2,8 @@ --################### SILVERFISH --################### +local PLAYER_SCAN_RADIUS = 5 + local S = minetest.get_translator(minetest.get_current_modname()) mobs:register_mob("mobs_mc:silverfish", { @@ -46,6 +48,20 @@ mobs:register_mob("mobs_mc:silverfish", { view_range = 16, attack_type = "punch", damage = 1, + do_custom = function(self, dtime) + self.do_custom_time = (self.do_custom_time or 0) + dtime + if self.do_custom_time < 1.5 then return end + self.do_custom_time = 0 + local selfpos = self.object:get_pos() + local objects = minetest.get_objects_inside_radius(selfpos, PLAYER_SCAN_RADIUS) + for _, obj in pairs(objects) do + if obj:is_player() then + self.attacking = obj + mobs.group_attack_initialization(self) + return + end + end + end }) mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) From a637e4bdafb3d7158f82fd95ceb6aabf0757fb94 Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 16:50:09 +0400 Subject: [PATCH 06/15] Restore mob spawn limit of 5 per area --- mods/ENTITIES/mcl_mobs/api/spawning.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api/spawning.lua b/mods/ENTITIES/mcl_mobs/api/spawning.lua index 2fcc83baf..d88d35b25 100644 --- a/mods/ENTITIES/mcl_mobs/api/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/api/spawning.lua @@ -389,8 +389,8 @@ if mobs_spawn then if #spawning_position_list <= 0 then return end local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)] - --hard code mob limit in area to 7 for now - if count_mobs(spawning_position) >= 7 then return end + --hard code mob limit in area to 5 for now + if count_mobs(spawning_position) >= 5 then return end local gotten_node = get_node(spawning_position).name local gotten_biome = minetest.get_biome_data(spawning_position) From 89cbc1deedf203f6f72dd514f12a5d2ac2fd235f Mon Sep 17 00:00:00 2001 From: kay27 Date: Sun, 13 Mar 2022 17:42:58 +0400 Subject: [PATCH 07/15] Fix crash in mcl_bows/rocket.lua:41 --- mods/ITEMS/mcl_bows/rocket.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_bows/rocket.lua b/mods/ITEMS/mcl_bows/rocket.lua index 678aba4d4..c6f6351a4 100644 --- a/mods/ITEMS/mcl_bows/rocket.lua +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -38,11 +38,14 @@ local function damage_explosion(self, damagemulitplier) for _,obj in pairs(objects) do if obj:is_player() then mcl_util.deal_damage(obj, damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos()), {type = "explosion"}) - elseif obj:get_luaentity()._cmi_is_mob then - obj:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos())}, - }, self.object:get_velocity()) + else + local entity = obj:get_luaentity() + if entity and entity._cmi_is_mob then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos())}, + }, self.object:get_velocity()) + end end end end From ba5474f5d4dd30cd400db360d0ba0e262f3a3b3c Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 11 Mar 2022 16:51:53 +0100 Subject: [PATCH 08/15] limit redstone distance by checking for players This should probably be implemented by having redstone signals lose strength like in mc. This just prevents redstone action further than 40 nodes from each player. --- mods/ITEMS/REDSTONE/mesecons/util.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mods/ITEMS/REDSTONE/mesecons/util.lua b/mods/ITEMS/REDSTONE/mesecons/util.lua index b6602526a..498c446cb 100644 --- a/mods/ITEMS/REDSTONE/mesecons/util.lua +++ b/mods/ITEMS/REDSTONE/mesecons/util.lua @@ -346,8 +346,16 @@ function mesecon.vm_abort() vm_cache = nil end +local function is_player_close(pos) + for k,p in pairs(minetest.get_connected_players()) do + local d=vector.distance(pos,p:get_pos()) + if d < 40 then return true end + end +end + -- Gets the cache entry covering a position, populating it if necessary. local function vm_get_or_create_entry(pos) + if not is_player_close(pos) then return end local hash = hash_blockpos(pos) local tbl = vm_cache[hash] if not tbl then @@ -364,6 +372,7 @@ end -- transaction. function mesecon.vm_get_node(pos) local tbl = vm_get_or_create_entry(pos) + if not tbl then return end local index = tbl.va:indexp(pos) local node_value = tbl.data[index] if node_value == minetest.CONTENT_IGNORE then @@ -380,6 +389,7 @@ end -- Existing param1, param2, and metadata are left alone. function mesecon.vm_swap_node(pos, name) local tbl = vm_get_or_create_entry(pos) + if not tbl then return end local index = tbl.va:indexp(pos) tbl.data[index] = minetest.get_content_id(name) tbl.dirty = true @@ -393,6 +403,7 @@ end -- -- Inside a VM transaction, the transaction’s VM cache is used. function mesecon.get_node_force(pos) + if not is_player_close(pos) then return end if vm_cache then return mesecon.vm_get_node(pos) else @@ -424,6 +435,7 @@ function mesecon.swap_node_force(pos, name) -- This serves to both ensure the mapblock is loaded and also hand us -- the old node table so we can preserve param2. local node = mesecon.get_node_force(pos) + if not node then return end node.name = name minetest.swap_node(pos, node) end From 37ff5f15bd57b6128f8216c39ff92d5658927e04 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 14 Mar 2022 02:59:21 +0400 Subject: [PATCH 09/15] #252 Fix review issues --- mods/ENTITIES/mcl_mobs/api/spawning.lua | 1 - mods/ENTITIES/mobs_mc/silverfish.lua | 2 +- mods/ITEMS/mcl_chests/init.lua | 102 ++++++++++++------------ mods/ITEMS/mcl_mushroom/init.lua | 8 +- mods/MAPGEN/mcl_debrisgen/init.lua | 16 ++-- mods/MAPGEN/mcl_structures/init.lua | 6 +- 6 files changed, 68 insertions(+), 67 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api/spawning.lua b/mods/ENTITIES/mcl_mobs/api/spawning.lua index d88d35b25..424989426 100644 --- a/mods/ENTITIES/mcl_mobs/api/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/api/spawning.lua @@ -302,7 +302,6 @@ function mobs:spawn_setup(def) on_spawn = on_spawn, } summary_chance = summary_chance + chance - minetest.log("warning", minetest.serialize(spawn_dictionary)) end function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 44b804fe0..70f358fb2 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -55,7 +55,7 @@ mobs:register_mob("mobs_mc:silverfish", { local selfpos = self.object:get_pos() local objects = minetest.get_objects_inside_radius(selfpos, PLAYER_SCAN_RADIUS) for _, obj in pairs(objects) do - if obj:is_player() then + if obj:is_player() and not minetest.is_creative_enabled(obj:get_player_name()) then self.attacking = obj mobs.group_attack_initialization(self) return diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 8b344d462..2ad6518a7 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -248,6 +248,51 @@ local function player_chest_close(player) open_chests[name] = nil end +local function drop_item_stack(pos, stack) + if not stack or stack:is_empty() then return end + local drop_offset = vector.new(math.random() - 0.5, 0, math.random() - 0.5) + minetest.add_item(vector.add(pos, drop_offset), stack) +end + +local function drop_items_chest(pos, oldnode, oldmetadata, digger) + if oldmetadata and oldmetadata.inventory then + -- process after_dig_node callback + local main = oldmetadata.inventory.main + if not main then return end + for _, stack in pairs(main) do + drop_item_stack(pos, stack) + end + else + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + for i = 1, inv:get_size("main") do + drop_item_stack(pos, inv:get_stack("main", i)) + end + meta:from_table() + end +end + +local function on_chest_blast(pos, intensity) + local node = minetest.get_node(pos) + drop_items_chest(pos, node) + minetest.remove_node(pos) + -- drop node itself with some probability depended on explosion intensity (1 for TNT): + if math.random(1, math.floor((intensity or 1) * 2)) ~= 1 then return end + local node_def = minetest.registered_nodes[node.name] + if not node_def then return end + local node_name = node_def.drop or node_def.name + drop_item_stack(pos, ItemStack(node_name)) +end + +local function close_forms(canonical_basename, pos) + local players = minetest.get_connected_players() + for p=1, #players do + if vector.distance(players[p]:get_pos(), pos) <= 30 then + minetest.close_formspec(players[p]:get_player_name(), "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z) + end + end +end + -- This is a helper function to register both chests and trapped chests. Trapped chests will make use of the additional parameters local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tiles_table, hidden, mesecons, on_rightclick_addendum, on_rightclick_addendum_left, on_rightclick_addendum_right, drop, canonical_basename) -- START OF register_chest FUNCTION BODY @@ -295,42 +340,6 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end end - local function drop_item_stack(pos, stack) - if not stack or stack:is_empty() then return end - local drop_offset = vector.new(math.random() - 0.5, 0, math.random() - 0.5) - minetest.add_item(vector.add(pos, drop_offset), stack) - end - - local function drop_items_chest(pos, oldnode, oldmetadata, digger) - if oldmetadata and oldmetadata.inventory then - -- process after_dig_node callback - local main = oldmetadata.inventory.main - if not main then return end - for _, stack in pairs(main) do - drop_item_stack(pos, stack) - end - else - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - for i = 1, inv:get_size("main") do - drop_item_stack(pos, inv:get_stack("main", i)) - end - meta:from_table() - end - end - - local function on_chest_blast(pos, intensity) - local node = minetest.get_node(pos) - drop_items_chest(pos, node) - minetest.remove_node(pos) - -- drop node itself with some probability depended on explosion intensity (1 for TNT): - if math.random(1, math.floor((intensity or 1) * 2)) ~= 1 then return end - local node_def = minetest.registered_nodes[node.name] - if not node_def then return end - local node_name = node_def.drop or node_def.name - drop_item_stack(pos, ItemStack(node_name)) - end - local function limit_put_list(stack, list) for _, other in ipairs(list) do stack = other:add_item(stack) @@ -380,15 +389,6 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end, }) - local function close_forms(canonical_basename, pos) - local players = minetest.get_connected_players() - for p=1, #players do - if vector.distance(players[p]:get_pos(), pos) <= 30 then - minetest.close_formspec(players[p]:get_player_name(), "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z) - end - end - end - minetest.register_node(small_name, { description = desc, _tt_help = tt_help, @@ -1476,9 +1476,11 @@ minetest.register_node("mcl_chests:barrel", { minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) end, after_dig_node = drop_items_chest, - on_blast = on_blast, + on_blast = on_chest_blast, on_rightclick = barrel_open, - on_destruct = close_forms, + on_destruct = function(pos) + close_forms("barrel", pos) + end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, }) @@ -1497,9 +1499,11 @@ minetest.register_node("mcl_chests:barrel_open", { sounds = mcl_sounds.node_sound_wood_defaults(), groups = {handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1, not_in_creative_inventory = 1}, after_dig_node = drop_items_chest, - on_blast = on_blast, + on_blast = on_chest_blast, on_rightclick = barrel_open, - on_destruct = close_forms, + on_destruct = function(pos) + close_forms("barrel_open", pos) + end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, }) diff --git a/mods/ITEMS/mcl_mushroom/init.lua b/mods/ITEMS/mcl_mushroom/init.lua index c5243c88a..a1a2f45c2 100644 --- a/mods/ITEMS/mcl_mushroom/init.lua +++ b/mods/ITEMS/mcl_mushroom/init.lua @@ -470,8 +470,8 @@ minetest.register_abm({ }) function generate_warped_tree(pos) - breakgrow = false - breakgrow2 = false + local breakgrow = false + local breakgrow2 = false -- Baumgenerator -- erste und zweite Etage for x = pos.x - 2,pos.x + 2 do @@ -547,8 +547,8 @@ function generate_warped_tree(pos) end function generate_crimson_tree(pos) - breakgrow = false - breakgrow2 = false + local breakgrow = false + local breakgrow2 = false -- Baumgenerator -- erste und zweite Etage for x = pos.x - 2,pos.x + 2 do diff --git a/mods/MAPGEN/mcl_debrisgen/init.lua b/mods/MAPGEN/mcl_debrisgen/init.lua index b2b630626..9d177cdbc 100644 --- a/mods/MAPGEN/mcl_debrisgen/init.lua +++ b/mods/MAPGEN/mcl_debrisgen/init.lua @@ -17,16 +17,14 @@ mcl_mapgen.register_mapgen_block(function(minp, maxp) local nodes = minetest_find_nodes_in_area(minp, maxp, debris_name) if nodes then for _, pos in pairs(nodes) do - minetest.log("warning","debris found at "..minetest.pos_to_string(pos)) local x, y, z = pos.x, pos.y, pos.z - if minetest_get_node({x = x-1, y = y, z = z}) == air_name - or minetest_get_node({x = x+1, y = y, z = z}) == air_name - or minetest_get_node({x = x, y = y-1, z = z}) == air_name - or minetest_get_node({x = x, y = y+1, z = z}) == air_name - or minetest_get_node({x = x, y = y, z = z-1}) == air_name - or minetest_get_node({x = x, y = y, z = z+1}) == air_name then - minetest_set_node(pos, netherrack_name) - minetest.log("warning","debris at "..minetest.pos_to_string(pos) .. " replaced to netherrack") + if minetest_get_node({x = x-1, y = y, z = z}).name == air_name + or minetest_get_node({x = x+1, y = y, z = z}).name == air_name + or minetest_get_node({x = x, y = y-1, z = z}).name == air_name + or minetest_get_node({x = x, y = y+1, z = z}).name == air_name + or minetest_get_node({x = x, y = y, z = z-1}).name == air_name + or minetest_get_node({x = x, y = y, z = z+1}).name == air_name then + minetest_set_node(pos, {name = netherrack_name}) end end end diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 83646179b..c99970813 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -289,9 +289,9 @@ function mcl_structures.place_schematic(def) pos = vector.new(pos), schematic = loaded_schematic, rotation = rotation, - replacements = replacements, - force_placement = force_placement, - flags = flags, + replacements = def.replacements, + force_placement = def.force_placement, + flags = def.flags, size = vector.new(size), pr = pr, on_placed = on_placed, From 6d27d5b5afa8a1280d4340d6d99801f7b6795709 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 14 Mar 2022 03:05:32 +0400 Subject: [PATCH 10/15] #252 Reduce zombipigs spawn in portal frames rate --- mods/ITEMS/mcl_portals/portal_nether.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 883f6e4fc..7390bbb2f 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -746,7 +746,7 @@ minetest.register_abm({ return end - if lower_node_name == OBSIDIAN and pos.y >= mcl_mapgen.overworld.min and random(1, 200) == 19 then + if lower_node_name == OBSIDIAN and pos.y >= mcl_mapgen.overworld.min and random(1, 750) == 19 then local pigman_obj = minetest.add_entity(pos, "mobs_mc:pigman") if pigman_obj then teleport_cooloff(pigman_obj) From 2ea71e936776a2fa5941d4203e71dc3582c7741f Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 14 Mar 2022 04:07:11 +0400 Subject: [PATCH 11/15] #249 Trace bubble column lift --- mods/PLAYER/mcl_playerplus/init.lua | 46 ++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 825bd0c3b..84a78baf8 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -456,14 +456,46 @@ minetest.register_globalstep(function(dtime) local bubble_column_feet = node_feet == "mcl_core:bubble_column_source" if bubble_column_feet then - if not player_pos_for_bubble_columns[name] then - player_pos_for_bubble_columns[name] = fly_pos + local bubble_column_head = node_head == "mcl_core:bubble_column_source" + if bubble_column_head then + if not player_pos_for_bubble_columns[name] then + player_pos_for_bubble_columns[name] = fly_pos + else + local head_alt_1 = fly_pos.y + 1.5 + local head_alt_2 = head_alt_1 + time + while head_alt_1 < head_alt_2 do + local next_alt = math.min(head_alt_1 + 1, head_alt_2) + local next_node_head = minetest.get_node({x = fly_pos.x, y = next_alt, z = fly_pos.z}).name + if next_node_head == "mcl_core:bubble_column_source" then + head_alt_1 = next_alt + else + local ndef = minetest.registered_nodes[next_node_head] + if (ndef.walkable == nil or ndef.walkable == true) + and (ndef.collision_box == nil or ndef.collision_box.type == "regular") + and (ndef.node_box == nil or ndef.node_box.type == "regular") + and (ndef.groups.disable_suffocation ~= 1) + and (ndef.groups.opaque == 1) + then + break + else + head_alt_1 = next_alt + break + end + end + end + local new_alt = head_alt_1 - 1.5 + local delta_y = new_alt - fly_pos.y + if delta_y > 0 then + fly_pos.y = new_alt + player:set_pos(fly_pos) + player:add_velocity({x = 0, y = -player_velocity.y / 3, z = 0}) + player_pos_for_bubble_columns[name] = fly_pos + else + player_pos_for_bubble_columns[name] = nil + end + end else - local bubble_column_head = node_head == "mcl_core:bubble_column_source" - fly_pos.y = player_pos_for_bubble_columns[name].y + (bubble_column_head and time or time/10) - player:set_pos(fly_pos) - player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) - player_pos_for_bubble_columns[name] = fly_pos + player_pos_for_bubble_columns[name] = nil end else local whirlpool_feet = node_feet == "mcl_core:whirlpool_source" From a392d59cab2dfef3e6e1f9da3b7c7b771981005d Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 14 Mar 2022 04:16:35 +0400 Subject: [PATCH 12/15] #249 Make slower bubble column pull above water level --- mods/PLAYER/mcl_playerplus/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 84a78baf8..4b4e8d1a7 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -478,7 +478,8 @@ minetest.register_globalstep(function(dtime) then break else - head_alt_1 = next_alt + -- show head slightly above water level: + head_alt_1 = head_alt_1 + (next_alt - head_alt_1) * 0.26 break end end From 7ca28d8a27b5cfe1a91a1a27a918b8c8cda712e1 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 14 Mar 2022 06:05:17 +0400 Subject: [PATCH 13/15] Make safer get_staticdata --- mods/ENTITIES/extra_mobs/glow_squid_items.lua | 3 ++- mods/ENTITIES/mcl_boats/init.lua | 5 ++++- mods/ENTITIES/mcl_falling_nodes/init.lua | 1 + mods/ENTITIES/mcl_item_entity/init.lua | 1 + mods/ENTITIES/mcl_minecarts/init.lua | 1 + mods/ENTITIES/mcl_mobs/api/api.lua | 4 +++- mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua | 2 +- mods/ENTITIES/mcl_paintings/init.lua | 1 + mods/ITEMS/mcl_banners/init.lua | 1 + mods/ITEMS/mcl_bows/arrow.lua | 1 + mods/ITEMS/mcl_bows/rocket.lua | 1 + mods/ITEMS/mcl_end/eye_of_ender.lua | 2 +- mods/ITEMS/mcl_itemframes/init.lua | 1 + mods/ITEMS/mcl_mobspawners/init.lua | 2 +- mods/ITEMS/mcl_potions/tipped_arrow.lua | 1 + mods/ITEMS/mcl_signs/init.lua | 1 + mods/ITEMS/mcl_throwing/init.lua | 1 + 17 files changed, 23 insertions(+), 6 deletions(-) diff --git a/mods/ENTITIES/extra_mobs/glow_squid_items.lua b/mods/ENTITIES/extra_mobs/glow_squid_items.lua index db4d88e89..c7f30662b 100644 --- a/mods/ENTITIES/extra_mobs/glow_squid_items.lua +++ b/mods/ENTITIES/extra_mobs/glow_squid_items.lua @@ -54,10 +54,11 @@ minetest.register_entity("extra_mobs:glow_item_frame_item",{ end end, get_staticdata = function(self) + if not self then return end if self._nodename ~= nil and self._texture ~= nil then local ret = self._nodename .. ';' .. self._texture if self._scale ~= nil then - ret = ret .. ';' .. self._scale + ret = ret .. ';' .. tostring(self._scale) end return ret end diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 9ec06d870..3a26c1b36 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -175,10 +175,13 @@ function boat.on_activate(self, staticdata, dtime_s) end function boat.get_staticdata(self) + if not self then return end + local object = self.object + local object_properties = object and object.get_properties and object:get_properties() return minetest.serialize({ v = self._v, itemstring = self._itemstring, - textures = self.object:get_properties().textures + textures = object_properties and object_properties.textures }) end diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index d527603de..769f1d4a9 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -89,6 +89,7 @@ minetest.register_entity(":__builtin:falling_node", { }) end, get_staticdata = function(self) + if not self then return end local meta = self.meta -- Workaround: Save inventory seperately from metadata. -- Because Minetest crashes when a node with inventory gets deactivated diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index b1202f4ad..e88f4dd80 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -486,6 +486,7 @@ minetest.register_entity(":__builtin:item", { end, get_staticdata = function(self) + if not self then return end local data = minetest.serialize({ itemstring = self.itemstring, always_collect = self.always_collect, diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 119a13523..4294c4630 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -503,6 +503,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end function cart:get_staticdata() + if not self then return end return minetest.serialize({_railtype = self._railtype}) end diff --git a/mods/ENTITIES/mcl_mobs/api/api.lua b/mods/ENTITIES/mcl_mobs/api/api.lua index ea7589f47..c72dca0bd 100644 --- a/mods/ENTITIES/mcl_mobs/api/api.lua +++ b/mods/ENTITIES/mcl_mobs/api/api.lua @@ -425,7 +425,9 @@ function mobs:register_mob(name, def) end, get_staticdata = function(self) - return mobs.mob_staticdata(self) + if self and mobs then + return mobs.mob_staticdata(self) + end end, --harmed_by_heal = def.harmed_by_heal, diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua index 454794dda..d9cc4237c 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua @@ -42,7 +42,7 @@ mobs.mob_staticdata = function(self) self.following = nil if use_cmi then - self.serialized_cmi_components = cmi.serialize_components(self._cmi_components) + self.serialized_cmi_components = cmi and cmi.serialize_components(self._cmi_components) end local tmp = {} diff --git a/mods/ENTITIES/mcl_paintings/init.lua b/mods/ENTITIES/mcl_paintings/init.lua index 26bd2c61b..74e7341ca 100644 --- a/mods/ENTITIES/mcl_paintings/init.lua +++ b/mods/ENTITIES/mcl_paintings/init.lua @@ -160,6 +160,7 @@ minetest.register_entity("mcl_paintings:painting", { set_entity(self.object) end, get_staticdata = function(self) + if not self then return end local data = { _facing = self._facing, _pos = self._pos, diff --git a/mods/ITEMS/mcl_banners/init.lua b/mods/ITEMS/mcl_banners/init.lua index cc0e02e66..0be8610f0 100644 --- a/mods/ITEMS/mcl_banners/init.lua +++ b/mods/ITEMS/mcl_banners/init.lua @@ -618,6 +618,7 @@ local entity_standing = { -- pattern: name of pattern (see list above) get_staticdata = function(self) + if not self then return end local out = { _base_color = self._base_color, _layers = self._layers, _name = self._name } return minetest.serialize(out) end, diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index baa4d633a..5cbafce62 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -441,6 +441,7 @@ function ARROW_ENTITY.on_punch(self) end function ARROW_ENTITY.get_staticdata(self) + if not self then return end local out = { lastpos = self._lastpos, startpos = self._startpos, diff --git a/mods/ITEMS/mcl_bows/rocket.lua b/mods/ITEMS/mcl_bows/rocket.lua index c6f6351a4..cac466376 100644 --- a/mods/ITEMS/mcl_bows/rocket.lua +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -630,6 +630,7 @@ function ARROW_ENTITY.on_punch(self) end function ARROW_ENTITY.get_staticdata(self) + if not self then return end local out = { lastpos = self._lastpos, startpos = self._startpos, diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index 97dee9336..d2e273c8d 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -10,7 +10,7 @@ minetest.register_entity("mcl_end:ender_eye", { -- Save and restore age get_staticdata = function(self) - return tostring(self._age) or "0" + return tostring(self and self._age) or "0" end, on_activate = function(self, staticdata, dtime_s) local age = tonumber(staticdata) diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index d46a393b8..5dde560b7 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -33,6 +33,7 @@ minetest.register_entity("mcl_itemframes:item",{ end end, get_staticdata = function(self) + if not self then return end if self._nodename and self._texture then local ret = self._nodename .. ";" .. self._texture if self._scale then diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index 37720e1e8..11339e1a4 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -352,7 +352,7 @@ local doll_def = { } doll_def.get_staticdata = function(self) - return self._mob + return self and self._mob end doll_def.on_activate = function(self, staticdata, dtime_s) diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index 1717533a8..907580aef 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -391,6 +391,7 @@ function mcl_potions.register_arrow(name, desc, color, def) end function ARROW_ENTITY.get_staticdata(self) + if not self then return end local out = { lastpos = self._lastpos, startpos = self._startpos, diff --git a/mods/ITEMS/mcl_signs/init.lua b/mods/ITEMS/mcl_signs/init.lua index b6bfb3fe8..c3c779356 100644 --- a/mods/ITEMS/mcl_signs/init.lua +++ b/mods/ITEMS/mcl_signs/init.lua @@ -537,6 +537,7 @@ minetest.register_entity("mcl_signs:text", { self.object:set_armor_groups({ immortal = 1 }) end, get_staticdata = function(self) + if not self then return end local out = { _signnodename = self._signnodename } return minetest.serialize(out) end, diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua index c468946dd..88c69a3f3 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -57,6 +57,7 @@ end -- Staticdata handling because objects may want to be reloaded function mcl_throwing.get_staticdata(self) + if not self then return end local thrower -- Only save thrower if it's a player name if type(self._thrower) == "string" then From 2f7bb481addd2deac6e882fab9f5131926064eb4 Mon Sep 17 00:00:00 2001 From: kay27 Date: Mon, 14 Mar 2022 13:23:09 +0400 Subject: [PATCH 14/15] Ban silently all the list, not only first player --- mods/PLAYER/mcl_anticheat/init.lua | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/mods/PLAYER/mcl_anticheat/init.lua b/mods/PLAYER/mcl_anticheat/init.lua index bd76e2818..2e3f427a6 100644 --- a/mods/PLAYER/mcl_anticheat/init.lua +++ b/mods/PLAYER/mcl_anticheat/init.lua @@ -199,11 +199,10 @@ local function step() end end elseif #players < 26 then - if should_be_banned then - minetest.chat_send_all("Player " .. first .. " has been banned for having more than 9 connections at once") - minetest.ban_player(first) - else - for _, player_name in pairs(players) do + for _, player_name in pairs(players) do + if should_be_banned then + minetest.ban_player(player_name) + else if (player_doesnt_move[player_name] or 0) > 90/step_seconds then minetest.kick_player(player_name, "Didn't move during 1.5 minutes being connected multiple times") ban_next_time[ip] = 1 @@ -211,18 +210,18 @@ local function step() end end elseif #players <= 100 then - if should_be_banned then - minetest.ban_player(first) - minetest.chat_send_all("Player " .. first .. " has been banned for having more than 25 connections at once") - else - for _, player_name in pairs(players) do + for _, player_name in pairs(players) do + if should_be_banned then + minetest.ban_player(player_name) + else minetest.kick_player(player_name, "More than 25 connections from IP address " .. ip) + ban_next_time[ip] = 1 end - ban_next_time[ip] = 1 end else - minetest.ban_player(first) - minetest.chat_send_all("Player " .. first .. " has been banned for having more than 100 connections at once") + for _, player_name in pairs(players) do + minetest.ban_player(player_name) + end end end end From cb4bb7922424d87bbabac5a4a9e28312839def24 Mon Sep 17 00:00:00 2001 From: kay27 Date: Tue, 15 Mar 2022 02:05:42 +0400 Subject: [PATCH 15/15] #249 Trace whirlpools --- mods/PLAYER/mcl_playerplus/init.lua | 65 +++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 4b4e8d1a7..85755e0de 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -478,8 +478,8 @@ minetest.register_globalstep(function(dtime) then break else - -- show head slightly above water level: - head_alt_1 = head_alt_1 + (next_alt - head_alt_1) * 0.26 + -- pull head slightly above water level: + head_alt_1 = head_alt_1 + (next_alt - head_alt_1) * 0.5 break end end @@ -489,7 +489,16 @@ minetest.register_globalstep(function(dtime) if delta_y > 0 then fly_pos.y = new_alt player:set_pos(fly_pos) - player:add_velocity({x = 0, y = -player_velocity.y / 3, z = 0}) + local velocity_y = player_velocity.y + local add_velocity_y + if velocity_y > 1 then + add_velocity_y = -velocity_y/5 + elseif velocity_y >= -1 then + add_velocity_y = -velocity_y/2.5 + else + add_velocity_y = -velocity_y/2 + end + player:add_velocity({x = 0, y = add_velocity_y, z = 0}) player_pos_for_bubble_columns[name] = fly_pos else player_pos_for_bubble_columns[name] = nil @@ -509,23 +518,43 @@ minetest.register_globalstep(function(dtime) if stands_on == "mcl_nether:magma" then fly_pos.y = math.floor(fly_pos.y) + (control.sneak and 0.51 or 0.5) player:set_pos(fly_pos) - player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) + local add_velocity_y + local velocity_y = player_velocity.y + if velocity_y < -1 then + add_velocity_y = -velocity_y/5 + elseif velocity_y <= 1 then + add_velocity_y = -velocity_y/2.5 + else + add_velocity_y = -velocity_y/2 + end + player:add_velocity({x = 0, y = add_velocity_y, z = 0}) + player_pos_for_bubble_columns[name] = fly_pos + elseif stands_on == "mcl_core:whirlpool_source" then + local estimated_pos_y = player_pos_for_bubble_columns[name].y - (whirlpool_head and time/2 or time/5) + local next_pos_y = fly_pos.y + while next_pos_y > estimated_pos_y do + next_pos_y = next_pos_y - math.min(1, next_pos_y - estimated_pos_y) + local will_stand_on = minetest.get_node({x = fly_pos.x, y = next_pos_y - 0.0001, z = fly_pos.z}).name + if will_stand_on ~= "mcl_core:whirlpool_source" then + next_pos_y = math.floor(next_pos_y - 0.0001) + (control.sneak and 0.51 or 0.5) + break + end + end + fly_pos.y = next_pos_y + player:set_pos(fly_pos) + local add_velocity_y + local velocity_y = player_velocity.y + if velocity_y < -1 then + add_velocity_y = -velocity_y/5 + elseif velocity_y <= 1 then + add_velocity_y = -velocity_y/2.5 + else + add_velocity_y = -velocity_y/2 + end + player:add_velocity({x = 0, y = add_velocity_y, z = 0}) player_pos_for_bubble_columns[name] = fly_pos else - fly_pos.y = player_pos_for_bubble_columns[name].y - (whirlpool_head and time/2 or time/5) - local will_stand_on = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.0001, z = fly_pos.z}).name - if will_stand_on == "mcl_nether:magma" then - fly_pos.y = math.floor(fly_pos.y) + (control.sneak and 0.51 or 0.5) - player:set_pos(fly_pos) - player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) - player_pos_for_bubble_columns[name] = fly_pos - elseif will_stand_on == "mcl_core:whirlpool_source" then - player:set_pos(fly_pos) - player:add_velocity({x = 0, y = -player_velocity.y / 2, z = 0}) - player_pos_for_bubble_columns[name] = fly_pos - else - player_pos_for_bubble_columns[name] = nil - end + player_pos_for_bubble_columns[name] = nil end end elseif player_pos_for_bubble_columns[name] then