197 lines
6.7 KiB
Lua
197 lines
6.7 KiB
Lua
lootchests = {}
|
|
|
|
lootchests.loot_table = {}
|
|
|
|
lootchests.spawn_chests = asuna.content.wayfarer.loot_chests
|
|
local S = minetest.get_translator(minetest.get_current_modname())
|
|
|
|
local debug = minetest.settings:get("lootchests_debug") or false
|
|
|
|
local function list_length(list)
|
|
local count = 0
|
|
for _,_ in pairs(list) do
|
|
count = count + 1
|
|
end
|
|
return count
|
|
end
|
|
|
|
lootchests.add_to_loot_table = function(key, add)
|
|
if not lootchests.loot_table[key] then
|
|
lootchests.loot_table[key] = {}
|
|
end
|
|
for _,v in pairs(add) do
|
|
table.insert(lootchests.loot_table[key], v)
|
|
end
|
|
end
|
|
|
|
local water_nodes = {
|
|
"default:water_source",
|
|
"default:river_water_source",
|
|
"default:lava_source",
|
|
"ethereal:quicksand2",
|
|
}
|
|
|
|
lootchests.register_lootchest = function(def)
|
|
|
|
if not def.name or not def.description then
|
|
minetest.log("error", S("[lootchests] Missing fields in chest definition!"))
|
|
return
|
|
end
|
|
|
|
if not lootchests.loot_table[def.name] then
|
|
minetest.log("error", S("[lootchests] Missing loot table for") .. " " .. def.name .. "!")
|
|
return
|
|
end
|
|
|
|
local tiles = def.tiles or {
|
|
"default_chest_top.png",
|
|
"default_chest_top.png",
|
|
"default_chest_side.png",
|
|
"default_chest_side.png",
|
|
"default_chest_front.png",
|
|
}
|
|
|
|
local sounds = def.sounds or default.node_sound_wood_defaults()
|
|
local groups = def.groups or {choppy = 2, oddly_breakable_by_hand = 2}
|
|
local rarity = def.spawn_in_rarity or 512
|
|
local fill_ratio = def.spawn_on_rarity or 512
|
|
local ymax = def.ymax or 31000
|
|
local ymin = def.ymin or -31000
|
|
local slot_spawn_chance = def.slot_spawn_chance or 0.25
|
|
local slots = def.slots or 32
|
|
local node_box = def.node_box or {
|
|
type = "fixed",
|
|
fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
}
|
|
|
|
local marker_drawtype = "airlike"
|
|
local marker_groups = {dig_immediate = 2, not_in_creative_inventory = 1}
|
|
if debug then
|
|
marker_drawtype = nil
|
|
marker_groups = {dig_immediate = 2}
|
|
end
|
|
|
|
minetest.register_node(def.name .. "_marker", {
|
|
drawtype = marker_drawtype,
|
|
description = def.description .. " " .. S("Spawn Marker"),
|
|
tiles = {"lootchests_marker_top.png", "lootchests_marker_side.png"},
|
|
groups = marker_groups,
|
|
paramtype2 = "facedir",
|
|
})
|
|
|
|
minetest.register_node(def.name, {
|
|
description = def.description,
|
|
drawtype = def.drawtype,
|
|
tiles = tiles,
|
|
node_box = node_box,
|
|
selection_box = node_box,
|
|
groups = groups,
|
|
sounds = sounds,
|
|
paramtype = "light",
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("formspec",
|
|
"size[8,9]" ..
|
|
default.gui_bg ..
|
|
default.gui_bg_img ..
|
|
default.gui_slots ..
|
|
"list[current_name;main;0,0;8,5;]" ..
|
|
"list[current_player;main;0,5;8,4;]" ..
|
|
"listring[current_name;main]" ..
|
|
"listring[current_player;main]"
|
|
)
|
|
meta:set_string("infotext", def.description)
|
|
local inv = meta:get_inventory()
|
|
inv:set_size("main", slots)
|
|
end,
|
|
can_dig = function(pos,player)
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
return inv:is_empty("main")
|
|
end,
|
|
})
|
|
|
|
-- Function for checking underwater
|
|
local check_water
|
|
if not def.underwater then
|
|
check_water = function(pos)
|
|
for _,waterpos in ipairs({
|
|
{ x = pos.x - 1, y = pos.y, z = pos.z - 1 },
|
|
{ x = pos.x + 1, y = pos.y, z = pos.z - 1 },
|
|
{ x = pos.x - 1, y = pos.y, z = pos.z + 1 },
|
|
{ x = pos.x + 1, y = pos.y, z = pos.z + 1 },
|
|
}) do
|
|
for _,water_node in ipairs(water_nodes) do
|
|
if minetest.get_node(waterpos).name == water_node then
|
|
return true -- found nearby water, trigger check
|
|
end
|
|
end
|
|
end
|
|
return false -- did not find nearby water, do not trigger check
|
|
end
|
|
else
|
|
check_water = function()
|
|
return false -- check never triggers
|
|
end
|
|
end
|
|
|
|
if not debug and lootchests.spawn_chests then
|
|
minetest.register_lbm({
|
|
label = S("Upgrade") .. " " .. def.description,
|
|
name = def.name .. "_marker_replace",
|
|
nodenames = def.name .. "_marker",
|
|
run_at_every_load = true,
|
|
action = function(pos, node)
|
|
if check_water(pos) then
|
|
minetest.set_node(pos, {name = "default:water_source", param2 = 0})
|
|
return -- loot chest is underwater and should not be, do not place here
|
|
else
|
|
minetest.set_node(pos, {name = def.name, param2 = 0})
|
|
end
|
|
local rand = PcgRandom(pos.x * pos.y * pos.z)
|
|
local inv = minetest.get_inventory({type = "node", pos = pos})
|
|
for i = 1, slots do
|
|
if rand:next(0,100) <= slot_spawn_chance then
|
|
local item_def = lootchests.loot_table[def.name][rand:next(1, #lootchests.loot_table[def.name])]
|
|
local item_name = item_def[#item_def < 3 and 1 or rand:next(1,#item_def - 1)]
|
|
local stack = ItemStack(item_name)
|
|
if minetest.registered_tools[item_name] then
|
|
stack:set_wear(rand:next(1,65535))
|
|
else
|
|
stack:set_count(rand:next(1, item_def[#item_def]))
|
|
end
|
|
inv:set_stack("main", i, stack)
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
end
|
|
|
|
if def.spawn_in and lootchests.spawn_chests then
|
|
minetest.register_ore({
|
|
ore_type = "scatter",
|
|
ore = def.name .. "_marker",
|
|
wherein = def.spawn_in,
|
|
clust_scarcity = rarity * rarity * rarity,
|
|
clust_num_ores = 1,
|
|
clust_size = 25,
|
|
y_min = ymin,
|
|
y_max = ymax,
|
|
})
|
|
end
|
|
|
|
if def.spawn_on and lootchests.spawn_chests then
|
|
minetest.register_decoration({
|
|
deco_type = "simple",
|
|
place_on = def.spawn_on,
|
|
spawn_by = def.spawn_by,
|
|
num_spawn_by = def.num_spawn_by,
|
|
sidelen = 80,
|
|
fill_ratio = 1/fill_ratio,
|
|
y_min = ymin,
|
|
y_max = ymax,
|
|
flags = "force_placement, all_floors",
|
|
decoration = def.name .. "_marker",
|
|
})
|
|
end
|
|
end
|