180 lines
7.0 KiB
Lua
180 lines
7.0 KiB
Lua
-- liblevelup mod for Minetest
|
|
-- Copyright © 2017-2019 Alex Yst <mailto:copyright@y.st>
|
|
|
|
-- This program is free software; you can redistribute it and/or
|
|
-- modify it under the terms of the GNU Lesser General Public
|
|
-- License as published by the Free Software Foundation; either
|
|
-- version 2.1 of the License, or (at your option) any later version.
|
|
|
|
-- This software is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
-- Lesser General Public License for more details.
|
|
|
|
-- You should have received a copy of the GNU Lesser General Public
|
|
-- License along with this program. If not, see
|
|
-- <https://www.gnu.org./licenses/>.
|
|
|
|
dofile(minetest.get_modpath("liblevelup").."/API.lua")
|
|
|
|
-- This constant tells other mods that depend on this one that the
|
|
-- minerals, saplings, seeds, and spores from Minetest Game versions
|
|
-- 0.4.0 through 5.4.1, Minimal 0.4.0 through 5.2.0, Development Test
|
|
-- 5.3.0 through 5.4.2, Build 0.4.6, and Survival 0.4.6 are properly
|
|
-- detected. Each time a new version of the engine is released with
|
|
-- corresponding versions of is official subgames, this number will be
|
|
-- incremented by one. Normally, it's best to compare using the
|
|
-- greater-than-or-equal-to operator. All past versions of the official
|
|
-- subgames will remain supported, so it doesn't make sense to require
|
|
-- an exact match when determining whether this mod has support for
|
|
-- detecting the countables in a given Minetest Game version.
|
|
--
|
|
-- Version 0.4.0 was the first to support mods, and corresponds to 0 as
|
|
-- this mod's detection level for that version. There have been 27
|
|
-- versions released since then, all of which are properly detected
|
|
-- with the below algorithm, so we're now at detection level 27. (This
|
|
-- is Development Test version 5.4.2; this engine version has no
|
|
-- corresponding Minetest Game version.)
|
|
liblevelup.meta.minetest_game_detection = 27
|
|
|
|
local debug_table = false
|
|
-- Uncomment this line for testing.
|
|
--debug_table = dofile(minetest.get_modpath("liblevelup").."/debug.lua")
|
|
|
|
local function generic_default_is_countable_function(node_string, drops, drop_opts, drop_key)
|
|
-- If multiple items are dropped, this is probably something we should
|
|
-- count.
|
|
if #drops > 1 then
|
|
return true
|
|
end
|
|
local drop_stack = ItemStack(drops[1])
|
|
local drop_def = drop_stack:get_definition()
|
|
local node_stack = ItemStack(node_string)
|
|
local node_def = node_stack:get_definition()
|
|
if drop_def.type ~= "node" then
|
|
-- If it's not a node and doesn't place as a node, count it.
|
|
if drop_def.on_place == minetest.craftitemdef_default.on_place then
|
|
return true
|
|
-- If it's not a node but does place as one, it's probably a door or a
|
|
-- 0.4.7 seed.
|
|
--
|
|
-- Seeds should be counted if they're dropped by non-farm plants,
|
|
-- dropped in multiples, or dropped along with other items. If dropped
|
|
-- with other items, they'll be taken care of by an above block.
|
|
else
|
|
-- Doors can be interacted with, so check for that.
|
|
if node_def.on_rightclick then
|
|
return false
|
|
end
|
|
-- Checking for multiples is easy.
|
|
if drop_stack:get_count() > 1 then
|
|
return true
|
|
end
|
|
-- Checking for farm plants isn't so easy. What we want to determine is
|
|
-- whether the single seed came from a plant that can be grown from
|
|
-- that single seed, but there's no way to do this as growth is handled
|
|
-- in another function, not handled by a string property of the seed.
|
|
-- Instead, we check to see if the plant's drop table seems similar to
|
|
-- that of a farm plant, and if it is, assume the seed-like item it
|
|
-- dropped was the single seed needed to regrow that same plant.
|
|
--
|
|
-- Basically, wild grasses tend to drop themselves if not their seed,
|
|
-- so only the grass *or* the seed will drop. This should be counted,
|
|
-- as the seed cannot be used to regrow the grass. Farm crops can drop
|
|
-- multiple items though, and they should all be counted unless only
|
|
-- one item drops and that one item is a single seed. This is because
|
|
-- that single seed could be converted back into the original farm
|
|
-- plant by planting it and waiting for it to grow, so it's not a true
|
|
-- drop.
|
|
if type(node_def.drop) == "table" and node_def.drop.max_items ~= 1 then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
-- This prevents the catching of 0.4.0-style doors.
|
|
if node_def.legacy_wallmounted then
|
|
return false
|
|
end
|
|
-- Nodes often get swapped for other nodes when interacted with, while
|
|
-- the new nodes drop the original ones for better stacking. This is
|
|
-- case with doors, gates, and chests, for example.
|
|
if drop_def.on_rightclick then
|
|
return false
|
|
end
|
|
-- Prevent grass from being caught.
|
|
if node_def.drawtype ~= "normal" and node_def.drawtype == drop_def.drawtype then
|
|
-- This prevents catching of 0.4.15 xpanes. Again, xpanes are a pain.
|
|
if node_def.drawtype == "nodebox" then
|
|
return false
|
|
end
|
|
-- We still want to catch mushrooms though.
|
|
if node_def.tiles and node_def.tiles[1] == drop_def.tiles[1] then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
-- The only way to prevent catching wet-soil-to-dirt drops when dealing
|
|
-- with 0.4.7 soil without hard-coding specific node names seems to be
|
|
-- to hard-code the soil group, which is far from ideal.
|
|
if minetest.get_item_group(node_stack:get_name(), "soil") > minetest.get_item_group(drop_stack:get_name(), "soil") then
|
|
return false
|
|
end
|
|
-- xpanes are such a pain. This check for the "airlike" draw type
|
|
-- prevents catching of 0.4.10 xpanes.
|
|
if drop_def.drawtype == "airlike" then
|
|
return false
|
|
end
|
|
-- This catches things such as saplings and modern seeds. We don't want
|
|
-- to catch single seeds dropped by farm plants though.
|
|
if node_def.drawtype ~= drop_def.drawtype then
|
|
if drop_stack:get_count() > 1 then
|
|
return true
|
|
end
|
|
if type(node_def.drop) == "table" and node_def.drop.max_items ~= 1 then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
local drop_tiles = drop_def.tiles or drop_def.tile_images or {}
|
|
local node_tiles = node_def.tiles or node_def.tile_images or {}
|
|
if #drop_tiles == 1 then
|
|
-- This catches ice.
|
|
if #node_tiles == 1 then
|
|
return true
|
|
end
|
|
-- This catches sand without catching dirt.
|
|
for _, tile in next, node_tiles do
|
|
if tile:split("^")[1] == drop_tiles[1] then
|
|
-- Instead of outright rejecting dirt though, we need to see if the
|
|
-- dirt likely converts itself to other forms. That lets us catch dry
|
|
-- dirt without catching regular dirt.
|
|
for _, def in next, minetest.registered_abms do
|
|
for _, node in next, def.nodenames do
|
|
if node == drops[1] then
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
if debug_table then
|
|
-- For debugging purposes
|
|
liblevelup.register.is_countable(function(node_string, drop, drop_opts, drop_key)
|
|
local result = generic_default_is_countable_function(node_string, drop, drop_opts, drop_key)
|
|
local key = "["..node_string.."]["..drop_key.."]"
|
|
if debug_table[key] == nil or debug_table[key] ~= result then
|
|
minetest.debug(key.." => "..dump(result == true))
|
|
end
|
|
return result
|
|
end)
|
|
else
|
|
liblevelup.register.is_countable(generic_default_is_countable_function)
|
|
end
|