]> git.lizzy.rs Git - minetest.git/blobdiff - src/clientmap.cpp
Dungeongen: Fix out-of-voxelmanip access segfault
[minetest.git] / src / clientmap.cpp
index 7d76e6e8bff4596493fb3ade62fc4371c6c2c490..11719539fee7b2981fb569ec23caf7bb9b79e749 100644 (file)
@@ -29,19 +29,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "profiler.h"
 #include "settings.h"
 #include "camera.h"               // CameraModes
-#include "util/mathconstants.h"
 #include "util/basic_macros.h"
 #include <algorithm>
 
 ClientMap::ClientMap(
                Client *client,
-               IGameDef *gamedef,
                MapDrawControl &control,
                scene::ISceneNode* parent,
                scene::ISceneManager* mgr,
                s32 id
 ):
-       Map(dout_client, gamedef),
+       Map(dout_client, client),
        scene::ISceneNode(parent, mgr, id),
        m_client(client),
        m_control(control),
@@ -140,7 +138,7 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
        return false;
 }
 
-void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes, 
+void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes,
                v3s16 *p_blocks_min, v3s16 *p_blocks_max)
 {
        v3s16 box_nodes_d = m_control.wanted_range * v3s16(1, 1, 1);
@@ -172,8 +170,6 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
        ScopeProfiler sp(g_profiler, "CM::updateDrawList()", SPT_AVG);
        g_profiler->add("CM::updateDrawList() count", 1);
 
-       INodeDefManager *nodemgr = m_gamedef->ndef();
-
        for (std::map<v3s16, MapBlock*>::iterator i = m_drawlist.begin();
                        i != m_drawlist.end(); ++i) {
                MapBlock *block = i->second;
@@ -219,7 +215,7 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
        if (g_settings->getBool("free_move")) {
                MapNode n = getNodeNoEx(cam_pos_nodes);
                if (n.getContent() == CONTENT_IGNORE ||
-                               nodemgr->get(n).solidness == 2)
+                               m_nodedef->get(n).solidness == 2)
                        occlusion_culling_enabled = false;
        }
 
@@ -297,23 +293,23 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
                        if (occlusion_culling_enabled &&
                                        // For the central point of the mapblock 'endoff' can be halved
                                        isOccluded(this, spn, cpn,
-                                               step, stepfac, startoff, endoff / 2.0f, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff / 2.0f, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(bs2,bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(bs2,-bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(bs2,-bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(-bs2,bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(-bs2,bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr) &&
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef) &&
                                        isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count, nodemgr)) {
+                                               step, stepfac, startoff, endoff, needed_count, m_nodedef)) {
                                blocks_occlusion_culled++;
                                continue;
                        }
@@ -374,10 +370,10 @@ struct MeshBufListList
 
        void add(scene::IMeshBuffer *buf)
        {
+               const video::SMaterial &m = buf->getMaterial();
                for(std::vector<MeshBufList>::iterator i = lists.begin();
                                i != lists.end(); ++i){
                        MeshBufList &l = *i;
-                       video::SMaterial &m = buf->getMaterial();
 
                        // comparing a full material is quite expensive so we don't do it if
                        // not even first texture is equal
@@ -390,7 +386,7 @@ struct MeshBufListList
                        }
                }
                MeshBufList l;
-               l.m = buf->getMaterial();
+               l.m = m;
                l.bufs.push_back(buf);
                lists.push_back(l);
        }
@@ -511,12 +507,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        {
                                scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
 
-                               buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, m_cache_trilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, m_cache_bilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, m_cache_anistropic_filter);
-                               buf->getMaterial().setFlag(video::EMF_WIREFRAME, m_control.show_wireframe);
-
-                               const video::SMaterial& material = buf->getMaterial();
+                               video::SMaterial& material = buf->getMaterial();
                                video::IMaterialRenderer* rnd =
                                                driver->getMaterialRenderer(material.MaterialType);
                                bool transparent = (rnd && rnd->isTransparent());
@@ -524,6 +515,12 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                        if (buf->getVertexCount() == 0)
                                                errorstream << "Block [" << analyze_block(block)
                                                         << "] contains an empty meshbuf" << std::endl;
+
+                                       material.setFlag(video::EMF_TRILINEAR_FILTER, m_cache_trilinear_filter);
+                                       material.setFlag(video::EMF_BILINEAR_FILTER, m_cache_bilinear_filter);
+                                       material.setFlag(video::EMF_ANISOTROPIC_FILTER, m_cache_anistropic_filter);
+                                       material.setFlag(video::EMF_WIREFRAME, m_control.show_wireframe);
+
                                        drawbufs.add(buf);
                                }
                        }
@@ -656,7 +653,6 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
                int oldvalue, bool *sunlight_seen_result)
 {
        const bool debugprint = false;
-       INodeDefManager *ndef = m_gamedef->ndef();
        static v3f z_directions[50] = {
                v3f(-100, 0, 0)
        };
@@ -694,7 +690,7 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
                float off = step * z_offsets[i];
                bool sunlight_seen_now = false;
                bool ok = getVisibleBrightness(this, m_camera_position, dir,
-                               step, 1.0, max_d*0.6+off, max_d, ndef, daylight_factor,
+                               step, 1.0, max_d*0.6+off, max_d, m_nodedef, daylight_factor,
                                sunlight_min_d,
                                &br, &sunlight_seen_now);
                if(sunlight_seen_now)
@@ -734,8 +730,8 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
        int ret = 0;
        if(brightness_count == 0){
                MapNode n = getNodeNoEx(floatToInt(m_camera_position, BS));
-               if(ndef->get(n).param_type == CPT_LIGHT){
-                       ret = decode_light(n.getLightBlend(daylight_factor, ndef));
+               if(m_nodedef->get(n).param_type == CPT_LIGHT){
+                       ret = decode_light(n.getLightBlend(daylight_factor, m_nodedef));
                } else {
                        ret = oldvalue;
                }
@@ -758,8 +754,6 @@ int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor,
 
 void ClientMap::renderPostFx(CameraMode cam_mode)
 {
-       INodeDefManager *nodemgr = m_gamedef->ndef();
-
        // Sadly ISceneManager has no "post effects" render pass, in that case we
        // could just register for that and handle it in renderMap().
 
@@ -768,10 +762,10 @@ void ClientMap::renderPostFx(CameraMode cam_mode)
        // - If the player is in a solid node, make everything black.
        // - If the player is in liquid, draw a semi-transparent overlay.
        // - Do not if player is in third person mode
-       const ContentFeatures& features = nodemgr->get(n);
+       const ContentFeatures& features = m_nodedef->get(n);
        video::SColor post_effect_color = features.post_effect_color;
        if(features.solidness == 2 && !(g_settings->getBool("noclip") &&
-                       m_gamedef->checkLocalPrivilege("noclip")) &&
+                       m_client->checkLocalPrivilege("noclip")) &&
                        cam_mode == CAMERA_MODE_FIRST)
        {
                post_effect_color = video::SColor(255, 0, 0, 0);