From 863a9bb1cb36d6619d37291c9a9fe2abafe46011 Mon Sep 17 00:00:00 2001 From: Ombridride Date: Sun, 14 Dec 2014 23:54:40 +0100 Subject: [PATCH] Update riesenpilz And add a new dependency : vector_extras --- mods/riesenpilz/{README.txt => LICENSE.txt} | 5 - mods/riesenpilz/README.md | 14 + mods/riesenpilz/depends.txt | 2 +- mods/riesenpilz/init.lua | 462 +++++++++++++----- mods/riesenpilz/mapgen.lua | 93 ++-- mods/riesenpilz/rest/old_mapgen.lua | 54 +- .../textures/maptools_super_apple_bottom.png | Bin 350 -> 0 bytes .../textures/maptools_super_apple_side.png | Bin 360 -> 0 bytes .../textures/maptools_super_apple_top.png | Bin 444 -> 0 bytes .../textures/riesenpilz_brown45_bottom.png | Bin 105 -> 119 bytes .../textures/riesenpilz_brown45_top.png | Bin 105 -> 0 bytes mods/vector_extras/.gitignore | 4 + mods/vector_extras/README.txt | 2 + mods/vector_extras/init.lua | 382 +++++++++++++++ mods/vector_extras/vector_meta.lua | 183 +++++++ 15 files changed, 1017 insertions(+), 184 deletions(-) rename mods/riesenpilz/{README.txt => LICENSE.txt} (67%) create mode 100755 mods/riesenpilz/README.md delete mode 100755 mods/riesenpilz/textures/maptools_super_apple_bottom.png delete mode 100755 mods/riesenpilz/textures/maptools_super_apple_side.png delete mode 100755 mods/riesenpilz/textures/maptools_super_apple_top.png delete mode 100755 mods/riesenpilz/textures/riesenpilz_brown45_top.png create mode 100755 mods/vector_extras/.gitignore create mode 100755 mods/vector_extras/README.txt create mode 100755 mods/vector_extras/init.lua create mode 100755 mods/vector_extras/vector_meta.lua diff --git a/mods/riesenpilz/README.txt b/mods/riesenpilz/LICENSE.txt similarity index 67% rename from mods/riesenpilz/README.txt rename to mods/riesenpilz/LICENSE.txt index d9e7a6aa..f397d18b 100755 --- a/mods/riesenpilz/README.txt +++ b/mods/riesenpilz/LICENSE.txt @@ -3,8 +3,3 @@ — glowshroom and lavashroom from bas080's plants mod (WTFPL) — parasol mushroom from a mod called mushrooms (WTFPL) — "45" mushrooms from r01922090's mush45 mod (WTFPL) - -TODO: -— add giant nethershroom -— finish supporting the mushrooms mod -— generate mushrooms not only in mushroom biomes diff --git a/mods/riesenpilz/README.md b/mods/riesenpilz/README.md new file mode 100755 index 00000000..d88b3ac9 --- /dev/null +++ b/mods/riesenpilz/README.md @@ -0,0 +1,14 @@ +[Mod] riesenpilz [riesenpilz] + +**Depends:** see [depends.txt](https://raw.githubusercontent.com/HybridDog/riesenpilz/master/depends.txt) +**License:** see [LICENSE.txt](https://raw.githubusercontent.com/HybridDog/riesenpilz/master/LICENSE.txt) +**Download:** [zip](https://github.com/HybridDog/riesenpilz/archive/master.zip), [tar.gz](https://github.com/HybridDog/riesenpilz/archive/master.tar.gz) + +![I'm a screenshot!](https://cloud.githubusercontent.com/assets/3192173/5332059/421c735a-7e47-11e4-88cc-b9ed90b659a8.png) + +If you got ideas or found bugs, please tell them to me. + + +TODO: +— add giant nethershroom +— finish supporting the mushrooms mod diff --git a/mods/riesenpilz/depends.txt b/mods/riesenpilz/depends.txt index 3a7daa1d..c24e6b10 100755 --- a/mods/riesenpilz/depends.txt +++ b/mods/riesenpilz/depends.txt @@ -1,2 +1,2 @@ default - +vector_extras diff --git a/mods/riesenpilz/init.lua b/mods/riesenpilz/init.lua index 67dba58d..5aac5521 100755 --- a/mods/riesenpilz/init.lua +++ b/mods/riesenpilz/init.lua @@ -13,13 +13,16 @@ local function r_area(manip, width, height, pos) return VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) end +riesenpilz.vm_update = true local function set_vm_data(manip, nodes, pos, t1, name) manip:set_data(nodes) manip:write_to_map() riesenpilz.inform("a "..name.." mushroom grew at ("..pos.x.."|"..pos.y.."|"..pos.z..")", 3, t1) - local t1 = os.clock() - manip:update_map() - riesenpilz.inform("map updated", 3, t1) + if riesenpilz.vm_update then + local t1 = os.clock() + manip:update_map() + riesenpilz.inform("map updated", 3, t1) + end end --Growing Functions @@ -371,14 +374,175 @@ minetest.register_node(":default:apple", { --Mushroom Nodes -local function pilz(name, desc, b, burntime) - burntime = burntime or 1 +local mushrooms_list = { + ["brown"] = { + description = "brown mushroom", + box = { + {-0.15, -0.2, -0.15, 0.15, -0.1, 0.15}, + {-0.2, -0.3, -0.2, 0.2, -0.2, 0.2}, + {-0.05, -0.5, -0.05, 0.05, -0.3, 0.05} + }, + growing = { + r = {min=3, max=4}, + grounds = {soil=1, crumbly=3}, + neighbours = {"default:tree"}, + light = {min=1, max=7}, + interval = 100, + chance = 18, + }, + }, + ["red"] = { + description = "red mushroom", + box = { + {-1/16, -8/16, -1/16, 1/16, -6/16, 1/16}, + {-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, + {-4/16, -5/16, -4/16, 4/16, -4/16, 4/16}, + {-3/16, -4/16, -3/16, 3/16, -3/16, 3/16}, + {-2/16, -3/16, -2/16, 2/16, -2/16, 2/16} + }, + growing = { + r = {min=4, max=5}, + grounds = {soil=2}, + neighbours = {"default:water_flowing"}, + light = {min=4, max=13}, + interval = 50, + chance = 30, + }, + }, + ["fly_agaric"] = { + description = "fly agaric", + box = { + {-0.05, -0.5, -0.05, 0.05, 1/20, 0.05}, + {-3/20, -6/20, -3/20, 3/20, 0, 3/20}, + {-4/20, -2/20, -4/20, 4/20, -4/20, 4/20} + }, + growing = { + r = 4, + grounds = {soil=1, crumbly=3}, + neighbours = {"default:pinetree"}, + light = {min=2, max=10}, + interval = 101, + chance = 30, + }, + }, + ["lavashroom"] = { + description = "Lavashroom", + box = { + {-1/16, -8/16, -1/16, 1/16, -6/16, 1/16}, + {-2/16, -6/16, -2/16, 2/16, 0, 2/16}, + {-3/16, -5/16, -3/16, 3/16, -1/16, 3/16}, + {-4/16, -4/16, -4/16, 4/16, -2/16, 4/16} + }, + growing = { + r = {min=5, max=6}, + grounds = {cracky=3}, + neighbours = {"default:lava_source"}, + light = {min=10, max=14}, + interval = 1010, + chance = 60, + }, + }, + ["glowshroom"] = { + description = "Glowshroom", + box = { + {-1/16, -8/16, -1/16, 1/16, -1/16, 1/16}, + {-2/16, -3/16, -2/16, 2/16, -2/16, 2/16}, + {-3/16, -5/16, -3/16, 3/16, -3/16, 3/16}, + {-3/16, -7/16, -3/16, -2/16, -5/16, -2/16}, + {3/16, -7/16, -3/16, 2/16, -5/16, -2/16}, + {-3/16, -7/16, 3/16, -2/16, -5/16, 2/16}, + {3/16, -7/16, 3/16, 2/16, -5/16, 2/16} + }, + growing = { + r = 3, + grounds = {soil=1, crumbly=3}, + neighbours = {"default:stone"}, + light = 0, + interval = 710, + chance = 320, + }, + }, + ["nether_shroom"] = { + description = "Nether mushroom", + box = { + {-1/16, -8/16, -1/16, 1/16, -2/16, 1/16}, + {-2/16, -6/16, -2/16, 2/16, -5/16, 2/16}, + {-3/16, -2/16, -3/16, 3/16, 0, 3/16}, + {-4/16, -1/16, -4/16, 4/16, 1/16,-2/16}, + {-4/16, -1/16, 2/16, 4/16, 1/16, 4/16}, + {-4/16, -1/16, -2/16,-2/16, 1/16, 2/16}, + { 2/16, -1/16, -2/16, 4/16, 1/16, 2/16} + }, + burntime = 6, + }, + ["parasol"] = { + description = "white parasol mushroom", + box = { + {-1/16, -8/16, -1/16, 1/16, 0, 1/16}, + {-2/16, -6/16, -2/16, 2/16, -5/16, 2/16}, + {-5/16, -4/16, -5/16, 5/16, -3/16, 5/16}, + {-4/16, -3/16, -4/16, 4/16, -2/16, 4/16}, + {-3/16, -2/16, -3/16, 3/16, -1/16, 3/16} + }, + growing = { + r = {min=3, max=5}, + grounds = {soil=1, crumbly=3}, + neighbours = {"default:pinetree"}, + light = {min=1, max=11}, + interval = 51, + chance = 36, + }, + }, + ["red45"] = { + description = "45 red mushroom", + box = { + {-1/16, -0.5, -1/16, 1/16, 1/8, 1/16}, + {-3/16, 1/8, -3/16, 3/16, 1/4, 3/16}, + {-5/16, -1/4, -5/16, -1/16, 1/8, -1/16}, + {1/16, -1/4, -5/16, 5/16, 1/8, -1/16}, + {-5/16, -1/4, 1/16, -1/16, 1/8, 5/16}, + {1/16, -1/4, 1/16, 5/16, 1/8, 5/16} + }, + growing = { + r = {min=3, max=4}, + grounds = {soil=2}, + neighbours = {"default:water_source"}, + light = {min=2, max=7}, + interval = 1000, + chance = 180, + }, + }, + ["brown45"] = { + description = "45 brown mushroom", + box = { + {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, + {-3/8, 1/8, -7/16, 3/8, 1/4, 7/16}, + {-7/16, 1/8, -3/8, 7/16, 1/4, 3/8}, + {-3/8, 1/4, -3/8, 3/8, 5/16, 3/8}, + {-3/8, 1/16, -3/8, 3/8, 1/8, 3/8} + }, + growing = { + r = {min=2, max=3}, + grounds = {tree=1}, + neighbours = {"default:water_flowing"}, + light = {min=7, max=11}, + interval = 100, + chance = 20, + }, + }, +} + +local abm_allowed = true +local disallowed_ps = {} +for name,i in pairs(mushrooms_list) do + local burntime = i.burntime or 1 local box = { type = "fixed", - fixed = b + fixed = i.box } - minetest.register_node("riesenpilz:"..name, { - description = desc, + local nd = "riesenpilz:"..name + minetest.register_node(nd, { + description = i.description, tiles = {"riesenpilz_"..name.."_top.png", "riesenpilz_"..name.."_bottom.png", "riesenpilz_"..name.."_side.png"}, inventory_image = "riesenpilz_"..name.."_side.png", walkable = false, @@ -391,142 +555,194 @@ local function pilz(name, desc, b, burntime) selection_box = box, furnace_burntime = burntime }) + + local g = i.growing + + if g then + local grounds = g.grounds + local nds = {} + for n in pairs(grounds) do + table.insert(nds, "group:"..n) + end + + local nbs = table.copy(g.neighbours) + table.insert(nbs, "air") + + local rmin, rmax, lmin, lmax + + local r = g.r + if type(r) == "table" then + rmin = r.min + rmax = r.max + else + rmin = r or 3 + rmax = rmin + end + + local l = g.light + if type(l) == "table" then + lmin = l.min + lmax = l.max + else + lmin = l or 3 + lmax = lmin + end + + minetest.register_abm({ + nodenames = nds, + neighbors = g.neighbours, + interval = g.interval, + chance = g.chance, + action = function(pos, node) + if not abm_allowed then + return + end + + -- don't try to spawn them on the same positions again + for _,p in pairs(disallowed_ps) do + if vector.equals(p, pos) then + return + end + end + + -- don't spawn mushroom circles next to other ones + if minetest.find_node_near(pos, rmax, nd) then + return + end + + -- spawn them around the right nodes + local data = minetest.registered_nodes[node.name] + if not data + or not data.groups then + return + end + local groups = data.groups + for n,i in pairs(grounds) do + if groups[n] ~= i then + return + end + end + + -- find their neighbours + for _,n in pairs(nbs) do + if not minetest.find_node_near(pos, rmin, n) then + return + end + end + + -- should disallow lag + abm_allowed = false + minetest.after(2, function() abm_allowed = true end) + table.insert(disallowed_ps, pos) + + -- witch circles + local ps = {} + for _,p in pairs(vector.circle(math.random(rmin, rmax))) do + local p = vector.add(pos, p) + + -- currently 3 is used here, approved by its use in the mapgen + if math.random(3) == 1 then + + -- don't only use the current y for them + for y = 1,-1,-1 do + local pos = {x=p.x, y=p.y+y, z=p.z} + if minetest.get_node(pos).name ~= "air" then + break + end + local f = minetest.get_node({x=p.x, y=p.y+y-1, z=p.z}).name + if f ~= "air" then + + -- they grown on walkable, cubic nodes + local data = minetest.registered_nodes[f] + if data + and data.walkable + and (not data.drawtype + or data.drawtype == "normal" + ) then + + -- they also need specific light strengths + local light = minetest.get_node_light(pos, 0.5) + if light >= lmin + and light <= lmax then + table.insert(ps, pos) + end + end + break + end + end + end + end + if not ps[1] then + return + end + + -- place them + for _,p in pairs(ps) do + minetest.set_node(p, {name=nd}) + end + print("[riesenpilz] "..nd.." mushrooms grew at "..minetest.pos_to_string(pos)) + end + }) + end end -local BOX = { - RED = { - {-1/16, -8/16, -1/16, 1/16, -6/16, 1/16}, - {-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, - {-4/16, -5/16, -4/16, 4/16, -4/16, 4/16}, - {-3/16, -4/16, -3/16, 3/16, -3/16, 3/16}, - {-2/16, -3/16, -2/16, 2/16, -2/16, 2/16} - }, - BROWN = { - {-0.15, -0.2, -0.15, 0.15, -0.1, 0.15}, - {-0.2, -0.3, -0.2, 0.2, -0.2, 0.2}, - {-0.05, -0.5, -0.05, 0.05, -0.3, 0.05} - }, - FLY_AGARIC = { - {-0.05, -0.5, -0.05, 0.05, 1/20, 0.05}, - {-3/20, -6/20, -3/20, 3/20, 0, 3/20}, - {-4/20, -2/20, -4/20, 4/20, -4/20, 4/20} - }, - LAVASHROOM = { - {-1/16, -8/16, -1/16, 1/16, -6/16, 1/16}, - {-2/16, -6/16, -2/16, 2/16, 0, 2/16}, - {-3/16, -5/16, -3/16, 3/16, -1/16, 3/16}, - {-4/16, -4/16, -4/16, 4/16, -2/16, 4/16} - }, - GLOWSHROOM = { - {-1/16, -8/16, -1/16, 1/16, -1/16, 1/16}, - {-2/16, -3/16, -2/16, 2/16, -2/16, 2/16}, - {-3/16, -5/16, -3/16, 3/16, -3/16, 3/16}, - {-3/16, -7/16, -3/16, -2/16, -5/16, -2/16}, - {3/16, -7/16, -3/16, 2/16, -5/16, -2/16}, - {-3/16, -7/16, 3/16, -2/16, -5/16, 2/16}, - {3/16, -7/16, 3/16, 2/16, -5/16, 2/16} - }, - NETHER_SHROOM = { - {-1/16, -8/16, -1/16, 1/16, -2/16, 1/16}, - {-2/16, -6/16, -2/16, 2/16, -5/16, 2/16}, - {-3/16, -2/16, -3/16, 3/16, 0, 3/16}, - {-4/16, -1/16, -4/16, 4/16, 1/16,-2/16}, - {-4/16, -1/16, 2/16, 4/16, 1/16, 4/16}, - {-4/16, -1/16, -2/16,-2/16, 1/16, 2/16}, - { 2/16, -1/16, -2/16, 4/16, 1/16, 2/16} - }, - PARASOL = { - {-1/16, -8/16, -1/16, 1/16, 0, 1/16}, - {-2/16, -6/16, -2/16, 2/16, -5/16, 2/16}, - {-5/16, -4/16, -5/16, 5/16, -3/16, 5/16}, - {-4/16, -3/16, -4/16, 4/16, -2/16, 4/16}, - {-3/16, -2/16, -3/16, 3/16, -1/16, 3/16} - }, - RED45 = { - {-1/16, -0.5, -1/16, 1/16, 1/8, 1/16}, - {-3/16, 1/8, -3/16, 3/16, 1/4, 3/16}, - {-5/16, -1/4, -5/16, -1/16, 1/8, -1/16}, - {1/16, -1/4, -5/16, 5/16, 1/8, -1/16}, - {-5/16, -1/4, 1/16, -1/16, 1/8, 5/16}, - {1/16, -1/4, 1/16, 5/16, 1/8, 5/16} - }, - BROWN45 = { - {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, - {-3/8, 1/8, -7/16, 3/8, 1/4, 7/16}, - {-7/16, 1/8, -3/8, 7/16, 1/4, 3/8}, - {-3/8, 1/4, -3/8, 3/8, 5/16, 3/8}, - {-3/8, 1/16, -3/8, 3/8, 1/8, 3/8} - }, -} - - -local mushrooms_list = { - {"brown", "Brown Mushroom", BOX.BROWN}, - {"red", "Red Mushroom", BOX.RED}, - {"fly_agaric", "Fly Agaric", BOX.FLY_AGARIC}, - {"lavashroom", "Lavashroom", BOX.LAVASHROOM}, - {"glowshroom", "Glowshroom", BOX.GLOWSHROOM}, - {"nether_shroom", "Nether Mushroom", BOX.NETHER_SHROOM, 6}, - {"parasol", "Parasol Mushroom", BOX.PARASOL}, - {"red45", "45 Brown Mushroom", BOX.RED45}, - {"brown45", "45 Red Mushroom", BOX.BROWN45}, -} - -for _,i in ipairs(mushrooms_list) do - pilz(i[1], i[2], i[3], i[4]) -end +-- disallow abms when the server is lagging +minetest.register_globalstep(function(dtime) + if dtime > 0.5 + and abm_allowed then + abm_allowed = false + minetest.after(2, function() abm_allowed = true end) + --minetest.chat_send_all(dtime) + end +end) --Mushroom Blocks -local function pilznode(name, desc, textures, sapling) -minetest.register_node("riesenpilz:"..name, { - description = desc, - tiles = textures, - groups = {oddly_breakable_by_hand=3}, - drop = {max_items = 1, - items = {{items = {"riesenpilz:"..sapling},rarity = 20,}, - {items = {"riesenpilz:"..name},rarity = 1,}}}, -}) -end - - local r = "riesenpilz_" local h = "head_" local s = "stem_" local rh = r..h local rs = r..s -local GS = "Giant Mushroom " -local GSH = GS.."Head " -local GSS = GS.."Stem " +local GS = "giant mushroom " +local GSH = GS.."head " +local GSS = GS.."stem " local pilznode_list = { - {"stem", GSS.."Beige", {rs.."top.png", rs.."top.png", "riesenpilz_stem.png"}, "stem"}, - {s.."brown", GSS.."Brown", {rs.."top.png", rs.."top.png", rs.."brown.png"}, s.."brown"}, - {s.."blue", GSS.."Blue", {rs.."top.png",rs.."top.png",rs.."blue.png"}, s.."blue"}, - {"lamellas", "Giant Mushroom Lamella", {"riesenpilz_lamellas.png"}, "lamellas"}, - {h.."red", GSH.."Red", {"riesenpilz_head.png", "riesenpilz_lamellas.png", "riesenpilz_head.png"}, "red"}, - {h.."orange", GSH.."Orange", {rh.."orange.png"}, "lavashroom"}, - {h.."yellow", GSH.."Yellow", {rh.."yellow.png"}, "lavashroom"}, - {h.."brown", GSH.."Brown", {r.."brown_top.png", r.."lamellas.png", r.."brown_top.png"}, "brown"}, - {h.."brown_full", GSH.."Full Brown", {r.."brown_top.png"},"brown"}, - {h.."blue_bright", GSH.."Blue Bright", {rh.."blue_bright.png"},"glowshroom"}, - {h.."blue", GSH.."Blue", {rh.."blue.png"},"glowshroom"}, - {h.."white", GSH.."White", {rh.."white.png"},"parasol"}, - {h.."binge", GSH.."Binge", {rh.."binge.png", rh.."white.png", rh.."binge.png"},"parasol"}, - {h.."brown_bright", GSH.."Brown Bright", {rh.."brown_bright.png", rh.."white.png", rh.."brown_bright.png"},"parasol"}, + {"stem", GSS.."beige", {rs.."top.png", rs.."top.png", "riesenpilz_stem.png"}, "stem"}, + {s.."brown", GSS.."brown", {rs.."top.png", rs.."top.png", rs.."brown.png"}, s.."brown"}, + {s.."blue", GSS.."blue", {rs.."top.png",rs.."top.png",rs.."blue.png"}, s.."blue"}, + {"lamellas", "giant mushroom lamella", {"riesenpilz_lamellas.png"}, "lamellas"}, + {h.."red", GSH.."red", {"riesenpilz_head.png", "riesenpilz_lamellas.png", "riesenpilz_head.png"}, "red"}, + {h.."orange", GSH.."orange", {rh.."orange.png"}, "lavashroom"}, + {h.."yellow", GSH.."yellow", {rh.."yellow.png"}, "lavashroom"}, + {h.."brown", GSH.."brown", {r.."brown_top.png", r.."lamellas.png", r.."brown_top.png"}, "brown"}, + {h.."brown_full", GSH.."full brown", {r.."brown_top.png"},"brown"}, + {h.."blue_bright", GSH.."blue bright", {rh.."blue_bright.png"},"glowshroom"}, + {h.."blue", GSH.."blue", {rh.."blue.png"},"glowshroom"}, + {h.."white", GSH.."white", {rh.."white.png"},"parasol"}, + {h.."binge", GSH.."binge", {rh.."binge.png", rh.."white.png", rh.."binge.png"},"parasol"}, + {h.."brown_bright", GSH.."brown bright", {rh.."brown_bright.png", rh.."white.png", rh.."brown_bright.png"},"parasol"}, } for _,i in ipairs(pilznode_list) do - pilznode(i[1], i[2], i[3], i[4]) + local name, desc, textures, sapling = unpack(i) + minetest.register_node("riesenpilz:"..name, { + description = desc, + tiles = textures, + groups = {oddly_breakable_by_hand=3}, + drop = {max_items = 1, + items = {{items = {"riesenpilz:"..sapling},rarity = 20,}, + {items = {"riesenpilz:"..name},rarity = 1,}}}, + }) end minetest.register_node("riesenpilz:head_red_side", { - description = "Giant Mushroom Head Side", + description = "giant mushroom head red side", tiles = {"riesenpilz_head.png", "riesenpilz_lamellas.png", "riesenpilz_head.png", "riesenpilz_head.png", "riesenpilz_head.png", "riesenpilz_lamellas.png"}, paramtype2 = "facedir", @@ -537,7 +753,7 @@ minetest.register_node("riesenpilz:head_red_side", { }) minetest.register_node("riesenpilz:ground", { - description = "Grass?", + description = "dirt with rotten grass", tiles = {"riesenpilz_ground_top.png","default_dirt.png","default_dirt.png^riesenpilz_ground_side.png"}, groups = {crumbly=3}, sounds = default.node_sound_dirt_defaults(), @@ -580,7 +796,7 @@ c = { minetest.register_tool("riesenpilz:growingtool", { - description = "Growingtool", + description = "growingtool", inventory_image = "riesenpilz_growingtool.png", }) diff --git a/mods/riesenpilz/mapgen.lua b/mods/riesenpilz/mapgen.lua index 56122e54..6195c9c0 100755 --- a/mods/riesenpilz/mapgen.lua +++ b/mods/riesenpilz/mapgen.lua @@ -42,7 +42,7 @@ local function define_contents() end -local function find_grond(a,list) +local function find_ground(a,list) for _,nam in ipairs(list) do if a == nam then return true @@ -52,14 +52,26 @@ local function find_grond(a,list) end +local function fix_light(minp, maxp) + local manip = minetest.get_voxel_manip() + local emerged_pos1, emerged_pos2 = manip:read_from_map(minp, maxp) + local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2}) + local nodes = manip:get_data() + + manip:set_data(nodes) + manip:write_to_map() + manip:update_map() +end + +local data, area function riesenpilz_circle(nam, pos, radius, chance) - for i = -radius, radius, 1 do - for j = -radius, radius, 1 do - if math.floor( math.sqrt(i^2+j^2) +0.5) == radius - and data[area:index(pos.x+i, pos.y, pos.z+j)] == c.air - and pr:next(1,chance) == 1 - and data[area:index(pos.x+i, pos.y-1, pos.z+j)] == c.ground then - data[area:index(pos.x+i, pos.y, pos.z+j)] = nam + for _,p in pairs(vector.circle(radius)) do + if pr:next(1,chance) == 1 then + local p = vector.add(pos, p) + local p_p = area:indexp(p) + if data[p_p] == c.air + and data[area:index(p.x, p.y-1, p.z)] == c.ground then + data[p_p] = nam end end end @@ -91,12 +103,28 @@ minetest.register_on_generated(function(minp, maxp, seed) end local x0,z0,x1,z1 = minp.x,minp.z,maxp.x,maxp.z -- Assume X and Z lengths are equal - --local env = minetest|.env --Should make things a bit faster. - local perlin1 = minetest.get_perlin(51,3, 0.5, perlin_scale) --Get map specific perlin + local env = minetest.env --Should make things a bit faster. + local perlin1 = env:get_perlin(51,3, 0.5, perlin_scale) --Get map specific perlin + + if not riesenpilz.always_generate then + local biome_allowed + for x = x0, x1, 16 do + for z = z0, z1, 16 do + if perlin1:get2d({x=x, y=z}) > nosmooth_rarity then + biome_allowed = true + break + end + end + end + if not biome_allowed then + return + end + end --[[if not (perlin1:get2d({x=x0, y=z0}) > 0.53) and not (perlin1:get2d({x=x1, y=z1}) > 0.53) and not (perlin1:get2d({x=x0, y=z1}) > 0.53) and not (perlin1:get2d({x=x1, y=z0}) > 0.53) - and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > 0.53) then]] + and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > 0.53) then + if not riesenpilz.always_generate and not ( perlin1:get2d( {x=x0, y=z0} ) > nosmooth_rarity ) --top left and not ( perlin1:get2d( { x = x0 + ( (x1-x0)/2), y=z0 } ) > nosmooth_rarity )--top middle @@ -108,7 +136,7 @@ minetest.register_on_generated(function(minp, maxp, seed) and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > nosmooth_rarity) --middle and not (perlin1:get2d({x=x0, y=z1+((z1-z0)/2)}) > nosmooth_rarity) then --bottom middle return - end + end]] local t1 = os.clock() riesenpilz.inform("tries to generate a giant mushroom biome at: x=["..minp.x.."; "..maxp.x.."]; y=["..minp.y.."; "..maxp.y.."]; z=["..minp.z.."; "..maxp.z.."]", 2) @@ -137,9 +165,9 @@ minetest.register_on_generated(function(minp, maxp, seed) end end --[[remove usual stuff - local trees = minetest.find_nodes_in_area(minp, maxp, USUAL_STUFF) + local trees = env:find_nodes_in_area(minp, maxp, USUAL_STUFF) for i,v in pairs(trees) do - minetest.remove_node(v) + env:remove_node(v) end]] @@ -184,7 +212,7 @@ minetest.register_on_generated(function(minp, maxp, seed) local ground_y = nil --Definition des Bodens: -- for y=maxp.y,0,-1 do for y=maxp.y,1,-1 do - if find_grond(data[area:index(x, y, z)], c.GROUND) then + if find_ground(data[area:index(x, y, z)], c.GROUND) then ground_y = y break end @@ -221,15 +249,15 @@ minetest.register_on_generated(function(minp, maxp, seed) elseif pr:next(1,5000) == 1 then riesenpilz_circle(c.riesenpilz_glowshroom, boden, 3, 3) --[[elseif pr:next(1,80) == 1 then - minetest.add_node(boden, {name="riesenpilz:brown"}) + env:add_node(boden, {name="riesenpilz:brown"}) elseif pr:next(1,90) == 1 then - minetest.add_node(boden, {name="riesenpilz:red"}) + env:add_node(boden, {name="riesenpilz:red"}) elseif pr:next(1,100) == 1 then - minetest.add_node(boden, {name="riesenpilz:fly_agaric"}) + env:add_node(boden, {name="riesenpilz:fly_agaric"}) elseif pr:next(1,4000) == 1 then - minetest.add_node(boden, {name="riesenpilz:lavashroom"}) + env:add_node(boden, {name="riesenpilz:lavashroom"}) elseif pr:next(1,5000) == 1 then - minetest.add_node(boden, {name="riesenpilz:glowshroom"})]] + env:add_node(boden, {name="riesenpilz:glowshroom"})]] elseif pr:next(1,380) == 1 then tab[num] = {1, boden} num = num+1 @@ -251,10 +279,14 @@ minetest.register_on_generated(function(minp, maxp, seed) end end vm:set_data(data) - vm:update_liquids() vm:write_to_map() riesenpilz.inform("ground finished", 2, t1) + local t2 = os.clock() + local single_map_update = #tab > 3 + if single_map_update then + riesenpilz.vm_update = false + end for _,v in pairs(tab) do local p = v[2] local m = v[1] @@ -270,13 +302,18 @@ minetest.register_on_generated(function(minp, maxp, seed) riesenpilz_parasol(p) end end + if single_map_update then + riesenpilz.vm_update = true + fix_light(minp, maxp) + end riesenpilz.inform("giant shrooms generated", 2, t2) + riesenpilz.inform("done", 1, t1) end) --[[ if maxp.y < -10 then local x0,z0,x1,z1 = minp.x,minp.z,maxp.x,maxp.z -- Assume X and Z lengths are equal - local env = minetest.|env --Should make things a bit faster. - local perlin1 = minetest.get_perlin(11,3, 0.5, 200) --Get map specific perlin + local env = minetest.env --Should make things a bit faster. + local perlin1 = env:get_perlin(11,3, 0.5, 200) --Get map specific perlin --[if not (perlin1:get2d({x=x0, y=z0}) > 0.53) and not (perlin1:get2d({x=x1, y=z1}) > 0.53) and not (perlin1:get2d({x=x0, y=z1}) > 0.53) and not (perlin1:get2d({x=x1, y=z0}) > 0.53) @@ -303,12 +340,12 @@ end) for y=minp.y,maxp.y,1 do local pos = {x=x, y=y, z=z} - if minetest.get_node(pos).name == "air" - and minetest.get_node({x=x, y=y-1, z=z}).name == "default:stone" + if env:get_node(pos).name == "air" + and env:get_node({x=x, y=y-1, z=z}).name == "default:stone" and pr:next(1,40) == 33 - and minetest.find_node_near(pos, 4, "group:igniter") - and not minetest.find_node_near(pos, 3, "group:igniter") then - minetest.add_node(pos, {name="riesenpilz:lavashroom"}) + and env:find_node_near(pos, 4, "group:igniter") + and not env:find_node_near(pos, 3, "group:igniter") then + env:add_node(pos, {name="riesenpilz:lavashroom"}) end end end diff --git a/mods/riesenpilz/rest/old_mapgen.lua b/mods/riesenpilz/rest/old_mapgen.lua index 20ae0a83..67661469 100755 --- a/mods/riesenpilz/rest/old_mapgen.lua +++ b/mods/riesenpilz/rest/old_mapgen.lua @@ -6,10 +6,10 @@ function riesenpilz_circle(nam, pos, radius, rand, seed) if math.floor( math.sqrt(i^2+j^2) +0.5) == radius then random = PseudoRandom(ra) p={x=pos.x+i, y=pos.y, z=pos.z+j} - if minetest.get_node(p).name == "air" + if minetest.env:get_node(p).name == "air" and random:next(1,rand) == 1 - and minetest.get_node({x=pos.x+i, y=pos.y-1, z=pos.z+j}).name ~= "air" then - minetest.add_node(p, {name=nam}) + and minetest.env:get_node({x=pos.x+i, y=pos.y-1, z=pos.z+j}).name ~= "air" then + minetest.env:add_node(p, {name=nam}) end ra = ra+1 end @@ -32,10 +32,10 @@ function riesenpilz_circle(nam, pos, radius, chance) for i = -radius, radius, 1 do for j = -radius, radius, 1 do if math.floor( math.sqrt(i^2+j^2) +0.5) == radius - and minetest.get_node({x=pos.x+i, y=pos.y, z=pos.z+j}).name == "air" + and minetest.env:get_node({x=pos.x+i, y=pos.y, z=pos.z+j}).name == "air" and math.random(1,chance) == 1 - and minetest.get_node({x=pos.x+i, y=pos.y-1, z=pos.z+j}).name == "riesenpilz:ground" then - minetest.add_node({x=pos.x+i, y=pos.y, z=pos.z+j}, {name=nam}) + and minetest.env:get_node({x=pos.x+i, y=pos.y-1, z=pos.z+j}).name == "riesenpilz:ground" then + minetest.env:add_node({x=pos.x+i, y=pos.y, z=pos.z+j}, {name=nam}) end end end @@ -43,7 +43,7 @@ end local function find_ground(pos, nodes) for _, evground in ipairs(nodes) do - if minetest.get_node(pos).name == evground then + if minetest.env:get_node(pos).name == evground then return true end end @@ -55,8 +55,8 @@ USUAL_STUFF = {"default:leaves","default:apple","default:tree","default:cactus", minetest.register_on_generated(function(minp, maxp, seed) if maxp.y >= -10 then local x0,z0,x1,z1 = minp.x,minp.z,maxp.x,maxp.z -- Assume X and Z lengths are equal - --local env = minetest.|env --Should make things a bit faster. - local perlin1 = minetest.get_perlin(11,3, 0.5, 200) --Get map specific perlin + local env = minetest.env --Should make things a bit faster. + local perlin1 = env:get_perlin(11,3, 0.5, 200) --Get map specific perlin --[[if not (perlin1:get2d({x=x0, y=z0}) > 0.53) and not (perlin1:get2d({x=x1, y=z1}) > 0.53) and not (perlin1:get2d({x=x0, y=z1}) > 0.53) and not (perlin1:get2d({x=x1, y=z0}) > 0.53) @@ -77,9 +77,9 @@ minetest.register_on_generated(function(minp, maxp, seed) local pr = PseudoRandom(seed+68) --remove usual stuff - local trees = minetest.find_nodes_in_area(minp, maxp, USUAL_STUFF) + local trees = env:find_nodes_in_area(minp, maxp, USUAL_STUFF) for i,v in pairs(trees) do - minetest.remove_node(v) + env:remove_node(v) end --Information: @@ -113,18 +113,18 @@ minetest.register_on_generated(function(minp, maxp, seed) end end if ground_y then - minetest.add_node({x=x,y=ground_y,z=z}, {name="riesenpilz:ground"}) + env:add_node({x=x,y=ground_y,z=z}, {name="riesenpilz:ground"}) for i = -1,-5,-1 do local pos = {x=x,y=ground_y+i,z=z} - if minetest.get_node(pos).name == "default:desert_sand" then - minetest.add_node(pos, {name="default:dirt"}) + if env:get_node(pos).name == "default:desert_sand" then + env:add_node(pos, {name="default:dirt"}) else break end end local boden = {x=x,y=ground_y+1,z=z} if pr:next(1,15) == 1 then - minetest.add_node(boden, {name="default:dry_shrub"}) + env:add_node(boden, {name="default:dry_shrub"}) elseif pr:next(1,80) == 1 then riesenpilz_circle("riesenpilz:brown", boden, pr:next(3,4), 3) elseif pr:next(1,90) == 1 then @@ -136,15 +136,15 @@ minetest.register_on_generated(function(minp, maxp, seed) elseif pr:next(1,5000) == 1 then riesenpilz_circle("riesenpilz:glowshroom", boden, 3, 3) --[[elseif pr:next(1,80) == 1 then - minetest.add_node(boden, {name="riesenpilz:brown"}) + env:add_node(boden, {name="riesenpilz:brown"}) elseif pr:next(1,90) == 1 then - minetest.add_node(boden, {name="riesenpilz:red"}) + env:add_node(boden, {name="riesenpilz:red"}) elseif pr:next(1,100) == 1 then - minetest.add_node(boden, {name="riesenpilz:fly_agaric"}) + env:add_node(boden, {name="riesenpilz:fly_agaric"}) elseif pr:next(1,4000) == 1 then - minetest.add_node(boden, {name="riesenpilz:lavashroom"}) + env:add_node(boden, {name="riesenpilz:lavashroom"}) elseif pr:next(1,5000) == 1 then - minetest.add_node(boden, {name="riesenpilz:glowshroom"})]] + env:add_node(boden, {name="riesenpilz:glowshroom"})]] elseif pr:next(1,380) == 1 then riesenpilz_hybridpilz(boden) elseif pr:next(1,340) == 10 then @@ -161,8 +161,8 @@ minetest.register_on_generated(function(minp, maxp, seed) end if maxp.y < -10 then local x0,z0,x1,z1 = minp.x,minp.z,maxp.x,maxp.z -- Assume X and Z lengths are equal - --local env = minetest.|env --Should make things a bit faster. - local perlin1 = minetest.get_perlin(11,3, 0.5, 200) --Get map specific perlin + local env = minetest.env --Should make things a bit faster. + local perlin1 = env:get_perlin(11,3, 0.5, 200) --Get map specific perlin --[[if not (perlin1:get2d({x=x0, y=z0}) > 0.53) and not (perlin1:get2d({x=x1, y=z1}) > 0.53) and not (perlin1:get2d({x=x0, y=z1}) > 0.53) and not (perlin1:get2d({x=x1, y=z0}) > 0.53) @@ -189,12 +189,12 @@ minetest.register_on_generated(function(minp, maxp, seed) for y=minp.y,maxp.y,1 do local pos = {x=x, y=y, z=z} - if minetest.get_node(pos).name == "air" - and minetest.get_node({x=x, y=y-1, z=z}).name == "default:stone" + if env:get_node(pos).name == "air" + and env:get_node({x=x, y=y-1, z=z}).name == "default:stone" and pr:next(1,40) == 33 - and minetest.find_node_near(pos, 4, "group:igniter") - and not minetest.find_node_near(pos, 3, "group:igniter") then - minetest.add_node(pos, {name="riesenpilz:lavashroom"}) + and env:find_node_near(pos, 4, "group:igniter") + and not env:find_node_near(pos, 3, "group:igniter") then + env:add_node(pos, {name="riesenpilz:lavashroom"}) end end end diff --git a/mods/riesenpilz/textures/maptools_super_apple_bottom.png b/mods/riesenpilz/textures/maptools_super_apple_bottom.png deleted file mode 100755 index 46495124e13385547cfe33a68780d581b2602a9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPq4~Gzw>HOxy>wrS9JzX3_EKWb2xZ8`_QKEJK&-6R8 zH(3qe9diZm%Opnff5_x)8=mPC6vyAptcP*Q`zRh>xi-UVIE9V?Ie585x!Tm~y&NtkY z*0`zQD{}47=hH^ZczlJK7m3C&|B!sqwP}SWH{-pJd40v&eg-mI9xP+rqI3VA!@RXW tj;-e2Q=H&qvFhT&nu<$v|G)pm&^Osl@A)b%V6ZSSc)I$ztaD0e0ssK*ks$y8 diff --git a/mods/riesenpilz/textures/maptools_super_apple_side.png b/mods/riesenpilz/textures/maptools_super_apple_side.png deleted file mode 100755 index f10846bf46e355eda2af240d800f7bb72b33878e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPq4~Gzwp6D|!C!o+*PZ!4!i_=#p+xi`L5NO>mxt{k_ zzv`n7q0WxBwl3uYag}opCu@sXr1%6>Ws5jFlw1^C8E>wco^-f>>$FrAskrUdpZ7}c zy?SW>^ecYhJI*~>n!a`I^O|Xe8zr{?nz8LsRj}akOBO$a*Gfw;YwbUou==K{pQzls z11<)ZpT1ANydi$pgA$IH0@M5_s1#HPB(6>U%JchpsoDvLtA}r9wC7x5zRCJh@Z_Z9 zzo#eMR%ljf%h6}rmuT?dTCXGv+w5?MOIAHhUV$YB74?Vxe{h=KWzV(?25B#b?>hh{3Cb+saxH$7MJp%yK5Q1G91JI0z z(hU*QQ=rwZ0I)S!V&AV%R{{4Uc?hNE6lBX`u>mH$J07c)0WY)9A2BB$2vP;y0RTH# z;*GYG;WfQ303%24fgqe01%^p!pB|;C+q+KUb~nRIGk>;|?$KvNf!x#Zz9Tasop#^* mT+_0d9~{ldG*nPfQ1}E$pH+9+%AKnK0000#LU3JkTh5P6OiHz@Ck8EGiI2XW_)I5+E*)IXP}^_r;B3<$Mxh0Ru&$C zB(XVLvs8Pw3VG;6FJw(wd*M`)LlBSJw1rx1ObofVHI*`+AI$-3V(@hJb6Mw<&;$U; C`X2EB delta 86 zcmXTVoFEa%!N$PAApiM)B9Johba4!+U`&>9dvNB=mj6o<*33#@Cb?KcNu}>-*TW{22WQ%mvv4FO#n-3AAkS= diff --git a/mods/riesenpilz/textures/riesenpilz_brown45_top.png b/mods/riesenpilz/textures/riesenpilz_brown45_top.png deleted file mode 100755 index 573d5c29e053322934a8702dc7c6ad3e0efe8fc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`2A(dCAr*|t5^fL9oZ0e!Ny3_0 z>B}S+YbdGoT`ddZS$u`N#c`J5;d%wN6%|(+0+|`~`d5cCt@m3F)XU)M>gTe~DWM4f D)1M%u diff --git a/mods/vector_extras/.gitignore b/mods/vector_extras/.gitignore new file mode 100755 index 00000000..d9c069a6 --- /dev/null +++ b/mods/vector_extras/.gitignore @@ -0,0 +1,4 @@ +## Generic ignorable patterns and files +*~ +.*.swp +debug.txt diff --git a/mods/vector_extras/README.txt b/mods/vector_extras/README.txt new file mode 100755 index 00000000..fe5b6b1a --- /dev/null +++ b/mods/vector_extras/README.txt @@ -0,0 +1,2 @@ +TODO: +— add things to this list diff --git a/mods/vector_extras/init.lua b/mods/vector_extras/init.lua new file mode 100755 index 00000000..255f84d9 --- /dev/null +++ b/mods/vector_extras/init.lua @@ -0,0 +1,382 @@ +local load_time_start = os.clock() + +function vector.pos_to_string(pos) + return "("..pos.x.."|"..pos.y.."|"..pos.z..")" +end + +local r_corr = 0.25 --remove a bit more nodes (if shooting diagonal) to let it look like a hole (sth like antialiasing) + +-- this doesn't need to be calculated every time +local f_1 = 0.5-r_corr +local f_2 = 0.5+r_corr + +--returns information about the direction +local function get_used_dir(dir) + local abs_dir = {x=math.abs(dir.x), y=math.abs(dir.y), z=math.abs(dir.z)} + local dir_max = math.max(abs_dir.x, abs_dir.y, abs_dir.z) + if dir_max == abs_dir.x then + local tab = {"x", {x=1, y=dir.y/dir.x, z=dir.z/dir.x}} + if dir.x >= 0 then + tab[3] = "+" + end + return tab + end + if dir_max == abs_dir.y then + local tab = {"y", {x=dir.x/dir.y, y=1, z=dir.z/dir.y}} + if dir.y >= 0 then + tab[3] = "+" + end + return tab + end + local tab = {"z", {x=dir.x/dir.z, y=dir.y/dir.z, z=1}} + if dir.z >= 0 then + tab[3] = "+" + end + return tab +end + +local function node_tab(z, d) + local n1 = math.floor(z*d+f_1) + local n2 = math.floor(z*d+f_2) + if n1 == n2 then + return {n1} + end + return {n1, n2} +end + +local function return_line(pos, dir, range) --range ~= length + local tab = {} + local num = 1 + local t_dir = get_used_dir(dir) + local dir_typ = t_dir[1] + if t_dir[3] == "+" then + f_tab = {0, range, 1} + else + f_tab = {0, -range, -1} + end + local d_ch = t_dir[2] + if dir_typ == "x" then + for d = f_tab[1],f_tab[2],f_tab[3] do + local x = d + local ytab = node_tab(d_ch.y, d) + local ztab = node_tab(d_ch.z, d) + for _,y in ipairs(ytab) do + for _,z in ipairs(ztab) do + tab[num] = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + num = num+1 + end + end + end + elseif dir_typ == "y" then + for d = f_tab[1],f_tab[2],f_tab[3] do + local xtab = node_tab(d_ch.x, d) + local y = d + local ztab = node_tab(d_ch.z, d) + for _,x in ipairs(xtab) do + for _,z in ipairs(ztab) do + tab[num] = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + num = num+1 + end + end + end + else + for d = f_tab[1],f_tab[2],f_tab[3] do + local xtab = node_tab(d_ch.x, d) + local ytab = node_tab(d_ch.y, d) + local z = d + for _,x in ipairs(xtab) do + for _,y in ipairs(ytab) do + tab[num] = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + num = num+1 + end + end + end + end + return tab +end + +local function table_contains2(t, v) + for i = #t, 1, -1 do + if t[i] == v then + return true + end + end + return false +end + +local function return_fine_line(pos, dir, range, scale) + local ps1 = return_line(vector.round(vector.multiply(pos, scale)), dir, range*scale) + local ps2 = {} + local ps2_num = 1 + for _,p1 in ipairs(ps1) do + local p2 = vector.round(vector.divide(p1, scale)) + if not table_contains2(ps2, p2) then + ps2[ps2_num] = p2 + ps2_num = ps2_num+1 + end + end + return ps2 +end + +function vector.fine_line(pos, dir, range, scale) + --assert_vector(pos) + if not range then --dir = pos2 + dir = vector.direction(pos, dir) + range = vector.distance(pos, dir) + end + return return_fine_line(pos, dir, range, scale) +end + +function vector.line(pos, dir, range, alt) + --assert_vector(pos) + if alt then + if not range then --dir = pos2 + dir, range = vector.direction(pos, dir), vector.distance(pos, dir) + end + return return_line(pos, dir, range) + end + if range then --dir = pos2 + dir = vector.round(vector.multiply(dir, range)) + else + dir = vector.subtract(dir, pos) + end + local line,n = {},1 + for _,i in ipairs(vector.threeline(dir.x, dir.y, dir.z)) do + line[n] = {x=pos.x+i[1], y=pos.y+i[2], z=pos.z+i[3]} + n = n+1 + end + return line +end + +local twolines = {} +function vector.twoline(x, y) + local pstr = x.." "..y + local line = twolines[pstr] + if line then + return line + end + line = {} + local n = 1 + local dirx = 1 + if x < 0 then + dirx = -dirx + end + local ymin, ymax = 0, y + if y < 0 then + ymin, ymax = ymax, ymin + end + local m = y/x --y/0 works too + local dir = 1 + if m < 0 then + dir = -dir + end + for i = 0,x,dirx do + local p1 = math.max(math.min(math.floor((i-0.5)*m+0.5), ymax), ymin) + local p2 = math.max(math.min(math.floor((i+0.5)*m+0.5), ymax), ymin) + for j = p1,p2,dir do + line[n] = {i, j} + n = n+1 + end + end + twolines[pstr] = line + return line +end + +local threelines = {} +function vector.threeline(x, y, z) + local pstr = x.." "..y.." "..z + local line = threelines[pstr] + if line then + return line + end + if x ~= math.floor(x) then + print("[vector_extras] INFO: The position used for vector.threeline isn't round.") + end + local two_line = vector.twoline(x, y) + line = {} + local n = 1 + local zmin, zmax = 0, z + if z < 0 then + zmin, zmax = zmax, zmin + end + local m = z/math.hypot(x, y) + local dir = 1 + if m < 0 then + dir = -dir + end + for _,i in ipairs(two_line) do + local px, py = unpack(i) + local ph = math.hypot(px, py) + local z1 = math.max(math.min(math.floor((ph-0.5)*m+0.5), zmax), zmin) + local z2 = math.max(math.min(math.floor((ph+0.5)*m+0.5), zmax), zmin) + for pz = z1,z2,dir do + line[n] = {px, py, pz} + n = n+1 + end + end + threelines[pstr] = line + return line +end + +function vector.straightdelay(s, v, a) + if not a then + return s/v + end + return (math.sqrt(v*v+2*a*s)-v)/a +end + +vector.zero = {x=0, y=0, z=0} + +function vector.sun_dir(time) + if not time then + time = minetest.get_timeofday() + end + local t = (time-0.5)*5/6+0.5 --the sun rises at 5 o'clock, not at 6 + if t < 0.25 + or t > 0.75 then + return + end + local tmp = math.cos(math.pi*(2*t-0.5)) + return {x=tmp, y=math.sqrt(1-tmp*tmp), z=0} +end + +function vector.inside(pos, minp, maxp) + for _,i in ipairs({"x", "y", "z"}) do + if pos[i] < minp[i] + or pos[i] > maxp[i] then + return false + end + end + return true +end + +function vector.minmax(p1, p2) + local p1 = vector.new(p1) --Are these 2 redefinitions necessary? + local p2 = vector.new(p2) + for _,i in ipairs({"x", "y", "z"}) do + if p1[i] > p2[i] then + p1[i], p2[i] = p2[i], p1[i] + end + end + return p1, p2 +end + +function vector.move(p1, p2, s) + return vector.round( + vector.add( + vector.multiply( + vector.direction( + p1, + p2 + ), + s + ), + p1 + ) + ) +end + +local explosion_tables = {} +function vector.explosion_table(r) + local table = explosion_tables[r] + if table then + return table + end + + local t1 = os.clock() + local tab, n = {}, 1 + + local tmp = r*r + r + for x=-r,r do + for y=-r,r do + for z=-r,r do + local rc = x*x+y*y+z*z + if rc <= tmp then + local np={x=x, y=y, z=z} + if math.floor(math.sqrt(rc) +0.5) > r-1 then + tab[n] = {np, true} + else + tab[n] = {np} + end + n = n+1 + end + end + end + end + explosion_tables[r] = tab + print(string.format("[vector_extras] table created after ca. %.2fs", os.clock() - t1)) + return tab +end + +local circle_tables = {} +function vector.circle(r) + local table = circle_tables[r] + if table then + return table + end + + local t1 = os.clock() + local tab, n = {}, 1 + + for i = -r, r do + for j = -r, r do + if math.floor(math.sqrt(i*i+j*j)+0.5) == r then + tab[n] = {x=i, y=0, z=j} + n = n+1 + end + end + end + circle_tables[r] = tab + print(string.format("[vector_extras] table created after ca. %.2fs", os.clock() - t1)) + return tab +end + +local ring_tables = {} +function vector.ring(r) + local table = ring_tables[r] + if table then + return table + end + + local t1 = os.clock() + local tab, n = {}, 1 + + local tmp = r*r + local p = {x=math.floor(r+0.5), z=0} + while p.x > 0 do + tab[n] = p + n = n+1 + local p1, p2 = {x=p.x-1, z=p.z}, {x=p.x, z=p.z+1} + local dif1 = math.abs(tmp-p1.x*p1.x-p1.z*p1.z) + local dif2 = math.abs(tmp-p2.x*p2.x-p2.z*p2.z) + if dif1 <= dif2 then + p = p1 + else + p = p2 + end + end + + local tab2, n = {}, 1 + for _,i in ipairs(tab) do + for _,j in ipairs({ + {i.x, i.z}, + {-i.z, i.x}, + {-i.x, -i.z}, + {i.z, -i.x}, + }) do + tab2[n] = {x=j[1], y=0, z=j[2]} + n = n+1 + end + end + ring_tables[r] = tab2 + print(string.format("[vector_extras] table created after ca. %.2fs", os.clock() - t1)) + return tab2 +end + +function vector.chunkcorner(pos) + return {x=pos.x-pos.x%16, y=pos.y-pos.y%16, z=pos.z-pos.z%16} +end + +dofile(minetest.get_modpath("vector_extras").."/vector_meta.lua") + +print(string.format("[vector_extras] loaded after ca. %.2fs", os.clock() - load_time_start)) diff --git a/mods/vector_extras/vector_meta.lua b/mods/vector_extras/vector_meta.lua new file mode 100755 index 00000000..d9606cd1 --- /dev/null +++ b/mods/vector_extras/vector_meta.lua @@ -0,0 +1,183 @@ +vector.meta = vector.meta or {} +vector.meta.nodes = {} + +vector.meta.nodes_file = { + load = function() + local nodesfile = io.open(minetest.get_worldpath()..'/vector_nodes.txt', "r") + if nodesfile then + local contents = nodesfile:read('*all') + io.close(nodesfile) + if contents ~= nil then + local lines = string.split(contents, "\n") + for _,entry in ipairs(lines) do + local name, px, py, pz, meta = unpack(string.split(entry, "°")) + vector.meta.set_node({x=px, y=py, z=pz}, name, meta) + end + end + end + end, + save = function() --WRITE CHANGES TO FILE + local output = '' + for x,ys in pairs(vector.meta.nodes) do + for y,zs in pairs(ys) do + for z,names in pairs(zs) do + for name,meta in pairs(names) do + output = name.."°"..x.."°"..y.."°"..z.."°"..dump(meta).."\n" + end + end + end + end + local f = io.open(minetest.get_worldpath()..'/vector_nodes.txt', "w") + f:write(output) + io.close(f) + end +} + +local function table_empty(tab) --looks if it's an empty table + if next(tab) == nil then + return true + end + return false +end + +function vector.meta.nodes_info() --returns an info string of the node table + local tmp = "[vector] "..dump(vector.meta.nodes).."\n[vector]:\n" + for x,a in pairs(vector.meta.nodes) do + for y,b in pairs(a) do + for z,c in pairs(b) do + for name,meta in pairs(c) do + tmp = tmp..">\t"..name.." "..x.." "..y.." "..z.." "..dump(meta).."\n" + end + end + end + end + return tmp +end + +function vector.meta.clean_node_table() --replaces {} with nil + local again = true + while again do + again = false + for x,ys in pairs(vector.meta.nodes) do + if table_empty(ys) then + vector.meta.nodes[x] = nil + again = true + else + for y,zs in pairs(ys) do + if table_empty(zs) then + vector.meta.nodes[x][y] = nil + again = true + else + for z,names in pairs(zs) do + if table_empty(names) then + vector.meta.nodes[x][y][z] = nil + again = true + else + for name,meta in pairs(names) do + if table_empty(meta) + or meta == "" then + vector.meta.nodes[x][y][z][name] = nil + again = true + end + end + end + end + end + end + end + end + end +end + +function vector.meta.complete_node_table(pos, name) --neccesary because tab[1] wouldn't work if tab is not a table + local tmp = vector.meta.nodes[pos.x] + if not tmp then + vector.meta.nodes[pos.x] = {} + end + local tmp = vector.meta.nodes[pos.x][pos.y] + if not tmp then + vector.meta.nodes[pos.x][pos.y] = {} + end + local tmp = vector.meta.nodes[pos.x][pos.y][pos.z] + if not tmp then + vector.meta.nodes[pos.x][pos.y][pos.z] = {} + end + local tmp = vector.meta.nodes[pos.x][pos.y][pos.z][name] + if not tmp then + vector.meta.nodes[pos.x][pos.y][pos.z][name] = {} + end +end + +function vector.meta.get_node(pos, name) + if not pos then + return false + end + local tmp = vector.meta.nodes[pos.x] + if not tmp + or table_empty(tmp) then + return false + end + local tmp = vector.meta.nodes[pos.x][pos.y] + if not tmp + or table_empty(tmp) then + return false + end + local tmp = vector.meta.nodes[pos.x][pos.y][pos.z] + if not tmp + or table_empty(tmp) then + return false + end + + -- if name isn't mentioned, just look if there's a node + if not name then + return true + end + + local tmp = vector.meta.nodes[pos.x][pos.y][pos.z][name] + if not tmp + or table_empty(tmp) then + return false + end + return tmp +end + +function vector.meta.remove_node(pos) + if not pos then + return false + end + if vector.meta.get_node(pos) then + vector.meta.nodes[pos.x][pos.y][pos.z] = nil + local xarr = vector.meta.nodes[pos.x] + if table_empty(xarr[pos.y]) then + vector.meta.nodes[pos.x][pos.y] = nil + end + if table_empty(xarr) then + vector.meta.nodes[pos.x] = nil + end + else + print("[vector_extras] Warning: The node at "..vector.pos_to_string(pos).." wasn't stored in vector.meta.nodes.") + end +end + +function vector.meta.set_node(pos, name, meta) + if not (name or pos) then + return false + end + vector.meta.complete_node_table(pos, name) + meta = meta or true + vector.meta.nodes[pos.x][pos.y][pos.z][name] = meta +end + +minetest.register_chatcommand('cleanvectormetatable',{ + description = 'Tidy up it.', + params = "", + privs = {}, + func = function(name) + vector.meta.clean_node_table() + local tmp = vector.meta.nodes_info() + minetest.chat_send_player(name, tmp) + print("[vector_extras] "..tmp) + end +}) + +vector.meta.nodes_file.load()