Full proper support for spectator mods.

If players are invisible, NodeCore will not add any visible or
audible effects for them, allowing such players to be completely
non-interactive with gameplay.

This allows things like spectator or stealth-admin mods to
function properly.
This commit is contained in:
Aaron Suen 2019-12-11 06:52:09 -05:00
parent 60e79c4c35
commit d7819762e5
8 changed files with 42 additions and 23 deletions

View File

@ -6,7 +6,8 @@ local minetest, nodecore
local lasthit = {}
minetest.register_on_punchnode(function(pos, node, puncher)
if not puncher then return end
if not nodecore.player_visible(puncher) then return end
local pname = puncher:get_player_name()
local now = minetest.get_us_time() / 1000000
local last = lasthit[pname] or 0
@ -30,11 +31,13 @@ minetest.register_on_punchnode(function(pos, node, puncher)
end)
minetest.register_on_dignode(function(pos, node, digger)
if not nodecore.player_visible(digger) then return end
return nodecore.node_sound(pos, "dug",
{node = node, except = digger})
end)
minetest.register_on_placenode(function(pos, node, placer)
if not nodecore.player_visible(placer) then return end
return nodecore.node_sound(pos, "place",
{node = node, except = placer})
end)

View File

@ -117,6 +117,13 @@ function nodecore.interact(player)
return minetest.get_player_privs(player).interact
end
function nodecore.player_visible(player)
if type(player) == "string" then player = minetest.get_player_by_name(player) end
if not player then return end
local vs = player:get_properties().visual_size
return vs.x > 0 and vs.y > 0
end
function nodecore.wieldgroup(who, group)
local wielded = who and who:get_wielded_item()
local nodedef = minetest.registered_nodes[wielded:get_name()]

View File

@ -1,18 +1,20 @@
-- LUALOCALS < ---------------------------------------------------------
local minetest, pairs
= minetest, pairs
local minetest, nodecore, pairs
= minetest, nodecore, pairs
-- LUALOCALS > ---------------------------------------------------------
local function wieldsound(player, idx, gain)
local n = player:get_inventory():get_stack("main", idx):get_name()
local def = minetest.registered_items[n]
if def and def.sounds then
local t = {}
for k, v in pairs(def.sounds.dig) do t[k] = v end
t.object = player
t.gain = gain or 1
if player:get_player_control().sneak then t.gain = t.gain / 4 end
return function() minetest.sound_play(t.name, t) end
if nodecore.player_visible(player) then
local n = player:get_inventory():get_stack("main", idx):get_name()
local def = minetest.registered_items[n]
if def and def.sounds then
local t = {}
for k, v in pairs(def.sounds.dig) do t[k] = v end
t.object = player
t.gain = gain or 1
if player:get_player_control().sneak then t.gain = t.gain / 4 end
return function() minetest.sound_play(t.name, t) end
end
end
return function() end
end

View File

@ -10,14 +10,16 @@ minetest.register_on_player_hpchange(function(player, hp)
end
if hp < 0 then
player:get_meta():set_float("hurttime", nodecore.gametime)
minetest.after(0, function()
local now = player:get_hp()
if now >= orig then return end
nodecore.sound_play_except("player_damage", {
pos = player:get_pos(),
gain = 0.5
}, player)
end)
if nodecore.player_visible(player) then
minetest.after(0, function()
local now = player:get_hp()
if now >= orig then return end
nodecore.sound_play_except("player_damage", {
pos = player:get_pos(),
gain = 0.5
}, player)
end)
end
end
if hp + orig <= 0 then
hp = 1 - orig

View File

@ -143,6 +143,8 @@ minetest.register_on_joinplayer(function(player)
minetest.register_globalstep(function()
for _, player in pairs(minetest.get_connected_players()) do
updatevisuals(player)
if nodecore.player_visible(player) then
updatevisuals(player)
end
end
end)

View File

@ -60,6 +60,7 @@ end
local function canseeface(p1, p2)
if p1:get_hp() <= 0 or p2:get_hp() <= 0 then return end
if p1:get_attach() or p2:get_attach() then return end
if not nodecore.player_visible(p2) then return end
-- Players must be within max distance of one another,
-- determined by light level, but not too close.

View File

@ -46,7 +46,8 @@ local function privdropinv(player)
end
local function setfootsteps(player)
local value = not player:get_player_control().sneak
local value = nodecore.player_visible(player)
and (not player:get_player_control().sneak)
local pname = player:get_player_name()
if footsteps[pname] ~= value then
player:set_properties({

View File

@ -23,7 +23,8 @@ local function entprops(stack, conf, widx)
is_visible = false,
static_save = false
}
if not (conf and conf.pname and nodecore.interact(conf.pname)) then return t end
if not (conf and conf.pname and nodecore.interact(conf.pname)
and nodecore.player_visible(conf.pname)) then return t end
if conf.slot then
t.is_visible = true
t.textures = {modname .. "_slot.png^[transformFX^[opacity:160", "[combine:1x1"}