Allow querying of the propagated light level.

This adds one Lua function, get_node_propagated_light, which works exactly
as get_node_light except that it excludes the entity at the specified location.

Class MapNode is extended to support this.

This allows extensions such as magic_lantern to work without removing the
object – each lamp would be removed prior to querying the light level then,
once the new setting had been determined, it would be re-created.
Unfortunately, this caused noticeable flicker...

The problem? The scene may be rendered while the lamp is removed.
This commit is contained in:
Darren Salt 2013-02-19 16:26:32 +00:00
parent 214a8b4597
commit d12d6a34a4
3 changed files with 76 additions and 5 deletions

View File

@ -63,6 +63,39 @@ void MapNode::setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr
assert(0);
}
u8 MapNode::getPropagatedLight(enum LightBank bank, INodeDefManager *nodemgr) const
{
const ContentFeatures &f = nodemgr->get(*this);
u8 light = 0;
if(f.param_type == CPT_LIGHT)
{
if(bank == LIGHTBANK_DAY)
light = param1 & 0x0f;
else if(bank == LIGHTBANK_NIGHT)
light = (param1>>4)&0x0f;
else
assert(0);
}
return light;
}
bool MapNode::getPropagatedLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const
{
const ContentFeatures &f = nodemgr->get(*this);
if(f.param_type == CPT_LIGHT)
{
lightday = param1 & 0x0f;
lightnight = (param1>>4)&0x0f;
return true;
}
else
{
lightday = 0;
lightnight = 0;
return false;
}
}
u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]

View File

@ -150,9 +150,31 @@ struct MapNode
}
void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
u8 getPropagatedLight(enum LightBank bank, INodeDefManager *nodemgr) const;
bool getPropagatedLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const;
u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
bool getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const;
// 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN
u8 getPropagatedLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
{
u8 lightday = 0;
u8 lightnight = 0;
getPropagatedLightBanks(lightday, lightnight, nodemgr);
return blend_light(daylight_factor, lightday, lightnight);
}
// 0.0 <= daylight_factor <= 1.0
// 0 <= return value <= LIGHT_SUN
u8 getPropagatedLightBlendF1(float daylight_factor, INodeDefManager *nodemgr) const
{
u8 lightday = 0;
u8 lightnight = 0;
getPropagatedLightBanks(lightday, lightnight, nodemgr);
return blend_light_f1(daylight_factor, lightday, lightnight);
}
// 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN
u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const

View File

@ -3773,10 +3773,8 @@ private:
}
}
// EnvRef:get_node_light(pos, timeofday)
// pos = {x=num, y=num, z=num}
// timeofday: nil = current time, 0 = night, 0.5 = day
static int l_get_node_light(lua_State *L)
// Internal light level code
static int l_get_node_light_internal(lua_State *L, bool propagated_only)
{
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
@ -3792,7 +3790,8 @@ private:
try{
MapNode n = env->getMap().getNode(pos);
INodeDefManager *ndef = env->getGameDef()->ndef();
lua_pushinteger(L, n.getLightBlend(dnr, ndef));
int level = propagated_only ? n.getPropagatedLightBlend(dnr, ndef) : n.getLightBlend(dnr, ndef);
lua_pushinteger(L, level);
return 1;
} catch(InvalidPositionException &e)
{
@ -3801,6 +3800,22 @@ private:
}
}
// EnvRef:get_node_propagated_light(pos, timeofday)
// pos = {x=num, y=num, z=num}
// timeofday: nil = current time, 0 = night, 0.5 = day
static int l_get_node_propagated_light(lua_State *L)
{
return l_get_node_light_internal(L, true);
}
// EnvRef:get_node_light(pos, timeofday)
// pos = {x=num, y=num, z=num}
// timeofday: nil = current time, 0 = night, 0.5 = day
static int l_get_node_light(lua_State *L)
{
return l_get_node_light_internal(L, false);
}
// EnvRef:place_node(pos, node)
// pos = {x=num, y=num, z=num}
static int l_place_node(lua_State *L)
@ -4321,6 +4336,7 @@ const luaL_reg EnvRef::methods[] = {
method(EnvRef, remove_node),
method(EnvRef, get_node),
method(EnvRef, get_node_or_nil),
method(EnvRef, get_node_propagated_light),
method(EnvRef, get_node_light),
method(EnvRef, place_node),
method(EnvRef, dig_node),