Add an isometric area preview on Waypoints
This commit is contained in:
parent
3d9881fd6c
commit
eb5a0a68de
|
@ -13,6 +13,8 @@ read_globals = {
|
|||
"string",
|
||||
"table",
|
||||
"ItemStack",
|
||||
"VoxelArea",
|
||||
"VoxelManip",
|
||||
}
|
||||
|
||||
globals = {
|
||||
|
|
|
@ -14,6 +14,7 @@ This mod requires **Minetest 5.4+**
|
|||
- Progressive Mode¹
|
||||
- Quick Crafting
|
||||
- 3D Player Model Real-Time Preview
|
||||
- Isometric Area Preview
|
||||
- Inventory Sorting (+ options: compression, reverse mode, automation, etc.)
|
||||
- Item List Compression (**`moreblocks`** is supported)
|
||||
- Item Bookmarks
|
||||
|
|
8
init.lua
8
init.lua
|
@ -38,6 +38,8 @@ i3 = {
|
|||
fuel_cache = {},
|
||||
usages_cache = {},
|
||||
recipes_cache = {},
|
||||
content_ids = {},
|
||||
cubes = {},
|
||||
|
||||
tabs = {},
|
||||
craft_types = {},
|
||||
|
@ -49,6 +51,7 @@ i3 = {
|
|||
files = {
|
||||
api = lf("/src/api.lua"),
|
||||
bags = lf("/src/bags.lua"),
|
||||
caches = lf("/src/caches.lua"),
|
||||
callbacks = lf("/src/callbacks.lua"),
|
||||
common = lf("/src/common.lua"),
|
||||
compress = lf("/src/compress.lua"),
|
||||
|
@ -57,7 +60,6 @@ i3 = {
|
|||
gui = lf("/src/gui.lua"),
|
||||
model_alias = lf("/src/model_aliases.lua"),
|
||||
progressive = lf("/src/progressive.lua"),
|
||||
recipes = lf("/src/recipes.lua"),
|
||||
styles = lf("/src/styles.lua"),
|
||||
},
|
||||
|
||||
|
@ -80,7 +82,7 @@ i3.data = dslz(storage:get_string"data") or {}
|
|||
|
||||
local init_bags = i3.files.bags()
|
||||
local init_inventories = i3.files.detached()
|
||||
local init_recipes = i3.files.recipes()
|
||||
local fill_caches = i3.files.caches()
|
||||
|
||||
local function get_lang_code(info)
|
||||
return info and info.lang_code
|
||||
|
@ -208,7 +210,7 @@ local function save_data(player_name)
|
|||
end
|
||||
|
||||
core.register_on_mods_loaded(function()
|
||||
init_recipes()
|
||||
fill_caches()
|
||||
disable_inventories()
|
||||
end)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
local replacements = {fuel = {}}
|
||||
|
||||
local ItemStack = ItemStack
|
||||
local fmt, reg_items, reg_aliases = i3.get("fmt", "reg_items", "reg_aliases")
|
||||
local maxn, copy, insert, sort, match = i3.get("maxn", "copy", "insert", "sort", "match")
|
||||
local fmt, reg_items, reg_aliases, reg_nodes = i3.get("fmt", "reg_items", "reg_aliases", "reg_nodes")
|
||||
local maxn, copy, insert, sort, match, sub = i3.get("maxn", "copy", "insert", "sort", "match", "sub")
|
||||
|
||||
local is_group, extract_groups, item_has_groups, groups_to_items =
|
||||
i3.get("is_group", "extract_groups", "item_has_groups", "groups_to_items")
|
||||
|
@ -286,4 +286,23 @@ local function init_recipes()
|
|||
end
|
||||
end
|
||||
|
||||
return init_recipes
|
||||
local function init_cubes()
|
||||
for name, def in pairs(reg_nodes) do
|
||||
if def and def.drawtype == "normal" or def.drawtype == "liquid" or
|
||||
sub(def.drawtype, 1, 9) == "glasslike" or
|
||||
sub(def.drawtype, 1, 8) == "allfaces" then
|
||||
local id = core.get_content_id(name)
|
||||
i3.content_ids[id] = name
|
||||
|
||||
local tile = def.tiles[1].name or def.tiles[1]
|
||||
local cube = core.inventorycube(tile, tile, tile)
|
||||
|
||||
i3.cubes[name] = cube
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return function()
|
||||
init_recipes()
|
||||
init_cubes()
|
||||
end
|
|
@ -2,8 +2,7 @@ local _, get_inventory_fs = i3.files.gui()
|
|||
|
||||
local set_fs = i3.set_fs
|
||||
local ItemStack = ItemStack
|
||||
local S, clr = i3.get("S", "clr")
|
||||
local min, random = i3.get("min", "random")
|
||||
local S, min, random = i3.get("S", "min", "random")
|
||||
local reg_items, reg_aliases = i3.get("reg_items", "reg_aliases")
|
||||
local fmt, find, match, sub, lower, split = i3.get("fmt", "find", "match", "sub", "lower", "split")
|
||||
local vec_new, vec_eq, vec_round = i3.get("vec_new", "vec_eq", "vec_round")
|
||||
|
@ -78,18 +77,25 @@ i3.new_tab("inventory", {
|
|||
|
||||
elseif find(field, "waypoint_%d+") then
|
||||
local id, action = match(field, "_(%d+)_(%w+)$")
|
||||
id = tonumber(id)
|
||||
id = tonumber(id)
|
||||
local waypoint = data.waypoints[id]
|
||||
if not waypoint then return end
|
||||
|
||||
if action == "delete" then
|
||||
if action == "see" then
|
||||
if data.waypoint_see and data.waypoint_see == id then
|
||||
data.waypoint_see = nil
|
||||
else
|
||||
data.waypoint_see = id
|
||||
end
|
||||
|
||||
elseif action == "delete" then
|
||||
player:hud_remove(waypoint.id)
|
||||
remove(data.waypoints, id)
|
||||
|
||||
elseif action == "teleport" then
|
||||
local pos = vec_new(str_to_pos(waypoint.pos))
|
||||
safe_teleport(player, pos)
|
||||
msg(name, fmt("Teleported to %s", clr("#ff0", waypoint.name)))
|
||||
msg(name, S("Teleported to: @1", waypoint.name))
|
||||
|
||||
elseif action == "refresh" then
|
||||
local color = random(0xffffff)
|
||||
|
@ -116,6 +122,7 @@ i3.new_tab("inventory", {
|
|||
if fields.quit then
|
||||
data.confirm_trash = nil
|
||||
data.show_settings = nil
|
||||
data.waypoint_see = nil
|
||||
|
||||
elseif fields.trash then
|
||||
data.show_settings = nil
|
||||
|
@ -140,6 +147,9 @@ i3.new_tab("inventory", {
|
|||
elseif fields.close_settings then
|
||||
data.show_settings = nil
|
||||
|
||||
elseif fields.close_preview then
|
||||
data.waypoint_see = nil
|
||||
|
||||
elseif fields.sort then
|
||||
sort_inventory(player, data)
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
local ItemStack = ItemStack
|
||||
local loadstring = loadstring
|
||||
|
||||
local vec_add, vec_mul = vector.add, vector.multiply
|
||||
local sort, concat, insert = table.sort, table.concat, table.insert
|
||||
local min, floor, ceil = math.min, math.floor, math.ceil
|
||||
local fmt, find, match, gmatch, sub, split, lower =
|
||||
|
@ -319,7 +321,7 @@ local function spawn_item(player, stack)
|
|||
local dir = player:get_look_dir()
|
||||
local ppos = player:get_pos()
|
||||
ppos.y = ppos.y + player:get_properties().eye_height
|
||||
local look_at = vector.add(ppos, vector.multiply(dir, 1))
|
||||
local look_at = vec_add(ppos, vec_mul(dir, 1))
|
||||
|
||||
core.add_item(look_at, stack)
|
||||
end
|
||||
|
@ -410,7 +412,7 @@ local function safe_teleport(player, pos)
|
|||
|
||||
pos.y = pos.y + 0.5
|
||||
local vel = player:get_velocity()
|
||||
player:add_velocity(vector.multiply(vel, -1))
|
||||
player:add_velocity(vec_mul(vel, -1))
|
||||
player:set_pos(pos)
|
||||
end
|
||||
|
||||
|
@ -691,6 +693,8 @@ local _ = {
|
|||
-- Vectors
|
||||
vec_new = vector.new,
|
||||
vec_add = vector.add,
|
||||
vec_sub = vector.subtract,
|
||||
vec_mul = vector.multiply,
|
||||
vec_round = vector.round,
|
||||
vec_eq = vector.equals,
|
||||
}
|
||||
|
|
87
src/gui.lua
87
src/gui.lua
|
@ -4,16 +4,19 @@ local model_aliases = i3.files.model_alias()
|
|||
local PNG, styles, fs_elements, colors = i3.files.styles()
|
||||
|
||||
local ItemStack = ItemStack
|
||||
local VoxelArea, VoxelManip = VoxelArea, VoxelManip
|
||||
|
||||
local S, ES, translate = i3.get("S", "ES", "translate")
|
||||
local clr, ESC, check_privs = i3.get("clr", "ESC", "check_privs")
|
||||
local vec_new, vec_sub, vec_round = i3.get("vec_new", "vec_sub", "vec_round")
|
||||
local min, max, floor, ceil, round = i3.get("min", "max", "floor", "ceil", "round")
|
||||
local sprintf, find, match, sub, upper = i3.get("fmt", "find", "match", "sub", "upper")
|
||||
local reg_items, reg_tools, reg_entities = i3.get("reg_items", "reg_tools", "reg_entities")
|
||||
local maxn, sort, concat, copy, insert, remove, unpack =
|
||||
i3.get("maxn", "sort", "concat", "copy", "insert", "remove", "unpack")
|
||||
|
||||
local true_str, is_fav, is_num, get_group =
|
||||
i3.get("true_str", "is_fav", "is_num", "get_group")
|
||||
local true_str, is_fav, is_num, get_group, str_to_pos =
|
||||
i3.get("true_str", "is_fav", "is_num", "get_group", "str_to_pos")
|
||||
local groups_to_items, compression_active, compressible =
|
||||
i3.get("groups_to_items", "compression_active", "compressible")
|
||||
local get_sorting_idx, is_group, extract_groups, item_has_groups =
|
||||
|
@ -224,6 +227,45 @@ local function get_award_list(data, fs, ctn_len, yextra, award_list, awards_unlo
|
|||
end
|
||||
end
|
||||
|
||||
local function get_isometric_view(fs, pos, X, Y)
|
||||
pos = vec_round(pos)
|
||||
local size = 0.25
|
||||
local width = 8
|
||||
|
||||
local pos1 = vec_new(pos.x - width, pos.y - 1, pos.z - width)
|
||||
local pos2 = vec_new(pos.x + width, pos.y + 3, pos.z + width)
|
||||
core.emerge_area(pos1, pos2)
|
||||
|
||||
local vm = VoxelManip(pos1, pos2)
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
|
||||
local data = vm:get_data()
|
||||
|
||||
local t = {}
|
||||
data[0] = #data
|
||||
|
||||
for i = 1, data[0] do
|
||||
local id = data[i]
|
||||
t[i] = i3.content_ids[id]
|
||||
end
|
||||
|
||||
for idx in area:iterp(pos1, pos2) do
|
||||
local name = t[idx]
|
||||
local cube = i3.cubes[name]
|
||||
|
||||
if cube then
|
||||
local p = area:position(idx)
|
||||
p = vec_sub(p, pos)
|
||||
|
||||
local x = 2 + (size / 2 * (p.z - p.x))
|
||||
local y = 1.15 + (size / 4 * (p.x + p.z - 2 * p.y))
|
||||
local elem = fmt("image[%f,%f;%.1f,%.1f;%s]", x + X, y + Y, size, size, cube)
|
||||
|
||||
insert(fs, elem)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
|
||||
fs(fmt("box[0,%f;4.9,0.6;#bababa25]", yextra + 1.1))
|
||||
fs("label", 0, yextra + 0.85, ES"Waypoint name:")
|
||||
|
@ -254,10 +296,19 @@ local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
|
|||
hex = "0" .. hex
|
||||
end
|
||||
|
||||
local teleport_priv = check_privs(player, {teleport = true})
|
||||
local waypoint_preview = data.waypoint_see and data.waypoint_see == i
|
||||
|
||||
fs("label", 0.15, y + 0.33, clr(fmt("#%s", hex), waypoint_name))
|
||||
fs("tooltip", 0, y, ctn_len - 2.5, 0.65,
|
||||
fmt("Name: %s\nPosition:%s", clr("#dbeeff", v.name),
|
||||
v.pos:sub(2,-2):gsub("(%-*%d*%.?%d+)", clr("#dbeeff", " %1"))))
|
||||
|
||||
local tooltip = fmt("Name: %s\nPosition:%s", clr("#dbeeff", v.name),
|
||||
v.pos:sub(2,-2):gsub("(%-*%d*%.?%d+)", clr("#dbeeff", " %1")))
|
||||
|
||||
if teleport_priv then
|
||||
tooltip = fmt("%s\n%s", tooltip, clr("#ff0", ES"[Click to teleport]"))
|
||||
end
|
||||
|
||||
fs("tooltip", 0, y, ctn_len - 2.1, 0.65, tooltip)
|
||||
|
||||
local del = fmt("waypoint_%u_delete", i)
|
||||
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]", del, PNG.trash, PNG.trash_hover))
|
||||
|
@ -269,17 +320,31 @@ local function get_waypoint_fs(fs, data, player, yextra, ctn_len)
|
|||
fs("image_button", ctn_len - 1, yi, icon_size, icon_size, "", rfs, "")
|
||||
fs(fmt("tooltip[%s;%s]", rfs, ES"Change color"))
|
||||
|
||||
local see = fmt("waypoint_%u_see", i)
|
||||
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
|
||||
see, waypoint_preview and PNG.search_hover or PNG.search, PNG.search, PNG.search_hover))
|
||||
fs("image_button", ctn_len - 1.5, yi, icon_size, icon_size, "", see, "")
|
||||
fs(fmt("tooltip[%s;%s]", see, ES"Preview the waypoint area"))
|
||||
|
||||
local vsb = fmt("waypoint_%u_hide", i)
|
||||
fs(fmt("style[%s;fgimg=%s;content_offset=0]", vsb, v.hide and PNG.nonvisible or PNG.visible))
|
||||
fs("image_button", ctn_len - 1.5, yi, icon_size, icon_size, "", vsb, "")
|
||||
fs("image_button", ctn_len - 2, yi, icon_size, icon_size, "", vsb, "")
|
||||
fs(fmt("tooltip[%s;%s]", vsb, v.hide and ES"Show waypoint" or ES"Hide waypoint"))
|
||||
|
||||
if check_privs(player, {teleport = true}) then
|
||||
if teleport_priv then
|
||||
local tp = fmt("waypoint_%u_teleport", i)
|
||||
fs(fmt("style[%s;fgimg=%s;fgimg_hovered=%s;content_offset=0]",
|
||||
tp, PNG.teleport, PNG.teleport_hover))
|
||||
fs("image_button", ctn_len - 2, yi, icon_size, icon_size, "", tp, "")
|
||||
fs(fmt("tooltip[%s;%s]", tp, ES"Teleport to waypoint"))
|
||||
fs("button", 0, y, ctn_len - 2.1, 0.6, tp, "")
|
||||
end
|
||||
|
||||
if waypoint_preview then
|
||||
fs("image", 0.25, y - 3.5, 5, 4, PNG.bg_content)
|
||||
fs("button", 0.25, y - 3.35, 5, 0.55, "area_preview", v.name)
|
||||
fs("image_button", 4.65, y - 3.25, 0.25, 0.25,
|
||||
PNG.cancel_hover .. "^\\[brighten", "close_preview", "")
|
||||
|
||||
local pos = vec_new(str_to_pos(data.waypoints[i].pos))
|
||||
get_isometric_view(fs, pos, 0.6, y - 2.5)
|
||||
fs("image", 2.7, y - 1.5, 0.3, 0.3, PNG.flag)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@ local PNG = {
|
|||
awards = "i3_award.png",
|
||||
skins = "i3_skin.png",
|
||||
waypoints = "i3_waypoint.png",
|
||||
teleport = "i3_teleport.png",
|
||||
add = "i3_add.png",
|
||||
refresh = "i3_refresh.png",
|
||||
visible = "i3_visible.png^\\[brighten",
|
||||
nonvisible = "i3_non_visible.png",
|
||||
exit = "i3_exit.png",
|
||||
home = "i3_home.png",
|
||||
flag = "i3_flag.png",
|
||||
|
||||
cancel_hover = "i3_cancel.png^\\[brighten",
|
||||
search_hover = "i3_search.png^\\[brighten",
|
||||
|
@ -57,7 +57,6 @@ local PNG = {
|
|||
awards_hover = "i3_award_hover.png",
|
||||
skins_hover = "i3_skin_hover.png",
|
||||
waypoints_hover = "i3_waypoint_hover.png",
|
||||
teleport_hover = "i3_teleport.png^\\[brighten",
|
||||
add_hover = "i3_add.png^\\[brighten",
|
||||
refresh_hover = "i3_refresh.png^\\[brighten",
|
||||
exit_hover = "i3_exit.png^\\[brighten",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 818 B |
Binary file not shown.
Before Width: | Height: | Size: 864 B |
Ŝarĝante…
Reference in New Issue