i3/src/api.lua

500 lines
11 KiB
Lua
Raw Permalink Normal View History

local http = ...
2022-01-08 17:05:29 +01:00
local make_fs, get_inventory_fs = i3.files.gui()
IMPORT("sorter", "sort_inventory", "play_sound")
2021-11-29 19:15:14 +01:00
IMPORT("sort", "concat", "copy", "insert", "remove")
IMPORT("get_player_by_name", "add_hud_waypoint", "init_hud_notif")
2023-01-07 12:28:07 +01:00
IMPORT("gmatch", "split", "S", "err", "fmt", "reg_items", "pos_to_str")
2021-11-29 19:15:14 +01:00
IMPORT("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name")
function i3.register_craft_type(name, def)
if not true_str(name) then
return err "i3.register_craft_type: name missing"
2021-10-25 20:31:20 +02:00
elseif not true_table(def) then
return err "i3.register_craft_type: definition missing"
elseif not is_str(def.description) then
def.description = ""
end
i3.craft_types[name] = def
end
function i3.register_craft(def)
local width, c = 0, 0
2021-12-24 00:36:13 +01:00
if http and true_str(def.url) then
http.fetch({url = def.url}, function(result)
if result.succeeded then
local t = core.parse_json(result.data)
if is_table(t) then
return i3.register_craft(t)
end
end
end)
return
end
2021-10-25 05:31:58 +02:00
if not true_table(def) then
return err "i3.register_craft: craft definition missing"
end
if #def > 1 then
for _, v in pairs(def) do
i3.register_craft(v)
end
return
end
if def.result then
def.output = def.result -- Backward compatibility
def.result = nil
end
2021-12-24 00:36:13 +01:00
if not true_str(def.output) and not def.url then
return err "i3.register_craft: output missing"
end
if not is_table(def.items) then
def.items = {}
end
if def.grid then
if not is_table(def.grid) then
def.grid = {}
end
if not is_table(def.key) then
def.key = {}
end
local cp = copy(def.grid)
2021-12-24 00:36:13 +01:00
sort(cp, function(a, b) return #a > #b end)
width = #cp[1]
for i = 1, #def.grid do
while #def.grid[i] < width do
def.grid[i] = def.grid[i] .. " "
end
end
for symbol in gmatch(concat(def.grid), ".") do
2021-11-29 02:47:36 +01:00
c++
def.items[c] = def.key[symbol]
end
else
2021-12-24 00:36:13 +01:00
local items = copy(def.items)
2021-12-25 17:23:49 +01:00
local lines = {}
def.items = {}
2021-12-25 17:23:49 +01:00
for i = 1, #items do
lines[i] = split(items[i], ",", true)
2021-12-25 17:23:49 +01:00
if #lines[i] > width then
width = #lines[i]
end
end
2021-12-25 17:23:49 +01:00
for i = 1, #items do
while #lines[i] < width do
insert(lines[i], items[i])
end
end
2021-12-25 17:23:49 +01:00
for _, line in ipairs(lines) do
2021-12-24 00:36:13 +01:00
for _, v in ipairs(line) do
c++
def.items[c] = clean_name(v)
end
end
end
2021-11-22 17:37:28 +01:00
local item = ItemStack(def.output):get_name()
i3.recipes_cache[item] = i3.recipes_cache[item] or {}
def.custom = true
def.width = width
insert(i3.recipes_cache[item], def)
end
function i3.add_recipe_filter(name, f)
if not true_str(name) then
return err "i3.add_recipe_filter: name missing"
elseif not is_func(f) then
return err "i3.add_recipe_filter: function missing"
end
i3.recipe_filters[name] = f
end
function i3.set_recipe_filter(name, f)
if not is_str(name) then
return err "i3.set_recipe_filter: name missing"
elseif not is_func(f) then
return err "i3.set_recipe_filter: function missing"
end
i3.recipe_filters = {[name] = f}
end
function i3.add_search_filter(name, f)
if not true_str(name) then
return err "i3.add_search_filter: name missing"
elseif not is_func(f) then
return err "i3.add_search_filter: function missing"
end
i3.search_filters[name] = f
end
function i3.get_recipes(item)
item = core.registered_aliases[item] or item
local recipes = i3.recipes_cache[item]
local usages = i3.usages_cache[item]
return {recipes = recipes, usages = usages}
end
function i3.set_fs(player)
if not player or player.is_fake_player then return end
local name = player:get_player_name()
local data = i3.data[name]
if not data then return end
if data.auto_sorting then
sort_inventory(player, data)
end
2022-03-21 00:06:51 +01:00
for i, tab in ipairs(i3.tabs) do
if data.tab == i and tab.access and not tab.access(player, data) then
data.tab = 1
break
end
end
local fs = make_fs(player, data)
player:set_inventory_formspec(fs)
end
function i3.new_tab(name, def)
if not true_str(name) then
return err "i3.new_tab: tab name missing"
elseif not true_table(def) then
return err "i3.new_tab: tab definition missing"
2021-10-25 20:31:20 +02:00
elseif not true_str(def.description) then
return err "i3.new_tab: description missing"
2021-10-25 20:31:20 +02:00
elseif #i3.tabs == 6 then
return err(fmt("i3.new_tab: cannot add '%s' tab. Limit reached (6).", def.name))
end
def.name = name
insert(i3.tabs, def)
end
2022-01-08 17:05:29 +01:00
i3.new_tab("inventory", {
description = S"Inventory",
formspec = get_inventory_fs,
slots = true,
2022-01-08 17:05:29 +01:00
})
function i3.remove_tab(name)
if not true_str(name) then
return err "i3.remove_tab: tab name missing"
end
2023-02-01 04:17:03 +01:00
for i = #i3.tabs, 2, -1 do
2023-01-07 12:28:07 +01:00
local def = i3.tabs[i]
if def and name == def.name then
remove(i3.tabs, i)
end
end
end
function i3.get_current_tab(player)
local name = player:get_player_name()
local data = i3.data[name]
2021-11-01 15:34:10 +01:00
return data.tab
end
function i3.set_tab(player, tabname)
local name = player:get_player_name()
local data = i3.data[name]
if not tabname or tabname == "" then
2021-11-01 15:34:10 +01:00
data.tab = 0
return
end
2022-03-21 00:06:51 +01:00
for i, tab in ipairs(i3.tabs) do
if tab.name == tabname then
2021-11-01 15:34:10 +01:00
data.tab = i
return
end
end
err(fmt("i3.set_tab: tab name '%s' does not exist", tabname))
end
function i3.override_tab(name, newdef)
if not true_str(name) then
return err "i3.override_tab: tab name missing"
elseif not true_table(newdef) then
return err "i3.override_tab: tab definition missing"
2021-10-25 20:31:20 +02:00
elseif not true_str(newdef.description) then
return err "i3.override_tab: description missing"
end
newdef.name = name
for i, def in ipairs(i3.tabs) do
if def.name == name then
i3.tabs[i] = newdef
break
end
end
end
i3.register_craft_type("digging", {
description = S"Digging",
icon = "i3_steelpick.png",
})
i3.register_craft_type("digging_chance", {
description = S"Digging (by chance)",
icon = "i3_mesepick.png",
})
i3.add_search_filter("groups", function(item, groups)
local def = reg_items[item]
local has_groups = true
for _, group in ipairs(groups) do
if not def.groups[group] then
has_groups = nil
break
end
end
return has_groups
end)
2021-10-25 00:14:21 +02:00
function i3.compress(item, def)
if not true_str(item) then
return err "i3.compress: item name missing"
2021-10-25 20:31:20 +02:00
elseif not true_table(def) then
2021-10-25 00:14:21 +02:00
return err "i3.compress: replace definition missing"
2021-10-25 20:31:20 +02:00
elseif not true_str(def.replace) then
2021-10-25 00:14:21 +02:00
return err "i3.compress: replace string missing"
2021-10-25 20:31:20 +02:00
elseif not is_table(def.by) then
2021-10-25 00:14:21 +02:00
return err "i3.compress: replace substrings missing"
2021-11-07 22:31:47 +01:00
elseif i3.compressed[item] then
return err(fmt("i3.compress: item '%s' is already compressed", item))
2021-10-25 00:14:21 +02:00
end
local t = {}
i3.compress_groups[item] = i3.compress_groups[item] or {}
for _, str in ipairs(def.by) do
local it = item:gsub(def.replace, str)
insert(t, it)
insert(i3.compress_groups[item], it)
i3.compressed[it] = true
end
end
2021-11-26 03:32:04 +01:00
function i3.hud_notif(name, msg, img)
if not true_str(name) then
return err "i3.hud_notif: player name missing"
elseif not true_str(msg) then
return err "i3.hud_notif: message missing"
end
local data = i3.data[name]
if not data then
return err "i3.hud_notif: no player data initialized"
end
local player = get_player_by_name(name)
2023-04-01 22:51:21 +02:00
if not player then return end
2023-04-02 01:23:11 +02:00
local max_y = -125
2021-11-26 03:32:04 +01:00
local def = {
show = true,
2023-04-01 22:45:18 +02:00
max = {x = -330, y = max_y},
hud_msg = msg,
hud_img = img and fmt("%s^[resize:64x64", img) or nil,
hud_timer = 0,
elems = init_hud_notif(player),
}
insert(data.hud.notifs, def)
play_sound(name, "i3_achievement", 1.0)
local nb_notifs = #data.hud.notifs
for i = 1, nb_notifs - 1 do
local notif = data.hud.notifs[i]
if notif then
notif.show = true
2023-04-01 22:45:18 +02:00
notif.max.y = ((nb_notifs - i) + 1) * max_y
2023-04-02 00:45:39 +02:00
notif.hud_timer = 0.5 * (nb_notifs - i)
end
2021-11-26 03:32:04 +01:00
end
end
2021-11-19 19:35:41 +01:00
function i3.add_sorting_method(name, def)
if not true_str(name) then
return err "i3.add_sorting_method: name missing"
2021-11-19 19:35:41 +01:00
elseif not true_table(def) then
return err "i3.add_sorting_method: definition missing"
elseif not is_func(def.func) then
return err "i3.add_sorting_method: function missing"
end
2021-11-19 19:35:41 +01:00
def.name = name
insert(i3.sorting_methods, def)
end
2021-11-19 19:35:41 +01:00
i3.add_sorting_method("alphabetical", {
description = S"Sort items by name (A-Z)",
func = function(list, data)
2022-07-03 19:39:07 +02:00
sorter(list, data, 1)
2021-11-02 01:35:30 +01:00
return list
end
2021-11-19 19:35:41 +01:00
})
2021-11-19 19:35:41 +01:00
i3.add_sorting_method("numerical", {
description = S"Sort items by number of items per stack",
func = function(list, data)
2022-07-03 19:39:07 +02:00
sorter(list, data, 2)
2021-11-02 01:35:30 +01:00
return list
end,
2021-11-19 19:35:41 +01:00
})
2023-01-07 12:28:07 +01:00
function i3.add_waypoint(name, def)
if not true_str(name) then
return err "i3.add_waypoint: name missing"
elseif not true_table(def) then
return err "i3.add_waypoint: definition missing"
elseif not true_str(def.player) then
return err "i3.add_waypoint: player name missing"
end
local data = i3.data[def.player]
if not data then
return err "i3.add_waypoint: no player data initialized"
end
local player = get_player_by_name(def.player)
local id = player and add_hud_waypoint(player, name, def.pos, def.color, def.image) or nil
insert(data.waypoints, {
name = name,
pos = pos_to_str(def.pos, 1),
color = def.color,
image = def.image,
id = id,
})
if data.subcat == 5 then
data.scrbar_inv += 1000
end
i3.set_fs(player)
end
function i3.remove_waypoint(player_name, name)
if not true_str(player_name) then
return err "i3.remove_waypoint: player name missing"
elseif not true_str(name) then
return err "i3.remove_waypoint: waypoint name missing"
end
local data = i3.data[player_name]
if not data then
return err "i3.remove_waypoint: no player data initialized"
end
local player = get_player_by_name(player_name)
for i = #data.waypoints, 1, -1 do
local waypoint = data.waypoints[i]
if waypoint and name == waypoint.name then
if player then
player:hud_remove(waypoint.id)
end
remove(data.waypoints, i)
end
end
i3.set_fs(player)
end
function i3.get_waypoints(player_name)
if not true_str(player_name) then
return err "i3.get_waypoints: player name missing"
end
local data = i3.data[player_name]
if not data then
return err "i3.get_waypoints: no player data initialized"
end
return data.waypoints
end
2023-01-19 01:24:45 +01:00
function i3.new_minitab(name, def)
if #i3.minitabs == 6 then
return err "i3.new_minitab: limit reached (6)"
elseif not true_str(name) then
2023-01-19 16:40:31 +01:00
return err "i3.new_minitab: name missing"
2023-01-19 01:24:45 +01:00
elseif not true_table(def) then
return err "i3.new_minitab: definition missing"
end
2023-01-19 18:57:16 +01:00
def.name = name
insert(i3.minitabs, def)
2023-01-19 01:24:45 +01:00
end
2023-01-19 16:40:31 +01:00
function i3.remove_minitab(name)
if not true_str(name) then
return err "i3.remove_minitab: name missing"
end
2023-02-01 04:17:03 +01:00
for i = #i3.minitabs, 2, -1 do
2023-01-19 16:40:31 +01:00
local v = i3.minitabs[i]
if v and v.name == name then
remove(i3.minitabs, i)
end
end
end
2023-01-19 18:57:16 +01:00
i3.new_minitab("all", {
description = "All",
2023-01-19 16:40:31 +01:00
sorter = function()
return true
end
})
2023-01-19 18:57:16 +01:00
i3.new_minitab("nodes", {
description = "Nodes",
2023-01-19 16:40:31 +01:00
sorter = function(item)
return core.registered_nodes[item]
end
})
2023-01-19 18:57:16 +01:00
i3.new_minitab("items", {
description = "Items",
2023-01-19 16:40:31 +01:00
sorter = function(item)
return core.registered_craftitems[item] or core.registered_tools[item]
end
})