revamp bones loot

This commit is contained in:
FaceDeer 2019-08-11 13:52:31 -06:00
parent bbe7f169c6
commit ca0db16a17
3 changed files with 158 additions and 37 deletions

View File

@ -2,38 +2,82 @@
local MP = minetest.get_modpath(minetest.get_current_modname()) local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua") local S, NS = dofile(MP.."/intllib.lua")
local dungeon_loot_path = minetest.get_modpath("dungeon_loot")
bones_loot = {} bones_loot = {}
local dungeon_loot_path = minetest.get_modpath("dungeon_loot") local local_loot = {}
if dungeon_loot_path then local local_loot_register = function(t)
local shuffle = function(tbl) if t.name ~= nil then
for i = #tbl, 2, -1 do t = {t} -- single entry
local rand = math.random(i)
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
return tbl
end 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 item_list = {}
local pos_y = pos.y local pos_y = pos.y
for _, loot in ipairs(dungeon_loot.registered_loot) do 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 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 if (not exclusive_loot_type and loot.types == nil) or
table.insert(item_list, loot) (loot.types and table.indexof(loot.types, loot_type) ~= -1) then
end table.insert(item_list, loot)
end end
end end
end
shuffle(item_list) return item_list
end
-- apply chances / randomized amounts and collect resulting items
local items = {} local shuffle = function(tbl)
for _, loot in ipairs(item_list) do for i = #tbl, 2, -1 do
if math.random() <= loot.chance then local rand = math.random(i)
local itemdef = minetest.registered_items[loot.name] 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 local amount = 1
if loot.count ~= nil then if loot.count ~= nil then
amount = math.random(loot.count[1], loot.count[2]) amount = math.random(loot.count[1], loot.count[2])
@ -56,13 +100,13 @@ if dungeon_loot_path then
end end
end end
end end
if max_stacks <= 0 then break end end
end if max_stacks <= 0 then break end
return items end
end return items
end 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}) minetest.set_node(pos, {name="bones:bones", param2 = math.random(1,4)-1})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if infotext == nil then if infotext == nil then
@ -70,8 +114,8 @@ bones_loot.place_bones = function(pos, loot_type, max_stacks, infotext)
end end
meta:set_string("infotext", infotext) meta:set_string("infotext", infotext)
if bones_loot.get_loot and loot_type and max_stacks then if max_stacks and max_stacks > 0 then
local loot = bones_loot.get_loot(pos, loot_type, max_stacks) local loot = bones_loot.get_loot(pos, loot_type, max_stacks, exclusive_loot_type)
local inv = meta:get_inventory() local inv = meta:get_inventory()
inv:set_size("main", 8 * 4) inv:set_size("main", 8 * 4)
for _, item in ipairs(loot) do for _, item in ipairs(loot) do
@ -79,4 +123,3 @@ bones_loot.place_bones = function(pos, loot_type, max_stacks, infotext)
end end
end end
end end

View File

@ -1,6 +1,4 @@
if not minetest.get_modpath("dungeon_loot") then if minetest.get_modpath("dungeon_loot") then
return
end
if df_caverns.config.enable_underworld then if df_caverns.config.enable_underworld then
dungeon_loot.register({ 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 = "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}}, {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

View File

@ -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) minetest.register_on_generated(function(minp, maxp, seed)
@ -389,7 +400,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
vm:write_to_map() vm:write_to_map()
if bones_loot_path then if bones_loot_path then
for i = 1, 15 do for i = 1, 30 do
local x = math.random(minp.x, maxp.x) local x = math.random(minp.x, maxp.x)
local z = math.random(minp.z, maxp.z) local z = math.random(minp.z, maxp.z)
local index2d = mapgen_helper.index2d(emin, emax, x, 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_pos = {x=x, y=y, z=z}
local target_node = minetest.get_node(target_pos) local target_node = minetest.get_node(target_pos)
if target_node.name == "air" then 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 break
elseif target_node.name == "bones:bones" then elseif target_node.name == "bones:bones" then
-- don't stack bones on bones, it looks silly -- don't stack bones on bones, it looks silly