From 86b2cd70f907dccb161bbdbb99e1770647ba2a76 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 6 Nov 2020 13:46:52 +0100 Subject: [PATCH] Fortune --- mods/CORE/mcl_enchanting/enchantments.lua | 2 +- mods/ENTITIES/mcl_item_entity/init.lua | 68 ++++++++++++++++++++++- mods/ITEMS/mcl_core/nodes_base.lua | 43 +++++++++++++- mods/ITEMS/mcl_core/nodes_trees.lua | 52 +++++++++-------- mods/ITEMS/mcl_farming/melon.lua | 7 +++ mods/ITEMS/mcl_flowers/init.lua | 19 ++++++- mods/ITEMS/mcl_nether/init.lua | 8 +++ mods/ITEMS/mcl_nether/nether_wart.lua | 6 ++ mods/ITEMS/mcl_ocean/prismarine.lua | 7 +++ 9 files changed, 183 insertions(+), 29 deletions(-) diff --git a/mods/CORE/mcl_enchanting/enchantments.lua b/mods/CORE/mcl_enchanting/enchantments.lua index 01b1bd9a4..c143044a0 100644 --- a/mods/CORE/mcl_enchanting/enchantments.lua +++ b/mods/CORE/mcl_enchanting/enchantments.lua @@ -189,7 +189,7 @@ mcl_enchanting.enchantments.fortune = { requires_tool = false, } --- implemented using walkover.register_global +-- implemented via walkover.register_global mcl_enchanting.enchantments.frost_walker = { name = "Frost Walker", max_level = 2, diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 8d451f9b0..641348132 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -212,6 +212,50 @@ local check_can_drop = function(node_name, tool_capabilities) end end +-- Stupid workaround to get drops from a drop table: +-- Create a temporary table in minetest.registered_nodes that contains the proper drops, +-- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition +-- (very ugly) + +local tmp_id = 0 + +local function get_drops(drop, toolname, param2, paramtype2) + tmp_id = tmp_id + 1 + local tmp_node_name = "mcl_item_entity:" .. tmp_id + minetest.registered_nodes[tmp_node_name] = { + name = tmp_node_name, + drop = drop, + paramtype2 = paramtype2 + } + local drops = minetest.get_node_drops({name = tmp_node_name, param2 = param2}, toolname) + minetest.registered_nodes[tmp_node_name] = nil + return drops +end + +local function discrete_uniform_distribution(drops, min_count, max_count, cap) + local new_drops = table.copy(drops) + for i, item in ipairs(drops) do + local new_item = ItemStack(item) + local multiplier = math.random(min_count, max_count) + if cap then + multiplier = math.min(cap, multiplier) + end + new_item:set_count(multiplier * new_item:get_count()) + new_drops[i] = new_item + end + return new_drops +end + +local function get_fortune_drops(fortune_drops, fortune_level) + local drop + local i = fortune_level + repeat + drop = fortune_drops[i] + i = i - 1 + until drop or i < 1 + return drop or {} +end + function minetest.handle_node_drops(pos, drops, digger) -- NOTE: This function override allows digger to be nil. -- This means there is no digger. This is a special case which allows this function to be called @@ -241,6 +285,9 @@ function minetest.handle_node_drops(pos, drops, digger) * true: Drop itself when dug by shears / silk touch tool * table: Drop every itemstring in this table when dug by shears _mcl_silk_touch_drop ]] + + local enchantments = tool and mcl_enchanting.get_enchantments(tool, "silk_touch") + local silk_touch_drop = false local nodedef = minetest.registered_nodes[dug_node.name] if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then @@ -249,7 +296,7 @@ function minetest.handle_node_drops(pos, drops, digger) else drops = nodedef._mcl_shears_drop end - elseif tool and mcl_enchanting.has_enchantment(tool, "silk_touch") and nodedef._mcl_silk_touch_drop then + elseif tool and enchantments.silk_touch and nodedef._mcl_silk_touch_drop then silk_touch_drop = true if nodedef._mcl_silk_touch_drop == true then drops = { dug_node.name } @@ -257,6 +304,25 @@ function minetest.handle_node_drops(pos, drops, digger) drops = nodedef._mcl_silk_touch_drop end end + + if tool and nodedef._mcl_fortune_drop and enchantments.fortune then + local fortune_level = enchantments.fortune + local fortune_drop = nodedef._mcl_fortune_drop + if fortune_drop.discrete_uniform_distribution then + local min_count = fortune_drop.min_count + local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1) + local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level) + if not chance or math.random() < chance then + drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count, fortune_drop.cap) + elseif fortune_drop.override then + drops = {} + end + else + -- Fixed Behavior + local drop = get_fortune_drops(fortune_drops, fortune_level) + drops = get_drops(drop, tool:get_name(), dug_node.param2, nodedef.paramtype2) + end + end if digger and mcl_experience.throw_experience and not silk_touch_drop then local experience_amount = minetest.get_item_group(dug_node.name,"xp") diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index b8ddabf97..f9ac0e01e 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -10,6 +10,14 @@ else ice_drawtype = "normal" end +mcl_core.fortune_drop_ore = { + discrete_uniform_distribution = true, + min_count = 2, + max_count = 1, + get_chance = function (fortune_level) return 1 - 2 / (fortune_level + 2) end, + multiply = true, +} + minetest.register_node("mcl_core:stone", { description = S("Stone"), _doc_items_longdesc = S("One of the most common blocks in the world, almost the entire underground consists of stone. It sometimes contains ores. Stone may be created when water meets lava."), @@ -38,6 +46,7 @@ minetest.register_node("mcl_core:stone_with_coal", { _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) minetest.register_node("mcl_core:stone_with_iron", { @@ -100,6 +109,12 @@ minetest.register_node("mcl_core:stone_with_redstone", { _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mesecons:redstone"}, + min_count = 4, + max_count = 5, + } }) local redstone_ore_reactivate = function(pos) @@ -138,7 +153,13 @@ minetest.register_node("mcl_core:stone_with_redstone_lit", { end, _mcl_blast_resistance = 3, _mcl_hardness = 3, - _mcl_silk_touch_drop = "mcl_core:stone_with_redstone", + _mcl_silk_touch_drop = {"mcl_core:stone_with_redstone"}, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mesecons:redstone"}, + min_count = 4, + max_count = 5, + } }) minetest.register_node("mcl_core:stone_with_lapis", { @@ -161,6 +182,7 @@ minetest.register_node("mcl_core:stone_with_lapis", { sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) minetest.register_node("mcl_core:stone_with_emerald", { @@ -175,6 +197,7 @@ minetest.register_node("mcl_core:stone_with_emerald", { _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) minetest.register_node("mcl_core:stone_with_diamond", { @@ -189,6 +212,7 @@ minetest.register_node("mcl_core:stone_with_diamond", { _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) minetest.register_node("mcl_core:stonebrick", { @@ -464,6 +488,23 @@ minetest.register_node("mcl_core:gravel", { _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + [1] = { + max_items = 1, + items = { + {items = {'mcl_core:flint'},rarity = 7}, + {items = {'mcl_core:gravel'}} + } + }, + [2] = { + max_items = 1, + items = { + {items = {'mcl_core:flint'},rarity = 4}, + {items = {'mcl_core:gravel'}} + } + }, + [3] = "mcl_core:flint" + }, }) -- sandstone -- diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 732eb2e43..3a8aef8d0 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -63,35 +63,39 @@ local register_wooden_planks = function(subname, description, tiles) }) end -local register_leaves = function(subname, description, longdesc, tiles, drop1, drop1_rarity, drop2, drop2_rarity, leafdecay_distance) +local register_leaves = function(subname, description, longdesc, tiles, sapling, drop_apples, sapling_chances, leafdecay_distance) local drop if leafdecay_distance == nil then leafdecay_distance = 4 end - if drop2 then - drop = { + local apple_chances = {200, 180, 160, 120, 40} + local stick_chances = {50, 45, 30, 35, 10} + + local function get_drops(fortune_level) + local drop = { max_items = 1, items = { { - items = {drop1}, - rarity = drop1_rarity, + items = {sapling}, + rarity = sapling_chances[fortune_level + 1] or sapling_chances[fortune_level] }, { - items = {drop2}, - rarity = drop2_rarity, + items = {"mcl_core:stick 1"}, + rarity = stick_chances[fortune_level + 1] }, - } - } - else - drop = { - max_items = 1, - items = { { - items = {drop1}, - rarity = drop1_rarity, + items = {"mcl_core:stick 2"}, + rarity = stick_chances[fortune_level + 1] }, } - } + } + if drop_apples then + table.insert(drop.items, { + items = {"mcl_core:apple"}, + rarity = apple_chances[fortune_level + 1] + }) + end + return drop end minetest.register_node("mcl_core:"..subname, { @@ -105,12 +109,13 @@ local register_leaves = function(subname, description, longdesc, tiles, drop1, d paramtype = "light", stack_max = 64, groups = {handy=1,shearsy=1,swordy=1, leafdecay=leafdecay_distance, flammable=2, leaves=1, deco_block=1, dig_by_piston=1, fire_encouragement=30, fire_flammability=60}, - drop = drop, + drop = get_drops(0), _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), _mcl_blast_resistance = 0.2, _mcl_hardness = 0.2, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { get_drops(1), get_drops(2), get_drops(3), get_drops(4) }, }) end @@ -197,12 +202,13 @@ register_sapling("birchsapling", S("Birch Sapling"), "mcl_core_sapling_birch.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16}) -register_leaves("leaves", S("Oak Leaves"), S("Oak leaves are grown from oak trees."), {"default_leaves.png"}, "mcl_core:sapling", 20, "mcl_core:apple", 200) -register_leaves("darkleaves", S("Dark Oak Leaves"), S("Dark oak leaves are grown from dark oak trees."), {"mcl_core_leaves_big_oak.png"}, "mcl_core:darksapling", 20, "mcl_core:apple", 200) -register_leaves("jungleleaves", S("Jungle Leaves"), S("Jungle leaves are grown from jungle trees."), {"default_jungleleaves.png"}, "mcl_core:junglesapling", 40) -register_leaves("acacialeaves", S("Acacia Leaves"), S("Acacia leaves are grown from acacia trees."), {"default_acacia_leaves.png"}, "mcl_core:acaciasapling", 20) -register_leaves("spruceleaves", S("Spruce Leaves"), S("Spruce leaves are grown from spruce trees."), {"mcl_core_leaves_spruce.png"}, "mcl_core:sprucesapling", 20) -register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from birch trees."), {"mcl_core_leaves_birch.png"}, "mcl_core:birchsapling", 20) +register_leaves("leaves", S("Oak Leaves"), S("Oak leaves are grown from oak trees."), {"default_leaves.png"}, "mcl_core:sapling", true, {20, 16, 12, 10}) +register_leaves("darkleaves", S("Dark Oak Leaves"), S("Dark oak leaves are grown from dark oak trees."), {"mcl_core_leaves_big_oak.png"}, "mcl_core:darksapling", true, {20, 16, 12, 10}) +register_leaves("jungleleaves", S("Jungle Leaves"), S("Jungle leaves are grown from jungle trees."), {"default_jungleleaves.png"}, "mcl_core:junglesapling", false, {40, 26, 32, 24, 10}) +register_leaves("acacialeaves", S("Acacia Leaves"), S("Acacia leaves are grown from acacia trees."), {"default_acacia_leaves.png"}, "mcl_core:acaciasapling", false, {20, 16, 12, 10}) +register_leaves("spruceleaves", S("Spruce Leaves"), S("Spruce leaves are grown from spruce trees."), {"mcl_core_leaves_spruce.png"}, "mcl_core:sprucesapling", false, {20, 16, 12, 10}) +register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from birch trees."), {"mcl_core_leaves_birch.png"}, "mcl_core:birchsapling", false, {20, 16, 12, 10}) + -- Node aliases diff --git a/mods/ITEMS/mcl_farming/melon.lua b/mods/ITEMS/mcl_farming/melon.lua index 587b8a6e5..38b4c713c 100644 --- a/mods/ITEMS/mcl_farming/melon.lua +++ b/mods/ITEMS/mcl_farming/melon.lua @@ -36,6 +36,13 @@ local melon_base_def = { _mcl_blast_resistance = 1, _mcl_hardness = 1, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_farming:melon_item"}, + min_count = 3, + max_count = 7, + cap = 9, + } } -- Drop proabilities for melon stem diff --git a/mods/ITEMS/mcl_flowers/init.lua b/mods/ITEMS/mcl_flowers/init.lua index 5b630d562..42deede2f 100644 --- a/mods/ITEMS/mcl_flowers/init.lua +++ b/mods/ITEMS/mcl_flowers/init.lua @@ -98,6 +98,16 @@ local wheat_seed_drop = { } } +local fortune_wheat_seed_drop = { + discrete_uniform_distribution = true, + items = {"mcl_farming:wheat_seeds"}, + chance = 1 / 8, + min_count = 1, + max_count = 1, + factor = 2, + overwrite = true, +} + -- CHECKME: How does tall grass behave when pushed by a piston? --- Tall Grass --- @@ -126,6 +136,7 @@ local def_tallgrass = { sounds = mcl_sounds.node_sound_leaves_defaults(), drop = wheat_seed_drop, _mcl_shears_drop = true, + _mcl_fortune_drop = fortune_wheat_seed_drop, node_placement_prediction = "", on_place = on_place_flower, _mcl_blast_resistance = 0, @@ -148,7 +159,7 @@ def_fern.selection_box = { minetest.register_node("mcl_flowers:fern", def_fern) -local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_img, selbox_radius, selbox_top_height, drop, shears_drop, is_flower, grass_color) +local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_img, selbox_radius, selbox_top_height, drop, shears_drop, is_flower, grass_color, fortune_drop) if not inv_img then inv_img = top_img end @@ -200,6 +211,7 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im buildable_to = true, drop = drop_bottom, _mcl_shears_drop = shears_drop, + _mcl_fortune_drop = fortune_drop, node_placement_prediction = "", selection_box = { type = "fixed", @@ -305,6 +317,7 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im }, drop = drop_top, _mcl_shears_drop = shears_drop, + _mcl_fortune_drop = fortune_drop, after_destruct = function(pos, oldnode) -- Remove bottom half of flower (if it exists) local top = pos @@ -334,8 +347,8 @@ add_large_plant("sunflower", S("Sunflower"), S("A sunflower is a large plant whi local longdesc_grass = S("Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.") local longdesc_fern = S("Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.") -add_large_plant("double_grass", S("Double Tallgrass"), longdesc_grass, "mcl_flowers_double_plant_grass_bottom.png", "mcl_flowers_double_plant_grass_top.png", "mcl_flowers_double_plant_grass_inv.png", 6/16, 4/16, wheat_seed_drop, {"mcl_flowers:tallgrass 2"}, false, true) -add_large_plant("double_fern", S("Large Fern"), longdesc_fern, "mcl_flowers_double_plant_fern_bottom.png", "mcl_flowers_double_plant_fern_top.png", "mcl_flowers_double_plant_fern_inv.png", 5/16, 5/16, wheat_seed_drop, {"mcl_flowers:fern 2"}, false, true) +add_large_plant("double_grass", S("Double Tallgrass"), longdesc_grass, "mcl_flowers_double_plant_grass_bottom.png", "mcl_flowers_double_plant_grass_top.png", "mcl_flowers_double_plant_grass_inv.png", 6/16, 4/16, wheat_seed_drop, {"mcl_flowers:tallgrass 2"}, false, true, nil, fortune_wheat_seed_drop) +add_large_plant("double_fern", S("Large Fern"), longdesc_fern, "mcl_flowers_double_plant_fern_bottom.png", "mcl_flowers_double_plant_fern_top.png", "mcl_flowers_double_plant_fern_inv.png", 5/16, 5/16, wheat_seed_drop, {"mcl_flowers:fern 2"}, false, true, nil, fortune_wheat_seed_drop) minetest.register_abm({ label = "Pop out flowers", diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index f026b6dbe..71221cc5c 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -28,6 +28,13 @@ minetest.register_node("mcl_nether:glowstone", { _mcl_blast_resistance = 0.3, _mcl_hardness = 0.3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_nether:glowstone_dust"}, + min_count = 2, + max_count = 4, + cap = 4, + } }) minetest.register_node("mcl_nether:quartz_ore", { @@ -42,6 +49,7 @@ minetest.register_node("mcl_nether:quartz_ore", { _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore }) -- For eternal fire on top of netherrack and magma blocks diff --git a/mods/ITEMS/mcl_nether/nether_wart.lua b/mods/ITEMS/mcl_nether/nether_wart.lua index 354fa6139..681abe094 100644 --- a/mods/ITEMS/mcl_nether/nether_wart.lua +++ b/mods/ITEMS/mcl_nether/nether_wart.lua @@ -93,6 +93,12 @@ minetest.register_node("mcl_nether:nether_wart", { }, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, sounds = mcl_sounds.node_sound_leaves_defaults(), + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_nether:nether_wart_item"}, + min_count = 2, + max_count = 4, + } }) minetest.register_craftitem("mcl_nether:nether_wart_item", { diff --git a/mods/ITEMS/mcl_ocean/prismarine.lua b/mods/ITEMS/mcl_ocean/prismarine.lua index 77d4f8e34..647e87fe1 100644 --- a/mods/ITEMS/mcl_ocean/prismarine.lua +++ b/mods/ITEMS/mcl_ocean/prismarine.lua @@ -22,6 +22,13 @@ minetest.register_node("mcl_ocean:sea_lantern", { _mcl_blast_resistance = 0.3, _mcl_hardness = 0.3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_ocean:prismarine_crystals"}, + min_count = 2, + max_count = 3, + cap = 5, + } }) minetest.register_node("mcl_ocean:prismarine", {