summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/camera.cpp11
-rw-r--r--src/camera.h4
-rw-r--r--src/client.cpp58
-rw-r--r--src/client.h26
-rw-r--r--src/collision.cpp17
-rw-r--r--src/collision.h9
-rw-r--r--src/content_mapblock.cpp78
-rw-r--r--src/content_mapblock.h4
-rw-r--r--src/content_mapnode.cpp113
-rw-r--r--src/content_mapnode.h5
-rw-r--r--src/content_sao.cpp20
-rw-r--r--src/content_tool.cpp6
-rw-r--r--src/content_tool.h4
-rw-r--r--src/environment.cpp43
-rw-r--r--src/environment.h2
-rw-r--r--src/game.cpp47
-rw-r--r--src/gamedef.h14
-rw-r--r--src/inventory.cpp6
-rw-r--r--src/main.cpp6
-rw-r--r--src/map.cpp164
-rw-r--r--src/map.h3
-rw-r--r--src/mapblock.cpp48
-rw-r--r--src/mapblock.h14
-rw-r--r--src/mapblock_mesh.cpp69
-rw-r--r--src/mapblock_mesh.h4
-rw-r--r--src/mapgen.cpp14
-rw-r--r--src/mapgen.h4
-rw-r--r--src/mapnode.cpp94
-rw-r--r--src/mapnode.h44
-rw-r--r--src/mapnode_contentfeatures.cpp150
-rw-r--r--src/mapsector.cpp18
-rw-r--r--src/mapsector.h14
-rw-r--r--src/materials.cpp9
-rw-r--r--src/materials.h4
-rw-r--r--src/nodedef.cpp175
-rw-r--r--src/nodedef.h (renamed from src/mapnode_contentfeatures.h)147
-rw-r--r--src/player.cpp54
-rw-r--r--src/player.h32
-rw-r--r--src/server.cpp50
-rw-r--r--src/server.h15
-rw-r--r--src/servermain.cpp7
-rw-r--r--src/test.cpp106
-rw-r--r--src/tile.cpp187
-rw-r--r--src/tile.h143
-rw-r--r--src/tooldef.cpp (renamed from src/tool.cpp)44
-rw-r--r--src/tooldef.h (renamed from src/tool.h)30
-rw-r--r--src/voxel.cpp60
-rw-r--r--src/voxel.h13
49 files changed, 1158 insertions, 1035 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 550bd1f55..0f6c567c3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -95,8 +95,8 @@ configure_file(
set(common_SRCS
content_tool.cpp
- tool.cpp
- mapnode_contentfeatures.cpp
+ tooldef.cpp
+ nodedef.cpp
luaentity_common.cpp
scriptapi.cpp
script.cpp
diff --git a/src/camera.cpp b/src/camera.cpp
index d001f8916..74ecd6cec 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cmath>
#include <SAnimatedMesh.h>
#include "settings.h"
-#include "mapnode_contentfeatures.h" // For wield visualization
+#include "nodedef.h" // For wield visualization
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr),
@@ -449,8 +449,11 @@ void Camera::updateSettings()
m_wanted_frametime = 1.0 / wanted_fps;
}
-void Camera::wield(const InventoryItem* item, ITextureSource *tsrc)
+void Camera::wield(const InventoryItem* item, IGameDef *gamedef)
{
+ ITextureSource *tsrc = gamedef->tsrc();
+ INodeDefManager *ndef = gamedef->ndef();
+
if (item != NULL)
{
bool isCube = false;
@@ -461,9 +464,9 @@ void Camera::wield(const InventoryItem* item, ITextureSource *tsrc)
// A block-type material
MaterialItem* mat_item = (MaterialItem*) item;
content_t content = mat_item->getMaterial();
- if (content_features(content).solidness || content_features(content).visual_solidness)
+ if (ndef->get(content).solidness || ndef->get(content).visual_solidness)
{
- m_wieldnode->setCube(content_features(content).tiles);
+ m_wieldnode->setCube(ndef->get(content).tiles);
m_wieldnode->setScale(v3f(30));
isCube = true;
}
diff --git a/src/camera.h b/src/camera.h
index 29b9fbdaa..8321a1f0d 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class LocalPlayer;
class MapDrawControl;
class ExtrudedSpriteSceneNode;
-class ITextureSource;
+class IGameDef;
/*
Client camera class, manages the player and camera scene nodes, the viewing distance
@@ -116,7 +116,7 @@ public:
void updateSettings();
// Replace the wielded item mesh
- void wield(const InventoryItem* item, ITextureSource *tsrc);
+ void wield(const InventoryItem* item, IGameDef *gamedef);
// Start digging animation
// Pass 0 for left click, 1 for right click
diff --git a/src/client.cpp b/src/client.cpp
index 876d22e8b..d0e5cd405 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -32,6 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h"
#include "log.h"
#include "nodemetadata.h"
+#include "nodedef.h"
+#include "tooldef.h"
/*
QueuedMeshUpdate
@@ -160,7 +162,7 @@ void * MeshUpdateThread::Thread()
ScopeProfiler sp(g_profiler, "Client: Mesh making");
scene::SMesh *mesh_new = NULL;
- mesh_new = makeMapBlockMesh(q->data, m_tsrc);
+ mesh_new = makeMapBlockMesh(q->data, m_gamedef);
MeshUpdateResult r;
r.p = q->p;
@@ -186,11 +188,14 @@ Client::Client(
const char *playername,
std::string password,
MapDrawControl &control,
- ITextureSource *tsrc,
- IToolDefManager *toolmgr):
+ IWritableTextureSource *tsrc,
+ IWritableToolDefManager *tooldef,
+ IWritableNodeDefManager *nodedef
+):
m_tsrc(tsrc),
- m_toolmgr(toolmgr),
- m_mesh_update_thread(tsrc),
+ m_tooldef(tooldef),
+ m_nodedef(nodedef),
+ m_mesh_update_thread(this),
m_env(
new ClientMap(this, this, control,
device->getSceneManager()->getRootSceneNode(),
@@ -214,18 +219,22 @@ Client::Client(
m_playerpos_send_timer = 0.0;
m_ignore_damage_timer = 0.0;
- //m_env_mutex.Init();
- //m_con_mutex.Init();
+ // Build main texture atlas, now that the GameDef exists (that is, us)
+ if(g_settings->getBool("enable_texture_atlas"))
+ tsrc->buildMainAtlas(this);
+ else
+ infostream<<"Not building texture atlas."<<std::endl;
+ // NOTE: This should be done only after getting possible dynamic
+ // game definitions from the server, or at least shut down and
+ // restarted when doing so
m_mesh_update_thread.Start();
/*
Add local player
*/
{
- //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
- Player *player = new LocalPlayer();
+ Player *player = new LocalPlayer(this);
player->updateName(playername);
@@ -827,7 +836,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
//TimeTaker t1("TOCLIENT_ADDNODE");
MapNode n;
- n.deSerialize(&data[8], ser_version);
+ n.deSerialize(&data[8], ser_version, m_nodedef);
addNode(p, n);
}
@@ -868,7 +877,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
Update an existing block
*/
//infostream<<"Updating"<<std::endl;
- block->deSerialize(istr, ser_version, this);
+ block->deSerialize(istr, ser_version);
}
else
{
@@ -876,8 +885,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
Create a new block
*/
//infostream<<"Creating new"<<std::endl;
- block = new MapBlock(&m_env.getMap(), p);
- block->deSerialize(istr, ser_version, this);
+ block = new MapBlock(&m_env.getMap(), p, this);
+ block->deSerialize(istr, ser_version);
sector->insertBlock(block);
//DEBUG
@@ -1041,7 +1050,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
// Create a player if it doesn't exist
if(player == NULL)
{
- player = new RemotePlayer(
+ player = new RemotePlayer(this,
m_device->getSceneManager()->getRootSceneNode(),
m_device,
-1);
@@ -2047,7 +2056,7 @@ void Client::setTempMod(v3s16 p, NodeMod mod)
i = affected_blocks.getIterator();
i.atEnd() == false; i++)
{
- i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio(), m_tsrc);
+ i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
}
}
@@ -2064,7 +2073,7 @@ void Client::clearTempMod(v3s16 p)
i = affected_blocks.getIterator();
i.atEnd() == false; i++)
{
- i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio(), m_tsrc);
+ i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
}
}
@@ -2173,3 +2182,18 @@ float Client::getRTT(void)
}
}
+// IGameDef interface
+// Under envlock
+IToolDefManager* Client::getToolDefManager()
+{
+ return m_tooldef;
+}
+INodeDefManager* Client::getNodeDefManager()
+{
+ return m_nodedef;
+}
+ITextureSource* Client::getTextureSource()
+{
+ return m_tsrc;
+}
+
diff --git a/src/client.h b/src/client.h
index d41603c9d..abbbed2f8 100644
--- a/src/client.h
+++ b/src/client.h
@@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h"
struct MeshMakeData;
+class IGameDef;
+class IWritableToolDefManager;
+class IWritableNodeDefManager;
class ClientNotReadyException : public BaseException
{
@@ -99,8 +102,8 @@ class MeshUpdateThread : public SimpleThread
{
public:
- MeshUpdateThread(ITextureSource *tsrc):
- m_tsrc(tsrc)
+ MeshUpdateThread(IGameDef *gamedef):
+ m_gamedef(gamedef)
{
}
@@ -110,7 +113,7 @@ public:
MutexedQueue<MeshUpdateResult> m_queue_out;
- ITextureSource *m_tsrc;
+ IGameDef *m_gamedef;
};
enum ClientEventType
@@ -155,8 +158,9 @@ public:
const char *playername,
std::string password,
MapDrawControl &control,
- ITextureSource *tsrc,
- IToolDefManager *toolmgr
+ IWritableTextureSource *tsrc,
+ IWritableToolDefManager *tooldef,
+ IWritableNodeDefManager *nodedef
);
~Client();
@@ -311,10 +315,9 @@ public:
// IGameDef interface
// Under envlock
- virtual IToolDefManager* getToolDefManager()
- { return m_toolmgr; }
- virtual INodeDefManager* getNodeDefManager()
- { assert(0); return NULL; } // TODO
+ virtual IToolDefManager* getToolDefManager();
+ virtual INodeDefManager* getNodeDefManager();
+ virtual ITextureSource* getTextureSource();
private:
@@ -338,8 +341,9 @@ private:
float m_ignore_damage_timer; // Used after server moves player
IntervalLimiter m_map_timer_and_unload_interval;
- ITextureSource *m_tsrc;
- IToolDefManager *m_toolmgr;
+ IWritableTextureSource *m_tsrc;
+ IWritableToolDefManager *m_tooldef;
+ IWritableNodeDefManager *m_nodedef;
MeshUpdateThread m_mesh_update_thread;
ClientEnvironment m_env;
con::Connection m_con;
diff --git a/src/collision.cpp b/src/collision.cpp
index 2380b1627..674cf4ed4 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -20,10 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "collision.h"
#include "mapblock.h"
#include "map.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
-collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f)
{
collisionMoveResult result;
@@ -80,7 +81,7 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
try{
// Object collides into walkable nodes
MapNode n = map->getNode(v3s16(x,y,z));
- if(content_features(n).walkable == false)
+ if(gamedef->getNodeDefManager()->get(n).walkable == false)
continue;
}
catch(InvalidPositionException &e)
@@ -184,8 +185,8 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
return result;
}
-collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f)
{
collisionMoveResult final_result;
@@ -226,8 +227,8 @@ collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
dtime_downcount = 0;
}
- collisionMoveResult result = collisionMoveSimple(map, pos_max_d,
- box_0, dtime_part, pos_f, speed_f);
+ collisionMoveResult result = collisionMoveSimple(map, gamedef,
+ pos_max_d, box_0, dtime_part, pos_f, speed_f);
if(result.touching_ground)
final_result.touching_ground = true;
diff --git a/src/collision.h b/src/collision.h
index 6d167bb7b..3354ea09a 100644
--- a/src/collision.h
+++ b/src/collision.h
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h"
class Map;
+class IGameDef;
struct collisionMoveResult
{
@@ -34,13 +35,13 @@ struct collisionMoveResult
};
// Moves using a single iteration; speed should not exceed pos_max_d/dtime
-collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f);
// Moves using as many iterations as needed
-collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
- const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
+ f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f);
enum CollisionType
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index ebb402475..ff6215a54 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -23,7 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor()
#include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
#ifndef SERVER
// Create a cuboid.
@@ -122,8 +123,11 @@ void makeCuboid(video::SMaterial &material, MeshCollector *collector,
#ifndef SERVER
void mapblock_mesh_generate_special(MeshMakeData *data,
- MeshCollector &collector, ITextureSource *tsrc)
+ MeshCollector &collector, IGameDef *gamedef)
{
+ ITextureSource *tsrc = gamedef->tsrc();
+ INodeDefManager *nodedef = gamedef->ndef();
+
// 0ms
//TimeTaker timer("mapblock_mesh_generate_special()");
@@ -316,7 +320,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0, ap.atlas);
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16;
@@ -360,34 +364,34 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add flowing liquid to mesh
*/
- else if(content_features(n).liquid_type == LIQUID_FLOWING)
+ else if(nodedef->get(n).liquid_type == LIQUID_FLOWING)
{
- assert(content_features(n).special_material);
+ assert(nodedef->get(n).special_material);
video::SMaterial &liquid_material =
- *content_features(n).special_material;
+ *nodedef->get(n).special_material;
video::SMaterial &liquid_material_bfculled =
- *content_features(n).special_material2;
+ *nodedef->get(n).special_material2;
- assert(content_features(n).special_atlas);
+ assert(nodedef->get(n).special_atlas);
AtlasPointer &pa_liquid1 =
- *content_features(n).special_atlas;
+ *nodedef->get(n).special_atlas;
bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
- content_t c_flowing = content_features(n).liquid_alternative_flowing;
- content_t c_source = content_features(n).liquid_alternative_source;
+ content_t c_flowing = nodedef->get(n).liquid_alternative_flowing;
+ content_t c_source = nodedef->get(n).liquid_alternative_source;
if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
top_is_same_liquid = true;
u8 l = 0;
// Use the light of the node on top if possible
- if(content_features(ntop).param_type == CPT_LIGHT)
- l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
+ if(nodedef->get(ntop).param_type == CPT_LIGHT)
+ l = decode_light(ntop.getLightBlend(data->m_daynight_ratio, nodedef));
// Otherwise use the light of this node (the liquid)
else
- l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(
- content_features(n).vertex_alpha, l);
+ nodedef->get(n).vertex_alpha, l);
// Neighbor liquid levels (key = relative position)
// Includes current node
@@ -520,7 +524,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
continue;
content_t neighbor_content = neighbor_contents[dir];
- ContentFeatures &n_feat = content_features(neighbor_content);
+ const ContentFeatures &n_feat = nodedef->get(neighbor_content);
// Don't draw face if neighbor is blocking the view
if(n_feat.solidness == 2)
@@ -654,15 +658,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add water sources to mesh if using new style
*/
- else if(content_features(n).liquid_type == LIQUID_SOURCE
+ else if(nodedef->get(n).liquid_type == LIQUID_SOURCE
&& new_style_water)
{
- assert(content_features(n).special_material);
+ assert(nodedef->get(n).special_material);
video::SMaterial &liquid_material =
- *content_features(n).special_material;
- assert(content_features(n).special_atlas);
+ *nodedef->get(n).special_material;
+ assert(nodedef->get(n).special_atlas);
AtlasPointer &pa_liquid1 =
- *content_features(n).special_atlas;
+ *nodedef->get(n).special_atlas;
bool top_is_air = false;
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
@@ -672,9 +676,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
if(top_is_air == false)
continue;
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(
- content_features(n).vertex_alpha, l);
+ nodedef->get(n).vertex_alpha, l);
video::S3DVertex vertices[4] =
{
@@ -703,8 +707,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/
else if(n.getContent() == CONTENT_LEAVES && new_style_leaves)
{
- /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));*/
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));*/
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++)
@@ -767,7 +771,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/
else if(n.getContent() == CONTENT_GLASS)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++)
@@ -830,7 +834,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/
else if(n.getContent() == CONTENT_FENCE)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
const f32 post_rad=(f32)BS/10;
@@ -907,7 +911,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/*
Add stones with minerals if stone is invisible
*/
- else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral() != MINERAL_NONE)
+ else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral(nodedef) != MINERAL_NONE)
{
for(u32 j=0; j<6; j++)
{
@@ -915,15 +919,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 dir = g_6dirs[j];
/*u8 l = 0;
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir);
- if(content_features(n2).param_type == CPT_LIGHT)
- l = decode_light(n2.getLightBlend(data->m_daynight_ratio));
+ if(nodedef->get(n2).param_type == CPT_LIGHT)
+ l = decode_light(n2.getLightBlend(data->m_daynight_ratio, nodedef));
else
l = 255;*/
u8 l = 255;
video::SColor c = MapBlock_LightColor(255, l);
// Get the right texture
- TileSpec ts = n.getTile(dir, tsrc);
+ TileSpec ts = n.getTile(dir, tsrc, nodedef);
AtlasPointer ap = ts.texture;
material_general.setTexture(0, ap.atlas);
@@ -974,7 +978,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
#endif
else if(n.getContent() == CONTENT_PAPYRUS)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
@@ -1024,7 +1028,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
else if(n.getContent() == CONTENT_JUNGLEGRASS)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
@@ -1121,7 +1125,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_rail.setTexture(0, ap.atlas);
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16;
@@ -1193,7 +1197,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
material_ladder.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_ladder.setTexture(0, ap.atlas);
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
video::SColor c(255,l,l,l);
float d = (float)BS/16;
@@ -1237,7 +1241,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
else if(n.getContent() == CONTENT_APPLE)
{
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
@@ -1286,7 +1290,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
}
}
else if(n.getContent() == CONTENT_SAPLING) {
- u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++)
diff --git a/src/content_mapblock.h b/src/content_mapblock.h
index 6eb63af4f..eaf74b142 100644
--- a/src/content_mapblock.h
+++ b/src/content_mapblock.h
@@ -23,9 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef SERVER
#include "mapblock_mesh.h"
#include "utility.h"
-class ITextureSource;
+class IGameDef;
void mapblock_mesh_generate_special(MeshMakeData *data,
- MeshCollector &collector, ITextureSource *tsrc);
+ MeshCollector &collector, IGameDef *gamedef);
#endif
#endif
diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp
index eff80f8af..507d34065 100644
--- a/src/content_mapnode.cpp
+++ b/src/content_mapnode.cpp
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h"
#include "content_nodemeta.h"
#include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#define WATER_ALPHA 160
@@ -156,7 +156,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
}
// See header for description
-void content_mapnode_init(ITextureSource *tsrc)
+void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr)
{
if(tsrc == NULL)
dstream<<"INFO: Initial run of content_mapnode_init with "
@@ -177,7 +177,7 @@ void content_mapnode_init(ITextureSource *tsrc)
ContentFeatures *f = NULL;
i = CONTENT_STONE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "stone.png");
f->setInventoryTextureCube("stone.png", "stone.png", "stone.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -189,7 +189,7 @@ void content_mapnode_init(ITextureSource *tsrc)
f->solidness = 0; // For debugging, hides regular stone
i = CONTENT_GRASS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png^grass_side.png");
f->setTexture(tsrc, 0, "grass.png");
f->setTexture(tsrc, 1, "mud.png");
@@ -199,7 +199,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_GRASS_FOOTSTEPS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png^grass_side.png");
f->setTexture(tsrc, 0, "grass_footsteps.png");
f->setTexture(tsrc, 1, "mud.png");
@@ -209,7 +209,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_MUD;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png");
f->setInventoryTextureCube("mud.png", "mud.png", "mud.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -218,7 +218,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_SAND;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "sand.png");
f->setInventoryTextureCube("sand.png", "sand.png", "sand.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -227,7 +227,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_GRAVEL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "gravel.png");
f->setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -236,7 +236,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setGravelLikeMaterialProperties(f->material, 1.0);
i = CONTENT_SANDSTONE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "sandstone.png");
f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -245,7 +245,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_CLAY;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "clay.png");
f->setInventoryTextureCube("clay.png", "clay.png", "clay.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -254,7 +254,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_BRICK;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "brick.png");
f->setInventoryTextureCube("brick.png", "brick.png", "brick.png", tsrc);
f->param_type = CPT_MINERAL;
@@ -263,7 +263,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 1.0);
i = CONTENT_TREE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "tree.png");
f->setTexture(tsrc, 0, "tree_top.png");
f->setTexture(tsrc, 1, "tree_top.png");
@@ -273,7 +273,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_JUNGLETREE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "jungletree.png");
f->setTexture(tsrc, 0, "jungletree_top.png");
f->setTexture(tsrc, 1, "jungletree_top.png");
@@ -283,9 +283,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_JUNGLEGRASS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("junglegrass.png", tsrc);
- f->used_texturenames["junglegrass.png"] = true;
+ f->used_texturenames.insert("junglegrass.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
//f->is_ground_content = true;
@@ -296,7 +296,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setLeavesLikeMaterialProperties(f->material, 1.0);
i = CONTENT_LEAVES;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->light_propagates = true;
//f->param_type = CPT_MINERAL;
f->param_type = CPT_LIGHT;
@@ -318,7 +318,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setLeavesLikeMaterialProperties(f->material, 1.0);
i = CONTENT_CACTUS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cactus_side.png");
f->setTexture(tsrc, 0, "cactus_top.png");
f->setTexture(tsrc, 1, "cactus_top.png");
@@ -329,9 +329,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_PAPYRUS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("papyrus.png", tsrc);
- f->used_texturenames["papyrus.png"] = true;
+ f->used_texturenames.insert("papyrus.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
@@ -341,7 +341,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setLeavesLikeMaterialProperties(f->material, 0.5);
i = CONTENT_BOOKSHELF;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "bookshelf.png");
f->setTexture(tsrc, 0, "wood.png");
f->setTexture(tsrc, 1, "wood.png");
@@ -353,7 +353,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_GLASS;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->light_propagates = true;
f->sunlight_propagates = true;
f->param_type = CPT_LIGHT;
@@ -366,7 +366,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setGlassLikeMaterialProperties(f->material, 1.0);
i = CONTENT_FENCE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
@@ -374,13 +374,13 @@ void content_mapnode_init(ITextureSource *tsrc)
f->solidness = 0; // drawn separately, makes no faces
f->air_equivalent = true; // grass grows underneath
f->setInventoryTexture("fence.png", tsrc);
- f->used_texturenames["fence.png"] = true;
+ f->used_texturenames.insert("fence.png"); // Add to atlas
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_RAIL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("rail.png", tsrc);
- f->used_texturenames["rail.png"] = true;
+ f->used_texturenames.insert("rail.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
@@ -392,9 +392,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 0.75);
i = CONTENT_LADDER;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("ladder.png", tsrc);
- f->used_texturenames["ladder.png"] = true;
+ f->used_texturenames.insert("ladder.png"); // Add to atlas
f->light_propagates = true;
f->param_type = CPT_LIGHT;
f->is_ground_content = true;
@@ -409,13 +409,13 @@ void content_mapnode_init(ITextureSource *tsrc)
// Deprecated
i = CONTENT_COALSTONE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "stone.png^mineral_coal.png");
f->is_ground_content = true;
setStoneLikeMaterialProperties(f->material, 1.5);
i = CONTENT_WOOD;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "wood.png");
f->setInventoryTextureCube("wood.png", "wood.png", "wood.png", tsrc);
f->is_ground_content = true;
@@ -423,7 +423,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_MESE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mese.png");
f->setInventoryTextureCube("mese.png", "mese.png", "mese.png", tsrc);
f->is_ground_content = true;
@@ -431,14 +431,14 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 0.5);
i = CONTENT_CLOUD;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cloud.png");
f->setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png", tsrc);
f->is_ground_content = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
i = CONTENT_AIR;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
@@ -450,7 +450,7 @@ void content_mapnode_init(ITextureSource *tsrc)
f->air_equivalent = true;
i = CONTENT_WATER;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
f->param_type = CPT_LIGHT;
f->light_propagates = true;
@@ -492,7 +492,7 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif
i = CONTENT_WATERSOURCE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
//f->setInventoryTexture("water.png", tsrc);
f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
if(new_style_water)
@@ -547,9 +547,9 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif
i = CONTENT_LAVA;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc);
- f->used_texturenames["lava.png"] = true;
+ f->used_texturenames.insert("lava.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = false;
f->light_source = LIGHT_MAX-1;
@@ -591,9 +591,9 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif
i = CONTENT_LAVASOURCE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc);
- f->used_texturenames["ladder.png"] = true;
+ f->used_texturenames.insert("ladder.png"); // Add to atlas
if(new_style_water)
{
f->solidness = 0; // drawn separately, makes no faces
@@ -646,12 +646,11 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif
i = CONTENT_TORCH;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("torch_on_floor.png", tsrc);
- f->used_texturenames["torch_on_floor.png"] = true;
- f->used_texturenames["torch_on_ceiling.png"] = true;
- f->used_texturenames["torch_on_floor.png"] = true;
- f->used_texturenames["torch.png"] = true;
+ f->used_texturenames.insert("torch_on_floor.png"); // Add to atlas
+ f->used_texturenames.insert("torch_on_ceiling.png"); // Add to atlas
+ f->used_texturenames.insert("torch.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
@@ -671,9 +670,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setConstantMaterialProperties(f->material, 0.0);
i = CONTENT_SIGN_WALL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("sign_wall.png", tsrc);
- f->used_texturenames["sign_wall.png"] = true;
+ f->used_texturenames.insert("sign_wall.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
@@ -688,7 +687,7 @@ void content_mapnode_init(ITextureSource *tsrc)
f->selection_box.type = NODEBOX_WALLMOUNTED;
i = CONTENT_CHEST;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "chest_side.png");
f->setTexture(tsrc, 0, "chest_top.png");
@@ -702,7 +701,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_LOCKABLE_CHEST;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "chest_side.png");
f->setTexture(tsrc, 0, "chest_top.png");
@@ -716,7 +715,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_FURNACE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "furnace_side.png");
f->setTexture(tsrc, 5, "furnace_front.png"); // Z-
@@ -728,7 +727,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_COBBLE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cobble.png");
f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png", tsrc);
f->param_type = CPT_NONE;
@@ -737,7 +736,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 0.9);
i = CONTENT_MOSSYCOBBLE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mossycobble.png");
f->setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png", tsrc);
f->param_type = CPT_NONE;
@@ -746,7 +745,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 0.8);
i = CONTENT_STEEL;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "steel_block.png");
f->setInventoryTextureCube("steel_block.png", "steel_block.png",
"steel_block.png", tsrc);
@@ -756,7 +755,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 5.0);
i = CONTENT_NC;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "nc_side.png");
f->setTexture(tsrc, 5, "nc_front.png"); // Z-
@@ -766,18 +765,18 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_NC_RB;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "nc_rb.png");
f->setInventoryTexture("nc_rb.png", tsrc);
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_SAPLING;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->param_type = CPT_LIGHT;
f->setAllTextures(tsrc, "sapling.png");
f->setInventoryTexture("sapling.png", tsrc);
- f->used_texturenames["sapling.png"] = true;
+ f->used_texturenames.insert("sapling.png"); // Add to atlas
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->light_propagates = true;
f->air_equivalent = false;
@@ -786,9 +785,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setConstantMaterialProperties(f->material, 0.0);
i = CONTENT_APPLE;
- f = &content_features(i);
+ f = nodemgr->getModifiable(i);
f->setInventoryTexture("apple.png", tsrc);
- f->used_texturenames["apple.png"] = true;
+ f->used_texturenames.insert("apple.png"); // Add to atlas
f->param_type = CPT_LIGHT;
f->light_propagates = true;
f->sunlight_propagates = true;
diff --git a/src/content_mapnode.h b/src/content_mapnode.h
index 3946c1e4d..ace30be7b 100644
--- a/src/content_mapnode.h
+++ b/src/content_mapnode.h
@@ -22,9 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h"
class ITextureSource;
+class IWritableNodeDefManager;
/*
- Fills stuff to the global ContentFeatures lookup table.
+ Initialize default node definitions
This accesses tsrc; if it is non-NULL, textures are set
for the nodes.
@@ -35,7 +36,7 @@ class ITextureSource;
Server only calls this once with tsrc=NULL.
*/
-void content_mapnode_init(ITextureSource *tsrc);
+void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr);
// Backwards compatibility for non-extended content types in v19
extern content_t trans_table_19[21][2];
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 9c48e0707..a7cee83ab 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -159,8 +159,9 @@ void ItemSAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
if(send_recommended == false)
return;
@@ -402,8 +403,9 @@ void RatSAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground;
setBasePosition(pos_f);
@@ -639,8 +641,9 @@ void Oerkki1SAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground;
// Do collision damage
@@ -887,8 +890,9 @@ void FireflySAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f;
- moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
- box, dtime, pos_f, m_speed_f);
+ IGameDef *gamedef = m_env->getGameDef();
+ moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+ pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground;
setBasePosition(pos_f);
diff --git a/src/content_tool.cpp b/src/content_tool.cpp
index c7c5504f5..d46401e54 100644
--- a/src/content_tool.cpp
+++ b/src/content_tool.cpp
@@ -18,9 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "content_tool.h"
-#include "tool.h"
+#include "tooldef.h"
-void content_tool_init(IToolDefManager *mgr)
+void content_tool_init(IWritableToolDefManager *mgr)
{
mgr->registerTool("WPick",
ToolDefinition("tool_woodpick.png",
@@ -62,7 +62,7 @@ void content_tool_init(IToolDefManager *mgr)
ToolDefinition("tool_steelsword.png",
ToolDiggingProperties(2.0, 3,0,1,-1, 300, 0,0,0,0)));
mgr->registerTool("",
- ToolDefinition("tool_hand.png",
+ ToolDefinition("tooldef.hand.png",
ToolDiggingProperties(0.5, 1,0,-1,0, 50, 0,0,0,0)));
}
diff --git a/src/content_tool.h b/src/content_tool.h
index 66529d3ed..c7f14be31 100644
--- a/src/content_tool.h
+++ b/src/content_tool.h
@@ -17,8 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-class IToolDefManager;
+class IWritableToolDefManager;
// Add default tools to manager
-void content_tool_init(IToolDefManager *mgr);
+void content_tool_init(IWritableToolDefManager *mgr);
diff --git a/src/environment.cpp b/src/environment.cpp
index a7439e7bc..e03007341 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -30,9 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"
#include "profiler.h"
#include "scriptapi.h"
-#include "mapnode_contentfeatures.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<<")"
@@ -324,7 +325,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
- testplayer.deSerialize(is, m_gamedef);
+ testplayer.deSerialize(is);
}
//infostream<<"Loaded test player with name "<<testplayer.getName()<<std::endl;
@@ -438,7 +439,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
- testplayer.deSerialize(is, m_gamedef);
+ testplayer.deSerialize(is);
}
if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS))
@@ -472,7 +473,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
infostream<<"Failed to read "<<path<<std::endl;
continue;
}
- player->deSerialize(is, m_gamedef);
+ player->deSerialize(is);
}
if(newplayer)
@@ -557,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;
@@ -567,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)
{
@@ -641,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);
@@ -1012,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);
@@ -1028,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);
@@ -1066,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)
@@ -2069,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)
{
@@ -2109,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);
@@ -2164,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);
@@ -2172,9 +2175,9 @@ void ClientEnvironment::step(float dtime)
}
}
-void ClientEnvironment::updateMeshes(v3s16 blockpos, ITextureSource *tsrc)
+void ClientEnvironment::updateMeshes(v3s16 blockpos)
{
- m_map->updateMeshes(blockpos, getDayNightRatio(), tsrc);
+ m_map->updateMeshes(blockpos, getDayNightRatio());
}
void ClientEnvironment::expireMeshes(bool only_daynight_diffed)
diff --git a/src/environment.h b/src/environment.h
index 754b63979..a8213ea6d 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -377,7 +377,7 @@ public:
LocalPlayer * getLocalPlayer();
// Slightly deprecated
- void updateMeshes(v3s16 blockpos, ITextureSource *tsrc);
+ void updateMeshes(v3s16 blockpos);
void expireMeshes(bool only_daynight_diffed);
void setTimeOfDay(u32 time)
diff --git a/src/game.cpp b/src/game.cpp
index 43d09b316..a0bc5ac15 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -44,12 +44,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"
#include "filesys.h"
// Needed for determining pointing to nodes
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "nodemetadata.h"
#include "main.h" // For g_settings
#include "content_mapnode.h" // For content_mapnode_init
-#include "tool.h"
-#include "content_tool.h" // For content_tool_init
+#include "tooldef.h"
+#include "content_tool.h" // Default tools
+#include "content_mapnode.h" // Default nodes
/*
Setting this to 1 enables a special camera mode that forces
@@ -321,7 +322,7 @@ void getPointedNode(Client *client, v3f player_position,
try
{
n = client->getNode(v3s16(x,y,z));
- if(content_pointable(n.getContent()) == false)
+ if(client->getNodeDefManager()->get(n).pointable == false)
continue;
}
catch(InvalidPositionException &e)
@@ -343,7 +344,7 @@ void getPointedNode(Client *client, v3f player_position,
v3s16(-1,0,0), // left
};
- ContentFeatures &f = content_features(n);
+ const ContentFeatures &f = client->getNodeDefManager()->get(n);
if(f.selection_box.type == NODEBOX_FIXED)
{
@@ -592,20 +593,17 @@ void the_game(
draw_load_screen(L"Loading...", driver, font);
- // Create tool manager
- IToolDefManager *toolmgr = createToolDefManager();
-
+ // Create tool definition manager
+ IWritableToolDefManager *tooldef = createToolDefManager();
// Create texture source
- TextureSource *tsrc = new TextureSource(device);
-
- // Initialize mapnode again to enable changed graphics settings
- // Initialize content feature table with textures
- init_contentfeatures(tsrc);
- // Fill content feature table with default definitions
- content_mapnode_init(tsrc);
+ IWritableTextureSource *tsrc = createTextureSource(device);
+ // Create node definition manager
+ IWritableNodeDefManager *nodedef = createNodeDefManager(tsrc);
- // Initialize default tool definitions
- content_tool_init(toolmgr);
+ // Fill node feature table with default definitions
+ content_mapnode_init(tsrc, nodedef);
+ // Set default tool definitions
+ content_tool_init(tooldef);
/*
Create server.
@@ -625,9 +623,14 @@ void the_game(
draw_load_screen(L"Creating client...", driver, font);
infostream<<"Creating client"<<std::endl;
+
MapDrawControl draw_control;
+
Client client(device, playername.c_str(), password, draw_control,
- tsrc, toolmgr);
+ tsrc, tooldef, nodedef);
+
+ // Client acts as our GameDef
+ IGameDef *gamedef = &client;
draw_load_screen(L"Resolving address...", driver, font);
Address connect_address(0,0,0,0, port);
@@ -1694,9 +1697,9 @@ void the_game(
// Get digging properties for material and tool
content_t material = n.getContent();
ToolDiggingProperties tp =
- toolmgr->getDiggingProperties(toolname);
+ tooldef->getDiggingProperties(toolname);
DiggingProperties prop =
- getDiggingProperties(material, &tp);
+ getDiggingProperties(material, &tp, nodedef);
float dig_time_complete = 0.0;
@@ -2102,7 +2105,7 @@ void the_game(
InventoryItem *item = NULL;
if(mlist != NULL)
item = mlist->getItem(g_selected_item);
- camera.wield(item, tsrc);
+ camera.wield(item, gamedef);
}
/*
@@ -2294,7 +2297,7 @@ void the_game(
gui_shuttingdowntext->remove();*/
}
- delete toolmgr;
+ delete tooldef;
delete tsrc;
}
diff --git a/src/gamedef.h b/src/gamedef.h
index 86fd1e80f..79f5d188e 100644
--- a/src/gamedef.h
+++ b/src/gamedef.h
@@ -21,9 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define GAMEDEF_HEADER
class IToolDefManager;
-class INodeDefManager; //TODO
+class INodeDefManager;
//class IItemDefManager; //TODO
// Mineral too?
+class ITextureSource;
/*
An interface for fetching game-global definitions like tool and
@@ -33,9 +34,20 @@ class INodeDefManager; //TODO
class IGameDef
{
public:
+ // These are thread-safe IF they are not edited while running threads.
+ // Thus, first they are set up and then they are only read.
virtual IToolDefManager* getToolDefManager()=0;
virtual INodeDefManager* getNodeDefManager()=0;
//virtual IItemDefManager* getItemDefManager()=0;
+
+ // This is always thread-safe, but referencing the irrlicht texture
+ // pointers in other threads than main thread will make things explode.
+ virtual ITextureSource* getTextureSource()=0;
+
+ // Shorthands
+ IToolDefManager* tdef(){return getToolDefManager();}
+ INodeDefManager* ndef(){return getNodeDefManager();}
+ ITextureSource* tsrc(){return getTextureSource();}
};
#endif
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 4ac2453de..8ddbd3ac8 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -29,8 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_sao.h"
#include "player.h"
#include "log.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
#include "gamedef.h"
/*
@@ -152,7 +152,7 @@ ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f
#ifndef SERVER
video::ITexture * MaterialItem::getImage(ITextureSource *tsrc) const
{
- return content_features(m_content).inventory_texture;
+ return m_gamedef->getNodeDefManager()->get(m_content).inventory_texture;
}
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 63dc94955..c94e903a5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -434,7 +434,7 @@ Doing currently:
#include "settings.h"
#include "profiler.h"
#include "log.h"
-#include "mapnode_contentfeatures.h" // For init_contentfeatures
+#include "nodedef.h" // For init_contentfeatures
#include "content_mapnode.h" // For content_mapnode_init
/*
@@ -1272,10 +1272,6 @@ int main(int argc, char *argv[])
These are needed for unit tests at least.
*/
- // Initialize content feature table without textures
- init_contentfeatures(NULL);
- // Initialize mapnode content without textures
- content_mapnode_init(NULL);
// Must be called before texturesource is created
// (for texture atlas making)
init_mineral();
diff --git a/src/map.cpp b/src/map.cpp
index 6b2142dba..2dfbbbb33 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -37,7 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "log.h"
#include "profiler.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -234,6 +235,8 @@ void Map::unspreadLight(enum LightBank bank,
core::map<v3s16, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
@@ -330,19 +333,20 @@ void Map::unspreadLight(enum LightBank bank,
If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node)
*/
- if(n2.getLight(bank) < oldlight)
+ if(n2.getLight(bank, nodemgr) < oldlight)
{
/*
And the neighbor is transparent and it has some light
*/
- if(n2.light_propagates() && n2.getLight(bank) != 0)
+ if(nodemgr->get(n2).light_propagates
+ && n2.getLight(bank, nodemgr) != 0)
{
/*
Set light to 0 and add to queue
*/
- u8 current_light = n2.getLight(bank);
- n2.setLight(bank, 0);
+ u8 current_light = n2.getLight(bank, nodemgr);
+ n2.setLight(bank, 0, nodemgr);
block->setNode(relpos, n2);
unlighted_nodes.insert(n2pos, current_light);
@@ -416,6 +420,8 @@ void Map::spreadLight(enum LightBank bank,
core::map<v3s16, bool> & from_nodes,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
const v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
@@ -474,7 +480,7 @@ void Map::spreadLight(enum LightBank bank,
// Get node straight from the block
MapNode n = block->getNode(relpos);
- u8 oldlight = n.getLight(bank);
+ u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors
@@ -512,7 +518,7 @@ void Map::spreadLight(enum LightBank bank,
If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn)
*/
- if(n2.getLight(bank) > undiminish_light(oldlight))
+ if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
{
lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos);
@@ -522,11 +528,11 @@ void Map::spreadLight(enum LightBank bank,
If the neighbor is dimmer than how much light this node
would spread on it, add to list
*/
- if(n2.getLight(bank) < newlight)
+ if(n2.getLight(bank, nodemgr) < newlight)
{
- if(n2.light_propagates())
+ if(nodemgr->get(n2).light_propagates)
{
- n2.setLight(bank, newlight);
+ n2.setLight(bank, newlight, nodemgr);
block->setNode(relpos, n2);
lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos);
@@ -575,6 +581,8 @@ void Map::lightNeighbors(enum LightBank bank,
v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
v3s16 dirs[6] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
@@ -600,8 +608,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
{
continue;
}
- if(n2.getLight(bank) > brightest_light || found_something == false){
- brightest_light = n2.getLight(bank);
+ if(n2.getLight(bank, nodemgr) > brightest_light || found_something == false){
+ brightest_light = n2.getLight(bank, nodemgr);
brightest_pos = n2pos;
found_something = true;
}
@@ -624,6 +632,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
s16 Map::propagateSunlight(v3s16 start,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
s16 y = start.Y;
for(; ; y--)
{
@@ -642,9 +652,9 @@ s16 Map::propagateSunlight(v3s16 start,
v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE;
MapNode n = block->getNode(relpos);
- if(n.sunlight_propagates())
+ if(nodemgr->get(n).sunlight_propagates)
{
- n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+ n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
block->setNode(relpos, n);
modified_blocks.insert(blockpos, block);
@@ -670,6 +680,8 @@ void Map::updateLighting(enum LightBank bank,
core::map<v3s16, MapBlock*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
/*m_dout<<DTIME<<"Map::updateLighting(): "
<<a_blocks.size()<<" blocks."<<std::endl;*/
@@ -713,8 +725,8 @@ void Map::updateLighting(enum LightBank bank,
try{
v3s16 p(x,y,z);
MapNode n = block->getNode(v3s16(x,y,z));
- u8 oldlight = n.getLight(bank);
- n.setLight(bank, 0);
+ u8 oldlight = n.getLight(bank, nodemgr);
+ n.setLight(bank, 0, nodemgr);
block->setNode(v3s16(x,y,z), n);
// Collect borders for unlighting
@@ -865,11 +877,11 @@ void Map::updateLighting(enum LightBank bank,
{
//TimeTaker timer("unSpreadLight");
- vmanip.unspreadLight(bank, unlight_from, light_sources);
+ vmanip.unspreadLight(bank, unlight_from, light_sources, nodemgr);
}
{
//TimeTaker timer("spreadLight");
- vmanip.spreadLight(bank, light_sources);
+ vmanip.spreadLight(bank, light_sources, nodemgr);
}
{
//TimeTaker timer("blitBack");
@@ -905,6 +917,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
/*PrintInfo(m_dout);
m_dout<<DTIME<<"Map::addNodeAndUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
@@ -931,7 +945,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
try{
MapNode topnode = getNode(toppos);
- if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+ if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
node_under_sunlight = false;
}
catch(InvalidPositionException &e)
@@ -942,7 +956,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
/*
If the new node is solid and there is grass below, change it to mud
*/
- if(content_features(n).walkable == true)
+ if(nodemgr->get(n).walkable == true)
{
try{
MapNode bottomnode = getNode(bottompos);
@@ -984,7 +998,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
{
enum LightBank bank = banks[i];
- u8 lightwas = getNode(p).getLight(bank);
+ u8 lightwas = getNode(p).getLight(bank, nodemgr);
// Add the block of the added node to modified_blocks
v3s16 blockpos = getNodeBlockPos(p);
@@ -1001,16 +1015,16 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
// light again into this.
unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks);
- n.setLight(bank, 0);
+ n.setLight(bank, 0, nodemgr);
}
/*
If node lets sunlight through and is under sunlight, it has
sunlight too.
*/
- if(node_under_sunlight && content_features(n).sunlight_propagates)
+ if(node_under_sunlight && nodemgr->get(n).sunlight_propagates)
{
- n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+ n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
}
/*
@@ -1023,7 +1037,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
Add intial metadata
*/
- NodeMetadata *meta_proto = content_features(n).initial_metadata;
+ NodeMetadata *meta_proto = nodemgr->get(n).initial_metadata;
if(meta_proto)
{
NodeMetadata *meta = meta_proto->clone(m_gamedef);
@@ -1038,7 +1052,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
TODO: This could be optimized by mass-unlighting instead
of looping
*/
- if(node_under_sunlight && !content_features(n).sunlight_propagates)
+ if(node_under_sunlight && !nodemgr->get(n).sunlight_propagates)
{
s16 y = p.Y - 1;
for(;; y--){
@@ -1054,12 +1068,12 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
break;
}
- if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+ if(n2.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
{
unLightNeighbors(LIGHTBANK_DAY,
- n2pos, n2.getLight(LIGHTBANK_DAY),
+ n2pos, n2.getLight(LIGHTBANK_DAY, nodemgr),
light_sources, modified_blocks);
- n2.setLight(LIGHTBANK_DAY, 0);
+ n2.setLight(LIGHTBANK_DAY, 0, nodemgr);
setNode(n2pos, n2);
}
else
@@ -1109,7 +1123,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
- if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
+ if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
{
m_transforming_liquid.push_back(p2);
}
@@ -1125,6 +1139,8 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
void Map::removeNodeAndUpdate(v3s16 p,
core::map<v3s16, MapBlock*> &modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
/*PrintInfo(m_dout);
m_dout<<DTIME<<"Map::removeNodeAndUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
@@ -1143,7 +1159,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
try{
MapNode topnode = getNode(toppos);
- if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+ if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
node_under_sunlight = false;
}
catch(InvalidPositionException &e)
@@ -1165,7 +1181,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
Unlight neighbors (in case the node is a light source)
*/
unLightNeighbors(bank, p,
- getNode(p).getLight(bank),
+ getNode(p).getLight(bank, nodemgr),
light_sources, modified_blocks);
}
@@ -1227,7 +1243,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
// TODO: Is this needed? Lighting is cleared up there already.
try{
MapNode n = getNode(p);
- n.setLight(LIGHTBANK_DAY, 0);
+ n.setLight(LIGHTBANK_DAY, 0, nodemgr);
setNode(p, n);
}
catch(InvalidPositionException &e)
@@ -1283,7 +1299,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2);
- if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
+ if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
{
m_transforming_liquid.push_back(p2);
}
@@ -1580,6 +1596,8 @@ struct NodeNeighbor {
void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
DSTACK(__FUNCTION_NAME);
//TimeTaker timer("transformLiquids()");
@@ -1614,11 +1632,11 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
*/
s8 liquid_level = -1;
u8 liquid_kind = CONTENT_IGNORE;
- LiquidType liquid_type = content_features(n0.getContent()).liquid_type;
+ LiquidType liquid_type = nodemgr->get(n0).liquid_type;
switch (liquid_type) {
case LIQUID_SOURCE:
liquid_level = LIQUID_LEVEL_SOURCE;
- liquid_kind = content_features(n0.getContent()).liquid_alternative_flowing;
+ liquid_kind = nodemgr->get(n0).liquid_alternative_flowing;
break;
case LIQUID_FLOWING:
liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
@@ -1658,7 +1676,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
}
v3s16 npos = p0 + dirs[i];
NodeNeighbor nb = {getNodeNoEx(npos), nt, npos};
- switch (content_features(nb.n.getContent()).liquid_type) {
+ switch (nodemgr->get(nb.n.getContent()).liquid_type) {
case LIQUID_NONE:
if (nb.n.getContent() == CONTENT_AIR) {
airs[num_airs++] = nb;
@@ -1678,8 +1696,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
case LIQUID_SOURCE:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if (liquid_kind == CONTENT_AIR)
- liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
- if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
+ liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
+ if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
sources[num_sources++] = nb;
@@ -1688,8 +1706,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
case LIQUID_FLOWING:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if (liquid_kind == CONTENT_AIR)
- liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
- if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
+ liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
+ if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
flows[num_flows++] = nb;
@@ -1710,7 +1728,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
// or the flowing alternative of the first of the surrounding sources (if it's air), so
// it's perfectly safe to use liquid_kind here to determine the new node content.
- new_node_content = content_features(liquid_kind).liquid_alternative_source;
+ new_node_content = nodemgr->get(liquid_kind).liquid_alternative_source;
} else if (num_sources == 1 && sources[0].t != NEIGHBOR_LOWER) {
// liquid_kind is set properly, see above
new_node_content = liquid_kind;
@@ -1739,7 +1757,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
}
}
- u8 viscosity = content_features(liquid_kind).liquid_viscosity;
+ u8 viscosity = nodemgr->get(liquid_kind).liquid_viscosity;
if (viscosity > 1 && max_node_level != liquid_level) {
// amount to gain, limited by viscosity
// must be at least 1 in absolute value
@@ -1765,7 +1783,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
/*
check if anything has changed. if not, just continue with the next node.
*/
- if (new_node_content == n0.getContent() && (content_features(n0.getContent()).liquid_type != LIQUID_FLOWING ||
+ if (new_node_content == n0.getContent() && (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
== flowing_down)))
@@ -1776,7 +1794,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
update the current node
*/
//bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
- if (content_features(new_node_content).liquid_type == LIQUID_FLOWING) {
+ if (nodemgr->get(new_node_content).liquid_type == LIQUID_FLOWING) {
// set level to last 3 bits, flowing down bit to 4th bit
n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
} else {
@@ -1790,14 +1808,14 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
if(block != NULL) {
modified_blocks.insert(blockpos, block);
// If node emits light, MapBlock requires lighting update
- if(content_features(n0).light_source != 0)
+ if(nodemgr->get(n0).light_source != 0)
lighting_modified_blocks[block->getPos()] = block;
}
/*
enqueue neighbors for update if neccessary
*/
- switch (content_features(n0.getContent()).liquid_type) {
+ switch (nodemgr->get(n0.getContent()).liquid_type) {
case LIQUID_SOURCE:
case LIQUID_FLOWING:
// make sure source flows into all neighboring nodes
@@ -2082,6 +2100,7 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
data->no_op = false;
data->seed = m_seed;
data->blockpos = blockpos;
+ data->nodemgr = m_gamedef->ndef();
/*
Create the whole area of this and the neighboring blocks
@@ -2389,7 +2408,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
Generate blank sector
*/
- sector = new ServerMapSector(this, p2d);
+ sector = new ServerMapSector(this, p2d, m_gamedef);
// Sector position on map in nodes
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
@@ -3054,7 +3073,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
<<fullpath<<" doesn't exist but directory does."
<<" Continuing with a sector with no metadata."
<<std::endl;*/
- sector = new ServerMapSector(this, p2d);
+ sector = new ServerMapSector(this, p2d, m_gamedef);
m_sectors.insert(p2d, sector);
}
else
@@ -3065,7 +3084,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
else
{
sector = ServerMapSector::deSerialize
- (is, this, p2d, m_sectors);
+ (is, this, p2d, m_sectors, m_gamedef);
if(save_after_load)
saveSectorMeta(sector);
}
@@ -3310,7 +3329,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
}
// Read basic data
- block->deSerialize(is, version, m_gamedef);
+ block->deSerialize(is, version);
// Read extra data stored on disk
block->deSerializeDiskExtra(is, version);
@@ -3380,7 +3399,7 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
}
// Read basic data
- block->deSerialize(is, version, m_gamedef);
+ block->deSerialize(is, version);
// Read extra data stored on disk
block->deSerializeDiskExtra(is, version);
@@ -3567,7 +3586,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
}
// Create a sector
- ClientMapSector *sector = new ClientMapSector(this, p2d);
+ ClientMapSector *sector = new ClientMapSector(this, p2d, m_gamedef);
{
//JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
@@ -3617,7 +3636,7 @@ void ClientMap::OnRegisterSceneNode()
}
static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
- float start_off, float end_off, u32 needed_count)
+ float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr)
{
float d0 = (float)BS * p0.getDistanceFrom(p1);
v3s16 u0 = p1 - p0;
@@ -3630,7 +3649,7 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
v3s16 p = floatToInt(pf, BS);
MapNode n = map->getNodeNoEx(p);
bool is_transparent = false;
- ContentFeatures &f = content_features(n);
+ const ContentFeatures &f = nodemgr->get(n);
if(f.solidness == 0)
is_transparent = (f.visual_solidness != 2);
else
@@ -3647,6 +3666,8 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
//m_dout<<DTIME<<"Rendering map..."<<std::endl;
DSTACK(__FUNCTION_NAME);
@@ -3855,23 +3876,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
u32 needed_count = 1;
if(
isOccluded(this, spn, cpn + v3s16(0,0,0),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,-bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(bs2,-bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,bs2),
- step, stepfac, startoff, endoff, needed_count) &&
+ step, stepfac, startoff, endoff, needed_count, nodemgr) &&
isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
- step, stepfac, startoff, endoff, needed_count)
+ step, stepfac, startoff, endoff, needed_count, nodemgr)
)
{
blocks_occlusion_culled++;
@@ -4016,6 +4037,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
void ClientMap::renderPostFx()
{
+ 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().
@@ -4027,7 +4050,7 @@ void ClientMap::renderPostFx()
// - If the player is in a solid node, make everything black.
// - If the player is in liquid, draw a semi-transparent overlay.
- ContentFeatures& features = content_features(n);
+ const ContentFeatures& features = nodemgr->get(n);
video::SColor post_effect_color = features.post_effect_color;
if(features.solidness == 2 && g_settings->getBool("free_move") == false)
{
@@ -4170,15 +4193,14 @@ void ClientMap::expireMeshes(bool only_daynight_diffed)
}
}
-void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
- ITextureSource *tsrc)
+void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
{
assert(mapType() == MAPTYPE_CLIENT);
try{
v3s16 p = blockpos + v3s16(0,0,0);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
@@ -4186,21 +4208,21 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
try{
v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(0,-1,0);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(0,0,-1);
MapBlock *b = getBlockNoCreate(p);
- b->updateMesh(daynight_ratio, tsrc);
+ b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
}
catch(InvalidPositionException &e){}
diff --git a/src/map.h b/src/map.h
index 6eb208be9..3def571b8 100644
--- a/src/map.h
+++ b/src/map.h
@@ -590,8 +590,7 @@ public:
Update the faces of the given block and blocks on the
leading edge, without threading. Rarely used.
*/
- void updateMeshes(v3s16 blockpos, u32 daynight_ratio,
- ITextureSource *tsrc);
+ void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
// Update meshes that touch the node
//void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 944d62230..dcafaae73 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -23,17 +23,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h"
#include "light.h"
#include <sstream>
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "nodemetadata.h"
+#include "gamedef.h"
/*
MapBlock
*/
-MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
+MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
m_node_metadata(new NodeMetadataList),
m_parent(parent),
m_pos(pos),
+ m_gamedef(gamedef),
m_modified(MOD_STATE_WRITE_NEEDED),
is_underground(false),
m_lighting_expired(true),
@@ -138,7 +140,7 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p)
#ifndef SERVER
#if 1
-void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc)
+void MapBlock::updateMesh(u32 daynight_ratio)
{
#if 0
/*
@@ -154,7 +156,7 @@ void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc)
MeshMakeData data;
data.fill(daynight_ratio, this);
- scene::SMesh *mesh_new = makeMapBlockMesh(&data, tsrc);
+ scene::SMesh *mesh_new = makeMapBlockMesh(&data, m_gamedef);
/*
Replace the mesh
@@ -229,6 +231,8 @@ void MapBlock::replaceMesh(scene::SMesh *mesh_new)
bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
bool remove_light, bool *black_air_left)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
// Whether the sunlight at the top of the bottom block is valid
bool block_below_is_valid = true;
@@ -249,7 +253,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
// Trust heuristics
no_sunlight = is_underground;
}
- else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+ else if(n.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) != LIGHT_SUN)
{
no_sunlight = true;
}
@@ -268,7 +272,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
{
MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
//if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
- if(content_features(n).sunlight_propagates == false)
+ if(m_gamedef->ndef()->get(n).sunlight_propagates == false)
{
no_sunlight = true;
}
@@ -317,11 +321,11 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
{
// Do nothing
}
- else if(current_light == LIGHT_SUN && n.sunlight_propagates())
+ else if(current_light == LIGHT_SUN && nodemgr->get(n).sunlight_propagates)
{
// Do nothing: Sunlight is continued
}
- else if(n.light_propagates() == false)
+ else if(nodemgr->get(n).light_propagates == false)
{
/*// DEPRECATED TODO: REMOVE
if(grow_grass)
@@ -355,11 +359,11 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
current_light = diminish_light(current_light);
}
- u8 old_light = n.getLight(LIGHTBANK_DAY);
+ u8 old_light = n.getLight(LIGHTBANK_DAY, nodemgr);
if(current_light > old_light || remove_light)
{
- n.setLight(LIGHTBANK_DAY, current_light);
+ n.setLight(LIGHTBANK_DAY, current_light, nodemgr);
}
if(diminish_light(current_light) != 0)
@@ -392,12 +396,12 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
if(block_below_is_valid)
{
MapNode n = getNodeParent(v3s16(x, -1, z));
- if(n.light_propagates())
+ if(nodemgr->get(n).light_propagates)
{
- if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN
+ if(n.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN
&& sunlight_should_go_down == false)
block_below_is_valid = false;
- else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN
+ else if(n.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN
&& sunlight_should_go_down == true)
block_below_is_valid = false;
}
@@ -438,6 +442,8 @@ void MapBlock::copyFrom(VoxelManipulator &dst)
void MapBlock::updateDayNightDiff()
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
if(data == NULL)
{
m_day_night_differs = false;
@@ -452,7 +458,7 @@ void MapBlock::updateDayNightDiff()
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
{
MapNode &n = data[i];
- if(n.getLight(LIGHTBANK_DAY) != n.getLight(LIGHTBANK_NIGHT))
+ if(n.getLight(LIGHTBANK_DAY, nodemgr) != n.getLight(LIGHTBANK_NIGHT, nodemgr))
{
differs = true;
break;
@@ -493,7 +499,7 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
for(; y>=0; y--)
{
MapNode n = getNodeRef(p2d.X, y, p2d.Y);
- if(content_features(n).walkable)
+ if(m_gamedef->ndef()->get(n).walkable)
{
if(y == MAP_BLOCKSIZE-1)
return -2;
@@ -655,8 +661,10 @@ void MapBlock::serialize(std::ostream &os, u8 version)
}
}
-void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
+void MapBlock::deSerialize(std::istream &is, u8 version)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapBlock format not supported");
@@ -690,7 +698,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
if(is.gcount() != len)
throw SerializationError
("MapBlock::deSerialize: no enough input data");
- data[i].deSerialize(*d, version);
+ data[i].deSerialize(*d, version, nodemgr);
}
}
else if(version <= 10)
@@ -772,7 +780,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
buf[0] = s[i];
buf[1] = s[i+nodecount];
buf[2] = s[i+nodecount*2];
- data[i].deSerialize(buf, version);
+ data[i].deSerialize(buf, version, m_gamedef->getNodeDefManager());
}
/*
@@ -786,7 +794,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
{
std::string data = deSerializeString(is);
std::istringstream iss(data, std::ios_base::binary);
- m_node_metadata->deSerialize(iss, gamedef);
+ m_node_metadata->deSerialize(iss, m_gamedef);
}
else
{
@@ -794,7 +802,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
std::ostringstream oss(std::ios_base::binary);
decompressZlib(is, oss);
std::istringstream iss(oss.str(), std::ios_base::binary);
- m_node_metadata->deSerialize(iss, gamedef);
+ m_node_metadata->deSerialize(iss, m_gamedef);
}
}
catch(SerializationError &e)
diff --git a/src/mapblock.h b/src/mapblock.h
index 75e146665..e7fd932b8 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -38,7 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map;
class NodeMetadataList;
-class ITextureSource;
class IGameDef;
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
@@ -120,7 +119,7 @@ public:
class MapBlock /*: public NodeContainer*/
{
public:
- MapBlock(Map *parent, v3s16 pos, bool dummy=false);
+ MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy=false);
~MapBlock();
/*virtual u16 nodeContainerId() const
@@ -393,12 +392,13 @@ public:
getNodeParentNoEx(p + face_dir),
face_dir);
}*/
- u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
+ u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir,
+ INodeDefManager *nodemgr)
{
return getFaceLight(daynight_ratio,
getNodeParentNoEx(p),
getNodeParentNoEx(p + face_dir),
- face_dir);
+ face_dir, nodemgr);
}
#ifndef SERVER // Only on client
@@ -409,7 +409,7 @@ public:
NOTE: Prefer generating the mesh separately and then using
replaceMesh().
*/
- void updateMesh(u32 daynight_ratio, ITextureSource *tsrc);
+ void updateMesh(u32 daynight_ratio);
#endif
// Replace the mesh with a new one
void replaceMesh(scene::SMesh *mesh_new);
@@ -539,7 +539,7 @@ public:
// These don't write or read version by itself
void serialize(std::ostream &os, u8 version);
- void deSerialize(std::istream &is, u8 version, IGameDef *gamedef);
+ void deSerialize(std::istream &is, u8 version);
// Used after the basic ones when writing on disk (serverside)
void serializeDiskExtra(std::ostream &os, u8 version);
void deSerializeDiskExtra(std::istream &is, u8 version);
@@ -589,6 +589,8 @@ private:
Map *m_parent;
// Position in blocks on parent
v3s16 m_pos;
+
+ IGameDef *m_gamedef;
/*
If NULL, block is a dummy block.
diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp
index 2f9f9ce43..5d8c0b737 100644
--- a/src/mapblock_mesh.cpp
+++ b/src/mapblock_mesh.cpp
@@ -22,11 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock.h"
#include "map.h"
#include "main.h" // For g_settings and g_texturesource
-#include "content_mapblock.h"
#include "settings.h"
#include "profiler.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "tile.h"
+#include "gamedef.h"
+#include "content_mapblock.h"
void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
{
@@ -84,7 +85,7 @@ void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
/*
vertex_dirs: v3s16[4]
*/
-void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
+static void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
{
/*
If looked from outside the node towards the face, the corners are:
@@ -170,7 +171,7 @@ struct FastFace
video::S3DVertex vertices[4]; // Precalculated vertices
};
-void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
+static void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
v3s16 dir, v3f scale, v3f posRelative_f,
core::array<FastFace> &dest)
{
@@ -252,11 +253,11 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
Gets node tile from any place relative to block.
Returns TILE_NODE if doesn't exist or should not be drawn.
*/
-TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
- NodeModMap &temp_mods, ITextureSource *tsrc)
+static TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
+ NodeModMap &temp_mods, ITextureSource *tsrc, INodeDefManager *ndef)
{
TileSpec spec;
- spec = mn.getTile(face_dir, tsrc);
+ spec = mn.getTile(face_dir, tsrc, ndef);
/*
Check temporary modifications on this node
@@ -273,7 +274,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
if(mod.type == NODEMOD_CHANGECONTENT)
{
MapNode mn2(mod.param);
- spec = mn2.getTile(face_dir, tsrc);
+ spec = mn2.getTile(face_dir, tsrc, ndef);
}
if(mod.type == NODEMOD_CRACK)
{
@@ -304,7 +305,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
return spec;
}
-content_t getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
+static content_t getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
{
/*
Check temporary modifications on this node
@@ -354,7 +355,8 @@ v3s16 dirs8[8] = {
};
// Calculate lighting at the XYZ- corner of p
-u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
+static u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio,
+ INodeDefManager *ndef)
{
u16 ambient_occlusion = 0;
u16 light = 0;
@@ -362,11 +364,11 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
for(u32 i=0; i<8; i++)
{
MapNode n = vmanip.getNodeNoEx(p - dirs8[i]);
- if(content_features(n).param_type == CPT_LIGHT
+ if(ndef->get(n).param_type == CPT_LIGHT
// Fast-style leaves look better this way
- && content_features(n).solidness != 2)
+ && ndef->get(n).solidness != 2)
{
- light += decode_light(n.getLightBlend(daynight_ratio));
+ light += decode_light(n.getLightBlend(daynight_ratio, ndef));
light_count++;
}
else
@@ -391,8 +393,8 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
}
// Calculate lighting at the given corner of p
-u8 getSmoothLight(v3s16 p, v3s16 corner,
- VoxelManipulator &vmanip, u32 daynight_ratio)
+static u8 getSmoothLight(v3s16 p, v3s16 corner,
+ VoxelManipulator &vmanip, u32 daynight_ratio, INodeDefManager *ndef)
{
if(corner.X == 1) p.X += 1;
else assert(corner.X == -1);
@@ -401,10 +403,10 @@ u8 getSmoothLight(v3s16 p, v3s16 corner,
if(corner.Z == 1) p.Z += 1;
else assert(corner.Z == -1);
- return getSmoothLight(p, vmanip, daynight_ratio);
+ return getSmoothLight(p, vmanip, daynight_ratio, ndef);
}
-void getTileInfo(
+static void getTileInfo(
// Input:
v3s16 blockpos_nodes,
v3s16 p,
@@ -413,7 +415,7 @@ void getTileInfo(
VoxelManipulator &vmanip,
NodeModMap &temp_mods,
bool smooth_lighting,
- ITextureSource *tsrc,
+ IGameDef *gamedef,
// Output:
bool &makes_face,
v3s16 &p_corrected,
@@ -422,16 +424,19 @@ void getTileInfo(
TileSpec &tile
)
{
+ ITextureSource *tsrc = gamedef->tsrc();
+ INodeDefManager *ndef = gamedef->ndef();
+
MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
- TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods, tsrc);
- TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc);
+ TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods, tsrc, ndef);
+ TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc, ndef);
// This is hackish
content_t content0 = getNodeContent(p, n0, temp_mods);
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
bool equivalent = false;
- u8 mf = face_contents(content0, content1, &equivalent);
+ u8 mf = face_contents(content0, content1, &equivalent, ndef);
if(mf == 0)
{
@@ -461,7 +466,7 @@ void getTileInfo(
if(smooth_lighting == false)
{
lights[0] = lights[1] = lights[2] = lights[3] =
- decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir));
+ decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir, ndef));
}
else
{
@@ -470,7 +475,7 @@ void getTileInfo(
for(u16 i=0; i<4; i++)
{
lights[i] = getSmoothLight(blockpos_nodes + p_corrected,
- vertex_dirs[i], vmanip, daynight_ratio);
+ vertex_dirs[i], vmanip, daynight_ratio, ndef);
}
}
@@ -482,7 +487,7 @@ void getTileInfo(
translate_dir: unit vector with only one of x, y or z
face_dir: unit vector with only one of x, y or z
*/
-void updateFastFaceRow(
+static void updateFastFaceRow(
u32 daynight_ratio,
v3f posRelative_f,
v3s16 startpos,
@@ -496,7 +501,7 @@ void updateFastFaceRow(
VoxelManipulator &vmanip,
v3s16 blockpos_nodes,
bool smooth_lighting,
- ITextureSource *tsrc)
+ IGameDef *gamedef)
{
v3s16 p = startpos;
@@ -508,7 +513,7 @@ void updateFastFaceRow(
u8 lights[4] = {0,0,0,0};
TileSpec tile;
getTileInfo(blockpos_nodes, p, face_dir, daynight_ratio,
- vmanip, temp_mods, smooth_lighting, tsrc,
+ vmanip, temp_mods, smooth_lighting, gamedef,
makes_face, p_corrected, face_dir_corrected, lights, tile);
for(u16 j=0; j<length; j++)
@@ -531,7 +536,7 @@ void updateFastFaceRow(
p_next = p + translate_dir;
getTileInfo(blockpos_nodes, p_next, face_dir, daynight_ratio,
- vmanip, temp_mods, smooth_lighting, tsrc,
+ vmanip, temp_mods, smooth_lighting, gamedef,
next_makes_face, next_p_corrected,
next_face_dir_corrected, next_lights,
next_tile);
@@ -644,7 +649,7 @@ void updateFastFaceRow(
}
}
-scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
+scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef)
{
// 4-21ms for MAP_BLOCKSIZE=16
// 24-155ms for MAP_BLOCKSIZE=32
@@ -692,7 +697,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
data->m_vmanip,
blockpos_nodes,
smooth_lighting,
- tsrc);
+ gamedef);
}
}
/*
@@ -711,7 +716,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
data->m_vmanip,
blockpos_nodes,
smooth_lighting,
- tsrc);
+ gamedef);
}
}
/*
@@ -730,7 +735,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
data->m_vmanip,
blockpos_nodes,
smooth_lighting,
- tsrc);
+ gamedef);
}
}
}
@@ -795,7 +800,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
- whatever
*/
- mapblock_mesh_generate_special(data, collector, tsrc);
+ mapblock_mesh_generate_special(data, collector, gamedef);
/*
Add stuff from collector to mesh
diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h
index ea6a73122..36cc9be24 100644
--- a/src/mapblock_mesh.h
+++ b/src/mapblock_mesh.h
@@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock_nodemod.h"
#include "voxel.h"
+class IGameDef;
+
/*
Mesh making stuff
*/
@@ -141,7 +143,7 @@ struct MeshMakeData
};
// This is the highest-level function in here
-scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc);
+scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef);
#endif
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 8fc568f36..2b8050260 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mineral.h"
//#include "serverobject.h"
#include "content_sao.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
namespace mapgen
{
@@ -1417,9 +1417,9 @@ void add_random_objects(MapBlock *block)
MapNode n = block->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE)
continue;
- if(content_features(n).liquid_type != LIQUID_NONE)
+ if(data->nodemgr->get(n)->liquid_type != LIQUID_NONE)
continue;
- if(content_features(n).walkable)
+ if(data->nodemgr->get(n)->walkable)
{
last_node_walkable = true;
continue;
@@ -1478,6 +1478,9 @@ void make_block(BlockMakeData *data)
return;
}
+ assert(data->vmanip);
+ assert(data->nodemgr);
+
v3s16 blockpos = data->blockpos;
/*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
@@ -2185,7 +2188,7 @@ void make_block(BlockMakeData *data)
{
u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i];
- if(content_features(*n).is_ground_content
+ if(data->nodemgr->get(*n).is_ground_content
|| n->getContent() == CONTENT_JUNGLETREE)
{
found = true;
@@ -2284,7 +2287,8 @@ void make_block(BlockMakeData *data)
BlockMakeData::BlockMakeData():
no_op(false),
vmanip(NULL),
- seed(0)
+ seed(0),
+ nodemgr(NULL)
{}
BlockMakeData::~BlockMakeData()
diff --git a/src/mapgen.h b/src/mapgen.h
index f848389a8..5caee2efa 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct BlockMakeData;
class MapBlock;
class ManualMapVoxelManipulator;
+class INodeDefManager;
namespace mapgen
{
@@ -54,10 +55,11 @@ namespace mapgen
struct BlockMakeData
{
bool no_op;
- ManualMapVoxelManipulator *vmanip;
+ ManualMapVoxelManipulator *vmanip; // Destructor deletes
u64 seed;
v3s16 blockpos;
UniqueQueue<v3s16> transforming_liquid;
+ INodeDefManager *nodemgr; // Destructor deletes
BlockMakeData();
~BlockMakeData();
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 829147839..9aceab17e 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string>
#include "mineral.h"
#include "main.h" // For g_settings
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
#include "content_mapnode.h" // For mapnode_translate_*_internal
/*
@@ -33,8 +33,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1: Face uses m1's content
2: Face uses m2's content
equivalent: Whether the blocks share the same face (eg. water and glass)
+
+ TODO: Add 3: Both faces drawn with backface culling, remove equivalent
*/
-u8 face_contents(content_t m1, content_t m2, bool *equivalent)
+u8 face_contents(content_t m1, content_t m2, bool *equivalent,
+ INodeDefManager *nodemgr)
{
*equivalent = false;
@@ -43,13 +46,15 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
bool contents_differ = (m1 != m2);
+ const ContentFeatures &f1 = nodemgr->get(m1);
+ const ContentFeatures &f2 = nodemgr->get(m2);
+
// Contents don't differ for different forms of same liquid
- if(content_liquid(m1) && content_liquid(m2)
- && make_liquid_flowing(m1) == make_liquid_flowing(m2))
+ if(f1.sameLiquid(f2))
contents_differ = false;
- u8 c1 = content_solidness(m1);
- u8 c2 = content_solidness(m2);
+ u8 c1 = f1.solidness;
+ u8 c2 = f2.solidness;
bool solidness_differs = (c1 != c2);
bool makes_face = contents_differ && solidness_differs;
@@ -58,16 +63,16 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
return 0;
if(c1 == 0)
- c1 = content_features(m1).visual_solidness;
+ c1 = f1.visual_solidness;
if(c2 == 0)
- c2 = content_features(m2).visual_solidness;
+ c2 = f2.visual_solidness;
if(c1 == c2){
*equivalent = true;
// If same solidness, liquid takes precense
- if(content_features(m1).liquid_type != LIQUID_NONE)
+ if(f1.isLiquid())
return 1;
- if(content_features(m2).liquid_type != LIQUID_NONE)
+ if(f2.isLiquid())
return 2;
}
@@ -147,28 +152,10 @@ v3s16 unpackDir(u8 b)
MapNode
*/
-// These four are DEPRECATED.
-bool MapNode::light_propagates()
-{
- return light_propagates_content(getContent());
-}
-bool MapNode::sunlight_propagates()
-{
- return sunlight_propagates_content(getContent());
-}
-u8 MapNode::solidness()
-{
- return content_solidness(getContent());
-}
-u8 MapNode::light_source()
-{
- return content_features(*this).light_source;
-}
-
-void MapNode::setLight(enum LightBank bank, u8 a_light)
+void MapNode::setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr)
{
// If node doesn't contain light data, ignore this
- if(content_features(*this).param_type != CPT_LIGHT)
+ if(nodemgr->get(*this).param_type != CPT_LIGHT)
return;
if(bank == LIGHTBANK_DAY)
{
@@ -184,11 +171,11 @@ void MapNode::setLight(enum LightBank bank, u8 a_light)
assert(0);
}
-u8 MapNode::getLight(enum LightBank bank)
+u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
u8 light = 0;
- if(content_features(*this).param_type == CPT_LIGHT)
+ if(nodemgr->get(*this).param_type == CPT_LIGHT)
{
if(bank == LIGHTBANK_DAY)
light = param1 & 0x0f;
@@ -197,32 +184,33 @@ u8 MapNode::getLight(enum LightBank bank)
else
assert(0);
}
- if(light_source() > light)
- light = light_source();
+ if(nodemgr->get(*this).light_source > light)
+ light = nodemgr->get(*this).light_source;
return light;
}
-u8 MapNode::getLightBanksWithSource()
+u8 MapNode::getLightBanksWithSource(INodeDefManager *nodemgr) const
{
// Select the brightest of [light source, propagated light]
u8 lightday = 0;
u8 lightnight = 0;
- if(content_features(*this).param_type == CPT_LIGHT)
+ if(nodemgr->get(*this).param_type == CPT_LIGHT)
{
lightday = param1 & 0x0f;
lightnight = (param1>>4)&0x0f;
}
- if(light_source() > lightday)
- lightday = light_source();
- if(light_source() > lightnight)
- lightnight = light_source();
+ if(nodemgr->get(*this).light_source > lightday)
+ lightday = nodemgr->get(*this).light_source;
+ if(nodemgr->get(*this).light_source > lightnight)
+ lightnight = nodemgr->get(*this).light_source;
return (lightday&0x0f) | ((lightnight<<4)&0xf0);
}
#ifndef SERVER
-TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
+TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc,
+ INodeDefManager *nodemgr) const
{
- if(content_features(*this).param_type == CPT_FACEDIR_SIMPLE)
+ if(nodemgr->get(*this).param_type == CPT_FACEDIR_SIMPLE)
dir = facedir_rotate(param1, dir);
TileSpec spec;
@@ -246,16 +234,16 @@ TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
if(dir_i == -1)
// Non-directional
- spec = content_features(*this).tiles[0];
+ spec = nodemgr->get(*this).tiles[0];
else
- spec = content_features(*this).tiles[dir_i];
+ spec = nodemgr->get(*this).tiles[dir_i];
/*
If it contains some mineral, change texture id
*/
- if(content_features(*this).param_type == CPT_MINERAL && tsrc)
+ if(nodemgr->get(*this).param_type == CPT_MINERAL && tsrc)
{
- u8 mineral = getMineral();
+ u8 mineral = getMineral(nodemgr);
std::string mineral_texture_name = mineral_block_texture(mineral);
if(mineral_texture_name != "")
{
@@ -273,9 +261,9 @@ TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
}
#endif
-u8 MapNode::getMineral()
+u8 MapNode::getMineral(INodeDefManager *nodemgr) const
{
- if(content_features(*this).param_type == CPT_MINERAL)
+ if(nodemgr->get(*this).param_type == CPT_MINERAL)
{
return param1 & 0x0f;
}
@@ -332,7 +320,7 @@ void MapNode::serialize(u8 *dest, u8 version)
dest[2] = n_foreign.param2;
}
}
-void MapNode::deSerialize(u8 *source, u8 version)
+void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
{
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported");
@@ -345,7 +333,7 @@ void MapNode::deSerialize(u8 *source, u8 version)
{
param0 = source[0];
// This version doesn't support saved lighting
- if(light_propagates() || light_source() > 0)
+ if(nodemgr->get(*this).light_propagates || nodemgr->get(*this).light_source > 0)
param1 = 0;
else
param1 = source[1];
@@ -402,12 +390,12 @@ void MapNode::deSerialize(u8 *source, u8 version)
returns encoded light value.
*/
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
- v3s16 face_dir)
+ v3s16 face_dir, INodeDefManager *nodemgr)
{
try{
u8 light;
- u8 l1 = n.getLightBlend(daynight_ratio);
- u8 l2 = n2.getLightBlend(daynight_ratio);
+ u8 l1 = n.getLightBlend(daynight_ratio, nodemgr);
+ u8 l2 = n2.getLightBlend(daynight_ratio, nodemgr);
if(l1 > l2)
light = l1;
else
diff --git a/src/mapnode.h b/src/mapnode.h
index 62815dad1..70a7638d2 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tile.h"
#endif
+class INodeDefManager;
+
/*
Naming scheme:
- Material = irrlicht's Material class
@@ -68,7 +70,8 @@ typedef u16 content_t;
2: Face uses m2's content
equivalent: Whether the blocks share the same face (eg. water and glass)
*/
-u8 face_contents(content_t m1, content_t m2, bool *equivalent);
+u8 face_contents(content_t m1, content_t m2, bool *equivalent,
+ INodeDefManager *nodemgr);
/*
Packs directions like (1,0,0), (1,-1,0) in six bits.
@@ -157,7 +160,7 @@ struct MapNode
}
// To be used everywhere
- content_t getContent()
+ content_t getContent() const
{
if(param0 < 0x80)
return param0;
@@ -180,27 +183,19 @@ struct MapNode
}
}
- /*
- These four are DEPRECATED I guess. -c55
- */
- bool light_propagates();
- bool sunlight_propagates();
- u8 solidness();
- u8 light_source();
-
- void setLight(enum LightBank bank, u8 a_light);
- u8 getLight(enum LightBank bank);
- u8 getLightBanksWithSource();
+ void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
+ u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
+ u8 getLightBanksWithSource(INodeDefManager *nodemgr) const;
// 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN
- u8 getLightBlend(u32 daylight_factor)
+ u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
{
- u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
- + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
+ u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY, nodemgr)
+ + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT, nodemgr))
)/1000;
u8 max = LIGHT_MAX;
- if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+ if(getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
max = LIGHT_SUN;
if(l > max)
l = max;
@@ -208,10 +203,10 @@ struct MapNode
}
/*// 0 <= daylight_factor <= 1000
// 0 <= return value <= 255
- u8 getLightBlend(u32 daylight_factor)
+ u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr)
{
- u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
- u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
+ u8 daylight = decode_light(getLight(LIGHTBANK_DAY, nodemgr));
+ u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT, nodemgr));
u8 mix = ((daylight_factor * daylight
+ (1000-daylight_factor) * nightlight)
)/1000;
@@ -226,14 +221,15 @@ struct MapNode
Returns: TileSpec. Can contain miscellaneous texture coordinates,
which must be obeyed so that the texture atlas can be used.
*/
- TileSpec getTile(v3s16 dir, ITextureSource *tsrc);
+ TileSpec getTile(v3s16 dir, ITextureSource *tsrc,
+ INodeDefManager *nodemgr) const;
#endif
/*
Gets mineral content of node, if there is any.
MINERAL_NONE if doesn't contain or isn't able to contain mineral.
*/
- u8 getMineral();
+ u8 getMineral(INodeDefManager *nodemgr) const;
/*
Serialization functions
@@ -241,7 +237,7 @@ struct MapNode
static u32 serializedLength(u8 version);
void serialize(u8 *dest, u8 version);
- void deSerialize(u8 *source, u8 version);
+ void deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr);
};
@@ -262,7 +258,7 @@ struct MapNode
returns encoded light value.
*/
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
- v3s16 face_dir);
+ v3s16 face_dir, INodeDefManager *nodemgr);
#endif
diff --git a/src/mapnode_contentfeatures.cpp b/src/mapnode_contentfeatures.cpp
deleted file mode 100644
index 6bafa7338..000000000
--- a/src/mapnode_contentfeatures.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "mapnode_contentfeatures.h"
-
-#include "main.h" // For g_settings
-#include "nodemetadata.h"
-#ifndef SERVER
-#include "tile.h"
-#endif
-
-struct ContentFeatures g_content_features[MAX_CONTENT+1];
-
-/*
- Initialize content feature table.
-
- Must be called before accessing the table.
-*/
-void init_contentfeatures(ITextureSource *tsrc)
-{
-#ifndef SERVER
- /*
- Set initial material type to same in all tiles, so that the
- same material can be used in more stuff.
- This is set according to the leaves because they are the only
- differing material to which all materials can be changed to
- get this optimization.
- */
- u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
- /*if(new_style_leaves)
- initial_material_type = MATERIAL_ALPHA_SIMPLE;
- else
- initial_material_type = MATERIAL_ALPHA_NONE;*/
- for(u16 i=0; i<MAX_CONTENT+1; i++)
- {
- ContentFeatures *f = &g_content_features[i];
- // Re-initialize
- f->reset();
-
- for(u16 j=0; j<6; j++)
- f->tiles[j].material_type = initial_material_type;
- }
-#endif
-
- /*
- Initially set every block to be shown as an unknown block.
- Don't touch CONTENT_IGNORE or CONTENT_AIR.
- */
- for(u16 i=0; i<MAX_CONTENT+1; i++)
- {
- if(i == CONTENT_IGNORE || i == CONTENT_AIR)
- continue;
- ContentFeatures *f = &g_content_features[i];
- f->setAllTextures(tsrc, "unknown_block.png");
- f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
- }
-
- // Make CONTENT_IGNORE to not block the view when occlusion culling
- content_features(CONTENT_IGNORE).solidness = 0;
-
-}
-
-ContentFeatures::~ContentFeatures()
-{
- delete initial_metadata;
-#ifndef SERVER
- delete special_material;
- delete special_atlas;
-#endif
-}
-
-#ifndef SERVER
-void ContentFeatures::setTexture(ITextureSource *tsrc,
- u16 i, std::string name, u8 alpha)
-{
- used_texturenames[name] = true;
-
- if(tsrc)
- {
- tiles[i].texture = tsrc->getTexture(name);
- }
-
- if(alpha != 255)
- {
- tiles[i].alpha = alpha;
- tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
- }
-
- if(inventory_texture == NULL)
- setInventoryTexture(name, tsrc);
-}
-
-void ContentFeatures::setInventoryTexture(std::string imgname,
- ITextureSource *tsrc)
-{
- if(tsrc == NULL)
- return;
-
- imgname += "^[forcesingle";
-
- inventory_texture = tsrc->getTextureRaw(imgname);
-}
-
-void ContentFeatures::setInventoryTextureCube(std::string top,
- std::string left, std::string right, ITextureSource *tsrc)
-{
- if(tsrc == NULL)
- return;
-
- str_replace_char(top, '^', '&');
- str_replace_char(left, '^', '&');
- str_replace_char(right, '^', '&');
-
- std::string imgname_full;
- imgname_full += "[inventorycube{";
- imgname_full += top;
- imgname_full += "{";
- imgname_full += left;
- imgname_full += "{";
- imgname_full += right;
- inventory_texture = tsrc->getTextureRaw(imgname_full);
-}
-#endif
-
-ContentFeatures & content_features(content_t i)
-{
- return g_content_features[i];
-}
-ContentFeatures & content_features(MapNode &n)
-{
- return content_features(n.getContent());
-}
-
-
diff --git a/src/mapsector.cpp b/src/mapsector.cpp
index 4a526c412..9b5432807 100644
--- a/src/mapsector.cpp
+++ b/src/mapsector.cpp
@@ -23,10 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "exceptions.h"
#include "mapblock.h"
-MapSector::MapSector(Map *parent, v2s16 pos):
+MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
differs_from_disk(false),
m_parent(parent),
m_pos(pos),
+ m_gamedef(gamedef),
m_block_cache(NULL)
{
}
@@ -89,7 +90,7 @@ MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
- MapBlock *block = new MapBlock(m_parent, blockpos_map);
+ MapBlock *block = new MapBlock(m_parent, blockpos_map, m_gamedef);
return block;
}
@@ -151,8 +152,8 @@ void MapSector::getBlocks(core::list<MapBlock*> &dest)
ServerMapSector
*/
-ServerMapSector::ServerMapSector(Map *parent, v2s16 pos):
- MapSector(parent, pos)
+ServerMapSector::ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
+ MapSector(parent, pos, gamedef)
{
}
@@ -186,7 +187,8 @@ ServerMapSector* ServerMapSector::deSerialize(
std::istream &is,
Map *parent,
v2s16 p2d,
- core::map<v2s16, MapSector*> & sectors
+ core::map<v2s16, MapSector*> & sectors,
+ IGameDef *gamedef
)
{
/*
@@ -229,7 +231,7 @@ ServerMapSector* ServerMapSector::deSerialize(
}
else
{
- sector = new ServerMapSector(parent, p2d);
+ sector = new ServerMapSector(parent, p2d, gamedef);
sectors.insert(p2d, sector);
}
@@ -247,8 +249,8 @@ ServerMapSector* ServerMapSector::deSerialize(
ClientMapSector
*/
-ClientMapSector::ClientMapSector(Map *parent, v2s16 pos):
- MapSector(parent, pos)
+ClientMapSector::ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
+ MapSector(parent, pos, gamedef)
{
}
diff --git a/src/mapsector.h b/src/mapsector.h
index 44f45d8f0..be9243e67 100644
--- a/src/mapsector.h
+++ b/src/mapsector.h
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class MapBlock;
class Map;
+class IGameDef;
/*
This is an Y-wise stack of MapBlocks.
@@ -43,7 +44,7 @@ class MapSector
{
public:
- MapSector(Map *parent, v2s16 pos);
+ MapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
virtual ~MapSector();
virtual u32 getId() const = 0;
@@ -76,7 +77,9 @@ protected:
Map *m_parent;
// Position on parent (in MapBlock widths)
v2s16 m_pos;
-
+
+ IGameDef *m_gamedef;
+
// Last-used block is cached here for quicker access.
// Be sure to set this to NULL when the cached block is deleted
MapBlock *m_block_cache;
@@ -92,7 +95,7 @@ protected:
class ServerMapSector : public MapSector
{
public:
- ServerMapSector(Map *parent, v2s16 pos);
+ ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
~ServerMapSector();
u32 getId() const
@@ -111,7 +114,8 @@ public:
std::istream &is,
Map *parent,
v2s16 p2d,
- core::map<v2s16, MapSector*> & sectors
+ core::map<v2s16, MapSector*> & sectors,
+ IGameDef *gamedef
);
private:
@@ -121,7 +125,7 @@ private:
class ClientMapSector : public MapSector
{
public:
- ClientMapSector(Map *parent, v2s16 pos);
+ ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
~ClientMapSector();
u32 getId() const
diff --git a/src/materials.cpp b/src/materials.cpp
index e990371ee..d89b1e079 100644
--- a/src/materials.cpp
+++ b/src/materials.cpp
@@ -1,12 +1,13 @@
#include "materials.h"
#include "mapnode.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
-DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp)
+DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
+ INodeDefManager *nodemgr)
{
assert(tp);
- MaterialProperties &mp = content_features(material).material;
+ const MaterialProperties &mp = nodemgr->get(content).material;
if(mp.diggability == DIGGABLE_NOT)
return DiggingProperties(false, 0, 0);
if(mp.diggability == DIGGABLE_CONSTANT)
diff --git a/src/materials.h b/src/materials.h
index 4f0fd6871..62bce1669 100644
--- a/src/materials.h
+++ b/src/materials.h
@@ -89,8 +89,10 @@ struct DiggingProperties
};
class ToolDiggingProperties;
+class INodeDefManager;
-DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp);
+DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
+ INodeDefManager *nodemgr);
#endif
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
new file mode 100644
index 000000000..74d825362
--- /dev/null
+++ b/src/nodedef.cpp
@@ -0,0 +1,175 @@
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "nodedef.h"
+
+#include "main.h" // For g_settings
+#include "nodemetadata.h"
+#ifndef SERVER
+#include "tile.h"
+#endif
+#include "log.h"
+
+ContentFeatures::~ContentFeatures()
+{
+ delete initial_metadata;
+#ifndef SERVER
+ delete special_material;
+ delete special_atlas;
+#endif
+}
+
+#ifndef SERVER
+void ContentFeatures::setTexture(ITextureSource *tsrc,
+ u16 i, std::string name, u8 alpha)
+{
+ used_texturenames.insert(name);
+
+ if(tsrc)
+ {
+ tiles[i].texture = tsrc->getTexture(name);
+ }
+
+ if(alpha != 255)
+ {
+ tiles[i].alpha = alpha;
+ tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
+ }
+
+ if(inventory_texture == NULL)
+ setInventoryTexture(name, tsrc);
+}
+
+void ContentFeatures::setInventoryTexture(std::string imgname,
+ ITextureSource *tsrc)
+{
+ if(tsrc == NULL)
+ return;
+
+ imgname += "^[forcesingle";
+
+ inventory_texture = tsrc->getTextureRaw(imgname);
+}
+
+void ContentFeatures::setInventoryTextureCube(std::string top,
+ std::string left, std::string right, ITextureSource *tsrc)
+{
+ if(tsrc == NULL)
+ return;
+
+ str_replace_char(top, '^', '&');
+ str_replace_char(left, '^', '&');
+ str_replace_char(right, '^', '&');
+
+ std::string imgname_full;
+ imgname_full += "[inventorycube{";
+ imgname_full += top;
+ imgname_full += "{";
+ imgname_full += left;
+ imgname_full += "{";
+ imgname_full += right;
+ inventory_texture = tsrc->getTextureRaw(imgname_full);
+}
+#endif
+
+class CNodeDefManager: public IWritableNodeDefManager
+{
+public:
+ CNodeDefManager(ITextureSource *tsrc)
+ {
+#ifndef SERVER
+ /*
+ Set initial material type to same in all tiles, so that the
+ same material can be used in more stuff.
+ This is set according to the leaves because they are the only
+ differing material to which all materials can be changed to
+ get this optimization.
+ */
+ u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
+ /*if(new_style_leaves)
+ initial_material_type = MATERIAL_ALPHA_SIMPLE;
+ else
+ initial_material_type = MATERIAL_ALPHA_NONE;*/
+ for(u16 i=0; i<=MAX_CONTENT; i++)
+ {
+ ContentFeatures *f = &m_content_features[i];
+ // Re-initialize
+ f->reset();
+
+ for(u16 j=0; j<6; j++)
+ f->tiles[j].material_type = initial_material_type;
+ }
+#endif
+ /*
+ Initially set every block to be shown as an unknown block.
+ Don't touch CONTENT_IGNORE or CONTENT_AIR.
+ */
+ for(u16 i=0; i<=MAX_CONTENT; i++)
+ {
+ if(i == CONTENT_IGNORE || i == CONTENT_AIR)
+ continue;
+ ContentFeatures *f = &m_content_features[i];
+ f->setAllTextures(tsrc, "unknown_block.png");
+ f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
+ }
+ // Make CONTENT_IGNORE to not block the view when occlusion culling
+ m_content_features[CONTENT_IGNORE].solidness = 0;
+ }
+ virtual ~CNodeDefManager()
+ {
+ }
+ virtual IWritableNodeDefManager* clone()
+ {
+ CNodeDefManager *mgr = new CNodeDefManager(NULL);
+ for(u16 i=0; i<=MAX_CONTENT; i++)
+ {
+ mgr->set(i, get(i));
+ }
+ return mgr;
+ }
+ virtual const ContentFeatures& get(content_t c) const
+ {
+ assert(c <= MAX_CONTENT);
+ return m_content_features[c];
+ }
+ virtual const ContentFeatures& get(const MapNode &n) const
+ {
+ return get(n.getContent());
+ }
+ // Writable
+ virtual void set(content_t c, const ContentFeatures &def)
+ {
+ infostream<<"registerNode: registering content \""<<c<<"\""<<std::endl;
+ assert(c <= MAX_CONTENT);
+ m_content_features[c] = def;
+ }
+ virtual ContentFeatures* getModifiable(content_t c)
+ {
+ assert(c <= MAX_CONTENT);
+ return &m_content_features[c];
+ }
+private:
+ ContentFeatures m_content_features[MAX_CONTENT+1];
+};
+
+IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc)
+{
+ return new CNodeDefManager(tsrc);
+}
+
diff --git a/src/mapnode_contentfeatures.h b/src/nodedef.h
index 0f7e35883..dece63fcd 100644
--- a/src/mapnode_contentfeatures.h
+++ b/src/nodedef.h
@@ -17,11 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef MAPNODE_CONTENTFEATURES_HEADER
-#define MAPNODE_CONTENTFEATURES_HEADER
+#ifndef NODEDEF_HEADER
+#define NODEDEF_HEADER
#include "common_irrlicht.h"
#include <string>
+#include <set>
#include "mapnode.h"
#ifndef SERVER
#include "tile.h"
@@ -30,6 +31,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class ITextureSource;
/*
+ TODO: Rename to nodedef.h
+*/
+
+#if 0
+
+/*
Content feature list
Used for determining properties of MapNodes by content type without
@@ -43,6 +50,8 @@ class ITextureSource;
*/
void init_contentfeatures(ITextureSource *tsrc);
+#endif
+
enum ContentParamType
{
CPT_NONE,
@@ -119,7 +128,7 @@ struct ContentFeatures
// List of all block textures that have been used (value is dummy)
// Used for texture atlas making.
// Exists on server too for cleaner code in content_mapnode.cpp.
- core::map<std::string, bool> used_texturenames;
+ std::set<std::string> used_texturenames;
// Type of MapNode::param1
ContentParamType param_type;
@@ -195,6 +204,7 @@ struct ContentFeatures
special_material2 = NULL;
special_atlas = NULL;
#endif
+ used_texturenames.clear();
param_type = CPT_NONE;
is_ground_content = false;
light_propagates = false;
@@ -256,16 +266,9 @@ struct ContentFeatures
#ifndef SERVER
void setTile(u16 i, const TileSpec &tile)
- {
- tiles[i] = tile;
- }
+ { tiles[i] = tile; }
void setAllTiles(const TileSpec &tile)
- {
- for(u16 i=0; i<6; i++)
- {
- setTile(i, tile);
- }
- }
+ { for(u16 i=0; i<6; i++) setTile(i, tile); }
#endif
#ifdef SERVER
@@ -281,94 +284,46 @@ struct ContentFeatures
void setInventoryTextureCube(std::string top,
std::string left, std::string right, ITextureSource *tsrc);
#endif
-};
-
-/*
- Call this to access the ContentFeature list
-*/
-ContentFeatures & content_features(content_t i);
-ContentFeatures & content_features(MapNode &n);
-/*
- Here is a bunch of DEPRECATED functions.
-*/
+ /*
+ Some handy methods
+ */
+ bool isLiquid() const{
+ return (liquid_type != LIQUID_NONE);
+ }
+ bool sameLiquid(const ContentFeatures &f) const{
+ if(!isLiquid() || !f.isLiquid()) return false;
+ return (liquid_alternative_flowing == f.liquid_alternative_flowing);
+ }
+};
-/*
- If true, the material allows light propagation and brightness is stored
- in param.
- NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline bool light_propagates_content(content_t m)
-{
- return content_features(m).light_propagates;
-}
-/*
- If true, the material allows lossless sunlight propagation.
- NOTE: It doesn't seem to go through torches regardlessly of this
- NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline bool sunlight_propagates_content(content_t m)
-{
- return content_features(m).sunlight_propagates;
-}
-/*
- On a node-node surface, the material of the node with higher solidness
- is used for drawing.
- 0: Invisible
- 1: Transparent
- 2: Opaque
- NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline u8 content_solidness(content_t m)
-{
- return content_features(m).solidness;
-}
-// Objects collide with walkable contents
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_walkable(content_t m)
+class INodeDefManager
{
- return content_features(m).walkable;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_liquid(content_t m)
-{
- return content_features(m).liquid_type != LIQUID_NONE;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_flowing_liquid(content_t m)
-{
- return content_features(m).liquid_type == LIQUID_FLOWING;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_liquid_source(content_t m)
-{
- return content_features(m).liquid_type == LIQUID_SOURCE;
-}
-// CONTENT_WATER || CONTENT_WATERSOURCE -> CONTENT_WATER
-// CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline content_t make_liquid_flowing(content_t m)
-{
- u8 c = content_features(m).liquid_alternative_flowing;
- assert(c != CONTENT_IGNORE);
- return c;
-}
-// Pointable contents can be pointed to in the map
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_pointable(content_t m)
-{
- return content_features(m).pointable;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_diggable(content_t m)
-{
- return content_features(m).diggable;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_buildable_to(content_t m)
+public:
+ INodeDefManager(){}
+ virtual ~INodeDefManager(){}
+ // Get node definition
+ virtual const ContentFeatures& get(content_t c) const=0;
+ virtual const ContentFeatures& get(const MapNode &n) const=0;
+};
+
+class IWritableNodeDefManager : public INodeDefManager
{
- return content_features(m).buildable_to;
-}
+public:
+ IWritableNodeDefManager(){}
+ virtual ~IWritableNodeDefManager(){}
+ virtual IWritableNodeDefManager* clone()=0;
+ // Get node definition
+ virtual const ContentFeatures& get(content_t c) const=0;
+ virtual const ContentFeatures& get(const MapNode &n) const=0;
+
+ // Register node definition
+ virtual void set(content_t c, const ContentFeatures &def)=0;
+ virtual ContentFeatures* getModifiable(content_t c)=0;
+};
+
+// If textures not actually available (server), tsrc can be NULL
+IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc);
#endif
diff --git a/src/player.cpp b/src/player.cpp
index a1edb8299..8e73f3501 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -27,9 +27,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif
#include "main.h" // For g_settings
#include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "environment.h"
+#include "gamedef.h"
-Player::Player():
+Player::Player(IGameDef *gamedef):
touching_ground(false),
in_water(false),
in_water_stable(false),
@@ -39,6 +41,8 @@ Player::Player():
craftresult_is_preview(true),
hp(20),
peer_id(PEER_ID_INEXISTENT),
+// protected
+ m_gamedef(gamedef),
m_selected_item(0),
m_pitch(0),
m_yaw(0),
@@ -129,7 +133,7 @@ void Player::serialize(std::ostream &os)
inventory.serialize(os);
}
-void Player::deSerialize(std::istream &is, IGameDef *gamedef)
+void Player::deSerialize(std::istream &is)
{
Settings args;
@@ -163,13 +167,28 @@ void Player::deSerialize(std::istream &is, IGameDef *gamedef)
hp = 20;
}
- inventory.deSerialize(is, gamedef);
+ inventory.deSerialize(is, m_gamedef);
}
/*
ServerRemotePlayer
*/
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
+ Player(env->getGameDef()),
+ ServerActiveObject(env, v3f(0,0,0))
+{
+}
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
+ const char *name_):
+ Player(env->getGameDef()),
+ ServerActiveObject(env, pos_)
+{
+ setPosition(pos_);
+ peer_id = peer_id_;
+ updateName(name_);
+}
+
/* ServerActiveObject interface */
InventoryItem* ServerRemotePlayer::getWieldedItem()
@@ -237,9 +256,11 @@ s16 ServerRemotePlayer::getHP()
#ifndef SERVER
RemotePlayer::RemotePlayer(
+ IGameDef *gamedef,
scene::ISceneNode* parent,
IrrlichtDevice *device,
s32 id):
+ Player(gamedef),
scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id),
m_text(NULL)
{
@@ -354,7 +375,8 @@ void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
LocalPlayer
*/
-LocalPlayer::LocalPlayer():
+LocalPlayer::LocalPlayer(IGameDef *gamedef):
+ Player(gamedef),
m_sneak_node(32767,32767,32767),
m_sneak_node_exists(false)
{
@@ -370,6 +392,8 @@ LocalPlayer::~LocalPlayer()
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
core::list<CollisionInfo> *collision_info)
{
+ INodeDefManager *nodemgr = m_gamedef->ndef();
+
v3f position = getPosition();
v3f oldpos = position;
v3s16 oldpos_i = floatToInt(oldpos, BS);
@@ -407,13 +431,13 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
if(in_water)
{
v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS);
- in_water = content_liquid(map.getNode(pp).getContent());
+ in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
}
// If not in water, the threshold of going in is at lower y
else
{
v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS);
- in_water = content_liquid(map.getNode(pp).getContent());
+ in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
}
}
catch(InvalidPositionException &e)
@@ -426,7 +450,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
*/
try{
v3s16 pp = floatToInt(position + v3f(0,0,0), BS);
- in_water_stable = content_liquid(map.getNode(pp).getContent());
+ in_water_stable = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
}
catch(InvalidPositionException &e)
{
@@ -438,14 +462,14 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
*/
try {
- v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
+ v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
- is_climbing = ((content_features(map.getNode(pp).getContent()).climbable ||
- content_features(map.getNode(pp2).getContent()).climbable) && !free_move);
+ is_climbing = ((nodemgr->get(map.getNode(pp).getContent()).climbable ||
+ nodemgr->get(map.getNode(pp2).getContent()).climbable) && !free_move);
}
catch(InvalidPositionException &e)
{
- is_climbing = false;
+ is_climbing = false;
}
/*
@@ -553,7 +577,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
bool is_unloaded = false;
try{
// Player collides into walkable nodes
- if(content_walkable(map.getNode(v3s16(x,y,z)).getContent()) == false)
+ if(nodemgr->get(map.getNode(v3s16(x,y,z))).walkable == false)
continue;
}
catch(InvalidPositionException &e)
@@ -719,10 +743,10 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
try{
// The node to be sneaked on has to be walkable
- if(content_walkable(map.getNode(p).getContent()) == false)
+ if(nodemgr->get(map.getNode(p)).walkable == false)
continue;
// And the node above it has to be nonwalkable
- if(content_walkable(map.getNode(p+v3s16(0,1,0)).getContent()) == true)
+ if(nodemgr->get(map.getNode(p+v3s16(0,1,0))).walkable == true)
continue;
}
catch(InvalidPositionException &e)
diff --git a/src/player.h b/src/player.h
index d6147b208..ecde59ce1 100644
--- a/src/player.h
+++ b/src/player.h
@@ -30,13 +30,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map;
+class IGameDef;
class Player
{
public:
-
- Player();
+ Player(IGameDef *gamedef);
virtual ~Player();
void resetInventory();
@@ -141,7 +141,7 @@ public:
deSerialize stops reading exactly at the right point.
*/
void serialize(std::ostream &os);
- void deSerialize(std::istream &is, IGameDef *gamedef);
+ void deSerialize(std::istream &is);
bool touching_ground;
// This oscillates so that the player jumps a bit above the surface
@@ -164,6 +164,8 @@ public:
u16 peer_id;
protected:
+ IGameDef *m_gamedef;
+
char m_name[PLAYERNAME_SIZE];
u16 m_selected_item;
f32 m_pitch;
@@ -185,26 +187,15 @@ public:
class ServerRemotePlayer : public Player, public ServerActiveObject
{
public:
- ServerRemotePlayer(ServerEnvironment *env):
- ServerActiveObject(env, v3f(0,0,0))
- {
- }
+ ServerRemotePlayer(ServerEnvironment *env);
ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
- const char *name_):
- ServerActiveObject(env, pos_)
- {
- setPosition(pos_);
- peer_id = peer_id_;
- updateName(name_);
- }
+ const char *name_);
+
virtual ~ServerRemotePlayer()
- {
- }
+ {}
virtual bool isLocal() const
- {
- return false;
- }
+ { return false; }
virtual void move(f32 dtime, Map &map, f32 pos_max_d)
{
@@ -242,6 +233,7 @@ class RemotePlayer : public Player, public scene::ISceneNode
{
public:
RemotePlayer(
+ IGameDef *gamedef,
scene::ISceneNode* parent=NULL,
IrrlichtDevice *device=NULL,
s32 id=0);
@@ -378,7 +370,7 @@ struct PlayerControl
class LocalPlayer : public Player
{
public:
- LocalPlayer();
+ LocalPlayer(IGameDef *gamedef);
virtual ~LocalPlayer();
bool isLocal() const
diff --git a/src/server.cpp b/src/server.cpp
index 40a5e183b..75fb7cd72 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -41,8 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"
#include "script.h"
#include "scriptapi.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
#include "content_tool.h" // For content_tool_init
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -959,6 +959,7 @@ Server::Server(
m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
m_lua(NULL),
m_toolmgr(createToolDefManager()),
+ m_nodemgr(createNodeDefManager(NULL)),
m_thread(this),
m_emergethread(this),
m_time_counter(0),
@@ -983,10 +984,15 @@ Server::Server(
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
+
+ infostream<<"m_nodemgr="<<m_nodemgr<<std::endl;
// Initialize default tool definitions
content_tool_init(m_toolmgr);
+ // Initialize default node definitions
+ content_mapnode_init(NULL, m_nodemgr);
+
// Initialize scripting
infostream<<"Server: Initializing scripting"<<std::endl;
@@ -1107,6 +1113,7 @@ Server::~Server()
delete m_env;
delete m_toolmgr;
+ delete m_nodemgr;
// Deinitialize scripting
infostream<<"Server: Deinitializing scripting"<<std::endl;
@@ -2481,14 +2488,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
{
MapNode n = m_env->getMap().getNode(p_under);
// Get mineral
- mineral = n.getMineral();
+ mineral = n.getMineral(m_nodemgr);
// Get material at position
material = n.getContent();
// If not yet cancelled
if(cannot_remove_node == false)
{
// If it's not diggable, do nothing
- if(content_diggable(material) == false)
+ if(m_nodemgr->get(material).diggable == false)
{
infostream<<"Server: Not finishing digging: "
<<"Node not diggable"
@@ -2584,7 +2591,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
ToolDiggingProperties tp =
m_toolmgr->getDiggingProperties(toolname);
DiggingProperties prop =
- getDiggingProperties(material, &tp);
+ getDiggingProperties(material, &tp, m_nodemgr);
if(prop.diggable == false)
{
@@ -2614,7 +2621,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// If not mineral
if(item == NULL)
{
- std::string &dug_s = content_features(material).dug_item;
+ const std::string &dug_s = m_nodemgr->get(material).dug_item;
if(dug_s != "")
{
std::istringstream is(dug_s, std::ios::binary);
@@ -2640,20 +2647,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// If not mineral
if(item == NULL)
{
- std::string &extra_dug_s = content_features(material).extra_dug_item;
- s32 extra_rarity = content_features(material).extra_dug_item_rarity;
+ const std::string &extra_dug_s = m_nodemgr->get(material).extra_dug_item;
+ s32 extra_rarity = m_nodemgr->get(material).extra_dug_item_rarity;
if(extra_dug_s != "" && extra_rarity != 0
&& myrand() % extra_rarity == 0)
{
- std::istringstream is(extra_dug_s, std::ios::binary);
+ std::istringstream is(extra_dug_s, std::ios::binary);
item = InventoryItem::deSerialize(is, this);
}
}
if(item != NULL)
{
- // Add a item to inventory
- player->inventory.addItem("main", item);
+ // Add a item to inventory
+ player->inventory.addItem("main", item);
// Send inventory
UpdateCrafting(player->peer_id);
@@ -2717,7 +2724,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" because privileges are "<<getPlayerPrivs(player)
<<std::endl;
- if(content_features(n2).buildable_to == false
+ if(m_nodemgr->get(n2).buildable_to == false
|| no_enough_privs)
{
// Client probably has wrong data.
@@ -2755,11 +2762,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" at "<<PP(p_under)<<std::endl;
// Calculate direction for wall mounted stuff
- if(content_features(n).wall_mounted)
+ if(m_nodemgr->get(n).wall_mounted)
n.param2 = packDir(p_under - p_over);
// Calculate the direction for furnaces and chests and stuff
- if(content_features(n).param_type == CPT_FACEDIR_SIMPLE)
+ if(m_nodemgr->get(n).param_type == CPT_FACEDIR_SIMPLE)
{
v3f playerpos = player->getPosition();
v3f blockpos = intToFloat(p_over, BS) - playerpos;
@@ -4192,6 +4199,21 @@ void Server::notifyPlayers(const std::wstring msg)
BroadcastChatMessage(msg);
}
+// IGameDef interface
+// Under envlock
+IToolDefManager* Server::getToolDefManager()
+{
+ return m_toolmgr;
+}
+INodeDefManager* Server::getNodeDefManager()
+{
+ return m_nodemgr;
+}
+ITextureSource* Server::getTextureSource()
+{
+ return NULL;
+}
+
v3f findSpawnPos(ServerMap &map)
{
//return v3f(50,50,50)*BS;
diff --git a/src/server.h b/src/server.h
index 2d0aa8183..e1a583826 100644
--- a/src/server.h
+++ b/src/server.h
@@ -32,7 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h"
struct LuaState;
typedef struct lua_State lua_State;
-class IToolDefManager;
+class IWritableToolDefManager;
+class IWritableNodeDefManager;
/*
Some random functions
@@ -486,10 +487,9 @@ public:
// IGameDef interface
// Under envlock
- virtual IToolDefManager* getToolDefManager()
- { return m_toolmgr; }
- virtual INodeDefManager* getNodeDefManager()
- { assert(0); return NULL; } // TODO
+ virtual IToolDefManager* getToolDefManager();
+ virtual INodeDefManager* getNodeDefManager();
+ virtual ITextureSource* getTextureSource();
private:
@@ -616,7 +616,10 @@ private:
lua_State *m_lua;
// Tool definition manager
- IToolDefManager *m_toolmgr;
+ IWritableToolDefManager *m_toolmgr;
+
+ // Node definition manager
+ IWritableNodeDefManager *m_nodemgr;
/*
Threads
diff --git a/src/servermain.cpp b/src/servermain.cpp
index deae90bba..64853604b 100644
--- a/src/servermain.cpp
+++ b/src/servermain.cpp
@@ -74,7 +74,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "profiler.h"
#include "log.h"
-#include "mapnode_contentfeatures.h" // For init_contentfeatures
+#include "nodedef.h" // For init_contentfeatures
#include "content_mapnode.h" // For content_mapnode_init
/*
@@ -302,11 +302,6 @@ int main(int argc, char *argv[])
// Initialize stuff
- // Initialize content feature table without textures
- init_contentfeatures(NULL);
- // Initialize mapnode content without textures
- content_mapnode_init(NULL);
-
init_mineral();
/*
diff --git a/src/test.cpp b/src/test.cpp
index 37412d179..e1242ccb3 100644
--- a/src/test.cpp
+++ b/src/test.cpp
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <sstream>
#include "porting.h"
#include "content_mapnode.h"
+#include "nodedef.h"
#include "mapsector.h"
#include "settings.h"
#include "log.h"
@@ -216,26 +217,26 @@ struct TestCompress
struct TestMapNode
{
- void Run()
+ void Run(INodeDefManager *nodedef)
{
MapNode n;
// Default values
assert(n.getContent() == CONTENT_AIR);
- assert(n.getLight(LIGHTBANK_DAY) == 0);
- assert(n.getLight(LIGHTBANK_NIGHT) == 0);
+ assert(n.getLight(LIGHTBANK_DAY, nodedef) == 0);
+ assert(n.getLight(LIGHTBANK_NIGHT, nodedef) == 0);
// Transparency
n.setContent(CONTENT_AIR);
- assert(n.light_propagates() == true);
+ assert(nodedef->get(n).light_propagates == true);
n.setContent(CONTENT_STONE);
- assert(n.light_propagates() == false);
+ assert(nodedef->get(n).light_propagates == false);
}
};
struct TestVoxelManipulator
{
- void Run()
+ void Run(INodeDefManager *nodedef)
{
/*
VoxelArea
@@ -278,13 +279,13 @@ struct TestVoxelManipulator
VoxelManipulator v;
- v.print(infostream);
+ v.print(infostream, nodedef);
infostream<<"*** Setting (-1,0,-1)=2 ***"<<std::endl;
v.setNodeNoRef(v3s16(-1,0,-1), MapNode(2));
- v.print(infostream);
+ v.print(infostream, nodedef);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
@@ -292,85 +293,16 @@ struct TestVoxelManipulator
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1)));
- v.print(infostream);
+ v.print(infostream, nodedef);
infostream<<"*** Adding area ***"<<std::endl;
v.addArea(a);
- v.print(infostream);
+ v.print(infostream, nodedef);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
-
-#if 0
- /*
- Water stuff
- */
-
- v.clear();
-
- const char *content =
- "#...###### "
- "#...##..## "
- "#........ .."
- "############"
-
- "#...###### "
- "#...##..## "
- "#........# "
- "############"
- ;
-
- v3s16 size(12, 4, 2);
- VoxelArea area(v3s16(0,0,0), size-v3s16(1,1,1));
-
- const char *p = content;
- for(s16 z=0; z<size.Z; z++)
- for(s16 y=size.Y-1; y>=0; y--)
- for(s16 x=0; x<size.X; x++)
- {
- MapNode n;
- //n.pressure = size.Y - y;
- if(*p == '#')
- n.setContent(CONTENT_STONE);
- else if(*p == '.')
- n.setContent(CONTENT_WATER);
- else if(*p == ' ')
- n.setContent(CONTENT_AIR);
- else
- assert(0);
- v.setNode(v3s16(x,y,z), n);
- p++;
- }
-
- v.print(infostream, VOXELPRINT_WATERPRESSURE);
-
- core::map<v3s16, u8> active_nodes;
- v.updateAreaWaterPressure(area, active_nodes);
-
- v.print(infostream, VOXELPRINT_WATERPRESSURE);
-
- //s16 highest_y = -32768;
- /*
- NOTE: These are commented out because this behaviour is changed
- all the time
- */
- //assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
- //assert(highest_y == 3);
- /*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
- //assert(highest_y == 3);*/
-
- active_nodes.clear();
- active_nodes[v3s16(9,1,0)] = 1;
- //v.flowWater(active_nodes, 0, true, 1000);
- v.flowWater(active_nodes, 0, false, 1000);
-
- infostream<<"Final result of flowWater:"<<std::endl;
- v.print(infostream, VOXELPRINT_WATERPRESSURE);
-#endif
-
- //assert(0);
}
};
@@ -1143,15 +1075,27 @@ struct TestConnection
x.Run();\
}
+#define TESTPARAMS(X, ...)\
+{\
+ X x;\
+ infostream<<"Running " #X <<std::endl;\
+ x.Run(__VA_ARGS__);\
+}
+
void run_tests()
{
DSTACK(__FUNCTION_NAME);
+
+ // Create node definitions
+ IWritableNodeDefManager *nodedef = createNodeDefManager(NULL);
+ content_mapnode_init(NULL, nodedef);
+
infostream<<"run_tests() started"<<std::endl;
TEST(TestUtilities);
TEST(TestSettings);
TEST(TestCompress);
- TEST(TestMapNode);
- TEST(TestVoxelManipulator);
+ TESTPARAMS(TestMapNode, nodedef);
+ TESTPARAMS(TestVoxelManipulator, nodedef);
//TEST(TestMapBlock);
//TEST(TestMapSector);
if(INTERNET_SIMULATOR == false){
diff --git a/src/tile.cpp b/src/tile.cpp
index 32de8cda2..c8fffffa7 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -27,7 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"
#include "mapnode.h" // For texture atlas making
#include "mineral.h" // For texture atlas making
-#include "mapnode_contentfeatures.h" // For texture atlas making
+#include "nodedef.h" // For texture atlas making
+#include "gamedef.h"
/*
A cache from texture name to texture path
@@ -148,6 +149,142 @@ std::string getTexturePath(const std::string &filename)
TextureSource
*/
+class TextureSource : public IWritableTextureSource
+{
+public:
+ TextureSource(IrrlichtDevice *device);
+ ~TextureSource();
+
+ /*
+ Example case:
+ Now, assume a texture with the id 1 exists, and has the name
+ "stone.png^mineral1".
+ Then a random thread calls getTextureId for a texture called
+ "stone.png^mineral1^crack0".
+ ...Now, WTF should happen? Well:
+ - getTextureId strips off stuff recursively from the end until
+ the remaining part is found, or nothing is left when
+ something is stripped out
+
+ But it is slow to search for textures by names and modify them
+ like that?
+ - ContentFeatures is made to contain ids for the basic plain
+ textures
+ - Crack textures can be slow by themselves, but the framework
+ must be fast.
+
+ Example case #2:
+ - Assume a texture with the id 1 exists, and has the name
+ "stone.png^mineral1" and is specified as a part of some atlas.
+ - Now MapBlock::getNodeTile() stumbles upon a node which uses
+ texture id 1, and finds out that NODEMOD_CRACK must be applied
+ with progression=0
+ - It finds out the name of the texture with getTextureName(1),
+ appends "^crack0" to it and gets a new texture id with
+ getTextureId("stone.png^mineral1^crack0")
+
+ */
+
+ /*
+ Gets a texture id from cache or
+ - if main thread, from getTextureIdDirect
+ - if other thread, adds to request queue and waits for main thread
+ */
+ u32 getTextureId(const std::string &name);
+
+ /*
+ Example names:
+ "stone.png"
+ "stone.png^crack2"
+ "stone.png^blit:mineral_coal.png"
+ "stone.png^blit:mineral_coal.png^crack1"
+
+ - If texture specified by name is found from cache, return the
+ cached id.
+ - Otherwise generate the texture, add to cache and return id.
+ Recursion is used to find out the largest found part of the
+ texture and continue based on it.
+
+ The id 0 points to a NULL texture. It is returned in case of error.
+ */
+ u32 getTextureIdDirect(const std::string &name);
+
+ /*
+ Finds out the name of a cached texture.
+ */
+ std::string getTextureName(u32 id);
+
+ /*
+ If texture specified by the name pointed by the id doesn't
+ exist, create it, then return the cached texture.
+
+ Can be called from any thread. If called from some other thread
+ and not found in cache, the call is queued to the main thread
+ for processing.
+ */
+ AtlasPointer getTexture(u32 id);
+
+ AtlasPointer getTexture(const std::string &name)
+ {
+ return getTexture(getTextureId(name));
+ }
+
+ // Gets a separate texture
+ video::ITexture* getTextureRaw(const std::string &name)
+ {
+ AtlasPointer ap = getTexture(name);
+ return ap.atlas;
+ }
+
+ /*
+ Update new texture pointer and texture coordinates to an
+ AtlasPointer based on it's texture id
+ */
+ void updateAP(AtlasPointer &ap);
+
+ /*
+ Build the main texture atlas which contains most of the
+ textures.
+
+ This is called by the constructor.
+ */
+ void buildMainAtlas(class IGameDef *gamedef);
+
+ /*
+ Processes queued texture requests from other threads.
+
+ Shall be called from the main thread.
+ */
+ void processQueue();
+
+private:
+
+ // The id of the thread that is allowed to use irrlicht directly
+ threadid_t m_main_thread;
+ // The irrlicht device
+ IrrlichtDevice *m_device;
+
+ // A texture id is index in this array.
+ // The first position contains a NULL texture.
+ core::array<SourceAtlasPointer> m_atlaspointer_cache;
+ // Maps a texture name to an index in the former.
+ core::map<std::string, u32> m_name_to_id;
+ // The two former containers are behind this mutex
+ JMutex m_atlaspointer_cache_mutex;
+
+ // Main texture atlas. This is filled at startup and is then not touched.
+ video::IImage *m_main_atlas_image;
+ video::ITexture *m_main_atlas_texture;
+
+ // Queued texture fetches (to be processed by the main thread)
+ RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+};
+
+IWritableTextureSource* createTextureSource(IrrlichtDevice *device)
+{
+ return new TextureSource(device);
+}
+
TextureSource::TextureSource(IrrlichtDevice *device):
m_device(device),
m_main_atlas_image(NULL),
@@ -162,12 +299,6 @@ TextureSource::TextureSource(IrrlichtDevice *device):
// Add a NULL AtlasPointer as the first index, named ""
m_atlaspointer_cache.push_back(SourceAtlasPointer(""));
m_name_to_id[""] = 0;
-
- // Build main texture atlas
- if(g_settings->getBool("enable_texture_atlas"))
- buildMainAtlas();
- else
- infostream<<"Not building texture atlas."<<std::endl;
}
TextureSource::~TextureSource()
@@ -487,8 +618,17 @@ AtlasPointer TextureSource::getTexture(u32 id)
return m_atlaspointer_cache[id].a;
}
-void TextureSource::buildMainAtlas()
+void TextureSource::updateAP(AtlasPointer &ap)
{
+ AtlasPointer ap2 = getTexture(ap.id);
+ ap = ap2;
+}
+
+void TextureSource::buildMainAtlas(class IGameDef *gamedef)
+{
+ assert(gamedef->tsrc() == this);
+ INodeDefManager *ndef = gamedef->ndef();
+
infostream<<"TextureSource::buildMainAtlas()"<<std::endl;
//return; // Disable (for testing)
@@ -521,15 +661,15 @@ void TextureSource::buildMainAtlas()
{
if(j == CONTENT_IGNORE || j == CONTENT_AIR)
continue;
- ContentFeatures *f = &content_features(j);
- for(core::map<std::string, bool>::Iterator
- i = f->used_texturenames.getIterator();
- i.atEnd() == false; i++)
+ const ContentFeatures &f = ndef->get(j);
+ for(std::set<std::string>::const_iterator
+ i = f.used_texturenames.begin();
+ i != f.used_texturenames.end(); i++)
{
- std::string name = i.getNode()->getKey();
+ std::string name = *i;
sourcelist[name] = true;
- if(f->often_contains_mineral){
+ if(f.often_contains_mineral){
for(int k=1; k<MINERAL_COUNT; k++){
std::string mineraltexture = mineral_block_texture(k);
std::string fulltexture = name + "^" + mineraltexture;
@@ -658,8 +798,18 @@ void TextureSource::buildMainAtlas()
Add texture to caches
*/
- // Get next id
+ bool reuse_old_id = false;
u32 id = m_atlaspointer_cache.size();
+ // Check old id without fetching a texture
+ core::map<std::string, u32>::Node *n;
+ n = m_name_to_id.find(name);
+ // If it exists, we will replace the old definition
+ if(n){
+ id = n->getValue();
+ reuse_old_id = true;
+ }
+ infostream<<"TextureSource::buildMainAtlas(): "
+ <<"Replacing old AtlasPointer"<<std::endl;
// Create AtlasPointer
AtlasPointer ap(id);
@@ -672,8 +822,11 @@ void TextureSource::buildMainAtlas()
// Create SourceAtlasPointer and add to containers
SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
- m_atlaspointer_cache.push_back(nap);
- m_name_to_id.insert(name, id);
+ if(reuse_old_id)
+ m_atlaspointer_cache[id] = nap;
+ else
+ m_atlaspointer_cache.push_back(nap);
+ m_name_to_id[name] = id;
// Increment position
pos_in_atlas.Y += dim.Height + padding * 2;
diff --git a/src/tile.h b/src/tile.h
index da23615c3..ac4e790b4 100644
--- a/src/tile.h
+++ b/src/tile.h
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h"
#include <string>
+class IGameDef;
+
/*
tile.{h,cpp}: Texture handling stuff.
*/
@@ -120,8 +122,9 @@ struct SourceAtlasPointer
};
/*
- Implementation (to be used as a no-op on the server)
+ TextureSource creates and caches textures.
*/
+
class ITextureSource
{
public:
@@ -137,133 +140,27 @@ public:
{return NULL;}
};
-/*
- Creates and caches textures.
-*/
-class TextureSource : public ITextureSource
+class IWritableTextureSource : public ITextureSource
{
public:
- TextureSource(IrrlichtDevice *device);
- ~TextureSource();
-
- /*
- Processes queued texture requests from other threads.
-
- Shall be called from the main thread.
- */
- void processQueue();
-
- /*
- Example case:
- Now, assume a texture with the id 1 exists, and has the name
- "stone.png^mineral1".
- Then a random thread calls getTextureId for a texture called
- "stone.png^mineral1^crack0".
- ...Now, WTF should happen? Well:
- - getTextureId strips off stuff recursively from the end until
- the remaining part is found, or nothing is left when
- something is stripped out
-
- But it is slow to search for textures by names and modify them
- like that?
- - ContentFeatures is made to contain ids for the basic plain
- textures
- - Crack textures can be slow by themselves, but the framework
- must be fast.
-
- Example case #2:
- - Assume a texture with the id 1 exists, and has the name
- "stone.png^mineral1" and is specified as a part of some atlas.
- - Now MapBlock::getNodeTile() stumbles upon a node which uses
- texture id 1, and finds out that NODEMOD_CRACK must be applied
- with progression=0
- - It finds out the name of the texture with getTextureName(1),
- appends "^crack0" to it and gets a new texture id with
- getTextureId("stone.png^mineral1^crack0")
-
- */
-
- /*
- Gets a texture id from cache or
- - if main thread, from getTextureIdDirect
- - if other thread, adds to request queue and waits for main thread
- */
- u32 getTextureId(const std::string &name);
-
- /*
- Example names:
- "stone.png"
- "stone.png^crack2"
- "stone.png^blit:mineral_coal.png"
- "stone.png^blit:mineral_coal.png^crack1"
-
- - If texture specified by name is found from cache, return the
- cached id.
- - Otherwise generate the texture, add to cache and return id.
- Recursion is used to find out the largest found part of the
- texture and continue based on it.
-
- The id 0 points to a NULL texture. It is returned in case of error.
- */
- u32 getTextureIdDirect(const std::string &name);
-
- /*
- Finds out the name of a cached texture.
- */
- std::string getTextureName(u32 id);
-
- /*
- If texture specified by the name pointed by the id doesn't
- exist, create it, then return the cached texture.
-
- Can be called from any thread. If called from some other thread
- and not found in cache, the call is queued to the main thread
- for processing.
- */
- AtlasPointer getTexture(u32 id);
-
- AtlasPointer getTexture(const std::string &name)
- {
- return getTexture(getTextureId(name));
- }
-
- // Gets a separate texture
- video::ITexture* getTextureRaw(const std::string &name)
- {
- AtlasPointer ap = getTexture(name);
- return ap.atlas;
- }
-
-private:
- /*
- Build the main texture atlas which contains most of the
- textures.
-
- This is called by the constructor.
- */
- void buildMainAtlas();
-
- // The id of the thread that is allowed to use irrlicht directly
- threadid_t m_main_thread;
- // The irrlicht device
- IrrlichtDevice *m_device;
-
- // A texture id is index in this array.
- // The first position contains a NULL texture.
- core::array<SourceAtlasPointer> m_atlaspointer_cache;
- // Maps a texture name to an index in the former.
- core::map<std::string, u32> m_name_to_id;
- // The two former containers are behind this mutex
- JMutex m_atlaspointer_cache_mutex;
-
- // Main texture atlas. This is filled at startup and is then not touched.
- video::IImage *m_main_atlas_image;
- video::ITexture *m_main_atlas_texture;
+ IWritableTextureSource(){}
+ virtual ~IWritableTextureSource(){}
+ virtual u32 getTextureId(const std::string &name){return 0;}
+ virtual u32 getTextureIdDirect(const std::string &name){return 0;}
+ virtual std::string getTextureName(u32 id){return "";}
+ virtual AtlasPointer getTexture(u32 id){return AtlasPointer(0);}
+ virtual AtlasPointer getTexture(const std::string &name)
+ {return AtlasPointer(0);}
+ virtual video::ITexture* getTextureRaw(const std::string &name)
+ {return NULL;}
- // Queued texture fetches (to be processed by the main thread)
- RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+ virtual void updateAP(AtlasPointer &ap)=0;
+ virtual void buildMainAtlas(class IGameDef *gamedef)=0;
+ virtual void processQueue()=0;
};
+IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
+
enum MaterialType{
MATERIAL_ALPHA_NONE,
MATERIAL_ALPHA_VERTEX,
diff --git a/src/tool.cpp b/src/tooldef.cpp
index d45556269..f35cf2b82 100644
--- a/src/tool.cpp
+++ b/src/tooldef.cpp
@@ -17,12 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "tool.h"
+#include "tooldef.h"
#include "irrlichttypes.h"
#include "log.h"
#include <ostream>
-class CToolDefManager: public IToolDefManager
+class CToolDefManager: public IWritableToolDefManager
{
public:
virtual ~CToolDefManager()
@@ -33,20 +33,7 @@ public:
delete i.getNode()->getValue();
}
}
- virtual bool registerTool(std::string toolname, const ToolDefinition &def)
- {
- infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
- core::map<std::string, ToolDefinition*>::Node *n;
- n = m_tool_definitions.find(toolname);
- if(n != NULL){
- errorstream<<"registerTool: registering tool \""<<toolname
- <<"\" failed: name is already registered"<<std::endl;
- return false;
- }
- m_tool_definitions[toolname] = new ToolDefinition(def);
- return true;
- }
- virtual ToolDefinition* getToolDefinition(const std::string &toolname)
+ virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const
{
core::map<std::string, ToolDefinition*>::Node *n;
n = m_tool_definitions.find(toolname);
@@ -54,33 +41,46 @@ public:
return NULL;
return n->getValue();
}
- virtual std::string getImagename(const std::string &toolname)
+ virtual std::string getImagename(const std::string &toolname) const
{
- ToolDefinition *def = getToolDefinition(toolname);
+ const ToolDefinition *def = getToolDefinition(toolname);
if(def == NULL)
return "";
return def->imagename;
}
virtual ToolDiggingProperties getDiggingProperties(
- const std::string &toolname)
+ const std::string &toolname) const
{
- ToolDefinition *def = getToolDefinition(toolname);
+ const ToolDefinition *def = getToolDefinition(toolname);
// If tool does not exist, just return an impossible
if(def == NULL){
// If tool does not exist, try empty name
- ToolDefinition *def = getToolDefinition("");
+ const ToolDefinition *def = getToolDefinition("");
if(def == NULL) // If that doesn't exist either, return default
return ToolDiggingProperties();
return def->properties;
}
return def->properties;
}
+ virtual bool registerTool(std::string toolname, const ToolDefinition &def)
+ {
+ infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
+ core::map<std::string, ToolDefinition*>::Node *n;
+ n = m_tool_definitions.find(toolname);
+ if(n != NULL){
+ errorstream<<"registerTool: registering tool \""<<toolname
+ <<"\" failed: name is already registered"<<std::endl;
+ return false;
+ }
+ m_tool_definitions[toolname] = new ToolDefinition(def);
+ return true;
+ }
private:
// Key is name
core::map<std::string, ToolDefinition*> m_tool_definitions;
};
-IToolDefManager* createToolDefManager()
+IWritableToolDefManager* createToolDefManager()
{
return new CToolDefManager();
}
diff --git a/src/tool.h b/src/tooldef.h
index a2a94f7fc..8aa6abea4 100644
--- a/src/tool.h
+++ b/src/tooldef.h
@@ -17,11 +17,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef TOOL_HEADER
-#define TOOL_HEADER
+#ifndef TOOLDEF_HEADER
+#define TOOLDEF_HEADER
#include <string>
+/*
+ TODO: Rename to tooldef.h
+*/
+
struct ToolDiggingProperties
{
// time = basetime + sum(feature here * feature in MaterialProperties)
@@ -69,14 +73,26 @@ class IToolDefManager
public:
IToolDefManager(){}
virtual ~IToolDefManager(){}
- virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
- virtual ToolDefinition* getToolDefinition(const std::string &toolname)=0;
- virtual std::string getImagename(const std::string &toolname)=0;
+ virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
+ virtual std::string getImagename(const std::string &toolname) const =0;
+ virtual ToolDiggingProperties getDiggingProperties(
+ const std::string &toolname) const =0;
+};
+
+class IWritableToolDefManager : public IToolDefManager
+{
+public:
+ IWritableToolDefManager(){}
+ virtual ~IWritableToolDefManager(){}
+ virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
+ virtual std::string getImagename(const std::string &toolname) const =0;
virtual ToolDiggingProperties getDiggingProperties(
- const std::string &toolname)=0;
+ const std::string &toolname) const =0;
+
+ virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
};
-IToolDefManager* createToolDefManager();
+IWritableToolDefManager* createToolDefManager();
#endif
diff --git a/src/voxel.cpp b/src/voxel.cpp
index 616a197e3..632431244 100644
--- a/src/voxel.cpp
+++ b/src/voxel.cpp
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h"
#include "utility.h" // For TimeTaker
#include "gettime.h"
-#include "content_mapnode.h"
+#include "nodedef.h"
/*
Debug stuff
@@ -63,7 +63,8 @@ void VoxelManipulator::clear()
m_flags = NULL;
}
-void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
+void VoxelManipulator::print(std::ostream &o, INodeDefManager *nodemgr,
+ VoxelPrintMode mode)
{
v3s16 em = m_area.getExtent();
v3s16 of = m_area.MinEdge;
@@ -102,7 +103,7 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
}
else if(mode == VOXELPRINT_WATERPRESSURE)
{
- if(m == CONTENT_WATER)
+ if(nodemgr->get(m).isLiquid())
{
c = 'w';
if(pr <= 9)
@@ -279,7 +280,7 @@ void VoxelManipulator::clearFlag(u8 flags)
}
void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
- core::map<v3s16, bool> & light_sources)
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr)
{
v3s16 dirs[6] = {
v3s16(0,0,1), // back
@@ -309,21 +310,21 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node)
*/
- if(n2.getLight(bank) < oldlight)
+ if(n2.getLight(bank, nodemgr) < oldlight)
{
/*
And the neighbor is transparent and it has some light
*/
- if(n2.light_propagates() && n2.getLight(bank) != 0)
+ if(nodemgr->get(n2).light_propagates && n2.getLight(bank, nodemgr) != 0)
{
/*
Set light to 0 and add to queue
*/
- u8 current_light = n2.getLight(bank);
- n2.setLight(bank, 0);
+ u8 current_light = n2.getLight(bank, nodemgr);
+ n2.setLight(bank, 0, nodemgr);
- unspreadLight(bank, n2pos, current_light, light_sources);
+ unspreadLight(bank, n2pos, current_light, light_sources, nodemgr);
/*
Remove from light_sources if it is there
@@ -362,7 +363,7 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
*/
void VoxelManipulator::unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes,
- core::map<v3s16, bool> & light_sources)
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr)
{
if(from_nodes.size() == 0)
return;
@@ -378,7 +379,7 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
u8 oldlight = j.getNode()->getValue();
- unspreadLight(bank, pos, oldlight, light_sources);
+ unspreadLight(bank, pos, oldlight, light_sources, nodemgr);
}
}
#endif
@@ -448,18 +449,18 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node)
*/
- if(n2.getLight(bank) < oldlight)
+ if(n2.getLight(bank, nodemgr) < oldlight)
{
/*
And the neighbor is transparent and it has some light
*/
- if(n2.light_propagates() && n2.getLight(bank) != 0)
+ if(nodemgr->get(n2).light_propagates && n2.getLight(bank, nodemgr) != 0)
{
/*
Set light to 0 and add to queue
*/
- u8 current_light = n2.getLight(bank);
+ u8 current_light = n2.getLight(bank, nodemgr);
n2.setLight(bank, 0);
unlighted_nodes.insert(n2pos, current_light);
@@ -491,7 +492,8 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
}
#endif
-void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
+void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p,
+ INodeDefManager *nodemgr)
{
const v3s16 dirs[6] = {
v3s16(0,0,1), // back
@@ -511,7 +513,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
MapNode &n = m_data[i];
- u8 oldlight = n.getLight(bank);
+ u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors
@@ -531,20 +533,20 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn)
*/
- if(n2.getLight(bank) > undiminish_light(oldlight))
+ if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
{
- spreadLight(bank, n2pos);
+ spreadLight(bank, n2pos, nodemgr);
}
/*
If the neighbor is dimmer than how much light this node
would spread on it, add to list
*/
- if(n2.getLight(bank) < newlight)
+ if(n2.getLight(bank, nodemgr) < newlight)
{
- if(n2.light_propagates())
+ if(nodemgr->get(n2).light_propagates)
{
- n2.setLight(bank, newlight);
- spreadLight(bank, n2pos);
+ n2.setLight(bank, newlight, nodemgr);
+ spreadLight(bank, n2pos, nodemgr);
}
}
}
@@ -583,7 +585,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
goes on recursively.
*/
void VoxelManipulator::spreadLight(enum LightBank bank,
- core::map<v3s16, bool> & from_nodes)
+ core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr)
{
const v3s16 dirs[6] = {
v3s16(0,0,1), // back
@@ -614,7 +616,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
MapNode &n = m_data[i];
- u8 oldlight = n.getLight(bank);
+ u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors
@@ -636,7 +638,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn)
*/
- if(n2.getLight(bank) > undiminish_light(oldlight))
+ if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
{
lighted_nodes.insert(n2pos, true);
}
@@ -644,11 +646,11 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
If the neighbor is dimmer than how much light this node
would spread on it, add to list
*/
- if(n2.getLight(bank) < newlight)
+ if(n2.getLight(bank, nodemgr) < newlight)
{
- if(n2.light_propagates())
+ if(nodemgr->get(n2).light_propagates)
{
- n2.setLight(bank, newlight);
+ n2.setLight(bank, newlight, nodemgr);
lighted_nodes.insert(n2pos, true);
}
}
@@ -666,7 +668,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
<<std::endl;*/
if(lighted_nodes.size() > 0)
- spreadLight(bank, lighted_nodes);
+ spreadLight(bank, lighted_nodes, nodemgr);
}
#endif
diff --git a/src/voxel.h b/src/voxel.h
index 51df18299..46864e06e 100644
--- a/src/voxel.h
+++ b/src/voxel.h
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h"
#include "mapnode.h"
+class INodeDefManager;
+
// For VC++
#undef min
#undef max
@@ -475,7 +477,8 @@ public:
virtual void clear();
- void print(std::ostream &o, VoxelPrintMode mode=VOXELPRINT_MATERIAL);
+ void print(std::ostream &o, INodeDefManager *nodemgr,
+ VoxelPrintMode mode=VOXELPRINT_MATERIAL);
void addArea(VoxelArea area);
@@ -497,14 +500,14 @@ public:
void clearFlag(u8 flag);
void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
- core::map<v3s16, bool> & light_sources);
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
void unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes,
- core::map<v3s16, bool> & light_sources);
+ core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
- void spreadLight(enum LightBank bank, v3s16 p);
+ void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
void spreadLight(enum LightBank bank,
- core::map<v3s16, bool> & from_nodes);
+ core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr);
/*
Virtual functions