GameDef compiles

This commit is contained in:
Perttu Ahola 2011-11-14 21:41:30 +02:00
parent abceeee92f
commit c6fd2986d4
49 changed files with 1168 additions and 1045 deletions

View File

@ -95,8 +95,8 @@ configure_file(
set(common_SRCS set(common_SRCS
content_tool.cpp content_tool.cpp
tool.cpp tooldef.cpp
mapnode_contentfeatures.cpp nodedef.cpp
luaentity_common.cpp luaentity_common.cpp
scriptapi.cpp scriptapi.cpp
script.cpp script.cpp

View File

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cmath> #include <cmath>
#include <SAnimatedMesh.h> #include <SAnimatedMesh.h>
#include "settings.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): Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr), m_smgr(smgr),
@ -449,8 +449,11 @@ void Camera::updateSettings()
m_wanted_frametime = 1.0 / wanted_fps; 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) if (item != NULL)
{ {
bool isCube = false; bool isCube = false;
@ -461,9 +464,9 @@ void Camera::wield(const InventoryItem* item, ITextureSource *tsrc)
// A block-type material // A block-type material
MaterialItem* mat_item = (MaterialItem*) item; MaterialItem* mat_item = (MaterialItem*) item;
content_t content = mat_item->getMaterial(); 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)); m_wieldnode->setScale(v3f(30));
isCube = true; isCube = true;
} }

View File

@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class LocalPlayer; class LocalPlayer;
class MapDrawControl; class MapDrawControl;
class ExtrudedSpriteSceneNode; class ExtrudedSpriteSceneNode;
class ITextureSource; class IGameDef;
/* /*
Client camera class, manages the player and camera scene nodes, the viewing distance Client camera class, manages the player and camera scene nodes, the viewing distance
@ -116,7 +116,7 @@ public:
void updateSettings(); void updateSettings();
// Replace the wielded item mesh // Replace the wielded item mesh
void wield(const InventoryItem* item, ITextureSource *tsrc); void wield(const InventoryItem* item, IGameDef *gamedef);
// Start digging animation // Start digging animation
// Pass 0 for left click, 1 for right click // Pass 0 for left click, 1 for right click

View File

@ -32,6 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h" #include "profiler.h"
#include "log.h" #include "log.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "nodedef.h"
#include "tooldef.h"
/* /*
QueuedMeshUpdate QueuedMeshUpdate
@ -160,7 +162,7 @@ void * MeshUpdateThread::Thread()
ScopeProfiler sp(g_profiler, "Client: Mesh making"); ScopeProfiler sp(g_profiler, "Client: Mesh making");
scene::SMesh *mesh_new = NULL; scene::SMesh *mesh_new = NULL;
mesh_new = makeMapBlockMesh(q->data, m_tsrc); mesh_new = makeMapBlockMesh(q->data, m_gamedef);
MeshUpdateResult r; MeshUpdateResult r;
r.p = q->p; r.p = q->p;
@ -186,11 +188,14 @@ Client::Client(
const char *playername, const char *playername,
std::string password, std::string password,
MapDrawControl &control, MapDrawControl &control,
ITextureSource *tsrc, IWritableTextureSource *tsrc,
IToolDefManager *toolmgr): IWritableToolDefManager *tooldef,
IWritableNodeDefManager *nodedef
):
m_tsrc(tsrc), m_tsrc(tsrc),
m_toolmgr(toolmgr), m_tooldef(tooldef),
m_mesh_update_thread(tsrc), m_nodedef(nodedef),
m_mesh_update_thread(this),
m_env( m_env(
new ClientMap(this, this, control, new ClientMap(this, this, control,
device->getSceneManager()->getRootSceneNode(), device->getSceneManager()->getRootSceneNode(),
@ -214,18 +219,22 @@ Client::Client(
m_playerpos_send_timer = 0.0; m_playerpos_send_timer = 0.0;
m_ignore_damage_timer = 0.0; m_ignore_damage_timer = 0.0;
//m_env_mutex.Init(); // Build main texture atlas, now that the GameDef exists (that is, us)
//m_con_mutex.Init(); 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(); m_mesh_update_thread.Start();
/* /*
Add local player Add local player
*/ */
{ {
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out Player *player = new LocalPlayer(this);
Player *player = new LocalPlayer();
player->updateName(playername); player->updateName(playername);
@ -827,7 +836,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
//TimeTaker t1("TOCLIENT_ADDNODE"); //TimeTaker t1("TOCLIENT_ADDNODE");
MapNode n; MapNode n;
n.deSerialize(&data[8], ser_version); n.deSerialize(&data[8], ser_version, m_nodedef);
addNode(p, n); addNode(p, n);
} }
@ -868,7 +877,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
Update an existing block Update an existing block
*/ */
//infostream<<"Updating"<<std::endl; //infostream<<"Updating"<<std::endl;
block->deSerialize(istr, ser_version, this); block->deSerialize(istr, ser_version);
} }
else else
{ {
@ -876,8 +885,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
Create a new block Create a new block
*/ */
//infostream<<"Creating new"<<std::endl; //infostream<<"Creating new"<<std::endl;
block = new MapBlock(&m_env.getMap(), p); block = new MapBlock(&m_env.getMap(), p, this);
block->deSerialize(istr, ser_version, this); block->deSerialize(istr, ser_version);
sector->insertBlock(block); sector->insertBlock(block);
//DEBUG //DEBUG
@ -1041,7 +1050,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
// Create a player if it doesn't exist // Create a player if it doesn't exist
if(player == NULL) if(player == NULL)
{ {
player = new RemotePlayer( player = new RemotePlayer(this,
m_device->getSceneManager()->getRootSceneNode(), m_device->getSceneManager()->getRootSceneNode(),
m_device, m_device,
-1); -1);
@ -2047,7 +2056,7 @@ void Client::setTempMod(v3s16 p, NodeMod mod)
i = affected_blocks.getIterator(); i = affected_blocks.getIterator();
i.atEnd() == false; i++) 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 = affected_blocks.getIterator();
i.atEnd() == false; i++) 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;
}

View File

@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h" #include "gamedef.h"
struct MeshMakeData; struct MeshMakeData;
class IGameDef;
class IWritableToolDefManager;
class IWritableNodeDefManager;
class ClientNotReadyException : public BaseException class ClientNotReadyException : public BaseException
{ {
@ -99,8 +102,8 @@ class MeshUpdateThread : public SimpleThread
{ {
public: public:
MeshUpdateThread(ITextureSource *tsrc): MeshUpdateThread(IGameDef *gamedef):
m_tsrc(tsrc) m_gamedef(gamedef)
{ {
} }
@ -110,7 +113,7 @@ public:
MutexedQueue<MeshUpdateResult> m_queue_out; MutexedQueue<MeshUpdateResult> m_queue_out;
ITextureSource *m_tsrc; IGameDef *m_gamedef;
}; };
enum ClientEventType enum ClientEventType
@ -155,8 +158,9 @@ public:
const char *playername, const char *playername,
std::string password, std::string password,
MapDrawControl &control, MapDrawControl &control,
ITextureSource *tsrc, IWritableTextureSource *tsrc,
IToolDefManager *toolmgr IWritableToolDefManager *tooldef,
IWritableNodeDefManager *nodedef
); );
~Client(); ~Client();
@ -311,10 +315,9 @@ public:
// IGameDef interface // IGameDef interface
// Under envlock // Under envlock
virtual IToolDefManager* getToolDefManager() virtual IToolDefManager* getToolDefManager();
{ return m_toolmgr; } virtual INodeDefManager* getNodeDefManager();
virtual INodeDefManager* getNodeDefManager() virtual ITextureSource* getTextureSource();
{ assert(0); return NULL; } // TODO
private: private:
@ -338,8 +341,9 @@ private:
float m_ignore_damage_timer; // Used after server moves player float m_ignore_damage_timer; // Used after server moves player
IntervalLimiter m_map_timer_and_unload_interval; IntervalLimiter m_map_timer_and_unload_interval;
ITextureSource *m_tsrc; IWritableTextureSource *m_tsrc;
IToolDefManager *m_toolmgr; IWritableToolDefManager *m_tooldef;
IWritableNodeDefManager *m_nodedef;
MeshUpdateThread m_mesh_update_thread; MeshUpdateThread m_mesh_update_thread;
ClientEnvironment m_env; ClientEnvironment m_env;
con::Connection m_con; con::Connection m_con;

View File

@ -20,10 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "collision.h" #include "collision.h"
#include "mapblock.h" #include "mapblock.h"
#include "map.h" #include "map.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "gamedef.h"
collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d, collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
const core::aabbox3d<f32> &box_0, f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f) f32 dtime, v3f &pos_f, v3f &speed_f)
{ {
collisionMoveResult result; collisionMoveResult result;
@ -80,7 +81,7 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
try{ try{
// Object collides into walkable nodes // Object collides into walkable nodes
MapNode n = map->getNode(v3s16(x,y,z)); MapNode n = map->getNode(v3s16(x,y,z));
if(content_features(n).walkable == false) if(gamedef->getNodeDefManager()->get(n).walkable == false)
continue; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -184,8 +185,8 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
return result; return result;
} }
collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d, collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
const core::aabbox3d<f32> &box_0, f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f) f32 dtime, v3f &pos_f, v3f &speed_f)
{ {
collisionMoveResult final_result; collisionMoveResult final_result;
@ -226,8 +227,8 @@ collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
dtime_downcount = 0; dtime_downcount = 0;
} }
collisionMoveResult result = collisionMoveSimple(map, pos_max_d, collisionMoveResult result = collisionMoveSimple(map, gamedef,
box_0, dtime_part, pos_f, speed_f); pos_max_d, box_0, dtime_part, pos_f, speed_f);
if(result.touching_ground) if(result.touching_ground)
final_result.touching_ground = true; final_result.touching_ground = true;

View File

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" #include "common_irrlicht.h"
class Map; class Map;
class IGameDef;
struct collisionMoveResult struct collisionMoveResult
{ {
@ -34,13 +35,13 @@ struct collisionMoveResult
}; };
// Moves using a single iteration; speed should not exceed pos_max_d/dtime // Moves using a single iteration; speed should not exceed pos_max_d/dtime
collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d, collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
const core::aabbox3d<f32> &box_0, f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f); f32 dtime, v3f &pos_f, v3f &speed_f);
// Moves using as many iterations as needed // Moves using as many iterations as needed
collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d, collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
const core::aabbox3d<f32> &box_0, f32 pos_max_d, const core::aabbox3d<f32> &box_0,
f32 dtime, v3f &pos_f, v3f &speed_f); f32 dtime, v3f &pos_f, v3f &speed_f);
enum CollisionType enum CollisionType

View File

@ -23,7 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mineral.h" #include "mineral.h"
#include "mapblock_mesh.h" // For MapBlock_LightColor() #include "mapblock_mesh.h" // For MapBlock_LightColor()
#include "settings.h" #include "settings.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "gamedef.h"
#ifndef SERVER #ifndef SERVER
// Create a cuboid. // Create a cuboid.
@ -122,8 +123,11 @@ void makeCuboid(video::SMaterial &material, MeshCollector *collector,
#ifndef SERVER #ifndef SERVER
void mapblock_mesh_generate_special(MeshMakeData *data, void mapblock_mesh_generate_special(MeshMakeData *data,
MeshCollector &collector, ITextureSource *tsrc) MeshCollector &collector, IGameDef *gamedef)
{ {
ITextureSource *tsrc = gamedef->tsrc();
INodeDefManager *nodedef = gamedef->ndef();
// 0ms // 0ms
//TimeTaker timer("mapblock_mesh_generate_special()"); //TimeTaker timer("mapblock_mesh_generate_special()");
@ -316,7 +320,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0, ap.atlas); 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); video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16; float d = (float)BS/16;
@ -360,34 +364,34 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
/* /*
Add flowing liquid to mesh 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 = video::SMaterial &liquid_material =
*content_features(n).special_material; *nodedef->get(n).special_material;
video::SMaterial &liquid_material_bfculled = 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 = AtlasPointer &pa_liquid1 =
*content_features(n).special_atlas; *nodedef->get(n).special_atlas;
bool top_is_same_liquid = false; bool top_is_same_liquid = false;
MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); 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_flowing = nodedef->get(n).liquid_alternative_flowing;
content_t c_source = content_features(n).liquid_alternative_source; content_t c_source = nodedef->get(n).liquid_alternative_source;
if(ntop.getContent() == c_flowing || ntop.getContent() == c_source) if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
top_is_same_liquid = true; top_is_same_liquid = true;
u8 l = 0; u8 l = 0;
// Use the light of the node on top if possible // Use the light of the node on top if possible
if(content_features(ntop).param_type == CPT_LIGHT) if(nodedef->get(ntop).param_type == CPT_LIGHT)
l = decode_light(ntop.getLightBlend(data->m_daynight_ratio)); l = decode_light(ntop.getLightBlend(data->m_daynight_ratio, nodedef));
// Otherwise use the light of this node (the liquid) // Otherwise use the light of this node (the liquid)
else 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( video::SColor c = MapBlock_LightColor(
content_features(n).vertex_alpha, l); nodedef->get(n).vertex_alpha, l);
// Neighbor liquid levels (key = relative position) // Neighbor liquid levels (key = relative position)
// Includes current node // Includes current node
@ -520,7 +524,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
continue; continue;
content_t neighbor_content = neighbor_contents[dir]; 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 // Don't draw face if neighbor is blocking the view
if(n_feat.solidness == 2) 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 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) && new_style_water)
{ {
assert(content_features(n).special_material); assert(nodedef->get(n).special_material);
video::SMaterial &liquid_material = video::SMaterial &liquid_material =
*content_features(n).special_material; *nodedef->get(n).special_material;
assert(content_features(n).special_atlas); assert(nodedef->get(n).special_atlas);
AtlasPointer &pa_liquid1 = AtlasPointer &pa_liquid1 =
*content_features(n).special_atlas; *nodedef->get(n).special_atlas;
bool top_is_air = false; bool top_is_air = false;
MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); 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) if(top_is_air == false)
continue; 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( video::SColor c = MapBlock_LightColor(
content_features(n).vertex_alpha, l); nodedef->get(n).vertex_alpha, l);
video::S3DVertex vertices[4] = video::S3DVertex vertices[4] =
{ {
@ -703,8 +707,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/ */
else if(n.getContent() == CONTENT_LEAVES && new_style_leaves) else if(n.getContent() == CONTENT_LEAVES && new_style_leaves)
{ {
/*u8 l = decode_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))); u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
video::SColor c = MapBlock_LightColor(255, l); video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++) for(u32 j=0; j<6; j++)
@ -767,7 +771,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/ */
else if(n.getContent() == CONTENT_GLASS) 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); video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<6; j++) for(u32 j=0; j<6; j++)
@ -830,7 +834,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
*/ */
else if(n.getContent() == CONTENT_FENCE) 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); video::SColor c = MapBlock_LightColor(255, l);
const f32 post_rad=(f32)BS/10; 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 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++) for(u32 j=0; j<6; j++)
{ {
@ -915,15 +919,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
v3s16 dir = g_6dirs[j]; v3s16 dir = g_6dirs[j];
/*u8 l = 0; /*u8 l = 0;
MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir); MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir);
if(content_features(n2).param_type == CPT_LIGHT) if(nodedef->get(n2).param_type == CPT_LIGHT)
l = decode_light(n2.getLightBlend(data->m_daynight_ratio)); l = decode_light(n2.getLightBlend(data->m_daynight_ratio, nodedef));
else else
l = 255;*/ l = 255;*/
u8 l = 255; u8 l = 255;
video::SColor c = MapBlock_LightColor(255, l); video::SColor c = MapBlock_LightColor(255, l);
// Get the right texture // Get the right texture
TileSpec ts = n.getTile(dir, tsrc); TileSpec ts = n.getTile(dir, tsrc, nodedef);
AtlasPointer ap = ts.texture; AtlasPointer ap = ts.texture;
material_general.setTexture(0, ap.atlas); material_general.setTexture(0, ap.atlas);
@ -974,7 +978,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
#endif #endif
else if(n.getContent() == CONTENT_PAPYRUS) 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); video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++) for(u32 j=0; j<4; j++)
@ -1024,7 +1028,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
} }
else if(n.getContent() == CONTENT_JUNGLEGRASS) 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); video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++) for(u32 j=0; j<4; j++)
@ -1121,7 +1125,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_rail.setTexture(0, ap.atlas); 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); video::SColor c = MapBlock_LightColor(255, l);
float d = (float)BS/16; 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.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material_ladder.setTexture(0, ap.atlas); 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); video::SColor c(255,l,l,l);
float d = (float)BS/16; float d = (float)BS/16;
@ -1237,7 +1241,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
} }
else if(n.getContent() == CONTENT_APPLE) 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); video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++) for(u32 j=0; j<4; j++)
@ -1286,7 +1290,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
} }
} }
else if(n.getContent() == CONTENT_SAPLING) { 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); video::SColor c = MapBlock_LightColor(255, l);
for(u32 j=0; j<4; j++) for(u32 j=0; j<4; j++)

