write something there

This commit is contained in:
N-Nachtigal 2025-05-04 16:01:41 +02:00
commit b4b6c08f4f
8546 changed files with 309825 additions and 0 deletions

View file

@ -0,0 +1,197 @@
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

View file

@ -0,0 +1 @@
default

View file

@ -0,0 +1 @@
An API for registering various loot containers

View file

@ -0,0 +1,70 @@
To spawn the lootchests, world is populated by spawn chest markers of corresponding type.
During the normal gameplay, they are of "airlike" type and are replaced with LBM which replaces them with corresponding chests and fill them with loot.
If minetest.conf setting "lootchests_debug = true" is active, markers are not replaced and can be taken from the creative inventory.
This can be used for placing them manually for various purposes, mainly for adding lootchest markers to schematics.
Creating a lootchest consists of two parts: defining the lootchest itself with lootchests.register_lootchest(def)
and creating a corresponding loot table in lootchests.loot_table[def.name]. Examples are below.
Example of a lootchest definition:
lootchests.register_lootchest({
--Mandatory
name = "lootchests:default_chest", --ID of the lootchest. A table with corresponding key should be created in tables.loot_table
description = "Loot Chest", --Name as it appears in inventory, also lootchest infobox
--Visuals
drawtype = "nodebox", --Drawtype of the node. Don't define for default node look
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
}, --Nodebox def if drawtype is "nodebox"
tiles = {
"default_chest_top.png",
"default_chest_top.png",
"default_chest_side.png",
"default_chest_side.png",
"default_chest_front.png",
}, --Node tile definition
--Sounds and groups
sounds = default.node_sound_wood_defaults(), --Node sound definition
groups = {choppy = 2, oddly_breakable_by_hand = 2}, --Node groups
--Spawning
spawn_in = {"default:sand", "default:desert_sand"}, --Spawn in which nodes, may be one itemstring or a list of them
spawn_on = {"default:stone", "default:desert_stone"}, --Spawn on which nodes, may be one itemstring or a list of them
spawn_in_rarity = 25, --Spawn in rarity, approximate spacing between each node
spawn_on_rarity = 1000. --Spawn on rarity, spawns one out of defined value (if default is 1000 then on 1 out of 1000)
--Height limit
ymax = 5, --Max Y limit
ymin = -64, --Min Y limit
--Container parameters
slot_spawn_chance = 50, --Chance to spawn something in a container slot. Ranges from 0 to 100
slots = 32, --Total amount of slots in the container. Max is 32
})
To actually add loot to your lootchests, you need to define a loot table in lootchests.loot_table. Table must be accessible by the key which equals to
the lootchest ID.
Example of a loot table definition for "lootchests:default_chest":
lootchests.loot_table["lootchests:default_chest"] = {
{"default:stick", 16}, --Each item definition is a table with 2 elements - their itemstring and maximum amount
{"default:axe_stone"}, --If defined item is a tool, it doesn't need an amount definition, there will always be one anyway
--Tools spawn with random wear instead
{"default:stone", 64},
}
Third-party mods can also access and modify loot tables, you can add custom items to them manually, or by using
lootchests.add_to_loot_table(key, items), where "key" is the lootchest ID and "items" is another table with loot.
Example:
local items = {
{"custom_mod:custom_item_01", 15},
{"custom_mod:custom_item_02", 32},
}
lootchests.add_to_loot_table("lootchests:default_chest", items)

View file

@ -0,0 +1 @@
dofile(minetest.get_modpath("lootchests").."/api.lua")

View file

@ -0,0 +1,6 @@
# textdomain: lootchests
[lootchests] Missing fields in chest definition!=[lootchests] Отсутствуют поля в определении сундука!
[lootchests] Missing loot table for=[lootchests] Отсутствует таблица добычи для
Spawn Marker=Маркер появления
Upgrade=Обновление

View file

@ -0,0 +1 @@
name = lootchests

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B