diff --git a/game_api.txt b/game_api.txt index 9c576947..c4250d50 100644 --- a/game_api.txt +++ b/game_api.txt @@ -599,6 +599,18 @@ Both nodedefs and entitydefs can provide an `on_blast()` callback * `drops` - a list of drops, e.g. {"wool:red"} +Node drops: + +When a node is detonated it is removed according to the following rules. +1. If `on_blast` is defined, that is called. +2. Else if the node has group `flammable` it is replaced with a fire node. +3. Else the dropped items are retrieved and it is replaced with air. + +The parameter `_tnt_loss` in any item definition can be set to a number to +effect that "one in X" of these drops will be lost during an explosion. +For example `_tnt_loss = 2` would cause 50% of items to disappear. +The default is to not lose any items, which is equivalent to `_tnt_loss = 0`. + Screwdriver API --------------- diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index 2bde6f8e..8537d9e8 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -271,6 +271,7 @@ minetest.register_node("default:cobble", { is_ground_content = false, groups = {cracky = 3, stone = 2}, sounds = default.node_sound_stone_defaults(), + _tnt_loss = 4, }) minetest.register_node("default:stonebrick", { @@ -297,9 +298,9 @@ minetest.register_node("default:mossycobble", { is_ground_content = false, groups = {cracky = 3, stone = 1}, sounds = default.node_sound_stone_defaults(), + _tnt_loss = 4, }) - minetest.register_node("default:desert_stone", { description = S("Desert Stone"), tiles = {"default_desert_stone.png"}, @@ -315,6 +316,7 @@ minetest.register_node("default:desert_cobble", { is_ground_content = false, groups = {cracky = 3, stone = 2}, sounds = default.node_sound_stone_defaults(), + _tnt_loss = 4, }) minetest.register_node("default:desert_stonebrick", { @@ -444,6 +446,7 @@ minetest.register_node("default:dirt", { tiles = {"default_dirt.png"}, groups = {crumbly = 3, soil = 1}, sounds = default.node_sound_dirt_defaults(), + _tnt_loss = 3, }) minetest.register_node("default:dirt_with_grass", { @@ -530,6 +533,7 @@ minetest.register_node("default:dry_dirt", { tiles = {"default_dry_dirt.png"}, groups = {crumbly = 3, soil = 1}, sounds = default.node_sound_dirt_defaults(), + _tnt_loss = 3, }) minetest.register_node("default:dry_dirt_with_dry_grass", { @@ -576,6 +580,7 @@ minetest.register_node("default:sand", { tiles = {"default_sand.png"}, groups = {crumbly = 3, falling_node = 1, sand = 1}, sounds = default.node_sound_sand_defaults(), + _tnt_loss = 2, }) minetest.register_node("default:desert_sand", { @@ -583,6 +588,7 @@ minetest.register_node("default:desert_sand", { tiles = {"default_desert_sand.png"}, groups = {crumbly = 3, falling_node = 1, sand = 1}, sounds = default.node_sound_sand_defaults(), + _tnt_loss = 2, }) minetest.register_node("default:silver_sand", { @@ -590,6 +596,7 @@ minetest.register_node("default:silver_sand", { tiles = {"default_silver_sand.png"}, groups = {crumbly = 3, falling_node = 1, sand = 1}, sounds = default.node_sound_sand_defaults(), + _tnt_loss = 2, }) @@ -604,7 +611,8 @@ minetest.register_node("default:gravel", { {items = {"default:flint"}, rarity = 16}, {items = {"default:gravel"}} } - } + }, + _tnt_loss = 3, }) minetest.register_node("default:clay", { @@ -639,6 +647,7 @@ minetest.register_node("default:snow", { }, groups = {crumbly = 3, falling_node = 1, snowy = 1}, sounds = default.node_sound_snow_defaults(), + _tnt_loss = 1, -- means it will disappear entirely on_construct = function(pos) pos.y = pos.y - 1 @@ -2807,6 +2816,7 @@ minetest.register_node("default:glass", { is_ground_content = false, groups = {cracky = 3, oddly_breakable_by_hand = 3}, sounds = default.node_sound_glass_defaults(), + _tnt_loss = 2, }) minetest.register_node("default:obsidian_glass", { diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 05f01e3d..4acbdaa9 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -12,12 +12,6 @@ if enable_tnt == nil then enable_tnt = minetest.is_singleplayer() end --- loss probabilities array (one in X will be lost) -local loss_prob = {} - -loss_prob["default:cobble"] = 3 -loss_prob["default:dirt"] = 4 - local tnt_radius = tonumber(minetest.settings:get("tnt_radius") or 3) -- Fill a list with data for content IDs, after all nodes are registered @@ -27,7 +21,7 @@ minetest.register_on_mods_loaded(function() cid_data[minetest.get_content_id(name)] = { name = name, drops = def.drops, - flammable = def.groups.flammable, + flammable = def.groups and (def.groups.flammable or 0) ~= 0, on_blast = def.on_blast, } end @@ -76,11 +70,14 @@ end local function add_drop(drops, item) item = ItemStack(item) - local name = item:get_name() - if loss_prob[name] ~= nil and math.random(1, loss_prob[name]) == 1 then + -- Note that this needs to be set on the dropped item, not the node. + -- Value represents "one in X will be lost" + local lost = item:get_definition()._tnt_loss or 0 + if lost > 0 and (lost == 1 or math.random(1, lost) == 1) then return end + local name = item:get_name() local drop = drops[name] if drop == nil then drops[name] = item