View File

@ -23,9 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef SERVER #ifndef SERVER
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
#include "utility.h" #include "utility.h"
class ITextureSource; class IGameDef;
void mapblock_mesh_generate_special(MeshMakeData *data, void mapblock_mesh_generate_special(MeshMakeData *data,
MeshCollector &collector, ITextureSource *tsrc); MeshCollector &collector, IGameDef *gamedef);
#endif #endif
#endif #endif

View File

@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h" #include "mapnode.h"
#include "content_nodemeta.h" #include "content_nodemeta.h"
#include "settings.h" #include "settings.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#define WATER_ALPHA 160 #define WATER_ALPHA 160
@ -156,7 +156,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
} }
// See header for description // See header for description
void content_mapnode_init(ITextureSource *tsrc) void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr)
{ {
if(tsrc == NULL) if(tsrc == NULL)
dstream<<"INFO: Initial run of content_mapnode_init with " dstream<<"INFO: Initial run of content_mapnode_init with "
@ -177,7 +177,7 @@ void content_mapnode_init(ITextureSource *tsrc)
ContentFeatures *f = NULL; ContentFeatures *f = NULL;
i = CONTENT_STONE; i = CONTENT_STONE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "stone.png"); f->setAllTextures(tsrc, "stone.png");
f->setInventoryTextureCube("stone.png", "stone.png", "stone.png", tsrc); f->setInventoryTextureCube("stone.png", "stone.png", "stone.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -189,7 +189,7 @@ void content_mapnode_init(ITextureSource *tsrc)
f->solidness = 0; // For debugging, hides regular stone f->solidness = 0; // For debugging, hides regular stone
i = CONTENT_GRASS; i = CONTENT_GRASS;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png^grass_side.png"); f->setAllTextures(tsrc, "mud.png^grass_side.png");
f->setTexture(tsrc, 0, "grass.png"); f->setTexture(tsrc, 0, "grass.png");
f->setTexture(tsrc, 1, "mud.png"); f->setTexture(tsrc, 1, "mud.png");
@ -199,7 +199,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0); setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_GRASS_FOOTSTEPS; i = CONTENT_GRASS_FOOTSTEPS;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png^grass_side.png"); f->setAllTextures(tsrc, "mud.png^grass_side.png");
f->setTexture(tsrc, 0, "grass_footsteps.png"); f->setTexture(tsrc, 0, "grass_footsteps.png");
f->setTexture(tsrc, 1, "mud.png"); f->setTexture(tsrc, 1, "mud.png");
@ -209,7 +209,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0); setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_MUD; i = CONTENT_MUD;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mud.png"); f->setAllTextures(tsrc, "mud.png");
f->setInventoryTextureCube("mud.png", "mud.png", "mud.png", tsrc); f->setInventoryTextureCube("mud.png", "mud.png", "mud.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -218,7 +218,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0); setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_SAND; i = CONTENT_SAND;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "sand.png"); f->setAllTextures(tsrc, "sand.png");
f->setInventoryTextureCube("sand.png", "sand.png", "sand.png", tsrc); f->setInventoryTextureCube("sand.png", "sand.png", "sand.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -227,7 +227,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0); setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_GRAVEL; i = CONTENT_GRAVEL;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "gravel.png"); f->setAllTextures(tsrc, "gravel.png");
f->setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png", tsrc); f->setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -236,7 +236,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setGravelLikeMaterialProperties(f->material, 1.0); setGravelLikeMaterialProperties(f->material, 1.0);
i = CONTENT_SANDSTONE; i = CONTENT_SANDSTONE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "sandstone.png"); f->setAllTextures(tsrc, "sandstone.png");
f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png", tsrc); f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -245,7 +245,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0); setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_CLAY; i = CONTENT_CLAY;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "clay.png"); f->setAllTextures(tsrc, "clay.png");
f->setInventoryTextureCube("clay.png", "clay.png", "clay.png", tsrc); f->setInventoryTextureCube("clay.png", "clay.png", "clay.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -254,7 +254,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 1.0); setDirtLikeMaterialProperties(f->material, 1.0);
i = CONTENT_BRICK; i = CONTENT_BRICK;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "brick.png"); f->setAllTextures(tsrc, "brick.png");
f->setInventoryTextureCube("brick.png", "brick.png", "brick.png", tsrc); f->setInventoryTextureCube("brick.png", "brick.png", "brick.png", tsrc);
f->param_type = CPT_MINERAL; f->param_type = CPT_MINERAL;
@ -263,7 +263,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 1.0); setStoneLikeMaterialProperties(f->material, 1.0);
i = CONTENT_TREE; i = CONTENT_TREE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "tree.png"); f->setAllTextures(tsrc, "tree.png");
f->setTexture(tsrc, 0, "tree_top.png"); f->setTexture(tsrc, 0, "tree_top.png");
f->setTexture(tsrc, 1, "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); setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_JUNGLETREE; i = CONTENT_JUNGLETREE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "jungletree.png"); f->setAllTextures(tsrc, "jungletree.png");
f->setTexture(tsrc, 0, "jungletree_top.png"); f->setTexture(tsrc, 0, "jungletree_top.png");
f->setTexture(tsrc, 1, "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); setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_JUNGLEGRASS; i = CONTENT_JUNGLEGRASS;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("junglegrass.png", tsrc); 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->light_propagates = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
//f->is_ground_content = true; //f->is_ground_content = true;
@ -296,7 +296,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setLeavesLikeMaterialProperties(f->material, 1.0); setLeavesLikeMaterialProperties(f->material, 1.0);
i = CONTENT_LEAVES; i = CONTENT_LEAVES;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->light_propagates = true; f->light_propagates = true;
//f->param_type = CPT_MINERAL; //f->param_type = CPT_MINERAL;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
@ -318,7 +318,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setLeavesLikeMaterialProperties(f->material, 1.0); setLeavesLikeMaterialProperties(f->material, 1.0);
i = CONTENT_CACTUS; i = CONTENT_CACTUS;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cactus_side.png"); f->setAllTextures(tsrc, "cactus_side.png");
f->setTexture(tsrc, 0, "cactus_top.png"); f->setTexture(tsrc, 0, "cactus_top.png");
f->setTexture(tsrc, 1, "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); setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_PAPYRUS; i = CONTENT_PAPYRUS;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("papyrus.png", tsrc); 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->light_propagates = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->is_ground_content = true; f->is_ground_content = true;
@ -341,7 +341,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setLeavesLikeMaterialProperties(f->material, 0.5); setLeavesLikeMaterialProperties(f->material, 0.5);
i = CONTENT_BOOKSHELF; i = CONTENT_BOOKSHELF;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "bookshelf.png"); f->setAllTextures(tsrc, "bookshelf.png");
f->setTexture(tsrc, 0, "wood.png"); f->setTexture(tsrc, 0, "wood.png");
f->setTexture(tsrc, 1, "wood.png"); f->setTexture(tsrc, 1, "wood.png");
@ -353,7 +353,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 0.75); setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_GLASS; i = CONTENT_GLASS;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->light_propagates = true; f->light_propagates = true;
f->sunlight_propagates = true; f->sunlight_propagates = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
@ -366,7 +366,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setGlassLikeMaterialProperties(f->material, 1.0); setGlassLikeMaterialProperties(f->material, 1.0);
i = CONTENT_FENCE; i = CONTENT_FENCE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->light_propagates = true; f->light_propagates = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->is_ground_content = true; f->is_ground_content = true;
@ -374,13 +374,13 @@ void content_mapnode_init(ITextureSource *tsrc)
f->solidness = 0; // drawn separately, makes no faces f->solidness = 0; // drawn separately, makes no faces
f->air_equivalent = true; // grass grows underneath f->air_equivalent = true; // grass grows underneath
f->setInventoryTexture("fence.png", tsrc); 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); setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_RAIL; i = CONTENT_RAIL;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("rail.png", tsrc); 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->light_propagates = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->is_ground_content = true; f->is_ground_content = true;
@ -392,9 +392,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setDirtLikeMaterialProperties(f->material, 0.75); setDirtLikeMaterialProperties(f->material, 0.75);
i = CONTENT_LADDER; i = CONTENT_LADDER;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("ladder.png", tsrc); 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->light_propagates = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->is_ground_content = true; f->is_ground_content = true;
@ -409,13 +409,13 @@ void content_mapnode_init(ITextureSource *tsrc)
// Deprecated // Deprecated
i = CONTENT_COALSTONE; i = CONTENT_COALSTONE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "stone.png^mineral_coal.png"); f->setAllTextures(tsrc, "stone.png^mineral_coal.png");
f->is_ground_content = true; f->is_ground_content = true;
setStoneLikeMaterialProperties(f->material, 1.5); setStoneLikeMaterialProperties(f->material, 1.5);
i = CONTENT_WOOD; i = CONTENT_WOOD;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "wood.png"); f->setAllTextures(tsrc, "wood.png");
f->setInventoryTextureCube("wood.png", "wood.png", "wood.png", tsrc); f->setInventoryTextureCube("wood.png", "wood.png", "wood.png", tsrc);
f->is_ground_content = true; f->is_ground_content = true;
@ -423,7 +423,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 0.75); setWoodLikeMaterialProperties(f->material, 0.75);
i = CONTENT_MESE; i = CONTENT_MESE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mese.png"); f->setAllTextures(tsrc, "mese.png");
f->setInventoryTextureCube("mese.png", "mese.png", "mese.png", tsrc); f->setInventoryTextureCube("mese.png", "mese.png", "mese.png", tsrc);
f->is_ground_content = true; f->is_ground_content = true;
@ -431,14 +431,14 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 0.5); setStoneLikeMaterialProperties(f->material, 0.5);
i = CONTENT_CLOUD; i = CONTENT_CLOUD;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cloud.png"); f->setAllTextures(tsrc, "cloud.png");
f->setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png", tsrc); f->setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png", tsrc);
f->is_ground_content = true; f->is_ground_content = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
i = CONTENT_AIR; i = CONTENT_AIR;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->light_propagates = true; f->light_propagates = true;
f->sunlight_propagates = true; f->sunlight_propagates = true;
@ -450,7 +450,7 @@ void content_mapnode_init(ITextureSource *tsrc)
f->air_equivalent = true; f->air_equivalent = true;
i = CONTENT_WATER; i = CONTENT_WATER;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc); f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->light_propagates = true; f->light_propagates = true;
@ -492,7 +492,7 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif #endif
i = CONTENT_WATERSOURCE; i = CONTENT_WATERSOURCE;
f = &content_features(i); f = nodemgr->getModifiable(i);
//f->setInventoryTexture("water.png", tsrc); //f->setInventoryTexture("water.png", tsrc);
f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc); f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
if(new_style_water) if(new_style_water)
@ -547,9 +547,9 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif #endif
i = CONTENT_LAVA; i = CONTENT_LAVA;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc); 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->param_type = CPT_LIGHT;
f->light_propagates = false; f->light_propagates = false;
f->light_source = LIGHT_MAX-1; f->light_source = LIGHT_MAX-1;
@ -591,9 +591,9 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif #endif
i = CONTENT_LAVASOURCE; i = CONTENT_LAVASOURCE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc); 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) if(new_style_water)
{ {
f->solidness = 0; // drawn separately, makes no faces f->solidness = 0; // drawn separately, makes no faces
@ -646,12 +646,11 @@ void content_mapnode_init(ITextureSource *tsrc)
#endif #endif
i = CONTENT_TORCH; i = CONTENT_TORCH;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("torch_on_floor.png", tsrc); f->setInventoryTexture("torch_on_floor.png", tsrc);
f->used_texturenames["torch_on_floor.png"] = true; f->used_texturenames.insert("torch_on_floor.png"); // Add to atlas
f->used_texturenames["torch_on_ceiling.png"] = true; f->used_texturenames.insert("torch_on_ceiling.png"); // Add to atlas
f->used_texturenames["torch_on_floor.png"] = true; f->used_texturenames.insert("torch.png"); // Add to atlas
f->used_texturenames["torch.png"] = true;
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->light_propagates = true; f->light_propagates = true;
f->sunlight_propagates = true; f->sunlight_propagates = true;
@ -671,9 +670,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setConstantMaterialProperties(f->material, 0.0); setConstantMaterialProperties(f->material, 0.0);
i = CONTENT_SIGN_WALL; i = CONTENT_SIGN_WALL;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("sign_wall.png", tsrc); 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->param_type = CPT_LIGHT;
f->light_propagates = true; f->light_propagates = true;
f->sunlight_propagates = true; f->sunlight_propagates = true;
@ -688,7 +687,7 @@ void content_mapnode_init(ITextureSource *tsrc)
f->selection_box.type = NODEBOX_WALLMOUNTED; f->selection_box.type = NODEBOX_WALLMOUNTED;
i = CONTENT_CHEST; i = CONTENT_CHEST;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE; f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "chest_side.png"); f->setAllTextures(tsrc, "chest_side.png");
f->setTexture(tsrc, 0, "chest_top.png"); f->setTexture(tsrc, 0, "chest_top.png");
@ -702,7 +701,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 1.0); setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_LOCKABLE_CHEST; i = CONTENT_LOCKABLE_CHEST;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE; f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "chest_side.png"); f->setAllTextures(tsrc, "chest_side.png");
f->setTexture(tsrc, 0, "chest_top.png"); f->setTexture(tsrc, 0, "chest_top.png");
@ -716,7 +715,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setWoodLikeMaterialProperties(f->material, 1.0); setWoodLikeMaterialProperties(f->material, 1.0);
i = CONTENT_FURNACE; i = CONTENT_FURNACE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE; f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "furnace_side.png"); f->setAllTextures(tsrc, "furnace_side.png");
f->setTexture(tsrc, 5, "furnace_front.png"); // Z- f->setTexture(tsrc, 5, "furnace_front.png"); // Z-
@ -728,7 +727,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 3.0); setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_COBBLE; i = CONTENT_COBBLE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "cobble.png"); f->setAllTextures(tsrc, "cobble.png");
f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png", tsrc); f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png", tsrc);
f->param_type = CPT_NONE; f->param_type = CPT_NONE;
@ -737,7 +736,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 0.9); setStoneLikeMaterialProperties(f->material, 0.9);
i = CONTENT_MOSSYCOBBLE; i = CONTENT_MOSSYCOBBLE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "mossycobble.png"); f->setAllTextures(tsrc, "mossycobble.png");
f->setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png", tsrc); f->setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png", tsrc);
f->param_type = CPT_NONE; f->param_type = CPT_NONE;
@ -746,7 +745,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 0.8); setStoneLikeMaterialProperties(f->material, 0.8);
i = CONTENT_STEEL; i = CONTENT_STEEL;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "steel_block.png"); f->setAllTextures(tsrc, "steel_block.png");
f->setInventoryTextureCube("steel_block.png", "steel_block.png", f->setInventoryTextureCube("steel_block.png", "steel_block.png",
"steel_block.png", tsrc); "steel_block.png", tsrc);
@ -756,7 +755,7 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 5.0); setStoneLikeMaterialProperties(f->material, 5.0);
i = CONTENT_NC; i = CONTENT_NC;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->param_type = CPT_FACEDIR_SIMPLE; f->param_type = CPT_FACEDIR_SIMPLE;
f->setAllTextures(tsrc, "nc_side.png"); f->setAllTextures(tsrc, "nc_side.png");
f->setTexture(tsrc, 5, "nc_front.png"); // Z- f->setTexture(tsrc, 5, "nc_front.png"); // Z-
@ -766,18 +765,18 @@ void content_mapnode_init(ITextureSource *tsrc)
setStoneLikeMaterialProperties(f->material, 3.0); setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_NC_RB; i = CONTENT_NC_RB;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setAllTextures(tsrc, "nc_rb.png"); f->setAllTextures(tsrc, "nc_rb.png");
f->setInventoryTexture("nc_rb.png", tsrc); f->setInventoryTexture("nc_rb.png", tsrc);
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
setStoneLikeMaterialProperties(f->material, 3.0); setStoneLikeMaterialProperties(f->material, 3.0);
i = CONTENT_SAPLING; i = CONTENT_SAPLING;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->param_type = CPT_LIGHT; f->param_type = CPT_LIGHT;
f->setAllTextures(tsrc, "sapling.png"); f->setAllTextures(tsrc, "sapling.png");
f->setInventoryTexture("sapling.png", tsrc); 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->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->light_propagates = true; f->light_propagates = true;
f->air_equivalent = false; f->air_equivalent = false;
@ -786,9 +785,9 @@ void content_mapnode_init(ITextureSource *tsrc)
setConstantMaterialProperties(f->material, 0.0); setConstantMaterialProperties(f->material, 0.0);
i = CONTENT_APPLE; i = CONTENT_APPLE;
f = &content_features(i); f = nodemgr->getModifiable(i);
f->setInventoryTexture("apple.png", tsrc); 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->param_type = CPT_LIGHT;
f->light_propagates = true; f->light_propagates = true;
f->sunlight_propagates = true; f->sunlight_propagates = true;

