123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- -- 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
|