diff --git a/falling_ice.lua b/falling_ice.lua new file mode 100644 index 0000000..dffe92e --- /dev/null +++ b/falling_ice.lua @@ -0,0 +1,210 @@ +-- CaveRealms: falling icicles +-- borrowed from base MineTest game's falling.lua + +-- +-- Falling ice +-- + +minetest.register_entity("caverealms:falling_ice", { + initial_properties = { + physical = true, + collide_with_objects = false, + collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + visual = "wielditem", + textures = {}, + visual_size = {x=0.667, y=0.667}, + }, + + node = {}, + + set_node = function(self, node) + self.node = node + local stack = ItemStack(node.name) + local itemtable = stack:to_table() + local itemname = nil + if itemtable then + itemname = stack:to_table().name + end + local item_texture = nil + local item_type = "" + if minetest.registered_items[itemname] then + item_texture = minetest.registered_items[itemname].inventory_image + item_type = minetest.registered_items[itemname].type + end + prop = { + is_visible = true, + textures = {node.name}, + } + self.object:set_properties(prop) + end, + + get_staticdata = function(self) + return self.node.name + end, + + on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal=1}) + --self.object:setacceleration({x=0, y=-10, z=0}) + self:set_node({name=staticdata}) + end, + + on_step = function(self, dtime) + -- Set gravity + self.object:setacceleration({x=0, y=-10, z=0}) + -- Destroy when collides to ground or just move + local pos = self.object:getpos() + local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point + local bcn = minetest.get_node(bcp) + local bcd = minetest.registered_nodes[bcn.name] + --check for players next to this and hurt them >:D + local all_objects = minetest.get_objects_inside_radius(pos, 1) + local _,obj + for _,obj in ipairs(all_objects) do + if obj:is_player() then + obj:set_hp(obj:get_hp() - 8) + end + end + -- Note: walkable is in the node definition, not in item groups + if not bcd or + (bcd.walkable or + (minetest.get_item_group(self.node.name, "float") ~= 0 and + bcd.liquidtype ~= "none")) then + if bcd and bcd.leveled and + bcn.name == self.node.name then + local addlevel = self.node.level + if addlevel == nil or addlevel <= 0 then + addlevel = bcd.leveled + end + if minetest.add_node_level(bcp, addlevel) == 0 then + self.object:remove() + return + end + elseif bcd and bcd.buildable_to and + (minetest.get_item_group(self.node.name, "float") == 0 or + bcd.liquidtype == "none") then + minetest.remove_node(bcp) + return + end + local np = {x=bcp.x, y=bcp.y+1, z=bcp.z} + -- Check what's here + local n2 = minetest.get_node(np) + -- remove node and replace it with it's drops + local drops = minetest.get_node_drops(n2.name, "") + minetest.remove_node(np) + local _, dropped_item + for _, dropped_item in ipairs(drops) do + minetest.add_item(np, dropped_item) + end + -- Run script hook + local _, callback + for _, callback in ipairs(minetest.registered_on_dignodes) do + callback(np, n2, nil) + end + -- remove entity + --minetest.add_node(np, self.node) + self.object:remove() + nodeupdate(np) + else + -- Do nothing + end + end +}) + +function spawn_falling_node(p, node) + obj = minetest.add_entity(p, "caverealms:falling_ice") + obj:get_luaentity():set_node(node) +end + +function drop_attached_node(p) + local nn = minetest.get_node(p).name + minetest.remove_node(p) + for _,item in ipairs(minetest.get_node_drops(nn, "")) do + local pos = { + x = p.x + math.random()/2 - 0.25, + y = p.y + math.random()/2 - 0.25, + z = p.z + math.random()/2 - 0.25, + } + minetest.add_item(pos, item) + end +end + +function check_attached_node(p, n) + local def = minetest.registered_nodes[n.name] + local d = {x=0, y=0, z=0} + if def.paramtype2 == "wallmounted" then + if n.param2 == 0 then + d.y = 1 + elseif n.param2 == 1 then + d.y = -1 + elseif n.param2 == 2 then + d.x = 1 + elseif n.param2 == 3 then + d.x = -1 + elseif n.param2 == 4 then + d.z = 1 + elseif n.param2 == 5 then + d.z = -1 + end + else + d.y = -1 + end + local p2 = {x=p.x+d.x, y=p.y+d.y, z=p.z+d.z} + local nn = minetest.get_node(p2).name + local def2 = minetest.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true +end + +-- +-- Some common functions +-- + +function nodeupdate_single(p, delay) + n = minetest.get_node(p) + if minetest.get_item_group(n.name, "falling_node") ~= 0 then + p_bottom = {x=p.x, y=p.y-1, z=p.z} + n_bottom = minetest.get_node(p_bottom) + -- Note: walkable is in the node definition, not in item groups + if minetest.registered_nodes[n_bottom.name] and + (minetest.get_item_group(n.name, "float") == 0 or + minetest.registered_nodes[n_bottom.name].liquidtype == "none") and + (n.name ~= n_bottom.name or (minetest.registered_nodes[n_bottom.name].leveled and + minetest.get_node_level(p_bottom) < minetest.get_node_max_level(p_bottom))) and + (not minetest.registered_nodes[n_bottom.name].walkable or + minetest.registered_nodes[n_bottom.name].buildable_to) then + if delay then + minetest.after(0.1, nodeupdate_single, {x=p.x, y=p.y, z=p.z}, false) + else + n.level = minetest.env:get_node_level(p) + minetest.remove_node(p) + spawn_falling_node(p, n) + nodeupdate(p) + end + end + end + + if minetest.get_item_group(n.name, "attached_node") ~= 0 then + if not check_attached_node(p, n) then + drop_attached_node(p) + nodeupdate(p) + end + end +end + +function nodeupdate(p, delay) + -- Round p to prevent falling entities to get stuck + p.x = math.floor(p.x+0.5) + p.y = math.floor(p.y+0.5) + p.z = math.floor(p.z+0.5) + + for x = -1,1 do + for y = -1,1 do + for z = -1,1 do + nodeupdate_single({x=p.x+x, y=p.y+y, z=p.z+z}, delay or not (x==0 and y==0 and z==0)) + end + end + end +end + diff --git a/init.lua b/init.lua index 46b149a..2c76108 100644 --- a/init.lua +++ b/init.lua @@ -9,6 +9,7 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) dofile(modpath.."/config.lua") dofile(modpath.."/crafting.lua") +dofile(modpath.."/falling_ice.lua") -- Parameters (see also config.lua) @@ -41,6 +42,10 @@ local MUSHCHA = 0.04 --chance of mushrooms local MYCCHA = 0.03 --chance of mycena mushrooms local WORMCHA = 0.03 --chance of glow worms local GIANTCHA = 0.001 -- chance of giant mushrooms +local ICICHA = 0.035 -- chance of icicles + +local FALLING_ICICLES = true --toggle to turn on or off falling icicles in glaciated biome +local FALLCHA = 0.33 --chance of causing the structure to fall -- 3D noise for caverns @@ -153,6 +158,56 @@ minetest.register_node("caverealms:glow_emerald_ore", { paramtype = "light", }) +--thin (transparent) ice +minetest.register_node("caverealms:thin_ice", { + description = "Thin Ice", + tiles = {"caverealms_thin_ice.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--alternate version for stalactites +minetest.register_node("caverealms:hanging_thin_ice", { + description = "Thin Ice", + tiles = {"caverealms_thin_ice.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, + drop = "caverealms:thin_ice", + after_dig_node = function(pos, oldnode, oldmetadata, digger) + if FALLING_ICICLES then + if math.random() <= FALLCHA then + obj = minetest.add_entity(pos, "caverealms:falling_ice") + obj:get_luaentity():set_node(oldnode) + for y = -13, 13 do + for x = -3, 3 do + for z = -3, 3 do + local npos = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + if minetest.get_node(npos).name == "caverealms:hanging_thin_ice" then + nobj = minetest.add_entity(npos, "caverealms:falling_ice") + nobj:get_luaentity():set_node(oldnode) + minetest.remove_node(npos) + end + end + end + end + minetest.remove_node(pos) + else + return 1 + end + else + return 1 + end + end, +}) + --glowing crystal gem minetest.register_node("caverealms:glow_gem", { description = "Glow Gem", @@ -174,13 +229,55 @@ minetest.register_node("caverealms:glow_gem", { }, }) +--upward pointing icicle +minetest.register_node("caverealms:icicle_up", { + description = "Icicle", + tiles = {"caverealms_icicle_up.png"}, + inventory_image = "caverealms_icicle_up.png", + wield_image = "caverealms_icicle_up.png", + is_ground_content = true, + groups = {cracky=3, oddly_breakable_by_hand=1}, + sounds = default.node_sound_glass_defaults(), + light_source = 8, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, +}) + +--downward pointing icicle +minetest.register_node("caverealms:icicle_down", { + description = "Icicle", + tiles = {"caverealms_icicle_down.png"}, + inventory_image = "caverealms_icicle_down.png", + wield_image = "caverealms_icicle_down.png", + is_ground_content = true, + groups = {cracky=3, oddly_breakable_by_hand=1}, + sounds = default.node_sound_glass_defaults(), + light_source = 8, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, +}) + --cave mossy cobble - bluish? minetest.register_node("caverealms:stone_with_moss", { description = "Cave Stone with Moss", tiles = {"default_cobble.png^caverealms_moss.png", "default_cobble.png", "default_cobble.png^caverealms_moss_side.png"}, is_ground_content = true, groups = {crumbly=3}, - drop = 'default:cobblestone', + drop = 'default:cobble', sounds = default.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.25}, }), @@ -192,7 +289,7 @@ minetest.register_node("caverealms:stone_with_lichen", { tiles = {"default_cobble.png^caverealms_lichen.png", "default_cobble.png", "default_cobble.png^caverealms_lichen_side.png"}, is_ground_content = true, groups = {crumbly=3}, - drop = 'default:cobblestone', + drop = 'default:cobble', sounds = default.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.25}, }), @@ -204,7 +301,7 @@ minetest.register_node("caverealms:stone_with_algae", { tiles = {"default_cobble.png^caverealms_algae.png", "default_cobble.png", "default_cobble.png^caverealms_algae_side.png"}, is_ground_content = true, groups = {crumbly=3}, - drop = 'default:cobblestone', + drop = 'default:cobble', sounds = default.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.25}, }), @@ -376,6 +473,8 @@ function caverealms:crystal_stalagmite(x,y,z, area, data, biome) local c_emore = minetest.get_content_id("caverealms:glow_emerald_ore") local c_mesecry = minetest.get_content_id("caverealms:glow_mese") local c_meseore = minetest.get_content_id("default:stone_with_mese") + local c_ice = minetest.get_content_id("default:ice") + local c_thinice = minetest.get_content_id("caverealms:thin_ice") --for randomness local mode = 1 @@ -383,7 +482,14 @@ function caverealms:crystal_stalagmite(x,y,z, area, data, biome) mode = 2 end if biome == 3 then - if math.random(10) == 1 then + if math.random(25) == 1 then + mode = 2 + else + mode = 1 + end + end + if biome == 4 or biome == 5 then + if math.random(3) == 1 then mode = 2 end end @@ -394,8 +500,13 @@ function caverealms:crystal_stalagmite(x,y,z, area, data, biome) for l = -3, 3 do if j == 0 then if k*k + l*l <= 9 then - local vi = area:index(x+k, y+j, z+l-3) - data[vi] = c_stone + if (biome == 4 or biome == 5) and mode == 1 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_ice + else + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end end elseif j <= top/5 then if k*k + l*l <= 4 then @@ -418,6 +529,12 @@ function caverealms:crystal_stalagmite(x,y,z, area, data, biome) else data[vi] = c_emore end + elseif biome == 4 or biome == 5 then + if mode == 2 then + data[vi] = c_crystore + else + data[vi] = c_ice + end end end elseif j <= top/5 * 3 then @@ -441,6 +558,12 @@ function caverealms:crystal_stalagmite(x,y,z, area, data, biome) else data[vi] = c_emerald end + elseif biome == 4 or biome == 5 then + if mode == 2 then + data[vi] = c_crystal + else + data[vi] = c_thinice + end end end else @@ -463,6 +586,12 @@ function caverealms:crystal_stalagmite(x,y,z, area, data, biome) else data[vi] = c_emerald end + elseif biome == 4 or biome == 5 then + if mode == 2 then + data[vi] = c_crystal + else + data[vi] = c_thinice + end end end end @@ -480,6 +609,8 @@ function caverealms:crystal_stalactite(x,y,z, area, data, biome) local c_emore = minetest.get_content_id("caverealms:glow_emerald_ore") local c_mesecry = minetest.get_content_id("caverealms:glow_mese") local c_meseore = minetest.get_content_id("default:stone_with_mese") + local c_ice = minetest.get_content_id("default:ice") + local c_thinice = minetest.get_content_id("caverealms:hanging_thin_ice") --for randomness local mode = 1 @@ -487,7 +618,14 @@ function caverealms:crystal_stalactite(x,y,z, area, data, biome) mode = 2 end if biome == 3 then - if math.random(10) == 1 then + if math.random(25) == 1 then + mode = 2 + else + mode = 1 + end + end + if biome == 4 or biome == 5 then + if math.random(3) == 1 then mode = 2 end end @@ -498,8 +636,13 @@ function caverealms:crystal_stalactite(x,y,z, area, data, biome) for l = -3, 3 do if j >= -1 then if k*k + l*l <= 9 then - local vi = area:index(x+k, y+j, z+l-3) - data[vi] = c_stone + if (biome == 4 or biome == 5) and mode == 1 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_ice + else + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end end elseif j >= bot/5 then if k*k + l*l <= 4 then @@ -522,6 +665,12 @@ function caverealms:crystal_stalactite(x,y,z, area, data, biome) else data[vi] = c_emore end + elseif biome == 4 or biome == 5 then + if mode == 2 then + data[vi] = c_crystore + else + data[vi] = c_ice + end end end elseif j >= bot/5 * 3 then @@ -545,6 +694,12 @@ function caverealms:crystal_stalactite(x,y,z, area, data, biome) else data[vi] = c_emerald end + elseif biome == 4 or biome == 5 then + if mode == 2 then + data[vi] = c_crystal + else + data[vi] = c_thinice + end end end else @@ -567,6 +722,12 @@ function caverealms:crystal_stalactite(x,y,z, area, data, biome) else data[vi] = c_emerald end + elseif biome == 4 or biome == 5 then + if mode == 2 then + data[vi] = c_crystal + else + data[vi] = c_thinice + end end end end @@ -696,8 +857,11 @@ minetest.register_on_generated(function(minp, maxp, seed) --grab content IDs local c_air = minetest.get_content_id("air") + local c_stone = minetest.get_content_id("default:stone") local c_water = minetest.get_content_id("default:water_source") local c_lava = minetest.get_content_id("default:lava_source") + local c_ice = minetest.get_content_id("default:ice") + local c_thinice = minetest.get_content_id("caverealms:thin_ice") local c_crystal = minetest.get_content_id("caverealms:glow_crystal") local c_gem = minetest.get_content_id("caverealms:glow_gem") local c_moss = minetest.get_content_id("caverealms:stone_with_moss") @@ -705,7 +869,9 @@ minetest.register_on_generated(function(minp, maxp, seed) local c_algae = minetest.get_content_id("caverealms:stone_with_algae") local c_fungus = minetest.get_content_id("caverealms:fungus") local c_mycena = minetest.get_content_id("caverealms:mycena") - local c_worm = minetest.get_content_id("caverealms:glow_worm") + local c_worm = minetest.get_content_id("caverealms:glow_worm") + local c_iciu = minetest.get_content_id("caverealms:icicle_up") + local c_icid = minetest.get_content_id("caverealms:icicle_down") --some mandatory values local sidelen = x1 - x0 + 1 --usually equals 80 with default mapgen values. Always a multiple of 16. @@ -773,12 +939,18 @@ minetest.register_on_generated(function(minp, maxp, seed) --determine biome local biome = false --preliminary declaration n_biome = nvals_biome[nixz] --make an easier reference to the noise - if n_biome >= 0.3 then - biome = 1 - elseif n_biome < -0.3 then - biome = 2 + if n_biome >= 0 and n_biome < 0.5 then + biome = 1 --moss + elseif n_biome <= -0.5 then + biome = 2 --fungal + elseif n_biome >= 0.5 then + if n_biome >= 0.7 then + biome = 5 --deep glaciated + else + biome = 4 --glaciated + end else - biome = 3 + biome = 3 --algae end --place dirt on floor, add plants if biome == 1 then @@ -787,6 +959,38 @@ minetest.register_on_generated(function(minp, maxp, seed) data[vi] = c_lichen elseif biome == 3 then data[vi] = c_algae + elseif biome == 4 then + data[vi] = c_thinice + local bi = area:index(x,y-1,z) + data[bi] = c_thinice + --bi = area:index(x,y-2,z) + --data[bi] = c_water + --bi = area:index(x,y-3,z) + --if math.random() <= GEMCHA then + --data[bi] = c_gem + --else + --data[bi] = c_water + --end + --bi = area:index(x,y-4,z) + --data[bi] = c_stone + --bi = area:index(x,y-5,z) + --data[bi] = c_stone + elseif biome == 5 then + data[vi] = c_ice + local bi = area:index(x,y-1,z) + data[bi] = c_ice + --bi = area:index(x,y-2,z) + --data[bi] = c_water + --bi = area:index(x,y-3,z) + --if math.random() <= GEMCHA then + --data[bi] = c_gem + --else + --data[bi] = c_water + --end + --bi = area:index(x,y-4,z) + --data[bi] = c_stone + --bi = area:index(x,y-5,z) + --data[bi] = c_stone end --on random chance, place glow crystal formations if math.random() <= CRYSTAL then @@ -814,6 +1018,10 @@ minetest.register_on_generated(function(minp, maxp, seed) caverealms:giant_shroom(x, y, z, area, data) end end + if math.random() < ICICHA and (biome == 4 or biome == 5) then + local gi = area:index(x,y+1,z) + data[gi] = c_iciu + end dirt[si] = 0 else -- solid rock stable[si] = 0 @@ -851,12 +1059,18 @@ minetest.register_on_generated(function(minp, maxp, seed) --determine biome local biome = false --preliminary declaration n_biome = nvals_biome[nixz2] --make an easier reference to the noise - if n_biome >= 0.3 then - biome = 1 - elseif n_biome < -0.3 then - biome = 2 + if n_biome >= 0 and n_biome < 0.5 then + biome = 1 --moss + elseif n_biome <= -0.5 then + biome = 2 --fungal + elseif n_biome >= 0.5 then + if n_biome >= 0.7 then + biome = 5 + else + biome = 4 --glaciated + end else - biome = 3 + biome = 3 --algae end --glow worm if math.random() <= WORMCHA then @@ -879,6 +1093,13 @@ minetest.register_on_generated(function(minp, maxp, seed) end end end + if math.random() < ICICHA and (biome == 4 or biome == 5) then + local ai = area:index(x,y+1,z)--index of node above + if data[ai] ~= c_air then + local gi = area:index(x,y-1,z) + data[gi] = c_icid + end + end if math.random() <= STALCHA then local ai = area:index(x,y+1,z) if data[ai] ~= c_air then diff --git a/textures/caverealms_icicle_down.png b/textures/caverealms_icicle_down.png new file mode 100644 index 0000000..2663c7a Binary files /dev/null and b/textures/caverealms_icicle_down.png differ diff --git a/textures/caverealms_icicle_up.png b/textures/caverealms_icicle_up.png new file mode 100644 index 0000000..ff9ee25 Binary files /dev/null and b/textures/caverealms_icicle_up.png differ diff --git a/textures/caverealms_thin_ice.png b/textures/caverealms_thin_ice.png new file mode 100644 index 0000000..0d0820f Binary files /dev/null and b/textures/caverealms_thin_ice.png differ