Add an isometric area preview on Waypoints

This commit is contained in:
Jean-Patrick Guerrero 2021-11-25 04:22:46 +01:00
parent 3d9881fd6c
commit eb5a0a68de
10 changed files with 128 additions and 26 deletions

View File

@ -13,6 +13,8 @@ read_globals = {
"string",
"table",
"ItemStack",
"VoxelArea",
"VoxelManip",
}
globals = {

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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,
}

View File

@ -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

View File

@ -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",

BIN
textures/i3_flag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B