Add a chat system that actually looks nice.
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 753 KiB After Width: | Height: | Size: 758 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 3.4 KiB |
149
mods/artifact_chat/init.lua
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
local ns = artifact
|
||||||
|
|
||||||
|
local hud_pop_times = {}
|
||||||
|
|
||||||
|
function ns.push_chat_message(msg, sender, splash, duration)
|
||||||
|
for name, m in pairs(artifact.players) do
|
||||||
|
local box = {}
|
||||||
|
local w = minetest.get_player_window_information(name).size.x
|
||||||
|
local y = (#m.chat *75)
|
||||||
|
box.left = artifact.hud_add(m, {
|
||||||
|
type = "image",
|
||||||
|
name = ""..math.random(),
|
||||||
|
pos = {x=0,y=0},
|
||||||
|
offset={x=8,y=12 +y},
|
||||||
|
align = {x=1,y=1},
|
||||||
|
scale = {x=4,y=4},
|
||||||
|
image = "artifact_chat_box_side.png"
|
||||||
|
})
|
||||||
|
box.middle = artifact.hud_add(m, {
|
||||||
|
type = "image",
|
||||||
|
name = ""..math.random(),
|
||||||
|
pos = {x=0,y=0},
|
||||||
|
offset={x=12,y=12 +y},
|
||||||
|
align = {x=1,y=1},
|
||||||
|
scale = {x=w -24,y=4},
|
||||||
|
image = "artifact_chat_box_middle.png"
|
||||||
|
})
|
||||||
|
box.right = artifact.hud_add(m, {
|
||||||
|
type = "image",
|
||||||
|
name = ""..math.random(),
|
||||||
|
pos = {x=1,y=0},
|
||||||
|
offset={x=-8,y=12 +y},
|
||||||
|
align = {x=-1,y=1},
|
||||||
|
scale = {x=4,y=4},
|
||||||
|
image = "artifact_chat_box_side.png"
|
||||||
|
})
|
||||||
|
if sender then msg = "["..sender.."] "..msg end
|
||||||
|
local i = 0
|
||||||
|
local str = ""
|
||||||
|
for x in msg:gmatch("(%s*[^%s]+%s*)") do
|
||||||
|
if (#str +#x) *8 < w -100 then
|
||||||
|
str = str..x
|
||||||
|
else
|
||||||
|
box["text"..i] = artifact.hud_add(m, {
|
||||||
|
type = "text",
|
||||||
|
name = ""..math.random(),
|
||||||
|
pos = {x=0,y=0},
|
||||||
|
padding_y = 10 +(i *18),
|
||||||
|
offset={x=64,y=22 +(i *18) +y},
|
||||||
|
align = {x=1,y=1},
|
||||||
|
text = str
|
||||||
|
})
|
||||||
|
str = x
|
||||||
|
i = i +1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
box["text"..i] = artifact.hud_add(m, {
|
||||||
|
type = "text",
|
||||||
|
name = ""..math.random(),
|
||||||
|
pos = {x=0,y=0},
|
||||||
|
padding_y = 10 +(i *18),
|
||||||
|
offset={x=64,y=22 +(i *18) +y},
|
||||||
|
align = {x=1,y=1},
|
||||||
|
text = str
|
||||||
|
})
|
||||||
|
-- if sender then
|
||||||
|
-- box.name = artifact.hud_add(m, {
|
||||||
|
-- type = "text",
|
||||||
|
-- pos = {x=0,y=0},
|
||||||
|
-- padding_y = 30,
|
||||||
|
-- offset={x=15,y=42 +y},
|
||||||
|
-- align = {x=1,y=1},
|
||||||
|
-- text = sender
|
||||||
|
-- })
|
||||||
|
-- end
|
||||||
|
if splash then
|
||||||
|
box.splash = artifact.hud_add(m, {
|
||||||
|
type = "image",
|
||||||
|
pos = {x=0,y=0},
|
||||||
|
padding_y = 25,
|
||||||
|
offset={x=32,y=37 +y},
|
||||||
|
align = {x=0,y=0},
|
||||||
|
-- scale = {x=0.5,y=0.5},
|
||||||
|
image = splash
|
||||||
|
})
|
||||||
|
end
|
||||||
|
m.chat[#m.chat +1] = box
|
||||||
|
end
|
||||||
|
-- Ensure that messages auto-pop strictly in order, in case of different durations.
|
||||||
|
-- If a message would cause a pop before its predecessor expires, its pop time is
|
||||||
|
-- pushed forward to immediately follow that of the last visible message.
|
||||||
|
table.insert(hud_pop_times, math.max(hud_pop_times[#hud_pop_times] or 0, (duration or 15) *1000000 +minetest.get_us_time()))
|
||||||
|
-- Track pop jobs to get the number of active messages, since the actual HUD is stored in each player.
|
||||||
|
if #hud_pop_times > 5 then
|
||||||
|
ns.pop_chat_message()
|
||||||
|
end
|
||||||
|
-- Write the message to the chat log. (Note that `msg` is updated above to include the sender name, if present.)
|
||||||
|
minetest.chat_send_all(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ns.pop_chat_message()
|
||||||
|
table.remove(hud_pop_times, 1)
|
||||||
|
for _, m in pairs(artifact.players) do
|
||||||
|
for _, x in pairs(m.chat[1]) do
|
||||||
|
x:remove(m)
|
||||||
|
end
|
||||||
|
table.remove(m.chat, 1)
|
||||||
|
for i, x in ipairs(m.chat) do
|
||||||
|
local y = (i -1) *75
|
||||||
|
for _, el in pairs(x) do
|
||||||
|
el:animate {
|
||||||
|
offset = {
|
||||||
|
value = {x=el.offset.x, y=12 +y +(el.padding_y or 0)},
|
||||||
|
duration = 0.3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_on_chat_message(function(name, msg)
|
||||||
|
ns.push_chat_message(msg, name)
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_globalstep(function()
|
||||||
|
local time = minetest.get_us_time()
|
||||||
|
if time >= (hud_pop_times[1] or math.huge) then
|
||||||
|
ns.pop_chat_message()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
if artifact.debug then
|
||||||
|
|
||||||
|
minetest.register_chatcommand("key", {
|
||||||
|
func = function(name, args)
|
||||||
|
ns.push_chat_message(args, "Key", "artifact_key_splash_low.png")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("vix", {
|
||||||
|
func = function(name, args)
|
||||||
|
ns.push_chat_message(args, "Vix", "artifact_vix_splash_low.png")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
end
|
||||||
2
mods/artifact_chat/mod.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = artifact_chat
|
||||||
|
depends = artifact_hud
|
||||||
BIN
mods/artifact_chat/textures/artifact_chat_box_middle.png
Normal file
|
After Width: | Height: | Size: 96 B |
BIN
mods/artifact_chat/textures/artifact_chat_box_side.png
Normal file
|
After Width: | Height: | Size: 99 B |
|
|
@ -77,6 +77,11 @@ function ns.hud_add(m, def)
|
||||||
if type.defaults then
|
if type.defaults then
|
||||||
def = extend(table.copy(type.defaults), def)
|
def = extend(table.copy(type.defaults), def)
|
||||||
end
|
end
|
||||||
|
-- Create a random name if none is given, since the
|
||||||
|
-- assumption is that the user doesn't care about the name.
|
||||||
|
if not def.name then
|
||||||
|
def.name = ""..math.random()
|
||||||
|
end
|
||||||
local el
|
local el
|
||||||
if m.hud[def.name] then
|
if m.hud[def.name] then
|
||||||
el = m.hud[def.name]
|
el = m.hud[def.name]
|
||||||
|
|
@ -222,8 +227,11 @@ ns.register_hud_type {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
remove = function(e, m)
|
remove = function(e, m)
|
||||||
|
m.hud[e.name] = nil
|
||||||
m.object:hud_remove(e._id)
|
m.object:hud_remove(e._id)
|
||||||
e._id = nil
|
e._id = nil
|
||||||
|
-- Prevent ongoing animations from attempting to change a nonexistent element.
|
||||||
|
e.update = function() end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,5 +278,7 @@ ns.register_hud_type {
|
||||||
m.hud[e.name] = nil
|
m.hud[e.name] = nil
|
||||||
m.object:hud_remove(e._id)
|
m.object:hud_remove(e._id)
|
||||||
e._id = nil
|
e._id = nil
|
||||||
|
-- Prevent ongoing animations from attempting to change a nonexistent element.
|
||||||
|
e.update = function() end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,13 @@ Player = setmetatable({
|
||||||
breathbar = false,
|
breathbar = false,
|
||||||
hotbar = artifact.debug,
|
hotbar = artifact.debug,
|
||||||
minimap = false,
|
minimap = false,
|
||||||
basic_debug = false
|
basic_debug = false,
|
||||||
|
chat = false, -- We provide our own implementation of the chat HUD.
|
||||||
}
|
}
|
||||||
|
|
||||||
m.hud = {}
|
m.hud = {}
|
||||||
m.poi = {}
|
m.poi = {}
|
||||||
|
m.chat = {}
|
||||||
m:create_hud()
|
m:create_hud()
|
||||||
|
|
||||||
m:set_hotbar_size(8)
|
m:set_hotbar_size(8)
|
||||||
|
|
|
||||||