API: Add i3.hud_notif
This commit is contained in:
parent
40a8c548ab
commit
54ba95ac80
8
API.md
8
API.md
|
@ -301,6 +301,14 @@ A map of all compressed item groups, indexed by stereotypes.
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
|
#### `i3.hud_notif(name, msg[, img])`
|
||||||
|
|
||||||
|
Shows a Steam-like HUD notification on the bottom-right corner of the screen (experimental).
|
||||||
|
|
||||||
|
- `name` is the player name.
|
||||||
|
- `msg` is the HUD message to show.
|
||||||
|
- `img` (optional) is the HUD image to show (preferably 16x16 px).
|
||||||
|
|
||||||
#### `i3.get_recipes(item)`
|
#### `i3.get_recipes(item)`
|
||||||
|
|
||||||
Returns a table of recipes and usages of `item`.
|
Returns a table of recipes and usages of `item`.
|
||||||
|
|
14
init.lua
14
init.lua
|
@ -16,6 +16,9 @@ i3 = {
|
||||||
MIN_FORMSPEC_VERSION = 4,
|
MIN_FORMSPEC_VERSION = 4,
|
||||||
SAVE_INTERVAL = 600, -- Player data save interval (in seconds)
|
SAVE_INTERVAL = 600, -- Player data save interval (in seconds)
|
||||||
|
|
||||||
|
HUD_TIMER_MAX = 1.5,
|
||||||
|
HUD_SPEED = 1,
|
||||||
|
|
||||||
SUBCAT = {
|
SUBCAT = {
|
||||||
"bag",
|
"bag",
|
||||||
"armor",
|
"armor",
|
||||||
|
@ -57,6 +60,7 @@ i3 = {
|
||||||
detached = lf("/src/detached_inv.lua"),
|
detached = lf("/src/detached_inv.lua"),
|
||||||
groups = lf("/src/groups.lua"),
|
groups = lf("/src/groups.lua"),
|
||||||
gui = lf("/src/gui.lua"),
|
gui = lf("/src/gui.lua"),
|
||||||
|
hud = lf("/src/hud.lua"),
|
||||||
model_alias = lf("/src/model_aliases.lua"),
|
model_alias = lf("/src/model_aliases.lua"),
|
||||||
progressive = lf("/src/progressive.lua"),
|
progressive = lf("/src/progressive.lua"),
|
||||||
styles = lf("/src/styles.lua"),
|
styles = lf("/src/styles.lua"),
|
||||||
|
@ -82,6 +86,7 @@ i3.data = dslz(storage:get_string"data") or {}
|
||||||
local init_bags = i3.files.bags()
|
local init_bags = i3.files.bags()
|
||||||
local init_inventories = i3.files.detached()
|
local init_inventories = i3.files.detached()
|
||||||
local fill_caches = i3.files.caches()
|
local fill_caches = i3.files.caches()
|
||||||
|
local init_hud = i3.files.hud()
|
||||||
|
|
||||||
local function get_lang_code(info)
|
local function get_lang_code(info)
|
||||||
return info and info.lang_code
|
return info and info.lang_code
|
||||||
|
@ -183,13 +188,6 @@ local function init_waypoints(player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function init_hudbar(player)
|
|
||||||
core.after(0, function()
|
|
||||||
player:hud_set_hotbar_itemcount(i3.HOTBAR_LEN)
|
|
||||||
player:hud_set_hotbar_image"i3_hotbar.png"
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function save_data(player_name)
|
local function save_data(player_name)
|
||||||
local _data = copy(i3.data)
|
local _data = copy(i3.data)
|
||||||
|
|
||||||
|
@ -225,7 +223,7 @@ core.register_on_joinplayer(function(player)
|
||||||
init_bags(player)
|
init_bags(player)
|
||||||
init_inventories(player)
|
init_inventories(player)
|
||||||
init_waypoints(player)
|
init_waypoints(player)
|
||||||
init_hudbar(player)
|
init_hud(player)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
core.register_on_leaveplayer(function(player)
|
core.register_on_leaveplayer(function(player)
|
||||||
|
|
21
src/api.lua
21
src/api.lua
|
@ -298,6 +298,27 @@ function i3.compress(item, def)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
data.show_hud = true
|
||||||
|
data.hud_msg = msg
|
||||||
|
|
||||||
|
if img then
|
||||||
|
data.hud_img = fmt("%s^[resize:16x16", img)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function i3.add_sorting_method(name, def)
|
function i3.add_sorting_method(name, def)
|
||||||
if not true_str(name) then
|
if not true_str(name) then
|
||||||
return err "i3.add_sorting_method: name missing"
|
return err "i3.add_sorting_method: name missing"
|
||||||
|
|
|
@ -410,10 +410,12 @@ local function safe_teleport(player, pos)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
play_sound(name, "i3_teleport", 0.8)
|
play_sound(name, "i3_teleport", 0.8)
|
||||||
|
|
||||||
local p = vec_new(pos)
|
|
||||||
p.y = p.y + 0.25
|
|
||||||
local vel = player:get_velocity()
|
local vel = player:get_velocity()
|
||||||
player:add_velocity(vec_mul(vel, -1))
|
player:add_velocity(vec_mul(vel, -1))
|
||||||
|
|
||||||
|
local p = vec_new(pos)
|
||||||
|
p.y = p.y + 0.25
|
||||||
|
|
||||||
player:set_pos(p)
|
player:set_pos(p)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -638,6 +640,7 @@ local _ = {
|
||||||
pos_to_str = core.pos_to_string,
|
pos_to_str = core.pos_to_string,
|
||||||
str_to_pos = core.string_to_pos,
|
str_to_pos = core.string_to_pos,
|
||||||
check_privs = core.check_player_privs,
|
check_privs = core.check_player_privs,
|
||||||
|
get_player_by_name = core.get_player_by_name,
|
||||||
|
|
||||||
-- Inventory
|
-- Inventory
|
||||||
get_stack = get_stack,
|
get_stack = get_stack,
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
local get_player_by_name = i3.get("get_player_by_name")
|
||||||
|
|
||||||
|
local function init_hud(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local data = i3.data[name]
|
||||||
|
|
||||||
|
data.hud = {
|
||||||
|
bg = player:hud_add {
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.78, y = 1},
|
||||||
|
alignment = {x = 1, y = 1},
|
||||||
|
scale = {x = 370, y = 112},
|
||||||
|
text = "i3_bg.png",
|
||||||
|
z_index = 0xDEAD,
|
||||||
|
},
|
||||||
|
|
||||||
|
img = player:hud_add {
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.79, y = 1.02},
|
||||||
|
alignment = {x = 1, y = 1},
|
||||||
|
scale = {x = 4, y = 4},
|
||||||
|
text = "",
|
||||||
|
z_index = 0xDEAD,
|
||||||
|
},
|
||||||
|
|
||||||
|
text = player:hud_add {
|
||||||
|
hud_elem_type = "text",
|
||||||
|
position = {x = 0.84, y = 1.04},
|
||||||
|
alignment = {x = 1, y = 1},
|
||||||
|
number = 0xffffff,
|
||||||
|
text = "",
|
||||||
|
z_index = 0xDEAD,
|
||||||
|
style = 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
core.after(0, function()
|
||||||
|
player:hud_set_hotbar_itemcount(i3.HOTBAR_LEN)
|
||||||
|
player:hud_set_hotbar_image"i3_hotbar.png"
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function show_hud(player, data)
|
||||||
|
-- It would better to have an engine function `hud_move` to only need
|
||||||
|
-- 2 calls for the notification's back and forth.
|
||||||
|
|
||||||
|
local hud_info_bg = player:hud_get(data.hud.bg)
|
||||||
|
local dt = 0.016
|
||||||
|
|
||||||
|
if hud_info_bg.position.y <= 0.9 then
|
||||||
|
data.show_hud = false
|
||||||
|
data.hud_timer = (data.hud_timer or 0) + dt
|
||||||
|
end
|
||||||
|
|
||||||
|
player:hud_change(data.hud.text, "text", data.hud_msg)
|
||||||
|
|
||||||
|
if data.hud_img then
|
||||||
|
player:hud_change(data.hud.img, "text", data.hud_img)
|
||||||
|
end
|
||||||
|
|
||||||
|
if data.show_hud then
|
||||||
|
for _, def in pairs(data.hud) do
|
||||||
|
local hud_info = player:hud_get(def)
|
||||||
|
|
||||||
|
player:hud_change(def, "position", {
|
||||||
|
x = hud_info.position.x,
|
||||||
|
y = hud_info.position.y - ((dt / 5) * i3.HUD_SPEED)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif data.show_hud == false then
|
||||||
|
if data.hud_timer >= i3.HUD_TIMER_MAX then
|
||||||
|
for _, def in pairs(data.hud) do
|
||||||
|
local hud_info = player:hud_get(def)
|
||||||
|
|
||||||
|
player:hud_change(def, "position", {
|
||||||
|
x = hud_info.position.x,
|
||||||
|
y = hud_info.position.y + ((dt / 5) * i3.HUD_SPEED)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if hud_info_bg.position.y >= 1 then
|
||||||
|
data.show_hud = nil
|
||||||
|
data.hud_timer = nil
|
||||||
|
data.hud_msg = nil
|
||||||
|
data.hud_img = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
core.register_globalstep(function()
|
||||||
|
for name, data in pairs(i3.data) do
|
||||||
|
if data.show_hud ~= nil then
|
||||||
|
local player = get_player_by_name(name)
|
||||||
|
show_hud(player, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return init_hud
|
|
@ -1,14 +1,12 @@
|
||||||
local singleplayer = core.is_singleplayer()
|
|
||||||
|
|
||||||
local set_fs = i3.set_fs
|
local set_fs = i3.set_fs
|
||||||
|
local hud_notif = i3.hud_notif
|
||||||
|
|
||||||
local fmt, search, table_merge, array_diff =
|
local fmt, search, table_merge, array_diff =
|
||||||
i3.get("fmt", "search", "table_merge", "array_diff")
|
i3.get("fmt", "search", "table_merge", "array_diff")
|
||||||
local is_group, extract_groups, item_has_groups, apply_recipe_filters =
|
local is_group, extract_groups, item_has_groups, apply_recipe_filters =
|
||||||
i3.get("is_group", "extract_groups", "item_has_groups", "apply_recipe_filters")
|
i3.get("is_group", "extract_groups", "item_has_groups", "apply_recipe_filters")
|
||||||
|
|
||||||
local POLL_FREQ = 0.25
|
local POLL_FREQ = 0.25
|
||||||
local HUD_TIMER_MAX = 1.5
|
|
||||||
local HUD_SPEED = 1
|
|
||||||
|
|
||||||
local function get_filtered_items(player, data)
|
local function get_filtered_items(player, data)
|
||||||
local items, known, c = {}, 0, 0
|
local items, known, c = {}, 0, 0
|
||||||
|
@ -118,85 +116,6 @@ local function get_inv_items(player)
|
||||||
return inv_items
|
return inv_items
|
||||||
end
|
end
|
||||||
|
|
||||||
local function init_hud(player, data)
|
|
||||||
data.hud = {
|
|
||||||
bg = player:hud_add {
|
|
||||||
hud_elem_type = "image",
|
|
||||||
position = {x = 0.78, y = 1},
|
|
||||||
alignment = {x = 1, y = 1},
|
|
||||||
scale = {x = 370, y = 112},
|
|
||||||
text = "i3_bg.png",
|
|
||||||
z_index = 0xDEAD,
|
|
||||||
},
|
|
||||||
|
|
||||||
book = player:hud_add {
|
|
||||||
hud_elem_type = "image",
|
|
||||||
position = {x = 0.79, y = 1.02},
|
|
||||||
alignment = {x = 1, y = 1},
|
|
||||||
scale = {x = 4, y = 4},
|
|
||||||
text = "i3_book.png",
|
|
||||||
z_index = 0xDEAD,
|
|
||||||
},
|
|
||||||
|
|
||||||
text = player:hud_add {
|
|
||||||
hud_elem_type = "text",
|
|
||||||
position = {x = 0.84, y = 1.04},
|
|
||||||
alignment = {x = 1, y = 1},
|
|
||||||
number = 0xffffff,
|
|
||||||
text = "",
|
|
||||||
z_index = 0xDEAD,
|
|
||||||
style = 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function show_hud_success(player, data)
|
|
||||||
-- It'd better to have an engine function `hud_move` to only need
|
|
||||||
-- 2 calls for the notification's back and forth.
|
|
||||||
|
|
||||||
local hud_info_bg = player:hud_get(data.hud.bg)
|
|
||||||
local dt = 0.016
|
|
||||||
|
|
||||||
if hud_info_bg.position.y <= 0.9 then
|
|
||||||
data.show_hud = false
|
|
||||||
data.hud_timer = (data.hud_timer or 0) + dt
|
|
||||||
end
|
|
||||||
|
|
||||||
local discovered = data.tot_discovered or data.discovered
|
|
||||||
|
|
||||||
player:hud_change(data.hud.text, "text",
|
|
||||||
fmt("%u new recipe%s unlocked!", discovered, discovered > 1 and "s" or ""))
|
|
||||||
|
|
||||||
if data.show_hud then
|
|
||||||
for _, def in pairs(data.hud) do
|
|
||||||
local hud_info = player:hud_get(def)
|
|
||||||
|
|
||||||
player:hud_change(def, "position", {
|
|
||||||
x = hud_info.position.x,
|
|
||||||
y = hud_info.position.y - ((dt / 5) * HUD_SPEED)
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif data.show_hud == false then
|
|
||||||
if data.hud_timer >= HUD_TIMER_MAX then
|
|
||||||
for _, def in pairs(data.hud) do
|
|
||||||
local hud_info = player:hud_get(def)
|
|
||||||
|
|
||||||
player:hud_change(def, "position", {
|
|
||||||
x = hud_info.position.x,
|
|
||||||
y = hud_info.position.y + ((dt / 5) * HUD_SPEED)
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if hud_info_bg.position.y >= 1 then
|
|
||||||
data.show_hud = nil
|
|
||||||
data.hud_timer = nil
|
|
||||||
data.tot_discovered = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Workaround. Need an engine call to detect when the contents of
|
-- Workaround. Need an engine call to detect when the contents of
|
||||||
-- the player inventory changed, instead.
|
-- the player inventory changed, instead.
|
||||||
local function poll_new_items(player, data, join)
|
local function poll_new_items(player, data, join)
|
||||||
|
@ -210,11 +129,8 @@ local function poll_new_items(player, data, join)
|
||||||
data.discovered = data.known_recipes - oldknown
|
data.discovered = data.known_recipes - oldknown
|
||||||
|
|
||||||
if data.discovered > 0 then
|
if data.discovered > 0 then
|
||||||
data.tot_discovered = (data.tot_discovered or 0) + data.discovered
|
local msg = fmt("%u new recipe%s unlocked!", data.discovered, data.discovered > 1 and "s" or "")
|
||||||
|
hud_notif(data.player_name, msg, "i3_book.png")
|
||||||
if data.show_hud == nil then
|
|
||||||
data.show_hud = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
data.items_raw = items
|
data.items_raw = items
|
||||||
|
@ -227,18 +143,6 @@ local function poll_new_items(player, data, join)
|
||||||
core.after(POLL_FREQ, poll_new_items, player, data)
|
core.after(POLL_FREQ, poll_new_items, player, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
if singleplayer then
|
|
||||||
core.register_globalstep(function()
|
|
||||||
local name = "singleplayer"
|
|
||||||
local player = core.get_player_by_name(name)
|
|
||||||
local data = i3.data[name]
|
|
||||||
|
|
||||||
if data and data.show_hud ~= nil then
|
|
||||||
show_hud_success(player, data)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
i3.add_recipe_filter("Default progressive filter", progressive_filter)
|
i3.add_recipe_filter("Default progressive filter", progressive_filter)
|
||||||
|
|
||||||
core.register_on_joinplayer(function(player)
|
core.register_on_joinplayer(function(player)
|
||||||
|
@ -251,8 +155,4 @@ core.register_on_joinplayer(function(player)
|
||||||
data.discovered = data.discovered or 0
|
data.discovered = data.discovered or 0
|
||||||
|
|
||||||
poll_new_items(player, data, true)
|
poll_new_items(player, data, true)
|
||||||
|
|
||||||
if singleplayer then
|
|
||||||
init_hud(player, data)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
Ŝarĝante…
Reference in New Issue