Ability to stack notifications on top of each other

This commit is contained in:
Jean-Patrick Guerrero 2023-04-01 22:15:25 +02:00
parent 1f43c8fac2
commit 1684388851
3 changed files with 92 additions and 73 deletions

View File

@ -2,8 +2,8 @@ local http = ...
local make_fs, get_inventory_fs = i3.files.gui() local make_fs, get_inventory_fs = i3.files.gui()
IMPORT("sorter", "sort_inventory", "play_sound") IMPORT("sorter", "sort_inventory", "play_sound")
IMPORT("get_player_by_name", "add_hud_waypoint")
IMPORT("sort", "concat", "copy", "insert", "remove") IMPORT("sort", "concat", "copy", "insert", "remove")
IMPORT("get_player_by_name", "add_hud_waypoint", "init_hud_notif")
IMPORT("gmatch", "split", "S", "err", "fmt", "reg_items", "pos_to_str") IMPORT("gmatch", "split", "S", "err", "fmt", "reg_items", "pos_to_str")
IMPORT("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name") IMPORT("true_str", "true_table", "is_str", "is_func", "is_table", "clean_name")
@ -319,13 +319,29 @@ function i3.hud_notif(name, msg, img)
return err "i3.hud_notif: no player data initialized" return err "i3.hud_notif: no player data initialized"
end end
data.show_hud = true local player = get_player_by_name(name)
data.hud_msg = msg local max_y = -120
local def = {
show = true,
max_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) play_sound(name, "i3_achievement", 1.0)
if img then local nb_notifs = #data.hud.notifs
data.hud_img = fmt("%s^[resize:64x64", img) for i = 1, nb_notifs - 1 do
local notif = data.hud.notifs[i]
if notif then
notif.show = true
notif.max_y = ((nb_notifs - i) + 1) * max_y
notif.hud_timer = 0
end
end end
end end

View File

