693 lines
24 KiB
Lua
693 lines
24 KiB
Lua
cozylights = {
|
|
-- constant size values and tables
|
|
version = "0.2.8",
|
|
default_size = tonumber(minetest.settings:get("mapfix_default_size")) or 40,
|
|
brightness_factor = tonumber(minetest.settings:get("cozylights_brightness_factor")) or 8,
|
|
reach_factor = tonumber(minetest.settings:get("cozylights_reach_factor")) or 2,
|
|
dim_factor = tonumber(minetest.settings:get("cozylights_dim_factor")) or 9.5,
|
|
wield_step = tonumber(minetest.settings:get("cozylights_wield_step")) or 0.01,
|
|
brush_hold_step = tonumber(minetest.settings:get("cozylights_brush_hold_step")) or 0.07,
|
|
on_gen_step = tonumber(minetest.settings:get("cozylights_on_gen_step")) or 0.7,
|
|
max_wield_light_radius = tonumber(minetest.settings:get("cozylights_wielded_light_radius")) or 17,
|
|
override_engine_lights = minetest.settings:get_bool("cozylights_override_engine_lights", false),
|
|
always_fix_edges = minetest.settings:get_bool("cozylights_always_fix_edges", false),
|
|
uncozy_mode = tonumber(minetest.settings:get("cozylights_uncozy_mode")) or 0,
|
|
crispy_potato = minetest.settings:get_bool("cozylights_crispy_potato", true),
|
|
-- this is a table of modifiers for global light source settings.
|
|
-- lowkeylike and dimlike usually assigned to decorations in hopes to make all ambient naturally occuring light sources weaker
|
|
-- this is for two reasons:
|
|
-- 1. performance: never know how many various nice looking blocks which emit light will be there, or for example computing lights for
|
|
-- every node of a lava lake would be extremely expensive if those would reach far/would be very bright
|
|
-- 2. looks: they were made with default engine lighting in mind, so usually are very frequent, with such frequency default cozylights
|
|
-- settings will make the environment look blunt
|
|
coziest_table = {
|
|
--"dimlike"
|
|
[1] = {
|
|
brightness_factor = 0,
|
|
reach_factor = 0,
|
|
dim_factor = 0
|
|
},
|
|
--"lowkeylike" almost the same as dimlike, but reaches much farther with its barely visible light
|
|
[2] = {
|
|
brightness_factor = 0,
|
|
reach_factor = 2,
|
|
dim_factor = -3
|
|
},
|
|
-- "candlelike" something-something
|
|
[3] = {
|
|
brightness_factor = 0,
|
|
reach_factor = 2,
|
|
dim_factor = -3
|
|
},
|
|
-- "torchlike" torches, fires, flames. made much dimmer than what default engine lights makes them
|
|
[4] = {
|
|
brightness_factor = -2,
|
|
reach_factor = 0,
|
|
dim_factor = 0
|
|
},
|
|
-- "lamplike" a bright source, think mese lamp(actually turned out its like a projector, and below is even bigger projector)
|
|
[5] = {
|
|
brightness_factor = 0,
|
|
reach_factor = 3,
|
|
dim_factor = 4
|
|
},
|
|
-- "projectorlike" a bright source with massive reach
|
|
[6] = {
|
|
brightness_factor = 1,
|
|
reach_factor = 3,
|
|
dim_factor = 4
|
|
},
|
|
},
|
|
-- appears nodes and items might not necessarily be the same array
|
|
source_nodes = nil,
|
|
cozy_items = nil,
|
|
-- dynamic size tables, okay now what about functions
|
|
cozycids_sunlight_propagates = {},
|
|
cozycids_light_sources = {},
|
|
cozyplayers = {},
|
|
area_queue = {},
|
|
single_light_queue = {},
|
|
modpath = minetest.get_modpath(minetest.get_current_modname())
|
|
}
|
|
|
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
|
dofile(modpath.."/helpers.lua")
|
|
|
|
-- backrooms test attempts to resolve mt engine lights problem with invisible lights, default settings will result
|
|
-- in many places being very well lit
|
|
-- me thinks ideal scenery with cozy lights in particular can be achieved with removal of all invisible lights
|
|
-- it also looks interesting after maybe a two thirds of light sources are broken
|
|
-- however the backrooms idea is not about broken windows theory at all, more about supernatural absence of any life
|
|
-- in a seemingly perfectly functioning infinite manmade mess, or idk i am not mentally masturbating any further,
|
|
-- some of the internets do that way too often, way too much
|
|
if cozylights:mod_loaded("br_core") then
|
|
cozylights.brightness_factor = cozylights.brightness_factor - 6
|
|
end
|
|
|
|
--if cozylights:mod_loaded("default") then
|
|
-- default.can_grow = function(pos)
|
|
-- local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
|
-- if not node_under then
|
|
-- return false
|
|
-- end
|
|
-- if minetest.get_item_group(node_under.name, "soil") == 0 then
|
|
-- return false
|
|
-- end
|
|
-- local light_level = minetest.get_node_light(pos)
|
|
-- if not light_level or light_level < 13 then
|
|
-- return false
|
|
-- end
|
|
-- return true
|
|
-- end
|
|
--end
|
|
|
|
|
|
dofile(modpath.."/nodes.lua")
|
|
dofile(modpath.."/shared.lua")
|
|
dofile(modpath.."/chat_commands.lua")
|
|
--ffi = require("ffi")
|
|
dofile(modpath.."/wield_light.lua")
|
|
dofile(modpath.."/node_light.lua")
|
|
dofile(modpath.."/light_brush.lua")
|
|
|
|
local c_air = minetest.get_content_id("air")
|
|
local c_light1 = minetest.get_content_id("cozylights:light1")
|
|
|
|
local c_lights = { c_light1, c_light1 + 1, c_light1 + 2, c_light1 + 3, c_light1 + 4, c_light1 + 5, c_light1 + 6,
|
|
c_light1 + 7, c_light1 + 8, c_light1 + 9, c_light1 + 10, c_light1 + 11, c_light1 + 12, c_light1 + 13 }
|
|
|
|
local mf = math.floor
|
|
|
|
------------------------------------------
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
local source_nodes = {}
|
|
local cozy_items = {}
|
|
local cozycids_sunlight_propagates = {}
|
|
local cozycids_light_sources = {}
|
|
local override = cozylights.override_engine_lights
|
|
for _,def in pairs(minetest.registered_items) do
|
|
if def.light_source and def.light_source > 1
|
|
and def.drawtype ~= "airlike" and def.drawtype ~= "liquid"
|
|
and string.find(def.name, "lava_flowing") == nil
|
|
and string.find(def.name, "lava_source") == nil
|
|
--and def.liquid_renewable == nil and def.drowning == nil
|
|
then
|
|
-- here we are going to define more specific skips and options for sus light sources
|
|
local skip = false
|
|
if string.find(def.name, "everness:") ~= nil and def.groups.vine ~= nil then
|
|
skip = true -- like goto continue
|
|
end
|
|
if skip == false then
|
|
local mods = nil
|
|
--if def.drawtype == "plantlike" then
|
|
-- mods = 1
|
|
--end
|
|
--if string.find(def.name,"torch") then
|
|
-- mods = 3
|
|
--end
|
|
cozy_items[def.name] = {light_source= def.light_source or 0,floodable=def.floodable or false,modifiers=mods}
|
|
if not string.find(def.name, "cozylights:light") then
|
|
source_nodes[#source_nodes+1] = def.name
|
|
end
|
|
end
|
|
end
|
|
end
|
|
for node,def in pairs(minetest.registered_nodes) do
|
|
if def.sunlight_propagates == true then
|
|
local cid = minetest.get_content_id(def.name)
|
|
cozycids_sunlight_propagates[cid] = true
|
|
end
|
|
if def.light_source and def.light_source > 1
|
|
and def.drawtype ~= "airlike" and def.drawtype ~= "liquid"
|
|
and not string.find(def.name, "lava_flowing")
|
|
and not string.find(def.name, "lava_source")
|
|
--and def.liquid_viscosity == nil and def.liquid_renewable == nil and def.drowning == nil
|
|
then
|
|
local cid = minetest.get_content_id(def.name)
|
|
if cid < c_lights[1] or cid > c_lights[14]+14 then
|
|
local skip = false
|
|
if string.find(def.name, "everness:") ~= nil and def.groups.vine ~= nil then
|
|
skip = true -- like goto :continue:
|
|
end
|
|
if skip == false then
|
|
cozycids_light_sources[cid] = true
|
|
if def.on_destruct then
|
|
local base_on_destruct = def.on_destruct
|
|
minetest.override_item(node,{
|
|
on_destruct = function(pos)
|
|
base_on_destruct(pos)
|
|
print(cozylights:dump(pos))
|
|
print(def.name.." is destroyed")
|
|
cozylights:destroy_light(pos, cozy_items[def.name])
|
|
end,
|
|
})
|
|
else
|
|
minetest.override_item(node,{
|
|
on_destruct = function(pos)
|
|
print(cozylights:dump(pos))
|
|
print(def.name.." is destroyed1")
|
|
cozylights:destroy_light(pos, cozy_items[def.name])
|
|
end,
|
|
})
|
|
end
|
|
if def.on_construct ~= nil then
|
|
local base_on_construct = def.on_construct
|
|
local light = override == true and 1 or def.light_source
|
|
if def.name == "br_core:ceiling_light_1" then
|
|
light = def.light_source - 7
|
|
end
|
|
minetest.override_item(node,{
|
|
light_source = light,
|
|
use_texture_alpha= def.use_texture_alpha or "clip",
|
|
on_construct = function(pos)
|
|
base_on_construct(pos)
|
|
cozylights:draw_node_light(pos, cozy_items[def.name])
|
|
end,
|
|
})
|
|
else
|
|
local light = override == true and 1 or def.light_source
|
|
if def.name == "br_core:ceiling_light_1" then
|
|
light = def.light_source - 7
|
|
end
|
|
minetest.override_item(node,{
|
|
light_source = light,
|
|
use_texture_alpha= def.use_texture_alpha or "clip",
|
|
on_construct = function(pos)
|
|
cozylights:draw_node_light(pos, cozy_items[def.name])
|
|
end,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
cozylights.source_nodes = source_nodes
|
|
cozylights.cozy_items = cozy_items
|
|
cozylights.cozycids_sunlight_propagates = cozycids_sunlight_propagates
|
|
cozylights.cozycids_light_sources = cozycids_light_sources
|
|
end)
|
|
|
|
--clean up possible stale wielded light on join, since on server shutdown we cant execute on_leave
|
|
--todo: make it more normal and less of a hack
|
|
function cozylights:on_join_cleanup(pos, radius)
|
|
local vm = minetest.get_voxel_manip()
|
|
local emin, emax = vm:read_from_map(vector.subtract(pos, radius+1), vector.add(pos, radius+1))
|
|
local data = vm:get_data()
|
|
local a = VoxelArea:new{
|
|
MinEdge = emin,
|
|
MaxEdge = emax
|
|
}
|
|
local param2data = vm:get_param2_data()
|
|
local max_radius = radius * (radius + 1)
|
|
for z = -radius, radius do
|
|
for y = -radius, radius do
|
|
for x = -radius, radius do
|
|
--local p = vector.add(pos,{x=x,y=y,z=z})
|
|
local p = {x=x+pos.x,y=y+pos.y,z=z+pos.z}
|
|
local idx = a:indexp(p)
|
|
local squared = x * x + y * y + z * z
|
|
if data[idx] >= c_lights[1] and data[idx] <= c_lights[14] and param2data[idx] == 0 and squared <= max_radius then
|
|
data[idx] = c_air
|
|
end
|
|
end
|
|
end
|
|
end
|
|
vm:set_data(data)
|
|
vm:update_liquids()
|
|
vm:write_to_map()
|
|
end
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
if not player then return end
|
|
local pos = vector.round(player:getpos())
|
|
pos.y = pos.y + 1
|
|
cozylights:on_join_cleanup(pos, 30)
|
|
cozylights.cozyplayers[player:get_player_name()] = {
|
|
name=player:get_player_name(),
|
|
pos_hash=pos.x + (pos.y)*100 + pos.z*10000,
|
|
wielded_item=0,
|
|
last_pos=pos,
|
|
last_wield="",
|
|
prev_wielded_lights={},
|
|
lbrush={
|
|
brightness=6,
|
|
radius=0,
|
|
strength=0.5,
|
|
mode=1,
|
|
cover_only_surfaces=0,
|
|
pos_hash=0,
|
|
}
|
|
}
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
if not player then return end
|
|
local name = player:get_player_name()
|
|
for i=1,#cozylights.cozyplayers do
|
|
if cozylights.cozyplayers[i].name == name then
|
|
cozylights:wielded_light_cleanup(player,cozylights.cozyplayers[i],30)
|
|
table.remove(cozylights.cozyplayers,i)
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_shutdown(function()
|
|
for i=1,#cozylights.cozyplayers do
|
|
local player = minetest.get_player_by_name(cozylights.cozyplayers[i].name)
|
|
if player ~= nil then
|
|
cozylights:wielded_light_cleanup(player,cozylights.cozyplayers[i],30)
|
|
end
|
|
end
|
|
end)
|
|
|
|
local agent_total = 0
|
|
local agent_count = 0
|
|
local recently_updated = {}
|
|
local function build_lights_after_generated(minp,maxp,sources)
|
|
local t = os.clock()
|
|
local vm = minetest.get_voxel_manip()
|
|
local emin, emax = vm:read_from_map(vector.subtract(minp, 1), vector.add(maxp, 1))
|
|
local data = vm:get_data()
|
|
local param2data = vm:get_param2_data()
|
|
local a = VoxelArea:new{
|
|
MinEdge = emin,
|
|
MaxEdge = emax
|
|
}
|
|
if sources then
|
|
for i=1, #sources do
|
|
local s = sources[i]
|
|
--local hash = minetest.hash_node_position(s.pos)
|
|
local hash = s.pos.x + (s.pos.y)*100 + s.pos.z*10000
|
|
if recently_updated[hash] == nil then
|
|
recently_updated[hash] = true
|
|
cozylights:draw_node_light(s.pos, s.cozy_item, vm, a, data, param2data)
|
|
end
|
|
end
|
|
else
|
|
local cozycids_light_sources = cozylights.cozycids_light_sources
|
|
for i in a:iterp(minp,maxp) do
|
|
local cid = data[i]
|
|
if cozycids_light_sources[cid] then
|
|
local cozy_item = cozylights.cozy_items[minetest.get_name_from_content_id(cid)]
|
|
-- check if radius is not too big
|
|
local radius, _ = cozylights:calc_dims(cozy_item)
|
|
local p = a:position(i)
|
|
if a:containsp(vector.subtract(p,radius)) and a:containsp(vector.add(p,radius))
|
|
then
|
|
cozylights:draw_node_light(p,cozy_item,vm,a,data,param2data)
|
|
else
|
|
table.insert(cozylights.single_light_queue, { pos=p, cozy_item=cozy_item })
|
|
end
|
|
end
|
|
end
|
|
end
|
|
cozylights:setVoxelManipData(vm,data,param2data,true)
|
|
agent_total = agent_total + mf((os.clock() - t) * 1000)
|
|
agent_count = agent_count + 1
|
|
--print("Av build after generated time: "..
|
|
-- mf(agent_total/agent_count).." ms. Sample of: "..agent_count..". Areas left: "..#cozylights.area_queue
|
|
--)
|
|
end
|
|
|
|
--idk, size should be smarter than a constant
|
|
local size = 85
|
|
local function place_schem_but_real(pos, schematic, rotation, replacements, force_placement, flags)
|
|
if tonumber(schematic) ~= nil or type(schematic) == "string" then -- schematic.data
|
|
cozylights.area_queue[#cozylights.area_queue+1]={
|
|
minp=vector.subtract(pos, size),
|
|
maxp=vector.add(pos, size),
|
|
sources=nil
|
|
}
|
|
return
|
|
end
|
|
local sd = schematic.data
|
|
local update_needed = false
|
|
for i, node in pairs(sd) do
|
|
-- todo: account for replacements
|
|
if cozylights.cozy_items[node.name] then
|
|
-- rotation can be random so we cant know the position
|
|
-- todo: account for faster cases when its not random
|
|
update_needed = true
|
|
break
|
|
end
|
|
end
|
|
if update_needed == true then
|
|
local cozycids_light_sources = cozylights.cozycids_light_sources
|
|
print("UPDATE NEEDED")
|
|
local minp,maxp,vm,data,param2data,a = cozylights:getVoxelManipData(pos, size)
|
|
for i in a:iterp(minp, maxp) do
|
|
local cid = data[i]
|
|
if cozycids_light_sources[cid] then
|
|
local cozy_item = cozylights.cozy_items[minetest.get_name_from_content_id(cid)]
|
|
-- check if radius is not too big
|
|
local radius, _ = cozylights:calc_dims(cozy_item)
|
|
local p = a:position(i)
|
|
if a:containsp(vector.subtract(p,radius)) and a:containsp(vector.add(p,radius))
|
|
then
|
|
cozylights:draw_node_light(p,cozy_item,vm,a,data,param2data)
|
|
else
|
|
table.insert(cozylights.single_light_queue, { pos=p, cozy_item=cozy_item })
|
|
end
|
|
end
|
|
end
|
|
cozylights:setVoxelManipData(vm,data,param2data,true)
|
|
end
|
|
end
|
|
|
|
--a feeble attempt to cover schematics placements
|
|
local placeschemthatisnotreal = minetest.place_schematic
|
|
--todo: if its a village(several schematics) dont rebuild same lights
|
|
--todo: schematic exception table, if we have discovered for a fact somehow that a particular schematic
|
|
--cant possibly have any kind of lights then we ignore
|
|
--if not in runtime, then a constant table,
|
|
--might require additional tools to load all schematics on contentdb to figure this out
|
|
local schem_queue = {}
|
|
minetest.place_schematic = function(pos, schematic, rotation, replacements, force_placement, flags)
|
|
if not placeschemthatisnotreal(pos, schematic, rotation, replacements, force_placement, flags) then return end
|
|
-- now totally real stuff starts to happen
|
|
schem_queue[#schem_queue+1] = {
|
|
pos = pos,
|
|
schematic = schematic,
|
|
rotation = rotation,
|
|
replacements = replacements,
|
|
force_placement = force_placement,
|
|
flags = flags
|
|
}
|
|
end
|
|
|
|
local place_schematic_on_vmanip_nicely = minetest.place_schematic_on_vmanip
|
|
minetest.place_schematic_on_vmanip = function(vmanip, minp, filename, rotation, replacements, force_placement,flags)
|
|
if not place_schematic_on_vmanip_nicely(vmanip, minp, filename, rotation, replacements, force_placement,flags) then return end
|
|
schem_queue[#schem_queue+1] = {
|
|
pos = minp,
|
|
schematic = filename,
|
|
rotation = rotation,
|
|
replacements = replacements,
|
|
force_placement = force_placement,
|
|
flags = flags
|
|
}
|
|
end
|
|
|
|
local createschemthatisveryreadable = minetest.create_schematic
|
|
minetest.create_schematic = function(p1, p2, probability_list, filename, slice_prob_list)
|
|
if not createschemthatisveryreadable(p1, p2, probability_list, filename, slice_prob_list) then return end
|
|
-- unreadable stuff happens here
|
|
cozylights.area_queue[#cozylights.area_queue+1] = {
|
|
minp = p1,
|
|
maxp = p2,
|
|
sources = nil
|
|
}
|
|
end
|
|
|
|
local wield_light_enabled = cozylights.max_wield_light_radius > -1 and true or false
|
|
local wield_step = cozylights.wield_step
|
|
local brush_hold_step = cozylights.brush_hold_step
|
|
local on_gen_step = cozylights.on_gen_step
|
|
|
|
function cozylights:switch_wielded_light(enabled)
|
|
wield_light_enabled = enabled
|
|
end
|
|
|
|
function cozylights:set_wield_step(_time)
|
|
wield_step = _time
|
|
minetest.settings:set("cozylights_wield_step",_time)
|
|
cozylights.wield_step = _time
|
|
end
|
|
|
|
function cozylights:set_brush_hold_step(_time)
|
|
brush_hold_step = _time
|
|
minetest.settings:set("cozylights_brush_hold_step",_time)
|
|
cozylights.brush_hold_step = _time
|
|
end
|
|
|
|
function cozylights:set_on_gen_step(_time)
|
|
on_gen_step = _time
|
|
minetest.settings:set("cozylights_on_gen_step",_time)
|
|
cozylights.on_gen_step = _time
|
|
end
|
|
|
|
local brush_hold_dtime = 0
|
|
local wield_dtime = 0
|
|
local on_gen_dtime = 0
|
|
|
|
local total_brush_hold_time = 0
|
|
local total_brush_hold_step_count = 0
|
|
local total_wield_time = 0
|
|
local total_wield_step_count = 0
|
|
local uncozy_queue = {}
|
|
|
|
local function on_brush_hold(player,cozyplayer,pos,t)
|
|
local control_bits = player:get_player_control_bits()
|
|
if control_bits < 128 or control_bits >= 256 then return end
|
|
local lb = cozyplayer.lbrush
|
|
if lb.radius > 10 then return end
|
|
local look_dir = player:get_look_dir()
|
|
local endpos = vector.add(pos, vector.multiply(look_dir, 100))
|
|
local hit = minetest.raycast(pos, endpos, false, false):next()
|
|
if not hit then return end
|
|
local nodenameunder = minetest.get_node(hit.under).name
|
|
local nodedefunder = minetest.registered_nodes[nodenameunder]
|
|
local above = hit.above
|
|
if nodedefunder.buildable_to == true then
|
|
above.y = above.y - 1
|
|
end
|
|
local above_hash = above.x + (above.y)*100 + above.z*10000
|
|
if above_hash ~= lb.pos_hash or lb.mode == 2 or lb.mode == 4 or lb.mode == 5 then
|
|
lb.pos_hash = above_hash
|
|
cozylights:draw_brush_light(above, lb)
|
|
local exe_time = os.clock() - t
|
|
total_brush_hold_time = total_brush_hold_time + mf(exe_time * 1000)
|
|
total_brush_hold_step_count = total_brush_hold_step_count + 1
|
|
print("Av cozy lights brush step time " .. mf(total_brush_hold_time/total_brush_hold_step_count) .. " ms. Sample of: "..total_brush_hold_step_count)
|
|
--if exe_time > brush_hold_step then
|
|
-- minetest.chat_send_all("brush hold step was adjusted to "..(exe_time*2).." secs to help crispy potato.")
|
|
-- brush_hold_step = exe_time*2
|
|
--end
|
|
end
|
|
end
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
if wield_light_enabled then
|
|
wield_dtime = wield_dtime + dtime
|
|
if wield_dtime > wield_step then
|
|
wield_dtime = 0
|
|
for _,cozyplayer in pairs(cozylights.cozyplayers) do
|
|
local t = os.clock()
|
|
local player = minetest.get_player_by_name(cozyplayer.name)
|
|
if player == nil then
|
|
goto next_player
|
|
end
|
|
local pos = vector.round(player:getpos())
|
|
pos.y = pos.y + 1
|
|
local wield_name = player:get_wielded_item():get_name()
|
|
-- simple hash, collision will result in a rare minor barely noticeable glitch if a user teleports:
|
|
-- if in collision case right after teleport the player does not move, wielded light wont work until the player starts moving
|
|
local pos_hash = pos.x + (pos.y)*100 + pos.z*10000
|
|
if pos_hash == cozyplayer.pos_hash and cozyplayer.last_wield == wield_name then
|
|
goto next_player
|
|
end
|
|
if cozylights.cozy_items[wield_name] ~= nil then
|
|
local vel = vector.round(vector.multiply(player:get_velocity(),wield_step))
|
|
cozylights:draw_wielded_light(
|
|
pos,
|
|
cozyplayer.last_pos,
|
|
cozylights.cozy_items[wield_name],
|
|
vel,
|
|
cozyplayer
|
|
)
|
|
else
|
|
cozylights:wielded_light_cleanup(player,cozyplayer,cozyplayer.last_wield_radius or 0)
|
|
end
|
|
cozyplayer.pos_hash = pos_hash
|
|
cozyplayer.last_pos = pos
|
|
cozyplayer.last_wield = wield_name
|
|
local exe_time = (os.clock() - t)
|
|
total_wield_time = total_wield_time + mf(exe_time * 1000)
|
|
total_wield_step_count = total_wield_step_count + 1
|
|
--print("Av wielded cozy light step time " .. mf(total_wield_time/total_wield_step_count) .. " ms. Sample of: "..total_wield_step_count)
|
|
if cozylights.crispy_potato and exe_time > wield_step then
|
|
cozylights:set_wielded_light_radius(cozylights.max_wield_light_radius - 1)
|
|
minetest.chat_send_all("wield light step was adjusted to "..(exe_time*2).." secs to help crispy potato.")
|
|
wield_step = exe_time*2
|
|
end
|
|
::next_player::
|
|
end
|
|
end
|
|
end
|
|
|
|
brush_hold_dtime = brush_hold_dtime + dtime
|
|
if brush_hold_dtime > brush_hold_step then
|
|
brush_hold_dtime = 0
|
|
for _,cozyplayer in pairs(cozylights.cozyplayers) do
|
|
local t = os.clock()
|
|
local player = minetest.get_player_by_name(cozyplayer.name)
|
|
if not player == nil then
|
|
local pos = vector.round(player:getpos())
|
|
pos.y = pos.y + 1
|
|
local wield_name = player:get_wielded_item():get_name()
|
|
--todo: checking against a string is expensive, what do
|
|
if wield_name == "cozylights:light_brush" then
|
|
on_brush_hold(player,cozyplayer,pos,t)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
on_gen_dtime = on_gen_dtime + dtime
|
|
if on_gen_dtime > on_gen_step then
|
|
on_gen_dtime = 0
|
|
if cozylights.uncozy_mode == 0 then
|
|
if #schem_queue > 0 then
|
|
local s = schem_queue[1]
|
|
place_schem_but_real(s.pos, s.schematic, s.rotation, s.replacements, s.force_placement, s.flags)
|
|
table.remove(schem_queue, 1)
|
|
end
|
|
if #cozylights.area_queue ~= 0 then
|
|
local ar = cozylights.area_queue[1]
|
|
table.remove(cozylights.area_queue, 1)
|
|
print("build_lights_after_generated: "..cozylights:dump(ar.minp))
|
|
build_lights_after_generated(ar.minp,ar.maxp,ar.sources)
|
|
else
|
|
cozylights:rebuild_light()
|
|
if #recently_updated > 0 then
|
|
recently_updated = {}
|
|
end
|
|
end
|
|
else
|
|
for _,cozyplayer in pairs(cozylights.cozyplayers) do
|
|
local player = minetest.get_player_by_name(cozyplayer.name)
|
|
local pos = vector.round(player:getpos())
|
|
pos.y = pos.y + 1
|
|
-- simple hash, collision will result in a rare minor barely noticeable glitch if a user teleports:
|
|
-- if in collision case right after teleport the player does not move, wielded light wont work until the player starts moving
|
|
local pos_hash = pos.x + (pos.y)*100 + pos.z*10000
|
|
if pos_hash == cozyplayer.pos_hash then
|
|
goto next_player
|
|
end
|
|
cozyplayer.pos_hash = pos_hash
|
|
cozyplayer.last_pos = pos
|
|
uncozy_queue[#uncozy_queue+1] = pos
|
|
::next_player::
|
|
end
|
|
if #uncozy_queue > 0 then
|
|
local exe_time = cozylights:clear(uncozy_queue[1], cozylights.uncozy_mode)
|
|
table.remove(uncozy_queue, 1)
|
|
if cozylights.crispy_potato and exe_time > on_gen_step then
|
|
minetest.chat_send_all("on_generated step was adjusted to "..(exe_time*2).." secs to help crispy potato.")
|
|
on_gen_step = exe_time*2
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
local gent_total = 0
|
|
local gent_count = 0
|
|
minetest.register_on_generated(function(minp, maxp)
|
|
local pos = vector.add(minp, vector.floor(vector.divide(vector.subtract(maxp,minp), 2)))
|
|
local light_sources = minetest.find_nodes_in_area(minp,maxp,cozylights.source_nodes)
|
|
if #light_sources == 0 then return end
|
|
if #light_sources > 1000 then
|
|
--print("Error: too many light sources around "..cozylights:dump(pos).." Report this to Cozy Lights dev")
|
|
return
|
|
end
|
|
--local minp_exp,maxp_exp,_,data,_,a = cozylights:getVoxelManipData(pos, size)
|
|
--local t = os.clock()
|
|
local sources = {}
|
|
local a = VoxelArea:new{
|
|
MinEdge = minp,
|
|
MaxEdge = maxp
|
|
}
|
|
local minp_exp, maxp_exp = minp, maxp
|
|
for _, p in pairs(light_sources) do
|
|
local name = minetest.get_node(p).name--get_name_from_content_id(cid)
|
|
local cozy_item = cozylights.cozy_items[name]
|
|
local radius, _ = cozylights:calc_dims(cozy_item)
|
|
local min_rad = vector.subtract(p,radius)
|
|
local max_rad = vector.add(p,radius)
|
|
if a:containsp(min_rad) and a:containsp(max_rad) then
|
|
sources[#sources+1] = {
|
|
pos=p,
|
|
cozy_item=cozy_item
|
|
}
|
|
else
|
|
minp_exp = {
|
|
x = minp_exp.x > min_rad.x and min_rad.x or minp_exp.x,
|
|
y = minp_exp.y > min_rad.y and min_rad.y or minp_exp.y,
|
|
z = minp_exp.z > min_rad.z and min_rad.z or minp_exp.z,
|
|
}
|
|
maxp_exp = {
|
|
x = maxp_exp.x < max_rad.x and max_rad.x or maxp_exp.x,
|
|
y = maxp_exp.y < max_rad.y and max_rad.y or maxp_exp.y,
|
|
z = maxp_exp.z < max_rad.z and max_rad.z or maxp_exp.z,
|
|
}
|
|
|
|
a = VoxelArea:new{
|
|
MinEdge = minp_exp,
|
|
MaxEdge = maxp_exp
|
|
}
|
|
sources[#sources+1] = {
|
|
pos=p,
|
|
cozy_item=cozy_item
|
|
}
|
|
--print("adding "..name.." to single_light_queue")
|
|
--table.insert(cozylights.single_light_queue, {
|
|
-- pos=p,
|
|
-- cozy_item=cozy_item
|
|
--})
|
|
end
|
|
end
|
|
--gent_total = gent_total + mf((os.clock() - t) * 1000)
|
|
--gent_count = gent_count + 1
|
|
--print("Av mapchunk generation time " .. mf(gent_total/gent_count) .. " ms. Sample of: "..gent_count)
|
|
if #sources > 0 then
|
|
print("on_generated adding area:"..cozylights:dump({minp=minp_exp,maxp=maxp_exp, volume=a:getVolume()}))
|
|
cozylights.area_queue[#cozylights.area_queue+1]={
|
|
minp=minp_exp,
|
|
maxp=maxp_exp,
|
|
sources=sources
|
|
}
|
|
end
|
|
end)
|
|
|