From ca0db16a171660b460421b38a36dbabfaefd6aff Mon Sep 17 00:00:00 2001 From: FaceDeer Date: Sun, 11 Aug 2019 13:52:31 -0600 Subject: [PATCH] revamp bones loot --- bones_loot/init.lua | 107 +++++++++++++++++++++++++----------- df_caverns/dungeon_loot.lua | 73 +++++++++++++++++++++++- df_caverns/underworld.lua | 15 ++++- 3 files changed, 158 insertions(+), 37 deletions(-) diff --git a/bones_loot/init.lua b/bones_loot/init.lua index 8f75e7e..4f7d08b 100644 --- a/bones_loot/init.lua +++ b/bones_loot/init.lua @@ -2,38 +2,82 @@ local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") +local dungeon_loot_path = minetest.get_modpath("dungeon_loot") + bones_loot = {} -local dungeon_loot_path = minetest.get_modpath("dungeon_loot") -if dungeon_loot_path then - local shuffle = function(tbl) - for i = #tbl, 2, -1 do - local rand = math.random(i) - tbl[i], tbl[rand] = tbl[rand], tbl[i] - end - return tbl +local local_loot = {} +local local_loot_register = function(t) + if t.name ~= nil then + t = {t} -- single entry end + for _, loot in ipairs(t) do + table.insert(local_loot, loot) + end +end - bones_loot.get_loot = function(pos, loot_type, max_stacks) +-- we could do this for the dungeon_loot registered loot table as well, +-- but best not to meddle in other mods' internals if it can be helped. +local clean_up_local_loot = function() + if local_loot == nil then return end + for i = #local_loot, 1, -1 do + if not minetest.registered_items[local_loot[i].name] then + table.remove(local_loot, i) + end + end +end + +-- Uses same table format as dungeon_loot +-- eg, {name = "bucket:bucket_water", chance = 0.45, types = {"sandstone", "desert"}}, +-- if dungeon_loot is installed it uses dungeon_loot's registration function directly. +if dungeon_loot_path then + bones_loot.register_loot = dungeon_loot.register +else + bones_loot.register_loot = local_loot_register + minetest.after(0, clean_up_local_loot) +end + +local get_loot_list = function(pos, loot_type, exclusive_loot_type) + local loot_table + if dungeon_loot_path then + loot_table = dungeon_loot.registered_loot + else + loot_table = local_loot + end - local item_list = {} - local pos_y = pos.y - for _, loot in ipairs(dungeon_loot.registered_loot) do - if loot.y == nil or (pos_y >= loot.y[1] and pos_y <= loot.y[2]) then - if loot.types == nil or table.indexof(loot.types, loot_type) ~= -1 then - table.insert(item_list, loot) - end + local item_list = {} + local pos_y = pos.y + for _, loot in ipairs(loot_table) do + if loot.y == nil or (pos_y >= loot.y[1] and pos_y <= loot.y[2]) then + if (not exclusive_loot_type and loot.types == nil) or + (loot.types and table.indexof(loot.types, loot_type) ~= -1) then + table.insert(item_list, loot) end end + end - shuffle(item_list) - - -- apply chances / randomized amounts and collect resulting items - local items = {} - for _, loot in ipairs(item_list) do - if math.random() <= loot.chance then - local itemdef = minetest.registered_items[loot.name] - + return item_list +end + +local shuffle = function(tbl) + for i = #tbl, 2, -1 do + local rand = math.random(i) + tbl[i], tbl[rand] = tbl[rand], tbl[i] + end + return tbl +end + +-- "exclusive" set to true means that loot table entries without a loot_type won't be considered. +bones_loot.get_loot = function(pos, loot_type, max_stacks, exclusive_loot_type) + local item_list = get_loot_list(pos, loot_type, exclusive_loot_type) + shuffle(item_list) + + -- apply chances / randomized amounts and collect resulting items + local items = {} + for _, loot in ipairs(item_list) do + if math.random() <= loot.chance then + local itemdef = minetest.registered_items[loot.name] + if itemdef then local amount = 1 if loot.count ~= nil then amount = math.random(loot.count[1], loot.count[2]) @@ -56,13 +100,13 @@ if dungeon_loot_path then end end end - if max_stacks <= 0 then break end - end - return items - end + end + if max_stacks <= 0 then break end + end + return items end -bones_loot.place_bones = function(pos, loot_type, max_stacks, infotext) +bones_loot.place_bones = function(pos, loot_type, max_stacks, infotext, exclusive_loot_type) minetest.set_node(pos, {name="bones:bones", param2 = math.random(1,4)-1}) local meta = minetest.get_meta(pos) if infotext == nil then @@ -70,8 +114,8 @@ bones_loot.place_bones = function(pos, loot_type, max_stacks, infotext) end meta:set_string("infotext", infotext) - if bones_loot.get_loot and loot_type and max_stacks then - local loot = bones_loot.get_loot(pos, loot_type, max_stacks) + if max_stacks and max_stacks > 0 then + local loot = bones_loot.get_loot(pos, loot_type, max_stacks, exclusive_loot_type) local inv = meta:get_inventory() inv:set_size("main", 8 * 4) for _, item in ipairs(loot) do @@ -79,4 +123,3 @@ bones_loot.place_bones = function(pos, loot_type, max_stacks, infotext) end end end - diff --git a/df_caverns/dungeon_loot.lua b/df_caverns/dungeon_loot.lua index 02ed0e4..b919ddd 100644 --- a/df_caverns/dungeon_loot.lua +++ b/df_caverns/dungeon_loot.lua @@ -1,6 +1,4 @@ -if not minetest.get_modpath("dungeon_loot") then - return -end +if minetest.get_modpath("dungeon_loot") then if df_caverns.config.enable_underworld then dungeon_loot.register({ @@ -42,3 +40,72 @@ dungeon_loot.register({ {name = "df_trees:torchspine_ember", chance = 0.3, count = {1, 3}, y = {-32768, df_caverns.config.level2_min}}, {name = "ice_sprites:ice_sprite_bottle", chance = 0.1, count = {1, 1}, y = {-32768, df_caverns.config.level2_min}}, }) + +end + +if minetest.get_modpath("bones_loot") and df_caverns.config.enable_underworld then + +bones_loot.register_loot({ + {name = "binoculars:binoculars", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "boats:boat", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "bucket:bucket_empty", chance = 0.3, count = {1,1}, types = {"underworld_warrior"}}, + {name = "fire:flint_and_steel", chance = 0.3, count = {1,2}, types = {"underworld_warrior"}}, + {name = "flowers:tulip_black", chance = 0.01, count = {1,1}, types = {"underworld_warrior"}}, + {name = "map:mapping_kit", chance = 0.1, count = {1,1}, types = {"underworld_warrior"}}, + {name = "screwdriver:screwdriver", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + -- don't give the player tnt:tnt, they can craft that from this if tnt is enabled for them + {name = "tnt:gunpowder", chance = 0.4, count = {1,10}, types = {"underworld_warrior"}}, + {name = "tnt:tnt_stick", chance = 0.3, count = {1,6}, types = {"underworld_warrior"}}, + + {name = "vessels:steel_bottle", chance = 0.4, count = {1,3}, types = {"underworld_warrior"}}, + {name = "vessels:glass_bottle", chance = 0.2, count = {1,2}, types = {"underworld_warrior"}}, + {name = "vessels:glass_fragments", chance = 0.1, count = {1,4}, types = {"underworld_warrior"}}, + + {name = "default:book", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:paper", chance = 0.1, count = {1,6}, types = {"underworld_warrior"}}, + {name = "default:skeleton_key", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:torch", chance = 0.75, count = {1,10}, types = {"underworld_warrior"}}, + + {name = "default:pick_bronze", chance = 0.15, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:pick_steel", chance = 0.1, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:pick_mese", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:pick_diamond", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:shovel_bronze", chance = 0.15, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:shovel_steel", chance = 0.1, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:shovel_mese", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:shovel_diamond", chance = 0.05, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:axe_bronze", chance = 0.3, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:axe_steel", chance = 0.5, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:axe_mese", chance = 0.15, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:axe_diamond", chance = 0.15, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:sword_bronze", chance = 0.5, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:sword_steel", chance = 0.75, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:sword_mese", chance = 0.35, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:sword_diamond", chance = 0.35, count = {1,1}, types = {"underworld_warrior"}}, + + {name = "default:coal_lump", chance = 0.5, count = {1,5}, types = {"underworld_warrior"}}, + {name = "default:mese_crystal", chance = 0.1, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:diamond", chance = 0.1, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:steel_ingot", chance = 0.2, count = {1,3}, types = {"underworld_warrior"}}, + {name = "default:copper_ingot", chance = 0.1, count = {1,2}, types = {"underworld_warrior"}}, + {name = "default:bronze_ingot", chance = 0.2, count = {1,5}, types = {"underworld_warrior"}}, + {name = "default:gold_ingot", chance = 0.3, count = {1,3}, types = {"underworld_warrior"}}, + {name = "default:mese_crystal_fragment", chance = 0.4, count = {1,5}, types = {"underworld_warrior"}}, + {name = "default:obsidian_shard", chance = 0.4, count = {1,3}, types = {"underworld_warrior"}}, + {name = "default:flint", chance = 0.3, count = {1,1}, types = {"underworld_warrior"}}, + {name = "default:sign_wall_wood", chance = 0.1, count = {1,4}, types = {"underworld_warrior"}}, + {name = "default:sign_wall_steel", chance = 0.1, count = {1,2}, types = {"underworld_warrior"}}, + {name = "default:ladder_wood", chance = 0.5, count = {1,10}, types = {"underworld_warrior"}}, + {name = "default:ladder_steel", chance = 0.2, count = {1,5}, types = {"underworld_warrior"}}, + {name = "default:meselamp", chance = 0.1, count = {1,2}, types = {"underworld_warrior"}}, + {name = "default:mese_post_light", chance = 0.25, count = {1,5}, types = {"underworld_warrior"}}, + + {name = "ice_sprites:ice_sprite_bottle", chance = 0.025, count = {1, 1}, types = {"underworld_warrior"}}, + {name = "df_underworld_items:glow_amethyst", chance = 0.25, count = {1, 2}, types = {"underworld_warrior"}}, +}) + +if df_caverns.config.enable_lava_sea then + bones_loot.register_loot({name = "df_mapitems:mese_crystal", chance = 0.25, count = {1, 2}, types = {"underworld_warrior"}}) +end + +end \ No newline at end of file diff --git a/df_caverns/underworld.lua b/df_caverns/underworld.lua index 5dd3d6c..5f3cd44 100644 --- a/df_caverns/underworld.lua +++ b/df_caverns/underworld.lua @@ -235,6 +235,17 @@ local perlin_pit = { ------------------------------------- +minetest.register_chatcommand("find_pit", { + params = "", + privs = {server=true}, + decription = "find a nearby glowing pit", + func = function(name, param) + local player = minetest.get_player_by_name(name) + local pit = get_pit(player:get_pos()) + minetest.chat_send_player(name, "Pit location: x=" .. math.floor(pit.location.x) .. " z=" .. math.floor(pit.location.z)) + end, +}) + minetest.register_on_generated(function(minp, maxp, seed) @@ -389,7 +400,7 @@ minetest.register_on_generated(function(minp, maxp, seed) vm:write_to_map() if bones_loot_path then - for i = 1, 15 do + for i = 1, 30 do local x = math.random(minp.x, maxp.x) local z = math.random(minp.z, maxp.z) local index2d = mapgen_helper.index2d(emin, emax, x, z) @@ -408,7 +419,7 @@ minetest.register_on_generated(function(minp, maxp, seed) local target_pos = {x=x, y=y, z=z} local target_node = minetest.get_node(target_pos) if target_node.name == "air" then - bones_loot.place_bones(target_pos, "normal", math.random(5, 15)) + bones_loot.place_bones(target_pos, "underworld_warrior", math.random(3, 10), nil, true) break elseif target_node.name == "bones:bones" then -- don't stack bones on bones, it looks silly