@ -636,6 +636,41 @@ local function add_hud_waypoint(player, name, pos, color, image)
} }
end end
local function init_hud_notif(player)
return {
bg = player:hud_add {
hud_elem_type = "image",
position = {x = 1, y = 1},
offset = {x = -330, y = 0},
alignment = {x = 1, y = 1},
scale = {x = 0.6, y = 0.6},
text = "i3_bg_notif.png",
z_index = 0xDEAD,
},
img = player:hud_add {
hud_elem_type = "image",
position = {x = 1, y = 1},
offset = {x = -320, y = 20},
alignment = {x = 1, y = 1},
scale = {x = 1, y = 1},
text = "",
z_index = 0xDEAD,
},
text = player:hud_add {
hud_elem_type = "text",
position = {x = 1, y = 1},
offset = {x = -245, y = 40},
alignment = {x = 1, y = 1},
number = 0xffffff,
text = "",
z_index = 0xDEAD,
style = 1,
}
}
end
local function get_detached_inv(name, player_name) local function get_detached_inv(name, player_name)
return core.get_inventory { return core.get_inventory {
type = "detached", type = "detached",
@ -725,6 +760,7 @@ local _ = {
play_sound = play_sound, play_sound = play_sound,
reset_data = reset_data, reset_data = reset_data,
safe_teleport = safe_teleport, safe_teleport = safe_teleport,
init_hud_notif = init_hud_notif,
add_hud_waypoint = add_hud_waypoint, add_hud_waypoint = add_hud_waypoint,
-- Core functions -- Core functions

View File

@ -1,4 +1,5 @@
IMPORT("ceil", "get_connected_players", "str_to_pos", "add_hud_waypoint") IMPORT("ceil", "remove", "str_to_pos")
IMPORT("get_connected_players", "add_hud_waypoint")
local function init_hud(player) local function init_hud(player)
local name = player:get_player_name() local name = player:get_player_name()
@ -13,36 +14,7 @@ local function init_hud(player)
end end
data.hud = { data.hud = {
bg = player:hud_add { notifs = {},
hud_elem_type = "image",
position = {x = 1, y = 1},
offset = {x = -330, y = 0},
alignment = {x = 1, y = 1},
scale = {x = 0.6, y = 0.6},
text = "i3_bg_notif.png",
z_index = 0xDEAD,
},
img = player:hud_add {
hud_elem_type = "image",
position = {x = 1, y = 1},
offset = {x = -320, y = 20},
alignment = {x = 1, y = 1},
scale = {x = 1, y = 1},
text = "",
z_index = 0xDEAD,
},
text = player:hud_add {
hud_elem_type = "text",
position = {x = 1, y = 1},
offset = {x = -245, y = 40},
alignment = {x = 1, y = 1},
number = 0xffffff,
text = "",
z_index = 0xDEAD,
style = 1,
},
wielditem = player:hud_add { wielditem = player:hud_add {
hud_elem_type = "text", hud_elem_type = "text",
@ -53,59 +25,52 @@ local function init_hud(player)
text = "", text = "",
z_index = 0xDEAD, z_index = 0xDEAD,
style = 1, style = 1,
}, }
} }
end end
local function show_hud(player, data, dt) local function show_hud(player, data, notif, idx, dt)
local hud_info_bg = player:hud_get(data.hud.bg) local hud_info_bg = player:hud_get(notif.elems.bg)
local offset_y = hud_info_bg.offset.y local offset_y = hud_info_bg.offset.y
local max_y = -120 local progress = offset_y * (1 / (notif.max_y - 5))
local progress = offset_y * (1 / (max_y - 5))
progress = 1 - (progress ^ 4) progress = 1 - (progress ^ 4)
local speed = i3.settings.hud_speed * (100 * progress) * dt local speed = i3.settings.hud_speed * (100 * progress) * dt
if offset_y < max_y then if offset_y < notif.max_y then
data.show_hud = false notif.show = false
data.hud_timer = (data.hud_timer or 0) + dt notif.hud_timer = notif.hud_timer + dt
end end
player:hud_change(data.hud.text, "text", data.hud_msg) player:hud_change(notif.elems.text, "text", notif.hud_msg)
if data.hud_img then if notif.hud_img then
player:hud_change(data.hud.img, "text", data.hud_img) player:hud_change(notif.elems.img, "text", notif.hud_img)
end end
if data.show_hud then if notif.show then
for name, def in pairs(data.hud) do for _, def in pairs(notif.elems) do
if name ~= "wielditem" then local hud_info = player:hud_get(def)
local hud_info = player:hud_get(def)
player:hud_change(def, "offset", { player:hud_change(def, "offset", {
x = hud_info.offset.x, x = hud_info.offset.x,
y = hud_info.offset.y - speed y = hud_info.offset.y - speed
}) })
end
end end
elseif data.show_hud == false and data.hud_timer >= i3.settings.hud_timer_max then elseif notif.show == false and notif.hud_timer >= (i3.settings.hud_timer_max + (idx * 0.25)) then
for name, def in pairs(data.hud) do for _, def in pairs(notif.elems) do
if name ~= "wielditem" then local hud_info = player:hud_get(def)
local hud_info = player:hud_get(def)
player:hud_change(def, "offset", { player:hud_change(def, "offset", {
x = hud_info.offset.x, x = hud_info.offset.x,
y = hud_info.offset.y + speed y = hud_info.offset.y + speed
}) })
if offset_y > 0 then
player:hud_remove(def)
remove(data.hud.notifs, idx)
end end
end end
if offset_y > 0 then
data.show_hud = nil
data.hud_timer = nil
data.hud_msg = nil
data.hud_img = nil
end
end end
end end
@ -119,8 +84,10 @@ core.register_globalstep(function(dt)
local data = i3.data[name] local data = i3.data[name]
if not data then return end if not data then return end
if data.show_hud ~= nil then for idx, notif in ipairs(data.hud.notifs) do
show_hud(player, data, dt) if notif.show ~= nil then
show_hud(player, data, notif, idx, dt)
end
end end
local has_text = player:hud_get(data.hud.wielditem).text ~= "" local has_text = player:hud_get(data.hud.wielditem).text ~= ""