diff --git a/mods/rp_lumien/init.lua b/mods/rp_lumien/init.lua index d766d9c4..744bff7f 100644 --- a/mods/rp_lumien/init.lua +++ b/mods/rp_lumien/init.lua @@ -5,6 +5,8 @@ local S = minetest.get_translator("rp_lumien") +local has_mobs_mod = minetest.get_modpath("rp_mobs") ~= nil + -- How close a player needs to be (in nodes) for a lumien crystal to light up local LUMIEN_ON_RADIUS = 2 -- How far a player needs to be (in nodes) from an active lumien crystal to turn off again @@ -20,52 +22,8 @@ local LUMIEN_CRYSTAL_SOUND_PITCH = 1.2 -- Sound pitch modifier for lumien footstep sound (both block and crystal) local LUMIEN_SOUND_PITCH_FOOTSTEP = 0.8 -local timer_interval = 1 -local timer = 0 - --- Update function - -local function on_globalstep(dtime) - timer = timer + dtime - - if timer < timer_interval then - return - end - - timer = 0 - - for _, player in ipairs(minetest.get_connected_players()) do - local pos = player:get_pos() - - util.nodefunc( - { - x = pos.x-LUMIEN_ON_RADIUS, - y = pos.y-LUMIEN_ON_RADIUS, - z = pos.z-LUMIEN_ON_RADIUS - }, - { - x = pos.x+LUMIEN_ON_RADIUS, - y = pos.y+LUMIEN_ON_RADIUS, - z = pos.z+LUMIEN_ON_RADIUS - }, - "rp_lumien:crystal_off", - function(pos) - local node = minetest.get_node(pos) - - minetest.set_node( - pos, - { - name = "rp_lumien:crystal_on", - param = node.param, - param2 = node.param2 - }) - end, - true - ) - end -end - -minetest.register_globalstep(on_globalstep) +-- Interval (in seconds) to check for nearby humanoids +local LUMIEN_CRYSTAL_CHECK_TIMER = 1.0 local get_sounds = function(pitch) if not pitch then @@ -79,6 +37,34 @@ local get_sounds = function(pitch) }) end +-- Return true if a "luminator" (an entity that causes a lumien crystal to glow) is nearby pos. +-- Players and animal and humanoid mobs are luminators. +-- * pos: Position to compare to +-- * is_on: true if lumien crystal +local is_luminator_nearby = function(pos, is_on) + local offset + if is_on then + -- Offset to turn crytal off + offset = LUMIEN_OFF_RADIUS + else + -- Offset to turn crytal on + offset = LUMIEN_ON_RADIUS + end + local objects = minetest.get_objects_in_area(vector.subtract(pos, offset), vector.add(pos, offset)) + for o=1, #objects do + local obj = objects[o] + if obj:is_player() then + return true + elseif has_mobs_mod then + local lua = obj:get_luaentity() + if lua and lua._cmi_is_mob and (rp_mobs.has_tag(lua, "animal") or rp_mobs.has_tag(lua, "humanoid")) then + return true + end + end + end + return false +end + -- Nodes minetest.register_node( @@ -101,6 +87,19 @@ minetest.register_node( on_flood = function(pos) minetest.add_item(pos, "rp_lumien:crystal_off") end, + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(LUMIEN_CRYSTAL_CHECK_TIMER) + end, + on_timer = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(LUMIEN_CRYSTAL_CHECK_TIMER) + if not is_luminator_nearby(pos, true) then + local node = minetest.get_node(pos) + node.name = "rp_lumien:crystal_off" + minetest.swap_node(pos, node) + end + end, groups = {crumbly = 3, not_in_creative_inventory = 1}, light_source = LUMIEN_CRYSTAL_LIGHT_MAX, @@ -130,6 +129,19 @@ minetest.register_node( on_flood = function(pos) minetest.add_item(pos, "rp_lumien:crystal_off") end, + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(LUMIEN_CRYSTAL_CHECK_TIMER) + end, + on_timer = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(LUMIEN_CRYSTAL_CHECK_TIMER) + if is_luminator_nearby(pos, false) then + local node = minetest.get_node(pos) + node.name = "rp_lumien:crystal_on" + minetest.swap_node(pos, node) + end + end, groups = {crumbly = 3, creative_decoblock = 1}, light_source = LUMIEN_CRYSTAL_LIGHT_MIN, @@ -185,35 +197,6 @@ minetest.register_ore( y_max = -100, }) --- Update functions - -minetest.register_abm( - { - label = "Lumien crystals", - nodenames = {"rp_lumien:crystal_on"}, - interval = timer_interval, - chance = 1, - action = function(pos, node) - local ok = true - - for _,object in ipairs(minetest.get_objects_inside_radius(pos, LUMIEN_OFF_RADIUS)) do - if object:is_player() then - ok = false - end - end - - if ok then - minetest.set_node( - pos, - { - name = "rp_lumien:crystal_off", - param = node.param, - param2 = node.param2 - }) - end - end, -}) - -- Crafting crafting.register_craft( @@ -259,6 +242,19 @@ minetest.register_craft( cooktime = 6, }) +minetest.register_lbm({ + name = "rp_lumien:restart_timers", + label = "Restart lumien crystal timers", + nodenames = { "rp_lumien:crystal_on", "rp_lumien:crystal_off" }, + run_at_every_load = true, + action = function(pos) + local timer = minetest.get_node_timer(pos) + if not timer:is_started() then + timer:start(LUMIEN_CRYSTAL_CHECK_TIMER) + end + end, +}) + -- Achievements achievements.register_achievement( diff --git a/mods/rp_lumien/mod.conf b/mods/rp_lumien/mod.conf index 4bed2dc5..1427183f 100644 --- a/mods/rp_lumien/mod.conf +++ b/mods/rp_lumien/mod.conf @@ -1,3 +1,3 @@ name = rp_lumien depends = rp_sounds, rp_tnt, rp_util, rp_crafting, rp_achievements, rp_default -optional_depends = rp_itemdef_defaults +optional_depends = rp_itemdef_defaults, rp_mobs diff --git a/mods/rp_mobs_mobs/mobs/villager.lua b/mods/rp_mobs_mobs/mobs/villager.lua index 623ed5ea..562f22d9 100644 --- a/mods/rp_mobs_mobs/mobs/villager.lua +++ b/mods/rp_mobs_mobs/mobs/villager.lua @@ -1424,7 +1424,7 @@ local droptables = { rp_mobs.register_mob("rp_mobs_mobs:villager", { description = S("Villager"), - tags = { peaceful = 1 }, + tags = { humanoid = 1, peaceful = 1 }, -- Profession-specific drops drop_func = function(self)