View File

@ -22,9 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapnode.h" #include "mapnode.h"
class ITextureSource; 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 This accesses tsrc; if it is non-NULL, textures are set
for the nodes. for the nodes.
@ -35,7 +36,7 @@ class ITextureSource;
Server only calls this once with tsrc=NULL. 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 // Backwards compatibility for non-extended content types in v19
extern content_t trans_table_19[21][2]; extern content_t trans_table_19[21][2];

View File

@ -159,8 +159,9 @@ void ItemSAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition(); v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f; v3f pos_f_old = pos_f;
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d, IGameDef *gamedef = m_env->getGameDef();
box, dtime, pos_f, m_speed_f); moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, pos_f, m_speed_f);
if(send_recommended == false) if(send_recommended == false)
return; return;
@ -402,8 +403,9 @@ void RatSAO::step(float dtime, bool send_recommended)
m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime); m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition(); v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f; v3f pos_f_old = pos_f;
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d, IGameDef *gamedef = m_env->getGameDef();
box, dtime, pos_f, m_speed_f); moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground; m_touching_ground = moveresult.touching_ground;
setBasePosition(pos_f); 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);*/ m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/
v3f pos_f = getBasePosition(); v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f; v3f pos_f_old = pos_f;
moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d, IGameDef *gamedef = m_env->getGameDef();
box, dtime, pos_f, m_speed_f); moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground; m_touching_ground = moveresult.touching_ground;
// Do collision damage // 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); m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
v3f pos_f = getBasePosition(); v3f pos_f = getBasePosition();
v3f pos_f_old = pos_f; v3f pos_f_old = pos_f;
moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d, IGameDef *gamedef = m_env->getGameDef();
box, dtime, pos_f, m_speed_f); moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, pos_f, m_speed_f);
m_touching_ground = moveresult.touching_ground; m_touching_ground = moveresult.touching_ground;
setBasePosition(pos_f); setBasePosition(pos_f);

View File

@ -18,9 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "content_tool.h" #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", mgr->registerTool("WPick",
ToolDefinition("tool_woodpick.png", ToolDefinition("tool_woodpick.png",
@ -62,7 +62,7 @@ void content_tool_init(IToolDefManager *mgr)
ToolDefinition("tool_steelsword.png", ToolDefinition("tool_steelsword.png",
ToolDiggingProperties(2.0, 3,0,1,-1, 300, 0,0,0,0))); ToolDiggingProperties(2.0, 3,0,1,-1, 300, 0,0,0,0)));
mgr->registerTool("", mgr->registerTool("",
ToolDefinition("tool_hand.png", ToolDefinition("tooldef.hand.png",
ToolDiggingProperties(0.5, 1,0,-1,0, 50, 0,0,0,0))); ToolDiggingProperties(0.5, 1,0,-1,0, 50, 0,0,0,0)));
} }

View File

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
class IToolDefManager; class IWritableToolDefManager;
// Add default tools to manager // Add default tools to manager
void content_tool_init(IToolDefManager *mgr); void content_tool_init(IWritableToolDefManager *mgr);

View File

