Sponge cultivation overhaul.

- Inhibit sponge colony growth beyond a maximum size.  Players
  will have to prune colonies (or, smarter yet, split them) to
  grow more sponges.

- Allow sponge colony transplantation.  Sponges near the "core"
  of a colony (i.e. surrounded by more sponges) are more viable
  and more able to survive the player's crude harvesting.
This commit is contained in:
Aaron Suen 2019-09-23 21:28:48 -04:00
parent d61f5c8c52
commit cc30c80069
7 changed files with 97 additions and 37 deletions

View File

@ -12,6 +12,9 @@ ICEBOX: Low-Priority Ideas
- Release an official beta pack/edition.
- Modpack of experimental features vs. alternate game by branch?
- Flammable/igniter ABM should be reversed, so we scan over few igniters
instead of many flammables?
- Wandering fluids API for concrete, glass?
- AStMs: Active Stack Modifiers.

View File

@ -13,16 +13,8 @@ ISSUES: Bugs, Cleanup and Refinements
learned and things observed about where the game is headed.
- Balance/nerf leaf composting rates.
- Flammable/igniter ABM should be reversed, so we scan over few igniters
instead of many flammables?
- Sponges grow way too much.
- Inhibit growth based on total in area.
- Allow transplantation of colonies.
- When digging, living sponge surrounded by at least
8 other living sponges will dig as living instead
of wet.
- Pack leaf nodes into a compost node?
- Need nearby moisture to compost?
- Lode smelting changes.
- Currently lode smelting is too counterintuitive.

View File

@ -5,20 +5,6 @@ local minetest, nodecore, pairs
local modname = minetest.get_current_modname()
nodecore.register_limited_abm({
label = "Sponge Growth",
interval = 10,
chance = 1000,
limited_max = 100,
nodenames = {"group:water"},
neighbors = {modname .. ":sponge_living"},
action = function(pos)
if minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}).name
~= "nc_terrain:sand" then return end
minetest.set_node(pos, {name = modname .. ":sponge_living"})
end
})
nodecore.register_limited_abm({
label = "Sponge Wettening",
interval = 1,
@ -44,7 +30,7 @@ nodecore.register_limited_abm({
interval = 1,
chance = 100,
limited_max = 100,
nodenames = {modname .. ":sponge_wet"},
nodenames = {modname .. ":sponge_wet", modname .. ":sponge_living"},
action = function(pos)
if minetest.get_node_light({x = pos.x, y = pos.y + 1, z = pos.z}) >= 15 then
minetest.sound_play("nc_api_craft_hiss", {gain = 0.02, pos = pos})
@ -58,7 +44,7 @@ nodecore.register_limited_abm({
interval = 1,
chance = 20,
limited_max = 100,
nodenames = {modname .. ":sponge_wet"},
nodenames = {modname .. ":sponge_wet", modname .. ":sponge_living"},
neighbors = {"group:igniter"},
action = function(pos)
minetest.sound_play("nc_api_craft_hiss", {gain = 0.02, pos = pos})

View File

@ -0,0 +1,87 @@
-- LUALOCALS < ---------------------------------------------------------
local ItemStack, math, minetest, nodecore, pairs, vector
= ItemStack, math, minetest, nodecore, pairs, vector
local math_pow, math_random
= math.pow, math.random
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local growdirs = nodecore.dirs()
local living = modname .. ":sponge_living"
nodecore.register_limited_abm({
label = "Sponge Growth",
interval = 10,
chance = 1000,
limited_max = 100,
nodenames = {living},
neighbors = {"group:water"},
action = function(pos)
local total = 0
if nodecore.scan_flood(pos, 6,
function(p, d)
if d >= 6 then return true end
if minetest.get_node(p).name ~= living then return false end
total = total + 1
if total >= 20 then return true end
end
) then return end
pos = vector.add(pos, growdirs[math_random(1, #growdirs)])
local node = minetest.get_node_or_nil(pos)
local def = node and minetest.registered_nodes[node.name]
local grp = def and def.groups and def.groups.water
if (not grp) or (grp < 1) then return end
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
node = minetest.get_node(below)
if (math_random() > 0.1) or (node.name ~= living) then
def = minetest.registered_nodes[node.name]
grp = def and def.groups and def.groups.sand
if (not grp) or (grp < 1) then return end
end
minetest.set_node(pos, {name = living})
end
})
-- A living sponge can be dug intact, RARELY, and ONLY if surrounded
-- on all sides and edges (X/Z plane) by other living sponges.
local digpos
local old_node_dig = minetest.node_dig
minetest.node_dig = function(pos, node, ...)
if (node and node.name) ~= living then
return old_node_dig(pos, node, ...)
end
local function helper(...)
digpos = nil
return ...
end
digpos = pos
return helper(old_node_dig(pos, node, ...))
end
local old_get_node_drops = minetest.get_node_drops
minetest.get_node_drops = function(...)
local drops = old_get_node_drops(...)
if not digpos then return drops end
local neighbors = #minetest.find_nodes_in_area(
{x = digpos.x - 1, y = digpos.y - 1, z = digpos.z - 1},
{x = digpos.x + 1, y = digpos.y + 1, z = digpos.z + 1},
{living})
if neighbors >= 5 then
local prob = math_pow(2, neighbors - 5) * 0.005
if math_random() <= prob then return drops end
end
drops = drops or {}
for k, v in pairs(drops) do
v = ItemStack(v)
if v:get_name() == living then
v:set_name(modname .. ":sponge_wet")
end
drops[k] = v
end
return drops
end

View File

@ -17,15 +17,6 @@ local c_sponge = minetest.get_content_id(modname .. ":sponge_living")
nodecore.register_mapgen_shared(function(minp, maxp, area, data)
if minp.y > maxy or maxp.y < miny then return end
local function spawn(x, y, z)
nodecore.scan_flood({x = x, y = y, z = z}, 5, function(p)
if math_random() < 0.1 then return true end
local idx = area:index(p.x, p.y + 1, p.z)
if data[idx] ~= c_water then return false end
data[idx] = c_sponge
end)
end
local qty = math_floor(math_random() * (maxp.x - minp.x)
* (maxp.z - minp.z) / (64 * 64))
for _ = 1, qty do
@ -42,7 +33,8 @@ nodecore.register_mapgen_shared(function(minp, maxp, area, data)
if cur == c_water then
waterabove = true
elseif cur == c_sand and waterabove then
spawn(x, y + 1, z)
local i = area:index(x, y + 1, z)
data[i] = c_sponge
break
else
break

View File

@ -8,4 +8,5 @@ nodecore.amcoremod()
include("node")
include("abm")
include("gen")
include("cultivate")
include("squeeze")

View File

@ -46,6 +46,5 @@ minetest.register_node(modname .. ":sponge_living", {
moist = 1,
sponge = 1
},
drop = modname .. ":sponge_wet",
sounds = nodecore.sounds("nc_terrain_swishy")
})