181 lines
5.1 KiB
Lua
181 lines
5.1 KiB
Lua
|
--[[ Config ]]--
|
||
|
local disable_inventory = false
|
||
|
local R = 1 -- Size of vbar radius
|
||
|
|
||
|
local visuals = {}
|
||
|
local hud = {}
|
||
|
local toggle = {}
|
||
|
|
||
|
local def_size = vector.multiply({x = 0.25, y = 0.25, z = 0.25}, R)
|
||
|
local def_sel = vector.multiply({x = 0.265, y = 0.265, z = 0.265}, R)
|
||
|
|
||
|
-- Swap hotbar items around
|
||
|
local function set_item(entity, player)
|
||
|
local inv = player:get_inventory()
|
||
|
local main = inv:get_list("main")
|
||
|
inv:set_stack("main", entity.idx, player:get_wielded_item())
|
||
|
player:set_wielded_item(main[entity.idx])
|
||
|
visuals[player:get_player_name()] = nil
|
||
|
end
|
||
|
|
||
|
minetest.register_entity("visualbar:item", {
|
||
|
initial_properties = {
|
||
|
visual = "wielditem",
|
||
|
wield_item = "",
|
||
|
visual_size = def_size,
|
||
|
selectionbox = {-0.25 * R, -0.25 * R, -0.25 * R, 0.25 * R, 0.25 * R, 0.25 * R},
|
||
|
collisionbox = {-0.25 * R, -0.25 * R, -0.25 * R, 0.25 * R, 0.25 * R, 0.25 * R},
|
||
|
},
|
||
|
parent = nil, -- You aren't really supposed to store references, but... sue me
|
||
|
timer = 0,
|
||
|
idx = 0,
|
||
|
on_activate = function(self)
|
||
|
self.object:set_armor_groups({immortal = 1})
|
||
|
end,
|
||
|
on_step = function(self, dt) -- Most of this is just fancy visuals
|
||
|
self.timer = self.timer + dt
|
||
|
if self.timer > 0.1 then
|
||
|
if not self.parent or not visuals[self.parent:get_player_name()] then
|
||
|
self.object:remove()
|
||
|
elseif self.object:get_properties().wield_item ~= "" then
|
||
|
local pointed = false
|
||
|
local player = self.parent
|
||
|
local pos = player:get_pos()
|
||
|
pos.y = pos.y + player:get_properties().eye_height
|
||
|
local dir = player:get_look_dir()
|
||
|
local ray = minetest.raycast(pos, vector.add(pos, vector.multiply(dir, 2)))
|
||
|
for pt in ray do
|
||
|
if pt.type == "object" and pt.ref == self.object then
|
||
|
pointed = true
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
if pointed then
|
||
|
self.object:set_properties({
|
||
|
visual_size = def_sel
|
||
|
})
|
||
|
else
|
||
|
self.object:set_properties({
|
||
|
visual_size = def_size
|
||
|
})
|
||
|
end
|
||
|
end
|
||
|
self.timer = 0
|
||
|
end
|
||
|
end,
|
||
|
on_punch = set_item,
|
||
|
on_rightclick = set_item,
|
||
|
})
|
||
|
|
||
|
local function display(player)
|
||
|
local name = player:get_player_name()
|
||
|
local inv = player:get_inventory()
|
||
|
local list = inv:get_list("main")
|
||
|
local pos = player:get_pos()
|
||
|
|
||
|
visuals[name] = table.copy(pos)
|
||
|
|
||
|
pos.y = pos.y + 1
|
||
|
local angle = 360 / 8
|
||
|
local y = player:get_look_horizontal()
|
||
|
for i = 1, 8 do
|
||
|
local rel = vector.multiply(minetest.yaw_to_dir(math.rad(i * -angle) + y + math.rad(45)), R)
|
||
|
local target = vector.add(pos, rel)
|
||
|
local ent = minetest.add_entity(target, "visualbar:item")
|
||
|
local luen = ent:get_luaentity()
|
||
|
local item = list[i]:get_name()
|
||
|
if item ~= "" then
|
||
|
ent:set_properties({wield_item = item, infotext = minetest.registered_items[item].description or item})
|
||
|
ent:set_yaw(minetest.dir_to_yaw(vector.direction(pos, ent:get_pos())))
|
||
|
if list[i]:get_count() > 1 then
|
||
|
ent:set_nametag_attributes({
|
||
|
color = "white",
|
||
|
text = list[i]:get_count()
|
||
|
})
|
||
|
end
|
||
|
else
|
||
|
ent:set_properties({visual_size = {x = 0, y = 0, z = 0}})
|
||
|
end
|
||
|
luen.parent = player
|
||
|
luen.idx = i
|
||
|
end
|
||
|
end
|
||
|
|
||
|
minetest.register_on_joinplayer(function(player)
|
||
|
local name = player:get_player_name()
|
||
|
|
||
|
player:hud_set_flags({
|
||
|
hotbar = false
|
||
|
})
|
||
|
player:hud_set_hotbar_itemcount(1) -- Force player to hold selected item
|
||
|
|
||
|
-- Display stack size
|
||
|
hud[name] = player:hud_add({
|
||
|
hud_elem_type = "text",
|
||
|
position = {x = 0.5, y = 1},
|
||
|
text = "",
|
||
|
alignment = 0,
|
||
|
offset = {x = 0, y = -20},
|
||
|
number = 0xFFFFFF,
|
||
|
})
|
||
|
|
||
|
if disable_inventory then
|
||
|
minetest.after(0, function(name)
|
||
|
local player = minetest.get_player_by_name(name)
|
||
|
if player then
|
||
|
player:set_inventory_formspec("size[0,0] no_prepend[] bgcolor[#00000000]")
|
||
|
end
|
||
|
end, name)
|
||
|
player:get_inventory():set_size("main", 8)
|
||
|
else
|
||
|
player:get_inventory():set_size("main", 8 * 4)
|
||
|
minetest.register_on_player_inventory_action(function(player)
|
||
|
visuals[player:get_player_name()] = nil
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
minetest.register_on_placenode(function(_, _, player)
|
||
|
visuals[player:get_player_name()] = nil
|
||
|
end)
|
||
|
minetest.register_on_dignode(function(_, _, player)
|
||
|
visuals[player:get_player_name()] = nil
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
minetest.register_on_leaveplayer(function(player)
|
||
|
visuals[player:get_player_name()] = nil
|
||
|
end)
|
||
|
|
||
|
local function precise_time()
|
||
|
return minetest.get_us_time() / 1000000
|
||
|
end
|
||
|
|
||
|
minetest.register_globalstep(function()
|
||
|
for _, player in pairs(minetest.get_connected_players()) do
|
||
|
local name = player:get_player_name()
|
||
|
local ctrl = player:get_player_control()
|
||
|
if visuals[name] then -- Remove visuals if aux1 is pressed or the player moves
|
||
|
if ctrl.aux1 or not vector.equals(vector.floor(player:get_pos()), vector.floor(visuals[name])) then
|
||
|
visuals[name] = nil
|
||
|
toggle[name] = 0
|
||
|
end
|
||
|
else
|
||
|
if ctrl.aux1 then -- Start the timer if aux1 is pressed
|
||
|
toggle[name] = toggle[name] or precise_time()
|
||
|
elseif toggle[name] then
|
||
|
if precise_time() - toggle[name] <= 0.12 then
|
||
|
display(player) -- Display if aux1 was released within 0.12 seconds
|
||
|
end
|
||
|
toggle[name] = nil
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Update stack count HUD element
|
||
|
local count = player:get_wielded_item():get_count()
|
||
|
if count < 1 then
|
||
|
count = ""
|
||
|
end
|
||
|
player:hud_change(hud[name], "text", count)
|
||
|
end
|
||
|
end)
|