Last active
March 9, 2022 00:51
-
-
Save sapier/7861582 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-------------------------------------------------------------------------------- | |
-- @function [parent=#adv_spawning] check_light_around_voxel | |
-- @param pos position to validate | |
-- @param light_around light around definitions | |
-- @return true/false | |
-------------------------------------------------------------------------------- | |
function adv_spawning.check_light_around_voxel(pos,light_around) | |
if light_around == nil then | |
return true | |
end | |
local maxdistance = 0 | |
for i=1,#light_around,1 do | |
maxdistance = adv_spawning.MAX(maxdistance,light_around[i].distance) | |
end | |
local minp = { x=math.floor(pos.x - maxdistance), | |
y=math.floor(pos.y - maxdistance), | |
z=math.floor(pos.z - maxdistance)} | |
local maxp = { x=math.ceil(pos.x + maxdistance), | |
y=math.ceil(pos.y + maxdistance), | |
z=math.ceil(pos.z + maxdistance)} | |
local voxeldata = minetest.get_voxel_manip() | |
local got_minp,got_maxp = voxeldata:read_from_map(minp,maxp) | |
local voxel_light_data = voxeldata:get_light_data() | |
local node_data = voxeldata:get_data() | |
local voxelhelper = VoxelArea:new(got_minp,got_maxp) | |
for i=1,#light_around,1 do | |
for x=pos.x-light_around[i].distance,pos.x+light_around[i].distance,1 do | |
for y=pos.y-light_around[i].distance,pos.y+light_around[i].distance,1 do | |
for z=pos.z-light_around[i].distance,pos.z+light_around[i].distance,1 do | |
local checkpos = { x=x,y=y,z=z} | |
local time = minetest.get_timeofday() | |
if light_around[i].type == "TIMED_MIN" or | |
light_around[i].type == "TIMED_MAX" then | |
time = light_around[i].time | |
end | |
if light_around[i].type == "OVERALL_MIN" or | |
light_around[i].type == "OVERALL_MAX" then | |
for j=0,24000,1000 do | |
local light_level = minetest.get_node_light(checkpos, j) | |
local voxellight = adv_spawning.voxelmaniplight(node_data,voxel_light_data,voxelhelper,checkpos,j) | |
if light_level ~= nil then | |
if light_around[i].type == "OVERALL_MAX" and | |
light_level > light_around[i].threshold then | |
return false | |
end | |
if light_around[i].type == "OVERALL_MIN" and | |
light_level < light_around[i].threshold then | |
return false | |
end | |
end | |
end | |
else | |
local light_level = minetest.get_node_light(checkpos, time) | |
local voxellight = adv_spawning.voxelmaniplight(node_data,voxel_light_data,voxelhelper,checkpos,time) | |
if light_level ~= nil then | |
if (light_around[i].type == "TIMED_MIN" or | |
light_around[i].type == "CURRENT_MIN") and | |
light_level < light_around[i].threshold then | |
return false | |
end | |
if (light_around[i].type == "TIMED_MAX" or | |
light_around[i].type == "CURRENT_MAX") and | |
light_level > light_around[i].threshold then | |
return false | |
end | |
end | |
end | |
end | |
end | |
end | |
end | |
return true | |
end | |
local light_lookup = { | |
{4250+125, 150}, | |
{4500+125, 150}, | |
{4750+125, 250}, | |
{5000+125, 350}, | |
{5250+125, 500}, | |
{5500+125, 675}, | |
{5750+125, 875}, | |
{6000+125, 1000}, | |
{6250+125, 1000} | |
} | |
function adv_spawning.day_night_ratio(time) | |
--make sure time is between 0 and 240000 | |
if time < 0 then | |
time = time - (((time*-1)/24000)*24000) | |
end | |
if time > 24000 then | |
time = time + ((time/24000)*24000) | |
end | |
--invert time for sunset | |
if time > 12000 then | |
time = 24000 - time | |
end | |
local dnr = 1000 | |
for i=1,#light_lookup,1 do | |
if time < light_lookup[i][1] then | |
dnr = light_lookup[i][2] | |
break | |
end | |
end | |
return dnr | |
end | |
function adv_spawning.voxelmaniplight(node_data,light_data,helper,pos,time) | |
if not helper:containsp(pos) then | |
minetest.get_node_light(pos, time) | |
end | |
local origpos = { x=pos.x, y=pos.y,z=pos.z } | |
pos = vector.round(pos) | |
local raw_light_value = light_data[helper:indexp(pos)] | |
if raw_light_value == nil then | |
print("Unable to fetch light value: " .. dump(pos)) | |
return 0 | |
end | |
local light_day = raw_light_value % 16 | |
local light_night = (raw_light_value - light_day)/16 | |
-- check for sunlight_propagates | |
local raw_node_data = node_data[helper:indexp(pos)] | |
local nodename = minetest.get_name_from_content_id(raw_node_data) | |
local nodedef = minetest.registered_nodes[nodename] | |
if nodedef.sunlight_propagates ~= true then | |
light_day = 0 | |
light_night = 0 | |
end | |
if nodedef.light_source ~= nil then | |
light_day = adv_spawning.MAX(nodedef.light_source,light_day) | |
light_night = adv_spawning.MAX(nodedef.light_source,light_night) | |
end | |
local orig_time = time | |
time = time *24000 | |
time = time %24000 | |
local dnr = adv_spawning.day_night_ratio(time) | |
local c = 1000 | |
local current_light = ((dnr * light_day + (c-dnr) * light_night))/c | |
if(current_light > LIGHT_MAX+1) then | |
current_light = LIGHT_MAX+1 | |
end | |
current_light = math.floor(current_light+0.5) | |
local official_light_value = minetest.get_node_light(origpos, orig_time) | |
if current_light ~= official_light_value then | |
local official_node = minetest.get_node(origpos) | |
print("RAW: " .. dump(raw_light_value) .. " NodeVM: " .. nodename .. | |
" NodeDirect: " .. official_node.name .. | |
" VL: " .. current_light .. " ND:" .. dump(official_light_value) .. | |
" Pos: " .. minetest.pos_to_string(origpos) .. | |
" Pos rounded: " .. minetest.pos_to_string(pos) .. | |
" time: " .. time .. " time_orig: " .. orig_time) | |
end | |
return current_light | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment