Update inventory texture too
[oweals/minetest.git] / src / environment.cpp
index e75e967c28dc4fee98e6e89646f965f4191b14d7..e03007341978a9fd564b94b9b017901afb801dc9 100644 (file)
@@ -30,6 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "profiler.h"
 #include "scriptapi.h"
+#include "nodedef.h"
+#include "nodemetadata.h"
+#include "main.h" // For g_settings, g_profiler
+#include "gamedef.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 
@@ -268,9 +272,11 @@ void ActiveBlockList::update(core::list<v3s16> &active_positions,
        ServerEnvironment
 */
 
-ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L):
+ServerEnvironment::ServerEnvironment(ServerMap *map, lua_State *L,
+               IGameDef *gamedef):
        m_map(map),
        m_lua(L),
+       m_gamedef(gamedef),
        m_random_spawn_timer(3),
        m_send_recommended_timer(0),
        m_game_time(0),
@@ -310,7 +316,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
                //infostream<<"Checking player file "<<path<<std::endl;
 
                // Load player to see what is its name
-               ServerRemotePlayer testplayer;
+               ServerRemotePlayer testplayer(this);
                {
                        // Open file and deserialize
                        std::ifstream is(path.c_str(), std::ios_base::binary);
@@ -424,7 +430,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                infostream<<"Checking player file "<<path<<std::endl;
 
                // Load player to see what is its name
-               ServerRemotePlayer testplayer;
+               ServerRemotePlayer testplayer(this);
                {
                        // Open file and deserialize
                        std::ifstream is(path.c_str(), std::ios_base::binary);
@@ -452,7 +458,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                if(player == NULL)
                {
                        infostream<<"Is a new player"<<std::endl;
-                       player = new ServerRemotePlayer();
+                       player = new ServerRemotePlayer(this);
                        newplayer = true;
                }
 
@@ -552,9 +558,9 @@ void spawnRandomObjects(MapBlock *block)
                        MapNode n = block->getNodeNoEx(p);
                        if(n.getContent() == CONTENT_IGNORE)
                                continue;
-                       if(content_features(n).liquid_type != LIQUID_NONE)
+                       if(m_gamedef->ndef()->get(n).liquid_type != LIQUID_NONE)
                                continue;
-                       if(content_features(n).walkable)
+                       if(m_gamedef->ndef()->get(n).walkable)
                        {
                                last_node_walkable = true;
                                continue;
@@ -562,7 +568,7 @@ void spawnRandomObjects(MapBlock *block)
                        if(last_node_walkable)
                        {
                                // If block contains light information
-                               if(content_features(n).param_type == CPT_LIGHT)
+                               if(m_gamedef->ndef()->get(n).param_type == CPT_LIGHT)
                                {
                                        if(n.getLight(LIGHTBANK_DAY) <= 5)
                                        {
@@ -606,7 +612,7 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
        activateObjects(block);
 
        // Run node metadata
-       bool changed = block->m_node_metadata.step((float)dtime_s);
+       bool changed = block->m_node_metadata->step((float)dtime_s);
        if(changed)
        {
                MapEditEvent event;
@@ -636,8 +642,8 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
                        if(dtime_s > 300)
                        {
                                MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
-                               if(content_features(n_top).air_equivalent &&
-                                               n_top.getLight(LIGHTBANK_DAY) >= 13)
+                               if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+                                               n_top.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) >= 13)
                                {
                                        n.setContent(CONTENT_GRASS);
                                        m_map->addNodeWithEvent(p, n);
@@ -916,7 +922,7 @@ void ServerEnvironment::step(float dtime)
                        block->setTimestampNoChangedFlag(m_game_time);
 
                        // Run node metadata
-                       bool changed = block->m_node_metadata.step(dtime);
+                       bool changed = block->m_node_metadata->step(dtime);
                        if(changed)
                        {
                                MapEditEvent event;
@@ -1007,8 +1013,9 @@ void ServerEnvironment::step(float dtime)
                                        if(myrand()%20 == 0)
                                        {
                                                MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
-                                               if(content_features(n_top).air_equivalent &&
-                                                               n_top.getLightBlend(getDayNightRatio()) >= 13)
+                                               if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+                                                               n_top.getLightBlend(getDayNightRatio(),
+                                                                               m_gamedef->ndef()) >= 13)
                                                {
                                                        n.setContent(CONTENT_GRASS);
                                                        m_map->addNodeWithEvent(p, n);
@@ -1023,7 +1030,7 @@ void ServerEnvironment::step(float dtime)
                                        //if(myrand()%20 == 0)
                                        {
                                                MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
-                                               if(content_features(n_top).air_equivalent == false)
+                                               if(m_gamedef->ndef()->get(n_top).air_equivalent == false)
                                                {
                                                        n.setContent(CONTENT_MUD);
                                                        m_map->addNodeWithEvent(p, n);
@@ -1061,7 +1068,8 @@ void ServerEnvironment::step(float dtime)
                                        {
                                                v3s16 p1 = p + v3s16(0,1,0);
                                                MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
-                                               if(n1a.getLightBlend(getDayNightRatio()) <= 3){
+                                               if(n1a.getLightBlend(getDayNightRatio(),
+                                                               m_gamedef->ndef()) <= 3){
                                                        MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
                                                        if(n1a.getContent() == CONTENT_AIR &&
                                                                        n1b.getContent() == CONTENT_AIR)
@@ -1141,6 +1149,11 @@ void ServerEnvironment::step(float dtime)
                }
        }
        
+       /*
+               Step script environment (run global on_step())
+       */
+       scriptapi_environment_step(m_lua, dtime);
+
        /*
                Step active objects
        */
@@ -1500,7 +1513,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->getId());
+       object->addedToEnvironment();
 
        return object->getId();
 }
@@ -1749,8 +1762,10 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                        if(n){
                                StaticObject static_old = n->getValue();
 
+                               float save_movem = obj->getMinimumSavedMovement();
+
                                if(static_old.data == staticdata_new &&
-                                               (static_old.pos - objectpos).getLength() < 2*BS)
+                                               (static_old.pos - objectpos).getLength() < save_movem)
                                        data_changed = false;
                        } else {
                                errorstream<<"ServerEnvironment::deactivateFarObjects(): "
@@ -1759,6 +1774,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                                                <<PP(obj->m_static_block)<<std::endl;
                        }
                }
+
+               bool shall_be_written = (!stays_in_same_block || data_changed);
                
                // Delete old static object
                if(obj->m_static_exists)
@@ -1769,7 +1786,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                                block->m_static_objects.remove(id);
                                obj->m_static_exists = false;
                                // Only mark block as modified if data changed considerably
-                               if(!stays_in_same_block || data_changed)
+                               if(shall_be_written)
                                        block->raiseModified(MOD_STATE_WRITE_NEEDED);
                        }
                }
@@ -1794,7 +1811,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                                block->m_static_objects.insert(new_id, s_obj);
                                
                                // Only mark block as modified if data changed considerably
-                               if(!stays_in_same_block || data_changed)
+                               if(shall_be_written)
                                        block->raiseModified(MOD_STATE_WRITE_NEEDED);
                                
                                obj->m_static_exists = true;
@@ -1851,9 +1868,12 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
        ClientEnvironment
 */
 
-ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr):
+ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
+               ITextureSource *texturesource, IGameDef *gamedef):
        m_map(map),
-       m_smgr(smgr)
+       m_smgr(smgr),
+       m_texturesource(texturesource),
+       m_gamedef(gamedef)
 {
        assert(m_map);
        assert(m_smgr);
@@ -2052,11 +2072,11 @@ void ClientEnvironment::step(float dtime)
 
                u32 damage_per_second = 0;
                damage_per_second = MYMAX(damage_per_second,
-                               content_features(n1).damage_per_second);
+                               m_gamedef->ndef()->get(n1).damage_per_second);
                damage_per_second = MYMAX(damage_per_second,
-                               content_features(n2).damage_per_second);
+                               m_gamedef->ndef()->get(n2).damage_per_second);
                damage_per_second = MYMAX(damage_per_second,
-                               content_features(n3).damage_per_second);
+                               m_gamedef->ndef()->get(n3).damage_per_second);
                
                if(damage_per_second != 0)
                {
@@ -2092,7 +2112,7 @@ void ClientEnvironment::step(float dtime)
                        // Get node at head
                        v3s16 p = player->getLightPosition();
                        MapNode n = m_map->getNode(p);
-                       light = n.getLightBlend(getDayNightRatio());
+                       light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
                }
                catch(InvalidPositionException &e) {}
                player->updateLight(light);
@@ -2147,7 +2167,7 @@ void ClientEnvironment::step(float dtime)
                                // Get node at head
                                v3s16 p = obj->getLightPosition();
                                MapNode n = m_map->getNode(p);
-                               light = n.getLightBlend(getDayNightRatio());
+                               light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
                        }
                        catch(InvalidPositionException &e) {}
                        obj->updateLight(light);
@@ -2231,14 +2251,15 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
        infostream<<"ClientEnvironment::addActiveObject(): "
                        <<"added (id="<<object->getId()<<")"<<std::endl;
        m_active_objects.insert(object->getId(), object);
-       object->addToScene(m_smgr);
+       // TODO: Make g_texturesource non-global
+       object->addToScene(m_smgr, m_texturesource);
        return object->getId();
 }
 
 void ClientEnvironment::addActiveObject(u16 id, u8 type,
                const std::string &init_data)
 {
-       ClientActiveObject* obj = ClientActiveObject::create(type);
+       ClientActiveObject* obj = ClientActiveObject::create(type, m_gamedef);
        if(obj == NULL)
        {
                infostream<<"ClientEnvironment::addActiveObject(): "