summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/builtin.lua1
-rw-r--r--builtin/falling.lua136
-rw-r--r--builtin/item_entity.lua16
-rw-r--r--builtin/misc_register.lua2
-rw-r--r--doc/lua_api.txt9
-rw-r--r--games/minimal/mods/default/init.lua79
-rw-r--r--src/content_cao.cpp30
-rw-r--r--src/content_mapblock.cpp16
-rw-r--r--src/content_sao.cpp10
-rw-r--r--src/content_sao.h4
-rw-r--r--src/environment.cpp40
-rw-r--r--src/environment.h4
-rw-r--r--src/mapgen.cpp2
-rw-r--r--src/mesh.cpp3
-rw-r--r--src/noise.cpp2
-rw-r--r--src/scriptapi.cpp24
-rw-r--r--src/scriptapi.h2
-rw-r--r--src/serverobject.h2
-rw-r--r--src/tile.cpp40
19 files changed, 288 insertions, 134 deletions
diff --git a/builtin/builtin.lua b/builtin/builtin.lua
index a17841fc8..f2811fa9c 100644
--- a/builtin/builtin.lua
+++ b/builtin/builtin.lua
@@ -22,4 +22,5 @@ dofile(minetest.get_modpath("__builtin").."/auth.lua")
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")
dofile(minetest.get_modpath("__builtin").."/detached_inventory.lua")
+dofile(minetest.get_modpath("__builtin").."/falling.lua")
diff --git a/builtin/falling.lua b/builtin/falling.lua
new file mode 100644
index 000000000..4a7f4167e
--- /dev/null
+++ b/builtin/falling.lua
@@ -0,0 +1,136 @@
+-- Minetest: builtin/item.lua
+
+--
+-- Falling stuff
+--
+
+minetest.register_entity("__builtin:falling_node", {
+ initial_properties = {
+ physical = true,
+ collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
+ visual = "wielditem",
+ textures = {},
+ visual_size = {x=0.667, y=0.667},
+ },
+
+ nodename = "",
+
+ set_node = function(self, nodename)
+ self.nodename = nodename
+ local stack = ItemStack(nodename)
+ local itemtable = stack:to_table()
+ local itemname = nil
+ if itemtable then
+ itemname = stack:to_table().name
+ end
+ local item_texture = nil
+ local item_type = ""
+ if minetest.registered_items[itemname] then
+ item_texture = minetest.registered_items[itemname].inventory_image
+ item_type = minetest.registered_items[itemname].type
+ end
+ prop = {
+ is_visible = true,
+ textures = {nodename},
+ }
+ self.object:set_properties(prop)
+ end,
+
+ get_staticdata = function(self)
+ return self.nodename
+ end,
+
+ on_activate = function(self, staticdata)
+ self.nodename = staticdata
+ self.object:set_armor_groups({immortal=1})
+ --self.object:setacceleration({x=0, y=-10, z=0})
+ self:set_node(self.nodename)
+ end,
+
+ on_step = function(self, dtime)
+ -- Set gravity
+ self.object:setacceleration({x=0, y=-10, z=0})
+ -- Turn to actual sand when collides to ground or just move
+ local pos = self.object:getpos()
+ local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
+ local bcn = minetest.env:get_node(bcp)
+ -- Note: walkable is in the node definition, not in item groups
+ if minetest.registered_nodes[bcn.name] and
+ minetest.registered_nodes[bcn.name].walkable then
+ local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
+ -- Check what's here
+ local n2 = minetest.env:get_node(np)
+ -- If it's not air or liquid, remove node and replace it with
+ -- it's drops
+ if n2.name ~= "air" and (not minetest.registered_nodes[n2.name] or
+ minetest.registered_nodes[n2.name].liquidtype == "none") then
+ local drops = minetest.get_node_drops(n2.name, "")
+ minetest.env:remove_node(np)
+ -- Add dropped items
+ local _, dropped_item
+ for _, dropped_item in ipairs(drops) do
+ minetest.env:add_item(np, dropped_item)
+ end
+ -- Run script hook
+ local _, callback
+ for _, callback in ipairs(minetest.registered_on_dignodes) do
+ callback(np, n2, nil)
+ end
+ end
+ -- Create node and remove entity
+ minetest.env:add_node(np, {name=self.nodename})
+ self.object:remove()
+ else
+ -- Do nothing
+ end
+ end
+})
+
+function spawn_falling_node(p, nodename)
+ obj = minetest.env:add_entity(p, "__builtin:falling_node")
+ obj:get_luaentity():set_node(nodename)
+end
+
+--
+-- Some common functions
+--
+
+function nodeupdate_single(p)
+ n = minetest.env:get_node(p)
+ if minetest.get_node_group(n.name, "falling_node") ~= 0 then
+ p_bottom = {x=p.x, y=p.y-1, z=p.z}
+ n_bottom = minetest.env:get_node(p_bottom)
+ -- Note: walkable is in the node definition, not in item groups
+ if minetest.registered_nodes[n_bottom.name] and
+ not minetest.registered_nodes[n_bottom.name].walkable then
+ minetest.env:remove_node(p)
+ spawn_falling_node(p, n.name)
+ nodeupdate(p)
+ end
+ end
+end
+
+function nodeupdate(p)
+ for x = -1,1 do
+ for y = -1,1 do
+ for z = -1,1 do
+ p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
+ nodeupdate_single(p2)
+ end
+ end
+ end
+end
+
+--
+-- Global callbacks
+--
+
+function on_placenode(p, node)
+ nodeupdate(p)
+end
+minetest.register_on_placenode(on_placenode)
+
+function on_dignode(p, node)
+ nodeupdate(p)
+end
+minetest.register_on_dignode(on_dignode)
diff --git a/builtin/item_entity.lua b/builtin/item_entity.lua
index 2d763d50b..2b12764f1 100644
--- a/builtin/item_entity.lua
+++ b/builtin/item_entity.lua
@@ -57,11 +57,23 @@ minetest.register_entity("__builtin:item", {
end,
get_staticdata = function(self)
- return self.itemstring
+ --return self.itemstring
+ return minetest.serialize({
+ itemstring = self.itemstring,
+ always_collect = self.always_collect,
+ })
end,
on_activate = function(self, staticdata)
- self.itemstring = staticdata
+ if string.sub(staticdata, 1, string.len("return")) == "return" then
+ local data = minetest.deserialize(staticdata)
+ if data and type(data) == "table" then
+ self.itemstring = data.itemstring
+ self.always_collect = data.always_collect
+ end
+ else
+ self.itemstring = staticdata
+ end
self.object:set_armor_groups({immortal=1})
self.object:setvelocity({x=0, y=2, z=0})
self.object:setacceleration({x=0, y=-10, z=0})
diff --git a/builtin/misc_register.lua b/builtin/misc_register.lua
index 4894e71bc..77c594de2 100644
--- a/builtin/misc_register.lua
+++ b/builtin/misc_register.lua
@@ -259,6 +259,7 @@ minetest.register_node(":air", {
diggable = false,
buildable_to = true,
air_equivalent = true,
+ drop = "",
groups = {not_in_creative_inventory=1},
})
@@ -274,6 +275,7 @@ minetest.register_node(":ignore", {
diggable = false,
buildable_to = true, -- A way to remove accidentally placed ignores
air_equivalent = true,
+ drop = "",
groups = {not_in_creative_inventory=1},
})
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 36dd6b2aa..301832618 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -456,6 +456,7 @@ Special groups
- disable_jump: Player (and possibly other things) cannot jump from node
- fall_damage_add_percent: damage speed = speed * (1 + value/100)
- bouncy: value is bounce speed in percent
+- falling_node: if there is no walkable block under the node it will fall
Known damage and digging time defining groups
----------------------------------------------
@@ -1087,6 +1088,7 @@ methods:
- punch(puncher, time_from_last_punch, tool_capabilities, direction)
^ puncher = an another ObjectRef,
^ time_from_last_punch = time since last punch action of the puncher
+ ^ direction: can be nil
- right_click(clicker); clicker = an another ObjectRef
- get_hp(): returns number of hitpoints (2 * number of hearts)
- set_hp(hp): set number of hitpoints (2 * number of hearts)
@@ -1236,7 +1238,7 @@ Entity definition (register_entity)
initial_properties = <initial object properties>,
- on_activate = function(self, staticdata),
+ on_activate = function(self, staticdata, dtime_s),
on_step = function(self, dtime),
on_punch = function(self, hitter),
on_rightclick = function(self, clicker),
@@ -1422,6 +1424,11 @@ Node definition (register_node)
on_metadata_inventory_take = func(pos, listname, index, stack, player),
^ Called after the actual action has happened, according to what was allowed.
^ No return value
+
+ on_blast = func(pos, intensity),
+ ^ intensity: 1.0 = mid range of regular TNT
+ ^ If defined, called when an explosion touches the node, instead of
+ removing the node
}
Recipe for register_craft: (shaped)
diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua
index 176fe899b..5f4d8e063 100644
--- a/games/minimal/mods/default/init.lua
+++ b/games/minimal/mods/default/init.lua
@@ -769,7 +769,7 @@ minetest.register_node("default:sand", {
description = "Sand",
tiles ={"default_sand.png"},
is_ground_content = true,
- groups = {crumbly=3},
+ groups = {crumbly=3, falling_node=1},
sounds = default.node_sound_sand_defaults(),
})
@@ -777,7 +777,7 @@ minetest.register_node("default:gravel", {
description = "Gravel",
tiles ={"default_gravel.png"},
is_ground_content = true,
- groups = {crumbly=2},
+ groups = {crumbly=2, falling_node=1},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_gravel_footstep", gain=0.45},
}),
@@ -1586,73 +1586,22 @@ minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
minetest.register_alias("mapgen_mese", "default:mese")
---
--- Some common functions
---
-
-default.falling_node_names = {}
-
-function nodeupdate_single(p)
- n = minetest.env:get_node(p)
- if default.falling_node_names[n.name] ~= nil then
- p_bottom = {x=p.x, y=p.y-1, z=p.z}
- n_bottom = minetest.env:get_node(p_bottom)
- if n_bottom.name == "air" then
- minetest.env:remove_node(p)
- minetest.env:add_entity(p, "default:falling_"..n.name)
- nodeupdate(p)
- end
- end
-end
-
-function nodeupdate(p)
- for x = -1,1 do
- for y = -1,1 do
- for z = -1,1 do
- p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
- nodeupdate_single(p2)
- end
- end
- end
+-- Support old code
+function default.spawn_falling_node(p, nodename)
+ spawn_falling_node(p, nodename)
end
---
--- Falling stuff
---
-
+-- Horrible crap to support old code
+-- Don't use this and never do what this does, it's completely wrong!
+-- (More specifically, the client and the C++ code doesn't get the group)
function default.register_falling_node(nodename, texture)
- default.falling_node_names[nodename] = true
- -- Override naming conventions for stuff like :default:falling_default:sand
- minetest.register_entity(":default:falling_"..nodename, {
- -- Static definition
- physical = true,
- collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
- visual = "cube",
- textures = {texture,texture,texture,texture,texture,texture},
- -- State
- -- Methods
- on_step = function(self, dtime)
- -- Set gravity
- self.object:setacceleration({x=0, y=-10, z=0})
- -- Turn to actual sand when collides to ground or just move
- local pos = self.object:getpos()
- local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
- local bcn = minetest.env:get_node(bcp)
- if bcn.name ~= "air" then
- -- Turn to a sand node
- local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
- minetest.env:add_node(np, {name=nodename})
- self.object:remove()
- else
- -- Do nothing
- end
- end
- })
+ minetest.log("error", debug.traceback())
+ minetest.log('error', "WARNING: default.register_falling_node is deprecated")
+ if minetest.registered_nodes[nodename] then
+ minetest.registered_nodes[nodename].groups.falling_node = 1
+ end
end
-default.register_falling_node("default:sand", "default_sand.png")
-default.register_falling_node("default:gravel", "default_gravel.png")
-
--
-- Global callbacks
--
@@ -1665,13 +1614,11 @@ minetest.register_globalstep(on_step)
function on_placenode(p, node)
--print("on_placenode")
- nodeupdate(p)
end
minetest.register_on_placenode(on_placenode)
function on_dignode(p, node)
--print("on_dignode")
- nodeupdate(p)
end
minetest.register_on_dignode(on_dignode)
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index aa5c2d674..cb14cf395 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -40,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/serialize.h"
#include "util/mathconstants.h"
#include "map.h"
+#include <IMeshManipulator.h>
class Settings;
struct ToolCapabilities;
@@ -797,8 +798,15 @@ public:
infostream<<"textures[0]: "<<m_prop.textures[0]<<std::endl;
IItemDefManager *idef = m_gamedef->idef();
ItemStack item(m_prop.textures[0], 1, 0, "", idef);
- scene::IMesh *mesh = item.getDefinition(idef).wield_mesh;
+ scene::IMesh *item_mesh = item.getDefinition(idef).wield_mesh;
+
+ // Copy mesh to be able to set unique vertex colors
+ scene::IMeshManipulator *manip =
+ irr->getVideoDriver()->getMeshManipulator();
+ scene::IMesh *mesh = manip->createMeshUniquePrimitives(item_mesh);
+
m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
+ mesh->drop();
m_meshnode->setScale(v3f(m_prop.visual_size.X/2,
m_prop.visual_size.Y/2,
@@ -838,15 +846,17 @@ public:
{
bool is_visible = (m_hp != 0);
u8 li = decode_light(light_at_pos);
- m_last_light = li;
- video::SColor color(255,li,li,li);
- if(m_meshnode){
- setMeshColor(m_meshnode->getMesh(), color);
- m_meshnode->setVisible(is_visible);
- }
- if(m_spritenode){
- m_spritenode->setColor(color);
- m_spritenode->setVisible(is_visible);
+ if(li != m_last_light){
+ m_last_light = li;
+ video::SColor color(255,li,li,li);
+ if(m_meshnode){
+ setMeshColor(m_meshnode->getMesh(), color);
+ m_meshnode->setVisible(is_visible);
+ }
+ if(m_spritenode){
+ m_spritenode->setColor(color);
+ m_spritenode->setVisible(is_visible);
+ }
}
}
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index ad819e793..ff8ef5276 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -492,15 +492,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// -Z towards +Z, thus the direction is +Z.
// Rotate texture to make animation go in flow direction
// Positive if liquid moves towards +Z
- int dz = (corner_levels[side_corners[2][0]] +
- corner_levels[side_corners[2][1]] <
- corner_levels[side_corners[3][0]] +
- corner_levels[side_corners[3][1]]);
+ int dz = (corner_levels[side_corners[3][0]] +
+ corner_levels[side_corners[3][1]]) -
+ (corner_levels[side_corners[2][0]] +
+ corner_levels[side_corners[2][1]]);
// Positive if liquid moves towards +X
- int dx = (corner_levels[side_corners[0][0]] +
- corner_levels[side_corners[0][1]] <
- corner_levels[side_corners[1][0]] +
- corner_levels[side_corners[1][1]]);
+ int dx = (corner_levels[side_corners[1][0]] +
+ corner_levels[side_corners[1][1]]) -
+ (corner_levels[side_corners[0][0]] +
+ corner_levels[side_corners[0][1]]);
// -X
if(-dx >= abs(dz))
{
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 843ab29f7..7526e0353 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -376,9 +376,9 @@ LuaEntitySAO::~LuaEntitySAO()
}
}
-void LuaEntitySAO::addedToEnvironment()
+void LuaEntitySAO::addedToEnvironment(u32 dtime_s)
{
- ServerActiveObject::addedToEnvironment();
+ ServerActiveObject::addedToEnvironment(dtime_s);
// Create entity from name
lua_State *L = m_env->getLua();
@@ -390,7 +390,7 @@ void LuaEntitySAO::addedToEnvironment()
// Initialize HP from properties
m_hp = m_prop.hp_max;
// Activate entity, supplying serialized state
- scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
+ scriptapi_luaentity_activate(L, m_id, m_init_state.c_str(), dtime_s);
}
}
@@ -805,9 +805,9 @@ std::string PlayerSAO::getDescription()
}
// Called after id has been set and has been inserted in environment
-void PlayerSAO::addedToEnvironment()
+void PlayerSAO::addedToEnvironment(u32 dtime_s)
{
- ServerActiveObject::addedToEnvironment();
+ ServerActiveObject::addedToEnvironment(dtime_s);
ServerActiveObject::setBasePosition(m_player->getPosition());
m_player->setPlayerSAO(this);
m_player->peer_id = m_peer_id;
diff --git a/src/content_sao.h b/src/content_sao.h
index ff427bac6..05c77e2cb 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -43,7 +43,7 @@ public:
{ return ACTIVEOBJECT_TYPE_LUAENTITY; }
u8 getSendType() const
{ return ACTIVEOBJECT_TYPE_GENERIC; }
- virtual void addedToEnvironment();
+ virtual void addedToEnvironment(u32 dtime_s);
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
@@ -118,7 +118,7 @@ public:
Active object <-> environment interface
*/
- void addedToEnvironment();
+ void addedToEnvironment(u32 dtime_s);
void removingFromEnvironment();
bool isStaticAllowed() const;
bool unlimitedTransferDistance() const;
diff --git a/src/environment.cpp b/src/environment.cpp
index a49a5e384..4abba6359 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -743,19 +743,25 @@ neighbor_found:
u32 active_object_count = block->m_static_objects.m_active.size();
// Find out how many objects this and all the neighbors contain
u32 active_object_count_wider = 0;
+ u32 wider_unknown_count = 0;
for(s16 x=-1; x<=1; x++)
for(s16 y=-1; y<=1; y++)
for(s16 z=-1; z<=1; z++)
{
MapBlock *block2 = map->getBlockNoCreateNoEx(
block->getPos() + v3s16(x,y,z));
- if(block2==NULL)
+ if(block2==NULL){
+ wider_unknown_count = 0;
continue;
+ }
active_object_count_wider +=
block2->m_static_objects.m_active.size()
+ block2->m_static_objects.m_stored.size();
}
-
+ // Extrapolate
+ u32 wider_known_count = 3*3*3 - wider_unknown_count;
+ active_object_count_wider += wider_unknown_count * active_object_count_wider / wider_known_count;
+
// Call all the trigger variations
i->abm->trigger(m_env, p, n);
i->abm->trigger(m_env, p, n,
@@ -784,7 +790,7 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
<<dtime_s<<" seconds old."<<std::endl;*/
// Activate stored objects
- activateObjects(block);
+ activateObjects(block, dtime_s);
// Run node timers
std::map<v3s16, NodeTimer> elapsed_timers =
@@ -1243,7 +1249,7 @@ u16 getFreeServerActiveObjectId(
u16 ServerEnvironment::addActiveObject(ServerActiveObject *object)
{
assert(object);
- u16 id = addActiveObjectRaw(object, true);
+ u16 id = addActiveObjectRaw(object, true, 0);
return id;
}
@@ -1402,7 +1408,7 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
*/
u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
- bool set_changed)
+ bool set_changed, u32 dtime_s)
{
assert(object);
if(object->getId() == 0){
@@ -1442,7 +1448,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
// Register reference in scripting api (must be done before post-init)
scriptapi_add_object_reference(m_lua, object);
// Post-initialize object
- object->addedToEnvironment();
+ object->addedToEnvironment(dtime_s);
// Add static data to block
if(object->isStaticAllowed())
@@ -1465,9 +1471,10 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
"addActiveObjectRaw");
}
else{
+ v3s16 p = floatToInt(objectpos, BS);
errorstream<<"ServerEnvironment::addActiveObjectRaw(): "
<<"could not find block for storing id="<<object->getId()
- <<" statically"<<std::endl;
+ <<" statically (pos="<<PP(p)<<")"<<std::endl;
}
}
@@ -1578,7 +1585,7 @@ static void print_hexdump(std::ostream &o, const std::string &data)
/*
Convert stored objects from blocks near the players to active.
*/
-void ServerEnvironment::activateObjects(MapBlock *block)
+void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
{
if(block==NULL)
return;
@@ -1602,7 +1609,7 @@ void ServerEnvironment::activateObjects(MapBlock *block)
"large amount of objects");
return;
}
- // A list for objects that couldn't be converted to static for some
+ // A list for objects that couldn't be converted to active for some
// reason. They will be stored back.
core::list<StaticObject> new_stored;
// Loop through stored static objects
@@ -1632,7 +1639,7 @@ void ServerEnvironment::activateObjects(MapBlock *block)
<<"activated static object pos="<<PP(s_obj.pos/BS)
<<" type="<<(int)s_obj.type<<std::endl;
// This will also add the object to the active static list
- addActiveObjectRaw(obj, false);
+ addActiveObjectRaw(obj, false, dtime_s);
}
// Clear stored list
block->m_static_objects.m_stored.clear();
@@ -1756,7 +1763,12 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
// Add to the block where the object is located in
v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
// Get or generate the block
- MapBlock *block = m_map->emergeBlock(blockpos);
+ MapBlock *block = NULL;
+ try{
+ block = m_map->emergeBlock(blockpos);
+ } catch(InvalidPositionException &e){
+ // Handled via NULL pointer
+ }
if(block)
{
@@ -1793,9 +1805,10 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
}
else{
if(!force_delete){
+ v3s16 p = floatToInt(objectpos, BS);
errorstream<<"ServerEnv: Could not find or generate "
<<"a block for storing id="<<obj->getId()
- <<" statically"<<std::endl;
+ <<" statically (pos="<<PP(p)<<")"<<std::endl;
continue;
}
}
@@ -2129,6 +2142,7 @@ void ClientEnvironment::step(float dtime)
Step active objects and update lighting of them
*/
+ bool update_lighting = m_active_object_light_update_interval.step(dtime, 0.21);
for(core::map<u16, ClientActiveObject*>::Iterator
i = m_active_objects.getIterator();
i.atEnd()==false; i++)
@@ -2137,7 +2151,7 @@ void ClientEnvironment::step(float dtime)
// Step object
obj->step(dtime, this);
- if(m_active_object_light_update_interval.step(dtime, 0.21))
+ if(update_lighting)
{
// Update lighting
u8 light = 0;
diff --git a/src/environment.h b/src/environment.h
index bb1da2461..042229038 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -312,7 +312,7 @@ private:
Returns the id of the object.
Returns 0 if not added and thus deleted.
*/
- u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed);
+ u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed, u32 dtime_s);
/*
Remove all objects that satisfy (m_removed && m_known_by_count==0)
@@ -322,7 +322,7 @@ private:
/*
Convert stored objects from block to active
*/
- void activateObjects(MapBlock *block);
+ void activateObjects(MapBlock *block, u32 dtime_s);
/*
Convert objects that are not in active blocks to static.
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 67e92f449..77b133020 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -1228,7 +1228,7 @@ double base_rock_level_2d(u64 seed, v2s16 p)
0.5+(float)p.X/125., 0.5+(float)p.Y/125.,
seed-932, 5, 0.7);
b = rangelim(b, 0.0, 1000.0);
- b = pow(b, 7);
+ b = b*b*b*b*b*b*b;
b *= 5;
b = rangelim(b, 0.5, 1000.0);
// Values 1.5...100 give quite horrible looking slopes
diff --git a/src/mesh.cpp b/src/mesh.cpp
index 0f075f72b..b9ec82e18 100644
--- a/src/mesh.cpp
+++ b/src/mesh.cpp
@@ -433,6 +433,9 @@ video::ITexture *generateTextureFromMesh(scene::IMesh *mesh,
}
// Create render target texture
+ video::ITexture *oldtexture = driver->findTexture(texture_name.c_str());
+ if(oldtexture)
+ driver->removeTexture(oldtexture);
video::ITexture *rtt = driver->addRenderTargetTexture(
dim, texture_name.c_str(), video::ECF_A8R8G8B8);
if(rtt == NULL)
diff --git a/src/noise.cpp b/src/noise.cpp
index 4a7fc87e7..e75fbf4bd 100644
--- a/src/noise.cpp
+++ b/src/noise.cpp
@@ -37,7 +37,7 @@ double dotProduct(double vx, double vy, double wx, double wy){
}
double easeCurve(double t){
- return 6*pow(t,5)-15*pow(t,4)+10*pow(t,3);
+ return t * t * t * (6. * t * t - 15. * t + 10.);
}
double linearInterpolation(double x0, double x1, double t){
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index e87c35482..09900ce1f 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -2543,7 +2543,7 @@ private:
return 0;
}
- // punch(self, puncher, tool_capabilities, direction, time_from_last_punch)
+ // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
static int l_punch(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
@@ -2552,13 +2552,18 @@ private:
ServerActiveObject *puncher = getobject(puncher_ref);
if(co == NULL) return 0;
if(puncher == NULL) return 0;
- ToolCapabilities toolcap = read_tool_capabilities(L, 3);
- v3f dir = read_v3f(L, 4);
+ v3f dir;
+ if(lua_type(L, 5) != LUA_TTABLE)
+ dir = co->getBasePosition() - puncher->getBasePosition();
+ else
+ dir = read_v3f(L, 5);
float time_from_last_punch = 1000000;
- if(lua_isnumber(L, 5))
- time_from_last_punch = lua_tonumber(L, 5);
+ if(lua_isnumber(L, 3))
+ time_from_last_punch = lua_tonumber(L, 3);
+ ToolCapabilities toolcap = read_tool_capabilities(L, 4);
+ dir.normalize();
// Do it
- puncher->punch(dir, &toolcap, puncher, time_from_last_punch);
+ co->punch(dir, &toolcap, puncher, time_from_last_punch);
return 0;
}
@@ -6479,7 +6484,7 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name)
}
void scriptapi_luaentity_activate(lua_State *L, u16 id,
- const std::string &staticdata)
+ const std::string &staticdata, u32 dtime_s)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
@@ -6497,8 +6502,9 @@ void scriptapi_luaentity_activate(lua_State *L, u16 id,
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self
lua_pushlstring(L, staticdata.c_str(), staticdata.size());
- // Call with 2 arguments, 0 results
- if(lua_pcall(L, 2, 0, 0))
+ lua_pushinteger(L, dtime_s);
+ // Call with 3 arguments, 0 results
+ if(lua_pcall(L, 3, 0, 0))
script_error(L, "error running function on_activate: %s\n",
lua_tostring(L, -1));
}
diff --git a/src/scriptapi.h b/src/scriptapi.h
index 0ae359112..144cb3bc6 100644
--- a/src/scriptapi.h
+++ b/src/scriptapi.h
@@ -167,7 +167,7 @@ void scriptapi_detached_inventory_on_take(lua_State *L,
// Returns true if succesfully added into Lua; false otherwise.
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name);
void scriptapi_luaentity_activate(lua_State *L, u16 id,
- const std::string &staticdata);
+ const std::string &staticdata, u32 dtime_s);
void scriptapi_luaentity_rm(lua_State *L, u16 id);
std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id);
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
diff --git a/src/serverobject.h b/src/serverobject.h
index 6acd0dfee..ece53fd98 100644
--- a/src/serverobject.h
+++ b/src/serverobject.h
@@ -62,7 +62,7 @@ public:
{ return getType(); }
// Called after id has been set and has been inserted in environment
- virtual void addedToEnvironment(){};
+ virtual void addedToEnvironment(u32 dtime_s){};
// Called before removing from environment
virtual void removingFromEnvironment(){};
// Returns true if object's deletion is the job of the
diff --git a/src/tile.cpp b/src/tile.cpp
index f7f1779ca..e676c56c4 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -519,6 +519,15 @@ core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<
void imageTransform(u32 transform, video::IImage *src, video::IImage *dst);
/*
+ Adds a new texture to the video driver and returns a pointer to it.
+ This pointer should not be dropped. Any texture that was registered
+ with that name before is removed (this may invalidate some ITexture
+ pointers).
+*/
+video::ITexture* register_texture(video::IVideoDriver *driver,
+ std::string name, video::IImage *img);
+
+/*
Generate image based on a string like "stone.png" or "[crack0".
if baseimg is NULL, it is created. Otherwise stuff is made on it.
*/
@@ -686,11 +695,9 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
" create texture \""<<name<<"\""<<std::endl;
}
+ // Create texture from resulting image
if(baseimg != NULL)
- {
- // Create texture from resulting image
- t = driver->addTexture(name.c_str(), baseimg);
- }
+ t = register_texture(driver, name, baseimg);
/*
Add texture to caches (add NULL textures too)
@@ -809,7 +816,7 @@ void TextureSource::rebuildImagesAndTextures()
// Create texture from resulting image
video::ITexture *t = NULL;
if(img)
- t = driver->addTexture(sap->name.c_str(), img);
+ t = register_texture(driver, sap->name, img);
// Replace texture
sap->a.atlas = t;
@@ -1044,7 +1051,7 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
/*
Make texture
*/
- video::ITexture *t = driver->addTexture("__main_atlas__", atlas_img);
+ video::ITexture *t = register_texture(driver, "__main_atlas__", atlas_img);
assert(t);
/*
@@ -1135,6 +1142,15 @@ video::IImage* generate_image_from_scratch(std::string name,
return baseimg;
}
+video::ITexture* register_texture(video::IVideoDriver *driver,
+ std::string name, video::IImage *img)
+{
+ video::ITexture *old_texture = driver->findTexture(name.c_str());
+ if(old_texture)
+ driver->removeTexture(old_texture);
+ return driver->addTexture(name.c_str(), img);
+}
+
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
IrrlichtDevice *device, SourceImageCache *sourcecache)
{
@@ -1541,12 +1557,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
assert(img_top && img_left && img_right);
// Create textures from images
- video::ITexture *texture_top = driver->addTexture(
- (imagename_top + "__temp__").c_str(), img_top);
- video::ITexture *texture_left = driver->addTexture(
- (imagename_left + "__temp__").c_str(), img_left);
- video::ITexture *texture_right = driver->addTexture(
- (imagename_right + "__temp__").c_str(), img_right);
+ video::ITexture *texture_top = register_texture(driver,
+ imagename_top + "__temp1__", img_top);
+ video::ITexture *texture_left = register_texture(driver,
+ imagename_left + "__temp2__", img_left);
+ video::ITexture *texture_right = register_texture(driver,
+ imagename_right + "__temp3__", img_right);
assert(texture_top && texture_left && texture_right);
// Drop images