@ -30,9 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#include "profiler.h" #include "profiler.h"
#include "scriptapi.h" #include "scriptapi.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "main.h" // For g_settings, g_profiler #include "main.h" // For g_settings, g_profiler
#include "gamedef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #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; infostream<<"Failed to read "<<path<<std::endl;
continue; continue;
} }
testplayer.deSerialize(is, m_gamedef); testplayer.deSerialize(is);
} }
//infostream<<"Loaded test player with name "<<testplayer.getName()<<std::endl; //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; infostream<<"Failed to read "<<path<<std::endl;
continue; continue;
} }
testplayer.deSerialize(is, m_gamedef); testplayer.deSerialize(is);
} }
if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS)) 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; infostream<<"Failed to read "<<path<<std::endl;
continue; continue;
} }
player->deSerialize(is, m_gamedef); player->deSerialize(is);
} }
if(newplayer) if(newplayer)
@ -557,9 +558,9 @@ void spawnRandomObjects(MapBlock *block)
MapNode n = block->getNodeNoEx(p); MapNode n = block->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE) if(n.getContent() == CONTENT_IGNORE)
continue; continue;
if(content_features(n).liquid_type != LIQUID_NONE) if(m_gamedef->ndef()->get(n).liquid_type != LIQUID_NONE)
continue; continue;
if(content_features(n).walkable) if(m_gamedef->ndef()->get(n).walkable)
{ {
last_node_walkable = true; last_node_walkable = true;
continue; continue;
@ -567,7 +568,7 @@ void spawnRandomObjects(MapBlock *block)
if(last_node_walkable) if(last_node_walkable)
{ {
// If block contains light information // 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) if(n.getLight(LIGHTBANK_DAY) <= 5)
{ {
@ -641,8 +642,8 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
if(dtime_s > 300) if(dtime_s > 300)
{ {
MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0)); MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
if(content_features(n_top).air_equivalent && if(m_gamedef->ndef()->get(n_top).air_equivalent &&
n_top.getLight(LIGHTBANK_DAY) >= 13) n_top.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) >= 13)
{ {
n.setContent(CONTENT_GRASS); n.setContent(CONTENT_GRASS);
m_map->addNodeWithEvent(p, n); m_map->addNodeWithEvent(p, n);
@ -1012,8 +1013,9 @@ void ServerEnvironment::step(float dtime)
if(myrand()%20 == 0) if(myrand()%20 == 0)
{ {
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0)); MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
if(content_features(n_top).air_equivalent && if(m_gamedef->ndef()->get(n_top).air_equivalent &&
n_top.getLightBlend(getDayNightRatio()) >= 13) n_top.getLightBlend(getDayNightRatio(),
m_gamedef->ndef()) >= 13)
{ {
n.setContent(CONTENT_GRASS); n.setContent(CONTENT_GRASS);
m_map->addNodeWithEvent(p, n); m_map->addNodeWithEvent(p, n);
@ -1028,7 +1030,7 @@ void ServerEnvironment::step(float dtime)
//if(myrand()%20 == 0) //if(myrand()%20 == 0)
{ {
MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,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); n.setContent(CONTENT_MUD);
m_map->addNodeWithEvent(p, n); m_map->addNodeWithEvent(p, n);
@ -1066,7 +1068,8 @@ void ServerEnvironment::step(float dtime)
{ {
v3s16 p1 = p + v3s16(0,1,0); v3s16 p1 = p + v3s16(0,1,0);
MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,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)); MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
if(n1a.getContent() == CONTENT_AIR && if(n1a.getContent() == CONTENT_AIR &&
n1b.getContent() == CONTENT_AIR) n1b.getContent() == CONTENT_AIR)
@ -2069,11 +2072,11 @@ void ClientEnvironment::step(float dtime)
u32 damage_per_second = 0; u32 damage_per_second = 0;
damage_per_second = MYMAX(damage_per_second, 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, 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, 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) if(damage_per_second != 0)
{ {
@ -2109,7 +2112,7 @@ void ClientEnvironment::step(float dtime)
// Get node at head // Get node at head
v3s16 p = player->getLightPosition(); v3s16 p = player->getLightPosition();
MapNode n = m_map->getNode(p); MapNode n = m_map->getNode(p);
light = n.getLightBlend(getDayNightRatio()); light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
} }
catch(InvalidPositionException &e) {} catch(InvalidPositionException &e) {}
player->updateLight(light); player->updateLight(light);
@ -2164,7 +2167,7 @@ void ClientEnvironment::step(float dtime)
// Get node at head // Get node at head
v3s16 p = obj->getLightPosition(); v3s16 p = obj->getLightPosition();
MapNode n = m_map->getNode(p); MapNode n = m_map->getNode(p);
light = n.getLightBlend(getDayNightRatio()); light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
} }
catch(InvalidPositionException &e) {} catch(InvalidPositionException &e) {}
obj->updateLight(light); 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) void ClientEnvironment::expireMeshes(bool only_daynight_diffed)

View File

@ -377,7 +377,7 @@ public:
LocalPlayer * getLocalPlayer(); LocalPlayer * getLocalPlayer();
// Slightly deprecated // Slightly deprecated
void updateMeshes(v3s16 blockpos, ITextureSource *tsrc); void updateMeshes(v3s16 blockpos);
void expireMeshes(bool only_daynight_diffed); void expireMeshes(bool only_daynight_diffed);
void setTimeOfDay(u32 time) void setTimeOfDay(u32 time)

View File

@ -44,12 +44,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#include "filesys.h" #include "filesys.h"
// Needed for determining pointing to nodes // Needed for determining pointing to nodes
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "main.h" // For g_settings #include "main.h" // For g_settings
#include "content_mapnode.h" // For content_mapnode_init #include "content_mapnode.h" // For content_mapnode_init
#include "tool.h" #include "tooldef.h"
#include "content_tool.h" // For content_tool_init #include "content_tool.h" // Default tools
#include "content_mapnode.h" // Default nodes
/* /*
Setting this to 1 enables a special camera mode that forces Setting this to 1 enables a special camera mode that forces
@ -321,7 +322,7 @@ void getPointedNode(Client *client, v3f player_position,
try try
{ {
n = client->getNode(v3s16(x,y,z)); n = client->getNode(v3s16(x,y,z));
if(content_pointable(n.getContent()) == false) if(client->getNodeDefManager()->get(n).pointable == false)
continue; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -343,7 +344,7 @@ void getPointedNode(Client *client, v3f player_position,
v3s16(-1,0,0), // left v3s16(-1,0,0), // left
}; };
ContentFeatures &f = content_features(n); const ContentFeatures &f = client->getNodeDefManager()->get(n);
if(f.selection_box.type == NODEBOX_FIXED) if(f.selection_box.type == NODEBOX_FIXED)
{ {
@ -592,20 +593,17 @@ void the_game(
draw_load_screen(L"Loading...", driver, font); draw_load_screen(L"Loading...", driver, font);
// Create tool manager // Create tool definition manager
IToolDefManager *toolmgr = createToolDefManager(); IWritableToolDefManager *tooldef = createToolDefManager();
// Create texture source // Create texture source
TextureSource *tsrc = new TextureSource(device); IWritableTextureSource *tsrc = createTextureSource(device);
// Create node definition manager
IWritableNodeDefManager *nodedef = createNodeDefManager(tsrc);
// Initialize mapnode again to enable changed graphics settings // Fill node feature table with default definitions
// Initialize content feature table with textures content_mapnode_init(tsrc, nodedef);
init_contentfeatures(tsrc); // Set default tool definitions
// Fill content feature table with default definitions content_tool_init(tooldef);
content_mapnode_init(tsrc);
// Initialize default tool definitions
content_tool_init(toolmgr);
/* /*
Create server. Create server.
@ -625,9 +623,14 @@ void the_game(
draw_load_screen(L"Creating client...", driver, font); draw_load_screen(L"Creating client...", driver, font);
infostream<<"Creating client"<<std::endl; infostream<<"Creating client"<<std::endl;
MapDrawControl draw_control; MapDrawControl draw_control;
Client client(device, playername.c_str(), password, 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); draw_load_screen(L"Resolving address...", driver, font);
Address connect_address(0,0,0,0, port); Address connect_address(0,0,0,0, port);
@ -1694,9 +1697,9 @@ void the_game(
// Get digging properties for material and tool // Get digging properties for material and tool
content_t material = n.getContent(); content_t material = n.getContent();
ToolDiggingProperties tp = ToolDiggingProperties tp =
toolmgr->getDiggingProperties(toolname); tooldef->getDiggingProperties(toolname);
DiggingProperties prop = DiggingProperties prop =
getDiggingProperties(material, &tp); getDiggingProperties(material, &tp, nodedef);
float dig_time_complete = 0.0; float dig_time_complete = 0.0;
@ -2102,7 +2105,7 @@ void the_game(
InventoryItem *item = NULL; InventoryItem *item = NULL;
if(mlist != NULL) if(mlist != NULL)
item = mlist->getItem(g_selected_item); item = mlist->getItem(g_selected_item);
camera.wield(item, tsrc); camera.wield(item, gamedef);
} }
/* /*
@ -2294,7 +2297,7 @@ void the_game(
gui_shuttingdowntext->remove();*/ gui_shuttingdowntext->remove();*/
} }
delete toolmgr; delete tooldef;
delete tsrc; delete tsrc;
} }

View File

@ -21,9 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define GAMEDEF_HEADER #define GAMEDEF_HEADER
class IToolDefManager; class IToolDefManager;
class INodeDefManager; //TODO class INodeDefManager;
//class IItemDefManager; //TODO //class IItemDefManager; //TODO
// Mineral too? // Mineral too?
class ITextureSource;
/* /*
An interface for fetching game-global definitions like tool and An interface for fetching game-global definitions like tool and
@ -33,9 +34,20 @@ class INodeDefManager; //TODO
class IGameDef class IGameDef
{ {
public: 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 IToolDefManager* getToolDefManager()=0;
virtual INodeDefManager* getNodeDefManager()=0; virtual INodeDefManager* getNodeDefManager()=0;
//virtual IItemDefManager* getItemDefManager()=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 #endif

View File

@ -29,8 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_sao.h" #include "content_sao.h"
#include "player.h" #include "player.h"
#include "log.h" #include "log.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "tool.h" #include "tooldef.h"
#include "gamedef.h" #include "gamedef.h"
/* /*
@ -152,7 +152,7 @@ ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f
#ifndef SERVER #ifndef SERVER
video::ITexture * MaterialItem::getImage(ITextureSource *tsrc) const video::ITexture * MaterialItem::getImage(ITextureSource *tsrc) const
{ {
return content_features(m_content).inventory_texture; return m_gamedef->getNodeDefManager()->get(m_content).inventory_texture;
} }
#endif #endif

View File

@ -434,7 +434,7 @@ Doing currently:
#include "settings.h" #include "settings.h"
#include "profiler.h" #include "profiler.h"
#include "log.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 #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. 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 // Must be called before texturesource is created
// (for texture atlas making) // (for texture atlas making)
init_mineral(); init_mineral();

View File

@ -37,7 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "log.h" #include "log.h"
#include "profiler.h" #include "profiler.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "gamedef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #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, bool> & light_sources,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
v3s16 dirs[6] = { v3s16 dirs[6] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
v3s16(0,1,0), // top v3s16(0,1,0), // top
@ -330,19 +333,20 @@ void Map::unspreadLight(enum LightBank bank,
If the neighbor is dimmer than what was specified If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node) 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 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 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); n2.setLight(bank, 0, nodemgr);
block->setNode(relpos, n2); block->setNode(relpos, n2);
unlighted_nodes.insert(n2pos, current_light); 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, bool> & from_nodes,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
const v3s16 dirs[6] = { const v3s16 dirs[6] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
v3s16(0,1,0), // top v3s16(0,1,0), // top
@ -474,7 +480,7 @@ void Map::spreadLight(enum LightBank bank,
// Get node straight from the block // Get node straight from the block
MapNode n = block->getNode(relpos); MapNode n = block->getNode(relpos);
u8 oldlight = n.getLight(bank); u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight); u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors // Loop through 6 neighbors
@ -512,7 +518,7 @@ void Map::spreadLight(enum LightBank bank,
If the neighbor is brighter than the current node, If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn) 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.insert(n2pos, true);
//lighted_nodes.push_back(n2pos); //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 If the neighbor is dimmer than how much light this node
would spread on it, add to list 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); block->setNode(relpos, n2);
lighted_nodes.insert(n2pos, true); lighted_nodes.insert(n2pos, true);
//lighted_nodes.push_back(n2pos); //lighted_nodes.push_back(n2pos);
@ -575,6 +581,8 @@ void Map::lightNeighbors(enum LightBank bank,
v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p) v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
v3s16 dirs[6] = { v3s16 dirs[6] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
v3s16(0,1,0), // top v3s16(0,1,0), // top
@ -600,8 +608,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
{ {
continue; continue;
} }
if(n2.getLight(bank) > brightest_light || found_something == false){ if(n2.getLight(bank, nodemgr) > brightest_light || found_something == false){
brightest_light = n2.getLight(bank); brightest_light = n2.getLight(bank, nodemgr);
brightest_pos = n2pos; brightest_pos = n2pos;
found_something = true; found_something = true;
} }
@ -624,6 +632,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
s16 Map::propagateSunlight(v3s16 start, s16 Map::propagateSunlight(v3s16 start,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
s16 y = start.Y; s16 y = start.Y;
for(; ; y--) for(; ; y--)
{ {
@ -642,9 +652,9 @@ s16 Map::propagateSunlight(v3s16 start,
v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE; v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE;
MapNode n = block->getNode(relpos); 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); block->setNode(relpos, n);
modified_blocks.insert(blockpos, block); 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*> & a_blocks,
core::map<v3s16, MapBlock*> & modified_blocks) core::map<v3s16, MapBlock*> & modified_blocks)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
/*m_dout<<DTIME<<"Map::updateLighting(): " /*m_dout<<DTIME<<"Map::updateLighting(): "
<<a_blocks.size()<<" blocks."<<std::endl;*/ <<a_blocks.size()<<" blocks."<<std::endl;*/
@ -713,8 +725,8 @@ void Map::updateLighting(enum LightBank bank,
try{ try{
v3s16 p(x,y,z); v3s16 p(x,y,z);
MapNode n = block->getNode(v3s16(x,y,z)); MapNode n = block->getNode(v3s16(x,y,z));
u8 oldlight = n.getLight(bank); u8 oldlight = n.getLight(bank, nodemgr);
n.setLight(bank, 0); n.setLight(bank, 0, nodemgr);
block->setNode(v3s16(x,y,z), n); block->setNode(v3s16(x,y,z), n);
// Collect borders for unlighting // Collect borders for unlighting
@ -865,11 +877,11 @@ void Map::updateLighting(enum LightBank bank,
{ {
//TimeTaker timer("unSpreadLight"); //TimeTaker timer("unSpreadLight");
vmanip.unspreadLight(bank, unlight_from, light_sources); vmanip.unspreadLight(bank, unlight_from, light_sources, nodemgr);
} }
{ {
//TimeTaker timer("spreadLight"); //TimeTaker timer("spreadLight");
vmanip.spreadLight(bank, light_sources); vmanip.spreadLight(bank, light_sources, nodemgr);
} }
{ {
//TimeTaker timer("blitBack"); //TimeTaker timer("blitBack");
@ -905,6 +917,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
void Map::addNodeAndUpdate(v3s16 p, MapNode n, void Map::addNodeAndUpdate(v3s16 p, MapNode n,
core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name) core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
/*PrintInfo(m_dout); /*PrintInfo(m_dout);
m_dout<<DTIME<<"Map::addNodeAndUpdate(): p=(" m_dout<<DTIME<<"Map::addNodeAndUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
@ -931,7 +945,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
try{ try{
MapNode topnode = getNode(toppos); MapNode topnode = getNode(toppos);
if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN) if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
node_under_sunlight = false; node_under_sunlight = false;
} }
catch(InvalidPositionException &e) 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 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{ try{
MapNode bottomnode = getNode(bottompos); MapNode bottomnode = getNode(bottompos);
@ -984,7 +998,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
{ {
enum LightBank bank = banks[i]; 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 // Add the block of the added node to modified_blocks
v3s16 blockpos = getNodeBlockPos(p); v3s16 blockpos = getNodeBlockPos(p);
@ -1001,16 +1015,16 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
// light again into this. // light again into this.
unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks); 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 If node lets sunlight through and is under sunlight, it has
sunlight too. 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 Add intial metadata
*/ */
NodeMetadata *meta_proto = content_features(n).initial_metadata; NodeMetadata *meta_proto = nodemgr->get(n).initial_metadata;
if(meta_proto) if(meta_proto)
{ {
NodeMetadata *meta = meta_proto->clone(m_gamedef); 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 TODO: This could be optimized by mass-unlighting instead
of looping 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; s16 y = p.Y - 1;
for(;; y--){ for(;; y--){
@ -1054,12 +1068,12 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
break; break;
} }
if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN) if(n2.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
{ {
unLightNeighbors(LIGHTBANK_DAY, unLightNeighbors(LIGHTBANK_DAY,
n2pos, n2.getLight(LIGHTBANK_DAY), n2pos, n2.getLight(LIGHTBANK_DAY, nodemgr),
light_sources, modified_blocks); light_sources, modified_blocks);
n2.setLight(LIGHTBANK_DAY, 0); n2.setLight(LIGHTBANK_DAY, 0, nodemgr);
setNode(n2pos, n2); setNode(n2pos, n2);
} }
else else
@ -1109,7 +1123,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
v3s16 p2 = p + dirs[i]; v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2); 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); m_transforming_liquid.push_back(p2);
} }
@ -1125,6 +1139,8 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
void Map::removeNodeAndUpdate(v3s16 p, void Map::removeNodeAndUpdate(v3s16 p,
core::map<v3s16, MapBlock*> &modified_blocks) core::map<v3s16, MapBlock*> &modified_blocks)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
/*PrintInfo(m_dout); /*PrintInfo(m_dout);
m_dout<<DTIME<<"Map::removeNodeAndUpdate(): p=(" m_dout<<DTIME<<"Map::removeNodeAndUpdate(): p=("
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
@ -1143,7 +1159,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
try{ try{
MapNode topnode = getNode(toppos); MapNode topnode = getNode(toppos);
if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN) if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
node_under_sunlight = false; node_under_sunlight = false;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -1165,7 +1181,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
Unlight neighbors (in case the node is a light source) Unlight neighbors (in case the node is a light source)
*/ */
unLightNeighbors(bank, p, unLightNeighbors(bank, p,
getNode(p).getLight(bank), getNode(p).getLight(bank, nodemgr),
light_sources, modified_blocks); light_sources, modified_blocks);
} }
@ -1227,7 +1243,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
// TODO: Is this needed? Lighting is cleared up there already. // TODO: Is this needed? Lighting is cleared up there already.
try{ try{
MapNode n = getNode(p); MapNode n = getNode(p);
n.setLight(LIGHTBANK_DAY, 0); n.setLight(LIGHTBANK_DAY, 0, nodemgr);
setNode(p, n); setNode(p, n);
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -1283,7 +1299,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
v3s16 p2 = p + dirs[i]; v3s16 p2 = p + dirs[i];
MapNode n2 = getNode(p2); 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); m_transforming_liquid.push_back(p2);
} }
@ -1580,6 +1596,8 @@ struct NodeNeighbor {
void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
//TimeTaker timer("transformLiquids()"); //TimeTaker timer("transformLiquids()");
@ -1614,11 +1632,11 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
*/ */
s8 liquid_level = -1; s8 liquid_level = -1;
u8 liquid_kind = CONTENT_IGNORE; 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) { switch (liquid_type) {
case LIQUID_SOURCE: case LIQUID_SOURCE:
liquid_level = LIQUID_LEVEL_SOURCE; liquid_level = LIQUID_LEVEL_SOURCE;
liquid_kind = content_features(n0.getContent()).liquid_alternative_flowing; liquid_kind = nodemgr->get(n0).liquid_alternative_flowing;
break; break;
case LIQUID_FLOWING: case LIQUID_FLOWING:
liquid_level = (n0.param2 & LIQUID_LEVEL_MASK); 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]; v3s16 npos = p0 + dirs[i];
NodeNeighbor nb = {getNodeNoEx(npos), nt, npos}; 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: case LIQUID_NONE:
if (nb.n.getContent() == CONTENT_AIR) { if (nb.n.getContent() == CONTENT_AIR) {
airs[num_airs++] = nb; airs[num_airs++] = nb;
@ -1678,8 +1696,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
case LIQUID_SOURCE: case LIQUID_SOURCE:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if (liquid_kind == CONTENT_AIR) if (liquid_kind == CONTENT_AIR)
liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing; liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) { if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
neutrals[num_neutrals++] = nb; neutrals[num_neutrals++] = nb;
} else { } else {
sources[num_sources++] = nb; sources[num_sources++] = nb;
@ -1688,8 +1706,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
case LIQUID_FLOWING: case LIQUID_FLOWING:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if (liquid_kind == CONTENT_AIR) if (liquid_kind == CONTENT_AIR)
liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing; liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) { if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
neutrals[num_neutrals++] = nb; neutrals[num_neutrals++] = nb;
} else { } else {
flows[num_flows++] = nb; 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) // 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 // 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. // 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) { } else if (num_sources == 1 && sources[0].t != NEIGHBOR_LOWER) {
// liquid_kind is set properly, see above // liquid_kind is set properly, see above
new_node_content = liquid_kind; 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) { if (viscosity > 1 && max_node_level != liquid_level) {
// amount to gain, limited by viscosity // amount to gain, limited by viscosity
// must be at least 1 in absolute value // 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. 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_LEVEL_MASK) == (u8)new_node_level &&
((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK) ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
== flowing_down))) == flowing_down)))
@ -1776,7 +1794,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
update the current node update the current node
*/ */
//bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK)); //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 // 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); n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
} else { } else {
@ -1790,14 +1808,14 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
if(block != NULL) { if(block != NULL) {
modified_blocks.insert(blockpos, block); modified_blocks.insert(blockpos, block);
// If node emits light, MapBlock requires lighting update // 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; lighting_modified_blocks[block->getPos()] = block;
} }
/* /*
enqueue neighbors for update if neccessary 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_SOURCE:
case LIQUID_FLOWING: case LIQUID_FLOWING:
// make sure source flows into all neighboring nodes // 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->no_op = false;
data->seed = m_seed; data->seed = m_seed;
data->blockpos = blockpos; data->blockpos = blockpos;
data->nodemgr = m_gamedef->ndef();
/* /*
Create the whole area of this and the neighboring blocks Create the whole area of this and the neighboring blocks
@ -2389,7 +2408,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
Generate blank sector Generate blank sector
*/ */
sector = new ServerMapSector(this, p2d); sector = new ServerMapSector(this, p2d, m_gamedef);
// Sector position on map in nodes // Sector position on map in nodes
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE; 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." <<fullpath<<" doesn't exist but directory does."
<<" Continuing with a sector with no metadata." <<" Continuing with a sector with no metadata."
<<std::endl;*/ <<std::endl;*/
sector = new ServerMapSector(this, p2d); sector = new ServerMapSector(this, p2d, m_gamedef);
m_sectors.insert(p2d, sector); m_sectors.insert(p2d, sector);
} }
else else
@ -3065,7 +3084,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
else else
{ {
sector = ServerMapSector::deSerialize sector = ServerMapSector::deSerialize
(is, this, p2d, m_sectors); (is, this, p2d, m_sectors, m_gamedef);
if(save_after_load) if(save_after_load)
saveSectorMeta(sector); saveSectorMeta(sector);
} }
@ -3310,7 +3329,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
} }
// Read basic data // Read basic data
block->deSerialize(is, version, m_gamedef); block->deSerialize(is, version);
// Read extra data stored on disk // Read extra data stored on disk
block->deSerializeDiskExtra(is, version); block->deSerializeDiskExtra(is, version);
@ -3380,7 +3399,7 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
} }
// Read basic data // Read basic data
block->deSerialize(is, version, m_gamedef); block->deSerialize(is, version);
// Read extra data stored on disk // Read extra data stored on disk
block->deSerializeDiskExtra(is, version); block->deSerializeDiskExtra(is, version);
@ -3567,7 +3586,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
} }
// Create a sector // 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 //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, 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); float d0 = (float)BS * p0.getDistanceFrom(p1);
v3s16 u0 = p1 - p0; 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); v3s16 p = floatToInt(pf, BS);
MapNode n = map->getNodeNoEx(p); MapNode n = map->getNodeNoEx(p);
bool is_transparent = false; bool is_transparent = false;
ContentFeatures &f = content_features(n); const ContentFeatures &f = nodemgr->get(n);
if(f.solidness == 0) if(f.solidness == 0)
is_transparent = (f.visual_solidness != 2); is_transparent = (f.visual_solidness != 2);
else 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) void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
//m_dout<<DTIME<<"Rendering map..."<<std::endl; //m_dout<<DTIME<<"Rendering map..."<<std::endl;
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -3855,23 +3876,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
u32 needed_count = 1; u32 needed_count = 1;
if( if(
isOccluded(this, spn, cpn + v3s16(0,0,0), 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), 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), 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), 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), 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), 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), 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), 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), isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
step, stepfac, startoff, endoff, needed_count) step, stepfac, startoff, endoff, needed_count, nodemgr)
) )
{ {
blocks_occlusion_culled++; blocks_occlusion_culled++;
@ -4016,6 +4037,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
void ClientMap::renderPostFx() void ClientMap::renderPostFx()
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
// Sadly ISceneManager has no "post effects" render pass, in that case we // Sadly ISceneManager has no "post effects" render pass, in that case we
// could just register for that and handle it in renderMap(). // 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 a solid node, make everything black.
// - If the player is in liquid, draw a semi-transparent overlay. // - 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; video::SColor post_effect_color = features.post_effect_color;
if(features.solidness == 2 && g_settings->getBool("free_move") == false) 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, void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
ITextureSource *tsrc)
{ {
assert(mapType() == MAPTYPE_CLIENT); assert(mapType() == MAPTYPE_CLIENT);
try{ try{
v3s16 p = blockpos + v3s16(0,0,0); v3s16 p = blockpos + v3s16(0,0,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio, tsrc); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true); //b->setMeshExpired(true);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
@ -4186,21 +4208,21 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
try{ try{
v3s16 p = blockpos + v3s16(-1,0,0); v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio, tsrc); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true); //b->setMeshExpired(true);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
try{ try{
v3s16 p = blockpos + v3s16(0,-1,0); v3s16 p = blockpos + v3s16(0,-1,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio, tsrc); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true); //b->setMeshExpired(true);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
try{ try{
v3s16 p = blockpos + v3s16(0,0,-1); v3s16 p = blockpos + v3s16(0,0,-1);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio, tsrc); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true); //b->setMeshExpired(true);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}

View File

@ -590,8 +590,7 @@ public:
Update the faces of the given block and blocks on the Update the faces of the given block and blocks on the
leading edge, without threading. Rarely used. leading edge, without threading. Rarely used.
*/ */
void updateMeshes(v3s16 blockpos, u32 daynight_ratio, void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
ITextureSource *tsrc);
// Update meshes that touch the node // Update meshes that touch the node
//void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio); //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);

View File

@ -23,17 +23,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h" #include "main.h"
#include "light.h" #include "light.h"
#include <sstream> #include <sstream>
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "nodemetadata.h" #include "nodemetadata.h"
#include "gamedef.h"
/* /*
MapBlock 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_node_metadata(new NodeMetadataList),
m_parent(parent), m_parent(parent),
m_pos(pos), m_pos(pos),
m_gamedef(gamedef),
m_modified(MOD_STATE_WRITE_NEEDED), m_modified(MOD_STATE_WRITE_NEEDED),
is_underground(false), is_underground(false),
m_lighting_expired(true), m_lighting_expired(true),
@ -138,7 +140,7 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p)
#ifndef SERVER #ifndef SERVER
#if 1 #if 1
void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc) void MapBlock::updateMesh(u32 daynight_ratio)
{ {
#if 0 #if 0
/* /*
@ -154,7 +156,7 @@ void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc)
MeshMakeData data; MeshMakeData data;
data.fill(daynight_ratio, this); data.fill(daynight_ratio, this);
scene::SMesh *mesh_new = makeMapBlockMesh(&data, tsrc); scene::SMesh *mesh_new = makeMapBlockMesh(&data, m_gamedef);
/* /*
Replace the mesh Replace the mesh
@ -229,6 +231,8 @@ void MapBlock::replaceMesh(scene::SMesh *mesh_new)
bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources, bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
bool remove_light, bool *black_air_left) bool remove_light, bool *black_air_left)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
// Whether the sunlight at the top of the bottom block is valid // Whether the sunlight at the top of the bottom block is valid
bool block_below_is_valid = true; bool block_below_is_valid = true;
@ -249,7 +253,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
// Trust heuristics // Trust heuristics
no_sunlight = is_underground; 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; 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)); MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
//if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE) //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; no_sunlight = true;
} }
@ -317,11 +321,11 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
{ {
// Do nothing // 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 // Do nothing: Sunlight is continued
} }
else if(n.light_propagates() == false) else if(nodemgr->get(n).light_propagates == false)
{ {
/*// DEPRECATED TODO: REMOVE /*// DEPRECATED TODO: REMOVE
if(grow_grass) if(grow_grass)
@ -355,11 +359,11 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
current_light = diminish_light(current_light); 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) 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) if(diminish_light(current_light) != 0)
@ -392,12 +396,12 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
if(block_below_is_valid) if(block_below_is_valid)
{ {
MapNode n = getNodeParent(v3s16(x, -1, z)); 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) && sunlight_should_go_down == false)
block_below_is_valid = 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) && sunlight_should_go_down == true)
block_below_is_valid = false; block_below_is_valid = false;
} }
@ -438,6 +442,8 @@ void MapBlock::copyFrom(VoxelManipulator &dst)
void MapBlock::updateDayNightDiff() void MapBlock::updateDayNightDiff()
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
if(data == NULL) if(data == NULL)
{ {
m_day_night_differs = false; m_day_night_differs = false;
@ -452,7 +458,7 @@ void MapBlock::updateDayNightDiff()
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++) for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
{ {
MapNode &n = data[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; differs = true;
break; break;
@ -493,7 +499,7 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
for(; y>=0; y--) for(; y>=0; y--)
{ {
MapNode n = getNodeRef(p2d.X, y, p2d.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) if(y == MAP_BLOCKSIZE-1)
return -2; 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)) if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapBlock format not supported"); 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) if(is.gcount() != len)
throw SerializationError throw SerializationError
("MapBlock::deSerialize: no enough input data"); ("MapBlock::deSerialize: no enough input data");
data[i].deSerialize(*d, version); data[i].deSerialize(*d, version, nodemgr);
} }
} }
else if(version <= 10) else if(version <= 10)
@ -772,7 +780,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
buf[0] = s[i]; buf[0] = s[i];
buf[1] = s[i+nodecount]; buf[1] = s[i+nodecount];
buf[2] = s[i+nodecount*2]; 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::string data = deSerializeString(is);
std::istringstream iss(data, std::ios_base::binary); std::istringstream iss(data, std::ios_base::binary);
m_node_metadata->deSerialize(iss, gamedef); m_node_metadata->deSerialize(iss, m_gamedef);
} }
else else
{ {
@ -794,7 +802,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
std::ostringstream oss(std::ios_base::binary); std::ostringstream oss(std::ios_base::binary);
decompressZlib(is, oss); decompressZlib(is, oss);
std::istringstream iss(oss.str(), std::ios_base::binary); 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) catch(SerializationError &e)

View File

@ -38,7 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map; class Map;
class NodeMetadataList; class NodeMetadataList;
class ITextureSource;
class IGameDef; class IGameDef;
#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff #define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
@ -120,7 +119,7 @@ public:
class MapBlock /*: public NodeContainer*/ class MapBlock /*: public NodeContainer*/
{ {
public: public:
MapBlock(Map *parent, v3s16 pos, bool dummy=false); MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy=false);
~MapBlock(); ~MapBlock();
/*virtual u16 nodeContainerId() const /*virtual u16 nodeContainerId() const
@ -393,12 +392,13 @@ public:
getNodeParentNoEx(p + face_dir), getNodeParentNoEx(p + face_dir),
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, return getFaceLight(daynight_ratio,
getNodeParentNoEx(p), getNodeParentNoEx(p),
getNodeParentNoEx(p + face_dir), getNodeParentNoEx(p + face_dir),
face_dir); face_dir, nodemgr);
} }
#ifndef SERVER // Only on client #ifndef SERVER // Only on client
@ -409,7 +409,7 @@ public:
NOTE: Prefer generating the mesh separately and then using NOTE: Prefer generating the mesh separately and then using
replaceMesh(). replaceMesh().
*/ */
void updateMesh(u32 daynight_ratio, ITextureSource *tsrc); void updateMesh(u32 daynight_ratio);
#endif #endif
// Replace the mesh with a new one // Replace the mesh with a new one
void replaceMesh(scene::SMesh *mesh_new); void replaceMesh(scene::SMesh *mesh_new);
@ -539,7 +539,7 @@ public:
// These don't write or read version by itself // These don't write or read version by itself
void serialize(std::ostream &os, u8 version); 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) // Used after the basic ones when writing on disk (serverside)
void serializeDiskExtra(std::ostream &os, u8 version); void serializeDiskExtra(std::ostream &os, u8 version);
void deSerializeDiskExtra(std::istream &is, u8 version); void deSerializeDiskExtra(std::istream &is, u8 version);
@ -589,6 +589,8 @@ private:
Map *m_parent; Map *m_parent;
// Position in blocks on parent // Position in blocks on parent
v3s16 m_pos; v3s16 m_pos;
IGameDef *m_gamedef;
/* /*
If NULL, block is a dummy block. If NULL, block is a dummy block.

View File

@ -22,11 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock.h" #include "mapblock.h"
#include "map.h" #include "map.h"
#include "main.h" // For g_settings and g_texturesource #include "main.h" // For g_settings and g_texturesource
#include "content_mapblock.h"
#include "settings.h" #include "settings.h"
#include "profiler.h" #include "profiler.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "tile.h" #include "tile.h"
#include "gamedef.h"
#include "content_mapblock.h"
void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block) void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
{ {
@ -84,7 +85,7 @@ void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
/* /*
vertex_dirs: v3s16[4] 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: If looked from outside the node towards the face, the corners are:
@ -170,7 +171,7 @@ struct FastFace
video::S3DVertex vertices[4]; // Precalculated vertices 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, v3s16 dir, v3f scale, v3f posRelative_f,
core::array<FastFace> &dest) 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. Gets node tile from any place relative to block.
Returns TILE_NODE if doesn't exist or should not be drawn. Returns TILE_NODE if doesn't exist or should not be drawn.
*/ */
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, static TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
NodeModMap &temp_mods, ITextureSource *tsrc) NodeModMap &temp_mods, ITextureSource *tsrc, INodeDefManager *ndef)
{ {
TileSpec spec; TileSpec spec;
spec = mn.getTile(face_dir, tsrc); spec = mn.getTile(face_dir, tsrc, ndef);
/* /*
Check temporary modifications on this node Check temporary modifications on this node
@ -273,7 +274,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
if(mod.type == NODEMOD_CHANGECONTENT) if(mod.type == NODEMOD_CHANGECONTENT)
{ {
MapNode mn2(mod.param); MapNode mn2(mod.param);
spec = mn2.getTile(face_dir, tsrc); spec = mn2.getTile(face_dir, tsrc, ndef);
} }
if(mod.type == NODEMOD_CRACK) if(mod.type == NODEMOD_CRACK)
{ {
@ -304,7 +305,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
return spec; 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 Check temporary modifications on this node
@ -354,7 +355,8 @@ v3s16 dirs8[8] = {
}; };
// Calculate lighting at the XYZ- corner of p // 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 ambient_occlusion = 0;
u16 light = 0; u16 light = 0;
@ -362,11 +364,11 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
for(u32 i=0; i<8; i++) for(u32 i=0; i<8; i++)
{ {
MapNode n = vmanip.getNodeNoEx(p - dirs8[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 // 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++; light_count++;
} }
else else
@ -391,8 +393,8 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
} }
// Calculate lighting at the given corner of p // Calculate lighting at the given corner of p
u8 getSmoothLight(v3s16 p, v3s16 corner, static u8 getSmoothLight(v3s16 p, v3s16 corner,
VoxelManipulator &vmanip, u32 daynight_ratio) VoxelManipulator &vmanip, u32 daynight_ratio, INodeDefManager *ndef)
{ {
if(corner.X == 1) p.X += 1; if(corner.X == 1) p.X += 1;
else assert(corner.X == -1); else assert(corner.X == -1);
@ -401,10 +403,10 @@ u8 getSmoothLight(v3s16 p, v3s16 corner,
if(corner.Z == 1) p.Z += 1; if(corner.Z == 1) p.Z += 1;
else assert(corner.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: // Input:
v3s16 blockpos_nodes, v3s16 blockpos_nodes,
v3s16 p, v3s16 p,
@ -413,7 +415,7 @@ void getTileInfo(
VoxelManipulator &vmanip, VoxelManipulator &vmanip,
NodeModMap &temp_mods, NodeModMap &temp_mods,
bool smooth_lighting, bool smooth_lighting,
ITextureSource *tsrc, IGameDef *gamedef,
// Output: // Output:
bool &makes_face, bool &makes_face,
v3s16 &p_corrected, v3s16 &p_corrected,
@ -422,16 +424,19 @@ void getTileInfo(
TileSpec &tile TileSpec &tile
) )
{ {
ITextureSource *tsrc = gamedef->tsrc();
INodeDefManager *ndef = gamedef->ndef();
MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p); MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir); MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
TileSpec tile0 = getNodeTile(n0, p, 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); TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc, ndef);
// This is hackish // This is hackish
content_t content0 = getNodeContent(p, n0, temp_mods); content_t content0 = getNodeContent(p, n0, temp_mods);
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods); content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
bool equivalent = false; bool equivalent = false;
u8 mf = face_contents(content0, content1, &equivalent); u8 mf = face_contents(content0, content1, &equivalent, ndef);
if(mf == 0) if(mf == 0)
{ {
@ -461,7 +466,7 @@ void getTileInfo(
if(smooth_lighting == false) if(smooth_lighting == false)
{ {
lights[0] = lights[1] = lights[2] = lights[3] = 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 else
{ {
@ -470,7 +475,7 @@ void getTileInfo(
for(u16 i=0; i<4; i++) for(u16 i=0; i<4; i++)
{ {
lights[i] = getSmoothLight(blockpos_nodes + p_corrected, 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 translate_dir: unit vector with only one of x, y or z
face_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, u32 daynight_ratio,
v3f posRelative_f, v3f posRelative_f,
v3s16 startpos, v3s16 startpos,
@ -496,7 +501,7 @@ void updateFastFaceRow(
VoxelManipulator &vmanip, VoxelManipulator &vmanip,
v3s16 blockpos_nodes, v3s16 blockpos_nodes,
bool smooth_lighting, bool smooth_lighting,
ITextureSource *tsrc) IGameDef *gamedef)
{ {
v3s16 p = startpos; v3s16 p = startpos;
@ -508,7 +513,7 @@ void updateFastFaceRow(
u8 lights[4] = {0,0,0,0}; u8 lights[4] = {0,0,0,0};
TileSpec tile; TileSpec tile;
getTileInfo(blockpos_nodes, p, face_dir, daynight_ratio, 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); makes_face, p_corrected, face_dir_corrected, lights, tile);
for(u16 j=0; j<length; j++) for(u16 j=0; j<length; j++)
@ -531,7 +536,7 @@ void updateFastFaceRow(
p_next = p + translate_dir; p_next = p + translate_dir;
getTileInfo(blockpos_nodes, p_next, face_dir, daynight_ratio, 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_makes_face, next_p_corrected,
next_face_dir_corrected, next_lights, next_face_dir_corrected, next_lights,
next_tile); 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 // 4-21ms for MAP_BLOCKSIZE=16
// 24-155ms for MAP_BLOCKSIZE=32 // 24-155ms for MAP_BLOCKSIZE=32
@ -692,7 +697,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
data->m_vmanip, data->m_vmanip,
blockpos_nodes, blockpos_nodes,
smooth_lighting, smooth_lighting,
tsrc); gamedef);
} }
} }
/* /*
@ -711,7 +716,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
data->m_vmanip, data->m_vmanip,
blockpos_nodes, blockpos_nodes,
smooth_lighting, smooth_lighting,
tsrc); gamedef);
} }
} }
/* /*
@ -730,7 +735,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
data->m_vmanip, data->m_vmanip,
blockpos_nodes, blockpos_nodes,
smooth_lighting, smooth_lighting,
tsrc); gamedef);
} }
} }
} }
@ -795,7 +800,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
- whatever - whatever
*/ */
mapblock_mesh_generate_special(data, collector, tsrc); mapblock_mesh_generate_special(data, collector, gamedef);
/* /*
Add stuff from collector to mesh Add stuff from collector to mesh

View File

@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock_nodemod.h" #include "mapblock_nodemod.h"
#include "voxel.h" #include "voxel.h"
class IGameDef;
/* /*
Mesh making stuff Mesh making stuff
*/ */
@ -141,7 +143,7 @@ struct MeshMakeData
}; };
// This is the highest-level function in here // This is the highest-level function in here
scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc); scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef);
#endif #endif

View File

@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mineral.h" #include "mineral.h"
//#include "serverobject.h" //#include "serverobject.h"
#include "content_sao.h" #include "content_sao.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
namespace mapgen namespace mapgen
{ {
@ -1417,9 +1417,9 @@ void add_random_objects(MapBlock *block)
MapNode n = block->getNodeNoEx(p); MapNode n = block->getNodeNoEx(p);
if(n.getContent() == CONTENT_IGNORE) if(n.getContent() == CONTENT_IGNORE)
continue; continue;
if(content_features(n).liquid_type != LIQUID_NONE) if(data->nodemgr->get(n)->liquid_type != LIQUID_NONE)
continue; continue;
if(content_features(n).walkable) if(data->nodemgr->get(n)->walkable)
{ {
last_node_walkable = true; last_node_walkable = true;
continue; continue;
@ -1478,6 +1478,9 @@ void make_block(BlockMakeData *data)
return; return;
} }
assert(data->vmanip);
assert(data->nodemgr);
v3s16 blockpos = data->blockpos; v3s16 blockpos = data->blockpos;
/*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<"," /*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
@ -2185,7 +2188,7 @@ void make_block(BlockMakeData *data)
{ {
u32 i = data->vmanip->m_area.index(p); u32 i = data->vmanip->m_area.index(p);
MapNode *n = &data->vmanip->m_data[i]; 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) || n->getContent() == CONTENT_JUNGLETREE)
{ {
found = true; found = true;
@ -2284,7 +2287,8 @@ void make_block(BlockMakeData *data)
BlockMakeData::BlockMakeData(): BlockMakeData::BlockMakeData():
no_op(false), no_op(false),
vmanip(NULL), vmanip(NULL),
seed(0) seed(0),
nodemgr(NULL)
{} {}
BlockMakeData::~BlockMakeData() BlockMakeData::~BlockMakeData()

View File

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct BlockMakeData; struct BlockMakeData;
class MapBlock; class MapBlock;
class ManualMapVoxelManipulator; class ManualMapVoxelManipulator;
class INodeDefManager;
namespace mapgen namespace mapgen
{ {
@ -54,10 +55,11 @@ namespace mapgen
struct BlockMakeData struct BlockMakeData
{ {
bool no_op; bool no_op;
ManualMapVoxelManipulator *vmanip; ManualMapVoxelManipulator *vmanip; // Destructor deletes
u64 seed; u64 seed;
v3s16 blockpos; v3s16 blockpos;
UniqueQueue<v3s16> transforming_liquid; UniqueQueue<v3s16> transforming_liquid;
INodeDefManager *nodemgr; // Destructor deletes
BlockMakeData(); BlockMakeData();
~BlockMakeData(); ~BlockMakeData();

View File

@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
#include "mineral.h" #include "mineral.h"
#include "main.h" // For g_settings #include "main.h" // For g_settings
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "content_mapnode.h" // For mapnode_translate_*_internal #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 1: Face uses m1's content
2: Face uses m2's content 2: Face uses m2's content
equivalent: Whether the blocks share the same face (eg. water and glass) 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; *equivalent = false;
@ -43,13 +46,15 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
bool contents_differ = (m1 != m2); 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 // Contents don't differ for different forms of same liquid
if(content_liquid(m1) && content_liquid(m2) if(f1.sameLiquid(f2))
&& make_liquid_flowing(m1) == make_liquid_flowing(m2))
contents_differ = false; contents_differ = false;
u8 c1 = content_solidness(m1); u8 c1 = f1.solidness;
u8 c2 = content_solidness(m2); u8 c2 = f2.solidness;
bool solidness_differs = (c1 != c2); bool solidness_differs = (c1 != c2);
bool makes_face = contents_differ && solidness_differs; bool makes_face = contents_differ && solidness_differs;
@ -58,16 +63,16 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent)
return 0; return 0;
if(c1 == 0) if(c1 == 0)
c1 = content_features(m1).visual_solidness; c1 = f1.visual_solidness;
if(c2 == 0) if(c2 == 0)
c2 = content_features(m2).visual_solidness; c2 = f2.visual_solidness;
if(c1 == c2){ if(c1 == c2){
*equivalent = true; *equivalent = true;
// If same solidness, liquid takes precense // If same solidness, liquid takes precense
if(content_features(m1).liquid_type != LIQUID_NONE) if(f1.isLiquid())
return 1; return 1;
if(content_features(m2).liquid_type != LIQUID_NONE) if(f2.isLiquid())
return 2; return 2;
} }
@ -147,28 +152,10 @@ v3s16 unpackDir(u8 b)
MapNode MapNode
*/ */
// These four are DEPRECATED. void MapNode::setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr)
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)
{ {
// If node doesn't contain light data, ignore this // 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; return;
if(bank == LIGHTBANK_DAY) if(bank == LIGHTBANK_DAY)
{ {
@ -184,11 +171,11 @@ void MapNode::setLight(enum LightBank bank, u8 a_light)
assert(0); 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] // Select the brightest of [light source, propagated light]
u8 light = 0; u8 light = 0;
if(content_features(*this).param_type == CPT_LIGHT) if(nodemgr->get(*this).param_type == CPT_LIGHT)
{ {
if(bank == LIGHTBANK_DAY) if(bank == LIGHTBANK_DAY)
light = param1 & 0x0f; light = param1 & 0x0f;
@ -197,32 +184,33 @@ u8 MapNode::getLight(enum LightBank bank)
else else
assert(0); assert(0);
} }
if(light_source() > light) if(nodemgr->get(*this).light_source > light)
light = light_source(); light = nodemgr->get(*this).light_source;
return light; return light;
} }
u8 MapNode::getLightBanksWithSource() u8 MapNode::getLightBanksWithSource(INodeDefManager *nodemgr) const
{ {
// Select the brightest of [light source, propagated light] // Select the brightest of [light source, propagated light]
u8 lightday = 0; u8 lightday = 0;
u8 lightnight = 0; u8 lightnight = 0;
if(content_features(*this).param_type == CPT_LIGHT) if(nodemgr->get(*this).param_type == CPT_LIGHT)
{ {
lightday = param1 & 0x0f; lightday = param1 & 0x0f;
lightnight = (param1>>4)&0x0f; lightnight = (param1>>4)&0x0f;
} }
if(light_source() > lightday) if(nodemgr->get(*this).light_source > lightday)
lightday = light_source(); lightday = nodemgr->get(*this).light_source;
if(light_source() > lightnight) if(nodemgr->get(*this).light_source > lightnight)
lightnight = light_source(); lightnight = nodemgr->get(*this).light_source;
return (lightday&0x0f) | ((lightnight<<4)&0xf0); return (lightday&0x0f) | ((lightnight<<4)&0xf0);
} }
#ifndef SERVER #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); dir = facedir_rotate(param1, dir);
TileSpec spec; TileSpec spec;
@ -246,16 +234,16 @@ TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
if(dir_i == -1) if(dir_i == -1)
// Non-directional // Non-directional
spec = content_features(*this).tiles[0]; spec = nodemgr->get(*this).tiles[0];
else else
spec = content_features(*this).tiles[dir_i]; spec = nodemgr->get(*this).tiles[dir_i];
/* /*
If it contains some mineral, change texture id 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); std::string mineral_texture_name = mineral_block_texture(mineral);
if(mineral_texture_name != "") if(mineral_texture_name != "")
{ {
@ -273,9 +261,9 @@ TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
} }
#endif #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; return param1 & 0x0f;
} }
@ -332,7 +320,7 @@ void MapNode::serialize(u8 *dest, u8 version)
dest[2] = n_foreign.param2; 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)) if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapNode format not supported"); throw VersionMismatchException("ERROR: MapNode format not supported");
@ -345,7 +333,7 @@ void MapNode::deSerialize(u8 *source, u8 version)
{ {
param0 = source[0]; param0 = source[0];
// This version doesn't support saved lighting // 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; param1 = 0;
else else
param1 = source[1]; param1 = source[1];
@ -402,12 +390,12 @@ void MapNode::deSerialize(u8 *source, u8 version)
returns encoded light value. returns encoded light value.
*/ */
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir) v3s16 face_dir, INodeDefManager *nodemgr)
{ {
try{ try{
u8 light; u8 light;
u8 l1 = n.getLightBlend(daynight_ratio); u8 l1 = n.getLightBlend(daynight_ratio, nodemgr);
u8 l2 = n2.getLightBlend(daynight_ratio); u8 l2 = n2.getLightBlend(daynight_ratio, nodemgr);
if(l1 > l2) if(l1 > l2)
light = l1; light = l1;
else else

View File

@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tile.h" #include "tile.h"
#endif #endif
class INodeDefManager;
/* /*
Naming scheme: Naming scheme:
- Material = irrlicht's Material class - Material = irrlicht's Material class
@ -68,7 +70,8 @@ typedef u16 content_t;
2: Face uses m2's content 2: Face uses m2's content
equivalent: Whether the blocks share the same face (eg. water and glass) 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. Packs directions like (1,0,0), (1,-1,0) in six bits.
@ -157,7 +160,7 @@ struct MapNode
} }
// To be used everywhere // To be used everywhere
content_t getContent() content_t getContent() const
{ {
if(param0 < 0x80) if(param0 < 0x80)
return param0; return param0;
@ -180,27 +183,19 @@ struct MapNode
} }
} }
/* void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
These four are DEPRECATED I guess. -c55 u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
*/ u8 getLightBanksWithSource(INodeDefManager *nodemgr) const;
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();
// 0 <= daylight_factor <= 1000 // 0 <= daylight_factor <= 1000
// 0 <= return value <= LIGHT_SUN // 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) u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY, nodemgr)
+ (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT)) + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT, nodemgr))
)/1000; )/1000;
u8 max = LIGHT_MAX; u8 max = LIGHT_MAX;
if(getLight(LIGHTBANK_DAY) == LIGHT_SUN) if(getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
max = LIGHT_SUN; max = LIGHT_SUN;
if(l > max) if(l > max)
l = max; l = max;
@ -208,10 +203,10 @@ struct MapNode
} }
/*// 0 <= daylight_factor <= 1000 /*// 0 <= daylight_factor <= 1000
// 0 <= return value <= 255 // 0 <= return value <= 255
u8 getLightBlend(u32 daylight_factor) u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr)
{ {
u8 daylight = decode_light(getLight(LIGHTBANK_DAY)); u8 daylight = decode_light(getLight(LIGHTBANK_DAY, nodemgr));
u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT)); u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT, nodemgr));
u8 mix = ((daylight_factor * daylight u8 mix = ((daylight_factor * daylight
+ (1000-daylight_factor) * nightlight) + (1000-daylight_factor) * nightlight)
)/1000; )/1000;
@ -226,14 +221,15 @@ struct MapNode
Returns: TileSpec. Can contain miscellaneous texture coordinates, Returns: TileSpec. Can contain miscellaneous texture coordinates,
which must be obeyed so that the texture atlas can be used. 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 #endif
/* /*
Gets mineral content of node, if there is any. Gets mineral content of node, if there is any.
MINERAL_NONE if doesn't contain or isn't able to contain mineral. MINERAL_NONE if doesn't contain or isn't able to contain mineral.
*/ */
u8 getMineral(); u8 getMineral(INodeDefManager *nodemgr) const;
/* /*
Serialization functions Serialization functions
@ -241,7 +237,7 @@ struct MapNode
static u32 serializedLength(u8 version); static u32 serializedLength(u8 version);
void serialize(u8 *dest, 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. returns encoded light value.
*/ */
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir); v3s16 face_dir, INodeDefManager *nodemgr);
#endif #endif

