Christian Sirolli c6e4f75dec Update 2 files
- /init.lua
- /moretrees.lua
2024-04-25 16:31:15 +00:00

403 lines
15 KiB
Lua

bettertrees = {
path = minetest.get_modpath('bettertrees'),
mods = {
default = minetest.global_exists('default'),
armor = minetest.global_exists('3d_armor'),
mcl = minetest.global_exists('mcl_core'),
-- stripped_tree = minetest.global_exists('stripped_tree'),
-- hunger_ng = minetest.global_exists('hunger_ng')
xdecor = minetest.global_exists('xdecor'),
moretrees = minetest.global_exists('moretrees'),
},
config = {
bushy = minetest.settings:get_bool('bettertrees.bushy', true),
cheap_bushy = minetest.settings:get_bool('bettertrees.cheap_bushy', false),
web = minetest.settings:get_bool('bettertrees.web', true),
web_min_rand = 60*20,
web_max_rand = 60*30,
}
}
local S = minetest.get_translator()
dofile(bettertrees.path .. '/functions.lua')
if bettertrees.mods.default then
bettertrees.stick = 'default:stick'
bettertrees.stick_sound = default.node_sound_wood_defaults()
bettertrees.stick_node = ':' .. bettertrees.stick
elseif bettertrees.mods.mcl then
bettertrees.stick = 'mcl_core:stick'
bettertrees.stick_sound = mcl_sounds.node_sound_wood_defaults()
bettertrees.stick_node = ':' .. bettertrees.stick
else
bettertrees.stick = 'bettertrees:stick'
bettertrees.stick_sound = nil
bettertrees.stick_node = bettertrees.stick
end
--- Runs code to place hidden node that regenerates leaves
---@param pos table
---@param node_name string
local function spawn_hidden(pos, node_name)
minetest.set_node(pos, {
name = "bettertrees:hidden"
})
local meta = minetest.get_meta(pos)
meta:set_string("leaf", node_name)
end
--- Runs code to break leaves, by either dropping them or decaying them into sticks
---@param pos table
---@param node_name string
---@param decay boolean
local function break_leaf(pos, node_name, decay)
if decay == true and bettertrees.stick then
minetest.swap_node(pos, {
name = bettertrees.stick
})
minetest.check_single_for_falling(pos)
else
minetest.dig_node(pos)
end
spawn_hidden(pos, node_name)
end
if bettertrees.config.web then
if bettertrees.mods.xdecor then
minetest.override_item("bettertrees:spider_web", {
description = S("Spider Web"),
on_construct = function(pos)
local time = math.random(bettertrees.config.web_min_rand, bettertrees.config.web_max_rand)
minetest.get_node_timer(pos):start(time)
end,
on_timer = function(pos, elapsed)
if math.random(200) == 1 then
minetest.swap_node(pos, {
name = 'bettertrees:spider_web_broken'
})
end
return true
end,
})
-- register alias with xdecor:cobweb
else
minetest.register_node("bettertrees:spider_web", {
description = S("Spider Web"),
drawtype = "plantlike",
tiles = {"xdecor_cobweb.png"},
inventory_image = "xdecor_cobweb.png",
move_resistance = 8,
walkable = false,
selection_box = {type = "regular"},
groups = {snappy = 3, flammable = 3},
is_ground_content = false,
sounds = default.node_sound_leaves_defaults(),
on_construct = function(pos)
local time = math.random(bettertrees.config.web_min_rand, bettertrees.config.web_max_rand)
minetest.get_node_timer(pos):start(time)
end,
on_timer = function(pos, elapsed)
if math.random(200) == 1 then
minetest.swap_node(pos, {
name = 'bettertrees:spider_web_broken'
})
end
return true
end,
})
-- register alias with xdecor:cobweb
end
minetest.register_node("bettertrees:spider_web_broken", {
description = S("Broken Spider Web"),
drawtype = "plantlike",
tiles = {"xdecor_cobweb.png"},
inventory_image = "xdecor_cobweb.png",
move_resistance = 8,
walkable = false,
selection_box = {type = "regular"},
groups = {snappy = 3, flammable = 3},
is_ground_content = false,
sounds = default.node_sound_leaves_defaults(),
on_construct = function(pos)
local time = math.random(bettertrees.config.web_min_rand, bettertrees.config.web_max_rand)
minetest.get_node_timer(pos):start(time)
end,
on_timer = function(pos, elapsed)
if math.random(200) == 1 then
minetest.swap_node(pos, {
name = 'air'
})
end
return true
end,
})
end
-- Regrow leaves or fruit, adapted from Tenplus1's regrow mod, licensed under MIT
minetest.register_node('bettertrees:hidden', {
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
drop = "",
groups = {
not_in_creative_inventory = 1
},
-- once placed start random timer between 20 and 30 minutes
on_construct = function(pos)
local time = math.random(60 * 20, 60 * 30)
minetest.get_node_timer(pos):start(time)
end,
-- when timer reached check which leaf or fruit to place if tree still exists
on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos)
if not meta then
return
end
local fruit = meta:get_string("fruit") or ""
local leaf = meta:get_string("leaf") or ""
if fruit == "" then
if leaf == "" or not minetest.find_node_near(pos, 1, leaf) then
leaf = "air"
end
minetest.set_node(pos, {
name = leaf
})
else
if leaf == "" or fruit == "" or not minetest.find_node_near(pos, 1, leaf) then
fruit = "air"
end
minetest.set_node(pos, {
name = fruit
})
end
end
})
if bettertrees.stick then
-- Basically strip leaves off branches
minetest.register_craft({
type = 'shapeless',
output = bettertrees.stick,
recipe = {'group:leaves'}
-- replacements = 'pile of leaves?'
})
minetest.register_node(bettertrees.stick_node, {
description = S('Stick'),
drawtype = 'mesh',
paramtype = 'light',
paramtype2 = 'none',
selection_box = {
type = 'fixed',
fixed = {-8 / 16, -8 / 16, -8 / 16, 8 / 16, -7 / 16, 8 / 16}
},
mesh = 'extrusion_mesh_16.obj',
tiles = {'default_stick.png'},
use_texture_alpha = 'clip',
inventory_image = "default_stick.png",
wield_image = "default_stick.png",
floodable = true,
walkable = false,
sunlight_propagates = true,
buildable_to = true,
is_ground_content = false,
groups = {
stick = 1,
falling_node = 1,
oddly_breakable_by_hand = 3,
snappy = 3,
flammable = 2,
choppy = 3,
attached_node = 1,
dig_immediate = 3,
},
sounds = bettertrees.stick_sound
})
end
minetest.register_on_mods_loaded(function()
local tree_nodes = {}
local dirt_nodes = {}
for node_name, def in pairs(minetest.registered_nodes) do
if def.groups and def.groups.leaves then
local override = {}
if not string.match(node_name, "bush") then
override = {
walkable = false,
climbable = true,
-- Climbing through leaves should slow players down
move_resistance = 3,
waving = 2,
-- Make leaves fall when placed
after_place_node = function(pos, oldnode, oldmeta, drops)
minetest.spawn_falling_node(pos)
end,
-- Adapted from Tenplus1's regrow mod, licensed under MIT
after_dig_node = function(pos, oldnode, oldmetadata, digger)
-- if node has been placed by player then do not regrow
if oldnode.param2 > 0 then
return
end
-- replace leaf with regrowth node, set leaf name
spawn_hidden(pos, node_name)
end,
on_construct = function(pos)
local time = math.random(60 * 20, 60 * 30)
minetest.get_node_timer(pos):start(time)
end,
-- when timer reached, check which leaf to remove
on_timer = function(pos, elapsed)
if math.random(200) == 1 then
local pos2 = table.copy(pos)
pos2.y = pos2.y - 1
local check_node = minetest.get_node(pos2)
if check_node.name == 'air' then
break_leaf(pos, node_name, true)
return false
end
end
return true
end
}
end
if bettertrees.config.bushy then
override.drawtype = 'mesh'
override.mesh = bettertrees.config.bushy_cheap and "bushy_leaves_cheap_model.obj" or "bushy_leaves_full_model.obj"
end
minetest.override_item(node_name, override)
elseif def.groups and def.groups.tree then
table.insert(tree_nodes, node_name)
local groups = table.copy(def.groups)
groups.oddly_breakable_by_hand = 0
-- groups.falling_node = 1
minetest.override_item(node_name, {
groups = groups,
on_punch = function(pos, node, puncher, pointed_thing)
local wielded_item = puncher:get_wielded_item();
if wielded_item:is_empty() then
-- take a little damage
local hp = puncher:get_hp()
puncher:set_hp(hp - 0.1, 'node_damage')
end
minetest.node_punch(pos, node, puncher, pointed_thing)
end,
on_dig = function(pos, node, digger)
-- this is where we start the logic to fell the tree
end,
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
if not meta then
return
end
if meta:contains('bettertrees_uuid') then
meta:set_string('bettertrees_uuid', '')
end
end,
})
elseif def.groups and (def.groups.soil or def.groups.snowy) then
table.insert(dirt_nodes, node_name)
elseif def.groups and def.groups.leafdecay_drop then
minetest.override_item(node_name, {
after_dig_node = function(pos, oldnode, oldmetadata, digger)
-- if node has been placed by player then do not regrow
if oldnode.param2 > 0 then
return
end
-- replace leaf with regrowth node, set leaf name
minetest.set_node(pos, {
name = "bettertrees:hidden"
})
local meta = minetest.get_meta(pos)
meta:set_string("leaf", minetest.get_node(minetest.find_node_near(pos, 1, 'group:leaves')).name)
meta:set_string("fruit", node_name)
end,
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
if not meta then
return
end
if meta:contains('bettertrees_uuid') then
meta:set_string('bettertrees_uuid', '')
end
end,
})
end
end
minetest.log('verbose', 'bettertrees: tree_nodes = '..minetest.serialize(tree_nodes))
minetest.log('verbose', 'bettertrees: dirt_nodes = '..minetest.serialize(dirt_nodes))
if bettertrees.stick then
minetest.register_decoration({
name = bettertrees.stick,
deco_type = 'simple',
place_on = dirt_nodes,
sidelen = 8,
decoration = bettertrees.stick,
rotation = 'random',
spawn_by = tree_nodes,
num_spawn_by = 1,
fill_ratio = 0.1,
})
end
end)
-- chance of limbs breaking while player is in leaves
minetest.register_globalstep(function(dtime)
local players = minetest.get_connected_players()
for i, player in ipairs(players) do
if minetest.is_player(player) then
local pos = player:get_pos()
local pos2 = table.copy(pos)
pos2.y = pos2.y + 1
local nodes = minetest.find_nodes_in_area(pos, pos2, 'group:leaves', true)
for node_name, node_poss in pairs(nodes) do
for i, node_pos in ipairs(node_poss) do
local chance = 200
-- calculate "weight" of armor and deduct from `chance`
if bettertrees.mods.armor then
local sum_gravity = 1
local worn_armor = armor:get_weared_armor_elements(player)
for el, i in ipairs(worn_armor) do
if el.groups and el.groups.physics_gravity then
sum_gravity = sum_gravity + (el.groups.physics_gravity * 10)
end
end
chance = chance / sum_gravity
end
if math.random(chance) == 1 then
break_leaf(node_pos, node_name, false)
end
end
end
end
end
end)
og_spawn_tree = minetest.spawn_tree
-- attempt to patch minetest.swawn_tree to assign uuid to nodes
function minetest.spawn_tree(pos, tree_def)
local result = og_spawn_tree(pos, tree_def)
local nodes = []
if (tree_def.fruit) then
table.insert(nodes, tree_def.fruit)
end
if (tree_def.trunk) then
table.insert(nodes, tree_def.trunk)
end
if (tree_def.leaves) then
table.insert(nodes, tree_def.leaves)
end
assign_uuid({ x = pos.x - 1, y = pos.y - 1, z = pos.z - 1 }, { x = pos.x + 1, y = pos.y + 3, z = pos.z + 1 }, nodes)
return result
end
if bettertrees.mods.default then
dofile(bettertrees.path .. '/default.lua')
end
if bettertrees.mods.moretrees then
dofile(bettertrees.path .. '/moretrees.lua')
end