Implement API architecture feedback
|
@ -95,18 +95,18 @@ This mod uses **droplets** to build the dripstone. These are incredibly tiny
|
||||||
drops of liquid that flow down a dripstone. Currently, there are two
|
drops of liquid that flow down a dripstone. Currently, there are two
|
||||||
types in use: `water` and `lava`.
|
types in use: `water` and `lava`.
|
||||||
|
|
||||||
### noordstar_dripstone.register_droplet(droplet)
|
### dripstone.register_droplet(droplet)
|
||||||
|
|
||||||
Every droplet type is a unique string. Different droplets interact uniquely
|
Every droplet type is a unique string. Different droplets interact uniquely
|
||||||
with different dripstones.
|
with different dripstones.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
noordstar_dripstone.register_droplet("magma")
|
dripstone.register_droplet("magma")
|
||||||
noordstar_dripstone.register_droplet("mercury")
|
dripstone.register_droplet("mercury")
|
||||||
noordstar_dripstone.register_droplet("mineral_water")
|
dripstone.register_droplet("mineral_water")
|
||||||
```
|
```
|
||||||
|
|
||||||
### noordstar_dripstone.add_droplet_source(droplet, nodename)
|
### dripstone.register_source(droplet, nodename)
|
||||||
|
|
||||||
In order to let droplets stream down dripstone nodes, you need to define which
|
In order to let droplets stream down dripstone nodes, you need to define which
|
||||||
nodes a full dripstone block can absorb liquid from. Absorbing liquid does not
|
nodes a full dripstone block can absorb liquid from. Absorbing liquid does not
|
||||||
|
@ -118,10 +118,10 @@ However, you don't need to do this! You could use any node, as long as it has a
|
||||||
name.
|
name.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
noordstar_dripstone.add_droplet_source("water", "mymod:swamp_water_source")
|
dripstone.register_source("water", "mymod:swamp_water_source")
|
||||||
```
|
```
|
||||||
|
|
||||||
### noordstar_dripstone.add_droplet_catcher(droplet, oldnodename, newnodename)
|
### dripstone.register_catcher(droplet, oldnodename, newnodename)
|
||||||
|
|
||||||
Similarly, on the other side of the dripstone, you can create a catcher that
|
Similarly, on the other side of the dripstone, you can create a catcher that
|
||||||
can catch any of the liquid drops dripping down. You can use this to create
|
can catch any of the liquid drops dripping down. You can use this to create
|
||||||
|
@ -129,12 +129,12 @@ orchids, or to create other interactions with nodes that might change from a
|
||||||
tiny bit of liquid.
|
tiny bit of liquid.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
noordstar_dripstone.add_droplet_catcher("water", "mymod:cauldron_empty", "mymod:water_cauldron")
|
dripstone.register_catcher("water", "mymod:cauldron_empty", "mymod:water_cauldron")
|
||||||
noordstar_dripstone.add_droplet_catcher("water", "mymod:dirt", "mymod:farmland")
|
dripstone.register_catcher("water", "mymod:dirt", "mymod:farmland")
|
||||||
noordstar_dripstone.add_droplet_catcher("lava", "mymod:precious_orchid", "mymod:dead_bush")
|
dripstone.register_catcher("lava", "mymod:precious_orchid", "mymod:dead_bush")
|
||||||
```
|
```
|
||||||
|
|
||||||
### noordstar_dripstone.register_dripstone(flavor, def)
|
### dripstone.register_dripstone(flavor, def)
|
||||||
|
|
||||||
You can define your own dripstone type. You need to pick a flavor (which you
|
You can define your own dripstone type. You need to pick a flavor (which you
|
||||||
shouldn't namespace) and you need to offer a dripstone definition, which is
|
shouldn't namespace) and you need to offer a dripstone definition, which is
|
||||||
|
@ -176,21 +176,21 @@ defined as follows:
|
||||||
|
|
||||||
For examples, refer to [this mod's init.lua file](init.lua).
|
For examples, refer to [this mod's init.lua file](init.lua).
|
||||||
|
|
||||||
### noordstar_dripstone.size_to_name(flavor, size)
|
### dripstone.size_to_name(flavor, size)
|
||||||
|
|
||||||
Lastly, this function serves as a tool to help you find the node name of a
|
Lastly, this function serves as a tool to help you find the node name of a
|
||||||
dripstone of a given flavor and size. Remember that dripstone size range from 1
|
dripstone of a given flavor and size. Remember that dripstone size range from 1
|
||||||
to 8.
|
to 8.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
noordstar_dripstone.size_to_name("dry", 1)
|
dripstone.size_to_name("dry", 1)
|
||||||
-- Returns "noordstar_dripstone:dry_dripstone_spike"
|
-- Returns "dripstone:dry_dripstone_spike"
|
||||||
|
|
||||||
noordstar_dripstone.size_to_name("lol", 3)
|
dripstone.size_to_name("lol", 3)
|
||||||
-- Returns "noordstar_dripstone:small_lol_dripstone"
|
-- Returns "dripstone:small_lol_dripstone"
|
||||||
|
|
||||||
noordstar_dripstone.size_to_name("cool", 8)
|
dripstone.size_to_name("cool", 8)
|
||||||
-- Returns "noordstar_dripstone:cool_dripstone_block"
|
-- Returns "dripstone:cool_dripstone_block"
|
||||||
```
|
```
|
||||||
|
|
||||||
Note how the function even returns a string if the dripstone type hasn't been
|
Note how the function even returns a string if the dripstone type hasn't been
|
|
@ -1,151 +1,49 @@
|
||||||
noordstar_dripstone = {}
|
-- Nodes that function as cauldrons
|
||||||
|
local CAULDRONS = {}
|
||||||
|
|
||||||
-- Internal values that cannot be changed by other mods (directly).
|
-- How many nodes downwards a droplet is able to drop from a stalactite
|
||||||
local internal = {
|
-- before the droplet evaporates.
|
||||||
-- These values are not meant to be changed during runtime.
|
local DROP_DOWN_REACH = 50
|
||||||
constant = {
|
|
||||||
-- How many nodes downwards a droplet is able to drop from a stalactite
|
|
||||||
-- before the droplet evaporates.
|
|
||||||
drop_down_reach = 50,
|
|
||||||
|
|
||||||
-- The number of seconds it takes for a dripstone node to grow 1 unit
|
-- The number of seconds it takes for a dripstone node to grow 1 unit
|
||||||
-- (NOTE: Not one node size! One unit, which quadratically increases
|
-- (NOTE: Not one node size! One unit, which quadratically increases
|
||||||
-- per node size.)
|
-- per node size.)
|
||||||
growth_factor = 3,
|
local GROWTH_FACTOR = 3
|
||||||
|
|
||||||
-- This mod's name.
|
-- This mod's name.
|
||||||
modname = minetest.get_current_modname(),
|
local MODNAME = minetest.get_current_modname()
|
||||||
|
|
||||||
-- The number of samples that each ABM should execute.
|
-- The number of samples that each ABM should execute.
|
||||||
-- Make sure this is a whole number and less than speed_factor.
|
-- Make sure this is a whole number and less than speed_factor.
|
||||||
samples_per_interval = 30,
|
local SAMPLES_PER_INTERVAL = 30
|
||||||
|
|
||||||
-- Factor deciding this mod's relative speed.
|
-- Nodes that provide droplets
|
||||||
-- Set this value to 1 if you wish to debug and let the dripstone
|
local SOURCES = {}
|
||||||
-- change rapidly.
|
|
||||||
-- Rule of thumb: with a setting of 60, it takes a lava farm about 30
|
|
||||||
-- minutes to fill a cauldron with lava.
|
|
||||||
speed_factor = 60,
|
|
||||||
|
|
||||||
-- Names of the various dripstone widths
|
-- Factor deciding this mod's relative speed.
|
||||||
width_names = {
|
-- Set this value to 1 if you wish to debug and let the dripstone
|
||||||
"spike", "tiny", "small", "medium",
|
-- change rapidly.
|
||||||
"great", "large", "huge", "block",
|
-- Rule of thumb: with a setting of 60, it takes a lava farm about 30
|
||||||
},
|
-- minutes to fill a cauldron with lava.
|
||||||
},
|
local SPEED_FACTOR = 60
|
||||||
|
|
||||||
-- Nodes that function as cauldrons
|
-- Nodes that allow a droplet to trickle down if it is directly below a
|
||||||
cauldrons = {},
|
|
||||||
|
|
||||||
-- Nodes that provide droplets
|
|
||||||
sources = {},
|
|
||||||
|
|
||||||
-- Nodes that allow a droplet to trickle down if it is directly below a
|
|
||||||
-- node that passes down that droplet.
|
-- node that passes down that droplet.
|
||||||
tricklers = {},
|
local TRICKLERS = {}
|
||||||
|
|
||||||
|
-- Names of the various dripstone widths
|
||||||
|
local WIDTH_NAMES = {
|
||||||
|
"spike", "tiny", "small", "medium", "great", "large", "huge", "block",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
--------------------------- PUBLIC API --------------------------------
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- Register a node that can catch a droplet from a dripstone stalactite.
|
|
||||||
function noordstar_dripstone.add_droplet_catcher(droplet, oldnodename, newnodename)
|
|
||||||
return internal.add_droplet_catcher(droplet, oldnodename, newnodename)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Register a new source node that can provide droplets to dripstone blocks.
|
|
||||||
function noordstar_dripstone.add_droplet_source(droplet, nodename)
|
|
||||||
return internal.add_droplet_source(droplet, nodename)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Register a new dripstone type.
|
|
||||||
--
|
|
||||||
-- {
|
|
||||||
-- -- What item is dropped when the dripstone is broken.
|
|
||||||
-- -- When left nil, the spike of the dripstone type is dropped.
|
|
||||||
-- drop = "dry"
|
|
||||||
--
|
|
||||||
-- -- What flavor to become when using liquid to grow.
|
|
||||||
-- -- Leave to nil when unable to grow.
|
|
||||||
-- grow_to = "dry"
|
|
||||||
--
|
|
||||||
-- -- When receiving a droplet of a given type, transform into a different
|
|
||||||
-- -- dripstone type. When a droplet is unspecified, the block cannot
|
|
||||||
-- -- receive the droplet.
|
|
||||||
-- on_droplet_receive = {
|
|
||||||
-- water = "watered",
|
|
||||||
-- lava = "molten",
|
|
||||||
-- }
|
|
||||||
--
|
|
||||||
-- -- Sounds that the dripstone makes
|
|
||||||
-- sounds = <standard sound definition for a node>
|
|
||||||
--
|
|
||||||
-- -- Node tiles for layout
|
|
||||||
-- tiles = <node tile layout>
|
|
||||||
--
|
|
||||||
-- -- Droplet type that the dripstone flavor can pass down.
|
|
||||||
-- -- When the droplet is passed down, the dripstone converts to the
|
|
||||||
-- -- "grow_to" type
|
|
||||||
-- trickle_down = "water"
|
|
||||||
--
|
|
||||||
-- -- Speed of how often a droplet trickles down.
|
|
||||||
-- trickle_speed = 5
|
|
||||||
-- }
|
|
||||||
function noordstar_dripstone.register_dripstone(flavor, def)
|
|
||||||
return internal.register_dripstone_flavor(flavor, def)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Register a new droplet type that can be absorbed and passed on by dripstone.
|
|
||||||
function noordstar_dripstone.register_droplet(droplet)
|
|
||||||
if internal.cauldrons[droplet] == nil then
|
|
||||||
internal.cauldrons[droplet] = {}
|
|
||||||
end
|
|
||||||
if internal.sources[droplet] == nil then
|
|
||||||
internal.sources[droplet] = {}
|
|
||||||
end
|
|
||||||
if internal.tricklers[droplet] == nil then
|
|
||||||
internal.tricklers[droplet] = {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Get a dripstone's node name based on its flavor and size.
|
|
||||||
function noordstar_dripstone.size_to_name(flavor, size)
|
|
||||||
return internal.size_to_name(flavor, size)
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- Add a droplet catcher, which is a node that allows a stalactite spike to
|
-- Internal table that lets us define functions without directly exposing them.
|
||||||
-- change the name using a droplet.
|
local internal = {}
|
||||||
function internal.add_droplet_catcher(droplet, oldnodename, newnodename)
|
|
||||||
return internal.register_cauldron(droplet, oldnodename, newnodename)
|
|
||||||
end
|
|
||||||
|
|
||||||
function internal.add_droplet_source(droplet, nodename)
|
|
||||||
if internal.sources[droplet] == nil then
|
|
||||||
internal.uninitialized_droplet_error(droplet)
|
|
||||||
end
|
|
||||||
table.insert(internal.sources[droplet], nodename)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add a droplet trickler, which is a dripstone node that allows a droplet to
|
|
||||||
-- be trickled down from the node directly above it.
|
|
||||||
-- Running this function overrides previous values.
|
|
||||||
function internal.add_droplet_trickler(droplet, oldnodename, newnodename)
|
|
||||||
if internal.tricklers[droplet] == nil then
|
|
||||||
internal.uninitialized_droplet_error(droplet)
|
|
||||||
end
|
|
||||||
|
|
||||||
internal.tricklers[droplet][oldnodename] = newnodename
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Capitalize a string
|
-- Capitalize a string
|
||||||
function internal.capitalize(str)
|
function internal.capitalize(str)
|
||||||
|
@ -161,7 +59,7 @@ function internal.drawtype_of_size(size)
|
||||||
end
|
end
|
||||||
|
|
||||||
function internal.hit_with_droplet(pos, node, droplet, spikename)
|
function internal.hit_with_droplet(pos, node, droplet, spikename)
|
||||||
local m = internal.cauldrons[droplet] or {}
|
local m = CAULDRONS[droplet] or {}
|
||||||
|
|
||||||
if m[node.name] == nil then
|
if m[node.name] == nil then
|
||||||
-- Not a cauldron! Therefore we place a spike on top.
|
-- Not a cauldron! Therefore we place a spike on top.
|
||||||
|
@ -177,11 +75,7 @@ end
|
||||||
|
|
||||||
-- Determine whether this mod considers a node an air node.
|
-- Determine whether this mod considers a node an air node.
|
||||||
function internal.is_air(nodename)
|
function internal.is_air(nodename)
|
||||||
if nodename == "air" then
|
return (nodename == "air") or (minetest.get_item_group(nodename, "air") ~= 0)
|
||||||
return true
|
|
||||||
else
|
|
||||||
return minetest.get_item_group(nodename, "air") ~= 0
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create a node box for any given dripstone size.
|
-- Create a node box for any given dripstone size.
|
||||||
|
@ -202,14 +96,14 @@ end
|
||||||
function internal.register_absorb_abm(droplet, oldnodename, newnodename)
|
function internal.register_absorb_abm(droplet, oldnodename, newnodename)
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = { oldnodename },
|
nodenames = { oldnodename },
|
||||||
interval = internal.constant.speed_factor / internal.constant.samples_per_interval,
|
interval = SPEED_FACTOR / SAMPLES_PER_INTERVAL,
|
||||||
chance = internal.constant.samples_per_interval,
|
chance = SAMPLES_PER_INTERVAL,
|
||||||
catch_up = true,
|
catch_up = true,
|
||||||
action = function (pos, node, aoc, aocw)
|
action = function(pos, node)
|
||||||
local pos_above = vector.offset(pos, 0, 1, 0)
|
local pos_above = vector.offset(pos, 0, 1, 0)
|
||||||
local node_above = minetest.get_node(pos_above)
|
local node_above = minetest.get_node(pos_above)
|
||||||
|
|
||||||
for _, source in pairs(internal.sources[droplet] or {}) do
|
for _, source in pairs(SOURCES[droplet] or {}) do
|
||||||
if node_above.name == source then
|
if node_above.name == source then
|
||||||
node.name = newnodename
|
node.name = newnodename
|
||||||
minetest.set_node(pos, node)
|
minetest.set_node(pos, node)
|
||||||
|
@ -220,14 +114,6 @@ function internal.register_absorb_abm(droplet, oldnodename, newnodename)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function internal.register_cauldron(droplet, oldnodename, newnodename)
|
|
||||||
if internal.cauldrons[droplet] == nil then
|
|
||||||
internal.uninitialized_droplet_error(droplet)
|
|
||||||
end
|
|
||||||
|
|
||||||
internal.cauldrons[droplet][oldnodename] = newnodename
|
|
||||||
end
|
|
||||||
|
|
||||||
function internal.register_dripstone_craft(newnodename, oldnodename, spikename)
|
function internal.register_dripstone_craft(newnodename, oldnodename, spikename)
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = newnodename,
|
output = newnodename,
|
||||||
|
@ -268,7 +154,7 @@ function internal.register_dripstone_flavor(flavor, def)
|
||||||
-- Allow dripstone nodes to trickle down droplets
|
-- Allow dripstone nodes to trickle down droplets
|
||||||
for droplet, new_flavor in pairs(on_droplet_receive) do
|
for droplet, new_flavor in pairs(on_droplet_receive) do
|
||||||
for width = 1, 8, 1 do
|
for width = 1, 8, 1 do
|
||||||
internal.add_droplet_trickler(
|
internal.register_trickler(
|
||||||
droplet,
|
droplet,
|
||||||
internal.size_to_name(flavor, width),
|
internal.size_to_name(flavor, width),
|
||||||
internal.size_to_name(new_flavor, width)
|
internal.size_to_name(new_flavor, width)
|
||||||
|
@ -276,9 +162,28 @@ function internal.register_dripstone_flavor(flavor, def)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Allow spike stalagmites to catch droplets
|
-- Makes dripstone stalagmite spikes delete droplets.
|
||||||
|
-- Without this, stalactites remain very thick and short while
|
||||||
|
-- stalagmites become absurdly long and thin.
|
||||||
|
-- A watered stalagmite can't accept a water droplet and the stalagmite
|
||||||
|
-- therefore grows one per droplet. To mitigate this, a watered spike
|
||||||
|
-- can still act as a water droplet cauldron without changing.
|
||||||
|
-- This way, no new droplets are passed on if the stalagmite is already
|
||||||
|
-- full, and the structure simply waits for a dripstone node to grow.
|
||||||
|
-- This behaviour is designed to be easy to override. (For example: if
|
||||||
|
-- you want a HEAVY watered dripstone type that holds 2 droplets.)
|
||||||
|
if trickl then
|
||||||
|
internal.register_droplet_catcher(
|
||||||
|
trickl,
|
||||||
|
internal.size_to_name(flavor, 1),
|
||||||
|
internal.size_to_name(flavor, 1)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Allow spike stalagmites to catch droplets.
|
||||||
|
-- This feature can override the former safeguard.
|
||||||
for droplet, new_flavor in pairs(on_droplet_receive) do
|
for droplet, new_flavor in pairs(on_droplet_receive) do
|
||||||
internal.register_cauldron(
|
internal.register_droplet_catcher(
|
||||||
droplet,
|
droplet,
|
||||||
internal.size_to_name(flavor, 1),
|
internal.size_to_name(flavor, 1),
|
||||||
internal.size_to_name(new_flavor, 1)
|
internal.size_to_name(new_flavor, 1)
|
||||||
|
@ -327,22 +232,6 @@ function internal.register_dripstone_flavor(flavor, def)
|
||||||
internal.size_to_name(dry_up, 1),
|
internal.size_to_name(dry_up, 1),
|
||||||
trickle_speed
|
trickle_speed
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Makes dripstone stalagmite spikes delete droplets.
|
|
||||||
-- Without this, stalactites remain very thick and short while
|
|
||||||
-- stalagmites become absurdly long and thin.
|
|
||||||
-- A watered stalagmite can't accept a water droplet and the stalagmite
|
|
||||||
-- therefore grows one per droplet. To mitigate this, a watered spike
|
|
||||||
-- can still act as a water droplet cauldron without changing.
|
|
||||||
-- This way, no new droplets are passed on if the stalagmite is already
|
|
||||||
-- full, and the structure simply waits for a dripstone node to grow.
|
|
||||||
-- This behaviour is designed to be easy to override. (For example: if
|
|
||||||
-- you want a HEAVY watered dripstone type that holds 2 droplets.)
|
|
||||||
internal.add_droplet_catcher(
|
|
||||||
trickl,
|
|
||||||
internal.size_to_name(flavor, 1),
|
|
||||||
internal.size_to_name(flavor, 1)
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -351,25 +240,29 @@ function internal.register_dripstone_node(flavor, size, tiles, sounds, drop)
|
||||||
description = internal.size_to_description(flavor, size),
|
description = internal.size_to_description(flavor, size),
|
||||||
tiles = tiles,
|
tiles = tiles,
|
||||||
groups = {
|
groups = {
|
||||||
pickaxey=2,
|
pickaxey = 2,
|
||||||
material_stone=1,
|
material_stone = 1,
|
||||||
fall_damage_add_percent = math.max(4 - size, 0) / 4 * 100
|
fall_damage_add_percent = math.max(4 - size, 0) / 4 * 100
|
||||||
},
|
},
|
||||||
is_ground_content = true,
|
is_ground_content = true,
|
||||||
drop = {
|
drop = {
|
||||||
max_items = math.floor((size + 1) / 2),
|
max_items = math.floor((size + 1) / 2),
|
||||||
items = {
|
items = {
|
||||||
{ rarity = 1
|
{
|
||||||
, items = { drop }
|
rarity = 1,
|
||||||
|
items = { drop },
|
||||||
},
|
},
|
||||||
{ rarity = 2
|
{
|
||||||
, items = { drop }
|
rarity = 2,
|
||||||
|
items = { drop },
|
||||||
},
|
},
|
||||||
{ rarity = 4
|
{
|
||||||
, items = { drop }
|
rarity = 4,
|
||||||
|
items = { drop },
|
||||||
},
|
},
|
||||||
{ rarity = 4
|
{
|
||||||
, items = { drop }
|
rarity = 4,
|
||||||
|
items = { drop },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -387,10 +280,10 @@ end
|
||||||
function internal.register_drop_down_abm(droplet, spikename, dryspikename, trickle_speed)
|
function internal.register_drop_down_abm(droplet, spikename, dryspikename, trickle_speed)
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = { spikename },
|
nodenames = { spikename },
|
||||||
interval = trickle_speed * internal.constant.speed_factor / internal.constant.samples_per_interval,
|
interval = trickle_speed * SPEED_FACTOR / SAMPLES_PER_INTERVAL,
|
||||||
chance = internal.constant.samples_per_interval,
|
chance = SAMPLES_PER_INTERVAL,
|
||||||
catch_up = true,
|
catch_up = true,
|
||||||
action = function (pos, node, aoc, aocw)
|
action = function(pos, node)
|
||||||
local pos_below = vector.offset(pos, 0, -1, 0)
|
local pos_below = vector.offset(pos, 0, -1, 0)
|
||||||
local node_below = minetest.get_node(pos_below)
|
local node_below = minetest.get_node(pos_below)
|
||||||
|
|
||||||
|
@ -399,7 +292,7 @@ function internal.register_drop_down_abm(droplet, spikename, dryspikename, trick
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
for dy = 2, internal.constant.drop_down_reach, 1 do
|
for dy = 2, DROP_DOWN_REACH, 1 do
|
||||||
pos_below = vector.offset(pos, 0, -dy, 0)
|
pos_below = vector.offset(pos, 0, -dy, 0)
|
||||||
node_below = minetest.get_node(pos_below)
|
node_below = minetest.get_node(pos_below)
|
||||||
|
|
||||||
|
@ -421,14 +314,48 @@ function internal.register_drop_down_abm(droplet, spikename, dryspikename, trick
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Register a new droplet type that can be absorbed and passed on by dripstone.
|
||||||
|
function internal.register_droplet(droplet)
|
||||||
|
if CAULDRONS[droplet] == nil then
|
||||||
|
CAULDRONS[droplet] = {}
|
||||||
|
end
|
||||||
|
if SOURCES[droplet] == nil then
|
||||||
|
SOURCES[droplet] = {}
|
||||||
|
end
|
||||||
|
if TRICKLERS[droplet] == nil then
|
||||||
|
TRICKLERS[droplet] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add a droplet catcher, which is a node that allows a stalactite spike to
|
||||||
|
-- change the name using a droplet.
|
||||||
|
function internal.register_droplet_catcher(droplet, oldnodename, newnodename)
|
||||||
|
if CAULDRONS[droplet] == nil then
|
||||||
|
internal.uninitialized_droplet_error(droplet)
|
||||||
|
end
|
||||||
|
|
||||||
|
CAULDRONS[droplet][oldnodename] = newnodename
|
||||||
|
end
|
||||||
|
|
||||||
|
function internal.register_droplet_source(droplet, nodename)
|
||||||
|
if SOURCES[droplet] == nil then
|
||||||
|
internal.uninitialized_droplet_error(droplet)
|
||||||
|
end
|
||||||
|
table.insert(SOURCES[droplet], nodename)
|
||||||
|
|
||||||
|
-- If the node can emit an infinite number of droplets,
|
||||||
|
-- it can also absorb an infinite number of droplets.
|
||||||
|
internal.register_droplet_catcher(droplet, nodename, nodename)
|
||||||
|
end
|
||||||
|
|
||||||
function internal.register_grow_abm(oldnodename, newnodename, width)
|
function internal.register_grow_abm(oldnodename, newnodename, width)
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = { oldnodename },
|
nodenames = { oldnodename },
|
||||||
-- 2(w + 1) * 2(w + 1) - 2w * 2w = 8w + 4
|
-- 2(w + 1) * 2(w + 1) - 2w * 2w = 8w + 4
|
||||||
interval = (8 * width + 4) * internal.constant.speed_factor * internal.constant.growth_factor / internal.constant.samples_per_interval,
|
interval = (8 * width + 4) * SPEED_FACTOR * GROWTH_FACTOR / SAMPLES_PER_INTERVAL,
|
||||||
chance = internal.constant.samples_per_interval,
|
chance = SAMPLES_PER_INTERVAL,
|
||||||
catch_up = true,
|
catch_up = true,
|
||||||
action = function (pos, node, aoc, aocw)
|
action = function(pos, node)
|
||||||
node.name = newnodename
|
node.name = newnodename
|
||||||
minetest.set_node(pos, node)
|
minetest.set_node(pos, node)
|
||||||
end
|
end
|
||||||
|
@ -438,14 +365,14 @@ end
|
||||||
function internal.register_trickle_down_abm(droplet, width, old_source, new_source, dry_up, trickle_speed)
|
function internal.register_trickle_down_abm(droplet, width, old_source, new_source, dry_up, trickle_speed)
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = { old_source },
|
nodenames = { old_source },
|
||||||
interval = trickle_speed * internal.constant.speed_factor / internal.constant.samples_per_interval,
|
interval = trickle_speed * SPEED_FACTOR / SAMPLES_PER_INTERVAL,
|
||||||
chance = internal.constant.samples_per_interval,
|
chance = SAMPLES_PER_INTERVAL,
|
||||||
catch_up = true,
|
catch_up = true,
|
||||||
action = function (pos, node, aoc, aocw)
|
action = function(pos, node)
|
||||||
local pos_below = vector.offset(pos, 0, -1, 0)
|
local pos_below = vector.offset(pos, 0, -1, 0)
|
||||||
local node_below = minetest.get_node(pos_below)
|
local node_below = minetest.get_node(pos_below)
|
||||||
|
|
||||||
local m = internal.tricklers[droplet] or {}
|
local m = TRICKLERS[droplet] or {}
|
||||||
|
|
||||||
if m[node_below.name] ~= nil then
|
if m[node_below.name] ~= nil then
|
||||||
-- Trickler found below!
|
-- Trickler found below!
|
||||||
|
@ -464,8 +391,19 @@ function internal.register_trickle_down_abm(droplet, width, old_source, new_sour
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add a droplet trickler, which is a dripstone node that allows a droplet to
|
||||||
|
-- be trickled down from the node directly above it.
|
||||||
|
-- Running this function overrides previous values.
|
||||||
|
function internal.register_trickler(droplet, oldnodename, newnodename)
|
||||||
|
if TRICKLERS[droplet] == nil then
|
||||||
|
internal.uninitialized_droplet_error(droplet)
|
||||||
|
end
|
||||||
|
|
||||||
|
TRICKLERS[droplet][oldnodename] = newnodename
|
||||||
|
end
|
||||||
|
|
||||||
function internal.size_to_description(flavor, size)
|
function internal.size_to_description(flavor, size)
|
||||||
local width_name = internal.constant.width_names[size]
|
local width_name = WIDTH_NAMES[size]
|
||||||
|
|
||||||
if size == 1 or size == 8 then
|
if size == 1 or size == 8 then
|
||||||
return internal.capitalize(flavor) .. " dripstone " .. width_name
|
return internal.capitalize(flavor) .. " dripstone " .. width_name
|
||||||
|
@ -475,8 +413,8 @@ function internal.size_to_description(flavor, size)
|
||||||
end
|
end
|
||||||
|
|
||||||
function internal.size_to_name(flavor, size)
|
function internal.size_to_name(flavor, size)
|
||||||
local namespace = internal.constant.modname .. ":"
|
local namespace = MODNAME .. ":"
|
||||||
local width_name = internal.constant.width_names[size]
|
local width_name = WIDTH_NAMES[size]
|
||||||
|
|
||||||
if size == 1 or size == 8 then
|
if size == 1 or size == 8 then
|
||||||
return namespace .. flavor .. "_dripstone_" .. width_name
|
return namespace .. flavor .. "_dripstone_" .. width_name
|
||||||
|
@ -490,3 +428,26 @@ function internal.uninitialized_droplet_error(droplet)
|
||||||
"Droplet " .. droplet .. " has not been initialized yet!"
|
"Droplet " .. droplet .. " has not been initialized yet!"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
--------------------------- PUBLIC API --------------------------------
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
dripstone = {
|
||||||
|
-- Register a node that can catch a droplet from a dripstone stalactite.
|
||||||
|
register_catcher = internal.register_droplet_catcher,
|
||||||
|
|
||||||
|
-- Register a new dripstone type.
|
||||||
|
register_dripstone = internal.register_dripstone_flavor,
|
||||||
|
|
||||||
|
-- Register a new droplet type that can be absorbed and passed on by dripstone.
|
||||||
|
register_droplet = internal.register_droplet,
|
||||||
|
|
||||||
|
-- Register a source node that can provide droplets to dripstone blocks.
|
||||||
|
register_source = internal.register_droplet_source,
|
||||||
|
|
||||||
|
-- Get a dripstone's node name based on its flavor and size.
|
||||||
|
size_to_name = internal.size_to_name,
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
-- Load dripstone API
|
||||||
|
|
||||||
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
|
local function load(name)
|
||||||
|
dofile(modpath.."/"..name..".lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
load("api")
|
||||||
|
|
||||||
|
-- Choose dripstone sounds
|
||||||
|
local dripstone_sounds
|
||||||
|
if minetest.get_modpath("mcl_sounds") then
|
||||||
|
dripstone_sounds = mcl_sounds.node_sound_stone_defaults()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Register droplet types
|
||||||
|
dripstone.register_droplet("water")
|
||||||
|
dripstone.register_droplet("lava")
|
||||||
|
|
||||||
|
-- Register dripstone types
|
||||||
|
dripstone.register_dripstone("dry", {
|
||||||
|
sounds = dripstone_sounds,
|
||||||
|
tiles = {
|
||||||
|
"dripstone_dripstone_top.png",
|
||||||
|
"dripstone_dripstone_top.png",
|
||||||
|
"dripstone_dripstone_side.png",
|
||||||
|
},
|
||||||
|
on_droplet_receive = {
|
||||||
|
water = "watered",
|
||||||
|
lava = "molten",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
dripstone.register_dripstone("watered", {
|
||||||
|
drop = dripstone.size_to_name("dry", 1),
|
||||||
|
grow_to = "dry",
|
||||||
|
on_droplet_receive = {
|
||||||
|
lava = "hardened",
|
||||||
|
},
|
||||||
|
sounds = dripstone_sounds,
|
||||||
|
tiles = {
|
||||||
|
"dripstone_watered_dripstone_top.png",
|
||||||
|
"dripstone_watered_dripstone_top.png",
|
||||||
|
"dripstone_watered_dripstone_side.png",
|
||||||
|
},
|
||||||
|
trickle_down = "water",
|
||||||
|
})
|
||||||
|
dripstone.register_dripstone("molten", {
|
||||||
|
drop = dripstone.size_to_name("dry", 1),
|
||||||
|
grow_to = "dry",
|
||||||
|
on_droplet_receive = {
|
||||||
|
water = "hardened",
|
||||||
|
},
|
||||||
|
sounds = dripstone_sounds,
|
||||||
|
tiles = {
|
||||||
|
"dripstone_molten_dripstone_top.png",
|
||||||
|
"dripstone_molten_dripstone_top.png",
|
||||||
|
"dripstone_molten_dripstone_side.png",
|
||||||
|
},
|
||||||
|
trickle_down = "lava",
|
||||||
|
trickle_speed = 6,
|
||||||
|
})
|
||||||
|
dripstone.register_dripstone("hardened", {
|
||||||
|
sounds = dripstone_sounds,
|
||||||
|
tiles = {
|
||||||
|
"dripstone_hardened_dripstone_top.png",
|
||||||
|
"dripstone_hardened_dripstone_top.png",
|
||||||
|
"dripstone_hardened_dripstone_side.png",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Register droplet sources above dripstone blocks
|
||||||
|
|
||||||
|
if minetest.get_modpath("mcl_core") then
|
||||||
|
dripstone.register_source("water", "mcl_core:water_source")
|
||||||
|
dripstone.register_source("lava", "mcl_core:lava_source")
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.get_modpath("mclx_core") then
|
||||||
|
dripstone.register_source("water", "mclx_core:river_water_source")
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
name=dripstone
|
||||||
|
description=Add stalactites and stalagmites to your game.
|
||||||
|
author=Noordstar
|
||||||
|
title=Dripstone
|
||||||
|
optional_depends=mcl_core,mcl_sounds,mclx_core
|
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 175 B |
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 178 B After Width: | Height: | Size: 178 B |
Before Width: | Height: | Size: 525 B After Width: | Height: | Size: 525 B |
Before Width: | Height: | Size: 177 B After Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 543 B After Width: | Height: | Size: 543 B |
|
@ -163,20 +163,18 @@ minetest.register_globalstep(function(dtime)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Register cauldrons to pick up dripstone droplets
|
-- Register cauldrons to pick up dripstone droplets
|
||||||
if minetest.get_modpath("noordstar_dripstone") then
|
if minetest.get_modpath("dripstone") then
|
||||||
local add_cauldron = noordstar_dripstone.add_droplet_catcher
|
dripstone.register_catcher("lava", "mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1_lava")
|
||||||
|
dripstone.register_catcher("lava", "mcl_cauldrons:cauldron_1_lava", "mcl_cauldrons:cauldron_2_lava")
|
||||||
|
dripstone.register_catcher("lava", "mcl_cauldrons:cauldron_2_lava", "mcl_cauldrons:cauldron_3_lava")
|
||||||
|
|
||||||
add_cauldron("lava", "mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1_lava")
|
dripstone.register_catcher("water", "mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1")
|
||||||
add_cauldron("lava", "mcl_cauldrons:cauldron_1_lava", "mcl_cauldrons:cauldron_2_lava")
|
dripstone.register_catcher("water", "mcl_cauldrons:cauldron_1", "mcl_cauldrons:cauldron_2")
|
||||||
add_cauldron("lava", "mcl_cauldrons:cauldron_2_lava", "mcl_cauldrons:cauldron_3_lava")
|
dripstone.register_catcher("water", "mcl_cauldrons:cauldron_2", "mcl_cauldrons:cauldron_3")
|
||||||
|
|
||||||
add_cauldron("water", "mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1")
|
|
||||||
add_cauldron("water", "mcl_cauldrons:cauldron_1", "mcl_cauldrons:cauldron_2")
|
|
||||||
add_cauldron("water", "mcl_cauldrons:cauldron_2", "mcl_cauldrons:cauldron_3")
|
|
||||||
|
|
||||||
if minetest.get_modpath("mclx_core") then
|
if minetest.get_modpath("mclx_core") then
|
||||||
add_cauldron("water", "mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1r")
|
dripstone.register_catcher("water", "mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1r")
|
||||||
add_cauldron("water", "mcl_cauldrons:cauldron_1r", "mcl_cauldrons:cauldron_2r")
|
dripstone.register_catcher("water", "mcl_cauldrons:cauldron_1r", "mcl_cauldrons:cauldron_2r")
|
||||||
add_cauldron("water", "mcl_cauldrons:cauldron_2r", "mcl_cauldrons:cauldron_3r")
|
dripstone.register_catcher("water", "mcl_cauldrons:cauldron_2r", "mcl_cauldrons:cauldron_3r")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
name = mcl_cauldrons
|
name = mcl_cauldrons
|
||||||
depends = mcl_core, mcl_sounds
|
depends = mcl_core, mcl_sounds
|
||||||
optional_depends = mclx_core, doc, mcl_burning, noordstar_dripstone
|
optional_depends = mclx_core, doc, mcl_burning, dripstone
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
-- Load dripstone API
|
|
||||||
|
|
||||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
|
|
||||||
local function load(name)
|
|
||||||
dofile(modpath.."/"..name..".lua")
|
|
||||||
end
|
|
||||||
|
|
||||||
load("api")
|
|
||||||
|
|
||||||
-- Choose dripstone sounds
|
|
||||||
local dripstone_sounds
|
|
||||||
if minetest.get_modpath("mcl_sounds") then
|
|
||||||
dripstone_sounds = mcl_sounds.node_sound_stone_defaults()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Register droplet types
|
|
||||||
noordstar_dripstone.register_droplet("water")
|
|
||||||
noordstar_dripstone.register_droplet("lava")
|
|
||||||
|
|
||||||
-- Register dripstone types
|
|
||||||
noordstar_dripstone.register_dripstone("dry", {
|
|
||||||
sounds = dripstone_sounds,
|
|
||||||
tiles = {
|
|
||||||
"noordstar_dripstone_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_dripstone_side.png",
|
|
||||||
},
|
|
||||||
on_droplet_receive = {
|
|
||||||
water = "watered",
|
|
||||||
lava = "molten",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
noordstar_dripstone.register_dripstone("watered", {
|
|
||||||
drop = noordstar_dripstone.size_to_name("dry", 1),
|
|
||||||
grow_to = "dry",
|
|
||||||
on_droplet_receive = {
|
|
||||||
lava = "hardened",
|
|
||||||
},
|
|
||||||
sounds = dripstone_sounds,
|
|
||||||
tiles = {
|
|
||||||
"noordstar_dripstone_watered_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_watered_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_watered_dripstone_side.png",
|
|
||||||
},
|
|
||||||
trickle_down = "water",
|
|
||||||
})
|
|
||||||
noordstar_dripstone.register_dripstone("molten", {
|
|
||||||
drop = noordstar_dripstone.size_to_name("dry", 1),
|
|
||||||
grow_to = "dry",
|
|
||||||
on_droplet_receive = {
|
|
||||||
water = "hardened",
|
|
||||||
},
|
|
||||||
sounds = dripstone_sounds,
|
|
||||||
tiles = {
|
|
||||||
"noordstar_dripstone_molten_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_molten_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_molten_dripstone_side.png",
|
|
||||||
},
|
|
||||||
trickle_down = "lava",
|
|
||||||
trickle_speed = 6,
|
|
||||||
})
|
|
||||||
noordstar_dripstone.register_dripstone("hardened", {
|
|
||||||
sounds = dripstone_sounds,
|
|
||||||
tiles = {
|
|
||||||
"noordstar_dripstone_hardened_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_hardened_dripstone_top.png",
|
|
||||||
"noordstar_dripstone_hardened_dripstone_side.png",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Register droplet sources above dripstone blocks
|
|
||||||
|
|
||||||
if minetest.get_modpath("default") then
|
|
||||||
noordstar_dripstone.add_droplet_source("water", "default:river_water_source")
|
|
||||||
noordstar_dripstone.add_droplet_source("water", "default:water_source")
|
|
||||||
noordstar_dripstone.add_droplet_source("lava", "default:lava_source")
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_modpath("mcl_core") then
|
|
||||||
noordstar_dripstone.add_droplet_source("water", "mcl_core:water_source")
|
|
||||||
noordstar_dripstone.add_droplet_source("lava", "mcl_core:lava_source")
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_modpath("mclx_core") then
|
|
||||||
noordstar_dripstone.add_droplet_source("water", "mclx_core:river_water_source")
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
name=noordstar_dripstone
|
|
||||||
description=Add stalactites and stalagmites to your game.
|
|
||||||
author=Noordstar
|
|
||||||
title=Noordstar Dripstone
|
|
||||||
optional_depends=default,mcl_core,mcl_sounds
|
|