View File

@ -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());
}

View File

@ -23,10 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "exceptions.h" #include "exceptions.h"
#include "mapblock.h" #include "mapblock.h"
MapSector::MapSector(Map *parent, v2s16 pos): MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
differs_from_disk(false), differs_from_disk(false),
m_parent(parent), m_parent(parent),
m_pos(pos), m_pos(pos),
m_gamedef(gamedef),
m_block_cache(NULL) m_block_cache(NULL)
{ {
} }
@ -89,7 +90,7 @@ MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
v3s16 blockpos_map(m_pos.X, y, m_pos.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; return block;
} }
@ -151,8 +152,8 @@ void MapSector::getBlocks(core::list<MapBlock*> &dest)
ServerMapSector ServerMapSector
*/ */
ServerMapSector::ServerMapSector(Map *parent, v2s16 pos): ServerMapSector::ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
MapSector(parent, pos) MapSector(parent, pos, gamedef)
{ {
} }
@ -186,7 +187,8 @@ ServerMapSector* ServerMapSector::deSerialize(
std::istream &is, std::istream &is,
Map *parent, Map *parent,
v2s16 p2d, v2s16 p2d,
core::map<v2s16, MapSector*> & sectors core::map<v2s16, MapSector*> & sectors,
IGameDef *gamedef
) )
{ {
/* /*
@ -229,7 +231,7 @@ ServerMapSector* ServerMapSector::deSerialize(
} }
else else
{ {
sector = new ServerMapSector(parent, p2d); sector = new ServerMapSector(parent, p2d, gamedef);
sectors.insert(p2d, sector); sectors.insert(p2d, sector);
} }
@ -247,8 +249,8 @@ ServerMapSector* ServerMapSector::deSerialize(
ClientMapSector ClientMapSector
*/ */
ClientMapSector::ClientMapSector(Map *parent, v2s16 pos): ClientMapSector::ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
MapSector(parent, pos) MapSector(parent, pos, gamedef)
{ {
} }

View File

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class MapBlock; class MapBlock;
class Map; class Map;
class IGameDef;
/* /*
This is an Y-wise stack of MapBlocks. This is an Y-wise stack of MapBlocks.
@ -43,7 +44,7 @@ class MapSector
{ {
public: public:
MapSector(Map *parent, v2s16 pos); MapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
virtual ~MapSector(); virtual ~MapSector();
virtual u32 getId() const = 0; virtual u32 getId() const = 0;
@ -76,7 +77,9 @@ protected:
Map *m_parent; Map *m_parent;
// Position on parent (in MapBlock widths) // Position on parent (in MapBlock widths)
v2s16 m_pos; v2s16 m_pos;
IGameDef *m_gamedef;
// Last-used block is cached here for quicker access. // Last-used block is cached here for quicker access.
// Be sure to set this to NULL when the cached block is deleted // Be sure to set this to NULL when the cached block is deleted
MapBlock *m_block_cache; MapBlock *m_block_cache;
@ -92,7 +95,7 @@ protected:
class ServerMapSector : public MapSector class ServerMapSector : public MapSector
{ {
public: public:
ServerMapSector(Map *parent, v2s16 pos); ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
~ServerMapSector(); ~ServerMapSector();
u32 getId() const u32 getId() const
@ -111,7 +114,8 @@ public:
std::istream &is, std::istream &is,
Map *parent, Map *parent,
v2s16 p2d, v2s16 p2d,
core::map<v2s16, MapSector*> & sectors core::map<v2s16, MapSector*> & sectors,
IGameDef *gamedef
); );
private: private:
@ -121,7 +125,7 @@ private:
class ClientMapSector : public MapSector class ClientMapSector : public MapSector
{ {
public: public:
ClientMapSector(Map *parent, v2s16 pos); ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
~ClientMapSector(); ~ClientMapSector();
u32 getId() const u32 getId() const

View File

@ -1,12 +1,13 @@
#include "materials.h" #include "materials.h"
#include "mapnode.h" #include "mapnode.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "tool.h" #include "tooldef.h"
DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp) DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
INodeDefManager *nodemgr)
{ {
assert(tp); assert(tp);
MaterialProperties &mp = content_features(material).material; const MaterialProperties &mp = nodemgr->get(content).material;
if(mp.diggability == DIGGABLE_NOT) if(mp.diggability == DIGGABLE_NOT)
return DiggingProperties(false, 0, 0); return DiggingProperties(false, 0, 0);
if(mp.diggability == DIGGABLE_CONSTANT) if(mp.diggability == DIGGABLE_CONSTANT)

View File

@ -89,8 +89,10 @@ struct DiggingProperties
}; };
class ToolDiggingProperties; class ToolDiggingProperties;
class INodeDefManager;
DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp); DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
INodeDefManager *nodemgr);
#endif #endif

175
src/nodedef.cpp Normal file
View File

@ -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);
}

View File

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef MAPNODE_CONTENTFEATURES_HEADER #ifndef NODEDEF_HEADER
#define MAPNODE_CONTENTFEATURES_HEADER #define NODEDEF_HEADER
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include <string> #include <string>
#include <set>
#include "mapnode.h" #include "mapnode.h"
#ifndef SERVER #ifndef SERVER
#include "tile.h" #include "tile.h"
@ -29,6 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "materials.h" // MaterialProperties #include "materials.h" // MaterialProperties
class ITextureSource; class ITextureSource;
/*
TODO: Rename to nodedef.h
*/
#if 0
/* /*
Content feature list Content feature list
@ -43,6 +50,8 @@ class ITextureSource;
*/ */
void init_contentfeatures(ITextureSource *tsrc); void init_contentfeatures(ITextureSource *tsrc);
#endif
enum ContentParamType enum ContentParamType
{ {
CPT_NONE, CPT_NONE,
@ -119,7 +128,7 @@ struct ContentFeatures
// List of all block textures that have been used (value is dummy) // List of all block textures that have been used (value is dummy)
// Used for texture atlas making. // Used for texture atlas making.
// Exists on server too for cleaner code in content_mapnode.cpp. // 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 // Type of MapNode::param1
ContentParamType param_type; ContentParamType param_type;
@ -195,6 +204,7 @@ struct ContentFeatures
special_material2 = NULL; special_material2 = NULL;
special_atlas = NULL; special_atlas = NULL;
#endif #endif
used_texturenames.clear();
param_type = CPT_NONE; param_type = CPT_NONE;
is_ground_content = false; is_ground_content = false;
light_propagates = false; light_propagates = false;
@ -256,16 +266,9 @@ struct ContentFeatures
#ifndef SERVER #ifndef SERVER
void setTile(u16 i, const TileSpec &tile) void setTile(u16 i, const TileSpec &tile)
{ { tiles[i] = tile; }
tiles[i] = tile;
}
void setAllTiles(const TileSpec &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 #endif
#ifdef SERVER #ifdef SERVER
@ -281,94 +284,46 @@ struct ContentFeatures
void setInventoryTextureCube(std::string top, void setInventoryTextureCube(std::string top,
std::string left, std::string right, ITextureSource *tsrc); std::string left, std::string right, ITextureSource *tsrc);
#endif #endif
/*
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);
}
}; };
/* class INodeDefManager
Call this to access the ContentFeature list {
*/ public:
ContentFeatures & content_features(content_t i); INodeDefManager(){}
ContentFeatures & content_features(MapNode &n); 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
Here is a bunch of DEPRECATED functions. {
*/ 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
If true, the material allows light propagation and brightness is stored IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc);
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)
{
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)
{
return content_features(m).buildable_to;
}
#endif #endif

View File

@ -27,9 +27,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif #endif
#include "main.h" // For g_settings #include "main.h" // For g_settings
#include "settings.h" #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), touching_ground(false),
in_water(false), in_water(false),
in_water_stable(false), in_water_stable(false),
@ -39,6 +41,8 @@ Player::Player():
craftresult_is_preview(true), craftresult_is_preview(true),
hp(20), hp(20),
peer_id(PEER_ID_INEXISTENT), peer_id(PEER_ID_INEXISTENT),
// protected
m_gamedef(gamedef),
m_selected_item(0), m_selected_item(0),
m_pitch(0), m_pitch(0),
m_yaw(0), m_yaw(0),
@ -129,7 +133,7 @@ void Player::serialize(std::ostream &os)
inventory.serialize(os); inventory.serialize(os);
} }
void Player::deSerialize(std::istream &is, IGameDef *gamedef) void Player::deSerialize(std::istream &is)
{ {
Settings args; Settings args;
@ -163,13 +167,28 @@ void Player::deSerialize(std::istream &is, IGameDef *gamedef)
hp = 20; hp = 20;
} }
inventory.deSerialize(is, gamedef); inventory.deSerialize(is, m_gamedef);
} }
/* /*
ServerRemotePlayer 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 */ /* ServerActiveObject interface */
InventoryItem* ServerRemotePlayer::getWieldedItem() InventoryItem* ServerRemotePlayer::getWieldedItem()
@ -237,9 +256,11 @@ s16 ServerRemotePlayer::getHP()
#ifndef SERVER #ifndef SERVER
RemotePlayer::RemotePlayer( RemotePlayer::RemotePlayer(
IGameDef *gamedef,
scene::ISceneNode* parent, scene::ISceneNode* parent,
IrrlichtDevice *device, IrrlichtDevice *device,
s32 id): s32 id):
Player(gamedef),
scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id), scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id),
m_text(NULL) m_text(NULL)
{ {
@ -354,7 +375,8 @@ void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
LocalPlayer LocalPlayer
*/ */
LocalPlayer::LocalPlayer(): LocalPlayer::LocalPlayer(IGameDef *gamedef):
Player(gamedef),
m_sneak_node(32767,32767,32767), m_sneak_node(32767,32767,32767),
m_sneak_node_exists(false) m_sneak_node_exists(false)
{ {
@ -370,6 +392,8 @@ LocalPlayer::~LocalPlayer()
void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
core::list<CollisionInfo> *collision_info) core::list<CollisionInfo> *collision_info)
{ {
INodeDefManager *nodemgr = m_gamedef->ndef();
v3f position = getPosition(); v3f position = getPosition();
v3f oldpos = position; v3f oldpos = position;
v3s16 oldpos_i = floatToInt(oldpos, BS); v3s16 oldpos_i = floatToInt(oldpos, BS);
@ -407,13 +431,13 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
if(in_water) if(in_water)
{ {
v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS); 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 // If not in water, the threshold of going in is at lower y
else else
{ {
v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS); 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) catch(InvalidPositionException &e)
@ -426,7 +450,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
*/ */
try{ try{
v3s16 pp = floatToInt(position + v3f(0,0,0), BS); 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) catch(InvalidPositionException &e)
{ {
@ -438,14 +462,14 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
*/ */
try { 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); v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
is_climbing = ((content_features(map.getNode(pp).getContent()).climbable || is_climbing = ((nodemgr->get(map.getNode(pp).getContent()).climbable ||
content_features(map.getNode(pp2).getContent()).climbable) && !free_move); nodemgr->get(map.getNode(pp2).getContent()).climbable) && !free_move);
} }
catch(InvalidPositionException &e) 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; bool is_unloaded = false;
try{ try{
// Player collides into walkable nodes // 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; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)
@ -719,10 +743,10 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
try{ try{
// The node to be sneaked on has to be walkable // 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; continue;
// And the node above it has to be nonwalkable // 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; continue;
} }
catch(InvalidPositionException &e) catch(InvalidPositionException &e)

View File

@ -30,13 +30,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map; class Map;
class IGameDef;
class Player class Player
{ {
public: public:
Player(IGameDef *gamedef);
Player();
virtual ~Player(); virtual ~Player();
void resetInventory(); void resetInventory();
@ -141,7 +141,7 @@ public:
deSerialize stops reading exactly at the right point. deSerialize stops reading exactly at the right point.
*/ */
void serialize(std::ostream &os); void serialize(std::ostream &os);
void deSerialize(std::istream &is, IGameDef *gamedef); void deSerialize(std::istream &is);
bool touching_ground; bool touching_ground;
// This oscillates so that the player jumps a bit above the surface // This oscillates so that the player jumps a bit above the surface
@ -164,6 +164,8 @@ public:
u16 peer_id; u16 peer_id;
protected: protected:
IGameDef *m_gamedef;
char m_name[PLAYERNAME_SIZE]; char m_name[PLAYERNAME_SIZE];
u16 m_selected_item; u16 m_selected_item;
f32 m_pitch; f32 m_pitch;
@ -185,26 +187,15 @@ public:
class ServerRemotePlayer : public Player, public ServerActiveObject class ServerRemotePlayer : public Player, public ServerActiveObject
{ {
public: public:
ServerRemotePlayer(ServerEnvironment *env): ServerRemotePlayer(ServerEnvironment *env);
ServerActiveObject(env, v3f(0,0,0))
{
}
ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_, ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
const char *name_): const char *name_);
ServerActiveObject(env, pos_)
{
setPosition(pos_);
peer_id = peer_id_;
updateName(name_);
}
virtual ~ServerRemotePlayer() virtual ~ServerRemotePlayer()
{ {}
}
virtual bool isLocal() const virtual bool isLocal() const
{ { return false; }
return false;
}
virtual void move(f32 dtime, Map &map, f32 pos_max_d) virtual void move(f32 dtime, Map &map, f32 pos_max_d)
{ {
@ -242,6 +233,7 @@ class RemotePlayer : public Player, public scene::ISceneNode
{ {
public: public:
RemotePlayer( RemotePlayer(
IGameDef *gamedef,
scene::ISceneNode* parent=NULL, scene::ISceneNode* parent=NULL,
IrrlichtDevice *device=NULL, IrrlichtDevice *device=NULL,
s32 id=0); s32 id=0);
@ -378,7 +370,7 @@ struct PlayerControl
class LocalPlayer : public Player class LocalPlayer : public Player
{ {
public: public:
LocalPlayer(); LocalPlayer(IGameDef *gamedef);
virtual ~LocalPlayer(); virtual ~LocalPlayer();
bool isLocal() const bool isLocal() const

View File

@ -41,8 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#include "script.h" #include "script.h"
#include "scriptapi.h" #include "scriptapi.h"
#include "mapnode_contentfeatures.h" #include "nodedef.h"
#include "tool.h" #include "tooldef.h"
#include "content_tool.h" // For content_tool_init #include "content_tool.h" // For content_tool_init
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@ -959,6 +959,7 @@ Server::Server(
m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"), m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
m_lua(NULL), m_lua(NULL),
m_toolmgr(createToolDefManager()), m_toolmgr(createToolDefManager()),
m_nodemgr(createNodeDefManager(NULL)),
m_thread(this), m_thread(this),
m_emergethread(this), m_emergethread(this),
m_time_counter(0), m_time_counter(0),
@ -983,10 +984,15 @@ Server::Server(
JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
infostream<<"m_nodemgr="<<m_nodemgr<<std::endl;
// Initialize default tool definitions // Initialize default tool definitions
content_tool_init(m_toolmgr); content_tool_init(m_toolmgr);
// Initialize default node definitions
content_mapnode_init(NULL, m_nodemgr);
// Initialize scripting // Initialize scripting
infostream<<"Server: Initializing scripting"<<std::endl; infostream<<"Server: Initializing scripting"<<std::endl;
@ -1107,6 +1113,7 @@ Server::~Server()
delete m_env; delete m_env;
delete m_toolmgr; delete m_toolmgr;
delete m_nodemgr;
// Deinitialize scripting // Deinitialize scripting
infostream<<"Server: Deinitializing scripting"<<std::endl; 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); MapNode n = m_env->getMap().getNode(p_under);
// Get mineral // Get mineral
mineral = n.getMineral(); mineral = n.getMineral(m_nodemgr);
// Get material at position // Get material at position
material = n.getContent(); material = n.getContent();
// If not yet cancelled // If not yet cancelled
if(cannot_remove_node == false) if(cannot_remove_node == false)
{ {
// If it's not diggable, do nothing // If it's not diggable, do nothing
if(content_diggable(material) == false) if(m_nodemgr->get(material).diggable == false)
{ {
infostream<<"Server: Not finishing digging: " infostream<<"Server: Not finishing digging: "
<<"Node not diggable" <<"Node not diggable"
@ -2584,7 +2591,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
ToolDiggingProperties tp = ToolDiggingProperties tp =
m_toolmgr->getDiggingProperties(toolname); m_toolmgr->getDiggingProperties(toolname);
DiggingProperties prop = DiggingProperties prop =
getDiggingProperties(material, &tp); getDiggingProperties(material, &tp, m_nodemgr);
if(prop.diggable == false) if(prop.diggable == false)
{ {
@ -2614,7 +2621,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// If not mineral // If not mineral
if(item == NULL) 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 != "") if(dug_s != "")
{ {
std::istringstream is(dug_s, std::ios::binary); 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 not mineral
if(item == NULL) if(item == NULL)
{ {
std::string &extra_dug_s = content_features(material).extra_dug_item; const std::string &extra_dug_s = m_nodemgr->get(material).extra_dug_item;
s32 extra_rarity = content_features(material).extra_dug_item_rarity; s32 extra_rarity = m_nodemgr->get(material).extra_dug_item_rarity;
if(extra_dug_s != "" && extra_rarity != 0 if(extra_dug_s != "" && extra_rarity != 0
&& myrand() % 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); item = InventoryItem::deSerialize(is, this);
} }
} }
if(item != NULL) if(item != NULL)
{ {
// Add a item to inventory // Add a item to inventory
player->inventory.addItem("main", item); player->inventory.addItem("main", item);
// Send inventory // Send inventory
UpdateCrafting(player->peer_id); UpdateCrafting(player->peer_id);
@ -2717,7 +2724,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" because privileges are "<<getPlayerPrivs(player) <<" because privileges are "<<getPlayerPrivs(player)
<<std::endl; <<std::endl;
if(content_features(n2).buildable_to == false if(m_nodemgr->get(n2).buildable_to == false
|| no_enough_privs) || no_enough_privs)
{ {
// Client probably has wrong data. // 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; <<" at "<<PP(p_under)<<std::endl;
// Calculate direction for wall mounted stuff // 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); n.param2 = packDir(p_under - p_over);
// Calculate the direction for furnaces and chests and stuff // 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 playerpos = player->getPosition();
v3f blockpos = intToFloat(p_over, BS) - playerpos; v3f blockpos = intToFloat(p_over, BS) - playerpos;
@ -4192,6 +4199,21 @@ void Server::notifyPlayers(const std::wstring msg)
BroadcastChatMessage(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) v3f findSpawnPos(ServerMap &map)
{ {
//return v3f(50,50,50)*BS; //return v3f(50,50,50)*BS;

View File

@ -32,7 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gamedef.h" #include "gamedef.h"
struct LuaState; struct LuaState;
typedef struct lua_State lua_State; typedef struct lua_State lua_State;
class IToolDefManager; class IWritableToolDefManager;
class IWritableNodeDefManager;
/* /*
Some random functions Some random functions
@ -486,10 +487,9 @@ public:
// IGameDef interface // IGameDef interface
// Under envlock // Under envlock
virtual IToolDefManager* getToolDefManager() virtual IToolDefManager* getToolDefManager();
{ return m_toolmgr; } virtual INodeDefManager* getNodeDefManager();
virtual INodeDefManager* getNodeDefManager() virtual ITextureSource* getTextureSource();
{ assert(0); return NULL; } // TODO
private: private:
@ -616,7 +616,10 @@ private:
lua_State *m_lua; lua_State *m_lua;
// Tool definition manager // Tool definition manager
IToolDefManager *m_toolmgr; IWritableToolDefManager *m_toolmgr;
// Node definition manager
IWritableNodeDefManager *m_nodemgr;
/* /*
Threads Threads

View File

@ -74,7 +74,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h" #include "settings.h"
#include "profiler.h" #include "profiler.h"
#include "log.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 #include "content_mapnode.h" // For content_mapnode_init
/* /*
@ -302,11 +302,6 @@ int main(int argc, char *argv[])
// Initialize stuff // Initialize stuff
// Initialize content feature table without textures
init_contentfeatures(NULL);
// Initialize mapnode content without textures
content_mapnode_init(NULL);
init_mineral(); init_mineral();
/* /*

View File

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <sstream> #include <sstream>
#include "porting.h" #include "porting.h"
#include "content_mapnode.h" #include "content_mapnode.h"
#include "nodedef.h"
#include "mapsector.h" #include "mapsector.h"
#include "settings.h" #include "settings.h"
#include "log.h" #include "log.h"
@ -216,26 +217,26 @@ struct TestCompress
struct TestMapNode struct TestMapNode
{ {
void Run() void Run(INodeDefManager *nodedef)
{ {
MapNode n; MapNode n;
// Default values // Default values
assert(n.getContent() == CONTENT_AIR); assert(n.getContent() == CONTENT_AIR);
assert(n.getLight(LIGHTBANK_DAY) == 0); assert(n.getLight(LIGHTBANK_DAY, nodedef) == 0);
assert(n.getLight(LIGHTBANK_NIGHT) == 0); assert(n.getLight(LIGHTBANK_NIGHT, nodedef) == 0);
// Transparency // Transparency
n.setContent(CONTENT_AIR); n.setContent(CONTENT_AIR);
assert(n.light_propagates() == true); assert(nodedef->get(n).light_propagates == true);
n.setContent(CONTENT_STONE); n.setContent(CONTENT_STONE);
assert(n.light_propagates() == false); assert(nodedef->get(n).light_propagates == false);
} }
}; };
struct TestVoxelManipulator struct TestVoxelManipulator
{ {
void Run() void Run(INodeDefManager *nodedef)
{ {
/* /*
VoxelArea VoxelArea
@ -278,13 +279,13 @@ struct TestVoxelManipulator
VoxelManipulator v; VoxelManipulator v;
v.print(infostream); v.print(infostream, nodedef);
infostream<<"*** Setting (-1,0,-1)=2 ***"<<std::endl; infostream<<"*** Setting (-1,0,-1)=2 ***"<<std::endl;
v.setNodeNoRef(v3s16(-1,0,-1), MapNode(2)); v.setNodeNoRef(v3s16(-1,0,-1), MapNode(2));
v.print(infostream); v.print(infostream, nodedef);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2); assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
@ -292,85 +293,16 @@ struct TestVoxelManipulator
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1))); EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1)));
v.print(infostream); v.print(infostream, nodedef);
infostream<<"*** Adding area ***"<<std::endl; infostream<<"*** Adding area ***"<<std::endl;
v.addArea(a); v.addArea(a);
v.print(infostream); v.print(infostream, nodedef);
assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2); assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1))); 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();\ x.Run();\
} }
#define TESTPARAMS(X, ...)\
{\
X x;\
infostream<<"Running " #X <<std::endl;\
x.Run(__VA_ARGS__);\
}
void run_tests() void run_tests()
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
// Create node definitions
IWritableNodeDefManager *nodedef = createNodeDefManager(NULL);
content_mapnode_init(NULL, nodedef);
infostream<<"run_tests() started"<<std::endl; infostream<<"run_tests() started"<<std::endl;
TEST(TestUtilities); TEST(TestUtilities);
TEST(TestSettings); TEST(TestSettings);
TEST(TestCompress); TEST(TestCompress);
TEST(TestMapNode); TESTPARAMS(TestMapNode, nodedef);
TEST(TestVoxelManipulator); TESTPARAMS(TestVoxelManipulator, nodedef);
//TEST(TestMapBlock); //TEST(TestMapBlock);
//TEST(TestMapSector); //TEST(TestMapSector);
if(INTERNET_SIMULATOR == false){ if(INTERNET_SIMULATOR == false){

View File

@ -27,7 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#include "mapnode.h" // For texture atlas making #include "mapnode.h" // For texture atlas making
#include "mineral.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 A cache from texture name to texture path
@ -148,6 +149,142 @@ std::string getTexturePath(const std::string &filename)
TextureSource 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): TextureSource::TextureSource(IrrlichtDevice *device):
m_device(device), m_device(device),
m_main_atlas_image(NULL), m_main_atlas_image(NULL),
@ -162,12 +299,6 @@ TextureSource::TextureSource(IrrlichtDevice *device):
// Add a NULL AtlasPointer as the first index, named "" // Add a NULL AtlasPointer as the first index, named ""
m_atlaspointer_cache.push_back(SourceAtlasPointer("")); m_atlaspointer_cache.push_back(SourceAtlasPointer(""));
m_name_to_id[""] = 0; 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() TextureSource::~TextureSource()
@ -487,8 +618,17 @@ AtlasPointer TextureSource::getTexture(u32 id)
return m_atlaspointer_cache[id].a; 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; infostream<<"TextureSource::buildMainAtlas()"<<std::endl;
//return; // Disable (for testing) //return; // Disable (for testing)
@ -521,15 +661,15 @@ void TextureSource::buildMainAtlas()
{ {
if(j == CONTENT_IGNORE || j == CONTENT_AIR) if(j == CONTENT_IGNORE || j == CONTENT_AIR)
continue; continue;
ContentFeatures *f = &content_features(j); const ContentFeatures &f = ndef->get(j);
for(core::map<std::string, bool>::Iterator for(std::set<std::string>::const_iterator
i = f->used_texturenames.getIterator(); i = f.used_texturenames.begin();
i.atEnd() == false; i++) i != f.used_texturenames.end(); i++)
{ {
std::string name = i.getNode()->getKey(); std::string name = *i;
sourcelist[name] = true; sourcelist[name] = true;
if(f->often_contains_mineral){ if(f.often_contains_mineral){
for(int k=1; k<MINERAL_COUNT; k++){ for(int k=1; k<MINERAL_COUNT; k++){
std::string mineraltexture = mineral_block_texture(k); std::string mineraltexture = mineral_block_texture(k);
std::string fulltexture = name + "^" + mineraltexture; std::string fulltexture = name + "^" + mineraltexture;
@ -658,8 +798,18 @@ void TextureSource::buildMainAtlas()
Add texture to caches Add texture to caches
*/ */
// Get next id bool reuse_old_id = false;
u32 id = m_atlaspointer_cache.size(); 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 // Create AtlasPointer
AtlasPointer ap(id); AtlasPointer ap(id);
@ -672,8 +822,11 @@ void TextureSource::buildMainAtlas()
// Create SourceAtlasPointer and add to containers // Create SourceAtlasPointer and add to containers
SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim); SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
m_atlaspointer_cache.push_back(nap); if(reuse_old_id)
m_name_to_id.insert(name, id); m_atlaspointer_cache[id] = nap;
else
m_atlaspointer_cache.push_back(nap);
m_name_to_id[name] = id;
// Increment position // Increment position
pos_in_atlas.Y += dim.Height + padding * 2; pos_in_atlas.Y += dim.Height + padding * 2;

View File

@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h" #include "utility.h"
#include <string> #include <string>
class IGameDef;
/* /*
tile.{h,cpp}: Texture handling stuff. 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 class ITextureSource
{ {
public: public:
@ -137,133 +140,27 @@ public:
{return NULL;} {return NULL;}
}; };
/* class IWritableTextureSource : public ITextureSource
Creates and caches textures.
*/
class TextureSource : public ITextureSource
{ {
public: public:
TextureSource(IrrlichtDevice *device); IWritableTextureSource(){}
~TextureSource(); 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;}
/* virtual void updateAP(AtlasPointer &ap)=0;
Processes queued texture requests from other threads. virtual void buildMainAtlas(class IGameDef *gamedef)=0;
virtual void processQueue()=0;
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;
// Queued texture fetches (to be processed by the main thread)
RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
}; };
IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
enum MaterialType{ enum MaterialType{
MATERIAL_ALPHA_NONE, MATERIAL_ALPHA_NONE,
MATERIAL_ALPHA_VERTEX, MATERIAL_ALPHA_VERTEX,

View File

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "tool.h" #include "tooldef.h"
#include "irrlichttypes.h" #include "irrlichttypes.h"
#include "log.h" #include "log.h"
#include <ostream> #include <ostream>
class CToolDefManager: public IToolDefManager class CToolDefManager: public IWritableToolDefManager
{ {
public: public:
virtual ~CToolDefManager() virtual ~CToolDefManager()
@ -33,6 +33,35 @@ public:
delete i.getNode()->getValue(); delete i.getNode()->getValue();
} }
} }
virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const
{
core::map<std::string, ToolDefinition*>::Node *n;
n = m_tool_definitions.find(toolname);
if(n == NULL)
return NULL;
return n->getValue();
}
virtual std::string getImagename(const std::string &toolname) const
{
const ToolDefinition *def = getToolDefinition(toolname);
if(def == NULL)
return "";
return def->imagename;
}
virtual ToolDiggingProperties getDiggingProperties(
const std::string &toolname) const
{
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
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) virtual bool registerTool(std::string toolname, const ToolDefinition &def)
{ {
infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl; infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
@ -46,41 +75,12 @@ public:
m_tool_definitions[toolname] = new ToolDefinition(def); m_tool_definitions[toolname] = new ToolDefinition(def);
return true; return true;
} }
virtual ToolDefinition* getToolDefinition(const std::string &toolname)
{
core::map<std::string, ToolDefinition*>::Node *n;
n = m_tool_definitions.find(toolname);
if(n == NULL)
return NULL;
return n->getValue();
}
virtual std::string getImagename(const std::string &toolname)
{
ToolDefinition *def = getToolDefinition(toolname);
if(def == NULL)
return "";
return def->imagename;
}
virtual ToolDiggingProperties getDiggingProperties(
const std::string &toolname)
{
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("");
if(def == NULL) // If that doesn't exist either, return default
return ToolDiggingProperties();
return def->properties;
}
return def->properties;
}
private: private:
// Key is name // Key is name
core::map<std::string, ToolDefinition*> m_tool_definitions; core::map<std::string, ToolDefinition*> m_tool_definitions;
}; };
IToolDefManager* createToolDefManager() IWritableToolDefManager* createToolDefManager()
{ {
return new CToolDefManager(); return new CToolDefManager();
} }

View File

@ -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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef TOOL_HEADER #ifndef TOOLDEF_HEADER
#define TOOL_HEADER #define TOOLDEF_HEADER
#include <string> #include <string>
/*
TODO: Rename to tooldef.h
*/
struct ToolDiggingProperties struct ToolDiggingProperties
{ {
// time = basetime + sum(feature here * feature in MaterialProperties) // time = basetime + sum(feature here * feature in MaterialProperties)
@ -69,14 +73,26 @@ class IToolDefManager
public: public:
IToolDefManager(){} IToolDefManager(){}
virtual ~IToolDefManager(){} virtual ~IToolDefManager(){}
virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0; virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
virtual ToolDefinition* getToolDefinition(const std::string &toolname)=0; virtual std::string getImagename(const std::string &toolname) const =0;
virtual std::string getImagename(const std::string &toolname)=0;
virtual ToolDiggingProperties getDiggingProperties( virtual ToolDiggingProperties getDiggingProperties(
const std::string &toolname)=0; const std::string &toolname) const =0;
}; };
IToolDefManager* createToolDefManager(); 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) const =0;
virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
};
IWritableToolDefManager* createToolDefManager();
#endif #endif

View File

@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h" #include "map.h"
#include "utility.h" // For TimeTaker #include "utility.h" // For TimeTaker
#include "gettime.h" #include "gettime.h"
#include "content_mapnode.h" #include "nodedef.h"
/* /*
Debug stuff Debug stuff
@ -63,7 +63,8 @@ void VoxelManipulator::clear()
m_flags = NULL; 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 em = m_area.getExtent();
v3s16 of = m_area.MinEdge; v3s16 of = m_area.MinEdge;
@ -102,7 +103,7 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
} }
else if(mode == VOXELPRINT_WATERPRESSURE) else if(mode == VOXELPRINT_WATERPRESSURE)
{ {
if(m == CONTENT_WATER) if(nodemgr->get(m).isLiquid())
{ {
c = 'w'; c = 'w';
if(pr <= 9) if(pr <= 9)
@ -279,7 +280,7 @@ void VoxelManipulator::clearFlag(u8 flags)
} }
void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, 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 dirs[6] = {
v3s16(0,0,1), // back 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 If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node) 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 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 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); 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 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, void VoxelManipulator::unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes, 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) if(from_nodes.size() == 0)
return; return;
@ -378,7 +379,7 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
u8 oldlight = j.getNode()->getValue(); u8 oldlight = j.getNode()->getValue();
unspreadLight(bank, pos, oldlight, light_sources); unspreadLight(bank, pos, oldlight, light_sources, nodemgr);
} }
} }
#endif #endif
@ -448,18 +449,18 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
If the neighbor is dimmer than what was specified If the neighbor is dimmer than what was specified
as oldlight (the light of the previous node) 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 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 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); n2.setLight(bank, 0);
unlighted_nodes.insert(n2pos, current_light); unlighted_nodes.insert(n2pos, current_light);
@ -491,7 +492,8 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
} }
#endif #endif
void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p) void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p,
INodeDefManager *nodemgr)
{ {
const v3s16 dirs[6] = { const v3s16 dirs[6] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
@ -511,7 +513,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
MapNode &n = m_data[i]; MapNode &n = m_data[i];
u8 oldlight = n.getLight(bank); u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight); u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors // 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, If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn) 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 If the neighbor is dimmer than how much light this node
would spread on it, add to list 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);
spreadLight(bank, n2pos); spreadLight(bank, n2pos, nodemgr);
} }
} }
} }
@ -583,7 +585,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
goes on recursively. goes on recursively.
*/ */
void VoxelManipulator::spreadLight(enum LightBank bank, void VoxelManipulator::spreadLight(enum LightBank bank,
core::map<v3s16, bool> & from_nodes) core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr)
{ {
const v3s16 dirs[6] = { const v3s16 dirs[6] = {
v3s16(0,0,1), // back v3s16(0,0,1), // back
@ -614,7 +616,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
MapNode &n = m_data[i]; MapNode &n = m_data[i];
u8 oldlight = n.getLight(bank); u8 oldlight = n.getLight(bank, nodemgr);
u8 newlight = diminish_light(oldlight); u8 newlight = diminish_light(oldlight);
// Loop through 6 neighbors // Loop through 6 neighbors
@ -636,7 +638,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
If the neighbor is brighter than the current node, If the neighbor is brighter than the current node,
add to list (it will light up this node on its turn) 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.insert(n2pos, true);
} }
@ -644,11 +646,11 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
If the neighbor is dimmer than how much light this node If the neighbor is dimmer than how much light this node
would spread on it, add to list 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); lighted_nodes.insert(n2pos, true);
} }
} }
@ -666,7 +668,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
<<std::endl;*/ <<std::endl;*/
if(lighted_nodes.size() > 0) if(lighted_nodes.size() > 0)
spreadLight(bank, lighted_nodes); spreadLight(bank, lighted_nodes, nodemgr);
} }
#endif #endif

View File

@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" #include "debug.h"
#include "mapnode.h" #include "mapnode.h"
class INodeDefManager;
// For VC++ // For VC++
#undef min #undef min
#undef max #undef max
@ -475,7 +477,8 @@ public:
virtual void clear(); 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); void addArea(VoxelArea area);
@ -497,14 +500,14 @@ public:
void clearFlag(u8 flag); void clearFlag(u8 flag);
void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, 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, void unspreadLight(enum LightBank bank,
core::map<v3s16, u8> & from_nodes, 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, void spreadLight(enum LightBank bank,
core::map<v3s16, bool> & from_nodes); core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr);
/* /*
Virtual functions Virtual functions