Update plantlife_modpack, moretrees and biome_lib as submodules
16
.gitmodules
vendored
|
@ -147,9 +147,6 @@
|
|||
path = minetest_game
|
||||
url = https://github.com/minetest/minetest_game.git
|
||||
branch = backport-0.4
|
||||
[submodule "mods/farming"]
|
||||
path = mods/farming
|
||||
url = https://github.com/tenplus1/farming.git
|
||||
[submodule "mods/unifieddyes"]
|
||||
path = mods/unifieddyes
|
||||
url = https://github.com/minetest-mods/unifieddyes.git
|
||||
|
@ -174,3 +171,16 @@
|
|||
[submodule "mods/sea"]
|
||||
path = mods/sea
|
||||
url = https://github.com/H4mlet/sea.git
|
||||
[submodule "mods/plantlife_modpack"]
|
||||
path = mods/plantlife_modpack
|
||||
url = https://github.com/minetest-mods/plantlife_modpack.git
|
||||
[submodule "mods/biome_lib"]
|
||||
path = mods/biome_lib
|
||||
url = https://github.com/minetest-mods/biome_lib.git
|
||||
[submodule "mods/moretrees"]
|
||||
path = mods/moretrees
|
||||
url = https://github.com/minetest-mods/moretrees.git
|
||||
[submodule "mods/farming"]
|
||||
path = mods/farming
|
||||
url = https://github.com/sys4-fr/farming.git
|
||||
branch = nalc
|
||||
|
|
1
mods/biome_lib
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 8fd0789ad296bcfad13f73084e95b8a93427ef81
|
|
@ -1,579 +0,0 @@
|
|||
This document describes the Plantlife mod API.
|
||||
|
||||
Last revision: 2015-02-16
|
||||
|
||||
|
||||
=========
|
||||
Functions
|
||||
=========
|
||||
|
||||
There are three main functions defined by the main "biome_lib" mod:
|
||||
|
||||
spawn_on_surfaces()
|
||||
register_generate_plant()
|
||||
grow_plants()
|
||||
|
||||
There are also several internal, helper functions that can be called if so
|
||||
desired, but they are not really intended for use by other mods and may change
|
||||
at any time. They are briefly described below these main functions, but see
|
||||
init.lua for details.
|
||||
|
||||
Most functions in plants lib are declared locally to avoid namespace
|
||||
collisions with other mods. They are accessible via the "biome_lib" method,
|
||||
e.g. biome_lib:spawn_on_surfaces() and so forth.
|
||||
|
||||
=====
|
||||
spawn_on_surfaces(biome)
|
||||
spawn_on_surfaces(sdelay, splant, sradius, schance, ssurface, savoid)
|
||||
|
||||
This first function is an ABM-based spawner function originally created as
|
||||
part of Ironzorg's flowers mod. It has since been largely extended and
|
||||
expanded. There are two ways to call this function: You can either pass it
|
||||
several individual string and number parameters to use the legacy interface,
|
||||
or you can pass a single biome definition as a table, with all of your options
|
||||
spelled out nicely. This is the preferred method.
|
||||
|
||||
When used with the legacy interface, you must specify the parameters exactly
|
||||
in order, with the first five being mandatory (even if some are set to nil),
|
||||
and the last one being optional:
|
||||
|
||||
sdelay: The value passed to the ABM's interval parameter, in seconds.
|
||||
splant: The node name of the item to spawn (e.g.
|
||||
"flowers:flower_rose"). A plant will of course only be
|
||||
spawned if the node about to be replaced is air.
|
||||
sradius: Don't spawn within this many nodes of the avoid items
|
||||
mentioned below. If set to nil, this check is skipped.
|
||||
schance: The value passed to the ABM's chance parameter, normally in
|
||||
the 10-100 range (1-in-X chance of operating on a given node)
|
||||
ssurface: String with the name of the node on which to spawn the plant
|
||||
in question, such as "default:sand" or
|
||||
"default:dirt_with_grass". It is not recommended to put air,
|
||||
stone, or plain dirt here if you can use some other node, as
|
||||
doing so will cause the engine to process potentially large
|
||||
numbers of such nodes when deciding when to execute the ABM
|
||||
and where it should operate.
|
||||
savoid: Table with a list of groups and/or node names to avoid when
|
||||
spawning the plant, such as {"group:flowers", "default:tree"}.
|
||||
|
||||
When passed a table as the argument, and thus using the modern calling method,
|
||||
you must pass a number of arguments in the form of an ordinary keyed-value
|
||||
table. Below is a list of everything supported by this function:
|
||||
|
||||
biome = {
|
||||
spawn_plants = something, -- [*] String or table; see below.
|
||||
spawn_delay = number, -- same as sdelay, above.
|
||||
spawn_chance = number, -- same as schance, above.
|
||||
spawn_surfaces = {table}, -- List of node names on which the plants
|
||||
-- should be spawned. As with the single-node "ssurface"
|
||||
-- option in the legacy API, you should not put stone, air,
|
||||
-- etc. here.
|
||||
|
||||
---- From here down are a number of optional parameters. You will
|
||||
---- most likely want to use at least some of these to limit how and
|
||||
---- where your objects are spawned.
|
||||
|
||||
avoid_nodes = {table}, -- same meaning as savoid, above
|
||||
avoid_radius = num, -- same as sradius
|
||||
seed_diff = num, -- The Perlin seed difference value passed to the
|
||||
-- minetest.get_perlin() function. Used along with
|
||||
-- the global Perlin controls below to create the
|
||||
-- "biome" in which the plants will spawn. Defaults
|
||||
-- to 0 if not provided.
|
||||
light_min = num, -- Minimum amount of light necessary to make a plant
|
||||
-- spawn. Defaults to 0.
|
||||
light_max = num, -- Maximum amount of light needed to spawn. Defaults
|
||||
-- to the engine's MAX_LIGHT value of 14.
|
||||
neighbors = {table}, -- List of neighboring nodes that need to be
|
||||
-- immediately next to the node the plant is about to
|
||||
-- spawn on. Can also be a string with a single node
|
||||
-- name. It is both passed to the ABM as the
|
||||
-- "neighbors" parameter, and is used to manually
|
||||
-- check the adjacent nodes. It only takes one of
|
||||
-- these for the spawn routine to mark the target as
|
||||
-- spawnable. Defaults to nil (ignored).
|
||||
ncount = num, -- There must be at least this many of the above
|
||||
-- neighbors in the eight spaces immediately
|
||||
-- surrounding the node the plant is about to spawn on
|
||||
-- for it to happen. If not provided, this check is
|
||||
-- disabled.
|
||||
facedir = num, -- The value passed to the param2 variable when adding
|
||||
-- the node to the map. Defaults to 0. Be sure that
|
||||
-- the value you use here (and the range thereof) is
|
||||
-- appropriate for the type of node you're spawning.
|
||||
random_facedir = {table}, -- If set, the table should contain two values.
|
||||
-- If they're both provided, the spawned plant will be
|
||||
-- given a random facedir value in the range specified
|
||||
-- by these two numbers. Overrides the facedir
|
||||
-- parameter above, if it exists. Use {0,3} if you
|
||||
-- want the full range for wallmounted nodes, or {2,5}
|
||||
-- for most everything else, or any other pair of
|
||||
-- numbers appropriate for the node you want to spawn.
|
||||
depth_max = num, -- If the object spawns on top of a water source, the
|
||||
-- water must be at most this deep. Defaults to 1.
|
||||
min_elevation = num, -- Surface must be at this altitude or higher to
|
||||
-- spawn at all. Defaults to -31000...
|
||||
max_elevation = num, -- ...but must be no higher than this altitude.
|
||||
-- Defaults to +31000.
|
||||
near_nodes = {table}, -- List of nodes that must be somewhere in the
|
||||
-- vicinity in order for the plant to spawn. Can also
|
||||
-- be a string with a single node name. If not
|
||||
-- provided, this check is disabled.
|
||||
near_nodes_size = num, -- How large of an area to check for the above
|
||||
-- node. Specifically, this checks a flat, horizontal
|
||||
-- area centered on the node to be spawned on.
|
||||
-- Defaults to 0, but is ignored if the above
|
||||
-- near_nodes value is not set.
|
||||
near_nodes_vertical = num, -- Used with the size value above, this extends
|
||||
-- the vertical range of the near nodes search.
|
||||
-- Basically, this turns the flat region described
|
||||
-- above into a cuboid region. The area to be checked
|
||||
-- will extend this high and this low above/below the
|
||||
-- target node, centered thereon. Defaults to 1 (only
|
||||
-- check the layer above, the layer at, and the layer
|
||||
-- below the target node), but is ignored if
|
||||
-- near_nodes is not set.
|
||||
near_nodes_count = num, -- How many of the above nodes must be within that
|
||||
-- radius. Defaults to 1 but is ignored if near_nodes
|
||||
-- isn't set. Bear in mind that the total area to be
|
||||
-- checked is equal to:
|
||||
-- (near_nodes_size^2)*near_nodes_vertical*2
|
||||
-- For example, if size is 10 and vertical is 4, then
|
||||
-- the area is (10^2)*8 = 800 nodes in size, so you'll
|
||||
-- want to make sure you specify a value appropriate
|
||||
-- for the size of the area being tested.
|
||||
air_size = num, -- How large of an area to check for air above and
|
||||
-- around the target. If omitted, only the space
|
||||
-- above the target is checked. This does not check
|
||||
-- for air at the sides or below the target.
|
||||
air_count = num, -- How many of the surrounding nodes need to be air
|
||||
-- for the above check to return true. If omitted,
|
||||
-- only the space above the target is checked.
|
||||
plantlife_limit = num, -- The value compared against the generic "plants
|
||||
-- can grow here" Perlin noise layer. Smaller numbers
|
||||
-- result in more abundant plants. Range of -1 to +1,
|
||||
-- with values in the range of about 0 to 0.5 being
|
||||
-- most useful. Defaults to 0.1.
|
||||
temp_min = num, -- Minimum temperature needed for the desired object
|
||||
-- to spawn. This is a 2d Perlin value, which has an
|
||||
-- inverted range of +1 to -1. Larger values
|
||||
-- represent *colder* temperatures, so this value is
|
||||
-- actually the upper end of the desired Perlin range.
|
||||
-- See the temperature map section at the bottom of
|
||||
-- this document for details on how these values work.
|
||||
-- Defaults to +1 (unlimited coldness).
|
||||
temp_max = num, -- Maximum temperature/lower end of the Perlin range.
|
||||
-- Defaults to -1 (unlimited heat).
|
||||
humidity_min = num, -- Minimum humidity for the plant to spawn in. Like
|
||||
-- the temperature map, this is a Perlin value where
|
||||
-- lower numbers mean more humidity in the area.
|
||||
-- Defaults to +1 (0% humidity).
|
||||
humidity_max = num, -- Maximum humidity for the plant to spawn at.
|
||||
-- Defaults to -1 (100% humidity).
|
||||
verticals_list = {table}, -- List of nodes that should be considered to be
|
||||
-- natural walls.
|
||||
alt_wallnode = "string", -- If specified, this node will be substituted in
|
||||
-- place of the plant(s) defined by spawn_plants
|
||||
-- above, if the spawn target has one or more adjacent
|
||||
-- walls. In such a case, the two above facedir
|
||||
-- parameters will be ignored.
|
||||
spawn_on_side = bool, -- Set this to true to immediately spawn the node on
|
||||
-- one side of the target node rather than the top.
|
||||
-- The code will search for an airspace to the side of
|
||||
-- the target, then spawn the plant at the first one
|
||||
-- found. The above facedir and random_facedir
|
||||
-- parameters are ignored in this case. If the above
|
||||
-- parameters for selecting generic wall nodes are
|
||||
-- provided, this option is ignored. Important note:
|
||||
-- the facedir values assigned by this option only
|
||||
-- make sense with wallmounted nodes (nodes which
|
||||
-- don't use facedir won't be affected).
|
||||
choose_random_wall = bool, -- if set to true, and searching for walls is
|
||||
-- being done, just pick any random wall if there is
|
||||
-- one, rather than returning the first one.
|
||||
spawn_on_bottom = bool, -- If set to true, spawn the object below the
|
||||
-- target node instead of above it. The above
|
||||
-- spawn_on_side variable takes precedence over this
|
||||
-- one if both happen to be true. When using this
|
||||
-- option with the random facedir function above, the
|
||||
-- values given to the facedir parameter are for
|
||||
-- regular nodes, not wallmounted.
|
||||
spawn_replace_node = bool, -- If set to true, the target node itself is
|
||||
-- replaced by the spawned object. Overrides the
|
||||
-- spawn_on_bottom and spawn_on_side settings.
|
||||
}
|
||||
|
||||
[*] spawn_plants must be either a table or a string. If it's a table, the
|
||||
values therein are treated as a list of nodenames to pick from randomly on
|
||||
each application of the ABM code. The more nodes you can pack into this
|
||||
parameter to avoid making too many calls to this function, the lower the CPU
|
||||
load will likely be.
|
||||
|
||||
You can also specify a string containing the name of a function to execute.
|
||||
In this case, the function will be passed a single position parameter
|
||||
indicating where the function should place the desired object, and the checks
|
||||
for spawning on top vs. sides vs. bottom vs. replacing the target node will be
|
||||
skipped.
|
||||
|
||||
By default, if a biome node, size, and count are not defined, the biome
|
||||
checking is disabled. Same holds true for the nneighbors bit above that.
|
||||
|
||||
|
||||
=====
|
||||
biome_lib:register_generate_plant(biome, nodes_or_function_or_treedef)
|
||||
|
||||
To register an object to be spawned at mapgen time rather than via an ABM,
|
||||
call this function with two parameters: a table with your object's biome
|
||||
information, and a string, function, or table describing what to do if the
|
||||
engine finds a suitable surface node (see below).
|
||||
|
||||
The biome table contains quite a number of options, though there are fewer
|
||||
here than are available in the ABM-based spawner, as some stuff doesn't make
|
||||
sense at map-generation time.
|
||||
|
||||
biome = {
|
||||
surface = something, -- What node(s). May be a string such as
|
||||
-- "default:dirt_with_grass" or a table with
|
||||
-- multiple such entries.
|
||||
|
||||
---- Everything else is optional, but you'll definitely want to use
|
||||
---- some of these other fields to limit where and under what
|
||||
---- conditions the objects are spawned.
|
||||
|
||||
below_nodes = {table}, -- List of nodes that must be below the target
|
||||
-- node. Useful in snow biomes to keep objects from
|
||||
-- spawning in snow that's on the wrong surface for
|
||||
-- that object.
|
||||
avoid_nodes = {table}, -- List of nodes to avoid when spawning. Groups are
|
||||
-- not supported here.
|
||||
avoid_radius = num, -- How much distance to leave between the object to be
|
||||
-- added and the objects to be avoided. If this or
|
||||
-- the avoid_nodes value is nil/omitted, this check is
|
||||
-- skipped. Avoid using excessively large radii.
|
||||
rarity = num, -- How rare should this object be in its biome? Larger
|
||||
-- values make objects more rare, via:
|
||||
-- math.random(1,100) > this
|
||||
max_count = num, -- The absolute maximum number of your object that
|
||||
-- should be allowed to spawn in a 5x5x5 mapblock area
|
||||
-- (80x80x80 nodes). Defaults to 5, but be sure you
|
||||
-- set this to some reasonable value depending on your
|
||||
-- object and its size if 5 is insufficient.
|
||||
seed_diff = num, -- Perlin seed-diff value. Defaults to 0, which
|
||||
-- causes the function to inherit the global value of
|
||||
-- 329.
|
||||
neighbors = {table}, -- What ground nodes must be right next to and at the
|
||||
-- same elevation as the node to be spawned on.
|
||||
ncount = num, -- At least this many of the above nodes must be next
|
||||
-- to the node to spawn on. Any value greater than 8
|
||||
-- will probably cause the code to never spawn
|
||||
-- anything. Defaults to 0.
|
||||
depth = num, -- How deep/thick of a layer the spawned-on node must
|
||||
-- be. Typically used for water.
|
||||
min_elevation = num, -- Minimum elevation in meters/nodes. Defaults to
|
||||
-- -31000 (unlimited).
|
||||
max_elevation = num, -- Max elevation. Defaults to +31000 (unlimited).
|
||||
near_nodes = {table}, -- what nodes must be in the general vicinity of the
|
||||
-- object being spawned.
|
||||
near_nodes_size = num, -- how wide of a search area to look for the nodes
|
||||
-- in that list.
|
||||
near_nodes_vertical = num, -- How high/low of an area to search from the
|
||||
-- target node.
|
||||
near_nodes_count = num, -- at least this many of those nodes must be in
|
||||
-- the area.
|
||||
plantlife_limit = num, -- The value compared against the generic "plants
|
||||
-- can grow here" Perlin noise layer. Smaller numbers
|
||||
-- result in more abundant plants. Range of -1 to +1,
|
||||
-- with values in the range of about 0 to 0.5 being
|
||||
-- most useful. Defaults to 0.1.
|
||||
temp_min = num, -- Coldest allowable temperature for a plant to spawn
|
||||
-- (that is, the largest Perlin value).
|
||||
temp_max = num, -- warmest allowable temperature to spawn a plant
|
||||
-- (lowest Perlin value).
|
||||
verticals_list = {table}, -- Same as with the spawn_on_surfaces function.
|
||||
check_air = bool, -- Flag to tell the mapgen code to check for air above
|
||||
-- the spawn target. Defaults to true if not
|
||||
-- explicitly set to false. Set this to false VERY
|
||||
-- SPARINGLY, as it will slow the map generator down.
|
||||
delete_above = bool, -- Flag to tell the mapgen code to delete the two
|
||||
-- nodes directly above the spawn target just before
|
||||
-- adding the plant or tree. Useful when generating
|
||||
-- in snow biomes. Defaults to false.
|
||||
delete_above_surround = bool, -- Flag to tell the mapgen code to also
|
||||
-- delete the five nodes surrounding the above space,
|
||||
-- and the five nodes above those, resulting in a two-
|
||||
-- node-deep cross-shaped empty region above/around
|
||||
-- the spawn target. Useful when adding trees to snow
|
||||
-- biomes. Defaults to false.
|
||||
spawn_replace_node = bool, -- same as with the ABM spawner.
|
||||
random_facedir = {table}, -- same as with the ABM spawner.
|
||||
}
|
||||
|
||||
Regarding nodes_or_function_or_treedef, this must either be a string naming
|
||||
a node to spawn, a table with a list of nodes to choose from, a table with an
|
||||
L-Systems tree definition, or a function.
|
||||
|
||||
If you specified a string, the code will attempt to determine whether that
|
||||
string specifies a valid node name. If it does, that node will be placed on
|
||||
top of the target position directly (unless one of the other mapgen options
|
||||
directs the code to do otherwise).
|
||||
|
||||
If you specified a table and there is no "axiom" field, the code assumes that
|
||||
it is a list of nodes. Simply name one node per entry in the list, e.g.
|
||||
{"default:junglegrass", "default:dry_shrub"} and so on, for as many nodes as
|
||||
you want to list. A random node from the list will be chosen each time the
|
||||
code goes to place a node.
|
||||
|
||||
If you specified a table, and there *is* an "axiom" field, the code assumes
|
||||
that this table contains an L-Systems tree definition, which will be passed
|
||||
directly to the engine's spawn_tree() function along with the position on
|
||||
which to spawn the tree.
|
||||
|
||||
You can also supply a function to be directly executed, which is given the
|
||||
current node position (the usual "pos" table format) as its sole argument. It
|
||||
will be called in the form:
|
||||
|
||||
somefunction(pos)
|
||||
|
||||
|
||||
=====
|
||||
biome_lib:grow_plants(options)
|
||||
|
||||
The third function, grow_plants() is used to turn the spawned nodes above
|
||||
into something else over time. This function has no return value, and accepts
|
||||
a biome definition table as the only parameter. These are defined like so:
|
||||
|
||||
options = {
|
||||
grow_plant = "string", -- Name of the node to be grown into something
|
||||
-- else. This value is passed to the ABM as the
|
||||
-- "nodenames" parameter, so it is the plants
|
||||
-- themselves that are the ABM trigger, rather than
|
||||
-- the ground they spawned on. A plant will only grow
|
||||
-- if the node above it is air. Can also be a table,
|
||||
-- but note that all nodes referenced therein will be
|
||||
-- grown into the same object.
|
||||
grow_delay = num, -- Passed as the ABM "interval" parameter, as with
|
||||
-- spawning.
|
||||
grow_chance = num, -- Passed as the ABM "chance" parameter.
|
||||
grow_result = "string", -- Name of the node into which the grow_plant
|
||||
-- node(s) should transform when the ABM executes.
|
||||
|
||||
---- Everything from here down is optional.
|
||||
|
||||
dry_early_node = "string", -- This value is ignored except for jungle
|
||||
-- grass (a corner case needed by that mod), where it
|
||||
-- indicates which node the grass must be on in order
|
||||
-- for it to turn from the short size to
|
||||
-- "default:dry_shrub" instead of the medium size.
|
||||
grow_nodes = {table}, -- One of these nodes must be under the plant in
|
||||
-- order for it to grow at all. Normally this should
|
||||
-- be the same as the list of surfaces passed to the
|
||||
-- spawning ABM as the "nodenames" parameter. This is
|
||||
-- so that the plant can be manually placed on
|
||||
-- something like a flower pot or something without it
|
||||
-- necessarily growing and perhaps dieing. Defaults
|
||||
-- to "default:dirt_with_grass".
|
||||
facedir = num, -- Same as with spawning a plant.
|
||||
need_wall = bool, -- Set this to true if you the plant needs to grow
|
||||
-- against a wall. Defaults to false.
|
||||
verticals_list = {table}, -- same as with spawning a plant.
|
||||
choose_random_wall = bool, -- same as with spawning a plant.
|
||||
grow_vertically = bool, -- Set this to true if the plant needs to grow
|
||||
-- vertically, as in climbing poison ivy. Defaults to
|
||||
-- false.
|
||||
height_limit = num, -- Set this to limit how tall the desired node can
|
||||
-- grow. The mod will search straight down from the
|
||||
-- position being spawned at to find a ground node,
|
||||
-- set via the field below. Defaults to 5 nodes.
|
||||
ground_nodes = {table}, -- What nodes should be treated as "the ground"
|
||||
-- below a vertically-growing plant. Usually this
|
||||
-- should be the same as the grow_nodes table, but
|
||||
-- might also include, for example, water or some
|
||||
-- other surrounding material. Defaults to
|
||||
-- "default:dirt_with_grass".
|
||||
grow_function = something, -- [*] see below.
|
||||
seed_diff = num, -- [*] see below.
|
||||
}
|
||||
|
||||
[*] grow_function can take one of three possible settings: it can be nil (or
|
||||
not provided), a string, or a table.
|
||||
|
||||
If it is not provided or it's set to nil, all of the regular growing code is
|
||||
executed normally, the value of seed_diff, if any, is ignored, and the node to
|
||||
be placed is assumed to be specified in the grow_result variable.
|
||||
|
||||
If this value is set to a simple string, this is treated as the name of the
|
||||
function to use to grow the plant. In this case, all of the usual growing
|
||||
code is executeed, but then instead of a plant being simply added to the
|
||||
world, grow_result is ignored and the named function is executed and passed a
|
||||
few parmeters in the following general form:
|
||||
|
||||
somefunction(pos, perlin1, perlin2)
|
||||
|
||||
These values represent the current position (the usual table), the Perlin
|
||||
noise value for that spot in the generic "plants can grow here" map for the
|
||||
seed_diff value above, the Perlin value for that same spot from the
|
||||
temperature map, and the detected neighboring wall face, if there was one (or
|
||||
nil if not). If seed_diff is not provided, it defaults to 0.
|
||||
|
||||
If this variable is instead set to a table, it is treated an an L-Systems tree
|
||||
definition. All of the growing code is executed in the usual manner, then the
|
||||
tree described by that definition is spawned at the current position instead,
|
||||
and grow_result is ignored.
|
||||
|
||||
|
||||
=====
|
||||
find_adjacent_wall(pos, verticals, randomflag)
|
||||
|
||||
Of the few helper functions, this one expects a position parameter and a table
|
||||
with the list of nodes that should be considered as walls. The code will
|
||||
search around the given position for a neighboring wall, returning the first
|
||||
one it finds as a facedir value, or nil if there are no adjacent walls.
|
||||
|
||||
If randomflag is set to true, the function will just return the facedir of any
|
||||
random wall it finds adjacent to the target position. Defaults to false if
|
||||
not specified.
|
||||
|
||||
=====
|
||||
is_node_loaded(pos)
|
||||
|
||||
This acts as a wrapper for the minetest.get_node_or_nil(node_pos)
|
||||
function and accepts a single position parameter. Returns true if the node in
|
||||
question is already loaded, or false if not.
|
||||
|
||||
|
||||
=====
|
||||
dbg(string)
|
||||
|
||||
This is a simple debug output function which takes one string parameter. It
|
||||
just checks if DEBUG is true and outputs the phrase "[Plantlife] " followed by
|
||||
the supplied string, via the print() function, if so.
|
||||
|
||||
=====
|
||||
biome_lib:generate_tree(pos, treemodel)
|
||||
biome_lib:grow_tree(pos, treemodel)
|
||||
|
||||
In the case of the growing code and the mapgen-based tree generator code,
|
||||
generating a tree is done via the above two calls, which in turn immediately
|
||||
call the usual spawn_tree() functions. This rerouting exists as a way for
|
||||
other mods to hook into biome_lib's tree-growing functions in general,
|
||||
perhaps to execute something extra whenever a tree is spawned.
|
||||
|
||||
biome_lib:generate_tree(pos, treemodel) is called any time a tree is spawned
|
||||
at map generation time. 'pos' is the position of the block on which the tree
|
||||
is to be placed. 'treemodel' is the standard L-Systems tree definition table
|
||||
expected by the spawn_tree() function. Refer to the 'trunk' field in that
|
||||
table to derive the name of the tree being spawned.
|
||||
|
||||
biome_lib:grow_tree(pos, treemodel) does the same sort of thing whenever a
|
||||
tree is spawned within the abm-based growing code, for example when growing a
|
||||
sapling into a tree.
|
||||
|
||||
|
||||
=====
|
||||
There are other, internal helper functions that are not meant for use by other
|
||||
mods. Don't rely on them, as they are subject to change without notice.
|
||||
|
||||
|
||||
===============
|
||||
Global Settings
|
||||
===============
|
||||
|
||||
Set this to true if you want the mod to spam your console with debug info :-)
|
||||
|
||||
plantlife_debug = false
|
||||
|
||||
|
||||
======================
|
||||
Fertile Ground Mapping
|
||||
======================
|
||||
|
||||
The mod uses Perlin noise to create "biomes" of the various plants, via the
|
||||
minetest.get_perlin() function. At present, there are three layers of
|
||||
Perlin noise used.
|
||||
|
||||
The first one is for a "fertile ground" layer, which I tend to refer to as the
|
||||
generic "stuff can potentially grow here" layer. Its values are hard-coded:
|
||||
|
||||
biome_lib.plantlife_seed_diff = 329
|
||||
perlin_octaves = 3
|
||||
perlin_persistence = 0.6
|
||||
perlin_scale = 100
|
||||
|
||||
For more information on how Perlin noise is generated, you will need to search
|
||||
the web, as these default values were from that which is used by minetest_game
|
||||
to spawn jungle grass at mapgen time, and I'm still learning how Perlin noise
|
||||
works. ;-)
|
||||
|
||||
|
||||
===================
|
||||
Temperature Mapping
|
||||
===================
|
||||
|
||||
The second Perlin layer is a temperature map, with values taken from
|
||||
SPlizard's Snow Biomes mod so that the two will be compatible, since that mod
|
||||
appears to be the standard now. Those values are:
|
||||
|
||||
temperature_seeddiff = 112
|
||||
temperature_octaves = 3
|
||||
temperature_persistence = 0.5
|
||||
temperature_scale = 150
|
||||
|
||||
The way Perlin values are used by this mod, in keeping with the snow mod's
|
||||
apparent methods, larger values returned by the Perlin function represent
|
||||
*colder* temperatures. In this mod, the following table gives a rough
|
||||
approximation of how temperature maps to these values, normalized to
|
||||
0.53 = 0 °C and +1.0 = -25 °C.
|
||||
|
||||
Perlin Approx. Temperature
|
||||
-1.0 81 °C ( 178 °F)
|
||||
-0.75 68 °C ( 155 °F)
|
||||
-0.56 58 °C ( 136 °F)
|
||||
-0.5 55 °C ( 131 °F)
|
||||
-0.25 41 °C ( 107 °F)
|
||||
-0.18 38 °C ( 100 °F)
|
||||
0 28 °C ( 83 °F)
|
||||
0.13 21 °C ( 70 °F)
|
||||
0.25 15 °C ( 59 °F)
|
||||
0.5 2 °C ( 35 °F)
|
||||
0.53 0 °C ( 32 °F)
|
||||
0.75 -12 °C ( 11 °F)
|
||||
0.86 -18 °C ( 0 °F)
|
||||
1.0 -25 °C (- 13 °F)
|
||||
|
||||
Included in this table are even 0.25 steps in Perlin values along with some
|
||||
common temperatures on both the Centigrade and Fahrenheit scales. Note that
|
||||
unless you're trying to model the Moon or perhaps Mercury in your mods/maps,
|
||||
you probably won't need to bother with Perlin values of less than -0.56 or so.
|
||||
|
||||
|
||||
================
|
||||
Humidity Mapping
|
||||
================
|
||||
|
||||
Last but not least is a moisture/humidity map. Like the temperature map
|
||||
above, Perlin values can be tested to determine the approximate humidity of
|
||||
the *air* in the area. This humidity map is basically the perlin layer used
|
||||
for deserts.
|
||||
|
||||
A value of +1.0 is very moist (basically a thick fog, if it could be seen), a
|
||||
value of roughly +0.25 represents the edge of a desert as usually seen in the
|
||||
game, and a value of -1.0 is as dry as a bone.
|
||||
|
||||
This does not check for nearby water, just general air humidity, and that
|
||||
being the case, nearby ground does not affect the reported humidity of a
|
||||
region (because this isn't yet possible to calculate yet). Use the near_nodes
|
||||
and avoid_nodes parameters and their related options to check for water and
|
||||
such.
|
||||
|
||||
The Perlin values use for this layer are:
|
||||
|
||||
humidity_seeddiff = 9130
|
||||
humidity_octaves = 3
|
||||
humidity_persistence = 0.5
|
||||
humidity_scale = 250
|
||||
|
||||
And this particular one is mapped slightly differently from the others:
|
||||
|
||||
noise3 = perlin3:get2d({x=p_top.x+150, y=p_top.z+50})
|
||||
|
||||
(Note the +150 and +50 offsets)
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# Biome Lib
|
||||
|
||||
This library's purpose is to allow other mods to add growing things to the map in a straightforward, simple manner. It contains all the core functions needed by mods and modpacks such as More Trees, Tiny Trees, Plantlife, and others.
|
||||
|
||||
Spawning of plants is optionally sensitive to the amount of available light, elevation, nearness to other nodes, plant-to-plant density, water depth, and a whole host of controls.
|
||||
|
||||
All objects spawned or generated using this mod use Perlin noise to stay within simple biomes, rather than just letting everything just spread around the map randomly.
|
||||
|
||||
This library also features a basic temperature map, which should blend in nicely with SPlizard's Snow Biomes mod (the same Perlin settings are used, with the assumption that the edge of a snow biome is 0° Centigrade).
|
||||
|
||||
Both mapgen-based spawning and ABM-based spawning is supported. Growing code is strictly ABM-based. L-system trees can be spawned at mapgen time via the engine's spawn_tree() function and are quite fast.
|
||||
|
||||
It is primarily intended for mapgen v6, but it should work fine when used with mapgen v7.
|
||||
|
||||
**Dependencies**: default from minetest_game
|
||||
|
||||
**Recommends**: [Plantlife Modpack](https://github.com/minetest-mods/plantlife_modpack),
|
||||
[More Trees](https://github.com/minetest-mods/moretrees)
|
||||
|
||||
**License**: WTFPL
|
||||
|
||||
**API**: This mod supplies a small number of very powerful functions. They are, briefly:
|
||||
|
||||
* biome_lib:register_generate_plant()
|
||||
* biome_lib:spawn_on_surfaces()
|
||||
* biome_lib:grow_plants()
|
||||
* biome_lib:find_valid_wall()
|
||||
* biome_lib:is_node_loaded()
|
||||
|
||||
For a complete description of these functions as well as several of the internal variables within the mod, [read the API.txt document](https://raw.githubusercontent.com/minetest-mods/biome_lib/master/API.txt) included in this package.
|
|
@ -1,3 +0,0 @@
|
|||
default
|
||||
intllib?
|
||||
|
|
@ -1 +0,0 @@
|
|||
The biome spawning and management library for Plantlife, Moretrees, Tiny Trees, and other mods that originally depended on plants_lib from the plantlife modpack.
|
|
@ -1,737 +0,0 @@
|
|||
-- Plantlife library mod by Vanessa Ezekowitz
|
||||
--
|
||||
-- License: WTFPL
|
||||
--
|
||||
-- I got the temperature map idea from "hmmmm", values used for it came from
|
||||
-- Splizard's snow mod.
|
||||
--
|
||||
|
||||
-- Various settings - most of these probably won't need to be changed
|
||||
|
||||
biome_lib = {}
|
||||
|
||||
plantslib = setmetatable({}, { __index=function(t,k) print("Use of deprecated function:", k) return biome_lib[k] end })
|
||||
|
||||
biome_lib.blocklist_aircheck = {}
|
||||
biome_lib.blocklist_no_aircheck = {}
|
||||
|
||||
biome_lib.surface_nodes_aircheck = {}
|
||||
biome_lib.surface_nodes_no_aircheck = {}
|
||||
|
||||
biome_lib.surfaceslist_aircheck = {}
|
||||
biome_lib.surfaceslist_no_aircheck = {}
|
||||
|
||||
biome_lib.actioncount_aircheck = {}
|
||||
biome_lib.actioncount_no_aircheck = {}
|
||||
|
||||
biome_lib.actionslist_aircheck = {}
|
||||
biome_lib.actionslist_no_aircheck = {}
|
||||
|
||||
biome_lib.modpath = minetest.get_modpath("biome_lib")
|
||||
|
||||
biome_lib.total_no_aircheck_calls = 0
|
||||
|
||||
-- Boilerplate to support localized strings if intllib mod is installed.
|
||||
local S
|
||||
if minetest.get_modpath("intllib") then
|
||||
S = intllib.Getter()
|
||||
else
|
||||
S = function(s) return s end
|
||||
end
|
||||
biome_lib.intllib = S
|
||||
|
||||
local DEBUG = false --... except if you want to spam the console with debugging info :-)
|
||||
|
||||
function biome_lib:dbg(msg)
|
||||
if DEBUG then
|
||||
minetest.log("info", "[Plantlife] "..msg)
|
||||
minetest.log("verbose", "[Plantlife] "..msg)
|
||||
end
|
||||
end
|
||||
|
||||
biome_lib.plantlife_seed_diff = 329 -- needs to be global so other mods can see it
|
||||
|
||||
local perlin_octaves = 3
|
||||
local perlin_persistence = 0.6
|
||||
local perlin_scale = 100
|
||||
|
||||
local temperature_seeddiff = 112
|
||||
local temperature_octaves = 3
|
||||
local temperature_persistence = 0.5
|
||||
local temperature_scale = 150
|
||||
|
||||
local humidity_seeddiff = 9130
|
||||
local humidity_octaves = 3
|
||||
local humidity_persistence = 0.5
|
||||
local humidity_scale = 250
|
||||
|
||||
local time_scale = 1
|
||||
local time_speed = tonumber(minetest.setting_get("time_speed"))
|
||||
|
||||
if time_speed and time_speed > 0 then
|
||||
time_scale = 72 / time_speed
|
||||
end
|
||||
|
||||
--PerlinNoise(seed, octaves, persistence, scale)
|
||||
|
||||
biome_lib.perlin_temperature = PerlinNoise(temperature_seeddiff, temperature_octaves, temperature_persistence, temperature_scale)
|
||||
biome_lib.perlin_humidity = PerlinNoise(humidity_seeddiff, humidity_octaves, humidity_persistence, humidity_scale)
|
||||
|
||||
-- Local functions
|
||||
|
||||
function biome_lib:is_node_loaded(node_pos)
|
||||
local n = minetest.get_node_or_nil(node_pos)
|
||||
if (not n) or (n.name == "ignore") then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function biome_lib:set_defaults(biome)
|
||||
biome.seed_diff = biome.seed_diff or 0
|
||||
biome.min_elevation = biome.min_elevation or -31000
|
||||
biome.max_elevation = biome.max_elevation or 31000
|
||||
biome.temp_min = biome.temp_min or 1
|
||||
biome.temp_max = biome.temp_max or -1
|
||||
biome.humidity_min = biome.humidity_min or 1
|
||||
biome.humidity_max = biome.humidity_max or -1
|
||||
biome.plantlife_limit = biome.plantlife_limit or 0.1
|
||||
biome.near_nodes_vertical = biome.near_nodes_vertical or 1
|
||||
|
||||
-- specific to on-generate
|
||||
|
||||
biome.neighbors = biome.neighbors or biome.surface
|
||||
biome.near_nodes_size = biome.near_nodes_size or 0
|
||||
biome.near_nodes_count = biome.near_nodes_count or 1
|
||||
biome.rarity = biome.rarity or 50
|
||||
biome.max_count = biome.max_count or 5
|
||||
if biome.check_air ~= false then biome.check_air = true end
|
||||
|
||||
-- specific to abm spawner
|
||||
biome.seed_diff = biome.seed_diff or 0
|
||||
biome.light_min = biome.light_min or 0
|
||||
biome.light_max = biome.light_max or 15
|
||||
biome.depth_max = biome.depth_max or 1
|
||||
biome.facedir = biome.facedir or 0
|
||||
end
|
||||
|
||||
local function search_table(t, s)
|
||||
for i = 1, #t do
|
||||
if t[i] == s then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- register the list of surfaces to spawn stuff on, filtering out all duplicates.
|
||||
-- separate the items by air-checking or non-air-checking map eval methods
|
||||
|
||||
function biome_lib:register_generate_plant(biomedef, nodes_or_function_or_model)
|
||||
|
||||
-- if calling code passes an undefined node for a surface or
|
||||
-- as a node to be spawned, don't register an action for it.
|
||||
|
||||
if type(nodes_or_function_or_model) == "string"
|
||||
and string.find(nodes_or_function_or_model, ":")
|
||||
and not minetest.registered_nodes[nodes_or_function_or_model] then
|
||||
biome_lib:dbg("Warning: Ignored registration for undefined spawn node: "..dump(nodes_or_function_or_model))
|
||||
return
|
||||
end
|
||||
|
||||
if type(nodes_or_function_or_model) == "string"
|
||||
and not string.find(nodes_or_function_or_model, ":") then
|
||||
biome_lib:dbg("Warning: Registered function call using deprecated string method: "..dump(nodes_or_function_or_model))
|
||||
end
|
||||
|
||||
if biomedef.check_air == false then
|
||||
biome_lib:dbg("Register no-air-check mapgen hook: "..dump(nodes_or_function_or_model))
|
||||
biome_lib.actionslist_no_aircheck[#biome_lib.actionslist_no_aircheck + 1] = { biomedef, nodes_or_function_or_model }
|
||||
local s = biomedef.surface
|
||||
if type(s) == "string" then
|
||||
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
|
||||
if not search_table(biome_lib.surfaceslist_no_aircheck, s) then
|
||||
biome_lib.surfaceslist_no_aircheck[#biome_lib.surfaceslist_no_aircheck + 1] = s
|
||||
end
|
||||
else
|
||||
biome_lib:dbg("Warning: Ignored no-air-check registration for undefined surface node: "..dump(s))
|
||||
end
|
||||
else
|
||||
for i = 1, #biomedef.surface do
|
||||
local s = biomedef.surface[i]
|
||||
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
|
||||
if not search_table(biome_lib.surfaceslist_no_aircheck, s) then
|
||||
biome_lib.surfaceslist_no_aircheck[#biome_lib.surfaceslist_no_aircheck + 1] = s
|
||||
end
|
||||
else
|
||||
biome_lib:dbg("Warning: Ignored no-air-check registration for undefined surface node: "..dump(s))
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
biome_lib:dbg("Register with-air-checking mapgen hook: "..dump(nodes_or_function_or_model))
|
||||
biome_lib.actionslist_aircheck[#biome_lib.actionslist_aircheck + 1] = { biomedef, nodes_or_function_or_model }
|
||||
local s = biomedef.surface
|
||||
if type(s) == "string" then
|
||||
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
|
||||
if not search_table(biome_lib.surfaceslist_aircheck, s) then
|
||||
biome_lib.surfaceslist_aircheck[#biome_lib.surfaceslist_aircheck + 1] = s
|
||||
end
|
||||
else
|
||||
biome_lib:dbg("Warning: Ignored with-air-checking registration for undefined surface node: "..dump(s))
|
||||
end
|
||||
else
|
||||
for i = 1, #biomedef.surface do
|
||||
local s = biomedef.surface[i]
|
||||
if s and (string.find(s, "^group:") or minetest.registered_nodes[s]) then
|
||||
if not search_table(biome_lib.surfaceslist_aircheck, s) then
|
||||
biome_lib.surfaceslist_aircheck[#biome_lib.surfaceslist_aircheck + 1] = s
|
||||
end
|
||||
else
|
||||
biome_lib:dbg("Warning: Ignored with-air-checking registration for undefined surface node: "..dump(s))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function biome_lib:populate_surfaces(biome, nodes_or_function_or_model, snodes, checkair)
|
||||
|
||||
biome_lib:set_defaults(biome)
|
||||
|
||||
-- filter stage 1 - find nodes from the supplied surfaces that are within the current biome.
|
||||
|
||||
local in_biome_nodes = {}
|
||||
local perlin_fertile_area = minetest.get_perlin(biome.seed_diff, perlin_octaves, perlin_persistence, perlin_scale)
|
||||
|
||||
for i = 1, #snodes do
|
||||
local pos = snodes[i]
|
||||
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
local noise1 = perlin_fertile_area:get2d({x=pos.x, y=pos.z})
|
||||
local noise2 = biome_lib.perlin_temperature:get2d({x=pos.x, y=pos.z})
|
||||
local noise3 = biome_lib.perlin_humidity:get2d({x=pos.x+150, y=pos.z+50})
|
||||
local biome_surfaces_string = dump(biome.surface)
|
||||
local surface_ok = false
|
||||
|
||||
if not biome.depth then
|
||||
local dest_node = minetest.get_node(pos)
|
||||
if string.find(biome_surfaces_string, dest_node.name) then
|
||||
surface_ok = true
|
||||
else
|
||||
if string.find(biome_surfaces_string, "group:") then
|
||||
for j = 1, #biome.surface do
|
||||
if string.find(biome.surface[j], "^group:")
|
||||
and minetest.get_item_group(dest_node.name, biome.surface[j]) then
|
||||
surface_ok = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif not string.find(biome_surfaces_string, minetest.get_node({ x = pos.x, y = pos.y-biome.depth-1, z = pos.z }).name) then
|
||||
surface_ok = true
|
||||
end
|
||||
|
||||
if surface_ok
|
||||
and (not checkair or minetest.get_node(p_top).name == "air")
|
||||
and pos.y >= biome.min_elevation
|
||||
and pos.y <= biome.max_elevation
|
||||
and noise1 > biome.plantlife_limit
|
||||
and noise2 <= biome.temp_min
|
||||
and noise2 >= biome.temp_max
|
||||
and noise3 <= biome.humidity_min
|
||||
and noise3 >= biome.humidity_max
|
||||
and (not biome.ncount or #(minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, biome.neighbors)) > biome.ncount)
|
||||
and (not biome.near_nodes or #(minetest.find_nodes_in_area({x=pos.x-biome.near_nodes_size, y=pos.y-biome.near_nodes_vertical, z=pos.z-biome.near_nodes_size}, {x=pos.x+biome.near_nodes_size, y=pos.y+biome.near_nodes_vertical, z=pos.z+biome.near_nodes_size}, biome.near_nodes)) >= biome.near_nodes_count)
|
||||
and math.random(1,100) > biome.rarity
|
||||
and (not biome.below_nodes or string.find(dump(biome.below_nodes), minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name) )
|
||||
then
|
||||
in_biome_nodes[#in_biome_nodes + 1] = pos
|
||||
end
|
||||
end
|
||||
|
||||
-- filter stage 2 - find places within that biome area to place the plants.
|
||||
|
||||
local num_in_biome_nodes = #in_biome_nodes
|
||||
|
||||
if num_in_biome_nodes > 0 then
|
||||
for i = 1, math.min(biome.max_count, num_in_biome_nodes) do
|
||||
local tries = 0
|
||||
local spawned = false
|
||||
while tries < 2 and not spawned do
|
||||
local pos = in_biome_nodes[math.random(1, num_in_biome_nodes)]
|
||||
if biome.spawn_replace_node then
|
||||
pos.y = pos.y-1
|
||||
end
|
||||
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
|
||||
if not (biome.avoid_nodes and biome.avoid_radius and minetest.find_node_near(p_top, biome.avoid_radius + math.random(-1.5,2), biome.avoid_nodes)) then
|
||||
if biome.delete_above then
|
||||
minetest.remove_node(p_top)
|
||||
minetest.remove_node({x=p_top.x, y=p_top.y+1, z=p_top.z})
|
||||
end
|
||||
|
||||
if biome.delete_above_surround then
|
||||
minetest.remove_node({x=p_top.x-1, y=p_top.y, z=p_top.z})
|
||||
minetest.remove_node({x=p_top.x+1, y=p_top.y, z=p_top.z})
|
||||
minetest.remove_node({x=p_top.x, y=p_top.y, z=p_top.z-1})
|
||||
minetest.remove_node({x=p_top.x, y=p_top.y, z=p_top.z+1})
|
||||
|
||||
minetest.remove_node({x=p_top.x-1, y=p_top.y+1, z=p_top.z})
|
||||
minetest.remove_node({x=p_top.x+1, y=p_top.y+1, z=p_top.z})
|
||||
minetest.remove_node({x=p_top.x, y=p_top.y+1, z=p_top.z-1})
|
||||
minetest.remove_node({x=p_top.x, y=p_top.y+1, z=p_top.z+1})
|
||||
end
|
||||
|
||||
if biome.spawn_replace_node then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
|
||||
local objtype = type(nodes_or_function_or_model)
|
||||
|
||||
if objtype == "table" then
|
||||
if nodes_or_function_or_model.axiom then
|
||||
biome_lib:generate_tree(p_top, nodes_or_function_or_model)
|
||||
spawned = true
|
||||
else
|
||||
local fdir = nil
|
||||
if biome.random_facedir then
|
||||
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
|
||||
end
|
||||
minetest.set_node(p_top, { name = nodes_or_function_or_model[math.random(#nodes_or_function_or_model)], param2 = fdir })
|
||||
spawned = true
|
||||
end
|
||||
elseif objtype == "string" and
|
||||
minetest.registered_nodes[nodes_or_function_or_model] then
|
||||
local fdir = nil
|
||||
if biome.random_facedir then
|
||||
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
|
||||
end
|
||||
minetest.set_node(p_top, { name = nodes_or_function_or_model, param2 = fdir })
|
||||
spawned = true
|
||||
elseif objtype == "function" then
|
||||
nodes_or_function_or_model(pos)
|
||||
spawned = true
|
||||
elseif objtype == "string" and pcall(loadstring(("return %s(...)"):
|
||||
format(nodes_or_function_or_model)),pos) then
|
||||
spawned = true
|
||||
else
|
||||
biome_lib:dbg("Warning: Ignored invalid definition for object "..dump(nodes_or_function_or_model).." that was pointed at {"..dump(pos).."}")
|
||||
end
|
||||
else
|
||||
tries = tries + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Primary mapgen spawner, for mods that can work with air checking enabled on
|
||||
-- a surface during the initial map read stage.
|
||||
|
||||
function biome_lib:generate_block_with_air_checking()
|
||||
if #biome_lib.blocklist_aircheck > 0 then
|
||||
|
||||
local minp = biome_lib.blocklist_aircheck[1][1]
|
||||
local maxp = biome_lib.blocklist_aircheck[1][2]
|
||||
|
||||
-- use the block hash as a unique key into the surface nodes
|
||||
-- tables, so that we can write the tables thread-safely.
|
||||
|
||||
local blockhash = minetest.hash_node_position(minp)
|
||||
|
||||
if not biome_lib.surface_nodes_aircheck.blockhash then
|
||||
|
||||
if type(minetest.find_nodes_in_area_under_air) == "function" then -- use newer API call
|
||||
biome_lib.surface_nodes_aircheck.blockhash =
|
||||
minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck)
|
||||
else
|
||||
local search_area = minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_aircheck)
|
||||
|
||||
-- search the generated block for air-bounded surfaces the slow way.
|
||||
|
||||
biome_lib.surface_nodes_aircheck.blockhash = {}
|
||||
|
||||
for i = 1, #search_area do
|
||||
local pos = search_area[i]
|
||||
local p_top = { x=pos.x, y=pos.y+1, z=pos.z }
|
||||
if minetest.get_node(p_top).name == "air" then
|
||||
biome_lib.surface_nodes_aircheck.blockhash[#biome_lib.surface_nodes_aircheck.blockhash + 1] = pos
|
||||
end
|
||||
end
|
||||
end
|
||||
biome_lib.actioncount_aircheck.blockhash = 1
|
||||
|
||||
else
|
||||
if biome_lib.actioncount_aircheck.blockhash <= #biome_lib.actionslist_aircheck then
|
||||
-- [1] is biome, [2] is node/function/model
|
||||
biome_lib:populate_surfaces(
|
||||
biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][1],
|
||||
biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][2],
|
||||
biome_lib.surface_nodes_aircheck.blockhash, true)
|
||||
biome_lib.actioncount_aircheck.blockhash = biome_lib.actioncount_aircheck.blockhash + 1
|
||||
else
|
||||
if biome_lib.surface_nodes_aircheck.blockhash then
|
||||
table.remove(biome_lib.blocklist_aircheck, 1)
|
||||
biome_lib.surface_nodes_aircheck.blockhash = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Secondary mapgen spawner, for mods that require disabling of
|
||||
-- checking for air during the initial map read stage.
|
||||
|
||||
function biome_lib:generate_block_no_aircheck()
|
||||
if #biome_lib.blocklist_no_aircheck > 0 then
|
||||
|
||||
local minp = biome_lib.blocklist_no_aircheck[1][1]
|
||||
local maxp = biome_lib.blocklist_no_aircheck[1][2]
|
||||
|
||||
local blockhash = minetest.hash_node_position(minp)
|
||||
|
||||
if not biome_lib.surface_nodes_no_aircheck.blockhash then
|
||||
|
||||
-- directly read the block to be searched into the chunk cache
|
||||
|
||||
biome_lib.surface_nodes_no_aircheck.blockhash =
|
||||
minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_no_aircheck)
|
||||
biome_lib.actioncount_no_aircheck.blockhash = 1
|
||||
|
||||
else
|
||||
if biome_lib.actioncount_no_aircheck.blockhash <= #biome_lib.actionslist_no_aircheck then
|
||||
biome_lib:populate_surfaces(
|
||||
biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][1],
|
||||
biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][2],
|
||||
biome_lib.surface_nodes_no_aircheck.blockhash, false)
|
||||
biome_lib.actioncount_no_aircheck.blockhash = biome_lib.actioncount_no_aircheck.blockhash + 1
|
||||
else
|
||||
if biome_lib.surface_nodes_no_aircheck.blockhash then
|
||||
table.remove(biome_lib.blocklist_no_aircheck, 1)
|
||||
biome_lib.surface_nodes_no_aircheck.blockhash = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- "Record" the chunks being generated by the core mapgen
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||
biome_lib.blocklist_aircheck[#biome_lib.blocklist_aircheck + 1] = { minp, maxp }
|
||||
end)
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||
biome_lib.blocklist_no_aircheck[#biome_lib.blocklist_no_aircheck + 1] = { minp, maxp }
|
||||
end)
|
||||
|
||||
-- "Play" them back, populating them with new stuff in the process
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if dtime < 0.2 and -- don't attempt to populate if lag is already too high
|
||||
(#biome_lib.blocklist_aircheck > 0 or #biome_lib.blocklist_no_aircheck > 0) then
|
||||
biome_lib.globalstep_start_time = minetest.get_us_time()
|
||||
biome_lib.globalstep_runtime = 0
|
||||
while (#biome_lib.blocklist_aircheck > 0 or #biome_lib.blocklist_no_aircheck > 0)
|
||||
and biome_lib.globalstep_runtime < 200000 do -- 0.2 seconds, in uS.
|
||||
if #biome_lib.blocklist_aircheck > 0 then
|
||||
biome_lib:generate_block_with_air_checking()
|
||||
end
|
||||
if #biome_lib.blocklist_no_aircheck > 0 then
|
||||
biome_lib:generate_block_no_aircheck()
|
||||
end
|
||||
biome_lib.globalstep_runtime = minetest.get_us_time() - biome_lib.globalstep_start_time
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Play out the entire log all at once on shutdown
|
||||
-- to prevent unpopulated map areas
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
minetest.log("action", "[biome_lib] Stand by, playing out the rest of the aircheck mapblock log")
|
||||
minetest.log("action", "(there are "..#biome_lib.blocklist_aircheck.." entries)...")
|
||||
while true do
|
||||
biome_lib:generate_block_with_air_checking(0.1)
|
||||
if #biome_lib.blocklist_aircheck == 0 then return end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
minetest.log("action", "[biome_lib] Stand by, playing out the rest of the no-aircheck mapblock log")
|
||||
minetest.log("action", "(there are "..#biome_lib.blocklist_aircheck.." entries)...")
|
||||
while true do
|
||||
biome_lib:generate_block_no_aircheck(0.1)
|
||||
if #biome_lib.blocklist_no_aircheck == 0 then return end
|
||||
end
|
||||
end)
|
||||
|
||||
-- The spawning ABM
|
||||
|
||||
function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa)
|
||||
|
||||
local biome = {}
|
||||
|
||||
if type(sd) ~= "table" then
|
||||
biome.spawn_delay = sd -- old api expects ABM interval param here.
|
||||
biome.spawn_plants = {sp}
|
||||
biome.avoid_radius = sr
|
||||
biome.spawn_chance = sc
|
||||
biome.spawn_surfaces = {ss}
|
||||
biome.avoid_nodes = sa
|
||||
else
|
||||
biome = sd
|
||||
end
|
||||
|
||||
if biome.spawn_delay*time_scale >= 1 then
|
||||
biome.interval = biome.spawn_delay*time_scale
|
||||
else
|
||||
biome.interval = 1
|
||||
end
|
||||
|
||||
biome_lib:set_defaults(biome)
|
||||
biome.spawn_plants_count = #(biome.spawn_plants)
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = biome.spawn_surfaces,
|
||||
interval = biome.interval,
|
||||
chance = biome.spawn_chance,
|
||||
neighbors = biome.neighbors,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
local n_top = minetest.get_node(p_top)
|
||||
local perlin_fertile_area = minetest.get_perlin(biome.seed_diff, perlin_octaves, perlin_persistence, perlin_scale)
|
||||
local noise1 = perlin_fertile_area:get2d({x=p_top.x, y=p_top.z})
|
||||
local noise2 = biome_lib.perlin_temperature:get2d({x=p_top.x, y=p_top.z})
|
||||
local noise3 = biome_lib.perlin_humidity:get2d({x=p_top.x+150, y=p_top.z+50})
|
||||
if noise1 > biome.plantlife_limit
|
||||
and noise2 <= biome.temp_min
|
||||
and noise2 >= biome.temp_max
|
||||
and noise3 <= biome.humidity_min
|
||||
and noise3 >= biome.humidity_max
|
||||
and biome_lib:is_node_loaded(p_top) then
|
||||
local n_light = minetest.get_node_light(p_top, nil)
|
||||
if not (biome.avoid_nodes and biome.avoid_radius and minetest.find_node_near(p_top, biome.avoid_radius + math.random(-1.5,2), biome.avoid_nodes))
|
||||
and n_light >= biome.light_min
|
||||
and n_light <= biome.light_max
|
||||
and (not(biome.neighbors and biome.ncount) or #(minetest.find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, biome.neighbors)) > biome.ncount )
|
||||
and (not(biome.near_nodes and biome.near_nodes_count and biome.near_nodes_size) or #(minetest.find_nodes_in_area({x=pos.x-biome.near_nodes_size, y=pos.y-biome.near_nodes_vertical, z=pos.z-biome.near_nodes_size}, {x=pos.x+biome.near_nodes_size, y=pos.y+biome.near_nodes_vertical, z=pos.z+biome.near_nodes_size}, biome.near_nodes)) >= biome.near_nodes_count)
|
||||
and (not(biome.air_count and biome.air_size) or #(minetest.find_nodes_in_area({x=p_top.x-biome.air_size, y=p_top.y, z=p_top.z-biome.air_size}, {x=p_top.x+biome.air_size, y=p_top.y, z=p_top.z+biome.air_size}, "air")) >= biome.air_count)
|
||||
and pos.y >= biome.min_elevation
|
||||
and pos.y <= biome.max_elevation
|
||||
then
|
||||
local walldir = biome_lib:find_adjacent_wall(p_top, biome.verticals_list, biome.choose_random_wall)
|
||||
if biome.alt_wallnode and walldir then
|
||||
if n_top.name == "air" then
|
||||
minetest.set_node(p_top, { name = biome.alt_wallnode, param2 = walldir })
|
||||
end
|
||||
else
|
||||
local currentsurface = minetest.get_node(pos).name
|
||||
if currentsurface ~= "default:water_source"
|
||||
or (currentsurface == "default:water_source" and #(minetest.find_nodes_in_area({x=pos.x, y=pos.y-biome.depth_max-1, z=pos.z}, {x=pos.x, y=pos.y, z=pos.z}, {"default:dirt", "default:dirt_with_grass", "default:sand"})) > 0 )
|
||||
then
|
||||
local rnd = math.random(1, biome.spawn_plants_count)
|
||||
local plant_to_spawn = biome.spawn_plants[rnd]
|
||||
local fdir = biome.facedir
|
||||
if biome.random_facedir then
|
||||
fdir = math.random(biome.random_facedir[1],biome.random_facedir[2])
|
||||
end
|
||||
if type(biome.spawn_plants) == "string" then
|
||||
assert(loadstring(biome.spawn_plants.."(...)"))(pos)
|
||||
elseif not biome.spawn_on_side and not biome.spawn_on_bottom and not biome.spawn_replace_node then
|
||||
if n_top.name == "air" then
|
||||
minetest.set_node(p_top, { name = plant_to_spawn, param2 = fdir })
|
||||
end
|
||||
elseif biome.spawn_replace_node then
|
||||
minetest.set_node(pos, { name = plant_to_spawn, param2 = fdir })
|
||||
|
||||
elseif biome.spawn_on_side then
|
||||
local onside = biome_lib:find_open_side(pos)
|
||||
if onside then
|
||||
minetest.set_node(onside.newpos, { name = plant_to_spawn, param2 = onside.facedir })
|
||||
end
|
||||
elseif biome.spawn_on_bottom then
|
||||
if minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
minetest.set_node({x=pos.x, y=pos.y-1, z=pos.z}, { name = plant_to_spawn, param2 = fdir} )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- The growing ABM
|
||||
|
||||
function biome_lib:grow_plants(opts)
|
||||
|
||||
local options = opts
|
||||
|
||||
options.height_limit = options.height_limit or 5
|
||||
options.ground_nodes = options.ground_nodes or { "default:dirt_with_grass" }
|
||||
options.grow_nodes = options.grow_nodes or { "default:dirt_with_grass" }
|
||||
options.seed_diff = options.seed_diff or 0
|
||||
|
||||
if options.grow_delay*time_scale >= 1 then
|
||||
options.interval = options.grow_delay*time_scale
|
||||
else
|
||||
options.interval = 1
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { options.grow_plant },
|
||||
interval = options.interval,
|
||||
chance = options.grow_chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local p_top = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local p_bot = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
local n_top = minetest.get_node(p_top)
|
||||
local n_bot = minetest.get_node(p_bot)
|
||||
local root_node = minetest.get_node({x=pos.x, y=pos.y-options.height_limit, z=pos.z})
|
||||
local walldir = nil
|
||||
if options.need_wall and options.verticals_list then
|
||||
walldir = biome_lib:find_adjacent_wall(p_top, options.verticals_list, options.choose_random_wall)
|
||||
end
|
||||
if (n_top.name == "air" or n_top.name == "default:snow")
|
||||
and (not options.need_wall or (options.need_wall and walldir)) then
|
||||
-- corner case for changing short junglegrass
|
||||
-- to dry shrub in desert
|
||||
if n_bot.name == options.dry_early_node and options.grow_plant == "junglegrass:short" then
|
||||
minetest.set_node(pos, { name = "default:dry_shrub" })
|
||||
|
||||
elseif options.grow_vertically and walldir then
|
||||
if biome_lib:search_downward(pos, options.height_limit, options.ground_nodes) then
|
||||
minetest.set_node(p_top, { name = options.grow_plant, param2 = walldir})
|
||||
end
|
||||
|
||||
elseif not options.grow_result and not options.grow_function then
|
||||
minetest.remove_node(pos)
|
||||
|
||||
else
|
||||
biome_lib:replace_object(pos, options.grow_result, options.grow_function, options.facedir, options.seed_diff)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- Function to decide how to replace a plant - either grow it, replace it with
|
||||
-- a tree, run a function, or die with an error.
|
||||
|
||||
function biome_lib:replace_object(pos, replacement, grow_function, walldir, seeddiff)
|
||||
local growtype = type(grow_function)
|
||||
if growtype == "table" then
|
||||
minetest.remove_node(pos)
|
||||
biome_lib:grow_tree(pos, grow_function)
|
||||
return
|
||||
elseif growtype == "function" then
|
||||
local perlin_fertile_area = minetest.get_perlin(seeddiff, perlin_octaves, perlin_persistence, perlin_scale)
|
||||
local noise1 = perlin_fertile_area:get2d({x=pos.x, y=pos.z})
|
||||
local noise2 = biome_lib.perlin_temperature:get2d({x=pos.x, y=pos.z})
|
||||
grow_function(pos,noise1,noise2,walldir)
|
||||
return
|
||||
elseif growtype == "string" then
|
||||
local perlin_fertile_area = minetest.get_perlin(seeddiff, perlin_octaves, perlin_persistence, perlin_scale)
|
||||
local noise1 = perlin_fertile_area:get2d({x=pos.x, y=pos.z})
|
||||
local noise2 = biome_lib.perlin_temperature:get2d({x=pos.x, y=pos.z})
|
||||
assert(loadstring(grow_function.."(...)"))(pos,noise1,noise2,walldir)
|
||||
return
|
||||
elseif growtype == "nil" then
|
||||
minetest.set_node(pos, { name = replacement, param2 = walldir})
|
||||
return
|
||||
elseif growtype ~= "nil" and growtype ~= "string" and growtype ~= "table" then
|
||||
error("Invalid grow function "..dump(grow_function).." used on object at ("..dump(pos)..")")
|
||||
end
|
||||
end
|
||||
|
||||
-- function to decide if a node has a wall that's in verticals_list{}
|
||||
-- returns wall direction of valid node, or nil if invalid.
|
||||
|
||||
function biome_lib:find_adjacent_wall(pos, verticals, randomflag)
|
||||
local verts = dump(verticals)
|
||||
if randomflag then
|
||||
local walltab = {}
|
||||
|
||||
if string.find(verts, minetest.get_node({ x=pos.x-1, y=pos.y, z=pos.z }).name) then walltab[#walltab + 1] = 3 end
|
||||
if string.find(verts, minetest.get_node({ x=pos.x+1, y=pos.y, z=pos.z }).name) then walltab[#walltab + 1] = 2 end
|
||||
if string.find(verts, minetest.get_node({ x=pos.x , y=pos.y, z=pos.z-1 }).name) then walltab[#walltab + 1] = 5 end
|
||||
if string.find(verts, minetest.get_node({ x=pos.x , y=pos.y, z=pos.z+1 }).name) then walltab[#walltab + 1] = 4 end
|
||||
|
||||
if #walltab > 0 then return walltab[math.random(1, #walltab)] end
|
||||
|
||||
else
|
||||
if string.find(verts, minetest.get_node({ x=pos.x-1, y=pos.y, z=pos.z }).name) then return 3 end
|
||||
if string.find(verts, minetest.get_node({ x=pos.x+1, y=pos.y, z=pos.z }).name) then return 2 end
|
||||
if string.find(verts, minetest.get_node({ x=pos.x , y=pos.y, z=pos.z-1 }).name) then return 5 end
|
||||
if string.find(verts, minetest.get_node({ x=pos.x , y=pos.y, z=pos.z+1 }).name) then return 4 end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Function to search downward from the given position, looking for the first
|
||||
-- node that matches the ground table. Returns the new position, or nil if
|
||||
-- height limit is exceeded before finding it.
|
||||
|
||||
function biome_lib:search_downward(pos, heightlimit, ground)
|
||||
for i = 0, heightlimit do
|
||||
if string.find(dump(ground), minetest.get_node({x=pos.x, y=pos.y-i, z = pos.z}).name) then
|
||||
return {x=pos.x, y=pos.y-i, z = pos.z}
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function biome_lib:find_open_side(pos)
|
||||
if minetest.get_node({ x=pos.x-1, y=pos.y, z=pos.z }).name == "air" then
|
||||
return {newpos = { x=pos.x-1, y=pos.y, z=pos.z }, facedir = 2}
|
||||
end
|
||||
if minetest.get_node({ x=pos.x+1, y=pos.y, z=pos.z }).name == "air" then
|
||||
return {newpos = { x=pos.x+1, y=pos.y, z=pos.z }, facedir = 3}
|
||||
end
|
||||
if minetest.get_node({ x=pos.x, y=pos.y, z=pos.z-1 }).name == "air" then
|
||||
return {newpos = { x=pos.x, y=pos.y, z=pos.z-1 }, facedir = 4}
|
||||
end
|
||||
if minetest.get_node({ x=pos.x, y=pos.y, z=pos.z+1 }).name == "air" then
|
||||
return {newpos = { x=pos.x, y=pos.y, z=pos.z+1 }, facedir = 5}
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- spawn_tree() on generate is routed through here so that other mods can hook
|
||||
-- into it.
|
||||
|
||||
function biome_lib:generate_tree(pos, nodes_or_function_or_model)
|
||||
minetest.spawn_tree(pos, nodes_or_function_or_model)
|
||||
end
|
||||
|
||||
-- and this one's for the call used in the growing code
|
||||
|
||||
function biome_lib:grow_tree(pos, nodes_or_function_or_model)
|
||||
minetest.spawn_tree(pos, nodes_or_function_or_model)
|
||||
end
|
||||
|
||||
-- Check for infinite stacks
|
||||
|
||||
if minetest.get_modpath("unified_inventory") or not minetest.setting_getbool("creative_mode") then
|
||||
biome_lib.expect_infinite_stacks = false
|
||||
else
|
||||
biome_lib.expect_infinite_stacks = true
|
||||
end
|
||||
|
||||
-- read a field from a node's definition
|
||||
|
||||
function biome_lib:get_nodedef_field(nodename, fieldname)
|
||||
if not minetest.registered_nodes[nodename] then
|
||||
return nil
|
||||
end
|
||||
return minetest.registered_nodes[nodename][fieldname]
|
||||
end
|
||||
|
||||
minetest.log("action", "[Biome Lib] Loaded")
|
||||
|
||||
minetest.after(0, function()
|
||||
minetest.log("action", "[Biome Lib] Registered a total of "..(#biome_lib.surfaceslist_aircheck)+(#biome_lib.surfaceslist_no_aircheck).." surface types to be evaluated, spread")
|
||||
minetest.log("action", "[Biome Lib] across "..#biome_lib.actionslist_aircheck.." actions with air-checking and "..#biome_lib.actionslist_no_aircheck.." actions without.")
|
||||
end)
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
# Translation by Xanthin
|
||||
|
||||
someone = jemand
|
||||
Sorry, %s owns that spot. = Entschuldige, %s gehoert diese Stelle.
|
||||
[Plantlife Library] Loaded = [Plantlife Library] Geladen
|
|
@ -1,5 +0,0 @@
|
|||
# Template
|
||||
|
||||
someone = quelqu'un
|
||||
Sorry, %s owns that spot. = Désolé, %s possède cet endroit.
|
||||
[Plantlife Library] Loaded = [Librairie Plantlife] Chargée.
|
|
@ -1,5 +0,0 @@
|
|||
# Template
|
||||
|
||||
someone =
|
||||
Sorry, %s owns that spot. =
|
||||
[Plantlife Library] Loaded =
|
|
@ -1,5 +0,0 @@
|
|||
# Turkish translation by mahmutelmas06
|
||||
|
||||
someone = birisi
|
||||
Sorry, %s owns that spot. = Üzgünüm, buranın sahibi %s.
|
||||
[Plantlife Library] Loaded = [Plantlife Library] yüklendi
|
|
@ -1 +0,0 @@
|
|||
name = biome_lib
|
|
@ -1 +1 @@
|
|||
Subproject commit 271c17180e2ec98a8c1981bb5f18070f990ce846
|
||||
Subproject commit 97c4ecf7059c898c2ca42058e588220315dfa350
|
1
mods/moretrees
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 324155f80519259fdf58f43604cecbf47bfb035e
|
1
mods/moretrees/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
*~
|
|
@ -1,392 +0,0 @@
|
|||
Minetest mod moretrees
|
||||
======================
|
||||
|
||||
All source code:
|
||||
© 2013, Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
|
||||
Published under the terms and conditions of the WTFPL.
|
||||
All sapling textures (textures/*_sapling.png):
|
||||
© 2013, Tim Huppertz <mitroman@naturalnet.de>
|
||||
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
||||
All other textures:
|
||||
© 2013, Vanessa Ezekowitz <vanessaezekowitz@gmail.com>
|
||||
Published under the terms and conditions of CC-BY-SA-3.0 Unported.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
||||
This license is commonly known as "WTFPL".
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
|
||||
DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
|
||||
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
|
||||
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
|
||||
AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
|
||||
TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
|
||||
BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
|
||||
CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
|
||||
CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "Adaptation" means a work based upon the Work, or upon the Work and
|
||||
other pre-existing works, such as a translation, adaptation,
|
||||
derivative work, arrangement of music or other alterations of a
|
||||
literary or artistic work, or phonogram or performance and includes
|
||||
cinematographic adaptations or any other form in which the Work may be
|
||||
recast, transformed, or adapted including in any form recognizably
|
||||
derived from the original, except that a work that constitutes a
|
||||
Collection will not be considered an Adaptation for the purpose of
|
||||
this License. For the avoidance of doubt, where the Work is a musical
|
||||
work, performance or phonogram, the synchronization of the Work in
|
||||
timed-relation with a moving image ("synching") will be considered an
|
||||
Adaptation for the purpose of this License.
|
||||
b. "Collection" means a collection of literary or artistic works, such as
|
||||
encyclopedias and anthologies, or performances, phonograms or
|
||||
broadcasts, or other works or subject matter other than works listed
|
||||
in Section 1(f) below, which, by reason of the selection and
|
||||
arrangement of their contents, constitute intellectual creations, in
|
||||
which the Work is included in its entirety in unmodified form along
|
||||
with one or more other contributions, each constituting separate and
|
||||
independent works in themselves, which together are assembled into a
|
||||
collective whole. A work that constitutes a Collection will not be
|
||||
considered an Adaptation (as defined below) for the purposes of this
|
||||
License.
|
||||
c. "Creative Commons Compatible License" means a license that is listed
|
||||
at http://creativecommons.org/compatiblelicenses that has been
|
||||
approved by Creative Commons as being essentially equivalent to this
|
||||
License, including, at a minimum, because that license: (i) contains
|
||||
terms that have the same purpose, meaning and effect as the License
|
||||
Elements of this License; and, (ii) explicitly permits the relicensing
|
||||
of adaptations of works made available under that license under this
|
||||
License or a Creative Commons jurisdiction license with the same
|
||||
License Elements as this License.
|
||||
d. "Distribute" means to make available to the public the original and
|
||||
copies of the Work or Adaptation, as appropriate, through sale or
|
||||
other transfer of ownership.
|
||||
e. "License Elements" means the following high-level license attributes
|
||||
as selected by Licensor and indicated in the title of this License:
|
||||
Attribution, ShareAlike.
|
||||
f. "Licensor" means the individual, individuals, entity or entities that
|
||||
offer(s) the Work under the terms of this License.
|
||||
g. "Original Author" means, in the case of a literary or artistic work,
|
||||
the individual, individuals, entity or entities who created the Work
|
||||
or if no individual or entity can be identified, the publisher; and in
|
||||
addition (i) in the case of a performance the actors, singers,
|
||||
musicians, dancers, and other persons who act, sing, deliver, declaim,
|
||||
play in, interpret or otherwise perform literary or artistic works or
|
||||
expressions of folklore; (ii) in the case of a phonogram the producer
|
||||
being the person or legal entity who first fixes the sounds of a
|
||||
performance or other sounds; and, (iii) in the case of broadcasts, the
|
||||
organization that transmits the broadcast.
|
||||
h. "Work" means the literary and/or artistic work offered under the terms
|
||||
of this License including without limitation any production in the
|
||||
literary, scientific and artistic domain, whatever may be the mode or
|
||||
form of its expression including digital form, such as a book,
|
||||
pamphlet and other writing; a lecture, address, sermon or other work
|
||||
of the same nature; a dramatic or dramatico-musical work; a
|
||||
choreographic work or entertainment in dumb show; a musical
|
||||
composition with or without words; a cinematographic work to which are
|
||||
assimilated works expressed by a process analogous to cinematography;
|
||||
a work of drawing, painting, architecture, sculpture, engraving or
|
||||
lithography; a photographic work to which are assimilated works
|
||||
expressed by a process analogous to photography; a work of applied
|
||||
art; an illustration, map, plan, sketch or three-dimensional work
|
||||
relative to geography, topography, architecture or science; a
|
||||
performance; a broadcast; a phonogram; a compilation of data to the
|
||||
extent it is protected as a copyrightable work; or a work performed by
|
||||
a variety or circus performer to the extent it is not otherwise
|
||||
considered a literary or artistic work.
|
||||
i. "You" means an individual or entity exercising rights under this
|
||||
License who has not previously violated the terms of this License with
|
||||
respect to the Work, or who has received express permission from the
|
||||
Licensor to exercise rights under this License despite a previous
|
||||
violation.
|
||||
j. "Publicly Perform" means to perform public recitations of the Work and
|
||||
to communicate to the public those public recitations, by any means or
|
||||
process, including by wire or wireless means or public digital
|
||||
performances; to make available to the public Works in such a way that
|
||||
members of the public may access these Works from a place and at a
|
||||
place individually chosen by them; to perform the Work to the public
|
||||
by any means or process and the communication to the public of the
|
||||
performances of the Work, including by public digital performance; to
|
||||
broadcast and rebroadcast the Work by any means including signs,
|
||||
sounds or images.
|
||||
k. "Reproduce" means to make copies of the Work by any means including
|
||||
without limitation by sound or visual recordings and the right of
|
||||
fixation and reproducing fixations of the Work, including storage of a
|
||||
protected performance or phonogram in digital form or other electronic
|
||||
medium.
|
||||
|
||||
2. Fair Dealing Rights. Nothing in this License is intended to reduce,
|
||||
limit, or restrict any uses free from copyright or rights arising from
|
||||
limitations or exceptions that are provided for in connection with the
|
||||
copyright protection under copyright law or other applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License,
|
||||
Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
|
||||
perpetual (for the duration of the applicable copyright) license to
|
||||
exercise the rights in the Work as stated below:
|
||||
|
||||
a. to Reproduce the Work, to incorporate the Work into one or more
|
||||
Collections, and to Reproduce the Work as incorporated in the
|
||||
Collections;
|
||||
b. to create and Reproduce Adaptations provided that any such Adaptation,
|
||||
including any translation in any medium, takes reasonable steps to
|
||||
clearly label, demarcate or otherwise identify that changes were made
|
||||
to the original Work. For example, a translation could be marked "The
|
||||
original work was translated from English to Spanish," or a
|
||||
modification could indicate "The original work has been modified.";
|
||||
c. to Distribute and Publicly Perform the Work including as incorporated
|
||||
in Collections; and,
|
||||
d. to Distribute and Publicly Perform Adaptations.
|
||||
e. For the avoidance of doubt:
|
||||
|
||||
i. Non-waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme cannot be waived, the Licensor
|
||||
reserves the exclusive right to collect such royalties for any
|
||||
exercise by You of the rights granted under this License;
|
||||
ii. Waivable Compulsory License Schemes. In those jurisdictions in
|
||||
which the right to collect royalties through any statutory or
|
||||
compulsory licensing scheme can be waived, the Licensor waives the
|
||||
exclusive right to collect such royalties for any exercise by You
|
||||
of the rights granted under this License; and,
|
||||
iii. Voluntary License Schemes. The Licensor waives the right to
|
||||
collect royalties, whether individually or, in the event that the
|
||||
Licensor is a member of a collecting society that administers
|
||||
voluntary licensing schemes, via that society, from any exercise
|
||||
by You of the rights granted under this License.
|
||||
|
||||
The above rights may be exercised in all media and formats whether now
|
||||
known or hereafter devised. The above rights include the right to make
|
||||
such modifications as are technically necessary to exercise the rights in
|
||||
other media and formats. Subject to Section 8(f), all rights not expressly
|
||||
granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made
|
||||
subject to and limited by the following restrictions:
|
||||
|
||||
a. You may Distribute or Publicly Perform the Work only under the terms
|
||||
of this License. You must include a copy of, or the Uniform Resource
|
||||
Identifier (URI) for, this License with every copy of the Work You
|
||||
Distribute or Publicly Perform. You may not offer or impose any terms
|
||||
on the Work that restrict the terms of this License or the ability of
|
||||
the recipient of the Work to exercise the rights granted to that
|
||||
recipient under the terms of the License. You may not sublicense the
|
||||
Work. You must keep intact all notices that refer to this License and
|
||||
to the disclaimer of warranties with every copy of the Work You
|
||||
Distribute or Publicly Perform. When You Distribute or Publicly
|
||||
Perform the Work, You may not impose any effective technological
|
||||
measures on the Work that restrict the ability of a recipient of the
|
||||
Work from You to exercise the rights granted to that recipient under
|
||||
the terms of the License. This Section 4(a) applies to the Work as
|
||||
incorporated in a Collection, but this does not require the Collection
|
||||
apart from the Work itself to be made subject to the terms of this
|
||||
License. If You create a Collection, upon notice from any Licensor You
|
||||
must, to the extent practicable, remove from the Collection any credit
|
||||
as required by Section 4(c), as requested. If You create an
|
||||
Adaptation, upon notice from any Licensor You must, to the extent
|
||||
practicable, remove from the Adaptation any credit as required by
|
||||
Section 4(c), as requested.
|
||||
b. You may Distribute or Publicly Perform an Adaptation only under the
|
||||
terms of: (i) this License; (ii) a later version of this License with
|
||||
the same License Elements as this License; (iii) a Creative Commons
|
||||
jurisdiction license (either this or a later license version) that
|
||||
contains the same License Elements as this License (e.g.,
|
||||
Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible
|
||||
License. If you license the Adaptation under one of the licenses
|
||||
mentioned in (iv), you must comply with the terms of that license. If
|
||||
you license the Adaptation under the terms of any of the licenses
|
||||
mentioned in (i), (ii) or (iii) (the "Applicable License"), you must
|
||||
comply with the terms of the Applicable License generally and the
|
||||
following provisions: (I) You must include a copy of, or the URI for,
|
||||
the Applicable License with every copy of each Adaptation You
|
||||
Distribute or Publicly Perform; (II) You may not offer or impose any
|
||||
terms on the Adaptation that restrict the terms of the Applicable
|
||||
License or the ability of the recipient of the Adaptation to exercise
|
||||
the rights granted to that recipient under the terms of the Applicable
|
||||
License; (III) You must keep intact all notices that refer to the
|
||||
Applicable License and to the disclaimer of warranties with every copy
|
||||
of the Work as included in the Adaptation You Distribute or Publicly
|
||||
Perform; (IV) when You Distribute or Publicly Perform the Adaptation,
|
||||
You may not impose any effective technological measures on the
|
||||
Adaptation that restrict the ability of a recipient of the Adaptation
|
||||
from You to exercise the rights granted to that recipient under the
|
||||
terms of the Applicable License. This Section 4(b) applies to the
|
||||
Adaptation as incorporated in a Collection, but this does not require
|
||||
the Collection apart from the Adaptation itself to be made subject to
|
||||
the terms of the Applicable License.
|
||||
c. If You Distribute, or Publicly Perform the Work or any Adaptations or
|
||||
Collections, You must, unless a request has been made pursuant to
|
||||
Section 4(a), keep intact all copyright notices for the Work and
|
||||
provide, reasonable to the medium or means You are utilizing: (i) the
|
||||
name of the Original Author (or pseudonym, if applicable) if supplied,
|
||||
and/or if the Original Author and/or Licensor designate another party
|
||||
or parties (e.g., a sponsor institute, publishing entity, journal) for
|
||||
attribution ("Attribution Parties") in Licensor's copyright notice,
|
||||
terms of service or by other reasonable means, the name of such party
|
||||
or parties; (ii) the title of the Work if supplied; (iii) to the
|
||||
extent reasonably practicable, the URI, if any, that Licensor
|
||||
specifies to be associated with the Work, unless such URI does not
|
||||
refer to the copyright notice or licensing information for the Work;
|
||||
and (iv) , consistent with Ssection 3(b), in the case of an
|
||||
Adaptation, a credit identifying the use of the Work in the Adaptation
|
||||
(e.g., "French translation of the Work by Original Author," or
|
||||
"Screenplay based on original Work by Original Author"). The credit
|
||||
required by this Section 4(c) may be implemented in any reasonable
|
||||
manner; provided, however, that in the case of a Adaptation or
|
||||
Collection, at a minimum such credit will appear, if a credit for all
|
||||
contributing authors of the Adaptation or Collection appears, then as
|
||||
part of these credits and in a manner at least as prominent as the
|
||||
credits for the other contributing authors. For the avoidance of
|
||||
doubt, You may only use the credit required by this Section for the
|
||||
purpose of attribution in the manner set out above and, by exercising
|
||||
Your rights under this License, You may not implicitly or explicitly
|
||||
assert or imply any connection with, sponsorship or endorsement by the
|
||||
Original Author, Licensor and/or Attribution Parties, as appropriate,
|
||||
of You or Your use of the Work, without the separate, express prior
|
||||
written permission of the Original Author, Licensor and/or Attribution
|
||||
Parties.
|
||||
d. Except as otherwise agreed in writing by the Licensor or as may be
|
||||
otherwise permitted by applicable law, if You Reproduce, Distribute or
|
||||
Publicly Perform the Work either by itself or as part of any
|
||||
Adaptations or Collections, You must not distort, mutilate, modify or
|
||||
take other derogatory action in relation to the Work which would be
|
||||
prejudicial to the Original Author's honor or reputation. Licensor
|
||||
agrees that in those jurisdictions (e.g. Japan), in which any exercise
|
||||
of the right granted in Section 3(b) of this License (the right to
|
||||
make Adaptations) would be deemed to be a distortion, mutilation,
|
||||
modification or other derogatory action prejudicial to the Original
|
||||
Author's honor and reputation, the Licensor will waive or not assert,
|
||||
as appropriate, this Section, to the fullest extent permitted by the
|
||||
applicable national law, to enable You to reasonably exercise Your
|
||||
right under Section 3(b) of this License (right to make Adaptations)
|
||||
but not otherwise.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
|
||||
OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
|
||||
KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
|
||||
INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
|
||||
LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
|
||||
WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
|
||||
OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
|
||||
LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
|
||||
ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
|
||||
ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
|
||||
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. This License and the rights granted hereunder will terminate
|
||||
automatically upon any breach by You of the terms of this License.
|
||||
Individuals or entities who have received Adaptations or Collections
|
||||
from You under this License, however, will not have their licenses
|
||||
terminated provided such individuals or entities remain in full
|
||||
compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
|
||||
survive any termination of this License.
|
||||
b. Subject to the above terms and conditions, the license granted here is
|
||||
perpetual (for the duration of the applicable copyright in the Work).
|
||||
Notwithstanding the above, Licensor reserves the right to release the
|
||||
Work under different license terms or to stop distributing the Work at
|
||||
any time; provided, however that any such election will not serve to
|
||||
withdraw this License (or any other license that has been, or is
|
||||
required to be, granted under the terms of this License), and this
|
||||
License will continue in full force and effect unless terminated as
|
||||
stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You Distribute or Publicly Perform the Work or a Collection,
|
||||
the Licensor offers to the recipient a license to the Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
|
||||
offers to the recipient a license to the original Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
c. If any provision of this License is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of
|
||||
the remainder of the terms of this License, and without further action
|
||||
by the parties to this agreement, such provision shall be reformed to
|
||||
the minimum extent necessary to make such provision valid and
|
||||
enforceable.
|
||||
d. No term or provision of this License shall be deemed waived and no
|
||||
breach consented to unless such waiver or consent shall be in writing
|
||||
and signed by the party to be charged with such waiver or consent.
|
||||
e. This License constitutes the entire agreement between the parties with
|
||||
respect to the Work licensed here. There are no understandings,
|
||||
agreements or representations with respect to the Work not specified
|
||||
here. Licensor shall not be bound by any additional provisions that
|
||||
may appear in any communication from You. This License may not be
|
||||
modified without the mutual written agreement of the Licensor and You.
|
||||
f. The rights granted under, and the subject matter referenced, in this
|
||||
License were drafted utilizing the terminology of the Berne Convention
|
||||
for the Protection of Literary and Artistic Works (as amended on
|
||||
September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
|
||||
Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
|
||||
and the Universal Copyright Convention (as revised on July 24, 1971).
|
||||
These rights and subject matter take effect in the relevant
|
||||
jurisdiction in which the License terms are sought to be enforced
|
||||
according to the corresponding provisions of the implementation of
|
||||
those treaty provisions in the applicable national law. If the
|
||||
standard suite of rights granted under applicable copyright law
|
||||
includes additional rights not granted under this License, such
|
||||
additional rights are deemed to be included in the License; this
|
||||
License is not intended to restrict the license of any rights under
|
||||
applicable law.
|
||||
|
||||
|
||||
Creative Commons Notice
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be
|
||||
liable to You or any party on any legal theory for any damages
|
||||
whatsoever, including without limitation any general, special,
|
||||
incidental or consequential damages arising in connection to this
|
||||
license. Notwithstanding the foregoing two (2) sentences, if Creative
|
||||
Commons has expressly identified itself as the Licensor hereunder, it
|
||||
shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the
|
||||
Work is licensed under the CCPL, Creative Commons does not authorize
|
||||
the use by either party of the trademark "Creative Commons" or any
|
||||
related trademark or logo of Creative Commons without the prior
|
||||
written consent of Creative Commons. Any permitted use will be in
|
||||
compliance with Creative Commons' then-current trademark usage
|
||||
guidelines, as may be published on its website or otherwise made
|
||||
available upon request from time to time. For the avoidance of doubt,
|
||||
this trademark restriction does not form part of the License.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
|
@ -1,11 +0,0 @@
|
|||
More trees!
|
||||
|
||||
This mod adds a whole bunch of new types of trees to the game
|
||||
|
||||
Much of the code here came from cisoun's conifers mod and bas080's
|
||||
jungle trees mod, and big contributions by RealBadAngel.
|
||||
|
||||
Brought together into one mod and made L-systems compatible by Vanessa
|
||||
Ezekowitz.
|
||||
|
||||
Dependencies: <a href="https://forum.minetest.net/viewtopic.php?f=11&t=12999">biome_lib</a> and default
|
|
@ -1,188 +0,0 @@
|
|||
|
||||
moretrees.beech_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 8,
|
||||
seed_diff = 2,
|
||||
rarity = 50,
|
||||
max_count = 20,
|
||||
}
|
||||
|
||||
moretrees.palm_biome = {
|
||||
surface = "default:sand",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 5,
|
||||
seed_diff = 330,
|
||||
min_elevation = -1,
|
||||
max_elevation = 1,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 15,
|
||||
near_nodes_count = 10,
|
||||
temp_min = 0.25,
|
||||
temp_max = -0.15,
|
||||
rarity = 50,
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
moretrees.apple_tree_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 331,
|
||||
min_elevation = 1,
|
||||
max_elevation = 10,
|
||||
temp_min = 0.1,
|
||||
temp_max = -0.15,
|
||||
rarity = 75,
|
||||
max_count = 5,
|
||||
}
|
||||
|
||||
moretrees.oak_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 15,
|
||||
seed_diff = 332,
|
||||
min_elevation = 0,
|
||||
max_elevation = 10,
|
||||
temp_min = 0.4,
|
||||
temp_max = 0.2,
|
||||
rarity = 50,
|
||||
max_count = 5,
|
||||
}
|
||||
|
||||
moretrees.sequoia_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 333,
|
||||
min_elevation = 0,
|
||||
max_elevation = 10,
|
||||
temp_min = 1,
|
||||
temp_max = -0.4,
|
||||
rarity = 90,
|
||||
max_count = 5,
|
||||
}
|
||||
|
||||
moretrees.birch_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 5,
|
||||
seed_diff = 334,
|
||||
min_elevation = 10,
|
||||
max_elevation = 15,
|
||||
temp_min = 0.9,
|
||||
temp_max = 0.3,
|
||||
rarity = 50,
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
moretrees.willow_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 337,
|
||||
min_elevation = -5,
|
||||
max_elevation = 5,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 15,
|
||||
near_nodes_count = 5,
|
||||
rarity = 75,
|
||||
max_count = 5,
|
||||
}
|
||||
|
||||
moretrees.acacia_biome = {
|
||||
surface = { "default:dirt_with_grass", "default:dirt_with_dry_grass", "default:desert_sand" },
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 15,
|
||||
seed_diff = 1,
|
||||
rarity = 50,
|
||||
max_count = 15,
|
||||
plantlife_limit = -1,
|
||||
humidity_min = 0.3,
|
||||
humidity_max = 0,
|
||||
}
|
||||
|
||||
moretrees.rubber_tree_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 338,
|
||||
min_elevation = -5,
|
||||
max_elevation = 5,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 15,
|
||||
near_nodes_count = 10,
|
||||
temp_min = -0.15,
|
||||
rarity = 75,
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
moretrees.jungletree_biome = {
|
||||
surface = {
|
||||
"default:dirt",
|
||||
"default:dirt_with_grass",
|
||||
"woodsoils:dirt_with_leaves_1",
|
||||
"woodsoils:grass_with_leaves_1",
|
||||
"woodsoils:grass_with_leaves_2"
|
||||
},
|
||||
avoid_nodes = {"moretrees:jungletree_trunk"},
|
||||
max_count = 12,
|
||||
avoid_radius = 3,
|
||||
rarity = 85,
|
||||
seed_diff = 329,
|
||||
min_elevation = 1,
|
||||
near_nodes = {"default:jungletree"},
|
||||
near_nodes_size = 6,
|
||||
near_nodes_vertical = 2,
|
||||
near_nodes_count = 1,
|
||||
plantlife_limit = -0.9,
|
||||
}
|
||||
|
||||
moretrees.spruce_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 335,
|
||||
min_elevation = 20,
|
||||
temp_min = 0.9,
|
||||
temp_max = 0.7,
|
||||
rarity = 50,
|
||||
max_count = 5,
|
||||
}
|
||||
|
||||
moretrees.cedar_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 336,
|
||||
near_nodes = {"default:water_source"},
|
||||
near_nodes_size = 15,
|
||||
near_nodes_count = 5,
|
||||
rarity = 50,
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
moretrees.fir_biome = {
|
||||
surface = "default:dirt_with_grass",
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 359,
|
||||
min_elevation = 25,
|
||||
temp_min = 0.9,
|
||||
temp_max = 0.3,
|
||||
rarity = 50,
|
||||
max_count = 10,
|
||||
}
|
||||
|
||||
moretrees.fir_biome_snow = {
|
||||
surface = {"snow:dirt_with_snow", "snow:snow"},
|
||||
below_nodes = {"default:dirt", "default:dirt_with_grass", "snow:dirt_with_snow"},
|
||||
avoid_nodes = moretrees.avoidnodes,
|
||||
avoid_radius = 10,
|
||||
seed_diff = 359,
|
||||
rarity = 50,
|
||||
max_count = 10,
|
||||
check_air = false,
|
||||
delete_above = true,
|
||||
spawn_replace_node = true
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
local S = moretrees.intllib
|
||||
|
||||
for i in ipairs(moretrees.treelist) do
|
||||
local treename = moretrees.treelist[i][1]
|
||||
|
||||
-- MODIFICATION MADE FOR MFF //MFF(Mg|08/12/15)
|
||||
if minetest.registered_items["moretrees:" .. treename .. "_trunk_sideways"] then
|
||||
minetest.register_craft({
|
||||
output = "moretrees:"..treename.."_trunk 2",
|
||||
recipe = {
|
||||
{"moretrees:"..treename.."_trunk_sideways"},
|
||||
{"moretrees:"..treename.."_trunk_sideways"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "moretrees:"..treename.."_planks 4",
|
||||
recipe = {
|
||||
"moretrees:"..treename.."_trunk_sideways"
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "moretrees:"..treename.."_planks 4",
|
||||
recipe = {
|
||||
"moretrees:"..treename.."_trunk"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "moretrees:"..treename.."_sapling",
|
||||
burntime = 10,
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "moretrees:rubber_tree_planks 4",
|
||||
recipe = {
|
||||
"moretrees:rubber_tree_trunk_empty"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:moretrees_leaves",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
-- Food recipes!
|
||||
|
||||
minetest.register_craftitem("moretrees:coconut_milk", {
|
||||
description = S("Coconut Milk"),
|
||||
inventory_image = "moretrees_coconut_milk_inv.png",
|
||||
wield_image = "moretrees_coconut_milk.png",
|
||||
on_use = minetest.item_eat(2),
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moretrees:raw_coconut", {
|
||||
description = S("Raw Coconut"),
|
||||
inventory_image = "moretrees_raw_coconut.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moretrees:acorn_muffin_batter", {
|
||||
description = S("Acorn Muffin batter"),
|
||||
inventory_image = "moretrees_acorn_muffin_batter.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moretrees:acorn_muffin", {
|
||||
description = S("Acorn Muffin"),
|
||||
inventory_image = "moretrees_acorn_muffin.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moretrees:spruce_nuts", {
|
||||
description = S("Roasted Spruce Cone Nuts"),
|
||||
inventory_image = "moretrees_spruce_nuts.png",
|
||||
on_use = minetest.item_eat(1),
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moretrees:cedar_nuts", {
|
||||
description = S("Roasted Cedar Cone Nuts"),
|
||||
inventory_image = "moretrees_cedar_nuts.png",
|
||||
on_use = minetest.item_eat(1),
|
||||
})
|
||||
|
||||
minetest.register_craftitem("moretrees:fir_nuts", {
|
||||
description = S("Roasted Fir Cone Nuts"),
|
||||
inventory_image = "moretrees_fir_nuts.png",
|
||||
on_use = minetest.item_eat(1),
|
||||
})
|
||||
|
||||
for i in ipairs(moretrees.cutting_tools) do
|
||||
local tool = moretrees.cutting_tools[i]
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "moretrees:coconut_milk",
|
||||
recipe = {
|
||||
"moretrees:coconut",
|
||||
"vessels:drinking_glass",
|
||||
tool
|
||||
},
|
||||
replacements = {
|
||||
{ "moretrees:coconut", "moretrees:raw_coconut" },
|
||||
{ tool, tool }
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "moretrees:acorn_muffin_batter",
|
||||
recipe = {
|
||||
"moretrees:acorn",
|
||||
"moretrees:acorn",
|
||||
"moretrees:acorn",
|
||||
"moretrees:acorn",
|
||||
"moretrees:coconut_milk",
|
||||
},
|
||||
replacements = {
|
||||
{ "moretrees:coconut_milk", "vessels:drinking_glass" }
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "moretrees:acorn_muffin 4",
|
||||
recipe = "moretrees:acorn_muffin_batter",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "moretrees:spruce_nuts 4",
|
||||
recipe = "moretrees:spruce_cone",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "moretrees:cedar_nuts 4",
|
||||
recipe = "moretrees:cedar_cone",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "moretrees:fir_nuts 4",
|
||||
recipe = "moretrees:fir_cone",
|
||||
})
|
||||
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
-- Global configuration variables
|
||||
|
||||
-- Enable the various kinds of trees.
|
||||
|
||||
moretrees.enable_apple_tree = true
|
||||
moretrees.enable_oak = true
|
||||
moretrees.enable_sequoia = true
|
||||
moretrees.enable_palm = true
|
||||
moretrees.enable_cedar = true
|
||||
moretrees.enable_rubber_tree = true
|
||||
moretrees.enable_willow = true
|
||||
moretrees.enable_acacia = true
|
||||
moretrees.enable_birch = true
|
||||
moretrees.enable_spruce = true
|
||||
moretrees.enable_jungle_tree = true
|
||||
moretrees.enable_fir = true
|
||||
moretrees.enable_beech = false
|
||||
|
||||
-- set this to true to make moretrees spawn saplings at mapgen time instead
|
||||
-- of fully-grown trees, which will grow into full trees after a very short
|
||||
-- delay. This reduces mapgen lag in some situations.
|
||||
|
||||
moretrees.spawn_saplings = false
|
||||
|
||||
-- Set this to true to allow defining stairs/slabs/etc. If Moreblocks is
|
||||
-- installed, this will use that mod's Stairs Plus component. Otherwise, it
|
||||
-- will use the default stairs mod in minetest_game, if present
|
||||
|
||||
moretrees.enable_stairs = true
|
||||
|
||||
-- Set this to true if you want the plantlike drawtype for leaves, which
|
||||
-- improves some peoples' framerates without resorting to making leaf nodes opaque.
|
||||
-- Affects default leaves and default jungle leaves also.
|
||||
|
||||
moretrees.plantlike_leaves = false
|
||||
|
||||
-- Enable this if you want moretrees to redefine default apples so that they
|
||||
-- fall when leaves decay/are dug.
|
||||
|
||||
moretrees.enable_redefine_apple = true
|
||||
|
||||
-- Set this to true to enable leaf decay of all trees except the default ones.
|
||||
|
||||
moretrees.enable_leafdecay = true
|
||||
|
||||
-- various related settings to configure leaf decay.
|
||||
|
||||
moretrees.leafdecay_delay = 2
|
||||
moretrees.leafdecay_chance = 5
|
||||
moretrees.leafdecay_radius = 5
|
||||
moretrees.palm_leafdecay_radius = 10
|
||||
|
||||
-- Change these settings if you want default trees to be gradually cut down
|
||||
-- above the elevation where firs normally generate.
|
||||
|
||||
moretrees.firs_remove_default_trees = false
|
||||
moretrees.firs_remove_interval = 2
|
||||
moretrees.firs_remove_chance = 150
|
||||
|
||||
-- Sapling settings
|
||||
|
||||
moretrees.sapling_interval = 500
|
||||
moretrees.sapling_chance = 20
|
||||
|
||||
-- If this variable is set to true, drop leaves out as entities during leaf
|
||||
-- decay, rather than just disappearing them.
|
||||
|
||||
moretrees.decay_leaves_as_items = false
|
|
@ -1,6 +0,0 @@
|
|||
default
|
||||
biome_lib
|
||||
stairs?
|
||||
moreblocks?
|
||||
intllib?
|
||||
|
|
@ -1 +0,0 @@
|
|||
This mod adds a whole bunch of new types of trees to the game
|
|
@ -1,300 +0,0 @@
|
|||
-- More trees! 2013-04-07
|
||||
--
|
||||
-- This mod adds more types of trees to the game
|
||||
--
|
||||
-- Some of the node definitions and textures came from cisoun's conifers mod
|
||||
-- and bas080's jungle trees mod.
|
||||
--
|
||||
-- Brought together into one mod and made L-systems compatible by Vanessa
|
||||
-- Ezekowitz.
|
||||
--
|
||||
-- Firs and Jungle tree axioms/rules by Vanessa Ezekowitz, with the
|
||||
-- latter having been tweaked by RealBadAngel, most other axioms/rules written
|
||||
-- by RealBadAngel.
|
||||
--
|
||||
-- License: WTFPL for all parts (code and textures, including those copied
|
||||
-- from the the old jungletree and conifers mods).
|
||||
|
||||
moretrees = {}
|
||||
|
||||
-- Read the default config file (and if necessary, copy it to the world folder).
|
||||
|
||||
local worldpath=minetest.get_worldpath()
|
||||
local modpath=minetest.get_modpath("moretrees")
|
||||
|
||||
dofile(modpath.."/default_settings.txt")
|
||||
|
||||
if io.open(worldpath.."/moretrees_settings.txt","r") then
|
||||
io.close()
|
||||
dofile(worldpath.."/moretrees_settings.txt")
|
||||
end
|
||||
|
||||
-- Boilerplate to support localized strings if intllib mod is installed.
|
||||
local S
|
||||
if minetest.get_modpath("intllib") then
|
||||
S = intllib.Getter()
|
||||
else
|
||||
S = function(s) return s end
|
||||
end
|
||||
moretrees.intllib = S
|
||||
|
||||
-- clone node
|
||||
|
||||
function moretrees.clone_node(name)
|
||||
local node2 = {}
|
||||
local node = minetest.registered_nodes[name]
|
||||
for k,v in pairs(node) do
|
||||
node2[k]=v
|
||||
end
|
||||
return node2
|
||||
end
|
||||
|
||||
-- infinite stacks checking
|
||||
|
||||
if minetest.get_modpath("unified_inventory") or not minetest.setting_getbool("creative_mode") then
|
||||
moretrees.expect_infinite_stacks = false
|
||||
else
|
||||
moretrees.expect_infinite_stacks = true
|
||||
end
|
||||
|
||||
-- tables, load other files
|
||||
|
||||
moretrees.cutting_tools = {
|
||||
"default:axe_bronze",
|
||||
"default:axe_diamond",
|
||||
"default:axe_mese",
|
||||
"default:axe_steel",
|
||||
-- "glooptest:axe_alatro",
|
||||
-- "glooptest:axe_arol",
|
||||
"default:axe_mithril",
|
||||
"default:axe_silver",
|
||||
-- "titanium:axe",
|
||||
}
|
||||
-- Cutting tools disabled. They are unknown //MFF(Mg|08/09/15)
|
||||
|
||||
dofile(modpath.."/tree_models.lua")
|
||||
dofile(modpath.."/node_defs.lua")
|
||||
dofile(modpath.."/biome_defs.lua")
|
||||
dofile(modpath.."/saplings.lua")
|
||||
dofile(modpath.."/crafts.lua")
|
||||
|
||||
-- tree spawning setup
|
||||
|
||||
if moretrees.spawn_saplings then
|
||||
moretrees.spawn_beech_object = "moretrees:beech_sapling_ongen"
|
||||
moretrees.spawn_apple_tree_object = "moretrees:apple_tree_sapling_ongen"
|
||||
moretrees.spawn_oak_object = "moretrees:oak_sapling_ongen"
|
||||
moretrees.spawn_sequoia_object = "moretrees:sequoia_sapling_ongen"
|
||||
moretrees.spawn_palm_object = "moretrees:palm_sapling_ongen"
|
||||
moretrees.spawn_cedar_object = "moretrees:cedar_sapling_ongen"
|
||||
moretrees.spawn_rubber_tree_object = "moretrees:rubber_tree_sapling_ongen"
|
||||
moretrees.spawn_willow_object = "moretrees:willow_sapling_ongen"
|
||||
moretrees.spawn_acacia_object = "moretrees:acacia_sapling_ongen"
|
||||
moretrees.spawn_birch_object = "moretrees:birch_sapling_ongen"
|
||||
moretrees.spawn_spruce_object = "moretrees:spruce_sapling_ongen"
|
||||
moretrees.spawn_jungletree_object = "moretrees:jungletree_sapling_ongen"
|
||||
moretrees.spawn_fir_object = "moretrees:fir_sapling_ongen"
|
||||
moretrees.spawn_fir_snow_object = "snow:sapling_pine"
|
||||
else
|
||||
moretrees.spawn_beech_object = moretrees.beech_model
|
||||
moretrees.spawn_apple_tree_object = moretrees.apple_tree_model
|
||||
moretrees.spawn_oak_object = moretrees.oak_model
|
||||
moretrees.spawn_sequoia_object = moretrees.sequoia_model
|
||||
moretrees.spawn_palm_object = moretrees.palm_model
|
||||
moretrees.spawn_cedar_object = moretrees.cedar_model
|
||||
moretrees.spawn_rubber_tree_object = moretrees.rubber_tree_model
|
||||
moretrees.spawn_willow_object = moretrees.willow_model
|
||||
moretrees.spawn_acacia_object = moretrees.acacia_model
|
||||
moretrees.spawn_birch_object = "moretrees.grow_birch"
|
||||
moretrees.spawn_spruce_object = "moretrees.grow_spruce"
|
||||
moretrees.spawn_jungletree_object = "moretrees.grow_jungletree"
|
||||
moretrees.spawn_fir_object = "moretrees.grow_fir"
|
||||
moretrees.spawn_fir_snow_object = "moretrees.grow_fir_snow"
|
||||
end
|
||||
|
||||
if moretrees.enable_beech then
|
||||
biome_lib:register_generate_plant(moretrees.beech_biome, moretrees.spawn_beech_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_apple_tree then
|
||||
biome_lib:register_generate_plant(moretrees.apple_tree_biome, moretrees.spawn_apple_tree_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_oak then
|
||||
biome_lib:register_generate_plant(moretrees.oak_biome, moretrees.spawn_oak_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_sequoia then
|
||||
biome_lib:register_generate_plant(moretrees.sequoia_biome, moretrees.spawn_sequoia_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_palm then
|
||||
biome_lib:register_generate_plant(moretrees.palm_biome, moretrees.spawn_palm_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_cedar then
|
||||
biome_lib:register_generate_plant(moretrees.cedar_biome, moretrees.spawn_cedar_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_rubber_tree then
|
||||
biome_lib:register_generate_plant(moretrees.rubber_tree_biome, moretrees.spawn_rubber_tree_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_willow then
|
||||
biome_lib:register_generate_plant(moretrees.willow_biome, moretrees.spawn_willow_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_acacia then
|
||||
biome_lib:register_generate_plant(moretrees.acacia_biome, moretrees.spawn_acacia_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_birch then
|
||||
biome_lib:register_generate_plant(moretrees.birch_biome, moretrees.spawn_birch_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_spruce then
|
||||
biome_lib:register_generate_plant(moretrees.spruce_biome, moretrees.spawn_spruce_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_jungle_tree then
|
||||
biome_lib:register_generate_plant(moretrees.jungletree_biome, moretrees.spawn_jungletree_object)
|
||||
end
|
||||
|
||||
if moretrees.enable_fir then
|
||||
biome_lib:register_generate_plant(moretrees.fir_biome, moretrees.spawn_fir_object)
|
||||
if minetest.get_modpath("snow") then
|
||||
biome_lib:register_generate_plant(moretrees.fir_biome_snow, moretrees.spawn_fir_snow_object)
|
||||
end
|
||||
end
|
||||
|
||||
-- Code to spawn a birch tree
|
||||
|
||||
function moretrees.grow_birch(pos)
|
||||
minetest.remove_node(pos)
|
||||
if math.random(1,2) == 1 then
|
||||
minetest.spawn_tree(pos, moretrees.birch_model1)
|
||||
else
|
||||
minetest.spawn_tree(pos, moretrees.birch_model2)
|
||||
end
|
||||
end
|
||||
|
||||
-- Code to spawn a spruce tree
|
||||
|
||||
function moretrees.grow_spruce(pos)
|
||||
minetest.remove_node(pos)
|
||||
if math.random(1,2) == 1 then
|
||||
minetest.spawn_tree(pos, moretrees.spruce_model1)
|
||||
else
|
||||
minetest.spawn_tree(pos, moretrees.spruce_model2)
|
||||
end
|
||||
end
|
||||
|
||||
-- Code to spawn jungle trees
|
||||
|
||||
moretrees.jt_axiom1 = "FFFA"
|
||||
moretrees.jt_rules_a1 = "FFF[&&-FBf[&&&Ff]^^^Ff][&&+FBFf[&&&FFf]^^^Ff][&&---FBFf[&&&Ff]^^^Ff][&&+++FBFf[&&&Ff]^^^Ff]F/A"
|
||||
moretrees.jt_rules_b1 = "[-Ff&f][+Ff&f]B"
|
||||
|
||||
moretrees.jt_axiom2 = "FFFFFA"
|
||||
moretrees.jt_rules_a2 = "FFFFF[&&-FFFBF[&&&FFff]^^^FFf][&&+FFFBFF[&&&FFff]^^^FFf][&&---FFFBFF[&&&FFff]^^^FFf][&&+++FFFBFF[&&&FFff]^^^FFf]FF/A"
|
||||
moretrees.jt_rules_b2 = "[-FFf&ff][+FFf&ff]B"
|
||||
|
||||
moretrees.ct_rules_a1 = "FF[FF][&&-FBF][&&+FBF][&&---FBF][&&+++FBF]F/A"
|
||||
moretrees.ct_rules_b1 = "[-FBf][+FBf]"
|
||||
|
||||
moretrees.ct_rules_a2 = "FF[FF][&&-FBF][&&+FBF][&&---FBF][&&+++FBF]F/A"
|
||||
moretrees.ct_rules_b2 = "[-fB][+fB]"
|
||||
|
||||
function moretrees.grow_jungletree(pos)
|
||||
local r1 = math.random(2)
|
||||
local r2 = math.random(3)
|
||||
if r1 == 1 then
|
||||
moretrees.jungletree_model.leaves2 = "moretrees:jungletree_leaves_red"
|
||||
else
|
||||
moretrees.jungletree_model.leaves2 = "moretrees:jungletree_leaves_yellow"
|
||||
end
|
||||
moretrees.jungletree_model.leaves2_chance = math.random(25, 75)
|
||||
|
||||
if r2 == 1 then
|
||||
moretrees.jungletree_model.trunk_type = "single"
|
||||
moretrees.jungletree_model.iterations = 2
|
||||
moretrees.jungletree_model.axiom = moretrees.jt_axiom1
|
||||
moretrees.jungletree_model.rules_a = moretrees.jt_rules_a1
|
||||
moretrees.jungletree_model.rules_b = moretrees.jt_rules_b1
|
||||
elseif r2 == 2 then
|
||||
moretrees.jungletree_model.trunk_type = "double"
|
||||
moretrees.jungletree_model.iterations = 4
|
||||
moretrees.jungletree_model.axiom = moretrees.jt_axiom2
|
||||
moretrees.jungletree_model.rules_a = moretrees.jt_rules_a2
|
||||
moretrees.jungletree_model.rules_b = moretrees.jt_rules_b2
|
||||
elseif r2 == 3 then
|
||||
moretrees.jungletree_model.trunk_type = "crossed"
|
||||
moretrees.jungletree_model.iterations = 4
|
||||
moretrees.jungletree_model.axiom = moretrees.jt_axiom2
|
||||
moretrees.jungletree_model.rules_a = moretrees.jt_rules_a2
|
||||
moretrees.jungletree_model.rules_b = moretrees.jt_rules_b2
|
||||
end
|
||||
|
||||
minetest.remove_node(pos)
|
||||
local leaves = minetest.find_nodes_in_area({x = pos.x-1, y = pos.y, z = pos.z-1}, {x = pos.x+1, y = pos.y+10, z = pos.z+1}, "default:leaves")
|
||||
for leaf in ipairs(leaves) do
|
||||
minetest.remove_node(leaves[leaf])
|
||||
end
|
||||
minetest.spawn_tree(pos, moretrees.jungletree_model)
|
||||
end
|
||||
|
||||
-- code to spawn fir trees
|
||||
|
||||
function moretrees.grow_fir(pos)
|
||||
if math.random(2) == 1 then
|
||||
moretrees.fir_model.leaves="moretrees:fir_leaves"
|
||||
else
|
||||
moretrees.fir_model.leaves="moretrees:fir_leaves_bright"
|
||||
end
|
||||
if math.random(2) == 1 then
|
||||
moretrees.fir_model.rules_a = moretrees.ct_rules_a1
|
||||
moretrees.fir_model.rules_b = moretrees.ct_rules_b1
|
||||
else
|
||||
moretrees.fir_model.rules_a = moretrees.ct_rules_a2
|
||||
moretrees.fir_model.rules_b = moretrees.ct_rules_b2
|
||||
end
|
||||
|
||||
moretrees.fir_model.iterations = 7
|
||||
moretrees.fir_model.random_level = 5
|
||||
|
||||
minetest.remove_node(pos)
|
||||
local leaves = minetest.find_nodes_in_area({x = pos.x, y = pos.y, z = pos.z}, {x = pos.x, y = pos.y+5, z = pos.z}, "default:leaves")
|
||||
for leaf in ipairs(leaves) do
|
||||
minetest.remove_node(leaves[leaf])
|
||||
end
|
||||
minetest.spawn_tree(pos,moretrees.fir_model)
|
||||
end
|
||||
|
||||
-- same thing, but a smaller version that grows only in snow biomes
|
||||
|
||||
function moretrees.grow_fir_snow(pos)
|
||||
if math.random(2) == 1 then
|
||||
moretrees.fir_model.leaves="moretrees:fir_leaves"
|
||||
else
|
||||
moretrees.fir_model.leaves="moretrees:fir_leaves_bright"
|
||||
end
|
||||
if math.random(2) == 1 then
|
||||
moretrees.fir_model.rules_a = moretrees.ct_rules_a1
|
||||
moretrees.fir_model.rules_b = moretrees.ct_rules_b1
|
||||
else
|
||||
moretrees.fir_model.rules_a = moretrees.ct_rules_a2
|
||||
moretrees.fir_model.rules_b = moretrees.ct_rules_b2
|
||||
end
|
||||
|
||||
moretrees.fir_model.iterations = 2
|
||||
moretrees.fir_model.random_level = 2
|
||||
|
||||
minetest.remove_node(pos)
|
||||
local leaves = minetest.find_nodes_in_area({x = pos.x, y = pos.y, z = pos.z}, {x = pos.x, y = pos.y+5, z = pos.z}, "default:leaves")
|
||||
for leaf in ipairs(leaves) do
|
||||
minetest.remove_node(leaves[leaf])
|
||||
end
|
||||
minetest.spawn_tree(pos,moretrees.fir_model)
|
||||
end
|
||||
|
||||
minetest.log("action", S("[Moretrees] Loaded (2013-02-11)"))
|
|
@ -1,73 +0,0 @@
|
|||
# Translation by Xanthin
|
||||
|
||||
### crafts.lua ###
|
||||
Coconut Milk = Kokosnussmilch
|
||||
Raw Coconut = Kokosnussfleisch
|
||||
Acorn Muffin batter = Eichelmuffinteig
|
||||
Acorn Muffin = Eichelmuffin
|
||||
Roasted Spruce Cone Nuts = Geroestete Fichtenzapfen
|
||||
Roasted Pine Cone Nuts = Geroestete Kiefernzapfen
|
||||
Roasted Fir Cone Nuts = Geroestete Tannenzapfen
|
||||
|
||||
### node_defs.lua ###
|
||||
Beech Tree Trunk = Buchenstamm
|
||||
Apple Tree Trunk = Apfelbaumstamm
|
||||
Oak Tree Trunk = Eichenstamm
|
||||
Giant Sequoia Trunk = Riesenmammutbaumstamm
|
||||
Birch Tree Trunk = Birkenstamm
|
||||
Palm Tree Trunk = Palmenstamm
|
||||
Spruce Tree Trunk = Fichtenstamm
|
||||
Pine Tree Trunk = Kiefernstamm
|
||||
Willow Tree Trunk = Weidenstamm
|
||||
Rubber Tree Trunk = Gummibaumstamm
|
||||
Jungle Tree Trunk = Tropenbaumstamm
|
||||
Douglas Fir Trunk = Douglasienstamm
|
||||
Beech Tree Planks = Buchebretter
|
||||
Apple Tree Planks = Apfelbaumbretter
|
||||
Oak Tree Planks = Eichenbretter
|
||||
Giant Sequoia Planks = Riesenmammutbaumbretter
|
||||
Birch Tree Planks = Birkebretter
|
||||
Palm Tree Planks = Palmenbretter
|
||||
Spruce Tree Planks = Fichtenbretter
|
||||
Pine Tree Planks = Kiefernbretter
|
||||
Willow Tree Planks = Weidenbretter
|
||||
Rubber Tree Planks = Gummibaumbretter
|
||||
Jungle Tree Planks = Tropenholzbretter
|
||||
Douglas Fir Planks = Douglasienbretter
|
||||
Beech Tree Sapling = Buchesetzling
|
||||
Apple Tree Sapling = Apfelbaumsetzling
|
||||
Oak Tree Sapling = Eichensetzling
|
||||
Giant Sequoia Sapling = Riesenmammutbaumsetzling
|
||||
Birch Tree Sapling = Birkensetzling
|
||||
Palm Tree Sapling = Palmensetzling
|
||||
Spruce Tree Sapling = Fichtensetzling
|
||||
Pine Tree Sapling = Kiefernsetzling
|
||||
Willow Tree Sapling = Weidensetzling
|
||||
Rubber Tree Sapling = Gummibaumsetzling
|
||||
Jungle Tree Sapling = Tropenbaumsetzling
|
||||
Douglas Fir Sapling = Douglasiensetzling
|
||||
Beech Tree Leaves = Buchenlaub
|
||||
Apple Tree Leaves = Apfelbaumlaub
|
||||
Oak Tree Leaves = Eichenlaub
|
||||
Giant Sequoia Leaves = Riesenmammutbaumlaub
|
||||
Birch Tree Leaves = Birkenlaub
|
||||
Palm Tree Leaves = Palmenlaub
|
||||
Spruce Tree Leaves = Fichtennadeln
|
||||
Pine Tree Leaves = Kiefernnadeln
|
||||
Willow Tree Leaves = Weidenlaub
|
||||
Rubber Tree Leaves = Gummibaumlaub
|
||||
Jungle Tree Leaves = Tropenbaumlaub
|
||||
Douglas Fir Leaves = Douglasiennadeln
|
||||
|
||||
Acorn = Eichel
|
||||
Coconut = Kokosnuss
|
||||
Spruce Cone = Fichtenzapfen
|
||||
Pine Cone = Kiefernzapfen
|
||||
Fir Cone = Tannenzapfen
|
||||
Jungle Sapling = Tropenbaumsetzling
|
||||
Jungle Tree Leaves (Yellow) = Tropenbaumlaub (gelb)
|
||||
Jungle Tree Leaves (Red) = Tropenbaumlaub (rot)
|
||||
Douglas Fir Leaves (Bright) = Douglasiennadeln (breit)
|
||||
Rubber Tree Trunk (Empty) = Gummibaumstamm (leer)
|
||||
|
||||
[Moretrees] Loaded (2013-02-11) = [Moretrees] geladen (2013-02-11)
|
|
@ -1,73 +0,0 @@
|
|||
# Template
|
||||
|
||||
### crafts.lua ###
|
||||
Coconut Milk =
|
||||
Raw Coconut =
|
||||
Acorn Muffin batter =
|
||||
Acorn Muffin =
|
||||
Roasted Spruce Cone Nuts =
|
||||
Roasted Pine Cone Nuts =
|
||||
Roasted Fir Cone Nuts =
|
||||
|
||||
### node_defs.lua ###
|
||||
Beech Tree Trunk =
|
||||
Apple Tree Trunk =
|
||||
Oak Tree Trunk =
|
||||
Giant Sequoia Trunk =
|
||||
Birch Tree Trunk =
|
||||
Palm Tree Trunk =
|
||||
Spruce Tree Trunk =
|
||||
Pine Tree Trunk =
|
||||
Willow Tree Trunk =
|
||||
Rubber Tree Trunk =
|
||||
Jungle Tree Trunk =
|
||||
Douglas Fir Trunk =
|
||||
Beech Tree Planks =
|
||||
Apple Tree Planks =
|
||||
Oak Tree Planks =
|
||||
Giant Sequoia Planks =
|
||||
Birch Tree Planks =
|
||||
Palm Tree Planks =
|
||||
Spruce Tree Planks =
|
||||
Pine Tree Planks =
|
||||
Willow Tree Planks =
|
||||
Rubber Tree Planks =
|
||||
Jungle Tree Planks =
|
||||
Douglas Fir Planks =
|
||||
Beech Tree Sapling =
|
||||
Apple Tree Sapling =
|
||||
Oak Tree Sapling =
|
||||
Giant Sequoia Sapling =
|
||||
Birch Tree Sapling =
|
||||
Palm Tree Sapling =
|
||||
Spruce Tree Sapling =
|
||||
Pine Tree Sapling =
|
||||
Willow Tree Sapling =
|
||||
Rubber Tree Sapling =
|
||||
Jungle Tree Sapling =
|
||||
Douglas Fir Sapling =
|
||||
Beech Tree Leaves =
|
||||
Apple Tree Leaves =
|
||||
Oak Tree Leaves =
|
||||
Giant Sequoia Leaves =
|
||||
Birch Tree Leaves =
|
||||
Palm Tree Leaves =
|
||||
Spruce Tree Leaves =
|
||||
Pine Tree Leaves =
|
||||
Willow Tree Leaves =
|
||||
Rubber Tree Leaves =
|
||||
Jungle Tree Leaves =
|
||||
Douglas Fir Leaves =
|
||||
|
||||
Acorn =
|
||||
Coconut =
|
||||
Spruce Cone =
|
||||
Pine Cone =
|
||||
Fir Cone =
|
||||
Jungle Sapling =
|
||||
Jungle Tree Leaves (Yellow) =
|
||||
Jungle Tree Leaves (Red) =
|
||||
Douglas Fir Leaves (Bright) =
|
||||
Rubber Tree Trunk (Empty) =
|
||||
|
||||
[Moretrees] Loaded (2013-02-11) =
|
|
@ -1 +0,0 @@
|
|||
name = moretrees
|
|
@ -1,437 +0,0 @@
|
|||
local S = moretrees.intllib
|
||||
|
||||
moretrees.avoidnodes = {}
|
||||
|
||||
moretrees.treelist = {
|
||||
{"beech", "Beech Tree"},
|
||||
{"apple_tree", "Apple Tree"},
|
||||
{"oak", "Oak Tree", "acorn", "Acorn", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
{"sequoia", "Giant Sequoia"},
|
||||
{"birch", "Birch Tree"},
|
||||
{"palm", "Palm Tree", "coconut", "Coconut", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 1.0 },
|
||||
{"spruce", "Spruce Tree", "spruce_cone", "Spruce Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
{"cedar", "Cedar Tree", "cedar_cone", "Cedar Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
{"willow", "Willow Tree"},
|
||||
{"rubber_tree", "Rubber Tree"},
|
||||
{"fir", "Douglas Fir", "fir_cone", "Fir Cone", {-0.2, -0.5, -0.2, 0.2, 0, 0.2}, 0.8 },
|
||||
|
||||
{"jungletree", "Jungle Tree", nil, nil, nil, nil, "default_junglesapling.png" },
|
||||
{"acacia", "Acacia Tree", nil, nil, nil, nil, "default_acacia_sapling.png" },
|
||||
}
|
||||
|
||||
local dirs1 = { 21, 20, 23, 22, 21 }
|
||||
local dirs2 = { 12, 9, 18, 7, 12 }
|
||||
local dirs3 = { 14, 11, 16, 5, 14 }
|
||||
|
||||
local moretrees_new_leaves_drawtype = "allfaces_optional"
|
||||
local moretrees_plantlike_leaves_visual_scale = 1
|
||||
|
||||
if moretrees.plantlike_leaves then
|
||||
moretrees_new_leaves_drawtype = "plantlike"
|
||||
moretrees_plantlike_leaves_visual_scale = 1.189
|
||||
end
|
||||
|
||||
-- redefine default leaves to handle plantlike and/or leaf decay options
|
||||
|
||||
if moretrees.plantlike_leaves then
|
||||
minetest.override_item("default:leaves", {
|
||||
inventory_image = minetest.inventorycube("default_leaves.png"),
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.189
|
||||
})
|
||||
else
|
||||
minetest.override_item("default:leaves", {
|
||||
waving = 1
|
||||
})
|
||||
end
|
||||
|
||||
-- redefine default jungle leaves for same
|
||||
|
||||
if moretrees.plantlike_leaves then
|
||||
minetest.override_item("default:jungleleaves", {
|
||||
inventory_image = minetest.inventorycube("default_jungleleaves.png"),
|
||||
drawtype = "plantlike",
|
||||
visual_scale = 1.189
|
||||
})
|
||||
else
|
||||
minetest.override_item("default:jungleleaves", {
|
||||
waving = 1
|
||||
})
|
||||
end
|
||||
|
||||
for i in ipairs(moretrees.treelist) do
|
||||
local treename = moretrees.treelist[i][1]
|
||||
local treedesc = moretrees.treelist[i][2]
|
||||
local fruit = moretrees.treelist[i][3]
|
||||
local fruitdesc = moretrees.treelist[i][4]
|
||||
local selbox = moretrees.treelist[i][5]
|
||||
local vscale = moretrees.treelist[i][6]
|
||||
|
||||
local saptex = moretrees.treelist[i][7]
|
||||
|
||||
if treename ~= "jungletree" -- the default game provides jungle tree, acacia, and pine trunk/planks nodes.
|
||||
and treename ~= "acacia"
|
||||
and treename ~= "pine" then
|
||||
|
||||
saptex = "moretrees_"..treename.."_sapling.png"
|
||||
|
||||
minetest.register_node("moretrees:"..treename.."_trunk", {
|
||||
description = S(treedesc.." Trunk"),
|
||||
tiles = {
|
||||
"moretrees_"..treename.."_trunk_top.png",
|
||||
"moretrees_"..treename.."_trunk_top.png",
|
||||
"moretrees_"..treename.."_trunk.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = true,
|
||||
groups = {tree=1,snappy=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_place = minetest.rotate_node,
|
||||
})
|
||||
|
||||
minetest.register_node("moretrees:"..treename.."_planks", {
|
||||
description = S(treedesc.." Planks"),
|
||||
tiles = {"moretrees_"..treename.."_wood.png"},
|
||||
is_ground_content = true,
|
||||
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("moretrees:"..treename.."_sapling", {
|
||||
description = S(treedesc.." Sapling"),
|
||||
drawtype = "plantlike",
|
||||
tiles = {saptex},
|
||||
inventory_image = saptex,
|
||||
paramtype = "light",
|
||||
paramtype2 = "waving",
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
|
||||
},
|
||||
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
})
|
||||
|
||||
-- player will get a sapling with 1/100 chance
|
||||
-- player will get leaves only if he/she gets no saplings,
|
||||
-- this is because max_items is 1
|
||||
|
||||
local droprarity = 100
|
||||
local decay = moretrees.leafdecay_radius
|
||||
|
||||
if treename == "palm" then
|
||||
droprarity = 20
|
||||
decay = moretrees.palm_leafdecay_radius
|
||||
end
|
||||
|
||||
local moretrees_leaves_inventory_image = nil
|
||||
local moretrees_new_leaves_waving = nil
|
||||
|
||||
if moretrees.plantlike_leaves then
|
||||
moretrees_leaves_inventory_image = minetest.inventorycube("moretrees_"..treename.."_leaves.png")
|
||||
else
|
||||
moretrees_new_leaves_waving = 1
|
||||
end
|
||||
|
||||
minetest.register_node("moretrees:"..treename.."_leaves", {
|
||||
description = S(treedesc.." Leaves"),
|
||||
drawtype = moretrees_new_leaves_drawtype,
|
||||
waving = moretrees_new_leaves_waving,
|
||||
visual_scale = moretrees_plantlike_leaves_visual_scale,
|
||||
tiles = { "moretrees_"..treename.."_leaves.png" },
|
||||
inventory_image = moretrees_leaves_inventory_image,
|
||||
paramtype = "light",
|
||||
groups = {snappy = 3, flammable = 2, leaves = 1, moretrees_leaves = 1, leafdecay = decay},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {"moretrees:"..treename.."_sapling"}, rarity = droprarity },
|
||||
{items = {"moretrees:"..treename.."_leaves"} }
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if moretrees.enable_stairs then
|
||||
if minetest.get_modpath("moreblocks") then
|
||||
|
||||
-- stairsplus:register_all(modname, subname, recipeitem, {fields})
|
||||
|
||||
stairsplus:register_all(
|
||||
"moretrees",
|
||||
treename.."_trunk",
|
||||
"moretrees:"..treename.."_trunk",
|
||||
{
|
||||
groups = { snappy=1, choppy=2, oddly_breakable_by_hand=1, flammable=2, not_in_creative_inventory=1 },
|
||||
tiles = {
|
||||
"moretrees_"..treename.."_trunk_top.png",
|
||||
"moretrees_"..treename.."_trunk_top.png",
|
||||
"moretrees_"..treename.."_trunk.png"
|
||||
},
|
||||
description = S(treedesc.." Trunk"),
|
||||
drop = treename.."_trunk",
|
||||
}
|
||||
)
|
||||
|
||||
stairsplus:register_all(
|
||||
"moretrees",
|
||||
treename.."_planks",
|
||||
"moretrees:"..treename.."_planks",
|
||||
{
|
||||
groups = { snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=3, not_in_creative_inventory=1 },
|
||||
tiles = { "moretrees_"..treename.."_wood.png" },
|
||||
description = S(treedesc.." Planks"),
|
||||
drop = treename.."_planks",
|
||||
}
|
||||
)
|
||||
elseif minetest.get_modpath("stairs") then
|
||||
stairs.register_stair_and_slab(
|
||||
"moretrees_"..treename.."_trunk",
|
||||
"moretrees:"..treename.."_trunk",
|
||||
{ snappy=1, choppy=2, oddly_breakable_by_hand=1, flammable=2 },
|
||||
{ "moretrees_"..treename.."_trunk_top.png",
|
||||
"moretrees_"..treename.."_trunk_top.png",
|
||||
"moretrees_"..treename.."_trunk.png"
|
||||
},
|
||||
S(treedesc.." Trunk Stair"),
|
||||
S(treedesc.." Trunk Slab"),
|
||||
default.node_sound_wood_defaults()
|
||||
)
|
||||
|
||||
stairs.register_stair_and_slab(
|
||||
"moretrees_"..treename.."_planks",
|
||||
"moretrees:"..treename.."_planks",
|
||||
{ snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=3 },
|
||||
{ "moretrees_"..treename.."_wood.png" },
|
||||
S(treedesc.." Planks Stair"),
|
||||
S(treedesc.." Planks Slab"),
|
||||
default.node_sound_wood_defaults()
|
||||
)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("moretrees:"..treename.."_sapling_ongen", {
|
||||
description = S(treedesc.." Sapling"),
|
||||
drawtype = "plantlike",
|
||||
tiles = {saptex},
|
||||
inventory_image = saptex,
|
||||
paramtype = "light",
|
||||
paramtype2 = "waving",
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
|
||||
},
|
||||
groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,not_in_creative_inventory=1,sapling=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
drop = "moretrees:"..treename.."_sapling"
|
||||
})
|
||||
|
||||
if fruit then
|
||||
minetest.register_node("moretrees:"..fruit, {
|
||||
description = S(fruitdesc),
|
||||
drawtype = "plantlike",
|
||||
tiles = { "moretrees_"..fruit..".png" },
|
||||
inventory_image = "moretrees_"..fruit..".png^[transformR180",
|
||||
wield_image = "moretrees_"..fruit..".png^[transformR180",
|
||||
visual_scale = vscale,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = selbox
|
||||
},
|
||||
groups = {fleshy=3,dig_immediate=3,flammable=2, attached_node=1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { "moretrees:"..treename.."_trunk_sideways" },
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local fdir = node.param2 or 0
|
||||
local nfdir = dirs2[fdir+1]
|
||||
minetest.add_node(pos, {name = "moretrees:"..treename.."_trunk", param2 = nfdir})
|
||||
end,
|
||||
})
|
||||
|
||||
table.insert(moretrees.avoidnodes, "moretrees:"..treename.."_trunk")
|
||||
|
||||
if moretrees.spawn_saplings then
|
||||
table.insert(moretrees.avoidnodes, "moretrees:"..treename.."_sapling")
|
||||
table.insert(moretrees.avoidnodes, "moretrees:"..treename.."_sapling_ongen")
|
||||
end
|
||||
end
|
||||
|
||||
-- Extra nodes for jungle trees:
|
||||
|
||||
local jungleleaves = {"yellow","red"}
|
||||
local jungleleavesnames = {"Yellow", "Red"}
|
||||
for color = 1, #jungleleaves do
|
||||
local leave_name = "moretrees:jungletree_leaves_"..jungleleaves[color]
|
||||
|
||||
local moretrees_leaves_inventory_image = nil
|
||||
|
||||
if moretrees.plantlike_leaves then
|
||||
moretrees_leaves_inventory_image = minetest.inventorycube("moretrees_jungletree_leaves_"..jungleleaves[color]..".png")
|
||||
else
|
||||
moretrees_new_leaves_waving = 1
|
||||
end
|
||||
|
||||
minetest.register_node(leave_name, {
|
||||
description = S("Jungle Tree Leaves ("..jungleleavesnames[color]..")"),
|
||||
drawtype = moretrees_new_leaves_drawtype,
|
||||
waving = moretrees_new_leaves_waving,
|
||||
visual_scale = moretrees_plantlike_leaves_visual_scale,
|
||||
tiles = {"moretrees_jungletree_leaves_"..jungleleaves[color]..".png"},
|
||||
inventory_image = moretrees_leaves_inventory_image,
|
||||
paramtype = "light",
|
||||
groups = {snappy = 3, flammable = 2, leaves = 1, moretrees_leaves = 1, leafdecay = moretrees.leafdecay_radius },
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {"default:junglesapling"}, rarity = 100 },
|
||||
{items = {"moretrees:jungletree_leaves_"..jungleleaves[color]} }
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
-- Extra needles for firs
|
||||
|
||||
local moretrees_leaves_inventory_image = nil
|
||||
|
||||
if moretrees.plantlike_leaves then
|
||||
moretrees_leaves_inventory_image = minetest.inventorycube("moretrees_fir_leaves_bright.png")
|
||||
end
|
||||
|
||||
minetest.register_node("moretrees:fir_leaves_bright", {
|
||||
drawtype = moretrees_new_leaves_drawtype,
|
||||
waving = moretrees_new_leaves_waving,
|
||||
visual_scale = moretrees_plantlike_leaves_visual_scale,
|
||||
description = S("Douglas Fir Leaves (Bright)"),
|
||||
tiles = { "moretrees_fir_leaves_bright.png" },
|
||||
inventory_image = moretrees_leaves_inventory_image,
|
||||
paramtype = "light",
|
||||
groups = {snappy = 3, flammable = 2, leaves = 1, moretrees_leaves = 1, leafdecay = moretrees.leafdecay_radius },
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {'moretrees:fir_sapling'}, rarity = 100 },
|
||||
{items = {'moretrees:fir_leaves_bright'} }
|
||||
}
|
||||
},
|
||||
sounds = default.node_sound_leaves_defaults()
|
||||
})
|
||||
|
||||
if moretrees.enable_redefine_apple then
|
||||
local appledef = moretrees.clone_node("default:apple")
|
||||
appledef.groups.attached_node = 1
|
||||
minetest.register_node(":default:apple", appledef)
|
||||
end
|
||||
|
||||
table.insert(moretrees.avoidnodes, "default:jungletree")
|
||||
table.insert(moretrees.avoidnodes, "default:pine_tree")
|
||||
table.insert(moretrees.avoidnodes, "default:acacia_tree")
|
||||
table.insert(moretrees.avoidnodes, "moretrees:fir_trunk")
|
||||
table.insert(moretrees.avoidnodes, "default:tree")
|
||||
|
||||
if moretrees.spawn_saplings then
|
||||
table.insert(moretrees.avoidnodes, "snow:sapling_pine")
|
||||
table.insert(moretrees.avoidnodes, "default:junglesapling")
|
||||
table.insert(moretrees.avoidnodes, "default:pine_sapling")
|
||||
table.insert(moretrees.avoidnodes, "default:acacia_sapling")
|
||||
end
|
||||
|
||||
-- "empty" (tapped) rubber tree nodes
|
||||
|
||||
minetest.register_node("moretrees:rubber_tree_trunk_empty", {
|
||||
description = S("Rubber Tree Trunk (Empty)"),
|
||||
tiles = {
|
||||
"moretrees_rubber_tree_trunk_top.png",
|
||||
"moretrees_rubber_tree_trunk_top.png",
|
||||
"moretrees_rubber_tree_trunk_empty.png"
|
||||
},
|
||||
is_ground_content = true,
|
||||
groups = {tree=1,snappy=1,choppy=2,oddly_breakable_by_hand=1,flammable=2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
paramtype2 = "facedir",
|
||||
on_place = minetest.rotate_node,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { "moretrees:rubber_tree_trunk_empty_sideways" },
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local fdir = node.param2 or 0
|
||||
nfdir = dirs2[fdir+1]
|
||||
minetest.add_node(pos, {name = "moretrees:rubber_tree_trunk_empty", param2 = nfdir})
|
||||
end,
|
||||
})
|
||||
|
||||
-- To get Moretrees to generate its own jungle trees among the default mapgen
|
||||
-- we need our own copy of that node, which moretrees will match against.
|
||||
|
||||
local jungle_tree = moretrees.clone_node("default:jungletree")
|
||||
jungle_tree.drop = jungle_tree.drop or { items = {} }
|
||||
table.insert(jungle_tree.drop.items, { items = {"default:jungletree"}})
|
||||
minetest.register_node("moretrees:jungletree_trunk", jungle_tree)
|
||||
|
||||
-- For compatibility with old nodes, recently-changed nodes, and default nodes
|
||||
|
||||
minetest.register_alias("technic:rubber_tree_full", "moretrees:rubber_tree_trunk")
|
||||
minetest.register_alias("farming_plus:rubber_tree_full", "moretrees:rubber_tree_trunk")
|
||||
minetest.register_alias("farming:rubber_tree_full", "moretrees:rubber_tree_trunk")
|
||||
|
||||
minetest.register_alias("technic:rubber_leaves", "moretrees:rubber_tree_leaves")
|
||||
minetest.register_alias("farming_plus:rubber_leaves", "moretrees:rubber_tree_leaves")
|
||||
minetest.register_alias("farming:rubber_leaves", "moretrees:rubber_tree_leaves")
|
||||
|
||||
minetest.register_alias("technic:rubber_tree_sapling", "moretrees:rubber_tree_sapling")
|
||||
minetest.register_alias("farming_plus:rubber_sapling", "moretrees:rubber_tree_sapling")
|
||||
minetest.register_alias("farming:rubber_sapling", "moretrees:rubber_tree_sapling")
|
||||
|
||||
minetest.register_alias("moretrees:conifer_trunk", "moretrees:fir_trunk")
|
||||
minetest.register_alias("moretrees:conifer_trunk_sideways", "moretrees:fir_trunk_sideways")
|
||||
minetest.register_alias("moretrees:conifer_leaves", "moretrees:fir_leaves")
|
||||
minetest.register_alias("moretrees:conifer_leaves_bright", "moretrees:fir_leaves_bright")
|
||||
minetest.register_alias("moretrees:conifer_sapling", "moretrees:fir_sapling")
|
||||
|
||||
minetest.register_alias("conifers:trunk", "moretrees:fir_trunk")
|
||||
minetest.register_alias("conifers:trunk_reversed", "moretrees:fir_trunk_sideways")
|
||||
minetest.register_alias("conifers:leaves", "moretrees:fir_leaves")
|
||||
minetest.register_alias("conifers:leaves_special", "moretrees:fir_leaves_bright")
|
||||
minetest.register_alias("conifers:sapling", "moretrees:fir_sapling")
|
||||
|
||||
minetest.register_alias("moretrees:jungletree_sapling", "default:junglesapling")
|
||||
minetest.register_alias("moretrees:jungletree_trunk_sideways", "moreblocks:horizontal_jungle_tree")
|
||||
minetest.register_alias("moretrees:jungletree_planks", "default:junglewood")
|
||||
minetest.register_alias("moretrees:jungletree_leaves_green", "default:jungleleaves")
|
||||
|
||||
minetest.register_alias("jungletree:leaves_green", "default:jungleleaves")
|
||||
minetest.register_alias("jungletree:leaves_red", "moretrees:jungletree_leaves_red")
|
||||
minetest.register_alias("jungletree:leaves_yellow", "moretrees:jungletree_leaves_yellow")
|
||||
|
||||
minetest.register_alias("moretrees:acacia_trunk", "default:acacia_tree")
|
||||
minetest.register_alias("moretrees:acacia_planks", "default:acacia_wood")
|
||||
minetest.register_alias("moretrees:acacia_sapling", "default:acacia_sapling")
|
||||
minetest.register_alias("moretrees:acacia_leaves", "default:acacia_leaves")
|
||||
|
||||
minetest.register_alias("moretrees:pine_trunk", "moretrees:cedar_trunk")
|
||||
minetest.register_alias("moretrees:pine_planks", "moretrees:cedar_planks")
|
||||
minetest.register_alias("moretrees:pine_sapling", "moretrees:cedar_sapling")
|
||||
minetest.register_alias("moretrees:pine_leaves", "moretrees:cedar_leaves")
|
||||
minetest.register_alias("moretrees:pine_cone", "moretrees:cedar_cone")
|
||||
minetest.register_alias("moretrees:pine_nuts", "moretrees:cedar_nuts")
|
||||
|
||||
-- Overriding moretrees' palm leaves:
|
||||
minetest.override_item("moretrees:palm_leaves",{walkable = false})
|
|
@ -1,93 +0,0 @@
|
|||
-- sapling growth
|
||||
|
||||
for i in ipairs(moretrees.treelist) do
|
||||
local treename = moretrees.treelist[i][1]
|
||||
local tree_model = treename.."_model"
|
||||
local tree_biome = treename.."_biome"
|
||||
|
||||
if treename ~= "birch" and treename ~= "spruce" and treename ~= "fir" and treename ~= "jungletree" then
|
||||
|
||||
biome_lib:dbg(dump(moretrees[tree_biome].surface))
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = moretrees.sapling_interval,
|
||||
grow_chance = moretrees.sapling_chance,
|
||||
grow_plant = "moretrees:"..treename.."_sapling",
|
||||
grow_nodes = moretrees[tree_biome].surface,
|
||||
grow_function = moretrees[tree_model],
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = 2,
|
||||
grow_chance = 30,
|
||||
grow_plant = "moretrees:"..treename.."_sapling_ongen",
|
||||
grow_nodes = moretrees[tree_biome].surface,
|
||||
grow_function = moretrees[tree_model],
|
||||
})
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = moretrees.sapling_interval,
|
||||
grow_chance = moretrees.sapling_chance,
|
||||
grow_plant = "moretrees:birch_sapling",
|
||||
grow_nodes = moretrees.birch_biome.surface,
|
||||
grow_function = "moretrees.grow_birch"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = 2,
|
||||
grow_chance = 30,
|
||||
grow_plant = "moretrees:birch_sapling_ongen",
|
||||
grow_nodes = moretrees.birch_biome.surface,
|
||||
grow_function = "moretrees.grow_birch"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = moretrees.sapling_interval,
|
||||
grow_chance = moretrees.sapling_chance,
|
||||
grow_plant = "moretrees:spruce_sapling",
|
||||
grow_nodes = moretrees.spruce_biome.surface,
|
||||
grow_function = "moretrees.grow_spruce"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = 2,
|
||||
grow_chance = 30,
|
||||
grow_plant = "moretrees:spruce_sapling_ongen",
|
||||
grow_nodes = moretrees.spruce_biome.surface,
|
||||
grow_function = "moretrees.grow_spruce"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = moretrees.sapling_interval,
|
||||
grow_chance = moretrees.sapling_chance,
|
||||
grow_plant = "moretrees:fir_sapling",
|
||||
grow_nodes = moretrees.fir_biome.surface,
|
||||
grow_function = "moretrees.grow_fir"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = 2,
|
||||
grow_chance = 30,
|
||||
grow_plant = "moretrees:fir_sapling_ongen",
|
||||
grow_nodes = moretrees.fir_biome.surface,
|
||||
grow_function = "moretrees.grow_fir"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = moretrees.sapling_interval,
|
||||
grow_chance = moretrees.sapling_chance,
|
||||
grow_plant = "default:junglesapling",
|
||||
grow_nodes = moretrees.jungletree_biome.surface,
|
||||
grow_function = "moretrees.grow_jungletree"
|
||||
})
|
||||
|
||||
biome_lib:grow_plants({
|
||||
grow_delay = 2,
|
||||
grow_chance = 30,
|
||||
grow_plant = "moretrees:jungletree_sapling_ongen",
|
||||
grow_nodes = moretrees.jungletree_biome.surface,
|
||||
grow_function = "moretrees.grow_jungletree"
|
||||
})
|
||||
|
Before Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 765 B |
Before Width: | Height: | Size: 602 B |
Before Width: | Height: | Size: 351 B |
Before Width: | Height: | Size: 178 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 503 B |
Before Width: | Height: | Size: 464 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 964 B |
Before Width: | Height: | Size: 926 B |
Before Width: | Height: | Size: 170 B |
Before Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 204 B |
Before Width: | Height: | Size: 959 B |
Before Width: | Height: | Size: 811 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 369 B |
Before Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 451 B |
Before Width: | Height: | Size: 648 B |
Before Width: | Height: | Size: 963 B |
Before Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 361 B |
Before Width: | Height: | Size: 161 B |
Before Width: | Height: | Size: 753 B |
Before Width: | Height: | Size: 924 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 730 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 982 B |
Before Width: | Height: | Size: 519 B |
Before Width: | Height: | Size: 599 B |
Before Width: | Height: | Size: 902 B |
Before Width: | Height: | Size: 122 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 400 B |
Before Width: | Height: | Size: 580 B |
Before Width: | Height: | Size: 466 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 151 B |
Before Width: | Height: | Size: 693 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 534 B |
Before Width: | Height: | Size: 435 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 620 B |
Before Width: | Height: | Size: 594 B |
Before Width: | Height: | Size: 1021 B |
Before Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 365 B |
Before Width: | Height: | Size: 151 B |
Before Width: | Height: | Size: 753 B |
Before Width: | Height: | Size: 414 B |
Before Width: | Height: | Size: 536 B |
Before Width: | Height: | Size: 409 B |
Before Width: | Height: | Size: 168 B |
Before Width: | Height: | Size: 620 B |
Before Width: | Height: | Size: 513 B |