From f47bc52b6f9911057cd73332e9812a9b5a381fd8 Mon Sep 17 00:00:00 2001 From: SFENCE Date: Thu, 3 Oct 2019 08:16:56 +0200 Subject: [PATCH] Support for landslide and cavein efects. --- LICENSE.txt | 2 +- mods/default/firmness.lua | 291 ++++++++++++++++++++++++++++++++++---- mods/default/init.lua | 5 +- mods/default/nodes.lua | 42 ++++++ mods/default/ores.lua | 19 +++ mods/fire/init.lua | 4 +- mods/recipes/recipes.lua | 4 +- mods/test/nodes.lua | 10 +- 8 files changed, 338 insertions(+), 39 deletions(-) create mode 100644 mods/default/ores.lua diff --git a/LICENSE.txt b/LICENSE.txt index 48f0b8d..40e469f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ License of media (textures and sounds) -------------------------------------- -Copyright (C) 2010-2012 celeron55, Perttu Ahola +Copyright (C) 2010-2012 celeron55, Perttu Ahola , Martin Strympl See README.txt in each mod directory for information about other authors. Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) diff --git a/mods/default/firmness.lua b/mods/default/firmness.lua index 6ddbf76..6d5319b 100644 --- a/mods/default/firmness.lua +++ b/mods/default/firmness.lua @@ -8,7 +8,7 @@ -- firmness mean number of steps under where should be any type of prop to prvent falling -- resilience mean number of step after prop is out of use, where increase probability of start falling -function default.is_should_fall(pos, node, only_firmness) +function default.is_should_fall(pos, node, only_firmness, to_stable) --minetest.log("warning", "default.is_should_fall called."); local node_def = minetest.registered_nodes[node.name]; @@ -58,10 +58,12 @@ function default.is_should_fall(pos, node, only_firmness) if ((node_walkable==true) and (falling_node==0)) then --minetest.log("warning", "Walkable on "..dump(pos_find).." for "..dump(pos)) is_should_fall = false; - node.name = default.firmness_node_to_stable[node.name]; - if (node.name) then - --minetest.log("warning", "To stable "..dump(pos)) - minetest.swap_node(pos, node); + if (to_stable==true) then + node.name = default.firmness_node_to_stable[node.name]; + if (node.name) then + --minetest.log("warning", "To stable "..dump(pos)) + minetest.swap_node(pos, node); + end end return false; end @@ -151,6 +153,7 @@ function default.is_should_fall(pos, node, only_firmness) end function default.check_neighbour_for_fall(pos) + --minetest.log("warning", "Check neighbour."); --minetest.log("warning", "Check neighbour on: "..dump(pos)); local check_pos = table.copy(pos); @@ -163,16 +166,9 @@ function default.check_neighbour_for_fall(pos) --minetest.log("warning", "After destruct x_diff: "..tostring(x_diff).." z_diff: "..tostring(z_diff).." y_diff: "..tostring(y_diff)); local check_node = minetest.get_node(check_pos); if (check_node.name~="ignore") then - local fall_it = default.is_should_fall(check_pos, check_node, true); + local fall_it = default.is_should_fall(check_pos, check_node, true, false); if (fall_it==true) then - local new_node_name = default.firmness_node_to_falling[check_node.name]; - if (new_node_name~=nil) then - --minetest.log("warning", "Falling 170 node "..check_node.name..": "..dump(check_pos)); - minetest.swap_node(check_pos,{name=new_node_name}); - else - minetest.spawn_falling_node(check_pos); - end - minetest.check_for_falling(check_pos); + default.fall_stable_node(check_pos, check_node, true); if (y_diff>0) then --minetest.log("warning", "Near refall check of "..check_node.name); minetest.after(1, default.check_neighbour_for_fall, table.copy(check_pos)); @@ -184,6 +180,164 @@ function default.check_neighbour_for_fall(pos) end end +-- when some node starts to fall, it can create cave-in effect. +-- use group cavein with values 1-100 to set probability of canein effect +function default.check_for_cavein(pos) + local node = minetest.get_node(pos); + local node_def = minetest.registered_nodes[node.name]; + + local cavein = node_def.groups["cavein"]; + + minetest.log("warning", "Node: "..node.name.." Cavein: "..tostring(cavein)) + + if ((cavein) and (cavein>0)) then + local check_pos = table.copy(pos); + check_pos.y = pos.y -1; + + local check_node = minetest.get_node(check_pos); + if (check_node.name=="ignore") then + return; + end + local node_def = minetest.registered_nodes[check_node.name]; + local node_walkable = node_def.walkable; + if (node_walkable==true) then + return; + end + + local no_cavein_points = 0; + local cavein_points = 0; + local recall_pos = {}; + + for y_diff = -1,1,1 do + check_pos.y = pos.y + y_diff; + local y_factor = (y_diff/2.0)+1.0; -- 0.5 to 1.5 + for x_diff = -1,1,1 do + check_pos.x = pos.x + x_diff; + for z_diff = -1,1,1 do + check_pos.z = pos.z + z_diff; + + if ((y_diff~=0) or (x_diff~=0) or (z_diff~=0)) then + local check_node = minetest.get_node(check_pos); + if (check_node.name~="ignore") then + local node_def = minetest.registered_nodes[check_node.name]; + local node_walkable = node_def.walkable; + + local distance = vector.distance(pos, check_pos); + + if (node_walkable==false) then + -- remove stability + cavein_points = cavein_points + (cavein/(y_factor*distance)); + else + -- add stability + no_cavein_points = no_cavein_points + (100/(y_factor*distance)); + + table.insert(recall_pos, table.copy(check_pos)); + end + + minetest.log("warning", "CaveIn points: "..tostring(cavein_points).."No cavin points:"..tostring(no_cavein_points).." cavein: "..tostring(cavein).." y_factor: "..tostring(y_factor).." distance:"..tostring(distance).." node_walkable: "..tostring(node_walkable)); + end + end + end + end + end + + local chance = (default.random_generator:next(0, 65535)/65535.0); + local no_cavein_chance = no_cavein_points/(no_cavein_points+cavein_points); + + minetest.log("warning", "Chance: "..tostring(chance).." No_cavein_chance: "..tostring(no_cavein_chance)); + + if (chance>no_cavein_chance) then + default.fall_stable_node(pos, node, false); + + for key, recall_pos in pairs(recall_pos) do + minetest.after(0.4, default.check_for_cavein, recall_pos); + end + end + end + +end + +-- if falling done fall to another node, and there is free space in another node level, it can happen to fall into that area +-- use group landslide with values 1-100 to set probability of landslide happen +function default.check_for_landslide(pos) + local node = minetest.get_node(pos); + local node_def = minetest.registered_nodes[node.name]; + + local landslide = node_def.groups["landslide"]; + + --minetest.log("warning", "Landslide: "..tostring(landslide)); + + if ((landslide) and (landslide>0)) then + local check_pos = table.copy(pos); + check_pos.y = pos.y -1; + + local check_node = minetest.get_node(check_pos); + if (check_node.name=="ignore") then + return; + end + local node_def = minetest.registered_nodes[check_node.name]; + local node_falling = node_def.groups["falling_node"]; + if (not(node_falling) or (node_falling<=0)) then + return; + end + + --minetest.log("warning", "Find positions of posible landslide,"); + + local landslide_pos = {}; + + for x_diff = -1,1,1 do + check_pos.x = pos.x + x_diff; + for z_diff = -1,1,1 do + check_pos.z = pos.z + z_diff; + if ((x_diff~=0)~=(z_diff~=0)) then -- xor + check_pos.y = pos.y; + + local check_node = minetest.get_node(check_pos); + if (check_node.name~="ignore") then + local node_def = minetest.registered_nodes[check_node.name]; + + if (node_def.buildable_to==true) then + check_pos.y = pos.y - 1; + + local check_node = minetest.get_node(check_pos); + if (check_node.name~="ignore") then + local node_def = minetest.registered_nodes[check_node.name]; + + if (node_def.buildable_to==true) then + table.insert(landslide_pos, table.copy(check_pos)) + end + end + end + end + end + end + end + + --minetest.log("warning", dump(landslide_pos)); + local positions = #landslide_pos; + if (positions>0) then + local chance = (default.random_generator:next(0, 65535)/65535.0)*100; + + --minetest.log("warning", "Chance: "..tostring(chance).." Landslide: "..tostring(landslide)); + + if (chance<=landslide) then + local move_pos = {}; + if (positions>1) then + local index = default.random_generator:next(1,#landslide_pos) + + move_pos = landslide_pos[index]; + else + move_pos = landslide_pos[1]; + end + + minetest.set_node(move_pos, node); + minetest.remove_node(pos); + minetest.check_single_for_falling(move_pos); + end + end + end +end + -- should be done for neightbour of stable or normal destroyed node -- default neightbour is 8 ( expect sum of firmness and resilience is not bigger then 8) function default.neighbour_stable_to_normal(pos) @@ -191,7 +345,7 @@ function default.neighbour_stable_to_normal(pos) local pos2 = {x = pos.x+8, y = pos.y+8, z = pos.z+8}; local positions = minetest.find_nodes_in_area(pos1, pos2, default.firmness_node_stable_names); - --minetest.log("warning", "Area "..dump(pos1).." to "..dump(pos2).." found "..tostring(#positions)); + -- minetest.log("warning", "Area "..dump(pos1).." to "..dump(pos2).." found "..tostring(#positions)); if (positions) then for i, find_pos in ipairs(positions) do @@ -210,40 +364,119 @@ default.firmness_node_to_stable = {}; default.firmness_node_from_stable = {}; default.firmness_node_stable_names = {}; +function default.fall_stable_node(pos, node, check_cavein) + --minetest.log("warning", "fall_stable_node."); + local new_node_name = default.firmness_node_to_falling[node.name]; + if (new_node_name~=nil) then + --minetest.log("warning", "Falling 296: "..dump(pos)); + minetest.swap_node(pos,{name=new_node_name}); + else + minetest.spawn_falling_node(pos); + end + minetest.check_for_falling(pos); + default.neighbour_stable_to_normal(pos); + + if (check_cavein==true) then + local check_pos = table.copy(pos); + + for x_diff = -1,1,1 do + check_pos.x = pos.x + x_diff; + for z_diff = -1,1,1 do + check_pos.z = pos.z + z_diff; + for y_diff = -1,1,1 do + check_pos.y = pos.y + y_diff; + + if ((x_diff~=0) or (y_diff~=0) or (z_diff~=0)) then + --minetest.log("warning", "X: "..tostring(check_pos.x).." Y:"..tostring(check_pos.y).." Z: "..tostring(check_pos.z)); + default.check_for_cavein(check_pos); + end + end + end + end + end +end + function default.register_firmness_node_change(node_name, falling_node_name, stable_node_name) - default.firmness_node_to_falling[node_name] = falling_node_name; - table.insert(default.firmness_node_falling_names, falling_node_name); - default.firmness_node_to_stable[node_name] = stable_node_name; - default.firmness_node_from_stable[stable_node_name] = node_name; - table.insert(default.firmness_node_stable_names, stable_node_name); + if (falling_node_name) then + default.firmness_node_to_falling[node_name] = falling_node_name; + table.insert(default.firmness_node_falling_names, falling_node_name); + end + if (stable_node_name) then + default.firmness_node_to_stable[node_name] = stable_node_name; + default.firmness_node_from_stable[stable_node_name] = node_name; + table.insert(default.firmness_node_stable_names, stable_node_name); + end end function default.firmness_abm_action(pos, node) - local fall_it = default.is_should_fall(pos, node, false); + local fall_it = default.is_should_fall(pos, node, false, true); --minetest.log("warning", "Node on pos "..dump(pos).." fall it is "..tostring(fall_it)); if (fall_it==true) then - local new_node_name = default.firmness_node_to_falling[node.name]; - if (new_node_name~=nil) then - --minetest.log("warning", "Falling 227: "..dump(pos)); - minetest.swap_node(pos,{name=new_node_name}); - else - minetest.spawn_falling_node(pos); - end - minetest.check_for_falling(pos); + default.fall_stable_node(pos, node, true); --default.firmness_after_destruct(pos, node); --minetest.after(1, default.check_neighbour_for_fall, pos); end end function default.firmness_after_destruct(pos, oldnode) + minetest.log("warning", "after_destruct"); default.neighbour_stable_to_normal(pos); --default.check_neighbour_for_fall(pos); minetest.after(1, default.check_neighbour_for_fall, pos); end function default.firmness_preserve_metadata(pos, oldnode, oldmeta, drops) + minetest.log("warning", "preverse_metadata"); default.neighbour_stable_to_normal(pos); --default.check_neighbour_for_fall(pos); minetest.after(1, default.check_neighbour_for_fall, pos); end +-- settings should include firmness, resilience, names +function default.register_node_with_firmness(node_def, settings) + if (setting.normal_node) then + normal_def = table.copy(node_def); + + normal_def.groups.firmness = setting.firmness; + normal_def.groups.resilience = setting.resilience; + + normal_def.after_destruct = default.firmness_after_destruct; + normal_def.preserve_metadata = default.firmness_preserve_metadata; + + minetest.register_node(setting.normal_node, normal_def); + end + + if (setting.stable_node) then + stable_def = table.copy(node_def); + + if not(stable_def.drops) then + stable_def.drops = setting.normal_node; + end + + stable_def.groups.not_in_creative_inventory = 1; + + stable_def.after_destruct = default.firmness_after_destruct; + + minetest.register_node(setting.stable_node, stable_def); + + default.register_firmness_node_change(setting.normal_node, nil, setting.stable_node); + end + + if (setting.falling_node) then + falling_def = table.copy(node_def); + + if not(falling_def.drops) then + falling_def.drops = setting.normal_node; + end + + falling_def.groups.falling_node = 1; + falling_def.groups.not_in_creative_inventory = 1; + + falling_def.after_destruct = default.firmness_after_destruct, + + minetest.register_node(setting.falling_node, stable_def); + + default.register_firmness_node_change(setting.normal_node, setting.falling_node, nil); + end +end + diff --git a/mods/default/init.lua b/mods/default/init.lua index 432f343..5e239ff 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -45,6 +45,9 @@ default.random_generator = PcgRandom(os.time()); -- Load files local default_path = minetest.get_modpath("default") +dofile(default_path.."/firmness.lua") +dofile(default_path.."/ores.lua") + dofile(default_path.."/functions.lua") dofile(default_path.."/trees.lua") dofile(default_path.."/nodes.lua") @@ -58,5 +61,3 @@ dofile(default_path.."/crafting.lua") dofile(default_path.."/mapgen.lua") dofile(default_path.."/aliases.lua") dofile(default_path.."/legacy.lua") - -dofile(default_path.."/firmness.lua") diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 621e581..97a352d 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -1239,6 +1239,13 @@ minetest.register_node("default:stone_with_iron", { drop = "default:iron_lump", sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:gravel_with_iron", { + description = S("Iron Ore"), + tiles = {"default_gravel.png^default_mineral_iron.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:iron_lump", + sounds = default.node_sound_gravel_defaults(), +}) minetest.register_node("default:steelblock", { description = S("Steel Block"), @@ -1256,6 +1263,13 @@ minetest.register_node("default:stone_with_copper", { drop = "default:copper_lump", sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:gravel_with_copper", { + description = S("Copper Ore"), + tiles = {"default_gravel.png^default_mineral_copper.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:copper_lump", + sounds = default.node_sound_gravel_defaults(), +}) minetest.register_node("default:copperblock", { description = S("Copper Block"), @@ -1273,6 +1287,13 @@ minetest.register_node("default:stone_with_tin", { drop = "default:tin_lump", sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:gravel_with_tin", { + description = S("Tin Ore"), + tiles = {"default_gravel.png^default_mineral_tin.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:tin_lump", + sounds = default.node_sound_gravel_defaults(), +}) minetest.register_node("default:tinblock", { description = S("Tin Block"), @@ -1299,6 +1320,13 @@ minetest.register_node("default:stone_with_mese", { drop = "default:mese_crystal", sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:gravel_with_mese", { + description = S("Mese Ore"), + tiles = {"default_gravel.png^default_mineral_mese.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:mese_crystal", + sounds = default.node_sound_gravel_defaults(), +}) minetest.register_node("default:mese", { description = S("Mese Block"), @@ -1317,6 +1345,13 @@ minetest.register_node("default:stone_with_gold", { drop = "default:gold_lump", sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:gravel_with_gold", { + description = S("Gold Ore"), + tiles = {"default_gravel.png^default_mineral_gold.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:gold_lump", + sounds = default.node_sound_gravel_defaults(), +}) minetest.register_node("default:goldblock", { description = S("Gold Block"), @@ -1334,6 +1369,13 @@ minetest.register_node("default:stone_with_diamond", { drop = "default:diamond", sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:gravel_with_diamond", { + description = S("Diamond Ore"), + tiles = {"default_gravel.png^default_mineral_diamond.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:diamond", + sounds = default.node_sound_gravel_defaults(), +}) minetest.register_node("default:diamondblock", { description = S("Diamond Block"), diff --git a/mods/default/ores.lua b/mods/default/ores.lua new file mode 100644 index 0000000..769d2ae --- /dev/null +++ b/mods/default/ores.lua @@ -0,0 +1,19 @@ + +local S = default.get_translator + +function default.register_ore_desert_and_gravel(ore_name, ore_def) + minetest.register_node("default:stone_with_iron", { + description = S("Iron Ore"), + tiles = {"default_stone.png^default_mineral_iron.png"}, + groups = {cracky = 2}, + drop = "default:iron_lump", + sounds = default.node_sound_stone_defaults(), + }) + minetest.register_node("default:gravel_with_iron", { + description = S("Iron Ore"), + tiles = {"default_gravel.png^default_mineral_iron.png"}, + groups = {crumbly = 2, falling_node = 1}, + drop = "default:iron_lump", + sounds = default.node_sound_gravel_defaults(), + }) +end diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 3c8a8fc..a1ee957 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -63,7 +63,7 @@ minetest.register_node("fire:basic_flame", { sunlight_propagates = true, floodable = true, damage_per_second = 4, - groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1}, + groups = {igniter = 2, not_in_creative_inventory = 1}, drop = "", on_timer = function(pos) @@ -109,7 +109,7 @@ minetest.register_node("fire:permanent_flame", { sunlight_propagates = true, floodable = true, damage_per_second = 4, - groups = {igniter = 2, dig_immediate = 3}, + groups = {igniter = 2}, drop = "", on_flood = flood_flame, diff --git a/mods/recipes/recipes.lua b/mods/recipes/recipes.lua index 12ae21e..9f4c7b2 100644 --- a/mods/recipes/recipes.lua +++ b/mods/recipes/recipes.lua @@ -6,8 +6,8 @@ local S = recipes.S; -- category -> category name string, used by machines to select only aviable recepts -- manual -> list of tables with one key and one value, where key mean work_name and key value mean, work_points. Work_name specify tool group which have to be used to work, higger group mean quicker work, work_point specify number of work which have to be done -- tool_in_order -> true if tool have to be used in order of manual definition, false when the usage in order is not required --- input -> recipe inputs, list of list --- output -> recipe outouts list +-- input -> recipe inputs, list of list (default:stone, deault:tool +5) +-- output -> recipe outouts list (default:stone, default:stone 5) recipes.recipes = {}; diff --git a/mods/test/nodes.lua b/mods/test/nodes.lua index 1331b05..6497fad 100644 --- a/mods/test/nodes.lua +++ b/mods/test/nodes.lua @@ -8,13 +8,12 @@ local S = test.S; minetest.register_node("test:firmness", { description = S("Firmness test"), tiles = {"test_node.png"}, - groups = {cracky = 1, oddly_breakable_by_hand = 1, firmness = 2, resilience = 3}, + groups = {cracky = 1, oddly_breakable_by_hand = 1, firmness = 2, resilience = 3, cavein = 5}, drop = "test:firmness", legacy_mineral = true, sounds = default.node_sound_stone_defaults(), after_destruct = default.firmness_after_destruct, - preserve_metadata = default.firmness_preserve_metadata; }) minetest.register_node("test:firmness_stable", { @@ -31,11 +30,16 @@ minetest.register_node("test:firmness_stable", { minetest.register_node("test:firmness_falling", { description = S("Firmness test falling"), tiles = {"test_node.png"}, - groups = {cracky = 1, oddly_breakable_by_hand = 1, falling_node=1, not_in_creative_inventory=1}, + groups = {cracky = 1, oddly_breakable_by_hand = 1, falling_node=1, landslide=90, not_in_creative_inventory=1}, drowning = 1, drop = "test:firmness", legacy_mineral = true, sounds = default.node_sound_stone_defaults(), + + on_construct = function (pos) + --minetest.log("warning", "on_construct") + minetest.after(0.1, default.check_for_landslide, pos); + end, }) default.register_firmness_node_change("test:firmness", "test:firmness_falling", "test:firmness_stable");