From 146e2de1a57350be9b43002dab6bed048725915a Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 24 Oct 2022 04:08:11 +0200 Subject: [PATCH 01/14] Structure-api: add initial rotation support --- mods/MAPGEN/mcl_structures/api.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua index f542dddba..311636e64 100644 --- a/mods/MAPGEN/mcl_structures/api.lua +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -180,10 +180,10 @@ function mcl_structures.place_structure(pos, def, pr, blockseed) local ap = function(pos,def,pr,blockseed) end if def.after_place then ap = def.after_place end - mcl_structures.place_schematic(pp, file, "random", nil, true, "place_center_x,place_center_z",function(p) + mcl_structures.place_schematic(pp, file, "random", def.replacements, true, "place_center_x,place_center_z",function(p1, p2, size, rotation) if def.loot then generate_loot(pp,def,pr,blockseed) end if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end - return ap(pp,def,pr,blockseed) + return ap(pp,def,pr,blockseed,p1,p2,size,rotation) end,pr) if log_enabled then minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) From c30e2c33b9391b8b926823534c89c715b98fd1b4 Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 24 Oct 2022 04:09:08 +0200 Subject: [PATCH 02/14] Move end portal shrine generation to structure api --- mods/MAPGEN/mcl_strongholds/init.lua | 89 +++++++++++++++- mods/MAPGEN/mcl_structures/init.lua | 145 +++------------------------ 2 files changed, 102 insertions(+), 132 deletions(-) diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua index 2a362cc40..6f234c51c 100644 --- a/mods/MAPGEN/mcl_strongholds/init.lua +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -16,6 +16,7 @@ local stronghold_rings = { } local strongholds = {} +local stronghold_positions = {} local strongholds_inited = false local mg_name = minetest.get_mapgen_setting("mg_name") @@ -54,6 +55,7 @@ local function init_strongholds() local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist } pos = vector.round(pos) table.insert(strongholds, { pos = pos, generated = false }) + table.insert(stronghold_positions, pos) -- Rotate angle by (360 / amount) degrees. -- This will cause the angles to be evenly distributed in the stronghold ring @@ -94,7 +96,7 @@ local function generate_strongholds(minp, maxp, blockseed) pos.z = maxp.z - 7 end - mcl_structures.call_struct(pos, "end_portal_shrine", nil, pr) + --mcl_structures.call_struct(pos, "end_portal_shrine", nil, pr) strongholds[s].generated = true end end @@ -103,4 +105,87 @@ end init_strongholds() -mcl_mapgen_core.register_generator("strongholds", nil, generate_strongholds, 999999) +mcl_structures.register_structure("end_shrine",{ + static_pos = stronghold_positions, + filenames = { + minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" + }, + after_place = function(pos,def,pr,blockseed,p1,p2,size,rotation) + local p1 = vector.subtract(pos,size) + local p2 = vector.add(pos,size) + local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") + for s=1, #spawners do + --local meta = minetest.get_meta(spawners[s]) + mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") + end + + -- Shuffle stone brick types + local bricks = minetest.find_nodes_in_area(p1, p2, "mcl_core:stonebrick") + for b=1, #bricks do + local r_bricktype = pr:next(1, 100) + local r_infested = pr:next(1, 100) + local bricktype + if r_infested <= 5 then + if r_bricktype <= 30 then -- 30% + bricktype = "mcl_monster_eggs:monster_egg_stonebrickmossy" + elseif r_bricktype <= 50 then -- 20% + bricktype = "mcl_monster_eggs:monster_egg_stonebrickcracked" + else -- 50% + bricktype = "mcl_monster_eggs:monster_egg_stonebrick" + end + else + if r_bricktype <= 30 then -- 30% + bricktype = "mcl_core:stonebrickmossy" + elseif r_bricktype <= 50 then -- 20% + bricktype = "mcl_core:stonebrickcracked" + end + -- 50% stonebrick (no change necessary) + end + if bricktype then + minetest.set_node(bricks[b], { name = bricktype }) + end + end + + -- Also replace stairs + local stairs = minetest.find_nodes_in_area(p1, p2, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) + for s=1, #stairs do + local stair = minetest.get_node(stairs[s]) + local r_type = pr:next(1, 100) + if r_type <= 30 then -- 30% mossy + if stair.name == "mcl_stairs:stair_stonebrick" then + stair.name = "mcl_stairs:stair_stonebrickmossy" + elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then + stair.name = "mcl_stairs:stair_stonebrickmossy_outer" + elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then + stair.name = "mcl_stairs:stair_stonebrickmossy_inner" + end + minetest.set_node(stairs[s], stair) + elseif r_type <= 50 then -- 20% cracky + if stair.name == "mcl_stairs:stair_stonebrick" then + stair.name = "mcl_stairs:stair_stonebrickcracked" + elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then + stair.name = "mcl_stairs:stair_stonebrickcracked_outer" + elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then + stair.name = "mcl_stairs:stair_stonebrickcracked_inner" + end + minetest.set_node(stairs[s], stair) + end + -- 50% no change + end + + -- Randomly add ender eyes into end portal frames, but never fill the entire frame + local frames = minetest.find_nodes_in_area(p1, p2, "mcl_portals:end_portal_frame") + local eyes = 0 + for f=1, #frames do + local r_eye = pr:next(1, 10) + if r_eye == 1 then + eyes = eyes + 1 + if eyes < #frames then + local frame_node = minetest.get_node(frames[f]) + frame_node.name = "mcl_portals:end_portal_frame_eye" + minetest.set_node(frames[f], frame_node) + end + end + end + end, +}) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index f57fa34f4..3a7681cc2 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -3,6 +3,7 @@ local S = minetest.get_translator(modname) local modpath = minetest.get_modpath(modname) mcl_structures = {} +local structure_data = {} local rotations = { "0", @@ -11,11 +12,6 @@ local rotations = { "270" } -local replacement = { - ["mcl_farming:pumpkintige_linked_t"] = "mcl_farming:pumpkintige_unconnect", - ["mcl_farming:melontige_linked_t"] = "mcl_farming:melontige_unconnect" -} - local function ecb_place(blockpos, action, calls_remaining, param) if calls_remaining >= 1 then return end minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) @@ -42,7 +38,7 @@ function mcl_structures.place_schematic(pos, schematic, rotation, replacements, local p1 = {x=pos.x , y=pos.y , z=pos.z } local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) - local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacement, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} + local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} minetest.emerge_area(p1, p2, ecb_place, param) return true end @@ -75,117 +71,21 @@ local function init_node_construct(pos) end mcl_structures.init_node_construct = init_node_construct --- The call of Struct -function mcl_structures.call_struct(pos, struct_style, rotation, pr) - minetest.log("action","[mcl_structures] call_struct " .. struct_style.." at "..minetest.pos_to_string(pos)) - if not rotation then - rotation = "random" +local function dir_to_rotation(dir) + local ax, az = math.abs(dir.x), math.abs(dir.z) + if ax > az then + if dir.x < 0 then + return "270" + end + return "90" end - if struct_style == "end_portal_shrine" then - return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) + if dir.z < 0 then + return "180" end + return "0" end -local function shrine_placement_callback(p1, p2, size, rotation, pr) - -- Find and setup spawner with silverfish - local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") - for s=1, #spawners do - --local meta = minetest.get_meta(spawners[s]) - mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") - end - - -- Shuffle stone brick types - local bricks = minetest.find_nodes_in_area(p1, p2, "mcl_core:stonebrick") - for b=1, #bricks do - local r_bricktype = pr:next(1, 100) - local r_infested = pr:next(1, 100) - local bricktype - if r_infested <= 5 then - if r_bricktype <= 30 then -- 30% - bricktype = "mcl_monster_eggs:monster_egg_stonebrickmossy" - elseif r_bricktype <= 50 then -- 20% - bricktype = "mcl_monster_eggs:monster_egg_stonebrickcracked" - else -- 50% - bricktype = "mcl_monster_eggs:monster_egg_stonebrick" - end - else - if r_bricktype <= 30 then -- 30% - bricktype = "mcl_core:stonebrickmossy" - elseif r_bricktype <= 50 then -- 20% - bricktype = "mcl_core:stonebrickcracked" - end - -- 50% stonebrick (no change necessary) - end - if bricktype then - minetest.set_node(bricks[b], { name = bricktype }) - end - end - - -- Also replace stairs - local stairs = minetest.find_nodes_in_area(p1, p2, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) - for s=1, #stairs do - local stair = minetest.get_node(stairs[s]) - local r_type = pr:next(1, 100) - if r_type <= 30 then -- 30% mossy - if stair.name == "mcl_stairs:stair_stonebrick" then - stair.name = "mcl_stairs:stair_stonebrickmossy" - elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then - stair.name = "mcl_stairs:stair_stonebrickmossy_outer" - elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then - stair.name = "mcl_stairs:stair_stonebrickmossy_inner" - end - minetest.set_node(stairs[s], stair) - elseif r_type <= 50 then -- 20% cracky - if stair.name == "mcl_stairs:stair_stonebrick" then - stair.name = "mcl_stairs:stair_stonebrickcracked" - elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then - stair.name = "mcl_stairs:stair_stonebrickcracked_outer" - elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then - stair.name = "mcl_stairs:stair_stonebrickcracked_inner" - end - minetest.set_node(stairs[s], stair) - end - -- 50% no change - end - - -- Randomly add ender eyes into end portal frames, but never fill the entire frame - local frames = minetest.find_nodes_in_area(p1, p2, "mcl_portals:end_portal_frame") - local eyes = 0 - for f=1, #frames do - local r_eye = pr:next(1, 10) - if r_eye == 1 then - eyes = eyes + 1 - if eyes < #frames then - local frame_node = minetest.get_node(frames[f]) - frame_node.name = "mcl_portals:end_portal_frame_eye" - minetest.set_node(frames[f], frame_node) - end - end - end -end - -function mcl_structures.generate_end_portal_shrine(pos, rotation, pr) - local offset = {x=6, y=4, z=6} - --local size = {x=13, y=8, z=13} - local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z } - - local path = modpath.."/schematics/mcl_structures_end_portal_room_simple.mts" - mcl_structures.place_schematic(newpos, path, rotation or "0", nil, true, nil, shrine_placement_callback, pr) -end - -local structure_data = {} - ---[[ Returns a table of structure of the specified type. -Currently the only valid parameter is "stronghold". -Format of return value: -{ - { pos = , generated= }, -- first structure - { pos = , generated= }, -- second structure - -- and so on -} - -TODO: Implement this function for all other structure types as well. -]] +--this is only used by end shrines - find a better way eventually ... function mcl_structures.get_structure_data(structure_type) if structure_data[structure_type] then return table.copy(structure_data[structure_type]) @@ -200,19 +100,6 @@ function mcl_structures.register_structure_data(structure_type, structures) structure_data[structure_type] = structures end -local function dir_to_rotation(dir) - local ax, az = math.abs(dir.x), math.abs(dir.z) - if ax > az then - if dir.x < 0 then - return "270" - end - return "90" - end - if dir.z < 0 then - return "180" - end - return "0" -end dofile(modpath.."/api.lua") dofile(modpath.."/shipwrecks.lua") @@ -290,7 +177,7 @@ mcl_structures.register_structure("ice_spike_large",{ -- Debug command minetest.register_chatcommand("spawnstruct", { - params = "end_portal_shrine | dungeon", + params = "dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) @@ -304,9 +191,7 @@ minetest.register_chatcommand("spawnstruct", { local pr = PseudoRandom(pos.x+pos.y+pos.z) local errord = false local message = S("Structure placed.") - if param == "end_portal_shrine" then - mcl_structures.generate_end_portal_shrine(pos, rot, pr) - elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then + if param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then mcl_dungeons.spawn_dungeon(pos, rot, pr) elseif param == "" then message = S("Error: No structure type given. Please use “/spawnstruct ”.") From 9aaa13408ae34c7b57afecedb5ff66557f14e2a1 Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 24 Oct 2022 05:12:01 +0200 Subject: [PATCH 03/14] Remove get_structure_data_construct the positions are available from the registered structure --- mods/ITEMS/mcl_end/eye_of_ender.lua | 8 ++++---- mods/MAPGEN/mcl_strongholds/init.lua | 25 +++++-------------------- mods/MAPGEN/mcl_structures/init.lua | 17 ----------------- 3 files changed, 9 insertions(+), 41 deletions(-) diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index bc697e359..b5adc7cb6 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -87,7 +87,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { end local origin = user:get_pos() origin.y = origin.y + 1.5 - local strongholds = mcl_structures.get_structure_data("stronghold") + local strongholds = mcl_structures.registered_structures["end_shrine"].static_pos local dim = mcl_worlds.pos_to_dimension(origin) local is_creative = minetest.is_creative_enabled(user:get_player_name()) @@ -105,7 +105,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { local closest_stronghold local lowest_dist for s=1, #strongholds do - local h_pos = table.copy(strongholds[s].pos) + local h_pos = table.copy(strongholds[s]) local h_origin = table.copy(origin) h_pos.y = 0 h_origin.y = 0 @@ -128,14 +128,14 @@ minetest.register_craftitem("mcl_end:ender_eye", { if lowest_dist <= 25 then local velocity = 4 -- Stronghold is close: Fly directly to stronghold and take Y into account. - dir = vector.normalize(vector.direction(origin, closest_stronghold.pos)) + dir = vector.normalize(vector.direction(origin, closest_stronghold)) obj:set_velocity({x=dir.x*velocity, y=dir.y*velocity, z=dir.z*velocity}) else local velocity = 12 -- Don't care about Y if stronghold is still far away. -- Fly to direction of X/Z, and always upwards so it can be seen easily. local o = {x=origin.x, y=0, z=origin.z} - local s = {x=closest_stronghold.pos.x, y=0, z=closest_stronghold.pos.z} + local s = {x=closest_stronghold.x, y=0, z=closest_stronghold.z} dir = vector.normalize(vector.direction(o, s)) obj:set_acceleration({x=dir.x*-3, y=4, z=dir.z*-3}) obj:set_velocity({x=dir.x*velocity, y=3, z=dir.z*velocity}) diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua index 6f234c51c..d5bc87963 100644 --- a/mods/MAPGEN/mcl_strongholds/init.lua +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -16,26 +16,17 @@ local stronghold_rings = { } local strongholds = {} -local stronghold_positions = {} -local strongholds_inited = false local mg_name = minetest.get_mapgen_setting("mg_name") local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" +local seed = tonumber(minetest.get_mapgen_setting("seed")) --- Determine the stronghold positions and store them into the strongholds table. --- The stronghold positions are based on the world seed. --- The actual position might be offset by a few blocks because it might be shifted --- to make sure the end portal room is completely within the boundaries of a mapchunk. local function init_strongholds() - if strongholds_inited then - return - end + local stronghold_positions = {} -- Don't generate strongholds in singlenode if mg_name == "singlenode" then - strongholds_inited = true - return + return {} end - local seed = tonumber(minetest.get_mapgen_setting("seed")) local pr = PseudoRandom(seed) for s=1, #stronghold_rings do local ring = stronghold_rings[s] @@ -54,7 +45,6 @@ local function init_strongholds() end local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist } pos = vector.round(pos) - table.insert(strongholds, { pos = pos, generated = false }) table.insert(stronghold_positions, pos) -- Rotate angle by (360 / amount) degrees. @@ -62,10 +52,7 @@ local function init_strongholds() angle = math.fmod(angle + ((math.pi*2) / ring.amount), math.pi*2) end end - - mcl_structures.register_structure_data("stronghold", table.copy(strongholds)) - - strongholds_inited = true + return stronghold_positions end -- Stronghold generation for register_on_generated. @@ -103,10 +90,8 @@ local function generate_strongholds(minp, maxp, blockseed) end end -init_strongholds() - mcl_structures.register_structure("end_shrine",{ - static_pos = stronghold_positions, + static_pos = init_strongholds(), filenames = { minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" }, diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 3a7681cc2..d771973be 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -3,7 +3,6 @@ local S = minetest.get_translator(modname) local modpath = minetest.get_modpath(modname) mcl_structures = {} -local structure_data = {} local rotations = { "0", @@ -85,22 +84,6 @@ local function dir_to_rotation(dir) return "0" end ---this is only used by end shrines - find a better way eventually ... -function mcl_structures.get_structure_data(structure_type) - if structure_data[structure_type] then - return table.copy(structure_data[structure_type]) - else - return {} - end -end - --- Register a structures table for the given type. The table format is the same as for --- mcl_structures.get_structure_data. -function mcl_structures.register_structure_data(structure_type, structures) - structure_data[structure_type] = structures -end - - dofile(modpath.."/api.lua") dofile(modpath.."/shipwrecks.lua") dofile(modpath.."/desert_temple.lua") From c850c0dfbb5f4bd334f8b1522b24b97df73297ef Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 24 Oct 2022 05:26:47 +0200 Subject: [PATCH 04/14] move remaining api code to mcl_structures/api.lua --- mods/MAPGEN/mcl_structures/api.lua | 71 ++++++++++++++++++- mods/MAPGEN/mcl_structures/init.lua | 105 +++++----------------------- 2 files changed, 87 insertions(+), 89 deletions(-) diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua index 311636e64..6611d17f4 100644 --- a/mods/MAPGEN/mcl_structures/api.lua +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -6,10 +6,76 @@ else disabled_structures = {} end local logging = minetest.settings:get_bool("mcl_logging_structures",true) +local rotations = { + "0", + "90", + "180", + "270" +} + function mcl_structures.is_disabled(structname) return table.indexof(disabled_structures,structname) ~= -1 end +local function ecb_place(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) + if param.after_placement_callback and param.p1 and param.p2 then + param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) + end +end + +function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) + local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")() + if s and s.size then + local x, z = s.size.x, s.size.z + if rotation then + if rotation == "random" and pr then + rotation = rotations[pr:next(1,#rotations)] + end + if rotation == "random" then + x = math.max(x, z) + z = x + elseif rotation == "90" or rotation == "270" then + x, z = z, x + end + end + local p1 = {x=pos.x , y=pos.y , z=pos.z } + local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} + minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} + minetest.emerge_area(p1, p2, ecb_place, param) + return true + end +end + +function mcl_structures.get_struct(file) + local localfile = modpath.."/schematics/"..file + local file, errorload = io.open(localfile, "rb") + if errorload then + minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) + return nil + end + + local allnode = file:read("*a") + file:close() + + return allnode +end + +-- Call on_construct on pos. +-- Useful to init chests from formspec. +local function init_node_construct(pos) + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + if def and def.on_construct then + def.on_construct(pos) + return true + end + return false +end +mcl_structures.init_node_construct = init_node_construct + function mcl_structures.fill_chests(p1,p2,loot,pr) for it,lt in pairs(loot) do local nodes = minetest.find_nodes_in_area(p1, p2, it) @@ -140,8 +206,9 @@ local function foundation(ground_p1,ground_p2,pos,sidelen) minetest.bulk_set_node(stone,{name=node_stone}) end -function mcl_structures.place_structure(pos, def, pr, blockseed) +function mcl_structures.place_structure(pos, def, pr, blockseed,rot) if not def then return end + if not rot then rot = "random" end local log_enabled = logging and not def.terrain_feature local y_offset = 0 if type(def.y_offset) == "function" then @@ -180,7 +247,7 @@ function mcl_structures.place_structure(pos, def, pr, blockseed) local ap = function(pos,def,pr,blockseed) end if def.after_place then ap = def.after_place end - mcl_structures.place_schematic(pp, file, "random", def.replacements, true, "place_center_x,place_center_z",function(p1, p2, size, rotation) + mcl_structures.place_schematic(pp, file, rot, def.replacements, true, "place_center_x,place_center_z",function(p1, p2, size, rotation) if def.loot then generate_loot(pp,def,pr,blockseed) end if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end return ap(pp,def,pr,blockseed,p1,p2,size,rotation) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index d771973be..cd5691fca 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -4,86 +4,6 @@ local modpath = minetest.get_modpath(modname) mcl_structures = {} -local rotations = { - "0", - "90", - "180", - "270" -} - -local function ecb_place(blockpos, action, calls_remaining, param) - if calls_remaining >= 1 then return end - minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) - if param.after_placement_callback and param.p1 and param.p2 then - param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) - end -end - -function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) - local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")() - if s and s.size then - local x, z = s.size.x, s.size.z - if rotation then - if rotation == "random" and pr then - rotation = rotations[pr:next(1,#rotations)] - end - if rotation == "random" then - x = math.max(x, z) - z = x - elseif rotation == "90" or rotation == "270" then - x, z = z, x - end - end - local p1 = {x=pos.x , y=pos.y , z=pos.z } - local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} - minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) - local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} - minetest.emerge_area(p1, p2, ecb_place, param) - return true - end -end - -function mcl_structures.get_struct(file) - local localfile = modpath.."/schematics/"..file - local file, errorload = io.open(localfile, "rb") - if errorload then - minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) - return nil - end - - local allnode = file:read("*a") - file:close() - - return allnode -end - --- Call on_construct on pos. --- Useful to init chests from formspec. -local function init_node_construct(pos) - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - if def and def.on_construct then - def.on_construct(pos) - return true - end - return false -end -mcl_structures.init_node_construct = init_node_construct - -local function dir_to_rotation(dir) - local ax, az = math.abs(dir.x), math.abs(dir.z) - if ax > az then - if dir.x < 0 then - return "270" - end - return "90" - end - if dir.z < 0 then - return "180" - end - return "0" -end - dofile(modpath.."/api.lua") dofile(modpath.."/shipwrecks.lua") dofile(modpath.."/desert_temple.lua") @@ -146,19 +66,30 @@ mcl_structures.register_structure("boulder",{ -- small boulder 3x as likely }, },true) --is spawned as a normal decoration. this is just for /spawnstruct + mcl_structures.register_structure("ice_spike_small",{ - filenames = { - modpath.."/schematics/mcl_structures_ice_spike_small.mts" - }, + filenames = { modpath.."/schematics/mcl_structures_ice_spike_small.mts" }, },true) --is spawned as a normal decoration. this is just for /spawnstruct mcl_structures.register_structure("ice_spike_large",{ sidelen = 6, - filenames = { - modpath.."/schematics/mcl_structures_ice_spike_large.mts" - }, + filenames = { modpath.."/schematics/mcl_structures_ice_spike_large.mts" }, },true) --is spawned as a normal decoration. this is just for /spawnstruct -- Debug command +local function dir_to_rotation(dir) + local ax, az = math.abs(dir.x), math.abs(dir.z) + if ax > az then + if dir.x < 0 then + return "270" + end + return "90" + end + if dir.z < 0 then + return "180" + end + return "0" +end + minetest.register_chatcommand("spawnstruct", { params = "dungeon", description = S("Generate a pre-defined structure near your position."), @@ -182,7 +113,7 @@ minetest.register_chatcommand("spawnstruct", { else for n,d in pairs(mcl_structures.registered_structures) do if n == param then - mcl_structures.place_structure(pos,d,pr,math.random()) + mcl_structures.place_structure(pos,d,pr,math.random(),rot) return true,message end end From 672e44bbb1692f1539ae70b9d5e257c2d56089a7 Mon Sep 17 00:00:00 2001 From: cora Date: Wed, 26 Oct 2022 11:47:35 +0200 Subject: [PATCH 05/14] Don't spawn multiple mobs at the same position this was originally intended to simulate group spawning i think --- mods/ENTITIES/mcl_mobs/spawning.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 371407c4e..9bc7a6780 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -716,9 +716,7 @@ if mobs_spawn then -- 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 + spawn_a_mob(pos, dimension, y_min, y_max) end end end) From d1d9f76c5d85f7ff8b723cb944469e7e2b505a55 Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 27 Oct 2022 20:18:49 +0000 Subject: [PATCH 06/14] Mobs set players on fire if they are/dogshoot strafing and enemy avoidance --- mods/ENTITIES/mcl_mobs/api.lua | 132 ++++++++++++++------------------- 1 file changed, 54 insertions(+), 78 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index a53dfd169..00f5c4450 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -13,8 +13,6 @@ local FLOP_HOR_SPEED = 1.5 local ENTITY_CRAMMING_MAX = 24 local CRAMMING_DAMAGE = 3 -local PATHFINDING = "gowp" - -- Localize local S = minetest.get_translator("mcl_mobs") @@ -320,6 +318,10 @@ local collision = function(self) local ent = object:get_luaentity() if object:is_player() or (ent and ent.is_mob and object ~= self.object) then + if object:is_player() and mcl_burning.is_burning(self.object) then + mcl_burning.set_on_fire(object, 4) + end + local pos2 = object:get_pos() local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} local force = (width + 0.5) - vector.distance( @@ -1345,6 +1347,7 @@ local do_env_damage = function(self) self.health = self.health - self.lava_damage effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + mcl_burning.set_on_fire(self.object, 10) if check_for_death(self, "lava", {type = "environment", pos = pos, node = self.standing_in}) then @@ -1361,6 +1364,7 @@ local do_env_damage = function(self) self.health = self.health - self.fire_damage effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + mcl_burning.set_on_fire(self.object, 5) if check_for_death(self, "fire", {type = "environment", pos = pos, node = self.standing_in}) then @@ -2548,11 +2552,10 @@ local function check_doors(self) if n.name:find("_b_") then local def = minetest.registered_nodes[n.name] local closed = n.name:find("_b_1") - if self.state == PATHFINDING then - if closed and def.on_rightclick then def.on_rightclick(d,n,self) end - --if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end + if t < 0.3 or t > 0.8 then + if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end else - + if closed and def.on_rightclick then def.on_rightclick(d,n,self) end end end @@ -2563,7 +2566,7 @@ local gowp_etime = 0 local function check_gowp(self,dtime) gowp_etime = gowp_etime + dtime - if gowp_etime < 0.1 then return end + if gowp_etime < 0.2 then return end gowp_etime = 0 local p = self.object:get_pos() @@ -2574,7 +2577,7 @@ local function check_gowp(self,dtime) return end - -- arrived at location, finish gowp + -- arrived at location local distance_to_targ = vector.distance(p,self._target) mcl_log("Distance to targ: ".. tostring(distance_to_targ)) if distance_to_targ < 2 then @@ -2590,79 +2593,34 @@ local function check_gowp(self,dtime) return true end - -- More pathing to be done - if self.waypoints and #self.waypoints > 0 and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then - -- We have waypoints, and no current target, or we're at it. We need a new current_target. - + if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then if not self.current_target then for i, j in pairs (self.waypoints) do + mcl_log("Way: ".. tostring(i)) mcl_log("Val: ".. tostring(j)) end + --mcl_log("nextwp:".. tostring(self.waypoints) ) end self.current_target = table.remove(self.waypoints, 1) - mcl_log("current target:".. minetest.pos_to_string(self.current_target) ) + mcl_log("current target:".. tostring(self.current_target) ) --mcl_log("type:".. type(self.current_target) ) go_to_pos(self,self.current_target) return elseif self.current_target then - -- No waypoints left, but have current target. Potentially last waypoint to go to. - - mcl_log("self.current_target: ".. minetest.pos_to_string(self.current_target)) - mcl_log("pos: ".. minetest.pos_to_string(p)) go_to_pos(self,self.current_target) - -- Do i just delete current_target, and return so we can find final path. - else - -- Not at target, no current waypoints or current_target. Through the door and should be able to path to target. - -- Is a little sensitive and could take 1 - 7 times. A 10 fail count might be a good exit condition. - - mcl_log("We don't have waypoints or a current target. Let's try to path to target") - local final_wp = minetest.find_path(p,self._target,150,1,4) - if final_wp then - mcl_log("We might be able to get to target here.") - self.waypoints = final_wp - --go_to_pos(self,self._target) - else - mcl_log("Cannot plot final route to target") - end end - --if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then - if self.current_target and (self.waypoints and #self.waypoints == 0) then - local updated_p = self.object:get_pos() - local distance_to_cur_targ = vector.distance(updated_p,self.current_target) - - mcl_log("Distance to current target: ".. tostring(distance_to_cur_targ)) - mcl_log("Current p: ".. minetest.pos_to_string(updated_p)) - --if not minetest.line_of_sight(self.object:get_pos(),self._target) then - - -- 1.6 is good. is 1.9 better? It could fail less, but will it path to door when it isn't after door - if distance_to_cur_targ > 1.9 then - mcl_log("no LOS to target: ".. minetest.pos_to_string(self.current_target)) - go_to_pos(self,self._current_target) - else - mcl_log("Let's go to target: ".. minetest.pos_to_string(self.current_target)) - self.current_target = nil - --go_to_pos(self,self._target) - self.waypoints=minetest.find_path(updated_p,self._target,150,1,4) - --if not self.waypoints then - --mcl_log("Give up ") - --self.state = "walk" - --end --give up - end - - --self.waypoints=minetest.find_path(p,self._target,150,1,4) - --if not self.waypoints then - --mcl_log("Give up ") - --self.state = "walk" - --end --give up - --self.current_target = nil + if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then + self.waypoints=minetest.find_path(p,self._target,150,1,4) + if not self.waypoints then self.state = "walk" end --give up + self.current_target = nil return end - --if not self.current_target then - --mcl_log("no path. Give up") - --self.state = "walk" - --end + if not self.current_target then + --mcl_log("no path") + self.state = "walk" + end end -- execute current state (stand, walk, run, attacks) @@ -2711,7 +2669,7 @@ local do_states = function(self, dtime) end -- npc's ordered to stand stay standing - if self.order == "stand" or self.order == "sleep" or self.order == "work" then + if self.type == "npc" or (self.order == "stand" or self.order == "sleep" or self.order == "work") then else if self.walk_chance ~= 0 @@ -2725,7 +2683,7 @@ local do_states = function(self, dtime) end end - elseif self.state == PATHFINDING then + elseif self.state == "gowp" then check_gowp(self,dtime) elseif self.state == "walk" then @@ -2978,7 +2936,7 @@ local do_states = function(self, dtime) end elseif self.attack_type == "dogfight" - or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2) + or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2) and (dist >= 9 or not self.shooter_avoid_enemy) or (self.attack_type == "dogshoot" and dist <= self.reach and dogswitch(self) == 0) then if self.fly @@ -3155,7 +3113,7 @@ local do_states = function(self, dtime) elseif self.attack_type == "shoot" or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 1) - or (self.attack_type == "dogshoot" and dist > self.reach and dogswitch(self) == 0) then + or (self.attack_type == "dogshoot" and (dist > self.reach or dist < 9 and self.shooter_avoid_enemy) and dogswitch(self) == 0) then p.y = p.y - .5 s.y = s.y + .5 @@ -3173,7 +3131,27 @@ local do_states = function(self, dtime) yaw = set_yaw(self, yaw, 0, dtime) - set_velocity(self, 0) + local stay_away_from_player = vector.new(0,0,0) + + --strafe back and fourth + + --stay away from player so as to shoot them + if dist < 9 and self.shooter_avoid_enemy then + set_animation(self, "walk") + stay_away_from_player=vector.multiply(vector.direction(p, s), 0.33) + end + + if self.strafes then + if not self.strafe_direction then + self.strafe_direction = 1.57 + end + if math.random(40) == 1 then + self.strafe_direction = self.strafe_direction*-1 + end + self.acc = vector.add(vector.multiply(vector.rotate_around_axis(vector.direction(s, p), vector.new(0,1,0), self.strafe_direction), 0.3*self.walk_velocity), stay_away_from_player) + else + set_velocity(self, 0) + end local p = self.object:get_pos() p.y = p.y + (self.collisionbox[2] + self.collisionbox[5]) / 2 @@ -3242,7 +3220,7 @@ local plane_adjacents = { local gopath_last = os.time() function mcl_mobs:gopath(self,target,callback_arrived) - if self.state == PATHFINDING then mcl_log("Already set as gowp, don't set another path until done.") return end + if self.state == "gowp" then mcl_log("Already set as gowp, don't set another path until done.") return end if os.time() - gopath_last < 15 then mcl_log("Not ready to path yet") @@ -3265,15 +3243,11 @@ function mcl_mobs:gopath(self,target,callback_arrived) --mcl_log("Found a door near") for _,v in pairs(plane_adjacents) do local pos = vector.add(d,v) - local n = minetest.get_node(pos) if n.name == "air" then wp = minetest.find_path(p,pos,150,1,4) if wp then - mcl_log("Found a path to next to door".. minetest.pos_to_string(pos)) - local other_side_of_door = vector.add(d,-v) - mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door)) - table.insert(wp, other_side_of_door) + --mcl_log("Found a path to next to door".. minetest.pos_to_string(pos)) break else @@ -3293,7 +3267,7 @@ function mcl_mobs:gopath(self,target,callback_arrived) self.callback_arrived = callback_arrived table.remove(wp,1) self.waypoints = wp - self.state = PATHFINDING + self.state = "gowp" return true else self.state = "walk" @@ -4344,7 +4318,7 @@ local mob_step = function(self, dtime) -- attack timer self.timer = self.timer + dtime - if self.state ~= "attack" and self.state ~= PATHFINDING then + if self.state ~= "attack" and self.state ~= "gowp" then if self.timer < 1 then return end @@ -4664,6 +4638,8 @@ minetest.register_entity(name, { -- MCL2 extensions + shooter_avoid_enemy = def.shooter_avoid_enemy, + strafes = def.strafes, teleport = teleport, do_teleport = def.do_teleport, spawn_class = def.spawn_class, From de73129c2b0563c9fb5f222c2f52eb292ecae1c6 Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 27 Oct 2022 20:24:33 +0000 Subject: [PATCH 07/14] Make skeleton strafe and avoid enemies --- mods/ENTITIES/mobs_mc/skeleton+stray.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index eb7c67802..18e1d99fe 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -30,6 +30,8 @@ local skeleton = { curiosity = 6, visual = "mesh", mesh = "mobs_mc_skeleton.b3d", + shooter_avoid_enemy = true, + strafes = true, textures = { { "mcl_bows_bow_0.png", -- bow "mobs_mc_skeleton.png", -- skeleton From 702ba252832a98fb87389cdf2c1f0bafa0fa66da Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 27 Oct 2022 20:42:58 +0000 Subject: [PATCH 08/14] Fix dogshooter animation when moving back --- mods/ENTITIES/mcl_mobs/api.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 00f5c4450..37c9cad86 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3137,7 +3137,7 @@ local do_states = function(self, dtime) --stay away from player so as to shoot them if dist < 9 and self.shooter_avoid_enemy then - set_animation(self, "walk") + set_animation(self, "shoot") stay_away_from_player=vector.multiply(vector.direction(p, s), 0.33) end From eed5ec6f6387039f07afcdeca0a0474fb0511b53 Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 27 Oct 2022 20:56:23 +0000 Subject: [PATCH 09/14] return pathfinding changes --- mods/ENTITIES/mcl_mobs/api.lua | 98 ++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 37c9cad86..40d26ef67 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -13,6 +13,8 @@ local FLOP_HOR_SPEED = 1.5 local ENTITY_CRAMMING_MAX = 24 local CRAMMING_DAMAGE = 3 +local PATHFINDING = "gowp" + -- Localize local S = minetest.get_translator("mcl_mobs") @@ -2552,10 +2554,11 @@ local function check_doors(self) if n.name:find("_b_") then local def = minetest.registered_nodes[n.name] local closed = n.name:find("_b_1") - if t < 0.3 or t > 0.8 then - if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end - else + if self.state == PATHFINDING then if closed and def.on_rightclick then def.on_rightclick(d,n,self) end + --if not closed and def.on_rightclick then def.on_rightclick(d,n,self) end + else + end end @@ -2566,7 +2569,7 @@ local gowp_etime = 0 local function check_gowp(self,dtime) gowp_etime = gowp_etime + dtime - if gowp_etime < 0.2 then return end + if gowp_etime < 0.1 then return end gowp_etime = 0 local p = self.object:get_pos() @@ -2577,7 +2580,7 @@ local function check_gowp(self,dtime) return end - -- arrived at location + -- arrived at location, finish gowp local distance_to_targ = vector.distance(p,self._target) mcl_log("Distance to targ: ".. tostring(distance_to_targ)) if distance_to_targ < 2 then @@ -2593,34 +2596,79 @@ local function check_gowp(self,dtime) return true end - if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then + -- More pathing to be done + if self.waypoints and #self.waypoints > 0 and ( not self.current_target or vector.distance(p,self.current_target) < 2 ) then + -- We have waypoints, and no current target, or we're at it. We need a new current_target. + if not self.current_target then for i, j in pairs (self.waypoints) do - mcl_log("Way: ".. tostring(i)) mcl_log("Val: ".. tostring(j)) end - --mcl_log("nextwp:".. tostring(self.waypoints) ) end self.current_target = table.remove(self.waypoints, 1) - mcl_log("current target:".. tostring(self.current_target) ) + mcl_log("current target:".. minetest.pos_to_string(self.current_target) ) --mcl_log("type:".. type(self.current_target) ) go_to_pos(self,self.current_target) return elseif self.current_target then + -- No waypoints left, but have current target. Potentially last waypoint to go to. + + mcl_log("self.current_target: ".. minetest.pos_to_string(self.current_target)) + mcl_log("pos: ".. minetest.pos_to_string(p)) go_to_pos(self,self.current_target) + -- Do i just delete current_target, and return so we can find final path. + else + -- Not at target, no current waypoints or current_target. Through the door and should be able to path to target. + -- Is a little sensitive and could take 1 - 7 times. A 10 fail count might be a good exit condition. + + mcl_log("We don't have waypoints or a current target. Let's try to path to target") + local final_wp = minetest.find_path(p,self._target,150,1,4) + if final_wp then + mcl_log("We might be able to get to target here.") + self.waypoints = final_wp + --go_to_pos(self,self._target) + else + mcl_log("Cannot plot final route to target") + end end - if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then - self.waypoints=minetest.find_path(p,self._target,150,1,4) - if not self.waypoints then self.state = "walk" end --give up - self.current_target = nil + --if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then + if self.current_target and (self.waypoints and #self.waypoints == 0) then + local updated_p = self.object:get_pos() + local distance_to_cur_targ = vector.distance(updated_p,self.current_target) + + mcl_log("Distance to current target: ".. tostring(distance_to_cur_targ)) + mcl_log("Current p: ".. minetest.pos_to_string(updated_p)) + --if not minetest.line_of_sight(self.object:get_pos(),self._target) then + + -- 1.6 is good. is 1.9 better? It could fail less, but will it path to door when it isn't after door + if distance_to_cur_targ > 1.9 then + mcl_log("no LOS to target: ".. minetest.pos_to_string(self.current_target)) + go_to_pos(self,self._current_target) + else + mcl_log("Let's go to target: ".. minetest.pos_to_string(self.current_target)) + self.current_target = nil + --go_to_pos(self,self._target) + self.waypoints=minetest.find_path(updated_p,self._target,150,1,4) + --if not self.waypoints then + --mcl_log("Give up ") + --self.state = "walk" + --end --give up + end + + --self.waypoints=minetest.find_path(p,self._target,150,1,4) + --if not self.waypoints then + --mcl_log("Give up ") + --self.state = "walk" + --end --give up + --self.current_target = nil return end - if not self.current_target then - --mcl_log("no path") - self.state = "walk" - end + --if not self.current_target then + --mcl_log("no path. Give up") + --self.state = "walk" + --end end -- execute current state (stand, walk, run, attacks) @@ -2669,7 +2717,7 @@ local do_states = function(self, dtime) end -- npc's ordered to stand stay standing - if self.type == "npc" or (self.order == "stand" or self.order == "sleep" or self.order == "work") then + if self.order == "stand" or self.order == "sleep" or self.order == "work" then else if self.walk_chance ~= 0 @@ -2683,7 +2731,7 @@ local do_states = function(self, dtime) end end - elseif self.state == "gowp" then + elseif self.state == PATHFINDING then check_gowp(self,dtime) elseif self.state == "walk" then @@ -3220,7 +3268,7 @@ local plane_adjacents = { local gopath_last = os.time() function mcl_mobs:gopath(self,target,callback_arrived) - if self.state == "gowp" then mcl_log("Already set as gowp, don't set another path until done.") return end + if self.state == PATHFINDING then mcl_log("Already set as gowp, don't set another path until done.") return end if os.time() - gopath_last < 15 then mcl_log("Not ready to path yet") @@ -3243,11 +3291,15 @@ function mcl_mobs:gopath(self,target,callback_arrived) --mcl_log("Found a door near") for _,v in pairs(plane_adjacents) do local pos = vector.add(d,v) + local n = minetest.get_node(pos) if n.name == "air" then wp = minetest.find_path(p,pos,150,1,4) if wp then - --mcl_log("Found a path to next to door".. minetest.pos_to_string(pos)) + mcl_log("Found a path to next to door".. minetest.pos_to_string(pos)) + local other_side_of_door = vector.add(d,-v) + mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door)) + table.insert(wp, other_side_of_door) break else @@ -3267,7 +3319,7 @@ function mcl_mobs:gopath(self,target,callback_arrived) self.callback_arrived = callback_arrived table.remove(wp,1) self.waypoints = wp - self.state = "gowp" + self.state = PATHFINDING return true else self.state = "walk" @@ -4318,7 +4370,7 @@ local mob_step = function(self, dtime) -- attack timer self.timer = self.timer + dtime - if self.state ~= "attack" and self.state ~= "gowp" then + if self.state ~= "attack" and self.state ~= PATHFINDING then if self.timer < 1 then return end From 83d92e08cab82c1f807fa68f2065ac9c494b6ad7 Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 27 Oct 2022 23:37:11 +0000 Subject: [PATCH 10/14] add an adjustable variable for avoid distance --- mods/ENTITIES/mcl_mobs/api.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 40d26ef67..e58eec00e 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2984,7 +2984,7 @@ local do_states = function(self, dtime) end elseif self.attack_type == "dogfight" - or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2) and (dist >= 9 or not self.shooter_avoid_enemy) + or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2) and (dist >= self.avoid_distance or not self.shooter_avoid_enemy) or (self.attack_type == "dogshoot" and dist <= self.reach and dogswitch(self) == 0) then if self.fly @@ -3161,7 +3161,7 @@ local do_states = function(self, dtime) elseif self.attack_type == "shoot" or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 1) - or (self.attack_type == "dogshoot" and (dist > self.reach or dist < 9 and self.shooter_avoid_enemy) and dogswitch(self) == 0) then + or (self.attack_type == "dogshoot" and (dist > self.reach or dist < self.avoid_distance and self.shooter_avoid_enemy) and dogswitch(self) == 0) then p.y = p.y - .5 s.y = s.y + .5 @@ -3184,7 +3184,7 @@ local do_states = function(self, dtime) --strafe back and fourth --stay away from player so as to shoot them - if dist < 9 and self.shooter_avoid_enemy then + if dist < self.avoid_distance and self.shooter_avoid_enemy then set_animation(self, "shoot") stay_away_from_player=vector.multiply(vector.direction(p, s), 0.33) end @@ -4692,6 +4692,7 @@ minetest.register_entity(name, { -- MCL2 extensions shooter_avoid_enemy = def.shooter_avoid_enemy, strafes = def.strafes, + avoid_distance = def.avoid_distance or 9, teleport = teleport, do_teleport = def.do_teleport, spawn_class = def.spawn_class, From 4fa1c445cc9e3c4291316d1e166e4104c9628dbc Mon Sep 17 00:00:00 2001 From: epCode Date: Fri, 28 Oct 2022 01:56:27 +0000 Subject: [PATCH 11/14] add customizable speed to mounts, not set value. --- mods/ENTITIES/mcl_mobs/mount.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index 3944613a5..95a145a4b 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -206,7 +206,7 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) -- move forwards if ctrl.up then - entity.v = entity.v + entity.accel / 10 + entity.v = entity.v + entity.accel / 10 * entity.run_velocity / 2.6 -- move backwards elseif ctrl.down then From 5378d8eba79400a97101b48a7fbcd95c9082491e Mon Sep 17 00:00:00 2001 From: epCode Date: Fri, 28 Oct 2022 01:57:15 +0000 Subject: [PATCH 12/14] add random horse speed per mc wiki --- mods/ENTITIES/mobs_mc/horse.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 0632f4d33..e4f8f72fc 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -181,6 +181,13 @@ local horse = { on_spawn = update_textures, do_custom = function(self, dtime) + if not self._horse_speed then + self._horse_speed = math.random(486, 1457)/100 + else + minetest.chat_send_all(self._horse_speed) + self.run_velocity = self._horse_speed + end + -- set needed values if not already present if not self._regentimer then self._regentimer = 0 From 2b2c2cf9cc0816b516480e558a24e7f817c008be Mon Sep 17 00:00:00 2001 From: epCode Date: Fri, 28 Oct 2022 02:00:39 +0000 Subject: [PATCH 13/14] remove debug and remove resetting value 20 times per second --- mods/ENTITIES/mobs_mc/horse.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index e4f8f72fc..d1c865968 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -183,8 +183,7 @@ local horse = { if not self._horse_speed then self._horse_speed = math.random(486, 1457)/100 - else - minetest.chat_send_all(self._horse_speed) + elseif self.run_velocity ~= self._horse_speed then self.run_velocity = self._horse_speed end From dc84b28d548233d7d8d76e19103611d6d87dfda2 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 29 Oct 2022 11:18:32 +0200 Subject: [PATCH 14/14] Fix warning in mcl_dye --- mods/ITEMS/mcl_dye/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index 1d39a0598..73884856a 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -156,7 +156,7 @@ function mcl_dye.register_on_bone_meal_apply(func) table.insert(mcl_dye.bone_meal_callbacks, func) end -local function apply_bone_meal(pointed_thing) +local function apply_bone_meal(pointed_thing,user) -- Bone meal currently spawns all flowers found in the plains. local flowers_table_plains = { "mcl_flowers:dandelion",