Support for landslide and cavein efects.

master
SFENCE 2019-10-03 08:16:56 +02:00
parent bf8a822e2e
commit f47bc52b6f
8 changed files with 338 additions and 39 deletions

View File

@ -1,6 +1,6 @@
License of media (textures and sounds)
--------------------------------------
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>, Martin Strympl <sfence.software@gmail.com>
See README.txt in each mod directory for information about other authors.
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)

View File

@ -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

View File

@ -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")

View File

@ -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"),

19
mods/default/ores.lua Normal file
View File

@ -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

View File

@ -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,

View File

@ -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 = {};

View File

@ -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");