diff --git a/init.lua b/init.lua index 073a2e5..8b943d5 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,7 @@ potions = { geodes = {}, + utils = {}, } local potions_players = {} @@ -19,6 +20,9 @@ dofile(modpath.."/hotsprings.lua") dofile(modpath.."/structures/ziggurat.lua") dofile(modpath.."/structures/coffer_dam.lua") dofile(modpath.."/structures/bridge.lua") +dofile(modpath.."/structures/tunnel.lua") +dofile(modpath.."/structures/island.lua") +dofile(modpath.."/util/spiral.lua") -- core dofile(modpath.."/minetunnels.lua") @@ -26,6 +30,10 @@ dofile(modpath.."/beanstalk.lua") dofile(modpath.."/enchanting.lua") dofile(modpath.."/alchemy.lua") +--spells +dofile(modpath.."/spells/plant_growth.lua") + + -- pure mapgen dofile(modpath.."/rocks.lua") @@ -54,8 +62,6 @@ potions/magic each move takes a time meta value along for cooling conjure a meteor freeze/thaw an area - conjure a coffer dam - conjure an island conjure a floatland conjure butterflies or fireflies a spell with two areas that sucks life-force from one area and vents it to another @@ -67,6 +73,9 @@ potions/magic effectively change biome clone object nodes that explode when you dig them + grow a big hollow bubble from the ground + create a space of air + emergent jungle tree with ladder inthe core up to a treehouse [engine] @@ -375,7 +384,7 @@ end local function update_all_manna() for _,p in pairs(potions_players) do - update_player_manna(p, 20) + update_player_manna(p, 20) -- HACK manna regenerates quickly for debugging end minetest.after(1, update_all_manna) diff --git a/spells/plant_growth.lua b/spells/plant_growth.lua new file mode 100644 index 0000000..3d19974 --- /dev/null +++ b/spells/plant_growth.lua @@ -0,0 +1,115 @@ + + +minetest.register_node("potions:grass_growth_accel", { + description = "Grass Growth Accelerator", + inventory_image = "default_grass.png", + tiles = {"default_grass.png"}, + groups = {cracky=3,}, +}) + + + +local function random_pos(pos, dist) + local p = { + x=pos.x + math.random(-dist, dist), + y=pos.y + 4, + z=pos.z + math.random(-dist, dist), + } + + while p.y > pos.y - dist do + local n = minetest.get_node(p) + if n.name ~= "air" and n.name ~= "ignore" then + if n.name == "default:water_source" or n.name == "default:water_flowing" then + return nil + end + + return p + end + + p.y = p.y - 1 + end + + return nil +end + + +minetest.register_abm({ + nodenames = "potions:grass_growth_accel", + interval = 1, + chance = 1, + action = function(pos) + local p = random_pos(pos, 10) + if not p then return end + + local b = minetest.get_node(p) + if b.name == "default:dirt" or b.name == "default:dirt_with_dry_grass" then + minetest.set_node(p, {name="default:dirt_with_grass"}) + elseif b.name == "default:dirt_with_grass" then + p.y = p.y + 1 + + local n = minetest.get_node(p) + if n.name == "air" then + minetest.set_node(p, {name="default:grass_1"}) + end + elseif b.name == "default:grass_1" then + minetest.set_node(p, {name="default:grass_2"}) + elseif b.name == "default:grass_2" then + minetest.set_node(p, {name="default:grass_3"}) + elseif b.name == "default:grass_3" then + minetest.set_node(p, {name="default:grass_4"}) + elseif b.name == "default:grass_4" then + minetest.set_node(p, {name="default:grass_5"}) + elseif b.name == "default:grass_5" then + return + end + end, +}) + + +minetest.register_node("potions:flower_growth_accel", { + description = "Flower Growth Accelerator", + inventory_image = "default_grass.png^flowers_rose.png", + tiles = {"default_grass.png^flowers_rose.png"}, + groups = {cracky=3,}, +}) + + + + + +minetest.register_abm({ + nodenames = "potions:flower_growth_accel", + interval = 1, + chance = 1, + action = function(pos) + local p = random_pos(pos, 10) + if not p then return end + + local b = minetest.get_node(p) + if b.name == "default:dirt" then + minetest.set_node(p, {name="default:dirt_with_grass"}) + else + if b.name == "default:dirt_with_grass" then + p.y = p.y + 1 + + local n = minetest.get_node(p) + if n.name == "air" then + local f = flowers.datas[math.random(#flowers.datas)] + minetest.set_node(p, {name="flowers:"..f[1]}) + end + else + local def = minetest.registered_nodes[b.name] + if def.groups.grass then + local f = flowers.datas[math.random(#flowers.datas)] + minetest.set_node(p, {name="flowers:"..f[1]}) + end + end + end + end, +}) + + + + +-- TODO: mushroom accelerator +-- max lifetime for these nodes diff --git a/structures/island.lua b/structures/island.lua new file mode 100644 index 0000000..03b93c7 --- /dev/null +++ b/structures/island.lua @@ -0,0 +1,136 @@ + + + +local function dist3(a, b) + local x = a.x - b.x + local y = a.y - b.y + local z = a.z - b.z + return math.sqrt(x*x + y*y + z*z) +end + +local function dist2(a, b) + local x = a.x - b.x + local z = a.z - b.z + return math.sqrt(x*x + z*z) +end + + +local function make_island(pos, size) +-- dir.y = 0 + + pos.y = pos.y - 3 + + + local r = size + + local r2 = math.ceil(r+1) + local top_nodes = {} + + -- foundation + for x = pos.x-r2,pos.x+r2,1 do + for y = -r2,0,1 do + for z = pos.z-r2,pos.z+r2,1 do + local p = {x=x, y=pos.y+y, z=z} + local p_squash = {x=x, y=pos.y + (y*2), z=z} + local d = dist3(p_squash, pos) + + d = d + math.random() * .5 + + local dd = d - r + + if dd < 1 then + if y == 0 then + table.insert(top_nodes, p) + end + + local n = minetest.get_node(p) + if n.name == "default:water_source" or n.name == "default:water_flowing" then + minetest.set_node(p, {name = "default:coral_skeleton"}) + end + elseif dd < 1.8 and math.random(8) == 1 then + if math.random(2) == 1 then + minetest.set_node(p, {name = "default:coral_brown"}) + else + minetest.set_node(p, {name = "default:coral_orange"}) + end + end + end + end + end + + -- sand + for _,p in ipairs(top_nodes) do + p.y = p.y + 1 + + minetest.set_node(p, {name="default:sand"}) + + local d = dist2(pos, p) + math.random() * .9 + if d / r < .5 then + p.y = p.y + 1 + minetest.set_node(p, {name="default:dirt_with_grass"}) + + if math.random(5) == 1 then + p.y = p.y + 1 + minetest.set_node(p, {name="default:grass_1"}) + end + elseif math.random(8) == 1 then + p.y = p.y + 1 + minetest.set_node(p, {name="default:marram_grass_1"}) + end + + + end + + -- add a tree + if size > 15 then + default.grow_new_emergent_jungle_tree({x=pos.x, y=pos.y+2, z=pos.z}) + elseif size > 10 then + default.grow_new_jungle_tree({x=pos.x, y=pos.y+2, z=pos.z}) + elseif size > 7 then + default.grow_new_aspen_tree({x=pos.x, y=pos.y+2, z=pos.z}) + elseif size > 3 then + default.grow_new_apple_tree({x=pos.x, y=pos.y+2, z=pos.z}) + end + + +end + + + + + +minetest.register_craftitem("potions:island_seed", { + description = "Island Seed", + inventory_image = "default_brick.png", + groups = {cracky=3,}, + liquids_pointable=true, + + on_use = function(itemstack, player, pointed_thing) + + + + + local pos = pointed_thing.above + if not pos then + return + end + + pos.y = pos.y + 1 + +-- local below = {x=pos.x, y=pos.y-1, z=pos.z} +-- local n = minetest.get_node(below) +-- if n.name == "air" or n.name == "ignore" then +-- return +-- end + +-- local newname = get_temp_node(n.name) + + potions.use_manna(player, 20) + + make_island(pos, 4) + -- get player yaw, calc direction + +-- itemstack:take_item() + return itemstack + end, +}) diff --git a/structures/tunnel.lua b/structures/tunnel.lua new file mode 100644 index 0000000..c5caacc --- /dev/null +++ b/structures/tunnel.lua @@ -0,0 +1,105 @@ + + +local function make_tunnel(pos, radius, length, dir) +-- dir.y = 0 + local ndir = vector.normalize(dir) + local cross = vector.normalize({x=-dir.z, y=0, z=dir.x}) + + local wlow = math.ceil(width / 2) + local whigh = math.floor(width / 2) + local exp = 2 +-- local off = math.sin(math.pi/(exp*exp)) * height + + for l = 0,length do + +-- local y = -off + math.sin(math.pi/(exp*exp) + ((l / length) * math.pi / exp) ) * height + + + local p = {x = pos.x+l*ndir.x, y=pos.y+l*ndir.y, z=pos.z+l*ndir.z} + +-- local param2 = 0 +-- if math.floor(y + .5) ~= math.floor(y) then +-- p.y = p.y - 1 +-- param2 = 20 +-- end + print(dump(p)) + minetest.set_node(p, {name="air"}) + + + for h = -radius,radius do + for w = -radius,radius do + if math.sqrt(h*h + w*w) <= radius then + local p2 = vector.add(p, vector.multiply(cross, w)) + p2.y = p2.y + h + minetest.set_node( + p2, + {name="air"}) + end + end + end + end + + +end + + + + + +minetest.register_craftitem("potions:tunnel_seed", { + description = "Tunnel Seed", + inventory_image = "default_sandstone_brick.png", + groups = {cracky=3,}, + liquids_pointable=true, + + on_use = function(itemstack, player, pointed_thing) + + local pos = player:get_pos() + if not pos then + return + end + + pos.y = pos.y + 1 + +-- local below = {x=pos.x, y=pos.y-1, z=pos.z} +-- local n = minetest.get_node(below) +-- if n.name == "air" or n.name == "ignore" then +-- return +-- end + +-- local newname = get_temp_node(n.name) + + local th = player:get_look_horizontal() + local thv = player:get_look_vertical() + local dir = vector.normalize({ + x = -math.sin(th), + y = math.sin(thv), + z = math.cos(th), + }) + + local pos2 = vector.add(pos, vector.multiply(dir, potions.get_manna(player))) + + +-- local b, pos3 = minetest.line_of_sight(pos, pos2) +-- if b == false then +-- pos2 = pos3 +-- end + + local dist = 20 -- vector.distance(pos, pos2) + + dist = potions.use_manna(player, dist) + + if dist < 2 then + return + end + + print(dump(dir)) + +-- minetest.set_node(pos, {name="air"}) + make_tunnel(pos, 4, 5, 30, dir) + -- get player yaw, calc direction + +-- itemstack:take_item() + return itemstack + end, +}) diff --git a/util/spiral.lua b/util/spiral.lua new file mode 100644 index 0000000..f431eab --- /dev/null +++ b/util/spiral.lua @@ -0,0 +1,168 @@ + + + + + + +potions.utils.spawn_in = function(nodes, height, node, delay, nmax) + + local h = 0 + local i = 1 + + local function go() + for n = 1,nmax do + + if i > #nodes then + i = 1 + h = h + 1 + if h > height then + return + end + end + + + local p = nodes[i] + + minetest.set_node({x=p.x, y=p.y+h, z=p.z}, {name=node}) + + i = i + 1 + end + + minetest.after(delay, go) + end + + go() + +end + + + +potions.utils.stairs = function(start, dir, height, stair_node, space_above, fill_node) + + local adv = {x=0, z=0} + + local param2 = minetest.dir_to_facedir(dir) + + for h = 0,height-1 do + local p = {x=start.x+adv.x, y=start.y+h, z=start.z+adv.z} + minetest.set_node(p, {name=stair_node, param2=param2}) + + + if fill_node then + while p.y > start.y do + p.y = p.y - 1 + minetest.set_node(p, {name=fill_node}) + end + end + + p.y = start.y + h + 1 + for i = 1,space_above do + minetest.set_node(p, {name="air"}) + p.y = p.y + 1 + end + + + adv.x = adv.x + dir.x + adv.z = adv.z + dir.z + end + +end + + + +potions.utils.disc_cheap = function(pos, radius) + local r = math.ceil(radius) + local out = {} + + for x = -r,r do + for z = -r,r do + if radius >= math.sqrt(x*x + z*z) then + table.insert(out, {x=pos.x+x, y=pos.y, z=pos.z+z}) + end + end + end + + return out +end + + +-- the nodes are not in consecutive order +potions.utils.circle_cheap = function(pos, radius) + + local r = radius + local r2f = math.floor(r * math.sin(math.pi/4) + .5) + local r2c = math.floor(r * math.sin(math.pi/4) + .5) + + local out = {} + + for x = -r2f,r2c,1 do + local z = math.sqrt(r*r - x*x) + + table.insert(out, {x=pos.x+x, y=pos.y, z=pos.z+z}) + table.insert(out, {x=pos.x+x, y=pos.y, z=pos.z-z}) +-- minetest.set_node({x=pos.x+x, y=pos.y, z=pos.z+z}, {name=node}) +-- minetest.set_node({x=pos.x+x, y=pos.y, z=pos.z-z}, {name=node}) + end + + + for z = -r2f,r2c,1 do + local x = math.sqrt(r*r - z*z) + + table.insert(out, {x=pos.x+x, y=pos.y, z=pos.z+z}) + table.insert(out, {x=pos.x-x, y=pos.y, z=pos.z+z}) +-- minetest.set_node({x=pos.x+x, y=pos.y+1, z=pos.z+z}, {name=node}) +-- minetest.set_node({x=pos.x-x, y=pos.y+1, z=pos.z+z}, {name=node}) + end + + return out +end + + + + + + + +minetest.register_craftitem("potions:spiral_test", { + description = "Spiral Seed", + inventory_image = "default_brick.png", + groups = {cracky=3,}, + liquids_pointable=true, + + on_use = function(itemstack, player, pointed_thing) + + local pos = pointed_thing.above + if not pos then + return + end + + pos.y = pos.y + 1 + + local nodes = potions.utils.circle_cheap(pos, 7) + + + local disc = potions.utils.disc_cheap({x=pos.x, y=pos.y+0, z=pos.z}, 6.8) + minetest.bulk_set_node(disc, {name="default:wood"}) + local disc = potions.utils.disc_cheap({x=pos.x, y=pos.y+5, z=pos.z}, 6.8) + minetest.bulk_set_node(disc, {name="default:wood"}) + local disc = potions.utils.disc_cheap({x=pos.x, y=pos.y+10, z=pos.z}, 6.8) + minetest.bulk_set_node(disc, {name="default:wood"}) + + pos.y = pos.y + 1 + potions.utils.stairs(pos, {x=-1, z=0}, 5, "stairs:stair_cobble", 3, "default:tree") + pos.y = pos.y - 1 + + + potions.utils.spawn_in(nodes, 10, "default:dirt", .5, 6) + + end, +}) + + + + + + + + +