Fix and optimize line of sight checks
- Check destination medium against source, since it's possible to transition from a fluid to air and raycast will NOT collide with the air, causing from-fluid-to-air transitions not to be detected. - Pre-cache fluid medium data for all node defs instead of running through logic at runtime.master
parent
0a9ba9c210
commit
64f28532f1
|
@ -94,42 +94,8 @@ local function setcamera(player, pos, target)
|
|||
return player:set_pos(pos)
|
||||
end
|
||||
|
||||
local function fluidmedium(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local def = minetest.registered_items[node.name]
|
||||
if not def then return node.name end
|
||||
if def.sunlight_propagates then return "CLEAR" end
|
||||
return def.liquid_alternative_source or node.name
|
||||
end
|
||||
local function sightblocked(from, to)
|
||||
local fsrc = fluidmedium(from)
|
||||
for pt in minetest.raycast(from, to, false, true) do
|
||||
if pt.type == "node" then
|
||||
if fluidmedium(pt.under) ~= fsrc then
|
||||
return pt.above
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local getdata
|
||||
do
|
||||
local datastore = {}
|
||||
function getdata(p)
|
||||
local pname = type(p) == "string" and p or p:get_player_name()
|
||||
local data = datastore[pname]
|
||||
if not data then
|
||||
data = {}
|
||||
datastore[pname] = data
|
||||
end
|
||||
return data
|
||||
end
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
datastore[player:get_player_name()] = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local allow
|
||||
local fluidmedium
|
||||
do
|
||||
local allow_drawtypes = {
|
||||
airlike = true,
|
||||
|
@ -149,17 +115,55 @@ do
|
|||
local allow_nodes = {
|
||||
ignore = true
|
||||
}
|
||||
local fluids = {}
|
||||
minetest.after(0, function()
|
||||
for k, v in pairs(minetest.registered_nodes) do
|
||||
if allow_drawtypes[v.drawtype]
|
||||
and v.paramtype == "light" then
|
||||
allow_nodes[k] = true
|
||||
end
|
||||
if v.sunlight_propagates then
|
||||
fluids[k] = "CLEAR"
|
||||
else
|
||||
fluids[k] = v.liquid_alternative_source or k
|
||||
end
|
||||
end
|
||||
end)
|
||||
allow = function(pos)
|
||||
return allow_nodes[minetest.get_node(pos).name]
|
||||
end
|
||||
fluidmedium = function(pos)
|
||||
return fluids[minetest.get_node(pos).name]
|
||||
end
|
||||
end
|
||||
|
||||
local function sightblocked(from, to)
|
||||
local fsrc = fluidmedium(from)
|
||||
for pt in minetest.raycast(from, to, false, true) do
|
||||
if pt.type == "node" then
|
||||
if fluidmedium(pt.under) ~= fsrc then
|
||||
return pt.above
|
||||
end
|
||||
end
|
||||
end
|
||||
if fluidmedium(to) ~= fsrc then return to end
|
||||
end
|
||||
|
||||
local getdata
|
||||
do
|
||||
local datastore = {}
|
||||
function getdata(p)
|
||||
local pname = type(p) == "string" and p or p:get_player_name()
|
||||
local data = datastore[pname]
|
||||
if not data then
|
||||
data = {}
|
||||
datastore[pname] = data
|
||||
end
|
||||
return data
|
||||
end
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
datastore[player:get_player_name()] = nil
|
||||
end)
|
||||
end
|
||||
|
||||
local function hudset(player, data, key, def)
|
||||
|
|
Loading…
Reference in New Issue